;adapted from https://github.com/mist64/cbmsrc/blob/master/KERNAL_C64_02/serial4.0
;.PAG 'SERIAL ROUTINES'
;COMMAND SERIAL BUS DEVICE TO TALK
;
TALK	ORA #$40        ;MAKE A TALK ADR
        .BYTE $2C       ;SKIP TWO BYTES
;
;COMMAND SERIAL BUS DEVICE TO LISTEN
;
LISTN	ORA #$20        ;MAKE A LISTEN ADR
  ; @@@ JSR RSP232      ;PROTECT SELF FROM RS232 NMI'S   --- disabled
LIST1	PHA
;
;
        BIT C3P0        ;CHARACTER LEFT IN BUF?
        BPL LIST2       ;NO...
;
;SEND BUFFERED CHARACTER
;
        SEC             ;SET EOI FLAG
        ROR R2D2
;
        JSR ISOUR       ;SEND LAST CHARACTER
;
        LSR C3P0        ;BUFFER CLEAR FLAG
        LSR R2D2        ;CLEAR EOI FLAG
;
;
LIST2	PLA             ;TALK/LISTEN ADDRESS
        STA BSOUR
        ; @@@ SEI
        JSR DATAHI
        CMP #$3F        ;CLKHI ONLY ON UNLISTEN   --- is this a bug?
        BNE LIST5
        JSR CLKHI
;
LIST5	LDA D2PRA       ;ASSERT ATTENTION
        ORA #BIT_ATN_OUT
        STA D2PRA
;
ISOURA  NOP ; @@@ SEI
        JSR CLKLO       ;SET CLOCK LINE LOW
        JSR DATAHI
        JSR W1MS        ;DELAY 1 MS
;
ISOUR   NOP ; @@@ SEI   ;NO IRQ'S ALLOWED
        JSR DATAHI      ;MAKE SURE DATA IS RELEASED
        JSR DEBPIA      ;DATA SHOULD BE LOW
        BCS NODEV
        JSR CLKHI       ;CLOCK LINE HIGH
        BIT R2D2        ;EOI FLAG TEST
        BPL NOEOI
; DO THE EOI
ISR02	JSR DEBPIA      ;WAIT FOR DATA TO GO HIGH
        BCC ISR02
;
ISR03	JSR DEBPIA      ;WAIT FOR DATA TO GO LOW
        BCS ISR03
;
NOEOI	JSR DEBPIA      ;WAIT FOR DATA HIGH
        BCC NOEOI
        JSR CLKLO       ;SET CLOCK LOW
;
; SET TO SEND DATA
;
        LDA #$08        ;COUNT 8 BITS
        STA COUNT
;
ISR01
        LDA D2PRA       ;DEBOUNCE THE BUS
        CMP D2PRA
        BNE ISR01
        ASL A           ;SET THE FLAGS
        #ifdef APPLE1 then ASL 
        BCC FRMERR      ;DATA MUST BE HI
;
        ROR BSOUR       ;NEXT BIT INTO CARRY
        BCS ISRHI
        JSR DATALO
        BNE ISRCLK
ISRHI	JSR DATAHI
ISRCLK	JSR CLKHI       ;CLOCK HI
        NOP
        NOP
        NOP
        NOP
        LDA D2PRA
        AND #$FF-BIT_DATA_OUT    ;DATA HIGH
        ORA #BIT_CLK_OUT         ;CLOCK LOW
        STA D2PRA
        DEC COUNT
        BNE ISR01

#ifdef C64        
        LDA #$04        ;SET TIMER FOR 1MS
        STA D1T2H
        LDA #TIMRB      ;TRIGGER TIMER
        STA D1CRB       ;--- timer starts here
        LDA D1ICR       ;CLEAR THE TIMER FLAGS<<<<<<<<<<<<<
ISR04	LDA D1ICR       ;--- read timer flag
        AND #$02        ;--- $02 is underflow timer B (ICR bit 1)
        BNE FRMERR
        JSR DEBPIA
        BCS ISR04
#endif

#ifdef APPLE1        
        LDA #$04        ;SET TIMER FOR 1MS
        STA D2T2H       ;--- timer starts here, flag cleared
ISR04	LDA D2IFR       ;--- read timer flag
        AND #$20        ;--- $20 is timer 2 (IFR bit 5)
        BNE FRMERR
        JSR DEBPIA
        BCS ISR04
#endif

        ; @@@ CLI       ;LET IRQ'S CONTINUE
        RTS
;
NODEV	;DEVICE NOT PRESENT ERROR
        LDA #$80
        .BYTE $2C
