# Programming the 80’s way #3

### Introduction to Integers.

One of my favorite tasks using a small system like our ZX Spectrum is to overcome limitations imposed on integers and floating-point numbers.

In ZX Basic, integers have a width of 16 bits (plus sign) allowing you to manipulate numbers between -65.535 and 65.535, and once out of this range, you’re venturing into floating point numbers wilderness.

In Forth, unless you can rely on some floating-point library, all math is integer math, and usually Z80 implementations uses 16-bits single-precision integers and 32-bits double-precision integers, so expanding the range to a wider interval of integers that lie between -2.147.483.648 and 2.147.483.647.

The lack of floating-point and engineering notation is not so bad because the trade-off is a faster speed and great simplicity, by defining suitable fine-grained unit-of-measure like “millimeters” instead of “thousandth of meter”, for instance.

On the other hand, irrational constant numbers, like “Greek-Pi”, that have an infinite number of decimal places, cannot be exactly represented neither using floating-points nor double precision integers, and in Forth, it is very common to exploit irrational constant numbers via Rational Approximation.

The concept behind this useful technique is that any irrational number can be represented by a rational approximation. For example, 355/113 is a very good approximation of “pi” with an error of less than one part in a million.

For instance, the formula to calculate the circumference of a circle can be coded directly as

```    : CIRCUMFERENCE  ( n1 -- n2 )
2* 355 113 */
;
```

in particular, the definition  */   is the typical scaling operator that takes a single-precision integer multiplies it by a number (355 in our case) and divides it by another (113 in our case) but ensuring a double-precision intermediate result to avoid loss of precision.

### Triple-precision integers

My v-Forth implementation provides a definition  UM* to multiply two single-precision numbers and get a double-precision number, and a definition  UM/MOD  to divide a double-precision number and get two single-precision numbers quotient and reminder.

It seems there is little way to use some “triple-precision” [1] integer i.e. 48-bits of precision, but I’ll show how I had the chance to code an improved definition of  */   that operates on a double-precision integer passing through a “triple-precision” integer so we can improve our previous version of CIRCUMFERENCE to cope with “double-precision” integer and use a “triple-precision”  intermediate result using this new definition  M*/

```    : CIRCUMFERENCE  ( d1 -- d2 )
2DUP D+      \ double the radius
355 113 M*/
;
```

Here below, I expose the implementation of such  M*/   using the math definitions already available UM* and UM/MOD.

In the following definition explanation, each symbol represents a single-precision unsigned integer, that is a number between 0 and 65535, so we can think of it as we were using some “65536-based” math.

1. we can split the double-precision integer  d  into its two components dH and dL and then multiply them by m separately getting two double-precision integer a and b, we split in aH, aL and bH, bL.
2. we have to add  aH part to b obtaining c, we split in cH, cL. This way we now have three single-precision integers cH, cL, aL, that represents our triple-precision intermediate value integer.
3. We can perform one first division, dividing c by n obtaining quotient q1 and reminder r1.
4. We compose r1 and aL that is the double-precision number we now divide by n to obtain quotient q2, while remainder r2 is discarded for our purposes.
```\     dH dL  x
\         m  =
\ ----------
\     aH aL
\  bH bL
\ ----------
\  cH cL aL  :  n  =  q1  q2
\     r1 aL
\
: M*/     ( d m n -- d2 )
2dup xor 3 pick xor >R     \ keep track of final sign
abs >R abs >R
swap R@ UM* rot R> UM*     \ 1. multiply by m and get a and b
rot 0 D+                   \ 2. obtain c
R@ UM/MOD                  \ 3. divide n into c giving quotient and reminder
rot rot R> UM/MOD          \ 4. divide n into the composition r1+aL
nip swap                   \ discard reminder r2 and reorder the two partial-quotients
R> D+-                     \ determine final sign.
;```

For example:

`500000. CIRCUMFERENCE D.`

prints

`3141592`

In conclusion, using just some Arithmetics we overcame the native 32-bit vForth limitation.

[1] Forth Application Techniques – Elizabeth D. Rather and the technical staff of FORTH Inc. – 2000 Forth Inc.

• peter bierbach says:

Hi good afternoon.

next vforth :

——————————–
NEEDS OPEN<
NEEDS J
needs layer11

layer11
OPEN< >R

6912 0 DO
16384 6912
J
DROP
LOOP
R> F_CLOSE 42 ?ERROR ;

: los
;
——————————

thanks, the new version (27.08.) is now running without any flaws.

there are no defects with me.
my english skills are not good.

to switch off the blinking cursor you have to explain to me.

thanks
greeting

