Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split neslib and nesdoug components so they are linked conditionally #217

Merged
merged 3 commits into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mos-platform/nes/nesdoug/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ install(FILES
TYPE INCLUDE)

add_platform_library(nes-nesdoug
metatile.c
metatile.s
nesdoug.s
nesdoug.c
padlib.s
vram_buffer.c
vram_buffer.s
zaplib.s
)
target_include_directories(nes-nesdoug BEFORE PUBLIC ..)
Expand Down
15 changes: 15 additions & 0 deletions mos-platform/nes/nesdoug/metatile.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2022 LLVM-MOS Project
// Licensed under the Apache License, Version 2.0 with LLVM Exceptions.
// See /~https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license
// information.

// Keeping these functions in C LTOs them in, which informs LTO code generation
// that the ZP regions aren't available. This saves users of the library from
// having to manually reserve ZP space from LTO.
__attribute__((section(".zp.meta_ptr"))) const char *META_PTR;
__attribute__((section(".zp.data_ptr"))) const char *DATA_PTR;

void set_data_pointer(const void *data) { DATA_PTR = (const char *)data; }
void set_mt_pointer(const void *metatiles) {
META_PTR = (const char *)metatiles;
}
270 changes: 270 additions & 0 deletions mos-platform/nes/nesdoug/metatile.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
;written by Doug Fraker
;version 1.2, 1/1/2022

.zeropage VRAM_BUF, META_PTR, DATA_PTR



;void buffer_4_mt(int ppu_address, char index);
.section .text.buffer_4_mt,"ax",@progbits
.globl buffer_4_mt
buffer_4_mt:
sta __rc3
lda __rc2
;a is the index into the data, get 4 metatiles

and #$ee ;sanitize, x and y should be even
tay
lda (DATA_PTR), y
sta __rc6
iny
lda (DATA_PTR), y
sta __rc7
tya
clc
adc #15
cmp #$f0 ;too far, data set only 240 bytes
bcs .Lskip
tay
lda (DATA_PTR), y
sta __rc8
iny
lda (DATA_PTR), y
sta __rc9
.Lskip:
;metatiles are in _rc6 - rc9 now
lda __rc3
and #$9c ;sanitize, should be top left
sta __rc11
stx __rc12 ;save for later, ppu_address

sta __rc4
txa
ora #$40 ;NT_UPD_HORZ
sta __rc5

;buffer the ppu_address

lda #0
sta __rc10 ;loop count, index to the metatiles
ldx VRAM_INDEX
.Lbuffer_4_mt_loop:
lda __rc4 ;low byte
sta VRAM_BUF+1, x
lda __rc5 ;high byte
sta VRAM_BUF,x
jsr .Lsub1 ;adds $20 to the address for next time

lda #4 ;tell the system 4 bytes in a row
sta VRAM_BUF+2,x
sta VRAM_BUF+9,x ;loops twice, so, it does this twice

jsr .Lsub2 ;gets y is which metatile

lda (META_PTR), y
sta VRAM_BUF+3,x ; buffer the 4 tiles
iny
lda (META_PTR), y
sta VRAM_BUF+4,x
iny
lda (META_PTR), y
sta VRAM_BUF+10,x
iny
lda (META_PTR), y
sta VRAM_BUF+11,x
jsr .Lsub4 ;get attrib bits, shift into place

;same, but for right side
lda __rc4 ;low byte ppu address, again
sta VRAM_BUF+8,x
lda __rc5 ;high byte
sta VRAM_BUF+7,x
jsr .Lsub1

inc __rc10 ;count and index
jsr .Lsub2
lda (META_PTR), y
sta VRAM_BUF+5,x ; buffer the 4 tiles
iny
lda (META_PTR), y
sta VRAM_BUF+6,x
iny
lda (META_PTR), y
sta VRAM_BUF+12,x
iny
lda (META_PTR), y
sta VRAM_BUF+13,x
jsr .Lsub4

txa ;adjust the vram index to the next set
clc
adc #14
tax

jsr .Lsub3 ;check if lowest y on screen, skip the la
bne .Lloop_done

inc __rc10
ldy __rc10
cpy #4
bcc .Lbuffer_4_mt_loop

.Lloop_done:



;now push 1 attribute byte to the vram buffer
;first, shift the bits to get an attribute address
;we stored the original at TEMP+7,8, 8 is high byte
;a bunch of bit shifting to get 3 bits from x and 3 y
lsr __rc12 ;high byte
ror __rc11
lsr __rc12
ror __rc11
lda __rc11
pha ;save
and #7 ;just the x bits
sta __rc4
pla
lsr a ;just the y bits
lsr a
and #$f8
ora #$c0
ora __rc4
sta __rc4 ;low byte
;now high byte
lda __rc12
asl a
asl a
ora #$23
sta __rc5 ;high byte, and the low byte is in TEMP


