samwdpckr
07.12.2023, 05:07 |
I made my own DOS implementation (Announce) |
Hello. I wrote my own operating system that is mostly compatible with the documented DOS API. It does many things differently than MS-DOS and FreeDOS - for example, it has dynamically growing caches and file buffers, which make disk I/O faster. It has driver APIs for device and filesystem drivers. Currently it has drivers for serial port, parallel port and CD-ROM drive and ISO9660 filesystem.
Download page:
http://sininenankka.dy.fi/~sami/fdshell/doskernel.php |
samwdpckr
17.12.2025, 23:53
@ bretjohn
|
I made my own DOS implementation |
IBM PC and compatibles don't check for that "boot sector signature" when booting from a floppy. Some BIOSes check that the first byte on the boot sector is a valid x86 instruction (I remember some sources stating that it is usually done by making sure that its numeral value is larger than 0x30, which also can cause problems because it assumes that the first instruction is a JMP instruction, which it necessarily isn't) but at least the IBM PC and PC XT BIOSes don't seem to have any checks there - it just jumps to the memory address where the contents of the first sector are.
Code from IBM PC BIOS version 3:
;--- INT 19 -----------------------------------------------------
; BOOT STRAP LOADER :
; IF A 5 1/4" DISKETTE DRIVE IS AVAILABLE ON THE SYSTEM, :
; TRACK 0, SECTOR 1 IS READ INTO THE BOOT LOCATION :
; (SEGMENT 0, OFFSET 7C00) AND CONTROL IS TRANSFERRED :
; THERE. :
; :
; IF THERE IS NO DISKETTE DRIVE, OR IF THERE IS A :
; HARDWARE ERROR CONTROL IS TRANSFERRED TO THE RESIDENT :
; BASIC ENTRY POINT. :
; :
; IPL ASSUMPTIONS :
; 8255 PORT 60H BIT 0 = 1 IF IPL FROM DISKETTE :
;----------------------------------------------------------------
ASSUME CS:CODE,DS:ABS0
;----- IPL WAS SUCCESSFUL
H4:
JMP BOOT_LOCN
ORG 0E6F2H
BOOT_STRAP PROC NEAR
STI ; ENABLE INTERRUPTS
SUB AX,AX
MOV DS,AX
;----- RESET DISKETTE PARAMETER TABLE VECTOR
MOV WORD PTR DISK_POINTER,OFFSET DISK_BASE
MOV WORD PTR DISK_POINTER+2,CS
MOV AX,DATA_WORD[OFFSET EQUIP_FLAG] ; GET THE EQUIPMENT SWITCHES
TEST AL,1 ; ISOLATE IPL SENSE SWITCH
JZ H3 ; GO TO CASSETTE BASIC ENTRY POINT
;----- MUST LOAD SYSTEM FROM DISKETTE -- CX HAS RETRY COUNT
MOV CX,4 ; SET RETRY COUNT
H1: ; IPL_SYSTEM
PUSH CX ; SAVE RETRY COUNT
MOV AH,0 ; RESET THE DISKETTE SYSTEM
INT 13H ; DISKETTE_IO
JC H2 ; IF ERROR, TRY AGAIN
MOV AX,201H ; READ IN THE SINGLE SECTOR
SUB DX,DX
MOV ES,DX
MOV BX,OFFSET BOOT_LOCN
MOV CX,1 ; SECTOR 1, TRACK 0
INT 13H ; DISKETTE_IO
H2: POP CX ; RECOVER RETRY COUNT
JNC H4 ; CF SET BY UNSUCCESSFUL READ
LOOP H1 ; DO IT FOR RETRY TIMES
;------ UNABLE TO IPL FROM THE DISKETTE
H3: ; CASSETTE_JUMP:
INT 18H ; USE INTERRUPT VECTOR TO GET TO BASIC
BOOT_STRAP ENDP
And BOOT_LOCN is 0x7C00.
In the PC XT BIOS the code is just arranged little differently, but it is still basically the same:
;--- INT 19 ---------------------------------------------
; BOOT STRAP LOADER :
; TRACK 0, SECTOR 1 IS READ INTO THE :
; BOOT LOCATION (SEGMENT 0, OFFSET 7C00) :
; AND CONTROL IS TRANSFERRED THERE. :
; :
; IF THERE IS A HARDWARE ERROR CONTROL IS :
; TRANSFERRED TO THE ROM BASIC ENTRY POINT. :
;--------------------------------------------------------
ASSUME CS:CODE,DS:ABS0
ORG 0E6F2H
BOOT_STRAP PROC NEAR
STI ; ENABLE INTERRUPTS
SUB AX,AX ; ESTABLISH ADDRESSING
MOV DS,AX
;----- RESET DISKETTE PARAMETER TABLE VECTOR
MOV WORD PTR DISK_POINTER,OFFSET DISK_BASE
MOV WORD PTR DISK_POINTER+2,CS
;----- LOAD SYSTEM FROM DISKETTE -- CX HAS RETRY COUNT
MOV CX,4 ; SET RETRY COUNT
H1: ; IPL_SYSTEM
PUSH CX ; SAVE RETRY COUNT
MOV AH,0 ; RESET THE DISKETTE SYSTEM
INT 13H ; DISKETTE_IO
JC H2 ; IF ERROR, TRY AGAIN
MOV AX,201H ; READ IN THE SINGLE SECTOR
SUB DX,DX
MOV ES,DX
MOV BX,OFFSET BOOT_LOCN
; DRIVE 0, HEAD 0
MOV CX,1 ; SECTOR 1, TRACK 0
INT 13H ; DISKETTE_IO
H2:
POP CX ; RECOVER RETRY COUNT
JNC H4 ; CF SET BY UNSUCCESSFUL READ
LOOP H1 ; DO IT FOR RETRY TIMES
;------ UNABLE TO IPL FROM THE DISKETTE
H3:
INT 18H ; GO TO RESIDENT BASIC
;----- IPL WAS SUCCESSFUL
H4:
JMP BOOT_LOCN
BOOT_STRAP ENDP
The PC AT BIOS does a lot more than PC and XT BIOSes. With floppies it first checks that the first word is not zero, and then it checks that the first 10 words are not the same. Technically this could also lead into problems if the first instruction is a short jump to somewhere beyond the first 20 bytes and the next 18 bytes are unreachable "code" that also happens to be the same JMP instruction repeating itself, in which case the system refuses to boot from a diskette that maybe should be bootable.
With hard disks the AT BIOS only checks that the boot sector signature 0x55AA is there. No other checks are made.
Code from IBM PC AT BIOS:
;--- BOOT_STRAP -- INT 19H ---------------------------
; BOOT STRAP LOADER :
; TRACK 0, SECTOR 1 IS READ INTO THE :
; BOOT LOCATION (SEGMENT 0 OFFSET 7C00) :
; AND CONTROL IS TRANSFERRED THERE. :
; :
; IF THERE IS A HARDWARE ERROR CONTROL IS :
; TRANSFERRED TO THE ROM BASIC ENTRY POINT :
;------------------------------------------------------
ASSUME CS:CODE,DS:ABS0
BOOT_STRAP_1 PROC NEAR
SUB AX,AX ; ESTABLISH ADDRESSING
MOV DS,AX
;------ RESET THE DISK PARAMETER TABLE VECTOR
MOV WORD PTR DISK_POINTER, OFFSET DISK_BASE
MOV WORD PTR DISK_POINTER+2,CS
;------ CLEAR BOOT_LOCN
MOV CX,256 ; CLEAR 256 WORDS
MOV BX,OFFSET BOOT_LOCN
H0: MOV [BX],AX
ADD BX,2
LOOP H0
;------ LOAD SYSTEM FROM DISKETTE -- CX HAS RETRY COUNT
STI
MOV CX,4 ; SET RETRY COUNT
H1: PUSH CX ; IPL SYSTEM
MOV AH,0 ; RESET THE DISKETTE SYSTEM
INT 13H ; DISKETTE_IO
JC H2 ; IF ERROR, TRY AGAIN
MOV AX,201H ; READ IN THE SINGLE SECTOR
SUB DX,DX ; TO THE BOOT LOCATION
MOV ES,DX
MOV BX,OFFSET BOOT_LOCN ; DRIVE 0, HEAD 0
MOV CX,1 ; SECTOR 1, TRACK 0
INT 13H ; DISKETTE_IO
H2: POP CX ; RECOVER RETRY COUNT
JNC H4 ; CARRY FLAG SET BY UNSUCCESSFUL READ
CMP AH,80H ; IF TIME OUT, NO RETRY
JZ H5 ; TRY FIXED DISK
LOOP H1 ; DO IT FOR RETRY TIMES
JMP H5 ; TRY FIXED DISK
;------ BOOT RECORD READ SUCCESSFUL
;------ INSURE FIRST BYTE OF LOADED BOOT RECORD IS VALID (NOT ZERO)
H4: CMP WORD PTR BOOT_LOCN,00H ; CHECK FOR FIRST INSTRUCTION INVALID
JE H10 ; IF BOOT NOT VALID PRINT MESSAGE HALT
;------ INSURE DATA PATTERN FIRST 10 WORDS NOT ALL EQUAL
MOV DI,OFFSET BOOT_LOCN ; CHECK DATA PATTERN
MOV CX,10 ; CHECK THE NEXT 10 WORDS
MOV AX,WORD PTR BOOT_LOCN
H4A: ADD DI,2 ; POINT TO NEXT LOCATION
CMP AX,[DI] ; CHECK DATA PATTERN FOR A FILL PATTERN
LOOPZ H4A
JZ H10 ; BOOT NOT VALID PRINT MESSAGE HALT
H4_A: JMP BOOT_LOCN
;------ ATTEMPT BOOTSTRAP FROM FIXED DISK
H5: MOV AL,044H ; <><><><><><><><><><><><><>
OUT MFG_PORT,AL ; <><><>CHECKPOINT 44 <><><>
ASSUME DS:DATA
CALL DDS
TEST HF_CNTRL,DUAL ; FLOPPY/FIXED DISK CARD INSTALLED
ASSUME DS:ABS0
MOV AX,ABS0 ; ESTABLISH ADDRESSING
MOV DS,AX
JZ H9 ; GO IF NOT
;------ CHECK FOR FIXED DISK INITIALIZATION ERROR
MOV AL,DIAG_STATUS ; GET POST POWER ON STATUS (NMI ENABLED)
AND AL,07FH
OUT CADR_PRT,AL
JMP SHORT $+2
IN AL,CDATA_PRT
TEST AL,HF_FAIL ; DID WE HAVE A FIXED DISK FAILURE?
JNZ H9 ; GO IF YES
SUB AX,AX ; RESET DISKETTE
SUB DX,DX
INT 13H
MOV CX,3 ; RETRY COUNT
H6:
PUSH CX ; SAVE RETRY COUNT
MOV DX,0080H ; FIXED DISK ZERO
MOV AX,0201H ; READ IN A SINGLE SECTOR
SUB BX,BX
MOV ES,BX
MOV BX,OFFSET BOOT_LOCN ; TO THE BOOT LOCATION
MOV CX,1 ; SECTOR 1, TRACK 0
INT 13H ; FILE I/O CALL
POP CX ; RECOVER RETRY COUNT
JC H8
CMP WORD PTR BOOT_LOCN+510D,0AA55H ; TEST FOR GENERIC BOOT BLOCK
JZ H4_A
H8: PUSH CX
MOV DX,0080H ; FIXED DISK ZERO
SUB AX,AX ; RESET THE FIXED DISK
INT 13H ; FILE I/O CALL
POP CX ; RESTORE LOOP COUNT
JC H10A ; IF ERROR, TRY AGAIN
LOOP H6 ; DO IT FOR RETRY TIMES
;------ UNABLE TO IPL FROM THE DISKETTE OR FIXED DISK
H9: MOV AL,045H ; <><><><><><><><><><><><><>
OUT MFG_PORT,AL ; <><><>CHECKPOINT 45 <><><>
INT 18H ; GO TO RESIDENT BASIC
;------ HARD FILE RESET FAILURE
H10A: LOOP H8 ; TRY RESET AGAIN
JMP H9 ; GO TO RESIDENT BASIC
;------ IF DISKETTE READ OK BUT BOOT RECORD IS NOT STOP SYSTEM ALLOW SOFT RESET
H10: MOV SI,OFFSET BOOT_INVA ; PRINT DISKETTE BOOT
CALL E_MSG ; PRINT MESSAGE
H11: JMP H11
BOOT_STRAP_1 ENDP
|
bretjohn

