732
|
1 ********************************************************************
|
|
2 * Rammer - OS-9 Level Two RAM Disk
|
|
3 *
|
|
4 * $Id$
|
|
5 *
|
|
6 * Alan DeKok's version of RAMMER - Based on original Keving Darling version
|
|
7 *
|
|
8 * Ed. Comments Who YY/MM/DD
|
|
9 * ------------------------------------------------------------------
|
|
10 * 4 Original Kevin Darling Version
|
|
11 * 5 Several changes by L. Curtis Boyle LCB 00/03/14
|
|
12 * 1) Allowed driver to go past 400K 00/05/09
|
|
13 * 2) Attempted some fixes for handling /MD, so
|
|
14 * that setting vfy=0 on /R0 would not
|
|
15 * completely crash the system.
|
|
16 * 3) Fixed some error reporting bugs that would
|
|
17 * crash the system
|
|
18 * 4) Moved entry table to between READ/WRITE to
|
|
19 * allow short branches to both
|
|
20 *
|
|
21 * NOTE: For some reason, when DEINIZing /r0, the INIT routine gets called...
|
|
22 * but it still deallocates memory!
|
|
23
|
|
24 * Following CAN be set higher, but will take another page of system RAM then.
|
|
25 * 200 will allow maximum of 1,638,400 byte RAM drive.
|
|
26 MAXBLOCK set 201 Maximum # of MMU blocks allowed in RAM drive
|
|
27
|
|
28 nam Rammer
|
|
29 ttl OS-9 Level Two RAM Disk
|
|
30
|
|
31 ifp1
|
|
32 use defsfile
|
|
33 use rbfdefs
|
|
34 endc
|
|
35
|
|
36 tylg set Drivr+Objct
|
|
37 atrv set ReEnt+rev
|
|
38 rev set $02
|
|
39 edition set 5
|
|
40
|
|
41 mod eom,name,tylg,atrv,start,size
|
|
42
|
|
43 * Device mem stuff - can make MMUTable bigger, but will take 2 pages of system
|
|
44 * RAM then for device memory
|
|
45 u0000 rmb DRVBEG+DRVMEM Reserve room for 1 entry drive table
|
|
46 MDFlag rmb 1 0=R0 descriptor, <>0=MD descriptor
|
|
47 numofBlk rmb 1 # of MMU blocks allocated for RAM drive
|
|
48 MMUTable rmb MAXBLOCK Table of MMU Block #'s being used.
|
|
49 size equ .
|
|
50
|
|
51 fcb DIR.+SHARE.+PREAD.+PWRIT.+PEXEC.+READ.+WRITE.+EXEC.
|
|
52
|
|
53 name fcs /Rammer/
|
|
54 fcb edition
|
|
55
|
|
56 * Terminate routine - deallocates RAM
|
|
57 L0024 lda <numofBlk,u Get # blocks we had allocated
|
|
58 beq L003D If none, exit
|
|
59 leay <MMUTable,u Point to MMU block table
|
|
60 IFNE H6309
|
|
61 clre Hi byte of block # to allocate (always 0)
|
|
62 L002E ldf ,y Get block #
|
|
63 ELSE
|
|
64 L002E ldb ,y
|
|
65 ENDC
|
|
66 clr ,y+ Zero it out in table
|
|
67 IFNE H6309
|
|
68 tfr w,x Block # to deallocate
|
|
69 ELSE
|
|
70 pshs a
|
|
71 clra
|
|
72 tfr d,x
|
|
73 puls a
|
|
74 ENDC
|
|
75 ldb #$01 1 block to deallocate
|
|
76 os9 F$DelRAM Deallocate the block
|
|
77 deca Dec # of blocks to clean out
|
|
78 bne L002E Do until entire RAM drive is deallocated
|
|
79 L003D clrb Exit w/o error
|
|
80 rts
|
|
81
|
|
82 * Deallocate RAM allocated so far, exit with no RAM error
|
|
83 L003F bsr L0024 Deallocate all RAM Drive ram blocks
|
|
84 L0041 comb Exit no RAM left error
|
|
85 ldb #E$MemFul
|
|
86 rts
|
|
87
|
|
88 * Init routine - only gets called once per driver inited.
|
|
89 * Called if you INIZ the device as well
|
|
90 * Entry: Y=Address of device descriptor
|
|
91 * U=Device mem area
|
|
92 * NOTE: All of device mem (Except V.PORT) is cleared to 0's
|
|
93 Init lda #1
|
|
94 sta V.NDRV,u only can handle 1 drive descriptor
|
|
95 leax DRVBEG,u Point to start of drive table
|
|
96 sta DD.TOT+2,x Set DD.TOT to non 0 value
|
|
97 lda <M$Opt,y Get # of bytes in device descriptor table
|
|
98 deca
|
|
99 * Following is if 1st access to RAMMER is on /MD
|
|
100 beq GetStat 0 (/MD desciptor), then exit w/o error
|
|
101 ldb <IT.CYL+1,y Get LSB of # of cylinders
|
|
102 lda <IT.SID,y Get # of heads
|
|
103 mul Calculate # head/cyls total
|
|
104 lda <IT.SCT+1,y Get # of sectors/track
|
|
105 mul Calculate # of sectors for RAM drive
|
|
106 subd <IT.SCT,y Subtract 1 tracks worth
|
|
107 addd <IT.T0S,y Add in the special track 0's # sectors/track
|
|
108 std DD.TOT+1,x Save as # sectors on drive
|
|
109 addd #$001F Round up to nearest 8K block
|
|
110 IFNE H6309
|
|
111 rold Shift # of 8K blocks needed into A
|
|
112 rold
|
|
113 rold
|
|
114 ELSE
|
|
115 rolb
|
|
116 rola
|
|
117 rolb
|
|
118 rola
|
|
119 rolb
|
|
120 rola
|
|
121 ENDC
|
|
122 cmpa #MAXBLOCK If higher than max, exit with mem full error
|
|
123 bhi L0041
|
|
124 leax <MMUTable,u Point to RAM block table
|
|
125 IFNE H6309
|
|
126 tfr a,e # blocks left to allocate
|
|
127 ENDC
|
|
128 L0078 ldb #$01 Try to allocate 1 8K RAM block
|
|
129 IFEQ H6309
|
|
130 pshs a
|
|
131 ENDC
|
|
132 os9 F$AllRAM
|
|
133 IFEQ H6309
|
|
134 puls a
|
|
135 ENDC
|
|
136 bcs L003F If error, deallocate RAM, and exit
|
|
137 inc <numofBlk,u Bump up # of blocks allocated
|
|
138 stb ,x+ Save MMU block # allocated in table
|
|
139 IFNE H6309
|
|
140 dece Do until done all blocks requested
|
|
141 ELSE
|
|
142 deca
|
|
143 ENDC
|
|
144 bne L0078
|
|
145 clrb No error & return
|
|
146 rts
|
|
147
|
|
148 * Entry: B:X=LSN to read (only X will be used, even with 2 MB)
|
|
149 * Y=Path dsc. ptr
|
|
150 * U=Device mem ptr
|
|
151 Read pshs y,x Preserve path & device mem ptrs
|
|
152 bsr L00C8 Calculate MMU block & offset for sector
|
|
153 bcs L00A5 Error, exit with it
|
|
154 bsr L00AE Transfer sector from RAM drive to PD.BUF
|
|
155 puls y,x Restore ptrs
|
|
156 leax ,x Sector 0?
|
|
157 bne GetStat No, exit without error
|
|
158 ldx PD.BUF,y Get buffer ptr
|
|
159 leay DRVBEG,u Point to start of drive table
|
|
160 IFNE H6309
|
|
161 ldw #DD.SIZ Copy the info we need into drive table
|
|
162 tfm x+,y+
|
|
163 ELSE
|
|
164 ldb #DD.SIZ Copy the info we need into drive table
|
|
165 ReadLp lda ,x+
|
|
166 sta ,y+
|
|
167 decb
|
|
168 bne ReadLp
|
|
169 ENDC
|
|
170 * GetStat/SetStat - no calls, just exit w/o error
|
|
171 GetStat clrb
|
|
172 L00A7 rts
|
|
173
|
|
174 L00A5 puls y,x,pc
|
|
175
|
|
176 start bra Init
|
|
177 nop
|
|
178 bra Read
|
|
179 nop
|
|
180 bra Write
|
|
181 nop
|
|
182 bra GetStat
|
|
183 nop
|
|
184 bra GetStat Actually SetStat (no calls, so same routine)
|
|
185 nop
|
|
186 lbra L0024 Terminate (returns memory)
|
|
187
|
|
188 * Entry: B:X = LSN to write
|
|
189 * Y=Path dsc. ptr
|
|
190 * U=Device mem ptr
|
|
191 Write bsr L00C8 Calculate MMU Block & offset for sector
|
|
192 bcs L00A7 Error,exit with it
|
|
193 exg x,y X=Sector buffer ptr, Y=Offset within MMU block
|
|
194 * Transfer between RBF sector buffer & RAM drive image sector buffer
|
|
195 * Called by both READ and WRITE (with X,Y swapping between the two)
|
|
196 L00AE orcc #IntMasks Shut IRQ's off
|
|
197 pshs x Preserve X
|
|
198 ldx <D.SysDAT Get ptr to system DAT image
|
|
199 ldb 1,x Get original System MMU block #0
|
|
200 puls x Get X back
|
|
201 sta >$FFA0 Map in RAM drive block into block #0
|
|
202 IFNE H6309
|
|
203 ldw #$0100 256 byte transfer
|
|
204 tfm x+,y+ Copy between the two buffers
|
|
205 ELSE
|
|
206 clrb
|
|
207 WriteLp lda ,x+
|
|
208 sta ,y+
|
|
209 decb
|
|
210 bne WriteLp
|
|
211 ENDC
|
|
212 stb >$FFA0 Remap in system block 0
|
|
213 andcc #^(IntMasks+Carry) Turn IRQ's back on & no error
|
|
214 rts
|
|
215
|
|
216 * Subroutine to calculate MMU block # and offset based on sector # requested
|
|
217 * Entry: Y=path dsc. ptr
|
|
218 * U=device mem ptr
|
|
219 * B:X=LSN to calculate for
|
|
220 * Exit: A=MMU block # we need to map in
|
|
221 * X=offset within MMU block to get sector from (always <8K)
|
|
222 * Y=Sector buffer ptr for RBF
|
|
223 * MDFlag,u=0 if NOT MD, else MD
|
|
224 L00C8 clr MDFlag,u Flag that we are on "real" RAM Drive
|
|
225 IFNE H6309
|
|
226 ldw PD.DEV,y Get our Device table entry ptr
|
|
227 ldw V$DESC,w Get device descriptor ptr
|
|
228 lda M$Opt,w Get size of options table
|
|
229 ELSE
|
|
230 pshs x
|
|
231 ldx PD.DEV,y Get our Device table entry ptr
|
|
232 ldx V$DESC,x Get device descriptor ptr
|
|
233 lda M$Opt,x Get size of options table
|
|
234 puls x
|
|
235 ENDC
|
|
236 deca
|
|
237 bne L00DB Not MD, skip ahead
|
|
238 inc MDFlag,u Flag we are on MD
|
|
239 sta <PD.SIZ,y
|
|
240 sta <PD.SIZ+3,y
|
|
241 sta <PD.SSZ,y
|
|
242 ldd <D.BlkMap+2 Get end of block memory ptr
|
|
243 subd <D.BlkMap Calc # of blocks of RAM
|
|
244 lda #32 * 32 for # of 'sectors'
|
|
245 mul
|
|
246 std <PD.SIZ+1,y Save as middle word of file size
|
|
247 std <PD.SSZ+1,y Save as segment size
|
|
248 bra L00DE Skip ahead (sector # will allow all 2 MB)
|
|
249
|
|
250 L00DB tstb Test MSB of sector #
|
|
251 bne L010F <>0, exit with Sector error
|
|
252 L00DE pshs x Preserve LSW of sector #
|
|
253 ldd ,s Load it again into D
|
|
254 tst MDFlag,u We on MD?
|
|
255 bne L00EE Yes, skip ahead
|
|
256 leax DRVBEG,u Point to drive table
|
|
257 cmpd DD.TOT+1,x LSW of sector compared to table's # of sectors
|
|
258 bhs L010E Sector # too large, exit with error
|
|
259 L00EE equ *
|
|
260 IFNE H6309
|
|
261 rold A=MMU block offset in RAM drive image
|
|
262 rold
|
|
263 rold
|
|
264 ELSE
|
|
265 rolb
|
|
266 rola
|
|
267 rolb
|
|
268 rola
|
|
269 rolb
|
|
270 rola
|
|
271 ENDC
|
|
272 tst MDFlag,u We on /MD?
|
|
273 bne L0100 Yup, skip calculating MMU stuff
|
|
274 leax <MMUTable,u Point to MMU table
|
|
275 lda a,x Get MMU block # we want
|
|
276 beq L010E If 0, exit with sector error
|
|
277 L0100 pshs a Save block #
|
|
278 clrb Calculate offset within 8k block we want
|
|
279 lda 2,s
|
|
280 anda #$1F Mask out all but within 8K address offset
|
|
281 std 1,s Save offset
|
|
282 ldy PD.BUF,y Get sector buffer address
|
|
283 puls x,a,pc Get offset, MMU block & return
|
|
284
|
|
285 L010E leas 2,s Eat X on stack
|
|
286 L010F comb Exit with bad sector #
|
|
287 ldb #E$Sect
|
|
288 rts
|
|
289
|
|
290 emod
|
|
291 eom equ *
|
|
292 end
|