* * Communications program for the Radio Shack Color Computer 1,2 * Receives up to 48K of data at 9600 baud * Times out after about 4 minutes with no incoming data, * and after a 10 second gap after recieving any * Entry point sstart: converts s19 records to binary data in-place * (ie: only contiguous programs should be sent!) * Entry point tstart: just recieve text, leave it in the buffer * See "interesting results" for return values other than buffer * * 13-Sep-1986 101am WJY * 31-Jan-1996 1248nn WJY * 4-Feb-1996 525pm WJY * 8-Feb-1996 255am WJY * 19-Feb-1996 1050am WJY - 17 cycle max delay testing start bit * 20-Feb-1998 8pm WJY - added ACTIND name for 05FF * 21-Feb-1998 2am WJY - corrected bug with .b getting munged in s_bit * BUFBEG equ $4000 buffer beginning address BUFEND equ $FF00 ending ACTIND equ $05FF activity indicator on screen S_IN_A equ $FF22 serial input address S_IN_B equ $01 serial input mask byte W1 equ $FF start-bit delays - gazillionths W2 equ $FA - jillionths W3 equ $F0 - seconds (roughly) * SAM addresses SAMVDG equ $FFC0 video display mode SAMDIS equ $FFC6 display address offset SAMPAG equ $FFD4 page #1 SAMRAT equ $FFD6 cpu rate SAMSIZ equ $FFDA memory size SAMTYP equ $FFDE memory map type org $3000 begin bra sstart fcb $98,$02,$21,$02,$00 revision data & time sstart lda #1 start s19 recieve sta do_s19 bra rstart tstart clr do_s19 start text recieve rstart sty y_tmp save .y and .u stu u_tmp orcc #$50 ignore interrupts sta SAMTYP+1 use 64K of RAM ldu #S_IN_A ldy #BUFBEG ldb #S_IN_B lda #W3 sta wait3 st2 bitb ,u test for start bit 4 \_ 7 beq strtbt 3 / lda #W2 sta wait2 st1 lda #W1 s_str1 bitb ,u test again 4 \_ 7 beq strtbt 3 / deca W1 loops 2 bne s_str1 3 bitb ,u test again 4 \_ 7 beq strtbt 3 / dec wait2 times W2 7 bne st1 3 bitb ,u test again 4 \_ 7 beq strtbt 3 / inc ACTIND activity indicator 7 bitb ,u test again 4 \_ 7 beq strtbt 3 / dec wait3 7 bne st2 times W3 3 lbra rdone no data, timed out, return * Need exactly 93 clock cycles between bits * 3 cycles were already used by the branch to get here, * and 7 more will be spent in the bit-check loop before checking strtbt ldd #$800D preset bit & delay count 3 \ sta byte 5 | s_str2 decb wait out start bit 2 \__ 65 | bne s_str2 3 / |- 83 inc ACTIND activity indicator 7 | brn s_bit waste three clock cycles 3 / s_bit ldx #0 check serial port for ones 3 ldb ,u check once 4 \ andb #S_IN_B 2 | abx 3 | * | ldb ,u check twice | andb #S_IN_B | abx | * | ldb ,u check thrice |- 72 andb #S_IN_B | abx | * | ldb ,u check 4 times | andb #S_IN_B | abx | * | ldb ,u check 5 times | andb #S_IN_B | abx | * | ldb ,u check 6 times | andb #S_IN_B | abx | * | ldb ,u check 7 times | andb #S_IN_B | abx | * | ldb ,u check 8 times | andb #S_IN_B | abx / nop 2 \ nop 2 | cmpx #5 did we get a one-bit? 4 |- 18 ror byte shift in negated bit 7 | bcc s_bit until the preset bit pops out 3 / * There must be at least one stop bit, so we have at least * 93 cycles to putter around here. (It is okay to finish sooner) lda byte 5 \ coma get the non-inverted bits 2 | sta ,y+ save 'em 6 | lda #10 2 |- 33 sta wait3 timeout is now 10 seconds 5 | ldb #S_IN_B restore .b, which got messed up 2 | cmpy #BUFEND 5 | lbne st2 if buffer isn't full, go get more 6 / rdone sty rlast note how much we got tst do_s19 lbeq done * check all s19 records for valid checksums s19bin ldx #BUFBEG clr errct no errors yet ssum cmpx rlast check a record bhs s19 past end of buffer? ldd ,x++ S1 or S9 ldd ,x++ length lbsr hex2 stb length stb sum initialize sum beq ssum9 empty record! ssum2 dec length beq ssum3 ldd ,x++ address or data lbsr hex2 addb sum stb sum bra ssum2 ssum3 ldd ,x++ checksum lbsr hex2 comb one's complement cmpb sum beq ssum9 if okay, skip EOL sumerr inc errct ssum9 cmpx rlast past end of buffer? bhs s19 decode data lda ,x+ cmpa #$20 blo ssum9 skip control characters leax -1,x ungetc printable character bra ssum * convert S19 records to binary data s19 ldx #BUFBEG first character stx slast nothing decoded yet ldd 4,x address MSB lbsr hex2 stb addr ldd 6,x lbsr hex2 stb addr+1 s19a ldd ,x cmpd #$5339 S9? beq s9 cmpd #$5331 S1? bne s19err s1 ldd 2,x length bsr hex2 subb #3 don't count addr or cksum stb length ldd 4,x addr MSB bsr hex2 pshs b ldd 6,x addr LSB bsr hex2 puls a address is in .d subd addr addd #BUFBEG cvt to buffer address tfr d,y leax 8,x point .x to data s1b ldd ,x++ bsr hex2 stb ,y+ dec length bne s1b sty slast remember last byte decoded leax 2,x skip over checksum bra s19end s9 ldd 2,x length bsr hex2 stb length ldd 4,x transfer address MSB bsr hex2 stb xfer ldd 6,x transfer address LSB bsr hex2 stb xfer+1 ldb length addb #2 count type & length too lslb two bytes each leax b,x skip to end of record bra s19end * error s19err inc errct unrecognized record type s19er2 cmpx rlast skip to EOL bhs done lda ,x+ cmpa #$20 bhs s19er2 leax -1,x ungetc EOL character * bra s19end end of record s19end cmpx rlast past end of buffer? bhs done decode data lda ,x+ cmpa #$20 blo s19end skip control characters leax -1,x ungetc printable character bra s19a * finished with everything, return to BASIC done ldy y_tmp restore registers .y and .u ldu u_tmp sta SAMTYP use ROMs again andcc #$AF re-enable interrupts rts * convert 2 ASCII characters in .d to binary number in .b hex2 bsr hex1 LSNybble pshs b tfr a,b bsr hex1 MSNybble lslb lslb lslb lslb orb ,s+ rts hex1 cmpb #$39 bls hex1a subb #7 hex1a andb #$0F rts org $3400 * interesting results rlast rmb 2 one past last buffer address received slast rmb 2 one past last buffer address decoded addr rmb 2 address from first s19 record xfer rmb 2 transfer address from last s9 record errct rmb 1 number of s19 errors found * internal temporary storage byte rmb 1 the byte being recieved y_tmp rmb 2 hold .y and .u while running u_tmp rmb 2 wait2 rmb 1 delay counters wait3 rmb 1 do_s19 rmb 1 convert s19 records? 0=no length rmb 1 length of an s19 record sum rmb 2 checksum of an s19 record end begin