Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: Assembler ::  Tastaturtreiber     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Thuruk
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.01.2012
Beiträge: 132
Beitrag Thuruk Mitglied 14:51:38 26.02.2012   Titel:   Tastaturtreiber            Zitieren

Ich suche gerade einen Fehler, der beim Ersetzen des Interrupt 0x16 durch folgende Datei entsteht - komischerweise werden beim Ausführen scheinbar danach stehende Variablen überschrieben, und beim Aufrufen der Funktion 'update_key_map' hängt Bochs.

Ist etwas in dieser Datei fehlerhaft? Sonst schreibe ich demnächst den Probekernel neu - will hier niemand mit wirrem Code nerven.^^

Assembler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
; Keyboard Driver
; include 'keyboard.asm'
 
; es and ds should point to 07C0:0000
; ax, di and si might be changed
 
; used labels: key_map, update_key_map, get_key_status
 
; use al for get_key_status decimal key number: 0 A, 1 S, 2 D, 3 W, 4 1, 5 2, 6 3, 7 4, 8 left, 9 down, 10 right, 11 up
; returns al=0 up, al=1 down
 
update_key_map:
    cli
 
    .test_kbc:
        in al, 0x64
        and al, 1b ; byte available
        jz .return_update_key_map
 
    in al, 0x60
    cmp al, 0xE0 ; arrow keys
    jz .arrow_key
 
    test al, 10000000b ; break code
    jz .make_code
 
    cmp al, 0x9E ; break A
    jz .break_A
 
    cmp al, 0x9F ; break S
    jz .break_S
 
    cmp al, 0xA0 ; break D
    jz .break_D
 
    cmp al, 0x91 ; break W
    jz .break_W
 
    cmp al, 0x82 ; break 1
    jz .break_1
 
    cmp al, 0x83 ; break 2
    jz .break_2
 
    cmp al, 0x84 ; break 3
    jz .break_3
 
    cmp al, 0x85 ; break 4
    jz .break_4
 
    .make_code:
        cmp al, 0x1E ; make A
        jz .make_A
 
        cmp al, 0x1F ; make S
        jz .make_S
 
        cmp al, 0x20 ; make D
        jz .make_D
 
        cmp al, 0x11 ; make W
        jz .make_W
 
        cmp al, 0x02 ; make 1
        jz .make_1
 
        cmp al, 0x03 ; make 2
        jz .make_2
 
        cmp al, 0x04 ; make 3
        jz .make_3
 
        cmp al, 0x05 ; make 4
        jz .make_4
 
    .arrow_key:
        in al, 0x60
        test al, 10000000b ; break code
        jz .make_arrow
 
        cmp al, 0xCB ; break left
        jz .break_left
 
        cmp al, 0xD0 ; break down
        jz .break_down
 
        cmp al, 0xCD ; break right
        jz .break_right
 
        cmp al, 0xC8 ; break up
        jz .break_up
 
        .make_arrow:
            cmp al, 0x4B ; make left
            jz .make_left
 
            cmp al, 0x50 ; make down
            jz .make_down
 
            cmp al, 0x4D ; make right
            jz .make_right
 
            cmp al, 0x48 ; make up
            jz .make_up
 
    .make_A:
        mov di, key_map
        jmp short .save_make_again
 
    .make_S:
        mov di, key_map+1
        jmp short .save_make_again
 
    .make_D:
        mov di, key_map+2
        jmp short .save_make_again
 
    .make_W:
        mov di, key_map+3
        jmp short .save_make_again
 
    .make_1:
        mov di, key_map+4
        jmp short .save_make_again
 
    .make_2:
        mov di, key_map+5
        jmp short .save_make_again
 
    .make_3:
        mov di, key_map+6
        jmp short .save_make_again
 
    .make_4:
        mov di, key_map+7
        jmp short .save_make_again
 
    .make_left:
        mov di, key_map+8
        jmp short .save_make_again
 
    .make_down:
        mov di, key_map+9
        jmp short .save_make_again
 
    .make_right:
        mov di, key_map+10
        jmp short .save_make_again
 
    .make_up:
        mov di, key_map+11
        jmp short .save_make_again
 
    .save_make_again:
        mov al, 0x1
        stosb
        jmp word .test_kbc
 
    .break_A:
        mov di, key_map
        jmp short .save_break_again
 
    .break_S:
        mov di, key_map+1
        jmp short .save_break_again
 
    .break_D:
        mov di, key_map+2
        jmp short .save_break_again
 
    .break_W:
        mov di, key_map+3
        jmp short .save_break_again
 
    .break_1:
        mov di, key_map+4
        jmp short .save_break_again
 
    .break_2:
        mov di, key_map+5
        jmp short .save_break_again
 
    .break_3:
        mov di, key_map+6
        jmp short .save_break_again
 
    .break_4:
        mov di, key_map+7
        jmp short .save_break_again
 
    .break_left:
        mov di, key_map+8
        jmp short .save_break_again
 
    .break_down:
        mov di, key_map+9
        jmp short .save_break_again
 
    .break_right:
        mov di, key_map+10
        jmp short .save_break_again
 
    .break_up:
        mov di, key_map+11
        jmp short .save_break_again
 
    .save_break_again:
        xor al, al
        stosb
        jmp word .test_kbc
 
    .return_update_key_map:
        sti
        ret
 
