09       .OPT NO LIST
10 ; Cassette 60317-60438
20 ; In old source, SIO is SIOINT
30 ; and SIOMAIN is SIO. Labels
40 ; here are per Mapping The Atari
50 ; Also SENDEN is DOSENDE
60 ;  " ISRODEN is XSEROUT
70 ;  " ISRSIR  is XSERIN
80 ;  " ISRTD is XSEROC
90       .PAGE "SIO"
0100      LIST  
0110     .LOCAL 
059740 SIO LDA #$3C  Turn off tape
059742   STA PACTL   motor
059745   LDA #$3C    Raise not Cmd
059747   STA PBCTL   line
059750   LDA #3      Setup Pokey:
059752   STA SSKCTL  Enable Kbd scan,
059755   STA SOUNDR  debounce and i/o
059757   STA SKCTL   noise off
059760   RTS 
059761 SIOMAIN TSX   SIO main routine
059762   STX STACKP
059765   LDA #1      Flag time
059767   STA CRITIC  critical i/o
059769   LDA DDEVIC
059772   CMP #$60    Cassette?
059774   BNE ?NOTCST No
059776   JMP ?CASENT Yes, go
059777 ;
059779 ?NOTCST LDA #0 Flag not
059781   STA CASFLG  tape
059784   LDA #1      Set device
059786   STA DRETRY  retries
059787 ;
059789 ?COMMND LDA #13 Send cmd frm
059791   STA CRETRY  set retries
059792 ;
059793 ;  Send command frame
059794 ?COMFRM LDA #$28 Set 19.2kbaud
059796   STA AUDF3
059799   LDA #0
059801   STA AUDF4
059804   CLC 
059805   LDA DDEVIC  Setup cmd
059808   ADC DUNIT   frame
059811   ADC #$FF    less 1
059813   STA CDEVIC  as bus i.d.
059816   LDA DCOMND
059819   STA CCOMND  bus command
059822   LDA DAUX1
059825   STA CAUX1   and aux bytes
059828   LDA DAUX2
059831   STA CAUX2
059834   CLC         Point to
059835   LDA # <CDEVIC command
059837   STA BUFRLO  frame buffer
059839   ADC #4
059841   STA BFENLO
059843   LDA # >CDEVIC
059845   STA BUFRHI
059847   STA BFENHI
059849   LDA #$34    Lower not
059851   STA PBCTL   command line
059854   JSR ?SENDIN Send cmd frame
059857   LDA ERRFLG  Check bus err
059860   BNE ?BADCOM Go if any
059862   TYA         Go if Ack
059863   BNE ?ACKREC received
059864 ;
059865 ?BADCOM DEC CRETRY Got err
059868   BPL ?COMFRM Go if any left
059870   JMP ?DERR1  To return code
059871 ;
059873 ?ACKREC LDA DSTATS If Ack
059876   BPL ?WATCOM go wait for
059877 ; complete if no data to send
059878   LDA #13     Send data frame
059880   STA CRETRY  Set retries
059883   JSR ?LDPNTR set buffr ptrs
059886   JSR ?SENDIN send data
059889   BEQ ?DERR1  Go if bad
059890 ; Wait for completion
059891 ?WATCOM JSR ?STTMOT Put time
059894   LDA #0      out in x,y
059896   STA ERRFLG  Clear errflg
059899   JSR ?WAITER Set timer/wait
059902   BEQ ?DERR   Go if timeout
059903 ;
059904   BIT DSTATS
059907   BVS ?MODATA Go if more data
059908 ;
059909   LDA ERRFLG
059912   BNE ?DERR1  Branch if error
059913 ;
059914   BEQ ?RETURN Else exit
059915 ;  Receive a data frame
059916 ?MODATA JSR ?LDPNTR set ptrs
059919   JSR ?RECEIV
059920 ;
059922 ?DERR LDA ERRFLG Go if no
059925   BEQ ?NOTERR error preceeded
059926 ;    data
059927   LDA TSTAT   Get temp status
059930   STA STATUS  store in real
059931 ;
059932 ?NOTERR LDA STATUS
059934   CMP #1
059936   BEQ ?RETURN Go if success
059937 ;
059938 ?DERR1 DEC DRETRY Go if out of
059941   BMI ?RETURN device retries
059943   JMP ?COMMND else redo cmd
059944 ;
059945 ; Complete sio op
059946 ?RETURN JSR ?SENDDS Kill Pokey
059949   LDA #0      ints & reenable
059951   STA CRITIC  stage 2 vblank
059953   LDY STATUS  Return status in
059955   STY DSTATS  y and dcb and
059958   RTS         leave flag valid
059959 ?WAIT LDA #0  Wait for ACK
059961   STA ERRFLG  or completion
059964   CLC 
059965   LDA # <TEMP Setup temporary
059967   STA BUFRLO  one byte buffer
059969   ADC #1
059971   STA BFENLO
059973   LDA # >TEMP
059975   STA BUFRHI
059977   STA BFENHI
059979   LDA #$FF    Set no cksum
059981   STA NOCKSUM follows data fg
059983   JSR ?RECEIV Go get byte
059986   LDY #$FF    Assume success
059988   LDA STATUS
059990   CMP #1
059992   BNE ?NWOK   Go if bad
059993 ;
059994   LDA TEMP
059997   CMP #'A     Ack?
059999   BEQ ?GOOD
060000 ;
060001   CMP #'C     Complete?
060003   BEQ ?GOOD
060004 ;
060005   CMP #'E     Error?
060007   BNE ?NOTDER Go if dev did
060008 ;   not return error code
060009   LDA #144    Else error 144
060011   STA STATUS
060013   BNE ?NWOK
060014 ;
060015 ?NOTDER LDA #139 NAK error 139
060017   STA STATUS
060018 ;
060019 ?NWOK LDA STATUS
060021   CMP #138    Timeout?
060023   BEQ ?BAD    Yes, go
060024 ;
060025   LDA #$FF    Flag some error
060027   STA ERRFLG  Return with
060030   BNE ?GOOD   y<>0
060031 ;
060032 ?BAD LDY #0   y=0 if timeout
060033 ;
060034 ?GOOD LDA STATUS
060036   STA TSTAT
060039   RTS 
060040 ?SEND LDA #1  Send buffer to
060042   STA STATUS  serial bus
060044   JSR DOSENDE Enable send
060047   LDY #0
060049   STY CHKSUM  Clear chksum
060051   STY CHKSNT  and sent flag
060053   STY XMTDON  and xmit done
060055   LDA (BUFRLO),Y Load first
060057   STA SEROUT  byte and
060060   STA CHKSUM  start checksum
060061 ;
060062 ?NOTDON LDA BRKKEY
060063 ;
060064   BNE ?NTBRK0
060066   JMP ?BROKE  Go if Break key
060067 ;
060069 ?NTBRK0 LDA XMTDON Loop til
060071   BEQ ?NOTDON xmission done
060072 ;
060073   JSR ?SENDDS Disable sending
060076   RTS 
060077 XSEROUT TYA   Process serial
060078   PHA         output ready irq
060079   INC BUFRLO  Bump buffer ptr
060081   BNE ?NOWRP0
060082 ;
060083   INC BUFRHI
060084 ;
060085 ?NOWRP0 LDA BUFRLO Check if
060087   CMP BFENLO  past end
060089   LDA BUFRHI
060091   SBC BFENHI
060093   BCC ?NOTEND Branch if not
060094 ;
060095   LDA CHKSNT  Go if chksum
060097   BNE ?RELONE sent
060098 ;
060099   LDA CHKSUM  Send checksum
060101   STA SEROUT
060104   LDA #$FF
060106   STA CHKSNT
060108   BNE ?CHKDON
060109 ;
060110 ?RELONE LDA POKMSK Enable
060112   ORA #$08    transmit done
060114   STA POKMSK  interrupt
060116   STA IRQEN
060117 ;
060119 ?CHKDON PLA   Exit interrupt
060120   TAY 
060121   PLA 
060122   RTI 
060123 ?NOTEND LDY #0 Send next byte
060125   LDA (BUFRLO),Y from buffer
060127   STA SEROUT
060130   CLC 
060131   ADC CHKSUM  Add to csum
060133   ADC #0
060135   STA CHKSUM
060137   JMP ?CHKDON Return
060138 ;
060139 ;  Process serial output comp
060140 XSEROC LDA CHKSNT Go if csum
060142   BEQ ?FOOEY  not yet sent
060143 ;
060144   STA XMTDON  Else flag done
060146   LDA POKMSK  Disable xmit
060148   AND #$F7    done interrupt
060150   STA POKMSK
060152   STA IRQEN
060153 ;
060155 ?FOOEY PLA 
060156   RTI 
060157 ?RECEIV LDA #0 Receive subrtn
060159   LDY CASFLG
060162   BNE ?NOCLR  Go if cassette
060163 ;
060164   STA CHKSUM  Clear cksum,
060165 ;
060166 ?NOCLR STA BUFRFL full flag,
060168   STA RECVDN  and done flag
060170   LDA #1
060172   STA STATUS  Default good
060174   JSR ?RECVEN Enable receive
060177   LDA #$3C    Command frame hi
060179   STA PBCTL   to pia
060180 ;
060182 ?CHKTIM LDA BRKKEY
060184   BNE ?NTBRK1
060185 ;
060186   JMP ?BROKE  Go if Break key
060187 ;
060189 ?NTBRK1 LDA TIMFLG If timeout
060192   BEQ ?TOUT   go set error
060193 ;
060194   LDA RECVDN  Done?
060196   BEQ ?CHKTIM
060197 ;
060198   RTS         Yes, exit
060199 ?TOUT LDA #138 Timeout
060201   STA STATUS
060203   RTS 
060204 XSERIN TYA    Process serial
060205   PHA         input ready irq
060206   LDA SKSTAT
060209   STA SKREST  Reset status reg
060212   BMI ?NTFRAM Go if no framerr
060213 ;
060214   LDY #140    Framing error
060216   STY STATUS
060217 ;
060218 ?NTFRAM AND #$20 Go if no
060220   BNE ?NTOVRN overrun error
060221 ;
060222   LDY #142    Data frame
060224   STY STATUS  overrun
060225 ;
060226 ?NTOVRN LDA BUFRFL Go if bffr
060228   BEQ ?NOTYET not filled
060229 ;
060230   LDA SERIN   Else, byte is
060233   CMP CHKSUM  checksum
060235   BEQ ?SRETRN Branch if match
060236 ;
060237   LDY #143    Checksum err
060239   STY STATUS
060240 ;
060241 ?SRETRN LDA #$FF Flag receive
060243   STA RECVDN  done
060244 ;
060245 ?SUSUAL PLA 
060246   TAY 
060247   PLA 
060248   RTI 
060249 ?NOTYET LDA SERIN
060252   LDY #0      Store input in
060254   STA (BUFRLO),Y buffer
060256   CLC 
060257   ADC CHKSUM  Add to csum
060259   ADC #0
060261   STA CHKSUM
060262 ;
060263   INC BUFRLO  Bump buffer
060265   BNE ?NTWRP1
060266 ;
060267   INC BUFRHI
060268 ;
060269 ?NTWRP1 LDA BUFRLO
060271   CMP BFENLO
060273   LDA BUFRHI
060275   SBC BFENHI
060277   BCC ?SUSUAL Go if end bffr
060278 ;
060279   LDA NOCKSUM Go if a csum
060281   BEQ ?GOON   will follow data
060282 ;
060283   LDA #0
060285   STA NOCKSUM Clear flag
060287   BEQ ?SRETRN Go always
060288 ;
060289 ?GOON LDA #$FF Set buffer
060291   STA BUFRFL  full flag
060293   BNE ?SUSUAL Go always
060294 ;
060295 ?LDPNTR CLC   Set buffer
060296   LDA DBUFLO  pointers
060299   STA BUFRLO  and end+1
060301   ADC DBYTLO
060304   STA BFENLO
060306   LDA DBUFHI
060309   STA BUFRHI
060311   ADC DBYTHI
060314   STA BFENHI
060316   RTS 
060317 ?CASENT LDA DSTATS Taoe i/o
060320   BPL ?CASRED Go if input
060321 ;  Write a record
060322   LDA #$CC    Set 600 baud
060324   STA AUDF3
060327   LDA #5
060329   STA AUDF4
060332   JSR DOSENDE Enable mark tone
060333 ;
060335   LDX PALNTS  Mod for pal/ntsc
060336 ;
060337   LDY NTSC.PAL+4,X Short gap
060340   LDA DAUX2
060343   BMI ?SRTIR0 Go if short ok
060344 ;
060345   LDY NTSC.PAL,X Else long gap
060346 ;
060348 ?SRTIR0 LDX #0
060350   JSR ?SETVBX Set write time
060353   LDA #$34
060355   STA PACTL   Motor on
060356 ;
060358 ?TIMIT LDA TIMFLG Loop til
060361   BNE ?TIMIT  done
060362 ;
060363   JSR ?LDPNTR Set buffr ptrs
060366   JSR ?SEND   Send buffer
060369   JMP ?CRETRN Exit
060370 ;
060372 ?CASRED LDA #$FF Receive tape
060374   STA CASFLG  set flag
060375 ;
060377   LDX PALNTS
060379   LDY NTSC.PAL+6,X Short irg
060382   LDA DAUX2
060385   BMI ?SRTIR1 Go if ok
060386 ;
060387   LDY NTSC.PAL+2,X Else long
060388 ;
060390 ?SRTIR1 LDX #0 Set timeout
060392   JSR ?SETVBX for read
060395   LDA #$34
060397   STA PACTL   Motor on
060398 ;
060400 ?TIMIT1 LDA TIMFLG Loop til
060403   BNE ?TIMIT1 done
060404 ;
060405   JSR ?LDPNTR set ptrs
060408   JSR ?STTMOT set timeout
060411   JSR ?SETVBX in y,x; exec
060414   JSR ?BEGIN  set baud rate
060417   JSR ?RECEIV receive block
060418 ;
060420 ?CRETRN LDA DAUX2
060423   BMI ?SRTIR2 Go if short irg
060425   LDA #$3C    Else turn off
060427   STA PACTL   motor
060428 ;
060430 ?SRTIR2 JMP ?RETURN
060431 ;
060433 ?CLRTMFG LDA #0 Timer expiration
060435   STA TIMFLG  for cdtimer1
060438   RTS 
060439 DOSENDE LDA #7 Enable sio send
060441   AND SSKCTL  save kbd/pot
060444   ORA #$20    set tx mode
060446   LDY DDEVIC
060449   CPY #$60
060451   BNE ?NOTCAS Go if not tape
060452 ;
060453   ORA #8      Set fsk o/p bit
060455   LDY #7
060457   STY AUDF2   Set low tone
060460   LDY #5
060462   STY AUDF1   and high tone
060463 ;
060465 ?NOTCAS STA SSKCTL Set mask
060468   STA SKCTL   and actual
060469 ;
060471   LDA #$C7    disable ser
060473   AND POKMSK  ints
060475   ORA #$10    enable seror
060477   JMP ?CONTIN
060478 ;
060480 ?RECVEN LDA #7 Enable sio rx
060482   AND SSKCTL
060485   ORA #$10    set rx asynch
060487   STA SSKCTL
060490   STA SKCTL
060493   STA SKREST  reset port/kbd
060496   LDA #$C7    kill old ints
060498   AND POKMSK
060500   ORA #$20    enable serin
060501 ;
060502 ?CONTIN STA POKMSK Set up send
060504   STA IRQEN   or receive
060507   LDA #$28    clock ch3 with 4
060509   STA AUDCTL  @ 1.79 mhz
060512   LDX #6      pure tone no vol
060514   LDA #$A8
060516   LDY SOUNDR  quiet i/o?
060518   BNE ?NOISE1 no, noise on
060520   LDA #$A0    kill noise
060521 ;
060522 ?NOISE1 STA AUDC1,X Into all
060525   DEX         four audc regs
060526   DEX 
060527   BPL ?NOISE1
060528 ;
060529   LDA #$A0    no noise in
060531   STA AUDC3   audc3
060534   LDY DDEVIC
060537   CPY #$60    cassette?
060539   BEQ ?CAS31  yes go
060540 ;
060541   STA AUDC1   no noise in
060544   STA AUDC2   ch1/2 for disk
060545 ;
060547 ?CAS31 RTS 
060548 ?SENDDS NOP   Disable send
060549   LDA #$C7    or receive
060551   AND POKMSK
060553   STA POKMSK
060555   STA IRQEN
060558   LDX #6
060560   LDA #0
060561 ;
060562 ?ZERIT STA AUDC1,X kill all
060565   DEX         audio vol
060566   DEX 
060567   BPL ?ZERIT
060568 ;
060569   RTS 
060570 ?STTMOT LDA DTIMLO Set device
060573   ROR A       timeout in x,y
060574   ROR A       high 6 bits in x
060575   TAY         low 2 in y
060576   AND #$3F    mask 2 hi bits
060578   TAX         x=msb timeout
060579   TYA 
060580   ROR A
060581   AND #$C0    keep only 2 hi
060583   TAY         bits, y=lsb
060584   RTS 
060585   .WORD XSERIN sio  Not ref
060587   .WORD XSEROUT interrupt
060589   .WORD XSEROC handlers
060590 ;
060591 ?SENDIN LDX #1 Send to
060592 ;
060593 ?DELAY0 LDY #$FF intelligent
060594 ;
060595 ?DELAY1 DEY   device
060596   BNE ?DELAY1 delay a bit
060597 ;
060598   DEX         then send
060599   BNE ?DELAY0 buffer to
060600 ;
060601   JSR ?SEND   serial bus
060602 ;
060604   LDY #2      set ack timeout
060606   LDX #0
060607 ;
060608 ?WAITER JSR ?SETVBX Set timer
060611   JSR ?WAIT   await response
060614   TYA         err if y=0
060615   RTS 
060616 ?COMPUT STA TIMER2 Compute
060619   STY TIMER2+1 baud rate
060622   JSR ?ADJUST adjust Vcount
060623 ;
060625   STA TIMER2
060628   LDA TIMER1
060631   JSR ?ADJUST
060634   STA TIMER1
060637   LDA TIMER2  Find Vcount
060640   SEC         difference
060641   SBC TIMER1
060644   STA TEMP1
060647   LDA TIMER2+1
060650   SEC 
060651   SBC TIMER1+1
060654   TAY 
060655   LDX PALNTS
060657   LDA #0
060659   SEC 
060660   SBC NTSC.PAL+8,X
060661 ;
060663 ?HITIMR CLC   multiply
060664   ADC NTSC.PAL+8,X
060667   DEY 
060668   BPL ?HITIMR
060669 ;
060670   CLC         total Vcount
060671   ADC TEMP1   difference
060672 ;
060674 ?FINDX TAY    label not ref
060675   LSR A       from 800
060676   LSR A
060677   LSR A
060678   ASL A
060679   SEC 
060680   SBC #22     adj table index
060682   TAX         div by 4
060683   TYA 
060684   AND #7      get 3 low bits
060686   TAY 
060687   LDA #-11
060688 ;
060689 ?DOINTP CLC   accumulate
060690   ADC #11     interpolation
060692   DEY         constant
060693   BPL ?DOINTP
060694 ;
060695 ?ENINTP LDY #0 lbl not ref (800)
060697   SEC         adjust interpol.
060698   SBC #7      const
060700   BPL ?PLUS
060701 ;
060702   DEY 
060703 ?PLUS CLC     add const to lsb
060704   ADC TPFV,X  freq table val
060707   STA CBAUDL
060710   TYA 
060711   ADC TPFV+1,X carry to msb
060714   STA CBAUDH
060717   RTS 
060718 ?ADJUST CMP #$7C Adjust Vcount
060720   BMI ?ADJ1   value
060721 ;
060722   SEC 
060723   SBC #$7C
060725   RTS 
060726 ?ADJ1 CLC 
060727   LDX PALNTS
060729   ADC NTSC.PAL+10,X
060732   RTS 
060733 ?BEGIN LDA BRKKEY Set initial
060735   BNE ?NTBRK2 baud rate
060736 ;
060737   JMP ?BROKE
060738 ;
060740 ?NTBRK2 SEI 
060741   LDA TIMFLG  go if not timed
060744   BNE ?OKTIM1 out
060745 ;
060746   BEQ ?TOUT1  Else glitch
060747 ;
060748 ?OKTIM1 LDA SKSTAT Read serial
060751   AND #$10    port
060753   BNE ?BEGIN  Start bit?
060754 ;
060755   STA SAVIO   Save data in
060758   LDX VCOUNT  Read count
060761   LDY RTCLOK+2
060763   STX TIMER1  Save initial
060766   STY TIMER1+1 timer value
060769   LDX #1
060771   STX TEMP3
060774   LDY #$0A
060775 ;
060776 ?60776 LDA BRKKEY
060778   BEQ ?BROKE
060779 ;
060780   LDA TIMFLG
060783   BNE ?60789
060784 ;
060785 ?TOUT1 CLI 
060786   JMP ?TOUT
060787 ;
060789 ?60789 LDA SKSTAT
060792   AND #$10
060794   CMP SAVIO
060797   BEQ ?60776
060798 ;
060799   STA SAVIO
060802   DEY 
060803   BNE ?60776
060804 ;
060805   DEC TEMP3
060808   BMI ?60822
060809 ;
060810   LDA VCOUNT
060813   LDY RTCLOK+2
060815   JSR ?COMPUT
060818   LDY #9
060820   BNE ?60776
060821 ;
060822 ?60822 LDA CBAUDL
060825   STA AUDF3   audf3
060828   LDA CBAUDH
060831   STA AUDF4   audf4
060834   LDA #0
060836   STA SKCTL
060839   LDA SSKCTL
060842   STA SKCTL
060845   LDA #$55
060847   STA (BUFRLO),Y
060849   INY 
060850   STA (BUFRLO),Y
060852   LDA #$AA
060854   STA CHKSUM
060856   CLC 
060857   LDA BUFRLO
060859   ADC #2
060861   STA BUFRLO
060863   LDA BUFRHI
060865   ADC #0
060867   STA BUFRHI
060869   CLI 
060870   RTS 
060871 ?BROKE JSR ?SENDDS Process
060874   LDA #$3C    BREAK key
060876   STA PACTL
060879   LDA #$3C
060881   STA PBCTL
060884   LDA #128    Break abort
060886   STA STATUS
060888   LDX STACKP  Restore stack
060891   TXS         to entry condit.
060892   DEC BRKKEY
060894   CLI 
060895   JMP ?RETURN
060896 ;
060898 ?SETVBX LDA # <?CLRTMFG Set
060900   STA CDTMA1  countdown timer1
060903   LDA # >?CLRTMFG address
060905   STA CDTMA1+1
060908   LDA #1      y and x preset
060910   SEI         by caller
060911   JSR SETVBV  set cdtimer1?
060914   LDA #1
060916   STA TIMFLG
060919   CLI 
060920   RTS 
060921 TPFV .WORD $03E8
060923   .WORD $0443 Pokey
060925   .WORD $049E
060927   .WORD $04F9 frequency
060929   .WORD $0554
060931   .WORD $05AF values
060933   .WORD $060A
060935   .WORD $0665
060937   .WORD $06C0
060939   .WORD $071A
060941   .WORD $0775
060943   .WORD $07D0
