Skip to content

Commit

Permalink
Improve allocation of VRAM/PAL/OAM buffers (#222)
Browse files Browse the repository at this point in the history
* Improve allocation of VRAM/PAL/OAM buffers

Fixes #215:
  - Use weak symbols
  - Move PAL_BUF out of hardware stack
  - Split multi_vram* ops from the definition of the buffer

* Fix weakness of VRAM_BUF
  • Loading branch information
cogwheel authored Sep 30, 2023
1 parent 26b23c9 commit e44cf72
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 118 deletions.
1 change: 1 addition & 0 deletions mos-platform/nes/nesdoug/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ add_platform_library(nes-nesdoug
padlib.s
vram_buffer.c
vram_buffer.s
vram_buffer_ops.s
zaplib.s
)
target_include_directories(nes-nesdoug BEFORE PUBLIC ..)
Expand Down
7 changes: 4 additions & 3 deletions mos-platform/nes/nesdoug/vram_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

__attribute__((section(".zp.vram_index"))) char VRAM_INDEX;

extern char VRAM_BUF[];
extern char VRAM_BUF[128];

__attribute__((leaf)) void __post_vram_update();

void set_vram_update(const void *buf);
void set_vram_buffer(void) {
VRAM_BUF[0] = 0xff;
VRAM_INDEX = 0;
set_vram_update(VRAM_BUF);
__post_vram_update();
}
103 changes: 2 additions & 101 deletions mos-platform/nes/nesdoug/vram_buffer.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
.zeropage VRAM_INDEX

.section .noinit.vram_buf,"aw",@nobits
.globl VRAM_BUF
.weak VRAM_BUF
.balign 128
VRAM_BUF:
.zero 128
.zero 128

.text
.global __post_vram_update
Expand All @@ -17,102 +17,3 @@ __post_vram_update:
inx ;x=0
stx VRAM_INDEX
rts

;void multi_vram_buffer_horz(char * data, char len, int ppu_address);
.section .text.multi_vram_buffer_horz,"ax",@progbits
.globl multi_vram_buffer_horz
multi_vram_buffer_horz:
; A - len
; X - <ppu_address
; __rc2 - <data
; __rc3 - >data
; __rc4 - >ppu_address
ldy VRAM_INDEX

sta __rc5 ; save len for loop comparison
sta VRAM_BUF+2, y ; store len in header

lda #$40 ; load horizontal flag

multi_vram_buffer_common:
ora __rc4 ; combine direction flag with upper address byte
sta VRAM_BUF+0, y ; store upper byte in header
txa
sta VRAM_BUF+1, y ; store lower byte in header

; get data index past header
tya
clc
adc #3
tax ;need y for source, x is for dest and for vram_index

ldy #0

; TODO: unroll?
.Lmulti_vram_buffer_common_loop:
lda (__rc2), y
sta VRAM_BUF, x
inx
iny
cpy __rc5
bne .Lmulti_vram_buffer_common_loop
lda #$ff ;=NT_UPD_EOF
sta VRAM_BUF, x
stx VRAM_INDEX
rts




;void multi_vram_buffer_vert(char * data, char len, int ppu_address);
.section .text.multi_vram_buffer_vert,"ax",@progbits
.globl multi_vram_buffer_vert
multi_vram_buffer_vert:
; A - len
; X - <ppu_address
; __rc2 - <data
; __rc3 - >data
; __rc4 - >ppu_address
ldy VRAM_INDEX

sta __rc5 ; save len for loop comparison
sta VRAM_BUF+2, y ; store len in header

lda #$80 ; load vertical flag
bne multi_vram_buffer_common ; always taken




;void one_vram_buffer(char data, int ppu_address);
.section .text.one_vram_buffer,"ax",@progbits
.globl one_vram_buffer
one_vram_buffer:
; A - data
; X - <ppu_address
; __rc2 - >ppu_address
ldy VRAM_INDEX

sta VRAM_BUF+2, y ; data
lda __rc2
sta VRAM_BUF, y ; address hi
txa
sta VRAM_BUF+1, y ; adderess lo
iny
iny
iny
lda #$ff ;=NT_UPD_EOF
sta VRAM_BUF, y
sty VRAM_INDEX
rts




;void clear_vram_buffer(void);
;_clear_vram_buffer:
; lda #0
; sta VRAM_INDEX
; lda #$ff
; sta VRAM_BUF
; rts
103 changes: 103 additions & 0 deletions mos-platform/nes/nesdoug/vram_buffer_ops.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
;written by Doug Fraker
;version 1.2, 1/1/2022

.zeropage VRAM_INDEX

; Horizontal and vertical share common code and need to stay in the same section
.section .text.multi_vram_buffer,"ax",@progbits

;void multi_vram_buffer_horz(char * data, char len, int ppu_address);
.globl multi_vram_buffer_horz
multi_vram_buffer_horz:
; A - len
; X - <ppu_address
; __rc2 - <data
; __rc3 - >data
; __rc4 - >ppu_address
ldy VRAM_INDEX

sta __rc5 ; save len for loop comparison
sta VRAM_BUF+2, y ; store len in header

lda #$40 ; load horizontal flag

multi_vram_buffer_common:
ora __rc4 ; combine direction flag with upper address byte
sta VRAM_BUF+0, y ; store upper byte in header
txa
sta VRAM_BUF+1, y ; store lower byte in header

; get data index past header
tya
clc
adc #3
tax ;need y for source, x is for dest and for vram_index

ldy #0

; TODO: unroll?
.Lmulti_vram_buffer_common_loop:
lda (__rc2), y
sta VRAM_BUF, x
inx
iny
cpy __rc5
bne .Lmulti_vram_buffer_common_loop
lda #$ff ;=NT_UPD_EOF
sta VRAM_BUF, x
stx VRAM_INDEX
rts



;void multi_vram_buffer_vert(char * data, char len, int ppu_address);
.globl multi_vram_buffer_vert
multi_vram_buffer_vert:
; A - len
; X - <ppu_address
; __rc2 - <data
; __rc3 - >data
; __rc4 - >ppu_address
ldy VRAM_INDEX

sta __rc5 ; save len for loop comparison
sta VRAM_BUF+2, y ; store len in header

lda #$80 ; load vertical flag
bne multi_vram_buffer_common ; always taken




;void one_vram_buffer(char data, int ppu_address);
.section .text.one_vram_buffer,"ax",@progbits
.globl one_vram_buffer
one_vram_buffer:
; A - data
; X - <ppu_address
; __rc2 - >ppu_address
ldy VRAM_INDEX

sta VRAM_BUF+2, y ; data
lda __rc2
sta VRAM_BUF, y ; address hi
txa
sta VRAM_BUF+1, y ; adderess lo
iny
iny
iny
lda #$ff ;=NT_UPD_EOF
sta VRAM_BUF, y
sty VRAM_INDEX
rts



; now in __post_vram_update
;void clear_vram_buffer(void);
;_clear_vram_buffer:
; lda #0
; sta VRAM_INDEX
; lda #$ff
; sta VRAM_BUF
; rts
1 change: 1 addition & 0 deletions mos-platform/nes/neslib/oam_update.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// information.

__attribute__((section(".zp.sprid"))) unsigned SPRID;
__attribute__((weak, aligned(256), section(".noinit.oam_buf"))) char OAM_BUF[256];

void oam_set(char index) { SPRID = index & 0xfc; }

Expand Down
8 changes: 0 additions & 8 deletions mos-platform/nes/neslib/oam_update.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@

.include "nes.inc"

; Reserve space at beginning of RAM for OAM buffer.
.section .noinit.oam_buf,"a",@nobits
.globl OAM_BUF
.align 256
OAM_BUF:
.space 256


.section .init.270,"axR",@progbits
.globl oam_update_init
oam_update_init:
Expand Down
3 changes: 1 addition & 2 deletions mos-platform/nes/neslib/pal_update.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
// information.

__attribute__((section(".zp.pal_update"))) volatile char PAL_UPDATE;
__attribute__((weak, aligned(32), section(".noinit.pal_buf"))) volatile char PAL_BUF[32];


extern volatile char PAL_BUF[];
void pal_col(char index, char color) {
PAL_BUF[index & 0x1f] = color;
++PAL_UPDATE;
Expand Down
4 changes: 0 additions & 4 deletions mos-platform/nes/neslib/pal_update.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@

.include "nes.inc"

; Place the pallette buffer at the very bottom 32 bytes of the hard stack.
.globl PAL_BUF
PAL_BUF = 0x0100

.section .init.265,"axR",@progbits
.globl pal_update_init
pal_update_init:
Expand Down

0 comments on commit e44cf72

Please sign in to comment.