system/shard-x86-at/7/src/PCPAR.ASM

Raw file
Back to index

;***************************************************************************
;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge =================*
;*                                                                         *
;*   Routinen fuer IBM - PC Parallel - Schnittstelle im EUMEL - System     *
;*                                                                         *
;*                                                                         *
;***************************************************************************

     device parallel

     dtcbroutines iocontrol
     routine 1,para_devicetype
     routine 2,para_frout
     routine 5,nil_size
     routine -3,para_force_rom_output
     routine -4,para_set_wait
     routine -1,no_channel_setup

     dtcbroutines control32
     routine -2,para_init
     routine -1,no_channel_setup

     dtcbroutines blockin
     dtcbroutines blockout
     routine -1,unknowncontrol

     dtcbparams para_output,3   ;typ = nur stream io


;******************************************************************
;*   der macro para_ccb muss fuer jede parallelschnittstelle im system
;*   einmal aufgerufen werden
;*
;*   parameter: 

para_ccb macro par,kanal
     startccb para&par&ccb,kanal
ccbentry para_number
     dw par
ccbentry para_stat
     db 0
ccbentry para_statusandmask
     db 80h                        ;;busy abfragen
ccbentry para_statusxormask
     db 80h                        ;;active high
ccbentry para_wait                 ;;wie lange vor busy warten
     db 1
ccbentry para_retry
     db 30                         ;;> 100 usec minimum
     endm

para_rom_mode equ 1

para_devicetype:
     mov cx,0                      ;erstmal 0 setzen
     call para_get_port
     ifnz <mov cl,shard:(si+devtype)>     ;type dazu
     ret

para_init:
     call para_get_port
     ifz <ret>
     test dx,0fc03h                ;ist die adresse ibm like
     jnz para_rom_init
     inc dx
     inc dx                        ;auf status ausgabe zeigen
     mov al,8                      ;init leitung aktivieren
     out (dx),al
     mov ax,4000
para_ini_loop:
     dec ax
     jnz para_ini_loop             ;warte ein weilchen
     mov al,0ch                    ;kein auto lf, init high
     out (dx),al
     ret

para_rom_init:
     mov ah,1
     mov dx,[di+para_number]
     int 17h
     ;es passt noch
     mov bx,dx                     ;nummer nach bx
     mov byte ptr es:[078h+bx],1 ;timeout wert,falls er doch mal busy kriegt
     ret

para_set_wait:
     inc dl
     mov [di+para_wait],dl
     inc dh
     mov [di+para_retry],dh
     ret

para_force_rom_output:
     or byte ptr [di+para_stat],para_rom_mode
     ret

para_output:
     jcxz para_all
     push es
     push bx
     call para_get_port
     pop bx
     pop es
     jz para_all                   ;kein port, dann wegwerfen
     test dx,0fc03h                ;ist die adresse ibm like
     jnz para_rom_output           ;nein, ueber rom raus
     test byte ptr [di+para_stat],para_rom_mode
     jnz para_rom_output
     push cx
     inc dx                   ;auf status gehen
para_out_loop:
     push cx
     mov cl,[di+para_wait]
     sub ch,ch                ;0 nach ch
     loop $                   ;pause fuer langsame drucker
     mov cl,[di+para_retry]
     ;ch ist 0
para_ow_loop:                 ;warten, bis output erlaubt
     in al,dx                 ;status holen
     and al,(di+para_statusandmask) ;welche bits interessieren uns
     xor al,(di+para_statusxormask) ;und wie sollen sie stehen
     jz para_ready            ;passt, ausgeben
     loop para_ow_loop
     pop dx                   ;restlaenge holen
     pop cx                   ;gesamtlaenge holen
     sub cx,dx                ;uebernommene laenge melden
                              ;carry ist geloescht
     ret

para_ready:
     pop cx                   ;zeichenzaehler zurueckholen
     dec dx                   ;auf port direkt gehen
     mov al,byte ptr es:[bx]  ;zeichen holen
     inc bx                   ;auf naechstes zeichen
     out (dx),al              ;zeichen ausgeben
     inc dx
     inc dx                   ;auf port fuer strobe zeigen
     mov al,0dh               ;strobe ist bit 0
     out (dx),al
     jmp short $+2
     mov al,0ch               ;und strobe zuruecknehmen
     out (dx),al
     dec dx                   ;auf status port gehen
     loop para_out_loop       ;naechstes ausgeben
     pop cx                   ;alles ausgegeben
para_all:
     stc
     ret

para_rom_output:
     push cx
     mov dx,[di+para_number]
para_rom_out_loop:
     push cx
     mov cl,[di+para_wait]
     sub ch,ch
     loop $                   ;pause fuer langsame drucker
     mov cl,[di+para_retry]
     shr cl,1                 ;durch 16
     shr cl,1
     shr cl,1
     shr cl,1                 
     inc cl                   ;aber nie 65000 mal     
para_rom_ow_loop:             ;warten, bis output erlaubt
     mov ah,2                 ;status holen
     int 17h
     and ah,(di+para_statusandmask) ;welche bits interessieren uns
     xor ah,(di+para_statusxormask) ;und wie sollen sie stehen
     jz para_rom_ready            ;passt, ausgeben
     loop para_rom_ow_loop
     pop dx                   ;restlaenge holen
     pop cx                   ;gesamtlaenge holen
     sub cx,dx                ;uebernommene laenge melden
                              ;carry ist geloescht
     ret

para_rom_ready:
     pop cx                   ;zeichenzaehler zurueckholen
     mov al,byte ptr es:[bx]  ;zeichen holen
     inc bx                   ;auf naechstes zeichen
     mov ah,0                 ;zeichen ausgeben
     int 17h
     loop para_rom_out_loop   ;naechstes ausgeben
     pop cx                   ;alles ausgegeben
     stc
     ret

para_frout:
     call para_get_port
     jz para_frout_ok
     test dx,0fc03h                ;ist die adresse ibm like
     jnz para_rom_frout            ;nein, ueber rom fragen
     test byte ptr [di+para_stat],para_rom_mode
     jnz para_rom_frout
     inc dx                   ;auf status gehen
     in al,dx                 ;status holen
     and al,(di+para_statusandmask) ;welche bits interessieren uns
     xor al,(di+para_statusxormask) ;und wie sollen sie stehen
     jnz para_frout_not_ok    ;passt nicht, melden
para_frout_ok:
     mov cx,50                ;kann ausgeben
     stc                      ;puffer leer
     ret

para_rom_frout:
     mov dx,[di+para_number]
     mov ah,2                 ;status holen
     int 17h
     and ah,(di+para_statusandmask) ;welche bits interessieren uns
     xor ah,(di+para_statusxormask) ;und wie sollen sie stehen
     jz para_frout_ok         ;passt, melden
para_frout_not_ok:
     mov cx,0                 ;nichts passt
     clc                      ;puffer nicht leer
     ret

para_get_port:
     ;setzt zero flag, wenn port = 0
     mov ax,40h                    ;ins pc datensegment
     mov es,ax
     mov bx,[di+para_number]       ;welcher printer
     shl bx,1                      ;fuer basis adresse passend
     mov dx,es:[8+bx]              ;printer basis adresse holen
     or dx,dx                      ;0?
     ret