1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-17 00:30:07 +00:00

Added NES tiles. Improved NES library. Closes #457

This commit is contained in:
jespergravgaard 2020-05-26 21:04:52 +02:00
parent a4c0627215
commit d8f6331d38
10 changed files with 4292 additions and 1823 deletions

View File

@ -0,0 +1 @@
lda {m1}+1

View File

@ -0,0 +1 @@
lda {m1}

View File

@ -13,6 +13,19 @@ struct RICOH_2A03 * APU = 0x4000;
// Pointer to the start of RAM memory
char * const MEMORY = 0;
// Sprite Object Attribute Memory Structure
// The memory layout of a sprite in the PPU's OAM memory
struct SpriteData {
char y;
char tile;
char attributes;
char x;
};
// DMA transfer a complete sprite memory buffer to the PPU
// - The Sprite OAM buffer to transfer (must be aligned to $100 in memory)
void ppuSpriteBufferDmaTransfer(struct SpriteData* spriteBuffer);
// Disable audio output
void disableAudioOutput();
@ -27,3 +40,39 @@ void waitForVBlank();
// Clear the vblank flag
void clearVBlankFlag();
// Initialize the NES after a RESET.
// Clears the memory and sets up the stack
// Note: Calling this will destroy the stack, so it only works if called directly inside the reset routine.
void initNES();
// Prepare for transferring data from the CPU to the PPU
// - ppuData : Pointer in the PPU memory
void ppuDataPrepare(void* const ppuData);
// Put one byte into PPU memory
// The byte is put into the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
void ppuDataPut(char val);
// Fill a number of bytes in the PPU memory
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
void ppuDataFill(void* const ppuData, char val, unsigned int size);
// 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
void ppuDataTransfer(void* const ppuData, void* const cpuData, unsigned int size);
// Transfer a 2x2 tile into the PPU memory
// - ppuData : Pointer in the PPU memory
// - tile : The tile to transfer
void ppuDataPutTile(void* const ppuData, char* tile);
// Set one byte in PPU memory
// - ppuData : Pointer in the PPU memory
// - val : The value to set
void ppuDataSet(void* const ppuData, char val);

View File

