Skip to content

Commit

Permalink
Finished documenting everything and preparing to open it up
Browse files Browse the repository at this point in the history
  • Loading branch information
deathy committed Nov 18, 2023
1 parent 60dba29 commit 8e18d5e
Show file tree
Hide file tree
Showing 13 changed files with 450 additions and 5 deletions.
71 changes: 70 additions & 1 deletion src/chips.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
/// \file chips.h
///
/// \brief This file defines the interface to IO registers.
///
/// This header file defines the structures that are used to interface with the
/// various chips and their IO registers. Wherever possible, the naming
/// convention used is the same as it is in the Big Book, though there are a
/// few places where I had to take some liberties.
///
/// \copyright 2023 by BAS and deathy (AKA Clifford A. Anderson).
/// All rights reserved.
#ifndef __CHIPS_H
#define __CHIPS_H

#include <stdint.h>

// This block just creates the types for the structs
typedef struct _CPU _CPU_t;
typedef struct _VIC2 _VIC2_t;
typedef struct _VIC3 _VIC3_t;
Expand All @@ -19,11 +31,18 @@ typedef struct _CIA1 _CIA1_t;
typedef struct _CIA2 _CIA2_t;
typedef struct _IRQ_VECTORS _IRQ_VECTORS_t;

/// \brief This is the interface to the CPU registers.
///
/// This is the interface to the CPU registers. It starts at $00.
struct _CPU {
uint8_t PORTDDR;
uint8_t PORT;
};

