544 lines
13 KiB
ArmAsm
544 lines
13 KiB
ArmAsm
|
* lst off
|
||
|
*--------------------------------------------------------*
|
||
|
* Ymodem Driver source code for GBBS... orginally by *
|
||
|
* Mike Golazewski or Greg Schaefer (you choose). Sourced *
|
||
|
* (Disassembled) w/ Merlin Pro. *
|
||
|
* This file is NOT for public distribution. *
|
||
|
* (So Lance doesn't get pissed...Aw poor baby) *
|
||
|
*--------------------------------------------------------*
|
||
|
|
||
|
ORG $5000
|
||
|
ORG $9E00
|
||
|
|
||
|
CHRGET = $03B1 ;acos get character routine
|
||
|
GETBYT = $0380 ;get next byte from segment
|
||
|
CHKBYT = $0383 ;check next byte in segment
|
||
|
GOBCOM = $0386 ;gobble a comma in segment
|
||
|
MOVNAME = $038F ;move filename to acos internal
|
||
|
SETOVEC = $03A1 ;set acos output vector to dev #
|
||
|
DECOUT = $03A7 ;print a signed decimal # to dev
|
||
|
OPEN = $03AD ;open a file using acos
|
||
|
CLOSE = $03B0 ;close a file using acos
|
||
|
RDBLK = $03B9 ;acos read a block call
|
||
|
ACOPTHLO = $03CB ;acos path pointer high part
|
||
|
ACOPTHHI = $03CC ;acos path pointer lo part
|
||
|
ACOSREF = $03CD ;acos reference number
|
||
|
PRINT = $0906 ;print to sysops screen (local)
|
||
|
MDMIN = $0E15 ;modem: receive a character
|
||
|
MDMOUT = $0E18 ;modem: send a character
|
||
|
MDMDCD = $0E1B ;modem: check for carrier loss
|
||
|
H9E00 = $9E00
|
||
|
H9E01 = $9E01
|
||
|
H9E02 = $9E02
|
||
|
HA5FF = $A5FF
|
||
|
HA600 = $A600
|
||
|
HA640 = $A640
|
||
|
HA642 = $A642
|
||
|
MLI = $BF00 ;prodos MLI dispatch point
|
||
|
KEY = $C000
|
||
|
STROBE = $C010
|
||
|
PTRIG = $C070
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
JSR CHKBYT
|
||
|
CMP #$AC ;Is it a comma?
|
||
|
BEQ H4F11 ;yes, go send a file
|
||
|
JSR GETBYT ;no, skip past the offending character
|
||
|
JSR H5174 ;zero out some counters and stuff
|
||
|
JMP H4F70 ;abort the xfer
|
||
|
RTS
|
||
|
|
||
|
H4F11 JSR GOBCOM ;gobble the comma
|
||
|
JSR MOVNAME ;move the name to acos's buff's
|
||
|
JSR OPEN ;open it using acos
|
||
|
BCC H4F1D ;if all is ok, continue
|
||
|
RTS ;maybe file missing, return...
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Go get some file information for use in the header pack *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
H4F1D LDA ACOPTHLO
|
||
|
STA H522E
|
||
|
LDA ACOPTHHI
|
||
|
STA H522F
|
||
|
JSR MLI ;dispatch the call
|
||
|
HEX C4 ;Get File Info call
|
||
|
DA H522D ;parameters found here
|
||
|
BCC H4F34 ;if everything's ok, continue
|
||
|
JMP CLOSE ;otherwise close it, leave
|
||
|
|
||
|
H4F34 LDA ACOSREF ;get acos internal file ref #
|
||
|
STA H5240 ;store it for parms
|
||
|
JSR MLI
|
||
|
HEX D1 ;Get EOF call
|
||
|
DA H523F ;address of Get EOF parms
|
||
|
|
||
|
JSR H5174 ;zero out some locations
|
||
|
LDA ACOPTHLO ;get pointer to filename/lo
|
||
|
STA $00 ;set up indirect address
|
||
|
LDA ACOPTHHI ;get pointer to filename/hi
|
||
|
STA $01 ;finish setting up
|
||
|
LDY #$00
|
||
|
LDA ($00),Y ;get filename length byte
|
||
|
TAX
|
||
|
H4F52 INY
|
||
|
LDA ($00),Y ;get character in filename
|
||
|
STA H4F8C,Y ;store it in the [ ]
|
||
|
STA HA5FF,Y ;store it in the header packet
|
||
|
DEX
|
||
|
BNE H4F52
|
||
|
LDA #$1D ;what's this?
|
||
|
STA HA640
|
||
|
|
||
|
LDX #$00 ;move the GFI and Get EOF
|
||
|
H4F65 LDA H522D,X ;results to header packet
|
||
|
STA HA642,X
|
||
|
INX
|
||
|
CPX #$17 ;done all?
|
||
|
BNE H4F65 ;no, loop
|
||
|
H4F70 LDA #$00
|
||
|
STA STROBE ;clear the keyboard strobe
|
||
|
STA $24 ;start flush left
|
||
|
LDY #$03 ;get output channel
|
||
|
JSR SETOVEC ;channel 3, sysop (local)
|
||
|
|
||
|
JSR SPRINT ;print this, return after brk
|
||
|
H4F7E ASC '['
|
||
|
H4F8C ASC ' ] _ #'
|
||
|
BRK
|
||
|
|
||
|
LDA BADSEND ;last file check
|
||
|
BEQ H4FAA ;if ok, continue
|
||
|
JMP H5086 ;close 'em, stop sending
|
||
|
H4FAA JSR NAKIN ;wait for a <NAK> or 'C' (wrong!)
|
||
|
|
||
|
* In theory, we should wait for just 'C' or 'CK' for ymodem
|
||
|
* But greg decides to do it his own way.
|
||
|
|
||
|
BCC SENDHEAD ;if ok, continue..
|
||
|
JMP H5086 ;else, close and stop sending
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Send the Header Packet with some file information in it *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
SENDHEAD LDA #$48 ;print an 'H' for header
|
||
|
JSR PRSCRN
|
||
|
|
||
|
JSR PRCOUNT ;print # of blocks sent
|
||
|
|
||
|
LDA #$01 ;get SOH
|
||
|
JSR MDMOUT ;send it out the port
|
||
|
LDA BLOCKNUM ;get protocol block #
|
||
|
JSR MDMOUT ;send it out the port
|
||
|
EOR #$FF ;get complement of block #
|
||
|
JSR MDMOUT ;send it out the port
|
||
|
|
||
|
LDX #$00 ;start at $a600
|
||
|
H4FCC LDA HA600,X ;get the header packet
|
||
|
JSR MDMOUT ;send the byte
|
||
|
JSR DOCRC ;compute cumulative CRC for it
|
||
|
INX ;next byte
|
||
|
CPX #$80 ;done 128 bytes?
|
||
|
BNE H4FCC ;no, send another
|
||
|
|
||
|
LDA CRCHI ;get CRC Hi part
|
||
|
JSR MDMOUT ;send it out the port
|
||
|
LDA CRCLO ;get CRC Lo part
|
||
|
JSR MDMOUT ;out the port we go
|
||
|
|
||
|
JSR ACKIN ;Check for an ACK received
|
||
|
BCS SENDHEAD ;ACK not received, resend header
|
||
|
|
||
|
LDA HA600 ;block length of 0? (EOT)
|
||
|
BNE H4FF3 ;no, send file
|
||
|
JMP H5089 ;else, yes, close up and return
|
||
|
|
||
|
H4FF3 JSR ACKIN ;wait for another ACK?
|
||
|
|
||
|
H4FF6 LDA #$0A ;initialize to 10 retries
|
||
|
STA RETRIES ;store counter
|
||
|
INC BLOCKNUM ;next xmodem block in series
|
||
|
|
||
|
LDA BLKLO ;get blocks sent lo
|
||
|
CLC
|
||
|
ADC #$08 ;blocks sent=blocks sent+8
|
||
|
STA BLKLO ;store result
|
||
|
LDA BLKHI ;continue to make sure we
|
||
|
ADC #$00 ;included the carry bit
|
||
|
STA BLKHI ;store it also
|
||
|
|
||
|
JSR PRCOUNT ;print # of blocks sent (again)
|
||
|
|
||
|
LDX #$00 ;lo address of read call
|
||
|
LDA #$A6 ;hi address of read call
|
||
|
LDY #$08 ;number of 128 byte packets
|
||
|
JSR RDBLK ;read 'em
|
||
|
BCS H506D ;if error, end of file, close...
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Send a Huge, 1024 Byte packet to the othe end with CRC *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
SEND1024 LDA #$53 ;get an 'S'
|
||
|
JSR PRSCRN ;print it for the sysop
|
||
|
|
||
|
LDA #$00 ;set up indirect address to
|
||
|
STA $00 ;point to $a600
|
||
|
LDA #$A6
|
||
|
STA $01
|
||
|
|
||
|
LDA #$02 ;get an STX
|
||
|
JSR MDMOUT ;send it out the port
|
||
|
LDA BLOCKNUM ;get current block #
|
||
|
JSR MDMOUT ;send it
|
||
|
EOR #$FF ;255-block #
|
||
|
JSR MDMOUT ;send it
|
||
|
|
||
|
LDX #$04 ;send 4 packs of 256 bytes
|
||
|
LDY #$00
|
||
|
STY CRCLO ;initialize CRC lo
|
||
|
STY CRCHI ;initialize CRC hi
|
||
|
H5044 LDA ($00),Y ;get the byte
|
||
|
JSR MDMOUT ;send it
|
||
|
JSR DOCRC ;compute the cumulative CRC
|
||
|
INY ;next byte
|
||
|
BNE H5044 ;done 256? no, do some more
|
||
|
|
||
|
INC $01 ;yes, next 256 bytes
|
||
|
DEX ;are we done with the 4 packs?
|
||
|
BNE H5044 ;no, go send some more
|
||
|
|
||
|
LDA CRCHI ;get CRC hi
|
||
|
JSR MDMOUT ;send it
|
||
|
LDA CRCLO ;get CRC lo
|
||
|
JSR MDMOUT ;send it
|
||
|
|
||
|
JSR ACKIN ;check for an ACK
|
||
|
BCC H4FF6 ;ok, send the next 1024 byte pack
|
||
|
|
||
|
DEC RETRIES ;count number of times packet sent
|
||
|
BNE SEND1024 ;if count <> 10, try again
|
||
|
JMP H5086 ;aborted transfer
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* End of transmission of one file, return to caller... *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
H506D LDA #$0A ;initialize count for last byte
|
||
|
STA RETRIES
|
||
|
H5072 LDA #$46 ;get an 'F' (final)
|
||
|
JSR PRSCRN ;print it to sysop
|
||
|
|
||
|
LDA #$04 ;get an EOT
|
||
|
JSR MDMOUT ;send it
|
||
|
JSR ACKIN ;wait for an ACK
|
||
|
BCC H5086 ;if ok, finish up
|
||
|
DEC RETRIES ;no ACK, try again...
|
||
|
BNE H5072 ;if retries <> 10, try it again
|
||
|
|
||
|
H5086 JSR CLOSE ;otherwise close it, finish up
|
||
|
|
||
|
H5089 LDX #$00 ;erase bottom line
|
||
|
STX $24 ;horizontal position = flush left
|
||
|
LDA #$20 ;print a whole line of spaces
|
||
|
H508F JSR PRINT
|
||
|
INX
|
||
|
CPX #$27 ;done yet?
|
||
|
BCC H508F ;nope, more spaces
|
||
|
|
||
|
LDX #$0F ;put something consistent
|
||
|
H5099 STA H4F8C,X ;over top of the filename
|
||
|
DEX
|
||
|
BNE H5099
|
||
|
LDA #$00 ;start flush left on return
|
||
|
STA $24
|
||
|
LDY #$00 ;output device is #0
|
||
|
JSR SETOVEC
|
||
|
RTS ;return to calling program
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* NAKIN routine gets a <NAK>, or times out waiting *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
NAKIN LDA #$57 ;put a 'W' on sysop's screen
|
||
|
JSR PRSCRN
|
||
|
|
||
|
LDY #$3C
|
||
|
H50B0 JSR INPUT ;get a character from the modem
|
||
|
CMP #$15 ;is it a <NAK>?
|
||
|
BEQ H50CF ;yes, return gracefully
|
||
|
CMP #$43 ;is it a 'C'?
|
||
|
BEQ H50CF ;yes, also return gracefully
|
||
|
CMP #$03 ;is it a ????
|
||
|
BEQ H50C6 ;non-fatal error in transmission
|
||
|
CMP #$18 ;<CAN> character, major problems
|
||
|
BEQ H50C8 ;uh oh, major type problems
|
||
|
DEY ;keep trying
|
||
|
BNE H50B0 ;not done yet, try again
|
||
|
H50C6 SEC ;either timed out or non-fatal
|
||
|
RTS
|
||
|
|
||
|
H50C8 LDA #$FF ;fatal transmission error
|
||
|
STA BADSEND ;cancel next file transmission
|
||
|
SEC
|
||
|
RTS
|
||
|
|
||
|
H50CF CLC ;<NAK> received, return properly
|
||
|
RTS
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* ACKIN routine gets an <ACK> , or times out waiting *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
ACKIN LDA #$57 ;print a 'W' to sysop
|
||
|
JSR PRSCRN
|
||
|
|
||
|
LDY #$0A ;10 total for retries
|
||
|
STY LASTCHAR
|
||
|
H50DB JSR INPUT ;get a character from the modem
|
||
|
CMP #$15 ;is it a <NAK>?
|
||
|
BEQ H50ED ;eww, yes, probably bad block
|
||
|
CMP #$43 ;is it a 'C'?
|
||
|
BEQ H50ED ;yes, bad block, or sync error
|
||
|
CMP #$06 ;is it an <ACK>?
|
||
|
BEQ H50F4 ;yes, return ok
|
||
|
DEY ;none of the above,
|
||
|
BNE H50DB ;try again
|
||
|
H50ED LDA #$45 ;put an 'E' on the sysop's end
|
||
|
JSR PRSCRN
|
||
|
SEC ;flag for bad data
|
||
|
RTS
|
||
|
|
||
|
H50F4 CLC ;data ok, return
|
||
|
RTS
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Get Input from modem or keyboard... <ESC> aborts send *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
INPUT LDA #$00 ;initialize outer loop
|
||
|
STA LOOPSML
|
||
|
LDA #$64 ;initialize inner loop
|
||
|
STA LOOPLRG
|
||
|
H5100 BIT PTRIG
|
||
|
JSR MDMDCD ;are we still connected?
|
||
|
BCC H513A ;no, close everything and return
|
||
|
JSR MDMIN ;yes, get a character
|
||
|
BCC H511E ;no character to get, branch
|
||
|
CMP #$03 ;is it an ETX (End of Text)
|
||
|
BNE H5115 ;no, check last character
|
||
|
CMP #$18 ;is it a can character
|
||
|
BNE H511A ;no, make this the last character
|
||
|
H5115 CMP LASTCHAR ;is this the last character? (can)
|
||
|
BEQ H513A ;yes, flag send as bad, end it
|
||
|
H511A STA LASTCHAR ;no, make this the last character
|
||
|
RTS
|
||
|
|
||
|
H511E LDA KEY ;check the keyboard
|
||
|
BMI H512A ;key pressed? No, next part of loop
|
||
|
STA STROBE ;yes, clear strobe
|
||
|
CMP #$1B ;is it an <ESC>?
|
||
|
BEQ H513A ;yes, stop transfer
|
||
|
H512A BIT PTRIG ;???
|
||
|
DEC LOOPSML ;take car of inside loop
|
||
|
BNE H5100
|
||
|
DEC LOOPLRG ;take care of large loop
|
||
|
BNE H5100 ;not done, try some more
|
||
|
LDA #$00 ;done, nothing, 1 timeout
|
||
|
RTS
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Take care of bad send info... abort transfer *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
H513A CMP #$18 ;is it a can character?
|
||
|
BNE H5143 ;no, just go abort it
|
||
|
LDA #$FF ;<CAN>, so mark it as bad send
|
||
|
STA BADSEND ;save it
|
||
|
H5143 PLA
|
||
|
PLA
|
||
|
PLA
|
||
|
PLA
|
||
|
JMP H5086
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Calculate a cumulative CRC-16 from Accumulator *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
DOCRC PHA
|
||
|
EOR CRCHI
|
||
|
STA CRCHI
|
||
|
TXA
|
||
|
PHA
|
||
|
LDX #$08
|
||
|
H5155 ASL CRCLO
|
||
|
ROL CRCHI
|
||
|
BCC H516D
|
||
|
LDA CRCHI
|
||
|
EOR #$10
|
||
|
STA CRCHI
|
||
|
LDA CRCLO
|
||
|
EOR #$21
|
||
|
STA CRCLO
|
||
|
H516D DEX
|
||
|
BNE H5155
|
||
|
PLA
|
||
|
TAX
|
||
|
PLA
|
||
|
RTS
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Initialize some locations & counters *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
H5174 LDA #$00 ;zero out some counters
|
||
|
STA BLOCKNUM
|
||
|
STA BLKLO
|
||
|
STA BLKHI
|
||
|
STA CRCLO
|
||
|
STA CRCHI
|
||
|
TAX
|
||
|
H5186 STA HA600,X ;zero out 1024 bytes
|
||
|
INX
|
||
|
CPX #$80
|
||
|
BNE H5186
|
||
|
RTS
|
||
|
|
||
|
PRSCRN PHA ;save accumulator
|
||
|
LDA #$12 ;save as horizontal position
|
||
|
STA $24
|
||
|
PLA ;restore acc
|
||
|
JSR PRINT ;print character in acc at horiz
|
||
|
RTS
|
||
|
|
||
|
SETUP LDA H9E00
|
||
|
CMP #$4C
|
||
|
BEQ H51CC
|
||
|
LDA #$4C
|
||
|
STA H9E00
|
||
|
LDA #$00
|
||
|
STA H9E01
|
||
|
LDA #$4F
|
||
|
STA H9E02
|
||
|
LDA $04
|
||
|
PHA
|
||
|
LDA $05
|
||
|
PHA
|
||
|
LDA #$2C
|
||
|
STA $04
|
||
|
LDA #$52
|
||
|
STA $05
|
||
|
JSR GETBYT
|
||
|
PLA
|
||
|
STA $05
|
||
|
PLA
|
||
|
STA $04
|
||
|
LDA #$00 ;flag it as no bad send
|
||
|
STA BADSEND
|
||
|
RTS
|
||
|
|
||
|
H51CC LDA #$00
|
||
|
STA H9E00
|
||
|
STA H9E02
|
||
|
LDA $04
|
||
|
PHA
|
||
|
LDA $05
|
||
|
PHA
|
||
|
LDA #>H522C
|
||
|
STA $04
|
||
|
LDA #<H522C
|
||
|
STA $05
|
||
|
JSR GETBYT
|
||
|
PLA
|
||
|
STA $05
|
||
|
PLA
|
||
|
STA $04
|
||
|
RTS
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Print number of blocks to sysop's screen (local) *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
PRCOUNT PHA ;save the ACC
|
||
|
TXA ;save the x reg
|
||
|
PHA
|
||
|
LDA #$15
|
||
|
STA $24 ;new horizontal position
|
||
|
LDX BLKLO ;block count lo
|
||
|
LDA BLKHI ;block count hi
|
||
|
JSR DECOUT ;print it
|
||
|
PLA ;get X
|
||
|
TAX
|
||
|
PLA ;get ACC
|
||
|
RTS
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Here begins a fairly sophisticated print routine, more *
|
||
|
* sophisticated than necessary in my opinion.. *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
SPRINT PLA ;get return addr hi
|
||
|
STA $48
|
||
|
PLA ;get return addr lo
|
||
|
STA $49
|
||
|
TYA
|
||
|
PHA ;save the y reg
|
||
|
LDY #$00
|
||
|
BEQ H520F ;does this work?
|
||
|
H520C JSR PRINT
|
||
|
H520F INC $48
|
||
|
BNE H5215
|
||
|
INC $49
|
||
|
H5215 LDA ($48),Y
|
||
|
BNE H520C
|
||
|
PLA ;restore Y
|
||
|
TAY
|
||
|
LDA $49 ;get changed return addr lo
|
||
|
PHA ;push it
|
||
|
LDA $48 ;get changed return addr hi
|
||
|
PHA ;push it
|
||
|
RTS ;return to altered location
|
||
|
|
||
|
*---------------------------------------------------------*
|
||
|
* Temporary Storage locations used by the program... *
|
||
|
*---------------------------------------------------------*
|
||
|
|
||
|
BLKLO HEX 00 ;blocks sent lo
|
||
|
BLKHI HEX 00 ;blocks sent hi
|
||
|
CRCLO HEX 00 ;CRC lo
|
||
|
CRCHI HEX 00 ;CRC hi
|
||
|
LOOPSML HEX 00 ;small loop
|
||
|
LOOPLRG HEX 00 ;large loop (for input)
|
||
|
LASTCHAR HEX 00 ;last character sent
|
||
|
RETRIES HEX 00 ;# of retries
|
||
|
BLOCKNUM HEX 00 ;block number
|
||
|
BADSEND HEX 00 ;condition of last file sent
|
||
|
H522C HEX 00 ;???
|
||
|
H522D HEX 0A
|
||
|
H522E BRK
|
||
|
H522F BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
H523F BRK
|
||
|
H5240 BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
BRK
|
||
|
|