You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was looking into adding LBA bios extensions (I have plans...) and I found this issue.
extended_read_disk always writes its return value to AL (not AX), but the invocation does:
movah,0cpu186shlax,9 extended_read_diskshrax,9cpu8086movah,0x02 ; Put read code backcmpal,0je rd_error
throwing AL away after extended_read_disk. Here I found disk read errors are thrown away. I was scratching my head on how this worked because extended_read_disk clearly sets AL to 0 on a successful read, but I finally figured out that AL is thrown away by the SHR instruction; thus the error code is never checked.
It's almost like the code wants the caller to do a ~read like the ~lseek, but even so that does nothing until this code is fixed. The following assembly change should fix the errors not being checked but will immediately break until the C code is fixed:
sub al, 1
adc ah, 0 ; Preserve CF through the following SHR
shr ax, 9
cpu 8086
mov ah, 0x02 ; Put read code back
jc rd_error
Checking lseek is useless anyway: lseek will happily seek out of bounds. Only checking read or write matters. Thus, the error code returned is always wrong. So rd_error and wr_error need work.
The text was updated successfully, but these errors were encountered:
joshudson
changed the title
Dodgy code in read
int13h Read and write don't check for errors
Nov 26, 2023
I was looking into adding LBA bios extensions (I have plans...) and I found this issue.
extended_read_disk always writes its return value to AL (not AX), but the invocation does:
throwing AL away after extended_read_disk. Here I found disk read errors are thrown away. I was scratching my head on how this worked because extended_read_disk clearly sets AL to 0 on a successful read, but I finally figured out that AL is thrown away by the SHR instruction; thus the error code is never checked.
It's almost like the code wants the caller to do a ~read like the ~lseek, but even so that does nothing until this code is fixed. The following assembly change should fix the errors not being checked but will immediately break until the C code is fixed:
Checking lseek is useless anyway: lseek will happily seek out of bounds. Only checking read or write matters. Thus, the error code returned is always wrong. So rd_error and wr_error need work.
The text was updated successfully, but these errors were encountered: