mirror of
https://github.com/marketideas/qasm.git
synced 2026-10-25 13:02:45 +00:00
Move the assembler to src/qasm. qlink links OMF 1.0 and 2.0 from a script. makeBin flattens a load file, qomf dumps OMF, and qpro builds ProDOS volumes. APW and MPW assemble through the ORCA front end. Relocatable modules emit OMF objects. Listings stay off unless -l is set. make boot assembles the GS/OS 6.0.1 ProDOS 8 kernel and BASIC.SYSTEM into an 800K volume. BASIC.SYSTEM accepts ls and pfx, and its splash reports PRODOS BASIC 2.0, copyright 1983-2026. IIGS.601.SRC is the source and the BASIC.SYSTEM oracle that image is built from.
1 line
121 KiB
NASM
1 line
121 KiB
NASM
|
|
the TE control should handle scrolling automatically, along with insertion of
|
|
text, automatically scrolls the text. insertion must be handled quickly -- no
|
|
moving of the entire text array with every character. look into background
|
|
tasks to handle recalculating of line starts, etc. the first character
|
|
inserted my be slow; as long as all the rest are fast. For now redraw every-
|
|
thing after the inserted text. later optimize to only redraw if a line wraps
|
|
and to bit-blit text instead of redrawing it. Use offscreen drawing to make
|
|
it all look smooth. provide special speedups for special cases like: single
|
|
font, fixed-width font, no word wrap, single text rectangle. allow multiple
|
|
rectangles for the text, but must develop a new way of linking them to handle
|
|
wrapping. make EVERYTHING into a control; this should be completely automatic.
|
|
Must decide how to work scroll bars with muliple text rectangles. must figure
|
|
out some way of getting keystrokes when i'm a control.
|
|
|
|
50 milliseconds maximum per char. so can do 20 chars / sec
|
|
200 mils at the beginning of a selection
|
|
100 mils per line of scrolling
|
|
500 mils per cut, copy, paste
|
|
25 mils per idle (1/40) second
|
|
|
|
********** end of notes on GS TextEdit ********** */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print off
|
|
INCLUDE 'all.macros'
|
|
INCLUDE 'E16.EVENT'
|
|
print on
|
|
INCLUDE 'GlobalRecords'
|
|
INCLUDE 'GlobalVars'
|
|
INCLUDE 'MemoryImports'
|
|
|
|
|
|
string asis
|
|
|
|
|
|
****************************************************************
|
|
;
|
|
;
|
|
; super arrays are an array of up to 8192 elements each one of which
|
|
; is a handle to up to 8192 elements
|
|
;
|
|
;
|
|
****************************************************************
|
|
|
|
|
|
|
|
****************************************************************
|
|
|
|
setupSuperCache PROC ENTRY
|
|
|
|
PushLong SuperCacheHandle ;get a pointer to the block of items
|
|
jsr DerefHandle
|
|
stax SuperLocalPtr
|
|
ldy SuperCacheIndex ;and load the current index
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
GetSuperOffset PROC EXPORT
|
|
|
|
lda SuperCacheHandle ;check to see if the cache handle is zero
|
|
ora SuperCacheHandle+2 ;..if it is, there is no cache
|
|
beq notInCache
|
|
cmp4 TextOffset,SuperCacheEndOffset ;check the current offset against the
|
|
bge notInCache ;..cache bounds
|
|
cmp4 TextOffset,SuperCacheOffset
|
|
blt notInCache
|
|
|
|
inCache MoveLong SuperCacheItem,SuperItem ;copy the cached item number
|
|
SubLong TextOffset,SuperCacheOffset,SuperOffsetLeft
|
|
jsr setupSuperCache ;setup the local pointer and index
|
|
brl localLoop
|
|
|
|
notInCache MoveLong TextOffset,SuperOffsetLeft ;setup the offset counter
|
|
stz4 SuperItem ;zero out the super item number
|
|
PushLong SuperHandle ;get a pointer to the array of handles
|
|
jsr DerefHandle
|
|
stax SuperMainPtr
|
|
mainLoop ldy #2
|
|
lda [SuperMainPtr],y
|
|
sta SuperCacheHandle+2
|
|
pha
|
|
lda [SuperMainPtr]
|
|
sta SuperCacheHandle
|
|
pha
|
|
ora SuperCacheHandle+2
|
|
beq notFound
|
|
jsr DerefHandle
|
|
stax SuperLocalPtr
|
|
ldy #2
|
|
lda [SuperLocalPtr],y
|
|
tax
|
|
lda [SuperLocalPtr]
|
|
cpx SuperOffsetLeft+2
|
|
blt skipLocal
|
|
bne doLocal
|
|
cmp SuperOffsetLeft
|
|
blt skipLocal
|
|
bne doLocal
|
|
skipLocal ldy #4
|
|
lda [SuperLocalPtr],y
|
|
clc
|
|
adc SuperItem
|
|
sta SuperItem
|
|
bcc @1
|
|
inc SuperItem+2
|
|
@1 lda SuperMainPtr
|
|
clc
|
|
adc #4
|
|
sta SuperMainPtr
|
|
bcc mainLoop
|
|
inc SuperMainPtr+2
|
|
bra mainLoop
|
|
|
|
doLocal clc
|
|
adc TextOffset
|
|
sta SuperCacheEndOffset
|
|
txa
|
|
adc TextOffset+2
|
|
sta SuperCacheEndOffset+2
|
|
SubLong SuperCacheEndOffset,SuperOffsetLeft,SuperCacheEndOffset
|
|
ldy #4
|
|
lda [SuperLocalPtr],y
|
|
clc
|
|
adc SuperItem
|
|
sta SuperCacheEndItem
|
|
lda SuperItem+2
|
|
adc #0
|
|
sta SuperCacheEndItem+2
|
|
ldy #6
|
|
localLoop lda [SuperLocalPtr],y
|
|
sta SuperLength
|
|
iny2
|
|
lda [SuperLocalPtr],y
|
|
sta SuperLength+2
|
|
cmp4 SuperLength,SuperOffsetLeft
|
|
bgt foundIt
|
|
SubLong SuperOffsetLeft,SuperLength,SuperOffsetLeft
|
|
inc4 SuperItem
|
|
iny4
|
|
bra localLoop
|
|
|
|
foundIt tya
|
|
dec A
|
|
dec A
|
|
sta SuperCacheIndex
|
|
iny2
|
|
lda [SuperLocalPtr],y
|
|
sta SuperData
|
|
SubLong SuperLength,SuperOffsetLeft,SuperLength
|
|
SubLong TextOffset,SuperOffsetLeft,SuperCacheOffset
|
|
MoveLong SuperItem,SuperCacheItem
|
|
clc
|
|
rts
|
|
|
|
notFound pla
|
|
pla
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
GetSuperItem PROC EXPORT
|
|
|
|
lda SuperCacheHandle
|
|
ora SuperCacheHandle+2
|
|
beq notInCache
|
|
cmp4 SuperItem,SuperCacheEndItem
|
|
bge notInCache
|
|
cmp4 SuperItem,SuperCacheItem
|
|
blt notInCache
|
|
|
|
inCache MoveLong SuperCacheOffset,TextOffset
|
|
SubLong SuperItem,SuperCacheItem,SuperItemsLeft
|
|
jsr setupSuperCache
|
|
brl localLoop
|
|
|
|
notInCache MoveLong SuperItem,SuperItemsLeft
|
|
stz4 TextOffset
|
|
PushLong SuperHandle
|
|
jsr DerefHandle
|
|
stax SuperMainPtr
|
|
mainLoop ldy #2
|
|
lda [SuperMainPtr],y
|
|
sta SuperCacheHandle+2
|
|
pha
|
|
lda [SuperMainPtr]
|
|
sta SuperCacheHandle
|
|
pha
|
|
ora SuperCacheHandle+2
|
|
beq notFound
|
|
jsr DerefHandle
|
|
stax SuperLocalPtr
|
|
ldy #4
|
|
lda [SuperLocalPtr],y
|
|
tax
|
|
lda SuperItemsLeft+2
|
|
bne skipLocal
|
|
cpx SuperItemsLeft
|
|
blt skipLocal
|
|
bne doLocal
|
|
skipLocal lda SuperItemsLeft
|
|
sec
|
|
sbc [SuperLocalPtr],y
|
|
sta SuperItemsLeft
|
|
lda SuperItemsLeft+2
|
|
sbc #0
|
|
sta SuperItemsLeft+2
|
|
ldy #2
|
|
lda [SuperLocalPtr]
|
|
clc
|
|
adc TextOffset
|
|
sta TextOffset
|
|
lda [SuperLocalPtr],y
|
|
adc TextOffset+2
|
|
sta TextOffset+2
|
|
lda SuperMainPtr
|
|
clc
|
|
adc #4
|
|
sta SuperMainPtr
|
|
bcc mainLoop
|
|
inc SuperMainPtr+2
|
|
bra mainLoop
|
|
|
|
doLocal txa
|
|
clc
|
|
adc SuperItem
|
|
sta SuperCacheEndItem
|
|
lda SuperItem+2
|
|
adc #0
|
|
sta SuperCacheEndItem+2
|
|
SubLong SuperCacheEndItem,SuperItemsLeft,SuperCacheEndItem
|
|
ldy #2
|
|
lda [SuperLocalPtr]
|
|
adc TextOffset
|
|
sta SuperCacheEndOffset
|
|
lda [SuperLocalPtr],y
|
|
adc TextOffset+2
|
|
sta SuperCacheEndOffset+2
|
|
ldy #6
|
|
lda SuperItemsLeft
|
|
ora SuperItemsLeft+2
|
|
beq foundIt
|
|
localLoop lda [SuperLocalPtr],y
|
|
sta SuperLength
|
|
clc
|
|
adc TextOffset
|
|
sta TextOffset
|
|
iny2
|
|
lda [SuperLocalPtr],y
|
|
sta SuperLength+2
|
|
adc TextOffset+2
|
|
sta TextOffset+2
|
|
iny4
|
|
dec SuperItemsLeft
|
|
bne localLoop
|
|
|
|
foundIt tya
|
|
dec A
|
|
dec A
|
|
sta SuperCacheIndex
|
|
iny2
|
|
lda [SuperLocalPtr],y
|
|
sta SuperData
|
|
MoveLong TextOffset,SuperCacheOffset
|
|
MoveLong SuperItem,SuperCacheItem
|
|
clc
|
|
rts
|
|
|
|
notFound pla
|
|
pla
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
SetSuperItem PROC EXPORT
|
|
|
|
lda SuperCacheHandle
|
|
ora SuperCacheHandle+2
|
|
beq notInCache
|
|
cmp4 SuperItem,SuperCacheEndItem
|
|
bge notInCache
|
|
cmp4 SuperItem,SuperCacheItem
|
|
blt notInCache
|
|
|
|
inCache SubLong SuperItem,SuperCacheItem,SuperItemsLeft
|
|
PushLong SuperCacheHandle ;get a pointer to the block of items
|
|
jsr DerefHandle
|
|
clc
|
|
adc SuperCacheIndex
|
|
sta SuperLocalPtr
|
|
stx SuperLocalPtr
|
|
bcc @1
|
|
inc SuperLocalPtr+2
|
|
@1 brl doLocal
|
|
|
|
notInCache MoveLong SuperItem,SuperItemsLeft
|
|
PushLong SuperHandle
|
|
jsr DerefHandle
|
|
stax SuperMainPtr
|
|
mainLoop ldy #2
|
|
lda [SuperMainPtr],y
|
|
pha
|
|
lda [SuperMainPtr]
|
|
pha
|
|
ora 3,s
|
|
beq notFound
|
|
jsr DerefHandle
|
|
stax SuperLocalPtr
|
|
ldy #4
|
|
lda [SuperLocalPtr],y
|
|
tax
|
|
lda SuperItemsLeft+2
|
|
bne skipLocal
|
|
cpx SuperItemsLeft
|
|
blt skipLocal
|
|
bne doLocal
|
|
skipLocal lda SuperItemsLeft
|
|
sec
|
|
sbc [SuperLocalPtr],y
|
|
sta SuperItemsLeft
|
|
lda SuperItemsLeft+2
|
|
sbc #0
|
|
sta SuperItemsLeft+2
|
|
lda SuperMainPtr
|
|
clc
|
|
adc #4
|
|
sta SuperMainPtr
|
|
bcc mainLoop
|
|
inc SuperMainPtr+2
|
|
bra mainLoop
|
|
|
|
doLocal asl SuperItemsLeft ;multiply the number of items by six
|
|
lda SuperItemsLeft
|
|
asl SuperItemsLeft
|
|
clc
|
|
adc SuperItemsLeft
|
|
clc
|
|
adc #6 ;skip the first 6 bytes in the handle
|
|
tay ;use as an index.
|
|
lda SuperLength
|
|
sta [SuperLocalPtr],y
|
|
iny
|
|
iny
|
|
lda SuperLength+2
|
|
sta [SuperLocalPtr],y
|
|
iny
|
|
iny
|
|
lda SuperData
|
|
sta [SuperLocalPtr],y
|
|
clc
|
|
rts
|
|
|
|
notFound pla
|
|
pla
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
InsertSuperItem PROC EXPORT
|
|
|
|
clc
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
RemoveSuperItem PROC EXPORT
|
|
|
|
notInCache MoveLong SuperItem,SuperItemsLeft
|
|
|
|
PushLong SuperHandle
|
|
jsr DerefHandle
|
|
stax SuperMainPtr
|
|
|
|
mainLoop ldy #2
|
|
lda [SuperMainPtr],y
|
|
pha
|
|
lda [SuperMainPtr]
|
|
pha
|
|
ora 3,s
|
|
beq notFound
|
|
jsr DerefHandle
|
|
stax SuperLocalPtr
|
|
ldy #4
|
|
lda [SuperLocalPtr],y
|
|
tax
|
|
lda SuperItemsLeft+2
|
|
bne skipLocal
|
|
cpx SuperItemsLeft
|
|
blt skipLocal
|
|
bne doLocal
|
|
skipLocal lda SuperItemsLeft
|
|
sec
|
|
sbc [SuperLocalPtr],y
|
|
sta SuperItemsLeft
|
|
lda SuperItemsLeft+2
|
|
sbc #0
|
|
sta SuperItemsLeft+2
|
|
lda SuperMainPtr
|
|
clc
|
|
adc #4
|
|
sta SuperMainPtr
|
|
bcc mainLoop
|
|
inc SuperMainPtr+2
|
|
bra mainLoop
|
|
|
|
doLocal asl SuperItemsLeft ;multiply the number of items by six
|
|
lda SuperItemsLeft
|
|
asl SuperItemsLeft
|
|
clc
|
|
adc SuperItemsLeft
|
|
clc
|
|
adc #6 ;skip the first 6 bytes in the handle
|
|
clc
|
|
adc SuperLocalPtr
|
|
sta SuperLocalPtr
|
|
bcc @1
|
|
inc SuperLocalPtr+2
|
|
@1 nop
|
|
|
|
clc
|
|
rts
|
|
|
|
notFound pla
|
|
pla
|
|
sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
END
|
|
|
|
|
|
|
|
GetSuperOffset: uses TextOffset and SuperHandle. searches the super array in SuperHandle for
|
|
the item at TextOffset. Sets the SuperItem, SuperLength, and SuperData values.
|
|
SuperLength will be the number of characters AFTER TextOffset that the data
|
|
pertains to. The SuperCache values will be used if SuperCacheHandle is non zero.
|
|
They will also be updated by this routine.
|
|
|
|
GetSuperItem: uses SuperItem and SuperHandle. Returns the SuperLength, SuperData, and
|
|
TextOffset values. The SuperCache values will be used and updated.
|
|
|
|
SetSuperItem: uses SuperHandle and SuperItem. Sets the length and data fields from SuperLength
|
|
and SuperData. The SuperCache values will be used and updated.
|
|
|
|
InsertSuperItem: uses SuperHandle and SuperItem. Inserts a new item AFTER SuperItem using
|
|
the SuperLength and SuperData values. The SuperCache values will be
|
|
used and updated.
|
|
|
|
RemoveSuperItem: uses SuperHandle and SuperItem. The item specified will be removed from the list.
|
|
The SuperCache values will be used and updated.
|
|
|
|
|
|
****************************************************************
|
|
|
|
OldDoKeystroke PROC EXPORT
|
|
|
|
IMPORT DoRightDelete
|
|
IMPORT DoLeftArrow
|
|
IMPORT DoDownArrow
|
|
IMPORT DoUpArrow
|
|
IMPORT DoCR
|
|
IMPORT DoRightArrow
|
|
IMPORT DoClear
|
|
IMPORT DoClearEOL
|
|
IMPORT DoDelete
|
|
IMPORT ScrollToSelection
|
|
IMPORT IsSelectionEmpty
|
|
IMPORT GetRecordLong
|
|
IMPORT IsItAWordBreak
|
|
IMPORT SimpleKey
|
|
IMPORT GetSelectionStart
|
|
IMPORT SetRecordLong
|
|
IMPORT AreWeWordWrapping
|
|
|
|
|
|
lda TheChar
|
|
casejmp $06,DoRightDelete ;Ctrl-F
|
|
casejmp $08,DoLeftArrow
|
|
casejmp $0A,DoDownArrow
|
|
casejmp $0B,DoUpArrow
|
|
casejmp $0D,DoCR
|
|
casejmp $15,DoRightArrow
|
|
casejmp $18,DoClear ;ctrl-X, clear
|
|
casejmp $19,DoClearEOL ;ctrl-Y
|
|
casejmp $7f,DoDelete ;Delete
|
|
|
|
normalchar PushWordSpace ;get the width of the character we
|
|
PushWord TheChar ;..inserted
|
|
_CharWidth
|
|
PullWord TheCharWidth
|
|
|
|
jsr ScrollToSelection ;scroll to the current selection.
|
|
|
|
jsr IsSelectionEmpty ;check to see if we have a selection
|
|
bcsl notEmpty
|
|
|
|
jsr AreWeWordWrapping
|
|
bcsl doSimple ;nope, so do simple case
|
|
|
|
jsr GetSelectionStart ;check to see if we are inserting into
|
|
ldy #TERecord.FirstWordEnd ;..the first word
|
|
jsr GetRecordLong
|
|
cmpl TextOffset
|
|
blt notInFirst
|
|
|
|
lda TheChar ;we are inserting into the first word
|
|
jsr IsItAWordBreak ;..so check for inserting a word break
|
|
bcc notWordBreak
|
|
|
|
ldax TextOffset ;set the first word end to the
|
|
ldy #TERecord.FirstWordEnd ;..current offset.
|
|
jsr SetRecordLong
|
|
; jsr MeasureTillOffset ;measure from the start of the line to
|
|
ldy #TERecord.FirstWordWidth ;..the current offset. Store the new width
|
|
sta [RecordPtr],y ;..in globals
|
|
bra checkPrevWrap
|
|
|
|
notWordBreak ldy #TERecord.FirstWordEnd ;increment the ending offset for the
|
|
jsr GetRecordLong ;..first word.
|
|
incl a
|
|
ldy #TERecord.FirstWordEnd ;increment the ending offset for the
|
|
jsr SetRecordLong ;re-store the value in globals
|
|
ldy #TERecord.FirstWordWidth ;add the width of the inserted character
|
|
lda [RecordPtr],y ;..to the first word width
|
|
clc ;..and re-store this in globals
|
|
adc TheCharWidth
|
|
sta [RecordPtr],y
|
|
lda WasSelectionEmpty ;if the selection was empty the width of
|
|
cmp #TRUE ;the first word INCREASED, so we don't
|
|
beq notInFirst ;need to check for wrap to the prev line
|
|
|
|
checkPrevWrap ldy #TERecord.FirstWordWidth ;get the width of the first word into
|
|
lda [RecordPtr],y ;..TempWord
|
|
sta TempWord
|
|
ldy #TERecord.PrevLineLeft ;get the number of pixels left on the
|
|
lda [RecordPtr],y ;..previous line.
|
|
cmp TempWord ;If pixels left >= word width we must
|
|
bge doComplex ;..word wrap, so call doComplex
|
|
|
|
notInFirst ldy #TERecord.LineWidth ;add the width of the character inserted
|
|
lda [RecordPtr],y ;..to the line width and re-store this
|
|
clc ;..value in globals
|
|
adc TheCharWidth
|
|
sta TempWord
|
|
sta [RecordPtr],y
|
|
ldy #TERecord.NextFirstWordWidth ;get the width of the first word on the
|
|
lda [RecordPtr],y ;..next line and check to see if it will
|
|
clc ;..fit on this line (this is necessary
|
|
adc TempWord ;..there was a non-empty selection)
|
|
sta TempWord+2 ;if this word will fit on this line, we
|
|
ldy #TERecord.WrapWidth ;..need to word wrap so call doComplex
|
|
lda [RecordPtr],y
|
|
cmp TempWord+2
|
|
bge doComplex
|
|
cmp TempWord
|
|
blt doComplex
|
|
|
|
doSimple jmp SimpleKey
|
|
|
|
notEmpty nop ;do some checks later
|
|
brk $26
|
|
|
|
doComplex nop
|
|
brk $25
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
****************************************************************
|
|
|
|
DoCR PROC EXPORT
|
|
|
|
clc
|
|
rts
|
|
|
|
oldHeight equ 0
|
|
|
|
jsr Save0_4
|
|
|
|
jsr UnhilightSelection ;hide the old cursor
|
|
jsr ScrollToSelection ;scroll to the current selection.
|
|
|
|
jsr IsSelectionEmpty ;check to see if we have a selection
|
|
bcsl doComplex
|
|
|
|
jsr GetSelectionStart
|
|
jsr FindLineInfo ;get the info for the current line
|
|
lda IsLineEndHard ;is this line ended by a CR or by end
|
|
cmp #FALSE ;..of text ? If it is not then we need
|
|
beql doComplex ;..to word wrap, so go do that.
|
|
|
|
mov LineHeight,oldHeight ;save the old line height and ascent.
|
|
|
|
jsr InsertChar ;insert the CR into the text.
|
|
jsr GetSelectionStart
|
|
incl TextOffset
|
|
jsr SetSelectionStart
|
|
jsr SetSelectionEnd
|
|
|
|
jsr AddLineBreak ;add a line break at the current TextOffset.
|
|
jsr GetSelectionStart
|
|
decl TextOffset
|
|
jsr FindLineInfo
|
|
mov LineHeight,TextHeight ;the first line new height is in TextHeight
|
|
incl TextOffset
|
|
jsr FindLineInfo ;the second line new height is in LineHeight
|
|
|
|
jsr GetViewRect
|
|
lda TextVPos ;this is the top of the line rect
|
|
clc
|
|
adc oldHeight ;this is the original line height
|
|
sta TempRect.top
|
|
|
|
lda LineHeight
|
|
clc
|
|
adc TextHeight
|
|
sec
|
|
sbc oldHeight
|
|
tax
|
|
|
|
PushZPtr TempRect
|
|
PushWord #0
|
|
phx
|
|
PushLong #0
|
|
_ScrollRect
|
|
|
|
jsr GetSelectionRect ;erase the rest of this line from the
|
|
ldy #TERecord.ViewRect.right ;..selection on.
|
|
jsr GetRecordWord
|
|
sta TempRect.right
|
|
lda TempRect.top
|
|
clc
|
|
adc TextHeight
|
|
sta TempRect.bottom
|
|
PushZPtr TempRect
|
|
_EraseRect
|
|
|
|
jsr GetSelectionStart
|
|
jsr OffsetToPoint
|
|
PushWord TextHPos
|
|
PushWord TextVPos
|
|
_MoveTo
|
|
|
|
jsr GetTextFormat ;get the format values
|
|
|
|
drawloop PushLong TextPtr
|
|
PushWord TextCount
|
|
_DrawText
|
|
lda TextCount
|
|
clc
|
|
adc TextOffset
|
|
sta TextOffset
|
|
bcc @1
|
|
inc TextOffset+2
|
|
@1 lda WhatStoppedFormat
|
|
cmp #lineBreak
|
|
beq done
|
|
cmp #endOfText
|
|
beq done
|
|
jsr GetTextFormat
|
|
bra drawloop
|
|
|
|
done jsr HilightSelection ;show the new cursor
|
|
jmp Restore0_4
|
|
|
|
doComplex brk $51
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
****************************************************************
|
|
* remove all the items from TextOffset to EndOffset
|
|
****************************************************************
|
|
RemoveSuperItems PROC EXPORT
|
|
|
|
IMPORT FindSuperInfo
|
|
|
|
PushAX ;save the super handle
|
|
jsr FindSuperInfo ;find the right spot in the super array
|
|
|
|
PushLong TextOffset ;save the starting TextOffset
|
|
|
|
addl SuperStart,SuperLength,TextOffset
|
|
cmpl TextOffset,EndOffset
|
|
bgtl nothingToDo
|
|
|
|
mov SuperLocalIndex,DestPtr ;save the local index
|
|
stzl SuperItemNumber ;use this as a counter
|
|
|
|
removeLoop lda SuperLocalIndex ;move the local index to the next
|
|
clc ;..position
|
|
adc #SuperItemSize
|
|
sta SuperLocalIndex
|
|
tay
|
|
|
|
lda [TempPtr],y ;add the new length to the original
|
|
pha ;..length. Also save the new length
|
|
clc
|
|
adc SuperLength
|
|
sta SuperLength
|
|
iny
|
|
iny
|
|
lda [TempPtr],y ;add the high word
|
|
tax
|
|
adc SuperLength+2
|
|
sta SuperLength+2
|
|
bcsl nextBlock ;if we wrapped around, we are in the
|
|
and SuperLength ;..next block
|
|
cmp #$FFFF ;if $FFFF FFFF then also in the next block
|
|
beql nextBlock
|
|
|
|
iny ;get the new height
|
|
iny
|
|
lda [TempPtr],y ;add to the original height
|
|
clc
|
|
adc LineHeight
|
|
sta LineHeight
|
|
|
|
ldy #BlockRecord.count ;update the line count field
|
|
lda [TempPtr],y
|
|
dec a
|
|
sta [TempPtr],y
|
|
incl SuperItemNumber ;increment the number of items we removed
|
|
|
|
pla ;restore the low word of the new length
|
|
clc ;move TextOffset to the next item
|
|
adc TextOffset
|
|
sta TextOffset
|
|
txa ;the high word is still in X
|
|
adc TextOffset+2
|
|
sta TextOffset+2
|
|
cmp EndOffset+2
|
|
blt removeLoop
|
|
bne done
|
|
lda TextOffset
|
|
cmp EndOffset
|
|
ble removeLoop
|
|
|
|
done ldy DestPtr ;get our original index
|
|
lda SuperLength ;copy the length into the original line.
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda SuperLength+2
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda LineHeight
|
|
sta [TempPtr],y
|
|
|
|
lda SuperLocalIndex
|
|
clc
|
|
adc #SuperItemSize
|
|
sta MoveLength
|
|
adc TempPtr
|
|
sta SourcePtr
|
|
lda TempPtr+2
|
|
adc #0
|
|
sta SourcePtr+2
|
|
|
|
lda DestPtr
|
|
adc #SuperItemSize ;carry is already clear
|
|
sta SuperLocalIndex
|
|
adc TempPtr
|
|
sta DestPtr
|
|
lda TempPtr+2
|
|
adc #0
|
|
sta DestPtr+2
|
|
|
|
ldy SuperMainIndex ;get the local handle into TempPtr
|
|
lda [MainSuperPtr],y
|
|
tax
|
|
iny
|
|
iny
|
|
lda [MainSuperPtr],y
|
|
pha ;one copy for set handle size
|
|
phx
|
|
pha ;..and one for get handle size
|
|
phx
|
|
jsr GetHandleSize
|
|
pha ;save the size (one word)
|
|
sec
|
|
sbc MoveLength
|
|
sta MoveLength
|
|
stz MoveLength+2
|
|
jsr BlockMove
|
|
pla
|
|
clc
|
|
adc DestPtr
|
|
sec
|
|
sbc SourcePtr
|
|
ldx #0
|
|
jsr SetHandleSize
|
|
|
|
nothingToDo PullLong TextOffset
|
|
PullAX ;restore the super handle
|
|
jmp FindSuperInfo ;re-position things to the new item.
|
|
|
|
nextBlock brk $33
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
|
|
; lda theOutputHandle,s
|
|
; sta OutputHandle
|
|
; lda theOutputHandle+2,s
|
|
; sta OutputHandle+2
|
|
|
|
; PushZLong OutputHandle ;resize the output handle
|
|
; ldy #TERecord.textLength
|
|
; jsr GetRecordLong
|
|
; jsr SetHandleSize
|
|
; bcs sizeError
|
|
|
|
; ldy #TERecord.textLength ;check for zero length
|
|
; lda [RecordPtr],y
|
|
; iny
|
|
; iny
|
|
; ora [RecordPtr],y
|
|
; beq skipCopy
|
|
|
|
; PushZLong OutputHandle ;deref the output handle
|
|
; jsr LockHandle
|
|
; stax DestPtr ;save the pointer in dest pointer
|
|
|
|
; jsr GetBlockListPtr
|
|
; ldy #BlockListRecord.firstItem
|
|
;copyLoop lda [MemoryPtr],y
|
|
; pha ;save the low word of block handle
|
|
; iny
|
|
; iny
|
|
; lda [MemoryPtr],y
|
|
; tax ;the high word goes in X
|
|
; and 1,s ;check for end of list
|
|
; cmp #$FFFF
|
|
; beq copyDone
|
|
; iny
|
|
; iny
|
|
; lda [MemoryPtr],y ;save the block length in move length
|
|
; sta MoveLength
|
|
; iny
|
|
; iny
|
|
; lda [MemoryPtr],y
|
|
; sta MoveLength+2
|
|
; pla
|
|
; phy ;save our current index
|
|
; jsr DerefAX ;get the source pointer
|
|
; stax SourcePtr
|
|
; jsr BlockMove ;move the data
|
|
; addl DestPtr,MoveLength,DestPtr ;bump the dest pointer forward.
|
|
; pla ;get back our index
|
|
; clc
|
|
; adc #BlockListItemSize-6
|
|
; tay
|
|
; bra copyLoop
|
|
|
|
;copyDone pla ;cleanup stack
|
|
; PushZLong OutputHandle
|
|
; jsr UnlockHandle
|
|
|
|
|
|
|
|
****************************************************************
|
|
* remove all the items from TextOffset to EndOffset
|
|
****************************************************************
|
|
RemoveSuperItems PROC EXPORT
|
|
|
|
IMPORT FindSuperInfo
|
|
|
|
PushAX ;save the super handle
|
|
jsr FindSuperInfo ;find the right spot in the super array
|
|
stzl SuperItemNumber ;use this as a counter
|
|
|
|
PushZLong TextOffset ;save the starting TextOffset
|
|
|
|
addl SuperStart,SuperLength,TextOffset
|
|
cmpl TextOffset,EndOffset
|
|
bgtl nothingToDo
|
|
|
|
mov SuperLocalIndex,DestPtr ;save the local index
|
|
|
|
removeLoop lda SuperLocalIndex ;move the local index to the next
|
|
clc ;..position
|
|
adc #SuperItemSize
|
|
sta SuperLocalIndex
|
|
tay
|
|
|
|
lda [TempPtr],y ;add the new length to the original
|
|
pha ;..length. Also save the new length
|
|
clc
|
|
adc SuperLength
|
|
sta SuperLength
|
|
iny
|
|
iny
|
|
lda [TempPtr],y ;add the high word
|
|
tax
|
|
adc SuperLength+2
|
|
sta SuperLength+2
|
|
bcsl nextBlock ;if we wrapped around, we are in the
|
|
and SuperLength ;..next block
|
|
cmp #$FFFF ;if $FFFF FFFF then also in the next block
|
|
beql nextBlock
|
|
|
|
iny ;get the new height
|
|
iny
|
|
lda [TempPtr],y ;add to the original height
|
|
clc
|
|
adc LineHeight
|
|
sta LineHeight
|
|
|
|
ldy #SuperBlockRecord.count ;update the line count field
|
|
lda [TempPtr],y
|
|
dec a
|
|
sta [TempPtr],y
|
|
incl SuperItemNumber ;increment the number of items we removed
|
|
|
|
pla ;restore the low word of the new length
|
|
clc ;move TextOffset to the next item
|
|
adc TextOffset
|
|
sta TextOffset
|
|
txa ;the high word is still in X
|
|
adc TextOffset+2
|
|
sta TextOffset+2
|
|
cmp EndOffset+2
|
|
blt removeLoop
|
|
bne done
|
|
lda TextOffset
|
|
cmp EndOffset
|
|
blt removeLoop
|
|
|
|
done ldy DestPtr ;get our original index
|
|
cpy SuperLocalIndex
|
|
beq nothingToDo
|
|
lda SuperLength ;copy the length into the original line.
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda SuperLength+2
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda LineHeight
|
|
sta [TempPtr],y
|
|
|
|
lda SuperLocalIndex
|
|
clc
|
|
adc #SuperItemSize
|
|
sta MoveLength
|
|
adc TempPtr
|
|
sta SourcePtr
|
|
lda TempPtr+2
|
|
adc #0
|
|
sta SourcePtr+2
|
|
|
|
lda DestPtr
|
|
adc #SuperItemSize ;carry is already clear
|
|
sta SuperLocalIndex
|
|
adc TempPtr
|
|
sta DestPtr
|
|
lda TempPtr+2
|
|
adc #0
|
|
sta DestPtr+2
|
|
|
|
ldy SuperMainIndex ;get the local handle into TempPtr
|
|
lda [MainSuperPtr],y
|
|
tax
|
|
iny
|
|
iny
|
|
lda [MainSuperPtr],y
|
|
pha ;one copy for set handle size
|
|
phx
|
|
pha ;..and one for get handle size
|
|
phx
|
|
jsr GetHandleSize
|
|
pha ;save the size (one word)
|
|
sec
|
|
sbc MoveLength
|
|
sta MoveLength
|
|
stz MoveLength+2
|
|
jsr BlockMove
|
|
pla
|
|
clc
|
|
adc DestPtr
|
|
sec
|
|
sbc SourcePtr
|
|
ldx #0
|
|
jsr SetHandleSize
|
|
|
|
nothingToDo PullLong TextOffset
|
|
PullAX ;restore the super handle
|
|
ldy SuperItemNumber+2
|
|
phy
|
|
ldy SuperItemNumber
|
|
phy
|
|
jsr FindSuperInfo ;re-position things to the new item.
|
|
PullAX ;return how many lines we removed
|
|
rts
|
|
|
|
nextBlock pla ;pull off trash
|
|
incl SuperLength ;adjust for the $FFFF FFFF length
|
|
lda SuperLocalIndex
|
|
sec
|
|
sbc #SuperItemSize
|
|
sta SuperLocalIndex
|
|
; cmp DestPtr
|
|
; beq skipCrunch
|
|
; brk $33 ;crunch it
|
|
|
|
movl TempPtr,TempLong
|
|
lda SuperMainIndex
|
|
clc
|
|
adc #4
|
|
sta SuperMainIndex
|
|
tay
|
|
lda [MainSuperPtr],y
|
|
sta TempPtr
|
|
iny
|
|
iny
|
|
lda [MainSuperPtr],y
|
|
sta TempPtr+2
|
|
and TempPtr
|
|
cmp #$FFFF
|
|
beq atEnd
|
|
brk $34
|
|
atEnd movl TempLong,TempPtr
|
|
lda SuperMainIndex
|
|
sec
|
|
sbc #4
|
|
sta SuperMainIndex
|
|
brl done
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
* This routine takes TextOffset as an input. TextOffset is an offset
|
|
* to the first line that changed. This line and all subsequent lines
|
|
* must be reformatted. This routine will also redraw the lines that
|
|
* it needs to. It will also scroll lines, by keeping track
|
|
* of the old TextVPos and the new TextVPos.
|
|
****************************************************************
|
|
RewrapUntilScreenEnd PROC EXPORT
|
|
|
|
ldy #TERecord.TextLength ;if there is no text, we can skip this
|
|
jsr GetRecordLong ;..entire routine - (there are no lines)
|
|
stx TempWord
|
|
ora TempWord
|
|
beql justRedraw
|
|
|
|
PushZLong TextOffset ;save the old text offset
|
|
|
|
jsr FindLineInfo ;start at the beginning of this line
|
|
lda SuperStart ;copy super start into text offset and
|
|
sta TextOffset ;..set end offset to be at the end of
|
|
clc ;..this line.
|
|
adc SuperLength
|
|
sta EndOffset
|
|
lda SuperStart+2
|
|
sta TextOffset+2
|
|
adc SuperLength+2
|
|
sta EndOffset+2
|
|
mov LineHeight,oldHeight
|
|
jsr OffsetToPoint ;find the TextVPos
|
|
lda TextVPos
|
|
clc
|
|
adc LineHeight
|
|
sta OldNextVPos ;this is the old VPos of the next line
|
|
|
|
lineLoop jsr FindNextLineBreak ;carry set means there was no line break
|
|
bcs done ;..found.
|
|
cmpl TextOffset,EndOffset
|
|
bge done
|
|
jsr GetLineSuperHandle ;get the line super pointers -- note
|
|
jsr SetupSuperPtrs ;..we must already be at the right spot
|
|
lda [TempPtr],y ;is the new length != the old length ?
|
|
cmp SuperLength ;then, we need to add a new item
|
|
bne addItem
|
|
iny
|
|
iny
|
|
lda [TempPtr],y
|
|
cmp SuperLength+2
|
|
beq checkForThru ;exactly equal means we are done.
|
|
addItem lda #$FFFF
|
|
sta addFlag
|
|
jsr GetLineSuperHandle
|
|
jsr InsertSuperItem ;insert a line at the current offset
|
|
ldy #TERecord.NumberOfLines ;increment the number of lines
|
|
jsr IncRecordLong
|
|
decl TextOffset ;move to the previous line
|
|
jsr CalculateLineHeight ;get the height
|
|
lda TextVPos ;move the new top of line down by the
|
|
clc ;..height of the previous line
|
|
adc LineHeight
|
|
sta TextVPos
|
|
incl TextOffset ;move to the new line
|
|
jsr CalculateLineHeight ;get the new height
|
|
brl lineLoop ;go back for another line
|
|
|
|
checkForThru ldy #TERecord.TextLength ;are we at the very end ?
|
|
jsr GetRecordLong
|
|
cmpl TextOffset
|
|
bne thruWrapping
|
|
decl TextOffset
|
|
jsr FindBlockInfo
|
|
jsr BlockToTextPtr
|
|
incl TextOffset
|
|
lda [TextPtr] ;was the last character a CR ?
|
|
and #$00FF
|
|
cmp #$0D
|
|
bne thruWrapping ;..nope
|
|
jsr FindLineInfo ;we are, so find the line info
|
|
cmpl SuperStart,TextOffset ;if there is alreay a new line, then
|
|
bne addItem ;..quit. otherwise, add the line
|
|
|
|
thruWrapping decl TextOffset
|
|
jsr CalculateLineHeight ;recal the line height for this line
|
|
incl TextOffset
|
|
jsr GetViewRect ;setup the scrolling rectangle
|
|
lda OldNextVPos ;start at the old next position
|
|
ldx addFlag
|
|
bne skipAdjust
|
|
sec
|
|
sbc oldHeight
|
|
clc
|
|
adc LineHeight
|
|
skipAdjust sta TempRect.top
|
|
lda TextVPos ;get the new top position of the line
|
|
clc ;..that didn't change
|
|
adc LineHeight
|
|
sta TextVPos
|
|
sec
|
|
sbc OldNextVPos
|
|
sta OldNextVPos ;save the amount to scroll
|
|
beq skipScroll
|
|
PushZPtr TempRect
|
|
PushWord #0
|
|
PushZWord OldNextVPos
|
|
PushLong #0
|
|
_ScrollRect
|
|
lda OldNextVPos
|
|
bpl skipScroll
|
|
; must redraw the bottom here
|
|
|
|
skipScroll movl TextOffset,SavedOffset
|
|
lda 1,s
|
|
sta TextOffset
|
|
lda 3,s
|
|
sta TextOffset+2
|
|
drawLoop jsr RedrawLine
|
|
cmpl TextOffset,SavedOffset
|
|
blt drawLoop
|
|
|
|
PullLong TextOffset ;restore text offset
|
|
|
|
allDone jmp Restore0_4
|
|
|
|
justRedraw jsr RedrawLine
|
|
bra allDone
|
|
|
|
ENDP
|
|
|
|
PROC
|
|
doSimple
|
|
jsr InsertChar ;put the character into the text block
|
|
jsr GetSelectionStart ;get the selection start into TextOffset
|
|
|
|
jsr GetJust
|
|
cmp #leftJust
|
|
bnel notLeftJust
|
|
|
|
jsr UnhilightSelection ;remove the selection hilighting
|
|
|
|
jsr CaretToPoint
|
|
lda TextHPos
|
|
pha ;save the old horizontal pos in TempRect
|
|
clc
|
|
adc TheCharWidth
|
|
sta TextHPos
|
|
jsr PointToCaret ;this kills TempRect
|
|
|
|
ldy #TERecord.ViewRect.right ;set the right side of the rectangle
|
|
lda [RecordPtr],y
|
|
sta TempRect.right
|
|
|
|
lda 1,s
|
|
sta TempRect.left
|
|
lda TextVPos
|
|
clc
|
|
adc LineAscent
|
|
pha
|
|
_MoveTo
|
|
|
|
jsr GetTextFormat ;get the format values
|
|
lda WhatStoppedFormat
|
|
cmp #lineBreak ;check to see if there are several styles
|
|
beq drawloop ;..in this line. If there are we want to
|
|
cmp #endOfText ;..erase the line
|
|
beq drawloop
|
|
|
|
jsr EraseTempRect
|
|
|
|
drawloop PushZLong TextPtr
|
|
PushZWord TextCount
|
|
_DrawText
|
|
lda TextCount
|
|
clc
|
|
adc TextOffset
|
|
sta TextOffset
|
|
bcc @1
|
|
inc TextOffset+2
|
|
@1 lda WhatStoppedFormat
|
|
cmp #lineBreak
|
|
beq done
|
|
cmp #endOfText
|
|
beq done
|
|
jsr GetTextFormat
|
|
bra drawloop
|
|
|
|
done lda WasSelectionEmpty
|
|
cmp #TRUE
|
|
beq allDone
|
|
|
|
PushZPtr TempLong
|
|
_GetPen
|
|
mov TempLong+2,TempRect.left
|
|
jsr EraseTempRect
|
|
|
|
allDone jsr GetSelectionStart
|
|
incl TextOffset
|
|
jsr SetSelectionStart
|
|
jsr SetSelectionEnd
|
|
jsr HilightSelection
|
|
clc
|
|
rts
|
|
|
|
notLeftJust brk $49
|
|
|
|
ENDP
|
|
****************************************************************
|
|
* remove all the line starts between TextOffset & EndOffset
|
|
* destroys TempPtr, TempWord, & TempLong
|
|
****************************************************************
|
|
RemoveLineStarts PROC EXPORT
|
|
|
|
ItemsRemoved equ SuperItemNumber
|
|
MaxLength equ EndOffset
|
|
|
|
jsr GetLineSuperHandle ;find the starting line in the super
|
|
jsr FindSuperInfo ;array.
|
|
|
|
lda SuperStart ;do a quick check to see if we are
|
|
clc ;..removing items or not. If not then
|
|
adc SuperLength ;..quickly exit.
|
|
tax
|
|
lda SuperStart+2
|
|
adc SuperLength+2
|
|
cmp EndOffset+2
|
|
blt mustRemoveItems
|
|
cpx EndOffset
|
|
bgtl nothingToDo
|
|
|
|
mustRemoveItems ldy SuperMainIndex ;save the original local handle
|
|
lda [MainSuperPtr],y
|
|
sta SuperLocalHandle
|
|
iny
|
|
iny
|
|
lda [MainSuperPtr],y
|
|
sta SuperLocalHandle+2
|
|
|
|
subl EndOffset,SuperStart,MaxLength ;we stop when SuperLength reaches MaxLength
|
|
stzl ItemsRemoved ;use this as an item counter
|
|
stzl SuperLength ;zero out SuperLength for the loop and
|
|
stz LineHeight ;..the same with line height
|
|
ldy SuperLocalIndex ;start at the current index
|
|
itemStart sty DestPtr ;save the starting index
|
|
itemLoop lda [TempPtr],y ;get the length of the current item
|
|
sta TempWord ;save it temporarily
|
|
clc ;X, A will contain the old super length
|
|
adc SuperLength ;..plus the length of the new item
|
|
tax ;..X is low, A is High
|
|
iny
|
|
iny
|
|
lda [TempPtr],y ;but first check to see if we are at
|
|
and TempWord ;..the end of a block ($FFFF FFFF)
|
|
cmp #$FFFF
|
|
beql nextBlock ;yes, goto next block
|
|
lda [TempPtr],y ;add the high word of the lengths and
|
|
clc ;..compare against the maximum length
|
|
adc SuperLength+2
|
|
cmp MaxLength+2
|
|
blt itemContinue
|
|
bne removeItems
|
|
cpx MaxLength
|
|
bge removeItems
|
|
itemContinue stx SuperLength+2 ;store the new length
|
|
sta SuperLength
|
|
iny
|
|
iny
|
|
tya
|
|
clc
|
|
adc #SuperItemSize-4
|
|
pha ;save on the stack
|
|
incl ItemsRemoved
|
|
ldy #SuperBlockRecord.count ;fix the block count field.
|
|
lda [TempPtr],y
|
|
dec a
|
|
sta [TempPtr],y
|
|
ply ;restore our index
|
|
bra itemLoop
|
|
|
|
removeItems bne skipLastItem ;check to see if we should remove the
|
|
tya ;..last item
|
|
clc
|
|
adc #SuperItemSize
|
|
pha
|
|
incl ItemsRemoved ;remove one more item.
|
|
ldy #SuperBlockRecord.count ;fix the block count field.
|
|
lda [TempPtr],y
|
|
dec a
|
|
sta [TempPtr],y
|
|
ply ;restore our index
|
|
skipLastItem dey ;adjust Y back to beginning of item
|
|
dey
|
|
sty SourcePtr
|
|
cpy DestPtr
|
|
beq skipCrunch ;is there anything to do ?
|
|
ldy SuperMainIndex ;get the current local handle
|
|
lda [MainSuperPtr],y
|
|
pha
|
|
iny
|
|
iny
|
|
lda [MainSuperPtr],y
|
|
tax
|
|
pla
|
|
jsr crunchIt ;crunch it.
|
|
skipCrunch PushZLong SuperLocalHandle ;dereference the orginal handle
|
|
jsr DerefHandle
|
|
stax TempPtr
|
|
ldy SuperLocalIndex
|
|
lda SuperLength
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda SuperLength+2
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda LineHeight
|
|
sta [TempPtr],y
|
|
ldy #TERecord.NumberOfLines ;adjust the number of lines in the record
|
|
lda [RecordPtr],y
|
|
sec
|
|
sbc ItemsRemoved
|
|
sta [RecordPtr],y
|
|
iny
|
|
iny
|
|
lda [RecordPtr],y
|
|
sbc ItemsRemoved+2
|
|
sta [RecordPtr],y
|
|
nothingToDo rts ;go back to caller
|
|
|
|
nextBlock lda #$FFFF ;on next block, mark line height overflow
|
|
sta LineHeight
|
|
lda SuperLocalIndex ;move just past the starting line
|
|
clc
|
|
adc #SuperItemSize
|
|
tay
|
|
jsr TerminateTempPtr ;terminate our original block
|
|
iny
|
|
iny
|
|
tya
|
|
ldx #0
|
|
PushZLong SuperLocalHandle ;resize the original handle
|
|
jsr SetHandleSize
|
|
|
|
lda SuperMainIndex ;save the destination index for the
|
|
clc ;..crunch
|
|
adc #4
|
|
sta DestPtr
|
|
blockLoop lda SuperMainIndex ;move the main index to the next handle
|
|
clc
|
|
adc #4
|
|
sta SuperMainIndex
|
|
tay
|
|
lda [MainSuperPtr],y ;save the local handle in tempPtr
|
|
sta TempPtr
|
|
iny
|
|
iny
|
|
lda [MainSuperPtr],y
|
|
sta TempPtr+2
|
|
and TempPtr
|
|
cmp #$FFFF
|
|
beq atEnd
|
|
PushZLong TempPtr ;save the local handle
|
|
jsr DerefTempPtr
|
|
ldy #SuperBlockRecord.length
|
|
lda [TempPtr],y
|
|
clc
|
|
adc SuperLength
|
|
tax
|
|
iny
|
|
iny
|
|
lda [TempPtr],y
|
|
adc SuperLength+2
|
|
cmp MaxLength+2
|
|
blt blockContinue
|
|
bne removeBlocks
|
|
cpx MaxLength
|
|
bge removeBlocks
|
|
blockContinue stx SuperLength
|
|
sta SuperLength+2
|
|
ldy #SuperBlockRecord.count
|
|
lda [TempPtr],y
|
|
clc
|
|
adc ItemsRemoved
|
|
sta ItemsRemoved
|
|
bcc @1
|
|
inc ItemsRemoved+2
|
|
@1 PullAX
|
|
jsr KillHandle ;kill the handle on the stack
|
|
bra blockLoop
|
|
|
|
atEnd jsr GetLineSuperHandle ;get the main line super handle
|
|
PushAX ;put it on the stack
|
|
ldy DestPtr
|
|
lda #$FFFF
|
|
sta [MainSuperPtr],y
|
|
iny
|
|
iny
|
|
sta [MainSuperPtr],y
|
|
iny
|
|
iny
|
|
ldx #0 ;high word is always zero
|
|
tya ;this is the low word
|
|
jsr SetHandleSize
|
|
brl skipCrunch
|
|
|
|
removeBlocks bne skipLast ;if equal, we want to remove this block too
|
|
PullAX
|
|
jsr KillHandle ;kill the last handle
|
|
stzl TempPtr ;set our last flag
|
|
lda SuperMainIndex ;saves bytes
|
|
bra crunchMain
|
|
skipLast PullLong TempPtr ;pull off the handle into temp pointer
|
|
lda SuperMainIndex ;move the index back
|
|
sec
|
|
sbc #4
|
|
crunchMain sta SourcePtr
|
|
jsr GetLineSuperHandle ;get the main line super handle
|
|
jsr crunchIt
|
|
|
|
lda TempPtr ;are we all through ?
|
|
ora TempPtr+2
|
|
beq allDone
|
|
jsr DerefTempPtr ;get the local pointer
|
|
ldy #SuperBlockRecord.firstItem ;start at the first item and go back to
|
|
brl itemStart ;..the item loop
|
|
|
|
allDone rts
|
|
|
|
crunchIt PushAX ;(handle comes in in A,X) - GetHandleSize
|
|
PushAX ;one copy for DerefHandle
|
|
PushAX ;one copy for DerefHandle
|
|
PushAX ;one copy for SetHandleSize
|
|
jsr GetHandleSize
|
|
sec
|
|
sbc SourcePtr
|
|
sta MoveLength ;this is the length to move
|
|
stz MoveLength
|
|
clc
|
|
adc DestPtr ;calculate the new size for the handle
|
|
pha ;..and save it on the stack
|
|
jsr DerefHandle ;add the starting pointer to the source
|
|
clc ;..index
|
|
adc SourcePtr
|
|
sta SourcePtr
|
|
bcc @1
|
|
inx
|
|
@1 stx SourcePtr+2
|
|
jsr DerefHandle ;add the starting pointer to the dest
|
|
clc ;..index
|
|
adc DestPtr
|
|
sta DestPtr
|
|
bcc @2
|
|
inx
|
|
@2 stx DestPtr+2
|
|
jsr BlockMove ;move the data
|
|
pla ;recover the new size and set the size of
|
|
ldx #0 ;..the handle
|
|
jsr SetHandleSize
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
CalculateLineHeight PROC EXPORT
|
|
|
|
PushZLong EndOffset ;save the original ending offset
|
|
PushZLong TextOffset ;save the original text offset
|
|
|
|
jsr FindLineInfo
|
|
stz LineHeight
|
|
stz LineAscent
|
|
lda SuperStart
|
|
sta TextOffset
|
|
clc
|
|
adc SuperLength
|
|
sta EndOffset
|
|
lda SuperStart+2
|
|
sta TextOffset+2
|
|
adc SuperLength+2
|
|
sta EndOffset+2
|
|
heightLoop jsr FindStyleInfo ;find the new style information
|
|
lda SuperData ;see, if there is a new style item
|
|
cmp TextStyleItem
|
|
beq skipSetStyle ;nope = skip this
|
|
sta TextStyleItem ;yes, so setup the values
|
|
jsr InstallStyleItem
|
|
skipSetStyle lda TextHeight
|
|
cmp LineHeight
|
|
blt @1
|
|
sta LineHeight
|
|
@1 lda TextAscent
|
|
cmp LineAscent
|
|
blt @2
|
|
sta LineAscent
|
|
@2 addl SuperStart,SuperLength,TextOffset
|
|
cmpl TextOffset,EndOffset
|
|
blt heightLoop
|
|
|
|
mov LineHeight,SuperData
|
|
mov LineAscent,SuperData+2
|
|
jsr GetLineSuperHandle
|
|
jsr SetSuperData
|
|
PullLong TextOffset ;restore the original text offset
|
|
PullLong EndOffset ;restore the original ending offset
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
* This routine takes TextOffset as an input. TextOffset is an offset
|
|
* to the first line that changed. This line and all subsequent lines
|
|
* must be reformatted. This routine will also redraw the lines that
|
|
* it needs to. It will also scroll lines, by keeping track
|
|
* of the old TextVPos and the new TextVPos.
|
|
****************************************************************
|
|
RewrapLines PROC EXPORT
|
|
|
|
addFlag equ 0
|
|
oldHeight equ 2
|
|
|
|
jsr Save0_4
|
|
|
|
stz addFlag ;this is for scrolling adjustment
|
|
|
|
ldy #TERecord.TextLength ;if there is no text, we can skip this
|
|
jsr GetRecordLong ;..entire routine - (there are no lines)
|
|
stx TempWord
|
|
ora TempWord
|
|
beql justRedraw
|
|
jsr AreWeWordWrapping
|
|
bcc simple ;nope
|
|
|
|
complex brk $4A ;needs more work.
|
|
|
|
simple PushZLong TextOffset ;save the starting text offset
|
|
jsr FindLineInfo ;move the offset to the beginning of the
|
|
movl SuperStart,TextOffset ;..current line
|
|
mov LineHeight,oldHeight
|
|
jsr OffsetToPoint ;find the TextVPos
|
|
lda TextVPos
|
|
clc
|
|
adc LineHeight
|
|
sta OldNextVPos ;this is the old VPos of the next line
|
|
|
|
blockLoopStart stzl SuperLength ;zero out the length field
|
|
blockLoop jsr FindBlockInfo ;get the text pointer
|
|
jsr BlockToTextPtr
|
|
lda BlockCount ;are we done ?
|
|
beql thruWrapping
|
|
|
|
ldy #0 ;search for a CR.
|
|
shortm
|
|
findCRLoop lda [TextPtr],y
|
|
cmp #$0D
|
|
beq foundCR
|
|
iny
|
|
cpy BlockCount
|
|
blt findCRLoop
|
|
|
|
longm
|
|
tya ;move the text offset forward by block
|
|
clc ;..count
|
|
adc TextOffset ;(Y is the block count)
|
|
sta TextOffset
|
|
bcc @1
|
|
inc TextOffset+2
|
|
@1 tya ;add block count to the new line length
|
|
clc ;(Y is the block count)
|
|
adc SuperLength
|
|
sta SuperLength
|
|
bcc @2
|
|
inc SuperLength+2
|
|
@2 ldy #TERecord.TextLength ;are we at the end of the text ?
|
|
jsr GetRecordLong ;..nope so go back to the block loop
|
|
cmp TextOffset
|
|
bne blockLoop
|
|
cpx TextOffset+2
|
|
bne blockLoop
|
|
brl checkLine ;we are done if we are at the end
|
|
|
|
foundCR longm ;back to long mode
|
|
tya ;where were we at ?
|
|
sec ;skip over the CR
|
|
adc TextOffset ;move the text offset to the new spot.
|
|
sta TextOffset
|
|
bcc @1
|
|
inc TextOffset+2
|
|
@1 tya ;add to the length.
|
|
sec
|
|
adc SuperLength
|
|
sta SuperLength
|
|
bcc checkLine
|
|
inc SuperLength+2
|
|
|
|
checkLine jsr GetLineSuperHandle ;get the line super pointers -- note
|
|
jsr SetupSuperPtrs ;..we must already be at the right spot
|
|
lda [TempPtr],y ;is the new length != the old length ?
|
|
cmp SuperLength ;then, we need to add a new item
|
|
bne addItem
|
|
iny
|
|
iny
|
|
lda [TempPtr],y
|
|
cmp SuperLength+2
|
|
beq checkForThru ;exactly equal means we are done.
|
|
|
|
addItem lda #$FFFF
|
|
sta addFlag
|
|
jsr GetLineSuperHandle
|
|
jsr InsertSuperItem ;insert a line at the current offset
|
|
ldy #TERecord.NumberOfLines ;increment the number of lines
|
|
jsr IncRecordLong
|
|
decl TextOffset ;move to the previous line
|
|
jsr CalculateLineHeight ;get the height
|
|
lda TextVPos ;move the new top of line down by the
|
|
clc ;..height of the previous line
|
|
adc LineHeight
|
|
sta TextVPos
|
|
incl TextOffset ;move to the new line
|
|
jsr CalculateLineHeight ;get the new height
|
|
brl blockLoopStart ;go back for another line
|
|
|
|
checkForThru ldy #TERecord.TextLength ;are we at the very end ?
|
|
jsr GetRecordLong
|
|
cmpl TextOffset
|
|
bne thruWrapping
|
|
decl TextOffset
|
|
jsr FindBlockInfo
|
|
jsr BlockToTextPtr
|
|
incl TextOffset
|
|
lda [TextPtr] ;was the last character a CR ?
|
|
and #$00FF
|
|
cmp #$0D
|
|
bne thruWrapping ;..nope
|
|
jsr FindLineInfo ;we are, so find the line info
|
|
cmpl SuperStart,TextOffset ;if there is alreay a new line, then
|
|
bne addItem ;..quit. otherwise, add the line
|
|
|
|
thruWrapping decl TextOffset
|
|
jsr CalculateLineHeight ;recal the line height for this line
|
|
incl TextOffset
|
|
jsr GetViewRect ;setup the scrolling rectangle
|
|
lda OldNextVPos ;start at the old next position
|
|
ldx addFlag
|
|
bne skipAdjust
|
|
sec
|
|
sbc oldHeight
|
|
clc
|
|
adc LineHeight
|
|
skipAdjust sta TempRect.top
|
|
lda TextVPos ;get the new top position of the line
|
|
clc ;..that didn't change
|
|
adc LineHeight
|
|
sta TextVPos
|
|
sec
|
|
sbc OldNextVPos
|
|
sta OldNextVPos ;save the amount to scroll
|
|
beq skipScroll
|
|
PushZPtr TempRect
|
|
PushWord #0
|
|
PushZWord OldNextVPos
|
|
PushLong #0
|
|
_ScrollRect
|
|
lda OldNextVPos
|
|
bpl skipScroll
|
|
; must redraw the bottom here
|
|
|
|
skipScroll movl TextOffset,SavedOffset
|
|
lda 1,s
|
|
sta TextOffset
|
|
lda 3,s
|
|
sta TextOffset+2
|
|
drawLoop jsr RedrawLine
|
|
cmpl TextOffset,SavedOffset
|
|
blt drawLoop
|
|
|
|
PullLong TextOffset ;restore text offset
|
|
|
|
allDone jmp Restore0_4
|
|
|
|
justRedraw jsr RedrawLine
|
|
bra allDone
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
INCLUDE 'GlobalIncludes'
|
|
|
|
|
|
****************************************************************
|
|
|
|
DebugPrintMain PROC EXPORT
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
jsr SetupDebugPrint
|
|
|
|
PushWord #10
|
|
PushWord #20
|
|
_MoveTo
|
|
PushWord Value1
|
|
PushLong #tempStr
|
|
PushWord #5
|
|
PushWord #1
|
|
_Int2Dec
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
|
|
PushWord #110
|
|
PushWord #20
|
|
_MoveTo
|
|
PushWord Value2
|
|
PushLong #tempStr
|
|
PushWord #5
|
|
PushWord #1
|
|
_Int2Dec
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
|
|
PushWord #210
|
|
PushWord #20
|
|
_MoveTo
|
|
PushWord Value3
|
|
PushLong #tempStr
|
|
PushWord #5
|
|
PushWord #1
|
|
_Int2Dec
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
|
|
PushWord #310
|
|
PushWord #20
|
|
_MoveTo
|
|
PushWord Value4
|
|
PushLong #tempStr
|
|
PushWord #5
|
|
PushWord #1
|
|
_Int2Dec
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
|
|
jsr RestoreDebugPrint
|
|
plb
|
|
rts
|
|
|
|
EXPORT Value1,Value2,Value3,Value4
|
|
Value1 ds.w 1
|
|
Value2 ds.w 1
|
|
Value3 ds.w 1
|
|
Value4 ds.w 1
|
|
|
|
tempStr ds.b 5
|
|
dc.b ' ',0
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
DebugPrintDefProc PROC EXPORT
|
|
|
|
DefineStack ;these are our direct page variables
|
|
OrigB byte ;..for the defproc
|
|
OrigD word
|
|
RTL block 3
|
|
theControlHandle long
|
|
ctrlParam long
|
|
ctrlMessage word
|
|
result long
|
|
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
jsr SetupDebugPrint
|
|
|
|
inc debugCount
|
|
|
|
PushWord #100
|
|
PushWord #10
|
|
_MoveTo
|
|
|
|
PushLong #mess1
|
|
_DrawCString
|
|
lda ctrlMessage
|
|
jsr DrawHexWord
|
|
|
|
PushLong #mess2
|
|
_DrawCString
|
|
ldax ctrlParam
|
|
jsr DrawHexLong
|
|
|
|
PushLong #mess3
|
|
_DrawCString
|
|
ldax theControlHandle
|
|
jsr DrawHexLong
|
|
|
|
PushLong #mess4
|
|
_DrawCString
|
|
PushWord debugCount
|
|
PushLong #tempStr
|
|
PushWord #4
|
|
PushWord #0 ;not signed
|
|
_Int2Dec
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
|
|
lda ctrlMessage
|
|
cmp #0
|
|
bra done
|
|
|
|
loop PushWordSpace ;pause for a key
|
|
PushWord #$000A
|
|
PushLong #extraRecord
|
|
_GetNextEvent
|
|
pla
|
|
beq loop
|
|
|
|
done jsr RestoreDebugPrint
|
|
plb
|
|
rts
|
|
|
|
mess1 dc.b 'Message = $',0
|
|
mess2 dc.b ', Parameter = $',0
|
|
mess3 dc.b ', Handle = $',0
|
|
mess4 dc.b ', ',0
|
|
|
|
extraRecord ds.b 32
|
|
debugCount dc.w 0
|
|
tempStr ds.b 4
|
|
dc.b 0
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
SetupDebugPrint PROC EXPORT
|
|
|
|
EXPORT SetDebugPort
|
|
EXPORT RestoreDebugPrint
|
|
|
|
;---------------------------------------------------------------
|
|
|
|
PullWord returnAddr
|
|
|
|
PushLongSpace ;save the old port
|
|
_GetPort
|
|
|
|
PushLong DebugPort
|
|
_SetPort
|
|
|
|
PushLongSpace
|
|
_GetVisHandle ;leave it on the stack
|
|
|
|
PushLongSpace
|
|
_NewRgn
|
|
lda 3,s
|
|
tax
|
|
lda 1,s
|
|
PushAX ;save three total copies on the stack
|
|
PushAX
|
|
PushWord #-2000
|
|
PushWord #-2000
|
|
PushWord #2000
|
|
PushWord #2000
|
|
_SetRectRgn ;use first copy
|
|
_SetVisHandle ;use second copy
|
|
|
|
PushLong #clearRect
|
|
_EraseRect
|
|
|
|
PushWord returnAddr
|
|
rts
|
|
|
|
;---------------------------------------------------------------
|
|
SetDebugPort
|
|
phb
|
|
phk
|
|
plb
|
|
stax DebugPort
|
|
plb
|
|
rts
|
|
|
|
;---------------------------------------------------------------
|
|
RestoreDebugPrint
|
|
PullWord returnAddr
|
|
|
|
_DisposeRgn ;dispose our clipping region
|
|
_SetVisHandle
|
|
_SetPort ;restore the port
|
|
|
|
PushWord returnAddr
|
|
rts
|
|
|
|
;---------------------------------------------------------------
|
|
|
|
returnAddr ds.w 1
|
|
clearRect dc.w 0,0,28,640
|
|
DebugPort ds.l 1
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
* the value to be draw comes in in A
|
|
****************************************************************
|
|
DrawHexWord PROC EXPORT
|
|
|
|
phb ;save the data bank
|
|
phk ;set it to ours
|
|
plb
|
|
|
|
PushLongSpace
|
|
pha
|
|
_HexIt
|
|
PullLong tempStr
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
|
|
plb ;restore the data bank
|
|
rts
|
|
|
|
tempStr ds.b 4
|
|
dc.b 0
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
* the value to be draw comes in in A and X
|
|
****************************************************************
|
|
DrawHexLong PROC EXPORT
|
|
|
|
phb ;save the data bank
|
|
phk ;set it to ours
|
|
plb
|
|
|
|
PushLongSpace ;save low word for later
|
|
pha
|
|
PushLongSpace ;do high word first.
|
|
phx
|
|
_HexIt
|
|
PullLong tempStr
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
_HexIt ;now do the low word
|
|
PullLong tempStr
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
|
|
plb ;restore the data bank
|
|
rts
|
|
|
|
tempStr ds.b 4
|
|
dc.b 0
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
****************************************************************
|
|
* This routine takes TextOffset as an input and returns the
|
|
* top of the line in TextVPos and the left of the character in
|
|
* TextHPos
|
|
****************************************************************
|
|
OffsetToPoint PROC EXPORT
|
|
|
|
originalOffset equ 0
|
|
myCounter equ 0
|
|
|
|
jsr Save0_4 ;get space for our locals
|
|
|
|
movl TextOffset,originalOffset ;save this for later
|
|
|
|
ldy #TERecord.ViewRect.top
|
|
jsr GetRecordLong ;this gets both the top and left
|
|
sta TextVPos ;this is the top
|
|
stx TextHPos ;this is the left
|
|
|
|
ldy #TERecord.VertScrollPos ;this is the offset for the top of the
|
|
jsr GetRecordLong ;..screen.
|
|
stax TextOffset
|
|
|
|
lineLoop jsr FindLineInfo ;get information on the line
|
|
lda TextOffset
|
|
clc
|
|
adc SuperLength
|
|
tax ;save in X
|
|
sta TextOffset
|
|
lda TextOffset+2
|
|
adc SuperLength+2
|
|
sta TextOffset+2
|
|
cmp originalOffset+2
|
|
blt keepGoing
|
|
bne foundLine
|
|
cpx originalOffset
|
|
blt keepGoing
|
|
bne foundLine
|
|
checkEnd ldy #TERecord.NumberOfLines+2
|
|
lda [RecordPtr],y
|
|
cmp LineNumber+2
|
|
bne keepGoing
|
|
dey
|
|
dey
|
|
lda [RecordPtr],y
|
|
cmp LineNumber
|
|
beq foundLine
|
|
keepGoing lda TextVPos ;add the line height to TextVPos
|
|
clc
|
|
adc LineHeight
|
|
sta TextVPos
|
|
bra lineLoop
|
|
|
|
foundLine movl SuperStart,TextOffset ;start at the beginning of this line
|
|
lda originalOffset
|
|
sec
|
|
sbc TextOffset
|
|
sta myCounter
|
|
lda originalOffset+2
|
|
sbc TextOffset+2
|
|
sta myCounter+2
|
|
|
|
jsr GetLeftMargin ;later on, we need to test for stuff
|
|
clc ;..like left just, etc
|
|
adc TextHPos
|
|
sta TextHPos
|
|
|
|
jsr SetupWidthTable ;setup the width table pointer
|
|
|
|
mainLoop jsr GetTextFormat
|
|
lda myCounter+2
|
|
bne skipCheck
|
|
lda myCounter
|
|
beq done
|
|
cmp TextCount
|
|
bge skipCheck
|
|
sta TextCount
|
|
skipCheck lda myCounter
|
|
sec
|
|
sbc TextCount
|
|
sta myCounter
|
|
bcs @1
|
|
dec myCounter+2
|
|
@1 lda #0
|
|
shortm
|
|
ldx TextCount
|
|
bra loopEnd
|
|
widthLoop txy
|
|
lda [TextPtr],y
|
|
tay
|
|
lda [WidthTablePtr],y
|
|
clc
|
|
adc TextHPos
|
|
sta TextHPos
|
|
bcc loopEnd
|
|
inc TextHPos+1
|
|
loopEnd dex
|
|
bne widthLoop
|
|
lda [TextPtr] ;do the last one.
|
|
tay
|
|
lda [WidthTablePtr],y
|
|
longm ;back to long mode here
|
|
clc
|
|
adc TextHPos
|
|
sta TextHPos
|
|
lda TextOffset
|
|
clc
|
|
adc TextCount
|
|
sta TextOffset
|
|
bcc @2
|
|
inc TextOffset+2
|
|
@2 lda myCounter
|
|
ora myCounter+2
|
|
bne mainLoop
|
|
|
|
done jsr FreeWidthTable ;unlock the width table
|
|
jmp Restore0_4
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
* This routine takes TextOffset as an input. It draws the line
|
|
* from TextOffset to the end if it is left justified; otherwise
|
|
* it draws the entire line.
|
|
****************************************************************
|
|
RedrawLine PROC EXPORT
|
|
|
|
jsr FindLineInfo
|
|
|
|
jsr GetJust ;get the current justification
|
|
cmp #leftJust
|
|
beq doLeft
|
|
|
|
movl SuperStart,TextOffset
|
|
jsr OffsetToPoint
|
|
jsr MeasureLineWidth
|
|
sta TextHPos
|
|
jsr GetLeftEdge
|
|
pha
|
|
jsr GetRightMargin
|
|
sec
|
|
sbc 1,s
|
|
plx
|
|
; sta WrapWidth
|
|
|
|
doLeft lda TextHPos ;position the cursor for drawing
|
|
sta TempRect.left
|
|
pha
|
|
lda TextVPos
|
|
sta TempRect.top
|
|
clc
|
|
adc LineAscent
|
|
pha
|
|
_MoveTo
|
|
|
|
drawloop jsr GetTextFormat ;get the format values
|
|
ldy #o_PnLoc+2 ;get the horizontal pen position before
|
|
lda [GrafPortPtr],y ;..the draw operation
|
|
sta TempRect.left
|
|
PushZLong TextPtr
|
|
PushZWord TextCount
|
|
_DrawText
|
|
lda TextCount
|
|
clc
|
|
adc TextOffset
|
|
sta TextOffset
|
|
bcc @1
|
|
inc TextOffset+2
|
|
@1 lda WhatStoppedFormat
|
|
cmp #lineBreak
|
|
beq done
|
|
cmp #endOfText
|
|
beq done
|
|
cmp #styleBreak ;if not style break then loop back
|
|
bne drawloop
|
|
lda LineAscent
|
|
sec
|
|
sbc TextAscent
|
|
beq drawLoop
|
|
clc
|
|
adc TextVPos
|
|
sta TempRect.bottom
|
|
ldy #o_PnLoc+2 ;horizontal pen position
|
|
lda [GrafPortPtr],y
|
|
sta TempRect.right
|
|
jsr EraseTempRect
|
|
bra drawloop
|
|
|
|
done ldy #o_PnLoc+2 ;horizontal pen position
|
|
lda [GrafPortPtr],y ;erase the rest of the line
|
|
sta TempRect.left
|
|
lda TempRect.top
|
|
clc
|
|
adc LineHeight
|
|
sta TempRect.bottom
|
|
ldy #TERecord.ViewRect.right
|
|
lda [RecordPtr],y
|
|
sta TempRect.right
|
|
jsr EraseTempRect
|
|
clc
|
|
rts
|
|
|
|
ENDP
|
|
****************************************************************
|
|
|
|
DoDelete PROC EXPORT
|
|
|
|
jsr UnhilightSelection ;remove the selection from the screen
|
|
|
|
jsr GetSelectionStart ;where are we ?
|
|
lda TextOffset
|
|
ora TextOffset+2
|
|
beql allDone
|
|
|
|
decl TextOffset ;move back one character
|
|
jsr SetSelectionStart ;set the new cursor offset.
|
|
jsr SetSelectionEnd
|
|
|
|
ldax TextOffset
|
|
; jsr DeleteChar ;remove this character from the block
|
|
|
|
; lda TextOffset ;we need to find some way to fix
|
|
; ora TextOffset+2 ;..this bug without kludges
|
|
; beq skip
|
|
; decl TextOffset
|
|
skip
|
|
; jsr RewrapLines
|
|
|
|
jsr GetSelectionStart ;set the new cursor position.
|
|
jsr OffsetToPoint
|
|
jsr PointToCaret
|
|
|
|
allDone jsr HilightSelection
|
|
clc
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
InsertChar PROC EXPORT
|
|
|
|
jsr GetSelectionStart ;get the selection start into TextOffset
|
|
jsr FindBlockInfo ;get block info for the current selection
|
|
|
|
subl TextOffset,BlockStart,SourcePtr ;the number of chars before the insert
|
|
subl BlockLength,SourcePtr,MoveLength ;calculate the number of chars to move
|
|
incl BlockLength ;increment the block length and re-store
|
|
jsr SetBlockSize ;..it in the block list
|
|
|
|
ldy #2 ;add the start of the block to source ptr
|
|
lda [BlockHandle]
|
|
clc
|
|
adc SourcePtr
|
|
sta SourcePtr
|
|
lda [BlockHandle],y
|
|
adc SourcePtr+2
|
|
sta SourcePtr+2
|
|
ldax SourcePtr ;copy source ptr to dest ptr. dest will be
|
|
inc a ;..one greater than source, so as to make
|
|
bne @1 ;..space for one character.
|
|
inx
|
|
@1 stax DestPtr
|
|
jsr BlockMove
|
|
shortm
|
|
lda TheChar ;store the character in the text
|
|
sta [SourcePtr]
|
|
longm
|
|
|
|
ldy #TERecord.TextLength ;increment the text length
|
|
jsr IncRecordLong
|
|
|
|
jsr FindLineInfo ;bump the line length counter by one
|
|
incl SuperLength
|
|
jsr SetLineLength
|
|
|
|
ldy #TERecord.monoStyle
|
|
lda [RecordPtr],y
|
|
cmp #TRUE
|
|
beq skipStyle
|
|
|
|
jsr FindStyleInfo ;bump the style length counter by one
|
|
incl SuperLength
|
|
jsr SetStyleInfo ;..since we didn't add any lines.
|
|
|
|
skipStyle clc
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
DeleteChar PROC EXPORT
|
|
|
|
jsr GetSelectionStart ;get the selection start into TextOffset
|
|
jsr FindBlockInfo ;get block info for the current selection
|
|
|
|
subl TextOffset,BlockStart,DestPtr ;the number of chars before the delete
|
|
subl BlockLength,DestPtr,MoveLength ;calculate the number of chars to move
|
|
decl MoveLength
|
|
|
|
ldy #2 ;add the start of the block to source ptr
|
|
lda [BlockHandle]
|
|
clc
|
|
adc DestPtr
|
|
sta DestPtr
|
|
lda [BlockHandle],y
|
|
adc DestPtr+2
|
|
sta DestPtr+2
|
|
ldax DestPtr ;copy source ptr to dest ptr. dest will be
|
|
inc a ;..one greater than source, so as to make
|
|
bne @1 ;..space for one character.
|
|
inx
|
|
@1 stax SourcePtr
|
|
jsr BlockMove
|
|
|
|
decl BlockLength ;decrement the block length and re-store
|
|
jsr SetBlockSize ;..it in the block list
|
|
|
|
ldy #TERecord.TextLength
|
|
lda [RecordPtr],y
|
|
dec a
|
|
sta [RecordPtr],y
|
|
cmp #$FFFF
|
|
bne @2
|
|
iny
|
|
iny
|
|
lda [RecordPtr],y
|
|
dec a
|
|
sta [RecordPtr],y
|
|
|
|
@2 jsr FindLineInfo ;bump the line length counter by one
|
|
decl SuperLength
|
|
jsr SetLineLength
|
|
|
|
ldy #TERecord.monoStyle
|
|
lda [RecordPtr],y
|
|
cmp #TRUE
|
|
beq skipStyle
|
|
|
|
jsr FindStyleInfo ;bump the style length counter by one
|
|
decl SuperLength
|
|
jsr SetStyleInfo
|
|
|
|
skipStyle clc
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
END
|
|
;---------------------------------------------------------------
|
|
; Quickdraw equates...stolen directly from the qd.equate file. Maybe later
|
|
; use QD's actual file.
|
|
;---------------------------------------------------------------
|
|
DSECT $00
|
|
|
|
o_PortSCB word
|
|
o_ImageRef long
|
|
o_Width word
|
|
o_BoundsRect block 8
|
|
o_PortRect block 8
|
|
|
|
o_ClipRgn long ;start of the stuff that we save
|
|
o_VisRgn long
|
|
|
|
o_BkPat block 32
|
|
|
|
o_PnLoc long
|
|
o_PnSize long
|
|
o_PnMode word
|
|
o_PnPat block 32
|
|
o_PnMask block 8
|
|
o_PnVis word
|
|
|
|
o_Font long
|
|
o_FontID long
|
|
o_FontFlags word
|
|
o_TxSize word
|
|
o_TxFace word
|
|
o_TxMode word
|
|
o_SpExtra long
|
|
o_ChExtra long
|
|
o_FGColor word
|
|
o_BGColor word ;end of the stuff that we save
|
|
|
|
o_PicSave long
|
|
o_RgnSave long
|
|
o_PolySave long
|
|
o_GrafProcs long
|
|
|
|
o_ArcRot word
|
|
o_UserField long
|
|
o_SysField long
|
|
;---------------------------------------------------------------
|
|
|
|
|
|
|
|
PushLongSpace ;space for control handle
|
|
PushZLong GrafPortPtr ;push the current port's pointer
|
|
ldax ParameterPtr ;pointer to the bounding rectangle
|
|
clc
|
|
adc #TEParam.viewRect
|
|
bcc @1
|
|
inx
|
|
@1 PushAX
|
|
PushLong #0 ;CtlData field
|
|
PushWord #0 ;CtlFlags field
|
|
PushWord #0 ;CtlValue
|
|
PushLong #0 ;Param1 + Param2
|
|
PushLong #TEDefProc ;my custom defproc
|
|
PushLong #0 ;refcon.. for application use
|
|
PushLong #0 ;color table pointer
|
|
_NewControl ;get our text edit control
|
|
****************************************************************
|
|
* This routine takes a pointer to the new ruler block in A,X
|
|
****************************************************************
|
|
AddToRulerList PROC EXPORT
|
|
|
|
stax MemoryPtr ;save the pointer to the new ruler
|
|
|
|
ldx #MinRulerSize ;calculate the ruler size
|
|
ldy #TERuler.tabType
|
|
lda [MemoryPtr],y
|
|
cmp #noTabs
|
|
beq resizeIt
|
|
inx ;if equal tabs then the ruler is two bytes
|
|
inx ;..bigger
|
|
cmp #equalTabs
|
|
beq resizeIt
|
|
inx ;if user tabs then the ruler is four bytes
|
|
inx ;..bigger than the minimum
|
|
cmp #variableTabs
|
|
bne resizeIt
|
|
ldy #TERuler.numberOfTabs ;the ruler has a variable number of tabs
|
|
lda [MemoryPtr],y ;..so find out how many, multiply by four
|
|
asl a ;..add the minimum size, and add two for
|
|
asl a ;..the count to get the final ruler size.
|
|
clc
|
|
adc #MinRulerSize+2
|
|
tax
|
|
|
|
resizeIt stx RulerSize
|
|
ldy #TERecord.RulerList ;the new ruler is not in the list, so
|
|
jsr GetRecordLong ;..add it to the end of the list
|
|
PushAX ;three copys of the list handle for
|
|
PushAX ;..Get, Set, and Deref.
|
|
PushAX
|
|
jsr GetHandleSize
|
|
stax TextRulerOffset
|
|
clc
|
|
adc RulerSize
|
|
bcc @1
|
|
inx
|
|
@1 jsr SetHandleSize
|
|
lda TextRulerOffset
|
|
sec
|
|
sbc #4
|
|
sta TextRulerOffset
|
|
bcs @2
|
|
dec TextRulerOffset+2
|
|
@2 jsr DerefHandle ;get a pointer to the end of the new list.
|
|
clc
|
|
adc TextRulerOffset
|
|
sta TempPtr
|
|
txa
|
|
adc TextRulerOffset+2
|
|
sta TempPtr+2
|
|
|
|
ldy #2 ;set the new count field to one.
|
|
lda #1
|
|
sta [TempPtr]
|
|
dec a
|
|
sta [TempPtr],y
|
|
ldy #4 ;then copy in the new ruler
|
|
@loop lda [MemoryPtr],y
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
cpy RulerSize
|
|
blt @loop
|
|
|
|
jmp TerminateTempPtr
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
****************************************************************
|
|
|
|
InitialWordWrapOld PROC EXPORT
|
|
|
|
NewLineLength equ $00
|
|
|
|
PushZLong NewLineLength
|
|
|
|
PushLong [RecordPtr],TERecord.LineSuper
|
|
jsr KillSuperHandle
|
|
|
|
ldy #TERecord.NumberOfLines ;clear the number of lines field
|
|
lda #0
|
|
tax
|
|
jsr SetRecordLong
|
|
|
|
ldy #TERecord.TextLength ;if there is no text, we can skip this
|
|
jsr GetRecordLong ;..entire routine - (there are no lines)
|
|
stx TempWord
|
|
ora TempWord
|
|
bne wordWrap
|
|
PullLong NewLineLength
|
|
rts ;return right here, if there is no text.
|
|
;---------------------------------------------------------------
|
|
wordWrap stzl TextOffset ;start at the beginning of the text and
|
|
|
|
lda #LineSuperItemSize*256+MinSuperBlockSize
|
|
jsr GetSmallHandle ;get a handle for the new line starts
|
|
stax LineBlockHandle ;..array
|
|
PushAX ;lock it down and get two pointers:
|
|
jsr LockHandle ;..one to the start and one to the current
|
|
stax LineBlockStart ;..item
|
|
clc
|
|
adc #SuperBlockRecord.firstItem
|
|
bcc @1
|
|
inx
|
|
@1 stax LineStartsPtr
|
|
ldy #TERecord.TextLength ;set the initial length field of the super
|
|
jsr GetRecordLong ;..block
|
|
stax [LineBlockStart],SuperBlockRecord.length
|
|
ldy #SuperBlockRecord.count ;clear the initial count field of the
|
|
lda #0 ;..super block
|
|
sta [LineBlockStart],y
|
|
stz LineStartsCount ;zero out the count field.
|
|
jsr SetupWidthTable ;setup the width table pointer
|
|
;---------------------------------------------------------------
|
|
lineLoop stz NewLineLength
|
|
stz LineHeight
|
|
stz LineAscent
|
|
jsr GetWrapWidth ;get the width of the line.
|
|
sta WrapWidth
|
|
sta LineWidth
|
|
;---------------------------------------------------------------
|
|
mainLoop jsr FindStyleInfo ;find the new style information
|
|
bcc @1
|
|
jsr InstallStyleItem
|
|
@1 jsr GetSuperCount
|
|
sta TextCount
|
|
|
|
jsr FindBlockInfo ;find the current block information
|
|
jsr BlockToTextPtr
|
|
lda BlockCount
|
|
cmp TextCount
|
|
bge @2
|
|
sta TextCount
|
|
|
|
@2 lda TextHeight ;set the height and ascent fields
|
|
cmp LineHeight
|
|
blt @skipHeight
|
|
sta LineHeight
|
|
@skipHeight lda TextAscent
|
|
cmp LineAscent
|
|
blt @skipAscent
|
|
sta LineAscent
|
|
@skipAscent lda #0 ;zero out both A and X
|
|
tax
|
|
shortm ;short mode for speed
|
|
;---------------------------------------------------------------
|
|
widthLoop txy
|
|
lda [TextPtr],y ;get the character
|
|
cmp #$0D ;is it a carriage return ?
|
|
beq foundCR
|
|
cmp #TAB
|
|
beq doTab
|
|
tay ;use as an index into the width table
|
|
lda WrapWidth ;subtract the character width
|
|
sec
|
|
sbc [WidthTablePtr],y
|
|
sta WrapWidth
|
|
bcs @1
|
|
dec WrapWidth+1
|
|
bmi breakIt ;did we go below zero ?
|
|
@1 inx ;increment our counter
|
|
cpx TextCount
|
|
blt widthLoop ;branch back
|
|
;---------------------------------------------------------------
|
|
longm ;we need a new block of text, here
|
|
ldx TextCount ;add TextCount to the new line's length
|
|
jsr addXToTextOffset
|
|
ldy #TERecord.TextLength ;check for being at the end of the text.
|
|
jsr GetRecordLong
|
|
cmp TextOffset
|
|
bne mainLoop
|
|
cpx TextOffset+2
|
|
bne mainLoop
|
|
brl lastBreak
|
|
;---------------------------------------------------------------
|
|
doTab longm
|
|
brk $4B
|
|
;---------------------------------------------------------------
|
|
foundCR longm
|
|
inx ;skip over the CR
|
|
jsr addXToTextOffset
|
|
jsr forceBreak
|
|
brl lineLoop
|
|
;---------------------------------------------------------------
|
|
breakIt lda [WidthTablePtr],y ;get the width of the current char
|
|
longm ;back to long mode (B = 0)
|
|
clc ;add it back to the WrapWidth
|
|
adc WrapWidth
|
|
sta WrapWidth
|
|
sta LineWidth
|
|
jsr addXToTextOffset
|
|
tya ;the character was in the Y-Reg
|
|
jsr IsItNotAWordBreak ;is the character a word break ?
|
|
bcc skipOverThem ;if yes, then skip over them
|
|
lda TextOffset ;move back to the beginning of this line
|
|
sec
|
|
sbc NewLineLength
|
|
sta TextOffset
|
|
bcs @1
|
|
dec TextOffset+2
|
|
@1 jsr FindTextPtr
|
|
ldx NewLineLength
|
|
;---------------------------------------------------------------
|
|
@loop dex
|
|
bmi breakAtEnd
|
|
txy
|
|
lda [TextPtr],y
|
|
and #$00FF
|
|
tay
|
|
lda [WidthTablePtr],y
|
|
and #$00FF
|
|
clc
|
|
adc WrapWidth
|
|
sta WrapWidth
|
|
tya
|
|
jsr IsItNotAWordBreak
|
|
bcs @loop
|
|
;---------------------------------------------------------------
|
|
lda [WidthTablePtr],y ;subtract the width of the character
|
|
and #$00FF
|
|
sta TempWord
|
|
lda WrapWidth
|
|
sec
|
|
sbc TempWord
|
|
sta WrapWidth
|
|
inx
|
|
stx NewLineLength
|
|
txa
|
|
addIt addl TextOffset
|
|
jsr forceBreak
|
|
brl lineLoop
|
|
breakAtEnd mov LineWidth,WrapWidth
|
|
lda NewLineLength
|
|
bra addIt
|
|
;---------------------------------------------------------------
|
|
skipOverThem inc NewLineLength
|
|
incl TextOffset
|
|
ldy #TERecord.TextLength
|
|
lda [RecordPtr],y
|
|
cmp TextOffset
|
|
bne @ok
|
|
iny
|
|
iny
|
|
lda [RecordPtr],y
|
|
cmp TextOffset+2 ;if at the end, then break.
|
|
beq lastBreak
|
|
@ok jsr FindTextPtr
|
|
lda #0
|
|
shortm
|
|
lda [TextPtr]
|
|
tay
|
|
lda WrapWidth
|
|
sec
|
|
sbc [WidthTablePtr],y
|
|
sta WrapWidth
|
|
bcs @1
|
|
dec WrapWidth+1
|
|
@1 longm
|
|
tya
|
|
jsr IsItNotAWordBreak
|
|
bcc skipOverThem
|
|
jsr forceBreak
|
|
brl lineLoop
|
|
;---------------------------------------------------------------
|
|
lastBreak jsr forceBreak ;break at the very end of the text.
|
|
jsr FreeWidthTable
|
|
ldy #TERecord.NumberOfLines
|
|
jsr GetRecordLong
|
|
clc
|
|
adc LineStartsCount
|
|
bcc @1
|
|
inx
|
|
@1 ldy #TERecord.NumberOfLines
|
|
jsr SetRecordLong
|
|
|
|
ldy #2
|
|
lda #$FFFF
|
|
sta [LineStartsPtr]
|
|
sta [LineStartsPtr],y
|
|
|
|
IF LineSuperItemSize<>8 THEN
|
|
AERROR 'WARNING... The multiply code must change !'
|
|
ENDIF
|
|
|
|
ldax LineBlockHandle
|
|
PushAX ;for the set handle size
|
|
PushAX ;for the get handle size
|
|
PushAX ;for the unlock
|
|
jsr UnlockHandle
|
|
lda #256
|
|
sec
|
|
sbc LineStartsCount
|
|
asl a
|
|
asl a
|
|
asl a
|
|
sta LineStartsCount
|
|
jsr GetHandleSize
|
|
sec
|
|
sbc LineStartsCount
|
|
bcs @2
|
|
dex
|
|
@2 jsr SetHandleSize
|
|
;---------------------------------------------------------------
|
|
lda #MinSuperSize
|
|
jsr GetClearHandle
|
|
PushAX ;for the unlock
|
|
PushAX ;for the lock
|
|
stax [RecordPtr],TERecord.LineSuper
|
|
jsr LockHandle
|
|
stax TempPtr
|
|
ldy #SuperRecord.terminator
|
|
jsr TerminateTempPtr
|
|
|
|
ldy #SuperRecord.mainIndex
|
|
lda #SuperRecord.firstItem ;set the main index cache value
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda #SuperBlockRecord.firstItem ;set the local index cahce value
|
|
sta [TempPtr],y
|
|
ldy #SuperRecord.itemNumber ;set the low word of item # to one
|
|
lda #1
|
|
sta [TempPtr],y
|
|
ldy #SuperRecord.itemSize ;set the item size field
|
|
lda #LineSuperItemSize
|
|
sta [TempPtr],y
|
|
|
|
jsr UnlockHandle ;unlock the main handle from the stack
|
|
;---------------------------------------------------------------
|
|
ldy #SuperRecord.firstItem
|
|
lda LineBlockHandle
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda LineBlockHandle+2
|
|
sta [TempPtr],y
|
|
;---------------------------------------------------------------
|
|
|
|
ldy #TERecord.VertScrollBar
|
|
jsr GetRecordLong
|
|
stx TempWord
|
|
ora TempWord
|
|
beq @skipParams
|
|
|
|
ldy #TERecord.NumberOfLines ;this won't work for more than 64K lines
|
|
lda [RecordPtr],y
|
|
pha
|
|
jsr CountLinesInView ;returns the number of lines in the view
|
|
pha ;..rect
|
|
ldy #TERecord.VertScrollBar
|
|
jsr GetRecordLong
|
|
PushAX
|
|
stax TempPtr
|
|
_SetCtlParams
|
|
|
|
jsr DerefTempPtr
|
|
ldy #CtrlRecord.ctlRect
|
|
@loop lda [TempPtr],y
|
|
tyx
|
|
sta TempRect-CtrlRecord.ctlRect,x
|
|
iny
|
|
iny
|
|
cpy #CtrlRecord.ctlRect+8
|
|
blt @loop
|
|
|
|
PushZPtr TempRect
|
|
_InvalRect
|
|
|
|
@skipParams stzl TextOffset
|
|
PullLong NewLineLength
|
|
rts
|
|
;---------------------------------------------------------------
|
|
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
; this subroutine puts a line break in at the current NewLineLength
|
|
;---------------------------------------------------------------
|
|
forceBreak ldy #2
|
|
lda NewLineLength ;set the new line length
|
|
sta [LineStartsPtr]
|
|
lda #0
|
|
sta [LineStartsPtr],y
|
|
iny
|
|
iny
|
|
lda LineHeight ;set the new line height
|
|
sta [LineStartsPtr],y
|
|
iny
|
|
iny
|
|
lda LineAscent ;set the new line ascent
|
|
sta [LineStartsPtr],y
|
|
iny
|
|
iny
|
|
lda #LineSuperItemSize
|
|
addl LineStartsPtr
|
|
|
|
ldy #SuperBlockRecord.count
|
|
lda [LineBlockStart],y
|
|
inc a
|
|
sta [LineBlockStart],y
|
|
|
|
inc LineStartsCount ;increment our count
|
|
lda LineStartsCount
|
|
cmp #256
|
|
bne @done
|
|
|
|
ldax LineBlockHandle
|
|
PushAX ;for the lock
|
|
PushAX ;for the set handle size
|
|
PushAX ;for the get handle size
|
|
PushAX ;for the unlock
|
|
jsr UnlockHandle
|
|
jsr GetHandleSize
|
|
stax MoveLength
|
|
clc
|
|
adc #LineSuperItemSize*256
|
|
bcc @1
|
|
inx
|
|
@1 jsr SetHandleSize
|
|
jsr LockHandle
|
|
stax LineBlockStart
|
|
clc
|
|
adc MoveLength
|
|
sta LineStartsPtr
|
|
txa
|
|
adc MoveLength+2
|
|
sta LineStartsPtr+2
|
|
stz LineStartsCount ;zero out the count field.
|
|
ldy #TERecord.NumberOfLines
|
|
jsr GetRecordLong
|
|
clc
|
|
adc #256
|
|
bcc @2
|
|
inx
|
|
@2 ldy #TERecord.NumberOfLines
|
|
jsr SetRecordLong
|
|
|
|
@done rts
|
|
;---------------------------------------------------------------
|
|
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
; this subroutine adds the X-Reg to both NewLineLength and TextOffset
|
|
;---------------------------------------------------------------
|
|
addXToTextOffset txa
|
|
clc
|
|
adc NewLineLength
|
|
sta NewLineLength
|
|
txa
|
|
addl TextOffset
|
|
rts
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
scrollColors dc.w $0000 ;Outline.
|
|
dc.w $00F0 ;Arrow when normal.
|
|
dc.w $00F0 ;Arrow when selected.
|
|
dc.w $00F0 ;Arrow's box interior.
|
|
dc.w $00F0 ;Thumber when normal.
|
|
dc.w $0000 ;Not used and should never be used.
|
|
dc.w $0030 ;Page region interior.
|
|
dc.w $00F0 ;Interior color of inactive bar.
|
|
|
|
****************************************************************
|
|
; this routine takes TextOffset pointing anywhere within the current
|
|
; line and it calculates the width of the LAST field in the line.
|
|
; It returns TextOffset pointing to the start of the last field, X-Reg
|
|
; as an offset into the line for the same thing. Finally TempWord is
|
|
; the field width
|
|
****************************************************************
|
|
MeasureLastField PROCNAME
|
|
|
|
jsr FindLineStart ;start at the beginning of the line
|
|
|
|
jsr FindTextPtr ;setup the text pointer
|
|
ldy SuperLength ;start at the end of the line
|
|
shortm ;short mode for speed
|
|
|
|
@tabLoop dey ;search backwards for the first TAB
|
|
bmi atStart
|
|
lda [TextPtr],y
|
|
cmp #TAB
|
|
bne @tabLoop
|
|
|
|
atStart longm ;back to long mode
|
|
iny ;skip over the TAB
|
|
tya ;move TextOffset to the start of the last
|
|
addl TextOffset ;..field
|
|
cpy SuperLength ;are we at the end of the line ?
|
|
beq tabAtEnd
|
|
phy ;nope, so save Y-Reg
|
|
jsr MeasureField ;measure the last field
|
|
sta TempWord ;store the result in TempWord
|
|
plx ;restore our index into X
|
|
rts
|
|
|
|
tabAtEnd stz TempWord ;zero out our width
|
|
tyx ;X-Reg is our returned index
|
|
rts
|
|
|
|
ENDP
|
|
****************************************************************
|
|
|
|
****************************************************************
|
|
* This checks TempRect to see if it is contained by the vis region
|
|
* of the current grafport. carry clr if TempRect IS inside the
|
|
* region. carry set if not. Uses MemoryPtr.
|
|
****************************************************************
|
|
|
|
IsTempRectInVisRgn PROCNAME
|
|
|
|
ldy #GrafPort.VisRgn+2 ;get the region handle out of the grafport
|
|
lda [GrafPortPtr],y
|
|
sta MemoryPtr+2
|
|
ldy #GrafPort.VisRgn
|
|
lda [GrafPortPtr],y
|
|
sta MemoryPtr
|
|
ldy #2 ;deref it into a pointer.
|
|
lda [MemoryPtr],y
|
|
tax
|
|
lda [MemoryPtr]
|
|
stax MemoryPtr
|
|
|
|
lda [MemoryPtr] ;is the vis region rectangular ?
|
|
cmp #10 ;if not then we can't check so return
|
|
bne outside ;..FALSE
|
|
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.top
|
|
bgt outside
|
|
ldy #4
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.left
|
|
bgt outside
|
|
ldy #6
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.bottom
|
|
blt outside
|
|
ldy #8
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.right
|
|
blt outside
|
|
clc ;we are completly within the region !!
|
|
rts
|
|
|
|
outside sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
ScrollUpOne PROCNAME
|
|
|
|
jsr GetScreenTopOffset
|
|
lda TextOffset
|
|
ora TextOffset+2
|
|
beq atTop
|
|
|
|
decl TextOffset ;get the height of the line right before
|
|
jsr FindLineStart ;..the screen top. start at the line start
|
|
jsr SetScreenTopOffset ;set the new screen top offset
|
|
jsr GetViewRect ;get the view rectangle
|
|
lda LineHeight ;scroll it down by the line height
|
|
jsr VScrollTempRect
|
|
|
|
jsr CalculateSelection
|
|
|
|
jsr GetScreenTopOffset
|
|
jsr FindLineInfo
|
|
jsr GetViewRect
|
|
lda TempRect.top
|
|
clc
|
|
adc LineHeight
|
|
sta TempRect.bottom
|
|
|
|
ldy #GrafPort.VisRgn
|
|
jsr GetPortLong
|
|
PushAX
|
|
jsr SetupVisRgn ;setup our vis region to clip to the textRect.
|
|
|
|
jsr OffsetToPoint ;find TextVPos for the drawLine
|
|
jsr DrawLine
|
|
|
|
PullAX
|
|
ldy #GrafPort.VisRgn
|
|
jsr SetPortLong
|
|
|
|
jsr SetCtrlValue
|
|
clc
|
|
rts
|
|
|
|
atTop sec
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
ScrollDownOne PROCNAME
|
|
|
|
jsr GetScreenTopOffset ;start at the top of the screen for both
|
|
ldy #TERecord.ViewRect.top ;..TextOffset and TextVPos
|
|
lda [RecordPtr],y
|
|
sta TextVPos
|
|
|
|
@loop jsr IsTextOffsetAtEnd
|
|
beq atBottom
|
|
jsr FindLineInfo
|
|
addl TextOffset,SuperLength,TextOffset
|
|
lda TextVPos
|
|
clc
|
|
adc LineHeight
|
|
sta TextVPos
|
|
ldy #TERecord.ViewRect.bottom
|
|
cmp [RecordPtr],y
|
|
blt @loop
|
|
|
|
jsr GetScreenTopOffset ;get the height of the line at the screen
|
|
jsr FindLineInfo
|
|
addl TextOffset,SuperLength,TextOffset
|
|
jsr SetScreenTopOffset ;set the new screen top offset
|
|
jsr FindLineInfo
|
|
|
|
jsr GetViewRect ;get the view rectangle
|
|
lda LineHeight ;scroll it down by the line height
|
|
eor #$FFFF ;change the sign (the INC is part of the
|
|
inc a ;..sign change)
|
|
pha
|
|
jsr VScrollTempRect
|
|
|
|
jsr CalculateSelection
|
|
PullWord LineHeight ;get our saved value into LineHeight
|
|
|
|
ldy #GrafPort.VisRgn
|
|
jsr GetPortLong
|
|
PushAX
|
|
jsr SetupVisRgn ;setup our vis region to clip to the textRect.
|
|
|
|
ldy #TERecord.ViewRect.left
|
|
lda [RecordPtr],y
|
|
sta DrawRect.left
|
|
ldy #TERecord.ViewRect.bottom
|
|
jsr GetRecordLong
|
|
sta DrawRect.bottom
|
|
stx DrawRect.right
|
|
clc
|
|
adc LineHeight
|
|
sta DrawRect.top
|
|
jsr DoDraw
|
|
|
|
PullAX
|
|
ldy #GrafPort.VisRgn
|
|
jsr SetPortLong
|
|
|
|
jsr SetCtrlValue
|
|
|
|
atBottom clc
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
SetCtrlValue PROCNAME
|
|
|
|
jsr GetScreenTopOffset
|
|
jsr FindLineInfo
|
|
|
|
jsr GetVertScrollBar
|
|
beq skipSet
|
|
ldy LineNumber ;save the new value
|
|
dey
|
|
phy
|
|
PushAX ;the control handle for the scroll bar.
|
|
stax TempPtr
|
|
jsr DerefTempPtr
|
|
ldy #CtrlRecord.dataSize
|
|
lda [TempPtr],y
|
|
ldy #CtrlRecord.viewSize
|
|
sec
|
|
sbc [TempPtr],y
|
|
cmp 5,s
|
|
bge @ok
|
|
sta 5,s
|
|
@ok _SetCtlValue
|
|
|
|
skipSet rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
SetupVisRgn PROCNAME
|
|
|
|
jsr GetViewRect ;clip to the text rectangle
|
|
|
|
ldy #GrafPort.VisRgn ;get the region handle, deref it and store
|
|
jsr GetPortLong ;..in memory pointer
|
|
jsr DerefAX
|
|
stax MemoryPtr
|
|
|
|
lda [MemoryPtr] ;is the region rectangular ? If not, we
|
|
cmp #10 ;..must intersect the regions
|
|
bne mustSectRgn
|
|
|
|
lda [MemoryPtr],y ;Y-Reg is still two here
|
|
cmp TempRect.top
|
|
bgt notContained
|
|
ldy #4
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.left
|
|
bgt notContained
|
|
ldy #6
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.bottom
|
|
blt notContained
|
|
ldy #8
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.right
|
|
bge setRectClip
|
|
;---------------------------------------------------------------
|
|
notContained ldy #8 ;compare right point
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.right
|
|
bpl @1
|
|
sta TempRect.right
|
|
@1 ldy #6 ;compare bottom point
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.bottom
|
|
bpl @2
|
|
sta TempRect.bottom
|
|
|
|
@2 ldy #4 ;compare left point
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.left
|
|
bmi @3
|
|
sta TempRect.left
|
|
@3 cmp TempRect.right ;check for empty rect
|
|
bpl @zeroIt
|
|
ldy #2 ;compare top point
|
|
lda [MemoryPtr],y
|
|
cmp TempRect.top
|
|
bmi @4
|
|
sta TempRect.top
|
|
@4 cmp TempRect.bottom ;check for empty rect
|
|
bmi setRectClip
|
|
|
|
@zeroIt jsr zeroTempRect
|
|
;---------------------------------------------------------------
|
|
setRectClip jsr SetRectClipRgn
|
|
bra setClip
|
|
;---------------------------------------------------------------
|
|
mustSectRgn jsr SetRectClipRgn ;set our clipping region to the ViewRect
|
|
ldy #GrafPort.VisRgn
|
|
jsr GetPortLong
|
|
PushWordSpace ;space for empty region results
|
|
PushAX ;for EmptyRgn
|
|
PushAX ;for sect region
|
|
ldax TextClipRgn ;push two copies of TempRgn
|
|
stax TempPtr ;save in TempPtr for deref
|
|
PushAX
|
|
PushAX
|
|
_SectRgn
|
|
_EmptyRgn
|
|
pla
|
|
beq @notEmpty
|
|
jsr zeroTempRect
|
|
bra setClip
|
|
|
|
@notEmpty jsr DerefTempPtr ;dereference the TextClipRgn's handle
|
|
ldy #2 ;copy the bounding box into DrawRect
|
|
@loop lda [TempPtr],y
|
|
tyx
|
|
sta TempRect-2,x
|
|
iny
|
|
iny
|
|
cpy #10
|
|
blt @loop
|
|
;---------------------------------------------------------------
|
|
setClip ldax TextClipRgn
|
|
ldy #GrafPort.VisRgn
|
|
jsr SetPortLong
|
|
|
|
mov TempRect.top,DrawRect.top ;copy TempRect into DrawRect
|
|
mov TempRect.left,DrawRect.left
|
|
mov TempRect.bottom,DrawRect.bottom
|
|
mov TempRect.right,DrawRect.right
|
|
|
|
jsr SetupColorPtr ;set the background pattern for the text
|
|
ldy #TEColorTable.content
|
|
lda [TempPtr],y
|
|
jsr SmearColor
|
|
ldy #GrafPort.BkPat
|
|
@loop sta [GrafPortPtr],y
|
|
iny
|
|
iny
|
|
cpy #GrafPort.BkPat+32
|
|
blt @loop
|
|
|
|
lda #0 ;zero out the space and character extra
|
|
tax ;..fields
|
|
ldy #GrafPort.SpExtra
|
|
jsr SetPortLong
|
|
ldy #GrafPort.ChExtra
|
|
jmp SetPortLong ;exit back to the caller
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
ZeroTempRect PROCNAME
|
|
|
|
stz TempRect.top
|
|
stz TempRect.left
|
|
stz TempRect.bottom
|
|
stz TempRect.right
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
SetRectClipRgn PROCNAME
|
|
|
|
jsr derefTextRgn ;dereference the Text region and leave
|
|
lda #10 ;..the pointer in TempPtr. Also leave Y-Reg
|
|
cmp [TempPtr] ;..set to #2
|
|
beq @sizeOK
|
|
|
|
sta [TempPtr] ;the new size is 10 bytes
|
|
ldx #0
|
|
PushZLong TextClipRgn
|
|
jsr SetHandleSize
|
|
jsr derefTextRgn
|
|
|
|
@sizeOK lda TempRect.top
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda TempRect.left
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda TempRect.bottom
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda TempRect.right
|
|
sta [TempPtr],y
|
|
rts
|
|
|
|
derefTextRgn ldy #2
|
|
lda [TextClipRgn],y
|
|
sta TempPtr+2
|
|
lda [TextClipRgn]
|
|
sta TempPtr
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
****************************************************************
|
|
ldy #2
|
|
@loop lda [MemoryPtr],y
|
|
cmp #$FFFF
|
|
beq @done
|
|
tya
|
|
adc #6 ;carry is already clear from the compare
|
|
tay
|
|
bra @loop
|
|
|
|
@done tya
|
|
sbc #8 ;carry is set from the compare
|
|
tay
|
|
lda [MemoryPtr],y
|
|
sta TempLong
|
|
iny
|
|
iny
|
|
lda [MemoryPtr],y
|
|
sta TempLong+2
|
|
ldy #TERecord.SelectionStart
|
|
jsr GetRecordLong
|
|
cmpl TempLong
|
|
bgel notOnScreen
|
|
****************************************************************
|
|
jsr SetupColorPtr ;set the background pattern for the text
|
|
ldy #TEColorTable.content
|
|
lda [TempPtr],y
|
|
jsr SmearColor
|
|
ldy #GrafPort.BkPat
|
|
@loop sta [GrafPortPtr],y
|
|
iny
|
|
iny
|
|
cpy #GrafPort.BkPat+32
|
|
blt @loop
|
|
|
|
****************************************************************
|
|
|
|
DrawFromOffset PROCNAME
|
|
EXPORT DrawLine
|
|
|
|
jsr GetJust ;if the text is not left justified then
|
|
cmp #leftJust ;..we must redraw the entire line
|
|
bnel DrawLine
|
|
|
|
jsr OffsetToPoint ;find the starting point
|
|
ldy #TERecord.ViewRect.left ;subtract the left edge of the text rect
|
|
lda TextHPos
|
|
sec
|
|
sbc [RecordPtr],y
|
|
sta TextHPos
|
|
;---------------------------------------------------------------
|
|
moveIt lda TextVPos
|
|
clc
|
|
adc LineAscent
|
|
ldy #GrafPort.PnLoc.v
|
|
sta [GrafPortPtr],y
|
|
lda TextVPos ;move the text position down to the next
|
|
sta TempRect.top ;..line. Also set TempRect to the line
|
|
clc ;..rect
|
|
adc LineHeight
|
|
sta TextVPos
|
|
sta TempRect.bottom
|
|
|
|
lda TextHPos ;erase before we draw
|
|
ldy #TERecord.ViewRect.left ;add the left edge of the view rect
|
|
clc ;..to get the final HPos
|
|
adc [RecordPtr],y
|
|
sta TempRect.left
|
|
ldy #TERecord.ViewRect.right
|
|
lda [RecordPtr],y
|
|
sta TempRect.right
|
|
jsr EraseTempRect
|
|
|
|
lda TextHPos
|
|
moveHorz ldy #TERecord.ViewRect.left ;add the left edge of the view rect
|
|
clc ;..to get the final HPos
|
|
adc [RecordPtr],y
|
|
ldy #GrafPort.PnLoc.h
|
|
sta [GrafPortPtr],y
|
|
;---------------------------------------------------------------
|
|
partLoop jsr GetTextFormat ;get the next chunck of text
|
|
|
|
PushZLong TextPtr ;.. and draw it.
|
|
PushZWord TextCount
|
|
_DrawText
|
|
|
|
lda TextCount ;move the TextOffset forward.
|
|
addl TextOffset
|
|
lda WhatStoppedFormat
|
|
cmp #endOfText ;are we at the end ? Yes = stop drawing
|
|
beq atEnd
|
|
cmp #tabBreak
|
|
beq doTab
|
|
cmp #lineBreak
|
|
bne partLoop
|
|
|
|
clc
|
|
allDone rts
|
|
|
|
atEnd sec
|
|
bra allDone
|
|
;---------------------------------------------------------------
|
|
doTab incl TextOffset ;skip over the TAB
|
|
ldy #GrafPort.PnLoc.h
|
|
lda [GrafPortPtr],y
|
|
sec
|
|
ldy #TERecord.ViewRect.left
|
|
sbc [RecordPtr],y
|
|
sta TextHPos
|
|
|
|
jsr MoveOverTab
|
|
sta TextHPos
|
|
jsr AdjustForJust
|
|
clc
|
|
adc TextHPos
|
|
bra moveHorz
|
|
;---------------------------------------------------------------
|
|
DrawLine jsr FindLineStart ;skip offset to point
|
|
jsr GetLeftEdge
|
|
sta TextHPos
|
|
jsr AdjustForJust
|
|
clc
|
|
adc TextHPos
|
|
sta TextHPos
|
|
brl moveIt
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
ldy #TERecord.SelectionState
|
|
lda [RecordPtr],y
|
|
cmp #offScreen
|
|
beq @skipFlip
|
|
|
|
ldy #TERecord.ViewRect
|
|
ldx #0
|
|
@loop1 lda [RecordPtr],y
|
|
pha
|
|
lda DrawRect,x
|
|
sta [RecordPtr],y
|
|
inx
|
|
inx
|
|
iny
|
|
iny
|
|
cpy #TERecord.ViewRect+8
|
|
blt @loop1
|
|
|
|
jsr FlipSelection
|
|
|
|
ldy #TERecord.ViewRect+6
|
|
@loop2 pla
|
|
sta [RecordPtr],y
|
|
dey
|
|
dey
|
|
cpy #TERecord.ViewRect
|
|
bge @loop2
|
|
|
|
@skipFlip ldy #TERecord.InsideDrawFlag
|
|
lda #$0000
|
|
sta [RecordPtr],y
|
|
****************************************************************
|
|
|
|
DoLeftArrow PROCNAME
|
|
|
|
ldy #TERecord.SavedHPos
|
|
lda #$FFFF
|
|
sta [RecordPtr],y
|
|
|
|
jsr GetSelectionStart ;see if we are at the beginning.
|
|
lda TextOffset
|
|
ora TextOffset+2
|
|
bne notAtStart
|
|
bit ExtendFlag ;are we extending the selection
|
|
bmi nothingToDo
|
|
|
|
setEnd jsr SetSelectionEnd ;make the selection a caret
|
|
jsr UnhilightSelection
|
|
jsr CalculateSelection
|
|
jsr HilightSelection
|
|
nothingToDo brl ScrollToSelection ;scroll to the selection if we are offscreen
|
|
;---------------------------------------------------------------
|
|
notAtStart lda MoveByFlag
|
|
cmp #2
|
|
beq moveLine
|
|
cmp #1
|
|
beq moveWord
|
|
decl TextOffset ;move the selection back
|
|
bra moveIt
|
|
;---------------------------------------------------------------
|
|
moveWord decl TextOffset
|
|
jsr FindTextPtr
|
|
lda [TextPtr]
|
|
jsr IsItNotAWordBreak
|
|
bcs @nowMove
|
|
lda TextOffset
|
|
ora TextOffset+2
|
|
beq moveIt
|
|
bra moveWord
|
|
@nowMove jsr FindWordStart
|
|
bra moveIt
|
|
;---------------------------------------------------------------
|
|
moveLine jsr FindLineStart
|
|
;---------------------------------------------------------------
|
|
moveIt bit ExtendFlag
|
|
bmi extend
|
|
jsr SetSelectionStart
|
|
bra setEnd
|
|
;---------------------------------------------------------------
|
|
extend ldy #TERecord.SelectionState
|
|
lda #onScreen
|
|
cmp [RecordPtr],y
|
|
beq @1
|
|
sta [RecordPtr],y
|
|
bra @2
|
|
@1 ldy #TERecord.SelectionType
|
|
lda [RecordPtr],y
|
|
cmp #caretType
|
|
bne @2
|
|
jsr FlipSelection
|
|
@2 ldy #TERecord.SelectionEnd
|
|
jsr PushRecordLong
|
|
ldy #TERecord.SelectionStart
|
|
jsr GetRecordLong
|
|
ldy #TERecord.SelectionEnd
|
|
jsr SetRecordLong
|
|
jsr SetSelectionStart
|
|
jsr CalculateSelection
|
|
jsr FlipSelection
|
|
PullAX
|
|
ldy #TERecord.SelectionEnd
|
|
jsr SetRecordLong
|
|
jsr CalculateSelection
|
|
brl ScrollToSelection
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
DoRightArrow PROCNAME
|
|
|
|
ldy #TERecord.SavedHPos
|
|
lda #$FFFF
|
|
sta [RecordPtr],y
|
|
|
|
jsr GetSelectionEnd ;see if we are at the beginning.
|
|
jsr IsTextOffsetAtEnd
|
|
bne notAtEnd
|
|
bit ExtendFlag
|
|
bmi nothingToDo
|
|
|
|
setStart jsr SetSelectionStart ;make the selection a caret
|
|
jsr UnhilightSelection
|
|
jsr CalculateSelection
|
|
jsr HilightSelection
|
|
nothingToDo brl ScrollToSelection ;scroll to the selection if we are offscreen
|
|
;---------------------------------------------------------------
|
|
notAtEnd lda MoveByFlag
|
|
cmp #2
|
|
beq moveLine
|
|
cmp #1
|
|
beq moveWord
|
|
incl TextOffset ;move the selection forward
|
|
bra moveIt
|
|
;---------------------------------------------------------------
|
|
moveWord jsr FindTextPtr
|
|
lda [TextPtr]
|
|
jsr IsItNotAWordBreak
|
|
bcs @nowMove
|
|
incl TextOffset
|
|
jsr IsTextOffsetAtEnd
|
|
beq moveIt
|
|
bra moveWord
|
|
@nowMove incl TextOffset
|
|
jsr FindWordEnd
|
|
bra moveIt
|
|
;---------------------------------------------------------------
|
|
moveLine jsr FindLineInfo
|
|
jsr MoveOffsetToNextItem
|
|
decl TextOffset
|
|
;---------------------------------------------------------------
|
|
moveIt bit ExtendFlag
|
|
bmi extend
|
|
jsr SetSelectionEnd
|
|
bra setStart
|
|
;---------------------------------------------------------------
|
|
extend ldy #TERecord.SelectionState
|
|
lda #onScreen
|
|
cmp [RecordPtr],y
|
|
beq @1
|
|
sta [RecordPtr],y
|
|
bra @2
|
|
@1 ldy #TERecord.SelectionType
|
|
lda [RecordPtr],y
|
|
cmp #caretType
|
|
bne @2
|
|
jsr FlipSelection
|
|
@2 ldy #TERecord.SelectionStart
|
|
jsr PushRecordLong
|
|
ldy #TERecord.SelectionEnd
|
|
jsr GetRecordLong
|
|
ldy #TERecord.SelectionStart
|
|
jsr SetRecordLong
|
|
jsr SetSelectionEnd
|
|
jsr CalculateSelection
|
|
jsr FlipSelection
|
|
PullAX
|
|
ldy #TERecord.SelectionStart
|
|
jsr SetRecordLong
|
|
jsr CalculateSelection
|
|
brl ScrollToSelection
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
DoDownArrow PROCNAME
|
|
|
|
jsr GetSelectionEnd
|
|
jsr FindLineInfo ;find the current line
|
|
ldy #TERecord.NumberOfLines
|
|
jsr GetRecordLong
|
|
cpx LineNumber+2
|
|
bne notAtEnd
|
|
cmp LineNumber
|
|
bne notAtEnd
|
|
|
|
bit ExtendFlag
|
|
bmi nothingToDo
|
|
|
|
jsr SetSelectionStart ;make the selection a caret
|
|
jsr UnhilightSelection
|
|
jsr CalculateSelection
|
|
jsr HilightSelection
|
|
nothingToDo brl ScrollToSelection ;scroll to the selection if we are offscreen
|
|
;---------------------------------------------------------------
|
|
notAtEnd jsr OffsetToPoint
|
|
ldy #TERecord.SavedHPos
|
|
lda [RecordPtr],y
|
|
cmp #$FFFF
|
|
beq @1
|
|
sta TextHPos
|
|
@1 pei TextHPos ;save the old horizontal position
|
|
|
|
jsr FindLineInfo
|
|
jsr MoveOffsetToNextItem
|
|
jsr HPosToOffset
|
|
|
|
bit ExtendFlag
|
|
bmi extend
|
|
jsr SetSelectionEnd
|
|
jsr SetSelectionStart ;make the selection a caret
|
|
jsr UnhilightSelection
|
|
jsr CalculateSelection
|
|
jsr HilightSelection
|
|
setSave ldy #TERecord.SavedHPos
|
|
pla
|
|
sta [RecordPtr],y
|
|
bra nothingToDo
|
|
;---------------------------------------------------------------
|
|
extend ldy #TERecord.SelectionState
|
|
lda #onScreen
|
|
cmp [RecordPtr],y
|
|
beq @1
|
|
sta [RecordPtr],y
|
|
bra @2
|
|
@1 ldy #TERecord.SelectionType
|
|
lda [RecordPtr],y
|
|
cmp #caretType
|
|
bne @2
|
|
jsr FlipSelection
|
|
@2 ldy #TERecord.SelectionStart
|
|
jsr PushRecordLong
|
|
ldy #TERecord.SelectionEnd
|
|
jsr GetRecordLong
|
|
ldy #TERecord.SelectionStart
|
|
jsr SetRecordLong
|
|
jsr SetSelectionEnd
|
|
jsr CalculateSelection
|
|
jsr FlipSelection
|
|
PullAX
|
|
ldy #TERecord.SelectionStart
|
|
jsr SetRecordLong
|
|
jsr CalculateSelection
|
|
bra setSave
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
DoUpArrow PROCNAME
|
|
|
|
jsr GetSelectionStart
|
|
jsr FindLineInfo ;find the current line
|
|
lda LineNumber+2
|
|
bne notAtStart
|
|
lda LineNumber
|
|
cmp #1
|
|
bne notAtStart
|
|
|
|
bit ExtendFlag
|
|
bmi nothingToDo
|
|
|
|
jsr SetSelectionEnd ;make the selection a caret
|
|
jsr UnhilightSelection
|
|
jsr CalculateSelection
|
|
jsr HilightSelection
|
|
nothingToDo brl ScrollToSelection ;scroll to the selection if we are offscreen
|
|
;---------------------------------------------------------------
|
|
notAtStart jsr OffsetToPoint
|
|
ldx #0
|
|
bcs @notOnScreen
|
|
dex
|
|
@notOnScreen stx ScreenFlag
|
|
ldy #TERecord.SavedHPos
|
|
lda [RecordPtr],y
|
|
cmp #$FFFF
|
|
beq @1
|
|
sta TextHPos
|
|
@1 pei TextHPos ;save the old horizontal position
|
|
jsr FindLineInfo
|
|
ldax SuperStart
|
|
decl a
|
|
stax TextOffset
|
|
jsr HPosToOffset
|
|
|
|
bit ExtendFlag
|
|
bmi extend
|
|
jsr SetSelectionStart
|
|
jsr SetSelectionEnd ;make the selection a caret
|
|
jsr UnhilightSelection
|
|
bit ScreenFlag
|
|
bmi @checkIt
|
|
jsr ScrollToSelection
|
|
bra calcIt
|
|
|
|
@checkIt ldy #TERecord.TopTextOffset
|
|
jsr GetRecordLong
|
|
cmpl TextOffset
|
|
blt calcIt
|
|
|
|
jsr ScrollUpOne
|
|
|
|
calcIt jsr CalculateSelection
|
|
jsr HilightSelection
|
|
setSave ldy #TERecord.SavedHPos
|
|
pla
|
|
sta [RecordPtr],y
|
|
rts
|
|
;---------------------------------------------------------------
|
|
extend ldy #TERecord.SelectionState
|
|
lda #onScreen
|
|
cmp [RecordPtr],y
|
|
beq @1
|
|
sta [RecordPtr],y
|
|
bra @2
|
|
@1 ldy #TERecord.SelectionType
|
|
lda [RecordPtr],y
|
|
cmp #caretType
|
|
bne @2
|
|
jsr FlipSelection
|
|
@2 PushZLong TextOffset
|
|
bit ScreenFlag
|
|
bpl @cont
|
|
ldy #TERecord.TopTextOffset
|
|
jsr GetRecordLong
|
|
cmpl TextOffset
|
|
blt @nope
|
|
jsr ScrollUpOne
|
|
bra @cont
|
|
|
|
@nope stz ScreenFlag
|
|
|
|
@cont PullLong TextOffset
|
|
ldy #TERecord.SelectionEnd
|
|
jsr PushRecordLong
|
|
ldy #TERecord.SelectionStart
|
|
jsr GetRecordLong
|
|
ldy #TERecord.SelectionEnd
|
|
jsr SetRecordLong
|
|
jsr SetSelectionStart
|
|
jsr CalculateSelection
|
|
jsr FlipSelection
|
|
PullAX
|
|
ldy #TERecord.SelectionEnd
|
|
jsr SetRecordLong
|
|
jsr CalculateSelection
|
|
bit ScreenFlag
|
|
bpl setSave
|
|
jsr ScrollToSelection
|
|
bra setSave
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
****************************************************************
|
|
; this routine returns the screen point TextVPos and TextHPos
|
|
; associated with TextOffset. It returns carry set (TRUE) if the
|
|
; offset is not on the screen. In this case TextVPos and TextHPos
|
|
; will be the topleft of the viewRect or the botRight of the viewRect
|
|
****************************************************************
|
|
OffsetToPoint PROCNAME
|
|
|
|
movl TextOffset,OriginalOffset ;save this for comparing against later
|
|
|
|
ldy #TERecord.ViewRect.top ;start TextVPos at the top of the
|
|
lda [RecordPtr],y ;..viewRect
|
|
sec
|
|
ldy #TERecord.TopTextVPos
|
|
sbc [RecordPtr],y
|
|
sta TextVPos
|
|
|
|
ldy #TERecord.TopTextOffset ;start scanning from the top of the screen
|
|
jsr GetRecordLong
|
|
cpx TextOffset+2 ;check to see if the offset we are looking
|
|
blt pastTheTop ;..for is before the top of the screen.
|
|
bne abortTop ;If so, then abort with carry set and
|
|
cmp TextOffset ;..TextVPos set to the viewRect.top
|
|
ble pastTheTop ;we're on screen here so continue
|
|
;---------------------------------------------------------------
|
|
abortTop ldy #TERecord.ViewRect.top ;start TextVPos at the top of the
|
|
lda [RecordPtr],y ;..viewRect
|
|
sta TextVPos
|
|
jsr GetLeftMargin ;find the leftmost position in the line
|
|
sta TextHPos ;..and return this as the TextHPos when
|
|
jsr GetLeftEdge ;..aborting because of being before the
|
|
cmp TextHPos ;..screen top
|
|
bge abortBottom
|
|
sta TextHPos
|
|
abortBottom ldy #TERecord.ViewRect.left
|
|
lda TextHPos
|
|
clc
|
|
adc [RecordPtr],y
|
|
sta TextHPos
|
|
movl OriginalOffset,TextOffset ;restore the original text offset
|
|
sec ;set the carry to indicate the text is
|
|
rts ;..off the screen. Then return
|
|
;---------------------------------------------------------------
|
|
pastTheTop stax TextOffset ;start at the offset of the screen top.
|
|
|
|
@lineLoop jsr FindLineInfo ;find the line length and height
|
|
lda TextOffset ;add the length to TextOffset and leave
|
|
clc ;..the result in the X-Reg (low) and the
|
|
adc SuperLength ;..A-Reg (high)
|
|
tax
|
|
lda TextOffset+2
|
|
adc SuperLength+2
|
|
cmp OriginalOffset+2 ;are we at (or past) the original offset?
|
|
blt @storeIt ;..yes = goto foundLine
|
|
bne foundLine
|
|
cpx OriginalOffset
|
|
blt @storeIt
|
|
bne foundLine
|
|
|
|
@storeIt sta TextOffset+2 ;save the new value of TextOffset
|
|
stx TextOffset
|
|
ldy #TERecord.NumberOfLines+2 ;check to see if there are any more lines
|
|
lda [RecordPtr],y ;..in the record. If not, we must be on
|
|
cmp LineNumber+2 ;..the last line, since illegal values
|
|
bne @keepGoing ;..of text offset are not permited.
|
|
ldy #TERecord.NumberOfLines
|
|
lda [RecordPtr],y
|
|
cmp LineNumber
|
|
beq @lastLine
|
|
|
|
@keepGoing jsr AreWePageBreaking
|
|
beq @skipPage
|
|
lda TextOffset
|
|
ora TextOffset+2
|
|
beq @skipPage
|
|
jsr FindPageInfo
|
|
lda TextOffset
|
|
cmp SuperStart
|
|
bne @skipPage
|
|
lda TextOffset+2
|
|
cmp SuperStart+2
|
|
bne @skipPage
|
|
mov PageHeight,LineHeight
|
|
|
|
@skipPage lda TextVPos ;add the line height to TextVPos to move
|
|
clc ;..to the next line
|
|
adc LineHeight
|
|
sta TextVPos
|
|
ldy #TERecord.ViewRect.bottom ;are we still in the viewRect ?
|
|
cmp [RecordPtr],y
|
|
bmi @lineLoop ;..yep, so continue looping
|
|
|
|
lda [RecordPtr],y ;get the bottom of the view rect again
|
|
sta TextVPos ;..and put it in TextVPos
|
|
jsr GetRightMargin
|
|
sta TextHPos
|
|
brl abortBottom ;abort with past the end of the screen
|
|
|
|
@lastLine subl TextOffset,SuperLength,TextOffset
|
|
;---------------------------------------------------------------
|
|
foundLine jsr GetLeftEdge ;start at the left edge of the rectangle
|
|
sta TextHPos
|
|
jsr FindAndInstallStyle ;find and install the new style info, then
|
|
jsr SetupWidthTable ;..setup the width table
|
|
|
|
lda OriginalOffset ;find out how many characters are left
|
|
sec ;..in the line.
|
|
sbc TextOffset
|
|
sta AmountLeft ;this is our outer text counter
|
|
sta LineOffset ;cache this for later with tabs
|
|
beql foundChar
|
|
;---------------------------------------------------------------
|
|
mainLoop jsr FindAndInstallStyle ;find and install the current style info
|
|
jsr GetSuperCount ;count how many characters are in the
|
|
cmp AmountLeft ;..current style. If this is > 64k, $FFFF
|
|
bge useLeft ;..will be returned.
|
|
sta TextCount ;the amount left is greater than the count
|
|
lda AmountLeft ;..in the current style, so reduce the amount
|
|
sec ;..left and use the current style count.
|
|
sbc TextCount ;In this case we will need to loop back to
|
|
sta AmountLeft ;..mainLoop eventually.
|
|
bra widthStart
|
|
|
|
useLeft lda AmountLeft ;the current style extends at least to the offset
|
|
sta TextCount ;..we are looking for.
|
|
stz AmountLeft ;zero out our outer text counter
|
|
;---------------------------------------------------------------
|
|
widthStart jsr FindTextPtr ;setup the text pointer
|
|
lda #0 ;set the high word of A to zero
|
|
tax ;also clear the index (X-Reg)
|
|
shortm ;short mode for speed
|
|
|
|
widthLoop txy
|
|
lda [TextPtr],y ;get the character
|
|
cmp #TAB ;is it a TAB ?
|
|
beq doTab
|
|
tay ;nope, so use the char as an index into
|
|
lda [WidthTablePtr],y ;..the width table. Add the width of the
|
|
clc ;..character to the current horz position
|
|
adc TextHPos
|
|
sta TextHPos
|
|
bcc nextChar
|
|
inc TextHPos+1 ;we are in short mode, so take care of the
|
|
nextChar inx ;..high BYTE !
|
|
cpx TextCount
|
|
blt widthLoop
|
|
|
|
longm ;back to long mode
|
|
lda TextCount ;move TextOffset past the characters
|
|
addl TextOffset ;..we just processed.
|
|
lda AmountLeft ;are there any more "parts" to process ?
|
|
bne mainLoop ;..yep = go back to the main loop
|
|
bra foundChar ;Nope, we found our character - goto foundChar
|
|
;---------------------------------------------------------------
|
|
doTab longm ;goto long mode for Tab processing
|
|
jsr MoveOverTab
|
|
sta TextHPos ;store the new HPos
|
|
sep #$20 ;set the processor to short mode
|
|
bra nextChar ;back to short mode and off to the next char
|
|
;---------------------------------------------------------------
|
|
foundChar jsr AdjustForJust
|
|
clc
|
|
adc TextHPos
|
|
sta TextHPos
|
|
lda FixExtraSpace ;if no fractional adjustment then we are
|
|
ora FixExtraSpace+2 ;..done
|
|
beq skipAdjust
|
|
|
|
jsr FindLineStart
|
|
jsr FindTextPtr
|
|
ldx #0
|
|
ldy LineOffset
|
|
@loop dey
|
|
beq @done
|
|
lda [TextPtr],y
|
|
cmp #' '
|
|
bne @nope
|
|
inx
|
|
@nope cmp #TAB
|
|
bne @loop
|
|
@done PushLongSpace ;space for the multiply
|
|
PushZLong FixExtraSpace ;the fractional pixel amount for spaces
|
|
phx ;the number of spaces
|
|
pea $0000
|
|
_FixMul
|
|
plx ;discard the fraction
|
|
pla ;the carry will be set if X > $8000 and
|
|
cpx #$8000 ;..clr if less than $8000. This rounds
|
|
adc TextHPos ;..the fraction into the nearest integer
|
|
sta TextHPos
|
|
|
|
skipAdjust ldy #TERecord.ViewRect.left
|
|
lda TextHPos
|
|
clc
|
|
adc [RecordPtr],y
|
|
sta TextHPos
|
|
jsr FreeWidthTable
|
|
movl OriginalOffset,TextOffset
|
|
clc ;clear the carry to indicate we are on the
|
|
rts ;..screen
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
****************************************************************
|
|
; the super handle comes in in A,X. the item that is operated on
|
|
; is the current one and the new length is in SuperLength. The
|
|
; extra amount is added to or subtracted from the NEXT item in
|
|
; the super array.
|
|
;---------------------------------------------------------------
|
|
ChangeSuperLength PROCNAME
|
|
|
|
stax TempLong ;save the passed super handle
|
|
jsr SetupSuperPtrs ;the SuperHandle comes in in A,X
|
|
;---------------------------------------------------------------
|
|
lda [TempPtr],y ;calculate (oldValue - newValue). leave
|
|
sec ;..the low word of the result on the
|
|
sbc SuperLength ;..stack and the high word in X-Reg.
|
|
pha
|
|
lda SuperLength ;also move the newValue into the array
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda [TempPtr],y
|
|
sbc SuperLength+2
|
|
tax
|
|
lda SuperLength+2
|
|
sta [TempPtr],y
|
|
|
|
jsr checkForRemove ;remove this item if the new length is zero
|
|
bcs @skipAdd ;TRUE means the item was removed, so don't
|
|
lda SuperLocalIndex ;..move to the next item
|
|
clc
|
|
adc SuperItemSize
|
|
|
|
@skipAdd inc a ;start with the high word of the item
|
|
inc a
|
|
tay
|
|
lda [TempPtr],y
|
|
dey
|
|
dey
|
|
and [TempPtr],y ;if both the low and high words are $FFFF
|
|
inc a ;..then goto next block
|
|
beq nextBlock
|
|
;---------------------------------------------------------------
|
|
doItem pla ;get back the low part of the difference
|
|
clc ;add the difference to the next item
|
|
adc [TempPtr],y
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
txa
|
|
adc [TempPtr],y
|
|
sta [TempPtr],y
|
|
brl checkForRemove ;remove this item if the length is zero
|
|
;---------------------------------------------------------------
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
nextBlock ldy #2 ;update the length field in the first
|
|
lda 1,s ;..block
|
|
clc
|
|
adc [TempPtr]
|
|
sta [TempPtr]
|
|
txa
|
|
adc [TempPtr],y
|
|
sta [TempPtr],y
|
|
|
|
lda SuperMainIndex ;move the main index to the next block
|
|
clc
|
|
adc #4
|
|
sta SuperMainIndex
|
|
jsr GetLocalSuperHandle
|
|
sta TempPtr
|
|
stx TempPtr+2
|
|
bmi @atEnd ;is this the final end ?
|
|
jsr DerefTempPtr ;local handle goes to local ptr
|
|
|
|
ldy #2 ;update the length field of the new block
|
|
lda [TempPtr]
|
|
sec
|
|
sbc 1,s
|
|
sta [TempPtr]
|
|
phx
|
|
lda [TempPtr],y
|
|
sbc 1,s
|
|
sta [TempPtr],y
|
|
plx
|
|
ldy #SuperBlockRecord.firstItem
|
|
bra doItem
|
|
|
|
@atEnd rts
|
|
;---------------------------------------------------------------
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
checkForRemove dey ;A-Reg contains the high word of the item
|
|
dey ;check for the item being zero
|
|
ora [TempPtr],y
|
|
beq @removeIt ;..if it is then remove it.
|
|
clc ;FALSE = did not remove an item
|
|
rts
|
|
|
|
@removeIt phx ;save the high word of the difference
|
|
|
|
bit StyleFlag
|
|
bpl @skipStyle
|
|
|
|
tya
|
|
clc
|
|
adc #4
|
|
tay
|
|
lda [TempPtr],y
|
|
sta TextStyleOffset
|
|
iny
|
|
iny
|
|
lda [TempPtr],y
|
|
sta TextStyleOffset+2
|
|
PushZLong TempPtr
|
|
jsr SetupStylePtr
|
|
ldy #2
|
|
lda [TempPtr]
|
|
bne @decIt
|
|
lda [TempPtr],y
|
|
dec a
|
|
sta [TempPtr],y
|
|
lda [TempPtr]
|
|
@decIt dec a
|
|
sta [TempPtr]
|
|
PullLong TempPtr
|
|
|
|
@skipStyle ldy #SuperBlockRecord.count
|
|
lda [TempPtr],y
|
|
dec a
|
|
sta [TempPtr],y
|
|
bne @insideBlock
|
|
|
|
lda #SuperBlockRecord.firstItem ;for reseting the pointers later
|
|
sta SuperLocalIndex
|
|
lda SuperMainIndex
|
|
sta DestPtr
|
|
clc
|
|
adc #4
|
|
sta SourcePtr
|
|
ldax TempLong
|
|
bra @crunchIt
|
|
|
|
@insideBlock lda SuperLocalIndex
|
|
sta DestPtr
|
|
clc
|
|
adc SuperItemSize
|
|
sta SourcePtr
|
|
jsr GetLocalSuperHandle
|
|
|
|
@crunchIt stz SourcePtr+2 ;zero the high words of the pointers
|
|
stz DestPtr+2
|
|
jsr CrunchHandle
|
|
ldax TempLong
|
|
jsr SetupSuperPtrs
|
|
|
|
plx
|
|
lda SuperLocalIndex
|
|
sec
|
|
rts
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
InsertSuperItem PROCNAME
|
|
|
|
PushAX ;save the super handle
|
|
jsr FindSuperInfo ;find the right spot in the super array
|
|
|
|
ldy SuperMainIndex ;get the local handle into TempPtr
|
|
lda [MainSuperPtr],y
|
|
sta TempPtr
|
|
tax
|
|
iny
|
|
iny
|
|
lda [MainSuperPtr],y
|
|
sta TempPtr+2
|
|
pha ;one copy for set handle size
|
|
phx
|
|
pha ;..and one for get handle size
|
|
phx
|
|
jsr GetHandleSize
|
|
stax MoveLength
|
|
clc
|
|
adc SuperItemSize
|
|
bcc @1
|
|
inx
|
|
@1 jsr SetHandleSize
|
|
|
|
jsr DerefTempPtr ;the local handle is still in TempPtr
|
|
lda SuperLocalIndex
|
|
clc
|
|
adc SuperItemSize
|
|
pha ;save this value for later
|
|
adc TempPtr
|
|
sta SourcePtr ;calculate the source pointer
|
|
lda TempPtr+2
|
|
adc #0
|
|
sta SourcePtr+2
|
|
sta DestPtr+2
|
|
lda SourcePtr ;..and the destination pointer
|
|
clc
|
|
adc SuperItemSize
|
|
sta DestPtr
|
|
bcc @2
|
|
inc DestPtr+2
|
|
@2 lda MoveLength ;calculate the length to move
|
|
sec
|
|
sbc 1,s
|
|
plx
|
|
sta MoveLength
|
|
lda MoveLength+2
|
|
sbc #0
|
|
sta MoveLength+2
|
|
jsr BlockMove ;move it !!
|
|
|
|
ldy SuperLocalIndex ;adjust the length of the first item
|
|
lda TextOffset
|
|
sec
|
|
sbc SuperStart
|
|
sta TempLong
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda TextOffset+2
|
|
sbc SuperStart+2
|
|
sta TempLong+2
|
|
sta [TempPtr],y
|
|
|
|
dey
|
|
dey
|
|
tya ;move the index to the next item
|
|
clc
|
|
adc SuperItemSize
|
|
tay
|
|
|
|
lda SuperLength ;adjust the length of the next item
|
|
sec
|
|
sbc TempLong
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda SuperLength+2
|
|
sbc TempLong+2
|
|
sta [TempPtr],y
|
|
|
|
ldy #SuperBlockRecord.count ;increment the item count
|
|
lda [TempPtr],y
|
|
inc a
|
|
sta [TempPtr],y
|
|
|
|
PullAX ;restore the super handle
|
|
brl FindSuperInfo ;re-position things to the new item.
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
GetLocalSuperHandle PROCNAME
|
|
|
|
ldy SuperMainIndex
|
|
lda [MainSuperPtr],y
|
|
pha
|
|
iny
|
|
iny
|
|
lda [MainSuperPtr],y
|
|
tax
|
|
pla
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
InsertStyleItem PROCNAME
|
|
|
|
ldy #TERecord.StyleSuper
|
|
jsr GetRecordLong
|
|
brl InsertSuperItem
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
ChangeStyleLength PROCNAME
|
|
|
|
lda #$FFFF
|
|
sta StyleFlag
|
|
ldy #TERecord.StyleSuper
|
|
jsr GetRecordLong
|
|
brl ChangeSuperLength
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
****************************************************************
|
|
|
|
FlipSelection PROCNAME
|
|
|
|
tempRgn1 equ 0
|
|
tempRgn2 equ 4
|
|
|
|
ldy #TERecord.SelectionActive
|
|
lda [RecordPtr],y
|
|
bne deactivate
|
|
|
|
ldy #TERecord.SelectionRect1
|
|
jsr CopyIntoTempRect
|
|
jsr InvertTempRect
|
|
|
|
ldy #TERecord.SelectionRect2
|
|
jsr CopyIntoTempRect
|
|
jsr InvertTempRect
|
|
|
|
ldy #TERecord.SelectionRect3
|
|
jsr CopyIntoTempRect
|
|
jsr InvertTempRect
|
|
|
|
done rts
|
|
|
|
deactivate jsr IsTheSelectionACaret
|
|
bne notCaret
|
|
|
|
PushLong #greyMask
|
|
_SetPenMask
|
|
|
|
ldy #TERecord.SelectionRect1
|
|
jsr CopyIntoTempRect
|
|
jsr InvertTempRect
|
|
|
|
PushLong #blackMask
|
|
_SetPenMask
|
|
|
|
bra done
|
|
|
|
notCaret PushZLong tempRgn1 ;save these temps
|
|
PushZLong tempRgn2
|
|
|
|
jsr GetNewRgn ;get two temporary regions
|
|
stax tempRgn1
|
|
jsr GetNewRgn
|
|
stax tempRgn2
|
|
|
|
ldy #TERecord.SelectionRect1
|
|
jsr CopyIntoTempRect
|
|
PushZLong tempRgn1
|
|
PushZPtr TempRect
|
|
_RectRgn
|
|
|
|
ldy #TERecord.SelectionRect2
|
|
jsr CopyIntoTempRect
|
|
PushZLong tempRgn2
|
|
PushZPtr TempRect
|
|
_RectRgn
|
|
|
|
PushZLong tempRgn1
|
|
PushZLong tempRgn2
|
|
PushZLong tempRgn1
|
|
_UnionRgn
|
|
|
|
ldy #TERecord.SelectionRect3
|
|
jsr CopyIntoTempRect
|
|
PushZLong tempRgn2
|
|
PushZPtr TempRect
|
|
_RectRgn
|
|
|
|
PushZLong tempRgn1
|
|
PushZLong tempRgn2
|
|
PushZLong tempRgn1
|
|
_UnionRgn
|
|
|
|
PushWord #$8002 ;use not X-OR mode
|
|
_SetPenMode
|
|
|
|
PushWord #0 ;black pattern
|
|
_SetSolidPenPat
|
|
|
|
PushZLong tempRgn1
|
|
_FrameRgn
|
|
|
|
PushZLong tempRgn1
|
|
_DisposeRgn
|
|
PushZLong tempRgn2
|
|
_DisposeRgn
|
|
|
|
PullLong tempRgn2 ;restore these temps
|
|
PullLong tempRgn1
|
|
|
|
rts
|
|
|
|
greyMask dc.w $AA55,$AA55
|
|
dc.w $AA55,$AA55
|
|
|
|
blackMask dc.w $FFFF,$FFFF
|
|
dc.w $FFFF,$FFFF
|
|
|
|
ENDP
|
|
****************************************************************
|
|
|
|
****************************************************************
|
|
|
|
CheckForFastReplace PROCNAME
|
|
|
|
sec
|
|
rts
|
|
|
|
jsr GetTextLength
|
|
cpx #0
|
|
bne @1
|
|
cmp #2
|
|
blt notFast
|
|
@1
|
|
jsr GetJust ;if the text is not left justified then
|
|
cmp #leftJust ;..we must redraw the entire line
|
|
bne notFast
|
|
|
|
lda RemovedHeight
|
|
ora RemovedHeight+2
|
|
bne notFast
|
|
lda RemovedAscent
|
|
ora RemovedAscent+2
|
|
bne notFast
|
|
|
|
ldy InputTextLength+2
|
|
bne notFast
|
|
ldy InputTextLength
|
|
bmi notFast
|
|
@loop dey
|
|
bmi @2
|
|
lda [InputTextPtr],y
|
|
and #$00FF
|
|
cmp #$0D
|
|
beq notFast
|
|
cmp #PAGE_BREAK
|
|
beq notFast
|
|
bra @loop
|
|
@2
|
|
jsr GetRightMargin
|
|
clc
|
|
ldy #TERecord.ViewRect.left
|
|
adc [RecordPtr],y
|
|
sta LineRightEdge
|
|
|
|
jsr GetSelectionStart
|
|
jsr FindLineStart
|
|
lda TextOffset
|
|
ora TextOffset+2
|
|
beq @skipFirst
|
|
decl TextOffset
|
|
jsr checkLine
|
|
@skipFirst
|
|
jsr GetSelectionStart
|
|
jsr checkLine
|
|
|
|
clc
|
|
rts
|
|
;---------------------------------------------------------------
|
|
notFast sec
|
|
rts
|
|
;---------------------------------------------------------------
|
|
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
checkLine jsr FindLineStart
|
|
PushZWord LineAscent
|
|
PushZWord LineHeight
|
|
jsr FindAndInstallStyle
|
|
|
|
lda #0 ;clear the maximum text height and ascent
|
|
tax
|
|
ldy #TERecord.MaxTextHeight
|
|
jsr SetRecordLong
|
|
|
|
lda LineRightEdge
|
|
sta TextHPos
|
|
jsr HPosToOffset
|
|
lda LineRightEdge ;compare the right edge with our position
|
|
cmp TextHPos
|
|
bge @1
|
|
decl TextOffset
|
|
@1 jsr FindTextPtr
|
|
lda [TextPtr]
|
|
and #$00FF
|
|
cmp #CR
|
|
bne @2
|
|
incl TextOffset
|
|
@2
|
|
PullAX
|
|
ldy #TERecord.MaxTextHeight
|
|
cmp [RecordPtr],y
|
|
bne @nope
|
|
txa
|
|
ldy #TERecord.MaxTextAscent
|
|
cmp [RecordPtr],y
|
|
bne @nope
|
|
|
|
jsr IsTextOffsetAtEnd
|
|
beq @checkEnd
|
|
jsr FindLineInfo
|
|
lda TextOffset
|
|
cmp SuperStart
|
|
bne @nope
|
|
lda TextOffset+2
|
|
cmp SuperStart+2
|
|
bne @nope
|
|
@done rts
|
|
|
|
@checkEnd decl TextOffset
|
|
jsr FindTextPtr
|
|
lda [TextPtr]
|
|
and #$00FF
|
|
cmp #CR
|
|
beq @ccc
|
|
ldy #TERecord.LineAtEndFlag
|
|
lda [RecordPtr],y
|
|
bpl @nope
|
|
bra @done
|
|
@ccc ldy #TERecord.LineAtEndFlag
|
|
lda [RecordPtr],y
|
|
bmi @nope
|
|
bra @done
|
|
|
|
@nope pla ;go back one level
|
|
sec
|
|
rts
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
****************************************************************
|
|
|
|
;---------------------------------------------------------------
|
|
&index SETA 80
|
|
WHILE >&index > 0 DO
|
|
|
|
lda |&index,y
|
|
sta >&index,x
|
|
|
|
&index SETA &index-1
|
|
ENDWHILE
|
|
;---------------------------------------------------------------
|
|
|
|
****************************************************************
|
|
|
|
Entry1Proc PROC
|
|
|
|
EXPORT QuickEntry
|
|
EXPORT QuickExit
|
|
EXPORT StandardEntry
|
|
EXPORT StandardExit
|
|
|
|
;---------------------------------------------------------------
|
|
DSECT 1
|
|
TEDirectPtr long
|
|
UserDirectPage word
|
|
RPart1 word
|
|
RPart2 word
|
|
RPart3 word
|
|
UserStuff word
|
|
;---------------------------------------------------------------
|
|
ErrorCode equ 0
|
|
;---------------------------------------------------------------
|
|
RetSave equ 0
|
|
;---------------------------------------------------------------
|
|
|
|
;---------------------------------------------------------------
|
|
QuickEntry jsl IncBusyFlg ;increment busy flag (doesn't change ANYTHING)
|
|
|
|
plx ;pull the return address in X-Reg
|
|
phd ;save the user's direct page
|
|
tcd ;set ours from our WAP
|
|
beq notStarted ;if zero, then we are not started
|
|
stx TempWord ;use TempWord to hold the return address
|
|
tyx ;check to see if the number of parameters
|
|
beq @skipMove ;..is zero.
|
|
clc ;make a pointer to our parameter
|
|
adc #ParameterSpace-2 ;..area in our direct page and save it
|
|
pea $0000 ;the high word is zero
|
|
pha
|
|
tsc ;get the current stack pointer
|
|
phx ;save the number of parameters for adjust
|
|
phd ;save our direct page
|
|
phx ;save the number of parameters for move
|
|
tcd ;set direct page to the old stack pointer
|
|
|
|
@loop lda UserStuff-2,x ;copy our parameters to OUR direct page
|
|
txy
|
|
sta [TEDirectPtr],y
|
|
dex
|
|
dex
|
|
bne @loop
|
|
|
|
@stripIt plx ;get back the number of parameters
|
|
lda RPart3 ;copy the user's direct page and the two
|
|
sta RPart3,x ;..return addrs over the parameters
|
|
lda RPart2
|
|
sta RPart2,x
|
|
lda RPart1
|
|
sta RPart1,x
|
|
lda UserDirectPage
|
|
sta UserDirectPage,x
|
|
tdc ;get the original stack pointer
|
|
pld ;restore our direct page
|
|
clc ;adjust the stack pointer by
|
|
adc 1,s ;..the number of parameters
|
|
adc #4 ;skip over the allocated pointer
|
|
tcs ;and set it back.
|
|
@skipMove phb ;save the user's data bank
|
|
phk ;set our data bank.
|
|
plb
|
|
pei TempWord
|
|
rts ;return to caller
|
|
|
|
notStarted tsc
|
|
tcd
|
|
lda RPart3-4 ;copy the user's direct page and the two
|
|
sta RPart3-4,x ;..return addrs over the parameters
|
|
lda RPart2-4
|
|
sta RPart2-4,x
|
|
lda RPart1-4
|
|
sta RPart1-4,x
|
|
lda UserDirectPage-4
|
|
sta UserDirectPage-4,x
|
|
phx
|
|
tdc ;adjust the stack
|
|
clc
|
|
adc 1,s
|
|
tcs
|
|
phb ;save the user's data bank
|
|
phk ;set our data bank.
|
|
plb
|
|
ldx #teNotStarted ;load the not started error
|
|
;---------------------------------------------------------------
|
|
QuickExit plb ;restore the original data bank
|
|
pld ;restore original direct page
|
|
txa ;put the error code into A
|
|
cmp #1 ;set the carry flag
|
|
jml DecBusyFlg ;decrement busy flag and return to caller
|
|
;---------------------------------------------------------------
|
|
StandardEntry plx ;pull off the return address
|
|
phd ;save the user's direct page
|
|
tcd ;set ours from our WAP
|
|
beq notStarted ;if zero, then we are not started, so use
|
|
stx RetSave ;..quick entry to exit.
|
|
pld
|
|
jsr QuickEntry ;setup TextEdit. number of parameters in Y
|
|
|
|
lda RecordHandle
|
|
ora RecordHandle+2
|
|
bne useThisOne
|
|
|
|
PushLongSpace
|
|
_FindActiveCtl
|
|
tax ;put the error code in the X-Reg
|
|
pla
|
|
sta RecordHandle
|
|
pla
|
|
sta RecordHandle+2
|
|
bcs QuickExit
|
|
useThisOne
|
|
jsr LockRecordHandle ;lock the main record handle
|
|
|
|
PushLongSpace ;save the current port
|
|
_GetPort
|
|
jsr SetWindowPort
|
|
|
|
pei RetSave
|
|
rts
|
|
;---------------------------------------------------------------
|
|
StandardExit stx ErrorCode
|
|
|
|
_SetPort
|
|
jsr UnlockRecordHandle
|
|
|
|
ldx ErrorCode
|
|
bra QuickExit
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
DSECT WorkArea
|
|
dstPortPtr long ;these are for the low level drawing
|
|
srcPtr long ;..routines
|
|
dstPtr long
|
|
srcWidth word
|
|
dstWidth word
|
|
numberOfWords word
|
|
numberOfLines word
|
|
leftMask word
|
|
rightMask word
|
|
|
|
****************************************************************
|
|
|
|
FindWordEnd PROCNAME
|
|
|
|
bra FindWordEndNew
|
|
decl TextOffset
|
|
jsr FindTextPtr
|
|
lda [TextPtr]
|
|
jsr IsItAWordBreak
|
|
bcs alreadyThere
|
|
|
|
@loop incl TextOffset
|
|
jsr IsOffsetAtEnd
|
|
beq atEnd
|
|
jsr FindTextPtr
|
|
lda [TextPtr]
|
|
jsr IsItAWordBreak
|
|
bcc @loop
|
|
atEnd rts
|
|
|
|
alreadyThere incl TextOffset
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
* the value to be draw comes in in A
|
|
****************************************************************
|
|
DebugHexWord PROC EXPORT
|
|
|
|
phb ;save the data bank
|
|
phk ;set it to ours
|
|
plb
|
|
|
|
PushLongSpace
|
|
pha
|
|
_HexIt
|
|
PullLong tempStr
|
|
|
|
PushLong #theRect
|
|
_GetPen
|
|
PushLong #theInfo
|
|
_GetFontInfo
|
|
|
|
PushWordSpace
|
|
PushLong #tempStr
|
|
_CStringWidth
|
|
pla
|
|
clc
|
|
adc theRectLeft
|
|
sta theRectRight
|
|
lda theRectTop
|
|
clc
|
|
adc theInfoAscent
|
|
adc theInfoDescent
|
|
sta theRectBottom
|
|
PushLong #theRect
|
|
_EraseRect
|
|
|
|
PushWord #0
|
|
PushWord theInfoAscent
|
|
_Move
|
|
PushLong #tempStr
|
|
_DrawCString
|
|
|
|
lda #30
|
|
jsr DebugDelay
|
|
|
|
plb ;restore the data bank
|
|
rts
|
|
|
|
origTicks ds.l 1
|
|
|
|
theRect
|
|
theRectTop ds.w 1
|
|
theRectLeft ds.w 1
|
|
theRectBottom ds.w 1
|
|
theRectRight ds.w 1
|
|
|
|
theInfo
|
|
theInfoAscent ds.w 1
|
|
theInfoDescent ds.w 1
|
|
theInfoWidMax ds.w 1
|
|
theInfoLeading ds.w 1
|
|
|
|
tempStr ds.b 4
|
|
dc.b 0
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
DebugDelay PROC
|
|
|
|
sta origTicks
|
|
stz origTicks+2
|
|
PushLongSpace
|
|
_TickCount
|
|
pla
|
|
clc
|
|
adc origTicks
|
|
sta origTicks
|
|
pla
|
|
adc origTicks+2
|
|
sta origTicks+2
|
|
|
|
@loop PushLongSpace
|
|
_TickCount
|
|
PullAX
|
|
cmpl origTicks
|
|
blt @loop
|
|
|
|
rts
|
|
|
|
origTicks ds.l 1
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
CalculateRemovedHeight PROCNAME
|
|
|
|
;---------------------------------------------------------------
|
|
stzl RemovedHeight ;this is for removing lines
|
|
|
|
jsr GetSelectionLength
|
|
lda SelectionLength
|
|
ora SelectionLength+2
|
|
bne doIt
|
|
rts
|
|
;---------------------------------------------------------------
|
|
doIt ldy #TERecord.LineSuper
|
|
jsr FindSuperInfo
|
|
|
|
jsr GetSuperMaxIndex
|
|
ldy #SuperHandle.cachedIndex ;get the current index for the selection
|
|
lda [SuperRecordPtr],y ;..start into Y-Reg
|
|
inc a ;start with the high word
|
|
inc a
|
|
tay
|
|
|
|
lda TextOffset ;check to see if we are starting on the
|
|
cmp SuperStart ;..first item
|
|
bne @notAtStart
|
|
lda TextOffset+2
|
|
cmp SuperStart+2
|
|
beq itemLoop
|
|
|
|
@notAtStart sty TempWord
|
|
jsr GetLongSuperCount
|
|
stax SuperLength
|
|
jsr adjustSelection
|
|
bcc allDone
|
|
ldy TempWord
|
|
bra enterLoop
|
|
;---------------------------------------------------------------
|
|
ItemLoop lda [TempPtr],y
|
|
bmi deletedItem
|
|
lda [TempPtr],y
|
|
sta SuperLength+2
|
|
dey
|
|
dey
|
|
lda [TempPtr],y
|
|
sta SuperLength
|
|
jsr adjustSelection
|
|
bcc allDone
|
|
iny
|
|
iny
|
|
enterLoop iny
|
|
iny
|
|
lda [TempPtr],y
|
|
addl RemovedHeight
|
|
tya
|
|
clc
|
|
adc #SuperItemSize-2
|
|
bra nextItem
|
|
deletedItem tya
|
|
clc
|
|
adc #SuperItemSize
|
|
nextItem tay
|
|
cpy SuperMaxIndex
|
|
blt ItemLoop
|
|
|
|
jsr MoveToNextHandle
|
|
bcs allDone
|
|
ldy #SuperBlock.RecordSize+2
|
|
bra ItemLoop
|
|
;---------------------------------------------------------------
|
|
allDone rts
|
|
;---------------------------------------------------------------
|
|
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
adjustSelection lda SelectionLength
|
|
sec
|
|
sbc SuperLength
|
|
sta SelectionLength
|
|
lda SelectionLength+2
|
|
sbc SuperLength+2
|
|
sta SelectionLength+2 ;carry remains set if we are continuing
|
|
ora SelectionLength ;carry is clear if we are done
|
|
rts ;..the Z-Flag is set if we are done
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
SplitBlockList PROCNAME Export
|
|
|
|
;---------------------------------------------------------------
|
|
jsr CachedBlockToPtr ;set TempPtr to our current block and
|
|
movl BlockHandle,TempLong ;..save the block handle in TempLong
|
|
|
|
@loop1 ldy #TextBlock.textLength+2 ;move back through all the previous blocks
|
|
lda [TempPtr],y ;..including the current one and see if
|
|
bne splitBlock ;..any of them are too big. If they are
|
|
ldy #TextBlock.textLength ;..then split just one of them
|
|
lda [TempPtr],y
|
|
cmp #MaxBlockSize
|
|
bge splitBlock
|
|
jsr MoveToPrevBlock
|
|
bcc @loop1
|
|
|
|
movl TempLong,BlockHandle ;restore our original block handle, then
|
|
jsr BlockHandleToPtr ;..move through all the blocks after this
|
|
bra @enter2 ;..one to see if any of these are too big.
|
|
@loop2 ldy #TextBlock.textLength+2 ;..If one is, then split it.
|
|
lda [TempPtr],y
|
|
bne splitBlock
|
|
ldy #TextBlock.textLength
|
|
lda [TempPtr],y
|
|
cmp #MaxBlockSize
|
|
bge splitBlock
|
|
@enter2 jsr MoveToNextBlock
|
|
bcc @loop2
|
|
|
|
exit rts ;everything was small, so exit
|
|
;---------------------------------------------------------------
|
|
splitBlock ldx #$FFE0 ;find the maximum number of characters
|
|
ldy #TextBlock.textLength+2 ;..to search through
|
|
lda [TempPtr],y
|
|
bne @1
|
|
dey
|
|
dey
|
|
lda [TempPtr],y
|
|
cmp #$FFE0
|
|
bge @1
|
|
tax
|
|
|
|
@1 ldy #TextBlock.textStart+SplitBlockSize
|
|
shortm ;look for the first carriage return after
|
|
@loop lda [TempPtr],y ;..the splitting block size. Note that
|
|
cmp #CR ;..if we can't find a CR in the first
|
|
beq doIt ;..64K, we abort the split
|
|
iny
|
|
dex
|
|
bne @loop
|
|
longm
|
|
abortIt rts
|
|
;---------------------------------------------------------------
|
|
doIt longm ;back to long mode
|
|
cpy #$FEFF ;If our index is greater than this, we
|
|
bge abortIt ;..will break some other code later on
|
|
tya ;..that assumes no overflow from a word.
|
|
sec ;If our index is too big, then abort the
|
|
sbc #TextBlock.textStart ;..split. Otherwise adjust the index back
|
|
sta TempWord ;..to a text offset and this is the new
|
|
|
|
ldy #TextBlock.textLength ;..length of the old block. Now find the
|
|
lda [TempPtr],y ;..length of the NEW block.
|
|
sec
|
|
sbc TempWord
|
|
sta MoveLength
|
|
lda TempWord ;also set the new length of the old block
|
|
sta [TempPtr],y ;..in the record.
|
|
iny
|
|
iny
|
|
lda [TempPtr],y
|
|
sbc #0
|
|
sta MoveLength+2
|
|
lda #0 ;the high word of the new length is always
|
|
sta [TempPtr],y ;..zero
|
|
|
|
ldax MoveLength ;round off and adjust the new length. Then
|
|
and #$FF00 ;..get a handle of the proper size
|
|
clc
|
|
adc #256+TextBlock.textStart
|
|
bcc @1
|
|
inx
|
|
@1 jsr GetLargeHandle ;if we get a memory error, then abort the
|
|
bcs abortIt ;..split
|
|
stax TempLong ;save the new handle in TempLong and
|
|
jsr DerefAX ;..deref it into MemoryPtr
|
|
stax MemoryPtr
|
|
|
|
jsr BlockHandleToPtr ;reset TempPtr in case the block moved
|
|
|
|
ldy #TextBlock.nextHandle ;set the next handle field for both the
|
|
lda [TempPtr],y ;..new block and the old block
|
|
sta [MemoryPtr],y
|
|
lda TempLong
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda [TempPtr],y
|
|
sta [MemoryPtr],y
|
|
lda TempLong+2
|
|
sta [TempPtr],y
|
|
|
|
ldy #TextBlock.prevHandle ;set the previous handle of the new block
|
|
lda BlockHandle
|
|
sta [MemoryPtr],y
|
|
iny
|
|
iny
|
|
lda BlockHandle+2
|
|
sta [MemoryPtr],y
|
|
|
|
ldy #TextBlock.textLength ;set the length of the new block
|
|
lda MoveLength
|
|
sta [MemoryPtr],y
|
|
iny
|
|
iny
|
|
lda MoveLength+2
|
|
sta [MemoryPtr],y
|
|
|
|
ldy #TextBlock.flags ;clear the flags for the new block
|
|
lda #0
|
|
sta [MemoryPtr],y
|
|
|
|
lda TempWord ;find the source pointer for moving the
|
|
clc ;..text from the old block to the new one
|
|
adc #TextBlock.textStart
|
|
adc TempPtr
|
|
sta SourcePtr
|
|
lda TempPtr+2
|
|
adc #0
|
|
sta SourcePtr+2
|
|
|
|
lda #TextBlock.textStart ;the dest pointer is the pointer to the
|
|
clc ;..start of the new block adjusted for
|
|
adc MemoryPtr ;..the header
|
|
sta DestPtr
|
|
lda MemoryPtr+2
|
|
adc #0
|
|
sta DestPtr+2
|
|
|
|
jsr BlockMove ;move the text
|
|
|
|
PushZLong BlockHandle ;set the size of the old handle to free
|
|
ldx #0 ;..up memory
|
|
lda TempWord
|
|
and #$FF00
|
|
clc
|
|
adc #256+TextBlock.textStart
|
|
jsr SetHandleSize
|
|
|
|
jsr BlockHandleToPtr ;reset TempPtr in case the block moved
|
|
jsr MoveToNextBlock ;this moves to the newly created block
|
|
jsr MoveToNextBlock ;find the next block and if there is one
|
|
bcs @allDone ;..then set the prev handle field of it
|
|
ldy #TextBlock.prevHandle ;..to the new block
|
|
lda TempLong
|
|
sta [TempPtr],y
|
|
iny
|
|
iny
|
|
lda TempLong+2
|
|
sta [TempPtr],y
|
|
@allDone rts
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
* this routine concatenates two handles
|
|
****************************************************************
|
|
HandAndHand PROCNAME Export
|
|
|
|
;---------------------------------------------------------------
|
|
DefineStack
|
|
origD word
|
|
returnAddr word
|
|
srcHandle long
|
|
dstHandle long
|
|
;---------------------------------------------------------------
|
|
|
|
phd ;save the old direct page
|
|
tsc ;setup our new direct page
|
|
tcd
|
|
|
|
ldy #HandleRecord.length ;get the size of the destination handle
|
|
lda [dstHandle],y
|
|
pha ;save the low word of the old length
|
|
clc
|
|
adc [srcHandle],y
|
|
tax
|
|
iny
|
|
iny
|
|
lda [dstHandle],y
|
|
pha ;save the high word of the old length
|
|
adc [srcHandle],y
|
|
pha ;Push the new size for set handle size
|
|
phx
|
|
PushZLong dstHandle
|
|
_SetHandleSize
|
|
bcs error
|
|
|
|
lda [dstHandle],y ;add the size of the original dest
|
|
tax ;..handle and put it in dest handle
|
|
pla
|
|
clc
|
|
adc [dstHandle]
|
|
sta dstHandle
|
|
txa
|
|
adc 1,s
|
|
sta dstHandle+2
|
|
plx
|
|
|
|
ldy #2
|
|
lda [srcHandle],y
|
|
tax
|
|
lda [srcHandle]
|
|
PushAX
|
|
PushZLong dstHandle ;now a pointer to the end of the old dest
|
|
ldy #HandleRecord.length+2 ;get the size of the source handle
|
|
lda [srcHandle],y
|
|
pha
|
|
dey
|
|
dey
|
|
lda [srcHandle],y
|
|
pha
|
|
PushWord #%0000100000000101
|
|
jsl $E10200 ;use the memory mover
|
|
|
|
lda returnAddr
|
|
sta dstHandle+2
|
|
|
|
clc ;indicate no error
|
|
;---------------------------------------------------------------
|
|
done pld
|
|
pla ;pull off 8 bytes of garbage
|
|
pla
|
|
pla
|
|
pla
|
|
rts
|
|
;---------------------------------------------------------------
|
|
error tax
|
|
pla ;cleanup the stack
|
|
pla
|
|
sec
|
|
bra done
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
Save0_4 PROCNAME Export
|
|
|
|
ply
|
|
pei 2
|
|
pei 0
|
|
phy
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
Restore0_4 PROCNAME Export
|
|
|
|
pha
|
|
lda 5,s
|
|
sta 2
|
|
pla
|
|
sta 3,s
|
|
pla
|
|
sta 0
|
|
pla
|
|
rts
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
|
|
IncRecordLong PROCNAME Export
|
|
|
|
lda [RecordPtr],y
|
|
inc a
|
|
sta [RecordPtr],y
|
|
bcc skipHigh
|
|
iny
|
|
iny
|
|
lda [RecordPtr],y
|
|
inc a
|
|
sta [RecordPtr],y
|
|
skipHigh rts
|
|
|
|
ENDP
|
|
|
|
moveGrowBox PushLongSpace ;find the new top/left of the grow box
|
|
_GrowSize ;..and move it to this position
|
|
ldy #GrafPort.portRect.bottom
|
|
lda [TempPtr],y
|
|
inc a
|
|
sec
|
|
sbc 1,s ;leave the new Y-Pos on the stack
|
|
sta 1,s
|
|
ldy #GrafPort.portRect.right
|
|
lda [TempPtr],y
|
|
inc a
|
|
sec
|
|
sbc 3,s ;leave the new X-Pos on the stack
|
|
sta 3,s
|
|
jsr GetGrowBoxHandle ;push the control handle
|
|
PushAX
|
|
_MoveControl
|
|
****************************************************************
|
|
|
|
TEScroll PROCNAME Export
|
|
|
|
;---------------------------------------------------------------
|
|
DSECT ParameterSpace
|
|
xRecordHandle long
|
|
horzAmount long
|
|
vertAmount long
|
|
theScrollVerb word
|
|
;---------------------------------------------------------------
|
|
|
|
;---------------------------------------------------------------
|
|
ldy #14
|
|
jsr StandardEntry
|
|
|
|
ldx #teInvalidVerb ;check for a verb overflow. If the verb
|
|
lda theScrollVerb ;..is ok, then jump thru the table.
|
|
cmp #6
|
|
bge error
|
|
asl a
|
|
tax
|
|
jmp (table,x)
|
|
;---------------------------------------------------------------
|
|
doTopOffset nop
|
|
doCenterOffset nop
|
|
doTopLine nop
|
|
doCenterLine nop
|
|
;---------------------------------------------------------------
|
|
doSetValue ldy #TERecord.VertScrollPos ;get the difference between the new value
|
|
lda vertAmount ;..and the old one and store it back in
|
|
sec ;..vertAmount.
|
|
sbc [RecordPtr],y
|
|
sta vertAmount
|
|
iny
|
|
iny
|
|
lda vertAmount+2
|
|
sbc [RecordPtr],y ;then, fall through into doOffsetValue
|
|
sta vertAmount+2 ;..to do the actual scroll
|
|
|
|
doOffsetValue ldax vertAmount ;A-Reg and X-Reg contain the amount to scroll
|
|
jsr ScrollByAmount ;..Then do it and fall thru into goodExit
|
|
;---------------------------------------------------------------
|
|
goodExit ldx #0 ;no error
|
|
error brl StandardExit
|
|
;---------------------------------------------------------------
|
|
|
|
;---------------------------------------------------------------
|
|
table dc.w doTopOffset
|
|
dc.w doCenterOffset
|
|
dc.w doTopLine
|
|
dc.w doCenterLine
|
|
dc.w doSetValue
|
|
dc.w doOffsetValue
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
****************************************************************
|
|
|
|
;---------------------------------------------------------------
|
|
checkitnow
|
|
ldy #TERecord.LastErrorCode
|
|
lda [RecordPtr],y
|
|
bne @error
|
|
|
|
jsr CachedBlockToPtr
|
|
lda TempPtr
|
|
ora TempPtr+2
|
|
beq @break
|
|
rts
|
|
|
|
@break brk $49
|
|
rts
|
|
@error brk $48
|
|
rts
|
|
|
|
;---------------------------------------------------------------
|
|
|
|
****************************************************************
|
|
|
|
WalkText PROCNAME Export
|
|
DSECT ParameterSpace
|
|
xRecordHandle long
|
|
CallBackPtr long
|
|
CallBackData long
|
|
TheVerb word
|
|
iTheLength long ; use some temp space in parameter area
|
|
iTheTemp long ; use some more temps!
|
|
MaxVerb equ $000F
|
|
TEInvalidCallBack equ $0024
|
|
TEBadLength equ $0025
|
|
;---------------------------------------------------------------
|
|
lda TheVerb ;first validate the verb
|
|
and #$00FF
|
|
cmp #MaxVerb
|
|
blt @VerbOK
|
|
ldx #teInvalidFlag
|
|
sec
|
|
rts
|
|
@VerbOK
|
|
lda CallBackPtr+1 ; next validate the callback pointer
|
|
beq @BadCallBack ; see if some bozo passed a nil
|
|
lda CallBackPtr+2
|
|
and #$00FF
|
|
cmp CallBackPtr+2 ; see if some bozo passed a random 4byte
|
|
beq @GoodCallBack
|
|
@BadCallBack ldx #teInvalidCallBack
|
|
sec
|
|
rts
|
|
;---------------------------------------------------------------
|
|
@GoodCallBack
|
|
; At this point we have done all the initializing that we can be expected to do...
|
|
;
|
|
; First position us at the very beginning of the text super block list...
|
|
jsr CachedBlockToPtr ;find the first block in the list
|
|
@loop1 jsr MoveToPrevBlock
|
|
bcc @loop1
|
|
; now at the top of the super block list, examine the verb to determine where to start
|
|
; and how long to go...
|
|
lda theVerb
|
|
and #$00FF ; strip off the flags byte..
|
|
asl a
|
|
tax
|
|
jsr (WalkTbl,x) ; calc the proper start/length
|
|
bcc @Loop ; start thru the loop if no error
|
|
ldx #teBadLength
|
|
sec
|
|
rts
|
|
;
|
|
; At this point textOffset is set to the proper starting location for us to run the list
|
|
; and the temp length variable is set to the length that we want to run.
|
|
;---------------------------------------------------------------
|
|
@loop jsr FindTextPtr ; set text ptr and block ptr to proper place...
|
|
; Now set up the data for our callback...
|
|
pha ; room for result
|
|
ldax TextOffset ; push block offset
|
|
PushAX
|
|
ldax BlockLength ; get the size of the current block
|
|
stax iTheTemp ; save it for later in the temp
|
|
ldax BlockStart ; see if we are at the beginning of a block..
|
|
cmp TextOffset ; by comparing to the text offset
|
|
bne @NotAtStart
|
|
cpx TextOffset+2
|
|
beq @AtStart
|
|
@NotAtStart
|
|
subl TextOffset,BlockStart,iTheTemp ; temp:=offset-blkStart
|
|
subl BlockLength,iTheTemp,iTheTemp ; temp:=Length-temp
|
|
@AtStart ldax iTheTemp ; temp now contains the size of the rest of the block
|
|
PushAX ; save the current block length...
|
|
ldax TextPtr ; push the BlockPointer
|
|
pushAX
|
|
ldax xRecordHandle ; and finally the record handle..
|
|
pushAX
|
|
jsl CallCallBack ; now call the callback routine!
|
|
|
|
jsr BlockHandleToPtr ; re-deref the current super handle
|
|
ldy #TextBlock.nextHandle+1 ; see if this was the last block
|
|
lda [tempPtr],y
|
|
beq @AtTheEnd ; if we are at the last block then just get out!
|
|
; bump textoffset and continue
|
|
addl TextOffset,iTheTemp,TextOffset ; offset := offset+temp
|
|
subl iTheLength,iTheTemp,iTheLength ; length:=length-temp
|
|
lda iTheLength+2
|
|
bmi @AtTheEnd ; if negative, then we are done..
|
|
ora iTheLength
|
|
beq @AtTheEnd ; or if its zero we are done!
|
|
bra @loop
|
|
;---------------------------------------------------------------
|
|
@AtTheEnd ldx #0
|
|
;---------------------------------------------------------------
|
|
allDone ;if the buffer was full, return buffer
|
|
cpx #1 ;..full error
|
|
rts
|
|
;---------------------------------------------------------------
|
|
CallCallBack
|
|
; This routine calls the routine passed by the programmer by cleverly
|
|
; stuffing its address-1 on the stack and RTLing
|
|
pha ; make room on the stack for 3 bytes..
|
|
phk
|
|
lda CallBackPtr+1
|
|
sta 2,s
|
|
lda CallBackPtr
|
|
dec a
|
|
sta 1,s
|
|
rtl
|
|
|
|
;---------------------------------------------------------------
|
|
doWholeRecord
|
|
; Set up the start to 0 and the length to the number of chars in the record
|
|
stzL TextOffset ; set the start to 0
|
|
jsr GetTextLength
|
|
stx iTheLength+2
|
|
sta iTheLength
|
|
doTestLength ora iTheLength+2 ; be sure we have data to run!
|
|
bne @ok
|
|
sec
|
|
rts
|
|
@ok clc ; flag that its ok data
|
|
rts
|
|
|
|
;---------------------------------------------------------------
|
|
doFromSelStart jsr GetSelectionStart ; set text offset first
|
|
dFSelCont stax TextOffset
|
|
jsr GetTextLength ; now, to calculate the remaining bytes
|
|
stax iTheLength
|
|
subl iTheLength,textOffset,iTheLength ; length:=length-offset
|
|
lda iTheLength
|
|
bra doTestLength
|
|
;---------------------------------------------------------------
|
|
doFromSelEnd jsr GetSelectionEnd
|
|
bra dfSelCont
|
|
;---------------------------------------------------------------
|
|
doSelectionOnly jsr GetSelectionStart
|
|
stax TextOffset
|
|
jsr GetSelectionLength
|
|
stax iTheLength
|
|
lda iTheLength
|
|
bra doTestLength
|
|
;---------------------------------------------------------------
|
|
doFromArbitrary ldax CallBackData ; programmer passed us the starting point
|
|
stax TextOffset
|
|
jsr GetTextLength
|
|
stax iTheLength
|
|
subl iTheLength,TextOffset,iTheLength ; length:=length-offset
|
|
bcs @LengthOK ; test here to see if subtract created
|
|
sec ; a negative number
|
|
rts ; if so flag an error and end.
|
|
@LengthOK lda iTheLength
|
|
bra doTestLength
|
|
;---------------------------------------------------------------
|
|
doGivenRange ldy #2
|
|
lda [CallBackData],y ; call back data for this is ptr
|
|
sta TextOffset+2 ; to the 2 longs of data
|
|
lda [callBackData]
|
|
sta TextOffset
|
|
iny
|
|
iny
|
|
lda [CallBackData],y
|
|
sta iTheLength
|
|
iny
|
|
iny
|
|
lda [CallBackData],y
|
|
sta iTheLength+2
|
|
; Now we must validate the length passed to be sure we don't crash
|
|
jsr GetTextLength ; test the offset first..
|
|
sec
|
|
sbc TextOffset
|
|
tay ; save it for a second..
|
|
txa
|
|
sbc TextOffset+2
|
|
bcc @BadOffset ; if carry clear out of record here!
|
|
tax
|
|
tya
|
|
sbc iTheLength ; now see if we are too long..
|
|
txa ; the result is un important..
|
|
sbc iTheLength+2
|
|
bcc @BadLength ; carry set here means they want too much data
|
|
@Cont lda iTheLength
|
|
brl doTestLength
|
|
@BadLength tya ; get the proper remaining chars in <A><X>
|
|
stax iTheLength
|
|
bra @cont
|
|
@BadOffset sec
|
|
rts
|
|
;---------------------------------------------------------------
|
|
WalkTbl dc.w doWholeRecord
|
|
dc.w doFromSelStart
|
|
dc.w doFromSelEnd
|
|
dc.w doSelectionOnly
|
|
dc.w doFromArbitrary
|
|
dc.W doGivenRange
|
|
;---------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|