#include #include __address(0x24) word ENDADDR; // End address of dump block __address(0x26) word STARTADDR; // Begin address of dump block __address(0x29) byte LASTSTATE; // Last input state __address(0x30) byte NUMPULSES; // Number of long pulses to sync at the header __address(0xC081) byte TAPEIN; // Tape input __address(0xD012) byte DSP; // display data port /* #pragma zp_reserve(0x24) #pragma zp_reserve(0x25) #pragma zp_reserve(0x26) #pragma zp_reserve(0x27) #pragma zp_reserve(0x29) #pragma zp_reserve(0x30) __export byte *const ENDADDR = (byte *) 0x24; // End address of dump block __export byte *const STARTADDR = (byte *) 0x26; // Begin address of dump block __export byte *const LASTSTATE = (byte *) 0x29; // Last input state __export byte *const NUMPULSES = (byte *) 0x30; // Number of long pulses to sync at the header __export byte *const TAPEIN = (byte *) 0xC081; // Tape input __export byte *const DSP = (byte *) 0xD012; // display data port */ byte PACKETSIZE; byte reference_packet[256]; byte *vmeter = "0123456789ABCDEF"; //byte *const RX_BUFFER = (byte *) 0x060c; //0x4200; const byte RX_BUFFER[256]; // TODO ?????????????????????????????????????????? void read_packet() { word RX_BUFFER_END = (word) RX_BUFFER + (word) PACKETSIZE - 1; ENDADDR = (word) RX_BUFFER_END; STARTADDR = (word) RX_BUFFER; /* *((word *)ENDADDR) = (word) RX_BUFFER_END; *((word *)STARTADDR) = (word) RX_BUFFER; */ /* woz_putc('\r'); woz_print_hex(*(STARTADDR+1)); woz_print_hex(*(STARTADDR)); woz_putc('.'); woz_print_hex(*(ENDADDR+1)); woz_print_hex(*(ENDADDR)); */ asm { // synchronizes with the short header syncstart: lda #24 // 24 cycles (3 bytes of $ff) sta NUMPULSES // count 24 cycles pulses jsr fullcycle // skip the first full cycle (when looping) nextsync: ldy #58 // full cycle duration jsr fullcycle // read a full cycle bcc syncstart // if short cycle found (c=0), redo from start dec NUMPULSES // else long cycle found, decrease count bne nextsync // if not 24 cycles, get next cycle // else read bit start and 32 bytes of data normally // the following routine was copied directly from the ACI ROM notstart: ldy #31 // try to detect the much shorter start bit jsr cmplevel // bcs notstart // start bit not detected yet! jsr cmplevel // wait for 2nd phase of start bit ldy #58 // set threshold value in middle rdbyte: ldx #8 // receiver 8 bits rdbit: pha jsr fullcycle // detect a full cycle pla rol // roll new bit into result ldy #57 // set threshold value in middle dex // decrement bit counter bne rdbit // read next bit! sta (STARTADDR,x) // save new byte jsr incaddr // increment address ldy #53 // compensate threshold with workload bcc rdbyte // do next byte if not done yet! bcs restidx // always taken! restore parse index fullcycle: jsr cmplevel // wait for two level changes cmplevel: dey // decrement time counter lda TAPEIN // get tape in data cmp LASTSTATE // same as before? beq cmplevel // yes! sta LASTSTATE // save new data cpy #128 // compare threshold rts // [...] incaddr: lda STARTADDR sbc >ENDADDR // carry set if STARTADDR = ENDADDR inc STARTADDR no_inc_hi: rts // end of read routine "restidx" is the exit point restidx: rts } } void decode_packets() { woz_puts("\rPACKET DECODER MONITOR\r"); // fill the reference packet with the known values for(byte t=0;t>1]); if(PACKETSIZE == 64) woz_putc(vmeter[i>>2]); if(PACKETSIZE == 128) woz_putc(vmeter[i>>3]); if(PACKETSIZE == 255) woz_putc(vmeter[i>>4]); } /* if(apple1_readkey()=='D') { woz_puts("\r\r"); for(i=0;i 32,64,128,255 BYTES PACKETS\r" "T SIMPLE TOGGLE MONITOR\r" "D DUTY CYLE MONITOR\r\r" "X EXIT\r\r" ); byte key = apple1_getkey(); if(key == '1') { PACKETSIZE = 32; decode_packets(); } if(key == '2') { PACKETSIZE = 64; decode_packets(); } if(key == '3') { PACKETSIZE = 128; decode_packets(); } if(key == '4') { PACKETSIZE = 255; decode_packets(); } if(key == 'T') simple_toggle_monitor(); if(key == 'D') duty_cycle_monitor(); if(key == 'X') woz_mon(); } }