;***************************************************************************** ; ROMWBW XMODEM FLASH UPDATER ; ; PROVIDES THE CAPABILITY TO UPDATE ROMWBW FROM THE SBC BOOT LOADER USING ; AN XMODEM FILE TRANSFER. ; ; THIS TOOL CAN BE LAUNCHED FROM THE ROMWBW BOOT LOADER USING OPTION 'X'. ; ; OPTION (C) AND (S) - CONSOLE AND SERIAL DEVICE ; ; BY DEFAULT THE UPDATER IS SET TO USE THE CURRENT CONSOLE DEVICE FOR ; DISPLAY OUTPUT AND FILES TRANSFER. IF YOU USE A DIFFERENT SERIAL DEVICE FOR ; THE FILE TRANSFER, PROGRESS INFORMATION WILL BE DISPLAYED. ; ; OPTION (>) AND (<) - SET AND REVERT BAUD RATE ; ; THE MAXIMUM TRANSFER RATE IS LOWER IN THE UPDATER UTILITY COMPARED TO ; THE STANDALONE XMODEM APPLICATION. THIS IS BECAUSE THE SENDER CAN OVERFLOW ; THE INPUT RECEIVE BUFFER WHILE THE PREVIOUSLY SENT DATA IS BEING WRITTEN ; TO THE FLASH DEVICE (THE FLASH SECTOR ALSO HAS TO BE ERASED BEFORE THIS WRITE). ; LOWERING THE BAUD RATE HELPS PREVENT THIS TRANSFER/WRITE FAILURE. ; (>) WILL CHANGE THE PLATFORM BOARD RATE TO THE RECOMMENDED BAUD RATE FOR ; THE PLATFORMS CURRENT SPEED. YOU MUST CHANGE THE SENDERS SPEED TO MATCH. ; (<) WILL REVERT THE PLATFORMS BAUD RATE TO ITS ORIGINAL SPEED. AGAIN YOU ; MUST CHANGE THE SENDERS SPEED TO MATCH ; ; OPTION (V) - WRITE VERIFY ; ; BY DEFAULT EACH FLASH SECTOR WILL BE VERIFIED AFTER BEING WRITTEN. SLIGHT ; PERFORMANCE IMPROVEMENTS CAN BE GAINED IF TURNED OFF AND COULD BE USED IF ; YOU ARE EXPERIENCING RELIABLE TRANSFERS AND FLASHING. ; ; OPTION (R) - REBOOT ; 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. ; ; 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 ; FLASH DEVICE. ; ; IF USING SEPARATE CONSOLE, BANK AND SECTOR PROGRESS 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 ; ; THE XMODEM FILE TRANSFER PROTOCOL DOES NOT PROVIDE ANY FILENAME OR SIZE ; INFORMATION FOR THE TRANSFER SO THE UPDATER DOES NOT PERFORM ANY CHECKS ; ON THE FILE SUITABILITY. ; ; THE UPDATER EXPECTS THE FILE SIZE TO BE A MULTIPLE OF 4 KILOBYTES AND ; WILL WRITE ALL DATA RECEIVED TO THE FLASH DEVICE. A SYSTEM UPDATE ; FILE (128KB .IMG) OR COMPLETE ROM CAN BE RECEIVED AND WRITTEN (512KB OR ; 1024KB .ROM) ; ; IF THE UPDATE FAILS IT IS RECOMMENDED THAT YOU RETRY BEFORE REBOOTING OR ; EXITING TO THE SBC BOOT LOADER AS YOUR MACHINE MAY NOT BE BOOTABLE. ; ; OPTION (Q) - EXIT TO THE SBC BOOT LOADER. THE SBC IS RELOADED FROM ROM AND ; EXECUTED. AFTER A SUCCESSFUL UPDATE A REBOOT SHOULD BE PERFORMED. HOWEVER, ; 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. ; ; OPTION (D) - DUPLICATE FLASH #1 TO FLASH #2 WILL MAKE A COPY OF FLASH #1 ; ONTO FLASH #2. THE PURPOSE OF THIS IS TO ENABLE MAKING A BACKUP COPY OF ; THE CURRENT FLASH. ; ; OPTION (1) AND (2) - CALCULATE AND DISPLAY CRC32 OF 1ST OR 2ND 512K ROM. ; OPTION (3) - CALCULATE AND DISPLAY CRC32 OF A 1024K ROM. ; ; OPTION (H) - DEBUG OPTION - SWITCH ON CPU CLOCK DIVIDER ON ; OPTION (T) - DEBUG OPTION - TEST TIMER FOR 32S, 16S, 8S, 4S, 2S & 1S ; ; V.1 5/1/2023 PHIL SUMMERS, DIFFICULTYLEVELHIGH@GMAIL.COM ; b1ackmai1er ON RETROBREWCOMPUTERS.ORG ; ; ; NOTES: ; TESTED WITH TERATERM XMODEM. ; PARTIAL WRITES CAN BE COMPLETED WITH 39SF040 CHIPS. ; OTHER CHIPS REQUIRE ENTIRE FLASH TO BE ERASED BEFORE BEFORE BEING WRITTEN. ; SBC V2-005 MEGAFLASH REQUIRED FOR 1MB FLASH SUPPORT. ; ASSUMES BOTH CHIPS ARE SAME TYPE ; FAILURE HANDLING HAS NOT BEEN TESTED. ; TIMING BROADLY CALIBRATED ON A Z80 SBC-V2 ; UNABIOS NOT SUPPORTED ; ; TERATERM: ; ; MACROS CAN BE USED TO AUTOMATE SENDING ROM UPDATES OR ROMS IMAGES. ; TRANSMISSION STARTUP IS MORE RELIABLE WHEN THE CHECKSUM OPTION (1) IS SPECIFIED ; ; EXAMPLE MACRO FILE TO SEND *.UPD FILE, SELECT CHECKSUM MODE AND DISPLAY CRC32 ; ; ;XMODEM send, checksum, display CRC32 ; xmodemsend '\\DESKTOP-FI43VI2\Users\Phillip\Documents\GitHub\RomWBW\Binary\SBC_std_cust.upd' 1 ; crc32file crc '\\DESKTOP-FI43VI2\Users\Phillip\Documents\GitHub\RomWBW\Binary\SBC_std_cust.rom' ; sprintf '0x%08X' crc ; messagebox inputstr 'CRC32' ; ; 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 ; SBC-MK4 ASCI NO FLOW CONTROL 18.432MHZ | 9600 ; SBC-MK4 ASCI WITH FLOW CONTROL 18.432MHZ | 38400 ; ; ACKNOWLEDGEMENTS: ; ; XR - Xmodem Receive for Z80 CP/M 2.2 using CON: ; Copyright 2017 Mats Engstrom, SmallRoomLabs ; Licensed under the MIT license ; https://github.com/SmallRoomLabs/xmodem80/blob/master/XR.Z80 ; ; md.asm - ROMWBW memory disk driver ; https://github.com/wwarthen/RomWBW/blob/master/Source/HBIOS/md.asm ; ; CRC32 - J.G. HARSTON - mdfs.net/Info/Comp/Comms/CRC32.htm ; ;***************************************************************************** ; #INCLUDE "std.asm" ; HBX_BNKSEL .EQU $FE2B ; #DEFINE HB_DI DI #DEFINE HB_EI EI ; XFUDBG .EQU 0 ; Enabling will cause a build failure ; Insufficient space for debug features ; .ORG UPD_LOC ; ; ASCII codes ; LF: .EQU 'J'-40h ; ^J LF CR: .EQU 'M'-40h ; ^M CR/ENTER SOH: .EQU 'A'-40h ; ^A CTRL-A EOT: .EQU 'D'-40h ; ^D = End of Transmission ACK: .EQU 'F'-40h ; ^F = Positive Acknowledgement NAK: .EQU 'U'-40h ; ^U = Negative Acknowledgement CAN: .EQU 'X'-40h ; ^X = Cancel BSPC: .EQU 'H'-40h ; ^H = Backspace ; ; Start of code ; LD (oldSP),SP ; SETUP STACK BELOW HBIOS LD SP,HBX_LOC-MD_CSIZ ; ALLOW FOR RELOCATABLE CODE AREA ; LD HL,MD_FSTART ; COPY FLASH LD DE,HBX_LOC-MD_CSIZ ; ROUTINES TO LD BC,MD_CSIZ ; HIGH MEMORY LDIR ; LD BC,$F8F2 ; LOOKUP RST 08 ; CURRENT LD B,$FA ; CONSOLE LD HL,$112 ; DEVICE RST 08 ; TO USE AS LD A,E ; DEFAULT LD (CONDEV),A ; LD BC,$F8F2 ; LOOKUP RST 08 ; CURRENT LD B,$FA ; SERIAL LD HL,$110 ; DEVICE RST 08 ; TO USE AS LD A,E ; DEFAULT LD (SERDEV),A CALL GETDINFO ; SAVE INITIAL LD (ORISPD),A ; SERIAL SPEED ; LD HL,msgHeader ; PRINT CALL PRTSTR0 ; GREETING ; RESTART: LD DE,$0000 ; SET UP START LD (MD_FBAS),DE ; BANK AND SECTOR ; LD HL,MD_FIDEN ; IDENTIFY CHIP CALL MD_FNCALL ; AT THIS BANK/SECTOR ; LD A,0-1 ; SEARCH DEVICE LD HL,DEVICES ; TABLE FOR NXTDEV: LD D,(HL) ; VALID DEVICE INC HL ; LD E,(HL) INC HL INC A CP +((LSTDEV-DEVICES)/2) JP Z,FAILBC ; SUPPORTED CHIP NOT FOUND OR A EX DE,HL SBC HL,BC EX DE,HL JR NZ,NXTDEV ; CHPFND: LD (ERATYP),A ; SAVE ERASE TYPE ; LD BC,$F8F0 ; GET CPU SPEED RST 08 ; AND MULTIPLY LD A,L ; BY 4 PUSH AF ADD A,A ; TO CREATE ADD A,A ; TIMEOUT DELAY LD (TmoFct),A ; FACTOR POP AF ; LD HL,CLKTBL-1 ; DETERMINE ADD A,L ; RECOMMENDED LD L,A ; SPEED BASED ADC A,H ; ON CPU CLOCK SUB L LD H,A ; LOOK IT LD A,(HL) ; UP IN THE LD (RECSPD),A ; CLOCK TABLE ; MENULP: LD DE,$0000 ; ENSURE WE ARE STARTING LD (MD_FBAS),DE ; AT BANK 0 SECTOR 0 LD HL,ERATYP ; RESET THE ERASE RES 7,(HL) ; SKIP FLAG ; CALL MENU ; DISPLAY MENU CALL GETINP ; GET SELECTION ; CP '>' ; CHANGE TO JP Z,OPTIONG ; RECOMMENDED BAUD RATE ; CP '<' ; REVERT TO JP Z,OPTIONL ; ORIGINAL BAUD RATE ; CP 'U' ; BEGIN JR Z,BEGUPD ; TRANSFER ; CP 'V' ; CHECK FOR JP Z,OPTIONV ; VERIFY TOGGLE ; CP 'Q' ; CHECK FOR JP Z,FAILUX ; USER EXIT ; CP 'R' ; CHECK FOR JP Z,REBOOT ; COLD REBOOT REQUEST ; CP 'C' ; CHECK FOR JP Z,OPTIONC ; CONSOLE CHANGE ; CP 'S' ; CHECK FOR JP Z,OPTIONS ; SERIAL CHANGE ; CP 'D' ; DUPLICATE JP Z,OPTIOND ; FLASH ; CP '1' ; CALCULATE JP Z,OPTION1 ; CRC FLASH #1 ; CP '2' ; CALCULATE JP Z,OPTION2 ; CRC FLASH #2 ; CP '3' ; CALCULATE JP Z,OPTION3 ; CRC 1024K FLASH ; #IF (XFUDBG) CP 'T' ; TEST TIMEOUT JP Z,OPTIONT ; LOOP ; CP 'H' ; HALF JP Z,OPTIONH ; SPEED SWITCH ; CP 'F' ; DEBUG JP Z,OPTIONF ; DUMP ; CP 'E' ; ERASE JP Z,OPTIONE ; CHIP #1 ; CP 'Z' ; ERASE JP Z,OPTIONR ; CHIP #2 #ENDIF ; JR MENULP ; BEGUPD: CALL SERST ; EMPTY SERIAL BUFFER OR A ; SO WE HAVE A CLEAN JR Z,SERCLR ; START ON TRANSFER CALL SERIN JR BEGUPD ; SERCLR: 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 LD (BLKCOUT),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 DE,sector4k ; POINT TO START OF SECTOR TO WRITE ; GetNewPacket: LD HL,retrycnt ; WE RETRY 20 TIMES BEFORE GIVING UP LD (HL),20 ; NPloop: LD B,6 ; 6 SECONDS OF TIMEOUT BEFORE EACH NEW BLOCK CALL GetCharTmo JP NC,NotPacketTimeout ; DEC (HL) ; REACHED MAX NUMBER OF RETRIES? 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 FAIL TRANSFER? JP Z,FAILCN ; YES, THEN WE'RE ALSO DONE CP SOH ; DID WE GET A START-OF-NEW-PACKET? JR NZ,NPloop ; NO, GO BACK AND TRY AGAIN ; #IF (XFUDBG) LD HL,packet ; SAVE THE RECEIVED CHAR INTO THE... LD (HL),A ; ...PACKET BUFFER AND... INC HL ; ...POINT TO THE NEXT LOCATION #ELSE LD HL,packet+1 ; SKIP SAVING #ENDIF ; CALL GetCharTmo1 ; GET CHARACTER LD (HL),A ; SHOULD BE PACKET NUMBER INC HL JR C,FAILTO ; CALL GetCharTmo1 ; GET CHARACTER LD (HL),A ; SHOULD BE PACKET NUMBER INC HL ; COMPLEMENT JR C,FAILTO ; LD C,0 ; GET 128 MORE CHARACTERS FOR A FULL PACKET GetRestOfPacket: ; C=0=256 TO ALLOW FOR DOUBLE DECREMENT CALL GetCharTmo1 ; GET CHARACTER JR C,FAILTO ; LD (HL),A ; SAVE THE RECEIVED CHAR INTO THE LDI ; PACKET BUFFER AND FLASH SECTOR BUFFER ; DEC C ; C GETS DECREMENTED TWICE EACH LOOP. ; JP NZ,GetRestOfPacket ; CALL GetCharTmo1 ; GET CHARACTER LD (HL),A ; SHOULD BE CHECKSUM JR C,FAILTO ; LD HL,packet+3 ; CALCULATE CHECKSUM FROM 128 BYTES OF DATA LD B,128 XOR A csloop: ADD A,(HL) ; JUST ADD UP THE BYTES INC HL DJNZ csloop ; XOR (HL) ; HL POINTS TO THE RECEIVED CHECKSUM SO JR 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 JR NZ,FAILPN ; LD A,C ; HAVE WE RECEIVED A BLOCK OF 32 DEC A ; XMODEM PACKETS? AND %00011111 ; IF YES THEN WERE WE CP %00011111 ; HAVE ENOUGH TO LD A,H ; WRITE A FLASH SECTOR CALL Z,WSEC ; ASSUME FLASH SUCCESSFUL OR A ; EXIT IF WE GOT A JR NZ,FAILWF ; WRITE VERIFICATION ERROR ; LD HL,pktNo ; UPDATE THE PACKET COUNTERS 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 ; FAILTO: LD HL,msgTimout ; TIMEOUT WAITING JR ERRRX ; FOR CHARACTER ; COUTON: LD A,$FF ; TURN ON LD (BLKCOUT),A ; OUTPUT RET ; Done: LD C,ACK ; TELL UPLOADER CALL SEROUT ; WE'RE DONE Done1: LD HL,msgSuccess ; BACK TO JR MSGRS ; MENU ; 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 ; FAILURE ; FAILUX: LD HL,msgUserEx ; USER JR Die ; EXIT ; FAILBC: LD HL,msgUnsupC ; UNSUPPORTED JR Die ; FLASH CHIP ; ERRRX: CALL COUTON ; TURN ON OUTPUT CALL PRTSTR0 ; DISPLAY TRANSMISSION LD HL,msgFailure ; RECEIPT ERROR CALL PRTSTR0 JP RESTART ; MSGRS: CALL COUTON ; TURN ON OUTPUT CALL PRTSTR0 ; DISPLAY JP RESTART ; MESSAGE ; REBOOT: LD HL,msgReboot ; REBOOT MESSAGE CALL PRTSTR0 LD C,BF_SYSRES_COLD ; COLD RESTART JR Die1 ; Die: CALL COUTON ; TURN ON OUTPUT 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 WSEC: CALL DISPROG ; DISPLAY PROGRESS ; WSEC1: LD A,(ERATYP) ; SECTOR OR A ; ERASE? JP Z,WSEC4 ; JP M,WSEC3 ; SKIP ERASE? ; LD HL,MD_FERAC ; SETUP CHIP ERASE SET 7,A ; SET FLAG SO LD (ERATYP),A ; WE DONT ERASE AGAIN JR WSEC2 ; WSEC4: LD HL,MD_FERAS ; SET ERASE SECTOR WSEC2: CALL MD_FNCALL ; ERASE CHIP OR SECTOR ; WSEC3: LD IX,sector4k ; WRITE THIS LD HL,MD_FWRIT ; BANK / SECTOR CALL MD_FNCALL ; LD A,(WRTVER) ; VERIFY OR A ; WRITE IF JR Z,NOVER ; OPTION SET ; LD IX,sector4k ; VERIFY LD HL,MD_FVERI ; WRITE CALL MD_FNCALL LD (VERRES),A ; SAVE STATUS ; NOVER: LD DE,sector4k ; POINT BACK TO START OF 4K BUFFER ; LD HL,MD_FBAS LD A,(HL) ; DID WE JUST SUB $70 ; DO LAST JR NZ,NXTS2 ; SECTOR ; LD (HL),A ; RESET SECTOR TO 0 INC HL INC (HL) ; NEXT BANK ; CP $10 ; IF WE ARE AT THE JR NZ,NXTS3 ; START OF A NEW LD HL,ERATYP ; CHIP THEN ALLOW RES 7,(HL) ; CHIP ERASE BY JR NXTS3 ; RESETTING FLAG ; NXTS2: LD A,$10 ; NEXT SECTOR ADD A,(HL) ; EACH SECTOR IS $1000 LD (HL),A ; SO WE JUST INCREASE HIGH BYTE ; NXTS3: LD A,(VERRES) ; EXIT WITH STATUS RET ; DISPROG:LD A,(BLKCOUT) ; SKIP OUTPUT OR A ; IF OUTPUT RET Z ; BLOCKED ; LD A,(MD_SECT) ; IF SECTOR IS 0 OR A ; THEN DISPLAY JR NZ,DISP1 ; BANK # PREFIX LD HL,msgBank CALL PRTSTR0 LD A,(MD_BANK) CALL PRTHEXB ; DISP1: LD C,' ' ; DISPLAY CALL CONOUT ; CURRENT LD C,'S' ; SECTOR CALL CONOUT LD A,(MD_SECT) RRCA RRCA RRCA RRCA CALL PRTHEXB RET ; ; WAITS FOR UP TO B SECONDS FOR A CHARACTER TO BECOME AVAILABLE AND ; RETURNS IT IN A WITHOUT ECHO AND CARRY CLEAR. IF TIMEOUT THEN CARRY ; IT SET. ; ; 4MHZ 20 SECONDS TmoFct = 16 ; 10MHZ 20 SECONDS TmoFct = 39 ; GetCharTmo1: LD B,1 ; WAIT 1 SECOND FOR SERIAL INPUT GetCharTmo: CALL SERST ; IF THERE IS A OR A ; CHARACTER AVAILABLE JR NZ,GotChrX ; EXIT NOW OTHERWISE POLL GCtmoa: 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 DJNZ GCtmob POP BC DJNZ GetCharTmo SCF ; SET CARRY SIGNALS TIMEOUT RET ; GotChar:POP BC POP BC POP BC GotChrX:CALL SERIN OR A ; CLEAR CARRY SIGNALS SUCCESS RET ; GETINP: CALL CONIN ; GET A CHARACTER LD C,A ; RETURN SEQUENCE CALL CONOUT ; CONVERT TO UPPERCASE LD C,BSPC ; RETURN CHARACTER IN A CALL CONOUT LD B,A CP BSPC JR Z,GETINP GETINP2:CALL CONIN CP BSPC JR Z,GETINP CP CR JR NZ,GETINP2 LD A,B LD C,A CALL CONOUT CP 'a' ; BELOW 'A'? JR C,GETINP3 ; IF SO, NOTHING TO DO CP 'z'+1 ; ABOVE 'Z'? JR NC,GETINP3 ; IF SO, NOTHING TO DO AND ~$20 ; CONVERT CHARACTER TO LOWER GETINP3:RET ; MENU: CALL COUTON LD HL,msgConsole ; DISPLAY CALL PRTSTR0 ; CONSOLE LD A,(CONDEV) ; DEVICE PUSH AF ADD A,'0' LD C,A CALL CONOUT LD C,' ' CALL CONOUT POP AF CALL DISPBAUD ; LD HL,msgIODevice ; DISPLAY CALL PRTSTR0 ; SERIAL LD A,(SERDEV) ; DEVICE PUSH AF ADD A,'0' LD C,A CALL CONOUT LD C,' ' CALL CONOUT POP AF CALL DISPBAUD ; LD HL,msgSetBaud ; DISPLAY CALL PRTSTR0 ; RECOMMENDED LD A,(RECSPD) ; BAUD RATE CALL DECBAUD ; LD HL,msgRevertBaud ; DISPLAY CALL PRTSTR0 ; ORIGINAL LD A,(ORISPD) ; BAUD RATE CALL DECBAUD ; LD HL,msgWriteV ; DISPLAY CALL PRTSTR0 ; VERIFY LD A,(WRTVER) ; OPTION OR A LD HL,msgYES JR NZ,MENU1 LD HL,msgNO MENU1: CALL PRTSTR0 ; LD HL,msgBegin ; DISPLAY OTHER CALL PRTSTR0 ; MENU OPTIONS RET ; ;====================================================================== ; DISPLAY THE BAUD RATE FOR THE DEVICE SPECIFIED IN A ;====================================================================== ; DISPBAUD: CALL GETDINFO ; GET DEVICE INFO RET NZ ; EXIT IF NOT SERIAL DECBAUD:;CALL PRTHEXB BIT 4,A ; CONVERT ; IF X > 15 X=(X-15)*2 JR Z,UNDER15 ; DEVICE ; ELSE X=(X*2)-1 AND %00001111 ; BAUD INC A ; CODE TO ADD A,A ; TABLE JR WASOVER ; INDEX UNDER15:AND %00001111 ADD A,A DEC A WASOVER:;CALL PRTHEXB LD DE,BAUDTBL ; DISPLAY CALL PRTIDXDEA ; BAUD RATE RET ; ; GET DEVICE INFO FOR DEVICE SPECIFIED IN A ; RETURN NZ FLAG IF NON SERIAL. ; RETURN Z FLAG IF SERIAL DEVICE AND A CONTAINING ENCODED BAUD BYTE ; GETDINFO: PUSH AF LD C,A LD B,$06 ; GET RST 08 ; DEVICE LD A,C ; TYPE POP BC OR A ; EXIT IF RET NZ ; NOT SERIAL ; LD C,B ; GET LD B,$05 ; DEVICE RST 08 ; INFO XOR A LD A,D RET ; OPTIOND:CALL COUTON ; TURN ON OUTPUT ; LD HL,msgConfirm ; CONFIRM CALL PRTSTR0 ; OK CALL GETINP ; TO CP 'Y' ; PROCEED JP NZ,MENULP DUPL: LD HL,msgCopying CALL PRTSTR0 ; LD A,(ERATYP) ; CHECK IF WE OR A ; NEED TO DO JR Z,NOERA1 ; A CHIP ERASE ; LD HL,$1000 LD (MD_FBAS),HL LD HL,MD_FERAC ; ERASE CALL MD_FNCALL ; CHIP #2 OR A JP FAILWF ; NOERA1: LD B,16 ; LOOP THROUGH 16 BANKS ; XOR A ; START AT LD (MD_BANK),A ; BANK 0 ; NXTB: PUSH BC ; XOR A ; START AT LD (MD_SECT),A ; SECTOR 0 ; LD B,8 ; LOOP THROUGH 8 SECTORS NXTS: PUSH BC ; CALL DISPROG ; DISPLAY PROGRESS ; LD IX,sector4k ; READ SECTOR LD HL,MD_FREAD ; FROM ROM #1 CALL MD_FNCALL ; LD HL,MD_BANK ; SET CHIP #2 SET 4,(HL) ; LD A,(ERATYP) ; SKIP ERASE OR A ; IF SECTOR ERASE JR NZ,NOERA2 ; IS NOT SUPPORTED ; LD HL,MD_FERAS ; ERASE SECTOR CALL MD_FNCALL ; ON ROM #2 OR A JR NZ,VERF ; NOERA2: LD IX,sector4k ; WRITE SECTOR LD HL,MD_FWRIT ; ON ROM #2 CALL MD_FNCALL ; LD A,(WRTVER) ; VERIFY OR A ; WRITE IF JR Z,NOVER1 ; OPTION ; LD IX,sector4k ; VERIFY LD HL,MD_FVERI ; WRITE CALL MD_FNCALL OR A ; EXIT IF JR NZ,VERF ; VERIFY FAILED ; NOVER1: LD HL,MD_BANK ; RESET TO CHIP #1 RES 4,(HL) ; LD A,(MD_SECT) ; POINT TO ADD A,$10 ; NEXT LD (MD_SECT),A ; SECTOR ; POP BC ; LOOP DJNZ NXTS ; NEXT SECTOR ; LD HL,MD_BANK ; POINT TO ; 00-15 = CHIP 1 INC (HL) ; NEXT BANK ; 16-21 = CHIP 2 ; POP BC ; LOOP DJNZ NXTB ; NEXT BANK ; JP Done1 ; SUCCESS. RETURN TO MENU ; VERF: POP BC ; EXIT WITH FAIL POP BC ; FAIL MESSAGE AND JP FAILWF ; RETURN TO MENU ; OPTIONG:LD HL,msgChangeNow ; CHANGE CALL PRTSTR0 ; SERIAL LD A,(RECSPD) ; DEVICE PUSH AF ; BAUD RATE CALL DECBAUD ; TO RECOMMENDED LD HL,msgPressKey CALL PRTSTR0 POP AF CALL CHGSPD CALL GETINP JP MENULP ; OPTIONL:LD HL,msgChangeNow ; CHANGE CALL PRTSTR0 ; SERIAL LD A,(ORISPD) ; DEVICE PUSH AF ; BAUD RATE CALL DECBAUD ; TO ORIGINAL LD HL,msgPressKey CALL PRTSTR0 POP AF CALL CHGSPD CALL GETINP JP MENULP ; CHGSPD: PUSH AF LD B,$05 ; GET SERIAL DEVICE LD A,(SERDEV) ; CHARACTERISTICS LD C,A RST 08 LD A,D ; MASK OUT EXISTING AND %11100000 ; REPLACE WITH RATE LD D,A POP AF OR D LD D,A ; LD B,$04 ; SET NEW LD A,(SERDEV) ; SPEED LD C,A RST 08 RET ; OPTIONV:LD A,(WRTVER) ; TOGGLE CPL ; VERIFY LD (WRTVER),A ; FLAG JP MENULP ; BACK TO MENU ; OPTIONC:LD HL,msgEnterUnit ; GET CALL PRTSTR0 ; CONSOLE 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 JR Z,CONCLR ; FALSE ENTRIES CALL CONIN JR CLRCON CONCLR: JP MENULP ; BACK TO MENU ; OPTIONS:LD HL,msgEnterUnit ; GET CALL PRTSTR0 ; CONSOLE CALL GETINP ; UNIT CP '0' JR C,CONCLR CP '9' + 1 JR NC,CONCLR SUB '0' ; NUMBER LD (SERDEV),A ; JP MENULP ; BACK TO MENU ; #IF (XFUDBG) OPTIONT:LD HL,msgCRLF ; TEST DELAY 32S, 16S, 8S, 4S, 2S, 1S CALL PRTSTR0 LD B,32 ; START DELAY IS 32 SECONDS TSTDLY: PUSH BC LD C,'>' ; DISPLAY START CALL CONOUT ; INDICATOR LD A,B CALL PRTHEXB CALL GetCharTmo ; DELAY B SECONDS LD C,'<' ; DISPLAY STOP CALL CONOUT ; INDICATOR POP BC SRL B ; NEXT DELAY IS HALF PREVIOUS JR NZ,TSTDLY ; RETURN TO MENU JP MENULP ; WHEN DELAY GETS TO 1 SECOND ; OPTIONH: LD BC,$F8F3 ; GET CURRENT RST 08 ; SPEED SETTING LD A,L ; EXIT IF ALREADY OR A ; HALF SPEED JP Z,MENULP ; LD BC,$F9F3 ; TRY TO SWITCH LD L,0 ; TO HALF SPEED LD DE,0 RST 08 OR A ; EXIT IF JP Z,MENULP ; CHANGE FAILS ; LD HL,TmoFct ; OTHERWISE ADJUST SRL (HL) ; DELAY FACTOR (/2) JP MENULP ; BACK TO MENU ; OPTIONF:LD HL,msgCRLF ; DISPLAY CALL PRTSTR0 ; BANK LD C,'b' ; SECTOR CALL CONOUT ; TIMEOUT LD A,(MD_BANK) ; CHIP CALL PRTHEXB LD C,'s' CALL CONOUT LD A,(MD_SECT) CALL PRTHEXB LD C,'t' CALL CONOUT LD A,(TmoFct) CALL PRTHEXB LD C,'c' CALL CONOUT LD A,(ERATYP) CALL PRTHEXB ; LD HL,msgCRLF ; DISPLAY CALL PRTSTR0 ; ACK/NAK BYTE LD HL,packet ; DISPLAY LD B,3 ; LAST DMPBUF2:LD A,(HL) ; NUMBERS CALL PRTHEXB LD C,' ' CALL CONOUT INC HL DJNZ DMPBUF2 LD HL,msgCRLF CALL PRTSTR0 LD B,128 ; DISPLAY LD HL,packet+3 ; LAST DMPBUF: LD A,(HL) ; PACKET CALL PRTHEXB ; CONTENTS LD C,' ' CALL CONOUT LD A,B SUB 2 AND %00001111 CP %00001111 JR NZ,DMPBUF1 PUSH HL LD HL,msgCRLF CALL PRTSTR0 POP HL DMPBUF1:INC HL DJNZ DMPBUF JP MENULP ; OPTIONR:LD HL,msgErase ; DISPLAY CALL PRTSTR0 ; ERASE CHIP LD HL,$1000 ; SET CHIP LD (MD_FBAS),HL ; ADDRESS LD HL,MD_FERAC ; ERASE CALL MD_FNCALL ; AND WRITE OR A JP NZ,FAILWF JP Done1 ; OPTIONE:LD HL,msgErase ; DISPLAY CALL PRTSTR0 ; ERASE CHIP LD HL,MD_FERAC ; ERASE CALL MD_FNCALL ; AND WRITE OR A JP NZ,FAILWF JP Done1 #ENDIF ; ;====================================================================== ; CONSOLE AND SERIAL I/O ROUTINES ;====================================================================== ; SEROUT: PUSH HL ; SERIAL OUTPUT CHARACTER IN C PUSH DE PUSH BC LD E,C LD B,$01 LD HL,SERDEV LD C,(HL) RST 08 POP BC POP DE POP HL RET ; SERST: PUSH HL ; SERIAL STATUS. RETURN CHARACTERS AVAILABLE IN A PUSH DE PUSH BC LD B,$02 LD HL,SERDEV LD C,(HL) RST 08 POP BC POP DE POP HL RET ; SERIN: PUSH HL ; SERIAL INPUT. WAIT FOR A CHARACTER AND RETURN IT IN A PUSH DE PUSH BC LD B,$00 LD HL,SERDEV LD C,(HL) RST 08 LD A,E POP BC POP DE POP HL RET ; CONOUT: PUSH AF ; OUTPUT IS BLOCKED DURING THE LD A,(BLKCOUT) ; FILE TRANSFER WHEN THE OR A ; CONSOLE AND SERIAL LINE JR Z,CONOUT1 ; ARE THE SAME PUSH HL ; CONSOLE OUTPUT CHARACTER IN C PUSH DE PUSH BC LD E,C LD B,$01 LD HL,CONDEV LD C,(HL) RST 08 POP BC POP DE POP HL CONOUT1:POP AF RET ; CONST: PUSH HL ; CONSOLE STATUS. RETURN CHARACTERS AVAILABLE IN A PUSH DE PUSH BC LD B,$02 LD HL,CONDEV LD C,(HL) RST 08 POP BC POP DE POP HL RET ; CONIN: PUSH HL ; CONSOLE INPUT. WAIT FOR A CHARACTER ADD RETURN IT IN A PUSH DE PUSH BC LD B,$00 LD HL,CONDEV LD C,(HL) RST 08 LD A,E POP BC POP DE POP HL RET ; ;====================================================================== ; TEXT OUTPUT ROUTINES ;====================================================================== ; PRTHEXB:PUSH AF ; PRINT HEX BYTE IN A TO CONSOLE PUSH BC PUSH DE CALL HEXASC LD C,D CALL CONOUT LD C,E CALL CONOUT POP DE POP BC POP AF RET HEXASC: LD D,A CALL HEXCONV LD E,A LD A,D RLCA RLCA RLCA RLCA CALL HEXCONV LD D,A RET ; HEXCONV:AND 0FH ; CONVERT LOW NIBBLE OF A TO ASCII HEX ADD A,90H DAA ADC A,40H DAA RET ; ; PRINT 0 TERMINATED STRING POINTED TO BY HL ; 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 INC HL JP PRTSTR0 ; ; PRINT $ TERMINATED STRING POINTED TO BY HL ; PRTSTRD:LD A,(HL) ; PRINT MESSAGE POINTED TOP HL UNTIL $ CP '$' ; CHECK IF GOT IT? RET Z ; IF MATCH RETURN TO CALLER LD C,A CALL CONOUT ; ELSE PRINT THE CHARACTER INC HL JP PRTSTRD ; ; PRINT THE nTH STRING IN A LIST OF STRINGS WHERE EACH IS TERMINATED BY $ ; A REGISTER DEFINES THE nTH STRING IN THE LIST TO PRINT AND DE POINTS ; TO THE START OF THE STRING LIST. ; PRTIDXDEA: PUSH BC LD C,A ; INDEX COUNT OR A LD A,0 PRTIDXDEA1: JR Z,PRTIDXDEA3 PRTIDXDEA2: LD A,(DE) ; LOOP UNIT INC DE ; WE REACH CP '$' ; END OF STRING JR NZ,PRTIDXDEA2 DEC C ; AT STRING END. SO GO JR PRTIDXDEA1 ; CHECK FOR INDEX MATCH PRTIDXDEA3: POP BC EX DE,HL CALL PRTSTRD ; FALL THROUGH TO WRITESTR RET ; ;====================================================================== ; CRC OPTIONS AND CALCULATIONS ;====================================================================== ; OPTION1:LD HL,$0000 ; CRC32 STARTING LD (MD_FBAS),HL ; BANK $00 SECTOR $00 LD B,16 ; 16 BANKS (512K) JR CALCCRC ; OPTION2:LD HL,$1000 ; CRC32 STARTING LD (MD_FBAS),HL ; BANK $10 SECTOR $00 LD B,16 ; 16 BANKS (512K) JR CALCCRC ; OPTION3:LD HL,$0000 ; CRC32 STARTING LD (MD_FBAS),HL ; BANK $00 SECTOR $00 LD B,32 ; 32 BANKS (1024K) ; CALCCRC:CALL COUTON ; TURN ON OUTPUT ; LD HL,msgCalc CALL PRTSTR0 ; LD HL,$FFFF ; SET THE LD (CRC),HL ; START CRC LD (CRC+2),HL ; CONDITION ; CRCLP1: PUSH BC ; LOOP THROUGH ALL BANKS LD B,8 ; LOOP THROUGH CRCLP2: PUSH BC ; 8 SECTORS ; PUSH BC CALL DISPROG ; DISPLAY PROGRESS ; LD IX,sector4k ; READ LD HL,MD_FREAD ; A SECTOR CALL MD_FNCALL CALL CRC32 ; CALCULATE CRC POP BC ; LD A,(MD_SECT) ; POINT ADD A,$10 ; TO NEXT LD (MD_SECT),A ; SECTOR ; POP BC ; NEXT DJNZ CRCLP2 ; SECTOR ; XOR A ; RESET SECTOR LD (MD_SECT),A ; START ; LD HL,MD_BANK ; POINT TO INC (HL) ; NEXT BANK ; POP BC ; NEXT DJNZ CRCLP1 ; BANK ; LD HL,msgCRC32 ; DISPLAY CALL PRTSTR0 ; RESULT LD HL,CRC+3 LD B,4 DISPCRC:LD A,$FF XOR (HL) CALL PRTHEXB DEC HL DJNZ DISPCRC ; JP MENULP ; CRC32: LD IX,sector4k ; CALCULATE LD BC,4096 ; CRC32 OF LD DE,(CRC) ; EACH SECTOR LD HL,(CRC+2) BYTELP: PUSH BC LD A,(IX) XOR E LD B,8 ROTLP: SRL H RR L RR D RRA JP NC,CLEAR LD E,A LD A,H XOR $ED LD H,A LD A,L XOR $B8 LD L,A LD A,D XOR $83 LD D,A LD A,E XOR $20 CLEAR: DEC B JP NZ,ROTLP LD E,A INC IX POP BC DEC BC LD A,B OR C JP NZ,BYTELP LD (CRC),DE LD (CRC+2),HL RET ; ; multiply DE:HL by 10, exit with C set if overflow ; multb10:call multb2 ; x2 ret c push de push hl call multb2 ; x4 ret c call multb2 ; x8 ret c ; pop bc ; x8 + 2 add hl,bc pop bc jr nc,multbc inc de ret c multbc: ex de,hl add hl,bc ex de,hl ret multb2: ex de,hl ; multiply by 2 add hl,hl ret c ex de,hl add hl,hl jr nc,multbnc inc de multbnc:ret ; ;====================================================================== ; CALCULATE BANK AND ADDRESS DATA FROM MEMORY ADDRESS ; ; ON ENTRY DE:HL CONTAINS 32 BIT MEMORY ADDRESS. ; ON EXIT B CONTAINS BANK SELECT BYTE ; C CONTAINS HIGH BYTE OF SECTOR ADDRESS ;====================================================================== ; ;MD_CALBAS: ; ; PUSH HL ; LD A,E ; BOTTOM PORTION OF SECTOR ; AND $0F ; ADDRESS THAT GETS WRITTEN ; RLC H ; WITH ERASE COMMAND BYTE ; RLA ; A15 GETS DROPPED OFF AND ; LD B,A ; ADDED TO BANK SELECT ; ; LD A,H ; TOP SECTION OF SECTOR ; RRA ; ADDRESS THAT GETS WRITTEN ; AND $70 ; TO BANK SELECT PORT ; LD C,A ; POP HL ; ; LD (MD_FBAS),BC ; SAVE BANK AND SECTOR FOR USE IN FLASH ROUTINES ; RET ; MD_FSTART: .EQU $ ; FLASH ROUTINES WHICH GET RELOCATED TO HIGH MEMORY ; ;====================================================================== ; COMMON FUNCTION CALL FOR: ; ; 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 ; ; 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 ; 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 ; ON EXIT A NO STATUS IS RETURNED ; ; MD_VERI_R - VERIFY 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 COMPARE. ; ON EXIT A RETURNS STATUS 0=SUCCESS NZ=FAIL ; ; 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 ; ON EXIT A NO STATUS IS RETURNED ; ; MD_FERAC_R - ERASE 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 A RETURNS STATUS 0=SUCCESS FF=FAIL ; ; GENERAL OPERATION: ; FLASH LIBRARY CODE NEEDS TO BE RELOCATED TO UPPER MEMORY ; STACK NEEDS TO BE SETUP IN UPPER MEMORY ; DEPENDING ON ROUTINE, RETURNS WITH STATUS CODE IN A. ;====================================================================== ; MD_FNCALL: LD DE,$0000 ; PRESET DE TO SAVE SPACE LD BC,(MD_FBAS) ; PUT BANK AND SECTOR DATA IN BC ; LD A,(HB_CURBNK) ; WE ARE STARTING IN HB_CURBNK ; HB_DI CALL MD_FJPHL HB_EI ; LD A,C ; RETURN WITH STATUS IN A RET ; MD_FJPHL: JP (HL) ; #INCLUDE "flashlib.inc" ; MD_FEND .EQU $ MD_CSIZ .EQU MD_FEND-MD_FSTART ; HOW MUCH SPACE WE NEED FOR RELOCATABLE CODE ; MD_FIDEN .EQU HBX_LOC-MD_CSIZ+MD_FIDEN_R-MD_FSTART ; CALL ADDRESS FOR IDENTIFY FLASH CHIP MD_FERAS .EQU HBX_LOC-MD_CSIZ+MD_FERAS_R-MD_FSTART ; CALL ADDRESS FOR ERASE FLASH SECTOR MD_FREAD .EQU HBX_LOC-MD_CSIZ+MD_FREAD_R-MD_FSTART ; CALL ADDRESS FOR READ FLASH SECTOR MD_FVERI .EQU HBX_LOC-MD_CSIZ+MD_FVERI_R-MD_FSTART ; CALL ADDRESS FOR VERIFY FLASH SECTOR MD_FWRIT .EQU HBX_LOC-MD_CSIZ+MD_FWRIT_R-MD_FSTART ; CALL ADDRESS FOR WRITE FLASH SECTOR MD_FERAC .EQU HBX_LOC-MD_CSIZ+MD_FERAC_R-MD_FSTART ; CALL ADDRESS FOR ERASE FLASH CHIP ; ; Message strings ; msgHeader: .DB CR,LF,CR,LF,"ROMWBW XMODEM FLASH UPDATER",CR,LF,0 msgPlatform .DB CR,LF,"PLATFORM NOT SUPPORTED",CR,LF,0 msgConfirm: .DB CR,LF,CR,LF,"ENTER Y TO CONFIRM OVERWRITE : ",0 msgInstr: .DB CR,LF,CR,LF,"START TRANSFER OF YOUR UPDATE IMAGE OR ROM",CR,LF,0 msgUserEx: .DB CR,LF,"UPDATER EXITED BY USER",CR,LF,0 msgBank: .DB CR,LF,"BANK ",0 msgUnsupC: .DB CR,LF,"FLASH CHIP NOT SUPPORTED",CR,LF,0 msgReboot: .DB CR,LF,"REBOOTING ...",CR,LF,0 msgCopying: .DB CR,LF,"COPYING ...",CR,LF,0 msgCalc: .DB CR,LF,"CALCULATING ...",CR,LF,0 msgErase: .DB CR,LF,"ERASING ...",CR,LF,0 msgCRC32: .DB CR,LF,CR,LF,"CRC32 : ",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 msgChangeNow: .DB CR,LF,"Change speed now to ",0 msgPressKey: .DB CR,LF,"Press a key to Resume.",CR,LF,0 msgConsole: .DB CR,LF,CR,LF,"(C) Set Console Device : ",0 msgIODevice: .DB CR,LF,"(S) Set Serial Device : ",0 msgSetBaud: .DB CR,LF,"(>) Set Recommended Baud Rate : ",0 msgRevertBaud: .DB CR,LF,"(<) Revert to Original Baud Rate : ",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,"(Q) Quit to Rom Loader" .DB CR,LF,"(D) Duplicate Flash #1 to #2" .DB CR,LF,"(1) CRC 512K Flash #1" .DB CR,LF,"(2) CRC 512K Flash #2" .DB CR,LF,"(3) CRC 1024K Flash" #IF (XFUDBG) .DB CR,LF,"(H) Select half speed" .DB CR,LF,"(T) Test timeout" .DB CR,LF,"(F) Dump Debug Data" .DB CR,LF,"(E) Erase Flash chip #1" .DB CR,LF,"(Z) Erase Flash chip #2" #ENDIF .DB CR,LF,CR,LF,"Select : ",0 msgSuccess: .DB CR,LF,CR,LF,"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 EXCEEDED",CR,LF,0 msgTimout .DB CR,LF,"ERROR, RECEIVE TIMEOUT",CR,LF,0 ; ; Variables ; CONDEV: .DB $00 ; HBIOS CONSOLE DEVICE NUMBER SERDEV: .DB $00 ; HBIOS SERIAL DEVICE NUMBER USED FOR XMODEM TRANSFER WRTVER: .DB $FF ; WRITE VERIFY OPTION FLAG VERRES: .DB $00 ; WRITE VERIFY RESULT BLKCOUT: .DB $FF ; BLOCK TEXT OUTPUT DURING TRANSFER IF ZERO ERATYP .DB $00 ; HOLDS THE ERASE TYPE FLAG FOR VARIOUS CHIPS ;CPUSPD: .DB 0 ; HOLDS CURRENT PROCESSOR SPEED ORISPD: .DB 0 ; HOLDS ORIGINAL BAUD RATE SPEED RECSPD: .DB 0 ; HOLDS RECOMMENDED BAUD RATE SPEED oldSP: .DW 0 ; The orginal SP to be restored before exiting 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_SECT .EQU MD_FBAS ; BANK BYTE MD_BANK .EQU MD_FBAS+1 ; SECTOR BYTE CRC .DW $FFFF ; CRC32 .DW $FFFF ; packet: .DB 0 ; SOH .DB 0 ; PacketN .DB 0 ; -PacketNo, .FILL 128,0 ; data*128, .DB 0 ; chksum ; ;====================================================================== ; SUPPORTED DEVICES AND ID CODES ;====================================================================== ; DEVICES: .DW $BFB7 ; 39SF040 0 .DW $01A4 ; 29F040 1 .DW $1F13 ; AT49F040 2 .DW $1FA4 ; AT29C040 3 .DW $20E2 ; M29F040 4 .DW $C2A4 ; MX29F040 5 .DW $37A4 ; A29010B 6 .DW $3786 ; A29040B 7 LSTDEV: .EQU $ ; ;====================================================================== ; BAUD RATE TABLE ;====================================================================== ; BAUDTBL:.DB "75$" ; 0 0 .DB "150$" ; 1 1 .DB "225$" ; 2 16 .DB "300$" ; 3 2 .DB "450$" ; 4 17 .DB "600$" ; 5 3 .DB "900$" ; 6 18 .DB "1200$" ; 7 4 .DB "1800$" ; 8 19 .DB "2400$" ; 9 5 .DB "3600$" ; 10 20 .DB "4800$" ; 11 6 .DB "7200$" ; 12 21 .DB "9600$" ; 13 7 .DB "14400$" ; 14 22 .DB "19200$" ; 15 8 .DB "28800$" ; 16 23 .DB "38400$" ; 17 9 .DB "57600$" ; 18 24 .DB "76800$" ; 19 10 .DB "115200$" ; 20 25 .DB "153600$" ; 21 11 .DB "230400$" ; 22 26 .DB "307200$" ; 23 12 .DB "460800$" ; 24 27 .DB "614400$" ; 25 13 .DB "921600$" ; 26 28 .DB "1228800$" ; 27 14 .DB "1843200$" ; 28 29 .DB "2457600$" ; 29 15 .DB "3686400$" ; 30 30 .DB "7372800$" ; 31 16 ; ;====================================================================== ; CLOCK SETTING TABLE ;====================================================================== ; CLKTBL: .DB 6 ; 1 4800 .DB 6 ; 2 4800 .DB 7 ; 3 9600 .DB 8 ; 4 19200 .DB 8 ; 5 19200 .DB 8 ; 6 19200 .DB 8 ; 7 19200 .DB 9 ; 8 38400 .DB 9 ; 9 38400 .DB 9 ; 10 38400 .DB 9 ; 11 38400 .DB 9 ; 12 38400 .DB 9 ; 13 38400 .DB 9 ; 14 38400 .DB 9 ; 15 38400 .DB 9 ; 16 38400 .DB 9 ; 17 38400 .DB 9 ; 18 38400 .DB 9 ; 19 38400 .DB 9 ; 20 38400 ; sector4k: .EQU $ ; 32 PACKETS GET ACCUMULATED HERE BEFORE FLASHING ; SLACK .EQU (UPD_END - $) .FILL SLACK,$FF .ECHO "ROM Updater space remaining: " .ECHO SLACK .ECHO " bytes.\n" .END