

*************************************
*   Xfer 6 Xmodem Transfer Module   *
*            Version 2.2            *
*                                   *
*          (C)opyright 1989         *
*           By Danny Haynes         *
*                                   *
* Published by SmokeSignal Software *
*                                   *
*************************************





FRETOP = $6F

STRLEN = $05
PTR = $06
PTR1 = $08
AREG = $0A
STATUS = $0B
YREG = $0C
INVRT = $32
A1L = $3C
A2L = $3E
A4L = $42
LINNUM = $50
STREND = $6D
VARPNT = $83
FORPNT = $85
LOWTR = $9B
TXTPTR = $B8
ERRFLG = $D8
ERRNUM = $DE
ERRLIN = $DA
CH = $24
CV = $25
COUT = $FDED
CHRGET = $B1
BAS = $28
CHRGOT = $B7
SPEAKER = $C030
INVERSE = $FE80
NORMAL = $FE84
MLI = $BF00

INTRP = $0300
OH = $0301
CARRIER = $0302
SLOTN = $0303
BAUD = $0304
KPAUSE = $030B
KABORT = $030C
NEXT = $030D

TBUFF = $0320
LOWCAS = $0321
LASTCHR = $0322
MODEMON = $0323
SCRNON = $0324
LINFD = $0325
SLOT = $0326
MDMCASE = $0327

NULLS = $0338
OUTMASK = $0339
MSKCHR = $033A

TBUFF1 = $033B
UPDWN = $033D
CHTFLG = $033E
BLOCK = $033F
PRVFLG = $0341
PRTCLL = $0342
JSTFLG = $0343
TYPE1 = $034A
IOERR = $034B
RREG = $0359
MCHR = $033C

EQUAL = 208
CHKSTR = $DD6C

BASIC = $D7D2 ;EXECUTE A NEW STATEMENT
PTRGET = $DFE3
FRMEVL = $DD7B
GETADR = $E752
ERROR = $D412
FRMNUM = $DD67
GETARYPT = $F7D9
FOUT = $ED34
SYNERR = $DEC9

GETBYT = $E6F8

KEY = $C000
VALTYP = $11
STRLIT = $E3E7
SCRN = $07D0
FREFAC = $E600
INDEX = $5E
CURLIN = $75
HOME = $FC58
TABV = $FB5B
MOVAF = $EB63
FMULTT = $E982
GIVAYF = $E2F2
FADDT = $E7C1
SGNFLT = $E301
ATIME = $030E
MUL10 = $EA39
MOVMF = $EB2B
FADD = $E7BE
LET1 = $DA5B
CHKNUM = $DD6A
FLOAT = $EB93
SAVREG = $FF4A
RESTORE = $FF3F

MACHID = $BF98
ID = $0353
MEM = $0354
COLUMN = $0355
CLOCK = $0356

SAMPER = $035E
BIN2 = $03E4
TSTMDM = $7200
POUT = TSTMDM+2
MOUT = POUT+2
MOUT1 = MOUT+2
MINP = MOUT1+2
PUSH = MINP+2

