Tiny Basic Instructions

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 73

DownloadTiny Basic Instructions
Open PDF In BrowserView PDF
Tiny BASIC for the CPUville Z80 Computer
by Donn Stewart
November, 2016
@Copyleft, all wrongs reserved

1

Table of Contents
Introduction................................................................................................................................................3
Setting up Tiny BASIC on the CPUville Z80 computer............................................................................5
Using Tiny BASIC with Realterm in Windows.........................................................................................6
Using Tiny BASIC with Minicom in Linux.............................................................................................15
Appendix A: Tiny BASIC Language Description....................................................................................25
Numbers..............................................................................................................................................25
Variables..............................................................................................................................................25
Functions.............................................................................................................................................25
Arithmetic and Compare operators.....................................................................................................25
Expressions..........................................................................................................................................26
Direct Commands................................................................................................................................26
Abbreviations and blanks....................................................................................................................27
Statements...........................................................................................................................................27
Commands...........................................................................................................................................28
REM or REMARK Command.......................................................................................................28
LET Command...............................................................................................................................28
PRINT Command...........................................................................................................................28
INPUT Command...........................................................................................................................29
IF Command...................................................................................................................................30
GOTO Command............................................................................................................................30
GOSUB and RETURN Commands................................................................................................30
FOR and NEXT Commands...........................................................................................................31
STOP Command.............................................................................................................................32
Stopping the Execution.......................................................................................................................32
Control of Output Device....................................................................................................................32
Error Report.........................................................................................................................................33
Error Corrections.................................................................................................................................34
Appendix B: Tiny BASIC Assembly listing............................................................................................35
Appendix C: Intel Hex Code for Tiny BASIC.........................................................................................71

2

Introduction
Early personal microcomputers, such as the Altair 8800, were programmed using assembly language
and machine code. However, there was much interest in developing higher-level computer languages
for these early machines. The BASIC programming language (Beginner's All-purpose Symbolic
Instruction Code) was a natural target for these efforts. The original BASIC was developed in 1964 and
ran on mainframe computers. Many computer science students wrote their first programs in BASIC.
So, when personal computers appeared, there was a natural desire to develop a BASIC language
interpreter that could run on these new machines.
Microcomputers where handicapped in the early years by the size of memory, which usually cost more
than the microprocessors. Nonetheless, a number of BASIC interpreters were written that could run in
small memory spaces of only a few kilobytes. One of the most influential was Palo Alto Tiny BASIC,
written by Li-Chen Wang in 1976. This program is famous for the comment in its source file heading
that read “@COPYLEFT ALL WRONGS RESERVED”. It was one of the early formal expressions of
the free software philosophy.
Tiny BASIC was written for the Intel 8080 processor, and 8080 machine code will almost always run
on the Z801. This BASIC interpreter runs in 2K of ROM, and 2K of RAM is more than adequate for
writing and running small programs. So, on first look it seems to be well suited for use in the CPUville
Z80 computer with the serial interface. The original Tiny BASIC 8080 assembly language was written
in a dialect for a mainframe assembler has since been lost. However, Roger Rauskolb in October of
1976 modified the assembly language so that it could be assembled by Intel's 8080 Macroassembler,
also known as MAC-80. The source code for this assembler was written in Fortran 66. Most mainframe
and minicomputers of the day had Fortran compilers, so this assembler was easy for most hobbyists to
access. Eventually, the MAC-80 assembler was made available in 8080 code, and was one of the
popular programs on early CP/M computers.
So, with the 8080 source code for Tiny BASIC, and an assembler source code available in Fortran,
there was a chance I could get Tiny BASIC up and running on the CPUville Z80 computer.
First, I had to compile the MAC-80 assembler. Fortunately, the open-source Fortran compiler gfortran
has the ability to compile obsolete Fortran dialects such as Fortran 66, and I was able to compile MAC80 and run it on a PC, in the Linux environment. Next, I modified the Tiny BASIC code to match the
CPUville Z80 computer hardware. Specifically, I had to change the status and data port addresses for
the UART (called the ACIA in the Tiny BASIC comments), the test bits for UART status, and the
UART initialization bytes. I changed the ORG statements at the end of the Tiny BASIC code to better
match a system with 2K ROM and 2K RAM. And, that was it! Tiny BASIC assembled without errors. I
loaded it onto a ROM, and it ran fine on the CPUville computer.
Tiny BASIC is quite limited in its capabilities. It is integer-only – no floating point numbers allowed. It
can only initialize one array, and can use only 26 variables, named A to Z. It does not have higher
1

The Z80 was designed to be compatible with the 8080. The 8080 registers, flags, and machine code are a subset of Z80
registers, flags, and machine code. All 8080 machine instructions will work properly on the Z80, with the exception of
instructions using the rarely used parity/overflow flag.

3

arithmetic functions, such as exponent. But surprisingly it has a random number generator function, so
games with probabilities can be programmed. There is a full summary of the Tiny BASIC language in
Appendix A.

4

Setting up Tiny BASIC on the CPUville Z80 computer
Tiny BASIC machine code has been loaded onto a 2K EPROM for use in the CPUville Z80 computer.
It is intended for use in the computer with the serial interface attached, as a substitute for the v.7
EPROM. For details on using the serial interface, please consult the Serial Interface Instruction
Manual. The Tiny BASIC EPROM can also be used in the computer with the disk and memory
expansion interface, taking the place of the v.8 EPROM, but in its current form Tiny BASIC can only
use 2K of RAM2. In the computer with the disk and memory expansion, one is able to install CP/M and
use the much more powerful Microsoft BASIC.
To set up the CPUville Z80 computer for Tiny BASIC, it should have the serial interface attached
directly to it. Remove the v.7 EPROM and replace it with the Tiny BASIC EPROM. The computer
needs to be set for the fast clock, and the jumpers need to be ON. It does not matter what is on the input
port DIP switches.
The following sections describe in detail how to use Tiny BASIC in both Windows and Linux
environments.

2

The Tiny BASIC code can easily be modified to use more RAM if this is desired.

5

Using Tiny BASIC with Realterm in Windows
Set the Realterm display to ANSI, 24 rows, and the port to 9600 baud with 8 data bits, one stop bit, and
no parity – the usual settings when operating the CPUville Z80 computer with the serial interface. With
the Tiny BASIC EPROM installed, connect the computer to power, and take it out of reset. The display
will show the Tiny BASIC greeting:

I will demonstrate Tiny BASIC programming, and how to save and load programs from the PC disk. A
full description of the Tiny BASIC programming language can be found in Appendix A.
To enter program statements, at the > prompt, type a number between 1 and 32767, a space, then a
program statement. When you have finished, hit return or enter. If you make a mistake, you can erase
the line by entering the line number only, then re-enter the line. Using backspace does not seem to work
6

to erase your characters in the Realterm environment.
Here is a sample program, which prints consecutive integers starting at 1 :

To run the program, type RUN at the prompt. The integers will scroll down the screen. To stop the
program, go to the Send tab of Realterm and hit the control-C button (^C, shown by the red arrow):

7

To see your program as it sits in Tiny BASIC's memory, type LIST:

8

We can use the LIST command, with the Realterm Capture function, to save a copy of the program to
the disk on the PC. On the Realterm Capture tab, enter or navigate to a file to save the program. By
default, the capture file, which is a text file, has the name capture.txt, but you can give it any name you
like. Sometimes people use the .bas extension for BASIC program files. Once you have entered a file
name and location, type LIST at the Tiny BASIC prompt but do not hit Enter. Then, hit the Start
Overwrite button on the Realterm Capture tab. The capture area will turn red. Then, at the BASIC
prompt, hit Enter:

9

Next, hit the Stop Capture button. The screen will clear, and the capture area will turn back to its
normal color:

10

It looks like Tiny BASIC is lost, but click in the terminal screen area and hit Enter a few times and the
Tiny BASIC prompt will re-appear.
We will now load back the program we saved. First, type LIST to show the program is still in the Tiny
BASIC memory. Then, type NEW to erase the program. After that, type LIST again to verify that the
program is gone:

11

We will use the functions on the Realterm Send tab to load the program back into Tiny BASIC's
memory area. In the terminal window, enter control-O. Nothing will happen, this just turns off Tiny
BASIC's terminal output. This will prevent Tiny BASIC from echoing the characters in the file as we
load them, which would mess up the screen. Then, in the Realterm Send tab, in the Dump File to Port
area, enter or navigate to the program file. Then, hit the Send File button. The blue progress bar will
show that the file has been sent. Then, hit the Stop button:

12

Now enter control-O again in the terminal window, to turn back on Tiny BASICs screen output. Type
LIST or hit Enter. Tiny BASIC will have some garbage in its input buffer, because the capture file will
have sent the “OK” and the prompt character from the LIST command output that we saved in the file,
so it will produce a WHAT ? error message. If this bothers you, you can edit the capture file to remove
them. But, if you hit Enter again, the error is cleared. Now enter LIST again, and you will see that the
program is back in Tiny BASIC's memory:

13

Use RUN to verify that the program works.
This concludes the discussion of running Tiny BASIC on the CPUville Z80 computer with Realterm in
Windows.

14

Using Tiny BASIC with Minicom in Linux
Open a terminal window and start Minicom, with the port set to 9600 baud with 8 data bits, one stop
bit, and no parity – the usual settings when operating the CPUville Z80 computer with the serial
interface. With the Tiny BASIC EPROM installed, connect the computer to power, and take it out of
reset. The terminal window will show the Tiny BASIC greeting:

I will demonstrate Tiny BASIC programming, and how to save and load programs from the PC disk. A
full description of the Tiny BASIC programming language can be found in Appendix A.
To enter program statements, at the > prompt, type a number between 1 and 32767, a space, then a
program statement. When you have finished entering a program statement, hit Enter. If you make a
mistake, you can erase the line by entering the line number only at the Tiny BASIC prompt, then reenter the line number with the corrected statement. Using backspace does not seem to work to erase
your characters in the Minicom environment before you enter a line.
Here is a sample program the prints consecutive integers:

15

To see your program as it sits in Tiny BASIC's memory, type LIST:

16

To run the program, type RUN at the prompt. The integers will scroll down the screen. To stop the
program, hit control-C:

17

We will use the LIST command, with the Minicom capture function, to save a copy of the program to
the disk on the PC. Start by typing LIST at the Tiny BASIC prompt but do not press Enter. Hit controlA then Z to get the Minicom Command Summary window:

18

Hit the L key to designate and activate a capture file:

19

The default is minicom.cap, but you can use any name. Many people like to use the .bas extension for
BASIC language program files. The Minicom capture function will append the capture file if it already
exists, so for the purposes of saving a program you should either delete the old capture file first, or
designate a new file. After you hit Enter the capture file is opened and the command summary closes.
Now hit Enter to perform the LIST command in Tiny BASIC. The program listing will be captured by
the file. Then, hit control-A then Z then L and close the capture file:

20

Note you can go directly to the capture file dialog by entering control-A then L, bypassing the Minicom
Command Summary.
Tiny BASIC sends text with carriage-return/linefeed characters at the end of each line (hex 0x0D,
0x0A). In Linux, which is derived from Unix, the convention is that lines in text files are terminated by
a newline character only. In ASCII, this is the same as the linefeed character, 0x0A. When the Tiny
BASIC program listing is saved, the Linux shell or the tty code strips out the carriage return characters.
However, Tiny BASIC needs the carriage return characters when it reads back the file. So, they need to
be put back into the capture file. There is a Linux utility that does this for us, called unix2dos3.
Open a second terminal window. Enter the command unix2dos followed by the name of the capture
file. To verify that you have the capture file, you can display it using the more command:

3

In Linux Debian-based system, the package that contains this utility is called dos2unix. It can be obtained from the
repositories by the command apt-get install dos2unix.

21

Note that the capture file contains the “OK” and the Tiny BASIC prompt “>” after the program listing.
These extra characters will cause Tiny BASIC to produce a WHAT error when you read back the file,
but this won't interfere with getting the program back. You can now close the second terminal window.
To read back the program file, we will use the Minicom Paste File function from the Command
Summary. But first, at the Tiny BASIC prompt, type NEW to erase the program from memory. Type
LIST to verify that the program is gone. Then type control-O. This will prevent Tiny BASIC from
echoing the incoming characters to the screen. Now type control-A then Z then Y, or just control-A then
Y to get to the Minicom Paste File command. You can navigate to the file, or hit Enter to get a space to
type in the name:

22

After the file name is entered, hit Enter to transfer the file. Now type control-O again to turn Tiny
BASIC's output back on. Hit Enter or type LIST. Tiny BASIC will show the WHAT error because of
the “OK” and “>” in the capture file, but just hit Enter again and you will get back to the Tiny BASIC
prompt and clear the error. Then type LIST and you will see that the program has been read back into
the Tiny BASIC memory:

23

Enter RUN to verify that the program works.
This concludes the discussion of using Tiny BASIC with Minicom in Linux.

24

Appendix A: Tiny BASIC Language Description
What follows is the original description of the Tiny BASIC language taken from Li-Chen Wang's
article published in Dr. Dobb's Journal of Computer Calisthenics and Orthodontia, vol. 1, number 5,
May 1976, pages 12-15. This document can be found on-line at:
https://archive.org/details/dr_dobbs_journal_vol_01
The original text has been corrected in a few places for spelling and grammar errors. When procedures
needed to be adapted for Tiny BASIC on the CPUville Z80 computer, I have added explanatory text in
clearly marked boxes.
--Donn Stewart, November 2016

THE LANGUAGE
Numbers
All numbers are integers and must be less than 32767.

Variables
There are 26 variables denoted by letters A through Z. There is also
a single array @(I). The dimension of this array is set automatically
to make use of all the memory space that is left unused by the
program. (i.e., 0 through SIZE/2, see SIZE function below.)

Functions
There are 3 functions:
ABS(X) gives the absolute value of X.
RND(X) gives a random number between 1 and x (inclusive).
SIZE gives the number of bytes left unused by the program.

Arithmetic and Compare operators
/

divide.
25

*
­
+
>
<
=
#
>=
<=

multiply.
subtract.
add.
greater than (compare).
less than (compare).
equal to (compare).
not equal to (compare).
greater than or equal to (compare).
less than or equal to (compare).

+, ­, *, and / operations result in a value between
­32767 and 32767. (­32768 is also allowed in some cases).
All compare operators result in a 1 if true and a 0 if not true.

Expressions
Expressions are formed with numbers, variables, and functions with
arithmetic and compare operators between them. + and ­ signs can also
he used at the beginning of an expression. The value of an expression
is evaluated from left to right, except that * and / are always done
first, and then + and ­, and then compare operators. Parentheses can
also be used to alter the order of evaluation. Note that compare
operators can be used in any expression. For example:
10 LET A=(X>Y)*123+(X=Y)*456+(XV)*(U<99)*(V>3) PRINT "YES"
30 LET R=RND(100), A=(R>3)*(R>15)+(R>56)+(R>98)
In statement 10, A will be set to 123 if X>Y, to 456 if X=Y, and to
789 if XB) *X+(A)
;AND RETURN THE FIRST
;NON­BLANK CHAR. IN A

