Skip to content

Commit eeca09a

Browse files
authored
Rework io (#310)
* Rework IO words for greater flexibility Removed old `OPENW` and `CLOSEW` words from disk.asm that were undocumented, and only used by `V`. Added new words corresponding more closely to their underlying kernal calls. `open.fs` contains the minimal set of IO words needed by `V`, and is included in the default dictionary, `io.fs` adds the remaining words and provides error checking. * Add printer example to docs * Utility for DOS commands and drive status * Changes per PR feedback: - (open), (chkin) and (chkout) renamed to open?, chkin?, chkout? and return file number and detailed error code - clrch renamed to clrchn - ioerr prints meaningful error message - made dos command utilities less hackish - fixes to docs, comments and changelog * Added cautionary note about low-level IO words * update dump-labels to use new io words * Changes per PR review * Removed 'easy' IO words * 'ioerr' renamed to 'ioabort' and documented * documentation and comment fixes
1 parent b4c304f commit eeca09a

File tree

11 files changed

+196
-53
lines changed

11 files changed

+196
-53
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2929
- DEFINE assigns HERE to a word in the word list and begins compilation.
3030
- DEFCODE does the same as DEFINE, but begins a CODE: segment instead.
3131
- V commands: A, R, +, -, HOME, e, C, D, s, S, H, L, M, ^w, f, F
32+
- Words for file and device IO in OPEN: and IO:
33+
- Utility for drive status and DOS commands in DOS:
3234
### Fixed
3335
- SP-X! had bug in most significant bit
3436
- GFX: PEEK fetched bitmap pixels from ROM instead of RAM
3537
- V did not compile in DECIMAL mode.
3638
- Documented SEE concatenating subsequent :NONAME
37-
- Made QUIT do CLRCHN instead of CHKIN.
39+
- Made QUIT do CLRCHN instead of CHKIN
40+
### Removed
41+
- Removed undocumented OPENW and CLOSEW words.
3842

3943
## [2.0.0] - 2020-03-22
4044

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ SRC_DIR = forth_src
88
SRC_NAMES = base debug v asm gfx gfxdemo rnd sin ls turtle fractals \
99
sprite doloop sys labels mml mmldemo sid spritedemo test testcore \
1010
testcoreplus tester format require compat timer float viceutil turnkey \
11-
wordlist
11+
wordlist io open dos
1212
SRCS = $(addprefix $(SRC_DIR)/,$(addsuffix .fs,$(SRC_NAMES)))
1313

1414
EMPTY_FILE = _empty.txt

disk.asm

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
;THE SOFTWARE. }}}
2222

23-
; DEVICE OPENW CLOSEW LOADB SAVEB INCLUDED
23+
; DEVICE LOADB SAVEB INCLUDED
2424

2525
READST = $ffb7
2626
SETLFS = $ffba
@@ -43,19 +43,6 @@ SAVE = $ffd8
4343
inx
4444
rts
4545