@ -6,22 +6,30 @@
// Based on: https://github.com/gregkrsak/first_nes written by Greg M. Krsak, 2018.
// PPU Memory Map
// $0000-$0FFF $1000 Pattern table 0
// $0000-$0fff $1000 Pattern table 0
char * const PPU_PATTERN_TABLE_0 = 0x0000;
// $1000-$1FFF $1000 Pattern table 1
// $1000-$1fff $1000 Pattern table 1
char * const PPU_PATTERN_TABLE_1 = 0x1000;
// $2000-$23FF $0400 Nametable 0
// $2000-$23bf $03c0 Name table 0
char * const PPU_NAME_TABLE_0 = 0x2000;
// $2400-$27FF $0400 Nametable 1
// $23c0-$23ff $0040 Attribute table 0
char * const PPU_ATTRIBUTE_TABLE_0 = 0x23c0;
// $2400-$27bf $03c0 Name table 1
char * const PPU_NAME_TABLE_1 = 0x2400;
// $2800-$2BFF $0400 Nametable 2
// $27c0-$27ff $0040 Attribute table 1
char * const PPU_ATTRIBUTE_TABLE_1 = 0x27c0;
// $2800-$2bbf $03c0 Name table 2
char * const PPU_NAME_TABLE_2 = 0x2800;
// $2C00-$2FFF $0400 Nametable 3
// $2bc0-$2bff $0040 Attribute table 2
char * const PPU_ATTRIBUTE_TABLE_2 = 0x2bc0;
// $2c00-$2fbf $03c0 Name table 3
char * const PPU_NAME_TABLE_3 = 0x2c00;
// $3000-$3EFF $0F00 Mirrors of $2000-$2EFF
// $3F00-$3F1F $0020 Palette RAM indexes
// $2fc0-$2fff $0040 Attribute table 3
char * const PPU_ATTRIBUTE_TABLE_3 = 0x2fc0;
// $3000-$3eff $0f00 Mirrors of $2000-$2eff
// $3f00-$3f1f $0020 Palette RAM indexes
char * const PPU_PALETTE = 0x3f00;
// $3F20-$3FFF $00E0 Mirrors of $3F00-$3F1F
// $3f20-$3fff $00e0 Mirrors of $3f00-$3f1f
struct RICOH_2C02 {
// ------+-----+---------------------------------------------------------------

View File

@ -23,8 +23,8 @@ inline void disableVideoOutput() {
inline void enableVideoOutput() {
// Enable vertical blank interrupt
PPU->PPUCTRL = 0b10000000;
// Enable sprite rendering
PPU->PPUMASK = 0b00010000;
// Enable sprite and tile rendering
PPU->PPUMASK = 0b00011000;
}
// Wait for vblank to start
@ -36,3 +36,109 @@ inline void waitForVBlank() {
inline void clearVBlankFlag() {
asm { lda PPU_PPUSTATUS }
}
// Initialize the NES after a RESET.
// Clears the memory and sets up the stack
// Note: Calling this will destroy the stack, so it only works if called directly inside the reset routine.
inline void initNES() {
// Initialize decimal-mode and stack
asm {
cld
ldx #$ff
txs
}
// Initialize the video & audio
disableVideoOutput();
disableAudioOutput();
// Note: When the system is first turned on or reset, the PPU may not be in a usable state right
// away. You should wait at least 30,000 (thirty thousand) CPU cycles for the PPU to initialize,
// which may be accomplished by waiting for 2 (two) vertical blank intervals.
clearVBlankFlag();
waitForVBlank();
// Clear RAM - since it has all variables and the stack it is necesary to do it inline
char i=0;
do {
(MEMORY+0x000)[i] = 0;
(MEMORY+0x100)[i] = 0;
(MEMORY+0x200)[i] = 0;
(MEMORY+0x300)[i] = 0;
(MEMORY+0x400)[i] = 0;
(MEMORY+0x500)[i] = 0;
(MEMORY+0x600)[i] = 0;
(MEMORY+0x700)[i] = 0;
} while (++i);
waitForVBlank();
// Now the PPU is ready.
// Reset the high/low latch to "high"
asm { lda PPU_PPUSTATUS }
}
// DMA transfer the entire sprite buffer to the PPU
// - The Sprite OAM buffer to transfer (must be aligned to $100 in memory)
inline void ppuSpriteBufferDmaTransfer(struct SpriteData* spriteBuffer) {
// Set OAM start address to sprite#0
PPU->OAMADDR = 0;
// Set the high byte (02) of the RAM address and start the DMA transfer to OAM memory
APU->OAMDMA = >spriteBuffer;
}
// Prepare for transfering data from the CPU to the PPU
// - ppuData : Pointer in the PPU memory
inline void ppuDataPrepare(void* const ppuData) {
// Write the high byte of PPU address
PPU->PPUADDR = >ppuData;
// Write the low byte of PPU address
PPU->PPUADDR = <ppuData;
}
// Put one byte into PPU memory
// The byte is put into the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
inline void ppuDataPut(char val) {
// Transfer to PPU
PPU->PPUDATA = val;
}
// Fill a number of bytes in the PPU memory
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
void ppuDataFill(void* const ppuData, char val, unsigned int size) {
ppuDataPrepare(ppuData);
// Transfer to PPU
for(unsigned int i=0;i<size;i++)
ppuDataPut(val);
}
// 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
void ppuDataTransfer(void* const ppuData, void* const cpuData, unsigned int size) {
ppuDataPrepare(ppuData);
// Transfer to PPU
char* cpuSrc = (char*)cpuData;
for(unsigned int i=0;i<size;i++)
ppuDataPut(*cpuSrc++);
}
// Transfer a 2x2 tile into the PPU memory
// - ppuData : Pointer in the PPU memory
// - tile : The tile to transfer
void ppuDataPutTile(void* const ppuData, char* tile) {
ppuDataPrepare(ppuData);
ppuDataPut(tile[0]);
ppuDataPut(tile[1]);
ppuDataPrepare((char*)ppuData+32);
ppuDataPut(tile[2]);
ppuDataPut(tile[3]);
}
// Set one byte in PPU memory
// - ppuData : Pointer in the PPU memory
// - val : The value to set
void ppuDataSet(void* const ppuData, char val) {
ppuDataPrepare(ppuData);
ppuDataPut(val);
}

View File

@ -4,115 +4,83 @@
#include <nes.h>
#include <string.h>
// Sprite OAM Buffer
// Will be transfered to the PPU via DMA during vblank
struct SpriteData * const OAM_BUFFER = 0x0200;
// RESET Called when the NES is reset, including when it is turned on.
void main() {
// Initialize decimal-mode and stack
asm {
cld
ldx #$ff
txs
}
// Initialize the video & audio
disableVideoOutput();
disableAudioOutput();
// Note: When the system is first turned on or reset, the PPU may not be in a usable state right
// away. You should wait at least 30,000 (thirty thousand) CPU cycles for the PPU to initialize,
// which may be accomplished by waiting for 2 (two) vertical blank intervals.
clearVBlankFlag();
waitForVBlank();
// Clear RAM - since it has all variables and the stack it is necesary to do it inline
char i=0;
do {
(MEMORY+0x000)[i] = 0;
(MEMORY+0x100)[i] = 0;
(MEMORY+0x200)[i] = 0;
(MEMORY+0x300)[i] = 0;
(MEMORY+0x400)[i] = 0;
(MEMORY+0x500)[i] = 0;
(MEMORY+0x600)[i] = 0;
(MEMORY+0x700)[i] = 0;
} while (++i);
waitForVBlank();
// Now the PPU is ready.
initPalette();
initSpriteBuffer();
// Initialize NES after RESET
initNES();
// Transfer the palette
ppuDataTransfer(PPU_PALETTE, PALETTE, sizeof(PALETTE));
// Clear the name table
ppuDataFill(PPU_NAME_TABLE_0, 0xfc, 0x3c0);
// Fill the PPU attribute table
ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40);
// Show the entire tile set
//char ch=0;
//for(char y=0;y!=16;y++) {
// ppuDataPrepare(PPU_NAME_TABLE_0+32*4+4+(unsigned int)y*32);
// for(char x=0;x!=16;x++)
// ppuDataPut(ch++);
//}
// Show floor
for(char x=0;x<32;x+=2)
ppuDataPutTile(PPU_NAME_TABLE_0+20*32+x, FLOOR);
// Show flag
ppuDataPutTile(PPU_NAME_TABLE_0+18*32+28, FLAG);
// Initialize Sprite OAM Buffer with the SPRITE data
for(char i=0;i<sizeof(SPRITES); i++)
((char*)OAM_BUFFER)[i] = ((char*)SPRITES)[i];
// Set initial scroll
PPU->PPUSCROLL = 0;
PPU->PPUSCROLL = -8;
// Enable screen rendering and vblank
enableVideoOutput();
// Infinite loop
while(1) {
}
}
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
interrupt(hardware_stack) void vblank() {
// Transfer the entire sprite buffer to the PPU
transferSpriteBufferToPpu();
// DMA transfer the entire sprite buffer to the PPU
ppuSpriteBufferDmaTransfer(OAM_BUFFER);
// Freeze the button positions.
// Latch the controller buttons
APU->JOY1 = 1;
APU->JOY1 = 0;
// Controllers for first and second player are now latched and will not change
// Read button A on controller 1
if(APU->JOY1&0b00000001) {
moveLuigiRight();
// move the Luigi sprites right
OAM_BUFFER[0].y++;
OAM_BUFFER[1].y++;
OAM_BUFFER[2].y++;
OAM_BUFFER[3].y++;
}
// Read button B on controller 1
if(APU->JOY1&0b00000001) {
moveLuigiLeft();
// move the Luigi sprites left
OAM_BUFFER[0].y--;
OAM_BUFFER[1].y--;
OAM_BUFFER[2].y--;
OAM_BUFFER[3].y--;
}
}
// Sprite Object Attribute Memory Structure
struct ObjectAttribute {
char y;
char tile;
char attributes;
char x;
};
// OAM (Object Attribute Memory) Buffer
// Will be transfered to the PPU via DMA
struct ObjectAttribute * const OAM_BUFFER = 0x0200;
// move the Luigi sprites right
void moveLuigiRight() {
OAM_BUFFER[0].x++;
OAM_BUFFER[1].x++;
OAM_BUFFER[2].x++;
OAM_BUFFER[3].x++;
}
// move the Luigi sprites left
void moveLuigiLeft() {
OAM_BUFFER[0].x--;
OAM_BUFFER[1].x--;
OAM_BUFFER[2].x--;
OAM_BUFFER[3].x--;
}
// DMA transfer the entire sprite buffer to the PPU
inline void transferSpriteBufferToPpu() {
// Set OAM start address to sprite#0
PPU->OAMADDR = 0;
// Set the high byte (02) of the RAM address and start the DMA transfer to OAM memory
APU->OAMDMA = >OAM_BUFFER;
}
// Initialize OAM (Object Attribute Memory) Buffer with the SPRITE data
void initSpriteBuffer() {
char i=0;
do {
((char*)OAM_BUFFER)[i] = ((char*)SPRITES)[i];
} while (++i!=sizeof(SPRITES));
}
// Flag tile
char FLAG[] = { 0x54, 0x55, 0x56, 0x57};
// Floor tile
char FLOOR[] = { 0x85, 0x85, 0x86, 0x86};
// Small Luigi Sprite Data
struct ObjectAttribute SPRITES[] = {
struct SpriteData SPRITES[] = {
// Y , TILE, ATTR , X
{ 128, 0x36, 0b00000010, 128 }, // Sprite 0
{ 128, 0x37, 0b00000010, 136 }, // Sprite 1
@ -120,26 +88,13 @@ struct ObjectAttribute SPRITES[] = {
{ 136, 0x39, 0b00000010, 136 } // Sprite 3
};
// Copy palette values to PPU
void initPalette() {
// Reset the high/low latch to "high"
asm { lda PPU_PPUSTATUS }
// Write the high byte of PPU Palette address
PPU->PPUADDR = >PPU_PALETTE;
// Write the low byte of PPU Palette address
PPU->PPUADDR = <PPU_PALETTE;
// Write to PPU
for(char i=0;i<sizeof(PALETTE);i++)
PPU->PPUDATA = PALETTE[i];
}
// Color Palette
char PALETTE[0x20] = {
// Background palettes
0x0f, 0x31, 0x32, 0x33,
0x0f, 0x35, 0x36, 0x37,
0x0f, 0x39, 0x3a, 0x3b,
0x0f, 0x3d, 0x3e, 0x0f,
0x0f, 0x13, 0x23, 0x33,
0x0f, 0x06, 0x15, 0x36,
0x0f, 0x39, 0x4a, 0x5b,
0x0f, 0x3d, 0x4e, 0x5f,
// Sprite palettes (selected by the attribute bits 0-1 of the sprites)
0x0f, 0x1c, 0x15, 0x14,
0x0f, 0x02, 0x38, 0x3c,
@ -147,7 +102,7 @@ char PALETTE[0x20] = {
0x0f, 0x0f, 0x0f, 0x0f // All black
};
// Tiles
// Tile Set
#pragma data_seg(Tiles)
export char TILES[] = kickasm(resource "smb1_chr.bin") {{
.import binary "smb1_chr.bin"

View File

@ -28,19 +28,23 @@
// Mirroring nibble 0001 == Vertical mirroring only
.segment Code
.const SIZEOF_STRUCT_OBJECTATTRIBUTE = 4
.const SIZEOF_STRUCT_SPRITEDATA = 4
.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_2A03_JOY1 = $16
.const OFFSET_STRUCT_OBJECTATTRIBUTE_X = 3
.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 OFFSET_STRUCT_RICOH_2A03_JOY1 = $16
.const SIZEOF_BYTE = 1
// $3000-$3EFF $0F00 Mirrors of $2000-$2EFF
// $3F00-$3F1F $0020 Palette RAM indexes
// $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
// APU Frame Counter
// generates low-frequency clocks for the channels and an optional 60 Hz interrupt.
@ -56,8 +60,8 @@
.label FR_COUNTER = $4017
// Pointer to the start of RAM memory
.label MEMORY = 0
// OAM (Object Attribute Memory) Buffer
// Will be transfered to the PPU via DMA
// Sprite OAM Buffer
// Will be transfered to the PPU via DMA during vblank
.label OAM_BUFFER = $200
// PPU Status Register for reading in ASM
.label PPU_PPUSTATUS = $2002
@ -69,7 +73,6 @@
// RESET Called when the NES is reset, including when it is turned on.
main: {
// asm
// Initialize decimal-mode and stack
cld
ldx #$ff
txs
@ -85,15 +88,15 @@ main: {
sta APU+OFFSET_STRUCT_RICOH_2A03_DMC_FREQ
// asm
lda PPU_PPUSTATUS
waitForVBlank1:
initNES1_waitForVBlank1:
// PPU->PPUSTATUS&0x80
lda #$80
and PPU+OFFSET_STRUCT_RICOH_2C02_PPUSTATUS
// while(!(PPU->PPUSTATUS&0x80))
cmp #0
beq waitForVBlank1
beq initNES1_waitForVBlank1
ldx #0
__b1:
initNES1___b1:
// (MEMORY+0x000)[i] = 0
lda #0
sta MEMORY,x
@ -114,70 +117,265 @@ main: {
// while (++i)
inx
cpx #0
bne __b1
waitForVBlank2:
bne initNES1___b1
initNES1_waitForVBlank2:
// PPU->PPUSTATUS&0x80
lda #$80
and PPU+OFFSET_STRUCT_RICOH_2C02_PPUSTATUS
// while(!(PPU->PPUSTATUS&0x80))
cmp #0
beq waitForVBlank2
// initPalette()
// Now the PPU is ready.
jsr initPalette
// initSpriteBuffer()
jsr initSpriteBuffer
beq initNES1_waitForVBlank2
// asm
lda PPU_PPUSTATUS
// ppuDataTransfer(PPU_PALETTE, PALETTE, sizeof(PALETTE))
// Transfer the palette
jsr ppuDataTransfer
// ppuDataFill(PPU_NAME_TABLE_0, 0xfc, 0x3c0)
// Clear the name table
ldx #$fc
lda #<$3c0
sta.z ppuDataFill.size
lda #>$3c0
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)
// Fill the PPU attribute table
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
// Show the entire tile set
//char ch=0;
//for(char y=0;y!=16;y++) {
// ppuDataPrepare(PPU_NAME_TABLE_0+32*4+4+(unsigned int)y*32);
// for(char x=0;x!=16;x++)
// ppuDataPut(ch++);
//}
// Show floor
__b1:
// for(char x=0;x<32;x+=2)
cpx #$20
bcc __b2
// ppuDataPutTile(PPU_NAME_TABLE_0+18*32+28, FLAG)
// Show flag
lda #<FLAG
sta.z ppuDataPutTile.tile
lda #>FLAG
sta.z ppuDataPutTile.tile+1
lda #<PPU_NAME_TABLE_0+$12*$20+$1c
sta.z ppuDataPutTile.ppuData
lda #>PPU_NAME_TABLE_0+$12*$20+$1c
sta.z ppuDataPutTile.ppuData+1
jsr ppuDataPutTile
ldx #0
// Initialize Sprite OAM Buffer with the SPRITE data
__b4:
// for(char i=0;i<sizeof(SPRITES); i++)
cpx #4*SIZEOF_STRUCT_SPRITEDATA
bcc __b5
// PPU->PPUSCROLL = 0
// Set initial scroll
lda #0
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
// PPU->PPUSCROLL = -8
lda #-8
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
// PPU->PPUCTRL = 0b10000000
lda #$80
sta PPU
// PPU->PPUMASK = 0b00010000
lda #$10
// PPU->PPUMASK = 0b00011000
lda #$18
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUMASK
__b2:
__b3:
// Infinite loop
jmp __b2
}
// Initialize OAM (Object Attribute Memory) Buffer with the SPRITE data
initSpriteBuffer: {
ldx #0
__b1:
jmp __b3
__b5:
// ((char*)OAM_BUFFER)[i] = ((char*)SPRITES)[i]
lda SPRITES,x
sta OAM_BUFFER,x
// while (++i!=sizeof(SPRITES))
// for(char i=0;i<sizeof(SPRITES); i++)
inx
cpx #4*SIZEOF_STRUCT_OBJECTATTRIBUTE
bne __b1
jmp __b4
__b2:
// PPU_NAME_TABLE_0+20*32+x
txa
clc
adc #<PPU_NAME_TABLE_0+$14*$20
sta.z ppuDataPutTile.ppuData
lda #>PPU_NAME_TABLE_0+$14*$20
adc #0
sta.z ppuDataPutTile.ppuData+1
// ppuDataPutTile(PPU_NAME_TABLE_0+20*32+x, FLOOR)
lda #<FLOOR
sta.z ppuDataPutTile.tile
lda #>FLOOR
sta.z ppuDataPutTile.tile+1
jsr ppuDataPutTile
// x+=2
inx
inx
jmp __b1
}
// Transfer a 2x2 tile into the PPU memory
// - ppuData : Pointer in the PPU memory
// - tile : The tile to transfer
// ppuDataPutTile(byte* zp(6) ppuData, byte* zp(2) tile)
ppuDataPutTile: {
.label ppuDataPrepare2_ppuData = 6
.label ppuData = 6
.label tile = 2
// >ppuData
lda.z ppuData+1
// PPU->PPUADDR = >ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// <ppuData
lda.z ppuData
// PPU->PPUADDR = <ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// ppuDataPut(tile[0])
ldy #0
lda (tile),y
// PPU->PPUDATA = val
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// ppuDataPut(tile[1])
ldy #1
lda (tile),y
// PPU->PPUDATA = val
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// (char*)ppuData+32
lda #$20
clc
adc.z ppuDataPrepare2_ppuData
sta.z ppuDataPrepare2_ppuData
bcc !+
inc.z ppuDataPrepare2_ppuData+1
!:
// >ppuData
lda.z ppuDataPrepare2_ppuData+1
// PPU->PPUADDR = >ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// <ppuData
lda.z ppuDataPrepare2_ppuData
// PPU->PPUADDR = <ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// ppuDataPut(tile[2])
ldy #2
lda (tile),y
// PPU->PPUDATA = val
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// ppuDataPut(tile[3])
ldy #3
lda (tile),y
// PPU->PPUDATA = val
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// }
rts
}
// Copy palette values to PPU
initPalette: {
// asm
// Reset the high/low latch to "high"
lda PPU_PPUSTATUS
// PPU->PPUADDR = >PPU_PALETTE
// Write the high byte of PPU Palette address
lda #>PPU_PALETTE
// 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(2) size)
ppuDataFill: {
.label ppuDataPrepare1_ppuData = 6
.label i = 4
.label size = 2
// >ppuData
lda.z ppuDataPrepare1_ppuData+1
// PPU->PPUADDR = >ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// PPU->PPUADDR = <PPU_PALETTE
// Write the low byte of PPU Palette address
// <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
tax
// Write to PPU
lda #<cpuData
sta.z cpuSrc
lda #>cpuData
sta.z cpuSrc+1
lda #<0
sta.z i
sta.z i+1
__b1:
// for(char i=0;i<sizeof(PALETTE);i++)
cpx #$20*SIZEOF_BYTE
// 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:
// PPU->PPUDATA = PALETTE[i]
lda PALETTE,x
// ppuDataPut(*cpuSrc++)
ldy #0
lda (cpuSrc),y
// PPU->PPUDATA = val
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// for(char i=0;i<sizeof(PALETTE);i++)
inx
// 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)
@ -190,11 +388,11 @@ vblank: {
// PPU->OAMADDR = 0
lda #0
sta PPU+OFFSET_STRUCT_RICOH_2C02_OAMADDR
// APU->OAMDMA = >OAM_BUFFER
// APU->OAMDMA = >spriteBuffer
lda #>OAM_BUFFER
sta APU+OFFSET_STRUCT_RICOH_2A03_OAMDMA
// APU->JOY1 = 1
// Freeze the button positions.
// Latch the controller buttons
lda #1
sta APU+OFFSET_STRUCT_RICOH_2A03_JOY1
// APU->JOY1 = 0
@ -206,8 +404,14 @@ vblank: {
// if(APU->JOY1&0b00000001)
cmp #0
beq __b1
// moveLuigiRight()
jsr moveLuigiRight
// OAM_BUFFER[0].y++;
inc OAM_BUFFER
// OAM_BUFFER[1].y++;
inc OAM_BUFFER+1*SIZEOF_STRUCT_SPRITEDATA
// OAM_BUFFER[2].y++;
inc OAM_BUFFER+2*SIZEOF_STRUCT_SPRITEDATA
// OAM_BUFFER[3].y++;
inc OAM_BUFFER+3*SIZEOF_STRUCT_SPRITEDATA
__b1:
// APU->JOY1&0b00000001
lda #1
@ -215,8 +419,14 @@ vblank: {
// if(APU->JOY1&0b00000001)
cmp #0
beq __breturn
// moveLuigiLeft()
jsr moveLuigiLeft
// OAM_BUFFER[0].y--;
dec OAM_BUFFER
// OAM_BUFFER[1].y--;
dec OAM_BUFFER+1*SIZEOF_STRUCT_SPRITEDATA
// OAM_BUFFER[2].y--;
dec OAM_BUFFER+2*SIZEOF_STRUCT_SPRITEDATA
// OAM_BUFFER[3].y--;
dec OAM_BUFFER+3*SIZEOF_STRUCT_SPRITEDATA
__breturn:
// }
pla
@ -226,36 +436,15 @@ vblank: {
pla
rti
}
// move the Luigi sprites left
moveLuigiLeft: {
// OAM_BUFFER[0].x--;
dec OAM_BUFFER+OFFSET_STRUCT_OBJECTATTRIBUTE_X
// OAM_BUFFER[1].x--;
dec OAM_BUFFER+OFFSET_STRUCT_OBJECTATTRIBUTE_X+1*SIZEOF_STRUCT_OBJECTATTRIBUTE
// OAM_BUFFER[2].x--;
dec OAM_BUFFER+OFFSET_STRUCT_OBJECTATTRIBUTE_X+2*SIZEOF_STRUCT_OBJECTATTRIBUTE
// OAM_BUFFER[3].x--;
dec OAM_BUFFER+OFFSET_STRUCT_OBJECTATTRIBUTE_X+3*SIZEOF_STRUCT_OBJECTATTRIBUTE
// }
rts
}
// move the Luigi sprites right
moveLuigiRight: {
// OAM_BUFFER[0].x++;
inc OAM_BUFFER+OFFSET_STRUCT_OBJECTATTRIBUTE_X
// OAM_BUFFER[1].x++;
inc OAM_BUFFER+OFFSET_STRUCT_OBJECTATTRIBUTE_X+1*SIZEOF_STRUCT_OBJECTATTRIBUTE
// OAM_BUFFER[2].x++;
inc OAM_BUFFER+OFFSET_STRUCT_OBJECTATTRIBUTE_X+2*SIZEOF_STRUCT_OBJECTATTRIBUTE
// OAM_BUFFER[3].x++;
inc OAM_BUFFER+OFFSET_STRUCT_OBJECTATTRIBUTE_X+3*SIZEOF_STRUCT_OBJECTATTRIBUTE
// }
rts
}
.segment Data
// Flag tile
FLAG: .byte $54, $55, $56, $57
// Floor tile
FLOOR: .byte $85, $85, $86, $86
// Small Luigi Sprite Data
SPRITES: .byte $80, $36, 2, $80, $80, $37, 2, $88, $88, $38, 2, $80, $88, $39, 2, $88
PALETTE: .byte $f, $31, $32, $33, $f, $35, $36, $37, $f, $39, $3a, $3b, $f, $3d, $3e, $f, $f, $1c, $15, $14, $f, 2, $38, $3c, $f, $30, $37, $1a, $f, $f, $f, $f
// Color Palette
PALETTE: .byte $f, $13, $23, $33, $f, 6, $15, $36, $f, $39, $4a, $5b, $f, $3d, $4e, $5f, $f, $1c, $15, $14, $f, 2, $38, $3c, $f, $30, $37, $1a, $f, $f, $f, $f
.segment Tiles
TILES:
.import binary "smb1_chr.bin"

View File

@ -10,142 +10,231 @@
(void()) main()
main: scope:[main] from @1
[4] phi()
to:main::initNES1
main::initNES1: scope:[main] from main
asm { cld ldx#$ff txs }
to:main::disableVideoOutput1
main::disableVideoOutput1: scope:[main] from main
[5] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) 0
[6] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUMASK) ← (byte) 0
to:main::disableAudioOutput1
main::disableAudioOutput1: scope:[main] from main::disableVideoOutput1
[7] *((const nomodify byte*) FR_COUNTER) ← (byte) $40
[8] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_DMC_FREQ) ← (byte) $40
to:main::clearVBlankFlag1
main::clearVBlankFlag1: scope:[main] from main::disableAudioOutput1
to:main::initNES1_disableVideoOutput1
main::initNES1_disableVideoOutput1: scope:[main] from main::initNES1
[6] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) 0
[7] *((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
[8] *((const nomodify byte*) FR_COUNTER) ← (byte) $40
[9] *((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::waitForVBlank1
main::waitForVBlank1: scope:[main] from main::clearVBlankFlag1
[10] phi()
to:main::waitForVBlank1_@1
main::waitForVBlank1_@1: scope:[main] from main::waitForVBlank1 main::waitForVBlank1_@1
[11] (byte~) main::waitForVBlank1_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[12] if((byte) 0==(byte~) main::waitForVBlank1_$0) goto main::waitForVBlank1_@1
to:main::@1
main::@1: scope:[main] from main::@1 main::waitForVBlank1_@1
[13] (byte) main::i#2 ← phi( main::@1/(byte) main::i#1 main::waitForVBlank1_@1/(byte) 0 )
[14] *((const nomodify byte*) MEMORY + (byte) main::i#2) ← (byte) 0
[15] *((const nomodify byte*) MEMORY+(word) $100 + (byte) main::i#2) ← (byte) 0
[16] *((const nomodify byte*) MEMORY+(word) $200 + (byte) main::i#2) ← (byte) 0
[17] *((const nomodify byte*) MEMORY+(word) $300 + (byte) main::i#2) ← (byte) 0
[18] *((const nomodify byte*) MEMORY+(word) $400 + (byte) main::i#2) ← (byte) 0
[19] *((const nomodify byte*) MEMORY+(word) $500 + (byte) main::i#2) ← (byte) 0
[20] *((const nomodify byte*) MEMORY+(word) $600 + (byte) main::i#2) ← (byte) 0
[21] *((const nomodify byte*) MEMORY+(word) $700 + (byte) main::i#2) ← (byte) 0
[22] (byte) main::i#1 ← ++ (byte) main::i#2
[23] if((byte) 0!=(byte) main::i#1) goto main::@1
to:main::waitForVBlank2
main::waitForVBlank2: scope:[main] from main::@1
[24] phi()
to:main::waitForVBlank2_@1
main::waitForVBlank2_@1: scope:[main] from main::waitForVBlank2 main::waitForVBlank2_@1
[25] (byte~) main::waitForVBlank2_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[26] if((byte) 0==(byte~) main::waitForVBlank2_$0) goto main::waitForVBlank2_@1
to:main::@3
main::@3: scope:[main] from main::waitForVBlank2_@1
[27] phi()
[28] call initPalette
to:main::@4
main::@4: scope:[main] from main::@3
to:main::initNES1_waitForVBlank1
main::initNES1_waitForVBlank1: scope:[main] from main::initNES1_clearVBlankFlag1
[11] phi()
to:main::initNES1_waitForVBlank1_@1
main::initNES1_waitForVBlank1_@1: scope:[main] from main::initNES1_waitForVBlank1 main::initNES1_waitForVBlank1_@1
[12] (byte~) main::initNES1_waitForVBlank1_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[13] 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
[14] (byte) main::initNES1_i#2 ← phi( main::initNES1_@1/(byte) main::initNES1_i#1 main::initNES1_waitForVBlank1_@1/(byte) 0 )
[15] *((const nomodify byte*) MEMORY + (byte) main::initNES1_i#2) ← (byte) 0
[16] *((const nomodify byte*) MEMORY+(word) $100 + (byte) main::initNES1_i#2) ← (byte) 0
[17] *((const nomodify byte*) MEMORY+(word) $200 + (byte) main::initNES1_i#2) ← (byte) 0
[18] *((const nomodify byte*) MEMORY+(word) $300 + (byte) main::initNES1_i#2) ← (byte) 0
[19] *((const nomodify byte*) MEMORY+(word) $400 + (byte) main::initNES1_i#2) ← (byte) 0
[20] *((const nomodify byte*) MEMORY+(word) $500 + (byte) main::initNES1_i#2) ← (byte) 0
[21] *((const nomodify byte*) MEMORY+(word) $600 + (byte) main::initNES1_i#2) ← (byte) 0
[22] *((const nomodify byte*) MEMORY+(word) $700 + (byte) main::initNES1_i#2) ← (byte) 0
[23] (byte) main::initNES1_i#1 ← ++ (byte) main::initNES1_i#2
[24] 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
[25] phi()
to:main::initNES1_waitForVBlank2_@1
main::initNES1_waitForVBlank2_@1: scope:[main] from main::initNES1_waitForVBlank2 main::initNES1_waitForVBlank2_@1
[26] (byte~) main::initNES1_waitForVBlank2_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[27] 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::@8
main::@8: scope:[main] from main::initNES1_@7
[29] phi()
[30] call initSpriteBuffer
to:main::enableVideoOutput1
main::enableVideoOutput1: scope:[main] from main::@4
[31] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) $80
[32] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUMASK) ← (byte) $10
to:main::@2
main::@2: scope:[main] from main::@2 main::enableVideoOutput1
[30] call ppuDataTransfer
to:main::@9
main::@9: scope:[main] from main::@8
[31] phi()
[32] call ppuDataFill
to:main::@10
main::@10: scope:[main] from main::@9
[33] phi()
to:main::@2
[34] call ppuDataFill
to:main::@1
main::@1: scope:[main] from main::@10 main::@11
[35] (byte) main::x#2 ← phi( main::@10/(byte) 0 main::@11/(byte) main::x#1 )
[36] if((byte) main::x#2<(byte) $20) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@1
[37] phi()
[38] call ppuDataPutTile
to:main::@4
main::@4: scope:[main] from main::@3 main::@5
[39] (byte) main::i#2 ← phi( main::@3/(byte) 0 main::@5/(byte) main::i#1 )
[40] if((byte) main::i#2<(byte) 4*(const byte) SIZEOF_STRUCT_SPRITEDATA) goto main::@5
to:main::@6
main::@6: scope:[main] from main::@4
[41] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL) ← (byte) 0
[42] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL) ← (byte) -8
to:main::enableVideoOutput1
main::enableVideoOutput1: scope:[main] from main::@6
[43] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) $80
[44] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUMASK) ← (byte) $18
to:main::@7
main::@7: scope:[main] from main::@7 main::enableVideoOutput1
[45] phi()
to:main::@7
main::@5: scope:[main] from main::@4
[46] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER + (byte) main::i#2) ← *((byte*)(const struct SpriteData*) SPRITES + (byte) main::i#2)
[47] (byte) main::i#1 ← ++ (byte) main::i#2
to:main::@4
main::@2: scope:[main] from main::@1
[48] (nomodify byte*) ppuDataPutTile::ppuData#0 ← (const nomodify byte*) PPU_NAME_TABLE_0+(word)(number) $14*(number) $20 + (byte) main::x#2
[49] (nomodify void*) ppuDataPutTile::ppuData#9 ← (void*)(nomodify byte*) ppuDataPutTile::ppuData#0
[50] call ppuDataPutTile
to:main::@11
main::@11: scope:[main] from main::@2
[51] (byte) main::x#1 ← (byte) main::x#2 + (byte) 2
to:main::@1
(void()) initSpriteBuffer()
initSpriteBuffer: scope:[initSpriteBuffer] from main::@4
[34] phi()
to:initSpriteBuffer::@1
initSpriteBuffer::@1: scope:[initSpriteBuffer] from initSpriteBuffer initSpriteBuffer::@1
[35] (byte) initSpriteBuffer::i#2 ← phi( initSpriteBuffer/(byte) 0 initSpriteBuffer::@1/(byte) initSpriteBuffer::i#1 )
[36] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER + (byte) initSpriteBuffer::i#2) ← *((byte*)(const struct ObjectAttribute*) SPRITES + (byte) initSpriteBuffer::i#2)
[37] (byte) initSpriteBuffer::i#1 ← ++ (byte) initSpriteBuffer::i#2
[38] if((byte) initSpriteBuffer::i#1!=(byte) 4*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE) goto initSpriteBuffer::@1
to:initSpriteBuffer::@return
initSpriteBuffer::@return: scope:[initSpriteBuffer] from initSpriteBuffer::@1
[39] return
(void()) ppuDataPutTile((nomodify void*) ppuDataPutTile::ppuData , (byte*) ppuDataPutTile::tile)
ppuDataPutTile: scope:[ppuDataPutTile] from main::@2 main::@3
[52] (byte*) ppuDataPutTile::tile#10 ← phi( main::@2/(const byte*) FLOOR main::@3/(const byte*) FLAG )
[52] (nomodify void*) ppuDataPutTile::ppuData#2 ← phi( main::@2/(nomodify void*) ppuDataPutTile::ppuData#9 main::@3/(void*)(const nomodify byte*) PPU_NAME_TABLE_0+(word)(number) $12*(number) $20+(byte) $1c )
to:ppuDataPutTile::ppuDataPrepare1
ppuDataPutTile::ppuDataPrepare1: scope:[ppuDataPutTile] from ppuDataPutTile
[53] (byte~) ppuDataPutTile::ppuDataPrepare1_$0 ← > (nomodify void*) ppuDataPutTile::ppuData#2
[54] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataPutTile::ppuDataPrepare1_$0
[55] (byte~) ppuDataPutTile::ppuDataPrepare1_$1 ← < (nomodify void*) ppuDataPutTile::ppuData#2
[56] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataPutTile::ppuDataPrepare1_$1
to:ppuDataPutTile::@1
ppuDataPutTile::@1: scope:[ppuDataPutTile] from ppuDataPutTile::ppuDataPrepare1
[57] (byte) ppuDataPutTile::ppuDataPut1_val#0 ← *((byte*) ppuDataPutTile::tile#10)
to:ppuDataPutTile::ppuDataPut1
ppuDataPutTile::ppuDataPut1: scope:[ppuDataPutTile] from ppuDataPutTile::@1
[58] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataPutTile::ppuDataPut1_val#0
to:ppuDataPutTile::@2
ppuDataPutTile::@2: scope:[ppuDataPutTile] from ppuDataPutTile::ppuDataPut1
[59] (byte) ppuDataPutTile::ppuDataPut2_val#0 ← *((byte*) ppuDataPutTile::tile#10 + (byte) 1)
to:ppuDataPutTile::ppuDataPut2
ppuDataPutTile::ppuDataPut2: scope:[ppuDataPutTile] from ppuDataPutTile::@2
[60] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataPutTile::ppuDataPut2_val#0
to:ppuDataPutTile::@3
ppuDataPutTile::@3: scope:[ppuDataPutTile] from ppuDataPutTile::ppuDataPut2
[61] (nomodify byte*) ppuDataPutTile::ppuDataPrepare2_ppuData#0 ← (byte*)(nomodify void*) ppuDataPutTile::ppuData#2 + (byte) $20
to:ppuDataPutTile::ppuDataPrepare2
ppuDataPutTile::ppuDataPrepare2: scope:[ppuDataPutTile] from ppuDataPutTile::@3
[62] (byte~) ppuDataPutTile::ppuDataPrepare2_$0 ← > (void*)(nomodify byte*) ppuDataPutTile::ppuDataPrepare2_ppuData#0
[63] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataPutTile::ppuDataPrepare2_$0
[64] (byte~) ppuDataPutTile::ppuDataPrepare2_$1 ← < (void*)(nomodify byte*) ppuDataPutTile::ppuDataPrepare2_ppuData#0
[65] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataPutTile::ppuDataPrepare2_$1
to:ppuDataPutTile::@4
ppuDataPutTile::@4: scope:[ppuDataPutTile] from ppuDataPutTile::ppuDataPrepare2
[66] (byte) ppuDataPutTile::ppuDataPut3_val#0 ← *((byte*) ppuDataPutTile::tile#10 + (byte) 2)
to:ppuDataPutTile::ppuDataPut3
ppuDataPutTile::ppuDataPut3: scope:[ppuDataPutTile] from ppuDataPutTile::@4
[67] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataPutTile::ppuDataPut3_val#0
to:ppuDataPutTile::@5
ppuDataPutTile::@5: scope:[ppuDataPutTile] from ppuDataPutTile::ppuDataPut3
[68] (byte) ppuDataPutTile::ppuDataPut4_val#0 ← *((byte*) ppuDataPutTile::tile#10 + (byte) 3)
to:ppuDataPutTile::ppuDataPut4
ppuDataPutTile::ppuDataPut4: scope:[ppuDataPutTile] from ppuDataPutTile::@5
[69] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataPutTile::ppuDataPut4_val#0
to:ppuDataPutTile::@return
ppuDataPutTile::@return: scope:[ppuDataPutTile] from ppuDataPutTile::ppuDataPut4
[70] return
to:@return
(void()) initPalette()
initPalette: scope:[initPalette] from main::@3
asm { ldaPPU_PPUSTATUS }
[41] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← >(const nomodify byte*) PPU_PALETTE
[42] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte) 0
to:initPalette::@1
initPalette::@1: scope:[initPalette] from initPalette initPalette::@2
[43] (byte) initPalette::i#2 ← phi( initPalette/(byte) 0 initPalette::@2/(byte) initPalette::i#1 )
[44] if((byte) initPalette::i#2<(byte) $20*(const byte) SIZEOF_BYTE) goto initPalette::@2
to:initPalette::@return
initPalette::@return: scope:[initPalette] from initPalette::@1
[45] return
(void()) ppuDataFill((nomodify void*) ppuDataFill::ppuData , (byte) ppuDataFill::val , (word) ppuDataFill::size)
ppuDataFill: scope:[ppuDataFill] from main::@10 main::@9
[71] (byte) ppuDataFill::val#4 ← phi( main::@10/(byte) 0 main::@9/(byte) $fc )
[71] (word) ppuDataFill::size#3 ← phi( main::@10/(byte) $40 main::@9/(word) $3c0 )
[71] (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0 ← phi( main::@10/(void*)(const nomodify byte*) PPU_ATTRIBUTE_TABLE_0 main::@9/(void*)(const nomodify byte*) PPU_NAME_TABLE_0 )
to:ppuDataFill::ppuDataPrepare1
ppuDataFill::ppuDataPrepare1: scope:[ppuDataFill] from ppuDataFill
[72] (byte~) ppuDataFill::ppuDataPrepare1_$0 ← > (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0
[73] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataFill::ppuDataPrepare1_$0
[74] (byte~) ppuDataFill::ppuDataPrepare1_$1 ← < (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0
[75] *((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
[76] (word) ppuDataFill::i#2 ← phi( ppuDataFill::ppuDataPrepare1/(word) 0 ppuDataFill::@2/(word) ppuDataFill::i#1 )
[77] if((word) ppuDataFill::i#2<(word) ppuDataFill::size#3) goto ppuDataFill::ppuDataPut1
to:ppuDataFill::@return
ppuDataFill::@return: scope:[ppuDataFill] from ppuDataFill::@1
[78] return
to:@return
initPalette::@2: scope:[initPalette] from initPalette::@1
[46] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← *((const byte*) PALETTE + (byte) initPalette::i#2)
[47] (byte) initPalette::i#1 ← ++ (byte) initPalette::i#2
to:initPalette::@1
ppuDataFill::ppuDataPut1: scope:[ppuDataFill] from ppuDataFill::@1
[79] *((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
[80] (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::@8
[81] phi()
to:ppuDataTransfer::ppuDataPrepare1
ppuDataTransfer::ppuDataPrepare1: scope:[ppuDataTransfer] from ppuDataTransfer
[82] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← >(const nomodify void*) ppuDataTransfer::ppuData#0
[83] *((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
[84] (byte*) ppuDataTransfer::cpuSrc#2 ← phi( ppuDataTransfer::ppuDataPrepare1/(byte*)(const nomodify void*) ppuDataTransfer::cpuData#0 ppuDataTransfer::@3/(byte*) ppuDataTransfer::cpuSrc#1 )
[84] (word) ppuDataTransfer::i#2 ← phi( ppuDataTransfer::ppuDataPrepare1/(word) 0 ppuDataTransfer::@3/(word) ppuDataTransfer::i#1 )
[85] if((word) ppuDataTransfer::i#2<(const word) ppuDataTransfer::size#0) goto ppuDataTransfer::@2
to:ppuDataTransfer::@return
ppuDataTransfer::@return: scope:[ppuDataTransfer] from ppuDataTransfer::@1
[86] return
to:@return
ppuDataTransfer::@2: scope:[ppuDataTransfer] from ppuDataTransfer::@1
[87] (byte) ppuDataTransfer::ppuDataPut1_val#0 ← *((byte*) ppuDataTransfer::cpuSrc#2)
to:ppuDataTransfer::ppuDataPut1
ppuDataTransfer::ppuDataPut1: scope:[ppuDataTransfer] from ppuDataTransfer::@2
[88] *((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
[89] (byte*) ppuDataTransfer::cpuSrc#1 ← ++ (byte*) ppuDataTransfer::cpuSrc#2
[90] (word) ppuDataTransfer::i#1 ← ++ (word) ppuDataTransfer::i#2
to:ppuDataTransfer::@1
interrupt(HARDWARE_STACK)(void()) vblank()
vblank: scope:[vblank] from
[48] phi()
to:vblank::transferSpriteBufferToPpu1
vblank::transferSpriteBufferToPpu1: scope:[vblank] from vblank
[49] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_OAMADDR) ← (byte) 0
[50] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_OAMDMA) ← >(const nomodify struct ObjectAttribute*) OAM_BUFFER
[91] phi()
to:vblank::ppuSpriteBufferDmaTransfer1
vblank::ppuSpriteBufferDmaTransfer1: scope:[vblank] from vblank
[92] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_OAMADDR) ← (byte) 0
[93] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_OAMDMA) ← >(const nomodify struct SpriteData*) OAM_BUFFER
to:vblank::@4
vblank::@4: scope:[vblank] from vblank::transferSpriteBufferToPpu1
[51] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) ← (byte) 1
[52] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) ← (byte) 0
[53] (byte~) vblank::$1 ← *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) & (byte) 1
[54] if((byte) 0==(byte~) vblank::$1) goto vblank::@1
vblank::@4: scope:[vblank] from vblank::ppuSpriteBufferDmaTransfer1
[94] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) ← (byte) 1
[95] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) ← (byte) 0
[96] (byte~) vblank::$1 ← *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) & (byte) 1
[97] if((byte) 0==(byte~) vblank::$1) goto vblank::@1
to:vblank::@2
vblank::@2: scope:[vblank] from vblank::@4
[55] phi()
[56] call moveLuigiRight
[98] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER) ← ++ *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER)
[99] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 1*(const byte) SIZEOF_STRUCT_SPRITEDATA) ← ++ *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 1*(const byte) SIZEOF_STRUCT_SPRITEDATA)
[100] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 2*(const byte) SIZEOF_STRUCT_SPRITEDATA) ← ++ *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 2*(const byte) SIZEOF_STRUCT_SPRITEDATA)
[101] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 3*(const byte) SIZEOF_STRUCT_SPRITEDATA) ← ++ *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 3*(const byte) SIZEOF_STRUCT_SPRITEDATA)
to:vblank::@1
vblank::@1: scope:[vblank] from vblank::@2 vblank::@4
[57] (byte~) vblank::$3 ← *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) & (byte) 1
[58] if((byte) 0==(byte~) vblank::$3) goto vblank::@return
[102] (byte~) vblank::$3 ← *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) & (byte) 1
[103] if((byte) 0==(byte~) vblank::$3) goto vblank::@return
to:vblank::@3
vblank::@3: scope:[vblank] from vblank::@1
[59] phi()
[60] call moveLuigiLeft
[104] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER) ← -- *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER)
[105] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 1*(const byte) SIZEOF_STRUCT_SPRITEDATA) ← -- *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 1*(const byte) SIZEOF_STRUCT_SPRITEDATA)
[106] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 2*(const byte) SIZEOF_STRUCT_SPRITEDATA) ← -- *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 2*(const byte) SIZEOF_STRUCT_SPRITEDATA)
[107] *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 3*(const byte) SIZEOF_STRUCT_SPRITEDATA) ← -- *((byte*)(const nomodify struct SpriteData*) OAM_BUFFER+(byte) 3*(const byte) SIZEOF_STRUCT_SPRITEDATA)
to:vblank::@return
vblank::@return: scope:[vblank] from vblank::@1 vblank::@3
[61] return
to:@return
(void()) moveLuigiLeft()
moveLuigiLeft: scope:[moveLuigiLeft] from vblank::@3
[62] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X) ← -- *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X)
[63] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 1*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE) ← -- *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 1*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE)
[64] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 2*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE) ← -- *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 2*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE)
[65] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 3*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE) ← -- *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 3*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE)
to:moveLuigiLeft::@return
moveLuigiLeft::@return: scope:[moveLuigiLeft] from moveLuigiLeft
[66] return
to:@return
(void()) moveLuigiRight()
moveLuigiRight: scope:[moveLuigiRight] from vblank::@2
[67] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X) ← ++ *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X)
[68] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 1*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE) ← ++ *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 1*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE)
[69] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 2*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE) ← ++ *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 2*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE)
[70] *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 3*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE) ← ++ *((byte*)(const nomodify struct ObjectAttribute*) OAM_BUFFER+(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X+(byte) 3*(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE)
to:moveLuigiRight::@return
moveLuigiRight::@return: scope:[moveLuigiRight] from moveLuigiRight
[71] return
[108] return
to:@return

File diff suppressed because it is too large Load Diff

View File

@ -2,10 +2,11 @@
(label) @begin
(label) @end
(const struct RICOH_2A03*) APU = (struct RICOH_2A03*) 16384
(const byte*) FLAG[] = { (byte) $54, (byte) $55, (byte) $56, (byte) $57 }
(const byte*) FLOOR[] = { (byte) $85, (byte) $85, (byte) $86, (byte) $86 }
(const nomodify byte*) FR_COUNTER = (byte*) 16407
(const nomodify byte*) MEMORY = (byte*) 0
(const nomodify struct ObjectAttribute*) OAM_BUFFER = (struct ObjectAttribute*) 512
(const byte) OFFSET_STRUCT_OBJECTATTRIBUTE_X = (byte) 3
(const nomodify struct SpriteData*) OAM_BUFFER = (struct SpriteData*) 512
(const byte) OFFSET_STRUCT_RICOH_2A03_DMC_FREQ = (byte) $10
(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1 = (byte) $16
(const byte) OFFSET_STRUCT_RICOH_2A03_OAMDMA = (byte) $14
@ -13,13 +14,12 @@
(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
(byte) ObjectAttribute::attributes
(byte) ObjectAttribute::tile
(byte) ObjectAttribute::x
(byte) ObjectAttribute::y
(const byte*) PALETTE[(number) $20] = { (byte) $f, (byte) $31, (byte) $32, (byte) $33, (byte) $f, (byte) $35, (byte) $36, (byte) $37, (byte) $f, (byte) $39, (byte) $3a, (byte) $3b, (byte) $f, (byte) $3d, (byte) $3e, (byte) $f, (byte) $f, (byte) $1c, (byte) $15, (byte) $14, (byte) $f, (byte) 2, (byte) $38, (byte) $3c, (byte) $f, (byte) $30, (byte) $37, (byte) $1a, (byte) $f, (byte) $f, (byte) $f, (byte) $f }
(const byte*) PALETTE[(number) $20] = { (byte) $f, (byte) $13, (byte) $23, (byte) $33, (byte) $f, (byte) 6, (byte) $15, (byte) $36, (byte) $f, (byte) $39, (byte) $4a, (byte) $5b, (byte) $f, (byte) $3d, (byte) $4e, (byte) $5f, (byte) $f, (byte) $1c, (byte) $15, (byte) $14, (byte) $f, (byte) 2, (byte) $38, (byte) $3c, (byte) $f, (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 to_volatile byte*) PPU_PPUSTATUS = (byte*) 8194
(byte) RICOH_2A03::DMC_FREQ
@ -55,46 +55,124 @@
(byte) RICOH_2C02::PPUSCROLL
(volatile byte) RICOH_2C02::PPUSTATUS loadstore
(const byte) SIZEOF_BYTE = (byte) 1
(const byte) SIZEOF_STRUCT_OBJECTATTRIBUTE = (byte) 4
(const struct ObjectAttribute*) SPRITES[] = { { y: (byte) $80, tile: (byte) $36, attributes: (byte) 2, x: (byte) $80 }, { y: (byte) $80, tile: (byte) $37, attributes: (byte) 2, x: (byte) $88 }, { y: (byte) $88, tile: (byte) $38, attributes: (byte) 2, x: (byte) $80 }, { y: (byte) $88, tile: (byte) $39, attributes: (byte) 2, x: (byte) $88 } }
(const byte) SIZEOF_STRUCT_SPRITEDATA = (byte) 4
(const struct SpriteData*) SPRITES[] = { { y: (byte) $80, tile: (byte) $36, attributes: (byte) 2, x: (byte) $80 }, { y: (byte) $80, tile: (byte) $37, attributes: (byte) 2, x: (byte) $88 }, { y: (byte) $88, tile: (byte) $38, attributes: (byte) 2, x: (byte) $80 }, { y: (byte) $88, tile: (byte) $39, attributes: (byte) 2, x: (byte) $88 } }
(byte) SpriteData::attributes
(byte) SpriteData::tile
(byte) SpriteData::x
(byte) SpriteData::y
(const byte*) TILES[] = kickasm {{ .import binary "smb1_chr.bin"
}}
(const to_nomodify void()**) VECTORS[] = { &interrupt(HARDWARE_STACK)(void()) vblank(), &(void()) main(), (void()*) 0 }
(void()) initPalette()
(label) initPalette::@1
(label) initPalette::@2
(label) initPalette::@return
(byte) initPalette::i
(byte) initPalette::i#1 reg byte x 2002.0
(byte) initPalette::i#2 reg byte x 1334.6666666666667
(void()) initSpriteBuffer()
(label) initSpriteBuffer::@1
(label) initSpriteBuffer::@return
(byte) initSpriteBuffer::i
(byte) initSpriteBuffer::i#1 reg byte x 1501.5
(byte) initSpriteBuffer::i#2 reg byte x 2002.0
(void()) main()
(label) main::@1
(label) main::@10
(label) main::@11
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::clearVBlankFlag1
(label) main::disableAudioOutput1
(label) main::disableVideoOutput1
(label) main::@5
(label) main::@6
(label) main::@7
(label) main::@8
(label) main::@9
(label) main::enableVideoOutput1
(byte) main::i
(byte) main::i#1 reg byte x 151.5
(byte) main::i#2 reg byte x 112.22222222222223
(label) main::waitForVBlank1
(byte~) main::waitForVBlank1_$0 reg byte a 202.0
(label) main::waitForVBlank1_@1
(label) main::waitForVBlank2
(byte~) main::waitForVBlank2_$0 reg byte a 202.0
(label) main::waitForVBlank2_@1
(void()) moveLuigiLeft()
(label) moveLuigiLeft::@return
(void()) moveLuigiRight()
(label) moveLuigiRight::@return
(byte) main::i#1 reg byte x 202.0
(byte) main::i#2 reg byte x 168.33333333333331
(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::x
(byte) main::x#1 reg byte x 202.0
(byte) main::x#2 reg byte x 80.8
(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]:4 2002.0
(word) ppuDataFill::i#2 i zp[2]:4 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]:6 67.33333333333333
(label) ppuDataFill::ppuDataPut1
(byte) ppuDataFill::ppuDataPut1_val
(word) ppuDataFill::size
(word) ppuDataFill::size#3 size zp[2]:2 111.22222222222223
(byte) ppuDataFill::val
(byte) ppuDataFill::val#4 reg byte x 111.22222222222223
(void()) ppuDataPutTile((nomodify void*) ppuDataPutTile::ppuData , (byte*) ppuDataPutTile::tile)
(label) ppuDataPutTile::@1
(label) ppuDataPutTile::@2
(label) ppuDataPutTile::@3
(label) ppuDataPutTile::@4
(label) ppuDataPutTile::@5
(label) ppuDataPutTile::@return
(nomodify void*) ppuDataPutTile::ppuData
(nomodify byte*) ppuDataPutTile::ppuData#0 ppuData zp[2]:6 101.0
(nomodify void*) ppuDataPutTile::ppuData#2 ppuData zp[2]:6 233.66666666666669
(nomodify void*) ppuDataPutTile::ppuData#9 ppuData zp[2]:6 202.0
(label) ppuDataPutTile::ppuDataPrepare1
(byte~) ppuDataPutTile::ppuDataPrepare1_$0 reg byte a 2002.0
(byte~) ppuDataPutTile::ppuDataPrepare1_$1 reg byte a 2002.0
(nomodify void*) ppuDataPutTile::ppuDataPrepare1_ppuData
(label) ppuDataPutTile::ppuDataPrepare2
(byte~) ppuDataPutTile::ppuDataPrepare2_$0 reg byte a 2002.0
(byte~) ppuDataPutTile::ppuDataPrepare2_$1 reg byte a 2002.0
(nomodify void*) ppuDataPutTile::ppuDataPrepare2_ppuData
(nomodify byte*) ppuDataPutTile::ppuDataPrepare2_ppuData#0 ppuDataPrepare2_ppuData zp[2]:6 333.6666666666667
(label) ppuDataPutTile::ppuDataPut1
(byte) ppuDataPutTile::ppuDataPut1_val
(byte) ppuDataPutTile::ppuDataPut1_val#0 reg byte a 2002.0
(label) ppuDataPutTile::ppuDataPut2
(byte) ppuDataPutTile::ppuDataPut2_val
(byte) ppuDataPutTile::ppuDataPut2_val#0 reg byte a 2002.0
(label) ppuDataPutTile::ppuDataPut3
(byte) ppuDataPutTile::ppuDataPut3_val
(byte) ppuDataPutTile::ppuDataPut3_val#0 reg byte a 2002.0
(label) ppuDataPutTile::ppuDataPut4
(byte) ppuDataPutTile::ppuDataPut4_val
(byte) ppuDataPutTile::ppuDataPut4_val#0 reg byte a 2002.0
(byte*) ppuDataPutTile::tile
(byte*) ppuDataPutTile::tile#10 tile zp[2]:2 250.25
(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::$1 reg byte a 4.0
(byte~) vblank::$3 reg byte a 4.0
@ -103,12 +181,28 @@ interrupt(HARDWARE_STACK)(void()) vblank()
(label) vblank::@3
(label) vblank::@4
(label) vblank::@return
(label) vblank::transferSpriteBufferToPpu1
(label) vblank::ppuSpriteBufferDmaTransfer1
(struct SpriteData*) vblank::ppuSpriteBufferDmaTransfer1_spriteBuffer
reg byte x [ main::initNES1_i#2 main::initNES1_i#1 ]
reg byte x [ main::x#2 main::x#1 ]
reg byte x [ main::i#2 main::i#1 ]
reg byte x [ initSpriteBuffer::i#2 initSpriteBuffer::i#1 ]
reg byte x [ initPalette::i#2 initPalette::i#1 ]
reg byte a [ main::waitForVBlank1_$0 ]
reg byte a [ main::waitForVBlank2_$0 ]
zp[2]:2 [ ppuDataFill::size#3 ppuDataPutTile::tile#10 ]
reg byte x [ ppuDataFill::val#4 ]
zp[2]:4 [ ppuDataTransfer::i#2 ppuDataTransfer::i#1 ppuDataFill::i#2 ppuDataFill::i#1 ]
zp[2]:6 [ ppuDataTransfer::cpuSrc#2 ppuDataTransfer::cpuSrc#1 ppuDataFill::ppuDataPrepare1_ppuData#0 ppuDataPutTile::ppuData#2 ppuDataPutTile::ppuData#9 ppuDataPutTile::ppuData#0 ppuDataPutTile::ppuDataPrepare2_ppuData#0 ]
reg byte a [ main::initNES1_waitForVBlank1_$0 ]
reg byte a [ main::initNES1_waitForVBlank2_$0 ]
reg byte a [ ppuDataPutTile::ppuDataPrepare1_$0 ]
reg byte a [ ppuDataPutTile::ppuDataPrepare1_$1 ]
reg byte a [ ppuDataPutTile::ppuDataPut1_val#0 ]
reg byte a [ ppuDataPutTile::ppuDataPut2_val#0 ]
reg byte a [ ppuDataPutTile::ppuDataPrepare2_$0 ]
reg byte a [ ppuDataPutTile::ppuDataPrepare2_$1 ]
reg byte a [ ppuDataPutTile::ppuDataPut3_val#0 ]
reg byte a [ ppuDataPutTile::ppuDataPut4_val#0 ]
reg byte a [ ppuDataFill::ppuDataPrepare1_$0 ]
reg byte a [ ppuDataFill::ppuDataPrepare1_$1 ]
reg byte a [ ppuDataTransfer::ppuDataPut1_val#0 ]
reg byte a [ vblank::$1 ]
reg byte a [ vblank::$3 ]