********************************
*                              *
* UPDWN     $033D (829)        *
*     0 = UPLOAD               *
*     1 = DOWNLOAD             *
*                              *
* PRTCLL    $0342 (834)        *
*     1 = ProDOS Xmodem        *
*     2 = DOS 3.3 Xmodem       *
*     3 = CRC-16 Xmodem        *
*     4 = Standard Chksum      *
*                              *
* BLOCKS    $033F (831)        *
*     TWO BYTES USED.          *
*     RETURNS THE TOTAL NUMBER *
*     OF BLOCKS SENT/RECEIVED. *
*                              *
* TYPE1     $034A (842)        *
*    THE TYPE OF FILE SENT     *
*    OR RECEIVED.              *
*                              *
* IOERR     $034B (843)        *
*    I/O ERROR STATUS          *
*      0 = ALL OK              *
*      1 = DISK ERROR          *
*      2 =                     *
*      3 = TIME OUT            *
*      4 = ABORTED             *
*      5 =                     *
*                              *
* BIN2      $03E4 (996)        *
*     Flags BIN ][ Download    *
*          0 = Normal          *
*        256 = Send Bin ][     *
*                              *
********************************


********************************
*                              *
*     PROGRAM STARTS HERE      *
*                              *
********************************

 ORG $0900


BEGIN JMP MAKBAS
 JMP UPLOAD



* SET THE PROGRAM END POINTERS


BASEND = $AF

MAKBAS LDY #>PRGEND ;SET THE BASIC PROGRAM POINTERS
 LDA #PRGEND ;FOR THE END OF THIS PROGRAM
 STA BASEND
 STY BASEND+1
 RTS
CRCFLG DFB 0
FIRFLG DFB 0
MFLAG DFB 0
CHAR DFB 0
FINISH DFB 0
TMPTXT DA 0
BLKCNT DFB 0
BLK1 DFB 0
AEFLG DFB 0
DOS3_3 DFB 0
BLK0 DFB 0
OFFSET DFB 0
PRMS33 DA 0,0
BIGBLK DA 0
SREG DFB 0

BATCH DFB 0
KEY1 DFB 0
FIRST DA 0,0
TRYS DA 0
ERR DFB 0
TERR DFB 0
DELREG DA 0,0
CRC DFB 0
EXP DFB 0
GS DFB 0
 DS \

********************************
*                              *
*    Upload / Receive a File   *
*                              *
********************************

UPLOAD LDA #$00
 LDX #FIRFLG
:CLEAR STA BEGIN,X
 INX
 BNE :CLEAR
 TSX
 STX SREG
 LDA #00
 STA CRCFLG
 LDA #>NAMBUF ;SEND THE FILE INFO BLOCK
 STA FILINFO+2
 LDA #NAMBUF
 STA FILINFO+1
 LDX #$00
:LOOP1 LDA $6800,X
 STA NAMBUF,X
 INX
 BNE :LOOP1
 LDA #$04
 STA RDPRM
 LDA UPDWN
 BEQ :NEXT
 JMP DOWNLD
:NEXT JSR OPENFIL
 BCC :FETCH
 LDA #$01
 STA IOERR
 JMP OKCLOS
:FETCH LDA REFNUM
 STA FILREF
 JSR DOSCRN ;SET UP SCREEN
 LDA #$FF
 STA BLK1
 LDA #$00
 STA BIN2
:MORE? JSR SETBUF ;SET PTR AND BUFFER COUNT
:LOOP JSR GETBLK ;GET THE BLOCK OF DATA
 BCC :WRITE1
 LDA FINISH
 BNE :WRITE1
 LDA BLKCNT
 BNE :LOOP
:WRITE1 JSR SETBAT
 LDA #$04
 STA RDPRM
 JSR MLI
 DFB $CB ;WRITE
 DA RDPRM
 BCS :LL1
 LDA #$01
 STA RDPRM
 JSR MLI
 DFB $CD ;FLUSH
 DA RDPRM
 BCS :LL1
 LDA FINISH
 BEQ :MORE?
 BNE :CLOSE
:LL1 LDA #$01
 STA IOERR
:CLOSE JSR SETEOF
 JSR CLOSE
 BCS BADDSK
 JSR SETPRM
 BCC OKCLOS
BADDSK LDA #$01
 STA IOERR
 LDA #$04
 JSR SEND
 JSR GETINP

OKCLOS LDA IOERR
 JMP RETBAS

CLOSE LDA #$01
 STA RDPRM
 JSR MLI ;CLOSE OUT THE FILE
 DFB $CC
 DA RDPRM
 RTS

SETPRM LDA AEFLG
 BNE :NEXT
 RTS
:NEXT LDA DOS3_3
 BEQ :DOPRO
 JMP SET33PM
:DOPRO LDX #$03
:LOOP LDA BUFNAM+3,X
 STA DACCES,X
 DEX
 BPL :LOOP
 LDX #$03
:LOOP1 LDA BUFNAM+14,X
 STA MTIME,X
 DEX
 BPL :LOOP1
SETINFO JSR MLI
 DFB $C3
 DA FILINFO
 RTS

SET33PM LDA TYPE1
 AND #$7F
 LDX #$06
:LOOP CMP DOSTYP,X
 BEQ :FND
 DEX
 BPL :LOOP
 LDA #$04
 BNE :STUFF
:FND LDA PROTBL,X
:STUFF STA TYPE1
 STA FILTYE
 LDA #$E3
 STA DACCES
 JMP SETINFO

CATCH1 LDA PTR ;MOVE THE POINTER TO
 STA TPTR1 ;POINT AT THE SPECIAL BLOCK
 LDA PTR+1 ;WHERE WE STORE THE DATA
 STA TPTR1+1
 LDA #>BIN2BLK
 STA PTR+1
 LDA #BIN2BLK
 STA PTR
 JSR FTCHBLK ;GO FETCH A BLOCK AND THE CHKSUM
 LDA FIRST+1
 EOR #$FF
 CMP FIRST
 BNE :MAKNAK
 LDA CHKSUM
 CMP FIRST+2
 BEQ :CKCRC ;GO SEE IF THIS IS CRC
 JMP :MAKNAK ;GO NAK AND IT TRY AGAIN
:CKCRC LDA CRC
 BEQ :ISBIN2? ;GO CHECK FOR BIN //
 LDA CHKSUM+1
 CMP FIRST+3
 BEQ :ISBIN2? ;GO CHECK BIN //
 JMP :MAKNAK
:ISBIN2? LDA BIN2BLK
 CMP #$0A
 BNE :NOTBIN2
 LDA BIN2BLK+1
 CMP #$47
 BNE :NOTBIN2
 LDA BIN2BLK+2
 CMP #$4C
 BNE :NOTBIN2
 LDA BIN2BLK+18
 CMP #$02
 BNE :NOTBIN2
 LDA BIN2BLK+127
 BNE :NOTBIN2 ;Put batch's in BIN // File
 JMP :DOBIN2
:MAKNAK LDA #21
 STA CHAR
 LDA TPTR1
 STA PTR
 LDA TPTR1+1
 STA PTR+1
 JMP AGAIN
:NOTBIN2 LDA BIN2BLK+32
 CMP #$1D
 BNE :NOTGS
 LDY #$12
:LOOP3 LDA BIN2BLK+33,Y
 STA BIN2BLK+3,Y
 DEY
 BNE :LOOP3
 LDA #$FF
 STA GS
 JMP :DOBIN2
:NOTGS LDA #$00
 STA BLK1
 LDA TPTR1
 STA PTR
 LDA TPTR1+1
 STA PTR+1
 LDA #21
 STA CHAR
 JMP AGAIN
:DOBIN2 LDA BIN2BLK+4
 STA TYPE1
 LDA #$07
 STA BIN2BLK
 LDA #>NAMBUF
 STA BIN2BLK+2
 LDA #NAMBUF
 STA BIN2BLK+1
 LDA #$E3
 STA BIN2BLK+3
 JSR MLI
 DFB $C3
 DA BIN2BLK
 BCS :DSKERR
 LDA TPTR1
 STA PTR
 LDA TPTR1+1
 STA PTR+1
 LDA #$00
 STA BLK1
 STA TRYS+1
 STA AEFLG
 LDA #$FF
 STA BLK0
 STA BIN2
 LDA #$06
 STA CHAR
 INC BLOCK
 BNE :NOCARRY
 INC BLOCK+1
:NOCARRY SEC
 RTS
:DSKERR LDA #$01
 JMP CANCEL

OPENFIL JSR MLI ;GET TIME
 DFB $82
 DA $0000
 LDX #$03
:LL1 LDA $BF90,X
 STA TIME,X
 DEX
 BPL :LL1
 JSR MLI ;CREATE THE FILE
 DFB $C0
 DA CRTPRM
 BCC DOOPEN
 LDA #$02
 JMP CANCEL

DOOPEN JSR MLI
 DFB $C8 ;OPEN
 DA OPNPRM
 RTS

CANCEL STA IOERR
 LDA #$04 ;ABORT THE TRANSMISSION
 JSR SEND
 LDA #$18
 JSR SEND
 LDA #$18
 JSR SEND
 JSR CLOSE
RETBAS LDA #$00
 STA TBUFF
 STA TBUFF1
 STA CRCFLG
 LDX SREG
 TXS
 RTS

FILINFO DFB $07
 DA NAMBUF
DACCES DFB $E3
FILTYE DFB $04
AUXTYP DA 0
 DFB 0,0,0 ;NOT USED
MTIME DA 0,0 ;DATE MODIFIED
 DA 0,0 ;DATE CREATED

EOFPRM DFB $02
 DFB 0
EOF DFB 0,0,0 ;EOF

SETEOF LDA DOS3_3
 BNE :NEXT
 LDA AEFLG
 BEQ :DONE
 JMP SETPRO
:DONE LDA BIN2
 BEQ :DONE1
 JSR EXPEOF
 RTS
:DONE1 CLC
 RTS
:NEXT LDA #$06
 JSR SEND ;ACK END OF FILE
 LDA TYPE1
 BEQ :DONE ;TEXT FILE
 CMP #$01 ;INTEGER?
 BEQ :DO2
 CMP #$02 ;BASIC?
 BEQ :DO2
 LDA PRMS33
 STA AUXTYP
 LDA PRMS33+1
 STA AUXTYP+1
 LDA PRMS33+2
 STA EOF
 LDA PRMS33+3
 STA EOF+1
 JMP :COREOF
:DO2 LDA PRMS33
 STA EOF
 LDA PRMS33+1
 STA EOF+1
 LDA #$08 ;SET FOR BEGINNING POSITION
 STA AUXTYP+1
 LDA #$01
 STA AUXTYP
:COREOF LDA REFNUM
 STA EOFPRM+1
 JSR MLI ;SET EOF ON THE FILE
 DFB $D0
 DA EOFPRM
 RTS

SETPRO LDX #$02
:LOOP LDA BUFNAM+20,X
 STA EOF,X
 DEX
 BPL :LOOP
 LDA REFNUM
 STA EOFPRM+1
 JSR MLI
 DFB $D0
 DA EOFPRM
 RTS

RDPRM DFB $04
FILREF DFB 0
DSKBUF DA MSGBUF
REQLEN DA 0
ACTLEN DA 0

OPNPRM DFB $03
 DA NAMBUF
 DA $6800
REFNUM DFB 0

CRTPRM DFB $07
 DA NAMBUF
 DFB $E3 ;ACCESS BITS
 DFB $04 ;TEXT FILE TYPE
 DA $0000 ;AUX TYPE
 DFB $01 ;STORAGE TYPE
TIME DA 0 ;DATE
 DA 0 ;TIME
 DA 0,0,0

SETBUF LDY #>MSGBUF ;INITIALIZE BUFFERS
 LDA #MSGBUF
 STY DSKBUF+1
 STA DSKBUF
 STY PTR+1
 STA PTR
 LDA #$20
 STA BLKCNT
 LDA #$00
 STA REQLEN
 LDA UPDWN
 BEQ :SAVE
 LDA #$10
:SAVE STA REQLEN+1
 RTS

* IF DOS 3_3 FILE, SAVE PARMS!


SETBAT LDA BATCH
 BEQ :NEXT
 RTS
:NEXT LDA DOS3_3
 BNE :SETPRMS
:TEXT RTS
:SETPRMS LDA #$FF
 STA BATCH
 LDA TYPE1
 CMP #$01 ;INTEGER
 BEQ :DO2
 CMP #$02 ;APPLESOFT
 BEQ :DO2
 CMP #$04 ;BINARY
 BNE :TEXT
 LDX #$03 ;SET FOR 4 BYTES
 LDA #$04
 BNE :LOOP1
:DO2 LDX #$01 SET FOR 2 BYTES
 LDA #$02
:LOOP1 STA OFFSET
:LOOP LDA MSGBUF,X
 STA PRMS33,X
 DEX
 BPL :LOOP
 LDA DSKBUF ;ADJUST REAL FILE BUFFER START
 CLC
 ADC OFFSET
 STA DSKBUF
 LDA DSKBUF+1
 ADC #$00
 STA DSKBUF+1
 LDA REQLEN
 SEC
 SBC OFFSET
 STA REQLEN
 LDA REQLEN+1
 SBC #$00
 STA REQLEN+1
 RTS


EVLFRST JSR GETINP ;GET FIRST FILE TYPE BYTE
 BCS :NOTOK
 STA FIRST
 JSR GETINP ;GET SECOND FILE TYPE BYTE
 BCS :NOTOK
 STA FIRST+1
 EOR #$FF
 CMP FIRST
 BEQ :OK
:NOTOK LDA #$FF
 STA BLK0
 LDA PRTCLL
 CMP #$03
 BGE :NOTAEOK
 LDA #$95
 STA CHAR
 JSR SEND
:NOTAEOK LDA #21
 STA CHAR
 JMP GETBLK
:OK LDA #$FF
 STA AEFLG
 STA BLK0
 LDA #$00
 STA EXP
 STA BLK1
 LDA FIRST
 STA TYPE1
 LDA PRTCLL
 CMP #$02 ;IS IT DOS 3.3?
 BNE :NOT3_3 ;NOPE!
 LDA #$FF ;YES! SET FLAG!
 STA DOS3_3
:NOT3_3 LDA #$06
 STA CHAR

GETBLK LDA BLK0
 BNE :NEXT
 LDA #00
 STA CRCFLG
 JMP AGAIN
:NEXT LDA #10 ;WAIT FOR SOH TO BEGIN
 STA TRYS
 LDA #$00
 STA ERR
AGAIN JSR UPDATE
 LDA CHAR ;SEND OUT A NAK OR ACK
 BEQ FETCH
 JSR SEND
FETCH JSR GETINP
 STA KEY1
 BCC :TEST
:TIMOUT LDA CRC
 BEQ :TIME
 LDA ERR
 CMP #30
 BGE :TIME
 INC CRCFLG
 LDA CRCFLG
 CMP #$06
 BLT :TIME
 LDA #21 ;^U
 STA CHAR
 LDA #$00
 STA CRC
:TIME JSR SETERR
 BNE AGAIN
 LDA BLK0
 BNE :OUT
 LDA #$03
 STA IOERR
 JMP CANCEL
:OUT SEC
 RTS
:TEST CMP #$04
 BEQ :DONE
 CMP #$01
 BEQ SETSIZ
 CMP #$02
 BEQ SETSIZ
 CMP #$18
 BNE :CKAE
 LDA #$04
 STA IOERR
 JMP CLOSE
:CKAE CMP #$81
 BNE :MM
 LDA BLK0
 BNE :MM
 JMP EVLFRST
:MM LDA DELREG+1
 BEQ FETCH ;DON'T COUNT UNLESS TIMED OUT
 SEC
 RTS
:SOHERR JSR SETERR
 JMP AGAIN
:DONE LDA #$FF
 STA FINISH
 LDA AEFLG
 BNE :GAE
 LDA #$06
 JSR SEND
 SEC
 RTS
:GAE LDA DOS3_3
 BEQ :REST
 SEC
 RTS
:REST LDA #>BUFNAM
 STA PTR+1
 LDA #BUFNAM
 STA PTR
 LDA #$06
 JSR SEND
 LDA #$16
 JSR SEND
 JSR GETINP
 BCS :DOS33
 LDA #21
 STA CHAR
 JSR GETBLK
 BCS :DOS33
 LDA #$06
 JSR SEND
 LDA BUFNAM+4
 STA TYPE1
:LLOP1 JSR GETINP
 SEC
 RTS
:DOS33 LDA #$FF
 STA DOS3_3
 SEC
 RTS

SETSIZ CMP #01 ;Is it 128 bytes?
 BNE :GOBIG ;Nope
 LDA #$01 ;Hex 24
 STA TOTACC+1
 LDA #$28
 STA TOTACC
 LDA #80
 STA BIGBLK
 LDA #$00
 STA BIGBLK+1
 JMP BLKSUM
:GOBIG LDA #$10
 STA TOTACC+1
 LDA #$24
 STA TOTACC
 LDA #$04
 STA BIGBLK+1
 LDA #$00
 STA BIGBLK

BLKSUM LDA #$FF
 STA BLK0
 JSR GETINP ;GET THE BLOCK HEADER
 BCS :ERROR
 LDA TBUFF1 ;GET NORMAL BLOCK NUMBER
 STA FIRST
 JSR GETINP
 BCS :ERROR
 LDA TBUFF1
 STA FIRST+1 ;GET EOR BLOCK NUMBER
 LDA BLK1
 BNE :GOSPCL
 JMP FTCHBLK
:GOSPCL JMP CATCH1
:ERROR JSR SETERR ;HEADER ERROR
 LDA #21
 STA CHAR
 JMP AGAIN

FTCHBLK LDA #$00 ;GET 128 BYTES AND CHKSUM
 STA AREG
 STA TRYS+1
:LOOP JSR GETINP
 BCC :L1
 LDA BLK0
 BNE :BAD
 LDA FIRST+1
 CMP #$FF
 BNE :BAD
 LDA FIRST
 BNE :BAD
 LDA #$06
 STA CHAR
 LDA #$FF
 STA BLK0
 STA AEFLG
 LDA #$00
 STA TRYS+1
 JMP GETBLK
:BAD LDA #21
 STA CHAR
 JMP AGAIN
:L1 LDY AREG
 LDA TBUFF1
 STA (PTR),Y
 INC AREG
 LDA AREG
 CMP #$80 ;CHECK TO SEE IF 128
 BNE :LOOP
 JSR GETINP ;GET THE CHECK SUM
 BCS :BAD
 LDA TBUFF1
 STA FIRST+2
 LDA CRC
 BEQ :DOCHK
 JSR GETINP
 BCS :BAD
 LDA TBUFF1
 STA FIRST+3
:DOCHK LDY #$7F
 LDA #$00
 STA CHKSUM
 STA CHKSUM+1
:CALCRC LDA CRC
 BEQ :LOOP1
 LDY #00
:CRC1 LDA (PTR),Y
 JSR :MAKCRC
 INY
 CPY #$80
 BNE :CRC1
 JMP :CRCIN
:MAKCRC STA HOLDCRC
 LDA #00
 LDX #08
:CRC2 ASL HOLDCRC
 ROR A
 AND #$80
 EOR CHKSUM
 ASL CHKSUM+1
 ROL A
 BCC :CRC3
 PHA
 LDA CHKSUM+1
 EOR #$21
 STA CHKSUM+1
 PLA
 EOR #$10
:CRC3 STA CHKSUM
 DEX
 BNE :CRC2
 RTS
:LOOP1 CLC ;DO CHECK SUM
 LDA (PTR),Y
 ADC CHKSUM
 STA CHKSUM
 LDA CHKSUM+1
 ADC #$00
 STA CHKSUM+1
 DEY
 BPL :LOOP1
:CRCIN LDA BLK1
 BEQ :CRCIN2
 RTS
:CRCIN2 LDA CHKSUM
 CMP FIRST+2
 BEQ :ISCRC?
:NOCHK JMP :BAD
:ISCRC? LDA CRC
 BEQ :OK
 LDA CHKSUM+1
 CMP FIRST+3
 BNE :NOCHK
:OK LDA FIRST+1 ;CHECK BLOCK HEADER
 EOR #$FF
 CMP FIRST
 BNE :NOCHK
 LDA #$06 ;SEND ACK
 STA CHAR
 LDA #$FF
 STA BLK0
 LDA #$00
 STA TRYS+1
 LDA FINISH
 BNE :LAST
 LDA REQLEN
 CLC
 ADC #$80
 STA REQLEN
 LDA REQLEN+1
 ADC #$00
 STA REQLEN+1
 INC BLOCK
 BNE :NOCARRY
 INC BLOCK+1
:NOCARRY LDA PTR
 CLC
 ADC #$80
 STA PTR
 LDA PTR+1
 ADC #$00
 STA PTR+1
 DEC BLKCNT
 SEC
 RTS
:LAST CLC
 RTS

UPDATE LDY #4
 LDA KEY1
 JSR SET
 LDY #13
 LDA FIRST
 JSR SET
 LDY #15
 LDA FIRST+1
 JSR SET
 LDY #25
 LDA CHKSUM
 JSR SET
 LDY #26
 LDA CHKSUM+1
 JSR SET
 LDY #36
 LDA TOTACC
 JSR SET
 LDA TOTACC+1
 JSR SET
 LDX #11
 LDA ERR
 LDY #$00
 JSR PRTNUM
 LDX #12
 LDY #$00
 LDA TERR
 JSR PRTNUM
 LDA BLOCK
 LDY BLOCK+1
 LDX #13
 JSR PRTNUM
 LDA #10
 JSR TABV
 JSR SNCR
 LDA BIN2
 BEQ :ISGS
 LDA #19
 STA CH
 LDY #>EXT1
 LDA #EXT1
 JMP PRINT
:ISGS LDA GS
 BEQ :ISPDOS
 LDA #19
 STA CH
 LDY #>EXT2
 LDA #EXT2
 JMP PRINT
:ISPDOS LDA AEFLG
 BEQ :NOTHING
 LDA DOS3_3
 BNE :NOTHING
 LDA #19
 STA CH
 LDY #>EXT3
 LDA #EXT3
 JMP PRINT
:NOTHING LDA #19
 STA CH
 LDY #>EXT0
 LDA #EXT0
 JMP PRINT
:GOBYE RTS


SCNUD DB 0
HOLDCRC DB 0
CHKSUM DA 0
TOTACC DA 0

PRTNUM STA ACC
 STY ACC+1
 TXA
 JSR VTAB
 JSR ITOC
 LDA #19
 STA CH
 LDY #$00
:LOOP LDA TMPSTR,Y
 BEQ :END
 ORA #$80
 BIT $0321
 BPL :NOCHNG
 CMP #"a"
 BLT :NOCHNG
 SEC
 SBC #$20
:NOCHNG JSR COUT
 INY
 BNE :LOOP
:END JSR :SPC1
:SPC1 JSR :SPC
:SPC LDA #" "
 JMP COUT

ATEMP DFB 0
YTEMP DFB 0

SET STA ATEMP
 STY YTEMP
 JSR POS
 LDY YTEMP
 STY CH
 LDA ATEMP
 JMP $FDDA

SEND STA MCHR
 LDY OH
 BEQ :NOSEND
 JMP MOUT1HK
:NOSEND RTS

GETINP LDA #$FF
 STA DELREG
 LDA #$FF
 STA DELREG+1
:LOOP LDY OH
 BNE :GETMDM
 LDA KEY
 BPL :DODELAY
 STA KEY+$10
 AND #$7F
 STA TBUFF1
 STA TBUFF
 JSR PUSHINP
 JMP :END
:GETMDM JSR MINPHK
 BCS :END
:DODELAY DEC DELREG
 BNE :LOOP
 DEC DELREG+1
 BNE :LOOP
 SEC
 RTS
:END LDA TBUFF1
 CLC
 RTS

SETERR LDA BLK0
 BNE :INC
 INC ERR
 DEC TRYS
 RTS
:INC INC ERR
 INC TERR
 DEC TRYS
 RTS


DOCR2 JSR DOCR
DOCR LDA #$0D
 JMP SEND

DOSCRN JSR HOME
 LDA #17
 JSR TABV
 JSR SNCR
 LDX #40
:LOOP LDA #$20
 JSR COUT
 DEX
 BNE :LOOP
 JSR POS
 LDY #>MSG0
 LDA #MSG0
 JSR PRINT
 LDA #04
 JSR TABV
 JSR SNCR
 LDY #>TITLE1
 LDA #TITLE1
 JSR PRINT
 LDA #06
 JSR TABV
 JSR SNCR
 LDY #>LINE1
 LDA #LINE1
 JSR PRINT
 LDA UPDWN
 BNE :L0
 LDY #>MOD1
 LDA #MOD1
 JSR PRINT
 JMP :LL0
:L0 LDY #>MOD2
 LDA #MOD2
 JSR PRINT
:LL0 LDY #>LINE2
 LDA #LINE2
 JSR PRINT
 LDA PRTCLL
 CMP #$01 ;ProDOS XMODEM
 BNE :L2
 LDY #>FORM1
 LDA #FORM1
 JSR PRINT
 JMP :LL1
:L2 CMP #$02 ;DOS 3.3 XMODEM
 BNE :L3
 LDY #>FORM2
 LDA #FORM2
 JSR PRINT
 JMP :LL1
:L3 CMP #$03 ;CRC XMODEM
 BNE :L4
 LDY #>FORM3
 LDA #FORM3
 JSR PRINT
 JMP :LL1
:L4 LDY #>FORM4 ;Checksum / Standard Xmodem
 LDA #FORM4
 JSR PRINT
:LL1 LDY #>LINE3
 LDA #LINE3
 JSR PRINT
 LDY #>NAMBUF+1
 LDA #NAMBUF+1
 JSR PRINT
 LDA #$8D
 JSR COUT
:LLL1 LDA #11
 JSR TABV
 LDY #>LINE8
 LDA #LINE8
 JSR PRINT
 LDY #>LINE4
 LDA #LINE4
 JSR PRINT
 LDY #>LINE5
 LDA #LINE5
 JSR PRINT
 LDA UPDWN
 BEQ :UP
 LDY #>LINE7 ;SENDING BLOCK
 LDA #LINE7
 JSR PRINT
 JMP :UP1
:UP LDY #>LINE6 ;RECIEVING BLOCK
 LDA #LINE6
 JSR PRINT
:UP1 LDA #16
 JSR TABV
 JSR DOCR2
 LDA UPDWN
 BEQ :NEXT
 LDY #>SMS1 ;READY TO SEND
 LDA #SMS1
 JMP :PRINT
:NEXT LDY #>SMS0 ;READY TO RECEIVE
 LDA #SMS0
:PRINT STA PTR
 STY PTR+1
 LDY #$00
:LOOP1 LDA (PTR),Y
 BEQ :END
 JSR POUTHK
 INY
 BNE :LOOP1
:END LDA #$01 ;INITIALIZE
 STA BLOCK
 LDA #$00
 STA BLOCK+1
 STA FINISH
 STA BLK0
 LDA PRTCLL
 CMP #$03
 BNE :NOTCRC
 LDA #'C'
 STA CHAR
 LDA #$FF
 STA CRC
 JMP SETBUF
:NOTCRC LDA #21
 STA CHAR
 JMP SETBUF

TITLE1 ASC '   ***    PRIME XFER 6   [2.20]    ***',00

LINE1 ASC "Mode...............",00
LINE2 ASC "Protocol...........",00
LINE3 ASC "File Name..........",00
LINE4 ASC "Errors this block..0",8D,00
LINE5 ASC "Total Errors.......0",8D,00
LINE6 ASC "Receiving Block....1",8D,8D,00
LINE7 ASC "Sending Block......1",8D,8D,00
LINE8 ASC "Extensions.........",8D,00
MSG0 ASC "SOH:00   "
 ASC "BLK:0000   "
 ASC "CHK:0000   "
 ASC "SIZ:0000",00

SMS0 ASC "Xfer 6: Begin Transmission Now",0D,0D,00
SMS1 ASC "Xfer 6: Ready To Send...",0D,0D,00

EXT0 ASC "       ",00
EXT1 ASC "BIN // ",00
EXT2 ASC "PROTERM",00
EXT3 ASC "ProDOS ",00

MOD1 ASC "Receiving File",8D,00
MOD2 ASC "Sending File",8D,00

FORM1 ASC "ProDOS Xmodem",8D,00
FORM2 ASC "DOS 3.3 Xmodem",8D,00
FORM3 ASC "CRC-16 Xmodem",8D,00
FORM4 ASC "Standard Xmodem",8D,00
FORM5 ASC "Y-Modem",8D,00

POS LDA #19
VTAB JSR TABV
SNCR LDA #$8D
 JMP COUT

PRINT STY PTR1+1
 STA PTR1
 LDY #$00
:LOOP LDA (PTR1),Y
 BEQ :END
 ORA #$80
 BIT $0321
 BPL :OK
 CMP #"a"
 BLT :OK
 SEC
 SBC #$20
:OK JSR COUT
 INY
 BNE :LOOP
:END RTS


ITOC LDY #$00
 LDX #$04
 STX STARTFLG
NXDIGIT LDA #"0"
 STA DIGIT
SUBTRCT LDA ACC
 CMP NUMLOW,X
 LDA ACC+1
 SBC NUMHI,X
 BCC GETDIG
 STA ACC+1
 LDA ACC
 SBC NUMLOW,X
 STA ACC
 INC DIGIT
 BNE SUBTRCT
GETDIG LDA DIGIT
 INX
 DEX
 BEQ STRNUM
 CMP #"0"
 BEQ CHKFLGS
 STA STARTFLG
CHKFLGS BIT STARTFLG
 BMI STRNUM
 LDA JUSTIFY
 BEQ NXTX
STRNUM STA TMPSTR,Y
 INY ;BE DELETED.
NXTX DEX
 BPL NXDIGIT
 LDA #$00
 STA TMPSTR,Y
 RTS

DIGIT DFB 0
STARTFLG DFB 0
JUSTIFY DFB 0

NUMLOW DFB 1
 DFB 10
 DFB 100
 DFB 1000
 DFB 10000

NUMHI DFB >1
 DFB >10
 DFB >100
 DFB >1000
 DFB >10000

TMPSTR ASC '12345'
 DFB 0

CASE AND #$7F
 CMP #'a'
 BLT CASE1
 CMP #'z'+1
 BGE CASE1
 SEC
 SBC #$20
CASE1 RTS

EXPEOF LDX #$02
:LOOP LDA BIN2BLK+20,X
 STA EOF,X
 DEX
 BPL :LOOP
 LDA REFNUM
 STA EOFPRM+1
 JSR MLI
 DFB $D0
 DA EOFPRM
 RTS

********************************
*                              *
*    DOWNLOAD / SEND  FILE     *
*                              *
********************************

INIT LDA #$01
 STA BLOCK
 STA FIRST
 STA KEY1
 LDA #$00
 STA BLOCK+1
 STA FIRST+1
 RTS

DOWNLD LDA #$00
 STA FINISH
 STA FIRFLG
 LDA #$0A
 STA FILINFO
 JSR MLI ;GET FILE INFORMATION
 DFB $C4
 DA FILINFO
 BCC :L1
:ERROR LDA #$01
 STA IOERR
 JMP OKCLOS
:L1 JSR DOOPEN
 BCS :ERROR
 LDA REFNUM
 STA FILREF
 STA EOFPRM+1
 STA BREF
 JSR MLI ;GET EOF LENGTH
 DFB $D1
 DA EOFPRM
 BCS :ERROR
 JSR INIT ;INITIALIZE
 JSR DOSCRN ;SET UP SCREEN
 JSR DOINIT
 JSR INIT
 JSR MAKSPBK
 JSR CKBIN2
 JMP :READ0
:READ1 JSR SETBUF
:READ0 JSR MLI ;NOW READ THE DATA IN
 DFB $CA
 DA RDPRM
 BCC :MORE?
 LDA #$01
 STA IOERR
 JMP :CLOSE
:MORE? LDA ACTLEN+1 ;IS IT FINISHED WITH THE FILE?
 CMP #$10
 BEQ :MORE2
 LDA FIR33
 BNE :NOT1
 LDA FILTYE
 BEQ :NOT1
 LDA ACTLEN+1
 CMP #$0F
 BLT :NOT1
 LDA ACTLEN
 CLC
 ADC ACCREG
 BCS :MORE2
:NOT1 LDA #$FF ;ALL OF THE FILE HAS BEEN READ NOW!
 STA FINISH
 LDA ACTLEN+1 ;CHECK TO MAKE SURE THERE IS DATA
 BNE :MORE1
 LDA ACTLEN
 BNE :MORE1
 JMP :CLOSE
:MORE2 LDA #$FF
 STA FIRFLG
 LDA #32
 BNE :STABLK
:MORE1 LDA ACTLEN+1 ;CALC BUFFER COUNT
 ASL
 STA BLKCNT
 LDA ACTLEN
 ASL
 LDA BLKCNT
 ADC #$01
:STABLK STA BLKCNT
:LOOP LDA #10
 STA TRYS
 JSR XMDM ;SEND THE BLOCK OF DATA
 LDA #$FF
 STA FIR33
 LDA FINISH
 BNE :CLOSE
 JMP :READ1
:CLOSE JSR SETPRMS
 JSR CLOSE
 BCC :OKCLOS
:BADDSK LDA #$01
 STA IOERR
:OKCLOS JMP OKCLOS

PROTBL HEX FA,FC,06,F1,F2,F3,F4
DOSTYP HEX 01,02,04,08,10,20,40
ACC DA 0
ACCREG DFB 0

SUBLEN STA ACCREG
 LDA REQLEN ;THEN IT MUST BE 2 BYTES FOR INT AND BAS
 SEC
 SBC ACCREG
 STA REQLEN
 LDA REQLEN+1
 SBC #$00
 STA REQLEN+1
 LDA DSKBUF
 CLC
 ADC ACCREG
 STA DSKBUF
 LDA DSKBUF+1
 ADC #$00
 STA DSKBUF+1
 RTS

********************************
*                              *
* ADJUST FIRST BLOCK INFO IF   *
* DOS 3.3  AND MAKE AS TEXT    *
* IF PRODOS.                   *
*                              *
********************************

FIR33 HEX FF

DOINIT JSR SETBUF
 LDA #$FF
 STA FIR33
 LDA #$00
 STA FIRFLG
 LDA PRTCLL
 CMP #$03 ;1=PRODOS, 2=DOS 3.3
 BLT :AETYP
:GETIN JSR UPDATE
 JSR GETINP ;NOT AE FORMAT
 BCC :ISOK?
 JSR SETERR
 BNE :GETIN
 LDA #$03
 STA IOERR
 JMP CANCEL
:ISOK? CMP #$04
 BEQ :L0
 CMP #21
 BEQ :L1
 CMP #'C'
 BNE :INL
 LDA #$FF
 STA CRC
 JMP :LA1
:INL LDA #$00
 STA CRC
 JMP :GETIN
:L0 JMP :CANCEL
:L1 LDA #$00
 STA CRC
:LA1 JMP :DONE
:AETYP LDA #$81 ;SET FOR AE FORMAT
 STA KEY1
 LDA FILTYE
 BEQ :TEXT
 LDA PRTCLL
 CMP #$02 ;IS DOS 3.3?
 BEQ :NOTTXT ;MUST BE DOS 3.3
 JMP :TEXT ;THEN IT IS PRODOS
:NOTTXT LDX #$06 ;CONVERT FOR DOS 3.3
 LDA #$00
 STA FIR33
 LDA FILTYE
:LOOP CMP PROTBL,X ;FIND DOS TYPE FOR DOS 3.3
 BEQ :FND
 DEX
 BPL :LOOP
 BMI :TEXT ;IF NOT FOUND, MAKE IT TEXT
:FND LDA DOSTYP,X
 STA FIRST
 JMP :FIX
:TEXT LDA #$00 ;SET THE DATA TYPE BYTES
 STA FIRST
:FIX LDA FIRST
 EOR #$FF
 STA FIRST+1
 LDA PRTCLL
 CMP #$01 ;CHECK FOR PRODOS
 BEQ :WAIT ;NO NEED TO ADJUST
 LDA FIRST ;NOW ADJUST FOR TYPES
 CMP #$00 ;TEXT FILE
 BEQ :WAIT
 CMP #$F1
 BGE :WAIT ;NO ADJUSTMENT NEEDED ON NON STANDARD FILES
 CMP #$04 ;BINARY FILE?
 BNE :DO2
 LDA #$04
 JSR SUBLEN
 LDA AUXTYP ;MOVE STARTING ADDRESS
 STA MSGBUF
 LDA AUXTYP+1
 STA MSGBUF+1
 LDA EOF ;MOVE FILE LENGTH
 STA MSGBUF+2
 LDA EOF+1
 STA MSGBUF+3
 JMP :WAIT
:DO2 LDA #$02
 JSR SUBLEN
 LDA EOF
 STA MSGBUF
 LDA EOF+1
 STA MSGBUF+1
:WAIT JSR UPDATE ;WAIT FOR STATING NAK
 JSR GETINP
 BCC :GOTONE
 JSR SETERR ;COUNT THE TIME OUT
 BNE :WAIT
 JMP CANCEL
:GOTONE CMP #$04
 BEQ :CANCEL
 CMP #$18
 BEQ :CANCEL
 CMP #21
 BNE :WAIT
:GAHEAD LDA #$03 ;GOT THE NAK, NOW SEND
 STA TRYS
 LDA #$FF
 STA FIRFLG
:WAIT0 JSR UPDATE
 LDA #$81 ;SEND INITIAL HEADER
 JSR SEND
 LDA FIRST
 JSR SEND
 LDA FIRST
 EOR #$FF
 JSR SEND
 JSR GETINP ;WAIT FOR THE ACK
 BCC :ISOK
 JSR SETERR
 BNE :WAIT0
:ISOK CMP #$06 ;TEST FOR ACK
 BEQ :DONE
 CMP #$04
 BEQ :CANCEL
 CMP #$18
 BEQ :CANCEL
 JSR SETERR
 BNE :WAIT0
 RTS
:DONE LDA #$FF
 STA AEFLG
 STA FIRFLG
 STA BLK0
 RTS
:CANCEL JMP CANCEL

********************************
*                              *
* SEND LAST BLOCK IF OK FOR    *
* PRODOS.  OTHERWISE RETURN.   *
*                              *
********************************

SETPRMS LDA AEFLG
 BEQ :END
 LDA PRTCLL
 CMP #$01 ;IS PRODOS?
 BEQ :OK
:END LDA #$04 ;SEND EOT
 JSR SEND
 JSR GETINP ;GET ACK
 BCS :ONE
 CMP #$06
 BEQ :RET
:ONE LDA #$04 ;SEND EOT
 JMP SEND
:RET RTS
:OK LDA #$02
 STA TRYS
:CLOSE1 LDA #$04 ;SEND EOT
 JSR SEND
 JSR GETINP ;GET ACK
 BCS :ERR
 CMP #$06
 BEQ :LL
:ERR DEC TRYS
 BNE :CLOSE1
 RTS
:LL JSR GETINP ;GET SYN
 BCS :ERR1
 CMP #$16
 BEQ :REPLY
:ERR1 DEC TRYS
 BNE :LL
 RTS
:REPLY LDA #$17
 JSR SEND ;RESPOND WITH ETB
 JSR GETINP
 CMP #21 ;WAIT FOR NAK
 BEQ :LASTBLK
 DEC TRYS
 BNE :REPLY
 RTS
:LASTBLK LDA #>FILINFO ;SEND THE FILE INFO BLOCK
 STA PTR+1
 LDA #FILINFO
 STA PTR
 LDA #$AA
 STA FIRST
 EOR #$FF
 STA FIRST+1
 LDA #$D4
 STA FILINFO+1
 LDA #$41
 STA FILINFO+2
 LDA #$01
 STA BLKCNT
 JMP XMDM

XMDM JSR GETCKSM
 JSR UPDATE
 LDA #$01 ;SEND SOH
 JSR SEND
XMDM1 LDA BLOCK ;SEND FIRST BLOCK NUMBER
 JSR SEND
 LDA BLOCK ;SEND SECOND BLOCK NUMBER
 EOR #$FF
 JSR SEND
 LDY #$00 ;SEND OUT THE ACTUAL DATA
 STY YREG
:LOOP1 LDY YREG
 LDA (PTR),Y
 JSR SEND
 INC YREG
 LDA YREG
 CMP #$80
 BNE :LOOP1
 LDA CHKSUM ;SEND THE CHECK SUM
 JSR SEND
 LDA CRC
 BEQ :GET
 LDA CHKSUM+1
 JSR SEND
:GET JSR GETINP ;WAIT FOR A NAK/ACK
 BCC :TEST
 JSR SETERR
 BEQ :CANCEL
 JSR UPDATE
 JMP :GET
:TEST CMP #21 ;SEND IT OVER!
 BEQ :RECERR
 CMP #$04
 BEQ :CANCEL
 CMP #'C'
 BEQ :GNB
:CNB CMP #$18
 BEQ :CANCEL
 CMP #$06 ;OK GOT IT, DO THE NEXT BLK
 BNE :GET
:GNB LDA #10
 STA TRYS
 LDA #$00
 STA ERR
 LDA PTR ;INCREMENT THE POINTER
 CLC
 ADC #$80
 STA PTR
 LDA PTR+1
 ADC #$00
 STA PTR+1
 INC BLOCK
 BNE :NOADD
 INC BLOCK+1 ;INCRMENT THE BLOCK NUMBER
:NOADD LDA BLOCK
 STA FIRST
 EOR #$FF
 STA FIRST+1
 DEC BLKCNT
 BNE :XMDM
 RTS
:RECERR JSR SETERR
 BEQ :CANCEL
:XMDM JMP XMDM
:CANCEL JMP CANCEL

GETCKSM LDA CRC
 BEQ DOCKSM
 JMP DOCRC16
DOCKSM LDY #$00 ;SEND OUT THE ACTUAL DATA
 STY CHKSUM
:LOOP1 LDA (PTR),Y
 CLC
 ADC CHKSUM
 STA CHKSUM
 INY
 CPY #$80
 BNE :LOOP1
 RTS
DOCRC16 LDX #$00
 STX CHKSUM
 STX CHKSUM+1
:CRC1 LDY #$00
:CRC2 LDA (PTR),Y
 JSR :CRC3
 INY
 CPY #$80
 BNE :CRC2
 RTS
:CRC3 STA HOLDCRC
 LDA #$00
 LDX #$08
:CRC4 ASL HOLDCRC
 ROR A
 AND #$80
 EOR CHKSUM
 ASL CHKSUM+1
 ROL A
 BCC :CRC5
 PHA
 LDA CHKSUM+1
 EOR #$21
 STA CHKSUM+1
 PLA
 EOR #$10
:CRC5 STA CHKSUM
 DEX
 BNE :CRC4
 RTS

BIN2BLK DFB $0A
 DS 2
 DS 1
 DS 1
 DS 2
 DS 1
BLKSIZ DS 2
 DS 8
 DS 1
BREF DS 1
BEOF DS 3
BNAML DS 1
BFNAM DS 64
MSBE0 DS 29
DSN DS 4
BNK DS 7
PADD DS 1

FRESPC DS 2

MAKSPBK LDA #>NAMBUF
 STA BIN2BLK+2
 LDA #NAMBUF
 STA BIN2BLK+1
 JSR MLI
 DFB $C4
 DA BIN2BLK
 BCC :DOEOF
:ERROR LDA #$09
 STA IOERR
 JMP OKCLOS
:ERROR2 LDA #$0A
 STA IOERR
 JMP OKCLOS
:DOEOF LDA #02
 STA BREF-1
 JSR MLI
 DFB $D1
 DA BIN2BLK+18
 BCS :ERROR2
 LDA BIN2BLK+8
 STA BIN2BLK+117
 LDA BIN2BLK+9
 STA BIN2BLK+118
 LDA #$0A
 STA BIN2BLK
 LDA #$02
 STA BIN2BLK+18
 LDX NAMBUF
:CKNAM LDA NAMBUF,X
 CMP #'/'
 BEQ :DONAM
 DEX
 BEQ :ALLNAM
 JMP :CKNAM
:DONAM STX TLEN1
 LDA NAMBUF
 SEC
 SBC TLEN1
 STA BIN2BLK+23
 LDX TLEN1
 INX
 LDY #01
:WORK LDA NAMBUF,X
 STA BIN2BLK+23,Y
 CPX NAMBUF
 BEQ :OUT
 INX
 INY
 JMP :WORK
:ALLNAM LDX NAMBUF
 LDA NAMBUF,X
 STA BIN2BLK+23,X
 DEX
 BNE :ALLNAM
:OUT LDA #$47
 STA BIN2BLK+1
 LDA #$4C
 STA BIN2BLK+2
 RTS

CKBIN2 LDA BIN2
 BEQ :NOPE
 JMP SEND0
:NOPE RTS

SEND0 LDA PTR
 STA TPTR1
 LDA PTR+1
 STA TPTR1+1
 LDA #>BIN2BLK
 STA PTR+1
 LDA #BIN2BLK
 STA PTR
 LDA #$01
 STA BLKCNT
 JSR XMDM
 LDA TPTR1
 STA PTR
 LDA TPTR1+1
 STA PTR+1
 LDA #$20
 STA BLKCNT
 LDA #$00
 STA BIN2
 RTS


POUTHK JMP (POUT)
MINPHK JMP (MINP)
MOUT1HK JMP (MOUT1)
PUSHINP JMP (PUSH)

TLEN1 DS 1
TPTR1 DS 2

 DS \

 LST OFF

NAMBUF DS $100
RETNAM = NAMBUF+$80
BUFNAM DS $100
MSGBUF DS $1000

 LST ON

PRGEND = *
