1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
;***************************************************************************
;*======= 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
|