• Hi Peter
If I understand what you wish to do, you don’t need a DO-LOOP structure to display a .SCR file.
Let me show my example to load, for instance, /DOT/KEYBOARD.SCR keymap file.

``` NEEDS LAYER11 DECIMAL : WAIT-BREAK ( -- ) \ wait for [BREAK] while cursor is hidden BEGIN ?TERMINAL UNTIL ; : SHOW-SCR LAYER11 OPEN< \ this leaves file-handle number on TOS DUP \ for later f_close 16384 6912 \ address and length to be read ROT \ bring file-handle on TOS F_READ DROP DROP \ ingore status and actual byte read F_CLOSE DROP \ ignore status ;```

``` ```

``` SHOW-SCR /DOT/KEYBOARD.SCR WAIT-BREAK ```

(The above code is copied by hand while I was testing it on CSpect emulator, it should work, but beware any typo)

( output )

Regards
_M.

• peter bierbach says:

hello tanks for : show-scr.
is wonderful.

how do I get this under : wait-break ?
—————————
: starte
case
119 of oben endof
101 of rechts endof
115 of unten endof
endcase ;

: los
SPRITE 0 SPRITE-UPDATE

begin
key
dup 13 – while
starte
repeat drop ;
————————

thanks
greeting

• Peter,
the problem is KEY that “stops execution, shows a flashing cursor and waits for a keypress”.
To avoid such a stop, you have to scan the keyboard yourself or check “LASTK” system variable at 23560 which is updated during standard interrupt routine: vForth much relies on any standard ZX-Spectrum behavior.
To see an example of Pac-Man like game, give a look to my “Chomp-Chomp” example available in Screens# 600-670: you can just give :
and after a minute, when compilation is done:
GAME

• peter bierbach says:

please can you help save f_write?

the datentest.bin is “0”

danke.
gruss
———————————-
NEEDS OPEN<
256 CONSTANT BUFLEN
CREATE BUFER BUFLEN ALLOT
BUFER BUFLEN ERASE

: voll
buflen 0 do
i dup bufer + c!
loop ;

: daten-save
OPEN<
DUP
BUFER BUFLEN
ROT
F_WRITE DROP DROP
F_CLOSE DROP
;

voll
DATEN-save ../../fth/datentest.bin

: los
;
————————-

• Hi Peter,
OPEN< opens file in read-only mode and cannot be use to save.
Try SEE OPEN< to understand how it is implemented.

There is a small example in Screens# 184-185 that could help with FILENAME" and SAVE-BYTES
For example
FILENAME" filename.bin" ( keep the string "filename.bin" at PAD which is a volatile memory zone )
16384 6912 SAVE-BYTES ( and try to save the standard screen to filename.bin )

Give a look to PDF manual https://github.com/mattsteeldue/vforth-next/blob/master/doc/vForth1.5-core-en.pdf

Regards.
_Matteo.

• peter bierbach says:

—————–
600-670: you can just give :
——————
but could not find my solution.
can you please give a tip where that can be found in there?

thanks.
greeting

• peter bierbach says:

hello my great master.
I’ve already learned some important things from you.
thanks.

this is ok:
……..
………
bufer 255 Filename “/daten/test.dat” save-bytes
: starte
;

this is not ok, how do you have to write it in there please?
…….
…….
: starte
bufer 255 Filename “/daten/test.dat” save-bytes
;

this is also not ok:
: starte
show-scr ../../fth/bild.scr
;

greeting

• Hi Peter,
There must be no space between Filename and ” since the word is FILENAME” (notice the final “).
Then there must be a space after FILENAME” and your filename that must be terminated with a double-quote ” .
bufer 255 Filename” /daten/test.dat” save-bytes

As per LASTK variable, see Screen # 660 where is defined MOVE-PACMAN.

Beware that Screen# 600-668 names “SPRITE” anything that moves, but in reality they are all old-fashion UDGs.

• peter bierbach says:

Hi, Thank You.
this is ok.
or do you have another tip please?

greeting

————————
……….
……….
……….
: los
SPRITE 0 SPRITE-UPDATE

begin
23560 c@
2000 0 do loop
starte
again ;

los
——————————–

• My tip: You are using a DO-LOOP to produce some delay…. I prefer synchronize everything at some point using SYNC that executes an HALT op-code. There is a few examples of it in Screen # 63, # 239 or # 601.

• peter bierbach says:

