--- /dev/null
+;DEBUG equ 1
+;DEBUGX equ 1 ;Requires silly CPU (680[01]0)
+;WaitDbg equ 1 ;Wait for RMB after each debug message
+;ModDebug equ 1 ;Do (Abs|Img)Module debugging
+
+PathLen equ 256
+StdBootPri equ 15
+StdTaskPri equ 10
+StdStackSize equ 512
+
+GV_DosBase equ $204
+
+ ifd ModDebug
+waitit macro
+ opt nochkimm
+ push d0
+\@a move.w d0,$dff180
+ addq.w #1,d0
+ btst.b #2,$dff016
+ bne.s \@a
+\@b move.w d0,$dff180
+ subq.w #1,d0
+ btst.b #2,$dff016
+ beq.s \@b
+ pop d0
+ opt chkimm
+ endm
+ else
+waitit macro
+ endm
+ endc
+
+ ifd DEBUGX
+amsg macro ;Text
+ opt w-
+ bsr DPrintf
+ opt w+
+ bra.s \@a
+\@b dc.b '\1'
+ ifeq NARG-1
+ dc.b 10
+ endc
+ dc.b 0
+ even
+\@a
+ endm
+ else
+amsg macro
+ endm
+ endc
+
+ include "SSMac.h"
+
+_LVOAddBootNode equ _LVOexpansionUnused
+
+;Main part:
+;My ResidentTag#
+;Word NULL - LongAlign#
+;Code#
+;Temporary variables
+;Static variables#
+;ResCmds SegLists+checksums#
+;NULL - stop of ResCmds#
+;Resident SegLists+checksums#
+;MyResident pointer#
+;Resident pointers#
+;ResidentList successor
+;KickMemHeader successor
+;KickMemHeader(w/o successor)#
+;KickMem(|s) [1-3]#
+;RES disk data#
+;DosHandler name#
+;Volume name#
+;ResCmds names#
+
+MyFORBID macro ;[exec]
+ ifne NARG
+ move.l 4.w,a6
+ endc
+ addq.b #1,TDNestCnt(a6)
+ endm
+
+ rsreset ;FileChain for ReadFiles
+FC_MinNode rs.b MLN_SIZE
+FC_FileSize rs.b 0 ;FileSize (1 Long)
+FC_DirList rs.b MLH_SIZE
+FC_ProtBits rs.b 1 ;Protection Bits (b7=1 -> dir)
+FC_FileName rs.b 0 ;FileName (ASCIIZ)
+FC_SIZEOF rs.b 0 ;w/o FileName
+
+ rsreset
+RFC_FileSize rs.l 1 ;Size of file/dir in bytes
+RFC_ProtBits rs.b 1 ;Protection bits (b7=1 -> dir)
+RFC_FileName rs.b 0 ;FileName (ASCIIZ)
+RFC_SIZEOF rs.b 0 ;w/o FileName
+
+ rsreset ;Resident chain
+RC_Next rs.l 1 ;^Next chain or NULL
+RC_Type rs.w 1 ;Type RCT_#?
+RC_CmdName rs.b 0 ;RCT_Cmd -> ^FileName of the PathName
+RC_Resident rs.b 0 ;!=RCT_Cmd -> ^ResidentTag
+RC_Tracker rs.l 1 ;File tracker
+RC_CheckSum rs.b 0 ;Segment values sum (LONG)
+RC_CheckSummed rs.w 1 ;BOOL value for summing
+RC_Hunks rs.w 1 ;# of hunks
+RC_SIZEOF rs.b 0 ;w/o (hunk sizes|hunk pointers)
+
+RCT_Cmd equ -1
+RCT_Lib equ 0
+RCT_KickMod equ 1
+
+ dbuf Anchor,ap_SIZEOF+PathLen
+ dv.l AnyTrk ;A! - Must be first
+ dv.l ChipTrk ;A!
+ dv.l ResMemory ;A! - Tracker of handler's memory
+ dbuf Root,FC_SIZEOF+1
+ dv.l RootLock
+ dv.l ResList ;Fwd-Linked list of residents
+ dv.l VolName ;B!
+ dv.l DevName ;B!
+ dv.l BootPri ;B!
+ dv.l OldCurDir
+ dv.l InhibitEnd ;Address of terminating 0/':' or NULL
+ dv.l LinPool
+ dbuf.l EOFRegs,9
+HunkBuf equ EOFRegs ;Size=20 bytes
+ dbuf AbsHeader,56
+ dv.w MEntries
+ dv.w UnitNum
+ dbuf StDevName,6
+ dbuf StVolName,9
+ dv.b Advisory
+
+ start
+
+ get.l sv_thistask,a0
+ put.l pr_CurrentDir(a0),OldCurDir
+ get.l Arg_Verbose,d0
+ beq.s NoneVerbose
+ move.l d0,a2
+ moveq #0,d2
+VerbParseMLoop move.b (a2)+,d0
+ beq.s VerbParseDone
+ move.b d0,d3
+ call utility,ToUpper
+ gett VerbParseTab,a1
+VerbParseCLoop move.b (a1)+,d1
+ bne.s VerbParseChar
+ dtl <Unrecognised VERBOSE char: ''%c''>,a0
+ move.w d3,-(sp) ;I hope RawDoFmt'll ignore b8-b15...
+ bra ErrorA1SS
+
+VerbParseChar cmp.b (a1)+,d0
+ bne.s VerbParseCLoop
+ or.b d1,d2
+ addq.b #2,d1
+ sne d1
+ and.b d1,d2 ;Clear if 254 (None)
+ bra.s VerbParseMLoop
+
+VerbParseDone put.l d2,Arg_Verbose
+NoneVerbose geta BootPri+4,a4
+ moveq #StdBootPri,d1
+ get.l Arg_BootPri,d0
+ beq.s BootPriStd
+ move.l d0,a0
+ move.l (a0),d1
+BootPriStd move.l d1,-(a4)
+ ext.w d1
+ ext.l d1
+ cmp.l (a4),d1
+ dtl <BootPri value %ld out of range (-128..127)>,a0
+ bne.s ErrorSSA4
+ move.l #RT_SIZE+2+ResidentCode+ResidentVars+12+ML_SIZE+ME_SIZE+RFC_SIZEOF+1,d6 ;RAM disk size
+ geta StDevName,a3
+ moveq #'0',d4
+ moveq #'0'-1,d5
+ moveq #LDF_DEVICES!LDF_READ,d1
+ moveq #LDF_DEVICES!LDF_READ,d3
+ call dos,LockDosList
+ move.l d0,d7
+ get.l Arg_Device,d0
+ beq DeviceStd
+ move.l d0,a2
+ dt InvalidName,<Invalid device name "%s">
+ tpea InvalidName
+ move.l a2,-(a4)
+TestDevNameLoop tst.b (a2)
+ beq.s TestDevError
+ cmp.b #':',(a2)+
+ bne.s TestDevNameLoop
+ tst.b (a2)
+ beq.s TestDevTerm
+TestDevError moveq #LDF_DEVICES!LDF_READ,d1
+ call UnLockDosList
+ pop a0
+ErrorSSA4 move.l a4,a1
+ bra ErrorSS
+
+TestDevTerm sub.l (a4),d6
+ add.l a2,d6 ;ASCIIZ name length
+ clr.b -(a2) ;Cut out ':'
+ move.l (a4),d2
+ move.l d7,d1
+ call FindDosEntry
+ tst.l d0
+ dt DevExists,<Device %s: already exists>
+ tpea DevExists
+ bne.s TestDevError
+ addq #8,sp
+ bsr.s DevNumDigit
+ bra DevStdOkay
+
+FindFreeNum move.l 4.w,a6
+ MyFORBID
+ move.l KickTagPtr(a6),d0
+ beq.s DevNumNoTags
+DevNumTagLoop bclr.l #31,d0
+ move.l d0,a0
+DevNumTgLoop move.l (a0)+,d0
+ beq.s DevNumNoTags
+ bmi.s DevNumTagLoop
+ move.l d0,a1
+ move.l RT_NAME(a1),a1
+ moveq #ResNumOne-ResName-1,d0
+ lea ResName(pc),a2
+ResNameLoop move.b (a1)+,d1
+ beq.s DevNumTgLoop
+ cmp.b (a2)+,d1
+ dbne d0,ResNameLoop
+ bne.s DevNumTgLoop
+ cmp.b (a2)+,d4
+ bne.s DevNumTgLoop
+ cmp.b (a2)+,d5
+ bne.s DevNumTgLoop
+ tst.b (a2)
+ bne.s DevNumTgLoop
+DevNumNoTags call Permit
+ get.l dosbase,a6
+ tst.w d0
+ beq Return
+DevNumDigit cmp.b #'9',d5
+ bne.s DevNumDigitL
+ cmp.b #'9',d4
+ bne.s DevNumDigitH
+ dt MaxDisks,<Max. # of RES disks reached>
+ tpea MaxDisks
+ bra TestDevError
+
+DevNumDigitH addq.b #1,d4
+ moveq #'0'-1,d5
+DevNumDigitL addq.b #1,d5
+ bra.s FindFreeNum
+
+DeviceStd move.l a3,-(a4)
+ move.l MyDiskTypeAddr(pc),(a3)
+DevNumLoop bsr.s DevNumDigit
+ lea 3(a3),a2
+ cmp.b #'0',d4
+ beq.s DevNum1Null
+ move.b d4,(a2)+
+ bra.s Digit2Force
+
+DevNum1Null cmp.b d4,d5
+ beq.s Digit2Null
+Digit2Force move.b d5,(a2)
+Digit2Null move.l a3,d2
+ move.l d7,d1
+ call FindDosEntry
+ tst.l d0
+ bne.s DevNumLoop
+DevNumOkay move.l a3,a2
+DevNumLength tst.b (a2)+
+ bne.s DevNumLength
+ sub.l (a4),a2
+ add.l a2,d6
+DevStdOkay moveq #LDF_DEVICES!LDF_READ,d1
+ call UnLockDosList
+ put.b d4,UnitNum
+ put.b d5,UnitNum+1
+ get.l Arg_Name,d0
+ move.l d0,a0
+ bne.s VolumeCustom
+ geta StVolName,a0
+ move.l a0,a1
+ move.l #'ResR',(a1)+ ;Standard volume name
+ move.w #'am',(a1)+
+ lea 3(a3),a2
+VolNameEnd move.b (a2)+,(a1)+
+ bne.s VolNameEnd
+VolumeCustom move.l a0,-(a4)
+TestVolName tst.b (a0)+
+ bne.s TestVolName
+ sub.l (a4),a0
+ add.l a0,d6
+
+ moveq #64,d0
+ lsl.l #6,d0 ;4KBytes Quantum
+ moveq #MEMF_PUBLIC,d1
+ call ss,TrackLinPool
+ put.l d0,LinPool
+ geta Root+LN_PRED,a1
+ move.l a1,-(a1)
+ addq #FC_DirList,a1
+ bsr InitDir ;@A4=Parent/Current dir
+ getad Anchor,a0,d2
+ move.l #(APF_DOWILD!APF_DODOT)<<24!PathLen,ap_Flags(a0)
+ get.l Arg_Files,d1
+ call dos,MatchFirst
+ tst.l d0
+ beq.s FileScanFirst
+ cmp.l #ERROR_NO_MORE_ENTRIES,d0
+ErrNoMorePtr equ *-4
+ bne.s ErrorScan
+ vpush Arg_Files
+ dtl <No files match %s>,a0
+ErrorA1SS move.l sp,a1
+ErrorSS jump ss,ExitError
+
+ErrorScan dtl <Error scanning files %s>,a0
+ vpush Arg_Files
+SSDosErrorA1 move.l sp,a1
+ jump ss,DosError
+
+PrintDirName btstv.b #VerbB_Dirs,Arg_Verbose+3
+ beq Return
+ vpea Anchor+ap_Buf
+ dtl <Scanning directory %s ...',13,$9B,'K>,a0
+ move.l sp,a1
+ call ss,Printf
+ReturnSPinc addq #4,sp
+ rts
+
+FileScanFirst get.l Anchor+ap_Current,a0
+ move.l an_Lock(a0),d1
+ call DupLock
+ put.l d0,RootLock
+ beq.s ErrorScan
+ tstv.l Arg_Verbose
+ beq.s FileScanLoop
+ dtl <',$9B,'0 p>,a0
+ call ss,Puts
+
+FileScanLoop tstv.l Anchor+ap_Info+fib_DirEntryType
+ bpl.s IsDir
+ btstv.b #VerbB_Files,Arg_Verbose+3
+ sne d7
+ beq.s FileVerbOff
+ bsr.s FileHeader
+FileVerbOff tstv.b Anchor+ap_Info+fib_Protection+3
+ bpl IsFile
+ tst.b d7
+ beq.s NextFile
+ dtl <Skipped>,a0
+ call PutsNL
+ bra.s NextFile
+
+FileHeader geta Anchor+ap_Buf,a0
+ call ss,Puts
+ dtl < - >,a0
+ jump Puts
+
+IsDir bclrv.b #APB_DIDDIR,Anchor+ap_Flags
+ bne WasDir
+ bsetv.b #APB_DODIR,Anchor+ap_Flags
+ tstv.b Anchor+ap_Info+fib_FileName
+ beq.s ClimbedUp
+ bsr AllocateFC
+ call ss,TestStack
+ push a4
+ bsr InitDir
+ClimbedUp bsr PrintDirName
+
+NextFile call ss,TestBreak
+ getad Anchor,a0,d1
+ call dos,MatchNext
+ tst.l d0
+ beq.s FileScanLoop
+ cmp.l ErrNoMorePtr(pc),d0
+ bne ErrorScan
+ bsr FlushStdout
+ get.l ResList,d3
+ beq ListPreNull ;No resident modules -> No detaching
+;Calculate size of the parts for detaching
+ geta ResMemory,a4
+ListPreSize move.l d3,a2
+ move.l (a2)+,d3 ;RC_Next
+ addq #RC_Hunks-RC_Type,a2
+ move.w (a2)+,d0 ;RC_Hunks
+ bra.s HunkSizeInto
+
+HunkSize move.l (a2)+,d1
+ addq.l #2,d1
+ move.l a4,a0
+ lsl.l #2,d1
+ bcs.s HunkSizeChip
+ subq #4,a0
+HunkSizeChip add.l d1,-(a0)
+HunkSizeInto dbra d0,HunkSize
+ tst.l d3
+ bne.s ListPreSize
+;Allocate detach part
+ moveq #MEMF_CHIP,d1
+ move.l sp,a2
+ dtl <CHIP>,a3
+ dt PublicMsg,<PUBLIC>
+GetDetaches push d1
+ move.l -(a4),d2
+ beq.s NoPart
+ addq.l #ME_SIZE,d6 ;(Any|Chip)Detach entry
+ gett DetachMsg,a0
+ move.l a3,a1
+ bsr AllocMemTopF
+ move.l d1,(a4)
+ move.l (sp),d1
+ move.l d0,(sp)
+ addq #5,a3
+NoPart subq.l #MEMF_CHIP,d1 ;CHIP,void
+ bcc.s GetDetaches
+;Fill in hunk pointers
+ get.l ResList,d2
+NextPtrMain move.l d2,a0
+ move.l (a0)+,d2 ;RC_Next
+ addq #RC_Hunks-RC_Type,a0
+ move.w (a0)+,d0
+ geta ResMemory,a2 ;Trashed long
+ bra.s HunkPtrsInto
+
+HunkPtrsLoop move.l (a0),d1
+ move.l sp,a3
+ lsl.l #2,d1
+ bcc.s HunkPtrsAny
+ addq #4,a3
+HunkPtrsAny move.l (a3),a1
+ move.l d1,(a1)
+ addq.l #8,(a1)+
+ move.l a1,d3
+ lsr.l #2,d3
+ move.l d3,(a2)
+ move.l a1,a2
+ clr.l (a1)+
+ move.l a1,(a0)+
+ add.l d1,a1
+ move.l a1,(a3)
+HunkPtrsInto dbra d0,HunkPtrsLoop
+ tst.l d2
+ bne.s NextPtrMain
+ addq #8,sp ;Trash destination addresses
+;LoadSeg the file
+ vmovev.l ResList,EOFRegs
+LoadSegLoop get.l EOFRegs,a4 ;previously D2
+ addq.l #8,d6 ;SegList+Checksum
+ move.l (a4)+,d4 ;RC_Next
+ move.w (a4)+,d3 ;RC_Type
+ bmi.s LoadSegCmd
+ addq.l #4,d6 ;^ResidentTag
+LoadSegCmd move.l (a4),a2 ;RC_Tracker
+ lea trk_ext(a2),a2
+ move.l (v),a6
+ btstv.b #VerbB_LoadFiles,Arg_Verbose+3
+ beq.s SkipLoadSegInfo
+ move.l a2,a1
+ dtl <LoadSeg of the file %s ...',13,$9B,'K>,a0
+ call Printf
+SkipLoadSegInfo move.l (a2),a0 ;trk_ext
+ move.l -(a2),d2 ;trk_data
+ moveq #OPEN_OLD,d0
+ moveq #0,d1
+ call TrackOpenBufFH
+ move.l d4,d2
+ move.l d0,a2
+ addq #RC_SIZEOF-RC_Tracker,a4
+ movemv.l d2-d6/a2/a4/a6/sp,EOFRegs
+ moveq #0,d4
+ moveq #0,d5
+;A4=Hunk pointer table
+;A2=File tracker
+;D2=Next RC
+;D3.W=Type
+;D4=Current hunk #*4 - modifiable
+;D5=Ptr to current hunk - (A2,D4.l) or NULL for no current hunk - modifiable
+HunkMainLoop movemv.l d4/d5,EOFRegs+2*4
+ vmovem.l EOFRegs+5*4,a2/a4/a6
+ lea FileEnd(pc),a0
+ move.l a0,bh_eofhook(a2)
+ call BGetLong
+ lea HunkError(pc),a0
+ move.l a0,bh_eofhook(a2)
+ bclr.l #HUNKB_ADVISORY,d0
+ snev Advisory
+ sub.w #HUNK_NAME,d0
+ bcs BadHunk
+ cmp.w #HUNK_RELRELOC32-HUNK_NAME+1,d0
+ bcc BadHunk
+ lsl.l #1,d0
+ move.w HunkTable(pc,d0.w),d1
+ swap d0
+ lsl.w #2,d0
+ bne HunkError
+ jsr HunkTable(pc,d1.w)
+ bra.s HunkMainLoop
+
+hunk macro ;HUNK_#?[,<routine>]
+ ifne _hunk-\1
+ fail Mismatched hunk numbers!
+ endc
+ ifeq NARG-1
+ dc.w BadHunk-HunkTable
+ else
+ dc.w hunk_\2-HunkTable
+ endc
+_hunk set _hunk+1
+ endm
+_hunk set 1000
+HunkTable
+ hunk HUNK_NAME,skipcnt ;1000
+ hunk HUNK_CODE,main ;1001
+ hunk HUNK_DATA,main ;1002
+ hunk HUNK_BSS,main ;1003
+ hunk HUNK_RELOC32,rel32 ;1004
+ hunk HUNK_RELOC16 ;1005
+ hunk HUNK_RELOC8 ;1006
+ hunk HUNK_EXT ;1007
+ hunk HUNK_SYMBOL,symbol ;1008
+ hunk HUNK_DEBUG,skipcnt ;1009
+ hunk HUNK_END,end ;1010
+ hunk HUNK_HEADER ;1011
+ hunk 1012 ;????
+ hunk HUNK_OVERLAY ;1013
+ hunk HUNK_BREAK ;1014
+ hunk HUNK_DREL32,rel16 ;1015
+ hunk HUNK_DREL16 ;1016
+ hunk HUNK_DREL8 ;1017
+ hunk HUNK_LIB ;1018
+ hunk HUNK_INDEX ;1019
+ hunk HUNK_RELOC32SHORT,rel16 ;1020
+ hunk HUNK_RELRELOC32,rrel16 ;1021
+ ifne _hunk-HUNK_RELRELOC32-1
+ fail Invalid number of hunks!
+ endc
+
+FileEnd vmovem.l EOFRegs,d2-d6/a2/a4/a6/sp
+ tst.l d5
+ bne HunkError
+ move.l a4,a3
+ lsr.l #2,d4
+ cmp.w -(a4),d4 ;RC_Hunks
+ bne HunkError
+ subq #RC_Hunks-RC_Tracker,a4
+ move.l (a4),a0 ;RC_Tracker
+ call FreeObject ;Non-buffered tracker
+ move.w d4,d7
+ tst.w d3 ;RC_Type
+ bmi.s LoadEndCmd
+ move.l a3,d5
+FindResInto dbra d4,FindResLoop
+ push bh_name(a2)
+ dtl <No resident tag found in file "%s">,a0
+ bra ErrorA1SS
+
+LoadEndCmd move.l bh_name(a2),d1
+ call dos,FilePart
+ move.l d0,(a4)+ ;RC_CmdName
+ bra.s LoadEnd
+
+FindResLoop move.l (a3)+,a0
+ move.l -8(a0),d0 ;Size of the hunk
+ moveq #RT_SIZE+8,d1
+ sub.l d1,d0
+ bcs.s FindResInto
+ lsr.l #1,d0
+ move.w d0,d1
+ swap d0
+FindResTag1 cmp.w #RTC_MATCHWORD,(a0)+
+FindResTag2 dbeq d1,FindResTag1
+ dbeq d0,FindResTag1
+ bne.s FindResInto
+ move.l a0,d0
+ subq.l #2,d0
+ cmp.l (a0),d0
+ bne.s FindResTag2
+ tst.w d3 ;RC_Type
+ bne.s KickMod
+ move.b RT_FLAGS-RT_MATCHTAG(a0),d0
+ and.b #$80,d0
+ or.b #RTF_AFTERDOS,d0
+ move.b d0,RT_FLAGS-RT_MATCHTAG(a0)
+ move.b #-128,RT_PRI-RT_MATCHTAG(a0)
+KickMod move.l (a0),(a4)+ ;RC_Resident
+ move.l d5,a3
+LoadEnd move.l a2,a0
+ call ss,FreeObject
+ moveq #0,d3
+ tst.w (a4)
+ beq.s CalcNoSum
+ subq.w #1,d7
+CalcSumMod move.l (a3)+,a0
+ move.l -8(a0),d0
+ lsr.l #2,d0
+ subq.l #3,d0
+ bmi.s CalcSumModInto
+ move.w d0,d1
+ swap d0
+CalcSumIt add.l (a0)+,d3
+ dbra d1,CalcSumIt
+ dbra d0,CalcSumIt
+CalcSumModInto dbra d7,CalcSumMod
+ seq d0
+ sub.b d0,d3
+CalcNoSum move.l d3,(a4)+ ;RC_CheckSum
+ move.l (a4),d0
+ lsr.l #2,d0
+ subq.l #1,d0
+ move.l d0,(a4)
+ tst.l d2
+ bne LoadSegLoop
+ bsr FlushStdout
+ListPreNull move.l d6,d2
+ gett BlockMsg,a0
+ dtl <Main>,a1
+ bsr AllocMemTop
+ put.l d1,ResMemory
+ move.l d0,d5
+ move.l d0,a1
+ move.w #RTC_MATCHWORD,(a1)+ ;RT_MATCHWORD
+ move.l #(RTF_COLDSTART<<24)!(1<<16),d7 ;RT_[FVTP]#?
+ lea ResName-ResidentPart+RT_SIZE-RT_MATCHTAG+2(a1),a0
+ move.l a0,d2
+ lea ResID-ResidentPart+RT_SIZE-RT_MATCHTAG+2(a1),a2
+ lea ResInit-ResidentPart+RT_SIZE-RT_MATCHTAG+2(a1),a3
+ movem.l d0/d4/d7/a0/a2/a3,(a1)
+ lea RT_SIZE-RT_MATCHTAG+2(a1),a1
+ lea ResidentPart(pc),a0
+ move.l #ResidentCode,d0
+ lea ResidentCode+ResidentVars(a1),a3
+ call exec,CopyMem
+ get.w UnitNum,ResNumOne-V-ResidentVars(a3)
+ get.w UnitNum,ResNumTwo-V-ResidentVars(a3)
+ lea -ds_SIZEOF(a3),a2
+ move.l a2,d1
+ call dos,DateStamp ;dosbase used below!
+ get.l ResList,d0
+ beq.s NoList1
+Cmds1Loop move.l d0,a0
+ move.l (a0)+,d0 ;RC_Next
+ tst.w (a0)+ ;RC_Type
+ bpl.s NoCmdNode1
+ addq #RC_SIZEOF-RC_CmdName,a0
+ move.l (a0),(a3)+ ;RC_SIZEOF - SegList
+ move.l -(a0),(a3)+ ;RC_CheckSum
+NoCmdNode1 tst.l d0
+ bne.s Cmds1Loop
+NoList1 clr.l (a3)+
+ get.l ResList,d0
+ beq.s NoList3
+Libs2Loop move.l d0,a0
+ move.l (a0)+,d0 ;RC_Next
+ tst.w (a0)+ ;RC_Type
+ bmi.s NoLibNode2
+ addq #RC_SIZEOF-RC_Resident,a0
+ move.l (a0),(a3)+ ;SegList
+ move.l -(a0),(a3)+ ;LibChkSum
+NoLibNode2 tst.l d0
+ bne.s Libs2Loop
+NoList3 push a3 ;STACK=^Resident list
+ move.l a3,-(a2) ;ResListPtr
+ move.l d5,(a3)+ ;My resident struct
+
+ get.l ResList,d0
+ beq.s NoList2
+Libs1Loop move.l d0,a0
+ move.l (a0)+,d0 ;RC_Next
+ tst.w (a0)+ ;RC_Type
+ bmi.s NoResMod
+ move.l (a0),(a3)+ ;RC_Resident
+NoResMod tst.l d0
+ bne.s Libs1Loop
+NoList2 move.l a3,-(a2) ;ResListSucc
+ clr.l (a3)+
+ clr.l (a3)+ ;LN_SUCC
+ push a3 ;STACK=^Resident list succ
+ clr.l (a3)+ ;LN_PRED
+ move.w #NT_KICKMEM<<8,(a3)+ ;LN_TYPE+LN_PRI
+ move.l d2,(a3)+ ;LN_NAME
+ get.w MEntries,(a3)+ ;ME_NUMENTRIES
+ geta AnyTrk,a0
+ moveq #2,d0
+MEntryLoop move.l (a0)+,d1
+ beq.s NoMEntry
+ move.l d1,a4
+ move.l trk_data(a4),(a3)+ ;ME_ADDR
+ move.l trk_ext(a4),(a3)+ ;ME_LENGTH
+NoMEntry dbra d0,MEntryLoop
+ move.l a3,-(a2) ;RootPtr
+ clr.l -(a2) ;NumLocks
+ clr.l -(a2) ;VolumeNode
+ move.l MyDiskTypeAddr(pc),-(a2) ;id_DiskType
+ moveq #64,d0
+ lsl.l #3,d0
+ move.l d0,-(a2) ;id_BytesPerBlock
+ move.l a3,a1
+ move.l -(a1),d0 ;Length
+ move.l d0,d7
+ add.l -(a1),d7
+ lsr.l #8,d0
+ lsr.l #1,d0 ;BlockSize=512
+ addq.l #1,d0
+ move.l d0,-(a2) ;id_NumBlocksUsed
+ move.l d0,-(a2) ;id_NumBlocks
+ moveq #ID_WRITE_PROTECTED,d0
+ move.l d0,-(a2) ;id_DiskState
+ clr.l -(a2) ;id_UnitNumber
+ clr.l -(a2) ;id_NumSoftErrors
+
+ mpush a1/a2
+ get.l RootLock,d1
+ call dos,CurrentDir
+ geta Root,a2
+ bsr ReadFiles
+ bsr FlushStdout
+ mpop a1/a2
+
+ move.l a3,-(a2) ;DosHName
+ geta DevName,a1
+ move.l (a1),a0
+LenDosHName tst.b (a0)+
+ bne.s LenDosHName
+ sub.l (a1),a0
+ move.w a0,d0
+ subq.w #1,d0
+ move.b d0,(a3)+
+ move.l (a1),a0
+ bra.s CopyDosHNameI
+
+CopyDosHNameL move.b (a0)+,(a3)+
+CopyDosHNameI dbra d0,CopyDosHNameL
+
+ move.l a3,-(a2) ;VolumeName
+ move.l -(a1),a0 ;VolName
+CopyVolName move.b (a0)+,(a3)+
+ bne.s CopyVolName
+
+ move.l a3,-(a2) ;CmdsNames
+ get.l ResList,d0
+ beq.s NoCmdsNoNames
+CmdNamesLoop move.l d0,a0
+ move.l (a0)+,d0
+ tst.w (a0)+ ;RC_Type
+ bpl.s NoCmdName
+ move.l (a0)+,a0 ;RC_CmdName
+CopyCmdName move.b (a0)+,(a3)+
+ bne.s CopyCmdName
+NoCmdName tst.l d0
+ bne.s CmdNamesLoop
+NoCmdsNoNames
+ move.l d5,a0
+ move.w #(RT_SIZE+2+ResidentCode)>>2-1,d1
+ moveq #0,d0
+GenSumMain sub.l (a0)+,d0
+ dbra d1,GenSumMain
+ move.l a2,a0
+GenSumMainE sub.l (a0)+,d0
+ cmp.l a0,d7
+ bne.s GenSumMainE
+ move.l d0,-(a2) ;AnySum
+ get.l BootPri,-(a2) ;VarBootPri
+
+;### Write out the AbsModule (if wished) ###
+;-HEADER- 00000000 00000001 00000000 00000000 *Length* --CODE--
+;*Length* 74Ln6014 0000ABCD 00000000 00000000 00000000 00000000
+ move.l (v),a6
+ pop a4 ;-(A4)=KickMem, ResListSucc
+ get.l Arg_GenAbs,d0
+ beq GenDisk
+ btstv.b #VerbB_SizeMod,Arg_Verbose+3
+ beq.s NoModVerb
+ push d0
+ dtl <Writing AbsModule to the file %s ...>,a0
+ move.l sp,a1
+ call Printf
+ bsr FlushStdout
+ move.l (v),a6
+ pop d0
+NoModVerb move.l d0,a0
+ moveq #OPEN_NEW,d0
+ moveq #0,d1
+ call TrackOpenBuf
+ move.l d0,a3
+ geta AbsHeader,a0
+ move.l HeaderPtr(pc),(a0)
+ addq.w #1,10(a0)
+ moveq #AbsHdrLength+3,d0
+ geta AnyTrk,a2
+ moveq #2,d1
+ move.l #$60147400!(21+AbsRawLength>>2),d2
+OutAbsLenLoop tst.l (a2)+
+ beq.s OutAbsLenInto
+ addq.w #2,d0
+ addq.b #2,d2
+OutAbsLenInto dbra d1,OutAbsLenLoop
+ move.w d0,22(a0)
+ subq.w #1,d0
+ move.w d0,30(a0)
+ move.w #HUNK_CODE,26(a0)
+ swap d2
+ move.l d2,32(a0)
+ move.w #$ABCD,38(a0)
+ moveq #56,d0
+ call BWrite
+ lea AbsModule(pc),a0
+ move.l #AbsRawLength,d0
+ call BWrite
+ lea _LVOBPutLong(a6),a1
+ bsr GenerateEnd
+ move.l #HUNK_END,(a0)+
+ move.l #HUNK_OVERLAY,(a0)+
+ clr.l (a0)+
+ clr.l (a0)+
+ move.l #HUNK_BREAK,(a0)+
+ move.l a0,d0
+ sub.l d3,d0
+ move.l d3,a0
+ call BWrite
+ bsr ClosenCleanup
+
+;### Generate AbsModule to the disk (if wished) ###
+GenDisk get.l Arg_GenDisk,d2
+ beq PrepHandler
+ moveq #LDF_DEVICES+LDF_READ,d1
+ call dos,LockDosList
+ move.l d0,d1
+ move.l d2,a3
+ moveq #':',d4
+ moveq #LDF_DEVICES,d3
+NextChar move.b (a3)+,d0
+ beq DiskErrorSP
+ cmp.b d4,d0
+ bne.s NextChar
+ clr.b -(a3)
+ call FindDosEntry
+ tst.l d0
+ beq NoDosEntry
+ move.l d0,a0
+ move.l dn_Startup(a0),d0
+ beq NoDosEntry
+ lsl.l #2,d0
+ move.l d0,a0
+ push (a0)+ ;fssm_Unit
+ push (a0)+ ;fssm_Device
+ move.l (a0)+,d0 ;fssm_Environ
+ push (a0) ;fssm_Flags
+ lsl.l #2,d0
+ move.l d0,a0
+ move.l (a0)+,d6 ;de_TableSize
+ cmp.l #128,(a0) ;de_SizeBlock
+ bne.s NoDosEntry
+ push de_HighCyl-de_SizeBlock(a0)
+ push de_LowCyl-de_SizeBlock(a0)
+ push de_Surfaces-de_SizeBlock(a0)
+ moveq #MEMF_PUBLIC,d0
+ subq.l #8,d6
+ subq.l #4,d6
+ bmi.s NoBufMemType
+ move.l de_BufMemType-de_SizeBlock(a0),d0
+NoBufMemType put.l d0,sv_memattr
+ move.l de_BlocksPerTrack-de_SizeBlock(a0),d0
+ moveq #3,d1 ;Min. are 3 Blocks/Track
+ cmp.l d1,d0
+ bcs.s NoDosEntry
+ lsl.l #8,d0
+ lsl.l #1,d0
+ move.l d0,d6 ;TrackBuffer size
+ get.l utilitybase,a0
+ lea _LVOUMult32(a0),a0
+ pop d1 ;de_Surfaces
+ jsr (a0)
+ pop d1 ;de_LowCyl
+ move.l d0,d7 ;Cylinder size
+ jsr (a0)
+ exg.l d0,d7 ;Position offset<->Cylinder size
+ pop d1 ;de_HighCyl
+ addq.l #1,d1
+ jsr (a0)
+ sub.l d7,d0
+ moveq #64,d5
+ lsl.l #3,d5 ;BootBlock size 512
+ geta AnyTrk,a0
+ moveq #2,d3
+LoopDiskTrk move.l (a0)+,d1
+ beq.s NoDiskTrk
+ move.l d1,a1
+ add.l trk_ext(a1),d5
+ subq.l #8,d5
+NoDiskTrk dbra d3,LoopDiskTrk
+ mpush d0/d5
+ push d2
+ dtl <Not enough disk space on the device %s (size %luB, needed %luB)>,a0
+ cmp.l d5,d0
+ bcs ErrorA1SS
+ lea 12(sp),sp
+ moveq #0,d3
+NoDosEntry moveq #LDF_DEVICES+LDF_READ,d1
+ call UnLockDosList
+DiskErrorSP push d2
+DiskError moveq #err_lock,d0
+ move.l (sp),a1
+ subq.l #LDF_DEVICES,d3
+ beq ReportSS
+ move.b d4,(a3)
+ move.l d2,d1
+ moveq #DOSTRUE,d2
+ call Inhibit
+ tst.l d0
+ beq.s DiskError
+ move.l (v),a6
+ put.l a3,InhibitEnd
+ tstv.l Arg_NoDiskReq
+ bne.s SkipDiskReq
+ dtl.lc <Insert disk for the boot image>,a0
+ dt.lc <into drive %s>
+ dt.l <All data on it will be overwritten!>
+ move.l sp,a1
+ dtl <Okay|Cancel>,a2
+ call ss,SimpleRequest
+ move.l d0,d1
+ moveq #err_break,d0
+ tst.l d1
+ beq ReportSS
+SkipDiskReq btstv.b #VerbB_SizeMod,Arg_Verbose+3
+ beq.s NoDiskModVerb
+ dtl <Generating boot image to the drive %s ...>,a0
+ move.l sp,a1
+ call Printf
+ bsr FlushStdout
+NoDiskModVerb addq #4,sp
+ move.l d6,d1
+ moveq #OPEN_NEW,d0
+ move.l d2,a0
+ call ss,TrackBufHandle
+ move.l d0,a3
+ lea RawDiskWrite(pc),a0
+ move.l a0,bh_writefunc(a3)
+ mpop d1/a0 ;fssm_Flags,fssm_Device
+ pop d0 ;fssm_Unit
+ add.l a0,a0
+ add.l a0,a0
+ addq.l #1,a0
+ sub.l a1,a1
+ sub.l a2,a2
+ call TrackDevice
+ move.l d1,bh_handle(a3)
+ move.w #TD_FORMAT,IO_COMMAND(a1)
+ move.l d7,IO_OFFSET(a1)
+ lea _LVOBPutLong(a6),a1
+ moveq #(ImgResList-BootImage)>>2,d0
+ lsl.l #2,d0
+ lea BootImage(pc),a0
+ call BWrite
+ bsr.s GenerateEnd
+ move.l a0,d0
+ move.l d3,a0
+ sub.l a0,d0
+ moveq #512-(ImgResList-BootImage)-4,d3
+ sub.l d0,d3
+ call BWrite
+ lsr.l #2,d3
+FillBoot moveq #0,d0
+ call BPutLong
+ dbra d3,FillBoot
+ bsr.s ClosenCleanup
+
+;### Prepare handler to be resident ###
+PrepHandler pop a3 ;^ResList
+ get.l Arg_Reboot,d0
+ beq.s NoReboot
+ pea ImgRebootNow(pc)
+NoReboot tstv.l Arg_NoRun
+ bne Return
+ tst.l d0
+ bne.s WellReboot
+ pea AbsNextRes(pc)
+WellReboot geta AnyTrk,a0
+ moveq #2,d1
+KillMemTrks move.l (a0)+,d0
+ beq.s NoMemTrk
+ move.l d0,a1
+ clr.b trk_type(a1)
+NoMemTrk dbra d1,KillMemTrks
+ move.l 4.w,a6
+ lea KickMemPtr(a6),a2
+ MyFORBID
+ move.l (a2),-(a4) ;KickMemPtr
+ move.l a4,(a2)+
+ move.l (a2),d0 ;KickTagPtr
+ beq.s NoNextReses
+ bset.l #31,d0
+NoNextReses move.l d0,-(a4)
+ bra EndMainInit
+
+ ifd DEBUG
+EXIT jump ss,ExitCleanup
+ endc
+
+;################
+;### Routines ###
+;################
+
+GenerateEnd geta HunkBuf,a0
+ move.l a0,d3
+ move.l 4(sp),(a0)+
+ move.l a4,(a0)+
+ moveq #2,d7
+ geta AnyTrk,a2
+ push a3
+OutAddrLoop move.l (a2)+,d0
+ beq.s OutAddrNo
+ move.l d0,a3
+ move.l trk_ext(a3),(a0)+
+ move.l trk_data(a3),(a0)+
+OutAddrNo dbra d7,OutAddrLoop
+ pop a3
+ rts
+
+ClosenCleanup geta AnyTrk,a2
+ moveq #2,d7
+OutDataLoop move.l (a2)+,d0
+ beq.s OutNoTrk
+ move.l d0,a0
+ move.l trk_ext(a0),d0
+ subq.l #8,d0
+ move.l trk_data(a0),a0
+ addq #8,a0
+ call BWrite
+OutNoTrk dbra d7,OutDataLoop
+ btstv.b #VerbB_SizeMod,Arg_Verbose+3
+ beq.s NoModSizeVerb
+ move.l a3,a2
+ call BTell
+ move.l d0,d1
+ lsr.l #8,d1
+ addq.l #2,d1
+ lsr.l #2,d1
+ mpush d0/d1
+ move.l sp,a1
+ dtl.l < %lu bytes (%luKB)>,a0
+ call Printf
+ addq #8,sp
+NoModSizeVerb move.l a3,a0
+ jump FreeObject
+
+;Inputs: A2=Source A3=Destination
+ReadFiles tst.l (a2)
+ beq Return
+ move.l (v),a6
+ReadFilesRout move.l a3,a4 ;As ptr where to fill in DirSize
+ lea FC_FileSize(a2),a1
+ move.l (a1)+,d2
+ moveq #3,d1
+PutLongA rol.l #8,d2
+ move.b d2,(a3)+
+ dbra d1,PutLongA
+ addq #MLH_SIZE-MLH_TAIL,a1
+ move.b (a1)+,(a3)+
+ move.l a3,a0
+CopyReadName move.b (a1)+,(a3)+
+ bne.s CopyReadName
+ tst.b FC_ProtBits(a2) ;FileSize (-1 for dir)
+ bmi.s CopyDir
+ btstv.b #VerbB_LoadFiles,Arg_Verbose+3
+ beq.s SkipLoadInfo
+ push a0
+ move.l sp,a1
+ dtl <Loading data file %s ...',13,$9B,'K>,a0
+ call Printf
+ pop a0
+SkipLoadInfo moveq #OPEN_OLD,d0
+ call TrackOpen
+ move.l d1,a0 ;Copy tracker for ChkRead
+ move.l d2,d0 ;Prepare FileSize
+ move.l d1,d2 ;Copy tracker for FreeObject
+ move.l a3,a1 ;Get dest
+ add.l d0,a3 ;Add FileSize to dest
+ call ChkRead
+ move.l d2,a0
+ call FreeObject
+NextObject move.l (a2),a2
+ bra.s ReadFiles
+
+CopyDir call TestStack
+ moveq #ACCESS_READ,d0
+ call TrackLock
+ push d1
+ move.l d0,d1
+ call dos,CurrentDir
+ mpush d0/a2/a4
+ push a3
+ move.l d2,a2
+ bsr.s ReadFiles
+ ; a3/d0/a2/a4
+ mpop d0/d1/a2/a4
+ sub.l a3,d0
+ neg.l d0
+ moveq #3,d2
+PutLongB rol.l #8,d0
+ move.b d0,(a4)+
+ dbra d2,PutLongB ;DirSize filled
+
+ call dos,CurrentDir
+ pop a0
+ call ss,FreeObject
+ bra.s NextObject
+
+IsFile moveq #-1,d3 ;Do checksumming flag
+ geta Anchor+ap_Info+fib_Comment,a2
+ move.l a2,a1
+PreCommentLoop tst.b (a2)
+ beq.s CommentEnd
+ cmp.b #':',(a2)+
+ bne.s PreCommentLoop
+ clr.b -1(a2)
+ dtl <4ResRAM>,a0
+ bsr CompareString
+ tst.l d0
+ bne.s CommentEnd
+CommentSpcLoop cmp.b #' ',(a2)+
+ beq.s CommentSpcLoop
+ subq #1,a2
+ move.l a2,a0
+CommentEndLoop tst.b (a2)
+ beq.s CommentEndOK
+ cmp.b #'!',(a2)+
+ bne.s CommentEndLoop
+ clr.b -(a2)
+ moveq #0,d3 ;'!'=>No checksumming
+CommentEndOK tst.b (a0)
+ beq.s CommentEnd
+ dt FullExtTable,<Data>
+ dt PureCmdMsg,<ResCmd> ;RCT_Cmd
+ dt MinExtTable,<Library> ;RCT_Lib
+ dt <Device> ;RCT_Lib
+ dt.c <KickMod> ;RCT_KickMod
+ dt WordNull,<',0,'>
+ gett FullExtTable,a3
+ bsr.s GetExtNum
+ tst.b (a3)
+ beq.s CommentEnd
+ tst.l d5
+ beq MakeFile
+ subq.l #2,d5
+ bra.s ChecknCorrect
+
+GetExtNum move.l a0,a2
+ moveq #0,d5
+GetExtNumLoop move.l a3,a0
+ move.l a2,a1
+ bsr CompareString
+ tst.l d0
+ beq Return
+ addq.l #1,d5
+SkipExtName tst.b (a3)+
+ bne.s SkipExtName
+ tst.b (a3)
+ bne.s GetExtNumLoop
+ rts
+
+CommentEnd moveq #FIBF_PURE!FIBF_EXECUTE,d0
+ vand.b Anchor+ap_Info+fib_Protection+3,d0
+ moveq #RCT_Cmd,d5
+ gett PureCmdMsg,a3
+ cmp.b #FIBF_PURE,d0
+ beq.s CheckResident
+ geta Anchor+ap_Info+fib_FileName,a0
+ call ss,GetExtension
+ gett MinExtTable,a3
+ bsr.s GetExtNum
+ tst.b (a3)
+ beq MakeFile
+ tst.l d5
+ChecknCorrect shi d0
+ add.b d0,d5 ;Library=Device
+CheckResident geta Anchor+ap_Buf,a2
+ moveq #0,d1
+ bsr LinAlloc
+ move.l d0,a0
+CopyOpen move.b (a2)+,(a0)+
+ bne.s CopyOpen
+ move.l d0,d2
+ get.l Anchor+ap_Last,a0
+ move.l an_Lock(a0),d1
+ call dos,CurrentDir
+ geta Anchor+ap_Info+fib_FileName,a0
+ moveq #OPEN_OLD,d0
+ call ss,TrackOpen
+ push d1
+ move.l d1,a0
+ move.l d2,trk_ext(a0) ;Full PathName of the file
+ geta HunkBuf,a1
+ move.l a1,a2
+ moveq #20,d0
+ call ChkTryRead
+ moveq #20,d1
+ cmp.l d0,d1
+ bne TryHunksFail
+ cmp.l #HUNK_HEADER,(a2)+
+HeaderPtr equ *-4
+ bne TryHunksFail
+ tst.l (a2)+
+ bne TryHunksFail
+ tst.w (a2)
+ bne TryHunksFail
+ move.l (a2)+,d1
+ beq TryHunksFail
+ tst.l (a2)+
+ bne TryHunksFail
+ addq.l #1,(a2)
+ cmp.l (a2),d1
+ bne TryHunksFail
+ move.l d1,d4
+ lsl.l #2,d1
+ move.l d1,d2
+ addq.l #8,d1
+ addq.l #RC_SIZEOF-8,d1
+ bsr LinAllocInt
+ move.l d0,a1
+ geta ResList,a2
+ move.l (a2),(a1)+ ;RC_Next
+ move.w d5,(a1)+ ;RC_Type
+ move.l (sp),(a1)+ ;RC_Tracker
+ move.w d3,(a1)+ ;RC_CheckSummed
+ move.w d4,(a1)+ ;RC_Hunks
+ move.l d0,d3
+ move.l d2,d0
+ move.l (sp),a0
+ push a1
+ call ChkTryRead
+ pop a0
+ cmp.l d0,d2
+ bne TryHunksFail
+ moveq #8,d1 ;SegList+CheckSum
+ move.w d4,d2
+ subq.l #1,d4
+TestHunkFlg move.l (a0)+,d0
+ rol.l #2,d0
+ add.l d0,d1
+ and.w #3,d0
+ sub.l d0,d1
+ addq.l #8,d1
+ subq.l #3,d0
+ dbeq d4,TestHunkFlg
+ beq TryHunksFail
+ move.l d3,(a2)
+ btstv.b #VerbB_LoadSeg,Arg_Verbose+3
+ beq.s NoFileInfo
+ move.w d2,-(sp)
+ push d1
+ tst.b d7
+ bne.s HeaderWritten
+ bsr FileHeader
+HeaderWritten bsr.s WriteFileInfo
+ dtl <; LoadSeg=%lu; Hunks=%u>,a0
+ move.l sp,a1
+ call Printf
+ pop d0
+ vcmp.l Anchor+ap_Info+fib_Size,d0
+ bls.s LoadSegSqueeze
+ dtl <; Large BSS part!!!>,a0
+ call Puts
+LoadSegSqueeze addq #2,sp
+ bra.s DoMsgCR
+
+NoFileInfo tst.b d7
+ beq.s NoMsgCR
+ bsr.s WriteFileInfo
+DoMsgCR bsr.s WriteOutCR
+NoMsgCR tst.w d5
+ bpl.s NotCmdIsNoName
+ geta Anchor+ap_Info+fib_FileName,a0
+ move.l a0,d0
+TestResNameLen tst.b (a0)+
+ bne.s TestResNameLen
+ sub.l d0,a0
+ add.l a0,d6
+NotCmdIsNoName addq #4,sp ;Discard the file tracker
+ bra NextFile
+
+WriteOutCR gett WordNull,a0
+ jump PutsNL
+
+WriteFileInfo move.l a3,a0
+ call Puts
+ tst.l d3
+ bne.s HasChkSum
+ dtl < (don''t checksum)>,a0
+ call Puts
+HasChkSum dtl <; Size=%lu>,a0
+ geta Anchor+ap_Info+fib_Size,a1
+ jump Printf
+
+LinAlloc move.l a2,a0
+TestGlobLen tst.b (a0)+
+ bne.s TestGlobLen
+ sub.l a2,a0
+ add.l a0,d1
+LinAllocInt get.l LinPool,a0
+ jump ss,LinearAlloc ;1/3 may be LinearAllocN, but ...
+
+TryHunksFail pop a0
+ call FreeObject
+MakeFile tst.b d7
+ beq.s NoFileVerbose
+ moveq #-1,d3
+ gett FullExtTable,a3
+ bsr.s WriteFileInfo
+ bsr.s WriteOutCR
+NoFileVerbose bsr.s AllocateFC
+ get.l Anchor+ap_Info+fib_Size,(a1) ;FC_FileSize
+ add.l (a1),d6
+ bra NextFile
+
+AllocateFC geta Anchor+ap_Info+fib_FileName,a2
+ moveq #FC_SIZEOF,d1
+ bsr.s LinAlloc
+ move.l a4,a0
+ move.l d0,a1
+ lea FC_ProtBits(a1),a2
+ call exec,AddTail
+ lea FC_DirList-FC_ProtBits(a2),a1
+ move.l a2,d0
+ get.b Anchor+ap_Info+fib_Protection+3,(a2)+
+ geta Anchor+ap_Info+fib_FileName,a0
+CopyFileNameA move.b (a0)+,(a2)+
+ bne.s CopyFileNameA
+ sub.l d0,a2
+ add.l a2,d6
+ addq.l #RFC_ProtBits,d6
+ rts ;A1=FC_FileSize/FC_DirList
+
+WasDir tstv.b Anchor+ap_Info+fib_FileName
+ beq ClimbedUp
+ tstv.l Arg_EmptyDirs
+ bne.s ClimbUp
+ cmp.l LH_TAILPRED(a4),a4 ;Is list empty?
+ beq.s RemoveThatNode
+ClimbUp move.l a4,a0
+ lea DirItemCmp(pc),a1
+ call ss,SortList
+NoDirLength pop a4
+ geta Anchor+ap_Buf,a2
+ move.l a2,d1
+ call dos,FilePart
+ cmp.l d0,a2
+ bne.s LongerPath
+ clr.b (a2)
+ bra ClimbedUp
+
+LongerPath move.l d0,a0
+ clr.b -(a0)
+ bra ClimbedUp
+
+RemoveThatNode lea -FC_DirList(a4),a1
+ call exec,Remove
+ lea FC_FileName-FC_DirList(a4),a0
+DirNameLength tst.b (a0)+
+ bne.s DirNameLength
+ sub.l a4,a0
+ sub.l a0,d6
+ addq.l #FC_SIZEOF-FC_DirList-RFC_SIZEOF,d6
+ bra.s NoDirLength
+
+;Inputs: A1=FC_DirList
+InitDir move.l a1,a4
+ addq #4,a1
+ move.l a1,(a4)
+ clr.l (a1)+
+ move.l a4,(a1)+
+ bset.b #7,(a1)
+ rts
+
+;Inputs: A0=^^Node1 A1=^^Node2, Results: D0=-1/0/1 (Node1<=>Node2)
+DirItemCmp move.l (a0),a0
+ move.l (a1),a1
+ lea FC_ProtBits(a0),a0
+ lea FC_ProtBits(a1),a1
+ tst.b (a0)+
+ smi d0
+ tst.b (a1)+
+ smi d1
+ sub.b d1,d0
+ beq.s CompareString
+ bpl Return
+ moveq #-1,d0
+ rts
+
+CompareString push a6
+ call utility,Stricmp
+ pop a6
+ rts
+
+AllocMemTop moveq #0,d1
+AllocMemTopF addqv.w #1,MEntries
+ addq.l #8,d2
+ addq.l #MEM_BLOCKMASK,d2
+ and.w #~MEM_BLOCKMASK,d2
+ or.l #MEMF_PUBLIC!MEMF_REVERSE!MEMF_KICK,d1
+ mpush d1/a0/a1
+ bclrv.b #err_memory,sv_errsw+3
+ move.l d2,d0
+ call ss,TrackAllocMem
+ bsetv.b #err_memory,sv_errsw+3
+ tst.l d0
+ bne.s AllocMemTopE
+ move.l d2,d0
+ move.l (sp),d1
+ eor.w #MEMF_KICK!MEMF_LOCAL,d1
+ call TrackAllocMem
+AllocMemTopE addq #4,sp
+ mpop a0/a1
+ btstv.b #VerbB_Mem,Arg_Verbose+3
+ beq.s NoMemVerbose
+ push d1
+ mpush d0/d2
+ push a1
+ dt.c DetachMsg,<Detachable >
+ dt.l BlockMsg,<%s memory block allocated at $%08lx, size $%08lx>
+ move.l sp,a1
+ call Printf
+ addq #4,sp
+ mpop d0/d2
+ pop d1
+NoMemVerbose addq #8,d0
+ rts
+
+FlushStdout get.l stdout,d1
+ jump dos,Flush
+
+Cleanup get.l OldCurDir,d1
+ call dos,CurrentDir
+ get.l RootLock,d1
+ call UnLock
+ getad Anchor,a0,d1
+ call MatchEnd ;after CurrentDir!
+ tstv.l Arg_Verbose
+ beq.s C_NoVerb
+ dtl <',$9B,' p>,a0
+ call ss,Puts
+ bsr.s FlushStdout
+C_NoVerb get.l InhibitEnd,d0
+ beq Return
+ move.l d0,a0
+ move.b #':',(a0)
+ get.l Arg_GenDisk,d1
+ moveq #DOSFALSE,d2
+ jump Inhibit
+
+hunk_main tst.l d5
+ bne HunkError
+ move.l (a4,d4.l),d5
+ push d0
+ call BGetLong
+ move.l d5,a3
+ move.l -8(a3),d6
+ cmp.l #(HUNK_BSS-HUNK_NAME)<<17,(sp)+
+ beq.s DoBSS
+ lsl.l #2,d0
+ sub.l d0,d6
+ add.l d0,a3
+ move.l d5,a0
+ call BRead
+DoBSS lsr.l #2,d6
+ subq.l #2,d6
+ move.w d6,d0
+ swap d6
+ bra.s CPUClearInto
+CPUClearLoop clr.l (a3)+
+CPUClearInto dbra d0,CPUClearLoop
+ dbra d6,CPUClearLoop
+ rts
+
+hunk_end tst.l d5
+ beq HunkError
+ moveq #0,d5 ;No CurrHunk
+ addq.l #4,d4 ;HunkNum+=4
+ rts
+
+hunk_rrel16 moveq #-1,d0
+ bra.s HunkReloc
+hunk_rel16 moveq #1,d0
+ bra.s HunkReloc
+hunk_rel32 moveq #0,d0
+HunkReloc tst.l d5
+ beq.s HunkError
+ move.l d5,a3
+ move.l -8(a3),d6
+ subq.l #8,d6
+ move.l d0,d2 ;RelocType
+ lea _LVOBGetLong(a6),a1
+ beq.s MainRelocLoop
+ addq #6,a1
+MainRelocLoop jsr (a1)
+ tst.l d0
+ beq.s RelocDone
+ move.l d0,d2
+ jsr (a1)
+ lsl.l #2,d0
+ move.l (a4,d0.l),d3
+ bra.s RelocInto
+
+RelocLoop2 swap d2
+RelocLoop1 jsr (a1)
+ cmp.l d6,d0
+ bcc.s HunkError
+ lea (a3,d0.l),a0
+ tst.w d2
+ bpl.s NotRelRel
+ move.l a3,d0
+ sub.l d0,(a0)
+NotRelRel add.l d3,(a0)
+RelocInto dbra d2,RelocLoop1
+ swap d2
+ dbra d2,RelocLoop2
+ bra.s MainRelocLoop
+
+RelocDone call BTell
+ ror.b #2,d0
+ bcc Return
+ jump BGetWord
+
+hunk_symbol call BGetLong
+ tst.l d0
+ beq Return
+ addq.l #1,d0
+ bsr.s RelSeekLongs
+ bra.s hunk_symbol
+
+BadHunk tstv.b Advisory
+ beq.s HunkError
+hunk_skipcnt call BGetLong
+RelSeekLongs lsl.l #2,d0
+ jump BRelSeek
+
+HunkError moveq #err_read,d0
+ get.l EOFRegs+5*4,a0 ;A2=BufFH
+ move.l bh_name(a0),a1
+ReportSS jump ss,ReportError
+
+RawDiskWrite move.l bh_bufsize(a0),d1
+ cmp.l d1,d0
+ bcc.s RDW_Larger
+ move.l d1,d0
+RDW_Larger move.l a1,d1
+ mpush d0/d2/a2/a4
+ bset.b #0,bh_arg1+3(a0)
+ bne.s RDW_OtherWrite
+ move.w #255,d2
+ moveq #0,d0
+RDW_SumLoop add.l (a1)+,d0
+ bcc.s RDW_SkipX
+ addq.l #1,d0
+RDW_SkipX dbra d2,RDW_SumLoop
+ not.l d0
+ move.l d0,-1020(a1)
+RDW_OtherWrite move.l bh_handle(a0),a1 ;DeviceTracker
+ move.l trk_data(a1),a2 ;IoRequest
+ move.l d1,IO_DATA(a2) ;^Buffer
+ move.l (sp),IO_LENGTH(a2)
+ sub.l a0,a0
+ call ss,ChkDoIO
+ pop d0
+ add.l d0,IO_OFFSET(a2)
+ mpop d2/a2/a4
+ rts
+
+;### AbsModule header ###
+AbsModule ;D2=Position in file to seek/2
+AbsModFH equ AbsModule-16
+ ifd ModDebug
+ lea AbsDosName(pc),a1
+ call exec,OldOpenLibrary
+ move.l d0,d6
+ else
+ move.l GV_DosBase(a2),d6
+ endc
+ move.l AbsModFH(pc),d7
+ moveq #OFFSET_BEGINNING,d3
+ move.l d7,d1
+ lsl.l #2,d2
+ move.l d6,a6
+ call Seek
+ call IoErr
+ tst.l d0
+ bne.s AbsExitErr
+ lea AbsModTab(pc),a3
+ move.l sp,d5
+ clr.l -(sp)
+AbsAllocLoop move.l (a3)+,d0
+ beq.s AbsAllocEnd
+ move.l (a3)+,a1
+ move.l d0,d3
+ call exec,AllocAbs
+ move.l d6,a6
+ move.l d0,d2
+ beq.s AbsAllocFail
+ push d0
+ push d3
+ move.l d7,d1
+ addq #8,d2
+ subq #8,d3
+ call Read
+ cmp.l d0,d3
+ beq.s AbsAllocLoop
+AbsExitErrFree pop d0
+ beq.s AbsExitErr
+ pop a1
+ call exec,FreeMem
+ bra.s AbsExitErrFree
+
+AbsExitErr moveq #-1,d0
+ rts
+
+AbsAllocFail moveq #103,d1
+ call SetIoErr
+ bra.s AbsExitErrFree
+
+EndMainInit move.l a3,(a2)+
+ call SumKickData
+ move.l d0,(a2)
+ call Permit
+ jump CacheClearU
+
+AbsAllocEnd move.l d5,sp
+ move.l 4.w,a6
+ lea KickMemPtr(a6),a2
+ MyFORBID
+ move.l AbsKickSucc(pc),a0
+ move.l (a2),-(a0) ;KickMemPtr
+ move.l a0,(a2)+
+ move.l (a2),d0 ;KickTagPtr
+ beq.s AbsNoNextReses
+ bset.l #31,d0
+AbsNoNextReses move.l d0,-(a0)
+ move.l AbsResList(pc),a3
+ bsr.s EndMainInit
+
+AbsNextRes move.l (a3)+,d0
+ ble.s AbsNoNextRes
+ move.l d0,a2
+ move.l RT_NAME(a2),d2
+ move.l d2,a1
+ call FindResident
+ bsr.s AbsChkEnd
+ lea LibList(a6),a0
+ bsr.s AbsChkList
+ lea DeviceList(a6),a0
+ bsr.s AbsChkList
+ move.l a2,a1
+ moveq #0,d1
+ call InitResident
+ bra.s AbsNextRes
+
+AbsChkList move.l d2,a1
+ MyFORBID
+ call FindName
+ call Permit
+AbsChkEnd tst.l d0
+ beq.s AbsReturn
+ addq #4,sp
+ bra.s AbsNextRes
+
+AbsNoNextRes moveq #0,d0
+AbsReturn rts
+
+ ifd ModDebug
+AbsDosName dc.b 'dos.library',0
+ even
+ endc
+
+AbsResList equ *+(*-AbsModule)&2
+AbsKickSucc equ AbsResList+4
+AbsModTab equ AbsKickSucc+4
+
+AbsHdrLength equ (AbsResList-AbsModule+24)>>2
+AbsRawLength equ AbsResList-AbsModule
+
+;### BootBlock of the bootimage disk ###
+
+BootImage dc.l 'DOS'<<8,0,0
+ move.l a1,d4 ;IoRequest
+ move.w #CMD_READ,IO_COMMAND(a1)
+ move.l #1024,IO_OFFSET(a1)
+ lea ImgModTab(pc),a3
+ lea BootImage+512(pc),a4
+ lea BootImage+1024(pc),a5
+ move.l 4.w,a6
+ImgAllocLoop move.l (a3)+,d0
+ beq ImgAllocEnd
+ move.l (a3)+,a1
+ move.l a1,d2
+ move.l d0,d3
+ call AllocAbs
+ tst.l d0
+ beq.s ImgAllocFail
+ addq #8,d2
+ subq #8,d3
+ move.l a5,d0
+ sub.l a4,d0
+ cmp.l d0,d3
+ bcc.s ImgCopyBuf
+ move.l d3,d0
+ImgCopyBuf move.l a4,a0
+ add.l d0,a4
+ move.l d2,a1
+ add.l d0,d2
+ sub.l d0,d3
+ call CopyMemQuick
+ move.l d3,d7
+ and.w #~511,d3
+ eor.l d3,d7
+ bsr.s ImgReadDisk
+ cmp.l a4,a5
+ bne.s ImgAllocLoop
+ push d2
+ lea BootImage+512(pc),a4
+ move.l a4,d2
+ moveq #64,d3
+ lsl.l #3,d3 ;One sector
+ bsr.s ImgReadDisk
+ pop d2
+ move.l d2,a1
+ move.l a4,a0
+ add.l d7,a4
+ move.l d7,d0
+ call CopyMemQuick
+ bra.s ImgAllocLoop
+
+ImgReadDisk move.l d4,a1
+ move.l d2,IO_DATA(a1)
+ add.l d3,d2
+ move.l d3,IO_LENGTH(a1)
+ call DoIO
+ move.l d4,a1
+ move.l IO_OFFSET(a1),d1
+ add.l d3,IO_OFFSET(a1)
+ tst.l d0
+ beq ImgReturn
+ push d0
+ mpush d1/d3
+ lea ImgReadFailMsg(pc),a0
+ bra.s ImgDoAlert
+
+ImgAllocFail mpush d2/d3
+ lea ImgAllocFailMsg(pc),a0
+;A0=Printf-string, SP=Printf-data
+ImgDoAlert move.l sp,a1
+ lea -80(sp),sp
+ move.l sp,a3
+ lea ImgAlertHdr(pc),a2
+ImgAlertPrefix move.b (a2)+,(a3)+
+ bne.s ImgAlertPrefix
+ subq.l #1,a3
+ call RawDoFmt
+ move.l d0,a0
+ clr.b (a0)
+ sub.l sp,d0
+ moveq #82,d1
+ sub.l d0,d1
+ lsl.w #2,d1
+ move.w d0,-(sp)
+ lea ImgIntuiName(pc),a1
+ call OldOpenLibrary
+ move.l d0,a6
+ moveq #-1,d0
+ moveq #29,d1
+ move.l sp,a0
+ call DisplayAlert
+ move.l 4.w,a6
+ bra.s ImgRebootNow
+
+ImgAllocEnd lea KickMemPtr(a6),a2
+ move.l ImgKickSucc(pc),a0
+ MyFORBID
+ move.l (a2),-(a0) ;KickMemPtr
+ move.l a0,(a2)+
+ move.l (a2),d0 ;KickTagPtr
+ beq.s ImgNoNextReses
+ bset.l #31,d0
+ImgNoNextReses move.l d0,-(a0)
+ move.l ImgResList(pc),(a2)+
+ call SumKickData
+ move.l d0,(a2)
+ call CacheClearU
+ImgRebootNow jump ColdReboot
+
+ImgReadFailMsg dc.b 'Read(offs=%lu, len=%lu) error %ld!',0
+ImgAlertHdr dc.b 16,'ResRAM boot: ',0
+ImgPutChar move.b d0,(a3)+
+ clr.b (a3)
+ImgReturn rts
+
+ImgAllocFailMsg dc.b 'AllocAbs($%08lx,$%08lx) fail!',0
+ImgIntuiName dc.b 'intuition.library',0
+
+ImgResList equ *+(4-(*-BootImage)&3)&3
+ImgKickSucc equ ImgResList+4
+ImgModTab equ ImgKickSucc+4
+
+ ifgt ImgResList-BootImage+36-512
+ fail <Bootblock too big!>
+ endc
+
+;### Code, which will be copied to the resident memory ###
+lerr macro
+ moveq #255-ERROR_\1,d1
+ endm
+
+ResidentPart dc.l 16
+ResSegList dc.l 0
+
+Res move.l 4.w,a6
+ amsg <Entering handler''s code>
+ lea V(pc),v
+
+ move.l ThisTask(a6),a0
+ lea pr_MsgPort(a0),a0
+ move.l a0,(v) ;ProcPort
+
+ bsr GetPacketInt
+
+ lsl.l #2,d4
+ move.l d4,a0
+ move.l (v),dn_Task(a0)
+ moveq #-1,d0
+ moveq #0,d1
+ bsr ReplyInt
+
+ amsg <Startup packet replied>
+
+ lea DosName(pc),a1
+ call OldOpenLibrary
+ put.l d0,DOSbase
+ beq DoOpenDOSAlert ;ZF=1!
+ move.l d0,a6
+ get.l VolumeName,d1
+ moveq #DLT_VOLUME,d2
+ call MakeDosEntry
+ lea HInitFail1(pc),a3
+ bsr AlertD0Mem
+ move.l d0,a0
+ move.l d0,d1
+ lsr.l #2,d0
+ geta VolumeNode,a1
+ move.l d0,(a1)
+ addq #dl_Task,a0
+ move.l (v),(a0)
+ addq #dl_VolumeDate-dl_Task,a0
+ movem.l GDateStamp(v),d0/d2-d3
+ movem.l d0/d2-d3,(a0)
+ move.l -(a1),dl_DiskType-dl_VolumeDate(a0) ;id_DiskType
+ call AddDosEntry
+ bsr AlertD0
+ amsg <Volume node added>
+
+ get.l CmdsNames,a2
+ lea SkipCmdName(pc),a3 ;Okay, we may ignore it
+ geta FirstSegment,a4
+AddSegLoop move.l (a4),d2
+ beq.s OpenUtil
+ amsg <Adding one resident command>
+ addq #8,a4 ;Skip ResCmd checksum
+ move.l a2,d1
+ moveq #CMD_INTERNAL,d3
+ call AddSegment
+ bsr AlertD0
+SkipCmdName tst.b (a2)+
+ bne.s SkipCmdName
+ bra.s AddSegLoop
+
+OpenUtil lea UtilName(pc),a1
+ call exec,OldOpenLibrary
+ addq.l #AO_UtilityLib-AO_DOSLib,d7
+ lea HInitFail2(pc),a3 ;VolumeNode from DosList
+ bsr AlertD0
+ put.l d0,UTILITYbase
+
+MainLoop pea MainLoop(pc)
+ put.l sp,ErrSP
+ amsg <Calling GetPacket>
+ bsr.s GetPacket
+ amsg <Packet received>
+ lea FuncTable(pc),a2
+TableLoop move.w (a2)+,d7
+ move.w (a2)+,d0
+ beq.s NotInTable
+ ext.l d0
+ cmp.l d0,d1
+ bne.s TableLoop
+ amsg <Packet is known>
+NotInTable jmp (a2,d7.w)
+
+;Returns: D0/A1=ExecMsg, A2=DosPacket, D1=dp_Type, D2-D4=dp_Arg[1-3]
+GetLoop move.l (v),a0
+ call WaitPort
+GetPacket move.l (v),a0
+GetPacketInt call GetMsg
+ tst.l d0
+ beq.s GetLoop
+ move.l d0,a0
+ move.l LN_NAME(a0),a0
+ move.l dp_Type(a0),d1
+ movem.l dp_Arg1(a0),d2-d4
+ put.l a0,CurrPacket
+ rts
+
+;---------------
+F_INFO ;(lock,info):bool
+ ifd DEBUGX
+ amsg <INFO(>,0
+ bsr PrintLockName
+ amsg <)>
+ endc
+ move.l d3,d2
+;---------------
+F_DISK_INFO ;(info):bool
+ amsg <DISK_INFO>
+ lsl.l #2,d2
+ move.l d2,a0
+ movem.l MyInfoData(v),d0-d7/a1
+ movem.l d0-d7/a1,(a0)
+;---------------
+F_IS_FILESYSTEM ;():bool
+ amsg <IS_FILESYSTEM>
+ReplyF0 moveq #-1,d0
+ReplyX0 moveq #0,d1
+;---------------
+ReplyPacket mpush d0/d1
+ move.l sp,a1
+ amsg <Packet value: $%08lx, $%08lx>
+ get.l ErrSP,sp
+ReplyInt amsg <Replying packet>
+ get.l CurrPacket,a2
+ move.l (a2),a1 ;dp_Link (ExecMsg)
+ReplyDie move.l d0,dp_Res1(a2)
+ move.l d1,dp_Res2(a2)
+ move.l dp_Port(a2),a0 ;Port for replying
+ move.l (v),dp_Port(a2)
+ jump PutMsg
+;---------------
+F_CURRENT_VOLUME ;(arg1):volume
+ ifd DEBUGX
+ amsg <CURRENT_VOLUME(>,0
+ bsr PrintLockName
+ amsg <)>
+ endc
+ get.l VolumeNode,d0
+ bra.s ReplyX0
+;---------------
+F_SAME_LOCK ;(lock1,lock2):bool
+ ifd DEBUGX
+ amsg <SAME_LOCK(>,0
+ bsr PrintLockName
+ amsg <,>,0
+ move.l d3,a0
+ bsr PrintLockNameX
+ amsg <)>
+ endc
+ lsl.l #2,d2
+ move.l d2,a0
+ move.l fl_Key(a0),d0
+ lsl.l #2,d3
+ move.l d3,a0
+ cmp.l fl_Key(a0),d0
+ beq.s ReplyF0
+Reply00 moveq #0,d0
+ bra.s ReplyX0
+;---------------
+F_NIL
+ ifd DEBUGX
+ move.w d1,-(sp)
+ move.l sp,a1
+ amsg <ERROR_ACTION_NOT_KNOWN: #%d>
+ addq #2,sp
+ endc
+ lerr ACTION_NOT_KNOWN
+Reply0XN not.b d1
+Reply0X moveq #0,d0
+ bra.s ReplyPacket
+;---------------
+F_FINDOUTPUT ;(fh,lock,name):bool
+F_DELETE_OBJECT ;(lock,name):bool
+F_CREATE_DIR ;(lock,name):lock
+F_SET_PROTECT ;(,lock,name,mask):bool
+F_SET_COMMENT ;(,lock,name,comment):bool
+F_RENAME_OBJECT ;(slock,sname,dlock,dname):bool
+F_RENAME_DISK ;(name):bool
+F_SET_DATE ;(,lock,name,stamp):bool
+F_SET_OWNER ;(,,lock,userinf):bool
+F_MAKE_LINK ;(lock,name,dest!#,soft):bool
+ lerr DISK_WRITE_PROTECTED
+ bra.s Reply0XN
+;---------------
+F_FINDUPDATE ;(fh,lock,name):bool
+ moveq #-1,d6
+ bra.s FindUpdateJmp
+;---------------
+F_FINDINPUT ;(fh,lock,name):bool
+ amsg <FINDINPUT>
+ moveq #0,d6
+FindUpdateJmp push d2
+ move.l d3,d2
+ move.l d4,d3
+ bsr.s LocateMain
+ pop a1
+JumpFhFromLock ;D0=arg1 A1=fh, A0=^DiskObject
+ tst.b RFC_ProtBits(a0)
+ bpl.s FindInputFile
+ move.l d0,d2
+ bsr.s FreeLockMain
+ObjWrongType lerr OBJECT_WRONG_TYPE
+ bra.s Reply0XN
+
+FindInputFile add.l a1,a1
+ add.l a1,a1
+ clr.l fh_Interactive(a1)
+ move.l d0,fh_Arg1(a1)
+ bra.s ReplyF0
+;---------------
+F_FREE_LOCK ;(lock):bool
+ amsg <FREE_LOCK>
+F_END ;(arg1):bool
+ ifd DEBUGX
+ amsg <END(>,0
+ bsr PrintLockName
+ amsg <)>
+ endc
+ pea ReplyF0(pc)
+;---------------
+FreeLockMain subqv.l #1,NumLocks
+ lsl.l #2,d2
+ move.l d2,a1
+ jump FreeVec
+;---------------
+F_LOCATE_OBJECT ;(lock,name,mode):lock
+ amsg <LOCATE_OBJECT>
+ lerr OBJECT_IN_USE
+ addq.l #-ACCESS_READ,d4
+ bne.s Reply0XN
+ pea ReplyX0(pc)
+;---------------
+;Inputs: D2=^Lock D3=Name D6=FindUpdate?
+LocateMainNoUpd moveq #0,d6
+LocateMain
+ ifd DEBUGX
+ amsg <LocateMain(>,0
+ bsr PrintLockName
+ move.l d3,a0
+ add.l a0,a0
+ add.l a0,a0
+ moveq #0,d0
+ move.b (a0)+,d0
+ lea -30(sp),sp
+ move.l sp,a1
+ bra.s CopyDbgInto
+CopyDbgLoop move.b (a0)+,(a1)+
+CopyDbgInto dbra d0,CopyDbgLoop
+ clr.b (a1)
+ push sp
+ move.l sp,a1
+ amsg <,%s)>
+ lea 34(sp),sp
+ endc
+
+ lsl.l #2,d3
+ move.l d3,a1
+ moveq #0,d3
+ move.b (a1)+,d3
+
+ move.l a1,a0
+ move.w d3,d0
+ bra.s ColInto
+ColLoop cmp.b #':',(a0)+
+ColInto dbeq d0,ColLoop
+ bne.s ColSkip
+ move.l a0,a1
+ move.w d0,d3
+ColSkip
+ get.l RootPtr,a0
+ lsl.l #2,d2
+ beq.s LockInRoot
+ amsg <Lock in UserDir>
+ move.l d2,a2
+ move.l fl_Key(a2),a0
+LockInRoot tst.b RFC_ProtBits(a0)
+ bpl.s ObjWrongType ;Given lock is to file
+
+NextComponent amsg <NextComponent:>
+ moveq #108,d4 ;Name buffer size
+ geta NameBuffer,a2
+ move.l a2,a4
+ lerr INVALID_COMPONENT_NAME
+ bra.s NameLoopInto
+
+NameLoop move.b (a1)+,d5
+ cmp.b #'/',d5
+ beq.s SlashFound
+ subq.l #1,d4
+ beq Reply0XN
+ move.b d5,(a2)+
+NameLoopInto dbra d3,NameLoop
+ amsg <End of FilePath reached>
+ cmp.l a2,a4
+ beq.s LockInternal
+ amsg <Locking file in CurrDir>
+ bsr.s FindDirItem
+ amsg <FindDirItem returned>
+;---------------
+;Inputs: A0=^Object, Results: D0=Lock (BPTR)
+LockInternal mpush d1/a0-a1
+ ifd DEBUGX
+ amsg <LockInternal(>,0
+ push a2
+ bsr PrintObjName
+ pop a2
+ amsg <)>
+ endc
+ moveq #fl_SIZEOF,d0
+ moveq #MEMF_PUBLIC,d1
+ call AllocVec
+ moveq #ERROR_NO_FREE_STORE,d1
+ tst.l d0
+ beq Reply0X
+ addqv.l #1,NumLocks
+ move.l d0,a0
+ clr.l (a0)+ ;fl_Link
+ move.l 4(sp),(a0)+ ;fl_Key
+ moveq #ACCESS_READ,d1
+ move.l d1,(a0)+ ;fl_Access
+ move.l (v),(a0)+ ;fl_Task
+ get.l VolumeNode,(a0) ;VolumeNode->fl_Volume
+ lsr.l #2,d0
+ mpop d1/a0-a1
+ amsg <LockInternal end>
+ rts
+;---------------
+;End>Empty>Lock CurrDir (A0)
+; Else >Lock FileName in CurrDir
+;/ >Empty>Parent of CurrDir->A0
+; Else >Find FileName in CurrDir->A0 (must be DIR)
+
+SlashFound amsg <SlashFound:>
+ cmp.l a2,a4
+ bne.s NoParent
+ amsg <Getting Parent>
+ bsr.s GetEntryParent
+ beq.s ObjNotFound
+ amsg <GetEntryParent returned>
+ bra.s NextComponent
+
+NoParent amsg <Switching to sub-directory>
+ bsr.s FindDirItem
+ amsg <FindDirItem returned>
+ bra.s LockInRoot
+
+;---------------
+;Inputs: A2=^End of filename A4=^NameBuffer A0=CurrDir D6=FindUpdate?
+;Results: D0/A0=^DirEntry D5=Size A4=LastDir, Destroys: D2/D4
+FindDirItem clr.b (a2)
+ ifd DEBUGX
+ mpush a0-a2
+ push a4
+ move.l sp,a1
+ amsg <FindDirItem(%s,>,0
+ addq #4,sp
+ bsr PrintObjName
+ amsg <)>
+ mpop a0-a2
+ endc
+ moveq #3,d2
+GetLongC lsl.l #8,d5
+ move.b (a0)+,d5
+ dbra d2,GetLongC
+ tst.b (a0)+ ;RFC_ProtBits
+ bpl ObjWrongType
+SkipNameB tst.b (a0)+
+ bne.s SkipNameB
+ move.l d5,d4
+ add.l a0,d4
+
+FindFileLoop cmp.l d4,a0 ;D4=Address after current dir
+ bcs.s StillInDir
+ lerr DISK_WRITE_PROTECTED
+ tst.l d6
+ bne Reply0XN
+ObjNotFound lerr OBJECT_NOT_FOUND
+ bra Reply0XN
+
+StillInDir move.l a0,d0
+ moveq #3,d2
+GetLongA lsl.l #8,d5
+ move.b (a0)+,d5
+ dbra d2,GetLongA
+ addq #RFC_FileName-RFC_ProtBits,a0
+ mpush d0-d1/a0-a1/a6
+ move.l a4,a1
+ call UTILITY,Stricmp
+ move.l d0,d2
+ mpop d0-d1/a0-a1/a6
+SkipNameC tst.b (a0)+
+ bne.s SkipNameC
+ add.l d5,a0
+ tst.l d2
+ bne.s FindFileLoop
+ move.l d0,a0
+ rts
+;---------------
+;Inputs: A0=^Entry, Results: A0=^Parent entry, ZF=EQ if no parent
+GetEntryParent mpush d0-d2/a1-a2
+ get.l RootPtr,a2
+ sub.l a1,a1 ;Parent of Root is 0
+NextEntry amsg <NextEntry:>
+ cmp.l a0,a2
+ beq.s ParentReturn
+ move.l a2,d2
+ moveq #3,d0
+GetLongB lsl.l #8,d1
+ move.b (a2)+,d1
+ dbra d0,GetLongB
+ move.b (a2)+,d0 ;RFC_ProtBits
+ReachEndName tst.b (a2)+
+ bne.s ReachEndName
+ amsg <Name skipped>
+ add.l d1,a2
+ tst.b d0
+ bpl.s NextEntry
+ amsg <Obj is directory>
+ cmp.l a2,a0
+ bcc.s NextEntry
+ amsg <Walking into...>
+ sub.l d1,a2
+ move.l d2,a1 ;Current is parent
+ bra.s NextEntry
+
+ParentReturn amsg <ParentReturn:>
+ move.l a1,a0
+ move.l a0,d0
+ mpop d0-d2/a1-a2
+ rts
+;---------------
+F_FH_FROM_LOCK ;(fh,lock):bool
+ amsg <FH_FROM_LOCK>
+ exg d2,d3
+F_PARENT_FH ;(arg1):lock
+ amsg <PARENT_FH>
+F_PARENT ;(lock):lock
+ amsg <PARENT>
+F_COPY_DIR_FH ;(arg1):lock
+ amsg <COPY_DIR_FH>
+F_COPY_DIR ;(lock):lock
+ ifd DEBUGX
+ amsg <COPY_DIR(>,0
+ bsr PrintLockName
+ amsg <)>
+ endc
+ lsl.l #2,d2
+ move.l d2,a0
+ move.l fl_Key(a0),a0
+ move.w d1,d0
+ lsl.w #2,d0
+ and.w d1,d0
+ beq.s DoCopyDir ;COPY_DIR(|_FH)
+ amsg <Getting parent of the lock> ;PARENT(|_FH)
+ bsr.s GetEntryParent
+ beq Reply00
+ amsg <GetEntryParent returned>
+DoCopyDir bsr LockInternal
+ amsg <PARENT/COPY_DIR locked>
+ cmp.w #ACTION_FH_FROM_LOCK,d1
+ bne ReplyX0
+ move.l d3,a1
+ bra JumpFhFromLock
+;---------------
+F_SEEK ;(arg1,pos,mode):oldpos/-1
+ amsg <SEEK>
+F_READ ;(arg1,&buf,len):len/-1
+ ifd DEBUGX
+ amsg <READ(>,0
+ bsr PrintLockName
+ amsg <)>
+ endc
+ lsl.l #2,d2
+ move.l d2,a1
+ move.l (a1)+,d5 ;fl_Link - Current position
+ move.l (a1),a0 ;fl_Key
+ moveq #3,d2
+GetLongD lsl.l #8,d0
+ move.b (a0)+,d0
+ dbra d2,GetLongD
+ tst.b (a0)+ ;RFC_ProtBits
+ bpl.s ObjIsFile
+ amsg <Wrong type!>
+ lerr OBJECT_WRONG_TYPE
+ReplyFXN not.b d1
+ReplyFX moveq #-1,d0
+ bra ReplyPacket
+;---------------
+F_WRITE ;(arg1,&buf,len):len
+ lerr DISK_WRITE_PROTECTED
+ bra.s ReplyFXN
+;---------------
+ObjIsFile cmp.w #ACTION_SEEK,d1
+ beq.s ActionIsSeek
+ sub.l d5,d0 ;D0=Remaining bytes
+SkipNameA tst.b (a0)+
+ bne.s SkipNameA
+ add.l d5,a0 ;a0=^1st byte for copy
+ cmp.l d0,d4
+ bcc.s DoReadFile
+ amsg <Read in range>
+ move.l d4,d0
+DoReadFile add.l d0,-(a1)
+ move.l d0,d2
+ move.l d3,a1
+ call CopyMem
+ amsg <Copied>
+ move.l d2,d0
+ bra ReplyX0
+
+ActionIsSeek lerr SEEK_ERROR
+ addq.l #1,d4
+ beq.s SeekDone ;OFFSET_BEGINNING=-1
+ subq.l #1,d4
+ beq.s SeekCurrent ;OFFSET_CURRENT=0
+ subq.l #1,d4
+ bne.s ReplyFXN ;OFFSET_END=1
+ amsg <offset_end>
+ add.l d0,d3 ;End-of-File
+SeekDone cmp.l d3,d0
+ bcs.s ReplyFXN
+ move.l -(a1),d0 ;Old position
+ move.l d3,(a1) ;fl_Link
+ bra ReplyX0
+
+SeekCurrent amsg <SeekCurrent:>
+ add.l d5,d3 ;fl_Link
+ bra.s SeekDone
+;---------------
+F_EXAMINE_FH ;(arg1,fib):bool
+ amsg <EXAMINE_FH>
+F_EXAMINE_OBJECT ;(lock,fib):bool
+ amsg <EXAMINE_OBJECT>
+F_EXAMINE_NEXT ;(lock,fib):bool
+ ifd DEBUGX
+ amsg <EXAMINE_NEXT(>,0
+ bsr PrintLockName
+ amsg <)>
+ endc
+ lsl.l #2,d2
+ move.l d2,a0
+ lsl.l #2,d3
+ move.l d3,a1
+ move.l fl_Key(a0),a2
+ pea ReplyF0(pc)
+ cmp.w #ACTION_EXAMINE_NEXT,d1
+ bne.s ExamineMain
+ lerr NO_MORE_ENTRIES
+ move.l (a1),d3 ;fib_DiskKey
+ beq Reply0XN ;ExNext without Examine
+ moveq #3,d2
+GetLongF lsl.l #8,d0
+ move.b (a2)+,d0
+ dbra d2,GetLongF
+ tst.b (a2)+ ;RFC_ProtBits
+ bpl ObjWrongType
+SkipNameD tst.b (a2)+
+ bne.s SkipNameD
+ add.l a2,d0 ;D0=End of this directory
+ cmp.l fl_Key(a0),d3
+ beq.s FirstEntryIn ;A2=Entry to process
+ move.l d3,a2
+ moveq #3,d2
+GetLongG lsl.l #8,d3
+ move.b (a2)+,d3
+ dbra d2,GetLongG
+ addq #RFC_FileName-RFC_ProtBits,a2
+SkipNameE tst.b (a2)+
+ bne.s SkipNameE
+ add.l d3,a2
+FirstEntryIn cmp.l a2,d0
+ beq Reply0XN ;No more entries
+
+;Inputs: A2=^DirEntry A1=^FileInfoBlock
+ExamineMain move.l a2,(a1)+ ;fib_DiskKey
+ moveq #3,d1
+GetLongE lsl.l #8,d0
+ move.b (a2)+,d0
+ dbra d1,GetLongE
+ moveq #ST_FILE,d1
+ moveq #0,d2
+ move.b (a2)+,d2
+ move.l d0,d4
+ subq.l #1,d4
+ asr.l #8,d4
+ asr.l #1,d4
+ addq.l #1,d4
+ bclr.l #7,d2
+ beq.s EntryTypeDone
+ moveq #0,d0 ;Size of directory is zero...
+ moveq #1,d4 ;... but the block size is 1 <- Magic
+ moveq #ST_USERDIR,d1
+ tst.b (a2)
+ bne.s EntryTypeDone
+ moveq #ST_ROOT,d1
+ get.l VolumeName,a2
+EntryTypeDone move.l d1,(a1)+ ;fib_DirEntryType
+ lea fib_Protection-fib_FileName(a1),a3
+ move.l a2,d3
+TestNameLength tst.b (a2)+
+ bne.s TestNameLength
+ sub.l d3,a2
+ exg d3,a2
+ move.b d3,(a1)+
+CopyFileNameB move.b (a2)+,(a1)+ ;RFC_FileName->fib_FileName
+ bne.s CopyFileNameB
+ move.l d2,(a3)+ ;fib_Protection /vvv-MORE MAGIC!!!
+ move.l d1,(a3)+ ;fib_EntryType (=fib_DirEntryType???)
+ move.l d0,(a3)+ ;fib_Size
+ move.l d4,(a3)+ ;fib_NumBlocks
+ geta GDateStamp,a0
+ move.l (a0)+,(a3)+ ;GDateStamp->fib_DateStamp
+ move.l (a0)+,(a3)+
+ move.l (a0),(a3)+
+ clr.b (a3) ;fib_Comment
+ bra ReplyF0
+;---------------
+F_DIE ;():bool
+ amsg <DIE>
+ lerr OBJECT_IN_USE
+ tstv.l NumLocks
+ bne Reply0XN
+ amsg <Replying the DIE packet to my killer>
+ moveq #-1,d0
+ moveq #0,d1
+ bsr ReplyInt
+ amsg <Death packet replied, closing UtilLib>
+ get.l UTILITYbase,a1
+ call exec,CloseLibrary
+HInitFail2 moveq #LDF_VOLUMES!LDF_WRITE,d1
+ call DOS,LockDosList
+ amsg <LockDosList OK>
+ get.l VolumeNode,d2
+ lsl.l #2,d2
+ move.l d2,d1
+ amsg <Calling RemDosEntry>
+ call RemDosEntry
+ amsg <VolumeNode removed>
+ moveq #LDF_VOLUMES!LDF_WRITE,d1
+ call UnLockDosList
+ amsg <DosList freed>
+HInitFail1 amsg <Forbidding>
+ MyFORBID exec
+ amsg <DieResMod regs load>
+ get.l ResListPtr,a2
+ move.l (a2),d1
+ moveq #31,d2
+ move.l ResModules(a6),d0
+ beq.s DieResModEnd
+DieResModChunk amsg <DieResModChunk:>
+ move.l d0,a0
+DieResModLoop amsg <DieResModLoop:>
+ move.l (a0),d0
+ beq.s DieResModEnd
+ amsg <Some entry>
+ bclr.l d2,d0
+ bne.s DieResModChunk
+ amsg <Resident pointer>
+ cmp.l (a0)+,d1
+ bne.s DieResModLoop
+ amsg <Resident is mine>
+ move.l a0,d0
+ bset.l d2,d0
+ move.l d0,-(a0)
+DieResModEnd amsg <DieTag regs load>
+ get.l ResListSucc,a1
+ lea KickTagPtr(a6),a0
+ move.l (a0)+,d0
+ bne.s DieTagInto
+ amsg <Empty KickTagPtr>
+DieTagNotFound amsg <DieTagNotFound:>
+ and.w #$7FFF,KickTagPtr(a6)
+ addq #4,a1
+ lea KickMemPtr(a6),a0
+DieMemLoop amsg <DieMemLoop:>
+ move.l (a0),d0 ;LN_SUCC
+ beq.s DieSumKick
+ cmp.l d0,a1
+ beq.s DieMemFound
+ move.l d0,a0
+ bra.s DieMemLoop
+
+DieTagFound amsg <DieTagFound:>
+ move.l (a1),-(a0)
+ bra.s DieTagNotFound
+
+DieTagLoop amsg <DieTagLoop:>
+ move.l (a0)+,d0
+ beq.s DieTagNotFound
+ bpl.s DieTagLoop
+ bclr.l d2,d0
+DieTagInto amsg <DieTagInto:>
+ cmp.l d0,a2
+ beq.s DieTagFound
+ move.l d0,a0
+ bra.s DieTagLoop
+
+DieMemFound amsg <DieMemFound:>
+ move.l (a1),(a0)
+DieSumKick call SumKickData
+ move.l d0,KickCheckSum(a6)
+ call CacheClearU
+ amsg <KickCheckSum rewritten>
+DiePortLoop amsg <DiePortLoop:>
+ move.l (v),a0
+ call GetMsg
+ tst.l d0
+ beq.s DiePortOK
+ amsg <Some packet got>
+ move.l d0,a1 ;ExecMsg
+ move.l LN_NAME(a1),a2 ;DosPacket
+ moveq #0,d0
+ lerr OBJECT_IN_USE
+ not.b d1
+ amsg <Replying...>
+ bsr ReplyDie
+ amsg <ReplyDie returned>
+ bra.s DiePortLoop
+
+DiePortOK amsg <DiePortOK:>
+ get.l DevNode,a0
+ clr.l dn_Task(a0)
+ clr.l dn_SegList(a0)
+ amsg <dn_(Task|SegList) cleared>
+ call Permit
+ amsg <Permit succeeded>
+ get.l VolumeNode,d1
+ lsl.l #2,d1
+ call DOS,FreeDosEntry
+ amsg <VolumeNode deallocated>
+ move.l a6,a1
+ call exec,CloseLibrary
+ amsg <DosLib closed>
+ get.l ErrSP,sp
+ addq #4,sp
+ amsg <The Final Forbid>
+ MyFORBID
+ get.l RootPtr,a0
+ move.l -(a0),d0 ;ME_LENGTH
+ move.l -(a0),a1 ;ME_ADDR
+ amsg <Calling FreeMem for myself>
+ call FreeMem
+ amsg <Running in non-allocated memory!>
+ moveq #0,d0
+ amsg <Final RTS... shutting down....>
+ rts
+
+;---------------
+func macro ;Function
+ dc.w F_\1-*-4,ACTION_\1
+ endm
+FuncTable
+; ACTION_#? ;Arg1 Arg2 Arg3 Res1
+; --------------------------------------------
+; STARTUP ;? startup devnode bool
+ func FINDINPUT ;fh lock name bool
+ func FINDUPDATE ;fh lock name bool
+ func READ ;arg1 &buf len len
+ func END ;arg1 bool
+ func SEEK ;arg1 pos mode oldpos
+ func EXAMINE_NEXT ;lock fib bool
+ func EXAMINE_OBJECT ;lock fib bool
+ func INFO ;lock info bool
+ func DISK_INFO ;info bool
+ func PARENT ;lock lock
+ func LOCATE_OBJECT ;lock name mode lock
+ func COPY_DIR ;lock lock
+ func FREE_LOCK ;lock bool
+ func CURRENT_VOLUME ;arg1 volume
+ func SAME_LOCK ;lock1 lock2 bool
+ func IS_FILESYSTEM ; bool
+ func FH_FROM_LOCK ;fh lock bool
+ func PARENT_FH ;arg1 lock
+ func EXAMINE_FH ;arg1 fib bool
+ func COPY_DIR_FH ;arg1 lock
+;Write-protected functions
+ func WRITE ;arg1 &buf len len
+ func FINDOUTPUT ;fh lock name bool
+ func DELETE_OBJECT ;lock name bool
+ func CREATE_DIR ;lock name lock
+ func SET_PROTECT ; lock name mask bool
+ func SET_COMMENT ; lock name comment bool
+ func RENAME_OBJECT ;slock sname dlock dname bool
+ func RENAME_DISK ;name bool
+ func SET_DATE ; lock name stamp bool
+ func SET_OWNER ; lock userinf bool
+ func MAKE_LINK ;lock name dest!# soft bool
+
+ func DIE ; bool
+ func NIL ;End-of-table mark
+
+;A0=Module with the checksum error
+SumError mpush a0/a6
+ lea ResIntuiName(pc),a1
+ call exec,OldOpenLibrary
+ move.l #AT_DeadEnd!AG_OpenLib!AO_Intuition,d7
+ bsr AlertD0
+ move.l d0,a6
+ move.l (sp),a0
+ link a2,#-$100
+ lea -252(sp),sp
+ move.l sp,a1
+SumErrLoop1 move.b (a0)+,(a1)+
+ bne.s SumErrLoop1
+ moveq #53,d0
+ add.l sp,d0
+ sub.l a1,d0
+ lsl.b #2,d0
+ clr.b (a1)
+ moveq #(SumErrMsgEnd-SumErrMsg)>>2-1,d1
+ lea SumErrMsgEnd(pc),a0
+SumErrLoop2 push -(a0)
+ dbra d1,SumErrLoop2
+ move.b d0,SumErrCenter-SumErrMsg(sp)
+ move.l sp,a0
+ moveq #0,d0 ;Recovery
+ moveq #61,d1
+ call DisplayAlert
+ tst.l d0
+ beq.s UserReboot
+ unlk a2
+ mpop a0/a6
+ rts
+
+UserReboot move.l 4.w,a6
+ not.l ChkBase(a6)
+ call CacheClearU
+ jump ColdReboot
+
+ResInit mpush d6/d7/a2/a3/a6
+ ifd DEBUGX
+ call RawIOInit
+ endc
+ amsg <ResidentInit started>
+
+ move.l ResListSucc+V(pc),a0
+ move.l (a0)+,d0 ;ResListSucc
+ add.l (a0),d0 ;KickMemSucc
+ lea ResidentPart-2-RT_SIZE(pc),a1
+ move.w #(RT_SIZE+2+ResidentCode)>>2-1,d1
+ResSumLoop sub.l (a1)+,d0
+ dbra d1,ResSumLoop
+ move.l RootPtr+V(pc),a0
+ move.l -(a0),d1 ;ME_LENGTH
+ add.l -(a0),d1 ;ME_ADDR
+ lea AnySum+V(pc),a1
+ clr.l VolumeNode-AnySum(a1)
+ clr.l NumLocks-AnySum(a1)
+ResSumLoopE sub.l (a1)+,d0
+ cmp.l a1,d1
+ bne.s ResSumLoopE
+ tst.l d0
+ beq.s ResSumOkay
+ lea ResName(pc),a0
+ bsr SumError
+
+ResSumOkay amsg <ResRAM checksumming passed, checksumming ResCmds...>
+ lea FirstSegment+V(pc),a2
+ move.l CmdsNames+V(pc),a0
+CmdSumsLoop move.l (a2)+,d0
+ beq.s CmdSumsDone
+ bsr.s SumModInit
+SkipResCmdName tst.b (a0)+
+ bne.s SkipResCmdName
+ bra.s CmdSumsLoop
+
+SumModInit
+ ifd DEBUGX
+ push a0
+ move.l sp,a1
+ amsg <CheckSumming module "%s">
+ addq #4,sp
+ endc
+ moveq #0,d7
+ tst.l (a2)
+ beq.s SumIncRet
+ amsg <This ResModule HAS checksum>
+SumOneModule lsl.l #2,d0
+ move.l d0,a1
+ move.l (a1)+,d0
+ move.l -8(a1),d1
+ lsr.l #2,d1
+ subq.l #3,d1
+ bmi.s SumOneHunkEnd
+ move.w d1,d6
+ swap d1
+SumOneHunkLoop add.l (a1)+,d7
+ dbra d6,SumOneHunkLoop
+ dbra d1,SumOneHunkLoop
+SumOneHunkEnd tst.l d0
+ bne.s SumOneModule
+ tst.l d7
+ seq d1
+ sub.b d1,d7
+SumIncRet cmp.l (a2)+,d7
+ bne SumError
+ amsg <CheckSum okay!>
+ rts
+
+CmdSumsDone amsg <Checksumming libraries and kickmods...>
+ move.l ResListPtr+V(pc),a3
+ addq #4,a3 ;Skip ^MyResident struct
+ResSumsLoop move.l (a3)+,d0
+ ble.s ResSumsDone
+ move.l d0,a0
+ move.l RT_NAME(a0),a0
+ move.l (a2)+,d0
+ bsr.s SumModInit
+ bra.s ResSumsLoop
+
+ResSumsDone amsg <All checksums done!>
+ move.l DosHName+V(pc),a2
+ moveq #0,d0
+ move.b (a2),d0
+ addq.l #2,d0
+ moveq #MEMF_PUBLIC,d1
+ call AllocVec
+ lea ResInitFail(pc),a3
+ bsr AlertD0Mem
+ amsg <DosHandler name allocated>
+ move.l d0,a0
+ move.l d0,d6
+ moveq #0,d0
+ move.b (a2),d0
+DosNCopy move.b (a2)+,(a0)+
+ clr.b (a0)
+ dbra d0,DosNCopy
+ amsg <DosHandler name copied>
+
+ moveq #(DeviceNode_SIZEOF+FileSysStartupMsg_SIZEOF+de_Baud+1+DeviceNameEnd-DeviceName)>>1,d0
+ lsl.l #1,d0
+ move.l #MEMF_PUBLIC!MEMF_CLEAR,d1
+ call AllocVec
+ bsr AlertD0
+ amsg <DeviceNode allocated>
+ move.l d0,a0
+ exg d0,d6
+ lea dn_StackSize+2(a0),a0
+ move.w #StdStackSize,(a0)+ ;dn_StackSize
+ addq.l #8,(a0)
+ addq.l #StdTaskPri-8,(a0)+ ;dn_Priority
+ lea DeviceNode_SIZEOF-dn_Startup(a0),a1
+ move.l a1,d1
+ lsr.l #2,d1
+ move.l d1,(a0)+ ;dn_Startup
+ lea ResSegList(pc),a1
+ move.l d6,DevNode+V-ResSegList(a1)
+ move.l a1,d1
+ lsr.l #2,d1
+ move.l d1,(a0)+ ;dn_SegList
+ not.l (a0)+ ;dn_GlobalVec
+ lsr.l #2,d0
+ move.l d0,(a0) ;dn_Name
+ addq #DeviceNode_SIZEOF-dn_Name+fssm_Device-FileSysStartupMsg,a0
+ lea FileSysStartupMsg_SIZEOF-fssm_Device+de_Baud-DosEnvec(a0),a1
+ move.l a1,d0
+ lsr.l #2,d0
+ move.l d0,(a0)+ ;fssm_Unit
+ lea FileSysStartupMsg_SIZEOF-fssm_Environ+DosEnvec(a0),a1
+ move.l a1,d0
+ lsr.l #2,d0
+ move.l d0,(a0) ;fssm_Environ
+ moveq #DE_DOSTYPE,d0
+ move.l d0,(a1)+ ;de_TableSize
+ lsl.l #3,d0 ;DE_DOSTYPE(=16)<<3=128
+ move.l d0,(a1) ;de_SizeBlock
+ addq #de_Surfaces-de_SizeBlock,a1
+ addq.l #1,(a1)+ ;de_Surfaces
+ addq.l #1,(a1)+ ;de_SectorPerBlock
+ addq.l #1,(a1) ;de_BlocksPerTrack
+ lea de_HighCyl-de_BlocksPerTrack(a1),a0
+ move.l MyInfoData+id_NumBlocks+V(pc),(a0)
+ subq.l #1,(a0)+ ;de_HighCyl
+ addq.l #5,(a0)+ ;de_NumBuffers
+ addq.l #MEMF_PUBLIC,(a0)+ ;de_BufMemType
+ move.l #1<<31-1,(a0)+ ;de_MaxTransfer
+ not.l (a0)+ ;de_Mask
+ move.l VarBootPri+V(pc),(a0)+ ;de_BootPri
+ move.l #'RES'<<8,(a0)+ ;de_DosType
+MyDiskTypeAddr equ *-4
+ lea DeviceName(pc),a1
+CopyDevName move.b (a1)+,(a0)+
+ bne.s CopyDevName
+ amsg <DeviceNode filled>
+
+ lea ExpName(pc),a1
+ call OldOpenLibrary
+ move.l #AG_OpenLib!AO_ExpansionLib,d7
+ bsr.s AlertD0
+ move.l d0,a6
+ amsg <Expansion opened>
+
+ call AllocConfigDev
+ lea ResInitCFail(pc),a3
+ bsr.s AlertD0Mem
+ amsg <AllocConfigDev succeeded>
+ move.l d0,a1
+ lea ResName(pc),a0
+ move.l a0,LN_NAME(a1)
+ move.b #ERT_NEWBOARD!ERTF_DIAGVALID,cd_Rom+er_Type(a1)
+ lea MyDiagArea(pc),a0
+ move.l a0,cd_Rom+er_Reserved0c(a1) ;er_Reserved0[c-f]
+ amsg <ConfigDev filled>
+
+ move.l d6,a0
+ move.b VarBootPri+3+V(pc),d0
+ moveq #ADNF_STARTPROC,d1
+ call AddBootNode
+ bsr.s AlertD0
+ amsg <AddBootNode succeeded>
+ResInitCFail move.l a6,a1
+ call exec,CloseLibrary
+ResInitFail amsg <Initialization finished>
+ mpop d6/d7/a2/a3/a6
+Return rts
+
+;### Debug part of the detach zone ###
+
+ ifd DEBUGX
+DPrintf mpush d0-d1/a0-a3/a6
+ move.l 28(sp),a0
+ addq #2,a0
+ move.l 4.w,a6
+ lea _LVORawPutChar(a6),a2
+ MyFORBID
+ call RawDoFmt
+ call Permit
+ ifd WaitDbg
+Wait1 btst.b #2,$dff016
+ bne.s Wait1
+Wait2 btst.b #2,$dff016
+ beq.s Wait2
+ endc
+ mpop d0-d1/a0-a3/a6
+ rts
+
+;Inputs: D2=Lock
+PrintLockName tst.l d2
+ bne.s LockNonNull
+ amsg <NULL>,0
+ rts
+
+LockNonNull push d2
+ move.l sp,a1
+ amsg <$%08lx/>,0
+ addq #4,sp
+ move.l d2,a0
+;Inputs: A0=Lock
+PrintLockNameX add.l a0,a0
+ add.l a0,a0
+ move.l fl_Key(a0),a0
+
+;Inputs: A0=^Object, Destroys: A0-A2 !!! VERY BIG STACK !!!
+PrintObjName lea -30(sp),sp
+ move.l sp,a2
+ lea RFC_FileName(a0),a1
+ move.b #':',(a2)+
+CopyName move.b (a1)+,(a2)+
+ bne.s CopyName
+ lea DPrintf(pc),a1
+ move.w #$4E75,(a1)
+ bsr GetEntryParent
+ beq.s ReachedRoot
+ vcmp.l RootPtr,a0
+ beq.s ReachedRoot
+ move.b #'/',(sp)
+ bsr.s PrintObjName
+ReachedRoot lea DPrintf(pc),a1
+ move.w #$48E7,(a1)
+ push sp
+ move.l sp,a1
+ amsg <%s>,0
+ lea 34(sp),sp
+ rts
+ endc
+
+; ### MyDiagArea - ptr to it is in ConfigDev structure ###
+MyDiagArea dc.b DAC_BOOTTIME,0 ;da_Config,da_Flags
+ dc.w DiagAreaEnd-MyDiagArea ;da_Size
+ dc.w 0,DiagBootUp-MyDiagArea ;da_DiagPoint,da_BootPoint
+ dc.w ResName-MyDiagArea ;da_Name
+ dc.w 0,0 ;da_Reserved01,da_Reserved02
+
+AlertD0Mem moveq #AG_NoMemory>>16,d7
+ swap d7
+AlertD0 tst.l d0
+ bne.s Return
+ move.l a6,(sp)
+ call exec,Alert
+ pop a6
+ jmp (a3)
+
+DiagBootUp amsg <DiagBootUp started>
+ lea DosName(pc),a1
+ call exec,FindResident
+DoOpenDOSAlert move.l #AT_DeadEnd!AG_OpenLib!AO_DOSLib,d7
+ bsr.s AlertD0
+ move.l d0,a0
+ move.l RT_INIT(a0),a0
+ amsg <DiagBootUp - Initializing DOS>
+ jmp (a0)
+DosName dc.b 'dos.library',0
+
+ResName dc.b 'ResRAM-Handler'
+ ifne (*-DosName)&1
+ fail <Odd length!>
+ endc
+ResNumOne dc.b 0,0,0
+ even
+DiagAreaEnd
+ dc.b '$VER: '
+ResID dc.b 'ResRAM-Handler 1.0 (5.2.95)',0
+ExpName dc.b 'expansion.library',0
+UtilName dc.b 'utility.library',0
+DeviceName dc.b DeviceNameEnd-DeviceName-2,'none.device',0
+DeviceNameEnd
+ ifne (DeviceNode_SIZEOF+FileSysStartupMsg_SIZEOF+de_Baud+1+DeviceNameEnd-DeviceName)&1
+ fail <Odd length!>
+ endc
+ResIntuiName dc.b 'intuition.library',0
+ even
+SumErrMsg dc.b 0,96,28,'!! SYSTEM IS NOW UNRELIABLE -'
+ dc.b ' COLD REBOOT RECOMMENDED !!',0,-1
+ dc.b 0,32,48,'LMB - Continue',0,-1
+ dc.b 480>>8,480&$FF,48,'RMB - ColdReboot',0,-1,0
+SumErrCenter dc.b 0,16,'ResRAM #'
+ ifne (*-SumErrMsg)&1
+ fail <Odd length!>
+ endc
+ResNumTwo dc.b 0,0,': Invalid checksum on '
+SumErrMsgEnd
+ ifne (SumErrMsgEnd-SumErrMsg)&3
+ fail <SumErr not long aligned!!>
+ endc
+V equ ResidentPart+(*-ResidentPart+3)&~3
+ResidentCode equ V-ResidentPart
+SYSCNTold equ SYSCNT
+SYSCNT set 0
+ dv.l ProcPort
+ dv.l UTILITYbase
+ dv.l CurrPacket
+ dv.l ErrSP
+ dv.l DOSbase
+ dv.l DevNode
+
+ dbuf NameBuffer,108
+ dv.l VarBootPri
+ dv.l AnySum ;Checksum of the main part
+ dv.l CmdsNames ;^1st name of Resident Command
+ dv.l VolumeName ;APTR to ASCIIZ of volume name
+ dv.l DosHName ;APTR to BSTR of dos handler name
+ dbuf MyInfoData,id_SIZEOF
+VolumeNode equ MyInfoData+id_VolumeNode ;BPTR
+NumLocks equ MyInfoData+id_InUse
+ dv.l RootPtr ;APTR to root entry
+ dv.l ResListSucc ;ResidentList successor
+ dv.l ResListPtr ;^^MyResidentStruct
+ dbuf GDateStamp,ds_SIZEOF ;Global DateStamp
+ dbuf FirstSegment,0 ;Label of seg of first ResCmd
+
+ResidentVars equ SYSCNT
+SYSCNT set SYSCNTold
+
+VerbOpt macro ;<name>,<letter>,<description>
+ ifc '\1','All'
+VerbF_\1 equ 255
+ else
+ ifc '\1','None'
+VerbF_\1 equ 254
+ else
+VerbB_\1 equ _VerbOpt
+VerbF_\1 equ 1<<_VerbOpt
+_VerbOpt set _VerbOpt+1
+ endc
+ endc
+ dt.c <',VerbF_\1,'\2>
+ dc.b ' \2: \3',10
+ endm
+_VerbOpt set 0
+
+ tags
+ template <FILES/A,DEVICE,NAME,PRI=BOOTPRI/N/K,EMPTYDIRS/S,GENABS/K,GENDISK/K,NODISKREQ/S,NORUN/S,REBOOT/S,VERBOSE/K>
+ dv.l Arg_Files
+ dv.l Arg_Device
+ dv.l Arg_Name
+ dv.l Arg_BootPri
+ dv.l Arg_EmptyDirs
+ dv.l Arg_GenAbs
+ dv.l Arg_GenDisk
+ dv.l Arg_NoDiskReq
+ dv.l Arg_NoRun
+ dv.l Arg_Reboot
+ dv.l Arg_Verbose
+ extrahelp
+ dc.b 'Resident RAM-Disk loader v1.0 --- (c) 1995 Short Software',10,10
+ dc.b 'FILES - Directory/pattern for files to load',10
+ dc.b ' (Wildcards in directory names aren''t supported)',10
+ dc.b 'DEVICE - DOS device name of RES-Disk (def. RES:)',10
+ dc.b 'NAME - Volume name of RES-Disk (def. ResRAM)',10
+ dc.b 'BOOTPRI - Boot priority (def. 15)',10
+ dc.b 'EMPTYDIRS - Don''t discard empty directories',10
+ dc.b 'GENABS - Filename where an AbsModule should be written',10
+ dc.b 'GENDISK - DOS device name for a boot image (e.g. DF0:)',10
+ dc.b 'NODISKREQ - Suppress ''Insert disk...'' requester (only for GENDISK)',10
+ dc.b 'NORUN - Don''t mount RES-Disk',10
+ dc.b 'REBOOT - Reboot machine when the load succeeds',10
+ dc.b ' (Doesn''t apply to AbsModules or boot images)',10
+ dc.b 'VERBOSE - Verbosity switches (seq. of following letters):',10
+ dt.c VerbParseTab,<>
+ VerbOpt All,A,<Turn all switches on>
+ VerbOpt None,N,<Turn all switches off>
+ VerbOpt Dirs,D,<Scanned directories>
+ VerbOpt Files,F,<Scanned file names & types>
+ VerbOpt LoadSeg,I,<Scan phase LoadSeg info>
+ VerbOpt LoadFiles,L,<Files being loaded>
+ VerbOpt Mem,M,<Memory being allocated>
+ VerbOpt SizeMod,G,<Sizes of modules being generated>
+ endhelp
+ dt <>
+ defvar <ResRAM>
+ exitrout Cleanup
+ finish
+ end