Metropoli BBS
VIEWER: compat.asm MODE: TEXT (ASCII)
        title   compatibility hardware test


Cseg    segment para public 'code'

        org 100h

        assume cs:cseg,ds:cseg,es:nothing,ss:cseg



entry   proc far


su1:
  call htest
  push cs
  xor ax,ax
  push ax
  ret


entry   endp




msg0       db 13,10
           db "---------------- Compatibility test --------------",10,13,10,13
           db 0

intno      db 0
times      db 6 
tick       db 0
tickcnt    dw 0
old1C      dw 0
           dw 0
oldint     dw 0
           dw 0
intnum     dw 12
rs232      db 0
comnum     dw 0
L8250      dw 0              ;rs232 card address
errs       db 0
speed      db 0


htest  proc near

  push cs
  pop ds
  mov si,offset msg0
  call outstr
  call parms

  mov ax,40h
  mov es,ax
  mov bx,cs:comnum
  shl bx,1
  mov ax,es:[bx]
  mov cs:L8250,ax
  or ax,ax
  jnz h6aa

  mov si,offset msg6
  call outstr
  ret

h6aa:
  push cs
  pop ds

  cli
  xor si,si
  mov es,si
  mov si,1Ch * 4
  mov ax,es:[si]
  mov old1C,ax
  mov ax,es:[si+2]
  mov old1C+2,ax
  mov ax,offset new1C
  mov es:[si],ax
  mov es:[si+2],cs
  sti

  call teststr
  db "Testing for timer tick",10,13
  db "  if test does not continue in 2 seconds"
  db " then tick is not standard",13,10,0

  xor ax,ax
  xor cx,cx
  mov tick,al

t0:
  cmp tick,18*2      ;wait 2 seconds
  jnz t0
  mov tick,0

t1:
  test tick,0FFh      ;wait 1 more tick, count loops
  jnz t2
  loop t1

  inc ax              ;inc MSWord
  jmp t1

t2:
  push cx             ;save loop count
  push ax
  call teststr
  db "GOOD:  Tick at int 1Ch",10,13,0
  pop ax              ;print MSWord
  call hexax
  pop ax              ;print LSWord
  neg ax
  call hexax
  call teststr
  db " <-- counted cpu loops",10,13,10,13,0
 

  call teststr
  db "Testing loop back on serial port",10,13,0

  push cs
  pop ds
  mov dx,L8250
  inc dx         ;dx--> int enable (1)
  xor ax,ax      ;no ints
  out dx,al
  inc dx         ;dx--> int id (2)
  out dx,al
  inc dx         ;dx--> line control (3)
  mov al,80h     ;select divisor
  out dx,al
  sub dx,3       ;dx--> LSByte (0)
  mov al,2       ;/2
  out dx,al
  inc dx         ;dx--> MSByte (1)
  xor ax,ax
  out dx,al
  add dx,2       ;dx--> line control (3)
  mov al,00011000b  ;even parity, 1 stop bit, 5 data bits
  out dx,al
  inc dx         ;dx--> modem control (4)
  mov al,10h     ;loopback
  out dx,al
  inc dx          ;dx--> line status reg (5)
  in al,dx
  inc dx          ;dx--> modem status reg (6)
  in al,dx

  mov dx,L8250
  in al,dx
  mov cx,6

lpbk1:
  push cx
  mov al,15h
  call tchar
  pop cx
  jnc lpbk2
  loop lpbk1

lpbk1a:
  call teststr
  db "BAD: Loop back test failed",10,13,0
  or cs:errs,1
  jmp lpbk5

lpbk2:
  call teststr
  db "sync ok",10,13,0
  mov si,offset lpbktest

lpbk3:
  lodsb
  cmp al,80h
  je lpbk4
  and al,1fh
  call tchar
  jc lpbk1a
  call hexal
  call teststr
  db " <-- ok",10,13,0
  jmp lpbk3

lpbk4:
  call teststr
  db "GOOD: Loop back successfull",10,13,10,13,0

lpbk5:
  call teststr
  db "Testing RS232 interrupt",10,13
  db "  if this fails you may have to reboot",10,13,0


  push cs
  pop ds
  xor ax,ax
  mov es,ax
  mov bx,intnum
  shl bx,1
  shl bx,1
  mov ax,es:[bx]
  mov oldint,ax
  mov ax,es:[bx+2]
  mov oldint+2,ax
  cli
  mov ax,offset newint
  mov es:[bx],ax
  mov es:[bx+2],cs
  mov rs232,0
  sti
  mov dx,21h
  mov al,0
  out dx,al
  mov dx,L8250
  inc dx         ;dx--> int enable (1)
  mov al,8       ;enable modem status
  out dx,al
  add dx,3       ;(4)
  mov al,0Ch
  out dx,al
  xor cx,cx
  mov ah,20h

