;            TALK
;
;        Nick Kennedy
;
;          10-29-86
;
; An experiment with the serial bus
; which will send characters between
; two Atari 800 computers using the 
; serial port, but not using SIO.
;
; System Equates:
B600LO EQU $CC ; for 600 baud
B600HI EQU $05
SERIN:  EQU $D20D ; Data in register.
SEROUT: EQU $D20D ; Outgoing data here
IRQST  EQU $D20E ; IRQ interrupt status. 1 = Interrupt, 0 = No interrupt. 
; Bit 5 is input ready.
;
IRQEN  EQU $D20E ; IRQ enable. 0=disable, 1=enable. Bit 5 is serial input.
;
POKMSK EQU $10 ; Shadow for above.
SKCTL:  EQU $D20F
SSKCTL: EQU $232 ; Shadow for above
AUDCTL  EQU $D208
VSERIN  EQU $20A; Serial input vector
VSEROR: EQU $20C ; Serial out ready.
AUDF1:  EQU $D200
AUDF2:  EQU $D202
AUDF3:  EQU $D204
AUDF4:  EQU $D206
AUDC1:  EQU $D201
AUDC2:  EQU $D203
AUDC3:  EQU $D205
AUDC4:  EQU $D207
PACTL:  EQU $D302 ; Bit 3=0 for motor
;                   on.
CH:     EQU $2FC ; Keyboard code here
CIOV:   EQU $E456
ICCOM:  EQU $342
ICBAL:  EQU $344
ICBAH:  EQU $345
ICBLL:  EQU $348
ICBLH:  EQU $349
ICAX1:  EQU $34A
RTCLOK: EQU $14
BEEP:   EQU $FD
CONSOL: EQU $D01F

;
        ORG $4000
PLACE:  DS 1
TIMER:  DS 1 ; My timeout timer
FLAG:   DS 1 ;
TVECT:  DS 2 ; Place for VSEROR
SWITCH: DS 1 ; Exch. trans/receive
SWIT1:  DS 1  ; Same.
;
;            STRINGS:
MODE:   DB 'PRESS START FOR RECEIVE',$9B
MODE2:  DB 'PRESS SELECT FOR TRANSMIT',$9B
MSG1:   DB 'NOW IN RECEIVE MODE.',$9B
MSG2:   DB 'NOW IN TRANSMIT MODE.',$9B
KYBD:   DB 'K:'
;
;
;            INITIALIZE
;
INIT:   LDA #125
        JSR PUTBYT
        LDA #$9B
        JSR PUTBYT
        LDA #$9B
        JSR PUTBYT
        PRINTS MODE
        LDA #$9B
        JSR PUTBYT
        PRINTS MODE2
        JSR OPENK
;
TORR:   JSR WAIT ; Get button choice
        CMP #6 ; START
        BEQ RINIT
        CMP #5 ;  SELECT
        BEQ GTINIT ; Long branch
        BNE TORR
GTINIT: JMP TINIT
;
;         INITIALIZE POKEY
;  de re Atari says do this on
;  page 7-2:
;
RINIT:  PRINTS MSG1
        LDA #0
        STA AUDCTL
        STA SKCTL ; Init. POKEY
        LDA #$13
        STA SSKCTL
        STA SKCTL 
        LDA #$28 ; 1.79 Mhz into 3 
        STA AUDCTL;and 3 into 4.
        LDA #$A0; Turn off sound.
        STA AUDC3
        STA AUDC1
        STA AUDC2
        LDA #$A8 ; Let's hear it.
        STA AUDC4
        LDA #$FF ; Don't switch flag
        STA SWITCH
;
;    Set baud rate to 600:
;
        LDA #B600LO
        STA AUDF3
        LDA #B600HI
        STA AUDF4
;
; Set the serial input IRQ vector to
; my service routine:
;
        SEI
        LDA #HIGH RECV
        STA VSERIN+1
        LDA #LOW RECV
        STA VSERIN
        LDA #%00100000
        ORA POKMSK
        STA POKMSK
        STA IRQEN
        CLI
;
; The program idles here while waiting for a SERIN interrupt:
;
TIME:   LDA CH ; CTRL-A PRESSED?
        CMP #$3F + $80 ; CTRL-A
        BEQ GOT
        LDA SWITCH ; CTRL-A RECEIVED?
        BEQ GOT ; Go to transmit
        JMP TIME 
GOT:    JMP TINIT 
;
; Wait for console button routine:
;
WAIT:   LDA CONSOL
        AND #7 ; 3 lo bits only.
        CMP #7
        BEQ WAIT
        RTS
