Appalm/palmapple/memory.c
2019-04-21 06:53:32 -07:00

900 lines
24 KiB
C

#include "6502.h"
#include "memory.h"
#include "iou.h"
#define LOW_BYTE 1
#define HIGH_BYTE 0
#define SET(x, y) IOUState[y] = (IOUSoftSwitch[y] = IOUSoftSwitch[y] | (x))
#define RESET(x, y) IOUState[y] = (IOUSoftSwitch[y] = IOUSoftSwitch[y] &~ (x))
UInt8 *AppleMemory;
UInt8 *AuxMemory;
UInt8 *TempMemory;
UInt8 *AppleROM;
extern union PCStruct Address;
extern UInt8 *address_line[0x700];
extern char *AppleFontBitmap;
extern BOOL LOOP;
extern BOOL QUIT;
BOOL LOOP1 = 1;
extern UInt16 AppleClock;
extern UInt16 DiskOffset;
UInt16 LastAppleClock = 0;
UInt8 BootROM[256];
UInt8 BootImage[256];
UInt8 SlotROMStatus = 0;
UInt8 LastKey = 0;
UInt16 IOUSoftSwitch[2] = {0, 0};
UInt16 IOUState[2] = {0, 0};
UInt8 address_latch, data_latch, C800ROMSlot;
EventType event;
/* Apple IO Read */
UInt8 RIOM();
/* SLOT 5 IO Read */
UInt8 SLT5();
/* SLOT 6 IO Read */
UInt8 SLT6();
/* Apple IO Write */
void WIOM(UInt8 value);
/* Screen Write */
void WSCM(UInt8 value);
/* Protect ROM */
void READONLY(UInt8 value);
/* Aux Memory Read Write */
UInt8 AuxRead();
void AuxWrite(UInt8 value);
UInt8 REXP();
UInt8 RC3M();
void LoadROM();
void toggleLanguageCard();
#define NO_OF_PHASES 8
#define MAX_PHYSICAL_TRACK_NO (40*NO_OF_PHASES)
#define RAW_TRACK_BYTES 6392
static Int8 stepper_movement_table[16][NO_OF_PHASES] = {
{ 0, 0, 0, 0, 0, 0, 0, 0 }, /* all electromagnets off */
{ 0, -1, -2, -3, 0, 3, 2, 1 }, /* EM 1 on */
{ 2, 1, 0, -1, -2, -3, 0, 3 }, /* EM 2 on */
{ 1, 0, -1, -2, -3, 0, 3, 2 }, /* EMs 1 & 2 on */
{ 0, 3, 2, 1, 0, -1, -2, -3 }, /* EM 3 on */
{ 0, -1, 0, 1, 0, -1, 0, 1 }, /* EMs 1 & 3 on */
{ 3, 2, 1, 0, -1, -2, -3, 0 }, /* EMs 2 & 3 on */
{ 2, 1, 0, -1, -2, -3, 0, 3 }, /* EMs 1, 2 & 3 on */
{ -2, -3, 0, 3, 2, 1, 0, -1 }, /* EM 4 on */
{ -1, -2, -3, 0, 3, 2, 1, 0 }, /* EMs 1 & 4 on */
{ 0, 1, 0, -1, 0, 1, 0, -1 }, /* EMs 2 & 4 */
{ 0, -1, -2, -3, 0, 3, 2, 1 }, /* EMs 1, 2 & 4 on */
{ -3, 0, 3, 2, 1, 0, -1, -2 }, /* EMs 3 & 4 on */
{ -2, -3, 0, 3, 2, 1, 0, -1 }, /* EMs 1, 3 & 4 on */
{ 0, 3, 2, 1, 0, -1, -2, -3 }, /* EMs 2, 3 & 4 on */
{ 0, 0, 0, 0, 0, 0, 0, 0 } }; /* all electromagnets on */
static DmOpenRef diskimage;
UInt16 motor_on;
static Int16 physical_track_no;
static Int16 stepper_status;
static UInt16 read_count = 0;
static Int8 track_buffer_valid=0;
static Int8 track_buffer_dirty=0;
static Int8 track_buffer_track=0;
static Int8 write_mode;
static Int16 last_track = -1;
static UInt8 nibble[RAW_TRACK_BYTES];
static UInt16 position;
static UInt8 write_protect;
static DmOpenRef romDB;
static UInt8* values;
static MemHandle value;
static LocalID rom;
UInt8 logical_track;
void toggleStepper();
void toggleMotor();
UInt8 read_nibble();
void load_track_buffer(void);
int mount_disk( int slot, int drive );
/* Read Operation of Memory Page Mapping */
READBYTE ReadFunction[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F*/
/* 00 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 10 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 20 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 30 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 40 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 50 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 60 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 70 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 80 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 90 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* A0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* B0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* C0 */ RIOM, NULL, NULL, RC3M, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* D0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* E0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* F0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
WRITEBYTE WriteFunction[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F*/
/* 00 */ NULL, NULL, NULL, NULL, WSCM, WSCM, WSCM, WSCM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 10 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 20 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 30 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 40 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 50 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 60 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 70 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 80 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* 90 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* A0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* B0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* C0 */ WIOM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* D0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* E0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/* F0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
void init_memory(void) {
FtrPtrNew('Pala', 0, 65536, (void**) &AppleMemory);
MemSet(AppleMemory, 65535, 0);
FtrPtrNew('Pala', 1, 65536, (void**) &AuxMemory);
MemSet(AuxMemory, 65535, 0);
FtrPtrNew('Pala', 2, 4096, (void**) &TempMemory);
MemSet(TempMemory, 4096, 0);
LoadROM();
{
UInt16 count;
for (count = 0xD0; count < 0x100; count++) {
WriteFunction[count] = READONLY;
}
}
C800ROMSlot = 0;
}
void LoadROM(void) {
DmOpenRef romDB;
LocalID romID;
MemHandle romRec;
UInt8* roms;
UInt32 romStart, memStart;
MemHandle handle;
romID = DmFindDatabase(0, "apple2e.rom");
romDB = DmOpenDatabase(0, romID, dmModeReadOnly);
romRec = DmQueryRecord(romDB, 0);
roms = (UInt8 *) MemHandleLock(romRec);
romStart = 0x004100; memStart = 0x00C100;
handle = MemHandleNew(0x3F00);
AppleROM = (UInt8*) MemHandleLock(handle);
MemMove(AppleMemory + memStart, roms + romStart, 0x3F00);
MemMove(AppleROM, roms + romStart, 0x3F00);
MemHandleUnlock(romRec);
DmCloseDatabase(romDB);
romID = DmFindDatabase(0, "slot6.rom");
romDB = DmOpenDatabase(0, romID, dmModeReadOnly);
romRec = DmQueryRecord(romDB, 0);
roms = (UInt8 *) MemHandleLock(romRec);
MemMove(BootROM, roms, 256);
MemHandleUnlock(romRec);
DmCloseDatabase(romDB);
physical_track_no = 0;
mount_disk(6, 0);
position = 0; last_track = -1;
BootROM[0x004C] = 0xA9;
BootROM[0x004D] = 0x00;
BootROM[0x004E] = 0xEA;
}
/* Apple ROM Paging */
UInt8 RRMP() {
return 0x00;
}
UInt8 readKey() {
if (EvtEventAvail()) {
EvtGetEvent(&event, 0);
SysHandleEvent(&event);
if (event.eType == appStopEvent) {
QUIT = 0;
return LastKey;
}
if (event.eType == keyDownEvent) {
UInt8 key;
key = (event.data.keyDown.chr == 10 ? 13 : event.data.keyDown.chr) | 0x80;
// if (event.data.keyDown.chr == 10) LOOP = 0;
return key;
}
}
return LastKey;
}
/* Apple Soft Switch Read */
UInt8 readSoftSwitch()
{
UInt16 flag;
UInt8 data;
static UInt16 soft_switch_list[16] = {
0 /* key strobe */, SS_LCBNK2, SS_LCRAM, SS_RAMRD,
SS_RAMWRT, SS_SLOTCXROM, SS_ALTZP, SS_SLOTC3ROM,
SS_80STORE, 0 /* VBL */, SS_TEXT, SS_MIXED,
SS_PAGE2, SS_HIRES, SS_ALTCHAR, SS_80COL };
data = 0;
flag = soft_switch_list[Address.Byte[LOW_BYTE] & 0x0F];
if (flag) {
data = (flag & IOUSoftSwitch[0])? data | 0x80 : data & 0x7f;
} else {
if (Address.PC == KBDSTRB) {
LastKey &= 0x7F;
LastKey = readKey();
return LastKey;
} else if (Address.PC == RDVBLBAR) {
data = (SS_VBLBAR & IOUSoftSwitch[1])? data | 0x80 : data & 0x7f;
}
}
return data;
}
UInt8 REXP() {
if (!(IOUState[0] & SS_SLOTCXROM) && Address.PC == 0xCFFF) {
// MemMove(AppleMemory + 0xCD00, BootROM, 256);
MemMove(AppleMemory + 0xCE00, BootROM, 256);
RESET(SS_EXPNROM, 1);
return 0x00;
} else {
return AppleMemory[Address.PC];
}
}
UInt8 RC3M() {
if (!(IOUSoftSwitch[0] & SS_SLOTC3ROM)) {
if (C800ROMSlot == 0) {
C800ROMSlot = 3;
SET(SS_EXPNROM, 1);
}
MemMove(AppleMemory + 0xC800, AppleROM + 0x700, 2048);
}
return AppleMemory[Address.PC];
}
void toggleVideoSoftSwitch() {
UInt8 vswitch = Address.Byte[LOW_BYTE] & 0x0F;
switch (vswitch) {
case 0x00:
RESET(SS_TEXT, 0);
break;
case 0x01:
SET(SS_TEXT, 0);
RESET(SS_HIRES, 0);
break;
case 0x04:
if (IOUSoftSwitch[0] & SS_PAGE2){
RESET(SS_PAGE2, 0);
if (IOUSoftSwitch[0] & SS_80STORE) {
ReadFunction[0x04] = NULL;
ReadFunction[0x05] = NULL;
ReadFunction[0x06] = NULL;
ReadFunction[0x07] = NULL;
WriteFunction[0x04] = NULL;
WriteFunction[0x05] = NULL;
WriteFunction[0x06] = NULL;
WriteFunction[0x07] = NULL;
}
}
break;
case 0x05:
if (!(IOUSoftSwitch[0] & SS_PAGE2)){
SET(SS_PAGE2, 0);
if (IOUSoftSwitch[0] & SS_80STORE) {
ReadFunction[0x04] = RRMP;
ReadFunction[0x05] = RRMP;
ReadFunction[0x06] = RRMP;
ReadFunction[0x07] = RRMP;
WriteFunction[0x04] = READONLY;
WriteFunction[0x05] = READONLY;
WriteFunction[0x06] = READONLY;
WriteFunction[0x07] = READONLY;
}
}
break;
case 0x06:
if (IOUSoftSwitch[0] & SS_HIRES)
RESET(SS_HIRES, 0);
break;
case 0x07:
if (!(IOUSoftSwitch[0] & SS_HIRES)) {
SET(SS_HIRES, 0);
RESET(SS_TEXT, 0);
}
break;
}
}
void toggleMemorySoftSwitch(UInt8 data) {
UInt8 Page;
switch (Address.PC) {
case SETSLOTCXROM:
RESET(SS_SLOTCXROM, 0);
for (Page = 0xC1; Page < 0xC8; Page++) if (Page != 0xC3) ReadFunction[Page] = RRMP;
MemSet(AppleMemory + 0xC100, 512, 0);
MemSet(AppleMemory + 0xC400, 1024, 0);
ReadFunction[0xC6] = NULL;
MemMove(AppleMemory + 0x00C600, BootROM, 256);
break;
case SETINTCXROM:
SET(SS_SLOTCXROM, 0);
for (Page = 0xC1; Page < 0xC8; Page++) if (Page != 0xC3) ReadFunction[Page] = NULL;
MemMove(AppleMemory + 0xC100, AppleROM, 512);
MemMove(AppleMemory + 0xC400, AppleROM + 0x300, 1024);
break;
case SETSTDZP:
break;
case SETALTZP:
break;
case SETINTC3ROM:
MemMove(AppleMemory + 0xC300, AppleROM + 0x200, 256);
SET(SS_SLOTC3ROM, 0);
break;
case SETSLOTC3ROM:
MemSet(AppleMemory + 0xC300, 256, 0);
RESET(SS_SLOTC3ROM, 0);
break;
case RDMAINRAM:
if (IOUSoftSwitch[0] & SS_RAMRD){
RESET(SS_RAMRD, 0);
}
break;
case RDCARDRAM:
SET(SS_RAMRD, 0);
break;
case WRMAINRAM:
RESET(SS_RAMWRT, 0);
break;
case WRCARDRAM:
SET(SS_RAMWRT, 0);
break;
case CLR80STORE:
if (IOUSoftSwitch[0] & SS_80STORE) {
RESET(SS_80STORE, 0);
}
break;
case SET80STORE:
if (!(IOUSoftSwitch[0] & SS_80STORE)) {
SET(SS_80STORE, 0);
}
break;
}
if (IOUState[0] & SS_RAMRD) {
UInt16 Page;
for (Page = 0x02; Page < 0xC0; Page++) ReadFunction[Page] = RRMP;
} else {
UInt16 Page;
for (Page = 0x02; Page < 0xC0; Page++) ReadFunction[Page] = NULL;
}
if (IOUState[0] & SS_RAMWRT) {
UInt16 Page;
for (Page = 0x02; Page < 0xC0; Page++) WriteFunction[Page] = READONLY;
} else {
UInt16 Page;
for (Page = 0x02; Page < 0xC0; Page++) WriteFunction[Page] = NULL;
}
}
/* Apple IO Read */
UInt8 RIOM() {
UInt8 value, soft;
value = 0x00;
// soft = (UInt8) (Address.Byte[LOW_BYTE] & (UInt8) (0xF0));
switch (Address.Byte[LOW_BYTE]) {
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0A: case 0x0B:
case 0x0C: case 0x0D: case 0x0E: case 0x0F:
LastKey = readKey();
value = LastKey;
break;
case 0x10: case 0x11: case 0x12: case 0x13:
case 0x14: case 0x15: case 0x16: case 0x17:
case 0x18: case 0x19: case 0x1A: case 0x1B:
case 0x1C: case 0x1D: case 0x1E: case 0x1F:
value = readSoftSwitch();
break;
case 0x20: case 0x21: case 0x22: case 0x23:
case 0x24: case 0x25: case 0x26: case 0x27:
case 0x28: case 0x29: case 0x2A: case 0x2B:
case 0x2C: case 0x2D: case 0x2E: case 0x2F:
case 0x30: case 0x31: case 0x32: case 0x33:
case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: case 0x3A: case 0x3B:
case 0x3C: case 0x3D: case 0x3E: case 0x3F:
case 0x40: case 0x41: case 0x42: case 0x43:
case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4A: case 0x4B:
case 0x4C: case 0x4D: case 0x4E: case 0x4F:
break;
case 0x50: case 0x51: case 0x52: case 0x53:
case 0x54: case 0x55: case 0x56: case 0x57:
case 0x58: case 0x59: case 0x5A: case 0x5B:
case 0x5C: case 0x5D: case 0x5E: case 0x5F:
toggleVideoSoftSwitch();
break;
case 0x60: case 0x61: case 0x62: case 0x63:
case 0x64: case 0x65: case 0x66: case 0x67:
case 0x68: case 0x69: case 0x6A: case 0x6B:
case 0x6C: case 0x6D: case 0x6E: case 0x6F:
case 0x70: case 0x71: case 0x72: case 0x73:
case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7A: case 0x7B:
case 0x7C: case 0x7D: case 0x7E: case 0x7F:
break;
/* Slot 0 */
case 0x80: case 0x81: case 0x82: case 0x83:
case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8A: case 0x8B:
case 0x8C: case 0x8D: case 0x8E: case 0x8F:
toggleLanguageCard();
break;
/* Slot 1 */
case 0x90: case 0x91: case 0x92: case 0x93:
case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9A: case 0x9B:
case 0x9C: case 0x9D: case 0x9E: case 0x9F:
break;
/* Slot 2 */
case 0xA0: case 0xA1: case 0xA2: case 0xA3:
case 0xA4: case 0xA5: case 0xA6: case 0xA7:
case 0xA8: case 0xA9: case 0xAA: case 0xAB:
case 0xAC: case 0xAD: case 0xAE: case 0xAF:
break;
/* Slot 3 */
case 0xB0: case 0xB1: case 0xB2: case 0xB3:
case 0xB4: case 0xB5: case 0xB6: case 0xB7:
case 0xB8: case 0xB9: case 0xBA: case 0xBB:
case 0xBC: case 0xBD: case 0xBE: case 0xBF:
break;
/* Slot 4 */
case 0xC0: case 0xC1: case 0xC2: case 0xC3:
case 0xC4: case 0xC5: case 0xC6: case 0xC7:
case 0xC8: case 0xC9: case 0xCA: case 0xCB:
case 0xCC: case 0xCD: case 0xCE: case 0xCF:
break;
/* Slot 5 */
case 0xD0: case 0xD1: case 0xD2: case 0xD3:
case 0xD4: case 0xD5: case 0xD6: case 0xD7:
case 0xD8: case 0xD9: case 0xDA: case 0xDB:
case 0xDC: case 0xDD: case 0xDE: case 0xDF:
break;
/* Slot 6 */
case 0xEC:
/* if ( address_latch == 0x0E ) */
/* write_mode = 0; */
/* else if ( address_latch == 0x0F ) */
/* write_mode = 1; */
/* if ( !write_mode ) */
/* value = read_nibble(); */
/* AppleMemory[Address.PC] = value; */
value = nibble[position++];
if ( position >= RAW_TRACK_BYTES ) position = 0;
address_latch = 0x0C;
break;
case 0xED:
address_latch = 0x0D;
break;
case 0xEE:
address_latch = 0x0E;
if ( address_latch == 0x0D ) /* check write protect */
value = 0xFF;
break;
case 0xEF:
address_latch = 0x0F;
break;
case 0xE8: /* motor off */
case 0xE9: /* motor on */
toggleMotor();
break;
case 0xEA: /* select driver 1 */
case 0xEB: /* select driver 2 */
break;
/* C0X0-C0X7, stepper toggle */
case 0xE0: case 0xE1: case 0xE2: case 0xE3:
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
toggleStepper( );
break;
/* Slot 7 */
case 0xF0: case 0xF1: case 0xF2: case 0xF3:
case 0xF4: case 0xF5: case 0xF6: case 0xF7:
case 0xF8: case 0xF9: case 0xFA: case 0xFB:
case 0xFC: case 0xFD: case 0xFE: case 0xFF:
break;
}
return value;
}
/* SLOT 5 IO Read */
UInt8 SLT5() {
Char buf[20];
StrPrintF(buf, "Boot : %4X", Address.PC);
WinDrawChars(buf, StrLen(buf), 50, 0);
return BootROM[Address.Byte[LOW_BYTE]];
}
/* SLOT 6 IO Read */
UInt8 SLT6() {
Char buf[20];
StrPrintF(buf, "Boot : %4X", Address.PC);
WinDrawChars(buf, StrLen(buf), 50, 0);
return BootROM[Address.Byte[LOW_BYTE]];
}
/* Apple IO Write */
void WIOM(UInt8 value) {
AppleMemory[Address.PC] = value;
switch ((UInt8) (Address.Byte[LOW_BYTE] & (UInt8) (0xF0))) {
case 0x00:
toggleMemorySoftSwitch(value);
/* HostTraceOutputTL(sysErrorClass, "Write Soft Card : %X %X", Address.PC, value); */
break;
case 0x10:
if (Address.PC == KBDSTRB)
LastKey &= 0x7F;
break;
case 0x20: case 0x30: case 0x40:
break;
case 0x50:
toggleVideoSoftSwitch();
/* HostTraceOutputTL(sysErrorClass, "Write Video Card : %X", Address.PC); */
break;
case 0x60: case 0x70:
break;
case 0x80: /* Slot 0 */
toggleLanguageCard();
/* HostTraceOutputTL(sysErrorClass, "Write Language Card : %X %X", Address.PC, value); */
break;
case 0x90: /* Slot 1 */
break;
case 0xA0: /* Slot 2 */
break;
case 0xB0: /* Slot 3 */
break;
case 0xC0: /* Slot 4 */
break;
case 0xD0: /* Slot 5 */
break;
case 0xE0: /* Slot 6 */
switch ((UInt8) (Address.Byte[LOW_BYTE] & (UInt8) (0x0F))) {
case 0x0C:
if ( address_latch == 0x0E )
write_mode = 0;
else if ( address_latch == 0x0F )
write_mode = 1;
address_latch = 0x0C;
return;
case 0x0D:
address_latch = 0x0D;
break;
case 0x0E:
if ( address_latch == 0x0D ) { /* check write protect */
address_latch = 0x0E;
return;
}
address_latch = 0x0E;
break;
case 0x0F:
address_latch = 0x0F;
break;
case 0x08: /* motor off */
case 0x09: /* motor on */
toggleMotor();
break;
case 0x0A: /* select driver 1 */
case 0x0B: /* select driver 2 */
break;
default: /* C0X0-C0X7, stepper toggle */
toggleStepper( );
break;
}
}
}
UInt8 AuxRead() {
UInt8 value;
if ((IOUState[0] & SS_LCRAMRD))
value = AuxMemory[Address.PC - ((!(IOUState[0] & SS_LCBNK2) && Address.PC < 0xE000) ? 0x1000 : 0x000)];
else
value = AppleMemory[Address.PC];
return value;
}
void AuxWrite(UInt8 value) {
AuxMemory[Address.PC - ((!(IOUState[0] & SS_LCBNK2) && Address.PC < 0xE000) ? 0x1000 : 0x000)] = value;
AppleMemory[Address.PC] = value;
}
void READONLY(UInt8 data) {
return;
}
/* Screen Write */
void WSCM(UInt8 data) {
AppleMemory[Address.PC] = data;
/*
{
UInt8 *line, value;
UInt16 count, count1, count2, value1;
value = data;
if (value < 0xE0) value &= 0x3F;
if (value >= 0xE0) value = value - 0xA0;
count1 = value << 3; count2 = count1 + 8;
if ((Address.PC - 0x400) < 0x800) {
line = address_line[Address.PC - 0x400];
value1 = 0;
for (count = count1; count < count2; count++) {
line[value1] = ~AppleFontBitmap[count];
value1 += 40;
}
}
}
*/
}
void toggleStepper()
{
register Int16 magnet, on, old_track_no, new_status,phase;
magnet = (Address.Byte[LOW_BYTE] & 0x0E) >> 1;
on = Address.Byte[LOW_BYTE] & 0x01;
old_track_no = physical_track_no;
if ( on )
stepper_status |= (1<<magnet);
else
stepper_status &= ~(1<<magnet);
if ( motor_on ) {
new_status = stepper_status;
phase = physical_track_no & 0x07;
physical_track_no += stepper_movement_table[new_status][phase];
if ( physical_track_no < 0 ) {
physical_track_no = 0;
}
else if ( physical_track_no >= MAX_PHYSICAL_TRACK_NO )
physical_track_no = MAX_PHYSICAL_TRACK_NO-1;
track_buffer_valid = 0;
}
if ( !track_buffer_valid ) {
load_track_buffer();
}
}
void toggleMotor( )
{
int on;
on = Address.Byte[LOW_BYTE] & 0x01;
if ( motor_on != on ) {
WinDrawChars("I", 1, 10, 150);
motor_on = on;
} else {
WinDrawChars(" ", 1, 10, 150);
}
}
UInt8 read_nibble()
{
UInt8 data;
if ( !track_buffer_valid ) {
load_track_buffer();
}
data = nibble[position++];
if ( position >= RAW_TRACK_BYTES ) position = 0;
return data;
}
int mount_disk( int slot, int drive )
{
write_protect = 0;
rom = DmFindDatabase(0, "prodos.dsk");
diskimage = DmOpenDatabase(0, rom, dmModeReadOnly);
load_track_buffer();
return 0;
}
void load_track_buffer(void)
{
Char test[20];
logical_track = (physical_track_no + 1) >> 2;
if (logical_track == last_track) {
position = 0;
track_buffer_track = physical_track_no;
track_buffer_dirty = 0;
track_buffer_valid = 1;
return;
}
last_track = logical_track;
StrPrintF(test, "Track : %d ", logical_track);
WinDrawChars(test, StrLen(test), 50, 150);
value = DmQueryRecord(diskimage, logical_track);
values = (UInt8 *) MemHandleLock(value);
MemMove(nibble, values, 6392);
track_buffer_track = physical_track_no;
track_buffer_dirty = 0;
track_buffer_valid = 1;
position = 0;
MemHandleUnlock(value);
}
void toggleLanguageCard( )
{
/* UInt8 old_ss, old_ss1; */
/* old_ss = IOUSoftSwitch[0]; */
/* old_ss1 = IOUSoftSwitch[1]; */
/* set IOU soft switches */
switch(Address.Byte[LOW_BYTE] & 0x0F){
case 0:
SET(SS_LCBNK2, 0);
SET(SS_LCRAMRD, 0);
RESET(SS_LCRAMWRT, 1);
break;
case 1:
SET(SS_LCBNK2, 0);
RESET(SS_LCRAMRD, 0);
SET(SS_LCRAMWRT, 1);
break;
case 2:
SET(SS_LCBNK2, 0);
RESET(SS_LCRAMRD, 0);
RESET(SS_LCRAMWRT, 1);
break;
case 3:
SET(SS_LCBNK2, 0);
SET(SS_LCRAMRD, 0);
SET(SS_LCRAMWRT, 1);
break;
case 8:
RESET(SS_LCBNK2, 0);
SET(SS_LCRAMRD, 0);
RESET(SS_LCRAMWRT, 1);
break;
case 9:
RESET(SS_LCBNK2, 0);
RESET(SS_LCRAMRD, 0);
SET(SS_LCRAMWRT, 1);
break;
case 0xA:
RESET(SS_LCBNK2, 0);
RESET(SS_LCRAMRD, 0);
RESET(SS_LCRAMWRT, 1);
break;
case 0xB:
RESET(SS_LCBNK2, 0);
SET(SS_LCRAMRD, 0);
SET(SS_LCRAMWRT, 1);
}
if ((IOUState[1] & SS_LCRAMWRT)) {
UInt16 Page;
for (Page = 0xD0; Page <= 0xFF; Page++) WriteFunction[Page] = AuxWrite;
} else {
UInt16 Page;
for (Page = 0xD0; Page <= 0xFF; Page++) WriteFunction[Page] = READONLY;
}
if ((IOUState[0] & SS_LCRAMRD)) {
UInt16 Page;
MemMove(AppleMemory + 0xD000, AuxMemory + 0xD000 - (!(IOUState[0] & SS_LCBNK2) ? 0x1000 : 0x000), 4096);
MemMove(AppleMemory + 0xE000, AuxMemory + 0xE000, 8192);
for (Page = 0xD0; Page <= 0xFF; Page++) ReadFunction[Page] = NULL;
} else {
UInt16 Page;
MemMove(AppleMemory + 0xD000, AppleROM + 0xD000 - 0xC100, 4096);
MemMove(AppleMemory + 0xE000, AppleROM + 0xE000 - 0xC100, 8192);
for (Page = 0xD0; Page <= 0xFF; Page++) ReadFunction[Page] = NULL;
}
}