.feature labels_without_colons
.export TERMINAL
.export START_HERE
.export PUNTER_START
;**************************************************
;*                                                *
;*      T E R M . C 1  (NEW PUNTER PROTOCOL)      *
;*      ------------------------------------      *
;*                                                *
;*               SOURCE = S/TERM.C1               *
;*               OBJECT = O/TERM.C1               *
;*                                                *
;*   THIS NEW PUNTER PROTOCOL FEATURES ADJUST-    *
;* ABLE DATA LENGTH (40-255 BYTES), NEW HAND-     *
;* SHAKING SIGNALS, AND FASTER UP/DOWNLOADS.      *
;*                                                *
;*    - COMMENTED DISASSEMBLY  BY TOM HUGHES -    *
;*                                                *
;*                    V081284                     *
;*                                                *
;**************************************************

;
;C-64 EQUATES
;

Z62    = $62 ;SYS JUMP VALUE/COUNTER
Z64    = $64 ;BUFFER POINTER-LO
Z65    = $65 ;  ''     ''   -HI
Z96    = $96 ;PSUEDO-ST REGISTER
;                         0 = OK
;                         1 = ALL BYTES RECEIVED ???
;                         2 = RECEIVE BUFFER EMPTY
;                         4 = SOME BYTES RECEIVED
;                         8 = $4806/4807 = 0
DEFTO  = $9a ;default output device
PTR1   = $9e ;tape pass1 error log (kernal)
ZBA    = $BA ;CURRENT DEVICE #
TAPE1  = $B2 ; Pointer to tape i/o buffer [2]
BUFPNTR= $A6 ; pointer to tape i/o buffer [2]
ZF7    = $F7 ;RS-232 INPUT BUFFER POINTER-LO
ZF8    = $F8 ;  ''     ''    ''      ''  -HI
ROBUF  = $F9 ; Pointer to RS-232 output buffer

X0200  = $0200 ;RS-232 BYTE/FLAG: BLOCK SIZE
X028D  = $028D ;KEYBRD FLAG: 2 = CMDR PRESSED
X029B  = $029B ;PTR: END OF RS-232 INPUT BUFFER
X029C  = $029C ;PTR: START   ''      ''    ''
RODBS  = $029D ; start position of RS-232 output buffer
RODBE  = $029E ; end position of RS-232 output buffer
X02A1  = $02A1 ;RS-232 ENABLES

IBSOUT = $0326 ; Vector to CHROUT

RS2SET = $F05B ;ENABLE RS-232 BYTE RECEPTION
BASIC1 = $F8C0 ; basic call from chrout
BASIC2 = $F290 ; basic call from chrout
BASIC3 = $EFEE ; Set next RS-232 buffer byte
; BASIC4 = ; Not used on VIC-20
CHKIN  = $FFC6 ;READY CHANNEL FOR OUTPUT
CHRIN  = $FFCF ;INPUT CHAR TO CHANNEL
CHKOUT = $FFC9 ; ''     ''     '' INPUT
CHROUT = $FFD2 ;OUTPUT CHAR TO CHANNEL
CLRCHN = $FFCC ;I/O TO DEFAULT (SCREEN)
GETIN  = $FFE4 ;GET CHAR FROM KEYBOARD
READST = $FFB7 ;READ/CLEAR I/O STATUS WORD
; 'PROGRAM STORAGE'
XC800  = $4800 ;3-LETTER HANDSHAKE
XC801  = $4801 ;    ''       ''
XC802  = $4802 ;    ''       ''
XC803  = $4803 ;SC051 LOOP COUNTER (1,2,4,8,16,32)
XC804  = $4804 ;SC051 HANDSHAKE PTR (0,3,6,9,12 OR 15)
XC805  = $4805 ;SC051 ENTRY VALUE (0,4,8,11 OR 16)
XC806  = $4806 ;SC051/SC27F FLAG: $FF=HSHAKE REC'D
XC807  = $4807 ;    ''       ''         ''
XC808  = $4808 ;HANDSHAKE INDEX (0,3,6,8,12)
XC809  = $4809 ;# BYTES IN BLOCK/COUNTER ???
XC80A  = $480A ;(UNUSED)
XC80B  = $480B ;DELAY FLAG: 0=NO DELAY IF $480C < 3
XC80C  = $480C ;SC55E COUNTER (0-3)
XC80D  = $480D ;REC/XMIT FLAG: 0 = 1ST BLOCK
XC80E  = $480E ;SC484 CHECKSUM WORKSPACE
XC80F  = $480F ;  ''     ''       ''
XC810  = $4810 ;  ''     ''       ''
XC811  = $4811 ;  ''     ''       ''
XC812  = $4812 ;SC380 CHECKSUM WORKSPACE
XC813  = $4813 ;  ''     ''       ''
XC814  = $4814 ;  ''     ''       ''
XC815  = $4815 ;  ''     ''       ''
XC816  = $4816 ;$64/65 OFFSET
XC817  = $4817 ;# BYTES TO SEND (SET BY $4904) ???
XC818  = $4818 ;BLOCK SIZE (40-255)
XC819  = $4819 ;COUNTER/FLAG: $FF FOR XMIT START ???
XC81A  = $481A ;      ''
XC81B  = $481B ;FILETYPE (1=PRG, 2=SEQ, 3=WORDPRO)
XC81C  = $481C ;ENTRY STACK POINTER
XC81D  = $481D ;XMIT FLAG: 0=SHORT BLK/1=LONG BLK
XC81E  = $481E ;XMIT FLAG: 0=SEND "GOO"/1=SEND "SYN"
XMIT   = $4B00
OLDOUT = $4B02

