home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c004 / 4.ddi / NETBIOS / CTSTSR.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-04-18  |  31.7 KB  |  1,257 lines

  1.     page ,132
  2.  
  3. comment !
  4.  *    netbios version of c-tree server
  5.  *    terminate/stay resident asm lang support
  6.  *
  7.  *    This program is the CONFIDENTIAL and PROPRIETARY property 
  8.  *    of FairCom(R) Corporation. Any unauthorized use, reproduction or
  9.  *    transfer of this program is strictly prohibited.
  10.  *
  11.  *      Copyright (c) 1987, 1988, 1989 FairCom Corporation
  12.  *    (Subject to limited distribution and
  13.  *     restricted disclosure only.)
  14.  *    *** ALL RIGHTS RESERVED ***
  15.  *
  16.  *    4006 West Broadway
  17.  *    Columbia, MO 65203
  18.  *
  19.  *
  20.  *    c-tree(R)    Version 4.3
  21.  *            Release C
  22.  *            February 7, 1989 17:30
  23.  *
  24. !
  25.  
  26. ;This module provides the ability to interrupt the main process
  27. ;(called user) and resume the ctree server (called task) whenever
  28. ;a netbios asynchonous command completes.
  29. ;
  30.  
  31.     extrn _disconnect:far    ;(in ctsmsg.c) undo from netbios
  32.  
  33.     include    asm.inc
  34.  
  35.  
  36.     DSEG
  37.     extrn __aintdiv:dword    ;dos's div exception vector ptr that
  38.                 ;was saved by c-runtime init code
  39.  
  40. MAXSEG = 20            ;size of _abrktb
  41.     extrn __abrktb:word    ;crt (c runtime) table of blocks
  42.                 ;alloc'd from dos
  43.     extrn __asegds:word    ;crt heaprec for malloc in DGROUP
  44.     extrn __asizds:word    ;crt size of DGROUP
  45.     extrn __psp:word    ;crt addr of program seg prefix
  46.  
  47. ifdef FPLIB
  48.     extrn __fpinit:word    ;at +2 is non 0 if fp library loaded
  49. endif
  50.     CSEG
  51.  
  52.  
  53.  
  54.     assume    ds:nothing
  55.  
  56. ;--------------------------------------------------------------------
  57. ;configuration control
  58. ;--------------------------------------------------------------------
  59. ;note: the same source module can be used for any C memory module
  60. ;(with appropiate 'far' modifiers). however it is recommended to
  61. ;assemble with a define (/D on the masm line) of one of the
  62. ;following:  SMALL or COMPACT or MEDIUM or LARGE
  63. ;example:  masm ctstsr /ml /DCOMPACT;
  64. ;--------------------------------------------------------------------
  65.  
  66.  
  67. DNCB_RETRY = 5*18        ;if an async netbios command cannot
  68.                 ;be started on first try, it is retried
  69.                 ;this many times. the retries occur on
  70.                 ;timer ticks (5*18 == try for 5 seconds)
  71.  
  72. ;comment out next to use dos default of 20 file max
  73. FID_TABLE_SZ = 255        ;up to 255 files open
  74.  
  75.  
  76. ;if FPLIB is defined, then the C floating point emulator vectors
  77. ;will be saved/restored for tasks.  Define this if necessary to
  78. ;use floating point in C code (note. float keys can be used without
  79. ;using library. see FPLIB and NO_FPLIB in C code).
  80.  
  81. ;;FPLIB = 1
  82.  
  83. ;--------------------------------------------------------------------
  84. ; program segment prefix
  85. ;--------------------------------------------------------------------
  86. ;--------------------------------------------------------------------
  87.  
  88. PSP struc
  89.   pp_int20    dw ?        ;+00 exit instruction
  90.   pp_mtop    dw ?        ; 02 paragraph past end of mem
  91.   pp_4        db ?        ; 04
  92.   pp_cpmcall    db ?        ; 05 long call opcode
  93.   pp_cpmmtop    dw ?        ; 06 long call oprand adj to look like mtop
  94.   pp_cpmcallseg    dw ?        ; 08 rest of long call
  95.   pp_i22term    dd ?        ; 0a exit to parent addr
  96.   pp_i23ctlcp    dd ?        ; 0e ctl-c trap of parent
  97.   pp_i24cerrp    dd ?        ; 12 critical err trap of parent
  98.   pp_parent    dw ?        ; 16 psp of parent
  99.   pp_fidtbl    db 20 dup (?)    ; 18 file id table
  100.   pp_envseg    dw ?        ; 2c seg of environment
  101.   pp_spsave    dw ?        ; 2e sp save while in dos or execing child
  102.   pp_sssave    dw ?        ; 30 ss save "
  103.   pp_fidtbllen    dw ?        ; 32 length of fidtbl
  104.   pp_fidtblptr    dd ?        ; 34 ptr to fidtbl
  105.   pp_shr0    dw ?        ; 38 set to ffff (used by share.exe)
  106.   pp_shr1    dw ?        ; 3a set  to ffff (used by share.exe)
  107.         db 14h dup (?)    ; 3c
  108.   pp_call50    dw ?        ; 50 old convention dos entry
  109.   pp_call50ret    db ?        ; 52
  110.         db 09h dup (?)    ; 53
  111.   pp_fcb0    db 16 dup (?)    ; 5c
  112.   pp_fcb1    db 16 dup (?)    ; 6c
  113.         db 4 dup (?)    ; 7c
  114.   pp_cmdtail    db 128 dup (?)    ; 80
  115. PSP ends
  116.  
  117. ;--------------------------------------------------------------------
  118. ;DOSSTATE structure
  119. ;--------------------------------------------------------------------
  120. ; msdos 3.x user context area - everything except current directorys
  121. ; the address of this table is obtained with DOS 5d06h call:
  122. ;        in:    ax = 5d06h
  123. ;        out:    ds:si = addr of context data
  124. ;            dx = len of context data when in_dos flag clear
  125. ;            cx = len of context data when in_dos flag set
  126. ;                 (struc of this small context is shown below)
  127. ;--------------------------------------------------------------------
  128.  
  129. DOSSTATE struc
  130.   dst_in_i24        db ?    ;00 dos is in int 24 counting flag
  131.   dst_in_dos        db ?    ;01 dos is in use counting flag
  132.   dst_wpe_drv        db ?    ;02 drive number of write prot error
  133.   dst_errloc        db ?    ;03 extended error locus
  134.   dst_err        dw ?    ;04 extended error
  135.   dst_erract        db ?    ;06 extended error suggested action
  136.   dst_errclass        db ?    ;07 extended error class
  137.   dst_errvol        dd ?    ;08 extended error volume label ptr
  138.   dst_dta        dd ?    ;0c data transfer address
  139.   dst_psp        dw ?    ;10 program segment prefix
  140.   dst_i23_sp        dw ?    ;12 sp save during int 23
  141.   dst_retcode        dw ?    ;14 dos return code
  142.   dst_defdrv        db ?    ;16 default drive
  143.   dst_breakon        db ?    ;17 check for ctl-break on/off flag
  144.                 ;18h sizeof dosstate
  145. DOSSTATE ends
  146.  
  147. ;--------------------------------------------------------------------
  148. ;CONTEXT structure
  149. ;--------------------------------------------------------------------
  150. ;this is the layout of context data saved for both the user and the
  151. ;task programs.
  152. ;--------------------------------------------------------------------
  153. ifdef FPLIB
  154. CONTEXT struc
  155.   co_ifp    dd 11 dup (?)    ;floating pt int vects 34-3e
  156.   co_i1b        dd ?    ;int 1b vector (kbd break)
  157.   co_i23        dd ?    ;int 23 vector (dos ^C)
  158.   co_i24        dd ?    ;int 24 vector (dos critical error)
  159.   co_dssz        dw ?    ;size used in next member
  160.   co_dosstate        db ?    ;buffer for psp, dta etc
  161.                 ;  (actually more than one byte long
  162.                 ;  so make sure its last in struc)
  163. CONTEXT ends
  164.  
  165. else ;(NO_FPLIB)
  166. CONTEXT struc
  167.   co_i1b        dd ?    ;int 1b vector (kbd break)
  168.   co_i23        dd ?    ;int 23 vector (dos ^C)
  169.   co_i24        dd ?    ;int 24 vector (dos critical error)
  170.   co_dssz        dw ?    ;size used in next member
  171.   co_dosstate        db ?    ;buffer for psp, dta etc
  172.                 ;  (actually more than one byte long
  173.                 ;  so make sure its last in struc)
  174. CONTEXT ends
  175. endif
  176.  
  177. ;--------------------------------------------------------------------
  178. ; netbios command block
  179. ;--------------------------------------------------------------------
  180. ;the ncb_next field is used in here to link together netbios commands
  181. ;that cannot be started right away (in case netbios runs out of
  182. ;resources)
  183. ;--------------------------------------------------------------------
  184.  
  185. NCBanr = 80h
  186. ; network command block
  187.  
  188. NCB struc
  189.   ncb_cmd        db ?    ;command code
  190.   ncb_err        db ?    ;error return
  191.   ncb_lsn        db ?    ;session id
  192.   ncb_namenum        db ?    ;name number
  193.   ncb_bufptr        dd ?    ;buffer address
  194.   ncb_buflen        dw ?    ;buffer length
  195.   ncb_rname    db 16 dup (?)    ;remote name
  196.   ncb_lname    db 16 dup (?)    ;local name
  197.   ncb_rto        db ?    ;receive timeout
  198.   ncb_sto        db ?    ;send timeout
  199.   ncb_anrptr        dd ?    ;anr entry
  200.   ncb_lana        db ?    ;adapter number
  201.   ncb_done        db ?    ;cmd complete when not ff
  202.   ncb_next        dd ?    ;* next on list
  203.   ncb_res1        dd ?    ;* 
  204.   ncb_res2    db 6 dup (?)    ;*
  205. NCB ends
  206.  
  207. ;* used only by netbios
  208.  
  209. ;--------------------------------------------------------------------
  210. ;local data
  211. ;--------------------------------------------------------------------
  212. ;all this data is in the code segment for easy addressibilty from
  213. ;int trap routines
  214. ;--------------------------------------------------------------------
  215.  
  216. ifdef DEBUG
  217.   public i08_passon,i13_passon,i21_passon,i28_passon,i2a_passon
  218.   public u_sp,u_ss,u_ctxt_ptr,t_sp,t_ss,t_ctxt_ptr
  219.   public dos_state,dctx_szsmall,dctx_szlarge
  220. ifdef FPLIB
  221.   public usefp_flag
  222. endif
  223.   public task_pending,in_task_flag
  224.   public dncb_head,dncb_retry
  225. endif
  226.  
  227. ; --- original vectors for interrupts trapped ---
  228.     even
  229. i08_passon    dd ?        ;timer tick
  230. i13_passon    dd ?        ;disk i/o
  231. i21_passon    dd ?        ;dos entry
  232. i28_passon    dd ?        ;dos idle while waiting for console
  233. i2a_passon    dd ?        ;dos idle while waiting for device (ah=84h)
  234.  
  235.  
  236. ; --- save areas for context switches ---
  237.     even
  238. u_sp        dw OTX init_ustk ;user sp save when in task context
  239. u_ss        dw seg _TEXT
  240. u_ctxt_ptr    dd ?        ;save area for user context
  241.  
  242. t_sp        dw ?        ;task sp save when in user context
  243. t_ss        dw ?
  244. t_ctxt_ptr    dd ?        ;save area for task context
  245.  
  246. dos_state    dd ?        ;pointer to dos variables
  247. dctx_szsmall    dw ?        ;size of dos variables for context sw.
  248.                 ;  when dos not busy or int 28 task switch
  249.                 ;  typically 24 bytes
  250. dctx_szlarge    dw ?        ;size of dos variables for context sw.
  251.                 ;  when int 2a, ah=84 task switch
  252.                 ;  typically some 2k bytes
  253.  
  254. ifdef FPLIB
  255. usefp_flag    dw 0        ;set to one if fp library loaded
  256. endif
  257.  
  258. ; --- task switch control ---
  259.     even
  260. task_pending    dw 0        ;task event happened
  261. in_task_flag    dw 0        ;task is active
  262. task_inhib_flags dw 0        ;bits set to inhibit task activate
  263. had_i2a84    dw 0        ;counts how many times int 24, ah=84h
  264.                 ;occurred since last netbios event. DOS
  265.                 ;issues this when it is polling a char
  266.                 ;device and dos can be safely interrupted,
  267.                 ;however, large DOS data area has to be
  268.                 ;saved. therefore this counter inhibits
  269.                 ;switching in case an int 28 (smaller save)
  270.                 ;comes along
  271. timeout        dw 0        ;clock tick downcounter schedules task on 0
  272. had_timeout    dw 0        ;had timeout flag
  273.  
  274. ; --- delayed start ncbs ---
  275.     even
  276. dncb_head    dd 0        ;ncb's to be started when netbios allows it
  277. dncb_retry    dw 0        ;retry counter for delayed start ncbs
  278.  
  279.  
  280. ; --- fixed up user's stack for first call to wait_task ---
  281. ;this will go to code that does and int 21 with ax = term, stay resident
  282. ifdef DEBUG
  283.   public init_ustk, task_memsize
  284. endif
  285.     even
  286.         dw 64 dup (?)        ;slack
  287. init_ustk    dw 0            ;bx
  288.         dw 0            ;cx
  289. task_memsize    dw ?            ;dx
  290.         dw 0            ;si
  291.         dw 0            ;di
  292.         dw 0            ;bp
  293.         dw seg _TEXT        ;ds
  294.         dw seg _TEXT        ;es
  295.         dw OTX go_tsr        ;near ret
  296.  
  297.  
  298. ;
  299. ;replacement file-id so dos can open more than 20 files
  300. ;
  301.  
  302. ifdef FID_TABLE_SZ
  303.   ifdef DEBUG
  304.    public fid_table
  305.   endif
  306. fid_table    db FID_TABLE_SZ dup (0ffh)
  307. endif
  308.  
  309.  
  310. ;--------------------------------------------------------------------
  311. ;UCOUNT do_nb(NCB far *)
  312. ;--------------------------------------------------------------------
  313. ;this is called from ctnbios to issue command to netbios. if the
  314. ;command cannot be started, then it will be reissued periodically
  315. ;from timer tick trap.
  316. ;--------------------------------------------------------------------
  317.  
  318.     public    _do_nb
  319. _do_nb proc far
  320.     push    bp
  321.     mov    bp,sp
  322.     les    bx,[bp+6]        ;es:bx -> ncb
  323.     int    5ch            ;call netbios
  324.     or    al,al
  325.     jz    ast4            ;if no immed err
  326.     test    es:[bx].ncb_cmd,NCBanr
  327.     jz    ast4            ;if not a nowait cmd
  328.     cmp    es:[bx].ncb_cmd,0ffh
  329.     jz    ast4            ;if just an install check
  330.     mov    es:[bx].ncb_done,0ffh    ;simulate cmd in progress
  331.     mov    es:[bx].ncb_err,0ffh
  332.     mov    WO es:[bx].ncb_next,0    ;put on can't start list
  333.     mov    WO es:[bx].ncb_next + 2,0
  334.     PUSHM    <ds,si>
  335.     cli
  336.     lds    si,cs:dncb_head
  337.     mov    ax,ds
  338.     or    ax,si
  339.     jnz    ast1
  340.     mov    WO cs:dncb_head,bx    ;list is empty so put at top
  341.     mov    WO cs:dncb_head + 2,es
  342.     mov    dncb_retry,DNCB_RETRY
  343.     jmp    ast3            ;return success
  344. ast1:    mov    ax,WO [si].ncb_next
  345.     or    ax,WO [si].ncb_next+2
  346.     jz    ast2            ;found end
  347.     lds    si,[si].ncb_next    ;keep looking
  348.     jmp    ast1
  349. ast2:    mov    WO [si].ncb_next,bx    ;put on end
  350.     mov    WO [si].ncb_next + 2,es
  351. ast3:    sti
  352.     POPM    <si,ds>
  353.     xor    ax,ax            ;return success
  354. ast4:    mov    ah,0            ;success (if nowait) or err code
  355.     pop    bp
  356.     ret
  357. _do_nb endp
  358.  
  359. ;--------------------------------------------------------------------
  360. ;chk_ancb_start
  361. ;--------------------------------------------------------------------
  362. ;called from timer tick trap to see if any ncb's are on can't start
  363. ;list.  if any are on the list, a start is attempted.  eventually
  364. ;a timeout will occur and then the command complete will be simulated
  365. ;with error sts.
  366. ;--------------------------------------------------------------------
  367.  
  368. ifdef DEBUG
  369.   public chk_ancb_start
  370. endif
  371.  
  372. chk_ancb_start:
  373.     PUSHM    <ax,bx,es>
  374. cas1:    les    bx,cs:dncb_head
  375.     mov    ax,es
  376.     or    ax,bx
  377.     jz    cas4                ;if list empty
  378.     mov    ax,WO es:[bx].ncb_next        ;remove 1st
  379.     mov    WO cs:dncb_head,ax
  380.     mov    ax,WO es:[bx].ncb_next + 2
  381.     mov    WO cs:dncb_head + 2,ax
  382.     int    5ch                ;try to start
  383.     or    al,al
  384.     jnz    cas2                ;if no luck
  385.     mov    cs:dncb_retry,DNCB_RETRY    ;good, restart timeout
  386.     jmp    cas1                ;try to start another
  387. cas2:    dec    cs:dncb_retry            ;check timeout
  388.     jnz    cas3                ;if not timeout
  389.     pushf
  390.     cli
  391.     call    es:[bx].ncb_anrptr        ;command complete
  392.     mov    cs:dncb_retry,1            ;fail the rest
  393.     jmp    cas1
  394.  
  395. cas3:    mov    es:[bx].ncb_done,0ffh        ;no timeout, requeue
  396.     mov    es:[bx].ncb_err,0ffh
  397.     mov    ax,WO cs:dncb_head
  398.     mov    WO es:[bx].ncb_next,ax
  399.     mov    ax,WO cs:dncb_head + 2
  400.     mov    WO es:[bx].ncb_next + 2,ax
  401. cas4:    POPM    <es,bx,ax>
  402.     ret
  403.  
  404.  
  405. ;--------------------------------------------------------------------
  406. ;misc dos traps
  407. ;--------------------------------------------------------------------
  408. ;these are set during task (server) context
  409. ;i24 (critical err) just causes dos call to fail
  410. ;i23 (ctl-brk dos) don't let user trap get control
  411. ;i1b (ctl-brk bios) "    "   "    "    "    "
  412. ;
  413. ;note: during heavy server activity ctl-brks may get lost.
  414. ;--------------------------------------------------------------------
  415.  
  416. ;misc default traps for task context
  417.  
  418. ifdef DEBUG
  419.   public i24_trap,i1b_trap,i23_trap
  420. endif
  421.  
  422. i24_trap:
  423.     mov    al,3            ;fail the call
  424. i1b_trap:
  425. i23_trap:
  426.     iret
  427.  
  428. ;--------------------------------------------------------------------
  429. ;int 8 trap
  430. ;--------------------------------------------------------------------
  431. ;check timeout specified on call to task_wait. schedule task if
  432. ;timer runs out
  433. ;--------------------------------------------------------------------
  434.  
  435. ifdef DEBUG
  436.   public i08_trap
  437. endif
  438.  
  439. i08_trap:
  440.     pushf
  441.     call    cs:i08_passon
  442.     call    chk_ancb_start    ;service netbios cmds needing start
  443.     cmp    cs:in_task_flag,0
  444.     jnz    tk2        ;if already in task
  445.     cmp    cs:timeout,0
  446.     jz    tk1        ;if no timeout or already timed out
  447.     dec    cs:timeout
  448.     jnz    tk1        ;if didn't time out
  449.     mov    cs:had_timeout,-1 ;set flag
  450.     mov    cs:task_pending,1 ;schedule server
  451. tk1:    call    chk_dotask    ;run task if needed and possible
  452. tk2:    iret
  453.  
  454. ;--------------------------------------------------------------------
  455. ;int 13 trap
  456. ;--------------------------------------------------------------------
  457. ;inhibit task switch if user program calls bios direct
  458. ;--------------------------------------------------------------------
  459.  
  460. ifdef DEBUG
  461.   public i13_trap
  462. endif
  463.  
  464. i13_trap:
  465.     or    cs:task_inhib_flags,1
  466.     pushf
  467.     call    cs:i13_passon
  468.     pushf
  469.     and    cs:task_inhib_flags,not 1
  470.     call    chk_dotask
  471.     popf
  472.     sti
  473.     retf    2
  474.  
  475. ;--------------------------------------------------------------------
  476. ;int 21 trap
  477. ;--------------------------------------------------------------------
  478. ;during user context:
  479. ;  trapped to give more opportunities to run task when event pending
  480. ;during task context:
  481. ;  trapped to (1) force error on mem alloc's (2) clean up if task
  482. ;  terminates
  483. ;--------------------------------------------------------------------
  484.  
  485. ifdef DEBUG
  486.   public i21_trap
  487. endif
  488.  
  489. i21_trap:
  490.     cmp    cs:in_task_flag,0
  491.     jnz    dtr2            ;if server task context
  492.     ;selected calls will be passed onto dos without our ret
  493.     ;info on the stack.  In those cases we're just outta luck
  494.     ;until the next dos call
  495.     cmp    ah,0            ;terminate
  496.     jz    dtr1
  497.     cmp    ah,26h            ;build psp
  498.     jz    dtr1
  499.     cmp    ah,4bh            ;exec
  500.     jz    dtr1
  501.     ;manipulate to get user's orig flags
  502.     push    ax
  503.     push    bp
  504.     mov    bp,sp
  505.     mov    ax,[bp+8]
  506.     xchg    ax,[bp+2]
  507.     pop    bp
  508.     call    cs:i21_passon        ;perform the dos func
  509.     push    bp
  510.     mov    bp,sp
  511.     pushf
  512.     pop    WO [bp+6]        ;in case dos returned info in flags
  513.     pop    bp
  514.     call    chk_dotask
  515.     iret
  516. dtr1:    jmp    cs:i21_passon
  517. dtr2:    cmp    ah,4ch            ;terminate?
  518.     jz    killtask
  519.     cmp    ah,48h            ;alloc?
  520.     jz    dtr3
  521.     cmp    ah,4ah            ;mod alloc?
  522.     jnz    dtr1
  523. dtr3:    mov    ax,8            ;no mem dos err
  524.     xor    bx,bx
  525.     stc
  526.     sti
  527.     retf    2
  528.  
  529. ;--------------------------------------------------------------------
  530. ;killtask
  531. ;--------------------------------------------------------------------
  532. ;entered from i21_trap if server task issued dos terminate call
  533. ;unhook from ints, undo netbios connections, release all memory
  534. ;and vanish into thin air
  535. ;
  536. ;NOTE: if this is to be used with other tsr's, then they should
  537. ;be removed first if they are loaded after this.  It might also be
  538. ;possible to look at int vectors and deduce another tsr is loaded
  539. ;and, if so, not completely eliminate ourselves.
  540. ;--------------------------------------------------------------------
  541. ifdef DEBUG
  542.  public killtask, clsall
  543. endif
  544.  
  545. killtask:
  546.  
  547.     mov    ax,DGROUP
  548.     mov    ds,ax
  549.  
  550.     assume    ds:DGROUP
  551.  
  552.     ;kill netbios connections if not already done
  553.     call    _disconnect        ;in ctsmsg.c
  554.  
  555.     push    ds
  556.     assume    ds:nothing
  557.     ;unlink int traps
  558.  
  559.     lds    dx,cs:i08_passon
  560.     DOS    2508h
  561.     lds    dx,cs:i13_passon
  562.     DOS    2513h
  563.     lds    dx,cs:i21_passon
  564.     DOS    2521h
  565.     lds    dx,cs:i28_passon
  566.     DOS    2528h
  567.     lds    dx,cs:i2a_passon
  568.     DOS    252ah
  569.  
  570.     pop    ds
  571.     assume    ds:DGROUP
  572.  
  573.     ;close all open files
  574.  
  575.     mov    es,__psp
  576.     push    ds
  577.     lds    si,es:[0].pp_fidtblptr
  578.     mov    cx,es:[0].pp_fidtbllen
  579.     xor    bx,bx
  580. clsall:    cmp    BY [si+bx],0ffh
  581.     jz    cla1
  582.     DOS    3eh
  583. cla1:    inc    bx
  584.     loop    clsall
  585.     pop    ds
  586.  
  587.     ;free all memory associated with task
  588.     mov    es,__psp
  589.     mov    ax,es:[0].pp_envseg    ;env ptr
  590.     mov    es,ax
  591.     or    ax,ax
  592.     jz    kt1
  593.     DOS    49h            ;free env
  594. kt1:
  595.     lea    si,__abrktb+4        ;free all far segs
  596.     mov    cx,MAXSEG-1
  597. kt2:    mov    ax,[si+2]
  598.     or    ax,ax
  599.     jz    kt3
  600.     mov    es,ax
  601.     DOS    49h
  602.     add    si,4
  603.     loop    kt2
  604. kt3:    mov    es,__psp        ;free the main seg
  605.     DOS    49h
  606.  
  607.     ;return to interrupted thread
  608.  
  609.     mov    cs:task_pending,0
  610.     call    far ptr _task_wait        ;won't return
  611.  
  612.     assume    ds:nothing
  613.  
  614. ;--------------------------------------------------------------------
  615. ;int 28
  616. ;--------------------------------------------------------------------
  617. ;dos issues this when it is polling keyboard
  618. ;--------------------------------------------------------------------
  619.  
  620. ifdef DEBUG
  621.   public i28_trap
  622. endif
  623.  
  624. i28_trap:
  625.     cmp    cs:task_pending,0
  626.     jz    i281
  627.     cmp    cs:in_task_flag,0
  628.     jnz    i281
  629.     push    ax
  630.     call    do_task_sm
  631.     pop    ax
  632. i281:    jmp    cs:i28_passon
  633.  
  634.  
  635. ;--------------------------------------------------------------------
  636. ;int 2a
  637. ;--------------------------------------------------------------------
  638. ;dos issues this when it is polling char device.  if a task switch
  639. ;is desired from this point, a large amount of data inside dos has
  640. ;to be saved. therefore a counter is used to slow down usage in the
  641. ;hope that a int 28 will occur
  642. ;--------------------------------------------------------------------
  643.  
  644. ifdef DEBUG
  645.   public i2a_trap
  646. endif
  647.  
  648. i2a_trap:
  649.     cmp    ah,84h
  650.     jz    i2a2
  651. i2a1:    jmp    cs:i2a_passon
  652. i2a2:    cmp    cs:task_pending,0
  653.     jz    i2a1
  654.     cmp    cs:in_task_flag,0
  655.     jnz    i2a1
  656.     inc    cs:had_i2a84
  657.     cmp    cs:had_i2a84,3
  658.     jb    i2a1
  659.     push    ax
  660.     mov    ax,cs:dctx_szlarge
  661.     call    do_task
  662.     pop    ax
  663.     iret
  664.  
  665. ;--------------------------------------------------------------------
  666. ;fanrf - async netbios command completed notification
  667. ;--------------------------------------------------------------------
  668. ;all async ncbs from server have an extra word in front that is set
  669. ;to 1 by this when command completes.  task_pending flag is set in
  670. ;case system state is such that the server can't be resumed
  671. ;
  672. ;note:
  673. ; some netbios' may call this routine with the hardware int service
  674. ; routine still pending.  In this case we dont want to run the server
  675. ; because this in-service interrupt will likely block the disk controller
  676. ; interrupt. (a less-common but possible case is nested ints where another
  677. ; is higher than disk-ctrlr).
  678. ;
  679. ; if the netbios does this, then the system will still work but
  680. ; performance will be degraded.
  681. ;
  682. ; One solution is to identify the netbios hdwe interrupt and trap
  683. ; it in here.  For example for IRQ3.  add set trap in task_init and
  684. ; clear trap in killtask.
  685. ;
  686. ; i0b_trap:
  687. ;   pushf
  688. ;   call cs:i0b_passon
  689. ;   call chk_dotask      ;switch tasks when isr bit clear
  690. ;   iret
  691. ;--------------------------------------------------------------------
  692.  
  693. ;es:bx -> ncb that has a word flag in front of it
  694.     public    _fanrf
  695. _fanrf proc far
  696.     mov    WO es:[bx-2],1    ;set done flag (xncb.f)
  697.     mov    cs:had_timeout,0
  698.     inc    cs:task_pending
  699.     mov    cs:had_i2a84,0
  700.     cmp    cs:in_task_flag,0
  701.     jnz    fanr1
  702.     ;*****************
  703.     push    ax
  704.     mov    al,0bh        ;read in-service reg
  705.     out    20h,al
  706.     in    al,20h
  707.     and    al,0ffh
  708.     pop    ax
  709.     ;*****************
  710.     jnz    fanr1        ;inhibit task switch in hardware isr
  711.     call    chk_dotask
  712. fanr1:    iret
  713. _fanrf endp
  714.  
  715. ;--------------------------------------------------------------------
  716. ;clear_task_events()
  717. ;--------------------------------------------------------------------
  718. ;server calls this just prior to polling all possible events.  this
  719. ;avoids a redundant poll pass.
  720. ;--------------------------------------------------------------------
  721.  
  722.     public _clear_task_events
  723. _clear_task_events proc far
  724.     mov    cs:task_pending,0
  725.     ret
  726. _clear_task_events endp
  727.  
  728. ;--------------------------------------------------------------------
  729. ;chk_dotask
  730. ;--------------------------------------------------------------------
  731. ;called from various int traps and event processors to see if it is
  732. ;desired and possible to switch to server task
  733. ;--------------------------------------------------------------------
  734.  
  735. ifdef DEBUG
  736.   public chk_dotask
  737. endif
  738.  
  739. chk_dotask:
  740.     cmp    cs:task_pending,0
  741.     jz    cdt1            ;if no event pending
  742.     cmp    cs:in_task_flag,0
  743.     jnz    cdt1            ;if already in task
  744.     cmp    cs:task_inhib_flags,0
  745.     jnz    cdt1            ;if misc lockout flags set
  746.     PUSHM    <ds,si>
  747.     lds    si,cs:dos_state
  748.     cmp    WO [si],0
  749.     POPM    <si,ds>
  750.     jnz    cdt1            ;if user in dos, then wait till
  751.                     ;(1) user exits (2) int 28 (3) int 2a
  752.     push    ax
  753.     call    do_task_sm        ;switch, saving small part of dos vars
  754.     pop    ax
  755. cdt1:    ret
  756.  
  757. ;--------------------------------------------------------------------
  758. ;UCOUNT task_wait(timeout)
  759. ;--------------------------------------------------------------------
  760. ;called from server (ctsmsg) to wait for event.  The user process is
  761. ;resumed.  The first time this is called, the user process has been
  762. ;set up to be a tsr call to dos, which gets back to command.com
  763. ;returns -1 if event was timeout, else 0
  764. ;--------------------------------------------------------------------
  765.  
  766.     public _task_wait
  767. _task_wait proc far
  768.     push    bp
  769.     mov    bp,sp
  770.     mov    ax,[bp+6]        ;get timeout value
  771.     pop    bp
  772.     mov    cs:timeout,ax
  773.     cmp    cs:task_pending,0    ;chk if new event already queued
  774.     jz    tw1
  775.     xor    ax,ax
  776.     mov    cs:task_pending,ax
  777.     ret                ;ret right away if so
  778. tw1:
  779.     ;save server task context
  780.     PUSHM    <es,ds,bp,di,si,dx,cx,bx>
  781.     mov    t_sp,sp    ;save task's sp
  782.     mov    t_ss,ss
  783.  
  784.     les    di,cs:t_ctxt_ptr;save task's context
  785.     mov    ax,cs:dctx_szsmall
  786.     call    save_context
  787.  
  788.     ;restore user context
  789.  
  790.     lds    si,cs:u_ctxt_ptr;get user's context
  791.     call    restore_context
  792.  
  793.     cli
  794.     mov    ss,u_ss        ;user's sp restored
  795.     mov    sp,u_sp
  796.     sti
  797.     POPM    <bx,cx,dx,si,di,bp,ds,es>
  798.  
  799.     ;one last check for new event occurred
  800.     cli
  801.     cmp    cs:task_pending,0
  802.     jnz    do_task        ;got one, so switch back with ax set
  803.     mov    cs:in_task_flag,0
  804.     sti
  805. _task_wait endp
  806.     ret                ;resume trap, which will ret
  807.                     ;to int'd user
  808.  
  809. ;--------------------------------------------------------------------
  810. ;do_task and do_task_sm
  811. ;--------------------------------------------------------------------
  812. ;called when (1) in user context (2) server event pending and (3) dos
  813. ;not in use or at task-switch checkpoint
  814. ;
  815. ;this suspends the user and resumes the server task (ie, return from
  816. ;task_wait())
  817. ;--------------------------------------------------------------------
  818.  
  819. ifdef DEBUG
  820.   public do_task, do_task_sm
  821. endif
  822. do_task_sm:
  823.     mov    ax,cs:dctx_szsmall
  824. do_task:                ;ax has dos save size
  825.     mov    cs:in_task_flag,1    ;set in task context
  826.     sti
  827.     PUSHM    <es,ds,bp,di,si,dx,cx,bx> ;save user's regs
  828.     mov    cs:u_sp,sp        ;save user's sp
  829.     mov    cs:u_ss,ss
  830.     cli
  831.     mov    ss,cs:t_ss        ;restore task's stack
  832.     mov    sp,cs:t_sp
  833.     sti
  834.     les    di,cs:u_ctxt_ptr    ;save user's context
  835.     call    save_context
  836.     lds    si,cs:t_ctxt_ptr    ;restore task's context
  837.     call    restore_context
  838.     POPM    <bx,cx,dx,si,di,bp,ds,es> ;restore task's regs
  839.     xor    ax,ax
  840.     mov    cs:task_pending,ax    ;clear task pending flag
  841.     xchg    ax,cs:had_timeout    ;get had timeout for return
  842.     retf
  843.  
  844.  
  845.  
  846. ;--------------------------------------------------------------------
  847. ;save_context
  848. ;--------------------------------------------------------------------
  849. ;utility used to save current context
  850. ;in:
  851. ;    es:di = save area
  852. ;    ax is size of dos context to save
  853. ;out:
  854. ;    ax,di,si,ds destroyed
  855. ;
  856. ;--------------------------------------------------------------------
  857.  
  858. ifdef DEBUG
  859.   public save_context
  860. endif
  861.  
  862. save_context:
  863.     cld
  864.     xor    cx,cx
  865.     mov    ds,cx
  866. ifdef FPLIB
  867.     cmp    cs:usefp_flag,0        ;save fp ints if used
  868.     jnz    gc2
  869.     add    di,11*4            ;else skip fp save area
  870.     jmp    short gc3
  871. gc2:    mov    si,34h*4
  872.     mov    cx,11*2
  873.     rep    movsw
  874. gc3:
  875. endif
  876.     mov    si,1bh*4        ;get int 1b vect
  877.     movsw
  878.     movsw
  879.     mov    si,23h*4        ;get ints 23,24 vects
  880.     movsw
  881.     movsw
  882.     movsw
  883.     movsw
  884.     stosw                ;dos context save size
  885.     mov    cx,ax
  886.     lds    si,cs:dos_state        ;get dos user context
  887.     shr    cx,1
  888.     rep    movsw
  889.     jnc    gc1
  890.     movsb
  891. gc1:    ret
  892.  
  893. ;--------------------------------------------------------------------
  894. ;restore_context
  895. ;--------------------------------------------------------------------
  896. ;utility used to save current context
  897. ;in:
  898. ;    ds:si = save area
  899. ;out:
  900. ;    ax size of restored dos context
  901. ;    cx,di,si,es destroyed
  902. ;
  903. ;--------------------------------------------------------------------
  904.  
  905. ifdef DEBUG
  906.   public restore_context
  907. endif
  908.  
  909. restore_context:
  910.     cld
  911.     xor    ax,ax
  912.     mov    es,ax
  913. ifdef FPLIB
  914.     cmp    cs:usefp_flag,0        ;restore fp ints if used
  915.     jnz    sc2
  916.     add    si,11*4            ;else skip fp save area
  917.     jmp    short sc3
  918. sc2:    mov    di,34h*4
  919.     mov    cx,11*2
  920.     rep    movsw
  921. sc3:
  922. endif
  923.     mov    di,1bh*4        ;set int 1b vect
  924.     cli
  925.     movsw
  926.     movsw
  927.     mov    di,23h*4        ;get ints 23,24 vects
  928.     movsw
  929.     movsw
  930.     movsw
  931.     movsw
  932.     sti
  933.     lodsw                ;dos context save size
  934.     mov    cx,ax
  935.     les    di,cs:dos_state        ;set dos user context
  936.     push    [si].dst_psp        ;get psp for restore
  937.     shr    cx,1
  938.     rep    movsw
  939.     jnc    sc1
  940.     movsb
  941. sc1:    pop    cx
  942.     push    ax
  943.     push    bx
  944.     mov    ah,50h
  945.     mov    bx,cx
  946.     pushf
  947.     cli
  948.     call    cs:i21_passon
  949.     pop    bx
  950.     pop    ax
  951.     ret
  952.  
  953.  
  954. ;--------------------------------------------------------------------
  955. ;task_init(ctxtsavebufptr)
  956. ;--------------------------------------------------------------------
  957. ;called from ctsmsg to divide the system into two processes -- the
  958. ;user and the server task.  When it returns, the server task is
  959. ;running and the user is suspended.  When the server suspends, the
  960. ;user will resume at a go term/stay resident instruction, which will
  961. ;return to the shell, leaving the server in memory (the user has its
  962. ;own little stack for this exit process)
  963. ;
  964. ;for the C small and medium models, this cuts off the heap at its
  965. ;first free space.  for other models, the thing to do is link
  966. ;with /CP:1 as noted in MS C users guide
  967. ;
  968. ;the dos internal handle table is moved to a bigger area so more
  969. ;files can be opened by the server task.
  970. ;--------------------------------------------------------------------
  971.  
  972.  
  973. __savebuf = 6
  974. ifdef DEBUG
  975.   public go_tsr
  976. endif
  977.  
  978. ;the code for the initial 'user task'
  979. go_tsr:
  980.     mov    ax,3100h
  981.     int    21h
  982.  
  983.     public _task_init
  984. _task_init proc far
  985.     assume ds:DGROUP
  986.     push    bp
  987.     mov    bp,sp
  988.     push    di
  989.     push    si
  990.  
  991.     call    fxalloc        ;cut off mainseg if possible, get size of it
  992.  
  993. ifdef FPLIB
  994.     ;set flag if fp lib used
  995.     mov    ax,__fpinit+2
  996.     mov    cs:usefp_flag,ax    ;non 0 if in use
  997. endif
  998.  
  999.     push    ds
  1000.  
  1001.  
  1002.     ifdef FID_TABLE_SZ
  1003. ; set bigger file id table for dos
  1004.     mov    es,__psp
  1005.     lds    si,es:[0].pp_fidtblptr
  1006.     assume    ds:nothing
  1007.     mov    cx,es:[0].pp_fidtbllen
  1008.     cmp    cx,FID_TABLE_SZ
  1009.     jae    iti2
  1010.     mov    di,OTX fid_table
  1011.     mov    WO es:[0].pp_fidtblptr,di
  1012.     mov    WO es:[0].pp_fidtblptr+2,cs
  1013.     mov    es:[0].pp_fidtbllen,FID_TABLE_SZ
  1014.     push    cs
  1015.     pop    es
  1016.     rep    movsb            ;copy already open file ids
  1017. iti2:
  1018.     endif
  1019.  
  1020.     assume    ds:nothing
  1021.     push    cs
  1022.     pop    ds
  1023.     assume    ds:_TEXT
  1024.  
  1025. ; set ptrs to context save areas
  1026.  
  1027.     mov    ax,[bp+__savebuf+2]    ;segment
  1028.     mov    WO u_ctxt_ptr+2,ax
  1029.     mov    WO t_ctxt_ptr+2,ax
  1030.     mov    ax,[bp+__savebuf]    ;offset
  1031.     mov    WO u_ctxt_ptr,ax
  1032.     mov    bx,dctx_szlarge
  1033.     add    bx,size CONTEXT - 1
  1034.     inc    bx
  1035.     and    bx,not 1
  1036.     add    ax,bx
  1037.     mov    WO t_ctxt_ptr,ax
  1038.  
  1039. ; copy current context to user context save
  1040.  
  1041.     les    di,u_ctxt_ptr        ;save user's context
  1042.     mov    ax,dctx_szsmall
  1043.     push    ds
  1044.     call    save_context
  1045.     pop    ds
  1046.  
  1047. ; if fp lib in use, try to find a vector to an iret in dos so
  1048. ; int vectors will look cleaner (cosmetic)
  1049.  
  1050. ifdef FPLIB
  1051.     cmp    cs:usefp_flag,0
  1052.     jz    civ2
  1053.     xor    ax,ax
  1054.     mov    ds,ax
  1055.     lds    bx,ds:[3fh*4]
  1056.     mov    ax,ds
  1057.     cmp    ax,WO cs:dos_state+2
  1058.     jnz    civ2
  1059.     mov    al,[bx]        ;get ins at ds:bx
  1060.     cmp    al,0cfh        ;iretins
  1061.     jnz    civ2
  1062.     les    di,cs:u_ctxt_ptr
  1063.     add    di,co_ifp     ;fix up fp ints in saved user state
  1064.     mov    cx,11
  1065. civ1:    mov    ax,bx
  1066.     stosw
  1067.     mov    ax,ds
  1068.     stosw
  1069.     loop    civ1
  1070. civ2:
  1071. endif
  1072.  
  1073.     push    cs
  1074.     pop    ds
  1075.  
  1076. ; turn off break checking
  1077.  
  1078.     mov    dl,0
  1079.     DOS    3301h
  1080.  
  1081. ; save int vectors
  1082. it3:
  1083.     DOS    3508h
  1084.     mov    WO i08_passon,bx
  1085.     mov    WO i08_passon+2,es
  1086.     DOS    3513h
  1087.     mov    WO i13_passon,bx
  1088.     mov    WO i13_passon+2,es
  1089.     DOS    3521h
  1090.     mov    WO i21_passon,bx
  1091.     mov    WO i21_passon+2,es
  1092.     DOS    3528h
  1093.     mov    WO i28_passon,bx
  1094.     mov    WO i28_passon+2,es
  1095.     DOS    352ah
  1096.     mov    WO i2a_passon,bx
  1097.     mov    WO i2a_passon+2,es
  1098.  
  1099.     mov    cs:in_task_flag,1    ;set in task
  1100.  
  1101. ;set int vect traps
  1102.     mov    dx,OTX i08_trap
  1103.     DOS    2508h
  1104.     mov    dx,OTX i13_trap
  1105.     DOS    2513h
  1106.     mov    dx,OTX i21_trap
  1107.     DOS    2521h
  1108.     mov    dx,OTX i28_trap
  1109.     DOS    2528h
  1110.     mov    dx,OTX i2a_trap
  1111.     DOS    252ah
  1112.  
  1113.  
  1114. ;set up error traps
  1115.  
  1116.     mov    dx,OTX i1b_trap
  1117.     DOS    251bh
  1118.     mov    dx,OTX i23_trap
  1119.     DOS    2523h
  1120.     mov    dx,OTX i24_trap
  1121.     DOS    2524h
  1122. ; restore dos's div by 0 trap
  1123.     mov    ax,seg DGROUP
  1124.     mov    ds,ax
  1125.     assume    ds:DGROUP
  1126.     lds    dx,__aintdiv
  1127.     assume    ds:nothing
  1128.     DOS    2500h
  1129.     xor    ax,ax
  1130. itxit:
  1131.     pop    ds
  1132.     assume    ds:nothing
  1133.     pop    si
  1134.     pop    di
  1135.     pop    bp
  1136.     ret
  1137. _task_init endp
  1138.  
  1139. ;--------------------------------------------------------------------
  1140. ;fxalloc
  1141. ;--------------------------------------------------------------------
  1142. ;if no _fmallocs have been done, this cuts off the main data seg
  1143. ;just past last used heap space.  This works for MSC 3 and 4, and
  1144. ;probably for 5 too.
  1145. ;
  1146. ;the size of the main segment (psp to end of data seg) is saved
  1147. ;for the TSR parameter
  1148. ;--------------------------------------------------------------------
  1149.  
  1150. ifdef DEBUG
  1151.  public fxalloc
  1152. endif
  1153.     assume    ds:DGROUP
  1154. fxalloc:
  1155.     cmp    __abrktb+6,0    ;_abrktb[1].sg
  1156.     jnz    fx6
  1157.     mov    si,__asegds+0    ;_asegds.bottom
  1158.     or    si,si
  1159.     jnz    fx1
  1160.     mov    di,__abrktb    ;__abrktb[0].sz
  1161.     jmp    fx5a        ;make di end of dseg
  1162. fx1:    mov    __asegds+2,si    ;_asegds.roveroff
  1163.     xor    di,di
  1164. fx2:    mov    ax,[si]
  1165.     cmp    ax,0fffeh
  1166.     jz    fx4
  1167.     test    ax,1
  1168.     jnz    fx3
  1169.     mov    di,si        ;last alloc'd block found
  1170. fx3:    and    ax,not 1
  1171.     add    si,ax
  1172.     add    si,2
  1173.     jmp    fx2
  1174. fx4:    or    di,di
  1175.     jnz    fx5
  1176.     mov    di,__abrktb
  1177.     mov    WO [di],1    ;dummy free block
  1178. fx5:    mov    ax,[di]
  1179.     and    ax,not 1
  1180.     add    di,ax
  1181.     add    di,2
  1182.     mov    WO [di],0fffeh
  1183.     add    di,2
  1184.  
  1185.     mov    __asegds+6,di    ;_asegds.top
  1186.     mov    __abrktb,di    ;_abrktb[0].sz
  1187. fx5a:
  1188.     mov    __asizds,di
  1189.  
  1190.     mov    ax,di
  1191.     add    ax,15
  1192.     rcr    ax,1
  1193.     mov    cl,3
  1194.     shr    ax,cl
  1195.     mov    es,__psp
  1196.     mov    bx,ds
  1197.     add    ax,bx
  1198.     mov    es:[0].pp_mtop,ax
  1199.     DOS    4ah
  1200.  
  1201. fx6:    mov    bx,__psp
  1202.     mov    es,bx
  1203.     mov    ax,es:[0].pp_mtop    ;get main seg size
  1204.     sub    ax,bx
  1205.     mov    cs:task_memsize,ax
  1206.     ret
  1207.     assume    ds:nothing
  1208.  
  1209. ;--------------------------------------------------------------------
  1210. ;UCOUNT task_preinit()
  1211. ;--------------------------------------------------------------------
  1212. ;this returns the size of a buffer needed at task_init() time.
  1213. ;0 is returned if not dos 3
  1214. ;--------------------------------------------------------------------
  1215.  
  1216.  
  1217. ; get adr, len of dos data for context switches
  1218. ;returns length of area to be alloc'd
  1219. ; or NULL if bad dos ver
  1220.  
  1221.     public _task_preinit
  1222. _task_preinit proc far
  1223.     push    bp
  1224.     mov    bp,sp
  1225.     push    di
  1226.     push    si
  1227. ; check dos version
  1228.  
  1229.     DOS    30h
  1230.     cmp    al,3
  1231.     jz    tpi1
  1232.     xor    ax,ax        ;return NULL for bad dos ver
  1233.     jmp    tpi2
  1234. tpi1:
  1235.     push    ds
  1236.     DOS    5d06h        ;see notes in struc section
  1237.     mov    ax,ds
  1238.     pop    ds
  1239.     mov    WO cs:dos_state,si
  1240.     mov    WO cs:dos_state+2,ax
  1241.     mov    cs:dctx_szsmall,dx
  1242.     mov    cs:dctx_szlarge,cx
  1243.     mov    ax,cx
  1244.     add    ax,size CONTEXT - 1
  1245.     inc    ax
  1246.     and    ax,not 1
  1247.     shl    ax,1
  1248. tpi2:    pop    si
  1249.     pop    di
  1250.     pop    bp
  1251.     ret
  1252. _task_preinit endp
  1253.  
  1254.  
  1255.     END_MOD
  1256.     end
  1257.