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

Added NES conio initial support. (scrolling not working atm.)

This commit is contained in:
jespergravgaard 2020-06-06 01:19:28 +02:00
parent 709039de87
commit ba90f9ea65
15 changed files with 8227 additions and 127 deletions

View File

@ -1,11 +1,11 @@
// Commodore 64 Registers and Constants
#ifndef __C64__
#error "Target platform must be C64"
#endif
#include <mos6526.h>
#include <mos6569.h>
#include <mos6581.h>
#ifndef __C64__
#error "Target platform must be C64"
#endif
// Processor port data direction register
char* const PROCPORT_DDR = 0x00;

View File

@ -1,6 +1,9 @@
// Nintendo Entertainment System (NES
// https://en.wikipedia.org/wiki/Nintendo_Entertainment_System_(Model_NES-101)
// https://github.com/gregkrsak/first_nes
#ifndef __NES__
#error "Target platform must be NES"
#endif
#include <ricoh_2c02.h>
#include <ricoh_2a03.h>
@ -83,6 +86,10 @@ void ppuDataPrepare(void* const ppuData);
// The byte is put into the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
void ppuDataPut(char val);
// Read one byte from PPU memory
// The byte is read from the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
char ppuDataRead();
// Fill a number of bytes in the PPU memory
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
@ -99,8 +106,11 @@ void ppuDataTransfer(void* const ppuData, void* const cpuData, unsigned int size
// - 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);
void ppuDataSet(void* const ppuData, char val);
// Get one byte from PPU memory
// - ppuData : Pointer in the PPU memory
char ppuDataGet(void* const ppuData);

173
src/main/kc/lib/conio-nes.c Normal file
View File

@ -0,0 +1,173 @@
// Conio.h implementation for NES
// No support for colors so far
// Scrolling is done by moving all chars in the PPU memory - very slowly!
#include <conio.h>
#include <nes.h>
// The screen width
#define CONIO_WIDTH 32
// The screen height
#define CONIO_HEIGHT 30
// The number of bytes on the screen
#define CONIO_BYTES CONIO_HEIGHT*CONIO_WIDTH
// The text screen address
char * const CONIO_SCREEN_TEXT = PPU_NAME_TABLE_0;
// Return true if there's any key pressed, return false if not
unsigned char kbhit (void) {
return ~readJoy1();
}
// Set the color for the background. The old color setting is returned.
unsigned char bgcolor(unsigned char color) {
return 0;
}
// Set the color for the border. The old color setting is returned.
unsigned char bordercolor(unsigned char color) {
return 0;
}
// The current cursor x-position
__ma char conio_cursor_x = 0;
// The current cursor y-position
__ma char conio_cursor_y = 0;
// The current text cursor line start
__ma char *conio_line_text = CONIO_SCREEN_TEXT;
// Is a cursor shown when waiting for input (0: no, other: yes)
__ma char conio_display_cursor = 0;
// Is scrolling enabled when outputting beyond the end of the screen (1: yes, 0: no).
// If disabled the cursor just moves back to (0,0) instead
__ma char conio_scroll_enable = 1;
// clears the screen and moves the cursor to the upper left-hand corner of the screen.
void clrscr(void) {
ppuDataFill(CONIO_SCREEN_TEXT, ' ', 0x3c0);
conio_cursor_x = 0;
conio_cursor_y = 0;
conio_line_text = CONIO_SCREEN_TEXT;
}
// Set the cursor to the specified position
void gotoxy(unsigned char x, unsigned char y) {
if(y>CONIO_HEIGHT) y = 0;
if(x>=CONIO_WIDTH) x = 0;
conio_cursor_x = x;
conio_cursor_y = y;
unsigned int line_offset = (unsigned int)y*CONIO_WIDTH;
conio_line_text = CONIO_SCREEN_TEXT + line_offset;
}
// Return the current screen size.
void screensize(unsigned char* x, unsigned char* y) {
*x = CONIO_WIDTH;
*y = CONIO_HEIGHT;
}
// Return the current screen size X width.
inline char screensizex() {
return CONIO_WIDTH;
}
// Return the current screen size Y height.
inline char screensizey() {
return CONIO_HEIGHT;
}
// Return the X position of the cursor
inline unsigned char wherex(void) {
return conio_cursor_x;
}
// Return the Y position of the cursor
inline unsigned char wherey(void) {
return conio_cursor_y;
}
// Output one character at the current cursor position
// Moves the cursor forward. Scrolls the entire screen if needed
void cputc(char c) {
if(c=='\n') {
cputln();
} else {
ppuDataSet(conio_line_text+conio_cursor_x, c);
if(++conio_cursor_x==CONIO_WIDTH)
cputln();
}
}
// Print a newline
void cputln() {
conio_line_text += CONIO_WIDTH;
conio_cursor_x = 0;
conio_cursor_y++;
cscroll();
}
// Scroll the entire screen if the cursor is beyond the last line
void cscroll() {
if(conio_cursor_y==CONIO_HEIGHT) {
if(conio_scroll_enable) {
// Scroll lines up
char* line1 = CONIO_SCREEN_TEXT;
char* line2 = CONIO_SCREEN_TEXT+CONIO_WIDTH;
for(char y=0;y<CONIO_HEIGHT-1;y++) {
for(char x=0;x<CONIO_WIDTH;x++) {
char ch = ppuDataGet(line2++);
ppuDataSet(line1++, ch);
}
}
// Fill last line with space
ppuDataFill(CONIO_SCREEN_TEXT+CONIO_BYTES-CONIO_WIDTH, ' ', CONIO_WIDTH);
conio_line_text -= CONIO_WIDTH;
conio_cursor_y--;
} else {
gotoxy(0,0);
}
}
}
// Output a NUL-terminated string at the current cursor position
void cputs(const char* s) {
char c;
while(c=*s++)
cputc(c);
}
// Move cursor and output one character
// Same as "gotoxy (x, y); cputc (c);"
void cputcxy(unsigned char x, unsigned char y, char c) {
gotoxy(x, y);
cputc(c);
}
// Move cursor and output a NUL-terminated string
// Same as "gotoxy (x, y); puts (s);"
void cputsxy(unsigned char x, unsigned char y, const char* s) {
gotoxy(x, y);
cputs(s);
}
// Set the color for text output. The old color setting is returned.
unsigned char textcolor(unsigned char color) {
return 0;
}
// If onoff is 1, a cursor is displayed when waiting for keyboard input.
// If onoff is 0, the cursor is hidden when waiting for keyboard input.
// The function returns the old cursor setting.
unsigned char cursor(unsigned char onoff) {
char old = conio_display_cursor;
conio_display_cursor = onoff;
return old;
}
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
// If onoff is 1, scrolling is disabled and the cursor instead moves to (0,0)
// The function returns the old scroll setting.
unsigned char scroll(unsigned char onoff) {
char old = conio_scroll_enable;
conio_scroll_enable = onoff;
return old;
}

View File

@ -11,6 +11,8 @@
#include "conio-plus4.c"
#elif defined(__VIC20__)
#include "conio-vic20.c"
#elif defined(__NES__)
#include "conio-nes.c"
#else
#error "Target platform does not support conio.h"
#endif

View File

@ -120,6 +120,13 @@ inline void ppuDataPut(char val) {
PPU->PPUDATA = val;
}
// Read one byte from PPU memory
// The byte is read from the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
inline char ppuDataRead() {
// Transfer from PPU
return PPU->PPUDATA;
}
// Fill a number of bytes in the PPU memory
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
@ -161,4 +168,11 @@ void ppuDataPutTile(void* const ppuData, char* tile) {
void ppuDataSet(void* const ppuData, char val) {
ppuDataPrepare(ppuData);
ppuDataPut(val);
}
// Get one byte from PPU memory
// - ppuData : Pointer in the PPU memory
char ppuDataGet(void* const ppuData) {
ppuDataPrepare(ppuData);
return ppuDataRead();
}

View File

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

View File

@ -4,119 +4,74 @@
"version": "2.0.0",
"tasks": [
{
"label": "KickAssembler",
"label": "KickAsm Build & Run",
"type": "shell",
"command": "java",
"args": [
"-jar",
"${config:kickassembler.kickAssPath}",
"${file}",
"-odir",
"build",
"-showmem",
"-execute",
"${workspaceFolder}\\tools\\exomize.bat"
],
"group": "build",
"problemMatcher": []
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"windows": {
"command": "java",
"args": [
"-jar",
"KickAss.jar",
"${file}",
"-showmem",
"-vicesymbols",
"-execute",
"x64sc"
]
},
"osx": {
"command": "java",
"args": [
"-jar",
"/Applications/KickAssembler/KickAss.jar",
"${file}",
"-showmem",
"-vicesymbols",
"-execute",
"open -a x64sc"
]
}
},
{
"label": "KickAsm Vice",
"label": "KickAsm Build & Debug",
"type": "shell",
"command": "java",
"args": [
"-jar",
"${config:kickassembler.kickAssPath}",
"${file}",
"-define",
"AUTORUN",
"-showmem",
"-vicesymbols",
"-execute",
"\"${config:vice.vicePath}\" -moncommands ${fileBasenameNoExtension}.vs"
],
"group": "build"
},
{
"label": "KickAsm Vice Debug",
"type": "shell",
"command": "java",
"args": [
"-jar",
"${config:kickassembler.kickAssPath}",
"${file}",
"-odir",
"debug",
"-define",
"AUTORUN",
"-define",
"DEBUG",
"-showmem",
"-vicesymbols",
":debug=true",
"-execute",
"\"${config:vice.vicePath}\" -moncommands ${fileBasenameNoExtension}.vs"
],
"group": "build"
},
{
"label": "KickAsm C64Debugger",
"type": "shell",
"command": "java",
"args": [
"-jar",
"${config:kickassembler.kickAssPath}",
"${file}",
"-odir",
"bin",
"-define",
"AUTORUN",
"-showmem",
"-debugdump",
"-execute",
"\"${config:c64debugger.c64debuggerPath}\""
],
"group": "build"
},
{
"label": "KickAsm C64Debugger Debug",
"type": "shell",
"command": "java",
"args": [
"-jar",
"${config:kickassembler.kickAssPath}",
"${file}",
"-odir",
"debug",
"-define",
"AUTORUN",
"-define",
"DEBUG",
"-showmem",
"-debugdump",
":debug=true",
"-execute",
"\"${config:c64debugger.c64debuggerPath}\""
],
"group": "build"
},
{
"label": "KickAsm Build",
"command": "java",
"args": [
"-jar",
"${config:kickassembler.kickAssPath}",
"${file}",
"-odir",
"build",
"-showmem"
],
"group": "build"
},
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"windows": {
"command": "java",
"args": [
"-jar",
"KickAss.jar",
"${file}",
"-showmem",
"-vicesymbols",
"-execute",
"C64Debugger"
]
},
"osx": {
"command": "java",
"args": [
"-jar",
"/Applications/KickAssembler/KickAss.jar",
"${file}",
"-showmem",
"-vicesymbols",
"-execute",
"open -a C64Debugger"
]
}
},
{
"label": "KickC Build & Run",
"type": "shell",
"cwd": "${workspaceFolder}",
"group": {
"kind": "build",
"isDefault": true
@ -130,7 +85,8 @@
"c:/c64/tmp/",
"-e",
"${relativeFile}"
] },
]
},
"osx": {
"command": "~/c64/kickc_local/bin/kickc.sh",
"args": [
@ -141,18 +97,9 @@
"${relativeFile}"
]
}
},
{
"label": "Exomize Build",
"command": "${workspaceFolder}\\tools\\exomize.bat",
"args": [
"${config:exomizer.exomizerPath}",
"${file}"
],
"dependsOn": [
"KickAsm Build"
],
"group": "build"
}
}
]
}
}

