Skip to content

Commit

Permalink
Merge pull request #6 from Googulator/hardware-compat
Browse files Browse the repository at this point in the history
Switch stage1 to LBA disk access
  • Loading branch information
rick-masters committed Jan 22, 2024
2 parents 8a6be6d + ec73321 commit 8621e56
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 99 deletions.
97 changes: 45 additions & 52 deletions builder-hex0-x86-stage1.hex0
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ FC # cld ; clear direction flag
#----------------------------------------
# Compile hex0 to binary
# compile(dl=boot_drive):
BF 00 7E # mov di, $stage2_entry

# this flag is set after the first digit is seen
31 DB # xor bx,bx

BF 00 7E # mov di, $stage2_entry

#:read_loop
E8 7D 00 # call read
E8 97 00 # call read
84 C0 # test al, al
74 4B # jz finish

Expand Down Expand Up @@ -95,7 +96,7 @@ EB 15 # jmp maybe_store
EB 09 # jmp maybe_store

#:skip_comment
E8 4A 00 # call read
E8 64 00 # call read
3C 0A # cmp al, '\n'
75 F9 # jnz skip_comment
EB C4 # jmp read_loop
Expand Down Expand Up @@ -124,64 +125,61 @@ EB AE # jmp read_loop
#:finish
E9 95 01 # jmp stage2_entry

#-------------
# align to 16 bit boundary
00 00 00 00 00
#:addr_packet
10 00
#:num_sectors_bios
01 00
#:dest_offset
00 78
#:dest_segment
00 00
#:starting_lba
01 00 00 00 00 00 00 00
#:last_byte
FF 01

#------------------------------------------------------------
#[7C6B]
#[7C82]
#:read_sector
# input:
# di = *dest_addr
# cx=cylinder/sector
# dh = head, dl=drive)
# ecx = logical sector to read
# dl = drive
#
# returns: di - next byte to write to
# cx,dh - next disk sector to read from
# returns: ecx - next logical sector to read from
#
50 # push ax
53 # push bx
66 60 # pushad

89 FB # mov bx, di ; int 13 writes to bx

#:read_one_loop
B4 02 # mov ah, 2 ; rw mode = 02 (read)
B0 01 # mov al, 1 ; num_sectors
66 89 0E 78 7C # mov dword ptr [starting_lba], ecx
BE 01 00 # mov si, 1
89 36 72 7C # mov word ptr [num_sectors_bios], si
B4 42 # mov ah, 0x42 ; rw mode = 42 (read LBA)
BE 70 7C # mov si, addr_packet ; disk address packet
CD 13 # int 0x13
72 14 # jc read_error

# Check for nonzero, not 1, because some BIOSes may read more
# sectors for future use, and wrongly report it
3C 00 # cmp al, 0
74 10 # jz read_error
72 0F # jc read_error

80 F9 3F # cmp cl, 0x3f ; if sector_num == max_sector
74 04 # jz next_head ; goto next_head
FE C1 # inc cl ; else sector_num++;
EB 04 # jmp read_sector_finish
8B 3E 72 7C # mov di, word ptr [num_sectors_bios] ; number of sectors actually read
85 FF # test di, di
74 07 # jz read_error

#:next_head
FE C6 # inc dh ; else head_num++
B1 01 # mov cl, 1 ; sector = 1

#:read_sector_finish
5B # pop bx
58 # pop ax
89 DF # mov di, bx
66 61 # popad
66 41 # inc ecx
C3 # ret

# Reset disk subsystem on error
#:read_error
31 C0 # xor ax, ax
CD 13 # int 0x13
EB DE # jmp read_one_loop

EB D6 # jmp read_one_loop

#----------------------------------------
#[7C91]
#:last_read_location
02 00 ; last_cylinder/sector
00 ; last_head
FF 01 ; last_byte

#----------------------------------------
#[7C96]
#[7CB0]
#:read
53 # push bx
51 # push cx
Expand All @@ -190,29 +188,26 @@ FF 01 ; last_byte
57 # push di

# get current position
BB 91 7C # mov bx, last_read_location
8B 0F # mov cx, [bx]
8A 77 02 # mov dh, [bx+2]
8B 47 03 # mov ax, [bx+3]
BB 78 7C # mov bx, starting_lba
66 8B 0F # mov ecx, [bx]
8B 47 08 # mov ax, [bx+8]

#end of sector?
3D FF 01 # cmp ax, 0x01ff
74 03 # je read_next_sector

#nextchar:
40 # inc ax
EB 0D # jmp getchar
EB 08 # jmp getchar

#:read_next_sector
BF 00 78 # mov di, 0x7800
E8 B7 FF # call read_sector
E8 B9 FF # call read_sector
# save new location and offset
89 0F # mov [bx], cx
88 77 02 # mov [bx+2], dh
66 89 0F # mov [bx], ecx
31 C0 # xor ax, ax

#:getchar
89 47 03 # mov [bx+3], ax
89 47 08 # mov [bx+8], ax
BE 00 78 # mov si, 0x7800
89 C3 # mov bx, ax
8A 00 # mov al, [si+bx]
Expand All @@ -227,8 +222,6 @@ C3 # ret


