better terminal support
This commit is contained in:
parent
3a8d170f05
commit
2f9ae98c96
70
term.py
70
term.py
|
@ -1,51 +1,49 @@
|
||||||
#!/usr/bin/python
|
#/usr/bin/env python
|
||||||
#
|
|
||||||
# ./term.py term.rom /bin/bash
|
|
||||||
|
|
||||||
from select import select
|
import fcntl
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
import os
|
||||||
|
import pty
|
||||||
import sys
|
import sys
|
||||||
|
import struct
|
||||||
# currently unbuffered
|
import termios
|
||||||
#
|
|
||||||
# TODO: figure out a more reasonable buffering strategy
|
|
||||||
def run(args):
|
|
||||||
return Popen(args, stdin=PIPE, stdout=PIPE, stderr=STDOUT, bufsize=0)
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
# check usage
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
if len(args) < 2:
|
if len(args) < 1:
|
||||||
print('usage: %s ROM SHELL [ ARGS... ]')
|
print('usage: %s ROM')
|
||||||
print('')
|
print('')
|
||||||
print('execute the given uxn terminal program (ROM)')
|
print(' ROM: the rom file to launch')
|
||||||
print('and start a shell process (SHELL + ARGS).')
|
|
||||||
print('')
|
|
||||||
print('example: %s term.rom /bin/bash -i' % sys.argv[0])
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
term = run(['uxnemu', args[0]])
|
# path to rom to run
|
||||||
term_out = term.stdout.fileno()
|
rom = args[0]
|
||||||
|
|
||||||
shell = run(args[1:])
|
# fork with a new pty
|
||||||
shell_out = shell.stdout.fileno()
|
pid, fd = pty.fork()
|
||||||
|
|
||||||
while shell.poll() is None and term.poll() is None:
|
if pid == 0:
|
||||||
# wait 100ms to see if anything is ready to write
|
# set TERM to something we can handle
|
||||||
ns, _, _ = select([term_out, shell_out], [], [], 0.1)
|
env = dict(os.environ)
|
||||||
for n in ns:
|
env['TERM'] = 'dumb'
|
||||||
if n == term_out:
|
os.execvpe('bash', ['bash', '--noediting', '-i'], env)
|
||||||
shell.stdin.write(term.stdout.read(1))
|
|
||||||
shell.stdin.flush()
|
|
||||||
elif n == shell_out:
|
|
||||||
term.stdin.write(shell.stdout.read(1))
|
|
||||||
term.stdin.flush()
|
|
||||||
else:
|
else:
|
||||||
raise Exception('unexpected fileno: %d (expected %d or %d)' % (n, term_out, shell_out))
|
# set the terminal size
|
||||||
|
#cols, rows = 63, 32
|
||||||
|
cols, rows = 79, 40
|
||||||
|
size = struct.pack("HHHH", rows, cols, 8, 8)
|
||||||
|
fcntl.ioctl(fd, termios.TIOCSWINSZ, size)
|
||||||
|
|
||||||
if shell.poll() is None:
|
# disable terminal echo
|
||||||
shell.kill()
|
attr = termios.tcgetattr(fd)
|
||||||
if term.poll() is None:
|
attr[3] = attr[3] & ~termios.ECHO
|
||||||
term.kill()
|
termios.tcsetattr(fd, termios.TCSADRAIN, attr)
|
||||||
|
|
||||||
|
# use fd for the terminals stdin/stdout
|
||||||
|
os.dup2(fd, sys.stdin.fileno())
|
||||||
|
os.dup2(os.dup(fd), sys.stdout.fileno())
|
||||||
|
os.execvp('uxnemu', ['uxnemu', rom])
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
49
term.tal
49
term.tal
|
@ -18,18 +18,18 @@
|
||||||
@subinput $1 ( reading from subprocess? )
|
@subinput $1 ( reading from subprocess? )
|
||||||
|
|
||||||
|0100
|
|0100
|
||||||
( 32 characters = 256 pixels )
|
( 80 cols x 24 rows )
|
||||||
#0020 .rows STZ2
|
#0028 .rows STZ2
|
||||||
#0040 .cols STZ2
|
#0050 .cols STZ2
|
||||||
|
|
||||||
( set screen height/width based on rows/cols )
|
( set screen height/width based on rows/cols )
|
||||||
.rows LDZ2 #30 SFT2 .Screen/h DEO2
|
.rows LDZ2 #30 SFT2 .Screen/h DEO2
|
||||||
.cols LDZ2 #30 SFT2 .Screen/w DEO2
|
.cols LDZ2 #30 SFT2 .Screen/w DEO2
|
||||||
|
|
||||||
( set colors )
|
( set colors )
|
||||||
#0ff0 .System/r DEO2
|
#0cf0 .System/r DEO2
|
||||||
#0f88 .System/g DEO2
|
#0c88 .System/g DEO2
|
||||||
#0f0f .System/b DEO2
|
#0c0f .System/b DEO2
|
||||||
|
|
||||||
( set pos, subinput flag )
|
( set pos, subinput flag )
|
||||||
.buffer .pos STZ
|
.buffer .pos STZ
|
||||||
|
@ -99,15 +99,15 @@
|
||||||
;draw-tile JMP2
|
;draw-tile JMP2
|
||||||
|
|
||||||
@on-key
|
@on-key
|
||||||
.Controller/key DEI #00 EQU ,&skip JCN
|
|
||||||
#00 .subinput STZ
|
#00 .subinput STZ
|
||||||
|
.Controller/key DEI #00 EQU ,&skip JCN
|
||||||
#41 .tint STZ
|
#41 .tint STZ
|
||||||
.Controller/key DEI ;read JSR2
|
.Controller/key DEI ;read JSR2
|
||||||
&skip BRK
|
&skip BRK
|
||||||
|
|
||||||
@on-input
|
@on-input
|
||||||
.Console/r DEI #00 EQU ,&skip JCN
|
|
||||||
#01 .subinput STZ
|
#01 .subinput STZ
|
||||||
|
.Console/r DEI #00 EQU ,&skip JCN
|
||||||
#41 .tint STZ
|
#41 .tint STZ
|
||||||
.Console/r DEI ;read JSR2
|
.Console/r DEI ;read JSR2
|
||||||
&skip BRK
|
&skip BRK
|
||||||
|
@ -123,11 +123,10 @@
|
||||||
;read-normal JMP2
|
;read-normal JMP2
|
||||||
|
|
||||||
( TODO: we need line-editing! )
|
( TODO: we need line-editing! )
|
||||||
@read-bel JMP2r
|
@read-bel POP JMP2r
|
||||||
@read-bs JMP2r ( POP ;scroll JMP2 )
|
@read-bs POP JMP2r ( POP ;scroll JMP2 )
|
||||||
@read-tab JMP2r ( POP POP2r #0000 DIV )
|
@read-esc POP JMP2r
|
||||||
@read-esc JMP2r
|
@read-del POP JMP2r
|
||||||
@read-del JMP2r
|
|
||||||
|
|
||||||
@write-line ( -> )
|
@write-line ( -> )
|
||||||
.pos LDZ .buffer
|
.pos LDZ .buffer
|
||||||
|
@ -135,17 +134,33 @@
|
||||||
&next LDZk .Console/w DEO INC ,&loop JMP
|
&next LDZk .Console/w DEO INC ,&loop JMP
|
||||||
&done #0a .Console/w DEO .buffer .pos STZ JMP2r
|
&done #0a .Console/w DEO .buffer .pos STZ JMP2r
|
||||||
|
|
||||||
|
( @read-tab POP JMP2r )
|
||||||
|
@read-tab
|
||||||
|
POP
|
||||||
|
.subinput LDZ ,&display JCN
|
||||||
|
#01 #0e DEO JMP2r ( POP POP2r #0000 DIV )
|
||||||
|
&display
|
||||||
|
.cur-x LDZ2 NIP #07 AND #08 SUB
|
||||||
|
&loop
|
||||||
|
#20 DUP ;cursor-addr JSR2 STA
|
||||||
|
;draw-tile JSR2
|
||||||
|
;forward JSR2
|
||||||
|
INC DUP ,&loop JCN
|
||||||
|
POP JMP2r
|
||||||
|
|
||||||
@read-cr ( 0d -> )
|
@read-cr ( 0d -> )
|
||||||
|
POP
|
||||||
.subinput LDZ ,&display JCN
|
.subinput LDZ ,&display JCN
|
||||||
;write-line JSR2
|
;write-line JSR2
|
||||||
&display
|
&display
|
||||||
POP
|
|
||||||
;hide-cursor JSR2
|
;hide-cursor JSR2
|
||||||
#0000 .cur-x STZ2
|
#0000 .cur-x STZ2
|
||||||
;down JMP2
|
;down JMP2
|
||||||
|
|
||||||
@read-nl ( 0a -> )
|
@read-nl ( 0a -> )
|
||||||
,read-cr JMP
|
POP
|
||||||
|
JMP2r
|
||||||
|
( ,read-cr JMP )
|
||||||
|
|
||||||
@forward ( -> )
|
@forward ( -> )
|
||||||
.cur-x LDZ2 INC2 DUP2 .cols LDZ2 LTH2 ,&ok JCN
|
.cur-x LDZ2 INC2 DUP2 .cols LDZ2 LTH2 ,&ok JCN
|
||||||
|
@ -179,7 +194,6 @@
|
||||||
.subinput LDZ ,&display JCN
|
.subinput LDZ ,&display JCN
|
||||||
.pos LDZ STZk INC .pos STZ
|
.pos LDZ STZk INC .pos STZ
|
||||||
&display
|
&display
|
||||||
;hide-cursor JSR2
|
|
||||||
DUP ;cursor-addr JSR2 STA
|
DUP ;cursor-addr JSR2 STA
|
||||||
;draw-tile JSR2
|
;draw-tile JSR2
|
||||||
;forward JMP2
|
;forward JMP2
|
||||||
|
@ -213,5 +227,6 @@
|
||||||
~chr/ascii.tal
|
~chr/ascii.tal
|
||||||
|
|
||||||
( screen to store characters for redraw, etc. )
|
( screen to store characters for redraw, etc. )
|
||||||
@screen $0800 ( 64 x 32 )
|
( @screen $0800 ( 64 x 32 ) )
|
||||||
|
@screen $0c80 ( 64 x 32 )
|
||||||
@end-screen
|
@end-screen
|
||||||
|
|
Loading…
Reference in New Issue