FRMERR	;FRAMING ERROR
        LDA #$03
CSBERR	JSR UDST        ;COMMODORE SERIAL BUSS ERROR ENTRY
        ; @@@ CLI       ;IRQ'S WERE OFF...TURN ON
        CLC             ;MAKE SURE NO KERNAL ERR
        BCC DLABYE      ;TURN ATN OFF ,RELEASE ALL LINES
;
;SEND SECONDARY ADDRESS AFTER LISTEN
;
SECND	STA BSOUR       ;BUFFER CHARACTER
        JSR ISOURA      ;SEND IT
;RELEASE ATTENTION AFTER LISTEN
;
SCATN	LDA D2PRA
        AND #$FF-BIT_ATN_OUT
        STA D2PRA       ;RELEASE ATTENTION
        RTS
;TALK SECOND ADDRESS
;
TKSA	STA BSOUR       ;BUFFER CHARACTER
        JSR ISOURA      ;SEND SECOND ADDR
TKATN	;SHIFT OVER TO LISTENER
        ; @@@ SEI       ;NO IRQ'S HERE
        JSR DATALO      ;DATA LINE LOW
        JSR SCATN
        JSR CLKHI       ;CLOCK LINE HIGH JSR/RTS
TKATN1	JSR DEBPIA      ;WAIT FOR CLOCK TO GO LOW
        BMI TKATN1
        ; @@@ CLI            ;IRQ'S OKAY NOW
        RTS
;BUFFERED OUTPUT TO SERIAL BUS
;
CIOUT	BIT C3P0        ;BUFFERED CHAR?
        BMI CI2         ;YES...SEND LAST
;
        SEC             ;NO...
        ROR C3P0        ;SET BUFFERED CHAR FLAG
        BNE CI4         ;BRANCH ALWAYS
;
CI2	PHA             ;SAVE CURRENT CHAR
        JSR ISOUR       ;SEND LAST CHAR
        PLA             ;RESTORE CURRENT CHAR
CI4	STA BSOUR       ;BUFFER CURRENT CHAR
        CLC             ;CARRY-GOOD EXIT
        RTS

;SEND UNTALK COMMAND ON SERIAL BUS
;
UNTLK   NOP ; @@@ SEI
        JSR CLKLO
        LDA D2PRA       ;PULL ATN
        ORA #BIT_ATN_OUT
        STA D2PRA
        LDA #$5F        ;UNTALK COMMAND
        .BYTE $2C       ;SKIP TWO BYTES
;SEND UNLISTEN COMMAND ON SERIAL BUS
;
UNLSN	LDA #$3F        ;UNLISTEN COMMAND
        JSR LIST1       ;SEND IT
;
; RELEASE ALL LINES
DLABYE	JSR SCATN       ;ALWAYS RELEASE ATN
; DELAY THEN RELEASE CLOCK AND DATA
;
DLADLH	TXA             ;DELAY APPROX 60 US
        LDX #10
DLAD00	DEX
        BNE DLAD00
        TAX
        JSR CLKHI
        JMP DATAHI

;INPUT A BYTE FROM SERIAL BUS
;
ACPTR
        SEI             ;NO IRQ ALLOWED
        LDA #$00        ;SET EOI/ERROR FLAG
        STA COUNT
        JSR CLKHI       ;MAKE SURE CLOCK LINE IS RELEASED
ACP00A	JSR DEBPIA      ;WAIT FOR CLOCK HIGH
        BPL ACP00A

