home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / packetdrivers.tar.gz / pd.tar / src / vpkt.asm < prev    next >
Assembly Source File  |  1992-02-10  |  15KB  |  650 lines

  1.     include defs.asm
  2.  
  3. ;  Copyright, 1988-9, 1990, Russell Nelson
  4. ;  Copyright, 1991, Roger F. James
  5.  
  6. ;   This program is free software; you can redistribute it and/or modify
  7. ;   it under the terms of the GNU General Public License as published by
  8. ;   the Free Software Foundation, version 1.
  9. ;
  10. ;   This program is distributed in the hope that it will be useful,
  11. ;   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ;   GNU General Public License for more details.
  14. ;
  15. ;   You should have received a copy of the GNU General Public License
  16. ;   along with this program; if not, write to the Free Software
  17. ;   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. code    segment word public
  20.     assume  cs:code, ds:code
  21.  
  22.     org 2ch
  23. phd_environ dw  ?
  24.  
  25.     org 80h
  26. phd_dioa    label   byte
  27.  
  28.     org 100h
  29. start:
  30.     jmp start_1
  31.  
  32.     even
  33.  
  34. ;Debugging stuff
  35. ;total_pkts dw  0
  36. ;gvm_pkts   dw  0
  37. ;bvm_pkts   dw  0
  38.  
  39. npacket_int_no  db  ?,?,?,?     ; interrupt to communicate.
  40.  
  41. per_handle  struc
  42. in_use      db  0       ;non-zero if this handle is in use.
  43. their_handle    dw  0       ;lower layer handle
  44. recv_handler    dd  0       ;receiver upcall.
  45. vm_id       dw  0       ;VM_ID for this handler
  46. per_handle  ends
  47.  
  48. handles     per_handle MAX_HANDLE dup(<>)
  49. end_handles label   byte
  50.  
  51.  
  52. regs    struc               ; stack offsets of incoming regs
  53. _ES dw  ?
  54. _DS dw  ?
  55. _BP dw  ?
  56. _DI dw  ?
  57. _SI dw  ?
  58. _DX dw  ?
  59. _CX dw  ?
  60. _BX dw  ?
  61. _AX dw  ?
  62. _IP dw  ?
  63. _CS dw  ?
  64. _F  dw  ?           ; flags, Carry flag is bit 0
  65. regs    ends
  66.  
  67. CY  equ 0001h
  68. EI  equ 0200h
  69.  
  70.  
  71. bytes   struc               ; stack offsets of incoming regs
  72.     dw  ?           ; es, ds, bp, di, si are 16 bits
  73.     dw  ?
  74.     dw  ?
  75.     dw  ?
  76.     dw  ?
  77. _DL db  ?
  78. _DH db  ?
  79. _CL db  ?
  80. _CH db  ?
  81. _BL db  ?
  82. _BH db  ?
  83. _AL db  ?
  84. _AH db  ?
  85. bytes   ends
  86.  
  87. their_isr   dd  0       ; original owner of pkt driver int
  88. old_isr     dd  0       ; old pkt driver int
  89. their_2f_isr    dd  0       ; original int 2f ISR
  90.  
  91. ; The following are globals that assume that the code that access them
  92. ; single threads.
  93. MAX_BUFFER_LEN  equ 1520
  94. our_buffer  db  MAX_BUFFER_LEN dup (0)
  95. buffer_flag db  0
  96. buffer_len  dw  0
  97. their_handler   dd  0       ; Recv handler to call
  98. their_bx    dw  0
  99. ;
  100. ;
  101.  
  102. vmm_running db  0       ; The 386 virtual machine manager is
  103.                     ; running
  104. our_handle  dw  0       ; Current top level handle
  105.  
  106. our_isr:
  107.     jmp our_isr_0       ;the required signature.
  108.     db  'PKT DRVR',0
  109.  
  110. our_isr_0:
  111.     assume  ds:nothing
  112.     cmp ah,2            ;Check if it one of the calls we
  113.     je  our_isr_2       ;want to intercept.
  114.     cmp ah,3
  115.     je  our_isr_2
  116.     cmp ah,5
  117.     je  our_isr_2
  118.     cmp ah,8
  119.     je  our_isr_2
  120. our_isr_1:
  121.     jmp old_isr         ;Just chain onto the original driver.
  122.  
  123. our_isr_2:
  124.     push    ax          ;We are interested in this one
  125.     push    bx          ;so save some registers and off we go.
  126.     push    cx
  127.     push    dx
  128.     push    si
  129.     push    di
  130.     push    bp
  131.     push    ds
  132.     push    es
  133.     cld
  134.     mov bx,cs           ;set up ds.
  135.     mov ds,bx
  136.     assume  ds:code
  137.     mov bp,sp           ;we use bp to access the original regs.
  138.     and _F[bp],not CY       ;start by clearing the carry flag.
  139.  
  140.     cmp ah,2            ;Jump to the function requested.
  141.     jne our_isr_3
  142.     jmp f_access_type
  143. our_isr_3:
  144.     cmp ah,3
  145.     jne our_isr_4
  146.     jmp f_release_type
  147. our_isr_4:
  148.     cmp ah,5
  149.     jne our_isr_5
  150.     jmp f_terminate
  151. our_isr_5:
  152.     jmp f_stop          ;Must be this one!
  153.  
  154. our_isr_error:
  155.     mov _DH[bp],dh
  156.     or  _F[bp],CY       ;return their carry flag.
  157. our_isr_return:
  158.     pop es
  159.     pop ds
  160.     pop bp
  161.     pop di
  162.     pop si
  163.     pop dx
  164.     pop cx
  165.     pop bx
  166.     pop ax
  167.     iret
  168.  
  169.  
  170. our_2f_isr:
  171.     assume  ds:nothing
  172.     cmp ax,1608h
  173.     jne our_2f_1
  174.     mov vmm_running,1   ;Windows has started.
  175.     jmp their_2f_isr    ;Pass it on down the chain.
  176. our_2f_1:
  177.     cmp ax,1609h
  178.     jne our_2f_2
  179.     mov vmm_running,0   ;Windows has stopped.
  180. our_2f_2:
  181.     jmp their_2f_isr    ;Pass it on down the chain.
  182.  
  183. our_handler:
  184.     cmp ax,1
  185.     je  our_handler_2   ;Second upcall
  186.                 ;Must be first upcall
  187.                 ;So check if our buffer is free
  188.     cmp buffer_flag,1
  189.     je  our_handler_1   ;Our buffer is busy
  190.     cmp cx,MAX_BUFFER_LEN
  191.     jg  our_handler_1   ;Frame to big for our buffer
  192.     mov buffer_flag,1   ;Mark our buffer busy
  193.     mov buffer_len,cx   ;Store frame length for later use
  194.     mov ax,cs
  195.     mov es,ax       ;Segment of our buffer
  196.     mov di,offset our_buffer
  197.     retf
  198.  
  199. our_handler_1:
  200.     mov ax,0        ;Tell the driver we dont want the frame
  201.     mov es,ax
  202.     mov di,0
  203.     retf
  204.  
  205. our_handler_2:          ;Second upcall
  206.     mov their_bx,bx ;Save their registers
  207.     mov dx,bx
  208.     mov bx,cs       ;Get our data segment
  209.     mov ds,bx
  210.     assume  ds:code
  211.     mov bx,offset handles
  212. our_handler_3:
  213.     cmp [bx].their_handle,dx
  214.     je  our_handler_4       ;Found their handle.
  215.     add bx,(size per_handle)    ;go to the next handle.
  216.     cmp bx,offset end_handles   ;examined all handles?
  217.     jb  our_handler_3       ;no, continue.
  218.                     ;Fall through if we cannot find it.
  219.     mov buffer_flag,0       ;Mark our buffer free
  220.     retf
  221.  
  222. our_handler_4:              ;Found the handle.
  223. ;   inc total_pkts
  224.     mov ax,[bx].recv_handler.segm
  225.     mov their_handler.segm,ax
  226.     mov ax,[bx].recv_handler.offs
  227.     mov their_handler.offs,ax
  228.     push    bx
  229.     mov ax,1683h        ;Check current VM_ID
  230.     int 2fh
  231.     mov ax,bx
  232.     pop bx
  233.     cmp ax,[bx].vm_id
  234.     je  our_handler_5       ;Correct VM is running
  235.     jmp our_handler_7       ;Wrong VM running so switch it
  236. our_handler_5:
  237. ;   inc gvm_pkts
  238.     call    pass_to_app
  239.     retf
  240.  
  241. pass_to_app:
  242.     mov ax,0            ;Set up registers for first upcall
  243.                     ;to application
  244.     mov bx,their_bx
  245.     mov cx,buffer_len
  246.     push    ds
  247.     call    their_handler
  248.     pop ds
  249.     mov ax,es
  250.     cmp ax,0
  251.     jne pass_to_app_1
  252.     cmp di,0
  253.     jne pass_to_app_1
  254.     mov buffer_flag,0   ;They dont want the frame
  255.     ret
  256. pass_to_app_1:
  257.     push    di
  258.     mov cx,buffer_len
  259.     mov si,offset our_buffer
  260.     rep movsb       ;Copy frame into apps buffer
  261.     mov ax,1        ;Set up regs for second upcall
  262.     mov bx,their_bx
  263.     mov cx,buffer_len
  264.     pop si
  265.     mov dx,es
  266.     push    ds
  267.     mov ds,dx
  268.     assume  ds:nothing
  269.     call    their_handler
  270.     pop ds
  271.     assume  ds:code
  272.     mov buffer_flag,0
  273.     ret
  274.  
  275. our_handler_7:
  276. ;   inc bvm_pkts
  277.     mov ax,1685h        ;Request switch VMs and callback
  278.     mov bx,[bx].vm_id
  279.     mov cx,0
  280.     mov dx,40h
  281.     mov si,0
  282.     push    cs
  283.     pop es
  284.     mov di,offset our_callback
  285.     int 2fh
  286.     retf
  287.  
  288.     assume ds:nothing
  289. our_callback:
  290.     push    ax
  291.     push    bx
  292.     push    cx
  293.     push    dx
  294.     push    si
  295.     push    di
  296.     push    ds
  297.     push    es
  298.     push    bp
  299.     mov ax,cs
  300.     mov ds,ax       ;Set up our ds
  301.     assume  ds:code
  302.     call    pass_to_app
  303.     pop bp
  304.     pop es
  305.     pop ds
  306.     assume  ds:nothing
  307.     pop di
  308.     pop si
  309.     pop dx
  310.     pop cx
  311.     pop bx
  312.     pop ax
  313.     iret
  314.  
  315.     assume  ds:code
  316. ;register caller of pkt TYPE
  317. f_access_type:
  318.  
  319.     mov bx,offset handles
  320. access_type_1:
  321.     cmp [bx].in_use,0       ;is this handle in use?
  322.     je  access_type_2       ;found free one
  323.     add bx,(size per_handle)    ;go to the next handle.
  324.     cmp bx,offset end_handles   ;examined all handles?
  325.     jb  access_type_1       ;no, continue.
  326.     jmp access_type_space   ;no - return error.
  327. access_type_2:
  328.     mov our_handle,bx       ;save our handle
  329.     mov [bx].in_use,1       ;remember that we're using it.
  330.     cmp vmm_running,0       ;Is VMM running
  331.     je  access_type_3       ;No, so dont bother to redirect
  332.     mov [bx].recv_handler.segm,es
  333.     mov [bx].recv_handler.offs,di
  334.     mov bx,cs
  335.     mov es,bx
  336.     mov di,offset our_handler
  337. access_type_3:
  338.     push    ds
  339.     mov bx,_DS[bp]
  340.     mov ds,bx
  341.     assume  ds:nothing
  342.     mov bx,_BX[bp]      ;restore callers registers
  343.     pushf
  344.     call    old_isr
  345.     pop ds
  346.     assume  ds:code
  347.     mov bx,our_handle
  348.     jnc access_type_4       ;it worked
  349.     mov [bx].in_use,0       ;it failed free our handle
  350.     jmp our_isr_error
  351. access_type_4:
  352.     mov [bx].their_handle,ax
  353.     mov _AX[bp],ax      ;save return handle
  354.     cmp vmm_running,0
  355.     je  access_type_5       ;Dont bother if VMM not running
  356.     push    bx
  357.     mov ax,1683h
  358.     int 2fh         ;get current VM_ID
  359.     mov ax,bx
  360.     pop bx
  361.     mov [bx].vm_id,ax
  362. access_type_5:
  363.     jmp our_isr_return
  364.  
  365. access_type_space:
  366.     mov dh,NO_SPACE
  367.     jmp our_isr_error
  368.  
  369. f_release_type:
  370.     mov bx,_BX[bp]      ;restore callers registers
  371.     pushf
  372.     call    old_isr
  373.     jnc release_type_1      ;it worked
  374.     jmp our_isr_error
  375. release_type_1:
  376.     mov ax,_BX[bp]      ;just in case
  377.     mov bx,offset handles
  378. release_type_2:
  379.     cmp [bx].their_handle,ax    ;compare handles
  380.     je  release_type_3      ;found a match
  381.     add bx,(size per_handle)    ;go to the next handle.
  382.     cmp bx,offset end_handles   ;examined all handles?
  383.     jb  release_type_2      ;no, continue.
  384.     jmp err_bad_handle      ;no - return error.
  385. release_type_3:
  386.     mov [bx].in_use,0
  387.     jmp our_isr_return
  388.  
  389. err_bad_handle:
  390.     mov dh,BAD_HANDLE
  391.     jmp our_isr_error
  392.  
  393. f_terminate:
  394.     mov bx,_BX[bp]      ;restore callers registers
  395.     pushf
  396.     call    old_isr
  397.     jnc terminate_1     ;it worked
  398.     jmp our_isr_error
  399. terminate_1:
  400.     mov ax,_BX[bp]      ;just in case
  401.     mov bx,offset handles
  402. terminate_2:
  403.     cmp [bx].their_handle,ax    ;compare handles
  404.     je  terminate_3     ;found a match
  405.     add bx,(size per_handle)    ;go to the next handle.
  406.     cmp bx,offset end_handles   ;examined all handles?
  407.     jb  terminate_2     ;no, continue.
  408.     jmp err_bad_handle      ;no - return error.
  409. terminate_3:
  410.     mov [bx].in_use,0       ; mark handle as free
  411.     mov bx,offset handles   ; check that all handles are free
  412. terminate_4:
  413.     cmp [bx].in_use,0       ; is this handle free?
  414.     jne terminate_5     ; ne = no, so can't exit completely
  415.     add bx,(size per_handle)    ; next handle
  416.     cmp bx,offset end_handles   ; examined all handles?
  417.     jb  terminate_4     ; b = no, continue examination
  418.  
  419.     mov al,npacket_int_no   ;release our_isr.
  420.     mov ah,25h
  421.     push    ds
  422.     lds dx,their_isr
  423.     int 21h
  424.     pop ds
  425.  
  426.     mov al,2fh          ;Restore 2f int
  427.     mov ah,25h          ;Just hope nobody has
  428.     push    ds          ;chained on top of us.
  429.     lds dx,their_2f_isr
  430.     int 21h
  431.     pop ds
  432.  
  433. ;
  434. ; Now free our memory
  435. ;
  436.     push    cs
  437.     pop es
  438.     mov ah,49h
  439.     int 21h
  440.     jmp our_isr_return
  441. terminate_5:
  442.     mov dh, CANT_TERMINATE
  443.     jmp our_isr_error
  444.  
  445. ; Stop the packet driver doing upcalls. Also a following terminate will
  446. ; always succed (no in use handles any longer).
  447. f_stop:
  448.     mov bx,_BX[bp]      ;restore callers registers
  449.     pushf
  450.     call    old_isr
  451.     mov bx,offset handles
  452. f_stop_2:
  453.     mov [bx].in_use,0
  454.     add bx,(size per_handle)    ; next handle
  455.     cmp bx,offset end_handles
  456.     jb  f_stop_2
  457.     clc
  458.     ret
  459.  
  460. end_resident    label   byte
  461.  
  462.     include printnum.asm
  463.     include decout.asm
  464.     include digout.asm
  465.     include chrout.asm
  466.  
  467. ;usage_msg is of the form "usage: driver [-d -n] <packet_int_no> <args>"
  468. usage_msg   label   byte
  469.  db "usage:vpkt <new_packet_int_no> <old_packet_int_no>",CR,LF,'$'
  470.  
  471. ;copyright_msg is of the form:
  472. ;"Packet driver for the foobar",CR,LF
  473. ;"Portions Copyright 19xx, J. Random Hacker".
  474. copyright_msg   label   byte
  475.  db "Virtual packet driver for Windows 3",CR,LF
  476.  db "Portions Copyright 1991 Roger F. James",CR,LF,'$'
  477.  
  478. copyleft_msg    label   byte
  479.  db "Packet driver skeleton copyright 1988-90, Russell Nelson.",CR,LF
  480.  db "This program is free software; see the file COPYING for details.",CR,LF
  481.  db "NO WARRANTY; see the file COPYING for details.",CR,LF
  482.  db CR,LF
  483. crlf_msg    db  CR,LF,'$'
  484.  
  485. location_msg    db  "Packet driver is at segment ",'$'
  486.  
  487. packet_int_no   db  ?
  488. opacket_int_no  db  ?,?,?,?
  489.  
  490. already_msg db  CR,LF,"There is already a packet driver at ",'$'
  491.  
  492. not_found_msg   db  CR,LF,"There is no packet driver at ",'$'
  493.  
  494. new_int_msg db  CR,LF,"Virtual packet driver installed on new interrupt ",'$'
  495.  
  496. old_int_msg db  "Using old interrupt ",'$'
  497.  
  498. not_found_error:
  499.     mov dx,offset not_found_msg
  500.     mov di,offset opacket_int_no
  501.     call    print_number
  502.     mov ax,4c05h
  503.     int 21h
  504.  
  505. already_error:
  506.     mov dx,offset already_msg
  507.     mov di,offset npacket_int_no
  508.     call    print_number
  509.     mov ax,4c05h        ; give errorlevel 5
  510.     int 21h
  511.  
  512. usage_error:
  513.     mov dx,offset usage_msg
  514. error:
  515.     mov ah,9
  516.     int 21h
  517.     mov ax,4c0ah        ; give errorlevel 10
  518.     int 21h
  519.  
  520. start_1:
  521.     cld
  522.  
  523.     mov dx,offset copyright_msg
  524.     mov ah,9
  525.     int 21h
  526.  
  527.     mov dx,offset copyleft_msg
  528.     mov ah,9
  529.     int 21h
  530.  
  531.     mov si,offset phd_dioa+1
  532.     call    skip_blanks     ;end of line?
  533.     cmp al,CR
  534.     je  usage_error
  535.  
  536. ;print the location we were loaded at.
  537.     mov dx,offset location_msg
  538.     mov ah,9
  539.     int 21h
  540.  
  541.     mov ax,cs           ;print cs as a word.
  542.     call    wordout
  543.  
  544.     mov dx,offset crlf_msg
  545.     mov ah,9
  546.     int 21h
  547.  
  548. chk_options:
  549.     call    skip_blanks
  550.     cmp al,'-'          ; any options?
  551.     jne no_more_opt
  552. usage_error_j_1:
  553.     jmp usage_error
  554. no_more_opt:
  555.  
  556.     mov di,offset npacket_int_no
  557.     call    get_number
  558.  
  559.     call    skip_blanks
  560.     cmp al,CR
  561.     je  usage_error
  562.     mov di,offset opacket_int_no
  563.     call    get_number
  564.  
  565.     call    skip_blanks     ;end of line?
  566.     cmp al,CR
  567.     jne usage_error
  568.  
  569.     mov al,npacket_int_no
  570.     mov packet_int_no,al
  571.     call    verify_packet_int
  572.     jnc packet_int_ok
  573.     jmp error
  574. packet_int_ok:
  575.     jne packet_int_unused
  576.     jmp already_error       ;give an error if there's one there.
  577. packet_int_unused:
  578.  
  579.     mov al,opacket_int_no
  580.     mov packet_int_no,al
  581.     call    verify_packet_int
  582.     jnc packet_int_ok_1
  583.     jmp error
  584. packet_int_ok_1:
  585.     je  packet_int_used
  586.     jmp not_found_error
  587. packet_int_used:
  588.     mov ah,35h          ;remember their packet interrupt.
  589.     mov al,opacket_int_no
  590.     int 21h
  591.     mov old_isr.offs,bx
  592.     mov old_isr.segm,es
  593.  
  594.     mov ah,35h          ;remember their 2f interrupt.
  595.     mov al,2fh
  596.     int 21h
  597.     mov their_2f_isr.offs,bx
  598.     mov their_2f_isr.segm,es
  599.  
  600.     mov ah,25h          ;install our 2f interrupt
  601.     mov dx,offset our_2f_isr
  602.     int 21h
  603.  
  604.     mov dx,offset new_int_msg
  605.     mov di,offset npacket_int_no
  606.     call    print_number
  607.     mov dx,offset old_int_msg
  608.     mov di,offset opacket_int_no
  609.     call    print_number
  610.  
  611.     call    take_packet_int
  612.  
  613.     mov ah,49h          ;free our environment, because
  614.     mov es,phd_environ      ;  we won't need it.
  615.     int 21h
  616.  
  617.     mov bx,1            ;get the stdout handle.
  618.     mov ah,3eh          ;close it in case they redirected it.
  619.     int 21h
  620.  
  621.     mov dx, offset end_resident
  622.     add dx,0fh          ;round up to next highest paragraph.
  623.     mov cl,4
  624.     shr dx,cl
  625.     mov ah,31h          ;terminate, stay resident.
  626.     mov al,0
  627.     int 21h
  628.  
  629. take_packet_int:
  630.     mov ah,35h          ;remember their packet interrupt.
  631.     mov al,npacket_int_no
  632.     int 21h
  633.     mov their_isr.offs,bx
  634.     mov their_isr.segm,es
  635.  
  636.     mov ah,25h          ;install our packet interrupt
  637.     mov dx,offset our_isr
  638.     int 21h
  639.     ret
  640.  
  641.     include verifypi.asm
  642.     include getnum.asm
  643.     include getdig.asm
  644.     include skipblk.asm
  645.     include printea.asm
  646.  
  647. code    ends
  648.  
  649.     end start
  650.