program i1284_info;
uses crt;
{The following code is based on the IEEE-1284 probe code from Linux, which was
written by Phil Blundell, Carsten Gross and Jose Renau.

The Turbo Pascal *implementation* is entirely my own creation.

version 1.1 : bugfix. Timing of signals in 'second check' found to work OK
for HP Laserjet 5L, but not for Canon BJ-210. Re-worked code to be compatable
with both types of printers. I assume this is an anomalie with the Linux
code, since the order of operations was copied from there.}

var q,y,z:byte;
    r:array[1..1024] of byte;
    i:integer;
    f,quit:boolean;

procedure adelay;assembler;
asm

   mov ax,65535;@sm1: dec ax;jnz @sm1 {delay routine should be improved}
   mov ax,65535;@sm2: dec ax;jnz @sm2 {delay routine should be improved}
   mov ax,65535;@sm3: dec ax;jnz @sm3 {delay routine should be improved}
   mov ax,65535;@sm4: dec ax;jnz @sm4 {delay routine should be improved}



(*push es
push di

xor ax,ax
mov es,ax
mov di,46ch

mov ax,es:[di]
@smycka:
cmp ax,es:[di]
jz @smycka *)

(*pop di
pop es*)

{mov ax,1
push ax
call delay}
end;

function wait : boolean;assembler;	{ wait 35ms for response }
{CH=mask, CL=RES}
asm
push dx
push bx
   mov bl,1
   mov dx,379h
@cycle:
   in al,dx
   inc bl
   call adelay
   cmp bl,40
  jz @quit_cycle
   and al,ch
   cmp al,cl
  jnz @cycle
@quit_cycle:
   mov al,1
   cmp bl,40
  jl @is_true
   xor al,al
@is_true:
pop bx
pop dx
end;


function read_nibble : byte;assembler;			{ read 4 bits of info }
asm
push dx
   mov dx,379h
   in al,dx
   shr al,3
   and al,0f7h
   test al,10h
  jnz @not_zero
   or al,8
@not_zero:
   and al,0fh
pop dx
end;

procedure print;assembler;
{retezec musi byt na DS:SI a ukonceny 0}
asm
push dx
@cycle:
   mov dl,ds:[si];inc si
   cmp dl,0
  jz @finished
   mov ah,2
   int 21h
  jmp @cycle
@finished:
pop dx
end;

procedure int2str;assembler; {BX = value; DS:DI = ASCIIZ value}
asm
push dx
push cx
push bx
push ax
mov ax,bx
mov bx,10
xor cx,cx
@smycka1:
   cmp ax,0
 jng @konec
 {------------------------}

 xor dx,dx
 div bx     {AX:=AX div 10; zbytek je v DX, PODIL v AX}

 add dx,48  {48=ord('0')}
 inc cx
 push dx
 jmp @smycka1
 {------------------------}
@konec:

xor bx,bx
cmp cx,0
jnz @smycka2
mov ax,3000h
mov ds:[si+0],ah
mov ds:[si+1],al
jmp @int_2_str_join
@smycka2:
pop ax
mov ds:[si+bx],al
inc bx
loop @smycka2
@zero_value:
mov al,0
mov ds:[si+bx],al
@int_2_str_join:
pop ax
pop bx
pop cx
pop dx
end;

const  ieee:pchar = 'IEEE-1284 Parallel port device scan.'#13#10#13#10;
       present:pchar = 'Passed initial check. An IEEE-1284 device is present.'#13#10;
       second:pchar = 'Passed second check. Device ID is readable.'#13#10;
       read_1_timeout:pchar = 'Read1 timeout!'#13#10;
       read_2_timeout:pchar = 'Read2 timeout!'#13#10;
       ok_id:pchar = 'ID Read terminated OK'#13#10#13#10;
       err_id:pchar = 'ID Read terminated with error!'#13#10#13#10;
       our_size:pchar = 'Size our count : ';
       ret_size:pchar = 'Size returned  : ';
       inf_ret:pchar = 'Info returned  : ';
       formatter:pchar = #13#10'                 ';
       failed_1:pchar = 'Failed initial check. No IEEE-1284 device detected.'#13#10;
       failed_2:pchar = 'Failed second check. No device ID Readable.'#13#10;
       crlf:pchar = #13#10;



