Boot sector problems...



Hello all,
I am having very odd, peculaiar and strange problems with my
bootsector. I do not know how to explain the problem since it seems to
be illogical, but when I comment out two lines of source code,
everything works fine.
The lines commented out are:
;Begin ASM Code
cmp bl,0x04
jne cont
;End ASM code
They are located just unde the label 'read_sector_anim'. I have
included a copy of the file with this post. Since I do not know which
sections of code are causing the problems, I will post the entire file
(approx 7K).
I'm realy sorry if the error is a really stupis one (i'm only an
intermediate!), and for the uncommented source code.
Help would be gratefully appreciated.
Cheers,
Mr. Linux Guy

PS: My kernel is actually more complicated than that, it's just that
instead of making people compile the kernel as well, I just made a
simple one for testing purposes. However, it does work.
When you compile the file, you can choose to either make it a 'true'
floppy image(1.44M) or a 'fake' one(Size depend on what is storeds in
it). See the bottom of the code).
I tested this with bochs 2.3, and with the code commented out, it
worked fine, and with the code included, no 'e' showed up (problem!). I
also tried it on my real computer, and had the same results (so bochs
was not buggy).

;; BEGIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

KRNLSIZE EQU 0x100 ; Kernel size (in 512 byte sectors)
KRNL16 EQU 0x1000; 1000:0 ; where the kernel is loaded (16-bit mem)
KRNL32 EQU 0x10000 ; where the kernel is loaded (32-bit mem)

[BITS 16] ; tells the assembler that this is 16 bit
[ORG 0x7C00] ; tells the assembler where we start
; (Bios loads us there)

jmp start ; jump to our main code segment, or else we
; execute the data (horrific results)

;; Data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

loading db 'Loading The OS',0 ; Tells user we're loading
gdtidt db 'Setting up GDT,IDT ',0 ; Tells user we are setting up idt
and gdt
prog db '-\|/',0 ; for the floppy animation :-)
plus db '+',0 ; for the box
dash db '-',0 ; for the box as well

;; Subroutines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; Prints a message by loading the memory location of the message into
si
; then using the bios teletype functin to typpe it, untill a 0 is
encountered
; at the end of the string.

print_message: ; prints a message
pusha ; save (push) all the registers!
mov ah,0x0E ; Tells the bios I want teletype function
string_loop: ; Writing the actuall string
lodsb ; load byte ds:si -> al (remember mov si,msgloc)
cmp al,0x0 ; compare al to 0 (termination byte of string)
je end_string ; if al = 0, then jump to end_string
int 0x10 ; call bios video interrupt (input: al,ah)
jmp string_loop ; string not yet finished, continue to write
end_string: ; if we get here, our string had ended
popa ; so we pop back all registers
ret ; and return to the caller

; Draws the pretty box that you see around the Nicotsoft OS loading
message
; It first prints the message, then the four pluses that make the
corners, then
; it draws the top bar and the bottom bar. It may be difficult to
undestand as
; it used cope optimistaion! It changes the cursor position many times,
so
; that's why there are many mov dh's and dl's, as well as int 0x10


