home *** CD-ROM | disk | FTP | other *** search
- ;*****************************************************
- ; *
- ; DYNATRACE *
- ; V 2.0 *
- ; *
- ; COPYRIGHT (C) 1976, BY RICHARD E. MEADOR *
- ; SACRAMENTO, CALIFORNIA *
- ; 95826 *
- ; *
- ; ALL RIGHTS RESERVED WITH THE EXCEPTION OF *
- ; REPRODUCTION BY THOSE INDIVIDUALS FOR THEIR OWN *
- ; NONCOMERCIAL USE WHO HAVE PURCHASED DYNATRACE FROM *
- ; AN AUTHORIZED DISTRIBUTOR. *
- ; *
- ;*****************************************************
- ;
- ;
- ;
- ORG 8000H
- DYNAT: DS 400H ;BASE ADDRESS OF PROGRAM
- STACK EQU DYNAT+0C00H ;SET UP SYSTEM STACK
- CONPRT EQU 0C8H ;CONTROL PORT ADDRESS
- SCREEN EQU 0BC00H ;1K OF BUFFER FOR SCREEN
- TOS EQU (SCREEN+1024)/256 ;LAST BUFFER ADDRESS+1
- MIDSCR EQU SCREEN+448 ;TOP LINE OF ROLLUP PORTION OF SCREEN
- LINE EQU 64 ;64 CHARACTERS/LINE
- LINE1 EQU SCREEN+LINE
- LINE2 EQU LINE1+64
- LINE3 EQU LINE2+64
- LINE4 EQU LINE3+64
- LINE5 EQU LINE4+64
- LINE15 EQU SCREEN+960
- PCH EQU LINE1+8 ;PC HEX DISPLAY LOCATION
- INSTA EQU LINE2+8 ;INSTRUCTION ASCII DISPLAY LOCATION
- INSTH EQU LINE2+18 ;INSTRUCTION HEX DISPLAY LOCATION
- SB EQU LINE4+8 ;SIGN FLAG BINARY DISPLAY LOCATION
- ZB EQU LINE4+9 ;ZERO FLAG BINARY DISPLAY LOCATION
- ACB EQU LINE4+11 ;AUX CARRY FLAG BINARY DISPLAY LOCATION
- PB EQU LINE4+13 ;PARITY FLAG BINARY DISPLAY LOCATION
- CYB EQU LINE4+15 ;CARRY FLAG BINARY DISPLAY LOCATION
- ACCH EQU LINE1+22 ;ACCUMULATOR HEX DISPLAY LOCATION
- ACCB EQU LINE1+25 ;ACCUMULATOR BINARY DISPLAY LOCATION
- BCH EQU LINE1+37 ;B REG HEX DISPLAY LOCATION
- BCB EQU LINE1+42 ;B REG BINARY DISPLAY LOCATION
- DEH EQU LINE2+37 ;DE REG PR HEX DISPLAY LOCATION
- DEB EQU LINE2+42 ;DE REG PR BINARY DISPLAY LOCATION
- HLH EQU LINE3+37 ;HL REG PR HEX DISPLAY LOCATION
- HLB EQU LINE3+42 ;HL REG PR BINARY DISPLAY LOCATION
- SPH EQU LINE4+37 ;SP REG PR HEX DISPLAY LOCATION
- KSTAT EQU 6EH
- KEYBRD EQU 6CH
- KBDRDY EQU 80H
- RSTAT EQU 07H
- READER EQU 06H
- RDRRDY EQU 02H
- SWTCHS EQU 0FFH
- CR EQU 0DH
- LF EQU 0AH
- ESC EQU 1BH
- ;
- ;
- ;STORAGE DEFINITION STATEMENTS
- ;
- ORG DYNAT+0B80H ;SYSTEM WORKING STORAGE AREA
- PC1: DS 2 ;USER'S PROGRAM COUNTER STORAGE
- STKPTR: DS 2 ;USER'S STACK POINTER STORAGE
- BC: DS 2 ;USER'S BC REG PR STORAGE
- DE: DS 2 ;USER'S DE REG PR STORAGE
- HL: DS 2 ;USER'S HL REG PR STORAGE
- STSWRD: DS 1 ;USER'S STATUS FLAG STORAGE
- AC: DS 1 ;USER'S ACCUMULATOR STORAGE
- PC: DS 2 ;USER'S PRIMARY PROGRAM COUNTER STORAGE
- BINFLG: DB 0 ;BINARY DISPLAY SWITCH(0=>NO BINARY DISPLAY)
- CPOSIT: DS 2 ;CURSER POSITION FOR ROLLUP PORTION OF SCREEN
- STKTMP: DS 2 ;TEMPORARY STORAGE FOR SYSTEM STACK
- BASE: DS 2 ;BASE ADDRESS STORAGE FOR VARIOUS ROUTINES
- LAST: DS 2 ;LAST ' ' ' ' '
- FROM: DB 'FROM-' ;MESSAGES
- TO: DB 'TO-' ;
- ASCII: DB '0123456789ABCDEF' ;ASCII HEX DIGIT TABLE
- MOVENM: DB 'MOV , ' ;MOVE MNUMONIC
- DB 'COPYRIGHT (C) 1976, RICHARD E. MEADOR'
- ;
- ;CODE BEGINS HERE
- ;
- ORG 100H
- DBYTE EQU 8000H ;PROGRAM WILL RUN HERE
-
- LXI H,0400H ;PROGRAM BASE POINTER
- LXI D,DBYTE ;NEW BASE POINTER
- LOOP MOV A,M ;PICK UP 1ST CHAR
- STAX D ;STORE AT NEW BASE
- INX H
- INX D
- MOV A,H ;MOVE POINTER
- CPI 10H ;
- JNZ LOOP ;DO UNTIL DONE
- JMP DBYTE ;GO TO NEW LOCATION
- ;
- ;
- ;
- ORG DYNAT ;START ADDRESS
- START: LXI SP,STACK ;DEFINE SYSTEM STACK
- CALL CLRSCR ;CLEAR VIDEO SCREEN
- CALL SETSCR ;SET UP DISPLAY OF USER REGISTERS
- MVI A,0 ;CLEAR ACCUMULATOR
- MVI B,14 ;SET CLEAR COUNT
- LXI H,PC1 ;SET FIRST ADDRESS TO BE CLEARED
- VDM010: MOV M,A ;CLEAR
- INX H ;NEXT ADDRESS
- DCR B ;1 LESS TO DO
- JNZ VDM010 ;DONE?
- LXI H,PC1 ;YES, DEFINE USER'S STACK POINTER
- SHLD STKPTR ;
- VDM015: CALL DSREGS ;DISPLAY CONTENTS OF USER'S REGISTERS
- CALL KEYBDI ;GET COMMAND
- CPI 40H ;CHECK FOR ALPHA
- JM VDM020 ;IGNORE IF NOT
- CPI 5BH ;
- JP VDM020 ;
- LXI H,KEYTAB ;GET COMMAND LOCATOR TABLE BASE ADDRESS
- SBI 40H ;SUBTRACT ASCII BIAS FROM RECEIVED COMMAND
- RLC ;DOUBLE FOR WORD INDEXING
- ADD L ;ADD INDEX
- MOV L,A ;
- MVI A,0 ; ADC H ;
- MOV H,A ;
- MOV E,M ;GET COMMAND ADDRESS FROM TABLE
- INX H ;
- MOV D,M ;
- LXI H,VDM020 ;SET UP RETURN ADDRESS
- PUSH H ;SAVE ON STACK
- XCHG ;HL=COMMAND ROUTINE ADDRESS
- PCHL ;(THIS IS REALLY A CALL TO A COMMAND ROUTINE)
- VDM020: LXI H,LINE15 ;RESET CURSOR
- SHLD CPOSIT ;
- JMP VDM015 ;END OF COMMAND PROCESSING LOOP
- ;
- ;COMMAND LOCATOR TABLE
- ;
- KEYTAB: DW UTURN ;A-NOP
- DW BINARY ;B-BINARY DISPLAY TOGGLE
- DW CALSUB ;C-CALL USER SUB-PROGRAM
- DW DUMPME ;D-DUMP MEMORY TO SCREEN
- DW UTURN ;E-NOP
- DW UTURN ;F-NOP
- DW GO ;G-EXECUTE USER PROGRAM INTERPRETIVELY
- DW UTURN ;H-NOP
- DW ISPEED ;I-SET EXECUTION SPEED OF INTERPRETER
- DW UTURN ;J-NOP
- DW UTURN ;K-NOP
- DW LOADRG ;L-LOAD REGISTER PAIR
- DW MEMSTR ;M-STORE BYTES IN CONSECUTIVE MEMORY LOCATIONS
- DW UTURN ;N-NOP
- DW UTURN ;O-NOP
- DW UTURN ;P-NOP
- DW UTURN ;Q-NOP
- DW READTP ;R-READ PAPER TAPE
- DW STEP ;S-INTERPRET ONE INSTRUCTION
- DW UTURN ;T-NOP
- DW UTURN ;U-NOP
- DW UTURN ;V-NOP
- DW UTURN ;W-NOP
- DW UTURN ;X-NOP
- DW UTURN ;Y-NOP
- DW ZERMEM ;Z-ZERO MEMORY
- ;
- ;
- ;
- UTURN: RET ;DUMMY ROUTINE FOR NOP'S
- ;
- ;
- ; CLEAR VDM ROUTINE
- ;
- CLRSCR: MVI A,0 ;CONTROL PORT IINITIALIZATUIION WORD
- OUT CONPRT ;SEND
- LXI B,SCREEN ;BASE ADDRESS OF VDM BUFFER
- CLR010: MVI A,' ' ;ASCII SPACE
- STAX B ;CLEAR 1 BUFFER WORD
- INX B ;UPDATE BUFFER POINTER
- MVI A,TOS AND 0FFH ;LAST BUFFER ADDRESS +1
- CMP B ;CHECK FOR END OF BUFFER AREA
- JNZ CLR010 ;DO UNTIL DONE
- LXI H,LINE15 ;INITIAL CURSOR LOCATION
- SHLD CPOSIT ;STORE TO CURSOR SAVE
- RET ;EXIT
- ;
- ; SET DISPLAY OF USER'S REGISTERS
- ;
- SETSCR: LXI H,'PC' ;PC
- SHLD LINE1+5
- MVI A,'A' ;A
- STA LINE1+20
- LXI H,'BC' ;BC
- SHLD LINE1+34
- LXI H,'IN' ;IN
- SHLD LINE2+2
- LXI H,'ST' ;ST
- SHLD LINE2+4
- MVI A,'R' ;R
- STA LINE2+6
- LXI H,'DE' ;DE
- SHLD LINE2+34
- MVI A,'C' ;C
- STA LINE3+15
- MVI A,'Z' ;Z
- STA LINE3+9
- MVI A,'P' ;P
- STA LINE3+13
- MVI A,'S' ;S
- STA LINE3+8
- MVI A,'A' ;A
- STA LINE3+11
- LXI H,'HL' ;HL
- SHLD LINE3+34
- LXI H,'SP' ;SP
- SHLD LINE4+34
- LXI H,'PS'
- SHLD LINE4+4
- MVI A,'W'
- STA LINE4+6
- MVI A,'0'
- STA LINE4+10
- STA LINE4+12
- INR A
- STA LINE4+14
- RET
- ;
- ;MOVE THE NUMBER OF BYTES INDICATED IN DE
- ;FROM THE ADDRESS BEGINNING IN BC
- ;TO THE ADDRESS BEGINNING IN HL
- ;
- SETLNE: LDAX B ;GETBYTE
- MOV M,A ;TRANSFER
- INX H ;UPDATE DESTINATION POINTER
- INX B ;UPDATE SOURCE POINTER
- DCX D ;UPDATE COUNT
- MOV A,E ;CHECK FOR COMPLETION
- CPI 0 ;
- JNZ SETLNE ;
- MOV A,D ;
- CPI 0 ;
- JNZ SETLNE ;
- RET ;EXIT
- ;
- ; DISPLAY REGISTERS ROUTINE
- ;
- ;THIS ROUTINE DECODES THE USER'S REGISTER INFORMATION
- ; AND FORMATS IT FOR DISPLAY ON THE CRT SCREEN
- ;
- DSREGS: PUSH B ;SAVE ALL REGISTERS
- PUSH D ;
- PUSH H ;
- PUSH PSW ;
- LXI D,PC1 ;
- LXI H,PCH+2 ;
- CALL DSPHEX ;
- LXI D,PC1+1 ;
- LXI H,PCH ;
- CALL DSPHEX ;
- LXI D,STKPTR ;
- LXI H,SPH+2 ;
- CALL DSPHEX ;
- LXI D,STKPTR+1 ;
- LXI H,SPH ;
- CALL DSPHEX ;
- LXI D,BC ;
- LXI H,BCH+2 ;
- CALL DSPHEX ;
- LXI D,BC+1 ;
- LXI H,BCH ;
- CALL DSPHEX ;
- LXI D,DE ;
- LXI H,DEH+2 ;
- CALL DSPHEX ;
- LXI D,DE+1 ;
- LXI H,DEH ;
- CALL DSPHEX ;
- LXI D,HL ;
- LXI H,HLH+2 ;
- CALL DSPHEX ;
- LXI D,HL+1 ;
- LXI H,HLH ;
- CALL DSPHEX ;
- LXI D,AC ;
- LXI H,ACCH ;
- CALL DSPHEX ;
- LDA STSWRD ;
- LXI H,CYB ;
- RAR ;
- MVI M,'0' ;
- JNC DSR010 ;
- MVI M,'1' ;
- DSR010: RAR ;
- RAR ;
- LXI H,PB ;
- MVI M,'0' ;
- JNC DSR020 ;
- MVI M,'1' ;
- DSR020: RAR ;
- RAR ;
- LXI H,ACB ;
- MVI M,'0' ;
- JNC DSR030 ;
- MVI M,'1' ;
- DSR030: RAR ;
- RAR ;
- LXI H,ZB ;
- MVI M,'0' ;
- JNC DSR040 ;
- MVI M,'1' ;
- DSR040: RAR ;
- LXI H,SB ;
- MVI M,'0' ;
- JNC DSR050 ;
- MVI M,'1' ;
- DSR050: POP PSW ;
- POP H ;
- POP D ;
- POP B ;
- LDA BINFLG ;CHECK FOR BINARY DISPLAY FLAG SET
- ANA A ;
- RZ ;DONE IF NOT SET
- PUSH B ;
- PUSH D ;
- PUSH H ;
- PUSH PSW ;
- LXI D,AC ;
- LXI H,ACCB ;
- CALL DSPBIN ;
- LXI D,BC ;
- LXI H,BCB+9 ;
- CALL DSPBIN ;
- LXI D,BC+1 ;
- LXI H,BCB ;
- CALL DSPBIN ;
- LXI D,DE ;
- LXI H,DEB+9 ;
- CALL DSPBIN ;
- LXI D,DE+1 ;
- LXI H,DEB ;
- CALL DSPBIN ;
- LXI D,HL ;
- LXI H,HLB+9 ;
- CALL DSPBIN ;
- LXI D,HL+1 ;
- LXI H,HLB ;
- CALL DSPBIN ;
- POP PSW ;
- POP H ;
- POP D ;
- POP B ;
- RET ;
- ;
- ; DECODE REGISTERS FOR DISPLAY ROUTINE
- ;
- DSPHEX: LDAX D ;GET REGISTER CONTENTS
- RRC ;SCALE ACCUMULATOR DOWN TO GET UPPER HEX DIGIT
- RRC ;
- RRC ;
- RRC ;
- ANI 0FH ;MASK OFF UNWANTED BITS
- LXI B,ASCII ;BASE ADDRESS OF ASCIIDIGIT TABLE
- ADD C ;ADD ACCUMULATOR TO BC TO GET ADDRESS OF DIGIT
- MOV C,A ;
- MVI A,0 ;
- ADC B ;
- MOV B,A ;
- LDAX B ;
- MOV M,A ;STORE ASCII CODE FOR HEX DIGIT
- INX H ;INCREMENT SCREEN POSITION
- LDAX D ;GET REGISTER CONTENTS AGAIN
- ANI 0FH ;DO THE SAME FOR THE LOWER HEX DIGIT
- LXI B,ASCII ;
- ADD C ;
- MOV C,A ;
- MVI A,0 ;
- ADC B ;
- MOV B,A ;
- LDAX B ;
- MOV M,A ;
- RET ;
- ;
- ; DECODE REGISTER TO BINARY DISPLAY ROUTINE
- ;
- DSPBIN: LDAX D ;GET USER REGISTER CONTENTS
- MVI C,8 ;# OF BITS
- DSP010: RAL ;SHIFT UPPER BIT TO CARRY FOR CHECKING
- MVI M,'0' ;ASSUME ZERO
- JNC DSP020 ;CHECK FOR ONE
- MVI M,'1' ;CHANGE IF ONE
- DSP020: INX H ;MOVE TO NEXT SCREEN POSITION
- DCR C ;COUNT OFF
- JNZ DSP010 ;DONE?
- RET ;YES
- ;
- ;SIMULATOR CODE BEGINS HERE
- ; ONE 8080 INSTRUCTION AS INDICATED BY THE USER'S PC REGISTER
- STEP: LHLD PC ;GET USER'S PROGRAM COUNTER VALUE
- SHLD PC1 ;SAVE FOR LAGGING DISPLAY
- MOV A,M ;GET THE CONTENTS OF MEMORY LOCATION INDICATED
- CPI 40H ;CHECK FOR CODES 0-3F HEX
- JC STP010 ;LOW ORDER 64 OPCODES?
- CPI 80H ;NO, CHECK FOR 40-7F HEX
- JNC STP020 ;IS A REGISTER TO REGISTER MOVE INSTRUCTION?
- CALL MOVE ;YES, EXECUTE IT
- RET ;RETURN TO MONITOR
- STP010: CALL OPLOW ;LOW ORDER OP CODES
- RET ;RETURN TO MONITOR
- STP020: CPI 0C0H ;CHECK FOR 80-BF HEX
- JNC STP030 ;ARTHMETIC INSTRUCTION?
- CALL ARITH ;YES, EXECUTE
- RET ;RETURN TO MONITOR
- STP030: CALL OPHIGH ;HIGH ORDER OP CODE
- RET ;RETURN TO MONITOR
- ;
- ; EXECUTE INSTRUCTION ROUTINE
- ;
- OPEXEC: LXI H,0 ;SAVE MONITOR'S STACK POINTER
- DAD SP
- SHLD STKTMP
- LHLD STSWRD ;LOAD REAL REGISTERS WITH USER'S DATA
- PUSH H
- POP PSW
- LHLD STKPTR
- SPHL
- LHLD BC
- MOV B,H
- MOV C,L
- LHLD DE
- XCHG
- LHLD HL
- INSTR: DS 3 ;INSTRUCTION TO BE EXECUTED IS STORED HERE
- ; IF IT WILL NOT CAUSE LOSS OF CONTROL
- SHLD HL ;SAVE USER REGISTER VALUES
- PUSH PSW ;
- POP H ;
- SHLD STSWRD ;
- LXI H,0 ;
- DAD SP ;
- SHLD STKPTR ;
- XCHG ;
- SHLD DE ;
- LHLD STKTMP ;GET MONITOR'S STACK POINTER
- SPHL ;
- MOV H,B ;
- MOV L,C ;
- SHLD BC ;
- RET ;
- ;
- ; MOV COMMAND EXECUTION ROUTINE
- ;
- MOVE: MOV B,A ;SAVE OP CODE
- ANI 07H ;DECODE SOURCE REGISTER
- MVI D,0 ;
- MOV E,A ;
- LXI H,RGSTRS ;
- DAD D ;
- MOV A,M ;GET REGISTER NAME
- STA MOVENM+6 ;SET UP NMEUMONIC
- MOV A,B ;RESTORE OP CODE
- RRC ;
- RRC ;
- RRC ;
- ANI 07H ;DO SAME FOR DESTINATION REGISTER
- MOV E,A ;
- LXI H,RGSTRS ;
- DAD D ;
- MOV A,M ;
- STA MOVENM+4 ;
- MOV A,B ;
- MVI B,1 ;# OF BYTES IN INSTRUCTION
- CALL MVINST ;COPY INSTRUCTION INTO EXECUTION AREA
- LXI H,INSTA ;DISPLAY NMEUMONIC
- LXI B,MOVENM ;
- LXI D,8 ;
- CALL SETLNE ;
- CALL OPEXEC ;GO EXECUTE INSTRUCTION
- RET ;DONE,
- ;
- ; ARITHMETIC INSTRUCTION EXECUTION ROUTINE
- ;
- ARITH: MOV B,A ;SAVE OP CODE
- LXI H,ARITHN ;GET ADDRESS OF ARITH NMEUMONICS
- ANI 38H ;ISOLATE REGISTER OPERAND
- MVI D,0 ;
- MOV E,A ;
- DAD D ;ADD INDEX TO GET APPROPRIATE NMEUMONIC
- PUSH H ;SAVE TEMPORARILY
- MOV A,B ;RESTORE OPCODE
- ANI 07H ;ISOLATE REGISTER OPERAND #
- LXI H,RGSTRS ;GET REGISTER NAME LIST ADDRESS
- MOV E,A ;
- DAD D ;ADD INDEX TO GET CORRECT REGISTER NMEUMONIC
- MOV A,M ;GET NMEUMONIC
- POP H ;RETRIEVE INSTRUCTION NMEUMONIC ADDRESS
- MVI E,4 ;
- DAD D ;
- MOV M,A ;MOVE REGISTER NAME TO MEMORY
- DCX SP ;
- DCX SP ;
- MOV A,B ;RESTORE OP CODE
- MVI B,1 ;SET # OF BYTES IN OPCODE
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- LXI H,INSTA ;DISPLAY NMEUMONIC
- LXI D,8 ;
- POP B ;
- CALL SETLNE ;
- CALL OPEXEC ;GO EXECUTE INSTRUCTION
- RET ;
- ;
- ;ARITHMETIC INSTRUCTION NMEUMONICS
- ;
- ARITHN: DB 'ADD ' ;ADD REGISTER TO ACCUMULATOR
- DB 'ADC ' ;ADD REGISTER+CARRY TO ACCUMULATOR
- DB 'SUB ' ;SUB REGISTER FROM ACCUMULATOR
- DB 'SBB ' ;SUB REGISTER+CARRY FROM ACCUMULATOR
- DB 'ANA ' ;LOGICAL AND REGISTER WITH ACCUMULATOR
- DB 'XRA ' ;LOGICAL EXCLUSIVE OR REGISTER WITH ACCU
- DB 'ORA ' ;LOGICAL OR REGISTER WITH ACCUMULATOR
- DB 'CMP ' ;COMPARE REGISTER WITH ACCUMULATOR
- ;
- ; LOW ORDER INSTRUCTION EXECUTION ROUINE
- ; OP CODES 0-3F HEX
- OPLOW: MOV E,A ;SAVE OP CODE
- ANI 07H ;DETERMINE CLASS AND BRANCH TO APPRPRIATE ROUTINE
- RLC ;
- MOV C,A ;
- MVI B,0 ;
- LXI H,OPTAB ;
- DAD B ;
- MOV A,E ;
- MOV E,M ;
- INX H ;
- MOV D,M ;
- XCHG ;
- PCHL ;
- ;
- ;OP CODE SIMULATION ROUTINE LOOKUP TABLE
- ;
- OPTAB: DW NPINST ; NO-OP ROUTINE POINTER
- DW LXIDAD ; LXI & DAD ROUTINE POINTER
- DW LDSTRX ; LDAX & STAX ROUTIN POINTER
- DW INXDCX ;INX & DCX ROUTINE POINTER
- DW INRDCR ; INR & DCR ROUTINE POINTER
- DW INRDCR ; SAME
- DW MVIMM ; MVI ROUTINE POINTER
- DW ROTATE ; ROTATE POINTER
- ;
- ; A=OP CODE, B= NO. OF BYTES
- ;
- MVINST: STA INSTR ;STORE OP CODE TO EXECUTION AREA
- PUSH B ;SAVE NUMBER OF BYTES IN OP CODE
- CALL HEXASC ;CONVERT OP CODE TO ASCII/HEX EQUIVALANT
- MOV H,C ;TRANSFER FOR DOUBLE LENGTH STORE
- MOV L,B ;
- SHLD INSTH ;STORE ASCII CODES OF OP CODE TO VDM BUFFER
- POP B ;RETRIEVE NUMBER OF BYTES IN INSTRUCTION
- LXI D,INSTR+1 ;GET ADDRESS OF NEXT LOCATION IN EXECUTI
- MVI A,0 ;ZERO NEXT 2 BYTES IN EXECUTION AREA
- STAX D ; IN CASE INSTRUCTION<3 BYTES
- STA INSTR+2 ;
- MVI H,' ' ;CLEAR PREVIOUS EXECUTION FROM SCREEN
- MOV L,H ;
- SHLD INSTH+2 ;
- SHLD INSTH+4 ;
- LXI H,INSTH+2 ;SET TO DISPLAY REST OF INSTRUCTION IF A
- SHLD STKTMP ;SAVE VDM BUFFER LOCATION OF ASCII/HEX DISPLAY A
- LHLD PC ;GET USER'S PROGRAM COUNTER
- INX H ;UPDATE IT
- MVI010: DCR B ;COUNT OFF NUMBER OF BYTES IN INSTRUCTION
- JZ MVI020 ;EXIT IF DONE
- MOV A,M ;GET NEXT BYTE OF INSTRUCTION FROM USER'S PROGRA
- INX H ;UPDATE USER'S PROGRAM COUNTER
- STAX D ;STORE BYTE TO EXECUTION AREA
- INX D ;UPDATE EXECUTION BUFFER POINTER
- PUSH B ;SAVE NUMBER OF BYTES IN INSTRUCTION
- PUSH D ;SAVE EXECUTION BUFFER POINTER
- PUSH H ;SAVE USER'S PROGRAM COUNTER
- CALL HEXASC ;CONVERT NEXT BYTE OF INSTRUCTION TO ASCII/HEX C
- LHLD STKTMP ;RETRIEVE VDM BUFFER LOCATIN OF ASCII/HEX DISPLA
- MOV M,B ;MOVE ASCII/HEX CODES OF CURRENT INSTRUCTION BYT
- INX H ; TO VDM BUFFER AREA
- MOV M,C ;
- INX H ;
- SHLD STKTMP ;SAVE VDM BUFFER LOCATION AGAIN
- POP H ;RETRIEVE USER'S PROGRAM COUNTER
- POP D ;RETRIEVE EXECUTION BUFFER POINTER
- POP B ;RETRIEVE NUMBER OF BYTES LEFT IN INSTRUCTION
- JMP MVI010 ;CONTINUE UNTIL ALL BYTES MOVED
- MVI020: SHLD PC ;STORE UPDATED USER'S PROGRAM COUNTER
- RET ;EXIT
- ;
- ;
- ; MOVE NMUMONIC TO BUFFER
- ;
- MVNMNC: LXI H,INSTA ;GET VDM BUFFER LOCATION OF MNEUMONIC DISPLAY AR
- PUSH D ;SAVE D REGISTER
- LXI D,4 ;SET NUMBER OF BYTES TO TRANSFER
- CALL SETLNE ;DO TRANSFER
- POP B ;GET OLD D REGISTER
- MVI D,' ' ;THE FOLLOWING CODE MOVES THE ASCII CHARACTERS O
- MOV M,D ; THE REGISTERS USED BY THE INSTRUCTION TO THE
- INX H ; THE VDM BUFFER AREA
- MOV M,C ;
- INX H ;
- MOV M,B ;
- INX H ;
- MOV M,D ;
- RET ;
- ;
- ; GET REGISTER PAIR ROUTINE
- ;
- GETRP: ANI 30H ;MASK REGISTER PAIR FIELD
- RRC ;SCALE FOR INDEXING
- RRC ;
- RRC ;
- MOV E,A ;BUILD INDEX IN DE
- MVI D,0 ;
- LXI H,REGPAR ;GET BASE ADDRESS OF REG PAIR MNEUMONICS
- DAD D ;ADD INDEX
- SHLD GET010+1 ;SAVE POINTER
- GET010: LHLD 0 ;0 IS REPLACED BY POINTER FROM ABOVE
- XCHG ;POSITION FOR SUB ROUTINE CALL
- CALL MVNMNC ;DISPLAY OP CODE
- RET ;
- ;
- ; EXECUTE NO-OP ROUTINE
- ;
- NPINST: MVI B,1 ;SET INSTRUCTION LENGTH
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- LXI D,' ' ;NO REGISTER DATA
- LXI B,LOWOP ;ADDRESS OF NOP MNEUMONIC
- CALL MVNMNC ;DISPLAY OP CODE
- CALL OPEXEC ;EXECUTE INSTRUCTION
- RET ;
- ;
- ; EXECUTE LXI AND DAD INSTRUCTIONS ROUTINE
- ;
- LXIDAD: MOV B,A ;SAVE INSTRUCTION
- ANI 08H ;ISOLATE LXI/DAD BIT
- MOV A,B ;RESTORE INSTRUCTION
- MVI B,1 ;ASSUME DAD INSTRUCTION
- JNZ LXI010 ;DAD OR LXI?
- MVI B,3 ;LXI, CHANGE INSTRUCTION LENGTH TO 3 BYTES
- LXI010: PUSH PSW ;SAVE INSTRUCTION DESIGNATOR WHICH IS THE ZERO F
- CALL MVINST ;DISPLAY OP CODE
- POP PSW ;RETRIEVE FLAG
- LXI B,LOWOP1+4 ;ASSUME DAD
- JNZ LXI020 ;DAD/LXI?
- LXI B,LOWOP1 ;LXI, CHANGE POINTER
- LXI020: CALL GETRP ;ISOLATE REG PAIR
- CALL OPEXEC ;EXECUTE INSTRUCTION
- RET ;
- ;
- ; LDA STA LDAX STAX SHLD LHLD EXECUTION ROUTINE
- ;
- LDSTRX: MOV C,A ;SAVE INSTRUCTION
- ANI 20H ;ISOLATE (LDX,STX)/(LHLD,SHLD,LDA,STA) BIT
- MOV A,C ;RESTORE INSTRUCTION
- JNZ LDS020 ;(LDX,STX)/(LHLD,SHLD,LDA,STA)?
- ANI 08H ;ISOLATE LDX/STX BIT
- MOV A,C ;RESTORE INSTRUCTION
- MVI B,1 ;INSTRUCTION LENGTH IS 1 FOR BOTH
- PUSH PSW ;SAVE DESIGNATOR BIT
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- POP PSW ;RETRIEVE DESIGNATOR BIT
- LXI B,LOWOP2 ;ASSUME STAX
- JZ LDS010 ;STAX/LDAX?
- LXI B,LOWOP2+4 ;LDAX, CHANGE MNEUMONIC POINTER
- LDS010: CALL GETRP ;DETERMINE REGISTER PAIR
- JMP LDS030 ;GO EXECUTE
- LDS020: MVI B,3 ;(LHLD,SHLD,LDA,STA), SET LENGTH TO 3 BYTES
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- MOV A,C ;RESTORE INSTRUCTION
- ANI 18H ;ISOLATE INSTRUCTION DESIGNATOR
- RRC ;SCALE FOR INDEXING
- MOV E,A ;BUILD INDEX
- MVI D,0 ;
- LXI H,LOWOP2+8 ;GET BASE ADDRESS OF INSTRUCTION GROUP
- DAD D ;ADD INDEX
- MOV B,H ;POSITION FOR CALL
- MOV C,L ;
- LXI D,' ' ;SET REG TYPE TO NULL
- CALL MVNMNC ;DISPLAY CODE
- LDS030: CALL OPEXEC ;EXECUTE INSTRUCTION
- RET ;
- ;
- ; INX DCX EXECUTION ROUTINE
- ;
- INXDCX: MOV C,A ;SAVE INSTRUCTION
- MVI B,1 ;THESE ARE ALL ONE BYTE
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- MOV A,C ;RESTORE INSTRUCTION
- PUSH PSW ;SAVE IT AGAIN
- ANI 08H ;ISOLATE DESIGNATOR BIT
- LXI B,LOWOP3 ;ASSUME INX
- JZ INX010 ;INX/DCX?
- LXI B,LOWOP3+4 ;DCX, CHAINGE POINTER
- INX010: POP PSW ;GET INSTRUCTION BACK
- CALL GETRP ;DETERMINE REG PAIR
- CALL OPEXEC ;EXECUTE INSTRUCTION
- RET ;
- ;
- ; INR DCR EXECUTION ROUTINE
- ;
- INRDCR: MOV C,A ;SAVE INSTRUCTION
- MVI B,1 ;THESE ARE ALL ONE BYTE
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- MOV A,C ;RESTORE INSTRUCTION
- STA STKTMP ;SAVE IT AGAIN
- LXI B,LOWOP4 ;ASSUME INR
- ANI 01H ;CHECK DESIGNATOR BIT
- JZ INR010 ;INR/DCR?
- LXI B,LOWOP5 ;DCR, CHANGE POINTER
- INR010: LDA STKTMP ;GET INSTRUCTION BACK
- CALL GETREG ;DETERMINE REGISTER
- CALL OPEXEC ;EXECUTE INSTRUCTION
- RET ;
- ;
- ; MVI EXECUTION ROUTINE
- ;
- MVIMM: MOV C,A ;SAVE INSTRUCTION
- MVI B,2 ;THESE ARE ALL 2 BYTE INSTRUCTIONS
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- MOV A,C ;RESTORE INSTRUCTION
- LXI B,LOWOP6 ;SET POINTER MVI MNEUMONIC
- CALL GETREG ;DETERMINE REGISTER
- CALL OPEXEC ;EXECUTE INSTRUCTION
- RET ;
- ;
- ; RLC RRC RAL RAR DAA CMA STC CMC
- ; EXECUTION ROUTINE
- ;
- ROTATE: MOV C,A ;SAVE INSTRUCTION
- MVI B,1 ;THESE ARE ALL ONE BYTE INSTRUCTIONS
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- MOV A,C ;RESTORE INSTRUCTION
- ANI 38H ;ISOLATE DESIGNATOR BITS
- RRC ;SCALE FOR INDEXING
- MOV E,A ;CONSTRUCT INDEX
- MVI D,0 ;
- LXI H,LOWOP7 ;GET BASE OF ADDRESS OF MNEUMONICS
- DAD D ;ADD INDEX
- MOV C,L ;POSITION ADDRESS FOR SUBROUTINE CALL
- MOV B,H ;
- LXI D,' ' ;SET REGISTER TO NULL
- CALL MVNMNC ;DISPLAY OP CODE
- CALL OPEXEC ;EXECUTE INSTRUCTION
- RET ;
- ;
- ; GET REGISTER ROUTINE
- ;
- GETREG: ANI 38H ;ISOLATE REGISTER DESIGNATOR BITS
- RRC ;SCALE FOR INDEXING
- RRC ;
- RRC ;
- MOV E,A ;CONSTRUCT INDEX WORD
- MVI D,0 ;
- LXI H,RGSTRS ;GET BASE ADDRESS OF REGISTER CODES
- DAD D ;ADD INDEX
- MVI E,' ' ;OTHER REGISTER IS NULL
- MOV D,M ;GET THIS REGISTER
- CALL MVNMNC ;DISPLAY OP CODE AND REGISTER
- RET ;
- LOWOP: DB 'NOP ' ;NO-OP
- LOWOP1: DB 'LXI ' ;LOAD REGISTER PAIR IMMEDIATE(EXTENDED)
- DB 'DAD ' ;DOUBLE LENGTH ADD
- LOWOP2: DB 'STAX' ;STORE ACCUMULATOR INDIRECT THROUGH REG PAIR
- DB 'LDAX' ;LOAD ACCUMULATOR INDIRECT THROUGH REG PAIR
- DB 'SHLD' ;STORE HL DIRECT
- DB 'LHLD' ;LOAD HL DIRECT
- DB 'STA ' ;STORE ACCUMULATOR DIRECT
- DB 'LDA ' ;LOAD ACCUMULATOR DIRECT
- LOWOP3: DB 'INX ' ;INCREMENT REGISTER PAIR
- DB 'DCX ' ;DECREMENT REGISTER PAIR
- LOWOP4: DB 'INR ' ;INCREMENT REGISTER
- LOWOP5: DB 'DCR ' ;DECREMENT REGISTER
- LOWOP6: DB 'MVI ' ;MOVE DATA IMMEDIATE TO REGISTER
- LOWOP7: DB 'RLC ' ;ROTATE LEFT THROUGH CARRY
- DB 'RRC ' ;ROTATE RIGHT THROUGH CARRY
- DB 'RAL ' ;ROTATE ARITHMETIC LEFT
- DB 'RAR ' ;ROTATE ARITHMETIC RIGHT
- DB 'DAA ' ;DECIMAL ADJUST ACCUMULATOR
- DB 'CMA ' ;COMPLIMENT ACCUMULATOR
- DB 'STC ' ;SET CARRY
- DB 'CMC ' ;COMPLIMENT CARRY
- RGSTRS: DB 'BCDEHLMA' ;REGISTER CODES
- REGPAR: DB 'B D H SP' ;REGISTER PAIR CODES
- FLAGS: DB 'NZZ NCC POPEP M ' ;STATUS FLAG CODES
- ;
- ;
- ;
- KEYBDI: PUSH H ;SAVE HL
- LHLD CPOSIT ;GET CURSOE POSITION
- KEY005: IN KSTAT ;CHECK 3P+S STATUS
- ANI KBDRDY ;LOOK FOR KEY BOARD READY
- JNZ KEY005 ;LOOP ON NO DATA AVAILABLE
- IN KEYBRD ;GET DATA FROM ASCII KEYBOARD
- ANI 7FH ;STRIP OFF PARITY BIT
- MOV B,A ;SAVE CHARACTER
- CPI ESC ;CHECK FOR ESCAPE SEQUENCE
- JNZ KEY007 ;WAS IT?
- LXI SP,STACK ;YES, RESET STACK POINTER
- CALL BMPLNE ;SCROLL UP ONE LINE
- JMP VDM015 ;RESUME SCAN LOOP
- KEY007: CPI CR ;CHECK FOR CARRIAGE RETURN
- JZ KEY020 ;WAS IT
- KEY010: MOV M,A ;NO, DISPLAY CHARACTER
- INX H ;UPDATE CURSER
- MOV A,H ;CHECK FOR VDM BUFFER OVERFLOW
- CPI TOS AND 0FFH ;
- JC KEY030 ;
- KEY020: CALL BMPLNE ;SCROLL UP ON BUFFER FULL
- LXI H,LINE15 ;RESET CURSOR TO BEGINNING OF LAST LINE
- KEY030: MOV A,B ;RESTORE CHARATER RECEIVED FROM KEYBOARD
- SHLD CPOSIT ;STORE UPDATED CURSOR
- POP H ;RESTORE ORIGINAL CONTENTS OF HL
- RET ;
- ;
- ;
- ;
- BMPLNE: PUSH H ;SAVE HL
- PUSH D ;SAVE DE
- PUSH B ;SAVE BC
- PUSH PSW ;SAVE PSW
- LXI H,MIDSCR ;BUFFER ADDRESS TO MOVE OLD DATA TO
- LXI B,MIDSCR+LINE ;BUFFER ADDRESS TO GET OLD DATA FROM
- MVI E,8 ;NUMBER OF LINES TO BE SCROLLED
- BMP010: PUSH D ;SAVE
- LXI D,64 ;NUMBER OF CHARACTERS PER LINE
- CALL SETLNE ;SCROLL ONE LINE AT A TIME FROM THE TOP DOWN
- POP D ;GET NUMBER OF LINES LEFT TO GO
- DCR E ;COUNT OFF ONE MORE
- JNZ BMP010 ;DO UNTIL DONE
- MVI A,' ' ;STE TO SPACE OUT LAST LINE
- MVI D,64 ;BLANK OUT ALL CHARACTERS ON LAST LINE
- LXI H,LINE15 ;GET ADDRESS OF FIRST CHARACTER OF LAST
- BMP020: MOV M,A ;BLANK IT OUT
- INX H ;UPDATE POINTER
- DCR D ;COUNT DOWN
- JNZ BMP020 ;DO WHILE NOT DONE
- LXI H,LINE15 ;RESET CURSOR
- SHLD CPOSIT ;
- POP PSW ;RESTORE ORIGINAL REGISTER CONTENTS
- POP B ;
- POP D ;
- POP H ;
- RET ;
- ;
- ;
- ;
- BINARY: LDA BINFLG ;GET BINARY DISPLAY FLAG
- CMA ;TOGGLE IT
- STA BINFLG ;PUT IT BACK
- CALL CLRSCR ;RESET SCREEN
- CALL SETSCR ;
- RET ;
- ;
- ;
- ;
- GTLMTS: CALL BMPLNE ;SCROLL UP
- LXI B,FROM ;DISPLAY FROM MESSAGE
- LXI H,LINE15 ;
- LXI D,5 ;
- CALL SETLNE ;
- LXI H,LINE15+5 ;
- SHLD CPOSIT ;
- CALL GETADR ;GET ONE HEX NUMBER OF UP TO 4 DIGITS
- SHLD BASE ;THAT WAS THE BASE ADDRESS
- CALL BMPLNE ;SCROLL UP
- LXI B,TO ;DISPLAY TO MESSAGE
- LXI H,LINE15 ;
- LXI D,3 ;
- CALL SETLNE ;
- LXI H,LINE15+3 ;
- SHLD CPOSIT ;
- CALL GETADR ;GET ONE HEX NUMBER
- XCHG ;MOVE TO DE
- LHLD BASE ;GET BASE ADDRESS
- CALL BMPLNE ;SCROLL UP
- RET ;
- ;
- ;
- ;
- DUMPME: CALL GTLMTS ;GET DUMP LIMITS
- DMP010: PUSH D ;SAVE LAST ADDRESS
- CALL DMEM16 ;DISPLAY 16 BYTES
- POP D ;GET LAST ADDRESS
- MOV A,E ;SEE IF LAST ADDRESS EXCEEDED
- SUB L ;
- MOV A,D ;
- SBB H ;
- JP DMP010 ;CONTINUE DUMPING IF NOT
- RET ;
- ;
- ;
- ;
- GETBYT: MVI E,2 ;GET TWO CHARACTERS FROM KEY BOARD
- JMP GTA005 ;GO AROUND NEXT ENTRY POINT
- GETADR: MVI E,4 ;GET 4 CHARACTERSFROM KEYBOARD
- GTA005: LXI H,0 ;START WITH ZERO
- GTA010: CALL KEYBDI ;GET ACHARACTER FROM THE KEYBOARD
- CPI CR ;CHECK FOR TERMINATOR
- JZ GTA020 ;EXIT ON END OF NUMBER
- CALL ASCHEX ;CONVERT CHARACTER TO HEX DIGIT
- MOV C,A ;POISITION FOR ADD
- MVI B,0 ;
- DAD H ;MULTIPLY HL BY 16
- DAD H ;
- DAD H ;
- DAD H ;
- DAD B ;ADD LAST CHARACTER RECIEVED
- DCR E ;COUNT OFF NUMBER OF DIGITS
- JNZ GTA010 ;DO UNTIL COUNT EXAUSTED OR CARRIAGE RETURN
- GTA020: RET ;
- ;
- ;
- ;
- ASCHEX: SBI '0' ;SUBTRACT OFF ASCII BIAS
- JM ASC010 ;CHAR<0?
- CPI 10 ;NO,
- RC ;DONE IF CHAR<=9
- SBI 07H ;ADJUST FOR ALPHA BIAS
- CPI LF ;
- JC ASC010 ;
- CPI 10H ;CHAR>0FH?
- RC ;NO, RETURN
- ASC010: MVI A,0 ;RETURN ZERO IF ILLEAGLE
- RET ;
- ;
- ;DUMP 16 BYTES TO TTY
- ;
- DMEM16: MOV A,L ;DISPLAY ADDRESS
- CALL HEXASC ;
- PUSH B ;
- MOV A,H ;
- CALL HEXASC ;
- LXI D,LINE15 ;
- XCHG ;
- MOV M,B ;
- INX H ;
- MOV M,C ;
- INX H ;
- POP B ;
- MOV M,B ;
- INX H ;
- MOV M,C ;
- MVI B,16 ;NUMBER OF BYTES TO DISPLAY
- DME010: PUSH B ;SAVE
- INX H ;UPDATE ADDRESS
- LDAX D ;GET BYTE FROM MEMORY
- INX D ;UPDATE POINTER
- CALL HEXASC ;CONVERT TO ASCII CHARACTERS AND DISPLAY
- INX H ;
- MOV M,B ;
- INX H ;
- MOV M,C ;
- POP B ;
- DCR B ;
- JNZ DME010 ;DO UNTIL ALL 16 DISPLAYED
- CALL BMPLNE ;SCROLL UP
- XCHG ;
- RET ;
- ;
- ;CONVERT BYTE IN ACCUMULATOR TO ASCII DIGITS
- ;
- HEXASC: PUSH D ;SAVE DE
- PUSH H ;SAVE HL
- LXI H,ASCII ;GET BASE ADDRESS OF ASCII CODE
- MOV B,A ;SAVE DATA
- ANI 0FH ;DO LOWER HEX DIGIT FIRST
- MOV E,A ;SET UP FOR INDEXING
- MVI D,0 ;
- DAD D ;ADD INDEX
- MOV C,M ;GET CHARACTER
- MOV A,B ;RESTORE DATA
- ANI 0F0H ;DO UPPER HEX DIGIT
- RRC ;SCALE DOWN FOR INDEXING
- RRC ;
- RRC ;
- RRC ;
- MOV E,A ;SET UP FOR INDEXING
- LXI H,ASCII ;GET BASE ADDRESS OF ASCII CODES AGAIN
- DAD D ;ADD INDEX
- MOV B,M ;GET CHARACTER
- POP H ;RESTORE HL
- POP D ;RESTORE DE
- RET ;
- ;
- ;LOAD REGISTERS FROM KEYBOARD ROUTINE
- ;
- LOADRG: CALL KEYBDI ;GET REGISTER IDENTIFIER
- LXI H,LDREGS ;DETERMINE SELECTED REGISTER
- MVI D,6 ;6 POSSIBLE REGISTER PAIRS
- MOV B,A ;SAVE REGISTER DESIGNATOR
- LOA010: MOV A,M ;GET ONE FROM MEMORY
- CMP B ;CHECK AGAINST SELECTED REGISTER PAIR
- JZ LOA020 ;MATCH
- INX H ;NO, KEEP LOOKING
- DCR D ;
- JNZ LOA010 ;
- RET ;RETURN IF NOT FOUND
- LOA020: MOV A,D ;GET INDEX NUMBER
- DCR A ;ADJUST
- RLC ;SCALE
- MOV E,A ;SET UP INDEX
- MVI D,0 ;
- PUSH D ;SAVE INDEX
- CALL GETADR ;GET A HEX NUMBER FROM KEYBOARD
- XCHG ;RELOCATE NUMBER TO LESS CONVENIENT REGISTER
- POP H ;GET INDEX BACK
- MOV A,L ;MOVE TO ACCUMULATOR
- ANA A ;SET FLAGS
- JNZ LOA030 ;IS IT THE PC REGISTER?
- PUSH H ;YES,
- LXI B,PC ;GET ADDRESS OF USER'S PC REG
- DAD B ;THIS IS REDUNDANT
- MOV M,E ;STORE DATA TO USER'S PC REGISTER
- INX H ;
- MOV M,D ;
- POP H ;
- LOA030: LXI B,PC1 ;STORE DATE TO USER REGISTER
- DAD B ;
- MOV M,E ;
- INX H ;
- MOV M,D ;
- CALL BMPLNE ;
- RET ;
- LDREGS: DB 'AHDBSP' ;POSSIBLE REGISTER DESIGNATIONS
- ;
- ;STORE DATA TO MEMORY ROUTINE
- ;
- MEMSTR: CALL GETADR ;GET BEGINNING ADDRESS
- MEM010: PUSH H ;SAVE IT
- LHLD CPOSIT ;GET CURSOR POSITION
- MVI A,'-' ;DISPLAY PROMPT
- MOV M,A ;
- INX H ;UPDATE CURSOR
- SHLD CPOSIT ;RESTORE UPDATED CURSOR
- CALL GETBYT ;GET A DATA BYTE
- MOV A,E ;GET NUMBER OF BYTES RECIEVED
- CPI 2 ;CHECK FOR NONE RECIEVED
- JNZ MEM020 ;ANY DATA RECIEVED?
- POP H ;NO, RESTORE HL
- RET ;GET OUT OF HERE
- MEM020: MOV A,L ;MOVE DATA BYTE TO ACCUMULATOR
- POP H ;GET ADDRESS BACK
- MOV M,A ;STORE DATA TO MEMORY
- INX H ;UPDATE ADDRESS
- JMP MEM010 ;CONTINUE
- ;
- ;CALL USER SUBROUTINE
- ;
- CALSUB: LHLD CPOSIT ;GET CURSOE POSITION
- MVI A,'-' ;DISPLAY PROMPT
- MOV M,A ;
- INX H ;UPDATE CURSOR POSITION
- SHLD CPOSIT ;RESTORE CURSOR
- MVI A,0CDH ;LOAD ACCUMULATOR WITH A CALL INSTRUCTION
- STA INSTR ;MOVE TO EXECUTION AREA
- CALL GETADR ;GET ADDRESS OF SUBROUTINE TO BE EXECUTED
- SHLD INSTR+1 ;STORE ADDRESS TO EXECUTION AREA PLUS ONE
- CALL BMPLNE ;SCROLL UP
- CALL OPEXEC ;EXECUTE SUBROUTINE
- CALL CLRSCR ;CLEAR ANY GARBAGE FROM SCREEN
- CALL SETSCR ;SET UPSCREEN AGAIN
- RET ;
- ;
- ;HIGH ORDER INSTRUCTION DECODE ROUTINE
- ;
- OPHIGH: MOV E,A ;SAVE INSTRUCTION
- ANI 07H ;DETERMINE SUB CLASS
- RLC ;SCALE FOR INDEX
- MOV C,A ;POSITION FOR INDEXING
- MVI B,0 ;
- LXI H,HOPTAB ;GET HIGH ORDER INSTRUCTION TABLE BASE A
- DAD B ;ADD INDEX
- MOV A,E ;RESTORE INSTRUCTION
- MOV E,M ;GET ADDRESS OF INSTRUCTION ROUTINE
- INX H ;
- MOV D,M ;
- XCHG ;MOVE TO HL
- PCHL ;PASS CONTROL TO APPROPIATE ROUTINE
- ;
- HOPTAB: DW RETURN ;RETURN
- DW PPINST ;POP
- DW JUMP ;JUMP
- DW MISC ;MISC
- DW CLINST ;CALL
- DW PSINST ;PUSH
- DW IMMEDT ;IMMEDIATE
- DW RESTRT ;RESTART
- ;
- HIGHOP: DB 'R ' ;CONDITIONAL RETURN
- HIHOP1: DB 'POP ' ;POP
- DB 'RET ' ;UNCONDITIONAL ROUTINE
- DB '*NOP' ;UNIMPLEMENTED OP CODES
- DB 'PCHL' ;INDIRECT JUMP
- DB 'SPHL' ;LOAD STACK POINTER WITH HL
- HIHOP2: DB 'J ' ;CONDITIONAL JUMP
- HIHOP3: DB 'JMP ' ;UNCONDITIONAL JUMP
- DB '*NOP' ;UNIMPLEMENTED OP CODE
- DB 'OUT ' ;OUTPUT
- DB 'IN ' ;INPUT
- DB 'XTHL' ;EXCHANGE HL AND TOP OF STACK
- DB 'XCHG' ;EXCHANGE HL AND DE
- DB 'DI ' ;DISABLE INTERRUPTS
- DB 'EI ' ;ENABLE INTERRUPTS
- HIHOP4: DB 'C ' ;CONDITIONAL CALL
- HIHOP5: DB 'PUSH' ;PUSH
- DB 'CALL' ;UNCONDITIONAL CALL
- DB '*NOP' ;UNIMPLEMENTED OP CODE
- HIHOP6: DB 'ADI ' ;ADD IMMEDIATE
- DB 'ACI ' ;ADD IMMEDIATE WITH CARRY
- DB 'SUI ' ;SUBTRACT IMMEDIATE
- DB 'SBI ' ;SUBTRACT IMMEDIATE WITH BORROW
- DB 'ANI ' ;AND IMMEDIATE
- DB 'XRI ' ;EXCLUSIVE OR IMMEDIATE
- DB 'ORI ' ;OR IMMEDIATE
- DB 'CPI ' ;COMPARE IMMEDIATE
- HIHOP7: DB 'RST ' ;RESTART
- ;
- ;DETERMINE CONDITIONAL FLAG ROUTINE
- ;
- GTFLAG: ANI 38H ;ISOLATE CONDITION BITS
- PUSH H ;SAVE HL
- RRC ;SCALE FOR INDEXING
- RRC ;
- MVI D,0 ;
- MOV E,A ;CONSTRUCT INDEX
- LXI H,FLAGS ;GET BASE ADDRESS OF FLAG CODES
- DAD D ;ADD INDEX
- MOV A,M ;GET FLAG CODE
- STAX B ;STORE TO VDM BUFFER
- INX B ;UPDATE POINTER
- INX H ;UPDATE FLAG LOCATOR
- MOV A,M ;GET SECOND CHARACTER OF FLAG
- STAX B ;DISPLAY IT
- LXI D,' ' ;OTHER CHARACTERS ARE BLANK
- POP B ;GET OLD HL
- CALL MVNMNC ;DISPLAY OP CODE
- RET ;
- ;
- ;TEST FLAG FOR CONDITION
- ;
- TSTFLG: ANI 38H ;ISOLATE FLAG
- ORI 0C0H ;ASSEMBLE A RETURN ON CONDITION INSTRUCTION
- STA TST010 ;STORE FOR LATER EXECUTION
- LHLD STSWRD ;GET USER STATUS WORD
- PUSH H ;MOVE TO REAL FLAGS
- POP PSW ;
- MVI A,1 ;A=1 MEANS CONDITION TRUE
- TST010: RET ;THIS IS REPLACED BY A CONDITIONAL RETURN
- MVI A,0 ;CLEAR A IF CONDITION FALSE
- RET ;
- ;
- ;CONDITIONAL JUMPS
- ;
- JUMP: LHLD PC ;GET USER PROGRAM COUNTER
- PUSH H ;SAVE IT
- PUSH PSW ;SAVE PSW
- MVI B,3 ;THIS IS 3 BYTES
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- POP PSW ;GET PSW BACK
- PUSH PSW ;SAVE IT AGAIN
- LXI H,HIHOP2 ;ADDRESS OF MNEUMONIC
- LXI B,HIHOP2+1 ;ADDRESS TO PUT FLAG INTO
- CALL GTFLAG ;WHAT CONDITION?
- POP PSW ;GET INSTRUCTION BACK
- CALL TSTFLG ;TEST CONDITION
- POP H ;GET PC AGAIN
- ANA A ;CHECK RESULT OF FLAG TEST
- RZ ;RETURN IF RESULT WAS NEGATIVE
- INX H ;UPDATE PC
- MOV A,M ;GET ADDRESS TO JUMP TO
- STA PC ;AND STORE TO USER'S PROGRAM COUNTER
- INX H ;
- MOV A,M ;
- STA PC+1 ;
- RET ;
- ;
- ;THIS ROUTINE PROCESSES ALL IMMEDIATE MODE COMMANDS
- ;
- IMMEDT: MOV C,A ;SAVE INSTRUCTION
- MVI B,2 ;ALL ARE 2 BYTES
- CALL MVINST ;MOVE INSTRUCTION TO EXECUTION AREA
- MOV A,C ;RSTORE INSTRUCTION
- ANI 38H ;DETERMINE TYPE OF IMMEDIATE INSTRUCTION
- RRC ;SCALE FOR INDEXING
- MOV E,A ;POSITION FOR INDEXING
- MVI D,0 ;
- LXI H,HIHOP6 ;GET BASE ADDRESS OF IMMEDIATE CODES
- DAD D ;ADD INDEX
- MOV B,H ;POSITION FOR SUBROUTINE CALL
- MOV C,L ;
- LXI D,' ' ;OTHER CHARACTERS ARE BLANK
- CALL MVNMNC ;DISPLAY MNEUMONIC
- CALL OPEXEC ;EXECUTE INSTRUCTION
- RET ;
- ;
- ;MISCELANEOUS INSTRUCTIONS
- ;
- MISC: PUSH PSW ;SAVE INSTRUCTION
- ANI 38H ;DETERMINE TYPE
- RRC ;
- MOV E,A ;
- MVI D,0 ;
- LXI H,HIHOP3 ;
- DAD D
- MOV C,L ;
- MOV B,H ;
- LXI D,' ' ;
- CALL MVNMNC ;DISPLAY CODE
- POP PSW ;GET INSTRUCTION
- CPI 0E3H ;
- JNC XSDE ;
- CPI 0D3H ;
- JNC IO ;
- CPI 0CBH ;
- JNC NOOP ;
- MVI B,3 ;
- CALL MVINST ;
- LHLD PC ;
- DCX H ;
- MOV A,M ;
- STA PC+1 ;
- DCX H ;
- MOV A,M ;
- STA PC ;
- RET ;
- NOOP: LXI B,HIHOP5+8 ;
- LXI D,' ' ;
- CALL MVNMNC ;
- MVI B,1 ;
- CALL MVINST ;
- RET ;
- IO: MVI B,2 ;
- CALL MVINST ;
- CALL OPEXEC ;
- RET ;
- XSDE: MVI B,1 ;
- CALL MVINST ;
- CALL OPEXEC ;
- RET ;
- ;
- ;CONDITIONAL CALL ROUTINE
- ;
- CLINST: PUSH PSW ;
- MVI B,3 ;
- CALL MVINST ;
- POP PSW ;
- PUSH PSW ;
- LXI H,HIHOP4 ;
- LXI B,HIHOP4+1 ;
- CALL GTFLAG ;
- POP PSW ;
- CALL TSTFLG ;
- ANA A ;
- RZ
- CAL010: LHLD PC ;
- XCHG ;
- LHLD STKPTR ;
- DCX H ;
- MOV M,D ;
- DCX H ;
- MOV M,E ;
- SHLD STKPTR ;
- LHLD PC ;
- DCX H ;
- MOV A,M ;
- STA PC+1 ;
- DCX H ;
- MOV A,M ;
- STA PC ;
- RET ;
- ;
- ;CONDITIONAL RETURN
- ;
- RETURN: PUSH PSW ;
- MVI B,1 ;
- CALL MVINST ;
- POP PSW ;
- PUSH PSW ;
- LXI H,HIGHOP ;
- LXI B,HIGHOP+1 ;
- CALL GTFLAG ;
- POP PSW ;
- CALL TSTFLG ;
- ANA A ;
- RZ ;
- RET010: LHLD STKPTR ;
- MOV A,M ;
- STA PC ;
- INX H ;
- MOV A,M ;
- STA PC+1 ;
- INX H ;
- SHLD STKPTR ;
- RET ;
- ;
- ;MISCELAEOUS STACK INSRUCTIONS
- ;
- STKWRD: DB ' B D H PSW' ;
- ;
- PPINST: PUSH PSW ;
- ANI 08H ;
- JNZ NOTPOP ;
- LXI B,HIHOP1 ;
- POP010: LXI D,4 ;
- LXI H,INSTA ;
- CALL SETLNE ;
- POP PSW ;
- PUSH PSW ;
- ANI '0' ;
- RRC ;
- RRC ;
- MOV C,A ;
- MVI B,0 ;
- LXI H,STKWRD ;
- DAD B ;
- MOV B,H ;
- MOV C,L ;
- LXI H,INSTA+4 ;
- LXI D,4 ;
- CALL SETLNE ;
- POP PSW ;
- MVI B,1 ;
- CALL MVINST ;
- CALL OPEXEC ;
- RET ;
- NOTPOP: POP PSW ;
- CPI 0C9H ;
- JNZ NOTRET ;
- MVI B,1 ;
- CALL MVINST ;
- LXI B,HIHOP1+4 ;
- LXI D,' ' ;
- CALL MVNMNC ;
- JMP RET010 ;
- NOTRET: CPI 0F9H ;
- JNZ NTSPHL ;
- MVI B,1 ;
- CALL MVINST ;
- LXI B,HIHOP1+16 ;
- LXI D,' ' ;
- CALL MVNMNC ;
- LHLD HL ;
- SHLD STKPTR ;
- RET ;
- NTSPHL: CPI 0E9H ;
- JNZ NOOP ;
- MVI B,1 ;
- CALL MVINST ;
- LXI B,HIHOP1+12 ;
- LXI D,' ' ;
- CALL MVNMNC ;
- LXI H,HL ;
- MOV A,M ;
- STA PC ;
- INX H ;
- MOV A,M ;
- STA PC+1 ;
- RET ;
- ;
- ;PUSH AND UNCONDITIONAL CALL
- ;
- PSINST: PUSH PSW ;
- ANI 08H ;
- JNZ CALLUN ;
- LXI B,HIHOP5 ;
- JMP POP010 ;
- CALLUN: POP PSW ;
- CPI 0CDH ;
- JNZ NOOP ;
- LHLD PC ;
- PUSH H ;
- MVI B,3 ;
- CALL MVINST ;
- LXI B,HIHOP5+4 ;
- LXI D,' ' ;
- LXI H,INSTA ;
- CALL MVNMNC ;
- POP B ;
- JMP CAL010 ;
- ;
- ;RESTARTS
- ;
- RESTRT: PUSH PSW ;
- MVI B,1 ;
- POP PSW ;
- PUSH PSW ;
- ANI 38H ;
- RRC ;
- RRC ;
- RRC ;
- CALL HEXASC ;
- MOV D,C ;
- MVI E,' ' ;
- LXI B,HIHOP7 ;
- CALL MVNMNC ;
- LHLD PC ;
- XCHG ;
- LHLD STKPTR ;
- DCX H ;
- MOV M,D ;
- DCX H ;
- MOV M,E ;
- SHLD STKPTR ;
- POP PSW ;
- ANI 38H ;
- MOV L,A ;
- MVI H,0 ;
- SHLD PC ;
- RET ;
- ;
- ;THE GO ROUTINE CONTROLS SIMULATED EXECUTION OF USER PROGRAMS
- ;
- GO: LHLD CPOSIT ;
- MVI A,'-' ;
- MOV M,A ;
- INX H ;
- SHLD CPOSIT ;
- CALL GETADR ;
- SHLD PC ;
- CALL BMPLNE ;
- LXI B,STPADR ;
- LXI D,8 ;
- LXI H,LINE15 ;
- CALL SETLNE ;
- LXI H,LINE15+8 ;
- SHLD CPOSIT ;
- CALL GETADR ;
- CALL BMPLNE ;
- XCHG ;
- GO010: LHLD PC ;
- MOV A,D ;
- SUB H ;
- JNZ GO020 ;
- MOV A,E ;
- SUB L ;
- RZ ;
- GO020: PUSH D ;
- PUSH H ;
- LHLD INSTSP ;
- GO030: DCX H ;
- MVI D,10H ;
- GO040: DCR D ;
- JNZ GO040 ;
- MOV A,H ;
- ANA A ;
- JNZ GO030 ;
- CALL STEP ;
- CALL DSREGS ;
- POP H ;
- POP D ;
- IN KSTAT ;
- ANI KBDRDY ;
- RZ ;REPLACE WITH RNZ FOR BOARDS WITH INVERTED I/O STATUS
- JMP GO010 ;
- STPADR: DB 'STOP AT-' ;
- ;
- ;THIS ROUTINE READS INTEL FORMAT TAPES
- ;
- READTP: CALL BMPLNE ;
- CALL TAPEIN ;
- MOV A,C ;
- RZ ;
- MVI B,0 ;
- LXI D,16 ;
- SUI 10H ;
- MOV C,A ;
- LXI H,ERRMES ;
- DAD B ;
- MOV B,H ;
- MOV C,L ;
- LHLD CPOSIT ;
- CALL BMPLNE ;
- CALL SETLNE ;
- CALL BMPLNE ;
- RET ;
- ;
- ;
- ;
- ;
- TAPEIN: MVI C,0 ;
- MVI A,0FFH ;
- OUT SWTCHS ;
- BBLK: CALL INPUT ;
- CPI 3AH ;
- JNZ BBLK ;
- MVI B,0 ;
- CALL RDBYTE ;
- MOV D,A ;
- CALL RDBYTE ;
- MOV H,A ;
- CALL RDBYTE ;
- MOV L,A ;
- CALL RDBYTE ;
- MOV E,D ;
- INR E ;
- LD10: DCR E ;
- JZ LD20 ;
- MOV A,L ;
- CMA ;
- OUT SWTCHS ;
- CALL RDBYTE ;
- MOV M,A ;
- CMP M ;
- INX H ;
- JZ LD10 ;
- MVI C,20H ;
- RET ;
- LD20: MOV A,H ;
- CMA ;
- OUT SWTCHS ;
- CALL RDBYTE ;
- MOV A,B ;
- ORA A ;
- JZ NBLK ;
- MVI C,10H ;
- RET ;
- NBLK: MOV A,D ;
- ORA A ;
- JNZ BBLK ;
- RET ;
- ;
- ;
- ;
- RDBYTE: PUSH D ;SAVE LENGTH
- CALL INDIGT ;GET 1 HEX DIGIT FROM TAPE
- ADD A ;MULTIPLY BY 16
- ADD A ;
- ADD A ;
- ADD A ;
- MOV D,A ;SAVE MSD
- CALL INDIGT ;GET NEXT HEX DIGIT FROM TAPE
- ORA D ;COMBINE HEX DIGITS TO FORM BYTE
- MOV D,A ;SAVE BYTE WHILE DOING CHKSUM
- ADD B ;ADD CHKSUM TO THE NEW BYTE
- MOV B,A ;REPLACE OLD CHKSUM WITH NEW
- MOV A,D ;GET NEW BYTE BACK
- POP D ;RESTORE LENGTH
- RET
- ;
- ;
- ;
- INDIGT: CALL INPUT ;READ A FRAME FROM TAPE
- CPI '9'+1 ;INSPECT DATA
- JM IND010 ;OK IF DATA < 10
- ADI 9 ;ELSE ADJUST FOR ASCII BIAS
- IND010: ANI 0FH ;REDUCE MOD 16
- RET ;
- ;
- ;
- INPUT: IN RSTAT ;GET READER STATUS FROM 3P+S
- ANI RDRRDY ;TURN OFF NON READER BITS
- JNZ INPUT ;LOOP UNTIL DATA AVAILABLE
- IN READER ;GET DATA
- ANI 7FH ;CLEAR PARITY BIT
- RET ;
- ;
- ;TAPE READER ROUTINE ERROR MESSAGES
- ;
- ERRMES: DB 'CHECK SUM ERROR '
- DB 'MEMORY FAILURE '
- ;
- ;THIS ROUTINE ZEROES A BLOCK OF MEMORY
- ;
- ZERMEM: CALL GTLMTS ;
- ZER010: MVI A,0 ;
- MOV M,A ;
- INX H ;
- MOV A,D ;
- SUB H ;
- JNZ ZER010 ;
- MOV A,E ;
- SUB L ;
- JNZ ZER010 ;
- RET ;
- ;
- ;
- ;
- ISPEED: CALL KEYBDI ;
- CALL ASCHEX ;
- ADI 01H ;
- MOV H,A ;
- MVI L,0 ;
- MVI A,10H ;
- SUB H ;
- MOV H,A ;
- SHLD INSTSP ;
- CALL BMPLNE ;
- RET ;
- INSTSP: DW 0400H ;
- ;
- ;
- ;
- END
-