home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / ddjmag / ddj9209.zip / WIN386.ASC < prev    next >
Text File  |  1992-08-10  |  31KB  |  964 lines

  1. _AN EXCEPTION HANDLER FOR WINDOWS 3_
  2. by Brett Salter
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7. ; winx.asm - exception handler for windows 3.x
  8. .386p               ; 386 protect mode
  9. wincs equ 28h           ; windows ring 0 cs
  10. winds equ 30h           ; windows ring 0 ds
  11.     include psequate.inc    ; general Periscope equates
  12.     include dosmgr.inc  ; all of these
  13.     include shell.inc   ; are from the
  14.     include vdd.inc     ; windows ddk
  15.     include vmm.inc     ; ...
  16.     include vpicd.inc   ; ...
  17.     ; device descriptor block
  18. Declare_Virtual_Device WINX, 3, 0, VAD_Control, Undefined_Device_ID, VMM_Init_Order \ , , VAD_PM_Svc_Call
  19. ; ****************************************************************************
  20. VxD_Locked_Data_Seg     ; data segment
  21. datastart equ $         ; symbol for start of data
  22.     ; global data follows
  23. psport  dw 0            ; Periscope Model IV port number
  24. currow  db 0            ; cursor row (0-24)
  25. curcol  db 0            ; cursor column (0-79)
  26. showregs db 0           ; 1 when we have something to show
  27. usemono db 0            ; 1 when output to mono screen
  28. monosave db 0           ; 1 when saving mono screen
  29. winmsg  db 1            ; 1 when output to windows screen
  30.  
  31. even
  32. hextable db '0123456789ABCDEF'  ; hex conversion table
  33. even                ; gdt/idt/ldt data
  34. gdtlimit    dw 0        ; global descriptor table limit
  35. gdtbase     dd 0        ; and base
  36. idtlimit    dw 0        ; interrupt descriptor table limit
  37. idtbase     dd 0        ; and base
  38. ldtvalue    dw 0        ; value of local descriptor table
  39. ldtlimit    dw 0        ; and limit
  40. tssvalue    dw 0        ; value of task state selector
  41.         ; original interrupt values
  42. origint6    df 0        ; illegal opcode
  43. origint8    df 0        ; double fault
  44. originta    df 0        ; invalid tss
  45. origintb    df 0        ; segment not present
  46. origintc    df 0        ; stack fault
  47. origintd    df 0        ; general protection fault
  48. originte    df 0        ; page fault
  49. origirq1    df 0        ; original keyboard interrupt
  50. align 4
  51. jumptable   dd offset32 p206,offset32 origint6  ; control table
  52.         dd 0,0      ; dummy for interrupt 7
  53.         dd offset32 p208,offset32 origint8
  54.         dd 0,0      ; dummy for interrupt 9
  55.         dd offset32 p20a,offset32 originta
  56.         dd offset32 p20b,offset32 origintb
  57.         dd offset32 p20c,offset32 origintc
  58.         dd offset32 p20d,offset32 origintd
  59.         dd offset32 p20e,offset32 originte
  60. intlistlen  equ 9       ; number of interrupts in above list
  61. intlist     db '060708090a0b0c0d0e' ; list of 9 exception vecs
  62.     ; keep the following together
  63. hookint06   db 1        ; all but interrupts 7 and 9
  64. hookint07   db 0        ; get hooked by default
  65. hookint08   db 1
  66. hookint09   db 0
  67. hookint0a   db 1
  68. hookint0b   db 1
  69. hookint0c   db 1
  70. hookint0d   db 1
  71. hookint0e   db 1
  72.     ; end of keep together
  73. intgate     dw 0ee00h   ; value for interrupt gate, dpl=3
  74. keystrokes  dw 0        ; keystroke count
  75. errorcode   dd 0        ; error code on interrupts 8 and higher
  76. inttype     dw 0        ; interrupt type
  77. exitaddr    df 0        ; original interrupt address as 16:32 ptr
  78. align 4
  79.     ; original registers
  80. saveeax dd 0            ; original eax
  81. saveebx dd 0            ; original ebx
  82. saveecx dd 0            ; original ecx
  83. saveedx dd 0            ; original edx
  84. saveesp dd 0            ; original esp
  85. saveebp dd 0            ; original ebp
  86. saveesi dd 0            ; original esi
  87. saveedi dd 0            ; original edi
  88. saveeip dd 0            ; original eip
  89. saveefl dd 0            ; original eflags
  90. saveds  dw 0            ; original ds
  91. savees  dw 0            ; original es 
  92. savess  dw 0            ; original ss
  93. savecs  dw 0            ; original cs
  94. savefs  dw 0            ; original fs
  95. savegs  dw 0            ; original gs
  96.     ; instruction prefixes - these opcodes are ignored
  97.     ; when searching for the start of an instruction
  98. prelist db 026h,02eh,036h,03eh,064h,065h,066h,067h,0f0h,0f2h,0f3h
  99. prelistlen dd 11
  100.     ; legal opcodes for int b - pass these on thru to the original handler
  101. intblist db 0fh             ; improve later to catch only 
  102.                     ; 0f/b2, 0f/b4, 0f/b5
  103.     db 063h             ; arpl
  104.     db 09ah             ; far call
  105.     db 0c4h,0c5h            ; les/lds ... used by visual basic
  106.     db 0cah,0cbh            ; retf
  107.     db 0eah             ; far jmp
  108.     db 0f4h             ; hlt
  109.     db 0fah,0fbh            ; cli/sti
  110.     db 0ffh             ; various
  111. intblistlen dd 12
  112.     ; legal opcodes for int d - pass these on thru to the original handler
  113. intdlist  db 06ch,06dh,06eh,06fh    ; in/out
  114.     db 09ah             ; far call
  115.     db 09ch             ; pushf
  116.     db 09dh             ; popf
  117.     db 0cch,0cdh,0ceh       ; int x
  118.     db 0cfh             ; iret
  119.     db 0e4h,0e5h,0e6h,0e7h      ; in/out
  120.     db 0ech,0edh,0eeh,0efh      ; in/out
  121.     db 0f4h             ; hlt
  122.     db 0fah,0fbh            ; cli/sti
  123. intdlistlen dd 22
  124. even
  125. opcode db 8 dup(0)      ; save the opcode bytes here
  126. opcodecs dw 0           ; cs for opcodes
  127. opcodeeip dd 0          ; eip for opcodes
  128. explcount equ 7         ; number of interrupt descriptions
  129. expllen equ 20          ; length of each interrupt description
  130. explanations equ $      ; 1 byte for type, 20 bytes for text
  131. db 06h,'Invalid opcode      '
  132. db 08h,'Double fault        '
  133. db 0ah,'Invalid TSS         '
  134. db 0bh,'Segment not present '
  135. db 0ch,'Stack exception     '
  136. db 0dh,'General protection  '
  137. db 0eh,'Page fault          '
  138. modep   db 'Protect'        ; mode can be Protect or V86 only - we'll
  139. modev86 db 'V86    '        ; never seel Real mode here
  140.             ; start of display area
  141. regline1 db cr,lf,'Interrupt '
  142. xinttype db '..h - '
  143. xexplain db '....................'
  144.         db '  Mode='
  145. xmode   db '.......  Ring='
  146. xring   db '.'
  147.     db cr,lf
  148. regline2 db 'Error code='
  149. errorno db '0000 0000       Opcodes='
  150. xopcode db '.. .. .. .. .. .. .. ..'
  151.     db cr,lf
  152.     db cr,lf
  153. regline3 db 'eax='
  154. regeax  db '.... ....  '
  155.     db 'ebx='
  156. regebx  db '.... ....  '
  157.     db 'ecx='
  158. regecx  db '.... ....  '
  159.     db 'edx='
  160. regedx  db '.... ....'
  161.     db cr,lf
  162. regline4 db 'ebp='
  163. regebp  db '.... ....  '
  164.     db 'efl='
  165. regefl  db '.... ....  '
  166.     db ' fs='
  167. regfs   db '....       '
  168.     db ' gs='
  169. reggs   db '....'
  170.     db cr,lf
  171. regline5 db 'eip='
  172. regeip  db '.... ....  '
  173.         db 'esp='
  174. regesp  db '.... ....  '
  175.     db 'esi='
  176. regesi  db '.... ....  '
  177.     db 'edi='
  178. regedi  db '.... ....'
  179.     db cr,lf
  180. regline6 db 'cs='
  181. regcs   db '....       '
  182.         db ' ss='
  183. regss   db '....       '
  184.     db ' ds='
  185. regds   db '....       '
  186.     db ' es='
  187. reges   db '....'
  188.     db cr,lf
  189.     db cr,lf
  190. regline7 db 'cr0=' 
  191. regcr0  db '.... ....  '
  192.     db 'cr2='
  193. regcr2  db '.... ....  '
  194.     db 'cr3='
  195. regcr3  db '.... ....'
  196.     db cr,lf
  197. regline8 db 'gdt='
  198. gdtb db '.... ..../'
  199. gdtl db '....  '
  200.     db 'ldt='
  201. ldtw    db '....  '
  202.     db 'idt='
  203. idtb db '.... ..../'
  204. idtl db '....  '
  205.     db 'tss='
  206. tssw    db '....'
  207.     db cr,lf
  208. regend  db 0,'$'
  209.                 ; end of display area
  210.     ; messages
  211. pause   db 'Press a key to continue ...',0
  212. crlf    db cr,lf,0
  213. periscopeid db 'WINX (Windows Exception Handler)'
  214.     db 0
  215. align 4 
  216. monoscreen dw 80*25 dup(0)  ; save the mono screen here
  217. VxD_Locked_Data_Ends        ; end of data segment
  218. ; ****************************************************************************
  219. VxD_Locked_Code_Seg     ; code segment
  220. codestart equ $         ; symbol for start of code
  221.     ; device control procedure 
  222. VAD_Control proc near       ; control table
  223.     Control_Dispatch Sys_Critical_Init, VAD_Sys_Crit_Init ; phase 1
  224.     Control_Dispatch Device_Init,       VAD_Device_Init   ; phase 2
  225.     Control_Dispatch Init_Complete,     VAD_Init_Complete ; phase 3
  226.     Control_Dispatch Create_VM,     VAD_Create_VM
  227.     clc         ; no errors
  228.     ret
  229. VAD_Control endp
  230. beginproc VAD_Get_Version, SERVICE
  231.     mov eax,300h
  232.     clc         ; no errors
  233.     ret
  234. endproc VAD_Get_Version
  235. VAD_PM_Svc_Call proc near
  236.     ret
  237. VAD_PM_Svc_Call endp
  238. align 4
  239. p006    proc near       ; int 6 handler
  240.     push eax
  241.     mov al,6
  242.     jmp short p020      ; to handler
  243. p006    endp
  244. align 4
  245. p008    proc near       ; int 8 handler
  246.     push eax
  247.     mov al,8
  248.     jmp short p020      ; to handler
  249. p008    endp
  250. align 4
  251. p00a    proc near       ; int a handler
  252.     push eax
  253.     mov al,0ah
  254.     jmp short p020      ; to handler
  255. p00a    endp
  256. align 4
  257. p00b    proc near       ; int b handler
  258.     push eax
  259.     mov al,0bh
  260.     jmp short p020      ; to handler
  261. p00b    endp
  262. align 4
  263. p00c    proc near       ; int c handler
  264.     push eax
  265.     mov al,0ch
  266.     jmp short p020      ; to handler
  267. p00c    endp
  268. align 4
  269. p00d    proc near       ; int d handler
  270.     push eax
  271.     mov al,0dh
  272.     jmp short p020      ; to handler
  273. p00d    endp
  274. align 4
  275. p00e    proc near       ; int e handler
  276.     push eax
  277.     mov al,0eh
  278.     jmp short p020      ; to handler
  279. p00e    endp
  280. align 4
  281. p013    proc near       ; irq 1 handler
  282.     ; this routine hooks the keyboard; it is used only to count
  283.     ; the number of keystrokes coming through
  284.     @save eax,ds        
  285.     mov ax,winds
  286.     mov ds,ax
  287.     inc keystrokes      ; count keystrokes
  288.     @restore
  289.     jmp cs:[origirq1]   ; pass control onto prior handler
  290. p013    endp
  291. align 4
  292. p020    proc near       ; exception handler
  293.     ; this is the common entry point for all exception handlers
  294.     push ds         ; save registers
  295.     push es
  296.     push ebp
  297.     cld         ; up!
  298.     push eax
  299.     mov ax,winds
  300.     mov ds,ax       ; set ds to windows ring 0 ds
  301.     pop eax
  302.     mov ah,0
  303.     mov inttype,ax      ; save interrupt type
  304.     mov ebp,esp     ; save registers
  305.     mov eax,[ebp]       ; 0=ebp,4=es,8=ds,12=eax,16=error/eip
  306.     mov saveebp,eax     ; save ebp
  307.     mov ax,[ebp+4]      ; get es from stack
  308.     mov savees,ax       ; save es
  309.     mov ax,[ebp+8]      ; get ds from stack
  310.     mov saveds,ax       ; save ds
  311.     mov eax,[ebp+12]    ; get eax from stack
  312.     mov saveeax,eax     ; save eax
  313.     mov saveebx,ebx     ; save ebx
  314.     mov saveecx,ecx     ; save ecx
  315.     mov saveedx,edx     ; save edx
  316.     mov saveesi,esi     ; save esi
  317.     mov saveedi,edi     ; save edi
  318.     mov savefs,fs       ; save fs
  319.     mov savegs,gs       ; save gs
  320.     mov ebp,esp
  321.     add ebp,16      ; point to eip/error
  322.     mov errorcode,0     ; clear error code
  323.     cmp inttype,8       ; error code?
  324.     jb short p020a      ; no
  325.     mov eax,[ebp]       ; get error code
  326.     mov errorcode,eax   ; save error code
  327.     add ebp,4       
  328. p020a:  mov eax,[ebp]       ; get eip from stack
  329.     mov saveeip,eax     ; save eip
  330.     mov ax,[ebp+4]      ; get cs from stack
  331.     mov savecs,ax       ; save cs
  332.     mov eax,[ebp+8]     ; get flags from stack
  333.     mov saveefl,eax     ; save flags
  334.     mov savess,ss
  335.     mov eax,ebp     ; get sp
  336.     add eax,12      ; skip eip, cs, & flags
  337.     mov saveesp,eax     ; save esp
  338.     test saveefl,bit17on    ; v86 mode?
  339.     jnz short p020d     ; yes
  340.     test savecs,3       ; ring 0 cs?
  341.     jz short p020b      ; yes
  342. p020d:
  343.     mov eax,[ebp+12]    ; get esp from stack
  344.     mov saveesp,eax     ; save esp
  345.     mov ax,[ebp+16]     ; get ss from stack
  346.     mov savess,ax       ; save ss
  347.     test saveefl,bit17on    ; v86 mode?
  348.     jz short p020b      ; no
  349.     mov ax,[ebp+20]     ; get es from stack
  350.     mov savees,ax       ; save es
  351.     mov ax,[ebp+24]     ; get ds from stack
  352.     mov saveds,ax       ; save ds
  353.     mov ax,[ebp+28]     ; get fs from stack
  354.     mov savefs,ax       ; save fs
  355.     mov ax,[ebp+32]     ; get gs from stack
  356.     mov savegs,ax       ; save gs
  357. p020b:  pushad          ; a bit redundant, but it's small
  358.     call p200       ; check exceptions
  359.     jnc short p020x     ; ok - skip display
  360.     mov dx,psport       ; get Periscope port
  361.     cmp dx,0        ; valid?
  362.     jz short p020c      ; no
  363.     mov al,0dbh
  364.     out dx,al       ; stop Periscope Model IV trace
  365. p020c:  call p950       ; display registers
  366.     mov showregs,1      ; indicate we have something to show
  367. p020x:  popad           ; pop all registers
  368.     pop ebp
  369.     pop es
  370.     pop ds
  371.     pop eax
  372.     jmp fword ptr cs:[exitaddr] ; pass control on to original handler
  373. p020    endp
  374. align 4
  375. p200    proc near       ; check exceptions
  376.     mov ax,ds
  377.     mov es,ax       ; es=ds
  378.     movzx eax,inttype   ; get interrupt type
  379.     sub eax,6       ; table starts at int 6
  380.     shl eax,3       ; times 8
  381.     mov esi,[jumptable+eax+4]
  382.     mov edi,offset32 exitaddr
  383.     movsw
  384.     movsd           ; copy original int to exitaddr
  385.     jmp [jumptable+eax]     ; handle the interrupt
  386. p200    endp
  387. align 4
  388. p206    proc near       ; handle int 6 - illegal instruction
  389.     call p220       ; get opcode in al
  390.     cmp al,63h      ; arpl instruction? (ms patented technique!)
  391.     jz short p206n      ; yes - don't show registers 
  392.     mov ax,word ptr opcode
  393.     cmp ax,0ff0fh       ; 0f ff opcode? (ms special case)
  394.     jz short p206n      ; yes - don't show registers 
  395.     stc         ; show registers
  396.     ret
  397. p206n:  clc         ; don't show registers
  398.     ret
  399. p206    endp
  400. align 4
  401. p208    proc near       ; handle int 8 - double fault
  402.     stc         ; show registers on all int 8
  403.     ret
  404. p208    endp
  405. align 4
  406. p20a    proc near       ; handle int a - invalid tss
  407.     stc         ; show registers on all int a
  408.     ret
  409. p20a    endp
  410. align 4
  411. p20b    proc near       ; handle int b - segment not present
  412.     test saveefl,bit17on    ; v86 mode?
  413.     jnz short p20bs     ; yes - show registers
  414.     call p220       ; get opcode in al
  415.     mov edi,offset32 intblist
  416.     mov ecx,intblistlen
  417.     repnz scasb     ; search for opcode
  418.     jnz short p20bs     ; no match
  419. p20bn:  clc         ; don't show registers
  420.     ret
  421. p20bs:  stc         ; show registers
  422.     ret
  423. p20b    endp
  424. align 4
  425. p20c    proc near       ; handle int c - stack fault
  426.     stc         ; show registers on all int c
  427.     ret
  428. p20c    endp
  429. align 4
  430. p20d    proc near       ; handle int d - general protection fault
  431.     call p220       ; get opcode in al
  432.     mov edi,offset32 intdlist
  433.     mov ecx,intdlistlen
  434.     cmp al,0cdh     ; get an int?
  435.     jz short p20dc      ; yes
  436.     repnz scasb     ; search for opcode
  437.     jnz short p20ds     ; no match
  438. p20dn:  clc         ; don't show registers
  439.     ret
  440. p20ds:  stc         ; show registers
  441.     ret
  442. p20dc:  ; expand to handle individual interrupts as needed
  443.     jmp p20dn
  444. p20d    endp
  445. align 4
  446. p20e    proc near       ; handle int e - page fault
  447.     clc         ; don't show registers
  448.     ret 
  449. p20e    endp
  450. align 4
  451. p220    proc near       ; get opcode byte in register al
  452.     test saveefl,bit17on    ; v86 mode?
  453.     jz short p220a      ; no
  454.     movzx ebx,savecs    ; get opcode address for v86 mode
  455.     shl ebx,4       ; times 16
  456.     add ebx,saveeip     ; plus eip
  457.     mov opcodecs,ds     ; use flat selector
  458.     mov opcodeeip,ebx   ; and our derived offset
  459.     jmp short p220b 
  460. p220a:  
  461.     mov bx,savecs       ; get opcode address for protect mode
  462.     mov opcodecs,bx     ; save cs
  463.     mov ebx,saveeip
  464.     mov opcodeeip,ebx   ; and eip
  465. p220b:  mov edi,offset32 opcode
  466.     mov ax,ds
  467.     mov es,ax       ; es=ds
  468.     mov ecx,8
  469.     mov esi,opcodeeip
  470.     push ds
  471.     mov ds,opcodecs
  472.     rep movsb       ; copy opcodes from user's cs:eip to us
  473.     pop ds
  474. mov esi,offset32 opcode
  475. p220c:  lodsb           ; get opcode byte
  476.     cmp esi,offset32 opcode+8   ; too far?
  477.     jae short p220d     ; yes - bail out
  478.     mov edi,offset32 prelist    ; is it a prefix byte?
  479.     mov ecx,prelistlen
  480.     repnz scasb     ; search for prefix
  481.     jz p220c        ; got a prefix - get next byte
  482. p220d:  ret
  483. p220    endp
  484. align 4
  485. p300    proc near       ; display message using Windows services
  486.     ; this routine is used as a callback unless WinxNoWinMsg is used
  487.     cmp showregs,1      ; something to show?
  488.     jz short p300a      ; yes
  489.     ret         ; no - exit now
  490. p300a:  @save eax,ebx,ecx,esi,edi   ; save registers
  491.     VMMcall Get_Cur_VM_Handle   ; get handle in ebx
  492.     mov eax,mb_iconhand+mb_ok
  493.     mov ecx,offset32 regline1
  494.     xor esi,esi     ; no callback
  495.     mov edi,offset32 periscopeid
  496.     VxDcall Shell_Sysmodal_Message  ; display message
  497.     mov showregs,0      ; nothing to show for now
  498.     @restore
  499.     ret
  500. p300    endp
  501. align 4
  502. p880    proc near       ; convert byte in al and output it to [edi]
  503.     push ebx
  504.     mov ah,0
  505.     mov ebx,offset32 hextable
  506.     shl ax,4        ; high nibble in ah
  507.     shr al,4        ; low nibble in al
  508.     xlat            ; convert low nibble
  509.     xchg ah,al
  510.     xlat            ; convert high nibble
  511.     mov [edi],ax        ; save the result
  512.     inc edi
  513.     inc edi         ; point to next output address
  514.     pop ebx
  515.     ret
  516. p880    endp
  517. align 4
  518. p885    proc near       ; convert word in dx and output it to [edi]
  519.     push eax
  520.     mov al,dh
  521.     call p880       ; convert high byte
  522.     mov al,dl
  523.     call p880       ; convert low byte
  524.     pop eax
  525.     ret
  526. p885    endp
  527. align 4
  528. p889    proc near       ; convert dword in edx and output it to [edi]
  529.     rol edx,16
  530.     call p885       ; convert high word
  531.     inc edi         ; a space between the high and low words
  532.     rol edx,16
  533.     call p885       ; convert low word
  534.     inc edi         ; a space after the low word
  535.     ret
  536. p889    endp
  537. align 4
  538. p900    proc near       ; display string on mono screen
  539.     @save eax,esi,edi,es
  540.     ; entry: esi points to string
  541.     mov ax,ds
  542.     mov es,ax       ; es=ds
  543. p900d:  call p905       ; calc offset
  544. p900a:  lodsb           ; get next byte
  545.     cmp al,0        ; end?
  546.     jz short p900x      ; yes
  547.     cmp al,cr       ; cr?
  548.     jz short p900b      ; yes
  549.     cmp al,lf       ; lf?
  550.     jz short p900c      ; yes
  551.     mov ah,0fh      ; high intensity
  552.     stosw           ; output it
  553.     inc curcol      ; bump column number
  554.     cmp curcol,79       ; at end of screen?
  555.     jbe p900a       ; no
  556.     mov curcol,0        ; line overflow
  557.     jmp short p900c     ; force an lf
  558. p900b:              ; handle cr
  559.     mov curcol,0        ; column 0
  560.     jmp short p900d     ; force recalc
  561. p900c:              ; handle lf
  562.     inc currow      ; next row
  563.     cmp currow,25       ; on row 25?
  564.     jb short p900d      ; no - force recalc
  565.     call p915       ; scroll the screen
  566.     jmp short p900d     ; recalc now
  567. p900x:  @restore
  568.     ret
  569. p900    endp
  570. align 4
  571. p905    proc near       ; calc offset in di using currow, curcol
  572.     @save eax,ebx,ecx
  573.     movzx eax,currow    ; current row
  574.     mov cl,80*2
  575.     mul cl          ; times 160 
  576.     movzx ebx,curcol
  577.     shl ebx,1       ; plus (column times 2)
  578.     add eax,ebx     ; gives offset relative to mono screen
  579.     add eax,0b0000h     ; plus mono segment*16 gives 32-bit offset
  580.     mov edi,eax     ; return result in edi
  581.     @restore
  582.     ret
  583. p905    endp
  584. align 4
  585. p910    proc near       ; clear mono screen
  586.     @save eax,ecx,edi,es
  587.     mov ax,ds
  588.     mov es,ax       ; es=ds
  589.     mov ax,720h
  590.     mov edi,0b0000h
  591.     mov ecx,25*80
  592.     rep stosw       ; init the screen
  593.     mov currow,cl       ; set these to zero
  594.     mov curcol,cl
  595.     @restore
  596.     ret
  597. p910    endp
  598. align 4
  599. p915    proc near       ; scroll mono screen
  600.     @save eax,ecx,esi,edi,es
  601.     mov ax,ds
  602.     mov es,ax       ; es=ds
  603.     mov esi,0b0000h
  604.     mov edi,esi
  605.     add esi,80*2        ; skip a line
  606.     mov ecx,24*80/2     ; dwords to copy
  607.     rep movsd       ; scroll it
  608.     mov ax,0720h
  609.     mov ecx,80/2        ; dwords in a line
  610.     rep stosd       ; blank last line
  611.     mov currow,24       ; now at row 24
  612.     mov curcol,cl       ; colum 0
  613.     @restore
  614.     ret
  615. p915    endp
  616. align 4
  617. p950    proc near       ; display registers
  618.     mov ax,inttype
  619.     mov edi,offset32 xinttype
  620.     call p880       ; convert byte
  621.     mov ax,inttype
  622.     mov ah,al       ; int type in ah
  623.     mov esi,offset32 explanations   ; point to interrupt descriptions
  624.     mov ecx,explcount   ; number of descriptions
  625. p950b:  lodsb           ; get the byte
  626.     cmp al,ah       ; does it match?
  627.     jz short p950c      ; yes
  628.     add esi,expllen     ; add the message length
  629.     loop p950b      ; and try again
  630.     jmp short p950d     ; no find
  631. p950c:  mov edi,offset32 xexplain ; point to output buffer
  632.     mov ecx,expllen     ; length of message
  633.     rep movsb       ; copy it across
  634. p950d:
  635.     mov ax,savecs
  636.     and eax,3       ; isolate cs ring bits
  637.     add al,'0'      ; convert to ascii
  638.     mov xring,al        ; save it
  639.     mov esi,offset32 modep  ; assume protect mode
  640.     test saveefl,bit17on    ; v86 mode?
  641.     jz short p950e      ; no
  642.     mov esi,offset32 modev86
  643.     mov xring,'3'       ; v86 is always ring 3
  644. p950e:  mov edi,offset32 xmode  ; point to output buffer
  645.     mov ecx,7
  646.     rep movsb       ; copy mode across
  647.     mov edx,errorcode
  648.     mov edi,offset32 errorno
  649.     call p889       ; convert error code
  650.     mov ecx,8 
  651.     mov esi,offset32 opcode ; point to opcode bytes
  652.     mov edi,offset32 xopcode
  653. p950a:  lodsb           ; get byte
  654.     call p880       ; convert byte
  655.     inc edi
  656.     loop p950a      ; continue
  657.     mov edx,saveeax 
  658.     mov edi,offset32 regeax
  659.     call p889       ; convert eax
  660.     mov edx,saveebx 
  661.     mov edi,offset32 regebx
  662.     call p889       ; convert ebx
  663.     mov edx,saveecx 
  664.     mov edi,offset32 regecx
  665.     call p889       ; convert ecx
  666.     mov edx,saveedx 
  667.     mov edi,offset32 regedx
  668.     call p889       ; convert edx
  669.     mov edx,saveebp 
  670.     mov edi,offset32 regebp
  671.     call p889       ; convert ebp
  672.     mov edx,saveesp 
  673.     mov edi,offset32 regesp
  674.     call p889       ; convert esp
  675.     mov edx,saveesi 
  676.     mov edi,offset32 regesi
  677.     call p889       ; convert esi
  678.     mov edx,saveedi 
  679.     mov edi,offset32 regedi
  680.     call p889       ; convert edi
  681.     mov edx,saveeip
  682.     mov edi,offset32 regeip
  683.     call p889       ; convert eip
  684.     mov edx,saveefl  
  685.     mov edi,offset32 regefl
  686.     call p889       ; convert efl
  687.     mov dx,savecs
  688.     mov edi,offset32 regcs
  689.     call p885       ; convert cs
  690.     mov dx,saveds
  691.     mov edi,offset32 regds
  692.     call p885       ; convert ds
  693.     mov dx,savees
  694.     mov edi,offset32 reges
  695.     call p885       ; convert es
  696.     mov dx,savefs
  697.     mov edi,offset32 regfs
  698.     call p885       ; convert fs
  699.     mov dx,savegs
  700.     mov edi,offset32 reggs
  701.     call p885       ; convert gs
  702.     mov dx,savess
  703.     mov edi,offset32 regss
  704.     call p885       ; convert ss
  705.     mov edx,cr0
  706.     mov edi,offset32 regcr0
  707.     call p889       ; convert cr0
  708.     mov edx,cr2
  709.     mov edi,offset32 regcr2
  710.     call p889       ; convert cr2
  711.     mov edx,cr3
  712.     mov edi,offset32 regcr3
  713.     call p889       ; convert cr3
  714.     sidt fword ptr idtlimit
  715.     mov edx,idtbase     ; get idt base
  716.     mov edi,offset32 idtb
  717.     call p889       ; convert idt base
  718.     mov dx,idtlimit     ; get idt limit
  719.     mov edi,offset32 idtl  
  720.     call p885       ; convert idt limit
  721.     sgdt fword ptr gdtlimit
  722.     mov edx,gdtbase     ; get gdt base
  723.     mov edi,offset32 gdtb
  724.     call p889       ; convert gdt base
  725.     mov dx,gdtlimit     ; get gdt limit
  726.     mov edi,offset32 gdtl
  727.     call p885       ; convert gdt limit
  728.     sldt ldtvalue
  729.     mov dx,ldtvalue     ; get ldt 
  730.     mov edi,offset32 ldtw
  731.     call p885       ; convert ldt
  732.     str tssvalue
  733.     mov dx,tssvalue     ; get tss 
  734.     mov edi,offset32 tssw
  735.     call p885       ; convert tss
  736.     cmp usemono,0       ; use mono screen?
  737.     jz short p950x      ; no
  738.     call p960       ; save/clear mono screen if needed
  739.     mov esi,offset32 regline1
  740.     call p900       ; display registers
  741.     mov esi,offset32 pause
  742.     call p900       ; display pause msg
  743.     mov keystrokes,0    ; clear keystrokes
  744.     sti         ; allow interrupts
  745. p950l:  cmp keystrokes,2    ; get 2 irq1s yet?
  746.     jb p950l        ; no
  747.     mov esi,offset32 crlf
  748.     call p900       ; display a crlf
  749.     call p970       ; restore mono screen if needed
  750.     cli         ; no more interrupts for now
  751. p950x:  ret
  752. p950    endp
  753. align 4
  754. p960    proc near       ; save/clear mono screen
  755.     cmp monosave,1      ; save it?
  756.     jnz short p960x     ; no
  757.     mov ax,ds
  758.     mov es,ax       ; es=ds
  759.     mov esi,0b0000h
  760.     mov edi,offset32 monoscreen
  761.     mov ecx,80*25/2
  762.     rep movsd       ; save the screen
  763.     call p910       ; clear the screen
  764. p960x:  ret
  765. p960    endp
  766. align 4
  767. p970    proc near       ; restore mono screen
  768.     cmp monosave,1      ; save it?
  769.     jnz short p970x     ; no
  770.     mov ax,ds
  771.     mov es,ax       ; es=ds
  772.     mov esi,offset32 monoscreen
  773.     mov edi,0b0000h
  774.     mov ecx,80*25/2
  775.     rep movsd       ; restore the screen
  776. p970x:  ret
  777. p970    endp
  778. VAD_Create_VM proc near
  779.     ret
  780. VAD_Create_VM endp
  781. VxD_Locked_Code_Ends
  782. ; ****************************************************************************
  783. VxD_Real_Init_Seg       ; init seg (real mode)
  784. p1000   proc near
  785.     mov ah,9
  786.     mov dx,offset copyr  
  787.     int 21h         ; display copyright
  788.     xor ax,ax       ; don't abort load
  789.     xor bx,bx       ; don't exclude any pages
  790.     xor si,si       ; no instance data items
  791.     xor edx,edx     ; dword of reference data
  792.     ret
  793. p1000   endp
  794. copyr   db 'WINX (Windows Exception Handler) Version 0.88'
  795.     db cr,lf
  796.     db 'Copyright 1991, The Periscope Company, Inc.  All rights reserved.'
  797.     db cr,lf,'$'
  798. VxD_Real_Init_Ends      ; init seg (real mode)
  799. ; ****************************************************************************
  800. VxD_Idata_Seg           ; init data seg (protect mode)
  801. winxusemono db 'WinxUseMono',0  ; tokens in system.ini
  802. winxmonosave    db 'WinxMonoSave',0
  803. winxnowinmsg    db 'WinxNoWinMsg',0
  804. winxpsport  db 'PeriscopePort',0
  805. winxnoint   db 'WinxNoInt'
  806. winxnoint2  db '..',0
  807. VxD_Idata_Ends
  808. ; ****************************************************************************
  809. VxD_Icode_Seg           ; init code seg (protect mode)
  810. VAD_Sys_Crit_Init proc near ; init phase 1
  811.     xor edx,edx     ; pointer to default string
  812.     xor esi,esi     ; look in [386enh]
  813.     mov edi,offset32 WinxUseMono
  814.     VMMcall Get_Profile_String  ; search for 'WinxUseMono'
  815.     jc short p1100a     ; no find 
  816.     mov usemono,1       ; use mono screen
  817.     call p1120      ; init mono screen
  818. p1100a:
  819.     xor edx,edx     ; pointer to default string
  820.     xor esi,esi     ; look in [386enh]
  821.     mov edi,offset32 WinxNoWinMsg
  822.     VMMcall Get_Profile_String  ; search for 'WinxNoWinMsg'
  823.     jc short p1100b     ; no find 
  824.     mov winmsg,0        ; no windows messages
  825. p1100b:
  826.     xor eax,eax     ; zap value
  827.     xor esi,esi     ; look in [386enh]
  828.     mov edi,offset32 WinxPSPort
  829.     VMMcall Get_Profile_Hex_Int ; search for 'PeriscopePort'
  830.     jc short p1100c     ; no find 
  831.     mov psport,ax       ; set Periscope's port
  832. p1100c:
  833.     xor edx,edx     ; pointer to default string
  834.     xor esi,esi     ; look in [386enh]
  835.     mov edi,offset32 WinxMonoSave
  836.     VMMcall Get_Profile_String  ; search for 'WinxMonoSave'
  837.     jc short p1100d     ; no find 
  838.     mov monosave,1      ; save/restore mono screen
  839.     call p1120      ; init mono screen
  840. p1100d:
  841.     mov eax,offset32 hookint06
  842.     mov ebx,offset32 intlist
  843.     mov ecx,intlistlen  ; count of interrupts
  844. p1100e: xor edx,edx     ; pointer to default string
  845.     xor esi,esi     ; look in [386enh]
  846.     mov edi,offset32 winxnoint
  847.     push ebx
  848.     mov bx,[ebx]        ; get int name in ascii
  849.     mov word ptr [winxnoint2],bx    ; save it
  850.     VMMcall Get_Profile_String  ; search for 'WinxNoInt..'
  851.     jc short p1100f     ; no find 
  852.     mov byte ptr [eax],0    ; don't hook this int
  853. p1100f: pop ebx
  854.     inc ebx
  855.     inc ebx
  856.     inc eax
  857.     loop p1100e     ; check all of our interrupts
  858.     call p1140      ; hook the indicated interrupts
  859.     clc         ; no error
  860.     ret
  861. align 4
  862. p1120   proc near       ; init mono screen
  863.     mov ax,ds
  864.     mov es,ax       ; es=ds
  865.     mov edi,0b0000h     ; init mono screen
  866.     mov ax,0720h
  867.     mov ecx,25*80
  868.     rep stosw
  869.     ret
  870. p1120   endp
  871. align 4
  872. p1140   proc near       ; set interrupts in idt
  873.     mov intgate,0ee00h  ; set interrupt gate, dpl=3
  874.     mov eax,offset32 p006   ; offset of exception handler
  875.     mov ebx,offset32 origint6   ; offset of original cs:eip
  876.     mov cl,hookint06    ; if 1, we hook this interrupt
  877.     mov edi,int6*2      ; offset of interrupt in idt
  878.     call p1160      ; set int 6
  879.     mov eax,offset32 p008
  880.     mov ebx,offset32 origint8
  881.     mov cl,hookint08
  882.     mov edi,int8*2
  883.     call p1160      ; set int 8
  884.     mov eax,offset32 p00a
  885.     mov ebx,offset32 originta
  886.     mov cl,hookint0a
  887.     mov edi,int0a*2
  888.     call p1160      ; set int a
  889.     mov eax,offset32 p00b
  890.     mov ebx,offset32 origintb
  891.     mov cl,hookint0b
  892.     mov edi,int0b*2
  893.     call p1160      ; set int b
  894.     mov eax,offset32 p00c
  895.     mov ebx,offset32 origintc
  896.     mov cl,hookint0c
  897.     mov edi,int0c*2
  898.     call p1160      ; set int c
  899.     mov eax,offset32 p00d
  900.     mov ebx,offset32 origintd
  901.     mov cl,hookint0d
  902.     mov edi,int0d*2
  903.     call p1160      ; set int d
  904.     mov eax,offset32 p00e
  905.     mov ebx,offset32 originte
  906.     mov cl,hookint0e
  907.     mov edi,int0e*2
  908.     call p1160      ; set int e
  909.     mov intgate,08e00h  ; interrupt gate, dpl=0
  910.     mov eax,offset32 p013
  911.     mov ebx,offset32 origirq1 
  912.     mov cl,1        ; always hook this interrupt
  913.     mov edi,51h*8
  914.     call p1160      ; set int 51h (keyboard)
  915.     ret
  916. p1140   endp
  917. p1160   proc near       ; set interrupt in idt
  918.     ; on entry, eax has offset of new handler,
  919.     ; ebx points to save area for current handler's address,
  920.     ; cl contains a 1 if the interrupt is to be hooked, and
  921.     ; edi has the interrupt number*4
  922.     cmp cl,1        ; hook it?
  923.     jnz short p1160x        ; no
  924.     push eax
  925.     mov ax,ds
  926.     mov es,ax       ; es=ds
  927.     sidt fword ptr idtlimit
  928.     add edi,idtbase
  929.     mov ax,[edi]        ; get low offset
  930.     mov word ptr [ebx],ax
  931.     mov ax,[edi+6]      ; get high offset
  932.     mov word ptr [ebx+2],ax
  933.     mov ax,[edi+2]      ; get segment 
  934.     mov word ptr [ebx+4],ax
  935.     pop eax
  936.     stosw           ; save low offset
  937.     mov ax,cs
  938.     stosw           ; save cs
  939.     mov ax,intgate      ; value for interrupt gate 
  940.     stosw           ; save misc bytes
  941.     shr eax,16
  942.     stosw           ; save high offset
  943. p1160x: ret
  944. p1160   endp
  945. VAD_Sys_Crit_Init endp
  946. ; ****************************************************************************
  947. VAD_Device_Init proc near   ; init phase 2
  948.     cmp winmsg,0        ; skip windows msg?
  949.     jz short p1200a     ; yes
  950.     mov esi,offset32 p300
  951.     VMMcall Call_When_Idle  ; setup callback
  952. p1200a:
  953.     clc         ; no error
  954.     ret
  955. VAD_Device_Init endp
  956. ; ****************************************************************************
  957. VAD_Init_Complete proc near ; init phase 3
  958.     clc         ; no error
  959.     ret
  960. VAD_Init_Complete endp
  961. VxD_Icode_Ends
  962. end
  963.  
  964.