mirror of https://github.com/stella-emu/stella.git
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
This commit is contained in:
parent
5898941bf0
commit
62b7ae6038
|
@ -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 <assert.h>
|
||||
|
@ -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);
|
||||
|
||||
// Load the specified load into RAM
|
||||
// Read the specified load into RAM
|
||||
loadIntoRAM(load);
|
||||
|
||||
return myImage[(addr & 0x07FF) + myImageOffset[1]];
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Are the "value" registers being accessed?
|
||||
// Is the data hold register being set?
|
||||
if(!(addr & 0x0F00) && (!myWriteEnabled || !myWritePending))
|
||||
{
|
||||
myLastAccess = addr;
|
||||
myDataHoldRegister = addr;
|
||||
myNumberOfDistinctAccesses = my6502->distinctAccesses();
|
||||
myWritePending = true;
|
||||
}
|
||||
|
@ -167,23 +141,18 @@ 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)
|
||||
{
|
||||
if(my6502->distinctAccesses() >= myNumberOfDistinctAccesses + 5)
|
||||
{
|
||||
if(my6502->distinctAccesses() == myNumberOfDistinctAccesses + 5)
|
||||
else if(myWriteEnabled && myWritePending &&
|
||||
(my6502->distinctAccesses() == (myNumberOfDistinctAccesses + 5)))
|
||||
{
|
||||
if((addr & 0x0800) == 0)
|
||||
myImage[(addr & 0x07FF) + myImageOffset[0]] = myLastAccess;
|
||||
myImage[(addr & 0x07FF) + myImageOffset[0]] = myDataHoldRegister;
|
||||
else if(myImageOffset[1] != 3 * 2048) // Can't poke to ROM :-)
|
||||
myImage[(addr & 0x07FF) + myImageOffset[1]] = myLastAccess;
|
||||
}
|
||||
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,24 +180,19 @@ 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)
|
||||
{
|
||||
if(my6502->distinctAccesses() >= myNumberOfDistinctAccesses + 5)
|
||||
{
|
||||
if(my6502->distinctAccesses() == myNumberOfDistinctAccesses + 5)
|
||||
else if(myWriteEnabled && myWritePending &&
|
||||
(my6502->distinctAccesses() == (myNumberOfDistinctAccesses + 5)))
|
||||
{
|
||||
if((addr & 0x0800) == 0)
|
||||
myImage[(addr & 0x07FF) + myImageOffset[0]] = myLastAccess;
|
||||
myImage[(addr & 0x07FF) + myImageOffset[0]] = myDataHoldRegister;
|
||||
else if(myImageOffset[1] != 3 * 2048) // Can't poke to ROM :-)
|
||||
myImage[(addr & 0x07FF) + myImageOffset[1]] = myLastAccess;
|
||||
}
|
||||
myImage[(addr & 0x07FF) + myImageOffset[1]] = myDataHoldRegister;
|
||||
myWritePending = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeAR::bankConfiguration(uInt8 configuration)
|
||||
|
@ -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
|
||||
// Copy page to Supercharger RAM (don't allow a copy into ROM area)
|
||||
if(bank < 3)
|
||||
{
|
||||
memcpy(myImage + (bank * 2048) + (page * 256), src, 256);
|
||||
}
|
||||
}
|
||||
|
||||
// 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]);
|
||||
|
||||
// Make sure the "dummy" ROM is installed
|
||||
setupROM();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <iomanip.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
;;
|
||||
;; Normal clear page zero routine for initial program load
|
||||
;; Entry point for multi-load reading
|
||||
;;
|
||||
LDA #0
|
||||
LDX #0
|
||||
clear STA $80,X
|
||||
INX
|
||||
CPX #$80
|
||||
BNE clear
|
||||
JMP cpcode
|
||||
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
|
||||
|
||||
;;
|
||||
;; Clear page zero routine for multi-load
|
||||
;; Entry point for initial load (invoked when the system is reset)
|
||||
;;
|
||||
org $FA20
|
||||
org $F80A
|
||||
|
||||
LDA #0
|
||||
LDX #0
|
||||
mlclr STA $80,X
|
||||
INX
|
||||
CPX #$1E
|
||||
BNE mlclr
|
||||
start SEI
|
||||
CLD
|
||||
|
||||
;;
|
||||
;; Now, copy some code into page zero to do the initial bank switch
|
||||
;; Clear page zero routine for initial load (e.g., RAM and TIA registers)
|
||||
;;
|
||||
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 $????
|
||||
|
||||
|
|
Loading…
Reference in New Issue