;
; The interrupt service routine:
;
RECV:   CLI
        TXA ; Preserve X during
        PHA ; interrupt.
        TYA ; And Y too.
        PHA
        LDA SERIN; Get byte from bus.
        STA PLACE
        JSR PUTBYT ; Put to screen
        LDA PLACE
        CMP #1 ; CONTROL-A
        BNE NOFLG
        LDA #0
        STA SWITCH
NOFLG:  PLA ; Restore registers:
        TAY
        PLA
        TAX
        PLA
        RTI
;
; Subroutine to put record to E:
; (Have ICBAH/L loaded before entry)
;
PUTREC: LDA #$80
        STA ICBLL
        LDX #0
        STX ICBLH
        LDA #9 ; Put record.
        STA ICCOM
        JSR CIOV
        RTS
;
; Subroutine to put byte to E:
; (Have byte in accumulator on entry)
;
PUTBYT: LDX #$B ; Put byte
        STX ICCOM
        LDX #0
        STX ICBLH
        STX ICBLL
        JSR CIOV
        RTS
;
;  TRANSMIT section follows:
;
TINIT:  PRINTS MSG2
        LDA #0
        STA AUDCTL
        STA SKCTL ; init POKEY
        LDA #$23 ; KYBD scan and
        STA SSKCTL ; debounce on and
        STA SKCTL; bit 5 mode.
        LDA #$28 ; 1.79Mhz; 3 into 4
        STA AUDCTL
        LDA #$A0
        STA AUDC1
        STA AUDC2
        STA AUDC3
        LDA #$A8 ; Let's hear it!
        STA AUDC4
        LDA #$FF; Enable one byte out
        STA FLAG
        STA CH ; Clear K:
;
; SWITCH = 0, CTRL-A has been pressed
; SWIT1 = 0, it's sent, now switch.
;
        STA SWITCH ; No switch
        STA SWIT1
        LDA VSEROR ; Save vector to
        STA TVECT ; be restored.
        LDA VSEROR+1
        STA TVECT+1
;
;       Enable interrupt:
;
        SEI
        LDA #%00010000
        ORA POKMSK
        STA IRQEN
        STA POKMSK
;
; Point interrupt vector to my routine
;
        LDA #HIGH TINT
        STA VSEROR+1
        LDA #LOW TINT
        STA VSEROR
;
; Set baud to 600:
;
        LDA #B600LO
        STA AUDF3
        LDA #B600HI
        STA AUDF4
;
; Enable processor IRQ's
;
        CLI
;
; Main program follows:
;
TLOOP:  LDA SWIT1
        BEQ GOR ; Go to receive.
        LDA SWITCH ; Loop till sent.
        BEQ TLOOP
        JSR GETK
        STA PLACE
        JSR PUTBYT
TLOOP1: LDA CONSOL
        AND #%00000100 ; OPTION
        BEQ THOME ; Back to DOS
        LDA FLAG ; Has interrupt
        BEQ TLOOP1 ; occured?
        LDA PLACE
        STA SEROUT; Yes, send byte.
        CMP #1 ; CTRL-A
        BNE NOSW
        LDA #0
        STA SWITCH
NOSW:   LDA #0
        STA FLAG ; Need another one.
        JMP TLOOP
THOME:  LDA #%11101111 ; Disable IRQ
        AND POKMSK
        SEI
        STA POKMSK
        STA IRQEN
        LDA TVECT ; Restore IRQ
        STA VSEROR ; vector.
        LDA TVECT+1
        STA VSEROR+1
        CLI
        LDA #$A0
        STA AUDC4
        JSR CLOSK
        RTS
;
GOR:    JMP RINIT ; Switch to receive
;
;
; A routine to get one byte from 
; IOCB #0 (assumed to be E:):
;
GETBYT: LDX #0
        STX ICBLL
        STX ICBLH
        LDA #7
        STA ICCOM ; Get bytes.
        JSR CIOV
        RTS
;
;       Transmit interrupt routine:
;
TINT:   CLI
        LDA #$FF 
        STA FLAG
        LDA SWITCH
        BNE NOSW1
        LDA #0 ; Last byte has just
        STA SWIT1 ; gone - switch.
NOSW1:  PLA
        RTI
;
; OPEN KEYBOARD, IOCB #1
;
OPENK:  LDX #$10
        LDA #3
        STA ICCOM,X
        LDA #4 ; Read
        STA ICAX1,X
        LDA #HIGH KYBD
        STA ICBAH,X
        LDA #LOW KYBD
        STA ICBAL,X
        JSR CIOV
        RTS
CLOSK:  LDX #$10 ; Close it.
        LDA #$C
        STA ICCOM,X
        JSR CIOV
        RTS
;
GETK:   LDX #$10 ; Get one byte from 
        LDA #$7 ;  keyboard.
        STA ICCOM,X
        LDA #0
        STA ICBLL,X
        STA ICBLH,X
        JSR CIOV
        RTS
;
        END INIT
;
        
