; -*- coding: utf-8 -*-
; forthMSP430FR_SD_LOAD.asm
-; Tested with MSP-EXP430FR5994 launchpad
-; Copyright (C) <2019> <J.M. THOORENS>
-;
-; This program is free software: you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation, either version 3 of the License, or
-; (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License
-; along with this program. If not, see <http://www.gnu.org/licenses/>.
-
+;Z SD_ACCEPT addr addr len -- addr' len' get line to interpret from a SD Card file
+; no interrupt allowed
+; defered word ACCEPT is redirected here by the word LOAD"
+; "defered" word CIB is redirected to SDIB (PAD if RAM<2k) by the word LOAD"
+; sequentially move an input line ended by CRLF from SD_BUF to PAD
+; if end of SD_BUF is reached before CRLF, asks Read_HandledFile to refill buffer with next sector
+; then load the end of the line to PAD ptr.
+; when all LOAD"ed files are read, redirects defered word ACCEPT to default ACCEPT and restore interpret pointers.
+; see CloseHandleT.
; used variables : BufferPtr, BufferLen
; SD card OPEN, LOAD subroutines
;-----------------------------------------------------------------------
+; used variables : BufferPtr, BufferLen
+
; rules for registers use
; S = error
; T = CurrentHdl, pathname
; ----------------------------------;
ClusterToFAT1sectWofstY ;WXY Input : Cluster ; Output: W = FATsector, Y = FAToffset
; ----------------------------------;
- MOV.B &ClusterL+1,W ;3 W = ClusterLoHI
- MOV.B &ClusterL,Y ;3 Y = ClusterLoLo
- CMP #1,&FATtype ;3 FAT16?
- JZ CTF1S_end ;2 yes
+ MOV.B &ClusterL+1,W ;3 W = ClusterLoHI
+ MOV.B &ClusterL,Y ;3 Y = ClusterLoLo
+ CMP #1,&FATtype ;3 FAT16?
+ JZ CTF1S_end ;2 yes
; input : Cluster n, max = 7FFFFF (SDcard up to 256 GB)
; ClusterLoLo*4 = displacement in 512 bytes sector ==> FAToffset
; ClusterHiLo&ClusterLoHi +C << 1 = relative FATsector + orgFAT1 ==> FATsector
; ----------------------------------;
- MOV.B &ClusterH,X ; X = 0:ClusterHiLo
- SWPB X ; X = ClusterHiLo:0
- ADD X,W ; W = ClusterHiLo:ClusterLoHi
+ MOV.B &ClusterH,X ; X = 0:ClusterHiLo
+ SWPB X ; X = ClusterHiLo:0
+ ADD X,W ; W = ClusterHiLo:ClusterLoHi
; ----------------------------------;
- SWPB Y ; Y = ClusterLoLo:0
- ADD Y,Y ;1 Y = ClusterLoLo:0 << 1 + carry for FATsector
- ADDC W,W ; W = ClusterHiLo:ClusterLoHi << 1 = ClusterHiLo:ClusterL / 128
- SWPB Y
+ SWPB Y ; Y = ClusterLoLo:0
+ ADD Y,Y ;1 Y = ClusterLoLo:0 << 1 + carry for FATsector
+ ADDC W,W ; W = ClusterHiLo:ClusterLoHi << 1 = ClusterHiLo:ClusterL / 128
+ SWPB Y
CTF1S_end
- ADD Y,Y ; Y = 0:ClusterLoLo << 1
- RET ;4
+ ADD Y,Y ; Y = 0:ClusterLoLo << 1
+ MOV @RSP+,PC ;4
; ----------------------------------;
.ENDIF ; MPY
; ----------------------------------;
CCFS_RET ;
- RET ;
+ MOV @RSP+,PC ;
; ----------------------------------;
; ----------------------------------;
ComputeHDLcurrentSector ; input: currentHandle, output: Cluster, Sector
; ----------------------------------;
- MOV HDLL_CurClust(T),&ClusterL;
- MOV HDLH_CurClust(T),&ClusterH;
- CALL #ComputeClusFrstSect ;
- MOV.B HDLB_ClustOfst(T),W ;
- ADD W,&SectorL ;
- ADDC #0,&SectorH ;
- RET ;
+ MOV HDLL_CurClust(T),&ClusterL ;
+ MOV HDLH_CurClust(T),&ClusterH ;
+ CALL #ComputeClusFrstSect ;
+ MOV.B HDLB_ClustOfst(T),W ;
+ ADD W,&SectorL ;
+ ADDC #0,&SectorH ;
+ MOV @RSP+,PC ;
; ----------------------------------;
-
-
; ----------------------------------; input : X = countdown_of_spaces, Y = name pointer in buffer
ParseEntryNameSpaces ;XY
; ----------------------------------; output: Z flag, Y is set after the last space char
SUB #1,X ;
JNZ ParseEntryNameSpacesLoop;
PENSL_END ;
- RET ;
+ MOV @RSP+,PC ;
; ----------------------------------;
SUBC #0,HDLH_CurSize(T) ;
ADD.B #1,HDLB_ClustOfst(T) ; current cluster offset is incremented
CMP.B &SecPerClus,HDLB_ClustOfst(T) ; Cluster Bound reached ?
- JLO SetBufLenAndLoadCurSector ; no
+ JNC SetBufLenAndLoadCurSector ; no
; ----------------------------------;
;SearchNextCluster ; yes
; ----------------------------------;
MOV.B #0,HDLB_ClustOfst(T) ; reset Current_Cluster sectors offset
CALL #HDLCurClusToFAT1sectWofstY;WXY Output: W=FATsector, Y=FAToffset, Cluster=HDL_CurCluster
- CALL #ReadFAT1SectorW ;SWX (< 65536)
+ ADD &OrgFAT1,W ;
+ MOV #0,X ;
+ CALL #ReadSectorWX ;SWX (< 65536)
MOV #0,HDLH_CurClust(T) ;
MOV SD_BUF(Y),HDLL_CurClust(T) ;
CMP #1,&FATtype ; FAT16?
CMP #0,HDLH_CurSize(T) ; CurSize > 65535 ?
JNZ LoadHDLcurrentSector ; yes
CMP HDLL_CurSize(T),&BufferPtr ; BufferPtr >= CurSize ? (BufferPtr = 0 or see RestorePreviousLoadedBuffer)
- JHS CloseHandleT ; yes
+ JC CloseHandleT ; yes
CMP #bytsPerSec,HDLL_CurSize(T) ; CurSize >= 512 ?
- JHS LoadHDLcurrentSector ; yes
+ JC LoadHDLcurrentSector ; yes
MOV HDLL_CurSize(T),&BufferLen ; no: adjust BufferLen
; ==================================;
LoadHDLcurrentSector ; <=== OPEN_WRITE_APPEND
; ----------------------------------; input : Cluster, EntryOfst
GetFreeHandle ;STWXY init handle(HDLL_DIRsect,HDLW_DIRofst,HDLL_FirstClus = HDLL_CurClust,HDLL_CurSize)
; ----------------------------------; output : T = new CurrentHdl
- MOV #8,S ; prepare file already open error
- MOV #FirstHandle,T ;
- MOV #0,X ; X = init previous handle as 0
+ MOV #8,S ; prepare file already open error
+ MOV #FirstHandle,T ;
+ MOV #0,X ; X = init previous handle as 0
; ----------------------------------;
SearchHandleLoop ;
; ----------------------------------;
- CMP.B #0,HDLB_Token(T) ; free handle ?
- JZ FreeHandleFound ; yes
+ CMP.B #0,HDLB_Token(T) ; free handle ?
+ JZ FreeHandleFound ; yes
AlreadyOpenTest ; no
CMP &ClusterH,HDLH_FirstClus(T);
JNE SearchNextHandle ;
JNZ SearchHandleLoop ;
ADD S,S ; 16 = no more handle error, abort ===>
InitHandleRET ;
- RET ;
+ MOV @RSP+,PC ;
; ----------------------------------;
FreeHandleFound ; T = new handle, X = previous handle
; ----------------------------------;
; ----------------------------------;
ReplaceInputBuffer ;
; ----------------------------------;
- MOV #SDIB_ORG,&PFACIB ; set SD Input Buffer as Current Input Buffer before return to QUIT
- MOV #SD_ACCEPT,&PFAACCEPT ; redirect ACCEPT to SD_ACCEPT before return to QUIT
+ MOV #SDIB_ORG,&CIB_ADR ; set SD Input Buffer as Current Input Buffer before return to QUIT
+ MOV #SD_ACCEPT,&PFAACCEPT ; redirect ACCEPT to SD_ACCEPT before return to QUIT
; ----------------------------------;
SaveBufferContext ; (see CloseHandleT)
; ----------------------------------;
MOV &SOURCE_LEN,HDLW_PrevLEN(T) ; = CPL
- SUB &TOIN,HDLW_PrevLEN(T) ; PREVLEN = CPL - >IN
+ SUB &TOIN,HDLW_PrevLEN(T) ; PREVLEN = CPL - >IN
MOV &SOURCE_ORG,HDLW_PrevORG(T) ; = CIB
- ADD &TOIN,HDLW_PrevORG(T) ; PrevORG = CIB + >IN
+ ADD &TOIN,HDLW_PrevORG(T) ; PrevORG = CIB + >IN
JMP SetBufLenAndLoadCurSector ; then RET
; ----------------------------------;
; ----------------------------------;
CloseHandleHere ;
; ----------------------------------;
- MOV.B #0,HDLB_Token(T) ; release the handle
- MOV @T,T ; T = previous handle
- MOV T,&CurrentHdl ; becomes current handle
- CMP #0,T ;
+ MOV.B #0,HDLB_Token(T) ; release the handle
+ MOV @T,T ; T = previous handle
+ MOV T,&CurrentHdl ; becomes current handle
+ CMP #0,T ;
JZ CloseHandleRet ; if no more handle
; ----------------------------------;
RestorePreviousLoadedBuffer ;
BIC #Z,SR ;
; ----------------------------------;
CloseHandleRet ;
- RET ; Z = 1 if no more handle
+ MOV @RSP+,PC ; Z = 1 if no more handle
; ----------------------------------;
; ==================================;
CloseHandleT ; <== CLOSE, Read_File, TERM2SD", OPEN_DEL
; ==================================;
- MOV &CurrentHdl,T ;
- CMP #0,T ; no handle?
- JZ CloseHandleRet ; RET
+ MOV &CurrentHdl,T ;
+ CMP #0,T ; no handle?
+ JZ CloseHandleRet ; RET
; ----------------------------------;
.IFDEF SD_CARD_READ_WRITE
- CMP.B #2,HDLB_Token(T) ; opened as write (updated) file ?
- JNZ TestClosedToken ; no
- CALL #WriteBuffer ;SWXY
- CALL #OPWW_UpdateDirectory ;SWXY
+ CMP.B #2,HDLB_Token(T) ; opened as write (updated) file ?
+ JNZ TestClosedToken ; no
+ CALL #WriteBuffer ;SWXY
+ CALL #OPWW_UpdateDirectory ;SWXY
.ENDIF ;
; ----------------------------------;
TestClosedToken ;
; ----------------------------------;
- CMP.B #0,HDLB_Token(T) ;
+ CMP.B #0,HDLB_Token(T) ;
; ----------------------------------;
CaseOfAnyReadWriteDelFileIsClosed ; token >= 0
; ----------------------------------;
; ----------------------------------;
ReturnOfSD_ACCEPT ;
; ----------------------------------;
- ADD #6,RSP ; R-- QUIT3 empties return stack
+ ADD #6,RSP ; R-- QUIT4 empties return stack
MOV @RSP+,IP ; skip return to SD_ACCEPT
; ----------------------------------;
CALL #CloseHandleHere ; Z = 1 if no more handle
; ----------------------------------;
RestoreDefaultACCEPT ; if no more handle, first loaded file is closed...
; ----------------------------------;
- MOV #TIB_ORG,&PFACIB ; restore TIB as Current Input Buffer for next line (next QUIT)
+ MOV #TIB_ORG,&CIB_ADR ; restore TIB as Current Input Buffer for next line (next QUIT)
MOV #BODYACCEPT,&PFAACCEPT ; restore default ACCEPT for next line (next QUIT)
MOV #ECHO,PC ; -- org len if return to Terminal ACCEPT
; ----------------------------------;
FORTHWORD "CLOSE" ;
; ----------------------------------;
CALL #CloseHandleT ;
- mNEXT ;
+ MOV @IP+,PC ;
; ----------------------------------;
.ENDIF ; SD_CARD_READ_WRITE
OPEN_EXEC ;
mDOCOL ; if exec state
.word lit,'"',WORDD,COUNT ; -- open_type addr u
- FORTHtoASM ;
+ .word $+2 ;
MOV @RSP+,IP ;
; ----------------------------------;
ParenOpen ; -- open_type HERE HERE as pathname ptr
CMP.B #'\\',-1(rDOCON) ; FirstNotEqualChar of Pathname = "\" ?
JZ OPN_EntryFound ;
CMP rDOCON,TOS ; EOS exceeded ?
- JLO OPN_EntryFound ; yes
+ JNC OPN_EntryFound ; yes
; ----------------------------------;
OPN_DIRentryMismatch ;
; ----------------------------------;
JMP OPN_EntryFound ;
OPN_ExtNotEqualChar ;
CMP rDOCON,TOS ; EOS exceeded ?
- JHS OPN_DIRentryMismatch ; no, loop back
+ JC OPN_DIRentryMismatch ; no, loop back
CMP.B #'\\',-1(rDOCON) ; FirstNotEqualChar = "\" ?
JNZ OPN_DIRentryMismatch ;
CALL #ParseEntryNameSpaces ; parse X spaces, X{0,...,3}
MOV &FATtype,&ClusterL ; set cluster as RootDIR cluster
OPN_DIRfoundNext ;
CMP rDOCON,TOS ; EOS exceeded ?
- JHS OPN_EndOfStringTest ; no: (we presume that FirstNotEqualChar = "\") ==> loop back
+ JC OPN_EndOfStringTest ; no: (we presume that FirstNotEqualChar = "\") ==> loop back
; ----------------------------------;
OPN_SetCurrentDIR ; -- open_type ptr
; ----------------------------------;
CMP #0,S ; open file happy end ?
JNZ OPEN_Error ; no
OPEN_LOAD_END
- mNEXT ;
+ MOV @IP+,PC ;
; ----------------------------------;
; ----------------------------------;
; Error 16 : NomoreHandle ; S = error 16
; ----------------------------------;
mDOCOL ; set ECHO, type Pathname, type #error, type "< OpenError"; no return
+ .word ECHO ;
.word XSQUOTE ; don't use S register
.byte 11,"< OpenError" ;
- .word BRAN,SD_QABORTYES ; to insert S error as flag, no return
-; ----------------------------------;
-
-
-
-
-
-
-
+ .word BRAN,ABORT_SD ; to insert S error as flag, no return
+; ----------------------------------;
+
+
+ .IFDEF BOOTLOADER
+ .IFNDEF CORE_COMPLEMENT
+ FORTHWORD "+"
+; https://forth-standard.org/standard/core/Plus
+; + n1/u1 n2/u2 -- n3/u3 add n1+n2
+ ADD @PSP+,TOS
+ MOV @IP+,PC
+ .ENDIF
+
+ FORTHWORD "BOOT"
+; BOOT RSTIV_MEM -- ; bootstrap on SD_CARD\BOOT.4th file
+; ; called by WARM
+; to enable bootstrap type: ' BOOT IS WARM
+; to disable bootstrap type: ' BOOT 2 + @ IS WARM
+ MOV @PC+,X
+PFA_BOOT .word INIT_SD ; X = INIT_SD
+ CMP #2,TOS ; RSTIV_MEM <> WARM ?
+ JC QSD_MEM ; yes
+ MOV @RSP+,PC ; if RSTIV_MEM U< 2, return to BODYWARM
+QSD_MEM BIT.B #CD_SD,&SD_CDIN ; SD_memory in SD_Card socket ?
+ JZ BOOT_YES ;
+ MOV 2(X),PC ; if no, goto previous INIT: INIT TERMINAL then ret to PFAWARM
+;---------------------------------------------------------------------------------
+; RESET 6: if RSTIV_MEM <> WARM, init TERM, init SD
+;---------------------------------------------------------------------------------
+BOOT_YES CALL X ; init TERM UC first then init SD card, TOS = RSTIV_MEM
+;---------------------------------------------------------------------------------
+; END OF RESET
+;---------------------------------------------------------------------------------
+ MOV #PSTACK-2,PSP ; PUSH 0 on Stack
+ MOV #0,0(PSP) ;
+ MOV #0,&STATE ; )
+ MOV #LSTACK,&LEAVEPTR ; > same as QUIT
+ MOV #RSTACK,RSP ; )
+ ASMtoFORTH ;
+ .word XSQUOTE ; -- RSTIV_MEM addr u
+ .byte 15,"LOAD\34 BOOT.4TH\34" ; LOAD" BOOT.4TH" issues error 2 if no such file...
+ .word BRAN,QUIT4 ; to interpret this string
+ .ENDIF