MockbaTheBorg / RunCPM

RunCPM is a multi-platform, portable, Z80 CP/M 2.2 emulator.
MIT License
411 stars 75 forks source link

Nulu, in some circumstances, can fail with Error 2 Disk Full message #110

Closed riwide closed 4 years ago

riwide commented 4 years ago

Tested with NULU 1.52 Use of NULU to extract LBR files can fail when LBR file is not on the default drive (but works fine in same scenarios on real Z80/Z180 systems (e.g. sc131)) e.g. M:> I:NULU -o -a:qt43all.lbr -e . -x fails but M:>I:NULU -o -qt43all.lbr -e . -x works if lbr file on m: see below: M>dir no file M>i:nulu -o a:qt43all.lbr -e . NULU 1.52 (07/12/87) Copyright (C) 1984, 1985 & 1987 by Martin Murray Bug fixes in version 1.52 by Mick Waters

TYPE -H FOR HELP

Drive M: Total 8160k, Used 84k, Free 8076k

Library A0:QT43ALL.LBR open. (Buffer size: 281 sectors) Active entries: 50, Deleted: 0, Free: 18, Total: 68. Extracting... ARX .DOC to M0:ARX .DOC ARX .O to M0:ARX .O BAUD .ZY to M0:BAUD .ZY BDOS .I to M0:BDOS .I CATCH .ZY to M0:CATCH .ZY CF .ZY to M0:CF .ZY CHAT .ZY to M0:CHAT .ZY DIR .ZY to M0:DIR .ZY FILE .ZY to M0:FILE .ZY FLAGS .ZY to M0:FLAGS .ZY KERMIT .IY to M0:KERMIT .IY KUTIL .ZY to M0:KUTIL .ZY LIB .DOC to M0:LIB .DOC ERROR 2: disk full

LIB .L to M0:LIB .L MAKEQT .SUB to M0:MAKEQT .SUB ODDS .ZY to M0:ODDS .ZY OFMT .DOC to M0:OFMT .DOC PARX .O to M0:PARX .O QARX .O to M0:QARX .O QTERM .ZY to M0:QTERM .ZY RARX .O to M0:RARX .O READ-ME . to M0:READ-ME . RECV .ZY to M0:RECV .ZY RECVK .ZY to M0:RECVK .ZY RECVX .ZY to M0:RECVX .ZY SEND .ZY to M0:SEND .ZY SENDK .ZY to M0:SENDK .ZY SENDX .ZY to M0:SENDX .ZY SHRINK .ZY to M0:SHRINK .ZY SRSCRN .ZY to M0:SRSCRN .ZY SRUTIL .ZY to M0:SRUTIL .ZY STDHDR .I to M0:STDHDR .I TERMCAP .IY to M0:TERMCAP .IY TERMIO .ZY to M0:TERMIO .ZY TEST .Z to M0:TEST .Z VARS .IY to M0:VARS .IY VERSION .IY to M0:VERSION .IY VT100 .ZY to M0:VT100 .ZY XLIB .DOC to M0:XLIB .DOC XLIB .L to M0:XLIB .L XMODEM .IY to M0:XMODEM .IY XUTIL .ZY to M0:XUTIL .ZY ZC .COM to M0:ZC .COM ZLIB .COM to M0:ZLIB .COM ZLINK .COM to M0:ZLINK .COM ZPATCH .COM to M0:ZPATCH .COM ZSM .COM to M0:ZSM .COM ZSM .DOC to M0:ZSM .DOC ZSM23 .PKG to M0:ZSM23 .PKG ERROR 2: disk full

-Extract members M0:>-x

Closing A0:QT43ALL.LBR... qt43all.zip

mecparts commented 4 years ago

I've created a pull request to fix this.

RunCPM's emulated BDOS didn't handle the "file unmodified" bit (B7) in the FCB's S2 byte.

NULU set it at some point, causing the next write to see an out of range S2 value and caused a disk full message.

I'd already added the "file unmodified" handling to my ZSDOS'ified emulated BDOS to update the "last written" timestamp when a modified file was closed. So it was just a matter of hauling all those changes back into the mainline code.

MockbaTheBorg commented 4 years ago

@riwide I have merged @mecparts change to the S2. Please give it a try and see if this resolved the issue for you.

Thanks a lot you both.

riwide commented 4 years ago

S2 fix has cleared the problem. Thanks

MockbaTheBorg commented 4 years ago

The S2 change seems to have broken Wordstar 3. The culprit seems to be the line 287: F->s2 = 0x80; // set unmodified flag If I set it back to 0x00 then WS3 works. Otherwise, when attempting to edit a file, it will bail out with a message: "System failure, or you changed diskettes'. I am still trying to understand why it is causing the issue.

mecparts commented 4 years ago

I think I messed that up.

That ought to be F->s2 |= 0x80; // set unmodified flag otherwise it destroys the S2 value for any files greater than 512K (any smaller and S2 was already 0).

I took a look in the original BDOS source (i.e. What Would DRI Do?) and that's what the open function did there; set the high bit of S2.

I'm going to dig up/mash together a 512K+ file and see if WS4 complains with the existing (bad) code.

mecparts commented 4 years ago

Hmm! I tried editing files both < 512K and > 512K in WS3.0, 3.3 and 4.0. I couldn't get any of them to complain.

Edit: ah, hold on. Tried changing disks and got your error message. Now I can test.

mecparts commented 4 years ago

Got it. (slaps head)

When closing an unmodified file (bit 7 in S2 set), it wasn't setting the result to 0 (error), just leaving it at 0xff (error). So that's why setting S2 to 0 in _OpenFile made the problem go away; _CloseFile already set the result to 0 in that case.

I changed my mind about ORing in the "unmodified flag" in _OpenFile. In the real BDOS, S2 (and everything else in the FCB) is copied in from the directory entry. So it has a sensible value. In RunCPM's emulated BDOS, we have to mock pretty much everything up. The RC field is right, but pretty much everything else is just zero.

If I OR'd S2 with 0x80, we'd end up with whatever value the program had in S2. Likely it'd be zero, but why take the chance? Returning 0x80 still makes good sense.

And there's a pull request with the 2 line change to _CloseFile. I actually had those 2 lines in my ZSDOS'ified code, which is why I never saw the problem.

Sorry about that!

MockbaTheBorg commented 4 years ago

No worries ... actually thank a lot for looking at it. I have been so buried in work that I am not having a chance to look at any of my projects in detail.

Thanks!