;          TRANSMIT
;
; A program to send DOS binary load
; files from one ATARI 800 to another
; using the JOYSTICK port.
;
;        Nick Kennedy
;
;          12/22/86
;
; System Equates:
;
CH:     EQU $2FC ; Keyboard code here
CIOV:   EQU $E456
ICCOM:  EQU $342
ICSTA:  EQU $343
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
        JMP INIT
LOADL:  DS 1
LOADH:  DS 1
ENDL:   DS 1
ENDH:   DS 1
PLACE:  DS 1
EOFF:   DS 1 ; EOF Flag
FLAG:   DS 1 ;
;
;            STRINGS:
SEGMES: DB 'SEGMENT SENT/READY RCVD',$9B
CIOE:   DB 'ERROR IN GETFB Y=$605',$9B
KYBD:   DB 'K:'
PMPT1:  DB 'Awaiting filespec from receiver:',$9B
BSTMSG: DB 'Bad status on opening file.', $9B
NTLF:   DB 'Header error - not a load file.', $9B

;
;
;            INITIALIZE
;
INIT:   LDA #$9B
        JSR PUTBYT
        LDA #$9B
        JSR PUTBYT
        PRINTS PMPT1
        LDA #$9B
        JSR PUTBYT
;
; Get the filespec from the other 800
;
        PROC
        JSR RINIT
        LDY #0
:GET1:  JSR RLOOP ; Get filespec byte
        STA RECORD,Y ; store it
        INY
        CMP #$9B ; EOR?
        BNE :GET1 ; No.
;
; Put the filespec to the screen
;
        LDA #LOW RECORD
        STA ICBAL
        LDA #HIGH RECORD
        STA ICBAH
        JSR PUTREC
        JSR TINIT ; To send status.
;
; Now, open the file for input:
; Use IOCB #1
;

        LDX #$10
        LDA #$C
        STA ICCOM,X ; First close it
        JSR CIOV
        LDA #3
        STA ICCOM,X
        LDA #HIGH RECORD
        STA ICBAH,X
        LDA #LOW RECORD
        STA ICBAL,X
        LDA #4
        STA ICAX1,X
        JSR CIOV ; Open it.
        BPL :NOERR
        PRINTS BSTMSG ; Bad open stat
        LDA #0
        JSR TLOOP ; Send badstat
        JSR INIT ; Start over
:NOERR: LDA #$FF ; Send goodstatus
        JSR TLOOP
;
        JSR GETFB ; Get file byte.
        PHA ; Stash byte
        JSR TLOOP ; Send it
        PLA
        CMP #$FF
        BNE :BADHD
        JSR GETFB
        PHA
        JSR TLOOP
        PLA
        CMP #$FF
        BEQ :GOODHD
:BADHD: PRINTS NTLF ; Not load file
        JMP INIT
;
; Get/Send Load/End addresses:
;
:GOODHD JSR GETFB
:GDHD1: STA LOADL
        JSR TLOOP
        JSR GETFB
:GDHD2: STA LOADH
        JSR TLOOP
        JSR GETFB
        STA ENDL
        JSR TLOOP
        JSR GETFB
        STA ENDH
        JSR TLOOP
;
; Now send the file bytes:
;
:SLOOP: JSR GETFB
        STY EOFF ; EOF Flag
        JSR TLOOP
;
; Now, is LOAD=END?
;
        LDA LOADH
        CMP ENDH
        BNE :NTDUN
        LDA LOADL
        CMP ENDL
        BNE :NTDUN
        JMP :SEGDUN ; Load = End.
:NTDUN: INC LOADL
        BNE :NOMO
        INC LOADH
:NOMO:  JMP :SLOOP ; Get/Send next.
;
; Receive ready code from RECEIVER:
;
:SEGDUN JSR RINIT
        JSR RLOOP ; Any byte received
        PRINTS SEGMES ;**************
        JSR TINIT ; means ready
        JSR JIF2 ; Waste jiffy or 2