my sprite loop
——————————–
……….
……….
: starte
case
dup 119 of oben endof
dup 101 of rechts endof
dup 115 of unten endof
dup 104 of 0 xsprite-hide 1 xsprite-hide 2 xsprite-hide endof
dup 97 of sprnr 1 + to sprnr sprnr SPRITE _spriteid ! SPRITE 0 SPRITE-UPDATE endof
dup 98 of sprnr 1 – to sprnr sprnr SPRITE _spriteid ! SPRITE 0 SPRITE-UPDATE endof
dup 99 of 1 sprite _pattern ! SPRITE 1 SPRITE-UPDATE endof
100 of 2 sprite _pattern ! SPRITE 2 SPRITE-UPDATE endof
endcase ;

: los
SPRITE 0 SPRITE-UPDATE
begin
23560 c@
3000 0 do loop
starte
again ;

los

• peter bierbach says:

hello tanks for info.
I use the sprite definition from #scr 400.

this is ok :
…….
…….
bufer 255 Filename” /daten/test.dat” save-bytes
……
……

——————————————————–

this not funktion:
…….
…….
: starte
bufer 255 Filename” /daten/test.dat” save-bytes
;
……
……

thanks
greeting

• for safety reason (and because i am often dumb) the example SAVE-BYTES cannot overwrite a file: only new files please.
If you need to overwrite a file you have open it in read/write mode and do that by using the correct “flags-number” used by F_OPEN primitive-word:

f_open ( a1 a2 b — u f )
\ open a file
\ a1 (filespec) is a null-terminated string, such as produced by ,” definition
\ a2 is address to an 8-byte header data used in some cases.
\ b is access mode-byte, that is a combination of:
\ any/all of:
\ esx_mode_write \$02 request write access
\ plus one of:
\ esx_mode_open_exist \$00 only open existing file
\ esx_mode_open_creat \$08 open existing or create file
\ esx_mode_creat_noexist \$04 create new file, error if exists
\ esx_mode_creat_trunc \$0c create new file, delete existing
\ Return file-handle u and 0 on success, True flag on error

• peter bierbach says:

thank you for your great description of the handling of the files.

a file in here ” : start … ; ” calling with start does not work:
: start
bufer 255 Filename ” /daten/test.dat” save-bytes
;

why not ?

greeting

thanks
greeting

• FILENAME” is quite experimental and for now can be used only interactively , i.e. it cannot be compiled as you’re trying to do. I hope improving it in the future.

In general (and in your case), first you need to declare a string containing the filename:

`CREATE DATEN-FILE ," /daten/test.dat" `

this create a new variable called DATEN-FILE that is a ‘counted-and-zero-terminated’ string suitable to be used with NextZXOS I/O primitives.
You can see its content using

`DATEN-FILE COUNT TYPE `

or

`DATEN-FILE 20 DUMP`

Then, I would define something like this

``` : SAVE-BUFER ( a -- ) \ save bufer to filename given by the counted-zero-terminated-string a 1+ 0 ( a 0 ) \ just to agree with F_OPEN syntax [ HEX ] 0E [ DECIMAL ] ( a 0 b ) \ option to create or overwrite file F_OPEN 41 ?ERROR ( fh ) \ DUP BUFER 255 ROT ( fh buf 255 fh ) F_WRITE 47 ?ERROR ( fh n ) \ write file DROP ( fh ) \ ignore number of bytes written F_CLOSE 42 ?ERROR ( ) \ close ; ```
you can use it anywhere as

DATEN-FILE SAVE-BUFFER

• peter bierbach says:

thanks for the information.

I would like to invite data several times after you have done it in a game.
i am looking forward to this change

thanks.
greeting.

• peter bierbach says:

this : SAVE-BUFER ( a — ) is ok !!!

tanks
greeting

• peter bierbach says:

Hi, Thank You.

greeting

——————————-
NEEDS J
NEEDS VALUE
NEEDS TO
needs layer11

down

layer11

100 mmu7!
: load-bild ( a — )
1+ 0
[ HEX ] 01 [ DECIMAL ]
F_OPEN 41 ?ERROR
DUP [ hex ] e000 1b00 [ decimal ] ROT
DROP
F_CLOSE 42 ?ERROR
;

CREATE DATEN-FILE ,” /fth/bild.scr”

: los
100 mmu7!

[ hex ] 1b00 0 do i e000 + c@ 4000 i + c! loop [ decimal ]
;
————————————–

• peter bierbach says:

hello you good man ….
why are they going :
Scr# 400 ( Sprite struct definition )

not by layer2:
if I have set to layer2 and then invite the sprites, the program jumps back to layer12.

thanks
greeting

• The reason is in Screen# 409 where i did

`BINARY 00001011 HEX 15 REG!`

