1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-29 08:31:03 +00:00

Fixed ASM error in fragment. Improved fragment synthesis. Working on lazynes (there seems to be an issue with waiting for vblank using lnSync(0) ).

This commit is contained in:
jespergravgaard 2020-07-05 21:58:53 +02:00
parent c10615b9b8
commit e25ef0e3f7
19 changed files with 221 additions and 373 deletions

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 1695362db1
//KICKC FRAGMENT CACHE 160b015f22
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 1695362db1
//KICKC FRAGMENT CACHE 160b015f22
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}
@ -6344,34 +6344,13 @@ tsx
txa
axs #-4
txs
//FRAGMENT pbuz1=_stackidxptr_vbuc1
tsx
lda STACK_BASE+{c1},x
sta {z1}
lda STACK_BASE+{c1}+1,x
sta {z1}+1
//FRAGMENT pbuc1_derefidx_vbuz1=_deref_pbuz2
ldx {z1}
ldy #0
lda ({z2}),y
sta {c1},x
//FRAGMENT _stackpushptr_=pbuc1
lda #>{c1}
pha
lda #<{c1}
pha
//FRAGMENT _stackpushbyte_=vbuc1
lda #{c1}
pha
//FRAGMENT _stackpullbyte_3
tsx
txa
axs #-3
txs
//FRAGMENT vbuz1=vbuz2_minus_1
ldx {z2}
dex
stx {z1}
//FRAGMENT _stackpushbyte_=vbuc1
lda #{c1}
pha
//FRAGMENT vbuaa=vbuz1_minus_1
lda {z1}
sec
@ -9067,21 +9046,6 @@ sta {z1}
lda #>{c1}
sbc {z1}+1
sta {z1}+1
//FRAGMENT pbuc1_derefidx_vbuaa=_deref_pbuz1
tax
ldy #0
lda ({z1}),y
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuxx=_deref_pbuz1
ldy #0
lda ({z1}),y
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuyy=_deref_pbuz1
tya
tax
ldy #0
lda ({z1}),y
sta {c1},x
//FRAGMENT pbsc1_derefidx_vbuz1=_deref_pbsc2
lda {c2}
ldy {z1}
@ -11501,180 +11465,6 @@ sta {z1}+1
asl $ff
rol {z1}
rol {z1}+1
//FRAGMENT vwuz1=pbuz2_bxor_vwuc1
lda #<{c1}
eor {z2}
sta {z1}
lda #>{c1}
eor {z2}+1
sta {z1}+1
//FRAGMENT pbuz1_derefidx_vbuz2=pbuz1_derefidx_vbuz2_bor_pbuc1_derefidx_vbuz3
ldy {z2}
lda ({z1}),y
ldy {z3}
ora {c1},y
ldy {z2}
sta ({z1}),y
//FRAGMENT vbuz1=vbuz1_bxor_pbuz2_derefidx_vbuz3
lda {z1}
ldy {z3}
eor ({z2}),y
sta {z1}
//FRAGMENT vbuz1=_neg_vbuz1
lda {z1}
eor #$ff
clc
adc #$01
sta {z1}
//FRAGMENT pbuz1_derefidx_vbuz2=pbuz1_derefidx_vbuz2_bor_pbuc1_derefidx_vbuaa
ldy {z2}
tax
lda ({z1}),y
ora {c1},x
ldy {z2}
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuz2=pbuz1_derefidx_vbuz2_bor_pbuc1_derefidx_vbuxx
ldy {z2}
lda ({z1}),y
ora {c1},x
ldy {z2}
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuz2=pbuz1_derefidx_vbuz2_bor_pbuc1_derefidx_vbuyy
tya
ldy {z2}
tax
lda ({z1}),y
ora {c1},x
ldy {z2}
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuxx=pbuz1_derefidx_vbuxx_bor_pbuc1_derefidx_vbuz2
txa
tay
lda ({z1}),y
ldy {z2}
stx $ff
ora {c1},y
ldy $ff
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuxx=pbuz1_derefidx_vbuxx_bor_pbuc1_derefidx_vbuaa
tay
txa
ldx {c1},y
tay
lda ({z1}),y
sty $ff
stx $ff
ora $ff
ldy $ff
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuxx=pbuz1_derefidx_vbuxx_bor_pbuc1_derefidx_vbuxx
txa
tay
lda ({z1}),y
stx $ff
ora {c1},x
ldy $ff
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuxx=pbuz1_derefidx_vbuxx_bor_pbuc1_derefidx_vbuyy
txa
ldx {c1},y
tay
lda ({z1}),y
sty $ff
stx $ff
ora $ff
ldy $ff
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuyy=pbuz1_derefidx_vbuyy_bor_pbuc1_derefidx_vbuz2
lda ({z1}),y
sty $ff
ldy {z2}
ora {c1},y
ldy $ff
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuyy=pbuz1_derefidx_vbuyy_bor_pbuc1_derefidx_vbuaa
tax
lda ({z1}),y
sty $ff
ora {c1},x
ldy $ff
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuyy=pbuz1_derefidx_vbuyy_bor_pbuc1_derefidx_vbuxx
lda ({z1}),y
sty $ff
ora {c1},x
ldy $ff
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuyy=pbuz1_derefidx_vbuyy_bor_pbuc1_derefidx_vbuyy
lda ({z1}),y
sty $ff
ora {c1},y
ldy $ff
sta ({z1}),y
//FRAGMENT vbuz1=vbuz1_bxor_pbuz2_derefidx_vbuaa
tay
lda {z1}
eor ({z2}),y
sta {z1}
//FRAGMENT vbuz1=vbuz1_bxor_pbuz2_derefidx_vbuxx
txa
tay
lda {z1}
eor ({z2}),y
sta {z1}
//FRAGMENT vbuz1=vbuz1_bxor_pbuz2_derefidx_vbuyy
lda {z1}
eor ({z2}),y
sta {z1}
//FRAGMENT vbuaa=vbuaa_bxor_pbuz1_derefidx_vbuz2
ldy {z2}
eor ({z1}),y
//FRAGMENT vbuaa=vbuaa_bxor_pbuz1_derefidx_vbuaa
tay
eor ({z1}),y
//FRAGMENT vbuaa=vbuaa_bxor_pbuz1_derefidx_vbuxx
stx $ff
ldy $ff
eor ({z1}),y
//FRAGMENT vbuaa=vbuaa_bxor_pbuz1_derefidx_vbuyy
eor ({z1}),y
//FRAGMENT vbuxx=vbuxx_bxor_pbuz1_derefidx_vbuz2
ldy {z2}
txa
eor ({z1}),y
tax
//FRAGMENT vbuxx=vbuxx_bxor_pbuz1_derefidx_vbuaa
tay
txa
eor ({z1}),y
tax
//FRAGMENT vbuxx=vbuxx_bxor_pbuz1_derefidx_vbuxx
txa
tay
eor ({z1}),y
tax
//FRAGMENT vbuxx=vbuxx_bxor_pbuz1_derefidx_vbuyy
txa
eor ({z1}),y
tax
//FRAGMENT vbuyy=_neg_vbuyy
dey
tya
eor #$ff
tay
//FRAGMENT vwuz1=pbuz1_bxor_vwuc1
lda #<{c1}
eor {z1}
sta {z1}
lda #>{c1}
eor {z1}+1
sta {z1}+1
//FRAGMENT vbsz1=vbsz2_plus_vbsc1
lax {z2}
axs #-[{c1}]
@ -12482,29 +12272,16 @@ ldy #{c2}
tax
lda ({z1}),y
sta {c1},x
//FRAGMENT pssz1=pssc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT pssz1=pssz1_plus_vbuc1
lda #{c1}
clc
adc {z1}
sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT pbuc1_derefidx_vbuaa=pbuz1_derefidx_vbuc2
ldy #{c2}
tax
lda ({z1}),y
sta {c1},x
//FRAGMENT _deref_qssc1=pssc2
lda #<{c2}
sta {c1}
lda #>{c2}
sta {c1}+1
//FRAGMENT pssz1=pssc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT pssc1_neq_pssz1_then_la1
lda {z1}+1
cmp #>{c1}
@ -13152,6 +12929,12 @@ lda #{c1}
sec
sbc {z1}
sta {z1}
//FRAGMENT vbuz1=_neg_vbuz1
lda {z1}
eor #$ff
clc
adc #$01
sta {z1}
//FRAGMENT vbsz1=vbsz2_ror_vbuz3
lda {z2}
ldy {z3}
@ -13203,6 +12986,11 @@ bne {la1}
tya
cmp #0
bne {la1}
//FRAGMENT vbuyy=_neg_vbuyy
dey
tya
eor #$ff
tay
//FRAGMENT vbsaa=vbsz1_ror_vbuz2
lda {z1}
ldy {z2}
@ -14735,6 +14523,14 @@ sta {z1}
lda #0
adc {z2}+1
sta {z1}+1
//FRAGMENT pssz1=pssz1_plus_vbuc1
lda #{c1}
clc
adc {z1}
sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT pssz1_lt_pssc1_then_la1
lda {z1}+1
cmp #>{c1}
@ -14806,6 +14602,11 @@ stx $fe
ldx {c1}+1
stx $ff
sta ($fe),y
//FRAGMENT pbuc1_derefidx_vbuaa=pbuz1_derefidx_vbuc2
ldy #{c2}
tax
lda ({z1}),y
sta {c1},x
//FRAGMENT pssz1_neq_pssc1_then_la1
lda {z1}+1
cmp #>{c1}
@ -14829,34 +14630,6 @@ sta {z1}
iny
lda ($fe),y
sta {z1}+1
//FRAGMENT pbuc1_derefidx_vbuz1=pbuc2_derefidx_(_deref_pbuz2)
ldx {z1}
ldy #0
lda ({z2}),y
tay
lda {c2},y
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuxx=pbuc2_derefidx_(_deref_pbuz1)
ldy #0
lda ({z1}),y
tay
lda {c2},y
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuaa=pbuc2_derefidx_(_deref_pbuz1)
tax
ldy #0
lda ({z1}),y
tay
lda {c2},y
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuyy=pbuc2_derefidx_(_deref_pbuz1)
tya
tax
ldy #0
lda ({z1}),y
tay
lda {c2},y
sta {c1},x
//FRAGMENT _deref_pwuc1=vbuc2
lda #0
sta {c1}+1

