Ah, yes... Linux is "different"... :) AFAIK, there's no "magic sys_call" that will help, but the common ones can be used in the "right combination" to do what you want, I think...
AFAIK, the "right" way is to use the "ncurses" library (my take is that you "might as well use C", if you're going to do it "that" way :)
Another way would be to use the "VT100 escape sequences" - like ansi.sys in dos, if you're familiar with that... Start with an "escape" character, 1Bh or 27 decimal. Most, but not all, follow with '['. Just write 'em to stdout. You can "query cursor position" with "db 1Bh, '[6n'". Reports the position to stdout(?) and messes up the display - maybe there's a way to "capture" this - if so,I haven't figured it out. You can "save current cursor poition [and attributes]" and "unsave" it - lord knows where it's stored. Unless you need cursor position for some reason other than "unsaving" it, this may help. Setting the position, colors, etc. is easy. This assumes that VT100 emulation is available... which it "usually" is, IME. There are escape sequences to check if the device is present and functioning (suspect they report to stdout, too)... This is the first of many that google found:
http://www.termsys.demon.co.uk/vtansi.htmThen... you may have heard that, in Unix "everything's a file". If you open "/dev/vcsa0", you can read/write what's on screen. First 4 bytes are screen size and cursor position. I have not had any success *setting* cursor position by writing those bytes, though. After those bytes, it's char, attr, char, attr,... just like a "direct screen write" to B800:???? in dos. Gotta be root to write that file (or, as root, "chown root:root mygem", "chmod +s mygem" - then the program runs as root, even if the user isn't). There are /dev/vsc? devices that use just characters - never tried that one. Note that there are several /dev/vcsa? numbers - 0 may not always be right. (I opened /dev/mouse in a console, and could read it, but it screwed up the mouse in my GUI as long as I had that file open - I don't know what the solution is) Possible issue with dev/vcsa0, too - but it "seems to work"...
As you know, bios ints are 16-bit code, and won't run in 32-bit Linux... unless... You can set up a v86 task in Linux which *will* allow you to use bios (etc.). There's a "linux real mode interface" library -
http://lmri.sf.net - to assist with this. Their example (setting video modes) works for me, but I haven't had any luck using it in my own code. I suspect that's the "hard way"...
A guy who goes by "Richard Cooper", also known as "PJ", has written a thing called "softer" which implements the "orange" protocol (??? like ansi.sys? a BBS thing, I think). This uses ports to set and run vga "mode 13" graphics - pretty chunky - and also has text/cursor manipulation routines. I *think* getcursor is in there, setcursor definitely is. I can dig up that code, if you want to look at it...
Don't be ashamed to ask for help. As you've found out, any kind of "graphics" - even get/set cursor - is a murky area in Linux - "here there be dragons"! We've gotta share any tidbit we find, or it'll remain murky.
In that spirit, here are a couple "rudimentary experiments" I've got. Not very useful, as is.
Ncurses (I named this "ncursed.asm"):
;-------------------
; nasm -f elf mygem.asm
; ld -o mygem mygem.o -I/lib/ld-linux.so.2 -lncurses
global _start
extern initscr
extern endwin
section .text
_start:
call initscr
; ???
; if all else fails, RTFM
; ???
call endwin
mov eax, 1
int 80h
;---------------------
VT100:
;---------------------------
; nasm -f elf mygem.asm
; ld -o mygem mygem.o
global _start
section .data
savecursor db 1Bh, '[s'
.len equ $ - savecursor
unsavecursor db 1Bh, '[u'
.len equ $ - unsavecursor
getcursor db 1Bh, '[6n'
.len equ $ - getcursor
setcursor db 1Bh, '[10;20H'
.len equ $ - setcursor
msg db "Hello, new cursor position!"
.len equ $ - msg
section .text
_start:
mov ecx, savecursor
mov edx, savecursor.len
call write_stdout
mov ecx, setcursor
mov edx, setcursor.len
call write_stdout
mov ecx, msg
mov edx, msg.len
call write_stdout
mov ecx, unsavecursor
mov edx, unsavecursor.len
call write_stdout
mov eax, 1
xor ebx, ebx
int 80h
;----------------
write_stdout:
push eax
push ebx
mov eax, 4
mov ebx, 1
int 80h
pop ebx
pop eax
ret
;---------------------
/dev/vcsa0 (especially crude):
;-------------------------
; nasm -f elf mygem.asm
; ld -o mygem mygem.o
;
; (as root)
; chown root:root mygem
; chmod +s mygem
; (don't forget to "exit"!)
; (if you want to run it as "user"
;
global _start
SCREEN_SIZE equ 80 * 25 * 2 + 4
section .text
_start:
nop
mov eax, 5 ; __NR_open
mov ebx, screen_dev
mov ecx, 2 ; O_rdwr
int 80h
test eax, eax
js error
mov [screen_fd], eax
mov eax, 3 ; __NR_read
mov ebx, [screen_fd]
mov ecx, old_screen
mov edx, SCREEN_SIZE
int 80h
test eax, eax
js error
mov eax, [old_screen]
mov [new_screen], eax
mov eax, 19 ; __NR_lseek
mov ebx, [screen_fd]
mov ecx, 0
mov edx, 0
int 80h
test eax, eax
js error
mov byte [new_screen + 2], 20
mov byte [new_screen + 3], 5
mov eax, 4 ; __NR_write
mov ebx, [screen_fd]
mov ecx, new_screen
mov edx, SCREEN_SIZE
int 80h
test eax, eax
js error
mov eax, [old_screen]
call showeaxh
mov eax, 3 ; __NR_read
mov ebx, 0 ; STDIN
mov ecx, key_buf
mov edx, 1
int 80h
mov eax, 19 ; __NR_lseek
mov ebx, [screen_fd]
mov ecx, 0
mov edx, 0
int 80h
test eax, eax
js error
mov eax, 4 ; __NR_write
mov ebx, [screen_fd]
mov ecx, old_screen
mov edx, SCREEN_SIZE
int 80h
test eax, eax
js error
xor eax, eax
error:
neg eax
mov ebx, eax
mov eax, 1 ; __NR_exit
int 80h
;------------------------------
showeaxh:
push eax
push ebx
push ecx
push edx
sub esp, 10h
mov ecx, esp
xor edx, edx
mov ebx, eax
.top:
rol ebx, 4
mov al, bl
and al, 0Fh
cmp al, 0Ah
sbb al, 69h
das
mov [ecx + edx], al
inc edx
cmp edx, 8
jnz .top
; stuff a newline in there
mov byte [ecx + edx], 10
inc edx
mov ebx, 1
mov eax, 4
int 80h
add esp, 10h
pop edx
pop ecx
pop ebx
pop eax
ret
;------------------------------
section .data
screen_dev db "/dev/vcsa0", 0
new_screen db 0, 0, 10, 10
times 100 db 20h, 10h
db "P", 7,"r", 7, "e", 7, "s", 7, "s", 7, " ",7, "e", 7, "n", 7, "t", 7, "e", 7, "r", 7, "!", 15
section .bss
screen_fd resd 1
old_screen resb SCREEN_SIZE
key_buf resb 1
;------------------------
That's about all I know right now. Always willing to learn...
Best,
Frank