that sets the Layers priority to “SUL” i.e. (Sprite over ULA over Layer2). Change it to “SLU” with

`BINARY 00000011 HEX 15 REG!`

• peter bierbach says:

now it works with the sprite.

greeting

• peter bierbach says:

hello you specialist from vforth, good afternoon.
i am happy that with me that vforth always
can do more thanks to your help.

I can’t get this sin-cos down to work with vforth.
or do you already have another idea for the future of sin-cos with integrity?

thanks
greeting

————————————-
\ Sinus und Cosinus
\ Tabellengestützte Berechnung für ganze Zahlen.
\ Ergibt auf 10K skalierte Werte.

\ Prototypische Lösung mittels:
\ Gforth 0.6.2, Copyright (C) 1995-2003 Free Software Foundation, Inc.

vocabulary sinus sinus definitions decimal

0000 , 0175 , 0349 , 0523 , 0698 , 0872 ,
1045 , 1219 , 1392 , 1564 , 1736 , 1908 ,
2079 , 2250 , 2419 , 2588 , 2756 , 2924 ,
3090 , 3256 , 3420 , 3584 , 3746 , 3907 ,
4067 , 4226 , 4384 , 4540 , 4695 , 4848 ,
5000 , 5150 , 5299 , 5446 , 5592 , 5736 ,
5878 , 6018 , 6157 , 6293 , 6428 , 6561 ,
6691 , 6820 , 6947 , 7071 , 7193 , 7314 ,
7431 , 7547 , 7660 , 7771 , 7880 , 7986 ,
8090 , 8192 , 8290 , 8387 , 8480 , 8572 ,
8660 , 8746 , 8829 , 8910 , 8988 , 9063 ,
9135 , 9205 , 9272 , 9336 , 9397 , 9455 ,
9511 , 9563 , 9613 , 9659 , 9703 , 9744 ,
9781 , 9816 , 9848 , 9877 , 9903 , 9925 ,
9945 , 9962 , 9976 , 9986 , 9994 , 9998 ,
10000 ,

: sinus@ cell * sinustabelle + @ ;
: sin ( grad — sinus )
dup 0r abs
360 mod
dup 180 > if 180 – true >r else false >r then
dup 90 > if 180 swap – then
sinus@
r> if negate then
r> if negate then ;
: cos 90 + sin ;
————————————-

• I suggest to move all these discussion within SpecNext Forum
https://www.specnext.com/forum/
Maybe we can add someone else’s contribution.

Here is my working version with a little optimization:

```: sin ( grad -- sinus ) dup >r \ save grad sign abs 360 mod dup 180 > if 180 - -1 else 0 then >r dup 90 > if 180 swap - then sinus@ r> +- \ apply sign -1 or 0 r> +- \ apply grad sign ```

Also needs CELL :
```2 constant cell ```

_M.

• peter bierbach says:

Hi, Thank You.

sine-cosine now works wonderfully with vforth.
maybe you can include that in your list?

greeting

• peter bierbach says:

try again here!!!

NEEDS VALUE
NEEDS TO
NEEDS CASE
NEEDS J

abs 360 mod
dup 180 > if 180 – -1 else 0 then >r
dup 90 > if 180 swap – then
sinus@
r> +-
r> +- ;

: cos 90 + sin ;

: los
SPRITE 0 SPRITE-UPDATE

80 to weg
360 0 do
wx i sin weg 10000 */ + to x
wy i cos weg 10000 */ + to y

x SPRITE _xcoord !
y SPRITE _ycoord !
SPRITE 0 SPRITE-UPDATE
1 pause
loop

80 to weg
360 0 do
wx 360 i – sin weg 10000 */ + to x
wy 360 i – cos weg 10000 */ + to y

x SPRITE _xcoord !
y SPRITE _ycoord !
SPRITE 0 SPRITE-UPDATE
1 pause
loop ;

• peter bierbach says:

everything is chaotic, the sine table does not appear and some other things also do not.
can you completely delete all three of this demo spritesinus?

thanks.

• peter bierbach says:

can you open a new title there “vforth”?
greeting

—————————————–
I suggest to move all these discussion within SpecNext Forum
https://www.specnext.com/forum/
Maybe we can add someone else’s contribution.
——————————————

• peter bierbach says:

Hi good afternoon.
the cursor has to be somewhere in vforth as a char.
how can you draw the cursor-char “empty”?

thanks.
greeting

• To make disappear the KEY flashing cursor you can give (at your risk…)
HEX
BL 026 +ORIGIN C!
BL 027 +ORIGIN C!
BL 028 +ORIGIN C!

• peter bierbach says:

hello thanks for info for cursor.

