@ -1,17 +1,17 @@
;*****************************************************************************
; ROMWBW XMODEM FLASH UPDATER
; ROMWBW XMODEM FLASH UPDATER
;
; PROVIDES THE CAPABILTY TO UPDATE ROMWBW FROM THE SBC BOOT LOADER USING
; PROVIDES THE CAPABILTY TO UPDATE ROMWBW FROM THE SBC BOOT LOADER USING
; AN XMODEM FILE TRANSFER. FOR SYSTEMS WITH AN SST39SF040 FLASH CHIP.
;
; TO INSTALL, SAVE THIS FILE AS USRROM.ASM IN \RomWBW\Source\HBIOS
; AND REBUILD AND INSTALL THE NEW ROM VERSION.
;
;
; THE UPDATER CAN THEN BE ACCESSED USING THE "U" OPTION IN THE SBC BOOT LOADER.
;
; OPTION (C) AND (S) - CONSOLE AND SERIAL DEVICE
;
; BY DEFAULT THE UPDATER IS SET TO USE THE FIRST ROMWBW CONSOLE DEVICE (0) FOR
; BY DEFAULT THE UPDATER IS SET TO USE THE FIRST ROMWBW CONSOLE DEVICE (0) FOR
; DISPLAY OUTPUT AND FILES TRANSFER. IF YOU USE A DIFFERENT SERIAL DEVICE FOR
; THE FILE TRANSFER, PROGRESS INFORMATION WILL BE DISPLAYED.
;
@ -22,24 +22,24 @@
; YOU ARE EXPERIENCING RELIABLE TRANSFERS AND FLASHING.
;
; OPTION (R) - REBOOT
; EXECUTE A COLD REBOOT. THIS SHOULD BE DONE AFTER A SUCCESSFUL UPDATE. IF
; EXECUTE A COLD REBOOT. THIS SHOULD BE DONE AFTER A SUCCESSFUL UPDATE. IF
; YOU PERFORM A COLD REBOOT AFTER A FAILED UPDATE THEN IT IS LIKELY THAT
; YOUR SYSTEM WILL BE UNUSABLE AND REMOVING AND REPROGRAMMING THE FLASH
; WILL BE REQUIRED.
;
; OPTION (U) - BEGIN UPDATE
; WILL BEGIN THE UPDATE PROCESS. THE UPDATER WILL EXPECT TO START RECEIVING
; AN XMODEM FILE ON THE SERIAL DEVICE UNIT.
; AN XMODEM FILE ON THE SERIAL DEVICE UNIT.
;
; XMODEM SENDS THE FILE IN PACKETS OF 128 BYTES. THE UPDATER WILL CACHE 32
; PACKETS WHICH IS 1 FLASH SECTOR AND THEN WRITE THAT SECTOR TO THE
; PACKETS WHICH IS 1 FLASH SECTOR AND THEN WRITE THAT SECTOR TO THE
; FLASH DEVICE.
;
; IF USING SEPARATE CONSOLE, BANK AND SECTOR PROGESS INFORMATION WILL SHOWN
;
; BANK 00 S00 S01 S02 S03 S04 S05 S06 S06 S07
; BANK 01 S00 S01 S02 S03 S04 S05 S06 S06 S07
; BANK 02 S00 S01 S02 S03 S04 S05 S06 S06 S07 etc
; BANK 01 S00 S01 S02 S03 S04 S05 S06 S06 S07
; BANK 02 S00 S01 S02 S03 S04 S05 S06 S06 S07 etc
;
; THE XMODEM FILE TRANSFER PROTOCOL DOES NOT PROVIDE ANY FILENAME OR SIZE
; INFORMATION FOR THE TRANSFER SO THE UPDATER DOES NOT PERFORM ANY CHECKS
@ -58,7 +58,12 @@
; IN THE CASE OF A FAILED UPDATE THIS OPTION COULD BE USED TO ATTEMPT TO
; LOAD CP/M AND PERFORM THE NORMAL XMODEM / FLASH PROCESS TO RECOVER.
;
; V.DEV 1/1/2021 PHIL SUMMERS, B1ACKMAI1ER @ RETROBREWCOMPUTERS.ORG
; OPTION (H) - DEBUG OPTION - SWITCH ON CPU CLCOK DIVIDER ON SBC-V2-004+
; OPTION (T) - DEBUG OPTION - TEST TIMER FOR 20 SECONDS. * = START AND FINISH
;
;
; V.DEV 3/1/2021 PHIL SUMMERS, DIFFICULTYLEVELHIGH@GMAIL.COM
; b1ackmai1er ON RETROBREWCOMPUTERS.ORG
;
;
; NOTES:
@ -66,7 +71,17 @@
; ONLY SST39F040 FLASH CHIP IS SUPPORTED DUE TO 4K SECTOR REQUIREMENT.
; SBC V2-005 MEGAFLASH REQUIRED FOR 1MB FLASH SUPPORT.
; FAILURE HANDLING HAS NOT BEEN TESTED.
; TIMING LOOPS ARE NOT CALIBRATED. DEVELOPED ON A 10MHZ Z80
; TIMING BROADLY CALIBRATED ON A Z80 SBC-V2
; UNABIOS NOT SUPPORTED
;
; MAXIMUM SERIAL SPEED LIMITATIONS
;
; SBC-V2 UART NO FLOW CONTROL 2MHZ | 9600
; SBC-V2 UART NO FLOW CONTROL 4MHZ | 19200
; SBC-V2 UART NO FLOW CONTROL 5MHZ | 19200
; SBC-V2 UART NO FLOW CONTROL 8MHZ | 38400
; SBC-V2 UART NO FLOW CONTROL 10MHZ | 38400
; SBC-V2 USB-FIFO 2MHZ+ | N/A
;
; ACKNOWLEDGEMENTS:
;
@ -87,6 +102,8 @@ HBX_START .EQU $FE00
;
# DEFINE HB_DI DI
# DEFINE HB_EI EI
;
XFUDBG .EQU 0
;
.ORG USR_LOC
;
@ -107,7 +124,7 @@ BSPC: .EQU 'H'-40h ; ^H = Backspace
ld SP , HBX_START - MD_CSIZ ; ALLOW FOR RELOCATABLE CODE AREA
ld HL , msgHeader ; PRINT
call PRTSTR0 ; GREETING
CALL PRTSTR0 ; GREETING
LD HL , MD_FSTART ; COPY FLASH
LD DE , HBX_START - MD_CSIZ ; ROUTINES TO
@ -119,13 +136,19 @@ RESTART:
CALL MD_CALBAS ; BANK AND
LD HL , MD_FIDEN ; SECTOR
CALL MD_FNCALL
LD HL , $ B7BF ; ABORT
LD HL , $ B7BF ; FAIL
XOR A ; IF FLASH
SBC HL , BC ; CHIP IS
JP NZ , BADCHIP ; NOT SUPPORTED
;
MENULP:
CALL MENU ; DISPLAY MENU
JP NZ , FAILBC ; NOT SUPPORTED
LD BC , $ F8F0 ; GET CPU SPEED
RST 08 ; AND MULTIPLY
LD A , L ; BY 4
ADD A , A ; TO CREATE
ADD A , A ; TIMOUT DELAY
LD ( TmoFct ), A ; FACTOR
;
MENULP: CALL MENU ; DISPLAY MENU
CALL GETINP ; GET SELECTION
;
CP 'U' ; BEGIN
@ -135,7 +158,7 @@ MENULP:
CALL Z , OPTIONV ; VERIFY TOGGLE
;
CP 'X' ; CHECK FOR
JP Z , ABORT ; USER EXIT
JP Z , FAILUX ; USER EXIT
CP 'R' ; CHECK FOR
JP Z , REBOOT ; COLD REBOOT REQUEST
@ -145,6 +168,14 @@ MENULP:
;
CP 'S' ; CHECK FOR
CALL Z , OPTIONS ; SERIAL CHANGE
;
# IF ( XFUDBG )
CP 'T' ; TEST TIMEOUT
CALL Z , OPTIONT ; LOOP
;
CP 'H' ; HALF
CALL Z , OPTIONH ; SPEED SWITCH
# ENDIF
;
JR MENULP
;
@ -154,175 +185,183 @@ CLRSER: CALL SERST ; EMPTY SERIAL BUFFER
CALL SERIN
JR CL RSER
;
SERCLR: LD HL , msgInstr ; PROVIDE
call PRTSTR0 ; INSTRUCTION
SERCLR: XOR A ; CLEAR VERIFY
LD ( VERRES ), A ; FAILURE FLAG
;
LD HL , msgInstr ; PROVIDE
CALL PRTSTR0 ; INSTRUCTION
;
LD A ,( SERDEV ) ; IF CONSOLE AND SERIAL
LD HL , CONDEV ; DEVICE ARE THE SAME,
SUB ( HL ) ; BLOCK ALL TEXT
SUB ( HL ) ; BLOCK ALL TEXT
LD ( BL KCOUT ), A ; OUTPUT DURING TRANSFER
;
ld A , 1 ; THE FIRST PACKET IS NUMBER 1
ld ( pktNo ), A
ld A , 255 - 1 ; ALSO STORE THE 1-COMPLEMENT OF IT
ld ( pktNo1c ), A
LD A , 1 ; THE FIRST PACKET IS NUMBER 1
LD ( pktNo ), A
LD A , 255 - 1 ; ALSO STORE THE 1-COMPLEMENT OF IT
LD ( pktNo1c ), A
;
LD DE , sector4k ; POINT TO START OF SECTOR TO WRITE
;
GetNewPacket:
ld A , 20 ; WE RETRY 20 TIMES BEFORE GIVING UP
ld ( retrycnt ), A
LD ( retrycnt ), A
;
NPloop: ld A , 5 ; 5 SECONDS OF TIMEOUT BEFORE EACH NEW BLOCK
call GetCharTmo
NPloop: LD B , 5 ; 5 SECONDS OF TIMEOUT BEFORE EACH NEW BLOCK
CALL GetCharTmo
jp NC , NotPacketTimeout
;
ld HL , retrycnt ; REACHED MAX NUMBER OF RETRIES?
dec ( HL )
jp Z , Failure0 ; YES, PRINT MESSAGE AND EXIT
ld C , NAK ; SEND A NAK TO THE UPLOADER
call SEROUT
jp NPloop
jp Z , FAILRT ; YES, PRINT MESSAGE AND EXIT
;
LD C , NAK ; SEND A NAK TO THE UPLOADER
CALL SEROUT
JR NPloop
;
NotPacketTimeout:
cp EOT ; DID UPLOADER SAY WE'RE FINISHED?
jp Z , Done ; YES, THEN WE'RE DONE
cp CAN ; UPLOADER WANTS TO ABORT TRANSFER?
jp Z , Cancelled ; YES, THEN WE'RE ALSO DONE
cp CAN ; UPLOADER WANTS TO FAIL TRANSFER?
jp Z , FAILCN ; YES, THEN WE'RE ALSO DONE
cp SOH ; DID WE GET A START-OF-NEW-PACKET?
jp NZ , NPloop ; NO, GO BACK AND TRY AGAIN
JR NZ , NPloop ; NO, GO BACK AND TRY AGAIN
;
ld HL , packet ; SAVE THE RECEIVED CHAR INTO THE...
ld ( HL ), A ; ...PACKET BUFFER AND...
inc HL ; ...POINT TO THE NEXT LOCATION
push HL
ld B , 131 ; GET 131 MORE CHARACTERS FOR A FULL PACKET
INC HL ; ...POINT TO THE NEXT LOCATION
;
LD B , 1 ; GET CHARACTER
CALL GetCharTmo ; SHOULD BE PACKET NUMBER
ld ( HL ), A
INC HL
JP C , FAILTO
;
LD B , 1 ; GET CHARACTER
CALL GetCharTmo ; SHOULD BE PACKET NUMBER
ld ( HL ), A ; COMPLEMENT
INC HL
JP C , FAILTO
;
LD B , 128 ; GET 128 MORE CHARACTERS FOR A FULL PACKET
GetRestOfPacket:
push BC
ld A , 1
call GetCharTmo
push BC ; GET CHARACTER
LD B , 1
CALL GetCharTmo
pop BC
LD C , A ; ONLY SAVE
LD A , B ; THE DATA BYTES IN THE 4K SECTOR
CP 130 ; BUFFER I.E. SKIP FIRST 3
LD A , C
JP P , DONTSAV
LD ( DE ), A
INC DE
DONTSAV:
pop HL ; SAVE THE RECEIVED CHAR INTO THE...
ld ( HL ), A ; ...PACKET BUFFER AND...
inc HL ; ...POINT TO THE NEXT LOCATION
push HL
djnz GetRestOfPacket
POP HL
JP C , FAILTO
;
LD ( HL ), A
INC HL ; SAVE THE RECEIVED CHAR INTO THE...
LD ( DE ), A ; ...PACKET BUFFER AND...
INC DE ; ...POINT TO THE NEXT LOCATION
;
DJNZ GetRestOfPacket
;
LD B , 1 ; GET CHARACTER
CALL GetCharTmo ; SHOULD BE CHECKSUM
LD ( HL ), A
JP C , FAILTO
;
ld HL , packet + 3 ; CALCULATE CHECKSUM FROM 128 BYTES OF DATA
ld B , 128
ld A , 0
XOR A
csloop: add A ,( HL ) ; JUST ADD UP THE BYTES
inc HL
djnz cs loop
xor ( HL ) ; HL POINTS TO THE RECEIVED CHECKSUM SO
jp NZ , Failure1 ; BY XORING IT TO OUR SUM WE CHECK FOR EQUALITY
ld A ,( pktNo ) ; CHECK IF AGREEMENT OF PACKET NUMBERS
ld C , A
ld A ,( packet + 1 )
cp C
jp NZ , Failure2
ld A ,( pktNo1c ) ; CHECK IF AGREEMENT OF 1-COMPL PACKET NUMBERS
ld C , A
ld A ,( packet + 2 )
cp C
jp NZ , Failure3
DJNZ cs loop
;
XOR ( HL ) ; HL POINTS TO THE RECEIVED CHECKSUM SO
JP NZ , FAILCS ; BY XORING IT TO OUR SUM WE CHECK FOR EQUALITY
;
LD HL ,( pktNo ) ; CHECK
LD BC ,( packet + 1 ) ; AGREEMENT
; XOR A ; PACKET
SBC HL , BC ; NUMBERS
JP NZ , FAILPN
;
LD HL , pktNo ; HAVE WE RECEIVED
LD A ,( HL ) ; A BLOCK OF 32
DEC A ; XMODEM PACKETS
AND % 00011111 ; IF YES THEN WERE WE
CP % 00011111 ; HAVE ENOUGH TO
CALL Z , WSEC ; WRITE A FLASH SECTOR
LD A ,( VERRES ) ; EXIT IF WE GOT A
OR A ; WRITE VERIFICATION
JP NZ , FailWrite ; ERROR
LD A , 0 ; WRITE A FLASH SECTOR
CALL Z , WSEC ; ASSUME FLASH SUCCESSFUL
;
OR A ; EXIT IF WE GOT A
JP NZ , FAILWF ; WRITE VERIFICATION ERROR
ld HL , pktNo ; UPDATE THE PACKET COUNTERS
inc ( HL )
ld HL , pktNo1c
INC ( HL )
INC HL
dec ( HL )
ld C , ACK ; TELL UPLOADER THAT WE'RE HAPPY WITH WITH
call SEROUT ; PACKET AND GO BACK AND FETCH SOME MORE
jp GetNewPacket
Done:
ld C , ACK ; TELL UPLOADER WE'RE DONE
call SEROUT
LD A , $ FF ; TURN ON OUTPUT
LD ( BL KCOUT ), A
ld HL , msgSucces1 ; PRINT SUCCESS MESSAGE
call PRTSTR0
;
LD C , ACK ; TELL UPLOADER THAT WE'RE HAPPY WITH WITH
CALL SEROUT ; PACKET AND GO BACK AND FETCH SOME MORE
;
JP GetNewPacket
;
Done: LD C , ACK ; TELL UPLOADER
CALL SEROUT ; WE'RE DONE
LD HL , msgSucces1 ; BACK TO
JR MSGRS ; MENU
;
FAILTO: LD HL , msgTimout ; TIMOUT WAITING
JR ERRRX ; FOR CHARACTER
;
FAILWF: LD HL , msgFailWrt ; FLASH
JR MSGRS ; VERIFY FAIL
;
FAILRT: LD HL , msgRetry ; RETRY
JR ERRRX ; TIMEOUT FAIL
;
FAILCS: LD HL , msgChkSum ; CHECKSUM
JR ERRRX ; ERROR
;
FAILPN: LD HL , msgPacErr ; PACKET
JR ERRRX ; NUMBER ERROR
;
FAILCN: LD HL , msgCancel ; TRANSMISSION
JR ERRRX ; FAILCN
;
FAILUX: LD HL , msgUserEx ; USER
JR Di e ; EXIT
;
FAILBC: LD HL , msgUnsupC ; UNSUPPORTED
JR Di e ; FLASH CHIP
;
ERRRX: LD A , $ FF
LD ( BL KCOUT ), A ; TURN ON OUTPUT
CALL PRTSTR0 ; DISPLAY TRANSMISSION
LD HL , msgFailure ; RECEIPT ERROR
CALL PRTSTR0
JP RESTART
FailWrite:
ld HL , msgFailWrt
jp Di e
Failure0:
; LD C,'0'
; CALL CONOUT
JR Failure
Failure1:
; LD C,'1'
; CALL CONOUT
JR Failure
Failure2:
; LD C,'2'
; CALL CONOUT
JR Failure
Failure3:
; LD C,'3'
; CALL CONOUT
JR Failure
Failure:
ld HL , msgFailure
JR Di e
Cancelled:
ld HL , msgCancel
JR Di e
ABORT:
ld HL , msgAbort
JR Di e
BADCHIP:
LD HL , msgBadChip
JR Di e
REBOOT:
LD HL , msgReboot ; REBOOT MESSAGE
;
MSGRS: LD A , $ FF
LD ( BL KCOUT ), A ; TURN ON OUTPUT
CALL PRTSTR0 ; DISPLAY TRANSMISSION
JP RESTART
;
REBOOT: LD HL , msgReboot ; REBOOT MESSAGE
CALL PRTSTR0
LD C , BF_SYSRES_COLD ; COLD RESTART
JR Di e1
;
;
Die: LD A , $ FF
LD ( BL KCOUT ), A ; TURN ON OUTPUT
call PRTSTR0 ; Prints message and exits from program
CALL PRTSTR0 ; Prints message and exits from program
LD C , BF_SYSRES_WARM ; WARM START
Die1: LD B , BF_SYSRESET ; SYSTEM RESTART
ld SP ,( oldSP )
CALL $ FFF0 ; CALL HBIOS
ret
RET
WSEC: PUSH HL
PUSH BC
PUSH DE
WSEC: PUSH HL ; WRITE A
PUSH BC ; FLASH
PUSH DE ; SECTOR
;
LD A ,( BL KCOUT ) ; SKIP OUTPUT
OR A ; IF TRANSFERRING
JR Z , WSEC1 ; OVER CONSOLE
;
LD HL , MD_SECT ; IF SECTOR IS 0
LD A ,( HL ) ; THEN DISPLAY
@ -332,7 +371,6 @@ WSEC: PUSH HL
CALL PRTSTR0
LD HL , MD_BANK
LD A ,( HL )
CALL PRTHEXB
;
NXTS1: LD C , ' ' ; DISPLAY
CALL CONOUT ; CURRENT
@ -346,24 +384,26 @@ NXTS1: LD C,' ' ; DISPLAY
RRCA
CALL PRTHEXB
;
LD HL , MD_FERAS ; ERASE
WSEC1: LD HL , MD_FERAS ; ERASE
CALL MD_FNCALL ; AND WRITE
LD IX , sector4k ; THIS
LD HL , MD_FWRIT ; BANK / SECTOR
CALL MD_FNCALL
CALL MD_FNCALL
;
LD A ,( WRT VER ) ; VERIFY
LD A ,( WRT VER ) ; VERIFY
OR A ; WRITE IF
JR Z , NOVER ; OPTION
LD IX , sector4k ; SELECTED
LD HL , MD_FVERI
;
LD IX , sector4k ; VERIFY
LD HL , MD_FVERI ; WRITE
CALL MD_FNCALL
LD ( VERRES ), A ; SAVE STATUS
CALL PRTHEXB
;
NOVER: POP DE ; POINT BACK TO
NOVER: POP DE ; POINT BACK TO
LD DE , sector4k ; START OF 4K BUFFER
PUSH DE
;
LD HL , MD_FBAS
LD A ,( HL ) ; DID WE JUST
SUB $ 70 ; DO LAST
@ -378,7 +418,8 @@ NXTS2: LD A,$10 ; NEXT SECTOR
ADD A ,( HL ) ; EACH SECTOR IS $1000
LD ( HL ), A ; BUT WE JUST INCREASE HIGH BYTE
;
NXTS3: POP DE
NXTS3: LD A ,( VERRES ) ; EXIT WITH STATUS
POP DE
POP BC
POP HL
RET
@ -387,40 +428,39 @@ NXTS3: POP DE
; RETURNS IT IN A WITHOUT ECHO AND CARRY CLEAR. IF TIMEOUT THEN CARRY
; IT SET.
;
; 4MHZ 20 SECONDS B=16
; 10MHZ 20 SECONDS B=39
;
GetCharTmo:
ld B , A
GCtmoa: push BC
ld B , 40
GCtmob: push BC
ld B , 255
GCtmoc: push BC
call SERST
OR A
; cp 00h ; A CHAR AVAILABLE?
jp NZ , GotChar ; YES, GET OUT OF LOOP
ld HL ,( 0 ) ; WASTE SOME CYCLES
ld HL ,( 0 ) ; ...
ld HL ,( 0 ) ; ...
ld HL ,( 0 ) ; ...
ld HL ,( 0 ) ; ...
ld HL ,( 0 ) ; ...
pop BC
CALL SERST ; IF THER IS A
OR A ; CHARACTER AVAILABLE
JR NZ , GotChrX ; EXIT NO OTHERWISE POLL
PUSH BC
ld BC , 255 ; C=CONSTANT (255) FOR INNER TIMING LOOP
TmoFct: .EQU $ - 1 ; B=SPEED FACTOR WHICH GETS UPDATED AT START
GCtmob: PUSH BC
ld B , C
GCtmoc: PUSH BC
CALL SERST
OR A ; A CHAR AVAILABLE?
JR NZ , GotChar ; YES, GET OUT OF LOOP
POP BC
djnz GCtmoc
pop BC
POP BC
djnz GCtmob
pop BC
djnz GCtmoa
POP BC
djnz GetCharTmo
scf ; SET CARRY SIGNALS TIMEOUT
ret
RET
;
GotChar: pop BC
pop BC
pop BC
call SERIN
GotChar: POP BC
POP BC
POP BC
GotChrX: CALL SERIN
or A ; CLEAR CARRY SIGNALS SUCCESS
ret
RET
;
GETINP: CALL CONIN ; GET A CHARACTER
GETINP: CALL CONIN ; GET A CHARACTER
LD C , A ; RETURN SEQUENCE
CALL CONOUT ; COVERT TO UPPERCASE
LD C , BSPC ; RETURN CHARACTER IN A
@ -441,13 +481,13 @@ GETINP2:CALL CONIN
CP 'z' + 1 ; ABOVE 'Z'?
JR NC , GETINP3 ; IF SO, NOTHING TO DO
AND ~ $ 20 ; CONVERT CHARACTER TO LOWER
GETINP3: RET
GETINP3: RET
;
PRTSTR0: ld A ,( HL ) ; PRINT MESSAGE POINTED TOP HL UNTIL 0
or A ; CHECK IF GOT ZERO?
ret Z ; IF ZERO RETURN TO CALLER
ld C , A
call CONOUT ; ELSE PRINT THE CHARACTER
RET Z ; IF ZERO RETURN TO CALLER
LD C , A
CALL CONOUT ; ELSE PRINT THE CHARACTER
inc HL
jp PRTSTR0
;
@ -485,8 +525,12 @@ OPTIONV:LD A,(WRTVER) ; TOGGLE
;
OPTIONC: LD HL , msgEnterUnit ; GET
CALL PRTSTR0 ; CONSOLE
CALL GETINP ; UNIT
SUB '0' ; NUMBER
CALL GETINP ; UNIT NUMBER
CP '0'
JR C , CONCLR
CP '9' + 1
JR NC , CONCLR
SUB '0'
LD ( CONDEV ), A
CLRCON: CALL CONST ; EMPTY CONSOLE BUFFER
OR A ; SO WE DON'T HAVE ANY
@ -499,11 +543,31 @@ CONCLR: XOR A
OPTIONS: LD HL , msgEnterUnit ; GET
CALL PRTSTR0 ; CONSOLE
CALL GETINP ; UNIT
SUB '0' ; NUMBER
CP '0'
JR C , CONCLR
CP '9' + 1
JR NC , CONCLR
SUB '0' ; NUMBER
LD ( SERDEV ), A
XOR A
RET
;
# IF ( XFUDBG )
OPTIONT: LD C , '*'
CALL CONOUT
LD B , 20
CALL GetCharTmo
LD C , '*'
CALL CONOUT
RET
;
OPTIONH: LD A , 8 ; TURN ON THE
OUT ( RTCIO ), A ; SBC-V2-004+
LD HL , TmoFct ; CLOCK DIVIDER
SRL ( HL ) ; AND ADJUST
RET ; DELAY FACTOR (/2)
# ENDIF
;
SEROUT: PUSH HL ; SERIAL OUTPUT CHARACTER IN C
PUSH DE
PUSH BC
@ -544,7 +608,7 @@ SERIN: PUSH HL ; SERIAL INPUT. WAIT FOR A CHARACTER ADD RETURN IT IN A
;
CONOUT: PUSH HL ; CONSOLE OUTPUT CHARACTER IN C
PUSH DE ; OUTPUT IS BLOCKED DURING THE
PUSH BC ; FILE TRANSFER WHEN THE
PUSH BC ; FILE TRANSFER WHEN THE
PUSH AF
LD A ,( BL KCOUT ) ; CONSOLE AND SERIAL LINE
OR A ; ARE THE SAME
@ -648,18 +712,18 @@ MD_FSTART: .EQU $ ; FLASH ROUTINES WHICH GET RELOCATED TO HIGH MEMORY
;======================================================================
; COMMON FUNCTION CALL FOR:
;
; MD_FIDEN_R - IDENTIFY FLASH CHIP
; MD_FIDEN_R - IDENTIFY FLASH CHIP
; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED
; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED
; ON EXIT BC CONTAINS THE CHIP ID BYTES.
; A NO STATUS IS RETURNED
; A NO STATUS IS RETURNED
;
; MD_FERAS_R - ERASE FLASH SECTOR
; MD_FERAS_R - ERASE FLASH SECTOR
; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED
; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED
; ON EXIT A RETURNS STATUS 0=SUCCESS NZ=FAIL
;
; MD_FREAD_R - READ FLASH SECTOR
; MD_FREAD_R - READ FLASH SECTOR
; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED
; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED
; IX POINTS TO WHERE TO SAVE DATA
@ -671,7 +735,7 @@ MD_FSTART: .EQU $ ; FLASH ROUTINES WHICH GET RELOCATED TO HIGH MEMORY
; IX POINTS TO DATA TO COMPARE.
; ON EXIT A RETURNS STATUS 0=SUCCESS NZ=FAIL
;
; MD_FWRIT_R - WRITE FLASH SECTOR
; MD_FWRIT_R - WRITE FLASH SECTOR
; ON ENTRY MD_FBAS HAS BEEN SET WITH BANK AND SECTOR BEING ACCESSED
; HL POINTS TO THE ROUTINE TO BE RELOCATED AND CALLED
; IX POINTS TO DATA TO BE WRITTEN
@ -699,7 +763,7 @@ MD_FNCALL:
EX AF , AF '
;
LD A , C ; RETURN WITH STATUS IN A
RET ; RETURN TO MD_READF, MD_WRITEF
RET
;
MD_FJPHL:
JP ( HL )
@ -713,9 +777,9 @@ MD_FJPHL:
; SELECT ORIGINAL BANK
;
; ON ENTRY BC CONTAINS BANK AND SECTOR DATA
; A CONTAINS CURRENT BANK
; A CONTAINS CURRENT BANK
; ON EXIT BC CONTAINS ID WORD
; NO STATUS IS RETURNED
; NO STATUS IS RETURNED
;======================================================================
;
MD_FIDEN_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY
@ -733,14 +797,14 @@ MD_FIDEN_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY
; ; LD ($5555),A
LD BC ,( $ 0000 ) ; READ ID
;
LD A , $ F0 ; LD A,$F0 ; EXIT
LD A , $ F0 ; LD A,$F0 ; EXIT
LD ( HL ), A ; LD ($5555),A ; COMMAND
;
LD A , D ; RETURN TO ORIGINAL BANK
JP HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY
;
;======================================================================
; ERASE FLASH SECTOR.
; ERASE FLASH SECTOR.
;
; SELECT THE APPROPRIATE BANK / ADDRESS
; ISSUE ERASE SECTOR COMMAND
@ -748,7 +812,7 @@ MD_FIDEN_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY
; SELECT ORIGINAL BANK
;
; ON ENTRY BC CONTAINS BANK AND SECTOR DATA
; A CONTAINS CURRENT BANK
; A CONTAINS CURRENT BANK
; ON EXIT C RETURNS STATUS 0=SUCCESS NZ=FAIL
;======================================================================
;
@ -759,15 +823,15 @@ MD_FERAS_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY
CALL HBX_BNKSEL ; TO PROGRAM
;
LD HL , $ 5555 ; LD ($5555),A
LD DE , $ 2 AAA ; LD A,$55
LD A , L ; LD ($2AAA),A
LD ( HL ), E ; LD A,$80
LD ( DE ), A ; LD ($5555),A
LD ( HL ), $ 80 ; LD A,$AA
LD ( HL ), E ; LD ($5555),A
LD ( DE ), A ; LD A,$55
; ; LD ($2AAA),A
LD H , C ; SECTOR
LD DE , $ 2 AAA ; LD A,$55
LD A , L ; LD ($2AAA),A
LD ( HL ), E ; LD A,$80
LD ( DE ), A ; LD ($5555),A
LD ( HL ), $ 80 ; LD A,$AA
LD ( HL ), E ; LD ($5555),A
LD ( DE ), A ; LD A,$55
; ; LD ($2AAA),A
LD H , C ; SECTOR
LD L , $ 00 ; ADDRESS
;
LD A , $ 30 ; SECTOR ERASE
@ -785,9 +849,9 @@ MD_WT4: LD A,(HL) ; DO TWO SUCCESSIVE READS
BIT 5 , C ; IF NO TIMEOUT YET THEN LOOP BACK AND KEEP CHECKING TOGGLE STATUS
JR Z , MD_WT4 ; IF BIT 5=0 THEN RETRY; NZ TRUE IF BIT 5=1
;
LD A ,( HL ) ; WE GOT A TIMOUT. RECHECK TOGGLE BIT IN CASE WE DID COMPLETE
LD A ,( HL ) ; WE GOT A TIMOUT. RECHECK TOGGLE BIT IN CASE WE DID COMPLETE
XOR ( HL ) ; THE OPERATION. DO TWO SUCCESSIVE READS. ARE THEY THE SAME?
BIT 6 , A ; IF THEY ARE THEN OPERATION WAS COMPLETED
BIT 6 , A ; IF THEY ARE THEN OPERATION WAS COMPLETED
JR Z , MD_WT5 ; OTHERWISE ERASE OPERATION FAILED OR TIMED OUT.
;
LD C , $ F0 ; COMMON FAIL STATUS / PREPARE DEVICE RESET CODE
@ -799,7 +863,7 @@ MD_WT6: EX AF,AF' ; RETURN TO ORIGINAL BANK
JP HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY
;
;======================================================================
; FLASH READ SECTOR.
; FLASH READ SECTOR.
;
; SELECT THE APPROPRIATE BANK / ADDRESS
; READ SECTOR OF 4096 BYTES, BYTE AT A TIME
@ -810,7 +874,7 @@ MD_WT6: EX AF,AF' ; RETURN TO ORIGINAL BANK
; ON ENTRY BC CONTAINS BANK AND SECTOR DATA
; DE = 0000 BYTE COUNT
; IX POINTS TO DATA TO BE WRITTEN
; A CONTAINS CURRENT BANK
; A CONTAINS CURRENT BANK
; ON EXIT NO STATUS RETURNED
; AF' TRASHED
;======================================================================
@ -823,10 +887,10 @@ MD_FREAD_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY
EX AF , AF ' ; PUT DESTINATION BANK IN AF'
LD A , B ; PUT SOURCE BANK IN AF
;
MD_FRD1:
MD_FRD1:
CALL HBX_BNKSEL ; READ ; SWITCH TO SOURCE BANK
LD C ,( HL ) ; BYTE
;
;
EX AF , AF ' ; SELECT BANK ; SWITCH DESTINATION BANK
CALL HBX_BNKSEL ; TO WRITE
LD ( IX + 0 ), C ; WRITE BYTE
@ -839,10 +903,10 @@ MD_FRD1:
BIT 4 , D ; WE HAVE DONE ONE SECTOR
JR Z , MD_FRD1
;
RET
RET
;
;======================================================================
; FLASH VERIFY SECTOR.
; FLASH VERIFY SECTOR.
;
; SELECT THE APPROPRIATE BANK / ADDRESS
; VERIFY SECTOR OF 4096 BYTES, BYTE AT A TIME
@ -853,7 +917,7 @@ MD_FRD1:
; ON ENTRY BC CONTAINS BANK AND SECTOR DATA
; DE = 0000 BYTE COUNT
; IX POINTS TO DATA TO BE VERIFIED
; A CONTAINS CURRENT BANK
; A CONTAINS CURRENT BANK
; ON EXIT C RETURNS STATUS 0=SUCCESS NZ=FAIL
;======================================================================
;
@ -864,7 +928,7 @@ MD_FVERI_R: ; THIS CODE GETS RELOCATED TO HIGH MEMORY
;
EX AF , AF ' ; PUT SOURCE BANK IN AF' ( RAM )
;
MD_FVE1:
MD_FVE1:
LD A , B ; SELECT BANK
CALL HBX_BNKSEL ; TO READ ; SWITCH TO FLASH BANK
LD A ,( HL ) ; READ BYTE
@ -884,13 +948,13 @@ MD_FVE1:
JR Z , MD_FVE1
;
MD_FVE2:
LD C , A ; SET STATUS
LD C , A ; SET STATUS
EX AF , AF '
;
RET
RET
;
;======================================================================
; FLASH WRITE SECTOR.
; FLASH WRITE SECTOR.
;
; SELECT THE APPROPRIATE BANK / ADDRESS
; WRITE 1 SECTOR OF 4096 BYTES, BYTE AT A TIME
@ -901,7 +965,7 @@ MD_FVE2:
; ON ENTRY BC CONTAINS BANK AND SECTOR DATA
; IX POINTS TO DATA TO BE WRITTEN
; DE = 0000 BYTE COUNT
; A CONTAINS CURRENT BANK
; A CONTAINS CURRENT BANK
; ON EXIT NO STATUS IS RETURNED
;======================================================================
;
@ -929,12 +993,12 @@ MD_FWRI1:
;
LD ( HL ), C ; WRITE OUT BYTE
;
; ; DO TWO SUCCESSIVE READS
MD_FW7: LD A ,( HL ) ; FROM THE SAME FLASH ADDRESS.
LD C ,( HL ) ; IF TOGGLE BIT (BIT 6)
; ; DO TWO SUCCESSIVE READS
MD_FW7: LD A ,( HL ) ; FROM THE SAME FLASH ADDRESS.
LD C ,( HL ) ; IF TOGGLE BIT (BIT 6)
XOR C ; IS THE SAME ON BOTH READS
BIT 6 , A ; THEN WRITE IS COMPLETE SO EXIT.
JR NZ , MD_FW7 ; Z TRUE IF BIT 6=0 I.E. "NO TOGGLE" WAS DETECTED.
JR NZ , MD_FW7 ; Z TRUE IF BIT 6=0 I.E. "NO TOGGLE" WAS DETECTED.
;
INC HL ; NEXT DESTINATION LOCATION
INC IX ; NEXT SOURCE LOCATION
@ -961,25 +1025,33 @@ MD_FWRIT .EQU HBX_START-MD_CSIZ+MD_FWRIT_R-MD_FSTART ; CALL ADDRESS FOR WRITE F
;
msgHeader: .DB CR , LF , CR , LF , "ROMWBW XMODEM FLASH UPDATER" , CR , LF , 0
msgInstr: .DB CR , LF , CR , LF , "START TRANSFER OF YOUR UPDATE IMAGE OR ROM" , CR , LF , 0
msgAbort : .DB CR , LF , "UPDATER ABOR TED BY USER" , CR , LF , 0
msgUserEx : .DB CR , LF , "UPDATER EXI TED BY USER" , CR , LF , 0
msgBank: .DB CR , LF , "BANK " , 0
msgBadChip : .DB CR , LF , "FLASH CHIP NOT SUPPORTED" , CR , LF , 0
msgUnsupC : .DB CR , LF , "FLASH CHIP NOT SUPPORTED" , CR , LF , 0
msgReboot: .DB CR , LF , "REBOOTING ..." , CR , LF , 0
msgFailWrt: .DB CR , LF , "FLASH WRITE FAILED" , CR , LF , 0
msgFailure: .DB CR , LF , "TRANSMISSION FAILED" , CR , LF , 0
msgCancel: .DB CR , LF , "TRANSMISSION CANCELLED " , CR , LF , 0
msgCancel: .DB CR , LF , "TRANSMISSION FAILCN " , CR , LF , 0
msgConsole: .DB CR , LF , "(C) Set Console Device : " , 0
msgIODevice: .DB CR , LF , "(S) Set Serial Device : " , 0
msgWriteV: .DB CR , LF , "(V) Toggle Write Verify : " , 0
msgBegin: .DB CR , LF , "(R) Reboot"
.DB CR , LF , "(U) Begin Update"
.DB CR , LF , "(X) Exit to Rom Loader"
# IF ( XFUDBG )
.DB CR , LF , "(H) Select half speed"
.DB CR , LF , "(T) Test 20s timeout"
# ENDIF
.DB CR , LF , CR , LF , "Select : " , 0
msgSucces1: .DB CR , LF , CR , LF , "UPDATE COMPLETED WITHOUT ERRORS " , CR , LF , 0
msgEnterUnit: .DB CR , LF , "ENTER UNIT NUMBER : " , 0
msgCRLF: .DB CR , LF , 0
msgYES: .DB "YES" , 0
msgNO: .DB "NO" , 0
msgPacErr: .DB CR , LF , "PACKET COUNT MISMATCH ERROR" , CR , LF , 0
msgChkSum .DB CR , LF , "CHECKSUM ERROR" , CR , LF , 0
msgRetry .DB CR , LF , "ERROR, RETRY COUNT EXCEED" , CR , LF , 0
msgTimout .DB CR , LF , "ERROR, RECEIVE TIMEOUT" , CR , LF , 0
;
; Variables
;
@ -993,7 +1065,7 @@ retrycnt: .DB 0 ; Counter for retries before giving up
chksum: .DB 0 ; For calculating the checksum of the packet
pktNo: .DB 0 ; Current packet Number
pktNo1c: .DB 0 ; Current packet Number 1-complemented
MD_FBAS .DW $ FFFF ; CURRENT BANK AND SECTOR
MD_FBAS .DW $ FFFF ; CURRENT BANK AND SECTOR
MD_SECT .EQU MD_FBAS ; BANK BYTE
MD_BANK .EQU MD_FBAS + 1 ; SECTOR BYTE
;