Autor Thema: Calls und IVT  (Gelesen 8116 mal)

Feuermonster

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« am: 01. May 2009, 13:15 »
Hallo,

ich habe versucht einen Handler fuer das Keyboard zu setzen, doch leider klappt dies irgendwie nicht. (keyboard_handler wird nie aufgerufen)

Ein weiteres Problem ist, dass nach dem call show_info der Kernel irgendwie haengen bleibt und ich kann mir nichts ausdenken, was dazu fuehren koennte. Eine unmittelbare Ausgabe auf den Bildschirm nach call show_info funktioniert nicht, d.h das jmp _continue nach call show_info wird gar nicht erst aufgerufen.

Code:

mov ax, 0x1000 ;update segment register...
mov ds, ax
mov es, ax

init0:
mov si,s_noos_init0
call noos_putstr


mov bl, 0x05
mov si, s_noos_logo
call noos_printf
mov bl, 0x02
mov si, s_noos_jmp_good
call noos_printf
call noos_inc_line
call noos_reset_line

mov bl, 0x05
mov si, s_noos_logo
call noos_printf
mov bl, 0x02
mov si, s_noos_step1
call noos_printf
call noos_inc_line
call noos_reset_line


push dx
    push es
    xor ax, ax
    mov es, ax
    cli
    mov word [es:0x21*4], _int0x021 
    mov [es:0x21*4+2], cs         

mov word[ds:(9*4)  ], keyboard_handler    ;Offset
mov word[ds:(9*4)+2], 0                  ;Segment


    sti
    pop es
    pop dx


mov bl, 0x05
mov si, s_noos_logo
mov dl, 0x03
int 0x021


mov bl, 0x02
mov si, s_noos_step2
mov dl, 0x03
int 0x021
mov dl, 0x07
int 0x021
mov dl, 0x08
int 0x021


mov bl, 0x05
mov si, s_noos_logo
mov dl, 0x03
int 0x021


mov bl, 0x02
mov si, s_noos_step3
mov dl, 0x03
int 0x021
mov dl, 0x07
int 0x021
mov dl, 0x08
int 0x021

mov bl, 0x05
mov si, s_noos_logo
mov dl, 0x03
int 0x021


mov bl, 0x02
mov si, s_noos_step4
mov dl, 0x03
int 0x021


mov dl, 0x09
int 0x021

mov bl, 0x06
mov dl, 0x03
int 0x021
mov dl, 0x07
int 0x021
mov dl, 0x08
int 0x021

mov bl, 0x0A
mov si, s_noos_i_info
mov dl, 0x03
int 0x021
mov dl, 0x07
int 0x021
mov dl, 0x08
int 0x021

loopi:
mov ah,00h
int 16h


mov bl,0x08
cmp al,0x31
je do_show_info
cmp al,0x32
je do_calc_test

jmp _continue


do_show_info:
 call show_info
 jmp _continue
do_calc_test:
 call calc_test
 jmp _continue
 
 
_continue:
call noos_putchar
call noos_inc_row
call noos_inc_line
call noos_reset_line
jmp loopi
;Variablen
;========

s_noos_init0 db "Init 0",13,10,0
s_noos_logo db "[ NoOS ]",0
s_noos_jmp_good db  " Jump into kernel successful",0
s_noos_step1 db " Setting up syscalls",0
s_noos_step2 db " Syscalls (INT 0x021) set",0
s_noos_step3 db " Reading from CMOS (Month)",0
s_noos_step4 db " And the month is: ",0
s_noos_keyp db "KEY_PRESSED",0
s_noos_i_info db "Options",13,9,"1.) Show copyright",13,9,"2.) Calc test",0
s_noos_i_autor db "NoOS (c) by Roman Muentener",0
s_noos_i_calc_end db "Calc test done...",0

;Funktionen
;========

calc_test:
 mov cx, 0xFFFF
 calc_test_loop:
   cmp cx,0
   je calc_test_end
   dec cx
   jmp calc_test_loop
 calc_test_end:
   mov bl,0xA8
   mov si,s_noos_i_calc_end
   mov dl,0x03
   int 0x021
  retn

show_info:
 mov bl,0x0D
 mov si,s_noos_i_autor
 mov dl,0x03
 int 0x021
 retn

keyboard_handler:
 mov si,s_noos_keyp
 mov bl,0x02
 mov dl,0x03
 int 0x021
 mov  al, 0x20
 out  0x20, al
 iret