;

;

TV1:

TV1
D
PARN
H
QHOW
D
SIZE
4
ASORRY
H,VARBGN
SUBDE
D
1BH
D
H,VARBGN
L
L,A

;IF A THROUGH Z
;COMPUTE ADDRESS OF
;THAT VARIABLE
;AND RETURN IT IN HL
;WITH C FLAG CLEARED

36

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0063
0065
0066
0067

3E00
8C
67
C9

0068
0069
006C
006D
006E
0070
0071
0072
0073
0074
0075
0076

23
CA7300
C5
4E
0600
09
C1
1B
13
23
E3
C9

0077
007A
007B
007C
007E
007F
0081
0082
0084
0085
0088
0089
008A
008B
008C
008D
008E
008F
0090
0091
0092
0094
0095
0096
0098
0099
009A
009B
009C
009F

210000
44
EF
FE30
D8
FE3A
D0
3EF0
A4
C29F00
04
C5
44
4D
29
29
09
29
1A
13
E60F
85
6F
3E00
8C
67
C1
1A
F27C00
D5

MVI
ADC
MOV
RET
;
;TSTC:
;
;
TC1:

TC2:

XTHL
RST
CMP
INX
JZ
PUSH
MOV
MVI
DAD
POP
DCX
INX
INX
XTHL
RET

;
TSTNUM: LXI
MOV
RST
TN1:
CPI
RC
CPI
RNC
MVI
ANA
JNZ
INR
PUSH
MOV
MOV
DAD
DAD
DAD
DAD
LDAX
INX
ANI
ADD
MOV
MVI
ADC
MOV
POP
LDAX
JP
QHOW:
PUSH

ERRORS = 0
17:09

10/02/2016
PAGE 3

A,0
H
H,A

5
M
H
TC2
B
C,M
B,0
B
B
D
D
H

H,0
B,H
5
30H
3AH
A,0F0H
H
QHOW
B
B
B,H
C,L
H
H
B
H
D
D
0FH
L
L,A
A,0
H
H,A
B
D
TN1
D

;*** TSTC OR RST 1 ***
;THIS IS AT LOC. 8
;AND THEN JUMP HERE
;COMPARE THE BYTE THAT
;FOLLOWS THE RST INST.
;WITH THE TEXT (DE­>)
;IF NOT =, ADD THE 2ND
;BYTE THAT FOLLOWS THE
;RST TO THE OLD PC
;I.E., DO A RELATIVE
;JUMP IF NOT =
;IF =, SKIP THOSE BYTES
;AND CONTINUE

;*** TSTNUM ***
;TEST IF THE TEXT IS
;A NUMBER
;IF NOT, RETURN 0 IN
;B AND HL
;IF NUMBERS, CONVERT
;TO BINARY IN HL AND
;SET B TO # OF DIGITS
;IF H>255, THERE IS NO
;ROOM FOR NEXT DIGIT
;B COUNTS # OF DIGITS
;HL=10*HL+(NEW DIGIT)
;WHERE 10* IS DONE BY
;SHIFT AND ADD
;AND (DIGIT) IS FROM
;STRIPPING THE ASCII
;CODE

;DO THIS DIGIT AFTER
;DIGIT. S SAYS OVERFLOW
;*** ERROR "HOW?" ***

37

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

00A0
00A3
00A6
00AA
00AB
00AD
00AE
00B2
00B3
00B4
00B8
00B9

11A600
C3CA04
484F573F
0D
4F4B
0D
57484154
3F
0D
534F5252
59
0D

00BA
00BD
00C0
00C3
00C4
00C7

310010
CD0E00
11AB00
97
CD6005
21CE00

AHOW:

ERRORS = 0
17:09

PAGE 4

WHAT:

LXI
JMP
DB
DB
DB
DB
DB

D,HOW
ERROR
'HOW?'
CR
'OK'
CR
'WHAT?'

SORRY:

DB
DB

CR
'SORRY'

HOW:
OK:

10/02/2016

DB
CR
;
;*************************************************************
;
; *** MAIN ***
;
; THIS IS THE MAIN LOOP THAT COLLECTS THE TINY BASIC PROGRAM
; AND STORES IT IN THE MEMORY.
;
; AT START, IT PRINTS OUT "(CR)OK(CR)", AND INITIALIZES THE
; STACK AND SOME OTHER INTERNAL VARIABLES. THEN IT PROMPTS
; ">" AND READS A LINE. IF THE LINE STARTS WITH A NON­ZERO
; NUMBER, THIS NUMBER IS THE LINE NUMBER. THE LINE NUMBER
; (IN 16 BIT BINARY) AND THE REST OF THE LINE (INCLUDING CR)
; IS STORED IN THE MEMORY. IF A LINE WITH THE SAME LINE
; NUMBER IS ALREADY THERE, IT IS REPLACED BY THE NEW ONE. IF
; THE REST OF THE LINE CONSISTS OF A CR ONLY, IT IS NOT STORED
; AND ANY EXISTING LINE WITH THE SAME LINE NUMBER IS DELETED.
;
; AFTER A LINE IS INSERTED, REPLACED, OR DELETED, THE PROGRAM
; LOOPS BACK AND ASKS FOR ANOTHER LINE. THIS LOOP WILL BE
; TERMINATED WHEN IT READS A LINE WITH ZERO OR NO LINE
; NUMBER; AND CONTROL IS TRANSFERED TO "DIRECT".
;
; TINY BASIC PROGRAM SAVE AREA STARTS AT THE MEMORY LOCATION
; LABELED "TXTBGN" AND ENDS AT "TXTEND". WE ALWAYS FILL THIS
; AREA STARTING AT "TXTBGN", THE UNFILLED PORTION IS POINTED
; BY THE CONTENT OF A MEMORY LOCATION LABELED "TXTUNF".
;
; THE MEMORY LOCATION "CURRNT" POINTS TO THE LINE NUMBER
; THAT IS CURRENTLY BEING INTERPRETED. WHILE WE ARE IN
; THIS LOOP OR WHILE WE ARE INTERPRETING A DIRECT COMMAND
; (SEE NEXT SECTION). "CURRNT" SHOULD POINT TO A 0.
;
RSTART: LXI SP,STACK
ST1:
CALL CRLF
;AND JUMP TO HERE
LXI D,OK
;DE­>STRING
SUB A
;A=0
CALL PRTSTG
;PRINT STRING UNTIL CR
LXI H,ST2+1
;LITERAL 0

38

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

00CA
00CD
00D0
00D3
00D6
00D8
00DB
00DC
00DF
00E2
00E3
00E4
00E5
00E6
00E9
00EA
00EB
00EC
00ED
00EE
00EF
00F0
00F1
00F2
00F3
00F4
00F7
00F8
00FB
00FC

220108
210000
220908
220308
3E3E
CDFA04
D5
11370F
CD7700
EF
7C
B5
C1
CA3807
1B
7C
12
1B
7D
12
C5
D5
79
93
F5
CD3805
D5
C20B01
D5
CD5405

00FF
0100
0103
0106
0107
0108
010B
010C
010F
0110
0111
0113
0116
0117
0118
011A
011B
011C
011F
0120

C1
2A1508
CDE505
60
69
221508
C1
2A1508
F1
E5
FE03
CABA00
85
6F
3E00
8C
67
11000F
E7
D2F304

ST2:
ST3:

ST4:

ERRORS = 0
17:09

10/02/2016
PAGE 5

SHLD
LXI
SHLD
SHLD
MVI
CALL
PUSH
LXI
CALL
RST
MOV
ORA
POP
JZ
DCX
MOV
STAX
DCX
MOV
STAX
PUSH
PUSH
MOV
SUB
PUSH
CALL
PUSH
JNZ
PUSH
CALL

CURRNT
H,0
LOPVAR
STKGOS
A,3EH
GETLN
D
D,BUFFER
TSTNUM
5
A,H
L
B
DIRECT
D
A,H
D
D
A,L
D
B
D
A,C
E
PSW
FNDLN
D
ST4
D
FNDNXT

POP
LHLD
CALL
MOV
MOV
SHLD
POP
LHLD
POP
PUSH
CPI
JZ
ADD
MOV
MVI
ADC
MOV
LXI
RST
JNC

B
TXTUNF
MVUP
H,B
L,C
TXTUNF
B
TXTUNF
PSW
H
3
RSTART
L
L,A
A,0
H
H,A
D,TXTEND
4
QSORRY

;CURRENT­>LINE # = 0

;PROMPT '>' AND
;READ A LINE
;DE­>END OF LINE
;DE­>BEGINNING OF LINE
;TEST IF IT IS A NUMBER
;HL=VALUE OF THE # OR
;0 IF NO # WAS FOUND
;BC­>END OF LINE
;BACKUP DE AND SAVE
;VALUE OF LINE # THERE

;BC,DE­>BEGIN, END

