; ; 8080A Microprocessor Instruction Set Emulator ; by Jeff Sheese, RETS Tech Center, Centerville, Ohio 45459 ; ; 8-18-82 ; ; The 8080A Instruction Set Emulator is a teaching tool used to ;demonstrate the operation of the assembly language commands and ;how they affect the memory and microprocessor register contents. ;The emulator was designed to operate the computer in a machine ;language 'direct' mode. In BASIC, the 'direct' mode is when a ;person types in a command such as PRINT and watches the results ;of the command. The emulator will speed learning and ;comprehension in a positive and instructive atmosphere. ; ; When the emulator is run, a sign-on message is printed on the ;screen, and immediately following is the prompt: ; ;Initial status: ;PC S Z A P C A B C D E H L M SP STACK ;2000 0 0 0 0 0 00 00 00 00 00 00 00 00 0000 0000 ; ;Instruction?_ ; ; The first line is a description of the type of registers in ;the microprocessor. Under each description is the actual content ;of the register. The letters S, Z, A, P, and C are the status ;flags. They change as the microprocessor status changes. Their ;functions and descriptions follow: ; ; Sign flag - This flag shows whether the result of the last ;operation was positive or negative. The sign flag will be a one ;if negative, or a zero if positive. It will be the same as the ;most significant bit in the accumulator. ; ; Zero flag - This flag shows whether the result of the last ;operation was zero. If the result is zero, the flag will be one. ;If it was not zero, the flag will be zero. ; ; Auxiliary carry flag - If the result of the last operation ;caused a carry from bit three to bit four, this will be one. ;This flag is only used for the DAA instruction. ; ; Parity flag - This flag shows whether the result of the last ;operation resulted in an even or odd number of ones in the ;resulting byte. This flag will be one if there is an even number ;one of bits, or odd if there is an odd number of one bits. ; ; Carry flag - This flag shows whether the result of the last ;operation caused a carry or a borrow from the last significant ;bit of the result. It will be one if a carry or a borrow did ;occur, or it will be zero if it did not occur. ; ; The rest of the line will show the different registers. A ;description of the registers follow: ; ; PC - This will show the current address of the program ;counter. Do not let this go below 2000H. If it does, you may ;accidentally alter memory that is essential for the emulator or ;the operating system of your computer. ; ; A - This will show the contents of the accumulator after the ;last instruction typed. ; ; B - This will show the contents of the B register after the ;last instruction typed. ; ; C - This will show the contents of the C register after the ;last instruction typed. ; ; D - This will show the contents of the D register after the ;last instruction typed. ; ; E - This will show the contents of the E register after the ;last instruction typed. ; ; H - This will show the contents of the H register after the ;last instruction typed. ; ; L - This will show the contents of the L register after the ;last instruction typed. ; ; M - This will show the contents of the memory address pointed ;to by the H-L register pair. ; ; SP - This will show the address that is the current top of ;the stack. ; ; STACK - This will show the last two bytes that were actually ;entered on the stack. This is data, not a memory address. ; ; ; The next thing to do is to actually type in an 8080A ;mnemonic. If you have a copy of the 8080A instruction set, you ;type in the mnemonic the same as if you were executing an ;assembly language program. This emulator does not support the ;use of labels. All numbers that are input and displayed are in ;hexidecimal format. After typing in the instruction, press ;return, and the emulator will display the new status. ; ; WARNING: ; DO NOT ALTER ANY MEMORY LOCATIONS BELOW 2000 HEX. THESE ;MEMORY LOCATIONS ARE ESSENTIAL FOR THE EMULATOR PROGRAM AND THE ;OPERATING SYSTEM OF YOUR COMPUTER. THE MNEMONICS AND COMMAND ;THAT ARE TYPED IN ARE ACTUALLY EXECUTED. ; ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED CONOUT EQU 2 ;CONSOLE OUTPUT CONIN EQU 1 ;CONSOLE INPUT BDOS EQU 5 ;BDOS CALL BEL EQU 7 ;BELL CODE DEL EQU 7FH ;DELETE CHARACTER FALSE EQU 0FFFFH ;FALSE CONDITION BSPACE EQU 8 ;BACKSPACE CHARACTER wboot equ 0 ; ; DISPLAY HEADING ON CRT ; ORG 0100H ;START OF TPA BEGIN LXI SP,STACK ;SET UP STACK POINTER CALL SHOTEL ;PRINT THE FOLLOWING DB cr,lf,lf,' 8080 INSTRUCTION ' DB 'SET EMULATOR',CR,LF,LF DB CR,LF,'Initial Status:',CR,LF,0 ; ;ZERO PROGRAM STASHES ; MVI B,0CH ;COUNTER FOR 12 LOCATIONS LXI H,PCSTOR+2 ;START OF STORAGE AREA ; MVI M,00H ;PUT 1000H IN PC COUNT INX H ; MVI M,10 ; INX H ; DCR B ; ZLOOP MVI M,0 ;PUT 0 AT H-L ADDRESS INX H ;SET H-L TO NEXT LOCATION DCR B ;COUNT 1 LOCATION DONE JNZ ZLOOP ;DO SOME MORE UNTIL B=0 ; ;DISPLAY EMULATOR CPU STATUS ; JMP SPREAD ;ROUTINE FOR HEADING AND STATUS ; ;INPUT A LINE OF TYPING ; NEXT1 LXI H,BUFFER ;SET H-L TO STORAGE AREA LXI SP,STACK ;RESET STACK POINTER ; INLOOP CALL INPUT ;GET KEYBOARD CHARACTER CPI bspace ;IS IT DELETE? JZ ERASE ;YES, ERASE IT cpi 7bh ;'z' or less? jnc inloop2 ;no, continue cpi 61h ;'a' or greater? jc inloop2 ;no, continue ani 0dfh ;yes, convert lower to upper case inloop2 cpi 03h ;is it ctrl-c? jz wboot ;yes, warm boot MOV M,A ;NO,STORE IT INX H ;SET H-L TO NEXT ADDRESS CPI CR ;IS IT CR? JZ DONEIN ;YES, FINISHED JMP INLOOP ;NO, GET NEXT CHARACTER ; ERASE DCX H ;NO, BACK UP ; MVI A,BSPACE ;GET BACKUP CODE ; CALL OUTPUT ;DISPLAY IT JMP INLOOP ;RETURN FOR MORE ; ;FIND MNEMONIC IN TABLE ; DONEIN LXI H,TABLE ;SET H-L TO START OF TABLE MVI B,0 ;INITIALIZE COUNTER ; FINDIT LXI D,BUFFER-1 ;SET D-E TO ONE BEFORE BUFFER ; KEEPON INX D ;NEXT BUFFER CHARACTER LDAX D ;GET CHARACTER FROM BUFFER CMP M ;SAME AS CHARACTER IN TABLE? MOV A,M ;GET CHARACTER FROM TABLE INX H ;SET H-L TO NEXT TABLE CHARACTER JZ KEEPON ;KEEP LOOKING IF CHARS MATCH CPI 20H ;IS IT LOWER THAN ASCII SPACE? JC FOUND ;CARRY MEANS ENTRY FOUND ; PASSBY MOV A,M ;GET NEXT CHARACTER INX H ;SET H-L TO NEXT TABLE CHAR. CPI 20H ;IS IT A TYPE BYTE? JNC PASSBY ;NO, KEEP GOING INR B ;ADD ONE TO COUNTER JNZ FINDIT ;CHECK NEXT CHAR IF STILL OK MVI A,1 ;INVALID-LOAD A WITH TYPE 1 ; ;SET UP OPCODES AND ARGUMENTS ; FOUND PUSH PSW ;SAVE TYPE BYTE ON STACK MOV A,B ;CODE TO REG. A STA OPCODE ;STORE THE BYTE STA CONDTN ;STORE AT "CONDTN" ALSO LXI H,0000H ;TWO NOP'S IN H-L SHLD ARGMNT ;STORE THEM AT ARGUMENT SHLD ADDRES ;STORE AT "ADDRES" ALSO ; ;SKIP TO APPROPRIATE HANDLER ROUTINE AND EXECUTE ; POP PSW ;GET TYPE BYTE BACK IN A DCR A ;MAKES IT 00 IF TYPE 1 JNZ TYPE2 ;TRY NEXT TYPE IF NOT 0 ; ;ROUTINE FOR TYPE 1 INSTRUCTIONS ; CALL SHOTEL ;DISLAY ERR MESSAGE DB CR,LF,' ***Invalid Mnemonic***',BEL,0 JMP NEXT2 ;GET PROPER MNEMONIC ; TYPE2 DCR A ;MAKES IT 0 IF TYPE 2 JNZ TYPE3 ;TRY NEXT TYPE IF NOT 0 ; ;ROUTINE FOR TYPE 2 INSTRUCTIONS ; MVI C,1 ;THESE ARE ONE-BYTE INSTRUCTIONS LDAX D ;GET CHARACTER AFTER MNEMONIC CPI CR ;MAKE SURE ITS 0DH JZ DOINST ;GO EMULATE IF ALL IS OK ; BADOP CALL SHOTEL ;DISPLAY ERR MESSAGE IF NOT DB CR,LF,' ***Bad Operand***',BEL,0 JMP NEXT2 ;GET PROPER ENTRY ; TYPE3 DCR A ;MAKES IT 0 IF TYPE 3 JNZ TYPE4 ;TRY NEXT TYPE IF NOT 0 ; ;ROUTINE FOR TYPE 3 INSTRUCTION ; LDAX D ;GET CHARACTER AFTER MNEMONIC CPI CR ;MAKE SURE ITS CR JNZ BADOP ;DISPLAY ERR IF NOT LHLD SPSTOR ;GET EMULATOR STACK POINTER SPHL ;MAKE IT THE REAL ONE LHLD PCSTOR ;GET EMULATOR PROGRAM COUNTER INX H ;POINT TO NEXT INSTRUCTION PUSH H ;WRITE RETURN ADDRESS ON STACK LXI H,0000H ;ZERO H-L DAD SP ;ADD NEW STACK POINTER SHLD SPSTOR ;UPDATE STACK POINTER STASH LXI SP,STACK ;MAKE OUR STACK POINTER REAL MOV A,B ;GET INTRUCTION CODE ANI 38H ;STRIP NON-UNIQUE BITS MOV L,A ;MOVE NEW VALUE TO L MVI H,0000H ;MAKE H ZERO SHLD PCSTOR ;STORE ADDRESS AS PROGRAM COUNTER JMP SPREAD ;SHOW NEW EMULATOR STATUS ; TYPE4 DCR A ;MAKES IT 0 IF TYPE 4 JNZ TYPE5 ;TRY NEXT TYPE IF NOT 0 ; ;ROUTINE FOR TYPE 4 INSTRUCTION ; LDAX D ;GET NEXT CHAR AFTER MNEMONIC CPI CR ;MAKE SURE ITS A CR JNZ BADOP ;DISPLAY ERR IF NOT CALL SHOTEL ;DISPLAY EXIT MESSAGE DB CR,LF,' ***Reboot Disk***',BEL,0 JMP WBOOT ; TYPE5 DCR A ;MAKES IT 0 IF TYPE 5 JNZ TYPE6 ;TRY NEXT TYPE IF NOT 0 ; ;ROUTINE FOR TYPE 5 INSTRUCTION ; LDAX D ;GET CHARACTER AFTER MNEMONIC CPI CR ;MAKE SURE ITS A CR JNZ BADOP ;DISPLAY ERR IF NOT LHLD HSTOR ;GET EMULATOR H-L DATA SHLD PCSTOR ;MAKE IT PROGRAM COUNTER JMP SPREAD ;SHOW NEW EMULATOR STATUS ; TYPE6 DCR A ;MAKES IT 0 IF TYPE 6 JNZ TYPE7 ;TRY NEXT TYPE IF NOT 0 ; ;ROUTINE FOT TYPE 6 INSTRUCTION ; LDAX D ;GET CHARACTER AFTER MNEMONIC CPI CR ;MAKE SURE ITS A CR JNZ BADOP ;DISPLAY ERR IF NOT MVI C,1 ;RETURNS ARE 1 BYTE CALL UPDATE ;UPDATE PROGRAM COUNTER CALL CTEST ;CALL CONDITIONAL TEST ; ;RETURN HERE IF CONDITION MET ; LHLD SPSTOR ;GET EMULATOR STACK POINTER SPHL ;MAKE IT REAL POP H ;GET LAST ENTRY ON STACK SHLD PCSTOR ;MAKE IT THE PROGRAM COUNTER LXI H,0000H ;ZERO H-L REGISTERS DAD SP ;ADD THE STACK POINTER SHLD SPSTOR ;STORE IN STACK POINTER STASH LXI SP,STACK ;MAKE OUR STACK POINTER REAL JMP SPREAD ;DISPLAY NEW EMULATOR STATUS ; ;GET NUMERICAL ARGUMENTS FOR REST OF INSTRUCTION TYPES ; TYPE7 PUSH PSW ;SAVE INSTRUCTION TYPE LXI B,0000H ;ZERO B-C REGISTERS LXI H,0000H ;ZERO H-L REGISTERS LDAX D ;DID WE GET AN ARGUMENT? CPI CR ;WON'T BE CR IF SO JNZ HLOOP ;ITS OK IF NOT CR CALL SHOTEL ;SAY ITS A BADDIE DB CR,LF,' ***Missing Argument***',BEL,0 JMP NEXT2 ;GO DO IT AGAIN ; HLOOP LDAX D ;GET NEXT CHAR FROM BUFFER INX D ;SET D-E TO NEXT BUFFER ADDRESS CPI CR ;END OF HEX VALUE? JZ NOMORE ;CONVERSION FINISHED IF SO SUI 30H ;REMOVE ASCII BIAS JC ERROR ;NO GOOD IF GET A CARRY CPI 0AH ;IS IT 0 THRU 9? JC HEXOK ;IT'S OK IF SO SUI 7 ;TRY HEX LETTERS CPI 0AH ;IS IT LESS THAN 0AH? JC ERROR ;NO GOOD IF SO CPI 10H ;HIGHER THAN OF HEX? JNC ERROR ;NO GOOD IF SO ; HEXOK DAD H ;H-L = H-L TIMES TWO DAD H ;H-L = H-L TIMES FOUR DAD H ;H-L = H-L TIMES EIGHT DAD H ;H-L = H-L TIMES SIXTEEN MOV C,A ;NEW UNIT VALUE TO C DAD B ;ADD UNIT VALUE TO TOTAL JMP HLOOP ;LOOP FOR NEXT DIGIT ; ERROR CALL SHOTEL ;DISPLAY ERROR MESSAGE DB CR,LF,' ***Bad Character in Operand***',BEL,0 JMP NEXT2 ;START OVER ; NOMORE SHLD ARGMNT ;STORE VALUE AS ARGUMENT POP PSW ;GET INSTRUCTION TYPE BACK ; DCR A ;MAKES IT 0 IF TYPE 7 JNZ TYPE8 ;TRY NEXT TYPE IF NOT 0 ; ;ROUTINE FOR TYPE 7 INSTRUCTIONS ; MVI C,2 ;THESE ARE TWO BYTE INSTRUCTIONS MOV A,H ;GET HIGH BYTE OF ARGUMENT ORA A ;MUST BE ZERO FOR TWO BYTE TYPES JZ DOINST ;GO EMULATE IF ALL OK CALL SHOTEL ;DISPLAY ERR MESSAGE DB CR,LF,' ***Argument too Large***',BEL,0 JMP NEXT2 ;START OVER ; TYPE8 DCR A ;MAKES IT 0 IF TYPE 8 JNZ TYPE9 ;TRY NEXT TYPE IF NOT 0 ; ;ROUTINE FOR TYPE 8 INSTRUCTION ; XCHG ;SAVE TYPED IN ARGUMENT MVI C,3 ;JUMPS ARE THREE BYTES CALL UPDATE ;UPDATE PROGRAM COUNTER LXI H,JBACK ;LOAD H-L WITH ADDRESS OF JBACK SHLD ADDRES ;STORE AS ARGUMENT OF COND INSTR JMP CTEST ;GO TO CONDITIONAL TEST ; JBACK XCHG ;GET TYPED-IN ARGUMENT BACK SHLD PCSTOR ;STORE NEW PROGRAM COUNT JMP SPREAD ;DISPLAY NEW EMULATOR STATUS ; TYPE9 DCR A ;MAKES IT 0 IF TYPE 9 JNZ TYPE10 ;DO TYPE 10 IF NOT 0 ; ;ROUTINE FOR TYPE 9 INSTRUCTIONS ; XCHG ;SAVE TYPED IN ARGUMENT MVI C,3 ;CALLS ARE THREE BYTES CALL UPDATE ;UPDATE PROGRAM COUNTER LXI H,CBACK ;LOAD H-L ADDRESS WITH CBACK SHLD ADDRES ;STORE AS ARGMNT OF COND INSTR JMP CTEST ;GO DO COND TEST ; CBACK LHLD SPSTOR ;GET EMULATOR STACK POINTER SPHL ;MAKE IT THE REAL ONE LHLD PCSTOR ;GET EMULATOR PROGRAM COUNTER PUSH H ;WRITE RETURN ADDRESS ON STACK LXI H,0000H ;ZERO H-L REG. DAD SP ;ADD NEW STACK POINTER SHLD SPSTOR ;UPDATE STACK POINTER STASH LXI SP,STACK ;MAKE OUR STACK POINTER REAL XCHG ;GET TYPED IN ARGUMENT SHLD PCSTOR ;MAKE IT THE PROGRAM COUNTER JMP SPREAD ;DISPLAY NEW EMULATOR STATUS ; ;ROUTINE FOR TYPE 10 INSTRUCTIONS ; TYPE10 MVI C,3 ;THESE ARE THREE BYTE INSTRUCTIONS ; ;DO INSTRUCTIONS THAT CAN BE EXECUTED ; DOINST CALL UPDATE ;UPDATE PROGRAM COUNTER LHLD PSWSTR ;GET EMULATOR PSW PUSH H ;PUSH ONTO STACK POP PSW ;POP OFF STACK INTO PLACE LHLD BSTOR ;GET EMULATOR B-C PUSH H ;PUSH ONTO STACK POP B ;POP OFF STACK INTO PLACE LHLD DSTOR ;GET EMULATOR D-E PUSH H ;PUSH ONTO STACK POP D ;POP OFF STACK INTO PLACE LHLD SPSTOR ;GET EMULATOR STACK POINTER SPHL ;MAKE IT REAL LHLD HSTOR ;GET EMULATOR H-L ; OPCODE DS 1 ;CPU CODE GOES HERE ARGMNT DS 2 ;NUMERICAL ARGUMENTS GO HERE ; STA PSWSTR ;SAVE ACCUMULATOR FOR NOW RAR ;ROTATE CARRY FLAG TO ACCUMULATOR SHLD HSTOR ;H-L TO STASH LXI H,0 ;ZERO H-L REGISTERS DAD SP ;ADD IN STACK POINTER SHLD SPSTOR ;STACK POINTER TO STASH LXI SP,STACK ;MAKE STACK POINTER REAL RAL ;ROTATE CARRY FLAG INTO PLACE LDA PSWSTR ;GET ACCUMULATOR BACK PUSH PSW ;PUSH PSW ONTO STACK POP H ;POP IT INTO H-L SHLD PSWSTR ;PSW TO STASH PUSH B ;PUSH B-C ONTO STACK POP H ;POP IT INTO H-L SHLD BSTOR ;B-C TO STASH PUSH D ;PUSH D-E ONTO STASH POP H ;POP IT INTO H-L SHLD DSTOR ;D-E TO STASH ; ;DISPLAY THE HEADING AND THE EMULATOR STATUS ; SPREAD CALL SHOTEL ;DISPLAY THE HEADING DB CR,LF,lf,'PC S Z A P C A B C D E H' DB ' L M SP STACK',CR,LF,0 LHLD PCSTOR ;GET PROGRAM COUNTER XCHG ;MOVE ADDRESS TO D-E CALL HWORD ;DISPLAY AS HEX WORD CALL BLANK2 ;PRINT TWO SPACES LHLD PSWSTR ;GET PROCESSOR STATUS WORD MOV A,L ;FLAG REGISTER TO A CALL AFLAG ;DISPLAY THE SIGN FLAG CALL AFLAG ;DISPLAY THE ZERO FLAG RLC ;PASS BY UNUSED BIT CALL AFLAG ;DISPLAY THE AUX CARRY FLAG RLC ;PASS BY UNUSED BIT CALL AFLAG ;DISPLAY PARITY FLAG RLC ;PASS BY UNUSED BIT CALL AFLAG ;DISPLAY CARRY FLAG CALL BLANK1 ;PRINT ONE SPACE MOV E,H ;GET REGISTER A DATA CALL HBYTE ;DISPLAY AS HEX CALL BLANK1 ;PRINT ONE SPACE LHLD BSTOR ;GET B-C REGISTER DATA CALL SHOREG ;DISPLAY THE REGISTERS IN HEX LHLD DSTOR ;GET D-E REGISTER DATA CALL SHOREG ;DISPLAY THE REGISTERS IN HEX LHLD HSTOR ;GET H-L REGISTER DATA CALL SHOREG ;DISPLAY THE REGISTERS IN HEX MOV E,M ;GET MEMORY DATA AT H-L ADDRESS CALL HBYTE ;DISPLAY IN HEX CALL BLANK2 ;PRINT TWO SPACES LHLD SPSTOR ;GET STACK POINTER DATA XCHG ;PUT STACK POINTER IN D-E CALL HWORD ;DISPLAY AS HEX CALL BLANK2 ;PRINT TWO SPACES XCHG ;STACK POINTER BACK TO H-L MOV E,M ;LOW BYTE OF DATA ON STACK TOP INX H ;SET H-L TO NEXT ADDRESS MOV D,M ;HIGH BYTE OF DATA ON STACK TOP CALL HWORD ;DISPLAY AS HEX ; NEXT2 CALL SHOTEL ;DISPLAY MESSAGE DB CR,LF,lf,'Instruction: ',0 JMP NEXT1 ;GET NEXT INSTRUCTION TO EMULATE ; ;DISPLAY "0" OR "1" FOR FLAG STATUS ; AFLAG RLC ;MOVE LEFTMOST BIT INTO CARRY MOV L,A ;SAVE MODIFIED BIT MVI A,'1' ;ANTICIPATE FLAG IS SET JC FLAGON ;DISPLAY "1" IF SET MVI A,'0' ;DISPLAY "0" IF RESET ; FLAGON CALL OUTPUT ;DISPLAY "1" OR "0" CALL BLANK1 ;PRINT ONE SPACE MOV A,L ;GET THE FLAG BYTE BACK RET ; ;DISPLAY H-L AS INDIVIDUAL REGISTERS ; SHOREG MOV E,H ;DO HIGH BYTE FIRST CALL HBYTE ;DISPLAY AS HEX CALL BLANK1 ;PRINT ONE SPACE MOV E,L ;DO LOW BYTE NEXT CALL HBYTE ;DISPLAY AS HEX JMP BLANK1 ;PRINT ONE SPACE ; ;PRINT ONE OR TWO BLANK SPACES ; BLANK2 CALL BLANK1 ;PRINT TWO BLANK SPACES ; BLANK1 MVI A,' ' ;PRINT ONE SPACE JMP OUTPUT ;DISPLAY THE SPACE ; ;TEST CONDITIONAL INSTRUCTIONS ; CTEST LHLD PSWSTR ;GET CONDITION FLAGS PUSH H ;PUSH THEM ONTO STACK ; CONDTN DS 1 ;HEX CPU CODE GOES HERE ADDRES DS 2 ;ADDRESS ARGUMENT GOES HERE JMP SPREAD ;DISPLAY OLD STATUS IF CONDITION FAILS ; ;UPDATE THE PROGRAM COUNTER ; UPDATE LHLD PCSTOR ;GET PROGRAM COUNTER MVI B,0 ;ZERO REGISTER B DAD B ;ADD INSTRUCTION LENGTH TO PC SHLD PCSTOR ;STORE NEW PROGRAM COUNTER RET ;RETURN ; ;OUTPUT A MESSAGE ; SHOTEL XTHL ;GET ADDRESS OF MESSAGE FROM STACK DISPL MOV A,M ;GET CHARACTER TO DISPLAY INX H ;SET H-L TO NEXT ADDRESS ORA A ;TEST FOR DELIMITER JZ EXIT ;FINISH IF END OF MESSAGE CALL OUTPUT ;DISPLAY THE CHARACTER JMP DISPL ;LOOP FOR NEXT CHARACTER ; EXIT XTHL ;FIX H-L AND STACK RET ;RETURN ; ;OUTPUT A BYTE IN HEX ; HWORD MOV A,D ;DO HIGH BYTE FIRST CALL DOHEX ; HBYTE MOV A,E ;DO LOW BYTE ; DOHEX PUSH PSW ;SAVE THE BYTE ON THE STACK RRC ;ROTATE LEFT 4 BITS INTO PLACE RRC ; RRC ; RRC ; CALL HEXOUT ;MAKE ASCII AND DISPLAY POP PSW ;GET THE BYTE BACK ; HEXOUT ANI 0FH ;KEEP ONLY RIGHT FOUR BITS ADI 30H ;ADD ASCII OFFSET CPI ':' ;IS IT A NUMBER? JC OUTPUT ;YES, DISPLAY IT ADI 7 ;MAKE IT A LETTER JMP OUTPUT ;DISPLAY THE LETTER ON THE CRT ; ;KEYBOARD INPUT ; INPUT PUSH B ;SAVE B-C PUSH D ;SAVE D-E PUSH H ;SAVE H-L MVI C,CONIN ;SET UP FOR INPUT CALL BDOS ; POP H ;RECALL H-L POP D ;RECALL D-E POP B ;RECALL BC RET ;RETURN ; ;CRT OUTPUT ; OUTPUT PUSH B ;SAVE B-C PUSH D ;SAVE D-E PUSH H ;SAVE H-L MOV E,A ;PUT CHARACTER IN REGISTER E MVI C,CONOUT ;SET UP FOR OUTPUT CALL BDOS ; POP H ;RECALL H POP D ;RECALL D POP B ;RECALL B RET ;RETURN ; BOOT JMP BOOT ;HANG HERE UNTIL RESET ; ;MNEMONIC LOOK-UP TABLE ; TABLE DB 'NOP',2 ;INSTRUCTION MNEMONIC AND TYPE DB 'LXI B,',10 DB 'STAX B',2 DB 'INX B',2 DB 'INR B',2 DB 'DCR B',2 DB 'MVI B,',7 DB 'RLC',2 DB '*',1 DB 'DAD B',2 DB 'LDAX B',2 DB 'DCX B',2 DB 'INR C',2 DB 'DCR C',2 DB 'MVI C,',7 DB 'RRC',2 DB '*',1 DB 'LXI D,',10 DB 'STAX D',2 DB 'INX D',2 DB 'INR D',2 DB 'DCR D',2 DB 'MVI D,',7 DB 'RAL',2 DB '*',1 DB 'DAD D',2 DB 'LDAX D',2 DB 'DCX D',2 DB 'INR E',2 DB 'DCR E',2 DB 'MVI E,',7 DB 'RAR',2 DB '*',1 DB 'LXI H,',10 DB 'SHLD ',10 DB 'INX H',2 DB 'INR H',2 DB 'DCR H',2 DB 'MVI H,',7 DB 'DAA',2 DB '*',1 DB 'DAD H',2 db 'LHLD ',10 ; DB 'LHLD',10 DB 'DCX H',2 DB 'INR L',2 DB 'DCR L',2 DB 'MVI L,',7 DB 'CMA',2 DB '*',1 DB 'LXI SP,',10 DB 'STA ',10 DB 'INX SP',2 DB 'INR M',2 DB 'DCR M',2 DB 'MVI M,',7 DB 'STC',2 DB '*',1 DB 'DAD SP',2 DB 'LDA ',10 DB 'DCX SP',2 DB 'INR A',2 DB 'DCR A',2 DB 'MVI A,',7 DB 'CMC',2 DB 'MOV B,B',2 DB 'MOV B,C',2 DB 'MOV B,D',2 DB 'MOV B,E',2 DB 'MOV B,H',2 DB 'MOV B,L',2 DB 'MOV B,M',2 DB 'MOV B,A',2 DB 'MOV C,B',2 DB 'MOV C,C',2 DB 'MOV C,D',2 DB 'MOV C,E',2 DB 'MOV C,H',2 DB 'MOV C,L',2 DB 'MOV C,M',2 DB 'MOV C,A',2 DB 'MOV D,B',2 DB 'MOV D,C',2 DB 'MOV D,D',2 DB 'MOV D,E',2 DB 'MOV D,H',2 DB 'MOV D,L',2 DB 'MOV D,M',2 DB 'MOV D,A',2 DB 'MOV E,B',2 DB 'MOV E,C',2 DB 'MOV E,D',2 DB 'MOV E,E',2 DB 'MOV E,H',2 DB 'MOV E,L',2 DB 'MOV E,M',2 DB 'MOV E,A',2 DB 'MOV H,B',2 DB 'MOV H,C',2 DB 'MOV H,D',2 DB 'MOV H,E',2 DB 'MOV H,H',2 DB 'MOV H,L',2 DB 'MOV H,M',2 DB 'MOV H,A',2 DB 'MOV L,B',2 DB 'MOV L,C',2 DB 'MOV L,D',2 DB 'MOV L,E',2 DB 'MOV L,H',2 DB 'MOV L,L',2 DB 'MOV L,M',2 DB 'MOV L,A',2 DB 'MOV M,B',2 DB 'MOV M,C',2 DB 'MOV M,D',2 DB 'MOV M,E',2 DB 'MOV M,H',2 DB 'MOV M,L',2 DB 'HLT',4 DB 'MOV M,A',2 DB 'MOV A,B',2 DB 'MOV A,C',2 DB 'MOV A,D',2 DB 'MOV A,E',2 DB 'MOV A,H',2 DB 'MOV A,L',2 DB 'MOV A,M',2 DB 'MOV A,A',2 DB 'ADD B',2 DB 'ADD C',2 DB 'ADD D',2 DB 'ADD E',2 DB 'ADD H',2 DB 'ADD L',2 DB 'ADD M',2 DB 'ADD A',2 DB 'ADC B',2 DB 'ADC C',2 DB 'ADC D',2 DB 'ADC E',2 DB 'ADC H',2 DB 'ADC L',2 DB 'ADC M',2 DB 'ADC A',2 DB 'SUB B',2 DB 'SUB C',2 DB 'SUB D',2 DB 'SUB E',2 DB 'SUB H',2 DB 'SUB L',2 DB 'SUB M',2 DB 'SUB A',2 DB 'SBB B',2 DB 'SBB C',2 DB 'SBB D',2 DB 'SBB E',2 DB 'SBB H',2 DB 'SBB L',2 DB 'SBB M',2 DB 'SBB A',2 DB 'ANA B',2 DB 'ANA C',2 DB 'ANA D',2 DB 'ANA E',2 DB 'ANA H',2 DB 'ANA L',2 DB 'ANA M',2 DB 'ANA A',2 DB 'XRA B',2 DB 'XRA C',2 DB 'XRA D',2 DB 'XRA E',2 DB 'XRA H',2 DB 'XRA L',2 DB 'XRA M',2 DB 'XRA A',2 DB 'ORA B',2 DB 'ORA C',2 DB 'ORA D',2 DB 'ORA E',2 DB 'ORA H',2 DB 'ORA L',2 DB 'ORA M',2 DB 'ORA A',2 DB 'CMP B',2 DB 'CMP C',2 DB 'CMP D',2 DB 'CMP E',2 DB 'CMP H',2 DB 'CMP L',2 DB 'CMP M',2 DB 'CMP A',2 DB 'RNZ',6 DB 'POP B',2 DB 'JNZ ',8 DB 'JMP ',8 DB 'CNZ ',9 DB 'PUSH B',2 DB 'ADI ',7 DB 'RST 0',3 DB 'RZ',6 DB 'RET',6 DB 'JZ ',8 DB '*',1 DB 'CZ ',9 DB 'CALL ',9 DB 'ACI ',7 DB 'RST 1',3 DB 'RNC',6 DB 'POP D',2 DB 'JNC ',8 DB 'OUT ',7 DB 'CNC ',9 DB 'PUSH D',2 DB 'SUI ',7 DB 'RST 2',3 DB 'RC',6 DB '*',1 DB 'JC ',8 DB 'IN ',7 DB 'CC ',9 DB '*',1 DB 'SBI ',7 DB 'RST 3',3 DB 'RPO',6 DB 'POP H',2 DB 'JPO ',8 DB 'XTHL',2 DB 'CPO ',9 DB 'PUSH H',2 DB 'ANI ',7 DB 'RST 4',3 DB 'RPE',6 DB 'PCHL',5 DB 'JPE ',8 DB 'XCHG',2 DB 'CPE ',9 DB '*',1 DB 'XRI ',7 DB 'RST 5',3 DB 'RP',6 DB 'POP PSW',2 DB 'JP ',8 DB 'DI',2 DB 'CP ',9 DB 'PUSH PSW',2 DB 'ORI ',7 DB 'RST 6',3 DB 'RM',6 DB 'SPHL',2 DB 'JM ',8 DB 'EI',1 DB 'CM ',9 DB '*',1 DB 'CPI ',7 DB 'RST 7',3 ; ;STORAGE SECTION ; PCSTOR DW 2000H ;PROGRAM COUNTER (DEFAULT) PSWSTR DS 2 ;FLAGS AND A REGISTER BSTOR DS 2 ;B AND C REGISTERS DSTOR DS 2 ;D AND E REGISTERS HSTOR DS 2 ;H AND L REGISTERS SPSTOR DS 2 ;STACK POINTER DS 64H ;PROGRAM STACK STACK DS 1 ;START OF STACK BUFFER EQU $ ;TYPE IN BUFFER ; ;END OF PROGRAM ; END ACK POINTER