commodore64: implement serial shift register in CIA chip to prepare for disk drive I/O

This commit is contained in:
saxxonpike 2012-11-15 20:49:54 +00:00
parent eb188fc8b9
commit bd3912939a
2 changed files with 74 additions and 14 deletions

View File

@ -13,10 +13,12 @@ namespace BizHawk.Emulation.Computers.Commodore64
public int ALARMMIN; // alarm minutes
public bool ALARMPM; // alarm AM/PM
public int ALARMSEC; // alarm seconds
public bool CNT; // external counter bit input
public bool EIALARM; // enable alarm interrupt (internal)
public bool EIFLAG; // enable flag pin interrupt (internal)
public bool EIFLG; // enable flag pin interrupt (internal)
public bool EISP; // enable shift register interrupt (internal)
public bool[] EIT = new bool[2]; // enable timer interrupt (internal)
public bool FLG; // external flag bit input
public bool IALARM; // alarm interrupt triggered
public bool IFLG; // interrupt triggered on FLAG pin
public int[] INMODE = new int[2]; // timer input mode
@ -28,9 +30,11 @@ namespace BizHawk.Emulation.Computers.Commodore64
public bool[] PBON = new bool[2]; // port bit modify on
public bool[] RUNMODE = new bool[2]; // running mode
public int SDR; // serial shift register
public int SDRCOUNT; // serial shift register bit count
public bool SPMODE; // shift register mode
public bool[] START = new bool[2]; // timer enabled
public int[] T = new int[2]; // timer counter
public bool[] TICK = new bool[2]; // execute timer tick
public int[] TLATCH = new int[2]; // timer latch (internal)
public int TOD10; // time of day 10ths of a second
public bool TODIN; // time of day/alarm set
@ -248,7 +252,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
public byte[] outputBitMask;
private CiaRegs regs;
public ChipSignals signal;
public bool thisCNT;
public int todCounter;
public int todFrequency;
public bool[] underflow;
@ -368,9 +371,6 @@ namespace BizHawk.Emulation.Computers.Commodore64
public void PerformCycle()
{
lastCNT = thisCNT;
thisCNT = ReadSerial();
// process time of day counter
todCounter--;
if (todCounter <= 0)
@ -407,6 +407,8 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
}
lastCNT = regs.CNT;
regs.CNT = false;
UpdateInterrupt();
}
@ -487,21 +489,23 @@ namespace BizHawk.Emulation.Computers.Commodore64
switch (regs.INMODE[index])
{
case 0:
TimerDec(index);
regs.TICK[index] = true;
break;
case 1:
if (thisCNT & !lastCNT)
TimerDec(index);
regs.TICK[index] |= (regs.CNT && !lastCNT);
break;
case 2:
if (underflow[0])
TimerDec(index);
regs.TICK[index] |= underflow[0];
break;
case 3:
if (underflow[0] || (thisCNT & !lastCNT))
TimerDec(index);
regs.TICK[index] |= (regs.CNT && !lastCNT) || underflow[0];
break;
}
if (regs.TICK[index])
{
TimerDec(index);
regs.TICK[index] = false;
}
}
public void UpdateInterrupt()
@ -509,7 +513,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
bool irq = false;
irq |= (regs.EIT[0] & regs.IT[0]);
irq |= (regs.EIT[1] & regs.IT[1]);
irq |= (regs.EIFLAG & regs.IFLG);
irq |= (regs.EIFLG & regs.IFLG);
irq |= (regs.EISP & regs.ISP);
irq |= (regs.EIALARM & regs.IALARM);
regs.IRQ = irq;
@ -581,7 +585,7 @@ namespace BizHawk.Emulation.Computers.Commodore64
regs.EIT[1] = ((intMask & 0x02) != 0x00);
regs.EIALARM = ((intMask & 0x04) != 0x00);
regs.EISP = ((intMask & 0x08) != 0x00);
regs.EIFLAG = ((intMask & 0x10) != 0x00);
regs.EIFLG = ((intMask & 0x10) != 0x00);
UpdateInterrupt();
break;
default:
@ -591,6 +595,45 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
public void WriteCNT(bool val)
{
if (!lastCNT && val)
{
if (!regs.SPMODE)
{
// read bit into shift register
bool inputBit = ReadSerial();
regs.SDR = ((regs.SDR << 1) | (inputBit ? 0x01 : 0x00)) & 0xFF;
regs.SDRCOUNT = (regs.SDRCOUNT - 1) & 0x7;
if (regs.SDRCOUNT == 0)
{
regs.ISP = true;
}
}
else
{
// write bit out from shift register
bool outputBit = ((regs.SDR & 0x01) != 0);
regs.SDR >>= 1;
WriteSerial(outputBit);
regs.SDRCOUNT = (regs.SDRCOUNT - 1) & 0x7;
if (regs.SDRCOUNT == 0)
{
regs.ISP = true;
}
}
}
regs.CNT = val;
}
public void WriteFLG(bool val)
{
regs.FLG = val;
regs.IFLG |= val;
}
private void WriteSerialDummy(bool val)
{
// do nothing

View File

@ -37,6 +37,23 @@ namespace BizHawk.Emulation.Computers.Commodore64
}
}
// 0x0: port B
// 0x1: port A
// 0x2: port B data direction
// 0x3: port A data direction
// 0x4: timer lo
// 0x5: timer hi
// 0x6: timer latch lo
// 0x7: timer latch hi
// 0x8: unused
// 0x9: unused
// 0xA: unused
// 0xB: timer control
// 0xC: auxilary control
// 0xD: interrupt status
// 0xE: interrupt control
// 0xF: unused
public class Via
{
public ViaRegs regs;