Mercurial > hg > Members > kono > nitros9-code
comparison level1/modules/dw3.asm @ 2308:b5f0c5326e7e
Changes made to move ISR to dw3
author | boisy |
---|---|
date | Sun, 03 Jan 2010 14:35:04 +0000 |
parents | 660cc987e18d |
children | b2bc1ad04163 |
comparison
equal
deleted
inserted
replaced
2307:2f90c1624ab4 | 2308:b5f0c5326e7e |
---|---|
15 ifp1 | 15 ifp1 |
16 use defsfile | 16 use defsfile |
17 use dwdefs.d | 17 use dwdefs.d |
18 endc | 18 endc |
19 | 19 |
20 tylg set Sbrtn+Objct | 20 tylg set Sbrtn+Objct |
21 atrv set ReEnt+rev | 21 atrv set ReEnt+rev |
22 rev set $01 | 22 rev set $01 |
23 | 23 |
24 mod eom,name,tylg,atrv,start,0 | 24 mod eom,name,tylg,atrv,start,0 |
25 | 25 |
26 name fcs /dw3/ | 26 * irq |
27 IRQPckt fcb $00,$01,$0A ;IRQ packet Flip(1),Mask(1),Priority(1) bytes | |
28 * Default time packet | |
29 DefTime dtb | |
30 | |
31 name fcs /dw3/ | |
27 | 32 |
28 * DriveWire subroutine entry table | 33 * DriveWire subroutine entry table |
29 start lbra Init | 34 start lbra Init |
30 bra Read | 35 bra Read |
31 nop | 36 nop |
32 lbra Write | 37 lbra Write |
33 | 38 |
34 * Term | 39 * Term |
35 * | 40 * |
36 * Entry: | 41 * Entry: |
37 * U = address of device memory area | 42 * U = address of device memory area |
39 * Exit: | 44 * Exit: |
40 * CC = carry set on error | 45 * CC = carry set on error |
41 * B = error code | 46 * B = error code |
42 * | 47 * |
43 Term | 48 Term |
44 clrb clear Carry | 49 clrb clear Carry |
45 rts | 50 rts |
46 | |
47 * Init | |
48 * | |
49 * Entry: | |
50 * Y = address of device descriptor | |
51 * U = address of device memory area | |
52 * | |
53 * Exit: | |
54 * CC = carry set on error | |
55 * B = error code | |
56 * | |
57 * Initialize the serial device | |
58 Init | |
59 clrb clear Carry | |
60 pshs cc,x then push CC on stack | |
61 orcc #IntMasks | |
62 ldx #PIA1Base $FF20 | |
63 clr 1,x clear CD | |
64 lda #%11111110 | |
65 sta ,x | |
66 lda #%00110100 | |
67 sta 1,x | |
68 lda ,x | |
69 puls cc,x,pc | |
70 | 51 |
71 * Read | 52 * Read |
72 * | 53 * |
73 * ON ENTRY: | 54 * ON ENTRY: |
74 * X = ADDRESS OF THE RECEIVE BUFFER | 55 * X = ADDRESS OF THE RECEIVE BUFFER |
79 * D = ACTUAL NUMBER OF BYTES RECEIVED | 60 * D = ACTUAL NUMBER OF BYTES RECEIVED |
80 * X AND U ARE PRESERVED | 61 * X AND U ARE PRESERVED |
81 * CC.CARRY IS SET IF A FRAMING ERROR WAS DETECTED | 62 * CC.CARRY IS SET IF A FRAMING ERROR WAS DETECTED |
82 * | 63 * |
83 Read | 64 Read |
84 use dwread.asm | 65 use dwread.asm |
85 | 66 |
86 * Write | 67 * Write |
87 * | 68 * |
88 * Entry: | 69 * Entry: |
89 Write | 70 Write |
90 use dwwrite.asm | 71 use dwwrite.asm |
72 | |
73 * Init | |
74 * | |
75 * Entry: | |
76 * Y = address of device descriptor | |
77 * U = address of device memory area | |
78 * | |
79 * Exit: | |
80 * CC = carry set on error | |
81 * B = error code | |
82 * | |
83 * Initialize the serial device | |
84 Init | |
85 clrb clear Carry | |
86 pshs y,x,cc then push CC on stack | |
87 orcc #IntMasks | |
88 ldx #PIA1Base $FF20 | |
89 clr 1,x clear CD | |
90 lda #%11111110 | |
91 sta ,x | |
92 lda #%00110100 | |
93 sta 1,x | |
94 lda ,x | |
95 | |
96 ; allocate DW statics page | |
97 pshs u | |
98 ldd #$0100 | |
99 os9 F$SRqMem | |
100 tfr u,x | |
101 puls u | |
102 lbcs InitEx | |
103 IFGT Level-1 | |
104 stx <D.DWStat | |
105 ELSE | |
106 stx >D.DWStat | |
107 ENDC | |
108 ; clear out 256 byte page at X | |
109 clrb | |
110 loop@ clr ,x+ | |
111 decb | |
112 bne loop@ | |
113 | |
114 * install ISR | |
115 InstIRQ | |
116 IFGT Level-1 | |
117 ldx <D.DWStat | |
118 ELSE | |
119 ldx >D.DWStat | |
120 ENDC | |
121 leax DW.VIRQPkt,x | |
122 pshs u | |
123 tfr x,u | |
124 leax Vi.Stat,x ;fake VIRQ status register | |
125 lda #$80 ;VIRQ flag clear, repeated VIRQs | |
126 sta ,x ;set it while we're here... | |
127 tfr x,d ;copy fake VIRQ status register address | |
128 leax IRQPckt,pcr ;IRQ polling packet | |
129 leay IRQSvc,pcr ;IRQ service entry | |
130 os9 F$IRQ ;install | |
131 puls u | |
132 bcs InitEx ;exit with error | |
133 ldd #$0003 ;lets try every 6 ticks (0.1 seconds) -- testing 3, gives better response in interactive things | |
134 IFGT Level-1 | |
135 ldx <D.DWStat | |
136 ELSE | |
137 ldx >D.DWStat | |
138 ENDC | |
139 leax DW.VIRQPkt,x | |
140 std Vi.Rst,x ; reset count | |
141 tfr x,y ; move VIRQ software packet to Y | |
142 tryagain | |
143 ldx #$0001 ; code to install new VIRQ | |
144 os9 F$VIRQ ; install | |
145 bcc IRQok ; no error, continue | |
146 cmpb #E$UnkSvc | |
147 bne InitEx | |
148 ; if we get an E$UnkSvc error, then clock has not been initialized, so do it here | |
149 leax DefTime,pcr | |
150 os9 F$STime | |
151 bra tryagain ; note: this has the slim potential of looping forever | |
152 IRQok | |
153 IFGT Level-1 | |
154 ldx <D.DWStat | |
155 ELSE | |
156 ldx >D.DWStat | |
157 ENDC | |
158 ; cheat: we know DW.StatTbl is at offset $00 from D.DWStat, do not bother with leax | |
159 leax DW.StatTbl,x | |
160 tfr u,d | |
161 ldb <V.PORT+1,u ; get our port # | |
162 sta b,x ; store in table | |
163 | |
164 InitEx | |
165 puls cc,x,y,pc | |
166 | |
167 | |
168 ; *********************************************************************** | |
169 ; Interrupt handler - Much help from Darren Atkinson | |
170 | |
171 IRQMulti3 anda #$1F ; mask first 5 bits, a is now port #+1 | |
172 deca ; we pass +1 to use 0 for no data | |
173 pshs a ; save port # | |
174 cmpb RxGrab,u ; compare room in buffer to server's byte | |
175 bhs IRQM06 ; room left >= server's bytes, no problem | |
176 | |
177 stb RxGrab,u ; else replace with room left in our buffer | |
178 | |
179 ; also limit to end of buffer | |
180 IRQM06 ldd RxBufEnd,u ; end addr of buffer | |
181 subd RxBufPut,u ; subtract current write pointer, result is # bytes left going forward in buff. | |
182 | |
183 IRQM05 cmpb RxGrab,u ; compare b (room left) to grab bytes | |
184 bhs IRQM03 ; branch if we have room for grab bytes | |
185 | |
186 stb RxGrab,u ; else set grab to room left | |
187 | |
188 ; send multiread req | |
189 IRQM03 puls a ; port # is on stack | |
190 ldb RxGrab,u | |
191 | |
192 pshs u | |
193 | |
194 ; setup DWsub command | |
195 pshs d ; (a port, b bytes) | |
196 lda #OP_SERREADM ; load command | |
197 pshs a ; command store on stack | |
198 leax ,s ; point X to stack | |
199 ldy #3 ; 3 bytes to send | |
200 | |
201 IFGT Level-1 | |
202 ldu <D.DWSubAddr | |
203 ELSE | |
204 ldu >D.DWSubAddr | |
205 ENDC | |
206 jsr 6,u ; call DWrite | |
207 | |
208 leas 3,s ; clean 3 DWsub args from stack | |
209 | |
210 ldx ,s ; pointer to this port's area (from U prior), leave it on stack | |
211 ldb RxGrab,x ; set B to grab bytes | |
212 clra ; 0 in high byte | |
213 tfr d,y ; set # bytes for DW | |
214 | |
215 ldx RxBufPut,x ; point X to insert position in this port's buffer | |
216 ; receive response | |
217 jsr 3,u ; call DWRead | |
218 ; handle errors? | |
219 | |
220 | |
221 puls u | |
222 ldb RxGrab,u ; our grab bytes | |
223 | |
224 ; set new RxBufPut | |
225 ldx RxBufPut,u ; current write pointer | |
226 abx ; add b (# bytes) to RxBufPut | |
227 cmpx RxBufEnd,u ; end of Rx buffer? | |
228 blo IRQM04 ; no, go keep laydown pointer | |
229 ldx RxBufPtr,u ; get Rx buffer start address | |
230 IRQM04 stx RxBufPut,u ; set new Rx data laydown pointer | |
231 | |
232 ; set new RxDatLen | |
233 ldb RxDatLen,u | |
234 addb RxGrab,u | |
235 stb RxDatLen,u ; store new value | |
236 | |
237 bra CkSuspnd | |
238 | |
239 IRQMulti | |
240 ; initial grab bytes | |
241 stb RxGrab,u | |
242 | |
243 ; limit server bytes to bufsize - datlen | |
244 ldb RxBufSiz,u ; size of buffer | |
245 subb RxDatLen,u ; current bytes in buffer | |
246 bne IRQMulti3 ; continue, we have some space in buffer | |
247 ; no room in buffer | |
248 tstb | |
249 bne CkSuspnd | |
250 bra IRQExit | |
251 | |
252 | |
253 ; **** IRQ ENTRY POINT | |
254 IRQSvc equ * | |
255 pshs cc,dp ; save system cc,DP | |
256 orcc #IntMasks ; mask interrupts | |
257 | |
258 ; mark VIRQ handled (note U is pointer to our VIRQ packet in DP) | |
259 lda Vi.Stat,u ; VIRQ status register | |
260 anda #^Vi.IFlag ; clear flag in VIRQ status register | |
261 sta Vi.Stat,u ; save it... | |
262 | |
263 ; poll server for incoming serial data | |
264 | |
265 ; send request | |
266 lda #OP_SERREAD ; load command | |
267 pshs a ; command store on stack | |
268 leax ,s ; point X to stack | |
269 ldy #1 ; 1 byte to send | |
270 | |
271 IFGT Level-1 | |
272 ldu <D.DWSubAddr | |
273 ELSE | |
274 ldu >D.DWSubAddr | |
275 ENDC | |
276 jsr 6,u ; call DWrite | |
277 | |
278 ; receive response | |
279 leas -1,s ; one more byte to fit response | |
280 leax ,s ; point X to stack head | |
281 ldy #2 ; 2 bytes to retrieve | |
282 jsr 3,u ; call DWRead | |
283 beq IRQSvc2 ; branch if no error | |
284 leas 2,s ; error, cleanup stack 2 | |
285 bra IRQExit2 ; don't reset error count on the way out | |
286 | |
287 ; process response | |
288 IRQSvc2 | |
289 ldd ,s++ ; pull returned status byte into A,data into B (set Z if zero, N if multiread) | |
290 beq IRQExit ; branch if D = 0 (nothing to do) | |
291 | |
292 ; save back D on stack and build our U | |
293 pshs d | |
294 anda #$1F ; mask first 5 bits, a is now port #+1 | |
295 deca ; we pass +1 to use 0 for no data | |
296 ; here we set U to the static storage area of the device we are working with | |
297 IFGT Level-1 | |
298 ldx <D.DWStat | |
299 ELSE | |
300 ldx >D.DWStat | |
301 ENDC | |
302 ; cheat: we know DW.StatTbl is at offset $00 from D.DWStat, do not bother with leax | |
303 ; leax DW.StatTbl,x | |
304 lda a,x | |
305 bne IRQCont ; if A is 0, then this device is not active, so exit | |
306 puls d | |
307 bra IRQExit | |
308 IRQCont | |
309 clrb | |
310 tfr d,u | |
311 | |
312 ldd ,s++ ; pull returned status byte into A,data into B (set Z if zero, N if multiread) | |
313 | |
314 bmi IRQMulti ; branch for multiread | |
315 | |
316 ; put byte B in port As buffer - optimization help from Darren Atkinson | |
317 IRQPutCh ldx RxBufPut,u ; point X to the data buffer | |
318 | |
319 ; process interrupt/quit characters here | |
320 ; note we will have to do this in the multiread (ugh) | |
321 tfr b,a ; put byte in A | |
322 ldb #S$Intrpt | |
323 cmpa V.INTR,u | |
324 beq send@ | |
325 ldb #S$Abort | |
326 cmpa V.QUIT,u | |
327 bne store | |
328 send@ lda V.LPRC,u | |
329 beq IRQExit | |
330 os9 F$Send | |
331 bra IRQExit | |
332 | |
333 store | |
334 ; store our data byte | |
335 sta ,x+ ; store and increment buffer pointer | |
336 | |
337 ; adjust RxBufPut | |
338 cmpx RxBufEnd,u ; end of Rx buffer? | |
339 blo IRQSkip1 ; no, go keep laydown pointer | |
340 ldx RxBufPtr,u ; get Rx buffer start address | |
341 IRQSkip1 stx RxBufPut,u ; set new Rx data laydown pointer | |
342 | |
343 ; increment RxDatLen | |
344 inc RxDatLen,u | |
345 | |
346 | |
347 ; check if we have a process waiting for data | |
348 CkSuspnd lda <V.WAKE,u ; V.WAKE? | |
349 beq IRQExit ; no | |
350 clr <V.WAKE,u ; clear V.WAKE | |
351 | |
352 ; wake up waiter for read | |
353 IFEQ Level-1 | |
354 ldb #S$Wake | |
355 os9 F$Send | |
356 ELSE | |
357 clrb | |
358 tfr d,x ; copy process descriptor pointer | |
359 lda P$State,x ; get state flags | |
360 anda #^Suspend ; clear suspend state | |
361 sta P$State,x ; save state flags | |
362 ENDC | |
363 | |
364 IRQExit | |
365 IRQExit2 puls cc,dp,pc ; restore interrupts cc,dp, return | |
91 | 366 |
92 emod | 367 emod |
93 eom equ * | 368 eom equ * |
94 end | 369 end |