mirror of
https://gitlab.com/octospacc/MultiSpaccSDK
synced 2025-03-01 10:17:53 +01:00
Add NES building and adapt example functions
This commit is contained in:
parent
5c404b5faf
commit
9be90d7629
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,7 @@
|
||||
*.o
|
||||
*.lib
|
||||
*.exe
|
||||
*.run
|
||||
*.tmp
|
||||
.tmp/
|
||||
Build/
|
||||
|
@ -3,7 +3,7 @@ AppSources = $(wildcard *.c)
|
||||
AppHeaders = $(wildcard *.h)
|
||||
SpaccSources = $(wildcard ../../LibMultiSpacc/*.c)
|
||||
SpaccHeaders = $(wildcard ../../LibMultiSpacc/*.h)
|
||||
CFlags = -Os -Wpedantic -Werror
|
||||
CFlags = -Os -Werror -Wpedantic -Wdeclaration-after-statement
|
||||
|
||||
# Default build is always for the host system
|
||||
ifndef Target
|
||||
@ -36,30 +36,37 @@ ifeq ($(MultiSpacc_Target), SDL12)
|
||||
Defines += -DMultiSpacc_Target_SDL12 -DMultiSpacc_Target_SDLCom
|
||||
CFlags += $(shell sdl-config --cflags)
|
||||
LdFlags += $(shell sdl-config --libs) -lSDL -lSDL_image -lSDL_mixer -lSDL_ttf
|
||||
BuildProcess = Normal
|
||||
BuildProcess = __Normal__
|
||||
else ifeq ($(MultiSpacc_Target), SDL20)
|
||||
Defines += -DMultiSpacc_Target_SDL20 -DMultiSpacc_Target_SDLCom
|
||||
CFlags += $(shell sdl2-config --cflags)
|
||||
LdFlags += $(shell sdl2-config --libs) -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf
|
||||
BuildProcess = Normal
|
||||
BuildProcess = __Normal__
|
||||
else ifeq ($(MultiSpacc_Target), NDS)
|
||||
Defines += -DMultiSpacc_Target_NDS
|
||||
BuildProcess = NDS
|
||||
BuildProcess = __NDS__
|
||||
else ifeq ($(MultiSpacc_Target), NES)
|
||||
Defines += -DMultiSpacc_Target_NES
|
||||
BuildProcess = NES
|
||||
BuildProcess = __NES__
|
||||
endif
|
||||
|
||||
CC = $(ToolsPrefix)gcc $(CFlags) $(Defines)
|
||||
BuildSources = $(AppSources) $(SpaccSources)
|
||||
Objects = $(BuildSources:.c=.o)
|
||||
Shell = $(shell echo $$SHELL)
|
||||
AppObjects = $(AppSources:.c=.o)
|
||||
SpaccObjects = $(SpaccSources:.c=.o)
|
||||
BuildObjects = $(AppObjects) $(SpaccObjects)
|
||||
#BuildSources = $(AppSources) $(SpaccSources)
|
||||
#Objects = $(BuildSources:.c=.o)
|
||||
|
||||
All all: $(BuildProcess)
|
||||
|
||||
Normal: $(Objects)
|
||||
# TODO: use virtual build dirs even for normals to allow linking against different wrapped libraries
|
||||
__Normal__: $(BuildObjects)
|
||||
$(CC) $^ $(LdFlags) -o $(AppName)$(ExeSuffix)
|
||||
|
||||
NDS:
|
||||
# TODO: Fix include substitutions properly in non-standard build processes
|
||||
|
||||
__NDS__:
|
||||
$(eval VirtualBuildDir = ./Build/NDS)
|
||||
mkdir -p $(VirtualBuildDir)/source/.tmp
|
||||
cp ../NDS.mk $(VirtualBuildDir)/Makefile
|
||||
@ -71,8 +78,20 @@ NDS:
|
||||
for i in $(VirtualBuildDir)/source/*; do sed -i 's|#include[ \t]"./|#include "./LibMultiSpacc_|g' $$i; done
|
||||
cd $(VirtualBuildDir); make
|
||||
|
||||
NES:
|
||||
#
|
||||
__NES__:
|
||||
cd ../../neslib; make
|
||||
$(eval VirtualBuildDir = ./Build/NES)
|
||||
mkdir -p $(VirtualBuildDir)/.tmp
|
||||
cp $(SpaccSources) $(SpaccHeaders) $(VirtualBuildDir)/.tmp/
|
||||
cd $(VirtualBuildDir)/.tmp; for i in *; do mv ./$$i ../LibMultiSpacc_$$i; done
|
||||
cp $(AppSources) $(AppHeaders) $(VirtualBuildDir)/
|
||||
for i in $(VirtualBuildDir)/*; do sed -i 's|#include[ \t]"../../LibMultiSpacc/|#include "LibMultiSpacc_|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/*; do sed -i 's|#include[ \t]"../MultiSpacc|#include "LibMultiSpacc_MultiSpacc|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/*; do sed -i 's|#include[ \t]"./|#include "./LibMultiSpacc_|g' $$i; done
|
||||
cp ../../neslib/*.cfg ../../neslib/crt0.o ../../neslib/chr_generic.o ../../neslib/*.lib ../../neslib/*.h $(VirtualBuildDir)/
|
||||
echo "AppName='$(AppName)'; Defines='$(Defines)'; AppSources='$(AppSources)'; SpaccSources='$(SpaccSources)'; AppObjects='$(AppObjects)'; BuildObjects='$(BuildObjects)';" > $(VirtualBuildDir)/Make.sh
|
||||
cat ../NES.mk.sh >> $(VirtualBuildDir)/Make.sh
|
||||
cd $(VirtualBuildDir); $(Shell) ./Make.sh
|
||||
|
||||
Run run: All
|
||||
./$(AppName)$(ExeSuffix)
|
||||
@ -80,5 +99,5 @@ Run run: All
|
||||
Clean clean Clear clear:
|
||||
find -L . -name "*.o" -type f -delete
|
||||
find -L ../../LibMultiSpacc -name "*.o" -type f -delete
|
||||
rm -f ./$(AppName)$(ExeSuffix) ./$(AppName).*$(ExeSuffix)
|
||||
rm -f ./$(AppName)$(ExeSuffix)
|
||||
rm -rf ./Build
|
||||
|
@ -2,16 +2,38 @@
|
||||
|
||||
#define AppName "Hello World"
|
||||
|
||||
/*{pal:"nes",layout:"nes"}*/
|
||||
const char PALETTE[32] = {
|
||||
0x03, // screen
|
||||
0x11,0x30,0x27,0x00, // background 0
|
||||
0x1c,0x20,0x2c,0x00, // background 1
|
||||
0x00,0x10,0x20,0x00, // background 2
|
||||
0x06,0x16,0x26,0x00, // background 3
|
||||
0x16,0x35,0x24,0x00, // sprite 0
|
||||
0x00,0x37,0x25,0x00, // sprite 1
|
||||
0x0d,0x2d,0x3a,0x00, // sprite 2
|
||||
0x0d,0x27,0x2a, // sprite 3
|
||||
};
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
int spriteX = 0;
|
||||
int spriteY = 0;
|
||||
int accelX = +2;
|
||||
int accelX = +1;
|
||||
int accelY = +2;
|
||||
|
||||
MultiSpacc_SurfaceConfig WindowConfig = { .Width = 320, .Height = 240, .Bits = 16 };
|
||||
MultiSpacc_Window *Window = MultiSpacc_SetWindow( WindowConfig );
|
||||
MultiSpacc_Surface *Screen = MultiSpacc_GetWindowSurface( Window );
|
||||
MultiSpacc_SurfaceConfig WindowConfig = {0};
|
||||
MultiSpacc_Window *Window;
|
||||
MultiSpacc_Surface *Screen;
|
||||
MultiSpacc_Surface *TilesImg;
|
||||
|
||||
WindowConfig.Width = 256;
|
||||
WindowConfig.Height = 240;
|
||||
WindowConfig.Bits = 16;
|
||||
memcpy( WindowConfig.Palette, PALETTE, 32 );
|
||||
//WindowConfig.Frequency = 50;
|
||||
Window = MultiSpacc_SetWindow( &WindowConfig /*, &PALETTE*/ );
|
||||
Screen = MultiSpacc_GetWindowSurface( Window );
|
||||
|
||||
if( Screen == NULL )
|
||||
{
|
||||
@ -23,19 +45,14 @@ int main( int argc, char *argv[] )
|
||||
|
||||
// Bitmap font borrowed from: <https://github.com/nesdoug/01_Hello/blob/master/Alpha.chr>
|
||||
// Copyright (c) 2018 Doug Fraker www.nesdoug.com (MIT)
|
||||
MultiSpacc_Surface *TilesImg = MultiSpacc_LoadImage( "Tiles.png", Screen, NULL );
|
||||
MultiSpacc_PrintText( "Hello, World!", Screen, WindowConfig, 0, 0, TilesImg );
|
||||
//TilesImg = MultiSpacc_LoadImage( "Tiles.png", Screen, NULL );
|
||||
MultiSpacc_PrintText( "Hello, World!", Screen, &WindowConfig, 2, 2, TilesImg );
|
||||
MultiSpacc_PrintDebug("[I] Ready!\n");
|
||||
|
||||
// if( MultiSpacc_UpdateWindowSurface(Window) != 0 )
|
||||
// {
|
||||
// MultiSpacc_PrintDebug("[E] Error Updating Screen.\n");
|
||||
// return -1;
|
||||
// };
|
||||
|
||||
while(true)
|
||||
{
|
||||
MultiSpacc_Sprite( 0, spriteX, spriteY, 0x80, TilesImg, Screen );
|
||||
MultiSpacc_Sprite( 0, spriteX, spriteY, 20/*128*/, TilesImg, Screen );
|
||||
//scroll(spriteX,0);
|
||||
|
||||
spriteX += accelX;
|
||||
spriteY += accelY;
|
||||
@ -57,9 +74,8 @@ int main( int argc, char *argv[] )
|
||||
};
|
||||
|
||||
// TODO: Implement cross-platform vblank-wait
|
||||
MultiSpacc_Sleep(16);
|
||||
//MultiSpacc_Sleep(16);
|
||||
}
|
||||
|
||||
//MultiSpacc_Sleep(4000);
|
||||
return 0;
|
||||
}
|
||||
|
14
LibMultiSpacc/Examples/NES.mk.sh
Normal file
14
LibMultiSpacc/Examples/NES.mk.sh
Normal file
@ -0,0 +1,14 @@
|
||||
#!/dev/null
|
||||
set -e
|
||||
|
||||
# ${SpaccSources} ${AppSources} ${SpaccObjects} ${AppObjects} chr_generic.s chr_generic.o crt0.o
|
||||
|
||||
for File in *.c
|
||||
do cc65 -Oirs --target nes ${File} ${Defines}
|
||||
done
|
||||
|
||||
for File in *.s
|
||||
do ca65 --target nes ${File}
|
||||
done
|
||||
|
||||
ld65 -v -o ${AppName}.nes *.o *.lib nes.lib --config NROM256.cfg -DNES_MAPPER=0 -DNES_PRG_BANKS=2 -DNES_CHR_BANKS=1 -DNES_MIRRORING=0
|
@ -86,4 +86,16 @@ void MultiSpacc_Sprite( int id, int x, int y, int sprite, MultiSpacc_Surface *Ti
|
||||
};
|
||||
SDL_BlitSurface( Tiles, &Clip, Surface, &Offset );
|
||||
#endif
|
||||
|
||||
#ifdef MultiSpacc_Target_NES
|
||||
oam_spr(x, y, sprite, 0, id);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MultiSpacc_Target_NES
|
||||
int MultiSpacc_UpdateWindowSurface( MultiSpacc_Window *Window )
|
||||
{
|
||||
ppu_wait_frame();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -1,9 +1,14 @@
|
||||
#pragma once
|
||||
#ifndef _MultiSpacc_h_
|
||||
#define _MultiSpacc_h_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#ifndef MultiSpacc_Target_NES
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef MultiSpacc_Target_SDL12
|
||||
#include <SDL/SDL.h>
|
||||
@ -54,16 +59,22 @@
|
||||
#ifdef MultiSpacc_Target_NES
|
||||
#include <nes.h>
|
||||
#include "neslib.h"
|
||||
#define Uint32 int
|
||||
#define MultiSpacc_Window int
|
||||
#define MultiSpacc_Surface int
|
||||
#define MultiSpacc_Event int
|
||||
int MultiSpacc_UpdateWindowSurface( MultiSpacc_Window *Window );
|
||||
#endif
|
||||
|
||||
typedef struct MultiSpacc_SurfaceConfig {
|
||||
int Width;
|
||||
int Height;
|
||||
int Bits;
|
||||
char Palette[32];
|
||||
Uint32 Flags;
|
||||
} MultiSpacc_SurfaceConfig;
|
||||
|
||||
MultiSpacc_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig WindowConfig );
|
||||
MultiSpacc_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig *WindowConfig );
|
||||
MultiSpacc_Surface *MultiSpacc_GetWindowSurface( MultiSpacc_Window *Window );
|
||||
|
||||
void MultiSpacc_SetAppTitle( MultiSpacc_Window *Window, const char Title[] );
|
||||
@ -75,6 +86,8 @@ int MultiSpacc_SetColorKey( MultiSpacc_Surface *Surface, bool Flag, Uint32 Key )
|
||||
int MultiSpacc_PollEvent( MultiSpacc_Event *Event );
|
||||
|
||||
void MultiSpacc_PrintDebug( const char *format, ... );
|
||||
void MultiSpacc_PrintText( char Text[], MultiSpacc_Surface *Surface, MultiSpacc_SurfaceConfig WindowConfig, int x, int y, MultiSpacc_Surface *Tiles /*, int FontSize, int Color */ ); // WIP
|
||||
void MultiSpacc_PrintText( char Text[], MultiSpacc_Surface *Surface, MultiSpacc_SurfaceConfig *WindowConfig, int x, int y, MultiSpacc_Surface *Tiles /*, int FontSize, int Color */ ); // WIP
|
||||
|
||||
void MultiSpacc_Sprite( int id, int x, int y, int sprite, MultiSpacc_Surface *Tiles, MultiSpacc_Surface *Surface );
|
||||
|
||||
#endif // _MultiSpacc_h_
|
@ -1,6 +1,6 @@
|
||||
#include "./MultiSpacc.h"
|
||||
|
||||
void MultiSpacc_PrintText( char Text[], MultiSpacc_Surface *Surface, MultiSpacc_SurfaceConfig WindowConfig, int x, int y, MultiSpacc_Surface *Tiles /*, int FontSize, int Color */ )
|
||||
void MultiSpacc_PrintText( char Text[], MultiSpacc_Surface *Surface, MultiSpacc_SurfaceConfig *WindowConfig, int x, int y, MultiSpacc_Surface *Tiles /*, int FontSize, int Color */ )
|
||||
{
|
||||
#ifdef MultiSpacc_Target_SDLCom
|
||||
for( int i = 0; i < strlen(Text); i++ )
|
||||
@ -22,6 +22,13 @@ void MultiSpacc_PrintText( char Text[], MultiSpacc_Surface *Surface, MultiSpacc_
|
||||
#ifdef MultiSpacc_Target_NDS
|
||||
iprintf("%s", Text);
|
||||
#endif
|
||||
|
||||
#ifdef MultiSpacc_Target_NES
|
||||
ppu_off();
|
||||
vram_adr(NTADR_A( x, y ));
|
||||
vram_write( Text, strlen(Text) );
|
||||
ppu_on_all();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MultiSpacc_PrintDebug( const char *format, ... )
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "./MultiSpacc.h"
|
||||
|
||||
MultiSpacc_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig WindowConfig )
|
||||
MultiSpacc_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig *WindowConfig )
|
||||
{
|
||||
#ifdef MultiSpacc_Target_SDL12
|
||||
return SDL_SetVideoMode( WindowConfig.Width, WindowConfig.Height, WindowConfig.Bits, WindowConfig.Flags );
|
||||
return SDL_SetVideoMode( WindowConfig->Width, WindowConfig->Height, WindowConfig->Bits, WindowConfig->Flags );
|
||||
#endif
|
||||
|
||||
#ifdef MultiSpacc_Target_SDL20
|
||||
return SDL_CreateWindow( NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WindowConfig.Width, WindowConfig.Height, WindowConfig.Flags );
|
||||
return SDL_CreateWindow( NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WindowConfig->Width, WindowConfig->Height, WindowConfig->Flags );
|
||||
#endif
|
||||
|
||||
#ifdef MultiSpacc_Target_NDS
|
||||
@ -20,6 +20,12 @@ MultiSpacc_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig WindowConfig )
|
||||
consoleSelect(bottomScreen);
|
||||
return bottomScreen;
|
||||
#endif
|
||||
|
||||
#ifdef MultiSpacc_Target_NES
|
||||
oam_clear();
|
||||
pal_all(WindowConfig->Palette);
|
||||
ppu_on_all();
|
||||
#endif
|
||||
}
|
||||
|
||||
MultiSpacc_Surface *MultiSpacc_GetWindowSurface( MultiSpacc_Window *Window )
|
||||
|
5
LibMultiSpacc/neslib/.gitignore
vendored
Normal file
5
LibMultiSpacc/neslib/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*.o
|
||||
*.lst
|
||||
*~
|
||||
crt0.lst
|
||||
neslib2.lib
|
18
LibMultiSpacc/neslib/COPYING
Normal file
18
LibMultiSpacc/neslib/COPYING
Normal file
@ -0,0 +1,18 @@
|
||||
(C) 2015 Alex Semenov (Shiru)
|
||||
(C) 2016 Lauri Kasanen
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
12
LibMultiSpacc/neslib/Makefile
Normal file
12
LibMultiSpacc/neslib/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
.PHONY: all clean
|
||||
|
||||
all: crt0.o neslib2.lib
|
||||
|
||||
neslib2.lib: lz4vram.o pad.o rand.o memfill.o vram_read.o vram_unrle.o oam_meta_spr_clip.o oam_meta_spr_pal.o oam_meta_spr.o oam_spr.o oam_clear_fast.o split.o splitxy.o
|
||||
ar65 a neslib2.lib $^
|
||||
|
||||
%.o: %.s $(wildcard *.s *.sinc)
|
||||
cl65 -t nes -Oisr -g -c $*.s
|
||||
|
||||
clean:
|
||||
rm -f *.o *.lst neslib2.lib
|
76
LibMultiSpacc/neslib/NROM256.cfg
Normal file
76
LibMultiSpacc/neslib/NROM256.cfg
Normal file
@ -0,0 +1,76 @@
|
||||
SYMBOLS {
|
||||
__STACKSIZE__: type = weak, value = $0500; # 5 pages stack
|
||||
}
|
||||
|
||||
# NROM256 (32 KB PRG ROM)
|
||||
|
||||
MEMORY {
|
||||
ZP: start = $00, size = $100, type = rw, define = yes;
|
||||
|
||||
# INES Cartridge Header
|
||||
|
||||
HEADER: start = $0, size = $10, file = %O ,fill = yes;
|
||||
|
||||
# 2 16K ROM Banks
|
||||
# - startup
|
||||
# - code
|
||||
# - rodata
|
||||
# - data (load)
|
||||
|
||||
PRG: start = $8000, size = $7f00, file = %O ,fill = yes, define = yes;
|
||||
|
||||
# DPCM Samples at end of the ROM
|
||||
|
||||
DMC: start = $ff00, size = $fa, file = %O, fill = yes;
|
||||
|
||||
# Hardware Vectors at end of the ROM
|
||||
|
||||
VECTORS: start = $fffa, size = $6, file = %O, fill = yes;
|
||||
|
||||
# 1 8K CHR Bank
|
||||
|
||||
CHR: start = $0000, size = $2000, file = %O, fill = yes;
|
||||
|
||||
# standard 2K SRAM (-zeropage)
|
||||
# $0100 famitone, palette, cpu stack
|
||||
# $0200 oam buffer
|
||||
# $0300..$800 ca65 stack
|
||||
|
||||
RAM: start = $0300, size = $0500, define = yes;
|
||||
|
||||
# Use this definition instead if you going to use extra 8K RAM
|
||||
# RAM: start = $6000, size = $2000, define = yes;
|
||||
}
|
||||
|
||||
SEGMENTS {
|
||||
HEADER: load = HEADER, type = ro;
|
||||
STARTUP: load = PRG, type = ro, define = yes;
|
||||
LOWCODE: load = PRG, type = ro, optional = yes;
|
||||
ONCE: load = PRG, type = ro, optional = yes;
|
||||
INIT: load = PRG, type = ro, define = yes, optional = yes;
|
||||
CODE: load = PRG, type = ro, define = yes;
|
||||
RODATA: load = PRG, type = ro, define = yes;
|
||||
DATA: load = PRG, run = RAM, type = rw, define = yes;
|
||||
VECTORS: load = VECTORS, type = rw;
|
||||
SAMPLES: load = DMC, type = rw;
|
||||
CHARS: load = CHR, type = rw;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
HEAP: load = RAM, type = bss, optional = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
}
|
||||
|
||||
FEATURES {
|
||||
CONDES: segment = INIT,
|
||||
type = constructor,
|
||||
label = __CONSTRUCTOR_TABLE__,
|
||||
count = __CONSTRUCTOR_COUNT__;
|
||||
CONDES: segment = RODATA,
|
||||
type = destructor,
|
||||
label = __DESTRUCTOR_TABLE__,
|
||||
count = __DESTRUCTOR_COUNT__;
|
||||
CONDES: type = interruptor,
|
||||
segment = RODATA,
|
||||
label = __INTERRUPTOR_TABLE__,
|
||||
count = __INTERRUPTOR_COUNT__;
|
||||
}
|
||||
|
13
LibMultiSpacc/neslib/README.asciidoc
Normal file
13
LibMultiSpacc/neslib/README.asciidoc
Normal file
@ -0,0 +1,13 @@
|
||||
Neslib
|
||||
======
|
||||
|
||||
This is a ca65 asm library consisting of useful NES functions. It's designed to be
|
||||
used with cc65 git master, no need for old runtimes or the like.
|
||||
|
||||
Credit for making this goes to Shiru, who published the original in public domain.
|
||||
|
||||
@clbr made some changes and fixed some things.
|
||||
|
||||
@sehugg made some more changes to integrate with http://8bitworkshop.com/
|
||||
|
||||
This is under the zlib license.
|
208
LibMultiSpacc/neslib/crt0.s
Normal file
208
LibMultiSpacc/neslib/crt0.s
Normal file
@ -0,0 +1,208 @@
|
||||
; Startup code for cc65 and Shiru's NES library
|
||||
; based on code by Groepaz/Hitmen <groepaz@gmx.net>, Ullrich von Bassewitz <uz@cc65.org>
|
||||
; edited by Steven Hugg (remove integrated Famitone2 library, add NMICallback)
|
||||
|
||||
.export _exit,__STARTUP__:absolute=1
|
||||
.import initlib,push0,popa,popax,_main,zerobss,copydata
|
||||
|
||||
; Linker generated symbols
|
||||
.import __RAM_START__ ,__RAM_SIZE__
|
||||
.import __ROM0_START__ ,__ROM0_SIZE__
|
||||
.import __STARTUP_LOAD__,__STARTUP_RUN__,__STARTUP_SIZE__
|
||||
.import __CODE_LOAD__ ,__CODE_RUN__ ,__CODE_SIZE__
|
||||
.import __RODATA_LOAD__ ,__RODATA_RUN__ ,__RODATA_SIZE__
|
||||
.import NES_MAPPER,NES_PRG_BANKS,NES_CHR_BANKS,NES_MIRRORING
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "nes.inc"
|
||||
|
||||
FT_BASE_ADR =$0100 ;page in RAM, should be $xx00
|
||||
|
||||
.define FT_THREAD 1 ;undefine if you call sound effects in the same thread as sound update
|
||||
.define FT_PAL_SUPPORT 1 ;undefine to exclude PAL support
|
||||
.define FT_NTSC_SUPPORT 1 ;undefine to exclude NTSC support
|
||||
|
||||
.segment "ZEROPAGE"
|
||||
|
||||
NTSC_MODE: .res 1
|
||||
FRAME_CNT1: .res 1
|
||||
FRAME_CNT2: .res 1
|
||||
VRAM_UPDATE: .res 1
|
||||
NAME_UPD_ADR: .res 2
|
||||
NAME_UPD_ENABLE: .res 1
|
||||
PAL_UPDATE: .res 1
|
||||
PAL_BG_PTR: .res 2
|
||||
PAL_SPR_PTR: .res 2
|
||||
SCROLL_X: .res 1
|
||||
SCROLL_Y: .res 1
|
||||
SCROLL_X1: .res 1
|
||||
SCROLL_Y1: .res 1
|
||||
PPU_CTRL_VAR: .res 1
|
||||
PPU_CTRL_VAR1: .res 1
|
||||
PPU_MASK_VAR: .res 1
|
||||
;;FT_TEMP: .res 3
|
||||
_oam_off: .res 1
|
||||
NMICallback: .res 3
|
||||
|
||||
TEMP: .res 11
|
||||
|
||||
.exportzp NTSC_MODE, FRAME_CNT1, FRAME_CNT2, VRAM_UPDATE
|
||||
.exportzp NAME_UPD_ADR, NAME_UPD_ENABLE
|
||||
.exportzp PAL_UPDATE, PAL_BG_PTR, PAL_SPR_PTR
|
||||
.exportzp SCROLL_X, SCROLL_Y, SCROLL_X1, SCROLL_Y1
|
||||
.exportzp PPU_CTRL_VAR, PPU_CTRL_VAR1, PPU_MASK_VAR
|
||||
.exportzp _oam_off, NMICallback
|
||||
.exportzp TEMP
|
||||
|
||||
.include "zpvars.inc"
|
||||
|
||||
.segment "HEADER"
|
||||
|
||||
.byte $4e,$45,$53,$1a
|
||||
.byte <NES_PRG_BANKS
|
||||
.byte <NES_CHR_BANKS
|
||||
.byte <NES_MIRRORING|(<NES_MAPPER<<4)
|
||||
.byte <NES_MAPPER&$f0
|
||||
.res 8,0
|
||||
|
||||
|
||||
|
||||
.segment "STARTUP"
|
||||
|
||||
start:
|
||||
_exit:
|
||||
|
||||
sei
|
||||
ldx #$ff
|
||||
txs
|
||||
inx
|
||||
stx PPU_MASK
|
||||
stx DMC_FREQ
|
||||
stx PPU_CTRL ;no NMI
|
||||
|
||||
initPPU:
|
||||
|
||||
bit PPU_STATUS
|
||||
@1:
|
||||
bit PPU_STATUS
|
||||
bpl @1
|
||||
@2:
|
||||
bit PPU_STATUS
|
||||
bpl @2
|
||||
|
||||
; no APU frame counter IRQs
|
||||
lda #$40
|
||||
sta PPU_FRAMECNT
|
||||
|
||||
clearPalette:
|
||||
|
||||
lda #$3f
|
||||
sta PPU_ADDR
|
||||
stx PPU_ADDR
|
||||
lda #$0f
|
||||
ldx #$20
|
||||
@1:
|
||||
sta PPU_DATA
|
||||
dex
|
||||
bne @1
|
||||
|
||||
clearVRAM:
|
||||
|
||||
txa
|
||||
ldy #$20
|
||||
sty PPU_ADDR
|
||||
sta PPU_ADDR
|
||||
ldy #$10
|
||||
@1:
|
||||
sta PPU_DATA
|
||||
inx
|
||||
bne @1
|
||||
dey
|
||||
bne @1
|
||||
|
||||
clearRAM:
|
||||
|
||||
txa
|
||||
@1:
|
||||
sta $000,x
|
||||
sta $100,x
|
||||
sta $200,x
|
||||
sta $300,x
|
||||
sta $400,x
|
||||
sta $500,x
|
||||
sta $600,x
|
||||
sta $700,x
|
||||
inx
|
||||
bne @1
|
||||
|
||||
lda #4
|
||||
jsr _pal_bright
|
||||
jsr _pal_clear
|
||||
jsr _oam_clear
|
||||
|
||||
jsr zerobss
|
||||
jsr copydata
|
||||
|
||||
lda #<(__RAM_START__+__RAM_SIZE__)
|
||||
sta sp
|
||||
lda #>(__RAM_START__+__RAM_SIZE__)
|
||||
sta sp+1 ; Set argument stack ptr
|
||||
|
||||
jsr initlib
|
||||
|
||||
; setup NMICallback trampoline to NOP
|
||||
lda #$4C ;JMP xxxx
|
||||
sta NMICallback
|
||||
lda #<HandyRTS
|
||||
sta NMICallback+1
|
||||
lda #>HandyRTS
|
||||
sta NMICallback+2
|
||||
|
||||
lda #%10000000
|
||||
sta <PPU_CTRL_VAR
|
||||
sta PPU_CTRL ;enable NMI
|
||||
lda #%00000110
|
||||
sta <PPU_MASK_VAR
|
||||
|
||||
waitSync3:
|
||||
lda <FRAME_CNT1
|
||||
@1:
|
||||
cmp <FRAME_CNT1
|
||||
beq @1
|
||||
|
||||
detectNTSC:
|
||||
ldx #52 ;blargg's code
|
||||
ldy #24
|
||||
@1:
|
||||
dex
|
||||
bne @1
|
||||
dey
|
||||
bne @1
|
||||
|
||||
lda PPU_STATUS
|
||||
and #$80
|
||||
sta <NTSC_MODE
|
||||
|
||||
jsr _ppu_off
|
||||
|
||||
lda #0
|
||||
sta PPU_SCROLL
|
||||
sta PPU_SCROLL
|
||||
sta PPU_OAM_ADDR
|
||||
|
||||
jmp _main ;no parameters
|
||||
|
||||
.include "neslib.sinc"
|
||||
|
||||
.segment "CHARS"
|
||||
;;
|
||||
|
||||
.segment "SAMPLES"
|
||||
;;
|
||||
|
||||
.segment "VECTORS"
|
||||
|
||||
.word nmi ;$fffa vblank nmi
|
||||
.word start ;$fffc reset
|
||||
.word irq ;$fffe irq / brk
|
||||
|
1243
LibMultiSpacc/neslib/famitone2.sinc
Normal file
1243
LibMultiSpacc/neslib/famitone2.sinc
Normal file
File diff suppressed because it is too large
Load Diff
349
LibMultiSpacc/neslib/lz4vram.s
Normal file
349
LibMultiSpacc/neslib/lz4vram.s
Normal file
@ -0,0 +1,349 @@
|
||||
;
|
||||
; Lauri Kasanen, 6 Jun 2017
|
||||
; (C) Mega Cat Studios
|
||||
; An optimized LZ4 decompressor
|
||||
;
|
||||
|
||||
.importzp sp, sreg, regsave, regbank
|
||||
.importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4
|
||||
.macpack longbranch
|
||||
.import pushax,popax,_vram_write
|
||||
.export _vram_unlz4
|
||||
|
||||
_out = regsave
|
||||
_written = regsave + 2
|
||||
_tmp = tmp1
|
||||
_token = tmp2
|
||||
_offset = ptr3
|
||||
_in = sreg
|
||||
_outlen = ptr4
|
||||
|
||||
PPU_ADDR = $2006
|
||||
PPU_DATA = $2007
|
||||
|
||||
; ---------------------------------------------------------------
|
||||
; void decompress_lz4 (const u8 *in, u8 * const out, const u16 outlen)
|
||||
; ---------------------------------------------------------------
|
||||
|
||||
.segment "CODE"
|
||||
|
||||
; size in ptr3, src in ptr1, dest in ptr2
|
||||
; don't touch size
|
||||
memcpy_r2v:
|
||||
|
||||
lda ptr2+1
|
||||
sta PPU_ADDR
|
||||
lda ptr2
|
||||
sta PPU_ADDR
|
||||
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
jsr pushax
|
||||
|
||||
lda ptr3
|
||||
ldx ptr3+1
|
||||
|
||||
jmp _vram_write
|
||||
|
||||
memcpy_v2v:
|
||||
|
||||
lda #0
|
||||
sta tmp3
|
||||
sta tmp4
|
||||
jmp @check
|
||||
|
||||
@loop:
|
||||
; read source byte
|
||||
lda ptr1+1
|
||||
sta PPU_ADDR
|
||||
lda ptr1
|
||||
sta PPU_ADDR
|
||||
|
||||
ldx PPU_DATA
|
||||
ldx PPU_DATA
|
||||
|
||||
inc ptr1
|
||||
bne @nosrcinc
|
||||
inc ptr1+1
|
||||
@nosrcinc:
|
||||
|
||||
; write dst byte
|
||||
lda ptr2+1
|
||||
sta PPU_ADDR
|
||||
lda ptr2
|
||||
sta PPU_ADDR
|
||||
|
||||
stx PPU_DATA
|
||||
|
||||
inc ptr2
|
||||
bne @nodstinc
|
||||
inc ptr2+1
|
||||
@nodstinc:
|
||||
|
||||
; increase counter
|
||||
inc tmp3
|
||||
bne @noinc
|
||||
inc tmp4
|
||||
@noinc:
|
||||
|
||||
@check:
|
||||
lda tmp3
|
||||
cmp ptr3
|
||||
lda tmp4
|
||||
sbc ptr3+1
|
||||
bcc @loop
|
||||
|
||||
rts
|
||||
|
||||
.proc _vram_unlz4: near
|
||||
|
||||
sta _outlen
|
||||
stx _outlen+1
|
||||
|
||||
jsr popax
|
||||
sta _out
|
||||
stx _out+1
|
||||
|
||||
jsr popax
|
||||
sta _in
|
||||
stx _in+1
|
||||
|
||||
;
|
||||
; written = 0;
|
||||
;
|
||||
lda #$00
|
||||
sta _written
|
||||
;
|
||||
; while (written < outlen) {
|
||||
;
|
||||
jmp L0046
|
||||
;
|
||||
; token = *in++;
|
||||
;
|
||||
L0004: ldy #0
|
||||
lda (_in),y
|
||||
sta _token
|
||||
|
||||
inc _in
|
||||
bne L000A
|
||||
inc _in+1
|
||||
L000A:
|
||||
;
|
||||
; offset = token >> 4;
|
||||
;
|
||||
ldx #$00
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
sta _offset
|
||||
stx _offset+1
|
||||
;
|
||||
; token &= 0xf;
|
||||
; token += 4; // Minmatch
|
||||
;
|
||||
lda _token
|
||||
and #$0F
|
||||
clc
|
||||
adc #4
|
||||
sta _token
|
||||
;
|
||||
; if (offset == 15) {
|
||||
;
|
||||
lda _offset
|
||||
cmp #$0F
|
||||
L0013: bne L001A
|
||||
;
|
||||
; tmp = *in++;
|
||||
;
|
||||
ldy #0
|
||||
lda (_in),y
|
||||
sta _tmp
|
||||
|
||||
inc _in
|
||||
bne L0017
|
||||
inc _in+1
|
||||
L0017:
|
||||
;
|
||||
; offset += tmp;
|
||||
;
|
||||
clc
|
||||
adc _offset
|
||||
sta _offset
|
||||
lda #$00
|
||||
adc _offset+1
|
||||
sta _offset+1
|
||||
;
|
||||
; if (tmp == 255)
|
||||
;
|
||||
lda _tmp
|
||||
cmp #$FF
|
||||
;
|
||||
; goto moreliterals;
|
||||
;
|
||||
jmp L0013
|
||||
;
|
||||
; if (offset) {
|
||||
;
|
||||
L001A: lda _offset
|
||||
ora _offset+1
|
||||
beq L001C
|
||||
;
|
||||
; memcpy(&out[written], in, offset);
|
||||
;
|
||||
lda _out
|
||||
clc
|
||||
adc _written
|
||||
sta ptr2
|
||||
lda _out+1
|
||||
adc _written+1
|
||||
tax
|
||||
stx ptr2+1
|
||||
lda _in
|
||||
ldx _in+1
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
jsr memcpy_r2v
|
||||
;
|
||||
; written += offset;
|
||||
;
|
||||
lda _offset
|
||||
clc
|
||||
adc _written
|
||||
sta _written
|
||||
lda _offset+1
|
||||
adc _written+1
|
||||
sta _written+1
|
||||
;
|
||||
; in += offset;
|
||||
;
|
||||
lda _offset
|
||||
clc
|
||||
adc _in
|
||||
sta _in
|
||||
lda _offset+1
|
||||
adc _in+1
|
||||
sta _in+1
|
||||
;
|
||||
; if (written >= outlen)
|
||||
;
|
||||
L001C: lda _written
|
||||
cmp _outlen
|
||||
lda _written+1
|
||||
sbc _outlen+1
|
||||
;
|
||||
; return;
|
||||
;
|
||||
bcc L0047
|
||||
rts
|
||||
;
|
||||
; memcpy(&offset, in, 2);
|
||||
;
|
||||
L0047: ldy #0
|
||||
lda (_in),y
|
||||
sta _offset
|
||||
iny
|
||||
lda (_in),y
|
||||
sta _offset+1
|
||||
;
|
||||
; in += 2;
|
||||
;
|
||||
lda #$02
|
||||
clc
|
||||
adc _in
|
||||
sta _in
|
||||
bcc L002F
|
||||
inc _in+1
|
||||
;
|
||||
; copysrc = out + written - offset;
|
||||
;
|
||||
L002F: lda _out
|
||||
clc
|
||||
adc _written
|
||||
pha
|
||||
lda _out+1
|
||||
adc _written+1
|
||||
tax
|
||||
pla
|
||||
sec
|
||||
sbc _offset
|
||||
sta ptr1
|
||||
txa
|
||||
sbc _offset+1
|
||||
sta ptr1+1
|
||||
;
|
||||
; offset = token;
|
||||
;
|
||||
lda #$00
|
||||
sta _offset+1
|
||||
lda _token
|
||||
sta _offset
|
||||
;
|
||||
; if (token == 19) {
|
||||
;
|
||||
cmp #$13
|
||||
L0045: bne L003C
|
||||
;
|
||||
; tmp = *in++;
|
||||
;
|
||||
ldy #0
|
||||
lda (_in),y
|
||||
sta _tmp
|
||||
|
||||
inc _in
|
||||
bne L0039
|
||||
inc _in+1
|
||||
L0039:
|
||||
;
|
||||
; offset += tmp;
|
||||
;
|
||||
clc
|
||||
adc _offset
|
||||
sta _offset
|
||||
tya
|
||||
adc _offset+1
|
||||
sta _offset+1
|
||||
;
|
||||
; if (tmp == 255)
|
||||
;
|
||||
lda _tmp
|
||||
cmp #$FF
|
||||
;
|
||||
; goto morematches;
|
||||
;
|
||||
jmp L0045
|
||||
;
|
||||
; memcpy(&out[written], copysrc, offset);
|
||||
;
|
||||
L003C: lda _out
|
||||
clc
|
||||
adc _written
|
||||
sta ptr2
|
||||
lda _out+1
|
||||
adc _written+1
|
||||
tax
|
||||
stx ptr2+1
|
||||
jsr memcpy_v2v
|
||||
;
|
||||
; written += offset;
|
||||
;
|
||||
lda _offset
|
||||
clc
|
||||
adc _written
|
||||
sta _written
|
||||
lda _offset+1
|
||||
adc _written+1
|
||||
L0046: sta _written+1
|
||||
;
|
||||
; while (written < outlen) {
|
||||
;
|
||||
lda _written
|
||||
cmp _outlen
|
||||
lda _written+1
|
||||
sbc _outlen+1
|
||||
jcc L0004
|
||||
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
49
LibMultiSpacc/neslib/memfill.s
Normal file
49
LibMultiSpacc/neslib/memfill.s
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
.importzp TEMP
|
||||
.import popa, popax
|
||||
.include "zpvars.inc"
|
||||
.export _memfill
|
||||
|
||||
;void __fastcall__ memfill(void *dst,unsigned char value,unsigned int len);
|
||||
|
||||
_memfill:
|
||||
|
||||
sta <LEN
|
||||
stx <LEN+1
|
||||
jsr popa
|
||||
sta <TEMP
|
||||
jsr popax
|
||||
sta <DST
|
||||
stx <DST+1
|
||||
|
||||
ldx #0
|
||||
|
||||
@1:
|
||||
|
||||
lda <LEN+1
|
||||
beq @2
|
||||
jsr @3
|
||||
dec <LEN+1
|
||||
inc <DST+1
|
||||
jmp @1
|
||||
|
||||
@2:
|
||||
|
||||
ldx <LEN
|
||||
beq @5
|
||||
|
||||
@3:
|
||||
|
||||
ldy #0
|
||||
lda <TEMP
|
||||
|
||||
@4:
|
||||
|
||||
sta (DST),y
|
||||
iny
|
||||
dex
|
||||
bne @4
|
||||
|
||||
@5:
|
||||
|
||||
rts
|
16
LibMultiSpacc/neslib/nes.inc
Normal file
16
LibMultiSpacc/neslib/nes.inc
Normal file
@ -0,0 +1,16 @@
|
||||
PPU_CTRL =$2000
|
||||
PPU_MASK =$2001
|
||||
PPU_STATUS =$2002
|
||||
PPU_OAM_ADDR =$2003
|
||||
PPU_OAM_DATA =$2004
|
||||
PPU_SCROLL =$2005
|
||||
PPU_ADDR =$2006
|
||||
PPU_DATA =$2007
|
||||
PPU_OAM_DMA =$4014
|
||||
PPU_FRAMECNT =$4017
|
||||
DMC_FREQ =$4010
|
||||
CTRL_PORT1 =$4016
|
||||
CTRL_PORT2 =$4017
|
||||
|
||||
OAM_BUF =$0200
|
||||
PAL_BUF =$01c0
|
339
LibMultiSpacc/neslib/neslib.h
Normal file
339
LibMultiSpacc/neslib/neslib.h
Normal file
@ -0,0 +1,339 @@
|
||||
#ifndef _NESLIB_H
|
||||
#define _NESLIB_H
|
||||
/*
|
||||
(C) 2015 Alex Semenov (Shiru)
|
||||
(C) 2016 Lauri Kasanen
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
// NES hardware-dependent functions by Shiru (shiru@mail.ru)
|
||||
// Feel free to do anything you want with this code, consider it Public Domain
|
||||
|
||||
// Versions history:
|
||||
// 280215 - fixed palette glitch caused with the active DMC DMA glitch
|
||||
// 030914 - minor fixes in the vram update system
|
||||
// 310814 - added vram_flush_update
|
||||
// 120414 - removed adr argument from vram_write and vram_read,
|
||||
// unrle_vram renamed to vram_unrle, with adr argument removed
|
||||
// 060414 - many fixes and improvements, including sequental VRAM updates
|
||||
// previous versions were created since mid-2011, there were many updates
|
||||
// xxxx19 - updated by sehugg@8bitworkshop
|
||||
|
||||
|
||||
// define basic types for convenience
|
||||
typedef unsigned char byte; // 8-bit unsigned
|
||||
typedef signed char sbyte; // 8-bit signed
|
||||
typedef unsigned short word; // 16-bit signed
|
||||
typedef enum { false, true } bool; // boolean
|
||||
|
||||
|
||||
// set bg and spr palettes, data is 32 bytes array
|
||||
void __fastcall__ pal_all(const char *data);
|
||||
|
||||
// set bg palette only, data is 16 bytes array
|
||||
void __fastcall__ pal_bg(const char *data);
|
||||
|
||||
// set spr palette only, data is 16 bytes array
|
||||
void __fastcall__ pal_spr(const char *data);
|
||||
|
||||
// set a palette entry, index is 0..31
|
||||
void __fastcall__ pal_col(unsigned char index, unsigned char color);
|
||||
|
||||
// reset palette to $0f
|
||||
void __fastcall__ pal_clear(void);
|
||||
|
||||
// set virtual bright both for sprites and background, 0 is black, 4 is normal, 8 is white
|
||||
void __fastcall__ pal_bright(unsigned char bright);
|
||||
|
||||
// set virtual bright for sprites only
|
||||
void __fastcall__ pal_spr_bright(unsigned char bright);
|
||||
|
||||
// set virtual bright for sprites background only
|
||||
void __fastcall__ pal_bg_bright(unsigned char bright);
|
||||
|
||||
|
||||
|
||||
// wait actual TV frame, 50hz for PAL, 60hz for NTSC
|
||||
void __fastcall__ ppu_wait_nmi(void);
|
||||
|
||||
// wait virtual frame, it is always 50hz, frame-to-frame in PAL, frameskip in NTSC
|
||||
void __fastcall__ ppu_wait_frame(void);
|
||||
|
||||
// turn off rendering, nmi still enabled when rendering is disabled
|
||||
void __fastcall__ ppu_off(void);
|
||||
|
||||
// turn on bg, spr
|
||||
void __fastcall__ ppu_on_all(void);
|
||||
|
||||
// turn on bg only
|
||||
void __fastcall__ ppu_on_bg(void);
|
||||
|
||||
// turn on spr only
|
||||
void __fastcall__ ppu_on_spr(void);
|
||||
|
||||
// set PPU_MASK directly
|
||||
void __fastcall__ ppu_mask(unsigned char mask);
|
||||
|
||||
// get current video system, 0 for PAL, not 0 for NTSC
|
||||
unsigned char __fastcall__ ppu_system(void);
|
||||
|
||||
// Return an 8-bit counter incremented at each vblank
|
||||
unsigned char __fastcall__ nesclock(void);
|
||||
|
||||
// get/set the internal ppu ctrl cache var for manual writing
|
||||
unsigned char __fastcall__ get_ppu_ctrl_var(void);
|
||||
void __fastcall__ set_ppu_ctrl_var(unsigned char var);
|
||||
|
||||
|
||||
// clear OAM buffer, all the sprites are hidden
|
||||
void __fastcall__ oam_clear(void);
|
||||
|
||||
// set sprite display mode, 0 for 8x8 sprites, 1 for 8x16 sprites
|
||||
void __fastcall__ oam_size(unsigned char size);
|
||||
|
||||
// set sprite in OAM buffer, chrnum is tile, attr is attribute, sprid is offset in OAM in bytes
|
||||
// returns sprid+4, which is offset for a next sprite
|
||||
unsigned char __fastcall__ oam_spr(unsigned char x, unsigned char y,
|
||||
unsigned char chrnum, unsigned char attr,
|
||||
unsigned char sprid);
|
||||
|
||||
// set metasprite in OAM buffer
|
||||
// meta sprite is a const unsigned char array, it contains four bytes per sprite
|
||||
// in order x offset, y offset, tile, attribute
|
||||
// x=128 is end of a meta sprite
|
||||
// returns sprid+4, which is offset for a next sprite
|
||||
unsigned char __fastcall__ oam_meta_spr(unsigned char x, unsigned char y,
|
||||
unsigned char sprid, const unsigned char *data);
|
||||
|
||||
// hide all remaining sprites from given offset
|
||||
void __fastcall__ oam_hide_rest(unsigned char sprid);
|
||||
|
||||
|
||||
// initialize the FamiTone system
|
||||
void __fastcall__ famitone_init(void* music_data);
|
||||
|
||||
// initialize the FamiTone SFX system
|
||||
void __fastcall__ sfx_init(void* sounds_data);
|
||||
|
||||
// play a music in FamiTone format
|
||||
void __fastcall__ music_play(unsigned char song);
|
||||
|
||||
// stop music
|
||||
void __fastcall__ music_stop(void);
|
||||
|
||||
// pause and unpause music
|
||||
void __fastcall__ music_pause(unsigned char pause);
|
||||
|
||||
// play FamiTone sound effect on channel 0..3
|
||||
void __fastcall__ sfx_play(unsigned char sound, unsigned char channel);
|
||||
|
||||
// play a DPCM sample, 1..63
|
||||
void __fastcall__ sample_play(unsigned char sample);
|
||||
|
||||
// call from NMI once per frame
|
||||
void __fastcall__ famitone_update(void);
|
||||
|
||||
|
||||
// poll controller and return flags like PAD_LEFT etc, input is pad number (0 or 1)
|
||||
unsigned char __fastcall__ pad_poll(unsigned char pad);
|
||||
|
||||
// poll controller in trigger mode, a flag is set only on button down, not hold
|
||||
// if you need to poll the pad in both normal and trigger mode, poll it in the
|
||||
// trigger mode for first, then use pad_state
|
||||
unsigned char __fastcall__ pad_trigger(unsigned char pad);
|
||||
|
||||
// get previous pad state without polling ports
|
||||
unsigned char __fastcall__ pad_state(unsigned char pad);
|
||||
|
||||
|
||||
// set scroll, including the top bits
|
||||
// it is always applied at beginning of a TV frame, not at the function call
|
||||
void __fastcall__ scroll(unsigned int x, unsigned int y);
|
||||
|
||||
// set scroll after screen split invoked by the sprite 0 hit
|
||||
// warning: all CPU time between the function call and the actual split point will be wasted!
|
||||
// warning: the program loop has to fit into the frame time, ppu_wait_frame should not be used
|
||||
// otherwise empty frames without split will be inserted, resulting in jumpy screen
|
||||
// warning: only X scroll could be changed in this version
|
||||
void __fastcall__ split(unsigned int x, unsigned int y);
|
||||
|
||||
// set scroll after screen split invoked by the sprite 0 hit
|
||||
// sets both X and Y, but timing might be iffy depending
|
||||
// on exact sprite 0 position
|
||||
void __fastcall__ splitxy(unsigned int x, unsigned int y);
|
||||
|
||||
|
||||
// select current chr bank for sprites, 0..1
|
||||
void __fastcall__ bank_spr(unsigned char n);
|
||||
|
||||
// select current chr bank for background, 0..1
|
||||
void __fastcall__ bank_bg(unsigned char n);
|
||||
|
||||
|
||||
|
||||
// get random number 0..255 or 0..65535
|
||||
unsigned char __fastcall__ rand8(void);
|
||||
unsigned int __fastcall__ rand16(void);
|
||||
|
||||
// set random seed
|
||||
void __fastcall__ set_rand(unsigned int seed);
|
||||
|
||||
|
||||
|
||||
// when display is enabled, vram access could only be done with this vram update system
|
||||
// the function sets a pointer to the update buffer that contains data and addresses
|
||||
// in a special format. It allows to write non-sequental bytes, as well as horizontal or
|
||||
// vertical nametable sequences.
|
||||
// buffer pointer could be changed during rendering, but it only takes effect on a new frame
|
||||
// number of transferred bytes is limited by vblank time
|
||||
// to disable updates, call this function with NULL pointer
|
||||
|
||||
// the update data format:
|
||||
// MSB, LSB, byte for a non-sequental write
|
||||
// MSB|NT_UPD_HORZ, LSB, LEN, [bytes] for a horizontal sequence
|
||||
// MSB|NT_UPD_VERT, LSB, LEN, [bytes] for a vertical sequence
|
||||
// NT_UPD_EOF to mark end of the buffer
|
||||
|
||||
// length of this data should be under 256 bytes
|
||||
|
||||
void __fastcall__ set_vram_update(unsigned char *buf);
|
||||
|
||||
// all following vram functions only work when display is disabled
|
||||
|
||||
// do a series of VRAM writes, the same format as for set_vram_update, but writes done right away
|
||||
void __fastcall__ flush_vram_update(unsigned char *buf);
|
||||
|
||||
// set vram pointer to write operations if you need to write some data to vram
|
||||
void __fastcall__ vram_adr(unsigned int adr);
|
||||
|
||||
// put a byte at current vram address, works only when rendering is turned off
|
||||
void __fastcall__ vram_put(unsigned char n);
|
||||
|
||||
// fill a block with a byte at current vram address, works only when rendering is turned off
|
||||
void __fastcall__ vram_fill(unsigned char n, unsigned int len);
|
||||
|
||||
// set vram autoincrement, 0 for +1 and not 0 for +32
|
||||
void __fastcall__ vram_inc(unsigned char n);
|
||||
|
||||
// read a block from current address of vram, works only when rendering is turned off
|
||||
void __fastcall__ vram_read(unsigned char *dst, unsigned int size);
|
||||
|
||||
// write a block to current address of vram, works only when rendering is turned off
|
||||
void __fastcall__ vram_write(const unsigned char *src, unsigned int size);
|
||||
|
||||
|
||||
// unpack RLE data to current address of vram, mostly used for nametables
|
||||
void __fastcall__ vram_unrle(const unsigned char *data);
|
||||
|
||||
// unpack LZ4 data to this address
|
||||
void __fastcall__ vram_unlz4(const unsigned char *in, unsigned char *out,
|
||||
const unsigned uncompressed_size);
|
||||
/*
|
||||
Rough speeds for a full 1024 nametable:
|
||||
- rle takes 0.5 frames
|
||||
- uncompressed takes 1.3 frames
|
||||
- lz4 takes 2.8 frames
|
||||
*/
|
||||
|
||||
|
||||
// like memset, but does not return anything
|
||||
void __fastcall__ memfill(void *dst, unsigned char value, unsigned int len);
|
||||
|
||||
// delay for N frames
|
||||
void __fastcall__ delay(unsigned char frames);
|
||||
|
||||
// display.sinc functions
|
||||
void __fastcall__ oam_clear_fast(void);
|
||||
void __fastcall__ oam_meta_spr_pal(unsigned char x,unsigned char y,unsigned char pal,const unsigned char *metasprite);
|
||||
void __fastcall__ oam_meta_spr_clip(signed int x,unsigned char y,const unsigned char *metasprite);
|
||||
|
||||
// set NMI/IRQ callback
|
||||
void __fastcall__ nmi_set_callback(void (*callback)(void));
|
||||
|
||||
|
||||
|
||||
#define PAD_A 0x01
|
||||
#define PAD_B 0x02
|
||||
#define PAD_SELECT 0x04
|
||||
#define PAD_START 0x08
|
||||
#define PAD_UP 0x10
|
||||
#define PAD_DOWN 0x20
|
||||
#define PAD_LEFT 0x40
|
||||
#define PAD_RIGHT 0x80
|
||||
|
||||
#define OAM_FLIP_V 0x80
|
||||
#define OAM_FLIP_H 0x40
|
||||
#define OAM_BEHIND 0x20
|
||||
|
||||
#define MAX(x1,x2) ((x1)<(x2)?(x2):(x1))
|
||||
#define MIN(x1,x2) ((x1)<(x2)?(x1):(x2))
|
||||
|
||||
#define MASK_SPR 0x10
|
||||
#define MASK_BG 0x08
|
||||
#define MASK_EDGE_SPR 0x04
|
||||
#define MASK_EDGE_BG 0x02
|
||||
#define MASK_TINT_RED 0x20
|
||||
#define MASK_TINT_BLUE 0x40
|
||||
#define MASK_TINT_GREEN 0x80
|
||||
#define MASK_MONO 0x01
|
||||
|
||||
#define NAMETABLE_A 0x2000
|
||||
#define NAMETABLE_B 0x2400
|
||||
#define NAMETABLE_C 0x2800
|
||||
#define NAMETABLE_D 0x2c00
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define NT_UPD_HORZ 0x40
|
||||
#define NT_UPD_VERT 0x80
|
||||
#define NT_UPD_EOF 0xff
|
||||
|
||||
// macro to calculate nametable address from X,Y in compile time
|
||||
|
||||
#define NTADR_A(x,y) (NAMETABLE_A|(((y)<<5)|(x)))
|
||||
#define NTADR_B(x,y) (NAMETABLE_B|(((y)<<5)|(x)))
|
||||
#define NTADR_C(x,y) (NAMETABLE_C|(((y)<<5)|(x)))
|
||||
#define NTADR_D(x,y) (NAMETABLE_D|(((y)<<5)|(x)))
|
||||
|
||||
// macro to get MSB and LSB
|
||||
|
||||
#define MSB(x) (((x)>>8))
|
||||
#define LSB(x) (((x)&0xff))
|
||||
|
||||
// OAM buffer @ $200-$2FF
|
||||
|
||||
typedef struct OAMSprite {
|
||||
byte y; // Y coordinate
|
||||
byte name; // tile index in name table
|
||||
byte attr; // attribute flags
|
||||
byte x; // X coordinate
|
||||
} OAMSprite;
|
||||
|
||||
#define OAMBUF ((OAMSprite*) 0x200)
|
||||
|
||||
// OAM offset for spr_pal and spr_clip
|
||||
|
||||
extern byte oam_off;
|
||||
#pragma zpsym ("oam_off")
|
||||
|
||||
#endif /* neslib.h */
|
||||
|
791
LibMultiSpacc/neslib/neslib.sinc
Normal file
791
LibMultiSpacc/neslib/neslib.sinc
Normal file
@ -0,0 +1,791 @@
|
||||
;NES hardware-dependent functions by Shiru (shiru@mail.ru)
|
||||
;with improvements by VEG
|
||||
;Feel free to do anything you want with this code, consider it Public Domain
|
||||
|
||||
|
||||
.export _pal_all,_pal_bg,_pal_spr,_pal_col,_pal_clear
|
||||
.export _pal_bright,_pal_spr_bright,_pal_bg_bright
|
||||
.export _ppu_off,_ppu_on_all,_ppu_on_bg,_ppu_on_spr,_ppu_mask,_ppu_system
|
||||
.export _oam_clear,_oam_size,_oam_hide_rest
|
||||
.export _ppu_wait_frame,_ppu_wait_nmi
|
||||
.export _scroll
|
||||
.export _bank_spr,_bank_bg
|
||||
.export _vram_write
|
||||
.export _vram_adr,_vram_put,_vram_fill,_vram_inc
|
||||
.export _set_vram_update,_flush_vram_update
|
||||
.export _delay
|
||||
.export _get_ppu_ctrl_var,_set_ppu_ctrl_var
|
||||
.export _nesclock
|
||||
.export _nmi_set_callback
|
||||
|
||||
|
||||
;NMI handler
|
||||
|
||||
nmi:
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
lda <PPU_MASK_VAR ;if rendering is disabled, do not access the VRAM at all
|
||||
and #%00011000
|
||||
bne @doUpdate
|
||||
jmp @skipAll
|
||||
|
||||
@doUpdate:
|
||||
|
||||
lda #>OAM_BUF ;update OAM
|
||||
sta PPU_OAM_DMA
|
||||
|
||||
lda <PAL_UPDATE ;update palette if needed
|
||||
bne @updPal
|
||||
jmp @updVRAM
|
||||
|
||||
@updPal:
|
||||
|
||||
ldx #0
|
||||
stx <PAL_UPDATE
|
||||
|
||||
lda #$3f
|
||||
sta PPU_ADDR
|
||||
stx PPU_ADDR
|
||||
|
||||
ldy PAL_BUF ;background color, remember it in X
|
||||
lda (PAL_BG_PTR),y
|
||||
sta PPU_DATA
|
||||
tax
|
||||
|
||||
.repeat 3,I
|
||||
ldy PAL_BUF+1+I
|
||||
lda (PAL_BG_PTR),y
|
||||
sta PPU_DATA
|
||||
.endrepeat
|
||||
|
||||
.repeat 3,J
|
||||
stx PPU_DATA ;background color
|
||||
.repeat 3,I
|
||||
ldy PAL_BUF+5+(J*4)+I
|
||||
lda (PAL_BG_PTR),y
|
||||
sta PPU_DATA
|
||||
.endrepeat
|
||||
.endrepeat
|
||||
|
||||
.repeat 4,J
|
||||
stx PPU_DATA ;background color
|
||||
.repeat 3,I
|
||||
ldy PAL_BUF+17+(J*4)+I
|
||||
lda (PAL_SPR_PTR),y
|
||||
sta PPU_DATA
|
||||
.endrepeat
|
||||
.endrepeat
|
||||
|
||||
@updVRAM:
|
||||
|
||||
lda <VRAM_UPDATE
|
||||
beq @skipUpd
|
||||
lda #0
|
||||
sta <VRAM_UPDATE
|
||||
|
||||
lda <NAME_UPD_ENABLE
|
||||
beq @skipUpd
|
||||
|
||||
jsr _flush_vram_update_nmi
|
||||
|
||||
@skipUpd:
|
||||
|
||||
lda #0
|
||||
sta PPU_ADDR
|
||||
sta PPU_ADDR
|
||||
|
||||
lda <SCROLL_X
|
||||
sta PPU_SCROLL
|
||||
lda <SCROLL_Y
|
||||
sta PPU_SCROLL
|
||||
|
||||
lda <PPU_CTRL_VAR
|
||||
sta PPU_CTRL
|
||||
|
||||
@skipAll:
|
||||
|
||||
lda <PPU_MASK_VAR
|
||||
sta PPU_MASK
|
||||
|
||||
inc <FRAME_CNT1
|
||||
inc <FRAME_CNT2
|
||||
lda <FRAME_CNT2
|
||||
cmp #6
|
||||
bne skipNtsc
|
||||
lda #0
|
||||
sta <FRAME_CNT2
|
||||
|
||||
skipNtsc:
|
||||
|
||||
jsr NMICallback
|
||||
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
|
||||
; IRQ: jumps to NMICallback, passing -1 as argument
|
||||
irq:
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
lda #$ff
|
||||
jmp skipNtsc
|
||||
|
||||
;void __fastcall__ nmi_set_callback(void (*callback)());
|
||||
|
||||
_nmi_set_callback:
|
||||
sta NMICallback+1
|
||||
stx NMICallback+2
|
||||
HandyRTS:
|
||||
rts
|
||||
|
||||
|
||||
;void __fastcall__ pal_all(const char *data);
|
||||
|
||||
_pal_all:
|
||||
|
||||
sta <PTR
|
||||
stx <PTR+1
|
||||
ldx #$00
|
||||
lda #$20
|
||||
|
||||
pal_copy:
|
||||
|
||||
sta <LEN
|
||||
|
||||
ldy #$00
|
||||
|
||||
@0:
|
||||
|
||||
lda (PTR),y
|
||||
sta PAL_BUF,x
|
||||
inx
|
||||
iny
|
||||
dec <LEN
|
||||
bne @0
|
||||
|
||||
inc <PAL_UPDATE
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ pal_bg(const char *data);
|
||||
|
||||
_pal_bg:
|
||||
|
||||
sta <PTR
|
||||
stx <PTR+1
|
||||
ldx #$00
|
||||
lda #$10
|
||||
bne pal_copy ;bra
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ pal_spr(const char *data);
|
||||
|
||||
_pal_spr:
|
||||
|
||||
sta <PTR
|
||||
stx <PTR+1
|
||||
ldx #$10
|
||||
txa
|
||||
bne pal_copy ;bra
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ pal_col(unsigned char index,unsigned char color);
|
||||
|
||||
_pal_col:
|
||||
|
||||
sta <PTR
|
||||
jsr popa
|
||||
and #$1f
|
||||
tax
|
||||
lda <PTR
|
||||
sta PAL_BUF,x
|
||||
inc <PAL_UPDATE
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ pal_clear(void);
|
||||
|
||||
_pal_clear:
|
||||
|
||||
lda #$0f
|
||||
ldx #0
|
||||
|
||||
@1:
|
||||
|
||||
sta PAL_BUF,x
|
||||
inx
|
||||
cpx #$20
|
||||
bne @1
|
||||
stx <PAL_UPDATE
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ pal_spr_bright(unsigned char bright);
|
||||
|
||||
_pal_spr_bright:
|
||||
|
||||
tax
|
||||
lda palBrightTableL,x
|
||||
sta <PAL_SPR_PTR
|
||||
lda palBrightTableH,x ;MSB is never zero
|
||||
sta <PAL_SPR_PTR+1
|
||||
sta <PAL_UPDATE
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ pal_bg_bright(unsigned char bright);
|
||||
|
||||
_pal_bg_bright:
|
||||
|
||||
tax
|
||||
lda palBrightTableL,x
|
||||
sta <PAL_BG_PTR
|
||||
lda palBrightTableH,x ;MSB is never zero
|
||||
sta <PAL_BG_PTR+1
|
||||
sta <PAL_UPDATE
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ pal_bright(unsigned char bright);
|
||||
|
||||
_pal_bright:
|
||||
|
||||
jsr _pal_spr_bright
|
||||
txa
|
||||
jmp _pal_bg_bright
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ ppu_off(void);
|
||||
|
||||
_ppu_off:
|
||||
|
||||
lda <PPU_MASK_VAR
|
||||
and #%11100111
|
||||
sta <PPU_MASK_VAR
|
||||
jmp _ppu_wait_nmi
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ ppu_on_all(void);
|
||||
|
||||
_ppu_on_all:
|
||||
|
||||
lda <PPU_MASK_VAR
|
||||
ora #%00011000
|
||||
|
||||
ppu_onoff:
|
||||
|
||||
sta <PPU_MASK_VAR
|
||||
jmp _ppu_wait_nmi
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ ppu_on_bg(void);
|
||||
|
||||
_ppu_on_bg:
|
||||
|
||||
lda <PPU_MASK_VAR
|
||||
ora #%00001000
|
||||
bne ppu_onoff ;bra
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ ppu_on_spr(void);
|
||||
|
||||
_ppu_on_spr:
|
||||
|
||||
lda <PPU_MASK_VAR
|
||||
ora #%00010000
|
||||
bne ppu_onoff ;bra
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ ppu_mask(unsigned char mask);
|
||||
|
||||
_ppu_mask:
|
||||
|
||||
sta <PPU_MASK_VAR
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;unsigned char __fastcall__ ppu_system(void);
|
||||
|
||||
_ppu_system:
|
||||
|
||||
lda <NTSC_MODE
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
;unsigned char __fastcall__ get_ppu_ctrl_var(void);
|
||||
|
||||
_get_ppu_ctrl_var:
|
||||
|
||||
lda <PPU_CTRL_VAR
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
;void __fastcall__ set_ppu_ctrl_var(unsigned char var);
|
||||
|
||||
_set_ppu_ctrl_var:
|
||||
|
||||
sta <PPU_CTRL_VAR
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ oam_clear(void);
|
||||
|
||||
_oam_clear:
|
||||
|
||||
ldx #0
|
||||
lda #$ff
|
||||
@1:
|
||||
sta OAM_BUF,x
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
bne @1
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ oam_size(unsigned char size);
|
||||
|
||||
_oam_size:
|
||||
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
and #$20
|
||||
sta <TEMP
|
||||
lda <PPU_CTRL_VAR
|
||||
and #$df
|
||||
ora <TEMP
|
||||
sta <PPU_CTRL_VAR
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ oam_hide_rest(unsigned char sprid);
|
||||
|
||||
_oam_hide_rest:
|
||||
|
||||
tax
|
||||
lda #240
|
||||
|
||||
@1:
|
||||
|
||||
sta OAM_BUF,x
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
bne @1
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ ppu_wait_frame(void);
|
||||
|
||||
_ppu_wait_frame:
|
||||
|
||||
lda #1
|
||||
sta <VRAM_UPDATE
|
||||
lda <FRAME_CNT1
|
||||
|
||||
@1:
|
||||
|
||||
cmp <FRAME_CNT1
|
||||
beq @1
|
||||
lda <NTSC_MODE
|
||||
beq @3
|
||||
|
||||
@2:
|
||||
|
||||
lda <FRAME_CNT2
|
||||
cmp #5
|
||||
beq @2
|
||||
|
||||
@3:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ ppu_wait_nmi(void);
|
||||
|
||||
_ppu_wait_nmi:
|
||||
|
||||
lda #1
|
||||
sta <VRAM_UPDATE
|
||||
lda <FRAME_CNT1
|
||||
@1:
|
||||
|
||||
cmp <FRAME_CNT1
|
||||
beq @1
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ scroll(unsigned int x,unsigned int y);
|
||||
|
||||
_scroll:
|
||||
|
||||
sta <TEMP
|
||||
|
||||
txa
|
||||
bne @1
|
||||
lda <TEMP
|
||||
cmp #240
|
||||
bcs @1
|
||||
sta <SCROLL_Y
|
||||
lda #0
|
||||
sta <TEMP
|
||||
beq @2 ;bra
|
||||
|
||||
@1:
|
||||
|
||||
sec
|
||||
lda <TEMP
|
||||
sbc #240
|
||||
sta <SCROLL_Y
|
||||
lda #2
|
||||
sta <TEMP
|
||||
|
||||
@2:
|
||||
|
||||
jsr popax
|
||||
sta <SCROLL_X
|
||||
txa
|
||||
and #$01
|
||||
ora <TEMP
|
||||
sta <TEMP
|
||||
lda <PPU_CTRL_VAR
|
||||
and #$fc
|
||||
ora <TEMP
|
||||
sta <PPU_CTRL_VAR
|
||||
rts
|
||||
|
||||
|
||||
;void __fastcall__ bank_spr(unsigned char n);
|
||||
|
||||
_bank_spr:
|
||||
|
||||
and #$01
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
sta <TEMP
|
||||
lda <PPU_CTRL_VAR
|
||||
and #%11110111
|
||||
ora <TEMP
|
||||
sta <PPU_CTRL_VAR
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ bank_bg(unsigned char n);
|
||||
|
||||
_bank_bg:
|
||||
|
||||
and #$01
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
asl a
|
||||
sta <TEMP
|
||||
lda <PPU_CTRL_VAR
|
||||
and #%11101111
|
||||
ora <TEMP
|
||||
sta <PPU_CTRL_VAR
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ vram_write(unsigned char *src,unsigned int size);
|
||||
|
||||
_vram_write:
|
||||
|
||||
sta <TEMP
|
||||
stx <TEMP+1
|
||||
|
||||
jsr popax
|
||||
sta <TEMP+2
|
||||
stx <TEMP+3
|
||||
|
||||
ldy #0
|
||||
|
||||
@1:
|
||||
|
||||
lda (TEMP+2),y
|
||||
sta PPU_DATA
|
||||
inc <TEMP+2
|
||||
bne @2
|
||||
inc <TEMP+3
|
||||
|
||||
@2:
|
||||
|
||||
lda <TEMP
|
||||
bne @3
|
||||
dec <TEMP+1
|
||||
|
||||
@3:
|
||||
|
||||
dec <TEMP
|
||||
lda <TEMP
|
||||
ora <TEMP+1
|
||||
bne @1
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ set_vram_update(unsigned char *buf);
|
||||
|
||||
_set_vram_update:
|
||||
|
||||
sta <NAME_UPD_ADR+0
|
||||
stx <NAME_UPD_ADR+1
|
||||
ora <NAME_UPD_ADR+1
|
||||
sta <NAME_UPD_ENABLE
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ flush_vram_update(unsigned char *buf);
|
||||
|
||||
_flush_vram_update:
|
||||
|
||||
sta <NAME_UPD_ADR+0
|
||||
stx <NAME_UPD_ADR+1
|
||||
|
||||
_flush_vram_update_nmi:
|
||||
|
||||
ldy #0
|
||||
|
||||
@updName:
|
||||
|
||||
lda (NAME_UPD_ADR),y
|
||||
iny
|
||||
cmp #$40 ;is it a non-sequental write?
|
||||
bcs @updNotSeq
|
||||
sta PPU_ADDR
|
||||
lda (NAME_UPD_ADR),y
|
||||
iny
|
||||
sta PPU_ADDR
|
||||
lda (NAME_UPD_ADR),y
|
||||
iny
|
||||
sta PPU_DATA
|
||||
jmp @updName
|
||||
|
||||
@updNotSeq:
|
||||
|
||||
tax
|
||||
lda <PPU_CTRL_VAR
|
||||
cpx #$80 ;is it a horizontal or vertical sequence?
|
||||
bcc @updHorzSeq
|
||||
cpx #$ff ;is it end of the update?
|
||||
beq @updDone
|
||||
|
||||
@updVertSeq:
|
||||
|
||||
ora #$04
|
||||
bne @updNameSeq ;bra
|
||||
|
||||
@updHorzSeq:
|
||||
|
||||
and #$fb
|
||||
|
||||
@updNameSeq:
|
||||
|
||||
sta PPU_CTRL
|
||||
|
||||
txa
|
||||
and #$3f
|
||||
sta PPU_ADDR
|
||||
lda (NAME_UPD_ADR),y
|
||||
iny
|
||||
sta PPU_ADDR
|
||||
lda (NAME_UPD_ADR),y
|
||||
iny
|
||||
tax
|
||||
|
||||
@updNameLoop:
|
||||
|
||||
lda (NAME_UPD_ADR),y
|
||||
iny
|
||||
sta PPU_DATA
|
||||
dex
|
||||
bne @updNameLoop
|
||||
|
||||
lda <PPU_CTRL_VAR
|
||||
sta PPU_CTRL
|
||||
|
||||
jmp @updName
|
||||
|
||||
@updDone:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ vram_adr(unsigned int adr);
|
||||
|
||||
_vram_adr:
|
||||
|
||||
stx PPU_ADDR
|
||||
sta PPU_ADDR
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ vram_put(unsigned char n);
|
||||
|
||||
_vram_put:
|
||||
|
||||
sta PPU_DATA
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ vram_fill(unsigned char n,unsigned int len);
|
||||
|
||||
_vram_fill:
|
||||
|
||||
sta <LEN
|
||||
stx <LEN+1
|
||||
jsr popa
|
||||
ldx <LEN+1
|
||||
beq @2
|
||||
ldx #0
|
||||
|
||||
@1:
|
||||
|
||||
sta PPU_DATA
|
||||
dex
|
||||
bne @1
|
||||
dec <LEN+1
|
||||
bne @1
|
||||
|
||||
@2:
|
||||
|
||||
ldx <LEN
|
||||
beq @4
|
||||
|
||||
@3:
|
||||
|
||||
sta PPU_DATA
|
||||
dex
|
||||
bne @3
|
||||
|
||||
@4:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;void __fastcall__ vram_inc(unsigned char n);
|
||||
|
||||
_vram_inc:
|
||||
|
||||
ora #0
|
||||
beq @1
|
||||
lda #$04
|
||||
|
||||
@1:
|
||||
|
||||
sta <TEMP
|
||||
lda <PPU_CTRL_VAR
|
||||
and #$fb
|
||||
ora <TEMP
|
||||
sta <PPU_CTRL_VAR
|
||||
sta PPU_CTRL
|
||||
|
||||
rts
|
||||
|
||||
|
||||
;unsigned char __fastcall__ nesclock(void);
|
||||
|
||||
_nesclock:
|
||||
lda <FRAME_CNT1
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
;void __fastcall__ delay(unsigned char frames);
|
||||
|
||||
_delay:
|
||||
|
||||
tax
|
||||
|
||||
@1:
|
||||
|
||||
jsr _ppu_wait_nmi
|
||||
dex
|
||||
bne @1
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
palBrightTableL:
|
||||
|
||||
.byte <palBrightTable0,<palBrightTable1,<palBrightTable2
|
||||
.byte <palBrightTable3,<palBrightTable4,<palBrightTable5
|
||||
.byte <palBrightTable6,<palBrightTable7,<palBrightTable8
|
||||
|
||||
palBrightTableH:
|
||||
|
||||
.byte >palBrightTable0,>palBrightTable1,>palBrightTable2
|
||||
.byte >palBrightTable3,>palBrightTable4,>palBrightTable5
|
||||
.byte >palBrightTable6,>palBrightTable7,>palBrightTable8
|
||||
|
||||
palBrightTable0:
|
||||
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f ;black
|
||||
palBrightTable1:
|
||||
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
|
||||
palBrightTable2:
|
||||
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
|
||||
palBrightTable3:
|
||||
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
|
||||
palBrightTable4:
|
||||
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0f,$0f,$0f ;normal colors
|
||||
palBrightTable5:
|
||||
.byte $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1a,$1b,$1c,$00,$00,$00
|
||||
palBrightTable6:
|
||||
.byte $10,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$10,$10,$10 ;$10 because $20 is the same as $30
|
||||
palBrightTable7:
|
||||
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$20,$20,$20
|
||||
palBrightTable8:
|
||||
.byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30 ;white
|
||||
.byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30
|
||||
.byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30
|
||||
.byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30
|
||||
|
20
LibMultiSpacc/neslib/oam_clear_fast.s
Normal file
20
LibMultiSpacc/neslib/oam_clear_fast.s
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
.include "nes.inc"
|
||||
.segment "CODE"
|
||||
|
||||
;void __fastcall__ oam_clear_fast(void);
|
||||
|
||||
.export _oam_clear_fast ;make this function accessible to C code
|
||||
|
||||
_oam_clear_fast:
|
||||
|
||||
lda #240
|
||||
|
||||
.repeat 64,I
|
||||
sta OAM_BUF+I*4
|
||||
.endrepeat
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
64
LibMultiSpacc/neslib/oam_meta_spr.s
Normal file
64
LibMultiSpacc/neslib/oam_meta_spr.s
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
.importzp TEMP, _oam_off, sp
|
||||
.import popa, popax
|
||||
.include "nes.inc"
|
||||
.include "zpvars.inc"
|
||||
|
||||
;unsigned char __fastcall__ oam_meta_spr(unsigned char x,unsigned char y,unsigned char sprid,const unsigned char *data);
|
||||
.export _oam_meta_spr
|
||||
|
||||
_oam_meta_spr:
|
||||
|
||||
sta <PTR
|
||||
stx <PTR+1
|
||||
|
||||
ldy #2 ;three popa calls replacement, performed in reversed order
|
||||
lda (sp),y
|
||||
dey
|
||||
sta <SCRX
|
||||
lda (sp),y
|
||||
dey
|
||||
sta <SCRY
|
||||
lda (sp),y
|
||||
tax
|
||||
|
||||
@1:
|
||||
|
||||
lda (PTR),y ;x offset
|
||||
cmp #$80
|
||||
beq @2
|
||||
iny
|
||||
clc
|
||||
adc <SCRX
|
||||
sta OAM_BUF+3,x
|
||||
lda (PTR),y ;y offset
|
||||
iny
|
||||
clc
|
||||
adc <SCRY
|
||||
sta OAM_BUF+0,x
|
||||
lda (PTR),y ;tile
|
||||
iny
|
||||
sta OAM_BUF+1,x
|
||||
lda (PTR),y ;attribute
|
||||
iny
|
||||
sta OAM_BUF+2,x
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
jmp @1
|
||||
|
||||
@2:
|
||||
|
||||
lda <sp
|
||||
adc #2 ;carry is always set here, so it adds 3
|
||||
sta <sp
|
||||
bcc @3
|
||||
inc <sp+1
|
||||
|
||||
@3:
|
||||
|
||||
txa
|
||||
ldx #$00
|
||||
rts
|
||||
|
107
LibMultiSpacc/neslib/oam_meta_spr_clip.s
Normal file
107
LibMultiSpacc/neslib/oam_meta_spr_clip.s
Normal file
@ -0,0 +1,107 @@
|
||||
|
||||
.importzp TEMP, _oam_off
|
||||
.import popa, popax
|
||||
.include "nes.inc"
|
||||
.include "zpvars.inc"
|
||||
|
||||
;void __fastcall__ oam_meta_spr_clip(signed int x,unsigned char y,const unsigned char *metasprite);
|
||||
|
||||
.segment "ZEROPAGE"
|
||||
|
||||
SPR_XOFF: .res 1
|
||||
SPR_YOFF: .res 1
|
||||
|
||||
.segment "CODE"
|
||||
|
||||
.export _oam_meta_spr_clip
|
||||
|
||||
_oam_meta_spr_clip:
|
||||
|
||||
sta <PTR
|
||||
stx <PTR+1
|
||||
|
||||
jsr popa ;y
|
||||
sta <SCRY
|
||||
|
||||
jsr popax ;x
|
||||
sta <SCRX
|
||||
stx <DST ;this is X MSB, repurposing RAM variable name
|
||||
|
||||
ldx _oam_off
|
||||
ldy #0
|
||||
|
||||
@1:
|
||||
|
||||
lda (PTR),y ;x offset
|
||||
cmp #$80
|
||||
beq @2
|
||||
iny
|
||||
|
||||
sta <SPR_XOFF+0
|
||||
clc
|
||||
adc <SCRX
|
||||
sta <SPR_XOFF+1
|
||||
|
||||
lda <SPR_XOFF+0
|
||||
ora #$7f
|
||||
bmi :+
|
||||
lda #0
|
||||
:
|
||||
|
||||
adc <DST
|
||||
bne @skip
|
||||
|
||||
lda <SPR_XOFF+1
|
||||
sta OAM_BUF+3,x
|
||||
lda (PTR),y ;y offset
|
||||
iny
|
||||
clc
|
||||
adc <SCRY
|
||||
sta OAM_BUF+0,x
|
||||
lda (PTR),y ;tile
|
||||
iny
|
||||
sta OAM_BUF+1,x
|
||||
lda (PTR),y ;attribute
|
||||
iny
|
||||
sta OAM_BUF+2,x
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
jmp @1
|
||||
|
||||
@skip:
|
||||
|
||||
iny
|
||||
iny
|
||||
iny
|
||||
jmp @1
|
||||
|
||||
@2:
|
||||
|
||||
stx _oam_off
|
||||
|
||||
rts
|
||||
|
||||
; static unsigned char sx,sy,tile,pal,off;
|
||||
; static signed int sxx;
|
||||
|
||||
; off=0;
|
||||
|
||||
; while(1)
|
||||
; {
|
||||
; sx=metasprite[off++];
|
||||
|
||||
; if(sx==128) return;
|
||||
|
||||
; sxx =x+(signed char)sx;
|
||||
; sy =metasprite[off++]+y;
|
||||
; tile=metasprite[off++];
|
||||
; pal =metasprite[off++];
|
||||
|
||||
; if(!(sxx&0xff00))
|
||||
; {
|
||||
; oam_spr(sxx,sy,tile,pal,oam_off);
|
||||
; oam_off+=4;
|
||||
; }
|
||||
; }
|
71
LibMultiSpacc/neslib/oam_meta_spr_pal.s
Normal file
71
LibMultiSpacc/neslib/oam_meta_spr_pal.s
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
.importzp TEMP, _oam_off, sp
|
||||
.import popa, popax
|
||||
.include "nes.inc"
|
||||
.include "zpvars.inc"
|
||||
|
||||
;void __fastcall__ oam_meta_spr_pal(unsigned char x,unsigned char y,unsigned char pal,const unsigned char *metasprite);
|
||||
|
||||
.export _oam_meta_spr_pal
|
||||
|
||||
_oam_meta_spr_pal:
|
||||
|
||||
sta <PTR
|
||||
stx <PTR+1
|
||||
|
||||
ldy #2 ;three popa calls replacement, performed in reversed order
|
||||
lda (sp),y
|
||||
dey
|
||||
sta <SCRX
|
||||
lda (sp),y
|
||||
dey
|
||||
sta <SCRY
|
||||
lda (sp),y
|
||||
sta <DST ;this is palette, just repurposing RAM variable name
|
||||
|
||||
ldx _oam_off
|
||||
|
||||
@1:
|
||||
|
||||
lda (PTR),y ;x offset
|
||||
cmp #$80
|
||||
beq @2
|
||||
iny
|
||||
clc
|
||||
adc <SCRX
|
||||
sta OAM_BUF+3,x
|
||||
lda (PTR),y ;y offset
|
||||
iny
|
||||
clc
|
||||
adc <SCRY
|
||||
sta OAM_BUF+0,x
|
||||
lda (PTR),y ;tile
|
||||
iny
|
||||
sta OAM_BUF+1,x
|
||||
lda (PTR),y ;attribute
|
||||
iny
|
||||
and #$fc ;remove palette bits
|
||||
ora <DST ;add new palette bits
|
||||
sta OAM_BUF+2,x
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
jmp @1
|
||||
|
||||
@2:
|
||||
|
||||
stx _oam_off
|
||||
|
||||
lda <sp
|
||||
adc #2 ;carry is always set here, so it adds 3
|
||||
sta <sp
|
||||
bcc @3
|
||||
inc <sp+1
|
||||
|
||||
@3:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
42
LibMultiSpacc/neslib/oam_spr.s
Normal file
42
LibMultiSpacc/neslib/oam_spr.s
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
.importzp TEMP, _oam_off, sp
|
||||
.import popa, popax
|
||||
.include "nes.inc"
|
||||
.include "zpvars.inc"
|
||||
|
||||
;unsigned char __fastcall__ oam_spr(unsigned char x,unsigned char y,unsigned char chrnum,unsigned char attr,unsigned char sprid);
|
||||
|
||||
.export _oam_spr
|
||||
|
||||
_oam_spr:
|
||||
|
||||
tax
|
||||
|
||||
ldy #0 ;four popa calls replacement
|
||||
lda (sp),y
|
||||
iny
|
||||
sta OAM_BUF+2,x
|
||||
lda (sp),y
|
||||
iny
|
||||
sta OAM_BUF+1,x
|
||||
lda (sp),y
|
||||
iny
|
||||
sta OAM_BUF+0,x
|
||||
lda (sp),y
|
||||
sta OAM_BUF+3,x
|
||||
|
||||
lda <sp
|
||||
clc
|
||||
adc #4
|
||||
sta <sp
|
||||
bcc @1
|
||||
inc <sp+1
|
||||
|
||||
@1:
|
||||
|
||||
txa
|
||||
clc
|
||||
adc #4
|
||||
ldx #$00
|
||||
rts
|
||||
|
89
LibMultiSpacc/neslib/pad.s
Normal file
89
LibMultiSpacc/neslib/pad.s
Normal file
@ -0,0 +1,89 @@
|
||||
|
||||
.segment "ZEROPAGE"
|
||||
|
||||
PAD_STATE: .res 2 ;one byte per controller
|
||||
PAD_STATEP: .res 2
|
||||
PAD_STATET: .res 2
|
||||
|
||||
.importzp TEMP
|
||||
PAD_BUF =TEMP+1
|
||||
|
||||
.include "nes.inc"
|
||||
.segment "CODE"
|
||||
.export _pad_poll, _pad_trigger, _pad_state
|
||||
|
||||
;unsigned char __fastcall__ pad_poll(unsigned char pad);
|
||||
|
||||
_pad_poll:
|
||||
|
||||
tay
|
||||
ldx #0
|
||||
|
||||
@padPollPort:
|
||||
|
||||
lda #1
|
||||
sta CTRL_PORT1
|
||||
lda #0
|
||||
sta CTRL_PORT1
|
||||
lda #8
|
||||
sta <TEMP
|
||||
|
||||
@padPollLoop:
|
||||
|
||||
lda CTRL_PORT1,y
|
||||
lsr a
|
||||
ror <PAD_BUF,x
|
||||
dec <TEMP
|
||||
bne @padPollLoop
|
||||
|
||||
inx
|
||||
cpx #3
|
||||
bne @padPollPort
|
||||
|
||||
lda <PAD_BUF
|
||||
cmp <PAD_BUF+1
|
||||
beq @done
|
||||
cmp <PAD_BUF+2
|
||||
beq @done
|
||||
lda <PAD_BUF+1
|
||||
|
||||
@done:
|
||||
|
||||
sta <PAD_STATE,y
|
||||
tax
|
||||
eor <PAD_STATEP,y
|
||||
and <PAD_STATE ,y
|
||||
sta <PAD_STATET,y
|
||||
txa
|
||||
sta <PAD_STATEP,y
|
||||
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;unsigned char __fastcall__ pad_trigger(unsigned char pad);
|
||||
|
||||
_pad_trigger:
|
||||
|
||||
pha
|
||||
jsr _pad_poll
|
||||
pla
|
||||
tax
|
||||
lda <PAD_STATET,x
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;unsigned char __fastcall__ pad_state(unsigned char pad);
|
||||
|
||||
_pad_state:
|
||||
|
||||
tax
|
||||
lda <PAD_STATE,x
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
|
||||
|
71
LibMultiSpacc/neslib/rand.s
Normal file
71
LibMultiSpacc/neslib/rand.s
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
.segment "ZEROPAGE"
|
||||
|
||||
RAND_SEED: .res 2
|
||||
|
||||
.segment "CODE"
|
||||
.export _rand8,_rand16,_set_rand
|
||||
.exportzp RAND_SEED
|
||||
|
||||
;unsigned char __fastcall__ rand8(void);
|
||||
;Galois random generator, found somewhere
|
||||
;out: A random number 0..255
|
||||
|
||||
rand1:
|
||||
|
||||
lda <RAND_SEED
|
||||
beq @z1
|
||||
asl a
|
||||
bcc @1
|
||||
@z1: eor #$cf
|
||||
|
||||
@1:
|
||||
|
||||
sta <RAND_SEED
|
||||
rts
|
||||
|
||||
rand2:
|
||||
|
||||
lda <RAND_SEED+1
|
||||
beq @z2
|
||||
asl a
|
||||
bcc @1
|
||||
@z2: eor #$d7
|
||||
|
||||
@1:
|
||||
|
||||
sta <RAND_SEED+1
|
||||
rts
|
||||
|
||||
_rand8:
|
||||
|
||||
jsr rand1
|
||||
jsr rand2
|
||||
adc <RAND_SEED
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
|
||||
|
||||
;unsigned int __fastcall__ rand16(void);
|
||||
|
||||
_rand16:
|
||||
|
||||
jsr rand1
|
||||
tax
|
||||
jsr rand2
|
||||
|
||||
rts
|
||||
|
||||
|
||||
;void __fastcall__ set_rand(unsigned char seed);
|
||||
|
||||
_set_rand:
|
||||
ora #1
|
||||
sta <RAND_SEED
|
||||
stx <RAND_SEED+1
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
41
LibMultiSpacc/neslib/split.s
Normal file
41
LibMultiSpacc/neslib/split.s
Normal file
@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
.importzp TEMP, PPU_CTRL_VAR, PPU_CTRL_VAR1, SCROLL_X1
|
||||
.import popax
|
||||
.include "nes.inc"
|
||||
.include "zpvars.inc"
|
||||
.export _split
|
||||
|
||||
;;void __fastcall__ split(unsigned int x,unsigned int y);
|
||||
|
||||
_split:
|
||||
|
||||
jsr popax
|
||||
sta <SCROLL_X1
|
||||
txa
|
||||
and #$01
|
||||
sta <TEMP
|
||||
lda <PPU_CTRL_VAR
|
||||
and #$fc
|
||||
ora <TEMP
|
||||
sta <PPU_CTRL_VAR1
|
||||
|
||||
@3:
|
||||
|
||||
bit PPU_STATUS
|
||||
bvs @3
|
||||
|
||||
@4:
|
||||
|
||||
bit PPU_STATUS
|
||||
bvc @4
|
||||
|
||||
lda <SCROLL_X1
|
||||
sta PPU_SCROLL
|
||||
lda #0
|
||||
sta PPU_SCROLL
|
||||
lda <PPU_CTRL_VAR1
|
||||
sta PPU_CTRL
|
||||
|
||||
rts
|
||||
|
81
LibMultiSpacc/neslib/splitxy.s
Normal file
81
LibMultiSpacc/neslib/splitxy.s
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
.importzp TEMP, PPU_CTRL_VAR, PPU_CTRL_VAR1, SCROLL_X1, SCROLL_Y1
|
||||
.import popax
|
||||
.include "nes.inc"
|
||||
.include "zpvars.inc"
|
||||
.export _splitxy
|
||||
|
||||
;;void __fastcall__ splitxy(unsigned int x,unsigned int y);
|
||||
|
||||
WRITE1=TEMP+1
|
||||
WRITE2=TEMP+2
|
||||
|
||||
_splitxy:
|
||||
|
||||
; Extract SCROLL_Y1, SCROLL_X1, WRITE1 from parameters.
|
||||
|
||||
sta <TEMP
|
||||
|
||||
txa
|
||||
bne @1
|
||||
lda <TEMP
|
||||
cmp #240
|
||||
bcs @1
|
||||
sta <SCROLL_Y1
|
||||
lda #0
|
||||
sta <TEMP
|
||||
beq @2 ;bra
|
||||
|
||||
@1:
|
||||
sec
|
||||
lda <TEMP
|
||||
sbc #240
|
||||
sta <SCROLL_Y1
|
||||
lda #8 ;; Bit 3
|
||||
sta <TEMP
|
||||
@2:
|
||||
|
||||
jsr popax
|
||||
sta <SCROLL_X1
|
||||
txa
|
||||
and #$01
|
||||
asl a
|
||||
asl a ;; Bit 2
|
||||
ora <TEMP ;; From Y
|
||||
sta <WRITE1 ;; Store!
|
||||
|
||||
; Calculate WRITE2 = ((Y & $F8) << 2) | (X >> 3)
|
||||
|
||||
lda <SCROLL_Y1
|
||||
and #$F8
|
||||
asl a
|
||||
asl a
|
||||
sta <TEMP ;; TEMP = (Y & $F8) << 2
|
||||
lda <SCROLL_X1
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a ;; A = (X >> 3)
|
||||
ora <TEMP ;; A = (X >> 3) | ((Y & $F8) << 2)
|
||||
sta <WRITE2 ;; Store!
|
||||
|
||||
; Wait for sprite 0 hit
|
||||
|
||||
@3:
|
||||
bit PPU_STATUS
|
||||
bvs @3
|
||||
@4:
|
||||
bit PPU_STATUS
|
||||
bvc @4
|
||||
|
||||
; Set scroll value
|
||||
lda PPU_STATUS
|
||||
lda <WRITE1
|
||||
sta PPU_ADDR
|
||||
lda <SCROLL_Y1
|
||||
sta PPU_SCROLL
|
||||
lda <SCROLL_X1
|
||||
ldx <WRITE2
|
||||
sta PPU_SCROLL
|
||||
stx PPU_ADDR
|
||||
|
||||
rts
|
47
LibMultiSpacc/neslib/vram_read.s
Normal file
47
LibMultiSpacc/neslib/vram_read.s
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
.importzp TEMP
|
||||
.import popa, popax
|
||||
.include "nes.inc"
|
||||
.include "zpvars.inc"
|
||||
.export _vram_read
|
||||
|
||||
;void __fastcall__ vram_read(unsigned char *dst,unsigned int size);
|
||||
|
||||
_vram_read:
|
||||
|
||||
sta <TEMP
|
||||
stx <TEMP+1
|
||||
|
||||
jsr popax
|
||||
sta <TEMP+2
|
||||
stx <TEMP+3
|
||||
|
||||
lda PPU_DATA
|
||||
|
||||
ldy #0
|
||||
|
||||
@1:
|
||||
|
||||
lda PPU_DATA
|
||||
sta (TEMP+2),y
|
||||
inc <TEMP+2
|
||||
bne @2
|
||||
inc <TEMP+3
|
||||
|
||||
@2:
|
||||
|
||||
lda <TEMP
|
||||
bne @3
|
||||
dec <TEMP+1
|
||||
|
||||
@3:
|
||||
|
||||
dec <TEMP
|
||||
lda <TEMP
|
||||
ora <TEMP+1
|
||||
bne @1
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
60
LibMultiSpacc/neslib/vram_unrle.s
Normal file
60
LibMultiSpacc/neslib/vram_unrle.s
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
.importzp TEMP
|
||||
.include "nes.inc"
|
||||
.include "zpvars.inc"
|
||||
.export _vram_unrle
|
||||
|
||||
;void __fastcall__ vram_unrle(const unsigned char *data);
|
||||
|
||||
_vram_unrle:
|
||||
|
||||
tay
|
||||
stx <RLE_HIGH
|
||||
lda #0
|
||||
sta <RLE_LOW
|
||||
|
||||
lda (RLE_LOW),y
|
||||
sta <RLE_TAG
|
||||
iny
|
||||
bne @1
|
||||
inc <RLE_HIGH
|
||||
|
||||
@1:
|
||||
|
||||
lda (RLE_LOW),y
|
||||
iny
|
||||
bne @11
|
||||
inc <RLE_HIGH
|
||||
|
||||
@11:
|
||||
|
||||
cmp <RLE_TAG
|
||||
beq @2
|
||||
sta PPU_DATA
|
||||
sta <RLE_BYTE
|
||||
bne @1
|
||||
|
||||
@2:
|
||||
|
||||
lda (RLE_LOW),y
|
||||
beq @4
|
||||
iny
|
||||
bne @21
|
||||
inc <RLE_HIGH
|
||||
|
||||
@21:
|
||||
|
||||
tax
|
||||
lda <RLE_BYTE
|
||||
|
||||
@3:
|
||||
|
||||
sta PPU_DATA
|
||||
dex
|
||||
bne @3
|
||||
beq @1
|
||||
|
||||
@4:
|
||||
|
||||
rts
|
||||
|
14
LibMultiSpacc/neslib/zpvars.inc
Normal file
14
LibMultiSpacc/neslib/zpvars.inc
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
PTR =TEMP ;word
|
||||
LEN =TEMP+2 ;word
|
||||
NEXTSPR =TEMP+4
|
||||
SCRX =TEMP+5
|
||||
SCRY =TEMP+6
|
||||
SRC =TEMP+7 ;word
|
||||
DST =TEMP+9 ;word
|
||||
|
||||
RLE_LOW =TEMP
|
||||
RLE_HIGH =TEMP+1
|
||||
RLE_TAG =TEMP+2
|
||||
RLE_BYTE =TEMP+3
|
||||
|
1
Transpiler/README.md
Normal file
1
Transpiler/README.md
Normal file
@ -0,0 +1 @@
|
||||
This component of the MultiSpaccSDK is abandoned until further notice.
|
Loading…
x
Reference in New Issue
Block a user