;
;BLOCK HEADER FORMAT ($4900=REC BUFF/$4A00=XMIT BUFF)
;

XC900  = $4900 ;CHECKSUM 1 - SUM
XC901  = $4901 ;    ''       ''
XC902  = $4902 ;CHECKSUM 2 - EOR
XC903  = $4903 ;    ''       ''
XC904  = $4904 ;# BYTES IN HEADER (7)
XC905  = $4905 ;# BYTES IN BLOCK ???
XC906  = $4906 ;ERROR FLAG: $FF=???
XC907  = $4907 ;FILETYPE (1-3)
; 'JUMPS & DATA'

.segment "PUNTER"
;
;SYS "ADJUSTABLE" JUMP VALUES
;
START_HERE
; .byte 0, 0, 0, 0, 0, 0, 0, 0
; .byte 0, 0, 0, 0, 0, 0, 0, 0
; .byte 0, 0

lda #0 ;sys 49152
.byt $2c
lda #3 ;sys 49155 (receive data-2)
.byt $2c
lda #6 ;sys 49158 (transmit data-2)
.byt $2c
lda #9 ;sys 49161 (receive data-1)
.byt $2c
lda #12 ;sys 49164 (transmit data-1)
.byt $2c
lda #15 ;sys 49167 (terminal mode)
nop

PUNTER_START
JMP JC018 ;SET ADJUSTABLE JUMP
JMP SC59B ;SYS 49173 (RS-232 SETTUP)
;JMP INIT ;

JC018 STA Z62 ;(0,3,6,9,12,15)
TSX
STX XC81C ;SAVE CURRENT STACK PTR
LDA #$30
CLC
ADC Z62
STA ADJUMP+1 ;SET JUMP-LO
LDA #>ADJUMP
ADC #0
STA ADJUMP+2 ;SET JUMP-HI
ADJUMP JMP $0000

JMP_TABLE
;
;JUMP TABLE
;
JMP SC051 ;(SYS 49152)
JMP SC408 ;RECEIVE 2 (SYS 49155)
JMP SC3D0 ;TRANSMIT 2 (SYS 49158)
JMP SC4CE ;RECEIVE 1 (SYS 49161)
JMP SC517 ;TRANSMIT 1 (SYS 49164)
TERMINAL
JMP SC5AA ;TERMINAL MODE (SYS 49167)

;
;HANDSHAKE SIGNALS (SENT BY SC124)
;
HSHAKE = * ;INDEXED BY .Y & $4808
.BYT "GOO" ;.Y = 0  (GO)  ???
.BYT "BAD" ;.Y = 3  (BAD BLOCK)
.BYT "ACK" ;.Y = 6  (ACKNOWLEDGE)
.BYT "S/B" ;.Y = 9  (SEND BLOCK) ???
.BYT "SYN" ;.Y = 12 (BBS READY) ???
; "RECEIVE HANDSHAKE"
;----------------------------------------
;SC151: CHECK FOR BBS HANDSHAKE
;----------------------------------------

;ENTRY: IF .A = 0, DON'T CHECK ANY
;               4, CHECK FOR "ACK" ONLY
;               8,   ''   '' "S/B"  ''
;              11,   ''   '' "GOO", "BAD", OR "S/B"
;              16,   ''   '' "SYN" ONLY
;EXIT: IF RECEIVED, $96 = 0 & $4806/C807 = 0
;      IF NOT, $96 = 1

SC051 STA XC805 ;SAVE ENTRY VALUE
LDA #0 ;CLEAR HANDSHAKE STORAGE
STA XC800
STA XC801
STA XC802

JC05F LDA #0 ;CLEAR COUNTERS/FLAGS
STA XC806
STA XC807
JC067 JSR SC67B ;CMDR KEY PRESSED? (IF YES,EXIT)
JSR SC0F2 ;GET BYTE FROM RS-232 BUFFER
LDA Z96 ;BYTE IN BUFFER?
BNE BC0C9
LDA XC801 ;YES, STORE @ $4800-C802
STA XC800
LDA XC802
STA XC801
LDA X0200 ;RS-232 BYTE
STA XC802
LDA #0
STA XC804 ;HANDSHAKE WORD PTR = 0
LDA #1
STA XC803 ;SET LOOP COUNTER

;VALIDATE BBS HANDSHAKE
;
BC08D LDA XC805 ;(= 0,4,8,11 OR 16)
BIT XC803 ;(= 1,2,4,8,16 OR 32)
BEQ BC0AB ;IF EQUAL, DON'T CHECK HSHAKE
LDY XC804
LDX #0
BC09A LDA XC800,X ;ELSE GET BBS HANDSHAKE WORD
CMP HSHAKE,Y ;SAME AS TABLE?
BNE BC0AB
INY
INX
CPX #3
BNE BC09A
JMP JC0BE ;YES, SET FLAGS & GET MORE BYTES
;
BC0AB ASL XC803 ;TIMES 2 (= 2,4,8,16 OR 32)
LDA XC804 ;SET TO NEXT HANDSHAKE WORD
CLC
ADC #3
STA XC804 ;BUMP INDEX BY 3
CMP #15 ;LAST WORD?
BNE BC08D
JMP JC05F ;YES, TRY AGAIN

;HANDSHAKE RECEIVED FROM BBS
;
JC0BE LDA #$FF ;SET FLAGS
STA XC806
STA XC807
JMP JC067 ;AND GET MORE BYTES

