           TITLE   ADDCOM for non-std com ports .... ac.asm

Cseg       SEGMENT para public 'code'

           org 0

           assume cs:cseg,ds:cseg,es:nothing,ss:cseg

           dw 0ffffh         ;next dvc
           dw 0ffffh
           dw 8000h          ;attr.
           dw dvcstrat       ;device strategy
           dw dvcint         ;device interrupt 
           db "edcom   "     ;mfg name/unit

msg0       db 13,10
           db "Adding non-standard COM ports",10,13,10,13,0
           db 0

L8250      dw 0              ;rs232 card address


jmptable  equ $

           dw INIT           ;init
           dw noop           ;media check
           dw noop           ;build bpb
           dw noop           ;ioctl input
           dw noop           ;input
           dw noop           ;input, non-destruct
           dw noop           ;input status
           dw noop           ;input flush
           dw noop           ;output
           dw noop           ;output, verify
           dw noop           ;output status
           dw noop           ;output flush
           dw noop           ;ioctl output


rqheadr    dd 0              ;request header ptr

;page


                             ;device strategy
dvcstrat proc far

  mov cs:word ptr rqheadr,bx    ;save request header ptr
  mov cs:word ptr rqheadr+2,es
  ret

dvcstrat   endp


                             ;device interrupt
dvcint   proc far

  push ax                    ;save all regs
  push bx
  push cx
  push dx
  push di
  push si
  push bp
  push ds
  push es

  mov bx,cs
  mov ds,bx
  les di,cs:rqheadr          ;es:di --> req. header
  xor bx,bx
  mov es:[di+3],bx           ;status word = 0
  mov bl,es:[di+2]           ;get command
  cmp bl,13                  ;make sure in range
  cmc
  mov al,3                   ;assume unknown command error
  jc cont1                   ;if bad command -->
  shl bx,1                   ;bx = index to jmp address
  cld
  call word ptr cs:[jmptable+bx] ;do command


                             ;commands all return here

cont1:
  les di,cs:rqheadr          ;es:di --> req. header
  mov ah,2                   ;set done bit
  rcr ah,1                   ;rotate in cy flag for error bit
  or es:[di+3],ax            ;or in error condition
  pop es                     ;restore all regs
  pop ds
  pop bp
  pop si
  pop di
  pop dx
  pop cx
  pop bx
  pop ax
  ret

dvcint endp


;page

master proc near

;........................... INIT: ..........................................

Init:
  push cs
  pop ds
  mov si,offset msg0         ;print sign-on
  call outstr

  call parms

  les di,cs:rqheadr          ;point to request header 
  mov word ptr es:[di+14],offset lastbyte    ;set last byte needed
  mov es:[di+16],cs

  push cs
  pop ds
  mov si,offset msg2
  mov al,numadds
  or al,al
  jz i1

  add al,"0"
  push ax
  mov ah,14
  int 10h
  pop ax
  mov si,offset msg1         ;tell user install ok
  cmp al,"1"
  je i1
  mov si,offset msg1a

i1:
  call outstr
  xor ax,ax
  clc

i2:
  ret

;page
;........................... No Operation: ...................................

noop:
  mov ax,3                   ;unknown command
  stc
  ret


errop:
  mov ax,3                   ;unknown command
  stc
  ret



LASTBYTE   db 0




;page
;........................... Get setup parameters .............................

parms:

  les di,dword ptr cs:rqheadr   ;point to request header 
  lds si,dword ptr es:[di+18]   ;point to the command line after "="
  add si,7                      ;skip over name
  mov cx,40                     ;allow 40 chars 

parms1:
  call nxtchar               ;get next char
  jc parms9                  ;if no more-->

  cmp al,"C"                 ;is COMx ?
  jne parms2
  call nxtchar
  cmp al,"O"
  jne parms2
  call nxtchar
  cmp al,"M"
  jne parms2                 ;yes:              no-->
  call getnum                ;pickup number
  dec dx
  mov cs:comnum,dx           ;save COM number
  call nxtchar
  jc parms9
  cmp al,"="
  jne parms1
  call gethexnum

  add dx,4
  in al,dx
  xor al,1
  mov ah,al
  out dx,al
  in al,dx
  cmp al,ah
  jne parms8
  xor al,1
  out dx,al
  sub dx,4
  inc cs:numadds
  push es
  mov bx,40h
  mov es,bx
  mov bx,cs:comnum
  shl bx,1
  mov es:[bx],dx
  pop es
  jmp parms1

parms2:
  jmp parms1

parms8:
  push ds
  mov si,cs
  mov ds,si
  mov si,offset msg3
  call outstr
  mov ax,cs:comnum
  add al,"1"
  mov ah,14
  int 10h
  mov si,offset msg4
  call outstr
  pop ds
  jmp parms1

parms9:
  ret          


;page
;........................... 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                     ;don't go passed CR
  xor cx,cx                  ;no more chars

nc10:
  stc                        ;return, none found
  ret


;........................... 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

;page

;........................... gethexnum .......................................

gethexnum:
  xor dx,dx

gh1: call nxtchar
  jc gh9

  mov ah,al

  sub al,"0"
  jc gh8
  cmp al,10
  jc gh4
  add al,"0"
  sub al,"A"
  jc gh8
  cmp al,6
  jnc gh8
  add al,10

gh4:
  shl dx,1
  shl dx,1
  shl dx,1
  shl dx,1
  add dl,al
  adc dh,0
  jmp gh1
  

gh8:
  dec si
  inc cx

gh9:
  ret


outstr:

  lodsb
  or al,al
  jz o2
  mov ah,14
  push si
  int 10h
  pop si
  jmp outstr

o2: ret


msg1       db " COM added",10,13,0
msg1a      db " COMs added",10,13,0
msg2       db 13,10,"No COMs added",10,13,0
msg3       db 13,10,"COM",0
msg4       db ": device does not exist",7,13,10,0


comnum     dw 0
numadds    db 0

master     endp

cseg       ends
           end