View File

@ -0,0 +1,96 @@
// NES conio printing
#pragma target(nes)
#include <nes.h>
#include <conio.h>
// RESET Called when the NES is reset, including when it is turned on.
void main() {
// Initialize NES after RESET
initNES();
// Transfer the palette
ppuDataTransfer(PPU_PALETTE, PALETTE, sizeof(PALETTE));
// Fill the PPU attribute table
ppuDataFill(PPU_ATTRIBUTE_TABLE_0, 0, 0x40);
ppuDataFill(PPU_ATTRIBUTE_TABLE_1, 0, 0x40);
// Print a string
clrscr();
cputs("hello world!\ni am nes\n look at me \n\n");
x_scroll = 0;
y_scroll = -8;
// Enable screen rendering and vblank
enableVideoOutput();
// Infinite loop
while(1) {
}
}
volatile char x_scroll;
volatile char y_scroll;
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
interrupt(hardware_stack) void vblank() {
// Read controller 1
char joy = readJoy1();
if(joy&JOY_DOWN) {
if(++y_scroll==240)
y_scroll=0;
}
if(joy&JOY_UP) {
if(--y_scroll==255)
y_scroll=239;
}
if(joy&JOY_LEFT) {
x_scroll++;
}
if(joy&JOY_RIGHT) {
x_scroll--;
}
PPU->PPUSCROLL = x_scroll;
PPU->PPUSCROLL = y_scroll;
}
// Data (in PRG ROM)
#pragma data_seg(Data)
char MESSAGE[] = "hello world!";
// Color Palette
char PALETTE[0x20] = {
// Background palettes
0x01, 0x21, 0x0f, 0x30, // C64 colors
0x01, 0x21, 0x0f, 0x30, // C64 colors
0x01, 0x21, 0x0f, 0x30, // C64 colors
0x01, 0x21, 0x0f, 0x30, // C64 colors
// Sprite palettes (selected by the attribute bits 0-1 of the sprites)
0x01, 0x0f, 0x30, 0x08, // Goomba upper colors
0x01, 0x0f, 0x18, 0x08, // Goomba lower colors
0x01, 0x30, 0x37, 0x1a, // Luigi-like colors
0x0f, 0x0f, 0x0f, 0x0f // All black
};
// Tile Set (in CHR ROM) - A C64 charset from http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/
#pragma data_seg(Tiles)
export char TILES[] = kickasm(resource "characters.901225-01.bin") {{
.var filechargen = LoadBinary("characters.901225-01.bin")
.for(var c=0; c<256; c++) {
// Plane 0
.fill 8, filechargen.get(c*8+i)
// Plane 1
.fill 8, 0
}
}};
// Interrupt Vectors (in PRG ROM)
#pragma data_seg(Vectors)
export void()* const VECTORS[] = {
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
&vblank,
// RESET Called when the NES is reset, including when it is turned on.
&main,
// IRQ Called when a BRK instruction is executed.
0
};

View File