# padding to fill a 512 byte sector
00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Expand Down
78 changes: 36 additions & 42 deletions builder-hex0-x86-stage1.hex2
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ FC # cld ; clear direction flag
#----------------------------------------
# Compile hex0 to binary
# compile(dl=boot_drive):
BF $stage2_entry # mov di, $stage2_entry

# this flag is set after the first digit is seen
31 DB # xor bx,bx

BF $stage2_entry # mov di, $stage2_entry

:read_loop
E8 @read # call read
84 C0 # test al, al
Expand Down Expand Up @@ -124,45 +125,50 @@ EB !read_loop # jmp read_loop
:finish
E9 @stage2_entry # jmp stage2_entry

#-------------
# align to 16 bit boundary
00 00 00 00 00
:addr_packet
10 00
:num_sectors_bios
01 00
:dest_offset
00 78
:dest_segment
00 00
:starting_lba
01 00 00 00 00 00 00 00
:last_byte
FF 01

#------------------------------------------------------------
:read_sector
# input:
# di = *dest_addr
# cx=cylinder/sector
# dh = head, dl=drive)
# ecx = logical sector to read
# dl = drive
#
# returns: di - next byte to write to
# cx,dh - next disk sector to read from
# returns: ecx - next logical sector to read from
#
50 # push ax
53 # push bx
66 60 # pushad

89 FB # mov bx, di ; int 13 writes to bx

:read_one_loop
B4 02 # mov ah, 2 ; rw mode = 02 (read)
B0 01 # mov al, 1 ; num_sectors
66 89 0E $starting_lba # mov dword ptr [starting_lba], ecx
BE 01 00 # mov si, 1
89 36 $num_sectors_bios # mov word ptr [num_sectors_bios], si
B4 42 # mov ah, 0x42 ; rw mode = 42 (read LBA)
BE $addr_packet # mov si, addr_packet ; disk address packet
CD 13 # int 0x13
72 !read_error # jc read_error

# Check for nonzero, not 1, because some BIOSes may read more
# sectors for future use, and wrongly report it
3C 00 # cmp al, 0
8B 3E $num_sectors_bios # mov di, word ptr [num_sectors_bios] ; number of sectors actually read
85 FF # test di, di
74 !read_error # jz read_error

80 F9 3F # cmp cl, 0x3f ; if sector_num == max_sector
74 !next_head # jz next_head ; goto next_head
FE C1 # inc cl ; else sector_num++;
EB !read_sector_finish # jmp read_sector_finish

:next_head
FE C6 # inc dh ; else head_num++
B1 01 # mov cl, 1 ; sector = 1

:read_sector_finish
5B # pop bx
58 # pop ax
89 DF # mov di, bx
66 61 # popad
66 41 # inc ecx
C3 # ret

# Reset disk subsystem on error
Expand All @@ -171,13 +177,6 @@ C3 # ret
CD 13 # int 0x13
EB !read_one_loop # jmp read_one_loop


#----------------------------------------
:last_read_location
02 00 ; last_cylinder/sector
00 ; last_head
FF 01 ; last_byte

#----------------------------------------
:read
53 # push bx
Expand All @@ -187,10 +186,9 @@ FF 01 ; last_byte
57 # push di

# get current position
BB $last_read_location # mov bx, last_read_location
8B 0F # mov cx, [bx]
8A 77 02 # mov dh, [bx+2]
8B 47 03 # mov ax, [bx+3]
BB $starting_lba # mov bx, starting_lba
66 8B 0F # mov ecx, [bx]
8B 47 08 # mov ax, [bx+8]

#end of sector?
3D FF 01 # cmp ax, 0x01ff
Expand All @@ -201,15 +199,13 @@ BB $last_read_location # mov bx, last_read_location
EB !getchar # jmp getchar

:read_next_sector
BF 00 78 # mov di, 0x7800
E8 @read_sector # call read_sector
# save new location and offset
89 0F # mov [bx], cx
88 77 02 # mov [bx+2], dh
66 89 0F # mov [bx], ecx
31 C0 # xor ax, ax

:getchar
89 47 03 # mov [bx+3], ax
89 47 08 # mov [bx+8], ax
BE 00 78 # mov si, 0x7800
89 C3 # mov bx, ax
8A 00 # mov al, [si+bx]
Expand All @@ -224,8 +220,6 @@ C3 # ret


# padding to fill a 512 byte sector
00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Expand Down
5 changes: 0 additions & 5 deletions hex2tohex0.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,3 @@ cut ${PROGRAM}.hex0 -f1 -d'#' | cut -f1 -d';' | xxd -r -p > hex2.bin
echo "This file must be a multiple of 512:"
ls -l hex2.bin
rm -f -- *.hex *.bin

if [ "${PROGRAM}" = "builder-hex0-x86-stage2" ]; then
echo "To test in live-bootstrap (replacing path as necessary):"
echo "cp ${PROGRAM}.hex0 ~/live-bootstrap/kernel-bootstrap/${PROGRAM}.hex0"
fi

0 comments on commit 8621e56

Please sign in to comment.