I suppose BIOS interrupt 8 (timer) should come 18.2 times per second, but it doesn't on qemu. See the following example:
$ cat c.asm
init:
.segments:
mov ax, 0x07C0
mov ds, ax
mov ax, 0
mov fs, ax
.interrupt:
mov [fs:0x08*4], word timer
mov [fs:0x08*4+2], ds
main:
hlt
jmp main
timer:
mov ah, 0x0e
mov al, 0x41
int 0x10
iret
times 510-($-$$) db 0
dw 0xaa55
$ nasm -f bin c.asm -o c.bin && qemu-system-x86_64 c.bin
Qemu window appears, and only one 'A' displayed, not continuously.
What's wrong with my code, if I hope interrupt 8 comings again and again.
I use nasm 1.14.02, qemu 4.2.1 and ubuntu 20.04.
The crucial change to make it display 'A' repeatedly is sending an End Of Interrupt signal to the PIC on port 20h. If you use interrupt 1Ch or chain to another interrupt 08h handler this is not needed in your code. If you replace the interrupt 08h handler entirely though, it is. The PIC won't send another IRQ #0 until the prior one gets an EOI. Because of this I was able to reproduce your problem.
The other changes I did were to insure that the interrupt flag is set before entering the main
loop (with a sti
instruction), and preserving all registers across the interrupt 08h handler (this is optional if your code is the only thing running on the machine).
init:
.segments:
mov ax, 0x07C0
mov ds, ax
mov ax, 0
mov fs, ax
.interrupt:
mov [fs:0x08*4], word timer
mov [fs:0x08*4+2], ds
sti
main:
hlt
jmp main
timer:
push ax
push bx
push bp
mov ah, 0x0e
mov al, 0x41
int 0x10
mov al, 20h
out 20h, al
pop bp
pop bx
pop ax
iret
times 510-($-$$) db 0
dw 0xaa55
Run like so:
$ nasm test.asm
$ timeout 10 qemu-system-x86_64 test -curses