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

Added nes-dxycp.c

This commit is contained in:
jespergravgaard 2020-06-07 03:56:27 +02:00
parent b53392f5fd
commit 7928b2920a
15 changed files with 4782 additions and 40 deletions

View File

@ -538,3 +538,219 @@ sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT vbuz1=vbuz2_rol_2
lda {z2}
asl
asl
sta {z1}
//FRAGMENT pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2
ldy {z2}
lda {c2},y
ldy {z1}
sta {c1},y
//FRAGMENT vbuz1=pbuc1_derefidx_vbuz2_plus_vbuc2
lda #{c2}
ldy {z2}
clc
adc {c1},y
sta {z1}
//FRAGMENT pbuc1_derefidx_vbuz1=vbuz2
lda {z2}
ldy {z1}
sta {c1},y
//FRAGMENT vbuz1=vbuz1_minus_vbuc1
lda {z1}
sec
sbc #{c1}
sta {z1}
//FRAGMENT vbuaa=vbuz1_rol_2
lda {z1}
asl
asl
//FRAGMENT vbuxx=vbuz1_rol_2
lda {z1}
asl
asl
tax
//FRAGMENT vbuyy=vbuz1_rol_2
lda {z1}
asl
asl
tay
//FRAGMENT vbuz1=vbuaa_rol_2
asl
asl
sta {z1}
//FRAGMENT vbuaa=vbuaa_rol_2
asl
asl
//FRAGMENT vbuxx=vbuaa_rol_2
asl
asl
tax
//FRAGMENT vbuyy=vbuaa_rol_2
asl
asl
tay
//FRAGMENT vbuz1=vbuxx_rol_2
txa
asl
asl
sta {z1}
//FRAGMENT vbuaa=vbuxx_rol_2
txa
asl
asl
//FRAGMENT vbuxx=vbuxx_rol_2
txa
asl
asl
tax
//FRAGMENT vbuyy=vbuxx_rol_2
txa
asl
asl
tay
//FRAGMENT vbuz1=vbuyy_rol_2
tya
asl
asl
sta {z1}
//FRAGMENT vbuaa=vbuyy_rol_2
tya
asl
asl
//FRAGMENT vbuxx=vbuyy_rol_2
tya
asl
asl
tax
//FRAGMENT vbuyy=vbuyy_rol_2
tya
asl
asl
tay
//FRAGMENT pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuz1
ldy {z1}
lda {c2},y
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuz1
ldx {z1}
lda {c2},x
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuxx
lda {c2},x
ldy {z1}
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx
lda {c2},x
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx
lda {c2},x
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuyy
lda {c2},y
ldy {z1}
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy
lda {c2},y
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuyy
lda {c2},y
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuaa=pbuc2_derefidx_vbuz1
ldx {z1}
tay
lda {c2},x
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuaa=pbuc2_derefidx_vbuxx
tay
lda {c2},x
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuaa=pbuc2_derefidx_vbuyy
tax
lda {c2},y
sta {c1},x
//FRAGMENT vbuaa=pbuc1_derefidx_vbuz1_plus_vbuc2
lda #{c2}
ldy {z1}
clc
adc {c1},y
//FRAGMENT vbuxx=pbuc1_derefidx_vbuz1_plus_vbuc2
lda #{c2}
ldx {z1}
clc
adc {c1},x
tax
//FRAGMENT vbuyy=pbuc1_derefidx_vbuz1_plus_vbuc2
lda #{c2}
ldy {z1}
clc
adc {c1},y
tay
//FRAGMENT vbuz1=pbuc1_derefidx_vbuxx_plus_vbuc2
lda #{c2}
clc
adc {c1},x
sta {z1}
//FRAGMENT vbuaa=pbuc1_derefidx_vbuxx_plus_vbuc2
lda #{c2}
clc
adc {c1},x
//FRAGMENT vbuxx=pbuc1_derefidx_vbuxx_plus_vbuc2
lda #{c2}
clc
adc {c1},x
tax
//FRAGMENT vbuyy=pbuc1_derefidx_vbuxx_plus_vbuc2
lda #{c2}
clc
adc {c1},x
tay
//FRAGMENT vbuz1=pbuc1_derefidx_vbuyy_plus_vbuc2
lda #{c2}
clc
adc {c1},y
sta {z1}
//FRAGMENT vbuaa=pbuc1_derefidx_vbuyy_plus_vbuc2
lda #{c2}
clc
adc {c1},y
//FRAGMENT vbuxx=pbuc1_derefidx_vbuyy_plus_vbuc2
lda #{c2}
clc
adc {c1},y
tax
//FRAGMENT vbuyy=pbuc1_derefidx_vbuyy_plus_vbuc2
lda #{c2}
clc
adc {c1},y
tay
//FRAGMENT pbuc1_derefidx_vbuz1=vbuaa
ldy {z1}
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuz1=vbuxx
ldy {z1}
txa
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuz1=vbuyy
tya
ldy {z1}
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuxx=vbuz1
lda {z1}
sta {c1},x
//FRAGMENT vbuxx=vbuxx_minus_vbuc1
txa
sec
sbc #{c1}
tax
//FRAGMENT vbuyy=vbuyy_minus_vbuc1
tya
sec
sbc #{c1}
tay
//FRAGMENT vbuyy=vbuz1
ldy {z1}
//FRAGMENT pbuc1_derefidx_vbuyy=vbuaa
sta {c1},y

View File

@ -0,0 +1,8 @@
// Commodore 128 Registers and Memory
// https://archive.org/details/C128_Programmers_Reference_Guide_1986_Bamtam_Books/page/n299/mode/2up
#ifndef __C128__
#error "Target platform must be C128"
#endif
#include <mos6526.h>
#include <mos6569.h>
#include <mos6581.h>

View File

