1942
|
1 ********************************************************************
|
|
2 * scbbp.asm - CoCo Bit-Banger Printer Driver
|
|
3 *
|
|
4 * $Id$
|
|
5 *
|
|
6 * Enhanced and re-written by Alan DeKok
|
|
7 *
|
|
8 * Problems with original:
|
|
9 * returns wrong error on Read/SetStt
|
|
10 * doesn't block output. The printer is a single-user device!
|
|
11 *
|
|
12 * Edt/Rev YYYY/MM/DD Modified by
|
|
13 * Comment
|
|
14 * ------------------------------------------------------------------
|
|
15 * 13 2003/01/05 Boisy G. Pitre
|
|
16 * Back-ported to OS-9 Level Two.
|
|
17 *
|
|
18 * 2003/09/04 Boisy G. Pitre
|
|
19 * Back-ported to OS-9 Level One.
|
|
20
|
|
21 nam scbbp
|
|
22 ttl CoCo Bit-Banger Printer Driver
|
|
23
|
|
24 ifp1
|
|
25 use defsfile
|
|
26 endc
|
|
27
|
|
28 tylg set Drivr+Objct
|
|
29 atrv set ReEnt+Rev
|
|
30 rev set $00
|
|
31 edition set 13
|
|
32
|
|
33 mod eom,name,tylg,atrv,Start,Size
|
|
34
|
|
35 fcb READ.+WRITE.
|
|
36
|
|
37 name fcs /scbbp/
|
|
38 fcb edition one more revision level than the stock printer
|
|
39
|
|
40 * Device memory area: offset from U
|
|
41 org V.SCF V.SCF: free memory for driver to use
|
|
42 V.PAR rmb 1 1=space, 2=mark parity
|
|
43 V.BIT rmb 1 0=7, 1=8 bits
|
|
44 V.STP rmb 1 0=1 stop bit, 1=2 stop bits
|
|
45 V.COM rmb 2 Com Status baud/parity (=Y from SS.Comst Set/GetStt
|
|
46 V.COL rmb 1 columns
|
|
47 V.ROW rmb 1 rows
|
|
48 V.WAIT rmb 2 wait count for baud rate?
|
|
49 V.TRY rmb 2 number of re-tries if printer is busy
|
|
50 V.RTRY rmb 1 low nibble of parity=high byte of number of retries
|
|
51 V.BUFF rmb $80 room for 128 blocked processes
|
|
52 size equ .
|
|
53
|
|
54 * Baud Rate Delay Table
|
|
55 BaudDly equ *
|
|
56 IFEQ Level-1
|
|
57 * OS-9 Level One delay values (0.89MHz)
|
|
58 fdb $0482 110 baud
|
|
59 fdb $01A2 300 baud
|
|
60 fdb $00CD 600 baud
|
|
61 fdb $0063 1200 baud
|
|
62 fdb $002D 2400 baud
|
|
63 fdb $0013 4800 baud
|
|
64 fdb $0005 9600 baud
|
|
65 ELSE
|
|
66 IFEQ H6309
|
|
67 * OS-9 Level Two delay values (1.78MHz)
|
|
68 fdb $090C 110 baud
|
|
69 fdb $034C 300 baud
|
|
70 fdb $01A2 600 baud
|
|
71 fdb $00CE 1200 baud
|
|
72 fdb $0062 2400 baud
|
|
73 fdb $002E 4800 baud
|
|
74 fdb $0012 9600 baud
|
|
75 fdb $0003 32000 baud
|
|
76 ELSE
|
|
77 * NitrOS-9 Level Two delay values (1.78MHz)
|
|
78 fdb $090C 110 baud (Unchanged, unknown)
|
|
79 fdb $03D0 300 baud
|
|
80 fdb $01A2 600 baud (Unchanged, unknown)
|
|
81 fdb $00F0 1200 baud
|
|
82 fdb $0073 2400 baud
|
|
83 fdb $0036 4800 baud
|
|
84 fdb $0017 9600 baud
|
|
85 fdb $0003 32000 baud (Unchanged, unknown)
|
|
86 ENDC
|
|
87 ENDC
|
|
88
|
|
89
|
|
90 start equ *
|
|
91 lbra Init
|
|
92 lbra Read
|
|
93 lbra Write
|
|
94 lbra GetStt
|
|
95 lbra SetStt
|
|
96
|
|
97 * Term
|
|
98 *
|
|
99 * Entry:
|
|
100 * U = address of device memory area
|
|
101 *
|
|
102 * Exit:
|
|
103 * CC = carry set on error
|
|
104 * B = error code
|
|
105 *
|
|
106 Term equ *
|
|
107 clrb
|
|
108 rts
|
|
109
|
|
110 * Init
|
|
111 *
|
|
112 * Entry:
|
|
113 * Y = address of device descriptor
|
|
114 * U = address of device memory area
|
|
115 *
|
|
116 * Exit:
|
|
117 * CC = carry set on error
|
|
118 * B = error code
|
|
119 *
|
|
120 Init orcc #IntMasks
|
|
121 ldx #PIA1Base
|
|
122 clr $01,x
|
|
123 ldd <IT.COL,y get number of columns/rows
|
|
124 std <V.COL,u save it in statics
|
|
125 lda #$FE
|
|
126 sta ,x
|
|
127 lda #$36
|
|
128 sta $01,x
|
|
129 lda ,x
|
|
130 andcc #^IntMasks
|
|
131 ldd <IT.PAR,y parity and baud rate
|
|
132 lbsr L0138 setup parity/baud in device memory
|
|
133 lbsr L0104 get low bit of $FF22 into carry
|
|
134 lbcs L0100 it's the ready flag
|
|
135 * clear out buffer
|
|
136 leax V.BUFF,u room for 128 blocked processes
|
|
137 ldb #128
|
|
138 I010 clr ,x+ we're more concerned with room
|
|
139 decb than with speed, so we don't use TFM
|
|
140 bne I010
|
|
141 rts
|
|
142
|
|
143 L005F ldb <PD.BAU,y get baud rate in path desc.
|
|
144 andb #$0F keep lower nibble
|
|
145 cmpb #$07 compare against highest
|
|
146 lbhs Read
|
|
147 aslb
|
|
148 leax <BaudDly,pc table of delay times
|
|
149 ldx b,x get delay counter
|
|
150 stx <V.WAIT,u save it off
|
|
151 clrb
|
|
152 rts
|
|
153
|
|
154 Bit_2 ldb #$02
|
|
155 L007D stb >PIA1Base
|
|
156 L0080 pshs d
|
|
157 ldd <V.WAIT,u get wait count for baud rate
|
|
158 L0085 equ *
|
|
159 IFNE H6309
|
|
160 decd count down by one
|
|
161 ELSE
|
|
162 subd #$0001
|
|
163 ENDC
|
|
164 bne L0085
|
|
165 puls pc,d
|
|
166
|
|
167 * Write
|
|
168 *
|
|
169 * Entry:
|
|
170 * A = character to write
|
|
171 * Y = address of path descriptor
|
|
172 * U = address of device memory area
|
|
173 *
|
|
174 * Exit:
|
|
175 * CC = carry set on error
|
|
176 * B = error code
|
|
177 *
|
|
178 Write equ *
|
|
179 leax V.BUFF,u point to the buffer
|
|
180 ldb V.BUSY,u get my process number
|
|
181 tst ,x get allowed process number
|
|
182 bne W010 if not zero, else
|
|
183 stb ,x I'm the only one allowed to use it
|
|
184
|
|
185 W010 cmpb ,x am I allowed to use /p?
|
|
186 beq W030 if yes, go write a character
|
|
187
|
|
188 ***************************************************************
|
|
189 * WARNING: If more than 128 processes try to use the printer,
|
|
190 * this will CRASH BADLY. Since Level II on the Coco is limited
|
|
191 * to 32 processes, I don't think it's a problem.
|
|
192 ***************************************************************
|
|
193
|
|
194 W020 tst ,x+ if not, find the first non-zero entry
|
|
195 bne W020
|
|
196 stb -1,x and save my process number at the first zero
|
|
197 pshs a
|
|
198 lda V.BUFF,u process that's allowed to use /p
|
|
199 sta V.BUSY,u make it the busy one
|
|
200 ldb #S$Wake wake it up
|
|
201 os9 F$Send send a signal to wake it
|
|
202 IFNE H6309
|
|
203 tfr 0,x
|
|
204 ELSE
|
|
205 ldx #$0000
|
|
206 ENDC
|
|
207 os9 F$Sleep and go to sleep forever
|
|
208 puls a restore character to be sent, and continue
|
|
209
|
|
210 W030 bsr L005F set up baud rate, etc in memory
|
|
211 bcs L00CA
|
|
212 pshs a
|
|
213 bsr L00CB make sure that the device is ready
|
|
214 puls a
|
|
215 bcs L00CA if the device is not ready
|
|
216 IFNE H6309
|
|
217 lde #$09 9 bits to send out
|
|
218 ELSE
|
|
219 pshs b,a
|
|
220 lda #$09
|
|
221 sta 1,s
|
|
222 puls a
|
|
223 ENDC
|
|
224 orcc #IntMasks turn off interrupts
|
|
225 tst <V.BIT,u number of bits
|
|
226 beq L00AC if 7 bits, count down by one
|
|
227 IFNE H6309
|
|
228 dece initially send out start bit
|
|
229 ELSE
|
|
230 dec ,s
|
|
231 ENDC
|
|
232
|
|
233 L00AC bsr L007D write B to $FF20 and wait
|
|
234 clrb
|
|
235 lsra move A into carry
|
|
236 rolb
|
|
237 rolb
|
|
238 IFNE H6309
|
|
239 dece count down on the number of bits to send
|
|
240 ELSE
|
|
241 dec ,s
|
|
242 ENDC
|
|
243 bne L00AC
|
|
244 IFEQ H6309
|
|
245 puls b
|
|
246 ENDC
|
|
247 ldb <V.PAR,u space/mark parity
|
|
248 beq L00BC 0=no parity
|
|
249 andb #$FE 1=space, 0=mark parity
|
|
250 * should be andb #$FD I think...
|
|
251 bsr L007D dump out parity
|
|
252 L00BC bsr Bit_2 and a stop bit
|
|
253 tst <V.STP,u do another one?
|
|
254 beq L00C9
|
|
255 bsr Bit_2 yes, dump out another stop bit
|
|
256 L00C9 andcc #^IntMasks
|
|
257 L00CA rts
|
|
258
|
|
259 L0104 pshs b
|
|
260 ldb >PIA1Base+$02 get a byte
|
|
261 lsrb
|
|
262 puls pc,b
|
|
263
|
|
264 L00CB equ *
|
|
265 IFNE H6309
|
|
266 clrd
|
|
267 ELSE
|
|
268 clra
|
|
269 clrb
|
|
270 ENDC
|
|
271 std <V.TRY,u
|
|
272 L00D0 ldd #$0303
|
|
273 L00D3 bsr L0104 get device ready status
|
|
274 bcs L00DE if not ready, wait for a bit
|
|
275 IFNE H6309
|
|
276 bsr L0080 wait
|
|
277 ELSE
|
|
278 lbsr L0080 wait
|
|
279 ENDC
|
|
280 decb
|
|
281 bne L00D3 try again
|
|
282 clrb
|
|
283 rts
|
|
284
|
|
285 L00DE lbsr L0080 wait for a while
|
|
286 deca try 3 times,
|
|
287 bne L00D3
|
|
288 pshs x
|
|
289 ldx #$0001
|
|
290 os9 F$Sleep sleep for the rest of this tick
|
|
291 puls x
|
|
292 ldd <V.TRY,u
|
|
293 IFNE H6309
|
|
294 incd we've tried once more and failed...
|
|
295 ELSE
|
|
296 addd #$0001
|
|
297 ENDC
|
|
298 std <V.TRY,u
|
|
299 ldb <V.RTRY,u number of retries to do
|
|
300 beq L00D0 if unspecified, keep retrying
|
|
301 cmpb <V.TRY,u if exceeded number of retries,
|
|
302 bhi L00D0 then we crap out
|
|
303
|
|
304 L0100 comb
|
|
305 ldb #E$NotRdy
|
|
306 rts
|
|
307
|
|
308 * GetStat
|
|
309 *
|
|
310 * Entry:
|
|
311 * A = function code
|
|
312 * Y = address of path descriptor
|
|
313 * U = address of device memory area
|
|
314 *
|
|
315 * Exit:
|
|
316 * CC = carry set on error
|
|
317 * B = error code
|
|
318 *
|
|
319 GetStt cmpa #SS.EOF end of file?
|
|
320 bne L0112
|
|
321 clrb if so, exit with no error
|
|
322 rts
|
|
323
|
|
324 L0112 ldx PD.RGS,y
|
|
325 cmpa #SS.ScSiz
|
|
326 beq L0123
|
|
327 cmpa #SS.ComSt
|
|
328 bne L0173
|
|
329 ldd <V.COM,u get Com status
|
|
330 std R$Y,x
|
|
331 clrb
|
|
332 rts
|
|
333
|
|
334 * get screen size GetStt
|
|
335 L0123 clra
|
|
336 ldb <V.COL,u
|
|
337 std R$X,x
|
|
338 ldb <V.ROW,u
|
|
339 std R$Y,x
|
|
340 clrb
|
|
341 rts
|
|
342
|
|
343 * SetStat
|
|
344 *
|
|
345 * Entry:
|
|
346 * A = function code
|
|
347 * Y = address of path descriptor
|
|
348 * U = address of device memory area
|
|
349 *
|
|
350 * Exit:
|
|
351 * CC = carry set on error
|
|
352 * B = error code
|
|
353 *
|
|
354 SetStt cmpa #SS.ComSt
|
|
355 bne Close if not, check if it's a close
|
|
356 ldx PD.RGS,y
|
|
357 ldd R$Y,x
|
|
358 * A = Parity byte
|
|
359 * B = baud rate
|
|
360 L0138 std <V.COM,u save parity, baud rate in com status
|
|
361 IFNE H6309
|
|
362 clrd
|
|
363 ELSE
|
|
364 clra
|
|
365 clrb
|
|
366 ENDC
|
|
367 std <V.PAR,u
|
|
368 sta <V.STP,u
|
|
369 ldd <V.COM,u
|
|
370 tstb
|
|
371 bpl L014C
|
|
372 inc <V.STP,u do 2 stop bits
|
|
373 L014C bitb #$40 make sure the bit is zero
|
|
374 bne Read
|
|
375 bitb #$20 0=8, 1=7 bits
|
|
376 beq L0157
|
|
377 inc <V.BIT,u
|
|
378 L0157 bita #$20
|
|
379 beq L0169 if=0, no parity
|
|
380 bita #$80
|
|
381 beq Read if high bit set (only for ACIA devices), error out
|
|
382 inc <V.PAR,u parity
|
|
383 bita #$40
|
|
384 bne L0169 1=space,
|
|
385 inc <V.PAR,u 2=mark parity
|
|
386 L0169 anda #$0F
|
|
387 sta <V.RTRY,u
|
|
388 rts
|
|
389
|
|
390 Read comb
|
|
391 ldb #E$BMode
|
|
392 rts
|
|
393
|
|
394 L0173 comb
|
|
395 ldb #E$UnkSVc
|
|
396 rts
|
|
397
|
|
398 Close cmpa #SS.Close close the device?
|
|
399 bne L0173
|
|
400 leax V.BUFF,u point to blocked process buffer
|
|
401
|
|
402 C010 lda 1,x get next process number
|
|
403 sta ,x+
|
|
404 bne C010 do until we have a zero byte
|
|
405
|
|
406 lda V.BUFF,u get the first process in the queue
|
|
407 beq C020 if none left
|
|
408 ldb #S$Wake wake up signal
|
|
409 os9 F$Send re-start the blocked process
|
|
410
|
|
411 C020 clrb
|
|
412 rts
|
|
413
|
|
414 emod
|
|
415 eom equ *
|
|
416 end
|