6502/vbcc/targets/6502-nes/include/lazynes.h
2022-05-12 21:36:39 +09:30

109 lines
4.1 KiB
C

// lazyNES - As lazy as possible NES hardware support library for vbcc6502
// (happily cooperates with Shiru's famitone2 replay code)
// V1.0, 'Lazycow 2020
typedef signed char byte;
typedef unsigned char ubyte;
typedef signed short word;
typedef unsigned short uword;
// Wait for next vblank
// flags: 0, lfBlank or lfSplit (see below)
// result: Amount of frames since last sync [0..31], 128 is added on NTSC
//
ubyte lnSync(__reg("a") ubyte flags);
enum {
lfBlank = 1, // activates blank mode, blanks screen and allows lnPush() calls
lfSplit = 2 // activates split mode, NMI waits for SPR0HIT and sets registers
};
// Write data into nametables, palettes, CHRRAM, etc.
// (System must be in blank mode!)
// o: Destination address offset in vram
// a: Amount of bytes that should be written
// p: Pointer to data
//
void lnPush(__reg("a/x") uword o, __reg("r0") ubyte a, __reg("r2/r3") void* s);
// Write data into nametables, palettes, CHRRAM, etc.
// (Screen has to be visible, doesn't work in blank mode!)
// updateList: Pointer to update list
//
void lnList(__reg("a/x") void* updateList);
enum { lfHor=64, lfVer=128, lfEnd=255 };
//
// remarks:
// - The format of the update list is an array of unsigned bytes.
// - There can be 3 different commands in the update list:
// a) addressHi, addressLo, value
// b) addressHi|lfHor, addressLo, amountOfBytes, byte1, byte2, byte3, ...
// c) addressHi|lfVer, addressLo, amountOfBytes, byte1, byte2, byte3, ...
// - Multiple commands can be queued in one list,
// but there can only be one activated updatelist at a time.
// - The end of the list is marked by lfEnd! (important!)
// - It's the same format that's used in set_vram_update() of Shiru's neslib
// Common offsets for lnPush() and lnList()
enum { //
lnNameTab0=0x2000, lnNameTab1=0x2400, lnNameTab2=0x2800, lnNameTab3=0x2C00,
lnAttrTab0=0x23C0, lnAttrTab1=0x27C0, lnAttrTab2=0x2BC0, lnAttrTab3=0x2FC0,
lnBackCol=0x3F00,
lnChrPal0=0x3F01, lnChrPal1=0x3F05, lnChrPal2=0x3F09, lnChrPal3=0x3F0D,
lnSprPal0=0x3F11, lnSprPal1=0x3F15, lnSprPal2=0x3F19, lnSprPal3=0x3F1D
};
// Scroll background
// x: New horizotnal scrolling offset in pixels, allowed range: [0..511]
// y: New vertical scrolling offset in pixels, allowed range: [0..479]
//
void lnScroll(__reg("r0/r1") uword x, __reg("r2/r3") uword y);
//
// remarks:
// - If a SPR0HIT based splitscreen is used, the 1st call of lnScroll() sets
// the scrolling offsets of the area above the split and the 2nd call of
// lnScroll() sets the scrolling offsets of the area below the split.
// Add meta-sprite to display list
// p: Pointer to metasprite data
// x,y: Sprite coordinates
// result: New position offset in OAM after the meta sprite has been added
//
ubyte lnAddSpr(__reg("r0/r1") void* p,
__reg("r2/r3") word x, __reg("r4/r5") word y);
//
// remarks:
// - The format for the metasprite data is an array of unsigned bytes.
// - Four bytes per sprite: x-offset, y-offset, tile, attributes
// - The end of the list is marked by the value 128! (important!)
// - It's the same format that's used in oam_meta_spr() from Shiru's neslib
// Query joypad state
// port: Joypad port (1 or 2)
// result: Set of joypad flags (see below)
//
ubyte lnGetPad(__reg("a") ubyte port);
enum { lfU=8, lfD=4, lfL=2, lfR=1, lfA=128, lfB=64, lfStart=16, lfSelect=32 };
//
// advanced usage
//
extern __zpage volatile ubyte
lnSpr0Wait, // delay until scroll registers will be set after a SPR0HIT
lnPPUCTRL, // current value of PPUCTRL register (will be written in NMI)
lnPPUMASK; // current value of PPUMASK register (will be written in NMI)
//
// remark: The lazyNES NMI will write the PPUCTRL and PPUMASK registers,
// so don't write PPUCTRL and PPUMASK directly - use these two
// variables insead. Their values will be written in the next NMI.
// Also, don't use these variables before the 1st call of lnSync()!