ORG 116Q ; MEMEND EQU 2FFFH OS EQU 8800H ; OUT EQU 4 CRLF EQU 1 INPUT EQU 2 RESET EQU 0 CR EQU 13 ; MINOL: MVI A,']' ;OUTPUT PROMPT RST OUT CALL INPTXT ;GET INPUT LINE LXI H,TXT ;POINT TO INPUT TEXT WITH HL MOV A,M CALL CHEKN ;CHECK FOR LABEL JNC DIRECT ;IF NO LABEL, GO EXECUTE COMMAND FND: INX H ;POINT TO FIRST NON-NUMERIC CHAR MOV A,M CALL CHEKN JC FND CALL MKBIN ;CONVERT ASCII LABEL TO BINARY LXI D,PROG ;THIS SECTION EDITS LINES OF THE PROGRAM ZIP: LDAX D CPI CR INX D JNZ ZIP LDAX D ;LOOK AT LINE NUMBER CPI -1 JZ INSRT STC CMC CMP B JC ZIP ;POINT TO LINE NUMBER GREATER THAN OR INSRT: MOV A,M ;OR EQUAL TO ENTERED LABEL CPI CR JZ EKIL ;IF LABEL ALONE, DELETE LINE MVI C,2 IHR: INX H ;COUNT LENGTH OF LINE AND ADD 2 MOV A,M INR C CPI CR JNZ IHR OHIO: LDAX D ;IF LINE ENTERED ALREADY EXISTS, FIRST CMP B ;DELETE THE OLD ONE, THEN INSERT NEW JNZ IBYH PZIY: PUSH D CALL KILLINE POP D IBYH: MOV H,D ;HL POINTS TO FIRST LOCATION WHERE NEW MOV L,E ;LINE WILL BE PLACED PUSH D ;SAVE POSITION IN STACK EHR: INX D LDAX D CPI -1 JNZ EHR ;CONTINUE UNTIL DE POINTS TO END OF FILE MOV A,C ;LENGTH OF NEW LINE IN A MOV B,D MOV C,E HBY: INX D INX H PUSH PSW MOV A,E CPI MEMEND AND 0FFH ;MEMORY LIMIT JNZ HII MOV A,D CPI MEMEND SHR 8 JZ ERR6 ;OUT OF MEMORY ERROR HII: POP PSW DCR A JNZ HBY ;INCREMENT UNTIL DE POINTS TO NEW UPDT: LDAX B ;END-OF-FILE POSITION, AND HL POINTS STAX D ;TO WHERE FILE UPDATING BEGINS MOV A,E ;BC POINTS TO END-OF-FILE CMP L JNZ NHR MOV A,D CMP H JZ NET NHR: DCX B DCX D JMP UPDT ;RELOCATE FILE LEAVING SPACE FOR NEW LINE NET: POP D ;RETRIEVE POINTER LXI H,TXT IFD: INX H MOV A,M CALL CHEKN JC IFD ;POINT TO FIRST NON-NUMERIC CHARACTER LDA BIN ;PUT LINE NUMBER IN A STAX D ;STORE LINE NUMBER IN FILE NTAT: INX D ;STORE LINE TEXT IN FILE MOV A,M STAX D INX H CPI CR JNZ NTAT RST RESET ;GO BACK TO MONITOR SECTION EKIL: CALL KILLINE ;DELETE LINE RST RESET KILLINE: LDAX D ;DELETE A LINE CMP B RNZ ;IF DELETING A LINE THAT DOES NOT EXIST,RETURN MOV H,D MOV L,E BBL: INX H MOV A,M CPI CR JNZ BBL ;POINT TO NEXT LINE ARK: INX H ;RELOCATE FILE, DELETING LINE MOV A,M STAX D CPI -1 RZ INX D JMP ARK DIRECT: RST CRLF ;DIRECT EXECUTION OF A STATEMENT XRA A STA LNE ;SET LNE (CURRENT LINE NO.) = 0 JMP EXEC ;EXECUTE STATEMENT RUN: LXI H,PROG ;RUN STATEMENT: START FROM BEGINNING OF LPUB: MOV A,M ;PROGRAM. GET NEXT STATEMENT CPI ':' INX H JZ EXEC ;IF NOT A NEW LINE, GO EXECUTE STATEMENT CPI CR JNZ LPUB BIB: MOV A,M CPI -1 JZ RESET ;IF STATEMENT NO. = 377 (END OF PROGRAM), STA LNE ; GO BACK TO MONITOR INX H ;IF NOT 377, STORE CURRENT LINE NO. AT LNE EXEC: CALL INT ;CHECK FOR KEYBOARD INTERRUPT INX H MOV A,M CPI '=' ;CHECK FOR = IN SECOND COLUMN (ASSIGNMENT) JZ LET DCX H MOV A,M CPI '(' ;IF ( IN FIRST COLUMN (MEMORY LOCATION JZ LET ; ASSIGNMENT) GO TO LET CPI 'C' ;CHECK FOR 'C' JNZ GSM ;IF NOT, GO ON INX H MOV A,M CPI 'A' JZ CALL ;CALL STATEMENT CPI 'L' JZ CLR ;CLEAR STATEMENT JMP ERR3 ;IF NEITHER, REPORT ERROR GSM: CPI 'E' ;CHECK FOR 'E' AS IN END JZ RESET CPI 'G' JZ GOTO CPI '"' ;CHECK FOR " INDICATING REM STATEMENT JZ LPUB CPI 'N' JZ NEW CPI 'P' JZ PR CPI 'O' JZ OS ;ADDRESS OF USER'S MONITOR CPI 'R' JZ RUN CPI 'I' JNZ LS INX H MOV A,M CPI 'N' JZ IN CPI 'F' JZ IF JMP ERR3 LS: CPI 'L' JNZ ERR3 INX H MOV A,M CPI 'E' JZ LET CPI 'I' JZ LIST JMP ERR3 LET: MOV A,M ;LET STATEMENT EXECUTOR CALL TERM ;FIND '=' JC ERR5 ;REPORT ERROR IF NO '=' BEFORE CR OR ':' CPI '=' INX H JNZ LET LXI D,EXPR ;TRANSFER EXPRESSION TEXT TO MRENX: MOV A,M ;EXPRESSION BUFFER STAX D CALL TERM INX H INX D JNC MRENX CALL EXPRS SERCH: MOV A,M ;GO BACK BEFORE '=' CPI '=' DCX H JNZ SERCH MOV A,M CALL CHEKLTR JNC INLET ;IF NOT VARIABLE, GET MEMORY ADDRESS CALL GETADR MOV A,C STAX D ;STORE IN VARIABLE JMP LPUB ;NEXT STATEMENT INLET: CPI ')' JNZ ERR4 JHR: DCX H MOV A,M CPI '(' JNZ JHR MOV A,C PUSH PSW CALL VAL ;GET MEMORY LOCATION IN BC POP PSW STAX B JMP LPUB PR: INX H ;PR STATEMENT EXECUTOR INX H ;SKIP ASSUMED CHARACTERS MOV A,M CALL TERM ;IF BLANK PRINT, GO TO CR JC DCR NXTE: CPI '"' ;CHECK FOR LITERAL JNZ VAR ;IF NOT, GO ON HR: INX H ;PRINT TEXT UNTIL " FOUND MOV A,M CPI '"' JZ MRENO CALL TERM ;IF TERMINATOR BEFORE CLOSING QUOTE, ERROR JC ERR5 RST OUT JMP HR MRENO: INX H MOV A,M CALL TERM ;IF END OF STATEMENT WITHOUT SEMICOLON, DO CR JC DCR CPI ';' JNZ ERR5 INX H MOV A,M CALL TERM ;IF TERM AFTER SEMICOLON, DO NOT PRINT CR JC NCR JMP NXTE DCR: RST CRLF NCR: JMP LPUB VAR: CPI '$' JZ STR ;CHECK IF STRING LXI D,EXPR MVI A,' ' ;OUTPUT LEADING SPACE RST OUT ER: MOV A,M ;TRANSFER EXPRESSION TEXT FROM PROGRAM TEXT STAX D ; TO EXPRESSION BUFFER INX H INX D CALL TERM JC HRX CPI ';' JNZ ER HRX: DCX H DCX D MVI A,CR STAX D CALL EXPRS MOV B,C CALL PBINBCD ;PRINT EXPRESSION'S VALUE MVI A,' ' RST OUT JMP MRENO+1 STR: INX H CALL VAL ;GET START ADDRESS OF STRING IN BC AND PRINT MRE: LDAX B RST OUT CPI -1 INX B JNZ MRE INX H JMP MRENO+1 IN: INX H ;INPUT STATEMENT IN -1 CPI 0 ;IF SENSE SWITCHES DOWN, PRINT '?' JNZ EAHR MVI A,'?' RST OUT MVI A,' ' RST OUT EAHR: MOV A,M CALL CHEKLTR ;CHECK FOR VARIABLE JC LVB CPI '$' ;CHECK FOR INPUT STRING JZ STRIN CPI '(' ;CHECK FOR SINGLE MEMORY LOCATION JNZ ERR4 CALL VALDE ;GET LOCATION IN DE PUSH H JMP HS LVB: PUSH H CALL GETADR ;GET ADDRESS OF LETTER VARIABLE HS: PUSH D IHERE: CALL INPTXT ;INPUT A LINE RST CRLF LXI H,TXT MOV A,M CALL CHEKN ;CHECK FOR A NUMBER JNC LETR FD: INX H MOV A,M CALL CHEKN JC FD ;POINT TO FIRST NON-NUMERIC CHAR PUSH B CALL MKBIN ;CONVERT ASCII INPUT DATA TO BINARY POP B LETR: POP D STAX D ;PUT A IN VARIABLE CHK: POP H INX H MOV A,M CPI ',' ;CHECK FOR MORE INPUT VARIABLES JZ IN CALL TERM JC LPUB JMP ERR5 STRIN: INX H ;INPUT STRING CALL VAL ;GET FIRST MEMORY LOCATION IN BC PUSH H PUSH B CALL INPXT POP B RST CRLF LXI H,TXT LD: MOV A,M ;STORE TEXT BEGINNING AT SPECIFIED LOC CPI CR JZ TE STAX B INX B INX H JMP LD TE: MVI A,-1 ;STORE 377 AT END OF STRING STAX B JMP CHK CLR: LXI D,VARSTOR ;CLEAR EXECUTOR VAR STORAGE LCR: XRA A STAX D INX D MOV A,E CPI VAREND ;LAST VARIABLE LOCATION JNZ LCR JMP LPUB CALL: NOP ;SKIP ASSUMED CHARACTERS INX H INX H INX H CALL VAL ;GET ADDRESS IN BC PUSH H PUSH D LXI D,RET ;LOAD DE WITH RETURN ADDRESS PUSH D ;PUSH RETURN ADDRESS ONTO STACK MOV H,B MOV L,C PCHL ;JUMP TO USER'S SUBROUTINE RET: POP D POP H JMP LPUB NEW: LXI D,PROG ;'NEW' PROCESSOR MVI A,CR ;INITIALIZE PROGRAM AREA STAX D INX D MVI A,-1 STAX D RST RESET INT: PUSH PSW ;THIS ROUTINE CHECKS FOR CONTROL C IN 10H CPI 3 ;CONTROL C JZ BREAK POP PSW RET BREAK: POP D POP D POP D POP D RST CRLF LXI D,BRKMSG CALL PRNTXT JMP ATX GOTO: INX D ;GOTO EXECUTOR INX H ;SKIP ASSUMED CHARACTERS INX H INX H LXI D,EXPR ;CALCULATE VALUE OF EXPRESSION RME: MOV A,M STAX D CALL TERM INX H INX D JNC RME CALL EXPRS MOV B,C MOV A,C CPI 0 ;??????????!!!!CPI 0 ???? JNZ JUMP LXI H,TXT JMP DIRECT JUMP: LXI H,PROG ;GOTO EXPRESSION DUP: MOV A,M CPI CR INX H JNZ DUP MOV A,M CPI -1 JZ ERR1 CMP B JNZ DUP JMP BIB ERRMSG: DB '!ERR ',-1 AT: DB ' AT ',-1 BRKMSG: DB 'BREAK',-1 BIN: DB 0 LNE: DW 0 ;CURRENT LINE NUMBER ACT: PUSH B ;GETS THE VALUE OF A MEMORY LOCATION XCHG CALL VAL ;PART OF THE EXPRS SUBROUTINE TO FOLLOW XCHG LDAX B POP B MOV B,A NXGT: INX D JMP GETNET NOTEQ: MOV A,E ;IF TWO EXPRESSIONS ARE NOT EQUAL, EXECUTE CMP C ;STATEMENT (PART OF IF STATEMENT EXECUTOR JNZ EXEC ;TO FOLLOW) JMP LPUB VALDE: CALL VAL MOV D,B MOV E,C RET EXPRS: PUSH H ;CALCULATES THE VALUE OF AN EXPRESSION LXI D,EXPR-1 ;STORED IN MEMORY MVI C,0 ;DE IS THE CURSOR RETPT: LDAX D CALL TERM ;CHECK FOR END OF EXPRESSION JNC GOMOR POP H RET GOMOR: PUSH PSW ;SAVE OPERATION ON STACK INX D ;GET TERM/FACTOR LDAX D CPI 47Q ;SINGLE CHARACTER VALUE JZ ASC CPI '(' ;MEMORY LOCATION JZ ACT CPI '!' ;RANDOM NUMBER JZ RND CALL CHEKN JC CONSTANT ;CONSTANT (NUMBER) CALL CHEKLTR JNC ERR5 INX D IVAR: PUSH D ;VARIABLE CALL GETADR LDAX D MOV B,A POP D GETNET: POP PSW ;RETRIEVE OPERATION CPI '+' JZ ADD CPI '-' JZ SUB CPI '*' JZ MULT CPI '/' JZ DIV JMP ERR5 ADD: MOV A,C ;ADD C=C+B ADD B MOV C,A JMP RETPT SUB: MOV A,C ;C=C-B SUB B MOV C,A JMP RETPT MULT: MOV A,C ;C=C*B DCR B GBK: ADD C DCR B JNZ GBK MOV C,A JMP RETPT DIV: MOV A,C ;C=C/B MVI C,0 CTUE: INR C SUB B JZ ZER JC MIN JMP CTUE MIN: DCR C ZER: JMP RETPT CONSTANT: INX D LDAX D CALL CHEKN JC CONSTANT XCHG CALL SURE XCHG MOV B,A JMP GETNET ASC: INX D LDAX D MOV B,A INX D JMP NXGT RND: LXI H,SH+3 MVI B,8 MOV A,M RTOP: RLC RLC RLC XRA M RAL RAL DCR L DCR L DCR L MOV A,M RAL MOV M,A INR L MOV A,M RAL MOV M,A INR L MOV A,M RAL MOV M,A INR L MOV A,M RAL MOV M,A INR B JNZ RTOP MOV B,A JMP NXGT SH: DB 21Q,231Q,132Q,351Q ;SEED INPTXT: MVI C,0 ;INPUT A LINE OF 72 CHARACTERS INPXT: LXI H,TXT-1 INO: RST INPUT HRER: MOV B,A MOV A,C CPI 0 ;??????!!!!! CPI 0 ??? MOV A,B JNZ MID CPI ' ' JZ INO ;DO NOT ACCEPT SPACE IF OUTSIDE QUOTES MID: CPI '"' JNZ GOON MOV A,C CPI 0 ;??????!!!!! CPI 0 ? JZ MRF MVI C,0 JMP GOON MRF: MVI C,3 GOON: CPI 14Q ;IF CONTROL L REDO LINE JNZ HRD MVI A,'\' RST OUT RST CRLF JMP INPTXT HRD: CPI CR JNZ CHM JMP HELP CHM: CPI 23Q ;IF CONTROL S GO BACK A CHARACTER JNZ CTN MVI A,'_' RST OUT DCX H JMP INO CTN: MOV A,L CPI TXTEND JZ ERR2 ;IF OVER 72 CHARACTERS REPORT ERROR INX H STOR: MOV M,B JMP INO ERR1: MVI B,'1' JMP ERR ERR2: MVI B,'2' JMP ERR ERR3: MVI B,'3' JMP ERR ERR4: MVI B,'4' JMP ERR ERR5: MVI B,'5' JMP ERR ERR6: MVI B,'6' ERR: RST CRLF ;PRINT 'ERR' MESSAGE LXI D,ERRMSG CALL PRNTXT MOV A,B RST OUT ATX: LXI D,AT CALL PRNTXT LDA LNE MOV B,A CALL PBINBCD RST 0 MKBIN: PUSH D ;GET VALUE OF ASCII NUMBERS DCX H MOV A,M SUI '0' MOV B,A DCX H MOV A,M CALL CHEKN JC STOC MVI C,0 MVI E,0 ;!!!!! SAVE A BYTE--USE MOV E,C JMP INK2 STOC: SUI '0' MOV C,A ENT: DCX H MOV A,M CALL CHEKN JC STOE MVI E,0 JMP INK3 STOE: MOV A,M SUI '0' MOV E,A INK3: INX H INK2: INX H INX H CALL BCDBIN MOV A,B STA BIN POP D RET GETADR: PUSH H ;GET ADDRESS OF VARIABLE LXI D,VARSTOR SUI 'A' MVI H,0 MOV L,A DAD D XCHG POP H RET PRNTXT: LDAX D ;PRINT TEXT POINTED BY DE CPI -1 RZ RST OUT INX D JMP PRNTXT CHEKLTR: STC ;CHECK IF CHAR IS A LETTER CMC CPI 'A' JC NOTAP STC CPI 'Z'+1 RET NOTAP: CMC RET VARSTOR: DS 27 ;VARIABLE STORAGE VAREND: DS 1 TERM: CPI CR ;CHECK FOR STATEMENT TERMINATOR JZ YES CPI ':' JZ YES STC CMC ;!!!!! THIS CAN BE DONE WITH ORA A RET YES: STC RET CHEKN: STC CMC ;!!!!!!!!! USE ORA A HERE CPI '0' JC NOTA STC CPI '9'+1 NOT: RET NOTA: CMC RET BCDBIN: MVI A,10 ;BCD TO BINARY ROUTINE ADD B MOV B,A DCR C JNZ BCDBIN SEC: MOV C,E MOV A,E CPI -1 THI: RZ MVI A,100 ADD B MOV B,A DCR C JMP THI LIST: LXI D,PROG+1 ;LIST COMMAND NEXN: LDAX D CPI -1 JZ LPUB MOV B,A CALL PBINBCD MVI A,' ' RST OUT INX D LDAX D OU: RST OUT CPI CR JNZ MREN INX D RST CRLF JMP NEXN MREN: INX D LDAX D JMP OU PBINBCD: PUSH B ;PRINT BINARY NUMBER PUSH D MVI D,0 MOV C,D MOV A,B IFIR: SUI 100 JC ISEC INR C JMP IFIR ISEC: MVI B,100 ADD B MOV B,A MVI A,'0' ADD C CPI '0' JZ NP RST OUT COM: MVI C,0 MOV A,B ITHR: SUI 10 JC FOR INR C JMP ITHR FOR: MVI B,10 ADD B MOV B,A MVI A,'0' ADD C CPI '0' JZ INU IPR: RST OUT DPR: MVI A,'0' ADD B RST OUT POP D POP B RET NP: MVI D,1 JMP COM INU: MOV C,A XRA A CMP D MOV A,C JNZ DPR JMP IPR SURE: PUSH B ;SAVES BC AND CALLS MKBIN CALL MKBIN POP B RET HELP: INX H ;ADDS 377 TERMINATOR AT END OF INPUT TEXT MOV M,B INX H MVI M,-1 RET IF: LXI D,EXPR ;IF STATEMENT NGO: INX H ;FIRST EXPRESSION MOV A,M CPI 43Q ;# SIGN JZ COMP CPI '=' JZ COMP CPI '<' JZ COMP CALL TERM JC ERR5 STAX D INX D JMP NGO COMP: PUSH PSW MVI A,CR STAX D CALL EXPRS PUSH B LXI D,EXPR NXTVR: INX H ;SECOND EXPRESSION MOV A,M CPI ';' JZ PHI CALL TERM JC ERR5 STAX D INX D JMP NXTVR PHI: INX H MVI A,CR STAX D CALL EXPRS POP D POP PSW CPI 43Q ;CHECK RELATIONAL OPERATOR (# SIGN HERE) JZ NOTEQ CPI '<' JZ LESSTH EQU: MOV A,E ;CHECK IF = CMP C JZ EXEC JMP LPUB LESSTH: MOV A,E ;CHECK IF < CMP C JNC LPUB JMP EXEC VAL: PUSH D ;GET ADDRESS OF MEMORY LOCATION LXI D,EXPR SHME: INX H MOV A,M STAX D CALL TERM INX D JC ERR5 CPI ',' JNZ SHME DCX D MVI A,CR STAX D CALL EXPRS PUSH B LXI D,EXPR MIG: INX H MOV A,M STAX D CALL TERM INX D JC ERR5 CPI ')' JNZ MIG DCX D MVI A,CR STAX D CALL EXPRS MOV A,C POP B MOV B,C MOV C,A POP D RET DB '+' EXPR: DS 31 ;EXPRESSION BUFFER TXT: DS 72 ;LINE BUFFER (INPUT TEXT) TXTEND: DS 1 ; ORG 3400Q PROG: DB CR,-1 ; END MINOL  DS 31 ;EXPRESSION BUFFER T