Tiny Basic Instructions
User Manual:
Open the PDF directly: View PDF
.
Page Count: 73
| Download | |
| Open PDF In Browser | View 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 X B) *X+(A) ;AND RETURN THE FIRST ;NONBLANK 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 NONZERO ; 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,TAB21 ;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 BACKARROW 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 CONTROLC ;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 CRLF AND ;CONTINUE SAME LINE ;IF NULL LIST (CR) ;ALSO GIVE CRLF 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 NONZERO ; '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,TAB51 ;USE 'EXEC' TO LOOK JMP EXEC ;FOR THE WORD 'TO' FR1: RST 3 ;EVALUATE THE LIMIT SHLD LOPLMT ;SAVE THAT LXI H,TAB61 ;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 SEMICOLONS. ; NOTE THAT THE WORD 'THEN' IS NOT USED. TBI EVALUATES THE ; EXPR. IF IT IS NONZERO, 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 BACKARROW, 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 CONTROLC. ; 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, RESTART ;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,TAB81 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,TAB41 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 NONZERO ;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. RUBOUT IS USED TO CAUSE IT TO DELETE ; THE LAST CHARACTER (IF THERE IS ONE), AND ALTMOD 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 BACKSLASH 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 UPARROW ;*** 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 BACKARROW, SINGLE QUOTE, OR DOUBLE ; QUOTE. IF NONE OF THESE, RETURN TO CALLER. IF BACKARROW, ; 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 BACKARROW? 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 CONTROLO, THE 'OCSW' SWITCH IS COMPLIMENTED, AND ; Z FLAG IS RETURNED. IF A CONTROLC 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, 8bit 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 CONTROLO? ;NO, MORE CHECKING ;CONTROLO FLIPS OCSW ;ON TO OFF, OFF TO ON ;GET ANOTHER INPUT ;IS IT CONTROLC? ;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 TABLE1. AT 'DIRECT', DE SHOULD POINT TO THE STRING. ; HL WILL BE SET UP TO POINT TO TAB11, 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 HILOW 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,TAB11 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:00EXIF Metadata provided by EXIF.tools