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.

 

100 Comments

  • peter bierbach says:

    Hi good afternoon.

    next vforth :
    why are only about 4800 bytes free when loading the image ?

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

    layer11
    : DATEN-LOAD< ( — )
    OPEN< >R

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

    DATEN-LOAD< ../../fth/bild.scr

    : 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
    113 of links 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 :
      600 LOAD
      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
    ;
    ————————-

  • peter bierbach says:

    —————–
    600-670: you can just give :
    600 LOAD
    ——————
    thank you, I had read that 10 times.
    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 ” .
      So your phrase should be
      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 113 of links 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_read $01 request read access
      \ esx_mode_write $02 request write access
      \ esx_mode_use_header $40 read/write +3DOS header
      \ 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.
    loading an image also works great
    your program

    greeting

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

    220 load
    down

    layer11

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

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

    : los
    100 mmu7!
    DATEN-FILE COUNT TYPE DATEN-FILE load-bild

    [ 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:

    Hello, thanks for your help.
    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.
    can you please help
    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

    create sinustabelle \ 0…90 Grad, Index in Grad
    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

    include /fth/spriteload3.f
    SPRITE-LOADr
    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

  • peter bierbach says:

    hello thanks for info for cursor.

    greeting

  • peter bierbach says:

    hello, good afternoon vforth fachman.

    I also read something about float in the vforth.
    but unfortunately I can’t find a demo that I understand.

    can you please help?
    thanks.
    greeting

  • peter bierbach says:

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

    thank you for your work for this float.

    another question about the flash.
    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 found your newest version vforth with
    float. thank you for your service.
    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

  • peter bierbach says:

    my demo :

    ———————————
    needs floating
    : los
    12.0 2.5 * F.
    2.0 FSQRT F.
    30.0 DEG>RAD FSIN 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.
    30.0 DEG>RAD FSIN F.
    INTEGER ;

    los 0.0000E0 4,4721E0 -0.8660E0 ok

    thanks
    greeting

    this :
    https://github.com/mattsteeldue/vforth-next

    and this
    https://github.com/mattsteeldue/vforth-next/tree/master/download

  • 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* ;

    30.0 deg>rad fsin
    f. 0.5000E0 ok

  • peter bierbach says:

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

    greeting

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

    thank you for your help.

    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

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

    thank you for your help.
    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.
    you had made a suggestion how the cursor can be made invisible.
    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 load it with include that it works?

    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:

    yes i like your vforth.
    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.

    thank you for your help.

    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

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

      [Edit] 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 [Edit] + [ 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:

    Hello, thanks for your help.
    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.

      I haven’t checked in for a long time.

      how can you create a tilemap in the vforth for the next?

      Thanks.
      greeting

  • peter bierbach says:

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

  • peter bierbach says:

    hello, error:

    forth15g.bin not found

    greeting

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.