Rio Rancho, NM, 17.12.2025, 21:47
@ samwdpckr
|
I made my own DOS implementation |
> The boot sector signature is only required for hard disks. Bootable
> floppies don't need it.
This can be very confusing. The word-sized signature at the end of a 512-byte sector (be it a Master Boot Record or Volume Boot Record) indicates an IBM-compatible boot sector. It doesn't mean the sector will actually boot anything, but it means it should be safe to execute it as if it will load an OS (i.e., it shouldn't crash). Booting mechanisms will also (or sometimes only) look at the first several bytes of the sector to see if it looks like executable code (usually, the first byte is a JMP OpCode).
You also need to be careful when you use the term "floppy" since hard drives (including bootable ones and removable ones) can be configured as a "superfloppy" where they just have a BPB/VBR and don't have an MBR (and only have one "partition"). |
Japheth

Germany (South), 17.12.2025, 16:34
@ samwdpckr
|
I made my own DOS implementation |
> The boot sector signature is only required for hard disks. Bootable
> floppies don't need it.
Perhaps you should change your nickname to samntpckr... (just kidding)  --- MS-DOS forever! |
samwdpckr
16.12.2025, 13:29
@ Japheth
|
I made my own DOS implementation |
> > It is in http://sininenankka.dy.fi/leetos/doskernel.php a link named
> "Tools
> > and utilities disk"
>
> Thanks!
>
> Just checked it with WDE - all seems correct. The boot sector doesn't
> contain the "0xAA55" signature, but this is only required if the sector is
> supposed to contain "bootable" code.
The boot sector signature is only required for hard disks. Bootable floppies don't need it. |
Japheth

Germany (South), 16.12.2025, 12:25
@ roytam
|
I made my own DOS implementation |
> It is in http://sininenankka.dy.fi/leetos/doskernel.php a link named "Tools
> and utilities disk"
Thanks!
Just checked it with WDE - all seems correct. The boot sector doesn't contain the "0xAA55" signature, but this is only required if the sector is supposed to contain "bootable" code. --- MS-DOS forever! |
roytam
16.12.2025, 10:26
@ Japheth
|
I made my own DOS implementation |
> > > The utilities disk now includes also a FAT12/16 filesystem checker
> > (CHKFAT)
> > > with its source code that also compiles on GCC. Currently it cannot
> fix
> > any
> > > errors, but it is better at finding them than GNU fsck.msdos.
> >
> > oh cool, but dostools.img is too broken that DOS 6.22 can't even read
> it.
> >
> > EDIT: oh because the disk image has invalid BPB.
>
> Where can this dostools.img file be found? Will check it with WDE ...
It is in http://sininenankka.dy.fi/leetos/doskernel.php a link named "Tools and utilities disk" |
Japheth

