comparison level1/modules/rbsuper.asm @ 2590:17d43fd29ee2

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