From a5fbbc83869d51da9c4f3154616bc2f1e8b701c6 Mon Sep 17 00:00:00 2001 From: short <> Date: Wed, 8 Oct 2003 06:51:38 +0000 Subject: [PATCH] +ResRAM --- configure.ac | 1 + project/Makefile.am | 3 +- project/ResRAM/Index.html.pl | 39 + project/ResRAM/ListItem.pm | 50 + project/ResRAM/Makefile.am | 23 + project/ResRAM/ResRAM.README | 11 + project/ResRAM/ResRAM.asm | 3038 ++++++++++++++++++++++++++++++++++++++++++ project/ResRAM/ResRAM.lha | Bin 0 -> 32819 bytes 8 files changed, 3164 insertions(+), 1 deletion(-) create mode 100755 project/ResRAM/Index.html.pl create mode 100755 project/ResRAM/ListItem.pm create mode 100644 project/ResRAM/Makefile.am create mode 100644 project/ResRAM/ResRAM.README create mode 100644 project/ResRAM/ResRAM.asm create mode 100644 project/ResRAM/ResRAM.lha diff --git a/configure.ac b/configure.ac index b7dbd11..01a1577 100644 --- a/configure.ac +++ b/configure.ac @@ -86,6 +86,7 @@ Makefile ./project/kewensis/Makefile ./project/QueryDev/Makefile ./project/SClock/Makefile +./project/ResRAM/Makefile ]) echo done. diff --git a/project/Makefile.am b/project/Makefile.am index 80a52be..982d2a2 100644 --- a/project/Makefile.am +++ b/project/Makefile.am @@ -69,7 +69,8 @@ SUBDIRS= \ wayback \ kewensis \ QueryDev \ - SClock + SClock \ + ResRAM EXTRA_DIST+= \ Index.html.pl \ diff --git a/project/ResRAM/Index.html.pl b/project/ResRAM/Index.html.pl new file mode 100755 index 0000000..5280008 --- /dev/null +++ b/project/ResRAM/Index.html.pl @@ -0,0 +1,39 @@ +#! /usr/bin/perl +# +# $Id$ +# Main page of 'My::Project::ResRAM' +# Copyright (C) 2003 Jan Kratochvil +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; exactly version 2 of June 1991 is required +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +package project::ResRAM::Index; +require 5.6.0; # at least 'use warnings;' but we need some 5.6.0+ modules anyway +our $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; }; +our $CVS_ID=q$Id$; +use strict; +use warnings; + +BEGIN{ open F,"Makefile"; our $top_dir=pop @{[split /\s/,(grep /^top_srcdir/,)[0]]}; eval "use lib '$top_dir'"; close F; } +use My::Web; +Wuse 'My::Project'; +Wuse 'project::ResRAM::ListItem'; + + +My::Project->init_project( + "__PACKAGE__"=>__PACKAGE__, + "ListItem"=>\@project::ResRAM::ListItem::ListItem, + ); + +My::Web->footer(); diff --git a/project/ResRAM/ListItem.pm b/project/ResRAM/ListItem.pm new file mode 100755 index 0000000..6893104 --- /dev/null +++ b/project/ResRAM/ListItem.pm @@ -0,0 +1,50 @@ +#! /usr/bin/perl +# +# $Id$ +# Definition of 'My::Project::ResRAM' for list.cgi.pl +# Copyright (C) 2003 Jan Kratochvil +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; exactly version 2 of June 1991 is required +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +package project::ResRAM::ListItem; +require 5.6.0; # at least 'use warnings;' but we need some 5.6.0+ modules anyway +our $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; }; +our $CVS_ID=q$Id$; +use strict; +use warnings; + +use My::Web; + + +our @ListItem=( + "name"=>"ResRAM", + "platform"=>"amiga", + "priority"=>5, + "download"=>"ResRAM.lha", + "link-source file"=>"ResRAM.asm", + "link-aminet README"=>"ResRAM.README", + "summary"=>"Reset-persisent bootable RAM-Disk", + "license"=>"PD", + "maintenance"=>"ready", + "language"=>"680x0 asm", + "description"=><<"HERE", +

ResRAM is generally used for the RAM disks which are not required to be +written to - for example RAD disks used for fast booting when no harddisk is +available. When ResRAM is run, it scans given files which are loaded to the +memory and a reset-surviving resident module is installed.