noos_reset_line:
call noos_get_cursor_pos
mov dl,0
call noos_set_cursor_pos
retn

;ret: DL = Spalte; ret: DH = Zeile
noos_get_cursor_pos:
mov ah, 0x03
int 0x10
retn


;DL = Spalte; DH = Zeile
noos_set_cursor_pos:
mov ah, 0x02
push bx
xor bh, bh
int 0x10
pop bx
retn

noos_inc_line:
call noos_get_cursor_pos
inc dh
call noos_set_cursor_pos
retn

noos_inc_row:
call noos_get_cursor_pos
inc dl
call noos_set_cursor_pos
retn

;SI = string
noos_printf:
lodsb
or al,al
jz noos_printf_end
call noos_putchar
call noos_inc_row
jmp noos_printf
noos_printf_end:
retn

;AL = char; BL = Farbe
noos_putchar:
push cx
mov cx, 1
mov ah, 0x09
int 0x10
pop cx
retn

;SI = string
noos_putstr:
lodsb
or al, al
jz noos_putstr_end
mov ah, 0x0E
mov bx, 0x07
int 0x10
jmp noos_putstr
noos_putstr_end:
retn

noos_reboot:
jmp 0xffff:0x0000

noos_getkey:
mov ah,00h
int 0x16
retn


;-------
;Syscalls
;-------


_int0x021:
 cmp dl, 0x01
 je _int0x021_f1
 cmp dl, 0x02
 je _int0x021_f2
 cmp dl, 0x03
 je _int0x021_f3
 cmp dl, 0x04
 je _int0x021_f4
 cmp dl, 0x05
 je _int0x021_f5
 cmp dl, 0x06
 je _int0x021_f6
 cmp dl, 0x07
 je _int0x021_f7
 cmp dl, 0x08
 je _int0x021_f8
 cmp dl, 0x09
 je _int0x021_f9
 iret
 
 ;noos_putstr: SI = string
 _int0x021_f1:
   push dx
   lodsb
   or al, al
   jmp _int0x021_f1_end
   mov ah, 0x0E
   mov bx, 0x07
   int 0x10
   _int0x021_f1_end:
    pop dx
   retn
 
 ;noos_putchar: AL = char, BL = farbe
 _int0x021_f2:
   push dx
   push cx
   cmp al, 0xD
   je _int0x021_f2_newline
   cmp al, 0x09
   je _int0x021_f2_tab
   mov cx, 1
   mov bh, 0x00
   mov ah, 0x09
   int 0x10
   call _int0x021_f4
   jmp _int0x021_f2_end
   _int0x021_f2_tab:
     call _int0x021_f4
call _int0x021_f4
call _int0x021_f4
call _int0x021_f4
jmp _int0x021_f2_end
   _int0x021_f2_newline:
     call _int0x021_f7
call _int0x021_f8
   _int0x021_f2_end:
    pop cx
    pop dx
    retn
   
  ;noos_printf: SI = string, BL = farbe
  _int0x021_f3:
    push dx
    lodsb
    or al,al
    jz _int0x021_f3_end
    call _int0x021_f2
pop dx
    jmp _int0x021_f3
_int0x021_f3_end:
pop dx
retn

  ;noos_inc_row
  _int0x021_f4:
    push dx
    call _int0x021_f5
    inc al
    call _int0x021_f6
pop dx
retn
 
  ;noos_get_cursor_pos: ret: AL = Spalte; ret: AH = Zeile
  _int0x021_f5:
    push dx
    mov ah, 0x03
    int 0x10
mov al,dl
mov ah,dh
pop dx
    retn

  ;noos_set_cursor_pos: ;AL = Spalte; AH = Zeile
  _int0x021_f6:
    push dx
    mov dl,al
mov dh,ah
    mov ah, 0x02
    push bx
    xor bh, bh
    int 0x10
    pop bx
pop dx
retn

  ;noos_inc_line
  _int0x021_f7:
    push dx
    call _int0x021_f5
    inc ah
    call _int0x021_f6
pop dx
retn
 
  ;noos_reset_line
  _int0x021_f8:
    push dx
    call _int0x021_f5
    mov al,0
    call _int0x021_f6
pop dx
retn

  ;noos_get_month
  _int0x021_f9:
    push dx
    mov al,0x08
out 0x70,al
in al,0x71

cmp al,0x01
je _int0x021_f9_jan
cmp al,0x02
je _int0x021_f9_feb
cmp al,0x03
je _int0x021_f9_mar
cmp al,0x04
je _int0x021_f9_apr
cmp al,0x05
je _int0x021_f9_may
cmp al,0x06
je _int0x021_f9_jun
cmp al,0x07
je _int0x021_f9_jul
cmp al,0x08
je _int0x021_f9_aug
cmp al,0x09
je _int0x021_f9_sep
cmp al,0x0A
je _int0x021_f9_oct
cmp al,0x0B
je _int0x021_f9_nov
cmp al,0x0C
je _int0x021_f9_dec

je _int0x021_f9_end

_int0x021_f9_jan:
  mov si,jan
  jmp _int0x021_f9_end
 
_int0x021_f9_feb:
  mov si,feb
  jmp _int0x021_f9_end
 
_int0x021_f9_mar:
  mov si,mar
  jmp _int0x021_f9_end

_int0x021_f9_apr:
  mov si,apr
  jmp _int0x021_f9_end
 
_int0x021_f9_may:
  mov si,may
  jmp _int0x021_f9_end
 
_int0x021_f9_jun:
  mov si,jun
  jmp _int0x021_f9_end
 
_int0x021_f9_jul:
  mov si,jul
  jmp _int0x021_f9_end
 
_int0x021_f9_aug:
  mov si,aug
  jmp _int0x021_f9_end
 
_int0x021_f9_sep:
  mov si,sep
  jmp _int0x021_f9_end
 
_int0x021_f9_oct:
  mov si,oct
  jmp _int0x021_f9_end
 
_int0x021_f9_nov:
  mov si,nov
  jmp _int0x021_f9_end
 
_int0x021_f9_dec:
  mov si,dec_
  jmp _int0x021_f9_end

mov si,unk
_int0x021_f9_end:
pop dx
retn
 
 
  retn
 _int0x021_end:
  iret
 
jan db "January",0
feb db "February",0
mar db "March",0
apr db "April",0
may db "May",0
jun db "June",0
jul db "July",0
aug db "August",0
sep db "September",0
oct db "October",0
nov db "November",0
dec_ db "December",0
unk db "Unknown",0

times 1474048-($-$$) db 0


Etwas viel ich weiss, aber ich hoffe ihr koennt mir weiterhelfen.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 01. May 2009, 13:54 »
  mov es, ax
    cli
    mov word [es:0x21*4], _int0x021
    mov [es:0x21*4+2], cs         

mov word[ds:(9*4)  ], keyboard_handler    ;Offset
mov word[ds:(9*4)+2], 0                  ;Segment

du benutzt für den Keyboard_handler ja auch die falsche Segmentaddresse für die IVT

du woltest wohl es stat ds schreiben ^^


außerdem gehst du für den handler von codsegemnt 0 aus. für den int 21 nimmst du das aktuelle cs, die sollten beide im aktuellen cs liegen, sonst stimmen die offsets nicht.

IIRC geht mov […], cs gar nicht. und muss z.B. lauten
mov ax, cs
mov […], ax

oder halt mit jedem anderen allzweckregister

[edit]
keyboard_handler:
mov si,s_noos_keyp
mov bl,0x02
mov dl,0x03
int 0x021
mov  al, 0x20
out  0x20, al
iret
ein interrupthandler sollte keine register verändern?
stell dir vor:

xor al, al
;hier drückt einer eine taste
;dann landet man bestimmt nicht mehr bei _bla
cmp al, 0
je _bla

also alle register die du im interrupt veränderst vor her push'en und am ende wieder vom stack holen.

loopi:
mov ah,00h
int 16h

hier wirst du nicht vorbei kommen, wenn du nicht den int0x16 auch noch selbst machst. Wie soll denn das BIOS mitkriegen das ne taste gedrückt wurde wenn du ihm den IRQ klaust und deine keyboard_handler dran hängst.
« Letzte Änderung: 01. May 2009, 14:08 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Feuermonster

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 01. May 2009, 14:21 »
>hier wirst du nicht vorbei kommen, wenn du nicht den int0x16 auch noch selbst machst. Wie soll denn das BIOS mitkriegen das ne taste gedrückt wurde wenn du ihm den IRQ klaust und deine keyboard_handler dran hängst.

Wenn der keyboard_handler funktioniert, dann ja. Momentan tut er das nicht, der int 16h funktioniert.

