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

Moved NES example files into a NES folder.

This commit is contained in:
jespergravgaard 2020-09-28 20:32:39 +02:00
parent a8272388b8
commit 5a121eb5dd
18 changed files with 8446 additions and 17506 deletions

File diff suppressed because it is too large Load Diff

View File

@ -222,24 +222,24 @@ public class TestPrograms {
compileAndCompare("minus-precedence-problem.c");
}
//@Test
//public void testNesBalls() throws IOException, URISyntaxException {
// compileAndCompare("complex/nes-balls/kickballs.c");
//}
@Test
public void testNesBalls() throws IOException, URISyntaxException {
compileAndCompare("complex/nes-balls/kickballs-2.c");
}
@Test
public void testNesDxycp() throws IOException, URISyntaxException {
compileAndCompare("examples/nes-dxycp/nes-dxycp.c");
compileAndCompare("examples/nes/nes-dxycp.c");
}
@Test
public void testNesConio() throws IOException, URISyntaxException {
compileAndCompare("examples/nes-conio/nes-conio.c");
compileAndCompare("examples/nes/nes-conio.c");
}
@Test
public void testNesDemo() throws IOException, URISyntaxException {
compileAndCompare("examples/nes-demo/nes-demo.c");
compileAndCompare("examples/nes/nes-demo.c");
}
//@Test

View File