Germany (South), 16.12.2025, 09:20
@ roytam
|
I made my own DOS implementation |
> > The utilities disk now includes also a FAT12/16 filesystem checker
> (CHKFAT)
> > with its source code that also compiles on GCC. Currently it cannot fix
> any
> > errors, but it is better at finding them than GNU fsck.msdos.
>
> oh cool, but dostools.img is too broken that DOS 6.22 can't even read it.
>
> EDIT: oh because the disk image has invalid BPB.
Where can this dostools.img file be found? Will check it with WDE ... --- MS-DOS forever! |
samwdpckr
16.12.2025, 03:34 (edited by samwdpckr, 16.12.2025, 04:08)
@ roytam
|
I made my own DOS implementation |
There's actually nothing wrong with that disk image. The problem is just that at some point Microsoft stopped conforming to the FAT specification. That's why FAT12/16 images that are created in other operating systems don't work properly on MS-DOS 6.22 and Windows.
If you read the output of that Norton tool carefully, you notice that it doesn't really make much sense at all. It even lists "errors" that aren't errors at all:
> Boot Record program is invalid
How does a disk utility know when the code there is "invalid" and when it isn't? You are allowed to have any code there - technically it doesn't even need to be x86 code.
You also seem to have one bad sector there, so your diskette is probably physically broken, if that isn't also some weird bug in the Norton Disk Doctor itself.
The FAT parser in NDD seems to be completely broken. Don't use it. |
roytam
15.12.2025, 16:42 (edited by roytam, 15.12.2025, 16:54)
@ samwdpckr
|
I made my own DOS implementation |
> Lots of progress has been made since I posted here last time. Nowadays the
> kernel can compile itself using the Open Watcom compiler and the DOS/32 DOS
> extender.
>
> The website now has a "Contribute" page, which also has a link to a set of
> guidelines of how to write userland programs. I will probably add more
> content to those pages in the near future.
>
> http://sininenankka.dy.fi/leetos/contribute.php
>
> The download page now has download counters. Only full file downloads are
> counted. Partial downloads don't increment the numbers.
>
> The utilities disk now includes also a FAT12/16 filesystem checker (CHKFAT)
> with its source code that also compiles on GCC. Currently it cannot fix any
> errors, but it is better at finding them than GNU fsck.msdos.
oh cool, but dostools.img is too broken that DOS 6.22 can't even read it.
EDIT: oh because the disk image has invalid BPB.
NDD log:
Disk Doctor
Norton Utilities 2002
December 15, 2025 3:46pm
*************************
* Report for Drive B: *
*************************
DISK TOTALS
----------------------------------------
1,457,664 bytes Total Disk Space
34,816 bytes in 1 User Files
13,824 bytes in 1 Hidden Files
512 bytes in bad sectors
1,408,512 bytes available on the disk
LOGICAL DISK INFORMATION
----------------------------------------
Media Descriptor: F0
Large Partition: No
FAT Type: 12-bit
Total Sectors: 2,880
Total Clusters: 2,847
Bytes Per Sector: 512
Sectors Per Cluster: 1
Bytes Per Cluster: 512
Number of FATs: 2
First Sector of FAT: 1
Number of Sectors Per FAT: 9
First Sector of Root Dir: 19
Number of Sectors in Root Dir: 14
Maximum Root Dir File Entries: 224
First Sector of Data Area: 33
PHYSICAL DISK INFORMATION
----------------------------------------
Drive Number: 1
Heads: 2
Cylinders: 80
Sectors Per Track: 18
Starting Head: 0
Starting Cylinder: 0
Starting Sector: 1
Ending Head: 1
Ending Cylinder: 79
Ending Sector: 18
SYSTEM AREA STATUS
----------------------------------------
Boot Record program is invalid
Status: Corrected
Media descriptor byte is invalid.
Status: Corrected
The FAT copies are not the same.
Status: Corrected
FILE STRUCTURE STATUS
----------------------------------------
**************** Errors processing directories ***************
Root Directory
Invalid entries found; Corrected
************* Errors in Long File Name Structures ************
Root Directory
has invalid long file names; Corrected
1 entries deleted.
************** Files with size allocation errors *************
\┼ox$.e$p
Status: Size adjusted
\║δ╢sueσi.$i
Status: Size adjusted
********************* Invalid directories ********************
\UσA╥TXE╧.╤τσ
Status: NOT Corrected
************************* Lost Chains ************************
Lost cluster chain at cluster 2
Status: Deleted
Lost cluster chain at cluster 3
Status: Deleted
Lost cluster chain at cluster 33
Status: Deleted
Lost cluster chain at cluster 35
Status: Deleted
Lost cluster chain at cluster 36
Status: Deleted
Lost cluster chain at cluster 69
Status: Deleted
Lost cluster chain at cluster 88
Status: Deleted
Lost cluster chain at cluster 89
Status: Deleted
Lost cluster chain at cluster 90
Status: Deleted
Lost cluster chain at cluster 128
Status: Deleted
Lost cluster chain at cluster 129
Status: Deleted
Lost cluster chain at cluster 130
Status: Deleted
Lost cluster chain at cluster 131
Status: Deleted
Lost cluster chain at cluster 132
Status: Deleted
Lost cluster chain at cluster 264
Status: Deleted
Lost cluster chain at cluster 297
Status: Deleted
Lost cluster chain at cluster 300
Status: Deleted
Lost cluster chain at cluster 303
Status: Deleted
Lost cluster chain at cluster 304
Status: Deleted
Lost cluster chain at cluster 320
Status: Deleted
Lost cluster chain at cluster 321
Status: Deleted
Lost cluster chain at cluster 415
Status: Deleted
Lost cluster chain at cluster 438
Status: Deleted
Lost cluster chain at cluster 475
Status: Deleted
Lost cluster chain at cluster 476
Status: Deleted
Lost cluster chain at cluster 495
Status: Deleted
Lost cluster chain at cluster 505
Status: Deleted
Lost cluster chain at cluster 508
Status: Deleted
Lost cluster chain at cluster 514
Status: Deleted
Lost cluster chain at cluster 516
Status: Deleted
Lost cluster chain at cluster 612
Status: Deleted
Lost cluster chain at cluster 2,730
Status: Deleted
Lost cluster chain at cluster 2,731
Status: Deleted
Lost cluster chain at cluster 2,732
Status: Deleted
Lost cluster chain at cluster 2,733
Status: Deleted
Lost cluster chain at cluster 2,734
Status: Deleted
Lost cluster chain at cluster 2,735
Status: Deleted
Lost cluster chain at cluster 2,736
Status: Deleted
Lost cluster chain at cluster 2,737
Status: Deleted
Lost cluster chain at cluster 2,738
Status: Deleted
Lost cluster chain at cluster 2,739
Status: Deleted
Lost cluster chain at cluster 2,740
Status: Deleted
Lost cluster chain at cluster 2,741
Status: Deleted
Lost cluster chain at cluster 2,742
Status: Deleted
Lost cluster chain at cluster 2,743
Status: Deleted
Lost cluster chain at cluster 2,744
Status: Deleted
Lost cluster chain at cluster 2,745
Status: Deleted
Lost cluster chain at cluster 2,746
Status: Deleted
Lost cluster chain at cluster 2,747
Status: Deleted
Lost cluster chain at cluster 2,748
Status: Deleted
Lost cluster chain at cluster 2,749
Status: Deleted
Lost cluster chain at cluster 2,750
Status: Deleted
Lost cluster chain at cluster 2,751
Status: Deleted
Lost cluster chain at cluster 2,752
Status: Deleted
Lost cluster chain at cluster 2,753
Status: Deleted
Lost cluster chain at cluster 2,754
Status: Deleted
Lost cluster chain at cluster 2,755
Status: Deleted
Lost cluster chain at cluster 2,756
Status: Deleted
Lost cluster chain at cluster 2,757
Status: Deleted
Lost cluster chain at cluster 2,758
Status: Deleted
Lost cluster chain at cluster 2,759
Status: Deleted
Lost cluster chain at cluster 2,760
Status: Deleted
Lost cluster chain at cluster 2,761
Status: Deleted
Lost cluster chain at cluster 2,762
Status: Deleted
Lost cluster chain at cluster 2,764
Status: Deleted
Lost cluster chain at cluster 2,765
Status: Deleted
Lost cluster chain at cluster 2,766
Status: Deleted
Lost cluster chain at cluster 2,767
Status: Deleted
Lost cluster chain at cluster 2,768
Status: Deleted
Lost cluster chain at cluster 2,769
Status: Deleted
Lost cluster chain at cluster 2,770
Status: Deleted
Lost cluster chain at cluster 2,771
Status: Deleted
Lost cluster chain at cluster 2,772
Status: Deleted
Lost cluster chain at cluster 2,773
Status: Deleted
Lost cluster chain at cluster 2,774
Status: Deleted
Lost cluster chain at cluster 2,775
Status: Deleted
Lost cluster chain at cluster 2,776
Status: Deleted
Lost cluster chain at cluster 2,777
Status: Deleted
Lost cluster chain at cluster 2,778
Status: Deleted
Lost cluster chain at cluster 2,779
Status: Deleted
Lost cluster chain at cluster 2,780
Status: Deleted
Lost cluster chain at cluster 2,781
Status: Deleted
Lost cluster chain at cluster 2,782
Status: Deleted
Lost cluster chain at cluster 2,783
Status: Deleted
Lost cluster chain at cluster 2,784
Status: Deleted
Lost cluster chain at cluster 2,785
Status: Deleted
Lost cluster chain at cluster 2,786
Status: Deleted
Lost cluster chain at cluster 2,787
Status: Deleted
Lost cluster chain at cluster 2,788
Status: Deleted
Lost cluster chain at cluster 2,789
Status: Deleted
Lost cluster chain at cluster 2,790
Status: Deleted
Lost cluster chain at cluster 2,791
Status: Deleted
Lost cluster chain at cluster 2,793
Status: Deleted
Lost cluster chain at cluster 2,794
Status: Deleted
Lost cluster chain at cluster 2,795
Status: Deleted
Lost cluster chain at cluster 2,796
Status: Deleted
Lost cluster chain at cluster 2,797
Status: Deleted
Lost cluster chain at cluster 2,798
Status: Deleted
Lost cluster chain at cluster 2,799
Status: Deleted
Lost cluster chain at cluster 2,800
Status: Deleted
Lost cluster chain at cluster 2,801
Status: Deleted
Lost cluster chain at cluster 2,802
Status: Deleted
Lost cluster chain at cluster 2,803
Status: Deleted
Lost cluster chain at cluster 2,804
Status: Deleted
Lost cluster chain at cluster 2,805
Status: Deleted
Lost cluster chain at cluster 2,806
Status: Deleted
Lost cluster chain at cluster 2,807
Status: Deleted
Lost cluster chain at cluster 2,808
Status: Deleted
Lost cluster chain at cluster 2,809
Status: Deleted
Lost cluster chain at cluster 2,810
Status: Deleted
Lost cluster chain at cluster 2,812
Status: Deleted
Lost cluster chain at cluster 2,813
Status: Deleted
Lost cluster chain at cluster 2,814
Status: Deleted
Lost cluster chain at cluster 2,815
Status: Deleted
Lost cluster chain at cluster 2,816
Status: Deleted
Lost cluster chain at cluster 2,818
Status: Deleted
Lost cluster chain at cluster 2,819
Status: Deleted
Lost cluster chain at cluster 2,820
Status: Deleted
Lost cluster chain at cluster 2,821
Status: Deleted
Lost cluster chain at cluster 2,822
Status: Deleted
Lost cluster chain at cluster 2,823
Status: Deleted
Lost cluster chain at cluster 2,824
Status: Deleted
Lost cluster chain at cluster 2,825
Status: Deleted
Lost cluster chain at cluster 2,827
Status: Deleted
Lost cluster chain at cluster 2,828
Status: Deleted
Lost cluster chain at cluster 2,829
Status: Deleted
Lost cluster chain at cluster 2,830
Status: Deleted
Lost cluster chain at cluster 2,831
Status: Deleted
Lost cluster chain at cluster 2,832
Status: Deleted
Lost cluster chain at cluster 2,833
Status: Deleted
Lost cluster chain at cluster 2,834
Status: Deleted
Lost cluster chain at cluster 2,835
Status: Deleted
Lost cluster chain at cluster 2,836
Status: Deleted
Lost cluster chain at cluster 2,837
Status: Deleted
Lost cluster chain at cluster 2,839
Status: Deleted
Lost cluster chain at cluster 2,840
Status: Deleted
Lost cluster chain at cluster 2,841
Status: Deleted
Lost cluster chain at cluster 2,842
Status: Deleted
Lost cluster chain at cluster 2,843
Status: Deleted
Lost cluster chain at cluster 2,844
Status: Deleted
Lost cluster chain at cluster 2,845
Status: Deleted
Lost cluster chain at cluster 2,846
Status: Deleted
Lost cluster chain at cluster 2,847
Status: Deleted
Lost cluster chain at cluster 2,848
Status: Deleted
SURFACE TEST STATUS
----------------------------------------
Surface Test not performed
|
samwdpckr
15.12.2025, 06:29
@ samwdpckr
|
I made my own DOS implementation |
Lots of progress has been made since I posted here last time. Nowadays the kernel can compile itself using the Open Watcom compiler and the DOS/32 DOS extender.
The website now has a "Contribute" page, which also has a link to a set of guidelines of how to write userland programs. I will probably add more content to those pages in the near future.
http://sininenankka.dy.fi/leetos/contribute.php
The download page now has download counters. Only full file downloads are counted. Partial downloads don't increment the numbers.
The utilities disk now includes also a FAT12/16 filesystem checker (CHKFAT) with its source code that also compiles on GCC. Currently it cannot fix any errors, but it is better at finding them than GNU fsck.msdos. |
samwdpckr
31.10.2024, 22:29
@ samwdpckr
|
I made my own DOS implementation |
I made a video of installing ST-DOS and NETDISK.
https://www.youtube.com/watch?v=iW4KVJcfmz8 |
samwdpckr
08.09.2024, 01:32 (edited by samwdpckr, 08.09.2024, 01:59)
@ samwdpckr
|
I made my own DOS implementation |
I noticed mbbrutman's NetDrive and got some inspiration from it. I created NETDISK. Now ST-DOS has the power of cloud too.
Download page:
http://sininenankka.dy.fi/leetos/netdisk.php
Because ST-DOS has a different device driver API than MS-DOS and its 100% clones, NETDISK only works on ST-DOS. The way it works is pretty similar to mTCP NetDrive - the server computer has disk images and they are shared to the client computers. There are some differences though. Although NETDISK and mTCP NetDrive are products that serve different purposes and are not competing against each other, some comparisons between them can still be made:
NETDISK's pros, compared to mTCP NetDrive:
+ Works with all filesystem types (because ST-DOS has a filesystem driver API)
+ Has dynamic caching, which probably makes NETDISK faster
+ The server works on both DOS and POSIX-compatible operating systems like Linux (compiling it to DOS needs the socket.h header from ST-DOS's TCP/IP stack and its sockhdr.obj object file)
+ Works with almost indefinitely large drives (ST-DOS uses 64-bit offsets for device files)
Cons:
- Only works with ST-DOS
- No advanced features like sessions and "undo" - the server program is currently very simple and doesn't have a lot of code
- The device driver does not currently support unloading, a reboot is needed
I had to make some fixes to the kernel and the TCP/IP stack to get NETDISK working, so it only works with the newest versions of them. |
fritz.mueller

Munich, Germany, 17.05.2024, 12:49
@ Rugxulo
|
I made my own DOS implementation |
Hi,
I ran one more test of ST-DOS with version 2024-05-16 in virtualbox.
I added some DOS programs to see what works and what not.
a) mkeyb gr lead to a blinking cursor, nothing else (I think I already
reported this). It would be great to have at least some other keyboards than US and finnish.
b) fdshell 0.10 (dosshell) lead to a freeze after the first basic information.
dosshell /? showed the help and exited.
c) fd edit worked but froze at "save as - filename" After a regular exit without saving I got an unknown system call 38Child exited with return code 0
d) doszip (dz) lead to a blinking cursor after start.
e) ctmouse seems to work
f) editor Blocek lead to a blinking cursor.
g) game blkdrop showed some code and exited with: Child exited wirth return code 243
h) game flpybird lead to a message: Child exit
i) game sayswho seemed to work - not absolutely sure - but after exit (ESC) the whole sourcecode ran through on screen and I got a message Child exited with return code 0
j) game senet seemed to work.
k) NewDOS browser seems to work but after exit the whole sourcecode ran through.
l) NewDOS calculator seems to work, after exit sourcecode ran through.
m) NewDOS scandrv -> same
n) NewDOS cleandsk -> same
o) NewDOS scanfix: Syscall44: Unknown function09
p) NewDOS setdate: changed Date but after exit sourcecode ran through.
q) It would be nice if "dir" would support "dir /w". |
Rugxulo

