
         ;*
         ;*  FFSBoot.s - V3.0
         ;*
         ;*  Written by Matthias Schmidt
         ;*

Init:
         move.l   sp,a5
         move.l   a0,a2
         move.l   d0,d2
         moveq  #20,d5
         move.l   4.s,a6
         lea DosName(pc),a1
         moveq  #$22,d0
         jsr   -$228(a6)
         move.l   d0,d6
         beq Exit
         move.l   d0,a6
         jsr   -$3C(a6)
         move.l   d0,d7
         lea HelpTxt(pc),a0
         cmp.b #'?',(a2)
         beq IsOk
         move.l   d2,d0
         subq.l   #2,d2
         bmi EndMsg

         beq.s BeqEnd1
         cmp.b #':',0(a2,d2)
         bne EndMsg
         moveq  #5,d5
         bclr   #0,d0
         sub.l d0,sp
         move.l   sp,a0
         move.b   d2,(a0)+
         bra.s CopyArgEntry
CopyArgLoop:
         move.b   (a2)+,(a0)+
CopyArgEntry:
         dbra  d2,CopyArgLoop
         move.l   4.s,a6
         move.l   $226(a6),d0
         beq.s NotExists
SearchResIsPtr:
         bclr   #31,d0
         move.l   d0,a2
SearchResLoop:
         move.l   (a2)+,d0
         beq.s NotExists
         bmi.s SearchResIsPtr
         move.l   d0,a0
         move.l   14(a0),a0
         subq.l   #1,a0
         move.l   sp,a1
         bsr   bstrcmp
         bne.s SearchResLoop
         lea ffsbootTxt(pc),a1
CmpResNameLoop:
         move.b   (a0)+,d0
         cmp.b (a1)+,d0
         bne.s SearchResLoop
         tst.b d0
         bne.s CmpResNameLoop
         lea AlreadyTxt(pc),a0
BeqEnd1:
         beq.s BeqEnd2
NotExists:
         moveq  #20,d5
         move.l   d6,a6
         move.l   $22(a6),a0
         move.l   $18(a0),d0
         lsl.l #2,d0
         move.l   d0,a4
         addq.l   #4,a4
SearchDevLoop:
         lea NotFoundTxt(pc),a0
         move.l   (a4),d0
BeqEnd2:
         beq.s BeqEnd3
         lsl.l #2,d0
         move.l   d0,a4
         tst.l 4(a4)
         bne.s SearchDevLoop
         move.l   $28(a4),d0
         lsl.l #2,d0
         move.l   d0,a0
         move.l   sp,a1
         bsr   bstrcmp
         bne.s SearchDevLoop
         lea NotLoadedTxt(pc),a0
         move.l   $20(a4),d2
BeqEnd3:
         beq.s BeqEnd4
         lea NotNeededTxt(pc),a0
         move.l #$FC0000,d1
         lsr.l #2,d1
         cmp.w d1,d2
         bhs EndMsg
         move.l   d2,d1
         moveq  #4,d0
CountLoop:
         addq.l   #8,d0
         lsl.l #2,d1
         move.l   d1,a0
         move.l   (a0),d1
         bne.s CountLoop
         add.l #ResidentSize+8,d0
         move.l   d0,d3
         moveq  #11,d1
         add.b (sp),d1
         add.l d1,d0
         and.w #-2,d0
         move.l   d0,d4
         moveq  #3,d1
         move.l   4.s,a6
         jsr   -$C6(a6)
         lea NoMemTxt(pc),a0
         tst.l d0
BeqEnd4:
         beq EndMsg
         move.l   d0,a2
         lea 8(a2),a3
         lea ResidentSize(a3),a1
SaveLoop:
         lsl.l #2,d2
         move.l   d2,(a1)+
         beq.s SaveEnd
         move.l   d2,a0
         move.l   (a0),d2
         move.l   -(a0),(a1)+
         bra.s SaveLoop
SaveEnd:
         move.l   a3,a1
         lea Resident(pc),a0
         move.w   #ResidentSize/2-1,d1
CopyResLoop:
         move.w   (a0)+,(a1)+
         dbra  d1,CopyResLoop
         add.l a2,d3
         move.l   a3,d0
         move.l   d0,2(a3)
         move.l   d4,6(a3)
         add.l d0,6(a3)
         add.l d3,14(a3)
         add.l d0,18(a3)
         add.l d0,22(a3)
         move.l   $24(a4),d2
         movem.l  d2/d4/a2,ResidentData-Resident(a3)
         move.l   d3,a1
         move.l   sp,a0
         clr.w d1
         move.l   $28(a4),d0
         lsl.l #2,d0
         move.l   d0,a0
         move.b   (a0),d1
CopyNameLoop:
         move.b   (a0)+,(a1)+
         dbra  d1,CopyNameLoop
         moveq  #8,d1
         lea ffsbootTxt(pc),a0
