> I am a little bit freaked out by that because the pointer to the buffer is set before the IOCTL call; the code knowingly sets a pointer to a buffer into what looks like its code area. Let's hope they knew they were done with that part of the code, or it's just another interesting bug to dissect.
This is common in code without segmentation protection. CODE and DATA are convention. You can just specify a function, then a small buffer, then another function. .COM files in particular were easier to write with CS and DS pointing to the same region of memory, assuming you could fit both your code and inline buffers in 64kB.
The code explains what they are doing. Even more interesting, they're using their own stack too:
; 1 - This program uses its own internal stack. The stack space provided
; by DOS is used as an input buffer for transfering IBMBIO and IBMDOS.
;
; SYS is linked with the CODE segment followed by the DATA segment. The
; last symbol in DATA is BUF. It marks the end end of data and the
; start of the BUFfer. The BUFfer extends from here to SP. The first
; 6.5Kb (13 sectors) in BUFfer are used for up to 12 sectors of the FAT
; or the directory. In Main, the remaining space is set
; as follows:
; cdBuf = SP - ( FAT_BUF + BUF )
;
I looked at the call before and after to see what they had set the buffer to, and they clearly set the buffer to point into what is code. The executable is only 5KB and it's tiny; they had plenty of space in the segment to use a different part of the segment without purposefully blasting their own code.
While it's common, it was still a terrible practice. If whatever was filling in that buffer changed, they could be blasting more code than they intended. (As indicated in what I wrote, I know it was common if they wanted to reuse the space. Device drivers do something similar when they are done with their init code.)
Here's the code from DOS 3.3. I am reasonably sure they didn't intend to overwrite code -- you're probably just seeing a weird artifact where the failure case is leaving a dangling random value that happens to point into valid code.
My guess is that DS isn't being maintained across the failing call to the IOCTL and ends up pointing to the wrong segment.
DOSOutFH DW ? ; fh of DOS destination
DumpMem:
MOV DX,OFFSET DG:BUF+512 ; get offset of bios start
MOV CX,pDOS ; beginning of next guy
SUB CX,DX ; difference is length
JZ DumpDos ; no bios to move
MOV BX,BIOSOutFH ; where to output
MOV AH,Write
INT 21h ; wham
retc ; error
CMP AX,CX ; Did it work?
JNZ WRERR ; No
DumpDos:
MOV DX,pDOS ; beginning of dos
MOV CX,pDOSEnd ; end of dos
SUB CX,DX ; difference is length
retz ; if zero no write
MOV BX,DOSOutFH ; where to output
MOV AH,Write
INT 21h ; wham
retc ; error
CMP AX,CX ; Did it work?
retz ; Yes, carry clear
To use an LBA HDD or especially a SSD as well as DOS can, I've always found that the DOS from W98SE, with the 2001 update, is about the most reliable.
The only repeatable way when ongoing testing is underway is to zero the media each time, since many times DOS will rely strongest on what is already there during a Format or SYS. So will every version of Windows, but without full consistency at all.
If using Win10 or 11, you may find that even with a zeroed floppy or HDD partition when you power off, the partition will be silently formatted just as Windows last remembers it when you reboot, transparently without notice.
Plus even with successfully zeroed media, there is often a difference in what the Format comes out like depending on whether you booted the PC to an actual floppy, HDD, or SSD, and what their geometry was. And this can often come out different on different motherboards because of their dissimilar bios recognition of what the geometry is and what will be compatible with potential booting on that particular device.
Other times it seemed like some bioses were not suitable for formatting some media well enough to be bootable on their own device. But worked just fine if formatted on a more "universal" motherboard, then boot fine on the problem PC.
These days I want my FAT32 volumes, which are often being used as boot volumes as expected under UEFI, to be fully formatted under DOS for best reliability. None of the intentionally lesser stuff ever since. But I also want my structure to align with 4096 byte sectors which really helps with AF HDDs and SSDs. DOS won't do this on its own. Plus Windows mostly defaults to putting the bootsector at 2048 now instead of 63 on LBA gear, so I format a zeroed FAT32 partition using Windows 10 or 11 first. Then to the disk editor where everything is re-zeroed except the bootsector and the following 8 sectors. Edit the bootsector & backup bootsector (6 sectors later) for 2048 Hidden Sectors. And 2048, 4096 or a multiple of 4096 Sectors Per Fat, depending on which multiple is closest to the value that was there by default (according to the size of the partition) when there was no awareness of SSDs.
Then back to DOS and Format /Q, on a good motherboard it will retain the values you edited in, and you've got a more reliable foundation for your boot files or anything else.
> If using Win10 or 11, you may find that even with a zeroed floppy or HDD partition when you power off, the partition will be silently formatted just as Windows last remembers it when you reboot, transparently without notice.
Actively maintained is a handicap for something that's supposed to be a fixed long-term "standard".
MS-DOS is that immutable standard of the past which reached maximum maturity in 2001.
FreeDOS was originally an alternative, but is for the future now.
I like FreeDOS but when companies started to distribute their device drivers or software on floppies or CDROMs that were formatted using FreeDOS, it was not pretty.
Often there was no successful access or booting to the FAT volume, but all you needed to do was SYS the writable floppy with MS-DOS, or go through the ordeal of "ripping" the CD to correctly SYS its contents.
Regardless of the '90's or today I would recommend very strong familiarity with MS-DOS for some time, there is really nothing new there, before moving forward to include FreeDOS in your toolbox.
This is how it happened organically when FreeDOS was first emerging.
I think of MS-DOS mostly as the ultimate fantasy console. It is sad that the only way to write something once and not have to maintain it to keep up with breaking dependencies all the time is to target a dead platform.
But I never had any compatibility issues with FreeDOS? It seems like a good implementation of DOS. I mostly use DOSBox-X, but I use FreeDOS now and then as well. It is the only DOS I would consider running on hardware.
BTW did anyone else notice that Microsoft included almost a complete 1988 vintage 16-bit DOS toolchain in their MIT-licensed MS-DOS repo? It has Microsoft C 5.1, MASM 5.1, Make, and several other tools, plus libraries and include-files. All of it in less than 3 MB.
The reason I suggested FreeDOS was because the root comment was essentially a laundry list of bugs in MS-DOS. If there's a readily-available MS-DOS that does the job and doesn't have (material) bugs then sure by all means use that, but then what are we even talking about here?
FreeDOS is good, but it's a different flavor of DOS and not everything directly lines up. It's certainly where I'd start if I needed a DOS, but I'm sure there are things it won't work with.
I was not. Some googling shows a DOS based on Win95SR2 / Win98SE's (?) with unknown changes, possibly just the copyright string or setup, possibly more?
Off-topic, but the letter "y" of "ye" is in fact the letter 'thorn' (þ) in Old English, but got turned into "y" because the printing press, which originated from Germany, didn't have that English letter. That's why English alphabet also uses German "w" (double v's as you can notice from its shape, and pronounced "vee" in German) instead of English "double u" which used to be represented by a different letter called 'wynn' ('ƿ' or "uu").
Yup. It was never pronounced "yuhee". Sometimes it was written þe, other times it was written with a small "e" above "þ" like a diacritic. Because cursive "þ" looked similar to cursive "y" when English printers imported movable type from the continent they just used "y" for it.
So "Ye" was always pronounced "The" the way we do today.
Also the pronoun "ye" was written "ge" but pronounced similar to how we'd pronounce "ye" today. "You" was the formal pronoun. Saying "you" to family or close friends would be insulting - as if you weren't close to them. At some point it became fashionable to sound more upperclass/aristocratic so the formal "you" took over.
Thus confusion because "ye" was a real word used back then but for entirely different purposes and spelled "ge", while þe/the was always pronounced with a "th" like today but spelled differently before "th" was standardized.
If you said "Ye Olden Days" at best someone of the time might think you were saying "(your) olden days" implying they are very old and you're trying to reference their youth in a very oddly formal way but with the wrong pronoun.
Another Fun fact: thy/thine was already archaic at the time the King James Bible was written. They used it deliberately the way the OP used "Ye Olden Days" - to deliberately sound old and thus imply authority/authenticity. In the 1300s/1400s it was used when implying familiarity or contempt - with family it means familiarity/close relationships. Used with a stranger or superior it was like someone saying "Hey pal" to your boss. Again it became fashionable to switch to the second person plural for formality, then being formal all the time became fashionable, and eventually the formal forms became the new informal.
> I am a little bit freaked out by that because the pointer to the buffer is set before the IOCTL call; the code knowingly sets a pointer to a buffer into what looks like its code area. Let's hope they knew they were done with that part of the code, or it's just another interesting bug to dissect.
This is common in code without segmentation protection. CODE and DATA are convention. You can just specify a function, then a small buffer, then another function. .COM files in particular were easier to write with CS and DS pointing to the same region of memory, assuming you could fit both your code and inline buffers in 64kB.
The code explains what they are doing. Even more interesting, they're using their own stack too:
I looked at the call before and after to see what they had set the buffer to, and they clearly set the buffer to point into what is code. The executable is only 5KB and it's tiny; they had plenty of space in the segment to use a different part of the segment without purposefully blasting their own code.
While it's common, it was still a terrible practice. If whatever was filling in that buffer changed, they could be blasting more code than they intended. (As indicated in what I wrote, I know it was common if they wanted to reuse the space. Device drivers do something similar when they are done with their init code.)
Here's the code from DOS 3.3. I am reasonably sure they didn't intend to overwrite code -- you're probably just seeing a weird artifact where the failure case is leaving a dangling random value that happens to point into valid code.
My guess is that DS isn't being maintained across the failing call to the IOCTL and ends up pointing to the wrong segment.
Where is that published? I was using Github for references on DOS 4 as 3.3 isn't there yet.
(Thanks in advance!)
https://github.com/AR1972/DOS3.3/blob/master/SRC/CMD/SYS/SYS...
Send me a note via email -- I might have some more pointers for you
To use an LBA HDD or especially a SSD as well as DOS can, I've always found that the DOS from W98SE, with the 2001 update, is about the most reliable.
The only repeatable way when ongoing testing is underway is to zero the media each time, since many times DOS will rely strongest on what is already there during a Format or SYS. So will every version of Windows, but without full consistency at all.
If using Win10 or 11, you may find that even with a zeroed floppy or HDD partition when you power off, the partition will be silently formatted just as Windows last remembers it when you reboot, transparently without notice.
Plus even with successfully zeroed media, there is often a difference in what the Format comes out like depending on whether you booted the PC to an actual floppy, HDD, or SSD, and what their geometry was. And this can often come out different on different motherboards because of their dissimilar bios recognition of what the geometry is and what will be compatible with potential booting on that particular device.
Other times it seemed like some bioses were not suitable for formatting some media well enough to be bootable on their own device. But worked just fine if formatted on a more "universal" motherboard, then boot fine on the problem PC.
These days I want my FAT32 volumes, which are often being used as boot volumes as expected under UEFI, to be fully formatted under DOS for best reliability. None of the intentionally lesser stuff ever since. But I also want my structure to align with 4096 byte sectors which really helps with AF HDDs and SSDs. DOS won't do this on its own. Plus Windows mostly defaults to putting the bootsector at 2048 now instead of 63 on LBA gear, so I format a zeroed FAT32 partition using Windows 10 or 11 first. Then to the disk editor where everything is re-zeroed except the bootsector and the following 8 sectors. Edit the bootsector & backup bootsector (6 sectors later) for 2048 Hidden Sectors. And 2048, 4096 or a multiple of 4096 Sectors Per Fat, depending on which multiple is closest to the value that was there by default (according to the size of the partition) when there was no awareness of SSDs.
Then back to DOS and Format /Q, on a good motherboard it will retain the values you edited in, and you've got a more reliable foundation for your boot files or anything else.
> If using Win10 or 11, you may find that even with a zeroed floppy or HDD partition when you power off, the partition will be silently formatted just as Windows last remembers it when you reboot, transparently without notice.
Tell us more about that
Heh, reminds me of the days I kept Win95 and Win98 DOS boot disks for emergency booting Windows machines.
Does FreeDOS do better? It has the distinct advantage of being actively maintained.
Actively maintained is a handicap for something that's supposed to be a fixed long-term "standard".
MS-DOS is that immutable standard of the past which reached maximum maturity in 2001.
FreeDOS was originally an alternative, but is for the future now.
I like FreeDOS but when companies started to distribute their device drivers or software on floppies or CDROMs that were formatted using FreeDOS, it was not pretty.
Often there was no successful access or booting to the FAT volume, but all you needed to do was SYS the writable floppy with MS-DOS, or go through the ordeal of "ripping" the CD to correctly SYS its contents.
Regardless of the '90's or today I would recommend very strong familiarity with MS-DOS for some time, there is really nothing new there, before moving forward to include FreeDOS in your toolbox.
This is how it happened organically when FreeDOS was first emerging.
I think of MS-DOS mostly as the ultimate fantasy console. It is sad that the only way to write something once and not have to maintain it to keep up with breaking dependencies all the time is to target a dead platform.
But I never had any compatibility issues with FreeDOS? It seems like a good implementation of DOS. I mostly use DOSBox-X, but I use FreeDOS now and then as well. It is the only DOS I would consider running on hardware.
BTW did anyone else notice that Microsoft included almost a complete 1988 vintage 16-bit DOS toolchain in their MIT-licensed MS-DOS repo? It has Microsoft C 5.1, MASM 5.1, Make, and several other tools, plus libraries and include-files. All of it in less than 3 MB.
https://github.com/microsoft/MS-DOS/tree/main/v4.0/src/TOOLS
> Actively maintained is a handicap for something that's supposed to be a fixed long-term "standard".
Not if the static version is buggy.
MS-DOS 6.22 from 1994 isn't stable enough?
The reason I suggested FreeDOS was because the root comment was essentially a laundry list of bugs in MS-DOS. If there's a readily-available MS-DOS that does the job and doesn't have (material) bugs then sure by all means use that, but then what are we even talking about here?
FreeDOS is good, but it's a different flavor of DOS and not everything directly lines up. It's certainly where I'd start if I needed a DOS, but I'm sure there are things it won't work with.
There is Svardos as well, with EDR-DOS kernel, enhanced DR-DOS.
That DOS was already the better one back then.
Are you familiar with MS-DOS 7.1 by Wengier Wu (China DOS Union)?
I was not. Some googling shows a DOS based on Win95SR2 / Win98SE's (?) with unknown changes, possibly just the copyright string or setup, possibly more?
Eg: https://groups.google.com/g/comp.sys.ibm.ps2.hardware/c/UEz0...
If you have more info I'd be very interested in hearing about it. I also have no info on the China DOS Union.
You can download it here
https://winworldpc.com/product/ms-dos/7x
> In ye olden days to make a diskette bootable
Off-topic, but the letter "y" of "ye" is in fact the letter 'thorn' (þ) in Old English, but got turned into "y" because the printing press, which originated from Germany, didn't have that English letter. That's why English alphabet also uses German "w" (double v's as you can notice from its shape, and pronounced "vee" in German) instead of English "double u" which used to be represented by a different letter called 'wynn' ('ƿ' or "uu").
Yup. It was never pronounced "yuhee". Sometimes it was written þe, other times it was written with a small "e" above "þ" like a diacritic. Because cursive "þ" looked similar to cursive "y" when English printers imported movable type from the continent they just used "y" for it.
So "Ye" was always pronounced "The" the way we do today.
Also the pronoun "ye" was written "ge" but pronounced similar to how we'd pronounce "ye" today. "You" was the formal pronoun. Saying "you" to family or close friends would be insulting - as if you weren't close to them. At some point it became fashionable to sound more upperclass/aristocratic so the formal "you" took over.
Thus confusion because "ye" was a real word used back then but for entirely different purposes and spelled "ge", while þe/the was always pronounced with a "th" like today but spelled differently before "th" was standardized.
If you said "Ye Olden Days" at best someone of the time might think you were saying "(your) olden days" implying they are very old and you're trying to reference their youth in a very oddly formal way but with the wrong pronoun.
Another Fun fact: thy/thine was already archaic at the time the King James Bible was written. They used it deliberately the way the OP used "Ye Olden Days" - to deliberately sound old and thus imply authority/authenticity. In the 1300s/1400s it was used when implying familiarity or contempt - with family it means familiarity/close relationships. Used with a stranger or superior it was like someone saying "Hey pal" to your boss. Again it became fashionable to switch to the second person plural for formality, then being formal all the time became fashionable, and eventually the formal forms became the new informal.
Man, this takes me back.
I'm surprised to find I feel disappointment he didn't provide a patch to fix it.
Some day ... It took me months even just to get around writing up what I found ...
I'm still puzzled by the jump on the segment register values. I need to trace through the entire path.
Always surprised to find DOS 3.3 not referring to the long-lived, ubiquitous Apple II DOS.