Wenn ich die Taste 1.) druecke, wird die Nachricht "[..] (c) Roman [...]" ausgegeben. Danach ist jedoch fertig. Theoretisch sollte ich ja wieder zur Auswahl kommen -> ist jedoch nicht der Fall.

>außerdem gehst du für den handler von codsegemnt 0 aus. für den int 21 nimmst du das aktuelle cs, die sollten beide im aktuellen cs liegen, sonst stimmen die offsets nicht.

CS aendere ich ja noch nicht. Soll ich das auch wie es auf 0 setzen?


Wenn ich

push dx
    push es
    xor ax, ax
    mov es, ax
mov cs, ax
    cli
    mov word [es:0x21*4], _int0x021 
    mov [es:0x21*4+2], cs         

mov word[es:(9*4)  ], keyboard_handler    ;Offset
mov word[es:(9*4)+2], cs                  ;Segment


    sti
    pop es
    pop dx

schreibe, bleibt der Kernel haengen. (Die nachricht Syscalls set kommt dann gar nicht mehr).
« Letzte Änderung: 01. May 2009, 14:25 von Feuermonster »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 01. May 2009, 14:27 »
>hier wirst du nicht vorbei kommen, wenn du nicht den int0x16 auch noch selbst machst. Wie soll denn das BIOS mitkriegen das ne taste gedrückt wurde wenn du ihm den IRQ klaust und deine keyboard_handler dran hängst.

Wenn der keyboard_handler funktioniert, dann ja. Momentan tut er das nicht, der int 16h funktioniert.
:?
Du registrierst einen IRQ1 Handler, richtig? Und du willst den BIOS Interrupts zum Empfangen einer Taste verwenden richtig? Beides zusammen geht nicht, wie MNemo bereits sagte, da damit der BIOS Interrupt funktioniert der IRQ1 Handler nicht verändert werden darf. Das BIOS wartet ja schließlich auf einen IRQ1, um vom Tastendruck was mitzubekommen. Und du klaust dem BIOS durch das Umbiegen der IVT einfach so den IRQ1.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 01. May 2009, 14:34 »
CS aendere ich ja noch nicht. Soll ich das auch wie es auf 0 setzen?


Wenn ich
push dx
    push es
    xor ax, ax
    mov es, ax
mov cs, ax
    cli
    mov word [es:0x21*4], _int0x021 
    mov [es:0x21*4+2], cs         

mov word[es:(9*4)  ], keyboard_handler    ;Offset
mov word[es:(9*4)+2], cs                  ;Segment


    sti
    pop es
    pop dx

schreibe, bleibt der Kernel haengen. (Die nachricht Syscalls set kommt dann gar nicht mehr).

nein du sollst nicht cs auf 0 setzen. ich finde es zwar merkwürdig das dein assembler den code oben überhaupt akzeptiert denn ich dachte dass man auf cs nicht direkt zugreifen kann, deshalb hatte ich gemeint du solst mal:

    push es
    xor ax, ax
    mov es, ax
mov ax, cs
    cli
    mov word [es:0x21*4], _int0x021 
    mov [es:0x21*4+2], ax         

mov word[es:(9*4)  ], keyboard_handler    ;Offset
mov word[es:(9*4)+2], ax                  ;Segment

    sti
    pop es

den sinn deines push/pop dx muss man nicht verstehen oder?
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Feuermonster

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 01. May 2009, 14:38 »
Zitat
Du registrierst einen IRQ1 Handler, richtig? Und du willst den BIOS Interrupts zum Empfangen einer Taste verwenden richtig? Beides zusammen geht nicht, wie MNemo bereits sagte, da damit der BIOS Interrupt funktioniert der IRQ1 Handler nicht verändert werden darf. Das BIOS wartet ja schließlich auf einen IRQ1, um vom Tastendruck was mitzubekommen. Und du klaust dem BIOS durch das Umbiegen der IVT einfach so den IRQ1.

Eben registriere ich ihn nicht. Der keyboard handler funktioniert nicht. Ich will den int 16h gar nicht, der steht einfach so da damit ich wenigstens etwas habe womit ich Eingaben verwerten kann (was irgendwie auch nicht so richtig funktionert, er springt nicht mehr nach loopi zurueck).

