Re: ReadConsole may not be sufficient for INKEY$, but...

by Michael Calkins (Login MCalkins)
ASM Forum

 
Thanks for the info.

I had a bit of trouble with the structure alignment. For one thing, I was thinking BOOL is a word, but it is a dword. Also, it seems that although KEY_EVENT_RECORD is packed, INPUT_RECORD is not, so that the start of KEY_EVENT_RECORD is dword aligned.

I probably won't need to focus too much on Ctrl and Alt combinations. Shift seems to be automatically handled for letters and punctuation. Key combinations would be relevant for Alt driven menus, for copying/pasting text in an editor, or for arcade games (in combination with arrow keys). In this sense, ReadConsoleInput replaces both Inkey$ and Peek(&h417), except for polling the keyboard while doing other things. I'm thinking GetNumberOfConsoleInputEvents could be used for such a purpose.

Regards,
Michael

_mode equ 0xb0

_EventType equ 0x0

_bKeyDown equ 0x4
_wRepeatCount equ 0x8
_wVirtualKeyCode equ 0xa
_wVirtualScanCode equ 0xc
_UnicodeChar equ 0xe
_kdwControlKeyState equ 0x10

_dwMousePosition equ 0x4
_dwButtonState equ 0x8
_mdwControlKeyState equ 0xc
_dwEventFlags equ 0x10

cpu 586

extern _GetStdHandle@4
extern _WriteConsoleW@20
extern _ReadConsoleInputW@16
extern _SetConsoleMode@8

global _asmmain

section .text

_asmmain:
pusha

push dword 0xfffffff5
call _GetStdHandle@4
mov [_stdout],eax

push dword 0xfffffff6
call _GetStdHandle@4
mov [_stdin],eax

mov ecx,(_endmsginit-_msginit)/2
mov ebx,_msginit
call _print
mov edx,_mode
call _pdword
call _printcrlf

push dword _mode
push dword [_stdin]
call _SetConsoleMode@8
test eax,eax
jz _error

_mainloop:

mov ecx,(_endmsgpmt-_msgpmt)/2
mov ebx,_msgpmt
call _print

push dword _count
push dword 0x1
push dword _buffer
push dword [_stdin]
call _ReadConsoleInputW@16

mov ecx,(_endmsgcnt-_msgcnt)/2
mov ebx,_msgcnt
call _print
mov edx,[_count]
call _pdword
call _printcrlf

mov ecx,(_endmsgtyp-_msgtyp)/2
mov ebx,_msgtyp
call _print
mov edx,[_buffer+_EventType]
call _pword
call _printcrlf

cmp dx,0x2
jz _mouse
cmp dx,0x1
jnz _mainloop

mov ecx,(_endmsgbkd-_msgbkd)/2
mov ebx,_msgbkd
call _print
mov edx,[_buffer+_bKeyDown]
call _pdword
call _printcrlf

mov ecx,(_endmsgrpt-_msgrpt)/2
mov ebx,_msgrpt
call _print
mov edx,[_buffer+_wRepeatCount]
call _pword
call _printcrlf

mov ecx,(_endmsgvkc-_msgvkc)/2
mov ebx,_msgvkc
call _print
mov edx,[_buffer+_wVirtualKeyCode]
call _pword

mov ecx,(_endmsglit-_msglit)/2
mov ebx,_msglit
call _print
push dword 0x2
push dword [_stdout]
call _SetConsoleMode@8
test eax,eax
jz _error
mov ecx,0x1
mov ebx,_buffer+_wVirtualKeyCode
call _print
push dword 0x3
push dword [_stdout]
call _SetConsoleMode@8
test eax,eax
jz _error
mov ecx,(_endmsglte-_msglte)/2
mov ebx,_msglte
call _print

mov ecx,(_endmsgvsc-_msgvsc)/2
mov ebx,_msgvsc
call _print
mov edx,[_buffer+_wVirtualScanCode]
call _pword
call _printcrlf

mov ecx,(_endmsguch-_msguch)/2
mov ebx,_msguch
call _print
mov edx,[_buffer+_UnicodeChar]
call _pword

mov ecx,(_endmsglit-_msglit)/2
mov ebx,_msglit
call _print
push dword 0x2
push dword [_stdout]
call _SetConsoleMode@8
test eax,eax
jz _error
mov ecx,0x1
mov ebx,_buffer+_UnicodeChar
call _print
push dword 0x3
push dword [_stdout]
call _SetConsoleMode@8
test eax,eax
jz _error
mov ecx,(_endmsglte-_msglte)/2
mov ebx,_msglte
call _print

mov ecx,(_endmsgctl-_msgctl)/2
mov ebx,_msgctl
call _print
mov edx,[_buffer+_kdwControlKeyState]
call _pdword
call _printcrlf

mov eax,[_buffer+_UnicodeChar]
cmp ax,0x1b
jz _exit

jmp _mainloop
_mouse:

mov ecx,(_endmsgmpos-_msgmpos)/2
mov ebx,_msgmpos
call _print
mov edx,[_buffer+_dwMousePosition]
call _pdword
call _printcrlf

mov ecx,(_endmsgmbut-_msgmbut)/2
mov ebx,_msgmbut
call _print
mov edx,[_buffer+_dwButtonState]
call _pdword
call _printcrlf

mov ecx,(_endmsgmkey-_msgmkey)/2
mov ebx,_msgmkey
call _print
mov edx,[_buffer+_mdwControlKeyState]
call _pdword
call _printcrlf

