os3/mbr/mbr.asm
2022-09-24 22:30:25 -04:00

125 lines
No EOL
3.5 KiB
NASM

USE16
NULL equ 0
section .text
global _main
_main:
JMP entry
; FAT32 Header.
global fat_header
fat_header: times 87 db 0
; function READ_SECTORS_EXTENDED: Read sectors from disk
; Uses INT 13h AH=42h from: http://www.ctyme.com/intr/rb-0708.htm
; Stack Parameters (in order of PUSH):
; - BYTE: Drive number
; - WORD: Number of blocks to transfer
; - DWORD: Transfer buffer
; - DWORD: Partial LBA of first block to transfer
; - WORD: RETURN ADDRESS
; Returns:
; AX: 0 = Ok, Other = Error
;
;
; SP + 0: Old BP
; SP + 2: Old SI
; SP + 4: Old DX
; SP + 6: return address
; SP + 8: LBA
; SP + 12: Transfer buffer
; SP + 16: Block
; SP + 18: Drive number
read_sectors_extended:
PUSH DX ; save DX
PUSH SI ; save SI
PUSH BP ; save BP
MOV BP, SP ; estabilish stack frame
MOV AX, [BP + 10] ; load first part of LBA address
MOV [packet_lba], AX ; write fist part of LBA to packet
MOV AX, [BP + 8] ; load second part of LBA to packet
MOV [packet_lba + 2], AX ; write second part of LBA to packet
MOV AX, [BP + 14] ; load first part of transfer buffer
MOV [packet_buffer], AX ; write first part of transfer buffer
MOV AX, [BP + 12] ; load second part of transfer buffer
MOV [packet_buffer + 2], AX ; write second part of transfer buffer
MOV AX, [BP + 16] ; load number of blocks
MOV [packet_blocks], AX ; write number of blocks
MOV DX, 0 ; zero-out DX
MOV DL, [BP + 18] ; load drive number
MOV SI, read_sectors_packet ; load address of packet
MOV AX, 4200h ; set AH to 42h, AL to 0h
INT 13h ; call interrupt 13H, AH=42h
JNC read_sectors_extended_exit ; exit if no error
read_sectors_extended_error: ; save error if it happened
MOV AL, AH ; move error to Al
MOV AH, 0 ; zero-out AH
read_sectors_extended_exit: ; leave function
POP BP ; restore BP
POP SI ; restore SI
POP DX ; restore DX
; function PRINT: teletype to display
; uses INT 10h AH=0Eh from: http://www.ctyme.com/intr/rb-0106.htm
; parameters (in order of PUSH):
; - WORD: address of string
; - WORD: size of string
; returns:
; AX: 0
print:
PUSH BX ; save BX
PUSH CX ; save CX
PUSH BP ; save BP (can change due to scrolling)
MOV BP, SP ; set up stack frame
MOV AH, 0Eh ; load INT 10h parameter
MOV BX, 0 ; zero-out BX (extra parameters)
entry:
; Set up stack and segments
MOV AX, 0 ; set up stack segment
MOV SS, AX ; ^^^
MOV SP, 0x7C00 ; set up stack pointer (0x6c00-x7BFF)
; Sp HAS TO be set in the instruction after settings SS
; as setting SS disables interrupts for the next instruction
; Not doing this may cause an interrupt to use an old SP and new SS
MOV DS, AX ; set up segment registers
MOV ES, AX ; ^^^
MOV FS, AX ; ^^^
MOV GS, AX ; ^^^
PUSH DX ; save drive number (DL)
; Load drive parameters
MOV AX, 4800h ; load AH=48h, AL=0h
MOV SI, disk_info_packet ; load address of Disk_Info_Packet
INT 13H ; INT 14h AH=48h: get drive parameters
section .data
disk_info_packet:
info_size dw 0x1A
info_flags dw 0x0
info_cyls dd 0x0
info_heads dd 0x0
info_sectors dd 0x0
info_total_sec dq 0x0
info_bps dw 0x0
read_sectors_packet:
packet_size db 10h
packet_reserved db 0h
packet_blocks dw 0h
packet_buffer dd 0h
packet_lba dq 0h
build_settings:
build_settings_magic_0 dd 0x49494949
build_settings_bytes dw 0x0
build_settings_magic_1 dd 0x49494949