key_map times 12 db 0
 
get_key_status:
    cli
    mov si, key_map
    xor ah, ah
    add si, ax
 
    lodsb
    sti
    ret


Edit: Die erste Zeile nach '.arrow_key:' hatte ich vergessen, ist eingefügt - ändert aber nichts am nicht funktionieren, hätte nur einen Fehler bei Pfeiltasten verursacht.


Zuletzt bearbeitet von Thuruk am 15:21:38 26.02.2012, insgesamt 2-mal bearbeitet
gargyle
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.02.2006
Beiträge: 122
Beitrag gargyle Mitglied 18:26:35 26.02.2012   Titel:              Zitieren

Ich würde mal ES:(E)DI prüfen, die sollen ja bestimmt auf key_map zeigen
supernicky
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.11.2011
Beiträge: 122
Beitrag supernicky Mitglied 22:48:21 26.02.2012   Titel:   Tipp            Zitieren

Hallo Thuruk,

schau dir mal den Befehl XLAT genauer an..

Der könnte dir bei deinem Code wertvolle Dienste leisten und den Code
erheblich verkürzen.

Gruß, Nicky
Thuruk
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.01.2012
Beiträge: 132
Beitrag Thuruk Mitglied 00:30:36 27.02.2012   Titel:   Re: Tipp            Zitieren

supernicky schrieb:
Hallo Thuruk,

schau dir mal den Befehl XLAT genauer an..

Der könnte dir bei deinem Code wertvolle Dienste leisten und den Code
erheblich verkürzen.

Gruß, Nicky


Guter Hinweis, danke. :) Ich kenn ja nur eine Handvoll Befehle.

gargyle schrieb:
Ich würde mal ES:(E)DI prüfen, die sollen ja bestimmt auf key_map zeigen


Der Fehler lag tatsächlich in einer absoluten Adressangabe, die davon ausging, dass ab 7C00:000+2 Sektoren alles frei sei. Mein Code lag aber ein paar Bytes darüber - es wurde ein Objekt mitten hinein gespeichert.

Jetzt funktioniert zwar der Treiber noch nicht wie er sollte, aber zumindest hängt das System nicht und der Rest geht wieder.

Für alle Interessierten kopiere ich mal die anderen Dateien:

Assembler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
; Bootloader
; sets registers, loads sectors
; graphics mode 13h
 
; cs:ip, es:di, ds:si to boot sector
; ss:sp to pre-vram segment
 
