Too much space needed; optimizing now

This commit is contained in:
Eric-Paul Ickhorn 2023-04-26 01:09:46 +02:00
parent 4887c61303
commit 49230d4c72
2 changed files with 196 additions and 108 deletions

View File

@ -3,8 +3,6 @@ section .text
org 0x7c00
start:
push dx
mov ax, 0
mov ds, ax
mov es, ax
@ -17,62 +15,196 @@ start:
mov sp, 256
mov bp, 256
mov si, dx ; save the origin disk number
mov ax, 0x7c00
add ax, 446
; ax now points to the start of the partition table
mov di, 0
xor di, di
call initialize_video_mode
.search_partition:
mov bx, ax
add bx, 4
mov bx, ax ; get the offset of the current entry
add bx, 4 ; go to the offset of the partition type
mov cl, [bx]
cmp cl, 0x9d
je .found_partition
je .load_partition
inc di
; leave and print debug message if the last partition entry
; did not provide the wanted bootloader - partition
cmp di, 4
je .no_boot_partition
add ax, 16
jmp .search_partition
.found_partition:
.load_partition:
; ax is the start of the bootloader's partition entry in the mbr
; read the chs-entry and push it onto the stack
; head
xor dx, dx
mov bx, ax
add bx, 1
mov dl, [bx]
push dx
; cylinder
xor dx, dx
mov bx, ax
add bx, 3
mov dh, [bx]
mov bx, ax
add bx, 2
mov dl, [bx]
shr dx, 6
push dx
; sector
xor dx, dx
mov bx, ax
add bx, 2
mov dl, [bx]
and dl, 0b00111111
push dx
; push the partition's length
mov bx, ax
add bx, 12
mov dx, [bx]
push dx ; lower part
mov bx, ax
add bx, 14
mov cx, [bx] ; more than 65536 sectors will NOT be
; supported for the bootloader's partition!
mov bx, 0x8000
mov es, bx
mov di, 0x0000
mov bx, ax
inc bx
; bx now points to the CHS-address of the first sector
; of the bootloader's partition.
mov dx, [bx]
mov ah, dh ; head
mov bl, dl ; sector
push dx ; higher part
; load it all and read from disk
mov bx, sp
add bx, 4
mov al, [bx] ; sector-count
add bx, 2
; bx now points to the CHS-cylinder of the first sector
; of the bootloader's partition.
mov cl, [bx] ; start-sector
mov al, [bx] ; cylinder
add bx, 2
mov ch, [bx] ; start-cylinder
call load_sectors
mov dx, si ; drive
mov bx, 0x0800
mov es, bx ; output segment
mov bx, sp
add bx, 8
mov dh, [bx] ; start-head
call .write_hex
mov cl, 2
mov ah, 0x02
mov al, 1
mov bx, 0x0000 ; output address in es - segment
int 13h
mov cx, 8
mov si, 0x8000
mov dh, 12
mov dl, 32
call print_string
jmp .keepalive
.no_boot_partition:
hlt
mov cx, LEN_TEXT_NO_BOOT_PARTITION
mov si, error_texts.no_boot_partition
mov dh, 12
mov dl, 32
call print_string
.keepalive:
jmp .keepalive
.write_hex:
push bx
push cx
mov bx, error_texts.hextab
and cx, 0x0f
add bx, cx
mov cl, [bx]
mov bx, error_texts.hexbuf
inc bx
mov [bx], cl
mov bx, error_texts.hextab
and cx, 0xf0
shr cx, 4
add bx, cx
mov cl, [bx]
mov bx, error_texts.hexbuf
mov [bx], cl
mov cx, 2
mov si, error_texts.hexbuf
mov dh, 12
mov dl, 32
call print_string
pop cx
pop bx
ret
; %include "exfat.asm"
%include "gdt.asm"
%include "utility.asm"
LEN_TEXT_NO_BOOT_PARTITION equ 17
error_texts:
.no_boot_partition:
;db "NO_BOOT_PARTITION"
.hextab:
db "0123456789abcdef"
.hexbuf:
resb 4
times 446 - ($-$$) db 0
db 0x80
db 0, 2, 0
db 0x9d
db 0, 3, 0
dd 1
dd 1
times 510 - ($-$$) db 0
db 0x55
db 0xAA
db "################"

