mirror of
https://github.com/InvisibleUp/uvmac.git
synced 2025-03-15 05:33:56 +00:00
System almost boots, but VIA interrupts are borked
This commit is contained in:
parent
725f477884
commit
027e2397c4
@ -37,6 +37,7 @@
|
||||
#include "GLOBGLUE.h"
|
||||
#include "HW/RAM/RAMADDR.h"
|
||||
#include "HW/VIA/VIAEMDEV.h"
|
||||
#include "HW/SCC/SCCEMDEV.h"
|
||||
|
||||
/*
|
||||
ReportAbnormalID unused 0x111D - 0x11FF
|
||||
@ -1519,28 +1520,28 @@ LOCALVAR uint8_t CurIPL = 0;
|
||||
|
||||
GLOBALPROC VIAorSCCinterruptChngNtfy(void)
|
||||
{
|
||||
#if (CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)
|
||||
uint8_t NewIPL;
|
||||
|
||||
if (InterruptButton) {
|
||||
NewIPL = 7;
|
||||
} else if (SCCInterruptRequest) {
|
||||
NewIPL = 4;
|
||||
} else if (VIA2_InterruptRequest) {
|
||||
NewIPL = 2;
|
||||
} else if (VIA1_InterruptRequest) {
|
||||
NewIPL = 1;
|
||||
} else {
|
||||
NewIPL = 0;
|
||||
}
|
||||
#else
|
||||
uint8_t VIA1_InterruptRequest = (VIA_Read(VIA1, rIFR) & 0b01111111) != 0;
|
||||
uint8_t SCCInterruptRequest = 0;
|
||||
uint8_t VIAandNotSCC = VIA1_InterruptRequest & ~ SCCInterruptRequest;
|
||||
uint8_t NewIPL = VIAandNotSCC
|
||||
| (SCCInterruptRequest << 1)
|
||||
| (InterruptButton << 2);
|
||||
#endif
|
||||
uint8_t VIA2_InterruptRequest = (VIA_Read(VIA2, rIFR) & 0b01111111) != 0;
|
||||
|
||||
if ((CurEmMd == kEmMd_II) || (CurEmMd == kEmMd_IIx)) {
|
||||
if (InterruptButton) {
|
||||
NewIPL = 7;
|
||||
} else if (SCCInterruptRequest) {
|
||||
NewIPL = 4;
|
||||
} else if (VIA2_InterruptRequest) {
|
||||
NewIPL = 2;
|
||||
} else if (VIA1_InterruptRequest) {
|
||||
NewIPL = 1;
|
||||
} else {
|
||||
NewIPL = 0;
|
||||
}
|
||||
} else {
|
||||
uint8_t VIAandNotSCC = VIA1_InterruptRequest & ~ SCCInterruptRequest;
|
||||
NewIPL = VIAandNotSCC
|
||||
| (SCCInterruptRequest << 1)
|
||||
| (InterruptButton << 2);
|
||||
}
|
||||
if (NewIPL != CurIPL) {
|
||||
CurIPL = NewIPL;
|
||||
m68k_IPLchangeNtfy();
|
||||
|
@ -38,6 +38,7 @@
|
||||
#endif
|
||||
|
||||
#include "HW/DISK/SONYEMDV.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
ReportAbnormalID unused 0x090B - 0x09FF
|
||||
@ -926,7 +927,12 @@ typedef struct DriverDat_R DriverDat_R;
|
||||
|
||||
#define kcom_checkval 0x841339E2
|
||||
|
||||
#define Sony_dolog (dbglog_HAVE && 0)
|
||||
//#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")
|
||||
|
||||
#if Sony_SupportTags
|
||||
LOCALVAR CPTR TheTagBuffer;
|
||||
@ -952,22 +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 */
|
||||
|
||||
#if Sony_dolog
|
||||
//fprintf(stderr, "Sony : Mount : Drive=%d, L=$%x\n", i, L);
|
||||
//#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) {
|
||||
@ -1026,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;
|
||||
@ -1097,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
|
||||
@ -1191,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);
|
||||
@ -1202,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)))
|
||||
@ -1248,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);
|
||||
@ -1265,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;
|
||||
@ -1294,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 */
|
||||
@ -1336,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,
|
||||
@ -1370,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 */
|
||||
@ -1397,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)
|
||||
@ -1436,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;
|
||||
@ -1483,11 +1490,12 @@ LOCALFUNC MacErr_t Sony_Close(CPTR p)
|
||||
return mnvm_closErr; /* Can't Close Driver */
|
||||
}
|
||||
|
||||
// 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 */
|
||||
@ -1504,14 +1512,15 @@ LOCALFUNC MacErr_t Sony_OpenA(CPTR p)
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize disk drives
|
||||
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) */
|
||||
@ -1579,11 +1588,12 @@ LOCALFUNC MacErr_t Sony_OpenB(CPTR p)
|
||||
return mnvm_noErr;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
@ -29,21 +29,12 @@
|
||||
#include "HW/KBRD/KBRDEMDV.h"
|
||||
#include "HW/VIA/VIAEMDEV.h"
|
||||
|
||||
#ifdef _VIA_Debug
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
ReportAbnormalID unused 0x0B03 - 0x0BFF
|
||||
*/
|
||||
|
||||
void KYBD_ShiftOutData(uint8_t v) {
|
||||
VIA_ShiftInData(VIA1, v);
|
||||
}
|
||||
uint8_t KYBD_ShiftInData(void) {
|
||||
return VIA_ShiftOutData(VIA1);
|
||||
}
|
||||
|
||||
enum {
|
||||
kKybdStateIdle,
|
||||
kKybdStateRecievingCommand,
|
||||
@ -64,7 +55,7 @@ LOCALPROC GotKeyBoardData(uint8_t v)
|
||||
HaveKeyBoardResult = true;
|
||||
KeyBoardResult = v;
|
||||
} else {
|
||||
v = VIA_Read(VIA1, rSR);
|
||||
VIA_ShiftInData_Ext(VIA1, v);
|
||||
VIA_RaiseInterrupt(VIA1, 2);
|
||||
}
|
||||
}
|
||||
@ -118,8 +109,9 @@ GLOBALPROC DoKybd_ReceiveCommand(void)
|
||||
ReportAbnormalID(0x0B01,
|
||||
"KybdState != kKybdStateRecievingCommand");
|
||||
} else {
|
||||
uint8_t in = KYBD_ShiftInData();
|
||||
uint8_t in = VIA_ShiftOutData_Ext(VIA1);
|
||||
|
||||
fprintf(stderr, "KybdStateRecievedCommand\n");
|
||||
KybdState = kKybdStateRecievedCommand;
|
||||
|
||||
switch (in) {
|
||||
@ -161,6 +153,7 @@ GLOBALPROC DoKybd_ReceiveEndCommand(void)
|
||||
"KybdState != kKybdStateRecievingEndCommand");
|
||||
} else {
|
||||
KybdState = kKybdStateIdle;
|
||||
fprintf(stderr, "KybdStateIdle\n");
|
||||
#ifdef _VIA_Debug
|
||||
fprintf(stderr, "enter DoKybd_ReceiveEndCommand\n");
|
||||
#endif
|
||||
@ -169,7 +162,7 @@ GLOBALPROC DoKybd_ReceiveEndCommand(void)
|
||||
fprintf(stderr, "HaveKeyBoardResult: %d\n", KeyBoardResult);
|
||||
#endif
|
||||
HaveKeyBoardResult = false;
|
||||
KYBD_ShiftOutData(KeyBoardResult);
|
||||
VIA_ShiftInData_Ext(VIA1, KeyBoardResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -178,13 +171,14 @@ GLOBALPROC Kybd_DataLineChngNtfy(void)
|
||||
{
|
||||
switch (KybdState) {
|
||||
case kKybdStateIdle:
|
||||
if (Kybd_CheckDataReady() == 0) {
|
||||
if (Kybd_CheckDataReady() == 1) {
|
||||
fprintf(stderr, "KybdStateRecievingCommand\n");
|
||||
KybdState = kKybdStateRecievingCommand;
|
||||
#ifdef _VIA_Debug
|
||||
fprintf(stderr, "posting kICT_Kybd_ReceiveCommand\n");
|
||||
#endif
|
||||
/*ICT_add(kICT_Kybd_ReceiveCommand,
|
||||
6800UL * kCycleScale / 64 * ClockMult);*/
|
||||
ICT_add(kICT_Kybd_ReceiveCommand,
|
||||
6800UL * kCycleScale / 64 * ClockMult);
|
||||
|
||||
if (InquiryCommandTimer != 0) {
|
||||
InquiryCommandTimer = 0; /* abort Inquiry */
|
||||
@ -192,14 +186,15 @@ GLOBALPROC Kybd_DataLineChngNtfy(void)
|
||||
}
|
||||
break;
|
||||
case kKybdStateRecievedCommand:
|
||||
if (Kybd_CheckDataReady() == 1) {
|
||||
if (Kybd_CheckDataReady() == 0) {
|
||||
KybdState = kKybdStateRecievingEndCommand;
|
||||
fprintf(stderr, "KybdStateRecievingEndCommand\n");
|
||||
#ifdef _VIA_Debug
|
||||
fprintf(stderr,
|
||||
"posting kICT_Kybd_ReceiveEndCommand\n");
|
||||
#endif
|
||||
/*ICT_add(kICT_Kybd_ReceiveEndCommand,
|
||||
6800UL * kCycleScale / 64 * ClockMult);*/
|
||||
ICT_add(kICT_Kybd_ReceiveEndCommand,
|
||||
6800UL * kCycleScale / 64 * ClockMult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -38,8 +38,6 @@
|
||||
"Zilog SCC/ESCC User's Manual".
|
||||
*/
|
||||
|
||||
#if 0
|
||||
|
||||
#include "SYSDEPNS.h"
|
||||
|
||||
#include "UI/MYOSGLUE.h"
|
||||
@ -257,17 +255,19 @@ static int rx_data_offset = 0;
|
||||
|
||||
/// VIA INTERFACE FUNCTIONS //////////////////////////////////////////////////
|
||||
|
||||
bool SCC_GetvSCCWrReq()
|
||||
uint8_t SCCInterruptRequest;
|
||||
|
||||
static bool SCC_GetvSCCWrReq()
|
||||
{
|
||||
return VIA_ReadBit(VIA1, rIRA, 7);
|
||||
}
|
||||
|
||||
void SCC_SetvSCCWrReq(bool value)
|
||||
static void SCC_SetvSCCWrReq(bool value)
|
||||
{
|
||||
VIA_WriteBit(VIA1, rIRA, 7, value, false);
|
||||
}
|
||||
|
||||
bool SCC_GetvSync()
|
||||
static bool SCC_GetvSync()
|
||||
{
|
||||
switch(CurEmMd) {
|
||||
case kEmMd_SE:
|
||||
@ -598,7 +598,7 @@ LOCALPROC SCC_ResetChannel(int chan)
|
||||
|
||||
GLOBALPROC SCC_Reset(void)
|
||||
{
|
||||
SCCwaitrq = 1;
|
||||
SCC_SetvSCCWrReq(1);
|
||||
|
||||
SCC.SCC_Interrupt_Type = 0;
|
||||
|
||||
@ -2827,5 +2827,3 @@ GLOBALFUNC uint32_t SCC_Access(uint32_t Data, bool WriteMem, CPTR addr)
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -17,10 +17,9 @@
|
||||
#ifndef SCCEMDEV_H
|
||||
#define SCCEMDEV_H
|
||||
|
||||
extern uint8_t SCCInterruptRequest;
|
||||
EXPORTPROC SCC_Reset(void);
|
||||
|
||||
EXPORTFUNC uint32_t SCC_Access(uint32_t Data, bool WriteMem, CPTR addr);
|
||||
|
||||
EXPORTFUNC bool SCC_InterruptsEnabled(void);
|
||||
|
||||
#if EmLocalTalk
|
||||
|
@ -33,6 +33,23 @@
|
||||
/* Global state */
|
||||
VIA_State_t VIA_State[VIA_MAXNUM];
|
||||
|
||||
#define CyclesPerViaTime (10 * ClockMult)
|
||||
#define CyclesScaledPerViaTime (kCycleScale * CyclesPerViaTime)
|
||||
|
||||
// TODO: Move these into the VIA_State_t struct
|
||||
bool VIA1_T1Running = true;
|
||||
bool VIA1_T1IntReady = false;
|
||||
iCountt VIA1_T1LastTime = 0;
|
||||
uint8_t VIA1_T1_Active = 0;
|
||||
const uint8_t VIA_T1_IRQ = 6;
|
||||
|
||||
bool VIA1_T2Running = true;
|
||||
bool VIA1_T2IntReady = false;
|
||||
bool VIA1_T2C_ShortTime = false;
|
||||
iCountt VIA1_T2LastTime = 0;
|
||||
uint8_t VIA1_T2_Active = 0;
|
||||
const uint8_t VIA_T2_IRQ = 5;
|
||||
|
||||
// Hardware reset
|
||||
bool VIA_Zap(void) {
|
||||
memset(VIA_State, 0, sizeof(VIA_State));
|
||||
@ -42,14 +59,29 @@ bool VIA_Zap(void) {
|
||||
// Software reset
|
||||
void VIA_Reset(void) {
|
||||
for (int i = 0; i < VIA_MAXNUM; i += 1) {
|
||||
VIA_State[i].vBufA = 0xFF;
|
||||
VIA_State[i].vBufB = 0xFF;
|
||||
VIA_State[i].vBufA = 0x00;
|
||||
VIA_State[i].vBufB = 0x00;
|
||||
VIA_State[i].vDirA = 0x00;
|
||||
VIA_State[i].vDirB = 0x00;
|
||||
VIA_State[i].vIER = 0x00;
|
||||
VIA_State[i].vIFR = 0x00;
|
||||
VIA_State[i].vSR = 0x00;
|
||||
VIA_State[i].vACR = 0x00;
|
||||
VIA_State[i].vPCR = 0x00;
|
||||
VIA_State[i].vT1C = 0x00;
|
||||
VIA_State[i].vT1L = 0x00;
|
||||
VIA_State[i].vT2C = 0x00;
|
||||
VIA_State[i].vT2L = 0x00;
|
||||
}
|
||||
// temporary
|
||||
VIA1_T1Running = false;
|
||||
VIA1_T1IntReady = false;
|
||||
VIA1_T1LastTime = 0;
|
||||
VIA1_T1_Active = 0;
|
||||
VIA1_T2Running = false;
|
||||
VIA1_T2IntReady = false;
|
||||
VIA1_T2LastTime = 0;
|
||||
VIA1_T2_Active = 0;
|
||||
}
|
||||
|
||||
// Raise an interrupt by irq number
|
||||
@ -60,16 +92,18 @@ void VIA_RaiseInterrupt(uint8_t id, uint8_t irq)
|
||||
|
||||
// Set interrupt flag
|
||||
uint8_t vIFR_old = VIA_State[id].vIFR & VIA_State[id].vIER & 0b01111111;
|
||||
VIA_State[id].vIFR |= (1 << irq) | (1 << 7);
|
||||
VIA_State[id].vIFR |= (1 << irq);// | (1 << 7);
|
||||
uint8_t vIFR_new = VIA_State[id].vIFR & VIA_State[id].vIER & 0b01111111;
|
||||
|
||||
// Call interrupt handler, if required
|
||||
if (vIFR_old != vIFR_new) {
|
||||
/*if (VIA_State[id].vISR[irq] != NULL) {
|
||||
if (irq == 2) {
|
||||
fprintf(stderr, "IRQ %d raised\n", irq);
|
||||
}
|
||||
if (VIA_State[id].vISR[irq] != NULL) {
|
||||
VIA_State[id].vISR[irq]();
|
||||
}*/
|
||||
}
|
||||
VIAorSCCinterruptChngNtfy();
|
||||
//fprintf(stderr, "IRQ %d raised\n", irq);
|
||||
} else {
|
||||
//fprintf(stderr, "IRQ %d attempted\n", irq);
|
||||
}
|
||||
@ -88,11 +122,13 @@ void VIA_LowerInterrupt(uint8_t id, uint8_t irq)
|
||||
|
||||
// Call interrupt handler, if required
|
||||
if (vIFR_old != vIFR_new) {
|
||||
/*if (VIA_State[id].vISR[irq] != NULL) {
|
||||
VIA_State[id].vISR[irq]();
|
||||
}*/
|
||||
if (irq == 2) {
|
||||
fprintf(stderr, "IRQ %d lowered\n", irq);
|
||||
}
|
||||
VIAorSCCinterruptChngNtfy();
|
||||
//fprintf(stderr, "IRQ %d lowered\n", irq);
|
||||
if (VIA_State[id].vISR[irq] != NULL) {
|
||||
VIA_State[id].vISR[irq]();
|
||||
}
|
||||
} else {
|
||||
//fprintf(stderr, "IRQ %d attempted (lower)\n", irq);
|
||||
}
|
||||
@ -199,24 +235,6 @@ void VIA_TickTimers()
|
||||
}
|
||||
}*/
|
||||
|
||||
// Do fancy shift register stuff
|
||||
void VIA_TickShiftRegister(uint8_t id)
|
||||
{
|
||||
assert(id < VIA_MAXNUM);
|
||||
VIA_State_t *via = &VIA_State[id];
|
||||
|
||||
switch ((via->vACR & 0x1C) >> 2) {
|
||||
case 3 : /* Shifting In */
|
||||
break;
|
||||
case 6 : /* shift out under o2 clock */
|
||||
VIA_LowerInterrupt(id, 3);
|
||||
VIA_RaiseInterrupt(id, 2);
|
||||
break;
|
||||
case 7 : /* Shifting Out */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// temporary debugging stuff
|
||||
#define BIN_PAT "%c%c%c%c_%c%c%c%c"
|
||||
#define TO_BIN(byte) \
|
||||
@ -236,19 +254,35 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data, bool runISR)
|
||||
assert(reg < rINVALID);
|
||||
VIA_State_t *via = &VIA_State[id];
|
||||
|
||||
uint8_t data_old = VIA_Read(id, reg);
|
||||
uint8_t vIFR_old = via->vIFR & via->vIER & 0b01111111;
|
||||
// Set up before/after comparisions
|
||||
uint8_t data_old = 0;
|
||||
if (reg == rIRA || reg == rORA) {
|
||||
//fprintf(stderr, "Set PA to "BIN_PAT"\n", TO_BIN(data));
|
||||
data_old = via->vBufA;
|
||||
} else if (reg == rIRB) {
|
||||
data_old = via->vBufB;
|
||||
} else if (reg == rIFR || reg == rIER) {
|
||||
//data_old = via->vIFR & via->vIER & 0b01111111;
|
||||
data_old = via->vIFR;
|
||||
} else if (reg == rACR) {
|
||||
data_old = via->vACR;
|
||||
}
|
||||
|
||||
/*if (reg == rIRA || reg == rORA) {
|
||||
fprintf(stderr, "Set PA to "BIN_PAT"\n", TO_BIN(data));
|
||||
} else {
|
||||
//`fprintf(stderr, "Set PB to "BIN_PAT"\n", TO_BIN(data));
|
||||
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) {
|
||||
fprintf(stderr, "vSR: %d, %d, %d\n", true, ((via->vACR & 0x1C) >> 2), data);
|
||||
}
|
||||
|
||||
switch(reg) {
|
||||
case rIRB: via->vIFR &= 0b11100111; // clear keyboard interrupts
|
||||
via->vBufB = data; break;
|
||||
case rIRA:
|
||||
case rORA: via->vBufA = data; break;
|
||||
case rORA: via->vIFR &= 0b11111100; // clear time interrupts
|
||||
via->vBufA = data; break;
|
||||
case rDDRB: via->vDirB = data; break;
|
||||
case rDDRA: via->vDirA = data; break;
|
||||
case rT1CL:
|
||||
@ -263,10 +297,10 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data, bool runISR)
|
||||
via->vT2C = via->vT2L;
|
||||
via->vIFR &= 0b10111111;
|
||||
break;
|
||||
case rSR: via->vSR = data; break;
|
||||
case rSR: VIA_ShiftInData_M68k(id, data); break;
|
||||
case rACR: via->vACR = data; break;
|
||||
case rPCR: via->vPCR = data; break;
|
||||
case rIFR: via->vIFR &= (~data & 0b01111111); break;
|
||||
case rIFR: via->vIFR &= (~data & 0b01111111); break; // seems to be correct?
|
||||
case rIER:
|
||||
switch(data & 0b10000000) {
|
||||
case 0b00000000: // clear
|
||||
@ -280,10 +314,6 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data, bool runISR)
|
||||
default: assert(true);
|
||||
}
|
||||
|
||||
/*if ((data_old & via->vIFR) != (data & via->vIFR) && reg == rIFR) {
|
||||
VIAorSCCinterruptChngNtfy();
|
||||
}*/
|
||||
|
||||
// Assert vBufA or vBufB ISRs if needed
|
||||
uint8_t diff = (data ^ data_old);
|
||||
if (runISR && (reg == rIRA || reg == rORA || reg == rIRB)) {
|
||||
@ -300,17 +330,41 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data, bool runISR)
|
||||
|
||||
// Run global ISR 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))
|
||||
{
|
||||
/*if (VIA_State[id].vISR[irq] != NULL) {
|
||||
VIA_State[id].vISR[irq]();
|
||||
}*/
|
||||
// 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;
|
||||
}
|
||||
VIAorSCCinterruptChngNtfy();
|
||||
//fprintf(stderr, "IRQ raised ("BIN_PAT")\n", TO_BIN((vIFR_old ^ vIFR_new)));
|
||||
fprintf(stderr, "IRQ raised ("BIN_PAT")\n", TO_BIN((vIFR_old ^ vIFR_new)));
|
||||
}
|
||||
else if (reg == rIFR || reg == rIER)
|
||||
{
|
||||
//fprintf(stderr, "IRQ attempt ("BIN_PAT")\n", TO_BIN((vIFR_old ^ vIFR_new)));
|
||||
fprintf(stderr, "IRQ attempt ("BIN_PAT")\n", TO_BIN((data_old ^ vIFR_new)));
|
||||
}
|
||||
|
||||
if (reg == rACR) {
|
||||
uint8_t ShiftMode = (via->vACR & 0x1C) >> 2;
|
||||
uint8_t ShiftMode_old = (data_old & 0x1C) >> 2;
|
||||
// Check if shift direction has changed
|
||||
if (ShiftMode != 0 && (ShiftMode & 0b100) != (ShiftMode_old & 0b100)) {
|
||||
if ((ShiftMode & 0b100) == 0) {
|
||||
VIA_RaiseInterrupt(id, 2);
|
||||
}
|
||||
}
|
||||
// Clear keyboard interrupt flag if we modified shift register params
|
||||
// Supposedly, this isn't sufficient. I have no idea what that means.
|
||||
else if (ShiftMode == 0) {
|
||||
VIA_LowerInterrupt(id, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,6 +375,10 @@ uint8_t VIA_Read(uint8_t id, VIA_Register_t reg)
|
||||
assert(reg < rINVALID);
|
||||
VIA_State_t *via = &VIA_State[id];
|
||||
|
||||
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,
|
||||
// but it shouldn't matter.
|
||||
@ -338,8 +396,7 @@ uint8_t VIA_Read(uint8_t id, VIA_Register_t reg)
|
||||
case rT2CL: via->vIFR &= 0b11011111; // TODO: is this used correctly?
|
||||
return (via->vT2C & 0xFF00) >> 8;
|
||||
case rT2CH: return (via->vT2C & 0x00FF);
|
||||
case rSR:
|
||||
return via->vSR;
|
||||
case rSR: return VIA_ShiftOutData_M68k(id);
|
||||
case rACR: return via->vACR;
|
||||
case rPCR: return via->vPCR;
|
||||
case rIFR: return via->vIFR;
|
||||
@ -348,6 +405,14 @@ uint8_t VIA_Read(uint8_t id, VIA_Register_t reg)
|
||||
}
|
||||
}
|
||||
|
||||
// temporary debugging thing
|
||||
/*uint8_t VIA_Read(uint8_t id, VIA_Register_t reg)
|
||||
{
|
||||
uint8_t result = VIA_Read2(id, reg);
|
||||
fprintf(stderr, "VIA%d Read %d -> %d\n", id+1, reg, result);
|
||||
return result;
|
||||
}*/
|
||||
|
||||
// Read a single bit
|
||||
bool VIA_ReadBit(uint8_t id, VIA_Register_t reg, uint8_t bit)
|
||||
{
|
||||
@ -369,56 +434,90 @@ void VIA_WriteBit(uint8_t id, VIA_Register_t reg, uint8_t bit, bool value, bool
|
||||
VIA_RunDataISR(id, reg, bit);*/
|
||||
}
|
||||
|
||||
// ShiftMode states (from M68k perspective)
|
||||
// 3: Shifting in (to M68k)
|
||||
// 6: Shifting out under O2 clock (raise interrupt when done)
|
||||
// 7: Shifting out
|
||||
|
||||
// Called by either end; store data in vSR.
|
||||
// TODO: this probably shouldn't be instant.
|
||||
void VIA_ShiftInData(uint8_t id, uint8_t v)
|
||||
void VIA_ShiftInData_M68k(uint8_t id, uint8_t v)
|
||||
{
|
||||
assert(id < VIA_MAXNUM);
|
||||
VIA_State_t *via = &VIA_State[id];
|
||||
|
||||
//VIA_LowerInterrupt(id, 2); // data ready
|
||||
uint8_t ShiftMode = (via->vACR & 0x1C) >> 2;
|
||||
assert(ShiftMode == 0 || ShiftMode == 3);
|
||||
|
||||
VIA_State[id].vSR = v;
|
||||
VIA_RaiseInterrupt(id, 2); // data ready
|
||||
VIA_RaiseInterrupt(id, 4); // data clock
|
||||
if (ShiftMode == 6) {
|
||||
VIA_RaiseInterrupt(id, 2); // data ready
|
||||
VIA_RaiseInterrupt(id, 4); // data clock
|
||||
}
|
||||
}
|
||||
|
||||
// Called by either end, get data out of vSR
|
||||
// TODO: this probably shouldn't be instant.
|
||||
uint8_t VIA_ShiftOutData(uint8_t id)
|
||||
uint8_t VIA_ShiftOutData_M68k(uint8_t id)
|
||||
{
|
||||
assert(id < VIA_MAXNUM);
|
||||
VIA_State_t *via = &VIA_State[id];
|
||||
|
||||
uint8_t ShiftMode = (via->vACR & 0x1C) >> 2;
|
||||
if (ShiftMode == 3) {
|
||||
VIA_RaiseInterrupt(id, 2); // data ready
|
||||
VIA_RaiseInterrupt(id, 4); // data clock
|
||||
// data bit
|
||||
if (via->vSR & 1) {
|
||||
VIA_RaiseInterrupt(id, 3);
|
||||
} else {
|
||||
VIA_LowerInterrupt(id, 3);
|
||||
}
|
||||
} else {
|
||||
VIA_LowerInterrupt(id, 2); // data ready
|
||||
}
|
||||
return VIA_State[id].vSR;
|
||||
}
|
||||
|
||||
// Same functions, from the peripheal end
|
||||
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);
|
||||
|
||||
assert(ShiftMode == 0 || ShiftMode == 3);
|
||||
|
||||
// Not immediately after startup?
|
||||
if (ShiftMode != 0) {
|
||||
VIA_State[id].vSR = v;
|
||||
VIA_RaiseInterrupt(id, 2); // data ready
|
||||
VIA_RaiseInterrupt(id, 4); // data clock
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this probably shouldn't be instant.
|
||||
uint8_t VIA_ShiftOutData_Ext(uint8_t id)
|
||||
{
|
||||
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", false, ShiftMode, VIA_State[id].vSR);
|
||||
assert(ShiftMode == 7);
|
||||
|
||||
VIA_RaiseInterrupt(id, 2); // data ready
|
||||
VIA_RaiseInterrupt(id, 3); // data rx
|
||||
VIA_WriteBit(id, rIFR, 4, (via->vSR & 1), false); // data clock
|
||||
VIA_RaiseInterrupt(id, 4); // data clock
|
||||
// data bit
|
||||
if (via->vSR & 1) {
|
||||
VIA_RaiseInterrupt(id, 3);
|
||||
} else {
|
||||
VIA_LowerInterrupt(id, 3);
|
||||
}
|
||||
return VIA_State[id].vSR;
|
||||
}
|
||||
|
||||
/// Old messy VIA timer code (VIA-1 only for now) ///
|
||||
|
||||
#define CyclesPerViaTime (10 * ClockMult)
|
||||
#define CyclesScaledPerViaTime (kCycleScale * CyclesPerViaTime)
|
||||
|
||||
// TODO: Move these into the VIA_State_t struct
|
||||
bool VIA1_T1Running = true;
|
||||
bool VIA1_T1IntReady = false;
|
||||
iCountt VIA1_T1LastTime = 0;
|
||||
uint8_t VIA1_T1_Active = 0;
|
||||
const uint8_t VIA_T1_IRQ = 6;
|
||||
|
||||
bool VIA1_T2Running = true;
|
||||
bool VIA1_T2IntReady = false;
|
||||
bool VIA1_T2C_ShortTime = false;
|
||||
iCountt VIA1_T2LastTime = 0;
|
||||
uint8_t VIA1_T2_Active = 0;
|
||||
const uint8_t VIA_T2_IRQ = 5;
|
||||
|
||||
|
||||
void VIA1_DoTimer1Check()
|
||||
{
|
||||
if (!VIA1_T1Running) { return; }
|
||||
|
@ -74,7 +74,7 @@ void VIA_Reset(void);
|
||||
// Raise an interrupt by irq number, calling registered ISR if required
|
||||
void VIA_RaiseInterrupt(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);
|
||||
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);
|
||||
|
||||
@ -90,9 +90,10 @@ 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);
|
||||
|
||||
// NOTE: for these, raise the interrupt manually w/ VIA_RaiseInterrupt
|
||||
void VIA_ShiftInData(uint8_t id, uint8_t v);
|
||||
uint8_t VIA_ShiftOutData(uint8_t id);
|
||||
void VIA_ShiftInData_M68k(uint8_t id, uint8_t v);
|
||||
uint8_t VIA_ShiftOutData_M68k(uint8_t id);
|
||||
void VIA_ShiftInData_Ext(uint8_t id, uint8_t v);
|
||||
uint8_t VIA_ShiftOutData_Ext(uint8_t id);
|
||||
|
||||
// Compatiblity stuff, probably
|
||||
void VIA1_DoTimer1Check();
|
||||
|
@ -112,7 +112,7 @@ const DevMethods_t DEVICES[] = {
|
||||
.timeend = NULL,
|
||||
},
|
||||
// SCC
|
||||
/* {
|
||||
{
|
||||
.init = NULL,
|
||||
.reset = SCC_Reset,
|
||||
.starttick = NULL,
|
||||
@ -120,7 +120,7 @@ const DevMethods_t DEVICES[] = {
|
||||
.subtick = NULL,
|
||||
.timebegin = NULL,
|
||||
.timeend = NULL,
|
||||
},*/
|
||||
},
|
||||
// SCSI
|
||||
{
|
||||
.init = NULL,
|
||||
@ -392,6 +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);
|
||||
return true;
|
||||
}
|
||||
// VBlank interrupt
|
||||
|
Loading…
x
Reference in New Issue
Block a user