term.asm (4472B)
1 ;;; Copyright 2021 Gerd Beuster (gerd@frombelow.net). This is free 2 ;;; software under the GNU GPL v3 license or any later version. See 3 ;;; COPYING in the root directory for details. 4 5 ;;; 6 ;;; Special commands for ANSI terminals 7 ;;; 8 9 term .namespace 10 .section rom 11 12 ;;; ANSI text attributes 13 plain = 0 14 bold = 1 15 blink = 5 16 reverse = 7 17 18 ;;; ANSI colors 19 black = 0 20 red = 1 21 green = 2 22 yellow = 3 23 blue = 4 24 magenta = 5 25 cyan = 6 26 white = 7 27 bright_black = 8 28 bright_red = 9 29 bright_green = 10 30 bright_yellow = 11 31 bright_blue = 12 32 bright_magenta = 13 33 bright_cyan = 14 34 bright_white = 15 35 36 ;;; get_screen_size 37 ;;; Returns screen size in X, A. 38 ;;; If not supported by terminal, C is set 39 ;;; Input: 40 ;;; - 41 ;;; Output: 42 ;;; X: Screen width 43 ;;; A: Screen height 44 ;;; Changes: 45 ;;; a, x, y, c 46 get_screen_size: 47 .block 48 jsr ds.create_stack_frame 49 #ds.PUSH $02 50 cursor_save_x = 0 ; Local variable 51 cursor_save_y = 1 ; Local variable 52 ;; Local variables 0 & 1: Saved cursor position 53 jsr term.get_cursor ; Save cursor position 54 bcs terminal_does_not_answer 55 #ds.sta_LOCAL cursor_save_y 56 txa 57 #ds.sta_LOCAL cursor_save_x 58 #SET_CURSOR #$FF, #$FF ; Try to move cursor to max. position 59 jsr term.get_cursor ; Get cursor position (= screen size) 60 pha ; Save it temporary 61 txa ; on the 62 pha ; hardware stack. 63 #ds.lda_LOCAL cursor_save_x ; Restore 64 tax ; old 65 #ds.lda_LOCAL cursor_save_y ; cursor 66 jsr term.set_cursor ; position 67 jsr ds.delete_stack_frame 68 pla 69 tax 70 pla 71 rts 72 terminal_does_not_answer: 73 jsr ds.delete_stack_frame 74 ldx #80 75 lda #25 76 rts 77 .bend 78 79 clear_screen: 80 #io.PRINTS x"1b" .. "[2J" 81 rts 82 83 set_color: 84 pha 85 #io.PRINTS x"1b" .. "[38;5;" 86 pla 87 jsr io.putd 88 lda #"m" 89 jmp io.putc 90 91 set_background_color: 92 pha 93 #io.PRINTS x"1b" .. "[48;5;" 94 pla 95 jsr io.putd 96 lda #"m" 97 jmp io.putc 98 99 set_text: 100 tax 101 lda #"m" 102 jmp send_CSI 103 104 cursor_up: 105 tax 106 lda #"A" 107 jmp send_CSI 108 109 cursor_down: 110 tax 111 lda #"B" 112 jmp send_CSI 113 114 cursor_forward: 115 tax 116 lda #"C" 117 jmp send_CSI 118 119 cursor_back: 120 tax 121 lda #"D" 122 jmp send_CSI 123 124 scroll_up: 125 tax 126 lda #"S" 127 jmp send_CSI 128 129 scroll_down: 130 tax 131 lda #"T" 132 jmp send_CSI 133 134 ;;; Send ANSI escape sequence to terminal. 135 ;;; A contains command, X value 136 send_CSI: 137 pha 138 phx 139 lda #$1b 140 jsr io.putc 141 lda #"[" 142 jsr io.putc 143 pla 144 jsr io.putd 145 pla 146 jmp io.putc 147 148 ;;; set_cursor 149 ;;; Sets cursor to position x, a. 150 ;;; Position starts at 1, not 0! 151 ;;; Input: 152 ;;; x: x position 153 ;;; a: y position 154 ;;; Output: 155 ;;; - 156 ;;; Changes: 157 ;;; a, x, y, c 158 ;;; Set Cursor; x position in X, y position in A 159 set_cursor: 160 phx 161 pha 162 lda #$1b 163 jsr io.putc 164 lda #"[" 165 jsr io.putc 166 pla 167 jsr io.putd 168 lda #";" 169 jsr io.putc 170 pla 171 jsr io.putd 172 lda #"H" 173 jmp io.putc 174 175 ;;; get_cursor 176 ;;; Store cursor position in x, a. 177 ;;; Position starts at 1, not 0! 178 ;;; Input: 179 ;;; - 180 ;;; Output: 181 ;;; x: x position 182 ;;; a: y position 183 ;;; Changes: 184 ;;; a, x, y, c 185 get_cursor: 186 .block 187 jsr ds.create_stack_frame 188 #ds.PUSH $08 ; Position as string 189 ;; We store the position string as local variables. 190 ;; By initializing the local variables with #$00, 191 ;; the strings terminate automatically when no 192 ;; more digits are written. 193 lda #$00 194 .for i = 0, i < 8, i += 1 195 #ds.sta_LOCAL i 196 .next 197 ;; Request cursor position 198 #io.PRINTS x"1b" .. "[6n" 199 ;; Read answer 200 ldx #$08 ; Number of tries 201 ldy #$ff ; to get an answer. 202 wait_for_answer: 203 phx 204 phy 205 jsr io.getc_nonblocking ; $1b 206 ply 207 plx 208 bcc terminal_answers 209 dey 210 cpy #$00 211 bne wait_for_answer 212 dex 213 cpx #$00 214 bne wait_for_answer 215 ;; Terminal does not answer. 216 jsr ds.delete_stack_frame 217 lda #$00 218 ldx #$00 219 sec 220 rts 221 terminal_answers: 222 jsr io.getc ; "[" 223 jsr io.getc ; First digit y 224 #ds.sta_LOCAL 0 225 jsr io.getc ; Second digit y 226 cmp #";" 227 beq got_y_position 228 #ds.sta_LOCAL 1 229 jsr io.getc ; Third digit y 230 cmp #";" 231 beq got_y_position 232 #ds.sta_LOCAL 2 233 jsr io.getc ; Read and ignore terminating ';' 234 got_y_position: 235 jsr io.getc ; First digit x 236 #ds.sta_LOCAL 4 237 jsr io.getc ; Second digit x 238 cmp #"R" 239 beq got_x_position 240 #ds.sta_LOCAL 5 241 jsr io.getc ; Third digit x 242 cmp #"R" 243 beq got_x_position 244 #ds.sta_LOCAL 6 245 jsr io.getc ; Read and ignore terminating 'R' 246 got_x_position: 247 ;; x position is in local variable(s) 4... 248 ;; y position is in local variable(s) 0... 249 ;; Convert them to ints 250 #ds.CALL io.str2byte, [0, 1, 2, 3], #ds.lda_LOCAL 251 #ds.lda_PARAM 0 252 pha 253 #ds.CALL io.str2byte, [4, 5, 6, 7], #ds.lda_LOCAL 254 #ds.lda_PARAM 0 255 pha 256 jsr ds.delete_stack_frame 257 plx 258 pla 259 clc 260 rts 261 .bend 262 263 .send rom 264 .endn