;P.C. Debug Monitor Revision 6/23/2005 by Don Stoner ; ORG 100H ;DOS file.COM execution begins here ; ;========================================================== ; ; Code Begins Here: ; JMP SHORT START ; ;------------------------------------------------ ; ; USER REGISTER CONTENTS: ; RAX: DW 1111H RBX: DW 8000H RCX: DW 3333H RDX: DW 4444H RSI: DW 5555H RDI: DW 6666H RBP: DW 7777H RSP: DW 0FF80H RCS: DW 0 RDS: DW 0 RES: DW 0 RSS: DW 0 RIP: DW 100H RFG: DW 0 ; ;========================================================== ; ; SETUP ; ; TAKE OVER INTERRUPT VECTORS 1 (STEP) AND 3 (BREAK) ; START: MOV AX,0 MOV DS,AX ; MOV AX,[4] ;SAVE EXISTING VECTORS MOV [CS:OFFSAV],AX MOV AX,[6] MOV [CS:SEGSAV],AX ; MOV AX,VECTOR ;SET NEW VECTORS MOV [4],AX MOV [12],AX MOV AX,CS MOV [6],AX MOV [14],AX ; ; Set up segment registers: ; MOV AX,CS MOV [RCS],AX MOV [RDS],AX MOV [RES],AX MOV [RSS],AX RESTART: MOV AX,CS MOV DS,AX MOV ES,AX CLI ;NO INTERRUPTS MOV SS,AX ;WHILE SETTING MOV SP,0FFFEH ;STACK POINTER STI ; ;================================================ ; ; Main Code Loop ; MLOOP: CALL CRLF ;Clear Screen CALL BLKOUT CALL INPUT ;GET INPUT MOV [KEY],AX ; ;---------------------------------------- ; ; Quit to DOS (only for debug under DOS) ; CMP AL,"Q" ;KEY IS Q? JNZ NTQ ; MOV AX,0 ;RESTORE INTERRUPT VECTORS MOV DS,AX MOV AX,[CS:OFFSAV] MOV [4],AX MOV [12],AX MOV AX,[CS:SEGSAV] MOV [6],AX MOV [14],AX ; MOV AH,0 ;"EXIT DOS" FUNCTION CALL INT 21H NTQ: ; ;======================================== ; ; GO (RUN) ; CMP AL,"G" ;KEY IS G? JNZ NTG JMP RUN NTG: ; ;---------------------------------------- ; ; SINGLE STEP ; CMP AL,"S" ;KEY IS S? JNZ NTS JMP STEP NTS: ; JMP MLOOP ; ;========================================================== ; ; SUBROUTINES: ; ;---------------------------------------- ; ; INPUT ASCII KEY CODE INTO AL ; (EXTENDED KEY CODE INTO AX) ; uses BIOS interrupt ; INPUT: MOV AH,0 INT 16H RET ; ;---------------------------------------- ; ; HEX OUTPUT (FROM AX OR AL) ; AXOUT: ;PUSH AX ;4 NIBBLES FROM AX ;MOV AL,AH xchg al,ah CALL ALOUT xchg ah,al ;POP AX ; ALOUT: PUSH AX ;2 NIBBLES FROM AQL PUSH CX MOV CL,4 ROR AL,CL POP CX CALL LSNOUT POP AX ; LSNOUT: AND AL,0FH ;LSN ONLY OR AL,30H CMP AL,3AH ;HEX ALPHA JC OUTPUT ADD AL,41H-3AH ;*** drops through *** ; ; OUTPUT ASCII CHARACTER (FROM AL) ; (uses BIOS interrupt) ; OUTPUT: PUSH AX ;SAVE AX MOV AH,0EH ;TTY OUT MOV BX,0 ;FOREGROUND PAGE,COLOR INT 10H POP AX ;RESTORE AX RET ; ;---------------------------------------- ; ; SPACE OUTPUT ; SPACE: PUSH AX MOV AL," " CALL OUTPUT POP AX RET ; ;---------------------------------------- ; ; C.R. AND L.F. ; CRLF: MOV AL,0DH CALL OUTPUT LF: MOV AL,0AH JMP SHORT OUTPUT ; ;---------------------------------------- ; ; OUTPUT AN ASCIIZ CHARACTER STRING (POINTED BY SI) ; PRINTS: LODSB ;(LODS - SAME AS MOV AL,[SI] INC SI) AND AL,AL ;END/NULL STRING? JZ ENDSTR CALL OUTPUT ;OUTPUT IT JMP SHORT PRINTS ENDSTR: RET ; ;---------------------------------------- ; ; BLOCK OUTPUT ; BLKOUT: MOV SI,MAX ;AX OUT CALL PRINTS MOV AX,[RAX] CALL AXOUT ; MOV SI,MBX ;BX OUT CALL PRINTS MOV AX,[RBX] CALL AXOUT ; MOV SI,MCX ;CX OUT CALL PRINTS MOV AX,[RCX] CALL AXOUT ; MOV SI,MDX ;DX OUT CALL PRINTS MOV AX,[RDX] CALL AXOUT ; MOV SI,MSI ;SI OUT CALL PRINTS MOV AX,[RSI] CALL AXOUT ; MOV SI,MDI ;DI OUT CALL PRINTS MOV AX,[RDI] CALL AXOUT ; MOV SI,MBP ;BP OUT CALL PRINTS MOV AX,[RBP] CALL AXOUT ; MOV SI,MSP ;SP OUT CALL PRINTS MOV AX,[RSP] CALL AXOUT ; MOV SI,MCS ;CS OUT CALL PRINTS MOV AX,[RCS] CALL AXOUT ; MOV SI,MDS ;DS OUT CALL PRINTS MOV AX,[RDS] CALL AXOUT ; MOV SI,MES ;ES OUT CALL PRINTS MOV AX,[RES] CALL AXOUT ; MOV SI,MSS ;SS OUT CALL PRINTS MOV AX,[RSS] CALL AXOUT ; MOV SI,MIP ;IP OUT CALL PRINTS MOV AX,[RIP] MOV DI,AX CALL AXOUT ; MOV SI,MFG ;FLAGS OUT CALL PRINTS MOV AX,[RFG] CALL AXOUT ; MOV SI,MEND CALL PRINTS JMP CRLF ; ;========================================================== ; ; SINGLE STEP OR RUN (INSIDE OUT INTERRUPT) ; STEP: MOV AX,[RFG] OR AX,100H ;SINGLE STEP FLAG BIT ON MOV [RFG],AX ; RUN: MOV AX,[RSS] ;"RESTORE" USER STACK CLI MOV SS,AX MOV SP,[RSP] STI ; ;PUSH [RFG] DW 36FFH,RFG ;SETUP IRET STUFF ;PUSH [RCS] ;(ON USER'S STACK) DW 36FFH,RCS ;PUSH [RIP] DW 36FFH,RIP ;(ASSEMBLER WORKAROUND) ; MOV AX,[RES] ;"RESTORE" ALL REGISTERS MOV ES,AX MOV BP,[RBP] MOV DI,[RDI] MOV SI,[RSI] MOV DX,[RDX] MOV CX,[RCX] MOV BX,[RBX] ; ;PUSH [RAX] DW 36FFH,RAX ;THESE ARE TRICKY MOV AX,[RDS] ;BECAUSE WE LOSE THE MOV DS,AX ;D-SEGMENT REGISTER POP AX ; IRET ;GO DO IT USING A INTERRUPT RETURN ;---------------------------------------------------------- ; ;THEN "RETURN" USING AN INTERRUPT ; ; INTERRUPT 1 (STEP) OR 3 (BREAK) RETURNS ; (FLAGS,CS,IP ARE ON STACK) ; VECTOR: PUSH DS ;SAVE THESE (ON THE USER STACK) PUSH AX ;BECAUSE WE NEED THE REGISTERS MOV AX,CS MOV DS,AX ;TO GET ACCESS TO MEMORY ; POP AX MOV [RAX],AX ;RECOVER AX MOV [RBX],BX MOV [RCX],CX ;SAVE ALL REGISTERS MOV [RDX],DX MOV [RSI],SI MOV [RDI],DI MOV [RBP],BP ; ;POP [RDS] ;SEGMENT REGISTERS ;DWL 368FH,RDS ;(WORKAROUND) POP AX MOV [RDS],AX MOV AX,ES MOV [RES],AX ; ;POP [RIP] ;RECOVER IRET STUFF FROM STACK ;DWL 368FH,RIP ;(WORKAROUND) POP AX MOV [RIP],AX ;POP [RCS] ;DWL 368FH,RCS POP AX MOV [RCS],AX ;POP [RFG] ;DWL 368FH,RFG POP AX MOV [RFG],AX ; MOV AX,SS ;RECOVER USER STACK POINTERS MOV [RSS],AX MOV [RSP],SP ; MOV AX,[RFG] AND AX,0FEFFH ;SINGLE STEP FLAG BIT OFF MOV [RFG],AX ; JMP RESTART ;RESTART PROGRAM LOOP ; ;========================================================== ; ; MONITOR VARIABLES ; SEGSAV: DW 0 OFFSAV: DW 0 ;SEG:OFF OF OLD INTERRUPT VECTORS KEY: DW 20H ;IMAGE OF LAST TYPED KEY ; ; Messages: ; MAX: DB 13,10,"AX:",0 MBX: DB " BX:",0 MCX: DB " CX:",0 MDX: DB " DX:",0 MSI: DB " SI:",0 MDI: DB " DI:",0 MBP: DB " BP:",0 MSP: DB " SP:",0 MCS: DB 13,10,"CS:",0 MDS: DB " DS:",0 MES: DB " ES:",0 MSS: DB " SS:",0 MIP: DB " IP:",0 MFG: DB " FLAGS:",0 MINST: DB " INST:",0 MKEY: DB " KEY: ",0 MFPU: DB 13,10,"FPU:",0 MEND: DB 13,10,10,0