mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-02 04:49:44 +00:00
140 lines
3.7 KiB
Plaintext
140 lines
3.7 KiB
Plaintext
|
|
||
|
bank zeropage @ 0x00 : [vardata; 256];
|
||
|
bank stack @ 0x100 : [vardata; 256];
|
||
|
bank ram @ 0x200 : [vardata; 1536];
|
||
|
bank prg @ 0x8000 : [constdata; 32768];
|
||
|
bank chr : [chrdata; 8192];
|
||
|
|
||
|
import "nes";
|
||
|
|
||
|
in zeropage {
|
||
|
var b0, b1, b2, b3, b4, b5, b6, b7 : u8;
|
||
|
var ptr0 @ &b0, ptr2 @ &b2 : *u8;
|
||
|
}
|
||
|
|
||
|
in prg {
|
||
|
func main() {
|
||
|
// Disable decimal arithmetic (though not actually supported on 2A03 anyway)
|
||
|
decimal = false;
|
||
|
// Disable interrupts.
|
||
|
nointerrupt = true;
|
||
|
// Prepare stack.
|
||
|
s = x = 0xFF;
|
||
|
|
||
|
// Turn off rendering.
|
||
|
nes.ppu.control = x = 0;
|
||
|
nes.ppu.mask = x;
|
||
|
// Disable DMC interrupts.
|
||
|
nes.apu.frame_counter = a = nes.apu.FRAME_COUNTER_IRQ_DISABLE;
|
||
|
|
||
|
// Wait for the PPU to be ready to use, which takes 2 vertical blanks.
|
||
|
do {
|
||
|
do {} while !nes.ppu.status$7;
|
||
|
x++;
|
||
|
} while x != 2;
|
||
|
|
||
|
// Read PPU status to reset the PPU high/low latch.
|
||
|
a = nes.ppu.status;
|
||
|
// Now setup the PPU for copying to the nametable.
|
||
|
nes.ppu.address = a = >:nes.ppu.ADDRESS_NAMETABLE_DATA;
|
||
|
nes.ppu.address = a = <:nes.ppu.ADDRESS_NAMETABLE_DATA;
|
||
|
// Clear the nametable.
|
||
|
x = >:nes.ppu.NAMETABLE_SIZE * 2;
|
||
|
do {
|
||
|
y = 0;
|
||
|
do {
|
||
|
nes.ppu.data = a;
|
||
|
y++;
|
||
|
} while !zero;
|
||
|
|
||
|
x--;
|
||
|
} while !zero;
|
||
|
|
||
|
// Read PPU status to reset the PPU high/low latch.
|
||
|
a = nes.ppu.status;
|
||
|
// Now setup the PPU for copying to the palette.
|
||
|
nes.ppu.address = a = >:nes.ppu.ADDRESS_PALETTE_DATA;
|
||
|
nes.ppu.address = a = <:nes.ppu.ADDRESS_PALETTE_DATA;
|
||
|
// Clear the palette.
|
||
|
x = 0;
|
||
|
do {
|
||
|
nes.ppu.data = a = palette[x++];
|
||
|
} while x != palette.len;
|
||
|
|
||
|
{
|
||
|
let START_X = 10;
|
||
|
let START_Y = 13;
|
||
|
let TILE_ADDRESS = nes.ppu.ADDRESS_NAMETABLE_DATA + START_Y * 32 + START_X;
|
||
|
|
||
|
// Read PPU status to reset the PPU high/low latch.
|
||
|
a = nes.ppu.status;
|
||
|
// Now setup the PPU for copying to the nametable.
|
||
|
nes.ppu.address = a = >:TILE_ADDRESS;
|
||
|
nes.ppu.address = a = <:TILE_ADDRESS;
|
||
|
// Copy the message.
|
||
|
x = 0;
|
||
|
while {
|
||
|
a = message[y];
|
||
|
} && !zero {
|
||
|
y++;
|
||
|
nes.ppu.data = a;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
a = nes.ppu.status;
|
||
|
nes.ppu.scroll = a = 0;
|
||
|
nes.ppu.scroll = a;
|
||
|
|
||
|
// We're finally ready to show the screen!
|
||
|
nes.ppu.control = a = nes.ppu.CONTROL_NMI;
|
||
|
nes.ppu.mask = a = nes.ppu.MASK_LEFTMOST_BG | nes.ppu.MASK_RENDER_BG;
|
||
|
|
||
|
// Enable interrupts.
|
||
|
nointerrupt = false;
|
||
|
|
||
|
while true {}
|
||
|
}
|
||
|
|
||
|
#[nmi] func draw() {
|
||
|
push(a);
|
||
|
a = x; push(a);
|
||
|
a = y; push(a);
|
||
|
a = nes.ppu.status;
|
||
|
nes.ppu.scroll = a = 0;
|
||
|
nes.ppu.scroll = a;
|
||
|
y = a = pop();
|
||
|
x = a = pop();
|
||
|
a = pop();
|
||
|
}
|
||
|
|
||
|
#[irq] func scanline() {
|
||
|
push(a);
|
||
|
a = x; push(a);
|
||
|
a = y; push(a);
|
||
|
y = a = pop();
|
||
|
x = a = pop();
|
||
|
a = pop();
|
||
|
}
|
||
|
|
||
|
const message = "HELLO WORLD\0";
|
||
|
|
||
|
const palette : [u8] = [
|
||
|
// Tiles
|
||
|
0x0F, 0x00, 0x10, 0x30,
|
||
|
0x0F, 0x00, 0x10, 0x30,
|
||
|
0x0F, 0x00, 0x10, 0x30,
|
||
|
0x0F, 0x00, 0x10, 0x30,
|
||
|
// Sprites
|
||
|
0x0F, 0x00, 0x10, 0x30,
|
||
|
0x0F, 0x00, 0x10, 0x30,
|
||
|
0x0F, 0x00, 0x10, 0x30,
|
||
|
0x0F, 0x00, 0x10, 0x30
|
||
|
];
|
||
|
|
||
|
const @ 0xFFFA = [draw, main, scanline];
|
||
|
}
|
||
|
|
||
|
in chr {
|
||
|
const = embed "hello_tiles.chr";
|
||
|
}
|