[BITS 16]
 
%define sectors 3
 
    jmp word 0x7C0:setup ; cs:ip to boot sector
 
setup:
    mov ax, 0x07C0 ; es:di and ds:si to boot sector
    mov ds, ax
    mov es, ax
 
    mov ax, 0x9000 ; ss:sp to start of pre-vram segment
    mov ss, ax
    xor ax, ax ; wraps to top of segment
    mov sp, ax
 
    mov ax, 0x13 ; mode 13h
    int 0x10
 
    load_sectors:
        xor ah, ah ; reset drive dl
        int 0x13
        jc load_sectors ; cf set on error
 
        mov bx, 0x200 ; es:bx to post boot sector
        xor dh, dh ; head=0
        mov cx, 0x2 ; cylinder:sector=0:2
        mov ax, 0x200+sectors
        int 0x13
        jc load_sectors ; cf set on error
 
    jmp word second_sector
 
times 510-($-$$) db 0
 
db 0x55
db 0xAA
 
second_sector:
    %include "kernel.asm" ; include kernel, drivers and resources
    %include "keyboard.asm"
    %include "vga.asm"
    %include "font.asm"
 
times 0x200*(sectors+1)-($-$$) db 0


Assembler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
; VGA Driver
; include 'vga.asm'
 
; used labels: 'draw_character', 'draw_brush'
; draws characters using fg/bg colors and brushes using 255 colors
; transparency color=0
 
%define screen_width 320
%define screen_height 200
 
draw_character: ; es:di to target, ds:si to source, bx=back:fore color, zero for transparency
    cli
 
    push es
    mov ax, 0xA000
    mov es, ax
 
    mov ch, 0x10 ; height
 
    .line_start:
        mov cl, 0x8 ; width
        mov ah, 10000000b ; start with left bit
 
    .loop:
        mov al, [ds:si] ; get bit from font source
        test al, ah ; foreground?
        jz .draw_bg
 
        mov al, bl ; fg color to al
        jmp short .draw_chk
 
    .draw_bg:
        mov al, bh ; bg color to al
 
    .draw_chk:
        or al, al ; transparency?
        jnz .draw
 
        inc di ; next byte in vram
        jmp short .post_draw
 
    .draw:
        stosb ; draw color and next byte in vram
 
    .post_draw:
        shr ah, 0x1 ; will test next bit in source
        dec cl ; decrement inline counter
        jnz .loop
 
        inc si ; next byte (=line) in source
        add di, screen_width-0x8 ; next line in vram
        dec ch ; decrement line counter
        jnz .line_start
 
        pop es
 
        sti
        ret
 
draw_brush: ; es:di to target, ds:si to source, bx=height, cx=width, writes nonzero source bytes to target
    cli
 
    push es
    mov ax, 0xA000
    mov es, ax
 
    mov dx, cx ; dx=width
 
    .pre_loop:
        or cx, dx ; cx=width (restore after each line)
 
    .loop:
        lodsb ; color to al & next byte in source
        or al, al ; transparency?
        jnz .draw
 
        inc di ; next byte in vram
        jmp short .post_draw
 
    .draw:
        stosb ; draw color to vram
 
    .post_draw:
        dec cx ; decrement inline counter
        jnz .loop ; line of source drawn?
 
        add di, screen_width
        sub di, dx
        dec bx ; decrement line counter
        jnz .pre_loop ; all lines drawn?
 
        pop es
 
        sti
        ret


Assembler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
; Kernel
; include 'kernel.asm'
 
; using vga.asm, keyboard.asm and font.asm
 
; TESTKERNEL
 
mov di, 0x200*(sectors+1) ; store brush in ram
mov cx, 6042
mov al, 0x4
rep stosb
 
mov si, 0x200*(sectors+1) ; draw brush
mov cx, 318
mov bx, 19
mov di, 57601
call word draw_brush
 