;RS-232 INPUT BUFFER EMPTY ($96 = 2)
;
BC0C9 INC XC806 ;BUMP COUNTERS/FLAGS
BNE BC0D1
INC XC807
BC0D1 LDA XC807
ORA XC806 ;HANDSHAKE RECEIVED?
BEQ BC0EC ;YES, EXIT
LDA XC806
CMP #7 ;???
LDA XC807
CMP #20 ;HI-COUNT < 20?
BCC JC067

LDA #1 ;NO, SET FLAG: HSHAKE REC'D
STA Z96
JMP SC55E ;DELAY/EXIT

BC0EC LDA #0 ;FLAG: HSHAKE RECEIVED
STA Z96
RTS
; "INPUT RS-232 BYTE"
;----------------------------------------
;SC0F1: GET BYTE FROM RS-232 BUFFER
;----------------------------------------

;EXIT:  IF BYTE, $0200 = BYTE/$96 = 0
;       IF NO BYTE, $0200 = 0/$96 = 2

SC0F1 NOP
SC0F2 TYA ;PRESERVE .Y
PHA
LDA X029B
CMP X029C ;INPUT BUFFER EMPTY?
BEQ BC112
LDY X029C
LDA (ZF7),Y ;NO, GET BYTE FROM BUFFER
PHA ;SAVE
INC X029C ;BUMP BUFFER POINTER
LDA #0
STA Z96 ;SET FLAG = 0
PLA
STA X0200 ;STORE BYTE
PLA
TAY ;RESTORE .Y
JMP JC11D

;RS-232 BUFFER EMPTY
;
BC112 LDA #2
STA Z96 ;SET FLAG = 2
LDA #0
STA X0200 ;STORE NULL BYTE
PLA
TAY ;RESTORE .Y

JC11D PHA ;PRESERVE .Y
LDA #3
STA ZBA ;SCREEN = CURRENT DEVICE
PLA ;RESTORE .Y
RTS
; 'SEND HANDSHAKE'
;----------------------------------------
;SC124: SEND HANDSHAKE TO BBS
;----------------------------------------

;ENTRY:  IF .Y = 0, "GOO"
;          ''    3, "BAD"
;          ''    6, "ACK"
;          ''    9, "S/B"
;          ''   12, "SYN"

SC124 LDX #4 ;READY MODEM FOR OUTPUT (was #5)
JSR CHKOUT
LDX #0
BC12B LDA HSHAKE,Y
JSR CHROUT ;HANDSHAKE -> MODEM
INY
INX
CPX #3 ;SEND 3 BYTES
BNE BC12B
JMP CLRCHN ;I/O TO DEFAULTS, EXIT

;----------------------------------------
;SC13A: SEND HANDSHAKE, GET DATA @ $4900
;----------------------------------------

;ENTRY:  .A = HANDSHAKE WORD INDEX (SEE ABOVE)
;             (0=1ST BLOCK/1=ALL OTHERS)

SC13A STA XC808 ;SAVE INDEX
LDA #0
STA XC80B ;FLAG: DELAY/EXIT IF $480C > 2
JC142 LDA #2
STA Z62 ;SET ATTEMPT COUNTER
LDY XC808
JSR SC124 ;SEND HANDSHAKE
BC14C LDA #4                    ; Did this get changed?
JSR SC051 ;WAIT FOR BBS "ACK"
LDA Z96 ;RECEIVED?
BEQ BC15C
DEC Z62
BNE BC14C
JMP JC142 ;NO, TRY AGAIN
;
;BBS "ACK" RECEIVED
;
BC15C LDY #9
JSR SC124 ;SEND "S/B" TO BBS
LDA XC80D ;FLAG: 1ST BLOCK?
BEQ BC16B
LDA XC808 ;FLAG: LAST HSHAKE = "GOO"?
BEQ BC18A ;YES, BRANCH

;RECEIVE 1ST BLOCK (8 BYTES)
;
BC16B LDA XC904 ;# OF BYTES TO RECEIVE (8=START)
STA XC809
STA XC817
JSR SC27F ;RECEIVE BBS DATA @ $4900
LDA Z96
CMP #1 ;ALL BYTES RECEIVED?
BEQ BC189 ;YES, EXIT
CMP #2 ;RECEIVE BUFFER EMPTY?
BEQ BC15C ;YES, SEND "S/B" AGAIN
CMP #4 ;1 OR MORE BYTES RECEIVED?
BEQ BC189 ;YES, EXIT
CMP #8 ;COUNTERS AT MAX?
BEQ BC15C ;YES, SEND "S/B" AGAIN
BC189 RTS ;$96 = 1 OR 4

;FLAG $480D = 0 ("GOO")
;
BC18A LDA #16
JSR SC051 ;WAIT FOR BBS "SYN"
LDA Z96 ;RECEIVED?
BNE BC15C ;NO, SEND "S/B" AGAIN

LDA #10
STA XC809
BC198 LDY #12
JSR SC124 ;YES, SEND "SYN" TO BBS
LDA #8
JSR SC051 ;WAIT FOR  "S/B"
LDA Z96 ;RECEIVED?
BEQ BC1AB
DEC XC809 ;NO, ATTEMPT 10 TIMES
BNE BC198
BC1AB RTS ;$96 = 0 OR 1
; 'BUFFER -> BBS'
;----------------------------------------
;SC1AC:  SEND $4809 BYTES -> BBS
;----------------------------------------

;EXIT: IF .A = 0, GOOD BLOCK
;        ''    1, BAD BLOCK/LAST BLK ???

