optimise pixel draw using lookup table

This commit is contained in:
hugova 2025-05-12 01:44:00 +02:00
parent 2bab2a6c8a
commit 65905fa7e7
6 changed files with 109 additions and 53 deletions

View file

@ -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

View file

@ -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

View file

@ -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, #>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

View file

@ -0,0 +1,8 @@
.scope pixel_test
.include "pixel.inc"
LDA #$40
STA X_pos
LDA #$40
STA Y_pos
jsr pixel_draw
.endscope

View file

@ -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

View file

@ -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: