I do deep-embedded stuff, in assembly (because I like it) on the
68332, with most projects in the 4-8 kline sort of range (if I don't do something goofy like a 128 kbyte sine lookup.)I use C32C, a "universal" table-driven cross-assembler, with home-brew (PowerBasic) pre and post processors to tweak the syntax and format the listings (including adding a table of contents.)
The "make" process, a batch file, preprocesses the source, assembles it, post processes the listing, and builds a rom image from the assembler S28 file and, typically, 2-5 Xilinx .rbt FPGA config files. The whole thing takes maybe 4 seconds.
This subroutine erases blocks in flash memory, the same flash we're executing code out of. So it must be relocated into CPU ram to execute, since flash disappears while any blocks are being erased. That sort of thing is easy in assembly.
The .SBTTL directive creates an entry in the table of contents:
.SBTTL . FLASH BLOCK ERASE DRIVER
; THIS GETS RELOCATED TO CPURAM FOR EXECUTION
; D0 IS A BITMAP, WITH Bn NAMING BLOCK 'n' TO BE ERASED. ; ERASING BLOCK 0 IS *NOT* ALLOWED.
; USES D7
FEPRO: TST.W SILLY.W ; ARE WE IN RAM/DEBUG MODE? BNE.S FLEE ; IF SO, SKIP FLASH COMMANDS! ANDI.W # 7FEh, D0 ; TRIM MAP TO BITS 10..1 BEQ.S FLEE ; AND BAIL IF NONE!
; POKE THE 'BLOCK ERASE' PREAMBLE...
MOVE.W # 0AAh, 0555h*2.W ; AA TO WORD 555 1 MOVE.W # 055h, 02AAh*2.W ; 55 TO WORD 2AA 2 MOVE.W # 080h, 0555h*2.W ; 80 TO WORD 555 3 MOVE.W # 0AAh, 0555h*2.W ; AA TO WORD 555 4 MOVE.W # 055h, 02AAh*2.W ; 55 TO WORD 2AA 5
; WE NOW WRITE 030h TO THE START OF ALL BLOCKS TO ZAP...
X = CPURAM + {ETAB-FEPRO} ; 'ETAB' AS RELOCATED!
MOVEA.W # X, A0 ; AIM AT BLOCK POINTER LIST MOVE.W # 10-1, D7 ; WHICH HAS 10 REAL ENTRIES
ELOOP: BTST.L # 1, D0 ; TEST BIT1 FIRST! BEQ.S ESKIP ; NO BIT, SKIP THIS ONE MOVEA.L (A0), A1 ; GOT BIT, GET VALID BLOCK POINTER MOVE.W # 030h, (A1) ; AND POKE '30' TO REQUEST ERASE
ESKIP: ADDQ.L # 4, A0 ; HOP TO NEXT TABLE ADDRESS LSR.L # 1, D0 ; SLIDE BITMAP DOWN DBF D7, ELOOP ; AND TEST ALL BITS MOVE.W # 6000, D0 ; NOW POLL FOR DONE, 6 SECONDS MAX
FLUTE: MOVE.W # 2000, D7 ; INNER LOOP IS 1 MSEC
FLOOG: SUBQ.W # 1, D7 ; BNE.S FLOOG ; 500 NS/LOOP IN CPU RAM, 10 CLKS
; WHEN DONE, THE 'FOFO' WORD WILL REAPPEAR...
CMPI.W # 0F0F0h, FOFO.W ; CHECK AND BEQ.S FLEER ; SKIP ON DONE
SUBQ.W # 1, D0 ; NO GO, TOCK ANOTHER MILLISEC BNE.S FLUTE ; AND LOOP.
; DO THE READ/RESET COMMAND IN CASE WE HAD AN ERROR...
FLEER: MOVE.W # 0F0h, DUMMY.W ; F0 TO ANYWHERE WILL DO MOVE.W # 20, D7 ; BUT TIME OUT > 10 USEC FL10: SUBQ.W # 1, D7 ; TO MAKE SURE FLASH BNE.S FL10 ; IS BACK ONLINE.
FLEE: RTS
; FLASH BLOCK POINTERS:
.LONG 0 ; 0 16K