ZX-IDE Tutorial for programming assembler and ZX BASIC

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX81 BASIC, _hide

Post by PokeMon »

So the last directive for now is _hide.
With hide you can hide a line or a full program or numeric parameters. The classic variant is the use with a REM line:

Code: Select all

            REM _hide _asm
    printch:
            LD  A,,'Z'
            RST $10
            LD  A,,'X'
            RST $10
            LD  A,,'8'
            RST $10
            LD  A,,'1'
            RST $10
            RET
    error:
            RST 8
            db  $0A
            END _asm

            RAND USR  #error
    AUTORUN:
            RAND USR  #printch
If you check the listing, there is simply a NEWLINE $FF used as the first REM parameters.

Code: Select all

    0074: [407D] 00 0A 13 00 EA 76 FF               REM _hide _asm
                                            printch:
    007B: [4084] 3E 3F                              LD  A,,'Z'
    007D: [4086] D7                                 RST $10
    007E: [4087] 3E 3D                              LD  A,,'X'
    0080: [4089] D7                                 RST $10
    0081: [408A] 3E 24                              LD  A,,'8'
    0083: [408C] D7                                 RST $10
    0084: [408D] 3E 1D                              LD  A,,'1'
    0086: [408F] D7                                 RST $10
    0087: [4090] C9                                 RET
                                            error:
    0088: [4091] CF                                 RST 8
    0089: [4092] 0A                                 db  $0A
    008A: [4093] 76                                 END _asm
                                           
    008B: [4094] 00 14 0E 00 F9 D4 1D 22            RAND USR  #error
                 21 1E 25 7E 8F 01 22 00   
                 00 76                     
                                            AUTORUN:
    009D: [40A6] 00 1E 0E 00 F9 D4 1D 22            RAND USR  #printch
                 21 1D 22 7E 8F 01 08 00   
                 00 76                     
So the disadvantage is the additional offset of 2 bytes if you use RAND USR with a line number (RAND USR #10#). This could be avoided with definition of explicit labels. Maybe in a future release this will be handled more efficient. If you enter LIST, the listing will be stopped after the first line (10 REM ...). Anyway the unreadable REM assembler content will be stopped to display and with _noedit it can not be touched any more. This can be bypassed with another line number and LIST, for example LIST 11 for list of the rest of the program.

Optical nicer is to use the code for REM in the last BASIC line because the code start address will be determined anyway automatically. Here the concept of no explicit use of line numbers is an advantage to move BASIC lines simply in the editor.

Code: Select all

            RAND USR  #error
    AUTORUN:
            RAND USR  #printch

            REM '(C) by PokeMon'

            REM _hide _asm
    printch:
            LD  A,,'Z'
            RST $10
            LD  A,,'X'
            RST $10
            LD  A,,'8'
            RST $10
            LD  A,,'1'
            RST $10
            RET
    error:
            RST 8
            db  $0A
            END _asm
EMU9a.jpg
EMU9a.jpg (25.52 KiB) Viewed 12099 times
With _hide you can hide more elements, for example any numeric value. So the display of the starting address of any assembly code can be manipulated. Background is the double use of a numeric value and a string to display with a numeric value.

Code: Select all

            RAND USR  #error
    AUTORUN:
            RAND USR  _hide #printch

Code: Select all

    0074: [407D] 00 0A 0E 00 F9 D4 1D 22            RAND USR  #error
                 21 24 1D 7E 8F 01 8A 00   
                 00 76                     
                                            AUTORUN:
    0086: [408F] 00 14 0A 00 F9 D4 1C 7E            RAND USR  _hide #printch
                 8F 01 70 00 00 76         
If you dismantle the second statement you will find:
2 byte line number big endian ($14=20)
2 byte line length little endian ($0A=10)
1 byte BASIC command RAND ($F9)
1 byte BASIC function USR ($D4)
1 byte string ($1C='0')
1 integer identifier ($7E)
5 byte integer ($8F,$01,$70,$00,$00 = 16572)
1 byte end character (NEWLINE) ($76)

This will look live like this:
EMU9b.jpg
EMU9b.jpg (23.87 KiB) Viewed 12099 times
So this was part 1 of ZX BASIC.
Last edited by PokeMon on Sun Sep 08, 2013 10:59 pm, edited 1 time in total.
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX emulator EightyOne - hints for using

Post by PokeMon »

In the last time I had some trouble using the emulator because some options have been changed manually for testing other things. The emulator is started with hotkey F8 but the program did not start/load. So have the following hints to check if emulator is not working as expected.

First the hardware has to be configured. If the emulator hangs after start with wrong options it could be reset via control menu. The setting can be changed with F6 (options->hardware) and the main setting is the target system ZX80 or ZX81 but also the hardware options to use (available memory and other options like sound, graphics). You should check the loaded ROM image via advanced settings, too. Maybe someone tried out another os. ;) The hardware settings will be changed immediately and saved for the next start. If you change between systems ZX80 and ZX81 you should keep an eye on it.

The available memory should correspond with your setting MEMAVL in the ZX-IDE. As used in the sample program ZX81DEMO.ASM the ZX-IDE can check automatically if the program fits into available memory and break with a message if doesn't fit. The directive assert checks if a logic expression is true or lets say assures that the given condition is met. assert can be used in source for other conditions as well as many time as needed. ;)

Code: Select all

        MEMAVL     =       MEM_1K          ; can be MEM_1K, MEM_2K, MEM_4K,
...
...
...
      assert ($-MEMST)<MEMAVL ; (letzte Zeile im Programm)
emu00.gif
emu00.gif (96.06 KiB) Viewed 12073 times
The second important setup is the tape manager. To load and start the compiled program automatically, the option "auto load on insert" has to be set "tools->tape manager" (CTRL-F9). To load the program faster, the flash loader can be activated.
emu01.gif
emu01.gif (103.07 KiB) Viewed 12073 times
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX80 BASIC, line numbers, REM, _asm

Post by PokeMon »

The ZX-IDE has a sample program ZX80DEMO.ASM in the main directory. The most important line is the first one which configures the IDE for the target system ZX81 or ZX80. And you have to assure to include the correct include files ZX80.INC or ZX81.INC and ZX80POST.INC or ZX81POST.INC.

Code: Select all

format zx80
;labelusenumeric
;LISTOFF
        ; hardware options to be set and change defaults in ZX81DEF.INC
        MEMAVL     =       MEM_1K          ; can be MEM_1K, MEM_2K, MEM_4K,
                                           ; default value is MEM_1K

        include 'SINCL-ZX\ZX80.INC'           ; definitions of constants
;LISTON
10    REM
        include 'SINCL-ZX\ZX80POST.INC'          ; include D_FILE and needed memory areas

assert ($-MEMST)<MEMAVL
; end of program
In the background there is another memory structure used, the ZX80 has less system variables, another output format and a partly different charset.
The format zx80 will create a .o file (instead of the .p file for the ZX81) with correct memory structure. Another difference is the audio transfer with LOAD and SAVE. The ZX80 doesn't know a program name to store or selective load.

The following screenshot shows the sample ZX80DEMO.ASM (assembled, in fact the ZX80DEMO.o).
clip1.gif
clip1.gif (98.06 KiB) Viewed 12074 times
Line numbers have nearly the same options and restrictions as for the ZX81. You can enter manually line numbers from 1 to 9999. Line numbers > 9999 can also be used when program is created with the ZX-IDE and not entered manually (up to 16383). This is tricky and line numbers > 9999 are not displayed correctly, only the last three digits. The first digit is 0-9 normally and A-G for 10000-16000. 16383 will be G383. All line numbers will be displayed correctly in the listing (only first char can be strange) and are executed. They can be used with RUN and GO TO with the decimal version (RUN 16000 works). Line numbers > 9999 are displayed but can not be changed from BASIC (EDIT doesn't work on these lines). They can be used for some hints, copyright notices or something else.
Clipboard11a.gif
Clipboard11a.gif (98.28 KiB) Viewed 12074 times
The rest is identical to ZX81. Line numbers can be used but are not necessary as lines will be numbered automatically from the ZX-IDE. The stepwidth for line numbers can be changed with AUTOLINE <value> (default is 10). Automatically and manually assigned line numbers can be mixed as you like but you have to assure an ascending order otherwise the IDE will stop assembling with an error message.

Here the complete program to the listing of the first added image to compare the corresponding line numbers:

Code: Select all

10      REM NUR EIN KLEINES TESTPROGRAMM
20      REM 123456789
30      REM INPUT=START-ENDE
40      REM '(C) by PokeMon'
50      REM

        AUTOLINE 100

        REM _asm
        dbzx 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        dbzx 'abcdefghijklmnopqrstuvwxyz'
        dbzx ' "$:?(.)><=+-*/;,.'''
        END _asm
        REM

        RAND USR(#lab_1000)
        REM

9999    REM noch editierbar
10000   REM nicht mehr editierbar
10001   REM 'ideal f. (C)opyright'

16000   REM _asm
        db $76,$76
lab_1000:
        LD A,-1
        RET
label1  db $10
        dbzx 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        dbzx 'abcdefghijklmnopqrstuvwxyz'
        dbzx ' "$:?(.)><=+-*/;,.'''
        END _asm
Assembler codeblocks can be used simply in similar way as for the ZX81 in REM lines. But the internal data format is different, the ZX80 has no information about the lenght of a line. A line ends simply with $76 (NEWLINE). Printable/displayable characters like in line 150 as data is not complicate to use but pure assembler programs or binary data can cause some problem when the ZX80 suppose the beginning of a new line while reading data.

But there are options to define lines which will be not displayed in a listing to avoid confusing or crashing the ZX80. Line 16000 in the listing above is a sample:

Code: Select all

16000   REM _asm
        db $76,$76
lab_1000:
        LD A,-1
        RET
label1  db $10
        dbzx 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        dbzx 'abcdefghijklmnopqrstuvwxyz'
        dbzx ' "$:?(.)><=+-*/;,.'''
        END _asm
The assembler block will be initiated with REM _asm and ends with marker END _asm. The first two bytes $76 (NEWLINE) will stop the listing. The first NEWLINE is interpreted as end of REM line and the second will be interpreted as the high part of the following line number and stop the listing. In fact all line numbers >= $40 stop the listing.

The ZX80 will list the line as REM but without data. But more lines can follow this line (e.g. more assembler blocks) but the following lines will not be shown nor will be executed as BASIC. So it is a good idea to put all assembler blocks at the end of a BASIC program. The ZX80 shows the last line number as executed but in fact it will be not exectued. Anyway you can place assembler code there and start with RANDOMISE USR(..) which have to be placed in the viewing part of the listing. ;)
Last edited by PokeMon on Sun Sep 08, 2013 11:04 pm, edited 1 time in total.
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX80 BASIC, RAND, RANDOMISE, USR, labels

Post by PokeMon »

The ZX80 has keywords which appear comlete when pressing a simple key but no function mode (F cursor). So all functions have to be entered in manual characters and the argument in brackets. Functions like CHR$(..) or USR(..) have to be entered letter by letter. ;)

Assembler programs are started with the keyword RAND(OMISE) in conjunction with function USR(..). In the ZX-IDE you can enter either the short form RAND or the long form RANDOMISE. The argument of USR(..) is simply the address of the code to be started. The return value can not be processed very good with RANDOMISE in comparison with assignment of a variable like LET A=USR(..) but this statement is not implemented yet.

There are 3 methods to bind an address to RAND(OMISE) and start the program:

Code: Select all

    10      REM NUR EIN KLEINES TESTPROGRAMM

            AUTOLINE 100

            RAND USR 8
            RAND USR(#lab_1000)
            RAND USR #16100#
            REM

    10001   REM '(C)opyright PokeMon'

    16000   REM _asm
            db $76,$76
    lab_1000:
            LD A,-1
            RET
    label1  db $10
            END _asm

    16100   REM _asm
            LD B,5
            ADD A,B
            RET
            END _asm

            include 'SINCL-ZX\ZX80POST.INC'          ; include D_FILE and needed memory areas
In the emulator it looks like this:
clip2.gif
clip2.gif (95.01 KiB) Viewed 12063 times
There are three different call methods of USR in the source. The first one calls directly the given address, RAND USR(8) jumps to the routine for printing error codes. The second example attaches a label to the USR call and takes the address of the label. Labels are in general only names for addresses which can not be remembered very good. :mrgreen: The label print_stack is more easy to remember than its value for example 17238. Labels are placed directly in front of an assembler instruction. In the example above USR(#lab_1000) jumps directly to the assembler instruction LD A,-1.

The last alternative ist the BASIC line number as parameter for the function USR. RAND USR #16100# will directly call the first assembler statement in the attached block of the REM BASIC line. An additional label is obsolete, the line number is like a label. The offset of 3 bytes for 2 digits line number and one byte for instruction is calculated automatically. The listing is ended in line 16000 with a sequence of two directly following $76 (NEWLINE), so this is not necessary for following assembler blocks like in line 16100. RAND USR #16000# would start with the two HALT instructions ($76), so an explicit label is necessary.

This is the listing (CTRL-F8 in ZX-IDE to create listing):

Code: Select all

0028: [4028] 00 0A FE 33 3A 37 00 2A    10      REM NUR EIN KLEINES TESTPROGRAMM
             2E 33 00 30 31 2A 2E 33   
             2A 38 00 39 2A 38 39 35   
             37 34 2C 37 26 32 32 76   
                                       
                                                AUTOLINE 100
                                       
0048: [4048] 00 6E EF 3A 38 37 DA 24            RAND USR 8
             D9 76                     
0052: [4052] 00 D2 EF 3A 38 37 DA 1D            RAND USR(#lab_1000)
             22 21 1E 22 D9 76         
0060: [4060] 01 36 EF 3A 38 37 DA 1D            RAND USR #16100#
             22 21 1F 20 D9 76          
You can read the corresponding start address of the 3 RAND USR statements in the listing. Brackets are optional the ZX-IDE creates them automatically ($DA ... $D9). The value follows in ASCII characters, an additional floating point notation is not available for the ZX80. $24 is the digit 8 and is parameter of the first RAND USR statement.

The label has $1D $22 $21 $1E $22 = 16526 (dezimal) = $408E (hexadezimal). At this address you can find LD A,-1 instruction or the label lab_1000.

The third method is the BASIC line number as parameter (double '#' is used for distinct the line number from the address 16100). $1D $22 $21 $1F $20 = 16534 = $4096. At this address the first assembly instruction LD B,5 is found.
Last edited by PokeMon on Sun Sep 08, 2013 11:11 pm, edited 1 time in total.
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX80 BASIC AUTORUN, _noedit, _hide

Post by PokeMon »

Now the last 3 statements for now. The first one AUTORUN is explained quickly, the ZX80 doesn't support auto starting programs after loading.

_noedit is an option for a BASIC line and can be used after a statement like REM or RAND(OMISE). The line number will be set to 0 and is no more editable. But a line number with 0 can not be executed directly. _noedit should be used carefully only in the beginning or ending part of a program. A mix between conventional line numbers and 0 can crash the ZX80. An alternative for the last program lines is to use line numbers > 9999 which are also no editable.

Code: Select all

    10      REM _noedit NUR EIN KLEINES TESTPROGRAMM

            AUTOLINE 100

            RAND _noedit USR 8
            RAND USR(#lab_1000)
            RAND _noedit USR #16100#
            REM

    10001   REM '(C)opyright PokeMon'

    16000   REM _hide _asm
    lab_1000:
            LD A,-1
            RET
    label1  db $10
            END _asm
clip3.gif
clip3.gif (95.37 KiB) Viewed 12064 times
_hide should be used carefully in same way. The line will be hidden but all following lines too. Hidden lines can be used for assembler programs only, the lines can not be displayed and can not be executed in BASIC context. But a simple line REM _hide can be used to hide all following assembler blocks very easy. In fact _hide does include a NEWLINE ($76) followed by $FF (same as for ZX81). In the previous posting you could use 15999 REM _hide to make labels obsolete for following code blocks.

Code: Select all

        AUTOLINE 100

        RAND USR 8
        RAND USR(#lab_1000)
        RAND USR #16100#
        REM

10001   REM '(C)opyright PokeMon'

15999   REM _hide
16000   REM _asm
lab_1000:
        LD A,-1
        RET
label1  db $10
        END _asm

16100   REM _asm
        LD B,5
        ADD A,B
        RET
        END _asm

_hide is not useful for parameter values since those will be stored as ASCII sequence only and not additional as floating point value like the ZX81.
Last edited by PokeMon on Sun Sep 08, 2013 11:12 pm, edited 1 time in total.
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX81 - different context of ZX BASIC and Assembly

Post by PokeMon »

Support of both Assembler and BASIC in one program source needs separation of the very different BASIC and Assembly contexts. I want to show what I mean with the following example:

Code: Select all

    10      REM TESTPROGRAMM;

    20      REM _asm
    LAB1:
            LD BC,0
            RET
    LAB2:
            LD BC,1
            RET
            END _asm

    30      PRINT USR LAB1
    40      PRINT "PROGRAMMLAENGE:" LAB2-LAB1
Line 30 shows an ambiguous declaration. LAB1 can be the address of LAB1 (a label) but could be just as well a BASIC variable. As there are BASIC variables a legal parameter for BASIC statements there is a distinction necessary between BASIC and Assembly or more detailed between BASIC variables and Assembly addresses or expressions. As we won't touch the typical writing of BASIC statements the labels or expressions from Assembly context are marked with the character '#' in front. This is already known from RAND statement with a line number (RAND 10 versus RAND #10). See following listing to be more clear:
ZX81BASIC1.gif
ZX81BASIC1.gif (100.3 KiB) Viewed 11997 times

Code: Select all

    10      REM TESTPROGRAMM;

    20      REM _asm
    LAB1:
            LD BC,0
            RET
    LAB2:
            LD BC,1
            RET
            END _asm

    30      PRINT USR #LAB1
    40      PRINT "PROGRAMMLAENGE:",#LAB2-LAB1
In this listing LAB1 is declared as an Assembly variable and will be resolved during Assembly and replaced with the resulting address of the label. The expression LAB2-LAB1 in line 40 will be evaluated too and the resulting number will be replaced in the PRINT statement. See following listing:
ZX81BASIC2.gif
ZX81BASIC2.gif (100.79 KiB) Viewed 11997 times
As soon as expressions can be resolved partly in BASIC and partly in Assembly you can place the '#' character inside of an expression and use brackets as well like in line 50. In other case the complete expression would be resolved like in the above example.

Code: Select all

    10      REM TESTPROGRAMM;

    20      REM _asm
    LAB1:
            LD BC,0
            RET
    LAB2:
            LD BC,1
            RET
            END _asm

    30      PRINT USR #LAB1
    40      PRINT "PROGRAMMLAENGE:",LAB2-#LAB1
    50      PRINT "PROGRAMMLAENGE:",(#LAB2)-LAB1
So does it look like in the emulator:
ZX81BASIC3.gif
ZX81BASIC3.gif (100.94 KiB) Viewed 11997 times
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

Re: ZX81 - different context of ZX BASIC and Assembly

Post by PokeMon »

Parameter for RAND can be used a numeric value either directly or with '#'. In both cases the numeric value will be translated from ASCII to the ZX81 internal numeric floating point format. Due to this reason the offset of 5 (line number + line length + REM statement) can not be calculated anymore automatically. Otherwise the offset would be used when calling internal ROM functions or during evaluation of numerical expressions. This can be solved by using the '#' double at the beginning and at the end of the value:

Code: Select all

    10      REM _asm
    LAB1:
            LD BC,0
            RET
    LAB2:
            LD BC,1
            RET
            END _asm

    20      PRINT USR #10
    30      PRINT USR #10#
ZX81BASIC4.gif
ZX81BASIC4.gif (99.86 KiB) Viewed 11977 times
Line 20 refers simply to the numerical value 10 (could be a more complicate expression evaluation as well), the double '#' in line 30 refers to the BASIC line number 10 and not to the numerical value 10 (assuming it is a REM line with following code) and determines the start address. It is not a must to define a separate label for it. On the other hand it is recommendable to work with explicit labels as this is more unique.

There is a reason why this is described so detailed:

The use of lines and labels has changed in comparison to earlier IDE versions:
previously usage:
RAND USR #10 => execute code in REM-line 10
RAND USR label => execute code at address label
New:
RAND USR #10 => jump to address 10
RAND USR #10# => execute code in REM line 10
RAND USR label => use label as BASIC variable
RAND USR #label => use label as code address
GOTO #label# => replace label with the line number of label or the following BASIC line after this label
More simplified you can use the following rule:
#label after a BASIC statement refers to the assembly context - without '#' label will be interpreted as BASIC variable

#10*10 refers to assembly context, too and evaluate the given expression which can be numbers, labels or constants

#label# will be replaced with the line number of label or following to label - this way you can omit line numbers completely and use together with GOTO and other statements.

#100# will be replaced with the address of line 100 plus an additional offest of 5 (when using assembly blocks in REM statements)
If you did already use ZX-IDE before you maybe have to modify old sources if they should run with ZX-IDE. I know that this is unluckily but this is now the price for using BASIC together with assembly in one source file. I modified the tutorials before in that point.

There is a second important change regarding comments due to BASIC support in the source file. Previously comments started with a semicolon ';' and the rest of the line is ignored and displayed in grey color in the editor. But the semicolon ';' is needed in conjunction with the PRINT statement and concatenation ofr strings and used quite often in BASIC programs. For this reason I had to change the start sign for use of comments and used the double slash '//' like the C++ style. So the rest of the line will be ignored and handled as comment. The use of double slash '//' inside of strings is allowed like in the following example:

Code: Select all

    10      REM TESTPROGRAMM;

    20      REM _asm
    LAB1:
            LD BC,0
            RET
    LAB2:
            LD BC,1   ; weiterhin zulässiger Kommentar aber nicht sichtbar :-(
            RET       // richtiger Kommentar
            END _asm

    30      PRINT USR #LAB1 ; kein Kommentar
    40      PRINT "PROGRAMMLAENGE:";#LAB2-LAB1 // richtiger Kommentar
    50      PRINT ABC;"//"
It looks like this in the emulator:
ZX81BASIC5.gif
ZX81BASIC5.gif (100.74 KiB) Viewed 11977 times
The use of ';' as comment for pure assembly line is still possible but no more for line with BASIC statements because ';' could be part of a BASIC statement / parameters. But the old comment style is not marked anymore in grey color in the editor as the editor doesn't know something about assembly or BASIC context. Maybe this feature will be supported in future. The new comment style '//Ä is marked in the editor in grey color. So this way old assembly sources did not need to be changed as the comment will be recognized during compilation of assembly lines.

I hope there are no more changes necessary in future. :wink:
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX81 PRINT, number formats , calculations

Post by PokeMon »

An important statement (PRINT) and the floating point format and the support of calculations has been implemented now for the ZX81. Now it is impossible to do calculations in BASIC. ;) The chapters 2 up to 5 of the ZX81 BASIC programming manual have been implemented completely. More statements will be supported soon.

Code: Select all

    10      REM PRINT UND GANZE ZAHLEN

            PRINT 2+3
            PRINT 2-3
            PRINT 2*3
            PRINT 3/2
            PRINT 2**3
            PRINT 20-2*3**2+4/2*3
            PRINT 20-2*3**2+4/2*3
            PRINT 3*2+2
            PRINT 3*(2+2)
            PRINT #3*2+2
All numbers will be converted to ZX81 floating point format automatically. The calculations will be done from the ZX81 in the order of the operator precedence of the ZX81. Brackets can be used as needed like in the line 100. Line numbers are optional as the line numbers can be assigned automatically with the AUTOLINE step width. The last line 110 will be calculated from the ZX-IDE and not from ZX81 as it is marked with the '#'. So this way it is not really assembly context. ;)
ZX81BASIC6.gif
ZX81BASIC6.gif (101.49 KiB) Viewed 11979 times
The next example uses floating point values. Internally there is no difference as every numeric value will be converted and interpreted as floating point value, even for simple GOTO statements or similar. The advantage is to use calculations of line numbers as well but it is quite slow in execution and wasting memory for programs with numeric values.

Code: Select all

    10      REM PRINT UND GLEITKOMMAZAHLEN

            PRINT 2.34
            PRINT 2.34E0
            PRINT 2.34E2
            PRINT 234
            PRINT 2.34E3
            PRINT 2.34E-2
            PRINT 1,2,,3,4
            PRINT 1;2;3;4
            PRINT 5E9-5E9+1
            PRINT 1234567890
"Real" floating point values are converted through the IDE in a different way but this doesn't matter here. The mantissa is marked with the decimal point '.' for decimal places and the exponent is given with the character 'E'. There is no difference if 234 is defined with "234" or with 2.34E2. The resulting number is stored in same binary way like in the following example with mantissa bytes 6A 00 00 00 and exponent 88 (internal floating point format of ZX81). See following listing:

Code: Select all

    00B0: [40B9] 00 28 0E 00 F5 1E 1B 1F            PRINT 2.34E2
                 20 2A 1E 7E 88 6A 00 00   
                 00 76                     
    00C2: [40CB] 00 32 0B 00 F5 1E 1F 20            PRINT 234
                 7E 88 6A 00 00 00 76       
and in the emulator:
ZX81BASIC7.gif
ZX81BASIC7.gif (97.27 KiB) Viewed 11979 times
When executing the program the result is a bit surprising. The number 1234567890 is printed as 1234567900 due to rounding when printing. It is possible to use more than just one value with a PRINT statement and separate them with either colon ',' or semicolon ';'. With semicolon the numbers are printed directly after each other and with comma they will be printed using (fixed) tabulators.
ZX81BASIC8.gif
ZX81BASIC8.gif (101.64 KiB) Viewed 11979 times
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX81 mathematics and functions

Post by PokeMon »

All mathematic are supported now as well.
Following functions are available:
ABS (Absolutwert)
ACS (Arc-Cosinus)
ASN (Arc-Sinus)
ATN (Arc-Tangens)
COS (Cosinus)
EXP (Exponential)
INT (Ganzzahl)
LN (Logarithmus)
PI (Konstante Pi)
RND (Zufallszahl)
SGN (Vorzeichen)
SIN (Sinus)
SQR (Quadratwurzel)
TAN (Tangens)
Here a sample program of chapter 5 with different functions:

Code: Select all

    10      REM PRINT UND FUNKTIONEN

            PRINT SQR 9
            PRINT SQR 2 * SQR 2
            PRINT SQR (2*2)
            RAND 1
            PRINT RND
            RAND 0
            PRINT RND
            PRINT LN 2/LN 10
            PRINT TAN(45/180*PI)
            PRINT INT (RND*6)+1
            PRINT INT(2.9+0.5)
            PRINT INT(2.4+0.5)
            PRINT PI-3.1415
ZX81BASIC9.gif
ZX81BASIC9.gif (102.53 KiB) Viewed 11981 times
And here the result of the calculations:
ZX81BASIC10.gif
ZX81BASIC10.gif (95.99 KiB) Viewed 11981 times
The last line 140 shows that the internal resolution of PI is better than shown with PRINT statement (rounded when printed). :wink:
User avatar
PokeMon
Posts: 2264
Joined: Sat Sep 17, 2011 6:48 pm

ZX81 startup variables

Post by PokeMon »

There is a small change and extension regarding the startup variables:

MEMAVL = available memory for the program - this has no effect on the compiled code and will be checked only internal (code size).
STARTMODE = can be either SLOW_MODE or FAST_MODE, ZX81 starts up in this mode (SLOW or FAST) after loading.
DFILETYPE = can be now COLLAPSED, EXPANDED or AUTO. If MEMAVL > 3k option AUTO chooses EXPANDED, otherwise COLLAPSED automatically.
AUTORUN = no change, has to be placed as label in front of the line to start with. No autorun if placed after the last line or not placed at all.

Code: Select all

    format zx81
    ;labelusenumeric
    ;LISTOFF

            // hardware options to be set and change defaults in ZX81DEF.INC
            MEMAVL     =       MEM_16K         // can be MEM_1K, MEM_2K, MEM_4K, MEM_8K, MEM_16K, MEM_32K, MEM_48K
                                               // default value is MEM_16K
            STARTMODE  EQU     SLOW_MODE       // SLOW_MODE or FAST_MODE
            DFILETYPE  EQU     AUTO            // COLLAPSED or EXPANDED or AUTO
            STARTUPMSG EQU    'CREATED WITH ZX81-IDE' // any message will be shown on screen after loading, max. 32 chars

            include 'SINCL-ZX\ZX81.INC'        // definitions of constants
    ;LISTON
    10      REM NUR SO ...

            include 'SINCL-ZX\ZX81POST.INC'          ; include D_FILE and needed memory areas
Post Reply