mov ecx,(_endmsgmflg-_msgmflg)/2
mov ebx,_msgmflg
call _print
mov edx,[_buffer+_dwEventFlags]
call _pdword
call _printcrlf

jmp _mainloop

_error:
mov ecx,(_endmsgerr-_msgerr)/2
mov ebx,_msgerr
call _print
_exit:
popa
xor eax,eax
retn

; _print
; prints a string
; call with:
; ebx = address of string to print
; ecx = number of characters (word size) to print
; returns nothing. preserves registers. (the winapi seems to destroy them)
; requires _trash, _stdout, _WriteConsoleW@20
_print:
pusha
push dword 0x0
push dword _trash
push ecx
push ebx
push dword [_stdout]
call _WriteConsoleW@20
popa
retn

; _printcrlf
; prints crlf
; call with:
; nothing
; returns nothing. preserves registers.
; requires _crlf, _trash, _stdout, _WriteConsoleW@20
_printcrlf:
pusha
push dword 0x0
push dword _trash
push dword 0x2
push dword _crlf
push dword [_stdout]
call _WriteConsoleW@20
popa
retn

; _pdword
; prints a dword as a hexadecimal string
; call with:
; edx = dword value
; returns nothing. preserves registers.
; requires _hexdword, _trash, _stdout, _WriteConsoleW@20
_pdword:
pusha
pushf
std
mov edi,_hexdword+0x12
mov ecx,0x8
xor eax,eax
.lp:
mov al,dl
and al,0xf
cmp al,0xa
jb .skip
add al,0x27
.skip:
add al,0x30
stosw
shr edx,0x4
loop .lp
popf
push dword 0x0
push dword _trash
push dword 0xa
push dword _hexdword
push dword [_stdout]
call _WriteConsoleW@20
popa
retn

; _pword
; prints a word as a hexadecimal string
; call with:
; edx = word value
; returns nothing. preserves registers.
; requires _hexdword, _trash, _stdout, _WriteConsoleW@20
_pword:
pusha
pushf
std
mov edi,_hexdword+0xa
mov ecx,0x4
xor eax,eax
.lp:
mov al,dl
and al,0xf
cmp al,0xa
jb .skip
add al,0x27
.skip:
add al,0x30
stosw
shr edx,0x4
loop .lp
popf
push dword 0x0
push dword _trash
push dword 0x6
push dword _hexdword
push dword [_stdout]
call _WriteConsoleW@20
popa
retn

section .data

_msginit:
dw "S","e","t","t","i","n","g"," ","s","t","d","i","n"," ","m","o","d","e"
dw " ","t","o",":"," "," "
_endmsginit:
_msgerr:
dw "S","e","t","C","o","n","s","o","l","e","M","o","d","e"," ","f","a","i"
dw "l","e","d",".",0xd,0xa
_endmsgerr:
_msgpmt:
dw 0xd,0xa,"E","S","C"," ","t","o"," ","e","x","i","t",".",0xd,0xa
_endmsgpmt:
_msgcnt:
dw "c","o","u","n","t",":"," ",0x9,0x9,0x9
_endmsgcnt:
_msgtyp:
dw "E","v","e","n","t","T","y","p","e",":"," ",0x9,0x9," "," "," "," "
_endmsgtyp:
_hexdword: dw "0","x",0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
_crlf: dw 0xd,0xa
_msgbkd:
dw "b","K","e","y","D","o","w","n",":"," ",0x9,0x9
_endmsgbkd:
_msgrpt:
dw "w","R","e","p","e","a","t","C","o","u","n","t",":"," ",0x9,0x9," "," "
dw " "," "
_endmsgrpt:
_msgvkc:
dw "w","V","i","r","t","u","a","l","K","e","y","C","o","d","e",":"," ",0x9
dw " "," "," "," "
_endmsgvkc:
_msgvsc:
dw "w","V","i","r","t","u","a","l","S","c","a","n","C","o","d","e",":"," "
dw 0x9," "," "," "," "
_endmsgvsc:
_msguch:
dw "U","n","i","c","o","d","e","C","h","a","r",":"," ",0x9,0x9," "," "," "
dw " "
_endmsguch:
_msgctl:
dw "d","w","C","o","n","t","r","o","l","K","e","y","S","t","a","t","e",":"
dw " ",0x9
_endmsgctl:
_msglit:
dw 0x9,0x22
_endmsglit:
_msglte:
dw 0x22,0xd,0xa
_endmsglte:
_msgmpos:
dw "d","w","M","o","u","s","e","P","o","s","i","t","i","o","n",":"," ",0x9
_endmsgmpos:
_msgmbut:
dw "d","w","B","u","t","t","o","n","S","t","a","t","e",":"," ",0x9,0x9
_endmsgmbut:
_msgmkey:
dw "d","w","C","o","n","t","r","o","l","K","e","y","S","t","a","t","e",":"
dw " ",0x9
_endmsgmkey:
_msgmflg:
dw "d","w","E","v","e","n","t","F","l","a","g","s",":"," ",0x9,0x9
_endmsgmflg:

section .bss

_stdout: resd 0x1
_stdin: resd 0x1
_count: resd 0x1
_buffer: resd 0x5
_trash: resd 0x1



    
This message has been edited by MCalkins on Jul 28, 2011 5:39 PM

Posted on Feb 12, 2011, 7:12 PM

Respond to this message   

Return to Index

 Copyright © 1999-2014 Network54. All rights reserved.   Terms of Use   Privacy Statement