46-
; CLOSEW ( file# -- )
47-
+BACKLINK "closew", 6
48-
CLOSEW
49-
lda LSB,x
50-
sta W
51-
stx W2
52-
jsr CLOSE
53-
ldx W
54-
jsr CHKOUT
55-
ldx W2
56-
inx
57-
rts
58-
5946
_errorchread
6047
LDA #$00 ; no filename
6148
tax
@@ -232,39 +219,6 @@ save_binary_srange_end_hi = *+1
232219
inx
233220
rts
234221

235-
; OPENW ( strptr strlen file# ) open file for writing
236-
+BACKLINK "openw", 5
237-
OPENW
238-
lda LSB,x
239-
sta W ; fileno
240-
stx W2
241-
242-
lda LSB+1, x
243-
ldy MSB+2, x
244-
pha
245-
lda LSB+2, x
246-
tax
247-
pla
248-
249-
jsr SETNAM
250-
lda W ; file number
251-
ldx $ba ; last used device#
252-
tay ; secondary address
253-
jsr SETLFS
254-
jsr OPEN
255-
bcc +
256-
jsr .close
257-
jmp ++
258-
+
259-
ldx W ; file number
260-
jsr CHKOUT
261-
++
262-
ldx W2
263-
inx
264-
inx
265-
inx
266-
rts
267-
268222
.close
269223
lda $b8 ; current file
270224
jsr CLOSE

docs/tutorial.tex

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ \section{Console I/O Example}
6363
foo
6464
\end{verbatim}
6565

66+
\section{Printer Example}
67+
68+
This piece of code prints a message to a printer on device \#4, and then prints a message to the screen:
69+
70+
\begin{verbatim}
71+
include io
72+
73+
: print-hello
74+
4 device ( use device 4 )
75+
0 0 47 7 open ioabort ( open address 7 as file 47, abort on failure )
76+
47 chkout ioabort ( redirect output to file 47, abort on failure )
77+
." Hello, printer!" cr
78+
clrchn ( stop input and output redirection )
79+
." Hello, screen!" cr
80+
47 close ( close file 47 ) ;
81+
82+
print-hello
83+
\end{verbatim}
84+
85+
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.
86+
6687
\section{Avoiding Stack Crashes}
6788

6889
durexForth should be one of the fastest and leanest Forths for the C64. To achieve this, there are

docs/words.tex

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,48 @@ \section{Disk I/O}
405405
\item[rdir ( addr -- )] Display disk directory previously loaded to addr.
406406
\end{description}
407407

408+
\subsection{DOS Commands}
409+
410+
Words for sending DOS commands to drives and reading drive status are available by including \texttt{dos}.
411+
412+
\begin{description}
413+
\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}:
414+
\begin{verbatim}
415+
: backup s" copy0:backup=durexforth" send-cmd ;
416+
backup
417+
\end{verbatim}
418+
419+
\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}''.
420+
\end{description}
421+
422+
\subsection{Low-Level Device I/O}
423+
424+
For more advanced uses, words corresponding to the standard Commodore Kernal IO routines are available by including \texttt{io}.
425+
426+
\begin{description}
427+
\item[open ( filenameptr filenamelength file\# secondary-addr -- file\# ioresult )] Open a logical file.
428+
\item[chkin ( file\# -- file\# ioresult )] Use a logical file as input device.
429+
\item[chkout ( file\# -- file\# ioresult )] Use a logical file as output device.
430+
\item[clrchn ( -- )] Resets input and output to the keyboard and screen.
431+
\item[close ( file\# -- )] Close a logical file.
432+
\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.
433+
\item[chrin ( -- char)] Reads a character from the current input device.
434+
\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.
435+
\end{description}
436+
437+
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.
438+
439+
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.
440+
441+
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:
442+
443+
\begin{itemize}
444+
\item Avoid using file numbers 15 and below (remember, any number up to 127 can be used as a file number).
445+
\item Only use input/output redirection (\texttt{chkin} and \texttt{chkout}) within word definitions, and ensure that \texttt{clrchn} is called before exit.
446+
\item Close files as soon as they are no longer needed.
447+
\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}.
448+
\end{itemize}
449+
408450
\section{Compatibility}
409451

410452
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.

forth_src/base.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ marker ---modules---
217217
.( debug..) include debug
218218
.( ls..) include ls
219219
.( require..) include require
220+
.( open..) include open
220221
.( v..) include v
221222

222223
decimal

forth_src/dos.fs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require io
2+
3+
\ send command string to drive and
4+
\ print response
5+
: send-cmd ( addr len -- )
6+
$f $f open ioabort
7+
clrchn $f chkin ioabort
8+
begin chrin emit readst until
9+
clrchn $f close cr ;
10+
11+
\ send remainder of line as dos command
12+
\ and print response
13+
: dos source >in @ /string
14+
dup >in +! \ consume buffer
15+
send-cmd ;

forth_src/io.fs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
require open
2+
3+
\ Use logical file as input device
4+
\ ioresult is 0 on success, kernal
5+
\ error # on failure.
6+
code chkin ( file# -- file# ioresult )
7+
w stx,
8+
lsb lda,x tax, \ x = file#
9+
$ffc6 jsr, \ CHKIN
10+
+branch bcs, \ carry set = error
11+
0 lda,# \ A is only valid on error
12+
:+
13+
w ldx, dex,
14+
lsb sta,x
15+
0 lda,# msb sta,x
16+
;code
17+
18+
\ Use logical file as output device
19+
\ ioresult is 0 on success, kernal
20+
\ error # on failure.
21+
code chkout ( file# -- file# ioresult )
22+
w stx,
23+
lsb lda,x tax, \ x = file#
24+
$ffc9 jsr, \ CHKOUT
25+
+branch bcs, \ carry set = error
26+
0 lda,# \ A is only valid on error
27+
:+
28+
w ldx, dex,
29+
lsb sta,x
30+
0 lda,# msb sta,x
31+
;code
32+
33+
\ Reset input and output to console
34+
code clrchn ( -- )
35+
txa, pha,
36+
$ffcc jsr, \ CLRCH
37+
pla, tax,
38+
;code
39+
40+
\ Read status of last IO operation
41+
code readst ( -- status )
42+
dex, 0 lda,# msb sta,x
43+
$ffb7 jsr, \ READST
44+
lsb sta,x
45+
;code
46+
47+
\ Get a byte from input device
48+
code chrin ( -- chr )
49+
dex, w stx, 0 lda,# msb sta,x
50+
$ffcf jsr, \ CHRIN
51+
w ldx, lsb sta,x
52+
;code
53+
54+
\ handle errors returned by open,
55+
\ close, and chkin. If ioresult is
56+
\ nonzero, close file and abort with
57+
\ an appropriate error message.
58+
: ioabort ( file# ioresult -- )
59+
?dup if rvs case
60+
2 of ." file# in use" endof
61+
3 of ." file not open" endof
62+
5 of ." device not present" endof
63+
6 of ." not input file" endof
64+
7 of ." not output file" endof
65+
." io err"
66+
endcase clrchn close cr abort
67+
else drop then ;

forth_src/open.fs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
\ Open a logical file
2+
\ ioresult is 0 on success, kernal
3+
\ error # on failure.
4+
( nameaddr namelen file# sa --
5+
file# ioresult )
6+
code open
7+
w stx,
8+
lsb 1+ lda,x \ a = file #
9+
lsb ldy,x \ y = sec. address
10+
$ba ldx, \ x = device
11+
$ffba jsr, \ SETLFS
12+
13+
w ldx,
14+
lsb 2+ lda,x pha, \ a = namelen
15+
msb 3 + ldy,x
16+
lsb 3 + lda,x tax, pla, \ xy = nameptr
17+
$ffbd jsr, \ SETNAM
18+
19+
$ffc0 jsr, \ OPEN
20+
+branch bcs, \ carry set = error
21+
0 lda,# \ A is only valid on error
22+
:+
23+
w ldx,
24+
inx, inx,
25+
lsb sta,x
26+
lsb 1- lda,x lsb 1+ sta,x
27+
0 lda,# msb sta,x msb 1+ sta,x
28+
;code
29+
30+
\ Close a logical file
31+
code close ( file# -- )
32+
txa, pha,
33+
lsb lda,x \ x = file#
34+
$ffc3 jsr, \ CLOSE
35+
pla, tax, inx,
36+
;code

forth_src/v.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ here
364364
filename 1+ over filename c@ move
365365
filename c@ + lf swap c!
366366
here filename c@ 4 +
367-
$f openw $f closew
367+
$f $f open drop close
368368

369369
bufstart eof @
370370
filename count saveb

forth_src/viceutil.fs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
require io
2+
13
$12 emit .( dump-labels) $92 emit
24
.( writes VICE emulator
3-
labels to the file 'words'
5+
labels to the PRG file 'words'
46

57
When written, extract the file from
68
.d64 using c1541 command
@@ -54,6 +56,7 @@ else emit then loop
5456
$a emit 1 ;
5557

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

0 commit comments

Comments
 (0)