Skip to content

Commit 8b47254

Browse files
committed
Initial commit.
0 parents  commit 8b47254

File tree

5 files changed

+349
-0
lines changed

5 files changed

+349
-0
lines changed

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*.bin
2+
*.rom
3+
*.img
4+
*.kate-swp
5+
*.86
6+
*.386
7+
optromloader9
8+
optromloader15
9+
optromloader18

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Roc Vallès i Domènech
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
fasm = fasm
2+
#hexdumpcmd = hexdump -C
3+
hexdumpcmd = xxd -a
4+
qemu = qemu-system-i386
5+
date = \"`date +%Y%m%d%H%M`\"
6+
.PHONY: all
7+
all: hexdump optromloader18 optromloader15 optromloader9 fd1440.img fd720.img fd1200.img fd360.img
8+
optromloader18: optromloader.S
9+
@echo "*** assembling $@..."
10+
$(fasm) -d date=$(date) -d sectorspertrack=18 optromloader.S $@
11+
optromloader15: optromloader.S
12+
@echo "*** assembling $@..."
13+
$(fasm) -d date=$(date) -d sectorspertrack=15 optromloader.S $@
14+
optromloader9: optromloader.S
15+
@echo "*** assembling $@..."
16+
$(fasm) -d date=$(date) -d sectorspertrack=9 optromloader.S $@
17+
fd1440.img: optromloader18 optrom.bin
18+
@echo "*** building $@..."
19+
cat optromloader18 optrom.bin | dd bs=1474560 conv=sync of=$@
20+
fd720.img: optromloader9 optrom.bin
21+
@echo "*** building $@..."
22+
cat optromloader9 optrom.bin | dd bs=737280 conv=sync of=$@
23+
fd1200.img: optromloader15 optrom.bin
24+
@echo "*** building $@..."
25+
cat optromloader15 optrom.bin | dd bs=1228800 conv=sync of=$@
26+
fd360.img: optromloader9 optrom.bin
27+
@echo "*** building $@..."
28+
cat optromloader9 optrom.bin | dd bs=368640 conv=sync of=$@
29+
.PHONY: clean
30+
clean:
31+
@echo "*** Removing build artifacts..."
32+
rm -f optromloader9 optromloader15 optromloader18 fd1440.img fd720.img fd1200.img fd360.img
33+
.PHONY: hexdump
34+
hexdump: optromloader18
35+
@echo "*** hexdump optromloader18..."
36+
$(hexdumpcmd) optromloader18
37+
.PHONY: emulate
38+
emulate: fd1440.img
39+
@echo "*** Emulating with qemu..."
40+
$(qemu) -drive if=floppy,format=raw,index=0,file=fd1440.img
41+
.PHONY: emulaterom
42+
emulaterom: optrom.bin
43+
@echo "*** Emulating with qemu..."
44+
$(qemu) -net none -option-rom optrom.bin

