;*************************************************************************** ;*======= 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 ;type dazu ret para_init: call para_get_port ifz 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