aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/msp430/drivers/flash
diff options
context:
space:
mode:
Diffstat (limited to 'amforth-6.5/msp430/drivers/flash')
-rw-r--r--amforth-6.5/msp430/drivers/flash/words/d-to-i.asm38
-rw-r--r--amforth-6.5/msp430/drivers/flash/words/flaligned.asm4
-rw-r--r--amforth-6.5/msp430/drivers/flash/words/flerase.asm39
-rw-r--r--amforth-6.5/msp430/drivers/flash/words/i-store.asm32
-rw-r--r--amforth-6.5/msp430/drivers/flash/words/ic-store.asm29
-rw-r--r--amforth-6.5/msp430/drivers/flash/words/init-ram.asm16
-rw-r--r--amforth-6.5/msp430/drivers/flash/words/save.asm7
-rw-r--r--amforth-6.5/msp430/drivers/flash/words/scrub.asm6
8 files changed, 171 insertions, 0 deletions
diff --git a/amforth-6.5/msp430/drivers/flash/words/d-to-i.asm b/amforth-6.5/msp430/drivers/flash/words/d-to-i.asm
new file mode 100644
index 0000000..12081f0
--- /dev/null
+++ b/amforth-6.5/msp430/drivers/flash/words/d-to-i.asm
@@ -0,0 +1,38 @@
+;Z D->I c-addr1 c-addr2 u -- move Data->Code
+; Block move from Data space to Code space. Flashable.
+; For the MSP430, this uses a "smart" algorithm that uses word writes,
+; rather than byte writes, whenever possible. Note that byte reads
+; are used for the source, so it need not be aligned.
+ CODEHEADER(XT_DTOI,4,"d->i")
+ MOV @PSP+,W ; dest adrs
+ MOV @PSP+,X ; src adrs
+ CMP #0,TOS
+ JZ DTOI_X
+DTOI_LOOP: ; Begin flash write sequence
+ DINT ; Disable interrupts
+ MOV #FWKEY,&FCTL3 ; Clear LOCK
+ MOV #FWKEY+WRT,&FCTL1 ; Enable write
+ ; If length is 1, or dest. address is odd, do a byte write.
+ ; Else, do a word write.
+ CMP #1,TOS
+ JZ DTOI_BYTE
+ BIT #1,W
+ JNZ DTOI_BYTE
+DTOI_WORD: MOV.B @X+,Y ; get low byte of word
+ MOV.B @X+,Q ; get high byte of word
+ SWPB Q
+ BIS Q,Y ; merge bytes
+ MOV Y,0(W) ; write byte to dest
+ ADD #2,W
+ SUB #1,TOS ; another 1 will be subtracted below
+ JMP DTOI_END
+DTOI_BYTE: MOV.B @X+,0(W) ; copy byte from src to dest
+ ADD #1,W
+DTOI_END: ; End flash write sequence
+ MOV #FWKEY,&FCTL1 ; Done. Clear WRT.
+ MOV #FWKEY+LOCK,&FCTL3 ; Set LOCK
+ EINT ; Enable interrupts
+ SUB #1,TOS
+ JNZ DTOI_LOOP
+DTOI_X: MOV @PSP+,TOS ; pop new TOS
+ NEXT
diff --git a/amforth-6.5/msp430/drivers/flash/words/flaligned.asm b/amforth-6.5/msp430/drivers/flash/words/flaligned.asm
new file mode 100644
index 0000000..9271eba
--- /dev/null
+++ b/amforth-6.5/msp430/drivers/flash/words/flaligned.asm
@@ -0,0 +1,4 @@
+;Z FLALIGNED a -- a' align IDP to flash boundary
+; $200 OVER - $1FF AND + ;
+ HEADER(XT_FLALIGNED,9,"flaligned",DOCOLON)
+ DW XT_DOLITERAL,0200h,XT_OVER,XT_MINUS,XT_DOLITERAL,01FFh,XT_AND,XT_PLUS,XT_EXIT
diff --git a/amforth-6.5/msp430/drivers/flash/words/flerase.asm b/amforth-6.5/msp430/drivers/flash/words/flerase.asm
new file mode 100644
index 0000000..e8cf97e
--- /dev/null
+++ b/amforth-6.5/msp430/drivers/flash/words/flerase.asm
@@ -0,0 +1,39 @@
+;Z FLERASE a-addr n --
+ CODEHEADER(XT_FLERASE,7,"flerase")
+ MOV @PSP+,W ; get address in W
+ ADD W,TOS ; TOS=end adrs (first unerased adrs)
+FLE_1:
+ CMP TOS,W ; adr-end
+ JC FLE_X ; if no borrow, adr>=end, do not erase
+ ; is it within Main flash?
+ CMP #FLASHSTART,W
+ JNC FLE_INFO ; if borrow, adr<start, check if Info
+ CMP #FLASHEND+1,W
+ JNC FLE_OK ; if no borrow, adr>end, check if Info
+FLE_INFO: ; is it within Info flash?
+ CMP #INFOSTART,W
+ JNC FLE_X ; if borrow, adr<start, do not erase
+ CMP #INFOEND+1,W
+ JC FLE_X ; if no borrow, adr>end, do not erase
+FLE_OK: ; Address is either in Main flash, or in Info flash.
+ ; Segment Erase from flash.
+ ; Assumes ACCVIE = NMIIE = OFIE = 0, watchdog disabled.
+ ; Per section 5.3.2 of MSP430 Family User's Guide
+ DINT ; Disable interrupts
+ MOV #FWKEY,&FCTL3 ; Clear LOCK
+ MOV #FWKEY+ERASE,&FCTL1 ; Enable segment erase
+ MOV #-1,0(W) ; Dummy write in segment to erase
+ MOV #FWKEY,&FCTL1 ; Done. Clear erase command.
+ MOV #FWKEY+LOCK,&FCTL3 ; Done, set LOCK
+ EINT ; Enable interrupts
+ ; Advance flash pointer by 512 bytes or 128 bytes
+ ; is it within Main flash?
+ CMP #FLASHSTART,W
+ JNC FL_INFO ; if borrow, adr<start, must be Info
+ CMP #FLASHEND+1,W
+ JC FL_INFO ; if no borrow, adr>end, must be Info
+ ADD #(MAINSEG-INFOSEG),W
+FL_INFO: ADD #INFOSEG,W
+ JMP FLE_1 ; continue till past end or outside limits
+FLE_X: MOV @PSP+,TOS
+ NEXT
diff --git a/amforth-6.5/msp430/drivers/flash/words/i-store.asm b/amforth-6.5/msp430/drivers/flash/words/i-store.asm
new file mode 100644
index 0000000..5febc64
--- /dev/null
+++ b/amforth-6.5/msp430/drivers/flash/words/i-store.asm
@@ -0,0 +1,32 @@
+;Z I! x a-addr -- store cell in Instruction memory
+ CODEHEADER(XT_STOREI,2,"!i")
+ MOV @PSP+,W ; get data to write
+ BIT #1,TOS
+ JNZ IST_X ; if not even address, do not write
+ CMP @TOS,W
+ JZ IST_X ; if memory is desired value, do not write
+ ; is it within Main flash?
+ CMP #FLASHSTART,TOS
+ JNC IST_INFO ; if borrow, adr<start, check if Info
+ CMP #FLASHEND+1,TOS
+ JNC IST_OK ; if no borrow, adr>end, check if Info
+IST_INFO: ; is it within Info flash?
+ CMP #INFOSTART,TOS
+ JNC IST_RAM ; if borrow, adr<start, assume it's RAM
+ CMP #INFOEND+1,TOS
+ JC IST_RAM ; if no borrow, adr>end, assume it's RAM
+IST_OK: ; Address is either in Main flash, or in Info flash.
+ ; Byte/word write from flash.
+ ; Assumes location to write is already erased
+ ; Assumes ACCVIE = NMIIE = OFIE = 0, watchdog disabled.
+ ; Per section 5.3.3 of MSP430 Family User's Guide
+ DINT ; Disable interrupts
+ MOV #FWKEY,&FCTL3 ; Clear LOCK
+ MOV #FWKEY+WRT,&FCTL1 ; Enable write
+IST_RAM: ; If RAM, jump here to write. FCTL1,FCTL3,EINT are superfluous
+ MOV W,0(TOS) ; Write word to flash location
+ MOV #FWKEY,&FCTL1 ; Done. Clear WRT.
+ MOV #FWKEY+LOCK,&FCTL3 ; Set LOCK
+ EINT ; Enable interrupts
+IST_X: MOV @PSP+,TOS ; pop new TOS
+ NEXT
diff --git a/amforth-6.5/msp430/drivers/flash/words/ic-store.asm b/amforth-6.5/msp430/drivers/flash/words/ic-store.asm
new file mode 100644
index 0000000..c8677ea
--- /dev/null
+++ b/amforth-6.5/msp430/drivers/flash/words/ic-store.asm
@@ -0,0 +1,29 @@
+;Z IC! x a-addr -- store char in Instruction memory
+ CODEHEADER(XT_CSTOREI,3,"c!i")
+ MOV @PSP+,W ; get data to write
+ CMP.B @TOS,W
+ JZ IST_X ; if memory is desired value, do not write
+ ; is it within Main flash?
+ CMP #FLASHSTART,TOS
+ JNC ICST_INFO ; if borrow, adr<start, check if Info
+ CMP #FLASHEND+1,TOS
+ JNC ICST_OK ; if no borrow, adr>end, check if Info
+ICST_INFO: ; is it within Info flash?
+ CMP #INFOSTART,TOS
+ JNC ICST_RAM ; if borrow, adr<start, assume it's RAM
+ CMP #INFOEND+1,TOS
+ JC ICST_RAM ; if no borrow, adr>end, assume it's RAM
+ICST_OK: ; Address is either in Main flash, or in Info flash.
+ ; Byte/word write from flash.
+ ; Assumes location to write is already erased
+ ; Assumes ACCVIE = NMIIE = OFIE = 0, watchdog disabled.
+ ; Per section 5.3.3 of MSP430 Family User's Guide
+ DINT ; Disable interrupts
+ MOV #FWKEY,&FCTL3 ; Clear LOCK
+ MOV #FWKEY+WRT,&FCTL1 ; Enable write
+ICST_RAM: ; If RAM, jump here to write. FCTL1,FCTL3,EINT are superfluous
+ MOV.B W,0(TOS) ; Write byte to flash location
+ MOV #FWKEY,&FCTL1 ; Done. Clear WRT.
+ MOV #FWKEY+LOCK,&FCTL3 ; Set LOCK
+ EINT ; Enable interrupts
+ JMP IST_X
diff --git a/amforth-6.5/msp430/drivers/flash/words/init-ram.asm b/amforth-6.5/msp430/drivers/flash/words/init-ram.asm
new file mode 100644
index 0000000..30fab64
--- /dev/null
+++ b/amforth-6.5/msp430/drivers/flash/words/init-ram.asm
@@ -0,0 +1,16 @@
+;Z INIT_RAM -- initialize RAM
+HEADER(XT_INIT_RAM,8,"init-ram",DOCOLON)
+; the first cell is either FFFF or the recognizer stack depth, see ram.asm
+ DW XT_DOLITERAL, INFOSTART, XT_FETCH
+ DW XT_ZEROLESS
+ DW XT_DOCONDBRANCH
+ DEST(COLD1)
+; there is no valid data in INFO flash
+ DW XT_UINIT,XT_DOBRANCH
+ DEST(COLD2)
+COLD1:
+; there is valid content in INFO, restore it
+ DW XT_DOLITERAL, INFOSTART
+COLD2:
+ DW XT_DOLITERAL,RAMINFOAREA,XT_DOLITERAL,INFO_SIZE,XT_CMOVE
+ dw XT_EXIT
diff --git a/amforth-6.5/msp430/drivers/flash/words/save.asm b/amforth-6.5/msp430/drivers/flash/words/save.asm
new file mode 100644
index 0000000..2e0e9c4
--- /dev/null
+++ b/amforth-6.5/msp430/drivers/flash/words/save.asm
@@ -0,0 +1,7 @@
+; SAVE erases the first 128 bytes of Info Flash, then
+; copies the User Area and subsequent RAM variables there.
+ HEADER(SAVE,4,"SAVE",DOCOLON)
+ DW XT_DOLITERAL,RAMINFOAREA
+ DW XT_DOLITERAL,INFOSTART
+ DW XT_DOLITERAL,INFO_SIZE
+ DW XT_2DUP,XT_FLERASE,XT_DTOI,XT_EXIT
diff --git a/amforth-6.5/msp430/drivers/flash/words/scrub.asm b/amforth-6.5/msp430/drivers/flash/words/scrub.asm
new file mode 100644
index 0000000..85fbe22
--- /dev/null
+++ b/amforth-6.5/msp430/drivers/flash/words/scrub.asm
@@ -0,0 +1,6 @@
+; SCRUB erases the application area of the Program Flash,
+; and then does COLD to reset the User Variables.
+ HEADER(SCRUB,5,"SCRUB",DOCOLON)
+ DW XT_DOLITERAL,INFOSTART,XT_DOLITERAL,INFO_SIZE,FLERASE
+ DW XT_DOLITERAL,FLASHSTART,XT_DOLITERAL,(FLASHEND-FLASHSTART),FLERASE
+ DW XT_COLD,XT_EXIT