NASM - The Netwide Assembler

NASM Forum => Example Code => Topic started by: dreamaco on August 17, 2011, 02:55:10 PM

Title: Loading from floppy using no DIV/MUL
Post by: dreamaco on August 17, 2011, 02:55:10 PM
Lots of people wants Floppy CHS example, here's one example
If using a modern computer and having no special demands, LBA is often preffered.
But CHS an easy way to load huge things from floppy without compability problems.
It loads single sector at a time to overcome any compability problems
And abit overly long due to the DIV/MUL criteria.

; Example loading 512KB worth data from floppy into memory starting at 7E00.
; This is old code digged up but supposedly perfectly and nicely working, and 94 bytes long.
;
; This example is a loader that doesn't use any multiply or divide instructions (as an excercise in using only simple math instructions in any dialect of asm).
;
; DL should contain drive (if this code is run at boottime it's already set by BIOS to the booted drive).
; Note if you make changes for different geometrics then also think of that tracks higher than 255 needs abit more work as highest two bits of track/cylinder is in CL.

loadsectors:
reset:
            xor ax,ax
            int 13h
            jc reset
            push word 07e0h
            pop es
            xor bx,bx
read:
            mov ah,2
            mov al,1
            mov cl,[sector]
            mov ch,[track]
            mov dh,[side]
            int 13h ; loads 1 sector into memory at a time.
            jc read
            mov ax,es
            add ax,20h ; Actually adds 512 bytes by increasing the memory segment, and now we're ready for loading the next sector.
            mov es,ax
            cmp ax,0x87e0 ; SET HERE HOW MUCH TO LOAD. E.g.(1024 sectors a' 512 bytes) + 7E00(startaddress) = 87e00. This loads 512KB worth data into memory starting at 7E00.
            je finished
            inc byte [sector]
            cmp byte [sector],18+1 ; 18 (floppy), 63 (common for HDs but check geometrics to be sure)
            je resetsector
            jmp read
            resetsector:
            mov byte [sector],1
            inc byte [side] ; increase (flip) side
            cmp byte [side],1+1 ;FLOPPY=1 (meaning 2 sides, 0 and 1) , Possible values are 1-255. Note always keep the + 1 and  also even if 255 the code uses byte wrapping 255+1 = 256  = 0, to make loop correct without rearrangeing the code itself)
            jne read
            mov byte [side],0
            inc byte [track]
            jmp read
finished:
ret

; Where to start load from
track:  db 0 ; Start track aka cylinder
side:   db 0 ; Start side aka head
sector: db 2 ; Start sectors in (CHS starts at 1 not 0) e.g. sector 1 contains bootsector, 2 would be the imm. following one.