SC1AC LDA #1
STA XC80B ;FLAG: DELAY/EXIT
BC1B1 LDA XC81E ;FLAG: 1=SEND "GOO"/0=NO "GOO"
BEQ BC1BB
LDY #0
JSR SC124 ;SEND "GOO"
BC1BB LDA #11
JSR SC051 ;WAIT FOR "GOO", "BAD" OR "S/B"
LDA Z96 ;ONE RECEIVED?
BNE BC1B1 ;NO, TRY AGAIN

;EITHER "GOO", "BAD" OR "S/B" RECEIVED
;
LDA #0
STA XC81E ;FLAG: 0=NO "GOO"
LDA XC804 ;WAS "GOO" RECEIVED?
CMP #0
BNE BC205 ;NO, PRINT ":", SEND "ACK" & HEADER, EXIT

;"GOO" RECEIVED
;
LDA XC80D ;FLAG: 1ST BLOCK?
BNE BC23D ;YES, PRINT "*", SEND "ACK" & "S/B",EXIT
INC XC819 ;(= 0 FOR 1ST BLK)
BNE BC1DD
INC XC81A ;(= 0 FOR 1ST BLK)
BC1DD JSR SC364 ;SET $64/65 = $4A00
LDY #5
INY
LDA (Z64),Y ;$4A06 = $FF? (START?)
CMP #$FF
BNE BC1FF ;NO, DISK -> BUFFER
LDA #1
STA XC80D ;FLAG: NOT 1ST BLOCK
LDA XC816
EOR #%00000001
STA XC816 ;RESET $64/65 = $4900
JSR SC364
JSR SC344 ;COMPUTE BLOCK CHECKSUM
JMP JC202 ;SEND "ACK" & $4809 BYTES
;
;DISK -> BUFFER  ($4906/CA06 <> $FF)
;
BC1FF JSR SC2FF ;DISK -> BUFFER
JC202 LDA #'-' ;"-" = GOOD BLOCK
.BYT $2C
BC205 LDA #':' ;":" = BAD BLOCK
JSR SC586 ;PRINT "-" OR ":" (IF $480D = 0)
LDY #6
JSR SC124 ;SEND "ACK"
LDA #8
JSR SC051 ;WAIT FOR BBS "S/B"
LDA Z96 ;RECEIVED?
BNE JC202 ;NO, TRY AGAIN

;BBS "S/B" RECEIVED, SEND $4809 BYTES
;
JSR SC364 ;SET $64/65 = $4A00 ???
LDY #4
LDA (Z64),Y ;GET # OF BYTES IN HEADER
STA XC809 ;SAVE
JSR SC371 ;SET $64/65 = $4900 ???
LDX #4 ; was #5
JSR CHKOUT ;READY MODEM FOR OUTPUT
LDY #0
BC22C LDA (Z64),Y ;$4809 BYTES -> BBS
JSR CHROUT
INY
CPY XC809 ;# BYTES IN HEADER ???
BNE BC22C
JSR CLRCHN ;I/O TO DEFAULT
LDA #0
RTS
;
;SEND SHORT BLOCK "*" ???
;ENTRY: $480D <> 0
;
BC23D LDA #'*'
JSR SC586 ;PRINT "*"
LDY #6
JSR SC124 ;SEND "ACK" TO BBS
LDA #8
JSR SC051 ;WAIT FOR BBS HSHAKE (EXCEPT "S/B")
LDA Z96 ;RECEIVED?
BNE BC23D ;NO, SEND AGAIN

;BBS HANDSHAKE RECEIVED
;
LDA #10
STA XC809
BC255 LDY #11
JSR SC124 ;SEND "SYN" TO BBS
LDA #16
JSR SC051 ;WAIT FOR BBS HSHAKE (EXCEPT "SYN")
LDA Z96 ;RECEIVED?
BEQ BC268
DEC XC809 ;N0, TRY 10 TIMES
BNE BC255

;BBS HANDSHAKE RECEIVED
;
BC268 LDA #3
STA XC809 ;SET ATTEMPT COUNTER
BC26D LDY #9
JSR SC124 ;SEND "S/B" 3 TIMES
LDA #0
JSR SC051 ;WAIT FOR ANY BBS HANDSHAKE
DEC XC809 ;-1 FROM ATTEMPT COUNTER
BNE BC26D
LDA #1 ;FLAG: ERROR ???
RTS
; 'BBS -> BUFFER'
;----------------------------------------
;SC27F: RECEIVE BBS DATA @ $4900
;----------------------------------------

SC27F LDY #0
BC281 LDA #0
STA XC806 ;CLEAR ATTEMPT COUNTERS
STA XC807
JC289 JSR SC67B ;CMDR KEY PRESSED?
JSR SC0F2 ;NO, GET RS-232 BUFFER BYTE
LDA Z96 ;BYTE IN BUFFER?
BNE BC2CF ;NO, BUMP ATTEMPT COUNT

;RS-232 BYTE RECEIVED
;
LDA X0200 ;GET MODEM BYTE
STA XC900,Y
CPY #3 ;3 HANDSHAKE BYTES RECEIVED?
BCS BC2B9 ;YES, SKIP

STA XC800,Y
CPY #2
BNE BC2B9
LDA XC800 ;FIRST 3 BYTES = "ACK"?
CMP #'A'
BNE BC2B9
LDA XC801
CMP #'C'
BNE BC2B9
LDA XC802
CMP #'K'
BEQ BC2C4 ;YES, BRANCH

