125 lines
No EOL
3.5 KiB
NASM
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 |