Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f49977bfb | |||
| 297d0ca8b3 |
6 changed files with 121 additions and 6 deletions
3
Makefile
3
Makefile
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
DEBUG ?= 0
|
||||
MEMSIZE ?= 128
|
||||
ENABLE_AUDIO ?= 1
|
||||
|
||||
SOURCES = $(wildcard src/*.c)
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ endif
|
|||
# Basic support for changing screen res (with the MacPlusV3 ROM)
|
||||
DISP_WIDTH ?= 512
|
||||
DISP_HEIGHT ?= 342
|
||||
CFLAGS_CFG = -DDISP_WIDTH=$(DISP_WIDTH) -DDISP_HEIGHT=$(DISP_HEIGHT)
|
||||
CFLAGS_CFG = -DDISP_WIDTH=$(DISP_WIDTH) -DDISP_HEIGHT=$(DISP_HEIGHT) -DENABLE_AUDIO=$(ENABLE_AUDIO)
|
||||
|
||||
all: main
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ extern int overlay;
|
|||
* But, that should never happen post-boot.
|
||||
*/
|
||||
#define CLAMP_RAM_ADDR(x) ((x) >= RAM_SIZE ? (x) % RAM_SIZE : (x))
|
||||
/* Is the address (previously clamped with CLAMP_RAM_ADDR) the audio trap address? (last byte of audio data) */
|
||||
#define IS_RAM_AUDIO_TRAP(x) (x == umac_get_audio_offset() + 2 * 369)
|
||||
|
||||
#define IS_VIA(x) ((ADR24(x) & 0xe80000) == 0xe80000)
|
||||
#define IS_IWM(x) ((ADR24(x) >= 0xdfe1ff) && (ADR24(x) < (0xdfe1ff + 0x2000)))
|
||||
|
|
|
|||
|
|
@ -53,4 +53,11 @@ static inline unsigned int umac_get_fb_offset(void)
|
|||
return RAM_SIZE - ((DISP_WIDTH * DISP_HEIGHT / 8) + 0x380);
|
||||
}
|
||||
|
||||
#if ENABLE_AUDIO
|
||||
#define umac_get_audio_offset() (RAM_SIZE - 768)
|
||||
|
||||
void umac_audio_trap();
|
||||
void umac_audio_cfg(int volume, int sndres);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
28
src/main.c
28
src/main.c
|
|
@ -40,6 +40,7 @@
|
|||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "umac.h"
|
||||
#include "machw.h"
|
||||
#include "m68k.h"
|
||||
#include "via.h"
|
||||
|
|
@ -70,6 +71,9 @@ static unsigned int g_int_controller_highest_int = 0; /* Highest pending interr
|
|||
uint8_t *_ram_base;
|
||||
uint8_t *_rom_base;
|
||||
|
||||
#if ENABLE_AUDIO
|
||||
static int umac_volume, umac_sndres;
|
||||
#endif
|
||||
int overlay = 1;
|
||||
static uint64_t global_time_us = 0;
|
||||
static int sim_done = 0;
|
||||
|
|
@ -155,6 +159,14 @@ static void via_ra_changed(uint8_t val)
|
|||
update_overlay_layout();
|
||||
}
|
||||
|
||||
#if ENABLE_AUDIO
|
||||
uint8_t vol = val & 7;
|
||||
if (vol != umac_volume) {
|
||||
umac_volume = val & 7;
|
||||
umac_audio_cfg(umac_volume, umac_sndres);
|
||||
}
|
||||
#endif
|
||||
|
||||
oldval = val;
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +178,15 @@ static void via_rb_changed(uint8_t val)
|
|||
// 4 = mouse4 (in, mouse X2)
|
||||
// 3 = mouse7 (in, 0 = button pressed)
|
||||
// [2:0] = RTC controls
|
||||
#if ENABLE_AUDIO
|
||||
uint8_t sndres = val >> 7;
|
||||
if(sndres != umac_sndres) {
|
||||
umac_sndres = sndres;
|
||||
umac_audio_cfg(umac_volume, umac_sndres);
|
||||
}
|
||||
#else
|
||||
(void)val;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t via_ra_in(void)
|
||||
|
|
@ -437,7 +457,13 @@ unsigned int cpu_read_long_dasm(unsigned int address)
|
|||
void FAST_FUNC(cpu_write_byte)(unsigned int address, unsigned int value)
|
||||
{
|
||||
if (IS_RAM(address)) {
|
||||
RAM_WR8(CLAMP_RAM_ADDR(address), value);
|
||||
address = CLAMP_RAM_ADDR(address);
|
||||
RAM_WR8(address, value);
|
||||
#if ENABLE_AUDIO
|
||||
if(IS_RAM_AUDIO_TRAP(address)) {
|
||||
umac_audio_trap();
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ static void rom_patch_plusv3(uint8_t *rom_base)
|
|||
* allowing the ROM checksum to fail (it returns failure, then
|
||||
* we carry on). This avoids wild RAM addrs being accessed.
|
||||
*/
|
||||
|
||||
/* Fix up the sound buffer as used by BootBeep */
|
||||
ROM_WR32(0x292, RAM_SIZE - 768);
|
||||
#endif
|
||||
|
||||
#if DISP_WIDTH != 512 || DISP_HEIGHT != 342
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
|
|
@ -35,6 +36,9 @@
|
|||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if ENABLE_AUDIO
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
#include "SDL.h"
|
||||
|
||||
#include "rom.h"
|
||||
|
|
@ -78,6 +82,42 @@ static void copy_fb(uint32_t *fb_out, uint8_t *fb_in)
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_AUDIO
|
||||
// audio_callback is called from a thread, so pending_v_retrace can't be a regular variable
|
||||
atomic_int pending_v_retrace;
|
||||
static int volscale;
|
||||
uint8_t *audio_base;
|
||||
|
||||
int16_t audio[370];
|
||||
|
||||
void umac_audio_cfg(int umac_volume, int umac_sndres) {
|
||||
volscale = umac_sndres ? 0 : 65536 * umac_volume / 7;
|
||||
}
|
||||
|
||||
void umac_audio_trap() {
|
||||
int32_t offset = 128;
|
||||
uint16_t *audiodata = (uint16_t*)audio_base;
|
||||
int scale = volscale;
|
||||
if (!scale) {
|
||||
memset(audio, 0, sizeof(audio));
|
||||
return;
|
||||
}
|
||||
int16_t *stream = audio;
|
||||
for(int i=0; i<370; i++) {
|
||||
int32_t a = (*audiodata++ & 0xff) - offset;
|
||||
a = (a * scale) >> 8;
|
||||
*stream++ = a;
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_callback(void *userdata, Uint8 *stream_in, int len_bytes) {
|
||||
(void) userdata;
|
||||
assert(len_bytes == sizeof(audio));
|
||||
atomic_store(&pending_v_retrace, 1);
|
||||
memcpy(stream_in, audio, sizeof(audio));
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
/* The emulator core expects to be given ROM and RAM pointers,
|
||||
|
|
@ -232,7 +272,11 @@ int main(int argc, char *argv[])
|
|||
SDL_Renderer *renderer;
|
||||
SDL_Texture *texture;
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_Init(SDL_INIT_VIDEO
|
||||
#if ENABLE_AUDIO
|
||||
| SDL_INIT_AUDIO
|
||||
#endif
|
||||
);
|
||||
SDL_Window *window = SDL_CreateWindow("umac",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
|
|
@ -264,18 +308,47 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if ENABLE_AUDIO
|
||||
SDL_AudioSpec desired, obtained;
|
||||
|
||||
audio_base = (uint8_t*)ram_base + umac_get_audio_offset();
|
||||
|
||||
SDL_zero(desired);
|
||||
desired.freq = 22256; // wat
|
||||
desired.channels = 1;
|
||||
desired.samples = 370;
|
||||
desired.userdata = (uint8_t*)ram_base + umac_get_audio_offset();
|
||||
desired.callback = audio_callback;
|
||||
desired.format = AUDIO_S16;
|
||||
|
||||
SDL_AudioDeviceID audio_device = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, 0);
|
||||
if (!audio_device) {
|
||||
char buf[500];
|
||||
SDL_GetErrorMsg(buf, sizeof(buf));
|
||||
printf("SDL audio_deviceSDL_GetError() -> %s\n", buf);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Emulator init
|
||||
|
||||
umac_init(ram_base, rom_base, discs);
|
||||
umac_opt_disassemble(opt_disassemble);
|
||||
|
||||
#if ENABLE_AUDIO
|
||||
// Default state is paused, this unpauses it
|
||||
SDL_PauseAudioDevice(audio_device, 0);
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Main loop
|
||||
|
||||
int done = 0;
|
||||
int mouse_button = 0;
|
||||
#if !ENABLE_AUDIO
|
||||
uint64_t last_vsync = 0;
|
||||
#endif
|
||||
uint64_t last_1hz = 0;
|
||||
do {
|
||||
struct timeval tv_now;
|
||||
|
|
@ -321,11 +394,14 @@ int main(int argc, char *argv[])
|
|||
uint64_t now_usec = (tv_now.tv_sec * 1000000) + tv_now.tv_usec;
|
||||
|
||||
/* Passage of time: */
|
||||
if ((now_usec - last_vsync) >= 16667) {
|
||||
#if ENABLE_AUDIO
|
||||
int do_v_retrace = atomic_exchange(&pending_v_retrace, 0);
|
||||
#else
|
||||
int do_v_retrace = (now_usec - last_vsync) >= 16667;
|
||||
#endif
|
||||
if (do_v_retrace) {
|
||||
umac_vsync_event();
|
||||
last_vsync = now_usec;
|
||||
|
||||
/* Cheapo framerate limiting: */
|
||||
copy_fb(framebuffer, ram_get_base() + umac_get_fb_offset());
|
||||
SDL_UpdateTexture(texture, NULL, framebuffer,
|
||||
DISP_WIDTH * sizeof (Uint32));
|
||||
|
|
|
|||
Loading…
Reference in a new issue