1;---------------------------------------------------------------------- 2; Serial Bus 3;---------------------------------------------------------------------- 4; (C)1983 Commodore Business Machines (CBM) 5; additions: (C)2020 Michael Steil, License: 2-clause BSD 6 7.feature labels_without_colons 8 9.include "io.inc" 10.include "mac.inc" 11 12.import status 13.import udst 14 15.export serial_secnd 16.export serial_tksa 17.export serial_acptr 18.export serial_ciout 19.export serial_untlk 20.export serial_unlsn 21.export serial_listn 22.export serial_talk 23 24.export tkatn; [channel] 25.export scatn; [channel] 26.export clklo; [machine init] 27 28sdata =HACK ; XXX fill for X16 - now points to #$80, so serial doesn't hang 29d1crb =$ffff ; XXX fill for X16 30d1icr =$ffff ; XXX fill for X16 31timrb =$19 ;6526 crb enable one-shot tb 32 33.segment "KVAR" 34 35c3p0 .res 1 ;$94 ieee buffered char flag 36bsour .res 1 ;$95 char buffer for ieee 37r2d2 .res 1 ;$A3 serial bus usage 38bsour1 .res 1 ;$A4 temp used by serial routine 39count .res 1 ;$A5 temp used by serial routine 40 41 .segment "SERIAL" 42 43HACK .byte $80 44 45;command serial bus device to talk 46; 47serial_talk 48 ora #$40 ;make a talk adr 49 bra list1 50 51;command serial bus device to listen 52; 53serial_listn 54 ora #$20 ;make a listen adr 55list1 pha 56; 57; 58 bit c3p0 ;character left in buf? 59 bpl list2 ;no... 60; 61;send buffered character 62; 63 sec ;set eoi flag 64 ror r2d2 65; 66 jsr isour ;send last character 67; 68 lsr c3p0 ;buffer clear flag 69 lsr r2d2 ;clear eoi flag 70; 71; 72list2 pla ;talk/listen address 73 sta bsour 74 sei 75 jsr datahi 76 cmp #$3f ;clkhi only on unlisten 77 bne list5 78 jsr clkhi 79; 80list5 lda sdata ;assert attention 81 ora #$08 82 sta sdata 83; 84 85isoura sei 86 jsr clklo ;set clock line low 87 jsr datahi 88 jsr w1ms ;delay 1 ms 89 90isour sei ;no irq's allowed 91 jsr datahi ;make sure data is released 92 jsr debpia ;data should be low 93 bcs nodev 94 jsr clkhi ;clock line high 95 bit r2d2 ;eoi flag test 96 bpl noeoi 97; do the eoi 98isr02 jsr debpia ;wait for data to go high 99 bcc isr02 100; 101isr03 jsr debpia ;wait for data to go low 102 bcs isr03 103; 104noeoi jsr debpia ;wait for data high 105 bcc noeoi 106 jsr clklo ;set clock low 107; 108; set to send data 109; 110 lda #$08 ;count 8 bits 111 sta count 112; 113isr01 114 lda sdata ;debounce the bus 115 cmp sdata 116 bne isr01 117 asl a ;set the flags 118 bcc frmerr ;data must be hi 119; 120 ror bsour ;next bit into carry 121 bcs isrhi 122 jsr datalo 123 bne isrclk 124isrhi jsr datahi 125isrclk jsr clkhi ;clock hi 126 nop 127 nop 128 nop 129 nop 130 lda sdata 131 and #$ff-$20 ;data high 132 ora #$10 ;clock low 133 sta sdata 134 dec count 135 bne isr01 136 lda #$04 ;set timer for 1ms 137 sta d1t2h 138 lda #timrb ;trigger timer 139 sta d1crb 140 lda d1icr ;clear the timer flags<<<<<<<<<<<<< 141isr04 lda d1icr 142 and #$02 143 bne frmerr 144 jsr debpia 145 bcs isr04 146 cli ;let irq's continue 147 rts 148; 149nodev ;device not present error 150 lda #$80 151 bra csberr 152frmerr ;framing error 153 lda #$03 154csberr jsr udst ;commodore serial buss error entry 155 cli ;irq's were off...turn on 156 clc ;make sure no kernal error returned 157 bcc dlabye ;turn atn off ,release all lines 158; 159 160;send secondary address after listen 161; 162serial_secnd 163 sta bsour ;buffer character 164 jsr isoura ;send it 165 166;release attention after listen 167; 168scatn lda sdata 169 and #$ff-$08 170 sta sdata ;release attention 171 rts 172 173;talk second address 174; 175serial_tksa 176 sta bsour ;buffer character 177 jsr isoura ;send second addr 178 179tkatn ;shift over to listener 180 sei ;no irq's here 181 jsr datalo ;data line low 182 jsr scatn 183 jsr clkhi ;clock line high jsr/rts 184tkatn1 jsr debpia ;wait for clock to go low 185 bmi tkatn1 186 cli ;irq's okay now 187 rts 188 189;buffered output to serial bus 190; 191serial_ciout 192 bit c3p0 ;buffered char? 193 bmi ci2 ;yes...send last 194; 195 sec ;no... 196 ror c3p0 ;set buffered char flag 197 bne ci4 ;branch always 198; 199ci2 pha ;save current char 200 jsr isour ;send last char 201 pla ;restore current char 202ci4 sta bsour ;buffer current char 203 clc ;carry-good exit 204 rts 205 206;send untalk command on serial bus 207; 208serial_untlk 209 sei 210 jsr clklo 211 lda sdata ;pull atn 212 ora #$08 213 sta sdata 214 lda #$5f ;untalk command 215 bra :+ 216 217;send unlisten command on serial bus 218; 219serial_unlsn 220 lda #$3f ;unlisten command 221: jsr list1 ;send it 222; 223; release all lines 224dlabye jsr scatn ;always release atn 225; delay then release clock and data 226; 227dladlh txa ;delay approx 60 us 228 ldx #10 229dlad00 dex 230 bne dlad00 231 tax 232 jsr clkhi 233 jmp datahi 234 235;input a byte from serial bus 236; 237serial_acptr 238 sei ;no irq allowed 239 lda #$00 ;set eoi/error flag 240 sta count 241 jsr clkhi ;make sure clock line is released 242acp00a jsr debpia ;wait for clock high 243 bpl acp00a 244; 245eoiacp 246 lda #$01 ;set timer 2 for 256us 247 sta d1t2h 248 lda #timrb 249 sta d1crb 250 jsr datahi ;data line high (makes timming more like vic-20 251 lda d1icr ;clear the timer flags<<<<<<<<<<<< 252acp00 lda d1icr 253 and #$02 ;check the timer 254 bne acp00b ;ran out..... 255 jsr debpia ;check the clock line 256 bmi acp00 ;no not yet 257 bpl acp01 ;yes..... 258; 259acp00b lda count ;check for error (twice thru timeouts) 260 beq acp00c 261 lda #2 262 jmp csberr ; st = 2 read timeout 263; 264; timer ran out do an eoi thing 265; 266acp00c jsr datalo ;data line low 267 jsr clkhi ; delay and then set datahi (fix for 40us c64) 268 lda #$40 269 jsr udst ;or an eoi bit into status 270 inc count ;go around again for error check on eoi 271 bne eoiacp 272; 273; do the byte transfer 274; 275acp01 lda #08 ;set up counter 276 sta count 277; 278acp03 lda sdata ;wait for clock high 279 cmp sdata ;debounce 280 bne acp03 281 asl a ;shift data into carry 282 bpl acp03 ;clock still low... 283 ror bsour1 ;rotate data in 284; 285acp03a lda sdata ;wait for clock low 286 cmp sdata ;debounce 287 bne acp03a 288 asl a 289 bmi acp03a 290 dec count 291 bne acp03 ;more bits..... 292;...exit... 293 jsr datalo ;data low 294 bit status ;check for eoi 295 bvc acp04 ;none... 296; 297 jsr dladlh ;delay then set data high 298; 299acp04 lda bsour1 300 cli ;irq is ok 301 clc ;good exit 302 rts 303; 304clkhi ;set clock line high (inverted) 305 lda sdata 306 and #$ff-$10 307 sta sdata 308 rts 309; 310clklo ;set clock line low (inverted) 311 lda sdata 312 ora #$10 313 sta sdata 314 rts 315; 316; 317datahi ;set data line high (inverted) 318 lda sdata 319 and #$ff-$20 320 sta sdata 321 rts 322; 323datalo ;set data line low (inverted) 324 lda sdata 325 ora #$20 326 sta sdata 327 rts 328; 329debpia lda sdata ;debounce the pia 330 cmp sdata 331 bne debpia 332 asl a ;shift the data bit into the carry... 333 rts ;...and the clock into neg flag 334; 335w1ms ;delay 1ms using loop 336 txa ;save .x 337 ldx #200-16 ;1000us-(1000/500*8=#40us holds) 338w1ms1 dex ;5us loop 339 bne w1ms1 340 tax ;restore .x 341 rts 342 343;******************************* 344;written 8/11/80 bob fairbairn 345;test serial0.6 8/12/80 rjf 346;change i/o structure 8/21/80 rjf 347;more i/o changes 8/24/80 rjf 348;final release into kernal 8/26/80 rjf 349;some clean up 9/8/80 rsr 350;add irq protect on isour and tkatn 9/22/80 rsr 351;fix untalk 10/7/80 rsr 352;modify for vic-40 i/o system 12/08/81 rsr 353;add sei to (untlk,isoura,list2) 12/14/81 rsr 354;modify for 6526 flags fix errs 12/31/81 rsr 355;modify for commodore 64 i/o 3/11/82 rsr 356;change acptr eoi for better response 3/28/82 rsr 357;change wait 1 ms routine for less code 4/8/82 rsr 358;****************************** 359 360