README.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# optromloader: IBM PC/Clone 8086+ floppy-loading of option roms.
2+
3+
Booted from a floppy, it will load an Option ROM image into the end of conventional memory.
4+
5+
![PCem PC1512 screenshot](https://b.rvalles.net/unsorted/pcem_pc1512_optromboot_xtide.png)
6+
7+
Usage
8+
* Ensure fasm (flat assembler) is installed
9+
* Copy your ROM image as the `optrom.bin` file.
10+
* Run `make`.
11+
* Optionally test with qemu: `make emulate`.
12+
* Floppy images will be created (fd*.img).
13+
* Alternatively, use a binary release. Concatenate:
14+
* optromloader9/15/18 (according to sectors per track in your floppy format)
15+
* 9 for 5.25" 360K and 3.5" 720K
16+
* 15 for 5.25" 1.2M
17+
* 18 for 3.5" 1.44M
18+
* the ROM image.
19+
* pad to floppy size.
20+
21+
Use cases (non-exhaustive)
22+
* Test boot ROMs before burning them.
23+
* Netboot with etherboot/gpxe/ipxe.
24+
* IDE support (including LBA!) with XTIDE Universal BIOS.
25+
26+
Highlights
27+
* flat assembler syntax.
28+
* Pure 8086 code.
29+
* Works on newer hardware, such as the 486 I wrote it for.
30+
* Fits in a floppy bootblock.
31+
* Trivial to use. Concatenate loader and the ROM image, write into floppy.
32+
* Makefile will prepare 5.25" 360K/1.2M and 3.5" 720K/1.44M floppy images.
33+
34+
Caveats
35+
* Hardcoded to use the first floppy drive.
36+
* ROM checksum isn't checked (yet).
37+
* Always ensure a boot ROM is signed before burning.
38+
* Qemu provides a python tool to sign ROMs:
39+
* https://github.com/qemu/qemu/blob/master/scripts/signrom.py
40+
* For XTIDE Universal BIOS roms, use its XTIDECFG tool to configure and sign ROM images.

optromloader.S

+235
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
;optromloader, by Roc Valles Domenech.
2+
;MIT license, see LICENSE for details.
3+
;https://www.rvalles.net
4+
format binary as "raw"
5+
use16
6+
org 7C00h
7+
jmp 0x0000:start
8+
start:
9+
mov sp,$7C00
10+
mov ax,0
11+
mov bx,ss
12+
mov ss,ax
13+
mov ds,ax
14+
mov si,banner_str
15+
call printstr
16+
mov ax,1
17+
mov bx,bootblock_end
18+
call readblock
19+
mov bx,[bootblock_end]
20+
cmp bx,$AA55
21+
jnz bad_header_magic
22+
mov si,romsize_str
23+
call printstr
24+
mov ax,0
25+
mov al,[bootblock_end+2]
26+
mov bx,ax
27+
call printhex8
28+
mov si,romsizebytes_str
29+
call printstr
30+
mov ax,bx
31+
mov cl,9
32+
shl ax,cl
33+
call printhex16
34+
mov si,ramsize_str
35+
call printstr
36+
int 12h
37+
call printhex16
38+
mov dx,bx
39+
test dx,1
40+
jz .blocks_even
41+
add dx,1
42+
.blocks_even:
43+
shr dx,1
44+
sub ax,dx
45+
mov [1043],ax
46+
mov si,ramsizeafter_str
47+
call printstr
48+
int 12h
49+
call printhex16
50+
mov cl,6
51+
shl ax,cl ;target segment
52+
mov es,ax
53+
mov dx,0
54+
mov si,readblocks_str
55+
call printstr
56+
mov cx,bx
57+
mov bx,0 ;target address
58+
.readrom:
59+
;hlt
60+
add dl,1
61+
mov ax,dx
62+
call printhex8
63+
call readblock
64+
add bx,512
65+
mov si,readblocksbs_str
66+
call printstr
67+
cmp cx,dx
68+
jne .readrom
69+
;mov si,cksum_str
70+
;call printstr
71+
mov ax,es
72+
mov [.calloptrom+3], ax
73+
mov ah,0eh
74+
mov al,'#'
75+
int 10h
76+
;sti ;some bad BIOSs disable on int13 and forget to restore.
77+
.calloptrom:
78+
call 0xA000:3
79+
mov ah,0eh
80+
mov al,'@'
81+
int 10h
82+
int 19h
83+
;*****************************************************************************
84+
bad_header_magic:
85+
mov si,bad_header_magic_str
86+
call printstr
87+
mov ax,bx
88+
call printhex16
89+
jmp $
90+
printstr: ;SI *str
91+
push ax
92+
mov ah,0eh ;print character
93+
.printstr_loop:
94+
lodsb ;SI++ -> al
95+
test al,al
96+
jz .printstr_end
97+
int 10h ;print
98+
jmp .printstr_loop
99+
.printstr_end:
100+
pop ax
101+
ret
102+
;FIXME: these value dumpers could be shorter.
103+
printhex8: ;AL (preserved) value to print
104+
push ax
105+
push bx
106+
push cx
107+
mov ah,0eh
108+
mov bl,al
109+
mov cl,4
110+
rol bl,cl ;in 8086, 1 or cl. 186+ for higher imm.
111+
call printhexdigit
112+
rol bl,cl
113+
call printhexdigit
114+
pop cx
115+
pop bx
116+
pop ax
117+
ret
118+
printhex16: ;AX (preserved) value to print
119+
push ax
120+
push bx
121+
push cx
122+
mov bx,ax
123+
mov ah,0eh
124+
mov cl,4
125+
rol bx,cl
126+
call printhexdigit
127+
rol bx,cl
128+
call printhexdigit
129+
rol bx,cl
130+
call printhexdigit
131+
rol bx,cl
132+
call printhexdigit
133+
pop cx
134+
pop bx
135+
pop ax
136+
ret
137+
printhexdigit: ;FIXME: Make shorter. possibly use daa/adc inst.
138+
mov al,bl
139+
and al,$F
140+
add al,$30
141+
cmp al,$3A
142+
jb .printhexlow
143+
add al,7
144+
.printhexlow:
145+
int 10h
146+
ret
147+
resetfloppy:
148+
mov ah,0
149+
mov dl,0
150+
int 13h
151+
ret
152+
readblock: ;AX blocknumber, ES:BX (preserved) addr.
153+
;call printhex16
154+
;xchg ax,bx
155+
;call printhex16
156+
;xchg ax,bx
157+
push cx
158+
push dx
159+
;CHS magic: get number of tracks, heads>>1 is cyl
160+
mov dl,sectorspertrack
161+
div dl ;ax/dl -> /al, %ah
162+
mov dh,0 ;head 0..15
163+
test al,1
164+
jz .heads_even
165+
add dh,1
166+
.heads_even:
167+
shr al,1
168+
;CX 0-5 sector, 6-7 track MSB, 8-15 track LSB
169+
mov ch,al ;cyl
170+
add ah,1 ;CHS sectors start at 1
171+
mov cl,ah ;sector
172+
mov ah,02h ;BIOS 13h read CHS block
173+
mov al,1 ;sectors to read 1..128
174+
mov dl,0 ;drive 0=A 80h=hdd0
175+
;xchg ax,cx
176+
;call printhex16
177+
;xchg ax,cx
178+
;xchg ax,dx
179+
;call printhex16
180+
;xchg ax,dx
181+
push ax
182+
.retry:
183+
;hlt
184+
;push ax
185+
;mov ah,0eh
186+
;mov al,'%'
187+
;int 10h
188+
;pop ax
189+
int 13h
190+
;push ax
191+
;mov ah,0eh
192+
;mov al,'?'
193+
;int 10h
194+
;pop ax
195+
cmp ah,0
196+
jne .error
197+
;mov dx,es
198+
;mov ds,dx
199+
;mov ax,[bx]
200+
;call printhex16
201+
mov dx,0
202+
mov ds,dx
203+
pop ax
204+
pop dx
205+
pop cx
206+
ret
207+
.error:
208+
push ax
209+
mov ah,0eh
210+
mov al,'E'
211+
int 10h
212+
pop ax
213+
mov al,ah
214+
mov ah,0
215+
call printhex8
216+
call resetfloppy
217+
mov si,readblocks_str
218+
call printstr
219+
pop ax
220+
push ax
221+
jmp .retry
222+
banner_str: db "optromloader, by Roc Valles Domenech <rvalles.net>, built ",date,'.',13,10,0
223+
bad_header_magic_str: db "Ehdrmagic:",0
224+
romsize_str: db "ROM blks:",0
225+
romsizebytes_str: db "->",0
226+
ramsize_str: db 13,10,"RAM:",0
227+
ramsizeafter_str: db "/",0
228+
readblocks_str: db 13,10,"Rd:",0
229+
readblocksbs_str: db 8,8,0
230+
;readblocksbs_str: db 13,10,"Rd+",0
231+
;cksum_str: db 13,10,"Ck+",0
232+
.finalize_bootblock:
233+
times 510-($-$$) db 0
234+
dw $AA55
235+
bootblock_end:

0 commit comments

Comments
 (0)