. It's an Apple II plus clone. . The 48K bank-switched Rom is controlled with AN0 and AN1. . The character generation video Rom has two full character sets: English and German (F10 to switch). NB. At the prompt, "TEST" runs the ROM self-test.
This commit is contained in:
parent
6dd129532f
commit
36e318e344
17 changed files with 131 additions and 24 deletions
|
@ -237,6 +237,8 @@
|
|||
<None Include="resource\Apple2e.rom" />
|
||||
<None Include="resource\Apple2e_Enhanced.rom" />
|
||||
<None Include="resource\Apple2_Plus.rom" />
|
||||
<None Include="resource\Base64A.rom" />
|
||||
<None Include="resource\Base64A_German_Video.rom" />
|
||||
<None Include="resource\DISK2.rom" />
|
||||
<None Include="resource\Freezes_Non-autostart_F8_Rom.rom" />
|
||||
<None Include="resource\Hddrvr.bin" />
|
||||
|
@ -298,6 +300,7 @@
|
|||
<Image Include="resource\LED_CAPS_ON_P8.BMP" />
|
||||
<Image Include="resource\RUN.BMP" />
|
||||
<Image Include="resource\RUN3000E.bmp" />
|
||||
<Image Include="resource\RUNBASE64A.BMP" />
|
||||
<Image Include="resource\RUNP.BMP" />
|
||||
<Image Include="resource\SETUP.BMP" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -593,6 +593,9 @@
|
|||
<Image Include="resource\RUN3000E.bmp">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="resource\RUNBASE64A.BMP">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="resource\Apple2.rom">
|
||||
|
@ -652,6 +655,12 @@
|
|||
<None Include="resource\TKClock.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="resource\Base64A.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="resource\Base64A_German_Video.rom">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="docs\CodingConventions.txt">
|
||||
|
|
|
@ -55,6 +55,7 @@ FULLSCR_BUTTON BITMAP "FULLSCR.BMP"
|
|||
RUN_BUTTON BITMAP "RUN.BMP"
|
||||
RUNP_BUTTON BITMAP "RUNP.BMP"
|
||||
RUN3000E_BUTTON BITMAP "RUN3000E.BMP"
|
||||
RUNBASE64A_BUTTON BITMAP "RUNBASE64A.BMP"
|
||||
DEBUG_BUTTON BITMAP "DEBUG.BMP"
|
||||
DRIVE1_BUTTON BITMAP "DRIVE1.BMP"
|
||||
DRIVE2_BUTTON BITMAP "DRIVE2.BMP"
|
||||
|
@ -332,6 +333,7 @@ IDR_PRAVETS_82_ROM ROM "Pravets82.rom"
|
|||
IDR_PRAVETS_8M_ROM ROM "Pravets8M.rom"
|
||||
IDR_PRAVETS_8C_ROM ROM "Pravets8C.rom"
|
||||
IDR_TK3000_2E_ROM ROM "TK3000e.rom"
|
||||
IDR_BASE_64A_ROM ROM "Base64A.rom"
|
||||
IDR_FREEZES_F8_ROM ROM "FREEZES_NON-AUTOSTART_F8_ROM.rom"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -340,6 +342,7 @@ IDR_FREEZES_F8_ROM ROM "FREEZES_NON-AUTOSTART_F8_ROM.ro
|
|||
//
|
||||
|
||||
IDR_APPLE2_JPLUS_VIDEO_ROM ROM "Apple2_JPlus_Video.rom"
|
||||
IDR_BASE64A_VIDEO_ROM ROM "Base64A_German_Video.rom"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
BIN
resource/Base64A.rom
Normal file
BIN
resource/Base64A.rom
Normal file
Binary file not shown.
BIN
resource/Base64A_German_Video.rom
Normal file
BIN
resource/Base64A_German_Video.rom
Normal file
Binary file not shown.
BIN
resource/RUNBASE64A.BMP
Normal file
BIN
resource/RUNBASE64A.BMP
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
|
@ -51,6 +51,8 @@
|
|||
#define IDR_DISK2_16SECTOR_FW 150
|
||||
#define IDR_APPLE2_JPLUS_ROM 151
|
||||
#define IDR_APPLE2_JPLUS_VIDEO_ROM 152
|
||||
#define IDR_BASE_64A_ROM 153
|
||||
#define IDR_BASE64A_VIDEO_ROM 154
|
||||
#define IDC_KEYB_BUFFER_ENABLE 1005
|
||||
#define IDC_SAVESTATE 1006
|
||||
#define IDC_SAVESTATE_ON_EXIT 1007
|
||||
|
|
|
@ -57,6 +57,7 @@ enum AppMode_e
|
|||
#define TITLE_PRAVETS_8M TEXT("Pravets 8M Emulator")
|
||||
#define TITLE_PRAVETS_8A TEXT("Pravets 8A Emulator")
|
||||
#define TITLE_TK3000_2E TEXT("TK3000 //e Emulator")
|
||||
#define TITLE_BASE64A TEXT("Base64A Emulator")
|
||||
|
||||
#define TITLE_PAUSED TEXT("* PAUSED *")
|
||||
#define TITLE_STEPPING TEXT("Stepping")
|
||||
|
@ -180,6 +181,7 @@ enum eApple2Type {
|
|||
A2TYPE_CLONE=APPLECLONE_MASK,
|
||||
A2TYPE_PRAVETS8M, // Apple ][ clone
|
||||
A2TYPE_PRAVETS82, // Apple ][ clone
|
||||
A2TYPE_BASE64A, // Apple ][ clone
|
||||
// (Gap for more Apple ][ clones)
|
||||
A2TYPE_CLONE_A2_MAX,
|
||||
|
||||
|
|
|
@ -33,12 +33,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
CPageAdvanced* CPageAdvanced::ms_this = 0; // reinit'd in ctor
|
||||
|
||||
enum CLONECHOICE {MENUITEM_CLONEMIN, MENUITEM_PRAVETS82=MENUITEM_CLONEMIN, MENUITEM_PRAVETS8M, MENUITEM_PRAVETS8A, MENUITEM_TK30002E, MENUITEM_CLONEMAX};
|
||||
enum CLONECHOICE {MENUITEM_CLONEMIN, MENUITEM_PRAVETS82=MENUITEM_CLONEMIN, MENUITEM_PRAVETS8M, MENUITEM_PRAVETS8A, MENUITEM_TK30002E, MENUITEM_BASE64A, MENUITEM_CLONEMAX};
|
||||
const TCHAR CPageAdvanced::m_CloneChoices[] =
|
||||
TEXT("Pravets 82\0") // Bulgarian
|
||||
TEXT("Pravets 8M\0") // Bulgarian
|
||||
TEXT("Pravets 8A\0") // Bulgarian
|
||||
TEXT("TK3000 //e\0"); // Brazilian
|
||||
TEXT("TK3000 //e\0") // Brazilian
|
||||
TEXT("Base 64A\0"); // Taiwanese
|
||||
|
||||
|
||||
BOOL CALLBACK CPageAdvanced::DlgProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
|
@ -223,6 +225,7 @@ eApple2Type CPageAdvanced::GetCloneType(DWORD NewMenuItem)
|
|||
case MENUITEM_PRAVETS8M: return A2TYPE_PRAVETS8M;
|
||||
case MENUITEM_PRAVETS8A: return A2TYPE_PRAVETS8A;
|
||||
case MENUITEM_TK30002E: return A2TYPE_TK30002E;
|
||||
case MENUITEM_BASE64A: return A2TYPE_BASE64A;
|
||||
default: return A2TYPE_PRAVETS82;
|
||||
}
|
||||
}
|
||||
|
@ -250,6 +253,7 @@ int CPageAdvanced::GetCloneMenuItem(void)
|
|||
case A2TYPE_PRAVETS8M: nMenuItem = MENUITEM_PRAVETS8M; break;
|
||||
case A2TYPE_PRAVETS8A: nMenuItem = MENUITEM_PRAVETS8A; break;
|
||||
case A2TYPE_TK30002E: nMenuItem = MENUITEM_TK30002E; break;
|
||||
case A2TYPE_BASE64A: nMenuItem = MENUITEM_BASE64A; break;
|
||||
default: // New clone needs adding here?
|
||||
_ASSERT(0);
|
||||
}
|
||||
|
|
|
@ -190,6 +190,7 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM
|
|||
case A2TYPE_PRAVETS8M: nCurrentChoice = MENUITEM_CLONE; break;
|
||||
case A2TYPE_PRAVETS8A: nCurrentChoice = MENUITEM_CLONE; break;
|
||||
case A2TYPE_TK30002E: nCurrentChoice = MENUITEM_CLONE; break;
|
||||
case A2TYPE_BASE64A: nCurrentChoice = MENUITEM_CLONE; break;
|
||||
default: _ASSERT(0); break;
|
||||
}
|
||||
|
||||
|
|
|
@ -263,6 +263,7 @@ static void GetAppleWindowTitle()
|
|||
case A2TYPE_PRAVETS8M: g_pAppTitle = TITLE_PRAVETS_8M ; break;
|
||||
case A2TYPE_PRAVETS8A: g_pAppTitle = TITLE_PRAVETS_8A ; break;
|
||||
case A2TYPE_TK30002E: g_pAppTitle = TITLE_TK3000_2E ; break;
|
||||
case A2TYPE_BASE64A: g_pAppTitle = TITLE_BASE64A ; break;
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
|
@ -386,6 +387,9 @@ static void CreateGdiObjects(void)
|
|||
case A2TYPE_TK30002E:
|
||||
buttonbitmap[BTN_RUN] = (HBITMAP)LOADBUTTONBITMAP(TEXT("RUN3000E_BUTTON"));
|
||||
break;
|
||||
case A2TYPE_BASE64A:
|
||||
buttonbitmap[BTN_RUN] = (HBITMAP)LOADBUTTONBITMAP(TEXT("RUNBASE64A_BUTTON"));
|
||||
break;
|
||||
default:
|
||||
buttonbitmap[BTN_RUN] = (HBITMAP)LOADBUTTONBITMAP(TEXT("RUN_BUTTON"));
|
||||
break;
|
||||
|
@ -1349,7 +1353,7 @@ LRESULT CALLBACK FrameWndProc (
|
|||
}
|
||||
else if (wparam == VK_F10)
|
||||
{
|
||||
if (g_Apple2Type == A2TYPE_APPLE2E || g_Apple2Type == A2TYPE_APPLE2EENHANCED)
|
||||
if (g_Apple2Type == A2TYPE_APPLE2E || g_Apple2Type == A2TYPE_APPLE2EENHANCED || g_Apple2Type == A2TYPE_BASE64A)
|
||||
{
|
||||
SetVideoRomRockerSwitch( !GetVideoRomRockerSwitch() ); // F10: toggle rocker switch
|
||||
NTSC_VideoInitAppleType();
|
||||
|
|
|
@ -77,6 +77,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#define SW_INTCXROM (memmode & MF_INTCXROM)
|
||||
#define SW_WRITERAM (memmode & MF_WRITERAM)
|
||||
#define SW_IOUDIS (memmode & MF_IOUDIS)
|
||||
#define SW_ALTROM0 (memmode & MF_ALTROM0)
|
||||
#define SW_ALTROM1 (memmode & MF_ALTROM1)
|
||||
|
||||
/*
|
||||
MEMORY MANAGEMENT SOFT SWITCHES
|
||||
|
@ -210,6 +212,8 @@ static LPBYTE g_pMemMainLanguageCard = NULL;
|
|||
static DWORD memmode = LanguageCardUnit::kMemModeInitialState;
|
||||
static BOOL modechanging = 0; // An Optimisation: means delay calling UpdatePaging() for 1 instruction
|
||||
|
||||
static UINT memrompages = 1;
|
||||
|
||||
static CNoSlotClock* g_NoSlotClock = new CNoSlotClock;
|
||||
static LanguageCardUnit* g_pLanguageCard = NULL; // For all Apple II, //e and above
|
||||
|
||||
|
@ -233,6 +237,15 @@ static SS_CARDTYPE g_MemTypeAppleIIPlus = CT_LanguageCard; // Keep a copy so it'
|
|||
static SS_CARDTYPE g_MemTypeAppleIIe = CT_Extended80Col; // Keep a copy so it's not lost if machine type changes, eg: A//e -> A][ -> A//e
|
||||
static UINT g_uSaturnBanksFromCmdLine = 0;
|
||||
|
||||
|
||||
const UINT CxRomSize = 4 * 1024;
|
||||
const UINT Apple2RomSize = 12 * 1024;
|
||||
const UINT Apple2eRomSize = Apple2RomSize + CxRomSize;
|
||||
//const UINT Pravets82RomSize = 12*1024;
|
||||
//const UINT Pravets8ARomSize = Pravets82RomSize+CxRomSize;
|
||||
const UINT MaxRomPages = 4;
|
||||
const UINT Base64ARomSize = MaxRomPages * Apple2RomSize;
|
||||
|
||||
// Called from MemLoadSnapshot()
|
||||
static void ResetDefaultMachineMemTypes(void)
|
||||
{
|
||||
|
@ -699,6 +712,11 @@ BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYT
|
|||
if (address >= 0xC05C && address <= 0xC05D && IsApple2JPlus(GetApple2Type()))
|
||||
NTSC_VideoInitAppleType(); // AN2 switches between Katakana & ASCII video rom chars (GH#773)
|
||||
|
||||
if (address >= 0xC058 && address <= 0xC05B && (g_Apple2Type == A2TYPE_BASE64A))
|
||||
{
|
||||
MemSetPaging(programcounter, address, write, value, nExecutedCycles);
|
||||
}
|
||||
|
||||
if (!write)
|
||||
return MemReadFloatingBus(nExecutedCycles);
|
||||
else
|
||||
|
@ -1132,12 +1150,14 @@ static void UpdatePaging(BOOL initialize)
|
|||
: pCxRomInternal+uRomOffset; // C800..CFFF - Internal ROM
|
||||
}
|
||||
|
||||
int selectedrompage = (SW_ALTROM0 ? 1 : 0) | (SW_ALTROM1 ? 2 : 0);
|
||||
int romoffset = (selectedrompage % memrompages) * Apple2RomSize;
|
||||
for (loop = 0xD0; loop < 0xE0; loop++)
|
||||
{
|
||||
int bankoffset = (SW_BANK2 ? 0 : 0x1000);
|
||||
memshadow[loop] = SW_HIGHRAM ? SW_ALTZP ? memaux+(loop << 8)-bankoffset
|
||||
: g_pMemMainLanguageCard+((loop-0xC0)<<8)-bankoffset
|
||||
: memrom+((loop-0xD0) * 0x100);
|
||||
: memrom+((loop-0xD0) * 0x100)+romoffset;
|
||||
|
||||
memwrite[loop] = SW_WRITERAM ? SW_HIGHRAM ? mem+(loop << 8)
|
||||
: SW_ALTZP ? memaux+(loop << 8)-bankoffset
|
||||
|
@ -1149,7 +1169,7 @@ static void UpdatePaging(BOOL initialize)
|
|||
{
|
||||
memshadow[loop] = SW_HIGHRAM ? SW_ALTZP ? memaux+(loop << 8)
|
||||
: g_pMemMainLanguageCard+((loop-0xC0)<<8)
|
||||
: memrom+((loop-0xD0) * 0x100);
|
||||
: memrom+((loop-0xD0) * 0x100)+romoffset;
|
||||
|
||||
memwrite[loop] = SW_WRITERAM ? SW_HIGHRAM ? mem+(loop << 8)
|
||||
: SW_ALTZP ? memaux+(loop << 8)
|
||||
|
@ -1429,19 +1449,13 @@ bool MemIsAddrCodeMemory(const USHORT addr)
|
|||
|
||||
//===========================================================================
|
||||
|
||||
const UINT CxRomSize = 4*1024;
|
||||
const UINT Apple2RomSize = 12*1024;
|
||||
const UINT Apple2eRomSize = Apple2RomSize+CxRomSize;
|
||||
//const UINT Pravets82RomSize = 12*1024;
|
||||
//const UINT Pravets8ARomSize = Pravets82RomSize+CxRomSize;
|
||||
|
||||
void MemInitialize()
|
||||
{
|
||||
// ALLOCATE MEMORY FOR THE APPLE MEMORY IMAGE AND ASSOCIATED DATA STRUCTURES
|
||||
memaux = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
||||
memmain = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE);
|
||||
memdirty = (LPBYTE)VirtualAlloc(NULL,0x100 ,MEM_COMMIT,PAGE_READWRITE);
|
||||
memrom = (LPBYTE)VirtualAlloc(NULL,0x5000 ,MEM_COMMIT,PAGE_READWRITE);
|
||||
memrom = (LPBYTE)VirtualAlloc(NULL,0x3000 * MaxRomPages ,MEM_COMMIT,PAGE_READWRITE);
|
||||
memimage = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_RESERVE,PAGE_NOACCESS);
|
||||
|
||||
pCxRomInternal = (LPBYTE) VirtualAlloc(NULL, CxRomSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
@ -1522,6 +1536,7 @@ void MemInitializeROM(void)
|
|||
case A2TYPE_PRAVETS8M: hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_PRAVETS_8M_ROM ), "ROM"); ROM_SIZE = Apple2RomSize ; break;
|
||||
case A2TYPE_PRAVETS8A: hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_PRAVETS_8C_ROM ), "ROM"); ROM_SIZE = Apple2eRomSize; break;
|
||||
case A2TYPE_TK30002E: hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_TK3000_2E_ROM ), "ROM"); ROM_SIZE = Apple2eRomSize; break;
|
||||
case A2TYPE_BASE64A: hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_BASE_64A_ROM ), "ROM"); ROM_SIZE = Base64ARomSize; break;
|
||||
}
|
||||
|
||||
if (hResInfo == NULL)
|
||||
|
@ -1538,6 +1553,7 @@ void MemInitializeROM(void)
|
|||
case A2TYPE_PRAVETS8M: _tcscpy(sRomFileName, TEXT("PRAVETS8M.ROM" )); break;
|
||||
case A2TYPE_PRAVETS8A: _tcscpy(sRomFileName, TEXT("PRAVETS8C.ROM" )); break;
|
||||
case A2TYPE_TK30002E: _tcscpy(sRomFileName, TEXT("TK3000e.ROM" )); break;
|
||||
case A2TYPE_BASE64A: _tcscpy(sRomFileName, TEXT("BASE64A.ROM" )); break;
|
||||
default:
|
||||
{
|
||||
_tcscpy(sRomFileName, TEXT("Unknown type!"));
|
||||
|
@ -1581,8 +1597,9 @@ void MemInitializeROM(void)
|
|||
ROM_SIZE -= CxRomSize;
|
||||
}
|
||||
|
||||
_ASSERT(ROM_SIZE == Apple2RomSize);
|
||||
memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF
|
||||
memrompages = MAX(MaxRomPages, ROM_SIZE / Apple2RomSize);
|
||||
_ASSERT(ROM_SIZE % Apple2RomSize == 0);
|
||||
memcpy(memrom, pData, ROM_SIZE); // ROM at $D000...$FFFF, one or several pages
|
||||
}
|
||||
|
||||
void MemInitializeCustomF8ROM(void)
|
||||
|
@ -2045,6 +2062,17 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE
|
|||
}
|
||||
}
|
||||
|
||||
if (g_Apple2Type == A2TYPE_BASE64A)
|
||||
{
|
||||
switch (address)
|
||||
{
|
||||
case 0x58: SetMemMode(memmode & ~MF_ALTROM0); break;
|
||||
case 0x59: SetMemMode(memmode | MF_ALTROM0); break;
|
||||
case 0x5A: SetMemMode(memmode & ~MF_ALTROM1); break;
|
||||
case 0x5B: SetMemMode(memmode | MF_ALTROM1); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (MemOptimizeForModeChanging(programcounter, address))
|
||||
return write ? 0 : MemReadFloatingBus(nExecutedCycles);
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#define MF_INTCXROM 0x00000200
|
||||
#define MF_WRITERAM 0x00000400 // Language Card RAM is Write Enabled
|
||||
#define MF_IOUDIS 0x00000800 // Disable IOU access for addresses $C058 to $C05F; enable access to DHIRES switch (0=on) (Enhanced //e only)
|
||||
#define MF_ALTROM0 0x00001000 // Use alternate ROM for $D000 to $FFFF. Two bits for up to 4 pages
|
||||
#define MF_ALTROM1 0x00002000 // Use alternate ROM, second bit to have four pages
|
||||
#define MF_IMAGEMASK 0x000003F7
|
||||
#define MF_LANGCARD_MASK (MF_WRITERAM|MF_HIGHRAM|MF_BANK2)
|
||||
|
||||
|
|
|
@ -457,6 +457,7 @@ static void set_csbits()
|
|||
case A2TYPE_PRAVETS8M: csbits = &csbits_pravets8M[0]; g_nVideoCharSet = 0; break; // Apple ][ clone
|
||||
case A2TYPE_PRAVETS8A: csbits = &csbits_pravets8C[0]; break; // Apple //e clone
|
||||
case A2TYPE_TK30002E: csbits = &csbits_enhanced2e[0]; break; // Enhanced Apple //e clone
|
||||
case A2TYPE_BASE64A: csbits = &csbits_base64a[GetVideoRomRockerSwitch() ? 0 : 1]; g_nVideoCharSet = 0; break; // Apple ][ clone
|
||||
default: _ASSERT(0); csbits = &csbits_enhanced2e[0]; break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ unsigned char csbits_a2j[2][256][8]; // ][J-Plus
|
|||
unsigned char csbits_pravets82[1][256][8]; // Pravets 82
|
||||
unsigned char csbits_pravets8M[1][256][8]; // Pravets 8M
|
||||
unsigned char csbits_pravets8C[2][256][8]; // Pravets 8A & 8C
|
||||
unsigned char csbits_base64a[2][256][8]; // Base 64A
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
@ -179,15 +181,15 @@ static void userVideoRomForIIe(void)
|
|||
|
||||
//-------------------------------------
|
||||
|
||||
static void userVideoRom2K(csbits_t csbits, const BYTE* pVideoRom, const bool isApple2JPlus=false, const int AN2=0);
|
||||
static void userVideoRom2K(csbits_t csbits, const BYTE* pVideoRom, eApple2Type type = A2TYPE_APPLE2, const int AN2=0);
|
||||
|
||||
static void userVideoRom2K(csbits_t csbits, const BYTE* pVideoRom, const bool isApple2JPlus/*=false*/, const int AN2/*=0*/)
|
||||
static void userVideoRom2K(csbits_t csbits, const BYTE* pVideoRom, const eApple2Type type /*= A2TYPE_APPLE2*/, const int AN2/*=0*/)
|
||||
{
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
int RA = i*8; // rom address
|
||||
|
||||
if (isApple2JPlus)
|
||||
if (type == A2TYPE_APPLE2JPLUS)
|
||||
{
|
||||
// AN2=0: $00-3F, $00-3F; $80-BF, $80-BF => KKAA (Repeat Katakana)
|
||||
// AN2=1: $40-7F, $40-7F; $C0-FF, $C0-FF => AAAA (Repeat ASCII)
|
||||
|
@ -202,16 +204,33 @@ static void userVideoRom2K(csbits_t csbits, const BYTE* pVideoRom, const bool is
|
|||
// UTAII:8-30 "Bit 7 of your EPROM fonts will control flashing in the lower 1024 bytes of the EPROM"
|
||||
// UTAII:8-31 "If you leave O7 (EPROM Output7) reset in these patterns, the resulting characters will be inversions..."
|
||||
// Apple II J-Plus: simplest logic is just invert if reading low 1K of video ROM
|
||||
// Base64A: Bit 0 instead of bit 7
|
||||
if (RA < 1024)
|
||||
{
|
||||
if (!(n & 0x80) || isApple2JPlus)
|
||||
n = n ^ 0x7f;
|
||||
if (type == A2TYPE_BASE64A)
|
||||
{
|
||||
if (!(n & 0x01))
|
||||
n = n ^ 0xfe;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(n & 0x80) || (type == A2TYPE_APPLE2JPLUS))
|
||||
n = n ^ 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
// UTAII:8-30 "TEXT ROM pattern is ... reversed"
|
||||
BYTE d = 0;
|
||||
for (BYTE j=0; j<7; j++, n >>= 1) // Just bits [0..6]
|
||||
d = (d << 1) | (n & 1);
|
||||
if (type == A2TYPE_BASE64A)
|
||||
{
|
||||
// On the Base 64A bits are ordered 1345672.
|
||||
d = (n >> 2) | ((n & 2) >> 1) | ((n & 4) << 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// UTAII:8-30 "TEXT ROM pattern is ... reversed"
|
||||
for (BYTE j = 0; j < 7; j++, n >>= 1) // Just bits [0..6]
|
||||
d = (d << 1) | (n & 1);
|
||||
}
|
||||
|
||||
csbits[0][i][y] = d;
|
||||
}
|
||||
|
@ -248,10 +267,33 @@ static void VideoRomForIIJPlus(void)
|
|||
if (pVideoRom == NULL)
|
||||
return;
|
||||
|
||||
userVideoRom2K(&csbits_a2j[0], pVideoRom, true, 0);
|
||||
userVideoRom2K(&csbits_a2j[1], pVideoRom, true, 1);
|
||||
userVideoRom2K(&csbits_a2j[0], pVideoRom, A2TYPE_APPLE2JPLUS, 0);
|
||||
userVideoRom2K(&csbits_a2j[1], pVideoRom, A2TYPE_APPLE2JPLUS, 1);
|
||||
}
|
||||
|
||||
static void VideoRomForBase64A(void)
|
||||
{
|
||||
HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_BASE64A_VIDEO_ROM), "ROM");
|
||||
if (hResInfo == NULL)
|
||||
return;
|
||||
|
||||
DWORD dwResSize = SizeofResource(NULL, hResInfo);
|
||||
if (dwResSize != kVideoRomSize4K)
|
||||
return;
|
||||
|
||||
HGLOBAL hResData = LoadResource(NULL, hResInfo);
|
||||
if (hResData == NULL)
|
||||
return;
|
||||
|
||||
BYTE* pVideoRom = (BYTE*)LockResource(hResData); // NB. Don't need to unlock resource
|
||||
if (pVideoRom == NULL)
|
||||
return;
|
||||
|
||||
userVideoRom2K(&csbits_base64a[0], pVideoRom, A2TYPE_BASE64A, 0);
|
||||
userVideoRom2K(&csbits_base64a[1], pVideoRom + kVideoRomSize2K, A2TYPE_BASE64A, 0);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void make_csbits(void)
|
||||
|
@ -269,6 +311,7 @@ void make_csbits(void)
|
|||
memcpy(&csbits_2e[1][64], &csbits_2e[0][64], 32*8);
|
||||
|
||||
VideoRomForIIJPlus(); // GH#773
|
||||
VideoRomForBase64A(); // GH#806
|
||||
|
||||
// Try to use any user-provided video ROM for Original/Enhanced //e
|
||||
userVideoRomForIIe();
|
||||
|
|
|
@ -8,6 +8,8 @@ extern unsigned char csbits_a2j[2][256][8]; // ][J-Plus
|
|||
extern unsigned char csbits_pravets82[1][256][8]; // Pravets 82
|
||||
extern unsigned char csbits_pravets8M[1][256][8]; // Pravets 8M
|
||||
extern unsigned char csbits_pravets8C[2][256][8]; // Pravets 8A & 8C
|
||||
extern unsigned char csbits_base64a[2][256][8]; // Base64A
|
||||
|
||||
|
||||
void make_csbits(void);
|
||||
csbits_t Get2e_csbits(void);
|
||||
|
|
|
@ -155,6 +155,7 @@ static std::string GetSnapshotUnitMiscName(void)
|
|||
#define SS_YAML_VALUE_PRAVETS8M "Pravets8M"
|
||||
#define SS_YAML_VALUE_PRAVETS8A "Pravets8A"
|
||||
#define SS_YAML_VALUE_TK30002E "TK3000//e"
|
||||
#define SS_YAML_VALUE_BASE64A "Base 64A"
|
||||
|
||||
static eApple2Type ParseApple2Type(std::string type)
|
||||
{
|
||||
|
@ -168,6 +169,7 @@ static eApple2Type ParseApple2Type(std::string type)
|
|||
else if (type == SS_YAML_VALUE_PRAVETS8M) return A2TYPE_PRAVETS8M;
|
||||
else if (type == SS_YAML_VALUE_PRAVETS8A) return A2TYPE_PRAVETS8A;
|
||||
else if (type == SS_YAML_VALUE_TK30002E) return A2TYPE_TK30002E;
|
||||
else if (type == SS_YAML_VALUE_BASE64A) return A2TYPE_BASE64A;
|
||||
|
||||
throw std::string("Load: Unknown Apple2 type");
|
||||
}
|
||||
|
@ -186,6 +188,7 @@ static std::string GetApple2TypeAsString(void)
|
|||
case A2TYPE_PRAVETS8M: return SS_YAML_VALUE_PRAVETS8M;
|
||||
case A2TYPE_PRAVETS8A: return SS_YAML_VALUE_PRAVETS8A;
|
||||
case A2TYPE_TK30002E: return SS_YAML_VALUE_TK30002E;
|
||||
case A2TYPE_BASE64A: return SS_YAML_VALUE_BASE64A;
|
||||
default:
|
||||
throw std::string("Save: Unknown Apple2 type");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue