indigodarkwolf / box16

A fork of the official X16 emulator, converted to C++20 and with a bunch of features tweaked and added.
MIT License
42 stars 19 forks source link

Kernal calls MACPTR indefinitely when LOAD'ing file absnet from HostFS using SA 2 or 3 #111

Closed cnelson20 closed 4 months ago

cnelson20 commented 4 months ago

When LOAD'ing a file on HostFS using secondary address 2 (header-less load), the kernal never returns control to the user (unless they Ctrl-C) if the file loaded doesn't exist on disk.

From debugging the hypercall for MACPTR(), when MACPTR successfully loads a file from HostFS (on any SA), MACPTR() is only called the appropriate number of times.

MACPTR($0801, $00, 0)
returning: 64

MACPTR($0801, $00, 0)
returning: 64

MACPTR($0801, $00, 0)
returning: 64

image

But when you attempt to LOAD a file that doesn't exist using SA 2, the hypercall is called repeatedly with the same arguments, while always returning -3.

MACPTR($0801, $00, 0)
returning: -3

image (note: it takes several seconds for the kernal to print the 'SEARCHING FOR ... LOADING FROM $0801' part)

some debugging

Looking at the function in ieee.cpp,

if (channels[channel].f) {
    //... code here ...
} else {
    ret = -3; // unsupported
}

Means that this check is failing (I added a print statement to double check that it is)

In hypercalls.cpp, we can take a look at how MACPTR() is called:

const int s = MACPTR(state6502.y << 8 | state6502.x, &count, state6502.status & 0x01);
state6502.x = count & 0xff;
state6502.y = count >> 8;

state6502.status &= 0xfe; // clear C -> supported

the return value of MACPTR() is totally ignored, which is problematic if MACPTR() returns -3.

Changing the last line to:

if (s == -3) {
    state6502.status |= 0x01; // set C -> unsupported
} else {
    state6502.status &= 0xfe; // clear C -> supported
}

actually solves the issue. (a PR is coming asap)