Preparing for rewriting load_sectors

This commit is contained in:
Eric-Paul Ickhorn 2023-04-25 21:12:35 +02:00
parent 6d9ad157fb
commit 4887c61303
1 changed files with 243 additions and 29 deletions

View File

@ -1,6 +1,203 @@
section .text section .text
initialize_video_mode:
.prolog:
push ax
; set the video mode correctly
xor ah, ah ; bios-function (set video mode)
mov al, 3 ; video mode with 80x25 characters
int 0x10
.epilog:
pop ax
ret
; cx: len_buffer
; si: buffer
; dl: start_x NOTE: Will contain the end of the text on-screen
; dh: start_y NOTE: Will contain the end of the text on-screen
print_string:
.prolog:
push di
push cx
push bx
push ax
xor di, di ; character index
.printing_loop:
.set_cursor_position:
mov ah, 0x02
mov bh, 0
int 0x10
.write_character:
push cx ; save len_buffer
; get the current character
mov bx, si
add bx, di
mov al, [bx]
; al now contains the current character
; set the other needed interrupt values
mov ah, 0x0a ; wanted function (write character at cursor position)
mov bh, 0 ; page number
mov cx, 1 ; repetitions of character
int 0x10 ; call bios basic draw functions
pop cx ; restore len_buffer
inc dl ; go to next column
; go to a new line if needed
cmp dl, 80
jb .no_new_line_needed
xor dl, dl
inc dh ; increase column
.no_new_line_needed:
inc di ; go to next character
; go further if the string-printing hasn't been finished
cmp di, cx
jb .printing_loop
.epilog:
pop ax
pop bx
pop cx
pop di
ret
; ds: source
; es: destination
; dx: len_to_copy
mem_copy:
push ax
push bx
push cx
push dx
xor cx, cx
mov di, dx
; ax: first region's value
; bx: address at index
; cx: byte_index
; dx: second region's value
.loop:
; retrieve the source byte at the current index
mov bx, cx
mov dx, [bx]
; swap the two segments
; here, ax and bx are used differently.
mov ax, es
mov bx, ds
mov ds, ax
mov es, bx
mov [bx], cx
; swap the two segments back
mov ax, es
mov bx, ds
mov ds, ax
mov es, bx
inc cx
; if the end has NOT been reached
cmp cx, di
jb .loop ; => continue
ret
; ds: region_1
; es: region_2
; dx: len_regions
; ax: result
mem_equals:
push bx
push cx
push dx
push di
xor cx, cx
mov di, dx
; ax: first region's value
; bx: address at index
; cx: byte_index
; dx: second region's value
.loop:
mov bx, cx
mov dx, [bx]
; swap the two segments
; here, ax and bx are used differently.
mov ax, es
mov bx, ds
mov ds, ax
mov es, bx
mov bx, cx
mov ax, [bx]
cmp ax, dx
; swap the two segments back
mov ax, es
mov bx, ds
mov ds, ax
mov es, bx
; jump accordingly to the comparison above
jne .not_equal
inc cx
cmp cx, di ; if the loop needs to continue
jb .loop ; (if the end is NOT reached yet)
; it goes here if the two regions are completely equal
pop di
pop dx
pop cx
pop bx
mov ax, 1
ret
.not_equal:
pop di
pop dx
pop cx
pop bx
mov ax, 0
ret
; ax: start_sector (lower) ; ax: start_sector (lower)
; bl: start_sector (upper) ; bl: start_sector (upper)
; cx: sector_count ; cx: sector_count
@ -14,28 +211,40 @@ load_sectors:
push bx push bx
push cx push cx
push dx push dx
push si
xor si, si ; current sector index xor si, si ; current sector index
; sets the arguments for the first run of '.load_data'
; which loads until the first CHS - cylinder boundary
.set_first_load_args:
; the first read only reads up to the next cylinder boundary,
; but potentially less (if not that many sectors have been requested)
; TODO================================================================================
mov bx, sp
add bx, 4
mov cx, [bx] ; get sector count
sub cx, si ; cx = num_missing_sectors
mov bx, sp ; calculate the distance (in sectors) to the next cylinder boundary
mov bx, [bx]
cmp cx, bx ; get the index of the current cylinder
js .load_data ; if there are more sectors needed after the 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:
; 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 ; next cylinder boundary
; if the number of sectors
; which are wanted (sector_count) is above the
; distance to the next cylinder boundary
; if not that many sectors are needed, just read as ; if not that many sectors are needed, just read as
; many sectors as are needed in total ; many sectors as are needed in total
mov cx, bx mov cx, bx
@ -53,22 +262,26 @@ load_sectors:
mov cx, [bx] mov cx, [bx]
sub cx, si ; cx = num_missing_sectors sub cx, si ; cx = num_missing_sectors
cmp cx, 64 cmp cx, 63
js .load_data jbe .add_num_missing_sectors_to_sector_index
; if this goes here, there are more than 64 sectors missing
; -> clamp them to 64 so they can be loaded. ; if this goes here, there are more than 63 sectors
mov cl, 64 ; still missing to be loaded
jmp .load_data ; redundant ; -> 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 ; loads at most 64 sectors from the disk into the main memory
; ax: scratchpad ; ax: scratchpad
; bx: start_sector (low part) ; bx: start_sector (high part)
; ch: start_sector (high part) ; ch: start_sector (low part)
; cl: num_sectors ; cl: num_sectors
.load_data: .load_data:
mov bx, sp
mov ah, 0x02 mov ah, 0x02
mov al, cl mov al, cl
mov dl, [bx] ; drive mov dl, [bx] ; drive
@ -86,12 +299,13 @@ load_sectors:
mov cx, [bx] ; sector_count mov cx, [bx] ; sector_count
cmp si, cx cmp si, cx
js .set_load_args jb .set_load_args
.epilog: .epilog:
pop si
pop dx pop dx
pop cx pop cx
pop bx pop bx