Skip to content

Commit

Permalink
Rewrite simple nesdoug functions in C.
Browse files Browse the repository at this point in the history
  • Loading branch information
mysterymath committed Nov 4, 2022
1 parent ee4ea70 commit 1b4f8d3
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 151 deletions.
51 changes: 48 additions & 3 deletions mos-platform/nes/nesdoug/nesdoug.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,56 @@
// information.

// Startup code for cc65 and Shiru's NES library
// based on code by Groepaz/Hitmen <[email protected]>, Ullrich von Bassewitz <[email protected]>
// based on code by Groepaz/Hitmen <[email protected]>, Ullrich von Bassewitz
// <[email protected]>

// 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"))) char* META_PTR;
__attribute__((section(".zp.data_ptr"))) char* DATA_PTR;
__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]; }

extern volatile char FRAME_CNT1;
char get_frame_count(void) { return FRAME_CNT1; }

extern volatile char __FT_SONG_SPEED;
void set_music_speed(char tempo) { __FT_SONG_SPEED = tempo; }

extern volatile char PPUCTRL_VAR;
extern volatile char SCROLL_X;
void set_scroll_x(unsigned x) {
SCROLL_X = x & 0xff;
PPUCTRL_VAR = PPUCTRL_VAR & 0xfe | x >> 8 & 0x01;
}

extern volatile char SCROLL_Y;
void set_scroll_y(unsigned y) {
SCROLL_Y = 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;
}

