home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / n / netbtime.zip / TIMESEND.ASM < prev    next >
Assembly Source File  |  1993-03-09  |  25KB  |  518 lines

  1.                 TITLE   TIMESEND
  2.                 PAGE    65,132
  3. ;╔═══════════════════════════════════════════════════════════════════════════╗
  4. ;║      TIMESEND -- A TSR to Broadcast Time Periodically Via NETBIOS         ║
  5. ;║                                                                           ║
  6. ;║     I am the original author of this work and hereby place it into        ║
  7. ;║     the public domain.  If your conscience bothers you, please feel       ║
  8. ;║     free to send me $25.00 so that I may provide more such goodies.       ║
  9. ;║                                                                           ║
  10. ;║     NOTE:  This source code was written to be assembled with OPTASM.      ║
  11. ;║            Phase errors and near jump problems will surely occur if       ║
  12. ;║            MASM is used.  Also, this program must be constructed as       ║
  13. ;║            a .COM file.                                                   ║
  14. ;║                                                                           ║
  15. ;║     Programmer ...... George W. Mays                                      ║
  16. ;║     Date ............ February, 1993                                      ║
  17. ;║     Site ............ 3314 Prince George                                  ║
  18. ;║                       San Antonio, TX 78230                               ║
  19. ;║     Source .......... 80286 Assembler                                     ║
  20. ;║     System .......... IBM PC/AT Compatible System Under MSDOS             ║
  21. ;║                                                                           ║
  22. ;╚═══════════════════════════════════════════════════════════════════════════╝
  23.                 .286
  24. CSEG    SEGMENT PARA    PUBLIC  'CODE'
  25.  
  26.         ASSUME  CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
  27.  
  28.                 INCLUDE NETBIOS.INC 
  29.  
  30.                 ORG     100H                    ;SKIP TO END OF THE PSP
  31. ENTPT:          JMP     INITIALIZE              ;COM FILE ENTRY ALWAYS AT 100H
  32.  
  33. COPYRIGHT       DB      "TIMESEND V1.0, (C) 1993, G.W. Mays",0Ah,0Dh
  34.                 DB      "In the Public Domain.  Use Freely.",0Ah,0Dh,'$'
  35.  
  36. ;╒═══════════════════════════════════════════════════════════════════════════╕
  37. ;│ Program data area.  Buffers & Stack at end of resident code.              │
  38. ;╘═══════════════════════════════════════════════════════════════════════════╛
  39. ;
  40. ;       Data Stuff
  41. STACKSIZE       EQU     0200h                   ;Our stack size
  42. VER             DW      0                       ;DOS version as returned
  43. DOSMAJOR        DB      0                       ;DOS major version number
  44. DOSMINOR        DB      0                       ;DOS minor version number
  45. REDIRACTIVE     DB      0                       ;Redirector flag
  46. BUSYFLAG        DB      0                       ;NB request outstanding flag
  47. LASTSTATUS      DB      0                       ;Completion code from last send
  48. NAMENUM         DB      0                       ;Name Number returned by NB
  49. SAVE_SP         DW      0                       ;Stack save cells
  50. SAVE_SS         DW      0
  51. BUFF            DB      "                "      ;Data buff for NB send
  52. PREVGUY         DD      0                       ;Addr of original 1C Handler
  53. COUNTER         DW      0                       ;Tick counter
  54. NTICKS          DW      182                     ;Tick count to trip action
  55. MYNAME          DB      "TIMESERVER      "      ;My NETBIOS name
  56. THEIRNAME       DB      "TIMECLIENT      "      ;Their NETBIOS name
  57. CB              NCB     <>                      ;Our NCB             
  58.  
  59. ;╒═══════════════════════════════════════════════════════════════════════════╕
  60. ;│ Control is passed here by DOS via INT 0x1C (the Timer interrupt).         │
  61. ;╘═══════════════════════════════════════════════════════════════════════════╛
  62.  
  63. INT_1C          PROC    FAR
  64.  NOP ;          INT     3                       ;Debug or NOP
  65.                 PUSHF                           ;Save flags
  66.                 PUSH    DS              
  67.                 PUSH    AX
  68. ; Bump & Test Counter
  69.                 MOV     AX,CS                   ;Set up addressing
  70.                 MOV     DS,AX
  71.                 MOV     AX,COUNTER              ;Bump counter
  72.                 INC     AX
  73.                 MOV     COUNTER,AX      
  74.                 CMP     AX,NTICKS               ;Have we hit "NTICKS"?
  75.                 JB      RESTORE                 ;No, restore & return
  76.                 XOR     AX,AX                   ;Yes, fall thru...
  77.                 MOV     COUNTER,AX              ;Zero counter
  78. ; Time to Broadcast Date/Time
  79.                 INT     3                       ;Debug or NOP
  80.                 CLI                             ;Set our stack
  81.                 MOV     CS:SAVE_SP,SP           ;Save stack address
  82.                 MOV     SP,SS                   ;
  83.                 MOV     CS:SAVE_SS,SP
  84.                 MOV     SP,CS                   
  85.                 MOV     SS,SP                   
  86.                 MOV     SP,OFFSET STACKTOP      ;             
  87.                 STI
  88.                 PUSHF
  89.                 PUSH    ES                      ;Save registers
  90.                 PUSH    DS
  91.                 PUSH    DI
  92.                 PUSH    SI
  93.                 PUSH    DX
  94.                 PUSH    CX
  95.                 PUSH    BX
  96.                 PUSH    AX
  97. ; The Reason We Came ----------------------------
  98.                 CALL    DOTIME                  ;Get & send date & time
  99. ; -----------------------------------------------
  100.                 POP     AX
  101.                 POP     BX                      ;Restore registers
  102.                 POP     CX
  103.                 POP     DX
  104.                 POP     SI
  105.                 POP     DI
  106.                 POP     DS
  107.                 POP     ES
  108.                 POPF
  109.                 CLI
  110.                 MOV     SP,CS:SAVE_SS           ;Restore stack address
  111.                 MOV     SS,SP                   
  112.                 MOV     SP,CS:SAVE_SP
  113.                 STI
  114. RESTORE:
  115.                 POP     AX                      ;Restore registers
  116.                 POP     DS
  117.                 POPF                            ;Restore flags and
  118.                 JMP     CS:[PREVGUY]            ; percolate the call
  119. INT_1C          ENDP
  120.  
  121.  
  122. ;╒═══════════════════════════════════════════════════════════════════════════╕
  123. ;│ Get date & time from BIOS; pack 'em up & ship 'em out....                 │
  124. ;╘═══════════════════════════════════════════════════════════════════════════╛
  125.                                                                       
  126. DOTIME          PROC    NEAR 
  127.                 MOV     AL,BUSYFLAG             ;Test for request already
  128.                 OR      AL,AL                   ; in progress....
  129.                 JZ      NOTBUSY 
  130.                 RET                             ;Just skip this time thru
  131. NOTBUSY:
  132.                 MOV     BUFF+00h,'D'            ;Format our packet
  133.                 MOV     BUFF+01h,'/'            ;It starts with "D/T"
  134.                 MOV     BUFF+02h,'T'
  135.                 MOV     BUFF+03h,00h
  136.                 MOV     AH,04h                  ;Get date
  137.                 INT     1Ah                     ;From the BIOS (AT or PS/2)
  138.                 MOV     AX,CX                   ;Start forming checksum
  139.                 ADD     AX,DX
  140.                 MOV     BUFF+04h,CH             ;Century (in packed decimal)
  141.                 MOV     BUFF+05h,CL             ;Year
  142.                 MOV     BUFF+06h,DH             ;Month
  143.                 MOV     BUFF+07h,DL             ;Day
  144.                 PUSH    AX                      ;Save checksum accumulator
  145.                 MOV     AH,02h                  ;Get time
  146.                 INT     1Ah                     ;From the BIOS (AT or PS/2)
  147.                 POP     AX                      ;Restore the checksum
  148.                 ADD     AX,CX                   ;Continue checksumming
  149.                 ADD     AX,DX
  150.                 MOV     BUFF+08h,CH             ;Hour
  151.                 MOV     BUFF+09h,CL             ;Minutes
  152.                 MOV     BUFF+0Ah,DH             ;Seconds
  153.                 MOV     BUFF+0Bh,DL             ;Daylight Savings Flag
  154.                 MOV     BUFF+0Ch,00h
  155.                 MOV     BUFF+0Dh,AL             ;Store the checksum
  156.                 MOV     BUFF+0Eh,AH             ; 
  157.                 MOV     BUFF+0Fh,00h            ;
  158. ;
  159.                 CALL    CLEARNCB                ;Prepare NCB
  160.                 MOV     AX,CS
  161.                 MOV     DS,AX
  162.                 MOV     ES,AX
  163.                 MOV     DI,OFFSET CB.NCB_CALLNAME
  164.                 MOV     SI,OFFSET THEIRNAME     ;Call Name
  165.                 MOV     CX,16   
  166.                 CLD
  167.                 REP     MOVSB
  168.                 MOV     AH,NAMENUM              ;Name Number
  169.                 MOV     CB.NCB_NUM,AH
  170.                 MOV     CB.NCB_LENGTH,16        ;Length
  171.                 MOV     AX,CS
  172.                 MOV     ES,AX
  173.                 MOV     CB.NCB_BUFF_SEG,AX      ;Buffer Address and
  174.                 MOV     CB.NCB_POST_SEG,AX      ; Post Address
  175.                 MOV     AX,OFFSET BUFF
  176.                 MOV     CB.NCB_BUFF_OFF,AX
  177.                 MOV     AX,OFFSET NBPOST
  178.                 MOV     CB.NCB_POST_OFF,AX
  179.                                                 ;Function Code
  180.                 MOV     AL,SENDDATAGRAM+NCB_NOWAIT         
  181.                 MOV     CB.NCB_COMMAND,AL
  182.                 MOV     BUSYFLAG,AL             ;Set BUSYFLAG
  183.                 MOV     BX,OFFSET CB            ;ES:BX -> NCB
  184.                 CALL    CALLNB                  ;Call NETBIOS
  185.                 RET                             ;Return
  186. DOTIME          ENDP
  187.  
  188.  
  189. ;╒═══════════════════════════════════════════════════════════════════════════╕
  190. ;│ NBPOST Function --- NETBIOS posts us here upon SEND DATAGRAM completion.  │
  191. ;╘═══════════════════════════════════════════════════════════════════════════╛
  192.  
  193. NBPOST          PROC    NEAR
  194.                 PUSHF
  195.                 PUSH    DS                      ;Save regs
  196.                 PUSH    AX
  197.                 STI                             ;Reenable interrupts
  198.  NOP ;          INT     3                       ;Debug or NOP
  199.                 MOV     AX,CS                   ;Set DS = CS
  200.                 MOV     DS,AX
  201.                 MOV     AL,CB.NCB_RETCODE       ;Tuck away completion status
  202.                 MOV     LASTSTATUS,AL   
  203.                 MOV     BUSYFLAG,00h            ;Clear BUSYFLAG
  204.                 POP     AX                      ;Restore regs
  205.                 POP     DS
  206.                 POPF
  207.                 IRET                            ;Return from interrupt
  208. NBPOST          ENDP
  209.  
  210.  
  211. ;╒═══════════════════════════════════════════════════════════════════════════╕
  212. ;│ CLEARNCB Function --- Fill the NCB with binary zeroes.                    │
  213. ;╘═══════════════════════════════════════════════════════════════════════════╛
  214.  
  215. CLEARNCB        PROC    NEAR
  216.                 PUSHF                           ;Save regs & flags
  217.                 PUSH    ES
  218.                 PUSH    DI
  219.                 PUSH    CX
  220.                 PUSH    AX
  221.                 MOV     AX,CS
  222.                 MOV     ES,AX
  223.                 MOV     DI,OFFSET CB            ;Zero the NCB
  224.                 MOV     CX,NCB_SIZE
  225.                 XOR     AL,AL
  226.                 CLD
  227.                 REP     STOSB
  228.                 POP     AX                      ;Restore regs & flags
  229.                 POP     CX
  230.                 POP     DI
  231.                 POP     ES
  232.                 POPF
  233.                 RET
  234. CLEARNCB        ENDP
  235.  
  236.  
  237. ;╔═══════════════════════════════════════════════════════════════════════════╗
  238. ;║ CALL NETBIOS - This routine is called to send an NCB to the NETBIOS.      ║
  239. ;║     If a redirector is loaded use int 2Ah otherwise use int 5Ch.          ║
  240. ;║                                                                           ║
  241. ;║ On entry:                                                                 ║
  242. ;║     ES:BX    addr of NCB                                                  ║
  243. ;║ On exit:                                                                  ║
  244. ;║     AX       return code                                                  ║
  245. ;╚═══════════════════════════════════════════════════════════════════════════╝
  246.  
  247. CALLNB          PROC    NEAR
  248.                 CMP     REDIRACTIVE,0           ;Is a redirector active?
  249.                 JNE     THRUREDIR
  250.                 INT     5Ch
  251.                 RET
  252. THRUREDIR:
  253.                 MOV     AX,0400h
  254.                 INT     2Ah
  255.                 RET
  256. CALLNB          ENDP
  257.  
  258. ;╞═══════════════════════════════════════════════════════════════════════════╡
  259. PC              =       $                       ;End of Code, OFFSET -> PC
  260.  
  261. STACKBOT        =       PC                      ;Stack starts after I/O Buffs
  262. PC              =       PC + STACKSIZE          ; and is STACKSIZE bytes long
  263. STACKTOP        =       PC                      ;STACKTOP here since stack
  264.                                                 ; grows downward
  265. PC              =       PC + 16
  266. LASTBYTE        =       PC                      ;LASTBYTE in resident code
  267.  
  268.  
  269. ;╔═══════════════════════════════════════════════════════════════════════════╗
  270. ;║ Initialization Procedure                                                  ║
  271. ;╚═══════════════════════════════════════════════════════════════════════════╝
  272.  
  273. INITIALIZE      PROC    NEAR
  274.         ASSUME  CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;Set by loader.
  275.  NOP ;          INT     3                       ;Debug or NOP
  276.                 MOV     AX,CS
  277.                 MOV     DS,AX
  278.                 MOV     AH,9
  279.                 MOV     DX,OFFSET COPYRIGHT
  280.                 INT     21H
  281. ;╒═══════════════════════════════════════════════════════════════════════════╕
  282. ;│ Check to see that NETBIOS is active.  Check for a redirector.             │
  283. ;╘═══════════════════════════════════════════════════════════════════════════╛
  284.                 CALL    CHECKDOS                ;DOS better be 3.1 or greater
  285.                 CALL    CHKNETB                 ;See if NETBIOS is in here
  286.                 JNC     NBTHERE
  287.                 PUSH    OFFSET CS:NASTYGRAM     ;Whoa!  No NETBIOS!
  288.                 CALL    FAILPROG                ;Die.
  289. NBTHERE:     
  290.                 MOV     AH,0
  291.                 INT     2Ah                     ;Check for redirector
  292.                 MOV     REDIRACTIVE,AH
  293. ;╒═══════════════════════════════════════════════════════════════════════════╕
  294. ;│ Look for TIMESEND.DAT file.  Verify filesize.  Extract NETBIOS names.     │
  295. ;╘═══════════════════════════════════════════════════════════════════════════╛
  296.                 MOV     AH,3Dh                  ;Open file
  297.                 XOR     AL,AL
  298.                 MOV     DX,OFFSET FILENAME
  299.                 INT     21h
  300.                 JNC     FILEISOPEN              ;Good open, jump 
  301.                 MOV     AH,9                    ;Bad open
  302.                 MOV     DX,OFFSET ASSUMPTION    ;Display warning msg
  303.                 INT     21h
  304.                 JMP     ADDNBNAME               ;...and proceed.
  305. FILEISOPEN:
  306.                 MOV     HANDLE,AX
  307.                 MOV     BX,AX
  308.                 MOV     AH,42h                  ;Seek to end of file
  309.                 MOV     AL,02h
  310.                 XOR     CX,CX
  311.                 XOR     DX,DX
  312.                 INT     21h
  313.                 CMP     AX,32
  314.                 JB      SHORTFILE
  315.                 CMP     AX,35
  316.                 JA      LONGFILE
  317.                 MOV     BX,HANDLE
  318.                 MOV     AH,42h                  ;Seek to start of file
  319.                 MOV     AL,00h
  320.                 XOR     CX,CX
  321.                 XOR     DX,DX
  322.                 INT     21h
  323.                 MOV     BX,HANDLE
  324.                 MOV     AH,3Fh                  ;Read from file
  325.                 MOV     CX,32
  326.                 MOV     DX,OFFSET MYNAME
  327.                 INT     21h
  328.                 JNC     CLOSEFILE
  329.                 PUSH    OFFSET CS:READFAILED
  330.                 CALL    FAILPROG
  331. SHORTFILE:
  332.                 PUSH    OFFSET CS:FILESHORT
  333.                 CALL    FAILPROG
  334. LONGFILE:
  335.                 PUSH    OFFSET CS:FILELONG
  336.                 CALL    FAILPROG
  337. CLOSEFILE:
  338.                 MOV     BX,HANDLE
  339.                 MOV     AH,3Eh                  ;Close file
  340.                 INT     21h
  341. ;╒═══════════════════════════════════════════════════════════════════════════╕
  342. ;│ Add our name to the NETBIOS name table.                                   │
  343. ;╘═══════════════════════════════════════════════════════════════════════════╛
  344. ADDNBNAME:
  345.                 CALL    CLEARNCB                ;Zero the NCB first
  346.                 MOV     AL,ADDNAME              ;Fill in NCB fields
  347.                 MOV     CB.NCB_COMMAND,AL
  348.                 PUSH    CS
  349.                 POP     ES
  350.                 MOV     DI,OFFSET CB.NCB_NAME
  351.                 MOV     SI,OFFSET MYNAME
  352.                 MOV     CX,16   
  353.                 CLD
  354.                 REP     MOVSB
  355.                 MOV     BX,OFFSET CB
  356.                 CALL    CALLNB                  ;Call NETBIOS
  357.                 MOV     AL,CB.NCB_RETCODE
  358.                 OR      AL,AL                   ;Check status
  359.                 JZ      ADDWASOK
  360.                 PUSH    OFFSET CS:ADDFAILED     ;Whoa!  It didn't work.
  361.                 CALL    FAILPROG                ;Die.
  362. ADDWASOK:
  363.                 MOV     AL,CB.NCB_NUM           ;Grab "name number" returned
  364.                 MOV     NAMENUM,AL              ; and save it for use later.
  365. ;╒═══════════════════════════════════════════════════════════════════════════╕
  366. ;│ Get the current address of Int 1C and save (it's the timer interrupt)     │
  367. ;╘═══════════════════════════════════════════════════════════════════════════╛
  368.                 MOV     AH,35h                  ;Get Int vector
  369.                 MOV     AL,1Ch                  ;For this Int
  370.                 INT     21h                     ;Result in ES:BX
  371.         ASSUME  ES:NOTHING
  372.                 MOV     WORD PTR PREVGUY[0],BX  ;offset
  373.                 MOV     WORD PTR PREVGUY[2],ES  ;segment
  374. ;╒═══════════════════════════════════════════════════════════════════════════╕
  375. ;│ Free our environment segment to save a little space.                      │
  376. ;╘═══════════════════════════════════════════════════════════════════════════╛
  377.                 PUSH    DS
  378.                 MOV     AH,62h                  ;Get PSP address
  379.                 INT     21h                     ;
  380.                 MOV     DS,BX
  381.                 MOV     ES,DS:2Ch               ;ES<-Env Seg Addr
  382.                 MOV     AH,49h                  ;Free memory alloc
  383.                 INT     21h                     ;
  384.                 POP     DS
  385. ;╒═══════════════════════════════════════════════════════════════════════════╕
  386. ;│ Plug ourselves into DOS Timer Interrupt (Interrupt 1C).                   │
  387. ;╘═══════════════════════════════════════════════════════════════════════════╛
  388.                 PUSH    DS
  389.                 PUSH    CS
  390.                 POP     DS
  391.                 MOV     DX,OFFSET INT_1C        ;INT_1C is ISR entry
  392.                 MOV     AH,25h                  ;Set Interrupt vector
  393.                 MOV     AL,1Ch                  ; 1Ch.
  394.                 INT     21h                     ; 
  395.                 POP     DS
  396. ;╒═══════════════════════════════════════════════════════════════════════════╕
  397. ;│ Terminate and stay resident.                                              │
  398. ;╘═══════════════════════════════════════════════════════════════════════════╛
  399.                 MOV     AX,3100H
  400.                 MOV     DX,(OFFSET LASTBYTE - OFFSET CSEG + 15) SHR 4
  401.                 INT     21H
  402.  
  403. INITIALIZE      ENDP
  404.  
  405. HANDLE          DW      0
  406. FILENAME        DB      "\TIMESEND.DAT",00h
  407. NASTYGRAM       DB      "NETBIOS is NOT active on this system",0Ah,0Dh,'$'
  408. ADDFAILED       DB      "NETBIOS Add Name failed",0Ah,0Dh,'$'
  409. ASSUMPTION      DB      "Assuming TIMESERVER sends to TIMECLIENT",0Ah,0Dh,'$'
  410. FILESHORT       DB      "TIMESEND.DAT file too small to be valid",0Ah,0Dh,'$'
  411. FILELONG        DB      "TIMESEND.DAT fill too big to be valid",0Ah,0Dh,'$'
  412. READFAILED      DB      "Error reading TIMESEND.DAT",0Ah,0Dh,'$'
  413.  
  414.  
  415. ;╒═══════════════════════════════════════════════════════════════════════════╕
  416. ;│ FAILPROG  ---  Display string (terminated with "$") on console, then      │
  417. ;│                exit the program with nonzero condition code.              │
  418. ;╘═══════════════════════════════════════════════════════════════════════════╛
  419.  
  420. FAILPROG        PROC    NEAR
  421.                 PUSH    SP
  422.                 POP     BX
  423.                 MOV     DX,WORD PTR [BX+2]      ;Get offset of string
  424.                 PUSH    CS                      ;Assume offset w/in this code
  425.                 POP     DS
  426.                 MOV     AH,09h                  ;Display String function
  427.                 INT     21h                     ; of DOS
  428.                 MOV     AH,4Ch                  ;Terminate a Process func
  429.                 MOV     AL,01h                  ; of DOS
  430.                 INT     21h                     ;
  431.                 INT     20h                     ;Just to be safe....
  432. FAILPROG        ENDP
  433.  
  434.  
  435. ;╒═══════════════════════════════════════════════════════════════════════════╕
  436. ;│ CHECKDOS  ---  Get the DOS version. Bomb if < DOS 3.10.                   │
  437. ;╘═══════════════════════════════════════════════════════════════════════════╛
  438.  
  439. CHECKDOS        PROC    NEAR
  440.                 PUSH    BP                      ;Save register(s)
  441.                 MOV     BP,SP
  442.                 PUSH    CX                      
  443.                 PUSH    BX                      
  444.                 PUSH    AX
  445.                 MOV     AH,30h                  ;Get DOS Version
  446.                 INT     21h
  447.                 MOV     CS:VER,AX               ;Save results
  448.                 MOV     CS:DOSMAJOR,AL
  449.                 MOV     CS:DOSMINOR,AH
  450.                 CMP     AL,3                    ;Check major level
  451.                 JL      VERCHOKE                ;<3, VERCHOKE
  452.                 JNE     VEROK                   ;>3, VEROK     
  453.                 CMP     AH,1                    ;Check minor level for 3.x
  454.                 JGE     VEROK                   ;VEROK if 3.1 or better
  455. VERCHOKE:
  456.                 PUSH    OFFSET CS:VERMSG        ;Push offset of nastygram
  457.                 CALL    FAILPROG                ;And kiss off....
  458. VEROK:
  459.                 POP     AX                      ;Restore registers
  460.                 POP     BX
  461.                 POP     CX
  462.                 MOV     SP,BP                   ;Restore stack
  463.                 POP     BP
  464.                 RET                             ;Return to caller
  465. CHECKDOS        ENDP                
  466.  
  467. VERMSG          DB      "DOS Version MUST be 3.1 or greater$"
  468.  
  469.  
  470. ;╔═══════════════════════════════════════════════════════════════════════════╗
  471. ;║ Check For NETBIOS Installed in System                                     ║
  472. ;║ Return with CARRY SET if NOT installed                                    ║
  473. ;╚═══════════════════════════════════════════════════════════════════════════╝
  474.  
  475. CHKNETB         PROC    NEAR
  476.                 MOV     AH,35h                  ;Who's plugged into INT 5C?
  477.                 MOV     AL,5Ch
  478.                 INT     21h
  479.                 MOV     AX,ES
  480.                 CMP     AX,0000h
  481.                 JE      NOTKOSHER
  482.                 CMP     AX,0F000h
  483.                 JE      NOTKOSHER
  484. ITSPLUGGED:
  485.                 PUSH    CS
  486.                 POP     ES
  487.                 MOV     DI,OFFSET FUNKYNCB      ;Zero the NCB
  488.                 MOV     CX,NCB_SIZE
  489.                 XOR     AL,AL
  490.                 CLD
  491.                 REP     STOSB
  492.                 MOV     BX,OFFSET FUNKYNCB
  493.                 MOV     AL,0FFh
  494.                 MOV     FUNKYNCB.NCB_COMMAND,AL
  495.                 MOV     AL,00h
  496.                 INT     5Ch                     ;Check it.
  497.                 MOV     AL,FUNKYNCB.NCB_RETCODE
  498.                 CMP     AL,03h                  ;Zero ?
  499.                 JNE     NOTKOSHER               ;Yes, so not installed.
  500.                 CLC
  501.                 RET
  502. NOTKOSHER:  
  503.                 STC
  504.                 RET
  505.  
  506. FUNKYNCB        NCB     <>                      ;NCB with FUNKY command
  507.                                                 ; to test things out
  508. CHKNETB         ENDP
  509.  
  510. CSEG    ENDS
  511.  
  512.         END     ENTPT
  513.  
  514. ;╔═══════════════════════════════════════════════════════════════════════════╗
  515. ;║ End of Program --- TIMESEND                                               ║
  516. ;╚═══════════════════════════════════════════════════════════════════════════╝
  517. 
  518.