First working text mode without end of screen scroll

This commit is contained in:
Daniele Verducci su MatissePenguin 2021-01-26 23:22:55 +01:00
parent 9d6e6efd13
commit 467197fd23
2 changed files with 103 additions and 12 deletions

View File

@ -27,7 +27,7 @@ draw_char:
; Obtain offset multiplying ascii_code * number_of_bytes_per_font
ldi r17, FONT_HEIGHT
mul HIGH_ACCUM, r17 ; result overwrites r0 and r1!
; 16-bit addition between gliph's first byte position and offset (and store result in Z)
; 16-bit addition between gliph's first byte position and offset (and store result in Z) to obtain our glyph position
add ZL, r0
adc ZH, r1
; Z contain our glyph's first byte position: draw it
@ -44,19 +44,66 @@ draw_char:
; Decrement loop counter and exit if reached 0
dec HIGH_ACCUM
brne draw_char_loop
; Char drawing is complete. Set chunk cursor position to next char first line
; Char drawing is complete. Increment cursor position
inc POS_COLUMN
; Check if end of line
cpi POS_COLUMN, 52
breq draw_char_eol
; Reset chunk position to first glyph line of next column
mov YL, r2 ; first restore Y
mov YH, r3
adiw YH:YL,1 ; just increment pre-char-drawing-saved chunk cursor position by 1
ret
draw_char_eol:
clr POS_COLUMN ; reset column to 0
adiw YH:YL,1 ; increment chunk cursor position by 1 (begin of next line on screen)
; Check if end of screen
cpi YH, high(FRAMEBUFFER_END + 1)
brne draw_char_end
cpi YL, low(FRAMEBUFFER_END + 1)
brne draw_char_end
; End of screen reached! Scroll framebuffer by 1 line (=52*FONT_HEIGHT bytes)
; TODO
draw_char_end:
ret
; Sets the cursor to 0,0 and clears fine position
cursor_pos_home:
; Set Y to framebuffer start
;ldi YH, high(FRAMEBUFFER)
;ldi YL, low(FRAMEBUFFER)
ldi YH, high(0x0068)
ldi YL, low(0x0068)
; Set all positions to 0
clr POS_COLUMN
clr POS_ROWP
clr POS_FINE
; Load framebuffer start position to Y
ldi YH, high(FRAMEBUFFER)
ldi YL, low(FRAMEBUFFER)
; ldi YH, high(0x1000)
; ldi YL, low(0x1000)
ret
; Updates framebuffer pointer (Y) to point to current text cursor position (POS_COLUMN, POS_ROWP)
; Usage:
; ldi POS_COLUMN, 55
; ldi POS_ROWP, 13
; call set_framebuffer_pointer_to_text_cursor ; (sets cursor to 4th character of second row in 13th row-pair = column 4, row 27 on screen)
; @modifies Y, R0, R1
set_framebuffer_pointer_to_text_cursor:
; Load framebuffer start position to Y
ldi YH, high(FRAMEBUFFER)
ldi YL, low(FRAMEBUFFER)
; Obtain offset between 0,0 and current cursor position
mul POS_COLUMN, POS_ROWP ; result is in r1,r0
; Sum offset to Y
add YL, r0
adc YH, r1
ret
; Draws a newline
; Moves cursor to start of following screen line
; Takes care of particular cases, i.e. end of screen (shifts all screen up by one line)
draw_carriage_return:
ret

View File

@ -29,9 +29,12 @@
; *** reserved registers ***
; Cursor Position
.def POS_COLUMN = r21 ; absolute coarse position on line (0 to 51)
.def POS_ROW = r20 ; absolute coarse position on line (0 to 51)
.def POS_FINE = r24 ; fine position (bit inside coarse-position-pointed byte)
; POS_COLUMN (0-103) represents the column on a pair of rows: 0 to 51 is the first row, 52 to 103 the second one
; POS_ROWP (0-152) represent the pair of rows. POS_ROWP = 5 means the 10th and 11th rows
; POS_FINE represents fine position (bit inside coarse-position-pointed chunk) in graphic mode.
.def POS_COLUMN = r21
.def POS_ROWP = r20
.def POS_FINE = r24
; Internal registers
.def A = r0 ; accumulator
.def STATUS = r25 ; signal status (see STATUS TABLE)
@ -52,6 +55,7 @@
; memory
.equ FRAMEBUFFER = 0x0100
.equ FRAMEBUFFER_END = 0x3EC0
; start vector
.org 0x0000
@ -88,14 +92,54 @@ main:
; test draw character routine
call cursor_pos_home
ldi r18, 0x30
ldi r18, 0x21
draw_chars:
mov HIGH_ACCUM, r18
call draw_char
inc r18
cpi r18, 0x64
cpi r18, 0x7E
brne draw_chars
ldi r18, 0x21
draw_chars2:
mov HIGH_ACCUM, r18
call draw_char
inc r18
cpi r18, 0x7E
brne draw_chars2
ldi r18, 0x21
draw_chars3:
mov HIGH_ACCUM, r18
call draw_char
inc r18
cpi r18, 0x7E
brne draw_chars3
ldi r18, 0x21
draw_chars4:
mov HIGH_ACCUM, r18
call draw_char
inc r18
cpi r18, 0x7E
brne draw_chars4
ldi r18, 0x21
draw_chars5:
mov HIGH_ACCUM, r18
call draw_char
inc r18
cpi r18, 0x7E
brne draw_chars5
ldi r18, 0x21
draw_chars6:
mov HIGH_ACCUM, r18
call draw_char
inc r18
cpi r18, 0x7E
brne draw_chars6
; *** timer setup (use 16-bit counter TC1) ***