extern volatile char FRAME_CNT1;
extern volatile char RAND_SEED;
void seed_rng(void) { RAND_SEED = FRAME_CNT1; }
20 changes: 10 additions & 10 deletions mos-platform/nes/nesdoug/nesdoug.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extern "C" {

// sets the vram update to point to the vram_buffer. VRAM_BUF defined in crt0.s
// this can be undone by set_vram_update(NULL)
__attribute__((leaf)) void set_vram_buffer(void);
void set_vram_buffer(void);

// to push a single byte write to the vram_buffer
__attribute__((leaf)) void one_vram_buffer(char data, int ppu_address);
Expand All @@ -30,17 +30,17 @@ __attribute__((leaf)) void multi_vram_buffer_vert(const void *data, char len, in

// pad 0 or 1, use AFTER pad_poll() to get the trigger / new button presses
// more efficient than pad_trigger, which runs the entire pad_poll code again
__attribute__((leaf)) char get_pad_new(char pad);
char get_pad_new(char pad);

// use this internal value to time events, this ticks up every frame
__attribute__((leaf)) char get_frame_count(void);
char get_frame_count(void);

// this will alter the tempo of music, range 1-12 are reasonable, low is faster
// default is 6
// music_play also sets the tempo, and any Fxx effect in the song will too
// you will probably have to repeatedly set_music_speed() every frame
// music_stop() and music_pause() also overwrite this value
__attribute__((leaf)) void set_music_speed(char tempo);
void set_music_speed(char tempo);

// expects an object (struct) where the first 4 bytes are X, Y, width, height
// you will probably have to pass the address of the object like &object
Expand All @@ -54,14 +54,14 @@ __attribute__((leaf)) void pal_fade_to(char from, char to);

// x can be in the range 0-0x1ff, but any value would be fine, it discards
// higher bits
__attribute__((leaf)) void set_scroll_x(unsigned x);
void set_scroll_x(unsigned x);

// y can be in the range 0-0x1ff, but any value would be fine, it discards
// higher bits NOTE - different system than neslib (which needs y in range
// 0-0x1df) the advantage here, is you can set Y scroll to 0xff (-1) to shift
// the screen down 1, which aligns it with sprites, which are shifted down 1
// pixel
__attribute__((leaf)) void set_scroll_y(unsigned y);
void set_scroll_y(unsigned y);

// add a value to y scroll, keep the low byte in the 0-0xef range
// returns y scroll, which will have to be passed to set_scroll_y
Expand All @@ -86,14 +86,14 @@ __attribute__((leaf)) int get_at_addr(char nt, char x, char y);
// for the metatile system, pass it the addresses of the room data
// room data should be exactly 240 bytes (16x15)
// each byte represents a 16x16 px block of the screen
__attribute__((leaf)) void set_data_pointer(const void *data);
void set_data_pointer(const void *data);

// for the metatile system, pass it the addresses of the metatile data
// a metatile is a 16x16 px block
// metatiles is variable length, 5 bytes per metatile...
// TopL, TopR, BottomL, BottomR, then 1 byte of palette 0-3
// max metatiles = 51 (because 51 x 5 = 255)
__attribute__((leaf)) void set_mt_pointer(const void *metatiles);
void set_mt_pointer(const void *metatiles);

// will push 1 metatile and 0 attribute bytes to the vram_buffer
// make sure to set_vram_buffer(), and clear_vram_buffer(),
Expand All @@ -116,7 +116,7 @@ __attribute__((leaf)) void buffer_4_mt(int ppu_address, char index);
__attribute__((leaf)) void flush_vram_update2(void);

// change the PPU's color emphasis bits
__attribute__((leaf)) void color_emphasis(char color);
void color_emphasis(char color);

#define COL_EMP_BLUE 0x80
#define COL_EMP_GREEN 0x40
Expand All @@ -142,7 +142,7 @@ __attribute__((leaf)) void gray_line(void);

// get from the frame count. You can use a button (start on title screen) to
// trigger
__attribute__((leaf)) void seed_rng(void);
void seed_rng(void);

#ifdef __cplusplus
}
Expand Down
138 changes: 0 additions & 138 deletions mos-platform/nes/nesdoug/nesdoug.s
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,6 @@ __post_vram_update:
stx mos8(VRAM_INDEX)
rts

;void set_vram_buffer(void)
.section .text.set_vram_buffer,"ax",@progbits
.globl set_vram_buffer
set_vram_buffer:
ldx #$ff
stx VRAM_BUF
inx ;x=0
stx mos8(VRAM_INDEX)
lda #<VRAM_BUF
sta mos8(__rc2)
lda #>VRAM_BUF
sta mos8(__rc3)
jmp set_vram_update




;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
Expand Down Expand Up @@ -125,37 +108,6 @@ one_vram_buffer:



;char get_pad_new(char pad);
.section .text.get_pad_new,"ax",@progbits
.globl get_pad_new
get_pad_new:
tay
lda mos8(PAD_STATET),y
rts




;char get_frame_count(void);
.section .text.get_frame_count,"ax",@progbits
.globl get_frame_count
get_frame_count:
lda mos8(FRAME_CNT1)
rts




;void set_music_speed(char tempo);
.section .text.set_music_speed,"ax",@progbits
.globl set_music_speed
set_music_speed:
sta __FT_SONG_SPEED
rts




;char check_collision(void * object1, void * object2);
.section .text.check_collision,"ax",@progbits
.globl check_collision
Expand Down Expand Up @@ -289,41 +241,6 @@ pal_fade_to:



;void set_scroll_x(unsigned x);
.section .text.set_scroll_x,"ax",@progbits
.globl set_scroll_x
set_scroll_x:
sta mos8(SCROLL_X)
txa
and #$01
sta mos8(__rc2)
lda mos8(PPUCTRL_VAR)
and #$fe
ora mos8(__rc2)
sta mos8(PPUCTRL_VAR)
rts




;void set_scroll_y(unsigned y);
.section .text.set_scroll_y,"ax",@progbits
.globl set_scroll_y
set_scroll_y:
sta mos8(SCROLL_Y)
txa
and #$01
asl a
sta mos8(__rc2)
lda mos8(PPUCTRL_VAR)
and #$fd
ora mos8(__rc2)
sta mos8(PPUCTRL_VAR)
rts




;int add_scroll_y(char add, unsigned scroll);
.section .text.add_scroll_y,"ax",@progbits
.globl add_scroll_y
Expand Down Expand Up @@ -437,32 +354,6 @@ get_at_addr:



;void set_data_pointer(const void * data);
.section .text.set_data_pointer,"ax",@progbits
.globl set_data_pointer
set_data_pointer:
lda mos8(__rc2)
sta mos8(DATA_PTR)
lda mos8(__rc3)
sta mos8(DATA_PTR+1)
rts




;void set_mt_pointer(const void * metatiles);
.section .text.set_mt_pointer,"ax",@progbits
.globl set_mt_pointer
set_mt_pointer:
lda mos8(__rc2)
sta mos8(META_PTR)
lda mos8(__rc3)
sta mos8(META_PTR+1)
rts




;void buffer_4_mt(int ppu_address, char index);
.section .text.buffer_4_mt,"ax",@progbits
.globl buffer_4_mt
Expand Down Expand Up @@ -727,22 +618,6 @@ buffer_1_mt:



;void color_emphasis(char color);
.section .text.color_emphasis,"ax",@progbits
.globl color_emphasis
color_emphasis:
;a = bits 1110 0000
and #$e0 ;sanitize
sta mos8(__rc2)
lda mos8(PPUMASK_VAR)
and #$1f
ora mos8(__rc2)
sta mos8(PPUMASK_VAR)
rts




;void xy_split(unsigned x, unsigned y);
.section .text.xy_split,"ax",@progbits
.globl xy_split
Expand Down Expand Up @@ -835,16 +710,3 @@ gray_line:
lda mos8(PPUMASK_VAR) ;normal
sta PPUMASK
rts




;void seed_rng(void);
.section .text.seed_rng,"ax",@progbits
.globl seed_rng
seed_rng:
lda mos8(FRAME_CNT1)
sta mos8(RAND_SEED)
rts


0 comments on commit 1b4f8d3

Please sign in to comment.