home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / COMMAND.ASM < prev    next >
Assembly Source File  |  1993-09-16  |  14KB  |  503 lines

  1. ;%    .MODEL  MEMMOD,C
  2. include asmglobal.h        
  3.     LOCALS
  4.     %MACS
  5.     .LALL
  6.  
  7.     extrn   pwait: far
  8.  
  9.     .DATA
  10.     db      4096 dup(?)
  11. cstack  label   byte
  12.  
  13.  
  14.     .CODE
  15.  
  16. dbase   dw      @Data
  17.  
  18. segoff  struc
  19. offs    dw      ?
  20. segm    dw      ?
  21. segoff  ends
  22.  
  23. main_subr       dw      ?
  24.  
  25. their_8h        dd ?
  26. their_10h       dd ?
  27. their_13h       dd ?
  28. their_1Bh       dd ?
  29. their_21h       dd ?
  30. their_23h       dd ?
  31. their_24h       dd ?
  32. their_28h       dd ?
  33.  
  34. dos_segment     dw ?                    ;segment of internal DOS flags
  35. indos_offset    dw ?                    ;offset of INDOS flag
  36. errflag_offset  dw ?                    ;offset of critical error flag
  37. program_status  db 0                    ;popup status
  38. flag_10h        db 0                    ;status of interrupt 10h
  39. flag_13h        db 0                    ;status of interrupt 13h
  40. zflag           db ?                    ;save and restore critical error.
  41. dos_version     db ?                    ;dos major version.
  42. main_countdown  db 20
  43. ss_register     dw ?                    ;SS register storage
  44. sp_register     dw ?                    ;SP register storage
  45. my_psp          dw ?                    ;our PSP.
  46. their_psp       dw ?                    ;PSP segment storage
  47.  
  48. tick_counter    dw ?
  49. indos_counter   dw ?
  50. errflag_counter dw ?
  51. status_counter  dw ?
  52. bp_counter      dw ?
  53. main_counter    dw ?
  54.  
  55.  
  56. their_dta       dd      ?
  57. ;
  58. ;------------------------------------------------------------------------------
  59. ;Interrupt 8 handling routine.
  60. ;------------------------------------------------------------------------------
  61. timer:
  62.     pushf                           ;call BIOS routine
  63.     call their_8h
  64.     inc tick_counter
  65.     cmp program_status,0            ;are we already running?
  66.     jne timer_status                ;yes, then suspend ticking.
  67.     cmp flag_10h,0                  ;video flag set?
  68.     jne timer_exit                  ;yes, then exit
  69.     cmp flag_13h,0                  ;disk flag set?
  70.     jne timer_exit                  ;yes, then exit
  71.     push es                         ;save ES and DI
  72.     push di
  73.     mov es,dos_segment              ;check INDOS flag
  74.     mov di,indos_offset
  75.     cmp byte ptr es:[di],0
  76.     jne timer_indos                 ;exit if it's set
  77.     mov di,errflag_offset           ;check critical error flag
  78.     cmp byte ptr es:[di],0
  79.     jne timer_errflag               ;exit if it's set
  80.     mov main_subr,offset cycle
  81.     call main                       ;call body of program
  82.     pop di
  83.     pop es
  84. timer_exit:
  85.     iret
  86. timer_indos:
  87.     inc indos_counter
  88.     pop di                          ;restore registers
  89.     pop es
  90.     iret
  91. timer_errflag:
  92.     inc errflag_counter
  93.     pop di                          ;restore registers
  94.     pop es
  95.     iret
  96. timer_status:
  97.     inc status_counter
  98.     iret
  99.  
  100. ;
  101. ;------------------------------------------------------------------------------
  102. ;Interrupt 10h handling routine.
  103. ;------------------------------------------------------------------------------
  104. video:
  105.     pushf                           ;push flags onto stack
  106.     inc flag_10h                    ;increment flag
  107.     call their_10h                  ;call BIOS routine
  108.     dec flag_10h                    ;decrement flag
  109.     iret
  110.  
  111. ;
  112. ;------------------------------------------------------------------------------
  113. ;Interrupt 13h handling routine.
  114. ;------------------------------------------------------------------------------
  115. my_13:
  116.     pushf                           ;push flags onto stack
  117.     inc flag_13h                    ;set 'busy' flag
  118.     call their_13h                  ;call BIOS routine
  119.     pushf                           ;save output flags
  120.     dec flag_13h                    ;clear flag
  121.     popf                            ;restore output flags
  122.     retf    2                       ;exit without destroying flags
  123.  
  124. ;
  125. ;------------------------------------------------------------------------------
  126. ;Interrupt 28h handling routine.
  127. ;------------------------------------------------------------------------------
  128. my_28:
  129.     pushf                           ;call original routine
  130.     call their_28h
  131.     inc bp_counter
  132.     cmp program_status,0            ;are we already running?
  133.     jne bp_exit                     ;yes, don't enter it again.
  134.     cmp flag_10h,0                  ;video flag set?
  135.     jne bp_exit                     ;yes, then exit
  136.     cmp flag_13h,0                  ;disk flag set?
  137.     jne bp_exit                     ;yes, then exit
  138.     push es                         ;save ES and DI
  139.     push di
  140.     mov es,dos_segment              ;check critical error flag
  141.     mov di,errflag_offset
  142.     cmp byte ptr es:[di],0
  143.     pop di                          ;clean up the stack
  144.     pop es
  145.     jne bp_errflag
  146.     mov main_subr,offset cycle
  147.     call main                       ;call main routine
  148. bp_exit:
  149.     iret                            ;done - exit
  150. bp_errflag:
  151.     inc errflag_counter
  152.     iret                            ;done - exit
  153.  
  154. ;
  155. ;------------------------------------------------------------------------------
  156. ;Interrupt 21h handling routine.
  157. ;------------------------------------------------------------------------------
  158. my_21:
  159.     pushf                           ;save the flags
  160.     or      ah,ah                   ;Doing function zero?
  161.     je      jump_to_dos             ;If yes, take the jump
  162.     cmp     ah,4bh                  ;Doing EXEC function?
  163.     je      jump_to_dos             ;If yes, take the jump
  164.     popf
  165.  
  166.     pushf
  167.     call    cs:their_21h            ;Do the DOS function
  168.  
  169.     pushf                           ;Save the result flags
  170.     cmp     cs:program_status,0     ;are we already running?
  171.     jne     no_recursion            ;yes, don't recurse.
  172.     dec     cs:main_countdown
  173.     jne     no_recursion
  174.     mov     cs:main_countdown,20
  175.     mov     main_subr,offset cycle
  176.     call    main                    ;Safe to access disk now
  177. no_recursion:
  178.     popf                            ;Recover DOS result flags
  179.  
  180.     sti                             ;Must return with interrupts on
  181.     retf    2                       ;Return with DOS result flags
  182. jump_to_dos:
  183.     popf
  184.     jmp     cs:their_21h
  185.  
  186. ;
  187. ;------------------------------------------------------------------------------
  188. ;Interrupt 24h handling routine (DOS 3.X only).
  189. ;------------------------------------------------------------------------------
  190. my_24:
  191.     mov al,3                        ;fail the call in progress
  192. ioexit:
  193.     iret                            ;give control back to DOS
  194.  
  195. cycle:
  196.     xor     ax,ax                   ;push a null pointer.
  197.     push    ax
  198.     push    ax
  199.     call    pwait
  200.     add     sp,4
  201.     ret
  202.  
  203. ;
  204. ;------------------------------------------------------------------------------
  205. ;MAIN is the routine called periodically.
  206. ;------------------------------------------------------------------------------
  207. main:
  208.     inc main_counter
  209.     mov program_status,1            ;set program active flag
  210.     cli                             ;make sure interrupts are off
  211.     mov ss_register,ss              ;save stack registers
  212.     mov sp_register,sp
  213.     mov ss,cs:dbase                 ; establish interrupt data segment
  214.     mov sp,offset cstack
  215.     sti                             ;enable interrupts
  216.     PUSHALL
  217.        ; push ax
  218.        ; push bx
  219.        ; push cx
  220.        ; push dx
  221.        ; push si
  222.        ; push di
  223.     push ds
  224.     push es
  225.        ; push bp
  226. ;
  227. ;Set DS and ES segment registers.
  228. ;
  229.     push cs                         ;set DS to code segment
  230.     pop ds
  231.     assume  ds:seg dos_version
  232. ;
  233. ;Save the current active PSP address and activate this PSP.
  234. ;
  235.     mov zflag,0                     ;clear flag
  236.     cmp dos_version,2               ;DOS version 2.X?
  237.     jne main5
  238.     mov es,dos_segment              ;point ES:DI to INDOS
  239.     mov di,indos_offset
  240.     cmp byte ptr es:[di],0          ;INDOS clear?
  241.     je main5                        ;yes, then branch
  242.     mov di,errflag_offset           ;point ES:DI to error flag
  243.     cmp byte ptr es:[di],0          ;critical error flag clear?
  244.     jne main5                       ;no, then branch
  245.     mov byte ptr es:[di],1          ;set critical error flag manually
  246.     mov zflag,1                     ;set change flag
  247. main5:
  248.     mov ah,51h                      ;get current PSP segment
  249.     int 21h
  250.     mov their_psp,bx                        ;save it
  251.  
  252.     mov ah,50h                      ;make this the active PSP
  253.     mov bx,my_psp
  254.     int 21h
  255.  
  256.     cmp zflag,0                     ;ZFLAG clear?
  257.     je main6                        ;yes, then branch
  258.     mov di,errflag_offset           ;point ES:DI to error flag
  259.     mov byte ptr es:[di],0          ;restore error flag value
  260. main6:
  261. ;
  262. ;Reset the interrupt 1Bh, 23h, and 24h vectors.
  263. ;
  264.     call ioset                      ;reset interrupt vectors
  265. ;
  266. ;Save the current dta and subdirectory
  267. ;
  268.     mov     ah,2fh                  ;get disk transfer address
  269.     int     21h
  270.     mov     their_dta.segm,es
  271.     mov     their_dta.offs,bx
  272.  
  273. ;
  274. ;Call the commutator loop of net until nothing gets queued up.
  275. ;
  276.     mov     ds,cs:dbase     ; establish interrupt data segment
  277.     assume  ds:nothing
  278.     call    main_subr
  279. ;
  280. ;Restore the current dta and subdirectory
  281. ;
  282.     lds     dx,their_dta
  283.     mov     ah,1ah
  284.     int     21h
  285.  
  286. ;
  287. ;Restore interrupt vectors and former active PSP.
  288. ;
  289.     mov ah,50h                      ;restore active PSP label
  290.     mov bx,their_psp
  291.     int 21h
  292.     call ioreset                    ;restore interrupt vectors
  293. ;
  294. ;Restore registers and stack before exit.
  295. ;
  296.        ; pop bp                          ;restore registers and exit
  297.     pop es
  298.     pop ds
  299.     POPALL
  300.        ; pop di
  301.        ; pop si
  302.        ; pop dx
  303.        ; pop cx
  304.        ; pop bx
  305.        ; pop ax
  306.     cli                             ;interrupts off
  307.     mov ss,ss_register              ;switch to original stack
  308.     mov sp,sp_register
  309.     sti                             ;interrupts on
  310.     mov program_status,0            ;clear status flag
  311.     ret
  312.  
  313. ;
  314.  
  315. intset:
  316. ;enter with al = interrupt number, cs:dx = offset of new interrupt,
  317. ;       cs:di -> place to store old interrupt.
  318.  
  319.     push    es                      ;get the old interrupt into es:bx
  320.     push    ds                      ;now set the new interrupt to ds:dx.
  321.     mov     bx,cs
  322.     mov     ds,bx
  323.  
  324.     mov     ah,35h
  325.     int     21h
  326.     mov     [di].segm,es            ;and store it into ds:di.
  327.     mov     [di].offs,bx
  328.  
  329.     mov     ah,25h
  330.     int     21h
  331.  
  332.     pop     ds
  333.     pop     es
  334.  
  335.     ret
  336.  
  337.  
  338. intreset:
  339. ;enter with al = interrupt number, di -> old interrupt.
  340.     push    ds
  341.     mov     ah,25h
  342.     lds     dx,cs:[di]
  343.     int     21h
  344.     pop     ds
  345.     ret
  346.  
  347.  
  348. ;------------------------------------------------------------------------------
  349. ;IOSET vectors interrupts 1Bh, 23h and 24h to internal handlers.  IORESET
  350. ;restores the original vector values.
  351. ;------------------------------------------------------------------------------
  352. ioset:
  353.     mov     al,1bh
  354.     mov     di,offset their_1Bh
  355.     mov     dx,offset ioexit
  356.     call    intset
  357.  
  358.     mov     al,23h
  359.     mov     di,offset their_23h
  360.     mov     dx,offset ioexit
  361.     call    intset
  362.  
  363.     mov     al,24h
  364.     mov     di,offset their_24h
  365.     mov     dx,offset my_24
  366.     call    intset
  367.  
  368.     ret
  369.  
  370. ;
  371. ioreset:
  372.     mov     al,24h
  373.     mov     di,offset their_24h
  374.     call    intreset
  375.  
  376.     mov     al,23h
  377.     mov     di,offset their_23h
  378.     call    intreset
  379.  
  380.     mov     al,1Bh
  381.     mov     di,offset their_1Bh
  382.     call    intreset
  383.  
  384.     ret
  385.  
  386.  
  387.     public  start_back
  388. start_back      proc
  389. ;
  390. ;Remember our psp.
  391. ;
  392.     mov ah,51h                      ;get current PSP segment
  393.     int 21h
  394.     mov my_psp,bx                   ;save it
  395.  
  396. ;
  397. ;Determine which version of DOS is running.
  398. ;
  399. init3:
  400.     mov ah,30h                      ;DOS function 30h
  401.     int 21h
  402.     mov dos_version,al              ;major version number
  403. ;
  404. ;Get and save the address of the INDOS flag.
  405. ;
  406.     mov ah,34h                      ;function 34h
  407.     int 21h                         ;get address
  408.     mov dos_segment,es              ;save segment
  409.     mov indos_offset,bx             ;save offset
  410. ;
  411. ;Get and save the address of the critical error flag.
  412. ;
  413.     mov ax,3E80h                    ;CMP opcode
  414.     mov cx,2000h                    ;max search length
  415.     mov di,bx                       ;start at INDOS address
  416. init4:
  417.     repne scasw                     ;do the search
  418.     jcxz init5                      ;branch if search failed
  419.     cmp byte ptr es:[di+5],0BCh     ;verify this is it
  420.     je found                        ;branch if it is
  421.     jmp init4                       ;resume loop if it's not
  422. init5:
  423.     mov cx,2000h                    ;search again
  424.     inc bx                          ;search odd addresses this time
  425.     mov di,bx
  426. init6:
  427.     repne scasw                     ;look for the opcode
  428.     jcxz notfound                   ;not found if loop expires
  429.     cmp byte ptr es:[di+5],0BCh     ;verify this is it
  430.     je found
  431.     jmp init6
  432. notfound:
  433.     xor     ax,ax
  434.     ret
  435. found:
  436.     mov ax,es:[di]                  ;get flag offset address
  437.     mov errflag_offset,ax           ;save it
  438.  
  439. ;
  440. ;Save and replace all required interrupt vectors.
  441. ;
  442.     mov     al,08h
  443.     mov     dx,offset timer
  444.     mov     di,offset their_8h
  445.     call    intset
  446.  
  447.     mov     al,10h
  448.     mov     dx,offset video
  449.     mov     di,offset their_10h
  450.     call    intset
  451.  
  452.     mov     al,13h
  453.     mov     dx,offset my_13
  454.     mov     di,offset their_13h
  455.     call    intset
  456.  
  457.     mov     al,28h
  458.     mov     dx,offset my_28
  459.     mov     di,offset their_28h
  460.     call    intset
  461.  
  462.     mov     al,21h
  463.     mov     dx,offset my_21
  464.     mov     di,offset their_21h
  465.     call    intset
  466.  
  467.     mov     ax,1
  468.     ret
  469. start_back      endp
  470.  
  471.     public  stop_back
  472. stop_back       proc
  473.     mov     cs:program_status,1
  474.  
  475.     mov     al,08h
  476.     mov     di,offset their_8h
  477.     call    intreset
  478.  
  479.     mov     al,10h
  480.     mov     di,offset their_10h
  481.     call    intreset
  482.  
  483.     mov     al,13h
  484.     mov     di,offset their_13h
  485.     call    intreset
  486.  
  487.     mov     al,28h
  488.     mov     di,offset their_28h
  489.     call    intreset
  490.  
  491.     mov     al,21h
  492.     mov     di,offset their_21h
  493.     call    intreset
  494.  
  495.     mov     cs:program_status,0
  496.  
  497.     mov dx,ds
  498.     mov ax,offset tick_counter
  499.     ret
  500. stop_back       endp
  501.  
  502.     end
  503.