BC2B9 INY
CPY XC809 ;ALL BYTES RECEIVED?
BNE BC281
LDA #1 ;YES, SET FLAG = 1
STA Z96
RTS

;"ACK" RECEIVED @ $4800-C802
;
BC2C4 LDA #$FF
STA XC806 ;SET FLAGS TO MAX
STA XC807
JMP JC289 ;GET MORE BYTES
;
;HANDLE $96 <> 0
;
BC2CF INC XC806 ;BUMP LO-COUNTER
BNE BC2D7
INC XC807 ;BUMP HI-COUNTER
BC2D7 LDA XC806
ORA XC807 ;COUNTERS AT MAX?
BEQ BC2FA
LDA XC806
CMP #6 ;???
LDA XC807
CMP #16 ;NO, HI-COUNTER < 16?
BNE JC289 ;YES, TRY AGAIN
LDA #2
STA Z96 ;IF NO BYTES, $96 = 2
CPY #0
BEQ BC2F7
LDA #4 ;IF 1+ BYTES, $96 = 4
STA Z96
BC2F7 JMP SC55E ;DELAY & EXIT

BC2FA LDA #8 ;IF COUNTERS = 0, $96 = 8
STA Z96
RTS
;
;----------------------------------------
;SC2FF:  DISK -> BUFFER
;----------------------------------------

SC2FF LDA XC816 ;CHANGE CURRENT BUFFER
EOR #%00000001
STA XC816
JSR SC364 ;SET $64/65 = $4A00 ???
LDY #5
LDA XC819 ;L-ADDRESS SEND BUFFER ???
CLC
ADC #1 ;+1
STA (Z64),Y ;SAVE @ $4A05/C905 ???
INY
LDA XC81A ;H-ADDRESS SEND BUFFER ???
ADC #0
STA (Z64),Y ;SAVE @ $4A06/C906 ???
LDX #2
JSR CHKIN ;READY CH 2 FOR INPUT (DISK)
LDY #7
BC323 JSR CHRIN ;GET DISK BYTE
STA (Z64),Y ;SAVE  @ $4A07 ON ...
INY
JSR READST ;ST = 0?
BNE BC338
CPY XC818 ;$4818 BYTES RECEIVED?
BNE BC323
TYA
PHA ;PRESERVE BUFFER POINTER
JMP JC345

;ST <> 0
;
BC338 TYA
PHA ;PRESERVE BUFFER POINTER
LDY #5
INY
LDA #$FF
STA (Z64),Y ;SET $4A06 = $FF
JMP JC345
; 'CHECKSUM'
;----------------------------------------
;SC344: COMPUTE BLOCK CHECKSUM
;----------------------------------------

;ENTRY: .A = $4804 (HANDSHAKE WORD INDEX)
;EXIT:  $4809 = # BYTES IN BLOCK
;       $4904 =     ''    ''   ???
;       CHECKSUM IN HEADER @ XX00-XX03

SC344 PHA ;SAVE INDEX

JC345 JSR CLRCHN ;I/O TO DEFAULTS
JSR SC59B ;ENABLE BYTE RECEPTION
JSR SC579 ;DELAY LOOP
JSR SC59B ;ENABLE BYTE RECEPTION
LDY #4
LDA (Z64),Y ;GET # OF BYTES IN BLOCK
STA XC809 ;SAVE
JSR SC371 ;SET $64/65 = $4900
PLA ;GET BUFFER POINTER
LDY #4
STA (Z64),Y ;SAVE AS # BYTES IN BLOCK
JSR SC380 ;COMPUTE BLOCK CHECKSUM
RTS
; 'SET $64/65'
;----------------------------------------
;SC364: SET $64/65 - ASCENDING
;----------------------------------------

;ENTRY: IF $4816 = 0, $64/65 = $4900
;            ''    1,   ''     $4A00

SC364 LDA #0
STA Z64
LDA XC816 ;POINTER OFFSET
CLC
ADC #$49 ;$4816 + $49 = $65
STA Z65
RTS

;----------------------------------------
;SC371: SET $64/65 - CHANGE BUFFER
;----------------------------------------

;ENTRY: IF $4816 = 0, $64/65 = $4A00
;             ''   1,    ''    $4900

SC371 LDA #0
STA Z64
LDA XC816 ;POINTER OFFSET
EOR #%00000001 ;CHANGE BUFFER
CLC
ADC #$49
STA Z65
RTS
; 'CHECKSUM 2'
;----------------------------------------
;SC380: COMPUTE BLOCK CHECKSUM
;----------------------------------------

;ENTRY: $4809 = # BYTES IN BLOCK
;EXIT:  $4814-C815 CONTAINS CHECKSUM
;       $4902-C903    ''       ''     ???

SC380 LDA #0
STA XC812 ;CHECKSUM 1 - SUM OF BYTES
STA XC813
STA XC814 ;CHECKSUM 2 - EOR OF BYTES
STA XC815
LDY #4 ;CHECKSUM FROM $4904 ON IN BLK
BC390 LDA XC812
CLC
ADC (Z64),Y
STA XC812
BCC BC39E
INC XC813
BC39E LDA XC814
EOR (Z64),Y
STA XC814
LDA XC815
ROL A ;$4815 CARRY -> BIT 0
ROL XC814 ;$4814 CARRY -> BIT 0
ROL XC815 ;$4815      ''
INY
CPY XC809 ;END OF BLOCK?
BNE BC390