CopyNameLoop2:
         move.b   (a0)+,(a1)+
         dbra  d1,CopyNameLoop2
         jsr   -$84(a6)
         lea ResidentArray-Resident+4(a3),a1
         move.l   $226(a6),(a1)
         beq NoOldResident
         bset   #7,(a1)
NoOldResident:
         move.l   a3,-(a1)
         move.l   a1,$226(a6)
         jsr   -$264(a6)
         move.l   d0,$22A(a6)
         jsr   -$8A(a6)
         lea IsOkTxt(pc),a0
IsOk:
         moveq  #0,d5
EndMsg:
         moveq  #0,d3
         move.b   (a0)+,d3
         move.l   a0,d2
         move.l   d7,d1
         move.l   d6,a6
         jsr   -$30(a6)
         move.l   4.s,a6
         move.l   d6,a1
         jsr   -$19E(a6)
Exit:
         move.l   d5,d0
         move.l   a5,sp
         rts

DosName:
         dc.b  'dos.library',0
HelpTxt:
         dc.b  24,'Usage: FFSBoot <DEVICE>',10
NotFoundTxt:
         dc.b  19,'Device not found !',10
NotLoadedTxt:
         dc.b  17,'FFS not loaded !',10
NotNeededTxt:
         dc.b  75,'The FileSystem for the given device is already '
         dc.b  'resident in the KickStart !',10
NoMemTxt:
         dc.b  48,'Not enough memory for resident-code and -data !',10
IsOkTxt:
         dc.b  15,'FFS installed.',10
AlreadyTxt:
         dc.b  23,'FFS already installed.',10
ffsbootTxt:
         dc.b  '.ffsboot',0
         even

Resident:
         dc.w  $4AFC
         dc.l  0
         dc.l  0
         dc.b  1
         dc.b  3
         dc.b  0
         dc.b  -30
         dc.l  1
         dc.l  ResidentId-Resident
         dc.l  ResidentCode-Resident
ResidentArray:
         dc.l  0,0
ResidentData:
         dc.l  0,0,0
ResidentId:
         dc.b  'FFSBoot Version 3.0 (12-Feb-89 18:00)',0
ExpansionName:
         dc.b  'expansion.library',0
         even

ResidentCode:
         movem.l  a2/d2/a6,-(sp)
         move.l   4.s,a6
         movem.l  ResidentData+4,d0/a1
         jsr   -$CC(a6)
         tst.l d0
         beq ResidentCodeEnd
         lea Resident+ResidentSize(pc),a2
         moveq  #1,d2
AllocLoop:
         movem.l  (a2)+,d0/a1
         exg d0,a1
         subq.l   #4,a1
         jsr   -$CC(a6)
         tst.l d0
         beq.s SearchBootNode
         move.l   d0,a0
         movem.l  -4(a2),d0/d1
         lsr.l #2,d1
         movem.l  d0/d1,(a0)
         bne.s AllocLoop
         moveq  #0,d2
SearchBootNode:
         lea ExpansionName(pc),a1
         moveq  #$22,d0
         jsr   -$228(a6)
         tst.l d0
         beq.s ResidentCodeEnd
         move.l   d0,a1
         lea $4A(a1),a2
         jsr   -$19E(a6)
SearchBootDevLoop:
         move.l   (a2),a2
         tst.l (a2)
         beq.s ResidentCodeEnd
         cmp.b #16,8(a2)
         bne.s ResidentCodeEnd
         move.l   $10(a2),a0
         move.l   $28(a0),d0
         lsl.l #2,d0
         move.l   d0,a0
         move.l   Resident+14(pc),a1
         subq.l   #1,a1
         bsr.s bstrcmp
         bne.s SearchBootDevLoop
         tst.w d2
         beq.s NotRemBootNode
         move.l   a2,a1
         jsr   -$FC(a6)
         bra.s ResidentCodeEnd
NotRemBootNode:
         move.l   $10(a2),a0
         move.l   Resident+ResidentSize(pc),d0
         lsr.l #2,d0
         move.l   ResidentData(pc),d1
         movem.l  d0/d1,$20(a0)
ResidentCodeEnd:
         movem.l  (sp)+,a2/d2/a6
         rts

bstrcmp:
         clr.w d0
         moveq  #0,d1
         move.b   (a0)+,d1
         cmp.b (a1)+,d1
         bra.s bstrcmpentry
bstrcmploop:
         move.b   (a0)+,d0
         bsr.s toupper
         move.w   d0,-(sp)
         move.b   (a1)+,d0
         bsr.s toupper
         cmp.w (sp)+,d0
bstrcmpentry:
         dbne  d1,bstrcmploop
         rts
toupper:
         cmp.b #'a',d0
         blo.s toupperok
         cmp.b #'z',d0
         bhs.s toupperok
         sub.b #'a'-'A',d0
toupperok:
         rts
                 e:
 ResidentSize =   e-Resident