;A=# OF BYTES IN LINE
;FIND THIS LINE IN SAVE
;AREA, DE­>SAVE AREA
;NZ:NOT FOUND, INSERT
;Z:FOUND, DELETE IT
;FIND NEXT LINE
;DE­>NEXT LINE
;BC­>LINE TO BE DELETED
;HL­>UNFILLED SAVE AREA
;MOVE UP TO DELETE
;TXTUNF­>UNFILLED AREA
;UPDATE
;GET READY TO INSERT
;BUT FIRST CHECK IF
;THE LENGTH OF NEW LINE
;IS 3 (LINE # AND CR)
;THEN DO NOT INSERT
;MUST CLEAR THE STACK
;COMPUTE NEW TXTUNF

;HL­>NEW UNFILLED AREA
;CHECK TO SEE IF THERE
;IS ENOUGH SPACE
;SORRY, NO ROOM FOR IT

39

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0123
0126
0127
012A
012B
012C
012F

221508
D1
CDEE05
D1
E1
CDE505
C3D600

0132
0135
0138

CDC204
211708
221508

013B
013E

CDC204
C3BA00

0141

CDC204

SHLD
POP
CALL
POP
POP
CALL
JMP

ERRORS = 0
17:09

10/02/2016
PAGE 6

TXTUNF
D
MVDOWN
D
H
MVUP
ST3

;OK, UPDATE TXTUNF
;DE­>OLD UNFILLED AREA
;DE­>BEGIN, HL­>END
;MOVE NEW LINE TO SAVE
;AREA

;
;*************************************************************
;
; WHAT FOLLOWS IS THE CODE TO EXECUTE DIRECT AND STATEMENT
; COMMANDS. CONTROL IS TRANSFERED TO THESE POINTS VIA THE
; COMMAND TABLE LOOKUP CODE OF 'DIRECT' AND 'EXEC' IN LAST
; SECTION. AFTER THE COMMAND IS EXECUTED, CONTROL IS
; TRANSFERED TO OTHERS SECTIONS AS FOLLOWS:
;
; FOR 'LIST', 'NEW', AND 'STOP': GO BACK TO 'RSTART'
; FOR 'RUN': GO EXECUTE THE FIRST STORED LINE IF ANY, ELSE
; GO BACK TO 'RSTART'.
; FOR 'GOTO' AND 'GOSUB': GO EXECUTE THE TARGET LINE.
; FOR 'RETURN' AND 'NEXT': GO BACK TO SAVED RETURN LINE.
; FOR ALL OTHERS: IF 'CURRENT' ­> 0, GO TO 'RSTART', ELSE
; GO EXECUTE NEXT COMMAND. (THIS IS DONE IN 'FINISH'.)
;*************************************************************
;
; *** NEW *** STOP *** RUN (& FRIENDS) *** & GOTO ***
;
; 'NEW(CR)' SETS 'TXTUNF' TO POINT TO 'TXTBGN'
;
; 'STOP(CR)' GOES BACK TO 'RSTART'
;
; 'RUN(CR)' FINDS THE FIRST STORED LINE, STORE ITS ADDRESS (IN
; 'CURRENT'), AND START EXECUTE IT. NOTE THAT ONLY THOSE
; COMMANDS IN TAB2 ARE LEGAL FOR STORED PROGRAM.
;
; THERE ARE 3 MORE ENTRIES IN 'RUN':
; 'RUNNXL' FINDS NEXT LINE, STORES ITS ADDR. AND EXECUTES IT.
; 'RUNTSL' STORES THE ADDRESS OF THIS LINE AND EXECUTES IT.
; 'RUNSML' CONTINUES THE EXECUTION ON SAME LINE.
;
; 'GOTO EXPR(CR)' EVALUATES THE EXPRESSION, FIND THE TARGET
; LINE, AND JUMP TO 'RUNTSL' TO DO IT.
;
NEW:
CALL ENDCHK
;*** NEW(CR) ***
LXI H,TXTBGN
SHLD TXTUNF
;
STOP:
CALL ENDCHK
;*** STOP(CR) ***
JMP RSTART
;
RUN:
CALL ENDCHK
;*** RUN(CR) ***

40

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0144

111708

0147
014A
014D

210000
CD4005
DABA00

0150
0151
0154
0155
0156

EB
220108
EB
13
13

0157
015A
015D

CD8406
21BD06
C33B07

0160
0161
0162
0165
0168
016B
016C

DF
D5
CDC204
CD3805
C2A000
F1
C35001

ERRORS = 0
17:09

10/02/2016
PAGE 7

LXI D,TXTBGN
;FIRST SAVED LINE
;
RUNNXL: LXI H,0
;*** RUNNXL ***
CALL FNDLP
;FIND WHATEVER LINE #
JC
RSTART
;C:PASSED TXTUNF, QUIT
;
RUNTSL: XCHG
;*** RUNTSL ***
SHLD CURRNT
;SET 'CURRENT'­>LINE #
XCHG
INX D
;BUMP PASS LINE #
INX D
;
RUNSML: CALL CHKIO
;*** RUNSML ***
LXI H,TAB2­1
;FIND COMMAND IN TAB2
JMP EXEC
;AND EXECUTE IT
;
GOTO:
RST 3
;*** GOTO EXPR ***
PUSH D
;SAVE FOR ERROR ROUTINE
CALL ENDCHK
;MUST FIND A CR
CALL FNDLN
;FIND THE TARGET LINE
JNZ AHOW
;NO SUCH LINE #
POP PSW
;CLEAR THE PUSH DE
JMP RUNTSL
;GO DO IT
;
;*************************************************************
;
; *** LIST *** & PRINT ***
;
; LIST HAS TWO FORMS:
; 'LIST(CR)' LISTS ALL SAVED LINES
; 'LIST #(CR)' START LIST AT THIS LINE #
; YOU CAN STOP THE LISTING BY CONTROL C KEY
;
; PRINT COMMAND IS 'PRINT ....;' OR 'PRINT ....(CR)'
; WHERE '....' IS A LIST OF EXPRESIONS, FORMATS, BACK­
; ARROWS, AND STRINGS. THESE ITEMS ARE SEPERATED BY COMMAS.
;
; A FORMAT IS A POUND SIGN FOLLOWED BY A NUMBER. IT CONTROLS
; THE NUMBER OF SPACES THE VALUE OF A EXPRESION IS GOING TO
; BE PRINTED. IT STAYS EFFECTIVE FOR THE REST OF THE PRINT
; COMMAND UNLESS CHANGED BY ANOTHER FORMAT. IF NO FORMAT IS
; SPECIFIED, 6 POSITIONS WILL BE USED.
;
; A STRING IS QUOTED IN A PAIR OF SINGLE QUOTES OR A PAIR OF
; DOUBLE QUOTES.
;
; A BACK­ARROW MEANS GENERATE A (CR) WITHOUT (LF)
;
; A (CRLF) IS GENERATED AFTER THE ENTIRE LIST HAS BEEN
; PRINTED OR IF THE LIST IS A NULL LIST. HOWEVER IF THE LIST
; ENDED WITH A COMMA, NO (CRLF) IS GENERATED.

41

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

016F
0172
0175
0178
017B
017E
0181
0184

CD7700
CDC204
CD3805
DABA00
CDD205
CD8406
CD4005
C37801

0187
0189
018A
018B
018C
018F
0192
0193
0194
0195
0198
019B
019C
019D
019E
019F
01A0
01A3
01A6
01A9
01AA
01AB
01AC
01AF
01B2
01B5
01B6
01B7
01B8
01BB
01BC

0E06
CF
3B
06
CD0E00
C35701
CF
0D
06
CD0E00
C34701
CF
23
05
DF
4D
C3A901
CD6C05
C3B601
CF
2C
06
CDB304
C39B01
CD0E00
F7
DF
C5
CD9205
C1
C3A901

;
LIST:
LS1:

;
PRINT:

PR2:

PR0:

PR1:
PR3:

PR6:
PR8:

ERRORS = 0
17:09

10/02/2016
PAGE 8

CALL
CALL
CALL
JC
CALL
CALL
CALL
JMP

TSTNUM
ENDCHK
FNDLN
RSTART
PRTLN
CHKIO
FNDLP
LS1

;TEST IF THERE IS A #
;IF NO # WE GET A 0
;FIND THIS OR NEXT LINE
;C:PASSED TXTUNF
;PRINT THE LINE
;STOP IF HIT CONTROL­C
;FIND NEXT LINE
;AND LOOP BACK

MVI
RST
DB
DB
CALL
JMP
RST
DB
DB
CALL
JMP
RST
DB
DB
RST
MOV
JMP
CALL
JMP
RST
DB
DB
CALL
JMP
CALL
RST
RST
PUSH
CALL
POP
JMP

C,6
1
3BH
PR2­$­1
CRLF
RUNSML
1
CR
PR0­$­1
CRLF
RUNNXL
1
'#'
PR1­$­1
3
C,L
PR3
QTSTG
PR8
1
','
PR6­$­1
FIN
PR0
CRLF
6
3
B
PRTNUM
B
PR3

;C = # OF SPACES
;IF NULL LIST & ";"
;GIVE CR­LF AND
;CONTINUE SAME LINE
;IF NULL LIST (CR)
;ALSO GIVE CR­LF AND
;GO TO NEXT LINE
;ELSE IS IT FORMAT?
;YES, EVALUATE EXPR.
;AND SAVE IT IN C
;LOOK FOR MORE TO PRINT
;OR IS IT A STRING?
;IF NOT, MUST BE EXPR.
;IF ",", GO FIND NEXT
;IN THE LIST.
;LIST CONTINUES
;LIST ENDS
;EVALUATE THE EXPR
;PRINT THE VALUE

;MORE TO PRINT?
;
;*************************************************************
;
; *** GOSUB *** & RETURN ***
;
; 'GOSUB EXPR;' OR 'GOSUB EXPR (CR)' IS LIKE THE 'GOTO'
; COMMAND, EXCEPT THAT THE CURRENT TEXT POINTER, STACK POINTER
; ETC. ARE SAVE SO THAT EXECUTION CAN BE CONTINUED AFTER THE
; SUBROUTINE 'RETURN'. IN ORDER THAT 'GOSUB' CAN BE NESTED
; (AND EVEN RECURSIVE), THE SAVE AREA MUST BE STACKED.

42

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

01BF
01C2
01C3
01C4
01C7
01CA
01CD
01CE
01D1
01D2
01D5
01D8
01D9
01DC
01DF
01E2
01E5
01E6
01E7
01EA
01EB
01EC
01EF
01F0
01F3
01F4
01F7

CD1906
DF
D5
CD3805
C2A000
2A0108
E5
2A0308
E5
210000
220908
39
220308
C35001
CDC204
2A0308
7C
B5
CAC604
F9
E1
220308
E1
220108
D1
CDFD05
F7

ERRORS = 0
17:09

10/02/2016
PAGE 9

; THE STACK POINTER IS SAVED IN 'STKGOS', THE OLD 'STKGOS' IS
; SAVED IN THE STACK. IF WE ARE IN THE MAIN ROUTINE, 'STKGOS'
; IS ZERO (THIS WAS DONE BY THE "MAIN" SECTION OF THE CODE),
; BUT WE STILL SAVE IT AS A FLAG FOR NO FURTHER 'RETURN'S.
;
; 'RETURN(CR)' UNDOS EVERYTHING THAT 'GOSUB' DID, AND THUS
; RETURN THE EXECUTION TO THE COMMAND AFTER THE MOST RECENT
; 'GOSUB'. IF 'STKGOS' IS ZERO, IT INDICATES THAT WE
; NEVER HAD A 'GOSUB' AND IS THUS AN ERROR.
;
GOSUB: CALL PUSHA
;SAVE THE CURRENT "FOR"
RST 3
;PARAMETERS
PUSH D
;AND TEXT POINTER
CALL FNDLN
;FIND THE TARGET LINE
JNZ AHOW
;NOT THERE. SAY "HOW?"
LHLD CURRNT
;FOUND IT, SAVE OLD
PUSH H
;'CURRNT' OLD 'STKGOS'
LHLD STKGOS
PUSH H
LXI H,0
;AND LOAD NEW ONES
SHLD LOPVAR
DAD SP
SHLD STKGOS
JMP RUNTSL
;THEN RUN THAT LINE
RETURN: CALL ENDCHK
;THERE MUST BE A CR
LHLD STKGOS
;OLD STACK POINTER
MOV A,H
;0 MEANS NOT EXIST
ORA L
JZ
QWHAT
;SO, WE SAY: "WHAT?"
SPHL
;ELSE, RESTORE IT
POP H
SHLD STKGOS
;AND THE OLD 'STKGOS'
POP H
SHLD CURRNT
;AND THE OLD 'CURRNT'
POP D
;OLD TEXT POINTER
CALL POPA
;OLD "FOR" PARAMETERS
RST 6
;AND WE ARE BACK HOME
;
;*************************************************************
;
; *** FOR *** & NEXT ***
;
; 'FOR' HAS TWO FORMS:
; 'FOR VAR=EXP1 TO EXP2 STEP EXP3' AND 'FOR VAR=EXP1 TO EXP2'
; THE SECOND FORM MEANS THE SAME THING AS THE FIRST FORM WITH
; EXP3=1. (I.E., WITH A STEP OF +1.)
; TBI WILL FIND THE VARIABLE VAR, AND SET ITS VALUE TO THE
; CURRENT VALUE OF EXP1. IT ALSO EVALUATES EXP2 AND EXP3
; AND SAVE ALL THESE TOGETHER WITH THE TEXT POINTER ETC. IN
; THE 'FOR' SAVE AREA, WHICH CONSISTS OF 'LOPVAR', 'LOPINC',
; 'LOPLMT', 'LOPLN', AND 'LOPPT'. IF THERE IS ALREADY SOME­

43

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

01F8
01FB
01FE
01FF
0202
0205
0208
0209
020C
020F
0212
0213
0216
0219
021C
021F
0222
0223
0226
0229
022C
022D
022E
022F
0230
0231
0232
0233
0234
0235
0238
0239
023A

CD1906
CDA004
2B
220908
211307
C33B07
DF
220D08
211907
C33B07
DF
C31902
210100
220B08
2A0108
220F08
EB
221108
010A00
2A0908
EB
60
68
39
3E
09
7E
23
B6
CA5202
7E
2B
BA

ERRORS = 0
17:09

10/02/2016
PAGE 10

; THING IN THE SAVE AREA (THIS IS INDICATED BY A NON­ZERO
; 'LOPVAR'), THEN THE OLD SAVE AREA IS SAVED IN THE STACK
; BEFORE THE NEW ONE OVERWRITES IT.
; TBI WILL THEN DIG IN THE STACK AND FIND OUT IF THIS SAME
; VARIABLE WAS USED IN ANOTHER CURRENTLY ACTIVE 'FOR' LOOP.
; IF THAT IS THE CASE, THEN THE OLD 'FOR' LOOP IS DEACTIVATED.
; (PURGED FROM THE STACK..)
;
; 'NEXT VAR' SERVES AS THE LOGICAL (NOT NECESSARILLY PHYSICAL)
; END OF THE 'FOR' LOOP. THE CONTROL VARIABLE VAR. IS CHECKED
; WITH THE 'LOPVAR'. IF THEY ARE NOT THE SAME, TBI DIGS IN
; THE STACK TO FIND THE RIGHT ONE AND PURGES ALL THOSE THAT
; DID NOT MATCH. EITHER WAY, TBI THEN ADDS THE 'STEP' TO
; THAT VARIABLE AND CHECK THE RESULT WITH THE LIMIT. IF IT
; IS WITHIN THE LIMIT, CONTROL LOOPS BACK TO THE COMMAND
; FOLLOWING THE 'FOR'. IF OUTSIDE THE LIMIT, THE SAVE AREA
; IS PURGED AND EXECUTION CONTINUES.
;
FOR:
CALL PUSHA
;SAVE THE OLD SAVE AREA
CALL SETVAL
;SET THE CONTROL VAR.
DCX H
;HL IS ITS ADDRESS
SHLD LOPVAR
;SAVE THAT
LXI H,TAB5­1
;USE 'EXEC' TO LOOK
JMP EXEC
;FOR THE WORD 'TO'
FR1:
RST 3
;EVALUATE THE LIMIT
SHLD LOPLMT
;SAVE THAT
LXI H,TAB6­1
;USE 'EXEC' TO LOOK
JMP EXEC
;FOR THE WORD 'STEP'
FR2:
RST 3
;FOUND IT, GET STEP
JMP FR4
FR3:
LXI H,1H
;NOT FOUND, SET TO 1
FR4:
SHLD LOPINC
;SAVE THAT TOO
FR5:
LHLD CURRNT
;SAVE CURRENT LINE #
SHLD LOPLN
XCHG
;AND TEXT POINTER
SHLD LOPPT
LXI B,0AH
;DIG INTO STACK TO
LHLD LOPVAR
;FIND 'LOPVAR'
XCHG
MOV H,B
MOV L,B
;HL=0 NOW
DAD SP
;HERE IS THE STACK
DB
3EH
FR7:
DAD B
;EACH LEVEL IS 10 DEEP
MOV A,M
;GET THAT OLD 'LOPVAR'
INX H
ORA M
JZ
FR8
;0 SAYS NO MORE IN IT
MOV A,M
DCX H
CMP D
;SAME AS THIS ONE?

44

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

023B
023E
023F
0240
0243
0244
0247
0248
0249
024A
024D
024E
0251
0252
0255
0256
0257
0258
025B
025E
025F
0260
0263
0264
0265
0268
0269
026C
026D
0270
0273
0276
0277
0278
0279
027C
027D
027E
027F
0280
0281
0284
0285
0288
0289
028C
028D
028E
028F
0292

C23102
7E
BB
C23102
EB
210000
39
44
4D
210A00
19
CDEE05
F9
2A1108
EB
F7
FF
DAC604
220508
D5
EB
2A0908
7C
B5
CAC704
E7
CA7602
D1
CDFD05
2A0508
C35E02
5E
23
56
2A0B08
E5
7C
AA
7A
19
FA8802
AC
FAAA02
EB
2A0908
73
23
72
2A0D08
F1

FR8:
;
NEXT:
NX0:

NX3:

NX4:

ERRORS = 0
17:09

10/02/2016
PAGE 11

JNZ
MOV
CMP
JNZ
XCHG
LXI
DAD
MOV
MOV
LXI
DAD
CALL
SPHL
LHLD
XCHG
RST

FR7
A,M
E
FR7

RST
JC
SHLD
PUSH
XCHG
LHLD
MOV
ORA
JZ
RST
JZ
POP
CALL
LHLD
JMP
MOV
INX
MOV
LHLD
PUSH
MOV
XRA
MOV
DAD
JM
XRA
JM
XCHG
LHLD
MOV
INX
MOV
LHLD
POP

;THE OTHER HALF?
;YES, FOUND ONE

H,0H
SP
B,H
C,L
H,0AH
D
MVDOWN

;TRY TO MOVE SP

LOPPT

;AND PURGE 10 WORDS
;IN THE STACK
;JOB DONE, RESTORE DE

6

;AND CONTINUE

7
QWHAT
VARNXT
D

;GET ADDRESS OF VAR.
;NO VARIABLE, "WHAT?"
;YES, SAVE IT
;SAVE TEXT POINTER

LOPVAR
A,H
L
AWHAT
4
NX3
D
POPA
VARNXT
NX0
E,M
H
D,M
LOPINC
H
A,H
D
A,D
D
NX4
H
NX5

;GET VAR. IN 'FOR'

LOPVAR
M,E
H
M,D
LOPLMT
PSW

;PUT IT BACK

;0 SAYS NEVER HAD ONE
;SO WE ASK: "WHAT?"
;ELSE WE CHECK THEM
;OK, THEY AGREE
;NO, LET'S SEE
;PURGE CURRENT LOOP
;AND POP ONE LEVEL
;GO CHECK AGAIN
;COME HERE WHEN AGREED
;DE=VALUE OF VAR.

;ADD ONE STEP

;HL­>LIMIT
;OLD HL

45

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0293
0294
0297
0298
029B
029C
029F
02A2
02A5
02A8
02A9
02AA
02AB
02AC
02AF

B7
F29802
EB
CD9804
D1
DAAC02
2A0F08
220108
2A1108
EB
F7
E1
D1
CDFD05
F7

NX1:

NX5:
NX2:

ORA
JP
XCHG
CALL
POP
JC
LHLD
SHLD
LHLD
XCHG
RST
POP
POP
CALL
RST

ERRORS = 0
17:09

10/02/2016
PAGE 12

A
NX1
CKHLDE
D
NX2
LOPLN
CURRNT
LOPPT
6
H
D
POPA
6

;STEP > 0
;STEP < 0
;COMPARE WITH LIMIT
;RESTORE TEXT POINTER
;OUTSIDE LIMIT
;WITHIN LIMIT, GO
;BACK TO THE SAVED
;'CURRNT' AND TEXT
;POINTER

;PURGE THIS LOOP

;
;*************************************************************
;
; *** REM *** IF *** INPUT *** & LET (& DEFLT) ***
;
; 'REM' CAN BE FOLLOWED BY ANYTHING AND IS IGNORED BY TBI.
; TBI TREATS IT LIKE AN 'IF' WITH A FALSE CONDITION.
;
; 'IF' IS FOLLOWED BY AN EXPR. AS A CONDITION AND ONE OR MORE
; COMMANDS (INCLUDING OTHER 'IF'S) SEPERATED BY SEMI­COLONS.
; NOTE THAT THE WORD 'THEN' IS NOT USED. TBI EVALUATES THE
; EXPR. IF IT IS NON­ZERO, EXECUTION CONTINUES. IF THE
; EXPR. IS ZERO, THE COMMANDS THAT FOLLOWS ARE IGNORED AND
; EXECUTION CONTINUES AT THE NEXT LINE.
;
; 'INPUT' COMMAND IS LIKE THE 'PRINT' COMMAND, AND IS FOLLOWED
; BY A LIST OF ITEMS. IF THE ITEM IS A STRING IN SINGLE OR
; DOUBLE QUOTES, OR IS A BACK­ARROW, IT HAS THE SAME EFFECT AS
; IN 'PRINT'. IF AN ITEM IS A VARIABLE, THIS VARIABLE NAME IS
; PRINTED OUT FOLLOWED BY A COLON. THEN TBI WAITS FOR AN
; EXPR. TO BE TYPED IN. THE VARIABLE IS THEN SET TO THE
; VALUE OF THIS EXPR. IF THE VARIABLE IS PROCEDED BY A STRING
; (AGAIN IN SINGLE OR DOUBLE QUOTES), THE STRING WILL BE
; PRINTED FOLLOWED BY A COLON. TBI THEN WAITS FOR INPUT EXPR.
; AND SET THE VARIABLE TO THE VALUE OF THE EXPR.
;
; IF THE INPUT EXPR. IS INVALID, TBI WILL PRINT "WHAT?",
; "HOW?" OR "SORRY" AND REPRINT THE PROMPT AND REDO THE INPUT.
; THE EXECUTION WILL NOT TERMINATE UNLESS YOU TYPE CONTROL­C.
; THIS IS HANDLED IN 'INPERR'.
;
; 'LET' IS FOLLOWED BY A LIST OF ITEMS SEPERATED BY COMMAS.
; EACH ITEM CONSISTS OF A VARIABLE, AN EQUAL SIGN, AND AN EXPR.
; TBI EVALUATES THE EXPR. AND SET THE VARIABLE TO THAT VALUE.
; TBI WILL ALSO HANDLE 'LET' COMMAND WITHOUT THE WORD 'LET'.
; THIS IS DONE BY 'DEFLT'.

46

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

02B0
02B3

210000
3E

02B4
02B5
02B6
02B7
02BA
02BD
02C0

DF
7C
B5
C25701
CD5605
D25001
C3BA00

02C3
02C6
02C7
02C8
02CB
02CC

2A0708
F9
E1
220108
D1
D1

02CD
02CD
02CE
02D1
02D4
02D5
02D8
02DB
02DC
02DD
02E0
02E1
02E2
02E3
02E4
02E5
02E8
02E9
02EA
02EB
02EC
02ED
02F0
02F1
02F4
02F7
02FA
02FB
02FE
02FF
0301
0304

D5
CD6C05
C3DB02
FF
DA1503
C3EB02
D5
FF
DAC604
1A
4F
97
12
D1
CD6005
79
1B
12
D5
EB
2A0108
E5
21CD02
220108
210000
39
220708
D5
3E3A
CDFA04
11370F

;
REM:
;
IFF:

ERRORS = 0
17:09

10/02/2016
PAGE 13

LXI
DB

H,0H
3EH

;*** REM ***
;THIS IS LIKE 'IF 0'

RST
MOV
ORA
JNZ
CALL
JNC
JMP

3
A,H
L
RUNSML
FNDSKP
RUNTSL
RSTART

;*** IF ***
;IS THE EXPR.=0?

STKINP

;*** INPERR ***
;RESTORE OLD SP
;AND OLD 'CURRNT'

;
INPERR: LHLD
SPHL
POP
SHLD
POP
POP
;
INPUT:
IP1:
PUSH
CALL
JMP
RST
JC
JMP
IP2:
PUSH
RST
JC
LDAX
MOV
SUB
STAX
POP
CALL
MOV
DCX
STAX
IP3:
PUSH
XCHG
LHLD
PUSH
LXI
SHLD
LXI
DAD
SHLD
PUSH
MVI
CALL
LXI

H
CURRNT
D
D
D
QTSTG
IP2
7
IP4
IP3
D
7
QWHAT
D
C,A
A
D
D
PRTSTG
A,C
D
D
D
CURRNT
H
H,IP1
CURRNT
H,0H
SP
STKINP
D
A,3AH
GETLN
D,BUFFER

;NO, CONTINUE
;YES, SKIP REST OF LINE
;AND RUN THE NEXT LINE
;IF NO NEXT, RE­START

;AND OLD TEXT POINTER
;REDO INPUT
;*** INPUT ***
;SAVE IN CASE OF ERROR
;IS NEXT ITEM A STRING?
;NO
;YES, BUT FOLLOWED BY A
;VARIABLE?
NO.
;YES. INPUT VARIABLE
;SAVE FOR 'PRTSTG'
;MUST BE VARIABLE NOW
;"WHAT?" IT IS NOT?
;GET READY FOR 'PRTSTR'

;PRINT STRING AS PROMPT
;RESTORE TEXT
;SAVE TEXT POINTER
;ALSO SAVE 'CURRNT'
;A NEGATIVE NUMBER
;AS A FLAG
;SAVE SP TOO
;OLD HL
;PRINT THIS TOO
;AND GET A LINE
;POINTS TO BUFFER

47

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0307
0308
0309
030A
030B
030C
030D
030E
030F
0310
0311
0314
0315
0316
0317
0318
0319
031C

DF
00
00
00
D1
EB
73
23
72
E1
220108
D1
F1
CF
2C
03
C3CD02
F7

031D
031E
0320

1A
FE0D
CA2C03

0323
0326
0327
0328
0329
032C

CDA004
CF
2C
03
C32303
F7

IP4:

IP5:
;
DEFLT:
;
LET:

RST
NOP
NOP
NOP
POP
XCHG
MOV
INX
MOV
POP
SHLD
POP
POP
RST
DB
DB
JMP
RST

ERRORS = 0
17:09

10/02/2016
PAGE 14

3

;EVALUATE INPUT
;CAN BE 'CALL ENDCHK'

D

;OK, GET OLD HL

M,E
H
M,D
H
CURRNT
D
PSW
1
','
IP5­$­1
IP1
6

;SAVE VALUE IN VAR.
;GET OLD 'CURRNT'
;AND OLD TEXT POINTER
;PURGE JUNK IN STACK
;IS NEXT CH. ','?
;YES, MORE ITEMS.

LDAX D
CPI CR
JZ
LT1

;*** DEFLT ***
;EMPTY LINE IS OK
;ELSE IT IS 'LET'

CALL
RST
DB
DB
JMP
RST

;*** LET ***
;SET VALUE TO VAR.

SETVAL
1
','
LT1­$­1
LET
6

;ITEM BY ITEM
LT1:
;UNTIL FINISH
;
;*************************************************************
;
; *** EXPR ***
;
; 'EXPR' EVALUATES ARITHMETICAL OR LOGICAL EXPRESSIONS.
; ::
;

; WHERE  IS ONE OF THE OPERATORS IN TAB8 AND THE
; RESULT OF THESE OPERATIONS IS 1 IF TRUE AND 0 IF FALSE.
; ::=(+ OR ­)(+ OR ­)(....)
; WHERE () ARE OPTIONAL AND (....) ARE OPTIONAL REPEATS.
; ::=(* OR />)(....)
; ::=
;

;
()
;  IS RECURSIVE SO THAT VARIABLE '@' CAN HAVE AN 
; AS INDEX, FUNCTIONS CAN HAVE AN  AS ARGUMENTS, AND
;  CAN BE AN  IN PARANTHESE.
;
;EXPR: CALL EXPR2
;THIS IS AT LOC. 18
;
PUSH H
;SAVE  VALUE

48

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

032D
0330
0333
0336
0337
0338
0339
033C
033D
033E
033F
0342
0343
0344
0345
0346
0349
034A
034B
034C
034D
034E
0351
0352
0353
0354
0357
0358
0359
035A
035B
035C
035D
035E
035F
0360
0361
0362
0365
0366
0367
036A
036B
036E
0370

212107
C33B07
CD5C03
D8
6F
C9
CD5C03
C8
6F
C9
CD5C03
C8
D8
6F
C9
CD5C03
6F
C8
D8
6C
C9
CD5C03
C0
6F
C9
CD5C03
D0
6F
C9
E1
C9
79
E1
C1
E5
C5
4F
CD7103
EB
E3
CD9804
D1
210000
3E01
C9

0371
0372
0373
0374
0377

CF
2D
06
210000
C39B03

EXPR1:
XP11:

XP12:

XP13:

XP14:

XP15:

XP16:

XP17:
XP18:

;
EXPR2:

ERRORS = 0
17:09

10/02/2016
PAGE 15

LXI
JMP
CALL
RC
MOV
RET
CALL
RZ
MOV
RET
CALL
RZ
RC
MOV
RET
CALL
MOV
RZ
RC
MOV
RET
CALL
RNZ
MOV
RET
CALL
RNC
MOV
RET
POP
RET
MOV
POP
POP
PUSH
PUSH
MOV
CALL
XCHG
XTHL
CALL
POP
LXI
MVI
RET

H,TAB8­1
EXEC
XP18

RST
DB
DB
LXI
JMP

1
'­'
XP21­$­1
H,0H
XP26

L,A
XP18
L,A
XP18
L,A

;LOOKUP REL.OP.
;GO DO IT
;REL.OP.">="
;NO, RETURN HL=0
;YES, RETURN HL=1
;REL.OP."#"
;FALSE, RETURN HL=0
;TRUE, RETURN HL=1
;REL.OP.">"
;FALSE
;ALSO FALSE, HL=0
;TRUE, HL=1

XP18
L,A

;REL.OP."<="
;SET HL=1
;REL. TRUE, RETURN

L,H

;ELSE SET HL=0

XP18

;REL.OP."="
;FALSE, RETURN HL=0
;ELSE SET HL=1

L,A
XP18
L,A
H
A,C
H
B
H
B
C,A
EXPR2
CKHLDE
D
H,0H
A,1

;REL.OP."<"
;FALSE, RETURN HL=0
;ELSE SET HL=1
;NOT .REL.OP
;RETURN HL=
;SUBROUTINE FOR ALL
;REL.OP.'S
;REVERSE TOP OF STACK
;GET 2ND 
;VALUE IN DE NOW
;1ST  IN HL
;COMPARE 1ST WITH 2ND
;RESTORE TEXT POINTER
;SET HL=0, A=1

;NEGATIVE SIGN?
;YES, FAKE '0­'
;TREAT LIKE SUBTRACT

49

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

037A
037B
037C
037D
0380
0381
0382
0383
0384
0387
0388
0389
038A
038B
038C
038D
038E
0391
0392
0395
0398
0399
039A
039B
039C
039F
03A2

CF
2B
00
CDA503
CF
2B
15
E5
CDA503
EB
E3
7C
AA
7A
19
D1
FA8003
AC
F28003
C39F00
CF
2D
86
E5
CDA503
CD8604
C38703

03A5
03A8
03A9
03AA
03AB
03AC
03AF
03B1
03B4
03B5
03B8
03B9
03BA
03BB
03BC
03BF
03C0
03C1
03C2
03C5
03C6
03C9
03CA

CD0504
CF
2A
2D
E5
CD0504
0600
CD8304
E3
CD8304
EB
E3
7C
B7
CAC503
7A
B2
EB
C2A000
7D
210000
B7
CAF703

XP21:
XP22:
XP23:

XP24:

XP25:
XP26:

;
EXPR3:
XP31:

XP32:

ERRORS = 0
17:09

10/02/2016
PAGE 16

RST
DB
DB
CALL
RST
DB
DB
PUSH
CALL
XCHG
XTHL
MOV
XRA
MOV
DAD
POP
JM
XRA
JP
JMP
RST
DB
DB
PUSH
CALL
CALL
JMP

1
'+'
XP22­$­1
EXPR3
1
'+'
XP25­$­1
H
EXPR3

CALL
RST
DB
DB
PUSH
CALL
MVI
CALL
XTHL
CALL
XCHG
XTHL
MOV
ORA
JZ
MOV
ORA
XCHG
JNZ
MOV
LXI
ORA
JZ

EXPR4
1
'*'
XP34­$­1
H
EXPR4
B,0H
CHKSGN

A,H
D
A,D
D
D
XP23
H
XP23
QHOW
1
'­'
XP42­$­1
H
EXPR3
CHGSGN
XP24

CHKSGN
A,H
A
XP32
A,D
D
AHOW
A,L
H,0H
A
XP35

;POSITIVE SIGN? IGNORE
;1ST 
;ADD?
;YES, SAVE VALUE
;GET 2ND 
;2ND IN DE
;1ST IN HL
;COMPARE SIGN

;RESTORE TEXT POINTER
;1ST AND 2ND SIGN DIFFER
;1ST AND 2ND SIGN EQUAL
;SO IS RESULT
;ELSE WE HAVE OVERFLOW
;SUBTRACT?
;YES, SAVE 1ST 
;GET 2ND 
;NEGATE
;AND ADD THEM
;GET 1ST 
;MULTIPLY?
;YES, SAVE 1ST
;AND GET 2ND 
;CLEAR B FOR SIGN
;CHECK SIGN
;1ST IN HL
;CHECK SIGN OF 1ST
;IS HL > 255 ?
;NO
;YES, HOW ABOUT DE
;PUT SMALLER IN HL
;ALSO >, WILL OVERFLOW
;THIS IS DUMB
;CLEAR RESULT
;ADD AND COUNT

50

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

03CD
03CE
03D1
03D2
03D5
03D8
03D9
03DA
03DB
03DC
03DF
03E1
03E4
03E5
03E8
03E9
03EA
03EB
03EC
03ED
03F0
03F1
03F4
03F5
03F6
03F7
03F8
03F9
03FA
03FD
03FE
03FF
0402

19
DAA000
3D
C2CD03
C3F703
CF
2F
46
E5
CD0504
0600
CD8304
E3
CD8304
EB
E3
EB
7A
B3
CAA000
C5
CD6604
60
69
C1
D1
7C
B7
FA9F00
78
B7
FC8604
C3A803

0405
0408
040B
040C
040F
0410
0411
0412
0413
0414
0417
0418
0419
041A
041B
041C
041D

210107
C33B07
FF
DA1404
7E
23
66
6F
C9
CD7700
78
B7
C0
CF
28
05
DF

XP33:

XP34:

XP35:

;
EXPR4:
XP40:

XP41:

PARN:

ERRORS = 0
17:09

10/02/2016
PAGE 17

DAD
JC
DCR
JNZ
JMP
RST
DB
DB
PUSH
CALL
MVI
CALL
XTHL
CALL
XCHG
XTHL
XCHG
MOV
ORA
JZ
PUSH
CALL
MOV
MOV
POP
POP
MOV
ORA
JM
MOV
ORA
CM
JMP

D
AHOW
A
XP33
XP35
1
'/'
XP42­$­1
H
EXPR4
B,0H
CHKSGN

A,D
E
AHOW
B
DIVIDE
H,B
L,C
B
D
A,H
A
QHOW
A,B
A
CHGSGN
XP31

;DIVIDE BY 0?

LXI
JMP
RST
JC
MOV
INX
MOV
MOV
RET
CALL
MOV
ORA
RNZ
RST
DB
DB
RST

H,TAB4­1
EXEC
7
XP41
A,M
H
H,M
L,A

;FIND FUNCTION IN TAB4
;AND GO DO IT
;NO, NOT A FUNCTION
;NOR A VARIABLE
;VARIABLE

TSTNUM
A,B
A

;OR IS IT A NUMBER
;# OF DIGIT

CHKSGN

;OVERFLOW
;FINISHED
;DIVIDE?
;YES, SAVE 1ST 
;AND GET THE SECOND ONE
;CLEAR B FOR SIGN
;CHECK SIGN OF 2ND
;GET 1ST IN HL
;CHECK SIGN OF 1ST

;SAY "HOW?"
;ELSE SAVE SIGN
;USE SUBROUTINE
;RESULT IN HL NOW
;GET SIGN BACK
;AND TEXT POINTER
;HL MUST BE +
;ELSE IT IS OVERFLOW
;CHANGE SIGN IF NEEDED
;LOOK FOR MORE TERMS

;VALUE IN HL

;OK
1
'('
XP43­$­1
3

;"(EXPR)"

51

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

041E
041F
0420
0421
0422

CF
29
01
C9
C3C604

0425
0428
0429
042A
042D
042E
0431
0432
0433
0436
0439
043A
043D
0440
0441
0442
0443
0446
0447
0448
0449
044C
044D
044E
044F

CD1A04
7C
B7
FA9F00
B5
CA9F00
D5
E5
2A1308
116907
E7
DA4004
210000
5E
23
56
221308
E1
EB
C5
CD6604
C1
D1
23
C9

0450
0453
0454
0457
0458

CD1A04
1B
CD8304
13
C9

0459
045C
045D
045E
0461
0464
0465

2A1508
D5
EB
21000F
CD7C04
D1
C9

XP42:
XP43:
;
RND:

RA1:

;
ABS:

;
SIZE:

ERRORS = 0
17:09

10/02/2016
PAGE 18

RST
DB
DB
RET
JMP

1
')'
XP43­$­1
QWHAT

;ELSE SAY: "WHAT?"

CALL
MOV
ORA
JM
ORA
JZ
PUSH
PUSH
LHLD
LXI
RST
JC
LXI
MOV
INX
MOV
SHLD
POP
XCHG
PUSH
CALL
POP
POP
INX
RET

PARN
A,H
A
QHOW
L
QHOW
D
H
RANPNT
D,LSTROM
4
RA1
H,START
E,M
H
D,M
RANPNT
H

;*** RND(EXPR) ***
;EXPR MUST BE +

CALL
DCX
CALL
INX
RET

PARN
D
CHKSGN
D

;*** ABS(EXPR) ***

LHLD
PUSH
XCHG
LXI
CALL
POP
RET

TXTUNF
D

;*** SIZE ***
;GET THE NUMBER OF FREE
;BYTES BETWEEN 'TXTUNF'
;AND 'VARBGN'

B
DIVIDE
B
D
H

H,VARBGN
SUBDE
D

;AND NON­ZERO
;SAVE BOTH
;GET MEMORY AS RANDOM
;NUMBER
;WRAP AROUND IF LAST

;RND(N)=MOD(M,N)+1

;CHECK SIGN

;
;*************************************************************
;
; *** DIVIDE *** SUBDE *** CHKSGN *** CHGSGN *** & CKHLDE ***
;
; 'DIVIDE' DIVIDES HL BY DE, RESULT IN BC, REMAINDER IN HL

52

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0466
0467
0468
046A
046D
046E
046F
0470
0471
0473
0474
0477
047A
047B

E5
6C
2600
CD7104
41
7D
E1
67
0EFF
0C
CD7C04
D27304
19
C9

047C
047D
047E
047F
0480
0481
0482

7D
93
6F
7C
9A
67
C9

0483
0484
0485

7C
B7
F0

0486
0487
0488
0489
048A
048B
048C
048D
048E
048F
0490
0493

7C
F5
2F
67
7D
2F
6F
23
F1
AC
F29F00
78

ERRORS = 0
17:09

10/02/2016
PAGE 19

;
; 'SUBDE' SUBSTRACTS DE FROM HL
;
; 'CHKSGN' CHECKS SIGN OF HL. IF +, NO CHANGE. IF ­, CHANGE
; SIGN AND FLIP SIGN OF B.
;
; 'CHGSGN' CHECKS SIGN N OF HL AND B UNCONDITIONALLY.
;
; 'CKHLDE' CHECKS SIGN OF HL AND DE. IF DIFFERENT, HL AND DE
; ARE INTERCHANGED. IF SAME SIGN, NOT INTERCHANGED. EITHER
; CASE, HL DE ARE THEN COMPARED TO SET THE FLAGS.
;
DIVIDE: PUSH H
;*** DIVIDE ***
MOV L,H
;DIVIDE H BY DE
MVI H,0
CALL DV1
MOV B,C
;SAVE RESULT IN B
MOV A,L
;(REMINDER+L)/DE
POP H
MOV H,A
DV1:
MVI C,0FFH
;RESULT IN C
DV2:
INR C
;DUMB ROUTINE
CALL SUBDE
;DIVIDE BY SUBTRACT
JNC DV2
;AND COUNT
DAD D
RET
;
SUBDE: MOV A,L
;*** SUBDE ***
SUB E
;SUBSTRACT DE FROM
MOV L,A
;HL
MOV A,H
SBB D
MOV H,A
RET
;
CHKSGN: MOV A,H
;*** CHKSGN ***
ORA A
;CHECK SIGN OF HL
RP
;IF ­, CHANGE SIGN
;
CHGSGN: MOV A,H
;*** CHGSGN ***
PUSH PSW
CMA
;CHANGE SIGN OF HL
MOV H,A
MOV A,L
CMA
MOV L,A
INX H
POP PSW
XRA H
JP
QHOW
MOV A,B
;AND ALSO FLIP B

53

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0494
0496
0497

EE80
47
C9

0498
0499
049A
049D
049E
049F

7C
AA
F29E04
EB
E7
C9

04A0
04A1
04A4
04A5
04A6
04A7
04A8
04A9
04AA

FF
DAC604
E5
CF
3D
08
DF
44
4D

XRI
MOV
RET

ERRORS = 0
17:09

10/02/2016
PAGE 20

80H
B,A

;
CKHLDE: MOV A,H
XRA D
;SAME SIGN?
JP
CK1
;YES, COMPARE
XCHG
;NO, XCH AND COMP
CK1:
RST 4
RET
;
;*************************************************************
;
; *** SETVAL *** FIN *** ENDCHK *** & ERROR (& FRIENDS) ***
;
; "SETVAL" EXPECTS A VARIABLE, FOLLOWED BY AN EQUAL SIGN AND
; THEN AN EXPR. IT EVALUATES THE EXPR. AND SET THE VARIABLE
; TO THAT VALUE.
;
; "FIN" CHECKS THE END OF A COMMAND. IF IT ENDED WITH ";",
; EXECUTION CONTINUES. IF IT ENDED WITH A CR, IT FINDS THE
; NEXT LINE AND CONTINUE FROM THERE.
;
; "ENDCHK" CHECKS IF A COMMAND IS ENDED WITH CR. THIS IS
; REQUIRED IN CERTAIN COMMANDS. (GOTO, RETURN, AND STOP ETC.)
;
; "ERROR" PRINTS THE STRING POINTED BY DE (AND ENDS WITH CR).
; IT THEN PRINTS THE LINE POINTED BY 'CURRNT' WITH A "?"
; INSERTED AT WHERE THE OLD TEXT POINTER (SHOULD BE ON TOP
; OF THE STACK) POINTS TO. EXECUTION OF TB IS STOPPED
; AND TBI IS RESTARTED. HOWEVER, IF 'CURRNT' ­> ZERO
; (INDICATING A DIRECT COMMAND), THE DIRECT COMMAND IS NOT
; PRINTED. AND IF 'CURRNT' ­> NEGATIVE # (INDICATING 'INPUT'
; COMMAND), THE INPUT LINE IS NOT PRINTED AND EXECUTION IS
; NOT TERMINATED BUT CONTINUED AT 'INPERR'.
;
; RELATED TO 'ERROR' ARE THE FOLLOWING:
; 'QWHAT' SAVES TEXT POINTER IN STACK AND GET MESSAGE "WHAT?"
; 'AWHAT' JUST GET MESSAGE "WHAT?" AND JUMP TO 'ERROR'.
; 'QSORRY' AND 'ASORRY' DO SAME KIND OF THING.
; 'AHOW' AND 'AHOW' IN THE ZERO PAGE SECTION ALSO DO THIS.
;
SETVAL: RST 7
;*** SETVAL ***
JC
QWHAT
;"WHAT?" NO VARIABLE
PUSH H
;SAVE ADDRESS OF VAR.
RST 1
;PASS "=" SIGN
DB
'='
DB
SV1­$­1
RST 3
;EVALUATE EXPR.
MOV B,H
;VALUE IS IN BC NOW
MOV C,L

