added some code to read from disk

This commit is contained in:
wes
2023-08-21 13:05:17 -04:00
parent 2b49fe3a8b
commit 1d349f2f23
+126 -3
View File
@@ -71,16 +71,139 @@ main:
mov ss, ax mov ss, ax
mov sp, 0x7c00 ; stack will grow downwards in memory as it is filled mov sp, 0x7c00 ; stack will grow downwards in memory as it is filled
;; read something from floppy disk
;; BIOS should have placed drive number in dl
mov [ebr_drive_number], dl
mov ax, 1 ; LBA=1 start reading at first sector after bootloader
mov cl, 1 ; read 1 sector
mov bx, 0x7E00 ; data should be read into memory after the bootloader
call disk_read
;; print message ;; print message
mov si, msg_hello mov si, msg_hello
call puts call puts
hlt ; stop executing cli
hlt
floppy_error:
mov si, msg_read_failed
call puts
jmp wait_key_and_reboot
wait_key_and_reboot:
mov ah, 0
int 16h ; wait for keypress
jmp 0FFFFh:0 ; jump to begininng of BIOS
.halt: .halt:
jmp .halt ; really make sure we're not executing random shit cli
hlt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Disk Routines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Convert an LBA address to a CHS address
;; Parameters:
;; - ax: LBA Address
;;
;; Returns:
;; - cx[bits 0-5]: sector number
;; - cx[bits 6-15]: cylinder
;; - dh: head
;;
lba_to_chs:
push ax
push dx
msg_hello: db 'Hello Shitass!', ENDL, 0 ; named constant ; Calculate Sector
; div dvides whatever is in ax by the divisor supplied
; ax contains our desired LBA at this point
xor dx, dx ; dx = 0 (dx receives the remainder after a div instruction)
div word [bdb_sectors_per_track] ; ax = LBA / sectors_per_track
; dx = LBA % sectors_per_track
inc dx ; dx = dx + 1 (this is the sector value)
mov cx, dx ; put sector value into cx
; Calculate Cylinder/Head
; ax still contains (LBA / sectors_per_track) at this point
xor dx, dx ; dx = 0
div word [bdb_heads] ; ax = (LBA / sectors_per_track) / heads (this is the cylinder value)
; dx = (LBA / sectors_per_track) % heads (this is the head value)
;; Move calculated values to target registers (cx already contains sector number by now)
mov dh, dl ; dl is the lower 8 bits of dx, this moves the calculated head value to dh
mov ch, al ; ch = cylinder (lower 8 bits)
shl ah, 6
or cl, ah ; put upper 2 bits of cylinder in CL
pop ax
mov dl, al ; restore whatever was in dl prior to this. dh needs to have the calculated head value
pop ax
ret
;; Reads sectors from a disk into memory
;; Parameters:
;; - ax: LBA Address
;; - cl: number of sectors to read (128 max)
;; - dl: drive number
;; - es:bx: memory address where to store data
disk_read:
push ax
push bx
push cx
push dx
push di
push cx ; save number of sectors to read to stack (lba_to_chs uses cx)
call lba_to_chs ; calculate CHS
pop ax ; restore number of sectors to read into ax, cx contains sector and cylinder, dh contains head
mov ah, 02h ; this is required by interrupt 13
mov di, 3 ; retry count
.retry:
pusha ; save all registers, BIOS does what BIOS wants
stc ; explicitly set carry flag to be safe
int 13h ; carry flag cleared = success
jnc .done ; jumo if carry not set
; read failed
popa
call disk_reset
dec di
test di, di
jnz .retry
.fail:
; all retry attempts used
jmp floppy_error
.done:
popa
pop di
pop dx
pop cx
pop bx
pop ax
ret
;; Resets disk controller
;; Parameters:
;; - dl: drive number
disk_reset:
pusha
mov ah, 0
stc
int 13h
jc floppy_error
popa
ret
msg_hello: db 'Hello Shitass!', ENDL, 0 ; named constant
msg_read_failed: db 'Read from disk failed!', ENDL, 0
times 510-($-$$) db 0 ; pad program with zeros up to byte 510 times 510-($-$$) db 0 ; pad program with zeros up to byte 510
dw 0AA55h ; BIOS requires last two bytes of first sector to be AA55 dw 0AA55h ; BIOS requires last two bytes of first sector to be AA55