Hallo,
ich versuche die ganze Zeit über Ports und dem IRQ14 Daten auf Sektore einer Festplatte zu schreiben. Dafür nehme ich mein altes Notebook. Ich habe Win95 installiert und mir die Ressourcen des Festplattencontrollers angeschaut. Dort steht wie erwartet: IRQ14, Ports 1F0h - 1F7h etc. Dann wandelte ich den Spaghetti Code (in C/C++ geschrieben) von meinem PC Hardwarebuch in Assembler Code um. Da ich 4 Sektore schreibe, soll der IRQ14 auch vier mal aufgerufen werden. Aber bei mir wird er nur ein einziges mal aufgerufen. Ich verstehe das einfach nicht. Schließlich sende ich ja am Ende einen EOI. Könnt ihr mir vielleicht weiter helfen. Das ist ein Bootsektor-Code den ich assembliere (mit fasm), auf Diskette kopiere und mein altes Notebook von dieser starten lasse. Hier der Code:
org 0
cli
mov ax,07C0h
mov ds,ax
mov es,ax
xor ax,ax
mov ss,ax
mov sp,7BFEh
sti
mov si,SetIRQ14Msg
call WriteMsg
push es
cli
xor ax,ax
mov es,ax
mov ax,07C0h
shl eax,16
mov ax,int76h ;IRQ14
mov [es:76h*4],eax
sti
pop es
mov si,WriteSectorsMsg
call WriteMsg
cli
.1:
mov dx,1F7h
in al,dx
test al,80h
jnz .1
mov al,4 ;Sektoranzahl
mov dx,1F2h
out dx,al
mov al,0 ;Sektornummer
mov dx,1F3h
out dx,al
mov al,0 ;Spur LSB
mov dx,1F4h
out dx,al
mov al,0 ;Spur MSB
mov dx,1F5h
out dx,al
mov al,10100000b ;DRV=0, Head = 0
mov dx,1F6h
out dx,al
mov al,00110011b ;command for write sectors
mov dx,1F7h
out dx,al
;warte bis bereit
.2:
mov dx,1F7h
in al,dx
test al,80h
jnz .2
test al,08h
jz .2
;schreibe ersten Sektor (erst danach sollte immer ein IRQ14 aufgerufen werden)
mov cx,512/2
mov si,WPuffer
mov dx,1F0h
rep outsw
mov cx,4
mov si,BPuffer
;mov dx,1F0h
rep outsb
sti ;jetzt können die IRQs kommen
.3:
cmp [int_count],4
jb .3 ;warte auf die restlichen IRQ14 <- hier bleibt der hängen da nur einmal der IRQ14 aufgerufen wird
mov si,FinishMsg <- wird nie ausgeführt
call WriteMsg
jmp $
int76h: <- Code des IRQ14, wird nur einmal ausgeführt
cmp [int_count],4
ja .1
inc [int_count]
mov cx,512/2
mov si,WPuffer
mov dx,1F0h
rep outsw
mov cx,4
mov si,BPuffer
;mov dx,1F0h
rep outsb
.1:
mov al,20h <- extra am EOI gedacht
out 20h,al
out 0A0h,al
iret
WriteMsg:
lodsb
or al,al
jz .1
mov ah,0Eh
int 10h
jmp WriteMsg
.1:
ret
SetIRQ14Msg db "Initialisiere den IRQ14 neu...",0
WriteSectorsMsg db 13,10,"Schreibe die Sektoren...",0
FinishMsg db 13,10,10,"Ende...",0
WPuffer: <- nur Testdaten (muss eigentlich 512 Byte groß sein, aber da kein Platz, ist ja egal)
dw 0AA55h
BPuffer:
times 4 db 22h
int_count db 0
times 510-($-$$) db 0
dw 0AA55h
Also ich bin mit mein Latein am Ende. Aber vielleicht wisst ihr ja was falsch ist.
thx
bitmaster