home *** CD-ROM | disk | FTP | other *** search
- ;
- ; EDUCATOR-8080
- ;
- ;Originally written by the Digital Group
- ;Converted to run on CP/M BY Keith Petersen,
- ;W8SDZ, July 28, 1980.
- ;
- BKSPC EQU 08H ;BACKSPACE
- CR EQU 0DH ;CARRIAGE RETURN
- LF EQU 0AH ;LINE FEED
- CLR EQU 1AH ;SCREEN CLEAR CHARACTER
- DEL EQU 7FH ;DELETE (RUBOUT)
- ;
- ORG 100H
- ;
- ;THE CONTROL ROUTINE IS THE TOP OF THE STRUCTURE AND
- ;CONTROLS THE OPERATION OF THE ENTIRE PROGRAM.
- ;
- CNTRL: LXI SP,STACK ;SET STACK POINTER
- LHLD 1 ;GET CBIOS POINTER
- LXI D,3 ;READY FOR DAD
- DAD D ;CONSTAT
- DAD D ;CONIN
- SHLD VCONIN+1 ;MODIFY CALL ADDRESS
- DAD D ;CONOUT
- SHLD VCONOUT+1 ;MODIFY CALL ADDRESS
- ;
- NOTZER: CALL DSPLY ;DISPLAY CONTENTS OF REGISTERS
- CALL CMDNT ;ENTER A COMMAND
- CALL FETCH ;FETCH THE CORRECT OPCODE
- ORA A ;SET ZERO FLAG AS PER CONTENTS
- JNZ NOTZER ;JUMP IF NOT ZERO ERROR OCCURED
- CALL XQTER ;GO EXECUTE THE CURRENT COMMAND
- JMP NOTZER ;LOOP FOREVER
- ;
- ;THIS DISPLAY ROUTINE CONTROLS THE GENERATION OF THE DYNAMIC
- ;DISPLAY.
- ;
- DSPLY: LXI H,TITLS ;LOAD ADDRESS OF TITLES INTO HL
- CALL CHEDT ;DISPLAY TITLES
- LXI H,BLINE ;LOAD ADDR OF BLINE TITLE
- LDA BREG ;LOAD CONTENTS OF BREG INTO A
- CALL DSPCV ;CONVERT AND DISPLAY
- LXI H,CLINE ;LOAD ADDR OF CLINE TITLE
- LDA CREG ;LOAD CONTENTS OF CREG INTO A
- CALL DSPCV ;CONVERT AND DISPLAY
- LXI H,AFHDR ;LOAD ADDR OF A FLAGS TITLE
- CALL CHEDT ;DISPLAY TITLES
- LHLD PSWA ;LOAD FLAGS AND A INTO HL
- MOV A,L ;MOVE FLAGS TO A
- ANI 4 ;AND OFF ALL BUT PARITY FLAG
- CALL DSPFG ;DISPLAY THE FLAG VALUE
- MOV A,L ;MOVE FLAGS TO A
- ANI 40H ;AND OFF ALL BUT ZERO FLAG
- CALL DSPFG ;DISPLAY THE FLAG VALUE
- MOV A,L ;MOVE FLAGS TO A
- ANI 80H ;AND OFF ALL BUT SIGN FLAG
- CALL DSPFG ;DISPLAY THE FLAG VALUE
- MOV A,L ;MOVE FLAGS TO A
- ANI 10H ;AND OFF ALL BUT AUX. CARRY FLAG
- CALL DSPFG ;DISPLAY THE FLAG VALUE
- MOV A,L ;MOVE FLAGS TO A
- ANI 1 ;AND OFF ALL BUT CARRY FLAG
- CALL DSPFG ;DISPLAY THE FLAG VALUE
- MOV A,H ;MOVE A REGISTER VALUE TO A
- CALL DSPCN ;DISPLAY WITH NO TITLE PRINT
- RET ;RETURN TO THE CNTRL ROUTINE
- ;
- ;THE DISPLAY CONVERSION ROUTINE PRINTS BINARY,
- ;OCTAL AND HEXADECIMAL.
- ;
- DSPCV: PUSH PSW ;SAVE OUTPUT VALUE FOR CHEDT
- CALL CHEDT ;DISPLAY LINE TITLE ADDR IN HL
- POP PSW ;RETRIEVE SAVED OUTPUT VALUE
- ;
- DSPCN: MVI E,8 ;MOVE 8 TO E REGISTER
- ;
- DSPBT: RLC ;ROTATE MSB INTO CARRY AND LSB
- PUSH PSW ;SAVE CURRENT VALUE
- ANI 1 ;AND OFF ALL BUT LSB
- CALL DSPFG ;GO DISPLAY BIT VALUE
- POP PSW ;RETRIEVE SAVED CURRENT VALUE
- DCR E ;DECREMENT LOOP COUNT
- JNZ DSPBT ;JUMP IF LOOP COUNT NOT ZERO
- ORA A ;RESET CARRY
- MVI E,3 ;MOVE 3 TO E REGISTER
- ;
- DSPQT: RAL ;MSB TO CARRY, CARRY TO LSB
- RAL ;DO IT AGAIN,
- RAL ; THREE TIMES FOR OCTAL DIGIT
- PUSH PSW ;SAVE CURRENT VALUE
- ANI 7 ;AND OFF ALL BUT OCTAL LSD
- ORI '0' ;MAKE ASCII
- CALL CHRPR ;OUTPUT THE CHARACTER
- POP PSW ;RETRIEVE SAVED CURRENT VALUE
- DCR E ;DECREMENT LOOP COUNT
- JNZ DSPQT ;JUMP IF LOOP COUNT NOT ZERO
- CALL DSPSP ;OUTPUT A SPACE
- MVI E,2 ;MOVE 2 TO E
- ;
- DSPHT: RLC ;ROTATE MSB INTO CARRY AND LSB
- RLC ;DO IT AGAIN
- RLC ; FOUR TIMES FOR
- RLC ; HEXADECIMAL SHIFT
- PUSH PSW ;SAVE CURRENT VALUE
- ANI 0FH ;AND OFF ALL BUT HEX LSD
- ADI '0' ;ADD ON BITS TO MAKE ASCII
- CPI '9'+1 ;COMPARE RESULT TO ONE MORE THAN 9
- JC DSPHS ;IF NUMERIC THEN SKIP ADJUSTMENT
- ADI 7 ;ADD 7 GIVING ASCII A-F CODES
- ;
- DSPHS: CALL CHRPR ;OUTPUT THE CHARACTER
- POP PSW ;RETRIEVE SAVED CURRENT VALUE
- NOP
- DCR E ;DECREMENT LOOP COUNT
- JNZ DSPHT ;JUMP IF LOOP COUNT NOT ZERO
- RET ;RETURN TO CALLING ROUTINE
- ;
- ;DISPLAY FLAG OR BINARY DIGIT FOLLOWED BY A SPACE. ALTERNATE
- ;ENTRY IS USED TO DISPLAY A SPACE.
- ;
- DSPFG: JZ DSPFZ ;JUMP IF PASSED VALUE IS A ZERO
- MVI A,1 ;OTHERWISE MOVE A 1 INTO A
- ;
- DSPFZ: ADI '0' ;CONVERT INTO ASCII NUMERIC CHAR.
- CALL CHRPR ;OUTPUT THE CHARACTER
- ;
- DSPSP: PUSH PSW ;SAVE THE FLAGS AND VALUE IN A
- MVI A,' ' ;MOVE SPACE INTO A
- CALL CHRPR ;OUTPUT THE SPACE
- POP PSW ;RETRIEVE THE SAVED FLAGS AND A
- RET ;RETURN TO THE CALLING ROUTINE
- ;
- ;THE CHARACTER STRING OUTPUT EDIT ROUTINE.
- ;
- CHEDT: MOV A,M ;MOVE NEXT CHARACTER INTO A
- CPI 80H ;COMPARE IT TO 200 OCTAL
- RZ ;RETURN IF EQUAL IT'S END OF STRING
- JNC CHSPA ;JUMP IF GREATER FOR SPACE ROUTINE
- CALL CHRPR ;ELSE GO OUTPUT THE CHARACTER
- ;
- CHEND: INX H ;INCREMENT THE STRING INDEX
- JMP CHEDT ;LOOP FOR NEXT CHARACTER
- ;
- CHSPA: SUI 80H ;SUBTRACT 200 OCTAL FROM VALUE
- MOV B,A ;MOVE SPACE COUNT TO B
- ;
- CHSPL: MVI A,' ' ;MOVE SPACE INTO A
- CALL CHRPR ;OUTPUT THE SPACE
- DCR B ;DECREMENT SPACE COUNT
- JNZ CHSPL ;JUMP IF COUNT NOT ZERO TO START OF LOOP
- JMP CHEND ;JUMP BACK INTO CHEDT LOOP
- ;
- ;THE COMMAND ENTRY ROUTINE ACCEPTS INPUT FROM THE KEYBOARD
- ;FOR COMMANDS.
- ;
- CMDNT: LXI H,CMDMS ;MOVE ADDRESS OF COMMAND? INTO HL
- CALL CHEDT ;DISPLAY THE MESSAGE
- LXI H,CMDAR ;MOVE ADRS OF COMMAND INPUT AREA HL
- MVI B,22 ;MOVE MAXIMUM LENGTH TO B
- ;
- CMDKB: CALL KEYBD ;GET AN INPUT CHARACTER
- CPI 'L'-40H ;IS IT A CONTROL-L LINE DELETE?
- JZ CNTRL ;IF SO THEN RESTART PROGRAM
- CPI CR ;IS IT A CARRIAGE RETURN?
- JZ CMDND ;IF SO THEN GO COMPRESS INPUT
- CPI DEL ;IS IT A DELETE CHARACTER?
- JNZ CMDST ;IF NOT THEN GO STORE THE CHARACTER
- MVI A,BKSPC ;IF SO REPLACE WITH BACKSPACE
- ;
- CMDST: MOV M,A ;STORE INPUT CHAR. IN COMMAND BUFFER
- CALL CHRPR ;DISPLAY THE INPUT CHARACTER
- INX H ;INCREMENT COMMAND WORK AREA INDEX
- DCR B ;DECREMENT COMMAND LENGTH COUNT
- JNZ CMDKB ;IF NOT FULL THEN REITERATE
- MVI A,1 ;IF BUFFER FULL THEN SELECT ERROR
- CALL ERROR ; NUMBER 1 AND PRINT ITS MSG.
- JMP CNTRL ;RESTART THE PROGRAM
- ;
- ;THE COMMAND COMPRESS ROUTINE ELIMINATES ALL BUT LETTERS
- ;AND NUMBERS.
- ;
- CMDND: LXI H,CMDAR ;LOAD HL WITH ADRS OF WORK AREA
- PUSH H ;PUSH & POP MOVE IT TO DE
- POP D ; AS THE COMPRESSION POINTER
- MVI A,22 ;LOAD A WITH MAXIMUM LENGTH
- SUB B ;SUBTRACT REMAINING LENGTH FROM B
- MOV B,A ;MOVE ACTUAL LENGTH TO B
- ;
- CMDNX: MOV A,M ;MOVE COMMAND CHARACTER TO A
- CPI BKSPC ;IS IT BACKSPACE?
- JNZ CMDCH ;IF NOT THEN GO TO OTHER TESTS
- MVI A,CMDAR AND 0FFH ;LOW ADRS BYTE OF CMDAR TO A
- CMP E ;COMPARE TO CURRENT LOW ADRS BYTE
- JNC CMDNS ;IF NOT GREATER THEN SKIP SAVE
- DCX D ;ELSE BACK UP COMPRESSION POINTER
- JMP CMDNS ;SKIP SAVING THE CHARACTER
- ;
- CMDCH: CPI '0' ;IS THE CHARACTER LESS THAN '0'?
- JC CMDNS ;IF SO THEN SKIP SAVING IT
- CPI '9'+1 ;IS THE CHARACTER LESS THAN '9'+1?
- JC CMDSV ;IF SO THEN SAVE NUMERIC VALUE
- CPI 'A' ;IS THE CHARACTER LESS THAN 'A'?
- JC CMDNS ;IF SO THEN SKIP SAVING IT
- CPI 'Z'+1 ;IS THE CHARACTER GREATER THAN 'Z'?
- JNC CMDNS ;IF SO THEN SKIP SAVING IT
- ;
- CMDSV: STAX D ;STORE CHARACTER IN COMPRESSED AREA
- INX D ;INCREMENT COMPRESSION POINTER INDEX
- ;
- CMDNS: INX H ;INCREMENT INPUT STRING POINTER
- DCR B ;DECREMENT ACTUAL LENGTH COUNT
- JNZ CMDNX ;IF LENGTH IS NOT ZERO THEN REITERATE
- RET ;ELSE RETURN TO CNTRL CALLING POINT
- ;
- ;THE FETCH INSTRUCTION/COMMAND ROUTINE VALIDATES AND BUILDS THE
- ;OBJECT CODE.
- ;
- FETCH: LXI H,OPTAB ;LOAD ADDRESS OF OPCODE TABLE HL
- MVI E,31 ;MOVE TABLE ELEMENT COUNT TO E
- ;
- FLOOP: PUSH H ;SAVE CURRENT ELEMENT ADDRESS
- LXI B,CMDAR ;LOAD ADDRESS OF CMDAR INTO BC
- MVI D,3 ;MOVE OPCODE LENGTH TO D
- ;
- FCOMP: LDAX B ;LOAD COMMAND CHARACTER TO A INDEXED BY B
- CMP M ;COMPARE IT TO TABLE CHARACTER
- JNZ FNXEL ;IF NOT EQUAL THEN GO TO NEXT ELEMENT
- INX B ;INCREMENT COMMAND CHARACTER INDEX
- INX H ;INCREMENT TABLE CHARACTER INDEX
- DCR D ;DECREMENT OPCODE LENGTH COUNTER
- JNZ FCOMP ;IF NOT ZERO CONTINUE TEST LOOP
- XTHL ;EXCHANGE HL WITH TOP OF STACK
- POP H ;POP HL FROM STACK TO CLEAR IT
- MOV E,M ;MOVE NAKED OPCODE TO E,D IS ZERO
- PUSH D ;SAVE NAKED OPCODE
- INX H ;INCREMENT TABLE POINTER
- MOV E,M ;DECODE ROUTINE LOW ADDRESS BYTE TO E
- INX H ;INCREMENT TABLE POINTER
- MOV D,M ;DECODE ROUTINE HIGH ADDRESS BYTE TO D
- XCHG ;MOVE DECODE ROUTINE ADDRESS TO HL
- POP D ;UNSAVE NAKED OPCODE TO DE
- XRA A ;CLEAR A, NO ERROR CODE
- PCHL ;JUMP TO ADDRESS OF DECODE ROUTINE
- ;
- FNXEL: LXI B,6 ;LOAD DOUBLE LENGTH 6 INTO BC
- POP H ;UNSAVE CURRENT ELEMENT ADDRESS
- DAD B ;ADD 6 TO IT
- DCR E ;DECREMENT TABLE ELEMENT COUNT
- JNZ FLOOP ;REITERATE TO TEST NEXT ELEMENT
- MVI A,2 ;MOVE ERROR CODE 2 TO A
- JMP ERROR ;GO DISPLAY ERROR 2, OPCODE UNKNOWN
- NOP ;NO OPERATION FILLER
- ;
- ;THE INSTRUCTION DECODER ROUTINES FOLLOW
- ;INSTRUCTIONS USING THE DIRCT ROUTINE REQUIRE NO DECODING.
- ;EXAMPLE: RAL, CMA, ETC.
- ;
- DIRCT: RET ;RETURN TO CNTRL FOR EXECUTION
- ;
- ;THE MOVRT IS USED ONLY BE THE MOV COMMAND
- ;
- MOVRT: CALL RG543 ;VALIDATE DESTINATION REGISTER
- ORA A ;SET FLAGS BASED ON A CONTENTS
- RNZ ;RETURN NOT ZERO WITH ERROR
- ;
- ;INSTRUCTIONS USING THE RG210 ROUTINE REQUIRE A SOURCE REGISTER
- ;
- RG210: LDAX B ;LOAD NEXT COMMAND CHARACTER INTO A
- INX B ;INCREMENT COMMAND CHARACTER INDEX
- CALL REGAN ;ANALYZE FOR VALID REGISTER
- JNC RGERR ;IF CY=0 THEN REGISTER NOT VALID
- ADD E ;ADD NAKED OPCODE TO REGISTER VALUE
- MOV E,A ;MOVE RESULT BACK TO E
- XRA A ;CLEAR A INDICATING NO ERRORS
- RET ;RETURN TO CNTRL
- ;
- ;THE REGISTER ERROR ROUTINE IS USED TO INDICATE REGISTER
- ;DESIGNATION ERRORS
- ;
- RGERR: MVI A,3 ;MOV ERROR CODE 3 TO A
- JMP ERROR ;GO DISPLAY ERROR 3, INVALID REGISTER
- ;
- ;THE REGISTER ANALYSIS AND VALIDATION ROUTINE IS USED BY RG543,
- ;RG210, AND RG54B
- ;
- REGAN: SUI 'A' ;SUBTRACT AN 'A' FROM THE CHARACTER
- CPI 3 ;COMPARE THE RESULT TO 3
- RNC ;IF NOT LESS THAN 3 RETURN WITH CY=0
- DCR A ;DECREMENT RESULT: A=377,B=000,C=001
- ANI 7 ;AND OFF ALL BUT OCTAL LSD
- STC ;SET CY=1 INDICATING NO ERROR
- RET ;RETURN TO CALLING ROUTINE
- ;
- ;THE MVIRT IS USED ONLY BY THE MVI COMMAND
- ;
- MVIRT: CALL RG543 ;VALIDATE DESTINATION REGISTER
- ORA A ;SET FLAGS BASED ON A CONTENTS
- RNZ ;RETURN NOT ZERO WITH ERROR
- ;
- ;INSTRUCTIONS REQUIRING AN IMMEDIATE OPERAND USE THE IMMED
- ;ROUTINE
- ;
- IMMED: LDAX B ;LOAD NEXT COMMAND CHARACTER INTO A
- INX B ;INCREMENT COMMAND CHARACTER INDEX
- CPI 'B' ;IS THE CMND CHAR. A 'B' ?
- JZ BINRY ;IF SO THEN PROCESS AS BINARY
- CPI 'Q' ;IS THE COMMAND CHARACTER A 'Q'?
- JZ OCTAL ;IF SO THEN PROCESS AS OCTAL
- CPI 'H' ;IS THE CMND CHAR. AN 'H' ?
- JZ HEX ;IF SO THEN PROCESS AS HEXADECIMAL
- CPI '8' ;IS THE COMMAND CHARACTER LESS THAN '8'?
- JC OCTAD ;IF SO THEN TREAT AS OCTAL
- MVI A,5 ;MOVE ERROR CODE 5 TO A
- JMP ERROR ;GO DISPLAY ERROR 5, INVALID IMMEDIATE
- ;
- ;INSTRUCTIONS USING THE RG543 ROUTINE REQUIRE A DESTINATION
- ;REGISTER
- ;
- RG543: LDAX B ;LOAD NEXT COMMAND CHARACTER INTO A
- INX B ;INCREMENT COMMAND CHARACTER INDEX
- CALL REGAN ;ANALYZE FOR VALID REGISTER
- JNC RGERR ;IF CY=0 THEN REGISTER NOT VALID
- RLC ;SHIFT OCTAL REGISTER VALUE
- RLC ;LEFT THREE
- RLC ; PLACES
- ADD E ;ADD NAKED OPCODE TO SHIFTED VALUE
- MOV E,A ;MOVE RESULT BACK TO E
- XRA A ;CLEAR A INDICATING NO ERRORS
- RET ;RETURN TO CALLING ROUTINE
- ;
- ;INSTRUCTIONS USING THE RG54B ROUTINE ARE INX AND DCX
- ;
- RG54B: LDAX B ;LOAD NEXT COMMAND CHARACTER INTO A
- INX B ;INCREMENT COMMAND CHARACTER INDEX
- CALL REGAN ;ANALYZE FOR VALID REGISTER
- CPI 0 ;IS THE REGISTER A ZERO?
- RZ ;IF SO IT'S 'B' SO RETURN
- MVI A,4 ;MOVE ERROR CODE 4 TO A
- JMP ERROR ;GO DISPLAY ERROR 4, INVALID REGISTER
- ;
- ;THE BINARY ROUTINE CONVERTS A BINARY IMMEDIATE VALUE INTO
- ;USABLE FORM
- ;
- BINRY: MVI H,8 ;MOVE 8 TO H FOR COUNT
- ;
- BLOOP: LDAX B ;LOAD NEXT COMMAND CHARACTER INTO A
- SUI '0' ;SUBTRACT A '0' FROM IT
- CPI 2 ;IS THE RESULT LESS THAN 2?
- JNC IMMER ;IF NOT THEN GO DISPLAY IMMEDIATE ERROR
- PUSH H ;SAVE THE COUNT
- MOV L,D ;MOVE D TO L (IMMEDIATE BYTE)
- DAD H ;SHIFT HL LEFT ONE BIT
- ADD L ;ADD L TO BIT IN A
- MOV D,A ;MOVE THE RESULT BACK TO D
- POP H ;UNSAVE THE COUNT
- INX B ;INCREMENT COMMAND CHARACTER INDEX
- DCR H ;DECREMENT THE COUNT
- JNZ BLOOP ;IF NOT ZERO THEN REITERATE
- XRA A ;CLEAR A INDICATING NO ERRORS
- RET ;RETURN TO CNTRL
- ;
- ;THE IMMEDIATE ERROR ROUTINE IS USED TO INDICATE IMMEDIATE VALUE
- ;ERRORS
- ;
- IMMER: MVI A,6 ;MOVE ERROR CODE 3 TO A
- JMP ERROR ;GO DISPLAY ERROR 3, INVALID IMMEDIATE
- ;
- ;THE OCTAD ENTRY POINT TO THE OCTAL ROUTINE IS FOR THE DEFAULT
- ;CONDITION
- ;
- OCTAD: DCX B ;DECREMENT COMMAND CHARACTER INDEX
- ;
- ;THE OCTAL ROUTINE CONVERTS AN OCTAL IMMEDIATE VALUE INTO
- ;USABLE FORM
- ;
- OCTAL: MVI H,3 ;MOVE A 3 INTO H FOR COUNT
- ;
- OLOOP: LDAX B ;LOAD NEXT COMMAND CHARACTER INTO A
- SUI '0' ;SUBTRACT A '0' FROM IT
- CPI 8 ;IS CMND LESS THAN 8?
- JNC IMMER ;IF NOT GO DISP IMMED ERROR
- PUSH H ;SAVE THE COUNT
- MOV L,D ;MOVE D TO L IMMED BYTE
- DAD H ;SHIFT IMMEDIATE
- DAD H ; BYTE LEFT
- DAD H ; THREE BITS
- ADD L ;ADD L TO VALUE IN A
- MOV D,A ;MOVE RESULT BACK TO D
- POP H ;UNSAVE THE COUNT
- INX B ;INCREMENT COMND CHAR INDEX
- DCR H ;DECREMENT THE COUNT
- JNZ OLOOP ;IF NOT ZERO THEN REITERATE
- XRA A ;CLEAR A INDICATING NO ERRORS
- RET ;RETURN TO CNTRL
- ;
- ;THE HEX ROUTINE COVERTS A HEXADECIMAL IMMEDIATE VALUE INTO
- ;USABLE FORM.
- ;
- HEX: MVI H,2 ;MOVE A 2 INTO H FOR COUNT
- ;
- HLOOP: LDAX B ;LOAD NEXT CMND CHAR INTO A
- SUI '0' ;SUBTRACT '0' FROM IT
- CPI 9+1 ;IS IT LESS THAN '9'+1?
- JC HCHOK ;IF SO THEN NUMERIC CHARACTER IS OK
- SUI 7 ;ELSE CONVERT ALPHABETIC TO NUMERIC
- CPI 15+1 ;IS CHARACTER VALUE GREATER THAN 15?
- JNC IMMER ;IF SO THAN INVALID HEXADECIMAL VALUE
- ;
- HCHOK: PUSH H ;SAVE THE COUNT
- MOV L,D ;MOVE D TO L IMMEDIATE BYTE
- DAD H ;SHIFT IMMEDIATE
- DAD H ; BYTE LEFT
- DAD H ; FOUR
- DAD H ; BITS
- ADD L ;ADD L TO VALUE IN A
- MOV D,A ;MOVE RESULT BACK TO D
- POP H ;UNSAVE THE COUNT
- INX B ;INCREMENT COMMAND CHARACTER INDEX
- DCR H ;DECREMENT THE COUNT
- JNZ HLOOP ;IF NOT ZERO THAN REITERATE
- XRA A ;CLEAR A INDICATING NO ERRORS
- RET ;RETURN TO CNTRL
- ;
- ;THE XQTER ROUTINE EXECUTES THE GENERATED OBJECT CODE FOR
- ;EDUCATOR 8080
- ;
- XQTER: XCHG ;MOVE GENERATED OPCODE TO HL
- SHLD XQTOP ;STORE IT AT EXECUTION POINT
- LHLD PSWA ;LOAD WORKING PSW & A INTO HL
- PUSH H ;PUSH & POP SETS VALUES FOR
- POP PSW ; WORKING REGISTER AND FLAGS
- LHLD BANDC ;LOAD WORKING B AND C INTO HL
- PUSH H ;PUSH & POP SETS VALUES FOR
- POP B ; WORKING B AND C REGISTERS
- ;
- XQTOP: NOP ;THE COMMAND TO BE EXECUTED
- NOP ;IMMEDIATE VALUE OR NOP
- PUSH B ;PUSH B AND C WORKING REGISTER VALUES
- POP H ;POP THEM INTO HL
- SHLD BANDC ;STORE THEM IN SAVE AREA
- PUSH PSW ;PUSH PSW AND A WORKING VALUES
- POP H ;POP THEM INTO HL
- SHLD PSWA ;STORE THEM IN SAVE AREA
- RET ;RETURN TO CNTRL FOR NEXT COMMAND
- ;
- ;THE ERROR ROUTINE IS USED TO DISPLAY ERROR MESSAGES
- ;
- ERROR: PUSH PSW ;SAVE ERROR CODE IN A
- LXI H,ERRSP ;LOAD ADDRESS OF ERROR HEADER SPACES
- CALL CHEDT ;GO OUTPUT ERROR HEADER SPACES
- POP PSW ;UNSAVE ERROR CODE
- LXI H,ERTAB ;LOAD ADDRESS OF ERROR MESSAGE TABLE
- ADD L ;ADD LOW ADDRESS BYTE TO ERROR CODE
- MOV L,A ;MOVE RESULT TO L, POINTS TO OFFSET
- MOV L,M ;MOVE OFFSET TO L
- ;
- ;NOTE: HL NOW CONTAINS THE ADDRESS OR THE ERROR MESSAGE
- ;
- CALL CHEDT ;OUTPUT THE ERROR MESSAGE
- ;
- ERTIM: LXI D,0 ;LOAD DE WITH TIMING LOOP VALUE
- DCR E ;DECREMENT VALUE IN E 256 TIMES
- JNZ ERTIM+1 ;REITERATE LOOP 256 TIMES
- ;
- ;THE ABOVE JMP GOES TO THE FIRST 000 IN THE LXI COMMAND WHICH
- ;IS AN EFFECTIVE NOP
- ;
- DCR D ;DECREMENT D
- JNZ ERTIM+1 ;REITERATE OUTER LOOP 256 TIMES
- MVI A,0FFH ;MOVE A 377 TO A INDICATING ERROR
- RET ;RETURN TO CNTRL
- ;
- OPTAB: DB 'ACI',0CEH
- DW IMMED
- DB 'ADC',88H
- DW RG210
- DB 'ADD',80H
- DW RG210
- DB 'ADI',0C6H
- DW IMMED
- DB 'ANA',0A0H
- DW RG210
- DB 'ANI',0E6H
- DW IMMED
- DB 'CMA',2FH
- DW DIRCT
- DB 'CMC',3FH
- DW DIRCT
- DB 'CMP',0B8H
- DW RG210
- DB 'CPI',0FEH
- DW IMMED
- DB 'DAA',27H
- DW DIRCT
- DB 'DCR',05H
- DW RG543
- DB 'DCX',0BH
- DW RG54B
- DB 'INR',04H
- DW RG543
- DB 'INX',03H
- DW RG54B
- DB 'MOV',40H
- DW MOVRT
- DB 'MVI',06H
- DW MVIRT
- DB 'NOP',00H
- DW DIRCT
- DB 'ORA',0B0H
- DW RG210
- DB 'ORI',0F6H
- DW IMMED
- DB 'RAL',17H
- DW DIRCT
- DB 'RAR',1FH
- DW DIRCT
- DB 'RLC',07H
- DW DIRCT
- DB 'RRC',0FH
- DW DIRCT
- DB 'SBB',98H
- DW RG210
- DB 'SBI',0DEH
- DW IMMED
- DB 'STC',37H
- DW DIRCT
- DB 'SUB',90H
- DW RG210
- DB 'SUI',0D6H
- DW IMMED
- DB 'XRA',0A8H
- DW RG210
- DB 'XRI',0EEH
- DW IMMED
- ;
- ERTAB: DB ERR AND 0FFH,ITL AND 0FFH,ICM AND 0FFH
- DB IRR AND 0FFH,IRR AND 0FFH,IIT AND 0FFH
- DB IIV AND 0FFH,ERR AND 0FFH
- ;
- ITL: DB 'INPUT TOO LONG',80H
- ;
- ICM: DB 'INVALID COMMAND',80H
- ;
- IRR: DB 'INVALID REGISTER',80H
- ;
- IIT: DB 'INVALID IMMED TYPE',80H
- ;
- IIV: DB 'INVALID IMMED VALUE',80H
- ;
- ERR: DB 'ERROR!',80H
- ;
- ERRSP: DB CR,LF,90H,80H
- ;
- TITLS: DB CLR,CR,LF
- DB 9BH,'EDUCATOR-8080',CR,LF
- DB CR,LF,9AH,'<---'
- DB 'BINARY-----'
- DB ' OCT HX',CR,LF
- DB 9AH,'7 6 5 4 3 2 1 0',80H
- ;
- BLINE: DB CR,LF,CR,LF,90H
- DB 'B-REG >> ',80H
- ;
- CLINE: DB CR,LF,CR,LF,90H
- DB 'C-REG >> ',80H
- ;
- AFHDR: DB CR,LF,CR,LF,90H
- DB 'FLAGS & ACC',CR,LF,90H
- DB 'P Z S A C',CR,LF,90H,80H
- ;
- CMDMS: DB CR,LF,CR,LF,90H
- DB 'COMMAND ? ',80H
- ;
- ;CHARACTER OUTPUT ROUTINE
- ;
- CHRPR PUSH PSW
- PUSH B
- PUSH D
- PUSH H
- MOV C,A ;CHARACTER TO C FOR CP/M
- VCONOUT CALL $-$ ;MODIFIED AT INIT
- POP H
- POP D
- POP B
- POP PSW
- RET
- ;
- ;KEYBOARD INPUT ROUTINE
- ;
- KEYBD PUSH B
- PUSH D
- PUSH H
- VCONIN CALL $-$ ;MODIFIED AT INIT
- POP H
- POP D
- POP B
- CPI 'C'-40H ;CONTROL-C FOR EXIT?
- JZ 0 ;YES, REBOOT CP/M
- RET
- ;
- ; DEFINE TEMPORARY STORAGE AREA
- ;
- BANDC: ;B AND C REGISTERS
- CREG: DB 0
- BREG: DB 0
- PSWA: DW 0
- CMDAR: DS 40
- STACK EQU $+60
- ;
- END