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