;
; Now, are we at the EOF?
;
        LDA EOFF ; Status byte
        CMP #3 ; 3 = impending EOF.
        BNE :NOEOF
        LDA #0 ; Indicates EOF
        JSR TLOOP ; Tell receiver.
        LDA #$C ; Close file.
        LDX #$10
        STA ICCOM,X
        JSR CIOV
        RTS ; Back to DOS
;
; Now, next two bytes may or may not
; be $FFFF header (optional).
;
:NOEOF: LDA #$FF ; =Not EOF status
        JSR TLOOP
        JSR GETFB
        CMP #$FF
        BNE :NOHDR
        JSR GETFB
        CMP #$FF
        BNE :OHNO
        JSR GETFB ; Header was $FFFF
:NOHDR: JMP :GDHD1
:OHNO:  PHA ; Stash 2nd byte
        LDA #$FF ; 1st was $FF
        STA LOADL
        JSR TLOOP
        PLA
        JMP :GDHD2 ; Whew!
;
	EPROC
;
; GET FILE BYTE:
;
GETFB:  LDX #$10
        LDA #0
        STA ICBLL,X
        STA ICBLH,X
        LDA #7
        STA ICCOM,X
        JSR CIOV
        BMI ERROR;*******************
        RTS
ERROR:  STY $605
        PRINTS CIOE ;****************
        PLA ;************
        PLA ;************
        RTS
; JIF2: Stall 2 jiffies waiting to
; be sure the other guy gets into
; receive mode.
;
JIF2:   LDA RTCLOK
        STA PLACE
        INC PLACE
        INC PLACE
JIF2A:  LDA RTCLOK
        CMP PLACE
        BNE JIF2A
        RTS
;
JIF10:  LDA RTCLOK
        ADC #$A
        STA PLACE
JIF10A: LDA RTCLOK
        CMP PLACE
        BNE JIF10A
        RTS
;
; Subroutine to put record to E:
; (Have ICBAH/L loaded before entry)
; (Use MACRO PRINTS)
;
PUTREC: LDA #$80
        STA ICBLL
        LDX #0
        STX ICBLH
        LDA #9 ; Put record.
        STA ICCOM
        JSR CIOV
        RTS
;
; Subroutine to get a record from #0
; User set ICBAL/H.
;
GETREC: LDX #0
        LDA #5
        STA ICCOM
        LDA #$80
        STA ICBLL
        STX ICBLH
        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
;
;
; 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
;
;
; The following is the transmit/
; receive portion of TALKP.
;
; System Equates:
PACTL:  EQU $D302
;
CTLRW:  EQU %00111100 ; to R/W port
CTLDD:  EQU %00111000 ; to write data
; direction. (0=input; 1=output)
;
PORTA:  EQU $D300
;
; For STICK 0, bits 0-3 equal pins
; 1-4. (8 is ground)
;
;   PINS:
;
;
;  1 2 3 4 5   ; View of jack on
;   6 7 8 9    ; console.
;
; NOTES:
;
; Pin 1 is data.
; Pin 2 is Transmitter status.
; (DATA READY or DR) (0 = READY).
; Pin 3 is Receiver status.
; (RECEIVER READY or RR) (0 = READY).
;
; Initialization: Before each byte
; sent/received all out lines are 
; made high. Transmitter makes sure
; RR is high, then sets DATA lo. 
; Receiver watches for DR high AND
; Data lo, then is freed to set RR
; lo (ready). Transmitter is then
; free to put data and set DR lo (rdy)
;
;
;
TIMER:  DS 1 ; My timeout timer
DATA    DS 1 ; Store/send byte here
BITCT:  DS 1 ; Bit counter
;
;            STRINGS:
TOM:    DB 'TIMED OUT DURING BYTE TRANSFER', $9B
;
;            INITIALIZE
;
;
RINIT:  LDA #$FF ; Not ready.
        STA PORTA
        LDA #$9B
        JSR PUTBYT
        LDA #LOW CTLDD ; Make PORTA
        STA PACTL ; be data direction
        LDA #%00000100 ; register.
        STA PORTA ; Made bit 2 input.
        LDA #LOW CTLRW ; Make PORTA
        STA PACTL ; be I/O port again
        RTS