Usono, 08.04.2024, 03:19
@ samwdpckr
|
I made my own DOS implementation |
> I just find it weird when a software developer, who doesn't even write
> assembly, suddenly says that someone else's computer is "too old" or "too
> slow" and must not be "supported" anymore. If we consider that that
> "someone else's computer" is a turing-complete machine that has enough
> memory to run the program in question, and has enough computing power that
> its owner does not consider it "too slow", the software developer should
> not have the right to say that it is.
The CDC 6600 mainframe from 1964 was a 60-bit processor at 10 Mhz up to 982 kb of memory (almost a meg??) running 2 MIPS. It cost $2.4 million (equivalent to $23 million today).
Wikipedia says:
"Many minicomputer performance claims were based on the Fortran version of the Whetstone benchmark, giving Millions of Whetstone Instructions Per Second (MWIPS). The VAX 11/780 with FPA (1977) runs at 1.02 MWIPS. Results on a 2.4 GHz Intel Core 2 Duo (1 CPU 2007) vary from 9.7 MWIPS using BASIC Interpreter to 2,403 MWIPS using a modern C/C++ compiler."
In fairness, you shouldn't have to be a systems engineer with a PhD just to use or program a computer. Having said that, choice of OS, compiler, and algorithm make a big difference (depending on the requirements). It's NOT true that everyone born before 1990 was a rube who knew nothing, nor that their machines were incapable of "real work".
> The job of the software developer is to just maintain the program, and
> generally when we are speaking of relatively high-level userspace programs
> or their libraries, they compile to older x86 hardware just fine, unless
> something is actively preventing it from happening.
C is much better than assembly for portability, but it's still VERY flawed. A skilled developer can work around most of that, but most people don't care. It is NOT "strictly conformant by default". No amount of "standards" or warnings or lints or libraries can hide all of that for you. You just have to "test test test!" and work around any problems you find (whether preprocessor macros, patches, separate modules, libraries, external tools, etc).
So-called "UNIX" or "UNIX-like" or "POSIX" or sticking to GNU tools or Ubuntu LTS does not save you from portability problems. There used to be a saying: "all the world's a VAX!" (see the Jargon File). VMS and Windows NT were both from Dave Cutler and somewhat considered anti-UNIX in philosophy. In other words, OS-specific code is nothing new. (And yet Cutler insisted that Windows NT be portable from the beginning. Too bad most other cpu makers like MIPS, Alpha, PowerPC couldn't compete with Intel.)
EDIT: You may prefer to hang around more sympathetic people (e.g. NetBSD or OpenBSD) rather than Linux. |
samwdpckr
01.04.2024, 16:31
@ samwdpckr
|
I made my own DOS implementation |
I wrote the basic utilities TREE, DELTREE, ATTRIB, XCOPY and DIRFIND (called when DIR /S command is given to the command prompt). DELTREE and XCOPY were important, because the graphical interface calls them when copying entire directories. I also added a non-standard syscall that changes the timestamp of a directory entry. |
Rugxulo

Usono, 31.03.2024, 22:59
@ Oso2k
|
I made my own DOS implementation |
> At least with gcc, binutils, and djlsr (djgpp’s bsd derived libc),
> you tell exactly build-djgpp builds and injects ISA support.
>
> https://github.com/andrewwutw/build-djgpp/issues/45
Just FYI ....
GNU sed (and FreeBSD sed) support a non-standard -i switch to edit "in place", thus no need for a temporary output file and mv afterwards. (If you use -i~, it will create a backup file first.) |
Oso2k
31.03.2024, 21:22
@ samwdpckr
|
I made my own DOS implementation |
> And 32-bit x86 Linux desktop is already completely broken because of those
> idiots who insist that everything must be compiled for at least SSE2
> targets. Literally nothing works and everything just throws invalid opcode
> errors. When the compiler is asked to generate i686, i586 or even i486
> code, there is still SSE2 instructions everywhere, because the CFLAGS are
> overridden in multiple lines of the build scripts. It is a lot of work to
> make them actually work and then the next software update breaks it again.
I think you’re making an assumption here. At least with gcc, binutils, and djlsr (djgpp’s bsd derived libc), you tell exactly build-djgpp builds and injects ISA support. Rich Felker’s cross compiler scripts do something very similar for musl libc and Linux.
https://github.com/andrewwutw/build-djgpp/issues/45
https://github.com/richfelker/musl-cross-make |
samwdpckr
30.03.2024, 20:09 (edited by samwdpckr, 30.03.2024, 20:32)
@ Rugxulo
|
I made my own DOS implementation |
> For many years the world has already tried to deprecate and kill IA-32.
> Ubuntu doesn't support it anymore (since 2019?). Like I said, people are
> arguing over whether x64 v3 should be the new baseline or not.
I remember when Ubuntu used it as a "marketing advantage" against Windows that Ubuntu works on older computers. Nowadays Ubuntu is a complete opposite of what it once was. It is so bloated that even new cheap laptops cannot run it anymore.
And 32-bit x86 Linux desktop is already completely broken because of those idiots who insist that everything must be compiled for at least SSE2 targets. Literally nothing works and everything just throws invalid opcode errors. When the compiler is asked to generate i686, i586 or even i486 code, there is still SSE2 instructions everywhere, because the CFLAGS are overridden in multiple lines of the build scripts. It is a lot of work to make them actually work and then the next software update breaks it again.
At least command line tools still work on a Pentium II, which also has easily more than enough computing power for them. Everything happens instantly and the difference to new computers is almost unnoticeable.
The situation is already so crazy that I'm scared of installing software updates on a computer that is only ten years old and has an i7-based Xeon CPU, because I fear that the new version of some important package has instructions that my CPU does not support.
You cannot trust the archname in the name of the software package anymore. "i686" does not actually mean i686 and x64 may be basically anything.
> To some people, RAM unused is wasted.
I thought that the one of the basic ideas of multitasking is that one program cannot consume all memory of the computer. Aren't se supposed to have multitasking computers in 2024? |
Rugxulo

Usono, 30.03.2024, 10:16
@ samwdpckr
|
I made my own DOS implementation |
> Nowadays many developers want to drop support of CPUs that don't have SSE2
> instructions, and they are basically using those new instruction set
> extensions as a tool to bully people who have an "old" computer that still
> has more than enough computing power for their use.
Those kinds of people upgrade every few years, maybe because of their workplace forcing them. They probably don't have the same import taxes or high shipping costs as you.
Also, when a compiler (or library) drops support for a certain OS or cpu family, someone else has to take up that burden or leave it abandoned. If one piece is missing, it's easy for the whole thing to crumble. "Tier 1" is almost always AMD64 (v2?) and maybe ARM64.
> They are reasoning it
> by saying that the new instruction set extensions make the program run
> faster, when the reality is that every new version of the program is always
> more bloated than the previous one. This culture is especially visible
> amongst the Rust gang and the developers of many graphical desktop
> libraries in the FOSS world.
CLMUL (circa 2010) claims to be faster. Have I ever used it? No.
I did, years ago, find 2x speedups in PAQ8 with his SSE2 patches. Actually, at that time, MMX or SSE2 was roughly the same speed. SSE2 improved more later. But my fork wasn't locking anyone in to specific OSes or cpus. (His default build was MinGW G++ 3.4 targeting MMX using MVSCRT.DLL that had a stupid tmpfile() bug on non-Admin Vista, so I rebuilt with newer DJGPP using CPUID. And I wanted CWSDPMI support so that it could swap to disk if needed. OpenWatcom/Causeway also worked but much less efficiently [worse malloc, slower swapping].).
Oscar Wilde said, "A cynic is someone who knows the cost of everything and the value of nothing."
> They are purposely writing code that breaks when sizeof(long) is not 64,
> and are writing makefiles that override the CFLAGS that the user has set,
> resulting in a binary that has a different CPU target than was intended by
> the user. This type of behaviour is unacceptable. When the program has zero
> lines of assembly, there is absolutely no reason to artificially limit its
> portability by preventing building it to certain CPU targets.
While I 100% agree, strict ISO C has never been meant to be portable. They explicitly allow non-portable things. (Heck, PAQ8 was pre-C++11 and didn't compile on AMD64 due to such bugs. It was also single core only and very slow but still very good.)
Actually, even ISO C only mandated that "long double" equal double, which is what MSVCRT does (or did, in the old days), same with OpenWatcom (unlike GCC). And I don't think AMD64 supports beyond "double" directly anyways. So FPC's Extended type is unsupported on AMD64. (AVX probably fixes that, but that's yet another can of worms.)
I believe the Linux kernel is roughly C11 (without VLAs) with GCC extensions of course.
> And my example shows that using those new instruction set extensions like
> MMX and SSE2 does not always even make the code faster. SSE2 can do 64-bit
> math natively, so there is less code involved in adding 64-bit numbers, and
> it should be faster in theory, but not always in practice. The user must
> always have the option to build and optimize the code for their own
> computer, even when the computer is "old" or something else than intended
> by the original developer of the software.
Old also means a lot of things. I remember my P4. It was single core only (mainly noticeable during antivirus scans, ugh). It had some USB 1.1 (slower) and some USB 2 ports. It was using a traditional hard drive (non-SSD). The 512 MB of RAM was probably DDR2. You can compare cpus from 2004 to 2020 to see a difference.
> I just find it weird when a software developer, who doesn't even write
> assembly, suddenly says that someone else's computer is "too old" or "too
> slow" and must not be "supported" anymore. If we consider that that "someone > else's computer" is a turing-complete machine that has enough memory to run
> the program in question, and has enough computing power that its owner does
> not consider it "too slow", the software developer should not have the right > to say that it is.
IIRC, the PlayStation 5 and XBox Series X are both Ryzen 2 with 16 GB of RAM. Compare that to 2013-era PS4 and XBoxOne. My point is that nothing is ever good enough for some people. (But they do try to do a lot more with HD/UHD/4k/whatever.)
> The job of the software developer is to just maintain the program, and
> generally when we are speaking of relatively high-level userspace programs or > their libraries, they compile to older x86 hardware just fine, unless
> something is actively preventing it from happening. Breaking compatibility
> with 32-bit x86 CPUs and/or pre-SSE2 CPUs will most likely also break
> compatibility with many non-x86 targets.
For many years the world has already tried to deprecate and kill IA-32. Ubuntu doesn't support it anymore (since 2019?). Like I said, people are arguing over whether x64 v3 should be the new baseline or not.
They don't really sympathize with people who don't upgrade every few years. (I would say every five years would be nice, but it's usually shorter than that.) A lot of software won't work on Win7 or 8 anymore. Heck, for laughs, I sent my mother an email about Cygwin. They used to support Win9x. Then it was XP (for Unicode). Then they dropped IA-32. Then they dropped older OSes (like Win7/8).
Linux is all about choice. But often that choice is "not invented here!" or "UNIX only!" or "we don't care about anything before 2017!". Roll your own, develop your own ... easier said than done. Face it, "portability" is not a priority for most people.
To some people, RAM unused is wasted. You know, ulimit says their stack is "unlimited", and virtual memory and AMD64's 48-bit addresses just encourage wasteful practice. (Granted, trying to do everything in 64 kb is unrealistic. But a home user REALLY shouldn't need 64 GB of RAM for anything!) I'm not saying we should all target 286s or use 486s to identify our algorithms' bottlenecks. But meh, the modern world is not optimal. ("We don't have time! It costs money! We don't have a test setup!")
You know what's slow? Recompiling headers over and over again. (But C++20 fixed that. "Just throw more cores at it!") Garbage collection. Bytecode. Quadratic algorithms. Cpu cache thrashing. AutoTools/Configure under Cygwin. Slow software emulation (because xyz isn't supported anymore). Bugs. Limits.
The whole point of "computer science", I thought, was to not be tied to any specific technology. In other words, don't rely too heavily on any cpu or OS or compiler or language dialect. They don't last. You have to do everything yourself. (Well, sometimes other people help.)
But yes, talk is cheap, and "upgrade!" is never useful advice. |
samwdpckr
29.03.2024, 22:31
@ Rugxulo
|
I made my own DOS implementation |
> I think I meant older cpus are quietly deprecated due to such bugs
> (overeager speculative execution or whatever).
Actually that's more of a problem with newer CPUs. Old pre-SSE2 CPUs don't do such things.
I just find it weird when a software developer, who doesn't even write assembly, suddenly says that someone else's computer is "too old" or "too slow" and must not be "supported" anymore. If we consider that that "someone else's computer" is a turing-complete machine that has enough memory to run the program in question, and has enough computing power that its owner does not consider it "too slow", the software developer should not have the right to say that it is.
The job of the software developer is to just maintain the program, and generally when we are speaking of relatively high-level userspace programs or their libraries, they compile to older x86 hardware just fine, unless something is actively preventing it from happening. Breaking compatibility with 32-bit x86 CPUs and/or pre-SSE2 CPUs will most likely also break compatibility with many non-x86 targets.
If the software developer only does their job and maintains the program so that it works efficiently, it also saves the environment because the users don't need to buy new computers to be able to continue using the program. In that case the program also consumes less electricity on newer machines. |
Rugxulo

Usono, 29.03.2024, 22:01
@ samwdpckr
|
I made my own DOS implementation |
> > Having said that, with all the malware / ransomware in the world, I think
> > a lot of concerns for older hardware and software are related to security.
>
> Instruction set extensions have nothing to do with security. If anything,
> unconditionally requiring these new instruction set extensions worsen the
> security, because that prevents some people from updating the software to
> the latest versions.
I think I meant older cpus are quietly deprecated due to such bugs (overeager speculative execution or whatever). There are many workarounds in the Linux kernel for such flaws, but the "oldest" Linux kernel still actively maintained (on kernel.org) is 4.19 from Oct. 2018. I'm sure distributions can still patch other kernels if needed.
But overall it's sometimes hard to find sympathy for old or weak tech. If it isn't actively sold, maintained, or doesn't receive security fixes (or microcode updates), some people refuse to care.
In a perfect world, any tech that could work should be potentially good enough (and not worthy of scorn).
I saw someone on Twitch stream Quest for Glory (EGA) via DOSBox. As you know, VGA was vastly more popular and easier to program. Still, EGA works on more machines and 320x200x16 colors is still "good enough" for some things. My point is we don't always forcibly have to use the "latest greatest", even if everyone else seems to be doing it. (We may both be preaching to the choir here.) |
samwdpckr
29.03.2024, 18:00
@ fritz.mueller
|
I made my own DOS implementation |
I noticed that the symbolic links were completely broken. Now it seems to handle all corner cases correctly.
> Only a few bug reports:
> a) After installation of latest version including leetos I removed the
> diskette (controller still inside), rebooted and got a freeze.
> Reason: HD changed to A: leetos still looks for "cd c:\leetos" instead of
> "%COMDRV%\leetos" and freezes.
> b) It also freezes when I enter Z:\test (not existing drive)
Thanks. I fixed that.
> c) edit: I tried to open A:\fdauto.bat (which does not exist), chose
> A:\autoexec.bat and get the error message: Syscall 44: Unknown function
> 09.
I don't understand what you mean. But syscall 44 function 09 does not have to exist when MS-DOS compatible networking functions are not loaded, so that's not necessarily a bug in ST-DOS. Other DOS kernels just don't show that error message, and I intend to hide it in future versions.
> d) I entered mkeyb041 gr (german keyboard layout) and got a freeze.
> e) I entered mkeyb050 gr /e 101keys keyboard and got a freeze.
Memory control blocks in ST-DOS are different than they are in ST-DOS.
> e) I played 2kTetris (can be found at:
> https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/games/tetris/
> It worked, but when game was over, I entered "n" (for no more game) and got
> a:
> "KERNEL>_(blinking cursor)"
The game may have corrupted something in the memory. Not necessarily a bug in ST-DOS.
> Having said that, with all the malware / ransomware in the world, I think a
> lot of concerns for older hardware and software are related to security.
Instruction set extensions have nothing to do with security. If anything, unconditionally requiring these new instruction set extensions worsen the security, because that prevents some people from updating the software to the latest versions. |
Rugxulo

Usono, 29.03.2024, 02:53
@ samwdpckr
|
I made my own DOS implementation |
> Nowadays many developers want to drop support of CPUs that don't have SSE2
> instructions, and they are basically using those new instruction set
> extensions as a tool to bully people who have an "old" computer that still
> has more than enough computing power for their use.
SSE2 is already ubiquitous. It's anything older than x64 v3 (AVX) that people are struggling with now. I don't get it, personally.
https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
> They are reasoning it
> by saying that the new instruction set extensions make the program run
> faster, when the reality is that every new version of the program is always
> more bloated than the previous one. This culture is especially visible
> amongst the Rust gang and the developers of many graphical desktop
> libraries in the FOSS world.
Intel does fund a lot of developers, and Windows, Linux, Mac are all pretty snobbish in jumping on trends and throwing a lot of things away.
Having said that, with all the malware / ransomware in the world, I think a lot of concerns for older hardware and software are related to security. |
fritz.mueller

Munich, Germany, 28.03.2024, 21:19
@ samwdpckr
|
I made my own DOS implementation |
Only a few bug reports:
a) After installation of latest version including leetos I removed the diskette (controller still inside), rebooted and got a freeze.
Reason: HD changed to A: leetos still looks for "cd c:\leetos" instead of "%COMDRV%\leetos" and freezes.
b) It also freezes when I enter Z:\test (not existing drive)
c) edit: I tried to open A:\fdauto.bat (which does not exist), chose A:\autoexec.bat and get the error message: Syscall 44: Unknown function 09.
d) I entered mkeyb041 gr (german keyboard layout) and got a freeze.
e) I entered mkeyb050 gr /e 101keys keyboard and got a freeze.
e) I played 2kTetris (can be found at: https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/games/tetris/
It worked, but when game was over, I entered "n" (for no more game) and got a:
"KERNEL>_(blinking cursor)"
So much for today. |
samwdpckr
28.03.2024, 04:15
@ Rugxulo
|
I made my own DOS implementation |
Nowadays many developers want to drop support of CPUs that don't have SSE2 instructions, and they are basically using those new instruction set extensions as a tool to bully people who have an "old" computer that still has more than enough computing power for their use. They are reasoning it by saying that the new instruction set extensions make the program run faster, when the reality is that every new version of the program is always more bloated than the previous one. This culture is especially visible amongst the Rust gang and the developers of many graphical desktop libraries in the FOSS world.
They are purposely writing code that breaks when sizeof(long) is not 64, and are writing makefiles that override the CFLAGS that the user has set, resulting in a binary that has a different CPU target than was intended by the user. This type of behaviour is unacceptable. When the program has zero lines of assembly, there is absolutely no reason to artificially limit its portability by preventing building it to certain CPU targets.
And my example shows that using those new instruction set extensions like MMX and SSE2 does not always even make the code faster. SSE2 can do 64-bit math natively, so there is less code involved in adding 64-bit numbers, and it should be faster in theory, but not always in practice. The user must always have the option to build and optimize the code for their own computer, even when the computer is "old" or something else than intended by the original developer of the software. |
Rugxulo

Usono, 28.03.2024, 01:29
@ samwdpckr
|
I made my own DOS implementation |
> My previous message did not make much sense. It turns out that MMX does
> only 32-bit math and many sources from the internet are wrong about this. I
> replaced the MMX routines with code that uses the 32-bit i386 registers.
> The new code is also much faster.
Keep in mind that MMX is still using the FPU behind the scenes.
> I also tried SSE2 instructions, but interestingly they were not much faster
> than MMX either.
You're using a 3 Ghz Pentium 4? Very quirky machines. SSE2 was first introduced with the Pentium 4, and is probably preferred for that machine (and default for AMD64). If it's not "faster" on that one machine, keep in mind that Pentium 4 had long pipelines and had no barrel shifter (i.e. shifts are slow) and other quirky things (use add 1 instead of inc). Even SSE2's bandwidth would greatly increase in later cpus, so it's definitely faster nowadays. GCC always had surprisingly good tuning for Pentium 4. Feel free to compare its output. Oh, and FXSAVE/FXRSTOR is faster than the old FPU way of saving things. |
samwdpckr
27.03.2024, 23:29
@ samwdpckr
|
I made my own DOS implementation |
My previous message did not make much sense. It turns out that MMX does only 32-bit math and many sources from the internet are wrong about this. I replaced the MMX routines with code that uses the 32-bit i386 registers. The new code is also much faster.
I also tried SSE2 instructions, but interestingly they were not much faster than MMX either.
Trying to replace 64-bit comparisons with hand-written routines seems to result in slow code. The reason is probably that the hand-written routines have to always have their return value in a general-purpose register, whereas the comparisons that the compiler generates natively have their "return value" in the flags register. So although comparing two 64-bit numbers in 16-bit registers means having to do four conditional jumps, it is still faster than a hand-written routine. AFAIK the Watcom compiler does not support having a return value of an actual function in the flags register. But replacing 64-bit additions and substractions with hand-written inline routines did speed things up a lot.
Symlinks can now point to device files. Previously they could only point to actual files.
The cache lookup table was previously a far object, but I moved it to the same segment with the kernel, which resulted in a small performance improvement. |
samwdpckr
26.03.2024, 04:36
@ samwdpckr
|
I made my own DOS implementation |
New version. No new features this time, and no significant bugfixes either. In the filesystem mounter there was a bug that affected only builds with 64-bit LBA support when the BIOS supported LBA48 or higher. The program left the most significant doubleword of the "starting sector" of a filesystem uninitialized and it caused read errors. The default build of the kernel uses only 32-bit sector indexes anyway.
I did numerous small fixes to make the kernel support 64-bit sector indexing properly, so now it should work with larger than 2 TB hard drives. I cannot test it though.
I did also many micro-optimizations and reordered the arguments of many functions.
I wrote routines that calculate the sector indexes using MMX instructions. I thought that it would make the math with 64-bit integers a lot faster than adding, subtracting and comparing the numbers 16 bits at time in the 8086-compatible general purpose registers. In the end the MMX version turned out to be significantly slower, at least on a 3 GHz Pentium 4. This again shows that using new fancy instruction set extensions does not always make the program run faster, but it can very efficiently ruin compatibility with older hardware. The kernel can be compiled with "-dUSE_MMX" to create a build that uses MMX instructions.
The kernel can also be compiled for different targets than just 8086. I noticed that when it is compiled for i386 or newer CPUs, some programs just stop working. One of those programs is Doom's installer. I don't know why that happens.
The "VER" command of the command prompt now also shows the build target of the kernel. |
samwdpckr
23.03.2024, 20:32
@ tom
|
I made my own DOS implementation |
Anyway, now the owner of the MCB changes when the realloc syscall is made, so modifying the internal structs is not necessary. I don't know if that works in FreeDOS, but because FreeDOS aims to be a 100% MS-DOS compatible operating system, it SHOULD work - if it doesn't, then it is a bug.
ST-DOS is not meant to be a clone of MS-DOS. Instead it is meant to be (mostly) compatible with the documented programming interface, so that it satisfies most already existing DOS programs and makes it easy to write new programs in such way that it works on both ST-DOS and FreeDOS. Many old CP/M syscalls are not supported, but I'll probably write a "compatibility TSR" that implements some syscalls that are currently not implemented in the kernel.
The main purpose of ST-DOS is to be as efficient 16-bit disk operating system as possible, and a software layer that provides basic I/O syscalls for accessing file systems and storage devices in Unix-like manner. If you need an MS-DOS clone, then you should just use FreeDOS. |
tom

Germany (West), 23.03.2024, 12:20
@ samwdpckr
|
I made my own DOS implementation |
>
> The program can change the memory allocation strategy and then load another
> instance of itself to the memory using normal DOS syscalls.
That's pretty much nonsense.
> For example, the program could free its environment segment and file
> handles, allocate memory for the resident part, copy its own PSP to the
> resident part (with memcpy to make sure that the parent PSP does not
> change), change the current PSP to the new PSP, jump to the new PSP, free
> the old PSP and then exit via int21,ah=31.
I prefer my method. |
ecm

Düsseldorf, Germany, 23.03.2024, 09:58
@ samwdpckr
|
I made my own DOS implementation |
> If that is not possible, there are other ways to stay resident in memory so
> that the part of the program that stays resident is not the memory block
> with the original PSP, but they are all either relatively difficult to do
> or need modifying the internal structures of the kernel.
>
> For example, the program could free its environment segment and file
> handles, allocate memory for the resident part, copy its own PSP to the
> resident part (with memcpy to make sure that the parent PSP does not
> change), change the current PSP to the new PSP, jump to the new PSP, free
> the old PSP and then exit via int21,ah=31.
Service 31h does have the problem that you need to keep a part of a/the PSP resident, at least 40h bytes though I'd go with 60h bytes. And as you mentioned a program using service 31h should free its process file handles unless it specifically wants to keep them around for later use. (Most programs using service 31h get this wrong.)
As also described in the link, my TSRs will relocate their initial process to the top of the LMA. This is done unconditionally, but the reason is to avoid fragmentation when installing without a suitable UMB being available. The process relocation can be disabled using a /J+P switch for insufficiently compatible systems. The final resident allocation is also made by allocating a new data block (with appropriate strategy and UMB link) and hacking its MCB, just like mkeyb. --- l |
samwdpckr
23.03.2024, 08:10
@ tom
|
I made my own DOS implementation |
I prefer keeping the struct members word-aligned.
Modifying a memory allocation now also changes its owner in the new version.
> What other way would you propose?
Probably the best way would be to change the memory allocation strategy _before_ the TSR program is loaded from the disk, or alternatively make sure that the TSR program is loaded to the lower addresses, before other programs like the command prompt are loaded. That way the memory is not fragmented. This shows how well it works:
![[image]](img/uploaded/image69.jpg)
The program can change the memory allocation strategy and then load another instance of itself to the memory using normal DOS syscalls.
If that is not possible, there are other ways to stay resident in memory so that the part of the program that stays resident is not the memory block with the original PSP, but they are all either relatively difficult to do or need modifying the internal structures of the kernel.
For example, the program could free its environment segment and file handles, allocate memory for the resident part, copy its own PSP to the resident part (with memcpy to make sure that the parent PSP does not change), change the current PSP to the new PSP, jump to the new PSP, free the old PSP and then exit via int21,ah=31. |
tom

Germany (West), 22.03.2024, 17:32 (edited by tom, 23.03.2024, 07:28)
@ samwdpckr
|
I made my own DOS implementation |
> > Yes, absolutely.
> > It allows to allocate some memory (and copy resident code to it) which
> will
> >
> > remain resident when the program calls exit().
> > There are other ways to stay TSR; but this has a couple of advantages.
>
> That does not require modifying the struct manually.
What other way would you propose?
>
> It is also not documented that the owner of a memory block changes when its
> size is changed.
I know. But MSDOS does exactly this.
> But I can easily change the behaviour of the kernel so
> that it works like that. Currently it does not change the owner.
>
> The way the memory allocation structs are done in MS-DOS is inefficient and
> makes it slow to traverse the memory allocations backwards, especially when
> there is a large number of allocated memory blocks.
Sure.
OTOH, you could place Type ('M' or 'Z'); owner and size in The proper location to solve the *this* problem. |
samwdpckr
22.03.2024, 16:21 (edited by samwdpckr, 22.03.2024, 16:53)
@ tom
|
I made my own DOS implementation |
> Yes, absolutely.
> It allows to allocate some memory (and copy resident code to it) which will
>
> remain resident when the program calls exit().
> There are other ways to stay TSR; but this has a couple of advantages.
That does not require modifying the struct manually.
It is also not documented that the owner of a memory block changes when its size is changed. But I can easily change the behaviour of the kernel so that it works like that. Currently it does not change the owner.
The way the memory allocation structs are done in MS-DOS is inefficient and makes it slow to traverse the memory allocations backwards, especially when there is a large number of allocated memory blocks. |
tom

Germany (West), 22.03.2024, 14:12 (edited by tom, 23.03.2024, 07:32)
@ samwdpckr
|
I made my own DOS implementation |
> Is there any good reason for the user program to modify that struct? Why
> would it want to make it "self-referencing"?
Yes, absolutely.
It allows to allocate some memory (and copy resident code to it) which will
remain resident when the program calls exit().
There are other ways to stay TSR; but this has a couple of advantages.
> Those memory control blocks are not even identical between different
> versions of MS-DOS.
if you allow that later versions added a char name[8]; field, they are 100% identical. since 31 41 years. Since MSDOS 2.0. Across all DOS clones.
> If you modify them, unpredictable things will happen.
Nope. MKEYB demonstrates that it works very predictable. |
samwdpckr
22.03.2024, 13:14 (edited by samwdpckr, 22.03.2024, 13:34)
@ tom
|
I made my own DOS implementation |
Is there any good reason for the user program to modify that struct? Why would it want to make it "self-referencing"?
Those memory control blocks are not even identical between different versions of MS-DOS. If you modify them, unpredictable things will happen. |
tom

Germany (West), 22.03.2024, 11:22
@ samwdpckr
|
I made my own DOS implementation |
as a sidenote:
There is an undocumented undocumented feature of MSDOS that MSNET uses to make some MCB selfreferening.
oldPSP = getCurrentPSP();
setCurrentPSP(mcb);
dosrealloc(mcb, mcb.currentsize); // this sets the owner of this mcb to PSP
setCurrentPSP(oldPSP);
unfortunately, this doesn't work with ST-DOS either |
tom

Germany (West), 22.03.2024, 10:58
@ samwdpckr
|
I made my own DOS implementation |
> the error is on line 92.
*(short far*)MK_FP(allocSeg-1, 1) = allocSeg; /* makes it selfreferencing */
_fmemcpy(MK_FP(allocSeg-1, 8), MY_MEMORY_SIGNATURE, 8); /* mark our name */
> It seems to be a different version of the program, but it also
> modifies the internal memory allocation structure of DOS.
the MCB structure (while never documented by MS) has been documented since MSDOS 2.0. And been implemented this way by any selfrespecting DOS clone.
this is indeed problematic if you decide to run your own structure
struct mcb
{
unsigned next_mcb_seg;
unsigned prev_mcb_seg;
unsigned paragraph_count;
unsigned owner_psp;
// 0: normal memory block
// 1: dta struct
// 2: disk cache
// 3: filesystem
// 4: handle
// 5: system
unsigned char type;
unsigned char __far *usercache_freedptr;
};
also, all MEM like memory diagnostic tools will fail on your "operating system that is mostly compatible with the documented DOS API."
Time to move on... |
ecm

Düsseldorf, Germany, 22.03.2024, 07:31
@ samwdpckr
|
I made my own DOS implementation |
> > Actually they are identical among compatible DOS systems. The system
> call
> > services with ax = 5800h to 5803h on int 21h are not "internal" to DOS.
> No, they are not identical.
>
> In that Github page (which does not even work on Seamonkey, the page is
> just missing elements and the console contains no errors) the error is on
> line 92. It seems to be a different version of the program, but it also
> modifies the internal memory allocation structure of DOS.
Okay well whatever revision of the file you have, in the repo that's https://github.com/davidebreso/mkeyb/blob/518d24d578dcb094b7f74800cd982bb4e4b7178b/mkeyb.c#L92
And yes, this does modify a DOS internal structure - it assumes the MCB format and how to make an MCB self-owned. This is not the same for all DOS systems but MS-DOS compatibles like (E)DR-DOS and FreeDOS do often use the same structures. My TSRs also assume that the MCB structure is compatible. --- l |
samwdpckr
22.03.2024, 02:06
@ ecm
|
I made my own DOS implementation |
> Actually they are identical among compatible DOS systems. The system call
> services with ax = 5800h to 5803h on int 21h are not "internal" to DOS.
No, they are not identical.
In that Github page (which does not even work on Seamonkey, the page is just missing elements and the console contains no errors) the error is on line 92. It seems to be a different version of the program, but it also modifies the internal memory allocation structure of DOS. |
ecm

Düsseldorf, Germany, 22.03.2024, 00:21
@ samwdpckr
|
I made my own DOS implementation |
> > I'm not certain about *most* KEYB implementations, but I am certain that
> > MKEYB does not rely on any MS-DOS feature, but interacts entirely with
> the
> > BIOS.
> > and I think KEYB behaves (in this respect) identical.
>
> MKEYB.C, line 76.
That's https://github.com/davidebreso/mkeyb/blob/518d24d578dcb094b7f74800cd982bb4e4b7178b/mkeyb.c#L76
> It changes DOS's internal undocumented memory allocation struct. That is
> why it crashes. It assumes that the underlying operating system is MS-DOS.
>
> Whoever wrote that should go fix their program. Those memory allocation
> structs are not identical between different DOS implementations.
Actually they are identical among compatible DOS systems. The system call services with ax = 5800h to 5803h on int 21h are not "internal" to DOS. --- l |
samwdpckr
21.03.2024, 22:21
@ tom
|
I made my own DOS implementation |
> I'm not certain about *most* KEYB implementations, but I am certain that
> MKEYB does not rely on any MS-DOS feature, but interacts entirely with the
> BIOS.
> and I think KEYB behaves (in this respect) identical.
MKEYB.C, line 76.
It changes DOS's internal undocumented memory allocation struct. That is why it crashes. It assumes that the underlying operating system is MS-DOS.
Whoever wrote that should go fix their program. Those memory allocation structs are not identical between different DOS implementations. |
fritz.mueller

Munich, Germany, 21.03.2024, 22:14
@ samwdpckr
|
I made my own DOS implementation |
> Then I need to investigate why it crashes.
![[image]](img/uploaded/image441.png)
![[image]](img/uploaded/image442.png) |
samwdpckr
21.03.2024, 19:56
@ tom
|
I made my own DOS implementation |
> I'm not certain about *most* KEYB implementations, but I am certain that
> MKEYB does not rely on any MS-DOS feature, but interacts entirely with the
> BIOS.
> and I think KEYB behaves (in this respect) identical.
Then I need to investigate why it crashes. |
tom

Germany (West), 21.03.2024, 19:32
@ samwdpckr
|
I made my own DOS implementation |
> > I tried german keyboards (mkeyb gr and keyb gr,850,C:\dos\keyboard.sys -
> > file was there) - both did
> > not work, mkeyb seems to freeze)
> Most KEYB implementations that come with FreeDOS are dependent of some
> undocumented features of MS-DOS, and they will not work. ST-DOS's KEYB
> implementation is just a simple TSR program that replaces the default BIOS
> keyboard interrupt handler.
I'm not certain about *most* KEYB implementations, but I am certain that MKEYB does not rely on any MS-DOS feature, but interacts entirely with the BIOS.
and I think KEYB behaves (in this respect) identical. |
samwdpckr
21.03.2024, 18:06
@ fritz.mueller
|
I made my own DOS implementation |
> This makes it more complex. I have an old laptop where I need an external
> USB diskette drive.
> And in virtual machines removing the whole diskette controller is not
> unusual.
> In this case the autoexec.bat (maybe others too) has several "C:\" inside
> that have to be modified via notepad.
I modified the command prompt. Now it creates an environment variable %COMDRV% when it starts. That environment variable is the drive letter of the command prompt. It can be used to make batch files that are independent from the drive letter of the current boot drive.
> For reasons that I do not know notepad.app (started from GUI - filemanager
> - directory: \leetos\ - filenames: notepad.app) starts the notepad window
> and exits at once (maybe working directory or something else is wrong).
Notepad needs a file to open. Otherwise it just exits. The file manager automatically opens files to Notepad when you click the "View" button.
> Several message boxes do not have an underlined letter key, e.g. OK, help,
> YES/NO etc. which makes it harder to
> work without mouse.
OK/Yes works by pressing Enter. No/Cancel works by pressing Escape. It is mentioned in the documentation.
> I tried german keyboards (mkeyb gr and keyb gr,850,C:\dos\keyboard.sys -
> file was there) - both did
> not work, mkeyb seems to freeze)
Most KEYB implementations that come with FreeDOS are dependent of some undocumented features of MS-DOS, and they will not work. ST-DOS's KEYB implementation is just a simple TSR program that replaces the default BIOS keyboard interrupt handler.
> One more strange behaviour: As I do not know the finnish keyboard, I typed
> through my keyboard layout
> (asdfghjklöä etc.) and after in about 25 keys there is a strange
> behaviour that I have not seen on other
> OSes till now: Especially after ' the "go back <--" button doesnt work and
> sometimes it is no longer possible
> to add other characters too. I am sure you can tell me a reason for this.
They are called "dead keys". I think the German keyboard layout does not have them.
The KEYMAPS.TXT file in the root of the install disk contains instructions how to create your own keyboard layouts.
> A "?" in command line (C:\?) that shows the commands built in command.com
> would be helpful too, see:
> https://www.bootablecd.de/FreeDOS-Internet-version/help110-no-fish/en/hhstndrd/command/question.htm
I will write a documentation for the command prompt. Currently it changes so much that I will not do it yet.
Now the SETUP program has a better support for installing from a USB storage stick. The target drive can also be changed, but the drive that it detects by default should usually be correct. |
fritz.mueller

