Skip to content

Commit

Permalink
V5.1: 03-Jan-2022 by wavemotion-dave
Browse files Browse the repository at this point in the history
* MSX1 emulation now supports some of the common Mappers - some of 
  the 128K games work but you'll probably have to turn off Vert Sync
  and turn on Frame Skip to get it to run full speed.
  • Loading branch information
wavemotion-dave committed Jan 3, 2022
1 parent 9cab4d7 commit bffb1a3
Show file tree
Hide file tree
Showing 10 changed files with 509 additions and 92 deletions.
Binary file modified ColecoDS.nds
Binary file not shown.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ include $(DEVKITARM)/ds_rules

export TARGET := ColecoDS
export TOPDIR := $(CURDIR)
export VERSION := 5.0
export VERSION := 5.1

ICON := -b $(CURDIR)/logo.bmp "ColecoDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/ColecoDS"

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ would personally try them:

Versions :
-----------------------
V5.1: 03-Jan-2022 by wavemotion-dave
* MSX1 emulation now supports some of the common Mappers - some of
the 128K games work but you'll probably have to turn off Vert Sync
and turn on Frame Skip to get it to run full speed.

V5.0: 02-Jan-2022 by wavemotion-dave
* MSX1 game support up to 32K Standard Loader (.msx format)
* New 3/4 Frameskip (show 3 of 4 frames) to help DS-LITE
Expand Down
Binary file modified arm9/gfx_data/pdev_bg0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion arm9/source/colecoDS.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <string.h>
#include "cpu/z80/drz80/Z80_interface.h"

#define VERSIONCLDS "5.0"
#define VERSIONCLDS "5.1"

//#define DEBUG_Z80 YES

Expand Down
279 changes: 212 additions & 67 deletions arm9/source/colecomngt.c

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions arm9/source/colecomngt.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@
#define IMAGE_VERIFY_FAIL 0X01
#define IMAGE_VERIFY_PASS 0x02

extern u8 mapperType;
extern u8 mapperMask;

#define KON8 0
#define ASC8 1
#define SCC8 2
#define ASC16 3

#define MAX_MAPPERS 4

extern u8 bROMInSlot[];
extern u8 bRAMInSlot[];
extern u8 PortA8;
extern u8 *Slot1ROMPtr[];

extern u8 VR; // Sound and VDP register storage

extern u8 JoyMode; // Joystick / Paddle management
Expand Down
64 changes: 51 additions & 13 deletions arm9/source/cpu/sn76496/Fake_AY.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
// The 'Fake' AY handler simply turns AY sound register access into corresponding
// SN sound chip calls. There is some loss of fidelity and we have to handle the
// volume envelopes in a very crude way... but it works and is good enough for now.
//
// The AY register map is as follows:
// Reg Description
// 0-5 Tone generator control for channels A,B,C
// 6 Noise generator control
// 7 Mixer control-I/O enable
// 8-10 Amplitude control for channels A,B,C
// 11-12 Envelope generator period
// 13 Envelope generator shape
// 14-15 I/O ports A & B (MSX Joystick mapped in here - otherwise unused)
// ------------------------------------------------------------------------------------

#include <nds.h>
Expand Down Expand Up @@ -78,12 +88,15 @@ void FakeAY_Loop(void)

if (envelope_period == 0) return;