/// \brief This is the interface to the VIC2.
///
/// This is the interface to the VIC2. It contains all the registers that
/// existed on the VIC2. It starts at $d000.
struct _VIC2 {
uint8_t S0X;
uint8_t S0Y;
Expand Down Expand Up @@ -101,6 +120,11 @@ struct _VIC2 {
uint8_t C128_FAST;
};

/// \brief This is the interface to the VIC3 extensions.
///
/// This is the interface to the VIC3's extensions. It contains all the
/// registers that were added with the VIC3, but does not point to any of the
/// VIC2's registers. It starts at $d02f.
struct _VIC3 {
uint8_t KEY;
union {
Expand Down Expand Up @@ -191,6 +215,10 @@ struct _VIC3 {

};

/// \brief This is the interface to the VIC4 extensions.
///
/// This is the interface to the VIC4's extensions. As with the VIC3, it only
/// contains those registers that it adds. It starts at $d048.
struct _VIC4 {
uint8_t TBDRPOSLSB;
union {
Expand Down Expand Up @@ -314,6 +342,9 @@ struct _VIC4 {
uint8_t PALBLUE [0x100];
};

/// \brief This is the interface to the Floppy Disk Controller registers
///
/// This is the interface to the Floppy Disk Controller. It starts at $d080.
struct _FDC {
union {
uint8_t DS : 3;
Expand Down Expand Up @@ -362,6 +393,7 @@ struct _FDC {
uint8_t PCODE;
};

/// \brief This is the interface to each individual channel on a SID
struct _SID_VOICE {
uint16_t FREQUENCY;
uint16_t PULSE_WIDTH;
Expand All @@ -371,6 +403,10 @@ struct _SID_VOICE {
uint8_t SUSTAINRELEASE;
};

/// \brief This is the interface to a single SID chip
///
/// This is the interface to a specific SID chip. It will start at one of
/// $d400, $d420, $d440, or $d460.
struct _SID {
_SID_VOICE_t VOICE[3];

Expand All @@ -380,11 +416,18 @@ struct _SID {
uint8_t VOLUME_FTYPE;
};

/// \brief This is the interface to the keyscanning registers.
///
/// This is the interface to the keyscanning registers, used for real time
/// unbuffered keyboard scanning. It starts at $d613.
struct _KEYSCAN {
uint8_t CRTACSCNT;
uint8_t MATRIXPEEK;
};

/// \brief This is the interface to the DMA registers.
///
/// This is the interface to the DMA. It starts at $d700.
struct _DMA {
uint8_t ADDRLSBTRIG;
uint8_t ADDRMSB;
Expand All @@ -397,6 +440,12 @@ struct _DMA {
uint8_t ADDRLSB;
};

/// \brief This is the interface to the math registers.
///
/// This is the interface to the math registers. Do not trust these, I think
/// I have a mistake somewhere in here that makes it not work right, but I
/// didn't need it enough to have solved it so, tread on this interface with
/// care.
struct _MATH {
union {
uint8_t _NA1 : 6;
Expand All @@ -411,6 +460,10 @@ struct _MATH {
uint32_t MULTOUT;
};

/// \brief This is the interface to a single audio DAC channel
///
/// This interface contains all of the registers that pertain to a single audio
/// DMA channel. It will start at one of $d720, $d730, $d740 or $d750.
struct _AUDIO_CHANNEL {
uint8_t CONTROL;
uint16_t BADDR;
Expand All @@ -425,6 +478,9 @@ struct _AUDIO_CHANNEL {
uint8_t TMRADDRMB;
};

/// \brief The main interface to the Audio DMA.
///
/// The main interface to the Audio DMA. It starts at $$d71c.
struct _AUDIO_DMA {
uint8_t CH0RVOL;
uint8_t CH1RVOL;
Expand All @@ -434,8 +490,12 @@ struct _AUDIO_DMA {
_AUDIO_CHANNEL_t CHANNELS[4];
};

// I can't get the CIA chips to work right.
/// \brief This is the interface to the first CIA chip
///
/// This is the interface to the first CIA chip's registers, starting at $dc00.
/// I never did get a CIA timed interrupt working.
struct _CIA1 {
// I can't get the CIA chips to work right.
uint8_t PORTA;
uint8_t PORTB;
uint8_t DDRA;
Expand Down Expand Up @@ -468,6 +528,11 @@ struct _CIA1 {
uint8_t ALRMHOUR;
};

/// \brief This is the interface to the second CIA chip
///
/// This is the interface to the second CIA chip's registers, starting at
/// $dd00. I never did get CIA timing working, so do not take this interface
/// as usable as is.
struct _CIA2 {
uint8_t PORTA;
uint8_t PORTB;
Expand Down Expand Up @@ -501,12 +566,16 @@ struct _CIA2 {
uint8_t ALRMHOUR;
};

/// \brief This is the interface to the IRQ vectors
///
/// This is the interface to the IRQ vectors, starting at $fffa.
struct _IRQ_VECTORS {
uint16_t NMI;
uint16_t COLDSTART;
uint16_t IRQ;
};

// This block points all the structs at an IO register bank.
#define CPU (* (volatile _CPU_t *) 0x00)
#define VIC2 (* (volatile _VIC2_t *) 0xd000)
#define VIC3 (* (volatile _VIC3_t *) 0xd02f)
Expand Down
38 changes: 37 additions & 1 deletion src/constants.h
Original file line number Diff line number Diff line change
@@ -1,35 +1,71 @@
/// \file constants.h
///
/// \brief This file defines the constants of the screen layout
///
/// \copyright 2023 by BAS and deathy (AKA Clifford A. Anderson).
/// All rights reserved.
#ifndef __CONSTANTS_H
#define __CONSTANTS_H


/// \brief This is where the palette is stored initially
///
/// This is where the palette is stored during loading. Once it is written to
/// the VIC3's palette, it is no longer used and gets stomped on by other
/// things.
#define PALETTE_STORE 0x0025000

/// \brief How long each line is in the loader's tile and attribute map
#define LOADER_LINE_LENGTH 80
/// \brief How tall are the loader's maps
#define LOADER_LINE_COUNT 60
/// \brief The byte size of the loader tile and attribute map
#define LOADER_MAP_LENGTH 0x2580


/// \brief A pointer to where the loader's tile map is stored during
/// loading
#define LOADER_TILE_MAP 0x0059200
/// \brief A pointer to where the loader's attribute map is stored during
/// loading
#define LOADER_ATTR_MAP 0x005b800


/// \brief How long each line is in the title screen's tile and attribute map
#define TITLE_LINE_LENGTH 80
/// \brief How tall are the title screen's maps
#define TITLE_LINE_COUNT 60
/// \brief The byte size of the title screen's tile and attribute map
#define TITLE_MAP_LENGTH 0x2580

/// \brief A pointer to where the title screen's tile map is stored
#define TITLE_TILE_MAP 0x0059400
/// \brief A pointer to where the title screen's attribute map is stored
#define TITLE_ATTR_MAP 0x803ba00


/// \brief How long each line is in the in-game tile and attribute map
#define INGAME_LINE_LENGTH 108
/// \brief How tall are the in-game maps
#define INGAME_LINE_COUNT 50
/// \brief The byte sie of the in-game maps
#define INGAME_MAP_LENGTH 0x2a30

/// \brief This is where the cleared in-game tile map is stored.
///
/// This is where the cleared in-game tile map is stored. It is DMAed to the
/// INGAME_TILE_MAP_STORE
#define INGAME_TILE_MAP_BAK 0x001c600
/// \brief This is where the in-game attribute map is stored.
#define INGAME_ATTR_MAP_BAK 0x809b200
/// \brief This is where the screen that is actively being displayed is stored
/// and worked on
#define INGAME_TILE_MAP_STORE 0x0020000

/// \brief The red elements of each ice cream flavor
#define FLAVORS_RED 0x001f100
/// \brief The green elements of each ice cream flavor
#define FLAVORS_GREEN 0x001f280
/// \brief The blue elements of each ice cream flavor
#define FLAVORS_BLUE 0x001f400


Expand Down
43 changes: 42 additions & 1 deletion src/gameoverloop.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/// \file gameoverloop.h
///
/// \brief This file contains the code for the loop at the end of the game
///
/// This file contains the code and variables for the game over loop of the
/// game.
///
/// \copyright 2023 by BAS and deathy (AKA Clifford A. Anderson).
/// All rights reserved.
#include "gameoverloop.h"


Expand All @@ -9,12 +18,22 @@
#include "unicorn.h"


/// \brief This is the loop for the game over state
///
/// This is the loop for the game over state. It plays the game over sound
/// effects, as well as causing the game over text to dance across the top of
/// the screen. It loops until the player has hit fire to dismiss it.
void gameover_loop() {
// the total timer for how long the samples play
unsigned short timer;
// the time into the timer at which the second sample needs to be triggered
unsigned short part_2;

// the x position of the game over text
gameover_x_pos = 640;
// the starting facing of the game over text. 0 = right, 1 = left
gameover_facing = 1;
// The y position of the game over text. 8 pixels wide.
gameover_y_index = 0;

// bank the tile map from $20000-$21fff into $a000-$bfff
Expand Down Expand Up @@ -43,29 +62,39 @@ void gameover_loop() {
// play first game over sfx
play_sample(game_over_sample_start[0], game_over_sample_end[0], 1);

// we first start with the loop for managing the sound effects playback
while (timer > 0) {
// simple raster loop
while (VIC4.FNRASTERLSB != (update_raster & 0xff) ||
VIC4.FNRASTERMSB != ((update_raster & 0x0f00) >> 8));

// draw the game over text
draw_gameover();

// make sure we have used at least one scanline of rastertime
while (VIC4.FNRASTERLSB == (update_raster & 0xff));

// if the timer has hit part 2
if (--timer == part_2) {
// play second game over sfx
play_sample(game_over_sample_start[1], game_over_sample_end[1],
0);
}
};
// now, loop until the player has hit fire in some way
while ((player_input & 0b00010000) == 0) {
while (VIC4.FNRASTERLSB != (update_raster & 0xff) ||
VIC4.FNRASTERMSB != ((update_raster & 0x0f00) >> 8));

// Process the input for this frame
process_input();
// draw the game over text
draw_gameover();

// make sure a scanline has passed
while (VIC4.FNRASTERLSB == (update_raster & 0xff));
};
// this is a hack - basically, wait for the player to RELEASE fire
while (player_input & 0b00010000) {
while (VIC4.FNRASTERLSB != (update_raster & 0xff) ||
VIC4.FNRASTERMSB != ((update_raster & 0x0f00) >> 8));
Expand Down Expand Up @@ -108,19 +137,31 @@ void draw_gameover() {
}
}

// if we're facing left and we're not at the left edge of the screen
if (gameover_facing == 1 && gameover_x_pos > 0) {
// keep moving the game over logo left
--gameover_x_pos;
} else if (gameover_facing == 0 && gameover_x_pos < 496) {
// otherwise, if facing right and we're not at the right edge of the
// screen, keep moving the logo right
++gameover_x_pos;
} else {
// otherwise, swap the facing
gameover_facing = gameover_facing ? 0 : 1;
}

// increment the sinus index used for looking up the vertical movement
if((++gameover_y_index)==25) {
gameover_y_index = 0;
}
}

/// \brief The current horizontal position of the game over logo
unsigned short gameover_x_pos;
/// \brief The current facing of the game over logo
///
/// The current facing of the game over logo. 0 = right, 1 = left
char gameover_facing;
char gameover_y_index;
/// \brief The current index into the sinus used for bouncing the game over
/// logo
char gameover_y_index;
10 changes: 10 additions & 0 deletions src/gameoverloop.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
/// \file gameoverloop.h
///
/// \brief This file is the header file that declares the loop code at the end
/// of the game
///
/// This header file declares the code and variables for the game over loop of
/// the game.
///
/// \copyright 2023 by BAS and deathy (AKA Clifford A. Anderson).
/// All rights reserved.
#ifndef __GAMEOVERLOOP_H
#define __GAMEOVERLOOP_H

Expand Down
Loading

0 comments on commit 8e18d5e

Please sign in to comment.