@ -0,0 +1,674 @@
// NES conio printing
// Nintendo Entertainment System (NES
// https://en.wikipedia.org/wiki/Nintendo_Entertainment_System_(Model_NES-101)
// https://github.com/gregkrsak/first_nes
// Ricoh 2C02 - NES Picture Processing Unit (PPU)
// Ricoh RP2C02 (NTSC version) / RP2C07 (PAL version),
// https://en.wikipedia.org/wiki/Picture_Processing_Unit
// https://wiki.nesdev.com/w/index.php/PPU_registers
// http://nesdev.com/2C02%20technical%20reference.TXT
// Based on: https://github.com/gregkrsak/first_nes written by Greg M. Krsak, 2018.
// Nintendo Entertainment System (NES) ROM
// https://sadistech.com/nesromtool/romdoc.html
// https://forums.nesdev.com/viewtopic.php?f=2&t=9896
// https://github.com/gregkrsak/first_nes
.file [name="nes-conio.nes", type="bin", segments="NesRom"]
.file [name="nes-conio.nes_hdr", type="bin", segments="Header"]
.file [name="nes-conio.nes_prg", type="bin", segments="ProgramRom"]
.file [name="nes-conio.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
// Standard Controller Right Button
.const JOY_RIGHT = 1
// Standard Controller Left Button
.const JOY_LEFT = 2
// Standard Controller Down Button
.const JOY_DOWN = 4
// Standard Controller Up Button
.const JOY_UP = 8
.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_RICOH_2C02_PPUADDR = 6
.const OFFSET_STRUCT_RICOH_2C02_PPUDATA = 7
.const OFFSET_STRUCT_RICOH_2C02_PPUSCROLL = 5
.const SIZEOF_BYTE = 1
// $2000-$23bf $03c0 Name table 0
.label PPU_NAME_TABLE_0 = $2000
// $23c0-$23ff $0040 Attribute table 0
.label PPU_ATTRIBUTE_TABLE_0 = $23c0
// $27c0-$27ff $0040 Attribute table 1
.label PPU_ATTRIBUTE_TABLE_1 = $27c0
// $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.
// 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
// PPU Status Register for reading in ASM
.label PPU_PPUSTATUS = $2002
// NES Picture Processing Unit (PPU)
.label PPU = $2000
// NES CPU and audion processing unit (APU)
.label APU = $4000
.label conio_cursor_x = $b
.label conio_cursor_y = $c
.label conio_line_text = $d
.label x_scroll = $f
.label y_scroll = $10
__bbegin:
// conio_cursor_x = 0
// The current cursor x-position
lda #0
sta.z conio_cursor_x
// conio_cursor_y = 0
// The current cursor y-position
sta.z conio_cursor_y
// conio_line_text = CONIO_SCREEN_TEXT
// The current text cursor line start
lda #<PPU_NAME_TABLE_0
sta.z conio_line_text
lda #>PPU_NAME_TABLE_0
sta.z conio_line_text+1
// x_scroll
lda #0
sta.z x_scroll
// y_scroll
sta.z y_scroll
jsr main
rts
.segment Code
// RESET Called when the NES is reset, including when it is turned on.
main: {
// asm
cld
ldx #$ff
txs
// PPU->PPUCTRL = 0
lda #0
sta PPU
// PPU->PPUMASK = 0
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUMASK
// *FR_COUNTER = 0b01000000
lda #$40
sta FR_COUNTER
// APU->DMC_FREQ = 0b01000000
sta APU+OFFSET_STRUCT_RICOH_2A03_DMC_FREQ
// asm
lda PPU_PPUSTATUS
initNES1_waitForVBlank1:
// PPU->PPUSTATUS&0x80
lda #$80
and PPU+OFFSET_STRUCT_RICOH_2C02_PPUSTATUS
// while(!(PPU->PPUSTATUS&0x80))
cmp #0
beq initNES1_waitForVBlank1
ldx #0
initNES1___b1:
// (MEMORY+0x000)[i] = 0
lda #0
sta MEMORY,x
// (MEMORY+0x100)[i] = 0
sta MEMORY+$100,x
// (MEMORY+0x200)[i] = 0
sta MEMORY+$200,x
// (MEMORY+0x300)[i] = 0
sta MEMORY+$300,x
// (MEMORY+0x400)[i] = 0
sta MEMORY+$400,x
// (MEMORY+0x500)[i] = 0
sta MEMORY+$500,x
// (MEMORY+0x600)[i] = 0
sta MEMORY+$600,x
// (MEMORY+0x700)[i] = 0
sta MEMORY+$700,x
// while (++i)
inx
cpx #0
bne initNES1___b1
initNES1_waitForVBlank2:
// PPU->PPUSTATUS&0x80
lda #$80
and PPU+OFFSET_STRUCT_RICOH_2C02_PPUSTATUS
// while(!(PPU->PPUSTATUS&0x80))
cmp #0
beq initNES1_waitForVBlank2
// asm
lda PPU_PPUSTATUS
// ppuDataTransfer(PPU_PALETTE, PALETTE, sizeof(PALETTE))
// Transfer the palette
jsr ppuDataTransfer
// ppuDataFill(PPU_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
// ppuDataFill(PPU_ATTRIBUTE_TABLE_1, 0, 0x40)
ldx #0
lda #<$40
sta.z ppuDataFill.size
lda #>$40
sta.z ppuDataFill.size+1
lda #<PPU_ATTRIBUTE_TABLE_1
sta.z ppuDataFill.ppuDataPrepare1_ppuData
lda #>PPU_ATTRIBUTE_TABLE_1
sta.z ppuDataFill.ppuDataPrepare1_ppuData+1
jsr ppuDataFill
// clrscr()
// Print a string
jsr clrscr
// cputs("hello world!\ni am nes\n look at me \n\n")
jsr cputs
// x_scroll = 0
lda #0
sta.z x_scroll
// y_scroll = -8
lda #-8
sta.z y_scroll
// PPU->PPUCTRL = 0b10000000
lda #$80
sta PPU
// PPU->PPUMASK = 0b00011110
lda #$1e
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUMASK
__b1:
// Infinite loop
jmp __b1
.segment Data
s: .text @"hello world!\ni am nes\n look at me \n\n"
.byte 0
}
.segment Code
// Output a NUL-terminated string at the current cursor position
// cputs(byte* zp(7) s)
cputs: {
.label s = 7
lda #<main.s
sta.z s
lda #>main.s
sta.z s+1
__b1:
// c=*s++
ldy #0
lda (s),y
// while(c=*s++)
inc.z s
bne !+
inc.z s+1
!:
cmp #0
bne __b2
// }
rts
__b2:
// cputc(c)
tax
jsr cputc
jmp __b1
}
// Output one character at the current cursor position
// Moves the cursor forward. Scrolls the entire screen if needed
// cputc(byte register(X) c)
cputc: {
// if(c=='\n')
cpx #'\n'
beq __b1
// conio_line_text+conio_cursor_x
lda.z conio_cursor_x
clc
adc.z conio_line_text
sta.z ppuDataSet.ppuData
lda #0
adc.z conio_line_text+1
sta.z ppuDataSet.ppuData+1
// ppuDataSet(conio_line_text+conio_cursor_x, c)
// ppuDataSet(conio_line_text+conio_cursor_x, c)
jsr ppuDataSet
// if(++conio_cursor_x==CONIO_WIDTH)
inc.z conio_cursor_x
lda #$20
cmp.z conio_cursor_x
bne __breturn
// cputln()
jsr cputln
__breturn:
// }
rts
__b1:
// cputln()
jsr cputln
rts
}
// Print a newline
cputln: {
// conio_line_text += CONIO_WIDTH
lda #$20
clc
adc.z conio_line_text
sta.z conio_line_text
bcc !+
inc.z conio_line_text+1
!:
// conio_cursor_x = 0
lda #0
sta.z conio_cursor_x
// conio_cursor_y++;
inc.z conio_cursor_y
// cscroll()
jsr cscroll
// }
rts
}
// Scroll the entire screen if the cursor is beyond the last line
cscroll: {
.label line2 = 9
// Scroll lines up
.label line1 = 3
.label y = 2
// if(conio_cursor_y==CONIO_HEIGHT)
lda #$1e
cmp.z conio_cursor_y
bne __breturn
lda #<PPU_NAME_TABLE_0
sta.z line1
lda #>PPU_NAME_TABLE_0
sta.z line1+1
lda #<PPU_NAME_TABLE_0+$20
sta.z line2
lda #>PPU_NAME_TABLE_0+$20
sta.z line2+1
lda #0
sta.z y
__b1:
// for(char y=0;y<CONIO_HEIGHT-1;y++)
lda.z y
cmp #$1e-1
bcc __b2
// ppuDataFill(CONIO_SCREEN_TEXT+CONIO_BYTES-CONIO_WIDTH, ' ', CONIO_WIDTH)
// Fill last line with space
ldx #' '
lda #<$20
sta.z ppuDataFill.size
lda #>$20
sta.z ppuDataFill.size+1
lda #<PPU_NAME_TABLE_0+$1e*$20-$20
sta.z ppuDataFill.ppuDataPrepare1_ppuData
lda #>PPU_NAME_TABLE_0+$1e*$20-$20
sta.z ppuDataFill.ppuDataPrepare1_ppuData+1
jsr ppuDataFill
// conio_line_text -= CONIO_WIDTH
sec
lda.z conio_line_text
sbc #$20
sta.z conio_line_text
lda.z conio_line_text+1
sbc #0
sta.z conio_line_text+1
// conio_cursor_y--;
dec.z conio_cursor_y
__breturn:
// }
rts
__b2:
ldy #0
__b3:
// for(char x=0;x<CONIO_WIDTH;x++)
cpy #$20
bcc __b4
// for(char y=0;y<CONIO_HEIGHT-1;y++)
inc.z y
jmp __b1
__b4:
// ppuDataGet(line2++)
lda.z line2
sta.z ppuDataGet.ppuData
lda.z line2+1
sta.z ppuDataGet.ppuData+1
jsr ppuDataGet
// ppuDataGet(line2++)
// ch = ppuDataGet(line2++)
tax
inc.z line2
bne !+
inc.z line2+1
!:
// ppuDataSet(line1++, ch)
lda.z line1
sta.z ppuDataSet.ppuData
lda.z line1+1
sta.z ppuDataSet.ppuData+1
jsr ppuDataSet
// ppuDataSet(line1++, ch);
inc.z line1
bne !+
inc.z line1+1
!:
// for(char x=0;x<CONIO_WIDTH;x++)
iny
jmp __b3
}
// Set one byte in PPU memory
// - ppuData : Pointer in the PPU memory
// - val : The value to set
// ppuDataSet(byte* zp(5) ppuData, byte register(X) val)
ppuDataSet: {
.label ppuDataPrepare1_ppuData = 5
.label ppuData = 5
// >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
// PPU->PPUDATA = val
stx PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// }
rts
}
// Get one byte from PPU memory
// - ppuData : Pointer in the PPU memory
// ppuDataGet(void* zp($11) ppuData)
ppuDataGet: {
.label ppuData = $11
// >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
// return PPU->PPUDATA;
lda PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// }
rts
}
// 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($11) size)
ppuDataFill: {
.label ppuDataPrepare1_ppuData = 5
.label i = 9
.label size = $11
// >ppuData
lda.z ppuDataPrepare1_ppuData+1
// PPU->PPUADDR = >ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// <ppuData
lda.z ppuDataPrepare1_ppuData
// PPU->PPUADDR = <ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
lda #<0
sta.z i
sta.z i+1
// Transfer to PPU
__b1:
// for(unsigned int i=0;i<size;i++)
lda.z i+1
cmp.z size+1
bcc ppuDataPut1
bne !+
lda.z i
cmp.z size
bcc ppuDataPut1
!:
// }
rts
ppuDataPut1:
// PPU->PPUDATA = val
stx PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// for(unsigned int i=0;i<size;i++)
inc.z i
bne !+
inc.z i+1
!:
jmp __b1
}
// clears the screen and moves the cursor to the upper left-hand corner of the screen.
clrscr: {
// ppuDataFill(CONIO_SCREEN_TEXT, ' ', 0x3c0)
ldx #' '
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
// conio_cursor_x = 0
lda #0
sta.z conio_cursor_x
// conio_cursor_y = 0
sta.z conio_cursor_y
// conio_line_text = CONIO_SCREEN_TEXT
lda #<PPU_NAME_TABLE_0
sta.z conio_line_text
lda #>PPU_NAME_TABLE_0
sta.z conio_line_text+1
// }
rts
}
// 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 = 9
.label i = 7
// PPU->PPUADDR = >ppuData
lda #>ppuData
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
// PPU->PPUADDR = <ppuData
lda #0
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUADDR
lda #<cpuData
sta.z cpuSrc
lda #>cpuData
sta.z cpuSrc+1
lda #<0
sta.z i
sta.z i+1
__b1:
// for(unsigned int i=0;i<size;i++)
lda.z i+1
cmp #>size
bcc __b2
bne !+
lda.z i
cmp #<size
bcc __b2
!:
// }
rts
__b2:
// ppuDataPut(*cpuSrc++)
ldy #0
lda (cpuSrc),y
// PPU->PPUDATA = val
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUDATA
// ppuDataPut(*cpuSrc++);
inc.z cpuSrc
bne !+
inc.z cpuSrc+1
!:
// for(unsigned int i=0;i<size;i++)
inc.z i
bne !+
inc.z i+1
!:
jmp __b1
}
// NMI Called when the PPU refreshes the screen (also known as the V-Blank period)
vblank: {
pha
txa
pha
tya
pha
// readJoy1()
jsr readJoy1
// joy = readJoy1()
tax
// joy&JOY_DOWN
txa
and #JOY_DOWN
// if(joy&JOY_DOWN)
cmp #0
beq __b1
// if(++y_scroll==240)
inc.z y_scroll
lda #$f0
cmp.z y_scroll
bne __b1
// y_scroll=0
lda #0
sta.z y_scroll
__b1:
// joy&JOY_UP
txa
and #JOY_UP
// if(joy&JOY_UP)
cmp #0
beq __b2
// if(--y_scroll==255)
dec.z y_scroll
lda #$ff
cmp.z y_scroll
bne __b2
// y_scroll=239
lda #$ef
sta.z y_scroll
__b2:
// joy&JOY_LEFT
txa
and #JOY_LEFT
// if(joy&JOY_LEFT)
cmp #0
beq __b3
// x_scroll++;
inc.z x_scroll
__b3:
// joy&JOY_RIGHT
txa
and #JOY_RIGHT
// if(joy&JOY_RIGHT)
cmp #0
beq __b4
// x_scroll--;
dec.z x_scroll
__b4:
// PPU->PPUSCROLL = x_scroll
lda.z x_scroll
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
// PPU->PPUSCROLL = y_scroll
lda.z y_scroll
sta PPU+OFFSET_STRUCT_RICOH_2C02_PPUSCROLL
// }
pla
tay
pla
tax
pla
rti
}
// Read Standard Controller #1
// Returns a byte representing the pushed buttons
// - bit 0: right
// - bit 1: left
// - bit 2: down
// - bit 3: up
// - bit 4: start
// - bit 5: select
// - bit 6: B
// - bit 7: A
readJoy1: {
.label __1 = $13
// APU->JOY1 = 1
// Latch the controller buttons
lda #1
sta APU+OFFSET_STRUCT_RICOH_2A03_JOY1
// APU->JOY1 = 0
lda #0
sta APU+OFFSET_STRUCT_RICOH_2A03_JOY1
tax
__b1:
// for(char i=0;i<8;i++)
cpx #8
bcc __b2
// }
rts
__b2:
// joy<<1
asl
sta.z __1
// APU->JOY1&1
lda #1
and APU+OFFSET_STRUCT_RICOH_2A03_JOY1
// joy = joy<<1 | APU->JOY1&1
ora.z __1
// for(char i=0;i<8;i++)
inx
jmp __b1
}
.segment Data
// Color Palette
PALETTE: .byte 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $21, $f, $30, 1, $f, $30, 8, 1, $f, $18, 8, 1, $30, $37, $1a, $f, $f, $f, $f
.segment Tiles
TILES:
.var filechargen = LoadBinary("characters.901225-01.bin")
.for(var c=0; c<256; c++) {
// Plane 0
.fill 8, filechargen.get(c*8+i)
// Plane 1
.fill 8, 0
}
.segment Vectors
VECTORS: .word vblank, main, 0

