Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
rvalles committed Sep 14, 2021
0 parents commit 8b47254
Show file tree
Hide file tree
Showing 5 changed files with 349 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*.bin
*.rom
*.img
*.kate-swp
*.86
*.386
optromloader9
optromloader15
optromloader18
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 Roc Vallès i Domènech

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
44 changes: 44 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
fasm = fasm
#hexdumpcmd = hexdump -C
hexdumpcmd = xxd -a
qemu = qemu-system-i386
date = \"`date +%Y%m%d%H%M`\"
.PHONY: all
all: hexdump optromloader18 optromloader15 optromloader9 fd1440.img fd720.img fd1200.img fd360.img
optromloader18: optromloader.S
@echo "*** assembling $@..."
$(fasm) -d date=$(date) -d sectorspertrack=18 optromloader.S $@
optromloader15: optromloader.S
@echo "*** assembling $@..."
$(fasm) -d date=$(date) -d sectorspertrack=15 optromloader.S $@
optromloader9: optromloader.S
@echo "*** assembling $@..."
$(fasm) -d date=$(date) -d sectorspertrack=9 optromloader.S $@
fd1440.img: optromloader18 optrom.bin
@echo "*** building $@..."
cat optromloader18 optrom.bin | dd bs=1474560 conv=sync of=$@
fd720.img: optromloader9 optrom.bin
@echo "*** building $@..."
cat optromloader9 optrom.bin | dd bs=737280 conv=sync of=$@
fd1200.img: optromloader15 optrom.bin
@echo "*** building $@..."
cat optromloader15 optrom.bin | dd bs=1228800 conv=sync of=$@
fd360.img: optromloader9 optrom.bin
@echo "*** building $@..."
cat optromloader9 optrom.bin | dd bs=368640 conv=sync of=$@
.PHONY: clean
clean:
@echo "*** Removing build artifacts..."
rm -f optromloader9 optromloader15 optromloader18 fd1440.img fd720.img fd1200.img fd360.img
.PHONY: hexdump
hexdump: optromloader18
@echo "*** hexdump optromloader18..."
$(hexdumpcmd) optromloader18
.PHONY: emulate
emulate: fd1440.img
@echo "*** Emulating with qemu..."
$(qemu) -drive if=floppy,format=raw,index=0,file=fd1440.img
.PHONY: emulaterom
emulaterom: optrom.bin
@echo "*** Emulating with qemu..."
$(qemu) -net none -option-rom optrom.bin
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# optromloader: IBM PC/Clone 8086+ floppy-loading of option roms.

Booted from a floppy, it will load an Option ROM image into the end of conventional memory.

