mirror of
https://github.com/jeremysrand/mocklib.git
synced 2024-06-08 06:29:29 +00:00
Initial commit with basic sound and speech support.
This commit is contained in:
parent
d871fb4660
commit
84ddb58602
|
@ -7,6 +7,7 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
9D16BCE21D9E070B005EE214 /* speech.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = speech.s; sourceTree = "<group>"; };
|
||||||
9DB3C98C1D84A11600395532 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
|
9DB3C98C1D84A11600395532 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
|
||||||
9DB3C98D1D84A11600395532 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
9DB3C98D1D84A11600395532 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
||||||
9DB3C98F1D84A11600395532 /* AppleCommander.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = AppleCommander.jar; path = make/AppleCommander.jar; sourceTree = "<group>"; };
|
9DB3C98F1D84A11600395532 /* AppleCommander.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = AppleCommander.jar; path = make/AppleCommander.jar; sourceTree = "<group>"; };
|
||||||
|
@ -17,6 +18,8 @@
|
||||||
9DB3C9941D84A11600395532 /* prodos_template.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; name = prodos_template.dsk; path = make/prodos_template.dsk; sourceTree = "<group>"; };
|
9DB3C9941D84A11600395532 /* prodos_template.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; name = prodos_template.dsk; path = make/prodos_template.dsk; sourceTree = "<group>"; };
|
||||||
9DB3C9951D84A11600395532 /* tail.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = tail.mk; path = make/tail.mk; sourceTree = "<group>"; };
|
9DB3C9951D84A11600395532 /* tail.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = tail.mk; path = make/tail.mk; sourceTree = "<group>"; };
|
||||||
9DB3C9961D84A11600395532 /* V2Make.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; name = V2Make.scpt; path = make/V2Make.scpt; sourceTree = "<group>"; };
|
9DB3C9961D84A11600395532 /* V2Make.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; name = V2Make.scpt; path = make/V2Make.scpt; sourceTree = "<group>"; };
|
||||||
|
9DB3C99C1D84A21E00395532 /* mockingboard.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mockingboard.c; sourceTree = "<group>"; };
|
||||||
|
9DB3C99D1D84A21E00395532 /* mockingboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mockingboard.h; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
@ -31,6 +34,9 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9DB3C98C1D84A11600395532 /* main.c */,
|
9DB3C98C1D84A11600395532 /* main.c */,
|
||||||
|
9DB3C99C1D84A21E00395532 /* mockingboard.c */,
|
||||||
|
9DB3C99D1D84A21E00395532 /* mockingboard.h */,
|
||||||
|
9D16BCE21D9E070B005EE214 /* speech.s */,
|
||||||
9DB3C98D1D84A11600395532 /* Makefile */,
|
9DB3C98D1D84A11600395532 /* Makefile */,
|
||||||
9DB3C98E1D84A11600395532 /* make */,
|
9DB3C98E1D84A11600395532 /* make */,
|
||||||
);
|
);
|
||||||
|
@ -223,6 +229,7 @@
|
||||||
9DB3C99B1D84A11600395532 /* Release */,
|
9DB3C99B1D84A11600395532 /* Release */,
|
||||||
);
|
);
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,22 @@
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
buildImplicitDependencies = "YES">
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "9DB3C98A1D84A11600395532"
|
||||||
|
BuildableName = "mocktest"
|
||||||
|
BlueprintName = "mocktest"
|
||||||
|
ReferencedContainer = "container:mocktest.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
</BuildAction>
|
</BuildAction>
|
||||||
<TestAction
|
<TestAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
|
@ -26,6 +42,15 @@
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "9DB3C98A1D84A11600395532"
|
||||||
|
BuildableName = "mocktest"
|
||||||
|
BlueprintName = "mocktest"
|
||||||
|
ReferencedContainer = "container:mocktest.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
|
@ -35,6 +60,15 @@
|
||||||
savedToolIdentifier = ""
|
savedToolIdentifier = ""
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
debugDocumentVersioning = "YES">
|
debugDocumentVersioning = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "9DB3C98A1D84A11600395532"
|
||||||
|
BuildableName = "mocktest"
|
||||||
|
BlueprintName = "mocktest"
|
||||||
|
ReferencedContainer = "container:mocktest.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
</ProfileAction>
|
</ProfileAction>
|
||||||
<AnalyzeAction
|
<AnalyzeAction
|
||||||
buildConfiguration = "Debug">
|
buildConfiguration = "Debug">
|
||||||
|
|
|
@ -25,7 +25,7 @@ PGM=mocktest
|
||||||
# Uncomment the one you want below (the first one is the default):
|
# Uncomment the one you want below (the first one is the default):
|
||||||
# MACHINE = apple2
|
# MACHINE = apple2
|
||||||
# MACHINE = apple2-dos33
|
# MACHINE = apple2-dos33
|
||||||
# MACHINE = apple2-system
|
MACHINE = apple2-system
|
||||||
# MACHINE = apple2-loader
|
# MACHINE = apple2-loader
|
||||||
# MACHINE = apple2-reboot
|
# MACHINE = apple2-reboot
|
||||||
# MACHINE = apple2enh
|
# MACHINE = apple2enh
|
||||||
|
|
|
@ -8,13 +8,105 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
|
||||||
|
#include "mockingboard.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern void setupSpeech(void);
|
||||||
|
uint8_t **tabPtr = (uint8_t **)0x00f9;
|
||||||
|
|
||||||
|
|
||||||
|
tMockingSoundRegisters soundData1 = {
|
||||||
|
{ TONE_PERIOD_A(4), 0, 0 }, // Tone period for the three channels
|
||||||
|
MIN_NOISE_PERIOD, // Noise period
|
||||||
|
ENABLE_CHANNEL(TONE_CHANNEL_A), // Enable
|
||||||
|
{ MAX_AMPLITUDE, MIN_AMPLITUDE, MIN_AMPLITUDE }, // Amplitude for the three channels
|
||||||
|
MIN_ENVELOPE_PERIOD, // Envelope period
|
||||||
|
ENVELOPE_SHAPE_ONE_SHOT_DECAY, // Envelope shape
|
||||||
|
0, // Dummy1
|
||||||
|
0 // Dummy2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
tMockingSoundRegisters soundData2 = {
|
||||||
|
{ TONE_PERIOD_F_SHARP(3), 0, 0 }, // Tone period for the three channels
|
||||||
|
MIN_NOISE_PERIOD, // Noise period
|
||||||
|
ENABLE_CHANNEL(TONE_CHANNEL_A), // Enable
|
||||||
|
{ MAX_AMPLITUDE, MIN_AMPLITUDE, MIN_AMPLITUDE }, // Amplitude for the three channels
|
||||||
|
MIN_ENVELOPE_PERIOD, // Envelope period
|
||||||
|
ENVELOPE_SHAPE_ONE_SHOT_DECAY, // Envelope shape
|
||||||
|
0, // Dummy1
|
||||||
|
0 // Dummy2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t speechData[] = {
|
||||||
|
0xCF, 0x00, 0xE8, 0x70, 0xA8, 0x5F, 0x00, 0xE8,
|
||||||
|
0x70, 0xA8, 0x5F, 0x00, 0xE8, 0x70, 0xA8, 0x5F,
|
||||||
|
0x00, 0xE8, 0x7B, 0xA8, 0x5F, 0x63, 0xE7, 0x6B,
|
||||||
|
0xA8, 0x59, 0x47, 0xE8, 0x6A, 0xA8, 0x61, 0x36,
|
||||||
|
0xE8, 0x79, 0xA8, 0x65, 0x37, 0xE7, 0x79, 0xA8,
|
||||||
|
0x69, 0x0E, 0xE7, 0x6A, 0xA8, 0x61, 0x29, 0xE8,
|
||||||
|
0x6B, 0xA8, 0x59, 0xAD, 0xE8, 0x6B, 0xA8, 0x51,
|
||||||
|
0xC0, 0xE8, 0x6A, 0xA8, 0x51, 0x07, 0xE8, 0x6A,
|
||||||
|
0xA8, 0x4B, 0x39, 0xE8, 0x6A, 0xA8, 0x49, 0x64,
|
||||||
|
0xE7, 0x6A, 0x88, 0x49, 0x11, 0xE7, 0x5A, 0xB8,
|
||||||
|
0x51, 0x63, 0xE7, 0x5A, 0xB8, 0x59, 0x1D, 0xE8,
|
||||||
|
0x7A, 0xA8, 0x61, 0x65, 0xE8, 0x79, 0xA8, 0x61,
|
||||||
|
0xC0, 0xE8, 0x70, 0x78, 0x51, 0x00, 0xE8, 0x70,
|
||||||
|
0x78, 0x51, 0x00, 0xE8, 0x70, 0x78, 0x59, 0x00,
|
||||||
|
0xE7, 0x79, 0xA8, 0x65, 0x04, 0xE7, 0x6A, 0x98,
|
||||||
|
0x61, 0x16, 0xE8, 0x6B, 0xA8, 0x61, 0x60, 0xE8,
|
||||||
|
0x7C, 0xA8, 0x59, 0x78, 0xE7, 0x7C, 0xA8, 0x55,
|
||||||
|
0x0A, 0xE8, 0x6B, 0xA8, 0x62, 0x33, 0xE8, 0x6A,
|
||||||
|
0xA8, 0x59, 0x1C, 0xE8, 0x7A, 0xA8, 0x51, 0x64,
|
||||||
|
0xE7, 0x7B, 0x88, 0x51, 0x01, 0xE8, 0x7C, 0xA8,
|
||||||
|
0x59, 0x30, 0xE8, 0x7D, 0xA8, 0x59, 0x27, 0xE7,
|
||||||
|
0x7D, 0x78, 0x61, 0x01, 0xE8, 0x6C, 0xA8, 0x61,
|
||||||
|
0x28, 0xE8, 0x6B, 0xA8, 0x59, 0x32, 0xE8, 0x6A,
|
||||||
|
0xA8, 0x4D, 0x60, 0xE7, 0x29, 0xA8, 0x41, 0x0A,
|
||||||
|
0xE8, 0x78, 0xA8, 0x41, 0x30, 0xE8, 0x70, 0xA8,
|
||||||
|
0x39, 0xFF, 0xE8, 0x70, 0xA8, 0x39, 0x00, 0xE8,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void delay(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 1000; i++) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
mockingBoardInit(4);
|
||||||
|
|
||||||
printf("HELLO, WORLD!\n");
|
printf("HELLO, WORLD!\n");
|
||||||
|
|
||||||
|
while (!kbhit()) {
|
||||||
|
mockingBoardTableAccess(SOUND_CHIP_1, &soundData1);
|
||||||
|
delay();
|
||||||
|
mockingBoardReset(SOUND_CHIP_1);
|
||||||
|
|
||||||
|
mockingBoardTableAccess(SOUND_CHIP_2, &soundData2);
|
||||||
|
delay();
|
||||||
|
mockingBoardReset(SOUND_CHIP_2);
|
||||||
|
}
|
||||||
|
|
||||||
cgetc();
|
cgetc();
|
||||||
|
printf("RUN SPEECH TEST (Y/N) ");
|
||||||
|
if (cgetc() != 'Y')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*tabPtr = speechData;
|
||||||
|
setupSpeech();
|
||||||
|
|
||||||
|
cgetc();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
114
mocktest/mockingboard.c
Normal file
114
mocktest/mockingboard.c
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
//
|
||||||
|
// mockingboard.c
|
||||||
|
// mocktest
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2016-09-10.
|
||||||
|
// Copyright © 2016 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "mockingboard.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Defines
|
||||||
|
|
||||||
|
#define LATCH_COMMAND 0x7
|
||||||
|
#define WRITE_COMMAND 0x6
|
||||||
|
#define RESET_COMMAND 0x0
|
||||||
|
#define THROUGH_PORT_B 0x4
|
||||||
|
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
|
||||||
|
// Addresses for the two 6522's (assuming slot 4 for now)
|
||||||
|
static uint8_t *gMockPortB[NUM_SOUND_CHIPS] = { (uint8_t *)0xc400, (uint8_t *)0xc480 };
|
||||||
|
static uint8_t *gMockPortA[NUM_SOUND_CHIPS] = { (uint8_t *)0xc401, (uint8_t *)0xc481 };
|
||||||
|
static uint8_t *gMockDataDirB[NUM_SOUND_CHIPS] = { (uint8_t *)0xc402, (uint8_t *)0xc482 };
|
||||||
|
static uint8_t *gMockDataDirA[NUM_SOUND_CHIPS] = { (uint8_t *)0xc403, (uint8_t *)0xc483 };
|
||||||
|
|
||||||
|
static uint8_t gMockingBoardInitialized = false;
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t *mapIOPointer(uint8_t slot, uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint16_t temp1 = (uint16_t)ptr;
|
||||||
|
uint16_t temp2 = slot;
|
||||||
|
|
||||||
|
temp2 << 8;
|
||||||
|
temp1 &= 0xf0ff;
|
||||||
|
|
||||||
|
temp1 |= temp2;
|
||||||
|
ptr = (uint8_t *)temp1;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mockingBoardInit(tSlot slot)
|
||||||
|
{
|
||||||
|
tSoundChip soundChip;
|
||||||
|
|
||||||
|
if (sizeof(tMockingSoundRegisters) != 16) {
|
||||||
|
printf("The sound registers must be 16 bytes long!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (soundChip = SOUND_CHIP_1; soundChip < NUM_SOUND_CHIPS; soundChip++) {
|
||||||
|
#if 0
|
||||||
|
gMockPortB[soundChip] = mapIOPointer(slot, gMockPortB[soundChip]);
|
||||||
|
gMockPortA[soundChip] = mapIOPointer(slot, gMockPortA[soundChip]);
|
||||||
|
gMockDataDirB[soundChip] = mapIOPointer(slot, gMockDataDirB[soundChip]);
|
||||||
|
gMockDataDirA[soundChip] = mapIOPointer(slot, gMockDataDirA[soundChip]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*(gMockDataDirA[soundChip]) = 0xff; // Set port A for output
|
||||||
|
*(gMockDataDirB[soundChip]) = 0x7; // Set port B for output
|
||||||
|
}
|
||||||
|
|
||||||
|
gMockingBoardInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void writeCommand(tSoundChip soundChip, uint8_t command)
|
||||||
|
{
|
||||||
|
volatile uint8_t *ptr = gMockPortB[soundChip];
|
||||||
|
|
||||||
|
*ptr = command;
|
||||||
|
*ptr = THROUGH_PORT_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mockingBoardLatch(tSoundChip soundChip)
|
||||||
|
{
|
||||||
|
writeCommand(soundChip, LATCH_COMMAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mockingBoardWrite(tSoundChip soundChip)
|
||||||
|
{
|
||||||
|
writeCommand(soundChip, WRITE_COMMAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mockingBoardReset(tSoundChip soundChip)
|
||||||
|
{
|
||||||
|
writeCommand(soundChip, RESET_COMMAND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mockingBoardTableAccess(tSoundChip soundChip, tMockingSoundRegisters *registers)
|
||||||
|
{
|
||||||
|
uint8_t *data = (uint8_t *)registers;
|
||||||
|
volatile uint8_t *ptr = gMockPortA[soundChip];
|
||||||
|
uint8_t index;
|
||||||
|
|
||||||
|
mockingBoardReset(soundChip);
|
||||||
|
for (index = 0; index < 16; index++) {
|
||||||
|
*ptr = index;
|
||||||
|
mockingBoardLatch(soundChip);
|
||||||
|
*ptr = *data;
|
||||||
|
mockingBoardWrite(soundChip);
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
}
|
123
mocktest/mockingboard.h
Normal file
123
mocktest/mockingboard.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
//
|
||||||
|
// mockingboard.h
|
||||||
|
// mocktest
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2016-09-10.
|
||||||
|
// Copyright © 2016 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __mocktest__mockingboard__
|
||||||
|
#define __mocktest__mockingboard__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Defines
|
||||||
|
|
||||||
|
#define MOCK_NUM_CHANNELS 3
|
||||||
|
|
||||||
|
|
||||||
|
#define TONE_PERIOD_C(octave) (0x7a3 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_C_SHARP(octave) (0x735 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_D(octave) (0x6cd >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_D_SHARP(octave) (0x66c >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_E(octave) (0x60f >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_F(octave) (0x5b8 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_F_SHARP(octave) (0x566 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_G(octave) (0x518 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_G_SHARP(octave) (0x4cf >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_A(octave) (0x48a >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_A_SHARP(octave) (0x449 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_B(octave) (0x40b >> (octave - 1))
|
||||||
|
|
||||||
|
#define MIN_NOISE_PERIOD 0
|
||||||
|
#define MAX_NOISE_PERIOD 31
|
||||||
|
|
||||||
|
#define TONE_CHANNEL_A 1
|
||||||
|
#define TONE_CHANNEL_B 2
|
||||||
|
#define TONE_CHANNEL_C 4
|
||||||
|
#define NOISE_CHANNEL_A 8
|
||||||
|
#define NOISE_CHANNLE_B 16
|
||||||
|
#define NOISE_CHANNEL_C 32
|
||||||
|
|
||||||
|
#define ENABLE_CHANNEL(channels) (0x3f ^ (channels))
|
||||||
|
|
||||||
|
#define MIN_AMPLITUDE 0
|
||||||
|
#define MAX_AMPLITUDE 15
|
||||||
|
#define VARIABLE_AMPLITUDE 16
|
||||||
|
|
||||||
|
#define MIN_ENVELOPE_PERIOD 0
|
||||||
|
#define MAX_ENVELOPE_PERIOD 65535u
|
||||||
|
#define MILLISEC_TO_ENVELOP_PERIOD(ms) ((ms) * 4)
|
||||||
|
|
||||||
|
|
||||||
|
// Here is a table of the envelope shapes and how they look:
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_ONE_SHOT_DECAY \__________...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_ONE_SHOT_ATTACK /__________...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_DECAY \|\|\|\|\|\...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_DECAY_HOLD \__________...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_DECAY_ALT \/\/\/\/\/\...
|
||||||
|
// _________
|
||||||
|
// ENVELOPE_SHAPE_CONT_DECAY_ALT_HOLD \| ...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_ATTACK /|/|/|/|/|/...
|
||||||
|
// __________
|
||||||
|
// ENVELOPE_SHAPE_CONT_ATTACK_HOLD / ...
|
||||||
|
// ENVELOPE_SHAPE_CONT_ATTACK_ALT /\/\/\/\/\/...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_ATTACK_ALT_HOLD /|_________...
|
||||||
|
|
||||||
|
#define ENVELOPE_SHAPE_ONE_SHOT_DECAY 0
|
||||||
|
#define ENVELOPE_SHAPE_ONE_SHOT_ATTACK 4
|
||||||
|
#define ENVELOPE_SHAPE_CONT_DECAY 8
|
||||||
|
#define ENVELOPE_SHAPE_CONT_DECAY_HOLD 9
|
||||||
|
#define ENVELOPE_SHAPE_CONT_DECAY_ALT 10
|
||||||
|
#define ENVELOPE_SHAPE_CONT_DECAY_ALT_HOLD 11
|
||||||
|
#define ENVELOPE_SHAPE_CONT_ATTACK 12
|
||||||
|
#define ENVELOPE_SHAPE_CONT_ATTACK_HOLD 13
|
||||||
|
#define ENVELOPE_SHAPE_CONT_ATTACK_ALT 14
|
||||||
|
#define ENVELOPE_SHAPE_CONT_ATTACK_ALT_HOLD 15
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Typedefs
|
||||||
|
|
||||||
|
typedef uint8_t tSlot;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SOUND_CHIP_1 = 0,
|
||||||
|
SOUND_CHIP_2 = 1,
|
||||||
|
NUM_SOUND_CHIPS = 2
|
||||||
|
} tSoundChip;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct tMockingSoundRegisters {
|
||||||
|
uint16_t tonePeriod[MOCK_NUM_CHANNELS];
|
||||||
|
uint8_t noisePeriod;
|
||||||
|
uint8_t enable;
|
||||||
|
uint8_t amplitude[MOCK_NUM_CHANNELS];
|
||||||
|
uint16_t envelopePeriod;
|
||||||
|
uint8_t envelopeShape;
|
||||||
|
uint8_t dummy1;
|
||||||
|
uint8_t dummy2;
|
||||||
|
} tMockingSoundRegisters;
|
||||||
|
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
void mockingBoardInit(tSlot slot);
|
||||||
|
|
||||||
|
void mockingBoardLatch(tSoundChip soundChip);
|
||||||
|
void mockingBoardWrite(tSoundChip soundChip);
|
||||||
|
void mockingBoardReset(tSoundChip soundChip);
|
||||||
|
|
||||||
|
void mockingBoardTableAccess(tSoundChip soundChip, tMockingSoundRegisters *registers);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* defined(__mocktest__mockingboard__) */
|
135
mocktest/speech.s
Normal file
135
mocktest/speech.s
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
;
|
||||||
|
; speech.s
|
||||||
|
; mocktest
|
||||||
|
;
|
||||||
|
; Created by Jeremy Rand on 2016-09-29.
|
||||||
|
; Copyright © 2016 Jeremy Rand. All rights reserved.
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
.export _setupSpeech
|
||||||
|
|
||||||
|
|
||||||
|
TABPTR := $F9 ;DATA POINTER
|
||||||
|
OUTPTR := $FB ;START OF DATA POINTER
|
||||||
|
ENDPTR := $FD ;END OF DATA POINTER
|
||||||
|
BUSY := $FF ;BUSY FLAG
|
||||||
|
IRQL := $03FE ;INTERRUPT VECTOR, LOW BYTE
|
||||||
|
IRQH := $03FF ;INTERRUPT VECTOR, HIGH BYTE
|
||||||
|
BASE := $C440 ;FIRST SPEECH CHIP
|
||||||
|
DURPHON := BASE ;REGISTER 0 OF SPEECH CHIP
|
||||||
|
INFLECT := BASE+$01 ;REGISTER 1 OF SPEECH CHIP
|
||||||
|
RATEINF := BASE+$02 ;REGISTER 2 OF SPEECH CHIP
|
||||||
|
CTTRAMP := BASE+$03 ;REGISTER 3 OF SPEECH CHIP
|
||||||
|
FILFREQ := BASE+$04 ;REGISTER 4 OF SPEECH CHIP
|
||||||
|
DDRB := $C402
|
||||||
|
DDRA := $C403
|
||||||
|
PCR := $C48C ;PERIPHERAL CONTROL REG-6522
|
||||||
|
IFR := $C48D ;INTERRUPT FLAG REG-6522
|
||||||
|
IER := $C48E
|
||||||
|
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
|
||||||
|
.proc _setupSpeech
|
||||||
|
SEI ;DISABLE INTERRUPTS
|
||||||
|
LDA #<_interr ;SET INTERRUPT VECTOR
|
||||||
|
STA IRQL ;TO POINT TO INTERRUPT
|
||||||
|
LDA #>_interr ;SERVICE ROUTINE
|
||||||
|
STA IRQH
|
||||||
|
LDA #$00
|
||||||
|
STA DDRA
|
||||||
|
STA DDRB
|
||||||
|
|
||||||
|
LDA TABPTR+1 ;GET HIGH ADDRESS OF DATA
|
||||||
|
STA OUTPTR+1 ;STORE IN WORK POINTER
|
||||||
|
LDX TABPTR ;GET LOW ADDRESS OF DATA
|
||||||
|
INX ;INCREMENT TWICE
|
||||||
|
INX ;TO SKIP OVER LENGTH BYTES
|
||||||
|
BNE @L1 ;CHECK FOR PAGE BOUNDARY
|
||||||
|
INC OUTPTR+1
|
||||||
|
@L1:
|
||||||
|
STX OUTPTR ;STORE LOW BYTE
|
||||||
|
|
||||||
|
LDY #$01
|
||||||
|
LDA (TABPTR),Y ;GET HIGH LENGTH BYTE
|
||||||
|
CLC
|
||||||
|
ADC TABPTR+1 ;AND ADD TO BASE ADDRESS
|
||||||
|
STA ENDPTR+1 ;STORE END ADDRESS
|
||||||
|
DEY
|
||||||
|
LDA (TABPTR),Y ;GET LOW LENGTH BYTE
|
||||||
|
CLC
|
||||||
|
ADC TABPTR ;AND ADD TO BASE ADDRESS
|
||||||
|
BCC @L2 ;CHECK FOR PAGE BOUNDARY
|
||||||
|
INC ENDPTR+1
|
||||||
|
@L2:
|
||||||
|
STA ENDPTR ;STORE END ADDRESS
|
||||||
|
|
||||||
|
LDA #$FF ;SET BUSY FLAG
|
||||||
|
STA BUSY ;AND SET PERIPHERAL CONTROL
|
||||||
|
LDA #$0C ;REGISTER TO RECOGNIZE
|
||||||
|
STA PCR ;SIGNAL FROM SPEECH CHIP
|
||||||
|
LDA #$80 ;RAISE CTRL BIT IN REGISTER 3
|
||||||
|
STA CTTRAMP
|
||||||
|
LDA #$C0 ;SET TRANSITIONED INFLECTION
|
||||||
|
STA DURPHON ;MODE IN REGISTER 0
|
||||||
|
LDA #$70 ;LOWER CTRL BIT
|
||||||
|
STA CTTRAMP
|
||||||
|
LDA #$82 ;ENABLE 6522 INTERRUPTS
|
||||||
|
STA IER
|
||||||
|
CLI ;CLEAR INTERRUPT MASK
|
||||||
|
RTS ;RETURN TO CALLER
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
.proc _interr
|
||||||
|
TXA ;SAVE REGISTERS
|
||||||
|
PHA
|
||||||
|
TYA
|
||||||
|
PHA
|
||||||
|
LDA IFR
|
||||||
|
BPL @L2
|
||||||
|
LDA #$02 ;CLEAR INTERRUPT FLAG
|
||||||
|
STA IFR
|
||||||
|
LDY #$00 ;INIT REGISTERS
|
||||||
|
LDX #$04
|
||||||
|
LDA OUTPTR ;CHECK FOR END OF DATA FILE
|
||||||
|
CMP ENDPTR
|
||||||
|
BCC @L1 ;IF NOT THEN CONTINUE
|
||||||
|
LDA OUTPTR+1 ;CHECK HIGH ADDRESS ALSO
|
||||||
|
CMP ENDPTR+1
|
||||||
|
BCC @L1 ;IF NOT THEN CONTINUE
|
||||||
|
LDA #$00 ;IF END, TURN EVERYTHING OFF
|
||||||
|
STA DURPHON ;STORE PAUSE PHONEME
|
||||||
|
LDA #$70 ;ZERO AMPLITUDE
|
||||||
|
STA CTTRAMP
|
||||||
|
LDA #$00 ;CLEAR BUSY FLAG
|
||||||
|
STA BUSY
|
||||||
|
LDA #$02 ;CLEAR INTERRUPT ENABLE
|
||||||
|
STA IER ;IN 6522
|
||||||
|
LDA #$FF
|
||||||
|
STA DDRA
|
||||||
|
LDA #$07
|
||||||
|
STA DDRB
|
||||||
|
@L2:
|
||||||
|
PLA ;RESTORE REGISTERS
|
||||||
|
TAY
|
||||||
|
PLA
|
||||||
|
TAX
|
||||||
|
LDA $45
|
||||||
|
RTI ;RETURN FROM INTERRUPT
|
||||||
|
|
||||||
|
@L1:
|
||||||
|
LDA (OUTPTR),Y ;GET DATA
|
||||||
|
STA BASE,X ;STORE IN SPEECH CHIP
|
||||||
|
INC OUTPTR ;NEXT DATA
|
||||||
|
BNE @L3
|
||||||
|
INC OUTPTR+1
|
||||||
|
|
||||||
|
@L3:
|
||||||
|
DEX ;NEXT REGISTER
|
||||||
|
CPX #$FF ;LAST REGISTER?
|
||||||
|
BNE @L1 ;NO, CONTINUE
|
||||||
|
BEQ @L2 ;YES, RETURN
|
||||||
|
.endproc
|
||||||
|
|
Loading…
Reference in New Issue
Block a user