1; Generic console driver - VT52 + ZX Codes 2; 3; Supported VT52 codes: 4; 5; * = With VT52x 6; 7; [ESC] A - Move the cursor to beginning of line above. 8; [ESC] B - Move the cursor to beginning of line below. 9; [ESC] C - Move the cursor right by one. 10; [ESC] D - Move the cursor left by one 11; [ESC] E - Clear the screen and place the cursor in the upper left corner. 12; [ESC] H - Move the cursor to the upper left corner. 13; // ![ESC] I - Move the cursor to beginning of line above. 14; *[ESC] J - Erase all lines after our current line 15; *[ESC] K - Clear the current line from the current cursor position. 16; [ESC] Y - row col 'Goto' Coordinate mode - first will change line number, then cursor position (both ASCII - 32) 17; [ESC] b - Byte after 'b' sets new foreground color (ASCII - 32) 18; [ESC] c - Byte after 'c' sets new background color (ASCII -32) 19; [ESC] p - start inverse video 20; [ESC] q - stop inverse video 21; *[ESC] 0 - start underlined 22; *[ESC] 1 - stop underlined 23; *[ESC] 2 - start bold 24; *[ESC] 3 - stop bold 25; [ESC] s - Enable/disable vertical scrolling 26; [ESC] r [char] - Print character (raw) 27; 8 - move cursor left 28; 10 - linefeed 29; 12 = cls 30; 31; Supported ZX Codes: 32; 33; 4,[0|1] = enable/disable vertical scroll 34; 8 = backspace 35; 9 = right 36; 10 = line feed 37; 11 = up 38; 13 = down 39; 16, 32 +n = set ink 40; 17, 32 +n = set paper 41; 22,y+32,x+32 = Move to position 42 43 44 ; Variables that can be adjusted by platform specific code 45 PUBLIC generic_console_flags 46 47 EXTERN generic_console_scrollup 48 EXTERN generic_console_printc 49 EXTERN generic_console_cls 50 EXTERN generic_console_set_ink 51 EXTERN generic_console_set_paper 52 EXTERN generic_console_set_attribute 53 EXTERN generic_console_set_attribute 54 EXTERN __console_x 55 EXTERN __console_y 56 EXTERN __console_w 57 EXTERN __console_h 58 59 60 61; extern int __LIB__ fputc_cons(char c); 62 ld hl,2 63 add hl,sp 64 ld d,(hl) 65IF __CPU_INTEL__ 66 ld hl,(__console_x) 67 ld c,l 68 ld b,h 69ELIF __CPU_GBZ80__ 70 ld hl,__console_x 71 ld c,(hl) 72 inc hl 73 ld b,(hl) 74ELSE 75 ld bc,(__console_x) ;coordinates 76ENDIF 77 ld hl,params_left 78 ld a,(hl) 79 and a 80 jr nz,handle_parameter 81 82 ; Check for raw flag here 83 ld a,(generic_console_flags) 84 ld e,1 85 rrca 86; jr nz,handle_character 87 88 dec e ;-> e = 0 (look at zxcodes) 89 call check_parameters ;Leaves e untouched 90 ret c ;Return if we processed the escape/it was a valid escape 91handle_character: 92 ld hl,generic_console_flags 93 ; At this point: 94 ;hl = generic_console_flags 95 ; c = x position 96 ; b = y position 97 ; d = character to print 98 ; e = raw character mode 99 ld a,(__console_h) 100 dec a 101 cp b 102 jr nc,handle_character_no_scroll 103 sub b 104 neg 105 ld b,a 106scroll_loop: 107IF __CPU_INTEL__ 108 ld a,(hl) 109 rlca 110 rlca 111 call nc,generic_console_scrollup 112ELSE 113 bit 6,(hl) 114 call z,generic_console_scrollup 115ENDIF 116 djnz scroll_loop 117 ld a,(__console_h) 118 dec a 119 ld b,a 120 ld c,0 121IF __CPU_GBZ80__ | __CPU_INTEL__ 122 ld (__console_x+1),a ;a holds vlaue of b 123 ld a,c 124 ld (__console_x),a 125ELSE 126 ld (__console_x),bc 127ENDIF 128handle_character_no_scroll: 129 ld a,d 130 push bc ;save coordinates 131 call generic_console_printc 132 pop bc 133 inc c 134 ld a,(__console_w) 135 cp c 136 jr nz,store_coords 137 ld c,0 138 inc b 139 jr store_coords 140 141 142; Entry: hl = flags 143; d = character 144IF SUPPORT_vt52 145set_escape: 146 ; We need to look at the escape table now 147 ld e,1 ;Consider ANSI side 148 call check_parameters 149 ret c ; Processed 150 ; Just print it in raw mode then 151print_raw: 152 ld e,1 153 jr handle_character 154ENDIF 155 156handle_parameter: 157 dec (hl) 158 jr z,parameter_dispatch 159 inc hl ;Now points to parameters 160 ld (hl),d 161 ret 162parameter_dispatch: 163IF __CPU_GBZ80__ 164 ld hl,parameter_processor 165 ld a,(hl+) 166 ld h,(hl) 167 ld l,a 168ELSE 169 ld hl,(parameter_processor) 170ENDIF 171 ld a,d ;Get parameter into a 172do_dispatch: 173 push hl 174 ld hl,generic_console_flags 175 ret 176 177check_parameters: 178 ld hl,parameter_table 179parameter_loop: 180 ld a,(hl) 181 inc hl 182IF SUPPORT_vt52 183 IF __CPU_INTEL__ 184 push de 185 ld d,a 186 ld a,e 187 rrca 188 jp nc,not_ansi 189 ld d,(hl) 190not_ansi: 191 ld a,d 192 pop de 193 ELSE 194 bit 0,e 195 jr z,not_ansi 196 ld a,(hl) 197not_ansi: 198 ENDIF 199ENDIF 200 inc hl ;points to parameter count now 201 and a ;nc 202 ret z 203 cp 255 204 jr z,try_again 205 cp d 206 jr nz, try_again 207 ; We matched a command 208 ld a,(hl) 209 ld (params_left),a 210 ld e,a 211 inc hl 212 ld a,(hl) 213 inc hl 214 ld h,(hl) 215 ld l,a 216IF __CPU_GBZ80__ 217 ld (parameter_processor),a 218 ld a,h 219 ld (parameter_processor+1),a 220ELSE 221 ld (parameter_processor),hl 222ENDIF 223 ld a,e 224 and a ;Immediate action? 225 ld a,d ;The character 226 ccf 227 jr z,do_dispatch 228 ret 229try_again: 230 inc hl 231 inc hl 232 inc hl 233 jr parameter_loop 234 235 236 237; hl = flags 238; bc = coordinates 239; d = x 240; (parameter) = y 241set_xypos: 242IF __CPU_GBZ80__ 243 ld hl,__console_w 244 ld a,(hl+) 245 ld h,(hl) 246 ld l,a 247ELSE 248 ld hl,(__console_w) ;l = width, h = height 249ENDIF 250 ld a,d 251 sub 32 252 ld c,a 253 ld a,l 254 dec a 255 cp c 256 ret c ;out of range 257 ld a,(parameters) 258 sub 32 259 ld b,a 260 ld a,h 261 dec a 262 cp b 263 ret c ;out of range 264 jr store_coords 265 266; Move print position left 267left: ld a,c 268 and a 269 jr nz,left_1 270 ld a,(__console_w) 271 dec a 272 ld c,a 273 jr up 274left_1: dec c 275store_coords: 276IF __CPU_GBZ80__ | __CPU_INTEL__ 277 ld a,c 278 ld (__console_x),a 279 ld a,b 280 ld (__console_x+1),a 281ELSE 282 ld (__console_x),bc 283ENDIF 284 scf 285 ret 286 287; Move print position up 288up: ld a,b 289 and a 290 jr z,store_coords 291 dec b 292 jr store_coords 293 294down: ld a,(__console_h) 295 dec a 296 cp b 297 ret z 298 inc b 299 jr store_coords 300 301right: ld a,(__console_w) 302 dec a 303 cp c 304 ret z 305 inc c 306 jr store_coords 307 308set_vscroll: 309IF __CPU_INTEL__ 310 ld e,a 311 ld a,(hl) 312 and @10111111 313 ld (hl),a 314 ld a,e 315 rrca 316 ret c 317 ld a,(hl) 318 or @01000000 319 ld (hl),a 320 scf 321 ret 322ELSE 323 res 6,(hl) 324 rrca 325 ret c 326 set 6,(hl) 327ENDIF 328 scf 329 ret 330 331set_ink: 332 call generic_console_set_ink 333 scf 334 ret 335 336set_paper: 337 call generic_console_set_paper 338 scf 339 ret 340 341 342cls: call generic_console_cls 343move_home: 344 ld bc,0 345 jr store_coords 346 347IF SUPPORT_vt52 348set_inverse_ansi: 349 dec a ;p = 70 = on, q = 71 = off 350ENDIF 351set_inverse: ;Entry hl = flags 352IF __CPU_INTEL__ 353 ld e,@01111111 354 ld d,@10000000 355 rra 356 jr c,set_inverse_doit 357 ld d,@00000000 358set_inverse_doit: 359 ld a,(hl) 360 and e 361 or d 362 ld (hl),a 363ELSE 364 rl (hl) ;drop bit 7 365 rra 366 rr (hl) ;get it back again 367ENDIF 368set_inverse_call_generic: 369 call generic_console_set_attribute 370 scf 371 ret 372 373 374IF SUPPORT_vt52x 375; bc = coordinates 376clear_eol: 377 ld a,b 378clear_eol_loop: 379 push af ;save row 380 ld e,0 ;not raw 381 ld a,' ' 382 call handle_character ;exits with bc=coordinates 383 pop af 384 cp b 385 jr nz,clear_eol_loop 386 scf 387 ret 388 389; bc = coordinates 390clear_eos: 391 call clear_eol ;exit, bc = coordinates 392 ld a,(__console_h) 393 sub b 394clear_eos_loop: 395 push af 396 call clear_eol 397 pop af 398 dec a 399 jr nz,clear_eos_loop 400 scf 401 ret 402ENDIF 403 404 405handle_cr: 406 ld a,(__console_h) 407 sub b 408 jr nc,handle_cr_no_need_to_scroll 409 dec a 410 jr nz,handle_cr_no_need_to_scroll 411 ; Check if scroll is enabled 412IF __CPU_INTEL__ 413 ld a,(hl) 414 rlca 415 rlca 416 call nc,generic_console_scrollup 417ELSE 418 bit 6,(hl) 419 call z,generic_console_scrollup 420ENDIF 421 422 ld a,(__console_h) 423 sub 2 424 ld b,a 425handle_cr_no_need_to_scroll: 426 inc b 427 ld c,0 428 jp store_coords 429 430 431 432IF SUPPORT_vt52x 433set_underlined_ansi: 434 ;'0' = 48 = on, '1' = 49 = off 435 dec a 436 and @00001000 437 ld c,a 438 ld a,(hl) 439 and @11110111 440 or c 441 ld (hl),a 442call_set_attribute: 443 call generic_console_set_attribute 444 scf 445 ret 446 447set_bold_ansi: 448 ;'2' = 50 = on, '3' = 51 = off 449 sub 3 ;So 47, 48 450 and @00001000 451 rlca 452 ld c,a 453 ld a,(hl) 454 and @11101111 455 or c 456 ld (hl),a 457 jr call_set_attribute 458ENDIF 459 460 461 462 463 SECTION rodata_clib 464 465; defb ZXCode, ANSICode 466; defb parameter_count 467; defw process_routine 468; 469; If code is 255 then not valid for this mode, so skip 470parameter_table: 471IF SUPPORT_vt52 472 defb 27,255 ;ESC 473 defb 1 ;We expect one parameter 474 defw set_escape 475ENDIF 476 defb 8, 8 477 defb 0 478 defw left 479 defb 10, 10 480 defb 0 481 defw handle_cr 482 defb 12, 12 483 defb 0 484 defw cls 485 486 defb 9, 'D' 487 defb 0 488 defw right 489 defb 11, 'A' 490 defb 0 491 defw up 492 defb 13, 'B' 493 defb 0 494 defw down 495IF SUPPORT_vt52 496 defb 255, 'D' 497 defb 0 498 defw left 499ENDIF 500 defb 22, 'Y' 501 defb 2 502 defw set_xypos 503IF SUPPORT_vt52 504 defb 255, 'E' 505 defb 0 506 defw cls 507 defb 255, 'H' 508 defb 0 509 defw move_home 510ENDIF 511 defb 4 , 's' 512 defb 1 513 defw set_vscroll 514 defb 16, 'b' 515 defb 1 516 defw set_ink 517 defb 17, 'c' 518 defb 1 519 defw set_paper 520IF SUPPORT_zxcodes 521 defb 20, 255 522 defb 1 523 defw set_inverse 524ENDIF 525IF SUPPORT_vt52 526 defb 255, 'p' 527 defb 0 528 defw set_inverse_ansi 529 defb 255, 'q' 530 defb 0 531 defw set_inverse_ansi 532ENDIF 533IF SUPPORT_vt52x 534 defb 255, '0' 535 defb 0 536 defw set_underlined_ansi 537 defb 255, '1' 538 defb 0 539 defw set_underlined_ansi 540 defb 255, '2' 541 defb 0 542 defw set_bold_ansi 543 defb 255, '3' 544 defb 0 545 defw set_bold_ansi 546 defb 255, 'K' 547 defb 0 548 defw clear_eol 549 defb 255,'J' 550 defb 0 551 defw clear_eos 552ENDIF 553IF SUPPORT_vt52 554 defb 255, 'r' 555 defb 1 556 defw print_raw 557ENDIF 558 defb 0 ;endmarker 559 560 SECTION bss_clib 561 562params_left: defb 0 ; Number of parameters left to read 563parameters: defb 0 ; We only have up-to two parameters 564parameter_processor: defw 0 ; Where we go to when we need to process 565 566generic_console_flags: defb 0 ; bit 0 = raw mode enabled 567 ; bit 3 = underline 568 ; bit 4 = bold 569 ; bit 6 = vscroll disabled 570 ; bit 7 = inverse on 571 572