1; 2; ANSI Video handling for the Sharp PC G-800 family 3; 4; Stefano Bodrato - 2017 5; Original code by maruhiro, 2007 6; 7; set it up with: 8; .__console_w = max columns 9; .__console_h = max rows 10; 11; Display a char in location (__console_y),(__console_x) 12; A=char to display 13; 14; 15; $Id: f_ansi_char_850.asm $ 16; 17 18 19 SECTION code_clib 20 21 PUBLIC ansi_CHAR 22 23 EXTERN __console_w 24 EXTERN __console_h 25 26 EXTERN __console_y 27 EXTERN __console_x 28 29 EXTERN ansifont 30 31 EXTERN CONSOLE_COLUMNS 32 EXTERN CONSOLE_ROWS 33 34 35 PUBLIC init_screen 36 PUBLIC scroll_up 37 PUBLIC screenmode 38 39IF USE_ATTR 40 EXTERN g850_attr 41ENDIF 42 43 44 45defc SCREENMODE_VISIBLECURSOR_MASK=0x01 46defc SCREENMODE_VISIBLECURSOR_BIT=0 47 48 49 50 51.ansi_CHAR 52_print_char: 53 ld de,(__console_x) 54 ; D=x; E=Y 55 push ix ;save callers 56; push BC 57; push HL 58 push DE 59 call vram_addr 60 ld (HL), A 61 62IF USE_ATTR 63 ld de,attr-vram 64 add hl,de 65 ld a,(g850_attr) 66 ld (hl),a 67ENDIF 68 69 pop DE 70 call update_vcell 71; pop HL 72; pop BC 73 pop ix ;restore callers 74 ret 75 76 77 78; 79; Display status 80; 81; Input 82; B: Real screen column number 83; C: Output pattern 84; 85; Output 86; Destroys: AF, BC 87; 88putstat: 89 push BC 90putstat_loop: 91 in A, (0x40) 92 rlca 93 jr C, putstat_loop 94 95 xor A 96 out (0x40), A 97 ld A, 0x19 98 out (0x40), A 99 100 ld A, (0x790d) 101 add B 102 and 0x0f 103 or 0xb0 104 out (0x40), A 105 106 ld A, C 107 out (0x41), A 108 109 pop BC 110 ret 111 112; 113; Display a pattern 114; 115; Input 116; D: Line number of real screen 117; E: Column number of the virtual screen 118; 119; Output 120; Destroys: AF, BC, HL 121; 122 123putpat: 124 ld C, 0x40 125putpat_wait: 126 in A, (C) 127 rlca 128 jr C, putpat_wait 129 130 ; Set X coordinate (lower order) 131 132 ld A, E 133 rlca 134 rlca 135 ld B, A 136 and 0x0f 137 out (C), A 138 ; Set X coordinate (upper) 139 ld A, B 140 and 0xf0 141 rrca 142 rrca 143 rrca 144 rrca 145 or 0x10 146 out (C), A 147 148 ; Set Y coordinate 149 ld A, (0x790d) 150 add D 151 and 0x07 152 or 0xb0 153 out (C), A 154 155 ; Display a pattern 156 inc C 157 ld HL, pattern 158 outi 159 outi 160 outi 161 outi 162 163 ; Erase the pattern buffer 164 xor A 165 dec HL 166 ld (HL), A 167 dec HL 168 ld (HL), A 169 dec HL 170 ld (HL), A 171 dec HL 172 ld (HL), A 173 ret 174 175pattern: 176 defb 0, 0, 0, 0, 0, 0, 0, 0 177 178; 179; Cursor position? 180; 181; Input 182; DE: Position to examine 183; 184; Output 185; BC: Destroyed 186; Z: Cursor position NZ: Not at cursor position 187; 188is_cur: 189 ; Cursor position? 190 ld C, A 191 ld A, (cursor_x) 192 cp E 193 jr NZ, is_cur_last 194 ld A, (cursor_y) 195 cp D 196 jr NZ, is_cur_last 197 ; Is the cursor hidden? 198 ld A, (screenmode) 199 cpl 200 and SCREENMODE_VISIBLECURSOR_MASK 201 jr NZ, is_cur_last 202 ; Flashing cursor 203 in A, (0x14) 204 neg 205is_cur_last: 206 ld A, C 207 ret 208 209; 210; Get font offset 211; 212; Input 213; A: letter 214; 215; Output 216; AF: destroyed 217; BC: offset 218; 219 220font_offset: 221 ; Can it be displayed? 222 ld B, A 223 and 0x60 224 ld A, B 225 ld BC, 0x00a0 226 ret Z 227 ; ???? 228 sub 0x20 229 cp 0x60 230 jr C, font_offset_alphabet 231 sub 0x20 232 ; Is it possible to display? 233 cp 0xa0 234 ret NC 235font_offset_alphabet: 236 ld C, A 237 ret 238 239; 240; Setting attributes 241; 242; Input 243; C: attribute 244; H: inverted pattern 245; L: Underline pattern 246; IY: font address 247; 248; Output 249; AF: destroyed 250; C: Attribute pattern 251; IY: font address 252; 253setattr: 254IF USE_ATTR 255 xor A 256 ld (font_bold + 0), A 257 ld (font_bold + 1), A 258 259 ; Inversion? 260 srl C 261 jr NC, setattr_no_reverse 262 xor H 263setattr_no_reverse: 264 265 ; Is it underlined? 266 srl C 267 jr NC, setattr_no_underline 268 xor L 269setattr_no_underline: 270 271 ; Is it blinking? 272 srl C 273 jr NC, setattr_no_blink 274 ld C, A 275 in A, (0x14) 276 or A 277 ld A, C 278 jr Z, setattr_no_blink 279 ld IY, ansifont 280setattr_no_blink: 281 282 ; Is it bold? 283 srl C 284 ld C, A 285 jr NC, setattr_no_bold 286 ld A, (IY+1) 287 ld (font_bold + 0), A 288 ld A, (IY+2) 289 ld (font_bold + 1), A 290setattr_no_bold: 291ENDIF 292 293 ; Is it a cursor position? 294IF USE_ATTR 295ELSE 296 ld C, 0 297ENDIF 298 push BC 299 call is_cur 300 pop BC 301 ret NZ 302 ld A, C 303 xor H 304 ld C, A 305 ret 306 307IF USE_ATTR 308font_bold: 309 defb 0, 0 310ENDIF 311 312; 313; Shift A register 314; 315; Input 316; A: number shifted 317; B: Amount to shift 318; 319; Output 320; A: number shifted 321; F: destroyed 322; 323shift_a: 324 push BC 325 inc B 326 dec B 327 jr Z, shift_a_last 328 jp P, shift_a_left 329shift_a_right: 330 ; ???? 331 ld C, A 332 ld A, B 333 neg 334 ld B, A 335 ld A, C 336shift_a_right0: 337 srl A 338 djnz shift_a_right0 339 pop BC 340 ret 341shift_a_left: 342 ; ???? 343 sla A 344 djnz shift_a_left 345shift_a_last: 346 pop BC 347 ret 348 349; 350; Write to the pattern buffer (3 x 5 font) 351; 352; Input 353; A: letter 354; B: shift 355; C: attribute 356; DE: virtual screen coordinates 357; 358; Output 359; AF, HL, IY: Destroyed 360; 361setpat3x5: 362 push IY 363 364 ; Get font address 365 push BC 366 ld IY, ansifont 367 call font_offset 368 add IY, BC 369 add IY, BC 370 add IY, BC 371 pop BC 372 ld HL, 0x3f20 373 call setattr 374 375 ; Write 1st byte 376 ld HL, pattern 377 ld A, (IY+0) 378 xor C 379 call shift_a 380 or (HL) 381 ld (HL), A 382 383 ; Write the second byte 384 inc HL 385 ld A, (IY+1) 386 xor C 387 call shift_a 388 or (HL) 389 ld (HL), A 390 391 ; Write the third byte 392 inc HL 393 ld A, (IY+2) 394IF USE_ATTR 395 ld IY, font_bold 396 or (IY+0) 397ENDIF 398 xor C 399 call shift_a 400 or (HL) 401 ld (HL), A 402 403 ; Write 4th byte 404IF USE_ATTR 405 inc HL 406 ld A, (font_bold + 1) 407 or (IY+1) 408 xor C 409 call shift_a 410 or (HL) 411 ld (HL), A 412ENDIF 413 pop IY 414 ret 415 416 417 418; 419; The contents of the virtual VRAM are reflected in the real VRAM 420; 421; Input 422; D: actual screen Y coordinate 423; E: X coordinate of the virtual screen 424; 425; Output 426; AF, BC, DE, HL, IX, IY: Destroyed 427; 428update_cell: 429 ; font size? 430 ld A, (__console_h) 431 cp CONSOLE_ROWS 432 jp Z, update_cell_3x5 433 434; 435; 36 x 8 screen 436; 437update_cell_3x5_0: 438 ld A, (IX+0) 439IF USE_ATTR 440 ld C, (IY+0) 441ENDIF 442 ld B, 0 443 ld D, B 444 call setpat3x5 445 ld A, (IX+CONSOLE_COLUMNS*1) 446IF USE_ATTR 447 ld C, (IY+CONSOLE_COLUMNS*1) 448ENDIF 449 ld B, 6 450 inc D 451 call setpat3x5 452 dec D 453 jp putpat 454 455update_cell_3x5: 456 ld B, 0 457 ld C, E 458 ld IX, vram0 459IF USE_ATTR 460 ld IY, attr0 461ENDIF 462 add IX, BC 463IF USE_ATTR 464 add IY, BC 465ENDIF 466 ld BC, CONSOLE_COLUMNS 467 inc D 468 dec D 469 jr Z, update_cell_3x5_0 470 add IX, BC 471IF USE_ATTR 472 add IY, BC 473ENDIF 474 dec D 475 jr Z, update_cell_3x5_1 476 add IX, BC 477IF USE_ATTR 478 add IY, BC 479ENDIF 480 dec D 481 jr Z, update_cell_3x5_2 482 add IX, BC 483 add IX, BC 484IF USE_ATTR 485 add IY, BC 486 add IY, BC 487ENDIF 488 dec D 489 jr Z, update_cell_3x5_3 490 add IX, BC 491IF USE_ATTR 492 add IY, BC 493ENDIF 494 dec D 495 jr Z, update_cell_3x5_4 496 add IX, BC 497IF USE_ATTR 498 add IY, BC 499ENDIF 500 dec D 501 jr Z, update_cell_3x5_5 502 ret 503update_cell_3x5_1: 504 ld A, (IX+0) 505IF USE_ATTR 506 ld C, (IY+0) 507ENDIF 508 ld B, -2 509 ld D, 1 510 call setpat3x5 511 ld A, (IX+CONSOLE_COLUMNS*1) 512IF USE_ATTR 513 ld C, (IY+CONSOLE_COLUMNS*1) 514ENDIF 515 ld B, 4 516 inc D 517 call setpat3x5 518 dec D 519 jr update_cell_3x5_last 520update_cell_3x5_2: 521 ld A, (IX+0) 522IF USE_ATTR 523 ld C, (IY+0) 524ENDIF 525 ld B, -4 526 ld D, 2 527 call setpat3x5 528 ld A, (IX+CONSOLE_COLUMNS*1) 529IF USE_ATTR 530 ld C, (IY+CONSOLE_COLUMNS*1) 531ENDIF 532 ld B, 2 533 inc D 534 call setpat3x5 535 dec D 536 jr update_cell_3x5_last 537update_cell_3x5_3: 538 ld A, (IX+0) 539IF USE_ATTR 540 ld C, (IY+0) 541ENDIF 542 ld B, 0 543 ld D, 4 544 call setpat3x5 545 ld A, (IX+CONSOLE_COLUMNS*1) 546IF USE_ATTR 547 ld C, (IY+CONSOLE_COLUMNS*1) 548ENDIF 549 ld B, 6 550 inc D 551 call setpat3x5 552 ld D, 3 553 jr update_cell_3x5_last 554update_cell_3x5_4: 555 ld A, (IX+0) 556IF USE_ATTR 557 ld C, (IY+0) 558ENDIF 559 ld B, -2 560 ld D, 5 561 call setpat3x5 562 ld A, (IX+CONSOLE_COLUMNS*1) 563IF USE_ATTR 564 ld C, (IY+CONSOLE_COLUMNS*1) 565ENDIF 566 ld B, 4 567 inc D 568 call setpat3x5 569 ld D, 4 570 jr update_cell_3x5_last 571update_cell_3x5_5: 572 push BC 573 ld A, (IX+0) 574IF USE_ATTR 575 ld C, (IY+0) 576ENDIF 577 ld B, -4 578 ld D, 6 579 call setpat3x5 580 ld A, (IX+CONSOLE_COLUMNS*1) 581IF USE_ATTR 582 ld C, (IY+CONSOLE_COLUMNS*1) 583ENDIF 584 ld B, 2 585 inc D 586 call setpat3x5 587 ld D, 5 588update_cell_3x5_last: 589 jp putpat 590 591 592 593; 594; wait a bit 595; 596; Input 597; None 598; 599; Output 600; None 601; 602wait: 603 push BC 604 ld B, 100 605wait_loop: 606 djnz wait_loop 607 pop BC 608 ret 609 610; 611; Get the address of the virtual VRAM 612; 613; Input 614; A: y coordinate 615; 616; Output 617; DE: Virtual VRAM address 618; AF, IX: Destroyed 619; 620vram_addr_row: 621 add A 622 ld D, 0 623 ld E, A 624 ld IX, row_table 625 add IX, DE 626 ld D, (IX+1) 627 ld E, (IX+0) 628 ret 629 630row_table: 631 defw vram0 632 defw vram1 633 defw vram2 634 defw vram3 635 defw vram4 636 defw vram5 637 defw vram6 638 defw vram7 639 defw vram_last 640 641; 642; Get the address of the virtual VRAM 643; 644; Input 645; DE: virtual screen coordinates 646; 647; Output 648; F, BC, IX: Destroyed 649; HL: Virtual VRAM address 650; 651vram_addr: 652 push AF 653 push DE 654 ld H, 0 655 ld L, E 656 ld A, D 657 call vram_addr_row 658 add HL, DE 659 pop DE 660 pop AF 661 662 ; Is it within range? 663 or A 664 push HL 665 ld BC, vram_last 666 sbc HL, BC 667 pop HL 668 jp P, vram_addr_err 669 ret 670vram_addr_err: 671 ; Out of range 672 ld HL, vram_err 673 ret 674 675; 676; ?? 677; A:?? 678; 679; ?? 680; BC:VRAM???? 681; AF,IX:?? 682; 683vram_size: 684 add A 685 ld B, 0 686 ld C, A 687 ld IX, vram_size_table 688 add IX, BC 689 ld B, (IX+1) 690 ld C, (IX+0) 691 ret 692 693vram_size_table: 694 defw CONSOLE_COLUMNS * 0 695 defw CONSOLE_COLUMNS * 1 696 defw CONSOLE_COLUMNS * 2 697 defw CONSOLE_COLUMNS * 3 698 defw CONSOLE_COLUMNS * 4 699 defw CONSOLE_COLUMNS * 5 700 defw CONSOLE_COLUMNS * 6 701 defw CONSOLE_COLUMNS * 7 702 defw CONSOLE_COLUMNS * 8 703 704; 705; Initialize the screen 706; 707; Input 708; None 709; 710; Output 711; AF, BC, DE, HL: Destroyed 712; 713init_screen: 714 ; Initialize update position 715 ld HL, 0 716 ld (update_loc), HL 717 ; Initialize screen area 718 ld A, (__console_h) 719 dec A 720 ld L, A 721 ld (screen_region), HL 722 ; Initialize mode 723 ;ld A, SCREENMODE_VISIBLECURSOR_MASK 724 xor A 725 ld (screenmode), A 726 ld DE, 0 727 ld (cursor_location), DE 728 ; Erase the screen 729 ld BC, 0x0700 730init_screen_loop: 731 call putstat 732 djnz init_screen_loop 733 call putstat 734 call clear_screen 735 jp refresh_screen 736 737; 738; Erase the entire screen 739; 740; Input 741; None 742; 743; Output 744; AF, BC, HL: Destroyed 745; 746clear_screen: 747 ld HL, CONSOLE_ROWS - 1 748 749; 750; Delete the scroll area of the screen 751; 752; Input 753; H: upper line 754; L: lower line 755; 756; Output 757; AF, BC, HL: Destroyed 758; 759clear_region: 760 push DE 761 762 ; BC 763 ld A, L 764 inc A 765 sub H 766 call vram_size 767 ; DE 768 ld A, H 769 call vram_addr_row 770 call clear_region0 771 772 pop DE 773 ret 774 775; 776; Clear specified address / length range 777; 778; Input 779; BC: length 780; DE: Start address 781; 782; Output 783; AF, BC, DE, HL: Destroyed 784; 785clear_region0: 786 ; Return if length is 0 787 ld A, B 788 or C 789 ret Z 790 791 ; Is the length one? 792 dec BC 793 xor A 794 cp B 795 jr NZ, clear_region0_skip 796 cp C 797 jr NZ, clear_region0_skip 798 799 ; Delete one character 800 ex DE, HL 801 ld (HL), ' ' 802IF USE_ATTR 803 ; Delete one attribute 804 ;ld BC, (CONSOLE_COLUMNS * 8 + 8) 805 ld bc,attr-vram 806 add HL, BC 807 ld (HL), 0 808ENDIF 809 ret 810 811clear_region0_skip: 812 ; Erase characters 813 ld H, D 814 ld L, E 815 inc DE 816IF USE_ATTR 817 push BC 818 push DE 819 push HL 820ENDIF 821 ld (HL), ' ' 822 ldir 823 824IF USE_ATTR 825 ; Delete attribute 826 pop HL 827 pop DE 828 ;ld BC, (CONSOLE_COLUMNS * 8 + 8) 829 ld bc,attr-vram 830 add HL, BC 831 ex DE, HL 832 add HL, BC 833 ex DE, HL 834 pop BC 835 ld (HL), 0 836 ldir 837ENDIF 838 ret 839 840; 841; Execute ldir for virtual VRAM 842; 843; Input 844; BC: Counter 845; DE: Source address 846; HL: Forwarding address 847; 848; Output 849; BC: 0 850; DE: Before execution DE + BC 851; HL: Before execution HL + BC 852; 853ldir_screen: 854IF USE_ATTR 855 push BC 856 push DE 857 push HL 858 ldir 859 pop HL 860 pop DE 861 ;ld BC, (CONSOLE_COLUMNS * 8 + 8) 862 ld bc,attr-vram 863 add HL, BC 864 ex DE, HL 865 add HL, BC 866 ex DE, HL 867 pop BC 868 ldir 869 870 ;ld BC, -(CONSOLE_COLUMNS * 8 + 8) 871 ld bc,-(attr-vram) 872 add HL, BC 873 ex DE, HL 874 add HL, BC 875 ex DE, HL 876 ld BC, 0 877 ret 878ELSE 879 ldir 880 ret 881ENDIF 882 883 884 885; 886; Scroll up the virtual VRAM 887; 888; Input 889; None 890; 891; Output 892; AF, BC, HL: Destroyed 893; 894scroll_up: 895 ld HL, 7 896 ld C, 1 897 898; 899; Scroll up the virtual VRAM by specifying the range and number of times 900; 901; Input 902; C: number of lines to scroll 903; H: upper line 904; L: lower line 905; 906; Output 907; AF, BC, HL: Destroyed 908; 909scroll_up0: 910 ; (BC) 911 ld A, L 912 sub H 913 sub C 914 jp C, clear_region 915 push DE 916 push AF 917 918 ; DE 919 ld A, H 920 call vram_addr_row 921 922 ; HL 923 ld A, C 924 call vram_size 925 ld H, D 926 ld L, E 927 add HL, BC 928 929 ; BC 930 pop AF 931 push BC 932 inc A 933 call vram_size 934 935 ; Execute scroll up 936 call ldir_screen 937 pop BC 938 or A 939 sbc HL, BC 940 ex DE, HL 941 call clear_region0 942 943 pop DE 944 ;ret 945 jp refresh_screen 946 947 948 949; 950; Reflect the contents of the virtual VRAM in the real VRAM 951; 952; Input 953; DE: the coordinates of the virtual screen 954; 955; Output 956; AF, BC, DE, HL, IX, IY: Destruction 957; 958; 959update_vcell: 960 ld A, D 961 ld D, 0 962 or A 963 jp Z, update_cell_3x5 964 dec A 965 jr Z, putch1 966 inc D 967 dec A 968 jr Z, putch2 969 inc D 970 dec A 971 jp Z, update_cell_3x5 972 inc D 973 dec A 974 jp Z, update_cell_3x5 975 dec A 976 jr Z, putch5 977 inc D 978 dec A 979 jr Z, putch6 980 inc D 981 jp update_cell_3x5 982putch1: 983 push DE 984 call update_cell_3x5 985 pop DE 986 inc D 987 jp update_cell_3x5 988putch2: 989 push DE 990 call update_cell_3x5 991 pop DE 992 inc D 993 jp update_cell_3x5 994putch5: 995 push DE 996 call update_cell_3x5 997 pop DE 998 inc D 999 jp update_cell_3x5 1000putch6: 1001 push DE 1002 call update_cell_3x5 1003 pop DE 1004 inc D 1005 jp update_cell_3x5 1006 1007; 1008; Update the screen 1009; 1010; Input 1011; None 1012; 1013; Output 1014; AF, BC, HL: Destruction 1015; 1016refresh_screen0: 1017 ; Update (x, y) 1018 push DE 1019 ld HL, update_loc 1020 ld D, (HL) 1021 inc HL 1022 ld E, (HL) 1023 call update_cell 1024 pop DE 1025 1026 ; x := x - 1, Return if x >= 0 1027 ld HL, update_x 1028 dec (HL) 1029 ret P 1030 1031 ; x := WIDTH - 1 1032 ld A, (__console_w) 1033 dec A 1034 ld (HL), A 1035 1036 ; y := y - 1, Return if y >= 0 1037 ld HL, update_y 1038 dec (HL) 1039 ret P 1040 1041 ; y := HEIGHT - 1 1042 ld (HL), 5 1043 ret 1044update_loc: 1045update_y: 1046 defb 0 1047update_x: 1048 defb 0 1049 1050; 1051; Update the screen 1052; 1053; Input 1054; None 1055; 1056; Output 1057; AF, BC, HL: Destruction 1058; 1059refresh_screen: 1060 ld B, 144 1061refresh_screen_loop: 1062 push BC 1063 call refresh_screen0 1064 call refresh_screen0 1065 pop BC 1066 djnz refresh_screen_loop 1067 ret 1068 1069 1070 1071; DATA section required, so we get a pre-initialized, scrollable region 1072 1073 SECTION data_clib 1074 1075; Virtual VRAM 1076vram: 1077vram0: 1078 defb 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 1079vram1: 1080 defb 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 1081vram2: 1082 defb 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 1083vram3: 1084 defb 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 1085vram4: 1086 defb 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 1087vram5: 1088 defb 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 1089vram6: 1090 defb 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 1091vram7: 1092 defb 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 1093vram_last: 1094vram_err: 1095vram8: 1096 defb 0, 0, 0, 0, 0, 0, 0, 0 1097IF USE_ATTR 1098attr: 1099attr0: 1100 defb 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1101attr1: 1102 defb 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1103attr2: 1104 defb 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1105attr3: 1106 defb 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1107attr4: 1108 defb 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1109attr5: 1110 defb 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1111attr6: 1112 defb 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1113attr7: 1114 defb 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 1115attr_last: 1116attr8: 1117 defb 0, 0, 0, 0, 0, 0, 0, 0 1118ENDIF 1119 1120; 1121; Screen up and down 1122; 1123screen_region: 1124screen_bottom: 1125 defb CONSOLE_ROWS - 1 1126screen_top: 1127 defb 0 1128 1129 1130; 1131; Cursor position 1132; 1133cursor_location: 1134cursor_x: 1135 defb 0 1136cursor_y: 1137 defb 0 1138 1139; 1140; Mode 1141; 1142screenmode: 1143 defb 0 1144 1145 1146