54

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

04AB
04AC
04AD
04AE
04AF
04B0

E1
71
23
70
C9
C3C604

04B3
04B4
04B5
04B6
04B7
04BA
04BB
04BC
04BD
04BE
04C1

CF
3B
04
F1
C35701
CF
0D
04
F1
C34701
C9

04C2
04C3
04C5

EF
FE0D
C8

04C6
04C7
04CA
04CB
04CE
04CF
04D0
04D1
04D2
04D3
04D6
04D7
04D8
04D9
04DA
04DB
04DE
04DF
04E0
04E3
04E6
04E7
04E8
04E9
04EB
04EC
04ED
04F0

D5
11AE00
97
CD6005
D1
1A
F5
97
12
2A0108
E5
7E
23
B6
D1
CABA00
7E
B7
FAC302
CDD205
1B
F1
12
3E3F
D7
97
CD6005
C3BA00

SV1:
;
FIN:

FI1:

ERRORS = 0
17:09

10/02/2016
PAGE 21

POP
MOV
INX
MOV
RET
JMP

H
M,C
H
M,B

;GET ADDRESS
;SAVE VALUE

QWHAT

;NO "=" SIGN

RST
DB
DB
POP
JMP
RST
DB
DB
POP
JMP
RET

1
3BH
FI1­$­1
PSW
RUNSML
1
CR
FI2­$­1
PSW
RUNNXL