;
; This subroutine receives a byte:
;
RLOOP:  LDA PORTA ; XMT initialized?
        AND #3 ; Get bits 0 and 1
        CMP #2 ; Data LO & DR HI?
        BNE RLOOP ; Keep checking
        LDA #7 ; Bit counter (0-7)
        STA BITCT
RLP3:   LDA #$FF - 4 ; clear bit 2
        STA PORTA ; (set RR ready)
RLP1:   LDA BITCT ; We don't time out
        CMP #7 ; if waiting for the
        BEQ SEVEN ; first bit.
        LDA RTCLOK ; But check on
        CMP TIMER ; later bits
        BNE NOTO ; No timeout
GOON:   PRINTS TOM ; timeout message
        PLA ; Clear return address
        PLA ; from stack.
        JMP INIT ; Goto menu
SEVEN:  LDA RTCLOK ; Set up timer for
        STA TIMER ; one to two jiff's
        INC TIMER
        INC TIMER
NOTO:   LDA PORTA ; check DR
        AND #2 ; Mask all but DR line
        BNE RLP1 ; DATA not ready
        ASL DATA
        LDA PORTA ; Read data
        AND #1 ; Mask non-data
        CLC
        ADC DATA ; add it to DATA
        STA DATA
        LDA #$0F
        STA PORTA ; RR not ready
RLP2:   LDA TIMER
        CMP RTCLOK
        BEQ GOON ;  Go on. (exit)
        LDA PORTA ; Check for DR not.
        AND #2
        BEQ RLP2 ; DR not set
        DEC BITCT ; Next bit
        BPL RLP3 ; Do 8 bits
        LDA DATA ; Take it home
        RTS
;
;
; This subroutine sends a byte out
; over the PIA line:
;
TLOOP:  STA DATA ; Store the byte
TLP4:   LDA PORTA ; Check rcvr status
        AND #4
        BEQ TLP4 ; Loop if ready.
        LDA #2 ; Set DR=1, DATA=0
        STA PORTA
        LDA #7 ;    Bit counter
        STA BITCT ; initialize
        LDA RTCLOK
        STA TIMER
        INC TIMER
        INC TIMER
TLP1:   LDA RTCLOK ; Check for time
        CMP TIMER ;waiting for RR.
        BNE TLP5 ; No timeout
TGOON:  PRINTS TOM ; timeout message
        PLA ; Clear return address
        PLA ; from stack.
        PLA ; Also clear data byte.
        JMP INIT ; Goto menu
TLP5:   LDA PORTA ; Receiver ready?
        AND #4 ; Bit 2 is RR line
        BNE TLP1 ; Not ready
        ASL DATA ; Knock left bit
        LDA #0 ; Into carry
        ADC #0 ; add carry to 0
        STA PORTA ; Put data/DR ready
TLP2:   LDA TIMER
        CMP RTCLOK
        BEQ TGOON ; Timed out
        LDA PORTA ; RCVR accept data?
        AND #4 ; RR line set?
        BEQ TLP2 ; Not yet
        LDA #$0F ; Data not ready.
        STA PORTA ; Tell RCVR
        DEC BITCT ; Count the bit
        BPL TLP1 ; 8 bits sent?
        RTS
;
;  TRANSMIT section follows:
;
TINIT:  LDA #$0F ; Not ready/Not init
        STA PORTA
        LDA #LOW CTLDD
        STA PACTL ; Data direction
        LDA #%00000011
        STA PORTA
        LDA #LOW CTLRW
        STA PACTL ; Data register
        RTS
;

; RECORD is where I input my filename
; It takes no file space cause it's 
; at the end
;
RECORD: END INIT
