From 931d5ef33c84ad3db93bd8baafe8f335b60799a2 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Wed, 18 Oct 2017 15:20:12 +0800 Subject: [PATCH] Add some decoding debug logic --- components/tme/scc.c | 84 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/components/tme/scc.c b/components/tme/scc.c index 42e6719..4ec5cbf 100644 --- a/components/tme/scc.c +++ b/components/tme/scc.c @@ -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<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); + } } }