greeting

• peter bierbach says:

hello, good afternoon vforth fachman.

but unfortunately I can’t find a demo that I understand.

thanks.
greeting

• peter bierbach says:

the vforth is very interesting, that’s why my many questions.

thank you for your work for this float.

you have set the software flash to 32 with me.
——————————–
\ software-flash: flips face every 320 ms
LDN A’| HEX 10 N,
ANDA (IY+ HEX 3E )|
\ LDN A’| HEX 8F N,
LDA() HEX 026 org^ + AA,
JRF NZ’| HOLDPLACE \ IF,
\ LDN A’| HEX 88 N,
LDA() HEX 027 org^ + AA,
BIT 3| (IY+ HEX 30 )|
JRF Z’| HOLDPLACE \ IF,
\ LDN A’| 5F N,
LDA() HEX 028 org^ + AA,
HERE DISP, \ THEN,
HERE DISP, \ THEN,
—————————————

can you do an emit without the flash being set to the right?

thanks.
greeting

• I am not quite sure what you’re meaning by “the flash being set to the right”.

KEY is a low-level word that waits for a keypress and returns its Ascii code and should not be used for real-time keyboard scan typical of games.

Games must use some more complex piece of software like Mr. Jones’ keyboard test routine that I’ve made available in Screen # 48 (you must provide a “scan-code” number and that routine returns a TRUE / FALSE flag).

A very simple game that uses one key at a time can simply use LASTK system variable (location 23560) to check the keyboard status i.e. the last key pressed.

• peter bierbach says:

hello, good afternoon master.

I now have to get to know how to use the commands. Enter float numbers and output float numbers again

started it with “needs floating”

thank you very much.

• In this last build I’m providing an experimental (but useful) “Floating-Point Option Library”.
Using NEEDS FLOATING the library is loaded in dictionary and provides a simple interface to the ZX Spectrum “standard ROM” Floating-Pointer routine (RST \$28).
e.g.
``` FLOATING ( to set NMODE to 1, that is Floating-Point mode ) 12.0 2.5 * F. ( and get 3.0000E1 ) 2.0 FSQRT F. ( and get 1.4142E0 ) 30.0 DEG>RAD FSIN F. ( and get 0.5000E0 ) INTEGER ( to set back NMODE to 0, that is integer mode ) ```

Screen # 470 contains an example that produce a your Sine-Cosine table values that is “a generated Forth code” in Screen # 471.

I’ve added a chapter in the documentation https://github.com/mattsteeldue/vforth-next/blob/master/doc/vForth1.5-core-en.pdf
_M.

• peter bierbach says:

thanks for the little float demo.
I’ve slowly got used to it.
once again my thanks for your work with the float for the vforth.

greeting

• peter bierbach says:

thanks.
the Screen # 470 , Screen # 471 is empty .

https://github.com/mattsteeldue/vforth-next/blob/master/doc/txt/!Blocks-64.bin_20210916.txt

greeting

• Again, silly me: I’ve just changed my laptop and restored some wrong backups…
Now it should be fine.

Screen # 470 is a funny example of “code generator”: the fastest way to write such a generated code is to write it to a BLOCK

_M.

• peter bierbach says:

is ein error in float?

needs floating
30.0 deg>rad fsin f. -0,8660E0 ok

greeting

• Silly me !
I released the wrong version where I swapped the two definitions RAD>DEG and DEG>RAD
Now it should be fine.
_M.

• peter bierbach says:

my demo :

———————————
needs floating
: los
12.0 2.5 * F.
2.0 FSQRT F.
INTEGER ;
————————————–

los
30.0 deg>rad fsin f. -0,8660E0 ok

greeting

• peter bierbach says:

here is the output of my program:
los 0.0000E0 4,4721E0 -0.8660E0 ok

greeting

• peter bierbach says:

hello, is noch error :
: los
12.0 2.5 * F.
2.0 FSQRT F.
INTEGER ;

los 0.0000E0 4,4721E0 -0.8660E0 ok

thanks
greeting

• peter bierbach says:

hello, the result is not yet correct.
thanks.
greeting

los 0.0000E0 4,4721E0 -0.8660E0 ok

• peter bierbach says:

I tested it like this:
: deg>rad pi 180.0 f/ f* ;

f. 0.5000E0 ok

• peter bierbach says:

hello,
an error must occur in there when it is loaded with “needs floating”

greeting

• Just reloaded the .zip file, maybe it was still old …
Anyway, you’ve managed very well to find the bug.

• peter bierbach says:

hello, now it’s wonderful.
I had caught the old vforth again who had the old bug.
now i have the new changed vforth and it works.

