Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework io #310

Merged
merged 9 commits into from
Dec 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- DEFINE assigns HERE to a word in the word list and begins compilation.
- DEFCODE does the same as DEFINE, but begins a CODE: segment instead.
- V commands: A, R, +, -, HOME, e, C, D, s, S, H, L, M, ^w, f, F
- Words for file and device IO in OPEN: and IO:
- Utility for drive status and DOS commands in DOS:
### Fixed
- SP-X! had bug in most significant bit
- GFX: PEEK fetched bitmap pixels from ROM instead of RAM
- V did not compile in DECIMAL mode.
- Documented SEE concatenating subsequent :NONAME
- Made QUIT do CLRCHN instead of CHKIN.
- Made QUIT do CLRCHN instead of CHKIN
### Removed
- Removed undocumented OPENW and CLOSEW words.

## [2.0.0] - 2020-03-22

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ SRC_DIR = forth_src
SRC_NAMES = base debug v asm gfx gfxdemo rnd sin ls turtle fractals \
sprite doloop sys labels mml mmldemo sid spritedemo test testcore \
testcoreplus tester format require compat timer float viceutil turnkey \
wordlist
wordlist io open dos
SRCS = $(addprefix $(SRC_DIR)/,$(addsuffix .fs,$(SRC_NAMES)))

EMPTY_FILE = _empty.txt
Expand Down
48 changes: 1 addition & 47 deletions disk.asm
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
;THE SOFTWARE. }}}

; DEVICE OPENW CLOSEW LOADB SAVEB INCLUDED
; DEVICE LOADB SAVEB INCLUDED

READST = $ffb7
SETLFS = $ffba
Expand All @@ -43,19 +43,6 @@ SAVE = $ffd8
inx
rts