+HERE + ); + +1; diff --git a/project/ResRAM/Makefile.am b/project/ResRAM/Makefile.am new file mode 100644 index 0000000..587004a --- /dev/null +++ b/project/ResRAM/Makefile.am @@ -0,0 +1,23 @@ +# $Id$ +# automake source for the Makefile of project/ResRAM/ subdir +# Copyright (C) 2003 Jan Kratochvil +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; exactly version 2 of June 1991 is required +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +include $(top_srcdir)/Makefile-head.am + +EXTRA_DIST+= \ + ListItem.pm \ + Index.html.pl diff --git a/project/ResRAM/ResRAM.README b/project/ResRAM/ResRAM.README new file mode 100644 index 0000000..8ee2fe8 --- /dev/null +++ b/project/ResRAM/ResRAM.README @@ -0,0 +1,11 @@ +Short: Reset surviving RAM FileSys (V37+&ss.lib) + +Description: + ResRAM is generally used for the RAM disks which are not required to be +written to - for example RAD disks used for fast booting when no harddisk is +available. When ResRAM is run, it scans given files which are loaded to the +memory and a reset-surviving resident module is installed. + +Requirements: + ResRAM executable requires Kickstart version 37 (2.0) or higher and the +ss.library V5.0 or higher (from package SSLib*.lha). diff --git a/project/ResRAM/ResRAM.asm b/project/ResRAM/ResRAM.asm new file mode 100644 index 0000000..254cdb4 --- /dev/null +++ b/project/ResRAM/ResRAM.asm @@ -0,0 +1,3038 @@ +;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 ,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 ,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, + 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, + 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, + 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 ,a0 +ErrorA1SS move.l sp,a1 +ErrorSS jump ss,ExitError + +ErrorScan dtl ,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 ,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 ,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 ,a3 + dt PublicMsg, +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 ,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_#?[,] + 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 ,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
,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 ,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 ,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 ,a0 + dt.lc + dt.l + move.l sp,a1 + dtl ,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 ,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 ,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, + dt PureCmdMsg, ;RCT_Cmd + dt MinExtTable, ;RCT_Lib + dt ;RCT_Lib + dt.c ;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, + 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 + 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 + 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 + + 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 + + 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 + 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 + bsr.s GetPacket + amsg + 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 +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 ,0 + bsr PrintLockName + amsg <)> + endc + move.l d3,d2 +;--------------- +F_DISK_INFO ;(info):bool + amsg + 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 +ReplyF0 moveq #-1,d0 +ReplyX0 moveq #0,d1 +;--------------- +ReplyPacket mpush d0/d1 + move.l sp,a1 + amsg + get.l ErrSP,sp +ReplyInt amsg + 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 ,0 + bsr PrintLockName + amsg <)> + endc + get.l VolumeNode,d0 + bra.s ReplyX0 +;--------------- +F_SAME_LOCK ;(lock1,lock2):bool + ifd DEBUGX + amsg ,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 + 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 + 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 +F_END ;(arg1):bool + ifd DEBUGX + amsg ,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 + 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 ,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 + 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 + 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 + cmp.l a2,a4 + beq.s LockInternal + amsg + bsr.s FindDirItem + amsg +;--------------- +;Inputs: A0=^Object, Results: D0=Lock (BPTR) +LockInternal mpush d1/a0-a1 + ifd DEBUGX + amsg ,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 + 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 + cmp.l a2,a4 + bne.s NoParent + amsg + bsr.s GetEntryParent + beq.s ObjNotFound + amsg + bra.s NextComponent + +NoParent amsg + bsr.s FindDirItem + amsg + 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 ,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 + 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 + add.l d1,a2 + tst.b d0 + bpl.s NextEntry + amsg + cmp.l a2,a0 + bcc.s NextEntry + amsg + sub.l d1,a2 + move.l d2,a1 ;Current is parent + bra.s NextEntry + +ParentReturn amsg + move.l a1,a0 + move.l a0,d0 + mpop d0-d2/a1-a2 + rts +;--------------- +F_FH_FROM_LOCK ;(fh,lock):bool + amsg + exg d2,d3 +F_PARENT_FH ;(arg1):lock + amsg +F_PARENT ;(lock):lock + amsg +F_COPY_DIR_FH ;(arg1):lock + amsg +F_COPY_DIR ;(lock):lock + ifd DEBUGX + amsg ,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 ;PARENT(|_FH) + bsr.s GetEntryParent + beq Reply00 + amsg +DoCopyDir bsr LockInternal + amsg + cmp.w #ACTION_FH_FROM_LOCK,d1 + bne ReplyX0 + move.l d3,a1 + bra JumpFhFromLock +;--------------- +F_SEEK ;(arg1,pos,mode):oldpos/-1 + amsg +F_READ ;(arg1,&buf,len):len/-1 + ifd DEBUGX + amsg ,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 + 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 + move.l d4,d0 +DoReadFile add.l d0,-(a1) + move.l d0,d2 + move.l d3,a1 + call CopyMem + amsg + 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 + 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 + add.l d5,d3 ;fl_Link + bra.s SeekDone +;--------------- +F_EXAMINE_FH ;(arg1,fib):bool + amsg +F_EXAMINE_OBJECT ;(lock,fib):bool + amsg +F_EXAMINE_NEXT ;(lock,fib):bool + ifd DEBUGX + amsg ,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 + lerr OBJECT_IN_USE + tstv.l NumLocks + bne Reply0XN + amsg + moveq #-1,d0 + moveq #0,d1 + bsr ReplyInt + amsg + get.l UTILITYbase,a1 + call exec,CloseLibrary +HInitFail2 moveq #LDF_VOLUMES!LDF_WRITE,d1 + call DOS,LockDosList + amsg + get.l VolumeNode,d2 + lsl.l #2,d2 + move.l d2,d1 + amsg + call RemDosEntry + amsg + moveq #LDF_VOLUMES!LDF_WRITE,d1 + call UnLockDosList + amsg +HInitFail1 amsg + MyFORBID exec + amsg + get.l ResListPtr,a2 + move.l (a2),d1 + moveq #31,d2 + move.l ResModules(a6),d0 + beq.s DieResModEnd +DieResModChunk amsg + move.l d0,a0 +DieResModLoop amsg + move.l (a0),d0 + beq.s DieResModEnd + amsg + bclr.l d2,d0 + bne.s DieResModChunk + amsg + cmp.l (a0)+,d1 + bne.s DieResModLoop + amsg + move.l a0,d0 + bset.l d2,d0 + move.l d0,-(a0) +DieResModEnd amsg + get.l ResListSucc,a1 + lea KickTagPtr(a6),a0 + move.l (a0)+,d0 + bne.s DieTagInto + amsg +DieTagNotFound amsg + and.w #$7FFF,KickTagPtr(a6) + addq #4,a1 + lea KickMemPtr(a6),a0 +DieMemLoop amsg + 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 + move.l (a1),-(a0) + bra.s DieTagNotFound + +DieTagLoop amsg + move.l (a0)+,d0 + beq.s DieTagNotFound + bpl.s DieTagLoop + bclr.l d2,d0 +DieTagInto amsg + cmp.l d0,a2 + beq.s DieTagFound + move.l d0,a0 + bra.s DieTagLoop + +DieMemFound amsg + move.l (a1),(a0) +DieSumKick call SumKickData + move.l d0,KickCheckSum(a6) + call CacheClearU + amsg +DiePortLoop amsg + move.l (v),a0 + call GetMsg + tst.l d0 + beq.s DiePortOK + amsg + move.l d0,a1 ;ExecMsg + move.l LN_NAME(a1),a2 ;DosPacket + moveq #0,d0 + lerr OBJECT_IN_USE + not.b d1 + amsg + bsr ReplyDie + amsg + bra.s DiePortLoop + +DiePortOK amsg + get.l DevNode,a0 + clr.l dn_Task(a0) + clr.l dn_SegList(a0) + amsg + call Permit + amsg + get.l VolumeNode,d1 + lsl.l #2,d1 + call DOS,FreeDosEntry + amsg + move.l a6,a1 + call exec,CloseLibrary + amsg + get.l ErrSP,sp + addq #4,sp + amsg + MyFORBID + get.l RootPtr,a0 + move.l -(a0),d0 ;ME_LENGTH + move.l -(a0),a1 ;ME_ADDR + amsg + call FreeMem + amsg + moveq #0,d0 + amsg + 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 + + 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 + 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 + addq #4,sp + endc + moveq #0,d7 + tst.l (a2) + beq.s SumIncRet + amsg +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 + rts + +CmdSumsDone amsg + 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 + 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 + 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 + + 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 + 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 + + lea ExpName(pc),a1 + call OldOpenLibrary + move.l #AG_OpenLib!AO_ExpansionLib,d7 + bsr.s AlertD0 + move.l d0,a6 + amsg + + call AllocConfigDev + lea ResInitCFail(pc),a3 + bsr.s AlertD0Mem + amsg + 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 + + move.l d6,a0 + move.b VarBootPri+3+V(pc),d0 + moveq #ADNF_STARTPROC,d1 + call AddBootNode + bsr.s AlertD0 + amsg +ResInitCFail move.l a6,a1 + call exec,CloseLibrary +ResInitFail amsg + 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 ,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 + 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 + jmp (a0) +DosName dc.b 'dos.library',0 + +ResName dc.b 'ResRAM-Handler' + ifne (*-DosName)&1 + fail + 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 + 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 + endc +ResNumTwo dc.b 0,0,': Invalid checksum on ' +SumErrMsgEnd + ifne (SumErrMsgEnd-SumErrMsg)&3 + fail + 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 ;,, + 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 + 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, + VerbOpt None,N, + VerbOpt Dirs,D, + VerbOpt Files,F, + VerbOpt LoadSeg,I, + VerbOpt LoadFiles,L, + VerbOpt Mem,M, + VerbOpt SizeMod,G, + endhelp + dt <> + defvar + exitrout Cleanup + finish + end diff --git a/project/ResRAM/ResRAM.lha b/project/ResRAM/ResRAM.lha new file mode 100644 index 0000000000000000000000000000000000000000..e8ad91729158e5386ba86ccfec79bdb37926b6a2 GIT binary patch literal 32819 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 Wv&_wgTDNnfvxAGO-(L@Jb3gz}Cj