![PCem PC1512 screenshot](https://b.rvalles.net/unsorted/pcem_pc1512_optromboot_xtide.png)

Usage
* Ensure fasm (flat assembler) is installed
* Copy your ROM image as the `optrom.bin` file.
* Run `make`.
* Optionally test with qemu: `make emulate`.
* Floppy images will be created (fd*.img).
* Alternatively, use a binary release. Concatenate:
* optromloader9/15/18 (according to sectors per track in your floppy format)
* 9 for 5.25" 360K and 3.5" 720K
* 15 for 5.25" 1.2M
* 18 for 3.5" 1.44M
* the ROM image.
* pad to floppy size.

Use cases (non-exhaustive)
* Test boot ROMs before burning them.
* Netboot with etherboot/gpxe/ipxe.
* IDE support (including LBA!) with XTIDE Universal BIOS.

Highlights
* flat assembler syntax.
* Pure 8086 code.
* Works on newer hardware, such as the 486 I wrote it for.
* Fits in a floppy bootblock.
* Trivial to use. Concatenate loader and the ROM image, write into floppy.
* Makefile will prepare 5.25" 360K/1.2M and 3.5" 720K/1.44M floppy images.

Caveats
* Hardcoded to use the first floppy drive.
* ROM checksum isn't checked (yet).
* Always ensure a boot ROM is signed before burning.
* Qemu provides a python tool to sign ROMs:
* https://github.com/qemu/qemu/blob/master/scripts/signrom.py
* For XTIDE Universal BIOS roms, use its XTIDECFG tool to configure and sign ROM images.
235 changes: 235 additions & 0 deletions optromloader.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
;optromloader, by Roc Valles Domenech.
;MIT license, see LICENSE for details.
;https://www.rvalles.net
format binary as "raw"
use16
org 7C00h
jmp 0x0000:start
start:
mov sp,$7C00
mov ax,0
mov bx,ss
mov ss,ax
mov ds,ax
mov si,banner_str
call printstr
mov ax,1
mov bx,bootblock_end
call readblock
mov bx,[bootblock_end]
cmp bx,$AA55
jnz bad_header_magic
mov si,romsize_str
call printstr
mov ax,0
mov al,[bootblock_end+2]
mov bx,ax
call printhex8
mov si,romsizebytes_str
call printstr
mov ax,bx
mov cl,9
shl ax,cl
call printhex16
mov si,ramsize_str
call printstr
int 12h
call printhex16
mov dx,bx
test dx,1
jz .blocks_even
add dx,1
.blocks_even:
shr dx,1
sub ax,dx
mov [1043],ax
mov si,ramsizeafter_str
call printstr
int 12h
call printhex16
mov cl,6
shl ax,cl ;target segment
mov es,ax
mov dx,0
mov si,readblocks_str
call printstr
mov cx,bx
mov bx,0 ;target address
.readrom:
;hlt
add dl,1
mov ax,dx
call printhex8
call readblock
add bx,512
mov si,readblocksbs_str
call printstr
cmp cx,dx
jne .readrom
;mov si,cksum_str
;call printstr
mov ax,es
mov [.calloptrom+3], ax
mov ah,0eh
mov al,'#'
int 10h
;sti ;some bad BIOSs disable on int13 and forget to restore.
.calloptrom:
call 0xA000:3
mov ah,0eh
mov al,'@'
int 10h
int 19h
;*****************************************************************************
bad_header_magic:
mov si,bad_header_magic_str
call printstr
mov ax,bx
call printhex16
jmp $
printstr: ;SI *str
push ax
mov ah,0eh ;print character
.printstr_loop:
lodsb ;SI++ -> al
test al,al
jz .printstr_end
int 10h ;print
jmp .printstr_loop
.printstr_end:
pop ax
ret
;FIXME: these value dumpers could be shorter.
printhex8: ;AL (preserved) value to print
push ax
push bx
push cx
mov ah,0eh
mov bl,al
mov cl,4
rol bl,cl ;in 8086, 1 or cl. 186+ for higher imm.
call printhexdigit
rol bl,cl
call printhexdigit
pop cx
pop bx
pop ax
ret
printhex16: ;AX (preserved) value to print
push ax
push bx
push cx
mov bx,ax
mov ah,0eh
mov cl,4
rol bx,cl
call printhexdigit
rol bx,cl
call printhexdigit
rol bx,cl
call printhexdigit
rol bx,cl
call printhexdigit
pop cx
pop bx
pop ax
ret
printhexdigit: ;FIXME: Make shorter. possibly use daa/adc inst.
mov al,bl
and al,$F
add al,$30
cmp al,$3A
jb .printhexlow
add al,7
.printhexlow:
int 10h
ret
resetfloppy:
mov ah,0
mov dl,0
int 13h
ret
readblock: ;AX blocknumber, ES:BX (preserved) addr.
;call printhex16
;xchg ax,bx
;call printhex16
;xchg ax,bx
push cx
push dx
;CHS magic: get number of tracks, heads>>1 is cyl
mov dl,sectorspertrack
div dl ;ax/dl -> /al, %ah
mov dh,0 ;head 0..15
test al,1
jz .heads_even
add dh,1
.heads_even:
shr al,1
;CX 0-5 sector, 6-7 track MSB, 8-15 track LSB
mov ch,al ;cyl
add ah,1 ;CHS sectors start at 1
mov cl,ah ;sector
mov ah,02h ;BIOS 13h read CHS block
mov al,1 ;sectors to read 1..128
mov dl,0 ;drive 0=A 80h=hdd0
;xchg ax,cx
;call printhex16
;xchg ax,cx
;xchg ax,dx
;call printhex16
;xchg ax,dx
push ax
.retry:
;hlt
;push ax
;mov ah,0eh
;mov al,'%'
;int 10h
;pop ax
int 13h
;push ax
;mov ah,0eh
;mov al,'?'
;int 10h
;pop ax
cmp ah,0
jne .error
;mov dx,es
;mov ds,dx
;mov ax,[bx]
;call printhex16
mov dx,0
mov ds,dx
pop ax
pop dx
pop cx
ret
.error:
push ax
mov ah,0eh
mov al,'E'
int 10h
pop ax
mov al,ah
mov ah,0
call printhex8
call resetfloppy
mov si,readblocks_str
call printstr
pop ax
push ax
jmp .retry
banner_str: db "optromloader, by Roc Valles Domenech <rvalles.net>, built ",date,'.',13,10,0
bad_header_magic_str: db "Ehdrmagic:",0
romsize_str: db "ROM blks:",0
romsizebytes_str: db "->",0
ramsize_str: db 13,10,"RAM:",0
ramsizeafter_str: db "/",0
readblocks_str: db 13,10,"Rd:",0
readblocksbs_str: db 8,8,0
;readblocksbs_str: db 13,10,"Rd+",0
;cksum_str: db 13,10,"Ck+",0
.finalize_bootblock:
times 510-($-$$) db 0
dw $AA55
bootblock_end:

0 comments on commit 8b47254

Please sign in to comment.