As you say:
There is a huge amount of hand-written assembly in IS-BASIC, EXOS and EXDOS - there must be loads of bugs!
Now found another one in the EXDOS
When started testing the SD interface cartridge I noticed the written files are randomly damaged
More than two weeks of debbuging I found exactly what is the bug.
When handling FAT sectors, some information copied to sector buffer header, for example the FAT size, this is will be used when calculating LBA address of specified FAT sector in the next FAT copy. Sector buffers are in the System Segment, paged to Page 2.
There is the buggy routine from 1.3 version (but all other versions have same):
CA5F 7E LD A, (HL)
CA60 D3 B1 OUT (B1), A
CA62 23 INC HL
CA63 5E LD E, (HL)
CA64 23 INC HL
CA65 56 LD D, (HL)
CA66 23 INC HL
CA67 D5 PUSH DE
CA68 CB B4 RES 6, H
CA6A CB FC SET 7, H
CA6C E5 PUSH HL
CA6D DD E1 POP IX
CA6F E1 POP HL
CA70 0E 01 LD C, 01
CA72 D1 POP DE
CA73 D5 PUSH DE
CA74 C5 PUSH BC
CA75 01 FF 01 LD BC, 01FF
CA78 CD B0 CA CALL CAB0
CA7B CD 1E CC CALL CC1E
CA7E C1 POP BC
CA7F D1 POP DE
CA80 20 01 JR NZ, CA83
CA82 0C INC C
CA83 FE BF CP BF
CA85 20 03 JR NZ, CA8A
CA87 01 01 01 LD BC, 0101
CA8A F5 PUSH AF
CA8B 7B LD A, E
CA8C DD 86 FC ADD A, (IX-04)
CA8F 5F LD E, A
CA90 30 01 JR NC, CA93
CA92 14 INC D
CA93 F1 POP AF
CA94 10 DD DJNZ CA73
It is page in to Page 1 the Unit Handler segment, this is needed for the Unit Handler call (The EXDOS paging routine will move it to Page 3, and page in the transfer segment fro C register to Page 1).
Ix will point to the transfer area (sector buffer data) it is converted to Page 1 address as the Unit Handler call (CC1Eh) need it.
After the call come the problem: using the IX addressing the sector buffer header (for the FAT size), but the IX point to the Page 1 where the Unit Handler segment paged in!!!
It is don't problem with the built in Units (floppy, Ramdisk) these are also in the System Segment then it is paged to both Page 1 and 2, the wrong IX also point to right place.
But with EXDOS extensions which are use separate segments the IX point to wrong place then using false data for calculations -> FAT2 written to the data area overwritting file data.
In the fix I only convert IX to Page 1 only for the Unit Handler call, removed the RES, SET from CA68h,CA6Ah, and the CALL CC1Eh modified to CALL this routine:
PUSH IX
PUSH HL
PUSH IX
POP HL
SET 6,H
RES 7,H
PUSH HL
POP IX
POP HL
CALL 0CC1EH
POP IX
RET
This is can be done only in 1.3 version, because only this have a free ROM space. It is renamed to version 1.4 because the extension programs can check the EXDOS are bug free (least this bug
).