
Since the ZX81 uses the powerful Z80 microprocessor, it is a good system for which to write machine code programs. In the past months while writing many programs, I have found that there is one feature lacking on the system: a machine language monitor.
A machine language monitor is a utility, provided by most computer systems, which aids in the development of machine language programs. Its basic functions are: a) to allow you to view the contents of each byte in the system’s memory, and b) to allow you to change these values.
The program provided here will allow you to perform these functions. It is a visual window into the system’s memory, hence the name. In addition, it is a program which illustrates the programming litany: a program should contain very few constants intermixed with its code.
Looking at the program, you will see that the first few score of lines are all assignment statements (LETs). All arbitrary constants are specified in this section of the program. All references to these values later in the program are, then, symbolic, making the code easier to read.
Another benefit of coding the program this way is the ease of modification it provides. For example, you can change the line on the screen on which the ‘window’ begins by modifying the value of the variable PRITOP (PRImary screen TOP). Most of the visual arrangement can be changed by changing the value in one or two LET statements.
The commands for WINDOW are:
- K- The K key (+) is used to move to the next memory location.
- J- The J key (-) is used to move to the previous memory location.
- G- The G key (GOTO) is used to move the current location to wherever you choose. The system will ask you for an address in hex.
- P- The P key (PRINT) is used to list out the contents of 10 memory locations, in hex and as characters. The PRINT starts at the current location and, when done, sets the current location equal to the next location.
- D- The D key (DISPLAY) is used to print out 5 lines of characters which are the characters in memory, from the current location on.
- Q- The Q key (QUIT) is used to exit the WINDOW program. It will leave you in FAST mode. You can re-enter the program with CONTinue.
- C- The C key (CALL) is used to call a machine language routine. Its address is specified by the current location address.
- O- The O key (OPEN) is used to change the contents of the current location. The system will prompt you for a 2-digit hex value. The system will then increment the current location pointer.
Ed.—For those who do not want to do the work of entering the program, but who do want to enjoy its benefits, it can be obtained on cassette from Heuristics, 25 Shute Path, Newton, MA 02159 for $8.00.)
█ = inverse space; [inv …] = inverse text.
1 REM 123456789012345678901..
.........
2 REM WINDOW
COPYRIGHT (C), 1981
BY:
HEURISTICS
ANY COPY OF THIS
PROGRAM, PRINTED
OR MACHINE-READABLE,
MUST INCLUDE THIS
COPYRIGHT NOTICE.
5 SLOW
10 LET HEX16=2000
12 LET DISP=1000
14 LET SPLITBYTE=2100
16 LET INVERSE=2200
18 LET HEX8=2300
20 LET GETKEY=2400
22 LET C$="GKJDQPCO"
24 LET INPUT=2500
26 LET DEC16=2600
28 LET AD=16514
30 LET VALX=15
32 LET CLRSEC=2700
34 LET DEC8=2800
36 LET CLRPMT=2900
40 LET LPD=22
42 LET PMTY=LPD-1
44 LET PRITOP=1
46 LET PRIBOT=5
48 LET SECTOP=PRIBOT+1
50 LET SECBOT=PMTY-1
52 LET SECSIZ=SECBOT-SECTOP+1
54 LET NUM=28
56 LET FLY=PRITOP+(PRIBOT-PRIT
OP)/2
58 LET FLV=6
60 LET INVERT=128
62 LET ADX=7
64 LET MAXADDR=65535
66 LET MINADDR=0
68 LET FLX=30
70 LET CURY=16442
72 LET LPP=SECSIZ
74 LET CHARX=20
76 LET DL=SECSIZ
78 LET MAIN=100
80 LET MAIN2=130
82 LET DISP2=1040
84 LET DISP3=1080
100 REM MAIN
120 GOSUB DISP
130 GOSUB GETKEY
132 PRINT AT FLY,FLX;"█"
135 IF Z=5 THEN GOTO 150
137 IF Z>5 THEN LET Z=Z-1
140 GOTO 3000+(Z-1)*1000
150 FAST
155 STOP
157 SLOW
160 GOTO MAIN
1000 REM DISPLAY
1010 FOR V=PRITOP TO PRIBOT
1020 PRINT AT V,0;"[inverse spaces, count illegible]
"
1030 NEXT V
1040 PRINT AT FLY,1;"[inv ADDR ]";
1045 LET Z=AD
1050 GOSUB HEX16
1070 PRINT AT FLY,ADX;Z$;
1080 PRINT AT FLY,VALX;
1090 LET Z1=PEEK AD
1100 GOSUB HEX8
1110 PRINT Z$
1120 RETURN
2000 REM HEX16
2010 LET Z1=INT (Z/256)
2020 LET Z2=Z-Z1*256
2030 GOSUB SPLITBYTE
2040 LET Z$=CHR$ (Z8+NUM)+CHR$ (
Z9+NUM)
2050 LET Z1=Z2
2060 GOSUB SPLITBYTE
2070 LET Z$=Z$+CHR$ (Z8+NUM)+CHR
$ (Z9+NUM)
2080 RETURN
2100 REM SPLITBYTE
2110 LET Z8=INT (Z1/16)
2120 LET Z9=Z1-Z8*16
2130 RETURN
2200 REM INVERSE
2210 FOR Z=1 TO LEN Z$
2220 LET Z$(Z)=CHR$ (CODE Z$(Z)+
INVERT)
2230 NEXT Z
2240 RETURN
2300 REM HEX8
2310 GOSUB SPLITBYTE
2320 LET Z$=CHR$ (Z8+NUM)+CHR$ (
Z9+NUM)
2330 RETURN
2400 REM GETKEY
2405 LET CB=FLV
2410 LET Z$=INKEY$
2415 PRINT AT FLY,FLX;CHR$ CB;
2417 GOSUB 2470
2420 IF Z$="" THEN GOTO 2410
2430 FOR Z=1 TO LEN C$
2440 IF Z$=C$(Z) THEN RETURN
2450 NEXT Z
2460 GOTO 2410
2470 IF CB=FLV+INVERT THEN GOTO
2490
2475 LET CB=CB+INVERT
2480 RETURN
2490 LET CB=CB-INVERT
2495 RETURN
2500 REM INPUT
2510 INPUT Z$
2520 RETURN
2600 REM DEC16
2610 LET Z$="0000"(1 TO 4-LEN Z$
)+Z$
2620 LET Z=0
2630 FOR G=1 TO 4
2640 LET Z=Z*16
2650 LET Z=Z+CODE Z$(G)-NUM
2660 NEXT G
2670 RETURN
2700 REM CLRSEC
2710 FOR B=SECTOP TO SECBOT+1
2720 PRINT AT B,0;" "
2730 NEXT B
2740 PRINT AT SECTOP,0;
2750 RETURN
2800 LET Z$="00"(1 TO 2-LEN Z$)+
Z$
2805 LET Z=16*CODE Z$+CODE Z$(2)
-476
2810 LET Z=(CODE Z$-NUM)*16+CODE
Z$(2)-NUM
2820 RETURN
2900 REM CLRPMT
2905 PRINT AT PMTY,0;" ";
2910 RETURN
3000 REM JUMP
3005 GOSUB 3200
3010 PRINT AT FLY+1,ADX;" "
3015 PRINT AT PMTY,0;"ENTER THE
ADDRESS IN HEX."
3020 GOSUB INPUT
3025 GOSUB CLRPMT
3030 IF LEN Z$>4 THEN GOTO 3020
3040 GOSUB DEC16
3060 PRINT AT FLY+1,ADX;Z$
3070 FOR V=ADX TO ADX+3
3080 PRINT AT FLY+1,V;"█"
3090 PRINT AT FLY,V;Z$(V-ADX+1)
3100 NEXT V
3120 LET AD=Z
3130 GOSUB DISP3
3140 GOTO MAIN2
3200 LET Z=AD
3210 GOSUB HEX16
3220 GOSUB INVERSE
3230 PRINT AT FLY,ADX;Z$
3240 RETURN
4000 REM INC ADDR
4010 LET AD=AD+1
4020 IF AD>MAXADDR THEN LET AD=M
INADDR
4025 GOSUB 1040
4030 GOTO MAIN2
5000 REM DEC ADDR
5010 LET AD=AD-1
5020 IF AD<MINADDR THEN LET AD=M
AXADDR
5025 GOSUB DISP2
5030 GOTO MAIN2
6000 REM DISPLAY
6001 LET TC=AD
6003 GOSUB CLRSEC
6005 PRINT AT SECTOP,0;
6010 LET IL=LPD-PEEK CURY
6030 IF LPD-PEEK CURY>=DL+IL OR
INKEY$<>"" THEN GOTO MAIN2
6033 PRINT CHR$ (PEEK TC);
6035 LET TC=TC+1
6040 GOTO 6020
7000 REM PRINT
7005 GOSUB CLRSEC
7010 FOR P=0 TO LPP-1
7015 IF INKEY$<>"" THEN GOTO 130
7020 LET Z=AD+P
7030 GOSUB HEX16
7040 PRINT TAB ADX;Z$;TAB VALX;
7050 LET Z1=PEEK Z
7055 GOSUB HEX8
7060 PRINT Z$;TAB CHARX;CHR$ (Z1
)
7070 NEXT P
7080 LET AD=AD+P
7090 GOTO MAIN
8000 REM CALL
8005 GOSUB CLRSEC
8010 LET KK=USR AD
8020 PRINT AT SECTOP,0;"THE CALL
SET BC=";
8030 LET Z=KK
8040 GOSUB HEX16
8050 PRINT Z$
8060 GOTO MAIN
9000 REM OPEN
9020 LET Z1=PEEK AD
9030 GOSUB HEX8
9040 GOSUB INVERSE
9060 FOR N=FLY+1 TO PRIBOT-1
9065 PRINT AT N,VALX;" "
9070 PRINT AT N-1,VALX;Z$
9080 LET Z$="██"
9095 NEXT N
9097 PRINT AT PMTY,0;"ENTER THE
VALUE IN HEX."
9100 GOSUB INPUT
9110 GOSUB CLRPMT
9120 IF LEN Z$>2 THEN GOTO 9100
9130 GOSUB DEC8
9140 PRINT AT PRIBOT-1,VALX;Z$
9150 FOR N=PRIBOT-1 TO FLY+1 STE
P -1
9160 PRINT AT N,VALX;"██"
9170 PRINT AT N-1,VALX;Z$
9180 NEXT N
9190 POKE AD,Z
9195 LET AD=AD+1
9200 GOTO MAIN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.