diff --git a/Source/HBIOS/flashfs.asm b/Source/HBIOS/flashfs.asm index baf6af34..ca84d870 100644 --- a/Source/HBIOS/flashfs.asm +++ b/Source/HBIOS/flashfs.asm @@ -2,7 +2,9 @@ ;================================================================================================== ; FLASH DRIVER FOR FLASH & EEPROM PROGRAMMING ; -; 26 SEP 2020 - CURRENTLY ONLY IMPLEMENTS CHIP IDENTIFICATION -- PHIL SUMMERS +; 26 SEP 2020 - CHIP IDENTIFICATION IMPLMENTED -- PHIL SUMMERS +; - CHIP ERASE IMPLEMENTED +; 23 OCT 2020 - SECTOR ERASE IMPLEMENTED ;================================================================================================== ; ; UPPER RAM BANK IS ALWAYS AVAILABLE REGARDLESS OF MEMORY BANK SELECTION. HBX_BNKSEL AND @@ -59,9 +61,9 @@ FF_NXT1:LD A,(HL) INC HL INC HL JR FF_NXT2 ; MATCH SO EXIT - +; FF_NXT0:PUSH BC ; WE DIDN'T MATCH SO POINT - LD BC,17 ; TO THE NEXT TABLE ENTRY + LD BC,FF_T_SZ ; TO THE NEXT TABLE ENTRY ADD HL,BC POP BC ; @@ -109,43 +111,267 @@ FF_IDENT: ; FLASH ROM ID CODE `` ; FF_I_SZ .EQU $-FF_IDENT ; +;====================================================================== +; ERASE FLASH CHIP. +;====================================================================== +; +FF_EINIT: + LD (FF_STACK),SP ; SAVE STACK + LD HL,(FF_STACK) +; + LD BC,FF_E_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_ERASE ; COPY OUR RELOCATABLE + LDIR ; CODE TO THE BUFFER +; + LD A,(HB_CURBNK) ; WE ARE STARTING IN HB_CURBNK + LD B,A ; WHICH IS THE RAM COPY OF THE BIOS + LD A,BID_BOOT ; BID_BOOT IS ROM BANK 0 +; + POP HL ; CALL OUR RELOCATABLE CODE + CALL JPHL +; + LD HL,(FF_STACK) ; RESTORE ORIGINAL + LD SP,HL ; STACK POSITION +; + LD A,C ; RETURN WITH STATUS IN A + RET +; +;====================================================================== +; ERASE FLASH CHIP. THIS CODE IS RELOCATED AND EXECUTED IN THE STACK. +; IT SWITCHES THE BOTTOM BANK TO ROM BANK 0 I.E. BOTTOM OF CHIP ADDRESS RANGE. +; RETURNS THE BOTTOM BANK TO INITIAL STATE. ERASE COMMAND IS ISSUED TO +; THE FLASH CHIP AND THEN TOGGLE BIT IS MONITORED FOR COMPLETION. +; RETURN C=0 FOR SUCCESS OR C=FF FOR FAILURE. +;====================================================================== +; +FF_ERASE: + HB_DI + CALL HBX_BNKSEL ; SELECT ROM BANK 0 +; + LD A,$AA ; SET CHIP ERASE + LD ($5555),A +; + LD A,$55 + LD ($2AAA),A +; + LD A,$80 + LD ($5555),A +; + LD A,$AA + LD ($5555),A +; + LD A,$55 + LD ($2AAA),A +; + LD A,$10 + LD ($5555),A +; + LD HL,$5555 ; DO TWO SUCCESSIVE READS + LD A,(HL) ; 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 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_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: LD A,B ; RETURN TO ORIGINAL BANK + CALL HBX_BNKSEL ; WHICH IS OUR RAM BIOS COPY + HB_EI +; + RET +; +FF_E_SZ .EQU $-FF_ERASE +; +;====================================================================== +; ERASE FLASH SECTOR (1MB LIMIT) +; ON ENTRY DE:HL contains 32 bit memory address. +; The sector number is bits 19-12 i.e there are 256 sectors per 1024K +; The erase sector command must be written to the lowest 32K of each chip. +; The bank number is bits 19-15 i.e. there are up to 32 for 1024K +; +; DDDDDDDDEEEEEEEE HHHHHHHHLLLLLLLL +; 3322222222221111 1111110000000000 +; 1098765432109876 5432109876543210 +; XXXXXXXXXXXXSSSS SSSSXXXXXXXXXXXX < SECTOR = ADDRESS / 4096 - 0-256 +; XXXXXXXXXXXXBBBB BXXXXXXXXXXXXXXX < BANK = ADDRESS / 32768 + +;====================================================================== +; +FF_SINIT: + CALL PC_SPACE ; DISPLAY FULL + EX DE,HL + CALL PRTHEXWORDHL ; SECTOR ADDRESS DE:HL + EX DE,HL + CALL PRTHEXWORDHL + CALL PC_SPACE ; DISPLAY SECTOR +; + LD A,E ; BOTTOM PORTION OF SECTOR + AND $0F ; ADDRESS THAT GETS WRITTEN + RLC H ; WITH ERASE COMMAND BYTE + RLA ; A15 GETS MASKED OFF AND + LD B,A ; ADDED TO BANK SELECT +; + LD A,H ; TOP SECTION OF SECTOR + RRA ; ADDRESS THAT GETS WRITTEN ; REG C SET + AND $70 ; TO BANK SELECT PORT + LD C,A +; + PUSH BC + POP IY +; + LD (FF_STACK),SP ; SAVE STACK + LD HL,(FF_STACK) +; + LD BC,FF_S_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_SERASE ; COPY OUR RELOCATABLE + LDIR ; CODE TO THE BUFFER + POP HL ; CALL OUR RELOCATABLE CODE +; + LD A,(HB_CURBNK) ; WE ARE STARTING IN HB_CURBNK +; + CALL JPHL ; CALL FF_SERASE +; + LD HL,(FF_STACK) ; RESTORE ORIGINAL + LD SP,HL ; STACK POSITION +; + LD A,C ; STATUS + RET +; +;====================================================================== +; ERASE FLASH CHIP SECTOR. THIS CODE IS RELOCATED AND EXECUTED IN THE STACK. +; IT SWITCHES THE REQUIRED BANK TO THE BOTTOM OF CHIP ADDRESS RANGE. +; RETURNS THE BOTTOM BANK TO INITIAL STATE. ERASE SECTOR COMMAND IS ISSUED TO +; THE FLASH CHIP AND THEN TOGGLE BIT IS MONITORED FOR COMPLETION. +; ON ENTRY B CONTAINS THE START BANK WHICH WE RETURN TO AT THE END +; C CONTAINS THE TOP SECTION OF SECTOR WHICH SELECTS THE BANK. +;====================================================================== +; +FF_SERASE: + HB_DI + PUSH AF + LD A,0 + CALL HBX_BNKSEL ; SELECT ROM BANK FROM A +; + LD A,$AA ; SET SECTOR ERASE + LD ($5555),A +; + LD A,$55 + LD ($2AAA),A +; + LD A,$80 + LD ($5555),A +; + LD A,$AA + LD ($5555),A +; + LD A,$55 + LD ($2AAA),A +; + LD A,B + CALL HBX_BNKSEL ; SELECT ROM BANK FROM A +; + LD H,C + LD L,$00 + LD A,$30 ; SECTOR ADDRESS + LD (HL),A +; + LD A,0 + CALL HBX_BNKSEL ; SELECT ROM BANK FROM A +; + LD HL,$5555 ; DO TWO SUCCESSIVE READS + LD A,(HL) ; FROM THE SAME FLASH ADDRESS. +FF_WT4: 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_WT5 ; 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_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 + + HB_EI +; + RET +; +FF_S_SZ .EQU $-FF_SERASE +; ; FLASH STYLE ; ST_NORMAL .EQU 0 -ST_ERASE_CHIP .EQU 1 +ST_ERASE_CHIP .EQU 1 ; SECTOR BASED ERASE NOT SUPPORTED ST_PROGRAM_SECT .EQU 2 ; ; FLASH CHIP MACRO ; -#DEFINE FF_CHIP(FFROMID,FFROMNM,FFROMSS,FFROMMD) \ +#DEFINE FF_CHIP(FFROMID,FFROMNM,FFROMSS,FFROMSC,FFROMMD)\ #DEFCONT ; \ #DEFCONT .DW FFROMID \ #DEFCONT .DB FFROMNM \ #DEFCONT .DW FFROMSS \ -#DEFCONT .DW FFROMMD \ +#DEFCONT .DW FFROMSC \ +#DEFCONT .DB FFROMMD \ #DEFCONT ; ; ; FLASH CHIP LIST ; FF_TABLE: -FF_CHIP(00120H,"29F010$ ",128,ST_NORMAL) -FF_CHIP(001A4H,"29F040$ ",512,ST_NORMAL) -FF_CHIP(01F04H,"AT49F001NT$",1024,ST_ERASE_CHIP) -FF_CHIP(01F05H,"AT49F001N$ ",1024,ST_ERASE_CHIP) -FF_CHIP(01F07H,"AT49F002N$ ",2048,ST_ERASE_CHIP) -FF_CHIP(01F08H,"AT49F002NT$",2048,ST_ERASE_CHIP) -FF_CHIP(01F13H,"AT49F040$ ",4096,ST_ERASE_CHIP) -FF_CHIP(01F5DH,"AT29C512$ ",1,ST_PROGRAM_SECT) -FF_CHIP(01FA4H,"AT29C040$ ",2,ST_PROGRAM_SECT) -FF_CHIP(01FD5H,"AT29C010$ ",1,ST_PROGRAM_SECT) -FF_CHIP(01FDAH,"AT29C020$ ",2,ST_PROGRAM_SECT) -FF_CHIP(02020H,"M29F010$ ",128,ST_PROGRAM_SECT) -FF_CHIP(020E2H,"M29F040$ ",512,ST_NORMAL) -FF_CHIP(0BFB5H,"39F010$ ",32,ST_NORMAL) -FF_CHIP(0BFB6H,"39F020$ ",32,ST_NORMAL) -FF_CHIP(0BFB7H,"39F040$ ",32,ST_NORMAL) -FF_CHIP(0C2A4H,"MX29F040$ ",512,ST_NORMAL) -; -FF_T_CNT .EQU ($-FF_TABLE) / 17 +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