draw_the_box: ; This drwas the 'box' around the message
pusha ; push the registers
mov ah,0x02 ; tells the bios I want to change cursor pos.
mov dh,12 ; new cursor position (row)
mov dl,29 ; new cursor position (col)
int 0x10 ; call bios video interrupt (input: ah,dh,dl)
mov si, loading ; mov si to mem location of loading (1st byte)
call print_message ; call the print_message (print 'loading' msg)
mov dh,11 ; new cursor pos (row)
mov dl,28 ; new cursor pos
int 0x10 ; call Bios video interrupt (input ah,dh,dl)
mov si,plus ; move the mem location of the plus msg into si
call print_message ; print the plus sign (for the box corners)
mov dl,53 ; new cursor pos (col)
int 0x10 ; call bios video interrupt (input ah,dh,dl)
call print_message ; print the plus on 2nd corner
mov dh,13 ; new cursor pos (row)
int 0x10 ; call bios video interrupt (input ah,dh,dl)
call print_message ; print yet another plus sing (on 3rd corner)
mov dl,28 ; new cursor pos (col)
int 0x10 ; call bios video interrupt (input ah,dh,dl)
call print_message ; prints the last plus sing (4th corner)
draw_two_bars: ; draws the top and bottom bars
mov dh,11 ; new cursor pos, row above the msg for top bar
mov dl,29 ; new cursor pos (col) (where we start)
mov si,dash ; we will use the dash to draw the bars
mov al,0x02 ; used to draw the bottom bar later on
the_bars: ; draws both bars
int 0x10 ; call bios video interrupt (input ah,dh,dl)
call print_message ; we now print our message
inc dl ; increase cursor col by one
cmp dl,53 ; 53 is end of the bars, so if it is not equ...
jne the_bars ; jump to the_bars and continue writing!
mov dh,13 ; we finished w/the top bar, so we do the bot.
mov dl,29 ; we put the cur col back to the start of th bar
dec al ; we dec al, so next time (after bot bar)
jnz the_bars ; we do not jump to the bar writing routine
popa ; but pop back all registers
ret ; and return to the caller

;; Main Code Segment - 16 Bits
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

start:
mov ax, 0x0
mov ss, ax
mov ds, ax
mov ax, 0x7C00
mov sp, ax

mov si, KRNLSIZE
mov ax, KRNL16
mov es, ax
mov ax, 0x0
mov bx, ax
mov cx, 0x0002
mov dx, ax
push si

push ax
mov al, 0x03
mov ah, 0x0
int 0x10
pop ax
call draw_the_box

mov bx,0
pop si
read_sector_anim:
pusha
mov ah,0x02
mov dh,12
mov dl,51
int 0x10
popa
inc bl
;cmp bl,0x04
;jne cont
mov bl,0
cont:
pusha
mov ah,0x0A
mov al,[prog+bx]
mov cx,1
push bx
mov bl,0
int 0x10
pop bx
popa

read_sector:

mov ax, 0x0201
int 0x13
mov ax, es
add ax, 0x20
mov es, ax
dec si
jz end_of_read
inc cl
cmp cl, 0x12
jbe read_sector
mov cl, 1
inc dh
cmp dh, 2
jne read_sector_anim
mov dh, 0
inc ch
jmp read_sector_anim

end_of_read:
pusha
mov al, 0x0C
mov dx, 0x3F2
out dx, al
popa
A20_1:
in al, 0x64
test al, 2
jnz A20_1
mov al, 0xD1
out 0x64, al
A20_2:
in al, 0x64
and ax, byte 2
jnz A20_2
mov al, 0xDF
out 0x60, al

pusha
mov ah,0x02
mov dh,12
mov dl,29
int 0x10
mov si,gdtidt
call print_message
popa
cli

lgdt [gdt_temp] ; Load the GDT
lidt [idt_temp] ; Load the IDT
mov eax, cr0 ; move CR0 into eax
or eax,1 ; or it by 1
mov cr0, eax ; put the results back into CR0
jmp 0x8 : protected_mode ; jump into protected mode!

;; Main Code Segment - 32 Bits (Protected mode)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[BITS 32]
protected_mode: ; this is protected mode segment

mov ax,0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov bx, 0
mov ss, ax
mov esp, 0xA0000
jmp 0x8:KRNL32 ; we jump and pass control over to the kernel.

idt_temp:
dw 0x0
dd 0x0

gdt_temp:
dw gdt_end - gdt - 1
dd gdt
gdt:
gdt_null:
dd 0x0
dd 0x0
gdt_code:
dw 0x0FFFF
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data:
dw 0x0FFFF
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end:


TIMES 510 - ($-$$) DB 0 ; fil the rest with 0's
DW 0xAA55 ; bootsector signature (who coined AA55 anyway?)
; ; this is 'sector one' of the floppy
mov byte [0x0B8000],'e' ; puts e in the upper left corner (0,0)
mov byte [0x0B8001],0x0F ; make e a white char on a black background
jmp $

; TIMES 1474560-($-$$) DB 0 ; uncomment this line if you need to make a
floppy image that has the same size as a real one.
;; END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.



Relevant Pages