Munich, Germany, 20.03.2024, 15:56
@ samwdpckr
|
I made my own DOS implementation |
Sorry, its me again.
Thank you for your new OS, but I think I will stop with tests now and maybe continue in a few months.
At the moment I think it is too early that users test it.
>On the last two pictures the operating system did not think that it was booted from a diskette. As I
>wrote earlier, it always starts counting drive letters from A:, so if you remove all diskette drives,
>the first hard drive becomes the A: drive. It works just as intended.
This makes it more complex. I have an old laptop where I need an external USB diskette drive.
And in virtual machines removing the whole diskette controller is not unusual.
In this case the autoexec.bat (maybe others too) has several "C:\" inside that have to be modified via notepad.
For reasons that I do not know notepad.app (started from GUI - filemanager - directory: \leetos\ - filenames: notepad.app) starts the notepad window and exits at once (maybe working directory or something else is wrong).
> You can get the mouse working by installing a mouse driver. Cutemouse works. Also you can try the
> KEYMOUSE.COM keyboard mouse emulator.
Cutemouse worked. But I was unable to add it in autoexec.bat because notepad.app did not work for me (see above).
> You don't have to press ALT when using the shortcut keys. Just press the underlined letter key.
Several message boxes do not have an underlined letter key, e.g. OK, help, YES/NO etc. which makes it harder to
work without mouse.
A doskey would be helpful to repeat the last commands (e.g. to fix a typo).
I tried german keyboards (mkeyb gr and keyb gr,850,C:\dos\keyboard.sys - file was there) - both did
not work, mkeyb seems to freeze)
One more strange behaviour: As I do not know the finnish keyboard, I typed through my keyboard layout
(asdfghjklöä etc.) and after in about 25 keys there is a strange behaviour that I have not seen on other
OSes till now: Especially after ' the "go back <--" button doesnt work and sometimes it is no longer possible
to add other characters too. I am sure you can tell me a reason for this.
Several tools got a freeze, I do not remember them all. One of them was mkeyb.
A "?" in command line (C:\?) that shows the commands built in command.com would be helpful too, see:
https://www.bootablecd.de/FreeDOS-Internet-version/help110-no-fish/en/hhstndrd/command/question.htm
Setting an alias in autoexec.bat seems not to be possible (I tried "alias install=a:\leetos\install.com" to avoid not working installations of leetos)
I tried to create a new shortcut for notepad - looks simple, but I did not get it with the shortcut editor. Could you add the correct syntax in the window where you have to enter the values (e.g. notepad or notepad.app, working directory: C:\leetos or whatever, icon file: xy.ico with path or no path, can an icon that is already in use be used a second time, how can I create a new icon etc). This are typical standard user questions.
Sorry, but I hope you can understand me now. Maybe this helps you to add some positions at the FAQs,
e.g. why does format not work although setup asks for it, why do I use a non standard system on the OS (even X-Ways Forensics does not recognize it, but IMDISK can mount it), why does the HD use A: when diskette drive is removed etc.
Thanks.
Fritz |
samwdpckr
18.03.2024, 22:22
@ fritz.mueller
|
I made my own DOS implementation |
Thank you for your efforts in documenting the problems so thoroughly.
The installer of the graphical user interface cannot find the files, because you ran it from the root directory. That's why the "Getting started" instructions also say to run it from the LEETOS\ directory.
The TEXTEDIT program may be hard to use. I recommend using the NOTEPAD application in the graphical user interface.
On the last two pictures the operating system did not think that it was booted from a diskette. As I wrote earlier, it always starts counting drive letters from A:, so if you remove all diskette drives, the first hard drive becomes the A: drive. It works just as intended.
The colors of the graphical system can be changed by running the CONFIG.COM program from the LEETOS\ directory. You can also rename the SETUP.INI file so that it does not find it, which causes it to use CGA high-res display mode with only black-and-white colors. I understand that most modern LCD displays have terrible contrast ratios. On my display your screenshots look just fine.
You can get the mouse working by installing a mouse driver. Cutemouse works. Also you can try the KEYMOUSE.COM keyboard mouse emulator.
You don't have to press ALT when using the shortcut keys. Just press the underlined letter key. |
fritz.mueller