LDY #0
LDA XC812 ;CHECKSUM 1 -> $4900/C901
STA (Z64),Y
INY
LDA XC813
STA (Z64),Y
INY
LDA XC814 ;CHECKSUM 2 -> $4902/C903
STA (Z64),Y
INY
LDA XC815
STA (Z64),Y
RTS
; 'TRANSMIT 2'
;========================================
;SC3D0: TRANSMIT 2 - BUFFER TO BBS
;========================================

;EXIT: $0200 = 0

SC3D0 LDA #0
STA XC80D ;FLAG: 1ST BLOCK?
STA XC80C ;DELAY COUNTER
STA XC81D ;SHORT BLK # BYTES ???
LDA #1
STA XC816 ;TRANSMIT BUFFER @ $4A00
LDA #$FF
STA XC819 ;SET FOR XMIT
STA XC81A
JSR SC371 ;SET $64/65 = $4900
LDY #4
LDA #7
STA (Z64),Y ;$4904 = 7 (# HEADER BYTES)
JSR SC364 ;SET $64/65 = $4A00
LDY #5
LDA #0
STA (Z64),Y ;$4A05 = 0 (# BLOCK BYTES-LO)
INY
STA (Z64),Y ;$4A06 = 0 (# BLOCK BYTES-HI)
BC3FD JSR SC1AC ;BLOCK(S) -> BBS ... ???
BEQ BC3FD
BC402 LDA #0
STA X0200 ;FLAG: END OF TRANSMISSION
RTS
; 'RECEIVE 2'
;========================================
;SC408: RECEIVE 2 - BUFFER TO DISK
;========================================

SC408 LDA #1
STA XC819 ;FLAG: RECEIVE ???
LDA #0
STA XC81A ;???
STA XC80D ;FLAG: 1ST BLOCK
STA XC816 ;RECEIVE BUFFER @ $4900
STA XC905 ;# BYTES IN BLOCK  ???
STA XC906 ;FLAG: $FF = SHORT BLK ???
STA XC80C ;DELAY COUNTER
LDA #7
STA XC904 ;7 BYTES IN HEADER
LDA #0
JC428 JSR SC13A ;BBS DATA -> BUFFER $4900 ???
LDA XC80D ;FLAG: 1ST BLOCK?
BNE BC402 ;YES, SET $0200 = 0 & EXIT
JSR SC484 ;BLOCK CHECKSUM OK?
BNE BC471

;BLOCK OK, SEND TO DISK
;
JSR CLRCHN ;I/O TO DEFAULTS
LDA XC809 ;# BYTES IN BLOCK
CMP #7 ;= 7 (JUST BLOCK HEADER)? ???
BEQ BC455
LDX #2
JSR CHKOUT ;NO, READY CH 2 FOR OUTPUT (DISK)
LDY #7
BC446 LDA XC900,Y ;$4907 TO $4907+$4809 -> DISK
JSR CHROUT
INY
CPY XC809
BNE BC446
JSR CLRCHN ;I/O TO DEFAULTS
;
;JUST "HEADER" OR SHORT BLOCK
;
BC455 LDA XC906
CMP #$FF ;SHORT BLOCK? ???
BNE BC464
LDA #1
STA XC80D ;FLAG: 1ST BLOCK
LDA #'*' ;PRINT "*"
.BYT $2C
BC464 LDA #'-' ;NO, PRINT "-"
JSR CHROUT
JSR SC59B ;ENABLE RS-232 BYTE RECEPTION
LDA #0 ;SEND "GOO"
JMP JC428 ;GET NEXT BLOCK

;BLOCK CHECKSUM BAD
;
BC471 JSR CLRCHN ;I/O TO DEFAULTS
LDA #':' ;PRINT ":"
JSR CHROUT
LDA XC817 ;# BYTES RECEIVED ???
STA XC904 ;SAVE IN BLOCK HEADER
LDA #3 ;SEND "BAD"
JMP JC428 ;TRY AGAIN
; 'CHECKSUM 3'
;----------------------------------------
;SC484: VERIFY CHECKSUM FOR BBS BLOCK
;----------------------------------------

;ENTRY: $4900-C903 = BBS BLOCK CHECKSUM
;EXIT:  IF .A = 0, CHECKSUM OK
;          ''   1, BAD CHECKSUM

SC484 LDA XC900 ;CHECKSUM 1 - SUM OF BYTES
STA XC80E
LDA XC901
STA XC80F
LDA XC902 ;CHECKSUM 2 - EOR OF BYTES
STA XC810
LDA XC903
STA XC811
JSR SC364 ;SET $64/65 = $4900  ???
LDA XC817 ;# BYTES IN BLOCK
STA XC809
JSR SC380 ;COMPUTE BLOCK CHECKSUM @ $4900 ???
LDA XC900 ;CHECKSUM OK?
CMP XC80E
BNE BC4CB
LDA XC901
CMP XC80F
BNE BC4CB
LDA XC902
CMP XC810
BNE BC4CB
LDA XC903
CMP XC811
BNE BC4CB
LDA #0 ;YES, SET .A = 0
RTS
BC4CB LDA #1 ;NO, SET .A = 1
RTS
; 'RECEIVE 1'
;========================================
;SC4CE: RECEIVE 1
;========================================

;EXIT: IF SHORT BLOCK, $0200 = 0

SC4CE LDA #0
STA XC819 ;SET FLAGS
STA XC81A
STA XC80D ;FLAG: 1ST BLOCK
STA XC816 ;$64/65 = $4900
STA XC80C ;DELAY COUNTER
LDA #7
CLC
ADC #1
STA XC904 ;# BYTES TO SEND = 8 (HEADER+1)
LDA #0 ;START HANDSHAKE = "GOO"

JC4E9 JSR SC13A ;SEND HANDSHAKE, GET DATA
LDA XC80D ;FLAG: 1ST BLOCK?
BNE BC511

JSR SC484 ;BLOCK CHECKSUM OK?
BNE BC506 ;NO
LDA XC907 ;1ST DATA BYTE OF BLOCK
STA XC81B ;= FILETYPE
LDA #1
STA XC80D ;FLAG: 1ST BLOCK?
LDA #0 ;SEND "GOO"
JMP JC4E9 ;GET NEXT BLOCK

;BLOCK CHECKSUM BAD
;
BC506 LDA XC817 ;# BYTES RECEIVED
STA XC904 ;SAVE IN HEADER
LDA #3 ;SEND "BAD"
JMP JC4E9 ;TRY AGAIN

;SHORT BLOCK ($480D <> 0)  ???
;
BC511 LDA #0 ;SET FLAG
STA X0200
RTS ;BACK TO BASIC
; 'TRANSMIT 1'
;========================================
;SC517: TRANSMIT 1
;========================================

;EXIT: IF TRANSMIT OK, THEN $0200 = 0

SC517 LDA #0
STA XC80D ;FLAG: 0 = 1ST BLOCK
STA XC80C ;SET DELAY COUNTER ???
LDA #1
STA XC816 ;SET $64/65 = $4A00
STA XC81D ;SET SHORT BLOCK FLAG ???
LDA #$FF
STA XC819 ;FLAG: TRANSMIT  ???
STA XC81A
JSR SC371 ;SET $64/65 = $4900
LDY #4
LDA #7
CLC
ADC #1
STA (Z64),Y ;$4904 = 8 (MIN # BYTES TO SEND)
JSR SC364 ;SET $64/65 = $4A00
LDY #5
LDA #$FF
STA (Z64),Y ;$4A05 = $FF
INY
STA (Z64),Y ;$4A06 = $FF
LDY #7
LDA XC81B ;FILE TYPE
STA (Z64),Y ;$4A07 = FILE TYPE (1-3)
LDA #1
STA XC81E ;FLAG: WAIT FOR BBS "SYN"
BC553 JSR SC1AC ;SEND BLOCK(S)
BEQ BC553
LDA #0
STA X0200 ;FLAG: ???
RTS ;BACK TO BASIC

;----------------------------------------
;SC55E: TRANSMIT - DELAY EXIT  ???
;----------------------------------------

SC55E INC XC80C ;SET @ 0 OR 1
LDA XC80C
CMP #3 ;< 3?
BCC BC574
LDA #0 ;NO, RESET
STA XC80C
LDA XC80B ;DELAY FLAG SET?
BEQ SC579 ;YES, DELAY & EXIT
BNE BC585 ;NO, JUST EXIT

BC574 LDA XC80B ;DELAY?
BEQ BC585 ;NO, QUIT
; 'MISC SUBS'
;----------------------------------------
;SC579: DELAY
;----------------------------------------

SC579 LDX #0 ;SET DELAY COUNTERS
BC57B LDY #0
BC57D INY
BNE BC57D
INX
CPX #$78
BNE BC57B
BC585 RTS

;----------------------------------------
;SC586: SEND BYTE   ???
;----------------------------------------

;ENTRY: .A = BYTE TO SENT
;EXIT:  .A =   ''    ''

SC586 PHA ;PRESERVE BYTE
LDA XC819 ;FLAG: $FF FOR XMIT ???
ORA XC81A
BEQ BC599 ;YES, EXIT
LDA XC80D ;FLAG: 1ST BLOCK
BNE BC599 ;YES,  EXIT
PLA
JSR CHROUT ;SEND BYTE
PHA
BC599 PLA ;RESTORE BYTE
RTS

;========================================
;SC59B: ENABLE RS-232 BYTE RECEPTION
;========================================

;ENTRY: DEVICE 2 (MODEM) MUST BE OPENED

SC59B JSR RS2SET ;ENABLE
LDA X02A1 ;CHECK FOR INTERRUPTS...
CMP #%10000000 ;NMI?
BEQ SC59B
CMP #%10010010 ;WAITING OR RECEIVING?
BEQ SC59B
RTS ;NONE OF THE ABOVE
; 'TERMINAL MODE'
;========================================
;SC5AA: TERMINAL MODE
;========================================

SC5AA JSR SC667 ;PRINT CRSR, CHECK CMDR KEY
BC5AD JSR SC0F1 ;GET RS-232 BYTE
LDA Z96 ;BYTE RECEIVED?
BNE BC5C8
LDA X0200 ;YES, GET BYTE
AND #%01111111 ;MAKE IT 7-BIT
STA X0200
CMP #8 ;ASCII DELETE?
BEQ BC5CB
CMP #13 ;ASCII C/R?
BEQ BC5CB
CMP #32 ;ASCII SPACE?
BPL BC5CB ;ANY OF THE ABOVE

BC5C8 JMP JC615 ;CHECK KEYBOARD

BC5CB CMP #$61 ;ASCII LOWERCASE ($61-7A)?
BCC BC5DC
CMP #$7B
BCS BC5DC
SEC ;YES, MAKE CBM LOWERCASE (-32)
SBC #32
STA X0200 ;SAVE
JMP JC5EA

BC5DC CMP #$41 ;ASCII UPPERCASE ($41-5A)?
BCC JC5EA
CMP #$5B
BCS JC5EA
CLC ;YES, MAKE CBM UPPERCASE (+128)
ADC #128
STA X0200 ;SAVE

JC5EA CMP #8 ;DELETE?
BNE BC5F3
LDA #20 ;YES, SAVE CBM DELETE
STA X0200
BC5F3 CMP #34 ;QUOTES?
BNE BC601
JSR CHROUT ;YES, PRINT QUOTES
LDA #20
JSR CHROUT ;+ DELETE
LDA #34 ;SAVE QUOTES
BC601 STA X0200
CMP #13 ;C/R?
BNE BC60F
LDA #32
JSR CHROUT ;YES, PRINT SPACE & C/R
LDA #13
BC60F JSR CHROUT ;PRINT CHAR
JSR SC667 ;PRINT CRSR, CMDR PRESSED?

;CHECK FOR KEYBOARD INPUT
;
JC615 JSR GETIN ;KEY PRESSED?
BEQ BC5AD ;NO, CHECK RS-232
STA X0200 ;YES, SAVE KEYBOARD CHAR
CMP #19 ;HOME?
BEQ BC666 ;YES, EXIT TO BASIC
CMP #$41 ;CBM LOWERCASE ($41-5A)?
BCC BC632
CMP #$5B
BCS BC632
CLC ;YES, MAKE ASCII LOWERCASE (+32)
ADC #32
STA X0200
JMP JC643

BC632 LDA X0200
CMP #$41 ;CBM UPPERCASE-2 ($41-DA)?
BCC JC643
CMP #$DB
BCS JC643
SEC ;YES, MAKE ASCII UPPERCASE (-128)
SBC #128
STA X0200

JC643 CMP #20 ;CBM DELETE?
BNE BC64C
LDA #8 ;YES, MAKE ASCII BS
STA X0200
BC64C CMP #83 ;CBM SHIFT/STOP?
BNE BC655
LDA #16 ;YES, MAKE ASCII CONTROL P
STA X0200
BC655 LDX #4 ; was 5 in C64 version
JSR CHKOUT ;READY RS-232 FOR OUTPUT
LDA X0200
JSR CHROUT ;SEND BYTE
JSR CLRCHN ;I/O TO DEFAULTS
JMP SC5AA ;BACK TO START...
BC666 RTS ;IF "HOME", EXIT TO BASIC
; 'CRSR & CMDR'
;----------------------------------------
;SC667: PRINT CRSR, CHECK IF CMDR PRESSED
;----------------------------------------

SC667 LDA #18
JSR CHROUT ;PRINT RVS ON
LDA #32
JSR CHROUT ;SPACE
LDA #157
JSR CHROUT ;CRSR LEFT
LDA #146
JSR CHROUT ;AND RVS OFF

;----------------------------------------
;SC67B: CHECK IF CMDR KEY PRESSED
;----------------------------------------

;EXIT: X0200 = 1 (EXIT TO TERMINAL MODE)

SC67B LDA X028D
CMP #2 ;CMDR PRESSED?
BNE BC689
BC682 PLA ;YES, POP STACK
TSX
CPX XC81C ;TILL BASIC ENTRY
BNE BC682
BC689 LDA #1 ;SET FLAG
STA X0200
RTS
;
; Move chrout vector if necessary
;
INIT
    LDA IBSOUT
    CMP #<NEWOUT
    BNE INIT1
    LDA IBSOUT + 1
    CMP #>NEWOUT
    BEQ INIT2
INIT1
    LDA IBSOUT
    STA OLDOUT
    LDA IBSOUT + 1
    STA OLDOUT + 1
    LDA #<NEWOUT
    STA IBSOUT
    LDA #>NEWOUT
    STA IBSOUT + 1
INIT2
    RTS

;
; new chrout routing to correct for 1200 baud speed problems
;
NEWOUT
    PHA
    LDA DEFTO
    CMP #$03
    BNE NEWOUT1
    PLA
    JMP (OLDOUT)
    ;
NEWOUT1
    BCC NEWOUT2
    PLA
    JMP (OLDOUT)
    ;
NEWOUT2
    LSR A
    PLA
    STA PTR1
    TXA
    PHA
    TYA
    PHA
    BCC NEWOUT9
    JSR BASIC1
    BNE NEWOUT5
    JSR BASIC2
    BCC NEWOUT7
    LDA #$02
    LDY #$00
    STA (TAPE1),y
    INY
    STY BUFPNTR
NEWOUT5
    LDA PTR1
    STA (TAPE1),y
NEWOUT6
    CLC
NEWOUT7
    PLA
    TAY
    PLA
    TXA
    LDA PTR1
    BCC NEWOUT8
    LDA #$00
NEWOUT8
    RTS
    ;
NEWOUT9
    JSR NEWOUT10
    JMP NEWOUT6
    ;
NEWOUT11
    JSR NEWOUT12
NEWOUT10
    LDY RODBE
    INY
    CPY RODBS
    BEQ NEWOUT11
    STY RODBE
    DEY
    LDA PTR1
    STA (ROBUF),y
    ;
NEWOUT12
    LDA X02A1
    LSR A
    BCS NEWOUT13
    LDA #$02
    ORA $9112
    STA $9112   ; Data direction register
    LDA XMIT
    STA $9114   ; VIA 1 Timer 1
    LDA XMIT + 1
    STA $9115
    LDA #$81
    JSR BASIC3
    ;JSR BASIC4
    LDA #$03
    ORA $9112
    STA $9112
NEWOUT13
    RTS