;*** FIN ***

5
CR

;*** ENDCHK ***
;END WITH CR?
;OK, ELSE SAY: "WHAT?"

D
D,WHAT
A
PRTSTG
D
D
PSW
A
D
CURRNT
H
A,M
H
M
D
RSTART
A,M
A
INPERR
PRTLN
D
PSW
D
A,3FH
2
A
PRTSTG
RSTART

;*** QWHAT ***
;*** AWHAT ***
;*** ERROR ***
;PRINT 'WHAT?', 'HOW?'
;OR 'SORRY'
;SAVE THE CHARACTER
;AT WHERE OLD DE ­>
;AND PUT A 0 THERE

FI2:
;
ENDCHK: RST
CPI
RZ
;
QWHAT: PUSH
AWHAT: LXI
ERROR: SUB
CALL
POP
LDAX
PUSH
SUB
STAX
LHLD
PUSH
MOV
INX
ORA
POP
JZ
MOV
ORA
JM
CALL
DCX
POP
STAX
MVI
RST
SUB
CALL
JMP

;";", PURGE RET. ADDR.
;CONTINUE SAME LINE
;NOT ";", IS IT CR?
;YES, PURGE RET. ADDR.
;RUN NEXT LINE
;ELSE RETURN TO CALLER

;GET CURRENT LINE #
;CHECK THE VALUE

;IF ZERO, JUST RESTART
;IF NEGATIVE,
;REDO INPUT
;ELSE PRINT THE LINE
;UPTO WHERE THE 0 IS
;RESTORE THE CHARACTER
;PRINT A "?"
;AND THE REST OF THE
;LINE
;THEN RESTART

55

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

04F3
04F4
04F7

D5
11B400
C3CA04

04FA
04FB
04FE
0501
0504
0506
0509
050A
050C
050F
0510
0513
0515
0518
0519
051A
051C
051D
051E

D7
11370F
CD8406
CAFE04
FE7F
CA2305
D7
FE0A
CAFE04
B7
CAFE04
FE7D
CA3005
12
13
FE0D
C8
7B
FE77

ERRORS = 0
17:09

10/02/2016
PAGE 22