;finally, push it all to the vram_buffer as a single byte
lda __rc5 ;high byte
sta VRAM_BUF,x
inx
lda __rc4 ;low byte
sta VRAM_BUF,x
inx
lda __rc14
sta VRAM_BUF,x
inx
lda #$ff ;=NT_UPD_EOF
sta VRAM_BUF,x
stx VRAM_INDEX
rts


.Lsub1: ;add $20 is a 1 down on the screen
tay ;high byte
lda __rc4
clc
adc #$20
sta __rc4
bcc .Lsub1b
iny
.Lsub1b:
sty __rc5
rts


.Lsub2: ;get the next metatile offset
ldy __rc10
lda __rc6, y ;metatile
;multiply by 5
sta __rc13
asl a
asl a ;x4 = 4 bytes per
clc
adc __rc13
tay
rts


.Lsub3: ;check make sure we're not at the lowest y and overflowing
ldy #0 ;x is forbidden
lda __rc12 ;high byte
and #$03
cmp #$03
bne .Lnot_overflow
lda __rc11
cmp #$80 ;last row of mt
bcc .Lnot_overflow
iny
lsr __rc14 ;make sure the attrib bits in correct position
lsr __rc14
lsr __rc14
lsr __rc14
.Lnot_overflow:
tya ;set flag
rts


.Lsub4: ;get attrib bits, roll them in place
iny
lda (META_PTR), y ;5th byte = attribute
and #3 ;just need 2 bits
ror a ;bit to carry
ror __rc14 ;shift carry in
ror a ;bit to carry
ror __rc14 ;roll the a.t. bits in the high 2 bits
rts




;void buffer_1_mt(int ppu_address, char metatile);
.section .text.buffer_1_mt,"ax",@progbits
.globl buffer_1_mt
buffer_1_mt:
and #$de ;sanitize, should be even x and y
sta __rc4
txa
ora #$40 ;NT_UPD_HORZ
sta __rc5

ldx VRAM_INDEX
lda __rc4 ;ppu address
sta VRAM_BUF+1,x
clc
adc #$20 ;shouldn't be rollover
sta VRAM_BUF+6,x

lda __rc5
sta VRAM_BUF,x
sta VRAM_BUF+5,x

lda #2 ;tell the system 2 bytes in a row
sta VRAM_BUF+2,x
sta VRAM_BUF+7,x

lda __rc2 ;which metatile
asl a
asl a
clc
adc __rc2 ;multiply 5
tay
lda (META_PTR), y ;tile
sta VRAM_BUF+3,x
iny
lda (META_PTR), y ;tile
sta VRAM_BUF+4,x
iny
lda (META_PTR), y ;tile
sta VRAM_BUF+8,x
iny
lda (META_PTR), y ;tile
sta VRAM_BUF+9,x

txa
clc
adc #10
sta VRAM_INDEX
tax
lda #$ff ;=NT_UPD_EOF
sta VRAM_BUF,x
rts



20 changes: 0 additions & 20 deletions mos-platform/nes/nesdoug/nesdoug.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,6 @@
// based on code by Groepaz/Hitmen <groepaz@gmx.net>, Ullrich von Bassewitz
// <uz@cc65.org>

// Keeping these functions in C LTOs them in, which informs LTO code generation
// that the ZP regions aren't available. This saves users of the library from
// having to manually reserve ZP space from LTO.
__attribute__((section(".zp.vram_index"))) char VRAM_INDEX;
__attribute__((section(".zp.meta_ptr"))) const char *META_PTR;
__attribute__((section(".zp.data_ptr"))) const char *DATA_PTR;

extern char VRAM_BUF[];
void set_vram_update(const void *buf);
void set_vram_buffer(void) {
VRAM_BUF[0] = 0xff;
VRAM_INDEX = 0;
set_vram_update(VRAM_BUF);
}

extern char PAD_STATET[];
char get_pad_new(char pad) { return PAD_STATET[pad]; }

Expand All @@ -44,11 +29,6 @@ void set_scroll_y(unsigned y) {
PPUCTRL_VAR = PPUCTRL_VAR & 0xfd | (y >> 8 & 0x01) << 1;
}

void set_data_pointer(const void *data) { DATA_PTR = (const char *)data; }
void set_mt_pointer(const void *metatiles) {
META_PTR = (const char *)metatiles;
}

extern volatile char PPUMASK_VAR;
void color_emphasis(char color) {
PPUMASK_VAR = PPUMASK_VAR & 0x1f | color & 0xe0;
Expand Down
Loading