mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-01 13:30:50 +00:00
Added nes-dxycp.c
This commit is contained in:
parent
b53392f5fd
commit
7928b2920a
216
src/main/fragment/cache/fragment-cache-mos6502.asm
vendored
216
src/main/fragment/cache/fragment-cache-mos6502.asm
vendored
@ -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
|
||||
|
8
src/main/kc/include/c128.h
Normal file
8
src/main/kc/include/c128.h
Normal 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>
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#pragma data_seg(GameRam)
|
||||
char num_buffer[11];
|
||||
char scroll_buffer[32];
|
||||
#pragma data_seg(Data)
|
||||
|
||||
|
||||
|
BIN
src/test/kc/examples/nes-dxycp/characters.901225-01.bin
Normal file
BIN
src/test/kc/examples/nes-dxycp/characters.901225-01.bin
Normal file
Binary file not shown.
100
src/test/kc/examples/nes-dxycp/nes-dxycp.c
Normal file
100
src/test/kc/examples/nes-dxycp/nes-dxycp.c
Normal 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
|
||||
};
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
401
src/test/ref/examples/nes-dxycp/nes-dxycp.asm
Normal file
401
src/test/ref/examples/nes-dxycp/nes-dxycp.asm
Normal 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
|
180
src/test/ref/examples/nes-dxycp/nes-dxycp.cfg
Normal file
180
src/test/ref/examples/nes-dxycp/nes-dxycp.cfg
Normal 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
|
3643
src/test/ref/examples/nes-dxycp/nes-dxycp.log
Normal file
3643
src/test/ref/examples/nes-dxycp/nes-dxycp.log
Normal file
File diff suppressed because it is too large
Load Diff
184
src/test/ref/examples/nes-dxycp/nes-dxycp.sym
Normal file
184
src/test/ref/examples/nes-dxycp/nes-dxycp.sym
Normal 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 ]
|
Loading…
Reference in New Issue
Block a user