--- /dev/null
+; MMURTL Operating System Source Code\r
+; Copyright 1991,1992,1993,1994 Richard A. Burgess\r
+; ALL RIGHTS RESERVED Version 1.0\r
+;=============================================================================\r
+.DATA\r
+.INCLUDE MOSEDF.INC\r
+.INCLUDE TSS.INC\r
+.INCLUDE RQB.INC\r
+.INCLUDE JOB.INC\r
+\r
+.ALIGN DWORD\r
+\r
+;External near Variables\r
+\r
+EXTRN rgTmrBlks DD\r
+EXTRN pJCBs DD\r
+EXTRN RdyQ DD\r
+EXTRN rgPAM DB\r
+\r
+;debugger variables and buffers\r
+\r
+PUBLIC DbgpTSSSave DD 0 ;TO save the TSS we interrupted\r
+PUBLIC dbgFAULT DD 0FFh ;0FFh is NO FAULT\r
+PUBLIC dbgFltErc DD 0\r
+PUBLIC dbgOldEIP DD 0\r
+PUBLIC dbgOldCS DD 0\r
+PUBLIC dbgOldEflgs DD 0\r
+\r
+DbgVidSave DD 0 ;To save interrupted video user\r
+dbgBuf DB '00000000' ;General use buffers\r
+dbgBuf2 DB '0000000000'\r
+\r
+.ALIGN DWORD\r
+cbBufLen2 DD 0 ;Active bytes in buf2\r
+dbgKeyCode DD 0 ;For ReadDbgKbd\r
+NextEIP DD 0 ;For Disassem display (next ins to be executed)\r
+dbgGPdd1 DD 0 ;General purpose DDs (used all over)\r
+dbgGPdd2 DD 0 ;\r
+dbgGPdd3 DD 0 ;\r
+dbgGPdd4 DD 0 ;\r
+dbgGPdd5 DD 0 ;\r
+dbgGPdd6 DD 0 ;flag 1 = Msg, 0 = Exch\r
+\r
+dbgNextAdd DD 0 ;Address we are setting as next\r
+dbgCrntAdd DD 0 ;Address of instructions we are displaying\r
+dbgDumpAdd DD 0 ;Address we are dumping\r
+\r
+dbgX DD 0 ;For line and column display coordination\r
+dbgY DD 0\r
+\r
+dbgBPAdd DD 0 ;Crnt Breakpoint Linear addresses\r
+\r
+dbgfDumpD DB 0 ;Boolean- are we dumping DWORDS?\r
+fDbgInit DB 0 ;Has Dbg Video been initialized?\r
+\r
+dbgCRLF DB 0Dh, 0Ah ;CR LF for Dump etc...\r
+dbgChar DB 0\r
+\r
+dbgMenu DB 'SStep',0B3h,'SetBP',0B3h,'ClrBP',0B3h,'CS:EIP '\r
+ DB 'Exchs',0B3h,'Tasks',0B3h,' ',0B3h,'CrntAddr'\r
+ DB 'DumpB',0B3h,'DumpD',0B3h,' ',0B3h,'AddInfo '\r
+dbgSpace DB ' '\r
+dbgCont DB 'ENTER to continue, ESC to quit.'\r
+dbgClear DB ' ' ;40 bytes\r
+dbgAsterisk DB 42\r
+\r
+; 0123456789012345678901234567890123456789012345678901234\r
+dbgExchMsg DB 'Exch Owner dMsgLo dMsgHi Task'\r
+\r
+; 0123456789012345678901234567890123456789012345678901234\r
+dbgTaskMsg DB 'Task# Job pJCB pTSS Priority '\r
+\r
+;For Debugger entry conditions\r
+dbgFltMsg DB 'FATAL Processor Exception/Fault: '\r
+sdbgFltMsg DD $-dbgFltMsg\r
+\r
+ ;Register display text\r
+\r
+dbgTxt00 DB 0B3h,'TSS: '\r
+dbgTxt01 DB 0B3h,'EAX: '\r
+dbgTxt02 DB 0B3h,'EBX: '\r
+dbgTxt03 DB 0B3h,'ECX: '\r
+dbgTxt04 DB 0B3h,'EDX: '\r
+dbgTxt05 DB 0B3h,'ESI: '\r
+dbgTxt06 DB 0B3h,'EDI: '\r
+dbgTxt07 DB 0B3h,'EBP: '\r
+dbgTxt08 DB 0B3h,' SS: '\r
+dbgTxt09 DB 0B3h,'ESP: '\r
+dbgTxt10 DB 0B3h,' CS: '\r
+dbgTxt11 DB 0B3h,'EIP: '\r
+dbgTxt12 DB 0B3h,' DS: '\r
+dbgTxt13 DB 0B3h,' ES: '\r
+dbgTxt14 DB 0B3h,' FS: '\r
+dbgTxt15 DB 0B3h,' GS: '\r
+dbgTxt16 DB 0B3h,'EFL: '\r
+dbgTxt17 DB 0B3h,'CR0: '\r
+dbgTxt18 DB 0B3h,'CR2: '\r
+dbgTxt19 DB 0B3h,'CR3: '\r
+dbgTxt20 DB 0B3h,'Erc: '\r
+\r
+dbgTxtAddr DB 'Linear address: '\r
+\r
+ ;For Important Address Info Display\r
+\r
+dbgM0 DB 'IDT: '\r
+dbgM1 DB 'GDT: '\r
+dbgM2 DB 'RQBs: '\r
+dbgM3 DB 'TSS1: '\r
+dbgM4 DB 'TSS3: '\r
+dbgM5 DB 'LBs: '\r
+dbgM6 DB 'RdyQ: '\r
+dbgM7 DB 'JCBs: '\r
+dbgM8 DB 'SVCs: '\r
+dbgM9 DB 'Exch: '\r
+dbgPA DB 'PAM: '\r
+dbgMB DB 'aTmr: '\r
+\r
+;==================== End Data, Begin Code ==========================\r
+\r
+.CODE\r
+\r
+EXTRN DDtoHex NEAR\r
+EXTRN HexToDD NEAR\r
+EXTRN _disassemble NEAR\r
+EXTRN ReadDbgKbd NEAR\r
+\r
+PUBLIC DbgTask:\r
+\r
+ MOV EAX, OFFSET DbgVidSave ;Save number of vid we interrupted\r
+ PUSH EAX\r
+ CALL FWORD PTR _GetVidOwner\r
+\r
+ STI\r
+\r
+ PUSH 2\r
+ CALL FWORD PTR _SetVidOwner ;Dbgr is Job 2\r
+\r
+ CMP fDbgInit, 0\r
+ JNE DbgInitDone\r
+ CALL FWORD PTR _ClrScr\r
+ MOV fDbgInit, 1\r
+\r
+DbgInitDone:\r
+\r
+ MOV EAX, DbgpTSSSave\r
+\r
+ ;When a fault or debug exception occurs, the values of\r
+ ;the Instruction Pointer, Code Seg, and flags are not the\r
+ ;way they were when the exception fired off becuase of the\r
+ ;interrupt procedure they enterred to get to the debugger.\r
+ ;We make them the same by putting the values we got from\r
+ ;the stack (entering the debugger) into the caller's TSS.\r
+ ;\r
+ MOV EBX,dbgOldEflgs ;Store correct flags\r
+ MOV [EAX+TSS_EFlags],EBX ;EAX still has DbgpTSSSave\r
+ MOV EBX,dbgOldCS ;Store correct CS\r
+ MOV [EAX+TSS_CS],BX\r
+ MOV EBX,dbgOldEIP ;Store correct EIP\r
+ MOV [EAX+TSS_EIP],EBX\r
+ ;\r
+ ;NOTE: The "book" says the TF flag is reset by the processor\r
+ ; when the handler is entered. This only applies if\r
+ ; the handler is a procedure (NOT a task). The debugger\r
+ ; is always entered as a procedure, (we chanage the tasks)\r
+ ; so we shouldn't have to reset it. But we do...\r
+ ; I guess I'm not reading it right or ROD SERLING LIVES!\r
+ ;\r
+ MOV EBX,[EAX+TSS_EFlags] ;Reset TF in case single steping\r
+ AND EBX,0FFFFFEFFh\r
+ MOV [EAX+TSS_EFlags],EBX\r
+\r
+ ;We set the FAULT variable based on which interrupt\r
+ ;procedure was entered.\r
+\r
+ CMP DWORD PTR dbgFAULT,0FFh ;Was the dbgr entered on a FAULT?\r
+ JE dbg000 ;NO\r
+ ;\r
+ ;NOTE: Must eventually add SS/ESP for a change in CPL on faults!!!\r
+ ;REF - See page 3-4 System Software Writer's Guide\r
+\r
+ XOR EAX, EAX\r
+ PUSH EAX ;Display fault message and\r
+ PUSH EAX ; and number at 0 ,0\r
+ CALL FWORD PTR _SetXY\r
+\r
+ LEA EAX,dbgFltMsg\r
+ PUSH EAX\r
+ PUSH sdbgFltMsg\r
+ PUSH 40h ;Color Black on RED\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ MOV EAX,dbgFAULT\r
+ PUSH EAX\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+\r
+ LEA EAX,dbgBuf\r
+ PUSH EAX\r
+ PUSH 8\r
+ PUSH 70h\r
+ CALL FWORD PTR _TTYOut\r
+ MOV DWORD PTR dbgFAULT, 0FFh ;reset fault indicator\r
+\r
+ LEA EAX,dbgCRLF\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h ;Color White on black\r
+ CALL FWORD PTR _TTYOut\r
+ XOR EAX, EAX\r
+ MOV dbgX, EAX ;Reset X & Y to 0,1\r
+ INC EAX\r
+ MOV dbgY, EAX\r
+\r
+;===================================================================\r
+dbg000:\r
+ CALL DbgRegVid ;Display BackLink's Register values\r
+ CALL dbgDispMenu ;Display menu\r
+ PUSH dbgX ;Back to where we were\r
+ PUSH dbgY\r
+ CALL FWORD PTR _SetXY\r
+\r
+\r
+ ;Display Instruction at CS:EIP\r
+ MOV EBX,DbgpTSSSave ;Get USER pUserTSS\r
+ MOV EAX, [EBX+TSS_EIP]\r
+ MOV dbgCrntAdd, EAX\r
+ CALL dbgShowBP\r
+ PUSH EAX\r
+ CALL _disassemble ;This puts the instruction on the line\r
+ MOV NextEIP, EAX\r
+ CALL dbgCheckScroll ;Fall through to keyboard loop\r
+\r
+;===========================================================\r
+ ;Now we read the keyboard\r
+dbg00:\r
+ MOV EAX, OFFSET dbgKeyCode\r
+ PUSH EAX\r
+ CALL ReadDbgKbd ;\r
+ MOV EAX, dbgKeyCode\r
+ AND EAX, 0FFh ;Lop off key status bytes\r
+\r
+ CMP EAX, 1Bh ;ESCAPE (Exit)\r
+ JE dbgExit\r
+\r
+ CMP EAX, 0Fh ;Single Step (F1)\r
+ JNE dbg02\r
+ MOV EBX,DbgpTSSSave ;Get USER pUserTSS\r
+ MOV ECX,[EBX+TSS_EFlags] ;\r
+ OR ECX,00000100h ;Set TF in flags for single step\r
+ MOV [EBX+TSS_EFlags],ECX\r
+ JMP dbgExit\r
+dbg02:\r
+ CMP EAX, 10h ;Set BP (Current Address - F2)\r
+ JNE dbg03\r
+ MOV EBX, dbgCrntAdd ;Address displayed\r
+ MOV dbgBPAdd, EBX ;Save it so we know where BP is\r
+ MOV DR0, EBX ;Move into BreakPoint Reg 0\r
+ XOR EAX, EAX\r
+ MOV DR6, EAX\r
+ MOV EAX, 00000002h ;BP0 Set global\r
+ MOV DR7, EAX\r
+ JMP dbg00 ;\r
+dbg03:\r
+ CMP EAX, 11h ;Clear BP (Current Address - F3)\r
+ JNE dbg04\r
+ XOR EAX, EAX\r
+ MOV dbgBPAdd, EAX ;Clear BP saved address\r
+ MOV DR7, EAX\r
+ JMP dbg00 ;\r
+dbg04:\r
+ CMP EAX, 12h ;Return to CS:EIP (F4)\r
+ JNE dbg05\r
+ MOV EBX,DbgpTSSSave ;Get USER pUserTSS\r
+ MOV EAX, [EBX+TSS_EIP]\r
+ MOV dbgCrntAdd, EAX\r
+ CALL dbgShowBP\r
+ PUSH EAX\r
+ CALL _disassemble ;This puts the instruction on the line\r
+ MOV NextEIP, EAX\r
+ CALL dbgCheckScroll ;See if we need to scroll up\r
+ JMP dbg00 ;\r
+dbg05:\r
+ CMP EAX, 13h ;Display Exchanges (F5)\r
+ JNE dbg06\r
+ CALL dbgDispExchs\r
+ JMP dbg000 ;Full display\r
+dbg06:\r
+ CMP EAX, 14h ;Task array display (F6)\r
+ JNE dbg07\r
+ CALL dbgDispTasks\r
+ JMP dbg000 ;\r
+dbg07:\r
+ CMP EAX, 15h ;Not used yet\r
+ JNE dbg08\r
+ JMP dbg00 ;\r
+dbg08:\r
+ CMP AL, 16h ;Set Disassembly Address (F8)\r
+ JNE dbg09\r
+ CALL dbgSetAddr ;Sets NextEIP\r
+ PUSH dbgX ;Back to where we were\r
+ PUSH dbgY\r
+ CALL FWORD PTR _SetXY\r
+ MOV EAX, NextEIP\r
+ MOV dbgCrntAdd, EAX\r
+ CALL dbgShowBP\r
+ PUSH EAX\r
+ CALL _disassemble ;This puts the instruction on the line\r
+ MOV NextEIP, EAX\r
+ CALL dbgCheckScroll ;See if we need to scroll up\r
+ JMP dbg00 ;\r
+dbg09:\r
+ CMP AL, 17h ;Memory Dump Bytes (F9)\r
+ JNE dbg10\r
+ MOV BL, 00\r
+ MOV dbgfDumpD, BL\r
+ CALL dbgDump ;\r
+ JMP dbg000\r
+dbg10:\r
+ CMP AL, 18h ;Memory Dump DWORDS (F10)\r
+ JNE dbg12\r
+ MOV BL, 0FFh\r
+ MOV dbgfDumpD, BL\r
+ CALL dbgDump ;\r
+ JMP dbg000\r
+dbg12:\r
+ CMP AL, 01Ah ;Info Address dump (F12)\r
+ JNE dbg13\r
+ CALL DbgInfo ;\r
+ JMP dbg00\r
+\r
+dbg13: CMP AL, 02h ;Display next Instruction (Down Arrow)\r
+ JNE dbg14\r
+ MOV EAX, NextEIP\r
+ MOV dbgCrntAdd, EAX\r
+ CALL dbgShowBP\r
+ PUSH EAX\r
+ CALL _disassemble ;This puts the instruction on the line\r
+ MOV NextEIP, EAX\r
+ CALL dbgCheckScroll ;See if we need to scroll up\r
+ JMP dbg00\r
+\r
+dbg14:\r
+ JMP dbg00 ;GO back for another key\r
+\r
+DbgExit:\r
+\r
+ LEA EAX,dbgX ;Query XY\r
+ PUSH EAX\r
+ LEA EAX,dbgY\r
+ PUSH EAX\r
+ CALL FWORD PTR _GetXY\r
+\r
+ PUSH DbgVidSave\r
+ CALL FWORD PTR _SetVidOwner ;Change screens back\r
+\r
+ MOV EAX, DbgpTSSSave ;Return saved pRunTSS\r
+ MOV pRunTSS, EAX\r
+ MOV BX, [EAX+Tid]\r
+ MOV TSS_Sel, BX ;Set up caller's TSS selector\r
+\r
+ JMP FWORD PTR [TSS]\r
+\r
+ ;Next time we enter the debugger task it will be here!\r
+ JMP DbgTask ;Back to begining\r
+\r
+;==============================================================\r
+\r
+dbgShowBP:\r
+ ;This compares the current breakpoint the address\r
+ ;we are about to display. If they are the same,\r
+ ;we put up an asterisk to indicate it's the breakpoint\r
+ ;EAX must be preserved\r
+\r
+ MOV EBX, dbgCrntAdd ;Address displayed\r
+ MOV ECX, dbgBPAdd ;BP Address\r
+ CMP EBX, ECX\r
+ JZ dbgShowBP1\r
+ RETN\r
+dbgShowBP1:\r
+ PUSH EAX ;Save EAX across call\r
+ PUSH OFFSET dbgAsterisk ;3 params to TTYOut\r
+ PUSH 01h\r
+ PUSH 47h ;Reverse Vid WHITE on RED\r
+ CALL FWORD PTR _TTYOut\r
+ POP EAX\r
+ RETN\r
+\r
+;==============================================================\r
+;This sets up and calls to display all of the regsiter\r
+;information on the right side of the debugger video display\r
+\r
+DbgRegVid:\r
+ MOV EBX,DbgpTSSSave ;EBX MUST be DbgpTSSSave\r
+ MOV ECX,00 ;TSS Display\r
+ MOV ESI,OFFSET DbgTxt00\r
+ XOR EAX,EAX\r
+ MOV AX,[EBX+TSSNum] ;Number of this TSS\r
+ CALL DispRegs\r
+\r
+ MOV ECX,01 ;EAX Display\r
+ MOV ESI,OFFSET DbgTxt01\r
+ MOV EAX,[EBX+TSS_EAX]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,02 ;EBX Display\r
+ MOV ESI,OFFSET DbgTxt02\r
+ MOV EAX,[EBX+TSS_EBX]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,03 ;ECX Display\r
+ MOV ESI,OFFSET DbgTxt03\r
+ MOV EAX,[EBX+TSS_ECX]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,04 ;EDX Display\r
+ MOV ESI,OFFSET DbgTxt04\r
+ MOV EAX,[EBX+TSS_EDX]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,05 ;ESI Display\r
+ MOV ESI,OFFSET DbgTxt05\r
+ MOV EAX,[EBX+TSS_ESI]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,06 ;EDI Display\r
+ MOV ESI,OFFSET DbgTxt06\r
+ MOV EAX,[EBX+TSS_EDI]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,07 ;EBP Display\r
+ MOV ESI,OFFSET DbgTxt07\r
+ MOV EAX,[EBX+TSS_EBP]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,08 ;SS Display\r
+ MOV ESI,OFFSET DbgTxt08\r
+ XOR EAX,EAX\r
+ MOV AX,[EBX+TSS_SS]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,09 ;ESP Display\r
+ MOV ESI,OFFSET DbgTxt09\r
+ MOV EAX,[EBX+TSS_ESP]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,10 ;CS Display\r
+ MOV ESI,OFFSET DbgTxt10\r
+ XOR EAX,EAX\r
+ MOV AX,[EBX+TSS_CS]\r
+ CALL DispRegs\r
+\r
+ MOV ECX,11 ;EIP Display\r
+ MOV ESI,OFFSET DbgTxt11\r
+ MOV EAX,[EBX+TSS_EIP]\r
+ CALL DispRegs\r
+ MOV ECX,12 ;DS Display\r
+ MOV ESI,OFFSET DbgTxt12\r
+ XOR EAX,EAX\r
+ MOV AX,[EBX+TSS_DS]\r
+ CALL DispRegs\r
+ MOV ECX,13 ;ES Display\r
+ MOV ESI,OFFSET DbgTxt13\r
+ XOR EAX,EAX\r
+ MOV AX,[EBX+TSS_ES]\r
+ CALL DispRegs\r
+ MOV ECX,14 ;FS Display\r
+ MOV ESI,OFFSET DbgTxt14\r
+ XOR EAX,EAX\r
+ MOV AX,[EBX+TSS_FS]\r
+ CALL DispRegs\r
+ MOV ECX,15 ;GS Display\r
+ MOV ESI,OFFSET DbgTxt15\r
+ XOR EAX,EAX\r
+ MOV AX,[EBX+TSS_GS]\r
+ CALL DispRegs\r
+ MOV ECX,16 ;EFlags Display\r
+ MOV ESI,OFFSET DbgTxt16\r
+ MOV EAX,[EBX+TSS_EFlags]\r
+ CALL DispRegs\r
+ MOV ECX,17 ;CR0 Display\r
+ MOV ESI,OFFSET DbgTxt17\r
+ MOV EAX,CR0\r
+ CALL DispRegs\r
+ MOV ECX,18 ;CR2 Display\r
+ MOV ESI,OFFSET DbgTxt18\r
+ MOV EAX,CR2\r
+ CALL DispRegs\r
+ MOV ECX,19 ;CR3 Display\r
+ MOV ESI,OFFSET DbgTxt19\r
+ MOV EAX,CR3\r
+ CALL DispRegs\r
+ MOV ECX,20 ;Fault Error Code Display\r
+ MOV ESI,OFFSET DbgTxt20\r
+ MOV EAX,dbgFltErc\r
+ CALL DispRegs\r
+ RETN\r
+;=============================================================================\r
+;\r
+; This is for Debugger Register display\r
+; Call with: EAX loaded with value to display (from TSS reg)\r
+; ECX loaded with number of text line to display on\r
+; ESI loaded with EA of text line to display\r
+; We save all registers cause the vid calls don't\r
+\r
+DispRegs:\r
+ PUSHAD\r
+\r
+ PUSH EAX ;Save number to display\r
+\r
+ PUSH 66\r
+ PUSH ECX\r
+ CALL FWORD PTR _SetXY\r
+\r
+ PUSH ESI\r
+ PUSH 05h\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ POP EAX ;Get number back for display\r
+\r
+ PUSH EAX\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+\r
+ PUSH OFFSET dbgBuf\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ POPAD\r
+ RETN\r
+;==============================================\r
+; This displays the debugger function key menu\r
+\r
+dbgDispMenu:\r
+ PUSH 0 ;Display Debugger FKey Menu\r
+ PUSH 24\r
+ CALL FWORD PTR _SetXY\r
+\r
+ LEA EAX,dbgMenu\r
+ PUSH EAX\r
+ PUSH 78\r
+ PUSH 70h\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ PUSH 25\r
+ PUSH 24\r
+ CALL FWORD PTR _SetXY\r
+\r
+ LEA EAX,dbgSpace\r
+ PUSH EAX\r
+ PUSH 1\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ PUSH 51\r
+ PUSH 24\r
+ CALL FWORD PTR _SetXY\r
+\r
+ LEA EAX,dbgSpace\r
+ PUSH EAX\r
+ PUSH 1\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ RETN\r
+;===========================\r
+;Allows the user to pick the currently displayed address\r
+\r
+dbgSetAddr:\r
+ PUSH 0 ;Goto Query Line\r
+ PUSH 23 ;\r
+ CALL FWORD PTR _SetXY\r
+\r
+ LEA EAX, dbgTxtAddr\r
+ PUSH EAX\r
+ PUSH 16\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ CMP EAX, 0\r
+ JNE DumpDone\r
+\r
+ LEA EAX, DbgBuf2 ;\r
+ PUSH EAX ;pEdString\r
+ PUSH cbBufLen2 ;Crnt size\r
+ PUSH 8 ;Max size\r
+ LEA EAX, cbBufLen2 ;\r
+ PUSH EAX ;ptr to size returned\r
+ LEA EAX, dbgChar ;\r
+ PUSH EAX ;ptr to char returned\r
+ PUSH 70h ;Black On White\r
+ CALL FWORD PTR _EditLine ;Ignore error if any\r
+\r
+ MOV AL, dbgChar ;did they exit with CR?\r
+ CMP AL, 0Dh\r
+ JNE dbgSetAddrDone\r
+\r
+ LEA EAX, dbgBuf2 ;Convert String to DD\r
+ PUSH EAX ;ptr to string\r
+ LEA EAX, dbgNextAdd\r
+ PUSH EAX ;ptr to destination DD\r
+ PUSH cbBufLen2 ;length of string\r
+ CALL HexToDD ;dbgDumpAdd has address to dump!\r
+ CMP EAX, 0\r
+ JNE dbgSetAddrDone\r
+\r
+ MOV EAX, dbgNextAdd\r
+ MOV NextEIP, EAX\r
+dbgSetAddrDone:\r
+ CALL dbgClearQuery\r
+ RETN ;Go home...\r
+;===========================\r
+;Queries user for address then dumps data to screen\r
+\r
+dbgDump:\r
+ PUSH 0 ;Goto Query Line\r
+ PUSH 23 ;\r
+ CALL FWORD PTR _SetXY\r
+\r
+ LEA EAX, dbgTxtAddr\r
+ PUSH EAX\r
+ PUSH 16\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ CMP EAX, 0\r
+ JNE DumpDone\r
+\r
+ LEA EAX, DbgBuf2 ;\r
+ PUSH EAX ;pEdString\r
+ PUSH cbBufLen2 ;Crnt size\r
+ PUSH 8 ;Max size\r
+ LEA EAX, cbBufLen2 ;\r
+ PUSH EAX ;ptr to size returned\r
+ LEA EAX, dbgChar ;\r
+ PUSH EAX ;ptr to char returned\r
+ PUSH 70h ;Black On White\r
+ CALL FWORD PTR _EditLine ;Ignore error if any\r
+\r
+ MOV AL, dbgChar ;did they exit with CR?\r
+ CMP AL, 0Dh\r
+ JE dbgDoDump\r
+ CALL dbgClearQuery\r
+ RETN ;Go home...\r
+\r
+dbgDoDump:\r
+ LEA EAX, dbgBuf2 ;Convert String to DD\r
+ PUSH EAX ;ptr to string\r
+ LEA EAX, dbgDumpAdd\r
+ PUSH EAX ;ptr to destination DD\r
+ PUSH cbBufLen2 ;length of string\r
+ CALL HexToDD ;dbgDumpAdd has address to dump!\r
+ CMP EAX, 0\r
+ JNE DumpDone\r
+\r
+ CALL FWORD PTR _ClrScr\r
+\r
+dbgDump00:\r
+ MOV DWORD PTR dbgGPdd1, 24 ;line counter begins at 24\r
+dbgDump01:\r
+ MOV DWORD PTR dbgGPdd3, 4 ;number of quads per line\r
+ PUSH dbgDumpAdd ;convert address to text\r
+ LEA EAX, dbgBuf\r
+ PUSH EAX\r
+ CALL DDtoHex\r
+\r
+ LEA EAX, dbgBuf\r
+ PUSH EAX\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ CMP EAX, 0\r
+ JNE DumpDone\r
+dbgDump02:\r
+ MOV DWORD PTR dbgGPdd2, 6 ;byte offset begins at 6\r
+ LEA EAX, dbgSpace\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ CMP EAX, 0\r
+ JNE DumpDone\r
+ MOV EBX, dbgDumpAdd ;get dump address\r
+ MOV EAX, [EBX] ;Get what it's pointing to\r
+ PUSH EAX ;make it a DD Text\r
+ LEA EAX, dbgBuf\r
+ PUSH EAX\r
+ CALL DDtoHex\r
+ MOV AL, dbgfDumpD ;Dumping DWORDS\r
+ CMP AL, 0\r
+ JE DumpB ;NO - go to display bytes\r
+\r
+ LEA EAX, dbgBuf ;Yes display Quad\r
+ PUSH EAX\r
+ PUSH 8\r
+ PUSH 07\r
+ CALL FWORD PTR _TTYOut\r
+ JMP DumpDin\r
+\r
+ dumpB:\r
+ LEA EAX, dbgBuf ;Display First byte\r
+ ADD EAX, dbgGPdd2\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut ;ignore error\r
+\r
+ LEA EAX, dbgSpace ;Display 1 spaces\r
+ PUSH EAX\r
+ PUSH 1\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ DEC dbgGPdd2 ;point to second 2 bytes\r
+ DEC dbgGPdd2\r
+\r
+ LEA EAX, dbgBuf ;display 2st byte\r
+ ADD EAX, dbgGPdd2\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut ;ignore error\r
+\r
+ LEA EAX, dbgSpace ; display 1 space\r
+ PUSH EAX\r
+ PUSH 1\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ DEC dbgGPdd2\r
+ DEC dbgGPdd2\r
+\r
+ LEA EAX, dbgBuf ;display 3rd byte\r
+ ADD EAX, dbgGPdd2\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut ;ignore error\r
+\r
+ LEA EAX, dbgSpace ;a space\r
+ PUSH EAX\r
+ PUSH 1\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ DEC dbgGPdd2\r
+ DEC dbgGPdd2\r
+\r
+ LEA EAX, dbgBuf ;display 4th byte\r
+ ADD EAX, dbgGPdd2\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut ;ignore error\r
+DumpDin:\r
+ INC dbgDumpAdd\r
+ INC dbgDumpAdd\r
+ INC dbgDumpAdd\r
+ INC dbgDumpAdd\r
+ DEC dbgGPdd3 ;done with 4 quads??\r
+ JNZ dbgDump02 ;NO - go back for next 4 bytes\r
+\r
+ LEA EAX, dbgSpace ;Yes - Display 2 spaces\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ LEA EAX,dbgX ;Query XY\r
+ PUSH EAX\r
+ LEA EAX,dbgY\r
+ PUSH EAX\r
+ CALL FWORD PTR _GetXY\r
+\r
+ PUSH dbgX ;Put 16 TEXT chars on right\r
+ PUSH dbgY\r
+ MOV EAX, dbgDumpAdd\r
+ SUB EAX, 16\r
+ PUSH EAX\r
+ PUSH 16\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;ignore error\r
+\r
+ LEA EAX, dbgCRLF ;Do CR/LF\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ ;\r
+ DEC dbgGPdd1 ;23lines yet??\r
+ JNZ dbgDump01 ;NO\r
+ ;\r
+ LEA EAX, dbgCont ;"Continue" Text\r
+ PUSH EAX\r
+ PUSH 31 ;size of "cont text"\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+dbgDump03:\r
+ MOV EAX, OFFSET dbgKeyCode\r
+ PUSH EAX\r
+ CALL ReadDbgKbd\r
+ MOV EAX, dbgKeyCode\r
+ AND EAX, 0FFh ;Lop off key status bytes\r
+ CMP EAX, 0\r
+ JE dbgDump03\r
+ CMP EAX, 1Bh ;Escape (Quit??)\r
+ JE DumpDone\r
+\r
+ LEA EAX, dbgCRLF ;Do CR/LF\r
+ PUSH EAX\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+ JMP dbgDump00\r
+\r
+ ;\r
+ DumpDone:\r
+ CALL FWORD PTR _ClrScr\r
+ MOV DWORD PTR dbgX, 0\r
+ MOV DWORD PTR dbgY, 0\r
+ RETN\r
+;===========================\r
+\r
+;Displays exchanges that are allocated along with\r
+;messages or tasks that may be wiating at them\r
+\r
+dbgDispExchs:\r
+\r
+ MOV DWORD PTR dbgGPdd2, 0 ;Exch# we are on\r
+dbgDE00:\r
+ CALL FWORD PTR _ClrScr\r
+ PUSH 0 ;Col\r
+ PUSH 0 ;Line for labels\r
+ PUSH OFFSET dbgExchMsg ;\r
+ PUSH 54 ;Length of message\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+ MOV DWORD PTR dbgGPdd1, 1 ;line we are one\r
+\r
+ ;First we do the exchange on the current line\r
+dbgDE01:\r
+ PUSH dbgGPdd2 ;Convert Exch number for display\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+\r
+ PUSH 0 ;Col\r
+ PUSH dbgGPdd1 ;Line we are one\r
+ PUSH OFFSET dbgBuf ;ExchNum\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ ;Then we do the Exch Owner (Job Number) next to it\r
+\r
+ MOV EAX, dbgGPdd2 ; Exch number\r
+ MOV EDX, sEXCH ; Compute offset of Exch in rgExch\r
+ MUL EDX ;\r
+ MOV EDX,prgExch ; Add offset of rgExch => EAX\r
+ ADD EAX,EDX ; EAX now pts to Exch\r
+ MOV dbgGPdd3, EAX ; pExch into save variable\r
+ MOV EBX, [EAX+Owner] ; pJCB of Owner into EBX\r
+ XOR EAX, EAX ; Clear for use as JobNum\r
+ OR EBX, EBX ; pNIL? (No owner if so)\r
+ JZ dbgDE03\r
+ MOV EAX, [EBX+JobNum] ;\r
+dbgDE03:\r
+ PUSH EAX ;Convert Job Number\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+\r
+ PUSH 10 ;Col\r
+ PUSH dbgGPdd1 ;Line\r
+ PUSH OFFSET dbgBuf ;\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ MOV dbgGPdd5, 0 ;Set pNextMsg to 0\r
+\r
+ ;See if there is a first message\r
+\r
+ MOV EAX, dbgGPdd3 ;pExch -> EAX\r
+ MOV EBX, [EAX+EHead] ;pMsg -> EBX\r
+ OR EBX, EBX ;Is is NIL (no msg or task)?\r
+ JZ dbgDE13 ;Yes. Go to next Exch\r
+\r
+ MOV EBX, [EAX+fEMsg] ;MsgFlag -> EBX\r
+ OR EBX, EBX ;Is is 1 (a message)?\r
+ JZ dbgDE05 ;No, Go check for tasks\r
+ MOV EBX, [EAX+EHead] ;pMsg -> EBX\r
+\r
+ ;Display Messages\r
+dbgDE04:\r
+ MOV DWORD PTR dbgGPdd6, 0 ;Flag to indicate we are doing messages\r
+ MOV EAX, [EBX+NextLB] ;For next msg in chain (if it exists)\r
+ MOV dbgGPdd5, EAX ;Save for loop\r
+ MOV EAX, [EBX+DataHi] ;Get dMsg1\r
+ MOV EDX, [EBX+DataLo] ;Get dMsg2\r
+ PUSH EDX ;Save dMsg2\r
+\r
+ PUSH EAX ;Convert dMsg1\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+\r
+ PUSH 20 ;Col\r
+ PUSH dbgGPdd1 ;Line\r
+ PUSH OFFSET dbgBuf ;\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ POP EDX ;Get dMsg2 back\r
+\r
+ ;Could have left it on stack, but would be confusing later...\r
+ ;"simplicity of maintenance is as important as simplicity of design"\r
+\r
+ PUSH EDX ;Convert dMsg2\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+\r
+ PUSH 30 ;Col\r
+ PUSH dbgGPdd1 ;Line\r
+ PUSH OFFSET dbgBuf ;\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+ JMP dbgDE07 ;Next line please\r
+\r
+ ;See if there are tasks waiting\r
+dbgDE05:\r
+ MOV DWORD PTR dbgGPdd6, 1 ;Flag to indicate we are doing tasks\r
+ MOV DWORD PTR dbgGPdd5, 0 ;Clear pNextTask\r
+ MOV EAX, dbgGPdd3 ;pExch -> EAX\r
+ MOV EBX, [EAX+EHead] ;pTSS -> EBX\r
+ OR EBX, EBX ;Is is 0 (no TSS)?\r
+ JZ dbgDE07 ;\r
+dbgDE06:\r
+ MOV EAX, [EBX+NextTSS]\r
+ MOV dbgGPdd5, EAX ;Save ptr to next task if it exists\r
+ XOR EAX, EAX\r
+ MOV AX, [EBX+TSSNum] ;Get Number of Task at exch\r
+\r
+ PUSH EAX ;Convert Task Number\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+\r
+ PUSH 50 ;Col\r
+ PUSH dbgGPdd1 ;Line\r
+ PUSH OFFSET dbgBuf ;\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+dbgDE07:\r
+ INC dbgGPdd1 ;Next line\r
+ CMP DWORD PTR dbgGPdd1, 23 ;23 lines yet?\r
+ JB dbgDE09 ;No\r
+ ;\r
+dbgDE08:\r
+ PUSH 0 ;Col\r
+ PUSH 24 ;Line\r
+ PUSH OFFSET dbgCont ;\r
+ PUSH 31 ;length of Cont string\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ MOV EAX, OFFSET dbgKeyCode\r
+ PUSH EAX\r
+ CALL ReadDbgKbd\r
+ MOV EAX, dbgKeyCode\r
+ AND EAX, 0FFh ;Lop off key status bytes\r
+ CMP EAX, 1Bh ;Escape (Quit??)\r
+ JE dbgDEDone\r
+\r
+ CMP DWORD PTR dbgGPdd2, nDynEXCH ; Number of dynamic exchanges\r
+ JAE dbgDEDone ; All Exchs displayed\r
+\r
+ CALL FWORD PTR _ClrScr ;\r
+ PUSH 0 ;Col\r
+ PUSH 0 ;Line for labels\r
+ PUSH OFFSET dbgExchMsg ;\r
+ PUSH 54 ;Length of message\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+ MOV DWORD PTR dbgGPdd1, 1 ;line. We are on line 1 again\r
+\r
+dbgDE09:\r
+ MOV EBX, dbgGPdd5 ;Set up to loop for next msg/task\r
+ XOR EBX, EBX ;Another pointer in the link?\r
+ JZ dbgDE13 ;No\r
+ MOV EAX, dbgGPdd6 ;\r
+ OR EAX, EAX ;NonZero if we are doing tasks\r
+ JNZ dbgDE06 ;Tasks\r
+ JMP dbgDE04 ;Messages\r
+dbgDE13:\r
+ INC dbgGPdd2 ; Exch number\r
+ CMP DWORD PTR dbgGPdd2, nDynEXCH ; Number of dynamic exchanges\r
+ JAE dbgDE08 ; Go back for prompt (to pause)\r
+ JMP dbgDE01 ; Back to display new exch num\r
+dbgDEDone:\r
+ CALL FWORD PTR _ClrScr\r
+ MOV DWORD PTR dbgX, 0\r
+ MOV DWORD PTR dbgY, 0\r
+ RETN\r
+\r
+;===========================\r
+;Displays Tasks that are active along with \r
+;pertinent address info about them\r
+\r
+dbgDispTasks:\r
+ MOV DWORD PTR dbgGPdd2, 1 ;Task# we are on\r
+dbgDT00:\r
+ CALL FWORD PTR _ClrScr\r
+ PUSH 0 ;Col\r
+ PUSH 0 ;Line for labels\r
+ PUSH OFFSET dbgTaskMsg ;\r
+ PUSH 54 ;Length of message\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+ MOV DWORD PTR dbgGPdd1, 1 ;line we are one\r
+\r
+ ;First we get pTSS and see if it is valid\r
+ ;If so, we get all the data BEFORE we display it\r
+ ;If not, we increment TSS number and go back\r
+ ;for the next one\r
+dbgDT01:\r
+ ;We get pJCB out of TSS and get JobNum from JCB\r
+\r
+ MOV EAX, dbgGPdd2 ; Task number\r
+ CMP EAX, 1 ; Is this TSS 1 (Static memory)\r
+ JNE dbgDT02\r
+ MOV EBX, OFFSET MonTSS ;\r
+ JMP SHORT dbgDT04\r
+dbgDT02:\r
+ CMP EAX, 2 ; Is this TSS 2 (Static memory)\r
+ JNE dbgDT03\r
+ MOV EBX, OFFSET DbgTSS ;\r
+ JMP SHORT dbgDT04\r
+dbgDT03:\r
+ MOV EBX, pDynTSSs\r
+ DEC EAX ;Make TSS Num offset in dynamic array\r
+ DEC EAX ;of TSSs\r
+ DEC EAX\r
+ MOV ECX, 512\r
+ MUL ECX\r
+ ADD EBX, EAX ;EBX points to TSS!\r
+dbgDT04:\r
+ ;EBX has pTSS of interest\r
+ MOV dbgGPdd5, EBX ;Save pTSS for display\r
+ XOR ECX, ECX ;\r
+ MOV CL, [EBX+Priority] ;Priotity of this task\r
+ MOV dbgGPdd6, ECX\r
+ MOV EAX, [EBX+TSS_pJCB] ;EAX has pJCB\r
+ OR EAX, EAX ;NON zero means it's valid\r
+ JNZ dbgDT05\r
+ MOV EAX, dbgGPdd2 ;Not used, go for next Task number\r
+ INC EAX\r
+ CMP EAX, nTSS ;\r
+ JE dbgDT06\r
+ MOV dbgGPdd2, EAX\r
+ JMP SHORT dbgDT01 ;back for next one\r
+dbgDT05:\r
+ ;EAX now pJCB\r
+ MOV dbgGPdd4, EAX ;Save pJCB for display\r
+ MOV EBX, [EAX] ;Job number is first DD in JCB\r
+ MOV dbgGPdd3, EBX\r
+\r
+ PUSH dbgGPdd2 ;Convert TSS number for display\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+ PUSH 0 ;Col\r
+ PUSH dbgGPdd1 ;Line we are one\r
+ PUSH OFFSET dbgBuf ;TaskNum\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ PUSH dbgGPdd3 ;Convert and display Job number\r
+ PUSH OFFSET dbgBuf ;\r
+ CALL DDtoHex\r
+ PUSH 10 ;Col\r
+ PUSH dbgGPdd1 ;Line we are one\r
+ PUSH OFFSET dbgBuf ;\r
+ PUSH 8 ;Size\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ PUSH dbgGPdd4 ;Convert and display pJCB\r
+ PUSH OFFSET dbgBuf ;\r
+ CALL DDtoHex\r
+ PUSH 20 ;Col\r
+ PUSH dbgGPdd1 ;Line we are one\r
+ PUSH OFFSET dbgBuf ;\r
+ PUSH 8 ;Size\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ PUSH dbgGPdd5 ;Convert and display pTSS\r
+ PUSH OFFSET dbgBuf ;\r
+ CALL DDtoHex\r
+ PUSH 30 ;Col\r
+ PUSH dbgGPdd1 ;Line we are one\r
+ PUSH OFFSET dbgBuf ;\r
+ PUSH 8 ;Size\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ PUSH dbgGPdd6 ;Convert and display Priority\r
+ PUSH OFFSET dbgBuf ;\r
+ CALL DDtoHex\r
+ PUSH 40 ;Col\r
+ PUSH dbgGPdd1 ;Line we are one\r
+ PUSH OFFSET dbgBuf ;\r
+ PUSH 8 ;Size\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ MOV EAX, dbgGPdd2 ;go for next Task number\r
+ INC EAX\r
+ CMP EAX, nTSS ;\r
+ JE dbgDT06\r
+ MOV dbgGPdd2, EAX ;Save it for the top\r
+\r
+ INC dbgGPdd1 ;Next line\r
+ CMP DWORD PTR dbgGPdd1, 23 ;23 lines yet?\r
+ JAE dbgDT06 ;Yes, continue prompt\r
+ JMP dbgDT01 ;No, go back for next\r
+dbgDT06:\r
+ PUSH 0 ;Col\r
+ PUSH 24 ;Line\r
+ PUSH OFFSET dbgCont ;\r
+ PUSH 31 ;length of Cont string\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;\r
+\r
+ MOV EAX, OFFSET dbgKeyCode\r
+ PUSH EAX\r
+ CALL ReadDbgKbd\r
+ MOV EAX, dbgKeyCode\r
+ AND EAX, 0FFh ;Lop off key status bytes\r
+ CMP EAX, 1Bh ;Escape (Quit??)\r
+ JE dbgDTDone\r
+ JMP dbgDT00 ;Back for next screen\r
+dbgDTDone:\r
+ CALL FWORD PTR _ClrScr\r
+ MOV DWORD PTR dbgX, 0\r
+ MOV DWORD PTR dbgY, 0\r
+ RETN\r
+\r
+;=============================================================================\r
+; This is for Debugger Address Info display\r
+; Call with:\r
+; EAX loaded with address to display (Linear Address)\r
+; ESI loaded with EA of text line to display\r
+; We save all registers cause the vid calls don't\r
+;=============================================================================\r
+DispAddr:\r
+ PUSHAD\r
+ PUSH EAX ;Save number to display\r
+\r
+ PUSH ESI ;ptr to line\r
+ PUSH 06h ;Length of line\r
+ PUSH 07h ;Vid Attribute\r
+ CALL FWORD PTR _TTYOut ;Do it\r
+\r
+ POP EAX ;Get number back for display\r
+\r
+ PUSH EAX\r
+ PUSH OFFSET dbgBuf\r
+ CALL DDtoHex\r
+\r
+ PUSH OFFSET dbgBuf\r
+ PUSH 8\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ PUSH OFFSET dbgCRLF\r
+ PUSH 2\r
+ PUSH 07h\r
+ CALL FWORD PTR _TTYOut\r
+\r
+ CALL dbgCheckScroll\r
+\r
+ POPAD\r
+ RETN\r
+;===============================================\r
+;DbgInfo - Displays important linear address for the OS\r
+\r
+DbgInfo:\r
+ MOV ESI,OFFSET DbgM0 ;IDT\r
+ LEA EAX, IDT\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM1 ;GDT\r
+ LEA EAX, GDT\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM2 ;RQBs\r
+ MOV EAX, pRQBs\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM3 ;MonTSS\r
+ MOV EAX, OFFSET MonTSS\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM4 ;pTSS3\r
+ MOV EAX, pDynTSSs\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM5 ;LBs\r
+ LEA EAX, rgLBs\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM6 ;RdyQ\r
+ LEA EAX, RdyQ\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM7 ;JCBs\r
+ MOV EAX, pJCBs\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM8 ;SVCs\r
+ LEA EAX, rgSVC\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgM9 ;Exchs\r
+ MOV EAX, prgExch\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgPA ;PAM (Page Allocation map)\r
+ LEA EAX, rgPAM\r
+ CALL DispAddr\r
+ MOV ESI,OFFSET DbgMB ;Timer Blocks\r
+ LEA EAX, rgTmrBlks\r
+ CALL DispAddr\r
+ RETN\r
+\r
+;=======================================================\r
+;All of the debugger text is displayed in a window\r
+;between colums 0 and 66, and line 0 to 24. The other\r
+;areas are resrved for the menu, query line,\r
+;and the register display.\r
+;This checks to see if the cursor is on line 23.\r
+;If so, we scroll up the text area by one line.\r
+\r
+dbgCheckScroll:\r
+ LEA EAX,dbgX ;Query XY (See what line and Col)\r
+ PUSH EAX\r
+ LEA EAX,dbgY\r
+ PUSH EAX\r
+ CALL FWORD PTR _GetXY\r
+ CMP DWORD PTR dbgY, 23 ;Are we at bottom (just above menu)??\r
+ JB dbgNoScroll ;No, go back for next key\r
+\r
+ PUSH 0 ;Yes, Scroll test area (Col 0-64, Line 0-24)\r
+ PUSH 0\r
+ PUSH 66 ;Columns 0-65\r
+ PUSH 24 ;Lines 0-23\r
+ PUSH 1 ;fUp (1)\r
+ CALL FWORD PTR _ScrollVid\r
+\r
+ PUSH 0 ;Got to Column 0, Line 22\r
+ PUSH 22\r
+ CALL FWORD PTR _SetXY\r
+dbgNoScroll:\r
+ RETN\r
+;\r
+;=======================================================\r
+;Clear the query line (Line 23, 40 chars)\r
+\r
+dbgClearQuery:\r
+ PUSH 0 ;Col 0, Line 23\r
+ PUSH 23\r
+ PUSH OFFSET dbgClear\r
+ PUSH 40\r
+ PUSH 07h\r
+ CALL FWORD PTR _PutVidChars ;ignore error\r
+ RETN\r
+\r
+;===================== module end ======================\r