poll_in = select.poll()
poll_in.register(fd_in, select.POLLIN)
mem = {
+ ZP_WNDLFT: 0,
+ ZP_WNDWTH: 40,
+ ZP_WNDTOP: 0,
+ ZP_WNDBTM: 24,
ZP_CH: 0,
ZP_CV: 0,
0x300: 0, # tone period
elif mem[ZP_CH] < 39:
mem[ZP_CH] += 1
else:
+ write('\r\n')
if mem[ZP_CV] < 23:
mem[ZP_CV] += 1
mem[ZP_CH] = 0
line = ''
while True:
ch = get()
- _print(ch)
- if ch == '\r':
- write('\x1b[?25l') # hide cursor
- return line
if ch == '\b':
if len(line):
- _print(' \b')
+ _print('\b \b')
line = line[:-1]
- else:
- # strictly, apple only does this if cursor not at left, maybe
- # because it knows the echoed backspace has no effect at left
+ elif mem[ZP_CH]:
_print('\r')
else:
- if len(line) >= 247:
- _print('\a')
- if len(line) >= 255:
- _print('\r')
- line = ''
- continue
- line += ch
+ _print(ch)
+ if ch == '\r':
+ write('\x1b[?25l') # hide cursor
+ return line
+ else:
+ if len(line) >= 247:
+ _print('\a')
+ if len(line) >= 255:
+ _print('\r')
+ line = ''
+ continue
+ line += ch
def htab(x):
write(f'\x1b[{x:d}G')
pass
def peek(addr):
- return mem.get(addr & 0xffff, 0)
+ addr &= 0xffff
+ return mem.get(addr, 0)
def poke(addr, data):
- mem[addr & 0xffff] = data & 0xff
+ addr &= 0xffff
+ data &= 0xff
+ mem[addr] = data
+ if addr == ZP_WNDTOP or addr == ZP_WNDBTM:
+ # save cursor, set scrolling region, restore cursor
+ write(f'\x1b[s\x1b{mem[ZP_WNDTOP + 1]:d};{mem[ZP_WNDBTM]:d}24r\x1b[u')
def call(addr):
addr &= 0xffff
raise Exception(f'call {addr:04x}')
def text():
- pass
+ # save cursor, set scrolling region, restore cursor
+ write('\x1b[s\x1b1;24r\x1b[u')
+ mem[ZP_WNDLFT] = 0
+ mem[ZP_WNDWTH] = 40
+ mem[ZP_WNDTOP] = 0
+ mem[ZP_WNDBTM] = 24
def gr():
- write('\x1b[2J\x1b[21H')
+ # clear screen, set scrolling region (homes cursor)
+ mem[ZP_WNDLFT] = 0
+ mem[ZP_WNDWTH] = 40
+ mem[ZP_WNDTOP] = 20
+ mem[ZP_WNDBTM] = 24
mem[ZP_CH] = 0
mem[ZP_CV] = 20
for i in range(40):