mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-01 11:29:27 +00:00
0ba83392d4
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
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
|
|
|
|
|