mirror of
https://github.com/antoinevignau/source.git
synced 2025-01-20 02:30:40 +00:00
1 line
15 KiB
Plaintext
Executable File
1 line
15 KiB
Plaintext
Executable File
*****************************************************************************************************
|
|
* WP File I/O Routines
|
|
*
|
|
* This file contains the routines used to read and write WP scraps & PL text threads.
|
|
*
|
|
*****************************************************************************************************
|
|
|
|
load 'macros.dump'
|
|
include 'driver.equ'
|
|
include 'scrap.equ'
|
|
|
|
IMPORT D_AlertBox
|
|
IMPORT D_BeachBall
|
|
IMPORT D_CurCursor
|
|
IMPORT D_Deref
|
|
IMPORT D_NeedHandle
|
|
IMPORT D_Read2
|
|
IMPORT D_ReadHandle2
|
|
IMPORT D_SetCursor
|
|
IMPORT D_WriteHandle2
|
|
IMPORT D_MustHandle
|
|
IMPORT D_Write2
|
|
IMPORT D_SetMark2
|
|
|
|
IMPORT X_DisposeWPScrap
|
|
IMPORT X_MassageWPScrap
|
|
IMPORT X_OldCursor
|
|
IMPORT X_ParBlockSize
|
|
IMPORT X_ReadWPScrap
|
|
IMPORT X_RulerSize
|
|
IMPORT X_WriteThread
|
|
|
|
*****************************************************************************************************
|
|
; X_ScReadWPScrap ( FileRef:word, Type:word )
|
|
;
|
|
; This routine is called to read both WPScraps and PL text threads from disk. If Type is non-zero
|
|
; then read text thread else read WPscrap. FileRef should be the file reference to the already opened
|
|
; and correctly positioned file. Memory and disk errors are returned.
|
|
;
|
|
; It is assumed that the bank has already been set to the Scrap segments bank.
|
|
|
|
X_ScReadWPScrap PROC EXPORT
|
|
|
|
;Using X_WPScrapData
|
|
;Using X_WPFileData
|
|
;Using D_IOData
|
|
;Using X_ClipData
|
|
;Using D_CursorData
|
|
|
|
input FileRef:w,Type:w
|
|
local Bpars:w,SaveArraySize:l,SaveArrayHand:l,SAPtr:l
|
|
local Blocks:w,Rulers:w,Picts:w
|
|
local BListhand:l,BLPtr:l,RListHand:l,RLPtr:l,PListHand:l,PLPtr:l
|
|
local Block:l,Ruler:l,ScrapSize:l,ScrapPtr:l,RulerPtr:l
|
|
local PBlockSize:w,Scratch:l
|
|
local Handles:w,RHands:w,BHands:w
|
|
output Scrap:l
|
|
error err
|
|
begin
|
|
|
|
; Save the current cursor and put up the beachball cursor.
|
|
|
|
moveword >D_CurCursor,X_OldCursor
|
|
jsl D_Beachball
|
|
|
|
; Set PBlockSize depending on whether we are reading in a PL text thread or a WP scrap.
|
|
|
|
lda Type
|
|
bne notwp
|
|
moveword #X_ParBlockSize,PBlockSize
|
|
bra cont
|
|
notwp moveword #(X_ParBlockSize+4),PBlockSize
|
|
|
|
; Read in the # of paragraph blocks in the file. Use this count to create temporary array into which
|
|
; we will read the paragraph info. Create the handle for the scrap we will be filling in with the
|
|
; information we read from disk. If any memory or disk errors occur dispose of the memory we have
|
|
; allocated and exit.
|
|
|
|
cont call D_Read2,in=(FileRef:w,!Bpars:l,#2:l),out=(ax:l),err=err
|
|
jcs exit
|
|
|
|
tool _Multiply,in=(BPars:w,#12:w),out=(SaveArraySize:l)
|
|
call D_NeedHandle,in=(SaveArraySize:l,#$8000:w),out=(SaveArrayHand:l),err=err
|
|
jcs exit
|
|
movelong [SaveArrayHand],SAPtr
|
|
call D_Read2,in=(FileRef:w,SAPtr:l,SaveArraySize:l),out=(ax:l),err=err
|
|
jcs killsave
|
|
|
|
tool _Multiply,in=(Bpars:w,PBlockSize:w),out=(ScrapSize:l)
|
|
addlong ScrapSize,#2,ScrapSize
|
|
call D_NeedHandle,in=(ScrapSize:l,#$8000:w),out=(Scrap:l),err=err
|
|
jcs killsave
|
|
|
|
; Put the number of paragraphs into the first word of the scrap, then bump scrapptr past the
|
|
; paragraph count. Initialize the number of text blocks & rulers to zero.
|
|
|
|
movelong [Scrap],ScrapPtr
|
|
moveword BPars,[ScrapPtr]
|
|
addlong ScrapPtr,#2,ScrapPtr
|
|
|
|
stz Blocks
|
|
stz Rulers
|
|
stz Picts
|
|
|
|
; For all paragraph blocks do: copy paragraph info to the scrap; keep track of number of rulers and
|
|
; text blocks encountered.
|
|
|
|
parloop lda Bpars
|
|
jeq doneloop
|
|
|
|
textblock cmpw [SAPtr],Blocks
|
|
blt nonewblock
|
|
inc Blocks
|
|
|
|
nonewblock lda Type
|
|
bne realruler
|
|
ldy #4
|
|
lda [SAPtr],y
|
|
bne incloop
|
|
|
|
realruler cmpw [SAPtr]:#6,Rulers
|
|
blt incloop
|
|
inc Rulers
|
|
|
|
incloop moveword [SAPtr]:#2,[ScrapPtr]:#X_scpOffset
|
|
moveword [SAPtr]:#4,[ScrapPtr]:#X_scpAttr
|
|
moveword [SAPtr]:#8,[ScrapPtr]:#X_scpPixels
|
|
moveword [SAPtr]:#10,[ScrapPtr]:#X_scpLastLine
|
|
movelong #0,[ScrapPtr]:#X_scpLinehand
|
|
addlong SAPtr,#12,SAPtr
|
|
addwl PBlockSize,ScrapPtr
|
|
dec Bpars
|
|
brl parloop
|
|
|
|
; Create handle to store ruler handles in until we are sure we will succeed.
|
|
|
|
doneloop lda Rulers
|
|
asl a
|
|
asl a
|
|
ldx #0
|
|
call D_NeedHandle,in=(ax:l,#$8000:w),out=(RListHand:l),err=err
|
|
jcs killscrap
|
|
movelong [RListHand],RLPtr
|
|
|
|
; Read in all the rulers remembering their handles in the ruler list so we can recover from errors.
|
|
|
|
stz RHands
|
|
ruleinloop jsl D_BeachBall
|
|
cmpw RHands,Rulers
|
|
jge endrloop
|
|
|
|
call D_NeedHandle,in=(#X_RulerSize:l,#$8000:w),out=(Ruler:l),err=err
|
|
jcs killrulers
|
|
movelong [Ruler],RulerPtr
|
|
|
|
lda RHands
|
|
asl a
|
|
asl a
|
|
tay
|
|
movelong Ruler,[RLPtr]:y
|
|
inc RHands
|
|
|
|
call D_Read2,in=(FileRef:w,RulerPtr:l,#X_RulerSize:l),out=(ax:l),err=err
|
|
jcs killrulers
|
|
tool _HUnlock,in=(Ruler:l)
|
|
brl ruleinloop
|
|
|
|
; If no text blocks exist then branch to handle pictures (ha ha).
|
|
|
|
endrloop lda Blocks
|
|
jeq dopicts
|
|
|
|
; Create handle to store text block handles in until we are sure we will succeed.
|
|
|
|
lda Blocks
|
|
asl a
|
|
asl a
|
|
ldx #0
|
|
call D_NeedHandle,in=(ax:l,#$8000:w),out=(BListHand:l),err=err
|
|
jcs killrulers
|
|
movelong [BListHand],BLPtr
|
|
|
|
; Read in all the text blocks putting their handles in the block list so we can recover from errors.
|
|
|
|
stz BHands
|
|
readbloop jsl D_BeachBall
|
|
call D_ReadHandle2,in=(FileRef:w),out=(Block:l),err=err
|
|
jcs killblocks
|
|
tool _HUnlock,in=(Block:l)
|
|
|
|
lda BHands
|
|
asl a
|
|
asl a
|
|
tay
|
|
movelong Block,[BLPtr]:y
|
|
inc BHands
|
|
cmpw BHands,Blocks
|
|
blt readbloop
|
|
|
|
; Handle reading picts ( picts not supported at this time ).
|
|
|
|
dopicts
|
|
|
|
; Use the reference indexes in the save array to put the text block & ruler handles we have read in
|
|
; the scrap paragraphs.
|
|
|
|
doinsert movelong [SaveArrayHand],SAPtr
|
|
movelong [Scrap],ScrapPtr
|
|
moveword [ScrapPtr],Bpars
|
|
addlong ScrapPtr,#2,ScrapPtr
|
|
|
|
stz Handles
|
|
insertloop moveword [SAPtr],a
|
|
asl a
|
|
asl a
|
|
tay
|
|
movelong [BLPtr]:y,[ScrapPtr]
|
|
lda Type
|
|
bne dorulesub
|
|
moveword [SAPtr]:#4,a
|
|
bne iloopinc
|
|
|
|
dorulesub moveword [SAPtr]:#6,a
|
|
asl a
|
|
asl a
|
|
tay
|
|
movelong [RLPtr]:y,[ScrapPtr]:#X_scpRulerHand
|
|
|
|
iloopinc inc Handles
|
|
addwl #12,SAptr
|
|
addwl PBlocksize,ScrapPtr
|
|
cmpw Handles,Bpars
|
|
jlt insertloop
|
|
|
|
; Successfully read in the scrap. Unlock the scrap and dispose of the text block & ruler lists.
|
|
; Dispose of the save array and exit with no error.
|
|
|
|
readdone tool _HUnlock,in=(Scrap:l)
|
|
lda Blocks
|
|
beq chkrlist
|
|
tool _DisposeHandle,in=(BListHand:l)
|
|
chkrlist lda Rulers
|
|
beq gokillsave
|
|
tool _DisposeHandle,in=(RListHand:l)
|
|
gokillsave brl killsave
|
|
|
|
; Error occurred. Dispose of all memory allocated so far.
|
|
|
|
killblocks lda BHands
|
|
beq killblist
|
|
dec a
|
|
asl a
|
|
asl a
|
|
tay
|
|
tool _DisposeHandle,in=([BLPtr]:y:l)
|
|
dec BHands
|
|
bra killblocks
|
|
killblist tool _DisposeHandle,in=(BListHand:l)
|
|
|
|
killrulers lda RHands
|
|
beq killrlist
|
|
dec a
|
|
asl a
|
|
asl a
|
|
tay
|
|
tool _DisposeHandle,in=([RLPtr]:y:l)
|
|
dec RHands
|
|
bra killrulers
|
|
killrlist tool _DisposeHandle,in=(RListHand:l)
|
|
|
|
killscrap tool _DisposeHandle,in=(Scrap:l)
|
|
killsave tool _DisposeHandle,in=(SaveArrayHand:l)
|
|
exit call D_SetCursor,in=(X_OldCursor:w)
|
|
return
|
|
|
|
ENDP
|
|
|
|
|
|
*****************************************************************************************************
|
|
; X_ScWriteWPScrap ( FileRef:word, Type:word )
|
|
;
|
|
; This routine is called to write both WPScraps and PL text threads from disk. If Type is non-zero
|
|
; then write text thread else write WPscrap. FileRef should be the file reference to the already
|
|
; opened and correctly positioned file. Memory and disk errors are returned.
|
|
;
|
|
; It is assumed that the bank has already been set to the Scrap segments bank.
|
|
|
|
X_ScWriteWPScrap PROC EXPORT
|
|
|
|
input FileRef:w,Scrap:l,Type:w
|
|
local Sptr:l,Pars:w
|
|
error err
|
|
begin
|
|
|
|
; Lock down the scrap; point past the paragraph count and call write thread to do the actual work.
|
|
|
|
tool _HLock,in=(Scrap:l)
|
|
movelong [Scrap],Sptr
|
|
moveword [Sptr],Pars
|
|
addwl #2,Sptr
|
|
call X_WriteThread,in=(FileRef:w,Pars:w,Sptr:l,Type:w),err=err
|
|
|
|
return
|
|
ENDP
|
|
|
|
*****************************************************************************************************
|
|
; X_ScWriteThread ( FileRef:word, Pars:word, Scrap:long, Type:word )
|
|
;
|
|
|
|
X_ScWriteThread PROC EXPORT
|
|
;Using X_WPScrapData
|
|
;Using X_WPFileData
|
|
;Using D_IOData
|
|
;Using X_ClipData
|
|
;Using D_CursorData
|
|
|
|
input FileRef:w,Pars:w,Scrap:l,Type:w
|
|
local Ptr:l,Bpars:w,SaveArraySize:l,SaveArrayHand:l,SAPtr:l
|
|
local BListPtr:l,BListhand:l,BLPtr:l,RListHand:l,RLPtr:l
|
|
local PicListHand:l,PLPtr:l,Blocks:w,Rulers:w,Picts:w
|
|
local BListSize:l,Block:l,Ruler:l,ScrapPtr:l
|
|
local PBlockSize:w,Scratch:l,ScratchSize:l
|
|
local ScratchPtr:l,Temp2:l,Temp:l
|
|
error err
|
|
begin
|
|
|
|
; Save the current cursor and put up the beachball cursor.
|
|
|
|
moveword >D_CurCursor,X_OldCursor
|
|
jsl D_Beachball
|
|
stz err
|
|
|
|
; Set PBlockSize depending on whether we are writing a PL text thread or a WP scrap.
|
|
|
|
lda Type
|
|
bne notwp
|
|
moveword #X_ParBlockSize,PBlockSize
|
|
bra cont
|
|
notwp moveword #(X_ParBlockSize+4),PBlockSize
|
|
|
|
; Setup local variables. Ptr will point to current location in document scrap and Bpars will contain
|
|
; the number of paragraphs in the scrap to go.
|
|
|
|
cont movelong Scrap,Ptr
|
|
moveword Pars,Bpars
|
|
|
|
; Yuk! We must copy all the paragraph information to a separate array where we will modify things
|
|
; like the ruler and text block handles to be indexes instead of handles. ( ie make it a semi-flat
|
|
; structure to save to disk. ) If we get a memory error then pass it back to the caller.
|
|
|
|
tool _Multiply,in=(Bpars:w,#12:w),out=(SaveArraySize:l)
|
|
call D_MustHandle,in=(SaveArraySize:l,#0:w),out=(SaveArrayHand:l),err=err
|
|
jcs exit
|
|
|
|
; Yuk! again! We must create lookup array for text block handles.
|
|
|
|
lda Bpars
|
|
asl a
|
|
asl a
|
|
sta BListSize
|
|
ldx #0
|
|
call D_MustHandle,in=(ax:l,#0:w),out=(BListHand:l),err=err
|
|
jcs killsave
|
|
|
|
; Yuk! Yuk! We must create lookup array for ruler handles.
|
|
|
|
call D_MustHandle,in=(#0:w,BListSize:w,#0:w),out=(RListHand:l),err=err
|
|
jcs killblist
|
|
|
|
; Lock down the handle and get their pointers.
|
|
|
|
rcall D_Deref,in=(SaveArrayHand:ax),out=(SAPtr:ax)
|
|
rcall D_Deref,in=(BListHand:ax),out=(BLPtr:ax)
|
|
rcall D_Deref,in=(RListHand:ax),out=(RLPtr:ax)
|
|
|
|
; Clear counts and initialize variables before loop.
|
|
|
|
stz Blocks
|
|
stz Rulers
|
|
stz Picts
|
|
stzl Block
|
|
movelong Scrap,Ptr
|
|
|
|
; For all paragraphs do:
|
|
|
|
parloop lda Bpars
|
|
jeq endloop
|
|
|
|
; Check if first time through if so add first text block in scrap to the block lookup array.
|
|
|
|
lda Block
|
|
ora Block+2
|
|
bne notfirst
|
|
movelong [Ptr],Block
|
|
bra addtolist
|
|
|
|
; Check if the text block currently being pointed to in the scrap is the same as the last text block
|
|
; we saw. If not add it to the block lookup array and make it the last block seen. If it is the same
|
|
; block then branch to handle the current paragraph ruler.
|
|
|
|
notfirst cmpl [Ptr],Block
|
|
beq dorulers
|
|
|
|
addtolist lda Blocks
|
|
asl a
|
|
asl a
|
|
tay
|
|
movelong [Ptr],[BLPtr]:y
|
|
inc Blocks
|
|
movelong [Ptr],Block
|
|
|
|
; Check if ruler exists. If WP scrap and Attr is non-zero then must be a page break paragraph and
|
|
; therefore won't have a ruler associated with it. In all other cases ruler should exist.
|
|
|
|
dorulers lda Type
|
|
bne realruler
|
|
ldy #X_scpAttr
|
|
lda [Ptr],y
|
|
jne endruler
|
|
|
|
; Scan through ruler lookup array trying to find the same ruler handle as the current one {temp}.
|
|
|
|
realruler ldx #0
|
|
movelong [Ptr]:#X_scpRulerHand,Temp
|
|
rulerloop txa
|
|
cmp Rulers
|
|
bge nofindruler
|
|
asl a
|
|
asl a
|
|
tay
|
|
cmpl Temp,[RLPtr]:y
|
|
beq rulerfound
|
|
inx
|
|
bra rulerloop
|
|
|
|
; Ruler found so put its lookup value in the save array.
|
|
|
|
rulerfound txa
|
|
bra putrulenum
|
|
|
|
; Ruler was not found so we need to add it to the lookup array and bump the ruler count.
|
|
|
|
nofindruler txa
|
|
asl a
|
|
asl a
|
|
pha
|
|
ldy #X_scpRulerHand
|
|
lda [Ptr],y
|
|
ply
|
|
phy
|
|
sta [RLPtr],y
|
|
ldy #X_scpRulerHand+2
|
|
lda [Ptr],y
|
|
ply
|
|
iny
|
|
iny
|
|
sta [RLPtr],y
|
|
inc Rulers
|
|
txa
|
|
|
|
putrulenum moveword a,[SAPtr]:#6
|
|
|
|
; Save the lookup value for the current text block, and the remaining paragraph information.
|
|
|
|
endruler lda Blocks
|
|
dec a
|
|
sta [SAPtr]
|
|
moveword [Ptr]:#X_scpOffset,[SAPtr]:#2
|
|
moveword [Ptr]:#X_scpAttr,[SAPtr]:#4
|
|
moveword [Ptr]:#X_scpPixels,[SAPtr]:#8
|
|
moveword [Ptr]:#X_scpLastLine,[SAPtr]:#10
|
|
|
|
; Point save array pointer past the paragraph info we just saved. Bump the scrap pointer past the
|
|
; paragraph we just processed. Decrement the number of paragraphs left to do and go back for more.
|
|
|
|
addlong SAPtr,#12,SAPtr
|
|
addwl PBlockSize,Ptr
|
|
dec Bpars
|
|
brl parloop
|
|
|
|
; Ok we have filled up the save array with all the paragraphs info. Ruler & text block handles have
|
|
; been replaced with their lookup values. No save out the paragraph cout and the save array.
|
|
|
|
endloop moveword Pars,Bpars
|
|
call D_Write2,in=(FileRef:w,!Bpars:l,#2:l),out=(ax:l),err=err
|
|
jcs killrlist
|
|
|
|
call D_Write2,in=(FileRef:w,[SaveArrayHand]:l,SaveArraySize:l),out=(ax:l),err=err
|
|
jcs killrlist
|
|
|
|
; Write out rulers
|
|
|
|
movelong RLPtr,temp
|
|
ruleoutloop jsl D_BeachBall
|
|
lda Rulers
|
|
beq endruleout
|
|
movelong [temp],Ruler
|
|
tool _HLock,in=(Ruler:l)
|
|
call D_Write2,in=(FileRef:w,[Ruler]:l,#X_RulerSize:l),out=(ax:l),err=err
|
|
jcs killrlist
|
|
tool _HUnlock,in=(Ruler:l)
|
|
addwl #4,temp
|
|
dec Rulers
|
|
bra ruleoutloop
|
|
endruleout
|
|
|
|
; Write out paragraph blocks. Paragraph blocks are written out as a long for the size of the
|
|
; paragraph and then the paragraph block is written out. The text block is shrunk by writing
|
|
; out the used size for both the block size & used size.
|
|
|
|
movelong BLPtr,temp
|
|
paroutloop jsl D_BeachBall
|
|
lda Blocks
|
|
jeq dopictout
|
|
|
|
movelong [temp],Scratch
|
|
movelong [Scratch],ScratchPtr
|
|
ldy #2
|
|
lda [ScratchPtr],y
|
|
sta ScratchSize
|
|
stz ScratchSize+2
|
|
call D_Write2,in=(FileRef:w,!ScratchSize:l,#4:l),out=(ax:l),err=err
|
|
jcs killrlist
|
|
|
|
addwl #2,ScratchPtr
|
|
call D_Write2,in=(FileRef:w,ScratchPtr:l,#2:l),out=(ax:l),err=err
|
|
jcs killrlist
|
|
|
|
sublong ScratchSize,#2,ScratchSize
|
|
call D_Write2,in=(FileRef:w,ScratchPtr:l,ScratchSize:l),out=(ax:l),err=err
|
|
jcs killrlist
|
|
|
|
addwl #4,temp
|
|
dec Blocks
|
|
brl paroutloop
|
|
|
|
; Write out picture blocks ( not implemented in this version ).
|
|
|
|
dopictout
|
|
|
|
; Dispose of all the memory that we allocated to save the scrap/thread.
|
|
|
|
killrlist tool _DisposeHandle,in=(RListHand:l)
|
|
killblist tool _DisposeHandle,in=(BListHand:l)
|
|
killsave tool _DisposeHandle,in=(SaveArrayHand:l)
|
|
exit call D_SetCursor,in=(X_OldCursor:w)
|
|
return
|
|
|
|
ENDP
|
|
|
|
*****************************************************************************************************
|
|
; X_ScImportWP ( FileRef:word )
|
|
;
|
|
; This routine will read from the given WP document and create a WP scrap from it. If the document
|
|
; is blank then warn the user and return an error. Memory & disk errors will be returned.
|
|
|
|
X_ScImportWP PROC EXPORT
|
|
;Using D_IOData
|
|
;Using X_WPFileData
|
|
|
|
input FileRef:w
|
|
local Offset:w,TotalOffset:l,Temp:l,Temp2:l,FileRef:w
|
|
output Dest:l
|
|
error err
|
|
begin
|
|
|
|
; Set the file mark after the file header, and the wp header. This is a hard wired magic number!!
|
|
; Yeah!! Isn't programming fun.
|
|
|
|
call D_SetMark2,in=(FileRef:w,#0:w,#$29C:l),err=err
|
|
|
|
; Read the WP document as a scrap.
|
|
|
|
call X_ReadWPScrap,in=(FileRef:w,#0:w),out=(Dest:l),err=err
|
|
bcs exit
|
|
|
|
; Separate the first and last paragraphs into their own text blocks.
|
|
|
|
call X_MassageWPScrap,in=(Dest:l),err=err
|
|
bcc checkblank
|
|
call X_DisposeWPScrap,in=(Dest:l)
|
|
stzl Dest
|
|
bra exit
|
|
|
|
; If there is one paragraph and its text block is of size 12 then warn user that document is blank.
|
|
|
|
checkblank movelong [Dest],Temp
|
|
Cmpw [Temp],#2
|
|
bge exit
|
|
movelong [Temp]:#2,Temp2
|
|
movelong [Temp2],Temp
|
|
Cmpw [Temp]:#2,#13
|
|
bge exit
|
|
call D_AlertBox,in=(#OKBox:w,#BlankScrap:l),out=(a:w)
|
|
call X_DisposeWPScrap,in=(Dest:l)
|
|
movelong #-1,err
|
|
|
|
exit return
|
|
|
|
BlankScrap STR 'This document is blank.'
|
|
|
|
ENDP
|
|
END
|
|
|