; -*- coding: utf-8 -*-
-; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
-
-; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
-; Copyright (C) <2017> <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
-; note : addr = TIB, addr' = PAD
+; no interrupt allowed
; defered word ACCEPT is redirected here by the word LOAD"
-; sequentially move an input line ended by CRLF from BUFFER to PAD
-; if end of buffer is reached before CRLF, asks Read_HandledFile to fill buffer with next sector
-; then move the end of the line.
-; when all LOAD"ed files are read, redirects defered word ACCEPT to (ACCEPT) and restore interpret pointers.
-; see CloseHandleT.
+; "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_File to refill buffer with next sector
+; then load the end of the line to SDIB_ptr.
+; when the last buffer is loaded, the handle is automaticaly closed
+; when all LOAD"ed files are read, redirects defered word ACCEPT to default ACCEPT and restore interpret pointers.
+; see CloseHandle.
; used variables : BufferPtr, BufferLen
-
-; ----------------------------------;
-; FORTHWORD "SD_ACCEPT" ; TIB TIB TIB_LEN -- PAD|SDIB len'
-; ----------------------------------;
-SD_ACCEPT ; sequentially move from BUFFER to SDIB (or PAD) a line of chars delimited by CRLF
-; ----------------------------------; up to TIB_LEN = 80 chars
- PUSH IP ;
- MOV #SDA_YEMIT_RET,IP ; set YEMIT return
-; ----------------------------------;
-StartNewLine ;
-; ----------------------------------;
- MOV &CurrentHdl,T ; prepare a link for the next LOADed file...
- MOV &BufferPtr,HDLW_BUFofst(T) ; ...see usage : HandleComplements
-; ----------------------------------; -- TIB TIB len
- .IFDEF RAM_1K ; use PAD as SD Input Buffer because the lack of RAM
- MOV #PAD,W ; W=dst
- .ELSEIF ; use SDIB as SD Input Buffer
- MOV #SDIB,W ; W=dst
- .ENDIF
- MOV W,2(PSP) ; -- StringOrg' TIB TIB_LEN
- MOV TOS,0(PSP) ; -- StringOrg' TIB_LEN TIB_LEN
- MOV #0,TOS ; -- StringOrg' TIB_LEN Count
-; ----------------------------------;
-SDA_InitSrcAddr ; <== SDA_GetFileNextSector
-; ----------------------------------;
- CMP #0,&BufferLen ; test if input buffer is empty (EOF)
- JZ SDA_GoToInterpret ; yes, to interpret an empty line (to do nothing)
- MOV &BufferPtr,X ; X=src
- JMP SDA_ComputeChar ;
+; QYEMIT uses only IP and Y registers
+; ==================================;
+; FORTHWORD "SD_ACCEPT" ; SDIB_org SDIB_org SDIB_len -- SDIB_org len IP = QUIT4
+; ==================================;
+SD_ACCEPT ; sequentially move from SD_BUF to SDIB a line of chars delimited by CRLF
+ PUSH IP ; R-- IP
+ MOV #SDA_YEMIT_RET,IP ; set QYEMIT return
+; ----------------------------------; up to CPL = 80 chars
+ MOV &CurrentHdl,T ; prepare a link for a next LOADed file, if any...
+ MOV &BufferPtr,HDLW_BUFofst(T) ; ...see usage : GetFreeHandle(CheckCaseOfLoadFileToken)
+; ----------------------------------;
+; SDA_InitDstAddr ;
+; ----------------------------------;
+ ADD TOS,0(PSP) ; -- SDIB_org SDIB_end SDIB_len
+ MOV 2(PSP),TOS ; -- SDIB_org SDIB_end SDIB_ptr
+; ==================================;
+SDA_InitSrcAddr ; -- SDIB_org SDIB_end SDIB_ptr <== Read_File return
+; ==================================;
+ MOV &BufferPtr,S ;
+ MOV &BufferLen,T ;
+ MOV @PSP,W ; W = SDIB_end
+ MOV.B #32,X ; X = BL
+ JMP SDA_ComputeCharLoop ;
; ----------------------------------;
SDA_YEMIT_RET ;
; ----------------------------------;
- FORTHtoASM ;
- SUB #2,IP ; 1 restore YEMIT return
-; ----------------------------------;
-SDA_ComputeChar ;
-; ----------------------------------;
- CMP &BufferLen,X ; 3 BufferPtr >= BufferLen ?
- JHS SDA_GetFileNextSector ; 2 yes
- MOV.B BUFFER(X),Y ; 3 Y = char
- ADD #1,X ; 1 increment input BufferPtr
- CMP.B #32,Y ; 2 ascii printable char ?
- JHS SDA_MoveChar ; 2 yes
- CMP.B #10,Y ; 2 control char = 'LF' ?
- JNZ SDA_ComputeChar ; 2 no
-; ----------------------------------;
-SDA_EndOfLine ;
-; ----------------------------------;
- MOV X,&BufferPtr ; yes save BufferPtr for next line
-; ----------------------------------;
-SDA_GoToInterpret ; -- StringOrg' TIB_LEN len'
-; ----------------------------------;
- ADD #2,PSP ; -- StringOrg' len'
- MOV @RSP+,IP ;
- MOV @IP+,PC ; ===> unique output
-; ----------------------------------;
-SDA_MoveChar ;
-; ----------------------------------;
- CMP @PSP,TOS ; 2 count = TIB_LEN ?
- JZ YEMIT ; 2 yes, don't move char to dst
- MOV.B Y,0(W) ; 3 move char to dst
- ADD #1,W ; 1 increment dst addr
- ADD #1,TOS ; 1 increment count of moved chars
- JMP YEMIT ; 9/6~ send echo to terminal if ECHO, do nothing if NOECHO
-; ----------------------------------; 32/29~ char loop, add 14~ for readsectorW ==> 46/43~ ==> 174/186 kbytes/s @ 8MHz
-SDA_GetFileNextSector ; StringOrg' TIB_LEN Count --
-; ----------------------------------;
- PUSH W ; save dst
- CALL #Read_File ; that resets BufferPtr
- MOV @RSP+,W ; restore dst
- JMP SDA_InitSrcAddr ; loopback to end the line
-; ----------------------------------;
-
-
+ mNEXTADR ;
+ SUB #2,IP ; 1 restore YEMIT return
+; ----------------------------------;
+SDA_ComputeCharLoop ; -- SDIB_org SDIB_end SDIB_ptr
+; ----------------------------------;
+ CMP T,S ; 1 SD_buf_ptr >= SD_buf_len ?
+ JC SDA_GetFileNextSect ; 2 if yes
+ MOV.B SD_BUF(S),Y ; 3 Y = char
+ ADD #1,S ; 1 increment SD_buf_ptr
+ CMP.B X,Y ; 1 ascii printable char ?
+ JC SDA_MoveChar ; 2 yes
+ CMP.B #10,Y ; 2 control char = 'LF' ?
+ JNZ SDA_ComputeCharLoop ; 2 no, loop back
+; ----------------------------------;
+;SDA_EndOfLine ;
+; ----------------------------------;
+ MOV S,&BufferPtr ; save SD_buf_ptr for next line loop
+; ==================================;
+SDA_EndOfFile ; -- SDIB_org SDIB_end SDIB_ptr <== CloseHandle return
+; ==================================;
+ MOV @RSP+,IP ; R--
+ ADD #2,PSP ; -- SDIB_ORG SDIB_PTR
+ SUB @PSP,TOS ; -- SDIB_ORG LEN
+ MOV.B X,Y ; Y = BL
+ JMP QYEMIT ; -- org len ==> output of SD_ACCEPT ==> INTERPRET
+; ----------------------------------;
+SDA_MoveChar ; -- SDIB_ORG SDIB_END SDIB_PTR
+; ----------------------------------;
+ CMP W,TOS ; 1 SDIB_ptr = SDIB_end ?
+ JZ QYEMIT ; 2 yes, don't move char to dst
+ MOV.B Y,0(TOS) ; 3 move char to dst
+ ADD #1,TOS ; 1 increment SDIB_ptr
+ JMP QYEMIT ; 9/6~ send echo to terminal if ECHO, do nothing if NOECHO
+; ----------------------------------; 27/24~ char loop, add 14~ for readsectorW one char ==> 41/38~ ==> 195/210 kbytes/s @ 8MHz
+SDA_GetFileNextSect ; -- SDIB_org SDIB_end SDIB_ptr
+; ----------------------------------;
+ PUSH #SDA_InitSrcAddr ; set the default return of Read_File, modified by CloseHandle when the end of file is reached
+ MOV #Read_File,PC ;
+; ----------------------------------;
\ No newline at end of file