View File

@ -198,14 +198,28 @@ mem_equals:
; ax: start_sector (lower)
; bl: start_sector (upper)
; cx: sector_count
; ax: start_sector (upper)
; bl: start_sector (lower)
; cx: wanted_sector_count
; dh: drive
; es: buffer_address (upper)
; si: buffer_address (upper)
; di: buffer_address (lower)
load_sectors:
; INNER WORKING:
;
; This function first checks if it needs to load sectors going over
; a cylinder boundary and loads to that cylinder boundary first continuing
; in 63-sector - parts after that until the last, < 63-sectors part is read.
;
; This is done because some systems don't like reading over the boundaries
; between the cylinders.
;
; The actual part loading the data is in .read_from_disk, it's no different
; from the first read to the other reads. It just gets different arguments
; from 1).load_first_sectors, and 2) .load_further_sectors
;
.prolog:
push ax
push bx
@ -214,101 +228,43 @@ load_sectors:
push si
xor si, si ; current sector index
; calculate the distance (in sectors) to the next cylinder boundary
; get the index of the current cylinder
and ax, 0b00111111 ; extract only the sector index
mov bx, 64 ; get the maximum number of sectors + 1
sub bx, ax ; invert the result; 1 becomes 63; 63 becomes 1
cmp ax, 63
jne .is_not_on_full_cylinder_boundary
; if it's indeed on a full cylinder boundary, the first_read-part is unimportant
mov ax, 0
set_load_args
.is_not_on_full_cylinder_boundary:
.load_first_sectors:
; cx still contains the entry-point's wanted sector_count
; ax now contains the distance to the next cylinder boundary
cmp cx, ax
jbe .load_data
; it gets here if there are more sectors needed after the
; next cylinder boundary
; if the number of sectors
; which are wanted (sector_count) is above the
; distance to the next cylinder boundary
; ah: EMPTY
; al: num_sectors_to_read
; bx: EMPTY
; ch: cylinder
; cl: sector
; dh: head
; dl: drive
.read_from_disk:
; if not that many sectors are needed, just read as
; many sectors as are needed in total
mov cx, bx
; set es:bx to the address in bytes to which the output should be written.
jmp .load_data
mov bx, si
shr bx, 9
; sets the arguments for a run of '.load_data' after the
; first one; aligned on a CHS - cylinder boundary
.set_load_args:
mov bx, sp
add bx, 4
mov cx, [bx]
sub cx, si ; cx = num_missing_sectors
cmp cx, 63
jbe .add_num_missing_sectors_to_sector_index
; if this goes here, there are more than 63 sectors
; still missing to be loaded
; -> clamp them to 63 so they can be loaded.
mov cl, 63
jmp .load_data
.add_num_missing_sectors_to_sector_index:
add si, cx
; loads at most 64 sectors from the disk into the main memory
; ax: scratchpad
; bx: start_sector (high part)
; ch: start_sector (low part)
; cl: num_sectors
.load_data:
mov ah, 0x02
mov al, cl
mov dl, [bx] ; drive
mov dh, bh ; head
mov cl, ch ; sector
mov ch, bl ; cylinder
mov bx, di ; buffer address (lower)
int 0x13
.continue_if_needed:
; check if there still are sectors missing to load
mov bx, sp
add bx, 4
mov cx, [bx] ; sector_count
cmp si, cx
jb .set_load_args
.load_further_sectors:
.epilog:
pop si
pop dx
pop cx
pop bx
pop ax
ret