0001 * 0002 * Communications program for the Radio Shack Color Computer 1,2 0003 * Receives up to 48K of data at 9600 baud 0004 * Times out after about 4 minutes with no incoming data, 0005 * and after a 10 second gap after recieving any 0006 * Entry point sstart: converts s19 records to binary data in-place 0007 * (ie: only contiguous programs should be sent!) 0008 * Entry point tstart: just recieve text, leave it in the buffer 0009 * See "interesting results" for return values other than buffer 0010 * 0011 * 13-Sep-1986 101am WJY 0012 * 31-Jan-1996 1248nn WJY 0013 * 4-Feb-1996 525pm WJY 0014 * 8-Feb-1996 255am WJY 0015 * 19-Feb-1996 1050am WJY - 17 cycle max delay testing start bit 0016 * 20-Feb-1998 8pm WJY - added ACTIND name for 05FF 0017 * 21-Feb-1998 2am WJY - corrected bug with .b getting munged in s_bit 0018 * 0019 0020 4000 BUFBEG equ $4000 buffer beginning address 0021 ff00 BUFEND equ $FF00 ending 0022 05ff ACTIND equ $05FF activity indicator on screen 0023 ff22 S_IN_A equ $FF22 serial input address 0024 0001 S_IN_B equ $01 serial input mask byte 0025 00ff W1 equ $FF start-bit delays - gazillionths 0026 00fa W2 equ $FA - jillionths 0027 00f0 W3 equ $F0 - seconds (roughly) 0028 0029 * SAM addresses 0030 ffc0 SAMVDG equ $FFC0 video display mode 0031 ffc6 SAMDIS equ $FFC6 display address offset 0032 ffd4 SAMPAG equ $FFD4 page #1 0033 ffd6 SAMRAT equ $FFD6 cpu rate 0034 ffda SAMSIZ equ $FFDA memory size 0035 ffde SAMTYP equ $FFDE memory map type 0036 0037 3000 org $3000 0038 0039 3000 20 05 begin bra sstart 0040 3002 98 02 21 02 00 fcb $98,$02,$21,$02,$00 revision data & time 0041 3007 86 01 sstart lda #1 start s19 recieve 0042 3009 b7 34 10 sta do_s19 0043 300c 20 03 bra rstart 0044 300e 7f 34 10 tstart clr do_s19 start text recieve 0045 0046 3011 10 bf 34 0a rstart sty y_tmp save .y and .u 0047 3015 ff 34 0c stu u_tmp 0048 3018 1a 50 orcc #$50 ignore interrupts 0049 301a b7 ff df sta SAMTYP+1 use 64K of RAM 0050 0051 301d ce ff 22 ldu #S_IN_A 0052 3020 10 8e 40 00 ldy #BUFBEG 0053 0054 3024 c6 01 ldb #S_IN_B 0055 3026 86 f0 lda #W3 0056 3028 b7 34 0f sta wait3 0057 302b e5 c4 st2 bitb ,u test for start bit 4 \_ 7 0058 302d 27 2a beq strtbt 3 / 0059 302f 86 fa lda #W2 0060 3031 b7 34 0e sta wait2 0061 3034 86 ff st1 lda #W1 0062 0063 3036 e5 c4 s_str1 bitb ,u test again 4 \_ 7 0064 3038 27 1f beq strtbt 3 / 0065 303a 4a deca W1 loops 2 0066 303b 26 f9 bne s_str1 3 0067 303d e5 c4 bitb ,u test again 4 \_ 7 0068 303f 27 18 beq strtbt 3 / 0069 3041 7a 34 0e dec wait2 times W2 7 0070 3044 26 ee bne st1 3 0071 3046 e5 c4 bitb ,u test again 4 \_ 7 0072 3048 27 0f beq strtbt 3 / 0073 304a 7c 05 ff inc ACTIND activity indicator 7 0074 304d e5 c4 bitb ,u test again 4 \_ 7 0075 304f 27 08 beq strtbt 3 / 0076 3051 7a 34 0f dec wait3 7 0077 3054 26 d5 bne st2 times W3 3 0078 3056 16 00 58 lbra rdone no data, timed out, return 0079 0080 * Need exactly 93 clock cycles between bits 0081 * 3 cycles were already used by the branch to get here, 0082 * and 7 more will be spent in the bit-check loop before checking 0083 3059 cc 80 0d strtbt ldd #$800D preset bit & delay count 3 \ 0084 305c b7 34 09 sta byte 5 | 0085 305f 5a s_str2 decb wait out start bit 2 \__ 65 | 0086 3060 26 fd bne s_str2 3 / |- 83 0087 3062 7c 05 ff inc ACTIND activity indicator 7 | 0088 3065 21 00 brn s_bit waste three clock cycles 3 / 0089 0090 3067 8e 00 00 s_bit ldx #0 check serial port for ones 3 0091 0092 306a e6 c4 ldb ,u check once 4 \ 0093 306c c4 01 andb #S_IN_B 2 | 0094 306e 3a abx 3 | 0095 * | 0096 306f e6 c4 ldb ,u check twice | 0097 3071 c4 01 andb #S_IN_B | 0098 3073 3a abx | 0099 * | 0100 3074 e6 c4 ldb ,u check thrice |- 72 0101 3076 c4 01 andb #S_IN_B | 0102 3078 3a abx | 0103 * | 0104 3079 e6 c4 ldb ,u check 4 times | 0105 307b c4 01 andb #S_IN_B | 0106 307d 3a abx | 0107 * | 0108 307e e6 c4 ldb ,u check 5 times | 0109 3080 c4 01 andb #S_IN_B | 0110 3082 3a abx | 0111 * | 0112 3083 e6 c4 ldb ,u check 6 times | 0113 3085 c4 01 andb #S_IN_B | 0114 3087 3a abx | 0115 * | 0116 3088 e6 c4 ldb ,u check 7 times | 0117 308a c4 01 andb #S_IN_B | 0118 308c 3a abx | 0119 * | 0120 308d e6 c4 ldb ,u check 8 times | 0121 308f c4 01 andb #S_IN_B | 0122 3091 3a abx / 0123 0124 3092 12 nop 2 \ 0125 3093 12 nop 2 | 0126 3094 8c 00 05 cmpx #5 did we get a one-bit? 4 |- 18 0127 3097 76 34 09 ror byte shift in negated bit 7 | 0128 309a 24 cb bcc s_bit until the preset bit pops out 3 / 0129 0130 * There must be at least one stop bit, so we have at least 0131 * 93 cycles to putter around here. (It is okay to finish sooner) 0132 309c b6 34 09 lda byte 5 \ 0133 309f 43 coma get the non-inverted bits 2 | 0134 30a0 a7 a0 sta ,y+ save 'em 6 | 0135 30a2 86 0a lda #10 2 |- 33 0136 30a4 b7 34 0f sta wait3 timeout is now 10 seconds 5 | 0137 30a7 c6 01 ldb #S_IN_B restore .b, which got messed up 2 | 0138 30a9 10 8c ff 00 cmpy #BUFEND 5 | 0139 30ad 10 26 ff 7a lbne st2 if buffer isn't full, go get more 6 / 0140 0141 30b1 10 bf 34 00 rdone sty rlast note how much we got 0142 30b5 7d 34 10 tst do_s19 0143 30b8 10 27 00 dd lbeq done 0144 0145 0146 * check all s19 records for valid checksums 0147 30bc 8e 40 00 s19bin ldx #BUFBEG 0148 30bf 7f 34 08 clr errct no errors yet 0149 0150 30c2 bc 34 00 ssum cmpx rlast check a record 0151 30c5 24 3e bhs s19 past end of buffer? 0152 30c7 ec 81 ldd ,x++ S1 or S9 0153 30c9 ec 81 ldd ,x++ length 0154 30cb 17 00 d8 lbsr hex2 0155 30ce f7 34 11 stb length 0156 30d1 f7 34 12 stb sum initialize sum 0157 30d4 27 20 beq ssum9 empty record! 0158 0159 30d6 7a 34 11 ssum2 dec length 0160 30d9 27 0d beq ssum3 0161 30db ec 81 ldd ,x++ address or data 0162 30dd 17 00 c6 lbsr hex2 0163 30e0 fb 34 12 addb sum 0164 30e3 f7 34 12 stb sum 0165 30e6 20 ee bra ssum2 0166 0167 30e8 ec 81 ssum3 ldd ,x++ checksum 0168 30ea 17 00 b9 lbsr hex2 0169 30ed 53 comb one's complement 0170 30ee f1 34 12 cmpb sum 0171 30f1 27 03 beq ssum9 if okay, skip EOL 0172 0173 30f3 7c 34 08 sumerr inc errct 0174 0175 30f6 bc 34 00 ssum9 cmpx rlast past end of buffer? 0176 30f9 24 0a bhs s19 decode data 0177 30fb a6 80 lda ,x+ 0178 30fd 81 20 cmpa #$20 0179 30ff 25 f5 blo ssum9 skip control characters 0180 3101 30 1f leax -1,x ungetc printable character 0181 3103 20 bd bra ssum 0182 0183 * convert S19 records to binary data 0184 3105 8e 40 00 s19 ldx #BUFBEG first character 0185 3108 bf 34 02 stx slast nothing decoded yet 0186 310b ec 04 ldd 4,x address MSB 0187 310d 17 00 96 lbsr hex2 0188 3110 f7 34 04 stb addr 0189 3113 ec 06 ldd 6,x 0190 3115 17 00 8e lbsr hex2 0191 3118 f7 34 05 stb addr+1 0192 311b ec 84 s19a ldd ,x 0193 311d 10 83 53 39 cmpd #$5339 S9? 0194 3121 27 38 beq s9 0195 3123 10 83 53 31 cmpd #$5331 S1? 0196 3127 26 51 bne s19err 0197 0198 3129 ec 02 s1 ldd 2,x length 0199 312b 8d 79 bsr hex2 0200 312d c0 03 subb #3 don't count addr or cksum 0201 312f f7 34 11 stb length 0202 3132 ec 04 ldd 4,x addr MSB 0203 3134 8d 70 bsr hex2 0204 3136 34 04 pshs b 0205 3138 ec 06 ldd 6,x addr LSB 0206 313a 8d 6a bsr hex2 0207 313c 35 02 puls a address is in .d 0208 313e b3 34 04 subd addr 0209 3141 c3 40 00 addd #BUFBEG cvt to buffer address 0210 3144 1f 02 tfr d,y 0211 3146 30 08 leax 8,x point .x to data 0212 3148 ec 81 s1b ldd ,x++ 0213 314a 8d 5a bsr hex2 0214 314c e7 a0 stb ,y+ 0215 314e 7a 34 11 dec length 0216 3151 26 f5 bne s1b 0217 3153 10 bf 34 02 sty slast remember last byte decoded 0218 3157 30 02 leax 2,x skip over checksum 0219 3159 20 2f bra s19end 0220 0221 315b ec 02 s9 ldd 2,x length 0222 315d 8d 47 bsr hex2 0223 315f f7 34 11 stb length 0224 3162 ec 04 ldd 4,x transfer address MSB 0225 3164 8d 40 bsr hex2 0226 3166 f7 34 06 stb xfer 0227 3169 ec 06 ldd 6,x transfer address LSB 0228 316b 8d 39 bsr hex2 0229 316d f7 34 07 stb xfer+1 0230 3170 f6 34 11 ldb length 0231 3173 cb 02 addb #2 count type & length too 0232 3175 58 lslb two bytes each 0233 3176 30 85 leax b,x skip to end of record 0234 3178 20 10 bra s19end 0235 0236 * error 0237 317a 7c 34 08 s19err inc errct unrecognized record type 0238 317d bc 34 00 s19er2 cmpx rlast skip to EOL 0239 3180 24 17 bhs done 0240 3182 a6 80 lda ,x+ 0241 3184 81 20 cmpa #$20 0242 3186 24 f5 bhs s19er2 0243 3188 30 1f leax -1,x ungetc EOL character 0244 * bra s19end end of record 0245 0246 318a bc 34 00 s19end cmpx rlast past end of buffer? 0247 318d 24 0a bhs done decode data 0248 318f a6 80 lda ,x+ 0249 3191 81 20 cmpa #$20 0250 3193 25 f5 blo s19end skip control characters 0251 3195 30 1f leax -1,x ungetc printable character 0252 3197 20 82 bra s19a 0253 0254 * finished with everything, return to BASIC 0255 3199 10 be 34 0a done ldy y_tmp restore registers .y and .u 0256 319d fe 34 0c ldu u_tmp 0257 31a0 b7 ff de sta SAMTYP use ROMs again 0258 31a3 1c af andcc #$AF re-enable interrupts 0259 31a5 39 rts 0260 0261 * convert 2 ASCII characters in .d to binary number in .b 0262 31a6 8d 0d hex2 bsr hex1 LSNybble 0263 31a8 34 04 pshs b 0264 31aa 1f 89 tfr a,b 0265 31ac 8d 07 bsr hex1 MSNybble 0266 31ae 58 lslb 0267 31af 58 lslb 0268 31b0 58 lslb 0269 31b1 58 lslb 0270 31b2 ea e0 orb ,s+ 0271 31b4 39 rts 0272 31b5 c1 39 hex1 cmpb #$39 0273 31b7 23 02 bls hex1a 0274 31b9 c0 07 subb #7 0275 31bb c4 0f hex1a andb #$0F 0276 31bd 39 rts 0277 0278 0279 3400 org $3400 0280 0281 * interesting results 0282 3400 rlast rmb 2 one past last buffer address received 0283 3402 slast rmb 2 one past last buffer address decoded 0284 3404 addr rmb 2 address from first s19 record 0285 3406 xfer rmb 2 transfer address from last s9 record 0286 3408 errct rmb 1 number of s19 errors found 0287 0288 * internal temporary storage 0289 3409 byte rmb 1 the byte being recieved 0290 340a y_tmp rmb 2 hold .y and .u while running 0291 340c u_tmp rmb 2 0292 340e wait2 rmb 1 delay counters 0293 340f wait3 rmb 1 0294 0295 3410 do_s19 rmb 1 convert s19 records? 0=no 0296 3411 length rmb 1 length of an s19 record 0297 3412 sum rmb 2 checksum of an s19 record 0298 0299 end begin Number of errors 0