Eigentlich will ich nur dass bei jedem Tastendruck mein keyboard_handler aufgerufen wird. Die Funktion zum den Tastendruck nachher auszulesen bau ich dann schon selber, aber dazu muss erst mal der Handler funktionieren.

Edit: Ich hab jetzt mal folgendes getaetigt

push dx
push es
xor ax, ax
mov es, ax
mov bx, cs
cli
mov word [es:0x21*4], _int0x021 
mov [es:0x21*4+2], bx         

mov word[es:(9*4)  ], keyboard_handler    ;Offset
mov word[es:(9*4)+2], bx                 ;Segment


sti
pop es
pop dx

Der Int 16h funktioniert nun nicht mehr, dass ist soweit ja wie es sein sollte.

Doch der keyboard_handler wird nicht aufgerufen. Oder die Nachrichtenausgabe failt, aber wenn ich ein int 0x09 schreibe, wird sie ausgegeben. Also tendiere ich eher dazu, dass die CPU meinen keyboard_handler nicht aufruft.
« Letzte Änderung: 01. May 2009, 14:47 von Feuermonster »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 01. May 2009, 15:18 »
Ich bezweifle das das viel mit deinem problem zu tun hat, aber ich hab da ein paar fehler entdeckt.

du machst folgeneds
int0x21:
cmp dl, 0x3
je func3

func3:

retn

