Add some decoding debug logic

This commit is contained in:
Jeroen Domburg 2017-10-18 15:20:12 +08:00
parent b54c0072fd
commit 931d5ef33c
1 changed files with 80 additions and 4 deletions

View File

@ -18,7 +18,7 @@ void sccIrq(int ena);
#define NO_RXBUF 4
typedef struct {
int delay; //-1 if buffer is free,
int delay; //-1 if buffer is free
int len;
uint8_t data[BUFLEN];
} RxBuf;
@ -36,6 +36,8 @@ typedef struct {
int rxPos;
int rxBufCur;
int rxDelay;
int eofDelay;
int eofIntPending;
} SccChan;
typedef struct {
@ -49,6 +51,16 @@ typedef struct {
static Scc scc;
/*
For SCC, Special conditions are:
- Receive overrun
- Framing Error (async)
- End of Frame
- Optional: Parity error
For the emu (where we atm only do sldc for appletalk) only End Of Frame is important.
*/
static void triggerRx(int chan);
@ -111,11 +123,59 @@ static int rxBufTick(int chan) {
#define SCC_RR3_CHA_TX (1<<4)
#define SCC_RR3_CHA_RX (1<<5)
static void explainWrite(int reg, int chan, int val) {
const static char *cmdLo[]={"null", "point_high", "reset_ext_status_int", "send_ABORT",
"ena_int_on_next_char", "reset_tx_pending", "error_reset", "reset_highest_ius"};
const static char *cmdHi[]={"null", "reset_rx_crc", "reset_tx_crc", "reset_tx_underrun_EOM_latch"};
const static char *intEna[]={"RxIntDisabled", "RxInt1stCharOrSpecial", "RxIntAllCharOrSpecial", "RxIntSpecial"};
const static char *rstDesc[]={"NoReset", "ResetChB", "ResetChA", "HwReset"};
if (reg==0 && ((val&0xF8)!=0)) {
if (((val&0xF8)!=0) && ((val&0xF8)!=0x08)) {
printf("Write reg 0; CmdHi=%s CmdLo=%s\n", cmdHi[(val>>6)&3], cmdLo[(val>>3)&7]);
}
} else if (reg==1) {
printf("Write reg 1 for chan %d: ", chan);
if (val&0x80) printf("WaitDmaReqEn ");
if (val&0x40) printf("WaitDmaReqFn ");
if (val&0x20) printf("WaitDmaOnRxTx ");
if (val&0x04) printf("ParityIsSpecial ");
if (val&0x02) printf("TxIntEna ");
if (val&0x01) printf("RxIntEna ");
printf("%s\n", intEna[(val>>3)&3]);
} else if (reg==9) {
printf("Write reg 9: cmd=%s ", rstDesc[(val>>6)&3]);
if (val&0x01) printf("VIS ");
if (val&0x02) printf("NV ");
if (val&0x04) printf("DLC ");
if (val&0x08) printf("MIE ");
if (val&0x10) printf("StatusHi ");
if (val&0x20) printf("RESVD ");
printf("\n");
} else if (reg==15) {
printf("Write reg 15: ");
if (val&0x02) printf("ZeroCountIE ");
if (val&0x08) printf("DcdIE ");
if (val&0x10) printf("SyncHuntIE ");
if (val&0x20) printf("CtsIE ");
if (val&0x40) printf("TxUnderrunIE ");
if (val&0x80) printf("BreakAbortIE ");
printf("\n");
} else {
printf("Write chan %d reg %d val 0x%02X\n", chan, reg, val);
}
}
//Raises an interrupt if needed, specifically when intpending indicates so. Need to
//change intpending beforehand.
static void raiseInt(int chan) {
const char *desc[]={"CHB_EXT", "CHB_TX", "CHB_RX", "CHA_EXT", "CHA_TX", "CHA_RX"};
if ((scc.chan[chan].wr1&1) ){ //&& (scc.intpending&(~scc.intpendingOld))) {
scc.intpendingOld=scc.intpending;
printf("SCC int, pending %x\n", scc.intpending);
printf("SCC int, pending %x: ", scc.intpending);
for (int i=0; i<6; i++) {
if (scc.intpending&(1<<i)) printf("%s ", desc[i]);
}
printf("\n");
sccIrq(1);
}
}
@ -195,6 +255,7 @@ static void triggerRx(int chan) {
raiseInt(chan);
}
scc.chan[chan].hunting=0;
scc.chan[chan].eofDelay=scc.chan[chan].rx[bufid].len*3;
} else {
printf("...Not for us, ignoring.\n");
rxBufIgnoreRest(chan);
@ -212,7 +273,7 @@ void sccWrite(unsigned int addr, unsigned int val) {
reg=scc.regptr;
scc.regptr=0;
}
explainWrite(reg, chan, val);
if (reg==0) {
scc.regptr=val&0x7;
if ((val&0x38)==0x8) scc.regptr|=8;
@ -251,7 +312,7 @@ void sccWrite(unsigned int addr, unsigned int val) {
scc.chan[chan].wr15=val;
raiseInt(chan);
}
printf("SCC: write to addr %x chan %d reg %d val %x\n", addr, chan, reg, val);
// printf("SCC: write to addr %x chan %d reg %d val %x\n", addr, chan, reg, val);
}
@ -267,6 +328,8 @@ unsigned int sccRead(unsigned int addr) {
scc.regptr=0;
}
if (reg==0) {
//Actually, the bits in this register that have an associated external/status int will be
//latched when that int is triggered. Yah...
if (rxHasByte(chan)) val|=(1<<0);
//Bit 1 is zero count - never set
val=(1<<2); //tx buffer always empty
@ -354,6 +417,19 @@ void sccTick() {
if (rxBufTick(n)) {
triggerRx(n);
}
if (scc.chan[n].eofDelay>0) {
scc.chan[n].eofDelay--;
if (scc.chan[n].eofDelay==0 && (scc.chan[n].wr1&0x10)!=0) {
//Int mode is recv char or special / special only
printf("Raise EOF int for channel %d\n", n);
scc.chan[n].eofIntPending=1;
scc.intpending|=((n==0)?SCC_RR3_CHA_RX:SCC_RR3_CHB_RX);
raiseInt(n);
}
//Break/Abort
scc.intpending|=(n?SCC_RR3_CHA_EXT:SCC_RR3_CHB_EXT);
raiseInt(n);
}
}
}