summaryrefslogtreecommitdiff
path: root/system/shard-x86-at/7/src/PCPAR.ASM
blob: 0bca2c51a1313391a7fe0aa7c8f05bcf6f08d628 (plain)
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