; CLOSEW ( file# -- )
rhalkyard marked this conversation as resolved.
Show resolved Hide resolved
+BACKLINK "closew", 6
CLOSEW
lda LSB,x
sta W
stx W2
jsr CLOSE
ldx W
jsr CHKOUT
ldx W2
inx
rts

_errorchread
LDA #$00 ; no filename
tax
Expand Down Expand Up @@ -232,39 +219,6 @@ save_binary_srange_end_hi = *+1
inx
rts

; OPENW ( strptr strlen file# ) open file for writing
+BACKLINK "openw", 5
OPENW
lda LSB,x
sta W ; fileno
stx W2

lda LSB+1, x
ldy MSB+2, x
pha
lda LSB+2, x
tax
pla

jsr SETNAM
lda W ; file number
ldx $ba ; last used device#
tay ; secondary address
jsr SETLFS
jsr OPEN
bcc +
jsr .close
jmp ++
+
ldx W ; file number
jsr CHKOUT
++
ldx W2
inx
inx
inx
rts

.close
lda $b8 ; current file
jsr CLOSE
Expand Down
21 changes: 21 additions & 0 deletions docs/tutorial.tex
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,27 @@ \section{Console I/O Example}
foo
\end{verbatim}

\section{Printer Example}

This piece of code prints a message to a printer on device \#4, and then prints a message to the screen:

\begin{verbatim}
include io

: print-hello
4 device ( use device 4 )
0 0 47 7 open ioabort ( open address 7 as file 47, abort on failure )
47 chkout ioabort ( redirect output to file 47, abort on failure )
." Hello, printer!" cr
clrchn ( stop input and output redirection )
." Hello, screen!" cr
47 close ( close file 47 ) ;
jkotlinski marked this conversation as resolved.
Show resolved Hide resolved

print-hello
\end{verbatim}

The device number and address may differ between printer models. Commodore MPS series printers use address 0 to print in their uppercase/graphics font, and address 7 to print in their lowercase/uppercase font.

jkotlinski marked this conversation as resolved.
Show resolved Hide resolved
\section{Avoiding Stack Crashes}

durexForth should be one of the fastest and leanest Forths for the C64. To achieve this, there are
Expand Down
42 changes: 42 additions & 0 deletions docs/words.tex
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,48 @@ \section{Disk I/O}
\item[rdir ( addr -- )] Display disk directory previously loaded to addr.
\end{description}

\subsection{DOS Commands}

Words for sending DOS commands to drives and reading drive status are available by including \texttt{dos}.

\begin{description}
\item[send-cmd ( addr length -- )] Writes the given string to secondary address 15 on the current device, and prints the drive's response. The following example defines a word, \texttt{backup} that creates a copy of \texttt{durexforth} called \texttt{backup}:
\begin{verbatim}
: backup s" copy0:backup=durexforth" send-cmd ;
backup
\end{verbatim}

\item[dos command ( -- )] Sends \texttt{command} to the current device's command channel, and prints the response. Note that the remainder of the line is treated as part of the command. This makes it possible to refer to file names that contain spaces, but means that \texttt{dos} and its command should be on their own line, or the last words on a line. Example: \texttt{dos scratch0:old file} will delete a file named ``\texttt{old file}''.
\end{description}

\subsection{Low-Level Device I/O}

For more advanced uses, words corresponding to the standard Commodore Kernal IO routines are available by including \texttt{io}.

\begin{description}
\item[open ( filenameptr filenamelength file\# secondary-addr -- file\# ioresult )] Open a logical file.
\item[chkin ( file\# -- file\# ioresult )] Use a logical file as input device.
\item[chkout ( file\# -- file\# ioresult )] Use a logical file as output device.
\item[clrchn ( -- )] Resets input and output to the keyboard and screen.
\item[close ( file\# -- )] Close a logical file.
\item[readst ( -- status )] Returns the status of the last IO operation. For serial-bus devices, \texttt{\$01} = write timeout, \texttt{\$02} = read timeout, \texttt{\$40} = end of file (EOI), \texttt{\$80} = device not present.
\item[chrin ( -- char)] Reads a character from the current input device.
\item[ioabort ( file\# ioresult -- )] Handle error conditions for \texttt{open}, \texttt{chkin} or \texttt{chkout}. On error, close the file and abort with an explanatory error message.
\end{description}

As per the underlying Kernal routines, \texttt{chrin} does not check for end-of-file or any other error condition. \texttt{readst} should be called to ensure that the returned character is valid.

The \texttt{ioresult} value returned by \texttt{open}, \texttt{chkin} and \texttt{chkout} is 0 on success, or a Kernal error number if an error occurred.

Note that use of low-level device I/O may interfere with disk accesses done by durexForth and the \texttt{V} editor. The following guidelines should be followed to avoid interference:

\begin{itemize}
\item Avoid using file numbers 15 and below (remember, any number up to 127 can be used as a file number).
\item Only use input/output redirection (\texttt{chkin} and \texttt{chkout}) within word definitions, and ensure that \texttt{clrchn} is called before exit.
\item Close files as soon as they are no longer needed.
\item If multiple files are open, always call \texttt{clrchn} to end any serial bus transactions before calling \texttt{open} or switching between files with \texttt{chkin} or \texttt{chkout}.
\end{itemize}

\section{Compatibility}

The \texttt{compat} module contains various words that are not deemed necessary for enjoyable DurexForth operation, but still must be provided to comply with the Forth 2012 core standard.
Expand Down
1 change: 1 addition & 0 deletions forth_src/base.fs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ marker ---modules---
.( debug..) include debug
.( ls..) include ls
.( require..) include require
.( open..) include open
.( v..) include v

decimal
Expand Down
15 changes: 15 additions & 0 deletions forth_src/dos.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require io

rhalkyard marked this conversation as resolved.
Show resolved Hide resolved
\ send command string to drive and
\ print response
: send-cmd ( addr len -- )
$f $f open ioabort
clrchn $f chkin ioabort
begin chrin emit readst until
clrchn $f close cr ;

\ send remainder of line as dos command
\ and print response
: dos source >in @ /string
dup >in +! \ consume buffer
send-cmd ;
67 changes: 67 additions & 0 deletions forth_src/io.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require open

\ Use logical file as input device
\ ioresult is 0 on success, kernal
\ error # on failure.
code chkin ( file# -- file# ioresult )
w stx,
lsb lda,x tax, \ x = file#
$ffc6 jsr, \ CHKIN
+branch bcs, \ carry set = error
0 lda,# \ A is only valid on error
:+
w ldx, dex,
lsb sta,x
0 lda,# msb sta,x
;code

\ Use logical file as output device
\ ioresult is 0 on success, kernal
\ error # on failure.
code chkout ( file# -- file# ioresult )
w stx,
lsb lda,x tax, \ x = file#
$ffc9 jsr, \ CHKOUT
+branch bcs, \ carry set = error
0 lda,# \ A is only valid on error
:+
w ldx, dex,
lsb sta,x
0 lda,# msb sta,x
;code

\ Reset input and output to console
code clrchn ( -- )
txa, pha,
$ffcc jsr, \ CLRCH
pla, tax,
;code

\ Read status of last IO operation
code readst ( -- status )
dex, 0 lda,# msb sta,x
$ffb7 jsr, \ READST
lsb sta,x
;code

\ Get a byte from input device
code chrin ( -- chr )
dex, w stx, 0 lda,# msb sta,x
$ffcf jsr, \ CHRIN
w ldx, lsb sta,x
;code

\ handle errors returned by open,
\ close, and chkin. If ioresult is
\ nonzero, close file and abort with
\ an appropriate error message.
: ioabort ( file# ioresult -- )
?dup if rvs case
2 of ." file# in use" endof
3 of ." file not open" endof
5 of ." device not present" endof
6 of ." not input file" endof
7 of ." not output file" endof
." io err"
endcase clrchn close cr abort
else drop then ;
36 changes: 36 additions & 0 deletions forth_src/open.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
\ Open a logical file
\ ioresult is 0 on success, kernal
\ error # on failure.
( nameaddr namelen file# sa --
file# ioresult )
code open
w stx,
lsb 1+ lda,x \ a = file #
lsb ldy,x \ y = sec. address
$ba ldx, \ x = device
$ffba jsr, \ SETLFS

w ldx,
lsb 2+ lda,x pha, \ a = namelen
msb 3 + ldy,x
lsb 3 + lda,x tax, pla, \ xy = nameptr
$ffbd jsr, \ SETNAM

$ffc0 jsr, \ OPEN
+branch bcs, \ carry set = error
0 lda,# \ A is only valid on error
:+
w ldx,
inx, inx,
lsb sta,x
lsb 1- lda,x lsb 1+ sta,x
0 lda,# msb sta,x msb 1+ sta,x
;code

\ Close a logical file
code close ( file# -- )
txa, pha,
lsb lda,x \ x = file#
$ffc3 jsr, \ CLOSE
pla, tax, inx,
;code
2 changes: 1 addition & 1 deletion forth_src/v.fs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ here
filename 1+ over filename c@ move
filename c@ + lf swap c!
here filename c@ 4 +
$f openw $f closew
$f $f open drop close

bufstart eof @
filename count saveb
Expand Down
9 changes: 6 additions & 3 deletions forth_src/viceutil.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require io

$12 emit .( dump-labels) $92 emit
.( writes VICE emulator
labels to the file 'words'
labels to the PRG file 'words'

When written, extract the file from
.d64 using c1541 command
Expand Down Expand Up @@ -54,6 +56,7 @@ else emit then loop
$a emit 1 ;

: dump-labels base @ >r hex
s" words" 1 openw
s" words,w" 1 1 open ioabort
1 chkout ioabort
['] (label) dowords
1 closew r> base ! ;
clrchn 1 close r> base ! ;