if (++delay > ((envelope_period)+1))
if (++delay > ((envelope_period>>2)+1))
{
delay = 0;
u8 shape=0;
shape = ay_reg[0x0D] & 0x0F;
if ((ay_reg[0x08] & 0x20) && (!(ay_reg[0x07] & 0x01)))
u8 shape = ay_reg[0x0D] & 0x0F;

// ---------------------------------------------------------------
// If Envelope is enabled for Channel A and Channel is enabled...
// ---------------------------------------------------------------
if ((ay_reg[0x08] & 0x20) && (!(ay_reg[0x07] & 0x01)) && channel_a_enable)
{
u8 vol = Envelopes[shape][a_idx];
if (++a_idx > 31)
Expand All @@ -93,7 +106,10 @@ void FakeAY_Loop(void)
sn76496W(0x90 | vol, &aycol);
}

if ((ay_reg[0x09] & 0x20) && (!(ay_reg[0x07] & 0x02)))
// ---------------------------------------------------------------
// If Envelope is enabled for Channel B and Channel is enabled...
// ---------------------------------------------------------------
if ((ay_reg[0x09] & 0x20) && (!(ay_reg[0x07] & 0x02)) && channel_b_enable)
{
u8 vol = Envelopes[shape][b_idx];
if (++b_idx > 31)
Expand All @@ -103,7 +119,10 @@ void FakeAY_Loop(void)
sn76496W(0xB0 | vol, &aycol);
}

if ((ay_reg[0x0A] & 0x20) && (!(ay_reg[0x07] & 0x04)))
// ---------------------------------------------------------------
// If Envelope is enabled for Channel C and Channel is enabled...
// ---------------------------------------------------------------
if ((ay_reg[0x0A] & 0x20) && (!(ay_reg[0x07] & 0x04)) && channel_c_enable)
{
u8 vol = Envelopes[shape][c_idx];
if (++c_idx > 31)
Expand Down Expand Up @@ -138,7 +157,7 @@ u8 FakeAY_ReadData(void)
// ------------------------------------------------------------------
void UpdateNoiseAY(void)
{
// Noise Channel - we turn it on if the noise channel is enable along with the channel's volume not zero...
// Noise Channel - we turn it on if the noise channel is enabled along with the channel's volume not zero...
if ( (!(ay_reg[0x07] & 0x08) && (ay_reg[0x08] != 0) && channel_a_enable) ||
(!(ay_reg[0x07] & 0x10) && (ay_reg[0x09] != 0) && channel_b_enable) ||
(!(ay_reg[0x07] & 0x20) && (ay_reg[0x0A] != 0) && channel_c_enable) )
Expand All @@ -149,9 +168,12 @@ void UpdateNoiseAY(void)
if (noise_period > 16) sn76496W(0xE2, &aycol); // E2 is the lowest frequency (highest period)
else if (noise_period > 8) sn76496W(0xE1, &aycol); // E1 is the middle frequency (middle period)
else sn76496W(0xE0, &aycol); // E0 is the highest frequency (lowest period)

// Now output the noise for the first channel it's enbled on...
if (!(ay_reg[0x07] & 0x08) && (ay_reg[0x08] != 0) && channel_a_enable) sn76496W(0xF0 | Volumes[ay_reg[0x08]], &aycol);
if (!(ay_reg[0x07] & 0x10) && (ay_reg[0x09] != 0) && channel_b_enable) sn76496W(0xF0 | Volumes[ay_reg[0x09]], &aycol);
if (!(ay_reg[0x07] & 0x20) && (ay_reg[0x0A] != 0) && channel_c_enable) sn76496W(0xF0 | Volumes[ay_reg[0x0A]], &aycol);
else if (!(ay_reg[0x07] & 0x10) && (ay_reg[0x09] != 0) && channel_b_enable) sn76496W(0xF0 | Volumes[ay_reg[0x09]], &aycol);
else if (!(ay_reg[0x07] & 0x20) && (ay_reg[0x0A] != 0) && channel_c_enable) sn76496W(0xF0 | Volumes[ay_reg[0x0A]], &aycol);
else sn76496W(0xFF, &aycol);
}
}
else
Expand Down Expand Up @@ -275,7 +297,7 @@ void FakeAY_WriteData(u8 Value)
if (channel_b_enable)
{
channel_b_enable = 0;
sn76496W(0xB0 | 0x0F, &aycol);
sn76496W(0xB0 | 0x0F, &aycol); // Set Volume to OFF
}
}

Expand Down Expand Up @@ -305,7 +327,9 @@ void FakeAY_WriteData(u8 Value)
UpdateNoiseAY();
break;

// Volume Registers for all channels...
// ----------------------------------
// Volume Registers are below...
// ----------------------------------
case 0x08:
if (Value & 0x20) // If Envelope Mode... see if this is being enabled
{
Expand Down Expand Up @@ -352,10 +376,24 @@ void FakeAY_WriteData(u8 Value)
UpdateNoiseAY();
break;

// Envelope Period
// -----------------------------
// Envelope Period Register
// -----------------------------
case 0x0B:
case 0x0C:
envelope_period = ((ay_reg[0x0C] << 8) | ay_reg[0x0B]) & 0x3FFF;
{
u16 new_period = ((ay_reg[0x0C] << 8) | ay_reg[0x0B]) & 0x3FFF;
if ((envelope_period > 0) && (new_period == 0))
{
prevEnvelopeA_enabled = false;
prevEnvelopeB_enabled = false;
prevEnvelopeC_enabled = false;
sn76496W(0x9F, &aycol);
sn76496W(0xBF, &aycol);
sn76496W(0xDF, &aycol);
}
envelope_period = new_period;
}
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion arm9/source/cpu/tms9918a/tms9918a.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ void RefreshLine3(u8 uY) {
* Emulator calls this function to write byte 'value' into a VDP register 'iReg'
********************************************************************************/
static u8 VDP_RegisterMasks[] = { 0x03, 0xfb, 0x0f, 0xff, 0x07, 0x7f, 0x07, 0xff };
ITCM_CODE byte Write9918(u8 iReg, u8 value)
byte Write9918(u8 iReg, u8 value)
{
int newMode;
int VRAMMask;
Expand Down
Loading

0 comments on commit bffb1a3

Please sign in to comment.