8086 Bootloader Bug
Posted: Mon Jul 25, 2011 8:45 pm
I'm writing a small operating system for an old Tandy 1100 hd i found in my attic. It only has an 8086 processor, so I'm a little restricted in what assembly instructions I can use, but I've managed to make the simple bootloader/picokernel below. I know it's a stupid idea to put a kernel (or at least its core) in the boot loader, and I know it's a stupid idea to make up my own filesystem instead, but I don't want to hear any complaints about that. I have good reasons for my stupidity, and what I'd really like is just a little help with a bug I've encountered.
On line 98,, my code hangs. It doesn't even execute the next line (I tried replacing it with a little int 13h code to write to the screen, but it didn't do anything. It did on the previous line). At first I thought it may be dividing by zero, but if you look at my data section at the top, there's absolutely no way SectorsPerTrack could be zero.
I'm relatively new to assembly. Can anyone tell me what's going wrong?
On line 98,
Code: Select all
div byte[SectorsPerTrack]
I'm relatively new to assembly. Can anyone tell me what's going wrong?
Code: Select all
[BITS 16]
[ORG 0x07c0]
jmp short start
nop
OSLabel db "DSKOS1.0"
NumberOfFiles dw 1
NumberOfExtends dw 0
NumberOfEntries dw 1
BytesPerSector dw 512
TotalSectors dd 2880
TracksPerHead db 80
SectorsPerTrack db 18
Heads dw 2
MediaDescriptor db 0F0h
SectorOffset dw 1
DriveNumber db 0
VolumeLabel db "DSKOS "
FileSystem db "DSKFS1.0"
start:
mov ax, cs ;Setup segments
mov ds, ax
mov es, ax
mov [DriveNumber], dl
cli ;Setup stack
mov ax, 0
mov ss, ax
mov sp, 7BFFh
sti
mov bx, filelist ;Load filelist intial sector
mov ax, 1
call readSector
mov bx, filelist ;Load the rest of the filelist
xor ax, ax
mov si, filelist_name
call getFileInfo
mov cx, bx
mov dl, [DriveNumber]
call loadFileSections
prompt:
mov ax, 0050h
mov es, ax
mov al, ">"
xor di, di
readCharacter:
push di
mov ah, 0Ah
mov bh, 0
mov cx, 1
int 10h
pop di
mov ah, 00h
int 16h
mov byte[di], al
inc di
cmp al, 0Dh
jne readCharacter
dec di
mov byte[di], 0Ah
mov ax, es
mov ds, ax
mov ax, 0000h
mov si, ax
call getFileInfo
mov cx, bx
mov dl, [DriveNumber]
xor bx, bx
call loadFileSections
xor bx, bx
jmp bx
getSectorNumber: ;ax = FileNumber, bx = SectionNumber; returns ax = SectorNumber
mov cx, ax
add cx, bx
.loop:
add ax, cx
dec cx
cmp cx, 0
jne .loop
add ax, [SectorOffset]
ret
readSector: ;ax = Sector, dl = Drive; reads to es:bx
div byte[SectorsPerTrack]
mov cl, ah ;needs later improvement
and cl, 00111111b
xor ah, ah
div byte[TracksPerHead]
mov ch, ah
mov dh, al
mov al, 01h
mov ah, 02h
int 13h
ret
getFileInfo: ;si = Filename; returns ax = FileNumber, bx = FileSize, cl = FilePrivelage
mov bx, filelist
.loop:
xor cx, cx
add bx, 4
push si
sub si, 1
.cmpstr:
inc cx
inc si
inc bx
cmp byte[bx], 0Ah
je .eos
mov al, byte[bx]
cmp byte[si], al
je .cmpstr
.movetoend
inc bx
cmp byte[bx], 0Ah
jne .movetoend
inc bx
pop si
jmp .loop
.eos:
mov al, byte[bx]
cmp byte[si], al
je .found
pop si
jmp .loop
.found:
sub bx, cx
mov cl, byte[bx]
sub bx, 4
mov ax, word [bx]
add bx, 2
mov bx, word [bx]
pop si
ret
loadFileSections: ;ax = FileNumber, cx = FileSize, dl = DriveNumber; reads to es:bx, cx = SectorsRead
push bx
mov bx, cx
call getSectorNumber
pop bx
cmp ax, [TotalSectors]
jg .done
call readSector
inc cx
jmp loadFileSections
.done:
ret
times 510-($-$$) db 0
db 0x55
db 0xAA
filelist:
filelist_number dw 0
filelist_size dw 2
filelist_privelage db 0
filelist_name db "filelist"
db 0Ah