Source of Afera (part 4: module names H-N)
Description of the page content
Fifth part of the Afera library sources for Abersoft Forth.
Source code
.( Move the 11-KiB RAM-disk )
\ hi-to.fsb
\ Move the RAM-disk of 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.
\ -----------------------------------------------------------
\ Description
\ This module increases the free dictionary space of Abersoft
\ Forth with 1 KiB, but only if the system has been
\ previously moved below 0xC000 by the module <lowersys.fsb>.
\ This module is most useful for a 48K Spectrum; the 128K
\ model can use the module <16kramdisks.fsb> instead, and get
\ 11 KiB of memory for the dictionary.
\
\ A detailed explanation follows.
\
\ The default value of `HI` (the highest address of the
\ 11-KiB RAM-disk) is 1 KiB below the top of memory. That
\ space is used only by the UDG (168 bytes); 856 bytes are
\ unused by the system.
\ Address Returned by Description
\ -------------- ----------- --------------------------
\ 0xFFFF (65535) Top of memory
\ 0xFF58 (65368) `UDG` User defined graphics
\ (168 bytes)
\ Unused space (856 bytes)
\ 0xFBFF (64511) `HI` End of screens area
\ (RAM-disk)
\ 0xD000 (53248) `LO` Start of screens area
\ (RAM-disk)
\ Of course the space above `HI` can be used by Forth
\ programs in any way, but it would be more useful as part of
\ the dictionary space.
\
\ This module is useful only after the module <lowersys.fsb>
\ has moved the system below 0xC000. Otherwise the freed
\ memory will not be available for the dictionary, but simply
\ moved down, between the RAM-disk and the disk buffers.
\
\ When compiling this module, the constant `NEW-HI` must be
\ the latest word defined. It must hold the new address of
\ `HI`. The modules <hi-to-top.fsb> and <hi-to-udg.fsb> do
\ that. See them for details.
\
\ WARNING: If `NEW-HI` is equal or greater than `UDG`, the
\ address of the user defined graphics will be changed to 0
\ (ROM). Then, in order to use them, the user must reserve
\ space for them in the dictionary and point the
\ correspondent system variable (0x5C7B) to it.
\ -----------------------------------------------------------
\ Requirements
49152 R0 @ U< ?NEEDS lowersys
\ The word `NEW-HI` is provided also by the module
\ <hi-to-udg.fsb>, but <hi-to-top.fsb> is used as
\ default.
NEEDS NEW-HI hi-to-top
\ -----------------------------------------------------------
\ History
\
\ 2015-05-15: Start. First working version..
\
\ 2015-05-17: `NEEDS` and `?NEEDS` used.
\
\ 2015-07-18: Fixed the hardcoded addresses of the RAM-disk
\ in `(TAPE)` and the tape headers. This problem was found
\ during the development of Tron 0xF
\ (http://programandala.net/en.program.tron_0xf.html).
\
\ 2015-10-26: Typo.
\ -----------------------------------------------------------
-->
( Main )
HEX
\ If the new location of the RAM-disk
\ overwrites the user defined graphics,
\ point them to 0 (ROM).
UDG NEW-HI U< ?\ 0 5C7B !
NEW-HI 1+ CONSTANT ABOVE-HI
ABOVE-HI /DISC - CONSTANT NEW-LO
NEW-HI HI - CONSTANT FREED
: HI>TOP ( -- )
\ Update `HI` and `LO`:
LO FREED + ' LO ! NEW-HI ' HI !
\ Patch `(TAPE)` and the tape headers
\ with the new value of `LO`:
LO [ ' (TAPE) 6 + ] LITERAL ! LO 75F3 ! LO 7604 ! ;
\ The origin and destination zones overlap, so `CMOVE>`
\ is the preferred method if available.
1 [DEFINED] CMOVE> ?\ 1+
+LOAD
DISC>TOP
FORGET NEW-HI DECIMAL
( Do it with CMOVE> )
: DISC>TOP ( -- )
LO ABOVE-HI /DISC - /DISC CMOVE>
HI>TOP ;
( Do it without CMOVE> )
\ The origin and destination zones overlap, so the 11 KiB are
\ moved by pieces of 512 bytes, from top to bottom.
512 CONSTANT /PIECE
/DISC /PIECE / CONSTANT PIECES
: PIECE ( n -- a1 a2 len )
/PIECE * >R HI R - ABOVE-HI R> - /PIECE ;
: DISC>TOP ( -- )
PIECES 0 DO I PIECE CMOVE LOOP
HI>TOP ;
\ vim: filetype=abersoftforthafera
.( The 11-KiB RAM-disk will be moved up to top of memory)
\ hi-to-top.fsb
\ Move the RAM-disk of ZX Spectrum Abersoft Forth to top
\ 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.
\ -----------------------------------------------------------
\ Description
\ This module increases the free dictionary space of Abersoft
\ Forth with 1 KiB, but only if the system has been
\ previously moved below 0xC000 by the module <lowersys.fsb>.
\ This module is most useful for a 48K Spectrum; the 128K
\ model can use the module <16kramdisks.fsb> instead, and get
\ 11 KiB of memory for the dictionary.
\
\ WARNING: This module moves the RAM-disk to the top of
\ memory, overwritting the zone reserved to user defined
\ graphics (UDG), whose address will be changed to 0 (ROM).
\ Then, in order to use the them, the user must reserve space
\ for them in the dictionary and point the correspondent
\ system variable (0x5C7B) to it. The alternative module
\ <hi-to-udg.fsb> preserves the UDG.
\
\ This module must be loaded right before the module
\ <hi-to.fsb>. See <hi-to.fsb> for full details, including a
\ memory map.
\ -----------------------------------------------------------
HEX
FFFF CONSTANT NEW-HI
DECIMAL
\ vim: filetype=abersoftforthafera
.( The 11-KiB RAM-disk will be moved up below the UDG)
\ hi-to-udg.fsb
\ Move the RAM-disk of ZX Spectrum Abersoft Forth to UDG
\ 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.
\ -----------------------------------------------------------
\ Description
\ This module increases the free dictionary space of Abersoft
\ Forth with 856 bytes, but only if the system has been
\ previously moved below 0xC000 by the module <lowersys.fsb>.
\ This module is most useful for a 48K Spectrum; the 128K
\ model can use the module <16kramdisks.fsb> instead, and get
\ 11 KiB of memory for the dictionary.
\
\ The alternative module <hi-to-top.fsb> overwrites the UDG
\ and frees 1 KiB of memory.
\
\ This module must be loaded right before <hi-to.fsb>. See
\ <hi-to.fsb> for full details, including a memory map.
\ -----------------------------------------------------------
UDG 1- CONSTANT NEW-HI
\ vim: filetype=abersoftforthafera
.( INKEY? )
\ inkeyq.fsb
\ `INKEY?` 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-31: Code written in the main file of the library.
\
\ 2015-04-09: Code extracted from the main file of the
\ library. Moved to a keyboard module.
\
\ 2015-05-03: Code moved to its own file.
\ -----------------------------------------------------------
: INKEY? ( -- c true | false )
\ If a key is pressed, return its code and a true flag;
\ otherwise return a false flag.
INKEY DUP 255 <> DUP 0= IF NIP THEN ;
\ INKEY DUP 255 <> DUP ?EXIT NIP ;
\ vim: filetype=abersoftforthafera
\ keyboard.fsb
\ Keyboard extensions 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.
\ -----------------------------------------------------------
\ Description
\ Some tools to manage key presses. An improved and detailed
\ implementation can be found in the Tron 0xF game
\ (http://programandala.net/en.program.tron_0xf.html).
\ -----------------------------------------------------------
\ History
\ 2015-03-21: Start: ports, key identifiers, key table,
\ 'pressed?', 'pressed'.
\
\ 2015-03-23: Fix: The 0x0A bit mask was used instead of
\ 0x10.
\
\ 2015-10-16: Fixed comment.
\
\ 2016-02-20: Changed the layout of the table.
\ -----------------------------------------------------------
-->
( Keyboard rows ports)
HEX
F7FE CONSTANT KEY-ROW-1-5 \ 1 to 5
FBFE CONSTANT KEY-ROW-Q-T \ Q to T
FDFE CONSTANT KEY-ROW-A-G \ A to G
FEFE CONSTANT KEY-ROW-CS-V \ Caps Shift to V
EFFE CONSTANT KEY-ROW-6-0 \ 6 to 0
DFFE CONSTANT KEY-ROW-Y-P \ Y to P
BFFE CONSTANT KEY-ROW-H-EN \ H to Enter
7FFE CONSTANT KEY-ROW-B-SP \ B to Space
-->
( Key identifiers)
01 KEY-ROW-1-5 2CONSTANT K-1
02 KEY-ROW-1-5 2CONSTANT K-2
04 KEY-ROW-1-5 2CONSTANT K-3
08 KEY-ROW-1-5 2CONSTANT K-4
10 KEY-ROW-1-5 2CONSTANT K-5
01 KEY-ROW-Q-T 2CONSTANT K-Q
02 KEY-ROW-Q-T 2CONSTANT K-W
04 KEY-ROW-Q-T 2CONSTANT K-E
08 KEY-ROW-Q-T 2CONSTANT K-R
10 KEY-ROW-Q-T 2CONSTANT K-T
01 KEY-ROW-A-G 2CONSTANT K-A
02 KEY-ROW-A-G 2CONSTANT K-S
04 KEY-ROW-A-G 2CONSTANT K-D
08 KEY-ROW-A-G 2CONSTANT K-F
10 KEY-ROW-A-G 2CONSTANT K-G -->
( Key identifiers)
01 KEY-ROW-CS-V 2CONSTANT K-CS
02 KEY-ROW-CS-V 2CONSTANT K-Z
04 KEY-ROW-CS-V 2CONSTANT K-X
08 KEY-ROW-CS-V 2CONSTANT K-C
10 KEY-ROW-CS-V 2CONSTANT K-V
01 KEY-ROW-6-0 2CONSTANT K-0
02 KEY-ROW-6-0 2CONSTANT K-9
04 KEY-ROW-6-0 2CONSTANT K-8
08 KEY-ROW-6-0 2CONSTANT K-7
10 KEY-ROW-6-0 2CONSTANT K-6
01 KEY-ROW-Y-P 2CONSTANT K-P
02 KEY-ROW-Y-P 2CONSTANT K-O
04 KEY-ROW-Y-P 2CONSTANT K-I
08 KEY-ROW-Y-P 2CONSTANT K-U
10 KEY-ROW-Y-P 2CONSTANT K-Y -->
( Key identifiers)
01 KEY-ROW-H-EN 2CONSTANT K-EN
02 KEY-ROW-H-EN 2CONSTANT K-L
04 KEY-ROW-H-EN 2CONSTANT K-K
08 KEY-ROW-H-EN 2CONSTANT K-J
10 KEY-ROW-H-EN 2CONSTANT K-H
01 KEY-ROW-B-SP 2CONSTANT K-SP
02 KEY-ROW-B-SP 2CONSTANT K-SS
04 KEY-ROW-B-SP 2CONSTANT K-M
08 KEY-ROW-B-SP 2CONSTANT K-N
10 KEY-ROW-B-SP 2CONSTANT K-B
DECIMAL -->
( Keys table manipulation -- slower )
\ ............................................
\ Method 1: more compact but slower
\ Every key identifier occupies 3 bytes in the table (total
\ size is 120 bytes)
\ 3 CONSTANT /K \ bytes per key definition in the keys table
\ Store a key definition into the keys table:
\ : K, ( bitmask port -- ) , C, ;
\ Fech a key definition from an element of the keys table:
\ : K@ ( a -- bitmask port ) DUP C@ SWAP 1+ @ ;
\ ............................................
\ Method 2: bigger but faster
\ With these words, every key identifier occupies 4 bytes
\ in the table (total size is 160 bytes)
4 CONSTANT /K \ bytes per key definition in the keys table
\ Store a key definition into the keys table:
: K, ( d -- ) , , ;
\ Fech a key definition from an element of the keys table:
: K@ ( a -- bitmask port ) 2@ ;
-->
( Keys table -- comon words and data )
40 CONSTANT KEYS
0 VARIABLE K-TABLE -2 ALLOT
K-1 K, K-2 K, K-3 K, K-4 K, K-5 K,
K-Q K, K-W K, K-E K, K-R K, K-T K,
K-A K, K-S K, K-D K, K-F K, K-G K,
K-CS K, K-Z K, K-X K, K-C K, K-V K,
K-0 K, K-9 K, K-8 K, K-7 K, K-6 K,
K-P K, K-O K, K-I K, K-U K, K-Y K,
K-EN K, K-L K, K-K K, K-J K, K-H K,
K-SP K, K-SS K, K-M K, K-N K, K-B K,
-->
( PRESSED? PRESSED )
: PRESSED? ( n1 n2 -- flag )
\ Is a key pressed?
\ n1 = key bit mask
\ n2 = keyboard row port
INP AND NOT ;
: PRESSED ( -- false | bitmask port true )
\ Return the key identifier of the first key
\ from the keys table that happens to be pressed.
0 \ false by default
[ K-TABLE KEYS /K * BOUNDS SWAP ] LITERAL LITERAL
DO I K@ PRESSED? IF DROP I K@ 1 LEAVE THEN
/K +LOOP ;
-->
( ONLY-ONE-PRESSED )
0. 2VARIABLE K-PRESSED
: ONLY-ONE-PRESSED ( -- false | bitmask port true )
\ XXX TODO finish
\ Return the key identifier of the key pressed,
\ if there's only one key pressed.
0. K-PRESSED 2! \ none by default
[ K-TABLE KEYS /K * BOUNDS SWAP ] LITERAL LITERAL
DO I K@ PRESSED?
IF K-PRESSED 2@ + IF
THEN
/K +LOOP
K-PRESSED 2@ 2DUP + IF 1 ELSE 2DROP 0 THEN
;
\ vim: filetype=abersoftforthafera
\ key_identifiers.fsb
\ Key identifiers 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-23: Written.
\
\ 2015-03-28: Converted to fsb format; file renamed.
\
\ 2015-05-02: Comments.
\ -----------------------------------------------------------
-->
( Load )
HEX
1 3 +THRU
DECIMAL
\ Every key is identified by a double constant that stores
\ the port of the key row and the key bitmask in its row.
( Rows 1-5 Q-T A-G )
01 F7FE 2CONSTANT K-1
02 F7FE 2CONSTANT K-2
04 F7FE 2CONSTANT K-3
08 F7FE 2CONSTANT K-4
10 F7FE 2CONSTANT K-5
01 FBFE 2CONSTANT K-Q
02 FBFE 2CONSTANT K-W
04 FBFE 2CONSTANT K-E
08 FBFE 2CONSTANT K-R
10 FBFE 2CONSTANT K-T
01 FDFE 2CONSTANT K-A
02 FDFE 2CONSTANT K-S
04 FDFE 2CONSTANT K-D
08 FDFE 2CONSTANT K-F
10 FDFE 2CONSTANT K-G
( Rows CS-V 0-9 P-Y )
01 FEFE 2CONSTANT K-CS
02 FEFE 2CONSTANT K-Z
04 FEFE 2CONSTANT K-X
08 FEFE 2CONSTANT K-C
10 FEFE 2CONSTANT K-V
01 EFFE 2CONSTANT K-0
02 EFFE 2CONSTANT K-9
04 EFFE 2CONSTANT K-8
08 EFFE 2CONSTANT K-7
10 EFFE 2CONSTANT K-6
01 DFFE 2CONSTANT K-P
02 DFFE 2CONSTANT K-O
04 DFFE 2CONSTANT K-I
08 DFFE 2CONSTANT K-U
10 DFFE 2CONSTANT K-Y
( Rows EN-H SP-B )
01 BFFE 2CONSTANT K-EN
02 BFFE 2CONSTANT K-L
04 BFFE 2CONSTANT K-K
08 BFFE 2CONSTANT K-J
10 BFFE 2CONSTANT K-H
01 7FFE 2CONSTANT K-SP
02 7FFE 2CONSTANT K-SS
04 7FFE 2CONSTANT K-M
08 7FFE 2CONSTANT K-N
10 7FFE 2CONSTANT K-B
\ vim: filetype=abersoftforthafera
.( Loaded )
\ loaded_execute.fsb
\ Part of a
\ tape source loader for ZX Spectrum Abersoft Forth
\ http://programandala.net/en.program.tron_0xf.html
\ 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.
\ -----------------------------------------------------------
\ Description
\ This file must be the last one to be loaded. It stores the
\ cfa of the latest word into the `LOADED' variable, what
\ causes the loader to stop and to execute it.
\
\ See <loader.fsb> for details.
\ -----------------------------------------------------------
\ History
\ 2015-05-08: Start.
\ 2015-07-14: Updated after the changes in <loader.fsb>.
\ -----------------------------------------------------------
LATEST PFA CFA LOADED !
\ vim: filetype=abersoftforthafera
.( Loaded )
\ loaded.fsb
\ Part of a
\ tape source loader for ZX Spectrum Abersoft Forth
\ http://programandala.net/en.program.tron_0xf.html
\ 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.
\ -----------------------------------------------------------
\ Description
\ This file must be the last one to be loaded. It simply
\ stores 1 into the `LOADED' variable, what causes the
\ loader to stop.
\
\ See <loader.fsb> for details.
\ -----------------------------------------------------------
\ History
\ 2015-05-08: Start.
\ 2015-07-14: Updated after the changes in <loader.fsb>.
\ -----------------------------------------------------------
1 LOADED !
\ vim: filetype=abersoftforthafera
.( Loaded )
\ loaded_quit.fsb
\ Part of a
\ tape source loader for ZX Spectrum Abersoft Forth
\ http://programandala.net/en.program.tron_0xf.html
\ 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.
\ -----------------------------------------------------------
\ Description
\ This file must be the last one to be loaded. It is an
\ alternative to <loaded.fsb>. See <loader.fsb> and
\ <loaded.fsb> for details.
\ -----------------------------------------------------------
\ History
\ 2015-05-09: Start.
\ -----------------------------------------------------------
RP! QUIT
\ vim: filetype=abersoftforthafera
--> \ loader.fsb
\ Part of a
\ tape source loader 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.
\ -----------------------------------------------------------
\ Description
\ This module defines an executes a tape source loader. It is
\ intended to make it easy to load sources of any length, in
\ other words, TAP files that contain any number of Forth
\ RAM-disk files with sources to be compiled in certain
\ order.
\
\ The loader gets every RAM-disk file from tape and loads its
\ screen 1. The process repeats until the `LOADED?` variable
\ is not zero. The modules <loaded.fsb> or
\ <loaded_execute.fsb> can be used to stop the process.
\
\ In some cases <loaded.fsb> or <loaded_execute.fsb> can not
\ be used. For example, when the RAM-disk is used as storage
\ for binary data loaded from tape at the end of the sources.
\ Then the application itself must stop the loader at the end
\ of the compilation process: Setting `LOADED?` to 1 (stop)
\ or -1 (stop and execute the latest word defined) is enough;
\ an alternative method is to clear the return stack with
\ `RP!` and then execute the boot word.
\ Note: This file is the first one to be loaded, even before
\ the <afera.fsb>. That's why it can not use any word defined
\ by the Afera library, or use the first screen for code.
\ -----------------------------------------------------------
\ History
\ 2015-05-08: Start, based on the loader of Tron 0xF
\ (http://programandala.net/en.program.tron_0xf.html).
\
\ 2015-05-17: Fix: `LOADER` didn't reset `LOADED?` at the
\ start.
\
\ 2015-07-05: Fix: Typo.
\
\ 2015-07-14: Changed the name and usage of `LOADED`, in
\ order to make it more flexible. Now any word can be
\ executed, not just the latesonee.
\ -----------------------------------------------------------
( Library modules loader )
." Loader "
FORTH DEFINITIONS
0 VARIABLE LOADED
\ Flag: Have all sources been loaded?
\ It's set in the last source file.
\ Possible values:
\ 0 = keep on loading sources
\ 1 = stop the loader
\ cfa = stop the loader and execute the cfa
: LOADER ( -- )
\ Get and compile every RAM-disk from tape, until `LOADED?`
\ is on, and then, depending of its value, execute the latest
\ word defined.
\ XXX TMP benchmark -- reset the system frames counter
\ 0 23672 ! 0 23674 C!
0 LOADED !
BEGIN LOADED @ 0= WHILE
255 23692 C! ( avoid the "scroll?" prompt)
EMPTY-BUFFERS INIT-DISC LOADT 1 LOAD
REPEAT
\ XXX TMP benchmark -- result
\ 23672 @ 23674 C@ D. ." FRAMES" CR
\ LOADED @ -1 = IF RP! LATEST PFA CFA EXECUTE THEN ;
LOADED @ 1 - IF
RP! LOADED @ EXECUTE QUIT
THEN ;
LOADER
\ vim: filetype=abersoftforthafera
.( Logo-like graphics)
\ logo.fsb
\ Logo-like graphics for ZX Spectrum Abersoft Forth
\ Copyright (C) 1985,2009,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
\ 1985-05-20: First version.
\
\ 2009-05-27: Improved with the following words: `X!`, `Y!`,
\ `COORDS`, `X-COORD`, `Y-COORD, `RELATIVE`.
\
\ 2015-04-15: Included in the Afera library. `COORDS` is
\ renamed to `SYS-COORDS` after the current convention.
\
\ 2015-05-02: Improved with `MINUS` and conditional
\ compilation. `X-COORD` and `Y-COORD` renamed with the
\ "SYS-" prefix, after the current convention for system
\ variable aliases.
\ -----------------------------------------------------------
-->
( Coordinates )
\ Define the required system variables,
\ if needed.
[DEFINED] SYS-COORDS
?\ 23677 CONSTANT SYS-COORDS \ ZX Spectrum system variable
[DEFINED] SYS-X-COORDS
?\ SYS-COORDS CONSTANT SYS-X-COORD
[DEFINED] SYS-Y-COORD
?\ SYS-COORDS 1+ CONSTANT SYS-Y-COORD
: X@ ( -- b ) SYS-X-COORD C@ ;
: Y@ ( -- b ) SYS-Y-COORD C@ ;
: X! ( b -- ) SYS-X-COORD C! ;
: Y! ( b -- ) SYS-Y-COORD C! ;
-->
( Commands )
: RELATIVE ( x1 y1 -- x2 y2 ) Y@ + SWAP X@ + SWAP ;
: RDRAW ( x y -- ) RELATIVE DRAW ;
: SETXY ( x y -- ) RELATIVE PLOT ;
: RIGHT ( u -- ) 0 RDRAW ;
: LEFT ( u -- ) MINUS 0 RDRAW ;
: UP ( u -- ) 0 SWAP RDRAW ;
: DOWN ( u -- ) MINUS 0 SWAP RDRAW ;
: PAT ( x y -- ) Y! X! ;
: RPAT ( x y -- ) Y@ + Y! X@ + X! ;
: RPLOT ( u -- ) 0 SETXY ;
: LPLOT ( u -- ) MINUS 0 SETXY ;
: UPLOT ( u -- ) 0 SWAP SETXY ;
: DPLOT ( u -- ) MINUS 0 SWAP SETXY ;
\ vim: filetype=abersoftforthafera
\ lowerc.fsb
\ `LOWERC` 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-23: First version.
\ -----------------------------------------------------------
-->
.( LOWERC )
HEX
CREATE LOWERC ( c -- c' )
\ Convert an ASCII character to lowercase.
E1 C, \ pop hl
78 05 + C, \ ld a,l
FE C, 41 C, \ cp 'A'
38 C, 06 C, \ jr c,end
FE C, 5B C, \ cp 'Z'+1
30 C, 02 C, \ jr nc,end
E6 C, 20 C, \ or %00100000 ; set bit 5
\ end:
68 07 + C, \ ld l,a
C3 C, PUSHHL , \ jp PUSHHL
SMUDGE
DECIMAL
\ vim: filetype=abersoftforthafera
.( LOWERS )
\ lowers.fsb
\ `LOWERS` 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-05-06: First version.
\ -----------------------------------------------------------
: LOWERS ( ca len -- )
\ Convert a string to uppercase.
BOUNDS DO I C@ LOWERC I C! LOOP ;
\ vim: filetype=abersoftforthafera
.( Lower the system below 0xC000 )
\ lowersys.fsb
\ Move ZX Spectrum Abersoft Forth below address 0xC000
\ 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.
\ -----------------------------------------------------------
\ Description
\ Abersoft Forth is a fig-Forth system and so its memory map:
\ Address Returned by Description
\ -------------- ----------- --------------------------
\ 0xFFFF (65535) Top of memory
\ 0xFF58 (65368) `UDG` User defined graphics
\ Unused space (856 bytes)
\ 0xFBFF (64511) `HI` End of screens area
\ (RAM-disk)
\ 0xD000 (53248) `LO` Start of screens area
\ (RAM-disk)
\ 0xD000 (53248) `LIMIT` End of buffer area plus 1
\ 0xCBE0 (52192) `FIRST` Start of buffer area
\ (lowest buffer start)
\ 0xCBE0 (52192) `R0 @` Initial location (bottom)
\ of the return stack
\ (grows toward low memory)
\ ? `RP@` Return stack pointer
\ 0xCB40 (52032) `TIB @` Terminal input buffer
\ 0xCB40 (52032) `S0 @` Initial location (bottom)
\ of the data stack
\ (grows toward low memory)
\ ? `SP@` Data stack pointer
\ ... Free space
\ 0x819D (33181) `PAD` Text output buffer
\ 0x8159 (33113) `HERE` `WORD` buffer
\ 0x8159 (33113) `HERE` Dictionary pointer
\ 0x5E40 (24128) `0 +ORIGIN` Start of the system
\ The problem is the ZX Spectrum 128 models page the
\ additional RAM banks on the upper 16 KiB of the memory
\ (0xC000-0xFFFF). In order to use this extra memory, the
\ vital parts of the Forth system (the data stack, the
\ terminal input buffer, the return stack and the disk block
\ buffers) have to be moved below address 0xC000.
\ This module is useful for the ZX Spectrum 48 too, in
\ combination with the module <hi-to.fsb>, in order to get 1
\ KiB of additional memory for the Forth dictionary. See
\ <hi-to.fsb> for more details.
\ Important note:
\
\ With the new memory map, a stack overflow could corrupt the
\ dictionary below the stack, before `?STACK` can notice,
\ easier than with the original fig-Forth memory map. The
\ same can happen when a stack is empty.
\ -----------------------------------------------------------
\ History
\ 2015-05-06: Start.
\ 2015-05-07: Data stack, return stack and TIB are moved.
\ 2015-05-08: Block buffers are moved. `FREE` is patched.
\ 2015-07-17: Description completed with a mention to
\ <hi-to.fsb>.
\ -----------------------------------------------------------
\ To-do
\ XXX FIXME 2015-05-15
\
\ Everything works fine when this module is loaded with
\ `LOADER`; but when the module is loaded manually with
\ `RUNT` or `LOADT 1 LOAD`, a strange "OT? MSG # 0" error
\ always happens at the end, but with no `WHERE` parameters
\ on the stack...
\
\ The reason of this problem is still unknown. The contents
\ of the buffers are exactly the same at the end of the
\ proccess, and the pointers have been properly adapted.
\ -----------------------------------------------------------
-->
( Move the data stack )
\ Definition of `?STACK` in C. H. Ting's book _Systems Guide
\ to figFORTH_.
\ : ?STACK ( -- )
\ \ Issue error message
\ \ if the data stack is out of bounds.
\ SP@ S0 > \ out of upper bound?
\ 1 ?ERROR \ stack underflow
\ SP@ HERE 128 + < \ out of lower bound?
\ 7 ?ERROR \ stack overflow
\ ;
\ Definition of `?STACK` in Abersoft Forth.
\ : ?STACK ( -- )
\ \ Issue error message
\ \ if the data stack is out of bounds.
\ SP@ S0 @ SWAP U< \ out of upper bound?
\ 1 ?ERROR \ stack underflow
\ SP@ HERE 128 + < \ out of lower bound?
\ 7 ?ERROR \ stack overflow
\ ;
\ The lower bound has to be changed: instead of `HERE 128 +`
\ it must be the new fixed address.
\ -----------------------------------------------------------
HEX
\ The current dictionary pointer is both the start of the
\ patch and the new lower bound of the data stack.
HERE
\ Step 0: Compile the patch for `?STACK`.
\
\ The first `?ERROR` in `?STACK` is temporarily substituted
\ with `2DROP` to prevent a later error during the init of
\ the new data stack pointers.
' 2DROP CFA , ' SP@ CFA , ' LIT CFA , DUP ,
' < CFA , ' LIT CFA , 7 , ' ?ERROR CFA , ' ;S CFA ,
\ XXX Unused space: 4 bytes at 0x6C4B
\ Step 1: Copy the patch
DUP \ Origin: start of the compiled patch.
' ?STACK 0C + \ Destination: first `?ERROR` in `?STACK`.
OVER HERE SWAP - CMOVE \ Do it.
\ Step 2: Allocate space for the new data stack
\ (0x80 bytes minus the bytes reused from the patch).
80 HERE ROT - - ALLOT
\ Step 3: Init the new data stack pointers.
\ System addresses:
\ 0x5E06 holds `S0`.
\ 0x5E54 holds its initial value.
HERE DUP 5E06 ! 5E52 ! SP!
\ Step 4: Restore the first `?ERROR` of `?STACK`,
\ that was substituted by a `2DROP`.
' ?ERROR CFA ' ?STACK 0C + !
DECIMAL -->
( Move the terminal input buffer )
HEX
\ System addresses:
\ 0x5E0A holds the address of `TIB`.
\ 0x5E56 holds its initial value.
HERE DUP 5E0A ! 5E56 ! 52 ALLOT
DECIMAL -->
( Move the return stack -- old first method ) --> \ XXX OLD
\ XXX FIXME 2015-05-15
\
\ Stacks dont't match at the end: A 0x20 is added at the top,
\ no matter if the limit of the second loop is reduced.
HEX 80 ALLOT \ space for the new return stack
\ System addresses:
\ 0x5E08 holds `R0`.
\ 0x5E54 holds its initial value.
\ 0x5E54 is used only by `COLD`, so it's safe to change it
\ now; it will be used to update 0x5E08:
HERE 5E54 !
: TASK ;
[DEFINED] RDEPTH ?\ : RDEPTH ( -- u ) RP@ R0 @ - -2 / ;
0 VARIABLE SAVED \ Elements saved from the old return stack.
: R>R ( -- )
\ Move the old return stack to the new one.
\ Copy the contents of the old return stack
\ to the data stack
\ (the `LOOP` parameters must be preserved).
RDEPTH
\ XXX TMP for debugging
\ DUP CR ." RDEPTH before=" . ." RTOS=" R . CR
CR .RS
DUP SAVED ! 0 DO R> R> R> ROT ROT >R >R LOOP
\ Activate and clear the new return stack:
5E54 @ 5E08 ! RP!
\ Restore the contents of the old return stack
\ from the data stack to the new return stack
\ (the `LOOP` parameters must be preserved).
SAVED @ 0 DO R> R> ROT >R >R >R LOOP
\ XXX TMP for debugging
\ RDEPTH ." RDEPTH after=" . ." RTOS=" R . KEY DROP ;
CR .RS ;
R>R FORGET TASK DECIMAL -->
( Move the return stack -- second method )
\ This second method is simpler, faster, and works fine.
\ The new stack is an exact copy of the old one.
HEX 80 ALLOT HERE \ space for the new return stack
\ System addresses:
\ 0x5E68 holds the return stack pointer, returned by `RP@`
\ 0x5E08 holds `R0`
\ 0x5E54 holds the initial value of `R0`
: R>R ( a -- )
\ Move the old return stack to the new one.
\ a = top of the new return stack
\ Calculate the positive offset
\ from the old stack to the new one.
R0 @ OVER -
\ Move the contents of the old stack to the new one.
OVER 50 - R0 @ 50 - SWAP 50 CMOVE
\ Activate the new return stack,
\ updating the pointer with the offset.
RP@ SWAP - 5E68 !
\ Update `R0` and its default value.
DUP 5E54 ! 5E08 ! ;
R>R FORGET R>R DECIMAL -->
( Compare buffers ) --> \ XXX TMP for debugging
0 CONSTANT OLD-PREV 0 CONSTANT OLD-USE
LIMIT CONSTANT OLD-LIMIT FIRST CONSTANT OLD-FIRST
B/BUF 4 + CONSTANT /BUF
: .BUFFERS ( -- )
HEX #BUFF 0 DO
." Buffer " I . ." is at " FIRST I /BUF * + U. CR
LOOP DECIMAL ;
-->
( Compare buffers ) --> \ XXX TMP for debugging
: COMPARE ( n1 n2 -- ) 2DUP U. U. SWAP - . CR ;
: MISMATCH ( n -- )
DUP ." Mismatch at FIRST + " U. CR CR
FIRST OVER + 32 DUMP CR OLD-FIRST SWAP + 32 DUMP ;
: COMPARE-BUFFERS ( -- )
HEX CR ." new old offset" CR
." FIRST = " OLD-FIRST FIRST COMPARE
." LIMIT = " OLD-LIMIT LIMIT COMPARE
." PREV = " OLD-PREV PREV @ COMPARE
." USE = " OLD-USE USE @ COMPARE
LIMIT FIRST - 0 DO
FIRST I + C@ OLD-FIRST I + C@ - IF I MISMATCH LEAVE THEN
LOOP DECIMAL ; -->
( Move the disk block buffers and update FREE )
HERE \ address of the new buffers
DUP FIRST - \ negative offset from the old buffers
LIMIT FIRST - ALLOT \ space for the new buffers
: BUFFERS>BUFFERS ( -n a -- )
\ Move the disk buffers to their new position.
\ a = address of the new buffers
\ -n = offset from the old buffers to the new ones
\ Copy the disk buffers to the new address.
FIRST OVER LIMIT FIRST - CMOVE
\ Update their bound addresses.
( a ) DUP ' FIRST ! B/BUF 4 + #BUFF * + ' LIMIT !
\ XXX TMP -- for debugging
\ PREV @ ' OLD-PREV ! USE @ ' OLD-USE !
\ HEX CR ." PREV = " PREV @ U. ." USE = " USE @ U. CR
\ ." offset=" DUP . CR
\ Update the buffer pointers with the offset.
( -n ) DUP PREV +! USE +!
\ XXX TMP -- for debugging
\ ." PREV = " PREV @ U. ." USE = " USE @ U. CR
\ XXX OLD
\ Make this word to forget itself.
\ [ LATEST ] LITERAL DUP DP ! PFA LFA @ CURRENT @ !
\ XXX TMP -- for debugging
\ COMPARE-BUFFERS
; SWAP BUFFERS>BUFFERS FORGET BUFFERS>BUFFERS
\ The word `FREE` returns the free dictionary space,
\ according to the original memory map.
\
\ : FREE ( -- n ) SP@ HERE - ;
\
\ It has to be modified because the top limit of the free
\ dictionary space is not the stack pointer any more, but the
\ start of the RAM-disk, returned by `LO`.
' LO CFA ' FREE !
\ vim: filetype=abersoftforthafera
.( -ROT )
\ minus-rot.fsb
\ `-ROT` 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-29: Code written in the main file of the library.
\ 2015-04-25: Code rewritten in Z80.
\ 2015-05-02: Code moved to this file.
\ 2015-05-13: Faster and smaller code, copied from DZX-Forth
\ (http://programandala.net/en.program.dzx-forth.html).
\ -----------------------------------------------------------
CREATE -ROT ( x1 x2 x3 -- x3 x1 x2 )
\ ROT ROT
HEX
\ XXX OLD first version
\ D9 C, \ exx
\ C1 C, D1 C, E1 C, \ pop bc / pop de / pop hl
\ C5 C, E5 C, D5 C, \ push bc / push hl / push de
\ D9 C, \ exx
\ C3 C, NEXT , \ jp NEXT
\ Version copied from DZX-Forth.
E1 C, D1 C, \ pop hl / pop de
E3 C, \ ex (sp),hl
EB C, \ ex de,hl
C3 C, PUSHDE , \ jp PUSHDE
DECIMAL SMUDGE
\ vim: filetype=abersoftforthafera
.( CMOVE> MOVE )
\ move.fsb
\ `MOVE` and `CMOVE>` for ZX Spectrum Abersoft Forth
\ Copyright (C) 2015 Marcos Cruz (programandala.net)
\ Copyright (C) 1998 Phil Burk
\ 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.
\ -----------------------------------------------------------
\ History
\ 2015-04-14: Code written as part of the strings module.
\
\ 2015-05-15: Code moved to an independent file.
\
\ 2015-10-26: Updated some comments.
\ -----------------------------------------------------------
-->
( CMOVE> )
HEX
CREATE CMOVE> ( ca1 ca2 u -- ) \ Forth-94
\ Note: Code adapted from Lennart Benschop's Spectrum
\ Forth-83.
\ exx / pop bc / pop de / pop hl
D9 C, C1 C, D1 C, E1 C,
\ ld a,c / or b / jr z,end
79 C, B0 C, 28 C, 8 C,
09 C, \ add hl,bc
2B C, \ dec hl
EB C, \ ex de,hl
09 C, \ add hl,bc
2B C, \ dec hl
EB C, \ ex de,hl
ED C, B8 C, \ lddr
\ end: / exx / jp NEXT
D9 C, C3 C, NEXT ,
SMUDGE DECIMAL -->
( MOVE )
: MOVE ( a1 a2 u -- ) \ Forth-94
\ Note: Code copied from Phil Burk's pForth (V19).
>R 2DUP - 0< IF R> CMOVE> ELSE R> CMOVE THEN ;
\ vim: filetype=abersoftforthafera
.( MS )
\ ms.fsb
\ `MS` 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-30: Code written in the main file of the library.
\
\ 2015-04-02: Code moved to a time extensions module.
\
\ 2015-07-16: Code moved to its own file. The temporary
\ version, that depends on the system frames counter and has
\ 20 ms precision, is substituted with code adapted from
\ DZX-Forth.
\
\ 2015-10-26: Improved some comments.
\ -----------------------------------------------------------
FORTH DEFINITIONS -->
( MS )
\ Note: Code adapted from DZX-Forth.
CREATE MS ( u -- ) HEX
\ Wait at least _u_ ms (milleseconds).
D1 C, \ pop de
HERE \ ms1:
78 03 + C, B0 02 + C,
\ ld a,e
\ or d
CA C, NEXT , \ jp z,next
21 C, 0004 , \ ld hl,4 ; MHz
29 C, 29 C, 29 C,
\ add hl,hl
\ add hl,hl
\ add hl,hl
HERE \ ms2:
E3 C, E3 C, E3 C, E3 C,
\ ex (sp),hl ; 19T
\ ex (sp),hl ; 19T
\ ex (sp),hl ; 19T
\ ex (sp),hl ; 19T
E5 C, E1 C, 2B C,
\ push hl ; 11T
\ pop hl ; 10T
\ dec hl ; 6T
3E C, 00 C, 78 05 + C, B0 04 + C,
\ ld a,0 ; 7T
\ ld a,l ; 4T
\ or h ; 4T
C2 C, , \ jp nz,ms2 ; 10T
1B C, \ dec de
C3 C, , \ jp ms1
SMUDGE DECIMAL
( MS ) \ XXX OLD -- first, temporary version
[DEFINED] SYS-FRAMES ?\ 23672 CONSTANT SYS-FRAMES
: MS ( u -- )
\ Wait at least _u_ ms (milliseconds), with 20 ms precision.
20 / SYS-FRAMES @ +
BEGIN DUP SYS-FRAMES @ U< UNTIL DROP ;
( MS ) \ XXX TODO -- alternative version
\ Note: Code from Matteo Vitturi's vForth, not adapted yet.
\ POP DE|
\ BEGIN,
\ LDI A'| 171 N,
\ BEGIN,
\ NOP
\ DEC A'|
\ -UNTIL,
\ DECX DE|
\ LD A'| D|
\ ORA E|
\ -UNTIL,
\ vim: filetype=abersoftforthafera
.( :NONAME )
\ noname.fsb
\ `:NONAME` 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-15: First draft.
\
\ 2015-05-04: First working version.
\
\ 2015-07-06: Bug found and fixed: the `SMUDGE` included to
\ compensate the `SMUDGE` done later by `;` made it
\ impossible to find the latest defined word during the
\ definition started by `:NONAME`. The solution is to patch
\ `;` and make `;` to unpatch itself every time. `;SMUDGE` is
\ written for that.
\ -----------------------------------------------------------
-->
( Patch ; )
: ;SMUDGE ( -- )
\ Called by `;` to do `SMUDGE`.
[ HERE ] \ Save the address of `SMUDGE`.
SMUDGE \ When patched by `:NONAME`, this is `NOOP`.
\ Unpatch a possible patch done by `:NONAME`,
\ using the saved address where `SMUDGE` was compiled:
[ ' SMUDGE CFA ] LITERAL LITERAL ! ;
\ Substitute the `SMUDGE` in `;` with `;SMUDGE`:
' ;SMUDGE CFA 25378 !
-->
( :NONAME )
: :NONAME ( -- cfa )
?EXEC CURRENT @ CONTEXT !
\ Deactivate the `SMUDGE` in `;SMUDGE`:
[ ' NOOP CFA ] LITERAL ' ;SMUDGE !
\ Create a code field of a colon definition:
HERE !CSP 25350 , \ 25350 = address of do_colon
] ;
\ vim: filetype=abersoftforthafera
\ notequals.fsb
\ `<>` 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-05-12: Extracted from the main file of the library and
\ rewritten in Z80.
\ -----------------------------------------------------------
-->
.( <> )
CREATE <> ( n1 n2 -- f )
\ = 0=
HEX
E1 C, \ pop hl
D1 C, \ pop de
A0 07 + C, \ and a ; reset cy flag
ED C, 52 C, \ sbc hl,de
78 04 + C, \ ld a,h
B0 05 + C, \ or l
CA C, PUSHHL , \ jp z,PUSHHL
21 C, 1 , \ ld hl,1
C3 C, PUSHHL , \ jp PUSHHL
SMUDGE DECIMAL
\ vim: filetype=abersoftforthafera