(also, are you sure the destination is denoted by ES:BX?)
Yes, I use the interrupt int $0x13 for load the sectors from the floppy!
AH = 02h
AL = number of sectors to read (must be nonzero)
CH = low eight bits of cylinder number
CL = sector number 1-63 (bits 0-5)
high two bits of cylinder (bits 6-7, hard disk only)
DH = head number
DL = drive number (bit 7 set for hard disk)
ES:BX -> data buffer
Do you correctly preserve registers? Did you check the values before each int call to make sure they match what you expect them to be? You know that registers may be modified by a bios call?
Yes, yes, yes!
The problem is this instruction :
addw $512, %bx .
Now, I have understand this solution :
Code: Select all
movw %es, %ax #
movw %ax, %es # each new switch is given by the previous plus 512 / 16 ( 32)
addw $0x20, %ax # add 32 to %ax
movw %ax, %es #
When the processor is on the real mode state, the memory is great 1MB and it is partition on 64K segments ! Right?
Then each segment is large 16 byte , therefore to have an offset of 512 can add 32 to the register es!!
Yet it should be right also my solution!
Code complete :
Code: Select all
.code16 # Necessario per eseguire il codice in modo reale
.set SEG_BOOT, 0x07c0
.set INIT_STACK, 0x0400
.set SEG_DEST, 0x0800
.set DIM_MODULO, 20 # settori del modulo
.text
movw $SEG_BOOT, %ax # caricamento di valori noti nei registri
movw %ax, %ds # selettore
movw %ax, %es
cli # interruzioni disabilitate nel cambiamento
# di pila
movw %ax, %ss
movw $INIT_STACK, %sp # pila iniziale a 0x07c0:0400, cioe'
# 512 byte dopo la fine del settore
# di avviamento in memoria
sti
movw $mess, %si # indirizzo del primo carattere del messaggio
# in si
# impostazione parametri int 0x10:
movb $0x0e, %ah # servizio stampa carattere
movb $0, %bh # numero di pagina
nuovo_car:
lodsb # carica il carattere in al
cmpb $0, %al # verifica se e' l' ultimo
je fine_str
int $0x10 # lo stampa
jmp nuovo_car
fine_str:
call carica # carica il modulo da floppy
call spegni # spegne il motore del floppy
ljmp $SEG_DEST, $0 # salto al modulo appena caricato
#
# Caricamento del modulo
# (non si salvano i registri)
da_leggere: .word DIM_MODULO
carica:
xorw %ax, %ax # reset del controllore del floppy
xorw %dx, %dx
int $0x13
movw $SEG_DEST, %ax # in es il segmento di destinazione
movw %ax, %es
movw $0x0002, %cx # la lettura inizia dal secondo settore
# del primo cilindro (i settori sono
# contati da uno, cilindri e testine da
# zero)
movw $0x0000, %dx # prima testina del drive zero (primo floppy) dh=0 testina zero
nuovo_sett:
movw $0x0201, %ax # lettura di un settore numero di settori da leggere
xorw %bx, %bx # azzeramento offset mette il settore su %es:%bx quindi bx è l'offeset
int $0x13
# jc errore_di_lettura # cf=1 indica un errore in lettura
decw da_leggere # decremento del contatore
cmpw $0, da_leggere
je fine_car
#movw %es, %ax # incremento del selettore in es:
#addw $0x20, %ax # ogni lettura si avanza di 512 byte, il perchè?????
#movw %ax, %es # nuovo selettore e' dato dal precedente
# piu' 512/16 = 32
addw $0x0200, %bx
incb %cl # incremento il settore
cmpb $18, %cl # se arrivo al 18-esimo devo cambiare testina ogni traccia e data 18 settori
jbe nuovo_sett
xorb $1, %dh # cambio di testina # metto la testina uno
movb $1, %cl # riprende a leggere dal primo settore
jnz nuovo_sett # xor e' l' ultima istruzione a modificare
# eflag, se la testina e' tornata 0
# e' necessario cambiare anche cilindro
# (non salta)
incb %ch # incremento del cilindro
jmp nuovo_sett
fine_car:
ret
#
# Spegnimento del motore del floppy tramite il controllore
#
spegni:
movw $0x3f2, %dx
movb $0, %al
outb %al, %dx
ret
mess: .asciz "Caricamento in corso"
.org 510
sign: .byte 0x55 # signature per un settore di avviamento valido
.byte 0xaa
this address 0x0800:0x0200 identify the same cell of memory of this address 0x0820:0000! Right?