greeting

• peter bierbach says:

thank you again for your great help.

now I would like to make a graph with floating sine-cosine:
plot and draw!
which screen # do I have to load for plot and draw?
in which layer can I please use the plot and draw?

thanks.
greeting

• Old standard ZX Spectrum’s ROM PLOT and DRAW routine are available via 43 LOAD
I just tested, they work in LAYER11 and LAYER0 (LAYER10 and LAYER2 seems not to work).
In LAYER12 they behave in a funny way.

I think we should move all these discussion to

In “Z80 Assembler” subsection of Programmers’ Corner should be fine: https://www.specnext.com/forum/viewforum.php?f=16

• peter bierbach says:

https://www.specnext.com/forum/

do you have the opportunity to bring everything that has been written here so that others can benefit from it?
and you the first point of contact?

thanks.
greeting

• peter bierbach says:

hello, here is a demo with draw and floating.

greeting

https://www.specnext.com/forum/viewtopic.php?f=13&t=2028

• peter bierbach says:

Hi good afternoon.

there is one thing that I cannot clarify myself.
this cursor is still there, but it just can’t be seen and is still to the right of the last click and takes a place.

my question is :
can you switch off the cursor so that it is no longer generated by the program for a certain input and therefore does not occupy any space on the screen?

thanks.
greeting

• During execution, the cursor isn’t displayed unless you’re explicitly use KEY.
So, you need to write your own word like the following example that “waits for a keypress” tout-court:

```HEX 5C08 CONSTANT LAST-K : KEYPRESS ( -- c ) 0 LAST-K C! BEGIN LAST-K C@ UNTIL LAST-K C@ ;```

KEY is written in machine-code and honestly the flashing cursor cannot be disabled.
In vForth, KEY is used only by ACCEPT which is used by QUERY which in turn is used by QUIT.
QUIT puts in place the main-loop that waits for keystrokes and INTERPRETs them by compiling or executing.

• peter bierbach says:

hello, good afternoon you specialist.
it works wonderfully with the floating and the sprites.

now I wanted to load my own interrupt with include.
when it was loaded the vforth crashes.

how can I please stop it again with int-off

tanks
greeting

—————————
needs interrupt
needs value
needs to

: at. 22 emitc swap emitc emitc ;
: ink. 16 emitc emitc ;
: paper. 17 emitc emitc ;

0 value wert

: isr-test
23672 ( frames ) @ 7 and 0= if
wert 1 + to wert
0 0 at. wert .
endif ;

int-on
———————————

• You must first set INT-W properly.

INT-OFF ( for safety reason )
‘ ISR-TEST INT-W ! ( put xt of your “ISR word” to INT-W variable )
INT-ON ( go live )

And remember to give INT-OFF if you FORGET ISR-TEST to re-do the same compilation…

• peter bierbach says:

hello, please have a look at the interrupt program with the picture.
https://www.specnext.com/forum/viewtopic.php?f=13&t=2028&p=12967#p12967

What am I doing wrong?

I also have such a crash here with:
——————————-

: at. 22 emitc swap emitc emitc ;
: ink. 16 emitc emitc ;
: paper. 17 emitc emitc ;

hex 5c08 constant last-k decimal

: keypress ( — c )
0 last-k c!
begin last-k c@ until
last-k c@
;

: los
begin
keypress
.
again ;
——————————

thanks.
greeting

• It works! But I would modify your infinite loop BEGIN-AGAIN like this

: los
begin
keypress
.
?terminal until ;

To stop the main loop you just have to use [BREAK] key (i.e. Caps Shift + SPACE)

• peter bierbach says:

hello thanks for keypress.

greeting

• peter bierbach says:

hello, good afternoon master.
my next problem is with layer2 for vforth.

How can you bring in a picture in layer2, please?
I don’t know where the screen address is.

how can you please bring tile in in vfoerth?
would also be a good extension for the vforth.

thanks.
greeting

• Hi Peter, I’m glad you’re asking, I’m planning to code some good example.

For now, Layer 2 can be enabled via LAYER2 that effectively invokes 512 IDE_MODE! to select High-Resolution Mode and chooses 64 characters per line to be compatible with the EDITor.

To know which 16K BANKs Layer2 is effectively using, you have to ask the system via HEX 12 REG@ that replies with the first of three 16K BANKs. Usually this is BANK # 9 that means Layer 2 lies on Banks # 9-11, which means 8K-Pages # 18-23.

Layer2 memory is divided into 6 horizontal stripes, 8K each, and the only way to access it in vForth is to -first- map the correct 8K-page on MMU7 using MMU7! and then use addresses \$E000-\$FFFF. Each address represents one pixel which color is given based on the current Palette.

