Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review LOADB+SAVEB error handling #363

Closed
jkotlinski opened this issue Aug 30, 2021 · 18 comments
Closed

Review LOADB+SAVEB error handling #363

jkotlinski opened this issue Aug 30, 2021 · 18 comments

Comments

@jkotlinski
Copy link
Owner

jkotlinski commented Aug 30, 2021

Do LOADB+SAVEB have appropriate error handling? If not, fix it.

see discussion in #357

@Whammo
Copy link
Collaborator

Whammo commented Aug 30, 2021

LOADB has two modes of failure.

  1. If the high byte of the destination address is zero, it still executes LOAD but sets load_binary_status to fail, executes _errorchread but zeropage could have been trashed- or loaded to.
  2. bcs .disk_io_error after LOAD also sets load_binary_status to fail,

@Whammo
Copy link
Collaborator

Whammo commented Aug 30, 2021

I'm pretty sure this works like it should.
open.fs

marker foo
: setlfs ( file# sa -- )
$b9 c! $b8 c! ;

: setnam ( nameaddr namelen -- )
$b7 c! $bb ! ;

\ Open a logical file
\ ioresult is 0 on success, kernal
\ error # on failure.
( nameaddr namelen file# sa --
  ioresult )
: open
 setlfs setnam [ w stx,
$ffc0 jsr, \ OPEN
+branch bcs, \ carry set = error
0 lda,# \ A is only valid on error
:+
w ldx,
lsb sta,x
0 lda,# msb sta,x
] ;

\ Close a logical file
code close ( file# -- )
txa, pha,
lsb lda,x \ x = file#
$ffc3 jsr, \ CLOSE
pla, tax, inx,
;code

: errchk  sr c@ 1 and if
ar c@ else
0  then ioabort ;

: load  ( sa dst -- ioresult )
xr ! ar c! $ffd5 sys errchk ;

: save ( start end zeropage -- ioresult
)
dup ar c! swap xr ! !
$ffd8 sys errchk ;

( filenameptr filenamelen dst -- endadd
)
: loadb
1 0 setlfs -rot setnam 0
swap load drop $ae @ ;

: saveb ( start end nameaddr namelen --
)
1 1 setlfs setnam $c1 save drop ;

@jkotlinski
Copy link
Owner Author

jkotlinski commented Aug 30, 2021

Some thoughts about existing code:

  • I think it would be good if LOADB and SAVEB return an ioresult that can be checked by calling code. If one is too lazy to do proper error handling, at least it's easy to call ioabort
  • It might be more straightforward if LOADB returned the number of read bytes.
  • It's not so nice that LOADB and SAVEB assume that logical file# 1 is free to use. But it's maybe livable.
  • It's not good that LOADB and SAVEB check the error channel in case of failure. If there is no device, it will hang.

EDIT: changed my mind on most of these points.

@jkotlinski
Copy link
Owner Author

jkotlinski commented Aug 30, 2021

i discovered now, thanks to $9d, CHKIN to device 0 (keyboard) actually is an error. CLRCHN should be used instead. see ea486d8

jkotlinski added a commit that referenced this issue Aug 30, 2021
jkotlinski added a commit that referenced this issue Aug 30, 2021
@Whammo
Copy link
Collaborator

Whammo commented Aug 30, 2021

Some thoughts about existing code:

  • I think it would be good if LOADB and SAVEB return an ioresult that can be checked by calling code. If one is too lazy to do proper error handling, at least it's easy to call ioabort
  • It might be more straightforward if LOADB returned the number of read bytes.
  • It's not so nice that LOADB and SAVEB assume that logical file# 1 is free to use. But it's maybe livable.
  • It's not good that LOADB and SAVEB check the error channel in case of failure. If there is no device, it will hang.

ioresult could be a variable that is simply overwritten with the next file, stack, or even a FIFO buffer

@jkotlinski
Copy link
Owner Author

yes, that could work too, with the advantage that it's not a breaking change.
benefits of returning ioresult is that it encourages error handling, and it is similar to standard word READ-FILE.

@jkotlinski
Copy link
Owner Author

it's also a bit of open question if LOADB/SAVEB should be interactive or not.
the existing words are interactive, in that they read and print the command channel.
my gut feel is that the words are more generally useful if they are Not interactive, and instead return ioresult. but I think I could be convinced otherwise.

@jkotlinski
Copy link
Owner Author

jkotlinski commented Aug 31, 2021

...I think I change my mind! I now think it's fine if LOADB/SAVEB keep their current signatures, and are "interactive"
but they should be improved so that they always give some nice feedback to user, and never hang or lock up

Two problems to fix:

  • 12 device parse-name foo $7000 loadb hangs
  • 12 device $7000 $7100 parse-name foo saveb hangs

@Whammo
Copy link
Collaborator

Whammo commented Aug 31, 2021

ST is supposed to set a timeout show serial bus timeout with Bit 2. I am unaware of the conditions, but it's something to look into.
Some sources say it's bits 1 for read or write and 2 that it occurred. 1541s generally don't do this.
They all agree that bit 7 is device not present.
Something to consider, load and save block. open does not.

@Whammo
Copy link
Collaborator

Whammo commented Aug 31, 2021

Load/Save uses fast loaders, so that's not going anywhere. so merely opening channel 15 first, then you can readst, and see if the device is present first. abort or close and then load/save.

@jkotlinski
Copy link
Owner Author

jkotlinski commented Aug 31, 2021 via email

@Whammo
Copy link
Collaborator

Whammo commented Aug 31, 2021

The point is, LOAD blocks on a device not present error, right? So you can't check, the carry, it hangs.
So if you can open an arbitrary file or the command channel first, you don't have to read it, but you know the device exists.
Then you can safely LOAD

@Whammo
Copy link
Collaborator

Whammo commented Aug 31, 2021

Anyway, _errorchread definitely hangs if DEVICE not present.

: ecr $1551 sys ; ( Version 3 address of _errorchread )

Try it with different device numbers.

@jkotlinski
Copy link
Owner Author

I find that LOAD does in fact return an error in A:

( set filename 'x' )
'x' w c!
1 ar ! w xr ! 0 yr !
$ffbd sys ( setnam )

( logical file 1
  device 10 - non existing
  secondary address 1 )
1 ar ! 10 xr ! 1 yr !
$ffba sys ( setlfs )

( LOAD file to memory )
0 ar ! $ffd5 sys

( prints 5 - DEVICE NOT PRESENT error )
cr
ar c@ .

@Whammo
Copy link
Collaborator

Whammo commented Aug 31, 2021

I was meaning LOADB and SAVEB hangs, no way to check status.

@jkotlinski
Copy link
Owner Author

jkotlinski commented Aug 31, 2021 via email

@jkotlinski
Copy link
Owner Author

It was complicated to fix loadb and saveb for every kind of error, so I'm abandoning this effort for now.

I follow your suggestion to let v check for a good device number: 9a4e8ce

@jkotlinski jkotlinski reopened this Dec 26, 2022
@jkotlinski
Copy link
Owner Author

Created follow-up issue for the loadb/saveb hangs.

#499

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants