mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-12 11:31:11 +00:00
Added NES conio initial support. (scrolling not working atm.)
This commit is contained in:
parent
709039de87
commit
ba90f9ea65
@ -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;
|
||||
|
@ -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
173
src/main/kc/lib/conio-nes.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
@ -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 {
|
||||
|
189
src/test/kc/.vscode/tasks.json
vendored
189
src/test/kc/.vscode/tasks.json
vendored
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
BIN
src/test/kc/examples/nes-conio/characters.901225-01.bin
Normal file
BIN
src/test/kc/examples/nes-conio/characters.901225-01.bin
Normal file
Binary file not shown.
96
src/test/kc/examples/nes-conio/nes-conio.c
Normal file
96
src/test/kc/examples/nes-conio/nes-conio.c
Normal 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
|
||||
};
|
674
src/test/ref/examples/nes-conio/nes-conio.asm
Normal file
674
src/test/ref/examples/nes-conio/nes-conio.asm
Normal 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
|
374
src/test/ref/examples/nes-conio/nes-conio.cfg
Normal file
374
src/test/ref/examples/nes-conio/nes-conio.cfg
Normal 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
|
6505
src/test/ref/examples/nes-conio/nes-conio.log
Normal file
6505
src/test/ref/examples/nes-conio/nes-conio.log
Normal file
File diff suppressed because it is too large
Load Diff
298
src/test/ref/examples/nes-conio/nes-conio.sym
Normal file
298
src/test/ref/examples/nes-conio/nes-conio.sym
Normal 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 ]
|
@ -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
|
||||
|
@ -12,6 +12,7 @@
|
||||
"print.h": "c",
|
||||
"printf.h": "c",
|
||||
"c64.h": "c"
|
||||
}
|
||||
},
|
||||
"kickassembler.assemblerJar": "/Applications/KickAssembler/KickAss.jar"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user