RayeR's homepage/ROMOS Project (english)
The ROMOS is a stand-alone x86 code allows you to load and run your own binary code or 3rd-party code. ROMOS rely on BIOS functions only so it can be executed directly without any operating system. The main purpose of ROMOS is to be placed in a ROM, from where it can load/run other software (e.g. bootmanager, HW diagnostics, special controlling software...) during POST (Power-On Self Test) while your PC is booting up. It can also load DOS-based operating systems (may be other OSes) such as
stored in ROM together with ROMOS. This mean that any floppy/harddisk/CD-ROM drive is not needed. It may be very useful in various embedded diskless systems. Or simply as reserve OS for rescue use. Other applications are on you.
The ROMOS can be placed in two ways. One way is to insert it as ISA ROM module into your system BIOS located in FlashROM memory chip on your motherboard. In this case any additional hardware is not needed. But there's limitation due to free space in FlashROM. Other way is to burn ROMOS in separated FlashROM / EPROM and place it on special ISA card. But cheaper solution is to use any of existing network adapter with a socket for BootROM. Then you may need to enable BootROM by vendor specific network adapter configuration utility - it will store your setting to small onboard EEPROM together with your MAC and other settings.
Here's system requirements:
-PC with BIOS stored in FlashROM (EPROM cannot be [easy] modified)
-running MS-DOS 7.0+ (included in Win9X) or FreeDOS operating system
-enough free space in FlashROM (min. 2 kB for ROMOS itself + your code)
(sample ROMOS build with FreeDOS requires 64 kB)
how to make more space in FlashROM see below.
-Award BIOS 4.51/6.00 (I did't tried it with AMI BIOS but newer versions don't support ISA ROM modules)
-your motherboard BIOS file (can be dumped with awdflash.exe)
-cbrom.exe and awdflash.exe programs to insert ROMOS and dump/burn your BIOS.
If you go 2nd way you'll only need:
-ISA card which supports up to 64kB ROM chips
-FlashROM or EPROM burner
If you want to make own ROMOS build you'll additionally need:
-1,44MB floppy disk drive and one diskette (for modifying virtual ROM disk image)
-romchk.exe and zalign.exe for making ROM image
-fdimg.exe for manipulating with disk image
(all needed software tools are included in ZIP file package)
Before installing ROMOS you will need to get your current BIOS image. You can download it from your hardware vendor or dump it via
awdflash.exe /pn /sy bios.bin
in ROMOS directory (where you extracted
) and also make a backup copy. If you want to modify content of virtual ROM disk insert 1,44MB floppy diskette without bad sectors in drive A: (for B: update paths in batch files) and run
(from DOS not Windows). FDIMG utility will transfer
to your floppy. Due to floppy specific format (63 kB with only one FAT) MS-DOS 7.0+ or FreeDOS is required to read/write this disk. Then you can add/delete files, transfer OS via sys command or everything else like with normal floppy. Also you can try to boot from the floppy to test it. When the floppy will be successfully tested you can take image file running
Then you may edit
source. There are few important options:
uncomment the %define MAKE_PCI_MODULE to insert additional PCIR and $PnP header to make PCI compatible ROM module. Some values in these headers have to be adjusted with
to allow hook
defines ROMOS module total size in kB (with included
), minimum size is 2 kB.
defines what drive will ROMOS emulate. If drive exists it will be overrided. If you have one FDD you should choose B: or A: for none.
define floppy image format. If you use format same as original
you needn't to modify it.
defines the offset of bootdrive byte in bootsector. Don't care if you use DOS - this byte is automatically modified according to ROMDISK_DRIVE defined in line 14.
define address where will be bootsector copied before running it. BIOS do this normally at
defines duration of displaying ROMOS boot message in 55ms timer ticks.
defines a hotkey to activate ROMOS (ScrollLock/NumLock/CapsLock).
to compile it. It will produce ISA ROM module
, aligned by 512B and patched checksum. This image may be directly burned to EPROM for your ISA board or included to your system BIOS. If you copied your bios image as
to ROMOS directory just run
and CBROM will place it in as ISA ROM module at
h (otherwise modify batch file for proper address). See CBROM screen output if ROMOS module was successfully inserted. If you get 'not enough space' message see
technical details section
how to make some space by removing unnecessary BIOS modules.
Finally flash your modified
and reboot your machine. If you use ROMOS PCI as replacement of onboard network adapter BOOTROM don't forget to enable BOOTROM option in SETUP and if there is a choice to allow hook
h enable it. After restart and BIOS POST done you should see white 'Press [ScrollLock] to boot ROMOS !' message at the top of your screen. It will be displayed for 1,6 s. If you do nothing BIOS will continue with booting from your drives and will free ROM space (which will be then available for UMB or EMS frame, etc.). If you pressed ScrollLock (you may press it before message displays) ROMOS will print some debug messages, install own
h handler (which allows access to virtual ROM disk), copy bootsector from virtual ROM disk image at specified address and gives control to it. Bootsector then load operating system stored in virtual ROM disk image. Then you will have read-only access to emulated drive assigned with letter as you specified ROMDISK_DRIVE variable.
Here you can download last ROMOS version. It is a free software, you can use and modify it as you want but please don't remove my copyright. Any software based on ROMOS should be also distributed free with included sources. If you will make some serious modification or find a bug please let me know.
romos.asm [33 kB] - ROMOS 1.05 ISA/PCI assembler source code, last updated 13.5.2012
romos.101 [28 kB] - ROMOS 1.01 assembler source code, older version
romos.094 [14 kB] - ROMOS 0.94 assembler source code, older version
romos.001 [7 kB] - ROMOS 0.01 assembler source code, even older version ;-)
romos.bin [64 kB], romospci.bin [64 kB] - ROMOS 1.05 ISA and PCI compiled module (to be placed at D000:0000h, emulating drive B:) including FreeDOS kernel 2035, Micro Manager 1.0 eng. (now about 2 kB smaller after recompression), Dynaload for dynamic drivers loading, SeeMem for exploring memory and few other small tools. The PCI variant has to be configured with bromcfg.exe (part of the romos.zip package) before using it.
romos16k.bin [16 kB] - ROMOS 1.02 PCI compiled module (to be placed at D000 - DC00:0000h, configured for PCI network adapter Realtek 8029, emulating drive A:) including DF-DOS 0.04b - www.dftech.cwc.net/osdev, memory viewer and some small demos. Here is a video showing DF-DOS running some old games.
romos.zip [835 kB] - ROMOS 1.05 developer's package with all essential tools including NASM.
rjdos.zip [12 kB] - RJDOS 0.01a by Richard L. James is a small replacement of command.com (9746 bytes) that can be placed in romdisk.
If you want to see how it works just now click below to see the animation showing ROMOS booting on my PC. It was reanimated by Borg Number One from my screenshots. It should be safe for your computer ;-)
Version 0.95 contains major changes. The main ROMOS code is now as
h handler. In 1st phase during POST, when BIOS is doing
, it only displays choice if you want to run ROMOS. If positive answer is got then ROMOS install new
h handler and redirect
h vector to the main code. Then ROMOS gives control back to BIOS which correctly finish POST. After full initialization BIOS call
h and ROMOS will be run again (if
h vector was redirected) and will load operating system from virtual ROM disk.
4.3.2004 was updated FreeDOS kernel to version 2033 (included in romos.bin and romos.zip), which was compiled by Luchezar Georgiev using BC for 386. This made kernel little bit smaller - 42518 B, so you have about 1 kB more space for your files in ROM disk image.
22.9.2004 New version 0.97 contains a lot of changes and code optimalizations. The most important improvement is change of storage of few needed permanent data from ROMOS segment to unused place in interrupt vector table. This allows ROMOS to run from true read-only memory (such as EPROM on ISA board without shadowing) and under BOCHS PC emulator where ROMOS can be comfortable and without risks tuned. Now ROMOS is not fixed to given ROM segment but practically we have only few choices in PC: D000h or E000h (only for older PCs). Also structure of INT 13h routine was changed for easier adding of new subfunctions. Subfunction 03 (write sector) was added and return proper errorcode. For faster orientation in code I placed a brief state diagram at end of source file. Later I updated kernel to version 2035 in virtual ROM disk image.
23.10.2004 Version 1.00 contains further code optimalisations and INT 13h handler was extended to support function 15h. Then I dealed with FreeDOS kernel 2035 sources and compilation. Due to removing some unnecessary things (fdconfig.sys - only config.sys, break, numlock, echo, switches, country, menus), optimalization of compiler and packer I reached the size only 39390 B for kernel with FAT32 support. So then I can fit it together with USB stack driver for mass-storage class devices (flashdisk, etc.), from where can I load other files. It would be possible to load Linux from flashdisk via loadlin.exen - but I cannot test it. ROMDISK image with USB driver is stored in complette zip package as romdusb.img together with standard romdisk.img.
18.3.2006 New version 1.02 brings support of Plug&Play PCI ROM. Most of new motherboards without ISA slots lost support of ISA ROM modules and this was the reason why ROMOS didn't work there. Now it's possible to compile ROMOS as PCI ROM module (PCI ROM also can be used as ISA ROM but not vice versa). PCI ROM headers contains specific vendor ID, device ID and device class which must match some real PCI device present in the system (otherwise ROM will not run). Some BIOSes require that assigned PCI device have a real ROM or socket for ROM (e.g. network adapter). In my system it works only assigned to network adapter (I also tried IDs of PIIX4, PCI to PCI bridge, USB controller... - without success). For this setting you can use bromcfg.exe utility from Arne which is included in zip package.
15.7.2007 There are only minor changes in version 1.03. Now you can use definition HOOK_INT19H to turn on/off INT 19h hook. When it's commented out then ROMOS will start immediatelly after query and hit activation key (keep in mind that POST may not be finished yet but this feature might be usefull). Also some programs on virtual ROMDISK was replaced. I successfully tested ROMOS on AMI BIOS of Asus P5LD2 motherboard and I added essential tool AMI MMTool 3.12 in zip package for placing ROMOS module into BIOS image.
22.6.2009 Version 1.04 contains only minor improvement in source - an optimization of routine for printing hexadecimal numbers and related routines. This saved 17 B of machine code.
13.5.2012 Version 1.05 contains further code optimizations that saved 16 B of machine code. I also changed the method of calling chained old ISR of INT 13h. Instead of modified FAR JMP I call it via another INT. This saved one entry in IVT for INT 84h where I placed the FAR JMP opcode directly before INT 85h vector. So now only the INT 85h IVT entry is used to store old INT 13h vector (this entry number can be easily cahnged in source code).
Technical details (BIOS hacking, ROM modules, ASM...)
I'll expect that you have some knowledge about PC hardware, BIOS (I will implicitly talking about AWARD BIOS), DOS and assembly language. If you're windows clicking dummie you should go to play with Mr. Paperclip von da M$ Mord... :)
O.K. let's sum some facts about the
BIOS (Basic Input Output System)
. This is the basic software (or we should say firmware) stored in nonvolatile memory on your motherboard providing basic functions such as disk/screen/keyboard/ports/timer/... access. Operating system may or may not use this functions. DOS based systems always use it. BIOS take control every time you turn-on (or cold reboot) your PC at it's entrypoint address
h. It makes
POST (Power-On Self Test)
- various hardware initializations and tests (initialization chipset registers, CPU speed (PLL), testing RAM, seeking for IDE drives, seeking for other ROMs and lot of other things). BIOS also include
program allows you to set various HW options and store them to
memory backuped with a battery.
In the past the BIOS was stored in one or two
chips. Usually one 27C512 (64 kB) in 486 systems or two 27C256 (32 kB - odd and even part [due to 16bit addressing]) in 286 and 386 systems EPROM chips was used. Note that EPROM chips can be erased only by UV light irradiation - high energy photons (for this purpose has chip a silica glass window sealed with some label, there is also cheap EPROM version without glass window, yes that in epoxide package, which can be erased only by X-ray radiation but I don't recommend you to do this at home :) so BIOS upgrade was very difficult if you don't have an EPROM eraser and burner. It usually contains raw binary BIOS code which resides at physical address range
F0000 - FFFFF
Pentium (also some modern 486 and 5x86) systems brought new important feature - BIOS has been moved to
. It allows user to electrically erase and reprogram the BIOS code inside motherboard without removing the chip. First FlashROM chips, such as 28F001, required extra 12 V for erasing and programming. Newer chips, such as 29F020, requires only single 5V supply. Now there's are also LV versions for 3,3 V usually used on graphics cards. Very old motherboards support only 12V FlashROM chips, newer has jumper for selecting 5 / 12 V and the newest supports only 5V or 3,3V chips. FlashROM chip capacity has been growing from 128 kB -> 256 kB -> 512 kB... On some newest motherboards PLCC SMD package is used instead classic DIL package. In extreme cases the BIOS chip is soldered directly on PCB so you can't simply remove it and reprogram in a programmer if something screws up. I think this is a bad trend. Yes, it's cheaper for manufacturers and enable some HW rescue service firms to get fucking easy money. To prevent unwanted BIOS modification there's usually a 'programming enable' or 'write protect' jumper close to FlashROM chip so enable it now.
Also the BIOS code structure has changed. Instead raw binary form it is divided in two parts - 8 kB uncompressed
compressed module(s). Bootblock takes control first and check'n'decompress the LHA packed modules at specified RAM addresses and then if everything is OK gives control to main module. If some module is corrupted and checksum doesn't match bootblock will beep to warn you. But don't panic, if bootblock is working it allows you to reflash BIOS using DOS bootable diskette with working BIOS file, flashing tool and properly made
file. You usually will see nothing on the screen because bootblock don't initialize PCI and AGP then watch FDD LED activity. If you use an old ISA VGA you should see BIOS messages normally. Just insert the diskette and reboot. Bootblock boots the DOS from the diskette and
to reflash your bios file and you should be saved :).
If all else fails you will need to pull out your FlashROM chip from motherboard and program it in a FlashROM programmer. Or you can do the
if you have your backup FlashROM chip. I also using this method because chip programmers are expansive. But there is a major or minor risk that you blow your chip or motherboard. It depends on how strong do you believe Murphy's laws ;-). I have made about 50 hotflashes and blow one FlashROM chip. It is a 98% effectivity - great result, isn't it? But new chip costs me about 200CZK. The hotflash is simple in the fact. To make a backup FlashROM first you will need an empty FlashROM chip same capacity as your current chip. It may be from other manufacturer. Turn off your PC and pull out the chip from the socket and reinsert it softly. Remove unnecessary cards and cables to make easy access to the chip. Turn-on your PC and boot up plain DOS. Now gently pull out the chip (if you reinserted it before, as I suggested, you will not need brute force now) and insert empty one. System will not crash because BIOS code is shadowed in RAM. Flash your working BIOS file into empty chip and reboot the computer. Now you have a backup chip. If something heavily fucks up you simply swap the chips and do this again.
Now something about
. You can list/add/remove them by
program. You can also extract all modules in one time with
. For AMI BIOSes there are similar tools called
for DOS & Windows and
for Windows. Here's listing of my BIOS file:
No. Item-Name Original-Size Compressed-Size Original-File-Name
0. System BIOS 20000h(128.00K) 14E93h(83.64K) original.tmp
1. XGROUP CODE 082F0h(32.73K) 05877h(22.12K) awardext.rom
2. ACPI table 02214h(8.52K) 00E51h(3.58K) ACPITBL.BIN
3. VRS ROM 02280h(8.62K) 014BBh(5.18K) ANTI_VIR.BIN
4. EPA LOGO 0279Ch(9.90K) 0132Ah(4.79K) SKULL4.EPA
5. CPU micro code 0A800h(42.00K) 060D8h(24.21K) cpucode.bin
6. ISA ROM[A] 10000h(64.00K) 0F437h(61.05K) romos.bin
Total compress code space = 34E93h(211.64K)
Total compressed code size = 3324Fh(204.58K)
Remain compress code space = 01C44h(7.07K)
** Micro Code Information **
Update ID CPUID | Update ID CPUID | Update ID CPUID | Update ID CPUID
SLOT1 13 0630 | SLOT1 20 0632 | SLOT1 36 0633 | SLOT1 37 0634
SLOT1 40 0650 | SLOT1 40 0651 | MOBILE 2D 0652 | SLOT1 10 0653
SLOT1 0A 0660 | PPGA 03 0665 | MOBILE 07 0670 | SLOT1 03 0671
SLOT1 10 0672 | SLOT1 0E 0673 | SLOT1 14 0680 | PPGA 14 0681
PPGA 14 0683 | PPGA 08 0686 | PPGA 01 068A | SLOT1 07 06B0
SLOT1 1D 06B1 |
The main module is
(at line 0.). It contains resident code, SETUP program and POST routines. It's always 128 kB long. The first 64 kB of
is loaded temporarily at
E000:0000 - E000:FFFF
h. After POST this memory range is freed. The second 64 kB of
is permanently loaded at
F000:0000 - F000:FFFF
h and become write protected after POST. CBROM doesn't allow you to extract/insert
module. It can be done with
(extraction only) or
is not easy because it is protected by two checksums but MODBIN can calculate them. Also inserting modified file back into BIOS file is not easy and I don't have reliable way how to do it. But I succeeded this job using
in my case.
As BIOS becoming more complex and larger all the code doesn't fit into
so it has been splited to
modules. My BIOS is quite old so it contains only XGROUP code listed as
. This module is usually decompressed at address
h. This code may be easily modified but after inserting your modified module remember to load and update it with MODBIN to update checksums.
Next we can see
CPU micro code
. It's an update of microcode that can modify behavior (
) of some complex CPU instruction that consists of many microinstructions e.g.
. Simple instructions are probably hardwired for speed reason.
consists of many blocks, each for a specific CPUID that MB supports that are min. 2 kB long with 1 kB granularity, simply glued together (except ASUS BIOSes). Every microcode block have a header:
dd 000000001h ; Header Version
dd 000000013h ; BIOS Update ID
dd 008271996h ; Date (BCD)
dd 000000630h ; CPUID of target processor
dd 0f316fc3bh ; Checksum (zero-align to DWord sum)
dd 000000001h ; Loader Version
dd 000000010h ; CPU Flags
dd 000000000h ; Size of pure microcode data (for >2048 B only)
dd 000000000h ; Total size (for >2048 B only)
dd 000000000h ; reserved
dd 000000000h ; reserved
dd 000000000h ; reserved
Then follows SHA1/SHA2 encrypted microcode data signed by RSA 2048. Of course there was many attempts to hack it but nobody was successful yet. Intel keeps this informations top secret.
you can read an interesting summary of microcode analysis. It was mentioned that there exists 2 various microcode formats for older and newer CPUs (changed in new Core 2 era).
You need a microcode block for your currently installed CPUID only. Also it is possible to remove it completely because modern operating systems like Windows/Linux loads necessary microcode update from a file during boot. UPDATE: it's no longer possible because a lot of modern CPUs have several bugs that prevent them normal boot without microcode update. So here's a way how to make some free space in FlashROM. After inserting modified
via CBROM you don't need to update any checksums. I wrote two tools to manipulate with microcode files.
CPU Microcode Loader
report used microcode ID and allows you to load microcode block file into CPU (this take effect until you turn-off or cold reboot your PC). Microcode is uploaded to CPU by following sequence: linear address to microcode data loaded from a file (including header) is stored to
h constant is stored to
constant is stored to
and finally a privileged instruction
is executed. CPU checks the microcode data and if it finds any mismatch it will reject the update. Some BIOSes may support extended services of
h) which allows you to write/read microcode data directly to/from FlashROM. See more details in:
Pentium Pro Processor BIOS Writer’s Guide
. The second tool
Binary CPU Microcode file info
allows you to view microcode file information and split
file to particular files named by corresponding CPUID for each block.
will join your selected files to one which you can then use as new
module is here for
support. I don't have more information.
module is needed for BIOS antivirus feature which I have always disabled. I think that it can be removed if you don't use it.
is an Energy Star logo displayed in the right top corner of the screen during POST. In older BIOSes it has only 2 colors (EPA 1.0) in newer 16 colors (EPA 2.0 with "AWBM" signature at the beginning of file). You can replace it by your own logo. I wrote
BMP -> EPA convertor
based on knowledge which I got when hacking EPA 2.0 format (I didn't find any format description that time so I did it myself). In AMI BIOSes, we can meet e.g. on newer Asus P4/C2D motherboards, are used 16 color logos in intel GRFX format. I wrote also my own
BMP -> GRFX convertor
. You can download it here
module is a fullscreen bitmap displayed during POST instead normal text output. It can be seen on some compaq, intel,... motherboards. You can free a lot of FlashROM space by removing it. There's also displayed small blue 'Award medal' logo in the left top corner. It is not stored is any extra module but probably in
but I don't know where.
There can be also other modules such as VGA videobios for integrated graphics adapters (you can use this feature when you bad flash your graphics card BIOS), network adapter bootrom, IDE/SCSI raid controller BIOS and more... I also found similar project called
ATA Security eXtension BIOS
, which extends main BIOS by harddisk security module. The most of modern IDE drives supports ATA commands for setting user and master password which can effectively secure the content of the drive. But BIOS programmers utilize this advanced features very rare yet (except notebooks).
If you want to execute your own code during POST you can make easily an ISA ROM module and insert it in your BIOS file. You have to choose address which will not collide with other ROM or system parts. Here you can see usual memory map of 1st megabyte in PC:
Here is usually free space at
D0000 - DFFFF
h (64 kB) which can be used for our own ISA ROM module. During POST the BIOS is doing a
- seeking for external adaptor's ROMs. ISA ROM must begin with first two bytes
h followed by 3dr byte telling
ROM size in 512B blocks
. But minimum ISA ROM module length is
. BIOS checks addresses with
increment so ROM address must be a multiple of
. ISA ROM module has checksum. If we sum up all bytes (including
header) into one byte variable (we don't care overflow) it must be
. If checksum doesn't match BIOS skip this ROM and continue seeking at next 2 kB else ISA ROM module code will be executed from 4th byte. Here we can place our code compiled with
as a flat binary. Code must end with
instruction. ROM file should be aligned with zeros to corresponding size. Look at the ROM template:
DB 55 ; header 1st byte
DB AA ; header 2nd byte
DB xx ; size in 512B blocks
JMP xxxx ; jump to our code
DB 0 ; reserved byte for checksum
xxxx ; our code
RETF ; return from ROM code
Be sure you are storing and restoring all CPU registers. The stack is usually set too small so I set it at
h. Remember if you make a mistake in your code and PC freeze you cannot disable ISA ROM module execution and you will have to reflash your BIOS in programmer or using hotflash! I also make some mistakes because it's impossible to debug the code. So I first write a part of code (label BEGIN) which give me a choice to continue ROM code execution. This is done by testing ScrollLock key flag at address
h bit 4. If ScrollLock is not pressed ROMOS restore all registers and stack and return control to BIOS. Otherwise executing continues. If there is a bug in this part (after label BOOT) I simply reboot PC and fix it.
providing some basic routines:
waits for AH*55ms,
sets cursor at
read cursor position to
prints zero terminated string at
by given attribute in
on current cursor position,
prints CR,LF to set cursor at new line,
prints a hexa word in
prints a hexa byte in
F, CS, SS, ES, DS, DI, SI, BP, SP
registers in hexa at one line,
set up 30 CPS keyboard repeat rate and 250 ms delay after first key,
set up new interrupt vector
h to new routine
and save old
h vector. Main program is between labels BOOT and EXIT.
handler supports only function 02 - read sectors. But this is enough to be able to boot and read-only access the virtual ROM disk which is placed behind label
(after ROMOS code).
just catch every
h call, checks if given drive belong to virtual ROM disk and function is 02. Then it calculates
linear memory address
CHS disk parameters
and copy required sectors (512B blocks) from virtual disk image (RAM) to given buffer at
character is displayed in the right top corner of the screen to have a visual feedback that the
h call was served successfully. If other drive or other function is caught it is passed to old
h handler (if drive match but function not then
character is displayed). There will not be problem to program read-write access, may be in future ROMOS version.
If we exit ROM code with
header then the address space stay occupied with unused code (which would be otherwise used by HMA, EMS frame,... to keep more conventional memory for DOS). This is reason why ROMOS normally write DW 0 over header. But you may leave it (and keep code in ROM address space) and hook
h by ROMOS to catch this calls to enter ROMOS after boot. If you want to use this feature simply uncomment the
And how the
virtual ROM disk image
is made? I wanted to use maximum of 64 kB ROM space for virtual disk. Normal 1,44MB diskette is formatted like this: 80 cylinders, 2 heads, 18 sectors per track and 512B per sector. Simply
CHS = 80 / 2 / 18
. If we multiply all this numbers we got 1474560 bytes. I was playing with reducing C, H parameters to get optimal disk size and found this:
CHS = 7 / 1 / 18
(126 sectors) this mean 64512 bytes. One 1 kB is reserved for the ROMOS code. For effective utilization of the disk I use 1 sector per cluster and 16 root entries. From total 126 sectors is one sector occupied by
second and third by two FAT copies and 4th one by root directory. So there remains 62464 bytes (122 sectors) for user files. To gain this space little bit I removed redundant FAT copy via DISKEDITOR and edited bootsector's values. So then I got 62976 bytes (123 sectors) for user files. But this disk format can be read only under newer MS-DOS than 6.22 (use DOS of Win9X or FreeDOS). Remember that if a file is only one byte long it occupy whole sector.
I hope that I described it understandable. I could write more details but it would be too long. And the ideas would lost in too large amount of words. I hope that it helps for people interested in this things, for beginners probably not. But don't be worry if you don't understand it just now. I have been gathering this information for some years from various Internet sources. Thanks to Google search engine, Darmawan Mappatutu Salihun - Award BIOS Reverse Engineering, Jan Steunebrink, Daemorhedron, Sunil Shrestha, Luchezar Georgiev, Eric Auer, Jakub Chalupník, FreeDOS community, Miroslav Němeček (MicroManager), Datalight, Rebels Haven BIOS modding forum.
Recently I was reading very interesting article describing that a modern PC contains some auxiliary MCU called EC (Embedded Controller) beside the main CPU which resides inside the chipset on mainboard (northbridge - MCH, later integrated into the main CPU). Intel use 32-bit ARC architecture processor inside P35 chipset. AMD use some 51 clone or LatticeMico32. The EC is running even in S3 sleep mode. This is part of intel VPro technology for remote PC administration (BTW EC can also run a small webserver). The level on which the firmware of EC is running is classified as ring -3 (ring -2 is SMI handler of system BIOS, ring -1 is hypervisor used for running virtualized OSes and ring 0 is well known OS kernel). Firmware is physically stored in SPI FlashROM together with system BIOS. You can see more info about AMD EC FW analysis on this video of my friend Ruik that he presented on CCC 2014. EC has interesting function that it can freely access host CPU RAM and reset host CPU at any time regardless on running OS. Every such incredible BigBrother-like function can be abused. More info about it you can read in this presentation: Introducing Ring -3 Rootkits.
FAQ, underline notes
Why doesn't ROMOS work under PC emulator
It's caused by BOCHS (let's say its BIOS) that doesn't support
feature (copying ROM content to RAM). Then ROM area, where ROMOS store original
h vector and
during start, is accesible for reading only. When restoring
or calling old interrupt vectors it use wrong address and fatal error occur. It's not problem to store this important data to RAM area (
00000 - 9FFFF
h) but I don't know what safe address should I choose to be procected against owerwriting by operating system, drivers or applications loaded after ROMOS.
Newly since version 0.97 storing of these data has been changed (now using free space in interrupt vector table) and write access to ROM segment is not required now. So ROMOS works now in BOCHS emulator.
Q: Is possible to enlarge ROM disk size to more than 62 kB?
A: Yes, it's possible. I can [EDIT:] cannot get additional 32 kB by quite easy way by splitting ROM disk image to two parts and using empty ROM hole at B0000 - B7FFFh. I plan to implement this in future version of ROMOS. Further ROM disk enlarging would be possible by this way: ROMOS would load ROM disk image (splitted on a few of ROM modules-due to max. 64 kB / module size limitation) somewhere above 1 MB to high address space during start and then it would paging just needed sectors to frame in low address space under 1 MB. But it would require programming in protected mode and I don't have any experiences with it under assembler. There's a question if it would payoff because we are still limited by relative small free space in FlashROM. It's preferable to use CompactFlash card with IDE adapter for more exacting applications.
Q: Can be address range B0000 - B7FFFh used or not?
A: Unfortunately I found out that can't. When I loaded 4kB dummy ROM (contained only RETF instruction) at address B000:0000h (I tried B400h too) my PC froze and I had to do hotflash recovery. So usable address range is D0000 - DFFFFh (64 kB) only, nothing more.