From 65905fa7e77a6ea24cbd0fc7e64aa6c33628eb80 Mon Sep 17 00:00:00 2001 From: hugova Date: Mon, 12 May 2025 01:44:00 +0200 Subject: [PATCH] optimise pixel draw using lookup table --- wip-hugo/END.s | 53 ++++++++++++++++++ wip-hugo/routines/pixel/pixel.inc | 6 +- wip-hugo/routines/pixel/pixel_draw.s | 83 +++++++++++++--------------- wip-hugo/routines/pixel/pixel_test.s | 8 +++ wip-hugo/routines/text/char.inc | 8 ++- wip-hugo/source.s | 4 +- 6 files changed, 109 insertions(+), 53 deletions(-) create mode 100644 wip-hugo/routines/pixel/pixel_test.s diff --git a/wip-hugo/END.s b/wip-hugo/END.s index 8e89422..3525ff6 100644 --- a/wip-hugo/END.s +++ b/wip-hugo/END.s @@ -1,2 +1,55 @@ binary_factor: .byte %00000001, %00000010, %00000100, %00001000, %00010000, %00100000, %01000000, %10000000 + +;;This is used by pixel_draw! look at it for more detail +big_y_offset: + .lobytes $0000 + .hibytes $0000 + .lobytes $0140 + .hibytes $0140 + .lobytes $0280 + .hibytes $0280 + .lobytes $03C0 + .hibytes $03C0 + .lobytes $0500 + .hibytes $0500 + .lobytes $0640 + .hibytes $0640 + .lobytes $0780 + .hibytes $0780 + .lobytes $08C0 + .hibytes $08C0 + .lobytes $0A00 + .hibytes $0A00 + .lobytes $0B40 + .hibytes $0B40 + .lobytes $0C80 + .hibytes $0C80 + .lobytes $0DC0 + .hibytes $0DC0 + .lobytes $0F00 + .hibytes $0F00 + .lobytes $1040 + .hibytes $1040 + .lobytes $1180 + .hibytes $1180 + .lobytes $12C0 + .hibytes $12C0 + .lobytes $1400 + .hibytes $1400 + .lobytes $1540 + .hibytes $1540 + .lobytes $1680 + .hibytes $1680 + .lobytes $17C0 + .hibytes $17C0 + .lobytes $1900 + .hibytes $1900 + .lobytes $1A40 + .hibytes $1A40 + .lobytes $1B80 + .hibytes $1B80 + .lobytes $1CC0 + .hibytes $1CC0 + .lobytes $1E00 + .hibytes $1E00 diff --git a/wip-hugo/routines/pixel/pixel.inc b/wip-hugo/routines/pixel/pixel.inc index bd800df..9c5f8d3 100644 --- a/wip-hugo/routines/pixel/pixel.inc +++ b/wip-hugo/routines/pixel/pixel.inc @@ -1,9 +1,9 @@ ;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*- - ;; public args +;; Note that this file should never collide with line.inc + ;; public args Y_pos = ARGVEC + 0 X_pos = ARGVEC + 1 ;; Private args byte_to_paint = $E8 btp_mem_pos = $E9 ; 16-bit value (uses EA), byte to paint memory position - C = $EB ; 16-bit value (uses EC) - B = $ED ; 16-bit value (uses EE) + Bitmap = $4000 diff --git a/wip-hugo/routines/pixel/pixel_draw.s b/wip-hugo/routines/pixel/pixel_draw.s index 0735dd5..922e5ea 100755 --- a/wip-hugo/routines/pixel/pixel_draw.s +++ b/wip-hugo/routines/pixel/pixel_draw.s @@ -2,75 +2,66 @@ ;;Screen print. Draws a pixel at a specified position. .proc pixel_draw; user-procedure :clobbers (A X Y) :clobbers-arguments 0 -;; Draws a pixel at Y_pos, X_pos se mem.inc .include "pixel.inc" - Bitmap = $4000 - Bitmap_end = $5F3F + + ;; Lets clear some memory for later + LDA #$00 + STA btp_mem_pos + 1 + +calc_byte_to_paint: ;; X = X_pos (mod 8) - LDA X_pos ; X (mod 8) + LDA X_pos AND #%00000111 TAX - ;;this is the same as: A = 2^X - LDA binary_factor, X - + ;;this is the same as: byte_to_paint = 2^X + LDA binary_factor, X;; (see END.s) STA byte_to_paint - ;;FIND THE POSITION IN MEMORY TO WRITE PIXEL + ;;FIND position to write byte_to_paint (btp_mem_pos) ;; + + + + + > X ;; + ;; + ;;\/ ;; Y - ;; - ;;pos = x_offset - LDA #%11111000 - AND X_pos + ;; The screen has a wierd memory to pixel maping! + ;; Each line of 8 pixels is one byte + ;; 8 consecutive bytes in memory makes up a chunk and are 'under each other' on the screen + ;; the chunks are orderd from the left to the right and then looping downwards. + ;; Therefore we have that: btp_mem_pos = big_x_offset + smal_y_offset + big_y_offset + bitmap_offset + + ;; We use a lookup-table for big_y_offset (see END.s) + ;; (Y_pos / 8 floor)*2 + LDA Y_pos + LSR A + LSR A + ;; We need to remove the last digit if its still there + LSR A + ASL A + + TAX + LDA big_y_offset, X STA btp_mem_pos - - LDA #$00 + INX + LDA big_y_offset,X STA btp_mem_pos + 1 - ;;The y_pos adds offset because chunk offsets + inside chunk offset. - ;; Adding inside chunk offset + ;; btp_mem_pos = big_x_offset + LDA #%11111000 + AND X_pos + Add_16 btp_mem_pos, btp_mem_pos +1, A, #$00 + + ;; + smal_y_offset LDA #%00000111 ; A = y (mod 8) AND Y_pos ;; offset to add TAY - LDA #$00 - STA $4B - ;;y =8 translates to 320 bytes. - CLC - LDA #%11111000 ; A = y - [y (mod 8)] - AND Y_pos - STA C - STA B - LDA #$00 - STA C+1 - STA B+1 - - ;;We need to calculate C*40. 40 = 2*2*2*(2^2 +1) - ;; _*2^2 - Mult_16 C, C+1 - Mult_16 C, C+1 - - ;; + _*1 - Add_16 C, C+1, B, B+1, ! - - ;; *2*2*2 - Mult_16 C, C + 1 - Mult_16 C, C + 1 - Mult_16 C, C + 1 - - Add_16 btp_mem_pos, btp_mem_pos + 1, C, C + 1, ! - - ;;add offset for where bitmap is Add_16 btp_mem_pos, btp_mem_pos + 1, #Bitmap, ! ;;Let draw some stuff LDA byte_to_paint ;; note that both bytes are used! - ORA (>btp_mem_pos), Y - STA (>btp_mem_pos), Y + ORA (btp_mem_pos), Y + STA (btp_mem_pos), Y RTS .endproc diff --git a/wip-hugo/routines/pixel/pixel_test.s b/wip-hugo/routines/pixel/pixel_test.s new file mode 100644 index 0000000..2839703 --- /dev/null +++ b/wip-hugo/routines/pixel/pixel_test.s @@ -0,0 +1,8 @@ +.scope pixel_test + .include "pixel.inc" + LDA #$40 + STA X_pos + LDA #$40 + STA Y_pos + jsr pixel_draw +.endscope diff --git a/wip-hugo/routines/text/char.inc b/wip-hugo/routines/text/char.inc index 0d5c22f..ffaae58 100644 --- a/wip-hugo/routines/text/char.inc +++ b/wip-hugo/routines/text/char.inc @@ -3,8 +3,6 @@ Y_pos = ARGVEC + 1 code = ARGVEC + 2 - ;; private variables - screen_position = $EE ; 16-bit value (uses EF) ;; 16-bit value, we reuse bytes from X_pos X_pos_offset_hi = $ED X_pos_offset_lo = X_pos @@ -12,11 +10,15 @@ Y_pos_offset_hi = $EC Y_pos_offset_lo = Y_pos + ;; private variables + screen_position = $EE ; 16-bit value (uses EF) + temp_value = $EC ; 16-bit value (uses ED) + ;; What you will see bellow is .. interesting. I want to reuse ;; code and I need it for a 16-bit pointer. Because 6502 pointers expect the bytes to be besides each other ;; I need to use code +1 to store data even though its fot ARGVEK. ;; Thats why it's cursed - petski_position = code ; 16 bit value uses (code +1) + petski_position = code ; 16-bit value uses (code +1) ;; values VIC_bank = $4000 diff --git a/wip-hugo/source.s b/wip-hugo/source.s index 5a1ae03..961e672 100755 --- a/wip-hugo/source.s +++ b/wip-hugo/source.s @@ -7,8 +7,10 @@ ;;Code to run .include "STARTUP.s" ;.include "dubbel_buffer/raster_irqs.s" + ;.include "routines/line/line_test.s" -.include "routines/text/char_draw_test.s" +;.include "routines/text/char_draw_test.s" +.include "routines/pixel/pixel_test.s" ;.include "routines/memory/memcpy_test.s" ;.include "routines/triangle/triangle_test.s" exit: