antoine-source/appleworksgs/WP/Src/Paste.aii
2023-03-04 03:45:20 +01:00

1 line
21 KiB
Plaintext
Executable File

*****************************************************************************************************
* WP Copy/Paste Routines
*
* This file contains the routines used by WP to handle cutting and pasting.
*
*****************************************************************************************************
load 'macros.dump'
include 'driver.equ'
include 'wp.equ'
include 'scrap.equ'
IMPORT D_BeachBall
IMPORT D_Deref
IMPORT D_GrowLHandle
IMPORT D_KillFont
IMPORT D_MemoryError
IMPORT D_UndoMemError
IMPORT D_Unlock
IMPORT W_CalcDocRect
IMPORT W_CalcFBytes
IMPORT W_CalcPages
IMPORT W_CollapseRulers
IMPORT W_CurDoc
IMPORT W_DelSelect
IMPORT W_EndLine
IMPORT W_EndOffset
IMPORT W_EndPar
IMPORT W_FindFont
IMPORT W_FindLine
IMPORT W_GetAddr
IMPORT W_GetDoc
IMPORT W_GetParRec
IMPORT W_JunkLeft
IMPORT W_JunkRight
IMPORT W_LastP
IMPORT W_LessRoom
IMPORT W_LineToTopPixel
IMPORT W_MakeCaret
IMPORT W_MakeCr
IMPORT W_MakeEmptyBlock
IMPORT W_MakeRoom
IMPORT W_MakeLines
IMPORT W_MaxP
IMPORT W_PHandle
IMPORT W_PPtr
IMPORT W_PasteLine
IMPORT W_PasteOffset
IMPORT W_PastePar
IMPORT W_PtToText
IMPORT W_PutOnScreen
IMPORT W_ReadFont
IMPORT W_Selected
IMPORT W_SelectOff
IMPORT W_SetFullREct
IMPORT W_StartLine
IMPORT W_StartOffset
IMPORT W_StartPar
IMPORT W_UnUseRuler
IMPORT W_UndoEndLine
IMPORT W_UndoEndOffset
IMPORT W_UndoEndPar
IMPORT W_UndoOff
IMPORT W_UndoOn
IMPORT W_UndoStartLine
IMPORT W_UndoStartOffset
IMPORT W_UndoStartPar
IMPORT W_UndoHandle
IMPORT W_UpdateText
IMPORT W_UseRuler
IMPORT W_View
IMPORT W_WpCopy
IMPORT W_WriteFBytes2
IMPORT X_DisposeScrap
IMPORT X_PostScrap
IMPORT X_SwitchFont
IMPORT caretOff
ENTRY W_PasteText
ENTRY W_SplitBlock
*****************************************************************************************************
; W_MyPaste ( WindowPtr:long, Scrap:long, Type:word, Paste:word, Where:long )
;
; This is the main paste vector for WP. If the given scrap is of the correct type it will be
; pasted into the document for the given window. If Paste is 1 then use the Where field to
; determine where in the window the paste should take place. If Paste is 2 then paste is coming
; from an import. Memory errors are returned. Where is in window local coordinates.
W_MyPaste PROC EXPORT
;Using wpglobals
input window:l,Scrap:l,type:w,Paste:w,where:l
local rect:r,ParCnt:w,WPtr:l,par:w,OldDoc:l
error err
begin +b
; Make sure that the scrap is a WP scrap if not dispose of it and exit with error #1.
stz err
cmpw type,#WPText
beq savedoc
inc err
call X_DisposeScrap,in=(Type:w,Scrap:l)
brl _exit
; Save current document so it can be restored before exiting. Turn carret off and clear the undo.
savedoc movelong W_CurDoc,OldDoc
tool _SetPort,in=(W_CurDoc:l)
jsl caretOff
jsl W_UndoOff
; Set port to given window and kill current font. Bring in document information.
tool _SetPort,in=(window:l)
jsl D_KillFont
call W_GetDoc,in=(window:l)
; Strip page breaks if we are pasting into the header or footer of the document. Note: PageBreaks
; are guaranteed to always have a carriage return after them. ( ie next paragraph is guaranteed to be
; a real paragraph - no consecutive page breaks paragraph blocks ). Also Page break paragraphs will
; have for their text blocks the same text block used for the text before the page break.
lda W_View
jeq NoKillPB
movelong [scrap],WPtr
moveword [WPtr],ParCnt
addwl #2,WPtr
parloop cmpw [WPtr]:#W_pAttr,#W_PgBrk
bne nextpar
movelong #0,[WPtr]:#W_pLineHand
moveword #0,[WPtr]:#W_pAttr
moveword #1,[WPtr]:#W_pLastLine
movelong [WPtr]:#W_pBytes+W_pRulerHand,[WPtr]:#W_pRulerHand
call W_UseRuler,in=(#1:w,[WPtr]:#W_pBytes+W_pRulerHand:l)
nextpar addwl #W_pBytes,WPtr
dec ParCnt
bne parloop
; If placement type paste then deselect current text and move insertion point to new place in text
; before doing the paste.
NoKillPB cmpw paste,#1
bne noplace
jsl W_SelectOff
call W_PtToText,in=(Where:l),out=(W_StartPar:w,W_StartLine:w,W_StartOffset:w)
jsl W_MakeCaret
; Make sure the given paragraph line is on the screen. Get current document rect and adjust top of
; rect based to top pixel of start line.
noplace call W_PutOnScreen,in=(W_StartPar:w,W_StartLine:w,#0:l)
call W_CalcDocRect,in=(!rect:l)
call W_LineToTopPixel,in=(W_StartPar:w,W_StartLine:w),out=(rect:w,a:w)
; If directional paste or import then deselect and don't allow undo.
lda paste
beq RegUndo
jsl W_DelSelect
brl NoUndo
; Clear undo handle. If something is selected then save copy of it in undo handle. If we can't get
; enough memory for undo copy then ask if should continue anyway.
RegUndo stzl W_UndoHandle
lda W_Selected
beq NoSelD
spacelong
pushword W_StartPar
pushword W_StartLine
pushword W_StartOffset
pushword W_EndPar
pushword W_EndLine
pushword W_EndOffset
jsl W_WpCopy
sta err
pla
plx
bcc putcopy
call D_UndoMemError,out=(a:w)
cmp #OK
beq noundo
brl exit
; Save copy of selected text in undo handle then delete selected text from document.
putcopy movelong ax,W_UndoHandle
jsl W_DelSelect
; Enable undo menu item and place undo text. Remember undo information to restore selection.
NoSelD call W_UndoOn,in=(#W_PasteUndo:w)
moveword W_StartPar,W_UndoStartPar
moveword W_StartLine,W_UndoStartLine
moveword W_StartOffset,W_UndoStartOffset
; Paste the scrap into the document. If memory error then return error to driver.
NoUndo pha
pha
pha
pushlong Scrap
pushword W_StartPar
pushword W_StartLine
pushword W_StartOffset
jsl W_PasteText
sta err
bcc NoErr
pla
pla
pla
bra exit
; Successfully pasted text into document. Set new values for start offset, line, and paragraph.
NoErr pullword W_StartOffset
pullword W_StartLine
pullword W_StartPar
; Save end position after paste into the undo information.
moveword W_StartPar,W_UndoEndPar
moveword W_StartLine,W_UndoEndLine
moveword W_StartOffset,W_UndoEndOffset
; Erase the clip and erase the document rect; then update its contents.
tool _ClipRect,in=(!rect:l)
tool _EraseRect,in=(!rect:l)
jsl W_UpdateText
; Set clip rect to port rect; put up caret; and collapse rulers.
exit jsl W_SetFullRect
jsl W_MakeCaret
jsl W_CollapseRulers
; Restore old document.
call W_GetDoc,in=(OldDoc:l)
_exit return
ENDP
*****************************************************************************************************
; W_GetCopy ( ): CopyHandle:xy
;
; This routine will return a wpscrap for the current selection. A-reg will contain any errors and
; carry flag is set accordingly.
W_GetCopy PROC EXPORT
spacelong
pushword W_StartPar
pushword W_StartLine
pushword W_StartOffset
pushword W_EndPar
pushword W_EndLine
pushword W_EndOffset
jsl W_WpCopy
plx
ply
rts
ENDP
*****************************************************************************************************
; W_MyCut ( WindowPtr:long ):ImageRoutine:long
;
; This routine is the cut vector entry point. It will copy the current selection and then delete
; it from the document. If not enough memory exists to copy then user will be asked told not enough
; memory to undo and be asked to continue or not. ImageRoutine is the routine to be called to draw
; the outline of what is being copied.
W_MyCut PROC EXPORT
;Using wpglobals
input window:l
local Handle:l,OldDoc:l
output ImageRoutine:l
error err
begin +b
; Remember old active document and set document and port for given window.
stzl ImageRoutine
movelong W_CurDoc,OldDoc
call W_GetDoc,in=(Window:l)
tool _SetPort,in=(Window:l)
; If nothing is current selected then simply exit.
lda W_Selected
jeq exit
; Attempt to copy the current selection. If we can't get copy then return memory error to the driver.
jsr W_GetCopy
sta err
jcs exit
movelong xy,handle
; Can perform the copy so now clear caret and undo.
jsl CaretOff
jsl W_UndoOff
; Try and get copy for undo. If we can't then ask user whether we should continue or not.
jsr W_GetCopy
sta err
bcc putundo
call D_UndoMemError,out=(a:w)
cmp #OK
beq noundo
stz err
tool _DisposeHandle,in=(handle:l)
bra exit
; Have enough memory for undo copy. Save it in undo handle and setup undo menu item.
putundo movelong xy,W_UndoHandle
call W_UndoOn,in=(#W_CutUndo:w)
; Post the scrap, point to our image routine, set clip rect to the entire port, and delete the
; current selection.
noundo call X_PostScrap,in=(#WPText:w,Handle:l)
; movelong #W_MyImage,ImageRoutine
jsl W_SetFullREct
jsl W_DelSelect
; Restore old document.
exit call W_GetDoc,in=(OldDoc:l)
return
ENDP
*****************************************************************************************************
; W_MyCopy ( WindowPtr:long ):ImageRoutine:long, Type:word, Scrap:long
;
; This routine is the copy vector entry point. It will copy the current selection. Memory errors
; are returned. ImageRoutine is the routine to draw an image of the scrap for dragging. Passes back
; zero for no scrap.
W_MyCopy PROC EXPORT
;Using WPGlobals
input window:l
output ImageRoutine:l,stype:w,OutHandle:l
error err
begin +b
; Clear error status and return scrap type. Save current document on stack and set current document
; to the given window's document. (and port)
stz err
stz stype
stzl ImageRoutine
pushlong W_CurDoc
call W_GetDoc,in=(window:l)
tool _SetPort,in=(window:l)
; If nothing is selected then ignore call.
lda W_Selected
jeq exit
; Turn off caret and clear undo buffer.
jsl CaretOff
jsl W_UndoOff
; Get copy of current selection. If error then exit returning error to driver, else return wpscrap
; and type. Set Imageroutine.
jsr W_GetCopy
sta err
bcs exit
movelong xy,outhandle
moveword #WPText,stype
; movelong #W_MyImage,ImageRoutine
; Restore old document.
exit jsl W_GetDoc
return
ENDP
*****************************************************************************************************
; W_MyImage ( Where:long )
;
; This routine draw a rect 0,0,50,120 at where.
; Note: No longer used.
;
;W_MyImage PROC EXPORT
; input where:l
; local rect:r
; begin +b
;
; movelong where,rect
; addword where,#50,rect+4
; addword where+2,#120,rect+4+2
; tool _FrameRect,in=(!Rect:l)
;
; return
;
; ENDP
*****************************************************************************************************
; W_PasteText ( Handle:l, Par:w, Line:w, Offset:w ): EndPar:w, EndLine:w, EndOffset:w
;
; This routine does the actually work of pasting a scrap handle @ the given paragraph, line, and
; offset. The ending paragraph, line, and offset are returned. Memory errors are returned as well.
W_PasteText PROC EXPORT
;Using wpglobals
input handle:l,par:w,line:w,offset:w
output Outpar:w,Outline:w,Outoffset:w
local ptr:l,ParRec1:l,ParRec2:l,Block1:l,Block2:l
local col1:w,font1:l,col2:w,font2:l,FBytes:l,TPtr:l
local bytes:l,NewLastP:w,NewMaxP:w,NewPars:w,temp:w
local BegRul:w,EndRul:w,RulRec:l,Offset1:w,Offset2:w,Ptr2:l
local TextPtr:l,NewSize:l
error err
begin
; Save paragraph, line, and offset in global variables. Spin the beach ball.
moveword par,W_PastePar
moveword line,W_PasteLine
moveword offset,W_PasteOffset
jsl D_BeachBall
; Clear error status, flags, and high word of byte counters.
stz err
stz bytes+2
stz FBytes+2
stz BegRul
stz EndRul
; Lock down the scrap handle. Point ParRec1 to first paragraph entry in scrap.
rcall D_Deref,in=(handle:ax),out=(ptr:ax)
addlong #2,ptr,ParRec1
; Point ParRec2 to last paragraph entry in scrap.
spacelong
lda [ptr]
dec a
pha
pushword #W_pBytes
_Multiply
addlong s,ParRec1,ParRec2
; Check if first paragraph entry is a page break. If it is we will need to add a carriage return
; paragraph to the scrap before we can process it.
cmpw [ParRec1]:#W_pAttr,#W_PgBrk
bne NoTopPB
jsr addcrtop
jcs killscrap
NoTopPB call W_JunkLeft,in=(par:w,line:w,offset:w),out=(a:w)
sta Offset1
sta W_PasteOffset
cmp #W_TextHeader
bne NoBR
inc BegRul
NoBr call W_JunkRight,in=(par:w,line:w,offset:w),out=(x:w)
stx Offset2
lda par
jsl W_GetAddr
movelong ax,Ptr2
cmpb [Ptr2],#cr
bne NoEr
inc EndRul
NoEr rcall D_Deref,in=([ParRec1]:ax),out=(Block1:ax)
rcall D_Deref,in=([ParRec2]:ax),out=(Block2:ax)
;get font stuff
pha
pha
pha
pha
pha
pha
pushword par
pushword line
pushword Offset1
jsl W_FindFont
lda par
ldx Offset1
jsl W_GetAddr
phx
pha
lda par
ldx Offset2
jsl W_GetAddr
phx
pha
jsl W_ReadFont
moveword 1:s,col1
moveLong 3:s,font1
pushlong handle
jsl X_SwitchFont
; done font stuff
moveword W_LastP,NewLastP
moveword W_MaxP,NewMaxP
lda [ptr]
cmp #2
bcc NoCheck
sec
sbc #2 ;check for a possible future mem error
sta NewPars
clc
adc W_LastP
sta NewLastP
inc a
inc a
cmp W_MaxP
bcc NoCheck
clc
adc #5
sta NewMaxP
tool _Multiply,in=(NewMaxP:w,#W_pBytes:w),out=(NewSize:l)
call D_GrowLHandle,in=(NewSize:l,W_PHandle:l),out=(W_PPtr:l),err=err
bcc NoCheck
brl killscrap
NoCheck moveword NewMaxP,W_MaxP
subword Offset2,Offset1,x
beq NoKillF
moveword Offset1,offset
pushword par
pushword offset
phx
jsl W_LessRoom
NoKillF movelong [Block1]:#W_BHeader,Font2
moveword [Block1]:#W_BHeader+4,a
and #$ff
sta col2
call W_CalcFBytes,in=(font1:l,col1:w,font2:l,col2:w),out=(Fbytes:w)
jsl D_BeachBall
lda [ptr]
cmp #1
jeq JustOne
; this is for the case that there is a cr
pushword Par
pushword line
pushword offset
jsl W_MakeCr
pushword par
jsl W_SplitBlock
jsl D_BeachBall
subword [Block1]:#W_BUsed,#W_BHeader+W_TextHeader+1,bytes
pushword par
pushword offset
addword bytes,FBytes,s
jsl W_MakeRoom
movelong [Block1]:#W_BHeader,font2
moveword [Block1]:#W_BHeader+4,a
and #$ff
sta col2
lda par
ldx offset
jsl W_GetAddr
movelong ax,TPtr
pha
pushword par
pushword offset
pushlong Font1
pushword col1
pushlong Font2
pushword col2
jsl W_WriteFBytes2
subword fbytes,s,fbytes
addlong Block1,#W_BHeader+W_TextHeader,s
addlong TPtr,FBytes,s
pushword #0
pushword bytes
_BlockMove
jsl D_BeachBall
lda par
inc a
ldx #0
jsl W_GetAddr
movelong ax,TPtr
movelong [Block2]:#W_BHeader,[TPtr]
moveword [Block2]:#W_BHeader+3,[TPtr]:#3
subword [Block2]:#W_BUsed,#W_BHeader+W_TextHeader+1,bytes
spacelong
spaceword
pushlong font2
pushword col2
addlong Block2,#W_BHeader+W_TextHeader,TPtr
pushlong TPtr
addlong TPtr,bytes,s
jsl W_ReadFont
pullword col2
pullLong font2
pha
pushlong font2
pushword col2
pushlong font1
pushword col1
jsl W_CalcFBytes
pullword FBytes
lda par
inc a
pha
pushword #W_TextHeader
addword bytes,FBytes,s
jsl W_MakeRoom
jsl D_BeachBall
pushlong TPtr
lda par
inc a
ldx #W_TextHeader
jsl W_GetAddr
movelong ax,TPtr
phx
pha
pushword #0
pushword bytes
_BlockMove
jsl D_BeachBall
pha
lda par
inc a
pha
addword #W_TextHeader,bytes,s
pushlong font2
pushword col2
pushlong font1
pushword col1
jsl W_WriteFBytes2
subword fbytes,s,fbytes
addword TPtr,bytes,a
addword a,FBytes,TPtr
lda par
inc a
ldx #0
jsl W_GetAddr
sta temp
subword TPtr,temp,OutOffset
pushlong [ParRec1]
_DisposeHandle
pushlong [ParRec2]
_DisposeHandle
jsl D_BeachBall
lda BegRul
beq NotInCr
rcall W_GetParRec,in=(par:a),out=(RulRec:ax)
call W_UnUseRuler,in=(#1:w,[RulRec]:#W_pRulerHand:l)
movelong [ParRec1]:#W_pRulerHand,[RulRec]:#W_pRulerHand
bra DoneRul
NotInCr call W_UnUseRuler,in=(#1:w,[ParRec1]:#W_pRulerHand:l)
DoneRul lda EndRul
beq NotInCr2
lda par
inc a
jsl W_GetParRec
movelong ax,RulRec
call W_UnUseRuler,in=(#1:w,[RulRec]:#W_pRulerHand:l)
movelong [ParRec2]:#W_pRulerHand,[RulRec]:#W_pRulerHand
bra DoneRul2
NotInCr2 call W_UnUseRuler,in=(#1:w,[ParRec2]:#W_pRulerHand:l)
DoneRul2 jsl D_BeachBall
lda [ptr]
cmp #2
jeq W_AllSet
lda par
inc a
jsl W_GetParRec
movelong ax,TPtr
phx
pha
lda par
inc a
clc
adc NewPars
jsl W_GetParRec
movelong ax,Block2
phx
pha
lda W_LastP
inc a
jsl W_GetParRec
movelong ax,Block1
sublong Block1,TPtr,s
_BlockMove
jsl D_BeachBall
moveword NewLastP,W_LastP
inc W_LastP
addlong ParRec1,#W_pBytes,Block2
pushlong Block2
pushlong TPtr
sublong ParRec2,Block2,s
_BlockMove
brl W_AllSet
;It is a special case of a paste within the par
JustOne
subword [Block1]:#W_BUsed,#W_BHeader+W_TextHeader+1,bytes
jeq killscrap
pushword par
pushword offset
lda FBytes
asl a
addword a,bytes,s
addword a,offset,OutOffset
jsl W_MakeRoom
jsl D_BeachBall
rcall W_GetAddr,in=(par:a,offset:x),out=(TPtr:ax)
pha
pushword par
pushword offset
pushlong Font1
pushword col1
pushlong Font2
pushword col2
jsl W_WriteFBytes2
subword OutOffset,1:s,OutOffset
subword fbytes,s,fbytes
addlong fbytes,TPtr,TPtr
addlong #W_BHeader+W_TextHeader,Block1,s
pushlong TPtr
pushlong bytes
_BlockMove
jsl D_BeachBall
pha
pushword par
addword offset,fbytes,a
addword a,bytes,s
pushlong Font2
pushword col2
pushlong Font1
pushword col1
jsl W_WriteFBytes2
subword OutOffset,s,OutOffset
;if W_target par was just a cr, use the ruler from copy
; lda BegRul
; beq NoDo
; lda EndRul
; beq NoDo
;
; lda par
; jsl W_GetParRec
; movelong ax,RulRec
;
; pushword #1
; pushlong [RulRec]:#W_pRulerHand
; jsl W_UnUseRuler
;
; movelong [ParRec1]:#W_pRulerHand,[RulRec]:#W_pRulerHand
;
; bra SkipRulDisp
NoDo tool _DisposeHandle,in=([ParRec1]:#W_pRulerHand:l)
SkipRulDisp
tool _DisposeHandle,in=([ParRec1]:l)
jsl D_BeachBall
W_AllSet ;
lda [ptr]
dec a
addword a,par,OutPar
PLoop
jsl D_BeachBall
call W_MakeLines,in=(par:w)
subword OutPar,par,a
cmp #3
bcc NoThow
rcall W_GetParRec,in=(par:a),out=(ParRec1:ax)
Cmpw [ParRec1]:#W_pAttr,#W_PgBrk
beq @1
tool _DisposeHandle,in=([ParRec1]:#W_pLineHand:l)
@1 movelong #0,[ParRec1]:#W_pLineHand
NoThow
inc par
cmpw OutPar,par
bcs PLoop
call W_FindLine,in=(OutPar:w,OutOffset:w),out=(OutLine:w)
jsl W_SetFullREct
jsl D_BeachBall
jsl W_CalcPages
jsl D_BeachBall
tool _DisposeHandle,in=(handle:l)
bra exit
; Memory error occured dispose of scrap.
killscrap rcall D_Unlock,in=(handle:ax)
call X_DisposeScrap,in=(#WPText:w,Handle:l)
exit return
;....................................................................................................
; addcrtop - add carriage return paragraph entry at the beginning of the scrap. Will return carry set
; if memory errors occured while trying to add carriage return paragraph entry.
; Grow scrap by two paragraph entries in size.
addcrtop spacelong
addlong #W_pBytes*2,ParRec2,ParRec2
sublong ParRec2,ptr,s
pushlong handle
jsl D_GrowLHandle
sta err
pullLong ptr
bcc @newpar1
rts
; Get new pointer to first and last paragraph entries.
@newpar1 addlong #2,ptr,ParRec1
spacelong
lda [ptr]
dec a
pha
pushword #W_pBytes
_Multiply
addlong s,ParRec1,ParRec2
addlong #W_pBytes,ParRec2,ParRec2
; Before we munge the scrap lets make sure we will be able to get the new text block we will need if
; not return with memory error.
spacelong
jsl W_MakeEmptyBlock
sta err
bcc @domove ; new text block left on stack until
pulllong a ; after block move is done.
rts
; Move up all paragraph entries one entry block in size.
@domove pushlong ParRec1
addlong ParRec1,#W_pBytes,s
sublong ParRec2,ParRec1,s
_BlockMove
; Fill carriage return paragraph entry default values. Use ruler from carriage return paragraph
; after the page break.
pulllong [ParRec1]
moveword #W_BHeader,[ParRec1]:#W_pOffset
moveword #0,[ParRec1]:#W_pAttr
movelong #0,[ParRec1]:#W_pLineHand
moveword #1,[ParRec1]:#W_pLastLine
movelong [ParRec1]:#W_pRulerHand+W_pBytes+W_pBytes,[ParRec1]:#W_pRulerHand
call W_UseRuler,in=(#1:w,[ParRec1]:#W_pRulerHand:l)
; Set default values for empty text block.
movelong [ParRec1],Block1
movelong [Block1],TextPtr
addword #W_TextHeader+1,[TextPtr]:#W_BUsed,[TextPtr]:#W_BUsed
addwl #W_BHeader,TextPtr
moveword #W_StandFont,[TextPtr]
moveword #W_StandStyle,[TextPtr]:#2
moveword #Black,[TextPtr]:#4
movebyte #cr,[TextPtr]:#W_TextHeader
; Bump the scrap paragraph entries count. Return with carry clear.
lda [ptr]
inc a
sta [ptr]
clc
rts
;....................................................................................................
ENDP
****************************************************************
* W_SplitBlock(par) will make sure that par and par+1 have different blocks
W_SplitBlock PROC EXPORT
;Using wpglobals
input par:w
local ParRec1:l,Blockhand:l,BlockPtr:l
local W_offset:w,bytes:w
begin
CheckAgain
lda par
jsl W_GetParRec
movelong ax,ParRec1
cmpl [ParRec1],[ParRec1]:#W_pBytes
bne NoProb
movelong [ParRec1],BlockHand
movelong [BlockHand],BlockPtr
pushword par
pushword #W_TextHeader
subword [BlockPtr],[ParRec1]:#W_pOffset+W_pBytes,a
dec a
pha
sta bytes
jsl W_MakeRoom
pushword par
pushword #W_TextHeader
pushword bytes
jsl W_LessRoom
brl CheckAgain
NoProb
return
ENDP
END