The emulator is probably a smarter idea, but we *can* get permission to diddle the ports. I don't think it's what we "should" do. Probably messing with ioctls to make the changes we want is safer. But we *can*...
Best,
Frank
global _start
; LED junk example | (CL) 2008 by ??? | 63 bytes !!!
; modified for Linux, fbk
; no longer 63 bytes!
;
; nasm -f elf32 kbled.asm
; ld -o kbled kbled.o
;
; (as root)
; chown root:root kbled
; chmod +s kbled
; (or run as root)
section .text
_start:
nop ; parking place for gdb
mov ebx, 60h ; starting port
mov ecx, 5 ; how many ports
mov edx, 3 ; read/write (?)
mov eax, 101 ; __NR_ioperm
int 80h
test eax, eax
jns okay_ioperm
neg eax ; (for display with "echo $?")
jmp exit
okay_ioperm:
;------------------------------;
; Rotate the keyboard LED's ;
;------------------------------;
;-------------------------------------------------------------------;
; _________________ LED status byte: ;
; |0|0|0|0|0|1|1|1| ;
; +---------------+ 1 = True 0 = False ;
; | | +---> scroll lock ;
; | +-----> num lock ;
; +-------> caps lock ;
;-------------------------------------------------------------------;
; Main start
mov dl, 100 ; Amount of loops
mov bl, 2 ; Starting value
loo:
; Write to the LED's
call kbdwait
mov al, $0ED ; command for "LED"
out $60, al
call kbdwait
mov al, bl ; The LED value finally
out $60, al
; call kbdwait ; we need this one?
; Rotate
shl bl, 1
cmp bl, 8
jne .continue
mov bl, 1
.continue:
mov eax, 500000000 ; 'arf a sec, guvnor
call delay
; Continue or abort
dec dl
jnz loo ; Looping back to the loo :-D
xor eax, eax ; no error
exit:
mov ebx, eax
mov eax, 1 ; __NR_exit
int 80h
;----
;------------------;
; keyboard wait ;
;------------------;
; b1 input buffer full (input 60/64 has data for 8042)
; no write access allowed until bit clears
; b0 output buffer full (output 60 has data for system)
; bit is cleared after read access
kbdwait:
; out $0ED, al ; "DUMMY" port (as $EB) for delaying
in al, $64
test al, 1 ; Something to pick ?
jz short .inbuf_empty ; NO :-(
; out $0ED, al ; "DUMMY" port (as $EB) for delaying
in al, $60 ; Eat it
jmp short kbdwait
;------------------
.inbuf_empty: test al, 2 ; Buffer full flag - can write now ?
jnz short kbdwait ; Full - NO :-(
ret
;----
;------------------
delay:
push ebx
push ecx
cmp eax, byte 1
jbe .no_delay
xor ebx, ebx
.check_ns:
cmp eax, 1000000000 ; limit for nanosleep 999999999 ns...
jb .okay_ns
sub eax, 1000000000
inc ebx
jmp short .check_ns
.okay_ns:
push eax ; set up a time_spec structure on the stack
push ebx
.take_a_nap:
mov eax, 162 ; __NR_nanosleep
mov ebx, esp ; same structure for "request"
mov ecx, esp ; and "remaining" - does this work?
int 80h
cmp eax, byte -4 ; -EINTR
jz .take_a_nap
add esp, byte 8 ; remove time_spec "structure"
.no_delay:
pop ecx
pop ebx
ret
;------------------