#ifdef C64
EOIACP
        LDA #$01        ;SET TIMER 2 FOR 256US
        STA D1T2H
        LDA #TIMRB
        STA D1CRB
        JSR DATAHI      ;DATA LINE HIGH (MAKES TIMMING MORE LIKE VIC-20
        LDA D1ICR       ;CLEAR THE TIMER FLAGS<<<<<<<<<<<<
ACP00	LDA D1ICR
        AND #$02        ;CHECK THE TIMER
        BNE ACP00B      ;RAN OUT.....
        JSR DEBPIA      ;CHECK THE CLOCK LINE
        BMI ACP00       ;NO NOT YET
        BPL ACP01       ;YES.....
#endif

#ifdef APPLE1
EOIACP	LDA #$01        ;SET TIMER 2 FOR 256US
	STA D2T2H
        JSR DATAHI      ;DATA LINE HIGH (MAKES TIMMING MORE LIKE VIC-20
ACP00	LDA D2IFR
	AND #$20        ;CHECK THE TIMER
	BNE ACP00B      ;RAN OUT.....
	JSR DEBPIA      ;CHECK THE CLOCK LINE
        BMI ACP00       ;NO NOT YET
        BPL ACP01       ;YES.....
#endif

;
ACP00B	LDA COUNT       ;CHECK FOR ERROR (TWICE THRU TIMEOUTS)
        BEQ ACP00C
        LDA #2
        JMP CSBERR      ; ST = 2 READ TIMEOUT
;
; TIMER RAN OUT DO AN EOI THING
;
ACP00C	JSR DATALO      ;DATA LINE LOW
        JSR CLKHI       ; DELAY AND THEN SET DATAHI (FIX FOR 40US C64)
        LDA #$40
        JSR UDST        ;OR AN EOI BIT INTO STATUS
        INC COUNT       ;GO AROUND AGAIN FOR ERROR CHECK ON EOI
        BNE EOIACP
;
; DO THE BYTE TRANSFER
;
ACP01   LDA #8          ;SET UP COUNTER
        STA COUNT
;
ACP03	LDA D2PRA       ;WAIT FOR CLOCK HIGH
        CMP D2PRA       ;DEBOUNCE
        BNE ACP03
        ASL A           ;SHIFT DATA INTO CARRY
        #ifdef APPLE1 then ASL 
        BPL ACP03       ;CLOCK STILL LOW...
        ROR BSOUR1      ;ROTATE DATA IN
;
ACP03A	LDA D2PRA       ;WAIT FOR CLOCK LOW
        CMP D2PRA       ;DEBOUNCE
        BNE ACP03A
        ASL A
        #ifdef APPLE1 then ASL 
        BMI ACP03A
        DEC COUNT
        BNE ACP03       ;MORE BITS.....
;...EXIT...
        JSR DATALO      ;DATA LOW
        BIT STATUS      ;CHECK FOR EOI
        BVC ACP04       ;NONE...
;
        JSR DLADLH      ;DELAY THEN SET DATA HIGH
;
ACP04	LDA BSOUR1
        ; @@@ CLI       ;IRQ IS OK
        CLC             ;GOOD EXIT
        RTS
;
CLKHI	;SET CLOCK LINE HIGH (INVERTED)
        LDA D2PRA
        AND #$FF-BIT_CLK_OUT
        STA D2PRA
        RTS
;
CLKLO	;SET CLOCK LINE LOW  (INVERTED)
        LDA D2PRA
        ORA #BIT_CLK_OUT
        STA D2PRA
        RTS
;
DATAHI	;SET DATA LINE HIGH (INVERTED)
        LDA D2PRA
        AND #$FF-BIT_DATA_OUT
        STA D2PRA
        RTS
;
DATALO	;SET DATA LINE LOW  (INVERTED)
        LDA D2PRA
        ORA #BIT_DATA_OUT
        STA D2PRA
        RTS
;
DEBPIA	LDA D2PRA       ;DEBOUNCE THE PIA
        CMP D2PRA
        BNE DEBPIA
        #ifdef APPLE1 then ASL         
        ASL A           ;SHIFT THE DATA BIT INTO THE CARRY...        
        RTS             ;...AND THE CLOCK INTO NEG FLAG
;
W1MS	;DELAY 1MS USING LOOP
        TXA             ;SAVE .X
        LDX #200-16     ;1000US-(1000/500*8=#40US HOLDS)
W1MS1	DEX             ;5US LOOP
        BNE W1MS1
        TAX             ;RESTORE .X
        RTS
;.END
;*******************************
;WRITTEN 8/11/80 BOB FAIRBAIRN
;TEST SERIAL0.6 8/12/80  RJF
;CHANGE I/O STRUCTURE 8/21/80 RJF
;MORE I/O CHANGES 8/24/80 RJF
;FINAL RELEASE INTO KERNAL 8/26/80 RJF
;SOME CLEAN UP 9/8/80 RSR
;ADD IRQ PROTECT ON ISOUR AND TKATN 9/22/80 RSR
;FIX UNTALK 10/7/80 RSR
;MODIFY FOR VIC-40 I/O SYSTEM 12/08/81 RSR
;ADD SEI TO (UNTLK,ISOURA,LIST2) 12/14/81 RSR
;MODIFY FOR 6526 FLAGS FIX ERRS 12/31/81 RSR
;MODIFY FOR COMMODORE 64 I/O  3/11/82 RSR
;CHANGE ACPTR EOI FOR BETTER RESPONSE 3/28/82 RSR
;CHANGE WAIT 1 MS ROUTINE FOR LESS CODE 4/8/82 RSR
;******************************
;.END
