xmodem: 'C02 optimizations, applesoft routine error handing improved

This commit is contained in:
mgcaret 2018-10-05 23:43:31 -07:00
parent 4affcb82e4
commit 7383c05f9e
1 changed files with 52 additions and 25 deletions

View File

@ -68,7 +68,7 @@ ZPSTART = $00
lastblk = ZPSTART+0 ; flag for last block lastblk = ZPSTART+0 ; flag for last block
blkno = ZPSTART+1 ; block number blkno = ZPSTART+1 ; block number
errcnt = ZPSTART+2 ; error counter 10 is the limit errcnt = ZPSTART+2 ; error counter 10 is the limit
bflag = ZPSTART+3 ; block flag bflag = ZPSTART+3 ; block flag, indicate block 1 received
crc = ZPSTART+4 ; CRC lo byte (two byte variable) crc = ZPSTART+4 ; CRC lo byte (two byte variable)
crch = ZPSTART+5 ; CRC hi byte crch = ZPSTART+5 ; CRC hi byte
@ -95,6 +95,7 @@ VARTAB = $69 ; start of variables (usually same as PRGEND)
LINNUM = $50 ; line number, usable as temporary storage LINNUM = $50 ; line number, usable as temporary storage
FIXLINKS = $D4F2 ; AppleSoft routine to re-link program FIXLINKS = $D4F2 ; AppleSoft routine to re-link program
SCRTCH = $D64B ; AppleSoft "SCRTCH" - erase program, reset everything
PRERR = $FF2D ; print "ERR" and beep PRERR = $FF2D ; print "ERR" and beep
@ -107,12 +108,17 @@ KBDSTR = $C010 ; keyboard strobe
ENOERR = $00 ; no error ENOERR = $00 ; no error
ENOSTK = $D0 ; not enough free stack ENOSTK = $D0 ; not enough free stack
EFAILED = $FF ; failed due to too many errors EFAILED = $FF ; failed due to too many errors
ECANCEL = $FE ; transfer cancelled ECANCEL = $FE ; transfer cancelled, receive memory changed
EMMBLK = $FC ; block number complement mismatch
EBLKMM = $FD ; block number mismatch EBLKMM = $FD ; block number mismatch
EMMBLK = $FC ; block number complement mismatch
ECANCELOK = $FB ; transfer cancelled, receive memory unchanged or send
ACIA_SLOT = 2 ; slot # of the ACIA, //c: 1=printer, 2=modem
; defining STANDALONE allow one to build a test version of the code .orged
; at $4000 in order to test the basic bits of the code without doing a full
; firmware build. Even works on the enhanced //e with SSC.
; comment out if going to //c firmware ; comment out if going to //c firmware
;STANDALONE = 1 ;STANDALONE = 1
@ -154,7 +160,7 @@ CPMEOF = $1A ; CP/M EOF char, which is the correct padding
; By Daryl Rictor, August 8, 2002 ; By Daryl Rictor, August 8, 2002
; ;
; v1.0 released on Aug 8, 2002. ; v1.0 released on Aug 8, 2002.
; MG's IIc version released ~Sep/Oct 2018 ; MG's IIc version released Oct 2018
; ;
; ;
@ -172,32 +178,44 @@ CPMEOF = $1A ; CP/M EOF char, which is the correct padding
; AppleSoft BASIC save/load ; AppleSoft BASIC save/load
asftsave: jsr asftprgio asftsave: jsr asftprgio
sec sec
jsr xmentry ; AppleSoft tape code doesn't check for errors, either jsr xmentry ; AppleSoft tape SAVE doesn't check for errors
bcs monerr ; but we will
.ifdef STANDALONE .ifdef STANDALONE
rts rts
.else .else
; //c aux bank code
jmp swrts2 jmp swrts2
.endif .endif
asftload: jsr asftprgio ; current length does not matter asftload: jsr asftprgio ; current length does not matter
clc clc
jsr xmentry jsr xmentry
lda A2L ; A2L/H have exact end address sta $300
bcs loaderr ; if error, execute NEW
lda A2L ; otherwise A2L/H have exact end address
ldy A2H ; regardless of appended junk ldy A2H ; regardless of appended junk
sta VARTAB sta VARTAB ; mark end of program/start of vars
sty VARTAB+1 sty VARTAB+1
.ifdef STANDALONE .ifdef STANDALONE
jmp FIXLINKS ; re-link the program jmp FIXLINKS ; finally, re-link the program
.else .else
; //c aux bank code ; //c aux bank code
lda #>(FIXLINKS-1) lda #>(FIXLINKS-1) ; indirectly if in aux ROM
pha pha
lda #<(FIXLINKS-1) lda #<(FIXLINKS-1)
pha pha
jmp swrts2 jmp swrts2
.endif .endif
loaderr: cmp #ECANCELOK ; program memory unchanged?
beq :+ ; yes, don't clear program
; (in case user accidentally used LOAD)
lda #>(SCRTCH-1) ; otherwise set up RTS trick for SCRTCH ('NEW')
pha ; whether we are in aux ROM or RAM
lda #<(SCRTCH-1)
pha
: bra monerr ; print ERR first
; set up A1L/H and A2L/H for applesoft program save/load ; set up A1L/H and A2L/H for applesoft program save/load
; this is exactly what AppleSoft does for tapes ; this is exactly what AppleSoft does for tapes
asftprgio: lda TXTTAB asftprgio: lda TXTTAB
@ -287,6 +305,7 @@ XModemSend: lda #$17 ; 'W' inverse
sta errcnt ; will count retries left sta errcnt ; will count retries left
stz lastblk ; set flag to false stz lastblk ; set flag to false
lda #$01 lda #$01
sta bflag ; if user cancels, we haven't changed memory
sta blkno ; set block # to 1 sta blkno ; set block # to 1
Wait4CRC: lda #$ff ; 3 seconds Wait4CRC: lda #$ff ; 3 seconds
sta retry2 ; sta retry2 ;
@ -408,7 +427,11 @@ ChkCancel: lda KBD ; see if ESC has been hit by user
lda #ESC ; send escape lda #ESC ; send escape
jsr Put_Chr ; to the remote end jsr Put_Chr ; to the remote end
SxCancel: jsr Flush ; flush receive stream SxCancel: jsr Flush ; flush receive stream
lda #ECANCEL ; and indicate a transfer cancelled lda bflag ; did user memory change?
beq :+ ; other error code if so
lda #ECANCELOK ; otherwise tell user all is OK
rts
: lda #ECANCEL ; and indicate a transfer cancelled
rts rts
; ;
; ;
@ -425,9 +448,11 @@ StartCrc: lda #'C' ; "C" start with CRC mode
jsr Put_Chr ; send it jsr Put_Chr ; send it
lda #$FF lda #$FF
sta retry2 ; set loop counter for ~3 sec delay sta retry2 ; set loop counter for ~3 sec delay
lda #$00 ;lda #$00
sta crc ;sta crc
sta crch ; init CRC value ;sta crch ; init CRC value
stz crc
stz crch
jsr GetByte ; wait for input jsr GetByte ; wait for input
bcs GotByte ; byte received, process it bcs GotByte ; byte received, process it
jsr ChkCancel jsr ChkCancel
@ -435,7 +460,7 @@ StartCrc: lda #'C' ; "C" start with CRC mode
sta STLOC sta STLOC
dec errcnt ; next try dec errcnt ; next try
bne StartCrc ; resend "C" if more tries bne StartCrc ; resend "C" if more tries
beq SxCancel ; otherwise cancel send beq SxCancel ; otherwise cancel it
StartBlk: jsr ChkCancel ; see if user wants to quit first StartBlk: jsr ChkCancel ; see if user wants to quit first
lda #$FF ; lda #$FF ;
@ -561,11 +586,10 @@ BlkStatus: lda blkno ; put block # mod 8 in status display
; You would call the ACIA_Init prior to running the xmodem transfer ; You would call the ACIA_Init prior to running the xmodem transfer
; routine. ; routine.
; ;
; //c Modem Port ACIA: ACIA_Data = $C088+(ACIA_SLOT*$10)
ACIA_Data = $C0A8 ACIA_Status = $C089+(ACIA_SLOT*$10)
ACIA_Status = $C0A9 ACIA_Command = $C08A+(ACIA_SLOT*$10)
ACIA_Command = $C0AA ACIA_Control = $C08B+(ACIA_SLOT*$10)
ACIA_Control = $C0AB
SPD_19_2_8N1 = $1F SPD_19_2_8N1 = $1F
SPD_115_2_8N1 = $10 SPD_115_2_8N1 = $10
@ -601,8 +625,9 @@ Put_Chr1: lda ACIA_Status ; serial port status
; ;
; ;
; ;
GetByte: lda #$00 ; wait for chr input and cycle timing loop GetByte: ;lda #$00 ; wait for chr input and cycle timing loop
sta retry ; set low value of timing loop ;sta retry ; set low value of timing loop
stz retry
StartCrcLp: jsr Get_Chr ; get chr from serial port, don't wait StartCrcLp: jsr Get_Chr ; get chr from serial port, don't wait
bcs GetByte1 ; got one, so exit bcs GetByte1 ; got one, so exit
dec retry ; no character received, so dec counter dec retry ; no character received, so dec counter
@ -624,9 +649,11 @@ Flush1: jsr GetByte ; read the port
; CRC subroutines ; CRC subroutines
; ;
; ;
CalcCRC: lda #$00 ; yes, calculate the CRC for the 128 bytes CalcCRC: ;lda #$00 ; yes, calculate the CRC for the 128 bytes
sta crc ; ;sta crc ;
sta crch ; ;sta crch ;
stz crc ; save 2 bytes with 'C02 code
stz crch ;
ldy #$02 ; ldy #$02 ;
CalcCRC1: lda Rbuff,y ; CalcCRC1: lda Rbuff,y ;
eor crc+1 ; Quick CRC computation with lookup tables eor crc+1 ; Quick CRC computation with lookup tables