Munich, Germany, 18.03.2024, 13:25
@ samwdpckr
|
I made my own DOS implementation |
Hi,
first of all I wanted to inform you that my posts were not meant to critizise you. This was simply a first test. I like testing new programs. There are often problems if I test a program / OS for the first time.
I just ran a second test with your latest version now. As I may have overlooked your email address on your website, I uploaded 35 zipped pictures on my website:
www.bootablecd.de/ST-DOS.7z
I hope you can see that ST-DOS sometimes behaves a little strange, e.g. it names the HD with 2 GB size "A" under special circumstances. The setup program says that it is possible to run format before installation. There is even a question if it was already formatted or not.
The most less helpful thing for me was the "GUI" (sorry for Win3).
I used in about the same background colour with the FreeDOS fish for my version 1.1.0 of the english online help and got a VERY LOUD cry: "With this colour the text is unreadable." I still cannot reproduce it on my website, but, sorry for that, with your GUI it is reproducable. For test purposes it would be very helpful to change the background from your "blue" (maybe you call it another colour) to white or something else. The marker for the actual "mouse position" (Meaning: which symbol is marked at the moment?) is invisible for me around most symbols, see pictures.
"vi": Maybe I used the wrong program.
At one picture I added the text Alt-c etc. Sorry, this was wrong.
Hope the pictures help you to understand what I talk about.
Fritz |
samwdpckr
18.03.2024, 01:52
@ samwdpckr
|
I made my own DOS implementation |
I added an RSS stream to the webpage. Also implemented DOS syscall 0x26 to the kernel. |