4 ; Loading and importing of files (MDW)
9 ;----- Standard header ------------------------------------------------------
14 ;----- External dependencies ------------------------------------------------
26 ;----- Main code ------------------------------------------------------------
28 AREA |Sapphire$$Code|,CODE,READONLY
32 ; On entry: R0 == pointer to entry point block
33 ; R1 == value of R10 to pass to entry points
34 ; R2 == value of R12 to pass to entry points
38 ; Use: Attempts to load a file after receipt of a Message_DataSave,
39 ; Message_DataLoad or Message_DataOpen. If user entries for
40 ; RAM transfer are provided, this is attempted, although the
41 ; entries must also be aware that file transfer may be
47 STMFD R13!,{R0-R6,R10,R12,R14} ;Save a load of registers
48 WSPACE load__wSpace ;Locate my workspace address
50 ; --- Save the handler information ---
52 ADR R14,load__entries ;Point to my entry info
53 STMIA R14,{R0-R2} ;And save the handler info
55 ; --- Read the current message ---
57 BL event_last ;Read the actual last event
58 CMP R0,#17 ;Is it a normal message?
59 CMPNE R0,#18 ;Or a bouncy one?
60 BNE %90load ;Neither -- ignore it then
62 LDR R0,[R1,#16] ;Load the message action
63 CMP R0,#1 ;Is it a Message_DataSave?
64 BEQ %20load ;Yes -- handle it then
65 CMP R0,#3 ;Is it a Message_DataLoad?
66 BEQ %50load ;Yes -- deal with that
67 CMP R0,#5 ;Is it a Message_DataOpen?
68 BEQ %60load ;Yes -- deal with that too
69 B %90load ;Otherwise ignore it
71 ; --- Deal with a Message_DataSave ---
73 ; First, set up all the data in my workspace.
75 20load MOV R6,R1 ;Keep the message pointer
76 ADR R0,load__message ;Point to my message buffer
77 LDR R2,[R6,#0] ;Get the message block size
78 BL fastMove ;Copy it over nicely
80 ; --- Find out if he can do RAM transfer ---
82 LDR R5,load__entries ;Find his handler block
83 LDR R14,[R5,#lEntry__initBuf] ;Point to his initBuf entry
84 CMP R14,#0 ;Is it defined?
85 BEQ %40load ;No -- just do scrap xfer
87 ; --- Set up for RAM transfer ---
89 ADR R0,load__name ;Point to the leafname
90 LDR R1,[R6,#36] ;Load the estimated size
91 MOV R2,#0 ;Pass a zero buffer handle
92 ADR R14,load__R10 ;Point to his R10/R12 values
93 LDMIA R14,{R10,R12} ;Load them out ready
94 ADDS R0,R0,#0 ;Clear lots of flags
95 MOV R14,PC ;Set up a return address
96 ADD PC,R5,#lEntry__initBuf ;Make him give me a buffer
97 WSPACE load__wSpace ;Get my workspace back again
98 STR R10,load__R10 ;Save his returned R10 value
99 BLVS load__finish ;If it failed, tidy it up
100 BVS %90load ;And return right now
101 ADR R14,load__buffStart ;Point to the buffer info
102 STMIA R14,{R0-R2} ;And save the buffer stuff
103 MOV R14,#0 ;We've not read any data yet
104 STR R14,load__totalSize ;So zero the total size
106 ; --- Build the Message_RAMFetch ---
108 MOV R14,#28 ;Size of a RAMFetch message
109 STR R14,[R11,#0] ;Store it in the scratchpad
110 ADD R14,R11,#12 ;Point to your_ref word
111 MOV R2,R0 ;Point to the buffer start
112 MOV R3,R1 ;And get the buffer size
113 LDR R0,[R6,#8] ;Load his reference number
114 MOV R1,#6 ;The RAMFetch message code
115 STMIA R14,{R0-R3} ;Save all that lot away
116 MOV R0,#18 ;Make it bounce if ignored
117 MOV R1,R11 ;Point to my message block
118 LDR R2,[R6,#4] ;Load his task handle
119 SWI Wimp_SendMessage ;And send along his message
121 ; --- Set everything up for the acknowledgement ---
123 MOV R14,#lState__test ;We're seeing if he'll cope
124 STR R14,load__state ;So save this state info
126 ADR R0,load__unknown ;Point to my unknown handler
127 MOV R1,#0 ;Nothing interesting in R4
128 MOV R2,#0 ;Nothing interesting in R10
129 MOV R3,R12 ;Pass workspace in R12
130 BL win_unknownHandler ;Register my unknown handler
131 B %90load ;And finish everything off
133 ; --- Set up scrap transfer ---
135 40load BL load__doScrap ;Start scrap transfer going
136 B %90load ;And finish everything off
138 ; --- Handle a Message_DataLoad ---
140 ; If this is *not* a reply to a Message_DataSaveAck then we
141 ; should clear all the associated data from out message
144 50load LDR R14,[R1,#12] ;Load message's your_ref
145 CMP R14,#0 ;Is this a new message?
146 BNE %70load ;No -- don't do setting up
148 ; --- Handle a new Message_DataLoad or Message_DataOpen ---
150 ; First, copy all the message data over
152 60load ADR R0,load__message ;Point to my message buffer
153 LDR R2,[R1,#0] ;Get the message block size
154 BL fastMove ;Copy it over nicely
156 ; --- Remember we're doing file transfer ---
158 MOV R14,#lState__file ;This is file transfer
159 STR R14,load__state ;Save this state value
161 ; --- Send an immediate acknowledgement ---
163 ; For a Message_DataOpen, this is very important -- if we
164 ; don't, and the application dies, we then get started all
165 ; over again from the command line, and probably die again
166 ; if it's a duff file. For a Message_DataLoad it doesn't
167 ; matter too much, although I suspect we should really send
168 ; the acknowledgement after we loaded the file.
170 70load MOV R6,R1 ;Keep the message pointer
171 ADD R0,R11,#20 ;Copy to the scratchpad
172 ADD R1,R6,#20 ;Point to the message data
173 LDR R2,[R6,#0] ;Get the message block size
174 SUB R2,R2,#20 ;Subtract the bit not copied
175 BL fastMove ;Copy it over nicely
177 LDR R14,[R6,#0] ;Load the message size word
178 STR R14,[R11,#0] ;Save it in my dummy message
179 LDR R0,[R6,#8] ;Load his my_ref field
180 MOV R1,#4 ;This is Message_DataLoadAck
181 ADD R14,R11,#12 ;Point to the your_ref field
182 STMIA R14,{R0,R1} ;Save them in there
184 MOV R0,#17 ;Don't want acknowledgement
185 MOV R1,R11 ;Point to the message block
186 LDR R2,[R6,#4] ;Get his task handle ready
187 SWI Wimp_SendMessage ;And acknowledge his message
189 ; --- Tell the client to load the file ---
191 ADR R0,load__name ;Point to apparent filename
192 ADD R1,R6,#44 ;Point to filename to load
193 LDR R2,load__state ;Load state (safeness flag)
194 ADR R14,load__entries ;Point to the entry data
195 LDMIA R14,{R5,R10,R12} ;Load the important stuff
196 ADDS R0,R0,#0 ;Clear C and V flags
197 MOV R14,PC ;Set up his return address
198 ADD PC,R5,#lEntry__file ;Tell him to load the file
199 WSPACE load__wSpace ;Find my workspace again
200 STR R10,load__R10 ;Save the new R10 value
201 BL load__finish ;Send a completed message
203 ; --- Now delete the Wimp$Scrap file if we need to ---
205 CMP R2,#0 ;Is the file `safe'?
206 BNE %90load ;Yes -- then do nothing
207 MOV R0,#27 ;Wipe files please
208 ADD R1,R6,#44 ;Point to the filename
209 MOV R3,#&3 ;No confirm, recurse
210 SWI XOS_FSControl ;Do the Wipe job
212 ; --- We finished at last! ---
214 90load LDMFD R13!,{R0-R6,R10,R12,PC}^ ;Return to caller
218 ; --- load__doScrap ---
224 ; Use: Sets everything up for Wimp$Scrap-type data transfer.
228 STMFD R13!,{R0-R4,R14} ;Save some registers
230 ; --- First, ensure the variable <Wimp$Scrap> exists ---
232 ADR R0,load__wimpScrap ;Point to my variable name
233 MOV R1,R11 ;Point to a convenient buffer
234 MOV R2,#256 ;Get the buffer size
235 MOV R3,#0 ;This is the first call
236 MOV R4,#0 ;Don't expand or anything
237 SWI XOS_ReadVarVal ;Read the variable value
238 BLVS load__finish ;If it failed, abort now
239 BVS %90load__doScrap ;And return to caller
241 ; --- Build the message and send it ---
243 ADD R0,R11,#20 ;Point at scratch msg data
244 ADR R1,load__message+20 ;And the saved bits of data
245 MOV R2,#24 ;All up to the filename
246 BL fastMove ;Copy all that lot over
248 MOV R14,#60 ;The size of this message
249 STR R14,[R11,#0] ;Store it in the right place
250 LDR R0,load__message+8 ;Load the message's my_ref
251 MOV R1,#2 ;This is Message_DataSaveAck
252 ADD R14,R11,#12 ;Point to your_ref
253 STMIA R14,{R0,R1} ;Save your_ref and action
255 ADD R0,R11,#44 ;Point to the filename area
256 ADR R1,load__scrapVar ;Point to the variable name
257 BL str_cpy ;Copy the string over
259 MOV R14,#-1 ;Say that the data's not safe
260 STR R14,[R11,#36] ;Save -1 as estimated size
261 MOV R0,#17 ;This should be send normal
262 MOV R1,R11 ;Point at my message
263 LDR R2,load__message+4 ;Load his task handle
264 SWI Wimp_SendMessage ;Send the message back
266 ; --- Now remember we're doing scrap transfer ---
268 MOV R14,#lState__scrap ;Get the right state number
269 STR R14,load__state ;And save it away nicely
271 ; --- That's it -- we're done ---
273 90load__doScrap LDMFD R13!,{R0-R4,PC}^ ;Return to caller
275 load__wimpScrap DCB "Wimp$Scrap",0
276 load__scrapVar DCB "<Wimp$Scrap>",0
280 ; --- load__unknown ---
282 ; On entry: R0 == an event code
283 ; R1 == pointer to event data
285 ; On exit: CS if we handled the event, CC otherwise
287 ; Use: Handles unknown events (i.e. user messages) during a RAM
292 CMP R0,#17 ;Is it a user message?
293 CMPNE R0,#18 ;Or a bouncy user message?
294 BEQ %00load__unknown ;Yes -- handle it then
295 CMP R0,#19 ;Is it a bounced message?
296 BEQ %60load__unknown ;Yes -- deal with that
297 MOVS PC,R14 ;Nothing we could do about it
299 ; --- Deal with a message ---
301 00load__unknown STMFD R13!,{R14} ;Save a register
302 LDR R14,[R1,#16] ;Load the message code
303 CMP R14,#7 ;Is it a Message_RAMTransmit?
304 LDMNEFD R13!,{PC}^ ;No -- ignore it then
306 ; --- Data transfer is go ---
308 STMFD R13!,{R0-R6,R10} ;Save loads of registers
309 MOV R6,R1 ;Look after the message ptr
310 MOV R14,#lState__ram ;We're doing RAM transfer now
311 STR R14,load__state ;So save this state away
313 ; --- Have we finished data transfer yet? ---
315 ADR R14,load__buffStart ;Point to the buffer info
316 LDMIA R14,{R0-R2} ;Load all the buffer stuff
317 LDR R3,[R6,#24] ;How much has he sent?
318 LDR R4,load__totalSize ;Load the total so far
319 ADD R4,R4,R3 ;Add on this new size
320 STR R4,load__totalSize ;And save back the new total
321 CMP R1,R3 ;Has he sent enough data?
322 BNE %30load__unknown ;No -- then it's all over
324 ; --- Get some more buffer space ---
326 ADR R14,load__entries ;Point at his entry info
327 LDMIA R14,{R5,R10,R12} ;Load all his info out
328 ADDS R0,R0,#0 ;Clear C and V flags
329 MOV R14,PC ;Set up the return address
330 ADD PC,R5,#lEntry__extend ;Extend your buffer please
331 WSPACE load__wSpace ;Find my workspace again
332 BVS %40load__unknown ;If it failed, kill buffer
333 ADR R14,load__buffStart ;Point to the buffer info
334 STMIA R14,{R0-R2} ;Save the buffer info again
336 ; --- Send another RAMFetch along ---
338 MOV R14,#28 ;Size of a RAMFetch message
339 STR R14,[R11,#0] ;Store it in the scratchpad
340 ADD R14,R11,#12 ;Point to your_ref word
341 MOV R2,R0 ;Point to the buffer start
342 MOV R3,R1 ;And get the buffer size
343 LDR R0,[R6,#8] ;Load his reference number
344 MOV R1,#6 ;The RAMFetch message code
345 STMIA R14,{R0-R3} ;Save all that lot away
346 MOV R0,#18 ;Make it bounce if ignored
347 MOV R1,R11 ;Point to my message block
348 LDR R2,[R6,#4] ;Load his task handle
349 SWI Wimp_SendMessage ;And send along his message
350 B %50load__unknown ;Finish off everything
352 ; --- Tell the client to wrap things up ---
354 30load__unknown ADR R0,load__name ;Point to the `filename'
355 MOV R1,R4 ;Get the total data size
356 ADR R14,load__entries ;Point at his entry info
357 LDMIA R14,{R5,R10,R12} ;Load all his info out
358 ADDS R0,R0,#0 ;Clear C and V flags
359 MOV R14,PC ;Set up the return address
360 ADD PC,R5,#lEntry__doneBuf ;Tidy up your buffer please
361 WSPACE load__wSpace ;Find my workspace again
362 BVS %40load__unknown ;If it failed, tidy up
363 BL load__finish ;It's all over now
365 ; --- Unattach this unknown handler ---
367 ADR R0,load__unknown ;Point to my unknown handler
368 MOV R1,#0 ;Nothing interesting in R4
369 MOV R2,#0 ;Nothing interesting in R10
370 MOV R3,R12 ;Pass workspace in R12
371 BL win_removeUnknownHandler ;Unattach the handler
372 B %50load__unknown ;And return nicely
374 ; --- Tidy up after buffer extension failed ---
376 40load__unknown MOV R4,R0 ;Look after the error pointer
377 ADR R14,load__buffStart ;Point to the buffer info
378 LDMIA R14,{R0-R2} ;Load it all out
379 LDR R12,load__R12 ;Find the client's R12
380 MOV R14,PC ;Set up a return address
381 ADD PC,R5,#lEntry__killBuf ;Destroy the buffer
382 WSPACE load__wSpace ;Find my workspace again
383 MOV R14,#V_flag ;Get the V bit position
384 TEQVCP R14,PC ;If clear, set it again
385 MOV R0,R4 ;Point at the error again
386 BL load__finish ;Report the error
388 ; --- We don't need the unknown handler any more ---
390 ADR R0,load__unknown ;Point to my unknown handler
391 MOV R1,#0 ;Nothing interesting in R4
392 MOV R2,#0 ;Nothing interesting in R10
393 MOV R3,R12 ;Pass workspace in R12
394 BL win_removeUnknownHandler ;Unattach the handler
396 ; --- Return to caller ---
398 50load__unknown LDMFD R13!,{R0-R6,R10,R14} ;Unstack all the registers
399 ORRS PC,R14,#C_flag ;And claim the event
401 ; --- Handle a bounced message ---
403 60load__unknown STMFD R13!,{R14} ;Save a register
404 LDR R14,[R1,#16] ;Load the message action
405 CMP R14,#6 ;Is it one of my RAMFetches?
406 LDMNEFD R13!,{PC}^ ;No -- ignore it then
408 ; --- My RAMFetch bounced! ---
410 LDR R14,load__state ;Get my current state?
411 CMP R14,#lState__test ;Was I just testing the water
412 BLEQ load__doScrap ;Yes -- set up for scrap xfer
414 ; --- Shut down the data transfer ---
416 STMFD R13!,{R0-R3,R10} ;Save some more registers
417 ADR R14,load__buffStart ;Point to the buffer info
418 LDMIA R14,{R0-R2} ;Load it all out
419 ADR R14,load__entries ;Point to entry information
420 LDMIA R14,{R3,R10,R12} ;Load all the stuff out
421 MOV R14,PC ;Set up a return address
422 ADD PC,R3,#lEntry__killBuf ;Destroy the buffer
423 WSPACE load__wSpace ;Find my workspace again
424 MOV R14,#V_flag ;Get the V bit position
425 TEQVCP R14,PC ;If clear, set it again
426 MOV R0,#0 ;Don't report any errors
427 BL load__finish ;Report the error
429 ; --- We don't need the unknown handler any more ---
431 ADR R0,load__unknown ;Point to my unknown handler
432 MOV R1,#0 ;Nothing interesting in R4
433 MOV R2,#0 ;Nothing interesting in R10
434 MOV R3,R12 ;Pass workspace in R12
435 BL win_removeUnknownHandler ;Unattach the handler
437 LDMFD R13!,{R0-R3,R10,R14} ;Unstack all the registers
438 ORRS PC,R14,#C_flag ;And return with C set
442 ; --- load__finish ---
444 ; On entry: VS and R0 points to error, or VC
446 ; On exit: R10 corrupted
448 ; Use: Calls the appropriate client routine for finishing off
453 STMFD R13!,{R0-R2,R12,R14} ;Save some registers
454 MOVVS R1,#1 ;If error, set button count
455 ADRVC R0,load__name ;Point to apparent name
456 LDRVC R1,load__state ;And load my state
457 AND R1,R1,#1 ;Leave only safeness flag
458 ADR R14,load__entries ;Point to the entry points
459 LDMIA R14,{R2,R10,R12} ;Load the entry info
460 ADDVS R2,R2,#4 ;If error, call fail entry
461 MOV R14,PC ;Set up the return address
462 ADD PC,R2,#lEntry__done ;Call the correct entry pt
463 LDMFD R13!,{R0-R2,R12,PC}^ ;Return to caller
467 ; --- load_initBuf ---
469 ; On entry: R1 == estimated file size
470 ; R2 == pointer to flex anchor (unallocated)
472 ; On exit: R0 == pointer to buffer start
474 ; May return an error
476 ; Use: Initialises a flex block for use as a RAM transfer buffer.
477 ; This routine is suitable for use as the initBuf routine for
478 ; RAM transfer loading.
483 STMFD R13!,{R14} ;Save some registers
484 MOV R0,R2 ;Point to caller's anchor
485 BL flex_alloc ;Try to allocate the buffer
486 MOVCS R1,#4096 ;Otherwise assume 4K size
487 BLCS flex_alloc ;And try again...
488 BLCS alloc_error ;If it failed, get an error
489 LDRCC R0,[R0,#0] ;Otherwise load buffer start
490 LDMFD R13!,{R14} ;Restore the link register
491 BICCCS PC,R14,#V_flag ;If no error, clear V on exit
492 ORRCSS PC,R14,#V_flag ;Otherwise set it
496 ; --- load_killBuf ---
498 ; On entry: R2 == pointer to flex anchor
502 ; Use: Frees a flex block. This routine should be used to free
503 ; the buffer used for RAM transfer.
508 STMFD R13!,{R0,R14} ;Save some registers
509 MOV R0,R2 ;Point to the flex anchor
510 BL flex_free ;Free the block
511 MOV R14,#0 ;Get a zero word
512 STR R14,[R2,#0] ;Write this over the anchor
513 LDMFD R13!,{R0,PC}^ ;Return to caller
517 ; --- load_extendBuf ---
519 ; On entry: R0 == pointer to previous buffer
520 ; R1 == size of previous buffer
521 ; R2 == pointer to flex anchor
523 ; On exit: R0 == pointer to a new buffer
524 ; R1 == size of the new buffer
525 ; May return an error
527 ; Use: Extends the flex block if it was initially too small.
528 ; This routine is designed to be used as the extend routine
529 ; during RAM transfer.
531 EXPORT load_extendBuf
534 STMFD R13!,{R3,R14} ;Save some registers
535 MOV R0,R2 ;Point to the flex anchor
536 BL flex_size ;Read the block's size
537 MOV R3,R0 ;Look after the size
538 MOV R0,R2 ;Point to the flex anchor
539 ADD R1,R3,#&1000 ;Extend buffer by 4K
540 BL flex_extend ;Make more space for loading
541 BLCS alloc_error ;If it failed, get an error
542 LDRCC R0,[R2,#0] ;Otherwise load the anchor
543 ADDCC R0,R0,R3 ;And add the old size
544 MOVCC R1,#&1000 ;Get the buffer size
545 LDMFD R13!,{R3,R14} ;Restore the registers
546 BICCCS PC,R14,#V_flag ;If no error, clear V on exit
547 ORRCSS PC,R14,#V_flag ;Otherwise set it
551 ; --- load_doneBuf ---
553 ; On entry: R1 == actual size of data
554 ; R2 == pointer to flex anchor
558 ; Use: Sets the block into which the data has been loaded to the
559 ; correct exact size.
564 STMFD R13!,{R0,R14} ;Save some registers
565 MOV R0,R2 ;Point to the anchor
566 BL flex_extend ;Set the block's correct size
567 LDMFD R13!,{R0,PC}^ ;Return to caller
573 ; On entry: R1 == pointer to filename to load
574 ; R2 == pointer to flex anchor
576 ; On exit: R0 == size of file loaded
577 ; May return an error
579 ; Use: Loads a named file into a flex block for your delectation.
584 STMFD R13!,{R0-R6,R14} ;Save some registers
585 MOV R6,R2 ;Keep the flex anchor safe
587 ; --- Find the file information ---
589 MOV R0,#17 ;Read file information
590 SWI XOS_File ;Find the file's size
591 BVS %90load_file ;If it failed, handle error
592 TST R0,#1 ;Is the object a file?
593 BEQ %80load_file ;No -- get an error for it
594 STR R4,[R13,#0] ;Save the file size in R0
596 ; --- Allocate the flex block ---
598 MOV R1,R4 ;Get the object size in R1
599 MOV R0,R6 ;Point to caller's anchor
600 BL flex_alloc ;Try to allocate the block
601 BLCS alloc_error ;No memory -- get the message
602 BCS %90load_file ;If it failed, handle error
604 ; --- Load file into the flex block ---
606 MOV R0,#16 ;Load the file
607 LDR R1,[R13,#4] ;Load the filename address
608 LDR R2,[R6,#0] ;Load the flex anchor
609 MOV R3,#0 ;Load into my buffer please
610 SWI XOS_File ;Try to do the load op
611 BVS %85load_file ;If it failed, tidy up
612 LDMFD R13!,{R0-R6,R14} ;Unstack registers
613 BICS PC,R14,#V_flag ;And return with no error
615 ; --- We found a bad object type ---
617 80load_file MOV R2,R0 ;Get object type in R2
618 MOV R0,#19 ;Get the error message
619 SWI XOS_File ;Return pointer in R0
620 B %90load_file ;Handle error in usual way
622 ; --- Tidy up after various errors ---
624 85load_file MOV R1,R0 ;Look after the error pointer
625 MOV R0,R6 ;Point to the flex anchor
626 BL flex_free ;Free up all tht memory
627 MOV R14,#0 ;Get a zero word
628 STR R14,[R6,#0] ;And zero out the anchor
629 MOV R0,R1 ;Restore the error pointer
631 90load_file ADD R13,R13,#4 ;Don't restore R0 on exit
632 LDMFD R13!,{R1-R6,R14} ;Unstack registers
633 ORRS PC,R14,#V_flag ;And return with the error
639 ;----- User entry points ----------------------------------------------------
643 lEntry__initBuf # 4 ;Create a load buffer
645 ; R0 == ptr to `filename'
646 ; R1 == estimated file size
649 ; R0 == ptr to buffer start
650 ; R1 == ptr to buffer end
651 ; R2 == buffer `handle'
654 lEntry__killBuf # 4 ;Destroy the load buffer
656 ; R0 == ptr to buffer start
657 ; R1 == ptr to buffer end
658 ; R2 == buffer `handle'
662 lEntry__extend # 4 ;Extend the load buffer
664 ; R0 == ptr to buffer start
665 ; R1 == ptr to buffer end
666 ; R2 == buffer `handle'
670 lEntry__doneBuf # 4 ;All data is now loaded
672 ; R0 == ptr to `filename'
673 ; R1 == total size of data
674 ; R2 == buffer `handle'
678 lEntry__file # 4 ;Load data from a file
680 ; R0 == ptr to `filename'
682 ; R2 == 0 if file unsafe
686 lEntry__done # 4 ;Completed loading
688 ; R0 == ptr to `filename'
689 ; R1 == safeness indicator
693 lEntry__failed # 4 ;Failed to load file
695 ; R0 == pointer to error
700 ; --- Explanation ---
702 ; Loading is several orders of magnitude harder than saving, at a guess.
703 ; I've tried to make it fairly straightforward here -- there are a few
704 ; standard routines provided for simple things like loading into a flex
705 ; block, and a coroutine-based system for unified RAM/file transfer is
708 ; Like saving, loading is based around a table of branch instructions which
709 ; perform application-specific actions during the load operation. All the
710 ; message passing protocol is hidden away, and all you have to do is write
711 ; the entries for the table.
713 ; If you want to support RAM-transfer, you must provide three buffer
716 ; * initBuf is called when load is attempting to start a RAM transfer with
717 ; the saving application. It should create a buffer of appropriate size
718 ; (possibly based on the estimated file size already given). You can
719 ; declare a buffer handle at this point, which is passed to all other
720 ; routines that need to deal with the buffer. It may return an error.
722 ; If you can't handle RAM transfer, you should replace the branch
723 ; instruction here with a null word.
725 ; * extend is called if the previous buffer was filled and there is more
726 ; data to come. The address of the previous buffer is returned to you,
727 ; so either you can process it there and then, or extend the buffer in
728 ; some way. You just have to return a new area of memory to fill with
729 ; data. It may return an error.
731 ; * doneBuf is called when all the data has been loaded, so that the buffer
732 ; can be set to the exact right size.
734 ; * killBuf is called if the attempt to load via RAM transfer failed and
735 ; the buffer has to be destroyed. It is always called whenever there is
736 ; a fault during RAM transfer, even if one of your other entry points
739 ; * file is called if you have to load a file from the filing system, either
740 ; because RAM transfer failed or because you received a direct load from
741 ; the Filer. It may return an error.
743 ; * done is called when the data transfer is successfully completed.
745 ; * failed is called when the data transfer fails due to an error.
747 ;----- Workspace ------------------------------------------------------------
752 load__state # 4 ;The current state (1 byte)
754 load__entries # 4 ;Pointer to entry pt block
755 load__R10 # 4 ;Client's R10 value
756 load__R12 # 4 ;Client's R12 value
758 load__buffStart # 4 ;The buffer's start address
759 load__buffSize # 4 ;And its size
760 load__buffHnd # 4 ;Client's buffer handle
762 load__totalSize # 4 ;How much data we've received
764 load__message # 44 ;The original load/save msg
765 load__name # 212 ;The file's apparent name
767 load__wSize EQU {VAR}-load__wStart
771 ; These have been carefully arranged so that we can return
772 ; the safeness flag to various routines. If we only
773 ; consider files, then the state /is/ the safeness flag.
774 ; Otherwise we only use the bottom bit of the state.
776 lState__scrap EQU 0 ;We're doing scrap transfer
777 lState__file EQU 1 ;We're loading from a file
778 lState__test EQU 2 ;We're testing RAM transfer
779 lState__ram EQU 4 ;We're doing RAM transfer
781 AREA |Sapphire$$LibData|,CODE,READONLY
788 ;----- That's all, folks ----------------------------------------------------