Implement HTAB and VTAB in HRCG terminal, fix character set addressing error
authorNick Downing <nick@ndcode.org>
Wed, 25 May 2022 05:18:36 +0000 (15:18 +1000)
committerNick Downing <nick@ndcode.org>
Wed, 25 May 2022 05:18:36 +0000 (15:18 +1000)
apple_io.py
hrcg/terminal.asm

index 703d983..15bfece 100644 (file)
@@ -245,6 +245,10 @@ current_gr = False
 current_speed = 255
 hrcg = False
 
+COUT_STATE_NORMAL = 0
+COUT_STATE_CTRL_A = 1
+cout_state = COUT_STATE_NORMAL
+
 def init():
   global termios_attr, pcm
 
@@ -308,50 +312,61 @@ def crlf():
   low_mem[ZP_CH] = low_mem[ZP_WNDLFT]
 
 def _print(data):
-  for ch in data:
-    if ch == '\a':
-      tone(1000., .1) # 1 kHz for .1 sec
-    elif ch == '\b':
-      if low_mem[ZP_CH] > low_mem[ZP_WNDLFT]:
-        write('\b')
-        low_mem[ZP_CH] -= 1
-    elif ch == '\n':
-      write('\n')
-      low_mem[ZP_CV] += 1
-      if low_mem[ZP_CV] >= low_mem[ZP_WNDBTM]:
-        low_mem[ZP_CV] = low_mem[ZP_WNDBTM] - 1
-    elif ch == '\r':
-      # apple treats \r as \r\n, so if you write e.g. \r\n you'll get \r\n\n
-      if hrcg:
-        write('\r')
-      crlf()
-    elif ord(ch) >= 0x20:
-      # some applications expect BASL, BASH = base address of current line
-      addr = bascalc(low_mem[ZP_CV])
-      low_mem[ZP_BASL] = addr & 0xff
-      low_mem[ZP_BASH] = addr >> 8
-      i = ord(ch)
-      data = (
-        (i & 0x3f) ^ 0x60
-      if invflg == INVFLG_FLASH else
-        (i & 0x3f) ^ 0x20
-      if invflg == INVFLG_INVERSE else
-        i | 0x80
-      )
-      low_mem[addr + low_mem[ZP_CH]] = data
+  global cout_state
 
-      if current_gr and low_mem[ZP_CV] < 20:
-        write(gr_encode([data])[0] + invflg())
-      else:
-        write(ch)
-      low_mem[ZP_CH] += 1
-      if low_mem[ZP_CH] >= low_mem[ZP_WNDLFT] + low_mem[ZP_WNDWTH]:
+  for ch in data:
+    if cout_state == COUT_STATE_NORMAL:
+      if ch == '\a':
+        tone(1000., .1) # 1 kHz for .1 sec
+      elif ch == '\b':
+        if low_mem[ZP_CH] > low_mem[ZP_WNDLFT]:
+          write('\b')
+          low_mem[ZP_CH] -= 1
+      elif ch == '\n':
+        write('\n')
+        low_mem[ZP_CV] += 1
+        if low_mem[ZP_CV] >= low_mem[ZP_WNDBTM]:
+          low_mem[ZP_CV] = low_mem[ZP_WNDBTM] - 1
+      elif ch == '\r':
+        # apple treats \r as \r\n, so if you write e.g. \r\n you'll get \r\n\n
+        if hrcg:
+          write('\r')
         crlf()
-
-      if current_speed < 255:
-        time.sleep((255 - current_speed) / 2550.) # up to .1s
-    elif hrcg:
+      elif ord(ch) >= 0x20:
+        # some applications expect BASL, BASH = base address of current line
+        addr = bascalc(low_mem[ZP_CV])
+        low_mem[ZP_BASL] = addr & 0xff
+        low_mem[ZP_BASH] = addr >> 8
+        i = ord(ch)
+        data = (
+          (i & 0x3f) ^ 0x60
+        if invflg == INVFLG_FLASH else
+          (i & 0x3f) ^ 0x20
+        if invflg == INVFLG_INVERSE else
+          i | 0x80
+        )
+        low_mem[addr + low_mem[ZP_CH]] = data
+
+        if current_gr and low_mem[ZP_CV] < 20:
+          write(gr_encode([data])[0] + invflg())
+        else:
+          write(ch)
+        low_mem[ZP_CH] += 1
+        if low_mem[ZP_CH] >= low_mem[ZP_WNDLFT] + low_mem[ZP_WNDWTH]:
+          crlf()
+
+        if current_speed < 255:
+          time.sleep((255 - current_speed) / 2550.) # up to .1s
+      elif hrcg:
+        write(ch)
+        if ord(ch) == 1: # ctrl-a
+          cout_state = COUT_STATE_CTRL_A
+    elif cout_state == COUT_STATE_CTRL_A:
+      # doesn't advance cursor
       write(ch)
+      COUT_STATE = COUT_STATE_NORMAL
+    else:
+      assert False
 
 def get_internal():
   global ch_in
@@ -482,7 +497,7 @@ def tone(freq, dur): # Hz, s
     while i < len(buf):
       i += pcm.write(buf[i:])
     pcm.close()
-  else: 
+  else:
     assert False
 
 def himem(addr):
index be6b7bd..8a202f8 100644 (file)
@@ -4,9 +4,11 @@ wndtop equ     $22
 wndbtm equ     $23
 ch     equ     $24
 cv     equ     $25
+state  equ     $fe
+number equ     $ff
 chario equ     $3ea
 hrcg   equ     $8dff
-extfont        equ     hrcg+6
+extfont        equ     hrcg+7
 font   equ     hrcg-$600               hard coded 2 sets
 kbd    equ     $c000
 kbdstrb        equ     $c010
@@ -37,6 +39,8 @@ cout  equ     $fded
        lda     #<font
        sta     extfont+1
        jsr     hrcg
+       ldx     #0
+newst  stx     state
 loop   lda     sout.s
        bpl     nosout
        lda     kbd
@@ -48,7 +52,52 @@ loop lda     sout.s
 nosout lda     sin.s
        bpl     nosin
        lda     sin.d
-       ora     #$80
+       ldx     state
+       beq     state0
+       dex
+       beq     state1
+       dex
+       beq     state2
+       lda     #1
+       sta     s.exit
+state0 cmp     #$1b                    esc
+       bne     notesc
+       inx
+       jmp     newst
+state1 cmp     #$5b                    [
+       bne     aborte
+       stx     number
+       ldx     #2
+       jmp     newst
+state2 cmp     #$30                    0
+       bcc     aborte
+       cmp     #$3a
+       bcs     notdig
+       sec
+       sbc     #$30                    digit value
+       asl     number
+       clc
+       adc     number                  + number * 2
+       asl     number
+       asl     number
+       clc
+       adc     number                  + number * 8
+       sta     number                  to number
+       jmp     loop
+notdig cmp     #$47                    G
+       bne     notch
+       dec     number
+       lda     number
+       sta     ch
+       jmp     newst
+notch  cmp     #$64                    d
+       bne     aborte
+       dec     number
+       lda     number
+       sta     cv
+       jmp     newst
+aborte stx     state
+notesc ora     #$80
        jsr     cout
        jmp     loop
 nosin  lda     >1000