mirror of
https://github.com/wavemotion-dave/GimliDS.git
synced 2025-06-18 22:05:33 -04:00
Version 1.0a - fix for TOD clock not running (fixes some utilities). Slight VIC refactor for additional speed (1-2 frames).
This commit is contained in:
parent
12cad5f3fa
commit
26d89638b1
BIN
GimliDS.nds
BIN
GimliDS.nds
Binary file not shown.
2
Makefile
2
Makefile
@ -9,7 +9,7 @@ include $(DEVKITARM)/ds_rules
|
|||||||
|
|
||||||
export TARGET := GimliDS
|
export TARGET := GimliDS
|
||||||
export TOPDIR := $(CURDIR)
|
export TOPDIR := $(CURDIR)
|
||||||
export VERSION := 1.0
|
export VERSION := 1.0a
|
||||||
|
|
||||||
ICON := -b $(CURDIR)/C64_icon.bmp "GimliDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/GimliDS"
|
ICON := -b $(CURDIR)/C64_icon.bmp "GimliDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/GimliDS"
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
@ -86,13 +86,15 @@ void MOS6526::Reset(void)
|
|||||||
ta = tb = 0xffff;
|
ta = tb = 0xffff;
|
||||||
latcha = latchb = 1;
|
latcha = latchb = 1;
|
||||||
|
|
||||||
tod_10ths = tod_sec = tod_min = tod_hr = 0;
|
tod_10ths = tod_sec = tod_min = 0; tod_hr = 1;
|
||||||
alm_10ths = alm_sec = alm_min = alm_hr = 0;
|
alm_10ths = alm_sec = alm_min = alm_hr = 0;
|
||||||
|
|
||||||
sdr = icr = cra = crb = int_mask = 0;
|
sdr = icr = cra = crb = int_mask = 0;
|
||||||
|
|
||||||
tod_halt = ta_cnt_phi2 = tb_cnt_phi2 = tb_cnt_ta = false;
|
ta_cnt_phi2 = tb_cnt_phi2 = tb_cnt_ta = false;
|
||||||
tod_divider = 0;
|
tod_divider = 0;
|
||||||
|
tod_alarm = false;
|
||||||
|
tod_halt = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MOS6526_1::Reset(void)
|
void MOS6526_1::Reset(void)
|
||||||
@ -231,12 +233,13 @@ uint8 MOS6526_1::ReadRegister(uint16 adr)
|
|||||||
case 0x05: return ta >> 8;
|
case 0x05: return ta >> 8;
|
||||||
case 0x06: return tb;
|
case 0x06: return tb;
|
||||||
case 0x07: return tb >> 8;
|
case 0x07: return tb >> 8;
|
||||||
case 0x08: tod_halt = false; return tod_10ths;
|
case 0x08: return tod_10ths; // TODO: unlatch
|
||||||
case 0x09: return tod_sec;
|
case 0x09: return tod_sec;
|
||||||
case 0x0a: return tod_min;
|
case 0x0a: return tod_min;
|
||||||
case 0x0b: tod_halt = true; return tod_hr;
|
case 0x0b: return tod_hr; // TODO: latch
|
||||||
case 0x0c: return sdr;
|
case 0x0c: return sdr;
|
||||||
case 0x0d: {
|
case 0x0d:
|
||||||
|
{
|
||||||
uint8 ret = icr; // Read and clear ICR
|
uint8 ret = icr; // Read and clear ICR
|
||||||
icr = 0;
|
icr = 0;
|
||||||
the_cpu->ClearCIAIRQ(); // Clear IRQ
|
the_cpu->ClearCIAIRQ(); // Clear IRQ
|
||||||
@ -265,12 +268,13 @@ uint8 MOS6526_2::ReadRegister(uint16 adr)
|
|||||||
case 0x05: return ta >> 8;
|
case 0x05: return ta >> 8;
|
||||||
case 0x06: return tb;
|
case 0x06: return tb;
|
||||||
case 0x07: return tb >> 8;
|
case 0x07: return tb >> 8;
|
||||||
case 0x08: tod_halt = false; return tod_10ths;
|
case 0x08: return tod_10ths; // TODO: unlatch
|
||||||
case 0x09: return tod_sec;
|
case 0x09: return tod_sec;
|
||||||
case 0x0a: return tod_min;
|
case 0x0a: return tod_min;
|
||||||
case 0x0b: tod_halt = true; return tod_hr;
|
case 0x0b: return tod_hr; // TODO: latch
|
||||||
case 0x0c: return sdr;
|
case 0x0c: return sdr;
|
||||||
case 0x0d: {
|
case 0x0d:
|
||||||
|
{
|
||||||
uint8 ret = icr; // Read and clear ICR
|
uint8 ret = icr; // Read and clear ICR
|
||||||
icr = 0;
|
icr = 0;
|
||||||
the_cpu->ClearNMI(); // Clear NMI
|
the_cpu->ClearNMI(); // Clear NMI
|
||||||
@ -324,28 +328,49 @@ void MOS6526_1::WriteRegister(uint16 adr, uint8 byte)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x8:
|
case 0x8:
|
||||||
if (crb & 0x80)
|
byte &= 0x0f;
|
||||||
alm_10ths = byte & 0x0f;
|
if (crb & 0x80)
|
||||||
else
|
{
|
||||||
tod_10ths = byte & 0x0f;
|
if (alm_10ths != byte)
|
||||||
|
{
|
||||||
|
check_tod_alarm();
|
||||||
|
}
|
||||||
|
alm_10ths = byte;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tod_10ths != byte)
|
||||||
|
{
|
||||||
|
check_tod_alarm();
|
||||||
|
}
|
||||||
|
tod_10ths = byte;
|
||||||
|
tod_halt = false;
|
||||||
|
}
|
||||||
|
check_tod_alarm();
|
||||||
break;
|
break;
|
||||||
case 0x9:
|
case 0x9:
|
||||||
if (crb & 0x80)
|
if (crb & 0x80)
|
||||||
alm_sec = byte & 0x7f;
|
alm_sec = byte & 0x7f;
|
||||||
else
|
else
|
||||||
tod_sec = byte & 0x7f;
|
tod_sec = byte & 0x7f;
|
||||||
|
check_tod_alarm();
|
||||||
break;
|
break;
|
||||||
case 0xa:
|
case 0xa:
|
||||||
if (crb & 0x80)
|
if (crb & 0x80)
|
||||||
alm_min = byte & 0x7f;
|
alm_min = byte & 0x7f;
|
||||||
else
|
else
|
||||||
tod_min = byte & 0x7f;
|
tod_min = byte & 0x7f;
|
||||||
|
check_tod_alarm();
|
||||||
break;
|
break;
|
||||||
case 0xb:
|
case 0xb:
|
||||||
if (crb & 0x80)
|
if (crb & 0x80)
|
||||||
alm_hr = byte & 0x9f;
|
alm_hr = byte & 0x9f;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
tod_hr = byte & 0x9f;
|
tod_hr = byte & 0x9f;
|
||||||
|
tod_halt = true;
|
||||||
|
}
|
||||||
|
check_tod_alarm();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xc:
|
case 0xc:
|
||||||
@ -357,8 +382,8 @@ void MOS6526_1::WriteRegister(uint16 adr, uint8 byte)
|
|||||||
if (ThePrefs.CIAIRQHack) // Hack for addressing modes that read from the address
|
if (ThePrefs.CIAIRQHack) // Hack for addressing modes that read from the address
|
||||||
icr = 0;
|
icr = 0;
|
||||||
if (byte & 0x80) {
|
if (byte & 0x80) {
|
||||||
int_mask |= byte & 0x7f;
|
int_mask |= byte & 0x1f;
|
||||||
if (icr & int_mask & 0x1f) { // Trigger IRQ if pending
|
if (icr & int_mask) { // Trigger IRQ if pending
|
||||||
icr |= 0x80;
|
icr |= 0x80;
|
||||||
the_cpu->TriggerCIAIRQ();
|
the_cpu->TriggerCIAIRQ();
|
||||||
}
|
}
|
||||||
@ -393,7 +418,8 @@ inline void MOS6526_2::write_pa(uint8_t byte)
|
|||||||
| ((byte << 2) & 0x40) // CLK
|
| ((byte << 2) & 0x40) // CLK
|
||||||
| ((byte << 1) & 0x10); // ATN
|
| ((byte << 1) & 0x10); // ATN
|
||||||
|
|
||||||
if ((IECLines ^ old_lines) & 0x10) { // ATN changed
|
if ((IECLines ^ old_lines) & 0x10) // ATN changed
|
||||||
|
{
|
||||||
the_cpu_1541->NewATNState();
|
the_cpu_1541->NewATNState();
|
||||||
if (old_lines & 0x10) // ATN 1->0
|
if (old_lines & 0x10) // ATN 1->0
|
||||||
the_cpu_1541->TriggerIECInterrupt();
|
the_cpu_1541->TriggerIECInterrupt();
|
||||||
@ -438,28 +464,48 @@ void MOS6526_2::WriteRegister(uint16 adr, uint8 byte)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x8:
|
case 0x8:
|
||||||
if (crb & 0x80)
|
byte &= 0x0f;
|
||||||
alm_10ths = byte & 0x0f;
|
if (crb & 0x80)
|
||||||
else
|
{
|
||||||
tod_10ths = byte & 0x0f;
|
if (alm_10ths != byte)
|
||||||
break;
|
{
|
||||||
|
check_tod_alarm();
|
||||||
|
}
|
||||||
|
alm_10ths = byte;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tod_10ths != byte)
|
||||||
|
{
|
||||||
|
check_tod_alarm();
|
||||||
|
}
|
||||||
|
tod_10ths = byte;
|
||||||
|
tod_halt = false;
|
||||||
|
}
|
||||||
|
check_tod_alarm();
|
||||||
case 0x9:
|
case 0x9:
|
||||||
if (crb & 0x80)
|
if (crb & 0x80)
|
||||||
alm_sec = byte & 0x7f;
|
alm_sec = byte & 0x7f;
|
||||||
else
|
else
|
||||||
tod_sec = byte & 0x7f;
|
tod_sec = byte & 0x7f;
|
||||||
|
check_tod_alarm();
|
||||||
break;
|
break;
|
||||||
case 0xa:
|
case 0xa:
|
||||||
if (crb & 0x80)
|
if (crb & 0x80)
|
||||||
alm_min = byte & 0x7f;
|
alm_min = byte & 0x7f;
|
||||||
else
|
else
|
||||||
tod_min = byte & 0x7f;
|
tod_min = byte & 0x7f;
|
||||||
|
check_tod_alarm();
|
||||||
break;
|
break;
|
||||||
case 0xb:
|
case 0xb:
|
||||||
if (crb & 0x80)
|
if (crb & 0x80)
|
||||||
alm_hr = byte & 0x9f;
|
alm_hr = byte & 0x9f;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
tod_hr = byte & 0x9f;
|
tod_hr = byte & 0x9f;
|
||||||
|
tod_halt = true;
|
||||||
|
}
|
||||||
|
check_tod_alarm();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xc:
|
case 0xc:
|
||||||
@ -505,11 +551,14 @@ void MOS6526_2::WriteRegister(uint16 adr, uint8 byte)
|
|||||||
void MOS6526::CountTOD(void)
|
void MOS6526::CountTOD(void)
|
||||||
{
|
{
|
||||||
uint8 lo, hi;
|
uint8 lo, hi;
|
||||||
|
|
||||||
|
if (tod_halt) return; // Clock halted - skip clocking
|
||||||
|
|
||||||
// Decrement frequency divider
|
// Decrement frequency divider
|
||||||
if (tod_divider)
|
if (tod_divider)
|
||||||
tod_divider--;
|
tod_divider--;
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
|
|
||||||
// Reload divider according to 50/60 Hz flag
|
// Reload divider according to 50/60 Hz flag
|
||||||
if (cra & 0x80)
|
if (cra & 0x80)
|
||||||
@ -519,27 +568,32 @@ void MOS6526::CountTOD(void)
|
|||||||
|
|
||||||
// 1/10 seconds
|
// 1/10 seconds
|
||||||
tod_10ths++;
|
tod_10ths++;
|
||||||
if (tod_10ths > 9) {
|
if (tod_10ths > 9)
|
||||||
|
{
|
||||||
tod_10ths = 0;
|
tod_10ths = 0;
|
||||||
|
|
||||||
// Seconds
|
// Seconds
|
||||||
lo = (tod_sec & 0x0f) + 1;
|
lo = (tod_sec & 0x0f) + 1;
|
||||||
hi = tod_sec >> 4;
|
hi = tod_sec >> 4;
|
||||||
if (lo > 9) {
|
if (lo > 9)
|
||||||
|
{
|
||||||
lo = 0;
|
lo = 0;
|
||||||
hi++;
|
hi++;
|
||||||
}
|
}
|
||||||
if (hi > 5) {
|
if (hi > 5)
|
||||||
|
{
|
||||||
tod_sec = 0;
|
tod_sec = 0;
|
||||||
|
|
||||||
// Minutes
|
// Minutes
|
||||||
lo = (tod_min & 0x0f) + 1;
|
lo = (tod_min & 0x0f) + 1;
|
||||||
hi = tod_min >> 4;
|
hi = tod_min >> 4;
|
||||||
if (lo > 9) {
|
if (lo > 9)
|
||||||
|
{
|
||||||
lo = 0;
|
lo = 0;
|
||||||
hi++;
|
hi++;
|
||||||
}
|
}
|
||||||
if (hi > 5) {
|
if (hi > 5)
|
||||||
|
{
|
||||||
tod_min = 0;
|
tod_min = 0;
|
||||||
|
|
||||||
// Hours
|
// Hours
|
||||||
@ -559,10 +613,7 @@ void MOS6526::CountTOD(void)
|
|||||||
tod_sec = (hi << 4) | lo;
|
tod_sec = (hi << 4) | lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alarm time reached? Trigger interrupt if enabled
|
check_tod_alarm();
|
||||||
if (tod_10ths == alm_10ths && tod_sec == alm_sec &&
|
|
||||||
tod_min == alm_min && tod_hr == alm_hr)
|
|
||||||
TriggerInterrupt(4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,7 +625,8 @@ void MOS6526::CountTOD(void)
|
|||||||
void MOS6526_1::TriggerInterrupt(int bit)
|
void MOS6526_1::TriggerInterrupt(int bit)
|
||||||
{
|
{
|
||||||
icr |= bit;
|
icr |= bit;
|
||||||
if (int_mask & bit) {
|
if (int_mask & bit)
|
||||||
|
{
|
||||||
icr |= 0x80;
|
icr |= 0x80;
|
||||||
the_cpu->TriggerCIAIRQ();
|
the_cpu->TriggerCIAIRQ();
|
||||||
}
|
}
|
||||||
@ -588,7 +640,8 @@ void MOS6526_1::TriggerInterrupt(int bit)
|
|||||||
void MOS6526_2::TriggerInterrupt(int bit)
|
void MOS6526_2::TriggerInterrupt(int bit)
|
||||||
{
|
{
|
||||||
icr |= bit;
|
icr |= bit;
|
||||||
if (int_mask & bit) {
|
if (int_mask & bit)
|
||||||
|
{
|
||||||
icr |= 0x80;
|
icr |= 0x80;
|
||||||
the_cpu->TriggerNMI();
|
the_cpu->TriggerNMI();
|
||||||
}
|
}
|
||||||
|
@ -72,11 +72,14 @@ protected:
|
|||||||
uint8 int_mask;
|
uint8 int_mask;
|
||||||
|
|
||||||
int tod_divider; // TOD frequency divider
|
int tod_divider; // TOD frequency divider
|
||||||
|
|
||||||
bool tod_halt, // Flag: TOD halted
|
bool tod_halt, // Flag: TOD halted
|
||||||
ta_cnt_phi2, // Flag: Timer A is counting Phi 2
|
ta_cnt_phi2, // Flag: Timer A is counting Phi 2
|
||||||
tb_cnt_phi2, // Flag: Timer B is counting Phi 2
|
tb_cnt_phi2, // Flag: Timer B is counting Phi 2
|
||||||
tb_cnt_ta; // Flag: Timer B is counting underflows of Timer A
|
tb_cnt_ta; // Flag: Timer B is counting underflows of Timer A
|
||||||
|
|
||||||
|
bool tod_alarm; // Flag: TOD in alarm state
|
||||||
|
void check_tod_alarm();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -151,6 +154,24 @@ struct MOS6526State {
|
|||||||
uint8 int_mask; // Enabled interrupts
|
uint8 int_mask; // Enabled interrupts
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for TOD alarm
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline void MOS6526::check_tod_alarm()
|
||||||
|
{
|
||||||
|
bool alarm_match = (tod_10ths == alm_10ths && tod_sec == alm_sec &&
|
||||||
|
tod_min == alm_min && tod_hr == alm_hr);
|
||||||
|
|
||||||
|
// Raise interrupt on positive edge of alarm match
|
||||||
|
if (alarm_match && !tod_alarm)
|
||||||
|
{
|
||||||
|
TriggerInterrupt(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
tod_alarm = alarm_match;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Emulate CIA for one cycle/raster line
|
* Emulate CIA for one cycle/raster line
|
||||||
|
Loading…
Reference in New Issue
Block a user