        title ncontrol.asm


cseg    segment para public 'code'

        org 100h

        assume cs:cseg,ds:cseg,es:nothing



entry   proc far


su1:
  cld
  mov rqh+16,cs              ;set transfer addr seg
  call parms                 ;read command line
  call lock1                 ;send (un)lock command
  mov ah,4Ch                 ;exit to DOS
  int 21h




                   ;return codes:   0=lock set ok
                   ;                1=link did not respond
                   ;                2=network not installed properly
                   ;                3=error while attempting remote lock
                   ;                4=error while attempting local lock

entry  endp



;page
subs proc near
;........................... lock routines .................................

lock1:
  mov al,cs:LockHow          ;get (un)lock mode
  mov cs:taddr+7,al          ;will send at byte 8





;. . . . . . . . . . . . . . write lock . . . . . . . . . . . . . . . . . . . .


                             ;NULL
t01:
  mov dx,cs                  ;ds:dx--> "NET0" fcb
  mov ds,dx
  mov dx,offset nulfcb
  mov ah,0Fh                 ;open file
  int 21h
  or al,al                   ;was open ok?
  jz t2f                     ;no:   yes-->

  test cs:msgmode,1          ;are we printing messages?
  jz t2e                     ;yes:    no-->
  mov si,offset msg8         ;print "ERROR: Net0 was not found!"
  call outstr

t2e:
  stc
  mov al,2                   ;network not installed
  ret



t2f:
  mov word ptr cs:nulfcb+14,4
  mov dx,cs
  mov ds,dx
  mov dx,offset net0rd       ;set dta
  mov ah,1Ah
  int 21h

  mov dx,offset nulfcb
  mov ah,14h                 ;read file
  int 21h
  mov ah,10h                 ;close file
  int 21h

;page
;. . . . . . . . . . . . . . scan for (un)lock device . . . . . . . . . . . .


  lds si,dword ptr cs:net0rd ;ss:si--> dvc driver list


t2g:
  mov ax,word ptr cs:destname ;is this a device match?  device=destname?
  cmp word ptr [si+10],ax
  jne t2h
  mov ax,word ptr cs:destname+2
  cmp word ptr [si+12],ax
  jne t2h
  mov ax,word ptr cs:destname+4
  cmp word ptr [si+14],ax
  jne t2h
  mov ax,word ptr cs:destname+6
  cmp word ptr [si+16],ax
  je t2j                     ;no:      yes-->

t2h:
  lds si,dword ptr [si]      ;advance ptr down dvc driver list
  mov ax,ds                  ;is this end of list?
  cmp ax,0FFFFh
  je t2i
  cmp si,0FFFFh
  jne t2g                    ;yes:   no-->


t2i:
  test cs:msgmode,1          ;are we printing messages?
  jz t2ii                    ;yes:    no-->
  mov si,offset msg10        ;print "ERROR: destination device was not found!"
  call outstr

t2ii:
  stc
  mov al,2                   ;network not installed
  ret


;page
;. . . . . . . . . . . . . . (un)lock device found . . . . . . . . . . . . .

                             ;ds:si--> device header

t2j:
  mov bx,[si+6]              ;signature = db "COM"
  cmp word ptr [bx-4],"$n"   ;            db comnum  ... 0=default, 1=com1 ...
  jne t2jj                   ;            db "n$25"
  cmp word ptr [bx-2],"52"
  jne t2jj
  cmp word ptr [bx-8],"OC"   ;must be n$25 device
  jne t2jj                   ;and support com# id
  cmp byte ptr [bx-6],"M"
  jne t2jj
  mov al,[bx-5]
  test al,0F0h               ;and com# must be 0..15
  jnz t2jj
  mov ah,4                   ;if so then test for com "alive"
  push dx
  mov dx,1234h
  int 5Ch
  pop dx
  or al,al                   ;0 means network link is alive
  jz t2jj                    ;dead:       alive-->

  push cs                    ;ds=cs
  pop ds
  test cs:msgmode,1          ;are we printing messages?
  jz t2jjj                   ;yes:   no-->
  mov si,offset msg1         ;print "COMx LINK IS DEAD"
  call outstr
  mov si,offset msg3
  call outstr

t2jjj:
  mov al,1                   ;return code (1) = dead network link
  ret                        ;exit


;page

t2jj:
  push cs                    ;es:bx--> local request header
  pop es
  mov bx,offset rqh
  mov byte ptr es:[bx+2],8   ;command = write
  mov word ptr es:[bx+3],0   ;zero status
  mov ax,[si+6]              ;get strategy address
  mov cs:lcall,ax            ;form long call dword
  mov cs:lcall+2,ds
  call dword ptr cs:lcall    ;do strategy

  mov ax,[si+8]              ;get interrupt address
  mov cs:lcall,ax            ;form long call dword
  call dword ptr cs:lcall    ;do interrupt

  push cs                    ;es:bx--> request header
  pop es
  mov bx,offset rqh
  mov ax,es:[bx+3]           ;get status
  test ax,8000h              ;any errors?
  jz t4                      ;yes:   no-->
  test cs:msgmode,1          ;are we printing messages?
  jz t3                      ;yes:    no-->
  mov si,offset msg9         ;print "LOCK VIOLATION: "
  call outstr
  mov si,offset taddr        ;now print lock name
  mov byte ptr [si+7]," "    ;kill command byte in message
  call outstr


