orr*_*az1 4 keyboard assembly pong x86-16 emu8086
我是初学者,所以这段代码可能没什么用,我用过int 16h这个,但我对此了解不多int。我刚刚发现你不能同时敲击多个按键;有什么帮助吗?
这段代码的问题是一次只能移动一块板,而我需要两块板。如何检查多个输入?
这是任何想要它的人的代码:
Run Code Online (Sandbox Code Playgroud)IDEAL MODEL small STACK 100h DATASEG ; -------------------------- ; Your variables here ; -------------------------- line1X dw 80 line1Y dw 120 line1start dw 5 line1end dw 10 line2X dw 80 line2Y dw 120 line2start dw 310 line2end dw 315 CODESEG proc startVideo ;creates video mode mov al,13h mov ah,0h int 10h ret endp startVideo proc clearScrean ;turns the screen black mov ah, 0ch xor al,al mov dx,200 BlankLine: mov cx,320 BlankColumn: int 10h Loop BlankColumn dec dx cmp dx,0 jne BlankLine ret endp clearScrean proc drawboard ;creates the board push bp mov bp,sp mov al,0fh mov ah,0ch beginning equ [bp+10] fn equ [bp+8] X equ [bp+6] ;boards start Y equ [bp+4] ;boards end mov dx,Y drawrow: mov cx,fn drawcolumn: int 10h dec cx cmp cx,beginning jne drawcolumn dec dx cmp dx,X jne drawrow pop bp ret 8 endp drawboard proc drawall push [line1start] push [line1end] push [line1X] push [line1Y] call drawboard push [line2start] push [line2end] push [line2X] push [line2Y] call drawboard ret endp drawall proc boardup push bp mov bp,sp mov bx,[bp+4] mov si,[bp+6] cmp [word ptr bx],0 ;checks if board didnt get to border je fn1 call clearScrean sub [word ptr bx],5 ;3 pixels added to board sub [word ptr si],5 call drawall ;prints both boards fn1: pop bp ret 4 endp boardup proc boarddown push bp mov bp,sp mov bx,[bp+4] mov si,[bp+6] cmp [word ptr si],200 ;checks if board didnt get to border je fn2 call clearScrean add [word ptr bx],5 ;3 pixels added to board add [word ptr si],5 call drawall ;prints both boards fn2: pop bp ret 4 endp boarddown start: mov ax, @data mov ds, ax mov bh,0 call startVideo call clearScrean call drawall checkskey: ;checks if key is being pressed mov ah,1 int 16h jz checkskey ;jumps if key isnt pressed mov ah,0 ;checks which key is pressed int 16h cmp ah,11h ;if key pressed is w jump to upboard je upboard1 cmp ah,01fh ;if key pressed is s jump to downboard je downboard1 cmp ah,050h je downboard2 cmp ah,048h je upboard2 jmp checkskey ;if key isnt pressed jump to check key upboard1: ;board 1 goes up push offset line1Y push offset line1X call boardup jmp checkskey downboard1: ;board 1 goes down push offset line1Y push offset line1X call boarddown jmp checkskey downboard2: push offset line2Y push offset line2X call boarddown jmp checkskey upboard2: push offset line2Y push offset line2X call boardup jmp checkskey exit: mov ax, 4c00h int 21h END start
另一个答案涉及多人游戏,其中没有玩家持续按下专用键并从而占用键盘。尽管这种情况相当合理,但您可能希望允许玩家按住按键更长时间。为此,我们可以用我们自己的处理程序替换 BIOS/DOS 提供的键盘处理程序。
键盘上的每个键都关联一个唯一的 8 位数字,我们称之为扫描码。
每当按下某个键时,键盘都会在端口 60h 上提供相关键的扫描码。键盘还产生中断09h。该中断的处理程序可以检查扫描码并以任何喜欢的方式处理它。这就是下面的演示程序的作用。
当按下一个键时,扫描码是一个字节,其最高位关闭。当释放按键时,扫描码是一个最高位打开的字节。对于按下和释放,其他 7 位保持不变。
应该指出的是,虽然对于乒乓球游戏的目的来说很好,但包含的替换处理程序是一个简约的处理程序。复杂的处理程序还会考虑以 E0h 或 E1h 代码为前缀的扩展扫描代码。
该程序有附加注释,因此您可以轻松了解正在发生的情况。该代码使用 FASM 语法。该演示在真实的 DOS 环境和 DOSBox (0.74) 中运行正常。
; Multi-player Keyboard Input (c) 2021 Sep Roland
ORG 256 ; Output will be a .COM program
mov ax, 3509h ; DOS.GetInterruptVector
int 21h ; -> ES:BX
push es bx ; (1)
mov dx, Int09
mov ax, 2509h ; DOS.SetInterruptVector
int 21h
mov ax, 0013h ; BIOS.SetVideoMode 320x200 (256 colors)
int 10h
mov ax, 0A000h ; Video buffer
mov es, ax
cld ; So we can use the string primitive STOSB
Cont:
mov si, 160 ; Width
mov di, 100 ; Height
mov al, 0 ; Black
cmp [KeyList+48h], al ; Up
je .a
mov al, 2 ; Green
.a: mov cx, 160 ; X
mov dx, 0 ; Y
call Paint
mov al, 0 ; Black
cmp [KeyList+50h], al ; Down
je .b
mov al, 14 ; Yellow
.b: mov cx, 160 ; X
mov dx, 100 ; Y
call Paint
mov al, 0 ; Black
cmp [KeyList+11h], al ; aZerty / qWerty
je .c
mov al, 4 ; Red
.c: mov cx, 0 ; X
mov dx, 0 ; Y
call Paint
mov al, 0 ; Black
cmp [KeyList+1Fh], al ; S
je .d
mov al, 1 ; Blue
.d: mov cx, 0 ; X
mov dx, 100 ; Y
call Paint
cmp byte [KeyList+1], 0 ; ESC
je Cont
pop dx ds ; (1)
mov ax, 2509h ; DOS.SetInterruptVector
int 21h
mov ax, 4C00h ; DOS.Terminate
int 21h
; --------------------------------------
Int09:
push ax bx
in al, 60h
mov ah, 0
mov bx, ax
and bx, 127 ; 7-bit scancode goes to BX
shl ax, 1 ; 1-bit press/release goes to AH
xor ah, 1 ; -> AH=1 Press, AH=0 Release
mov [cs:KeyList+bx], ah
mov al, 20h ; The non specific EOI (End Of Interrupt)
out 20h, al
pop bx ax
iret
; --------------------------------------
; IN (al,cx,dx,si,di)
Paint:
push cx dx di ; AL=Color CX=X DX=Y SI=Width DI=Height
push ax ; (1)
mov ax, 320 ; BytesPerScanline
mul dx
add ax, cx ; (Y * BPS) + X
mov dx, di
mov di, ax
pop ax ; (1)
.a: mov cx, si
rep stosb
sub di, si
add di, 320
dec dx
jnz .a
pop di dx cx
ret
; --------------------------------------
KeyList db 128 dup 0
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)KeyList db 128 dup 0
程序的KeyList记录了键盘上所有按键的当前状态。如果某个字节为 0,则表示该键未被按下。如果某个字节为 1,则当前正在按下该键。
| 归档时间: |
|
| 查看次数: |
619 次 |
| 最近记录: |