Source of Afera (part 3: module names D-G)
Description of the page content
Fourth part of the Afera library sources for Abersoft Forth.
Source code
.( DECODE )
\ decode.fsb
\ `DECODE` for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ Copyright (C) 1984 EHR
\ Copyright (C) 1982 Robert Dudley Ackerman
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Adapted and deeply modified from:
\ Z80 CP/M fig-Forth 1.1g (adaptative version by EHR).
\ Original code by Robert Dudley Ackerman, published in
\ Forth Dimensions IV,#2 p28 (1982-07);
\ modified by Dennis L. Wilson.
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Requirements
NEEDS RECURSE recurse
\ -----------------------------------------------------------
\ History
\ 2015-04-17: Code copied and adapted from Z80 CP/M fig-Forth
\ 1.1g. It works fine.
\
\ 2015-05-03: Improvement: The current address is shown, in
\ hex. Clearer instructions.
\
\ 2015-05-04: No hex forced, the current base is used.
\
\ 2015-05-07:
\
\ The code that handles the special decoding cases and the
\ key selection have been rewritten with `CASE` structures,
\ easier to read, maintain and extend.
\
\ The check that prevented from decoding `ERROR` has been
\ removed.
\
\ Improvement: The destination address of branches is shown
\ after the relative value.
\
\ The main code has been divided in smaller pieces, easier to
\ understand and maintain.
\
\ 2015-05-13: Fix: the address shown at the left of the colon
\ was the last value of `DECODE-ADDRESS`. Now it's the nfa of
\ the definition. The check in `INDENT` is removed.
\
\ 2015-05-17: `NEEDS` used. Improved with run-time and
\ shorter instructions.
\ -----------------------------------------------------------
-->
( DECODE -- variables, indentation and pause control )
FORTH DEFINITIONS DECIMAL
0 VARIABLE DECODE-LEVEL \ depth of nesting
0 VARIABLE DECODE-ADDRESS \ in the word being decoded
: INDENT ( -- )
CR DECODE-ADDRESS @ U. DECODE-LEVEL @ 2 * SPACES ;
: INDENT+ ( -- ) 1 DECODE-LEVEL +! INDENT ;
-->
( DECODE -- Special cases )
: DECODE-COMPILE ( a1 -- a2 ) 2+ DUP @ 2+ NFA ID. ;
: DECODE-LITERAL ( a1 -- a2 ) 2+ DUP @ . ;
: DECODE-BRANCH ( a1 -- a2 )
DECODE-LITERAL ." \ to " DUP DUP @ + U. ;
: DECODE-DOT-QUOTE ( a1 -- a2 )
2+ DUP COUNT TYPE DUP C@ + 1 - ;
-->
( DECODE -- Special cases dispatcher )
: DECODE-SPECIAL-CASES ( a1 -- a1 | a2 )
DUP @ CASE
[ ' COMPILE CFA ] LITERAL OF DECODE-COMPILE ENDOF
[ ' LIT CFA ] LITERAL OF DECODE-LITERAL ENDOF
[ ' BRANCH CFA ] LITERAL OF DECODE-BRANCH ENDOF
[ ' 0BRANCH CFA ] LITERAL OF DECODE-BRANCH ENDOF
[ ' (LOOP) CFA ] LITERAL OF DECODE-BRANCH ENDOF
[ ' (+LOOP) CFA ] LITERAL OF DECODE-BRANCH ENDOF
[ ' (.") CFA ] LITERAL OF DECODE-DOT-QUOTE ENDOF
ENDCASE ;
-->
( DECODE -- checks of the main code )
: DECODE-END? ( cfa -- f )
\ Is the given cfa the end of a definition?
DUP ' ;S CFA = SWAP ' (;CODE) CFA = OR ;
: COLON-PFA? ( pfa -- f )
\ Is the given pfa a colon definition?
CFA @ ' : CFA @ = ;
-->
( DECODE -- main code )
: (DECODE) ( pfa --- )
\ Decode the definition at the given pfa.
DUP COLON-PFA? IF
DUP NFA DECODE-ADDRESS ! INDENT ." : " DUP NFA ID.
BEGIN ( pfa+n ) DUP DECODE-ADDRESS !
DUP @ DUP ( pfa+n cfa cfa ) DECODE-END? 0=
\ ( pfa+n cfa f )
WHILE \ high level & NOT end of colon definition
\ ( pfa+n cfa )
( pfa+n cfa ) 2+ ( pfa+n pfa' ) DUP INDENT+ NFA ID.
KEY CASE [CHAR] Q OF SP! QUIT ENDOF \ Q
BL OF DROP ENDOF \ Space
SWAP RECURSE \ Default
ENDCASE DECODE-SPECIAL-CASES
2+ -1 DECODE-LEVEL +!
REPEAT INDENT 2+ NFA ID. \ show the last word
ELSE ." Not a colon definition." THEN DROP ; -->
( DECODE -- interface )
: DECODE-USAGE ( -- )
\ <------------------------------>
CR ." Keys: Space=more, Q=quit, other=deeper." CR ;
: DECODE ( "name" -- )
DECODE-USAGE
-FIND IF DROP 0 DECODE-LEVEL ! (DECODE)
ELSE ." Not Found" THEN ;
\ vim: filetype=abersoftforthafera
.( DEFER )
\ defer.fsb
\ Deferred words for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ History
\ 2015-03-28: Start.
\
\ 2015-04-02: Fix.
\
\ 2015-07-04: Typo. Simpler `ACTION-OF`.
\
\ 2015-07-07: Revised, tested, fixed, simplified (removed
\ `[IS]` and `<IS>`), documented.
\
\ 2015-10-26: Improved and fixed some comments.
\
\ 2016-01-25: Layout.
\ -----------------------------------------------------------
-->
( Create and fetch deferred words )
: (DEFER) ( -- )
\ Default behaviour of an uninitialized deferred word:
\ "Definition not finished".
20 ERROR ;
: DEFER ( "name" -- )
\ Create a deferred word.
\ Note: using `:` and `;` is more compact and faster
\ than using `<BUILDS` and `DOES>` in this case.
[COMPILE] : COMPILE (DEFER) [COMPILE] ; ;
: DEFER@ ( pfa -- cfa )
\ pfa = parameter field address of a deferred word
\ cfa = code field address the deferred word
\ is set to execute
@ ;
: DEFERS ( "name" -- )
\ Compile the present contents of the deferred word "name"
\ into the current definition. I.e. this produces static
\ binding as if "name" was not deferred.
[COMPILE] ' DEFER@ , ; IMMEDIATE
: ACTION-OF ( Interpretation: "name" -- cfa )
( Compilation: "name" -- )
( Runtime: -- cfa )
\ "name" = name of a deferred word
\ cfa = code field address the deferred word
\ is set to execute
[COMPILE] ' STATE @ IF COMPILE DEFER@
ELSE DEFER@ THEN ; IMMEDIATE
-->
( Set deferred words -- version with CFA )
\ This version uses a cfa (code field address) to set the
\ deferred words. This version seems a better compromise than
\ the pfa version (see next screen), therefore it's loaded by
\ default.
\
\ Note: Since fig-Forth's `'` returns a pfa (parameter field
\ address) `CFA` must be used to convert it to the
\ correspondent cfa required by `IS` or `DEFER!`. `:NONAME`
\ returns a cfa (see the module <noname.fsb>), so it can be
\ used directly with `IS` and `DEFER!`.
\
\ Usage examples:
\ DEFER MYWORD
\
\ ' WHATEVER-0 CFA IS MYWORD
\ MYWORD \ execute WHATEVER-0
\
\ ' WHATEVER-1 CFA ' MYWORD DEFER!
\ MYWORD \ execute WHATEVER-1
\
\ :NONAME WHATEVER-2 ; IS MYWORD
\ MYWORD \ execute WHATEVER-2
\
\ :NONAME WHATEVER-3 ; ' MYWORD DEFER!
\ MYWORD \ execute WHATEVER-3
: DEFER! ( cfa pfa -- ) ! ;
: IS ( Interpretation: cfa "name" -- )
( Compilation: "name" -- )
[COMPILE] ' STATE @ IF COMPILE DEFER! ELSE DEFER! THEN
; IMMEDIATE
( Set deferred words -- version with PFA )
\ This version uses a pfa (parameter field address) to set
\ the deferred words.
\
\ Note: Since `:NONAME` is written after ANS Forth and so it
\ returns a cfa (see the module <noname.fsb>), `2+` must be
\ used to convert it to the pfa required by `IS`.
\
\ Usage examples:
\ DEFER MYWORD
\
\ ' WHATEVER-0 IS MYWORD
\ MYWORD \ execute WHATEVER-0
\
\ ' WHATEVER-1 ' MYWORD DEFER!
\ MYWORD \ execute WHATEVER-1
\
\ :NONAME WHATEVER-2 ; 2+ IS MYWORD
\ MYWORD \ execute WHATEVER-2
\
\ :NONAME WHATEVER-3 ; 2+ ' MYWORD DEFER!
\ MYWORD \ execute WHATEVER-3
: DEFER! ( pfa1 pfa2 -- ) SWAP CFA SWAP ! ;
: IS ( Interpretation: cfa "name" -- )
( Compilation: "name" -- )
[COMPILE] ' STATE @ IF COMPILE DEFER! ELSE DEFER! THEN
; IMMEDIATE
\ vim: filetype=abersoftforthafera
\ dminus.fsb
\ `D-` for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ Copyright (C) 1988 Lennart Benschop
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Description
\ In fig-Forth `DMINUS D+` can be used instead of `D-`,
\ but `D-` is faster.
\ -----------------------------------------------------------
\ History
\ 2015-04-18: Code adapted from Lennart Benschop's Spectrum
\ Forth-83.
\
\ 2015-06-06: New version compiled directly with opcodes,
\ without the assembler.
\
\ 2015-10-26: Fixed the layout.
\ -----------------------------------------------------------
-->
( D- ) \ version compiled with opcodes
CREATE D- ( d1 d2 -- d3 )
HEX D9 C, \ exx
C1 C, \ pop bc
D1 C, \ pop de
E1 C, \ pop hl
E3 C, \ ex (sp),hl
A0 07 + C, \ and a
ED C, 52 C, \ sbc hl,de
E3 C, \ ex (sp),hl
A0 07 + C, \ and a
ED C, 42 C, \ sbc hl,bc
E5 C, \ push hl
D9 C, \ exx
C3 C, NEXT , \ jp NEXT
SMUDGE DECIMAL
( D- ) \ assembler version
NEEDS CODE assembler
CODE D- ( d1 d2 -- d3 )
EXX
BC POP
DE POP
HL POP
EXSP
DE SUBP
EXSP
BC SBCP
HL PUSH
EXX
NEXT JP
END-CODE
\ vim: filetype=abersoftforthafera
.( .RS )
\ dot-rs.fsb
\ `.RS` for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ History
\ 2015-05-15: Written after the code of `.S`.
[DEFINED] RDEPTH
?\ : RDEPTH ( -- u ) RP@ R0 @ - -2 / ;
: .RS ( -- )
RDEPTH 2- DUP
S->D <# [CHAR] > HOLD #S [CHAR] < HOLD #> TYPE SPACE
IF RP@ 2- R0 @ 2- DO I @ . -2 +LOOP THEN ;
\ vim: filetype=abersoftforthafera
.( .S )
\ dot-s.fsb
\ `.S` for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ Copyright (C) 1990-2013 Matteo Vitturi
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ History
\ 2015-03-30: First version.
\ 2015-04-14: Second version, from Matteo Vitturi's vForth.
\ 2015-04-19: Combined version.
\ 2015-10-26: Updated header.
\ -----------------------------------------------------------
: .S ( -- )
DEPTH
DUP S->D <# [CHAR] > HOLD #S [CHAR] < HOLD #> TYPE SPACE
\ First version:
\ DEPTH -DUP IF 0 DO DEPTH I - 1 - PICK . LOOP THEN
\ Second version, from Matteo Vitturi's vForth:
\ SP@ 2 - S0 @ 2 - DO I @ . -2 +LOOP
\ Combined version:
IF SP@ 2- S0 @ 2- DO I @ . -2 +LOOP THEN
;
\ vim: filetype=abersoftforthafera
.( .VOCS )
\ dot-vocs.fsb
\ `.VOCS` for ZX Spectrum Abersoft Forth
\ Copyright (C) 1990-2013 Matteo Vitturi
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ History
\ 2015-04-17: Copied from Mateo Vitturi's v.Forth 1.3
\ (1990-2013).
\ -----------------------------------------------------------
: .VOCS ( -- )
CR ." Current " CURRENT @ 4 - NFA ID.
CR ." Context " CONTEXT @ 4 - NFA ID. ;
\ vim: filetype=abersoftforthafera
.( DUMP )
\ dump.fsb
\ `DUMP` for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ Copyright (C) 1988 Lennart Benschop
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Requirements
NEEDS CSWAP cswap
\ -----------------------------------------------------------
\ History
\ 2015-03-26: Start. Copied from Lennart Benschop's Spectrum
\ Forth-83.
\
\ 2015-03-28: Simple version as a temporary alternative,
\ until `?DO` is defined.
\
\ 2015-04-17: The code from ZX Spectrum Forth-83 has been
\ adapted, with `IF ... DO` instead of `?DO`.
\
\ 2015-04-20: Fix in `H.`.
\
\ 2015-05-17: `NEEDS` used.
\ -----------------------------------------------------------
-->
( BS H. STYPE )
: BS ( -- ) 8 EMIT ;
: H. ( n -- )
\ Print n in hexadecimal with four digits.
BASE @ HEX SWAP S->D <# # # # # #> TYPE SPACE BASE ! ;
HEX
: STYPE ( ca len -- )
0 2DUP - IF
DO
DUP C@ 7F AND DUP BL < IF DROP [CHAR] . THEN EMIT 1+
LOOP
ELSE 2DROP THEN DROP ;
DECIMAL -->
( DUMP )
: DUMP ( a len -- )
7 + -8 AND 8 / 0
2DUP - IF
DO
CR DUP H.
8 0 DO
I OVER + @ CSWAP H.
2 +LOOP
DUP BS 8 STYPE
?TERMINAL IF LEAVE THEN
8 + LOOP
ELSE 2DROP THEN DROP ;
\ vim: filetype=abersoftforthafera
\ flags.fsb
\ Boolean flags for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ History
\ 2015-04-16: Extracted from the main file of the library.
\ `ON` and `OFF` are rewritten in Z80.
\
\ 2015-04-23: Faster and smaller version of `OFF`.
\ -----------------------------------------------------------
-->
.( FALSE TRUE )
0 CONSTANT FALSE
FALSE 0= CONSTANT TRUE
-->
.( ON OFF )
CREATE ON ( a -- ) HEX
\ TRUE SWAP !
E1 C, \ pop hl
36 C, 01 C, \ ld (hl),1 ; 10T
23 C, \ inc hl ; 06T
36 C, 00 C, \ ld (hl),0 ; 10T
C3 C, NEXT , \ jp NEXT
SMUDGE
CREATE OFF ( a -- )
\ FALSE SWAP !
E1 C, \ pop hl
A8 07 + C, \ xor a ; 04T
70 07 + C, \ ld (hl),a ; 07T
23 C, \ inc hl ; 06T
70 07 + C, \ ld (hl),a ; 07T
C3 C, NEXT , \ jp NEXT
SMUDGE DECIMAL
\ vim: filetype=abersoftforthafera
.( G+DOS -- part 1 )
\ gplusdos_1.fsb
\ G+DOS support for ZX Spectrum Abersoft Forth (part 1)
\ Copyright (C) 1988,1994,2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Requirements
NEEDS CODE assembler
\ -----------------------------------------------------------
\ History
\ 2015-03-13: Start, based on code already written in 1988
\ and 1994.
\
\ 2015-04-01: Checks.
\
\ 2015-04-02: First succesful compilation, after some fixes
\ in the assembler. Some words renamed. New: alternative
\ words that don't use `?ERROR` but return the error
\ parameters.
\
\ 2015-04-07: Renamed to <gdos.fsb> (formerly
\ <gplusdos.fsb>).
\
\ 2015-04-14: New: the list of hooks has been completed;
\ `GDOS?` and `G+DOS?+'.
\
\ 2015-04-16: Change: `GDOS?` and `G+DOS?+' are removed. It
\ doesn't worth the effort to make the code compatible with
\ both GDOS and G+DOS, because all low level operations
\ should be duplicated. Even the word `GDOS?` should use a
\ different port to page the interface out, DISCiPLE or +D,
\ depending on its own result! Only G+DOS will be supported.
\ File renamed to <g+dos_1.fsb>.
\
\ 2015-05-08: Renamed to <gplusdos_1.fsb>, because of an
\ issue with Makefile.
\
\ 2015-05-12: Improvement: `DEVICE` is not a variable to
\ update UFIA with anymore, but the address of the
\ correspondent byte in UFIA, faster and shorter.
\ -----------------------------------------------------------
FORTH DEFINITIONS DECIMAL
10 CONSTANT /FILENAME \ max filename length
1 VARIABLE DRIVE
\ G+DOS addresses (in it own paged memory).
HEX 3E01 CONSTANT UFIA1 DECIMAL
\ 3E1A CONSTANT UFIA2
2 6 THRU
( UFIA: User File Information Area)
24 CONSTANT /UFIA /UFIA BUFFER: UFIA UFIA /UFIA ERASE
\ Note: The original field names are used, except `DEVICE`,
\ whose original name is "LSTR1".
UFIA CONSTANT DSTR1 \ drive: 1 or 2
UFIA 1+ CONSTANT FSTR1 \ program number
UFIA 2+ CONSTANT SSTR1 \ stream number
UFIA 3 + CONSTANT DEVICE \ device: "D" or "d"
UFIA 4 + CONSTANT NSTR1 \ directory description
UFIA 5 + CONSTANT NSTR2 \ file name
UFIA 15 + CONSTANT HD00 \ file type
UFIA 16 + CONSTANT HD0B \ file length
UFIA 18 + CONSTANT HD0D \ file start address
\ XXX OLD -- not needed
\ UFIA 20 + CONSTANT HD0F \ BASIC length without variables
\ UFIA 22 + CONSTANT HD11 \ BASIC autorun line
CHAR d DEVICE C! \ "d" or "D"
2 SSTR1 C! \ stream 2
\ These variables hold a copy of the HD0B and HD0D UFIA
\ fields. They are used by `(<DISK)`.
0 VARIABLE FILE-LENGTH
0 VARIABLE FILE-ADDRESS
( File types, directory descriptions and hook codes)
\ XXX TODO Move all this constants to another file, as
\ reference. They ocuppy a lot and most of them are not
\ necessary.
\ File types
0 CONSTANT BASIC-FILETYPE 1 CONSTANT DATA-ARRAY-FILETYPE
2 CONSTANT STRING-ARRAY-FILETYPE 3 CONSTANT CODE-FILETYPE
\ Directory descriptions
01 CONSTANT BASIC-FILE 02 CONSTANT DATA-ARRAY
03 CONSTANT STRING-ARRAY 04 CONSTANT CODE-FILE
05 CONSTANT SNAPSHOT-48K 06 CONSTANT MICRODRIVE-FILE
07 CONSTANT SCREENS$-FILE 08 CONSTANT SPECIAL-FILE
09 CONSTANT SNAPSHOT-128K 10 CONSTANT OPENTYPE-FILE
11 CONSTANT EXECUTE-FILE HEX
\ Hook codes
33 CONSTANT HXFER 34 CONSTANT OFSM 35 CONSTANT HOFLE
36 CONSTANT SBYT 37 CONSTANT HSVBK 38 CONSTANT CFSM
39 CONSTANT PNTP 3A CONSTANT COPS 3B CONSTANT HGFLE
3C CONSTANT LBYT 3D CONSTANT HLDBK 3E CONSTANT WSAD
3F CONSTANT SAD 40 CONSTANT REST 41 CONSTANT HERAZ
42 CONSTANT COPS2 43 CONSTANT PCAT 44 CONSTANT HRSAD
45 CONSTANT HWSAD 46 CONSTANT OTFOC 47 CONSTANT PATCH DECIMAL
( Error checking)
\ G+DOS Error codes and messages.
\ Most of them are useless for this implementation.
\ 0x00 'Nonsense in G+DOS'
\ 0x01 'Nonsense in GNOS'
\ 0x02 'Statement END error'
\ 0x03 'BREAK requested'
\ 0x04 ',SECTOR error'
\ 0x05 'FORMAT data lost'
\ 0x06 'CHECK DISC in drive'
\ 0x07 'No "+ SYS " file'
\ 0x08 'Invalid FILE NAME'
\ 0x09 'Invalid STATION'
\ 0x0A 'Invalid DEVICE'
\ 0x0B 'VARIABLE not found'
\ 0x0C 'VERIFY failed'
\ 0x0D 'Wrong FILE type'
\ 0x0E 'MERGE error'
\ 0x0F 'CODE error'
\ 0x10 'PUPIL set'
\ 0x11 'Invalid CODE'
\ 0x12 'Reading a WRITE file'
\ 0x13 'Writing a READ file'
\ 0x14 'O.K. G+DOS'
\ 0x15 'Network OFF'
\ 0x16 'Wrong DRIVE'
\ 0x17 'Disc WRITE protected'
\ 0x18 'Not enough SPACE on disc'
\ 0x19 'Directory FULL'
\ 0x1A 'File NOT FOUND'
\ 0x1B 'END of file'
\ 0x1C 'File NAME used'
\ 0x1D 'NO G+DOS loaded'
\ 0x1E 'STREAM used'
\ 0x1F 'CHANNEL used'
: IOR>ERROR ( ior -- f n )
\ Convert a DOS ior to a Forth error number.
\ ior = the AF register returned by a DOS command:
\ bit 0 = set: error
\ bits 8-14 = error code
\ bit 15 = set: ZX Spectrum error; unset: DOS error
\ f = error?
\ n = error number:
\ n<0 = ZX Spectrum error number (negative)
\ n>99 = DOS error number (plus 100)
DUP 1 AND \ error?
SWAP 255 / \ error code
DUP 128 AND \ ZX Spectrum error?
IF MINUS ELSE 100 + THEN ;
: ?DOS-ERROR ( ior -- )
\ ior = the AF register returned by a DOS command:
\ bit 0 = set: error
\ bits 8-14 = error code
\ bit 15 = set: ZX Spectrum error; unset: DOS error
IOR>ERROR ?ERROR ;
( Drive)
\ XXX TODO -- Make this compatible with `DRIVE`, the variable
\ used by the tape and disk common words.
CODE DRIVE@ ( -- n )
\ Get the current drive (1 or 2).
BC PUSH IX PUSH \ save the Forth registers
PATCH HOOK
\ 3E01 LDA \ XXX OLD
3ACE LDA \ XXX NEW
\ XXX TODO check this method:
\ bit 0 of 3DD1
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
0 H LD# A L LD PUSHHL JP END-CODE
CODE DRIVE! ( n -- )
\ Set the current drive (1 or 2).
HL POP
BC PUSH IX PUSH \ save the Forth registers
\ XXX OLD
\ HL PUSH
\ PATCH HOOK HL POP L A LD 3E01 STA
\ E7 OUT \ page +D out
\ XXX NEW
L A LD 21 HOOK
IX POP BC POP \ restore the Forth registers
NEXT JP END-CODE
( UFIA manipulation)
: -FILENAME ( -- )
\ Blank the filename in UFIA.
NSTR2 /FILENAME BLANKS ;
: FILENAME! ( ca len -- )
\ Store a filename into UFIA.
\ ca len = filename
-FILENAME /FILENAME MIN NSTR2 SWAP CMOVE ;
: >UFIA ( a1 len1 ca2 len2 -- )
\ Set the UFIA.
\ a1 len1 = memory region
\ ca2 len2 = filename
3 HD00 C! 4 NSTR1 C! \ code filetype and dir description
FILENAME!
DUP HD0B ! FILE-LENGTH !
DUP HD0D ! FILE-ADDRESS !
DRIVE @ DSTR1 C! ;
: FILENAME>UFIA ( ca len -- )
0 0 2SWAP >UFIA ;
\ vim: filetype=abersoftforthafera
.( G+DOS -- part 2 )
\ gplusdos_2.fsb
\ G+DOS support for ZX Spectrum Abersoft Forth (part 2)
\ Copyright (C) 1988,1994,2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Requirements
NEEDS CODE assembler
\ -----------------------------------------------------------
\ Note
\ "DISC" in Forth words means the Forth RAM-disk, after the
\ name used by Abersoft Forth's documentation and vocabulary,
\ e.g. `INIT-DISC`.
\
\ "DISK" means always a G+DOS disk.
\
\ In the comments of this library, "disc" is not used, and
\ the Abersoft Forth RAM-disk is always called "RAM-disk".
\ -----------------------------------------------------------
\ Requirements
\ This module needs the circular string buffer, part of the
\ module <strings.fsb>. But `NEEDS` can not be used yet
\ because it must be defined later.
[UNDEFINED] SAVE-STRING 0 ?ERROR
\ -----------------------------------------------------------
\ History
\ 2015-04-15: Extracted from <gdos_1.fsb>.
\
\ 2015-04-16: File renamed to <g+dos_2.fsb>.
\
\ 2015-04-30: New version of `RUND` and new word `/RUND`,
\ after the tape versions `RUNT` and `/RUNT`. `'BLOCK`
\ instead of `BLOCK>A`, after the change in the main file of
\ the library.
\
\ 2015-05-03: Simpler word names: no "MEM" affix.
\
\ 2015-05-08: Renamed to <gplusdos_2.fsb>, because of an
\ issue with Makefile. Some words are renamed.
\
\ 2015-05-10: `'BLOCK` changed to `'SCR`, after the changes
\ in the library.
\
\ 2015-05-12:
\
\ The "RAM-" prefix is removed from the RAM-disk words, after
\ the changes in the library. Minor fixes: `EMPTY-BUFFERS`
\ instead of `FLUSH`; parameter of `/RUND`.
\
\ Fix: `(<DISK)`. The problem was the specified parameters,
\ stored in UFIA, are always overwritten by the file header.
\ Now they are saved apart and a calculation is done to
\ decide which start address and file length must be used.
\
\ Change: `'SCR` renamed to `DISC-SCR`, after the changes in
\ the library.
\
\ 2015-05-17: New: `FILE?`. Some renamings, after the changes
\ in the library (common core words for some tape and disk
\ operations).
\
\ 2015-05-18: New: support for 16-KiB RAM-disks in memory
\ banks.
\
\ 2015-05-20: The `CAT` code, still under development, is
\ moved to its own file.
\
\ 2015-08-28: Typo.
\ -----------------------------------------------------------
2 10 THRU
( Save a file)
CODE (>FILE) ( -- ior )
\ Save a file to disk using the data hold in UFIA.
BC PUSH IX PUSH \ save the Forth registers
UFIA IX LDP#
HOFLE HOOK \ open the file and create its header
NC IF \ no error?
HD0D DE LDP \ start
HD0B BC LDP \ length
HSVBK HOOK \ save to file
NC IF \ no error?
CFSM HOOK \ close the file
THEN
THEN IX POP BC POP \ restore the Forth registers
AF PUSH \ ior
NEXT JP
END-CODE
( Load a file -- part 1 )
CODE (<FILE) ( -- ior )
\ Load a file from disk, using the data hold in UFIA, the
\ file header and the parameters specified by the high level
\ command.
BC PUSH IX PUSH \ save the Forth registers
UFIA IX LDP# HGFLE HOOK \ get the file
NC IF \ no error? -- load the file header:
\ Load the file header
HD00 DE LDP# 9 B LD# \ destination and count
BEGIN
LBYT HOOK \ load byte and store it in A
DE STAP DE INCP \ update destination and count
DSZ
( Load a file -- part 2 )
\ The start address and length specified
\ in the command are used by default instead
\ of those stored in the file header.
FILE-ADDRESS DE LDP
FILE-LENGTH BC LDP
BC TST \ is the length zero?
\ If so, use the length of the file header instead:
Z IF HD0B BC LDP THEN
\ Load the file data
HLDBK HOOK
THEN
IX POP BC POP \ restore the Forth registers
AF PUSH \ ior
NEXT JP
END-CODE
( Delete a file)
CODE (-FILE) ( -- ior )
\ Delete a disk file using the data hold in UFIA.
BC PUSH IX PUSH \ save the Forth registers
UFIA IX LDP#
HERAZ HOOK \ erase the file
IX POP BC POP \ restore the Forth registers
AF PUSH
NEXT JP
END-CODE
( Forth RAM-disk)
: DISC>UFIA ( ca len -- ) LO 0 2SWAP >UFIA ;
\ `DISC-FILENAME` keeps the address and length of the latest
\ RAM-disk loaded. It is updated by `LOADD?` and used by
\ `(NEEDS-DISK)` to implement nested requirements between
\ modules.
0. 2VARIABLE DISC-FILENAME
\ When the system has been lowered below 0xC000 by
\ <lowersys.fsb>, in order to use the memory banks, and the
\ 16-KiB RAM-disks have been installed by <16kramdisks.fsb>,
\ the G+DOS words that manage the Forth RAM-disk must include
\ the commands to switch the memory banks.
\
\ A flag is calculated to be used by `SAVED?` and `LOAD?`
\ during compilation. Every word needs to check the flag
\ twice. The flag can not be put on the stack and duplicated,
\ because it would be consumed during the compilation, what
\ would make `;` to stop with an error 20 (definition not
\ finished). The variable `X1`, only used by `DRAW`, is used
\ as a temporary storage.
HEX
R0 @ C000 U< \ Has the system been lowered below 0xC000
/DISC 4000 = AND \ and the 16-KiB RAM-disks installed?
0= X1 ! \ No? Save it into a temporary storage.
DECIMAL
\ XXX TODO -- Use a different address to store the flag. One
\ of the planned modules removes `DRAW` and its variables
\ from the dictionary and redefines it in Z80.
( Forth RAM-disk -- user interface)
\ DISC>UFIA ( ca len -- )
\
\ Init the User File Information Area to load or save the
\ Forth RAM-disk. Zero length is specified, what will make
\ `(<FILE)` to use the length of the file header.
\
\ ca1 len1 = filename
: SAVED? ( ca len -- f n )
\ Save the Forth RAM-disk to disk
\ (word named after Abersoft Forth's `SAVET`).
\ ca len = filename
\ f = error?
\ n = error
\ During compilation, as a temporary solution,
\ `X1` holds a flag: Use the original RAM-disk?
DISC>UFIA [ X1 @ ] ?\ DISC-BANK BANK
(>FILE) [ X1 @ ] ?\ 0 BANK
IOR>ERROR ;
\ SAVED ( ca len -- )
\
\ Save the Forth RAM-disk to disk
\ (word named after Abersoft Forth's `SAVET`).
\ ca len = filename
: SAVED ( ca len -- ) SAVED? ?ERROR ;
\ The latest filename used to load a RAM-disk is saved by
\ `LOADD?` (the lowest level word) into the circular string
\ buffer and its address and length are stored into a double
\ variable.
: LOADD? ( ca len -- f n )
\ Load a Forth RAM-disk from disk.
\ (word named after Abersoft Forth's `LOADT`).
\ ca len = filename
\ f = error?
\ n = error
\ During compilation, as a temporary solution,
\ `X1` holds a flag: Use the original RAM-disk?
SAVE-STRING 2DUP DISC-FILENAME 2!
DISC>UFIA [ X1 @ ] ?\ DISC-BANK BANK
(<FILE) [ X1 @ ] ?\ 0 BANK
IOR>ERROR ;
\ LOADD ( ca len -- )
\
\ Load a Forth RAM-disk from disk.
\ (word named after Abersoft Forth's `LOADT`).
\ ca len = filename
: LOADD ( ca len -- ) LOADD? ?ERROR ;
: /RUND ( ca len n -- )
\ Read a new RAM-disk from disk and load block 'n'.
\ ca len = filename
>R EMPTY-BUFFERS INIT-DISC LOADD R> LOAD ;
\ RUND ( ca len -- )
\
\ Read a new RAM-disk from disk and load its first block.
\ ca len = filename
: RUND ( ca len -- ) 1 /RUND ;
( User interface: ordinary files )
: <FILE? ( a1 len1 ca2 len2 -- f n )
\ Load a file from disk.
\ a1 len1 = memory region to load
\ ca2 len2 = filename
\ f = error?
\ n = error
>UFIA (<FILE) IOR>ERROR ;
: <FILE ( a1 len1 ca2 len2 -- )
\ Load a file from disk.
\ a1 len1 = memory region to load
\ ca2 len2 = filename
<FILE? ?ERROR ;
: >FILE? ( ca1 len1 ca2 len2 -- f n )
\ Save a file to disk.
\ a1 len1 = memory region to save
\ ca2 len2 = filename
\ f = error?
\ n = error
>UFIA (>FILE) IOR>ERROR ;
: >FILE ( ca1 len1 ca2 len2 -- )
\ Save a file to disk.
\ a1 len1 = memory region to save
\ ca2 len2 = filename
>FILE? ?ERROR ;
: -FILE? ( ca len -- f n )
\ Delete a disk file.
\ ca len = filename
\ f = error?
\ n = error
FILENAME>UFIA (-FILE) IOR>ERROR ;
: -FILE ( ca len -- )
\ Delete a disk file.
\ ca len = filename
-FILE? ?ERROR ;
( FILE? )
CODE (FILE?) ( -- f )
\ XXX FIXME this changes the current drive to 2! why?
BC PUSH IX PUSH \ save the Forth registers
PATCH HOOK
NSTR2 IX LDP# 1146 CALL
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
0 HL LDP# PUSHHL JPNZ
HL INCP PUSHHL JP
END-CODE
: FILE? ( ca len -- f ) FILENAME! (FILE?) ;
\ CODE DISK-CAPACITY ( -- n )
\ \ n = tracks (+128 if double sided)
\ \
\ \ XXX OLD -- not useful, it just reads the DOS variable at
\ \ 0x2001 or 0x2002, depending on the current drive.
\ PATCH HOOK
\ 0985 CALL
\ E7 OUT \ page +D out
\ 0 H LD# A L LD PUSHHL JP
\ END-CODE
( User interface: screens of the Forth RAM-disk )
: (/LOADD) ( n ca len -- a len1 ca2 len2 )
\ Prepare the parameters to load a RAM-disk from disk,
\ at address of screen n.
\ Warning: the file will be loaded, no matter its length.
\ n = first block (1..11)
ROT FLUSH DISC-SCR 0 2SWAP ;
: /LOADD ( n ca len -- )
\ Load a RAM-disk from disk, at address of screen n.
\ Warning: the file will be loaded, no matter its length.
\ n = first screen (1..11)
(/LOADD) <FILE ;
: /LOADD? ( n ca len -- error? error )
\ Load a RAM-disk from disk, at address of screen n.
\ Warning: the file will be loaded, no matter its length.
\ n = first screen (1..11)
(/LOADD) <FILE? ;
: (/SAVED) ( n1 n2 ca len -- ca len ca2 len2 )
\ Prepare the parameters to save a RAM-disk to disk,
\ from screen n1 to screen n2.
\ n1 = first screen (1..11)
\ n2 = last screen (1..11)
\ ca len = filename
\ ca2 len2 = memory zone
2SWAP 1+ DISC-SCR SWAP DISC-SCR DUP ROT SWAP - 2SWAP ;
: /SAVED ( n1 n2 ca len -- )
\ Save a RAM-disk to disk, from block n1 to block n2.
\ n1 = first block (1..11)
\ n2 = last block (1..11)
\ ca len = filename
(/SAVED) >FILE ;
: /SAVED? ( n1 n2 ca len -- error? error )
\ Save a RAM-disk to disk, from block n1 to block n2.
\ n1 = first block (1..11)
\ n2 = last block (1..11)
\ ca len = filename
(/SAVED) >FILE? ;
\ vim: filetype=abersoftforthafera
.( G+DOS -- part 3 )
\ gplusdos_3.fsb
\ G+DOS support for ZX Spectrum Abersoft Forth (part 3)
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Note
\ "DISC" in Forth words means the Forth RAM-disk, after the
\ name used by Abersoft Forth's documentation and vocabulary,
\ e.g. `INIT-DISC`.
\
\ "DISK" means always a G+DOS disk.
\
\ In the comments of this library, "disc" is not used, and
\ the Abersoft Forth RAM-disk is always called "RAM-disk".
\ -----------------------------------------------------------
\ Requirements
\ `NEEDS` can not be used yet because it's defined in this
\ module...
[UNDEFINED] 2>R 0 ?ERROR
[UNDEFINED] 2R> 0 ?ERROR
\ -----------------------------------------------------------
\ History
\ 2015-05-17: Start.
\ 2015-05-18: Fix.
\ -----------------------------------------------------------
-->
( NEEDS-DISK )
\ XXX TODO
\ (NEEDS-DISK) ( f "filename" -- )
\
\ Disk version of `(NEEDS)`.
\
\ f = is there a word needed from the given filename?
\ XXX FIXME -- This can not work with several nesting levels.
\ The buffers must be emptied at the start and the current
\ block must be refreshed at the end. (new code required to
\ do it) .
\ XXX TODO -- Already solved? Try it.
: (NEEDS-DISK) ( f "filename" -- )
BL WORD IF
DISC-FILENAME 2@ 2>R OFFSET @ >R
HERE COUNT RUND
R> OFFSET ! 2R> EMPTY-BUFFERS LOADD
EMPTY-BUFFERS BLK @ BLOCK DROP
THEN ;
' (NEEDS-DISK) CFA ' ?NEEDS !
\ vim: filetype=abersoftforthafera
.( G+DOS -- CAT )
\ gplusdos_cat.fsb
\ G+DOS `CAT` for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Requirements
NEEDS CODE assembler
\ -----------------------------------------------------------
\ Note
\ "DISC" in Forth words means the Forth RAM-disk, after the
\ name used by Abersoft Forth's documentation and vocabulary,
\ e.g. `INIT-DISC`.
\
\ "DISK" means always a G+DOS disk.
\
\ In the comments of this library, "disc" is not used, and
\ the Abersoft Forth RAM-disk is always called "RAM-disk".
\ -----------------------------------------------------------
\ History
\ 2015-05-20: Extracted from <gplusdos_2.fsb>. Finished.
\
\ 2015-08-27: Typo.
\ -----------------------------------------------------------
-->
( CAT ACAT )
CODE (CAT) ( n -- )
AF POP
BC PUSH IX PUSH \ save the Forth registers
AF PUSH PATCH HOOK
\ Copy Forth UFIA to G+DOS UFIA1.
UFIA HL LDP# UFIA1 DE LDP# /UFIA BC LDP# LDIR
HL POP L A LD \ CAT type: 2=compact;4=detailed
24B5 CALL \ CAT_RUN
168E CALL \ BORD_REST = restore the border
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
NEXT JP END-CODE
\ CAT ( ca len -- )
\
\ Show a disk catologue using the given wild-card filename.
\ See the +D manual for wild-card syntax.
\
\ The catalogue can be printed out on a printer by storing
\ the number 3 into SSTR1 (a field of UFIA that holds the
\ stream number to use) before doing `CAT`. The default value
\ is 2 (screen) and should be restored. Example:
\
\ 3 SSTR1 C! S" FORTH?.*" CAT 2 SSTR C!
: CAT ( ca len -- ) FILENAME>UFIA 4 (CAT) ;
\ ACAT ( ca len -- )
\
\ A variant of `CAT` that shows an abbreviated catalogue.
: ACAT ( ca len -- ) FILENAME>UFIA 2 (CAT) ;
DECIMAL
\ vim: filetype=abersoftforthafera
.( G+DOS support -- +D memory)
\ gplusdos_mem.fsb
\ G+DOS support for ZX Spectrum Abersoft Forth (+D memory)
\ Copyright (C) 1988,1994,2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Description
\ This module provides words to use the memory of the +D
\ interface: ROM 0x0000..0x1FFFF; RAM 0x2000..0x3FFFF.
\ -----------------------------------------------------------
\ Requirements
NEEDS CODE assembler
\ -----------------------------------------------------------
\ History
\ 2015-05-19: Start.
\ -----------------------------------------------------------
2 5 THRU
( DOSC@ )
CODE DOSC@ ( a -- b )
\ Fetch the content of +D memory address.
HL POP
BC PUSH IX PUSH \ save the Forth registers
HL PUSH
PATCH HOOK
HL POP
(HL) A LD 0 H LD# A L LD
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
PUSHHL JP
END-CODE
( DOS@ )
CODE DOS@ ( a -- n )
\ Fetch the content of +D memory address.
HL POP
BC PUSH IX PUSH \ save the Forth registers
HL PUSH
PATCH HOOK
HL POP (HL) E LD HL INCP (HL) D LD
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
DE PUSH
NEXT JP
END-CODE
( DOSC! )
CODE DOSC! ( b a -- )
\ Store b into the +D memory address a.
HL POP DE POP
BC PUSH IX PUSH \ save the Forth registers
DE PUSH HL PUSH
PATCH HOOK
HL POP DE POP E (HL) LD
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
NEXT JP
END-CODE
( DOS! )
CODE DOS! ( n a -- )
\ Store n into the +D memory address a.
HL POP DE POP
BC PUSH IX PUSH \ save the Forth registers
DE PUSH HL PUSH
PATCH HOOK
HL POP DE POP E (HL) LD HL INCP D (HL) LD
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
NEXT JP
END-CODE
\ vim: filetype=abersoftforthafera
.( G+DOS support -- DOS variables)
\ gplusdos_vars.fsb
\ G+DOS support for ZX Spectrum Abersoft Forth (DOS vars)
\ Copyright (C) 1988,1994,2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ Description
\ This module provides words to manage the G+DOS system
\ variables.
\ -----------------------------------------------------------
\ Requirements
NEEDS CODE assembler
\ -----------------------------------------------------------
\ History
\ 2015-04-15: Start.
\
\ 2015-04-16: File renamed to <g+dos_vars.fsb>.
\
\ 2015-05-08: Renamed to <gplusdos_vars.fsb>, because of an
\ issue with Makefile.
\
\ 2015-05-17: `DOSC@` and `DOSC!`are finished.
\ -----------------------------------------------------------
\ Address of the G+DOS vars in its own memory.
8192 CONSTANT DOS-VARS
2 5 THRU
( DOSVARC@ )
CODE DOSVARC@ ( n -- b )
\ Fetch the content of G+DOS variable n.
HL POP
BC PUSH IX PUSH \ save the Forth registers
HL PUSH
PATCH HOOK
HL POP DOS-VARS DE LDP# DE ADDP
(HL) A LD 0 D LD# A E LD
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
DE PUSH
NEXT JP
END-CODE
( DOSVAR@ )
CODE DOSVAR@ ( n1 -- n2 )
\ Fetch the content of G+DOS variable n1.
HL POP
BC PUSH IX PUSH \ save the Forth registers
HL PUSH
PATCH HOOK
HL POP DOS-VARS DE LDP# DE ADDP
(HL) E LD HL INCP (HL) D LD
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
DE PUSH
NEXT JP
END-CODE
( DOSVARC! )
CODE DOSVARC! ( b n -- )
\ Store b into the G+DOS variable n.
HL POP DE POP
BC PUSH IX PUSH \ save the Forth registers
DE PUSH HL PUSH
PATCH HOOK
HL POP DOS-VARS DE LDP# DE ADDP DE POP
E (HL) LD
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
NEXT JP
END-CODE
( DOSVAR! )
CODE DOSVAR! ( n1 n2 -- )
\ Store n1 into the G+DOS variable n2.
HL POP DE POP
BC PUSH IX PUSH \ save the Forth registers
DE PUSH HL PUSH
PATCH HOOK
HL POP DOS-VARS DE LDP# DE ADDP DE POP
E (HL) LD HL INCP D (HL) LD
E7 OUT \ page +D out
IX POP BC POP \ restore the Forth registers
NEXT JP
END-CODE
\ vim: filetype=abersoftforthafera
\ graphics.fsb
\ Graphic extensions for ZX Spectrum Abersoft Forth
\ Copyright (C) 1985-1987,2015 Marcos Cruz (programandala.net)
\ This file is part of
\ Afera (Abersoft Forth Extensions, Resources and Addons)
\ http://programandala.net/en.program.afera.html
\ Copying and distribution of this file, with or without
\ modification, are permitted in any medium without royalty
\ provided the copyright notice and this notice are
\ preserved. This file is offered as-is, without any
\ warranty.
\ -----------------------------------------------------------
\ History
\ 2015-03-28: Code extracted from the main file of the
\ library.
\
\ 2015-04-22: `UDG!` is moved to its own file
\ <udg-store.fsb>.
\
\ 2015-10-26: Updated header.
\ -----------------------------------------------------------
-->
.( Graphic extensions )
FORTH DEFINITIONS DECIMAL
\ System variables and addresses
23677 CONSTANT SYS-COORDS \ ZX Spectrum system variable
SYS-COORDS CONSTANT X-COORD
SYS-COORDS 1+ CONSTANT Y-COORD
22528 CONSTANT ATTRIBUTES
: DRAWL ( x1 y1 x2 y2 -- )
\ Draw a line from x1 y1 to x2 y2
2SWAP PLOT DRAW ;
: RDRAW ( inc-x inc-y -- )
\ Draw a line from the current plot position
Y-COORD C@ + SWAP X-COORD C@ + SWAP DRAW ;
: RDRAWL ( x y inc-x inc-y -- )
\ Draw a line from x1 y1
2SWAP PLOT RDRAW ;
: XY>ATTRA ( x y -- a )
\ Convert a pixel coordinate to its attribute address.
\ XXX TODO Rewrite in Z80, using the ROM routine.
175 SWAP - 8 / 32 * SWAP 8 / + ATTRIBUTES + ;
\ vim: filetype=abersoftforthafera