BTW, in Screen # 520 there is a nice “Colour-Picker” you can use to choose the correct byte-color to use.

Y-Coord value spans from 0 (left-side) to 255 (right-side) and always refers to the low-byte part of the address ( e.g. \$xx00 – \$xxFF ).
X-Coord value spans from 0 (top-side) to 191 (bottom-side) and must be first divided by 32 to determine which 8K stripe/page the X-Coord lies, the remainder being a number between 0 and 31 that is the pixel inside the 8K stripe.

For example, point 0,0 (top-left corner) can be addressed using ?HEX 12 MMU7! E000 C@ or C!
point 0,255 (top-right corner) can be addressed using HEX 12 MMU7! E0FF C@ or C!
point 191,0 (bottom-left corner) can be addressed using HEX 17 MMU7! FF00 C@ or C!
point 192,255 (bottom-right corner) can be addressed using HEX 17 MMU7! FFFF C@ or C!

point 100,100 is HEX 1A MMU! E464 C!

M.

• peter bierbach says:

hello, thanks for your new revision of vforth.

the pdf in there is from build 20210502

I have a new version that already includes floting.

thanks.
greeting

vForth_15e_20210916.zip

• peter bierbach says:

error in floating.

needs floating
the error :

1/2? undefined

greeting

• peter bierbach says:

i am only working with it at the moment.
to learn about special things from the next and implement them in vforth
brings great joy.

greeting

• peter bierbach says:

hello, demo for layer2 not loop correkt.
thanks
greeting

https://www.specnext.com/forum/viewtopic.php?f=13&t=2028&p=12973#p12973

• peter bierbach says:

I have the screen error again.
where does it come from?

https://www.specnext.com/forum/viewtopic.php?f=13&t=2028

thanks.
greeting

• peter bierbach says:

thank you for your great help for layer2.

how do you have to change plot and draw, so that it works in layer2 with the 255 colors. your asm-code plot and draw is unfortunately not a source code screen 43.

thanks.
greeting

• Screen# 43 uses “our old 48K Basic” ROM calls to perform PLOT and DRAW.

Layer2 PLOT is quite easy: it’s just a C! like that

: PLOT ( color x y — ) pixeladd c! ;

Layer2 DRAW has to be coded using some Line drawing algorithm

• peter bierbach says:

hello thanks for help.

greeting.

• peter bierbach says:

i found something in forth here.
unfortunately I can’t do it with my mind for the vforth.

thanks.
greeting

—————————————————
defer steep \ noop or swap
defer ystep \ 1+ or 1-

: line ( x0 y0 x1 y1 color bmp — )
{ color bmp }
rot swap
( x0 x1 y0 y1 )
2dup – abs >r
2over – abs r>
if swap 2swap swap \ ensure x1 > x0
else 2swap
then
( x0 x1 y0 y1 )
2dup >
if [‘] 1-
else [‘] 1+
then is ystep
over – abs { y deltay }
swap 2dup – dup { deltax }
2/ rot 1+ rot
( error x1+1 x0 )
do color i y steep bmp b!
deltay –
dup 0<
if y ystep to y
deltax +
then
loop
drop ;
—————————————

• peter bierbach says:

hello, good day great master.

i have already learned a lot about the vforth in connection with the spectrum next and have come a long way thanks to your help.
it was my wish to take the spurs off the nextbasic and to give the vforth what you did really well.

I think that one more hurdle was not touched: tilemap

could you imagine touching the last big hurdle in the image display in the vforth?

thanks.
greeting

• peter bierbach says:

this is a good thing you have in mind for
the vforth. I think it’s the icing on the cake
in vforth this tilemap.

a lot of success and strength for it.

thanks
greeting

• peter bierbach says:

hello, good afternoon master.
here is layer2 with floating plot.

greeting

https://www.specnext.com/forum/viewtopic.php?f=13&t=2028&p=12989#p12989

• peter bierbach says:

Hi good afternoon.
for the first time i use the built-in text editor from vforth at cspect. but do not get along with the buttons from the menu below.

how are the buttons for the menu operated by the pc?

thanks.
greeting

• EDIT is a full-screen editor that can be used to manipulate one Screen at a time. A Screen is composed by two BLOCKs.

In vForth a BLOCK is 512 bytes long and can be persistently stored inside !Blocks-64.bin file. This file is automatically opened at WARM or COLD startup and closed when quitting to Basic via BYE.

