DOS 3.30 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
8.2 KiB

5 years ago
  1. ; MSStack.inc
  2. ;
  3. ; Interrupt level 2, 3, 4, 5, 6, 7,(10, 11, 12, 14, 15 - AT level)
  4. ; should follow the standard Interrupt Sharing Scheme which has
  5. ; a standard header structure.
  6. ; Fyi, the following shows the relations between
  7. ; the interrupt vector and interrupt level.
  8. ; VEC(Hex) 2 8 9 A B C D E 70 72 73 74 76 77
  9. ; LVL(Deci) 9 0 1 2 3 4 5 6 8 10 11 12 14 15
  10. ; MSSTACK module modifies the following interrupt vectors
  11. ; to meet the standard Interrupt Sharing standard;
  12. ; A, B, C, D, E, 72, 73, 74, 76, 77.
  13. ; Also, for interrupt level 7 and 15, the FirstFlag in a standard header
  14. ; should be initialized to indicat whether this interrupt handler is
  15. ; the first (= 80h) or not. The FirstFlag entry of INT77h's
  16. ; program header is initialized in STKINIT.INC module.
  17. ; FirstFlag is only meaningful for interrupt level 7 and 15.
  18. ;
  19. ; User specifies the number of stack elements - default = 9
  20. ; minimum = 8
  21. ; maximum = 64
  22. ;
  23. ; Intercepts Asynchronous Hardware Interrupts only
  24. ;
  25. ; Picks a stack from pool of stacks and switches to it
  26. ;
  27. ; Calls the previously saved interrupt vector after pushing flags
  28. ;
  29. ; On return, returns the stack to the stack pool
  30. ;
  31. ; This is a modification of STACKS:
  32. ; 1. To fix a bug which was causing the program to take up too much space.
  33. ; 2. To dispense stack space from hi-mem first rather than low-mem first.
  34. ; . Clobbers the stack that got too big instead of innocent stack
  35. ; . Allows system to work if the only stack that got too big was the most
  36. ; deeply nested one
  37. ; 3. Disables NMI interrupts while setting the NMI vector.
  38. ; 4. Does not intercept any interupts on a PCjr.
  39. ; 5. Double checks that a nested interrupt didn't get the same stack.
  40. ; 6. Intercepts Ints 70, 72-77 for PC-ATs and other future products
  41. ;The following variables are for MSSTACK.inc
  42. EVEN
  43. dw 0 ; SPARE FIELD BUT LEAVE THESE IN ORDER
  44. StackCount dw 0
  45. StackAt dw 0
  46. StackSize dw 0
  47. Stacks dw 0
  48. dw 0
  49. FirstEntry dw Stacks
  50. LastEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
  51. NextEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
  52. ;End of variables defined for MSSTACK.
  53. ;*******************************************************************
  54. ;Macro Interrupt handler for the ordinary interrupt vectors and
  55. ;the shared interrupt vectors.
  56. ;*****************************
  57. Stack_Main MACRO AA
  58. ASSUME DS:NOTHING
  59. ASSUME ES:NOTHING
  60. ASSUME SS:NOTHING
  61. PUBLIC Int&AA
  62. PUBLIC Old&AA
  63. ;-----------------------------
  64. ife IntSharingFlag ;if not IntSharingFlag
  65. ;-----------------------------
  66. Old&AA DD 0
  67. Int&AA PROC FAR
  68. ;-----------------------------
  69. else ;for shared interrupt. A Header exists.
  70. PUBLIC FirstFlag&AA
  71. Int&AA PROC FAR
  72. jmp short Entry_Int&AA&_Stk
  73. Old&AA dd 0 ;Forward pointer
  74. dw 424Bh ;compatible signature for Int. Sharing
  75. FirstFlag&AA db 0 ;the firstly hooked.
  76. jmp short Intret_&AA ;Reset routine. We don't care this.
  77. db 7 dup (0) ;Reserved for future.
  78. Entry_Int&AA&_Stk:
  79. ;-----------------------------
  80. endif
  81. ;-----------------------------
  82. ;
  83. ; Keyboard interrupt must have a three byte jump, a NOP and a zero byte
  84. ; as its first instruction for compatibility reasons
  85. ifidn <&aa>,<09>
  86. jmp Keyboard_lbl
  87. nop
  88. db 0
  89. Keyboard_lbl label near
  90. endif
  91. ; This patches INTERRUPT 75h to be "unhooked". We do this Wierdness,
  92. ; rather than never hooking INT 75h, to maintain maximum compat. with IBMs
  93. ; post production patch.
  94. push ax
  95. ifidn <&aa>,<02>
  96. ; *********************************************************************
  97. ;
  98. ; This is special support for the P12 / NMI handler
  99. ;
  100. ; On the P12, there is a situation where an NMI can be caused by
  101. ; using the "OUT" instructions to certain ports. When this
  102. ; occurs, the P12 hardware *GUARANTEES* that **NOTHING** can stop
  103. ; the NMI or interfere with getting to the NMI handler. This
  104. ; includes other type of interrupts (hardware and software), and
  105. ; also includes other type of NMI's. When any NMI has occured,
  106. ; no other interrtupt (hardware, software or NMI) can occur until
  107. ; the software takes specific steps to allow further interrupting.
  108. ;
  109. ; For P12, the situation where the NMI is generated by the "OUT"
  110. ; to a control port requires "fixing-up" and re-attempting. In
  111. ; otherwords, it is actually a "restartable exception". In this
  112. ; case, the software handler must be able to get to the stack in
  113. ; order to figure out what instruction caused the problem, where
  114. ; it was "OUT"ing to and what value it was "OUT"ing. Therefore,
  115. ; we will not switch stacks in this situation. This situation is
  116. ; detected by interrogating port 62h, and checking for a bit value
  117. ; of 80h. If set, *****DO NOT SWITCH STACKS*****.
  118. ;
  119. ; *********************************************************************
  120. push ds
  121. mov ax,0f000h
  122. mov ds,ax
  123. cmp byte ptr ds:[0fffeh],0f9h ;check if P12
  124. pop ds
  125. jne Normal&aa
  126. in al,62h
  127. test al,80h
  128. jz Normal&aa
  129. Special&aa:
  130. pop ax
  131. jmp dword ptr Old&aa
  132. Normal&aa:
  133. ; *********************************************************************
  134. endif
  135. push bp
  136. push es
  137. mov es, cs:[STACKS+2] ; Get segment of stacks
  138. mov bp,NextEntry ; get most likely candidate
  139. mov al,Allocated
  140. xchg AllocByte,al ; grab the entry
  141. cmp al,Free ; still avail?
  142. jne NotFree&aa
  143. sub NextEntry,EntrySize ; set for next interrupt
  144. Found&aa:
  145. mov SavedSP,sp ; save sp value
  146. mov SavedSS,ss ; save ss also
  147. ; mov IntLevel,aa&h ; save the int level
  148. mov ax,bp ; temp save of table offset
  149. mov bp,NewSP ; get new SP value
  150. cmp es:[bp],ax ; check for offset into table
  151. jne FoundBad&aa
  152. mov ax,es ; point ss,sp to the new stack
  153. mov ss,ax
  154. mov sp,bp
  155. pushf ; go execute the real interrupt handler
  156. call dword ptr old&aa ; which will iret back to here
  157. mov bp,sp ; retrieve the table offset for us
  158. mov bp,es:[bp] ; but leave it on the stack
  159. mov ss,SavedSS ; get old stack back
  160. mov sp,SavedSP
  161. ; cmp AllocByte,Allocated ; If an error occured,
  162. ; jne NewError&aa ; do not free us
  163. mov AllocByte,Free ; free the entry
  164. mov NextEntry,bp ; setup to use next time
  165. NewError&aa:
  166. pop es
  167. pop bp ; saved on entry
  168. pop ax ; saved on entry
  169. INTRET_&AA: ;3.30
  170. iret ; done with this interrupt
  171. NotFree&aa:
  172. cmp al,Allocated ; error flag
  173. je findnext&aa ; no, continue
  174. xchg AllocByte,al ; yes, restore error value
  175. FindNext&aa:
  176. call LongPath
  177. jmp Found&aa
  178. FoundBad&aa:
  179. cmp bp,FirstEntry
  180. jc findnext&aa
  181. mov bp,ax ; flag this entry
  182. mov AllocByte,Clobbered
  183. ; add bp,EntrySize ; and previous entry
  184. ; mov AllocByte,Overflowed
  185. ; sub bp,EntrySize
  186. jmp findnext&aa ; keep looking
  187. int&aa endp
  188. endm
  189. ;***************************** ;3.30
  190. ;End of Macro definition ;3.30
  191. ;******************************************************************** ;3.30
  192. ; THESE ARE THE INDIVIDUAL INTERRUPT HANDLERS ;3.30
  193. ;3.30
  194. IRP A,<02,08,09,70> ;3.30
  195. IntSharingFlag=0 ;3.30
  196. Stack_Main &A ;3.30
  197. ENDM ;3.30
  198. ;3.30
  199. IRP A,<0A,0B,0C,0D,0E,72,73,74,76,77> ;3.30
  200. IntSharingFlag=1 ;3.30
  201. Stack_Main &A ;3.30
  202. ENDM ;3.30
  203. ;3.30
  204. ;******************************************************************** ;3.30
  205. ;Common routines ;3.30
  206. longpath:
  207. mov bp,LastEntry ; start with last entry in table
  208. LPLOOPP: ;3.30
  209. cmp AllocByte,Free ; is entry free?
  210. jne inuse ; no, try next one
  211. mov al,Allocated
  212. xchg AllocByte,al ; allocate entry
  213. cmp al,Free ; is it still free?
  214. je found ; yes, go use it
  215. cmp al,Allocated ; is it other than Allocated or Free?
  216. je inuse ; no, check the next one
  217. mov AllocByte,al ; yes, put back the error state
  218. inuse:
  219. cmp bp,FirstEntry
  220. je Fatal
  221. sub bp,EntrySize
  222. JMP LPLOOPP ;3.30
  223. found:
  224. ret
  225. page
  226. fatal proc near
  227. push ds ;3.30
  228. mov ax, 0f000h ;loook at the model byte ;3.30
  229. mov ds, ax ;3.30
  230. cmp ds:byte ptr [0fffeh], 0f9h ;convertible ;3.30
  231. pop ds ;3.30
  232. jne Skip_NMIS ;3.30
  233. ;3.30
  234. mov al,07h ; disable p12 NMIs
  235. out 72h,al
  236. Skip_NMIS: ;3.30
  237. cli ; disable and mask
  238. mov al,0ffh ; all other ints
  239. out 021h,al
  240. out 0a1h,al
  241. mov si,cs
  242. mov ds,si
  243. mov si,offset fatal_msg
  244. fatal_loop:
  245. lodsb
  246. cmp al,'$'
  247. je fatal_done
  248. mov bl,7 ;3.30*
  249. mov ah,14 ;3.30*
  250. int 010h ; whoops, this enables ints ;3.30*
  251. jmp fatal_loop
  252. fatal_done:
  253. jmp fatal_done
  254. fatal endp