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

1 line
12 KiB
Plaintext
Executable File

*****************************************************************************************************
* WPFileIO Routines
*
* This file contains the WP open and save routines.
*
*****************************************************************************************************
load 'macros.dump'
include 'driver.equ'
include 'wp.equ'
IMPORT D_AlertBox
IMPORT D_BeachBall
IMPORT D_BitMapChanged
IMPORT D_BitMapPtr
IMPORT D_ClearFileChanged
IMPORT D_Deref
IMPORT D_GrowHandle
IMPORT D_KillFont
IMPORT D_MemoryError
IMPORT D_NeedHandle
IMPORT D_SystemHandle
IMPORT D_StringBuffer
IMPORT D_Read2
IMPORT D_Write2
IMPORT W_CollapseRulers
IMPORT W_CurDoc
IMPORT W_FillDateTime
IMPORT W_GetAddr
IMPORT W_GetDoc
IMPORT W_GetParRec
IMPORT W_LastP
IMPORT W_MakeScrollBar
IMPORT W_MaxP
IMPORT W_NewWinComin
IMPORT W_PHandle
IMPORT W_PPtr
IMPORT W_PutDoc
IMPORT W_ScrollBar
IMPORT W_SetFullREct
IMPORT D_SetRefCon
IMPORT W_ShowRuler
IMPORT W_SizeWinGlobals
IMPORT W_StartPar
IMPORT W_StartRuler
IMPORT W_StartWinGlobals
IMPORT W_SwitchData
IMPORT W_View
IMPORT X_DisposeWPScrap
IMPORT X_ReadWPScrap
IMPORT X_WriteThread
*****************************************************************************************************
; W_OpenDoc ( FileRef:word, WindowPtr:long )
;
; This routine will handle reading in a word processing document with the given file reference.
; The file has already been opened by the driver and the file mark moved to the start of the document
; data. Memory or file I/O errors are returned to the driver which will handle closing the file and
; alerting the user.
W_OpenDoc PROC EXPORT
;Using WpGlobals
;Using D_IOData
;Using W_SampleData
;Using W_ATTRData
;Using W_WPFileIOData
EXPORT W_FVersion
input FileRef:w,window:l
local Scrap:l,ScrapPtr:l,ScrapSize:l,OldShowRul:w
local Version:w,CurView:w,RefHand:l,Ptr:l,SaveDoc:l
local bodyscrap:l,footerscrap:l,headerscrap:l
error err
begin +b
; Clear error status, save current document's data to its refcon, save the document so it can be
; restored before exiting, and make the input window the current document. Remember the old port
; on the stack and setport to new window.
stz err
jsl W_PutDoc
movelong W_CurDoc,SaveDoc
movelong window,W_CurDoc
tool _GetPort,out=(:l)
tool _SetPort,in=(window:l)
; Create the refcon handle that will hold this windows globals. If we get a memory err then exit.
call D_NeedHandle,in=(#W_SizeWinGlobals:l,#attrfixed:w),out=(RefHand:l),err=err
jcs exit
; Set window refcon to the handle we created.
movelong [RefHand],Ptr
call D_SetRefCon,in=(Ptr:l,Window:l)
; Get version number from file. If error reading then exit after disposing of refcon. Check if valid
; version if not warn user and exit.
call D_Read2,in=(FileRef:w,!Version:l,#2:l),out=(ax:l),err=err
jcs killref
cmpw Version,W_FVersion
jlt laterversion
cmp #1
jeq earlyversion
; Read in the globals for the document. If error then dispose of refcon and exit.
call D_Read2,in=(FileRef:w,#W_StartWinGlobals:l,#W_SizeWinGlobals:l),out=(ax:l),err=err
jcs killref
; Save ruler status and view status brought in from file.
moveword W_ShowRuler,OldShowRul
moveword W_View,CurView
; Read in the document body, header, and footer. If any memory errors occurs dispose of the scraps
; we have read so far and the document refcon we created.
call X_ReadWPScrap,in=(FileRef:w,#0:w),out=(bodyscrap:l),err=err
jcs killref
call X_ReadWPScrap,in=(FileRef:w,#0:w),out=(headerscrap:l),err=err
jcs killbody
call X_ReadWPScrap,in=(FileRef:w,#0:w),out=(footerscrap:l),err=err
jcs killheader
; Successfully read in all three document parts as WP scraps. Now managle each scrap into a document
; thread and switch it into its correct globals location. Finally switch to the document part that
; was being edited when the document was saved.
call W_SwitchData,in=(#W_NormalOn:w)
movelong bodyscrap,scrap
jsr manglescrap
call W_SwitchData,in=(#W_HeaderOn:w)
movelong headerscrap,scrap
jsr manglescrap
call W_SwitchData,in=(#W_FooterOn:w)
movelong footerscrap,scrap
jsr manglescrap
call W_SwitchData,in=(CurView:w)
; Kill the current font and set clip rect to entire port rect.
jsl D_KillFont
jsl W_SetFullREct
; Create new scroll bar for this document window. By setting W_ScrollBar to NIL we make sure that
; a new scroll bar will be created. Call MakeScrollBar with flag set to indicate that clip rect
; is already set correctly.
stzl W_ScrollBar
call W_MakeScrollBar,in=(#1:w)
; Get ptr to start paragraph record use this to derive the start ruler.
rcall W_GetParRec,in=(W_StartPar:a),out=(ScrapPtr:ax)
movelong [ScrapPtr]:#W_pRulerHand,W_StartRuler
; Get current date & time into WP string buffers. Clear the file changed status.
jsl W_FillDateTime
call D_ClearFileChanged,in=(window:l)
movelong window,W_NewWinComin
bra exit
; Handle version errors. Return -1 error to the driver to say we handled it.
laterversion
movelong #LaterString,xy
bra doalert
earlyversion
movelong #EarlyString,xy
doalert call D_AlertBox,in=(#OkBox:w,xy:l),out=(a:w)
dec err
bra killref
; Dispose of memory allocated for error recovery.
killheader call X_DisposeWPScrap,in=(headerscrap:l)
killbody call X_DisposeWPScrap,in=(bodyscrap:l)
killref tool _DisposeHandle,in=(RefHand:l)
; Restore the old port and document before returning.
exit tool _SetPort
call W_GetDoc,in=(SaveDoc:l)
return
;...................................................................................................;
LaterString str 'Later version of AppleWorks GS needed to load this file.'
EarlyString str 'This file cannot be opened by this version of AppleWorks GS.'
W_FVersion DC.W 2
;...................................................................................................;
*
* Mangle "scrap" into a document thread. ie remove the paragraph count word from the front of the
* scrap.
; Get paragraph count from scrap as last & max paragraphs.
manglescrap movelong [Scrap],ScrapPtr
moveword [ScrapPtr],W_LastP
moveword W_LastP,W_MaxP
; Resize the scrap down to remove the paragraph count and turn it into a "real" wp document.
; Note: We are sizing the handle down so no memory error is possible.
tool _GetHandleSize,in=(Scrap:l),out=(ScrapSize:l)
AddLong ScrapPtr,#2,s
PushLong ScrapPtr
SubLong ScrapSize,#2,ScrapSize
PushLong Scrapsize
_BlockMove
call D_GrowHandle,in=(ScrapSize:l,Scrap:l)
; Set scrap as current document and lock down its handle ( get its pointer ).
movelong Scrap,W_PHandle
rcall D_Deref,in=(Scrap:ax),out=(W_PPtr:ax)
; Get ruler associated with current paragraph.
SpaceLong
PushWord W_StartPar
PushWord #W_pBytes
_Multiply
pla
plx
clc
adc #W_pRulerHand
tay
movelong [ScrapPtr]:y,W_StartRuler
clc
rts
;...................................................................................................;
ENDP
*****************************************************************************************************
; W_SaveDoc ( FileRef:word, WindowPtr:long )
;
; This routine will handle saving a word processing document with the given file reference.
; The file has already been opened by the driver and the file mark moved to the start of the document
; data. Memory or file I/O errors are returned to the driver which will handle killing the file and
; alerting the user.
W_SaveDoc PROC EXPORT
;Using WpGlobals
;Using D_IOData
;Using W_ATTRData
;Using W_WPFileIOData
input FileRef:w,window:l,type:w
local CurView:w,Buffer:l
local BufPtr:l,TextPtr:l,Pars:w,Boff:l
local ParArray:l,Bsize:l,SaveDoc:l
error err
begin +b
; Clear error status, save current document, get globals for the document to be saved and collapse
; the rulers for the document before it goes to disk.
stz err
movelong W_CurDoc,SaveDoc
call W_GetDoc,in=(window:l)
jsl W_CollapseRulers
; Remember the current view of the document.
moveword W_View,CurView
; Check type we should save document as. If Ascii save then branch.
lda Type
jne doascii
; Write WP version number and window globals for the document. If disk error occurs then restore old
; document and return error to the driver.
call D_Write2,in=(FileRef:w,#W_FVersion:l,#2:l),out=(ax:l),err=err
jcs exit
call D_Write2,in=(FileRef:w,#W_StartWinGlobals:l,#W_SizeWinGlobals:l),out=(ax:l),err=err
jcs exit
; Switch in the body of the document and write out its contents. If error occurs then restore correct
; view of document and return error to the caller.
lda #W_NormalOn
jsr writethread
jcs restoreview
; Switch in the header of the document and write out its contents. If error occurs then restore
; correct view of document and return error to the caller.
lda #W_HeaderOn
jsr writethread
jcs restoreview
; Switch in the footer of the document. Whether or not we have encountered and error we will want to
; restore the view and the old document. The error will be returned to the caller.
lda #W_FooterOn
jsr writethread
brl restoreview
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Switch in the body of the document (no headers/footers in ASCII save).
doascii call W_SwitchData,in=(#W_NormalOn:w)
; Use 32k bitmap to buffer the output. Clear paragraph count. Since we are going to be using the 32k
; buffer set the dirty flag.
movelong >D_BitMapPtr,Buffer
moveword #1,>D_BitMapChanged
movelong #$7FFF,Bsize
stz Pars
; For all paragraphs do:
ploop jsl D_BeachBall
lda Pars
cmp W_LastP
jge restoreview
; Get pointer to paragraph text, set bufptr to start of 32k buffer and clear buffer offset.
inc a
ldx #7
jsl W_GetAddr
movelong ax,Textptr
movelong Buffer,Bufptr
stzl Boff
; Scan characters into buffer. Carriage will terminate the line. Handle font/style changes.
cloop shortm
lda [TextPtr]
cmp #CR
jeq doCR
bge putchar
cmp #TAB
beq putchar
cmp #1
beq fontchange
cmp #5
blt stylechange
bra putchar
; If font or style change then just bump the text pointer past the font/style information.
fontchange longm
addwl #3,TextPtr
bra cloop
stylechange longm
addwl #2,TextPtr
bra cloop
; Add character to the buffer and bump pointers. If buffer is full write it out. If error writing
; buffer then restore original document view and return error to the caller.
LONGA Off
putchar sta [BufPtr]
longm
incl TextPtr
incl Bufptr
incl Boff
cmpl Boff,Bsize
jlt cloop
jsr writebuffer
jcs restoreview
brl cloop
; Carriage return encountered. Add carriage return to the buffer if this is not the last paragraph.
LONGA Off
doCR sta [BufPtr]
longm
lda Pars
inc a
cmp W_LastP
bge nowritecr
incl Boff
; Write out the buffer and increment the paragraph count. Go back for more. If error writing buffer
; then restore original document view and return error to the caller.
nowritecr jsr writebuffer
jcs restoreview
inc Pars
brl ploop
; Unlock the paragraph array that we locked down and switch the original view back in before we
; exit and return the error to the caller.
restoreview call W_SwitchData,in=(CurView:w)
; Restore the old document and return to the caller.
exit call W_GetDoc,in=(SaveDoc:l)
return
;...................................................................................................;
writethread call W_SwitchData,in=(a:w)
movelong W_PHandle,ParArray
call X_WriteThread,in=(FileRef:w,W_LastP:w,[ParArray]:l,#0:w),err=err
rts
;...................................................................................................;
writebuffer call D_Write2,in=(FileRef:w,Buffer:l,Boff:l),out=(ax:l),err=err
bcs writeerr
movelong Buffer,Bufptr
stzl Boff
writeerr rts
;...................................................................................................;
ENDP
END