t3:
  stc
  mov al,4                   ;return code (4) = error writing local lock
  ret



t4:
  test cs:msgmode,1          ;are we printing messages?
  jz t4b                     ;yes:    no-->
  mov si,offset msg9a        ;print "LOCKED: "
  cmp byte ptr cs:LockHow,1
  je t4a
  mov si,offset msg9b        ;print "UNLOCKED: "

t4a:
  call outstr
  mov si,offset taddr        ;now print lock name
  mov byte ptr [si+7]," "    ;kill command byte in message
  call outstr

t4b:
  xor ax,ax                  ;return code = 0
  ret





;page
;........................... test for valid 5C ...............................

test5C:
  push ds                    ;ds=abs0
  xor dx,dx
  mov ds,dx
  lds si,dword ptr ds:170h   ;get vector
  mov dx,ds                  ;is 0:0?
  or dx,si
;  jnz t5Cb                  ;will be valid signature in future
;  cmp word ptr [si-4],"EN"  ;(vector-4 = "NET?")
;  jnz t5Cb
;  cmp byte ptr [si-2],"T"

t5Cb:
  pop ds
  ret

subs endp


;page
setup proc near
;........................... Get setup parameters ............................

parms:
  push cs
  pop es
  push cs
  pop ds
  xor cx,cx                  ;cx will = # of chars in line
  mov si,81h                 ;ds:si --> command line
  mov cl,[si-1]              ;get count

parms1:
  call nxtchar               ;get next char
  jnc parms1a                ;if no more, return
  ret

parms1a:


parms2:
  cmp al,"M"                 ;*****  Is it PRINT MSG *****
  jne parms3
  call nxtchar
  cmp al,"S"
  jne parms1a
  call nxtchar
  cmp al,"G"
  jne parms1a                ;yes:                no-->
  mov cs:msgmode,1           ;messages on
  jmp parms1



parms3:
  cmp al,"U"                 ;*****  Is it UNLOCK ? *****
  jne parms4
  call nxtchar
  cmp al,"N"
  jne parms1a
  or cs:LockHow,2

parms4:
  cmp al,"L"                 ;*****  Is it LOCK ? *****
  jne parms4a
  call nxtchar
  cmp al,"O"
  jne parms4_1a
  call nxtchar
  cmp al,"C"
  jne parms4_1a
  call nxtchar
  cmp al,"K"
  jne parms4a
  or cs:LockHow,1
  jmp parms4_1b

parms4a:
  jmp parms6


parms4_1a:
  jmp parms1a

;page
;. . . . . . . . . . . . . . pickup logical computer name

parms4_1b:
  call nxtchar               ;find start of name
  jc parms4_1c
  cmp al," "
  je parms4_1b

  dec si                     ;backup 1 char
  inc cx
  mov cs:dstring,si          ;save start pos

parms4_1c:
  call nxtchar               ;find end of string
  jc parms4_1z
  cmp al," "
  jne parms4_1c

  dec si
  inc cx

  mov ax,si                  ;calc length of string
  sub ax,cs:dstring
  mov cs:dstring+2,ax
  mov al,[si-2]              ;was string possesive?
  cmp al,"'"
  jne parms4_1d              ;yes:    no-->
  sub cs:dstring+2,2         ;don't use  's
  
parms4_1d:
  push si
  push cx
  mov di,offset destname
  push cs
  pop es
  mov cx,8
  mov al," "
  rep stosb
  mov di,offset destname
  mov si,cs:dstring
  mov cx,cs:dstring+2
  call nxtchar ;1
  stosb
  call nxtchar ;2
  stosb
  call nxtchar ;3
  stosb
  call nxtchar ;4
  stosb
  call nxtchar ;5
  stosb
  call nxtchar ;6
  stosb
  call nxtchar ;7
  stosb
  call nxtchar ;8
  stosb

  pop cx
  pop si
  call getname               ;get the lock name

parms4_1z:
  jmp parms1
;page


parms6:
  cmp al,"W"                 ;*****  is WAIT:n ? *****
  jne parms7
  call nxtchar
  cmp al,"A"
  jne parms6b
  call nxtchar
  cmp al,"I"
  jne parms6b
  call nxtchar
  cmp al,"T"
  jne parms6b
  call nxtchar
  cmp al,":"
  jne parms6b                ;yes:                no-->
  call getnum                ;pickup number
  test dh,0FFh               ;too big?
  jz parms6a                 ;yes:   no-->
  mov dx,255                 ;limit to 255

parms6a:
  mov cs:wait,dx             ;set wait count
  jmp parms1

parms6b:
  jmp parms1a


parms7:

parms9:
  jmp parms1
          
;page
;........................... get lock name ...................................