falls du das versuchst, zu einem jmp kann man mit einem retn nicht zurückkehren, das funktioniert nur nach einem call.
falls das nicht dein ziel ist und du einfach nur aus der ISR zurückkehren wilst must du das mit iret machn.
ret und iret unterscheiden sich dahingehend, dass iret zusätzlich noch die flags vom stack holt(mit ret bleiben die nach einem int einfach da liegen und machen dir den stack kaput.


daraus folgt auch, dass du nicht einfach einmal
jmp func2
und einmal
call func2
machen kannst.(ich geb zu, unter gewissen umständen geht das schon, die sind hier aber nicht gegeben)
« Letzte Änderung: 01. May 2009, 15:20 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Feuermonster

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 01. May 2009, 15:31 »
Ein iret geht nicht, da ich ja zwischen den Interrupts auch calls habe. wenn func4 mittels call func5 aufruft und func5 wuerde mit iret ja sofort den ganzen Interrupt zufrueh beenden.

D.h ich muss das Design der Interrupts wohl umschreiben.
« Letzte Änderung: 01. May 2009, 15:35 von Feuermonster »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 01. May 2009, 15:37 »
wie gesagt du kannst das nicht einfach mischen.

Entweder dein func5 ist eine Procedure, die du mittels call aufrufst und mit ret beendest,(darfst du sie nicht mit jmp/je/.. aufrufen) oder du darfst func5 nicht mit call starten.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 01. May 2009, 15:38 »
Eine Funktion kannst du nur entweder als Interrupt oder als normale Funktion aufrufen, wenn du anfängst zu mischen hast du ein Problem.

Das call legt ja letztendlich nur die Rücksprungadresse auf den Stack und springt, und ret holt sie wieder vom Stack und springt zurück. Ein Interrupt speichert etwas mehr auf den Stack und ein iret holt entsprechend auch wieder mehr zurück, um den alten Zustand wiederherzustellen.

Wenn der Aufruf und der Rücksprung nicht zusammenpassen, läßt du entweder überschüssiges Zeug auf dem Stack liegen, was den Aufrufer durcheinanderbringt oder du nimmst zuviel runter, was den Aufrufer ebenfalls durcheinanderbringt und höchstwahrscheinlich einen unsinnigen Zustand "wiederherstellt".
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Feuermonster

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 01. May 2009, 15:45 »
Kann ich wenn ich innerhalb des Interrupts 0x21 bin,
einen weiteren Interrupt 0x21 ausloesen?

Genau gesagt, wenn die Funktion 0x3 fuer jedes Byte die Funktion 0x2 aufruft mittels mov dl,0x02 int 0x21, geht das in Ordnung?

Edit: Hat jemand eine Idee wieso der keyboard_handler nicht funktioniert?
« Letzte Änderung: 01. May 2009, 15:52 von Feuermonster »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #11 am: 01. May 2009, 15:47 »
Jo, natürlich.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 01. May 2009, 15:47 »
Ja, grundsätzlich schon. Bringt eben ein bißchen Overhead mit sich. Aber das ist dann halt die berühmte Geschwindigkeit, wenn man Assembler programmiert.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #13 am: 01. May 2009, 15:50 »
Und es wird halt extrem übersichtlich und Probleme lassen sich so extrem einfach debuggen. :roll:
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 01. May 2009, 16:00 »
Edit: Hat jemand eine Idee wieso der keyboard_handler nicht funktioniert?

wenn du mir deinen bootsector auch noch gibst kann ich mir das mal mit bochs angucken.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Feuermonster

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 01. May 2009, 16:17 »
Vielen Dank fuer die Hilfe. Ich habe den Code jetzt mal aufgeraeumt.

;===========
; Kernel
;===========

; Update segment registers
mov ax, 0x1000
mov ds, ax
mov es, ax

push dx
push es
xor ax, ax
mov es, ax
mov bx, cs
cli
mov word [es:0x21*4], noos_int21h
mov [es:0x21*4+2], bx         
mov word[es:(9*4)  ], noos_keyboard_handler    ;Offset
mov word[es:(9*4)+2], bx                 ;Segment
sti
pop es
pop dx

mov si, s_noos_logo
xor bh, bh
mov bl, 0x05
mov dl, 0x01
int 0x21

noos_loop:
jmp noos_loop

;=============
; Variables
;=============

s_noos_logo db "[ NoOS ]",0
s_noos_jmp_good db  " Jump into kernel successful",0
s_noos_step1 db " Setting up syscalls",0
s_noos_step2 db " Syscalls (INT 0x021) set",0
s_noos_step3 db " Reading from CMOS (Month)",0
s_noos_step4 db " And the month is: ",0
s_noos_keyp db "KEY_PRESSED",0
s_noos_i_info db "Options",13,9,"1.) Show copyright",13,9,"2.) Calc test",0
s_noos_i_autor db "NoOS (c) by Roman Muentener",0
s_noos_i_calc_end db "Calc test done...",0

;==============
; Handlers
;==============

noos_keyboard_handler:
  pusha
 
  ; Print dummy message
  mov bl, 0x06
  xor bh, bh
  mov dl, 0x01
  mov si, s_noos_keyp
  int 0x21
 
  ; Tell the PIC we handled the interrupt
  mov  al, 0x20
  out  0x20, al
 
  popa
  iret

;==============
; Functions
;==============

noos_int21h:
 
  ;Jump to the right function
  cmp dl, 0x01
  je noos_int21h_0x1
  cmp dl, 0x02
  je noos_int21h_0x2
  cmp dl, 0x03
  je noos_int21h_0x3
  cmp dl, 0x04
  je noos_int21h_0x4
  cmp dl, 0x05
  je noos_int21h_0x5
 
  iret
 
  ;=========
  ;noos_print
  ; BL = Attribute, SI = String
  ;=========
  noos_int21h_0x1:
    lodsb ;Load byte
or al, al ;Zero byte?
jz noos_int21h_0x1_end

; Call noos_putchar
mov dl, 0x02
int 0x21

;Loop
jmp noos_int21h_0x1

noos_int21h_0x1_end:
  iret
 
  ;============
  ;noos_putchar
  ; BL = Attribute, AL = Character, BH = Page
  ;============
  noos_int21h_0x2:
mov cx, 1
    mov ah, 0x09
    int 0x10

; Call noos_inc_column
mov dl, 0x05
int 0x21

iret

  ;===================
  ;noos_get_cursor_pos
  ; ret: AL = Column, ret: AH = Row
  ;===================
  noos_int21h_0x3:
mov ah, 0x03
int 0x10
mov al, dl
mov ah, dh
iret

  ;===================
  ;noos_set_cursor_pos
  ; AL = Column, AH = Row, BH = Page
  ;===================
  noos_int21h_0x4:
mov dl, al
mov dh, ah
mov ah, 0x02
int 0x10
iret

  ;============
  ;noos_inc_column
  ;============
  noos_int21h_0x5:

; Call noos_get_cursor_pos
mov dl, 0x03
int 0x21

; Increment
inc al

; Call noos_set_cursor_pos
mov dl, 0x04
    int 0x21

iret



times 1474048-($-$$) db 0

Der Handler wird jetzt aufgerufen, jedoch nur einmal. Was ist noch falsch?

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 01. May 2009, 16:30 »
Jetzt musst du nur noch die Daten aus dem KBC-Auslesen, sonst nimmt der keine weiteren tasten drücke an, und gibt auch keine mehr weiter.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

 

Einloggen