;****************************************************************************
;****************************************************************************
;*
;* USING VIRTUAL TERMINALS UNDER LINUX
;*
;* written by Karsten Scheibler, 2003-DEC-08
;*
;****************************************************************************
;****************************************************************************
global vt_start
;****************************************************************************
;* some assign's
;****************************************************************************
%assign SYS_IOCTL 54
%assign SYS_SIGACTION 67
%assign SYS_SELECT 142
%assign VT_GETMODE 0x00005601
%assign VT_SETMODE 0x00005602
%assign VT_GETSTATE 0x00005603
%assign VT_RELDISP 0x00005605
%assign VT_PROCESS 1
%assign SIGUSR1 10
%assign SIGUSR2 12
%assign STDIN 0
%assign SA_RESTART 0x10000000
struc tvtmode
alignb 4
tvtmode_mode: resb 1
tvtmode_waitv: resb 1
tvtmode_relsig: resw 1
tvtmode_acqsig: resw 1
tvtmode_frsig: resw 1
endstruc
%if tvtmode_size != 8
%error "wrong size"
%endif
struc tvtstat
alignb 4
tvtstat_active: resw 1
tvtstat_signal: resw 1
tvtstat_state: resw 1
endstruc
%if tvtstat_size > 8
%error "wrong size"
%endif
%assign VT_MODE_SAVED 0x00000001
;****************************************************************************
;* data
;****************************************************************************
section .data
align 4
vt_state: dd 0
vt_flag: dd 0
section .bss
alignb 4
exit_handler: resd 1
error_handler: resd 1
vtmode_data: resb tvtmode_size
vtmode_original: resb tvtmode_size
vtstat_data: resb tvtstat_size
;****************************************************************************
;* vt_start
;****************************************************************************
section .text
vt_start:
xor dword eax, eax
xor dword ebx, ebx
call near vt_init
;mainloop: this code checks if the user
;pressed enter and checks if we have to switch the virtual terminal
.keypress1:
call near vt_check_keypress
cmp dword eax, byte 1
je near vt_end
call near vt_check_release
test dword eax, eax
js short .keypress1
call near vt_commit_release
test dword eax, eax
js short .keypress1
.keypress2:
call near vt_check_keypress ;vt is not active => no keypress
;possible, we simply use select to
;wait here
call near vt_check_acquire
test dword eax, eax
js short .keypress2
jmp short .keypress1
;****************************************************************************
;* vt_init
;****************************************************************************
section .text
vt_init:
mov dword [exit_handler], eax
mov dword [error_handler], ebx
;signal handler for release and acquire signal
xor dword edx, edx
push dword edx
push dword SA_RESTART
push dword edx
push dword vt_release_handler
mov dword eax, SYS_SIGACTION
mov dword ebx, SIGUSR1
mov dword ecx, esp
int byte 0x80
add dword esp, byte 16
test dword eax, eax
js near vt_error
xor dword edx, edx
push dword edx
push dword SA_RESTART
push dword edx
push dword vt_acquire_handler
mov dword eax, SYS_SIGACTION
mov dword ebx, SIGUSR2
mov dword ecx, esp
int byte 0x80
add dword esp, byte 16
test dword eax, eax
js near vt_error
;get current active virtual terminal
mov dword eax, SYS_IOCTL
mov dword ebx, STDIN
mov dword ecx, VT_GETSTATE
mov dword edx, vtstat_data
int byte 0x80
test dword eax, eax
js near vt_error
mov dword eax, SYS_IOCTL
mov dword ebx, STDIN
mov dword ecx, VT_GETMODE
mov dword edx, vtmode_data
int byte 0x80
test dword eax, eax
js near vt_error
mov dword eax, [vtmode_data]
mov dword ebx, [vtmode_data + 4]
mov dword [vtmode_original], eax
mov dword [vtmode_original + 4], ebx
or dword [vt_state], VT_MODE_SAVED
;tell the kernel which signals to use
mov byte [vtmode_data + tvtmode_mode], VT_PROCESS
mov word [vtmode_data + tvtmode_relsig], SIGUSR1
mov word [vtmode_data + tvtmode_acqsig], SIGUSR2
mov dword eax, SYS_IOCTL
mov dword ebx, STDIN
mov dword ecx, VT_SETMODE
mov dword edx, vtmode_data
int byte 0x80
test dword eax, eax
js near vt_error
ret
;****************************************************************************
;* vt_check_keypress
;****************************************************************************
section .text
vt_check_keypress:
push dword (1 << STDIN)
mov dword ecx, esp
push dword 50000 ;1/20 second
push dword 0
mov dword eax, SYS_SELECT
mov dword ebx, (STDIN + 1)
xor dword edx, edx
xor dword esi, esi
mov dword edi, esp
int byte 0x80
add dword esp, byte 12
ret
;****************************************************************************
;* vt_check_release
;****************************************************************************
section .text
vt_check_release:
xor dword eax, eax
cmp dword [vt_flag], byte 1
je short .release
dec dword eax
.release:
ret
;****************************************************************************
;* vt_commit_release
;****************************************************************************
section .text
vt_commit_release:
mov dword eax, SYS_IOCTL
mov dword ebx, STDIN
mov dword ecx, VT_RELDISP
mov dword edx, 1
int byte 0x80
test dword eax, eax
jns short .release
mov dword [vt_flag], 0
.release:
ret
;****************************************************************************
;* vt_check_acquire
;****************************************************************************
section .text
vt_check_acquire:
xor dword eax, eax
cmp dword eax, [vt_flag]
je short .acquire
dec dword eax
.acquire:
ret
;****************************************************************************
;* vt_release_handler
;****************************************************************************
section .text
vt_release_handler:
mov dword [vt_flag], 1
ret
;****************************************************************************
;* vt_acquire_handler
;****************************************************************************
section .text
vt_acquire_handler:
sub dword esp, byte 8
mov dword eax, SYS_IOCTL
mov dword ebx, STDIN
mov dword ecx, VT_GETSTATE
mov dword edx, esp
int byte 0x80
mov word bx, [esp + tvtstat_active]
add dword esp, byte 8
test dword eax, eax
js short .no_acquire
cmp word bx, [vtstat_data + tvtstat_active]
jne short .no_acquire
mov dword [vt_flag], 0
.no_acquire:
ret
;****************************************************************************
;* vt_restore
;****************************************************************************
section .text
vt_restore:
test dword [vt_state], VT_MODE_SAVED
jz short .no_mode_saved
mov dword eax, SYS_IOCTL
mov dword ebx, STDIN
mov dword ecx, VT_SETMODE
mov dword edx, vtmode_original
int byte 0x80
.no_mode_saved:
ret
;****************************************************************************
;* vt_error
;****************************************************************************
section .text
vt_error:
call near vt_restore
xor dword eax, eax
cmp dword eax, [error_handler]
je short .no_handler
jmp dword [error_handler]
.no_handler:
inc dword eax
mov dword ebx, eax
int byte 0x80
;****************************************************************************
;* vt_end
;****************************************************************************
section .text
vt_end:
call near vt_restore
xor dword eax, eax
cmp dword eax, [exit_handler]
je short .no_handler
jmp dword [exit_handler]
.no_handler:
xor dword ebx, ebx
inc dword eax
int byte 0x80
;*********************************************** linuxassembly@unusedino.de *
|