@ -117,8 +117,8 @@ void cscroll() {
char* line1 = CONIO_SCREEN_TEXT;
char* line2 = CONIO_SCREEN_TEXT+CONIO_WIDTH;
for(char y=0;y<CONIO_HEIGHT-1;y++) {
ppuDataFetch(scroll_buffer, line2, CONIO_WIDTH);
ppuDataTransfer(line1, scroll_buffer, CONIO_WIDTH);
ppuDataFetch(conio_cscroll_buffer, line2, CONIO_WIDTH);
ppuDataTransfer(line1, conio_cscroll_buffer, CONIO_WIDTH);
line1 += CONIO_WIDTH;
line2 += CONIO_WIDTH;
}

View File

@ -62,6 +62,11 @@ public class TestPrograms {
compileAndCompare("minus-precedence-problem.c");
}
@Test
public void testNesDxycp() throws IOException, URISyntaxException {
compileAndCompare("examples/nes-dxycp/nes-dxycp.c");
}
@Test
public void testNesConio() throws IOException, URISyntaxException {
compileAndCompare("examples/nes-conio/nes-conio.c");

View File

@ -6,7 +6,6 @@
#pragma data_seg(GameRam)
char num_buffer[11];
char scroll_buffer[32];
#pragma data_seg(Data)

View File

@ -0,0 +1,100 @@
// NES DXYCP using sprites
#pragma target(nes)
#include <nes.h>
#include <string.h>
// RESET Called when the NES is reset, including when it is turned on.
void main() {
// Initialize NES after RESET
initNES();
// Transfer the palette
ppuDataTransfer(PPU_PALETTE, PALETTE, sizeof(PALETTE));
// Fill the PPU attribute table
ppuDataFill(PPU_NAME_TABLE_0, '*', 32*30);
ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40);
// Initialize Sprite Buffer with the SPRITE data
for(char s=0;s<0x40;s++) {
SPRITE_BUFFER[s] = { 0, MESSAGE[s], 0b00000010, 0 };
}
// Enable screen rendering and vblank
enableVideoOutput();
// Infinite loop
while(1) {
}
}
// Index into the Y sine
volatile char y_sin_idx = 0;
// Index into the X sine
volatile char x_sin_idx = 73;
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
interrupt(hardware_stack) void vblank() {
// Set scroll
PPU->PPUSCROLL = 0;
PPU->PPUSCROLL = 0;
// DMA transfer the entire sprite buffer to the PPU
ppuSpriteBufferDmaTransfer(SPRITE_BUFFER);
// Update sprite positions
char y_idx = y_sin_idx++;
char x_idx = x_sin_idx++;
for(char s=0;s<0x40;s++) {
SPRITE_BUFFER[s].y = SINTABLE[y_idx];
SPRITE_BUFFER[s].x = SINTABLE[x_idx]+8;
y_idx += 4;
x_idx -= 7;
}
}
// Data (in PRG ROM)
#pragma data_seg(Data)
// The DXYCP message 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
char MESSAGE[0x40] = "rex-of-camelot-presents-a-dxycp-on-nintendo-entertainment-system"z;
// Color Palette
char PALETTE[0x20] = {
// Background palettes
0x01, 0x21, 0x0f, 0x30, // C64 colors
0x01, 0x21, 0x0f, 0x30, // C64 colors
0x01, 0x21, 0x0f, 0x30, // C64 colors
0x01, 0x21, 0x0f, 0x30, // C64 colors
// Sprite palettes (selected by the attribute bits 0-1 of the sprites)
0x01, 0x0f, 0x30, 0x08, // Goomba upper colors
0x01, 0x0f, 0x18, 0x08, // Goomba lower colors
0x01, 0x30, 0x37, 0x1a, // Luigi-like colors
0x0f, 0x0f, 0x0f, 0x0f // All black
};
// Sinus Table (0-239)
const char SINTABLE[0x100] = kickasm {{
.fill $100, round(115.5+107.5*sin(2*PI*i/256))
}};
// Tile Set (in CHR ROM) - A C64 charset from http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/
#pragma data_seg(Tiles)
export char TILES[] = kickasm(resource "characters.901225-01.bin") {{
.var filechargen = LoadBinary("characters.901225-01.bin")
.for(var c=0; c<256; c++) {
// Plane 0
.fill 8, filechargen.get(c*8+i)
// Plane 1
.fill 8, 0
}
}};
// 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[0x100];
// 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

@ -409,13 +409,13 @@ cscroll: {
// }
rts
__b2:
// ppuDataFetch(scroll_buffer, line2, CONIO_WIDTH)
// ppuDataFetch(conio_cscroll_buffer, line2, CONIO_WIDTH)
lda.z line2
sta.z ppuDataFetch.ppuData
lda.z line2+1
sta.z ppuDataFetch.ppuData+1
jsr ppuDataFetch
// ppuDataTransfer(line1, scroll_buffer, CONIO_WIDTH)
// ppuDataTransfer(line1, conio_cscroll_buffer, CONIO_WIDTH)
lda.z line1
sta.z ppuDataTransfer.ppuData
lda.z line1+1
@ -424,9 +424,9 @@ cscroll: {
sta.z ppuDataTransfer.size
lda #>$20
sta.z ppuDataTransfer.size+1
lda #<scroll_buffer
lda #<conio_cscroll_buffer
sta.z ppuDataTransfer.cpuData
lda #>scroll_buffer
lda #>conio_cscroll_buffer
sta.z ppuDataTransfer.cpuData+1
jsr ppuDataTransfer
// line1 += CONIO_WIDTH
@ -509,7 +509,7 @@ ppuDataTransfer: {
// ppuDataFetch(void* zp($19) ppuData)
ppuDataFetch: {
.const size = $20
.label cpuData = scroll_buffer
.label cpuData = conio_cscroll_buffer
// Fetch from PPU to CPU
.label cpuDst = 7
.label i = 5
@ -947,6 +947,9 @@ readJoy1: {
inx
jmp __b1
}
.segment GameRam
// Buffer used for scrolling the NES screen
conio_cscroll_buffer: .fill $20, 0
.segment Data
// The digits used for numbers
DIGITS: .text "0123456789abcdef"
@ -954,7 +957,6 @@ readJoy1: {
RADIX_HEXADECIMAL_VALUES_CHAR: .byte $10
.segment GameRam
num_buffer: .fill $b, 0
scroll_buffer: .fill $20, 0
.segment Data
// Color Palette
PALETTE: .byte 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $f, $30, 8, 1, $f, $18, 8, 1, $30, $37, $1a, $f, $f, $f, $f

View File

@ -244,7 +244,7 @@ cscroll::@5: scope:[cscroll] from cscroll::@4
(void()) ppuDataTransfer((nomodify void*) ppuDataTransfer::ppuData , (nomodify void*) ppuDataTransfer::cpuData , (word) ppuDataTransfer::size)
ppuDataTransfer: scope:[ppuDataTransfer] from cscroll::@4 main::@6
[110] (word) ppuDataTransfer::size#3 ← phi( cscroll::@4/(byte) $20 main::@6/(byte) $20*(const byte) SIZEOF_BYTE )
[110] (nomodify void*) ppuDataTransfer::cpuData#2 ← phi( cscroll::@4/(void*)(const byte*) scroll_buffer main::@6/(void*)(const byte*) PALETTE )
[110] (nomodify void*) ppuDataTransfer::cpuData#2 ← phi( cscroll::@4/(void*)(const byte*) conio_cscroll_buffer main::@6/(void*)(const byte*) PALETTE )
[110] (nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0 ← phi( cscroll::@4/(nomodify void*) ppuDataTransfer::ppuData#0 main::@6/(void*)(const nomodify byte*) PPU_PALETTE )
to:ppuDataTransfer::ppuDataPrepare1
ppuDataTransfer::ppuDataPrepare1: scope:[ppuDataTransfer] from ppuDataTransfer

View File

@ -1,5 +1,3 @@
Resolved forward reference scroll_buffer to (const byte*) scroll_buffer
Resolved forward reference scroll_buffer to (const byte*) scroll_buffer
Resolved forward reference PALETTE to (const byte*) PALETTE
Resolved forward reference PALETTE to (const byte*) PALETTE
Resolved forward reference x_scroll to (volatile byte) x_scroll
@ -431,7 +429,7 @@ cscroll::@5: scope:[cscroll] from cscroll::@4
(byte) cscroll::y#5 ← phi( cscroll::@4/(byte) cscroll::y#2 )
(byte*) cscroll::line1#4 ← phi( cscroll::@4/(byte*) cscroll::line1#5 )
(byte*) cscroll::line2#2 ← phi( cscroll::@4/(byte*) cscroll::line2#4 )
(nomodify void*) ppuDataFetch::cpuData#0 ← (void*)(const byte*) scroll_buffer
(nomodify void*) ppuDataFetch::cpuData#0 ← (void*)(const byte*) conio_cscroll_buffer
(nomodify void*) ppuDataFetch::ppuData#0 ← (void*)(byte*) cscroll::line2#2
(word) ppuDataFetch::size#0 ← (number) $20
call ppuDataFetch
@ -441,7 +439,7 @@ cscroll::@8: scope:[cscroll] from cscroll::@5
(byte*) cscroll::line2#5 ← phi( cscroll::@5/(byte*) cscroll::line2#2 )
(byte*) cscroll::line1#2 ← phi( cscroll::@5/(byte*) cscroll::line1#4 )
(nomodify void*) ppuDataTransfer::ppuData#0 ← (void*)(byte*) cscroll::line1#2
(nomodify void*) ppuDataTransfer::cpuData#0 ← (void*)(const byte*) scroll_buffer
(nomodify void*) ppuDataTransfer::cpuData#0 ← (void*)(const byte*) conio_cscroll_buffer
(word) ppuDataTransfer::size#0 ← (number) $20
call ppuDataTransfer
to:cscroll::@9
@ -1137,6 +1135,7 @@ SYMBOL TABLE SSA
(void()) clrscr()
(label) clrscr::@1
(label) clrscr::@return
(const byte*) conio_cscroll_buffer[(number) $20] = { fill( $20, 0) }
(byte) conio_cursor_x loadstore
(byte) conio_cursor_y loadstore
(byte*) conio_line_text loadstore
@ -1674,7 +1673,6 @@ SYMBOL TABLE SSA
(byte) readJoy1::return#2
(byte) readJoy1::return#3
(byte) readJoy1::return#4
(const byte*) scroll_buffer[(number) $20] = { fill( $20, 0) }
(void()) uctoa((byte) uctoa::value , (byte*) uctoa::buffer , (byte) uctoa::radix)
(bool~) uctoa::$0
(bool~) uctoa::$1
@ -2443,9 +2441,9 @@ Constant (const byte*) cscroll::line2#0 = CONIO_SCREEN_TEXT+$20
Constant (const byte) cscroll::y#0 = 0
Constant (const byte) gotoxy::x#1 = 0
Constant (const byte) gotoxy::y#1 = 0
Constant (const nomodify void*) ppuDataFetch::cpuData#0 = (void*)scroll_buffer
Constant (const nomodify void*) ppuDataFetch::cpuData#0 = (void*)conio_cscroll_buffer
Constant (const word) ppuDataFetch::size#0 = $20
Constant (const nomodify void*) ppuDataTransfer::cpuData#0 = (void*)scroll_buffer
Constant (const nomodify void*) ppuDataTransfer::cpuData#0 = (void*)conio_cscroll_buffer
Constant (const word) ppuDataTransfer::size#0 = $20
Constant (const nomodify void*) ppuDataFill::ppuData#1 = (void*)CONIO_SCREEN_TEXT+(word)$1e*$20-$20
Constant (const byte) ppuDataFill::val#1 = ' '
@ -2761,7 +2759,7 @@ Constant inlined readJoy1::joy#0 = (byte) 0
Constant inlined ppuDataTransfer::cpuData#1 = (void*)(const byte*) PALETTE
Constant inlined cscroll::y#0 = (byte) 0
Constant inlined cscroll::line2#0 = (const nomodify byte*) PPU_NAME_TABLE_0+(byte) $20
Constant inlined ppuDataTransfer::cpuData#0 = (void*)(const byte*) scroll_buffer
Constant inlined ppuDataTransfer::cpuData#0 = (void*)(const byte*) conio_cscroll_buffer
Constant inlined ppuDataTransfer::ppuData#1 = (void*)(const nomodify byte*) PPU_PALETTE
Constant inlined cputcxy::c#3 = (byte) 'i'
Constant inlined cputcxy::c#2 = (byte) 'i'
@ -3260,7 +3258,7 @@ cscroll::@5: scope:[cscroll] from cscroll::@4
(void()) ppuDataTransfer((nomodify void*) ppuDataTransfer::ppuData , (nomodify void*) ppuDataTransfer::cpuData , (word) ppuDataTransfer::size)
ppuDataTransfer: scope:[ppuDataTransfer] from cscroll::@4 main::@6
[110] (word) ppuDataTransfer::size#3 ← phi( cscroll::@4/(byte) $20 main::@6/(byte) $20*(const byte) SIZEOF_BYTE )
[110] (nomodify void*) ppuDataTransfer::cpuData#2 ← phi( cscroll::@4/(void*)(const byte*) scroll_buffer main::@6/(void*)(const byte*) PALETTE )
[110] (nomodify void*) ppuDataTransfer::cpuData#2 ← phi( cscroll::@4/(void*)(const byte*) conio_cscroll_buffer main::@6/(void*)(const byte*) PALETTE )
[110] (nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0 ← phi( cscroll::@4/(nomodify void*) ppuDataTransfer::ppuData#0 main::@6/(void*)(const nomodify byte*) PPU_PALETTE )
to:ppuDataTransfer::ppuDataPrepare1
ppuDataTransfer::ppuDataPrepare1: scope:[ppuDataTransfer] from ppuDataTransfer
@ -4805,10 +4803,10 @@ cscroll: {
sta.z ppuDataTransfer.size
lda #>$20
sta.z ppuDataTransfer.size+1
// [110] phi (nomodify void*) ppuDataTransfer::cpuData#2 = (void*)(const byte*) scroll_buffer [phi:cscroll::@4->ppuDataTransfer#1] -- pvoz1=pvoc1
lda #<scroll_buffer
// [110] phi (nomodify void*) ppuDataTransfer::cpuData#2 = (void*)(const byte*) conio_cscroll_buffer [phi:cscroll::@4->ppuDataTransfer#1] -- pvoz1=pvoc1
lda #<conio_cscroll_buffer
sta.z ppuDataTransfer.cpuData
lda #>scroll_buffer
lda #>conio_cscroll_buffer
sta.z ppuDataTransfer.cpuData+1
// [110] phi (nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0 = (nomodify void*) ppuDataTransfer::ppuData#0 [phi:cscroll::@4->ppuDataTransfer#2] -- register_copy
jsr ppuDataTransfer
@ -4943,7 +4941,7 @@ ppuDataTransfer: {
// ppuDataFetch(void* zp($3e) ppuData)
ppuDataFetch: {
.const size = $20
.label cpuData = scroll_buffer
.label cpuData = conio_cscroll_buffer
.label ppuDataPrepare1___0 = $43
.label ppuDataPrepare1___1 = $44
.label ppuDataRead1_return = $45
@ -5740,6 +5738,9 @@ readJoy1: {
jmp __b1
}
// File Data
.segment GameRam
// Buffer used for scrolling the NES screen
conio_cscroll_buffer: .fill $20, 0
.segment Data
// The digits used for numbers
DIGITS: .text "0123456789abcdef"
@ -5747,7 +5748,6 @@ readJoy1: {
RADIX_HEXADECIMAL_VALUES_CHAR: .byte $10
.segment GameRam
num_buffer: .fill $b, 0
scroll_buffer: .fill $20, 0
.segment Data
// Color Palette
PALETTE: .byte 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $f, $30, 8, 1, $f, $18, 8, 1, $30, $37, $1a, $f, $f, $f, $f
@ -6845,10 +6845,10 @@ cscroll: {
sta.z ppuDataTransfer.size
lda #>$20
sta.z ppuDataTransfer.size+1
// [110] phi (nomodify void*) ppuDataTransfer::cpuData#2 = (void*)(const byte*) scroll_buffer [phi:cscroll::@4->ppuDataTransfer#1] -- pvoz1=pvoc1
lda #<scroll_buffer
// [110] phi (nomodify void*) ppuDataTransfer::cpuData#2 = (void*)(const byte*) conio_cscroll_buffer [phi:cscroll::@4->ppuDataTransfer#1] -- pvoz1=pvoc1
lda #<conio_cscroll_buffer
sta.z ppuDataTransfer.cpuData
lda #>scroll_buffer
lda #>conio_cscroll_buffer
sta.z ppuDataTransfer.cpuData+1
// [110] phi (nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0 = (nomodify void*) ppuDataTransfer::ppuData#0 [phi:cscroll::@4->ppuDataTransfer#2] -- register_copy
jsr ppuDataTransfer
@ -6970,7 +6970,7 @@ ppuDataTransfer: {
// ppuDataFetch(void* zp($19) ppuData)
ppuDataFetch: {
.const size = $20
.label cpuData = scroll_buffer
.label cpuData = conio_cscroll_buffer
// Fetch from PPU to CPU
.label cpuDst = 7
.label i = 5
@ -7662,6 +7662,9 @@ readJoy1: {
jmp __b1
}
// File Data
.segment GameRam
// Buffer used for scrolling the NES screen
conio_cscroll_buffer: .fill $20, 0
.segment Data
// The digits used for numbers
DIGITS: .text "0123456789abcdef"
@ -7669,7 +7672,6 @@ readJoy1: {
RADIX_HEXADECIMAL_VALUES_CHAR: .byte $10
.segment GameRam
num_buffer: .fill $b, 0
scroll_buffer: .fill $20, 0
.segment Data
// Color Palette
PALETTE: .byte 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $f, $30, 8, 1, $f, $18, 8, 1, $30, $37, $1a, $f, $f, $f, $f
@ -8061,6 +8063,7 @@ FINAL SYMBOL TABLE
(void()) clrscr()
(label) clrscr::@1
(label) clrscr::@return
(const byte*) conio_cscroll_buffer[(number) $20] = { fill( $20, 0) }
(byte) conio_cursor_x loadstore zp[1]:17 4375315.90625
(byte) conio_cursor_y loadstore zp[1]:18 6.5306328755102046E7
(byte*) conio_line_text loadstore zp[2]:19 4.9111335755555555E7
@ -8209,7 +8212,7 @@ FINAL SYMBOL TABLE
(label) ppuDataFetch::@3
(label) ppuDataFetch::@return
(nomodify void*) ppuDataFetch::cpuData
(const nomodify void*) ppuDataFetch::cpuData#0 cpuData = (void*)(const byte*) scroll_buffer
(const nomodify void*) ppuDataFetch::cpuData#0 cpuData = (void*)(const byte*) conio_cscroll_buffer
(byte*) ppuDataFetch::cpuDst
(byte*) ppuDataFetch::cpuDst#1 cpuDst zp[2]:7 1.0E17
(byte*) ppuDataFetch::cpuDst#2 cpuDst zp[2]:7 7.5E16
@ -8309,7 +8312,6 @@ FINAL SYMBOL TABLE
(byte) readJoy1::joy#2 reg byte a 51.0
(byte) readJoy1::return
(byte) readJoy1::return#2 reg byte a 4.0
(const byte*) scroll_buffer[(number) $20] = { fill( $20, 0) }
(void()) uctoa((byte) uctoa::value , (byte*) uctoa::buffer , (byte) uctoa::radix)
(label) uctoa::@1
(label) uctoa::@2
@ -9068,7 +9070,7 @@ cscroll: {
rts
// cscroll::@2
__b2:
// ppuDataFetch(scroll_buffer, line2, CONIO_WIDTH)
// ppuDataFetch(conio_cscroll_buffer, line2, CONIO_WIDTH)
// [103] (nomodify void*) ppuDataFetch::ppuData#0 ← (void*)(byte*) cscroll::line2#2 -- pvoz1=pvoz2
lda.z line2
sta.z ppuDataFetch.ppuData
@ -9078,7 +9080,7 @@ cscroll: {
// [123] phi from cscroll::@2 to ppuDataFetch [phi:cscroll::@2->ppuDataFetch]
jsr ppuDataFetch
// cscroll::@4
// ppuDataTransfer(line1, scroll_buffer, CONIO_WIDTH)
// ppuDataTransfer(line1, conio_cscroll_buffer, CONIO_WIDTH)
// [105] (nomodify void*) ppuDataTransfer::ppuData#0 ← (void*)(byte*) cscroll::line1#2 -- pvoz1=pvoz2
lda.z line1
sta.z ppuDataTransfer.ppuData
@ -9091,10 +9093,10 @@ cscroll: {
sta.z ppuDataTransfer.size
lda #>$20
sta.z ppuDataTransfer.size+1
// [110] phi (nomodify void*) ppuDataTransfer::cpuData#2 = (void*)(const byte*) scroll_buffer [phi:cscroll::@4->ppuDataTransfer#1] -- pvoz1=pvoc1
lda #<scroll_buffer
// [110] phi (nomodify void*) ppuDataTransfer::cpuData#2 = (void*)(const byte*) conio_cscroll_buffer [phi:cscroll::@4->ppuDataTransfer#1] -- pvoz1=pvoc1
lda #<conio_cscroll_buffer
sta.z ppuDataTransfer.cpuData
lda #>scroll_buffer
lda #>conio_cscroll_buffer
sta.z ppuDataTransfer.cpuData+1
// [110] phi (nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0 = (nomodify void*) ppuDataTransfer::ppuData#0 [phi:cscroll::@4->ppuDataTransfer#2] -- register_copy
jsr ppuDataTransfer
@ -9212,7 +9214,7 @@ ppuDataTransfer: {
// ppuDataFetch(void* zp($19) ppuData)
ppuDataFetch: {
.const size = $20
.label cpuData = scroll_buffer
.label cpuData = conio_cscroll_buffer
// Fetch from PPU to CPU
.label cpuDst = 7
.label i = 5
@ -9882,6 +9884,9 @@ readJoy1: {
jmp __b1
}
// File Data
.segment GameRam
// Buffer used for scrolling the NES screen
conio_cscroll_buffer: .fill $20, 0
.segment Data
// The digits used for numbers
DIGITS: .text "0123456789abcdef"
@ -9889,7 +9894,6 @@ readJoy1: {
RADIX_HEXADECIMAL_VALUES_CHAR: .byte $10
.segment GameRam
num_buffer: .fill $b, 0
scroll_buffer: .fill $20, 0
.segment Data
// Color Palette
PALETTE: .byte 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $f, $30, 8, 1, $f, $18, 8, 1, $30, $37, $1a, $f, $f, $f, $f

View File

@ -80,6 +80,7 @@
(void()) clrscr()
(label) clrscr::@1
(label) clrscr::@return
(const byte*) conio_cscroll_buffer[(number) $20] = { fill( $20, 0) }
(byte) conio_cursor_x loadstore zp[1]:17 4375315.90625
(byte) conio_cursor_y loadstore zp[1]:18 6.5306328755102046E7
(byte*) conio_line_text loadstore zp[2]:19 4.9111335755555555E7
@ -228,7 +229,7 @@
(label) ppuDataFetch::@3
(label) ppuDataFetch::@return
(nomodify void*) ppuDataFetch::cpuData
(const nomodify void*) ppuDataFetch::cpuData#0 cpuData = (void*)(const byte*) scroll_buffer
(const nomodify void*) ppuDataFetch::cpuData#0 cpuData = (void*)(const byte*) conio_cscroll_buffer
(byte*) ppuDataFetch::cpuDst
(byte*) ppuDataFetch::cpuDst#1 cpuDst zp[2]:7 1.0E17
(byte*) ppuDataFetch::cpuDst#2 cpuDst zp[2]:7 7.5E16
@ -328,7 +329,6 @@
(byte) readJoy1::joy#2 reg byte a 51.0
(byte) readJoy1::return
(byte) readJoy1::return#2 reg byte a 4.0
(const byte*) scroll_buffer[(number) $20] = { fill( $20, 0) }
(void()) uctoa((byte) uctoa::value , (byte*) uctoa::buffer , (byte) uctoa::radix)
(label) uctoa::@1
(label) uctoa::@2

View File

@ -0,0 +1,401 @@
// NES DXYCP using sprites
// Nintendo Entertainment System (NES
// https://en.wikipedia.org/wiki/Nintendo_Entertainment_System_(Model_NES-101)
// https://github.com/gregkrsak/first_nes
// Ricoh 2C02 - NES Picture Processing Unit (PPU)
// Ricoh RP2C02 (NTSC version) / RP2C07 (PAL version),
// https://en.wikipedia.org/wiki/Picture_Processing_Unit
// https://wiki.nesdev.com/w/index.php/PPU_registers
// http://nesdev.com/2C02%20technical%20reference.TXT
// Based on: https://github.com/gregkrsak/first_nes written by Greg M. Krsak, 2018.
// Nintendo Entertainment System (NES) ROM
// https://sadistech.com/nesromtool/romdoc.html
// https://forums.nesdev.com/viewtopic.php?f=2&t=9896
// https://github.com/gregkrsak/first_nes
.file [name="nes-dxycp.nes", type="bin", segments="NesRom"]
.file [name="nes-dxycp.nes_hdr", type="bin", segments="Header"]
.file [name="nes-dxycp.nes_prg", type="bin", segments="ProgramRom"]
.file [name="nes-dxycp.nes_chr", type="bin", segments="CharacterRom"]
.segmentdef Header [ start=$0000, min=$0000, max=$000f, fill ]
.segmentdef Tiles [ start=$0000, min=$0000, max=$1fff, fill ]
.segmentdef Code [ start=$c000, min=$c000, max=$fff9 ]
.segmentdef Data [ startAfter="Code", min=$c000, max=$fff9 ]
.segmentdef Vectors [ start=$fffa, min=$fffa, max=$ffff ]
.segmentdef GameRam [start=$200,max=$7ff, virtual]
.segmentdef ProgramRom [ segments="Code, Data, Vectors" ]
.segmentdef CharacterRom [ segments="Tiles" ]
.segmentdef NesRom
.segment NesRom
.segmentout [ segments="Header" ]
.segmentout [ segments="ProgramRom" ]
.segmentout [ segments="CharacterRom" ]
.segment Header
.text @"NES\$1a"
.byte $01 // 1x 16KB ROM (PRG)
.byte $01 // 1x 8KB VROM (CHR)
.byte %00000001 // Mapper nibble 0000 == No mapping (a simple 16KB PRG + 8KB CHR game)
// Mirroring nibble 0001 == Vertical mirroring only
.segment Code
.const OFFSET_STRUCT_SPRITEDATA_TILE = 1
.const OFFSET_STRUCT_SPRITEDATA_ATTRIBUTES = 2
.const OFFSET_STRUCT_SPRITEDATA_X = 3
.const OFFSET_STRUCT_RICOH_2A03_DMC_FREQ = $10
.const OFFSET_STRUCT_RICOH_2C02_PPUMASK = 1
.const OFFSET_STRUCT_RICOH_2C02_PPUSTATUS = 2
.const OFFSET_STRUCT_RICOH_2C02_OAMADDR = 3
.const OFFSET_STRUCT_RICOH_2A03_OAMDMA = $14
.const OFFSET_STRUCT_RICOH_2C02_PPUADDR = 6
.const OFFSET_STRUCT_RICOH_2C02_PPUDATA = 7
.const OFFSET_STRUCT_RICOH_2C02_PPUSCROLL = 5
.const SIZEOF_BYTE = 1
// $2000-$23bf $03c0 Name table 0
.label PPU_NAME_TABLE_0 = $2000
// $23c0-$23ff $0040 Attribute table 0
.label PPU_ATTRIBUTE_TABLE_0 = $23c0
// $3000-$3eff $0f00 Mirrors of $2000-$2eff
// $3f00-$3f1f $0020 Palette RAM indexes
.label PPU_PALETTE = $3f00
// PPU Status Register for reading in ASM
.label PPU_PPUSTATUS = $2002
// APU Frame Counter
// generates low-frequency clocks for the channels and an optional 60 Hz interrupt.
// https://wiki.nesdev.com/w/index.php/APU_Frame_Counter
// ------+-----+---------------------------------------------------------------
// $4017 | W | FR_COUNTER Frame Counter Set mode and interrupt
// ------+-----+---------------------------------------------------------------
// | 7 | Sequencer mode: 0 selects 4-step sequence, 1 selects 5-step sequence
// | 6 | Interrupt inhibit flag. If set, the frame interrupt flag is cleared, otherwise it is unaffected.
// ------+-----+---------------------------------------------------------------
// Side effects After 3 or 4 CPU clock cycles*, the timer is reset.
// If the mode flag is set, then both "quarter frame" and "half frame" signals are also generated.
.label FR_COUNTER = $4017
// Pointer to the start of RAM memory
.label MEMORY = 0
// NES Picture Processing Unit (PPU)
.label PPU = $2000
// NES CPU and audion processing unit (APU)
.label APU = $4000
.label y_sin_idx = $a
.label x_sin_idx = $b
__bbegin:
// y_sin_idx = 0
// Index into the Y sine
lda #0
sta.z y_sin_idx
// x_sin_idx = 73
// Index into the X sine
lda #$49
sta.z x_sin_idx
jsr main
rts
.segment Code
// RESET Called when the NES is reset, including when it is turned on.
main: {
// asm
cld
ldx #$ff
txs
// PPU->PPUCTRL = 0
lda #0
sta PPU
// PPU->PPUMASK = 0
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUMASK
// *FR_COUNTER = 0b01000000
lda #$40
sta FR_COUNTER
// APU->DMC_FREQ = 0b01000000
sta APU+OFFSET_STRUCT_RICOH_2A03_DMC_FREQ
// asm
lda PPU_PPUSTATUS
initNES1_waitForVBlank1:
// PPU->PPUSTATUS&0x80
lda #$80
and PPU+OFFSET_STRUCT_RICOH_2C02_PPUSTATUS
// while(!(PPU->PPUSTATUS&0x80))
cmp #0
beq initNES1_waitForVBlank1
ldx #0
initNES1___b1:
// (MEMORY+0x000)[i] = 0
lda #0
sta MEMORY,x
// (MEMORY+0x100)[i] = 0
sta MEMORY+$100,x
// (MEMORY+0x200)[i] = 0
sta MEMORY+$200,x
// (MEMORY+0x300)[i] = 0
sta MEMORY+$300,x
// (MEMORY+0x400)[i] = 0
sta MEMORY+$400,x
// (MEMORY+0x500)[i] = 0
sta MEMORY+$500,x
// (MEMORY+0x600)[i] = 0
sta MEMORY+$600,x
// (MEMORY+0x700)[i] = 0
sta MEMORY+$700,x
// while (++i)
inx
cpx #0
bne initNES1___b1
initNES1_waitForVBlank2:
// PPU->PPUSTATUS&0x80
lda #$80
and PPU+OFFSET_STRUCT_RICOH_2C02_PPUSTATUS
// while(!(PPU->PPUSTATUS&0x80))
cmp #0
beq initNES1_waitForVBlank2
// asm
lda PPU_PPUSTATUS
// ppuDataTransfer(PPU_PALETTE, PALETTE, sizeof(PALETTE))
// Transfer the palette
jsr ppuDataTransfer
// ppuDataFill(PPU_NAME_TABLE_0, '*', 32*30)
// Fill the PPU attribute table
ldx #'*'
lda #<$20*$1e
sta.z ppuDataFill.size
lda #>$20*$1e
sta.z ppuDataFill.size+1
lda #<PPU_NAME_TABLE_0
sta.z ppuDataFill.ppuDataPrepare1_ppuData
lda #>PPU_NAME_TABLE_0
sta.z ppuDataFill.ppuDataPrepare1_ppuData+1
jsr ppuDataFill
// ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40)
ldx #0
lda #<$40
sta.z ppuDataFill.size
lda #>$40
sta.z ppuDataFill.size+1
lda #<PPU_ATTRIBUTE_TABLE_0
sta.z ppuDataFill.ppuDataPrepare1_ppuData
lda #>PPU_ATTRIBUTE_TABLE_0
sta.z ppuDataFill.ppuDataPrepare1_ppuData+1
jsr ppuDataFill
ldx #0
// Initialize Sprite Buffer with the SPRITE data
__b1:
// for(char s=0;s<0x40;s++)
cpx #$40
bcc __b2
// PPU->PPUCTRL = 0b10000000
lda #$80
sta PPU
// PPU->PPUMASK = 0b00011110
lda #$1e
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUMASK
__b3:
// Infinite loop
jmp __b3
__b2:
// SPRITE_BUFFER[s] = { 0, MESSAGE[s], 0b00000010, 0 }
txa
asl
asl
tay
lda #0
sta SPRITE_BUFFER,y
lda MESSAGE,x
sta SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_TILE,y
lda #2
sta SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_ATTRIBUTES,y
lda #0
sta SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X,y
// for(char s=0;s<0x40;s++)
inx
jmp __b1
}
// Fill a number of bytes in the PPU memory
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
// ppuDataFill(byte register(X) val, word zp(6) size)
ppuDataFill: {
.label ppuDataPrepare1_ppuData = 4
.label i = 2
.label size = 6
// >ppuData
lda.z ppuDataPrepare1_ppuData+1
// PPU->PPUADDR = >ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// <ppuData
lda.z ppuDataPrepare1_ppuData
// PPU->PPUADDR = <ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
lda #<0
sta.z i
sta.z i+1
// Transfer to PPU
__b1:
// for(unsigned int i=0;i<size;i++)
lda.z i+1
cmp.z size+1
bcc ppuDataPut1
bne !+
lda.z i
cmp.z size
bcc ppuDataPut1
!:
// }
rts
ppuDataPut1:
// PPU->PPUDATA = val
stx PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// for(unsigned int i=0;i<size;i++)
inc.z i
bne !+
inc.z i+1
!:
jmp __b1
}
// Transfer a number of bytes from the CPU memory to the PPU memory
// - cpuData : Pointer to the CPU memory (RAM of ROM)
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
ppuDataTransfer: {
.const size = $20*SIZEOF_BYTE
.label ppuData = PPU_PALETTE
.label cpuData = PALETTE
// Transfer to PPU
.label cpuSrc = 6
.label i = 4
// PPU->PPUADDR = >ppuData
lda #>ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// PPU->PPUADDR = <ppuData
lda #0
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
lda #<cpuData
sta.z cpuSrc
lda #>cpuData
sta.z cpuSrc+1
lda #<0
sta.z i
sta.z i+1
__b1:
// for(unsigned int i=0;i<size;i++)
lda.z i+1
cmp #>size
bcc __b2
bne !+
lda.z i
cmp #<size
bcc __b2
!:
// }
rts
__b2:
// ppuDataPut(*cpuSrc++)
ldy #0
lda (cpuSrc),y
// PPU->PPUDATA = val
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// ppuDataPut(*cpuSrc++);
inc.z cpuSrc
bne !+
inc.z cpuSrc+1
!:
// for(unsigned int i=0;i<size;i++)
inc.z i
bne !+
inc.z i+1
!:
jmp __b1
}
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
vblank: {
.label __4 = $c
.label y_idx = 8
.label x_idx = 9
pha
txa
pha
tya
pha
// PPU->PPUSCROLL = 0
// Set scroll
lda #0
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
// PPU->OAMADDR = 0
sta PPU+OFFSET_STRUCT_RICOH_2C02_OAMADDR
// APU->OAMDMA = >spriteBuffer
lda #>SPRITE_BUFFER
sta APU+OFFSET_STRUCT_RICOH_2A03_OAMDMA
// y_idx = y_sin_idx++
// Update sprite positions
lda.z y_sin_idx
sta.z y_idx
inc.z y_sin_idx
// x_idx = x_sin_idx++
lda.z x_sin_idx
sta.z x_idx
inc.z x_sin_idx
ldx #0
__b1:
// for(char s=0;s<0x40;s++)
cpx #$40
bcc __b2
// }
pla
tay
pla
tax
pla
rti
__b2:
// SPRITE_BUFFER[s].y = SINTABLE[y_idx]
txa
asl
asl
sta.z __4
ldy.z y_idx
lda SINTABLE,y
ldy.z __4
sta SPRITE_BUFFER,y
// SINTABLE[x_idx]+8
lda #8
ldy.z x_idx
clc
adc SINTABLE,y
// SPRITE_BUFFER[s].x = SINTABLE[x_idx]+8
ldy.z __4
sta SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X,y
// y_idx += 4
lda #4
clc
adc.z y_idx
sta.z y_idx
// x_idx -= 7
lda.z x_idx
sec
sbc #7
sta.z x_idx
// for(char s=0;s<0x40;s++)
inx
jmp __b1
}
.segment Data
// The DXYCP message 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
MESSAGE: .text "rex-of-camelot-presents-a-dxycp-on-nintendo-entertainment-system"
// Color Palette
PALETTE: .byte 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $f, $30, 8, 1, $f, $18, 8, 1, $30, $37, $1a, $f, $f, $f, $f
// Sinus Table (0-239)
SINTABLE:
.fill $100, round(115.5+107.5*sin(2*PI*i/256))
.segment Tiles
TILES:
.var filechargen = LoadBinary("characters.901225-01.bin")
.for(var c=0; c<256; c++) {
// Plane 0
.fill 8, filechargen.get(c*8+i)
// Plane 1
.fill 8, 0
}
.segment GameRam
.align $100
SPRITE_BUFFER: .fill 4*$100, 0
.segment Vectors
VECTORS: .word vblank, main, 0

View File

@ -0,0 +1,180 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] (volatile byte) y_sin_idx ← (byte) 0
[2] (volatile byte) x_sin_idx ← (byte) $49
to:@2
@2: scope:[] from @1
[3] phi()
[4] call main
to:@end
@end: scope:[] from @2
[5] phi()
(void()) main()
main: scope:[main] from @2
[6] phi()
to:main::initNES1
main::initNES1: scope:[main] from main
asm { cld ldx#$ff txs }
to:main::initNES1_disableVideoOutput1
main::initNES1_disableVideoOutput1: scope:[main] from main::initNES1
[8] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) 0
[9] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUMASK) ← (byte) 0
to:main::initNES1_disableAudioOutput1
main::initNES1_disableAudioOutput1: scope:[main] from main::initNES1_disableVideoOutput1
[10] *((const nomodify byte*) FR_COUNTER) ← (byte) $40
[11] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_DMC_FREQ) ← (byte) $40
to:main::initNES1_clearVBlankFlag1
main::initNES1_clearVBlankFlag1: scope:[main] from main::initNES1_disableAudioOutput1
asm { ldaPPU_PPUSTATUS }
to:main::initNES1_waitForVBlank1
main::initNES1_waitForVBlank1: scope:[main] from main::initNES1_clearVBlankFlag1
[13] phi()
to:main::initNES1_waitForVBlank1_@1
main::initNES1_waitForVBlank1_@1: scope:[main] from main::initNES1_waitForVBlank1 main::initNES1_waitForVBlank1_@1
[14] (byte~) main::initNES1_waitForVBlank1_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[15] if((byte) 0==(byte~) main::initNES1_waitForVBlank1_$0) goto main::initNES1_waitForVBlank1_@1
to:main::initNES1_@1
main::initNES1_@1: scope:[main] from main::initNES1_@1 main::initNES1_waitForVBlank1_@1
[16] (byte) main::initNES1_i#2 ← phi( main::initNES1_@1/(byte) main::initNES1_i#1 main::initNES1_waitForVBlank1_@1/(byte) 0 )
[17] *((const nomodify byte*) MEMORY + (byte) main::initNES1_i#2) ← (byte) 0
[18] *((const nomodify byte*) MEMORY+(word) $100 + (byte) main::initNES1_i#2) ← (byte) 0
[19] *((const nomodify byte*) MEMORY+(word) $200 + (byte) main::initNES1_i#2) ← (byte) 0
[20] *((const nomodify byte*) MEMORY+(word) $300 + (byte) main::initNES1_i#2) ← (byte) 0
[21] *((const nomodify byte*) MEMORY+(word) $400 + (byte) main::initNES1_i#2) ← (byte) 0
[22] *((const nomodify byte*) MEMORY+(word) $500 + (byte) main::initNES1_i#2) ← (byte) 0
[23] *((const nomodify byte*) MEMORY+(word) $600 + (byte) main::initNES1_i#2) ← (byte) 0
[24] *((const nomodify byte*) MEMORY+(word) $700 + (byte) main::initNES1_i#2) ← (byte) 0
[25] (byte) main::initNES1_i#1 ← ++ (byte) main::initNES1_i#2
[26] if((byte) 0!=(byte) main::initNES1_i#1) goto main::initNES1_@1
to:main::initNES1_waitForVBlank2
main::initNES1_waitForVBlank2: scope:[main] from main::initNES1_@1
[27] phi()
to:main::initNES1_waitForVBlank2_@1
main::initNES1_waitForVBlank2_@1: scope:[main] from main::initNES1_waitForVBlank2 main::initNES1_waitForVBlank2_@1
[28] (byte~) main::initNES1_waitForVBlank2_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[29] if((byte) 0==(byte~) main::initNES1_waitForVBlank2_$0) goto main::initNES1_waitForVBlank2_@1
to:main::initNES1_@7
main::initNES1_@7: scope:[main] from main::initNES1_waitForVBlank2_@1
asm { ldaPPU_PPUSTATUS }
to:main::@4
main::@4: scope:[main] from main::initNES1_@7
[31] phi()
[32] call ppuDataTransfer
to:main::@5
main::@5: scope:[main] from main::@4
[33] phi()
[34] call ppuDataFill
to:main::@6
main::@6: scope:[main] from main::@5
[35] phi()
[36] call ppuDataFill
to:main::@1
main::@1: scope:[main] from main::@2 main::@6
[37] (byte) main::s#2 ← phi( main::@2/(byte) main::s#1 main::@6/(byte) 0 )
[38] if((byte) main::s#2<(byte) $40) goto main::@2
to:main::enableVideoOutput1
main::enableVideoOutput1: scope:[main] from main::@1
[39] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) $80
[40] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUMASK) ← (byte) $1e
to:main::@3
main::@3: scope:[main] from main::@3 main::enableVideoOutput1
[41] phi()
to:main::@3
main::@2: scope:[main] from main::@1
[42] (byte~) main::$7 ← (byte) main::s#2 << (byte) 2
[43] *((byte*)(const struct SpriteData*) SPRITE_BUFFER + (byte~) main::$7) ← (byte) 0
[44] *((byte*)(const struct SpriteData*) SPRITE_BUFFER+(const byte) OFFSET_STRUCT_SPRITEDATA_TILE + (byte~) main::$7) ← *((const byte*) MESSAGE + (byte) main::s#2)
[45] *((byte*)(const struct SpriteData*) SPRITE_BUFFER+(const byte) OFFSET_STRUCT_SPRITEDATA_ATTRIBUTES + (byte~) main::$7) ← (byte) 2
[46] *((byte*)(const struct SpriteData*) SPRITE_BUFFER+(const byte) OFFSET_STRUCT_SPRITEDATA_X + (byte~) main::$7) ← (byte) 0
[47] (byte) main::s#1 ← ++ (byte) main::s#2
to:main::@1
(void()) ppuDataFill((nomodify void*) ppuDataFill::ppuData , (byte) ppuDataFill::val , (word) ppuDataFill::size)
ppuDataFill: scope:[ppuDataFill] from main::@5 main::@6
[48] (byte) ppuDataFill::val#4 ← phi( main::@5/(byte) '*' main::@6/(byte) 0 )
[48] (word) ppuDataFill::size#3 ← phi( main::@5/(word)(number) $20*(number) $1e main::@6/(byte) $40 )
[48] (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0 ← phi( main::@5/(void*)(const nomodify byte*) PPU_NAME_TABLE_0 main::@6/(void*)(const nomodify byte*) PPU_ATTRIBUTE_TABLE_0 )
to:ppuDataFill::ppuDataPrepare1
ppuDataFill::ppuDataPrepare1: scope:[ppuDataFill] from ppuDataFill
[49] (byte~) ppuDataFill::ppuDataPrepare1_$0 ← > (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0
[50] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataFill::ppuDataPrepare1_$0
[51] (byte~) ppuDataFill::ppuDataPrepare1_$1 ← < (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0
[52] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataFill::ppuDataPrepare1_$1
to:ppuDataFill::@1
ppuDataFill::@1: scope:[ppuDataFill] from ppuDataFill::@2 ppuDataFill::ppuDataPrepare1
[53] (word) ppuDataFill::i#2 ← phi( ppuDataFill::ppuDataPrepare1/(word) 0 ppuDataFill::@2/(word) ppuDataFill::i#1 )
[54] if((word) ppuDataFill::i#2<(word) ppuDataFill::size#3) goto ppuDataFill::ppuDataPut1
to:ppuDataFill::@return
ppuDataFill::@return: scope:[ppuDataFill] from ppuDataFill::@1
[55] return
to:@return
ppuDataFill::ppuDataPut1: scope:[ppuDataFill] from ppuDataFill::@1
[56] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataFill::val#4
to:ppuDataFill::@2
ppuDataFill::@2: scope:[ppuDataFill] from ppuDataFill::ppuDataPut1
[57] (word) ppuDataFill::i#1 ← ++ (word) ppuDataFill::i#2
to:ppuDataFill::@1
(void()) ppuDataTransfer((nomodify void*) ppuDataTransfer::ppuData , (nomodify void*) ppuDataTransfer::cpuData , (word) ppuDataTransfer::size)
ppuDataTransfer: scope:[ppuDataTransfer] from main::@4
[58] phi()
to:ppuDataTransfer::ppuDataPrepare1
ppuDataTransfer::ppuDataPrepare1: scope:[ppuDataTransfer] from ppuDataTransfer
[59] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← >(const nomodify void*) ppuDataTransfer::ppuData#0
[60] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte) 0
to:ppuDataTransfer::@1
ppuDataTransfer::@1: scope:[ppuDataTransfer] from ppuDataTransfer::@3 ppuDataTransfer::ppuDataPrepare1
[61] (byte*) ppuDataTransfer::cpuSrc#2 ← phi( ppuDataTransfer::ppuDataPrepare1/(byte*)(const nomodify void*) ppuDataTransfer::cpuData#0 ppuDataTransfer::@3/(byte*) ppuDataTransfer::cpuSrc#1 )
[61] (word) ppuDataTransfer::i#2 ← phi( ppuDataTransfer::ppuDataPrepare1/(word) 0 ppuDataTransfer::@3/(word) ppuDataTransfer::i#1 )
[62] if((word) ppuDataTransfer::i#2<(const word) ppuDataTransfer::size#0) goto ppuDataTransfer::@2
to:ppuDataTransfer::@return
ppuDataTransfer::@return: scope:[ppuDataTransfer] from ppuDataTransfer::@1
[63] return
to:@return
ppuDataTransfer::@2: scope:[ppuDataTransfer] from ppuDataTransfer::@1
[64] (byte) ppuDataTransfer::ppuDataPut1_val#0 ← *((byte*) ppuDataTransfer::cpuSrc#2)
to:ppuDataTransfer::ppuDataPut1
ppuDataTransfer::ppuDataPut1: scope:[ppuDataTransfer] from ppuDataTransfer::@2
[65] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataTransfer::ppuDataPut1_val#0
to:ppuDataTransfer::@3
ppuDataTransfer::@3: scope:[ppuDataTransfer] from ppuDataTransfer::ppuDataPut1
[66] (byte*) ppuDataTransfer::cpuSrc#1 ← ++ (byte*) ppuDataTransfer::cpuSrc#2
[67] (word) ppuDataTransfer::i#1 ← ++ (word) ppuDataTransfer::i#2
to:ppuDataTransfer::@1
interrupt(HARDWARE_STACK)(void()) vblank()
vblank: scope:[vblank] from
[68] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL) ← (byte) 0
[69] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL) ← (byte) 0
to:vblank::ppuSpriteBufferDmaTransfer1
vblank::ppuSpriteBufferDmaTransfer1: scope:[vblank] from vblank
[70] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_OAMADDR) ← (byte) 0
[71] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_OAMDMA) ← >(const struct SpriteData*) SPRITE_BUFFER
to:vblank::@3
vblank::@3: scope:[vblank] from vblank::ppuSpriteBufferDmaTransfer1
[72] (byte) vblank::y_idx#0 ← (volatile byte) y_sin_idx
[73] (volatile byte) y_sin_idx ← ++ (volatile byte) y_sin_idx
[74] (byte) vblank::x_idx#0 ← (volatile byte) x_sin_idx
[75] (volatile byte) x_sin_idx ← ++ (volatile byte) x_sin_idx
to:vblank::@1
vblank::@1: scope:[vblank] from vblank::@2 vblank::@3
[76] (byte) vblank::x_idx#2 ← phi( vblank::@2/(byte) vblank::x_idx#1 vblank::@3/(byte) vblank::x_idx#0 )
[76] (byte) vblank::y_idx#2 ← phi( vblank::@2/(byte) vblank::y_idx#1 vblank::@3/(byte) vblank::y_idx#0 )
[76] (byte) vblank::s#2 ← phi( vblank::@2/(byte) vblank::s#1 vblank::@3/(byte) 0 )
[77] if((byte) vblank::s#2<(byte) $40) goto vblank::@2
to:vblank::@return
vblank::@return: scope:[vblank] from vblank::@1
[78] return
to:@return
vblank::@2: scope:[vblank] from vblank::@1
[79] (byte~) vblank::$4 ← (byte) vblank::s#2 << (byte) 2
[80] *((byte*)(const struct SpriteData*) SPRITE_BUFFER + (byte~) vblank::$4) ← *((const to_nomodify byte*) SINTABLE + (byte) vblank::y_idx#2)
[81] (byte~) vblank::$2 ← *((const to_nomodify byte*) SINTABLE + (byte) vblank::x_idx#2) + (byte) 8
[82] *((byte*)(const struct SpriteData*) SPRITE_BUFFER+(const byte) OFFSET_STRUCT_SPRITEDATA_X + (byte~) vblank::$4) ← (byte~) vblank::$2
[83] (byte) vblank::y_idx#1 ← (byte) vblank::y_idx#2 + (byte) 4
[84] (byte) vblank::x_idx#1 ← (byte) vblank::x_idx#2 - (byte) 7
[85] (byte) vblank::s#1 ← ++ (byte) vblank::s#2
to:vblank::@1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,184 @@
(label) @1
(label) @2
(label) @begin
(label) @end
(const struct RICOH_2A03*) APU = (struct RICOH_2A03*) 16384
(const nomodify byte*) FR_COUNTER = (byte*) 16407
(const nomodify byte*) MEMORY = (byte*) 0
(const byte*) MESSAGE[(number) $40] = (byte*) "rex-of-camelot-presents-a-dxycp-on-nintendo-entertainment-system"z
(const byte) OFFSET_STRUCT_RICOH_2A03_DMC_FREQ = (byte) $10
(const byte) OFFSET_STRUCT_RICOH_2A03_OAMDMA = (byte) $14
(const byte) OFFSET_STRUCT_RICOH_2C02_OAMADDR = (byte) 3
(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR = (byte) 6
(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA = (byte) 7
(const byte) OFFSET_STRUCT_RICOH_2C02_PPUMASK = (byte) 1
(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL = (byte) 5
(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS = (byte) 2
(const byte) OFFSET_STRUCT_SPRITEDATA_ATTRIBUTES = (byte) 2
(const byte) OFFSET_STRUCT_SPRITEDATA_TILE = (byte) 1
(const byte) OFFSET_STRUCT_SPRITEDATA_X = (byte) 3
(const byte*) PALETTE[(number) $20] = { (byte) 1, (byte) $21, (byte) $f, (byte) $30, (byte) 1, (byte) $21, (byte) $f, (byte) $30, (byte) 1, (byte) $21, (byte) $f, (byte) $30, (byte) 1, (byte) $21, (byte) $f, (byte) $30, (byte) 1, (byte) $f, (byte) $30, (byte) 8, (byte) 1, (byte) $f, (byte) $18, (byte) 8, (byte) 1, (byte) $30, (byte) $37, (byte) $1a, (byte) $f, (byte) $f, (byte) $f, (byte) $f }
(const struct RICOH_2C02*) PPU = (struct RICOH_2C02*) 8192
(const nomodify byte*) PPU_ATTRIBUTE_TABLE_0 = (byte*) 9152
(const nomodify byte*) PPU_NAME_TABLE_0 = (byte*) 8192
(const nomodify byte*) PPU_PALETTE = (byte*) 16128
(const nomodify to_volatile byte*) PPU_PPUSTATUS = (byte*) 8194
(byte) RICOH_2A03::DMC_FREQ
(byte) RICOH_2A03::DMC_LEN
(byte) RICOH_2A03::DMC_RAW
(byte) RICOH_2A03::DMC_START
(byte) RICOH_2A03::JOY1
(byte) RICOH_2A03::JOY2
(byte) RICOH_2A03::NOISE_HI
(byte) RICOH_2A03::NOISE_LO
(byte) RICOH_2A03::NOISE_VOL
(byte) RICOH_2A03::OAMDMA
(byte) RICOH_2A03::SND_CHN
(byte) RICOH_2A03::SQ1_HI
(byte) RICOH_2A03::SQ1_LO
(byte) RICOH_2A03::SQ1_SWEEP
(byte) RICOH_2A03::SQ1_VOL
(byte) RICOH_2A03::SQ2_HI
(byte) RICOH_2A03::SQ2_LO
(byte) RICOH_2A03::SQ2_SWEEP
(byte) RICOH_2A03::SQ2_VOL
(byte) RICOH_2A03::TRI_HI
(byte) RICOH_2A03::TRI_LINEAR
(byte) RICOH_2A03::TRI_LO
(byte) RICOH_2A03::UNUSED1
(byte) RICOH_2A03::UNUSED2
(byte) RICOH_2C02::OAMADDR
(byte) RICOH_2C02::OAMDATA
(byte) RICOH_2C02::PPUADDR
(byte) RICOH_2C02::PPUCTRL
(byte) RICOH_2C02::PPUDATA
(byte) RICOH_2C02::PPUMASK
(byte) RICOH_2C02::PPUSCROLL
(volatile byte) RICOH_2C02::PPUSTATUS loadstore
(const to_nomodify byte*) SINTABLE[(number) $100] = kickasm {{ .fill $100, round(115.5+107.5*sin(2*PI*i/256))
}}
(const byte) SIZEOF_BYTE = (byte) 1
(const struct SpriteData*) SPRITE_BUFFER[(number) $100] = { fill( $100, 0) }
(byte) SpriteData::attributes
(byte) SpriteData::tile
(byte) SpriteData::x
(byte) SpriteData::y
(const byte*) TILES[] = kickasm {{ .var filechargen = LoadBinary("characters.901225-01.bin")
.for(var c=0; c<256; c++) {
// Plane 0
.fill 8, filechargen.get(c*8+i)
// Plane 1
.fill 8, 0
}
}}
(const to_nomodify void()**) VECTORS[] = { &interrupt(HARDWARE_STACK)(void()) vblank(), &(void()) main(), (void()*) 0 }
(void()) main()
(byte~) main::$7 reg byte y 126.25
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@5
(label) main::@6
(label) main::enableVideoOutput1
(label) main::initNES1
(label) main::initNES1_@1
(label) main::initNES1_@7
(label) main::initNES1_clearVBlankFlag1
(label) main::initNES1_disableAudioOutput1
(label) main::initNES1_disableVideoOutput1
(byte) main::initNES1_i
(byte) main::initNES1_i#1 reg byte x 151.5
(byte) main::initNES1_i#2 reg byte x 112.22222222222223
(label) main::initNES1_waitForVBlank1
(byte~) main::initNES1_waitForVBlank1_$0 reg byte a 202.0
(label) main::initNES1_waitForVBlank1_@1
(label) main::initNES1_waitForVBlank2
(byte~) main::initNES1_waitForVBlank2_$0 reg byte a 202.0
(label) main::initNES1_waitForVBlank2_@1
(byte) main::s
(byte) main::s#1 reg byte x 202.0
(byte) main::s#2 reg byte x 72.14285714285714
(void()) ppuDataFill((nomodify void*) ppuDataFill::ppuData , (byte) ppuDataFill::val , (word) ppuDataFill::size)
(label) ppuDataFill::@1
(label) ppuDataFill::@2
(label) ppuDataFill::@return
(word) ppuDataFill::i
(word) ppuDataFill::i#1 i zp[2]:2 2002.0
(word) ppuDataFill::i#2 i zp[2]:2 1001.0
(nomodify void*) ppuDataFill::ppuData
(label) ppuDataFill::ppuDataPrepare1
(byte~) ppuDataFill::ppuDataPrepare1_$0 reg byte a 202.0
(byte~) ppuDataFill::ppuDataPrepare1_$1 reg byte a 202.0
(nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData
(nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0 ppuDataPrepare1_ppuData zp[2]:4 67.33333333333333
(label) ppuDataFill::ppuDataPut1
(byte) ppuDataFill::ppuDataPut1_val
(word) ppuDataFill::size
(word) ppuDataFill::size#3 size zp[2]:6 111.22222222222223
(byte) ppuDataFill::val
(byte) ppuDataFill::val#4 reg byte x 111.22222222222223
(void()) ppuDataTransfer((nomodify void*) ppuDataTransfer::ppuData , (nomodify void*) ppuDataTransfer::cpuData , (word) ppuDataTransfer::size)
(label) ppuDataTransfer::@1
(label) ppuDataTransfer::@2
(label) ppuDataTransfer::@3
(label) ppuDataTransfer::@return
(nomodify void*) ppuDataTransfer::cpuData
(const nomodify void*) ppuDataTransfer::cpuData#0 cpuData = (void*)(const byte*) PALETTE
(byte*) ppuDataTransfer::cpuSrc
(byte*) ppuDataTransfer::cpuSrc#1 cpuSrc zp[2]:6 1001.0
(byte*) ppuDataTransfer::cpuSrc#2 cpuSrc zp[2]:6 750.75
(word) ppuDataTransfer::i
(word) ppuDataTransfer::i#1 i zp[2]:4 2002.0
(word) ppuDataTransfer::i#2 i zp[2]:4 600.5999999999999
(nomodify void*) ppuDataTransfer::ppuData
(const nomodify void*) ppuDataTransfer::ppuData#0 ppuData = (void*)(const nomodify byte*) PPU_PALETTE
(label) ppuDataTransfer::ppuDataPrepare1
(nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData
(label) ppuDataTransfer::ppuDataPut1
(byte) ppuDataTransfer::ppuDataPut1_val
(byte) ppuDataTransfer::ppuDataPut1_val#0 reg byte a 2002.0
(word) ppuDataTransfer::size
(const word) ppuDataTransfer::size#0 size = (byte) $20*(const byte) SIZEOF_BYTE
interrupt(HARDWARE_STACK)(void()) vblank()
(byte~) vblank::$2 reg byte a 22.0
(byte~) vblank::$4 zp[1]:12 11.0
(label) vblank::@1
(label) vblank::@2
(label) vblank::@3
(label) vblank::@return
(label) vblank::ppuSpriteBufferDmaTransfer1
(struct SpriteData*) vblank::ppuSpriteBufferDmaTransfer1_spriteBuffer
(byte) vblank::s
(byte) vblank::s#1 reg byte x 22.0
(byte) vblank::s#2 reg byte x 5.5
(byte) vblank::x_idx
(byte) vblank::x_idx#0 x_idx zp[1]:9 2.0
(byte) vblank::x_idx#1 x_idx zp[1]:9 11.0
(byte) vblank::x_idx#2 x_idx zp[1]:9 5.0
(byte) vblank::y_idx
(byte) vblank::y_idx#0 y_idx zp[1]:8 1.0
(byte) vblank::y_idx#1 y_idx zp[1]:8 7.333333333333333
(byte) vblank::y_idx#2 y_idx zp[1]:8 5.833333333333333
(volatile byte) x_sin_idx loadstore zp[1]:11 1.1428571428571428
(volatile byte) y_sin_idx loadstore zp[1]:10 1.6
reg byte x [ main::initNES1_i#2 main::initNES1_i#1 ]
reg byte x [ main::s#2 main::s#1 ]
reg byte x [ ppuDataFill::val#4 ]
zp[2]:2 [ ppuDataFill::i#2 ppuDataFill::i#1 ]
zp[2]:4 [ ppuDataTransfer::i#2 ppuDataTransfer::i#1 ppuDataFill::ppuDataPrepare1_ppuData#0 ]
zp[2]:6 [ ppuDataTransfer::cpuSrc#2 ppuDataTransfer::cpuSrc#1 ppuDataFill::size#3 ]
reg byte x [ vblank::s#2 vblank::s#1 ]
zp[1]:8 [ vblank::y_idx#2 vblank::y_idx#1 vblank::y_idx#0 ]
zp[1]:9 [ vblank::x_idx#2 vblank::x_idx#1 vblank::x_idx#0 ]
zp[1]:10 [ y_sin_idx ]
zp[1]:11 [ x_sin_idx ]
reg byte a [ main::initNES1_waitForVBlank1_$0 ]
reg byte a [ main::initNES1_waitForVBlank2_$0 ]
reg byte y [ main::$7 ]
reg byte a [ ppuDataFill::ppuDataPrepare1_$0 ]
reg byte a [ ppuDataFill::ppuDataPrepare1_$1 ]
reg byte a [ ppuDataTransfer::ppuDataPut1_val#0 ]
zp[1]:12 [ vblank::$4 ]
reg byte a [ vblank::$2 ]