home *** CD-ROM | disk | FTP | other *** search
/ TopWare Tools / TOOLS.iso / tools / top1190 / unmark.asm < prev    next >
Encoding:
Assembly Source File  |  1989-05-31  |  37.5 KB  |  738 lines

  1. Title   UnMark.ASM -- Replaces TurboPower RELEASE Version 2.8
  2. Cseg    Segment Public Para   ;Version 3.1 31-May-1989 - 03:10
  3.         Assume  cs:Cseg,ds:Cseg
  4.         Org 0100h
  5. Main    Proc    Far
  6.         Jmp Start
  7. UsageMsg    DB  13,'   ',9,10
  8. DB 'UnMark replaces RELEASE ver 2.8 by TurboPower Software',13,10,9
  9. DB '======================================================',13,10,9
  10. DB 'UnMark, like RELEASE, removes memory-resident programs',13,10,9
  11. DB 'and restores interrupt vectors to pre[F]Mark addresses.',13,10,10,9
  12. DB 'UnMark will UpDate the WATCH data area when WATCH has',13,10,9
  13. DB 'been installed ahead of the [F]Mark that is removed.',13,10,10,9
  14. DB 'UnMark also releases any Lotus/Intel expanded memory',13,10,9
  15. DB 'used by TSR programs which it releases.',13,10,10,9
  16. DB '/Keep [F]Mark and /No EMS RELEASE options are NOT',13,10,9
  17. DB 'implemented in UnMark.  The UnMark syntax is:',13,10,10,9
  18. DB 'UNMARK [[FilePath\]MarkName] [Options]',13,10,10,9
  19. DB 9,'[/]?',9,'Write this Help screen',13,10,10,9
  20. DB 'Other Options MUST begin with a "/" character:',13,10,10
  21. DB 9,9,'/D',9,"Display MCBs",13,10
  22. DB 9,9,'/R',9,'Leave 8259 interrupt controller as is',13,10
  23. DB 9,9,'/S',9,'STUFF Keyboard Buffer (<=14 bytes+CR)'
  24. CRLF        DB  13,10,"$",8,32,26       ; You can >TYPE UnMark.COM
  25. EMSid       DB  'EMMXXXX0'
  26. MarkID      DB  '3.1 TSR '              ; ID of [F]Marks 7 bytes
  27. WatchM      DB  'WATCHER$'              ; or Watch ID = 12 bytes
  28. Header      DB  ' MCB Block Len User  Release? $'
  29. TruMsg      DB  '  True  $'
  30. FalMsg      DB  ' False  $'
  31. MrkMsg      DB  '[F]Mark$PARAMETER'
  32. PgmMsg      DB  'Program$'
  33. EnvMsg      DB  'Environ$'
  34. TrapMsg     DB  'Trapped$'
  35. NotFound    DB  13,10,'NO '
  36. WasFound    DB  '[F]Mark found',13,10,"$"
  37. Protected   DB  13,10,'Protected Mark Encountered!',13,10,"$"
  38. FileError   DB  13,10,'Error Reading FMark File!',13,10,"$"
  39. ReleasErr   DB  13,10,'Release Failed!',13,10,'$'
  40. RamMsg      DB  'RAM bytes available: '
  41. Free        DB  6 DUP(' '),13,10,"$"
  42. FlagD       DB  0                       ; Display MCBs IF Set
  43. FlagR       DB  0                       ; Reset 8259 UNLESS Set
  44. ASCII_TBL   DB  "!#$%&()-1234567890:'@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_{}~"
  45. NumChars    equ $ - ASCII_TBL
  46. ScanC_TBL   DB  2,4,5,6,8,10,11,12,2,3,4,5,6,7,8,9,10,11,39,40,3,30,48,46
  47.             DB  32,18,33,34,35,23,36,37,38,50,49,24,25,16,19,31,20,22,47
  48.             DB  17,45,21,44,43,7,12,26,27,41,0
  49. Stuff_BUF   DW  15 DUP(1C0Dh)
  50. ErrLvl      DW  4C00h                   ; Set for Program Exit
  51. PflagA      DW  0                       ; Set if Protected Mark
  52. MflagA      DW  0                       ; [F]Mark PSP When Found
  53. WatchF      DW  0                       ; PSP of Watch When Found
  54. FMarkF      DW  0                       ; Set if FMark File Found
  55. MkParm      equ offset buffer           ; Command [F]Mark Name
  56. MrkLen      DW  ?                       ; Length of Name
  57. MCBbuf      equ MkParm  +  40h          ; MCB Table and [F]Mark
  58. MCBend      DW  ?                       ; End of MCB area
  59. vector      equ MCBbuf  + 400h          ; Interrupt Vectors, EGA and
  60. parent      equ vector  + 418h          ; ICA areas plus Parent Word
  61. emscnt      equ parent  +   2h          ; EMS Handle Count and MAP
  62. emsmap      equ emscnt  +   2h          ; from [F]Mark Storage
  63.                                         ; <= 100h bytes for MAP
  64. Start:  xor     ax,ax                   ; Zero
  65.         mov     cx,2048                 ; data
  66.         mov     di,MkParm               ; buffer
  67.         rep     stosw                   ; words
  68.         mov     di,MkParm               ; Set for [F]Mark ID
  69.         mov     si,81h                  ; Get Command
  70.         call    Ploop                   ; Parameter(s)
  71.         mov     ah,9                    ; If NO ?
  72.         jnc     DoNew                   ; Then New Line
  73.         mov     dx,offset UsageMsg      ; Else Display
  74.         int     21h                     ; Syntax Message
  75.         jmp     Exit                    ; and Exit
  76.  
  77. DoNew:  mov     dx,offset CRLF          ; Display
  78.         int     21h                     ; New Line
  79.         mov     dx,MkParm               ; Calculate and
  80.         sub     di,dx                   ; Store [F]Mark
  81.         mov     MrkLen,di               ; Name Length
  82.         mov     ax,4300h                ; If Attributes
  83.         int     21h                     ; NOT Returned
  84.         jc      DoBuf                   ; Then NOT FMark
  85.         mov     FMarkF,CX               ; Else Flag as FMark
  86.  
  87. DoBuf:  mov     ah,52h                  ; Undocumented
  88.         int     21h                     ; Function
  89.         mov     di,es:[bx-2]            ; obtains
  90.         mov     es,di                   ; MCB of DOS
  91.         inc     di                      ; Config.Sys
  92.         mov     si,MCBbuf               ; Initialize Source and
  93.         xor     bx,bx                   ; Basic Index Pointers
  94.  
  95. MCBlp:  add     di,es:[3]               ; Advance so as to
  96.         mov     es,di                   ; Point to MCB and
  97.         inc     di                      ; Next Paragraph
  98.         mov     [si+bx+0],es            ; Store MCB
  99.         mov     dx,es:[1]               ; Get and Store
  100.         mov     [si+bx+2],dx            ; Block Address
  101.         mov     ax,es:[3]               ; and Block
  102.         mov     [si+bx+4],ax            ; Length
  103.         call    DoFlags                 ; Set Appropriate Flags
  104.         add     bx,8                    ; Advance to Next and
  105.         cmp     byte ptr es:[0],"Z"     ; Loop Until Last MCB
  106.         jne     MCBlp
  107.         push    ds                      ; Restore Extra Segment
  108.         pop     es                      ; Register to DATA
  109.         mov     MCBend,si               ; Initialize MCB buffer end
  110.         add     MCBend,bx               ; Adjust buffer end for length
  111.         mov     ax,MflagA               ; If NO [F]Mark
  112.         or      ax,ax                   ; Name Matched
  113.         jz      CkLast                  ; Then Try Last
  114.         cmp     ax,PflagA               ; Else If Below Protected
  115.         jc      IsPME                   ; Then Protected Error Exit
  116.  
  117. CkLast: mov     di,si                   ; Point to Buffer
  118.         mov     ax,-1                   ; Find [F]Mark
  119.         mov     cx,bx                   ; for Release
  120.         shr     cx,1                    ; In MCB Words
  121.         repne   scasw                   ; If None Found Yet
  122.         jne     DoLast                  ; Then Assume Last Mark
  123.         jmp     DoMark                  ; Else Get [F]Mark Data
  124.  
  125. DoLast: cmp     word ptr MrkLen,0       ; If [F]Mark
  126.         jnz     NoMark                  ; Command Name
  127.         mov     di,MCBend               ; Or If Scan MCBs
  128.         std                             ; backwards finds
  129.         mov     cx,bx                   ; NO [F]Mark
  130.         repne   scasb                   ; Marked
  131.         cld                             ; Then NO [F]Mark
  132.         jne     NoMark                  ; Found Error Exit
  133.         sub     di,5                    ; Else Point to
  134.         mov     bx,di                   ; [F]Mark Record
  135.         sub     bx,si                   ; With Basic Index
  136.         mov     di,MkParm               ; Set Destination
  137.         push    si                      ; Preserve
  138.         push    ds                      ; Source
  139.         mov     ds,[si+bx+2]            ; Point to and
  140.         mov     si,81h                  ; Get Command
  141.         call    Ploop                   ; [F]Mark Name
  142.         pop     ds                      ; Restore
  143.         pop     si                      ; Source
  144.         mov     cx,di                   ; If NO [F]Mark
  145.         sub     cx,MkParm               ; Command Length
  146.         jz      ReLast                  ; Then Release Mark
  147.         mov     di,MkParm               ; Else Scan
  148.         mov     al,"!"                  ;  for "!"
  149.         repne   scasb                   ; If Found
  150.         je      IsPME                   ; Then Protected Error Exit
  151.         jmp     short NoMark            ; Else Is Named Mark
  152.  
  153. ReLast: mov     ax,[si+bx+2]            ; Set the [F]Mark
  154.         mov     MflagA,ax               ; PSP Address and
  155.         mov     MrkLen,ax               ; use as Length
  156.         mov     word ptr [si+bx+6],-1   ; Flag for Release
  157.         mov     es,[si+bx+0]            ; Re-Set Registers
  158.         mov     di,[si+bx+2]            ; and Re-Enter MCBs
  159.         add     bx,8                    ; Loop after [F]Mark to
  160.         jmp     MCBlp                   ; Release subsequent MCBs
  161.  
  162. IsPME:  cmp     byte ptr FlagD,0FFh     ; If NO Display MCBs Flag
  163.         jne     DoPME                   ; Then Skip to Message
  164.         call    DoDeBug                 ; Else Show MCBs
  165. DoPME:  mov     dx,offset Protected     ; Error Exit with
  166.         mov     byte ptr ErrLvl,1       ; Error Level 1 and
  167.         jmp     Show                    ; Protected [F]Mark Message
  168.  
  169. NoMark: cmp     byte ptr FlagD,0FFh     ; If NO Display MCBs Flag
  170.         jne     DoNFM                   ; Then Skip to Message
  171.         call    DoDeBug                 ; Else Show MCBs
  172. DoNFM:  mov     dx,offset NotFound      ; Error Exit with
  173.         mov     byte ptr ErrLvl,2       ; Error Level 2 and
  174.         jmp     short Show              ; Not Found Message
  175.  
  176. DoFErr: mov     ah,3Eh                  ; Close the File
  177.         int     21h                     ; Handle If Possible
  178.         mov     dx,offset FileError     ; Reading [F]Mark File
  179.         mov     byte ptr ErrLvl,3       ; Error Level 3 and
  180.         jmp     short Show              ; Exit without Release
  181.  
  182. DoMark: mov     dx,di                   ; Save Pointer and
  183.         mov     bx,es:[di+2]            ; Block of [F]Mark
  184. DMloop: sub     di,8                    ; If Down to
  185.         cmp     si,di                   ; MCBbuf start
  186.         jnc     IfMark                  ; Then Do File or Mark
  187.         mov     ax,es:[di+2]            ; Else If Block
  188.         mov     cx,es:[di]              ; Compared to
  189.         inc     cx                      ; MCB + 1
  190.         cmp     ax,cx                   ; Shows
  191.         jz      DMloop                  ; Program
  192.         or      ax,ax                   ; Or If Trapped
  193.         jz      DMloop                  ; Block Or If
  194.         cmp     ax,bx                   ; Less Than [F]Mark
  195.         jc      DMloop                  ; Then Continue Look-Back
  196.         mov     byte ptr es:[di+7],0FFh ; Else Mark Environment
  197.         jmp     short DMloop            ; Loop-Back Until Start
  198.  
  199. IfMark: mov     di,dx                   ; Restore Pointer to [F]Mark
  200.         cmp     word ptr FMarkF,0       ; If NOT File Mark
  201.         jz      IsMark                  ; Then is Memory
  202.         mov     dx,MkParm               ; Else Open File
  203.         mov     ax,3D00h                ;  for Read Only
  204.         int     21h                     ; If Open Fails
  205.         jc      DoFErr                  ; Then File Error Exit
  206.         mov     dx,vector               ; Else Copy Interrupt
  207.         mov     cx,051Ch                ; EGA, ICA, Parent and
  208.         mov     bx,ax                   ; EM Handle Count from
  209.         mov     ah,3Fh                  ; File Mark file
  210.         int     21h                     ; If file Read Fails
  211.         jc      DoFErr                  ; Then File Error Exit
  212.         mov     ah,3Eh                  ; Else Close the
  213.         int     21h                     ; File Handle and
  214.         jmp     short MkExit            ; Check DeBug Flag
  215.  
  216. IsMark: mov     ds,[di-6]               ; Get Memory data
  217.         mov     si,0120h                ; Copy Mark Interrupts
  218.         mov     cx,051Ch                ; EGA,ICA, Parent and
  219.         mov     di,vector               ; EMS Information
  220.         rep     movsb                   ; Into data buffer
  221.         push    cs                      ; Restore
  222.         pop     ds                      ; Segment
  223. MkExit: cmp     byte ptr FlagD,0FFh     ; If NO Flag
  224.         mov     dx,offset WasFound      ; Then Show
  225.         jne     Show                    ; only Result
  226.         call    DoDeBug                 ; Else MCBs also
  227. Show:   mov     ah,9                    ; Display
  228.         int     21h                     ; Message
  229.         mov     si,MCBend               ; Start at the
  230.         sub     si,8                    ; UnMark Block
  231.         mov     di,MCBbuf               ; Working Toward
  232.         add     di,16                   ; DOS Environment
  233.         mov     dx,[si+2]               ; Get UnMark Address
  234.         mov     ax,[si+4]               ; and Free at UnMark
  235.         cmp     dx,[si-6]               ; Unless Contiguous
  236.         jne     ChkErr                  ; UnMark Environment
  237.         inc     ax                      ; Don't Include MCB
  238. ChkErr: cmp     byte ptr ErrLvl,0       ; If an UnMark Error
  239.         jnz     FreeOk                  ; Then Free is Unchanged
  240. LookLp: sub     si,8                    ; Look-Back Loop
  241.         mov     cx,[si+2]               ; If Block Address
  242.         cmp     cx,dx                   ; IS Same as UnMark
  243.         je      EndChk                  ; Then Don't Add
  244.         or      cx,cx                   ; Else If NOT Trapped
  245.         jnz     LookCk                  ; Then Check If Marked
  246.         cmp     byte ptr [si+15],0      ; Else If Marked Above
  247.         jnz     LookAd                  ; Then Add to Free
  248.         jmp     short EndChk            ; Else Don't Add
  249. LookCk: cmp     byte ptr [si+7],0       ; If Block NOT Marked
  250.         jz      EndChk                  ; Then Don't Add
  251. LookAd: add     ax,[si+4]               ; Else Add Length
  252.         inc     ax                      ;  and MCB to Free
  253. EndChk: cmp     di,si                   ; Until Just Above
  254.         jc      LookLp                  ; DOS Environment
  255. FreeOk: xor     dx,dx                   ; Clear Extension
  256.         mov     dl,ah                   ; Free RAM Equals
  257.         mov     cl,4                    ; Free Paragraphs
  258.         shr     dx,cl                   ; Converted to
  259.         shl     ax,cl                   ; DD bytes in DX:AX
  260.         mov     bx,offset Free+6        ; Store Free as
  261.         mov     cx,10                   ; Decimal Digits
  262. NexDig: div     cx                      ; Store each
  263.         or      dx,30h                  ; ASCII digit
  264.         dec     bx                      ; Right to Left
  265.         mov     [bx],dl                 ; Until
  266.         xor     dx,dx                   ; both DX
  267.         or      ax,ax                   ; and AX
  268.         jnz     NexDig                  ; are 0
  269.         mov     ah,9                    ; Display
  270.         mov     dx,offset RamMsg        ; RAM Bytes Free
  271.         int     21h
  272.         cmp     byte ptr ErrLvl,0       ; If NO [F]Mark Error
  273.         jz      ChkEMS                  ; Then Continue
  274.         jmp     Exit                    ; Else Error Exit
  275.  
  276. ChkEMS: mov     ax,3567h                ; Locate Driver
  277.         int     21h                     ; Interrupt
  278.         mov     di,0Ah                  ; Address
  279.         lea     si,EMSid                ; If Name
  280.         mov     cx,8                    ; 'EMMXXXX0'
  281.         rep     cmpsb                   ; Is NOT Found
  282.         push    cs                      ; After Extra Segment
  283.         pop     es                      ; Register is Restored
  284.         jne     EndEMS                  ; Then NO EMS
  285.         mov     di,emsmap               ; Else Point to
  286.         add     di,100h                 ; Next Map Area
  287.         mov     ah,4Dh                  ; Get Current
  288.         int     67h                     ; Handle Map
  289.         or      ah,ah                   ; If Function Fails
  290.         jnz     EndEMS                  ; Then EMS Broken
  291.         mov     si,emscnt               ; Else If [F]Mark
  292.         lodsw                           ; Handle Count Is
  293.         mov     cx,bx                   ; Not Less Than
  294.         cmp     ax,bx                   ; Current Count
  295.         jnc     EndEMS                  ; Then EMS NOT Used
  296.  
  297. EMSHlp: mov     dx,es:[di]              ; Else Compare
  298.         cmpsw                           ; Maps and Release
  299.         cmpsw                           ; Handle(s) NOT in
  300.         je      lpEMSH                  ; [F]Mark Map Using
  301.         mov     ah,45h                  ; Deallocate Handle
  302.         int     67h                     ; EMS Function
  303.         or      ah,ah                   ; If Ok AND More
  304. lpEMSH: loopz   EMSHlp                  ; Then Continue
  305.         mov     byte ptr ErrLvl,ah      ; Else EMS Done
  306. EndEMS: mov     ax,WatchF               ; If WATCH
  307.         or      ax,ax                   ; NOT Found
  308.         jz      WatchX                  ; Then Skip
  309.         mov     es,ax                   ; Else Point
  310.         mov     di,218h                 ; short of WATCH
  311.         mov     dx,-1                   ; Vector Change Area
  312.         mov     ax,MflagA               ; Looking for [F]Mark
  313.         mov     cx,620h
  314. UCloop: add     di,8                    ; If Reach End of
  315.         cmp     di,cx                   ; Vector Change Area
  316.         jnc     WatchX                  ; Then NO Changes
  317.         cmp     es:[di],dx              ; Else If NOT PSPid
  318.         jnz     UCloop                  ; Or If PSP is NOT
  319.         cmp     es:[di+2],ax            ; PSP of [F]Mark
  320.         jnz     UCloop                  ; Then Keep Looking
  321.         mov     dx,di                   ; Else Calculate
  322.         sub     dx,220h                 ;  and store new
  323.         mov     es:[104h],dx            ; vpos offset and
  324.         xor     al,al                   ; Null-out
  325.         sub     cx,di                   ; remaining
  326.         rep     stosb                   ; Vector Change Area
  327.         mov     si,vector               ; Copy Interrupt
  328.         mov     cx,200h                 ; Vector words
  329.         mov     di,0A20h                ; Into WATCH prevv
  330.         rep     movsw                   ; Current Vector Table
  331. WatchX: push    cs                      ; Restore Extra
  332.         pop     es                      ; Segment Register
  333.         mov     di,MCBbuf               ; Prepare to Kill File(s)
  334. FileLp: push    cs                      ; Insure Data Segment
  335.         pop     ds                      ; Register in Program
  336.         mov     cx,MCBend               ; Calculate
  337.         sub     cx,di                   ; Number of
  338.         shr     cx,1                    ; Words to
  339.         mov     ax,-1                   ; Scan for Marked
  340.         repne   scasw                   ; [F]Mark Blocks
  341.         jne     CheckR                  ; Until all Done
  342.         mov     ds,es:[di-6]            ; Point to Mark
  343.         mov     si,81h                  ; Command Name
  344.         xor     bx,bx                   ; Set Pointer to
  345.         mov     bl,ds:[si-1]            ; Length of Name
  346.         xor     ch,ch                   ; Make ASCIIZ and
  347.         mov     cl,ds:[si+bx]           ; Save Previous
  348.         mov     ds:[si+bx],ch           ; Name Command End
  349.         mov     ah,41h                  ; Delete
  350.         mov     dx,82h                  ; File(s)
  351.         int     21h                     ; Restore
  352.         mov     ds:[si+bx],cl           ; Ending
  353.         jmp     short FileLp            ; Loop Until Done
  354.  
  355. CheckR: cmp     byte ptr FlagR,0        ; If Leave 8259 as is
  356.         jnz     UnMark                  ; Then Skip Procedure
  357.         call    Rst8259                 ; Else Reset 8259
  358. UnMark: mov     si,MCBend               ; Work between
  359.         sub     si,8                    ; UnMark Program
  360.         mov     bp,MCBbuf               ; and Master
  361.         add     bp,8                    ; Environment
  362. Loop49: sub     si,8                    ; If Down to Master
  363.         cmp     si,bp                   ; Environment
  364.         je      Result                  ; Then Done Releasing
  365.         mov     ax,[si]                 ; Else If NOT
  366.         inc     ax                      ; Marked for
  367.         cmp     byte ptr [si+7],0FFh    ; Release
  368.         jne     Loop49                  ; Then Loop
  369.         mov     es,ax                   ; Else If
  370.         mov     ah,49h                  ; Released
  371.         int     21h                     ; w/o error
  372.         jnc     Loop49                  ; Then Continue
  373.         mov     byte ptr ErrLvl,al      ; Else Set Error
  374.         mov     ah,9                    ;  and Display
  375.         mov     dx,offset ReleasErr     ; Error Message
  376.         int     21h
  377. Result: cmp     byte ptr ErrLvl,0       ; If NO Error
  378.         jz      SetPSP                  ; Then Continue
  379.         int     19h                     ; Else ReBoot
  380. SetPSP: push    cs                      ; Restore Extra
  381.         pop     es                      ; Segment Register
  382.         mov     di,0Ah                  ; Set PSP from
  383.         mov     si,vector               ; Vectors for
  384.         add     si,88h                  ; Interrupts
  385.         mov     cx,6                    ; 22h, 23h,
  386.         rep     movsw                   ; and 24h
  387.         mov     si,parent               ; Get Parent Word
  388.         movsw                           ; and Take Command
  389.         xor     di,di
  390.         mov     es,di                   ; Restore
  391.         mov     si,vector               ; Interrupt
  392.         mov     cx,1024                 ; Vectors
  393.         cli
  394.         rep     movsb
  395.         sti
  396.         add     di,0A8h                 ; Restore EGA
  397.         mov     cx,8                    ; Information
  398.         rep     movsb
  399.         add     di,40h                  ; Restore Inter-
  400.         mov     cx,8                    ; Communications
  401.         rep     movsw                   ; Area Information
  402.  
  403.         cmp     word ptr Stuff_BUF,1C0Dh; If Nothing to Stuff
  404.         je      Exit                    ; Then Exit
  405.         call    StufKey                 ; Else Stuff
  406.  
  407. Exit:   mov     ax,ErrLvl               ; Set Error Level
  408.         int     21h                     ; and Exit to DOS
  409. Main    EndP
  410.  
  411. Ploop   Proc
  412.         lodsb                           ; Get a Byte
  413.         cmp     di,MkParm               ; If Stuffing
  414.         jc      Stuff                   ; Then Stuff
  415.         cmp     al,"/"                  ; Else If Switch
  416.         je      Parms                   ; Then Get Parameter
  417.         cmp     al,"?"                  ; Else If Question
  418.         je      DoHelp                  ; Then Give Help
  419.         cmp     al,13                   ; Else If End Byte
  420.         je      Pexit                   ; Then Exit Parsing
  421.         cmp     al,"!"                  ; Else If Space or Below
  422.         jc      Ploop                   ; Then Ignore Character
  423.         stosb                           ; Else Store ID Name
  424.         jmp     short Ploop             ; Until [F]Mark ID ends
  425.  
  426. Parms:  lodsb                           ; Get Byte After Switch
  427.         cmp     di,MkParm               ; If NOT Stuffing
  428.         jnc     ParaQ                   ; Then Ready to Check
  429.         pop     di                      ; Else Even the Stack
  430. ParaQ:  cmp     al,"?"                  ; If Question
  431.         je      DoHelp                  ; Then Give Help
  432.         and     al,5Fh                  ; Else UP-case
  433.         cmp     al,"D"                  ; If NOT "D"eBug
  434.         jne     ParaR                   ; Then Check "R"eset
  435.         mov     byte ptr FlagD,0FFh     ; Else Set D Flag
  436. ParaR:  cmp     al,"R"                  ; If NOT "R"eset 8259
  437.         jne     ParaS                   ; Then Check Stuff
  438.         mov     byte ptr FlagR,0FFh     ; Else Set R Flag
  439. ParaS:  cmp     al,"S"                  ; If NOT "S"tuff
  440.         jne     Ploop                   ; Then Get Next Byte
  441.         push    di                      ; Else Preserve Pointer
  442.         mov     di,offset Stuff_BUF     ; While Storing Stuff
  443.         mov     cx,14                   ; Up to 14 bytes plus
  444.         jmp     short Ploop             ; Ending Carriage Return
  445. Stuff:  cmp     al,"!"                  ; If Space Or Less
  446.         jc      Sexit                   ; Or If Another
  447.         cmp     al,"/"                  ; Switch While Stuffing
  448.         je      Sexit                   ; Then Exit Stuffing
  449.         cmp     al,"a"                  ; Else Insure
  450.         jc      UCexit                  ; Alphabetic
  451.         cmp     al,"z"                  ; Characters
  452.         ja      UCexit                  ; Converted to
  453.         and     al,5Fh                  ; UPPERcase
  454. UCexit: push    cx                      ; Preserve Limit and
  455.         push    di                      ; Position in Stuff_BUF
  456.         mov     cx,NumChars             ; Set Scan Count and
  457.         mov     bx,offset ScanC_TBL     ; Indices to Scan Codes
  458.         mov     di,offset ASCII_TBL     ; Versus ASCII Codes
  459.         sub     bx,di                   ; Adjust Scan Code
  460.         repne   scasb                   ; Pointer for Position in
  461.         add     bx,di                   ; ASCII Character Table
  462.         mov     ah,[bx-1]               ; Get Scan Code and
  463.         pop     di                      ; Restore Pointer and
  464.         pop     cx                      ; Stuff Character Counter
  465.         or      ah,ah                   ; If Invalid Code
  466.         jz      Sexit                   ; Then Exit Stuffing
  467.         stosw                           ; Else Store Code/Byte
  468.         loop    Ploop                   ; Until End of Stuffing
  469. Sexit:  pop     di                      ; Even Stack and Back-Up
  470.         dec     si                      ; Input In Case of Switch
  471.         cmp     al,"/"                  ; If If End With Switch
  472.         je      Ploop                   ; Then Resume Parsing
  473.         cmp     al,13                   ; Else If End of Input
  474.         je      Pexit                   ; Then Exit Normally
  475. DoHelp: stc                             ; Else Set CY for Help
  476.  
  477. Pexit:  ret
  478. Ploop   EndP
  479.  
  480. DoFlags Proc
  481.         push    si                      ; Preserve
  482.         push    di                      ; Pointers and
  483.         push    es                      ; Segment Register
  484.         mov     bp,di                   ; Copy for Comparisons
  485.         sub     dx,di                   ; If a Program
  486.         jz      ChkPgm                  ; Then Check It
  487.         xor     dx,dx                   ; Else Zero Flags
  488. ChkRel: cmp     word ptr MflagA,0       ; If NO [F]Mark Yet
  489.         jz      ExitDF                  ; Then NO Release Flag
  490.         mov     dh,0FFh                 ; Else Mark for Release
  491. ExitDF: jmp     short DFexit
  492.  
  493. ChkPgm: mov     es,di                   ; Look in
  494.         mov     di,62h                  ; Program
  495.         mov     cx,7                    ; for ID of
  496.         mov     si,offset MarkID        ; an [F]Mark
  497.         rep     cmpsb
  498.         mov     di,81h                  ; If an [F]Mark
  499.         je      ChkMrk                  ; Then Check Name
  500.         mov     si,offset MrkMsg+8      ; Else Check for
  501.         mov     di,108h                 ; TurboPower
  502.         mov     cx,9                    ; "PARAMETER"
  503.         rep     cmpsb
  504.         mov     di,81h                  ; If TurboPower
  505.         je      ChkMrk                  ; Then Check Name
  506.         mov     cx,11                   ; Else If NOT TSR
  507.         mov     si,offset MarkID+4      ; WATCHER Name
  508.         rep     cmpsb                   ; "TSR WATCHER"
  509.         jne     ChkRel                  ; Then Check Release
  510.         mov     WatchF,bp               ; Else Store Address
  511.         jmp     short ChkRel
  512. ChkMrk: mov     dl,0FFh                 ; Flag as [F]Mark
  513.         mov     cl,es:[di-1]            ; If NO Length
  514.         jcxz    Chk4MF                  ; Then NO Protect
  515.         push    di                      ; Else Save Name
  516.         push    cx                      ;  and Length
  517.         mov     al,"!"                  ; Scan for
  518.         repne   scasb                   ; Protected
  519.         pop     cx                      ; If NOT
  520.         pop     di                      ; Protected
  521.         jne     Chk4MF                  ; Then Check Mark Flag
  522.         mov     PflagA,bp               ; Else Set Protected Flag
  523. Chk4MF: cmp     word ptr MflagA,0       ; If NO Release [F]Mark
  524.         jz      DoName                  ; Then Check This One
  525.         mov     dh,0FFh                 ; Else Mark for Release
  526.         jmp     short DFexit
  527. DoName: dec     cx                      ; Assume space
  528.         cmp     MrkLen,cx               ; If NOT length of
  529.         mov     si,MkParm               ; Parameter Name
  530.         jne     DFexit                  ; Then Check Release
  531. FNloop: inc     di                      ; Else Get
  532.         lodsb                           ; Next Byte
  533.         cmp     PflagA,bp               ; If Protected [F]Mark
  534.         jz      FNBcmp                  ; Then Compare Exact
  535.         or      al,20h                  ; Else Insure lower
  536. FNBcmp: sub     al,es:[di]              ; If Name Bytes Match
  537.         je      loopFN                  ; Then Compare Until
  538.         cmp     PflagA,bp               ; Else If Protected
  539.         jz      DFexit                  ; Then MCB Flag Exit
  540.         cmp     al,20h                  ; Else If Only Case
  541. loopFN: loope   FNloop                  ; Then Compare Until
  542.         jne     DFexit                  ; Fail or Match
  543. Match:  mov     dh,0FFh                 ; Mark [F]Mark and
  544.         mov     MflagA,bp               ; Subsequent MCBs
  545.                                         ; for Release
  546. DFexit: pop     es                      ; Restore Segment
  547.         pop     di                      ; Destination and
  548.         pop     si                      ; Source Pointers
  549.         mov     [si+bx+6],dx            ; Set MCB Flags
  550.         ret
  551. DoFlags EndP
  552.  
  553. DoDeBug Proc
  554.         push    dx                      ; Preserve Message
  555.         mov     ah,9                    ; Display
  556.         mov     cx,2                    ; two sets of
  557.         mov     dx,offset Header        ; DeBug Headers
  558. ShoHdr: int     21h
  559.         loop    ShoHdr
  560.         mov     si,MCBbuf               ; Point to Array
  561. DoMCBs: mov     cx,2                    ; Two Members
  562.         mov     dx,offset CRLF          ; per each
  563.         int     21h                     ; New Line
  564.  
  565. ShoMCB: push    cx                      ; Preserve Set Count
  566.         mov     bl,[si+1]               ; Get MCB High Byte
  567.         call    ShowVal                 ; and Display ASCII
  568.         mov     bl,[si+0]               ; Get MCB Low Byte
  569.         call    ShowVal                 ; and Display ASCII
  570.         mov     dl," "                  ; Add a Space
  571.         int     21h
  572.         mov     bl,[si+3]               ; Get Block High Byte
  573.         call    ShowVal                 ; and Display ASCII
  574.         mov     bl,[si+2]               ; Get Block Low Byte
  575.         call    ShowVal                 ; and Display ASCII
  576.         mov     dl," "                  ; Add a Space
  577.         int     21h
  578.         mov     bl,[si+5]               ; Get Length High Byte
  579.         call    ShowVal                 ; and Display ASCII
  580.  
  581.         mov     bl,[si+4]               ; Get Length Low Byte
  582.         call    ShowVal                 ; and Display ASCII
  583.         mov     dl," "                  ; Add a Space
  584.         int     21h
  585.         mov     dx,offset WatchM        ; If Watch
  586.         mov     ax,WatchF               ; PSP Block
  587.         dec     ax                      ; minus one
  588.         cmp     ax,[si]                 ; Matches MCB
  589.         je      ShoUsr                  ; Then is Watch
  590.         mov     dx,offset MrkMsg        ; Else If [F]Mark
  591.         cmp     byte ptr [si+6],0FFh    ; flag is set
  592.         je      ShoUsr                  ; Then [F]Mark
  593.         mov     dx,offset PgmMsg        ; Else If Block
  594.         mov     bx,[si+2]               ; is the next
  595.         dec     bx                      ; paragraph
  596.         cmp     bx,[si+0]               ; after MCB
  597.         je      ShoUsr                  ; Then Program
  598.         mov     dx,offset EnvMsg        ; Else Environ
  599.         cmp     bx,-1                   ; Unless
  600.         jne     ShoUsr                  ; Block is
  601.         mov     dx,offset TrapMsg       ; Trapped
  602. ShoUsr: mov     ah,9                    ; Display
  603.         int     21h                     ; User
  604.         mov     dx,offset TruMsg        ; If Marked
  605.         cmp     byte ptr [si+7],0FFh    ; for Release
  606.         je      ShoRel                  ; Then True
  607.         mov     dx,offset FalMsg        ; Else False
  608. ShoRel: int     21h                     ; Message
  609.         pop     cx                      ; Restore Counter
  610.         add     si,8                    ; If NOT at
  611.         cmp     si,MCBend               ; End of MCBs
  612.         loopne  ShoMCB                  ; Then Continue
  613.         jne     DoMCBs                  ; Until All Done
  614.         pop     DX                      ; Restore Message
  615.         ret
  616. DoDeBug EndP
  617.  
  618. ShowVal Proc
  619.         mov     cl,4                    ; Set Divisor 16
  620.         mov     ah,2                    ; for Show Byte
  621.         mov     dl,bl                   ; Copy the Byte
  622.         and     dl,0F0h                 ; Isolate High
  623.         shr     dl,cl                   ; Nibble as
  624.         add     dl,30h                  ; ASCII
  625.         cmp     dl,3Ah                  ; If Decimal
  626.         jc      SV1                     ; Then Show Dec
  627.         add     dl,7                    ; Else Show Hex
  628. SV1:    int     21h
  629.         mov     dl,bl                   ; Copy the Byte
  630.         and     dl,0Fh                  ; Isolate Low
  631.         add     dl,30h                  ; ASCII Nibble
  632.         cmp     dl,3Ah                  ; If Decimal
  633.         jc      SV2                     ; Then Show Dec
  634.         add     dl,7                    ; Else Show Hex
  635. SV2:    int     21h
  636.         ret
  637. ShowVal EndP
  638.  
  639. StufKey Proc
  640.         mov     ah,1                    ; If KeyBoard Buffer
  641.         int     16h                     ; is Clear of Keys
  642.         jz      Set_SI                  ; Then Ready to Stuff
  643.         xor     ah,ah                   ; Else Read Scan Code
  644.         int     16h                     ; Code and Character
  645.         jmp     short StufKey           ; Until Buffer Clear
  646. Set_SI: mov     si,offset Stuff_BUF     ; Point to StufString
  647.         mov     ax,40h                  ; Set Segment of
  648.         mov     es,ax                   ; Buffer and its
  649.         mov     ax,es:[80h]             ; Beginning Word
  650.         mov     di,ax                   ; As Pointers to
  651.         sub     di,4                    ; Head and Tail
  652.         cli                             ; Hold Interrupts
  653.         stosw                           ; While Initializing
  654.         mov     bp,di                   ; Key Buffer Head, Tail
  655.         stosw                           ; and Key Word Contents
  656. SKloop: lodsw                           ; Stuff Stuff_BUF Stuff
  657.         stosw                           ; Into Key Buffer and
  658.         add     word ptr es:[bp],2      ; Adjust Tail Until
  659.         cmp     ax,1C0Dh                ; Carriage
  660.         jne     SKloop                  ; Return
  661.         push    ds                      ; Restore Extra
  662.         pop     es                      ; Segment Register
  663.         sti                             ; Allow Interrupts
  664.         ret
  665. StufKey EndP
  666.  
  667. Rst8259 Proc  ; RESET THE 8259 INTERRUPT CONTROLLER CHIP - Rick Housh
  668.         push    es                      ; Point Extra Segment to
  669.         mov     ax,-1                   ; Machine ID byte at
  670.         mov     es,ax                   ; Offset 14, in ROM BIOS
  671.         mov     al,Byte Ptr es:[0Eh]    ; Store machine ID byte
  672.         pop     es                      ; PC=0FFh, XT=0FEh, AT=0FCh
  673.         cli                             ; Interrupts off
  674.         cmp     al,0FCh                 ; If ID Byte = 0FCh
  675.         jz      RstAT                   ; Then Reset AT
  676.         cmp     al,0FEh                 ; Else If NOT PC/XT
  677.         jc      RstX                    ; Then phooey on PC Jr
  678.                                         ;  and NON-Compatibles
  679. RstPC:  in      al,21h                  ; Else Get and Save
  680.         mov     ah,al                   ; Current Interrupt
  681.         mov     al,13h                  ; Mask for PC or XT
  682.         out     20h,al
  683.         jmp     short $+2               ; Delay
  684.         mov     al,8                    ; Set up main vector number
  685.         out     21h,al
  686.         jmp     short $+2
  687.         mov     al,9
  688.         out     21h,al
  689.         jmp     short $+2
  690.         mov     al,ah                   ; Restore mask and reset
  691.         out     21h,al                  ; previous interrupt state
  692.         jmp     Short RstX              ; Interrupts back on and exit
  693.  
  694. RstAT:  xor     al,al                   ; For AT, turn off any
  695.         out     0F1h,al                 ; 80287 math coprocessor
  696.         jmp     short $+2               ; Delay
  697.         in      al,21h                  ; Get current interrupt mask
  698.         mov     ah,al                   ; and save it
  699.         mov     al,11h
  700.         out     20h,al
  701.         jmp     short $+2
  702.         mov     al,8                    ; Set up main vector number
  703.         out     21h,al
  704.         jmp     short $+2
  705.         mov     al,4
  706.         out     21h,al
  707.         jmp     short $+2
  708.         mov     al,1
  709.         out     21h,al
  710.         jmp     short $+2
  711.         mov     al,ah                   ; Restore mask, reset
  712.         out     21h,al                  ; previous interrupt state
  713.         jmp     short $+2
  714.  
  715. RstSlv: in      al,0A1h                 ; For slave 8259,
  716.         mov     ah,al                   ; Get and save current Mask
  717.         mov     al,11h
  718.         out     0A0h,al
  719.         jmp     short $+2               ; Delay
  720.         mov     al,70h
  721.         out     0A1h,al
  722.         jmp     short $+2
  723.         mov     al,2
  724.         out     0A1h,al
  725.         jmp     short $+2
  726.         mov     al,1
  727.         out     0A1h,al
  728.         jmp     short $+2
  729.         mov     al,ah                   ; Restore mask, reset
  730.         out     0A1h,al                 ; previous interrupt state
  731. RstX:   sti                             ; Interrupts back on
  732.         Ret                             ; Exit
  733. Rst8259 EndP
  734. align   16
  735. buffer  equ     $
  736. Cseg    EndS
  737.         End     Main
  738.