added some code to read from disk
This commit is contained in:
+126
-3
@@ -71,16 +71,139 @@ main:
|
||||
mov ss, ax
|
||||
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
|
||||
mov si, msg_hello
|
||||
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:
|
||||
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
|
||||
dw 0AA55h ; BIOS requires last two bytes of first sector to be AA55
|
||||
|
||||
Reference in New Issue
Block a user