6

I would like to use the Kernal's LOAD routine to load a file into memory, because that seems to be the easiest way to do it. However, that LOAD call is synchronous in the sense that it returns once the full file has been loaded.

I would like the user some kind of indication that the loading is happening. If I wasn't using LOAD, I could just INC $D020 every now and then (after a successful CHRIN, for example). What is a good way to do that without giving up the convenience of using LOAD? For example, is there a good interrupt source that can be used for this?

5

One could configure the second CIA to trigger an NMI sometime during vertical blank, at a rate precisely equal to the frame rate. If the NMI were something like:

    bit $dd0d ; Reset NMI
    inc $d020
    rti

then the time required to dispatch, service, and return from the NMI would be IIRC 7+5+4+6+6 = 28 cycles. Since the kernel load routine is prepared to have the VIC-II chip steal chunks of 43 cycles for display refresh, having an NMI steal 28 cycles would pose no problem provided that the NMI doesn't steal such cycles near the time the VIC-II does so. If code disables the NMI timer, configures it for the frame rate (bearing in mind that different eras of C64/C128 will use different frame rates!), and enables it near the start of vertical blank, the NMI will be able to update the display cleanly.

Note that this won't do anything to show that the load is actually making any progress, and one couldn't include much in the way of a progress indicator without increasing the length of the NMI to the point that it might cause trouble. Perhaps code could safely enable sprite 0 near the bottom of the screen (so its data fetches would occur after the last badline), push the timing of the NMI to occur after the last sprite 0 data fetch, and then do something like:

    bit $dd0d ; Reset NMI
    pha
    lda $__ ; MSB of address used by kernel load routine
    sta $d000
    pla
    rti

I think that would increase the NMI time to 36 cycles, which would still be within acceptable tolerance, while causing a sprite to move across the screen in such a way that its X position would increase by one pixel for every 256 bytes that get loaded.

On the other hand, instead of trying to provide a progress update to show how much longer the slow kernel routines are going to take to load the file, perhaps it might be more useful to use one of the plentiful fast-load routines.

4

I have found on this page a loader that does exactly this. So how does it work? By overriding the ISTOP interrupt handler, which seems to be called by the kernal even during LOAD.

One thing I haven't quite been able to figure out is why their flashload routine ends with a jump to $f6fe in the middle of the error handler; I ended up jumping to $f6ed, the original STOP handler, instead, to play it safe.

Here are the relevant parts of the linked code:

                sei
                lda #$37  ;Turn kernal on 
                sta $01

                ;Accumulate IRQ for flashing border routine
                lda #<flashload
                ldx #>flashload
                sta $0328
                stx $0329
                cli

                ; proceed to load file via LOAD as you'd otherwise do

flashload       inc $d020
                dec $d020
                jmp $f6fe

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.