La rutina de manejo de interrupciones en modo real no funciona como se esperaba
Logré cargar un pequeño núcleo en la memoria a través de un cargador de arranque que realiza un salto lejano a0x0090:0x0000
. El núcleo se carga correctamente cuando imprimo un personaje desde allí para probarlo y funciona correctamente.
Quería reasignar interrupciones0x08->0x0F
y0x70->0x77
para interrumpir0x20->0x2F
, por lo que las interrupciones de excepción / reservadas no se superponen. Hasta ahora, solo manejo una pulsación del teclado e intento imprimirlo en la pantalla.
Lo revisé varias veces y, por alguna razón, no sé por qué, pero no sucede nada cuando presiono una tecla.
El mapa de teclas es solo una matriz de códigos de escaneo para su valor ASCII respetado.
Si esto es de alguna ayuda: probé ejecutando un bucle e imprimiendo un personaje y luegoHLT
ing, y una vez que se imprimieron 2 caracteres, se colgó. Me aseguré de habilitar las interrupciones.
(Estoy cargando 4 sectores (del sector 2 al sector 5) para el gestor de arranque, por eso estoy rellenando esto para que tenga un tamaño de 2048 bytes).
Por cierto, no tengo queCLI
en mis procedimientos de interrupción ya que está hecho para mí, ¿verdad? Recuerdo haber leído esto, pero no estoy muy seguro.
BITS 16
ORG 0x0000
; Setup Segments ;
cli
cld
mov ax, cs
mov ds, ax ; this program was far-jumped to (0x0090:0x0000) so ds = cs = 0x0090
mov ax, VIDEO_ORIGIN
mov es, ax
; Remap PIC Interrupt Vector Offsets to 0x20 -> 0x35 ;
remapInterrupts:
; Send Initialization Command (expecting ICW4)
mov al, 0x11
out 0x20, al
out 0xA0, al
; Remap Vector Offsets (ICW2)
mov al, 0x20 ; Master IRQ lines mapped to 0x20 -> 0x27
out 0x21, al
mov al, 0x28 ; Slave IRQ lines mapped to 0x28 -> 0x2F
out 0xA1, al
; Set Cascade Lines between Master and Slave PICs (ICW3)
mov al, 0x04 ; 00000100 (line 2)
out 0x21, al
mov al, 0x02 ; 00000010 (line 2 in binary, cascade identity)
out 0xA1, al
; Set 80x86 Mode (ICW4)
mov al, 0x01
out 0x21, al
out 0xA1, al
; Set Masks
mov al, 0xFD ; 11111101 (keyboard)
out 0x21, al
mov al, 0xFF ; 11111111
out 0xA1, al
setInterrupts:
push ds
mov ax, 0x0000
mov ds, ax
mov [ds:0x84], word interrupt21 ; 0x84 = 0x21 * 4
mov [ds:0x86], cs
pop ds
jmp start
interrupt20: ; Programmable Interval Timer
; NOT SUPPORTED, place holder
push ax
mov al, 0x20
out 0x20, al
pop ax
iret
interrupt21: ; Keyboard
push ax
push bx
in al, 0x60
test al, 0x80 ; high-bit set = keyup = don't print
jnz .finish
movzx bx, al
mov al, [keymap + bx]
mov ah, 0x07
stosw
.finish:
mov al, 0x20
out 0x20, al
pop bx
pop ax
iret
interrupt22: ; Slave Cascade
interrupt23: ; COM2 / COM4
interrupt24: ; COM1 / COM3
interrupt25: ; LPT2
interrupt26: ; Floppy controller
interrupt27: ; LPT1
; NOT SUPPORTED, place holder
push ax
mov al, 0x20
out 0x20, al
pop ax
iret
interrupt28: ; RTC
interrupt29: ; Unassigned
interrupt2A: ; Unassigned
interrupt2B: ; Unassigned
interrupt2C: ; Mouse Controller
interrupt2D: ; Math Coprocessor
interrupt2E: ; Hard Disk Controller 1
interrupt2F: ; Hard Disk Controller 2
; NOT SUPPORTED, place holder
push ax
mov al, 0x20
out 0xA0, al
out 0x20, al
pop ax
iret
start:
sti
xor di, di
jmp $
; --- CONSTANTS --- ;
VIDEO_ORIGIN EQU 0xB800
; --- DATA --- ;
drive db 0
keymap:
db 00h, 1Bh, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 08h, 09h
db 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 00h, 00h
db 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', "'", '`', 00h, '\'
db 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 00h, 00h, 00h, ' ', 00h,
db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h,
db '-', 00h, 00h, 00h, '+', 00h, 00h, 00h, 00h, 00h
times 2048 - ($ - $) db 0