View File

@ -1,6 +1,6 @@
clc
adc {m1}
adc {m2}
sta {m1}
lda {m1}+1
lda {m2}+1
adc #0
sta {m1}+1

View File

@ -355,6 +355,7 @@ class AsmFragmentTemplateSynthesisRule {
String lvalC2 = ".*c2.*=.*";
String lvalDerefZM1 = ".*_deref_...[zm]1=.*";
String lvalDerefZM2 = ".*_deref_...[zm]2=.*";
String lvalDerefZM3 = ".*_deref_...[zm]3=.*";
String lvalDerefC1 = ".*_deref_...c1=.*";
String lvalDerefC2 = ".*_deref_...c2=.*";
String lvalDerefC3 = ".*_deref_...c3=.*";
@ -651,6 +652,18 @@ class AsmFragmentTemplateSynthesisRule {
synths.add(new AsmFragmentTemplateSynthesisRule("(.*z1.*)_deref_pb(.)z1(.*)", rvalAa+"|"+rvalYy+"|"+lvalDerefZM1, "ldy #0\n"+"lda ({z1}),y", "$1vb$2aa$3", null, null));
// Rewrite _deref_pb.z1_ to _vb.aa_ (if other Z1)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_deref_pb(.)z1(.*[zm]1.*)", rvalAa+"|"+rvalYy+"|"+ lvalDerefZM1, "ldy #0\n"+"lda ({z1}),y", "$1vb$2aa$3", null, null));
// Rewrite _deref_pb.z2_ to _vb.aa_ (if no other Z2s)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_deref_pb(.)z2(.*)", twoZM2+"|"+rvalAa+"|"+rvalYy+"|"+ lvalDerefZM2, "ldy #0\n"+"lda ({z2}),y", "$1vb$2aa$3", null, mapZM2));
// Rewrite _deref_pb.z2_ to _vb.aa_ (if other Z2)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*z2.*)_deref_pb(.)z2(.*)", rvalAa+"|"+rvalYy+"|"+lvalDerefZM2, "ldy #0\n"+"lda ({z2}),y", "$1vb$2aa$3", null, null));
// Rewrite _deref_pb.z2_ to _vb.aa_ (if other Z2)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_deref_pb(.)z2(.*[zm]2.*)", rvalAa+"|"+rvalYy+"|"+ lvalDerefZM2, "ldy #0\n"+"lda ({z2}),y", "$1vb$2aa$3", null, null));
// Rewrite _deref_pb.z3_ to _vb.aa_ (if no other Z3s)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_deref_pb(.)z3(.*)", twoZM3+"|"+rvalAa+"|"+rvalYy+"|"+ lvalDerefZM3, "ldy #0\n"+"lda ({z3}),y", "$1vb$2aa$3", null, mapZM3));
// Rewrite _deref_pb.z3_ to _vb.aa_ (if other Z3)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*z3.*)_deref_pb(.)z3(.*)", rvalAa+"|"+rvalYy+"|"+lvalDerefZM3, "ldy #0\n"+"lda ({z3}),y", "$1vb$2aa$3", null, null));
// Rewrite _deref_pb.z3_ to _vb.aa_ (if other Z3)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_deref_pb(.)z3(.*[zm]3.*)", rvalAa+"|"+rvalYy+"|"+ lvalDerefZM3, "ldy #0\n"+"lda ({z3}),y", "$1vb$2aa$3", null, null));
// Rewrite _deref_pb.m1_ to _vb.aa_ (if no other M1s)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_deref_pb(.)m1(.*)", twoZM1+"|"+rvalAa+"|"+rvalYy+"|"+lvalDerefZM1, "ldy {m1}\nsty $fe\nldy {m1}+1\nsty $ff\nldy #0\n"+"lda ($fe),y", "$1vb$2aa$3", null, mapZM1));

View File

@ -0,0 +1,40 @@
// lazyNES balloon demo
#pragma target(nes)
#include "lazynes.h"
int lnMain() {
static const ubyte bgColors[]={2,33};
static const ubyte sprPal0[]={33};
static const ubyte balloonData[]={
0,0,0,0, // balloon is build out of 6 sprites, 4 bytes define a sprite
8,0,1,0, // x-offset, y-offset, tile, palette + flags
0,8,2,0,
8,8,3,0,
0,16,4,0,
8,16,5,0,
128 // end of list marker (important!)
};
sword x=0, y=0;
// To avoid glitches, always write color palettes immediately after lnSync()!
lnSync(lfBlank); // blank screen to enable lnPush() usage
lnSync(lfBlank); // blank screen to enable lnPush() usage
lnPush(lnBackCol,2,bgColors); // set colors, always directly after lnSync()!
lnPush(lnSprPal0,1,sprPal0); // set sprite colors
while(1) {
ubyte j=lnGetPad(1); // query 1st joypad
if (0==j) { // automatic movement?
x+=1; if (x>=240) x=0;
y+=1; if (y>=240) y=0;
}
if (j&lfL) x-=1; else if (j&lfR) x+=1; // move left/right?
if (j&lfU) y-=1; else if (j&lfD) y+=1; // move up/down?
lnAddSpr(balloonData,x,y); // add meta sprite to display list
lnSync(0); // sync with vblank
}
return 0;
}

View File

@ -3,6 +3,7 @@
// Ported to KickC 2020 by Jesper Gravgaard
// Original Source VBCC alpha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip
#pragma target(nes)
#include "lazynes.h"
int lnMain() {

View File

@ -1,62 +0,0 @@
// lazyNES lazyhello demo
// Main file
// Ported to KickC 2020 by Jesper Gravgaard
// Original Source VBCC aplha 2 http://www.ibaug.de/vbcc/vbcc6502_2.zip
#pragma target(nes)
#include <nes.h>
#include <string.h>
#include "lazynes.c"
#include "balloon.c"
// RESET Called when the NES is reset, including when it is turned on.
void main() {
// Initialize NES after RESET
initNES();
// Clear the name table
ppuDataFill(PPU_NAME_TABLE_0, 0, 0x3c0);
// Fill the PPU attribute table
ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40);
// Enable screen rendering and vblank
enableVideoOutput();
// Execute main code
lnMain();
// Infinite loop
while(1) ;
}
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
interrupt(hardware_stack) void vblank() {
// DMA transfer the entire sprite buffer to the PPU
ppuSpriteBufferDmaTransfer(SPRITE_BUFFER);
// Set scroll
PPU->PPUSCROLL = 0;
PPU->PPUSCROLL = 0;
}
// Data (in PRG ROM)
#pragma data_seg(Data)
// Tile Set (in CHR ROM)
#pragma data_seg(Tiles)
export char TILES[] = kickasm(resource "example.chr", resource "sprites.chr") {{
.import binary "example.chr"
.import binary "sprites.chr"
}};
// Sprite Buffer (in GAME RAM)
// Will be transferred to the PPU via DMA during vblank
#pragma data_seg(GameRam)
struct SpriteData align(0x100) SPRITE_BUFFER[0x40];
// Interrupt Vectors (in PRG ROM)
#pragma data_seg(Vectors)
export void()* const VECTORS[] = {
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
&vblank,
// RESET Called when the NES is reset, including when it is turned on.
&main,
// IRQ Called when a BRK instruction is executed.
0
};

View File

@ -7,14 +7,85 @@
#include "lazynes.h"
#include <nes.h>
// Tile Set (in CHR ROM)
#pragma data_seg(Tiles)
export char TILES[] = kickasm(resource "example.chr", resource "sprites.chr") {{
.import binary "example.chr"
.import binary "sprites.chr"
}};
// Interrupt Vectors (in PRG ROM)
#pragma data_seg(Vectors)
export void()* const VECTORS[] = {
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
&vblank,
// RESET Called when the NES is reset, including when it is turned on.
&main,
// IRQ Called when a BRK instruction is executed.
0
};
// RESET Called when the NES is reset, including when it is turned on.
void main() {
// Initialize NES after RESET
initNES();
// Clear the name table
ppuDataFill(PPU_NAME_TABLE_0, 0, 0x3c0);
// Fill the PPU attribute table
ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40);
// move all sprites off the screen
for(char i=0;i!=0x40;i++)
SPRITE_BUFFER[i].y = 0xff;
// Enable screen rendering and vblank
// Set sprite tileset to upper - enable vblank NMI
PPU->PPUCTRL = 0b10001000;
// Enable sprite and tile rendering
PPU->PPUMASK = 0b00011110;
// Execute lazynes main code
lnMain();
// Infinite loop
while(1) ;
}
// Sprite Buffer (in GAME RAM)
// Will be transferred to the PPU via DMA during vblank
#pragma data_seg(GameRam)
struct SpriteData align(0x100) SPRITE_BUFFER[0x40];
// Data (in PRG ROM)
#pragma data_seg(Data)
// Index of the next SpriteData in SPRITE_BUFFER to write to in lnAddSpr()
volatile char add_sprite_idx;
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
interrupt(hardware_stack) void vblank() {
// DMA transfer the entire sprite buffer to the PPU
ppuSpriteBufferDmaTransfer(SPRITE_BUFFER);
// Set scroll
PPU->PPUSCROLL = 0;
PPU->PPUSCROLL = 0;
// move all sprites off the screen
//for(char i=0;i!=0x40;i++)
// SPRITE_BUFFER[i].y = 0xff;
// Reset the index of sprites to add
add_sprite_idx = 0;
}
// Wait for next vblank
// flags: 0, lfBlank or lfSplit (see below)
// result: Amount of frames since last sync [0..31], 128 is added on NTSC
//
ubyte lnSync(ubyte flags) {
// Enable video output if lfBlank not set
if(!(flags&lfBlank))
enableVideoOutput();
if(!(flags&lfBlank)) {
// Set sprite tileset to upper - enable vblank NMI
PPU->PPUCTRL = 0b10001000;
// Enable sprite and tile rendering
PPU->PPUMASK = 0b00011110;
}
// Wait for V-Blank
waitForVBlank();
// Disable video output if lfBlank set
@ -72,15 +143,23 @@ void lnPush(uword o, ubyte a, void* s) {
// p: Pointer to metasprite data
// x,y: Sprite coordinates
// result: New position offset in OAM after the meta sprite has been added
//
// TODO: ubyte lnAddSpr(void* p, sword x, sword y);
//
// remarks:
// - The format for the metasprite data is an array of unsigned bytes.
// - Four bytes per sprite: x-offset, y-offset, tile, attributes
// - The end of the list is marked by the value 128! (important!)
// - It's the same format that's used in oam_meta_spr() from Shiru's neslib
// remarks:
// - The format for the metasprite data is an array of unsigned bytes.
// - Four bytes per sprite: x-offset, y-offset, tile, attributes
// - The end of the list is marked by the value 128! (important!)
// - It's the same format that's used in oam_meta_spr() from Shiru's neslib
ubyte lnAddSpr(void* p, sword x, sword y) {
char* ptr = p;
while(*ptr!=128) {
SPRITE_BUFFER[add_sprite_idx].x = (char) (x+ptr[0]);
SPRITE_BUFFER[add_sprite_idx].y = (char) (y+ptr[1]);
SPRITE_BUFFER[add_sprite_idx].tile = ptr[2];
SPRITE_BUFFER[add_sprite_idx].attributes = ptr[3];
ptr+=4;
add_sprite_idx++;
}
return add_sprite_idx*4;
}
// Query joypad state
// port: Joypad port (1 or 2)
@ -94,10 +173,10 @@ ubyte lnGetPad(ubyte port) {
// advanced usage
//
__zp volatile ubyte
lnSpr0Wait, // delay until scroll registers will be set after a SPR0HIT
lnPPUCTRL, // current value of PPUCTRL register (will be written in NMI)
lnPPUMASK; // current value of PPUMASK register (will be written in NMI)
// TODO: __zp volatile ubyte
// TODO: lnSpr0Wait, // delay until scroll registers will be set after a SPR0HIT
// TODO: lnPPUCTRL, // current value of PPUCTRL register (will be written in NMI)
// TODO: lnPPUMASK; // current value of PPUMASK register (will be written in NMI)
//
// remark: The lazyNES NMI will write the PPUCTRL and PPUMASK registers,
// so don't write PPUCTRL and PPUMASK directly - use these two

View File

@ -10,6 +10,11 @@ typedef unsigned char ubyte;
typedef signed short sword;
typedef unsigned short uword;
// RESET Called when the NES is reset, including when it is turned on.
void main();
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
interrupt(hardware_stack) void vblank();
// Wait for next vblank
// flags: 0, lfBlank or lfSplit (see below)
// result: Amount of frames since last sync [0..31], 128 is added on NTSC
@ -74,7 +79,7 @@ enum {
// x,y: Sprite coordinates
// result: New position offset in OAM after the meta sprite has been added
//
// TODO: ubyte lnAddSpr(void* p, sword x, sword y);
ubyte lnAddSpr(void* p, sword x, sword y);
//
// remarks:
// - The format for the metasprite data is an array of unsigned bytes.
@ -94,10 +99,10 @@ enum { lfU=8, lfD=4, lfL=2, lfR=1, lfA=128, lfB=64, lfStart=16, lfSelect=32 };
// advanced usage
//
extern __zp volatile ubyte
lnSpr0Wait, // delay until scroll registers will be set after a SPR0HIT
lnPPUCTRL, // current value of PPUCTRL register (will be written in NMI)
lnPPUMASK; // current value of PPUMASK register (will be written in NMI)
// TODO: extern __zp volatile ubyte
// TODO: lnSpr0Wait, // delay until scroll registers will be set after a SPR0HIT
// TODO: lnPPUCTRL, // current value of PPUCTRL register (will be written in NMI)
// TODO: lnPPUMASK; // current value of PPUMASK register (will be written in NMI)
//
// remark: The lazyNES NMI will write the PPUCTRL and PPUMASK registers,
// so don't write PPUCTRL and PPUMASK directly - use these two

View File

@ -873,7 +873,7 @@ eorfill: {
iny
jmp __b3
}
// Get the absolute value of a u-bit unsigned number treated as a signed number.
// Get the absolute value of a 8-bit unsigned number treated as a signed number.
// abs_u8(byte register(A) u)
abs_u8: {
// u & 0x80

View File

@ -5577,7 +5577,7 @@ eorfill: {
jmp __b3
}
// abs_u8
// Get the absolute value of a u-bit unsigned number treated as a signed number.
// Get the absolute value of a 8-bit unsigned number treated as a signed number.
// abs_u8(byte zp($23) u)
abs_u8: {
.label __0 = $5c
@ -7450,7 +7450,7 @@ eorfill: {
jmp __b3
}
// abs_u8
// Get the absolute value of a u-bit unsigned number treated as a signed number.
// Get the absolute value of a 8-bit unsigned number treated as a signed number.
// abs_u8(byte register(A) u)
abs_u8: {
// [212] (byte~) abs_u8::$0 ← (byte) abs_u8::u#2 & (byte) $80 -- vbuxx=vbuaa_band_vbuc1
@ -9536,7 +9536,7 @@ eorfill: {
jmp __b3
}
// abs_u8
// Get the absolute value of a u-bit unsigned number treated as a signed number.
// Get the absolute value of a 8-bit unsigned number treated as a signed number.
// abs_u8(byte register(A) u)
abs_u8: {
// u & 0x80

View File

@ -398,10 +398,10 @@ print: {
// print::@2
__b2:
// [11] *((const nomodify byte*) SCREEN + (byte) idx#19) ← *((byte*) print::msg#5) -- pbuc1_derefidx_vbuz1=_deref_pbuz2
ldx.z idx
ldy #0
lda (msg),y
sta SCREEN,x
ldy.z idx
sta SCREEN,y
// [12] (byte) idx#7 ← ++ (byte) idx#19 -- vbuz1=_inc_vbuz1
inc.z idx
// [13] (byte*) print::msg#4 ← ++ (byte*) print::msg#5 -- pbuz1=_inc_pbuz1

View File

@ -315,10 +315,10 @@ main: {
print: {
.label ptr = 2
// [10] *((const nomodify byte*) SCREEN + (byte) idx#13) ← *((byte*)(void*) print::ptr#3) -- pbuc1_derefidx_vbuz1=_deref_pbuz2
ldx.z idx
ldy #0
lda (ptr),y
sta SCREEN,x
ldy.z idx
sta SCREEN,y
// [11] (byte) idx#14 ← ++ (byte) idx#13 -- vbuz1=_inc_vbuz1
inc.z idx
jmp __breturn

View File

@ -309,10 +309,10 @@ main: {
print: {
.label ptr = 2
// [10] *((const nomodify byte*) SCREEN + (byte) idx#13) ← *((byte*)(void*) print::ptr#3) -- pbuc1_derefidx_vbuz1=_deref_pbuz2
ldx.z idx
ldy #0
lda (ptr),y
sta SCREEN,x
ldy.z idx
sta SCREEN,y
// [11] (byte) idx#14 ← ++ (byte) idx#13 -- vbuz1=_inc_vbuz1
inc.z idx
jmp __breturn

View File

@ -38,10 +38,10 @@ print: {
rts
__b2:
// SCREEN[idx++] = *(str++)
ldx.z idx
ldy #0
lda (str),y
sta SCREEN,x
ldy.z idx
sta SCREEN,y
// SCREEN[idx++] = *(str++);
inc.z idx
inc.z str

View File

@ -332,10 +332,10 @@ print: {
// print::@2
__b2:
// [10] *((const nomodify byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) -- pbuc1_derefidx_vbuz1=_deref_pbuz2
ldx.z idx
ldy #0
lda (str),y
sta SCREEN,x
ldy.z idx
sta SCREEN,y
// [11] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
inc.z idx
// [12] (byte*) print::str#1 ← ++ (byte*) print::str#2 -- pbuz1=_inc_pbuz1
@ -424,8 +424,7 @@ Statement [6] (byte) print::spacing#0 ← stackidx(byte,(const byte) print::OFFS
Statement [8] if((byte) 0!=*((byte*) print::str#2)) goto print::@2 [ idx print::spacing#0 print::str#2 ] ( main:3::print:20 [ idx print::spacing#0 print::str#2 ] { } main:3::print:24 [ idx print::spacing#0 print::str#2 ] { } ) always clobbers reg byte a reg byte y
Removing always clobbered register reg byte a as potential for zp[1]:6 [ print::spacing#0 ]
Removing always clobbered register reg byte y as potential for zp[1]:6 [ print::spacing#0 ]
Statement [10] *((const nomodify byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [ idx print::spacing#0 print::str#2 ] ( main:3::print:20 [ idx print::spacing#0 print::str#2 ] { } main:3::print:24 [ idx print::spacing#0 print::str#2 ] { } ) always clobbers reg byte a reg byte x reg byte y
Removing always clobbered register reg byte x as potential for zp[1]:6 [ print::spacing#0 ]
Statement [10] *((const nomodify byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [ idx print::spacing#0 print::str#2 ] ( main:3::print:20 [ idx print::spacing#0 print::str#2 ] { } main:3::print:24 [ idx print::spacing#0 print::str#2 ] { } ) always clobbers reg byte a reg byte y
Statement [15] *((const nomodify byte*) SCREEN + (byte) idx) ← (byte) ' ' [ idx print::spacing#0 print::str#1 print::c#2 ] ( main:3::print:20 [ idx print::spacing#0 print::str#1 print::c#2 ] { } main:3::print:24 [ idx print::spacing#0 print::str#1 print::c#2 ] { } ) always clobbers reg byte a reg byte y
Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::c#2 print::c#1 ]
Removing always clobbered register reg byte y as potential for zp[1]:4 [ print::c#2 print::c#1 ]
@ -439,7 +438,7 @@ Statement [1] (byte) idx ← (byte) 0 [ idx ] ( [ idx ] { } ) always clobbers
Statement [5] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET_STACK_STR) [ idx print::str#0 ] ( main:3::print:20 [ idx print::str#0 ] { } main:3::print:24 [ idx print::str#0 ] { } ) always clobbers reg byte a reg byte x
Statement [6] (byte) print::spacing#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_SPACING) [ idx print::str#0 print::spacing#0 ] ( main:3::print:20 [ idx print::str#0 print::spacing#0 ] { } main:3::print:24 [ idx print::str#0 print::spacing#0 ] { } ) always clobbers reg byte a reg byte x
Statement [8] if((byte) 0!=*((byte*) print::str#2)) goto print::@2 [ idx print::spacing#0 print::str#2 ] ( main:3::print:20 [ idx print::spacing#0 print::str#2 ] { } main:3::print:24 [ idx print::spacing#0 print::str#2 ] { } ) always clobbers reg byte a reg byte y
Statement [10] *((const nomodify byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [ idx print::spacing#0 print::str#2 ] ( main:3::print:20 [ idx print::spacing#0 print::str#2 ] { } main:3::print:24 [ idx print::spacing#0 print::str#2 ] { } ) always clobbers reg byte a reg byte x reg byte y
Statement [10] *((const nomodify byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [ idx print::spacing#0 print::str#2 ] ( main:3::print:20 [ idx print::spacing#0 print::str#2 ] { } main:3::print:24 [ idx print::spacing#0 print::str#2 ] { } ) always clobbers reg byte a reg byte y
Statement [15] *((const nomodify byte*) SCREEN + (byte) idx) ← (byte) ' ' [ idx print::spacing#0 print::str#1 print::c#2 ] ( main:3::print:20 [ idx print::spacing#0 print::str#1 print::c#2 ] { } main:3::print:24 [ idx print::spacing#0 print::str#1 print::c#2 ] { } ) always clobbers reg byte a reg byte y
Statement [18] stackpush(byte*) ← (const byte*) main::str [ idx ] ( main:3 [ idx ] { } ) always clobbers reg byte a
Statement [19] stackpush(byte) ← (byte) 1 [ idx ] ( main:3 [ idx ] { } ) always clobbers reg byte a
@ -450,7 +449,7 @@ Statement sideeffect stackpullbytes((number) 3) always clobbers reg byte a reg b
Potential registers zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] : zp[2]:2 ,
Potential registers zp[1]:4 [ print::c#2 print::c#1 ] : zp[1]:4 , reg byte x ,
Potential registers zp[1]:5 [ idx ] : zp[1]:5 ,
Potential registers zp[1]:6 [ print::spacing#0 ] : zp[1]:6 ,
Potential registers zp[1]:6 [ print::spacing#0 ] : zp[1]:6 , reg byte x ,
REGISTER UPLIFT SCOPES
Uplift Scope [print] 27,502.75: zp[1]:4 [ print::c#2 print::c#1 ] 5,210.92: zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] 918.36: zp[1]:6 [ print::spacing#0 ]
@ -539,10 +538,10 @@ print: {
// print::@2
__b2:
// [10] *((const nomodify byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) -- pbuc1_derefidx_vbuz1=_deref_pbuz2
ldx.z idx
ldy #0
lda (str),y
sta SCREEN,x
ldy.z idx
sta SCREEN,y
// [11] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
inc.z idx
// [12] (byte*) print::str#1 ← ++ (byte*) print::str#2 -- pbuz1=_inc_pbuz1
@ -746,10 +745,10 @@ print: {
__b2:
// SCREEN[idx++] = *(str++)
// [10] *((const nomodify byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) -- pbuc1_derefidx_vbuz1=_deref_pbuz2
ldx.z idx
ldy #0
lda (str),y
sta SCREEN,x
ldy.z idx
sta SCREEN,y
// SCREEN[idx++] = *(str++);
// [11] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
inc.z idx

View File

@ -407,12 +407,12 @@ print_person: {
.label i = 5
.label person = 2
// [6] *((const nomodify byte*) SCREEN + (byte) idx#14) ← *((const byte*) DIGIT + *((byte*)(struct Person*) print_person::person#2)) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_(_deref_pbuz2)
ldx.z idx_2
ldy #0
lda (person),y
tay
lda DIGIT,y
sta SCREEN,x
ldy.z idx_2
sta SCREEN,y
// [7] (byte) idx#3 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz2
ldy.z idx_2
iny

View File

@ -380,12 +380,12 @@ print_person: {
.label i = 5
.label person = 2
// [6] *((const nomodify byte*) SCREEN + (byte) idx#14) ← *((const byte*) DIGIT + *((byte*)(struct Person*) print_person::person#2)) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_(_deref_pbuz2)
ldx.z idx_2
ldy #0
lda (person),y
tay
lda DIGIT,y
sta SCREEN,x
ldy.z idx_2
sta SCREEN,y
// [7] (byte) idx#3 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz2
ldy.z idx_2
iny

View File

@ -382,10 +382,10 @@ main: {
// main::@2
__b2:
// [9] *((const nomodify byte*) main::SCREEN + (byte) main::idx#4) ← *((byte*)(struct Point*) main::points#5) -- pbuc1_derefidx_vbuz1=_deref_pbuz2
ldx.z idx_2
ldy #0
lda (points_1),y
sta SCREEN,x
ldy.z idx_2
sta SCREEN,y
// [10] (byte) main::idx#1 ← ++ (byte) main::idx#4 -- vbuz1=_inc_vbuz2
ldy.z idx_2
iny