The BLOCK/Screen system can be envised as a mass-storage zone accessed one Screen at a time and, for some purposes, a virtual-memory area that can be accessed a BLOCK at a time using a BUFFER i.e a dedicated (but volatile) RAM area.

A Screen can be loaded (i.e. interpreted) using LOAD and vForth begins interpretation of Screen # and to edit a Screen I coded this peculiar or “built-in” editor.

The cursor keys, i.e. [Shift] + [5] / [6] / [7] / [8] keys, allow the flashing cursor to be moved across the screen to point the current position and text can be typed at any position in the Screen.

[Delete] key or [Shift] + [0] removes a character at current cursor position, shifting left the rest of the line.

[Break] key or [Shift] + [SPACE] inserts a space at current cursor position, shifting right the rest of the line.

 key or [Shift] + [1] enters in “command mode” and the Editor waits for a single key-stroke commands:
[ Q ] : Quit
[ H ] : Hold or take current line content and keep it in PAD
[ R ] : Replace current line with the current PAD content.
[ S ] : make Space at current cursor position shifting down lower lines; last line will be lost.
[ D ] : Delete current line shifting up lower line, but a copy is copied to PAD before deletion using H
[ I ] : Insert PAD at current line: it does commands S and R.
[ N ] : go to Next screen
[ B ] : go Back to previous screen
[ U ] : Undo, the Screen is re-read from disk ignoring any modification done since last FLUSH. This
feature is quite important, since it does for a single Screen what EMPTY-BUFFERS does for all of them.
[ P ] : accepts two hexadecimal digits representing a byte and puts it at cursor position.

Any other key has no meaning and returns the flashing cursor back to its position.

Beware, any modification immediately affects the underlying BUFFER, so if you mess things too much and  + [ U ] is not enough, there is only a way to recover it: quitting and using EMPTY-BUFFERS to erase all buffers without flushing to disk.

• peter bierbach says:

Hello, thanks for the help

the editor is very sensitive to use.

thanks.
greeting

• peter bierbach says:

hello, good day great master.

have you already achieved success with the tilemap and vforth.
I am already looking forward to reading how it works with the vforth. this tilemap is very new to me.

thanks.
greeting

• peter bierbach says:

hello , layer-scroll functions with layer21.

https://www.specnext.com/forum/viewtopic.php?f=13&t=2042

• peter bierbach says:

the layer21 scrolls in the background and with the interrupt.
the sprite can be moved in the foreground.

greeting

https://www.specnext.com/forum/viewtopic.php?f=13&t=2042&p=13031#p13031

• peter bierbach says:

https://www.specnext.com/forum/viewtopic.php?t=2043&start=10

hello master, have something new from the tilemap.
maybe you can help me there again?
works fine.

would like to load 255 chars from your own chargen.bin for example chargen from the c64 (winvice)? where do they have to be packed (memory) and how are they packed according to tile-map?

thanks.
greeting

• peter bierbach says:

hello, this tilemap runs on the cspect and on the n-go / next.
it always starts in cspect.

only when I start the n-go / next tilemap in vforth does the tilemap screen remain dark. only when I start the tm.nex from the folder c: / demos / tilemap does the vforth tilemap work.
Somehow something has to be switched in the program of the tilemap in the vforth.

thanks.
greeting

• peter bierbach says:

Hi good afternoon matteo.

vforth:
in the inc folder with “BORDER..f there is an error.

greeting

———————————
\
\ border..f
\
.( BORDER. )
\
NEEDS CALL#
\
HEX
: BORDER >>>>>>>>>>>> BORDER.
2297
CALL#
DROP
;

DECIMAL
——————————————

• peter bierbach says:

hello great master … good afternoon.

the new layer2 is no longer black and white. but blue like the border.
Is that correct?

thanks.
greeting

• peter bierbach says:

Hello….
the sprite no longer goes into the tilemap window but remains in the area of layer2, when it leaves layer2 it is no longer visible in the visible area.

greeting

• Have you modified some clipping window ? There are registers that allows you clip each layer individually.
For the colors, yes the first Basic loader changes to yellow-on-blue every Layer.

• peter bierbach says:

thanks for new vforth.

your new vforth and tilemap now works with it:
7 21 reg!

this ist now with new vforth ok :
—————————–
only when I start the n-go / next tilemap in vforth does the tilemap screen remain dark. only when I start the tm.nex from the folder c: / demos / tilemap does the vforth tilemap work.
Somehow something has to be switched in the program of the tilemap in the vforth.
—————————-

greeting

• peter bierbach says:

Hi good afternoon.
was on vacation for 8 days.
now it continues with vforth.
greeting

• peter bierbach says:

hello, error: