Move all Mac Plus modules to new VIA code

The emulator is completely broken, but *at least* it compiles.
I should probably add the ICT task management back in. I forget why I
removed that. Maybe it was too tied to the old VIA implementation.
This commit is contained in:
InvisibleUp 2020-07-11 18:50:59 -04:00
parent 02b8c9c721
commit 0a2109f481
12 changed files with 317 additions and 213 deletions

View File

@ -36,6 +36,7 @@
#include "GLOBGLUE.h"
#include "HW/RAM/RAMADDR.h"
#include "HW/VIA/VIAEMDEV.h"
/*
ReportAbnormalID unused 0x111D - 0x11FF
@ -57,12 +58,9 @@ bool ControlKeyPressed = false;
IMPORTPROC m68k_reset(void);
IMPORTPROC IWM_Reset(void);
IMPORTPROC SCC_Reset(void);
//IMPORTPROC SCC_Reset(void);
IMPORTPROC SCSI_Reset(void);
IMPORTPROC VIA1_Reset(void);
#if EmVIA2
IMPORTPROC VIA2_Reset(void);
#endif
IMPORTPROC VIA_Reset(void);
IMPORTPROC Sony_Reset(void);
IMPORTPROC ExtnDisk_Access(CPTR p);
@ -84,12 +82,9 @@ IMPORTPROC SetHeadATTel(ATTep p);
IMPORTFUNC ATTep FindATTel(CPTR addr);
IMPORTFUNC uint32_t SCSI_Access(uint32_t Data, bool WriteMem, CPTR addr);
IMPORTFUNC uint32_t SCC_Access(uint32_t Data, bool WriteMem, CPTR addr);
//IMPORTFUNC uint32_t SCC_Access(uint32_t Data, bool WriteMem, CPTR addr);
IMPORTFUNC uint32_t IWM_Access(uint32_t Data, bool WriteMem, CPTR addr);
IMPORTFUNC uint32_t VIA1_Access(uint32_t Data, bool WriteMem, CPTR addr);
#if EmVIA2
IMPORTFUNC uint32_t VIA2_Access(uint32_t Data, bool WriteMem, CPTR addr);
#endif
//IMPORTFUNC uint32_t VIA1_Access(uint32_t Data, bool WriteMem, CPTR addr);
#if EmASC
IMPORTFUNC uint32_t ASC_Access(uint32_t Data, bool WriteMem, CPTR addr);
#endif
@ -107,12 +102,9 @@ GLOBALVAR uint32_t disk_icon_addr;
GLOBALPROC customreset(void)
{
IWM_Reset();
SCC_Reset();
//SCC_Reset();
SCSI_Reset();
VIA1_Reset();
#if EmVIA2
VIA2_Reset();
#endif
VIA_Reset();
Sony_Reset();
Extn_Reset();
#if CurEmMd <= kEmMd_Plus
@ -129,17 +121,8 @@ GLOBALPROC customreset(void)
}
GLOBALVAR uint8_t * RAM = nullpr;
#if EmVidCard
GLOBALVAR uint8_t * VidROM = nullpr;
#endif
#if IncludeVidMem
GLOBALVAR uint8_t * VidMem = nullpr;
#endif
GLOBALVAR uint8_t Wires[kNumWires];
#if WantDisasm
IMPORTPROC m68k_WantDisasmContext(void);
@ -1081,6 +1064,7 @@ LOCALPROC SetUp_RAM24(void)
LOCALPROC SetUp_address(void)
{
ATTer r;
bool MemOverlay = VIA_ReadBit(VIA1, rIRA, 4);
if (MemOverlay) {
r.cmpmask = Overlay_ROM_CmpZeroMask |
@ -1237,8 +1221,11 @@ GLOBALFUNC uint32_t MMDV_Access(ATTep p, uint32_t Data,
"access VIA1 nonstandard address");
}
#endif
Data = VIA1_Access(Data, WriteMem,
(addr >> 9) & kVIA1_Mask);
if (WriteMem) {
VIA_Write(VIA1, (addr >> 9) & kVIA1_Mask, Data);
} else {
Data = VIA_Read(VIA1, (addr >> 9) & kVIA1_Mask);
}
}
break;
@ -1250,11 +1237,10 @@ GLOBALFUNC uint32_t MMDV_Access(ATTep p, uint32_t Data,
|| (0x3e02 == (addr & 0x1FFFF))))
{
/* for weirdness at offset 0x71E in ROM */
Data =
(VIA2_Access(Data, WriteMem,
(addr >> 9) & kVIA2_Mask) << 8)
| VIA2_Access(Data, WriteMem,
(addr >> 9) & kVIA2_Mask);
Data = (
VIA_Read(VIA2, (addr >> 9) & kVIA2_Mask) << 8) |
VIA_Read(VIA2, (addr >> 9) & kVIA2_Mask);
);
} else {
ReportAbnormalID(0x1109, "access VIA2 word");
@ -1305,7 +1291,7 @@ GLOBALFUNC uint32_t MMDV_Access(ATTep p, uint32_t Data,
#endif
#endif
} else {
SCC_Reset();
//SCC_Reset();
}
} else
#endif
@ -1328,8 +1314,8 @@ GLOBALFUNC uint32_t MMDV_Access(ATTep p, uint32_t Data,
"access SCC nonstandard address");
}
#endif
Data = SCC_Access(Data, WriteMem,
(addr >> 1) & kSCC_Mask);
/*Data = SCC_Access(Data, WriteMem,
(addr >> 1) & kSCC_Mask);*/
}
break;
case kMMDV_Extn:
@ -1548,8 +1534,9 @@ GLOBALPROC VIAorSCCinterruptChngNtfy(void)
NewIPL = 0;
}
#else
uint8_t VIAandNotSCC = VIA1_InterruptRequest
& ~ SCCInterruptRequest;
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);
@ -1562,20 +1549,14 @@ GLOBALPROC VIAorSCCinterruptChngNtfy(void)
GLOBALFUNC bool AddrSpac_Init(void)
{
int i;
for (i = 0; i < kNumWires; i++) {
Wires[i] = 1;
}
MINEM68K_Init(
&CurIPL);
MINEM68K_Init(&CurIPL);
return true;
}
GLOBALPROC Memory_Reset(void)
{
MemOverlay = 1;
// reset memory overlay
VIA_WriteBit(VIA1, rIRA, 4, 1, false);
SetUpMemBanks();
}
@ -1626,7 +1607,7 @@ GLOBALFUNC bool FindKeyEvent(int *VirtualKey, bool *KeyDown)
#ifdef _VIA_Debug
#include <stdio.h>
#endif
/*
GLOBALVAR uimr ICTactive;
GLOBALVAR iCountt ICTwhen[kNumICTs];
@ -1650,7 +1631,7 @@ GLOBALFUNC iCountt GetCuriCount(void)
GLOBALPROC ICT_add(int taskid, uint32_t n)
{
/* n must be > 0 */
// n must be > 0
int32_t x = GetCyclesRemaining();
uint32_t when = NextiCount - x + n;
@ -1664,3 +1645,4 @@ GLOBALPROC ICT_add(int taskid, uint32_t n)
NextiCount = when;
}
}
*/

View File

@ -162,40 +162,6 @@ EXPORTPROC VIAorSCCinterruptChngNtfy(void);
EXPORTVAR(bool, InterruptButton)
EXPORTPROC SetInterruptButton(bool v);
enum {
kICT_SubTick,
#if EmClassicKbrd
kICT_Kybd_ReceiveCommand,
kICT_Kybd_ReceiveEndCommand,
#endif
#if EmADB
kICT_ADB_NewState,
#endif
#if EmPMU
kICT_PMU_Task,
#endif
kICT_VIA1_Timer1Check,
kICT_VIA1_Timer2Check,
#if EmVIA2
kICT_VIA2_Timer1Check,
kICT_VIA2_Timer2Check,
#endif
kNumICTs
};
EXPORTPROC ICT_add(int taskid, uint32_t n);
#define iCountt uint32_t
EXPORTFUNC iCountt GetCuriCount(void);
EXPORTPROC ICT_Zap(void);
EXPORTVAR(uimr, ICTactive)
EXPORTVAR(iCountt, ICTwhen[kNumICTs])
EXPORTVAR(iCountt, NextiCount)
EXPORTVAR(uint8_t, Wires[kNumWires])
#define kLn2CycleScale 6
#define kCycleScale (1 << kLn2CycleScale)

View File

@ -22,14 +22,12 @@
This code adapted from "Keyboard.c" in vMac by Philip Cummins.
*/
#ifndef AllFiles
#include "SYSDEPNS.h"
#include "UI/MYOSGLUE.h"
#include "EMCONFIG.h"
#include "GLOBGLUE.h"
#endif
#include "HW/KBRD/KBRDEMDV.h"
#include "HW/VIA/VIAEMDEV.h"
#ifdef _VIA_Debug
#include <stdio.h>
@ -39,8 +37,12 @@
ReportAbnormalID unused 0x0B03 - 0x0BFF
*/
IMPORTPROC KYBD_ShiftOutData(uint8_t v);
IMPORTFUNC uint8_t KYBD_ShiftInData(void);
void KYBD_ShiftOutData(uint8_t v) {
VIA_ShiftInData(VIA1, v);
}
uint8_t KYBD_ShiftInData(void) {
return VIA_ShiftOutData(VIA1);
}
enum {
kKybdStateIdle,
@ -62,11 +64,16 @@ LOCALPROC GotKeyBoardData(uint8_t v)
HaveKeyBoardResult = true;
KeyBoardResult = v;
} else {
KYBD_ShiftOutData(v);
VIA1_iCB2 = 1;
v = VIA_Read(VIA1, rSR);
VIA_RaiseInterrupt(VIA1, 2);
}
}
static bool Kybd_CheckDataReady()
{
return VIA_ReadBit(VIA1, rIFR, 2);
}
LOCALVAR uint8_t InstantCommandData = 0x7B;
LOCALFUNC bool AttemptToFinishInquiry(void)
@ -163,7 +170,6 @@ GLOBALPROC DoKybd_ReceiveEndCommand(void)
#endif
HaveKeyBoardResult = false;
KYBD_ShiftOutData(KeyBoardResult);
VIA1_iCB2 = 1;
}
}
}
@ -172,13 +178,13 @@ GLOBALPROC Kybd_DataLineChngNtfy(void)
{
switch (KybdState) {
case kKybdStateIdle:
if (VIA1_iCB2 == 0) {
if (Kybd_CheckDataReady() == 0) {
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 */
@ -186,14 +192,14 @@ GLOBALPROC Kybd_DataLineChngNtfy(void)
}
break;
case kKybdStateRecievedCommand:
if (VIA1_iCB2 == 1) {
if (Kybd_CheckDataReady() == 1) {
KybdState = kKybdStateRecievingEndCommand;
#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;
}

View File

@ -23,7 +23,6 @@
Macintosh port of vMac, by Philip Cummins.
*/
#ifndef AllFiles
#include "SYSDEPNS.h"
#include "UI/MYOSGLUE.h"
#include "UTIL/ENDIANAC.h"
@ -31,9 +30,38 @@
#include "GLOBGLUE.h"
#include "HW/SCC/SCCEMDEV.h"
#include "HW/M68K/MINEM68K.h"
#endif
#include "HW/MOUSE/MOUSEMDV.h"
#include "HW/VIA/VIAEMDEV.h"
static void Mouse_SetButtonUp(bool value)
{
switch(CurEmMd) {
case kEmMd_Twig43:
case kEmMd_Twiggy:
case kEmMd_128K:
case kEmMd_512Ke:
case kEmMd_Plus:
VIA_WriteBit(VIA1, rIRB, 3, value, false);
return;
default:
return;
}
}
static bool Mouse_Enabled()
{
switch(CurEmMd) {
case kEmMd_Twig43:
case kEmMd_Twiggy:
case kEmMd_128K:
case kEmMd_512Ke:
case kEmMd_Plus:
//return SCC_InterruptsEnabled();
return true;
default:
return false;
}
}
GLOBALPROC Mouse_Update(void)
{
@ -110,7 +138,7 @@ GLOBALPROC Mouse_Update(void)
(nullpr != (p = EvtQOutP())))
{
if (EvtQElKindMouseButton == p->kind) {
MouseBtnUp = p->u.press.down ? 0 : 1;
Mouse_SetButtonUp(p->u.press.down ? 0 : 1);
EvtQOutDone();
MasterEvtQLock = 4;
}

View File

@ -27,6 +27,7 @@
#include "UTIL/ENDIANAC.h"
#include "EMCONFIG.h"
#include "GLOBGLUE.h"
#include "HW/VIA/VIAEMDEV.h"
/* define _RTC_Debug */
#ifdef _RTC_Debug
@ -143,11 +144,53 @@ GLOBALPROC DumpRTC(void)
}
#endif
/// VIA interface wrappers ///////////////////////////////////////////////////
bool RTC_CheckEnabled()
{
// for all Macs except Portable, which isn't emulated yet,
return (VIA_ReadBit(VIA1, rIRB, 2) == 0);
}
bool RTC_CheckDataClock()
{
// for all Macs except Portable, which isn't emulated yet,
return (VIA_ReadBit(VIA1, rIRB, 1) == 0);
}
bool RTC_GetSerialData()
{
// for all Macs except Portable, which isn't emulated yet,
return (VIA_ReadBit(VIA1, rIRB, 0) == 0);
}
void RTC_SetSerialData(bool value)
{
// for all Macs except Portable, which isn't emulated yet,
VIA_WriteBit(VIA1, rIRB, 0, value, false);
}
// Register outgoing ISRs
void RTC_RegisterISRs()
{
// for all Macs except Portable, which isn't emulated yet,
VIA_RegisterDataISR(DataRegB, VIA1, 2, RTCunEnabled_ChangeNtfy);
VIA_RegisterDataISR(DataRegB, VIA1, 1, RTCclock_ChangeNtfy);
VIA_RegisterDataISR(DataRegB, VIA1, 0, RTCdataLine_ChangeNtfy);
}
void RTC_RaiseOneSecIRQ()
{
VIA_RaiseInterrupt(VIA1, 0);
}
/// End VIA wrappers /////////////////////////////////////////////////////////
GLOBALFUNC bool RTC_Init(void)
{
int Counter;
uint32_t secs;
RTC.Mode = RTC.ShiftData = RTC.Counter = 0;
RTC.DataOut = RTC.DataNextOut = 0;
RTC.WrProtect = false;
@ -296,13 +339,11 @@ if ((0 == vMacScreenDepth) || (vMacScreenDepth >= 4)) {
#endif /* RTCinitPRAM */
RTC_RegisterISRs();
return true;
}
#ifdef RTC_OneSecond_PulseNtfy
IMPORTPROC RTC_OneSecond_PulseNtfy(void);
#endif
GLOBALPROC RTC_Interrupt(void)
{
uint32_t Seconds = 0;
@ -319,10 +360,6 @@ GLOBALPROC RTC_Interrupt(void)
RTC.Seconds_1[3] = (Seconds & 0xFF000000) >> 24;
LastRealDate = NewRealDate;
#ifdef RTC_OneSecond_PulseNtfy
RTC_OneSecond_PulseNtfy();
#endif
}
}
@ -437,9 +474,11 @@ LOCALPROC RTC_DoCmd(void)
}
}
/// INTERRUPT SERVICE ROUTINES ///////////////////////////////////////////////
GLOBALPROC RTCunEnabled_ChangeNtfy(void)
{
if (RTCunEnabled) {
if (!RTC_CheckEnabled()) {
/* abort anything going on */
if (RTC.Counter != 0) {
#ifdef _RTC_Debug
@ -457,24 +496,22 @@ GLOBALPROC RTCunEnabled_ChangeNtfy(void)
GLOBALPROC RTCclock_ChangeNtfy(void)
{
if (! RTCunEnabled) {
if (RTCclock) {
RTC.DataOut = RTC.DataNextOut;
RTC.Counter = (RTC.Counter - 1) & 0x07;
if (RTC.DataOut) {
RTCdataLine = ((RTC.ShiftData >> RTC.Counter) & 0x01);
/*
should notify VIA if changed, so can check
data direction
*/
if (RTC.Counter == 0) {
RTC.DataNextOut = 0;
}
} else {
RTC.ShiftData = (RTC.ShiftData << 1) | RTCdataLine;
if (RTC.Counter == 0) {
RTC_DoCmd();
}
if (RTC_CheckEnabled() && RTC_CheckDataClock()) {
RTC.DataOut = RTC.DataNextOut;
RTC.Counter = (RTC.Counter - 1) & 0x07;
if (RTC.DataOut) {
RTC_SetSerialData((RTC.ShiftData >> RTC.Counter) & 0x01);
/*
should notify VIA if changed, so can check
data direction
*/
if (RTC.Counter == 0) {
RTC.DataNextOut = 0;
}
} else {
RTC.ShiftData = (RTC.ShiftData << 1) | RTC_GetSerialData();
if (RTC.Counter == 0) {
RTC_DoCmd();
}
}
}

View File

@ -38,6 +38,8 @@
"Zilog SCC/ESCC User's Manual".
*/
#if 0
#ifndef AllFiles
#include "SYSDEPNS.h"
@ -47,6 +49,7 @@
#endif
#include "HW/SCC/SCCEMDEV.h"
#include "HW/VIA/VIAEMDEV.h"
/*
ReportAbnormalID unused 0x0721, 0x0722, 0x074D - 0x07FF
@ -254,6 +257,33 @@ static int rx_data_offset = 0;
/* when data pending, this is used */
#endif
/// VIA INTERFACE FUNCTIONS //////////////////////////////////////////////////
bool SCC_GetvSCCWrReq()
{
return VIA_ReadBit(VIA1, rIRA, 7);
}
void SCC_SetvSCCWrReq(bool value)
{
VIA_WriteBit(VIA1, rIRA, 7, value, false);
}
bool SCC_GetvSync()
{
switch(CurEmMd) {
case kEmMd_SE:
case kEmMd_SEFDHD:
case kEmMd_II:
case kEmMd_IIx:
return VIA_ReadBit(VIA1, rIRA, 3);
default:
return false;
}
}
/// END VIA INTERFACE FUNCTIONS //////////////////////////////////////////////
EXPORTFUNC bool SCC_InterruptsEnabled(void)
{
return SCC.MIE;
@ -2799,3 +2829,5 @@ GLOBALFUNC uint32_t SCC_Access(uint32_t Data, bool WriteMem, CPTR addr)
return Data;
}
#endif

View File

@ -31,6 +31,7 @@
#include "EMCONFIG.h"
#include "GLOBGLUE.h"
#include "HW/SCREEN/SCRNEMDV.h"
#include "HW/VIA/VIAEMDEV.h"
#include "CFGMAN.h"
#if ! IncludeVidMem
@ -55,6 +56,11 @@ bool UseLargeScreenHack;
char *ScreenColorBlack = NULL;
char *ScreenColorWhite = NULL;
bool Screen_UseMainPage()
{
return VIA_ReadBit(VIA1, rIRA, 6);
}
bool Screen_Init(void)
{
// enable a palette because heck it
@ -101,7 +107,7 @@ void Screen_EndTickNotify(void)
#if IncludeVidMem
screencurrentbuff = VidMem;
#else
if (SCRNvPage2 == 1) {
if (Screen_UseMainPage()) {
screencurrentbuff = get_ram_address(kMain_Buffer);
} else {
screencurrentbuff = get_ram_address(kAlternate_Buffer);
@ -110,3 +116,8 @@ void Screen_EndTickNotify(void)
Screen_OutputFrame(screencurrentbuff);
}
void Screen_RaiseVBlank()
{
VIA_RaiseInterrupt(VIA1, 1);
}

View File

@ -21,6 +21,7 @@
bool Screen_LoadCfg(void);
bool Screen_Init(void);
void Screen_EndTickNotify(void);
void Screen_RaiseVBlank();
extern uint16_t vMacScreenHeight;
extern uint16_t vMacScreenWidth;

View File

@ -17,24 +17,19 @@
/*
SouND EMulated DEVice
Emulation of Sound in the Mac Plus could go here.
Emulation of pre-ASC sound circuitry
This code adapted from "Sound.c" in vMac by Philip Cummins.
*/
#ifndef AllFiles
#include "SYSDEPNS.h"
#include "UI/MYOSGLUE.h"
#include "EMCONFIG.h"
#include "GLOBGLUE.h"
#include "HW/M68K/MINEM68K.h"
#endif
#include "HW/SOUND/SNDEMDEV.h"
#if SoundEnabled
#include "HW/VIA/VIAEMDEV.h"
#define kSnd_Main_Offset 0x0300
#define kSnd_Alt_Offset 0x5F00
@ -102,10 +97,28 @@ LOCALVAR const uint8_t SubTick_n[kNumSubTicks] = {
LOCALVAR uint32_t SoundInvertPhase = 0;
LOCALVAR uint16_t SoundInvertState = 0;
IMPORTFUNC uint16_t GetSoundInvertTime(void);
/// VIA INTERFACE FUNCTIONS //////////////////////////////////////////////////
uint8_t MacSound_GetVolume()
{
return VIA_Read(VIA1, rIRA) & 0b00000111;
}
bool MacSound_CheckDisabled()
{
return VIA_ReadBit(VIA1, rIRB, 7);
}
bool MacSound_NeedAltBuffer()
{
return !VIA_ReadBit(VIA1, rIRA, 3);
}
/// END VIA FUNCTIONS ////////////////////////////////////////////////////////
GLOBALPROC MacSound_SubTick(int SubTick)
{
if (!SoundEnabled) { return; }
uint16_t actL;
tpSoundSamp p;
uint16_t i;
@ -121,10 +134,10 @@ GLOBALPROC MacSound_SubTick(int SubTick)
#else
CPTR addr = addy + (2 * StartOffset);
#endif
uint16_t SoundInvertTime = GetSoundInvertTime();
uint8_t SoundVolume = SoundVolb0
| (SoundVolb1 << 1)
| (SoundVolb2 << 2);
uint16_t SoundInvertTime = ((VIA_Read(VIA1, rT1CH) << 8) | VIA_Read(VIA1, rT1CL));
uint8_t SoundVolume = MacSound_GetVolume();
bool SoundDisable = MacSound_CheckDisabled();
if (VIA_ReadBit(VIA1, rACR, 7) == 0) { SoundInvertTime = 0; }
#if dbglog_HAVE && 0
dbglog_StartLine();
@ -219,5 +232,3 @@ label_retry:
}
}
}
#endif

View File

@ -34,6 +34,10 @@ VIA_State_t VIA_State[VIA_MAXNUM];
// Hardware reset
bool VIA_Zap(void) {
memset(VIA_State, 0, sizeof(VIA_State));
for (int i = 0; i < VIA_MAXNUM; i += 1) {
VIA_State[i].vBufA = 0xFF;
VIA_State[i].vBufB = 0xFF;
}
return true;
}
// Software reset
@ -44,27 +48,44 @@ void VIA_Reset(void) {
// Raise an interrupt by irq number
void VIA_RaiseInterrupt(uint8_t id, uint8_t irq)
{
assert (id == 0 || id == 1);
assert (irq <= 6);
assert (id < VIA_MAXNUM);
assert (irq < 7);
// Set interrupt flag
VIA_State[id].vIFR |= (1 << irq) | (1 << 7);
// Call interrupt handler, if required
/*// Call interrupt handler, if required
if (VIA_State[id].vISR[irq] != NULL) {
VIA_State[id].vISR[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)
{
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)
{
assert(id < VIA_MAXNUM);
assert(port == DataRegA || port == DataRegB);
assert(irq < 8);
if (port == DataRegA) {
VIA_State[id].vISR_A[irq] = isr;
} else {
VIA_State[id].vISR_B[irq] = isr;
}
}
// Tick VIA timer 1 (and set PB7 as needed)
static void VIA_TickTimer1(uint8_t id)
{
assert(id < VIA_MAXNUM);
VIA_State_t *via = &VIA_State[id];
uint8_t T1_MODE = (via->vACR & 0b11000000) >> 6;
bool T1_PULSE = (T1_MODE & 0b01) != 0;
@ -82,6 +103,7 @@ static void VIA_TickTimer1(uint8_t id)
// Tick VIA timer 2. Raise interrupt if required
static void VIA_TickTimer2(uint8_t id, bool forceTick)
{
assert(id < VIA_MAXNUM);
VIA_State_t *via = &VIA_State[id];
// Check we're not in the mode where T2 counts PB6 falling edges
bool T2_ISCOUNTER = VIA_ReadBit(id, rACR, 5);
@ -95,21 +117,18 @@ static void VIA_TickTimer2(uint8_t id, bool forceTick)
// Tick all timers by one step (call every 1.2766 us)
void VIA_TickTimers()
{
for (uint8_t id = 0; id < 2; id += 1) {
for (uint8_t id = 0; id < VIA_MAXNUM; id += 1) {
VIA_TickTimer1(id);
VIA_TickTimer2(id, false);
}
}
// Write to a register
// Write to a register, bypassing data ISRs
void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data)
{
assert(id == 0 || id == 1);
assert(id < VIA_MAXNUM);
assert(reg < rINVALID);
// store PB6's state
bool PB6_old = VIA_ReadBit(id, rIRB, 6);
VIA_State_t *via = &VIA_State[id];
switch(reg) {
@ -146,19 +165,12 @@ void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data)
break;
default: assert(true);
}
// Decrement timer 2 if in counter mode and PB6 hits falling edge
bool PB6_new = VIA_ReadBit(id, rIRB, 6);
bool T2_ISCOUNTER = VIA_ReadBit(id, rACR, 5);
if (PB6_old == true && PB6_new == false && T2_ISCOUNTER) {
VIA_TickTimer2(id, true);
}
}
// Read to a register
uint8_t VIA_Read(uint8_t id, VIA_Register_t reg)
{
assert(id == 0 || id == 1);
assert(id < VIA_MAXNUM);
assert(reg < rINVALID);
VIA_State_t *via = &VIA_State[id];
@ -170,14 +182,14 @@ uint8_t VIA_Read(uint8_t id, VIA_Register_t reg)
case rORA: return via->vBufA;
case rDDRB: return via->vDirB;
case rDDRA: return via->vDirA;
case rT1CL: via->vIFR &= 0b10111111;
return (via->vT1C & 0xFF00);
case rT1CH: return (via->vT1C & 0x00FF) >> 8;
case rT1LL: return (via->vT1L & 0xFF00);
case rT1LH: return (via->vT1L & 0x00FF) >> 8;
case rT2CL: via->vIFR &= 0b11011111;
return (via->vT2C & 0xFF00);
case rT2CH: return (via->vT2C & 0x00FF) >> 8;
case rT1CL: //via->vIFR &= 0b10111111;
return (via->vT1C & 0xFF00) >> 8;
case rT1CH: return (via->vT1C & 0x00FF);
case rT1LL: return (via->vT1L & 0xFF00) >> 8;
case rT1LH: return (via->vT1L & 0x00FF);
case rT2CL: //via->vIFR &= 0b11011111;
return (via->vT2C & 0xFF00) >> 8;
case rT2CH: return (via->vT2C & 0x00FF);
case rSR: return via->vSR;
case rACR: return via->vACR;
case rPCR: return via->vPCR;
@ -194,19 +206,32 @@ bool VIA_ReadBit(uint8_t id, VIA_Register_t reg, uint8_t bit)
}
// Write a single bit
void VIA_WriteBit(uint8_t id, VIA_Register_t reg, uint8_t bit, bool set)
void VIA_WriteBit(uint8_t id, VIA_Register_t reg, uint8_t bit, bool value, bool runISR)
{
uint8_t data = VIA_Read(id, reg);
if (set) { data |= (1 << bit); }
else { data &= ~(1 << bit); }
uint8_t olddata = VIA_Read(id, reg);
uint8_t data = olddata;
if (value) { data |= (1 << bit); } // set
else { data &= ~(1 << bit); } // clear
VIA_Write(id, reg, data);
// Call data-change ISR
if (!runISR || (data == olddata)) { return; }
if (reg == rIRA || reg == rORA) {
if (VIA_State[id].vISR_A[bit] != NULL) {
VIA_State[id].vISR_A[bit]();
}
} else if (reg == rIRB) {
if (VIA_State[id].vISR_B[bit] != NULL) {
VIA_State[id].vISR_B[bit]();
}
}
}
// Called by either end; store data in vSR.
// TODO: this probably shouldn't be instant.
void VIA_ShiftInData(uint8_t id, uint8_t v)
{
assert(id == 0 | id == 1);
assert(id < VIA_MAXNUM);
VIA_State[id].vSR = v;
}
@ -214,6 +239,7 @@ void VIA_ShiftInData(uint8_t id, uint8_t v)
// TODO: this probably shouldn't be instant.
uint8_t VIA_ShiftOutData(uint8_t id)
{
assert(id < VIA_MAXNUM);
return VIA_State[id].vSR;
}

View File

@ -32,7 +32,10 @@ typedef struct {
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
//VIA_ISR_t vISR[8]; // ISRs to automatically call when interrupt is raised
VIA_ISR_t vISR_A[8]; // ISRs to call when vBufA changes
VIA_ISR_t vISR_B[8]; // ISRs to call when vBufB changes
} VIA_State_t;
/* Names from SY6522 datasheet */
@ -56,6 +59,11 @@ typedef enum {
rINVALID = 16, // end of list
} VIA_Register_t;
#define DataRegA 0
#define DataRegB 1
#define VIA1 0
#define VIA2 1
/// PUBLIC FUNCTIONS /////////////////////////////////////////////////////////
// Hardware reset
@ -66,19 +74,21 @@ 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);
// Tick all timers by one step (call every 1.2766 us)
void VIA_TickTimers();
// Write to a register
// Write to a register. Does not raise data ISRs.
void VIA_Write(uint8_t id, VIA_Register_t reg, uint8_t data);
// Read to a register
uint8_t VIA_Read(uint8_t id, VIA_Register_t reg);
// Read a single bit
bool VIA_ReadBit(uint8_t id, VIA_Register_t reg, uint8_t bit);
// Write a single bit
void VIA_WriteBit(uint8_t id, VIA_Register_t reg, uint8_t bit, bool set);
// 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);

View File

@ -60,6 +60,16 @@ typedef struct DevMethods {
} DevMethods_t;
const DevMethods_t DEVICES[] = {
// VIA
{
.init = VIA_Zap,
.reset = VIA_Reset,
.starttick = VIA_TickTimers,
.endtick = NULL,
.subtick = NULL,
.timebegin = NULL,
.timeend = NULL,
},
// RTC
{
.init = EmRTC ? RTC_Init : NULL,
@ -90,16 +100,6 @@ const DevMethods_t DEVICES[] = {
.timebegin = NULL,
.timeend = NULL,
},
// ICT
{
.init = NULL,
.reset = ICT_Zap,
.starttick = NULL,
.endtick = NULL,
.subtick = NULL,
.timebegin = NULL,
.timeend = NULL,
},
// IWM
{
.init = NULL,
@ -111,7 +111,7 @@ const DevMethods_t DEVICES[] = {
.timeend = NULL,
},
// SCC
{
/* {
.init = NULL,
.reset = SCC_Reset,
.starttick = NULL,
@ -119,7 +119,7 @@ const DevMethods_t DEVICES[] = {
.subtick = NULL,
.timebegin = NULL,
.timeend = NULL,
},
},*/
// SCSI
{
.init = NULL,
@ -130,16 +130,6 @@ const DevMethods_t DEVICES[] = {
.timebegin = NULL,
.timeend = NULL,
},
// VIA1
{
.init = VIA_Zap,
.reset = VIA_Reset,
.starttick = VIA_TickTimers,
.endtick = NULL,
.subtick = NULL,
.timebegin = NULL,
.timeend = NULL,
},
// Sony disk drive
{
.init = NULL,
@ -243,7 +233,7 @@ const DevMethods_t DEVICES[] = {
{
.init = Screen_Init,
.reset = NULL,
.starttick = Sixtieth_PulseNtfy, // VBlank interrupt
.starttick = Screen_RaiseVBlank,
.endtick = Screen_EndTickNotify,
.subtick = NULL,
.timebegin = NULL,
@ -303,14 +293,14 @@ LOCALPROC SubTickTaskDo(void)
might not equal CyclesScaledPerTick.
*/
ICT_add(kICT_SubTick, CyclesScaledPerSubTick);
//ICT_add(kICT_SubTick, CyclesScaledPerSubTick);
}
}
LOCALPROC SubTickTaskStart(void)
{
SubTickCounter = 0;
ICT_add(kICT_SubTick, CyclesScaledPerSubTick);
//ICT_add(kICT_SubTick, CyclesScaledPerSubTick);
}
LOCALPROC SubTickTaskEnd(void)
@ -334,7 +324,8 @@ LOCALPROC SixtiethSecondNotify(void)
if (EmClassicKbrd) { KeyBoard_Update(); }
//if (EmADB) { ADB_Update(); }
Sixtieth_PulseNtfy(); /* Vertical Blanking Interrupt */
//Sixtieth_PulseNtfy(); /* Vertical Blanking Interrupt */
Screen_RaiseVBlank();
Sony_Update();
#if EmLocalTalk
@ -398,7 +389,9 @@ LOCALFUNC bool InitEmulation(void)
EmulatedHardwareZap();
return true;
}
// VBlank interrupt
#if 0
LOCALPROC ICT_DoTask(int taskid)
{
switch (taskid) {
@ -478,18 +471,19 @@ LOCALFUNC uint32_t ICT_DoGetNext(uint32_t maxn)
return v;
}
#endif
LOCALPROC m68k_go_nCycles_1(uint32_t n)
{
uint32_t n2;
uint32_t StopiCount = NextiCount + n;
do {
ICT_DoCurrentTasks();
//uint32_t n2;
//uint32_t StopiCount = NextiCount + n;
//do {
/*ICT_DoCurrentTasks();
n2 = ICT_DoGetNext(n);
NextiCount += n2;
m68k_go_nCycles(n2);
n = StopiCount - NextiCount;
} while (n != 0);
NextiCount += n2;*/
m68k_go_nCycles(n);
//n = StopiCount - NextiCount;
//} while (n != 0);
}
LOCALVAR uint32_t ExtraSubTicksToDo = 0;