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

1 line
9.1 KiB
Plaintext
Executable File

*****************************************************************************************************
; Memory.aii
;
; This file contains the routines that are called when WP is running low on memory. Currently two
; routines exist to free up memory:
;
; W_CollapseRulers - Compare all of the rulers and get rid of any duplicates.
; W_ShrinkTextBlocks - Shrink text blocks to fit the text in them.
;
*****************************************************************************************************
load 'macros.dump'
include 'driver.equ'
include 'wp.equ'
import D_Deref
import D_BeachBall
import W_SwitchData
import W_View
import W_Pptr
import W_LastP
import W_UseRuler
import W_UnUseRuler
import W_CurrentBlockHandle
import W_CurrentBlockHandle2
import W_DocLocked
import W_PHandle
import W_StartRuler
entry W_LockArrays
entry W_UnlockArrays
entry W_CompareRulers
*****************************************************************************************************
; W_CollapseRulers ( )
;
; This routine will scan all the rulers in the current WP document and make sure that no duplicate
; rulers exist. For each document part ( body, header, and footer ) call the routine to collapse the
; rulers, then restore the original document view.
W_CollapseRulers PROC EXPORT
local SPtr:l,ParPtr:l,RulerHand:l,RulerPtr:l
local TestHand:l,SPars:w,DPtr:l,DPars:w,CurView:w
begin
moveword W_View,curview
call W_SwitchData,in=(#W_NormalOn:w)
jsr DoCollapse
call W_SwitchData,in=(#W_HeaderOn:w)
jsr DoCollapse
call W_SwitchData,in=(#W_FooterOn:w)
jsr DoCollapse
call W_SwitchData,in=(CurView:w)
return
;...................................................................................................;
DoCollapse
; Get paragraph array pointer for current body part whose rulers are being collapsed. Set the
; paragraph count at the first paragraph.
movelong W_Pptr,SPtr
moveword #1,SPars
; Get first ruler in document (skip page breaks which don't have rulers).
findloop cmpw [SPtr]:#W_pAttr,#W_PgBrk
bne foundrule
addwl #W_pBytes,SPtr
inc Spars
cmpw W_LastP,Spars
bge findloop
bra goexit
; Get the ruler for the first paragraph. If ruler count is same as total number of paragraphs then
; nothing exists to be collapsed - exit.
foundrule movelong [SPtr]:#W_pRulerHand,RulerHand
movelong [RulerHand],RulerPtr
cmpw W_LastP,[RulerPtr]
bne markit
goexit brl exit
; Mark this ruler by setting the high bit of the handle. Start comparison with ruler for second
; paragraph. Point DPtr to second paragraph in paragraph array.
markit jsr MarkRuler
addword Spars,#1,Dpars
addlong Sptr,#W_pBytes,Dptr
; For each unmarked ruler repeatedly get the next ruler. Compare it with the current one. If it
; is the same then use the old ruler instead and unuse the new one.
rulerloop jsl D_BeachBall
cmpw W_LastP,Dpars
jlt nextruler
; Get next test handle. ( skip over any page breaks ).
cmpw [DPtr]:#W_pAttr,#W_PgBrk
beq nexttest
; Get handle for current paragraph. If high bit set then ruler has already been collapsed so go to
; next handle to compare. If same handle then simply mark it.
ldy #W_pRulerHand+2
lda [DPtr],y
bmi nexttest
sta TestHand+2
moveword [DPtr]:#W_pRulerHand,TestHand
cmpl TestHand,RulerHand
bne notsamehand
jsr MarkTest
bra nexttest
; Different ruler was found; now we will need to determine whether they are actually equivalent.
notsamehand call W_CompareRulers,in=(RulerHand:l,TestHand:l)
bcs nexttest
; Check if TestRuler was the current visable ruler if so we will need to update W_StartRuler.
cmpl TestHand,W_StartRuler
bne replaceit
movelong RulerHand,W_StartRuler
; Replace test ruler with source ruler. Mark test ruler so we won't look at it again.
replaceit call W_UseRuler,in=(#1:w,RulerHand:l)
call W_UnUseRuler,in=(#1:w,TestHand:l)
movelong Rulerhand,[DPtr]:#W_pRulerHand
jsr MarkTest
; Get the next unmarked ruler.
nexttest inc Dpars
addwl #W_pBytes,Dptr
brl rulerloop
; Scan for next ruler to be collapsed. Bump to next ruler and check if past last paragraph if so
; branch and unmark everything.
nextruler addwl #W_pBytes,Sptr
inc Spars
cmpw W_LastP,Spars
blt unmark
; Get next ruler to be checked. (skip over page breaks).
cmpw [SPtr]:#W_pAttr,#W_PgBrk
beq nextruler
; If ruler has already been marked then skip it; else mark the ruler and scan the remaining rulers
; for any equivalent rulers.
ldy #W_pRulerHand+2
lda [SPtr],y
bmi nextruler
moveword [SPtr]:#W_pRulerHand,RulerHand
brl markit
; Unmark all of the rulers.
unmark movelong W_Pptr,Sptr
moveword #1,Spars
unmarkloop cmpw [SPtr]:#W_pAttr,#W_PgBrk
beq unmarknext
jsr UnmarkRuler
unmarknext addwl #W_pBytes,Sptr
inc Spars
cmpw W_LastP,Spars
bge unmarkloop
exit rts
;..................................................................................................;
MarkRuler ldy #W_pRulerHand+2
lda [SPtr],y
ora #$8000
ldy #W_pRulerHand+2
sta [SPtr],y
rts
;..................................................................................................;
MarkTest ldy #W_pRulerHand+2
lda [DPtr],y
ora #$8000
ldy #W_pRulerHand+2
sta [DPtr],y
rts
;..................................................................................................;
UnmarkRuler ldy #W_pRulerHand+2
lda [SPtr],y
and #$7FFF
sta [SPtr],y
rts
;..................................................................................................;
ENDP
*****************************************************************************************************
; W_CompareRulers ( SourceRuler:long, DestRuler:long )
;
; This routine will compare the two given rulers and return a 0 is the accumulator if they are
; equal or -1 if they are not.
W_CompareRulers PROC EXPORT
input Src:l,Dest:l
local Sptr:l,Dptr:l,Tabs:w
error Result
begin
stz Result
movelong [Src],Sptr
movelong [Dest],Dptr
;In this series, y will contain the correct offset after the [Src] part is evaluated.
ldy #2
lda [Sptr],y ; W_or_Status
cmp [Dptr],y
bne dobne
iny
iny
lda [Sptr],y ; W_or_LeftM
cmp [Dptr],y
dobne bne @notequal
iny
iny
lda [Sptr],y ; W_or_IndentM
cmp [Dptr],y
bne @notequal
iny
iny
lda [Sptr],y ; W_or_RightM
cmp [Dptr],y
bne @notequal
iny
iny
lda [Sptr],y ; W_or_NumTabs
cmp [Dptr],y
bne @notequal
sta Tabs
tax
beq @exit ; exit with tabs equal if both 0.
iny
iny ; Get to first tab
@tabloop lda [SPtr],y
cmp [DPtr],y
bne @notequal
iny
iny
lda [SPtr],y
cmp [DPtr],y
bne @notequal
dec Tabs
beq @exit
iny
iny
bra @tabloop
@notequal dec Result
@exit return
ENDP
;*************************************************************************************
;
; W_ShrinkTextBlocks - make text blocks shrink to fit the text.
;
;*************************************************************************************
W_ShrinkTextBlocks PROC EXPORT
MoveWord W_View, >CurView
call W_SwitchData, in=(#W_NormalOn:w)
jsl DoShrink
call W_SwitchData, in=(#W_HeaderOn:w)
jsl DoShrink
call W_SwitchData, in=(#W_FooterOn:w)
jsl DoShrink
call W_SwitchData, in=(>CurView:w)
rtl
CurView DS.W 1
DoShrink
local OldHand:l, PArrayPtr:l,TextBlockHand:l,TBPtr:l,Size:l
local Pars:w
begin
;Get pointer to the paragraph array and the number of paragraphs. The paragraph
;array must be locked or the memory manager must be required not to move memory
;when shrinking handles.
MoveLong W_Pptr, PArrayPtr
MoveWord W_lastP, Pars
stz Size+2 ;Size is always <64K
Stzl OldHand
@ploop MoveLong [PArrayPtr], TextBlockHand ;Text block is first field in record
Cmpl TextBlockHand, OldHand
beq @next
Cmpl TextBlockHand, W_CurrentBlockHandle
beq @next
Cmpl TextBlockHand, W_CurrentBlockHandle2
beq @next
MoveLong [TextBlockHand], TBPtr
MoveWord [TBPtr]:#2,Size
tool _SetHandleSize,in=(Size:l, TextBlockHand:l)
MoveLong TextBlockHand, OldHand
MoveWord Size, [TBPtr]
@next Addwl #W_pBytes, PArrayPtr
dec Pars
bne @ploop
return
ENDP
;*****************************************************************************
;
; W_UnlockArrays - not really. Only unlock if we get zero in count
;
;*****************************************************************************
W_UnlockArrays PROC EXPORT
local CurView:w
begin
lda W_DocLocked
beq @doit
dec W_DocLocked
bne @exit
@doit MoveWord W_View,CurView
call W_SwitchData, in=(#W_NormalOn:w)
tool _HUnLock, in=(W_PHandle:l)
call W_SwitchData, in=(#W_HeaderOn:w)
tool _HUnLock, in=(W_PHandle:l)
call W_SwitchData, in=(#W_FooterOn:w)
tool _HUnLock, in=(W_PHandle:l)
@exit return
ENDP
;******************************************************************************
;
; W_LockArrays - Lock arrays if count is zero; increment count in any case
;
;******************************************************************************
W_LockArrays PROC EXPORT
local CurView:w
begin
lda W_DocLocked
bne @exit
MoveWord W_View, CurView
call W_SwitchData, in=(#W_NormalOn:w)
rcall D_Deref, in=(W_PHandle:ax), out=(W_Pptr:ax)
call W_SwitchData, in=(#W_HeaderOn:w)
rcall D_Deref, in=(W_PHandle:ax), out=(W_Pptr:ax)
call W_SwitchData, in=(#W_FooterOn:w)
rcall D_Deref, in=(W_PHandle:ax), out=(W_Pptr:ax)
call W_SwitchData, in=(CurView:w)
@exit inc W_DocLocked
return
ENDP
END