main_loop:
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    call word update_key_map
    xor al, al
   
    call word get_key_status
    or al, al
    jnz draw_a
   
    jmp short main_loop
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    call word get_cursor_position
    mov bx, 0xF
    mov si, font_cursor
    call word draw_character
 
    xor ah, ah
    int 0x16
   
    cmp ax, 0x1E41
    jz draw_A
 
    cmp ax, 0x1E61
    jz draw_a
 
    cmp ax, 0x3042
    jz draw_B
 
    cmp ax, 0x3062
    jz draw_b
 
    cmp ax, 0x2E43
    jz draw_C
 
    cmp ax, 0x2E63
    jz draw_c
 
    cmp ax, 0x0E08
    jz backspace
 
    cmp ax, 0x5300
    jz delete
 
    cmp ax, 0x1C0D
    jz enter_key
 
    cmp ax, 0x4B00
    jz left_key
 
    cmp ax, 0x5000
    jz down_key
 
    cmp ax, 0x4D00
    jz right_key
 
    cmp ax, 0x4800
    jz up_key
 
    cmp ax, 0x343E
    jz DP_key
 
    cmp ax, 0x342E
    jz PU_key
 
    cmp ax, 0x332C
    jz CO_key
 
    cmp ax, 0x567C
    jz prompt
 
    cmp ax, 0x8200
    jz backslash
 
    cmp ax, 0x3920
    jz space
 
    jmp word main_loop
 
draw_A:
call word get_cursor_position
mov bx, 0x100F
mov si, font_A
call word draw_character
call word inc_cx
jmp word main_loop
 
draw_a:
call word get_cursor_position
mov bx, 0x100F
mov si, font_a
call word draw_character
call word inc_cx
jmp word main_loop
 
draw_B:
call word get_cursor_position
mov bx, 0x100F
mov si, font_B
call word draw_character
call word inc_cx
jmp word main_loop
 
draw_b:
call word get_cursor_position
mov bx, 0x100F
mov si, font_b
call word draw_character
call word inc_cx
jmp word main_loop
 
draw_C:
call word get_cursor_position
mov bx, 0x100F
mov si, font_C
call word draw_character
call word inc_cx
jmp word main_loop
 
draw_c:
call word get_cursor_position
mov bx, 0x100F
mov si, font_c
call word draw_character
call word inc_cx
jmp word main_loop
 
backspace:
call word navigation
call word dec_cx
call word get_cursor_position
mov bl, 0x10
mov si, font_full
call word draw_character
jmp word main_loop
 
delete:
call word navigation
call word get_cursor_position
mov bl, 0x10
mov si, font_full
call word draw_character
jmp word main_loop
 
enter_key:
call word navigation
call word inc_cy
xor ax, ax
mov [cursor_position_x], ax
jmp word main_loop
 
left_key:
call word navigation
call word dec_cx
jmp word main_loop
 
down_key:
call word navigation
call word inc_cy
jmp word main_loop
 
right_key:
call word navigation
call word inc_cx
jmp word main_loop
 
up_key:
call word navigation
call word dec_cy
jmp word main_loop
 
DP_key:
call word get_cursor_position
mov bx, 0x100F
mov si, font_DP
call word draw_character
call word inc_cx
jmp word main_loop
 
CO_key:
call word get_cursor_position
mov bx, 0x100F
mov si, font_CO
call word draw_character
call word inc_cx
jmp word main_loop
 
PU_key:
call word get_cursor_position
mov bx, 0x100F
mov si, font_PU
call word draw_character
call word inc_cx
jmp word main_loop
 
prompt:
call word get_cursor_position
mov bx, 0x100F
mov si, font_prompt
call word draw_character
call word inc_cx
jmp word main_loop
 
backslash:
call word get_cursor_position
mov bx, 0x100F
mov si, font_BS
call word draw_character
call word inc_cx
jmp word main_loop
 
