1 ; MMURTL Operating System Source Code
\r
2 ; Copyright 1991,1992,1993,1994 Richard A. Burgess
\r
3 ; ALL RIGHTS RESERVED Version 1.0
\r
4 ;=============================================================================
\r
13 ;External near Variables
\r
20 ;debugger variables and buffers
\r
22 PUBLIC DbgpTSSSave DD 0 ;TO save the TSS we interrupted
\r
23 PUBLIC dbgFAULT DD 0FFh ;0FFh is NO FAULT
\r
24 PUBLIC dbgFltErc DD 0
\r
25 PUBLIC dbgOldEIP DD 0
\r
26 PUBLIC dbgOldCS DD 0
\r
27 PUBLIC dbgOldEflgs DD 0
\r
29 DbgVidSave DD 0 ;To save interrupted video user
\r
30 dbgBuf DB '00000000' ;General use buffers
\r
31 dbgBuf2 DB '0000000000'
\r
34 cbBufLen2 DD 0 ;Active bytes in buf2
\r
35 dbgKeyCode DD 0 ;For ReadDbgKbd
\r
36 NextEIP DD 0 ;For Disassem display (next ins to be executed)
\r
37 dbgGPdd1 DD 0 ;General purpose DDs (used all over)
\r
42 dbgGPdd6 DD 0 ;flag 1 = Msg, 0 = Exch
\r
44 dbgNextAdd DD 0 ;Address we are setting as next
\r
45 dbgCrntAdd DD 0 ;Address of instructions we are displaying
\r
46 dbgDumpAdd DD 0 ;Address we are dumping
\r
48 dbgX DD 0 ;For line and column display coordination
\r
51 dbgBPAdd DD 0 ;Crnt Breakpoint Linear addresses
\r
53 dbgfDumpD DB 0 ;Boolean- are we dumping DWORDS?
\r
54 fDbgInit DB 0 ;Has Dbg Video been initialized?
\r
56 dbgCRLF DB 0Dh, 0Ah ;CR LF for Dump etc...
\r
59 dbgMenu DB 'SStep',0B3h,'SetBP',0B3h,'ClrBP',0B3h,'CS:EIP '
\r
60 DB 'Exchs',0B3h,'Tasks',0B3h,' ',0B3h,'CrntAddr'
\r
61 DB 'DumpB',0B3h,'DumpD',0B3h,' ',0B3h,'AddInfo '
\r
63 dbgCont DB 'ENTER to continue, ESC to quit.'
\r
64 dbgClear DB ' ' ;40 bytes
\r
67 ; 0123456789012345678901234567890123456789012345678901234
\r
68 dbgExchMsg DB 'Exch Owner dMsgLo dMsgHi Task'
\r
70 ; 0123456789012345678901234567890123456789012345678901234
\r
71 dbgTaskMsg DB 'Task# Job pJCB pTSS Priority '
\r
73 ;For Debugger entry conditions
\r
74 dbgFltMsg DB 'FATAL Processor Exception/Fault: '
\r
75 sdbgFltMsg DD $-dbgFltMsg
\r
77 ;Register display text
\r
79 dbgTxt00 DB 0B3h,'TSS: '
\r
80 dbgTxt01 DB 0B3h,'EAX: '
\r
81 dbgTxt02 DB 0B3h,'EBX: '
\r
82 dbgTxt03 DB 0B3h,'ECX: '
\r
83 dbgTxt04 DB 0B3h,'EDX: '
\r
84 dbgTxt05 DB 0B3h,'ESI: '
\r
85 dbgTxt06 DB 0B3h,'EDI: '
\r
86 dbgTxt07 DB 0B3h,'EBP: '
\r
87 dbgTxt08 DB 0B3h,' SS: '
\r
88 dbgTxt09 DB 0B3h,'ESP: '
\r
89 dbgTxt10 DB 0B3h,' CS: '
\r
90 dbgTxt11 DB 0B3h,'EIP: '
\r
91 dbgTxt12 DB 0B3h,' DS: '
\r
92 dbgTxt13 DB 0B3h,' ES: '
\r
93 dbgTxt14 DB 0B3h,' FS: '
\r
94 dbgTxt15 DB 0B3h,' GS: '
\r
95 dbgTxt16 DB 0B3h,'EFL: '
\r
96 dbgTxt17 DB 0B3h,'CR0: '
\r
97 dbgTxt18 DB 0B3h,'CR2: '
\r
98 dbgTxt19 DB 0B3h,'CR3: '
\r
99 dbgTxt20 DB 0B3h,'Erc: '
\r
101 dbgTxtAddr DB 'Linear address: '
\r
103 ;For Important Address Info Display
\r
118 ;==================== End Data, Begin Code ==========================
\r
124 EXTRN _disassemble NEAR
\r
125 EXTRN ReadDbgKbd NEAR
\r
129 MOV EAX, OFFSET DbgVidSave ;Save number of vid we interrupted
\r
131 CALL FWORD PTR _GetVidOwner
\r
136 CALL FWORD PTR _SetVidOwner ;Dbgr is Job 2
\r
140 CALL FWORD PTR _ClrScr
\r
145 MOV EAX, DbgpTSSSave
\r
147 ;When a fault or debug exception occurs, the values of
\r
148 ;the Instruction Pointer, Code Seg, and flags are not the
\r
149 ;way they were when the exception fired off becuase of the
\r
150 ;interrupt procedure they enterred to get to the debugger.
\r
151 ;We make them the same by putting the values we got from
\r
152 ;the stack (entering the debugger) into the caller's TSS.
\r
154 MOV EBX,dbgOldEflgs ;Store correct flags
\r
155 MOV [EAX+TSS_EFlags],EBX ;EAX still has DbgpTSSSave
\r
156 MOV EBX,dbgOldCS ;Store correct CS
\r
157 MOV [EAX+TSS_CS],BX
\r
158 MOV EBX,dbgOldEIP ;Store correct EIP
\r
159 MOV [EAX+TSS_EIP],EBX
\r
161 ;NOTE: The "book" says the TF flag is reset by the processor
\r
162 ; when the handler is entered. This only applies if
\r
163 ; the handler is a procedure (NOT a task). The debugger
\r
164 ; is always entered as a procedure, (we chanage the tasks)
\r
165 ; so we shouldn't have to reset it. But we do...
\r
166 ; I guess I'm not reading it right or ROD SERLING LIVES!
\r
168 MOV EBX,[EAX+TSS_EFlags] ;Reset TF in case single steping
\r
170 MOV [EAX+TSS_EFlags],EBX
\r
172 ;We set the FAULT variable based on which interrupt
\r
173 ;procedure was entered.
\r
175 CMP DWORD PTR dbgFAULT,0FFh ;Was the dbgr entered on a FAULT?
\r
178 ;NOTE: Must eventually add SS/ESP for a change in CPL on faults!!!
\r
179 ;REF - See page 3-4 System Software Writer's Guide
\r
182 PUSH EAX ;Display fault message and
\r
183 PUSH EAX ; and number at 0 ,0
\r
184 CALL FWORD PTR _SetXY
\r
189 PUSH 40h ;Color Black on RED
\r
190 CALL FWORD PTR _TTYOut
\r
201 CALL FWORD PTR _TTYOut
\r
202 MOV DWORD PTR dbgFAULT, 0FFh ;reset fault indicator
\r
207 PUSH 07h ;Color White on black
\r
208 CALL FWORD PTR _TTYOut
\r
210 MOV dbgX, EAX ;Reset X & Y to 0,1
\r
214 ;===================================================================
\r
216 CALL DbgRegVid ;Display BackLink's Register values
\r
217 CALL dbgDispMenu ;Display menu
\r
218 PUSH dbgX ;Back to where we were
\r
220 CALL FWORD PTR _SetXY
\r
223 ;Display Instruction at CS:EIP
\r
224 MOV EBX,DbgpTSSSave ;Get USER pUserTSS
\r
225 MOV EAX, [EBX+TSS_EIP]
\r
226 MOV dbgCrntAdd, EAX
\r
229 CALL _disassemble ;This puts the instruction on the line
\r
231 CALL dbgCheckScroll ;Fall through to keyboard loop
\r
233 ;===========================================================
\r
234 ;Now we read the keyboard
\r
236 MOV EAX, OFFSET dbgKeyCode
\r
239 MOV EAX, dbgKeyCode
\r
240 AND EAX, 0FFh ;Lop off key status bytes
\r
242 CMP EAX, 1Bh ;ESCAPE (Exit)
\r
245 CMP EAX, 0Fh ;Single Step (F1)
\r
247 MOV EBX,DbgpTSSSave ;Get USER pUserTSS
\r
248 MOV ECX,[EBX+TSS_EFlags] ;
\r
249 OR ECX,00000100h ;Set TF in flags for single step
\r
250 MOV [EBX+TSS_EFlags],ECX
\r
253 CMP EAX, 10h ;Set BP (Current Address - F2)
\r
255 MOV EBX, dbgCrntAdd ;Address displayed
\r
256 MOV dbgBPAdd, EBX ;Save it so we know where BP is
\r
257 MOV DR0, EBX ;Move into BreakPoint Reg 0
\r
260 MOV EAX, 00000002h ;BP0 Set global
\r
264 CMP EAX, 11h ;Clear BP (Current Address - F3)
\r
267 MOV dbgBPAdd, EAX ;Clear BP saved address
\r
271 CMP EAX, 12h ;Return to CS:EIP (F4)
\r
273 MOV EBX,DbgpTSSSave ;Get USER pUserTSS
\r
274 MOV EAX, [EBX+TSS_EIP]
\r
275 MOV dbgCrntAdd, EAX
\r
278 CALL _disassemble ;This puts the instruction on the line
\r
280 CALL dbgCheckScroll ;See if we need to scroll up
\r
283 CMP EAX, 13h ;Display Exchanges (F5)
\r
286 JMP dbg000 ;Full display
\r
288 CMP EAX, 14h ;Task array display (F6)
\r
293 CMP EAX, 15h ;Not used yet
\r
297 CMP AL, 16h ;Set Disassembly Address (F8)
\r
299 CALL dbgSetAddr ;Sets NextEIP
\r
300 PUSH dbgX ;Back to where we were
\r
302 CALL FWORD PTR _SetXY
\r
304 MOV dbgCrntAdd, EAX
\r
307 CALL _disassemble ;This puts the instruction on the line
\r
309 CALL dbgCheckScroll ;See if we need to scroll up
\r
312 CMP AL, 17h ;Memory Dump Bytes (F9)
\r
319 CMP AL, 18h ;Memory Dump DWORDS (F10)
\r
326 CMP AL, 01Ah ;Info Address dump (F12)
\r
331 dbg13: CMP AL, 02h ;Display next Instruction (Down Arrow)
\r
334 MOV dbgCrntAdd, EAX
\r
337 CALL _disassemble ;This puts the instruction on the line
\r
339 CALL dbgCheckScroll ;See if we need to scroll up
\r
343 JMP dbg00 ;GO back for another key
\r
347 LEA EAX,dbgX ;Query XY
\r
351 CALL FWORD PTR _GetXY
\r
354 CALL FWORD PTR _SetVidOwner ;Change screens back
\r
356 MOV EAX, DbgpTSSSave ;Return saved pRunTSS
\r
359 MOV TSS_Sel, BX ;Set up caller's TSS selector
\r
361 JMP FWORD PTR [TSS]
\r
363 ;Next time we enter the debugger task it will be here!
\r
364 JMP DbgTask ;Back to begining
\r
366 ;==============================================================
\r
369 ;This compares the current breakpoint the address
\r
370 ;we are about to display. If they are the same,
\r
371 ;we put up an asterisk to indicate it's the breakpoint
\r
372 ;EAX must be preserved
\r
374 MOV EBX, dbgCrntAdd ;Address displayed
\r
375 MOV ECX, dbgBPAdd ;BP Address
\r
380 PUSH EAX ;Save EAX across call
\r
381 PUSH OFFSET dbgAsterisk ;3 params to TTYOut
\r
383 PUSH 47h ;Reverse Vid WHITE on RED
\r
384 CALL FWORD PTR _TTYOut
\r
388 ;==============================================================
\r
389 ;This sets up and calls to display all of the regsiter
\r
390 ;information on the right side of the debugger video display
\r
393 MOV EBX,DbgpTSSSave ;EBX MUST be DbgpTSSSave
\r
394 MOV ECX,00 ;TSS Display
\r
395 MOV ESI,OFFSET DbgTxt00
\r
397 MOV AX,[EBX+TSSNum] ;Number of this TSS
\r
400 MOV ECX,01 ;EAX Display
\r
401 MOV ESI,OFFSET DbgTxt01
\r
402 MOV EAX,[EBX+TSS_EAX]
\r
405 MOV ECX,02 ;EBX Display
\r
406 MOV ESI,OFFSET DbgTxt02
\r
407 MOV EAX,[EBX+TSS_EBX]
\r
410 MOV ECX,03 ;ECX Display
\r
411 MOV ESI,OFFSET DbgTxt03
\r
412 MOV EAX,[EBX+TSS_ECX]
\r
415 MOV ECX,04 ;EDX Display
\r
416 MOV ESI,OFFSET DbgTxt04
\r
417 MOV EAX,[EBX+TSS_EDX]
\r
420 MOV ECX,05 ;ESI Display
\r
421 MOV ESI,OFFSET DbgTxt05
\r
422 MOV EAX,[EBX+TSS_ESI]
\r
425 MOV ECX,06 ;EDI Display
\r
426 MOV ESI,OFFSET DbgTxt06
\r
427 MOV EAX,[EBX+TSS_EDI]
\r
430 MOV ECX,07 ;EBP Display
\r
431 MOV ESI,OFFSET DbgTxt07
\r
432 MOV EAX,[EBX+TSS_EBP]
\r
435 MOV ECX,08 ;SS Display
\r
436 MOV ESI,OFFSET DbgTxt08
\r
438 MOV AX,[EBX+TSS_SS]
\r
441 MOV ECX,09 ;ESP Display
\r
442 MOV ESI,OFFSET DbgTxt09
\r
443 MOV EAX,[EBX+TSS_ESP]
\r
446 MOV ECX,10 ;CS Display
\r
447 MOV ESI,OFFSET DbgTxt10
\r
449 MOV AX,[EBX+TSS_CS]
\r
452 MOV ECX,11 ;EIP Display
\r
453 MOV ESI,OFFSET DbgTxt11
\r
454 MOV EAX,[EBX+TSS_EIP]
\r
456 MOV ECX,12 ;DS Display
\r
457 MOV ESI,OFFSET DbgTxt12
\r
459 MOV AX,[EBX+TSS_DS]
\r
461 MOV ECX,13 ;ES Display
\r
462 MOV ESI,OFFSET DbgTxt13
\r
464 MOV AX,[EBX+TSS_ES]
\r
466 MOV ECX,14 ;FS Display
\r
467 MOV ESI,OFFSET DbgTxt14
\r
469 MOV AX,[EBX+TSS_FS]
\r
471 MOV ECX,15 ;GS Display
\r
472 MOV ESI,OFFSET DbgTxt15
\r
474 MOV AX,[EBX+TSS_GS]
\r
476 MOV ECX,16 ;EFlags Display
\r
477 MOV ESI,OFFSET DbgTxt16
\r
478 MOV EAX,[EBX+TSS_EFlags]
\r
480 MOV ECX,17 ;CR0 Display
\r
481 MOV ESI,OFFSET DbgTxt17
\r
484 MOV ECX,18 ;CR2 Display
\r
485 MOV ESI,OFFSET DbgTxt18
\r
488 MOV ECX,19 ;CR3 Display
\r
489 MOV ESI,OFFSET DbgTxt19
\r
492 MOV ECX,20 ;Fault Error Code Display
\r
493 MOV ESI,OFFSET DbgTxt20
\r
497 ;=============================================================================
\r
499 ; This is for Debugger Register display
\r
500 ; Call with: EAX loaded with value to display (from TSS reg)
\r
501 ; ECX loaded with number of text line to display on
\r
502 ; ESI loaded with EA of text line to display
\r
503 ; We save all registers cause the vid calls don't
\r
508 PUSH EAX ;Save number to display
\r
512 CALL FWORD PTR _SetXY
\r
517 CALL FWORD PTR _TTYOut
\r
519 POP EAX ;Get number back for display
\r
528 CALL FWORD PTR _TTYOut
\r
531 ;==============================================
\r
532 ; This displays the debugger function key menu
\r
535 PUSH 0 ;Display Debugger FKey Menu
\r
537 CALL FWORD PTR _SetXY
\r
543 CALL FWORD PTR _TTYOut
\r
547 CALL FWORD PTR _SetXY
\r
553 CALL FWORD PTR _TTYOut
\r
557 CALL FWORD PTR _SetXY
\r
563 CALL FWORD PTR _TTYOut
\r
566 ;===========================
\r
567 ;Allows the user to pick the currently displayed address
\r
570 PUSH 0 ;Goto Query Line
\r
572 CALL FWORD PTR _SetXY
\r
574 LEA EAX, dbgTxtAddr
\r
578 CALL FWORD PTR _TTYOut
\r
583 PUSH EAX ;pEdString
\r
584 PUSH cbBufLen2 ;Crnt size
\r
586 LEA EAX, cbBufLen2 ;
\r
587 PUSH EAX ;ptr to size returned
\r
589 PUSH EAX ;ptr to char returned
\r
590 PUSH 70h ;Black On White
\r
591 CALL FWORD PTR _EditLine ;Ignore error if any
\r
593 MOV AL, dbgChar ;did they exit with CR?
\r
597 LEA EAX, dbgBuf2 ;Convert String to DD
\r
598 PUSH EAX ;ptr to string
\r
599 LEA EAX, dbgNextAdd
\r
600 PUSH EAX ;ptr to destination DD
\r
601 PUSH cbBufLen2 ;length of string
\r
602 CALL HexToDD ;dbgDumpAdd has address to dump!
\r
606 MOV EAX, dbgNextAdd
\r
611 ;===========================
\r
612 ;Queries user for address then dumps data to screen
\r
615 PUSH 0 ;Goto Query Line
\r
617 CALL FWORD PTR _SetXY
\r
619 LEA EAX, dbgTxtAddr
\r
623 CALL FWORD PTR _TTYOut
\r
628 PUSH EAX ;pEdString
\r
629 PUSH cbBufLen2 ;Crnt size
\r
631 LEA EAX, cbBufLen2 ;
\r
632 PUSH EAX ;ptr to size returned
\r
634 PUSH EAX ;ptr to char returned
\r
635 PUSH 70h ;Black On White
\r
636 CALL FWORD PTR _EditLine ;Ignore error if any
\r
638 MOV AL, dbgChar ;did they exit with CR?
\r
645 LEA EAX, dbgBuf2 ;Convert String to DD
\r
646 PUSH EAX ;ptr to string
\r
647 LEA EAX, dbgDumpAdd
\r
648 PUSH EAX ;ptr to destination DD
\r
649 PUSH cbBufLen2 ;length of string
\r
650 CALL HexToDD ;dbgDumpAdd has address to dump!
\r
654 CALL FWORD PTR _ClrScr
\r
657 MOV DWORD PTR dbgGPdd1, 24 ;line counter begins at 24
\r
659 MOV DWORD PTR dbgGPdd3, 4 ;number of quads per line
\r
660 PUSH dbgDumpAdd ;convert address to text
\r
669 CALL FWORD PTR _TTYOut
\r
673 MOV DWORD PTR dbgGPdd2, 6 ;byte offset begins at 6
\r
678 CALL FWORD PTR _TTYOut
\r
681 MOV EBX, dbgDumpAdd ;get dump address
\r
682 MOV EAX, [EBX] ;Get what it's pointing to
\r
683 PUSH EAX ;make it a DD Text
\r
687 MOV AL, dbgfDumpD ;Dumping DWORDS
\r
689 JE DumpB ;NO - go to display bytes
\r
691 LEA EAX, dbgBuf ;Yes display Quad
\r
695 CALL FWORD PTR _TTYOut
\r
699 LEA EAX, dbgBuf ;Display First byte
\r
704 CALL FWORD PTR _TTYOut ;ignore error
\r
706 LEA EAX, dbgSpace ;Display 1 spaces
\r
710 CALL FWORD PTR _TTYOut
\r
711 DEC dbgGPdd2 ;point to second 2 bytes
\r
714 LEA EAX, dbgBuf ;display 2st byte
\r
719 CALL FWORD PTR _TTYOut ;ignore error
\r
721 LEA EAX, dbgSpace ; display 1 space
\r
725 CALL FWORD PTR _TTYOut
\r
730 LEA EAX, dbgBuf ;display 3rd byte
\r
735 CALL FWORD PTR _TTYOut ;ignore error
\r
737 LEA EAX, dbgSpace ;a space
\r
741 CALL FWORD PTR _TTYOut
\r
745 LEA EAX, dbgBuf ;display 4th byte
\r
750 CALL FWORD PTR _TTYOut ;ignore error
\r
756 DEC dbgGPdd3 ;done with 4 quads??
\r
757 JNZ dbgDump02 ;NO - go back for next 4 bytes
\r
759 LEA EAX, dbgSpace ;Yes - Display 2 spaces
\r
763 CALL FWORD PTR _TTYOut
\r
765 LEA EAX,dbgX ;Query XY
\r
769 CALL FWORD PTR _GetXY
\r
771 PUSH dbgX ;Put 16 TEXT chars on right
\r
773 MOV EAX, dbgDumpAdd
\r
778 CALL FWORD PTR _PutVidChars ;ignore error
\r
780 LEA EAX, dbgCRLF ;Do CR/LF
\r
784 CALL FWORD PTR _TTYOut
\r
786 DEC dbgGPdd1 ;23lines yet??
\r
789 LEA EAX, dbgCont ;"Continue" Text
\r
791 PUSH 31 ;size of "cont text"
\r
793 CALL FWORD PTR _TTYOut
\r
795 MOV EAX, OFFSET dbgKeyCode
\r
798 MOV EAX, dbgKeyCode
\r
799 AND EAX, 0FFh ;Lop off key status bytes
\r
802 CMP EAX, 1Bh ;Escape (Quit??)
\r
805 LEA EAX, dbgCRLF ;Do CR/LF
\r
809 CALL FWORD PTR _TTYOut
\r
814 CALL FWORD PTR _ClrScr
\r
815 MOV DWORD PTR dbgX, 0
\r
816 MOV DWORD PTR dbgY, 0
\r
818 ;===========================
\r
820 ;Displays exchanges that are allocated along with
\r
821 ;messages or tasks that may be wiating at them
\r
825 MOV DWORD PTR dbgGPdd2, 0 ;Exch# we are on
\r
827 CALL FWORD PTR _ClrScr
\r
829 PUSH 0 ;Line for labels
\r
830 PUSH OFFSET dbgExchMsg ;
\r
831 PUSH 54 ;Length of message
\r
833 CALL FWORD PTR _PutVidChars ;
\r
834 MOV DWORD PTR dbgGPdd1, 1 ;line we are one
\r
836 ;First we do the exchange on the current line
\r
838 PUSH dbgGPdd2 ;Convert Exch number for display
\r
843 PUSH dbgGPdd1 ;Line we are one
\r
844 PUSH OFFSET dbgBuf ;ExchNum
\r
847 CALL FWORD PTR _PutVidChars ;
\r
849 ;Then we do the Exch Owner (Job Number) next to it
\r
851 MOV EAX, dbgGPdd2 ; Exch number
\r
852 MOV EDX, sEXCH ; Compute offset of Exch in rgExch
\r
854 MOV EDX,prgExch ; Add offset of rgExch => EAX
\r
855 ADD EAX,EDX ; EAX now pts to Exch
\r
856 MOV dbgGPdd3, EAX ; pExch into save variable
\r
857 MOV EBX, [EAX+Owner] ; pJCB of Owner into EBX
\r
858 XOR EAX, EAX ; Clear for use as JobNum
\r
859 OR EBX, EBX ; pNIL? (No owner if so)
\r
861 MOV EAX, [EBX+JobNum] ;
\r
863 PUSH EAX ;Convert Job Number
\r
868 PUSH dbgGPdd1 ;Line
\r
869 PUSH OFFSET dbgBuf ;
\r
872 CALL FWORD PTR _PutVidChars ;
\r
874 MOV dbgGPdd5, 0 ;Set pNextMsg to 0
\r
876 ;See if there is a first message
\r
878 MOV EAX, dbgGPdd3 ;pExch -> EAX
\r
879 MOV EBX, [EAX+EHead] ;pMsg -> EBX
\r
880 OR EBX, EBX ;Is is NIL (no msg or task)?
\r
881 JZ dbgDE13 ;Yes. Go to next Exch
\r
883 MOV EBX, [EAX+fEMsg] ;MsgFlag -> EBX
\r
884 OR EBX, EBX ;Is is 1 (a message)?
\r
885 JZ dbgDE05 ;No, Go check for tasks
\r
886 MOV EBX, [EAX+EHead] ;pMsg -> EBX
\r
890 MOV DWORD PTR dbgGPdd6, 0 ;Flag to indicate we are doing messages
\r
891 MOV EAX, [EBX+NextLB] ;For next msg in chain (if it exists)
\r
892 MOV dbgGPdd5, EAX ;Save for loop
\r
893 MOV EAX, [EBX+DataHi] ;Get dMsg1
\r
894 MOV EDX, [EBX+DataLo] ;Get dMsg2
\r
895 PUSH EDX ;Save dMsg2
\r
897 PUSH EAX ;Convert dMsg1
\r
902 PUSH dbgGPdd1 ;Line
\r
903 PUSH OFFSET dbgBuf ;
\r
906 CALL FWORD PTR _PutVidChars ;
\r
908 POP EDX ;Get dMsg2 back
\r
910 ;Could have left it on stack, but would be confusing later...
\r
911 ;"simplicity of maintenance is as important as simplicity of design"
\r
913 PUSH EDX ;Convert dMsg2
\r
918 PUSH dbgGPdd1 ;Line
\r
919 PUSH OFFSET dbgBuf ;
\r
922 CALL FWORD PTR _PutVidChars ;
\r
923 JMP dbgDE07 ;Next line please
\r
925 ;See if there are tasks waiting
\r
927 MOV DWORD PTR dbgGPdd6, 1 ;Flag to indicate we are doing tasks
\r
928 MOV DWORD PTR dbgGPdd5, 0 ;Clear pNextTask
\r
929 MOV EAX, dbgGPdd3 ;pExch -> EAX
\r
930 MOV EBX, [EAX+EHead] ;pTSS -> EBX
\r
931 OR EBX, EBX ;Is is 0 (no TSS)?
\r
934 MOV EAX, [EBX+NextTSS]
\r
935 MOV dbgGPdd5, EAX ;Save ptr to next task if it exists
\r
937 MOV AX, [EBX+TSSNum] ;Get Number of Task at exch
\r
939 PUSH EAX ;Convert Task Number
\r
944 PUSH dbgGPdd1 ;Line
\r
945 PUSH OFFSET dbgBuf ;
\r
948 CALL FWORD PTR _PutVidChars ;
\r
951 INC dbgGPdd1 ;Next line
\r
952 CMP DWORD PTR dbgGPdd1, 23 ;23 lines yet?
\r
958 PUSH OFFSET dbgCont ;
\r
959 PUSH 31 ;length of Cont string
\r
961 CALL FWORD PTR _PutVidChars ;
\r
963 MOV EAX, OFFSET dbgKeyCode
\r
966 MOV EAX, dbgKeyCode
\r
967 AND EAX, 0FFh ;Lop off key status bytes
\r
968 CMP EAX, 1Bh ;Escape (Quit??)
\r
971 CMP DWORD PTR dbgGPdd2, nDynEXCH ; Number of dynamic exchanges
\r
972 JAE dbgDEDone ; All Exchs displayed
\r
974 CALL FWORD PTR _ClrScr ;
\r
976 PUSH 0 ;Line for labels
\r
977 PUSH OFFSET dbgExchMsg ;
\r
978 PUSH 54 ;Length of message
\r
980 CALL FWORD PTR _PutVidChars ;
\r
981 MOV DWORD PTR dbgGPdd1, 1 ;line. We are on line 1 again
\r
984 MOV EBX, dbgGPdd5 ;Set up to loop for next msg/task
\r
985 XOR EBX, EBX ;Another pointer in the link?
\r
987 MOV EAX, dbgGPdd6 ;
\r
988 OR EAX, EAX ;NonZero if we are doing tasks
\r
990 JMP dbgDE04 ;Messages
\r
992 INC dbgGPdd2 ; Exch number
\r
993 CMP DWORD PTR dbgGPdd2, nDynEXCH ; Number of dynamic exchanges
\r
994 JAE dbgDE08 ; Go back for prompt (to pause)
\r
995 JMP dbgDE01 ; Back to display new exch num
\r
997 CALL FWORD PTR _ClrScr
\r
998 MOV DWORD PTR dbgX, 0
\r
999 MOV DWORD PTR dbgY, 0
\r
1002 ;===========================
\r
1003 ;Displays Tasks that are active along with
\r
1004 ;pertinent address info about them
\r
1007 MOV DWORD PTR dbgGPdd2, 1 ;Task# we are on
\r
1009 CALL FWORD PTR _ClrScr
\r
1011 PUSH 0 ;Line for labels
\r
1012 PUSH OFFSET dbgTaskMsg ;
\r
1013 PUSH 54 ;Length of message
\r
1015 CALL FWORD PTR _PutVidChars ;
\r
1016 MOV DWORD PTR dbgGPdd1, 1 ;line we are one
\r
1018 ;First we get pTSS and see if it is valid
\r
1019 ;If so, we get all the data BEFORE we display it
\r
1020 ;If not, we increment TSS number and go back
\r
1023 ;We get pJCB out of TSS and get JobNum from JCB
\r
1025 MOV EAX, dbgGPdd2 ; Task number
\r
1026 CMP EAX, 1 ; Is this TSS 1 (Static memory)
\r
1028 MOV EBX, OFFSET MonTSS ;
\r
1031 CMP EAX, 2 ; Is this TSS 2 (Static memory)
\r
1033 MOV EBX, OFFSET DbgTSS ;
\r
1037 DEC EAX ;Make TSS Num offset in dynamic array
\r
1042 ADD EBX, EAX ;EBX points to TSS!
\r
1044 ;EBX has pTSS of interest
\r
1045 MOV dbgGPdd5, EBX ;Save pTSS for display
\r
1047 MOV CL, [EBX+Priority] ;Priotity of this task
\r
1049 MOV EAX, [EBX+TSS_pJCB] ;EAX has pJCB
\r
1050 OR EAX, EAX ;NON zero means it's valid
\r
1052 MOV EAX, dbgGPdd2 ;Not used, go for next Task number
\r
1057 JMP SHORT dbgDT01 ;back for next one
\r
1060 MOV dbgGPdd4, EAX ;Save pJCB for display
\r
1061 MOV EBX, [EAX] ;Job number is first DD in JCB
\r
1064 PUSH dbgGPdd2 ;Convert TSS number for display
\r
1065 PUSH OFFSET dbgBuf
\r
1068 PUSH dbgGPdd1 ;Line we are one
\r
1069 PUSH OFFSET dbgBuf ;TaskNum
\r
1072 CALL FWORD PTR _PutVidChars ;
\r
1074 PUSH dbgGPdd3 ;Convert and display Job number
\r
1075 PUSH OFFSET dbgBuf ;
\r
1078 PUSH dbgGPdd1 ;Line we are one
\r
1079 PUSH OFFSET dbgBuf ;
\r
1082 CALL FWORD PTR _PutVidChars ;
\r
1084 PUSH dbgGPdd4 ;Convert and display pJCB
\r
1085 PUSH OFFSET dbgBuf ;
\r
1088 PUSH dbgGPdd1 ;Line we are one
\r
1089 PUSH OFFSET dbgBuf ;
\r
1092 CALL FWORD PTR _PutVidChars ;
\r
1094 PUSH dbgGPdd5 ;Convert and display pTSS
\r
1095 PUSH OFFSET dbgBuf ;
\r
1098 PUSH dbgGPdd1 ;Line we are one
\r
1099 PUSH OFFSET dbgBuf ;
\r
1102 CALL FWORD PTR _PutVidChars ;
\r
1104 PUSH dbgGPdd6 ;Convert and display Priority
\r
1105 PUSH OFFSET dbgBuf ;
\r
1108 PUSH dbgGPdd1 ;Line we are one
\r
1109 PUSH OFFSET dbgBuf ;
\r
1112 CALL FWORD PTR _PutVidChars ;
\r
1114 MOV EAX, dbgGPdd2 ;go for next Task number
\r
1118 MOV dbgGPdd2, EAX ;Save it for the top
\r
1120 INC dbgGPdd1 ;Next line
\r
1121 CMP DWORD PTR dbgGPdd1, 23 ;23 lines yet?
\r
1122 JAE dbgDT06 ;Yes, continue prompt
\r
1123 JMP dbgDT01 ;No, go back for next
\r
1127 PUSH OFFSET dbgCont ;
\r
1128 PUSH 31 ;length of Cont string
\r
1130 CALL FWORD PTR _PutVidChars ;
\r
1132 MOV EAX, OFFSET dbgKeyCode
\r
1135 MOV EAX, dbgKeyCode
\r
1136 AND EAX, 0FFh ;Lop off key status bytes
\r
1137 CMP EAX, 1Bh ;Escape (Quit??)
\r
1139 JMP dbgDT00 ;Back for next screen
\r
1141 CALL FWORD PTR _ClrScr
\r
1142 MOV DWORD PTR dbgX, 0
\r
1143 MOV DWORD PTR dbgY, 0
\r
1146 ;=============================================================================
\r
1147 ; This is for Debugger Address Info display
\r
1149 ; EAX loaded with address to display (Linear Address)
\r
1150 ; ESI loaded with EA of text line to display
\r
1151 ; We save all registers cause the vid calls don't
\r
1152 ;=============================================================================
\r
1155 PUSH EAX ;Save number to display
\r
1157 PUSH ESI ;ptr to line
\r
1158 PUSH 06h ;Length of line
\r
1159 PUSH 07h ;Vid Attribute
\r
1160 CALL FWORD PTR _TTYOut ;Do it
\r
1162 POP EAX ;Get number back for display
\r
1165 PUSH OFFSET dbgBuf
\r
1168 PUSH OFFSET dbgBuf
\r
1171 CALL FWORD PTR _TTYOut
\r
1173 PUSH OFFSET dbgCRLF
\r
1176 CALL FWORD PTR _TTYOut
\r
1178 CALL dbgCheckScroll
\r
1182 ;===============================================
\r
1183 ;DbgInfo - Displays important linear address for the OS
\r
1186 MOV ESI,OFFSET DbgM0 ;IDT
\r
1189 MOV ESI,OFFSET DbgM1 ;GDT
\r
1192 MOV ESI,OFFSET DbgM2 ;RQBs
\r
1195 MOV ESI,OFFSET DbgM3 ;MonTSS
\r
1196 MOV EAX, OFFSET MonTSS
\r
1198 MOV ESI,OFFSET DbgM4 ;pTSS3
\r
1201 MOV ESI,OFFSET DbgM5 ;LBs
\r
1204 MOV ESI,OFFSET DbgM6 ;RdyQ
\r
1207 MOV ESI,OFFSET DbgM7 ;JCBs
\r
1210 MOV ESI,OFFSET DbgM8 ;SVCs
\r
1213 MOV ESI,OFFSET DbgM9 ;Exchs
\r
1216 MOV ESI,OFFSET DbgPA ;PAM (Page Allocation map)
\r
1219 MOV ESI,OFFSET DbgMB ;Timer Blocks
\r
1220 LEA EAX, rgTmrBlks
\r
1224 ;=======================================================
\r
1225 ;All of the debugger text is displayed in a window
\r
1226 ;between colums 0 and 66, and line 0 to 24. The other
\r
1227 ;areas are resrved for the menu, query line,
\r
1228 ;and the register display.
\r
1229 ;This checks to see if the cursor is on line 23.
\r
1230 ;If so, we scroll up the text area by one line.
\r
1233 LEA EAX,dbgX ;Query XY (See what line and Col)
\r
1237 CALL FWORD PTR _GetXY
\r
1238 CMP DWORD PTR dbgY, 23 ;Are we at bottom (just above menu)??
\r
1239 JB dbgNoScroll ;No, go back for next key
\r
1241 PUSH 0 ;Yes, Scroll test area (Col 0-64, Line 0-24)
\r
1243 PUSH 66 ;Columns 0-65
\r
1244 PUSH 24 ;Lines 0-23
\r
1246 CALL FWORD PTR _ScrollVid
\r
1248 PUSH 0 ;Got to Column 0, Line 22
\r
1250 CALL FWORD PTR _SetXY
\r
1254 ;=======================================================
\r
1255 ;Clear the query line (Line 23, 40 chars)
\r
1258 PUSH 0 ;Col 0, Line 23
\r
1260 PUSH OFFSET dbgClear
\r
1263 CALL FWORD PTR _PutVidChars ;ignore error
\r
1266 ;===================== module end ======================
\r