Mercurial > hg > Members > kono > nitros9-code
comparison level1/modules/scdwn.asm @ 2324:ccd33b48321a
Renamed scdwt to scdwn, t/u to n descriptors
author | boisy |
---|---|
date | Tue, 12 Jan 2010 21:43:57 +0000 |
parents | |
children | 080b3670b08f |
comparison
equal
deleted
inserted
replaced
2323:190820cc58f0 | 2324:ccd33b48321a |
---|---|
1 ******************************************************************** | |
2 * scdwn - CoCo DriveWire Network Driver | |
3 * | |
4 * $Id$ | |
5 * | |
6 * Edt/Rev YYYY/MM/DD Modified by | |
7 * Comment | |
8 * ------------------------------------------------------------------ | |
9 * 1 2009/11/30 Aaron Wolfe | |
10 * Started | |
11 * | |
12 * 2009/12/28 Boisy G. Pitre | |
13 * Modified so that F$STime is called if we get an error on calling | |
14 * F$VIRQ (which means the clock module has not be initialized) | |
15 * | |
16 * 2009/12/31 Boisy G. Pitre | |
17 * Fixed crash in Init where F$Link failure would not clean up stack | |
18 * | |
19 * 2010/01/03 Boisy G. Pitre | |
20 * Moved IRQ stuff into DW3 subroutine module | |
21 | |
22 nam scdwn | |
23 ttl CoCo DriveWire Network Driver | |
24 | |
25 ifp1 | |
26 use defsfile | |
27 use dwdefs.d | |
28 endc | |
29 | |
30 | |
31 tylg set Drivr+Objct | |
32 atrv set ReEnt+Rev | |
33 rev set $00 | |
34 edition set 1 | |
35 | |
36 * Note: driver memory defined in dwdefs.d | |
37 mod eom,name,tylg,atrv,start,SCFDrvMemSz | |
38 | |
39 * module info | |
40 fcb READ.+WRITE. ;driver access modes | |
41 name fcs /scdwn/ ;driver name | |
42 fcb edition ;driver edition | |
43 | |
44 * dispatch calls | |
45 start equ * | |
46 lbra Init | |
47 lbra Read | |
48 lbra Write | |
49 lbra GetStat | |
50 lbra SetStat | |
51 | |
52 *********************************************************************** | |
53 * Term | |
54 * | |
55 * shut down the driver. | |
56 * should close only the correct port, tell server to close the port, | |
57 * and remove irq handler when no ports are left | |
58 * | |
59 * Entry: | |
60 * U = address of device memory area | |
61 * | |
62 * Exit: | |
63 * CC = carry set on error | |
64 * B = error code | |
65 Term equ * | |
66 lda <V.PORT+1,u ;get our port # | |
67 pshs a ;port # on stack | |
68 * clear statics table entry | |
69 IFGT Level-1 | |
70 ldx <D.DWStat | |
71 ELSE | |
72 ldx >D.DWStat | |
73 ENDC | |
74 beq tell | |
75 ; cheat: we know DW.StatTbl is at offset $00 from D.DWStat, do not bother with leax | |
76 ; leax DW.StatTbl,x | |
77 clr a,x ;clear out | |
78 | |
79 ; tell server | |
80 tell | |
81 lda #OP_SERTERM ; load command | |
82 pshs a ; command store on stack | |
83 leax ,s ; point X to stack | |
84 ldy #2 ; 2 bytes to send | |
85 | |
86 pshs u | |
87 | |
88 IFGT Level-1 | |
89 ldu <D.DWSubAddr | |
90 ELSE | |
91 ldu >D.DWSubAddr | |
92 ENDC | |
93 beq nosub | |
94 jsr 6,u ; call DWrite | |
95 | |
96 nosub | |
97 puls u | |
98 leas 2,s ; clean 3 DWsub args from stack | |
99 clrb | |
100 rts | |
101 | |
102 *********************************************************************** | |
103 * Init | |
104 * | |
105 * Entry: | |
106 * Y = address of device descriptor | |
107 * U = address of device memory area | |
108 * | |
109 * Exit: | |
110 * CC = carry set on error | |
111 * B = error code | |
112 * | |
113 | |
114 Init equ * | |
115 | |
116 lda IT.PAR,y | |
117 pshs a ; save parity byte for later | |
118 | |
119 ; link to subroutine module | |
120 ; has the link already been done? | |
121 IFGT Level-1 | |
122 ldx <D.DWSubAddr | |
123 ELSE | |
124 ldx >D.DWSubAddr | |
125 ENDC | |
126 bne already ; if so, do not bother | |
127 | |
128 pshs u ; preserve u since os9 link is coming up | |
129 | |
130 IFGT Level-1 | |
131 ldx <D.Proc | |
132 pshs x | |
133 ldx <D.SysPrc | |
134 stx <D.Proc | |
135 ENDC | |
136 clra | |
137 | |
138 leax dw3name,pcr | |
139 os9 F$Link | |
140 IFGT Level-1 | |
141 puls x | |
142 stx <D.Proc | |
143 ENDC | |
144 bcs InitEx2 | |
145 IFGT Level-1 | |
146 sty <D.DWSubAddr | |
147 ELSE | |
148 sty >D.DWSubAddr | |
149 ENDC | |
150 jsr ,y ; call DW init routine | |
151 | |
152 puls u ; restore u | |
153 | |
154 already | |
155 ; tell DW we have a new port opening (port mode already on stack) | |
156 ldb <V.PORT+1,u ; get our port # | |
157 lda #OP_SERINIT ; command | |
158 pshs d ; command + port # on stack | |
159 leax ,s ; point X to stack | |
160 ldy #3 ; # of bytes to send | |
161 | |
162 pshs u | |
163 IFGT Level-1 | |
164 ldu <D.DWSubAddr | |
165 ELSE | |
166 ldu >D.DWSubAddr | |
167 ENDC | |
168 jsr 6,u ; call DWrite | |
169 puls u | |
170 | |
171 ; set up local buffer | |
172 ldb #RxBufDSz ; default Rx buffer size | |
173 leax RxBuff,u ; default Rx buffer address | |
174 stb RxBufSiz,u ; save Rx buffer size | |
175 stx RxBufPtr,u ; save Rx buffer address | |
176 stx RxBufGet,u ; set initial Rx buffer input address | |
177 stx RxBufPut,u ; set initial Rx buffer output address | |
178 abx ; add buffer size to buffer start.. | |
179 stx RxBufEnd,u ; save Rx buffer end address | |
180 | |
181 tfr u,d ; (A = high page of statics) | |
182 puls b | |
183 puls b ; (B = port number) | |
184 IFGT Level-1 | |
185 ldx <D.DWStat | |
186 ELSE | |
187 ldx >D.DWStat | |
188 ENDC | |
189 ; cheat: we know DW.StatTbl is at offset $00 from D.DWStat, do not bother with leax | |
190 ; leax DW.StatTbl,x | |
191 sta b,x | |
192 InitEx equ * | |
193 puls a,pc | |
194 InitEx2 | |
195 puls u | |
196 puls a,pc | |
197 | |
198 ; drivewire info | |
199 dw3name fcs /dw3/ | |
200 | |
201 | |
202 ***************************************************************************** | |
203 * Write | |
204 * | |
205 * Entry: | |
206 * A = character to write | |
207 * Y = address of path descriptor | |
208 * U = address of device memory area | |
209 * | |
210 * Exit: | |
211 * CC = carry set on error | |
212 * B = error code | |
213 * | |
214 Write equ * | |
215 pshs a ; character to send on stack | |
216 ldb <V.PORT+1,u ; port number into B | |
217 lda #OP_SERWRITE ; put command into A | |
218 pshs d | |
219 leax ,s | |
220 ldy #$0003 ; 3 bytes to send.. ugh. need WRITEM (data mode) | |
221 IFGT Level-1 | |
222 ldu <D.DWSubAddr | |
223 ELSE | |
224 ldu >D.DWSubAddr | |
225 ENDC | |
226 jsr 6,u | |
227 WriteOK clrb | |
228 WriteExit puls a,x,pc ; clean stack, return | |
229 | |
230 | |
231 ************************************************************************************* | |
232 * Read | |
233 * | |
234 * Entry: | |
235 * Y = address of path descriptor | |
236 * U = address of device memory area | |
237 * | |
238 * Exit: | |
239 * A = character read | |
240 * CC = carry set on error | |
241 * B = error code | |
242 * | |
243 Read equ * | |
244 pshs cc,dp ; save IRQ/Carry status, system DP | |
245 | |
246 ReadChr orcc #IntMasks ; mask interrupts | |
247 | |
248 lda RxDatLen,u ; get our Rx buffer count | |
249 beq ReadSlp ; no data, go sleep while waiting for new Rx data... | |
250 | |
251 ; we have data waiting | |
252 deca ; one less byte in buffer | |
253 sta RxDatLen,u ; save new Rx data count | |
254 | |
255 ldx RxBufGet,u ; current Rx buffer pickup position | |
256 lda ,x+ ; get Rx character, set up next pickup position | |
257 | |
258 cmpx RxBufEnd,u ; end of Rx buffer? | |
259 blo ReadChr1 ; no, keep pickup pointer | |
260 ldx RxBufPtr,u ; get Rx buffer start address | |
261 ReadChr1 stx RxBufGet,u ; set new Rx data pickup pointer | |
262 | |
263 ; return to caller | |
264 puls cc,dp,pc ; recover IRQ/Carry status, system DP, return with character in A | |
265 | |
266 ReadSlp equ * | |
267 | |
268 IFEQ Level-1 | |
269 ReadSlp2 lda <V.BUSY,u | |
270 sta <V.WAKE,u ; store process id in this port's entry in the waiter table | |
271 lbsr Sleep0 ; sleep level 1 style | |
272 ELSE | |
273 ReadSlp2 lda >D.Proc ; process descriptor address MSB | |
274 sta <V.WAKE,u ; save MSB in V.WAKE | |
275 clrb | |
276 tfr d,x ; process descriptor address | |
277 IFNE H6309 | |
278 oim #Suspend,P$State,x ; suspend | |
279 ELSE | |
280 ldb P$State,x | |
281 orb #Suspend | |
282 stb P$State,x ; suspend | |
283 ENDC | |
284 bsr Sleep1 ; sleep level 2 style | |
285 ENDC | |
286 | |
287 ; we have been awakened.. | |
288 | |
289 ; check for signals | |
290 ldx >D.Proc ; process descriptor address | |
291 ldb P$Signal,x ; pending signal for this process? | |
292 beq ChkState ; no, go check process state... | |
293 cmpb #S$Peer ; (S$Peer or lower) | |
294 bls ErrExit ; yes, go do it... | |
295 | |
296 ChkState equ * | |
297 ; have we been condemned to die? | |
298 IFNE H6309 | |
299 tim #Condem,P$State,x | |
300 ELSE | |
301 ldb P$State,x | |
302 bitb #Condem | |
303 ENDC | |
304 bne PrAbtErr ; yes, go do it... | |
305 | |
306 ; check that our waiter byte was cleared by ISR instance | |
307 tst <V.WAKE,u ; our waiter byte | |
308 beq ReadChr ; 0 = its our turn, go get a character | |
309 bra ReadSlp ; false alarm, go back to sleep | |
310 | |
311 PrAbtErr ldb #E$PrcAbt ; set error code | |
312 | |
313 ErrExit equ * | |
314 IFNE H6309 | |
315 oim #Carry,,s ; set carry | |
316 ELSE | |
317 lda ,s | |
318 ora #Carry | |
319 sta ,s | |
320 ENDC | |
321 puls cc,dp,pc ; restore CC, system DP, return | |
322 | |
323 IFEQ Level-1 | |
324 Sleep0 ldx #$0 ; sleep till ISR wakes us | |
325 bra TimedSlp | |
326 ENDC | |
327 | |
328 Sleep1 ldx #$1 ; just sleep till end of slice, we are suspended (level 2) | |
329 TimedSlp andcc #^Intmasks ; enable IRQs | |
330 os9 F$Sleep | |
331 clr <V.WAKE,u | |
332 rts ; return | |
333 | |
334 | |
335 ********************************************************************** | |
336 * GetStat - heavily borrowed from sc6551 | |
337 * | |
338 * Entry: | |
339 * A = function code | |
340 * Y = address of path descriptor | |
341 * U = address of device memory area | |
342 * | |
343 * Exit: | |
344 * CC = carry set on error | |
345 * B = error code | |
346 * | |
347 GetStat | |
348 clrb ; default to no error... | |
349 pshs cc,dp ; save IRQ/Carry status,system DP | |
350 | |
351 ldx PD.RGS,y ; caller's register stack pointer | |
352 cmpa #SS.EOF | |
353 beq GSExitOK ; SCF devices never return EOF | |
354 | |
355 cmpa #SS.Ready | |
356 bne Advertise ; next check | |
357 | |
358 ; SS.Ready | |
359 lda RxDatLen,u ; get Rx data length | |
360 beq NRdyErr ; none, go report error | |
361 sta R$B,x ; set Rx data available in caller's [B] | |
362 GSExitOK puls cc,dp,pc ; restore Carry status, system DP, return | |
363 | |
364 NRdyErr ldb #E$NotRdy | |
365 bra ErrExit ; return error code | |
366 | |
367 UnSvcErr ldb #E$UnkSvc | |
368 bra ErrExit ; return error code | |
369 | |
370 ; We advertise all of our SERGETSTAT calls (except SS.Ready) to the server | |
371 Advertise | |
372 ldb #OP_SERGETSTAT | |
373 bsr SendStat | |
374 | |
375 ; Note: Here we could somehow obtain the size of the terminal window from the server | |
376 GetScSiz cmpa #SS.ScSiz | |
377 bne GetComSt ; next check | |
378 ldu PD.DEV,y | |
379 ldu V$DESC,u ; device descriptor | |
380 clra | |
381 ldb IT.COL,u ; return screen size | |
382 std R$X,x | |
383 ldb IT.ROW,u | |
384 std R$Y,x | |
385 puls cc,dp,pc ; restore Carry status, system DP, return | |
386 | |
387 GetComSt cmpa #SS.ComSt | |
388 bne UnSvcErr ; no, we have no more answers, report error | |
389 ldd #$0000 ; not used, return $0000 | |
390 std R$Y,x | |
391 sta R$B,x | |
392 puls cc,dp,pc ; restore Carry status, system DP, return | |
393 | |
394 * Advertise Stat Code to server | |
395 * A = Function Code | |
396 * B = OP_SERGETSTAT or OP_SERSETSTAT | |
397 SendStat | |
398 ; advertise our GetStt code to the server | |
399 pshs a,y,x,u | |
400 leas -3,s | |
401 leax ,s | |
402 stb ,x | |
403 sta 2,x | |
404 ldb V.PORT+1,u | |
405 stb 1,x | |
406 ldy #$0003 | |
407 IFGT LEVEL-1 | |
408 ldu <D.DWSubAddr | |
409 ELSE | |
410 ldu >D.DWSubAddr | |
411 ENDC | |
412 jsr 6,u | |
413 leas 3,s | |
414 puls a,y,x,u,pc | |
415 | |
416 ************************************************************************* | |
417 * SetStat | |
418 * | |
419 * Entry: | |
420 * A = function code | |
421 * Y = address of path descriptor | |
422 * U = address of device memory area | |
423 * | |
424 * Exit: | |
425 * CC = carry set on error | |
426 * B = error code | |
427 * | |
428 SetStat | |
429 ldb #OP_SERSETSTAT | |
430 bsr SendStat | |
431 cmpa #SS.ComSt | |
432 bne donebad | |
433 leax PD.OPT,y | |
434 ldy #OPTCNT | |
435 IFGT LEVEL-1 | |
436 ldu <D.DWSubAddr | |
437 ELSE | |
438 ldu >D.DWSubAddr | |
439 ENDC | |
440 jsr 6,u | |
441 clrb | |
442 rts | |
443 | |
444 IFEQ 1 | |
445 SetPortSig | |
446 cmpa #SS.PortSig | |
447 bne SetPortRel | |
448 lda PD.CPR,y current process ID | |
449 ldb R$X+1,x LSB of [X] is signal code | |
450 std <PortSigPID | |
451 clrb | |
452 rts | |
453 SetPortRel | |
454 cmpa #SS.PortRel | |
455 bne donebad | |
456 leax PortSigPID,u | |
457 bsr ReleaSig | |
458 clrb | |
459 rts | |
460 ENDC | |
461 donebad comb | |
462 ldb #E$UnkSVc | |
463 rts | |
464 | |
465 ReleaSig pshs cc save IRQ enable status | |
466 orcc #IntMasks disable IRQs while releasing signal | |
467 lda PD.CPR,y get current process ID | |
468 suba ,x same as signal process ID? | |
469 bne NoReleas no, go return... | |
470 sta ,x clear this signal's process ID | |
471 NoReleas puls cc,pc restore IRQ enable status, return | |
472 | |
473 emod | |
474 eom equ * | |
475 end |