View File

@ -0,0 +1,374 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] (byte) conio_cursor_x ← (byte) 0
[2] (byte) conio_cursor_y ← (byte) 0
[3] (byte*) conio_line_text ← (const nomodify byte*) PPU_NAME_TABLE_0
to:@2
@2: scope:[] from @1
[4] (volatile byte) x_scroll ← (byte) 0
[5] (volatile byte) y_scroll ← (byte) 0
to:@3
@3: scope:[] from @2
[6] phi()
[7] call main
to:@end
@end: scope:[] from @3
[8] phi()
(void()) main()
main: scope:[main] from @3
[9] 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
[11] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) 0
[12] *((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
[13] *((const nomodify byte*) FR_COUNTER) ← (byte) $40
[14] *((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
[16] phi()
to:main::initNES1_waitForVBlank1_@1
main::initNES1_waitForVBlank1_@1: scope:[main] from main::initNES1_waitForVBlank1 main::initNES1_waitForVBlank1_@1
[17] (byte~) main::initNES1_waitForVBlank1_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[18] 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
[19] (byte) main::initNES1_i#2 ← phi( main::initNES1_@1/(byte) main::initNES1_i#1 main::initNES1_waitForVBlank1_@1/(byte) 0 )
[20] *((const nomodify byte*) MEMORY + (byte) main::initNES1_i#2) ← (byte) 0
[21] *((const nomodify byte*) MEMORY+(word) $100 + (byte) main::initNES1_i#2) ← (byte) 0
[22] *((const nomodify byte*) MEMORY+(word) $200 + (byte) main::initNES1_i#2) ← (byte) 0
[23] *((const nomodify byte*) MEMORY+(word) $300 + (byte) main::initNES1_i#2) ← (byte) 0
[24] *((const nomodify byte*) MEMORY+(word) $400 + (byte) main::initNES1_i#2) ← (byte) 0
[25] *((const nomodify byte*) MEMORY+(word) $500 + (byte) main::initNES1_i#2) ← (byte) 0
[26] *((const nomodify byte*) MEMORY+(word) $600 + (byte) main::initNES1_i#2) ← (byte) 0
[27] *((const nomodify byte*) MEMORY+(word) $700 + (byte) main::initNES1_i#2) ← (byte) 0
[28] (byte) main::initNES1_i#1 ← ++ (byte) main::initNES1_i#2
[29] 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
[30] phi()
to:main::initNES1_waitForVBlank2_@1
main::initNES1_waitForVBlank2_@1: scope:[main] from main::initNES1_waitForVBlank2 main::initNES1_waitForVBlank2_@1
[31] (byte~) main::initNES1_waitForVBlank2_$0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSTATUS) & (byte) $80
[32] 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::@2
main::@2: scope:[main] from main::initNES1_@7
[34] phi()
[35] call ppuDataTransfer
to:main::@3
main::@3: scope:[main] from main::@2
[36] phi()
[37] call ppuDataFill
to:main::@4
main::@4: scope:[main] from main::@3
[38] phi()
[39] call ppuDataFill
to:main::@5
main::@5: scope:[main] from main::@4
[40] phi()
[41] call clrscr
to:main::@6
main::@6: scope:[main] from main::@5
[42] phi()
[43] call cputs
to:main::@7
main::@7: scope:[main] from main::@6
[44] (volatile byte) x_scroll ← (byte) 0
[45] (volatile byte) y_scroll ← (byte) -8
to:main::enableVideoOutput1
main::enableVideoOutput1: scope:[main] from main::@7
[46] *((byte*)(const struct RICOH_2C02*) PPU) ← (byte) $80
[47] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUMASK) ← (byte) $1e
to:main::@1
main::@1: scope:[main] from main::@1 main::enableVideoOutput1
[48] phi()
to:main::@1
(void()) cputs((to_nomodify byte*) cputs::s)
cputs: scope:[cputs] from main::@6
[49] phi()
to:cputs::@1
cputs::@1: scope:[cputs] from cputs cputs::@2
[50] (to_nomodify byte*) cputs::s#2 ← phi( cputs/(const byte*) main::s cputs::@2/(to_nomodify byte*) cputs::s#0 )
[51] (byte) cputs::c#1 ← *((to_nomodify byte*) cputs::s#2)
[52] (to_nomodify byte*) cputs::s#0 ← ++ (to_nomodify byte*) cputs::s#2
[53] if((byte) 0!=(byte) cputs::c#1) goto cputs::@2
to:cputs::@return
cputs::@return: scope:[cputs] from cputs::@1
[54] return
to:@return
cputs::@2: scope:[cputs] from cputs::@1
[55] (byte) cputc::c#0 ← (byte) cputs::c#1
[56] call cputc
to:cputs::@1
(void()) cputc((byte) cputc::c)
cputc: scope:[cputc] from cputs::@2
[57] if((byte) cputc::c#0==(byte) '
') goto cputc::@1
to:cputc::@2
cputc::@2: scope:[cputc] from cputc
[58] (nomodify byte*) ppuDataSet::ppuData#0 ← (byte*) conio_line_text + (byte) conio_cursor_x
[59] (byte) ppuDataSet::val#0 ← (byte) cputc::c#0
[60] (nomodify void*) ppuDataSet::ppuDataPrepare1_ppuData#2 ← (void*)(nomodify byte*) ppuDataSet::ppuData#0
[61] call ppuDataSet
to:cputc::@4
cputc::@4: scope:[cputc] from cputc::@2
[62] (byte) conio_cursor_x ← ++ (byte) conio_cursor_x
[63] if((byte) conio_cursor_x!=(byte) $20) goto cputc::@return
to:cputc::@3
cputc::@3: scope:[cputc] from cputc::@4
[64] phi()
[65] call cputln
to:cputc::@return
cputc::@return: scope:[cputc] from cputc::@1 cputc::@3 cputc::@4
[66] return
to:@return
cputc::@1: scope:[cputc] from cputc
[67] phi()
[68] call cputln
to:cputc::@return
(void()) cputln()
cputln: scope:[cputln] from cputc::@1 cputc::@3
[69] (byte*) conio_line_text ← (byte*) conio_line_text + (byte) $20
[70] (byte) conio_cursor_x ← (byte) 0
[71] (byte) conio_cursor_y ← ++ (byte) conio_cursor_y
[72] call cscroll
to:cputln::@return
cputln::@return: scope:[cputln] from cputln
[73] return
to:@return
(void()) cscroll()
cscroll: scope:[cscroll] from cputln
[74] if((byte) conio_cursor_y!=(byte) $1e) goto cscroll::@return
to:cscroll::@1
cscroll::@1: scope:[cscroll] from cscroll cscroll::@5
[75] (byte*) cscroll::line1#6 ← phi( cscroll/(const nomodify byte*) PPU_NAME_TABLE_0 cscroll::@5/(byte*) cscroll::line1#2 )
[75] (byte*) cscroll::line2#6 ← phi( cscroll/(const nomodify byte*) PPU_NAME_TABLE_0+(byte) $20 cscroll::@5/(byte*) cscroll::line2#2 )
[75] (byte) cscroll::y#2 ← phi( cscroll/(byte) 0 cscroll::@5/(byte) cscroll::y#1 )
[76] if((byte) cscroll::y#2<(byte)(number) $1e-(number) 1) goto cscroll::@3
to:cscroll::@2
cscroll::@2: scope:[cscroll] from cscroll::@1
[77] phi()
[78] call ppuDataFill
to:cscroll::@6
cscroll::@6: scope:[cscroll] from cscroll::@2
[79] (byte*) conio_line_text ← (byte*) conio_line_text - (byte) $20
[80] (byte) conio_cursor_y ← -- (byte) conio_cursor_y
to:cscroll::@return
cscroll::@return: scope:[cscroll] from cscroll cscroll::@6
[81] return
to:@return
cscroll::@3: scope:[cscroll] from cscroll::@1 cscroll::@8
[82] (byte*) cscroll::line1#2 ← phi( cscroll::@8/(byte*) cscroll::line1#1 cscroll::@1/(byte*) cscroll::line1#6 )
[82] (byte*) cscroll::line2#2 ← phi( cscroll::@8/(byte*) cscroll::line2#1 cscroll::@1/(byte*) cscroll::line2#6 )
[82] (byte) cscroll::x#2 ← phi( cscroll::@8/(byte) cscroll::x#1 cscroll::@1/(byte) 0 )
[83] if((byte) cscroll::x#2<(byte) $20) goto cscroll::@4
to:cscroll::@5
cscroll::@5: scope:[cscroll] from cscroll::@3
[84] (byte) cscroll::y#1 ← ++ (byte) cscroll::y#2
to:cscroll::@1
cscroll::@4: scope:[cscroll] from cscroll::@3
[85] (nomodify void*) ppuDataGet::ppuData#0 ← (void*)(byte*) cscroll::line2#2
[86] call ppuDataGet
[87] (byte) ppuDataGet::return#2 ← (byte) ppuDataGet::ppuDataRead1_return#0
to:cscroll::@7
cscroll::@7: scope:[cscroll] from cscroll::@4
[88] (byte) cscroll::ch#0 ← (byte) ppuDataGet::return#2
[89] (byte*) cscroll::line2#1 ← ++ (byte*) cscroll::line2#2
[90] (nomodify void*) ppuDataSet::ppuData#1 ← (void*)(byte*) cscroll::line1#2
[91] (byte) ppuDataSet::val#1 ← (byte) cscroll::ch#0
[92] call ppuDataSet
to:cscroll::@8
cscroll::@8: scope:[cscroll] from cscroll::@7
[93] (byte*) cscroll::line1#1 ← ++ (byte*) cscroll::line1#2
[94] (byte) cscroll::x#1 ← ++ (byte) cscroll::x#2
to:cscroll::@3
(void()) ppuDataSet((nomodify void*) ppuDataSet::ppuData , (byte) ppuDataSet::val)
ppuDataSet: scope:[ppuDataSet] from cputc::@2 cscroll::@7
[95] (byte) ppuDataSet::val#2 ← phi( cputc::@2/(byte) ppuDataSet::val#0 cscroll::@7/(byte) ppuDataSet::val#1 )
[95] (nomodify void*) ppuDataSet::ppuDataPrepare1_ppuData#0 ← phi( cputc::@2/(nomodify void*) ppuDataSet::ppuDataPrepare1_ppuData#2 cscroll::@7/(nomodify void*) ppuDataSet::ppuData#1 )
to:ppuDataSet::ppuDataPrepare1
ppuDataSet::ppuDataPrepare1: scope:[ppuDataSet] from ppuDataSet
[96] (byte~) ppuDataSet::ppuDataPrepare1_$0 ← > (nomodify void*) ppuDataSet::ppuDataPrepare1_ppuData#0
[97] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataSet::ppuDataPrepare1_$0
[98] (byte~) ppuDataSet::ppuDataPrepare1_$1 ← < (nomodify void*) ppuDataSet::ppuDataPrepare1_ppuData#0
[99] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataSet::ppuDataPrepare1_$1
to:ppuDataSet::ppuDataPut1
ppuDataSet::ppuDataPut1: scope:[ppuDataSet] from ppuDataSet::ppuDataPrepare1
[100] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataSet::val#2
to:ppuDataSet::@return
ppuDataSet::@return: scope:[ppuDataSet] from ppuDataSet::ppuDataPut1
[101] return
to:@return
(byte()) ppuDataGet((nomodify void*) ppuDataGet::ppuData)
ppuDataGet: scope:[ppuDataGet] from cscroll::@4
[102] phi()
to:ppuDataGet::ppuDataPrepare1
ppuDataGet::ppuDataPrepare1: scope:[ppuDataGet] from ppuDataGet
[103] (byte~) ppuDataGet::ppuDataPrepare1_$0 ← > (nomodify void*) ppuDataGet::ppuData#0
[104] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataGet::ppuDataPrepare1_$0
[105] (byte~) ppuDataGet::ppuDataPrepare1_$1 ← < (nomodify void*) ppuDataGet::ppuData#0
[106] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataGet::ppuDataPrepare1_$1
to:ppuDataGet::ppuDataRead1
ppuDataGet::ppuDataRead1: scope:[ppuDataGet] from ppuDataGet::ppuDataPrepare1
[107] (byte) ppuDataGet::ppuDataRead1_return#0 ← *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA)
to:ppuDataGet::@return
ppuDataGet::@return: scope:[ppuDataGet] from ppuDataGet::ppuDataRead1
[108] return
to:@return
(void()) ppuDataFill((nomodify void*) ppuDataFill::ppuData , (byte) ppuDataFill::val , (word) ppuDataFill::size)
ppuDataFill: scope:[ppuDataFill] from clrscr cscroll::@2 main::@3 main::@4
[109] (byte) ppuDataFill::val#10 ← phi( clrscr/(byte) ' ' cscroll::@2/(byte) ' ' main::@3/(byte) 0 main::@4/(byte) 0 )
[109] (word) ppuDataFill::size#5 ← phi( clrscr/(word) $3c0 cscroll::@2/(byte) $20 main::@3/(byte) $40 main::@4/(byte) $40 )
[109] (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0 ← phi( clrscr/(void*)(const nomodify byte*) PPU_NAME_TABLE_0 cscroll::@2/(void*)(const nomodify byte*) PPU_NAME_TABLE_0+(word)(number) $1e*(number) $20-(byte) $20 main::@3/(void*)(const nomodify byte*) PPU_ATTRIBUTE_TABLE_0 main::@4/(void*)(const nomodify byte*) PPU_ATTRIBUTE_TABLE_1 )
to:ppuDataFill::ppuDataPrepare1
ppuDataFill::ppuDataPrepare1: scope:[ppuDataFill] from ppuDataFill
[110] (byte~) ppuDataFill::ppuDataPrepare1_$0 ← > (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0
[111] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← (byte~) ppuDataFill::ppuDataPrepare1_$0
[112] (byte~) ppuDataFill::ppuDataPrepare1_$1 ← < (nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0
[113] *((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
[114] (word) ppuDataFill::i#2 ← phi( ppuDataFill::ppuDataPrepare1/(word) 0 ppuDataFill::@2/(word) ppuDataFill::i#1 )
[115] if((word) ppuDataFill::i#2<(word) ppuDataFill::size#5) goto ppuDataFill::ppuDataPut1
to:ppuDataFill::@return
ppuDataFill::@return: scope:[ppuDataFill] from ppuDataFill::@1
[116] return
to:@return
ppuDataFill::ppuDataPut1: scope:[ppuDataFill] from ppuDataFill::@1
[117] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUDATA) ← (byte) ppuDataFill::val#10
to:ppuDataFill::@2
ppuDataFill::@2: scope:[ppuDataFill] from ppuDataFill::ppuDataPut1
[118] (word) ppuDataFill::i#1 ← ++ (word) ppuDataFill::i#2
to:ppuDataFill::@1
(void()) clrscr()
clrscr: scope:[clrscr] from main::@5
[119] phi()
[120] call ppuDataFill
to:clrscr::@1
clrscr::@1: scope:[clrscr] from clrscr
[121] (byte) conio_cursor_x ← (byte) 0
[122] (byte) conio_cursor_y ← (byte) 0
[123] (byte*) conio_line_text ← (const nomodify byte*) PPU_NAME_TABLE_0
to:clrscr::@return
clrscr::@return: scope:[clrscr] from clrscr::@1
[124] return
to:@return
(void()) ppuDataTransfer((nomodify void*) ppuDataTransfer::ppuData , (nomodify void*) ppuDataTransfer::cpuData , (word) ppuDataTransfer::size)
ppuDataTransfer: scope:[ppuDataTransfer] from main::@2
[125] phi()
to:ppuDataTransfer::ppuDataPrepare1
ppuDataTransfer::ppuDataPrepare1: scope:[ppuDataTransfer] from ppuDataTransfer
[126] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUADDR) ← >(const nomodify void*) ppuDataTransfer::ppuData#0
[127] *((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
[128] (byte*) ppuDataTransfer::cpuSrc#2 ← phi( ppuDataTransfer::ppuDataPrepare1/(byte*)(const nomodify void*) ppuDataTransfer::cpuData#0 ppuDataTransfer::@3/(byte*) ppuDataTransfer::cpuSrc#1 )
[128] (word) ppuDataTransfer::i#2 ← phi( ppuDataTransfer::ppuDataPrepare1/(word) 0 ppuDataTransfer::@3/(word) ppuDataTransfer::i#1 )
[129] if((word) ppuDataTransfer::i#2<(const word) ppuDataTransfer::size#0) goto ppuDataTransfer::@2
to:ppuDataTransfer::@return
ppuDataTransfer::@return: scope:[ppuDataTransfer] from ppuDataTransfer::@1
[130] return
to:@return
ppuDataTransfer::@2: scope:[ppuDataTransfer] from ppuDataTransfer::@1
[131] (byte) ppuDataTransfer::ppuDataPut1_val#0 ← *((byte*) ppuDataTransfer::cpuSrc#2)
to:ppuDataTransfer::ppuDataPut1
ppuDataTransfer::ppuDataPut1: scope:[ppuDataTransfer] from ppuDataTransfer::@2
[132] *((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
[133] (byte*) ppuDataTransfer::cpuSrc#1 ← ++ (byte*) ppuDataTransfer::cpuSrc#2
[134] (word) ppuDataTransfer::i#1 ← ++ (word) ppuDataTransfer::i#2
to:ppuDataTransfer::@1
interrupt(HARDWARE_STACK)(void()) vblank()
vblank: scope:[vblank] from
[135] phi()
[136] call readJoy1
[137] (byte) readJoy1::return#2 ← (byte) readJoy1::joy#2
to:vblank::@11
vblank::@11: scope:[vblank] from vblank
[138] (byte) vblank::joy#0 ← (byte) readJoy1::return#2
[139] (byte~) vblank::$1 ← (byte) vblank::joy#0 & (const nomodify byte) JOY_DOWN
[140] if((byte) 0==(byte~) vblank::$1) goto vblank::@1
to:vblank::@5
vblank::@5: scope:[vblank] from vblank::@11
[141] (volatile byte) y_scroll ← ++ (volatile byte) y_scroll
[142] if((volatile byte) y_scroll!=(byte) $f0) goto vblank::@1
to:vblank::@6
vblank::@6: scope:[vblank] from vblank::@5
[143] (volatile byte) y_scroll ← (byte) 0
to:vblank::@1
vblank::@1: scope:[vblank] from vblank::@11 vblank::@5 vblank::@6
[144] (byte~) vblank::$3 ← (byte) vblank::joy#0 & (const nomodify byte) JOY_UP
[145] if((byte) 0==(byte~) vblank::$3) goto vblank::@2
to:vblank::@7
vblank::@7: scope:[vblank] from vblank::@1
[146] (volatile byte) y_scroll ← -- (volatile byte) y_scroll
[147] if((volatile byte) y_scroll!=(byte) $ff) goto vblank::@2
to:vblank::@8
vblank::@8: scope:[vblank] from vblank::@7
[148] (volatile byte) y_scroll ← (byte) $ef
to:vblank::@2
vblank::@2: scope:[vblank] from vblank::@1 vblank::@7 vblank::@8
[149] (byte~) vblank::$5 ← (byte) vblank::joy#0 & (const nomodify byte) JOY_LEFT
[150] if((byte) 0==(byte~) vblank::$5) goto vblank::@3
to:vblank::@9
vblank::@9: scope:[vblank] from vblank::@2
[151] (volatile byte) x_scroll ← ++ (volatile byte) x_scroll
to:vblank::@3
vblank::@3: scope:[vblank] from vblank::@2 vblank::@9
[152] (byte~) vblank::$7 ← (byte) vblank::joy#0 & (const nomodify byte) JOY_RIGHT
[153] if((byte) 0==(byte~) vblank::$7) goto vblank::@4
to:vblank::@10
vblank::@10: scope:[vblank] from vblank::@3
[154] (volatile byte) x_scroll ← -- (volatile byte) x_scroll
to:vblank::@4
vblank::@4: scope:[vblank] from vblank::@10 vblank::@3
[155] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL) ← (volatile byte) x_scroll
[156] *((byte*)(const struct RICOH_2C02*) PPU+(const byte) OFFSET_STRUCT_RICOH_2C02_PPUSCROLL) ← (volatile byte) y_scroll
to:vblank::@return
vblank::@return: scope:[vblank] from vblank::@4
[157] return
to:@return
(byte()) readJoy1()
readJoy1: scope:[readJoy1] from vblank
[158] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) ← (byte) 1
[159] *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) ← (byte) 0
to:readJoy1::@1
readJoy1::@1: scope:[readJoy1] from readJoy1 readJoy1::@2
[160] (byte) readJoy1::joy#2 ← phi( readJoy1/(byte) 0 readJoy1::@2/(byte) readJoy1::joy#1 )
[160] (byte) readJoy1::i#2 ← phi( readJoy1/(byte) 0 readJoy1::@2/(byte) readJoy1::i#1 )
[161] if((byte) readJoy1::i#2<(byte) 8) goto readJoy1::@2
to:readJoy1::@return
readJoy1::@return: scope:[readJoy1] from readJoy1::@1
[162] return
to:@return
readJoy1::@2: scope:[readJoy1] from readJoy1::@1
[163] (byte~) readJoy1::$1 ← (byte) readJoy1::joy#2 << (byte) 1
[164] (byte~) readJoy1::$2 ← *((byte*)(const struct RICOH_2A03*) APU+(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1) & (byte) 1
[165] (byte) readJoy1::joy#1 ← (byte~) readJoy1::$1 | (byte~) readJoy1::$2
[166] (byte) readJoy1::i#1 ← ++ (byte) readJoy1::i#2
to:readJoy1::@1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,298 @@
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(const struct RICOH_2A03*) APU = (struct RICOH_2A03*) 16384
(const nomodify byte*) FR_COUNTER = (byte*) 16407
(const nomodify byte) JOY_DOWN = (byte) 4
(const nomodify byte) JOY_LEFT = (byte) 2
(const nomodify byte) JOY_RIGHT = (byte) 1
(const nomodify byte) JOY_UP = (byte) 8
(const nomodify byte*) MEMORY = (byte*) 0
(const byte) OFFSET_STRUCT_RICOH_2A03_DMC_FREQ = (byte) $10
(const byte) OFFSET_STRUCT_RICOH_2A03_JOY1 = (byte) $16
(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*) PALETTE[(number) $20] = { (byte) 1, (byte) $21, (byte) $f, (byte) $30, (byte) 1, (byte) $21, (byte) $f, (byte) $30, (byte) 1, (byte) $21, (byte) $f, (byte) $30, (byte) 1, (byte) $21, (byte) $f, (byte) $30, (byte) 1, (byte) $f, (byte) $30, (byte) 8, (byte) 1, (byte) $f, (byte) $18, (byte) 8, (byte) 1, (byte) $30, (byte) $37, (byte) $1a, (byte) $f, (byte) $f, (byte) $f, (byte) $f }
(const struct RICOH_2C02*) PPU = (struct RICOH_2C02*) 8192
(const nomodify byte*) PPU_ATTRIBUTE_TABLE_0 = (byte*) 9152
(const nomodify byte*) PPU_ATTRIBUTE_TABLE_1 = (byte*) 10176
(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
(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
(byte) SpriteData::attributes
(byte) SpriteData::tile
(byte) SpriteData::x
(byte) SpriteData::y
(const byte*) TILES[] = kickasm {{ .var filechargen = LoadBinary("characters.901225-01.bin")
.for(var c=0; c<256; c++) {
// Plane 0
.fill 8, filechargen.get(c*8+i)
// Plane 1
.fill 8, 0
}
}}
(const to_nomodify void()**) VECTORS[] = { &interrupt(HARDWARE_STACK)(void()) vblank(), &(void()) main(), (void()*) 0 }
(void()) clrscr()
(label) clrscr::@1
(label) clrscr::@return
(byte) conio_cursor_x loadstore zp[1]:11 5189.185185185185
(byte) conio_cursor_y loadstore zp[1]:12 64002.159999999996
(byte*) conio_line_text loadstore zp[2]:13 45104.24489795918
(void()) cputc((byte) cputc::c)
(label) cputc::@1
(label) cputc::@2
(label) cputc::@3
(label) cputc::@4
(label) cputc::@return
(byte) cputc::c
(byte) cputc::c#0 reg byte x 7001.0
(void()) cputln()
(label) cputln::@return
(void()) cputs((to_nomodify byte*) cputs::s)
(label) cputs::@1
(label) cputs::@2
(label) cputs::@return
(byte) cputs::c
(byte) cputs::c#1 reg byte a 1001.0
(to_nomodify byte*) cputs::s
(to_nomodify byte*) cputs::s#0 s zp[2]:7 500.5
(to_nomodify byte*) cputs::s#2 s zp[2]:7 1501.5
(void()) cscroll()
(label) cscroll::@1
(label) cscroll::@2
(label) cscroll::@3
(label) cscroll::@4
(label) cscroll::@5
(label) cscroll::@6
(label) cscroll::@7
(label) cscroll::@8
(label) cscroll::@return
(byte) cscroll::ch
(byte) cscroll::ch#0 reg byte x 6.666666673333334E8
(byte*) cscroll::line1
(byte*) cscroll::line1#1 line1 zp[2]:3 1.000000001E9
(byte*) cscroll::line1#2 line1 zp[2]:3 2.0000000036363637E8
(byte*) cscroll::line1#6 line1 zp[2]:3 1.00000001E8
(byte*) cscroll::line2
(byte*) cscroll::line2#1 line2 zp[2]:9 3.333333336666667E8
(byte*) cscroll::line2#2 line2 zp[2]:9 3.1428571485714287E8
(byte*) cscroll::line2#6 line2 zp[2]:9 1.00000001E8
(byte) cscroll::x
(byte) cscroll::x#1 reg byte y 2.000000002E9
(byte) cscroll::x#2 reg byte y 2.72727273E8
(byte) cscroll::y
(byte) cscroll::y#1 y zp[1]:2 2.00000002E8
(byte) cscroll::y#2 y zp[1]:2 2.142857164285714E7
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@5
(label) main::@6
(label) main::@7
(label) main::enableVideoOutput1
(label) main::initNES1
(label) main::initNES1_@1
(label) main::initNES1_@7
(label) main::initNES1_clearVBlankFlag1
(label) main::initNES1_disableAudioOutput1
(label) main::initNES1_disableVideoOutput1
(byte) main::initNES1_i
(byte) main::initNES1_i#1 reg byte x 151.5
(byte) main::initNES1_i#2 reg byte x 112.22222222222223
(label) main::initNES1_waitForVBlank1
(byte~) main::initNES1_waitForVBlank1_$0 reg byte a 202.0
(label) main::initNES1_waitForVBlank1_@1
(label) main::initNES1_waitForVBlank2
(byte~) main::initNES1_waitForVBlank2_$0 reg byte a 202.0
(label) main::initNES1_waitForVBlank2_@1
(const byte*) main::s[(byte) $25] = (byte*) "hello world!
i am nes
look at me
"
(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]:9 2.00000002E8
(word) ppuDataFill::i#2 i zp[2]:9 1.00000001E8
(nomodify void*) ppuDataFill::ppuData
(label) ppuDataFill::ppuDataPrepare1
(byte~) ppuDataFill::ppuDataPrepare1_$0 reg byte a 2.0000002E7
(byte~) ppuDataFill::ppuDataPrepare1_$1 reg byte a 2.0000002E7
(nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData
(nomodify void*) ppuDataFill::ppuDataPrepare1_ppuData#0 ppuDataPrepare1_ppuData zp[2]:5 6666667.333333333
(label) ppuDataFill::ppuDataPut1
(byte) ppuDataFill::ppuDataPut1_val
(word) ppuDataFill::size
(word) ppuDataFill::size#5 size zp[2]:17 1.1111111222222222E7
(byte) ppuDataFill::val
(byte) ppuDataFill::val#10 reg byte x 1.1111111222222222E7
(byte()) ppuDataGet((nomodify void*) ppuDataGet::ppuData)
(label) ppuDataGet::@return
(nomodify void*) ppuDataGet::ppuData
(nomodify void*) ppuDataGet::ppuData#0 ppuData zp[2]:17 5.25000000075E9
(label) ppuDataGet::ppuDataPrepare1
(byte~) ppuDataGet::ppuDataPrepare1_$0 reg byte a 2.0000000002E10
(byte~) ppuDataGet::ppuDataPrepare1_$1 reg byte a 2.0000000002E10
(nomodify void*) ppuDataGet::ppuDataPrepare1_ppuData
(label) ppuDataGet::ppuDataRead1
(byte) ppuDataGet::ppuDataRead1_return
(byte) ppuDataGet::ppuDataRead1_return#0 reg byte a 3.666666667333333E9
(byte) ppuDataGet::return
(byte) ppuDataGet::return#2 reg byte a 2.000000002E9
(void()) ppuDataSet((nomodify void*) ppuDataSet::ppuData , (byte) ppuDataSet::val)
(label) ppuDataSet::@return
(nomodify void*) ppuDataSet::ppuData
(nomodify byte*) ppuDataSet::ppuData#0 ppuData zp[2]:5 5000.5
(nomodify void*) ppuDataSet::ppuData#1 ppuData zp[2]:5 1.000000001E9
(label) ppuDataSet::ppuDataPrepare1
(byte~) ppuDataSet::ppuDataPrepare1_$0 reg byte a 2.0000000002E10
(byte~) ppuDataSet::ppuDataPrepare1_$1 reg byte a 2.0000000002E10
(nomodify void*) ppuDataSet::ppuDataPrepare1_ppuData
(nomodify void*) ppuDataSet::ppuDataPrepare1_ppuData#0 ppuDataPrepare1_ppuData zp[2]:5 7.000003334666666E9
(nomodify void*) ppuDataSet::ppuDataPrepare1_ppuData#2 ppuDataPrepare1_ppuData zp[2]:5 20002.0
(label) ppuDataSet::ppuDataPut1
(byte) ppuDataSet::ppuDataPut1_val
(byte) ppuDataSet::val
(byte) ppuDataSet::val#0 reg byte x 10001.0
(byte) ppuDataSet::val#1 reg byte x 2.000000002E9
(byte) ppuDataSet::val#2 reg byte x 2.2000020006E9
(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]:9 1001.0
(byte*) ppuDataTransfer::cpuSrc#2 cpuSrc zp[2]:9 750.75
(word) ppuDataTransfer::i
(word) ppuDataTransfer::i#1 i zp[2]:7 2002.0
(word) ppuDataTransfer::i#2 i zp[2]:7 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
(byte()) readJoy1()
(byte~) readJoy1::$1 zp[1]:19 101.0
(byte~) readJoy1::$2 reg byte a 202.0
(label) readJoy1::@1
(label) readJoy1::@2
(label) readJoy1::@return
(byte) readJoy1::i
(byte) readJoy1::i#1 reg byte x 202.0
(byte) readJoy1::i#2 reg byte x 60.599999999999994
(byte) readJoy1::joy
(byte) readJoy1::joy#1 reg byte a 101.0
(byte) readJoy1::joy#2 reg byte a 51.0
(byte) readJoy1::return
(byte) readJoy1::return#2 reg byte a 4.0
interrupt(HARDWARE_STACK)(void()) vblank()
(byte~) vblank::$1 reg byte a 4.0
(byte~) vblank::$3 reg byte a 4.0
(byte~) vblank::$5 reg byte a 4.0
(byte~) vblank::$7 reg byte a 4.0
(label) vblank::@1
(label) vblank::@10
(label) vblank::@11
(label) vblank::@2
(label) vblank::@3
(label) vblank::@4
(label) vblank::@5
(label) vblank::@6
(label) vblank::@7
(label) vblank::@8
(label) vblank::@9
(label) vblank::@return
(byte) vblank::joy
(byte) vblank::joy#0 reg byte x 0.7142857142857142
(volatile byte) x_scroll loadstore zp[1]:15 1.1500000000000001
(volatile byte) y_scroll loadstore zp[1]:16 1.4761904761904767
reg byte x [ main::initNES1_i#2 main::initNES1_i#1 ]
zp[1]:2 [ cscroll::y#2 cscroll::y#1 ]
zp[2]:3 [ cscroll::line1#6 cscroll::line1#2 cscroll::line1#1 ]
reg byte y [ cscroll::x#2 cscroll::x#1 ]
reg byte x [ ppuDataSet::val#2 ppuDataSet::val#0 ppuDataSet::val#1 ]
zp[2]:5 [ ppuDataFill::ppuDataPrepare1_ppuData#0 ppuDataSet::ppuDataPrepare1_ppuData#0 ppuDataSet::ppuDataPrepare1_ppuData#2 ppuDataSet::ppuData#1 ppuDataSet::ppuData#0 ]
reg byte x [ ppuDataFill::val#10 ]
zp[2]:7 [ ppuDataTransfer::i#2 ppuDataTransfer::i#1 cputs::s#2 cputs::s#0 ]
zp[2]:9 [ ppuDataTransfer::cpuSrc#2 ppuDataTransfer::cpuSrc#1 cscroll::line2#6 cscroll::line2#2 cscroll::line2#1 ppuDataFill::i#2 ppuDataFill::i#1 ]
reg byte x [ readJoy1::i#2 readJoy1::i#1 ]
reg byte a [ readJoy1::joy#2 readJoy1::joy#1 ]
zp[1]:11 [ conio_cursor_x ]
zp[1]:12 [ conio_cursor_y ]
zp[2]:13 [ conio_line_text ]
zp[1]:15 [ x_scroll ]
zp[1]:16 [ y_scroll ]
reg byte a [ main::initNES1_waitForVBlank1_$0 ]
reg byte a [ main::initNES1_waitForVBlank2_$0 ]
reg byte a [ cputs::c#1 ]
reg byte x [ cputc::c#0 ]
zp[2]:17 [ ppuDataGet::ppuData#0 ppuDataFill::size#5 ]
reg byte a [ ppuDataGet::return#2 ]
reg byte x [ cscroll::ch#0 ]
reg byte a [ ppuDataSet::ppuDataPrepare1_$0 ]
reg byte a [ ppuDataSet::ppuDataPrepare1_$1 ]
reg byte a [ ppuDataGet::ppuDataPrepare1_$0 ]
reg byte a [ ppuDataGet::ppuDataPrepare1_$1 ]
reg byte a [ ppuDataGet::ppuDataRead1_return#0 ]
reg byte a [ ppuDataFill::ppuDataPrepare1_$0 ]
reg byte a [ ppuDataFill::ppuDataPrepare1_$1 ]
reg byte a [ ppuDataTransfer::ppuDataPut1_val#0 ]
reg byte a [ readJoy1::return#2 ]
reg byte x [ vblank::joy#0 ]
reg byte a [ vblank::$1 ]
reg byte a [ vblank::$3 ]
reg byte a [ vblank::$5 ]
reg byte a [ vblank::$7 ]
zp[1]:19 [ readJoy1::$1 ]
reg byte a [ readJoy1::$2 ]

View File

@ -71,6 +71,8 @@ Inlined call call ppuDataPut *((byte*) ppuDataPutTile::tile + (number) 2)
Inlined call call ppuDataPut *((byte*) ppuDataPutTile::tile + (number) 3)
Inlined call call ppuDataPrepare (nomodify void*) ppuDataSet::ppuData
Inlined call call ppuDataPut (byte) ppuDataSet::val
Inlined call call ppuDataPrepare (nomodify void*) ppuDataGet::ppuData
Inlined call (byte~) ppuDataGet::$1 ← call ppuDataRead
Inlined call call initNES
Inlined call call enableVideoOutput
Inlined call call ppuSpriteBufferDmaTransfer (const struct SpriteData*) SPRITE_BUFFER

View File

@ -12,6 +12,7 @@
"print.h": "c",
"printf.h": "c",
"c64.h": "c"
}
},
"kickassembler.assemblerJar": "/Applications/KickAssembler/KickAss.jar"
}
}