;; This example shows how to draw chars to the screen in mode 2 ;; using the OS/firmware pixel data from the ROM. ;; ;; this example is for mode 2 ;; ;; This code can't be in the range &0000-&3fff because it ;; activates the lower rom in this range. scr_base equ &c000 scr_height equ 200 chars_width equ 8 chars_height equ 25 scr_set_mode equ &bc0e ;;-------------------------------------------------------------------------------------------- org &4000 ;;-------------------------------------------------------------------------------------------- start: ;; disable interrupts so firmware doesn't take control ;; also shows we don't use firmware for our functions di ;; set mode 2 ;; lower and upper rom disabled ld bc,&7f00+%10001110 out (c),c ;; initialise screen address table used for calculating position to draw chars call make_scr_table ;; set char coordinates ld h,10 ld l,10 call set_char_coords ld hl,message call print_msg ;; and loop forever end_loop: jp end_loop ;;-------------------------------------------------------------------------------------------- message: defb "This is a text drawing test using mode 2 and OS rom char data",0 ;;-------------------------------------------------------------------------------------------- print_msg: ld a,(hl) inc hl or a ret z call print_char jr print_msg ;;-------------------------------------------------------------------------------------------- ;; H = X char coord (0-79) ;; L = Y char coord (0-24) ;; origin is top-left 0,0 set_char_coords: ld a,h ld (x_coord),a ld a,l ld (y_coord),a scc2: ld a,l ;; X = byte/char coordinate ;; multiply Y by 8 to get line add a,a ;; x2 add a,a ;; x4 add a,a ;; x8 ld l,a ;; call calc_scr_addr ld (char_scr_addr),hl ret ;;-------------------------------------------------------------------------------------------- char_scr_addr: defw 0 x_coord: defb 0 y_coord: defb 0 ;;-------------------------------------------------------------------------------------------- ;; update x and y coordinate to move to right ;; if we get to end of the line, go to start of next line ;; if we go past last char, wrap back to start go_right: ld a,(x_coord) inc a ld (x_coord),a cp chars_width ret nz xor a ld (x_coord),a ld a,(y_coord) inc a ld (y_coord),a cp chars_height ret nz xor a ld (y_coord),a ret ;;-------------------------------------------------------------------------------------------- ;; update char coords and recalc screen address go_char_right: call go_right ld a,(x_coord) ld h,a ld a,(y_coord) ld l,a call scc2 ret ;;-------------------------------------------------------------------------------------------- ;; IN: ;; h = x byte coord ;; l = y line coord ;; OUT: ;; HL = screen coordinate calc_scr_addr: push bc push de ld c,h ld h,0 add hl,hl ld de,scr_table add hl,de ld a,(hl) inc hl ld h,(hl) ld l,a ld b,0 add hl,bc pop de pop bc ret ;;-------------------------------------------------------------------------------------------- scr_table: defs 400 ;;-------------------------------------------------------------------------------------------- make_scr_table: ld ix,scr_table ld hl,scr_base ;; screen base ld b,scr_height ;; height in lines .st1 ld (ix+0),l ld (ix+1),h inc ix inc ix call scr_next_line djnz st1 ret ;;-------------------------------------------------------------------------------------------- scr_next_line: ld a,h add a,8 ld h,a ld a,h and &38 ret nz ld a,l add a,&50 ld l,a ld a,h adc a,&c0 ld h,a ret ;;-------------------------------------------------------------------------------------------- ;; A = char to display print_char: push hl push de push bc ;; page in lower rom ;; bit 1,0: mode (mode 2) ;; bit 2: lower rom enable ;; bit 3: upper rom disable ;; ;; get addr for char pixel data ;; ;; each char is 8 bytes. One byte per line. ;; each bit is a single pixel and we can ;; plot this directly to the screen for mode 2. ;; ;; The OS converts the pixel data at runtime for mode 1 and mode 0. ;; ;; The OS stores char 0 to char 255. ;; ;; a = char ld l,a ld h,0 add hl,hl ;; x2 add hl,hl ;; x4 add hl,hl ;; x8 ld de,&3800 ;; address of font in OS rom ;; char 0 add hl,de ex de,hl ;; DE = char pixel data ld hl,(char_scr_addr) ;; HL = screen address ;; lower rom readable between &0000-&3fff ld bc,&7f00+%10001010 out (c),c ;; print entire char ld b,8 print_char_line: ;; do one line ld a,(de) ld (hl),a ;; update pixel pointer inc de ;; update screen pointer call scr_next_line djnz print_char_line ;; disable lower rom ;; mode 2, upper rom disabled ld bc,&7f00+%10001110 out (c),c ;; now update coords for next char call go_char_right pop bc pop de pop hl ret ;;-------------------------------------------------------------------------------------------- ;;end start