|
|
1.1 root 1: SECTION code
2: ; This file can be translated with A68k or PhxAss and then linked with BLink
3: ; to produce an Amiga executable. Make sure it does not contain any
4: ; relocations, then run it through the filesys.sh script
1.1.1.2 ! root 5: ;
! 6: ; Patrick: It also works with SAS/C asm+slink, but I had to remove
! 7: ; the .l from jsr.l and jmp.l.
1.1 root 8:
9: dc.l 16
10: our_seglist:
11: dc.l 0 ;/* NextSeg */
12: start:
13: bra filesys_mainloop
14: dc.l make_dev-start
15: dc.l filesys_init-start
16: dc.l exter_server-start
17: dc.l bootcode-start
18:
19: bootcode:
20: lea.l doslibname(pc),a1
1.1.1.2 ! root 21: jsr -96(a6) ; FindResident
1.1 root 22: move.l d0,a0
23: move.l 22(a0),d0
24: move.l d0,a0
25: jsr (a0)
26: rts
27:
28: filesys_init:
29: movem.l d0-d7/a0-a6,-(sp)
30: move.l 4.w,a6
31: move.l $F0FFFC,a5 ; filesys base
32: lea.l explibname(pc),a1 ; expansion lib name
33: moveq.l #36,d0
34: moveq.l #0,d5
1.1.1.2 ! root 35: jsr -552(a6) ; OpenLibrary
1.1 root 36: tst.l d0
37: bne.b FSIN_explibok
38: lea.l explibname(pc),a1 ; expansion lib name
39: moveq.l #0,d0
40: moveq.l #1,d5
1.1.1.2 ! root 41: jsr -552(a6) ; OpenLibrary
1.1 root 42: FSIN_explibok:
43: move.l d0,a4
44: moveq.l #88,d0
45: moveq.l #1,d1 ; MEMF_PUBLIC
1.1.1.2 ! root 46: jsr -198(a6) ; AllocMem
1.1 root 47: move.l d0,a3 ; param packet
48:
49: moveq.l #84,d7 ; initialize it
50: FSIN_loop:
51: move.l 0(a5,d7.l),0(a3,d7.l)
52: subq.l #4,d7
53: bcc.b FSIN_loop
54:
55: moveq.l #0,d6
56: FSIN_init_units:
57: cmp.l $10c(a5),d6
58: bcc.b FSIN_units_ok
59: move.l a3,a0
60: movem.l d6/a3,-(sp)
61: move.l #1,d7
1.1.1.2 ! root 62: bsr.w make_dev
1.1 root 63: movem.l (sp)+,d6/a3
64: addq.l #$1,d6
65: bra.b FSIN_init_units
66:
67: FSIN_units_ok:
68: move.l 4.w,a6
69: move.l a4,a1
1.1.1.2 ! root 70: jsr -414(a6) ; CloseLibrary
! 71: bsr.w setup_exter
1.1 root 72: move.l 4.w,a6
1.1.1.2 ! root 73: jsr $F0FF80
1.1 root 74: moveq.l #3,d1
75: moveq.l #-10,d2
76: move.l #$200000,a0
77: sub.l a0,d0
78: bcs.b FSIN_chip_done
79: beq.b FSIN_chip_done
80: moveq.l #0,d4
81: move.l d4,a1
82: jsr -618(a6)
83: FSIN_chip_done
84: movem.l (sp)+,d0-d7/a0-a6
85: general_ret:
86: rts
87:
1.1.1.2 ! root 88: exter_data:
! 89: exter_server:
! 90: movem.l a2,-(sp)
! 91: moveq.l #0,d0
! 92: jsr $F0FF50
! 93: tst.l d0
! 94: beq.b exter_server_exit
! 95: ; This is the hard part - we have to send some messages.
! 96: move.l 4.w,a6
! 97: EXTS_loop:
! 98: moveq.l #2,d0
! 99: jsr $F0FF50
! 100: cmp.l #1,d0
! 101: blt.b EXTS_done
! 102: bgt.b EXTS_signal_reply
! 103: jsr -366(a6) ; PutMsg
! 104: bra.b EXTS_loop
! 105: EXTS_signal_reply:
! 106: cmp.l #2,d0
! 107: bgt.b EXTS_reply
! 108: move.l d1,d0
! 109: jsr -$144(a6) ; Signal
! 110: bra.b EXTS_loop
! 111: EXTS_reply:
! 112: jsr -$17a(a6) ; ReplyMsg
! 113: bra.b EXTS_loop
! 114: EXTS_done:
! 115: moveq.l #4,d0
! 116: jsr $F0FF50
! 117: moveq.l #1,d0 ; clear Z - it was for us.
! 118: exter_server_exit:
! 119: movem.l (sp)+,a2
! 120: rts
! 121:
1.1 root 122: setup_exter:
123: move.l 4.w,a6
124: moveq.l #26,d0
125: move.l #$10001,d1
126: jsr -198(a6) ; AllocMem
127: move.l d0,a1
128: lea.l exter_name(pc),a0
129: move.l a0,10(a1)
130: lea.l exter_data(pc),a0
131: move.l a0,14(a1)
132: lea.l exter_server(pc),a0
133: move.l a0,18(a1)
134: moveq.l #13,d0
1.1.1.2 ! root 135: jmp -168(a6) ; AddIntServer
1.1 root 136:
137: make_dev: ; IN: A0 param_packet, D6: unit_no, D7: boot, A4: expansionbase
138: move.l $F0FFFC,a5 ; filesys base
139:
140: jsr $F0FF28 ; fill in unit-dependent info, return 1 if hardfile.
141: move.l d0,d3
142:
143: ; Don't init hardfiles if < V36
144: and.l d5,d0
1.1.1.2 ! root 145: bne.w general_ret
1.1 root 146:
147: move.l a4,a6
1.1.1.2 ! root 148: jsr -144(a6) ; MakeDosNode()
1.1 root 149: move.l d0,a3 ; devicenode
1.1.1.2 ! root 150: jsr $F0FF20 ; record in ui.startup
1.1 root 151: moveq.l #0,d0
152: move.l d0,8(a3) ; dn_Task
153: move.l d0,16(a3) ; dn_Handler
154: move.l d0,32(a3) ; dn_SegList
155:
156: tst.l d3
157: bne.b MKDV_doboot
158:
159: MKDV_is_filesys:
160: move.l #4000,20(a3) ; dn_StackSize
161: lea.l our_seglist(pc),a1
162: move.l a1,d0
163: lsr.l #2,d0
164: move.l d0,32(a3) ; dn_SegList
165: move.l #-1,36(a3) ; dn_GlobalVec
166:
167: MKDV_doboot:
168: tst.l d7
169: beq.b MKDV_noboot
170:
171: move.l 4.w,a6
172: moveq.l #20,d0
173: moveq.l #0,d1
1.1.1.2 ! root 174: jsr -198(a6) ; AllocMem
1.1 root 175: move.l d0,a1 ; bootnode
176: moveq.l #0,d0
177: move.l d0,(a1)
178: move.l d0,4(a1)
179: move.w d0,14(a1)
180: move.w #$10FF,d0
181: sub.b d6,d0
182: move.w d0,8(a1)
183: move.l $104(a5),10(a1) ; filesys_configdev
184: move.l a3,16(a1) ; devicenode
185: lea.l 74(a4),a0 ; MountList
1.1.1.2 ! root 186: jmp -270(a6) ; Enqueue()
1.1 root 187:
188: MKDV_noboot:
189: move.l a3,a0
190: moveq.l #0,d1
191: move.l d1,a1
192: moveq.l #-1,d0
193: move.l a4,a6 ; expansion base
1.1.1.2 ! root 194: jmp -150(a6) ; AddDosNode
1.1 root 195:
196: filesys_mainloop:
197: move.l 4.w,a6
198: moveq.l #0,d0
199: move.l d0,a1
200: jsr -294(a6) ; FindTask
201: move.l d0,a0
202: lea.l $5c(a0),a5 ; pr_MsgPort
203:
204: ; Open DOS library
205: lea.l doslibname(pc),a1
206: moveq.l #0,d0
207: jsr -552(a6) ; OpenLibrary
208: move.l d0,a2
209:
210: ; Allocate some memory. Usage:
211: ; 0: lock chain
212: ; 4: command chain
213: ; 8: second thread's lock chain
214: ; 12: dummy message
215: ; 32: the volume (80+44+1 bytes)
216: move.l #80+44+1+20+12,d0
217: move.l #$10001,d1 ; MEMF_PUBLIC | MEMF_CLEAR
1.1.1.2 ! root 218: jsr -198(a6) ; AllocMem
1.1 root 219: move.l d0,a3
220: moveq.l #0,d6
221: move.l d6,(a3)
222: move.l d6,4(a3)
223: move.l d6,8(a3)
224:
225: moveq.l #0,d5 ; No commands queued.
226:
227: ; Fetch our startup packet
228: move.l a5,a0
229: jsr -384(a6) ; WaitPort
230: move.l a5,a0
231: jsr -372(a6) ; GetMsg
232: move.l d0,a4
233: move.l 10(a4),d3 ; ln_Name
234: moveq.l #0,d0
1.1.1.2 ! root 235: jsr $F0FF40
1.1 root 236: bra.b FSML_Reply
237:
238: ; We abuse some of the fields of the message we get. Offset 0 is
239: ; used for chaining unprocessed commands, and offset 1 is used for
240: ; indicating the status of a command. 0 means the command was handed
241: ; off to some UAE thread and did not complete yet, 1 means we didn't
242: ; even hand it over yet because we were afraid that might blow some
243: ; pipe limit, and -1 means the command was handed over and has completed
244: ; processing by now, so it's safe to reply to it.
245:
246: FSML_loop:
247: move.l a5,a0
248: jsr -384(a6) ; WaitPort
249: move.l a5,a0
250: jsr -372(a6) ; GetMsg
251: move.l d0,a4
252: move.l 10(a4),d3 ; ln_Name
253: bne.b FSML_FromDOS
254:
255: ; It's a dummy packet indicating that some queued command finished.
256: moveq.l #1,d0
1.1.1.2 ! root 257: jsr $F0FF50
1.1 root 258: ; Go through the queue and reply all those that finished.
259: lea.l 4(a3),a2
260: move.l (a2),a0
261: FSML_check_old:
262: move.l a0,d0
263: beq.b FSML_loop
264: move.l (a0),a1
265: move.l d0,a0
266: ; This field may be accessed concurrently by several UAE threads.
267: ; This _should_ be harmless on all reasonable machines.
268: move.l 4(a0),d0
269: bpl.b FSML_check_next
270: movem.l a0/a1,-(a7)
271: move.l 10(a0),a4
272: bsr.b ReplyOne
273: subq.l #1,d5 ; One command less in the queue
274: movem.l (a7)+,a0/a1
275: move.l a1,(a2)
276: move.l a1,a0
277: bra.b FSML_check_old
278: FSML_check_next:
279: move.l a0,a2
280: move.l a1,a0
281: bra.b FSML_check_old
282:
283: FSML_FromDOS:
284: ; Limit the number of outstanding started commands. We can handle an
285: ; unlimited number of unstarted commands.
286: cmp.l #20,d5
287: bcs FSML_DoCommand
288: ; Too many commands queued.
289: moveq.l #1,d0
290: move.l d0,4(a4)
291: bra.b FSML_Enqueue
292:
293: FSML_DoCommand:
294: bsr.b LockCheck ; Make sure there are enough locks for the C code to grab.
1.1.1.2 ! root 295: jsr $F0FF30
1.1 root 296: tst.l d0
297: beq.b FSML_Reply
298: ; The command did not complete yet. Enqueue it and increase number of
299: ; queued commands
300: ; The C code already set 4(a4) to 0
301: addq.l #1,d5
302: FSML_Enqueue:
303: move.l 4(a3),(a4)
304: move.l a4,4(a3)
305: bra.b FSML_loop
306:
307: FSML_Reply:
308: move.l d3,a4
309: bsr.b ReplyOne
310: bra.b FSML_loop
311:
312: ReplyOne:
313: move.l (a4),a1 ; dp_Link
314: move.l 4(a4),a0 ; dp_Port
315: move.l a5,4(a4)
316: jmp -366(a6) ; PutMsg
317:
318: ; ugly code to avoid calling AllocMem / FreeMem from native C code.
319: ; We keep a linked list of 3 locks. In theory, only one should ever
320: ; be used. Before handling every packet, we check that the list has the
321: ; right length.
322:
323: LockCheck:
324: move.l d5,-(a7)
325: moveq.l #-4,d5 ; Keep three locks
326: move.l (a3),a2
327: move.l a2,d7
328: LKCK_Loop:
329: move.l a2,d1
330: beq LKCK_ListEnd
331: addq.l #1,d5
332: beq.b LKCK_TooMany
333: move.l a2,a1
334: move.l (a2),a2
335: bra.b LKCK_Loop
336: LKCK_ListEnd:
337: addq.l #1,d5
338: beq.b LKCK_ret
339: move.l d7,a2
340: moveq.l #24,d0 ; sizeof Lock is 20, 4 for chain
341: moveq.l #1,d1 ; MEMF_PUBLIC
1.1.1.2 ! root 342: jsr -198(a6) ; AllocMem
1.1 root 343: addq.w #1,d6
344: move.l d0,a2
345: move.l d7,(a2)
346: move.l a2,d7
347: bra.b LKCK_ListEnd
348: LKCK_TooMany:
349: move.l (a2),d0 ; We have too many, but we tolerate that to some extent.
350: beq.b LKCK_ret
351: move.l d0,a0
352: move.l (a0),d0
353: beq.b LKCK_ret
354: move.l d0,a0
355: move.l (a0),d0
356: beq.b LKCK_ret
357:
358: moveq.l #0,d0 ; Now we are sure that we really have too many. Delete some.
359: move.l d0,(a1)
360: LKCK_TooManyLoop:
361: move.l a2,a1
362: move.l (a1),a2
363: moveq.l #24,d0
364: jsr -210(a6) ; FreeMem
365: add.l #$10000,d6
366: move.l a2,d0
367: bne.b LKCK_TooManyLoop
368: LKCK_ret:
369: move.l d7,(a3)
370: move.l (a7)+,d5
371: rts
372:
373: exter_name: dc.b 'UAE filesystem',0
374: doslibname: dc.b 'dos.library',0
375: explibname: dc.b 'expansion.library',0
376: END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.