space:
call word get_cursor_position
mov bl, 0x10
mov si, font_full
call word draw_character
call word inc_cx
jmp word main_loop
 
get_cursor_position:
    mov ax, [cursor_position_y]
    mov bx, 5120
    mul bx
    mov di, ax
    mov ax, [cursor_position_x]
    mov bx, 8
    mul bx
    add di, ax
    mov bx, 0x10
    ret
 
inc_cx:
    mov ax, [cursor_position_x]
    cmp ax, 39
    jz .left
    inc ax
    .write:
    mov [cursor_position_x], ax
    ret
    .left:
    call word inc_cy
    xor ax, ax
    jmp short .write
 
dec_cx:
    mov ax, [cursor_position_x]
    or ax, ax
    jz .right
    dec ax
    .write:
    mov [cursor_position_x], ax
    ret
    .right:
    call word dec_cy
    mov ax, 39
    jmp short .write
 
inc_cy:
    mov ax, [cursor_position_y]
    cmp ax, 10
    jz .top
    inc ax
    .write:
    mov [cursor_position_y], ax
    ret
    .top:
    xor ax, ax
    jmp short .write
 
dec_cy:
    mov ax, [cursor_position_y]
    or ax, ax
    jz .bottom
    dec ax
    .write:
    mov [cursor_position_y], ax
    ret
    .bottom:
    mov ax, 10
    jmp short .write
 
navigation:
    call word get_cursor_position
    mov bx, 0x10
    mov si, font_cursor
    call word draw_character
    ret
 
cursor_position_x db 0, 0
cursor_position_y db 0, 0
Thuruk
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.01.2012
Beiträge: 132
Beitrag Thuruk Mitglied 11:44:25 28.02.2012   Titel:              Zitieren

Sry wenn der letzte Beitrag den Firefox ein wenig stresst.

Was haltet ihr von folgendem Konzept:

Tastatureingaben werden je nach Wahl des Programmierers in eine programmeigene Tabelle der Form

Code:
Nr. Tastendruck (1 Byte) | Code (1 Byte)
                       0 |            24
                       1 |            33


eingelesen, wobei ein weiteres Byte die aktuelle Position angibt - für einen Verlauf bei Textverarbeitung o.ä. und/oder in einer Keymap gespeichert:

Code:
           Code (1 Byte) | Status (1 Byte)
                      24 |               0
                      35 |               1


Die Programme müssen dann die Tastatureingaben verwerten. Müsste also einen Interrupt die Tabelle bearbeiten lassen und das Betriebssystem für jedes Programm den entsprechenden Speicher reservieren.

Wie habt ihr das gelöst? Gute oder schlechte Idee?
Nobuo T
Moderator

Benutzerprofil
Anmeldungsdatum: 09.10.2001
Beiträge: 4754
Beitrag Nobuo T Moderator 13:08:12 28.02.2012   Titel:              Zitieren

Habe zwar nicht ganz verstanden, wie das praktisch aussehen soll, klingt aber etwas umstaendlich. Intern in deinem OS kannst du das vielleicht so handhaben, extern fuer die APIs wuerde ich mich da jedoch an die Klassiker FIFO-Queue fuer Tasteneingaben (siehe z.B. BIOS / "readkey"-funktion) und events (Taste xy wurde gedrueckt/losgelassen) und evtl. abgespeckte Bitmaps der Form "Taste gedrueckt? ja/nein" ("keypressed"-funktion) halten.

Kannst auch mal schauen, wie Erhard das in seinem BS geloest hat und die Sache dort evtl. etwas lebhafter diskutieren... Projekt: OS-Development

_________________
==Mod im Assembler-Forum==

http://z0r.de/2908


Zuletzt bearbeitet von Nobuo T am 13:10:32 28.02.2012, insgesamt 1-mal bearbeitet
c++.de :: Assembler ::  Tastaturtreiber   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.