mattgodbolt / jsbeeb

Javascript BBC micro emulator
GNU General Public License v3.0
351 stars 68 forks source link

DFS reports error 18 (sector not found) when creating new files on certain disk images #428

Closed komadori closed 1 month ago

komadori commented 1 month ago

If you load a disk image into hosted JsBeeb, either via a URL or by uploading from a local file, normally it is possible to write new files onto the disk which exist transiently for the length of the session.

However, if the size of the disk image is a multiple of 10 256-byte sectors (i.e it contains a whole number of tracks) then creating a new non-empty file fails with DFS error 18 (sector not found). This can be tested as follows:

https://bbc.xania.org/?&disc1=https://raw.codeberg.page/komadori/JMC-disks/jmc-0.0.1.ssd (this image is 5120 bytes, 20 sectors)

>*BUILD TEST
0001 TEST
0002
Disk fault 18 as 02/00

This occurs with both DFS 0.9 and 1.2.

mattgodbolt commented 1 month ago

Doops; this will be part of my changes to more accurately model discs....but not accounting for that properly in the disc loaders. Thanks for the report! I'll look into fixing.

mattgodbolt commented 1 month ago

@komadori I've been unable to reproduce this: did you change your SSD image?

mattgodbolt commented 1 month ago

I was also unable to repro with an empty disc:

$ dd if=/dev/zero of=discs/blank.ssd bs=256 count=10
10+0 records in
10+0 records out
2560 bytes (2.6 kB, 2.5 KiB) copied, 6.2411e-05 s, 41.0 MB/s

image

Has the problem been fixed? I have made some changes to the disc system but not since you posted this issue.

komadori commented 1 month ago

@mattgodbolt Yes, I can still reproduce using the version from bbc.xania.org. I believe this is auto-deployed with the most recent trunk commit so I haven't tried building JsBeeb myself. No, the linked SSD hasn't changed.

After looking at your screenshot, I think the problem is that I didn't clarify exactly what keys I pressed. After typing "TEST" at the 0001 prompt (it's necessary for the file to be non-empty) I pressed Return to advance to the next line, and then at the 0002 prompt I pressed Escape to terminate the *BUILD command. This causes DFS to try and flush its buffer to disk and that is the part of the process which triggers the error.

Also, to be more specific, I think the error is caused whenever DFS accesses a track which is outside the bounds of the disk image. In the case of my example image, it is contains exactly one track which is completely full with files, so trying to create a new non-empty file causes the DFS to access the next track and hence fails. In the case of your blank.ssd file, it is empty so BUILD doesn't fail straight away. The first 2 sectors are used by the disk catalogue and each non-empty file uses at least one sector. Hence, if I run the BUILD command repeatedly with different file names on that image, it doesn't fail until I get to the 9th file. This is expected because it takes the first 8 files to fill the track.

For the most stark test case, if I load a zero byte SSD into JsBeeb then any command which tries to access the disk catalogue (e.g. *CAT) will fail with "Disk fault 18 at 00/00".

mattgodbolt commented 1 month ago

Ahhhh! got it. thanks @komadori I can repro now . and fix :)

The new code "simulates" a formatted disc (with all that entails) but...due to dumbness on my part if the input file is short I don't "format" empty tracks to the end of the disc surface! Should be a quick fix

mattgodbolt commented 1 month ago

Confirmed fix is deployed! Thanks for your patience.