nes: updated presets

This commit is contained in:
Steven Hugg 2019-03-10 12:17:12 -04:00
parent 8d635bcf5d
commit 1e44d05536
17 changed files with 265 additions and 192 deletions

View File

@ -97,7 +97,8 @@ TODO:
- NES: disassembly not aligned on PC
- NES: vrambuf.c for Solarian
- game starts even if switched away before first load
- vcs: break on # of lines changed (maybe using getRasterPosition?)
- profiler restarts when paused
WEB WORKER FORMAT

View File

@ -3,19 +3,15 @@
#include <string.h>
#include <stdlib.h>
// link the pattern table into PRG ROM
// we'll write it into CHR RAM on startup
// link the pattern table into CHR ROM
//#link "chr_generic.s"
//#link "jroatch.c"
extern unsigned char jroatch_chr[0x1000];
#define PATTERN_TABLE jroatch_chr
// palette for balls, there are four sets for different ball colors
const unsigned char bg_palette[16]={/*{pal:"nes",n:4,sets:4}*/
0x0f,0x17,0x27,0x37,
0x0f,0x11,0x21,0x31,
0x0f,0x15,0x25,0x35,
0x0f,0x19,0x29,0x39
const char PALETTE[16] = {
0x03,
0x11,0x30,0x27, 0,
0x1c,0x20,0x2c, 0,
0x00,0x10,0x20, 0,
0x06,0x16,0x26
};
// convert nametable address to attribute address
@ -63,7 +59,8 @@ void color_demo(void) {
while (1) {
char x = rand() & 0x3f;
char y = rand() & 0x3f;
put_pixel(x, y, 2);
char color = rand() & 3;
put_pixel(x, y, color);
// reset scroll position
vram_adr(0);
}
@ -94,16 +91,8 @@ void color_demo1(void) {
// main function, run after console reset
void main(void) {
// copy pattern table to PRG RAM
vram_adr(0x0);
vram_write((unsigned char*)PATTERN_TABLE, sizeof(PATTERN_TABLE));
// clear name tables
vram_adr(0x2000);
vram_fill(0, 0x800);
// set palette colors
pal_bg(bg_palette);
pal_bg(PALETTE);
// enable PPU rendering (turn on screen)
ppu_on_all();

View File

@ -0,0 +1,79 @@
.export _climbr_title_pal
.export _climbr_title_rle
_climbr_title_pal:
.byte $0f,$11,$25,$35,$0f,$01,$21,$30
.byte $0f,$06,$1c,$3c,$0f,$11,$28,$38
_climbr_title_rle:
.byte $01,$00,$01,$10,$80,$01,$02,$00
.byte $80,$00,$80,$00,$01,$1f,$80,$80
.byte $00,$01,$07,$41,$4e,$00,$38,$42
.byte $49,$54,$57,$4f,$52,$4b,$53,$48
.byte $4f,$50,$00,$47,$41,$4d,$45,$00
.byte $01,$02,$80,$00,$01,$1d,$7f,$7f
.byte $80,$00,$01,$1c,$8f,$7f,$80,$00
.byte $01,$06,$80,$01,$0b,$00,$01,$09
.byte $80,$8f,$80,$00,$01,$09,$7f,$01
.byte $02,$80,$01,$02,$7f,$7f,$80,$01
.byte $02,$00,$ba,$bb,$00,$01,$02,$80
.byte $00,$8f,$80,$01,$03,$00,$80,$80
.byte $00,$01,$03,$7f,$7f,$8f,$8f,$7f
.byte $7f,$80,$7f,$7f,$80,$01,$03,$be
.byte $bf,$80,$00,$00,$80,$01,$04,$00
.byte $80,$01,$03,$00,$01,$02,$7f,$7f
.byte $8f,$80,$80,$8f,$8f,$00,$7f,$7f
.byte $80,$7f,$7f,$80,$7f,$7f,$80,$7f
.byte $00,$7f,$00,$80,$80,$7f,$7f,$80
.byte $7f,$00,$80,$00,$00,$7f,$01,$02
.byte $80,$01,$02,$00,$01,$02,$7f,$7f
.byte $80,$8f,$8f,$80,$7f,$01,$06,$80
.byte $80,$7f,$01,$02,$8f,$80,$80,$00
.byte $00,$7f,$01,$02,$80,$01,$02,$00
.byte $01,$02,$7f,$7f,$80,$80,$00,$80
.byte $7f,$7f,$8f,$7f,$8f,$7f,$7f,$80
.byte $80,$7f,$7f,$8f,$80,$80,$00,$01
.byte $02,$7f,$01,$02,$80,$01,$02,$00
.byte $01,$02,$7f,$7f,$80,$7f,$7f,$80
.byte $7f,$7f,$80,$7f,$80,$7f,$7f,$80
.byte $80,$7f,$7f,$80,$01,$02,$00,$01
.byte $02,$7f,$01,$02,$80,$01,$02,$00
.byte $01,$02,$7f,$7f,$80,$7f,$7f,$80
.byte $7f,$7f,$80,$7f,$80,$7f,$7f,$80
.byte $80,$7f,$7f,$80,$80,$00,$01,$03
.byte $7f,$01,$02,$00,$80,$01,$04,$7f
.byte $7f,$80,$7f,$7f,$80,$7f,$7f,$80
.byte $7f,$80,$7f,$7f,$80,$80,$7f,$7f
.byte $80,$80,$00,$01,$03,$8f,$7f,$7f
.byte $00,$80,$01,$04,$7f,$7f,$80,$7f
.byte $7f,$80,$7f,$7f,$80,$7f,$80,$7f
.byte $7f,$80,$80,$7f,$7f,$80,$80,$00
.byte $01,$04,$8f,$7f,$7f,$00,$00,$7f
.byte $7f,$80,$8f,$8f,$80,$8f,$8f,$80
.byte $8f,$8f,$80,$8f,$00,$8f,$8f,$80
.byte $00,$8f,$8f,$80,$80,$00,$01,$05
.byte $8f,$7f,$01,$03,$8f,$00,$01,$05
.byte $90,$80,$80,$00,$80,$00,$80,$00
.byte $00,$80,$01,$02,$00,$80,$00,$01
.byte $06,$8f,$01,$03,$00,$01,$02,$a1
.byte $01,$13,$00,$01,$0a,$ac,$a1,$01
.byte $13,$00,$01,$09,$ac,$ac,$20,$01
.byte $03,$00,$01,$18,$ac,$ac,$00,$06
.byte $01,$12,$00,$01,$08,$ac,$ac,$00
.byte $00,$06,$00,$01,$10,$06,$00,$01
.byte $07,$ac,$ac,$00,$01,$02,$06,$00
.byte $1f,$00,$50,$52,$45,$53,$53,$00
.byte $53,$54,$41,$52,$54,$00,$1e,$00
.byte $06,$00,$01,$06,$ac,$ac,$00,$01
.byte $03,$06,$00,$01,$10,$06,$00,$01
.byte $05,$ac,$ac,$00,$01,$04,$06,$01
.byte $12,$00,$01,$04,$ac,$ac,$00,$01
.byte $1c,$ac,$ac,$00,$01,$1c,$ac,$ac
.byte $00,$01,$1c,$ac,$ac,$00,$01,$1c
.byte $ac,$ac,$00,$01,$1d,$80,$a0,$01
.byte $03,$20,$00,$01,$02,$a0,$20,$00
.byte $f0,$00,$01,$02,$88,$22,$02,$00
.byte $01,$04,$88,$22,$20,$00,$01,$05
.byte $0a,$02,$00,$01,$07,$d5,$55,$01
.byte $02,$75,$00,$01,$02,$55,$01,$04
.byte $00,$01,$02,$05,$01,$03,$05,$01
.byte $00

View File

@ -69,34 +69,33 @@ SetPalette: subroutine
;;;;; INTERRUPT HANDLERS
NMIHandler:
SAVE_REGS
SAVE_REGS ; save registers
; update scroll position (must be done after VRAM updates)
jsr ReadJoypad
pha
and #$03
tay
lda ScrollDirTab,y
jsr ReadJoypad0 ; read first controller
pha ; push joypad bitmask
and #$03 ; only keep first 2 bits
tay ; A -> Y
lda ScrollDirTab,y ; lookup table
clc
adc ScrollX
sta ScrollX
sta PPU_SCROLL
pla
adc ScrollX ; A = A + ScrollX
sta ScrollX ; -> ScrollX
sta PPU_SCROLL ; -> first scroll byte
pla ; pop joypad bitmask
lsr
lsr
and #$03
tay
lda ScrollDirTab,y
and #$03 ; take next two bits
tay
lda ScrollDirTab,y ; do another lookup
clc
adc ScrollY
sta ScrollY
sta PPU_SCROLL
; reload registers
RESTORE_REGS
adc ScrollY ; A = A + ScrollY
sta ScrollY ; -> ScrollY
sta PPU_SCROLL ; -> second scroll byte
RESTORE_REGS ; restore registers
rti
; Scroll direction lookup table
ScrollDirTab:
hex 00 01 ff 00
hex 00 01 ff 00 ; 0,1,-1,0
;;;;; CONSTANT DATA

View File

@ -1,48 +1,34 @@
#include <nes.h>
#include "neslib.h"
#include <string.h>
const unsigned char TEXT[]="Hello PPU!!!!";
// link the pattern table into CHR ROM
//#link "chr_generic.s"
const unsigned char PALETTE[]={0x1, 0x00, 0x10, 0x20}; // blue, gray, lt gray, white
// function to write a string into the name table
// adr = start address in name table
// str = pointer to string
void put_str(unsigned int adr, const char *str) {
vram_adr(adr); // set PPU read/write address
vram_write(str, strlen(str)); // write bytes to PPU
}
void main (void) {
unsigned char index; // used in 'for' loops
// main function, run after console reset
void main(void) {
// set palette colors
pal_col(1,0x04);
pal_col(2,0x20);
pal_col(3,0x30);
// if we've just powered on,
// wait for PPU to warm-up
waitvsync();
waitvsync();
// write text to name table
put_str(NTADR_A(2,2),"HELLO, WORLD!");
put_str(NTADR_A(2,4),"THIS CODE PRINTS SOME TEXT");
put_str(NTADR_A(2,5),"USING ASCII-ENCODED CHARACTER");
put_str(NTADR_A(2,6),"SET WITH CAPITAL LETTERS ONLY");
// turn off screen
PPU.control = 0x0; // NMI off
PPU.mask = 0x0; // screen off
// load the palette
// set PPU address to 0x3f00
PPU.vram.address = 0x3f;
PPU.vram.address = 0x00;
for (index = 0; index < sizeof(PALETTE); index++) {
PPU.vram.data = PALETTE[index];
}
// load the text into VRAM
// set PPU address to 0x21c9
PPU.vram.address = 0x21;
PPU.vram.address = 0xc9;
for (index = 0; index < sizeof(TEXT); index++) {
PPU.vram.data = TEXT[index];
}
// reset the scroll position to 0
PPU.scroll = 0;
PPU.scroll = 0;
// reset the PPU address to 0x2000 (frame start)
PPU.vram.address = 0x20;
PPU.vram.address = 0x00;
// turn on the screen
PPU.mask = 0x1e;
// enable PPU rendering (turn on screen)
ppu_on_all();
// infinite loop
while (1);
while (1) ;
}

View File

@ -1,34 +0,0 @@
#include "neslib.h"
#include <string.h>
// link the pattern table into CHR ROM
//#link "chr_generic.s"
// function to write a string into the name table
// adr = start address in name table
// str = pointer to string
void put_str(unsigned int adr, const char *str) {
vram_adr(adr); // set PPU read/write address
vram_write(str, strlen(str)); // write bytes to PPU
}
// main function, run after console reset
void main(void) {
// set palette colors
pal_col(1,0x04);
pal_col(2,0x20);
pal_col(3,0x30);
// write text to name table
put_str(NTADR_A(2,2),"HELLO, WORLD!");
put_str(NTADR_A(2,4),"THIS CODE PRINTS SOME TEXT");
put_str(NTADR_A(2,5),"USING ASCII-ENCODED CHARACTER");
put_str(NTADR_A(2,6),"SET WITH CAPITAL LETTERS ONLY");
// enable PPU rendering (turn on screen)
ppu_on_all();
// infinite loop
while (1) ;
}

View File

@ -1,55 +0,0 @@
//this example code unpacks a RLE'd nametable into the VRAM
//you can create the source data using NES Screen Tool
#include "neslib.h"
const unsigned char test[308]={
0x01,0x00,0x01,0xa3,0x10,0x01,0x04,0x00,0x10,0x01,0x04,0x00,0x10,0x01,0x04,0x00,
0x10,0x01,0x04,0x00,0x01,0x0a,0x10,0x00,0x01,0x02,0x10,0x00,0x01,0x04,0x10,0x00,
0x01,0x06,0x10,0x00,0x01,0x0c,0x10,0x00,0x01,0x02,0x10,0x01,0x02,0x00,0x01,0x02,
0x10,0x01,0x04,0x00,0x01,0x02,0x10,0x00,0x01,0x0c,0x10,0x00,0x01,0x02,0x10,0x00,
0x01,0x08,0x10,0x00,0x01,0x02,0x10,0x00,0x01,0x0c,0x10,0x00,0x01,0x02,0x10,0x01,
0x04,0x00,0x10,0x01,0x04,0x00,0x01,0x02,0x10,0x00,0x01,0x42,0x10,0x00,0x01,0x06,
0x10,0x01,0x04,0x00,0x10,0x00,0x01,0x04,0x10,0x01,0x04,0x00,0x10,0x00,0x01,0x04,
0x10,0x00,0x01,0x06,0x10,0x00,0x01,0x02,0x10,0x00,0x10,0x00,0x01,0x04,0x10,0x00,
0x01,0x06,0x10,0x01,0x04,0x00,0x01,0x06,0x10,0x00,0x01,0x02,0x10,0x00,0x10,0x00,
0x01,0x04,0x10,0x01,0x02,0x00,0x01,0x04,0x10,0x00,0x01,0x02,0x10,0x00,0x01,0x06,
0x10,0x01,0x03,0x00,0x00,0x10,0x00,0x01,0x04,0x10,0x00,0x01,0x06,0x10,0x00,0x01,
0x02,0x10,0x00,0x01,0x06,0x10,0x00,0x01,0x02,0x10,0x00,0x10,0x01,0x04,0x00,0x10,
0x01,0x04,0x00,0x01,0x02,0x10,0x01,0x04,0x00,0x01,0x46,0x10,0x00,0x01,0x02,0x10,
0x00,0x10,0x01,0x04,0x00,0x10,0x01,0x04,0x00,0x01,0x0e,0x10,0x10,0x00,0x10,0x10,
0x00,0x10,0x00,0x01,0x02,0x10,0x00,0x10,0x00,0x01,0x02,0x10,0x00,0x01,0x0e,0x10,
0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x01,0x02,0x10,0x00,0x10,0x00,0x01,0x02,0x10,
0x00,0x01,0x0e,0x10,0x00,0x01,0x02,0x10,0x00,0x10,0x01,0x04,0x00,0x10,0x01,0x04,
0x00,0x01,0x0e,0x10,0x00,0x01,0x02,0x10,0x00,0x10,0x00,0x01,0x02,0x10,0x00,0x10,
0x00,0x01,0xde,0x50,0x01,0x07,0x55,0x01,0x07,0xa5,0x01,0x07,0xaa,0x01,0x0f,0x0a,
0x01,0x07,0x01,0x00
};
const unsigned char palette[16]={ 0x0f,0x21,0x10,0x30,0x0f,0x14,0x21,0x31,0x0f,0x29,0x16,0x26,0x0f,0x09,0x19,0x29 }; //palette data
//#link "tileset1.c"
// tile set, two planes for 4 colors
extern unsigned char TILESET[8*256];
void main(void)
{
//rendering is disabled at the startup, and palette is all black
pal_bg(palette);//set background palette from an array
//copy tileset to RAM
vram_adr(0x0);
vram_write((unsigned char*)TILESET, sizeof(TILESET));
//unpack nametable into the VRAM
vram_adr(0x2000);
vram_unrle(test);
//enable rendering
ppu_on_all();
while(1);//do nothing, infinite loop
}

View File

@ -44,18 +44,21 @@ PrevRandom subroutine
;;;;; CONTROLLER READING
ReadJoypad subroutine
ReadJoypad0 subroutine
ldy #0
ReadJoypadY
lda #$01
sta JOYPAD1 ; set strobe bit
tax ; X = 1
sta JOYPAD1,y ; set strobe bit
lsr ; now A is 0
sta JOYPAD1 ; clear strobe bit
sta JOYPAD1,y ; clear strobe bit
ldx #8 ; read 8 bits
.loop:
lda JOYPAD1 ; load controller state
pha ; save A (result)
lda JOYPAD1,y ; load controller state
lsr ; bit 0 -> carry
txa ; X -> A
rol ; carry -> bit 0 of result, bit 7 -> carry
tax ; A -> X
bcc .loop ; repeat until 1 shifted out
pla ; restore A (result)
rol ; carry -> bit 0 of result
dex ; X = X - 1
bne .loop ; repeat if X is 0
rts ; controller bits returned in A

48
presets/nes/ppuhello.c Normal file
View File

@ -0,0 +1,48 @@
#include <nes.h>
const unsigned char TEXT[]="Hello PPU!!!!";
const unsigned char PALETTE[]={0x1, 0x00, 0x10, 0x20}; // blue, gray, lt gray, white
void main (void) {
unsigned char index; // used in 'for' loops
// if we've just powered on,
// wait for PPU to warm-up
waitvsync();
waitvsync();
// turn off screen
PPU.control = 0x0; // NMI off
PPU.mask = 0x0; // screen off
// load the palette
// set PPU address to 0x3f00
PPU.vram.address = 0x3f;
PPU.vram.address = 0x00;
for (index = 0; index < sizeof(PALETTE); index++) {
PPU.vram.data = PALETTE[index];
}
// load the text into VRAM
// set PPU address to 0x21c9
PPU.vram.address = 0x21;
PPU.vram.address = 0xc9;
for (index = 0; index < sizeof(TEXT); index++) {
PPU.vram.data = TEXT[index];
}
// reset the scroll position to 0
PPU.scroll = 0;
PPU.scroll = 0;
// reset the PPU address to 0x2000 (frame start)
PPU.vram.address = 0x20;
PPU.vram.address = 0x00;
// turn on the screen
PPU.mask = 0x1e;
// infinite loop
while (1);
}

49
presets/nes/rletitle.c Normal file
View File

@ -0,0 +1,49 @@
// this example code unpacks a RLE'd nametable into the VRAM
// you can create the source data using NES Screen Tool
#include "neslib.h"
extern const byte climbr_title_pal[16];
extern const byte climbr_title_rle[];
// link the pattern table into CHR ROM
//#link "chr_generic.s"
// link title screen palette and RLE nametable
//#link "climbr_title.s"
void fade_in() {
byte vb;
for (vb=0; vb<=4; vb++) {
// set virtual bright vaule
pal_bright(vb);
// wait for 4/60 sec
ppu_wait_frame();
ppu_wait_frame();
ppu_wait_frame();
ppu_wait_frame();
}
}
void show_title_screen(const byte* pal, const byte* rle) {
// disable rendering
ppu_off();
// set palette, virtual bright to 0 (total black)
pal_bg(pal);
pal_bright(0);
// unpack nametable into the VRAM
vram_adr(0x2000);
vram_unrle(rle);
// enable rendering
ppu_on_all();
// fade in from black
fade_in();
}
void main(void)
{
show_title_screen(climbr_title_pal, climbr_title_rle);
while(1);//do nothing, infinite loop
}

View File

@ -26,14 +26,16 @@ byte getchar(byte x, byte y) {
word addr = NTADR_A(x,y);
byte rd;
// wait for VBLANK to start
ppu_wait_nmi();
ppu_wait_frame();
// set vram address and read byte
vram_adr(addr);
vram_read(&rd, 1);
// scroll registers are corrupt
// fix by setting vram address
vram_adr(0x0);
return rd + 0x20;
return rd;
}
void cputcxy(byte x, byte y, char ch) {
putbytes(NTADR_A(x,y), &ch, 1);
}
@ -137,7 +139,7 @@ void move_player(Player* p) {
cputcxy(p->x, p->y, p->tail_attr);
p->x += DIR_X[p->dir];
p->y += DIR_Y[p->dir];
if (getchar(p->x, p->y) != ' ')
if (getchar(p->x, p->y) != 0)
p->collided = 1;
draw_player(p);
}

View File

@ -7,7 +7,7 @@ byte updptr = 0;
// add EOF marker to buffer (but don't increment pointer)
void cendbuf(void) {
updbuf[updptr] = NT_UPD_EOF;
VRAMBUF_SET(NT_UPD_EOF);
}
// clear vram buffer and place EOF marker

View File

@ -8,7 +8,7 @@
#define VBUFSIZE 128
// update buffer starts at $100 (stack page)
#define updbuf ((byte*)0x100)
#define updbuf ((byte* const)0x100)
// index to end of buffer
extern byte updptr;
@ -19,11 +19,15 @@ extern byte updptr;
VRAMBUF_ADD(addr);\
VRAMBUF_ADD(len);
// macro to add a single byte to buffer
#define VRAMBUF_ADD(b)\
// macro to set a single byte in buffer
#define VRAMBUF_SET(b)\
__A__ = (b);\
asm("ldy %v", updptr);\
asm("sta $100,y");\
asm("sta $100,y");
// macro to set a single byte to buffer, then increment
#define VRAMBUF_ADD(b)\
VRAMBUF_SET(b)\
asm("inc %v", updptr);
// add EOF marker to buffer (but don't increment pointer)

View File

@ -28,7 +28,7 @@ void scroll_demo() {
// wait for next frame
// and flush VRAM buffer
cflushnow();
// set scroll register
// set scroll (shadow) registers
scroll(x, y);
// update y variable
y += dy;

View File

@ -14,7 +14,7 @@ const JSNES_PRESETS = [
{id:'ex2.asm', name:'Scrolling Demo (ASM)'},
{id:'ex3.asm', name:'Sprite Demo (ASM)'},
{id:'ex4.asm', name:'Controller Demo (ASM)'},
{id:'neslib1.c', name:'Text'},
{id:'hello.c', name:'Text'},
{id:'scroll.c', name:'Scrolling'},
{id:'vrambuffer.c', name:'VRAM Buffer'},
{id:'sprites.c', name:'Sprites'},
@ -22,9 +22,10 @@ const JSNES_PRESETS = [
{id:'flicker.c', name:'Flickering Sprites'},
{id:'metacursor.c', name:'Controllers'},
{id:'metatrigger.c', name:'Trigger Mode + Vbright'},
{id:'neslib5.c', name:'RLE Unpack'},
{id:'rletitle.c', name:'Title Screen RLE'},
{id:'statusbar.c', name:'Split Status Bar'},
{id:'horizmask.c', name:'Offscreen Scrolling'},
{id:'attributes.c', name:'Attribute Table + Pixels'},
{id:'music.c', name:'Music Player'},
{id:'siegegame.c', name:'Siege Game'},
{id:'shoot2.c', name:'Solarian Game'},

View File

@ -843,6 +843,7 @@ function resetAndDebug() {
var lastBreakExpr = "c.PC == 0x6000";
function _breakExpression() {
console.log(platform.saveState());
var exprs = window.prompt("Enter break expression", lastBreakExpr);
if (exprs) {
var fn = new Function('c', 'return (' + exprs + ');').bind(platform);

2
tss

@ -1 +1 @@
Subproject commit 5b5ee67fc06956bc7dce51726e98812d2d897eaa
Subproject commit d630ddcb29d74a178cde043d74188fac35d6a21f