;
QSORRY: PUSH D
;*** QSORRY ***
ASORRY: LXI D,SORRY
;*** ASORRY ***
JMP ERROR
;
;*************************************************************
;
; *** GETLN *** FNDLN (& FRIENDS) ***
;
; 'GETLN' READS A INPUT LINE INTO 'BUFFER'. IT FIRST PROMPT
; THE CHARACTER IN A (GIVEN BY THE CALLER), THEN IT FILLS
; THE BUFFER AND ECHOS. IT IGNORES LF'S AND NULLS, BUT STILL
; ECHOS THEM BACK. RUB­OUT IS USED TO CAUSE IT TO DELETE
; THE LAST CHARACTER (IF THERE IS ONE), AND ALT­MOD IS USED TO
; CAUSE IT TO DELETE THE WHOLE LINE AND START IT ALL OVER.
; CR SIGNALS THE END OF A LINE, AND CAUSE 'GETLN' TO RETURN.
;
; 'FNDLN' FINDS A LINE WITH A GIVEN LINE # (IN HL) IN THE
; TEXT SAVE AREA. DE IS USED AS THE TEXT POINTER. IF THE
; LINE IS FOUND, DE WILL POINT TO THE BEGINNING OF THAT LINE
; (I.E., THE LOW BYTE OF THE LINE #), AND FLAGS ARE NC & Z.
; IF THAT LINE IS NOT THERE AND A LINE WITH A HIGHER LINE #
; IS FOUND, DE POINTS TO THERE AND FLAGS ARE NC & NZ. IF
; WE REACHED THE END OF TEXT SAVE AREA AND CANNOT FIND THE
; LINE, FLAGS ARE C & NZ.
; 'FNDLN' WILL INITIALIZE DE TO THE BEGINNING OF THE TEXT SAVE
; AREA TO START THE SEARCH. SOME OTHER ENTRIES OF THIS
; ROUTINE WILL NOT INITIALIZE DE AND DO THE SEARCH.
; 'FNDLNP' WILL START WITH DE AND SEARCH FOR THE LINE #.
; 'FNDNXT' WILL BUMP DE BY 2, FIND A CR AND THEN START SEARCH.
; 'FNDSKP' USE DE TO FIND A CR, AND THEN START SEARCH.
;
GETLN: RST 2
;*** GETLN ***
LXI D,BUFFER
;PROMPT AND INIT.
GL1:
CALL CHKIO
;CHECK KEYBOARD
JZ
GL1
;NO INPUT, WAIT
CPI 7FH
;DELETE LAST CHARACTER?
JZ
GL3
;YES
RST 2
;INPUT, ECHO BACK
CPI 0AH
;IGNORE LF
JZ
GL1
ORA A
;IGNORE NULL
JZ
GL1
CPI 7DH
;DELETE THE WHOLE LINE?
JZ
GL4
;YES
STAX D
;ELSE SAVE INPUT
INX D
;AND BUMP POINTER
CPI 0DH
;WAS IT CR?
RZ
;YES, END OF LINE
MOV A,E
;ELSE MORE FREE ROOM?
CPI BUFEND AND 0FFH

56

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0520
0523
0524
0526
0529
052A
052C
052D
0530
0533
0535

C2FE04
7B
FE37
CA3005
1B
3E5C
D7
C3FE04
CD0E00
3E5E
C3FA04

0538
0539
053A
053D

7C
B7
FA9F00
111708

0540
0540
0541
0544
0545
0546
0547
0548
0549
054A
054B
054C
054D
054E
0551
0552
0553

E5
2A1508
2B
E7
E1
D8
1A
95
47
13
1A
9C
DA5505
1B
B0
C9

GL3:

GL4:
;
FNDLN:

;
FNDLP:
FL1:

ERRORS = 0
17:09

PAGE 23

JNZ
MOV
CPI
JZ
DCX
MVI
RST
JMP
CALL
MVI
JMP

GL1
A,E
BUFFER AND 0FFH
GL4
D
A,5CH
2
GL1
CRLF
A,05EH
GETLN

;YES, GET NEXT INPUT
;DELETE LAST CHARACTER
;BUT DO WE HAVE ANY?
;NO, REDO WHOLE LINE
;YES, BACKUP POINTER
;AND ECHO A BACK­SLASH

MOV
ORA
JM
LXI

A,H
A
QHOW
D,TXTBGN

;*** FNDLN ***
;CHECK SIGN OF HL
;IT CANNOT BE ­
;INIT TEXT POINTER

PUSH
LHLD
DCX
RST
POP
RC
LDAX
SUB
MOV
INX
LDAX
SBB
JC
DCX
ORA
RET

H
TXTUNF
H
4
H

INX
INX

D
D

D
L
B,A
D
D
H
FL2
D
B

;
FNDNXT:

0554
0554
0555

13
13

0556
0557
0559
055C
055D

1A
FE0D
C25505
13
C34005

10/02/2016

;GO GET NEXT INPUT
;REDO ENTIRE LINE
;CR, LF AND UP­ARROW

;*** FDLNP ***
;SAVE LINE #
;CHECK IF WE PASSED END
;GET LINE # BACK
;C,NZ PASSED END
;WE DID NOT, GET BYTE 1
;IS THIS THE LINE?
;COMPARE LOW ORDER
;GET BYTE 2
;COMPARE HIGH ORDER
;NO, NOT THERE YET
;ELSE WE EITHER FOUND
;IT, OR IT IS NOT THERE
;NC,Z:FOUND, NC,NZ:NO
;*** FNDNXT ***
;FIND NEXT LINE
;JUST PASSED BYTE 1 & 2

FL2:
;
FNDSKP: LDAX D
;*** FNDSKP ***
CPI CR
;TRY TO FIND CR
JNZ FL2
;KEEP LOOKING
INX D
;FOUND CR, SKIP OVER
JMP FL1
;CHECK IF END OF TEXT
;
;*************************************************************
;
; *** PRTSTG *** QTSTG *** PRTNUM *** & PRTLN ***
;
; 'PRTSTG' PRINTS A STRING POINTED BY DE. IT STOPS PRINTING
; AND RETURNS TO CALLER WHEN EITHER A CR IS PRINTED OR WHEN

57

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0560
0561
0562
0563
0564
0565
0566
0568
056B

47
1A
13
B8
C8
D7
FE0D
C26105
C9

056C
056D
056E
056F
0571
0574
0576
0577
057A
057B
057C
057D
057E
057F
0580
0581
0583
0586
0587
0588
0589
058B
058C

CF
22
0F
3E22
CD6005
FE0D
E1
CA4701
23
23
23
E9
CF
27
05
3E27
C37105
CF
5F
08
3E8D
D7
D7

ERRORS = 0
17:09

10/02/2016
PAGE 24

; THE NEXT BYTE IS THE SAME AS WHAT WAS IN A (GIVEN BY THE
; CALLER). OLD A IS STORED IN B, OLD B IS LOST.
;
; 'QTSTG' LOOKS FOR A BACK­ARROW, SINGLE QUOTE, OR DOUBLE
; QUOTE. IF NONE OF THESE, RETURN TO CALLER. IF BACK­ARROW,
; OUTPUT A CR WITHOUT A LF. IF SINGLE OR DOUBLE QUOTE, PRINT
; THE STRING IN THE QUOTE AND DEMANDS A MATCHING UNQUOTE.
; AFTER THE PRINTING THE NEXT 3 BYTES OF THE CALLER IS SKIPPED
; OVER (USUALLY A JUMP INSTRUCTION.
;
; 'PRTNUM' PRINTS THE NUMBER IN HL. LEADING BLANKS ARE ADDED
; IF NEEDED TO PAD THE NUMBER OF SPACES TO THE NUMBER IN C.
; HOWEVER, IF THE NUMBER OF DIGITS IS LARGER THAN THE # IN
; C, ALL DIGITS ARE PRINTED ANYWAY. NEGATIVE SIGN IS ALSO
; PRINTED AND COUNTED IN, POSITIVE SIGN IS NOT.
;
; 'PRTLN' PRINTS A SAVED TEXT LINE WITH LINE # AND ALL.
;
PRTSTG: MOV B,A
;*** PRTSTG ***
PS1:
LDAX D
;GET A CHARACTER
INX D
;BUMP POINTER
CMP B
;SAME AS OLD A?
RZ
;YES, RETURN
RST 2
;ELSE PRINT IT
CPI CR
;WAS IT A CR?
JNZ PS1
;NO, NEXT
RET
;YES, RETURN
;
QTSTG: RST 1
;*** QTSTG ***
DB
'"'
DB
QT3­$­1
MVI A,22H
;IT IS A "
QT1:
CALL PRTSTG
;PRINT UNTIL ANOTHER
CPI CR
;WAS LAST ONE A CR?
POP H
;RETURN ADDRESS
JZ
RUNNXL
;WAS CR, RUN NEXT LINE
QT2:
INX H
;SKIP 3 BYTES ON RETURN
INX H
INX H
PCHL
;RETURN
QT3:
RST 1
;IS IT A '?
DB
27H
DB
QT4­$­1
MVI A,27H
;YES, DO THE SAME
JMP QT1
;AS IN "
QT4:
RST 1
;IS IT BACK­ARROW?
DB
5FH
DB
QT5­$­1
MVI A,08DH
;YES, CR WITHOUT LF
RST 2
;DO IT TWICE TO GIVE
RST 2
;TTY ENOUGH TIME

58

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

058D
058E
0591

E1
C37A05
C9

0592
0594
0597
059A
059C
059D
059E
05A1
05A2
05A3
05A4
05A7
05A8
05A9
05AC
05AD
05AE
05AF
05B0
05B1
05B4
05B5
05B6
05B7
05B8
05BB
05BD
05BE
05C1
05C2
05C3
05C6
05C7
05C8
05CA
05CB
05CC
05CE
05CF

0600
CD8304
F29D05
062D
0D
D5
110A00
D5
0D
C5
CD6604
78
B1
CAB405
E3
2D
E5
60
69
C3A405
C1
0D
79
B7
FAC105
3E20
D7
C3B505
78
B7
C41000
5D
7B
FE0A
D1
C8
C630
D7
C3C705

05D2
05D3
05D4
05D5
05D6
05D7
05D8

1A
6F
13
1A
67
13
0E04

POP
JMP
RET

QT5:
;
PRTNUM: MVI
CALL
JP
MVI
DCR
PN1:
PUSH
LXI
PUSH
DCR
PUSH
PN2:
CALL
MOV
ORA
JZ
XTHL
DCR
PUSH
MOV
MOV
JMP
PN3:
POP
PN4:
DCR
MOV
ORA
JM
MVI
RST
JMP
PN5:
MOV
ORA
CNZ
MOV
PN6:
MOV
CPI
POP
RZ
ADI
RST
JMP
;
PRTLN: LDAX
MOV
INX
LDAX
MOV
INX
MVI

ERRORS = 0
17:09

10/02/2016
PAGE 25

H
QT2

;RETURN ADDRESS
;NONE OF ABOVE

B,0
CHKSGN
PN1
B,'­'
C
D
D,0AH
D
C
B
DIVIDE
A,B
C
PN3
L
H
H,B
L,C
PN2
B
C
A,C
A
PN5
A,20H
2
PN4
A,B
A
10H
E,L
A,E
0AH
D
30H
2
PN6
D
L,A
D
D
H,A
D
C,4H

;*** PRTNUM ***
;CHECK SIGN
;NO SIGN
;B=SIGN
;'­' TAKES SPACE
;SAVE
;DECIMAL
;SAVE AS A FLAG
;C=SPACES
;SAVE SIGN & SPACE
;DIVIDE HL BY 10
;RESULT 0?
;YES, WE GOT ALL
;NO, SAVE REMAINDER
;AND COUNT SPACE
;HL IS OLD BC
;MOVE RESULT TO BC
;AND DIVIDE BY 10
;WE GOT ALL DIGITS IN
;THE STACK
;LOOK AT SPACE COUNT
;NO LEADING BLANKS
;LEADING BLANKS
;MORE?
;PRINT SIGN
;LAST REMAINDER IN E
;CHECK DIGIT IN E
;10 IS FLAG FOR NO MORE
;IF SO, RETURN
;ELSE CONVERT TO ASCII
;AND PRINT THE DIGIT
;GO BACK FOR MORE
;*** PRTLN ***
;LOW ORDER LINE #
;HIGH ORDER
;PRINT 4 DIGIT LINE #

59

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

05DA
05DD
05DF
05E0
05E1
05E4

CD9205
3E20
D7
97
CD6005
C9

05E5
05E6
05E7
05E8
05E9
05EA
05EB

E7
C8
1A
02
13
03
C3E505

05EE
05EF
05F0
05F3
05F4
05F5
05F6
05F7
05F8
05F9
05FA

78
92
C2F605
79
93
C8
1B
2B
1A
77
C3EE05

05FD
05FE
05FF
0602
0603
0604
0607
0608

C1
E1
220908
7C
B5
CA1706
E1
220B08

CALL
MVI
RST
SUB
CALL
RET

ERRORS = 0
17:09

10/02/2016
PAGE 26

PRTNUM
A,20H
2
A
PRTSTG

;FOLLOWED BY A BLANK
;AND THEN THE NEXT

;
;*************************************************************
;
; *** MVUP *** MVDOWN *** POPA *** & PUSHA ***
;
; 'MVUP' MOVES A BLOCK UP FROM WHERE DE­> TO WHERE BC­> UNTIL
; DE = HL
;
; 'MVDOWN' MOVES A BLOCK DOWN FROM WHERE DE­> TO WHERE HL­>
; UNTIL DE = BC
;
; 'POPA' RESTORES THE 'FOR' LOOP VARIABLE SAVE AREA FROM THE
; STACK
;
; 'PUSHA' STACKS THE 'FOR' LOOP VARIABLE SAVE AREA INTO THE
; STACK
;
MVUP:
RST 4
;*** MVUP ***
RZ
;DE = HL, RETURN
LDAX D
;GET ONE BYTE
STAX B
;MOVE IT
INX D
;INCREASE BOTH POINTERS
INX B
JMP MVUP
;UNTIL DONE
;
MVDOWN: MOV A,B
;*** MVDOWN ***
SUB D
;TEST IF DE = BC
JNZ MD1
;NO, GO MOVE
MOV A,C
;MAYBE, OTHER BYTE?
SUB E
RZ
;YES, RETURN
MD1:
DCX D
;ELSE MOVE A BYTE
DCX H
;BUT FIRST DECREASE
LDAX D
;BOTH POINTERS AND
MOV M,A
;THEN DO IT
JMP MVDOWN
;LOOP BACK
;
POPA:
POP B
;BC = RETURN ADDR.
POP H
;RESTORE LOPVAR, BUT
SHLD LOPVAR
;=0 MEANS NO MORE
MOV A,H
ORA L
JZ
PP1
;YEP, GO RETURN
POP H
;NOP, RESTORE OTHERS
SHLD LOPINC

60

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

060B
060C
060F
0610
0613
0614
0617
0618

E1
220D08
E1
220F08
E1
221108
C5
C9

0619
061C
061F
0620
0621
0624
0627
0628
0629
062C
062F
0630
0633
0634
0637
0638
063B
063C
063F
0640
0641

21780F
CD8604
C1
39
D2F304
2A0908
7C
B5
CA3F06
2A1108
E5
2A0F08
E5
2A0D08
E5
2A0B08
E5
2A0908
E5
C5
C9

PP1:
;
PUSHA:

PU1:

ERRORS = 0
17:09

10/02/2016
PAGE 27

POP
SHLD
POP
SHLD
POP
SHLD
PUSH
RET

H
LOPLMT
H
LOPLN
H
LOPPT
B

LXI
CALL
POP
DAD
JNC
LHLD
MOV
ORA
JZ
LHLD
PUSH
LHLD
PUSH
LHLD
PUSH
LHLD
PUSH
LHLD
PUSH
PUSH
RET

H,STKLMT
CHGSGN
B
SP
QSORRY
LOPVAR
A,H
L
PU1
LOPPT
H
LOPLN
H
LOPLMT
H
LOPINC
H
LOPVAR
H
B

;BC = RETURN ADDR.
;*** PUSHA ***
;BC=RETURN ADDRESS
;IS STACK NEAR THE TOP?
;YES, SORRY FOR THAT
;ELSE SAVE LOOP VAR'S
;BUT IF LOPVAR IS 0
;THAT WILL BE ALL
;ELSE, MORE TO SAVE

;BC = RETURN ADDR.

;
;*************************************************************
;
; *** OUTC *** & CHKIO ***
;
; THESE ARE THE ONLY I/O ROUTINES IN TBI.
; 'OUTC' IS CONTROLLED BY A SOFTWARE SWITCH 'OCSW'. IF OCSW=0
; 'OUTC' WILL JUST RETURN TO THE CALLER. IF OCSW IS NOT 0,
; IT WILL OUTPUT THE BYTE IN A. IF THAT IS A CR, A LF IS ALSO
; SEND OUT. ONLY THE FLAGS MAY BE CHANGED AT RETURN. ALL REG.
; ARE RESTORED.
;
; 'CHKIO' CHECKS THE INPUT. IF NO INPUT, IT WILL RETURN TO
; THE CALLER WITH THE Z FLAG SET. IF THERE IS INPUT, Z FLAG
; IS CLEARED AND THE INPUT BYTE IS IN A. HOWEVER, IF THE
; INPUT IS A CONTROL­O, THE 'OCSW' SWITCH IS COMPLIMENTED, AND
; Z FLAG IS RETURNED. IF A CONTROL­C IS READ, 'CHKIO' WILL
; RESTART TBI AND DO NOT RETURN TO THE CALLER.
;
;OUTC: PUSH PSW
;THIS IS AT LOC. 10
;
LDA OCSW
;CHECK SOFTWARE SWITCH

61

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

;
INIT:

0642
0645
0647
0649
064B
064D
064F
064F
0652
0653
0656
0657
065A
065D
0660
0663
0666
0669
066C
066F
0670
0671
0673
0675
0678
0679
067B
067D
067E
0680
0681
0683

320008
3E4E
D303
3E37
D303
1619

0684
0686
0687
0689
068A
068C
068E
0690
0693
0696
0697
069A
069D
069F
06A0

DB03
00
E602
C8
DB02
E67F
FE0F
C29D06
3A0008
2F
320008
C38406
FE03
C0
C3BA00

06A3

;
54494E59 MSG1:

ERRORS = 0
17:09

10/02/2016
PAGE 28

ORA
STA
MVI
OUT
MVI
OUT
MVI

A
OCSW
A,4EH
3
A,37H
3
D,19H

CALL
DCR
JNZ
SUB
LXI
CALL
LXI
SHLD
LXI
SHLD
JMP
JNZ
POP
RET
IN
ANI
JZ
POP
OUT
CPI
RNZ
MVI
RST
MVI
RET

CRLF
D
PATLOP
A
D,MSG1
PRTSTG
H,START
RANPNT
H,TXTBGN
TXTUNF
RSTART
OC3
PSW

IN
NOP
ANI
RZ
IN
ANI
CPI
JNZ
LDA
CMA
STA
JMP
CPI
RNZ
JMP

3

;Initialize 8251A UART ­­ 3 is status port
;1 stop bit, no parity, 8­bit char, 16x baud
;enable receive and transmit

PATLOP:
CD0E00
15
C24F06
97
11A306
CD6005
210000
221308
211708
221508
C3BA00
C27106
F1
C9
DB03
E601
CA7106
F1
D302
FE0D
C0
3E0A
D7
3E0D
C9

OC2:
OC3:

;
CHKIO:

CI1:

DB

3
1H
OC3
PSW
2
CR
A,LF
2
A,CR

2H
2
7FH
0FH
CI1
OCSW
OCSW
CHKIO
3H
RSTART

;IT IS ON
;IT IS OFF
;RESTORE AF AND RETURN
;Check status
;STATUS BIT
;NOT READY, WAIT
;READY, GET OLD A BACK
;Out to data port
;WAS IT CR?
;NO, FINISHED
;YES, WE SEND LF TOO
;THIS IS RECURSIVE
;GET CR BACK IN A
;*** CHKIO ***
;STATUS BIT FLIPPED?
;MASK STATUS BIT
;NOT READY, RETURN "Z"
;READY, READ DATA
;MASK BIT 7 OFF
;IS IT CONTROL­O?
;NO, MORE CHECKING
;CONTROL­O FLIPS OCSW
;ON TO OFF, OFF TO ON
;GET ANOTHER INPUT
;IS IT CONTROL­C?
;NO, RETURN "NZ"
;YES, RESTART TBI

'TINY '

62

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

06A7
06A8
06AC
06AD

06AE
06AE
06B2 1
06B3 1
06B4
06B7 1
06B8 1
06B9
06BC 1
06BD 1
06BE
06BE
06C2 1
06C3 1
06C4

20
42415349
43
0D

DB

ERRORS = 0
17:09

10/02/2016
PAGE 29

'BASIC'

DB
CR
;
;*************************************************************
;
; *** TABLES *** DIRECT *** & EXEC ***
;
; THIS SECTION OF THE CODE TESTS A STRING AGAINST A TABLE.
; WHEN A MATCH IS FOUND, CONTROL IS TRANSFERED TO THE SECTION
; OF CODE ACCORDING TO THE TABLE.
;
; AT 'EXEC', DE SHOULD POINT TO THE STRING AND HL SHOULD POINT
; TO THE TABLE­1. AT 'DIRECT', DE SHOULD POINT TO THE STRING.
; HL WILL BE SET UP TO POINT TO TAB1­1, WHICH IS THE TABLE OF
; ALL DIRECT AND STATEMENT COMMANDS.
;
; A '.' IN THE STRING WILL TERMINATE THE TEST AND THE PARTIAL
; MATCH WILL BE CONSIDERED AS A MATCH. E.G., 'P.', 'PR.',
; 'PRI.', 'PRIN.', OR 'PRINT' WILL ALL MATCH 'PRINT'.
;
; THE TABLE CONSISTS OF ANY NUMBER OF ITEMS. EACH ITEM
; IS A STRING OF CHARACTERS WITH BIT 7 SET TO 0 AND
; A JUMP ADDRESS STORED HI­LOW WITH BIT 7 OF THE HIGH
; BYTE SET TO 1.
;
; END OF TABLE IS AN ITEM WITH A JUMP ADDRESS ONLY. IF THE
; STRING DOES NOT MATCH ANY OF THE OTHER ITEMS, IT WILL
; MATCH THIS NULL ITEM AS DEFAULT.
;
TAB1:
;DIRECT COMMANDS
4C495354
DB
'LIST'
DWA LIST
81
+
DB
(LIST SHR 8) + 128
6F
+
DB
LIST AND 0FFH
52554E
DB
'RUN'
DWA RUN
81
+
DB
(RUN SHR 8) + 128
41
+
DB
RUN AND 0FFH
4E4557
DB
'NEW'
DWA NEW
81
+
DB
(NEW SHR 8) + 128
32
+
DB
NEW AND 0FFH
;
TAB2:
;DIRECT/STATEMENT
4E455854
DB
'NEXT'
DWA NEXT
82
+
DB
(NEXT SHR 8) + 128
57
+
DB
NEXT AND 0FFH
4C4554
DB
'LET'

63

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

06C7 1 83
06C8 1 23
06C9
4946

+
+

06CB 1 82
+
06CC 1 B4
+
06CD
474F544F
06D1 1 81
+
06D2 1 60
+
06D3
474F5355
06D7
42
06D8 1 81
+
06D9 1 BF
+
06DA
52455455
06DE
524E
06E0 1 81
06E1 1 DF
06E2
52454D

+
+

06E5 1 82
06E6 1 B0
06E7
464F52

+
+

06EA 1 81
+
06EB 1 F8
+
06EC
494E5055
06F0
54
06F1 1 82
+
06F2 1 CD
+
06F3
5052494E
06F7
54
06F8 1 81
+
06F9 1 87
+
06FA
53544F50
06FE 1 81
06FF 1 3B

+
+

0700 1 83
0701 1 1D

+
+
;
TAB4:

0702
0702

524E44

0705 1 84

+

ERRORS = 0
17:09

10/02/2016
PAGE 30

DWA
DB
DB
DB
DWA
DB
DB
DB
DWA
DB
DB
DB

LET
(LET SHR 8) + 128
LET AND 0FFH
'IF'
IFF
(IFF SHR 8) + 128
IFF AND 0FFH
'GOTO'
GOTO
(GOTO SHR 8) + 128
GOTO AND 0FFH
'GOSUB'

DWA
DB
DB
DB

GOSUB
(GOSUB SHR 8) + 128
GOSUB AND 0FFH
'RETURN'

DWA
DB
DB
DB
DWA
DB
DB
DB
DWA
DB
DB
DB

RETURN
(RETUR SHR 8) + 128
RETUR AND 0FFH
'REM'
REM
(REM SHR 8) + 128
REM AND 0FFH
'FOR'
FOR
(FOR SHR 8) + 128
FOR AND 0FFH
'INPUT'

DWA
DB
DB
DB

INPUT
(INPUT SHR 8) + 128
INPUT AND 0FFH
'PRINT'

DWA
DB
DB
DB
DWA
DB
DB
DWA
DB
DB

PRINT
(PRINT SHR 8) + 128
PRINT AND 0FFH
'STOP'
STOP
(STOP SHR 8) + 128
STOP AND 0FFH
DEFLT
(DEFLT SHR 8) + 128
DEFLT AND 0FFH

DB
DWA
DB

'RND'
RND
(RND SHR 8) + 128

;FUNCTIONS

64

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0706 1 25
0707
414253

+

070A 1 84
+
070B 1 50
+
070C
53495A45
0710 1 84
0711 1 59

+
+

0712 1 84
0713 1 0B

+
+
;
TAB5:

0714
0714

544F

0716 1 82
0717 1 08

+
+

0718 1 84
0719 1 C6
071A
071A

+
+
;
TAB6:
53544550

071E 1 82
071F 1 12

+
+

0720 1 82
0721 1 16

+
+
;
TAB8:

0722
0722

3E3D

0724 1 83
0725 1 33
0726
23

+
+

0727 1 83
0728 1 39
0729
3E

+
+

072A 1 83
072B 1 3F
072C
3D

+
+

072D 1 83
072E 1 4E
072F
3C3D

+
+

0731 1 83

+

ERRORS = 0
17:09

10/02/2016
PAGE 31

DB
DB
DWA
DB
DB
DB
DWA
DB
DB
DWA
DB
DB

RND AND 0FFH
'ABS'
ABS
(ABS SHR 8) + 128
ABS AND 0FFH
'SIZE'
SIZE
(SIZE SHR 8) + 128
SIZE AND 0FFH
XP40
(XP40 SHR 8) + 128
XP40 AND 0FFH

DB
DWA
DB
DB
DWA
DB
DB

'TO'
FR1
(FR1 SHR 8) + 128
FR1 AND 0FFH
QWHAT
(QWHAT SHR 8) + 128
QWHAT AND 0FFH

DB
DWA
DB
DB
DWA
DB
DB

'STEP'
FR2
(FR2 SHR 8) + 128
FR2 AND 0FFH
FR3
(FR3 SHR 8) + 128
FR3 AND 0FFH

DB
DWA
DB
DB
DB
DWA
DB
DB
DB
DWA
DB
DB
DB
DWA
DB
DB
DB
DWA
DB

'>='
XP11
(XP11 SHR 8) +
XP11 AND 0FFH
'#'
XP12
(XP12 SHR 8) +
XP12 AND 0FFH
'>'
XP13
(XP13 SHR 8) +
XP13 AND 0FFH
'='
XP15
(XP15 SHR 8) +
XP15 AND 0FFH
'<='
XP14
(XP14 SHR 8) +

;"TO" IN "FOR"

;"STEP" IN "FOR"

;RELATION OPERATORS
128

128

128

128

128

65

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0732 1 46
0733
3C

+

0734 1 83
0735 1 54

+
+

0736 1 83
0737 1 5A

+
+
;
DIRECT: LXI
;
EXEC:
EX0:
RST
PUSH
EX1:
LDAX
INX
CPI
JZ
INX
CMP
JZ
MVI
DCX
CMP
JC
EX2:
INX
CMP
JNC
INX
POP
JMP
EX3:
MVI
EX4:
INX
CMP
JNC
EX5:
MOV
INX
MOV
ANI
MOV
POP
PCHL
;
LSTROM:
;
ORG
ORG
OCSW:
DS
CURRNT: DS
STKGOS: DS
VARNXT: DS
STKINP: DS

0738

21AD06

073B
073B
073C
073D
073E
073F
0741
0744
0745
0746
0749
074B
074C
074D
0750
0751
0752
0755
0756
0757
075A
075C
075D
075E
0761
0762
0763
0764
0766
0767
0768

EF
D5
1A
13
FE2E
CA5A07
23
BE
CA3D07
3E7F
1B
BE
DA6107
23
BE
D25007
23
D1
C33B07
3E7F
23
BE
D25C07
7E
23
6E
E67F
67
F1
E9

0769
0800
0800
0801
0803
0805
0807

DB
DB
DWA
DB
DB
DWA
DB
DB

ERRORS = 0
17:09

10/02/2016
PAGE 32

XP14 AND 0FFH
'<'
XP16
(XP16 SHR 8) + 128
XP16 AND 0FFH
XP17
(XP17 SHR 8) + 128
XP17 AND 0FFH
H,TAB1­1
5
D
D
D
2EH
EX3
H
M
EX1
A,07FH
D
M
EX5
H
M
EX2
H
D
EX0
A,07FH
H
M
EX4
A,M
H
L,M
7FH
H,A
PSW

1000H
0800H
1
2
2
2
2

;*** DIRECT ***
;*** EXEC ***
;IGNORE LEADING BLANKS
;SAVE POINTER
;IF FOUND '.' IN STRING
;BEFORE ANY MISMATCH
;WE DECLARE A MATCH
;HL­>TABLE
;IF MATCH, TEST NEXT
;ELSE SEE IF BIT 7
;OF TABLE IS SET, WHICH
;IS THE JUMP ADDR. (HI)
;C:YES, MATCHED
;NC:NO, FIND JUMP ADDR.
;BUMP TO NEXT TAB. ITEM
;RESTORE STRING POINTER
;TEST AGAINST NEXT ITEM
;PARTIAL MATCH, FIND
;JUMP ADDR., WHICH IS
;FLAGGED BY BIT 7
;LOAD HL WITH THE JUMP
;ADDRESS FROM THE TABLE
;MASK OFF BIT 7
;CLEAN UP THE GABAGE
;AND WE GO DO IT
;ALL ABOVE CAN BE ROM
;HERE DOWN MUST BE RAM
;SWITCH FOR OUTPUT
;POINTS TO CURRENT LINE
;SAVES SP IN 'GOSUB'
;TEMP STORAGE
;SAVES SP IN 'INPUT'

66

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

0809
080B
080D
080F
0811
0813
0815
0817
0F00
0F00
0F00
0F37
0F77
0F78
1000
1000
000D
000A

LOPVAR:
LOPINC:
LOPLMT:
LOPLN:
LOPPT:
RANPNT:
TXTUNF:
TXTBGN:
;
;
TXTEND:
VARBGN:
BUFFER:
BUFEND:
STKLMT:
;
;
STACK:
;
CR
LF

ERRORS = 0
17:09

10/02/2016
PAGE 33

DS
DS
DS
DS
DS
DS
DS
DS
ORG
ORG
ORG
DS
DS
DS
DS
DS
ORG
ORG
ORG
DS

2
2
2
2
2
2
2
2
1366H
1F00H
0F00H
0
55
64
1
1
1400H
2000H
1000H
0

EQU
EQU

0DH
0AH

;'FOR' LOOP SAVE AREA
;INCREMENT
;LIMIT
;LINE NUMBER
;TEXT POINTER
;RANDOM NUMBER POINTER
;­>UNFILLED TEXT AREA
;TEXT SAVE AREA BEGINS
;for 2K RAM
;TEXT SAVE AREA ENDS
;VARIABLE @(0)
;INPUT BUFFER
;BUFFER ENDS
;TOP LIMIT FOR STACK
;for 4K system ­­ 2k ROM, 2K RAM
;STACK STARTS HERE

END
NO PROGRAM ERRORS

67

1
8080 MACRO ASSEMBLER, VER 3.0
+
+

ERRORS = 0
17:09

10/02/2016
PAGE 34

SYMBOL TABLE
* 01
A
AWHAT
C
CI1
CRLF
DIREC
DWA
EX0
EX4
EXPR2
FI2
FNDLN
FOR
FR4
GETLN
GOSUB
IFF
IP1
IP5
LIST
LOPPT
LT1
MVDOW
NX0
NX4
OCSW
PN1
PN5
PR0
PR6
PRTNU
PU1
QT1
QT5
RANPN
RSTAR
RUNTS
SP
ST3
STKGO
SUBDE
TAB4
TC1
TV1
VARBG
XP12
XP16

0007
04C7
0001
069D
000E
0738
06CB
073B
075C
0371
04C1
0538
01F8
0219
04FA
01BF
02B4
02CD
031C
016F
0811
032C
05EE
025E
0288
0800
059D
05C1
019B
01B2
0592
063F
0571
0591
0813
00BA
0150
0006
00D6
0803
047C
0702
0068
0058
0F00
0339
0354

ABS
B
CHGSG
CK1
CURRN
DIVID
E
EX1
EX5
EXPR3
FIN
FNDLP
FR1
FR5
GL1
GOTO
INIT
IP2
L
LOPIN
LOPVA
M
MVUP
NX1
NX5
OK
PN2
PN6
PR1
PR8
PRTST
PUSHA
QT2
QTSTG
REM
RUN
SETVA
SS1
ST4
STKIN
SV1
TAB5
TC2
TXTBG
VARNX
XP13
XP17

0450
0000
0486
049E
0801
0466
0003
073D
0761
03A5
04B3
0540
0208
021C *
04FE
0160
0642
02DB
0005
080B
0809
0006
05E5
0298
02AA
00AB
05A4
05C7
01A3
01B6
0560
0619
057A
056C
02B0
0141
04A0
0028
010B
0807
04B0
0714
0073
0817
0805
033F
035A

AHOW
BUFEN
CHKIO
CKHLD
D
DV1
ENDCH
EX2
EXEC
EXPR4
FL1
FNDNX
FR2
FR7
GL3
H
INPER
IP3
LET
LOPLM
LS1
MD1
NEW
NX2
OC2
PARN
PN3
POPA
PR2
PRINT
PS1
QHOW
QT3
QWHAT
RETUR
RUNNX
SIZE
ST1
STACK
STKLM
TAB1
TAB6
TN1
TXTEN
WHAT
XP14
XP18

00A0
0F77
0684
0498
0002
0471
04C2
0750
073B
0405
0540
0554
0212
0231
0523
0004
02C3
02EB
0323
080D
0178
05F6
0132
02AC
066C
041A
05B4
05FD
0192
0187
0561
009F
057E
04C6
01DF
0147
0459
00BD *
1000
0F78
06AE
071A
007C
0F00
00AE
0346
035C

ASORR
BUFFE
CHKSG
CR
DEFLT
DV2
ERROR
EX3
EXPR1
FI1
FL2
FNDSK
FR3
FR8
GL4
HOW
INPUT
IP4
LF
LOPLN
LSTRO
MSG1
NEXT
NX3
OC3
PATLO
PN4
PP1
PR3
PRTLN
PSW
QSORR
QT4
RA1
RND
RUNSM
SORRY
ST2
START
STOP
TAB2
TAB8
TSTNU
TXTUN
XP11
XP15
XP21

04F4
0F37
0483
000D
031D
0473
04CA
075A
032D
04BA
0555
0556
0216
0252
0530
00A6
02CD
0315
000A
080F
0769
06A3
0257
0276
0671
064F
05B5
0617
01A9
05D2
0006
04F3
0586
0440
0425
0157
00B4
00CD
0000
013B
06BE
0722
0077
0815
0333
034E
037A

68

1
8080 MACRO ASSEMBLER, VER 3.0
ERRORS = 0
+
+
SYMBOL TABLE
XP22
XP26
XP34
XP42

037D
039B
03D8
0421

XP23
XP31
XP35
XP43

0380
03A8
03F7
0422

XP24
XP32
XP40

0387
03C5
040B

17:09

10/02/2016
PAGE 35

XP25
XP33
XP41

0398
03CD
0414

* 02
* 03
* 04
* 05
* 06
* 07
* 08
* 09
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17

69

1
8080 MACRO ASSEMBLER, VER 3.0
ERRORS = 0
+
+
SYMBOL TABLE

17:09

10/02/2016
PAGE 36

* 18
* 19
* 20
* 21
* 22
* 23
* 24
* 25
* 26
* 27
* 28
* 29
* 30
* 31

70

Appendix C: Intel Hex Code for Tiny BASIC
What follows is the hex file output from the assembly of the Tiny BASIC code in Appendix B. This can
be copied and pasted into a text file. Some EPROM programmers will accept Intel hex files for
programming EPROMs, so you can make your own Tiny BASIC EPROM that way. There are also
utilities in both Windows (hex2bin) and Linux (objcopy) to convert an Intel hex file into a binary file.
:100000003100103EFFC34206E3EFBEC368003E0D61
:10001000F53A0008B7C36C06CD7103E5C32D03574D
:100020007CBAC07DBBC9414E1AFE20C013C3280054
:10003000F1CDB304C3C60447EFD640D8C25800136D
:10004000CD1A0429DA9F00D5EBCD5904E7DAF40480
:1000500021000FCD7C04D1C9FE1B3FD81321000F16
:1000600007856F3E008C67C923CA7300C54E060022
:1000700009C11B1323E3C921000044EFFE30D8FE61
:100080003AD03EF0A4C29F0004C5444D2929092955
:100090001A13E60F856F3E008C67C11AF27C00D5FB
:1000A00011A600C3CA04484F573F0D4F4B0D574888
:1000B00041543F0D534F5252590D310010CD0E0097
:1000C00011AB0097CD600521CE0022010821000070
:1000D0002209082203083E3ECDFA04D511370FCD80
:1000E0007700EF7CB5C1CA38071B7C121B7D12C597
:1000F000D57993F5CD3805D5C20B01D5CD5405C1C1
:100100002A1508CDE5056069221508C12A1508F1F0
:10011000E5FE03CABA00856F3E008C6711000FE749
:10012000D2F304221508D1CDEE05D1E1CDE505C30A
:10013000D600CDC204211708221508CDC204C3BAC7
:1001400000CDC204111708210000CD4005DABA0025
:10015000EB220108EB1313CD840621BD06C33B0738
:10016000DFD5CDC204CD3805C2A000F1C35001CD0A
:100170007700CDC204CD3805DABA00CDD205CD84E2
:1001800006CD4005C378010E06CF3B06CD0E00C359
:100190005701CF0D06CD0E00C34701CF2305DF4D1C
:1001A000C3A901CD6C05C3B601CF2C06CDB304C3E2
:1001B0009B01CD0E00F7DFC5CD9205C1C3A901CDCE
:1001C0001906DFD5CD3805C2A0002A0108E52A03AB
:1001D00008E521000022090839220308C35001CD97
:1001E000C2042A03087CB5CAC604F9E1220308E167
:1001F000220108D1CDFD05F7CD1906CDA0042B2293
:100200000908211307C33B07DF220D08211907C383
:100210003B07DFC31902210100220B082A01082233
:100220000F08EB221108010A002A0908EB6068395F
:100230003E097E23B6CA52027E2BBAC231027EBB71
:10024000C23102EB21000039444D210A0019CDEEE4
:1002500005F92A1108EBF7FFDAC604220508D5EBE9
:100260002A09087CB5CAC704E7CA7602D1CDFD05C4
:100270002A0508C35E025E23562A0B08E57CAA7A8B
:1002800019FA8802ACFAAA02EB2A09087323722A27
:100290000D08F1B7F29802EBCD9804D1DAAC022A3E
:1002A0000F082201082A1108EBF7E1D1CDFD05F76F

71

:1002B0002100003EDF7CB5C25701CD5605D250016A
:1002C000C3BA002A0708F9E1220108D1D1D5CD6CC3
:1002D00005C3DB02FFDA1503C3EB02D5FFDAC60460
:1002E0001A4F9712D1CD6005791B12D5EB2A010860
:1002F000E521CD0222010821000039220708D53E60
:100300003ACDFA0411370FDF000000D1EB732372EE
:10031000E1220108D1F1CF2C03C3CD02F71AFE0D63
:10032000CA2C03CDA004CF2C03C32303F72121073C
:10033000C33B07CD5C03D86FC9CD5C03C86FC9CD83
:100340005C03C8D86FC9CD5C036FC8D86CC9CD5CDD
:1003500003C06FC9CD5C03D06FC9E1C979E1C1E5C4
:10036000C54FCD7103EBE3CD9804D12100003E01D0
:10037000C9CF2D06210000C39B03CF2B00CDA503C1
:10038000CF2B15E5CDA503EBE37CAA7A19D1FA8032
:1003900003ACF28003C39F00CF2D86E5CDA503CD2E
:1003A0008604C38703CD0504CF2A2DE5CD050406B9
:1003B00000CD8304E3CD8304EBE37CB7CAC5037AA5
:1003C000B2EBC2A0007D210000B7CAF70319DAA082
:1003D000003DC2CD03C3F703CF2F46E5CD0504068C
:1003E00000CD8304E3CD8304EBE3EB7AB3CAA00032
:1003F000C5CD66046069C1D17CB7FA9F0078B7FCAF
:100400008604C3A803210107C33B07FFDA14047E57
:1004100023666FC9CD770078B7C0CF2805DFCF2915
:1004200001C9C3C604CD1A047CB7FA9F00B5CA9FA0
:1004300000D5E52A1308116907E7DA400421000016
:100440005E2356221308E1EBC5CD6604C1D123C952
:10045000CD1A041BCD830413C92A1508D5EB21003E
:100460000FCD7C04D1C9E56C2600CD7104417DE13E
:10047000670EFF0CCD7C04D2730419C97D936F7C89
:100480009A67C97CB7F07CF52F677D2F6F23F1AC9D
:10049000F29F0078EE8047C97CAAF29E04EBE7C980
:1004A000FFDAC604E5CF3D08DF444DE1712370C992
:1004B000C3C604CF3B04F1C35701CF0D04F1C347BA
:1004C00001C9EFFE0DC8D511AE0097CD6005D11A58
:1004D000F597122A0108E57E23B6D1CABA007EB785
:1004E000FAC302CDD2051BF1123E3FD797CD60056E
:1004F000C3BA00D511B400C3CA04D711370FCD84D5
:1005000006CAFE04FE7FCA2305D7FE0ACAFE04B748
:10051000CAFE04FE7DCA30051213FE0DC87BFE77AD
:10052000C2FE047BFE37CA30051B3E5CD7C3FE0407
:10053000CD0E003E5EC3FA047CB7FA9F0011170887
:10054000E52A15082BE7E1D81A9547131A9CDA55C6
:10055000051BB0C913131AFE0DC2550513C3400580
:10056000471A13B8C8D7FE0DC26105C9CF220F3E86
:1005700022CD6005FE0DE1CA4701232323E9CF27E1
:10058000053E27C37105CF5F083E8DD7D7E1C37AFB
:1005900005C90600CD8304F29D05062D0DD5110A6F
:1005A00000D50DC5CD660478B1CAB405E32DE5606C
:1005B00069C3A405C10D79B7FAC1053E20D7C3B5FB
:1005C0000578B7C410005D7BFE0AD1C8C630D7C31A
:1005D000C7051A6F131A67130E04CD92053E20D774
:1005E00097CD6005C9E7C81A021303C3E5057892E1
:1005F000C2F6057993C81B2B1A77C3EE05C1E12219

72

:1006000009087CB5CA1706E1220B08E1220D08E1B2
:10061000220F08E1221108C5C921780FCD8604C137
:1006200039D2F3042A09087CB5CA3F062A1108E525
:100630002A0F08E52A0D08E52A0B08E52A0908E52E
:10064000C5C93200083E4ED3033E37D3031619CD39
:100650000E0015C24F069711A306CD6005210000BC
:10066000221308211708221508C3BA00C27106F127
:10067000C9DB03E601CA7106F1D302FE0DC03E0AD2
:10068000D73E0DC9DB0300E602C8DB02E67FFE0FA2
:10069000C29D063A00082F320008C38406FE03C03C
:1006A000C3BA0054494E592042415349430D4C4965
:1006B0005354816F52554E81414E455781324E45BC
:1006C000585482574C45548323494682B4474F546B
:1006D0004F8160474F53554281BF52455455524E4A
:1006E00081DF52454D82B0464F5281F8494E5055F8
:1006F0005482CD5052494E54818753544F50813BC0
:10070000831D524E448425414253845053495A45D7
:100710008459840B544F820884C653544550821226
:1007200082163E3D83332383393E833F3D834E3CD7
:100730003D83463C8354835A21AD06EFD51A13FE00
:100740002ECA5A0723BECA3D073E7F1BBEDA610789
:1007500023BED2500723D1C33B073E7F23BED25CCA
:09076000077E236EE67F67F1E9D4
:00000001FF

73



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Page Count                      : 73
Language                        : en-US
Creator                         : Writer
Producer                        : LibreOffice 4.2
Create Date                     : 2016:11:16 10:20:21-05:00
EXIF Metadata provided by EXIF.tools

Navigation menu