var buffer:array[0..255] of char;

begin
asm
lds si,ieee;call print;
   seges lea di,r

   mov dx,378h
   mov al,4
   out dx,al
  call adelay;call adelay;call adelay;call adelay

   mov dx,37ah
   in al,dx;and al,0f7h;out dx,al
   in al,dx;or al,2;out dx,al

   mov cx,7838h;call wait
   cmp al,0
jz @nesplnen_1_check
{-------------------tady musi bejt JNZ @nenalezeno----------------------}
   lds si,present;call print;

    in al,dx;or al,1;out dx,al                  { strobe high }
    in al,dx;and al,0fdh;out dx,al              { autofeed low }
 call adelay;call adelay;call adelay;call adelay
    in al,dx;and al,0feh;out dx,al              { stobe low }
 call adelay;call adelay;call adelay;call adelay

    mov cx,2000h;call wait
    cmp al,0
jz @nesplnen_2_check
    lds si,second;call print;

{}  mov f,0
{}  mov quit,0
   xor bx,bx             {BX je misto S}
    call adelay;call adelay;call adelay;call adelay
    call adelay;call adelay;call adelay;call adelay

{==========================================================================}
@repeat_block:
    mov dx,3fah
    in al,dx;or al,2;out dx,al
    mov cx,4000h;call wait
    cmp al,0
   jnz @skip1
{------------------------------------------------}
    lds si,read_1_timeout;call print;
    in al,dx;and al,0fdh;out dx,al              {reset printer}
    mov quit,1
@skip1:
{------------------------------------------------}
   call read_nibble
    mov y,al                                    { get 4 bits }
    in al,dx;and al,0fdh;out dx,al              { autofeed low }
    mov cx,4040h;call wait
    cmp al,0
   jnz @skip2
{------------------------------------------------}
    lds si,read_2_timeout;call print;
    mov quit,1
@skip2:
{------------------------------------------------}
    cmp f,0                                     { f signals when a byte is }
   jz @f_is_zero                               { ready - each 2 passes }

    mov f,0
    mov al,y
    shl al,4
    add q,al
    mov al,q
   mov es:[di+bx],al;inc bx

    mov dx,379h
    in al,dx
    mov dx,37ah
    and al,8
    cmp al,8                                     { eof? }
   jnz @no_quit
    mov quit,1
@no_quit:
   jmp @f_join
@f_is_zero:

    mov f,1
    mov al,y
    mov q,al
@f_join:

    cmp bx,1023                                 { out of table space ? }
   jng @no_greater
    mov quit,1
@no_greater:

cmp quit,1
jnz @repeat_block
{==========================================================================}

    in al,dx
    and al,0fdh
    or al,8
    out dx,al                                   { terminate read }

    mov cx,8000h;call wait
    cmp al,1
   jnz @id_error
    lds si,ok_id;call print;
   jmp @id_join
@id_error:
    lds si,err_id;call print;
@id_join:

{ Display Result, nicely formatted }
    lds si,our_size;call print;
    lea si,buffer;call int2str;call print;
    lds si,crlf;call print;

    lds si,ret_size;call print;
    mov ah,es:[di]
    mov al,es:[di+1]
    xchg ax,bx
    mov cx,ax
    lea si,buffer;call int2str;call print;
    lds si,crlf;call print;


    lds si,inf_ret;call print;

    mov bx,2
@write_cycle:
    mov al,es:[di+bx]
    cmp al,59 {;}
   jnz @normal_char
    lds si,formatter;call print;
   jmp @write_join
@normal_char:
    mov dl,al
    mov ah,2
    int 21h
@write_join:
    inc bx
    cmp bx,cx
    jng @write_cycle

    lds si,crlf;call print;
    lds si,crlf;call print;
   jmp @Go_exit

@nesplnen_2_check:
    lds si,failed_2;call print;
    mov dx,37ah;in al,dx;and al,0fdh;or al,8;out dx,al
   jmp @Go_Exit

@nesplnen_1_check:
    lds si,failed_1;call print;
    mov dx,37ah;in al,dx;and al,0fdh;or al,8;out dx,al

@Go_exit:
end;
end.
