diff --git a/Source/HBIOS/flashfs.asm b/Source/HBIOS/flashfs.asm deleted file mode 100644 index 47c12eab..00000000 --- a/Source/HBIOS/flashfs.asm +++ /dev/null @@ -1,835 +0,0 @@ -; -;================================================================================================== -; FLASH DRIVER FOR FLASH & EEPROM PROGRAMMING -; -; 26 SEP 2020 - CHIP IDENTIFICATION IMPLEMENTED -- PHIL SUMMERS -; - CHIP ERASE IMPLEMENTED -; 23 OCT 2020 - SECTOR ERASE IMPLEMENTED -; 01 NOV 2020 - WRITE SECTOR IMPLEMENTED -; 04 DEC 2020 - READ SECTOR IMPLEMENTED -;================================================================================================== -; -; UPPER RAM BANK IS ALWAYS AVAILABLE REGARDLESS OF MEMORY BANK SELECTION. -; HBX_BNKSEL AND HB_CURBNK ARE ALWAYS AVAILABLE IN UPPER MEMORY. -; -; THE STACK IS IN UPPER MEMORY DURING BIOS INITIALIZATION BUT IS IN LOWER -; MEMORY DURING HBIOS CALLS. -; -; TO ACCESS THE FLASH CHIP FEATURES, CODE IS COPIED TO THE UPPER RAM BANK -; AND THE FLASH CHIP IS SWITCHED INTO THE LOWER BANK. -; -; INSPIRED BY WILL SOWERBUTTS FLASH4 UTILITY - https://github.com/willsowerbutts/flash4/ -; -;================================================================================================== -; -FF_DBG: .EQU 0 ; DEBUG -FF_HBX: .EQU 1 ; =0 USE STACK, =1 USE HBX_BUF -; -FF_RW .DB 00h ; READ WRITE FLAG -FF_TGT .EQU 0BFB7H ; TARGET CHIP FOR R/W FILESYSTEM -; -;====================================================================== -; BIOS FLASH INITIALIZATION -; -; IDENTIFY AND DISPLAY FLASH CHIPS IN SYSTEM. -; USES MEMORY SIZE DEFINED BY BUILD CONFIGURATION. -;====================================================================== -; -; -FF_INIT: - CALL NEWLINE ; DISLAY NUMBER - PRTS("FF: UNITS=$") ; OF UNITS - LD A,+(ROMSIZE/512) ; CONFIGURED FOR. - CALL PRTDECB -; - LD B,A ; NUMBER OF DEVICES TO PROBE - LD C,$00 ; START ADDRESS IS 0000:0000 IN DE:HL -FF_PROBE: - LD D,$00 ; SET ADDRESS IN DE:HL - LD E,C ; - LD H,D ; WE INCREASE E BY $08 - LD L,D ; ON EACH CYCLE THROUGH -; - PUSH BC - CALL PC_SPACE - LD A,+(ROMSIZE/512)+1 - SUB B ; PRINT - CALL PRTDECB ; DEVICE - LD A,'=' ; NUMBER - CALL COUT - CALL FF_IINIT ; GET ID AT THIS ADDRESS -; - PUSH HL - PUSH DE - LD H,FF_TGT&$FF ; IF WE MATCH WITH - LD L,FF_TGT/$FF - CCF ; A NON 39SF040 - SBC HL,DE ; CHIP SET THE - LD A,(FF_RW) ; R/W FLAG TO R/O - OR H - OR L - LD (FF_RW),A - POP DE - POP HL -; - CALL FF_LAND ; LOOKUP AND DISPLAY - POP BC -; - LD A,C ; UPDATE ADDRESS - ADD A,$08 ; TO NEXT DEVICE - LD C,A -; - DJNZ FF_PROBE ; ALWAYS AT LEAST ONE DEVICE -; - LD A,(FF_RW) - OR A - JR NZ,FF_PR1 - CALL PRTSTRD - .TEXT " FLASH FILESYSTEM ENABLED$" -FF_PR1: -; -#IF (FF_DBG==1) - CALL FF_TESTING -#ENDIF -; - XOR A ; INIT SUCCEEDED - RET -; -;====================================================================== -; TEST CODE AREA -;====================================================================== -; -FF_TESTING: -; -#IF (0) - LD DE,$0008 ; SET - LD HL,$0000 ; ADDRESS - CALL FF_EINIT ; CHIP ERASE - CALL PRTHEXBYTE ; DISPLAY STATUS -#ENDIF -; -#IF (0) - LD DE,$000A ; SET - LD HL,$8000 ; ADDRESS - CALL FF_SINIT ; SECTOR ERASE - CALL PRTHEXBYTE ; DISPLAY STATUS -#ENDIF -; -#IF (0) - LD DE,$000A ; SET DESTINATION - LD HL,$8000 ; ADDRESS - LD IX,FF_BUFFER ; SET SOURCE ADDRESS - CALL FF_WINIT ; WRITE SECTOR - CALL PRTHEXBYTE ; DISPLAY STATUS -#ENDIF -; -#IF (1) - LD DE,$0000 ; SET SOURCE - LD HL,$7000 ; ADDRESS - LD IX,FF_BUFFER ; SET DESTINATION ADDRESS - CALL FF_RINIT ; READ SECTOR - CALL PRTHEXBYTE ; DISPLAY STATUS - LD DE,FF_BUFFER - CALL DUMP_BUFFER -#ENDIF -; -#IF (1) - LD HL,FF_BUFFER ; FILL BUFFER - LD (HL),'J' - LD DE,FF_BUFFER+1 - LD BC,$1000-1 - LDIR -#ENDIF -; -#IF (1) - LD DE,$0000 ; SET - LD HL,$7000 ; ADDRESS - CALL FF_SINIT ; SECTOR ERASE - CALL PRTHEXBYTE ; DISPLAY STATUS -#ENDIF -#IF (1) - LD DE,$0000 ; SET DESTINATION - LD HL,$7000 ; ADDRESS - LD IX,FF_BUFFER ; SET SOURCE ADDRESS - CALL FF_WINIT ; WRITE SECTOR - CALL PRTHEXBYTE ; DISPLAY STATUS -#ENDIF -; -#IF (1) - LD DE,$0000 ; SET SOURCE - LD HL,$7000 ; ADDRESS - LD IX,FF_BUFFER ; SET DESTINATION ADDRESS - CALL FF_RINIT ; READ SECTOR - CALL PRTHEXBYTE ; DISPLAY STATUS - LD DE,FF_BUFFER - CALL DUMP_BUFFER -#ENDIF - RET -; -;====================================================================== -; LOOKUP AND DISPLAY CHIP -; -; ON ENTRY DE CONTAINS CHIP ID -; ON EXIT A CONTAINS STATUS 0=SUCCESS, NZ=NOT IDENTIFIED -;====================================================================== -; -FF_LAND: -; -#IF (FF_DBG==1) - PRTS(" ID:$") - LD H,E - LD L,D - CALL PRTHEXWORDHL ; DISPLAY FLASH ID - CALL PC_SPACE -#ENDIF -; - LD HL,FF_TABLE ; SEARCH THROUGH THE FLASH - LD BC,FF_T_CNT ; TABLE TO FIND A MATCH -FF_NXT1:LD A,(HL) - CP D - JR NZ,FF_NXT0 ; FIRST BYTE DOES NOT MATCH -; - INC HL - LD A,(HL) - CP E - DEC HL - JR NZ,FF_NXT0 ; SECOND BYTE DOES NOT MATCH -; - INC HL - INC HL - JR FF_NXT2 ; MATCH SO EXIT -; -FF_NXT0:PUSH BC ; WE DIDN'T MATCH SO POINT - LD BC,FF_T_SZ ; TO THE NEXT TABLE ENTRY - ADD HL,BC - POP BC -; - LD A,B ; CHECK IF WE REACHED THE - OR C ; END OF THE TABLE - DEC BC - JR NZ,FF_NXT1 ; NOT AT END YET -; - LD HL,FF_UNKNOWN ; WE REACHED THE END WITHOUT A MATCH -; -FF_NXT2:CALL PRTSTR ; AFTER SEARCH DISPLAY THE RESULT - RET -;====================================================================== -;COMMON FUNCTION CALL -; -;====================================================================== -; -#IF (FF_HBX==0) -FF_FNCALL: ; USING STACK FOR CODE AREA - CALL FF_CALCA ; GET BANK AND SECTOR DATA IN IY -; - POP DE ; GET ROUTINE TO CALL -; - LD (FF_STACK),SP ; SAVE STACK - LD HL,(FF_STACK) -; - LD BC,64 -; LD BC,FF_I_SZ ; CODE SIZE REQUIRED - CCF ; CREATE A RELOCATABLE - SBC HL,BC ; CODE BUFFER IN THE - LD SP,HL ; STACK AREA -; - PUSH HL ; SAVE THE EXECUTE ADDRESS - EX DE,HL ; PUT EXECUTE / START ADDRESS IN DE -; LD HL,FF_IDENT ; COPY OUR RELOCATABLE - LDIR ; CODE TO THE BUFFER - POP HL ; CALL OUR RELOCATABLE CODE - - PUSH IY ; PUT BANK AND SECTOR - POP BC ; DATA IN BC -; -#IF (FF_DBG==1) - CALL PRTHEXWORD -#ENDIF -; - HB_DI - CALL JPHL ; EXECUTE RELOCATED CODE - HB_EI -; - LD HL,(FF_STACK) ; RESTORE ORIGINAL - LD SP,HL ; STACK POSITION -; -#IF (FF_DBG==1) - CALL PC_SPACE - CALL PRTHEXWORD - CALL PC_SPACE - EX DE,HL - CALL PRTHEXWORDHL - CALL PC_SPACE - EX DE,HL -#ENDIF -; - LD A,C ; RETURN WITH STATUS IN A -; - RET -#ELSE -FF_FNCALL: ; USING HBX_BUF FOR CODE AREA - CALL FF_CALCA ; GET BANK AND SECTOR DATA IN IY -; - POP HL ; GET ROUTINE TO CALL -; - LD DE,HBX_BUF ; PUT EXECUTE / START ADDRESS IN DE - LD BC,HBX_BUFSIZ ; CODE SIZE REQUIRED -; - PUSH DE ; SAVE THE EXECUTE ADDRESS - ; COPY OUR RELOCATABLE - LDIR ; CODE TO THE BUFFER - POP HL ; CALL OUR RELOCATABLE CODE - - PUSH IY ; PUT BANK AND SECTOR - POP BC ; DATA IN BC -; -#IF (FF_DBG==1) - CALL PRTHEXWORD -#ENDIF -; - HB_DI - CALL JPHL ; EXECUTE RELOCATED CODE - HB_EI -; -#IF (FF_DBG==1) - CALL PC_SPACE - CALL PRTHEXWORD - CALL PC_SPACE - EX DE,HL - CALL PRTHEXWORDHL - CALL PC_SPACE - EX DE,HL -#ENDIF -; - LD A,C ; RETURN WITH STATUS IN A -; - RET - -#ENDIF -; -;====================================================================== -; IDENTIFY FLASH CHIP. -; CALCULATE BANK AND ADDRESS DATA FROM ENTRY ADDRESS -; CREATE A CODE BUFFER IN HIGH MEMORY AREA -; COPY FLASH CODE TO CODE BUFFER -; CALL RELOCATED FLASH IDENTITY CODE -; RESTORE STACK -; RETURN WITH ID CODE. -; -; ON ENTRY DE:HL POINTS TO AN ADDRESS WITH THE ADDRESS RANGE OF THE -; CHIP TO BE IDENTIFIED. -; ON EXIT DE CONTAINS THE CHIP ID BYTES. -; NO STATUS IS RETURNED -;====================================================================== -; -FF_IINIT: - PUSH HL ; SAVE ADDRESS INFO - LD HL,FF_IDENT ; PUT ROUTINE TO CALL - EX (SP),HL ; ON THE STACK - JP FF_FNCALL ; EXECUTE -; -;====================================================================== -; FLASH IDENTIFY -; SELECT THE APPROPRIATE BANK / ADDRESS -; ISSUE ID COMMAND -; READ IN ID WORD -; ISSUE ID EXIT COMMAND -; SELECT ORIGINAL BANK -; -; ON ENTRY BC CONTAINS BANK AND SECTOR DATA -; A CONTAINS CURRENT BANK -; ON EXIT DE CONTAINS ID WORD -; NO STATUS IS RETURNED -;====================================================================== -; -FF_IDENT: ; THIS CODE GETS RELOCATED TO HIGH MEMORY -; - PUSH AF ; SAVE CURRENT BANK - LD A,B ; SELECT BANK - CALL HBX_BNKSEL ; TO PROGRAM -; - LD HL,$5555 ; LD A,$AA ; COMMAND - LD (HL),$AA ; LD ($5555),A ; SETUP - LD A,H ; LD A,$55 - LD ($2AAA),A ; LD ($2AAA),A - LD (HL),$90 ; LD A,$90 -; ; LD ($5555),A - LD DE,($0000) ; READ ID -; - LD A,$F0 ; ; EXIT - LD (HL),A ; LD ($5555),A ; COMMAND -; - POP AF ; RETURN TO ORIGINAL BANK - CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY -; - RET -; -FF_I_SZ .EQU $-FF_IDENT ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED -; -;====================================================================== -; FLASH CHIP ERASE. -; CALCULATE BANK AND ADDRESS DATA FROM ENTRY ADDRESS -; CREATE A CODE BUFFER IN HIGH MEMORY AREA -; COPY FLASH CODE TO CODE BUFFER -; CALL RELOCATED FLASH ERASE CODE -; RESTORE STACK -; RETURN WITH STATUS CODE. -; -; ON ENTRY DE:HL POINTS TO AN ADDRESS IDENTIFYING THE CHIP -; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL -;====================================================================== -; -FF_EINIT: - PUSH HL ; SAVE ADDRESS INFO - LD HL,FF_ERASE ; PUT ROUTINE TO CALL - EX (SP),HL ; ON THE STACK - JP FF_FNCALL ; EXECUTE -; -;====================================================================== -; ERASE FLASH CHIP. -; -; SELECT THE APPROPRIATE BANK / ADDRESS -; ISSUE ERASE COMMAND -; POLL TOGGLE BIT FOR COMPLETION STATUS. -; SELECT ORIGINAL BANK -; -; ON ENTRY BC CONTAINS BANK AND SECTOR DATA -; A CONTAINS CURRENT BANK -; ON EXIT DE CONTAINS ID WORD -; A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL -;====================================================================== -; -FF_ERASE: ; THIS CODE GETS RELOCATED TO HIGH MEMORY -; - PUSH AF ; SAVE CURRENT BANK - LD A,B ; SELECT BANK - CALL HBX_BNKSEL ; TO PROGRAM -; - LD HL,$5555 ; LD A,$AA ; COMMAND - LD (HL),$AA ; LD ($5555),A ; SETUP - LD A,L ; LD A,$55 - LD ($2AAA),A ; LD ($2AAA),A - LD (HL),$80 ; LD A,$80 - LD (HL),$AA ; LD ($5555),A - LD A,L ; LD A,$AA - LD ($2AAA),A ; LD ($5555),A - LD (HL),$10 ; LD A,$55 - ; LD ($2AAA),A - ; LD A,$10 - ; LD ($5555),A -; - LD A,(HL) ; DO TWO SUCCESSIVE READS FROM THE SAME FLASH ADDRESS. -FF_WT2: LD C,(HL) ; IF TOGGLE BIT (BIT 6) - XOR C ; IS THE SAME ON BOTH READS - BIT 6,A ; THEN ERASE IS COMPLETE SO EXIT. - JR Z,FF_WT1 ; Z TRUE IF BIT 6=0 I.E. "NO TOGGLE" WAS DETECTED. -; - LD A,C ; OPERATION IS NOT COMPLETE. CHECK TIMEOUT BIT (BIT 5). - BIT 5,C ; IF NO TIMEOUT YET THEN LOOP BACK AND KEEP CHECKING TOGGLE STATUS - JR Z,FF_WT2 ; IF BIT 5=0 THEN RETRY; NZ TRUE IF BIT 5=1 -; - LD A,(HL) ; WE GOT A TIMEOUT. 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 - JR Z,FF_WT1 ; OTHERWISE ERASE OPERATION FAILED OR TIMED OUT. -; - LD (HL),$F0 ; WRITE DEVICE RESET - LD C,$FF ; SET FAIL STATUS - JR FF_WT3 -; -FF_WT1: LD C,0 ; SET SUCCESS STATUS -FF_WT3: POP AF -; LD A,B ; RETURN TO ORIGINAL BANK - CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY - RET -; -FF_E_SZ .EQU $-FF_ERASE ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED -; -;====================================================================== -; CALCULATE BANK AND ADDRESS DATA FROM MEMORY ADDRESS -; -; ON ENTRY DE:HL CONTAINS 32 BIT MEMORY ADDRESS. -; ON EXIT I,B CONTAINS BANK SELECT BYTE -; Y,C CONTAINS HIGH BYTE OF SECTOR ADDRESS -; A CONTAINS CURRENT BANK HB_CURBNK -; -; DDDDDDDDEEEEEEEE HHHHHHHHLLLLLLLL -; 3322222222221111 1111110000000000 -; 1098765432109876 5432109876543210 -; XXXXXXXXXXXXSSSS SSSSXXXXXXXXXXXX < S = SECTOR -; XXXXXXXXXXXXBBBB BXXXXXXXXXXXXXXX < B = BANK -;====================================================================== -; -FF_CALCA: -; -#IF (FF_DBG==1) - CALL PC_SPACE ; DISPLAY SECTOR - CALL PRTHEX32 ; SECTOR ADDRESS - CALL PC_SPACE ; IN DE:HL -#ENDIF -; - 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 -; - PUSH BC - POP IY -; -#IF (FF_DBG==1) - CALL PRTHEXWORD ; DISPLAY BANK AND - CALL PC_SPACE ; SECTOR RESULT -#ENDIF -; - LD A,(HB_CURBNK) ; WE ARE STARTING IN HB_CURBNK -; - RET -; -;====================================================================== -; ERASE FLASH SECTOR -; -; ON ENTRY DE:HL CONTAINS 32 BIT MEMORY ADDRESS. -; CALCULATE BANK AND ADDRESS DATA FROM ENTRY ADDRESS -; CREATE A CODE BUFFER IN HIGH MEMORY AREA -; COPY FLASH CODE TO CODE BUFFER -; CALL RELOCATED FLASH ERASE CODE -; RESTORE STACK -; RETURN WITH STATUS CODE. -; -; ON ENTRY DE:HL POINTS TO AN ADDRESS IDENTIFYING THE CHIP -; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL -;====================================================================== -; -FF_SINIT: - PUSH HL ; SAVE ADDRESS INFO - LD HL,FF_SERASE ; PUT ROUTINE TO CALL - EX (SP),HL ; ON THE STACK - JP FF_FNCALL ; EXECUTE -; -;====================================================================== -; ERASE FLASH SECTOR. -; -; SELECT THE APPROPRIATE BANK / ADDRESS -; ISSUE ERASE SECTOR COMMAND -; POLL TOGGLE BIT FOR COMPLETION STATUS. -; SELECT ORIGINAL BANK -; -; ON ENTRY BC CONTAINS BANK AND SECTOR DATA -; A CONTAINS CURRENT BANK -; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL -;====================================================================== -; -FF_SERASE: ; THIS CODE GETS RELOCATED TO HIGH MEMORY -; - PUSH AF ; SAVE CURRENT BANK - LD A,B ; SELECT BANK - CALL HBX_BNKSEL ; TO PROGRAM - ; - LD HL,$5555 ; LD A,$AA ; COMMAND - LD A,L ; LD ($5555),A ; SETUP - LD (HL),$AA ; LD A,$55 - LD ($2AAA),A ; LD ($2AAA),A - LD (HL),$80 ; LD A,$80 - LD (HL),$AA ; LD ($5555),A - LD ($2AAA),A ; LD A,$AA - ; LD ($5555),A - ; LD A,$55 - ; LD ($2AAA),A - - LD H,C ; SECTOR - LD L,$00 ; ADDRESS -; - LD A,$30 ; SECTOR ERASE - LD (HL),A ; COMMAND -; -; LD DE,$0000 ; DEBUG COUNT -; - LD A,(HL) ; DO TWO SUCCESSIVE READS -FF_WT4: LD C,(HL) ; FROM THE SAME FLASH ADDRESS. - XOR C ; IF THE SAME ON BOTH READS - BIT 6,A ; THEN ERASE IS COMPLETE SO EXIT. -; INC DE ; - JR Z,FF_WT5 ; BIT 6 = 0 IF SAME ON SUCCESSIVE READS = COMPLETE - ; BIT 6 = 1 IF DIFF ON SUCCESSIVE READS = INCOMPLETE -; - LD A,C ; OPERATION IS NOT COMPLETE. CHECK TIMEOUT BIT (BIT 5). - BIT 5,C ; IF NO TIMEOUT YET THEN LOOP BACK AND KEEP CHECKING TOGGLE STATUS - JR Z,FF_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 - XOR (HL) ; THE OPERATION. DO TWO SUCCESSIVE READS. ARE THEY THE SAME? - BIT 6,A ; IF THEY ARE THEN OPERATION WAS COMPLETED - JR Z,FF_WT5 ; OTHERWISE ERASE OPERATION FAILED OR TIMED OUT. -; - LD (HL),$F0 ; WRITE DEVICE RESET - LD C,$FF ; SET FAIL STATUS - JR FF_WT6 -; -FF_WT5: LD C,0 ; SET SUCCESS STATUS -FF_WT6: POP AF ; RETURN TO ORIGINAL BANK - CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY -; - RET -; -FF_S_SZ .EQU $-FF_SERASE ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED -; -;====================================================================== -; READ FLASH SECTOR OF 4096 BYTES -; -; SET ADDRESS TO START OF SECTOR -; CALCULATE BANK AND ADDRESS DATA FROM SECTOR START ADDRESS -; CREATE A CODE BUFFER IN HIGH MEMORY AREA -; COPY FLASH CODE TO CODE BUFFER -; CALL RELOCATED FLASH READ SECTOR CODE -; RESTORE STACK -; -; ON ENTRY DE:HL POINTS TO A 32 BIT MEMORY ADDRESS. -; IX POINTS TO WHERE TO SAVE DATA -;====================================================================== -; -FF_RINIT: - LD L,0 ; CHANGE ADDRESS - LD A,H ; TO SECTOR BOUNDARY - AND $F0 ; BY MASKING OFF - LD H,A ; LOWER 12 BITS -; - PUSH HL ; SAVE ADDRESS INFO - LD HL,FF_SREAD ; PUT ROUTINE TO CALL - EX (SP),HL ; ON THE STACK - JP FF_FNCALL ; EXECUTE -; - RET -;====================================================================== -; FLASH READ SECTOR. -; -; SELECT THE APPROPRIATE BANK / ADDRESS -; READ SECTOR OF 4096 BYTES, BYTE AT A TIME -; SELECT SOURCE BANK, READ DATA, -; SELECT DESTINATION BANK, WRITE DATA -; DESTINATION BANK IS ALWAYS CURRENT BANK -; -; ON ENTRY BC CONTAINS BANK AND SECTOR DATA -; IX POINTS TO DATA TO BE WRITTEN -; A CONTAINS CURRENT BANK -; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL -;====================================================================== -; -FF_SREAD: ; THIS CODE GETS RELOCATED TO HIGH MEMORY -; - PUSH AF ; SAVE CURRENT BANK -; - LD H,C ; SECTOR - LD L,$00 ; ADDRESS - LD D,L ; INITIALIZE - LD E,L ; BYTE COUNT -; -FF_RD1: - LD A,B ; SELECT BANK - CALL HBX_BNKSEL ; TO READ - LD C,(HL) ; READ BYTE -; - POP AF - PUSH AF ; SELECT BANK - CALL HBX_BNKSEL ; TO WRITE - LD (IX+0),C ; WRITE BYTE - - INC HL ; NEXT SOURCE LOCATION - INC IX ; NEXT DESTINATION LOCATION -; - INC DE ; CONTINUE READING UNTIL - BIT 4,D ; WE HAVE DONE ONE SECTOR - JR Z,FF_RD1 - - POP AF ; RETURN TO ORIGINAL BANK -; CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY - XOR A -; - RET -; -FF_R_SZ .EQU $-FF_SREAD ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED -; -;====================================================================== -; WRITE FLASH SECTOR OF 4096 BYTES -; -; SET ADDRESS TO START OF SECTOR -; CALCULATE BANK AND ADDRESS DATA FROM SECTOR START ADDRESS -; CREATE A CODE BUFFER IN HIGH MEMORY AREA -; COPY FLASH CODE TO CODE BUFFER -; CALL RELOCATED FLASH WRITE SECTOR CODE -; RESTORE STACK -; -; ON ENTRY DE:HL POINTS TO A 32 BIT MEMORY ADDRESS. -; IX POINTS TO DATA TO BE WRITTEN -;====================================================================== -; -FF_WINIT: - LD L,0 ; CHANGE ADDRESS - LD A,H ; TO SECTOR BOUNDARY - AND $F0 ; BY MASKING OFF - LD H,A ; LOWER 12 BITS -; - PUSH HL ; SAVE ADDRESS INFO - LD HL,FF_SWRITE ; PUT ROUTINE TO CALL - EX (SP),HL ; ON THE STACK - JP FF_FNCALL ; EXECUTE -; -;====================================================================== -; FLASH WRITE SECTOR. -; -; SELECT THE APPROPRIATE BANK / ADDRESS -; WRITE 1 SECTOR OF 4096 BYTES, BYTE AT A TIME -; ISSUE WRITE BYTE COMMAND AND WRITE THE DATA BYTE -; POLL TOGGLE BIT FOR COMPLETION STATUS. -; SELECT ORIGINAL BANK -; -; ON ENTRY BC CONTAINS BANK AND SECTOR DATA -; IX POINTS TO DATA TO BE WRITTEN -; A CONTAINS CURRENT BANK -; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL -;====================================================================== -; -FF_SWRITE: ; THIS CODE GETS RELOCATED TO HIGH MEMORY -; - PUSH AF ; SAVE CURRENT BANK -; - LD H,C ; SECTOR - LD L,$00 ; ADDRESS - LD D,L ; INITIALIZE - LD E,L ; BYTE COUNT -; -FF_WR1: - POP AF ; SELECT BANK - PUSH AF ; TO READ - CALL HBX_BNKSEL -; - LD C,(IX+0) ; READ IN BYTE -; - LD A,B ; SELECT BANK - CALL HBX_BNKSEL ; TO PROGRAM -; - LD A,$AA ; COMMAND - LD ($5555),A ; SETUP - LD A,$55 - LD ($2AAA),A -; - LD A,$A0 ; WRITE - LD ($5555),A ; COMMAND -; - LD (HL),C ; WRITE OUT BYTE -; -; ; DO TWO SUCCESSIVE READS - LD A,(HL) ; FROM THE SAME FLASH ADDRESS. -FF_WT7: LD C,(HL) ; IF TOGGLE BIT (BIT 6) - XOR C ; IS THE SAME ON BOTH READS - BIT 6,A ; THEN ERASE IS COMPLETE SO EXIT. - JR NZ,FF_WT7 ; Z TRUE IF BIT 6=0 I.E. "NO TOGGLE" WAS DETECTED. -; - INC HL ; NEXT DESTINATION LOCATION - INC IX ; NEXT SOURCE LOCATION -; - INC DE ; CONTINUE WRITING UNTIL - BIT 4,D ; WE HAVE DONE ONE SECTOR - JR Z,FF_WR1 -; - POP AF ; RETURN TO ORIGINAL BANK - CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY -; - RET -; -FF_W_SZ .EQU $-FF_SWRITE ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED -; -;====================================================================== -; -; FLASH STYLE -; -;====================================================================== -; -ST_NORMAL .EQU 0 -ST_ERASE_CHIP .EQU 1 ; SECTOR BASED ERASE NOT SUPPORTED -ST_PROGRAM_SECT .EQU 2 -; -;====================================================================== -; -; FLASH CHIP MACRO -; -;====================================================================== -; -#DEFINE FF_CHIP(FFROMID,FFROMNM,FFROMSS,FFROMSC,FFROMMD)\ -#DEFCONT ; \ -#DEFCONT .DW FFROMID \ -#DEFCONT .DB FFROMNM \ -#DEFCONT .DW FFROMSS \ -#DEFCONT .DW FFROMSC \ -#DEFCONT .DB FFROMMD \ -#DEFCONT ; -; -;====================================================================== -; -; FLASH CHIP LIST -; -;====================================================================== -; -FF_TABLE: -FF_CHIP(00120H,"29F010$ ",128,8,ST_NORMAL) -FF_CHIP(001A4H,"29F040$ ",512,8,ST_NORMAL) -FF_CHIP(01F04H,"AT49F001NT$",1024,1,ST_ERASE_CHIP) -FF_CHIP(01F05H,"AT49F001N$ ",1024,1,ST_ERASE_CHIP) -FF_CHIP(01F07H,"AT49F002N$ ",2048,1,ST_ERASE_CHIP) -FF_CHIP(01F08H,"AT49F002NT$",2048,1,ST_ERASE_CHIP) -FF_CHIP(01F13H,"AT49F040$ ",4096,1,ST_ERASE_CHIP) -FF_CHIP(01F5DH,"AT29C512$ ",1,512,ST_PROGRAM_SECT) -FF_CHIP(01FA4H,"AT29C040$ ",2,2048,ST_PROGRAM_SECT) -FF_CHIP(01FD5H,"AT29C010$ ",1,1024,ST_PROGRAM_SECT) -FF_CHIP(01FDAH,"AT29C020$ ",2,1024,ST_PROGRAM_SECT) -FF_CHIP(02020H,"M29F010$ ",128,8,ST_PROGRAM_SECT) -FF_CHIP(020E2H,"M29F040$ ",512,8,ST_NORMAL) -FF_CHIP(0BFB5H,"39F010$ ",32,32,ST_NORMAL) -FF_CHIP(0BFB6H,"39F020$ ",32,64,ST_NORMAL) -FF_CHIP(0BFB7H,"39F040$ ",32,128,ST_NORMAL) -FF_CHIP(0C2A4H,"MX29F040$ ",512,8,ST_NORMAL) -; -FF_T_CNT .EQU 17 -FF_T_SZ .EQU ($-FF_TABLE) / FF_T_CNT -FF_UNKNOWN .DB "UNKNOWN$" -FF_STACK: .DW 0 -; -;====================================================================== -; -; 4K FLASH BUFFER -; -;====================================================================== -; -FF_BUFFER .FILL 4096,$FF -;====================================================================== -; -; RELOCATABLE CODE SPACE REQUIREMENTS -; -;====================================================================== -; -FF_CSIZE .EQU 0 -; -#IF (FF_W_SZ>FF_CSIZE) -FF_CSIZE .SET FF_W_SZ -#ENDIF -#IF (FF_S_SZ>FF_CSIZE) -FF_CSIZE .SET FF_S_SZ -#ENDIF -#IF (FF_E_SZ>FF_CSIZE) -FF_CSIZE .SET FF_E_SZ -#ENDIF -#IF (FF_I_SZ>FF_CSIZE) -FF_CSIZE .SET FF_I_SZ -#ENDIF -#IF (FF_R_SZ>FF_CSIZE) -FF_CSIZE .SET FF_R_SZ -#ENDIF -; - .ECHO "FF requires " - .ECHO FF_CSIZE - .ECHO " bytes high memory space.\n" diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 1205b0c3..cf0e7b82 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1905,9 +1905,6 @@ HB_INITTBL: #IF (MDENABLE) .DW MD_INIT #ENDIF -#IF (FFENABLE) - .DW FF_INIT -#ENDIF #IF (FDENABLE) .DW FD_INIT #ENDIF @@ -3626,14 +3623,6 @@ SIZ_MD .EQU $ - ORG_MD .ECHO SIZ_MD .ECHO " bytes.\n" #ENDIF -#IF (FFENABLE) -ORG_FF .EQU $ - #INCLUDE "flashfs.asm" -SIZ_FF .EQU $ - ORG_FF - .ECHO "FF occupies " - .ECHO SIZ_FF - .ECHO " bytes.\n" -#ENDIF ; #IF (FDENABLE) ORG_FD .EQU $ @@ -4101,6 +4090,8 @@ PS_PRTDC: JR Z,PS_PRTDC1 ; PRINT CAPACITY IN KB CP 5 ; RAM DISK? JR Z,PS_PRTDC1 ; PRINT CAPACITY IN KB + CP 7 ; FLASH DISK? + JR Z,PS_PRTDC1 ; PRINT CAPACITY IN KB ; ; PRINT HARD DISK STORAGE SIZE IN MB LD B,BF_DIOCAP ; HBIOS FUNC: GET CAPACTIY @@ -4501,7 +4492,7 @@ PS_DDHDSK .TEXT "HDSK$" ; PS_DTSTRREF: .DW PS_DTFLOP, PS_DTHARD, PS_DTCF, PS_DTSD - .DW PS_DTUSB, PS_DTROM, PS_DTRAM, PS_DTRF + .DW PS_DTUSB, PS_DTROM, PS_DTRAM, PS_DTRF, PS_DTFSH ; PS_DTFLOP .TEXT "Floppy Disk$" PS_DTHARD .TEXT "Hard Disk$" @@ -4511,6 +4502,7 @@ PS_DTUSB .TEXT "USB Drive$" PS_DTROM .TEXT "ROM Disk$" PS_DTRAM .TEXT "RAM Disk$" PS_DTRF .TEXT "RAM Floppy$" +PS_DTFSH .TEXT "Flash Drive$" PS_DTOTHER .TEXT "???$" ; ; FLOPPY ATTRIBUTE STRINGS diff --git a/Source/HBIOS/md.asm b/Source/HBIOS/md.asm index 1761b530..b3fb5180 100644 --- a/Source/HBIOS/md.asm +++ b/Source/HBIOS/md.asm @@ -6,11 +6,19 @@ ; MD DEVICE CONFIGURATION ; MD_DEVCNT .EQU 2 ; NUMBER OF MD DEVICES SUPPORTED -MD_CFGSIZ .EQU 6 ; SIZE OF CFG TBL ENTRIES +MD_CFGSIZ .EQU 8 ; SIZE OF CFG TBL ENTRIES ; MD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) MD_STAT .EQU 1 ; OFFSET OF STATUS (BYTE) MD_LBA .EQU 2 ; OFFSET OF LBA (DWORD) +MD_MID .EQU 6 ; OFFSET OF MEDIA ID (BYTE) +MD_ATTRIB .EQU 7 ; OFFSET OF ATTRIBUTE (BYTE) +; +MD_AROM .EQU %00100000 ; ROM ATTRIBUTE +MD_ARAM .EQU %00101000 ; RAM ATTRIBUTE +MD_AFSH .EQU %00111000 ; FLASH ATTRIBUTE +; +MID_MDFS .EQU 10 ; REWRITEABLE FLASH MEDIA ; ; DEVICE CONFIG TABLE (RAM DEVICE FIRST TO MAKE IT ALWAYS FIRST DRIVE) ; @@ -19,10 +27,14 @@ MD_CFGTBL: .DB 1 ; DRIVER DEVICE NUMBER .DB 0 ; DEVICE STATUS .DW 0,0 ; CURRENT LBA + .DB MID_MDRAM ; DEVICE MEDIA ID + .DB MD_ARAM ; DEVICE ATTRIBUTE ; DEVICE 0 (ROM) .DB 0 ; DEVICE NUMBER .DB 0 ; DEVICE STATUS .DW 0,0 ; CURRENT LBA + .DB MID_MDROM ; DEVICE MEDIA ID + .DB MD_AROM ; DEVICE ATTRIBUTE ; #IF ($ - MD_CFGTBL) != (MD_DEVCNT * MD_CFGSIZ) .ECHO "*** INVALID MD CONFIG TABLE ***\n" @@ -33,6 +45,8 @@ MD_CFGTBL: ; ; MD_INIT: + CALL FF_INIT ; PROBE FLASH CAPABILITY + CALL NEWLINE ; FORMATTING PRTS("MD: UNITS=2 $") PRTS("ROMDISK=$") @@ -50,9 +64,14 @@ MD_INIT: PUSH BC CALL DIO_ADDENT POP BC +;#IF (FFENABLE) ; IF FLASH +; LD A,(FF_RW) ; FILESYSTEM +; OR A ; ENABLED SKIP +; JR Z,MD_IN1 ; ROM DISK +;#ENDIF LD DE,MD_CFGTBL + MD_CFGSIZ CALL DIO_ADDENT -; +MD_IN1: XOR A ; INIT SUCCEEDED RET ; RETURN ; @@ -88,8 +107,8 @@ MD_DEFMED: ; ; MD_STATUS: - XOR A ; ALWAYS OK - RET +; XOR A ; ALWAYS OK +; RET ; ; ; @@ -130,7 +149,7 @@ MD_GEOM: ; A DISK DEVICE WITH 1 HEAD AND 16 SECTORS / TRACK. CALL MD_CAP ; HL := CAPACITY IN BLOCKS LD D,1 | $80 ; HEADS / CYL := 1 BY DEFINITION, SET LBA CAPABILITY BIT - LD E,16 ; SECTORS / TRACK := 16 BY DEFINTION + LD E,16 ; SECTORS / TRACK := 16 BY DEFINITION LD B,4 ; PREPARE TO DIVIDE BY 16 MD_GEOM1: SRL H ; SHIFT H @@ -143,12 +162,14 @@ MD_GEOM1: ; MD_DEVICE: LD D,DIODEV_MD ; D := DEVICE TYPE - LD A,(IY+MD_DEV) ; GET DEVICE NUMBER - LD E,A ; PUT IN E FOR RETURN - OR A ; SET FLAGS - LD C,%00100000 ; ASSUME ROM DISK ATTRIBUTES - JR Z,MD_DEVICE1 ; IF ZERO, IT IS ROM DISK, DONE - LD C,%00101000 ; USE RAM DISK ATTRIBUTES +; LD A,(IY+MD_DEV) ; GET DEVICE NUMBER +; LD E,A ; PUT IN E FOR RETURN +; OR A ; SET FLAGS + LD E,(IY+MD_DEV) + LD C,(IY+MD_ATTRIB) +; LD C,%00100000 ; ASSUME ROM DISK ATTRIBUTES +; JR Z,MD_DEVICE1 ; IF ZERO, IT IS ROM DISK, DONE +; LD C,%00101000 ; USE RAM DISK ATTRIBUTES LD H,0 ; H := 0, DRIVER HAS NO MODES LD L,0 ; L := 0, NO BASE I/O ADDRESS MD_DEVICE1: @@ -158,9 +179,10 @@ MD_DEVICE1: ; ; MD_MEDIA: - LD A,(IY+MD_DEV) ; GET DEVICE NUM - ADD A,MID_MDROM ; OFFSET BY MD ROM - LD E,A ; RESULTANT MEDIA ID TO E +; LD A,(IY+MD_DEV) ; GET DEVICE NUM +; ADD A,MID_MDROM ; OFFSET BY MD ROM +; LD E,A ; RESULTANT MEDIA ID TO E + LD E,(IY+MD_MID) LD D,0 ; D:0=0 MEANS NO MEDIA CHANGE XOR A ; SIGNAL SUCCESS RET @@ -409,6 +431,841 @@ MD_PRT: ; ; ; +;================================================================================================== +; FLASH DRIVER FOR FLASH & EEPROM PROGRAMMING +; +; 26 SEP 2020 - CHIP IDENTIFICATION IMPLEMENTED -- PHIL SUMMERS +; - CHIP ERASE IMPLEMENTED +; 23 OCT 2020 - SECTOR ERASE IMPLEMENTED +; 01 NOV 2020 - WRITE SECTOR IMPLEMENTED +; 04 DEC 2020 - READ SECTOR IMPLEMENTED +;================================================================================================== +; +; UPPER RAM BANK IS ALWAYS AVAILABLE REGARDLESS OF MEMORY BANK SELECTION. +; HBX_BNKSEL AND HB_CURBNK ARE ALWAYS AVAILABLE IN UPPER MEMORY. +; +; THE STACK IS IN UPPER MEMORY DURING BIOS INITIALIZATION BUT IS IN LOWER +; MEMORY DURING HBIOS CALLS. +; +; TO ACCESS THE FLASH CHIP FEATURES, CODE IS COPIED TO THE UPPER RAM BANK +; AND THE FLASH CHIP IS SWITCHED INTO THE LOWER BANK. +; +; INSPIRED BY WILL SOWERBUTTS FLASH4 UTILITY - https://github.com/willsowerbutts/flash4/ +; +;================================================================================================== +; +FF_DBG: .EQU 0 ; DEBUG +FF_HBX: .EQU 1 ; =0 USE STACK, =1 USE HBX_BUF +; +FF_RW .DB 00h ; READ WRITE FLAG +FF_TGT .EQU 0BFB7H ; TARGET CHIP FOR R/W FILESYSTEM +; +;====================================================================== +; BIOS FLASH INITIALIZATION +; +; IDENTIFY AND DISPLAY FLASH CHIPS IN SYSTEM. +; USES MEMORY SIZE DEFINED BY BUILD CONFIGURATION. +;====================================================================== +; +; +FF_INIT: + CALL NEWLINE ; DISLAY NUMBER + PRTS("FF: UNITS=$") ; OF UNITS + LD A,+(ROMSIZE/512) ; CONFIGURED FOR. + CALL PRTDECB +; + LD B,A ; NUMBER OF DEVICES TO PROBE + LD C,$00 ; START ADDRESS IS 0000:0000 IN DE:HL +FF_PROBE: + LD D,$00 ; SET ADDRESS IN DE:HL + LD E,C ; + LD H,D ; WE INCREASE E BY $08 + LD L,D ; ON EACH CYCLE THROUGH +; + PUSH BC + CALL PC_SPACE + LD A,+(ROMSIZE/512)+1 + SUB B ; PRINT + CALL PRTDECB ; DEVICE + LD A,'=' ; NUMBER + CALL COUT + CALL FF_IINIT ; GET ID AT THIS ADDRESS +; + PUSH HL + PUSH DE + LD H,FF_TGT&$FF ; IF WE MATCH WITH + LD L,FF_TGT/$FF + CCF ; A NON 39SF040 + SBC HL,DE ; CHIP SET THE + LD A,(FF_RW) ; R/W FLAG TO R/O + OR H + OR L + LD (FF_RW),A + POP DE + POP HL +; + CALL FF_LAND ; LOOKUP AND DISPLAY + POP BC +; + LD A,C ; UPDATE ADDRESS + ADD A,$08 ; TO NEXT DEVICE + LD C,A +; + DJNZ FF_PROBE ; ALWAYS AT LEAST ONE DEVICE +; + LD A,(FF_RW) + OR A + JR NZ,FF_PR1 + CALL PRTSTRD + .TEXT " FLASH FILESYSTEM ENABLED$" +FF_PR1: +; +#IF (FF_DBG==1) + CALL FF_TESTING +#ENDIF +; + XOR A ; INIT SUCCEEDED + RET +; +;====================================================================== +; TEST CODE AREA +;====================================================================== +; +FF_TESTING: +; +#IF (0) + LD DE,$0008 ; SET + LD HL,$0000 ; ADDRESS + CALL FF_EINIT ; CHIP ERASE + CALL PRTHEXBYTE ; DISPLAY STATUS +#ENDIF +; +#IF (0) + LD DE,$000A ; SET + LD HL,$8000 ; ADDRESS + CALL FF_SINIT ; SECTOR ERASE + CALL PRTHEXBYTE ; DISPLAY STATUS +#ENDIF +; +#IF (0) + LD DE,$000A ; SET DESTINATION + LD HL,$8000 ; ADDRESS + LD IX,FF_BUFFER ; SET SOURCE ADDRESS + CALL FF_WINIT ; WRITE SECTOR + CALL PRTHEXBYTE ; DISPLAY STATUS +#ENDIF +; +#IF (1) + LD DE,$0000 ; SET SOURCE + LD HL,$7000 ; ADDRESS + LD IX,FF_BUFFER ; SET DESTINATION ADDRESS + CALL FF_RINIT ; READ SECTOR + CALL PRTHEXBYTE ; DISPLAY STATUS + LD DE,FF_BUFFER + CALL DUMP_BUFFER +#ENDIF +; +#IF (1) + LD HL,FF_BUFFER ; FILL BUFFER + LD (HL),'J' + LD DE,FF_BUFFER+1 + LD BC,$1000-1 + LDIR +#ENDIF +; +#IF (1) + LD DE,$0000 ; SET + LD HL,$7000 ; ADDRESS + CALL FF_SINIT ; SECTOR ERASE + CALL PRTHEXBYTE ; DISPLAY STATUS +#ENDIF +#IF (1) + LD DE,$0000 ; SET DESTINATION + LD HL,$7000 ; ADDRESS + LD IX,FF_BUFFER ; SET SOURCE ADDRESS + CALL FF_WINIT ; WRITE SECTOR + CALL PRTHEXBYTE ; DISPLAY STATUS +#ENDIF +; +#IF (1) + LD DE,$0000 ; SET SOURCE + LD HL,$7000 ; ADDRESS + LD IX,FF_BUFFER ; SET DESTINATION ADDRESS + CALL FF_RINIT ; READ SECTOR + CALL PRTHEXBYTE ; DISPLAY STATUS + LD DE,FF_BUFFER + CALL DUMP_BUFFER +#ENDIF + RET +; +;====================================================================== +; LOOKUP AND DISPLAY CHIP +; +; ON ENTRY DE CONTAINS CHIP ID +; ON EXIT A CONTAINS STATUS 0=SUCCESS, NZ=NOT IDENTIFIED +;====================================================================== +; +FF_LAND: +; +#IF (FF_DBG==1) + PRTS(" ID:$") + LD H,E + LD L,D + CALL PRTHEXWORDHL ; DISPLAY FLASH ID + CALL PC_SPACE +#ENDIF +; + LD HL,FF_TABLE ; SEARCH THROUGH THE FLASH + LD BC,FF_T_CNT ; TABLE TO FIND A MATCH +FF_NXT1:LD A,(HL) + CP D + JR NZ,FF_NXT0 ; FIRST BYTE DOES NOT MATCH +; + INC HL + LD A,(HL) + CP E + DEC HL + JR NZ,FF_NXT0 ; SECOND BYTE DOES NOT MATCH +; + INC HL + INC HL + JR FF_NXT2 ; MATCH SO EXIT +; +FF_NXT0:PUSH BC ; WE DIDN'T MATCH SO POINT + LD BC,FF_T_SZ ; TO THE NEXT TABLE ENTRY + ADD HL,BC + POP BC +; + LD A,B ; CHECK IF WE REACHED THE + OR C ; END OF THE TABLE + DEC BC + JR NZ,FF_NXT1 ; NOT AT END YET +; + LD HL,FF_UNKNOWN ; WE REACHED THE END WITHOUT A MATCH +; +FF_NXT2:CALL PRTSTR ; AFTER SEARCH DISPLAY THE RESULT + RET +;====================================================================== +;COMMON FUNCTION CALL +; +;====================================================================== +; +#IF (FF_HBX==0) +FF_FNCALL: ; USING STACK FOR CODE AREA + CALL FF_CALCA ; GET BANK AND SECTOR DATA IN IY +; + POP DE ; GET ROUTINE TO CALL +; + LD (FF_STACK),SP ; SAVE STACK + LD HL,(FF_STACK) +; + LD BC,64 +; LD BC,FF_I_SZ ; CODE SIZE REQUIRED + CCF ; CREATE A RELOCATABLE + SBC HL,BC ; CODE BUFFER IN THE + LD SP,HL ; STACK AREA +; + PUSH HL ; SAVE THE EXECUTE ADDRESS + EX DE,HL ; PUT EXECUTE / START ADDRESS IN DE +; LD HL,FF_IDENT ; COPY OUR RELOCATABLE + LDIR ; CODE TO THE BUFFER + POP HL ; CALL OUR RELOCATABLE CODE + + PUSH IY ; PUT BANK AND SECTOR + POP BC ; DATA IN BC +; +#IF (FF_DBG==1) + CALL PRTHEXWORD +#ENDIF +; + HB_DI + CALL JPHL ; EXECUTE RELOCATED CODE + HB_EI +; + LD HL,(FF_STACK) ; RESTORE ORIGINAL + LD SP,HL ; STACK POSITION +; +#IF (FF_DBG==1) + CALL PC_SPACE + CALL PRTHEXWORD + CALL PC_SPACE + EX DE,HL + CALL PRTHEXWORDHL + CALL PC_SPACE + EX DE,HL +#ENDIF +; + LD A,C ; RETURN WITH STATUS IN A +; + RET +#ELSE +FF_FNCALL: ; USING HBX_BUF FOR CODE AREA + CALL FF_CALCA ; GET BANK AND SECTOR DATA IN IY +; + POP HL ; GET ROUTINE TO CALL +; + LD DE,HBX_BUF ; PUT EXECUTE / START ADDRESS IN DE + LD BC,HBX_BUFSIZ ; CODE SIZE REQUIRED +; + PUSH DE ; SAVE THE EXECUTE ADDRESS + ; COPY OUR RELOCATABLE + LDIR ; CODE TO THE BUFFER + POP HL ; CALL OUR RELOCATABLE CODE + + PUSH IY ; PUT BANK AND SECTOR + POP BC ; DATA IN BC +; +#IF (FF_DBG==1) + CALL PRTHEXWORD +#ENDIF +; + HB_DI + CALL JPHL ; EXECUTE RELOCATED CODE + HB_EI +; +#IF (FF_DBG==1) + CALL PC_SPACE + CALL PRTHEXWORD + CALL PC_SPACE + EX DE,HL + CALL PRTHEXWORDHL + CALL PC_SPACE + EX DE,HL +#ENDIF +; + LD A,C ; RETURN WITH STATUS IN A +; + RET + +#ENDIF +; +;====================================================================== +; IDENTIFY FLASH CHIP. +; CALCULATE BANK AND ADDRESS DATA FROM ENTRY ADDRESS +; CREATE A CODE BUFFER IN HIGH MEMORY AREA +; COPY FLASH CODE TO CODE BUFFER +; CALL RELOCATED FLASH IDENTITY CODE +; RESTORE STACK +; RETURN WITH ID CODE. +; +; ON ENTRY DE:HL POINTS TO AN ADDRESS WITH THE ADDRESS RANGE OF THE +; CHIP TO BE IDENTIFIED. +; ON EXIT DE CONTAINS THE CHIP ID BYTES. +; NO STATUS IS RETURNED +;====================================================================== +; +FF_IINIT: + PUSH HL ; SAVE ADDRESS INFO + LD HL,FF_IDENT ; PUT ROUTINE TO CALL + EX (SP),HL ; ON THE STACK + JP FF_FNCALL ; EXECUTE +; +;====================================================================== +; FLASH IDENTIFY +; SELECT THE APPROPRIATE BANK / ADDRESS +; ISSUE ID COMMAND +; READ IN ID WORD +; ISSUE ID EXIT COMMAND +; SELECT ORIGINAL BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; A CONTAINS CURRENT BANK +; ON EXIT DE CONTAINS ID WORD +; NO STATUS IS RETURNED +;====================================================================== +; +FF_IDENT: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + PUSH AF ; SAVE CURRENT BANK + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO PROGRAM +; + LD HL,$5555 ; LD A,$AA ; COMMAND + LD (HL),$AA ; LD ($5555),A ; SETUP + LD A,H ; LD A,$55 + LD ($2AAA),A ; LD ($2AAA),A + LD (HL),$90 ; LD A,$90 +; ; LD ($5555),A + LD DE,($0000) ; READ ID +; + LD A,$F0 ; ; EXIT + LD (HL),A ; LD ($5555),A ; COMMAND +; + POP AF ; RETURN TO ORIGINAL BANK + CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY +; + RET +; +FF_I_SZ .EQU $-FF_IDENT ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; FLASH CHIP ERASE. +; CALCULATE BANK AND ADDRESS DATA FROM ENTRY ADDRESS +; CREATE A CODE BUFFER IN HIGH MEMORY AREA +; COPY FLASH CODE TO CODE BUFFER +; CALL RELOCATED FLASH ERASE CODE +; RESTORE STACK +; RETURN WITH STATUS CODE. +; +; ON ENTRY DE:HL POINTS TO AN ADDRESS IDENTIFYING THE CHIP +; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL +;====================================================================== +; +FF_EINIT: + PUSH HL ; SAVE ADDRESS INFO + LD HL,FF_ERASE ; PUT ROUTINE TO CALL + EX (SP),HL ; ON THE STACK + JP FF_FNCALL ; EXECUTE +; +;====================================================================== +; ERASE FLASH CHIP. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; ISSUE ERASE COMMAND +; POLL TOGGLE BIT FOR COMPLETION STATUS. +; SELECT ORIGINAL BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; A CONTAINS CURRENT BANK +; ON EXIT DE CONTAINS ID WORD +; A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL +;====================================================================== +; +FF_ERASE: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + PUSH AF ; SAVE CURRENT BANK + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO PROGRAM +; + LD HL,$5555 ; LD A,$AA ; COMMAND + LD (HL),$AA ; LD ($5555),A ; SETUP + LD A,L ; LD A,$55 + LD ($2AAA),A ; LD ($2AAA),A + LD (HL),$80 ; LD A,$80 + LD (HL),$AA ; LD ($5555),A + LD A,L ; LD A,$AA + LD ($2AAA),A ; LD ($5555),A + LD (HL),$10 ; LD A,$55 + ; LD ($2AAA),A + ; LD A,$10 + ; LD ($5555),A +; + LD A,(HL) ; DO TWO SUCCESSIVE READS FROM THE SAME FLASH ADDRESS. +FF_WT2: LD C,(HL) ; IF TOGGLE BIT (BIT 6) + XOR C ; IS THE SAME ON BOTH READS + BIT 6,A ; THEN ERASE IS COMPLETE SO EXIT. + JR Z,FF_WT1 ; Z TRUE IF BIT 6=0 I.E. "NO TOGGLE" WAS DETECTED. +; + LD A,C ; OPERATION IS NOT COMPLETE. CHECK TIMEOUT BIT (BIT 5). + BIT 5,C ; IF NO TIMEOUT YET THEN LOOP BACK AND KEEP CHECKING TOGGLE STATUS + JR Z,FF_WT2 ; IF BIT 5=0 THEN RETRY; NZ TRUE IF BIT 5=1 +; + LD A,(HL) ; WE GOT A TIMEOUT. 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 + JR Z,FF_WT1 ; OTHERWISE ERASE OPERATION FAILED OR TIMED OUT. +; + LD (HL),$F0 ; WRITE DEVICE RESET + LD C,$FF ; SET FAIL STATUS + JR FF_WT3 +; +FF_WT1: LD C,0 ; SET SUCCESS STATUS +FF_WT3: POP AF +; LD A,B ; RETURN TO ORIGINAL BANK + CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY + RET +; +FF_E_SZ .EQU $-FF_ERASE ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; CALCULATE BANK AND ADDRESS DATA FROM MEMORY ADDRESS +; +; ON ENTRY DE:HL CONTAINS 32 BIT MEMORY ADDRESS. +; ON EXIT I,B CONTAINS BANK SELECT BYTE +; Y,C CONTAINS HIGH BYTE OF SECTOR ADDRESS +; A CONTAINS CURRENT BANK HB_CURBNK +; +; DDDDDDDDEEEEEEEE HHHHHHHHLLLLLLLL +; 3322222222221111 1111110000000000 +; 1098765432109876 5432109876543210 +; XXXXXXXXXXXXSSSS SSSSXXXXXXXXXXXX < S = SECTOR +; XXXXXXXXXXXXBBBB BXXXXXXXXXXXXXXX < B = BANK +;====================================================================== +; +FF_CALCA: +; +#IF (FF_DBG==1) + CALL PC_SPACE ; DISPLAY SECTOR + CALL PRTHEX32 ; SECTOR ADDRESS + CALL PC_SPACE ; IN DE:HL +#ENDIF +; + 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 +; + PUSH BC + POP IY +; +#IF (FF_DBG==1) + CALL PRTHEXWORD ; DISPLAY BANK AND + CALL PC_SPACE ; SECTOR RESULT +#ENDIF +; + LD A,(HB_CURBNK) ; WE ARE STARTING IN HB_CURBNK +; + RET +; +;====================================================================== +; ERASE FLASH SECTOR +; +; ON ENTRY DE:HL CONTAINS 32 BIT MEMORY ADDRESS. +; CALCULATE BANK AND ADDRESS DATA FROM ENTRY ADDRESS +; CREATE A CODE BUFFER IN HIGH MEMORY AREA +; COPY FLASH CODE TO CODE BUFFER +; CALL RELOCATED FLASH ERASE CODE +; RESTORE STACK +; RETURN WITH STATUS CODE. +; +; ON ENTRY DE:HL POINTS TO AN ADDRESS IDENTIFYING THE CHIP +; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL +;====================================================================== +; +FF_SINIT: + PUSH HL ; SAVE ADDRESS INFO + LD HL,FF_SERASE ; PUT ROUTINE TO CALL + EX (SP),HL ; ON THE STACK + JP FF_FNCALL ; EXECUTE +; +;====================================================================== +; ERASE FLASH SECTOR. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; ISSUE ERASE SECTOR COMMAND +; POLL TOGGLE BIT FOR COMPLETION STATUS. +; SELECT ORIGINAL BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; A CONTAINS CURRENT BANK +; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL +;====================================================================== +; +FF_SERASE: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + PUSH AF ; SAVE CURRENT BANK + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO PROGRAM + ; + LD HL,$5555 ; LD A,$AA ; COMMAND + LD A,L ; LD ($5555),A ; SETUP + LD (HL),$AA ; LD A,$55 + LD ($2AAA),A ; LD ($2AAA),A + LD (HL),$80 ; LD A,$80 + LD (HL),$AA ; LD ($5555),A + LD ($2AAA),A ; LD A,$AA + ; LD ($5555),A + ; LD A,$55 + ; LD ($2AAA),A + + LD H,C ; SECTOR + LD L,$00 ; ADDRESS +; + LD A,$30 ; SECTOR ERASE + LD (HL),A ; COMMAND +; +; LD DE,$0000 ; DEBUG COUNT +; + LD A,(HL) ; DO TWO SUCCESSIVE READS +FF_WT4: LD C,(HL) ; FROM THE SAME FLASH ADDRESS. + XOR C ; IF THE SAME ON BOTH READS + BIT 6,A ; THEN ERASE IS COMPLETE SO EXIT. +; INC DE ; + JR Z,FF_WT5 ; BIT 6 = 0 IF SAME ON SUCCESSIVE READS = COMPLETE + ; BIT 6 = 1 IF DIFF ON SUCCESSIVE READS = INCOMPLETE +; + LD A,C ; OPERATION IS NOT COMPLETE. CHECK TIMEOUT BIT (BIT 5). + BIT 5,C ; IF NO TIMEOUT YET THEN LOOP BACK AND KEEP CHECKING TOGGLE STATUS + JR Z,FF_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 + XOR (HL) ; THE OPERATION. DO TWO SUCCESSIVE READS. ARE THEY THE SAME? + BIT 6,A ; IF THEY ARE THEN OPERATION WAS COMPLETED + JR Z,FF_WT5 ; OTHERWISE ERASE OPERATION FAILED OR TIMED OUT. +; + LD (HL),$F0 ; WRITE DEVICE RESET + LD C,$FF ; SET FAIL STATUS + JR FF_WT6 +; +FF_WT5: LD C,0 ; SET SUCCESS STATUS +FF_WT6: POP AF ; RETURN TO ORIGINAL BANK + CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY +; + RET +; +FF_S_SZ .EQU $-FF_SERASE ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; READ FLASH SECTOR OF 4096 BYTES +; +; SET ADDRESS TO START OF SECTOR +; CALCULATE BANK AND ADDRESS DATA FROM SECTOR START ADDRESS +; CREATE A CODE BUFFER IN HIGH MEMORY AREA +; COPY FLASH CODE TO CODE BUFFER +; CALL RELOCATED FLASH READ SECTOR CODE +; RESTORE STACK +; +; ON ENTRY DE:HL POINTS TO A 32 BIT MEMORY ADDRESS. +; IX POINTS TO WHERE TO SAVE DATA +;====================================================================== +; +FF_RINIT: + LD L,0 ; CHANGE ADDRESS + LD A,H ; TO SECTOR BOUNDARY + AND $F0 ; BY MASKING OFF + LD H,A ; LOWER 12 BITS +; + PUSH HL ; SAVE ADDRESS INFO + LD HL,FF_SREAD ; PUT ROUTINE TO CALL + EX (SP),HL ; ON THE STACK + JP FF_FNCALL ; EXECUTE +; + RET +;====================================================================== +; FLASH READ SECTOR. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; READ SECTOR OF 4096 BYTES, BYTE AT A TIME +; SELECT SOURCE BANK, READ DATA, +; SELECT DESTINATION BANK, WRITE DATA +; DESTINATION BANK IS ALWAYS CURRENT BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; IX POINTS TO DATA TO BE WRITTEN +; A CONTAINS CURRENT BANK +; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL +;====================================================================== +; +FF_SREAD: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + PUSH AF ; SAVE CURRENT BANK +; + LD H,C ; SECTOR + LD L,$00 ; ADDRESS + LD D,L ; INITIALIZE + LD E,L ; BYTE COUNT +; +FF_RD1: + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO READ + LD C,(HL) ; READ BYTE +; + POP AF + PUSH AF ; SELECT BANK + CALL HBX_BNKSEL ; TO WRITE + LD (IX+0),C ; WRITE BYTE + + INC HL ; NEXT SOURCE LOCATION + INC IX ; NEXT DESTINATION LOCATION +; + INC DE ; CONTINUE READING UNTIL + BIT 4,D ; WE HAVE DONE ONE SECTOR + JR Z,FF_RD1 + + POP AF ; RETURN TO ORIGINAL BANK +; CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY + XOR A +; + RET +; +FF_R_SZ .EQU $-FF_SREAD ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; WRITE FLASH SECTOR OF 4096 BYTES +; +; SET ADDRESS TO START OF SECTOR +; CALCULATE BANK AND ADDRESS DATA FROM SECTOR START ADDRESS +; CREATE A CODE BUFFER IN HIGH MEMORY AREA +; COPY FLASH CODE TO CODE BUFFER +; CALL RELOCATED FLASH WRITE SECTOR CODE +; RESTORE STACK +; +; ON ENTRY DE:HL POINTS TO A 32 BIT MEMORY ADDRESS. +; IX POINTS TO DATA TO BE WRITTEN +;====================================================================== +; +FF_WINIT: + LD L,0 ; CHANGE ADDRESS + LD A,H ; TO SECTOR BOUNDARY + AND $F0 ; BY MASKING OFF + LD H,A ; LOWER 12 BITS +; + PUSH HL ; SAVE ADDRESS INFO + LD HL,FF_SWRITE ; PUT ROUTINE TO CALL + EX (SP),HL ; ON THE STACK + JP FF_FNCALL ; EXECUTE +; +;====================================================================== +; FLASH WRITE SECTOR. +; +; SELECT THE APPROPRIATE BANK / ADDRESS +; WRITE 1 SECTOR OF 4096 BYTES, BYTE AT A TIME +; ISSUE WRITE BYTE COMMAND AND WRITE THE DATA BYTE +; POLL TOGGLE BIT FOR COMPLETION STATUS. +; SELECT ORIGINAL BANK +; +; ON ENTRY BC CONTAINS BANK AND SECTOR DATA +; IX POINTS TO DATA TO BE WRITTEN +; A CONTAINS CURRENT BANK +; ON EXIT A RETURNS STATUS FLASH 0=SUCCESS FF=FAIL +;====================================================================== +; +FF_SWRITE: ; THIS CODE GETS RELOCATED TO HIGH MEMORY +; + PUSH AF ; SAVE CURRENT BANK +; + LD H,C ; SECTOR + LD L,$00 ; ADDRESS + LD D,L ; INITIALIZE + LD E,L ; BYTE COUNT +; +FF_WR1: + POP AF ; SELECT BANK + PUSH AF ; TO READ + CALL HBX_BNKSEL +; + LD C,(IX+0) ; READ IN BYTE +; + LD A,B ; SELECT BANK + CALL HBX_BNKSEL ; TO PROGRAM +; + LD A,$AA ; COMMAND + LD ($5555),A ; SETUP + LD A,$55 + LD ($2AAA),A +; + LD A,$A0 ; WRITE + LD ($5555),A ; COMMAND +; + LD (HL),C ; WRITE OUT BYTE +; +; ; DO TWO SUCCESSIVE READS + LD A,(HL) ; FROM THE SAME FLASH ADDRESS. +FF_WT7: LD C,(HL) ; IF TOGGLE BIT (BIT 6) + XOR C ; IS THE SAME ON BOTH READS + BIT 6,A ; THEN ERASE IS COMPLETE SO EXIT. + JR NZ,FF_WT7 ; Z TRUE IF BIT 6=0 I.E. "NO TOGGLE" WAS DETECTED. +; + INC HL ; NEXT DESTINATION LOCATION + INC IX ; NEXT SOURCE LOCATION +; + INC DE ; CONTINUE WRITING UNTIL + BIT 4,D ; WE HAVE DONE ONE SECTOR + JR Z,FF_WR1 +; + POP AF ; RETURN TO ORIGINAL BANK + CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY +; + RET +; +FF_W_SZ .EQU $-FF_SWRITE ; SIZE OF RELOCATABLE CODE BUFFER REQUIRED +; +;====================================================================== +; +; FLASH STYLE +; +;====================================================================== +; +ST_NORMAL .EQU 0 +ST_ERASE_CHIP .EQU 1 ; SECTOR BASED ERASE NOT SUPPORTED +ST_PROGRAM_SECT .EQU 2 +; +;====================================================================== +; +; FLASH CHIP MACRO +; +;====================================================================== +; +#DEFINE FF_CHIP(FFROMID,FFROMNM,FFROMSS,FFROMSC,FFROMMD)\ +#DEFCONT ; \ +#DEFCONT .DW FFROMID \ +#DEFCONT .DB FFROMNM \ +#DEFCONT .DW FFROMSS \ +#DEFCONT .DW FFROMSC \ +#DEFCONT .DB FFROMMD \ +#DEFCONT ; +; +;====================================================================== +; +; FLASH CHIP LIST +; +;====================================================================== +; +FF_TABLE: +FF_CHIP(00120H,"29F010$ ",128,8,ST_NORMAL) +FF_CHIP(001A4H,"29F040$ ",512,8,ST_NORMAL) +FF_CHIP(01F04H,"AT49F001NT$",1024,1,ST_ERASE_CHIP) +FF_CHIP(01F05H,"AT49F001N$ ",1024,1,ST_ERASE_CHIP) +FF_CHIP(01F07H,"AT49F002N$ ",2048,1,ST_ERASE_CHIP) +FF_CHIP(01F08H,"AT49F002NT$",2048,1,ST_ERASE_CHIP) +FF_CHIP(01F13H,"AT49F040$ ",4096,1,ST_ERASE_CHIP) +FF_CHIP(01F5DH,"AT29C512$ ",1,512,ST_PROGRAM_SECT) +FF_CHIP(01FA4H,"AT29C040$ ",2,2048,ST_PROGRAM_SECT) +FF_CHIP(01FD5H,"AT29C010$ ",1,1024,ST_PROGRAM_SECT) +FF_CHIP(01FDAH,"AT29C020$ ",2,1024,ST_PROGRAM_SECT) +FF_CHIP(02020H,"M29F010$ ",128,8,ST_PROGRAM_SECT) +FF_CHIP(020E2H,"M29F040$ ",512,8,ST_NORMAL) +FF_CHIP(0BFB5H,"39F010$ ",32,32,ST_NORMAL) +FF_CHIP(0BFB6H,"39F020$ ",32,64,ST_NORMAL) +FF_CHIP(0BFB7H,"39F040$ ",32,128,ST_NORMAL) +FF_CHIP(0C2A4H,"MX29F040$ ",512,8,ST_NORMAL) +; +FF_T_CNT .EQU 17 +FF_T_SZ .EQU ($-FF_TABLE) / FF_T_CNT +FF_UNKNOWN .DB "UNKNOWN$" +FF_STACK: .DW 0 +; +;====================================================================== +; +; 4K FLASH BUFFER +; +;====================================================================== +; +FF_BUFFER .FILL 4096,$FF +;====================================================================== +; +; RELOCATABLE CODE SPACE REQUIREMENTS +; +;====================================================================== +; +FF_CSIZE .EQU 0 +; +#IF (FF_W_SZ>FF_CSIZE) +FF_CSIZE .SET FF_W_SZ +#ENDIF +#IF (FF_S_SZ>FF_CSIZE) +FF_CSIZE .SET FF_S_SZ +#ENDIF +#IF (FF_E_SZ>FF_CSIZE) +FF_CSIZE .SET FF_E_SZ +#ENDIF +#IF (FF_I_SZ>FF_CSIZE) +FF_CSIZE .SET FF_I_SZ +#ENDIF +#IF (FF_R_SZ>FF_CSIZE) +FF_CSIZE .SET FF_R_SZ +#ENDIF +; + .ECHO "FF requires " + .ECHO FF_CSIZE + .ECHO " bytes high memory space.\n" + MD_RWFNADR .DW 0 ; MD_DSKBUF .DW 0