From 2b3f9946d9e6eaec4c2c2d741143d3339362e7aa Mon Sep 17 00:00:00 2001 From: Daniele Verducci su MatissePenguin Date: Mon, 22 Feb 2021 19:55:53 +0100 Subject: [PATCH] Working end of screen scrolling --- .../avr-assembly/character_generator.asm | 105 +++++++----------- .../avr-assembly/example_data/cat.asm | 1 - .../software/avr-assembly/main.asm | 41 +++---- 3 files changed, 59 insertions(+), 88 deletions(-) diff --git a/pat80-io-devices/composite-pal-adapter/software/avr-assembly/character_generator.asm b/pat80-io-devices/composite-pal-adapter/software/avr-assembly/character_generator.asm index dbde929..cc32b95 100644 --- a/pat80-io-devices/composite-pal-adapter/software/avr-assembly/character_generator.asm +++ b/pat80-io-devices/composite-pal-adapter/software/avr-assembly/character_generator.asm @@ -17,10 +17,6 @@ draw_char: ; But all the fonts are 1 byte large, so a glyph is 1*height bytes: ; glyph_pointer = FONT + (ascii_code * FONT_HEIGHT) - ; Save current chunk cursor position (Y) - mov r2, YL - mov r3, YH - ; Load first glyph position on Z ldi ZH, high(FONT<<1) ldi ZL, low(FONT<<1) @@ -31,6 +27,8 @@ draw_char: add ZL, r0 adc ZH, r1 ; Z contain our glyph's first byte position: draw it + ; Obtain drawing position in framebuffer memory (in Y) + call update_mem_pointer ; The drawing consist of FONT_HEIGHT cycles. Every glyph byte is placed on its own line ; on screen. To do this, we place it LINE_COLUMNS bytes after the previous one. ldi HIGH_ACCUM, FONT_HEIGHT @@ -49,22 +47,17 @@ draw_char: inc POS_COLUMN ; Check if end of line cpi POS_COLUMN, LINE_COLUMNS - 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 + brsh draw_char_eol ret draw_char_eol: ; end of line - adiw YH:YL,1 ; increment chunk cursor position by 1 (begin of next line on screen) clr POS_COLUMN ; reset column to 0 - ; check if reached end of screen - cpi POS_ROWP, SCREEN_HEIGHT-FONT_HEIGHT - breq draw_char_eos - ; if not end of screen, increment row + ; Move cursor to next line ldi HIGH_ACCUM, FONT_HEIGHT add POS_ROWP, HIGH_ACCUM + ; check if reached end of screen + cpi POS_ROWP, SCREEN_HEIGHT + brsh draw_char_eos ret draw_char_eos: ; end of screen: scroll screen but leave line pointer to last line @@ -76,60 +69,28 @@ cursor_pos_home: ; Set all positions to 0 clr POS_COLUMN clr POS_ROWP - ; Load framebuffer start position to Y - ldi YH, high(FRAMEBUFFER) - ldi YL, low(FRAMEBUFFER) ret -; Updates framebuffer pointer (Y) to point to current text cursor position (POS_COLUMN, POS_ROWP) -; Usage: -; ldi POS_COLUMN, 10 -; ldi POS_ROWP, 13 -; call set_framebuffer_pointer_to_text_cursor -; @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 ; NOTE: wrong, multiplicate with bytes per row -; ; 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: - ; Check if end of screen - cpi POS_ROWP, SCREEN_HEIGHT - brne draw_carriage_return_not_eos - call scroll_screen - dec POS_ROWP ; compensate for next inc - draw_carriage_return_not_eos: - ; Move cursor to line start - ldi POS_COLUMN, 0 - ; Move cursor to next line - ldi HIGH_ACCUM, FONT_HEIGHT - add POS_ROWP, HIGH_ACCUM - ; Compute memory pointer offset - mul POS_COLUMN, POS_ROWP ; result overwrites r0 and r1! - ; Set pointer to start of framebuffer - ldi ZL, low(FRAMEBUFFER) - ldi ZH, high(FRAMEBUFFER) - ; Add offset to pointer - add ZL, r0 - adc ZH, r1 - ret +; draw_carriage_return: +; ; Move cursor to line start +; ldi POS_COLUMN, 0 +; ; Move cursor to next line +; ldi HIGH_ACCUM, FONT_HEIGHT +; add POS_ROWP, HIGH_ACCUM +; ; Check if end of screen +; cpi POS_ROWP, SCREEN_HEIGHT +; brsh draw_carriage_return_eos +; ret +; draw_carriage_return_eos: +; call scroll_screen ; Scrolls the screen by one line (=LINE_COLUMNS*FONT_HEIGHT bytes) ; and clears the last line (FRAMEBUFFER_END - LINE_COLUMNS*FONT_HEIGHT bytes) ; @uses A, Z scroll_screen: - clr POS_COLUMN ; cursor to first column ; "Read" Pointer to first char of second line ldi YH, high(FRAMEBUFFER+(LINE_COLUMNS*FONT_HEIGHT)) ldi YL, low(FRAMEBUFFER+(LINE_COLUMNS*FONT_HEIGHT)) @@ -140,9 +101,9 @@ scroll_screen: scroll_screen_copy_loop: ld A, Y+ st Z+, A - cpi ZH, high(FRAMEBUFFER_END-(LINE_COLUMNS*FONT_HEIGHT)) + cpi YH, high(FRAMEBUFFER_END) brne scroll_screen_copy_loop - cpi ZL, low(FRAMEBUFFER_END-(LINE_COLUMNS*FONT_HEIGHT)) + cpi YL, low(FRAMEBUFFER_END) brne scroll_screen_copy_loop ; All the lines have been "shifted" up by one line. ; The first line is lost and the last is duplicate. Clear the last. @@ -153,8 +114,26 @@ scroll_screen: brne scroll_screen_clear_loop cpi r30, low(FRAMEBUFFER_END) brne scroll_screen_clear_loop - ; Last line cleared. Leave cursor pointer to last line start - ldi YH, high(FRAMEBUFFER_END-LINE_COLUMNS*FONT_HEIGHT) - ldi YL, low(FRAMEBUFFER_END-LINE_COLUMNS*FONT_HEIGHT) + ; Last line cleared. Set cursor position + clr POS_COLUMN ; cursor to first column + ldi POS_ROWP, SCREEN_HEIGHT-FONT_HEIGHT ret +; Sets the Y register to point to the cursor's first line memory position +; The cursor's position is represented by registers POS_COLUMN and POS_ROWP +update_mem_pointer: + ; Compute memory pointer offset: offset = (LINE_COLUMNS*POS_ROWP)+POS_COLUMN + ; LINE_COLUMNS*POS_ROWP + ldi HIGH_ACCUM, LINE_COLUMNS + mul HIGH_ACCUM, POS_ROWP ; result overwrites r0 and r1! + ; ...+POS_COLUMN + add r0, POS_COLUMN + clr HIGH_ACCUM + adc r0, HIGH_ACCUM + ; Set pointer to start of framebuffer + ldi YL, low(FRAMEBUFFER) + ldi YH, high(FRAMEBUFFER) + ; Add offset to pointer + add YL, r0 + adc YH, r1 + ret diff --git a/pat80-io-devices/composite-pal-adapter/software/avr-assembly/example_data/cat.asm b/pat80-io-devices/composite-pal-adapter/software/avr-assembly/example_data/cat.asm index 5d2bd7f..633af47 100644 --- a/pat80-io-devices/composite-pal-adapter/software/avr-assembly/example_data/cat.asm +++ b/pat80-io-devices/composite-pal-adapter/software/avr-assembly/example_data/cat.asm @@ -11,7 +11,6 @@ draw_cat: ; wait ser r19 cat_wait_loop_1: - ldi r20, 32 dec r19 brne cat_wait_loop_1 ; if reached the last framebuffer byte, exit cycle diff --git a/pat80-io-devices/composite-pal-adapter/software/avr-assembly/main.asm b/pat80-io-devices/composite-pal-adapter/software/avr-assembly/main.asm index 3eaf47d..754332c 100644 --- a/pat80-io-devices/composite-pal-adapter/software/avr-assembly/main.asm +++ b/pat80-io-devices/composite-pal-adapter/software/avr-assembly/main.asm @@ -79,17 +79,17 @@ main: ; clear ram ;*** Load data into ram *** - ; Set X to 0x0100 - ; ldi XH, high(FRAMEBUFFER) - ; ldi XL, low(FRAMEBUFFER) - ; load_mem_loop: - ; clr r17 - ; st X+, r17 - ; ; if reached the last framebuffer byte, exit cycle - ; cpi XH, 0b00111110 - ; brne load_mem_loop ; if not 0, repeat h_picture_loop - ; cpi XL, 0b11000000 - ; brne load_mem_loop ; if not 0, repeat h_picture_loop + Set X to 0x0100 + ldi XH, high(FRAMEBUFFER) + ldi XL, low(FRAMEBUFFER) + load_mem_loop: + clr r17 + st X+, r17 + ; if reached the last framebuffer byte, exit cycle + cpi XH, 0b00111110 + brne load_mem_loop ; if not 0, repeat h_picture_loop + cpi XL, 0b11000000 + brne load_mem_loop ; if not 0, repeat h_picture_loop @@ -122,34 +122,27 @@ main: ; draw example image - call draw_cat + ;call draw_cat ; test draw character routine - call draw_carriage_return - call draw_carriage_return - call draw_carriage_return - call cursor_pos_home - ldi r18, 0x41 dctest: + ldi r18, 0x41 draw_chars: mov HIGH_ACCUM, r18 call draw_char - inc r18 - cpi r18, 0x5B - brne dc_continue - ldi r18, 0x41 - call draw_carriage_return dc_continue: ; wait ser r19 dc_wait_loop_1: - ser r20 + ldi r24, 64 dc_wait_loop_2: - dec r20 + dec r24 brne dc_wait_loop_2 dec r19 brne dc_wait_loop_1 + inc r18 + cpi r18, 0x5B brne draw_chars jmp dctest