@ -0,0 +1,689 @@
//#pragma emulator("java -jar /Applications/Nintaco_bin_2020-05-01/Nintaco.jar")
// 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 (Mapper 0 NROM, Vertical Mirroring)
// https://sadistech.com/nesromtool/romdoc.html
// https://forums.nesdev.com/viewtopic.php?f=2&t=9896
// https://github.com/gregkrsak/first_nes
.file [name="kickballs-2.nes", type="bin", segments="NesRom"]
.file [name="kickballs-2.nes_hdr", type="bin", segments="Header"]
.file [name="kickballs-2.nes_prg", type="bin", segments="ProgramRom"]
.file [name="kickballs-2.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_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_SPRITEDATA_TILE = 1
.const OFFSET_STRUCT_SPRITEDATA_ATTRIBUTES = 2
.const OFFSET_STRUCT_SPRITEDATA_X = 3
.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 scroll_y = $a
.label vblank_hit = $b
// The random state variable
.label rand_state = 8
.segment Code
__start: {
// scroll_y = 0
lda #0
sta.z scroll_y
// vblank_hit = 0
sta.z vblank_hit
jsr main
rts
}
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
vblank: {
pha
txa
pha
tya
pha
// PPU->PPUSCROLL = 0
// Set scroll
lda #0
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
// PPU->PPUSCROLL = scroll_y
lda.z scroll_y
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
// PPU->OAMADDR = 0
lda #0
sta PPU+OFFSET_STRUCT_RICOH_2C02_OAMADDR
// APU->OAMDMA = >spriteBuffer
lda #>SPRITE_BUFFER
sta APU+OFFSET_STRUCT_RICOH_2A03_OAMDMA
// vblank_hit++;
inc.z vblank_hit
// }
pla
tay
pla
tax
pla
rti
}
main: {
.label __9 = $1a
.label __10 = $1a
.label __11 = $1a
.label __20 = $d
.label __23 = $f
.label __25 = $11
.label __26 = $13
.label __31 = $14
.label __32 = $16
.label __33 = $18
.label __56 = $14
.label i = 2
.label timer_2 = 3
.label h_bar = $c
.label active_balls = 4
.label sprite_idx = 7
.label i_1 = 6
.label timer = 5
// 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
lda #<palette
sta.z ppuDataTransfer.cpuData
lda #>palette
sta.z ppuDataTransfer.cpuData+1
lda #<PPU_PALETTE
sta.z ppuDataTransfer.ppuDataPrepare1_ppuData
lda #>PPU_PALETTE
sta.z ppuDataTransfer.ppuDataPrepare1_ppuData+1
jsr ppuDataTransfer
// ppuDataFill(PPU_NAME_TABLE_0, 0, 32*30)
// Fill the PPU attribute table
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)
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
// ppuDataTransfer(0x2040, h_bar_tilemap, sizeof(h_bar_tilemap))
lda #<h_bar_tilemap
sta.z ppuDataTransfer.cpuData
lda #>h_bar_tilemap
sta.z ppuDataTransfer.cpuData+1
lda #<$2040
sta.z ppuDataTransfer.ppuDataPrepare1_ppuData
lda #>$2040
sta.z ppuDataTransfer.ppuDataPrepare1_ppuData+1
jsr ppuDataTransfer
// PPU->PPUCTRL = 0b10000000
lda #$80
sta PPU
// PPU->PPUMASK = 0b00011110
lda #$1e
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUMASK
// PPU->PPUCTRL = 0b10001000
// Enable vertical blank interrupt, select sprite pattern table 1
lda #$88
sta PPU
lda #<1
sta.z rand_state
lda #>1
sta.z rand_state+1
sta.z i
__b1:
// for (i = 0; i < MAX_BALLS; i++)
lda.z i
cmp #$20
bcs !__b2+
jmp __b2
!__b2:
lda #0
sta.z timer
sta.z active_balls
sta.z timer_2
__b4:
// timer_2++;
inc.z timer_2
// h_bar = sine_table[timer_2] + 0x60
lda #$60
ldy.z timer_2
clc
adc sine_table,y
sta.z h_bar
// h_bar ^ 0xFF
lda #$ff
eor.z h_bar
// scroll_y = h_bar ^ 0xFF
sta.z scroll_y
// if (active_balls < MAX_BALLS)
lda.z active_balls
cmp #$20
bcs __b5
// if (timer++ == RELEASE_TIMER)
ldx.z timer
inx
lda #9
cmp.z timer
beq !__b25+
jmp __b25
!__b25:
// active_balls++;
inc.z active_balls
// balls[active_balls].x_position = 0
lda.z active_balls
asl
asl
asl
tax
lda #0
sta balls,x
sta balls+1,x
// balls[active_balls].y_position = 0
sta balls+2,x
sta balls+2+1,x
sta.z timer
__b5:
lda #0
sta.z sprite_idx
sta.z i_1
__b6:
// for (i = 0; i < active_balls; i++)
lda.z i_1
cmp.z active_balls
bcc __b7
// poke(0x2001) = 0x98
lda #$98
sta $2001
__b13:
// while (!vblank_hit)
lda #0
cmp.z vblank_hit
beq __b13
// vblank_hit = 0
// wait for vblank
sta.z vblank_hit
// poke(0x2001) = 0x18
lda #$18
sta $2001
jmp __b4
__b7:
// balls[i].x_position += balls[i].x_velocity
lda.z i_1
asl
asl
asl
tay
clc
lda balls,y
adc balls+4,y
sta balls,y
lda balls+1,y
adc balls+4+1,y
sta balls+1,y
// balls[i].y_velocity += WEIGHT
clc
lda balls+6,y
adc #$10
sta balls+6,y
lda balls+6+1,y
adc #0
sta balls+6+1,y
// balls[i].y_position += (balls[i].y_velocity += WEIGHT)
clc
lda balls+2,y
adc balls+6,y
sta balls+2,y
lda balls+2+1,y
adc balls+6+1,y
sta balls+2+1,y
// balls[i].x_position >> 8
lda #0
sta.z __20+1
lda balls+1,y
sta.z __20
// if ((balls[i].x_position >> 8) < 8)
lda.z __20+1
bne __b9
lda.z __20
cmp #8
bcs __b9
!:
// balls[i].x_velocity ^= 0xFFFF
lda.z i_1
asl
asl
asl
tay
lda balls+4,y
eor #<$ffff
sta balls+4,y
lda balls+4+1,y
eor #>$ffff
sta balls+4+1,y
__b9:
// balls[i].y_position >> 8
lda.z i_1
asl
asl
asl
tay
lda #0
sta.z __23+1
lda balls+2+1,y
sta.z __23
lda #0
sta.z __25+1
lda balls+2+1,y
sta.z __25
// h_bar + 8
lax.z h_bar
axs #-[8]
stx.z __26
// if (((balls[i].y_position >> 8) >= h_bar) && (balls[i].y_position >> 8) < h_bar + 8)
lda.z __23+1
bne !+
lda.z __23
cmp.z h_bar
bcc __b10
!:
lda.z __25+1
bne __b10
lda.z __25
cmp.z __26
bcs __b10
!:
// balls[i].y_velocity ^= 0xFFFF
lda.z i_1
asl
asl
asl
tay
lda balls+6,y
eor #<$ffff
sta balls+6,y
lda balls+6+1,y
eor #>$ffff
sta balls+6+1,y
// h_bar - 2
lda.z h_bar
sec
sbc #2
// (unsigned short)(h_bar - 2) << 8
sta.z __56
lda #0
sta.z __56+1
lda.z __31
sta.z __31+1
lda #0
sta.z __31
// balls[i].y_position = ((unsigned short)(h_bar - 2) << 8)
sta balls+2,y
lda.z __31+1
sta balls+2+1,y
__b10:
// balls[i].y_position >> 8
lda.z i_1
asl
asl
asl
tay
lda #0
sta.z __32+1
lda balls+2+1,y
sta.z __32
// SPRITE_BUFFER[sprite_idx].y = (unsigned char) (balls[i].y_position >> 8)
lda.z sprite_idx
asl
asl
tax
lda.z __32
sta SPRITE_BUFFER,x
// SPRITE_BUFFER[sprite_idx].tile = 0x0a
lda #$a
sta SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_TILE,x
// SPRITE_BUFFER[sprite_idx].attributes = 3
lda #3
sta SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_ATTRIBUTES,x
// balls[i].x_position >> 8
lda #0
sta.z __33+1
lda balls+1,y
sta.z __33
// SPRITE_BUFFER[sprite_idx].x = (unsigned char) (balls[i].x_position >> 8)
sta SPRITE_BUFFER+OFFSET_STRUCT_SPRITEDATA_X,x
// sprite_idx++;
inc.z sprite_idx
// for (i = 0; i < active_balls; i++)
inc.z i_1
jmp __b6
__b25:
stx.z timer
jmp __b5
__b2:
// rand()
jsr rand
// rand()
// rand() & 0x3FF
lda.z __10
and #<$3ff
sta.z __10
lda.z __10+1
and #>$3ff
sta.z __10+1
// balls[i].x_velocity = rand() & 0x3FF
lda.z i
asl
asl
asl
tay
lda.z __10
sta balls+4,y
lda.z __10+1
sta balls+4+1,y
// rand()
jsr rand
// rand()
// rand() & 0x0FF
lda #$ff
and.z __11
tax
// balls[i].y_velocity = rand() & 0x0FF
lda.z i
asl
asl
asl
tay
txa
sta balls+6,y
// for (i = 0; i < MAX_BALLS; i++)
inc.z i
jmp __b1
}
// Transfer a number of bytes from the CPU memory to the PPU memory
// - ppuData : Pointer in the PPU memory
// - cpuData : Pointer to the CPU memory (RAM of ROM)
// - size : The number of bytes to transfer
// ppuDataTransfer(void* zp($f) cpuData)
ppuDataTransfer: {
.label ppuDataPrepare1_ppuData = $d
.label cpuSrc = $f
.label i = $11
.label cpuData = $f
// >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
__b1:
// for(unsigned int i=0;i<size;i++)
lda.z i+1
cmp #>$20*SIZEOF_BYTE
bcc __b2
bne !+
lda.z i
cmp #<$20*SIZEOF_BYTE
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
}
// Fill a number of bytes in the PPU memory
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
// ppuDataFill(word zp($f) size)
ppuDataFill: {
.label ppuDataPrepare1_ppuData = $d
.label i = $11
.label size = $f
// >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
lda #0
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// for(unsigned int i=0;i<size;i++)
inc.z i
bne !+
inc.z i+1
!:
jmp __b1
}
// Returns a pseudo-random number in the range of 0 to RAND_MAX (65535)
// Uses an xorshift pseudorandom number generator that hits all different values
// Information https://en.wikipedia.org/wiki/Xorshift
// Source http://www.retroprogramming.com/2017/07/xorshift-pseudorandom-numbers-in-z80.html
rand: {
.label __0 = $1c
.label __1 = $1e
.label __2 = $20
.label return = $1a
// rand_state << 7
lda.z rand_state+1
lsr
lda.z rand_state
ror
sta.z __0+1
lda #0
ror
sta.z __0
// rand_state ^= rand_state << 7
lda.z rand_state
eor.z __0
sta.z rand_state
lda.z rand_state+1
eor.z __0+1
sta.z rand_state+1
// rand_state >> 9
lsr
sta.z __1
lda #0
sta.z __1+1
// rand_state ^= rand_state >> 9
lda.z rand_state
eor.z __1
sta.z rand_state
lda.z rand_state+1
eor.z __1+1
sta.z rand_state+1
// rand_state << 8
lda.z rand_state
sta.z __2+1
lda #0
sta.z __2
// rand_state ^= rand_state << 8
lda.z rand_state
eor.z __2
sta.z rand_state
lda.z rand_state+1
eor.z __2+1
sta.z rand_state+1
// return rand_state;
lda.z rand_state
sta.z return
lda.z rand_state+1
sta.z return+1
// }
rts
}
.segment GameRam
// Moving balls (in GameRAM)
balls: .fill 8*$40, 0
.segment Data
sine_table: .byte $40, $42, $43, $45, $46, $48, $49, $4b, $4c, $4e, $50, $51, $53, $54, $56, $57, $58, $5a, $5b, $5d, $5e, $60, $61, $62, $64, $65, $66, $67, $69, $6a, $6b, $6c, $6d, $6e, $6f, $70, $71, $72, $73, $74, $75, $76, $77, $78, $78, $79, $7a, $7b, $7b, $7c, $7c, $7d, $7d, $7e, $7e, $7e, $7f, $7f, $7f, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $80, $7f, $7f, $7f, $7e, $7e, $7e, $7d, $7d, $7c, $7c, $7b, $7b, $7a, $79, $78, $78, $77, $76, $75, $74, $73, $72, $71, $70, $6f, $6e, $6d, $6c, $6b, $6a, $69, $67, $66, $65, $64, $62, $61, $60, $5e, $5d, $5b, $5a, $58, $57, $56, $54, $53, $51, $50, $4e, $4c, $4b, $49, $48, $46, $45, $43, $42, $40, $3e, $3d, $3b, $3a, $38, $37, $35, $34, $32, $30, $2f, $2d, $2c, $2a, $29, $28, $26, $25, $23, $22, $20, $1f, $1e, $1c, $1b, $1a, $19, $17, $16, $15, $14, $13, $12, $11, $10, $f, $e, $d, $c, $b, $a, 9, 8, 8, 7, 6, 5, 5, 4, 4, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 8, 9, $a, $b, $c, $d, $e, $f, $10, $11, $12, $13, $14, $15, $16, $17, $19, $1a, $1b, $1c, $1e, $1f, $20, $22, $23, $25, $26, $28, $29, $2a, $2c, $2d, $2f, $30, $32, $34, $35, $37, $38, $3a, $3b, $3d, $3e
palette: .byte $34, $24, $14, 4, $34, $24, $14, 4, $34, $24, $14, 4, $34, $24, $14, 4, $34, $24, $14, 4, $34, $24, $14, 4, $34, $24, $14, 4, $34, $24, $14, 4
h_bar_tilemap: .byte 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
.segment Tiles
TILES:
.import binary "lazydata.chr"
.segment GameRam
.align $100
SPRITE_BUFFER: .fill 4*$100, 0
.segment Vectors
VECTORS: .word vblank, main, 0

