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

1 line
8.3 KiB
Plaintext
Executable File

load 'macros.dump'
include 'driver.equ'
include 'wp.equ'
include 'scrap.equ'
;-----------------------------------------------
;
; Imported addresses
;
;-----------------------------------------------
IMPORT D_BeachBall
IMPORT W_CalcFBytes
IMPORT W_FindFont
IMPORT W_FindFont2
IMPORT W_GetAddr
IMPORT W_GetEndPar
IMPORT W_Getparrec
IMPORT W_LessRoom
IMPORT W_MakeRoom
IMPORT D_NeedHandle
IMPORT W_WriteFBytes
IMPORT W_addr
import W_RulBytes
import X_MassageWPScrap
import D_NeedHand
import D_Deref
import D_GrowHandle
import X_DisposeWPScrap
****************************************************************
*
* W_WpCopy(startp,startl,starto,endp,endl,endo):wpscrap
*
****************************************************************
W_WpCopy PROC EXPORT
BlockSize equ $c00 ;3K
input Startp:w,Startl:w,Starto:w
input Endp:w,Endl:w,Endo:w
local Pars:w,Par:w,Block:l,ParPtr:l,Sptr:l,ParRec:l,Type:w
local Length:w,Offset:w,Bptr:l,NewOffset:l,CurrentBlock:l
local CBPtr:l,NewRuler:l,NRPtr:l,Ruler:l,OldRuler:l,BlockUsed:w
local ScrapSize:l,NextBlock:l,NewSize:l,Soff:l
output Scrap:l
error err
begin +b
stz err
SubWord Endp,Startp,Pars
inc Pars
tool _Multiply,in=(Pars:w,#W_pBytes:w),out=(:l)
AddLong s,#2,ScrapSize
call D_NeedHand,in=ScrapSize:l,out=Scrap:l,err=err
jcs exit
MoveLong [Scrap],Sptr
MoveWord #0,[Sptr]
MoveLong #2,Soff
MoveWord Startp,Par
Stzl Block
Stzl OldRuler
parloop
jsl D_BeachBall
jsr GetParInfo ;ParRec will have pointer to
;paragraph,Type will be set,returns
;length of paragraph Length, and offset
;to first character in Offset.
jsr GrowBlock ;Will allocate a new block if there
jcs memoryerror ;is none. Will make space if there
;would still be less than 3K. Will
;make new text block if not. Sets
;up the variables Block,Bptr,NewOffset.
;Uses Length variable. Does NOT lock
;the block.
MoveLong [ParRec],CurrentBlock
MoveLong [CurrentBlock],CBPtr
Addwl Offset,CBPtr
Cmpw Par,StartP
bne nofont
;Get font info for the first paragraph
call W_FindFont,in=(Startp:w,Startl:w,Starto:w),out=(:l,:w)
PullWord [Bptr]:#4 ;Color
PullLong [Bptr] ;Font ID
Addwl #7,Bptr
bra docopy
nofont lda [CBPtr]
sta [Bptr]
ldy #2
lda [CBptr],y
sta [Bptr],y
iny
iny
lda [CBptr],y
sta [Bptr],y
Addwl #7,CBptr
Addwl #7,Bptr
Subwl #7,Length
docopy
;Now set up the copying of text.
jsr CopyText
;Copy the ruler if necessary.
lda Type
bne noruler
MoveLong [ParRec]:#W_pRulerHand,Ruler
Cmpl Ruler,OldRuler
bne getnewruler
MoveLong [NewRuler],NRPtr
lda [NRPtr]
inc a
sta [NRPtr]
bra noruler
getnewruler
call D_NeedHand,in=(#W_RulBytes:l),out=(NewRuler:l),err=err
bcc @1
jsr DisposeCurrentBlock ;Only disposes if nothing else has used it.
brl memoryerror
@1
MoveLong [NewRuler],NRPtr
tool _BlockMove,in=([Ruler]:l,NRPtr:l,#W_RulBytes:l)
MoveWord #1,[NRPtr]
MoveLong Ruler,OldRuler
bra update
noruler Stzl Ruler
update
;Update the paragraph array. This is used for all paragraphs
MoveLong [Scrap],Sptr
AddLong Sptr,Soff,ParPtr
Addwl #W_pBytes,Soff
MoveLong Block,[ParPtr]
MoveWord NewOffset,[ParPtr]:#W_pOffset
MoveWord Type,[ParPtr]:#W_pAttr
MoveLong NewRuler,[ParPtr]:#W_pRulerHand
MoveWord #0,[ParPtr]:#W_PRulerHand+4
MoveWord a,[ParPtr]:#W_PRulerHand+6
MoveWord a,[ParPtr]:#W_PRulerHand+8
MoveWord a,[ParPtr]:#W_PRulerHand+10
lda [Sptr]
inc a
sta [Sptr]
Cmpw Par,Endp
bge massage
inc Par
brl parloop
massage call X_MassageWPScrap,in=(Scrap:l)
bra exit
memoryerror call X_DisposeWPScrap,in=Scrap:l
exit return
;This sets up several variables about the paragraph in Par. Length will be the size
;of the text. ParRec wil be the pointer to the paragraph record. OldTextPtr will
;point to the first character of text past the paragraph header. Offset will be
;the offset into the block for this character. Type will be the type of paragraph.
;Length includes the carraige return.
GetParInfo rcall W_GetParRec,in=(Par:a),out=(ParRec:ax) ;input paragraph in Par
stz Length
MoveWord [ParRec]:#W_pAttr,Type
MoveWord [ParRec]:#W_pOffset,Offset
;Find the end of the paragraph by subtracting offsets.
;Is this the first paragraph?
Cmpw Par,Startp
bne notfirst
AddWord StartO,Offset,Offset
notfirst
;Is this the last? Then this is simple.
Cmpw Par,Endp
bne notlast
cmpw Par,StartP
bne @1
Subword EndO,StartO,Length ;fucking special cases !
rts
@1
MoveWord EndO,Length
rts
;Note: Since this is not the last paragraph in the selection, it is not the last
;paragraph in the document. This takes care of one special case.
;If the next paragraph is in the same block, we subtract the offsets of the two paragraphs.
notlast MoveLong [ParRec],CurrentBlock
MoveLong [ParRec]:#W_pBytes,NextBlock
Cmpl CurrentBlock,NextBlock
bne notsameblock
SubWord [ParRec]:#W_PBytes+W_pOffset,Offset,Length
rts
;If not, we subtract the start offset from the used field in the text block.
notsameblock
MoveLong [CurrentBlock],CBPtr
SubWord [CBPtr]:#2,Offset,Length
rts
;Will allocate a new block if there is none. Will make space if there would still
;be less than 3K. Will make new text block if not. Sets up the variables Block,
;Bptr,NewOffset. Uses Length variable. Does NOT lock the block. If it is the last
;paragraph, one is added to the size for the carriage return.
GrowBlock Cpzl Block
beq newblock
MoveLong [Block],Bptr
AddWord Length,[Bptr],NewSize
Cmpw Par,EndP
bne nocrroom
inc NewSize
nocrroom Cmpw NewSize,#BlockSize
jge newblock
inc BlockUsed
call D_GrowHandle,in=(#0:w,NewSize:w,Block:l),err=err
bcc @1
rts
@1
MoveLong [Block],Bptr
MoveWord [Bptr],NewOffset
MoveWord NewSize,[Bptr]
MoveWord a,[Bptr]:#2
Addwl NewOffset,Bptr
clc
rts
newblock
;This is the first allocation
stz BlockUsed
AddWord Length,#4,NewSize
Cmpw Par,StartP
bne @3
Addwl #7,NewSize
@3 Cmpw Par,Endp
bne @2
inc NewSize
@2
call D_NeedHand,in=(#0:w,NewSize:w),out=(Block:l),err=err
bcc @1
rts
@1 MoveLong [Block],Bptr
MoveWord NewSize,[Bptr]
MoveWord a,[Bptr]:#2
MoveWord #4,NewOffset
Addwl #4,Bptr
clc
rts
;Disposes of current block if it has never been grown.
DisposeCurrentBlock
lda BlockUsed
bne @1
tool _DisposeHandle,in=(Block:l)
@1 rts
;Copies text from CBptr to Bptr filtering out date pages and time
CopyText ldy #0
shortm
loop lda Length
ora Length+1
beq addcr
lda [CBptr],y
sta [Bptr],y
cmp #CR+1
blt special
notspecial iny
lda Length
bne @1
dec Length+1
@1 dec Length
bra loop
special cmp #CR
beq docr
cmp #8
bge notspecial
cmp #5
blt changes
lda #' '
sta [Bptr],y
bra notspecial
changes cmp #1
beq dofont
dotwo longm
lda [CBptr],y
sta [Bptr],y
iny
iny
SubWord Length,#2,Length
shortm
bra loop
dofont iny
lda Length
bne @1
dec Length+1
@1 dec Length
bra dotwo
addcr lda #CR
sta [BPtr],y
docr longm
rts
ENDP
*****************************************************************************************************
; W_PasteAscii ( textptr:long, textlen:word, paragraph:word, offset:word )
;
; This routine is called to quickly paste text at the given location, without remaking the line
; handles. The text must not contain carriage returns.
;
; Note: Can return memory errors.
W_PasteAscii PROC EXPORT
input txtptr:l,txtlen:w,par:w,off:w
local addr:l
error err
begin
stz err
lda txtlen
beq exit
call W_MakeRoom,in=(par:w,off:w,txtlen:w),err=err
bcs exit
rcall W_GetAddr,in=(par:a,off:x),out=(addr:ax)
tool _BlockMove,in=(txtptr:l,addr:l,#0:w,txtlen:w)
exit return
ENDP
****************************************************************
*
* W_DeleteText(par:w,soff:w,eoff:w) -- quickly delete the text
* between the two limits, without recomputing the line
* handles.
*
****************************************************************
W_DeleteText PROC EXPORT
input par:w,soff:w,eoff:w
local sfont:l,scolor:w,efont:l,ecolor:w,fbytes:w
begin
cmpw soff,eoff
jeq exit
spaceword
spacelong
pushword par
pushword soff
jsl W_FindFont2
pulllong sfont
pullword scolor
spaceword
spacelong
pushword par
pushword eoff
jsl W_FindFont2
pulllong efont
pullword ecolor
spaceword
pushlong sfont
pushword scolor
pushlong efont
pushword ecolor
jsl W_CalcFBytes
pullword fbytes
pushword par
pushword soff
lda eoff
sec
sbc soff
sbc fbytes
pha
jsl W_LessRoom
lda par
ldx soff
jsl W_GetAddr
pushlong ax
pushlong sfont
pushword scolor
pushlong efont
pushword ecolor
jsl W_WriteFBytes
exit return
ENDP
END