Mercurial > hg > Members > kono > nitros9-code
annotate level1/modules/rbsuper.asm @ 2910:87f2133301b0
Remove execute permissions from files that should not have it
author | Tormod Volden <debian.tormod@gmail.com> |
---|---|
date | Sat, 11 Jan 2014 21:52:42 +0100 |
parents | ebf319736e9c |
children |
rev | line source |
---|---|
2590 | 1 ******************************************************************** |
2 * rbsuper - RBF Super Caching Device Driver | |
3 * | |
4 * $Id$ | |
5 * | |
6 * (C) 2004 Boisy G. Pitre - Licensed to Cloud-9 | |
7 * | |
8 * RBSuper is the framework for a new type of RBF device driver -- one | |
9 * that fetches native-size, or PHYSICAL sectors. A physical sector is | |
10 * a sector that is sized to its device. For example, all IDE drives and | |
11 * pretty much all SCSI drives have 512 byte sectors; CD-ROMs have 2048 | |
12 * byte sectors. | |
13 * | |
14 * As a high-level driver, this module is responsible for managing | |
15 * the cache, verifying writes, etc. | |
16 * | |
17 * The actual reading and writing of sectors is performed by the | |
18 * low-level driver, which can be designed for any device. | |
19 * | |
20 * Conditionals: | |
21 * H6309 - if set, assembles for 6309 | |
22 * USECS - if set, uses critical section code (slows down driver) | |
23 * HDBDOS - if set, adds code to handle HDB-DOS partitions | |
2733
ebf319736e9c
Adjusted disk format for dw .dsk's, took a blank line out of regdmp to compact its display
gheskett
parents:
2590
diff
changeset
|
24 * And somewhere this flag has been lost GH 2012/11/13 |
ebf319736e9c
Adjusted disk format for dw .dsk's, took a blank line out of regdmp to compact its display
gheskett
parents:
2590
diff
changeset
|
25 * Only found when I trashed my systems vdisks |
ebf319736e9c
Adjusted disk format for dw .dsk's, took a blank line out of regdmp to compact its display
gheskett
parents:
2590
diff
changeset
|
26 HDBDOS set 1 |
2590 | 27 * Edt/Rev YYYY/MM/DD Modified by |
28 * Comment | |
29 * ------------------------------------------------------------------ | |
30 * 2004/04/10 Boisy G. Pitre | |
31 * Created due to Mark's constant harping about a NitrOS-9 driver for | |
32 * the SuperIDE Interface. Here ya go, Marlette. | |
33 * | |
34 * 2005/12/12 Boisy G. Pitre | |
35 * The SS.VarSect call has been moved from the low level driver to rbsuper | |
36 * for efficiency. Also it no longer calls SS.DSize every time it is called. | |
37 * Instead, it only calls it the first time, then caches the sector size value | |
38 * and returns that value on subsequent calls. | |
39 * | |
40 * 2005/12/13 Boisy G. Pitre | |
41 * Employed a trick to "shift" the idea of where the driver's static | |
42 * data starts at the start of each entry point. This saves about 200 | |
43 * bytes of memory. | |
44 * | |
45 * 1 2006/08/20 Boisy G. Pitre | |
46 * Fixed bug where linking to a non-existent module in Init would cause a crash | |
47 * because IOMan calls the Term routine when Init returns an error. Added a simple | |
48 * one line test in Term to see if a value was non-zero which would indicate if Init | |
49 * | |
50 * 2 2008/02/05 Boisy G. Pitre | |
51 * Fixed bug where DNS HDB flag was being pulled from PD.TYP byte instead of PD.DNS. | |
52 * | |
53 * 3 2011/12/22 Boisy G. Pitre | |
54 * Made a "fast path" for 256 byte sector devices to read/write directly into PD.BUF | |
55 * instead of using the cache, for performance reasons. | |
56 * Conditionalized critical section code since it may not be needed, and affects performance. | |
57 | |
58 NAM rbsuper | |
59 TTL RBF Super Caching Device Driver | |
60 | |
61 IFP1 | |
62 USE defsfile | |
63 USE rbsuper.d | |
64 ENDC | |
65 | |
66 tylg SET Drivr+Objct | |
67 atrv SET ReEnt+rev | |
68 rev SET 0 | |
69 edition SET 2 | |
70 | |
71 MOD eom,name,tylg,atrv,start,V.RBSuper | |
72 | |
73 FCB DIR.+SHARE.+PEXEC.+PREAD.+PWRIT.+EXEC.+UPDAT. | |
74 | |
75 name FCS /RBSuper/ | |
76 FCB edition | |
77 | |
78 start lbra Init | |
79 bra Read | |
80 nop | |
81 lbra Write | |
82 lbra GetStat | |
83 lbra SetStat | |
84 | |
85 * | |
86 * Term | |
87 * | |
88 * Entry: | |
89 * U = address of device memory area | |
90 * | |
91 * Exit: | |
92 * CC = carry set on error | |
93 * B = error code | |
94 * | |
95 Term leau UOFFSET,u | |
96 * Free memory allocated for cache | |
97 lda V.CchSize,u get cache size into A | |
98 * Note, the next line fixes a bug where the system would crash when F$Link in Init failed. | |
99 * If it fails, V.CchSize will never get set, and since it is set to 0 initally, we assume | |
100 * that init failed if V.CchSize is 0 and thus we simply return. | |
101 beq ret@ | |
102 tfr u,x move statics ptr into X for safety | |
103 ldu V.CchAddr,u and load U with cache address | |
104 beq nofree@ | |
105 os9 F$SRtMem return cache memory to system | |
106 nofree@ tfr x,u and restore statics ptr | |
107 * Call low-level driver term | |
108 ldx V.LLTerm,u | |
109 lbsr LLCall | |
110 * Unlink low-level driver | |
111 IFGT Level-1 | |
112 ldx D.Proc get curr proc ptr | |
113 ldd D.SysPrc get system process desc ptr | |
114 std D.Proc and make current proc | |
115 ENDC | |
116 ldu V.LLAddr,u get the address of the low-level module | |
117 os9 F$Unlink unlink it | |
118 IFGT Level-1 | |
119 stx D.Proc restore | |
120 ENDC | |
121 ret@ rts return | |
122 | |
123 * | |
124 * Read | |
125 * | |
126 * Entry: | |
127 * B = MSB of the disk's LSN | |
128 * X = LSB of the disk's LSN | |
129 * Y = address of path descriptor | |
130 * U = address of device memory area | |
131 * | |
132 * Exit: | |
133 * CC = carry set on error | |
134 * B = error code | |
135 * | |
136 Read leau UOFFSET,u | |
137 cmpx #$0000 LSN 0? | |
138 bne ReadSect branch if not | |
139 tstb LSN 0? | |
140 bne ReadSect branch if not | |
141 bsr ReadSect else read LSN0 | |
142 bcs bye if error, return | |
143 * Code to deal with copying LSN0 | |
144 leax DRVBEG-UOFFSET,u point X to start of drive table | |
145 ldb PD.DRV,y get drive number | |
146 lsn@ beq CopyLSN0 branch if zero | |
147 leax DRVMEM,x else increase X by drive table size | |
148 decb decrement drive number | |
149 bra lsn@ branch to loop | |
150 | |
151 * X = drive table pointer for PD.DRV | |
152 * Copy DD.SIZ bytes (LSN0) from buffer to drive table | |
153 CopyLSN0 EQU * | |
154 ldu PD.BUF,y | |
155 IFNE H6309 | |
156 ldw #DD.SIZ | |
157 tfm u+,x+ | |
158 ELSE | |
159 ldb #DD.SIZ | |
160 CpyLSNLp pulu a one cycle less than lda ,u+ | |
161 sta ,x+ | |
162 decb | |
163 bne CpyLSNLp | |
164 ENDC | |
165 rret rts | |
166 | |
167 IFNE HDBDOS | |
168 * For HDB-DOS, we must add in drive number | |
169 * First, multiply drive number in descriptor by $276 (630 sectors), | |
170 * then, add the product to the PSect | |
171 ComputeHDB | |
172 IFNE H6309 | |
173 clra | |
174 ldb V.HDBDrive,u | |
175 muld #$0276 | |
176 addw V.PhysSect+1,u | |
177 stw V.PhysSect+1,u | |
178 adcb V.PhysSect,u | |
179 stb V.PhysSect,u | |
180 ELSE | |
181 leas -4,s make a stack to store product of $276 * DriveNum | |
182 lda V.HDBDrive,u get drive number | |
183 ldb #$76 | |
184 mul | |
185 std 2,s | |
186 lda V.HDBDrive,u | |
187 ldb #$02 | |
188 mul | |
189 std ,s | |
190 clrb | |
191 lda 1,s | |
192 addd 2,s | |
193 std 2,s | |
194 bcc f@ | |
195 inc ,s | |
196 f@ lda ,s | |
197 sta 1,s | |
198 ldd 2,s | |
199 addd V.PhysSect+1,u | |
200 std V.PhysSect+1,u | |
201 lda 1,s | |
202 adca V.PhysSect,u | |
203 sta V.PhysSect,u | |
204 leas 4,s | |
205 ENDC | |
206 ENDC | |
207 bye rts | |
208 | |
209 * 256 byte sector device: setup for low level driver to put 256 byte sector directly into PD.BUF | |
210 Read256 | |
211 lbsr Log2Phys | |
212 * We may not have to do this (and disturb the cache as a result) | |
213 * lda PD.DRV,y get current drive number | |
214 * sta V.LastDrv,u and make this the current drive | |
215 lda #1 | |
216 sta V.SectCnt,u | |
217 ldx PD.BUF,y put address of PD.BUF directly into cache spot | |
218 stx V.CchPSpot,u | |
219 * Call low-level driver read | |
220 ldx V.LLRead,u | |
221 lbra LLCall | |
222 | |
223 * Read Sector | |
224 * | |
225 * The sector will be read from either the cache or the controller. | |
226 * A cache "hit" is verified by two methods: | |
227 * 1. Comparing the drive number of the drive for the current path to | |
228 * the drive number of the last path -- if they match, we *MAY* | |
229 * have a cache hit. If not, we fill the cache | |
230 * 2. If #1 matches, then we know the current drive and the last drive | |
231 * are the same. We then check the logical sector to see if it is | |
232 * in the cache. | |
233 * | |
234 * Entry: | |
235 * Y = address of path descriptor | |
236 * U = address of device memory area | |
237 * B = Sector bits 23-16 | |
238 * X = Sector bits 15-0 | |
239 * | |
240 ReadSect bsr PreXfr to pre-transfer stuff | |
241 bcs bye branch if error | |
242 IFNE HDBDOS | |
243 tst V.HDBPart,u HDB-DOS partition? | |
244 beq NotHDB | |
245 * This is the HDB-DOS partition "read" code path. | |
246 * As an HDB-DOS partition, we are interested ONLY in reading the first 256 bytes | |
247 * regardless of the size of the cache. | |
248 lda V.SectSize,u get sector size (0=256,1=512,2=1024,etc) | |
249 leax SCTTBL,pcr | |
250 lda a,x | |
251 sta V.Log2Phys,u set logical sectors per phys | |
252 lda #$01 get sector count | |
253 sta V.SectCnt,u and store it | |
254 sta V.CchDirty,u the cache will ALWAYS be dirty in HDB-DOS mode | |
255 lda V.LogSect,u get logical sector stored earlier | |
256 sta V.PhysSect,u save off logical sector as physical one | |
257 ldd V.LogSect+1,u get logical sector stored earlier | |
258 std V.PhysSect+1,u save off logical sector as physical sector | |
259 lbsr AddSectorOffset add in partition offset and HDB-DOS drive | |
260 bsr ComputeHDB and compute HDB-DOS offset | |
261 * Set up the pointer to the buffer | |
262 ldx V.CchAddr,u get address of cache | |
263 stx V.CchPSpot,u save in current sector pointer | |
264 * Call low-level driver | |
265 ldx V.LLRead,u | |
266 lbsr LLCall | |
267 bcs bye | |
268 ldx V.CchAddr,u get cache pointer which holds HDB-DOS sector | |
269 bra CopyXToPDBUF | |
270 ENDC | |
271 NotHDB | |
272 * New: Dec 20, 2011 | |
273 * Fast path opportunity: if sector size is 256 bytes, call LLRead right into PD.BUF | |
274 tst V.SectSize,u (0=256 byte sector device) | |
275 beq Read256 | |
276 bsr ValidateCache | |
277 bcs ex@ | |
278 * Copy appropriate 256 byte sector from V.CchAddr to PD.BUF,y | |
279 lda V.CchSize,u get hi byte of cache size | |
280 deca | |
281 anda V.LogSect+2,u | |
282 clrb | |
283 ldx V.CchAddr,u | |
284 leax d,x | |
285 CopyXToPDBUF pshs y | |
286 ldy PD.BUF,y | |
287 IFNE H6309 | |
288 ldw #256 | |
289 tfm x+,y+ | |
290 clrb | |
291 puls y,pc | |
292 ELSE | |
293 clr ,-s | |
294 next@ ldd ,x++ | |
295 std ,y++ | |
296 inc ,s | |
297 bpl next@ | |
298 clrb | |
299 puls a,y,pc | |
300 ENDC | |
301 ex@ rts | |
302 | |
303 * ValidateCache | |
304 * | |
305 * Check if the cache is coherent (i.e. contains requested sector). | |
306 * If the cache is NOT coherent, it calls 'FillCache' to fill it. | |
307 ValidateCache | |
308 * We must determine if the currently requested sector is already in cache. | |
309 * First, is this drive the same as the last drive that accessed the cache? | |
310 * If not, then we need to fill the cache with sectors from the current drive. | |
311 tst V.CchDirty,u has cache been initialized? | |
312 bne nomatch branch if not | |
313 lda PD.DRV,y get current drive | |
314 cmpa V.LastDrv,u save as last drive to access cache? | |
315 bne nomatch if not, fill cache | |
316 * Same drive as last access... is this sector in cache? | |
317 ldb V.LogSect,u save off logical sector | |
318 cmpb V.CchBase,u compare bits 23-16 | |
319 bne nomatch branch if not the same | |
320 lda V.LogSect+1,u save off logical sector | |
321 ldb V.CchSize,u get hi byte of cache size | |
322 decb decrement (e.g. 8=7,4=3,2=1,1=0) | |
323 comb invert (e.g. 7=$F8,3=$FC,1=$FE,0=$FF) | |
324 andb V.LogSect+2,u mask out cached sectors | |
325 cmpd V.CchBase+1,u same as what's in cache? | |
326 beq exok@ YES, WE HAVE A CACHE HIT!!! | |
327 nomatch bra FillCache no, we must fil the cache | |
328 * | |
329 * PreXfr | |
330 * | |
331 * Called at read/write to gather info from path descriptor and | |
332 * device descriptor. | |
333 PreXfr stb V.LogSect,u save off logical sector | |
334 stx V.LogSect+1,u save off logical sector | |
335 lda PD.STP,y get possible HDB-DOS drive number | |
336 sta V.HDBDrive,u save off in our statics | |
337 lda PD.TYP,y | |
338 anda #TYPH.SSM lob off all but sector size bits | |
339 * SmartCache - check if our current cache can accommodate this sector size | |
340 cmpa V.SectSize,u do we need to expand? | |
341 bls no@ branch if not | |
342 * Yes, we need to free our current cache mem and alloc more | |
343 pshs a,u save regs | |
344 ldd V.CchSize,u get current cache size | |
345 ldu V.CchAddr,u and cache pointer | |
346 beq nofree@ | |
347 os9 F$SRtMem return that memory | |
348 nofree@ puls a,u restore regs | |
349 lbsr ExpandCache go expand cache | |
350 bcs ex@ and branch if error | |
351 sta V.SectSize,u save new sector size | |
352 no@ | |
353 lda PD.DNS,y get DNS byte | |
354 anda #DNS.HDB isolate HDB-DOS flag | |
355 sta V.HDBPart,u and save state | |
356 exok@ clrb clear carry | |
357 rts return | |
358 ex@ clr V.SectSize,u clear sector size to force realloc | |
359 orcc #Carry set carry (indicates error) | |
360 rts return | |
361 | |
362 * FillCache | |
363 * | |
364 * Fill the cache with sectors from the device. | |
365 * | |
366 * Destroys: A, B, X | |
367 FillCache | |
368 lda V.LogSect,u get logical sector bits 23-16 | |
369 sta V.CchBase,u save as cached base | |
370 lda V.LogSect+1,u save off logical sector | |
371 ldb V.CchSize,u get hi byte of cache size (1, 2, 4 or 8) | |
372 decb decrement (e.g. 8=7,4=3,2=1,1=0) | |
373 comb invert (e.g. 7=$F8,3=$FC,1=$FE,0=$FF) | |
374 andb V.LogSect+2,u mask out cached sectors | |
375 std V.CchBase+1,u save as cached base | |
376 lbsr Log2Phys convert logical sectors to physical | |
377 lda PD.DRV,y get current drive number | |
378 sta V.LastDrv,u and make this the currently cached drive | |
379 * Set up the transfer | |
380 ldb V.CchSize,u get upper 8 bits of cache size | |
381 lda V.SectSize,u get sector size (0=256,1=512,2=1024,etc) | |
382 leax SCTTBL,pcr | |
383 lda a,x | |
384 sta V.Log2Phys,u | |
385 lda V.SectSize,u get sector size (0=256,1=512,2=1024,etc) | |
386 beq ok@ | |
387 lsr@ lsrb divide by 2 | |
388 deca decrement | |
389 bne lsr@ else divide again | |
390 ok@ stb V.SectCnt,u save sector count | |
391 decb | |
392 comb | |
393 andb V.PhysSect+2,u | |
394 stb V.PhysSect+2,u | |
395 * Set up the pointer to the buffer | |
396 ldx V.CchAddr,u get pointer to big buffer | |
397 stx V.CchPSpot,u save in current sector pointer | |
398 * Call low-level driver read | |
399 ldx V.LLRead,u | |
400 bsr LLCall | |
401 bcs ex@ | |
402 clr V.CchDirty,u cache is no longer dirty | |
403 clrb | |
404 rts | |
405 ex@ stb V.CchDirty,u store error code as dirty flag | |
406 rts | |
407 | |
408 | |
409 SCTTBL FCB 256/256 | |
410 FCB 512/256 | |
411 FCB 1024/256 | |
412 FCB 2048/256 | |
413 | |
414 * GetStat/SetStat | |
415 * | |
416 * Entry: | |
417 * R$B = function code | |
418 * Y = address of path descriptor | |
419 * U = address of device memory area | |
420 * | |
421 * Exit: | |
422 * CC = carry set on error | |
423 * B = error code | |
424 * | |
425 SetStat leau UOFFSET,u | |
426 ldx V.LLStSt,u | |
427 bra LLCall | |
428 | |
429 SSVarSect ldb PD.DRV,y get drive number | |
430 leax V.SSCache,u point to sector size cache table | |
431 abx | |
432 lda ,x get sector size | |
433 bne go2@ if not zero, use that value | |
434 pshs x | |
435 ldx PD.RGS,y | |
436 pshs x | |
437 leas -R$Size,s | |
438 sts PD.RGS,y | |
439 lda #SS.DSize | |
440 sta R$B,s | |
441 bsr gs2 make a call to low level driver's SS.DSize | |
442 * Be sure that no instructions from here to the bcs modify carry | |
443 lda R$A,s | |
444 leas R$Size,s | |
445 puls x | |
446 stx PD.RGS,y | |
447 puls x | |
448 bcs ex@ | |
449 cmpa #8 2048 byte sector? | |
450 beq go@ | |
451 lsra else shift right | |
452 FCB $8C skip next two bytes (cmpx...) | |
453 go@ lda #3 | |
454 sta ,x save newly acquired value off into cached size table | |
455 go2@ pshs a | |
456 lda PD.TYP,y | |
457 anda #^TYPH.SSM | |
458 ora ,s+ | |
459 * Boisy's Notes 3/27/06: | |
460 * Notice that we save the true sector size of the device in the PD.TYP byte of | |
461 * the path descriptor EACH TIME SS.VarSect is called. This is important, | |
462 * because it alleviates the user from having to set this value in the device | |
463 * descriptor in a situation where the device being accessed has a larger sector | |
464 * size than what is in the device descriptor. | |
465 * | |
466 * Note that the value in the device descriptor IS used to initially determine | |
467 * the size of the cache at INIT time since we haven't even talked to the | |
468 * controller at that time yet to query it for its size. | |
469 * sta PD.TYP,y and in path descriptor | |
470 clrb | |
471 ex@ rts | |
472 | |
473 | |
474 GetStat leau UOFFSET,u | |
475 ldx PD.RGS,y get registers | |
476 ldb R$B,x get caller's B | |
477 cmpb #SS.VarSect | |
478 beq SSVarSect | |
479 | |
480 gs2 ldx V.LLGtSt,u | |
481 | |
482 * Entry: Y = path desc ptr | |
483 * U = statics ptr | |
484 * X = address of routine to call | |
485 LLCall | |
486 IFEQ USECS-1 | |
487 pshs a preserve A for duration of csacq_wait | |
488 lda #255 wait the maximum number of counts | |
489 bsr csacq_wait acquire the critical section | |
490 tsta test A for zero | |
491 puls a restore A | |
492 beq cserr return if A was zero (semaphore wasn't acquired) | |
493 ENDC | |
494 pshs u,y save U and Y | |
495 jsr ,x call low level routine | |
496 puls y,u restore U and Y | |
497 | |
498 IFEQ USECS-1 | |
499 * Critical Section Release - clear the critial section to zero, allowing others to use it | |
500 csrel pshs cc preserve CC | |
501 clr V.LLSema,u clear critical section | |
502 puls cc,pc restore CC and return | |
503 cserr comb set the carry | |
504 ldb #111 and load B with error indicating a semaphore timeout | |
505 ENDC | |
506 rts | |
507 | |
508 IFEQ USECS-1 | |
509 * Critical Section Acquire With Wait | |
510 * | |
511 * Entry: | |
512 * A = number of times to check before giving up | |
513 * | |
514 * Exit: | |
515 * A = status (>0 = Critical section acquired, 0 = Critical section not acquired) | |
516 * | |
517 csacq_wait pshs cc save CC on stack | |
518 orcc #IntMasks mask interrupts | |
519 tst V.LLSema,u does someone already have the critical section? | |
520 bne w@ if so, then branch | |
521 inc V.LLSema,u else claim critical section (0->1) | |
522 e@ puls cc,pc restore CC and return | |
523 w@ deca decrement our timeout counter | |
524 beq e@ if zero, we've timed out, return | |
525 puls cc give interrupts a chance to breathe | |
526 IFGT Level-1 | |
527 * Give up timeslice unless this is the system | |
528 pshs x | |
529 ldx D.Proc get proc descriptor | |
530 cmpx D.SysPrc system? | |
531 beq wd@ yep, system cannot sleep | |
532 * ldx D.AProcQ get active proc queue | |
533 * beq wd@ if empty, return | |
534 ldx #$0001 | |
535 os9 F$Sleep give up timeslice | |
536 wd@ puls x return to caller | |
537 ENDC | |
538 bra csacq_wait and try again | |
539 ENDC | |
540 | |
541 | |
542 * Log2Phys - Convert logical sector to physical sector | |
543 * | |
544 * Stores V.PhysSect,u from V.LogSect,u based on V.SectSize,u | |
545 * Also adds IT.SOFF1-IT.SOFF3 to V.PhysSect,u for partitioning. | |
546 * Results are placed in V.PhysSect,u | |
547 Log2Phys lda V.LogSect,u | |
548 sta V.PhysSect,u | |
549 ldd V.LogSect+1,u | |
550 std V.PhysSect+1,u | |
551 lda V.SectSize,u | |
552 beq AddSectorOffset | |
553 DivBy2 lsr V.PhysSect,u | |
554 ror V.PhysSect+1,u | |
555 ror V.PhysSect+2,u | |
556 deca | |
557 bne DivBy2 | |
558 * This routine adds the 3 byte sector offset in the | |
559 * device descriptor to the physical sector. | |
560 AddSectorOffset | |
561 ldx PD.DEV,y | |
562 ldx V$DESC,x | |
563 ldd IT.SOFF2,x | |
564 addd V.PhysSect+1,u | |
565 std V.PhysSect+1,u | |
566 lda IT.SOFF1,x | |
567 adca V.PhysSect,u | |
568 sta V.PhysSect,u | |
569 logex rts | |
570 | |
571 | |
572 * 256 byte sector device: setup for low level driver to put 256 byte sector directly into PD.BUF | |
573 Write256 | |
574 bsr Log2Phys | |
575 * We may not have to do this (and disturb the cache as a result) | |
576 * lda PD.DRV,y get current drive number | |
577 * sta V.LastDrv,u and make this the current drive | |
578 lda #1 | |
579 sta V.SectCnt,u | |
580 ldx PD.BUF,y put address of PD.BUF directly into cache spot | |
581 stx V.CchPSpot,u | |
582 * Call low-level driver read | |
583 ldx V.LLWrite,u | |
584 bra LLCall | |
585 | |
586 * Write | |
587 * | |
588 * Entry: | |
589 * B = MSB of the disk's LSN | |
590 * X = LSB of the disk's LSN | |
591 * Y = address of path descriptor | |
592 * U = address of device memory area | |
593 * | |
594 * Exit: | |
595 * CC = carry set on error | |
596 * B = error code | |
597 * | |
598 Write leau UOFFSET,u | |
599 lbsr PreXfr to pre-transfer stuff | |
600 bcs logex branch if error | |
601 IFNE HDBDOS | |
602 lda V.HDBPart,u HDB-DOS partition? | |
603 beq h@ | |
604 * HDB-DOS partition code path | |
605 sta V.CchDirty,u cache is dirty | |
606 lda V.SectSize,u get sector size (0=256,1=512,2=1024,3=2048) | |
607 leax SCTTBL,pcr | |
608 lda a,x | |
609 sta V.Log2Phys,u set logical sectors per phys | |
610 lda V.LogSect,u | |
611 sta V.PhysSect,u | |
612 ldd V.LogSect+1,u | |
613 std V.PhysSect+1,u | |
614 bsr AddSectorOffset add in partition offset and HDB-DOS drive | |
615 lbsr ComputeHDB and compute HDB-DOS offset | |
616 ldx PD.BUF,y get path desc buffer | |
617 stx V.CchPSpot,u we write directly from PD.BUF | |
618 bra writeit | |
619 ENDC | |
620 * New: Dec 20, 2011 | |
621 * Fast path opportunity: if sector size is 256 bytes, call LLRead right into PD.BUF | |
622 h@ | |
623 tst V.SectSize,u (0=256 byte sector device) | |
624 beq Write256 | |
625 lbsr ValidateCache | |
626 bcs logex | |
627 * Copy appropriate 256 byte sector from PD.BUF,y to V.CchAddr,u | |
628 * Determine where in the cache we copy this 256 byte sector | |
629 bsr Log2Phys compute physical sector from logical sector | |
630 lda V.CchSize,u get hi byte of cache size | |
631 deca | |
632 anda V.LogSect+2,u | |
633 clrb | |
634 ldx V.CchAddr,u | |
635 leax d,x | |
636 stx V.CchLSpot,u save for possible verify later | |
637 pshs y save path desc for now | |
638 ldy PD.BUF,y | |
639 IFNE H6309 | |
640 ldw #256 | |
641 tfm y+,x+ | |
642 puls y | |
643 ELSE | |
644 clr ,-s | |
645 loop@ ldd ,y++ | |
646 std ,x++ | |
647 inc ,s | |
648 bpl loop@ | |
649 puls a,y | |
650 ENDC | |
651 * Now that sector is copied, determine where in cache we start | |
652 lda V.LogSect+2,u get logical sector bits 7-0 | |
653 leax MASKTBL,pcr point to base of cache | |
654 ldb V.SectSize,u get sector size in B | |
655 anda b,x | |
656 pshs a | |
657 lda V.CchSize,u get upper 8 bits of cache size | |
658 deca | |
659 anda ,s+ | |
660 clrb | |
661 ldx V.CchAddr,u point to base of cache | |
662 leax d,x | |
663 stx V.CchPSpot,u | |
664 * Call low-level driver write routine | |
665 writeit lda #$01 | |
666 sta V.SectCnt,u | |
667 ldx V.LLWrite,u | |
668 lbsr LLCall | |
669 * If verify flag is on, read back and compare | |
670 tst PD.VFY,y verify flag set? | |
671 bne ex@ if so, we don't verify -- just exit | |
672 * Read back physical sector into cache | |
673 tst V.HDBPart,u HDB-DOS partition? | |
674 beq o@ | |
675 * If in HDB-DOS mode, we simply place the base address of the cache into | |
676 * V.CchPSpot... and V.CchLSpot for later verify | |
677 ldx V.CchAddr,u | |
678 stx V.CchPSpot,u | |
679 stx V.CchLSpot,u | |
680 o@ lda #$01 | |
681 sta V.SectCnt,u | |
682 ldx V.LLRead,u | |
683 lbsr LLCall | |
684 * Now compare PD.BUF to sector in cache just re-read | |
685 ldx V.CchLSpot,u get spot in cache where 256 byte sector is. | |
686 ldy PD.BUF,y get pointer to buffer | |
687 clra | |
688 a@ ldb ,x+ get byte in cache | |
689 cmpb ,y+ compare against byte in PD.BUF | |
690 bne err@ | |
691 deca | |
692 bne a@ | |
693 ex@ clrb | |
694 rts | |
695 err@ comb | |
696 ldb #E$Write | |
697 stb V.CchDirty,u make cache dirty due to error | |
698 rts | |
699 | |
700 * | |
701 * Init | |
702 * | |
703 * Entry: | |
704 * Y = address of device descriptor | |
705 * U = address of device memory area | |
706 * | |
707 * Exit: | |
708 * CC = carry set on error | |
709 * B = error code | |
710 * | |
711 Init pshs y save device descriptor ptr on stack | |
712 ldb #DrvCount get maximum drives supported | |
713 stb V.NDRV,u save in our device memory | |
714 leax DRVBEG,u point X to the drive tables | |
715 lda #$FF | |
716 * Invalidate V.NDRV drive tables | |
717 drvx sta DD.TOT,x | |
718 sta DD.TOT+1,x | |
719 sta DD.TOT+2,x | |
720 leax DRVMEM,x point to next drive table | |
721 decb decrement counter | |
722 bne drvx if not zero, continue | |
723 * Link to low-level driver | |
724 ldd IT.LLDRV,y point to name in descriptor | |
725 leax d,y point to name in descriptor | |
726 pshs u | |
727 IFGT Level-1 | |
728 ldd D.Proc get curr proc ptr | |
729 pshs d save on stack | |
730 ldd D.SysPrc get system process desc ptr | |
731 std D.Proc and make current proc | |
732 ENDC | |
733 lda #Sbrtn+Objct | |
734 os9 F$Link link to it | |
735 IFGT Level-1 | |
736 puls x get curr proc ptr | |
737 stx D.Proc restore | |
738 ENDC | |
739 tfr u,x transfer module address to X | |
740 puls u restore U | |
741 leau UOFFSET,u | |
742 bcs ret@ | |
743 stx V.LLAddr,u else save module address | |
744 * setup entry points to low-level module | |
745 leax V.LLInit,u | |
746 lda #6 number of entry points | |
747 l@ sty ,x++ | |
748 leay 3,y | |
749 deca | |
750 bne l@ | |
751 * Call low-level driver init | |
752 ldy ,s grab path desc ptr | |
753 ldx V.LLInit,u | |
754 lbsr LLCall | |
755 bcc r@ | |
756 ret@ puls y,pc | |
757 * Allocate cache memory | |
758 r@ lda IT.TYP,y get type byte | |
759 anda #TYPH.SSM mask out all but sector size | |
760 * Added Dec 20, 2011: save off to V.SectSize (never got initialized until now!) | |
761 sta V.SectSize,u clear out V.SectSize | |
762 puls y | |
763 * Fall through to ExpandCache | |
764 | |
765 * Entry: A = cache size to expand to (1 = 512, 2 = 1024, 3 = 2048) | |
766 * Exit: D is destroyed | |
767 * Note: any previously allocated cache memory must have been | |
768 * freed before this call! | |
769 * | |
770 ExpandCache | |
771 pshs a,x | |
772 leax CCHTBL,pcr | |
773 lda a,x get 1, 2, 4 or 8 | |
774 sta V.CchDirty,u make cache dirty since we will expand it | |
775 clrb | |
776 std V.CchSize,u save cache size (256, 512, 1024 or 2048) | |
777 tfr u,x | |
778 os9 F$SRqMem allocate cache memory | |
779 stu V.CchAddr,x save cache ptr | |
780 tfr x,u restore mem pointer | |
781 ex@ puls a,x,pc | |
782 | |
783 | |
784 CCHTBL FCB 256/256 | |
785 FCB 512/256 | |
786 FCB 1024/256 | |
787 FCB 2048/256 | |
788 | |
789 MASKTBL FCB $07,$06,$04,$00 | |
790 | |
791 EMOD | |
792 eom EQU * | |
793 END |