View File

@ -0,0 +1,288 @@
(void()) __start()
__start: scope:[__start] from
[0] phi()
to:__start::__init1
__start::__init1: scope:[__start] from __start
[1] (volatile byte) scroll_y ← (byte) 0
[2] (volatile byte) vblank_hit ← (byte) 0
to:__start::@1
__start::@1: scope:[__start] from __start::__init1
[3] phi()
[4] call main
to:__start::@return
__start::@return: scope:[__start] from __start::@1
[5] return
to:@return
interrupt(HARDWARE_STACK)(void()) vblank()
vblank: scope:[vblank] from
[6] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL) ← (byte) 0
[7] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL) ← (volatile byte) scroll_y
to:vblank::ppuSpriteBufferDmaTransfer1
vblank::ppuSpriteBufferDmaTransfer1: scope:[vblank] from vblank
[8] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_OAMADDR) ← (byte) 0
[9] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_OAMDMA) ← >(const struct SpriteData*) SPRITE_BUFFER
to:vblank::@1
vblank::@1: scope:[vblank] from vblank::ppuSpriteBufferDmaTransfer1
[10] (volatile byte) vblank_hit ← ++ (volatile byte) vblank_hit
to:vblank::@return
vblank::@return: scope:[vblank] from vblank::@1
[11] return
to:@return
(signed word()) main()
main: scope:[main] from __start::@1
[12] 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
[14] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) 0
[15] *((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
[16] *((const nomodify byte*) FR_COUNTER) ← (byte) $40
[17] *((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
[19] phi()
to:main::initNES1_waitForVBlank1_@1
main::initNES1_waitForVBlank1_@1: scope:[main] from main::initNES1_waitForVBlank1 main::initNES1_waitForVBlank1_@1
[20] (byte~) main::initNES1_waitForVBlank1_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[21] 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
[22] (byte) main::initNES1_i#2 ← phi( main::initNES1_@1/(byte) main::initNES1_i#1 main::initNES1_waitForVBlank1_@1/(byte) 0 )
[23] *((const nomodify byte*) MEMORY + (byte) main::initNES1_i#2) ← (byte) 0
[24] *((const nomodify byte*) MEMORY+(word) $100 + (byte) main::initNES1_i#2) ← (byte) 0
[25] *((const nomodify byte*) MEMORY+(word) $200 + (byte) main::initNES1_i#2) ← (byte) 0
[26] *((const nomodify byte*) MEMORY+(word) $300 + (byte) main::initNES1_i#2) ← (byte) 0
[27] *((const nomodify byte*) MEMORY+(word) $400 + (byte) main::initNES1_i#2) ← (byte) 0
[28] *((const nomodify byte*) MEMORY+(word) $500 + (byte) main::initNES1_i#2) ← (byte) 0
[29] *((const nomodify byte*) MEMORY+(word) $600 + (byte) main::initNES1_i#2) ← (byte) 0
[30] *((const nomodify byte*) MEMORY+(word) $700 + (byte) main::initNES1_i#2) ← (byte) 0
[31] (byte) main::initNES1_i#1 ← ++ (byte) main::initNES1_i#2
[32] 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
[33] phi()
to:main::initNES1_waitForVBlank2_@1
main::initNES1_waitForVBlank2_@1: scope:[main] from main::initNES1_waitForVBlank2 main::initNES1_waitForVBlank2_@1
[34] (byte~) main::initNES1_waitForVBlank2_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[35] 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::@17
main::@17: scope:[main] from main::initNES1_@7
[37] phi()
[38] call ppuDataTransfer
to:main::@19
main::@19: scope:[main] from main::@17
[39] phi()
[40] call ppuDataFill
to:main::@20
main::@20: scope:[main] from main::@19
[41] phi()
[42] call ppuDataFill
to:main::@21
main::@21: scope:[main] from main::@20
[43] phi()
[44] call ppuDataTransfer
to:main::enableVideoOutput1
main::enableVideoOutput1: scope:[main] from main::@21
[45] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) $80
[46] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUMASK) ← (byte) $1e
to:main::@18
main::@18: scope:[main] from main::enableVideoOutput1
[47] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) $88
to:main::@1
main::@1: scope:[main] from main::@18 main::@23
[48] (word) rand_state#17 ← phi( main::@18/(word) 1 main::@23/(word) rand_state#11 )
[48] (byte) main::i#14 ← phi( main::@18/(byte) 0 main::@23/(byte) main::i#2 )
[49] if((byte) main::i#14<(byte) $20) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@1 main::@14
[50] (byte) main::timer#3 ← phi( main::@1/(byte) 0 main::@14/(byte) main::timer#15 )
[50] (byte) main::active_balls#2 ← phi( main::@1/(byte) 0 main::@14/(byte) main::active_balls#8 )
[50] (byte) main::timer_2#2 ← phi( main::@1/(byte) 0 main::@14/(byte) main::timer_2#1 )
to:main::@4
main::@4: scope:[main] from main::@3
[51] (byte) main::timer_2#1 ← ++ (byte) main::timer_2#2
[52] (byte) main::h_bar#1 ← *((const to_nomodify byte*) sine_table + (byte) main::timer_2#1) + (byte) $60
[53] (byte~) main::$14 ← (byte) main::h_bar#1 ^ (byte) $ff
[54] (volatile byte) scroll_y ← (byte~) main::$14
[55] if((byte) main::active_balls#2>=(byte) $20) goto main::@5
to:main::@15
main::@15: scope:[main] from main::@4
[56] (byte) main::timer#1 ← ++ (byte) main::timer#3
[57] if((byte) main::timer#3!=(byte) 9) goto main::@25
to:main::@16
main::@16: scope:[main] from main::@15
[58] (byte) main::active_balls#1 ← ++ (byte) main::active_balls#2
[59] (byte~) main::$38 ← (byte) main::active_balls#1 << (byte) 3
[60] *((word*)(const struct $0*) balls + (byte~) main::$38) ← (byte) 0
[61] *((word*)(const struct $0*) balls+(byte) 2 + (byte~) main::$38) ← (byte) 0
to:main::@5
main::@5: scope:[main] from main::@16 main::@25 main::@4
[62] (byte) main::timer#15 ← phi( main::@25/(byte) main::timer#21 main::@16/(byte) 0 main::@4/(byte) main::timer#3 )
[62] (byte) main::active_balls#8 ← phi( main::@25/(byte) main::active_balls#2 main::@16/(byte) main::active_balls#1 main::@4/(byte) main::active_balls#2 )
to:main::@6
main::@6: scope:[main] from main::@10 main::@5
[63] (byte) main::sprite_idx#3 ← phi( main::@10/(byte) main::sprite_idx#2 main::@5/(byte) 0 )
[63] (byte) main::i#10 ← phi( main::@10/(byte) main::i#4 main::@5/(byte) 0 )
[64] if((byte) main::i#10<(byte) main::active_balls#8) goto main::@7
to:main::@8
main::@8: scope:[main] from main::@6
[65] *((byte*) 8193) ← (byte) $98
to:main::@13
main::@13: scope:[main] from main::@13 main::@8
[66] if((byte) 0==(volatile byte) vblank_hit) goto main::@13
to:main::@14
main::@14: scope:[main] from main::@13
[67] (volatile byte) vblank_hit ← (byte) 0
[68] *((byte*) 8193) ← (byte) $18
to:main::@3
main::@7: scope:[main] from main::@6
[69] (byte~) main::$40 ← (byte) main::i#10 << (byte) 3
[70] *((word*)(const struct $0*) balls + (byte~) main::$40) ← *((word*)(const struct $0*) balls + (byte~) main::$40) + *((word*)(const struct $0*) balls+(byte) 4 + (byte~) main::$40)
[71] *((word*)(const struct $0*) balls+(byte) 6 + (byte~) main::$40) ← *((word*)(const struct $0*) balls+(byte) 6 + (byte~) main::$40) + (byte) $10
[72] *((word*)(const struct $0*) balls+(byte) 2 + (byte~) main::$40) ← *((word*)(const struct $0*) balls+(byte) 2 + (byte~) main::$40) + *((word*)(const struct $0*) balls+(byte) 6 + (byte~) main::$40)
[73] (word~) main::$20 ← *((word*)(const struct $0*) balls + (byte~) main::$40) >> (byte) 8
[74] if((word~) main::$20>=(byte) 8) goto main::@9
to:main::@11
main::@11: scope:[main] from main::@7
[75] (byte~) main::$45 ← (byte) main::i#10 << (byte) 3
[76] *((word*)(const struct $0*) balls+(byte) 4 + (byte~) main::$45) ← *((word*)(const struct $0*) balls+(byte) 4 + (byte~) main::$45) ^ (word) $ffff
to:main::@9
main::@9: scope:[main] from main::@11 main::@7
[77] (byte~) main::$44 ← (byte) main::i#10 << (byte) 3
[78] (word~) main::$23 ← *((word*)(const struct $0*) balls+(byte) 2 + (byte~) main::$44) >> (byte) 8
[79] (word~) main::$25 ← *((word*)(const struct $0*) balls+(byte) 2 + (byte~) main::$44) >> (byte) 8
[80] (byte~) main::$26 ← (byte) main::h_bar#1 + (byte) 8
[81] if((word~) main::$23<(byte) main::h_bar#1) goto main::@10
to:main::@24
main::@24: scope:[main] from main::@9
[82] if((word~) main::$25>=(byte~) main::$26) goto main::@10
to:main::@12
main::@12: scope:[main] from main::@24
[83] (byte~) main::$53 ← (byte) main::i#10 << (byte) 3
[84] *((word*)(const struct $0*) balls+(byte) 6 + (byte~) main::$53) ← *((word*)(const struct $0*) balls+(byte) 6 + (byte~) main::$53) ^ (word) $ffff
[85] (byte~) main::$30 ← (byte) main::h_bar#1 - (byte) 2
[86] (word~) main::$56 ← (word)(byte~) main::$30
[87] (word~) main::$31 ← (word~) main::$56 << (byte) 8
[88] *((word*)(const struct $0*) balls+(byte) 2 + (byte~) main::$53) ← (word~) main::$31
to:main::@10
main::@10: scope:[main] from main::@12 main::@24 main::@9
[89] (byte~) main::$50 ← (byte) main::i#10 << (byte) 3
[90] (word~) main::$32 ← *((word*)(const struct $0*) balls+(byte) 2 + (byte~) main::$50) >> (byte) 8
[91] (byte~) main::$48 ← (byte) main::sprite_idx#3 << (byte) 2
[92] *((byte*)(const struct SpriteData*) SPRITE_BUFFER + (byte~) main::$48) ← (byte)(word~) main::$32
[93] *((byte*)(const struct SpriteData*) SPRITE_BUFFER+(const byte) OFFSET_STRUCT_SPRITEDATA_TILE + (byte~) main::$48) ← (byte) $a
[94] *((byte*)(const struct SpriteData*) SPRITE_BUFFER+(const byte) OFFSET_STRUCT_SPRITEDATA_ATTRIBUTES + (byte~) main::$48) ← (byte) 3
[95] (word~) main::$33 ← *((word*)(const struct $0*) balls + (byte~) main::$50) >> (byte) 8
[96] *((byte*)(const struct SpriteData*) SPRITE_BUFFER+(const byte) OFFSET_STRUCT_SPRITEDATA_X + (byte~) main::$48) ← (byte)(word~) main::$33
[97] (byte) main::sprite_idx#2 ← ++ (byte) main::sprite_idx#3
[98] (byte) main::i#4 ← ++ (byte) main::i#10
to:main::@6
main::@25: scope:[main] from main::@15
[99] (byte) main::timer#21 ← (byte) main::timer#1
to:main::@5
main::@2: scope:[main] from main::@1
[100] phi()
[101] call rand
[102] (word) rand::return#2 ← (word) rand::return#0
to:main::@22
main::@22: scope:[main] from main::@2
[103] (word~) main::$9 ← (word) rand::return#2
[104] (word~) main::$10 ← (word~) main::$9 & (word) $3ff
[105] (byte~) main::$35 ← (byte) main::i#14 << (byte) 3
[106] *((word*)(const struct $0*) balls+(byte) 4 + (byte~) main::$35) ← (word~) main::$10
[107] call rand
[108] (word) rand::return#3 ← (word) rand::return#0
to:main::@23
main::@23: scope:[main] from main::@22
[109] (word~) main::$11 ← (word) rand::return#3
[110] (byte~) main::$12 ← (word~) main::$11 & (byte) $ff
[111] (byte~) main::$36 ← (byte) main::i#14 << (byte) 3
[112] *((word*)(const struct $0*) balls+(byte) 6 + (byte~) main::$36) ← (byte~) main::$12
[113] (byte) main::i#2 ← ++ (byte) main::i#14
to:main::@1
(void()) ppuDataTransfer((nomodify void*) ppuDataTransfer::ppuData , (nomodify void*) ppuDataTransfer::cpuData , (word) ppuDataTransfer::size)
ppuDataTransfer: scope:[ppuDataTransfer] from main::@17 main::@21
[114] (nomodify void*) ppuDataTransfer::cpuData#2 ← phi( main::@17/(void*)(const to_nomodify byte*) palette main::@21/(void*)(const to_nomodify byte*) h_bar_tilemap )
[114] (nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0 ← phi( main::@17/(void*)(const nomodify byte*) PPU_PALETTE main::@21/(void*) 8256 )
to:ppuDataTransfer::ppuDataPrepare1
ppuDataTransfer::ppuDataPrepare1: scope:[ppuDataTransfer] from ppuDataTransfer
[115] (byte~) ppuDataTransfer::ppuDataPrepare1_$0 ← > (nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0
[116] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataTransfer::ppuDataPrepare1_$0
[117] (byte~) ppuDataTransfer::ppuDataPrepare1_$1 ← < (nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0
[118] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataTransfer::ppuDataPrepare1_$1
to:ppuDataTransfer::@3
ppuDataTransfer::@3: scope:[ppuDataTransfer] from ppuDataTransfer::ppuDataPrepare1
[119] (byte*) ppuDataTransfer::cpuSrc#6 ← (byte*)(nomodify void*) ppuDataTransfer::cpuData#2
to:ppuDataTransfer::@1
ppuDataTransfer::@1: scope:[ppuDataTransfer] from ppuDataTransfer::@3 ppuDataTransfer::@4
[120] (byte*) ppuDataTransfer::cpuSrc#2 ← phi( ppuDataTransfer::@3/(byte*) ppuDataTransfer::cpuSrc#6 ppuDataTransfer::@4/(byte*) ppuDataTransfer::cpuSrc#1 )
[120] (word) ppuDataTransfer::i#2 ← phi( ppuDataTransfer::@3/(word) 0 ppuDataTransfer::@4/(word) ppuDataTransfer::i#1 )
[121] if((word) ppuDataTransfer::i#2<(byte) $20*(const byte) SIZEOF_BYTE) goto ppuDataTransfer::@2
to:ppuDataTransfer::@return
ppuDataTransfer::@return: scope:[ppuDataTransfer] from ppuDataTransfer::@1
[122] return
to:@return
ppuDataTransfer::@2: scope:[ppuDataTransfer] from ppuDataTransfer::@1
[123] (byte) ppuDataTransfer::ppuDataPut1_val#0 ← *((byte*) ppuDataTransfer::cpuSrc#2)
to:ppuDataTransfer::ppuDataPut1
ppuDataTransfer::ppuDataPut1: scope:[ppuDataTransfer] from ppuDataTransfer::@2
[124] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataTransfer::ppuDataPut1_val#0
to:ppuDataTransfer::@4
ppuDataTransfer::@4: scope:[ppuDataTransfer] from ppuDataTransfer::ppuDataPut1
[125] (byte*) ppuDataTransfer::cpuSrc#1 ← ++ (byte*) ppuDataTransfer::cpuSrc#2
[126] (word) ppuDataTransfer::i#1 ← ++ (word) ppuDataTransfer::i#2
to:ppuDataTransfer::@1
(void()) ppuDataFill((nomodify void*) ppuDataFill::ppuData , (byte) ppuDataFill::val , (word) ppuDataFill::size)
ppuDataFill: scope:[ppuDataFill] from main::@19 main::@20
[127] (word) ppuDataFill::size#3 ← phi( main::@19/(word)(number) $20*(number) $1e main::@20/(byte) $40 )
[127] (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0 ← phi( main::@19/(void*)(const nomodify byte*) PPU_NAME_TABLE_0 main::@20/(void*)(const nomodify byte*) PPU_ATTRIBUTE_TABLE_0 )
to:ppuDataFill::ppuDataPrepare1
ppuDataFill::ppuDataPrepare1: scope:[ppuDataFill] from ppuDataFill
[128] (byte~) ppuDataFill::ppuDataPrepare1_$0 ← > (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0
[129] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataFill::ppuDataPrepare1_$0
[130] (byte~) ppuDataFill::ppuDataPrepare1_$1 ← < (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0
[131] *((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
[132] (word) ppuDataFill::i#2 ← phi( ppuDataFill::ppuDataPrepare1/(word) 0 ppuDataFill::@2/(word) ppuDataFill::i#1 )
[133] if((word) ppuDataFill::i#2<(word) ppuDataFill::size#3) goto ppuDataFill::ppuDataPut1
to:ppuDataFill::@return
ppuDataFill::@return: scope:[ppuDataFill] from ppuDataFill::@1
[134] return
to:@return
ppuDataFill::ppuDataPut1: scope:[ppuDataFill] from ppuDataFill::@1
[135] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) 0
to:ppuDataFill::@2
ppuDataFill::@2: scope:[ppuDataFill] from ppuDataFill::ppuDataPut1
[136] (word) ppuDataFill::i#1 ← ++ (word) ppuDataFill::i#2
to:ppuDataFill::@1
(word()) rand()
rand: scope:[rand] from main::@2 main::@22
[137] (word) rand_state#10 ← phi( main::@2/(word) rand_state#17 main::@22/(word) rand_state#11 )
[138] (word~) rand::$0 ← (word) rand_state#10 << (byte) 7
[139] (word) rand_state#0 ← (word) rand_state#10 ^ (word~) rand::$0
[140] (word~) rand::$1 ← (word) rand_state#0 >> (byte) 9
[141] (word) rand_state#1 ← (word) rand_state#0 ^ (word~) rand::$1
[142] (word~) rand::$2 ← (word) rand_state#1 << (byte) 8
[143] (word) rand_state#11 ← (word) rand_state#1 ^ (word~) rand::$2
[144] (word) rand::return#0 ← (word) rand_state#11
to:rand::@return
rand::@return: scope:[rand] from rand
[145] return
to:@return

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,282 @@
(word) $0::x_position
(word) $0::x_velocity
(word) $0::y_position
(word) $0::y_velocity
(const struct RICOH_2A03*) APU = (struct RICOH_2A03*) 16384
(const nomodify byte*) FR_COUNTER = (byte*) 16407
(const nomodify byte*) MEMORY = (byte*) 0
(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 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
(const byte) RADIX::BINARY = (number) 2
(const byte) RADIX::DECIMAL = (number) $a
(const byte) RADIX::HEXADECIMAL = (number) $10
(const byte) RADIX::OCTAL = (number) 8
(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 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 {{ .import binary "lazydata.chr"
}}
(const to_nomodify void()**) VECTORS[] = { &interrupt(HARDWARE_STACK)(void()) vblank(), &(signed word()) main(), (void()*) 0 }
(void()) __start()
(label) __start::@1
(label) __start::@return
(label) __start::__init1
(const struct $0*) balls[(number) $40] = { fill( $40, 0) }
(const to_nomodify byte*) h_bar_tilemap[] = { (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1, (byte) 1 }
(signed word()) main()
(word~) main::$10 zp[2]:26 101.0
(word~) main::$11 zp[2]:26 202.0
(byte~) main::$12 reg byte x 101.0
(byte~) main::$14 reg byte a 202.0
(word~) main::$20 zp[2]:13 2002.0
(word~) main::$23 zp[2]:15 667.3333333333334
(word~) main::$25 zp[2]:17 667.3333333333334
(byte~) main::$26 zp[1]:19 1001.0
(byte~) main::$30 reg byte a 1001.0
(word~) main::$31 zp[2]:20 2002.0
(word~) main::$32 zp[2]:22 500.5
(word~) main::$33 zp[2]:24 1001.0
(byte~) main::$35 reg byte a 202.0
(byte~) main::$36 reg byte a 202.0
(byte~) main::$38 reg byte x 151.5
(byte~) main::$40 reg byte y 2502.5
(byte~) main::$44 reg byte y 1501.5
(byte~) main::$45 reg byte a 3003.0
(byte~) main::$48 reg byte x 1001.0
(byte~) main::$50 reg byte y 500.5
(byte~) main::$53 reg byte y 800.8
(word~) main::$56 zp[2]:20 2002.0
(word~) main::$9 zp[2]:26 202.0
(label) main::@1
(label) main::@10
(label) main::@11
(label) main::@12
(label) main::@13
(label) main::@14
(label) main::@15
(label) main::@16
(label) main::@17
(label) main::@18
(label) main::@19
(label) main::@2
(label) main::@20
(label) main::@21
(label) main::@22
(label) main::@23
(label) main::@24
(label) main::@25
(label) main::@3
(label) main::@4
(label) main::@5
(label) main::@6
(label) main::@7
(label) main::@8
(label) main::@9
(byte) main::active_balls
(byte) main::active_balls#1 active_balls zp[1]:4 75.75
(byte) main::active_balls#2 active_balls zp[1]:4 56.11111111111111
(byte) main::active_balls#8 active_balls zp[1]:4 37.97297297297297
(label) main::enableVideoOutput1
(byte) main::h_bar
(byte) main::h_bar#1 h_bar zp[1]:12 72.8409090909091
(byte) main::i
(byte) main::i#10 i_1 zp[1]:6 258.3225806451613
(byte) main::i#14 i zp[1]:2 33.666666666666664
(byte) main::i#2 i zp[1]:2 202.0
(byte) main::i#4 i_1 zp[1]:6 2002.0
(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
(signed word) main::return
(byte) main::sprite_idx
(byte) main::sprite_idx#2 sprite_idx zp[1]:7 1001.0
(byte) main::sprite_idx#3 sprite_idx zp[1]:7 100.1
(byte) main::timer
(byte) main::timer#1 reg byte x 101.0
(byte) main::timer#15 timer zp[1]:5 8.18918918918919
(byte) main::timer#21 timer zp[1]:5 202.0
(byte) main::timer#3 timer zp[1]:5 57.714285714285715
(byte) main::timer_2
(byte) main::timer_2#1 timer_2 zp[1]:3 6.183673469387754
(byte) main::timer_2#2 timer_2 zp[1]:3 202.0
(const to_nomodify byte*) palette[] = { (byte) $34, (byte) $24, (byte) $14, (byte) 4, (byte) $34, (byte) $24, (byte) $14, (byte) 4, (byte) $34, (byte) $24, (byte) $14, (byte) 4, (byte) $34, (byte) $24, (byte) $14, (byte) 4, (byte) $34, (byte) $24, (byte) $14, (byte) 4, (byte) $34, (byte) $24, (byte) $14, (byte) 4, (byte) $34, (byte) $24, (byte) $14, (byte) 4, (byte) $34, (byte) $24, (byte) $14, (byte) 4 }
(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]:17 2002.0
(word) ppuDataFill::i#2 i zp[2]:17 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]:13 67.33333333333333
(label) ppuDataFill::ppuDataPut1
(byte) ppuDataFill::ppuDataPut1_val
(word) ppuDataFill::size
(word) ppuDataFill::size#3 size zp[2]:15 111.22222222222223
(byte) ppuDataFill::val
(void()) ppuDataTransfer((nomodify void*) ppuDataTransfer::ppuData , (nomodify void*) ppuDataTransfer::cpuData , (word) ppuDataTransfer::size)
(label) ppuDataTransfer::@1
(label) ppuDataTransfer::@2
(label) ppuDataTransfer::@3
(label) ppuDataTransfer::@4
(label) ppuDataTransfer::@return
(nomodify void*) ppuDataTransfer::cpuData
(nomodify void*) ppuDataTransfer::cpuData#2 cpuData zp[2]:15
(byte*) ppuDataTransfer::cpuSrc
(byte*) ppuDataTransfer::cpuSrc#1 cpuSrc zp[2]:15 1001.0
(byte*) ppuDataTransfer::cpuSrc#2 cpuSrc zp[2]:15 776.0
(byte*) ppuDataTransfer::cpuSrc#6 cpuSrc zp[2]:15 202.0
(word) ppuDataTransfer::i
(word) ppuDataTransfer::i#1 i zp[2]:17 2002.0
(word) ppuDataTransfer::i#2 i zp[2]:17 600.5999999999999
(nomodify void*) ppuDataTransfer::ppuData
(label) ppuDataTransfer::ppuDataPrepare1
(byte~) ppuDataTransfer::ppuDataPrepare1_$0 reg byte a 202.0
(byte~) ppuDataTransfer::ppuDataPrepare1_$1 reg byte a 202.0
(nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData
(nomodify void*) ppuDataTransfer::ppuDataPrepare1_ppuData#0 ppuDataPrepare1_ppuData zp[2]:13 67.33333333333333
(label) ppuDataTransfer::ppuDataPut1
(byte) ppuDataTransfer::ppuDataPut1_val
(byte) ppuDataTransfer::ppuDataPut1_val#0 reg byte a 2002.0
(word) ppuDataTransfer::size
(const byte*) printf_buffer_number::digits[(number) $b] = { fill( $b, 0) }
(byte) printf_buffer_number::sign
(byte) printf_format_number::justify_left
(byte) printf_format_number::min_length
(byte) printf_format_number::radix
(byte) printf_format_number::sign_always
(byte) printf_format_number::upper_case
(byte) printf_format_number::zero_padding
(byte) printf_format_string::justify_left
(byte) printf_format_string::min_length
(word()) rand()
(word~) rand::$0 zp[2]:28 2002.0
(word~) rand::$1 zp[2]:30 2002.0
(word~) rand::$2 zp[2]:32 2002.0
(label) rand::@return
(word) rand::return
(word) rand::return#0 return zp[2]:26 300.75
(word) rand::return#2 return zp[2]:26 202.0
(word) rand::return#3 return zp[2]:26 202.0
(word) rand_state
(word) rand_state#0 rand_state zp[2]:8 1501.5
(word) rand_state#1 rand_state zp[2]:8 1501.5
(word) rand_state#10 rand_state zp[2]:8 1102.0
(word) rand_state#11 rand_state zp[2]:8 137.75
(word) rand_state#17 rand_state zp[2]:8 67.33333333333333
(volatile byte) scroll_y loadstore zp[1]:10 105.0
(const to_nomodify byte*) sine_table[(number) $100] = { (byte) $40, (byte) $42, (byte) $43, (byte) $45, (byte) $46, (byte) $48, (byte) $49, (byte) $4b, (byte) $4c, (byte) $4e, (byte) $50, (byte) $51, (byte) $53, (byte) $54, (byte) $56, (byte) $57, (byte) $58, (byte) $5a, (byte) $5b, (byte) $5d, (byte) $5e, (byte) $60, (byte) $61, (byte) $62, (byte) $64, (byte) $65, (byte) $66, (byte) $67, (byte) $69, (byte) $6a, (byte) $6b, (byte) $6c, (byte) $6d, (byte) $6e, (byte) $6f, (byte) $70, (byte) $71, (byte) $72, (byte) $73, (byte) $74, (byte) $75, (byte) $76, (byte) $77, (byte) $78, (byte) $78, (byte) $79, (byte) $7a, (byte) $7b, (byte) $7b, (byte) $7c, (byte) $7c, (byte) $7d, (byte) $7d, (byte) $7e, (byte) $7e, (byte) $7e, (byte) $7f, (byte) $7f, (byte) $7f, (byte) $80, (byte) $80, (byte) $80, (byte) $80, (byte) $80, (byte) $80, (byte) $80, (byte) $80, (byte) $80, (byte) $80, (byte) $80, (byte) $7f, (byte) $7f, (byte) $7f, (byte) $7e, (byte) $7e, (byte) $7e, (byte) $7d, (byte) $7d, (byte) $7c, (byte) $7c, (byte) $7b, (byte) $7b, (byte) $7a, (byte) $79, (byte) $78, (byte) $78, (byte) $77, (byte) $76, (byte) $75, (byte) $74, (byte) $73, (byte) $72, (byte) $71, (byte) $70, (byte) $6f, (byte) $6e, (byte) $6d, (byte) $6c, (byte) $6b, (byte) $6a, (byte) $69, (byte) $67, (byte) $66, (byte) $65, (byte) $64, (byte) $62, (byte) $61, (byte) $60, (byte) $5e, (byte) $5d, (byte) $5b, (byte) $5a, (byte) $58, (byte) $57, (byte) $56, (byte) $54, (byte) $53, (byte) $51, (byte) $50, (byte) $4e, (byte) $4c, (byte) $4b, (byte) $49, (byte) $48, (byte) $46, (byte) $45, (byte) $43, (byte) $42, (byte) $40, (byte) $3e, (byte) $3d, (byte) $3b, (byte) $3a, (byte) $38, (byte) $37, (byte) $35, (byte) $34, (byte) $32, (byte) $30, (byte) $2f, (byte) $2d, (byte) $2c, (byte) $2a, (byte) $29, (byte) $28, (byte) $26, (byte) $25, (byte) $23, (byte) $22, (byte) $20, (byte) $1f, (byte) $1e, (byte) $1c, (byte) $1b, (byte) $1a, (byte) $19, (byte) $17, (byte) $16, (byte) $15, (byte) $14, (byte) $13, (byte) $12, (byte) $11, (byte) $10, (byte) $f, (byte) $e, (byte) $d, (byte) $c, (byte) $b, (byte) $a, (byte) 9, (byte) 8, (byte) 8, (byte) 7, (byte) 6, (byte) 5, (byte) 5, (byte) 4, (byte) 4, (byte) 3, (byte) 3, (byte) 2, (byte) 2, (byte) 2, (byte) 1, (byte) 1, (byte) 1, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 1, (byte) 1, (byte) 2, (byte) 2, (byte) 2, (byte) 3, (byte) 3, (byte) 4, (byte) 4, (byte) 5, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 8, (byte) 9, (byte) $a, (byte) $b, (byte) $c, (byte) $d, (byte) $e, (byte) $f, (byte) $10, (byte) $11, (byte) $12, (byte) $13, (byte) $14, (byte) $15, (byte) $16, (byte) $17, (byte) $19, (byte) $1a, (byte) $1b, (byte) $1c, (byte) $1e, (byte) $1f, (byte) $20, (byte) $22, (byte) $23, (byte) $25, (byte) $26, (byte) $28, (byte) $29, (byte) $2a, (byte) $2c, (byte) $2d, (byte) $2f, (byte) $30, (byte) $32, (byte) $34, (byte) $35, (byte) $37, (byte) $38, (byte) $3a, (byte) $3b, (byte) $3d, (byte) $3e }
interrupt(HARDWARE_STACK)(void()) vblank()
(label) vblank::@1
(label) vblank::@return
(label) vblank::ppuSpriteBufferDmaTransfer1
(struct SpriteData*) vblank::ppuSpriteBufferDmaTransfer1_spriteBuffer
(volatile byte) vblank_hit loadstore zp[1]:11 10.25925925925926
reg byte x [ main::initNES1_i#2 main::initNES1_i#1 ]
zp[1]:2 [ main::i#14 main::i#2 ]
zp[1]:3 [ main::timer_2#2 main::timer_2#1 ]
zp[1]:4 [ main::active_balls#2 main::active_balls#8 main::active_balls#1 ]
zp[1]:5 [ main::timer#3 main::timer#15 main::timer#21 ]
zp[1]:6 [ main::i#10 main::i#4 ]
zp[1]:7 [ main::sprite_idx#3 main::sprite_idx#2 ]
zp[2]:8 [ rand_state#10 rand_state#17 rand_state#11 rand_state#0 rand_state#1 ]
zp[1]:10 [ scroll_y ]
zp[1]:11 [ vblank_hit ]
reg byte a [ main::initNES1_waitForVBlank1_$0 ]
reg byte a [ main::initNES1_waitForVBlank2_$0 ]
zp[1]:12 [ main::h_bar#1 ]
reg byte a [ main::$14 ]
reg byte x [ main::timer#1 ]
reg byte x [ main::$38 ]
reg byte y [ main::$40 ]
zp[2]:13 [ main::$20 ppuDataFill::ppuDataPrepare1_ppuData#0 ppuDataTransfer::ppuDataPrepare1_ppuData#0 ]
reg byte a [ main::$45 ]
reg byte y [ main::$44 ]
zp[2]:15 [ main::$23 ppuDataFill::size#3 ppuDataTransfer::cpuData#2 ppuDataTransfer::cpuSrc#2 ppuDataTransfer::cpuSrc#6 ppuDataTransfer::cpuSrc#1 ]
zp[2]:17 [ main::$25 ppuDataFill::i#2 ppuDataFill::i#1 ppuDataTransfer::i#2 ppuDataTransfer::i#1 ]
zp[1]:19 [ main::$26 ]
reg byte y [ main::$53 ]
reg byte a [ main::$30 ]
zp[2]:20 [ main::$56 main::$31 ]
reg byte y [ main::$50 ]
zp[2]:22 [ main::$32 ]
reg byte x [ main::$48 ]
zp[2]:24 [ main::$33 ]
zp[2]:26 [ rand::return#2 main::$9 rand::return#0 main::$10 rand::return#3 main::$11 ]
reg byte a [ main::$35 ]
reg byte x [ main::$12 ]
reg byte a [ main::$36 ]
reg byte a [ ppuDataTransfer::ppuDataPrepare1_$0 ]
reg byte a [ ppuDataTransfer::ppuDataPrepare1_$1 ]
reg byte a [ ppuDataTransfer::ppuDataPut1_val#0 ]
reg byte a [ ppuDataFill::ppuDataPrepare1_$0 ]
reg byte a [ ppuDataFill::ppuDataPrepare1_$1 ]
zp[2]:28 [ rand::$0 ]
zp[2]:30 [ rand::$1 ]
zp[2]:32 [ rand::$2 ]