mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-28 13:52:37 +00:00
654 lines
20 KiB
Plaintext
654 lines
20 KiB
Plaintext
;
|
||
; File: ScrapMgr.a
|
||
;
|
||
; Contains: Scrap Manager for Macintosh Operating System
|
||
;
|
||
; Copyright: © 1983-1993 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM5> 5/12/93 PN Roll in Dean's changes. Cleaned up and shorten PutScrap patch
|
||
; roll in
|
||
; <SM4> 12/21/92 PN Radar#1048596 Fix the return address on the stack of DoPut
|
||
; routine depending on _PtrAndHandl call
|
||
; <SM3> 10/22/92 CSS Change some branch short instructions to word branches.
|
||
; <SM2> 4/9/92 PN Roll in FixputScrap and F2PutScrap from ScrapMgrPatches.s
|
||
; <2> 2/10/92 JSM Moved this file to ScrapMgr folder, keeping all the old
|
||
; revisions; cleaned up header.
|
||
; <1.1> 11/10/88 CCH Fixed Header.
|
||
; <1.0> 11/9/88 CCH Adding to EASE.
|
||
; <•1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
||
; <1.0> 2/11/88 BBM Adding file for the first time into EASE…
|
||
; <C716> 1/28/87 bbm Fixed obscure error in unloadseg (now exits correctly.)
|
||
; <C206> 10/9/86 bbm Modified to mpw aincludes.
|
||
; 2/19/86 BBM Made some modifications to work under MPW
|
||
; 6/15/85 SC ZeroScrap will never let scrap count go negative.
|
||
; 6/15/85 SC InfoScrap will zero scrap if uninited too.
|
||
; 4/27/85 SC GetScrap and PutScrap will never return noScrap error. If the
|
||
; scrap hasn't been inited, it will call zero scrap for caller.
|
||
; New routine FailSafe used for this.
|
||
; 4/27/85 SC Set Type, Creator and system file bit in IOUsrWds for finder.
|
||
; 4/27/85 SC Scrap File moved to bootdrive, not default.
|
||
; 1/25/85 LAK Added patch in LoadScrap (pass D0=bytecount to SetUpRW2).
|
||
; 1/23/85 LAK Adapted for new equate files.
|
||
; 9/7/83 SC Added scrapCount
|
||
; 9/5/83 SC Andy found a bug...
|
||
; 8/29/83 SC Changed scrap info interface
|
||
; 8/21/83 SC Crunched eight bytes out
|
||
;
|
||
;
|
||
|
||
;---------------------------------------------------------------
|
||
;
|
||
; Mac Scrap Manager
|
||
;
|
||
; This is a set of simple routines to help the applications
|
||
; manipulate the scrap for inter-application cutting and pasting.
|
||
;
|
||
; The scrap is simply a collection of typed data objects(Hi Bruce).
|
||
; in a handle that is maintained through application launches.
|
||
; There are two "Universal types," TEXT, for vanilla text, and PICT,
|
||
; for QuickDraw pictures. However, the application is free to
|
||
; add private types like SYLK.
|
||
;
|
||
; The general rules of thumb are: applications MUST be able to
|
||
; read both universal types and write at least one. This should
|
||
; insure that all applications can minimally exchange information
|
||
; through at least one level. If applications choose to write more
|
||
; than one type, the order is important; one should write the types
|
||
; in order of importance to that application. eg. a word processor
|
||
; should write out its private format first, then text, then a picture
|
||
; if desired. This implicitly states which type has the highest
|
||
; information content coming from that particular application. When
|
||
; reading the scrap one should scan for the types in the same order
|
||
; in an attempt to recover the highest information content.
|
||
;
|
||
; There are user-defined "fields" in both the TEXT and PICT types so
|
||
; the applications are encouraged to place custom data there in an
|
||
; effort to reduce the size of the scrap. As in the example above, a
|
||
; word processor might hide its formatting information in the TEXT
|
||
; comments so that only two types are written into the scrap.
|
||
;
|
||
; The script for using the scrap is: The application starts up. It
|
||
; inquires as early as possible about the scrap to determine if there
|
||
; will be enough room for the application and scrap to coexist in the
|
||
; heap. If not, it calls an unload procedure to save the scrap to disk.
|
||
; If that fails, or is deemed impossible, an alert should be raised to
|
||
; inform the user and ask for guidance. The user might just want to
|
||
; abort the application at this point.
|
||
;
|
||
; Then the application must remember that the universal scrap is
|
||
; pregnant with data when a paste command is executed. At that point
|
||
; it should dissect the scrap to find the most logical type and
|
||
; paste that into its data. An alternative is to automatically
|
||
; convert the scrap to the applications internal format so that the
|
||
; paste code can be dumb and not have to serve two masters. It is
|
||
; important to realize that the scrap data cannot be dumped until a
|
||
; cut/copy-like command is executed. While the applications runs
|
||
; there is, of course, no need to maintain or otherwise diddle with
|
||
; the universal scrap.
|
||
;
|
||
; When the application terminates, it should make every attempt to
|
||
; dump its scrap into the universal one. Obviously, if the application
|
||
; has a disk based scrap, it may be impossible to copy into memory.
|
||
; Or even with a memory based scrap, there might not be enough room
|
||
; for a "second" copy in the heap. In either case an alert should
|
||
; be raised telling the user of the applications dilemma. The user
|
||
; might at this point stay in the application and prune the scrap.
|
||
;
|
||
; When the user activates or deactivates an ornament, a similar course
|
||
; should be followed by the application. The activate and deactivate
|
||
; events contain some additional bits in the modifiers field which will
|
||
; indicate whether the transition is between a system or application
|
||
; window. If this case is true and the event is a deactivate, the
|
||
; application should call the same code as the termination sequence
|
||
; above. Of course, activate events should then parallel the startup
|
||
; scenario.
|
||
;
|
||
;
|
||
; The routines are:
|
||
;
|
||
; ScrapStuff = RECORD
|
||
; scrapSize: LONGINT;
|
||
; scrapHandle: Handle;
|
||
; scrapCount: INTEGER;
|
||
; scrapState: INTEGER;
|
||
; scrapName: StringPtr;
|
||
; END;
|
||
; pScrapStuff: ^ ScrapStuff;
|
||
|
||
; FUNCTION InfoScrap: pScrapStuff;
|
||
; returns a pointer to the scrap info
|
||
;
|
||
; FUNCTION UnloadScrap: LONGINT;
|
||
; Unloads the scrap from memory
|
||
;
|
||
; FUNCTION LoadScrap: LONGINT;
|
||
; Loads the scrap from scrap file into memory
|
||
;
|
||
; FUNCTION GetScrap( hDest: Handle; what: ResType;
|
||
; VAR offset: LONGINT ): LONGINT;
|
||
; hDest = the destination handle in which to copy the object.
|
||
; If handle is NIL, then doesn't get it.
|
||
; what = the type of object to copy
|
||
; offset returned as offset in scrap of this object
|
||
; result is -1 if it couldn't be found or a negative system
|
||
; error; set >= 0 (to size) if OK
|
||
;
|
||
; FUNCTION ZeroScrap: LONGINT;
|
||
; Cuts back the scrap to empty.
|
||
;
|
||
; FUNCTION PutScrap( length: LONGINT; what: ResType; source: Ptr ): LONGINT;
|
||
; what = the type of object to copy
|
||
; source = pointer from which to copy the object
|
||
; length = length of object at source
|
||
;
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
LOAD 'StandardEqu.d'
|
||
|
||
|
||
; 3 States of scrap (In scrapState): negative uninitialized, positive on disk,
|
||
; zero in memory
|
||
|
||
|
||
; Defs for a scrap entry
|
||
|
||
scrType EQU 0
|
||
scrLength EQU scrType+4
|
||
scrData EQU scrLength+4
|
||
|
||
; Std frame off A6
|
||
|
||
scrapIO EQU -IOFQElSize ; io cmd
|
||
dLength EQU scrapIO-4 ; disk object length
|
||
dType EQU dLength-4 ; disk object type
|
||
|
||
stdLink EQU dType ; std frame size
|
||
|
||
|
||
ScrapMgr PROC EXPORT
|
||
|
||
EXPORT InfoScrap
|
||
EXPORT LoadScrap
|
||
EXPORT UnloadScrap
|
||
EXPORT GetScrap
|
||
EXPORT ZeroScrap
|
||
EXPORT PutScrap
|
||
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
; FUNCTION InfoScrap: pScrapStuff;
|
||
;
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
|
||
InfoScrap
|
||
TST scrapState ; <15Jun85>
|
||
BGE.S @0 ; <15Jun85>
|
||
SUBQ #4,SP ; <15Jun85>
|
||
_ZeroScrap ; <15Jun85>
|
||
ADDQ #4,SP ; <15Jun85>
|
||
@0 ; <15Jun85>
|
||
|
||
MOVE.L (SP)+,A0 ; RTS
|
||
LEA scrapVars,A1
|
||
MOVE.L A1,(SP)
|
||
JMP (A0)
|
||
|
||
|
||
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
; StdEntry
|
||
;
|
||
; This routine sets up the standard frame and builds the
|
||
; io command block for an open. Then it tries to create and then open
|
||
; the file
|
||
;
|
||
;
|
||
; Exit:
|
||
; A0 - io command block
|
||
; A3 - io command block
|
||
; D0 - IO error
|
||
; D4 - scrapInfo
|
||
; D5 - scrapHandle
|
||
; D6 - scrapState
|
||
; CC's - set according to Open or create result (e.g. IO error)
|
||
;
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
StdEntry
|
||
MOVE.L (SP)+,A1 ; save local return address
|
||
LINK A6,#stdLink ; set up frame
|
||
MOVEM.L D2-D7/A2-A4,-(SP) ; save the regs
|
||
MOVE.L A1,-(SP) ; push back on return
|
||
StdSetup
|
||
MOVEM.L scrapVars,D4/D5/D6/A2 ; preload scrapInfo,handle,state and name
|
||
LEA scrapHandle,A4 ; convenient pointer
|
||
|
||
LEA scrapIO(A6),A0 ; set up io command block
|
||
MOVE.L A0,A3 ; Save I/O ptr in A3
|
||
MOVE.L A2,IOFileName(A0) ; set file name ptr
|
||
; CLR.W IODrvNum(A0) ; use default drive
|
||
MOVE.W BootDrive,IODrvNum(A0) ; use boot drive <27 Apr>
|
||
CLR.W IOFileType(A0) ; clear type, permissions
|
||
CLR.L IOOwnBuf(A0) ; use system buffer
|
||
|
||
TST D6 ; scrapState = disk
|
||
BNE goHome0 ; skip open if not on disk <SM3> CSS
|
||
|
||
; Now try to open; if that fails, create and open the file
|
||
|
||
StdOpen
|
||
_Open ; try an open first
|
||
BEQ.S goHome ; and escape if good
|
||
CMP #OpWrErr,D0 ; if open already, pretend it's ok
|
||
BEQ.S goHome0
|
||
CMP #FNFErr,D0 ; create if not there
|
||
BNE.S goHome
|
||
|
||
_Create ; io cmd set up
|
||
BNE.S goHome
|
||
|
||
_GetFileInfo ; set the finder shit <27 Apr>
|
||
MOVE.L #'CLIP',IOFlUsrWds(A0) ; set type <27 Apr>
|
||
MOVE.L #'MACS',IOFlUsrWds+4(A0); set creator <27 Apr>
|
||
BSET #4,IOFlUsrWds+8(A0) ; set system bit <27 Apr>
|
||
_SetFileInfo ; <27 Apr>
|
||
BNE.S goHome ; <27 Apr>
|
||
|
||
BRA StdOpen ; go open now
|
||
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
; FUNCTION UnloadScrap: LONGINT;
|
||
; FUNCTION LoadScrap: LONGINT;
|
||
;
|
||
; Reminder:
|
||
; D4 = scrapLength from StdEntry
|
||
; D5 = scrapHandle
|
||
; D6 = scrapState
|
||
; A4^ scrapHandle
|
||
;
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
|
||
UnloadScrap
|
||
BSR StdEntry ; go set up local world
|
||
BNE.S err0Exit ; escape if IO error
|
||
|
||
TST D6 ; escape if on disk or un-inited
|
||
BLE.S ok0Exit ; scrapState is <=0'
|
||
|
||
BSR StdOpen ; go open it
|
||
BNE.S err0Exit ; more robust error checking <C716>
|
||
|
||
MOVE.L D4,D0 ; pass the length
|
||
BSR.S SetupRW ; set up IO cmd
|
||
|
||
_Write ; write it out
|
||
BNE.S err0Exit
|
||
|
||
MOVE.L D5,A0 ; get rid of the handle
|
||
_DisposHandle ; ignore errors from dispose
|
||
|
||
CLR.L (A4)+ ; indicate on disk(scrapHandle)
|
||
CLR.L (A4)+ ; indicate on disk(scrapState)
|
||
|
||
ok0Exit
|
||
MOVEQ #0,D0 ; no error
|
||
err0Exit
|
||
EXT.L D0
|
||
MOVE.L D0,8(A6) ; return result code (link+0 param)
|
||
|
||
MOVEQ #0,D0 ; see you later
|
||
StdExit
|
||
MOVEM.L (SP)+,D2-D7/A2-A4 ; see you later
|
||
StdUNLK
|
||
UNLK A6
|
||
stdRTS
|
||
MOVE.L (SP)+,A0
|
||
ADD D0,SP
|
||
JMP (A0)
|
||
|
||
|
||
goHome0
|
||
MOVEQ #0,D0 ; jam no error
|
||
goHome
|
||
RTS ; return
|
||
|
||
LoadScrap
|
||
BSR StdEntry ; go set up the world
|
||
BNE err0Exit
|
||
|
||
TST D6 ; check scrap state
|
||
BNE.S ok0Exit ; escape if in memory
|
||
|
||
MOVE.L D4,D0 ; get scrap length
|
||
_NewHandle
|
||
BNE err0Exit
|
||
|
||
MOVE.L A0,(A4)+ ; save the new handle(scrapHandle)
|
||
ADDQ.L #1,(A4)+ ; 0 disk => 1 memory(scrapState)
|
||
|
||
MOVE.L D4,D0 ; pass the length
|
||
BSR.S SetupRW2 ; set up IO cmd for read
|
||
_Read ; read it in
|
||
BRA err0Exit
|
||
|
||
|
||
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
; Set up Read/Write for IO in command block off A6
|
||
; Absolute pos mode at beginning
|
||
;
|
||
; Entry:
|
||
; A0 - (SetupRW2) handle for scrap
|
||
; A3 - io cmd block
|
||
; D0 - length to read or write
|
||
; D5 - scrap handle from stdEntry
|
||
; Exit:
|
||
; A0 - iocommand block
|
||
;
|
||
;-----------------------------------Scrap-----------------------------------
|
||
|
||
SetupRW
|
||
MOVE.L D5,A0 ; set up buffer address
|
||
SetupRW2
|
||
MOVE.L (A0),IOBuffer(A3) ; to scrap handle
|
||
MOVE.L D0,IOByteCount(A3) ; set up the buffer count
|
||
MOVE #1,IOPosMode(A3) ; absolute position
|
||
CLR.L IOPosOffset(A3) ; position to beginning
|
||
MOVE.L A3,A0 ; set up for I/O
|
||
|
||
RTS ; return for read or write
|
||
|
||
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
; FUNCTION ZeroScrap: LONGINT;
|
||
;
|
||
; Reminder:
|
||
; D4 = scrapLength from StdEntry
|
||
; D5 = scrapHandle
|
||
; D6 = scrapState
|
||
;
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
ZeroScrap
|
||
BSR StdEntry ; D0 set to 0 by above
|
||
BNE err0Exit
|
||
|
||
MOVE.L D0,scrapInfo ; zero out info
|
||
ADDQ #8,4(A4) ; increment validation word
|
||
BPL.S @0
|
||
NEG 4(A4) ; force it positive
|
||
@0
|
||
TST D6
|
||
BEQ.S zeroDisk ; see if on disk
|
||
BGT.S zeroMem ; see if in memory
|
||
|
||
; allocate a new scrap
|
||
|
||
_NewHandle ; create the handle if the location
|
||
BRA.S zsExit ; was negative
|
||
|
||
zeroMem
|
||
MOVE.L D5,A0 ; get the existing handle
|
||
_SetHandleSize
|
||
zsExit
|
||
MOVE.L A0,(A4)+ ; save the handle(scrapHandle)
|
||
MOVE (A4)+,(A4) ; positive => 1 memory(scrapState)
|
||
BRA err0Exit
|
||
|
||
zeroDisk
|
||
CLR.L IOLEOF(A0) ; set to zero
|
||
_SetEOF
|
||
BRA err0Exit
|
||
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
; FUNCTION GetScrap( hDest: Handle; what: ResType;
|
||
; VAR offset: LONGINT ): LONGINT;
|
||
;
|
||
; Reminder:
|
||
; D4 = scrapLength from StdEntry
|
||
; D5 = scrapHandle
|
||
; D6 = scrapState
|
||
;
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
gsOffset EQU 8 ; VAR offset
|
||
gsType EQU gsOffset+4 ; type
|
||
gsHDest EQU gsType+4 ; destination handle
|
||
gsResult EQU gsHDest+4 ; result longint
|
||
|
||
; Utility to "get" bytes from the scrap on disk or in memeory
|
||
;
|
||
; Entry:
|
||
; D3 contains byte offset in scrap
|
||
; D0 contains amount to read
|
||
; A1 points to receiving buffer
|
||
DoGet
|
||
TST D6 ; see if on disk
|
||
BEQ.S getDisk
|
||
|
||
; Get the data from the scrap handle in memeory
|
||
MOVE.L D5,A2 ; get scrapHandle
|
||
MOVE.L (A2),A0 ; set up source for move
|
||
ADD.L D3,A0 ; add in offset
|
||
_BlockMove
|
||
BRA goHome0 ; return zero
|
||
|
||
; Get the data from the file
|
||
getDisk
|
||
BSR SetupRW ; fill out I/O command blk
|
||
MOVE.L D3,IOPosOffset(A0) ; absolute read @ D3
|
||
MOVE.L A1,IOBuffer(A0) ; point to dest buffer
|
||
_Read
|
||
RTS
|
||
|
||
|
||
|
||
GetScrap
|
||
BSR StdEntry ; Open things up
|
||
BNE.S err12Exit ; escape if file error
|
||
|
||
; Make sure scrap exists <27 Apr>
|
||
; MOVEQ #noScrapErr,D0 ; scrap don't exist <27 Apr>
|
||
; TST D6 ; check scrap state <27 Apr>
|
||
; BMI.S err12Exit ; escape if not zeroed <27 Apr>
|
||
|
||
BSR FailSafe ; <27 Apr>
|
||
BMI.S err12Exit ; escape if error on init <27 Apr>
|
||
|
||
; Start looking through the scrap
|
||
;
|
||
; D0 is used for read lengths
|
||
; D3 is the offset @ which to read
|
||
; A1 points to dest buffer
|
||
|
||
MOVEQ #0,D3 ; start offset
|
||
readNext
|
||
CMP.L D4,D3 ; see if done with list
|
||
BGE.S notFound
|
||
|
||
MOVEQ #scrData,D0 ; read object header(8)
|
||
LEA dType(A6),A1 ; buffer to place stuff
|
||
BSR.S DoGet ; go get it
|
||
BNE.S err12Exit
|
||
|
||
okRead
|
||
ADDQ.L #scrData,D3 ; point to next entry(more below)
|
||
|
||
MOVE.L (A1)+,D7 ; get type from file
|
||
CMP.L gsType(A6),D7 ; and compare
|
||
BEQ.S foundIt
|
||
|
||
ADD.L (A1)+,D3 ; by adding 8 plus length
|
||
ADDQ.L #1,D3 ; round up to even
|
||
BCLR D0,D3 ; assume D0 = 0
|
||
BRA readNext
|
||
|
||
; We now have D3 offset to correct entry, A1 points to object's length
|
||
; If the dest handle is nil, escape after passing back offset and D0
|
||
; contains the length
|
||
|
||
notFound
|
||
MOVEQ #noTypeErr,D0 ; couldn't find type
|
||
BRA.S err12LExit
|
||
|
||
; We now have D3 offset to correct entry, A1 points to object's length
|
||
; If the dest handle is nil, escape after passing back offset and D0
|
||
; contains the length
|
||
|
||
foundIt
|
||
MOVE.L gsOffset(A6),A2 ; set up var address
|
||
MOVE.L D3,(A2) ; return the offset to caller
|
||
MOVE.L (A1),D0 ; Get object's length for return in D0
|
||
MOVE.L D0,20(A6) ; and return length for now
|
||
|
||
MOVE.L gsHDest(A6),D1 ; set up destination
|
||
BEQ.S go12Exit ; return length if no handle
|
||
|
||
MOVE.L D1,A0 ; set it's size
|
||
_SetHandleSize
|
||
BNE.S err12Exit
|
||
|
||
; Do the actual fetch of the object
|
||
MOVE.L (A1),D0 ; and read it's length
|
||
MOVE.L (A0),A1 ; and read into dereferenced handle
|
||
BSR.S DoGet
|
||
|
||
BEQ.S go12Exit ; if no error(the length is stuffed above)
|
||
|
||
err12Exit ; see you later
|
||
EXT.L D0 ; turn OS error into a long
|
||
err12LExit
|
||
MOVE.L D0,20(A6) ; and return error code
|
||
go12Exit ; link(8) + params(12)
|
||
MOVEQ #12,D0
|
||
BRA StdExit
|
||
|
||
|
||
; Called by get and put to insure the scrap is zeroed if it hasn't been inited
|
||
; yet. This removes the noScrapErr error and makes it easier to use.
|
||
|
||
; Entered with cc's set according to D6 (just after StdEntry)
|
||
|
||
FailSafe ; <27 Apr>
|
||
TST D6 ; what's the scoop? <27 Apr>
|
||
BGE.S @0 ; is scrap inited? <27 Apr>
|
||
|
||
SUBQ #4,SP ; zero the scrap <27 Apr>
|
||
_ZeroScrap
|
||
MOVE.L (SP)+,D0
|
||
BMI.S err12Exit ; pass error along if there <27 Apr>
|
||
BSR StdSetup
|
||
@0
|
||
RTS
|
||
|
||
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
; FUNCTION PutScrap( length: LONGINT; what: ResType; pSource: Ptr ): LONGINT;
|
||
;
|
||
; Doesn't check for existing object of that type because caller
|
||
; will have always zeroed scrap prior to this.
|
||
;
|
||
; Reminder:
|
||
; D4 = scrapLength from StdEntry
|
||
; D5 = scrapHandle
|
||
; D6 = scrapState
|
||
;
|
||
;-----------------------------------Scrap-----------------------------------
|
||
;
|
||
psSource EQU 8 ; source ptr
|
||
psType EQU psSource+4 ; type
|
||
psLength EQU psType+4 ; source length
|
||
|
||
psResult EQU psLength+4 ; result
|
||
|
||
PutScrap
|
||
BSR StdEntry ; set up frame
|
||
|
||
; MOVEQ #noScrapErr,D0 ; assume the worst <27 Apr>
|
||
; TST D6 ; see if on disk <27 Apr>
|
||
; BMI.S err12Exit ; <27 Apr>
|
||
|
||
BSR FailSafe ; make sure it's inited <27 Apr>
|
||
BMI.S err12Exit ; escape if error on init <27 Apr>
|
||
|
||
BSR SetupRW ; get ready for a write <27 Apr, moved>
|
||
|
||
MOVEQ #scrData,D0 ; length of type
|
||
LEA psType(A6),A0 ; save type and length
|
||
BSR.S DoPut ; ignore error, catch it below
|
||
|
||
MOVE.L psSource(A6),A0 ; get source ptr
|
||
MOVE.L psLength(A6),D0 ; save the length's worth
|
||
MOVEQ #-2,D1 ; evenizer mask
|
||
ADDQ.L #1,D0 ; round up to even
|
||
AND.L D1,D0
|
||
BSR.S DoPut ; errors handled on exit
|
||
|
||
MOVE.L D4,-(A4) ; and save new scrap length(ScrapInfo)
|
||
|
||
BRA.S err12Exit ; see you later D0 set from above
|
||
|
||
DoPut
|
||
MOVE.L D4,IOPosOffset(A3) ; set file position to old size
|
||
ADD.L D0,D4 ; add this length to get new size
|
||
|
||
TST D6 ; see if on disk
|
||
BEQ.S putDisk
|
||
|
||
MOVE.L D5,A1 ; get scrap handle
|
||
_PtrAndHand ; add on to handle
|
||
|
||
;roll in FixPutScrap from ScrapMgrPatches.a. If _PtrAndHand returns an error
|
||
; (in D0), then we skip over the updating of low-mem scrapSize and cut back the
|
||
; scrap handle to the last scrapSize <SM2> <PN>
|
||
|
||
bz.s @exitDoPut ; <SM4+> Exit if PtrAndHand succeeded
|
||
move.w d0,-(sp) ; save orginal error code <SM2> <PN>
|
||
move.l scrapSize,d0 ; resize handle to last good size, to delete last 'next entry' <SM2> <PN>
|
||
_SetHandleSize ; <SM2> <PN>
|
||
move.w (sp)+,d0 ; return with original error code <SM2> <PN>
|
||
addq #4,sp ; <SM4+> Pop DoPut caller’s return address
|
||
bra err12Exit ; <SM4+> And exit immediately.
|
||
|
||
@exitDoPut
|
||
rts ; <SM2> <PN>
|
||
|
||
putDisk
|
||
MOVE.L A0,IOBuffer(A3) ; stuff ptr to data
|
||
MOVE.L D0,IOByteCount(A3) ; 8 bytes of I/O
|
||
MOVE.L A3,A0 ; restore I/O command
|
||
|
||
_Write
|
||
|
||
;roll in F2PutScrap from ScrapMgrPatches.a. If _Write returns an error
|
||
; (in D0), then we skip over the updating of low-mem scrapSize and cut back the
|
||
; scrap handle to the last scrapSize <SM2> <PN>
|
||
|
||
bz.s @exitPutDisk ; <SM4+> Exit if Write succeeded
|
||
move.w d0,-(sp) ; save orginal error code <SM2> <PN>
|
||
move.l scrapSize,ioMix(a0) ; resize file to last good size, to delete last 'next entry' <SM2> <PN>
|
||
_SetEOF ; <SM2> <PN>
|
||
move.w (sp)+,d0 ; return with original error code <SM2> <PN>
|
||
addq #4,sp ; <SM4+> Pop PutDisk caller’s return address
|
||
bra err12Exit ; <SM4+> And exit immediately
|
||
|
||
@exitPutDisk
|
||
RTS ; <SM2> <PN>
|
||
|
||
|
||
END
|
||
|
||
|