getname:
  mov di,offset taddr        ;put name at TransferADDRess
  call nxtchar               ;skip any leading whitespace
  jc gname9
  cmp al," "
  je getname
  cmp al,9
  je getname                 ;if blank or tab--> skip it

  dec si                     ;backup 1 char to name start
  inc cx

gname1:
  call nxtchar               ;get next name char
  jc gname9                  ;if no more-->
  cmp al," "                 ;is end of name?
  je gname9
  cmp al,9
  je gname9                  ;no:   yes-->

  cmp al,"?"                 ;is single wildcard?
  jne gname2                 ;yes:   no-->
  xor al,al                  ;use 00 internally
  jmp gname3                 ;go to loop bottom-->

gname2:
  cmp al,"*"                 ;is rep wildcard?
  jne gname3                 ;yes:    no-->
  xor al,al                  ;use 00 internally

gname2a:
  mov cs:[di],al             ;save nul to taddr buffer
  inc di                     ;advance
  cmp di,offset tend         ;reached end?
  jc gname2a                 ;yes:   no-->


gname3:
  mov cs:[di],al             ;save char to taddr buffer
  inc di                     ;advance
  cmp di,offset tend         ;reached end?
  jc gname1                  ;yes:   no-->

gname9:
  ret


;........................... Get next char ...................................

nxtchar:
  jcxz nc10                  ;if no more chars in buffer-->
  lodsb                      ;get next char
  dec cx                     ;decrement count remaining
  cmp al,13                  ;is CR ?
  jz nc9                     ;no:             yes-->
  cmp al,"a"                 ;force to CAPs
  jc nc8
  cmp al,"z"+1
  jnc nc8
  xor al,20h

nc8:
  clc                        ;return good
  ret

nc9:
  dec si                     ;dont go passed CR
  xor cx,cx                  ;no more chars

nc10:
  mov al," "
  stc                        ;return, none found
  ret

;page
;........................... Get number .....................................

getnum:
  xor dx,dx                  ;init number = 0

gn1:
  jcxz gn9                   ;are any chars left?  no-->
  lodsb                      ;yes, get next one
  dec cx                     ;dec # left
  mov ah,al                  ;save char
  sub ah,"0"                 ;adjust ascii to number
  jc gn8                     ;was char < "0" ?   yes-->
  cmp ah,10                  ;is char  > "9" ?   
  jnc gn8                    ;                   yes-->
  xchg ax,dx
  mov ah,10                  ;decimal shift left
  mul ah
  xchg ax,dx
  add dl,ah                  ;add in ones
  adc dh,0
  jmp gn1                    ;see if more

gn8:
  dec si                     ;restore buffer ptr
  inc cx                     ;restore # remaining

gn9:
  ret

setup endp


;........................... CON string output ................................
outstr proc near

  push cs
  pop ds

o1:
  lodsb
  or al,al
  jz o2
  mov ah,14
  push si
  int 10h
  pop si
  jmp o1

o2: ret

outstr endp

;page
;..............................................................................

lcall   dw 0           ;dword used for long call
        dw 0

comnum  db 0           ;COM link to use
wait    dw 100         ;count to wait for reply (in character times)


destname db "NETLKS00"

nulfcb   db 0,"NET0       "
         db 40 dup(0) 



                       ;DOS request header:
rqh     db 22          ;len                    0
        db 0           ;unit                   1
        db 8           ;command = write        2
        dw 0           ;status                 3
        db 8 dup(0)    ;reserved               5,6,7,8,9,10,11,12
        db 0           ;                       13
        dw taddr       ;transfer addr          14
        dw 0           ;                       16
        dw 8           ;count                  18
        dw 0           ;


net0rd  db 0,0,0,0,0,0



taddr     db "       ",1 ;transfer address
tend      db 13,10,0üŒtèsè´LÍ!. ‹.¢‡ŒÊŽÚº0´Í!
Àt.öŒt¾ÊèÜù°Ã.Ç>ŒÊŽÚºz´Í!º0´Í!´Í!.Å6z.¡(9D
u.¡*9Du.¡,9Du	.¡.9Dt"Å4ŒØ=ÿÿtþÿÿuÍ.öŒt¾ètù°Ã‹\ün$uBþ25u;øCOu4€úMu.ŠGû¨ðu'´Rº4Í\Z
Àt.öŒt¾‘è-¾©è'°Ã»d&ÆG&ÇG‹D.£!.Œ#.ÿ!‹D.£!.ÿ!»d&‹G©€t.öŒt¾éèÚ¾€ÆD èÐù°Ã.öŒt¾ü.€>‹t¾è²¾€ÆD è¨3ÀÃ3ÒŽÚÅ6pŒÚÖÃ3É¾ŠLÿèJsÃ<Muè@<Suõè9<Guî.ÆŒëß<Uuè%<NuÚ.€‹<Luè<Ouè<Cuè<Ku
.€‹ëëyë«èïr< t÷NA.‰6èßr^< u÷NA‹Æ.+.£ŠDþ<'u.ƒ.VQ¿(