r1:
  test rs232,4
  jnz r2
  loop r1
  dec ah
  jnz r1

  call teststr
  db "Specified interrupt is bad",10,13,0
  or cs:errs,1
  jmp r3

r2:
  call teststr
  db "GOOD: Interrupt seems ok",10,13,0

r3:






  cli                ;restore int 1C
  mov si,0
  mov es,si
  mov si,1Ch * 4
  mov ax,old1C
  mov es:[si],ax
  mov ax,old1C+2
  mov es:[si+2],ax

                     ;restore rs232 int
  mov si,intnum
  shl si,1
  shl si,1
  mov ax,oldint
  mov es:[si],ax
  mov ax,oldint+2
  mov es:[si+2],ax
  sti

  call teststr
  db 10,13,"Test completed --> ",0
  cmp cs:errs,0
  jz r4

  call teststr
  db "BAD.",10,13,0
  ret

r4:
  call teststr
  db "GOOD.",10,13,0
  ret

lpbktest db 12h,7,1Fh,0,1Ch,10h,80h


;............................................................................

tchar:
  mov ah,al
  mov dx,L8250
  xor cx,cx

  out dx,al
  add dx,5
  xor cx,cx

w1:
  in al,dx
  test al,1
  jnz w3
  loop w1
  call teststr
  db "receiver never full",10,13,0
  stc
  ret

w3:
  sub dx,5
  in al,dx
  cmp ah,al
  je w4
  call teststr
  db "chars did not match",10,13,0
  stc
  ret

w4:
  clc
  ret
  
  

;............................................................................

new1C:
  inc cs:tick
  iret

;............................................................................

newint:
  inc cs:rs232
  push dx
  push ax
  mov dx,20h
  mov al,dl
  out dx,al
  mov dx,cs:L8250
  add dx,6
  in al,dx
  pop ax
  pop dx
  iret


;............................................................................

msg6 db "Specified COM port is not installed",7,10,13,0


;..........................................................................





;page
;........................... Get setup parameters ............................

parms:
  push cs
  pop es
  xor cx,cx                  ;cx will = # of chars in line
  mov si,81h                 ;es:si --> command line
  mov cl,[si-1]              ;get count

parms1:
  call nxtchar               ;get next char
  jnc parms1a                ;if no more, return
  ret

parms1a:
  cmp al,"C"                 ;is COMx ?
  jne parms2                 ;maybe:          no-->
  call nxtchar
  cmp al,"O"
  jne parms1a
  call nxtchar
  cmp al,"M"
  jne parms1a                ;yes:            no-->
  call getnum                ;pickup number
  dec dx
  mov cs:comnum,dx           ;save COM number
  jmp parms1



parms2:
  cmp al,"/"                 ;is it divisor select?
  jne parms5                 ;yes:                no-->
  call getnum                ;pick up divisor
  or dx,dx                   ;can't be zero
  jz parms1
  cmp dx,200                 ;must be < 200
  jnc parms1
  mov cs:speed,dl            ;save divisor
  jmp parms1

;page

parms5:
  cmp al,"I"
  jne parms6
  call nxtchar
  cmp al,"N"
  jne parms1a
  call nxtchar
  cmp al,"T"
  jne parms1a                ;yes:            no-->
  call getnum                ;pickup number
  mov cs:intnum,dx           ;save INT number

parms6:
  jmp parms1



;page
;........................... 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:
  stc                        ;return, none found
  ret





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

















outstr:
  push ax

o1:
  lodsb                      ;get next char
  or al,al                   ;is end of string?
  jz o2                      ;no:              yes-->
  mov ah,14                  ;print it
  push si
  int 10h
  pop si
  jmp o1                     ;do more-->

o2:
  pop ax
  ret





teststr:
  mov cs:test_si,si
  mov cs:test_di,di
  mov cs:test_ax,ax
  mov cs:test_ds,ds
  sahf
  mov cs:test_f,ah
  mov si,cs
  mov ds,si
  pop si
  call outstr
  push si
  mov ah,cs:test_f
  lahf
  mov ds,cs:test_ds
  mov ax,cs:test_ax
  mov di,cs:test_di
  mov si,cs:test_si
  ret


test_di dw 0 
test_si dw 0
test_ax dw 0
test_ds dw 0
test_f  db 0




;page

hexal:
  push ax
  push cx
  mov ch,al
  mov cl,4
  shr al,cl
  add al,"0"
  cmp al,3Ah
  jc hx1
  add al,7

hx1:
  mov ah,14
  int 10h
  mov al,ch
  and al,0fh
  add al,"0"
  cmp al,3Ah
  jc hx2
  add al,7

hx2:
  mov ah,14
  int 10h
  pop cx
  pop ax
  ret




hexax:
  push ax
  mov al,ah
  call hexal
  pop ax
  call hexal
  ret

  

htest      endp

Cseg       ends
           end su1












[ RETURN TO DIRECTORY ]