From 62b7ae603838e63fe01c057d091bda48b7677b72 Mon Sep 17 00:00:00 2001 From: bwmott Date: Fri, 5 Apr 2002 02:18:23 +0000 Subject: [PATCH] A new BIOS has been added to the Supercharger emulation based on code from Eckhard Stolberg. This version simulates the progress bar and leaves the TIA in a state more like the real thing. This fixes some display problems with games (e.g., Mindmaster). In addtion, the bank switching and RAM writing emulation has been improved. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@63 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/emucore/CartAR.cxx | 223 ++++++++++++------------ stella/src/emucore/CartAR.hxx | 19 +- stella/src/emucore/misc/romtohex.cxx | 8 +- stella/src/emucore/misc/scrom.asm | 248 ++++++++++++++++++++++----- 4 files changed, 331 insertions(+), 167 deletions(-) diff --git a/stella/src/emucore/CartAR.cxx b/stella/src/emucore/CartAR.cxx index b7c845bc5..1f345aa23 100644 --- a/stella/src/emucore/CartAR.cxx +++ b/stella/src/emucore/CartAR.cxx @@ -8,12 +8,12 @@ // SS SS tt ee ll ll aa aa // SSSS ttt eeeee llll llll aaaaa // -// Copyright (c) 1995-1999 by Bradford W. Mott +// Copyright (c) 1995-2002 by Bradford W. Mott // // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: CartAR.cxx,v 1.1.1.1 2001-12-27 19:54:19 bwmott Exp $ +// $Id: CartAR.cxx,v 1.2 2002-04-05 02:18:23 bwmott Exp $ //============================================================================ #include @@ -41,11 +41,8 @@ CartridgeAR::CartridgeAR(const uInt8* image, uInt32 size) myImage[i] = random.next(); } - // Initialize ROM with an invalid 6502 opcode - for(i = 6 * 1024; i < 8 * 1024; ++i) - { - myImage[i] = 0xFF; - } + // Initialize SC BIOS ROM + initializeROM(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -63,20 +60,16 @@ const char* CartridgeAR::name() const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeAR::reset() { - // Try to load the first load into RAM upon reset - loadIntoRAM(0); - myPower = true; - myPowerRomCycle = 0; + myPowerRomCycle = mySystem->cycles(); myWriteEnabled = false; - myLastAccess = 0; + myDataHoldRegister = 0; myNumberOfDistinctAccesses = 0; myWritePending = false; - // Set bank configuration upon reset so ROM is selected - myImageOffset[0] = 0 * 2048; - myImageOffset[1] = 3 * 2048; + // Set bank configuration upon reset so ROM is selected and powered up + bankConfiguration(0); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -116,49 +109,30 @@ void CartridgeAR::install(System& system) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeAR::peek(uInt16 addr) { - // Check to see if the Supercharger ROM is being accessed? - if(myImageOffset[1] == 3 * 2048) + // Is the "dummy" SC BIOS hotspot for reading a load being accessed? + if(((addr & 0x1FFF) == 0x1850) && (myImageOffset[1] == (3 * 2048))) { - Int32 cycles = mySystem->cycles(); + // Get load that's being accessed (BIOS places load number at 0x80) + uInt8 load = mySystem->peek(0x0080); - // Is the tape rewind routine being accessed? - if((addr & 0x1FFF) == 0x180A) - { - // See if the ROM has been powered up long enough - if(!myPower || (myPower && ((myPowerRomCycle + 7) > cycles))) - { - cerr << "ERROR: Supercharger ROM has not been powered up!\n"; - } - else - { - cerr << "ERROR: Supercharger code doesn't handle rewinding tape!\n"; - } - } - // Is the multiload routine being accessed? - else if((addr & 0x1FFF) == 0x1800) - { - // See if the ROM has been powered up long enough - if(!myPower || (myPower && ((myPowerRomCycle + 7) > cycles))) - { - cerr << "ERROR: Supercharger ROM has not been powered up!\n"; - } - else - { - // Get the load they're trying to access - uInt8 load = mySystem->peek(0x00FA); + // Read the specified load into RAM + loadIntoRAM(load); - // Load the specified load into RAM - loadIntoRAM(load); - - return myImage[(addr & 0x07FF) + myImageOffset[1]]; - } - } + return myImage[(addr & 0x07FF) + myImageOffset[1]]; } - // Are the "value" registers being accessed? + // Cancel any pending write if more than 5 distinct accesses have occurred + // TODO: Modify to handle when the distinct counter wraps around... + if(myWritePending && + (my6502->distinctAccesses() > myNumberOfDistinctAccesses + 5)) + { + myWritePending = false; + } + + // Is the data hold register being set? if(!(addr & 0x0F00) && (!myWriteEnabled || !myWritePending)) { - myLastAccess = addr; + myDataHoldRegister = addr; myNumberOfDistinctAccesses = my6502->distinctAccesses(); myWritePending = true; } @@ -167,22 +141,17 @@ uInt8 CartridgeAR::peek(uInt16 addr) { // Yes, so handle bank configuration myWritePending = false; - bankConfiguration(myLastAccess); + bankConfiguration(myDataHoldRegister); } // Handle poke if writing enabled - else if(myWriteEnabled && myWritePending) + else if(myWriteEnabled && myWritePending && + (my6502->distinctAccesses() == (myNumberOfDistinctAccesses + 5))) { - if(my6502->distinctAccesses() >= myNumberOfDistinctAccesses + 5) - { - if(my6502->distinctAccesses() == myNumberOfDistinctAccesses + 5) - { - if((addr & 0x0800) == 0) - myImage[(addr & 0x07FF) + myImageOffset[0]] = myLastAccess; - else if(myImageOffset[1] != 3 * 2048) // Can't poke to ROM :-) - myImage[(addr & 0x07FF) + myImageOffset[1]] = myLastAccess; - } - myWritePending = false; - } + if((addr & 0x0800) == 0) + myImage[(addr & 0x07FF) + myImageOffset[0]] = myDataHoldRegister; + else if(myImageOffset[1] != 3 * 2048) // Can't poke to ROM :-) + myImage[(addr & 0x07FF) + myImageOffset[1]] = myDataHoldRegister; + myWritePending = false; } return myImage[(addr & 0x07FF) + myImageOffset[(addr & 0x0800) ? 1 : 0]]; @@ -191,10 +160,18 @@ uInt8 CartridgeAR::peek(uInt16 addr) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void CartridgeAR::poke(uInt16 addr, uInt8) { - // Are the "value" registers being accessed? + // Cancel any pending write if more than 5 distinct accesses have occurred + // TODO: Modify to handle when the distinct counter wraps around... + if(myWritePending && + (my6502->distinctAccesses() > myNumberOfDistinctAccesses + 5)) + { + myWritePending = false; + } + + // Is the data hold register being set? if(!(addr & 0x0F00) && (!myWriteEnabled || !myWritePending)) { - myLastAccess = addr; + myDataHoldRegister = addr; myNumberOfDistinctAccesses = my6502->distinctAccesses(); myWritePending = true; } @@ -203,22 +180,17 @@ void CartridgeAR::poke(uInt16 addr, uInt8) { // Yes, so handle bank configuration myWritePending = false; - bankConfiguration(myLastAccess); + bankConfiguration(myDataHoldRegister); } // Handle poke if writing enabled - else if(myWriteEnabled && myWritePending) + else if(myWriteEnabled && myWritePending && + (my6502->distinctAccesses() == (myNumberOfDistinctAccesses + 5))) { - if(my6502->distinctAccesses() >= myNumberOfDistinctAccesses + 5) - { - if(my6502->distinctAccesses() == myNumberOfDistinctAccesses + 5) - { - if((addr & 0x0800) == 0) - myImage[(addr & 0x07FF) + myImageOffset[0]] = myLastAccess; - else if(myImageOffset[1] != 3 * 2048) // Can't poke to ROM :-) - myImage[(addr & 0x07FF) + myImageOffset[1]] = myLastAccess; - } - myWritePending = false; - } + if((addr & 0x0800) == 0) + myImage[(addr & 0x07FF) + myImageOffset[0]] = myDataHoldRegister; + else if(myImageOffset[1] != 3 * 2048) // Can't poke to ROM :-) + myImage[(addr & 0x07FF) + myImageOffset[1]] = myDataHoldRegister; + myWritePending = false; } } @@ -314,45 +286,67 @@ void CartridgeAR::bankConfiguration(uInt8 configuration) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void CartridgeAR::setupROM() +void CartridgeAR::initializeROM() { static uInt8 dummyROMCode[] = { - 0xa9, 0x0, 0xa2, 0x0, 0x95, 0x80, 0xe8, 0xe0, - 0x80, 0xd0, 0xf9, 0x4c, 0x2b, 0xfa, 0xff, 0xff, + 0xa5, 0xfa, 0x85, 0x80, 0x4c, 0x18, 0xf8, 0xff, + 0xff, 0xff, 0x78, 0xd8, 0xa0, 0x0, 0xa2, 0x0, + 0x94, 0x0, 0xe8, 0xd0, 0xfb, 0x4c, 0x50, 0xf8, + 0xa2, 0x0, 0xbd, 0x6, 0xf0, 0xad, 0xf8, 0xff, + 0xa2, 0x0, 0xad, 0x0, 0xf0, 0xea, 0xbd, 0x0, + 0xf7, 0xca, 0xd0, 0xf6, 0x4c, 0x50, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xa9, 0x0, 0xa2, 0x0, 0x95, 0x80, 0xe8, 0xe0, - 0x1e, 0xd0, 0xf9, 0xa2, 0x0, 0xbd, 0x45, 0xfa, - 0x95, 0xfa, 0xe8, 0xe0, 0x6, 0xd0, 0xf6, 0xa2, - 0xff, 0xa0, 0x0, 0xa9, 0x0, 0x85, 0x80, 0xcd, - 0x0, 0xf0, 0x4c, 0xfa, 0x0, 0xad, 0xf8, 0xff, - 0x4c, 0x0, 0x0 + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xa2, 0x3, 0xbc, 0x1d, 0xf9, 0x94, 0xfa, 0xca, + 0x10, 0xf8, 0xa0, 0x0, 0xa2, 0x28, 0x94, 0x4, + 0xca, 0x10, 0xfb, 0xa2, 0x1c, 0x94, 0x81, 0xca, + 0x10, 0xfb, 0xa9, 0x0, 0x85, 0x1b, 0x85, 0x1c, + 0x85, 0x1d, 0x85, 0x1e, 0x85, 0x1f, 0x85, 0x19, + 0x85, 0x1a, 0x85, 0x8, 0x85, 0x1, 0xa9, 0x10, + 0x85, 0x21, 0x85, 0x2, 0xa2, 0x7, 0xca, 0xca, + 0xd0, 0xfd, 0xa9, 0x0, 0x85, 0x20, 0x85, 0x10, + 0x85, 0x11, 0x85, 0x2, 0x85, 0x2a, 0xa9, 0x5, + 0x85, 0xa, 0xa9, 0xff, 0x85, 0xd, 0x85, 0xe, + 0x85, 0xf, 0x85, 0x84, 0x85, 0x85, 0xa9, 0xf0, + 0x85, 0x83, 0xa9, 0x74, 0x85, 0x9, 0xa9, 0xc, + 0x85, 0x15, 0xa9, 0x1f, 0x85, 0x17, 0x85, 0x82, + 0xa9, 0x7, 0x85, 0x19, 0xa2, 0x8, 0xa0, 0x0, + 0x85, 0x2, 0x88, 0xd0, 0xfb, 0x85, 0x2, 0x85, + 0x2, 0xa9, 0x2, 0x85, 0x2, 0x85, 0x0, 0x85, + 0x2, 0x85, 0x2, 0x85, 0x2, 0xa9, 0x0, 0x85, + 0x0, 0xca, 0x10, 0xe4, 0x6, 0x83, 0x66, 0x84, + 0x26, 0x85, 0xa5, 0x83, 0x85, 0xd, 0xa5, 0x84, + 0x85, 0xe, 0xa5, 0x85, 0x85, 0xf, 0xa6, 0x82, + 0xca, 0x86, 0x82, 0x86, 0x17, 0xe0, 0xa, 0xd0, + 0xc3, 0xa9, 0x2, 0x85, 0x1, 0xa2, 0x1c, 0xa0, + 0x0, 0x84, 0x19, 0x84, 0x9, 0x94, 0x81, 0xca, + 0x10, 0xfb, 0xa6, 0x80, 0xdd, 0x0, 0xf0, 0xa5, + 0x80, 0x45, 0xfe, 0x45, 0xff, 0xa2, 0xff, 0xa0, + 0x0, 0x9a, 0x4c, 0xfa, 0x0, 0xcd, 0xf8, 0xff, + 0x4c }; - int size = sizeof(dummyROMCode); + uInt32 size = sizeof(dummyROMCode); - // Copy the "dummy" ROM code into the ROM area - for(int i = 0; i < size; ++i) + // Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam + for(uInt32 i = 0; i < 2048; ++i) { - myImage[0x1A00 + i] = dummyROMCode[i]; + myImage[3 * 2048 + i] = 0x02; } - // Put a JMP $FA20 at multiload entry point ($F800) - myImage[0x1800] = 0x4C; - myImage[0x1801] = 0x20; - myImage[0x1802] = 0xFA; + // Copy the "dummy" Supercharger BIOS code into the ROM area + for(uInt32 j = 0; j < size; ++j) + { + myImage[3 * 2048 + j] = dummyROMCode[j]; + } - // Update ROM code to have the correct reset address and bank configuration - myImage[0x1A00 + size - 2] = myHeader[0]; - myImage[0x1A00 + size - 1] = myHeader[1]; - myImage[0x1A00 + size - 11] = myHeader[2]; - myImage[0x1A00 + size - 15] = myHeader[2]; - - // Finally set 6502 vectors to point to this "dummy" code at 0xFA00 - myImage[3 * 2048 + 2044] = 0x00; - myImage[3 * 2048 + 2045] = 0xFA; - myImage[3 * 2048 + 2046] = 0x00; - myImage[3 * 2048 + 2047] = 0xFA; + // Finally set 6502 vectors to point to initial load code at 0xF80A of BIOS + myImage[3 * 2048 + 2044] = 0x0A; + myImage[3 * 2048 + 2045] = 0xF8; + myImage[3 * 2048 + 2046] = 0x0A; + myImage[3 * 2048 + 2047] = 0xF8; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -403,12 +397,19 @@ void CartridgeAR::loadIntoRAM(uInt8 load) invalidPageChecksumSeen = true; } - // Copy page to Supercharger RAM - memcpy(myImage + (bank * 2048) + (page * 256), src, 256); + // Copy page to Supercharger RAM (don't allow a copy into ROM area) + if(bank < 3) + { + memcpy(myImage + (bank * 2048) + (page * 256), src, 256); + } } - // Make sure the "dummy" ROM is installed - setupROM(); + // Copy the bank switching byte and starting address into the 2600's + // RAM for the "dummy" SC BIOS to access it + mySystem->poke(0xfe, myHeader[0]); + mySystem->poke(0xff, myHeader[1]); + mySystem->poke(0x80, myHeader[2]); + return; } } diff --git a/stella/src/emucore/CartAR.hxx b/stella/src/emucore/CartAR.hxx index aa365d738..8736d040a 100644 --- a/stella/src/emucore/CartAR.hxx +++ b/stella/src/emucore/CartAR.hxx @@ -8,12 +8,12 @@ // SS SS tt ee ll ll aa aa // SSSS ttt eeeee llll llll aaaaa // -// Copyright (c) 1995-1999 by Bradford W. Mott +// Copyright (c) 1995-2002 by Bradford W. Mott // // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: CartAR.hxx,v 1.1.1.1 2001-12-27 19:54:19 bwmott Exp $ +// $Id: CartAR.hxx,v 1.2 2002-04-05 02:18:23 bwmott Exp $ //============================================================================ #ifndef CARTRIDGEAR_HXX @@ -28,13 +28,14 @@ class M6502High; /** This is the cartridge class for Arcadia (aka Starpath) Supercharger games. Christopher Salomon provided most of the technical details - used in creating this class. + used in creating this class. A good description of the Supercharger + is provided in the Cuttle Cart's manual. The Supercharger has four 2K banks. There are three banks of RAM and one bank of ROM. All 6K of the RAM can be read and written. @author Bradford W. Mott - @version $Id: CartAR.hxx,v 1.1.1.1 2001-12-27 19:54:19 bwmott Exp $ + @version $Id: CartAR.hxx,v 1.2 2002-04-05 02:18:23 bwmott Exp $ */ class CartridgeAR : public Cartridge { @@ -106,8 +107,8 @@ class CartridgeAR : public Cartridge // Load the specified load into SC RAM void loadIntoRAM(uInt8 load); - // Sets up a "dummy" bootstrap ROM in the ROM bank of the cartridge - void setupROM(); + // Sets up a "dummy" BIOS ROM in the ROM bank of the cartridge + void initializeROM(); private: // Pointer to the 6502 processor in the system @@ -137,10 +138,10 @@ class CartridgeAR : public Cartridge // Indicates when the power was last turned on Int32 myPowerRomCycle; - // Indicates the "value" address which was accessed - uInt16 myLastAccess; + // Data hold register used for writing + uInt8 myDataHoldRegister; - // Indicates the number of distinct accesses when "value" was set + // Indicates number of distinct accesses when data hold register was set uInt32 myNumberOfDistinctAccesses; // Indicates if a write is pending or not diff --git a/stella/src/emucore/misc/romtohex.cxx b/stella/src/emucore/misc/romtohex.cxx index eacc15df9..7cbec94ae 100644 --- a/stella/src/emucore/misc/romtohex.cxx +++ b/stella/src/emucore/misc/romtohex.cxx @@ -2,7 +2,7 @@ Simple program that produces a hex list of a binary object file @author Bradford W. Mott - @version $Id: romtohex.cxx,v 1.1.1.1 2001-12-27 19:54:32 bwmott Exp $ + @version $Id: romtohex.cxx,v 1.2 2002-04-05 02:18:23 bwmott Exp $ */ #include @@ -10,7 +10,9 @@ main() { - ifstream in("rom.o"); + ifstream in("scrom.bin"); + + cout << " "; for(int t = 0; ; ++t) { @@ -23,7 +25,7 @@ main() cout << "0x" << hex << (int)c << ", "; if((t % 8) == 7) - cout << endl; + cout << endl << " "; } cout << endl; } diff --git a/stella/src/emucore/misc/scrom.asm b/stella/src/emucore/misc/scrom.asm index 1313889c7..428dd41f9 100644 --- a/stella/src/emucore/misc/scrom.asm +++ b/stella/src/emucore/misc/scrom.asm @@ -8,74 +8,234 @@ ;; SS SS tt ee ll ll aa aa ;; SSSS ttt eeeee llll llll aaaaa ;; -;; Copyright (c) 1995-1998 by Bradford W. Mott +;; Copyright (c) 1995-2002 by Bradford W. Mott ;; ;; See the file "license" for information on usage and redistribution of ;; this file, and for a DISCLAIMER OF ALL WARRANTIES. ;; -;; $Id: scrom.asm,v 1.1.1.1 2001-12-27 19:54:32 bwmott Exp $ +;; $Id: scrom.asm,v 1.2 2002-04-05 02:18:23 bwmott Exp $ ;;============================================================================ ;; -;; This file contains a "dummy" Supercharger ROM for Stella. It basically -;; contains some bootstrapping code to get the game up and running. +;; This file contains a "dummy" Supercharger BIOS for Stella. It is based +;; on routines developed by Eckhard Stolberg. ;; ;;============================================================================ processor 6502 - org $FA00 +VSYNC equ $00 +VBLANK equ $01 +WSYNC equ $02 +COLUPF equ $08 +COLUBK equ $09 +CTRLPF equ $0a +PF0 equ $0d +PF1 equ $0e +PF2 equ $0f +RESP0 equ $10 +RESP1 equ $11 +AUDC0 equ $15 +AUDF0 equ $17 +AUDV0 equ $19 +AUDV1 equ $1a +GRP0 equ $1b +GRP1 equ $1c +ENAM0 equ $1d +ENAM1 equ $1e +ENABL equ $1f +HMP0 equ $20 +HMP1 equ $21 +HMOVE equ $2a + +;; +;; Entry point for multi-load reading +;; + org $F800 + + LDA $FA ; Grab the load number and store it in $80 where the + STA $80 ; emulator will grab it when it does the loading + JMP clrp7 ; Go clear page 7 of RAM bank 1 like the real SC ;; -;; Normal clear page zero routine for initial program load +;; Entry point for initial load (invoked when the system is reset) ;; - LDA #0 - LDX #0 -clear STA $80,X - INX - CPX #$80 - BNE clear - JMP cpcode + org $F80A + +start SEI + CLD ;; -;; Clear page zero routine for multi-load +;; Clear page zero routine for initial load (e.g., RAM and TIA registers) ;; - org $FA20 - - LDA #0 - LDX #0 -mlclr STA $80,X - INX - CPX #$1E - BNE mlclr - -;; -;; Now, copy some code into page zero to do the initial bank switch -;; -cpcode LDX #0 -copy LDA code,X - STA $fa,X - INX - CPX #6 - BNE copy - -;; -;; Initialize X and Y registers -;; - LDX #$ff LDY #$00 + LDX #$00 +ilclr STY $00,X + INX + BNE ilclr + + JMP load ;; -;; Store the bank configuration in $80 and in CMP instruction +;; Clear page 7 of RAM bank 1 (used for stars in the real SC) ;; - LDA #$00 ;; $00 is changed by emulator to the correct value - STA $80 +clrp7 LDX #$00 + LDA $F006,X + LDA $FFF8 + LDX #$00 +mlclr3 LDA $F000 + NOP + LDA $F700,X + DEX + BNE mlclr3 + JMP load + +;; +;; NOTE: The emulator does the actual reading of the new load when the +;; next instruction is accessed. The emulator expects the load number to +;; to be stored in location $80. As a side-effect the emulator sets $80 +;; to contain the bank selection byte from the load's header and sets +;; $FE and $FF to contain the starting address from the load's header. +;; +load org $F850 + +;; +;; Copy code into page zero to do the bank switching +;; + LDX #$03 +copy LDY code,X + STY $FA,X + DEX + BPL copy + +;; +;; Clear some of the 2600's RAM and TIA registers like the real SC BIOS does +;; + LDY #$00 + LDX #$28 +mlclr1 STY $04,X + DEX + BPL mlclr1 + + LDX #$1C +mlclr2 STY $81,X + DEX + BPL mlclr2 + +;; +;; Display the "emulated" Supercharger loading progress bar +;; + LDA #$00 + STA GRP0 + STA GRP1 + STA ENAM0 + STA ENAM1 + STA ENABL + STA AUDV0 + STA AUDV1 + STA COLUPF + STA VBLANK + + LDA #$10 + STA HMP1 + STA WSYNC + LDX #$07 + DEX +pos DEX + BNE pos + LDA #$00 + STA HMP0 + STA RESP0 + STA RESP1 + STA WSYNC + STA HMOVE + + LDA #%00000101 + STA CTRLPF + LDA #$FF + STA PF0 + STA PF1 + STA PF2 + STA $84 + STA $85 + LDA #$F0 + STA $83 + LDA #$74 + STA COLUBK + LDA #$0C + STA AUDC0 + LDA #$1F + STA AUDF0 + STA $82 + LDA #$07 + STA AUDV0 +a1 + LDX #$08 + LDY #$00 +a2 + STA WSYNC + DEY + BNE a2 + STA WSYNC + STA WSYNC + LDA #$02 + STA WSYNC + STA VSYNC + STA WSYNC + STA WSYNC + STA WSYNC + LDA #$00 + STA VSYNC + DEX + BPL a2 + ASL $83 + ROR $84 + ROL $85 + LDA $83 + STA PF0 + LDA $84 + STA PF1 + LDA $85 + STA PF2 + LDX $82 + DEX + STX $82 + STX AUDF0 + CPX #$0A + BNE a1 + + LDA #%00000010 + STA VBLANK + + LDX #$1C + LDY #$00 + STY AUDV0 + STY COLUBK +clear: + STY $81,x + DEX + BPL clear + +;; +;; Setup value to be stored in the bank switching control register +;; + LDX $80 + CMP $F000,X + +;; +;; Initialize A, X, Y, and SP registers +;; + LDA $80 + EOR $FE + EOR $FF + LDX #$FF + LDY #$00 + TXS - CMP $f000 ;; $00 is changed by emulator to the correct value ;; ;; Execute the code to do bank switch and start running cartridge code ;; - JMP $fa + JMP $FA -code dc.b $ad, $f8, $ff ;; LDA $fff8 - dc.b $4c, $00, $00 ;; JMP $???? ($???? is filled in by emulator) +code dc.b $cd, $f8, $ff ;; CMP $fff8 + dc.b $4c ;; JMP $????