mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-29 14:51:17 +00:00
266 lines
7.5 KiB
C
266 lines
7.5 KiB
C
|
|
#ifndef _VCSLIB_H
|
|
#define _VCSLIB_H
|
|
|
|
#include <atari2600.h>
|
|
#include <stdint.h>
|
|
|
|
// Define data types for different data sizes and signedness
|
|
|
|
typedef unsigned char byte; // 8-bit unsigned data type
|
|
typedef signed char sbyte; // 8-bit signed data type
|
|
typedef unsigned short word; // 16-bit unsigned data type
|
|
typedef signed short sword; // 16-bit signed data type
|
|
|
|
// Bank switching functions that will be called directly when needed
|
|
// These are for changing which section of ROM or RAM the Atari 2600 accesses
|
|
|
|
// Select a ROM bank by index
|
|
extern void fastcall bankselect(byte bankindex);
|
|
|
|
// Select a RAM bank by index
|
|
extern void fastcall ramselect(byte ramindex);
|
|
|
|
// Set address in extended RAM
|
|
extern void fastcall xramset(void* address);
|
|
|
|
// Write a byte to extended RAM at set address
|
|
extern void fastcall xramwrite(byte value);
|
|
|
|
// Read a byte from extended RAM at set address
|
|
extern byte fastcall xramread(void);
|
|
|
|
// Copies initialized data from ROM to RAM at startup, if used
|
|
extern void copyxdata(void);
|
|
|
|
// Atari 2600 kernel helpers, called in a sequence every frame
|
|
|
|
extern void kernel_1(void); // before preframe
|
|
extern void kernel_2(void); // before kernel
|
|
extern void kernel_3(void); // after kernel
|
|
extern void kernel_4(void); // after postframe
|
|
|
|
// Function to set horizontal position of a game object.
|
|
// The position and object index are packed into a single int.
|
|
// Hi byte = object index
|
|
// Lo byte = X coordinate
|
|
|
|
extern void fastcall set_horiz_pos(int hi_obj__lo_xpos);
|
|
|
|
// Waits for next scanline start
|
|
#define do_wsync() asm("sta $42 ; WSYNC");
|
|
|
|
// Applies horizontal motion to sprite(s) after set_horiz_pos()
|
|
#define apply_hmove() \
|
|
asm("sta $42 ; WSYNC"); \
|
|
asm("sta $6a ; HMOVE");
|
|
|
|
|
|
/**** SCOREBOARD ROUTINES ****/
|
|
|
|
// Add 4-digit BCD to 6-digit BCD score
|
|
extern void fastcall score6_add(int delta_bcd);
|
|
|
|
#pragma wrapped-call (push, bankselect, bank)
|
|
|
|
// Setup TIA for Playfield score display
|
|
extern void scorepf_build(void);
|
|
|
|
// Kernel for Playfield score display
|
|
extern void scorepf_kernel(void);
|
|
|
|
#pragma wrapped-call (pop)
|
|
|
|
|
|
/**** SOUND AND MUSIC ROUTINES ****/
|
|
|
|
#pragma wrapped-call (push, bankselect, bank)
|
|
|
|
// Update sound playback (once per frame)
|
|
extern void sound_update();
|
|
|
|
// Play a specific sound
|
|
extern void sound_play(byte sndindex);
|
|
|
|
// Update music playback
|
|
extern void music_update();
|
|
|
|
#pragma wrapped-call (pop)
|
|
|
|
extern const byte* music_ptr; // Pointer to current music data
|
|
#pragma zpsym("music_ptr");
|
|
|
|
// Macro to set music data pointer and begin playback
|
|
#define music_play(ptr) music_ptr = (ptr);
|
|
|
|
extern byte sndchan_timer[2]; // sound channel timers, 0 = free channel
|
|
#pragma zpsym("sndchan_timer");
|
|
|
|
extern byte sndchan_sfx[2]; // sound channel sound index
|
|
#pragma zpsym("sndchan_sfx");
|
|
|
|
|
|
/**** 48-PIXEL BITMAP ROUTINES ****/
|
|
|
|
// Setup TIA for 48-pixel wide bitmap mode
|
|
extern void fastcall bitmap48_setup();
|
|
|
|
#pragma wrapped-call (push, ramselect, 0)
|
|
|
|
// Draws a 48-pixel wide bitmap
|
|
extern void fastcall bitmap48_kernel(unsigned char nlines);
|
|
|
|
// Sets height for bitmap48_setaddress() function
|
|
extern void fastcall bitmap48_setheight(byte height);
|
|
|
|
// Sets address of 48-pixel bitmap data
|
|
// Bitmap should be 6 bytes wide
|
|
extern void fastcall bitmap48_setaddress(byte* bitmap);
|
|
|
|
// Builds a 6-digit score display in XRAM
|
|
extern void fastcall score6_build();
|
|
|
|
#pragma wrapped-call (pop)
|
|
|
|
#pragma wrapped-call (push, bankselect, bank)
|
|
|
|
// Create 48-pixel font from string (requires tinyfont48.c)
|
|
extern void tinyfont48_build(byte* dest, const char str[12]);
|
|
|
|
#pragma wrapped-call (pop)
|
|
|
|
/////
|
|
|
|
#define P0 0
|
|
#define P1 1
|
|
#define M0 2
|
|
#define M1 3
|
|
#define BALL 4
|
|
|
|
#define OBJ_PLAYER_0 0x000
|
|
#define OBJ_PLAYER_1 0x100
|
|
#define OBJ_MISSILE_0 0x200
|
|
#define OBJ_MISSILE_1 0x300
|
|
#define OBJ_BALL 0x400
|
|
|
|
#define SW_RESET() ((RIOT.swchb & RESET_MASK) == 0)
|
|
#define SW_SELECT() ((RIOT.swchb & SELECT_MASK) == 0)
|
|
#define SW_COLOR() ((RIOT.swchb & BW_MASK) != 0)
|
|
#define SW_P0_PRO() ((RIOT.swchb & P0_DIFF_MASK) != 0)
|
|
#define SW_P1_PRO() ((RIOT.swchb & P1_DIFF_MASK) != 0)
|
|
|
|
#define COLOR_CONV(color) (SW_COLOR() ? color : color & 0x0f)
|
|
|
|
#define _CYCLES(lines) (((lines) * 76) - 13)
|
|
#define _TIM64(cycles) (((cycles) >> 6) - (((cycles) & 63) < 12))
|
|
#define _T1024(cycles) ((cycles) >> 10)
|
|
|
|
#ifdef PAL
|
|
#define VBLANK_TIM64 _TIM64(_CYCLES(45))
|
|
#define KERNAL_T1024 _T1024(_CYCLES(250))
|
|
#define OVERSCAN_TIM64 _TIM64(_CYCLES(36))
|
|
#else
|
|
#define VBLANK_TIM64 _TIM64(_CYCLES(37))
|
|
#define KERNAL_TIM64 _TIM64(_CYCLES(194))
|
|
#define OVERSCAN_TIM64 _TIM64(_CYCLES(32))
|
|
#endif
|
|
|
|
#define JOY_UP(plyr) (!(RIOT.swcha & ((plyr) ? 0x1 : ~MOVE_UP)))
|
|
#define JOY_DOWN(plyr) (!(RIOT.swcha & ((plyr) ? 0x2 : ~MOVE_DOWN)))
|
|
#define JOY_LEFT(plyr) (!(RIOT.swcha & ((plyr) ? 0x4 : ~MOVE_LEFT)))
|
|
#define JOY_RIGHT(plyr) (!(RIOT.swcha & ((plyr) ? 0x8 : ~MOVE_RIGHT)))
|
|
#define JOY_FIRE(plyr) !(((plyr) ? TIA.inpt5 : TIA.inpt4) & 0x80)
|
|
|
|
// TIA - CONSTANTS
|
|
|
|
#define HMOVE_L7 (0x70)
|
|
#define HMOVE_L6 (0x60)
|
|
#define HMOVE_L5 (0x50)
|
|
#define HMOVE_L4 (0x40)
|
|
#define HMOVE_L3 (0x30)
|
|
#define HMOVE_L2 (0x20)
|
|
#define HMOVE_L1 (0x10)
|
|
#define HMOVE_0 (0x00)
|
|
#define HMOVE_R1 (0xF0)
|
|
#define HMOVE_R2 (0xE0)
|
|
#define HMOVE_R3 (0xD0)
|
|
#define HMOVE_R4 (0xC0)
|
|
#define HMOVE_R5 (0xB0)
|
|
#define HMOVE_R6 (0xA0)
|
|
#define HMOVE_R7 (0x90)
|
|
#define HMOVE_R8 (0x80)
|
|
|
|
// Values for ENAMx and ENABL
|
|
#define DISABLE_BM (0b00)
|
|
#define ENABLE_BM (0b10)
|
|
|
|
// Values for RESMPx
|
|
#define LOCK_MISSILE (0b10)
|
|
#define UNLOCK_MISSILE (0b00)
|
|
|
|
// Values for REFPx
|
|
#define NO_REFLECT (0b0000)
|
|
#define REFLECT (0b1000)
|
|
|
|
// Values for NUSIZx
|
|
#define ONE_COPY (0b000)
|
|
#define TWO_COPIES (0b001)
|
|
#define TWO_MED_COPIES (0b010)
|
|
#define THREE_COPIES (0b011)
|
|
#define TWO_WIDE_COPIES (0b100)
|
|
#define DOUBLE_SIZE (0b101)
|
|
#define THREE_MED_COPIES (0b110)
|
|
#define QUAD_SIZE (0b111)
|
|
#define MSBL_SIZE1 (0b000000)
|
|
#define MSBL_SIZE2 (0b010000)
|
|
#define MSBL_SIZE4 (0b100000)
|
|
#define MSBL_SIZE8 (0b110000)
|
|
|
|
// Values for CTRLPF
|
|
#define PF_PRIORITY (0b100)
|
|
#define PF_SCORE (0b10)
|
|
#define PF_REFLECT (0b01)
|
|
#define PF_NO_REFLECT (0b00)
|
|
|
|
// Values for SWCHB
|
|
#define P1_DIFF_MASK (0b10000000)
|
|
#define P0_DIFF_MASK (0b01000000)
|
|
#define BW_MASK (0b00001000)
|
|
#define SELECT_MASK (0b00000010)
|
|
#define RESET_MASK (0b00000001)
|
|
|
|
#define VERTICAL_DELAY (1)
|
|
|
|
// SWCHA joystick bits
|
|
#define MOVE_RIGHT (0b01111111)
|
|
#define MOVE_LEFT (0b10111111)
|
|
#define MOVE_DOWN (0b11011111)
|
|
#define MOVE_UP (0b11101111)
|
|
#define P0_JOYSTICK_MASK (0b11110000)
|
|
#define P1_JOYSTICK_MASK (0b00001111)
|
|
#define P0_NO_MOVE (P0_JOYSTICK_MASK)
|
|
#define P1_NO_MOVE (P1_JOYSTICK_MASK)
|
|
#define NO_MOVE (P0_NO_MOVE | P1_NO_MOVE)
|
|
#define P0_HORIZ_MOVE (MOVE_RIGHT & MOVE_LEFT & P0_NO_MOVE)
|
|
#define P0_VERT_MOVE (MOVE_UP & MOVE_DOWN & P0_NO_MOVE)
|
|
#define P1_HORIZ_MOVE (((MOVE_RIGHT & MOVE_LEFT) >> 4) & P1_NO_MOVE)
|
|
#define P1_VERT_MOVE (((MOVE_UP & MOVE_DOWN) >> 4) & P1_NO_MOVE)
|
|
|
|
// SWCHA paddle bits
|
|
#define P0_TRIGGER_PRESSED (0b01111111)
|
|
#define P1_TRIGGER_PRESSED (0b10111111)
|
|
#define P2_TRIGGER_PRESSED (0b11110111)
|
|
#define P3_TRIGGER_PRESSED (0b11111011)
|
|
|
|
// Values for VBLANK
|
|
#define DUMP_PORTS (0b10000000)
|
|
#define ENABLE_LATCHES (0b01000000)
|
|
#define DISABLE_TIA (0b00000010)
|
|
#define ENABLE_TIA (0b00000000)
|
|
|
|
// Values for VSYNC
|
|
#define START_VERT_SYNC (0b10)
|
|
#define STOP_VERT_SYNC (0b00)
|
|
|
|
#endif
|