all repos — xyw @ 3007

A minimal virtual machine and assembler for terminals.

examples/clock-repl.xyw

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
.include "lib/macros.xyw"

; Clock REPL - demonstrates simultaneous keypress + timer handling.
; The prompt shows a live clock [HH:MM:SS] that updates every second
; while accepting keyboard input. Type a line and press Enter to echo it.

; Main program: show initial prompt, register both handlers, halt
print-prompt JSRw
setup-handlers JSRw
HLT

.include "lib/putd.xyw"
.include "lib/puts.xyw"

; Register keypress and timer handlers, start 1-second timer
; --
.label setup-handlers
  on-keypress terminal.on_keypress STW
  on-timer clock.on_timer STW
  $0100 clock.timer STW
  RTS

; Timer handler: redraw the prompt line with updated clock
; --
.label on-timer
  redraw-line JSRw
  $0100 clock.timer STW
  RTS

; Keypress handler
; --
.label on-keypress
  terminal.input LDB
  ; Enter
  DUP $0D EQU on-enter JCNw
  DUP $0A EQU on-enter JCNw
  ; Backspace (DEL or BS)
  DUP $7F EQU on-backspace JCNw
  DUP $08 EQU on-backspace JCNw
  ; Ignore non-printable
  DUP $20 LTH on-ignore JCNw
  ; Ignore if buffer full (48 chars)
  buf-len LDBw $30 EQU on-ignore JCNw
  ; Store char in buffer at buf[len]
  DUP
  buf-len LDBw $00 SWP buf ADDw STBw
  ; Increment length
  buf-len LDBw INC buf-len STBw
  ; Echo the character
  PUTC
  RTS

.label on-ignore
  POP RTS

; Enter: echo back the line
; --
.label on-enter
  POP
  NL
  echo-prefix puts JSRw
  print-buffer JSRw
  NL
  ; Clear buffer
  $00 buf-len STBw
  ; Show fresh prompt
  print-prompt JSRw
  RTS

; Backspace: remove last character
; --
.label on-backspace
  POP
  buf-len LDBw $00 EQU on-backspace.done JCNw
  buf-len LDBw DEC buf-len STBw
  $08 PUTC $20 PUTC $08 PUTC
  .label on-backspace.done
    RTS

; Print the clock prompt: [HH:MM:SS] > 
; --
.label print-prompt
  $5B PUTC
  clock.hour LDB ZEROPADx JSRw
  $3A PUTC
  clock.minute LDB ZEROPADx JSRw
  $3A PUTC
  clock.second LDB ZEROPADx JSRw
  $5D PUTC SP $3E PUTC SP
  RTS

; Redraw current line in-place: CR + prompt + buffer + clear-to-EOL
; --
.label redraw-line
  $0D PUTC
  print-prompt JSRw
  print-buffer JSRw
  ; ANSI escape: ESC[K (clear to end of line)
  $1B PUTC $5B PUTC $4B PUTC
  RTS

; Print buffer contents (buf[0..len-1])
; -[xw, y]-
.label print-buffer
  buf POPxw
  buf-len LDBw POPy
  .label print-buffer.loop
    PSHy $00 EQU print-buffer.done JCNw
    LDBxw PUTC
    INCxw DECy
    print-buffer.loop JMPw
  .label print-buffer.done
    RTS

; Print 8-bit value with leading zero if < 10
; a8 -[x]-
.label ZEROPADx
  POPx PSHx $0A LTH zeropad.zero JCNw
  .label zeropad.digit
    PSHx putd JSRw
    RTS
  .label zeropad.zero
    $30 PUTC
    zeropad.digit JMPw

; --- Data ---

.label echo-prefix
  .string "< "

.label buf-len
  .byte $00

.label buf
  .byte $00 $00 $00 $00 $00 $00 $00 $00
  .byte $00 $00 $00 $00 $00 $00 $00 $00
  .byte $00 $00 $00 $00 $00 $00 $00 $00
  .byte $00 $00 $00 $00 $00 $00 $00 $00
  .byte $00 $00 $00 $00 $00 $00 $00 $00
  .byte $00 $00 $00 $00 $00 $00 $00 $00