Fix 6522 interrupts, keyboard inits ok now

So, turns out, there's state contained on the literal wire attached to
the CB2 input on the 6522. Possibly the others. That would explain the
whole "wires" concept in the old code, wouldn't it? I would restore more
of that, but it doesn't really matter I don't think.
This commit is contained in:
InvisibleUp 2020-07-14 19:29:44 -04:00
parent 87e08c6cd3
commit c4a6735f68
5 changed files with 163 additions and 151 deletions

View File

@ -927,12 +927,12 @@ typedef struct DriverDat_R DriverDat_R;
#define kcom_checkval 0x841339E2
//#define Sony_dolog (dbglog_HAVE && 0)
#define dbglog_StartLine()
#define Sony_dolog (dbglog_HAVE && 0)
/*#define dbglog_StartLine()
#define dbglog_writeCStr(str) fprintf(stderr, "%s", str)
#define dbglog_writeHex(hex) fprintf(stderr, "$%X", hex)
#define dbglog_WriteNote(str) fprintf(stderr, "%s\n", str)
#define dbglog_writeReturn(str) fprintf(stderr, "\n")
#define dbglog_writeReturn(str) fprintf(stderr, "\n")*/
#if Sony_SupportTags
LOCALVAR CPTR TheTagBuffer;
@ -958,23 +958,23 @@ LOCALFUNC MacErr_t Sony_Mount(CPTR p)
CPTR dvl = DriveVarsLocation(i);
if (0 == dvl) {
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Mount : no dvl");
//#endif
#endif
result = mnvm_nsDrvErr;
} else if (get_vm_byte(dvl + kDiskInPlace) == 0x00) {
uint32_t L = ImageDataSize[i] >> 9; /* block count */
//fprintf(stderr, "Sony : Mount : Drive=%d, L=$%x\n", i, L);
//#if Sony_dolog
#if Sony_dolog
dbglog_StartLine();
dbglog_writeCStr("Sony : Mount : Drive=");
dbglog_writeHex(i);
dbglog_writeCStr(", L=");
dbglog_writeHex(L);
dbglog_writeReturn();
//#endif
#endif
#if CurEmMd <= kEmMd_Twiggy
if (L == 1702) {
@ -1033,9 +1033,9 @@ LOCALFUNC MacErr_t Sony_Mount(CPTR p)
result = mnvm_noErr;
} else {
/* disk already in place, a mistake has been made */
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Mount : already in place");
//#endif
#endif
}
return result;
@ -1104,18 +1104,18 @@ LOCALFUNC MacErr_t Sony_Prime(CPTR p)
CPTR dvl = DriveVarsLocation(Drive_No);
if (0 == dvl) {
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Prime : no dvl");
//#endif
#endif
result = mnvm_nsDrvErr;
} else
#if CurEmMd >= kEmMd_Twiggy
if (0xA002 != (IOTrap & 0xF0FE)) {
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Prime : "
"not read (0xA002) or write (0xA003)");
//#endif
#endif
result = mnvm_controlErr;
} else
@ -1198,7 +1198,7 @@ LOCALFUNC MacErr_t Sony_Prime(CPTR p)
Sony_Count = get_vm_long(ParamBlk + kioReqCount);
//#if Sony_dolog
#if Sony_dolog
dbglog_StartLine();
dbglog_writeCStr("Sony : Prime : Drive=");
dbglog_writeHex(Drive_No);
@ -1209,7 +1209,7 @@ LOCALFUNC MacErr_t Sony_Prime(CPTR p)
dbglog_writeCStr(", Count=");
dbglog_writeHex(Sony_Count);
dbglog_writeReturn();
//#endif
#endif
if ((0 != (Sony_Start & 0x1FF))
|| (0 != (Sony_Count & 0x1FF)))
@ -1255,15 +1255,15 @@ LOCALFUNC MacErr_t Sony_Control(CPTR p)
uint16_t OpCode = get_vm_word(ParamBlk + kcsCode);
if (kKillIO == OpCode) {
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Control : kKillIO");
//#endif
#endif
result = mnvm_miscErr;
} else if (kSetTagBuffer == OpCode) {
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Control : kSetTagBuffer");
//#endif
#endif
#if Sony_SupportTags
TheTagBuffer = get_vm_long(ParamBlk + kcsParam);
@ -1272,9 +1272,9 @@ LOCALFUNC MacErr_t Sony_Control(CPTR p)
result = mnvm_controlErr;
#endif
} else if (kTrackCacheControl == OpCode) {
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Control : kTrackCacheControl");
//#endif
#endif
#if CurEmMd <= kEmMd_128K
result = mnvm_controlErr;
@ -1301,33 +1301,33 @@ LOCALFUNC MacErr_t Sony_Control(CPTR p)
CPTR dvl = DriveVarsLocation(Drive_No);
if (0 == dvl) {
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Control : no dvl");
//#endif
#endif
result = mnvm_nsDrvErr;
} else if (get_vm_byte(dvl + kDiskInPlace) == 0) {
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Control : not DiskInPlace");
//#endif
#endif
result = mnvm_offLinErr;
} else {
switch (OpCode) {
case kVerifyDisk :
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : Control : kVerifyDisk");
//#endif
#endif
result = mnvm_noErr;
break;
case kEjectDisk :
//#if Sony_dolog
#if Sony_dolog
dbglog_StartLine();
dbglog_writeCStr("Sony : Control : kEjectDisk : ");
dbglog_writeHex(Drive_No);
dbglog_writeReturn();
//#endif
#endif
put_vm_byte(dvl + kWriteProt, 0x00);
/* Drive Writeable */
@ -1343,22 +1343,22 @@ LOCALFUNC MacErr_t Sony_Control(CPTR p)
result = Drive_Eject(Drive_No);
break;
case kFormatDisk :
//#if Sony_dolog
#if Sony_dolog
dbglog_StartLine();
dbglog_writeCStr("Sony : Control : kFormatDisk : ");
dbglog_writeHex(Drive_No);
dbglog_writeReturn();
//#endif
#endif
result = mnvm_noErr;
break;
case kDriveIcon :
//#if Sony_dolog
#if Sony_dolog
dbglog_StartLine();
dbglog_writeCStr("Sony : Control : kDriveIcon : ");
dbglog_writeHex(Drive_No);
dbglog_writeReturn();
//#endif
#endif
if (get_vm_word(dvl + kQType) != 0) {
put_vm_long(ParamBlk + kcsParam,
@ -1377,13 +1377,13 @@ LOCALFUNC MacErr_t Sony_Control(CPTR p)
{
uint32_t v;
//#if Sony_dolog
#if Sony_dolog
dbglog_StartLine();
dbglog_writeCStr(
"Sony : Control : kDriveInfo : ");
dbglog_writeHex(kDriveIcon);
dbglog_writeReturn();
//#endif
#endif
if (get_vm_word(dvl + kQType) != 0) {
v = 0x00000001; /* unspecified drive */
@ -1404,12 +1404,12 @@ LOCALFUNC MacErr_t Sony_Control(CPTR p)
break;
#endif
default :
//#if Sony_dolog
#if Sony_dolog
dbglog_StartLine();
dbglog_writeCStr("Sony : Control : OpCode : ");
dbglog_writeHex(OpCode);
dbglog_writeReturn();
//#endif
#endif
#if ExtraAbnormalReports
if ((kGetIconID != OpCode)
&& (kMediaIcon != OpCode)
@ -1443,12 +1443,12 @@ LOCALFUNC MacErr_t Sony_Status(CPTR p)
/* CPTR DeviceCtl = get_vm_long(p + ExtnDat_params + 4); */
uint16_t OpCode = get_vm_word(ParamBlk + kcsCode);
//#if Sony_dolog
#if Sony_dolog
dbglog_StartLine();
dbglog_writeCStr("Sony : Sony_Status OpCode = ");
dbglog_writeHex(OpCode);
dbglog_writeReturn();
//#endif
#endif
if (kDriveStatus == OpCode) {
tDrive Drive_No = get_vm_word(ParamBlk + kioVRefNum) - 1;
@ -1493,9 +1493,9 @@ LOCALFUNC MacErr_t Sony_Close(CPTR p)
// Initialize disk subsystem
LOCALFUNC MacErr_t Sony_OpenA(CPTR p)
{
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : OpenA");
//#endif
#endif
if (MountCallBack != 0) {
return mnvm_opWrErr; /* driver already open */
@ -1518,9 +1518,9 @@ LOCALFUNC MacErr_t Sony_OpenB(CPTR p)
int16_t i;
CPTR dvl;
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : OpenB");
//#endif
#endif
CPTR SonyVars = get_vm_long(p + ExtnDat_params + 4);
/* CPTR ParamBlk = get_vm_long(p + ExtnDat_params + 24); (unused) */
@ -1591,9 +1591,9 @@ LOCALFUNC MacErr_t Sony_OpenB(CPTR p)
// Write callback address for M68k to mount disks w/
LOCALFUNC MacErr_t Sony_OpenC(CPTR p)
{
//#if Sony_dolog
#if Sony_dolog
dbglog_WriteNote("Sony : OpenC");
//#endif
#endif
MountCallBack = get_vm_long(p + ExtnDat_params + 0)
#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)

View File

@ -61,7 +61,7 @@ LOCALPROC GotKeyBoardData(uint8_t v)
static bool Kybd_CheckDataReady()
{
return VIA_ReadBit(VIA1, rIFR, 2);
return VIA_GetCB2(VIA1);
}
LOCALVAR uint8_t InstantCommandData = 0x7B;
@ -110,7 +110,7 @@ GLOBALPROC DoKybd_ReceiveCommand(void)
} else {
uint8_t in = VIA_ShiftOutData_Ext(VIA1);
fprintf(stderr, "KybdStateRecievedCommand\n");
//fprintf(stderr, "KybdStateRecievedCommand\n");
KybdState = kKybdStateRecievedCommand;
switch (in) {
@ -152,7 +152,7 @@ GLOBALPROC DoKybd_ReceiveEndCommand(void)
"KybdState != kKybdStateRecievingEndCommand");
} else {
KybdState = kKybdStateIdle;
fprintf(stderr, "KybdStateIdle\n");
//fprintf(stderr, "KybdStateIdle\n");
#ifdef _VIA_Debug
fprintf(stderr, "enter DoKybd_ReceiveEndCommand\n");
#endif
@ -170,8 +170,8 @@ GLOBALPROC Kybd_DataLineChngNtfy(void)
{
switch (KybdState) {
case kKybdStateIdle:
if (Kybd_CheckDataReady() == 1) {
fprintf(stderr, "KybdStateRecievingCommand\n");
if (Kybd_CheckDataReady() == false) {
//fprintf(stderr, "KybdStateRecievingCommand\n");
KybdState = kKybdStateRecievingCommand;
#ifdef _VIA_Debug
fprintf(stderr, "posting kICT_Kybd_ReceiveCommand\n");
@ -185,9 +185,9 @@ GLOBALPROC Kybd_DataLineChngNtfy(void)
}
break;
case kKybdStateRecievedCommand:
if (Kybd_CheckDataReady() == 0) {
if (Kybd_CheckDataReady() == true) {
KybdState = kKybdStateRecievingEndCommand;
fprintf(stderr, "KybdStateRecievingEndCommand\n");
//fprintf(stderr, "KybdStateRecievingEndCommand\n");
#ifdef _VIA_Debug
fprintf(stderr,
"posting kICT_Kybd_ReceiveEndCommand\n");

View File

@ -72,6 +72,7 @@ void VIA_Reset(void) {
VIA_State[i].vT1L = 0x00;
VIA_State[i].vT2C = 0x00;
VIA_State[i].vT2L = 0x00;
VIA_State[i].vCB2 = true;
}
// temporary
VIA1_T1Running = false;
@ -97,12 +98,7 @@ void VIA_RaiseInterrupt(uint8_t id, uint8_t irq)
// Call interrupt handler, if required
if (vIFR_old != vIFR_new) {
if (irq == 2) {
fprintf(stderr, "IRQ %d raised\n", irq);
}
if (VIA_State[id].vISR[irq] != NULL) {
VIA_State[id].vISR[irq]();
}
//fprintf(stderr, "IRQ %d raised\n", irq);
VIAorSCCinterruptChngNtfy();
} else {
//fprintf(stderr, "IRQ %d attempted\n", irq);
@ -122,28 +118,15 @@ void VIA_LowerInterrupt(uint8_t id, uint8_t irq)
// Call interrupt handler, if required
if (vIFR_old != vIFR_new) {
if (irq == 2) {
fprintf(stderr, "IRQ %d lowered\n", irq);
}
//fprintf(stderr, "IRQ %d lowered\n", irq);
VIAorSCCinterruptChngNtfy();
if (VIA_State[id].vISR[irq] != NULL) {
VIA_State[id].vISR[irq]();
}
} else {
//fprintf(stderr, "IRQ %d attempted (lower)\n", irq);
}
}
// Register a VIA interrupt service routine
void VIA_RegisterISR(uint8_t id, uint8_t irq, VIA_ISR_t isr)
{
assert(irq < 7);
assert(id < VIA_MAXNUM);
VIA_State[id].vISR[irq] = isr;
}
// Register data state-change notification interrupts
void VIA_RegisterDataISR(uint8_t port, uint8_t id, uint8_t irq, VIA_ISR_t isr)
void VIA_RegisterDataISR(uint8_t id, uint8_t port, uint8_t irq, VIA_ISR_t isr)
{
assert(id < VIA_MAXNUM);
assert(port == DataRegA || port == DataRegB);
@ -176,8 +159,37 @@ static void VIA_RunDataISR(uint8_t id, VIA_Register_t reg, uint8_t bit)
//fprintf(stderr, "ISR PB%d not found\n", bit);
}
}
}
// CB2 stuff
void VIA_RegisterCB2ISR(uint8_t id, VIA_ISR_t isr)
{
assert(id < VIA_MAXNUM);
VIA_State[id].vISR_CB2 = isr;
}
static void VIA_RunCB2ISR(uint8_t id)
{
assert(id < VIA_MAXNUM);
if (VIA_State[id].vISR_CB2 != NULL) {
VIA_State[id].vISR_CB2();
}
}
// Get the value of CB2, specifically
bool VIA_GetCB2(uint8_t id)
{
assert(id < VIA_MAXNUM);
return VIA_State[id].vCB2;
}
// And likewise, set it
void VIA_SetSB2(uint8_t id, bool value)
{
assert(id < VIA_MAXNUM);
VIA_State[id].vCB2 = value;
}
/*
const int TEMPSKIP = 1;
@ -273,9 +285,9 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data, bool runISR)
fprintf(stderr, "Set PB to "BIN_PAT"\n", TO_BIN(data));
}*/
//fprintf(stderr, "VIA%d Write %d <- %d\n", id+1, reg, data);
if (reg == rSR) {
/*if (reg == rSR) {
fprintf(stderr, "vSR: %d, %d, %d\n", true, ((via->vACR & 0x1C) >> 2), data);
}
}*/
switch(reg) {
case rIRB: via->vIFR &= 0b11100111; // clear keyboard interrupts
@ -314,7 +326,7 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data, bool runISR)
default: assert(true);
}
// Assert vBufA or vBufB ISRs if needed
// Run vBufA or vBufB ISRs if needed
uint8_t diff = (data ^ data_old);
if (runISR && (reg == rIRA || reg == rORA || reg == rIRB)) {
// Iterate through each bit
@ -328,29 +340,24 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data, bool runISR)
}
}
// Run global ISR if required
// Check ISRs for changes if required
uint8_t vIFR_new = via->vIFR & via->vIER & 0b01111111;
uint8_t vIFR_old = data_old & via->vIER & 0b01111111;
if (runISR && (reg == rIFR || reg == rIER) && (vIFR_old != vIFR_new))
{
// Iterate through each bit
uint8_t bit = 0;
uint8_t mask = 0b1;
while (mask != 0) {
if ((vIFR_new & vIFR_new & mask) != 0) {
if (via->vISR[bit] != NULL) { via->vISR[bit](); }
}
bit += 1;
mask <<= 1;
}
/*fprintf(
stderr, "IRQ changed ("BIN_PAT") -> ("BIN_PAT")\n",
TO_BIN(vIFR_old & (vIFR_old ^ vIFR_new)),
TO_BIN(vIFR_new & (vIFR_old ^ vIFR_new))
);*/
VIAorSCCinterruptChngNtfy();
fprintf(stderr, "IRQ changed ("BIN_PAT") -> ("BIN_PAT")\n", TO_BIN(vIFR_old & (vIFR_old ^ vIFR_new)), TO_BIN(vIFR_new & (vIFR_old ^ vIFR_new)));
}
else if (reg == rIFR || reg == rIER)
/*else if (reg == rIFR || reg == rIER)
{
fprintf(stderr, "IRQ attempt ("BIN_PAT")\n", TO_BIN((data_old ^ vIFR_new)));
}
}*/
// Check if shift mode has changed
if (reg == rACR) {
uint8_t ShiftMode = (via->vACR & 0x1C) >> 2;
uint8_t ShiftMode_old = (data_old & 0x1C) >> 2;
@ -362,7 +369,9 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data, bool runISR)
// Check if shift direction has changed
if ((ShiftMode & 0b100) != (ShiftMode_old & 0b100)) {
if ((ShiftMode & 0b100) == 0) { // if now shifting in
VIA_RaiseInterrupt(id, 2); // raise interrupt
// notify keyboard/ADB controller
via->vCB2 = true;
VIA_RunCB2ISR(id);
}
}
}
@ -376,9 +385,9 @@ uint8_t VIA_Read(uint8_t id, VIA_Register_t reg)
assert(reg < rINVALID);
VIA_State_t *via = &VIA_State[id];
if (reg == rSR) {
/*if (reg == rSR) {
fprintf(stderr, "vSR: %d, %d, %d\n", false, ((via->vACR & 0x1C) >> 2), via->vSR);
}
}*/
switch(reg) {
// not sure if reading *all* of vBufA or vBufB is correct,
@ -437,14 +446,14 @@ void VIA_WriteBit(uint8_t id, VIA_Register_t reg, uint8_t bit, bool value, bool
}
// ShiftMode states (from M68k perspective)
// 0: Shift in under external control w/ no interrupts.
// 1: Shift in under control of Timer 2
// 2: Shift in under system clock control
// 3: Shift in under external control. ISR every byte. R/W resets ISR.
// 4: Shift out under T2 control (forever)
// 5: Shift out under T2 control
// 6: Shift out under system clock control
// 7: Shift out under external control. ISR every byte. R/W resets ISR.
// 0b000 (0): Shift in under external control w/ no interrupts.
// 0b001 (1): Shift in under control of Timer 2
// 0b010 (2): Shift in under system clock control
// 0b011 (3): Shift in under external control. ISR every byte. R/W resets ISR.
// 0b100 (4): Shift out under T2 control (forever)
// 0b101 (5): Shift out under T2 control
// 0b110 (6): Shift out under system clock control
// 0b111 (7): Shift out under external control. ISR every byte. R/W resets ISR.
// TODO: this probably shouldn't be instant.
// also i got the in/out mixed up compared to the datasheet. oh well.
@ -455,12 +464,19 @@ void VIA_ShiftInData_M68k(uint8_t id, uint8_t v)
//VIA_LowerInterrupt(id, 2); // data ready
uint8_t ShiftMode = (via->vACR & 0x1C) >> 2;
assert(((ShiftMode & 0b100) == 0b100) || (ShiftMode == 0));
VIA_LowerInterrupt(id, 2); // reset "data ready"
VIA_State[id].vSR = v;
// If shifting out under system clock...
if (ShiftMode == 6) {
VIA_RaiseInterrupt(id, 2); // data ready
VIA_RaiseInterrupt(id, 4); // data clock
// If data line is high, clear line and notify ADB/keyboard
if (VIA_State[id].vCB2 == true) {
VIA_State[id].vCB2 = false;
VIA_RunCB2ISR(id);
}
// and raise SR data ready ISR
VIA_RaiseInterrupt(id, 2);
}
}
@ -471,19 +487,12 @@ uint8_t VIA_ShiftOutData_M68k(uint8_t id)
VIA_State_t *via = &VIA_State[id];
uint8_t ShiftMode = (via->vACR & 0x1C) >> 2;
VIA_LowerInterrupt(id, 2); // reset "data ready"
uint8_t result = VIA_State[id].vSR;
/*if (ShiftMode == 3) {
VIA_RaiseInterrupt(id, 2); // data ready
VIA_RaiseInterrupt(id, 4); // data clock
// last data bit
if (via->vSR & 1) {
VIA_RaiseInterrupt(id, 3);
} else {
VIA_LowerInterrupt(id, 3);
}
}*/
return result;
assert((ShiftMode & 0b100) == 0b000);
// Notify keyboard
//via->vCB2 = true;
//VIA_RunCB2ISR(id);
return VIA_State[id].vSR;
}
// Same functions, from the peripheal end
@ -492,14 +501,13 @@ void VIA_ShiftInData_Ext(uint8_t id, uint8_t v)
assert(id < VIA_MAXNUM);
VIA_State_t *via = &VIA_State[id];
uint8_t ShiftMode = (via->vACR & 0x1C) >> 2;
fprintf(stderr, "vSR: %d, %d, %d (ext)\n", true, ShiftMode, v);
//fprintf(stderr, "vSR: %d, %d, %d (ext)\n", true, ShiftMode, v);
assert(ShiftMode == 0 || ShiftMode == 3);
assert ((ShiftMode & 0b100) == 0b000);
if (ShiftMode == 3) {
if (ShiftMode != 0) {
VIA_State[id].vSR = v;
VIA_State[id].vIFR |= 0b10010100; // data ready; no callback
VIAorSCCinterruptChngNtfy();
VIA_RaiseInterrupt(id, 2); // data ready
}
}
@ -510,17 +518,12 @@ uint8_t VIA_ShiftOutData_Ext(uint8_t id)
VIA_State_t *via = &VIA_State[id];
uint8_t ShiftMode = (via->vACR & 0x1C) >> 2;
fprintf(stderr, "vSR: %d, %d, %d (ext)\n", false, ShiftMode, VIA_State[id].vSR);
assert(ShiftMode == 7);
//fprintf(stderr, "vSR: %d, %d, %d (ext)\n", false, ShiftMode, VIA_State[id].vSR);
assert(((ShiftMode & 0b100) == 0b100) || (ShiftMode == 0));
VIA_State[id].vIFR |= 0b10010100; // data ready; no callback
// data bit
if (via->vSR & 1) {
VIA_State[id].vIFR |= 0b00001000;
} else {
VIA_State[id].vIFR &= 0b11110111;
}
VIAorSCCinterruptChngNtfy();
VIA_RaiseInterrupt(id, 2);
VIA_RaiseInterrupt(id, 4);
VIA_State[id].vCB2 = ((VIA_State[id].vSR & 1) == 1);
return VIA_State[id].vSR;
}

View File

@ -19,23 +19,27 @@ typedef void (*VIA_ISR_t)(void);
/* Names from Guide to Macintosh Family Hardware, Second Edition, pg. 159 */
typedef struct {
uint8_t vBufA; // Data Register A
uint8_t vBufB; // Data Register B
uint8_t vDirA; // Data Direction A (0 = in, 1 = out)
uint8_t vDirB; // Data Direction B (0 = in, 1 = out)
uint8_t vPCR; // Peripheal Control
uint8_t vACR; // Auxiliary Control
uint8_t vIFR; // Interrupt Flag
uint8_t vIER; // Interrupt Enable
uint8_t vSR; // Shift register
uint16_t vT1L; // Timer 1 latch
uint16_t vT1C; // Timer 1 counter
uint16_t vT2L; // Timer 2 latch
uint16_t vT2C; // Timer 2 counter
uint8_t vBufA; // Data Register A
uint8_t vBufB; // Data Register B
uint8_t vDirA; // Data Direction A (0 = in, 1 = out)
uint8_t vDirB; // Data Direction B (0 = in, 1 = out)
uint8_t vPCR; // Peripheal Control
uint8_t vACR; // Auxiliary Control
uint8_t vIFR; // Interrupt Flag
uint8_t vIER; // Interrupt Enable
uint8_t vSR; // Shift register
uint16_t vT1L; // Timer 1 latch
uint16_t vT1C; // Timer 1 counter
uint16_t vT2L; // Timer 2 latch
uint16_t vT2C; // Timer 2 counter
VIA_ISR_t vISR[8]; // ISRs to automatically call when interrupt is raised
// data-change ISRs
VIA_ISR_t vISR_A[8]; // ISRs to call when vBufA changes
VIA_ISR_t vISR_B[8]; // ISRs to call when vBufB changes
// Shift register external device notifications
bool vCB2; // CB2 state
VIA_ISR_t vISR_CB2; // thing to call when CB2 changes
} VIA_State_t;
/* Names from SY6522 datasheet */
@ -74,10 +78,10 @@ void VIA_Reset(void);
// Raise an interrupt by irq number, calling registered ISR if required
void VIA_RaiseInterrupt(uint8_t id, uint8_t irq);
void VIA_LowerInterrupt(uint8_t id, uint8_t irq);
// Register a VIA interrupt service routine
void VIA_RegisterISR(uint8_t id, uint8_t irq, VIA_ISR_t isr);
// Register data state-change notification interrupts
void VIA_RegisterDataISR(uint8_t port, uint8_t id, uint8_t bit, VIA_ISR_t isr);
void VIA_RegisterDataISR(uint8_t id, uint8_t port, uint8_t bit, VIA_ISR_t isr);
// Register a routine for CB2's ISR
void VIA_RegisterCB2ISR(uint8_t id, VIA_ISR_t isr);
// Tick all timers by one step (call every 1.2766 us)
//void VIA_TickTimers();
@ -90,6 +94,11 @@ uint8_t VIA_Read(uint8_t id, VIA_Register_t reg);
bool VIA_ReadBit(uint8_t id, VIA_Register_t reg, uint8_t bit);
// Write a single bit. Can raise data ISR if required.
void VIA_WriteBit(uint8_t id, VIA_Register_t reg, uint8_t bit, bool value, bool runISR);
// Get the value of CB2, specifically
bool VIA_GetCB2(uint8_t id);
// And likewise, set it
void VIA_SetSB2(uint8_t id, bool value);
void VIA_ShiftInData_M68k(uint8_t id, uint8_t v);
uint8_t VIA_ShiftOutData_M68k(uint8_t id);

View File

@ -392,7 +392,7 @@ LOCALFUNC bool InitEmulation(void)
// temporarily register some ISRs until I put these in a better place
// Mac Plus only
VIA_RegisterDataISR(VIA1, DataRegA, 4, MemOverlay_ChangeNtfy);
VIA_RegisterISR(VIA1, 2, Kybd_DataLineChngNtfy);
VIA_RegisterCB2ISR(VIA1, Kybd_DataLineChngNtfy);
return true;
}
// VBlank interrupt