rtoss

Subversion Repositories:
Compare Path: Rev
With Path: Rev
/ @ 336  →  / @ 337
/np21/video/cirrus_vga.c
@@ -1,23 +1,4 @@
#include "compiler.h"
 
#if defined(SUPPORT_CL_GD5430)
 
#include "video.h"
#include "cirrus_vga.h"
#include "vga_int.h"
#include "dosio.h"
#include "cpucore.h"
#include "pccore.h"
#include "iocore.h"
 
const uint8_t sr_mask[8] = {0};
const uint8_t gr_mask[16] = {0};
 
static void cpu_register_physical_memory(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset){
//memp_writes(start_addr, mem+phys_offset, size);
}
 
 
/*
* QEMU Cirrus CLGD 54xx VGA Emulator.
*
@@ -46,23 +27,46 @@
* Reference: Finn Thogersons' VGADOC4b
* available at http://home.worldonline.dk/~finth/
*/
//#include "hw.h"
//#include "pc.h"
//#include "pci.h"
//#include "console.h"
//#include "vga_int.h"
//#include "kvm.h"
 
/*
* TODO:
* - destination write mask support not complete (bits 5..7)
* - optimize linear mappings
* - optimize bitblt functions
*/
#include "compiler.h"
 
//#define DEBUG_CIRRUS
//#define DEBUG_BITBLT
#if defined(SUPPORT_CL_GD5430)
 
#include "video.h"
#include "cirrus_vga.h"
#include "vga_int.h"
#include "dosio.h"
#include "cpucore.h"
#include "pccore.h"
#include "iocore.h"
#include "soundmng.h"
 
const uint8_t sr_mask[8] = {0};
const uint8_t gr_mask[16] = {0};
 
REG8 cirrusvga_regindexA2 = 0;
REG8 cirrusvga_regindex = 0;
//REG8 cirrusvga_iomap = 0x0F;
REG8 cirrusvga_mmioenable = 0;
REG8 cirrusvga_paletteChanged = 1;
 
BITMAPINFO *ga_bmpInfo;
HWND ga_hWnd = NULL;
HDC ga_hdc = NULL;
HPALETTE ga_hpal = NULL;
 
UINT32 ga_VRAMWindowAddr = (0x0F<<24);
 
void cirrusvga_setGAWindow(HWND hWnd, HDC hdc){
ga_hWnd = hWnd;
ga_hdc = hdc;
}
 
static void cpu_register_physical_memory(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset){
//cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0);
 
}
 
/***************************************
*
* definitions
@@ -79,6 +83,7 @@
#define CIRRUS_ID_CLGD5430 (0x28<<2)
#define CIRRUS_ID_CLGD5434 (0x2A<<2)
#define CIRRUS_ID_CLGD5436 (0x2B<<2)
#define CIRRUS_ID_CLGD5440 (0x2C<<2)
#define CIRRUS_ID_CLGD5446 (0x2E<<2)
 
// sequencer 0x07
@@ -326,6 +331,164 @@
 
static uint8_t rop_to_index[256];
 
typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
#define NB_DEPTHS 7
 
static uint32_t_ rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
{
return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
}
 
static uint32_t_ rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
{
return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
}
 
static uint32_t_ rgb_to_pixel24(unsigned int r, unsigned int g, unsigned b)
{
return (r << 16) | (g << 8) | b;
}
 
static uint32_t_ rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
{
return (r << 16) | (g << 8) | b;
}
static unsigned int rgb_to_pixel8(unsigned int r, unsigned int g,
unsigned int b)
{
return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
}
 
static unsigned int rgb_to_pixel15bgr(unsigned int r, unsigned int g,
unsigned int b)
{
return ((b >> 3) << 10) | ((g >> 3) << 5) | (r >> 3);
}
 
static unsigned int rgb_to_pixel16bgr(unsigned int r, unsigned int g,
unsigned int b)
{
return ((b >> 3) << 11) | ((g >> 2) << 5) | (r >> 3);
}
 
static unsigned int rgb_to_pixel24bgr(unsigned int r, unsigned int g,
unsigned int b)
{
return (b << 16) | (g << 8) | r;
}
 
static unsigned int rgb_to_pixel32bgr(unsigned int r, unsigned int g,
unsigned int b)
{
return (b << 16) | (g << 8) | r;
}
 
static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel8(r, g, b);
col |= col << 8;
col |= col << 16;
return col;
}
 
static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel15(r, g, b);
col |= col << 16;
return col;
}
 
static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g,
unsigned int b)
{
unsigned int col;
col = rgb_to_pixel15bgr(r, g, b);
col |= col << 16;
return col;
}
 
static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel16(r, g, b);
col |= col << 16;
return col;
}
 
static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g,
unsigned int b)
{
unsigned int col;
col = rgb_to_pixel16bgr(r, g, b);
col |= col << 16;
return col;
}
 
static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel32(r, g, b);
return col;
}
 
static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
col = rgb_to_pixel32bgr(r, g, b);
return col;
}
 
static int ds_get_linesize(DisplayState *ds)
{
return ds->surface->linesize;
}
 
static uint8_t* ds_get_data(DisplayState *ds)
{
return ds->surface->data;
}
 
static int ds_get_width(DisplayState *ds)
{
return ds->surface->width;
}
 
static int ds_get_height(DisplayState *ds)
{
return ds->surface->height;
}
 
static int ds_get_bits_per_pixel(DisplayState *ds)
{
return ds->surface->pf.bits_per_pixel;
}
 
static int ds_get_bytes_per_pixel(DisplayState *ds)
{
return ds->surface->pf.bytes_per_pixel;
}
 
static void dpy_update(DisplayState *s, int x, int y, int w, int h)
{
struct DisplayChangeListener *dcl = s->listeners;
while (dcl != NULL) {
dcl->dpy_update(s, x, y, w, h);
dcl = dcl->next;
}
}
 
static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {
rgb_to_pixel8_dup,
rgb_to_pixel15_dup,
rgb_to_pixel16_dup,
rgb_to_pixel32_dup,
rgb_to_pixel32bgr_dup,
rgb_to_pixel15bgr_dup,
rgb_to_pixel16bgr_dup,
};
 
/***************************************
*
* prototypes.
@@ -415,8 +578,6 @@
#define ROP_OP(d, s) d = (~(s)) & (~(d))
#include "cirrus_vga_rop.h"
 
#include "cirrus_func.h"
 
static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
cirrus_bitblt_rop_fwd_0,
cirrus_bitblt_rop_fwd_src_and_dst,
@@ -1246,26 +1407,27 @@
limit = s->real_vram_size - offset;
 
if (((s->gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
if (limit > 0x8000) {
offset += 0x8000;
limit -= 0x8000;
} else {
limit = 0;
}
if (limit > 0x8000) {
offset += 0x8000;
limit -= 0x8000;
} else {
limit = 0;
}
}
 
if (limit > 0) {
/* Thinking about changing bank base? First, drop the dirty bitmap information
* on the current location, otherwise we lose this pointer forever */
if (s->lfb_vram_mapped) {
target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
target_phys_addr_t base_addr = isa_mem_base + 0xF80000 + bank_index * 0x8000;
cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
TRACEOUT(("UNSUPPORT1"));
}
s->cirrus_bank_base[bank_index] = offset;
s->cirrus_bank_limit[bank_index] = limit;
s->cirrus_bank_base[bank_index] = offset;
s->cirrus_bank_limit[bank_index] = limit;
} else {
s->cirrus_bank_base[bank_index] = 0;
s->cirrus_bank_limit[bank_index] = 0;
s->cirrus_bank_base[bank_index] = 0;
s->cirrus_bank_limit[bank_index] = 0;
}
}
 
@@ -2030,45 +2192,49 @@
*
***************************************/
 
#define ADDR_SH1 0x000
 
uint32_t_ cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
{
CirrusVGAState *s = opaque;
unsigned bank_index;
unsigned bank_offset;
uint32_t_ val;
 
addr += ADDR_SH1;
 
if ((s->sr[0x07] & 0x01) == 0) {
return vga_mem_readb(s, addr);
}
 
addr &= 0x1ffff;
 
if (addr < 0x10000) {
/* XXX handle bitblt */
/* video memory */
bank_index = addr >> 15;
bank_offset = addr & 0x7fff;
if (bank_offset < s->cirrus_bank_limit[bank_index]) {
bank_offset += s->cirrus_bank_base[bank_index];
if ((s->gr[0x0B] & 0x14) == 0x14) {
bank_offset <<= 4;
} else if (s->gr[0x0B] & 0x02) {
bank_offset <<= 3;
}
bank_offset &= s->cirrus_addr_mask;
val = *(s->vram_ptr + bank_offset);
} else
val = 0xff;
} else if (addr >= 0x18000 && addr < 0x18100) {
/* memory-mapped I/O */
val = 0xff;
if ((s->sr[0x17] & 0x44) == 0x04) {
val = cirrus_mmio_blt_read(s, addr & 0xff);
}
} else {
val = 0xff;
/* XXX handle bitblt */
/* video memory */
bank_index = addr >> 15;
bank_offset = addr & 0x7fff;
if (bank_offset < s->cirrus_bank_limit[bank_index]) {
bank_offset += s->cirrus_bank_base[bank_index];
if ((s->gr[0x0B] & 0x14) == 0x14) {
bank_offset <<= 4;
} else if (s->gr[0x0B] & 0x02) {
bank_offset <<= 3;
}
bank_offset &= s->cirrus_addr_mask;
val = *(s->vram_ptr + bank_offset);
} else
val = 0xff;
} else if (addr >= 0x18000 && addr < 0x18100) {
/* memory-mapped I/O */
val = 0xff;
if ((s->sr[0x17] & 0x44) == 0x04) {
val = cirrus_mmio_blt_read(s, addr & 0xff);
}
} else {
val = 0xff;
#ifdef DEBUG_CIRRUS
printf("cirrus: mem_readb %06x\n", addr);
printf("cirrus: mem_readb %06x\n", addr);
#endif
}
return val;
@@ -2111,56 +2277,58 @@
unsigned bank_index;
unsigned bank_offset;
unsigned mode;
addr += ADDR_SH1;
 
if ((s->sr[0x07] & 0x01) == 0) {
vga_mem_writeb(s, addr, mem_value);
return;
}
 
addr &= 0x1ffff;
 
if (addr < 0x10000) {
if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
/* bitblt */
*s->cirrus_srcptr++ = (uint8_t) mem_value;
if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
cirrus_bitblt_cputovideo_next(s);
}
} else {
/* video memory */
bank_index = addr >> 15;
bank_offset = addr & 0x7fff;
if (bank_offset < s->cirrus_bank_limit[bank_index]) {
bank_offset += s->cirrus_bank_base[bank_index];
if ((s->gr[0x0B] & 0x14) == 0x14) {
bank_offset <<= 4;
} else if (s->gr[0x0B] & 0x02) {
bank_offset <<= 3;
}
bank_offset &= s->cirrus_addr_mask;
mode = s->gr[0x05] & 0x7;
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
*(s->vram_ptr + bank_offset) = mem_value;
cpu_physical_memory_set_dirty(s->vram_offset +
bank_offset);
if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
/* bitblt */
*s->cirrus_srcptr++ = (uint8_t) mem_value;
if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
cirrus_bitblt_cputovideo_next(s);
}
} else {
if ((s->gr[0x0B] & 0x14) != 0x14) {
cirrus_mem_writeb_mode4and5_8bpp(s, mode,
bank_offset,
mem_value);
} else {
cirrus_mem_writeb_mode4and5_16bpp(s, mode,
bank_offset,
mem_value);
}
/* video memory */
bank_index = addr >> 15;
bank_offset = addr & 0x7fff;
if (bank_offset < s->cirrus_bank_limit[bank_index]) {
bank_offset += s->cirrus_bank_base[bank_index];
if ((s->gr[0x0B] & 0x14) == 0x14) {
bank_offset <<= 4;
} else if (s->gr[0x0B] & 0x02) {
bank_offset <<= 3;
}
bank_offset &= s->cirrus_addr_mask;
mode = s->gr[0x05] & 0x7;
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
*(s->vram_ptr + bank_offset) = mem_value;
cpu_physical_memory_set_dirty(s->vram_offset +
bank_offset);
} else {
if ((s->gr[0x0B] & 0x14) != 0x14) {
cirrus_mem_writeb_mode4and5_8bpp(s, mode,
bank_offset,
mem_value);
} else {
cirrus_mem_writeb_mode4and5_16bpp(s, mode,
bank_offset,
mem_value);
}
}
}
}
}
}
} else if (addr >= 0x18000 && addr < 0x18100) {
/* memory-mapped I/O */
if ((s->sr[0x17] & 0x44) == 0x04) {
cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
}
/* memory-mapped I/O */
if ((s->sr[0x17] & 0x44) == 0x04) {
cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
}
} else {
#ifdef DEBUG_CIRRUS
printf("cirrus: mem_writeb %06x value %02x\n", addr, mem_value);
@@ -2301,6 +2469,20 @@
}
}
 
static int get_depth_index(DisplayState *s)
{
switch(ds_get_bits_per_pixel(s)) {
default:
case 8:
return 0;
case 15:
return 1;
case 16:
return 2;
case 32:
return 3;
}
}
static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y)
{
CirrusVGAState *s = (CirrusVGAState *)s1;
@@ -2350,6 +2532,7 @@
x2 = s->last_scr_width;
w = x2 - x1;
palette = s->cirrus_hidden_palette;
s->rgb_to_pixel = rgb_to_pixel_dup_table[get_depth_index(s->ds)];
color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
c6_to_8(palette[0x0 * 3 + 1]),
c6_to_8(palette[0x0 * 3 + 2]));
@@ -2667,10 +2850,11 @@
return;
 
s->lfb_vram_mapped = 0;
 
cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
//@‚±‚Ìcpu_register_physical_memory‚̏ڍׂª‚³‚Á‚ς蕪‚©‚ç‚È‚¢¥¥¥
cpu_register_physical_memory(isa_mem_base + 0xF80000, 0x8000,
(s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_UNASSIGNED);
cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
cpu_register_physical_memory(isa_mem_base + 0xF88000, 0x8000,
(s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_UNASSIGNED);
if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
&& !((s->sr[0x07] & 0x01) == 0)
@@ -2678,15 +2862,16 @@
&& !(s->gr[0x0B] & 0x02)) {
 
vga_dirty_log_stop((VGAState *)s);
cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
//@‚±‚±‚à
cpu_register_physical_memory(isa_mem_base + 0xF80000, 0x8000,
(s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM);
cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
cpu_register_physical_memory(isa_mem_base + 0xF88000, 0x8000,
(s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_RAM);
 
s->lfb_vram_mapped = 1;
}
else {
cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
cpu_register_physical_memory(isa_mem_base + 0xF80000, 0x20000,
s->vga_io_memory);
}
 
@@ -2699,8 +2884,9 @@
 
if (s->map_addr && s->lfb_addr && s->lfb_end)
s->map_addr = s->map_end = 0;
 
cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
//@‚±‚±‚à
cpu_register_physical_memory(isa_mem_base + 0xF80000, 0x20000,
s->vga_io_memory);
 
vga_dirty_log_start((VGAState *)s);
@@ -2746,6 +2932,7 @@
CirrusVGAState *s = (CirrusVGAState *)opaque;
int val, index;
//@ƒ|[ƒgŒˆ‚ß‘Å‚¿‚È‚Ì‚Å–³—–•ÏŠ·
if(addr==0x904) addr = 0x094;
if(addr==0xCA0) addr = 0x3C0;
if(addr==0xCA1) addr = 0x3C1;
@@ -2815,13 +3002,13 @@
val = s->dac_write_index;
s->cirrus_hidden_dac_lockindex = 0;
break;
case 0x3c9:
case 0x3c9:
if (cirrus_hook_read_palette(s, &val))
break;
val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
if (++s->dac_sub_index == 3) {
s->dac_sub_index = 0;
s->dac_read_index++;
break;
val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
if (++s->dac_sub_index == 3) {
s->dac_sub_index = 0;
s->dac_read_index++;
}
break;
case 0x3ca:
@@ -2879,31 +3066,32 @@
{
CirrusVGAState *s = (CirrusVGAState *)opaque;
int index;
//@ƒ|[ƒgŒˆ‚ß‘Å‚¿‚È‚Ì‚Å–³—–•ÏŠ·
if(addr==0x904) addr = 0x094;
if(addr==0xCA0) addr = 0x3C0;
if(addr==0xCA1) addr = 0x3C1;
if(addr==0xCA2) addr = 0x3C2;
if(addr==0xCA3) addr = 0x3C3;
if(addr==0xCA4) addr = 0x3C4;
if(addr==0xCA5) addr = 0x3C5;
if(addr==0xCA6) addr = 0x3C6;
if(addr==0xCA7) addr = 0x3C7;
if(addr==0xCA8) addr = 0x3C8;
if(addr==0xCA9) addr = 0x3C9;
if(addr==0xCAA) addr = 0x3CA;
if(addr==0xCAB) addr = 0x3CB;
if(addr==0xCAC) addr = 0x3CC;
if(addr==0xCAD) addr = 0x3CD;
if(addr==0xCAE) addr = 0x3CE;
if(addr==0xCAF) addr = 0x3CF;
if(addr==0xBA4) addr = 0x3B4;
if(addr==0xBA5) addr = 0x3B5;
if(addr==0xDA4) addr = 0x3D4;
if(addr==0xDA5) addr = 0x3D5;
if(addr==0xBAA) addr = 0x3BA;
if(addr==0xDAA) addr = 0x3DA;
 
//if(addr==0x904) addr = 0x094;
//if(addr==0xCA0) addr = 0x3C0;
//if(addr==0xCA1) addr = 0x3C1;
//if(addr==0xCA2) addr = 0x3C2;
//if(addr==0xCA3) addr = 0x3C3;
//if(addr==0xCA4) addr = 0x3C4;
//if(addr==0xCA5) addr = 0x3C5;
//if(addr==0xCA6) addr = 0x3C6;
//if(addr==0xCA7) addr = 0x3C7;
//if(addr==0xCA8) addr = 0x3C8;
//if(addr==0xCA9) addr = 0x3C9;
//if(addr==0xCAA) addr = 0x3CA;
//if(addr==0xCAB) addr = 0x3CB;
//if(addr==0xCAC) addr = 0x3CC;
//if(addr==0xCAD) addr = 0x3CD;
//if(addr==0xCAE) addr = 0x3CE;
//if(addr==0xCAF) addr = 0x3CF;
//if(addr==0xBA4) addr = 0x3B4;
//if(addr==0xBA5) addr = 0x3B5;
//if(addr==0xDA4) addr = 0x3D4;
//if(addr==0xDA5) addr = 0x3D5;
//if(addr==0xBAA) addr = 0x3BA;
//if(addr==0xDAA) addr = 0x3DA;
 
/* check port range access depending on color/monochrome mode */
if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
|| (addr >= 0x3d0 && addr <= 0x3df
@@ -2998,6 +3186,7 @@
memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
s->dac_sub_index = 0;
s->dac_write_index++;
cirrusvga_paletteChanged = 1; // ƒpƒŒƒbƒg•Ï‚¦‚Ü‚µ‚½
}
break;
case 0x3ce:
@@ -3065,9 +3254,9 @@
static void __fastcall vga_ioport_write_wrap(UINT addr, REG8 dat)
{
//TRACEOUT((""));
if(addr==0xca5 && dat==0x01){
TRACEOUT((""));
}
//if(addr==0xca5 && dat==0x01){
// TRACEOUT((""));
//}
vga_ioport_write(cirrusvga, addr, dat);
}
 
@@ -3305,11 +3494,383 @@
/* Win2K seems to assume that the pattern buffer is at 0xff
initially ! */
memset(s->vram_ptr, 0xff, s->real_vram_size);
//memset(s->vram_ptr+s->real_vram_size/2, 0xa0, s->real_vram_size/2);
 
s->cirrus_hidden_dac_lockindex = 5;
s->cirrus_hidden_dac_data = 0;
}
 
static void vga_draw_graphic(VGAState *s, int full_update)
{
int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask, depth;
int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
int disp_width, multi_scan, multi_run;
uint8_t *d;
uint32_t_ v, addr1, addr;
vga_draw_line_func *vga_draw_line;
 
//full_update |= update_basic_params(s);
 
//if (!full_update)
// vga_sync_dirty_bitmap(s);
 
s->get_resolution(s, &width, &height);
disp_width = width;
 
shift_control = (s->gr[0x05] >> 5) & 3;
double_scan = (s->cr[0x09] >> 7);
if (shift_control != 1) {
multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
} else {
/* in CGA modes, multi_scan is ignored */
/* XXX: is it correct ? */
multi_scan = double_scan;
}
multi_run = multi_scan;
if (shift_control != s->shift_control ||
double_scan != s->double_scan) {
full_update = 1;
s->shift_control = shift_control;
s->double_scan = double_scan;
}
 
if (shift_control == 0) {
if (s->sr[0x01] & 8) {
disp_width <<= 1;
}
} else if (shift_control == 1) {
if (s->sr[0x01] & 8) {
disp_width <<= 1;
}
}
 
depth = s->get_bpp(s);
if (s->line_offset != s->last_line_offset ||
disp_width != s->last_width ||
height != s->last_height ||
s->last_depth != depth) {
#if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
if (depth == 16 || depth == 32) {
#else
if (depth == 32) {
#endif
// if (is_graphic_console()) {
// qemu_free_displaysurface(s->ds->surface);
// s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
// s->line_offset,
// s->vram_ptr + (s->start_addr * 4));
//#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
// s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
//#endif
// dpy_resize(s->ds);
// } else {
// qemu_console_resize(s->ds, disp_width, height);
// }
} else {
//qemu_console_resize(s->ds, disp_width, height);
}
s->last_scr_width = disp_width;
s->last_scr_height = height;
s->last_width = disp_width;
s->last_height = height;
s->last_line_offset = s->line_offset;
s->last_depth = depth;
full_update = 1;
//} else if (is_graphic_console() && is_buffer_shared(s->ds->surface) &&
// (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
// s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
// dpy_setdata(s->ds);
}
 
//s->rgb_to_pixel = rgb_to_pixel_dup_table[get_depth_index(s->ds)];
 
//if (shift_control == 0) {
// full_update |= update_palette16(s);
// if (s->sr[0x01] & 8) {
// v = VGA_DRAW_LINE4D2;
// } else {
// v = VGA_DRAW_LINE4;
// }
// bits = 4;
//} else if (shift_control == 1) {
// full_update |= update_palette16(s);
// if (s->sr[0x01] & 8) {
// v = VGA_DRAW_LINE2D2;
// } else {
// v = VGA_DRAW_LINE2;
// }
// bits = 4;
//} else {
// switch(s->get_bpp(s)) {
// default:
// case 0:
// full_update |= update_palette256(s);
// v = VGA_DRAW_LINE8D2;
// bits = 4;
// break;
// case 8:
// full_update |= update_palette256(s);
// v = VGA_DRAW_LINE8;
// bits = 8;
// break;
// case 15:
// v = VGA_DRAW_LINE15;
// bits = 16;
// break;
// case 16:
// v = VGA_DRAW_LINE16;
// bits = 16;
// break;
// case 24:
// v = VGA_DRAW_LINE24;
// bits = 24;
// break;
// case 32:
// v = VGA_DRAW_LINE32;
// bits = 32;
// break;
// }
//}
//vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
 
//if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)
// s->cursor_invalidate(s);
 
line_offset = s->line_offset;
#if 0
printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
#endif
//addr1 = (s->start_addr * 4);
//bwidth = (width * bits + 7) / 8;
//y_start = -1;
//page_min = 0x7fffffff;
//page_max = -1;
//d = ds_get_data(s->ds);
//linesize = ds_get_linesize(s->ds);
//y1 = 0;
//for(y = 0; y < height; y++) {
// addr = addr1;
// if (!(s->cr[0x17] & 1)) {
// int shift;
// /* CGA compatibility handling */
// shift = 14 + ((s->cr[0x17] >> 6) & 1);
// addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
// }
// if (!(s->cr[0x17] & 2)) {
// addr = (addr & ~0x8000) | ((y1 & 2) << 14);
// }
// page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
// page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
// update = full_update;// |
// //cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
// //cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
// if ((page1 - page0) > TARGET_PAGE_SIZE) {
// /* if wide line, can use another page */
// //update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
// // VGA_DIRTY_FLAG);
// }
// /* explicit invalidation for the hardware cursor */
// update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
// if (update) {
// if (y_start < 0)
// y_start = y;
// if (page0 < page_min)
// page_min = page0;
// if (page1 > page_max)
// page_max = page1;
// if (1/*!(is_buffer_shared(s->ds->surface))*/) {
// vga_draw_line(s, d, s->vram_ptr + addr, width);
// if (s->cursor_draw_line)
// s->cursor_draw_line(s, d, y);
// }
// } else {
// if (y_start >= 0) {
// /* flush to display */
// dpy_update(s->ds, 0, y_start,
// disp_width, y - y_start);
// y_start = -1;
// }
// }
// if (!multi_run) {
// mask = (s->cr[0x17] & 3) ^ 3;
// if ((y1 & mask) == mask)
// addr1 += line_offset;
// y1++;
// multi_run = multi_scan;
// } else {
// multi_run--;
// }
// /* line compare acts on the displayed lines */
// if (y == s->line_compare)
// addr1 = 0;
// d += linesize;
//}
//if (y_start >= 0) {
// /* flush to display */
// dpy_update(s->ds, 0, y_start,
// disp_width, y - y_start);
//}
/* reset modified pages */
//if (page_max != -1) {
// cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
// VGA_DIRTY_FLAG);
//}
memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
}
 
LOGPALETTE * NewLogPal(const uint8_t *pCirrusPalette , int iSize) {
LOGPALETTE *lpPalette;
int count;
 
lpPalette = (LOGPALETTE*)malloc(sizeof (LOGPALETTE) + iSize * sizeof (PALETTEENTRY));
lpPalette->palVersion = 0x0300;
lpPalette->palNumEntries = iSize;
for (count = 0 ; count < iSize ; count++) {
lpPalette->palPalEntry[count].peRed = c6_to_8(pCirrusPalette[count*3]);
lpPalette->palPalEntry[count].peGreen = c6_to_8(pCirrusPalette[count*3+1]);
lpPalette->palPalEntry[count].peBlue = c6_to_8(pCirrusPalette[count*3+2]);
lpPalette->palPalEntry[count].peFlags = NULL;
}
return lpPalette;
}
//@‰æ–Ê•\Ž¦(‰¼)@–{“–‚ÍQEMU‚̃IƒŠƒWƒiƒ‹‚̃R[ƒh‚ðˆÚA‚·‚ׂ«‚È‚ñ‚¾‚¯‚Ç¥¥¥
void cirrusvga_drawGraphic(){
int i, y, width, height, bpp;
LOGPALETTE * lpPalette;
static HPALETTE hPalette, oldpalette;
HCURSOR hCursor = GetCursor();
HWND hWnd = ga_hWnd;
HDC hdc = ga_hdc;
int r;
int scanW = 0;
int scanpixW = 0;
uint8_t *scanptr;
 
bpp = cirrusvga->get_bpp((VGAState*)cirrusvga);
//bpp = cirrusvga->cirrus_blt_pixelwidth*8;
cirrusvga->get_resolution((VGAState*)cirrusvga, &width, &height);
//@“ä‚Ì•\Ž¦•’²®i2^n‚ɃpƒfƒBƒ“ƒO‚³‚ê‚邱‚Æ‚ª‚ ‚é‚炵‚¢‚¯‚ÇðŒ‚ª•ª‚©‚ç‚È‚¢‚Ì‚Å–³—–j
scanW = width*bpp/8;
if(scanW<=512 ) scanW = 512;
else if(scanW<=1024) scanW = 1024;
else if(scanW<=2048) scanW = 2048;
else if(scanW<=4096) scanW = 4096;
else if(scanW<=8192) scanW = 8192;
scanpixW = width;
if(width==640){
// XXX: ‰½‚à•â³‚µ‚È‚¢
}else{
if(scanpixW<=256 ) scanpixW = 256;
else if(scanpixW<=512) scanpixW = 512;
else if(scanpixW<=1024) scanpixW = 1024;
else if(scanpixW<=2048) scanpixW = 2048;
}
if(width==800 && bpp==8 && ((ga_VRAMWindowAddr>>24)&0xff)==0xf0){
// XXX: Win2k—p‚â‚Á‚‚¯C³
scanW = width*2;
scanpixW = width;
}
if(bpp==16){
uint32_t_* bitfleld = (uint32_t_*)(ga_bmpInfo->bmiColors);
scanW = width*2;
bitfleld[0] = 0x0000F800;
bitfleld[1] = 0x000007E0;
bitfleld[2] = 0x0000001F;
ga_bmpInfo->bmiHeader.biCompression = BI_BITFIELDS;
}else{
ga_bmpInfo->bmiHeader.biCompression = BI_RGB;
}
if(bpp==15){
bpp = 16;
scanW = width*2;
}
 
ga_bmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
if(ga_bmpInfo->bmiHeader.biWidth != width || ga_bmpInfo->bmiHeader.biHeight != height){
// ‰ð‘œ“x‚ª•Ï‚í‚Á‚Ä‚¢‚½‚çƒEƒBƒ“ƒhƒEƒTƒCƒY‚à•Ï‚¦‚é
RECT rect = { 0, 0, width, height };
//ga_bmpInfo->bmiHeader.biWidth = scanW;//width;
//ga_bmpInfo->bmiHeader.biHeight = -height;
AdjustWindowRectEx( &rect, WS_OVERLAPPEDWINDOW, FALSE, 0 );
SetWindowPos( hWnd, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE|SWP_NOZORDER );
cirrusvga_paletteChanged = 1;
}
if(ga_bmpInfo->bmiHeader.biBitCount!=8 && bpp==8){
cirrusvga_paletteChanged = 1;
}
ga_bmpInfo->bmiHeader.biWidth = width; // ‰¼ƒZƒbƒg
ga_bmpInfo->bmiHeader.biHeight = 1; // ‰¼ƒZƒbƒg
ga_bmpInfo->bmiHeader.biPlanes = 1;
ga_bmpInfo->bmiHeader.biBitCount = bpp;
vga_draw_graphic((VGAState *)cirrusvga, 1);
if(bpp<=8){
if(cirrusvga_paletteChanged){
//for(i=0;i<256;i++){
// //ga_bmpInfo->bmiColors[i].rgbReserved = cirrusvga->palette[i*3];
// ga_bmpInfo->bmiColors[i].rgbRed = c6_to_8(cirrusvga->palette[i*3]);
// ga_bmpInfo->bmiColors[i].rgbGreen = c6_to_8(cirrusvga->palette[i*3+1]);
// ga_bmpInfo->bmiColors[i].rgbBlue = c6_to_8(cirrusvga->palette[i*3+2]);
//}
//@256ƒpƒŒƒbƒg‚ªŠXF‰»‚¯‚·‚é‚͉̂½ŒÌ‚¾‚낤
lpPalette = NewLogPal(cirrusvga->palette , 1<<bpp);
hPalette = CreatePalette(lpPalette);
free(lpPalette);
oldpalette = SelectPalette(hdc , hPalette , FALSE);
cirrusvga_paletteChanged = 0;
}
RealizePalette(hdc);
// 256ƒ‚[ƒh‚È‚ç‘f’¼‚É“]‘—‚µ‚Ä—Ç‚µ
ga_bmpInfo->bmiHeader.biWidth = scanpixW;
ga_bmpInfo->bmiHeader.biHeight = -height;
scanptr = cirrusvga->vram_ptr;
SetDIBitsToDevice(
hdc , 0 , 0 ,
ga_bmpInfo->bmiHeader.biWidth , -ga_bmpInfo->bmiHeader.biHeight ,
0 , 0 , 0 , -ga_bmpInfo->bmiHeader.biHeight ,
cirrusvga->vram_ptr , ga_bmpInfo , DIB_PAL_COLORS
);
}else{
if(scanpixW*bpp/8==scanW){
ga_bmpInfo->bmiHeader.biWidth = scanpixW;
ga_bmpInfo->bmiHeader.biHeight = -height;
scanptr = cirrusvga->vram_ptr;
SetDIBitsToDevice(
hdc , 0 , 0 ,
ga_bmpInfo->bmiHeader.biWidth , -ga_bmpInfo->bmiHeader.biHeight ,
0 , 0 , 0 , -ga_bmpInfo->bmiHeader.biHeight ,
cirrusvga->vram_ptr , ga_bmpInfo , DIB_RGB_COLORS
);
}else{
// ƒYƒŒ‚ª‚ ‚é‚È‚ç1ƒ‰ƒCƒ“‚¸‚“]‘—
scanptr = cirrusvga->vram_ptr;
for(i=0;i<height;i++){
ga_bmpInfo->bmiHeader.biWidth = width;
ga_bmpInfo->bmiHeader.biHeight = 1;
r = SetDIBitsToDevice(
hdc , 0 , i ,
width , 1 ,
0 , 0 , 0 , 1 ,
scanptr , ga_bmpInfo , DIB_RGB_COLORS
);
scanptr += scanW;
}
}
}
ga_bmpInfo->bmiHeader.biWidth = width; // ‘O‰ñ‚̉𑜓x‚ð•Û‘¶
ga_bmpInfo->bmiHeader.biHeight = height; // ‘O‰ñ‚̉𑜓x‚ð•Û‘¶
if ((cirrusvga->sr[0x12] & CIRRUS_CURSOR_SHOW)){
DrawIcon(hdc, cirrusvga->hw_cursor_x, cirrusvga->hw_cursor_y, hCursor);
}
// for(y = 0; y < height; y++) {
// if (cirrusvga->cursor_draw_line){
// cirrusvga->cursor_draw_line((VGAState*)cirrusvga, cirrusvga->vram_ptr+640*4*y, y);
// }
//}
}
 
static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
{
int i;
@@ -3406,10 +3967,10 @@
CirrusVGAState *s;
 
s = (CirrusVGAState*)qemu_mallocz(sizeof(CirrusVGAState));
 
vga_common_init((VGAState *)s,
vga_ram_base, vga_ram_offset, vga_ram_size);
cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
cirrus_init_common(s, CIRRUS_ID_CLGD5440, 0);
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s);
/* XXX ISA-LFB support */
@@ -3420,8 +3981,64 @@
* PC-9821 support
*
***************************************/
REG8 cirrusvga_regindex = 0;
REG8 cirrusvga_relay = 0;
static void IOOUTCALL cirrusvga_ofa2(UINT port, REG8 dat) {
TRACEOUT(("CIRRUS VGA: set register index %02X", dat));
cirrusvga_regindexA2 = dat;
(void)port;
(void)dat;
}
static REG8 IOINPCALL cirrusvga_ifa2(UINT port) {
TRACEOUT(("CIRRUS VGA: get register index %02X", cirrusvga_regindex));
return cirrusvga_regindexA2;
}
static void IOOUTCALL cirrusvga_ofa3(UINT port, REG8 dat) {
TRACEOUT(("CIRRUS VGA: out %04X d=%.2X", port, dat));
switch(cirrusvga_regindexA2){
case 0x00:
break;
case 0x01:
break;
case 0x02:
ga_VRAMWindowAddr = (dat<<24);
break;
case 0x03:
if((!!ga_relay) != (!!(dat&0x2))){
ga_relay = (dat&0x2 ? 0x3 : 0x0);
if(dat){
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ShowWindow(ga_hWnd, SW_SHOWNOACTIVATE);
SetWindowPos(ga_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
}else{
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ShowWindow(ga_hWnd, SW_HIDE);
}
}
cirrusvga_mmioenable = (dat&0x1);
break;
}
(void)port;
(void)dat;
}
static REG8 IOINPCALL cirrusvga_ifa3(UINT port) {
REG8 ret = 0xff;
TRACEOUT(("CIRRUS VGA: inp %04X", port));
switch(cirrusvga_regindexA2){
case 0x00:
ret = 0x5B;
break;
case 0x01:
ret = 0x80;
break;
case 0x02:
ret = (ga_VRAMWindowAddr>>24)&0xff;
break;
case 0x03:
ret = (ga_relay ? 0x2 : 0x0) | cirrusvga_mmioenable;
break;
}
return ret;
}
 
static void IOOUTCALL cirrusvga_ofaa(UINT port, REG8 dat) {
TRACEOUT(("CIRRUS VGA: set register index %02X", dat));
cirrusvga_regindex = dat;
@@ -3433,12 +4050,35 @@
return cirrusvga_regindex;
}
static void IOOUTCALL cirrusvga_ofab(UINT port, REG8 dat) {
TRACEOUT(("CIRRUS VGA: out %04X d=%02X", port, dat));
TRACEOUT(("CIRRUS VGA: out %04X d=%.2X", port, dat));
switch(cirrusvga_regindex){
case 0x00:
break;
case 0x01:
break;
case 0x02:
ga_VRAMWindowAddr = (dat<<24);
break;
case 0x03:
if((!!ga_relay) != (!!(dat&0x2))){
ga_relay = (dat&0x2 ? 0x3 : 0x0);
if(dat){
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ShowWindow(ga_hWnd, SW_SHOWNOACTIVATE);
SetWindowPos(ga_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
}else{
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ShowWindow(ga_hWnd, SW_HIDE);
}
}
cirrusvga_mmioenable = (dat&0x1);
break;
}
(void)port;
(void)dat;
}
static REG8 IOINPCALL cirrusvga_ifab(UINT port) {
REG8 ret = 0;
REG8 ret = 0xff;
TRACEOUT(("CIRRUS VGA: inp %04X", port));
switch(cirrusvga_regindex){
case 0x00:
@@ -3447,32 +4087,60 @@
case 0x01:
ret = 0x80;
break;
case 0x02:
ret = (ga_VRAMWindowAddr>>24)&0xff;
break;
case 0x03:
ret = (ga_relay ? 0x2 : 0x0) | cirrusvga_mmioenable;
break;
}
return ret;
}
static void IOOUTCALL cirrusvga_ofac(UINT port, REG8 dat) {
TRACEOUT(("CIRRUS VGA: set relay %04X d=%02X", port, dat));
cirrusvga_relay = dat;
dat = dat & ~0xfc;
if(ga_relay != dat){
ga_relay = dat;
if(dat){
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ShowWindow(ga_hWnd, SW_SHOWNOACTIVATE);
SetWindowPos(ga_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
}else{
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ShowWindow(ga_hWnd, SW_HIDE);
}
}
(void)port;
(void)dat;
}
static REG8 IOINPCALL cirrusvga_ifac(UINT port) {
TRACEOUT(("CIRRUS VGA: get relay %04X", port));
return cirrusvga_relay;
return 0xfc | ga_relay;
}
 
static void IOOUTCALL cirrusvga_off82(UINT port, REG8 dat) {
TRACEOUT(("CIRRUS VGA: out %04X d=%02X", port, dat));
cirrusvga_relay = dat;
if(ga_relay != dat){
ga_relay = dat;
if(dat){
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ShowWindow(ga_hWnd, SW_SHOWNOACTIVATE);
SetWindowPos(ga_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
}else{
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ShowWindow(ga_hWnd, SW_HIDE);
}
}
(void)port;
(void)dat;
}
static REG8 IOINPCALL cirrusvga_iff82(UINT port) {
TRACEOUT(("CIRRUS VGA: inp %04X", port));
return cirrusvga_relay;
return ga_relay;
}
 
 
 
static void vga_dumb_update_retrace_info(VGAState *s)
{
(void) s;
@@ -3510,6 +4178,12 @@
s->bustype = CIRRUS_BUSTYPE_ISA;
}
iocore_attachout(0xfa2, cirrusvga_ofa2);
iocore_attachinp(0xfa2, cirrusvga_ifa2);
iocore_attachout(0xfa3, cirrusvga_ofa3);
iocore_attachinp(0xfa3, cirrusvga_ifa3);
iocore_attachout(0xfaa, cirrusvga_ofaa);
iocore_attachinp(0xfaa, cirrusvga_ifaa);
@@ -3530,6 +4204,7 @@
//iocore_attachout(0x904, vga_ioport_write_wrap);
//iocore_attachinp(0x904, vga_ioport_read_wrap);
 
//@‚±‚̕ӂ̃}ƒbƒsƒ“ƒO–{“–‚É‚ ‚Á‚Ä‚éH
iocore_attachout(0xba4, vga_ioport_write_wrap);
iocore_attachinp(0xba4, vga_ioport_read_wrap);
iocore_attachout(0xba5, vga_ioport_write_wrap);
@@ -3559,24 +4234,30 @@
//register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
//register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
//register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
#define ADDR_SH2 0x0
// ‚±‚ê‚ç‚̃ƒ‚ƒŠ‚Í‚Ç‚±‚Ƀ}ƒbƒsƒ“ƒO‚·‚ê‚Ηǂ¢‚Ì‚©¥¥¥
 
s->vga_io_memory = 0xF0000000;//cpu_register_io_memory(0, cirrus_vga_mem_read, cirrus_vga_mem_write, s);
// s->vga_io_memory = 0x0F000000;//cpu_register_io_memory(0, cirrus_vga_mem_read, cirrus_vga_mem_write, s);
//cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
// s->vga_io_memory);
//qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
 
/* I/O handler for LFB */
s->cirrus_linear_io_addr = 0xF0011000;//cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write, s);
//s->cirrus_linear_io_addr = 0x0F200000;//cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write, s);
s->cirrus_linear_write = cirrus_vga_mem_write;//cpu_get_io_memory_write(s->cirrus_linear_io_addr);
 
/* I/O handler for LFB */
s->cirrus_linear_bitblt_io_addr = 0xF0012000;//cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write, s);
//s->cirrus_linear_bitblt_io_addr = 0x0F100000;//cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write, s);
 
/* I/O handler for memory-mapped I/O */
//s->cirrus_mmio_io_addr = cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s);
s->cirrus_mmio_io_addr = 0xF0013000;
//s->cirrus_mmio_io_addr = 0xF80000;
 
s->real_vram_size = (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
s->vram_ptr = (uint8_t*)malloc(s->real_vram_size);
s->vram_offset = 0;
s->vram_size = s->real_vram_size;
 
/* XXX: s->vram_size must be a power of two */
s->cirrus_addr_mask = s->real_vram_size - 1;
@@ -3593,30 +4274,47 @@
 
qemu_register_reset(cirrus_reset, s);
cirrus_reset(s);
ShowWindow(ga_hWnd, SW_HIDE);
if(ga_relay){
soundmng_pcmplay(SOUND_RELAY1, FALSE);
ga_relay = 0;
}
cirrusvga_mmioenable = 0;
cirrusvga_paletteChanged = 1;
//register_savevm("cirrus_vga", 0, 2, cirrus_vga_save, cirrus_vga_load, s);// XXX:
}
 
 
void pc98_cirrus_vga_init()
{
UINT i;
WORD* PalIndexes;
ga_bmpInfo = (BITMAPINFO*)calloc(1, sizeof(BITMAPINFO)+sizeof(WORD)*256);
PalIndexes = (WORD*)((char*)ga_bmpInfo + sizeof(BITMAPINFOHEADER));
for (i = 0; i < 256; ++i) PalIndexes[i] = i;
//ga_hpal =
//vga_common_init((VGAState *)s, vga_ram_base, vga_ram_offset, vga_ram_size);
}
void pc98_cirrus_vga_bind()
{
CirrusVGAState *s;
 
if(!np2cfg.usegd5430){
TRACEOUT(("CL-GD5430: PC-9821 Xe10 Window Accelerator Disabled"));
return;
}
 
cirrusvga_opaque = cirrusvga = s = (CirrusVGAState*)calloc(1, sizeof(CirrusVGAState));
s->vram_ptr = (uint8_t*)malloc((9 * 1024 * 1024));
s->vram_offset = 0;
s->vram_size = (9 * 1024 * 1024);
pc98_cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
s->ds = graphic_console_init(s->update, s->invalidate, s->screen_dump, s->text_update, s);
 
//g_memptr = s->vram_ptr;
TRACEOUT(("CL-GD5430: PC-9821 Xe10 Window Accelerator Enabled"));
}
void pc98_cirrus_vga_shutdown()
{
 
//DeleteObject(ga_hpal);
free(ga_bmpInfo);
}
 
 
New file
/np21/video/video.c
@@ -0,0 +1,165 @@
 
#include "compiler.h"
 
#if defined(SUPPORT_CL_GD5430)
 
#include "np2.h"
#include "resource.h"
#include "dosio.h"
#include "cpucore.h"
#include "pccore.h"
#include "iocore.h"
#include "video.h"
 
BITMAPINFO bmpInfo = {0};
DisplayState ds = {0};
HDC g_hDC = NULL;
HWND g_hWndVGA = NULL;
UINT8 *g_memptr = NULL;
TCHAR gName[100] = _T("NP2 Window Accelerator");
 
REG8 ga_relay = 0;
static HANDLE ga_hThread = NULL;
static int ga_exitThread = 0;
static int ga_threadmode = 1;
LRESULT CALLBACK WndProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam){
if(mes == WM_DESTROY) {PostQuitMessage(0); return 0;}
return DefWindowProc(hWnd, mes, wParam, lParam);
}
 
void np2vga_ds_dpy_update(struct DisplayState *s, int x, int y, int w, int h)
{
}
void np2vga_ds_dpy_resize(struct DisplayState *s)
{
}
void np2vga_ds_dpy_setdata(struct DisplayState *s)
{
}
void np2vga_ds_dpy_refresh(struct DisplayState *s)
{
}
void np2vga_ds_dpy_copy(struct DisplayState *s, int src_x, int src_y,
int dst_x, int dst_y, int w, int h)
{
}
void np2vga_ds_dpy_fill(struct DisplayState *s, int x, int y,
int w, int h, uint32_t_ c)
{
}
void np2vga_ds_dpy_text_cursor(struct DisplayState *s, int x, int y)
{
}
 
 
DisplaySurface np2vga_ds_surface = {0};
DisplayChangeListener np2vga_ds_listeners = {0, 0, np2vga_ds_dpy_update, np2vga_ds_dpy_resize,
np2vga_ds_dpy_setdata, np2vga_ds_dpy_refresh,
np2vga_ds_dpy_copy, np2vga_ds_dpy_fill,
np2vga_ds_dpy_text_cursor, NULL};
 
void np2vga_ds_mouse_set(int x, int y, int on){
 
}
void np2vga_ds_cursor_define(int width, int height, int bpp, int hot_x, int hot_y,
uint8_t *image, uint8_t *mask){
 
}
 
// “¯Šú•`‰æiga_threadmode‚ª‹Uj
void np2vga_drawframe()
{
if(!ga_threadmode && g_memptr){
cirrusvga_drawGraphic();
}
}
// ”ñ“¯Šú•`‰æiga_threadmode‚ª^j
DWORD WINAPI ga_ThreadFunc(LPVOID vdParam) {
DWORD time = GetTickCount();
int timeleft = 0;
while (!ga_exitThread && ga_threadmode) {
if(g_memptr){
if(ga_relay) cirrusvga_drawGraphic();
}
while(GetTickCount() >= time && GetTickCount()-time < 16){
timeleft = 16 - (GetTickCount()-time);
if(timeleft>0) Sleep(timeleft);
}
time = GetTickCount();
}
ga_threadmode = 0;
return 0;
}
 
void np2vga_init(HINSTANCE hInstance)
{
WNDPROC wndproc = NULL;
WNDCLASSEX wcex = {0};
DWORD dwID;
//wndproc = (WNDPROC)GetWindowLongPtr(g_hWndMain, GWLP_WNDPROC);
if(!wndproc) wndproc = WndProc;
 
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = wndproc;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wcex.lpszClassName = (TCHAR*)gName;
if(!RegisterClassEx(&wcex)) return;
if(!(g_hWndVGA = CreateWindow(gName, gName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL))) return;
 
//ShowWindow(g_hWndVGA, SW_SHOWDEFAULT);
//SetWindowPos(g_hWndVGA, NULL, 0, 0, 640, 480, SWP_NOMOVE);
ds.surface = &np2vga_ds_surface;
ds.listeners = &np2vga_ds_listeners;
ds.mouse_set = np2vga_ds_mouse_set;
ds.cursor_define = np2vga_ds_cursor_define;
ds.next = NULL;
 
g_hDC = GetDC(g_hWndVGA);
 
cirrusvga_setGAWindow(g_hWndVGA, g_hDC);
ga_threadmode = 1;
ga_hThread = CreateThread(NULL , 0 , ga_ThreadFunc , NULL , 0 , &dwID);
}
void np2vga_shutdown()
{
bmpInfo.bmiHeader.biWidth = bmpInfo.bmiHeader.biHeight = 0;
ga_exitThread = 1;
WaitForSingleObject(ga_hThread, 5000);
ga_hThread = NULL;
ReleaseDC(g_hWndVGA, g_hDC);
DestroyWindow(g_hWndVGA);
}
 
DisplayState *graphic_console_init(vga_hw_update_ptr update,
vga_hw_invalidate_ptr invalidate,
vga_hw_screen_dump_ptr screen_dump,
vga_hw_text_update_ptr text_update,
void *opaque)
{
ds.opaque = opaque;
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = 1024;
bmpInfo.bmiHeader.biHeight = 512;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
g_memptr = mem;
np2vga_ds_surface.width = 640;
np2vga_ds_surface.height = 480;
np2vga_ds_surface.pf.bits_per_pixel = 32;
np2vga_ds_surface.pf.bytes_per_pixel = 4;
 
return &ds;
}
 
 
#endif /* SUPPORT_CL_GD5430 */
/np21/video/cirrus_vga_rop.h
@@ -1,4 +1,4 @@
#if defined(SUPPORT_CL_GD5430)
 
/*
* QEMU Cirrus CLGD 54xx VGA Emulator.
*
@@ -23,6 +23,8 @@
* THE SOFTWARE.
*/
 
#if defined(SUPPORT_CL_GD5430)
 
static void
glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
uint8_t *dst,const uint8_t *src,
/np21/video/cirrus_vga_rop2.h
@@ -1,4 +1,3 @@
#if defined(SUPPORT_CL_GD5430)
 
/*
* QEMU Cirrus CLGD 54xx VGA Emulator.
@@ -24,6 +23,8 @@
* THE SOFTWARE.
*/
 
#if defined(SUPPORT_CL_GD5430)
 
#if DEPTH == 8
#define PUTPIXEL() ROP_OP(d[0], col)
#elif DEPTH == 16
New file
/np21/video/video.h
@@ -0,0 +1,135 @@
 
#pragma once
 
#ifdef __cplusplus
extern "C" {
#endif
 
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t_;
typedef signed int int32_t;
typedef unsigned int uint32_t_;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
 
typedef uint32_t_ ram_addr_t;
typedef uint32_t_ target_phys_addr_t;
 
typedef unsigned long console_ch_t;
 
typedef void (*vga_hw_update_ptr)(void *);
typedef void (*vga_hw_invalidate_ptr)(void *);
typedef void (*vga_hw_screen_dump_ptr)(void *, const char *);
typedef void (*vga_hw_text_update_ptr)(void *, console_ch_t *);
 
typedef struct PixelFormat {
uint8_t bits_per_pixel;
uint8_t bytes_per_pixel;
uint8_t depth; /* color depth in bits */
uint32_t_ rmask, gmask, bmask, amask;
uint8_t rshift, gshift, bshift, ashift;
uint8_t rmax, gmax, bmax, amax;
uint8_t rbits, gbits, bbits, abits;
} PixelFormat;
 
typedef struct DisplaySurface {
uint8_t flags;
int width;
int height;
int linesize; /* bytes per line */
uint8_t *data;
 
struct PixelFormat pf;
} DisplaySurface;
 
typedef struct DisplayChangeListener {
int idle;
uint64_t gui_timer_interval;
 
void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
void (*dpy_resize)(struct DisplayState *s);
void (*dpy_setdata)(struct DisplayState *s);
void (*dpy_refresh)(struct DisplayState *s);
void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
int dst_x, int dst_y, int w, int h);
void (*dpy_fill)(struct DisplayState *s, int x, int y,
int w, int h, uint32_t_ c);
void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 
struct DisplayChangeListener *next;
} DisplayChangeListener;
 
struct DisplayState {
struct DisplaySurface *surface;
void *opaque;
//struct QEMUTimer *gui_timer;
 
struct DisplayChangeListener* listeners;
 
void (*mouse_set)(int x, int y, int on);
void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
uint8_t *image, uint8_t *mask);
 
struct DisplayState *next;
};
typedef struct DisplayState DisplayState;
 
uint32_t_ cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr);
uint32_t_ cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr);
uint32_t_ cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr);
void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t_ val);
void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t_ val);
void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t_ val);
 
uint32_t_ cirrus_linear_readb(void *opaque, target_phys_addr_t addr);
uint32_t_ cirrus_linear_readw(void *opaque, target_phys_addr_t addr);
uint32_t_ cirrus_linear_readl(void *opaque, target_phys_addr_t addr);
void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, uint32_t_ val);
void cirrus_linear_writew(void *opaque, target_phys_addr_t addr, uint32_t_ val);
void cirrus_linear_writel(void *opaque, target_phys_addr_t addr, uint32_t_ val);
 
uint32_t_ cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr);
uint32_t_ cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr);
uint32_t_ cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr);
void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr, uint32_t_ val);
void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr, uint32_t_ val);
void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr, uint32_t_ val);
 
uint32_t_ cirrus_mmio_readb(void *opaque, target_phys_addr_t addr);
uint32_t_ cirrus_mmio_readw(void *opaque, target_phys_addr_t addr);
uint32_t_ cirrus_mmio_readl(void *opaque, target_phys_addr_t addr);
void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t_ val);
void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t_ val);
void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t_ val);
 
DisplayState *graphic_console_init(vga_hw_update_ptr update,
vga_hw_invalidate_ptr invalidate,
vga_hw_screen_dump_ptr screen_dump,
vga_hw_text_update_ptr text_update,
void *opaque);
 
extern REG8 ga_relay;
extern void *cirrusvga_opaque;
//extern UINT8 *g_memptr;
extern UINT32 ga_VRAMWindowAddr;
 
 
// –³—–ŠO‚©‚çŒÄ‚ׂé‚悤‚É
void pc98_cirrus_vga_init();
void pc98_cirrus_vga_bind();
void pc98_cirrus_vga_shutdown();
 
void cirrusvga_setGAWindow(HWND hWnd, HDC hdc);
 
void np2vga_init(HINSTANCE g_hInstance);
void np2vga_drawframe();
void np2vga_shutdown();
 
void cirrusvga_drawGraphic();
 
#ifdef __cplusplus
}
#endif
 
/np21/video/vga_int.h
@@ -183,6 +183,8 @@
VGA_STATE_COMMON
} VGAState;
 
typedef void vga_draw_line_func(VGAState *s1, uint8_t *d, const uint8_t *s, int width);
 
static int c6_to_8(int v)
{
int b;
@@ -198,16 +200,311 @@
void vga_dirty_log_start(VGAState *s){}
void vga_dirty_log_stop(VGAState *s){}
 
#define cbswap_32(__x) \
((uint32_t_)( \
(((uint32_t_)(__x) & (uint32_t_)0x000000ffUL) << 24) | \
(((uint32_t_)(__x) & (uint32_t_)0x0000ff00UL) << 8) | \
(((uint32_t_)(__x) & (uint32_t_)0x00ff0000UL) >> 8) | \
(((uint32_t_)(__x) & (uint32_t_)0xff000000UL) >> 24) ))
 
#ifdef WORDS_BIGENDIAN
#define PAT(x) x
#else
#define PAT(x) cbswap_32(x)
#endif
 
#ifdef WORDS_BIGENDIAN
#define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
#else
#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
#endif
 
static const uint32_t_ mask16[16] = {
PAT(0x00000000),
PAT(0x000000ff),
PAT(0x0000ff00),
PAT(0x0000ffff),
PAT(0x00ff0000),
PAT(0x00ff00ff),
PAT(0x00ffff00),
PAT(0x00ffffff),
PAT(0xff000000),
PAT(0xff0000ff),
PAT(0xff00ff00),
PAT(0xff00ffff),
PAT(0xffff0000),
PAT(0xffff00ff),
PAT(0xffffff00),
PAT(0xffffffff),
};
 
uint32_t_ vga_mem_readb(void *opaque, target_phys_addr_t addr){
return 0;
VGAState *s = (VGAState *)opaque;
int memory_map_mode, plane;
uint32_t_ ret;
 
/* convert to VGA memory offset */
memory_map_mode = (s->gr[6] >> 2) & 3;
addr &= 0x1ffff;
switch(memory_map_mode) {
case 0:
break;
case 1:
if (addr >= 0x10000)
return 0xff;
addr += s->bank_offset;
break;
case 2:
addr -= 0x10000;
if (addr >= 0x8000)
return 0xff;
break;
default:
case 3:
addr -= 0x18000;
if (addr >= 0x8000)
return 0xff;
break;
}
 
if (s->sr[4] & 0x08) {
/* chain 4 mode : simplest access */
ret = s->vram_ptr[addr];
} else if (s->gr[5] & 0x10) {
/* odd/even mode (aka text mode mapping) */
plane = (s->gr[4] & 2) | (addr & 1);
ret = s->vram_ptr[((addr & ~1) << 1) | plane];
} else {
/* standard VGA latched access */
s->latch = ((uint32_t_ *)s->vram_ptr)[addr];
 
if (!(s->gr[5] & 0x08)) {
/* read mode 0 */
plane = s->gr[4];
ret = GET_PLANE(s->latch, plane);
} else {
/* read mode 1 */
ret = (s->latch ^ mask16[s->gr[2]]) & mask16[s->gr[7]];
ret |= ret >> 16;
ret |= ret >> 8;
ret = (~ret) & 0xff;
}
}
return ret;
}
void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t_ val){
VGAState *s = (VGAState *)opaque;
int memory_map_mode, plane, write_mode, b, func_select, mask;
uint32_t_ write_mask, bit_mask, set_mask;
 
#ifdef DEBUG_VGA_MEM
printf("vga: [0x%x] = 0x%02x\n", addr, val);
#endif
/* convert to VGA memory offset */
memory_map_mode = (s->gr[6] >> 2) & 3;
addr &= 0x1ffff;
switch(memory_map_mode) {
case 0:
break;
case 1:
if (addr >= 0x10000)
return;
addr += s->bank_offset;
break;
case 2:
addr -= 0x10000;
if (addr >= 0x8000)
return;
break;
default:
case 3:
addr -= 0x18000;
if (addr >= 0x8000)
return;
break;
}
 
if (s->sr[4] & 0x08) {
/* chain 4 mode : simplest access */
plane = addr & 3;
mask = (1 << plane);
if (s->sr[2] & mask) {
s->vram_ptr[addr] = val;
#ifdef DEBUG_VGA_MEM
printf("vga: chain4: [0x%x]\n", addr);
#endif
s->plane_updated |= mask; /* only used to detect font change */
cpu_physical_memory_set_dirty(s->vram_offset + addr);
}
} else if (s->gr[5] & 0x10) {
/* odd/even mode (aka text mode mapping) */
plane = (s->gr[4] & 2) | (addr & 1);
mask = (1 << plane);
if (s->sr[2] & mask) {
addr = ((addr & ~1) << 1) | plane;
s->vram_ptr[addr] = val;
#ifdef DEBUG_VGA_MEM
printf("vga: odd/even: [0x%x]\n", addr);
#endif
s->plane_updated |= mask; /* only used to detect font change */
cpu_physical_memory_set_dirty(s->vram_offset + addr);
}
} else {
/* standard VGA latched access */
write_mode = s->gr[5] & 3;
switch(write_mode) {
default:
case 0:
/* rotate */
b = s->gr[3] & 7;
val = ((val >> b) | (val << (8 - b))) & 0xff;
val |= val << 8;
val |= val << 16;
 
/* apply set/reset mask */
set_mask = mask16[s->gr[1]];
val = (val & ~set_mask) | (mask16[s->gr[0]] & set_mask);
bit_mask = s->gr[8];
break;
case 1:
val = s->latch;
goto do_write;
case 2:
val = mask16[val & 0x0f];
bit_mask = s->gr[8];
break;
case 3:
/* rotate */
b = s->gr[3] & 7;
val = (val >> b) | (val << (8 - b));
 
bit_mask = s->gr[8] & val;
val = mask16[s->gr[0]];
break;
}
 
/* apply logical operation */
func_select = s->gr[3] >> 3;
switch(func_select) {
case 0:
default:
/* nothing to do */
break;
case 1:
/* and */
val &= s->latch;
break;
case 2:
/* or */
val |= s->latch;
break;
case 3:
/* xor */
val ^= s->latch;
break;
}
 
/* apply bit mask */
bit_mask |= bit_mask << 8;
bit_mask |= bit_mask << 16;
val = (val & bit_mask) | (s->latch & ~bit_mask);
 
do_write:
/* mask data according to sr[2] */
mask = s->sr[2];
s->plane_updated |= mask; /* only used to detect font change */
write_mask = mask16[mask];
((uint32_t_ *)s->vram_ptr)[addr] =
(((uint32_t_ *)s->vram_ptr)[addr] & ~write_mask) |
(val & write_mask);
#ifdef DEBUG_VGA_MEM
printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n",
addr * 4, write_mask, val);
#endif
cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
}
}
void vga_invalidate_scanlines(VGAState *s, int y1, int y2){}
void vga_invalidate_scanlines(VGAState *s, int y1, int y2){
int y;
if (y1 >= VGA_MAX_HEIGHT)
return;
if (y2 >= VGA_MAX_HEIGHT)
y2 = VGA_MAX_HEIGHT;
for(y = y1; y < y2; y++) {
s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
}
}
int ppm_save(const char *filename, struct DisplaySurface *ds){return 0;}
 
static void vga_draw_cursor_line(uint8_t *d1,
const uint8_t *src1,
int poffset, int w,
unsigned int color0,
unsigned int color1,
unsigned int color_xor)
{
const uint8_t *plane0, *plane1;
int x, b0, b1;
uint8_t *d;
 
d = d1;
plane0 = src1;
plane1 = src1 + poffset;
for (x = 0; x < w; x++) {
b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
 
b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
 
switch (b0 | (b1 << 1)) {
 
case 0:
 
break;
 
case 1:
 
((uint32_t_ *)d)[0] ^= color_xor;
((uint32_t_ *)d)[0] |= 0xff000000;
 
break;
 
case 2:
 
((uint32_t_ *)d)[0] = color0;
((uint32_t_ *)d)[0] |= 0xff000000;
break;
 
case 3:
 
((uint32_t_ *)d)[0] = color1;
((uint32_t_ *)d)[0] |= 0xff000000;
 
break;
 
}
 
d += 4;
 
}
 
}
 
void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1,
int poffset, int w,
unsigned int color0, unsigned int color1,
@@ -219,7 +516,10 @@
void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
int poffset, int w,
unsigned int color0, unsigned int color1,
unsigned int color_xor){}
unsigned int color_xor)
{
vga_draw_cursor_line(d1, src1, poffset, w, color0, color1, color_xor);
}
 
extern const uint8_t sr_mask[8];
extern const uint8_t gr_mask[16];
/np21/io/cpuio.c
@@ -16,8 +16,7 @@
}
#endif
if (CPU_MSW & 1) {
//return;
TRACEOUT(("80286 ProtectMode Disable"));
//return; // noreset”Å‚É‚·‚éê‡‚Í‚±‚̃Rƒƒ“ƒg‚ð‰ðœ‚µ‚Ä‚­‚¾‚³‚¢
}
epsonio.cpumode = (CPU_MSW & 1)?'P':'R';
CPU_A20EN(FALSE);
/np21/io/iocore.c
@@ -180,6 +180,10 @@
if ((port & 0xf0ff) == 0x801e) {
return(dipsw_r8(port));
}
if ((port & 0xffff) == 0x043B) {
TRACEOUT(("in%X - %.4x %.4x", port&0xff, CPU_CS, CPU_IP));
return 0x00;
}
//keytmp = (port & 0xfcff);
//if (0xE0 <= keytmp && keytmp <= 0xEE) {
// //TRACEOUT(("in%X - %.4x %.4x", port&0xff, CPU_CS, CPU_IP));
/np21/lio/gline.c
@@ -309,7 +309,7 @@
lp.x2 = (SINT16)LOADINTELWORD(dat.x2);
lp.y2 = (SINT16)LOADINTELWORD(dat.y2);
 
TRACEOUT(("lio_gline %d,%d-%d,%d [%d]", lp.x1, lp.y1, lp.x2, lp.y2, dat.type));
//TRACEOUT(("lio_gline %d,%d-%d,%d [%d]", lp.x1, lp.y1, lp.x2, lp.y2, dat.type));
 
if (dat.pal == 0xff) {
dat.pal = lio->work.fgcolor;
/np21/fdd/sxsi.c
@@ -229,6 +229,7 @@
 
// CD“ü‚ê‘Ö‚¦‚̃^ƒCƒ€ƒAƒEƒgi“Š‚°‚â‚èj
char cdchange_flag = 0;
DWORD cdchange_reqtime = 0;
REG8 cdchange_drv;
OEMCHAR cdchange_fname[MAX_PATH];
void cdchange_timeoutproc(NEVENTITEM item) {
@@ -259,8 +260,13 @@
break;
 
case SXSIDEV_CDROM:
#if defined(SUPPORT_IDEIO)
if (cdchange_flag) {
// CDŒðŠ·’†
if(GetTickCount()-cdchange_reqtime>15000){
// ‰ö‚µ‚¢‚̂ōēx—v‹
cdchange_timeoutset();
}
return(FAILURE);
}
if ((fname == NULL) || (fname[0] == '\0')) {
@@ -281,10 +287,10 @@
file_cpyname(cdchange_fname, fname, NELEMENTS(cdchange_fname));
cdchange_flag = 1;
cdchange_timeoutset();
cdchange_reqtime = GetTickCount();
return(FAILURE); // XXX: ‚±‚±‚ÅŽ¸”s•Ô‚µ‚Ä‚¦‚¦‚́H
}
r = sxsicd_open(sxsi, fname);
#if defined(SUPPORT_IDEIO)
if (r == SUCCESS) {
int num = drv & 0x0f;
file_cpyname(np2cfg.idecd[num-2], fname, NELEMENTS(cdchange_fname));
@@ -294,8 +300,8 @@
file_cpyname(np2cfg.idecd[num-2], "\0\0\0\0", 1);
sysmng_updatecaption(1);
}
}
#endif
}
break;
 
default:
/np21/fdd/newdisk.c
@@ -43,7 +43,7 @@
ZeroMemory(work, sizeof(work));
while(size) {
wsize = min(size, sizeof(work));
if (file_write(fh, work, wsize) != wsize) {
if (file_write(fh, work, (UINT)wsize) != wsize) {
return(FAILURE);
}
size -= wsize;
@@ -53,7 +53,7 @@
 
static BRESULT writehddipl(FILEH fh, UINT ssize, FILELEN tsize) {
 
UINT8 work[16384];
UINT8 work[65536];
FILELEN size;
 
ZeroMemory(work, sizeof(work));
@@ -71,7 +71,7 @@
while(tsize) {
size = min(tsize, sizeof(work));
tsize -= size;
if (file_write(fh, work, size) != size) {
if (file_write(fh, work, (UINT)size) != size) {
return(FAILURE);
}
}
@@ -80,7 +80,7 @@
}
 
void newdisk_thd(const OEMCHAR *fname, UINT hddsize) {
 
FILEH fh;
UINT8 work[256];
UINT size;
@@ -158,22 +158,30 @@
CopyMemory(&nhd.sig, sig_nhd, 15);
STOREINTELDWORD(nhd.headersize, sizeof(nhd));
#ifdef SUPPORT_LARGE_HDD
if(hddsize <= 4096){
if(hddsize <= 4000){
size = hddsize * 15;
STOREINTELDWORD(nhd.cylinders, size);
STOREINTELDWORD(nhd.cylinders, (UINT32)size);
STOREINTELWORD(nhd.surfaces, 8);
STOREINTELWORD(nhd.sectors, 17);
STOREINTELWORD(nhd.sectorsize, 512);
r = (file_write(fh, &nhd, sizeof(nhd)) == sizeof(nhd)) ? SUCCESS : FAILURE;
r |= writehddipl(fh, 512, size * 8 * 17 * 512);
}else{
}else if(hddsize <= 32000){
size = hddsize * 15 * 17 / 2 / 63;
STOREINTELDWORD(nhd.cylinders, size);
STOREINTELDWORD(nhd.cylinders, (UINT32)size);
STOREINTELWORD(nhd.surfaces, 16);
STOREINTELWORD(nhd.sectors, 63);
STOREINTELWORD(nhd.sectorsize, 512);
r = (file_write(fh, &nhd, sizeof(nhd)) == sizeof(nhd)) ? SUCCESS : FAILURE;
r |= writehddipl(fh, 512, (UINT64)size * 16 * 63 * 512);
}else{
size = hddsize * 15 * 17 / 2 / 255;
STOREINTELDWORD(nhd.cylinders, (UINT32)size);
STOREINTELWORD(nhd.surfaces, 16);
STOREINTELWORD(nhd.sectors, 255);
STOREINTELWORD(nhd.sectorsize, 512);
r = (file_write(fh, &nhd, sizeof(nhd)) == sizeof(nhd)) ? SUCCESS : FAILURE;
r |= writehddipl(fh, 512, (UINT64)size * 16 * 255 * 512);
}
#else
size = hddsize * 15;
/np21/fdd/diskdrv.c
@@ -91,9 +91,9 @@
drv++;
}
else if(np2cfg.sasihdd[i]!=NULL && np2cfg.sasihdd[i][0]!='\0'){
char buf[2048];
vsnprintf(buf, sizeof(buf), "Cannot open file %s", np2cfg.sasihdd[i]);
msgbox("HDD file open error", buf);
//char buf[2048];
//vsnprintf(buf, sizeof(buf), "Cannot open file %s", np2cfg.sasihdd[i]);
msgbox("HDD file open error" ,"HDD file open error");
sxsi_setdevtype(drv, SXSIDEV_NC);
}
}
/np21/x11/ext/externalchip.h
@@ -1,75 +1,75 @@
/**
* @file externalchip.h
* @brief Interface of thg external modules
*/
 
#pragma once
 
/**
* @brief The interface of thg external modules
*/
class IExternalChip
{
public:
/**
* ChipType
*/
enum ChipType
{
kNone = 0, /*!< None */
kAY8910, /*!< AY-3-8910 */
 
kYM2203, /*!< OPN */
kYM2608, /*!< OPNA */
kYM3438, /*!< OPN2 */
kYMF288, /*!< OPN3 */
 
kYM3812, /*!< OPL2 */
kYMF262, /*!< OPL3 */
kY8950, /*!< Y8950 */
 
kYM2151 /*!< OPM */
};
 
/**
* MessageType
*/
enum
{
kMute = 0,
kBusy
};
 
/**
* Destructor
*/
virtual ~IExternalChip()
{
}
 
/**
* Get chip type
* @return The type of the chip
*/
virtual ChipType GetChipType() = 0;
 
/**
* Reset
*/
virtual void Reset() = 0;
 
/**
* Writes register
* @param[in] nAddr The address
* @param[in] cData The data
*/
virtual void WriteRegister(UINT nAddr, UINT8 cData) = 0;
 
/**
* Message
* @param[in] nMessage The message
* @param[in] nParameter The parameter
* @return Result
*/
virtual INTPTR Message(UINT nMessage, INTPTR nParameter = 0) = 0;
};
/**
* @file externalchip.h
* @brief Interface of thg external modules
*/
 
#pragma once
 
/**
* @brief The interface of thg external modules
*/
class IExternalChip
{
public:
/**
* ChipType
*/
enum ChipType
{
kNone = 0, /*!< None */
kAY8910, /*!< AY-3-8910 */
 
kYM2203, /*!< OPN */
kYM2608, /*!< OPNA */
kYM3438, /*!< OPN2 */
kYMF288, /*!< OPN3 */
 
kYM3812, /*!< OPL2 */
kYMF262, /*!< OPL3 */
kY8950, /*!< Y8950 */
 
kYM2151 /*!< OPM */
};
 
/**
* MessageType
*/
enum
{
kMute = 0,
kBusy
};
 
/**
* Destructor
*/
virtual ~IExternalChip()
{
}
 
/**
* Get chip type
* @return The type of the chip
*/
virtual ChipType GetChipType() = 0;
 
/**
* Reset
*/
virtual void Reset() = 0;
 
/**
* Writes register
* @param[in] nAddr The address
* @param[in] cData The data
*/
virtual void WriteRegister(UINT nAddr, UINT8 cData) = 0;
 
/**
* Message
* @param[in] nMessage The message
* @param[in] nParameter The parameter
* @return Result
*/
virtual INTPTR Message(UINT nMessage, INTPTR nParameter = 0) = 0;
};
/np21/x11/ext/externalpsg.cpp
@@ -1,102 +1,102 @@
/**
* @file externalpsg.cpp
* @brief ŠO•” PSG ‰‰‘tƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalpsg.h"
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pChip ƒ`ƒbƒv
*/
CExternalPsg::CExternalPsg(IExternalChip* pChip)
: m_pChip(pChip)
, m_cPsgMix(0x3f)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CExternalPsg::~CExternalPsg()
{
delete m_pChip;
}
 
/**
* ƒ`ƒbƒv ƒ^ƒCƒv‚𓾂é
* @return ƒ`ƒbƒv ƒ^ƒCƒv
*/
IExternalChip::ChipType CExternalPsg::GetChipType()
{
return m_pChip->GetChipType();
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalPsg::Reset()
{
m_cPsgMix = 0x3f;
m_pChip->Reset();
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalPsg::WriteRegister(UINT nAddr, UINT8 cData)
{
if (nAddr < 0x0e)
{
if (nAddr == 0x07)
{
// psg mix
cData &= 0x3f;
if (m_cPsgMix == cData)
{
return;
}
m_cPsgMix = cData;
}
WriteRegisterInner(nAddr, cData);
}
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return Œ‹‰Ê
*/
INTPTR CExternalPsg::Message(UINT nMessage, INTPTR nParameter)
{
switch (nMessage)
{
case kMute:
Mute(nParameter != 0);
break;
}
return 0;
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalPsg::Mute(bool bMute) const
{
WriteRegisterInner(0x07, (bMute) ? 0x3f : m_cPsgMix);
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý(“à•”)
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalPsg::WriteRegisterInner(UINT nAddr, UINT8 cData) const
{
m_pChip->WriteRegister(nAddr, cData);
}
/**
* @file externalpsg.cpp
* @brief ŠO•” PSG ‰‰‘tƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalpsg.h"
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pChip ƒ`ƒbƒv
*/
CExternalPsg::CExternalPsg(IExternalChip* pChip)
: m_pChip(pChip)
, m_cPsgMix(0x3f)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CExternalPsg::~CExternalPsg()
{
delete m_pChip;
}
 
/**
* ƒ`ƒbƒv ƒ^ƒCƒv‚𓾂é
* @return ƒ`ƒbƒv ƒ^ƒCƒv
*/
IExternalChip::ChipType CExternalPsg::GetChipType()
{
return m_pChip->GetChipType();
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalPsg::Reset()
{
m_cPsgMix = 0x3f;
m_pChip->Reset();
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalPsg::WriteRegister(UINT nAddr, UINT8 cData)
{
if (nAddr < 0x0e)
{
if (nAddr == 0x07)
{
// psg mix
cData &= 0x3f;
if (m_cPsgMix == cData)
{
return;
}
m_cPsgMix = cData;
}
WriteRegisterInner(nAddr, cData);
}
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return Œ‹‰Ê
*/
INTPTR CExternalPsg::Message(UINT nMessage, INTPTR nParameter)
{
switch (nMessage)
{
case kMute:
Mute(nParameter != 0);
break;
}
return 0;
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalPsg::Mute(bool bMute) const
{
WriteRegisterInner(0x07, (bMute) ? 0x3f : m_cPsgMix);
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý(“à•”)
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalPsg::WriteRegisterInner(UINT nAddr, UINT8 cData) const
{
m_pChip->WriteRegister(nAddr, cData);
}
/np21/x11/ext/opl3.cpp
@@ -1,381 +1,381 @@
/**
* @file opl3.cpp
* @brief Implementation of OPL3
*/
 
#include "compiler.h"
#include "sound/opl3.h"
#include "pccore.h"
#include "iocore.h"
#include "sound/fmboard.h"
#include "generic/keydisp.h"
#include "externalchipmanager.h"
#include "externalopl3.h"
 
static void writeRegister(POPL3 opna, UINT nAddress, REG8 cData);
static void writeExtendedRegister(POPL3 opna, UINT nAddress, REG8 cData);
 
/**
* Initialize instance
* @param[in] opna The instance
*/
void opl3_construct(POPL3 opl3)
{
memset(opl3, 0, sizeof(*opl3));
}
 
/**
* Deinitialize instance
* @param[in] opl3 The instance
*/
void opl3_destruct(POPL3 opl3)
{
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
CExternalChipManager::GetInstance()->Release(pExt);
opl3->userdata = reinterpret_cast<INTPTR>(NULL);
}
 
/**
* Reset
* @param[in] opl3 The instance
* @param[in] cCaps
*/
void opl3_reset(POPL3 opl3, REG8 cCaps)
{
memset(&opl3->s, 0, sizeof(opl3->s));
opl3->s.cCaps = cCaps;
for (UINT i = 0; i < 2; i++)
{
memset(opl3->s.reg + (i * 0x100) + 0x20, 0xff, 0x80);
}
 
if (cCaps == 0)
{
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
if (pExt)
{
CExternalChipManager::GetInstance()->Release(pExt);
opl3->userdata = reinterpret_cast<INTPTR>(NULL);
}
}
}
 
/**
* Restore
* @param[in] opl3 The instance
*/
static void restore(POPL3 opl3)
{
writeExtendedRegister(opl3, 0x05, opl3->s.reg[0x105]);
writeExtendedRegister(opl3, 0x04, opl3->s.reg[0x104]);
writeExtendedRegister(opl3, 0x08, opl3->s.reg[0x108]);
 
for (UINT i = 0x20; i < 0x100; i++)
{
if (((i & 0xe0) == 0xa0) || ((i & 0xe0) == 0xc0))
{
continue;
}
if (((i & 0x1f) >= 0x18) || ((i & 0x07) >= 0x06))
{
continue;
}
writeRegister(opl3, i, opl3->s.reg[i]);
writeExtendedRegister(opl3, i, opl3->s.reg[i + 0x100]);
}
for (UINT i = 0xa0; i < 0xa9; i++)
{
writeRegister(opl3, i, opl3->s.reg[i]);
writeRegister(opl3, i + 0x10, opl3->s.reg[i + 0x10] & 0xdf);
writeRegister(opl3, i + 0x20, opl3->s.reg[i + 0x20]);
writeExtendedRegister(opl3, i, opl3->s.reg[i + 0x100]);
writeExtendedRegister(opl3, i + 0x10, opl3->s.reg[i + 0x110] & 0xdf);
writeExtendedRegister(opl3, i + 0x20, opl3->s.reg[i + 0x120]);
}
writeExtendedRegister(opl3, 0xbd, opl3->s.reg[0xbd]);
}
 
/**
* Bind
* @param[in] opl3 The instance
*/
void opl3_bind(POPL3 opl3)
{
UINT nBaseClock = 3579545;
UINT8 cCaps = opl3->s.cCaps;
 
nBaseClock = (cCaps & OPL3_HAS_OPL3) ? 3579545 : 3993600;
 
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
if (pExt == NULL)
{
IExternalChip::ChipType nChipType = IExternalChip::kNone;
UINT nClock = nBaseClock;
if (cCaps & OPL3_HAS_OPL3)
{
nChipType = IExternalChip::kYMF262;
nClock *= 4;
}
else if (cCaps & OPL3_HAS_OPL2)
{
nChipType = IExternalChip::kYM3812;
}
else
{
nChipType = IExternalChip::kY8950;
}
pExt = static_cast<CExternalOpl3*>(CExternalChipManager::GetInstance()->GetInterface(nChipType, nClock));
opl3->userdata = reinterpret_cast<INTPTR>(pExt);
}
if (pExt)
{
pExt->Reset();
}
else
{
oplgen_reset(&opl3->oplgen, nBaseClock);
}
restore(opl3);
 
if (pExt == NULL)
{
sound_streamregist(&opl3->oplgen, (SOUNDCB)oplgen_getpcm);
}
 
keydisp_bindopl3(opl3->s.reg, (cCaps & OPL3_HAS_OPL3) ? 18 : 9, nBaseClock);
}
 
/**
* Status
* @param[in] opl3 The instance
* @return Status
*/
REG8 opl3_readStatus(POPL3 opl3)
{
return 0;
}
 
/**
* Writes register
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
void opl3_writeRegister(POPL3 opl3, UINT nAddress, REG8 cData)
{
opl3->s.reg[nAddress] = cData;
writeRegister(opl3, nAddress, cData);
}
 
/**
* Writes register (Inner)
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
static void writeRegister(POPL3 opl3, UINT nAddress, REG8 cData)
{
const UINT8 cCaps = opl3->s.cCaps;
 
switch (nAddress & 0xe0)
{
case 0x20:
case 0x40:
case 0x60:
case 0x80:
if (((nAddress & 0x1f) >= 0x18) || ((nAddress & 7) >= 6))
{
return;
}
break;
 
case 0xa0:
if (nAddress == 0xbd)
{
break;
}
if ((nAddress & 0x0f) >= 9)
{
return;
}
if (nAddress & 0x10)
{
keydisp_opl3keyon(opl3->s.reg, nAddress & 0x0f, cData);
}
break;
 
case 0xc0:
if ((nAddress & 0x1f) >= 9)
{
return;
}
if (!(cCaps & OPL3_HAS_OPL3))
{
cData |= 0x30;
}
break;
 
case 0xe0:
if (!(cCaps & OPL3_HAS_OPL2))
{
return;
}
if (((nAddress & 0x1f) >= 0x18) || ((nAddress & 7) >= 6))
{
return;
}
break;
 
default:
return;
}
 
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
if (pExt)
{
pExt->WriteRegister(nAddress, cData);
}
else
{
sound_sync();
oplgen_setreg(&opl3->oplgen, nAddress, cData);
}
}
 
/**
* Writes extended register
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
void opl3_writeExtendedRegister(POPL3 opl3, UINT nAddress, REG8 cData)
{
opl3->s.reg[nAddress + 0x100] = cData;
writeExtendedRegister(opl3, nAddress, cData);
}
 
/**
* Writes extended register (Inner)
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
static void writeExtendedRegister(POPL3 opl3, UINT nAddress, REG8 cData)
{
const UINT8 cCaps = opl3->s.cCaps;
 
if (!(cCaps & OPL3_HAS_OPL3))
{
return;
}
 
switch (nAddress & 0xe0)
{
case 0x20:
case 0x40:
case 0x60:
case 0x80:
case 0xe0:
if (((nAddress & 0x1f) >= 0x18) || ((nAddress & 7) >= 6))
{
return;
}
break;
 
case 0xa0:
if ((nAddress & 0x0f) >= 9)
{
return;
}
if (nAddress & 0x10)
{
keydisp_opl3keyon(opl3->s.reg, (nAddress & 0x0f) + 9, cData);
}
break;
 
case 0xc0:
if ((nAddress & 0x1f) >= 9)
{
return;
}
break;
 
default:
if ((nAddress == 0x04) || (nAddress == 0x05) || (nAddress == 0x08))
{
break;
}
return;
}
 
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
if (pExt)
{
pExt->WriteRegister(nAddress + 0x100, cData);
}
#if 0
else
{
sound_sync();
oplgen_setreg(&opl3->oplgen, nAddress + 0x100, cData);
}
#endif
}
 
/**
* Reads register
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opl3_readRegister(POPL3 opl3, UINT nAddress)
{
return 0xff;
}
 
/**
* Reads extended register
* @param[in] opna The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opl3_readExtendedRegister(POPL3 opl3, UINT nAddress)
{
return 0xff;
}
 
 
 
// ---- statsave
 
/**
* Save
* @param[in] opl3 The instance
* @param[in] sfh The handle of statsave
* @param[in] tbl The item of statsave
* @return Error
*/
int opl3_sfsave(PCOPL3 opl3, STFLAGH sfh, const SFENTRY *tbl)
{
int ret = statflag_write(sfh, &opl3->s, sizeof(opl3->s));
if (opl3->s.cCaps & OPL3_HAS_8950ADPCM)
{
}
return ret;
}
 
/**
* Load
* @param[in] opl3 The instance
* @param[in] sfh The handle of statsave
* @param[in] tbl The item of statsave
* @return Error
*/
int opl3_sfload(POPL3 opl3, STFLAGH sfh, const SFENTRY *tbl)
{
int ret = statflag_read(sfh, &opl3->s, sizeof(opl3->s));
if (opl3->s.cCaps & OPL3_HAS_8950ADPCM)
{
}
return ret;
}
/**
* @file opl3.cpp
* @brief Implementation of OPL3
*/
 
#include "compiler.h"
#include "sound/opl3.h"
#include "pccore.h"
#include "iocore.h"
#include "sound/fmboard.h"
#include "generic/keydisp.h"
#include "externalchipmanager.h"
#include "externalopl3.h"
 
static void writeRegister(POPL3 opna, UINT nAddress, REG8 cData);
static void writeExtendedRegister(POPL3 opna, UINT nAddress, REG8 cData);
 
/**
* Initialize instance
* @param[in] opna The instance
*/
void opl3_construct(POPL3 opl3)
{
memset(opl3, 0, sizeof(*opl3));
}
 
/**
* Deinitialize instance
* @param[in] opl3 The instance
*/
void opl3_destruct(POPL3 opl3)
{
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
CExternalChipManager::GetInstance()->Release(pExt);
opl3->userdata = reinterpret_cast<INTPTR>(NULL);
}
 
/**
* Reset
* @param[in] opl3 The instance
* @param[in] cCaps
*/
void opl3_reset(POPL3 opl3, REG8 cCaps)
{
memset(&opl3->s, 0, sizeof(opl3->s));
opl3->s.cCaps = cCaps;
for (UINT i = 0; i < 2; i++)
{
memset(opl3->s.reg + (i * 0x100) + 0x20, 0xff, 0x80);
}
 
if (cCaps == 0)
{
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
if (pExt)
{
CExternalChipManager::GetInstance()->Release(pExt);
opl3->userdata = reinterpret_cast<INTPTR>(NULL);
}
}
}
 
/**
* Restore
* @param[in] opl3 The instance
*/
static void restore(POPL3 opl3)
{
writeExtendedRegister(opl3, 0x05, opl3->s.reg[0x105]);
writeExtendedRegister(opl3, 0x04, opl3->s.reg[0x104]);
writeExtendedRegister(opl3, 0x08, opl3->s.reg[0x108]);
 
for (UINT i = 0x20; i < 0x100; i++)
{
if (((i & 0xe0) == 0xa0) || ((i & 0xe0) == 0xc0))
{
continue;
}
if (((i & 0x1f) >= 0x18) || ((i & 0x07) >= 0x06))
{
continue;
}
writeRegister(opl3, i, opl3->s.reg[i]);
writeExtendedRegister(opl3, i, opl3->s.reg[i + 0x100]);
}
for (UINT i = 0xa0; i < 0xa9; i++)
{
writeRegister(opl3, i, opl3->s.reg[i]);
writeRegister(opl3, i + 0x10, opl3->s.reg[i + 0x10] & 0xdf);
writeRegister(opl3, i + 0x20, opl3->s.reg[i + 0x20]);
writeExtendedRegister(opl3, i, opl3->s.reg[i + 0x100]);
writeExtendedRegister(opl3, i + 0x10, opl3->s.reg[i + 0x110] & 0xdf);
writeExtendedRegister(opl3, i + 0x20, opl3->s.reg[i + 0x120]);
}
writeExtendedRegister(opl3, 0xbd, opl3->s.reg[0xbd]);
}
 
/**
* Bind
* @param[in] opl3 The instance
*/
void opl3_bind(POPL3 opl3)
{
UINT nBaseClock = 3579545;
UINT8 cCaps = opl3->s.cCaps;
 
nBaseClock = (cCaps & OPL3_HAS_OPL3) ? 3579545 : 3993600;
 
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
if (pExt == NULL)
{
IExternalChip::ChipType nChipType = IExternalChip::kNone;
UINT nClock = nBaseClock;
if (cCaps & OPL3_HAS_OPL3)
{
nChipType = IExternalChip::kYMF262;
nClock *= 4;
}
else if (cCaps & OPL3_HAS_OPL2)
{
nChipType = IExternalChip::kYM3812;
}
else
{
nChipType = IExternalChip::kY8950;
}
pExt = static_cast<CExternalOpl3*>(CExternalChipManager::GetInstance()->GetInterface(nChipType, nClock));
opl3->userdata = reinterpret_cast<INTPTR>(pExt);
}
if (pExt)
{
pExt->Reset();
}
else
{
oplgen_reset(&opl3->oplgen, nBaseClock);
}
restore(opl3);
 
if (pExt == NULL)
{
sound_streamregist(&opl3->oplgen, (SOUNDCB)oplgen_getpcm);
}
 
keydisp_bindopl3(opl3->s.reg, (cCaps & OPL3_HAS_OPL3) ? 18 : 9, nBaseClock);
}
 
/**
* Status
* @param[in] opl3 The instance
* @return Status
*/
REG8 opl3_readStatus(POPL3 opl3)
{
return 0;
}
 
/**
* Writes register
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
void opl3_writeRegister(POPL3 opl3, UINT nAddress, REG8 cData)
{
opl3->s.reg[nAddress] = cData;
writeRegister(opl3, nAddress, cData);
}
 
/**
* Writes register (Inner)
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
static void writeRegister(POPL3 opl3, UINT nAddress, REG8 cData)
{
const UINT8 cCaps = opl3->s.cCaps;
 
switch (nAddress & 0xe0)
{
case 0x20:
case 0x40:
case 0x60:
case 0x80:
if (((nAddress & 0x1f) >= 0x18) || ((nAddress & 7) >= 6))
{
return;
}
break;
 
case 0xa0:
if (nAddress == 0xbd)
{
break;
}
if ((nAddress & 0x0f) >= 9)
{
return;
}
if (nAddress & 0x10)
{
keydisp_opl3keyon(opl3->s.reg, nAddress & 0x0f, cData);
}
break;
 
case 0xc0:
if ((nAddress & 0x1f) >= 9)
{
return;
}
if (!(cCaps & OPL3_HAS_OPL3))
{
cData |= 0x30;
}
break;
 
case 0xe0:
if (!(cCaps & OPL3_HAS_OPL2))
{
return;
}
if (((nAddress & 0x1f) >= 0x18) || ((nAddress & 7) >= 6))
{
return;
}
break;
 
default:
return;
}
 
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
if (pExt)
{
pExt->WriteRegister(nAddress, cData);
}
else
{
sound_sync();
oplgen_setreg(&opl3->oplgen, nAddress, cData);
}
}
 
/**
* Writes extended register
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
void opl3_writeExtendedRegister(POPL3 opl3, UINT nAddress, REG8 cData)
{
opl3->s.reg[nAddress + 0x100] = cData;
writeExtendedRegister(opl3, nAddress, cData);
}
 
/**
* Writes extended register (Inner)
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
static void writeExtendedRegister(POPL3 opl3, UINT nAddress, REG8 cData)
{
const UINT8 cCaps = opl3->s.cCaps;
 
if (!(cCaps & OPL3_HAS_OPL3))
{
return;
}
 
switch (nAddress & 0xe0)
{
case 0x20:
case 0x40:
case 0x60:
case 0x80:
case 0xe0:
if (((nAddress & 0x1f) >= 0x18) || ((nAddress & 7) >= 6))
{
return;
}
break;
 
case 0xa0:
if ((nAddress & 0x0f) >= 9)
{
return;
}
if (nAddress & 0x10)
{
keydisp_opl3keyon(opl3->s.reg, (nAddress & 0x0f) + 9, cData);
}
break;
 
case 0xc0:
if ((nAddress & 0x1f) >= 9)
{
return;
}
break;
 
default:
if ((nAddress == 0x04) || (nAddress == 0x05) || (nAddress == 0x08))
{
break;
}
return;
}
 
CExternalOpl3* pExt = reinterpret_cast<CExternalOpl3*>(opl3->userdata);
if (pExt)
{
pExt->WriteRegister(nAddress + 0x100, cData);
}
#if 0
else
{
sound_sync();
oplgen_setreg(&opl3->oplgen, nAddress + 0x100, cData);
}
#endif
}
 
/**
* Reads register
* @param[in] opl3 The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opl3_readRegister(POPL3 opl3, UINT nAddress)
{
return 0xff;
}
 
/**
* Reads extended register
* @param[in] opna The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opl3_readExtendedRegister(POPL3 opl3, UINT nAddress)
{
return 0xff;
}
 
 
 
// ---- statsave
 
/**
* Save
* @param[in] opl3 The instance
* @param[in] sfh The handle of statsave
* @param[in] tbl The item of statsave
* @return Error
*/
int opl3_sfsave(PCOPL3 opl3, STFLAGH sfh, const SFENTRY *tbl)
{
int ret = statflag_write(sfh, &opl3->s, sizeof(opl3->s));
if (opl3->s.cCaps & OPL3_HAS_8950ADPCM)
{
}
return ret;
}
 
/**
* Load
* @param[in] opl3 The instance
* @param[in] sfh The handle of statsave
* @param[in] tbl The item of statsave
* @return Error
*/
int opl3_sfload(POPL3 opl3, STFLAGH sfh, const SFENTRY *tbl)
{
int ret = statflag_read(sfh, &opl3->s, sizeof(opl3->s));
if (opl3->s.cCaps & OPL3_HAS_8950ADPCM)
{
}
return ret;
}
/np21/x11/ext/opna.cpp
@@ -1,546 +1,546 @@
/**
* @file opna.cpp
* @brief Implementation of OPNA
*/
 
#include "compiler.h"
#include "sound/opna.h"
#include "pccore.h"
#include "iocore.h"
#include "sound/fmboard.h"
#include "sound/sound.h"
#include "sound/s98.h"
#include "generic/keydisp.h"
#include "externalchipmanager.h"
#include "externalopna.h"
 
static void writeRegister(POPNA opna, UINT nAddress, REG8 cData);
static void writeExtendedRegister(POPNA opna, UINT nAddress, REG8 cData);
 
/**
* Initialize instance
* @param[in] opna The instance
*/
void opna_construct(POPNA opna)
{
memset(opna, 0, sizeof(*opna));
}
 
/**
* Deinitialize instance
* @param[in] opna The instance
*/
void opna_destruct(POPNA opna)
{
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
CExternalChipManager::GetInstance()->Release(pExt);
opna->userdata = reinterpret_cast<INTPTR>(NULL);
}
 
/**
* Reset
* @param[in] opna The instance
* @param[in] cCaps
*/
void opna_reset(POPNA opna, REG8 cCaps)
{
memset(&opna->s, 0, sizeof(opna->s));
opna->s.adpcmmask = ~(0x1c);
opna->s.cCaps = cCaps;
opna->s.irq = 0xff;
opna->s.reg[0x07] = 0xbf;
opna->s.reg[0x0e] = 0xff;
opna->s.reg[0x0f] = 0xff;
opna->s.reg[0xff] = (cCaps & OPNA_HAS_RHYTHM) ? 0x01 : 0x00;
for (UINT i = 0; i < 2; i++)
{
memset(opna->s.reg + (i * 0x100) + 0x30, 0xff, 0x60);
memset(opna->s.reg + (i * 0x100) + 0xb4, 0xc0, 0x04);
}
for (UINT i = 0; i < 7; i++)
{
opna->s.keyreg[i] = i & 7;
}
 
opngen_reset(&opna->opngen);
psggen_reset(&opna->psg);
rhythm_reset(&opna->rhythm);
adpcm_reset(&opna->adpcm);
 
if (cCaps == 0)
{
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
if (pExt)
{
CExternalChipManager::GetInstance()->Release(pExt);
opna->userdata = reinterpret_cast<INTPTR>(NULL);
}
}
}
 
/**
* Restore
* @param[in] opna The instance
*/
static void restore(POPNA opna)
{
// FM
writeRegister(opna, 0x22, opna->s.reg[0x22]);
for (UINT i = 0x30; i < 0xa0; i++)
{
if ((i & 3) == 3)
{
continue;
}
writeRegister(opna, i, opna->s.reg[i]);
writeExtendedRegister(opna, i, opna->s.reg[i + 0x100]);
}
for (UINT i = 0xb7; i >= 0xa0; i--)
{
if ((i & 3) == 3)
{
continue;
}
writeRegister(opna, i, opna->s.reg[i]);
writeExtendedRegister(opna, i, opna->s.reg[i + 0x100]);
}
for (UINT i = 0; i < 8; i++)
{
if ((i & 3) == 3)
{
continue;
}
writeRegister(opna, 0x28, opna->s.keyreg[i]);
}
 
// PSG
for (UINT i = 0; i < 0x10; i++)
{
writeRegister(opna, i, opna->s.reg[i]);
}
 
// Rhythm
writeRegister(opna, 0x11, opna->s.reg[0x11]);
for (UINT i = 0x18; i < 0x1e; i++)
{
writeRegister(opna, i, opna->s.reg[i]);
}
}
 
/**
* Bind
* @param[in] opna The instance
*/
void opna_bind(POPNA opna)
{
UINT8 cCaps = opna->s.cCaps;
UINT nClock = 3993600;
 
keydisp_bindopna(opna->s.reg, (cCaps & OPNA_HAS_EXTENDEDFM) ? 6 : 3, nClock);
if (cCaps & OPNA_HAS_PSG)
{
keydisp_bindpsg(opna->s.reg, nClock);
}
 
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
if (pExt == NULL)
{
IExternalChip::ChipType nChipType = IExternalChip::kYM2203;
if (cCaps & OPNA_HAS_EXTENDEDFM)
{
nChipType = IExternalChip::kYMF288;
nClock *= 2;
if (cCaps & OPNA_HAS_ADPCM)
{
nChipType = IExternalChip::kYM2608;
}
else if (cCaps == OPNA_MODE_3438)
{
nChipType = IExternalChip::kYM3438;
}
}
pExt = static_cast<CExternalOpna*>(CExternalChipManager::GetInstance()->GetInterface(nChipType, nClock));
opna->userdata = reinterpret_cast<INTPTR>(pExt);
}
if (pExt)
{
pExt->Reset();
pExt->WriteRegister(0x22, 0x00);
pExt->WriteRegister(0x29, 0x80);
pExt->WriteRegister(0x10, 0xbf);
pExt->WriteRegister(0x11, 0x30);
pExt->WriteRegister(0x27, opna->s.reg[0x27]);
}
else
{
opna->opngen.opnch[2].extop = opna->s.reg[0x27] & 0xc0;
}
restore(opna);
 
if (pExt)
{
if ((cCaps & OPNA_HAS_PSG) && (pExt->HasPsg()))
{
cCaps &= ~OPNA_HAS_PSG;
}
if ((cCaps & OPNA_HAS_RHYTHM) && (pExt->HasRhythm()))
{
cCaps &= ~OPNA_HAS_RHYTHM;
}
if ((cCaps & OPNA_HAS_ADPCM) && (pExt->HasADPCM()))
{
sound_streamregist(&opna->adpcm, (SOUNDCB)adpcm_getpcm_dummy);
cCaps &= ~OPNA_HAS_ADPCM;
}
}
 
if (cCaps & OPNA_HAS_PSG)
{
sound_streamregist(&opna->psg, (SOUNDCB)psggen_getpcm);
}
if (cCaps & OPNA_HAS_VR)
{
sound_streamregist(&opna->opngen, (SOUNDCB)opngen_getpcmvr);
}
else
{
sound_streamregist(&opna->opngen, (SOUNDCB)opngen_getpcm);
}
if (cCaps & OPNA_HAS_RHYTHM)
{
rhythm_bind(&opna->rhythm);
}
if (cCaps & OPNA_HAS_ADPCM)
{
sound_streamregist(&opna->adpcm, (SOUNDCB)adpcm_getpcm);
}
}
 
/**
* Status
* @param[in] opna The instance
* @return Status
*/
REG8 opna_readStatus(POPNA opna)
{
if (opna->s.cCaps & OPNA_HAS_TIMER)
{
return opna->s.status;
}
return 0;
}
 
/**
* Status
* @param[in] opna The instance
* @return Status
*/
REG8 opna_readExtendedStatus(POPNA opna)
{
const UINT8 cCaps = opna->s.cCaps;
REG8 ret = 0;
 
if (cCaps & OPNA_HAS_ADPCM)
{
ret = adpcm_status(&opna->adpcm);
}
else
{
ret = opna->s.adpcmmask & 8;
}
 
if (cCaps & OPNA_HAS_TIMER)
{
ret |= opna->s.status;
}
 
return ret;
}
 
/**
* Writes register
* @param[in] opna The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
void opna_writeRegister(POPNA opna, UINT nAddress, REG8 cData)
{
opna->s.reg[nAddress] = cData;
 
if (opna->s.cCaps & OPNA_S98)
{
S98_put(NORMAL2608, nAddress, cData);
}
 
writeRegister(opna, nAddress, cData);
}
 
/**
* Writes register (Inner)
* @param[in] opna The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
static void writeRegister(POPNA opna, UINT nAddress, REG8 cData)
{
const UINT8 cCaps = opna->s.cCaps;
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
 
if (nAddress < 0x10)
{
if (cCaps & OPNA_HAS_PSG)
{
keydisp_psg(opna->s.reg, nAddress);
if ((!pExt) || (!pExt->HasPsg()))
{
psggen_setreg(&opna->psg, nAddress, cData);
}
else
{
pExt->WriteRegister(nAddress, cData);
}
}
}
else if (nAddress < 0x20)
{
if (cCaps & OPNA_HAS_RHYTHM)
{
if ((!pExt) || (!pExt->HasRhythm()))
{
rhythm_setreg(&opna->rhythm, nAddress, cData);
}
else
{
pExt->WriteRegister(nAddress, cData);
}
}
}
else if (nAddress < 0x30)
{
if (nAddress == 0x28)
{
REG8 cChannel = cData & 0x0f;
if (cChannel < 8)
{
opna->s.keyreg[cChannel] = cData;
}
if (cChannel < 3)
{
}
else if ((cCaps & OPNA_HAS_EXTENDEDFM) && (cChannel >= 4) && (cChannel < 7))
{
cChannel--;
}
else
{
return;
}
 
if (!pExt)
{
opngen_keyon(&opna->opngen, cChannel, cData);
}
else
{
pExt->WriteRegister(nAddress, cData);
}
keydisp_opnakeyon(opna->s.reg, cData);
}
else if (nAddress == 0x27)
{
if (cCaps & OPNA_HAS_TIMER)
{
opna_settimer(opna, cData);
}
 
if (pExt)
{
pExt->WriteRegister(nAddress, cData);
}
else
{
opna->opngen.opnch[2].extop = cData & 0xc0;
}
}
else if (nAddress == 0x22)
{
if (pExt)
{
pExt->WriteRegister(nAddress, cData);
}
}
}
else if (nAddress < 0xc0)
{
if (!pExt)
{
opngen_setreg(&opna->opngen, 0, nAddress, cData);
}
else
{
pExt->WriteRegister(nAddress, cData);
}
}
}
 
/**
* Writes extended register
* @param[in] opna The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
void opna_writeExtendedRegister(POPNA opna, UINT nAddress, REG8 cData)
{
opna->s.reg[nAddress + 0x100] = cData;
 
if (opna->s.cCaps & OPNA_S98)
{
S98_put(EXTEND2608, nAddress, cData);
}
 
writeExtendedRegister(opna, nAddress, cData);
}
 
/**
* Writes extended register (Inner)
* @param[in] opna The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
static void writeExtendedRegister(POPNA opna, UINT nAddress, REG8 cData)
{
const UINT8 cCaps = opna->s.cCaps;
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
 
if (nAddress < 0x12)
{
if (cCaps & OPNA_HAS_ADPCM)
{
adpcm_setreg(&opna->adpcm, nAddress, cData);
if ((pExt) && (pExt->HasADPCM()))
{
pExt->WriteRegister(nAddress + 0x100, cData);
}
}
else
{
if (nAddress == 0x10)
{
if (!(cData & 0x80))
{
opna->s.adpcmmask = ~(cData & 0x1c);
}
}
}
}
else if (nAddress >= 0x30)
{
if (cCaps & OPNA_HAS_EXTENDEDFM)
{
if (!pExt)
{
opngen_setreg(&opna->opngen, 3, nAddress, cData);
}
else
{
pExt->WriteRegister(nAddress + 0x100, cData);
}
}
}
}
 
/**
* Reads register
* @param[in] opna The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opna_readRegister(POPNA opna, UINT nAddress)
{
if (nAddress < 0x10)
{
if (!(opna->s.cCaps & OPNA_HAS_PSG))
{
return 0xff;
}
}
else if (nAddress < 0x20)
{
if (!(opna->s.cCaps & OPNA_HAS_RHYTHM))
{
return 0xff;
}
}
else if (nAddress == 0xff)
{
return (opna->s.cCaps & OPNA_HAS_RHYTHM) ? 1 : 0;
}
return opna->s.reg[nAddress];
}
 
/**
* Reads extended register
* @param[in] opna The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opna_readExtendedRegister(POPNA opna, UINT nAddress)
{
if ((opna->s.cCaps & OPNA_HAS_ADPCM) && (nAddress == 0x08))
{
return adpcm_readsample(&opna->adpcm);
}
return opna->s.reg[nAddress + 0x100];
}
 
/**
* Reads 3438 extended register
* @param[in] opna The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opna_read3438ExtRegister(POPNA opna, UINT nAddress)
{
return opna->s.reg[nAddress];
}
 
 
 
// ---- statsave
 
/**
* Save
* @param[in] opna The instance
* @param[in] sfh The handle of statsave
* @param[in] tbl The item of statsave
* @return Error
*/
int opna_sfsave(PCOPNA opna, STFLAGH sfh, const SFENTRY *tbl)
{
int ret = statflag_write(sfh, &opna->s, sizeof(opna->s));
if (opna->s.cCaps & OPNA_HAS_ADPCM)
{
ret |= statflag_write(sfh, &opna->adpcm, sizeof(opna->adpcm));
}
 
return ret;
}
 
/**
* Load
* @param[in] opna The instance
* @param[in] sfh The handle of statsave
* @param[in] tbl The item of statsave
* @return Error
*/
int opna_sfload(POPNA opna, STFLAGH sfh, const SFENTRY *tbl)
{
int ret = statflag_read(sfh, &opna->s, sizeof(opna->s));
if (opna->s.cCaps & OPNA_HAS_ADPCM)
{
ret |= statflag_read(sfh, &opna->adpcm, sizeof(opna->adpcm));
adpcm_update(&opna->adpcm);
}
 
return ret;
}
/**
* @file opna.cpp
* @brief Implementation of OPNA
*/
 
#include "compiler.h"
#include "sound/opna.h"
#include "pccore.h"
#include "iocore.h"
#include "sound/fmboard.h"
#include "sound/sound.h"
#include "sound/s98.h"
#include "generic/keydisp.h"
#include "externalchipmanager.h"
#include "externalopna.h"
 
static void writeRegister(POPNA opna, UINT nAddress, REG8 cData);
static void writeExtendedRegister(POPNA opna, UINT nAddress, REG8 cData);
 
/**
* Initialize instance
* @param[in] opna The instance
*/
void opna_construct(POPNA opna)
{
memset(opna, 0, sizeof(*opna));
}
 
/**
* Deinitialize instance
* @param[in] opna The instance
*/
void opna_destruct(POPNA opna)
{
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
CExternalChipManager::GetInstance()->Release(pExt);
opna->userdata = reinterpret_cast<INTPTR>(NULL);
}
 
/**
* Reset
* @param[in] opna The instance
* @param[in] cCaps
*/
void opna_reset(POPNA opna, REG8 cCaps)
{
memset(&opna->s, 0, sizeof(opna->s));
opna->s.adpcmmask = ~(0x1c);
opna->s.cCaps = cCaps;
opna->s.irq = 0xff;
opna->s.reg[0x07] = 0xbf;
opna->s.reg[0x0e] = 0xff;
opna->s.reg[0x0f] = 0xff;
opna->s.reg[0xff] = (cCaps & OPNA_HAS_RHYTHM) ? 0x01 : 0x00;
for (UINT i = 0; i < 2; i++)
{
memset(opna->s.reg + (i * 0x100) + 0x30, 0xff, 0x60);
memset(opna->s.reg + (i * 0x100) + 0xb4, 0xc0, 0x04);
}
for (UINT i = 0; i < 7; i++)
{
opna->s.keyreg[i] = i & 7;
}
 
opngen_reset(&opna->opngen);
psggen_reset(&opna->psg);
rhythm_reset(&opna->rhythm);
adpcm_reset(&opna->adpcm);
 
if (cCaps == 0)
{
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
if (pExt)
{
CExternalChipManager::GetInstance()->Release(pExt);
opna->userdata = reinterpret_cast<INTPTR>(NULL);
}
}
}
 
/**
* Restore
* @param[in] opna The instance
*/
static void restore(POPNA opna)
{
// FM
writeRegister(opna, 0x22, opna->s.reg[0x22]);
for (UINT i = 0x30; i < 0xa0; i++)
{
if ((i & 3) == 3)
{
continue;
}
writeRegister(opna, i, opna->s.reg[i]);
writeExtendedRegister(opna, i, opna->s.reg[i + 0x100]);
}
for (UINT i = 0xb7; i >= 0xa0; i--)
{
if ((i & 3) == 3)
{
continue;
}
writeRegister(opna, i, opna->s.reg[i]);
writeExtendedRegister(opna, i, opna->s.reg[i + 0x100]);
}
for (UINT i = 0; i < 8; i++)
{
if ((i & 3) == 3)
{
continue;
}
writeRegister(opna, 0x28, opna->s.keyreg[i]);
}
 
// PSG
for (UINT i = 0; i < 0x10; i++)
{
writeRegister(opna, i, opna->s.reg[i]);
}
 
// Rhythm
writeRegister(opna, 0x11, opna->s.reg[0x11]);
for (UINT i = 0x18; i < 0x1e; i++)
{
writeRegister(opna, i, opna->s.reg[i]);
}
}
 
/**
* Bind
* @param[in] opna The instance
*/
void opna_bind(POPNA opna)
{
UINT8 cCaps = opna->s.cCaps;
UINT nClock = 3993600;
 
keydisp_bindopna(opna->s.reg, (cCaps & OPNA_HAS_EXTENDEDFM) ? 6 : 3, nClock);
if (cCaps & OPNA_HAS_PSG)
{
keydisp_bindpsg(opna->s.reg, nClock);
}
 
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
if (pExt == NULL)
{
IExternalChip::ChipType nChipType = IExternalChip::kYM2203;
if (cCaps & OPNA_HAS_EXTENDEDFM)
{
nChipType = IExternalChip::kYMF288;
nClock *= 2;
if (cCaps & OPNA_HAS_ADPCM)
{
nChipType = IExternalChip::kYM2608;
}
else if (cCaps == OPNA_MODE_3438)
{
nChipType = IExternalChip::kYM3438;
}
}
pExt = static_cast<CExternalOpna*>(CExternalChipManager::GetInstance()->GetInterface(nChipType, nClock));
opna->userdata = reinterpret_cast<INTPTR>(pExt);
}
if (pExt)
{
pExt->Reset();
pExt->WriteRegister(0x22, 0x00);
pExt->WriteRegister(0x29, 0x80);
pExt->WriteRegister(0x10, 0xbf);
pExt->WriteRegister(0x11, 0x30);
pExt->WriteRegister(0x27, opna->s.reg[0x27]);
}
else
{
opna->opngen.opnch[2].extop = opna->s.reg[0x27] & 0xc0;
}
restore(opna);
 
if (pExt)
{
if ((cCaps & OPNA_HAS_PSG) && (pExt->HasPsg()))
{
cCaps &= ~OPNA_HAS_PSG;
}
if ((cCaps & OPNA_HAS_RHYTHM) && (pExt->HasRhythm()))
{
cCaps &= ~OPNA_HAS_RHYTHM;
}
if ((cCaps & OPNA_HAS_ADPCM) && (pExt->HasADPCM()))
{
sound_streamregist(&opna->adpcm, (SOUNDCB)adpcm_getpcm_dummy);
cCaps &= ~OPNA_HAS_ADPCM;
}
}
 
if (cCaps & OPNA_HAS_PSG)
{
sound_streamregist(&opna->psg, (SOUNDCB)psggen_getpcm);
}
if (cCaps & OPNA_HAS_VR)
{
sound_streamregist(&opna->opngen, (SOUNDCB)opngen_getpcmvr);
}
else
{
sound_streamregist(&opna->opngen, (SOUNDCB)opngen_getpcm);
}
if (cCaps & OPNA_HAS_RHYTHM)
{
rhythm_bind(&opna->rhythm);
}
if (cCaps & OPNA_HAS_ADPCM)
{
sound_streamregist(&opna->adpcm, (SOUNDCB)adpcm_getpcm);
}
}
 
/**
* Status
* @param[in] opna The instance
* @return Status
*/
REG8 opna_readStatus(POPNA opna)
{
if (opna->s.cCaps & OPNA_HAS_TIMER)
{
return opna->s.status;
}
return 0;
}
 
/**
* Status
* @param[in] opna The instance
* @return Status
*/
REG8 opna_readExtendedStatus(POPNA opna)
{
const UINT8 cCaps = opna->s.cCaps;
REG8 ret = 0;
 
if (cCaps & OPNA_HAS_ADPCM)
{
ret = adpcm_status(&opna->adpcm);
}
else
{
ret = opna->s.adpcmmask & 8;
}
 
if (cCaps & OPNA_HAS_TIMER)
{
ret |= opna->s.status;
}
 
return ret;
}
 
/**
* Writes register
* @param[in] opna The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
void opna_writeRegister(POPNA opna, UINT nAddress, REG8 cData)
{
opna->s.reg[nAddress] = cData;
 
if (opna->s.cCaps & OPNA_S98)
{
S98_put(NORMAL2608, nAddress, cData);
}
 
writeRegister(opna, nAddress, cData);
}
 
/**
* Writes register (Inner)
* @param[in] opna The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
static void writeRegister(POPNA opna, UINT nAddress, REG8 cData)
{
const UINT8 cCaps = opna->s.cCaps;
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
 
if (nAddress < 0x10)
{
if (cCaps & OPNA_HAS_PSG)
{
keydisp_psg(opna->s.reg, nAddress);
if ((!pExt) || (!pExt->HasPsg()))
{
psggen_setreg(&opna->psg, nAddress, cData);
}
else
{
pExt->WriteRegister(nAddress, cData);
}
}
}
else if (nAddress < 0x20)
{
if (cCaps & OPNA_HAS_RHYTHM)
{
if ((!pExt) || (!pExt->HasRhythm()))
{
rhythm_setreg(&opna->rhythm, nAddress, cData);
}
else
{
pExt->WriteRegister(nAddress, cData);
}
}
}
else if (nAddress < 0x30)
{
if (nAddress == 0x28)
{
REG8 cChannel = cData & 0x0f;
if (cChannel < 8)
{
opna->s.keyreg[cChannel] = cData;
}
if (cChannel < 3)
{
}
else if ((cCaps & OPNA_HAS_EXTENDEDFM) && (cChannel >= 4) && (cChannel < 7))
{
cChannel--;
}
else
{
return;
}
 
if (!pExt)
{
opngen_keyon(&opna->opngen, cChannel, cData);
}
else
{
pExt->WriteRegister(nAddress, cData);
}
keydisp_opnakeyon(opna->s.reg, cData);
}
else if (nAddress == 0x27)
{
if (cCaps & OPNA_HAS_TIMER)
{
opna_settimer(opna, cData);
}
 
if (pExt)
{
pExt->WriteRegister(nAddress, cData);
}
else
{
opna->opngen.opnch[2].extop = cData & 0xc0;
}
}
else if (nAddress == 0x22)
{
if (pExt)
{
pExt->WriteRegister(nAddress, cData);
}
}
}
else if (nAddress < 0xc0)
{
if (!pExt)
{
opngen_setreg(&opna->opngen, 0, nAddress, cData);
}
else
{
pExt->WriteRegister(nAddress, cData);
}
}
}
 
/**
* Writes extended register
* @param[in] opna The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
void opna_writeExtendedRegister(POPNA opna, UINT nAddress, REG8 cData)
{
opna->s.reg[nAddress + 0x100] = cData;
 
if (opna->s.cCaps & OPNA_S98)
{
S98_put(EXTEND2608, nAddress, cData);
}
 
writeExtendedRegister(opna, nAddress, cData);
}
 
/**
* Writes extended register (Inner)
* @param[in] opna The instance
* @param[in] nAddress The address
* @param[in] cData The data
*/
static void writeExtendedRegister(POPNA opna, UINT nAddress, REG8 cData)
{
const UINT8 cCaps = opna->s.cCaps;
CExternalOpna* pExt = reinterpret_cast<CExternalOpna*>(opna->userdata);
 
if (nAddress < 0x12)
{
if (cCaps & OPNA_HAS_ADPCM)
{
adpcm_setreg(&opna->adpcm, nAddress, cData);
if ((pExt) && (pExt->HasADPCM()))
{
pExt->WriteRegister(nAddress + 0x100, cData);
}
}
else
{
if (nAddress == 0x10)
{
if (!(cData & 0x80))
{
opna->s.adpcmmask = ~(cData & 0x1c);
}
}
}
}
else if (nAddress >= 0x30)
{
if (cCaps & OPNA_HAS_EXTENDEDFM)
{
if (!pExt)
{
opngen_setreg(&opna->opngen, 3, nAddress, cData);
}
else
{
pExt->WriteRegister(nAddress + 0x100, cData);
}
}
}
}
 
/**
* Reads register
* @param[in] opna The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opna_readRegister(POPNA opna, UINT nAddress)
{
if (nAddress < 0x10)
{
if (!(opna->s.cCaps & OPNA_HAS_PSG))
{
return 0xff;
}
}
else if (nAddress < 0x20)
{
if (!(opna->s.cCaps & OPNA_HAS_RHYTHM))
{
return 0xff;
}
}
else if (nAddress == 0xff)
{
return (opna->s.cCaps & OPNA_HAS_RHYTHM) ? 1 : 0;
}
return opna->s.reg[nAddress];
}
 
/**
* Reads extended register
* @param[in] opna The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opna_readExtendedRegister(POPNA opna, UINT nAddress)
{
if ((opna->s.cCaps & OPNA_HAS_ADPCM) && (nAddress == 0x08))
{
return adpcm_readsample(&opna->adpcm);
}
return opna->s.reg[nAddress + 0x100];
}
 
/**
* Reads 3438 extended register
* @param[in] opna The instance
* @param[in] nAddress The address
* @return data
*/
REG8 opna_read3438ExtRegister(POPNA opna, UINT nAddress)
{
return opna->s.reg[nAddress];
}
 
 
 
// ---- statsave
 
/**
* Save
* @param[in] opna The instance
* @param[in] sfh The handle of statsave
* @param[in] tbl The item of statsave
* @return Error
*/
int opna_sfsave(PCOPNA opna, STFLAGH sfh, const SFENTRY *tbl)
{
int ret = statflag_write(sfh, &opna->s, sizeof(opna->s));
if (opna->s.cCaps & OPNA_HAS_ADPCM)
{
ret |= statflag_write(sfh, &opna->adpcm, sizeof(opna->adpcm));
}
 
return ret;
}
 
/**
* Load
* @param[in] opna The instance
* @param[in] sfh The handle of statsave
* @param[in] tbl The item of statsave
* @return Error
*/
int opna_sfload(POPNA opna, STFLAGH sfh, const SFENTRY *tbl)
{
int ret = statflag_read(sfh, &opna->s, sizeof(opna->s));
if (opna->s.cCaps & OPNA_HAS_ADPCM)
{
ret |= statflag_read(sfh, &opna->adpcm, sizeof(opna->adpcm));
adpcm_update(&opna->adpcm);
}
 
return ret;
}
/np21/x11/ext/externalopm.cpp
@@ -1,135 +1,135 @@
/**
* @file externalopm.cpp
* @brief ŠO•” OPM ‰‰‘tƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalopm.h"
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pChip ƒ`ƒbƒv
*/
CExternalOpm::CExternalOpm(IExternalChip* pChip)
: m_pChip(pChip)
{
memset(m_cAlgorithm, 0, sizeof(m_cAlgorithm));
memset(m_cTtl, 0x7f, sizeof(m_cTtl));
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CExternalOpm::~CExternalOpm()
{
delete m_pChip;
}
 
/**
* ƒ`ƒbƒv ƒ^ƒCƒv‚𓾂é
* @return ƒ`ƒbƒv ƒ^ƒCƒv
*/
IExternalChip::ChipType CExternalOpm::GetChipType()
{
return m_pChip->GetChipType();
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalOpm::Reset()
{
memset(m_cAlgorithm, 0, sizeof(m_cAlgorithm));
memset(m_cTtl, 0x7f, sizeof(m_cTtl));
m_pChip->Reset();
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpm::WriteRegister(UINT nAddr, UINT8 cData)
{
if ((nAddr & 0xe0) == 0x60) // ttl
{
m_cTtl[nAddr & 0x1f] = cData;
}
else if ((nAddr & 0xf8) == 0x20) // algorithm
{
m_cAlgorithm[nAddr & 7] = cData;
}
WriteRegisterInner(nAddr, cData);
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return Œ‹‰Ê
*/
INTPTR CExternalOpm::Message(UINT nMessage, INTPTR nParameter)
{
switch (nMessage)
{
case kMute:
Mute(nParameter != 0);
break;
}
return 0;
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalOpm::Mute(bool bMute) const
{
const int nVolume = (bMute) ? -127 : 0;
for (UINT ch = 0; ch < 8; ch++)
{
SetVolume(ch, nVolume);
}
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý(“à•”)
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpm::WriteRegisterInner(UINT nAddr, UINT8 cData) const
{
m_pChip->WriteRegister(nAddr, cData);
}
 
/**
* ƒ”ƒHƒŠƒ…[ƒ€Ý’è
* @param[in] nChannel ƒ`ƒƒƒ“ƒlƒ‹
* @param[in] nVolume ƒ”ƒHƒŠƒ…[ƒ€’l
*/
void CExternalOpm::SetVolume(UINT nChannel, int nVolume) const
{
/*! ƒAƒ‹ƒSƒŠƒYƒ€ ƒXƒƒbƒg ƒ}ƒXƒN */
static const UINT8 s_opmask[] = {0x08, 0x08, 0x08, 0x08, 0x0c, 0x0e, 0x0e, 0x0f};
UINT8 cMask = s_opmask[m_cAlgorithm[nChannel] & 7];
 
int nOffset = nChannel;
do
{
if (cMask & 1)
{
int nTtl = (m_cTtl[nOffset] & 0x7f) - nVolume;
if (nTtl < 0)
{
nTtl = 0;
}
else if (nTtl > 0x7f)
{
nTtl = 0x7f;
}
WriteRegisterInner(0x60 + nOffset, static_cast<UINT8>(nTtl));
}
nOffset += 8;
cMask >>= 1;
} while (cMask != 0);
}
/**
* @file externalopm.cpp
* @brief ŠO•” OPM ‰‰‘tƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalopm.h"
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pChip ƒ`ƒbƒv
*/
CExternalOpm::CExternalOpm(IExternalChip* pChip)
: m_pChip(pChip)
{
memset(m_cAlgorithm, 0, sizeof(m_cAlgorithm));
memset(m_cTtl, 0x7f, sizeof(m_cTtl));
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CExternalOpm::~CExternalOpm()
{
delete m_pChip;
}
 
/**
* ƒ`ƒbƒv ƒ^ƒCƒv‚𓾂é
* @return ƒ`ƒbƒv ƒ^ƒCƒv
*/
IExternalChip::ChipType CExternalOpm::GetChipType()
{
return m_pChip->GetChipType();
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalOpm::Reset()
{
memset(m_cAlgorithm, 0, sizeof(m_cAlgorithm));
memset(m_cTtl, 0x7f, sizeof(m_cTtl));
m_pChip->Reset();
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpm::WriteRegister(UINT nAddr, UINT8 cData)
{
if ((nAddr & 0xe0) == 0x60) // ttl
{
m_cTtl[nAddr & 0x1f] = cData;
}
else if ((nAddr & 0xf8) == 0x20) // algorithm
{
m_cAlgorithm[nAddr & 7] = cData;
}
WriteRegisterInner(nAddr, cData);
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return Œ‹‰Ê
*/
INTPTR CExternalOpm::Message(UINT nMessage, INTPTR nParameter)
{
switch (nMessage)
{
case kMute:
Mute(nParameter != 0);
break;
}
return 0;
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalOpm::Mute(bool bMute) const
{
const int nVolume = (bMute) ? -127 : 0;
for (UINT ch = 0; ch < 8; ch++)
{
SetVolume(ch, nVolume);
}
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý(“à•”)
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpm::WriteRegisterInner(UINT nAddr, UINT8 cData) const
{
m_pChip->WriteRegister(nAddr, cData);
}
 
/**
* ƒ”ƒHƒŠƒ…[ƒ€Ý’è
* @param[in] nChannel ƒ`ƒƒƒ“ƒlƒ‹
* @param[in] nVolume ƒ”ƒHƒŠƒ…[ƒ€’l
*/
void CExternalOpm::SetVolume(UINT nChannel, int nVolume) const
{
/*! ƒAƒ‹ƒSƒŠƒYƒ€ ƒXƒƒbƒg ƒ}ƒXƒN */
static const UINT8 s_opmask[] = {0x08, 0x08, 0x08, 0x08, 0x0c, 0x0e, 0x0e, 0x0f};
UINT8 cMask = s_opmask[m_cAlgorithm[nChannel] & 7];
 
int nOffset = nChannel;
do
{
if (cMask & 1)
{
int nTtl = (m_cTtl[nOffset] & 0x7f) - nVolume;
if (nTtl < 0)
{
nTtl = 0;
}
else if (nTtl > 0x7f)
{
nTtl = 0x7f;
}
WriteRegisterInner(0x60 + nOffset, static_cast<UINT8>(nTtl));
}
nOffset += 8;
cMask >>= 1;
} while (cMask != 0);
}
/np21/x11/ext/externalopl3.cpp
@@ -1,105 +1,105 @@
/**
* @file externalopl3.cpp
* @brief ŠO•” OPL3 ‰‰‘tƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalopl3.h"
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pChip ƒ`ƒbƒv
*/
CExternalOpl3::CExternalOpl3(IExternalChip* pChip)
: m_pChip(pChip)
{
memset(m_cKon, 0x00, sizeof(m_cKon));
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CExternalOpl3::~CExternalOpl3()
{
delete m_pChip;
}
 
/**
* ƒ`ƒbƒv ƒ^ƒCƒv‚𓾂é
* @return ƒ`ƒbƒv ƒ^ƒCƒv
*/
IExternalChip::ChipType CExternalOpl3::GetChipType()
{
return m_pChip->GetChipType();
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalOpl3::Reset()
{
m_pChip->Reset();
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpl3::WriteRegister(UINT nAddr, UINT8 cData)
{
if ((nAddr & 0xf0) == 0xb0)
{
m_cKon[(nAddr & 0x100) >> 8][nAddr & 0x0f] = cData;
}
WriteRegisterInner(nAddr, cData);
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return Œ‹‰Ê
*/
INTPTR CExternalOpl3::Message(UINT nMessage, INTPTR nParameter)
{
switch (nMessage)
{
case kMute:
Mute(nParameter != 0);
break;
}
return 0;
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalOpl3::Mute(bool bMute)
{
if (bMute)
{
for (UINT i = 0; i < 2; i++)
{
for (UINT j = 0; j < 9; j++)
{
if (m_cKon[i][j] & 0x20)
{
m_cKon[i][j] &= 0xdf;
WriteRegisterInner((i * 0x100) + j + 0xb0, m_cKon[i][j]);
}
}
}
}
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý(“à•”)
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpl3::WriteRegisterInner(UINT nAddr, UINT8 cData) const
{
m_pChip->WriteRegister(nAddr, cData);
}
/**
* @file externalopl3.cpp
* @brief ŠO•” OPL3 ‰‰‘tƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalopl3.h"
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pChip ƒ`ƒbƒv
*/
CExternalOpl3::CExternalOpl3(IExternalChip* pChip)
: m_pChip(pChip)
{
memset(m_cKon, 0x00, sizeof(m_cKon));
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CExternalOpl3::~CExternalOpl3()
{
delete m_pChip;
}
 
/**
* ƒ`ƒbƒv ƒ^ƒCƒv‚𓾂é
* @return ƒ`ƒbƒv ƒ^ƒCƒv
*/
IExternalChip::ChipType CExternalOpl3::GetChipType()
{
return m_pChip->GetChipType();
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalOpl3::Reset()
{
m_pChip->Reset();
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpl3::WriteRegister(UINT nAddr, UINT8 cData)
{
if ((nAddr & 0xf0) == 0xb0)
{
m_cKon[(nAddr & 0x100) >> 8][nAddr & 0x0f] = cData;
}
WriteRegisterInner(nAddr, cData);
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return Œ‹‰Ê
*/
INTPTR CExternalOpl3::Message(UINT nMessage, INTPTR nParameter)
{
switch (nMessage)
{
case kMute:
Mute(nParameter != 0);
break;
}
return 0;
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalOpl3::Mute(bool bMute)
{
if (bMute)
{
for (UINT i = 0; i < 2; i++)
{
for (UINT j = 0; j < 9; j++)
{
if (m_cKon[i][j] & 0x20)
{
m_cKon[i][j] &= 0xdf;
WriteRegisterInner((i * 0x100) + j + 0xb0, m_cKon[i][j]);
}
}
}
}
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý(“à•”)
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpl3::WriteRegisterInner(UINT nAddr, UINT8 cData) const
{
m_pChip->WriteRegister(nAddr, cData);
}
/np21/x11/ext/externalopna.cpp
@@ -1,171 +1,171 @@
/**
* @file externalopna.cpp
* @brief ŠO•” OPNA ‰‰‘tƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalopna.h"
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pChip ƒ`ƒbƒv
*/
CExternalOpna::CExternalOpna(IExternalChip* pChip)
: CExternalPsg(pChip)
, m_bHasPsg(false)
, m_bHasExtend(false)
, m_bHasRhythm(false)
, m_bHasADPCM(false)
, m_cMode(0)
{
memset(m_cAlgorithm, 0, sizeof(m_cAlgorithm));
memset(m_cTtl, 0x7f, sizeof(m_cTtl));
 
switch (GetChipType())
{
case IExternalChip::kYM2203:
m_bHasPsg = true;
break;
 
case IExternalChip::kYM2608:
m_bHasPsg = true;
m_bHasExtend = true;
m_bHasRhythm = true;
m_bHasADPCM = true;
break;
 
case IExternalChip::kYM3438:
m_bHasExtend = true;
break;
 
case IExternalChip::kYMF288:
m_bHasPsg = true;
m_bHasExtend = true;
m_bHasRhythm = true;
break;
 
default:
break;
}
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CExternalOpna::~CExternalOpna()
{
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalOpna::Reset()
{
m_cMode = 0;
memset(m_cAlgorithm, 0, sizeof(m_cAlgorithm));
memset(m_cTtl, 0x7f, sizeof(m_cTtl));
if (m_bHasPsg)
{
CExternalPsg::Reset();
}
else
{
m_pChip->Reset();
}
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpna::WriteRegister(UINT nAddr, UINT8 cData)
{
if (nAddr < 0x10)
{
if (m_bHasPsg)
{
CExternalPsg::WriteRegister(nAddr, cData);
}
}
else
{
if (nAddr == 0x27)
{
cData &= 0xc0;
if (m_cMode == cData)
{
return;
}
m_cMode = cData;
}
else if ((nAddr & 0xf0) == 0x40)
{
// ttl
m_cTtl[((nAddr & 0x100) >> 4) + (nAddr & 15)] = cData;
}
else if ((nAddr & 0xfc) == 0xb0)
{
// algorithm
m_cAlgorithm[((nAddr & 0x100) >> 6) + (nAddr & 3)] = cData;
}
WriteRegisterInner(nAddr, cData);
}
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalOpna::Mute(bool bMute) const
{
if (m_bHasPsg)
{
CExternalPsg::Mute(bMute);
}
 
const int nVolume = (bMute) ? -127 : 0;
for (UINT ch = 0; ch < 3; ch++)
{
SetVolume(ch + 0, nVolume);
if (m_bHasExtend)
{
SetVolume(ch + 4, nVolume);
}
}
}
 
/**
* ƒ”ƒHƒŠƒ…[ƒ€Ý’è
* @param[in] nChannel ƒ`ƒƒƒ“ƒlƒ‹
* @param[in] nVolume ƒ”ƒHƒŠƒ…[ƒ€’l
*/
void CExternalOpna::SetVolume(UINT nChannel, int nVolume) const
{
const UINT nBaseReg = (nChannel & 4) ? 0x140 : 0x40;
 
/*! ƒAƒ‹ƒSƒŠƒYƒ€ ƒXƒƒbƒg ƒ}ƒXƒN */
static const UINT8 s_opmask[] = {0x08, 0x08, 0x08, 0x08, 0x0c, 0x0e, 0x0e, 0x0f};
UINT8 cMask = s_opmask[m_cAlgorithm[nChannel & 7] & 7];
const UINT8* pTtl = m_cTtl + ((nChannel & 4) << 2);
 
int nOffset = nChannel & 3;
do
{
if (cMask & 1)
{
int nTtl = (pTtl[nOffset] & 0x7f) - nVolume;
if (nTtl < 0)
{
nTtl = 0;
}
else if (nTtl > 0x7f)
{
nTtl = 0x7f;
}
WriteRegisterInner(nBaseReg + nOffset, static_cast<UINT8>(nTtl));
}
nOffset += 4;
cMask >>= 1;
} while (cMask != 0);
}
/**
* @file externalopna.cpp
* @brief ŠO•” OPNA ‰‰‘tƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalopna.h"
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pChip ƒ`ƒbƒv
*/
CExternalOpna::CExternalOpna(IExternalChip* pChip)
: CExternalPsg(pChip)
, m_bHasPsg(false)
, m_bHasExtend(false)
, m_bHasRhythm(false)
, m_bHasADPCM(false)
, m_cMode(0)
{
memset(m_cAlgorithm, 0, sizeof(m_cAlgorithm));
memset(m_cTtl, 0x7f, sizeof(m_cTtl));
 
switch (GetChipType())
{
case IExternalChip::kYM2203:
m_bHasPsg = true;
break;
 
case IExternalChip::kYM2608:
m_bHasPsg = true;
m_bHasExtend = true;
m_bHasRhythm = true;
m_bHasADPCM = true;
break;
 
case IExternalChip::kYM3438:
m_bHasExtend = true;
break;
 
case IExternalChip::kYMF288:
m_bHasPsg = true;
m_bHasExtend = true;
m_bHasRhythm = true;
break;
 
default:
break;
}
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CExternalOpna::~CExternalOpna()
{
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalOpna::Reset()
{
m_cMode = 0;
memset(m_cAlgorithm, 0, sizeof(m_cAlgorithm));
memset(m_cTtl, 0x7f, sizeof(m_cTtl));
if (m_bHasPsg)
{
CExternalPsg::Reset();
}
else
{
m_pChip->Reset();
}
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CExternalOpna::WriteRegister(UINT nAddr, UINT8 cData)
{
if (nAddr < 0x10)
{
if (m_bHasPsg)
{
CExternalPsg::WriteRegister(nAddr, cData);
}
}
else
{
if (nAddr == 0x27)
{
cData &= 0xc0;
if (m_cMode == cData)
{
return;
}
m_cMode = cData;
}
else if ((nAddr & 0xf0) == 0x40)
{
// ttl
m_cTtl[((nAddr & 0x100) >> 4) + (nAddr & 15)] = cData;
}
else if ((nAddr & 0xfc) == 0xb0)
{
// algorithm
m_cAlgorithm[((nAddr & 0x100) >> 6) + (nAddr & 3)] = cData;
}
WriteRegisterInner(nAddr, cData);
}
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalOpna::Mute(bool bMute) const
{
if (m_bHasPsg)
{
CExternalPsg::Mute(bMute);
}
 
const int nVolume = (bMute) ? -127 : 0;
for (UINT ch = 0; ch < 3; ch++)
{
SetVolume(ch + 0, nVolume);
if (m_bHasExtend)
{
SetVolume(ch + 4, nVolume);
}
}
}
 
/**
* ƒ”ƒHƒŠƒ…[ƒ€Ý’è
* @param[in] nChannel ƒ`ƒƒƒ“ƒlƒ‹
* @param[in] nVolume ƒ”ƒHƒŠƒ…[ƒ€’l
*/
void CExternalOpna::SetVolume(UINT nChannel, int nVolume) const
{
const UINT nBaseReg = (nChannel & 4) ? 0x140 : 0x40;
 
/*! ƒAƒ‹ƒSƒŠƒYƒ€ ƒXƒƒbƒg ƒ}ƒXƒN */
static const UINT8 s_opmask[] = {0x08, 0x08, 0x08, 0x08, 0x0c, 0x0e, 0x0e, 0x0f};
UINT8 cMask = s_opmask[m_cAlgorithm[nChannel & 7] & 7];
const UINT8* pTtl = m_cTtl + ((nChannel & 4) << 2);
 
int nOffset = nChannel & 3;
do
{
if (cMask & 1)
{
int nTtl = (pTtl[nOffset] & 0x7f) - nVolume;
if (nTtl < 0)
{
nTtl = 0;
}
else if (nTtl > 0x7f)
{
nTtl = 0x7f;
}
WriteRegisterInner(nBaseReg + nOffset, static_cast<UINT8>(nTtl));
}
nOffset += 4;
cMask >>= 1;
} while (cMask != 0);
}
/np21/x11/ext/scci/sccisoundchip.cpp
@@ -1,93 +1,93 @@
/**
* @file sccisoundchip.cpp
* @brief Implementation of sound chip
*/
 
#include "compiler.h"
#include "sccisoundchip.h"
#include "sccisoundinterface.h"
 
namespace scci
{
 
/**
* Constructor
* @param[in] pInterface The instance of the sound interface
* @param[in] info The information
*/
CSoundChip::CSoundChip(CSoundInterface* pInterface, const SCCI_SOUND_CHIP_INFO& info)
: m_pInterface(pInterface)
, m_info(info)
{
}
 
/**
* Destructor
*/
CSoundChip::~CSoundChip()
{
Release();
m_pInterface->Delete(m_info.dBusID);
}
 
/**
* Release the chip
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundChip::Release()
{
if (m_info.bIsUsed)
{
m_info.bIsUsed = false;
m_pInterface->Release();
return true;
}
else
{
return false;
}
}
 
/**
* Is macthed?
* @param[in] iSoundChipType The type of the chip
* @param[in] dClock The clock of the chip
* @retval true Yes
* @retval false No
*/
bool CSoundChip::IsMatch(SC_CHIP_TYPE iSoundChipType, UINT dClock) const
{
if ((m_info.iSoundChip == iSoundChipType) && (m_info.dClock == dClock))
{
return true;
}
for (UINT i = 0; i < 2; i++)
{
if ((m_info.iCompatibleSoundChip[i] == iSoundChipType) && (m_info.dCompatibleClock[i] == dClock))
{
return true;
}
}
return false;
}
 
/**
* Gets the informations of the sound chip
* @return The pointer of informations
*/
const SCCI_SOUND_CHIP_INFO* CSoundChip::getSoundChipInfo()
{
return &m_info;
}
 
/**
* Gets sound chip type
* @return The type of the chip
*/
SC_CHIP_TYPE CSoundChip::getSoundChipType()
{
return m_info.iSoundChip;
}
 
} // namespace scci
/**
* @file sccisoundchip.cpp
* @brief Implementation of sound chip
*/
 
#include "compiler.h"
#include "sccisoundchip.h"
#include "sccisoundinterface.h"
 
namespace scci
{
 
/**
* Constructor
* @param[in] pInterface The instance of the sound interface
* @param[in] info The information
*/
CSoundChip::CSoundChip(CSoundInterface* pInterface, const SCCI_SOUND_CHIP_INFO& info)
: m_pInterface(pInterface)
, m_info(info)
{
}
 
/**
* Destructor
*/
CSoundChip::~CSoundChip()
{
Release();
m_pInterface->Delete(m_info.dBusID);
}
 
/**
* Release the chip
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundChip::Release()
{
if (m_info.bIsUsed)
{
m_info.bIsUsed = false;
m_pInterface->Release();
return true;
}
else
{
return false;
}
}
 
/**
* Is macthed?
* @param[in] iSoundChipType The type of the chip
* @param[in] dClock The clock of the chip
* @retval true Yes
* @retval false No
*/
bool CSoundChip::IsMatch(SC_CHIP_TYPE iSoundChipType, UINT dClock) const
{
if ((m_info.iSoundChip == iSoundChipType) && (m_info.dClock == dClock))
{
return true;
}
for (UINT i = 0; i < 2; i++)
{
if ((m_info.iCompatibleSoundChip[i] == iSoundChipType) && (m_info.dCompatibleClock[i] == dClock))
{
return true;
}
}
return false;
}
 
/**
* Gets the informations of the sound chip
* @return The pointer of informations
*/
const SCCI_SOUND_CHIP_INFO* CSoundChip::getSoundChipInfo()
{
return &m_info;
}
 
/**
* Gets sound chip type
* @return The type of the chip
*/
SC_CHIP_TYPE CSoundChip::getSoundChipType()
{
return m_info.iSoundChip;
}
 
} // namespace scci
/np21/x11/ext/scci/sccispfmlight.cpp
@@ -1,396 +1,396 @@
/**
* @file sccispfmlight.cpp
* @brief Implementation of accessing SPFM Light
*/
 
#include "compiler.h"
#include "sccispfmlight.h"
#include "sccisoundchip.h"
#include "misc/threadbase.h"
 
namespace scci
{
 
/**
* Constructor
* @param[in] pManager The instance of the manager
* @param[in] deviceName The name of the device
* @param[in] nDelay delay time
*/
CSpfmLight::CSpfmLight(CSoundInterfaceManager* pManager, const std::oemstring& deviceName, UINT nDelay)
: CSoundInterface(pManager, deviceName)
, m_nDelay(nDelay)
, m_bReseted(false)
, m_nQueIndex(0)
, m_nQueCount(0)
{
}
 
/**
* Destructor
*/
CSpfmLight::~CSpfmLight()
{
}
 
/**
* Initialize
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::Initialize()
{
if (!m_serial.Open(m_info.cInterfaceName, 1500000, OEMTEXT("8N1")))
{
return false;
}
 
bool bResult = false;
 
m_ttyGuard.Enter();
const UINT nUntil = GETTICK() + 3000;
const unsigned char query[1] = {0xff};
if (Write(query, sizeof(query), nUntil) == sizeof(query))
{
unsigned char buffer[2];
bResult = (Read(buffer, sizeof(buffer), nUntil) == sizeof(buffer)) && (buffer[0] == 'L') && (buffer[1] == 'T');
}
m_ttyGuard.Leave();
 
if (bResult)
{
reset();
}
 
m_serial.Close();
 
m_bReseted = false;
return bResult;
}
 
/**
* Deinitialize
*/
void CSpfmLight::Deinitialize()
{
m_serial.Close();
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CSpfmLight::AddRef()
{
const size_t nRef = CSoundInterface::AddRef();
if (nRef == 1)
{
if (m_serial.Open(m_info.cInterfaceName, 1500000, OEMTEXT("8N1")))
{
Start();
}
}
return nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CSpfmLight::Release()
{
const size_t nRef = CSoundInterface::Release();
if (nRef == 0)
{
Stop();
m_serial.Close();
}
return nRef;
}
 
/**
* Add
* @param[in] info The information
*/
void CSpfmLight::Add(const SCCI_SOUND_CHIP_INFO& info)
{
std::map<UINT, CSoundChip*>::iterator it = m_chips.find(info.dBusID);
if (it == m_chips.end())
{
m_chips[info.dBusID] = new Chip(this, info);
m_info.iSoundChipCount++;
}
}
 
/**
* Is supported low level API
* @retval true yes
*/
bool CSpfmLight::isSupportLowLevelApi()
{
return true;
}
 
/**
* Sends data to the interface
* @param[in] pData The buffer of data
* @param[in] dSendDataLen The length of data
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::setData(const unsigned char* pData, size_t dSendDataLen)
{
m_ttyGuard.Enter();
m_bReseted = false;
const size_t r = m_serial.Write(pData, dSendDataLen);
m_ttyGuard.Leave();
return (r == dSendDataLen);
}
 
/**
* Gets data from the interface
* @param[out] pData The buffer of data
* @param[in] dGetDataLen The length of data
* @return The size of read
*/
size_t CSpfmLight::getData(unsigned char* pData, size_t dGetDataLen)
{
m_ttyGuard.Enter();
const ssize_t r = m_serial.Read(pData, dGetDataLen);
m_ttyGuard.Leave();
return r;
}
 
/**
* Sets delay time
* @param[in] dDelay delay time
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::setDelay(UINT dDelay)
{
if (dDelay > 10000)
{
return false;
}
m_nDelay = dDelay;
return true;
}
 
/**
* Gets delay time
* @return delay time
*/
UINT CSpfmLight::getDelay()
{
return m_nDelay;
}
 
/**
* Resets the interface
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::reset()
{
if (m_bReseted)
{
return true;
}
 
if (!m_serial.IsOpened())
{
return false;
}
 
m_queGuard.Enter();
m_nQueIndex = 0;
m_nQueCount = 0;
m_queGuard.Leave();
 
m_ttyGuard.Enter();
const UINT nUntil = GETTICK() + 3000;
const unsigned char reset[1] = {0xfe};
if (Write(reset, sizeof(reset), nUntil) == sizeof(reset))
{
unsigned char buffer[2];
m_bReseted = (Read(buffer, sizeof(buffer), nUntil) == sizeof(buffer)) && (buffer[0] == 'O') && (buffer[1] == 'K');
}
m_ttyGuard.Leave();
 
return m_bReseted;
}
 
/**
* Read
* @param[out] lpBuffer The pointer of the buffer
* @param[in] cbBuffer The size of the buffer
* @param[in] nUntil until
* @return The read size
*/
ssize_t CSpfmLight::Read(unsigned char* lpBuffer, ssize_t cbBuffer, UINT nUntil)
{
ssize_t nRead = m_serial.Read(lpBuffer, cbBuffer);
if (nRead == -1)
{
return -1;
}
while ((nRead < cbBuffer) && ((static_cast<SINT>(nUntil) - static_cast<SINT>(GETTICK())) > 0))
{
Delay(1000);
const ssize_t r = m_serial.Read(lpBuffer + nRead, cbBuffer - nRead);
if (r == -1)
{
return -1;
}
nRead += r;
}
return nRead;
}
 
/**
* Write
* @param[out] lpBuffer The pointer of the buffer
* @param[in] cbBuffer The size of the buffer
* @param[in] nUntil until
* @return The written size
*/
ssize_t CSpfmLight::Write(const unsigned char* lpBuffer, ssize_t cbBuffer, UINT nUntil)
{
ssize_t nWritten = m_serial.Write(lpBuffer, cbBuffer);
if (nWritten == -1)
{
return -1;
}
while ((nWritten < cbBuffer) && ((static_cast<SINT>(nUntil) - static_cast<SINT>(GETTICK())) > 0))
{
Delay(1000);
const ssize_t w = m_serial.Write(lpBuffer + nWritten, cbBuffer - nWritten);
if (w == -1)
{
return -1;
}
nWritten += w;
}
return nWritten;
}
 
/**
* Adds the event
* @param[in] nData data
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::AddEvent(UINT nData)
{
const UINT nNow = GETTICK();
 
m_queGuard.Enter();
 
m_bReseted = false;
 
while (m_nQueCount >= NELEMENTS(m_que))
{
m_queGuard.Leave();
Delay(1000);
m_queGuard.Enter();
}
 
QueData& que = m_que[(m_nQueIndex + m_nQueCount) % NELEMENTS(m_que)];
m_nQueCount++;
 
que.nTimestamp = nNow + m_nDelay;
que.nData = nData;
 
m_queGuard.Leave();
 
return true;
}
 
/**
* Thread
* @retval true Cont.
*/
bool CSpfmLight::Task()
{
/* builds data */
UINT8 sData[64];
UINT nIndex = 0;
 
const UINT nNow = GETTICK();
 
m_queGuard.Enter();
while (m_nQueCount)
{
const QueData& que = m_que[m_nQueIndex];
if ((static_cast<SINT>(que.nTimestamp) - static_cast<SINT>(nNow)) > 0)
{
break;
}
if ((nIndex + 4) > NELEMENTS(sData))
{
break;
}
 
sData[nIndex++] = static_cast<UINT8>(que.nData >> 24);
sData[nIndex++] = static_cast<UINT8>(que.nData >> 16);
sData[nIndex++] = static_cast<UINT8>(que.nData >> 8);
sData[nIndex++] = static_cast<UINT8>(que.nData >> 0);
 
m_nQueIndex = (m_nQueIndex + 1) % NELEMENTS(m_que);
m_nQueCount--;
}
m_queGuard.Leave();
 
/* writes */
if (nIndex > 0)
{
m_ttyGuard.Enter();
Write(sData, nIndex, nNow + 3000);
m_ttyGuard.Leave();
}
else
{
Delay(1000);
}
return true;
}
 
/**
* Constructor
* @param[in] pInterface The instance of the sound interface
* @param[in] info The information
*/
CSpfmLight::Chip::Chip(CSoundInterface* pInterface, const SCCI_SOUND_CHIP_INFO& info)
: CSoundChip(pInterface, info)
{
}
 
/**
* Sets Register data
* Writes the register
* @param[in] dAddr The address of register
* @param[in] dData The data
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::Chip::setRegister(UINT dAddr, UINT dData)
{
UINT nData = (m_info.dBusID & 0x0f) << 24;
nData |= (dAddr & 0x100) << 9;
nData |= (dAddr & 0xff) << 8;
nData |= (dData & 0xff) << 0;
return (static_cast<CSpfmLight*>(m_pInterface))->AddEvent(nData);
}
 
/**
* Initializes sound chip(clear registers)
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::Chip::init()
{
return m_pInterface->reset();
}
 
} // namespace scci
/**
* @file sccispfmlight.cpp
* @brief Implementation of accessing SPFM Light
*/
 
#include "compiler.h"
#include "sccispfmlight.h"
#include "sccisoundchip.h"
#include "misc/threadbase.h"
 
namespace scci
{
 
/**
* Constructor
* @param[in] pManager The instance of the manager
* @param[in] deviceName The name of the device
* @param[in] nDelay delay time
*/
CSpfmLight::CSpfmLight(CSoundInterfaceManager* pManager, const std::oemstring& deviceName, UINT nDelay)
: CSoundInterface(pManager, deviceName)
, m_nDelay(nDelay)
, m_bReseted(false)
, m_nQueIndex(0)
, m_nQueCount(0)
{
}
 
/**
* Destructor
*/
CSpfmLight::~CSpfmLight()
{
}
 
/**
* Initialize
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::Initialize()
{
if (!m_serial.Open(m_info.cInterfaceName, 1500000, OEMTEXT("8N1")))
{
return false;
}
 
bool bResult = false;
 
m_ttyGuard.Enter();
const UINT nUntil = GETTICK() + 3000;
const unsigned char query[1] = {0xff};
if (Write(query, sizeof(query), nUntil) == sizeof(query))
{
unsigned char buffer[2];
bResult = (Read(buffer, sizeof(buffer), nUntil) == sizeof(buffer)) && (buffer[0] == 'L') && (buffer[1] == 'T');
}
m_ttyGuard.Leave();
 
if (bResult)
{
reset();
}
 
m_serial.Close();
 
m_bReseted = false;
return bResult;
}
 
/**
* Deinitialize
*/
void CSpfmLight::Deinitialize()
{
m_serial.Close();
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CSpfmLight::AddRef()
{
const size_t nRef = CSoundInterface::AddRef();
if (nRef == 1)
{
if (m_serial.Open(m_info.cInterfaceName, 1500000, OEMTEXT("8N1")))
{
Start();
}
}
return nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CSpfmLight::Release()
{
const size_t nRef = CSoundInterface::Release();
if (nRef == 0)
{
Stop();
m_serial.Close();
}
return nRef;
}
 
/**
* Add
* @param[in] info The information
*/
void CSpfmLight::Add(const SCCI_SOUND_CHIP_INFO& info)
{
std::map<UINT, CSoundChip*>::iterator it = m_chips.find(info.dBusID);
if (it == m_chips.end())
{
m_chips[info.dBusID] = new Chip(this, info);
m_info.iSoundChipCount++;
}
}
 
/**
* Is supported low level API
* @retval true yes
*/
bool CSpfmLight::isSupportLowLevelApi()
{
return true;
}
 
/**
* Sends data to the interface
* @param[in] pData The buffer of data
* @param[in] dSendDataLen The length of data
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::setData(const unsigned char* pData, size_t dSendDataLen)
{
m_ttyGuard.Enter();
m_bReseted = false;
const size_t r = m_serial.Write(pData, dSendDataLen);
m_ttyGuard.Leave();
return (r == dSendDataLen);
}
 
/**
* Gets data from the interface
* @param[out] pData The buffer of data
* @param[in] dGetDataLen The length of data
* @return The size of read
*/
size_t CSpfmLight::getData(unsigned char* pData, size_t dGetDataLen)
{
m_ttyGuard.Enter();
const ssize_t r = m_serial.Read(pData, dGetDataLen);
m_ttyGuard.Leave();
return r;
}
 
/**
* Sets delay time
* @param[in] dDelay delay time
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::setDelay(UINT dDelay)
{
if (dDelay > 10000)
{
return false;
}
m_nDelay = dDelay;
return true;
}
 
/**
* Gets delay time
* @return delay time
*/
UINT CSpfmLight::getDelay()
{
return m_nDelay;
}
 
/**
* Resets the interface
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::reset()
{
if (m_bReseted)
{
return true;
}
 
if (!m_serial.IsOpened())
{
return false;
}
 
m_queGuard.Enter();
m_nQueIndex = 0;
m_nQueCount = 0;
m_queGuard.Leave();
 
m_ttyGuard.Enter();
const UINT nUntil = GETTICK() + 3000;
const unsigned char reset[1] = {0xfe};
if (Write(reset, sizeof(reset), nUntil) == sizeof(reset))
{
unsigned char buffer[2];
m_bReseted = (Read(buffer, sizeof(buffer), nUntil) == sizeof(buffer)) && (buffer[0] == 'O') && (buffer[1] == 'K');
}
m_ttyGuard.Leave();
 
return m_bReseted;
}
 
/**
* Read
* @param[out] lpBuffer The pointer of the buffer
* @param[in] cbBuffer The size of the buffer
* @param[in] nUntil until
* @return The read size
*/
ssize_t CSpfmLight::Read(unsigned char* lpBuffer, ssize_t cbBuffer, UINT nUntil)
{
ssize_t nRead = m_serial.Read(lpBuffer, cbBuffer);
if (nRead == -1)
{
return -1;
}
while ((nRead < cbBuffer) && ((static_cast<SINT>(nUntil) - static_cast<SINT>(GETTICK())) > 0))
{
Delay(1000);
const ssize_t r = m_serial.Read(lpBuffer + nRead, cbBuffer - nRead);
if (r == -1)
{
return -1;
}
nRead += r;
}
return nRead;
}
 
/**
* Write
* @param[out] lpBuffer The pointer of the buffer
* @param[in] cbBuffer The size of the buffer
* @param[in] nUntil until
* @return The written size
*/
ssize_t CSpfmLight::Write(const unsigned char* lpBuffer, ssize_t cbBuffer, UINT nUntil)
{
ssize_t nWritten = m_serial.Write(lpBuffer, cbBuffer);
if (nWritten == -1)
{
return -1;
}
while ((nWritten < cbBuffer) && ((static_cast<SINT>(nUntil) - static_cast<SINT>(GETTICK())) > 0))
{
Delay(1000);
const ssize_t w = m_serial.Write(lpBuffer + nWritten, cbBuffer - nWritten);
if (w == -1)
{
return -1;
}
nWritten += w;
}
return nWritten;
}
 
/**
* Adds the event
* @param[in] nData data
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::AddEvent(UINT nData)
{
const UINT nNow = GETTICK();
 
m_queGuard.Enter();
 
m_bReseted = false;
 
while (m_nQueCount >= NELEMENTS(m_que))
{
m_queGuard.Leave();
Delay(1000);
m_queGuard.Enter();
}
 
QueData& que = m_que[(m_nQueIndex + m_nQueCount) % NELEMENTS(m_que)];
m_nQueCount++;
 
que.nTimestamp = nNow + m_nDelay;
que.nData = nData;
 
m_queGuard.Leave();
 
return true;
}
 
/**
* Thread
* @retval true Cont.
*/
bool CSpfmLight::Task()
{
/* builds data */
UINT8 sData[64];
UINT nIndex = 0;
 
const UINT nNow = GETTICK();
 
m_queGuard.Enter();
while (m_nQueCount)
{
const QueData& que = m_que[m_nQueIndex];
if ((static_cast<SINT>(que.nTimestamp) - static_cast<SINT>(nNow)) > 0)
{
break;
}
if ((nIndex + 4) > NELEMENTS(sData))
{
break;
}
 
sData[nIndex++] = static_cast<UINT8>(que.nData >> 24);
sData[nIndex++] = static_cast<UINT8>(que.nData >> 16);
sData[nIndex++] = static_cast<UINT8>(que.nData >> 8);
sData[nIndex++] = static_cast<UINT8>(que.nData >> 0);
 
m_nQueIndex = (m_nQueIndex + 1) % NELEMENTS(m_que);
m_nQueCount--;
}
m_queGuard.Leave();
 
/* writes */
if (nIndex > 0)
{
m_ttyGuard.Enter();
Write(sData, nIndex, nNow + 3000);
m_ttyGuard.Leave();
}
else
{
Delay(1000);
}
return true;
}
 
/**
* Constructor
* @param[in] pInterface The instance of the sound interface
* @param[in] info The information
*/
CSpfmLight::Chip::Chip(CSoundInterface* pInterface, const SCCI_SOUND_CHIP_INFO& info)
: CSoundChip(pInterface, info)
{
}
 
/**
* Sets Register data
* Writes the register
* @param[in] dAddr The address of register
* @param[in] dData The data
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::Chip::setRegister(UINT dAddr, UINT dData)
{
UINT nData = (m_info.dBusID & 0x0f) << 24;
nData |= (dAddr & 0x100) << 9;
nData |= (dAddr & 0xff) << 8;
nData |= (dData & 0xff) << 0;
return (static_cast<CSpfmLight*>(m_pInterface))->AddEvent(nData);
}
 
/**
* Initializes sound chip(clear registers)
* @retval true If succeeded
* @retval false If failed
*/
bool CSpfmLight::Chip::init()
{
return m_pInterface->reset();
}
 
} // namespace scci
/np21/x11/ext/scci/scciif.cpp
@@ -1,287 +1,287 @@
/**
* @file scciif.cpp
* @brief SCCI ƒAƒNƒZƒX ƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "scciif.h"
#include "scci.h"
 
using namespace scci;
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
*/
CScciIf::CScciIf()
: m_pManager(NULL)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CScciIf::~CScciIf()
{
Deinitialize();
}
 
/**
* ‰Šú‰»
* @retval true ¬Œ÷
* @retval false Ž¸”s
*/
bool CScciIf::Initialize()
{
if (m_pManager)
{
return false;
}
 
do
{
/* ƒTƒEƒ“ƒhƒCƒ“ƒ^[ƒtƒF[ƒXƒ}ƒl[ƒWƒƒ[Žæ“¾ */
m_pManager = GetSoundInterfaceManager();
if (m_pManager == NULL)
{
break;
}
 
/* ƒTƒEƒ“ƒhƒCƒ“ƒ^[ƒtƒF[ƒXƒ}ƒl[ƒWƒƒ[ƒCƒ“ƒXƒ^ƒ“ƒX‰Šú‰» */
/* •K‚¸Å‰‚ÉŽÀs‚µ‚Ä‚­‚¾‚³‚¢ */
if (!m_pManager->initializeInstance())
{
break;
}
 
/* ƒŠƒZƒbƒg‚ðs‚¤ */
Reset();
return true;
} while (false /*CONSTCOND*/);
 
Deinitialize();
return false;
}
 
/**
* ‰ð•ú
*/
void CScciIf::Deinitialize()
{
if (m_pManager)
{
/* ˆêŠ‡ŠJ•ú‚·‚éê‡iƒ`ƒbƒvˆêŠ‡ŠJ•ú‚̏ꍇj */
m_pManager->releaseAllSoundChip();
 
/* ƒTƒEƒ“ƒhƒCƒ“ƒ^[ƒtƒF[ƒXƒ}ƒl[ƒWƒƒ[ƒCƒ“ƒXƒ^ƒ“ƒXŠJ•ú */
/* FreeLibrary‚ðs‚¤‘O‚É•K‚¸ŒÄ‚яo‚µ‚µ‚Ä‚­‚¾‚³‚¢ */
m_pManager->releaseInstance();
 
m_pManager = NULL;
}
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CScciIf::Reset()
{
if (m_pManager)
{
/* ƒŠƒZƒbƒg‚ðs‚¤ */
m_pManager->reset();
}
}
 
/**
* ƒCƒ“ƒ^[ƒtƒFƒCƒXŽæ“¾
* @param[in] nChipType ƒ^ƒCƒv
* @param[in] nClock ƒNƒƒbƒN
* @return ƒCƒ“ƒXƒ^ƒ“ƒX
*/
IExternalChip* CScciIf::GetInterface(IExternalChip::ChipType nChipType, UINT nClock)
{
const bool bInitialized = Initialize();
 
do
{
if (m_pManager == NULL)
{
break;
}
 
SC_CHIP_TYPE iSoundChipType = SC_TYPE_NONE;
switch (nChipType)
{
case IExternalChip::kAY8910:
iSoundChipType = SC_TYPE_AY8910;
break;
 
case IExternalChip::kYM2203:
iSoundChipType = SC_TYPE_YM2203;
break;
 
case IExternalChip::kYM2608:
iSoundChipType = SC_TYPE_YM2608;
break;
 
case IExternalChip::kYM3438:
iSoundChipType = SC_TYPE_YM2612;
break;
 
case IExternalChip::kYMF288:
iSoundChipType = SC_TYPE_YMF288;
break;
 
case IExternalChip::kYM3812:
iSoundChipType = SC_TYPE_YM3812;
break;
 
case IExternalChip::kYMF262:
iSoundChipType = SC_TYPE_YMF262;
break;
 
case IExternalChip::kY8950:
iSoundChipType = SC_TYPE_Y8950;
break;
 
case IExternalChip::kYM2151:
iSoundChipType = SC_TYPE_YM2151;
break;
 
default:
break;
}
 
SoundChip* pSoundChip = m_pManager->getSoundChip(iSoundChipType, nClock);
if (pSoundChip != NULL)
{
/* ƒTƒEƒ“ƒhƒ`ƒbƒvŽæ“¾‚Å‚«‚½ */
return new Chip(this, pSoundChip);
}
} while (false /*CONSTCOND*/);
 
if (bInitialized)
{
// Deinitialize();
}
return NULL;
}
 
/**
* ‰ð•ú
* @param[in] pChip ƒ`ƒbƒv
*/
void CScciIf::Detach(CScciIf::Chip* pChip)
{
/* ƒ`ƒbƒv‚ÌŠJ•úiƒ`ƒbƒv’PˆÊ‚ÅŠJ•ú‚̏ꍇj */
if (m_pManager)
{
m_pManager->releaseSoundChip(*pChip);
}
}
 
/* ---- ƒ`ƒbƒv */
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pScciIf eƒCƒ“ƒXƒ^ƒ“ƒX
* @param[in] pChip ƒ`ƒbƒv ƒCƒ“ƒXƒ^ƒ“ƒX
*/
CScciIf::Chip::Chip(CScciIf* pScciIf, SoundChip* pSoundChip)
: m_pScciIf(pScciIf)
, m_pSoundChip(pSoundChip)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CScciIf::Chip::~Chip()
{
m_pScciIf->Detach(this);
}
 
/**
* ƒIƒyƒŒ[ƒ^
*/
CScciIf::Chip::operator SoundChip*()
{
return m_pSoundChip;
}
 
/**
* Get chip type
* @return The type of the chip
*/
IExternalChip::ChipType CScciIf::Chip::GetChipType()
{
int iSoundChip = m_pSoundChip->getSoundChipType();
 
const SCCI_SOUND_CHIP_INFO* pInfo = m_pSoundChip->getSoundChipInfo();
if (pInfo)
{
iSoundChip = pInfo->iSoundChip;
}
 
switch (iSoundChip)
{
case SC_TYPE_AY8910:
return IExternalChip::kAY8910;
 
case SC_TYPE_YM2203:
return IExternalChip::kYM2203;
 
case SC_TYPE_YM2608:
return IExternalChip::kYM2608;
 
case SC_TYPE_YM2612:
return IExternalChip::kYM3438;
 
case SC_TYPE_YM3812:
return IExternalChip::kYM3812;
 
case SC_TYPE_YMF262:
return IExternalChip::kYMF262;
 
case SC_TYPE_YMF288:
return IExternalChip::kYMF288;
 
case SC_TYPE_Y8950:
return IExternalChip::kY8950;
 
case SC_TYPE_YM2151:
return IExternalChip::kYM2151;
 
default:
break;
}
return IExternalChip::kNone;
}
 
/**
* ƒŠƒZƒbƒg
*/
void CScciIf::Chip::Reset()
{
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CScciIf::Chip::WriteRegister(UINT nAddr, UINT8 cData)
{
m_pSoundChip->setRegister(nAddr, cData);
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return ƒŠƒUƒ‹ƒg
*/
INTPTR CScciIf::Chip::Message(UINT nMessage, INTPTR nParameter)
{
return 0;
}
/**
* @file scciif.cpp
* @brief SCCI ƒAƒNƒZƒX ƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "scciif.h"
#include "scci.h"
 
using namespace scci;
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
*/
CScciIf::CScciIf()
: m_pManager(NULL)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CScciIf::~CScciIf()
{
Deinitialize();
}
 
/**
* ‰Šú‰»
* @retval true ¬Œ÷
* @retval false Ž¸”s
*/
bool CScciIf::Initialize()
{
if (m_pManager)
{
return false;
}
 
do
{
/* ƒTƒEƒ“ƒhƒCƒ“ƒ^[ƒtƒF[ƒXƒ}ƒl[ƒWƒƒ[Žæ“¾ */
m_pManager = GetSoundInterfaceManager();
if (m_pManager == NULL)
{
break;
}
 
/* ƒTƒEƒ“ƒhƒCƒ“ƒ^[ƒtƒF[ƒXƒ}ƒl[ƒWƒƒ[ƒCƒ“ƒXƒ^ƒ“ƒX‰Šú‰» */
/* •K‚¸Å‰‚ÉŽÀs‚µ‚Ä‚­‚¾‚³‚¢ */
if (!m_pManager->initializeInstance())
{
break;
}
 
/* ƒŠƒZƒbƒg‚ðs‚¤ */
Reset();
return true;
} while (false /*CONSTCOND*/);
 
Deinitialize();
return false;
}
 
/**
* ‰ð•ú
*/
void CScciIf::Deinitialize()
{
if (m_pManager)
{
/* ˆêŠ‡ŠJ•ú‚·‚éê‡iƒ`ƒbƒvˆêŠ‡ŠJ•ú‚̏ꍇj */
m_pManager->releaseAllSoundChip();
 
/* ƒTƒEƒ“ƒhƒCƒ“ƒ^[ƒtƒF[ƒXƒ}ƒl[ƒWƒƒ[ƒCƒ“ƒXƒ^ƒ“ƒXŠJ•ú */
/* FreeLibrary‚ðs‚¤‘O‚É•K‚¸ŒÄ‚яo‚µ‚µ‚Ä‚­‚¾‚³‚¢ */
m_pManager->releaseInstance();
 
m_pManager = NULL;
}
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CScciIf::Reset()
{
if (m_pManager)
{
/* ƒŠƒZƒbƒg‚ðs‚¤ */
m_pManager->reset();
}
}
 
/**
* ƒCƒ“ƒ^[ƒtƒFƒCƒXŽæ“¾
* @param[in] nChipType ƒ^ƒCƒv
* @param[in] nClock ƒNƒƒbƒN
* @return ƒCƒ“ƒXƒ^ƒ“ƒX
*/
IExternalChip* CScciIf::GetInterface(IExternalChip::ChipType nChipType, UINT nClock)
{
const bool bInitialized = Initialize();
 
do
{
if (m_pManager == NULL)
{
break;
}
 
SC_CHIP_TYPE iSoundChipType = SC_TYPE_NONE;
switch (nChipType)
{
case IExternalChip::kAY8910:
iSoundChipType = SC_TYPE_AY8910;
break;
 
case IExternalChip::kYM2203:
iSoundChipType = SC_TYPE_YM2203;
break;
 
case IExternalChip::kYM2608:
iSoundChipType = SC_TYPE_YM2608;
break;
 
case IExternalChip::kYM3438:
iSoundChipType = SC_TYPE_YM2612;
break;
 
case IExternalChip::kYMF288:
iSoundChipType = SC_TYPE_YMF288;
break;
 
case IExternalChip::kYM3812:
iSoundChipType = SC_TYPE_YM3812;
break;
 
case IExternalChip::kYMF262:
iSoundChipType = SC_TYPE_YMF262;
break;
 
case IExternalChip::kY8950:
iSoundChipType = SC_TYPE_Y8950;
break;
 
case IExternalChip::kYM2151:
iSoundChipType = SC_TYPE_YM2151;
break;
 
default:
break;
}
 
SoundChip* pSoundChip = m_pManager->getSoundChip(iSoundChipType, nClock);
if (pSoundChip != NULL)
{
/* ƒTƒEƒ“ƒhƒ`ƒbƒvŽæ“¾‚Å‚«‚½ */
return new Chip(this, pSoundChip);
}
} while (false /*CONSTCOND*/);
 
if (bInitialized)
{
// Deinitialize();
}
return NULL;
}
 
/**
* ‰ð•ú
* @param[in] pChip ƒ`ƒbƒv
*/
void CScciIf::Detach(CScciIf::Chip* pChip)
{
/* ƒ`ƒbƒv‚ÌŠJ•úiƒ`ƒbƒv’PˆÊ‚ÅŠJ•ú‚̏ꍇj */
if (m_pManager)
{
m_pManager->releaseSoundChip(*pChip);
}
}
 
/* ---- ƒ`ƒbƒv */
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pScciIf eƒCƒ“ƒXƒ^ƒ“ƒX
* @param[in] pChip ƒ`ƒbƒv ƒCƒ“ƒXƒ^ƒ“ƒX
*/
CScciIf::Chip::Chip(CScciIf* pScciIf, SoundChip* pSoundChip)
: m_pScciIf(pScciIf)
, m_pSoundChip(pSoundChip)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
CScciIf::Chip::~Chip()
{
m_pScciIf->Detach(this);
}
 
/**
* ƒIƒyƒŒ[ƒ^
*/
CScciIf::Chip::operator SoundChip*()
{
return m_pSoundChip;
}
 
/**
* Get chip type
* @return The type of the chip
*/
IExternalChip::ChipType CScciIf::Chip::GetChipType()
{
int iSoundChip = m_pSoundChip->getSoundChipType();
 
const SCCI_SOUND_CHIP_INFO* pInfo = m_pSoundChip->getSoundChipInfo();
if (pInfo)
{
iSoundChip = pInfo->iSoundChip;
}
 
switch (iSoundChip)
{
case SC_TYPE_AY8910:
return IExternalChip::kAY8910;
 
case SC_TYPE_YM2203:
return IExternalChip::kYM2203;
 
case SC_TYPE_YM2608:
return IExternalChip::kYM2608;
 
case SC_TYPE_YM2612:
return IExternalChip::kYM3438;
 
case SC_TYPE_YM3812:
return IExternalChip::kYM3812;
 
case SC_TYPE_YMF262:
return IExternalChip::kYMF262;
 
case SC_TYPE_YMF288:
return IExternalChip::kYMF288;
 
case SC_TYPE_Y8950:
return IExternalChip::kY8950;
 
case SC_TYPE_YM2151:
return IExternalChip::kYM2151;
 
default:
break;
}
return IExternalChip::kNone;
}
 
/**
* ƒŠƒZƒbƒg
*/
void CScciIf::Chip::Reset()
{
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void CScciIf::Chip::WriteRegister(UINT nAddr, UINT8 cData)
{
m_pSoundChip->setRegister(nAddr, cData);
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return ƒŠƒUƒ‹ƒg
*/
INTPTR CScciIf::Chip::Message(UINT nMessage, INTPTR nParameter)
{
return 0;
}
/np21/x11/ext/scci/sccisoundinterface.h
@@ -1,69 +1,69 @@
/**
* @file sccisoundinterface.h
* @brief Interface of sound interfaces
*/
 
#pragma once
 
#include <map>
#include "scci.h"
#include "oemtext.h"
 
namespace scci
{
 
class CSoundChip;
class CSoundInterfaceManager;
 
/**
* @brief The class of interface
*/
class CSoundInterface : public SoundInterface
{
public:
CSoundInterface(CSoundInterfaceManager* pManager, const std::oemstring& deviceName);
virtual ~CSoundInterface();
virtual size_t AddRef();
virtual size_t Release();
void ReleaseAllChips();
const SCCI_INTERFACE_INFO* GetInfo() const;
SoundChip* GetSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock);
 
/**
* Initialize
* @retval true If succeeded
* @retval false If failed
*/
virtual bool Initialize() = 0;
 
/**
* Deinitialize
*/
virtual void Deinitialize() = 0;
 
/**
* Add
* @param[in] info The information
*/
virtual void Add(const SCCI_SOUND_CHIP_INFO& info) = 0;
 
protected:
size_t m_nRef; /*!< The reference counter */
CSoundInterfaceManager* m_pManager; /*!< Manager */
SCCI_INTERFACE_INFO m_info; /*!< The information */
std::map<UINT, CSoundChip*> m_chips; /*!< The interfaces */
void Delete(UINT dBusID);
 
friend class CSoundChip;
};
 
/**
* Gets the informations of the sound interface
* @return The poitner of the information
*/
inline const SCCI_INTERFACE_INFO* CSoundInterface::GetInfo() const
{
return &m_info;
}
 
} // namespace scci
/**
* @file sccisoundinterface.h
* @brief Interface of sound interfaces
*/
 
#pragma once
 
#include <map>
#include "scci.h"
#include "oemtext.h"
 
namespace scci
{
 
class CSoundChip;
class CSoundInterfaceManager;
 
/**
* @brief The class of interface
*/
class CSoundInterface : public SoundInterface
{
public:
CSoundInterface(CSoundInterfaceManager* pManager, const std::oemstring& deviceName);
virtual ~CSoundInterface();
virtual size_t AddRef();
virtual size_t Release();
void ReleaseAllChips();
const SCCI_INTERFACE_INFO* GetInfo() const;
SoundChip* GetSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock);
 
/**
* Initialize
* @retval true If succeeded
* @retval false If failed
*/
virtual bool Initialize() = 0;
 
/**
* Deinitialize
*/
virtual void Deinitialize() = 0;
 
/**
* Add
* @param[in] info The information
*/
virtual void Add(const SCCI_SOUND_CHIP_INFO& info) = 0;
 
protected:
size_t m_nRef; /*!< The reference counter */
CSoundInterfaceManager* m_pManager; /*!< Manager */
SCCI_INTERFACE_INFO m_info; /*!< The information */
std::map<UINT, CSoundChip*> m_chips; /*!< The interfaces */
void Delete(UINT dBusID);
 
friend class CSoundChip;
};
 
/**
* Gets the informations of the sound interface
* @return The poitner of the information
*/
inline const SCCI_INTERFACE_INFO* CSoundInterface::GetInfo() const
{
return &m_info;
}
 
} // namespace scci
/np21/x11/ext/scci/sccisoundchip.h
@@ -1,45 +1,45 @@
/**
* @file sccisoundchip.h
* @brief Interface of sound chip
*/
 
#pragma once
 
#include "scci.h"
 
namespace scci
{
 
class CSoundInterface;
 
/**
* @brief The class of chip
*/
class CSoundChip : public SoundChip
{
public:
CSoundChip(CSoundInterface* pInterface, const SCCI_SOUND_CHIP_INFO& info);
virtual ~CSoundChip();
bool Release();
SCCI_SOUND_CHIP_INFO* GetSoundChipInfo();
bool IsMatch(SC_CHIP_TYPE iSoundChipType, UINT dClock) const;
 
// SoundChip
virtual const SCCI_SOUND_CHIP_INFO* getSoundChipInfo();
virtual SC_CHIP_TYPE getSoundChipType();
 
protected:
CSoundInterface* m_pInterface; /*!< Interface */
SCCI_SOUND_CHIP_INFO m_info; /*!< The information */
};
 
/**
* Gets the informations of the sound chip
* @return The pointer of informations
*/
inline SCCI_SOUND_CHIP_INFO* CSoundChip::GetSoundChipInfo()
{
return &m_info;
}
 
} // namespace scci
/**
* @file sccisoundchip.h
* @brief Interface of sound chip
*/
 
#pragma once
 
#include "scci.h"
 
namespace scci
{
 
class CSoundInterface;
 
/**
* @brief The class of chip
*/
class CSoundChip : public SoundChip
{
public:
CSoundChip(CSoundInterface* pInterface, const SCCI_SOUND_CHIP_INFO& info);
virtual ~CSoundChip();
bool Release();
SCCI_SOUND_CHIP_INFO* GetSoundChipInfo();
bool IsMatch(SC_CHIP_TYPE iSoundChipType, UINT dClock) const;
 
// SoundChip
virtual const SCCI_SOUND_CHIP_INFO* getSoundChipInfo();
virtual SC_CHIP_TYPE getSoundChipType();
 
protected:
CSoundInterface* m_pInterface; /*!< Interface */
SCCI_SOUND_CHIP_INFO m_info; /*!< The information */
};
 
/**
* Gets the informations of the sound chip
* @return The pointer of informations
*/
inline SCCI_SOUND_CHIP_INFO* CSoundChip::GetSoundChipInfo()
{
return &m_info;
}
 
} // namespace scci
/np21/x11/ext/scci/SCCIDefines.h
@@ -1,65 +1,65 @@
/**
* @file SCCIDefines.h
* @brief SCCI Sound Interfaces defines
*/
 
#pragma once
 
namespace scci
{
 
/**
* Sound chip list
*/
enum SC_CHIP_TYPE
{
SC_TYPE_NONE = 0,
SC_TYPE_YM2608,
SC_TYPE_YM2151,
SC_TYPE_YM2610,
SC_TYPE_YM2203,
SC_TYPE_YM2612,
SC_TYPE_AY8910,
SC_TYPE_SN76489,
SC_TYPE_YM3812,
SC_TYPE_YMF262,
SC_TYPE_YM2413,
SC_TYPE_YM3526,
SC_TYPE_YMF288,
SC_TYPE_SCC,
SC_TYPE_SCCS,
SC_TYPE_Y8950,
SC_TYPE_MAX
};
 
/**
* Sound chip clock list
*/
enum SC_CHIP_CLOCK
{
SC_CLOCK_1789773 = 1789773, //!< SSG,OPN,OPM,SN76489 etc
SC_CLOCK_2000000 = 2000000, //!< SSG,OPN,OPM,SN76489 etc
SC_CLOCK_3579545 = 3579545, //!< SSG,OPN,OPM,SN76489 etc
SC_CLOCK_3993600 = 3993600, //!< OPN(88)
SC_CLOCK_4000000 = 4000000, //!< SSF,OPN,OPM etc
SC_CLOCK_7670454 = 7670454, //!< YM-2612 etc
SC_CLOCK_7987200 = 7987200, //!< OPNA(88)
SC_CLOCK_8000000 = 8000000, //!< OPNB etc
SC_CLOCK_12500000 = 12500000, //!< RF5C164
SC_CLOCK_14318180 = 14318180, //!< OPL2
SC_CLOCK_16934400 = 16934400, //!< YMF271
SC_CLOCK_23011361 = 23011361, //!< PWM
};
 
/**
* Sound chip location
*/
enum SC_CHIP_LOCATION
{
SC_LOCATION_MONO = 0,
SC_LOCATION_LEFT = 1,
SC_LOCATION_RIGHT = 2,
SC_LOCATION_STEREO = 3
};
 
} // namespace scci
/**
* @file SCCIDefines.h
* @brief SCCI Sound Interfaces defines
*/
 
#pragma once
 
namespace scci
{
 
/**
* Sound chip list
*/
enum SC_CHIP_TYPE
{
SC_TYPE_NONE = 0,
SC_TYPE_YM2608,
SC_TYPE_YM2151,
SC_TYPE_YM2610,
SC_TYPE_YM2203,
SC_TYPE_YM2612,
SC_TYPE_AY8910,
SC_TYPE_SN76489,
SC_TYPE_YM3812,
SC_TYPE_YMF262,
SC_TYPE_YM2413,
SC_TYPE_YM3526,
SC_TYPE_YMF288,
SC_TYPE_SCC,
SC_TYPE_SCCS,
SC_TYPE_Y8950,
SC_TYPE_MAX
};
 
/**
* Sound chip clock list
*/
enum SC_CHIP_CLOCK
{
SC_CLOCK_1789773 = 1789773, //!< SSG,OPN,OPM,SN76489 etc
SC_CLOCK_2000000 = 2000000, //!< SSG,OPN,OPM,SN76489 etc
SC_CLOCK_3579545 = 3579545, //!< SSG,OPN,OPM,SN76489 etc
SC_CLOCK_3993600 = 3993600, //!< OPN(88)
SC_CLOCK_4000000 = 4000000, //!< SSF,OPN,OPM etc
SC_CLOCK_7670454 = 7670454, //!< YM-2612 etc
SC_CLOCK_7987200 = 7987200, //!< OPNA(88)
SC_CLOCK_8000000 = 8000000, //!< OPNB etc
SC_CLOCK_12500000 = 12500000, //!< RF5C164
SC_CLOCK_14318180 = 14318180, //!< OPL2
SC_CLOCK_16934400 = 16934400, //!< YMF271
SC_CLOCK_23011361 = 23011361, //!< PWM
};
 
/**
* Sound chip location
*/
enum SC_CHIP_LOCATION
{
SC_LOCATION_MONO = 0,
SC_LOCATION_LEFT = 1,
SC_LOCATION_RIGHT = 2,
SC_LOCATION_STEREO = 3
};
 
} // namespace scci
/np21/x11/ext/scci/sccispfmlight.h
@@ -1,79 +1,79 @@
/**
* @file sccispfmlight.h
* @brief Interface of accessing SPFM Light
*/
 
#pragma once
 
#include "sccisoundchip.h"
#include "sccisoundinterface.h"
#include "misc/guard.h"
#include "misc/threadbase.h"
#include "misc/tty.h"
 
namespace scci
{
 
/**
* @brief The class of SPFM Light
*/
class CSpfmLight : public CSoundInterface, protected CThreadBase
{
public:
CSpfmLight(CSoundInterfaceManager* pManager, const std::oemstring& deviceName, UINT nDelay);
virtual ~CSpfmLight();
 
virtual bool Initialize();
virtual void Deinitialize();
virtual size_t AddRef();
virtual size_t Release();
virtual void Add(const SCCI_SOUND_CHIP_INFO& info);
 
virtual bool isSupportLowLevelApi();
virtual bool setData(const unsigned char* pData, size_t dSendDataLen);
virtual size_t getData(unsigned char* pData, size_t dGetDataLen);
virtual bool setDelay(UINT dDelay);
virtual UINT getDelay();
virtual bool reset();
 
protected:
virtual bool Task();
 
private:
/**
* @brief event
*/
struct QueData
{
UINT nTimestamp; /*!< Timestamp */
UINT nData; /*!< data */
};
 
/**
* @brief The class of Chip
*/
class Chip : public CSoundChip
{
public:
Chip(CSoundInterface* pInterface, const SCCI_SOUND_CHIP_INFO& info);
virtual bool setRegister(UINT dAddr, UINT dData);
virtual bool init();
};
 
UINT m_nDelay; /*!< delay time */
bool m_bReseted; /*!< Reset flag */
CTty m_serial; /*!< Serial */
CGuard m_ttyGuard; /*!< The quard of accessing USB */
CGuard m_queGuard; /*!< The quard of que */
UINT m_nQueIndex; /*!< The position in que */
UINT m_nQueCount; /*!< The count in que */
QueData m_que[0x400]; /*!< que */
 
ssize_t Read(unsigned char* lpBuffer, ssize_t cbBuffer, UINT nUntil);
ssize_t Write(const unsigned char* lpBuffer, ssize_t cbBuffer, UINT nUntil);
bool AddEvent(UINT nData);
 
friend class Chip;
};
 
} // namespace scci
/**
* @file sccispfmlight.h
* @brief Interface of accessing SPFM Light
*/
 
#pragma once
 
#include "sccisoundchip.h"
#include "sccisoundinterface.h"
#include "misc/guard.h"
#include "misc/threadbase.h"
#include "misc/tty.h"
 
namespace scci
{
 
/**
* @brief The class of SPFM Light
*/
class CSpfmLight : public CSoundInterface, protected CThreadBase
{
public:
CSpfmLight(CSoundInterfaceManager* pManager, const std::oemstring& deviceName, UINT nDelay);
virtual ~CSpfmLight();
 
virtual bool Initialize();
virtual void Deinitialize();
virtual size_t AddRef();
virtual size_t Release();
virtual void Add(const SCCI_SOUND_CHIP_INFO& info);
 
virtual bool isSupportLowLevelApi();
virtual bool setData(const unsigned char* pData, size_t dSendDataLen);
virtual size_t getData(unsigned char* pData, size_t dGetDataLen);
virtual bool setDelay(UINT dDelay);
virtual UINT getDelay();
virtual bool reset();
 
protected:
virtual bool Task();
 
private:
/**
* @brief event
*/
struct QueData
{
UINT nTimestamp; /*!< Timestamp */
UINT nData; /*!< data */
};
 
/**
* @brief The class of Chip
*/
class Chip : public CSoundChip
{
public:
Chip(CSoundInterface* pInterface, const SCCI_SOUND_CHIP_INFO& info);
virtual bool setRegister(UINT dAddr, UINT dData);
virtual bool init();
};
 
UINT m_nDelay; /*!< delay time */
bool m_bReseted; /*!< Reset flag */
CTty m_serial; /*!< Serial */
CGuard m_ttyGuard; /*!< The quard of accessing USB */
CGuard m_queGuard; /*!< The quard of que */
UINT m_nQueIndex; /*!< The position in que */
UINT m_nQueCount; /*!< The count in que */
QueData m_que[0x400]; /*!< que */
 
ssize_t Read(unsigned char* lpBuffer, ssize_t cbBuffer, UINT nUntil);
ssize_t Write(const unsigned char* lpBuffer, ssize_t cbBuffer, UINT nUntil);
bool AddEvent(UINT nData);
 
friend class Chip;
};
 
} // namespace scci
/np21/x11/ext/scci/scciif.h
@@ -1,53 +1,53 @@
/**
* @file scciif.h
* @brief SCCI ƒAƒNƒZƒX ƒNƒ‰ƒX‚̐錾‚¨‚æ‚уCƒ“ƒ^[ƒtƒFƒCƒX‚Ì’è‹`‚ð‚µ‚Ü‚·
*/
 
#pragma once
 
#include "../externalchip.h"
 
namespace scci
{
class SoundChip;
class SoundInterfaceManager;
}
 
/**
* @brief SCCI ƒAƒNƒZƒX ƒNƒ‰ƒX
*/
class CScciIf
{
public:
CScciIf();
~CScciIf();
bool Initialize();
void Deinitialize();
void Reset();
IExternalChip* GetInterface(IExternalChip::ChipType nChipType, UINT nClock);
 
private:
scci::SoundInterfaceManager* m_pManager; /*!< ƒ}ƒl[ƒWƒƒ */
 
/**
* @brief ƒ`ƒbƒv ƒNƒ‰ƒX
*/
class Chip : public IExternalChip
{
public:
Chip(CScciIf* pScciIf, scci::SoundChip* pSoundChip);
virtual ~Chip();
operator scci::SoundChip*();
virtual ChipType GetChipType();
virtual void Reset();
virtual void WriteRegister(UINT nAddr, UINT8 cData);
virtual INTPTR Message(UINT nMessage, INTPTR nParameter = 0);
 
private:
CScciIf* m_pScciIf; /*!< eƒCƒ“ƒXƒ^ƒ“ƒX */
scci::SoundChip* m_pSoundChip; /*!< ƒ`ƒbƒv ƒCƒ“ƒXƒ^ƒ“ƒX */
};
 
void Detach(Chip* pChip);
friend class Chip;
};
/**
* @file scciif.h
* @brief SCCI ƒAƒNƒZƒX ƒNƒ‰ƒX‚̐錾‚¨‚æ‚уCƒ“ƒ^[ƒtƒFƒCƒX‚Ì’è‹`‚ð‚µ‚Ü‚·
*/
 
#pragma once
 
#include "../externalchip.h"
 
namespace scci
{
class SoundChip;
class SoundInterfaceManager;
}
 
/**
* @brief SCCI ƒAƒNƒZƒX ƒNƒ‰ƒX
*/
class CScciIf
{
public:
CScciIf();
~CScciIf();
bool Initialize();
void Deinitialize();
void Reset();
IExternalChip* GetInterface(IExternalChip::ChipType nChipType, UINT nClock);
 
private:
scci::SoundInterfaceManager* m_pManager; /*!< ƒ}ƒl[ƒWƒƒ */
 
/**
* @brief ƒ`ƒbƒv ƒNƒ‰ƒX
*/
class Chip : public IExternalChip
{
public:
Chip(CScciIf* pScciIf, scci::SoundChip* pSoundChip);
virtual ~Chip();
operator scci::SoundChip*();
virtual ChipType GetChipType();
virtual void Reset();
virtual void WriteRegister(UINT nAddr, UINT8 cData);
virtual INTPTR Message(UINT nMessage, INTPTR nParameter = 0);
 
private:
CScciIf* m_pScciIf; /*!< eƒCƒ“ƒXƒ^ƒ“ƒX */
scci::SoundChip* m_pSoundChip; /*!< ƒ`ƒbƒv ƒCƒ“ƒXƒ^ƒ“ƒX */
};
 
void Detach(Chip* pChip);
friend class Chip;
};
/np21/x11/ext/scci/scci.h
@@ -1,231 +1,231 @@
/**
* @file scci.h
* @brief Sound Chip common Interface
*/
 
#pragma once
 
#include "SCCIDefines.h"
 
namespace scci
{
 
class SoundChip;
 
/**
* @brief Sound Interface Infomation
*/
struct SCCI_INTERFACE_INFO
{
OEMCHAR cInterfaceName[64]; /*!< Interface Name */
size_t iSoundChipCount; /*!< Sound Chip Count */
};
 
/**
* @brief Sound Chip Infomation
*/
struct SCCI_SOUND_CHIP_INFO
{
OEMCHAR cSoundChipName[64]; /*!< Sound Chip Name */
SC_CHIP_TYPE iSoundChip; /*!< Sound Chip ID */
SC_CHIP_TYPE iCompatibleSoundChip[2]; /*!< Compatible Sound Chip ID */
UINT dClock; /*!< Sound Chip clock */
UINT dCompatibleClock[2]; /*!< Sound Chip clock */
bool bIsUsed; /*!< Sound Chip Used Check */
UINT dBusID; /*!< Ú‘±ƒoƒXID */
SC_CHIP_LOCATION dSoundLocation; /*!< ƒTƒEƒ“ƒhƒƒP[ƒVƒ‡ƒ“ */
};
 
class SoundInterface;
 
/**
* @brief Sound Interface Manager
*/
class SoundInterfaceManager
{
public:
/**
* Gets the count of interfaces
* @return The count of interfaces
*/
virtual size_t getInterfaceCount() = 0;
 
/**
* Gets the information of the interface
* @param[in] iInterfaceNo The index of interfaces
* @return The information
*/
virtual const SCCI_INTERFACE_INFO* getInterfaceInfo(size_t iInterfaceNo) = 0;
 
/**
* Gets interface instance
* @param[in] iInterfaceNo The index of interfaces
* @return The instance
*/
virtual SoundInterface* getInterface(size_t iInterfaceNo) = 0;
 
/**
* Releases interface instance
* @param[in] pSoundInterface The instance of the interface
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseInterface(SoundInterface* pSoundInterface) = 0;
 
/**
* Release all interface instance
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseAllInterface() = 0;
 
/**
* Gets instance of the sound chip
* @param[in] iSoundChipType The type of the chip
* @param[in] dClock The clock of the chip
* @return The interface
*/
virtual SoundChip* getSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock) = 0;
 
/**
* Releases the instance of the sound chip
* @param[in] pSoundChip The instance of the sound chip
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseSoundChip(SoundChip* pSoundChip) = 0;
 
/**
* Releases all instances of the sound chip
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseAllSoundChip() = 0;
 
/**
* Sets delay time
* @param[in] dMSec delay time
* @retval true If succeeded
* @retval false If failed
*/
virtual bool setDelay(UINT dMSec) = 0;
 
/**
* Gets delay time
* @return delay time
*/
virtual UINT getDelay() = 0;
 
/**
* Resets all interfaces
* @retval true If succeeded
* @retval false If failed
*/
virtual bool reset() = 0;
 
/**
* Sound Interface instance initialize
* @retval true If succeeded
* @retval false If failed
*/
virtual bool initializeInstance() = 0;
 
/**
* Sound Interface instance release
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseInstance() = 0;
};
 
/**
* @brief Sound Interface(LOW level APIs)
*/
class SoundInterface
{
public:
/**
* Is supported low level API
* @retval true yes
* @retval false no
*/
virtual bool isSupportLowLevelApi() = 0;
 
/**
* Sends data to the interface
* @param[in] pData The buffer of data
* @param[in] dSendDataLen The length of data
* @retval true If succeeded
* @retval false If failed
*/
virtual bool setData(const unsigned char* pData, size_t dSendDataLen) = 0;
 
/**
* Gets data from the interface
* @param[out] pData The buffer of data
* @param[in] dGetDataLen The length of data
* @return The size of read
*/
virtual size_t getData(unsigned char* pData, size_t dGetDataLen) = 0;
 
/**
* Sets delay time
* @param[in] dDelay delay time
* @retval true If succeeded
* @retval false If failed
*/
virtual bool setDelay(UINT dDelay) = 0;
 
/**
* Gets delay time
* @return delay time
*/
virtual UINT getDelay() = 0;
 
/**
* Resets the interface
* @retval true If succeeded
* @retval false If failed
*/
virtual bool reset() = 0;
};
 
/**
* @brief Sound Chip
*/
class SoundChip
{
public:
/**
* Gets the informations of the sound chip
* @return The pointer of informations
*/
virtual const SCCI_SOUND_CHIP_INFO* getSoundChipInfo() = 0;
 
/**
* Gets sound chip type
* @return The type of the chip
*/
virtual SC_CHIP_TYPE getSoundChipType() = 0;
 
/**
* Sets Register data
* Writes the register
* @param[in] dAddr The address of register
* @param[in] dData The data
* @retval true If succeeded
* @retval false If failed
*/
virtual bool setRegister(UINT dAddr, UINT dData) = 0;
 
/**
* Initializes sound chip(clear registers)
* @retval true If succeeded
* @retval false If failed
*/
virtual bool init() = 0;
};
 
SoundInterfaceManager* GetSoundInterfaceManager();
 
} // namespace scci
/**
* @file scci.h
* @brief Sound Chip common Interface
*/
 
#pragma once
 
#include "SCCIDefines.h"
 
namespace scci
{
 
class SoundChip;
 
/**
* @brief Sound Interface Infomation
*/
struct SCCI_INTERFACE_INFO
{
OEMCHAR cInterfaceName[64]; /*!< Interface Name */
size_t iSoundChipCount; /*!< Sound Chip Count */
};
 
/**
* @brief Sound Chip Infomation
*/
struct SCCI_SOUND_CHIP_INFO
{
OEMCHAR cSoundChipName[64]; /*!< Sound Chip Name */
SC_CHIP_TYPE iSoundChip; /*!< Sound Chip ID */
SC_CHIP_TYPE iCompatibleSoundChip[2]; /*!< Compatible Sound Chip ID */
UINT dClock; /*!< Sound Chip clock */
UINT dCompatibleClock[2]; /*!< Sound Chip clock */
bool bIsUsed; /*!< Sound Chip Used Check */
UINT dBusID; /*!< Ú‘±ƒoƒXID */
SC_CHIP_LOCATION dSoundLocation; /*!< ƒTƒEƒ“ƒhƒƒP[ƒVƒ‡ƒ“ */
};
 
class SoundInterface;
 
/**
* @brief Sound Interface Manager
*/
class SoundInterfaceManager
{
public:
/**
* Gets the count of interfaces
* @return The count of interfaces
*/
virtual size_t getInterfaceCount() = 0;
 
/**
* Gets the information of the interface
* @param[in] iInterfaceNo The index of interfaces
* @return The information
*/
virtual const SCCI_INTERFACE_INFO* getInterfaceInfo(size_t iInterfaceNo) = 0;
 
/**
* Gets interface instance
* @param[in] iInterfaceNo The index of interfaces
* @return The instance
*/
virtual SoundInterface* getInterface(size_t iInterfaceNo) = 0;
 
/**
* Releases interface instance
* @param[in] pSoundInterface The instance of the interface
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseInterface(SoundInterface* pSoundInterface) = 0;
 
/**
* Release all interface instance
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseAllInterface() = 0;
 
/**
* Gets instance of the sound chip
* @param[in] iSoundChipType The type of the chip
* @param[in] dClock The clock of the chip
* @return The interface
*/
virtual SoundChip* getSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock) = 0;
 
/**
* Releases the instance of the sound chip
* @param[in] pSoundChip The instance of the sound chip
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseSoundChip(SoundChip* pSoundChip) = 0;
 
/**
* Releases all instances of the sound chip
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseAllSoundChip() = 0;
 
/**
* Sets delay time
* @param[in] dMSec delay time
* @retval true If succeeded
* @retval false If failed
*/
virtual bool setDelay(UINT dMSec) = 0;
 
/**
* Gets delay time
* @return delay time
*/
virtual UINT getDelay() = 0;
 
/**
* Resets all interfaces
* @retval true If succeeded
* @retval false If failed
*/
virtual bool reset() = 0;
 
/**
* Sound Interface instance initialize
* @retval true If succeeded
* @retval false If failed
*/
virtual bool initializeInstance() = 0;
 
/**
* Sound Interface instance release
* @retval true If succeeded
* @retval false If failed
*/
virtual bool releaseInstance() = 0;
};
 
/**
* @brief Sound Interface(LOW level APIs)
*/
class SoundInterface
{
public:
/**
* Is supported low level API
* @retval true yes
* @retval false no
*/
virtual bool isSupportLowLevelApi() = 0;
 
/**
* Sends data to the interface
* @param[in] pData The buffer of data
* @param[in] dSendDataLen The length of data
* @retval true If succeeded
* @retval false If failed
*/
virtual bool setData(const unsigned char* pData, size_t dSendDataLen) = 0;
 
/**
* Gets data from the interface
* @param[out] pData The buffer of data
* @param[in] dGetDataLen The length of data
* @return The size of read
*/
virtual size_t getData(unsigned char* pData, size_t dGetDataLen) = 0;
 
/**
* Sets delay time
* @param[in] dDelay delay time
* @retval true If succeeded
* @retval false If failed
*/
virtual bool setDelay(UINT dDelay) = 0;
 
/**
* Gets delay time
* @return delay time
*/
virtual UINT getDelay() = 0;
 
/**
* Resets the interface
* @retval true If succeeded
* @retval false If failed
*/
virtual bool reset() = 0;
};
 
/**
* @brief Sound Chip
*/
class SoundChip
{
public:
/**
* Gets the informations of the sound chip
* @return The pointer of informations
*/
virtual const SCCI_SOUND_CHIP_INFO* getSoundChipInfo() = 0;
 
/**
* Gets sound chip type
* @return The type of the chip
*/
virtual SC_CHIP_TYPE getSoundChipType() = 0;
 
/**
* Sets Register data
* Writes the register
* @param[in] dAddr The address of register
* @param[in] dData The data
* @retval true If succeeded
* @retval false If failed
*/
virtual bool setRegister(UINT dAddr, UINT dData) = 0;
 
/**
* Initializes sound chip(clear registers)
* @retval true If succeeded
* @retval false If failed
*/
virtual bool init() = 0;
};
 
SoundInterfaceManager* GetSoundInterfaceManager();
 
} // namespace scci
/np21/x11/ext/scci/sccisoundinterfacemanager.cpp
@@ -1,337 +1,337 @@
/**
* @file sccisoundinterfacemanager.cpp
* @brief Implementation of manager
*/
 
#include "compiler.h"
#include "sccisoundinterfacemanager.h"
#include <algorithm>
#include "sccisoundinterface.h"
#include "sccispfmlight.h"
#include "dosio.h"
#include "common/profile.h"
 
namespace scci
{
 
//! Singleton instance
CSoundInterfaceManager CSoundInterfaceManager::sm_instance;
 
/**
* Gets instance
* @return The instance of sound manager
*/
SoundInterfaceManager* GetSoundInterfaceManager()
{
return CSoundInterfaceManager::GetInstance();
}
 
/**
* Constructor
*/
CSoundInterfaceManager::CSoundInterfaceManager()
: m_nDelayTime(0)
{
}
 
/**
* Destructor
*/
CSoundInterfaceManager::~CSoundInterfaceManager()
{
}
 
/**
* Delete
* @param[in] pInterface The instance of the sound interface
*/
void CSoundInterfaceManager::Delete(CSoundInterface* pInterface)
{
std::vector<CSoundInterface*>::iterator it = std::find(m_interfaces.begin(), m_interfaces.end(), pInterface);
if (it != m_interfaces.end())
{
m_interfaces.erase(it);
}
}
 
/**
* Get the count of interfaces
* @return The count of interfaces
*/
size_t CSoundInterfaceManager::getInterfaceCount()
{
return m_interfaces.size();
}
 
/**
* Get the information of the interface
* @param[in] iInterfaceNo The index of interfaces
* @return The information
*/
const SCCI_INTERFACE_INFO* CSoundInterfaceManager::getInterfaceInfo(size_t iInterfaceNo)
{
if (iInterfaceNo < m_interfaces.size())
{
return m_interfaces[iInterfaceNo]->GetInfo();
}
else
{
return NULL;
}
}
 
/**
* Gets interface instance
* @param[in] iInterfaceNo The index of interfaces
* @return The instance
*/
SoundInterface* CSoundInterfaceManager::getInterface(size_t iInterfaceNo)
{
if (iInterfaceNo < m_interfaces.size())
{
CSoundInterface* pInterface = m_interfaces[iInterfaceNo];
m_attachedInterfaces.push_back(pInterface);
pInterface->AddRef();
return pInterface;
}
else
{
return NULL;
}
}
 
/**
* Releases the sound interface
* @param[in] pSoundInterface The instance of the sound interface
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseInterface(SoundInterface* pSoundInterface)
{
std::vector<CSoundInterface*>::iterator it = std::find(m_attachedInterfaces.begin(), m_attachedInterfaces.end(), pSoundInterface);
if (it != m_attachedInterfaces.end())
{
m_attachedInterfaces.erase(it);
static_cast<CSoundInterface*>(pSoundInterface)->Release();
return true;
}
else
{
return false;
}
}
 
/**
* Releases all interfaces
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseAllInterface()
{
while (!m_attachedInterfaces.empty())
{
releaseInterface(m_attachedInterfaces.back());
}
return true;
}
 
/**
* Gets sound chip instance
* @param[in] iSoundChipType The type of the chip
* @param[in] dClock The clock of the chip
* @return The interface
*/
SoundChip* CSoundInterfaceManager::getSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock)
{
if (iSoundChipType == SC_TYPE_NONE)
{
return NULL;
}
 
for (std::vector<CSoundInterface*>::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
{
SoundChip* pChip = (*it)->GetSoundChip(iSoundChipType, dClock);
if (pChip)
{
return pChip;
}
}
return NULL;
}
 
/**
* Releases the instance of the sound chip
* @param[in] pSoundChip The instance of the sound chip
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseSoundChip(SoundChip* pSoundChip)
{
delete static_cast<CSoundChip*>(pSoundChip);
return true;
}
 
/**
* Releases all instances of the sound chip
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseAllSoundChip()
{
return releaseAllInterface();
}
 
/**
* Sets delay time
* @param[in] dMSec delay time
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::setDelay(UINT dMSec)
{
if (dMSec > 10000)
{
return false;
}
m_nDelayTime = dMSec;
 
for (std::vector<CSoundInterface*>::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
{
(*it)->setDelay(dMSec);
}
return true;
}
 
/**
* Gets delay time
* @return delay time
*/
UINT CSoundInterfaceManager::getDelay()
{
return m_nDelayTime;
}
 
/**
* Resets all interfaces
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::reset()
{
bool err = false;
for (std::vector<CSoundInterface*>::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
{
if (!(*it)->reset())
{
err = true;
}
}
return !err;
}
 
/**
* Sound Interface instance initialize
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::initializeInstance()
{
OEMCHAR szPath[MAX_PATH];
milstr_ncpy(szPath, file_getcd(OEMTEXT("SCCI.ini")), NELEMENTS(szPath));
PFILEH pfh = profile_open(szPath, PFILEH_READONLY);
 
m_nDelayTime = profile_readint(OEMTEXT("scci"), OEMTEXT("DelayTime"), 0, pfh);
 
OEMCHAR szSections[4096];
if (profile_getsectionnames(szSections, NELEMENTS(szSections), pfh))
{
OEMCHAR* lpSections = szSections;
while (*lpSections != '\0')
{
OEMCHAR* lpKeyName = lpSections;
const size_t cchKeyName = OEMSTRLEN(lpSections);
lpSections += cchKeyName + 1;
 
if (milstr_memcmp(lpKeyName, OEMTEXT("SPFM Light")) != 0)
{
continue;
}
if ((lpKeyName[10] != '(') || (lpKeyName[cchKeyName - 1] != ')'))
{
continue;
}
 
if (profile_readint(lpKeyName, OEMTEXT("ACTIVE"), 0, pfh) == 0)
{
continue;
}
 
std::string deviceName(lpKeyName + 11, lpKeyName + cchKeyName - 1);
 
CSoundInterface* pInterface = new CSpfmLight(this, deviceName, m_nDelayTime);
if (!pInterface->Initialize())
{
delete pInterface;
continue;
}
 
for (UINT i = 0; i < 4; i++)
{
SCCI_SOUND_CHIP_INFO info;
memset(&info, 0, sizeof(info));
info.dBusID = i;
 
OEMCHAR szAppName[32];
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_NAME"), i);
profile_read(lpKeyName, szAppName, OEMTEXT(""), info.cSoundChipName, NELEMENTS(info.cSoundChipName), pfh);
 
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_ID"), i);
info.iSoundChip = static_cast<SC_CHIP_TYPE>(profile_readint(lpKeyName, szAppName, 0, pfh));
 
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_CLOCK"), i);
info.dClock = profile_readint(lpKeyName, szAppName, 0, pfh);
 
if (info.iSoundChip == 0)
{
continue;
}
 
for (UINT j = 0; j < 2; j++)
{
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_ID_CMP%d"), i, j + 1);
info.iCompatibleSoundChip[j] = static_cast<SC_CHIP_TYPE>(profile_readint(lpKeyName, szAppName, 0, pfh));
 
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_CLOCK_CMP%d"), i, j + 1);
info.dCompatibleClock[j] = profile_readint(lpKeyName, szAppName, 0, pfh);
}
 
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_LOCATION"), i);
info.dSoundLocation = static_cast<SC_CHIP_LOCATION>(profile_readint(lpKeyName, szAppName, 0, pfh));
 
pInterface->Add(info);
}
m_interfaces.push_back(pInterface);
}
}
profile_close(pfh);
 
return true;
}
 
/**
* Sound Interface instance release
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseInstance()
{
while (!m_interfaces.empty())
{
CSoundInterface* pInterface = m_interfaces.back();
m_interfaces.pop_back();
delete pInterface;
}
return true;
}
 
} // namespace scci
/**
* @file sccisoundinterfacemanager.cpp
* @brief Implementation of manager
*/
 
#include "compiler.h"
#include "sccisoundinterfacemanager.h"
#include <algorithm>
#include "sccisoundinterface.h"
#include "sccispfmlight.h"
#include "dosio.h"
#include "common/profile.h"
 
namespace scci
{
 
//! Singleton instance
CSoundInterfaceManager CSoundInterfaceManager::sm_instance;
 
/**
* Gets instance
* @return The instance of sound manager
*/
SoundInterfaceManager* GetSoundInterfaceManager()
{
return CSoundInterfaceManager::GetInstance();
}
 
/**
* Constructor
*/
CSoundInterfaceManager::CSoundInterfaceManager()
: m_nDelayTime(0)
{
}
 
/**
* Destructor
*/
CSoundInterfaceManager::~CSoundInterfaceManager()
{
}
 
/**
* Delete
* @param[in] pInterface The instance of the sound interface
*/
void CSoundInterfaceManager::Delete(CSoundInterface* pInterface)
{
std::vector<CSoundInterface*>::iterator it = std::find(m_interfaces.begin(), m_interfaces.end(), pInterface);
if (it != m_interfaces.end())
{
m_interfaces.erase(it);
}
}
 
/**
* Get the count of interfaces
* @return The count of interfaces
*/
size_t CSoundInterfaceManager::getInterfaceCount()
{
return m_interfaces.size();
}
 
/**
* Get the information of the interface
* @param[in] iInterfaceNo The index of interfaces
* @return The information
*/
const SCCI_INTERFACE_INFO* CSoundInterfaceManager::getInterfaceInfo(size_t iInterfaceNo)
{
if (iInterfaceNo < m_interfaces.size())
{
return m_interfaces[iInterfaceNo]->GetInfo();
}
else
{
return NULL;
}
}
 
/**
* Gets interface instance
* @param[in] iInterfaceNo The index of interfaces
* @return The instance
*/
SoundInterface* CSoundInterfaceManager::getInterface(size_t iInterfaceNo)
{
if (iInterfaceNo < m_interfaces.size())
{
CSoundInterface* pInterface = m_interfaces[iInterfaceNo];
m_attachedInterfaces.push_back(pInterface);
pInterface->AddRef();
return pInterface;
}
else
{
return NULL;
}
}
 
/**
* Releases the sound interface
* @param[in] pSoundInterface The instance of the sound interface
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseInterface(SoundInterface* pSoundInterface)
{
std::vector<CSoundInterface*>::iterator it = std::find(m_attachedInterfaces.begin(), m_attachedInterfaces.end(), pSoundInterface);
if (it != m_attachedInterfaces.end())
{
m_attachedInterfaces.erase(it);
static_cast<CSoundInterface*>(pSoundInterface)->Release();
return true;
}
else
{
return false;
}
}
 
/**
* Releases all interfaces
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseAllInterface()
{
while (!m_attachedInterfaces.empty())
{
releaseInterface(m_attachedInterfaces.back());
}
return true;
}
 
/**
* Gets sound chip instance
* @param[in] iSoundChipType The type of the chip
* @param[in] dClock The clock of the chip
* @return The interface
*/
SoundChip* CSoundInterfaceManager::getSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock)
{
if (iSoundChipType == SC_TYPE_NONE)
{
return NULL;
}
 
for (std::vector<CSoundInterface*>::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
{
SoundChip* pChip = (*it)->GetSoundChip(iSoundChipType, dClock);
if (pChip)
{
return pChip;
}
}
return NULL;
}
 
/**
* Releases the instance of the sound chip
* @param[in] pSoundChip The instance of the sound chip
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseSoundChip(SoundChip* pSoundChip)
{
delete static_cast<CSoundChip*>(pSoundChip);
return true;
}
 
/**
* Releases all instances of the sound chip
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseAllSoundChip()
{
return releaseAllInterface();
}
 
/**
* Sets delay time
* @param[in] dMSec delay time
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::setDelay(UINT dMSec)
{
if (dMSec > 10000)
{
return false;
}
m_nDelayTime = dMSec;
 
for (std::vector<CSoundInterface*>::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
{
(*it)->setDelay(dMSec);
}
return true;
}
 
/**
* Gets delay time
* @return delay time
*/
UINT CSoundInterfaceManager::getDelay()
{
return m_nDelayTime;
}
 
/**
* Resets all interfaces
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::reset()
{
bool err = false;
for (std::vector<CSoundInterface*>::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it)
{
if (!(*it)->reset())
{
err = true;
}
}
return !err;
}
 
/**
* Sound Interface instance initialize
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::initializeInstance()
{
OEMCHAR szPath[MAX_PATH];
milstr_ncpy(szPath, file_getcd(OEMTEXT("SCCI.ini")), NELEMENTS(szPath));
PFILEH pfh = profile_open(szPath, PFILEH_READONLY);
 
m_nDelayTime = profile_readint(OEMTEXT("scci"), OEMTEXT("DelayTime"), 0, pfh);
 
OEMCHAR szSections[4096];
if (profile_getsectionnames(szSections, NELEMENTS(szSections), pfh))
{
OEMCHAR* lpSections = szSections;
while (*lpSections != '\0')
{
OEMCHAR* lpKeyName = lpSections;
const size_t cchKeyName = OEMSTRLEN(lpSections);
lpSections += cchKeyName + 1;
 
if (milstr_memcmp(lpKeyName, OEMTEXT("SPFM Light")) != 0)
{
continue;
}
if ((lpKeyName[10] != '(') || (lpKeyName[cchKeyName - 1] != ')'))
{
continue;
}
 
if (profile_readint(lpKeyName, OEMTEXT("ACTIVE"), 0, pfh) == 0)
{
continue;
}
 
std::string deviceName(lpKeyName + 11, lpKeyName + cchKeyName - 1);
 
CSoundInterface* pInterface = new CSpfmLight(this, deviceName, m_nDelayTime);
if (!pInterface->Initialize())
{
delete pInterface;
continue;
}
 
for (UINT i = 0; i < 4; i++)
{
SCCI_SOUND_CHIP_INFO info;
memset(&info, 0, sizeof(info));
info.dBusID = i;
 
OEMCHAR szAppName[32];
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_NAME"), i);
profile_read(lpKeyName, szAppName, OEMTEXT(""), info.cSoundChipName, NELEMENTS(info.cSoundChipName), pfh);
 
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_ID"), i);
info.iSoundChip = static_cast<SC_CHIP_TYPE>(profile_readint(lpKeyName, szAppName, 0, pfh));
 
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_CLOCK"), i);
info.dClock = profile_readint(lpKeyName, szAppName, 0, pfh);
 
if (info.iSoundChip == 0)
{
continue;
}
 
for (UINT j = 0; j < 2; j++)
{
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_ID_CMP%d"), i, j + 1);
info.iCompatibleSoundChip[j] = static_cast<SC_CHIP_TYPE>(profile_readint(lpKeyName, szAppName, 0, pfh));
 
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_CLOCK_CMP%d"), i, j + 1);
info.dCompatibleClock[j] = profile_readint(lpKeyName, szAppName, 0, pfh);
}
 
OEMSPRINTF(szAppName, OEMTEXT("SLOT_%02d_CHIP_LOCATION"), i);
info.dSoundLocation = static_cast<SC_CHIP_LOCATION>(profile_readint(lpKeyName, szAppName, 0, pfh));
 
pInterface->Add(info);
}
m_interfaces.push_back(pInterface);
}
}
profile_close(pfh);
 
return true;
}
 
/**
* Sound Interface instance release
* @retval true If succeeded
* @retval false If failed
*/
bool CSoundInterfaceManager::releaseInstance()
{
while (!m_interfaces.empty())
{
CSoundInterface* pInterface = m_interfaces.back();
m_interfaces.pop_back();
delete pInterface;
}
return true;
}
 
} // namespace scci
/np21/x11/ext/scci/sccisoundinterface.cpp
@@ -1,117 +1,117 @@
/**
* @file sccisoundinterface.cpp
* @brief Implementation of sound interfaces
*/
 
#include "compiler.h"
#include "sccisoundinterface.h"
#include "sccisoundchip.h"
#include "sccisoundinterfacemanager.h"
 
namespace scci
{
 
/**
* Constructor
* @param[in] pManager The instance of the manager
* @param[in] deviceName The information
*/
CSoundInterface::CSoundInterface(CSoundInterfaceManager* pManager, const std::oemstring& deviceName)
: m_nRef(0)
, m_pManager(pManager)
{
memset(&m_info, 0, sizeof(m_info));
 
milstr_ncpy(m_info.cInterfaceName, deviceName.c_str(), NELEMENTS(m_info.cInterfaceName));
m_info.iSoundChipCount = 0;
}
 
/**
* Destructor
*/
CSoundInterface::~CSoundInterface()
{
while (!m_chips.empty())
{
delete m_chips.begin()->second;
}
m_pManager->Delete(this);
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CSoundInterface::AddRef()
{
m_nRef++;
return m_nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CSoundInterface::Release()
{
if (m_nRef)
{
m_nRef--;
}
return m_nRef;
}
 
/**
* Release
*/
void CSoundInterface::ReleaseAllChips()
{
for (std::map<UINT, CSoundChip*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
it->second->Release();
}
}
 
/**
* Get the chip
* @param[in] iSoundChipType The type of the chip
* @param[in] dClock The clock of the chip
* @return The instance of the chip
*/
SoundChip* CSoundInterface::GetSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock)
{
for (std::map<UINT, CSoundChip*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
CSoundChip* pChip = it->second;
if (!pChip->IsMatch(iSoundChipType, dClock))
{
continue;
}
 
SCCI_SOUND_CHIP_INFO* pInfo = pChip->GetSoundChipInfo();
if (pInfo->bIsUsed)
{
continue;
}
pInfo->bIsUsed = true;
AddRef();
return pChip;
}
return NULL;
}
 
/**
* Delete
* @param[in] dBusID Then number of the slot
*/
void CSoundInterface::Delete(UINT dBusID)
{
std::map<UINT, CSoundChip*>::iterator it = m_chips.find(dBusID);
if (it != m_chips.end())
{
m_chips.erase(it);
m_info.iSoundChipCount--;
}
}
 
} // namespace scci
/**
* @file sccisoundinterface.cpp
* @brief Implementation of sound interfaces
*/
 
#include "compiler.h"
#include "sccisoundinterface.h"
#include "sccisoundchip.h"
#include "sccisoundinterfacemanager.h"
 
namespace scci
{
 
/**
* Constructor
* @param[in] pManager The instance of the manager
* @param[in] deviceName The information
*/
CSoundInterface::CSoundInterface(CSoundInterfaceManager* pManager, const std::oemstring& deviceName)
: m_nRef(0)
, m_pManager(pManager)
{
memset(&m_info, 0, sizeof(m_info));
 
milstr_ncpy(m_info.cInterfaceName, deviceName.c_str(), NELEMENTS(m_info.cInterfaceName));
m_info.iSoundChipCount = 0;
}
 
/**
* Destructor
*/
CSoundInterface::~CSoundInterface()
{
while (!m_chips.empty())
{
delete m_chips.begin()->second;
}
m_pManager->Delete(this);
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CSoundInterface::AddRef()
{
m_nRef++;
return m_nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CSoundInterface::Release()
{
if (m_nRef)
{
m_nRef--;
}
return m_nRef;
}
 
/**
* Release
*/
void CSoundInterface::ReleaseAllChips()
{
for (std::map<UINT, CSoundChip*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
it->second->Release();
}
}
 
/**
* Get the chip
* @param[in] iSoundChipType The type of the chip
* @param[in] dClock The clock of the chip
* @return The instance of the chip
*/
SoundChip* CSoundInterface::GetSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock)
{
for (std::map<UINT, CSoundChip*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
CSoundChip* pChip = it->second;
if (!pChip->IsMatch(iSoundChipType, dClock))
{
continue;
}
 
SCCI_SOUND_CHIP_INFO* pInfo = pChip->GetSoundChipInfo();
if (pInfo->bIsUsed)
{
continue;
}
pInfo->bIsUsed = true;
AddRef();
return pChip;
}
return NULL;
}
 
/**
* Delete
* @param[in] dBusID Then number of the slot
*/
void CSoundInterface::Delete(UINT dBusID)
{
std::map<UINT, CSoundChip*>::iterator it = m_chips.find(dBusID);
if (it != m_chips.end())
{
m_chips.erase(it);
m_info.iSoundChipCount--;
}
}
 
} // namespace scci
/np21/x11/ext/scci/sccisoundinterfacemanager.h
@@ -1,60 +1,60 @@
/**
* @file sccisoundinterfacemanager.h
* @brief Interface of the SCCI manager
*/
 
#pragma once
 
#include <vector>
#include "scci.h"
 
namespace scci
{
 
class CSoundInterface;
 
/**
* @brief The class of the sound interface manager
*/
class CSoundInterfaceManager : public SoundInterfaceManager
{
public:
static CSoundInterfaceManager* GetInstance();
 
virtual size_t getInterfaceCount();
virtual const SCCI_INTERFACE_INFO* getInterfaceInfo(size_t iInterfaceNo);
virtual SoundInterface* getInterface(size_t iInterfaceNo);
virtual bool releaseInterface(SoundInterface* pSoundInterface);
virtual bool releaseAllInterface();
virtual SoundChip* getSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock);
virtual bool releaseSoundChip(SoundChip* pSoundChip);
virtual bool releaseAllSoundChip();
virtual bool setDelay(UINT dMSec);
virtual UINT getDelay();
virtual bool reset();
virtual bool initializeInstance();
virtual bool releaseInstance();
 
private:
static CSoundInterfaceManager sm_instance; /*!< Singleton */
UINT m_nDelayTime; /*!< Delay time */
std::vector<CSoundInterface*> m_interfaces; /*!< The list of interfaces */
std::vector<CSoundInterface*> m_attachedInterfaces; /*!< The list of attached interfaces */
 
CSoundInterfaceManager();
~CSoundInterfaceManager();
void Delete(CSoundInterface* pInterface);
 
friend class CSoundInterface;
};
 
/**
* Gets instance
* @return The instance of sound manager
*/
inline CSoundInterfaceManager* CSoundInterfaceManager::GetInstance()
{
return &sm_instance;
}
 
} // namespace scci
/**
* @file sccisoundinterfacemanager.h
* @brief Interface of the SCCI manager
*/
 
#pragma once
 
#include <vector>
#include "scci.h"
 
namespace scci
{
 
class CSoundInterface;
 
/**
* @brief The class of the sound interface manager
*/
class CSoundInterfaceManager : public SoundInterfaceManager
{
public:
static CSoundInterfaceManager* GetInstance();
 
virtual size_t getInterfaceCount();
virtual const SCCI_INTERFACE_INFO* getInterfaceInfo(size_t iInterfaceNo);
virtual SoundInterface* getInterface(size_t iInterfaceNo);
virtual bool releaseInterface(SoundInterface* pSoundInterface);
virtual bool releaseAllInterface();
virtual SoundChip* getSoundChip(SC_CHIP_TYPE iSoundChipType, UINT dClock);
virtual bool releaseSoundChip(SoundChip* pSoundChip);
virtual bool releaseAllSoundChip();
virtual bool setDelay(UINT dMSec);
virtual UINT getDelay();
virtual bool reset();
virtual bool initializeInstance();
virtual bool releaseInstance();
 
private:
static CSoundInterfaceManager sm_instance; /*!< Singleton */
UINT m_nDelayTime; /*!< Delay time */
std::vector<CSoundInterface*> m_interfaces; /*!< The list of interfaces */
std::vector<CSoundInterface*> m_attachedInterfaces; /*!< The list of attached interfaces */
 
CSoundInterfaceManager();
~CSoundInterfaceManager();
void Delete(CSoundInterface* pInterface);
 
friend class CSoundInterface;
};
 
/**
* Gets instance
* @return The instance of sound manager
*/
inline CSoundInterfaceManager* CSoundInterfaceManager::GetInstance()
{
return &sm_instance;
}
 
} // namespace scci
/np21/x11/ext/externalchipmanager.cpp
@@ -1,188 +1,188 @@
/**
* @file externalchipmanager.cpp
* @brief ŠO•”ƒ`ƒbƒvŠÇ—ƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalchipmanager.h"
#include <algorithm>
#include "externalopl3.h"
#include "externalopm.h"
#include "externalopna.h"
 
/*! —Bˆê‚̃Cƒ“ƒXƒ^ƒ“ƒX‚Å‚· */
CExternalChipManager CExternalChipManager::sm_instance;
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
*/
CExternalChipManager::CExternalChipManager()
{
}
 
/**
* ‰Šú‰»
*/
void CExternalChipManager::Initialize()
{
}
 
/**
* ‰ð•ú
*/
void CExternalChipManager::Deinitialize()
{
std::vector<IExternalChip*>::iterator it = m_chips.begin();
while (it != m_chips.end())
{
IExternalChip* pChip = *it;
it = m_chips.erase(it);
 
pChip->Reset();
delete pChip;
}
 
m_c86ctl.Deinitialize();
m_scci.Deinitialize();
}
 
/**
* ƒ`ƒbƒvŠm•Û
* @param[in] nChipType ƒ`ƒbƒv ƒ^ƒCƒv
* @param[in] nClock ƒ`ƒbƒv ƒNƒƒbƒN
* @return ƒCƒ“ƒXƒ^ƒ“ƒX
*/
IExternalChip* CExternalChipManager::GetInterface(IExternalChip::ChipType nChipType, UINT nClock)
{
IExternalChip* pChip = GetInterfaceInner(nChipType, nClock);
if (pChip == NULL)
{
switch (nChipType)
{
case IExternalChip::kAY8910:
pChip = GetInterface(IExternalChip::kYM2203, nClock);
break;
 
case IExternalChip::kYM2203:
pChip = GetInterface(IExternalChip::kYMF288, nClock * 2);
break;
 
case IExternalChip::kYMF288:
pChip = GetInterface(IExternalChip::kYM2608, nClock);
break;
 
case IExternalChip::kYM3438:
pChip = GetInterface(IExternalChip::kYMF288, nClock);
break;
 
case IExternalChip::kY8950:
pChip = GetInterface(IExternalChip::kYM3812, nClock);
break;
 
case IExternalChip::kYM3812:
pChip = GetInterface(IExternalChip::kYMF262, nClock * 4);
break;
 
default:
break;
}
}
return pChip;
}
 
/**
* ƒ`ƒbƒvŠm•Û (Inner)
* @param[in] nChipType ƒ`ƒbƒv ƒ^ƒCƒv
* @param[in] nClock ƒ`ƒbƒv ƒNƒƒbƒN
* @return ƒCƒ“ƒXƒ^ƒ“ƒX
*/
IExternalChip* CExternalChipManager::GetInterfaceInner(IExternalChip::ChipType nChipType, UINT nClock)
{
IExternalChip* pChip = NULL;
 
/* G.I.M.I.C / C86BOX */
if (pChip == NULL)
{
pChip = m_c86ctl.GetInterface(nChipType, nClock);
}
 
/* SPFM Light */
if (pChip == NULL)
{
pChip = m_scci.GetInterface(nChipType, nClock);
}
 
/* ƒ‰ƒbƒsƒ“ƒO */
if (pChip)
{
switch (nChipType)
{
case IExternalChip::kAY8910:
pChip = new CExternalPsg(pChip);
break;
 
case IExternalChip::kYM2203:
case IExternalChip::kYM2608:
case IExternalChip::kYM3438:
case IExternalChip::kYMF288:
pChip = new CExternalOpna(pChip);
break;
 
case IExternalChip::kYM3812:
case IExternalChip::kYMF262:
case IExternalChip::kY8950:
pChip = new CExternalOpl3(pChip);
break;
 
case IExternalChip::kYM2151:
pChip = new CExternalOpm(pChip);
break;
 
default:
break;
}
}
if (pChip)
{
m_chips.push_back(pChip);
}
return pChip;
}
 
/**
* ƒ`ƒbƒv‰ð•ú
* @param[in] pChip ƒ`ƒbƒv
*/
void CExternalChipManager::Release(IExternalChip* pChip)
{
std::vector<IExternalChip*>::iterator it = std::find(m_chips.begin(), m_chips.end(), pChip);
if (it != m_chips.end())
{
m_chips.erase(it);
pChip->Reset();
delete pChip;
}
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalChipManager::Reset()
{
for (std::vector<IExternalChip*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
(*it)->Reset();
}
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalChipManager::Mute(bool bMute)
{
for (std::vector<IExternalChip*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
(*it)->Message(IExternalChip::kMute, static_cast<INTPTR>(bMute));
}
}
/**
* @file externalchipmanager.cpp
* @brief ŠO•”ƒ`ƒbƒvŠÇ—ƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "externalchipmanager.h"
#include <algorithm>
#include "externalopl3.h"
#include "externalopm.h"
#include "externalopna.h"
 
/*! —Bˆê‚̃Cƒ“ƒXƒ^ƒ“ƒX‚Å‚· */
CExternalChipManager CExternalChipManager::sm_instance;
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
*/
CExternalChipManager::CExternalChipManager()
{
}
 
/**
* ‰Šú‰»
*/
void CExternalChipManager::Initialize()
{
}
 
/**
* ‰ð•ú
*/
void CExternalChipManager::Deinitialize()
{
std::vector<IExternalChip*>::iterator it = m_chips.begin();
while (it != m_chips.end())
{
IExternalChip* pChip = *it;
it = m_chips.erase(it);
 
pChip->Reset();
delete pChip;
}
 
m_c86ctl.Deinitialize();
m_scci.Deinitialize();
}
 
/**
* ƒ`ƒbƒvŠm•Û
* @param[in] nChipType ƒ`ƒbƒv ƒ^ƒCƒv
* @param[in] nClock ƒ`ƒbƒv ƒNƒƒbƒN
* @return ƒCƒ“ƒXƒ^ƒ“ƒX
*/
IExternalChip* CExternalChipManager::GetInterface(IExternalChip::ChipType nChipType, UINT nClock)
{
IExternalChip* pChip = GetInterfaceInner(nChipType, nClock);
if (pChip == NULL)
{
switch (nChipType)
{
case IExternalChip::kAY8910:
pChip = GetInterface(IExternalChip::kYM2203, nClock);
break;
 
case IExternalChip::kYM2203:
pChip = GetInterface(IExternalChip::kYMF288, nClock * 2);
break;
 
case IExternalChip::kYMF288:
pChip = GetInterface(IExternalChip::kYM2608, nClock);
break;
 
case IExternalChip::kYM3438:
pChip = GetInterface(IExternalChip::kYMF288, nClock);
break;
 
case IExternalChip::kY8950:
pChip = GetInterface(IExternalChip::kYM3812, nClock);
break;
 
case IExternalChip::kYM3812:
pChip = GetInterface(IExternalChip::kYMF262, nClock * 4);
break;
 
default:
break;
}
}
return pChip;
}
 
/**
* ƒ`ƒbƒvŠm•Û (Inner)
* @param[in] nChipType ƒ`ƒbƒv ƒ^ƒCƒv
* @param[in] nClock ƒ`ƒbƒv ƒNƒƒbƒN
* @return ƒCƒ“ƒXƒ^ƒ“ƒX
*/
IExternalChip* CExternalChipManager::GetInterfaceInner(IExternalChip::ChipType nChipType, UINT nClock)
{
IExternalChip* pChip = NULL;
 
/* G.I.M.I.C / C86BOX */
if (pChip == NULL)
{
pChip = m_c86ctl.GetInterface(nChipType, nClock);
}
 
/* SPFM Light */
if (pChip == NULL)
{
pChip = m_scci.GetInterface(nChipType, nClock);
}
 
/* ƒ‰ƒbƒsƒ“ƒO */
if (pChip)
{
switch (nChipType)
{
case IExternalChip::kAY8910:
pChip = new CExternalPsg(pChip);
break;
 
case IExternalChip::kYM2203:
case IExternalChip::kYM2608:
case IExternalChip::kYM3438:
case IExternalChip::kYMF288:
pChip = new CExternalOpna(pChip);
break;
 
case IExternalChip::kYM3812:
case IExternalChip::kYMF262:
case IExternalChip::kY8950:
pChip = new CExternalOpl3(pChip);
break;
 
case IExternalChip::kYM2151:
pChip = new CExternalOpm(pChip);
break;
 
default:
break;
}
}
if (pChip)
{
m_chips.push_back(pChip);
}
return pChip;
}
 
/**
* ƒ`ƒbƒv‰ð•ú
* @param[in] pChip ƒ`ƒbƒv
*/
void CExternalChipManager::Release(IExternalChip* pChip)
{
std::vector<IExternalChip*>::iterator it = std::find(m_chips.begin(), m_chips.end(), pChip);
if (it != m_chips.end())
{
m_chips.erase(it);
pChip->Reset();
delete pChip;
}
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void CExternalChipManager::Reset()
{
for (std::vector<IExternalChip*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
(*it)->Reset();
}
}
 
/**
* ƒ~ƒ…[ƒg
* @param[in] bMute ƒ~ƒ…[ƒg
*/
void CExternalChipManager::Mute(bool bMute)
{
for (std::vector<IExternalChip*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
(*it)->Message(IExternalChip::kMute, static_cast<INTPTR>(bMute));
}
}
/np21/x11/ext/externalpsg.h
@@ -1,29 +1,29 @@
/**
* @file externalpsg.h
* @brief ŠO•” PSG ‰‰‘tƒNƒ‰ƒX‚̐錾‚¨‚æ‚уCƒ“ƒ^[ƒtƒFƒCƒX‚Ì’è‹`‚ð‚µ‚Ü‚·
*/
 
#pragma once
 
#include "externalchip.h"
 
/**
* @brief ŠO•” PSG ‰‰‘tƒNƒ‰ƒX
*/
class CExternalPsg : public IExternalChip
{
public:
CExternalPsg(IExternalChip* pChip);
virtual ~CExternalPsg();
virtual ChipType GetChipType();
virtual void Reset();
virtual void WriteRegister(UINT nAddr, UINT8 cData);
virtual INTPTR Message(UINT nMessage, INTPTR nParameter);
 
protected:
IExternalChip* m_pChip; //!< ƒ`ƒbƒv
UINT8 m_cPsgMix; //!< PSG ƒ~ƒLƒT[
 
virtual void Mute(bool bMute) const;
void WriteRegisterInner(UINT nAddr, UINT8 cData) const;
};
/**
* @file externalpsg.h
* @brief ŠO•” PSG ‰‰‘tƒNƒ‰ƒX‚̐錾‚¨‚æ‚уCƒ“ƒ^[ƒtƒFƒCƒX‚Ì’è‹`‚ð‚µ‚Ü‚·
*/
 
#pragma once
 
#include "externalchip.h"
 
/**
* @brief ŠO•” PSG ‰‰‘tƒNƒ‰ƒX
*/
class CExternalPsg : public IExternalChip
{
public:
CExternalPsg(IExternalChip* pChip);
virtual ~CExternalPsg();
virtual ChipType GetChipType();
virtual void Reset();
virtual void WriteRegister(UINT nAddr, UINT8 cData);
virtual INTPTR Message(UINT nMessage, INTPTR nParameter);
 
protected:
IExternalChip* m_pChip; //!< ƒ`ƒbƒv
UINT8 m_cPsgMix; //!< PSG ƒ~ƒLƒT[
 
virtual void Mute(bool bMute) const;
void WriteRegisterInner(UINT nAddr, UINT8 cData) const;
};
/np21/x11/ext/c86ctl/c86ctlrealchipbase.h
@@ -1,59 +1,59 @@
/**
* @file c86ctlrealchipbase.h
* @brief Interface of IRealChipBase
*/
 
#pragma once
 
#include <vector>
#include "c86ctl.h"
 
namespace c86ctl
{
 
/**
* @brief The class of the chip base
*/
class CRealChipBase : public IRealChipBase
{
public:
/**
* @brief The class of the device
*/
class CDevice : public IRealChipBase
{
public:
virtual ~CDevice();
};
 
static CRealChipBase* GetInstance();
 
CRealChipBase();
virtual ~CRealChipBase();
 
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChipBase
virtual C86CtlErr initialize();
virtual C86CtlErr deinitialize();
virtual size_t getNumberOfChip();
virtual C86CtlErr getChipInterface(size_t id, IID riid, void** ppi);
 
private:
static CRealChipBase sm_instance; /*!< instance */
size_t m_nRef; /*!< The reference counter */
std::vector<CDevice*> m_devices; /*!< The instance of devices */
};
 
/**
* Gets instance
* @return The instance of sound manager
*/
inline CRealChipBase* CRealChipBase::GetInstance()
{
return &sm_instance;
}
 
} // namespace c86ctl
/**
* @file c86ctlrealchipbase.h
* @brief Interface of IRealChipBase
*/
 
#pragma once
 
#include <vector>
#include "c86ctl.h"
 
namespace c86ctl
{
 
/**
* @brief The class of the chip base
*/
class CRealChipBase : public IRealChipBase
{
public:
/**
* @brief The class of the device
*/
class CDevice : public IRealChipBase
{
public:
virtual ~CDevice();
};
 
static CRealChipBase* GetInstance();
 
CRealChipBase();
virtual ~CRealChipBase();
 
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChipBase
virtual C86CtlErr initialize();
virtual C86CtlErr deinitialize();
virtual size_t getNumberOfChip();
virtual C86CtlErr getChipInterface(size_t id, IID riid, void** ppi);
 
private:
static CRealChipBase sm_instance; /*!< instance */
size_t m_nRef; /*!< The reference counter */
std::vector<CDevice*> m_devices; /*!< The instance of devices */
};
 
/**
* Gets instance
* @return The instance of sound manager
*/
inline CRealChipBase* CRealChipBase::GetInstance()
{
return &sm_instance;
}
 
} // namespace c86ctl
/np21/x11/ext/c86ctl/c86ctlgimic.cpp
@@ -1,689 +1,689 @@
/**
* @file c86ctlgimic.cpp
* @brief Implementation of G.I.M.I.C
*/
 
#include "compiler.h"
#include "c86ctlgimic.h"
#include <algorithm>
 
namespace c86ctl
{
 
/**
* Constructor
* @param[in] nIndex The index
*/
CGimic::CGimic(UINT nIndex)
: m_nRef(1)
, m_nIndex(nIndex)
, m_nChipType(CHIP_UNKNOWN)
, m_nQueIndex(0)
, m_nQueCount(0)
{
}
 
/**
* Destructor
*/
CGimic::~CGimic()
{
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CGimic::AddRef()
{
m_nRef++;
return m_nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CGimic::Release()
{
m_nRef--;
return m_nRef;
}
 
/**
* Initialize
* @return C86CTL_ERR
*/
C86CtlErr CGimic::initialize()
{
if (!m_usb.Open(0x16c0, 0x05e5, m_nIndex))
{
return C86CTL_ERR_NODEVICE;
}
 
// Query G.I.M.I.C module info.
Devinfo info;
::memset(&info, 0, sizeof(info));
if (m_gimic2.getModuleInfo(&info) != 0)
{
m_usb.Close();
return C86CTL_ERR_NODEVICE;
}
 
printf("Found G.I.M.I.C!\n");
printf("Devname: %s\n", info.Devname);
printf(" Rev: %d\n", info.Rev);
printf(" Serial: %s\n", info.Serial);
 
if (!::memcmp(info.Devname, "GMC-OPN3L", 9))
{
m_nChipType = CHIP_OPN3L;
}
else if (!::memcmp(info.Devname, "GMC-OPM", 7))
{
m_nChipType = CHIP_OPM;
}
else if (!::memcmp(info.Devname, "GMC-OPNA", 8))
{
m_nChipType = CHIP_OPNA;
}
else if (!::memcmp(info.Devname, "GMC-OPL3", 8))
{
m_nChipType = CHIP_OPL3;
}
 
m_nQueIndex = 0;
m_nQueCount = 0;
Start();
return C86CTL_ERR_NONE;
}
 
/**
* Deinitialize
* @return C86CTL_ERR
*/
C86CtlErr CGimic::deinitialize()
{
Stop();
m_usb.Close();
 
m_nChipType = CHIP_UNKNOWN;
 
return C86CTL_ERR_NONE;
}
 
/**
* Gets the count of chips
* @return The chips
*/
size_t CGimic::getNumberOfChip()
{
return (m_nChipType != CHIP_UNKNOWN) ? 1 : 0;
}
 
/**
* Gets interfaces
* @param[in] id ID
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
C86CtlErr CGimic::getChipInterface(size_t id, IID riid, void** ppi)
{
if (ppi == NULL)
{
return C86CTL_ERR_INVALID_PARAM;
}
 
if (id != 0)
{
return C86CTL_ERR_NODEVICE;
}
 
switch (riid)
{
case IID_IRealChip:
case IID_IRealChip2:
case IID_IRealChip3:
m_chip3.AddRef();
*ppi = &m_chip3;
return C86CTL_ERR_NONE;
 
case IID_IGimic:
case IID_IGimic2:
m_gimic2.AddRef();
*ppi = &m_gimic2;
return C86CTL_ERR_NONE;
 
default:
break;
}
 
return C86CTL_ERR_UNSUPPORTED;
}
 
/**
* Sends and receives data from USB
* @param[in] lpOutput A pointer to the buffer that sends the data
* @param[in] cbOutput The number of bytes to be written
* @param[out] lpInput A pointer to the buffer that receives the data
* @param[in] cbInput The maximum number of bytes to be read
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Transaction(const void* lpOutput, int cbOutput, void* lpInput, int cbInput)
{
if (!m_usb.IsOpened())
{
return C86CTL_ERR_NODEVICE;
}
 
char sBuffer[64];
if ((lpOutput == NULL) || (cbOutput <= 0) || (cbOutput >= sizeof(sBuffer)))
{
return C86CTL_ERR_INVALID_PARAM;
}
 
::memcpy(sBuffer, lpOutput, cbOutput);
::memset(sBuffer + cbOutput, 0xff, sizeof(sBuffer) - cbOutput);
 
m_usbGuard.Enter();
int nResult = m_usb.WriteBulk(sBuffer, sizeof(sBuffer));
if ((nResult == sizeof(sBuffer)) && (cbInput > 0))
{
nResult = m_usb.ReadBulk(sBuffer, sizeof(sBuffer));
}
m_usbGuard.Leave();
 
if (nResult != sizeof(sBuffer))
{
return C86CTL_ERR_UNKNOWN;
}
 
if ((lpInput != NULL) && (cbInput > 0))
{
cbInput = (std::min)(cbInput, static_cast<int>(sizeof(sBuffer)));
::memcpy(lpInput, sBuffer, cbInput);
}
return C86CTL_ERR_NONE;
}
 
/**
* Gets the informations
* @param[in] cParam The parameter
* @param[out] pInfo A pointer to the informations
* @return C86CTL_ERR
*/
C86CtlErr CGimic::GetInfo(UINT8 cParam, Devinfo* pInfo)
{
UINT8 sData[3];
sData[0] = 0xfd;
sData[1] = 0x91;
sData[2] = cParam;
const C86CtlErr ret = Transaction(sData, sizeof(sData), pInfo, sizeof(*pInfo));
if ((ret == C86CTL_ERR_NONE) && (pInfo != NULL))
{
TailZeroFill(pInfo->Devname, sizeof(pInfo->Devname));
TailZeroFill(pInfo->Serial, sizeof(pInfo->Serial));
}
return ret;
}
 
/**
* Sets ZeroFill
* @param[in] lpBuffer A pointer to the buffer
* @param[in] cbBuffer The number of bytes
*/
void CGimic::TailZeroFill(char* lpBuffer, size_t cbBuffer)
{
while (cbBuffer > 0)
{
cbBuffer--;
if (lpBuffer[cbBuffer] == -1)
{
lpBuffer[cbBuffer] = '\0';
}
else if (lpBuffer[cbBuffer] != '\0')
{
break;
}
}
}
 
/**
* Reset
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Reset()
{
m_queGuard.Enter();
m_nQueIndex = 0;
m_nQueCount = 0;
m_queGuard.Leave();
 
static const UINT8 sData[2] = {0xfd, 0x82};
return Transaction(sData, sizeof(sData));
}
 
/**
* Remaps address
* @param[in] nAddr The address
* @return The remapped address
*/
UINT CGimic::GetChipAddr(UINT nAddr) const
{
switch (m_nChipType)
{
case CHIP_OPNA:
case CHIP_OPN3L:
if ((nAddr >= 0x100) && (nAddr <= 0x110))
{
nAddr -= 0x40;
}
break;
 
case CHIP_OPM:
if ((nAddr >= 0xfc) && (nAddr <= 0xff))
{
nAddr -= 0xe0;
}
break;
 
default:
break;
}
return nAddr;
}
 
/**
* Output
* @param[in] nAddr The address of registers
* @param[in] cData The data
*/
void CGimic::Out(UINT nAddr, UINT8 cData)
{
m_queGuard.Enter();
while (m_nQueCount >= NELEMENTS(m_que))
{
m_queGuard.Leave();
Delay(1000);
m_queGuard.Enter();
}
 
FMDATA& data = m_que[(m_nQueIndex + m_nQueCount) % NELEMENTS(m_que)];
data.wAddr = static_cast<UINT16>(nAddr);
data.cData = cData;
m_nQueCount++;
 
m_queGuard.Leave();
}
 
/**
* Thread
* @retval true Cont.
*/
bool CGimic::Task()
{
/* builds data */
UINT8 sData[64];
int nIndex = 0;
 
m_queGuard.Enter();
while (m_nQueCount)
{
const FMDATA& data = m_que[m_nQueIndex];
const UINT nAddr = data.wAddr;
const UINT8 cData = data.cData;
 
if (nAddr < 0xfc)
{
if ((nIndex + 2 + 1) >= NELEMENTS(sData))
{
break;
}
sData[nIndex++] = static_cast<UINT8>(nAddr & 0xff);
sData[nIndex++] = cData;
}
else if ((nAddr >= 0x100) && (nAddr <= 0x1fb))
{
if ((nIndex + 3 + 1) >= NELEMENTS(sData))
{
break;
}
sData[nIndex++] = 0xfe;
sData[nIndex++] = static_cast<UINT8>(nAddr & 0xff);
sData[nIndex++] = cData;
}
 
m_nQueIndex = (m_nQueIndex + 1) % NELEMENTS(m_que);
m_nQueCount--;
}
m_queGuard.Leave();
 
/* writes */
if (nIndex > 0)
{
Transaction(sData, nIndex);
}
else
{
Delay(1000);
}
return true;
}
 
/* IGimic2 */
 
/**
* Get the instance of the device
* @return The instance
*/
inline CGimic* CGimic::Gimic2::GetDevice()
{
return reinterpret_cast<CGimic*>(reinterpret_cast<INTPTR>(this) - offsetof(CGimic, m_gimic2));
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CGimic::Gimic2::AddRef()
{
return GetDevice()->AddRef();
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CGimic::Gimic2::Release()
{
return GetDevice()->Release();
}
 
/**
* Gets the informations of firm
* @param[out] pnMajor A pointer to the major
* @param[out] pnMinor A pointer to the minor
* @param[out] pnRev A pointer to the revision
* @param[out] pnBuild A pointer to the number of build
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getFWVer(UINT* pnMajor, UINT* pnMinor, UINT* pnRev, UINT* pnBuild)
{
static const UINT8 sData[2] = {0xfd, 0x92};
UINT8 sRecv[16];
const C86CtlErr ret = GetDevice()->Transaction(sData, sizeof(sData), sRecv, sizeof(sRecv));
if (ret == C86CTL_ERR_NONE)
{
if (pnMajor != NULL)
{
*pnMajor = (sRecv[0] << 0) | (sRecv[1] << 8) | (sRecv[2] << 16) | (sRecv[3] << 24);
}
if (pnMinor != NULL)
{
*pnMinor = (sRecv[4] << 0) | (sRecv[5] << 8) | (sRecv[6] << 16) | (sRecv[7] << 24);
}
if (pnRev != NULL)
{
*pnRev = (sRecv[8] << 0) | (sRecv[9] << 8) | (sRecv[10] << 16) | (sRecv[11] << 24);
}
if (pnBuild != NULL)
{
*pnBuild = (sRecv[12] << 0) | (sRecv[13] << 8) | (sRecv[14] << 16) | (sRecv[15] << 24);
}
}
return ret;
}
 
/**
* Gets the informations of the mother
* @param[out] pInfo A pointer to the informations
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getMBInfo(Devinfo* pInfo)
{
return GetDevice()->GetInfo(0xff, pInfo);
}
 
/**
* Gets the informations of modules
* @param[out] pInfo A pointer to the informations
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getModuleInfo(Devinfo* pInfo)
{
return GetDevice()->GetInfo(0, pInfo);
}
 
/**
* Sets the volumes of SSG
* @param[in] cVolume The volume
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::setSSGVolume(UINT8 cVolume)
{
if (GetDevice()->m_nChipType != CHIP_OPNA)
{
return C86CTL_ERR_UNSUPPORTED;
}
 
UINT8 sData[3];
sData[0] = 0xfd;
sData[1] = 0x84;
sData[2] = cVolume;
return GetDevice()->Transaction(sData, sizeof(sData));
}
 
/**
* Gets the volume of SSG
* @param[out] pcVolume A pointer of the volume
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getSSGVolume(UINT8* pcVolume)
{
if (GetDevice()->m_nChipType != CHIP_OPNA)
{
return C86CTL_ERR_UNSUPPORTED;
}
 
static const UINT8 sData[2] = {0xfd, 0x86};
return GetDevice()->Transaction(sData, sizeof(sData), pcVolume, sizeof(*pcVolume));
}
 
/**
* Sets the clock
* @param[in] nClock The clock
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::setPLLClock(UINT nClock)
{
const ChipType nChipType = GetDevice()->m_nChipType;
if ((nChipType != CHIP_OPNA) && (nChipType != CHIP_OPM) && (nChipType != CHIP_OPL3))
{
return C86CTL_ERR_UNSUPPORTED;
}
 
UINT8 sData[6];
sData[0] = 0xfd;
sData[1] = 0x83;
sData[2] = static_cast<UINT8>((nClock >> 0) & 0xff);
sData[3] = static_cast<UINT8>((nClock >> 8) & 0xff);
sData[4] = static_cast<UINT8>((nClock >> 16) & 0xff);
sData[5] = static_cast<UINT8>((nClock >> 24) & 0xff);
return GetDevice()->Transaction(sData, sizeof(sData));
}
 
/**
* Gets the clock
* @param[out] pnClock A pointer to the clock
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getPLLClock(UINT* pnClock)
{
const ChipType nChipType = GetDevice()->m_nChipType;
if ((nChipType != CHIP_OPNA) && (nChipType != CHIP_OPM) && (nChipType != CHIP_OPL3))
{
return C86CTL_ERR_UNSUPPORTED;
}
 
static const UINT8 sData[2] = {0xfd, 0x85};
UINT8 sRecv[4];
const C86CtlErr ret = GetDevice()->Transaction(sData, sizeof(sData), sRecv, sizeof(sRecv));
if ((ret == C86CTL_ERR_NONE) && (pnClock != NULL))
{
*pnClock = (sRecv[0] << 0) | (sRecv[1] << 8) | (sRecv[2] << 16) | (sRecv[3] << 24);
}
return ret;
}
 
/**
* Gets the type of the modules
* @param[out] pnType The type
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getModuleType(ChipType* pnType)
{
if (pnType != NULL)
{
*pnType = GetDevice()->m_nChipType;
}
return C86CTL_ERR_NONE;
}
 
/* IRealChip3 */
 
/**
* Get the instance of the device
* @return The instance
*/
inline CGimic* CGimic::Chip3::GetDevice()
{
return reinterpret_cast<CGimic*>(reinterpret_cast<INTPTR>(this) - offsetof(CGimic, m_chip3));
}
 
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CGimic::Chip3::AddRef()
{
return GetDevice()->AddRef();
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CGimic::Chip3::Release()
{
return GetDevice()->Release();
}
 
/**
* Reset
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Chip3::reset()
{
memset(m_sReg, 0, sizeof(m_sReg));
return GetDevice()->Reset();
}
 
/**
* Output
* @param[in] nAddr The address
* @param[in] cData The data
*/
void CGimic::Chip3::out(UINT nAddr, UINT8 cData)
{
if (nAddr >= sizeof(m_sReg))
{
return;
}
m_sReg[nAddr] = cData;
 
GetDevice()->Out(nAddr, cData);
}
 
/**
* Input
* @param[in] nAddr The address of registers
* @return The data
*/
UINT8 CGimic::Chip3::in(UINT nAddr)
{
if (nAddr < sizeof(m_sReg))
{
return m_sReg[nAddr];
}
return 0xff;
}
 
/**
* Gets the current status
* @param[in] nAddr The address
* @param[out] pcStatus The status
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Chip3::getChipStatus(UINT nAddr, UINT8* pcStatus)
{
UINT8 sData[3];
sData[0] = 0xfd;
sData[1] = 0x93;
sData[2] = static_cast<UINT8>(nAddr & 1);
UINT8 sRecv[4];
const C86CtlErr ret = GetDevice()->Transaction(sData, sizeof(sData), sRecv, sizeof(sRecv));
if ((ret == C86CTL_ERR_NONE) && (pcStatus != NULL))
{
*pcStatus = sRecv[0];
}
return ret;
}
 
/**
* Output
* @param[in] nAddr The address
* @param[in] cData The data
*/
void CGimic::Chip3::directOut(UINT nAddr, UINT8 cData)
{
if (nAddr >= sizeof(m_sReg))
{
return;
}
m_sReg[nAddr] = cData;
 
nAddr = GetDevice()->GetChipAddr(nAddr);
if (nAddr < 0xfc)
{
UINT8 sData[2];
sData[0] = static_cast<UINT8>(nAddr & 0xff);
sData[1] = cData;
GetDevice()->Transaction(sData, sizeof(sData));
}
else if ((nAddr >= 0x100) && (nAddr <= 0x1fb))
{
UINT8 sData[3];
sData[0] = 0xfe;
sData[1] = static_cast<UINT8>(nAddr & 0xff);
sData[2] = cData;
GetDevice()->Transaction(sData, sizeof(sData));
}
}
 
/**
* Gets the type of the chip
* @param[out] pnType A pointer of type
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Chip3::getChipType(ChipType* pnType)
{
if (pnType != NULL)
{
*pnType = GetDevice()->m_nChipType;
}
return C86CTL_ERR_NONE;
}
 
} // namespace c86ctl
/**
* @file c86ctlgimic.cpp
* @brief Implementation of G.I.M.I.C
*/
 
#include "compiler.h"
#include "c86ctlgimic.h"
#include <algorithm>
 
namespace c86ctl
{
 
/**
* Constructor
* @param[in] nIndex The index
*/
CGimic::CGimic(UINT nIndex)
: m_nRef(1)
, m_nIndex(nIndex)
, m_nChipType(CHIP_UNKNOWN)
, m_nQueIndex(0)
, m_nQueCount(0)
{
}
 
/**
* Destructor
*/
CGimic::~CGimic()
{
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CGimic::AddRef()
{
m_nRef++;
return m_nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CGimic::Release()
{
m_nRef--;
return m_nRef;
}
 
/**
* Initialize
* @return C86CTL_ERR
*/
C86CtlErr CGimic::initialize()
{
if (!m_usb.Open(0x16c0, 0x05e5, m_nIndex))
{
return C86CTL_ERR_NODEVICE;
}
 
// Query G.I.M.I.C module info.
Devinfo info;
::memset(&info, 0, sizeof(info));
if (m_gimic2.getModuleInfo(&info) != 0)
{
m_usb.Close();
return C86CTL_ERR_NODEVICE;
}
 
printf("Found G.I.M.I.C!\n");
printf("Devname: %s\n", info.Devname);
printf(" Rev: %d\n", info.Rev);
printf(" Serial: %s\n", info.Serial);
 
if (!::memcmp(info.Devname, "GMC-OPN3L", 9))
{
m_nChipType = CHIP_OPN3L;
}
else if (!::memcmp(info.Devname, "GMC-OPM", 7))
{
m_nChipType = CHIP_OPM;
}
else if (!::memcmp(info.Devname, "GMC-OPNA", 8))
{
m_nChipType = CHIP_OPNA;
}
else if (!::memcmp(info.Devname, "GMC-OPL3", 8))
{
m_nChipType = CHIP_OPL3;
}
 
m_nQueIndex = 0;
m_nQueCount = 0;
Start();
return C86CTL_ERR_NONE;
}
 
/**
* Deinitialize
* @return C86CTL_ERR
*/
C86CtlErr CGimic::deinitialize()
{
Stop();
m_usb.Close();
 
m_nChipType = CHIP_UNKNOWN;
 
return C86CTL_ERR_NONE;
}
 
/**
* Gets the count of chips
* @return The chips
*/
size_t CGimic::getNumberOfChip()
{
return (m_nChipType != CHIP_UNKNOWN) ? 1 : 0;
}
 
/**
* Gets interfaces
* @param[in] id ID
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
C86CtlErr CGimic::getChipInterface(size_t id, IID riid, void** ppi)
{
if (ppi == NULL)
{
return C86CTL_ERR_INVALID_PARAM;
}
 
if (id != 0)
{
return C86CTL_ERR_NODEVICE;
}
 
switch (riid)
{
case IID_IRealChip:
case IID_IRealChip2:
case IID_IRealChip3:
m_chip3.AddRef();
*ppi = &m_chip3;
return C86CTL_ERR_NONE;
 
case IID_IGimic:
case IID_IGimic2:
m_gimic2.AddRef();
*ppi = &m_gimic2;
return C86CTL_ERR_NONE;
 
default:
break;
}
 
return C86CTL_ERR_UNSUPPORTED;
}
 
/**
* Sends and receives data from USB
* @param[in] lpOutput A pointer to the buffer that sends the data
* @param[in] cbOutput The number of bytes to be written
* @param[out] lpInput A pointer to the buffer that receives the data
* @param[in] cbInput The maximum number of bytes to be read
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Transaction(const void* lpOutput, int cbOutput, void* lpInput, int cbInput)
{
if (!m_usb.IsOpened())
{
return C86CTL_ERR_NODEVICE;
}
 
char sBuffer[64];
if ((lpOutput == NULL) || (cbOutput <= 0) || (cbOutput >= sizeof(sBuffer)))
{
return C86CTL_ERR_INVALID_PARAM;
}
 
::memcpy(sBuffer, lpOutput, cbOutput);
::memset(sBuffer + cbOutput, 0xff, sizeof(sBuffer) - cbOutput);
 
m_usbGuard.Enter();
int nResult = m_usb.WriteBulk(sBuffer, sizeof(sBuffer));
if ((nResult == sizeof(sBuffer)) && (cbInput > 0))
{
nResult = m_usb.ReadBulk(sBuffer, sizeof(sBuffer));
}
m_usbGuard.Leave();
 
if (nResult != sizeof(sBuffer))
{
return C86CTL_ERR_UNKNOWN;
}
 
if ((lpInput != NULL) && (cbInput > 0))
{
cbInput = (std::min)(cbInput, static_cast<int>(sizeof(sBuffer)));
::memcpy(lpInput, sBuffer, cbInput);
}
return C86CTL_ERR_NONE;
}
 
/**
* Gets the informations
* @param[in] cParam The parameter
* @param[out] pInfo A pointer to the informations
* @return C86CTL_ERR
*/
C86CtlErr CGimic::GetInfo(UINT8 cParam, Devinfo* pInfo)
{
UINT8 sData[3];
sData[0] = 0xfd;
sData[1] = 0x91;
sData[2] = cParam;
const C86CtlErr ret = Transaction(sData, sizeof(sData), pInfo, sizeof(*pInfo));
if ((ret == C86CTL_ERR_NONE) && (pInfo != NULL))
{
TailZeroFill(pInfo->Devname, sizeof(pInfo->Devname));
TailZeroFill(pInfo->Serial, sizeof(pInfo->Serial));
}
return ret;
}
 
/**
* Sets ZeroFill
* @param[in] lpBuffer A pointer to the buffer
* @param[in] cbBuffer The number of bytes
*/
void CGimic::TailZeroFill(char* lpBuffer, size_t cbBuffer)
{
while (cbBuffer > 0)
{
cbBuffer--;
if (lpBuffer[cbBuffer] == -1)
{
lpBuffer[cbBuffer] = '\0';
}
else if (lpBuffer[cbBuffer] != '\0')
{
break;
}
}
}
 
/**
* Reset
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Reset()
{
m_queGuard.Enter();
m_nQueIndex = 0;
m_nQueCount = 0;
m_queGuard.Leave();
 
static const UINT8 sData[2] = {0xfd, 0x82};
return Transaction(sData, sizeof(sData));
}
 
/**
* Remaps address
* @param[in] nAddr The address
* @return The remapped address
*/
UINT CGimic::GetChipAddr(UINT nAddr) const
{
switch (m_nChipType)
{
case CHIP_OPNA:
case CHIP_OPN3L:
if ((nAddr >= 0x100) && (nAddr <= 0x110))
{
nAddr -= 0x40;
}
break;
 
case CHIP_OPM:
if ((nAddr >= 0xfc) && (nAddr <= 0xff))
{
nAddr -= 0xe0;
}
break;
 
default:
break;
}
return nAddr;
}
 
/**
* Output
* @param[in] nAddr The address of registers
* @param[in] cData The data
*/
void CGimic::Out(UINT nAddr, UINT8 cData)
{
m_queGuard.Enter();
while (m_nQueCount >= NELEMENTS(m_que))
{
m_queGuard.Leave();
Delay(1000);
m_queGuard.Enter();
}
 
FMDATA& data = m_que[(m_nQueIndex + m_nQueCount) % NELEMENTS(m_que)];
data.wAddr = static_cast<UINT16>(nAddr);
data.cData = cData;
m_nQueCount++;
 
m_queGuard.Leave();
}
 
/**
* Thread
* @retval true Cont.
*/
bool CGimic::Task()
{
/* builds data */
UINT8 sData[64];
int nIndex = 0;
 
m_queGuard.Enter();
while (m_nQueCount)
{
const FMDATA& data = m_que[m_nQueIndex];
const UINT nAddr = data.wAddr;
const UINT8 cData = data.cData;
 
if (nAddr < 0xfc)
{
if ((nIndex + 2 + 1) >= NELEMENTS(sData))
{
break;
}
sData[nIndex++] = static_cast<UINT8>(nAddr & 0xff);
sData[nIndex++] = cData;
}
else if ((nAddr >= 0x100) && (nAddr <= 0x1fb))
{
if ((nIndex + 3 + 1) >= NELEMENTS(sData))
{
break;
}
sData[nIndex++] = 0xfe;
sData[nIndex++] = static_cast<UINT8>(nAddr & 0xff);
sData[nIndex++] = cData;
}
 
m_nQueIndex = (m_nQueIndex + 1) % NELEMENTS(m_que);
m_nQueCount--;
}
m_queGuard.Leave();
 
/* writes */
if (nIndex > 0)
{
Transaction(sData, nIndex);
}
else
{
Delay(1000);
}
return true;
}
 
/* IGimic2 */
 
/**
* Get the instance of the device
* @return The instance
*/
inline CGimic* CGimic::Gimic2::GetDevice()
{
return reinterpret_cast<CGimic*>(reinterpret_cast<INTPTR>(this) - offsetof(CGimic, m_gimic2));
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CGimic::Gimic2::AddRef()
{
return GetDevice()->AddRef();
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CGimic::Gimic2::Release()
{
return GetDevice()->Release();
}
 
/**
* Gets the informations of firm
* @param[out] pnMajor A pointer to the major
* @param[out] pnMinor A pointer to the minor
* @param[out] pnRev A pointer to the revision
* @param[out] pnBuild A pointer to the number of build
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getFWVer(UINT* pnMajor, UINT* pnMinor, UINT* pnRev, UINT* pnBuild)
{
static const UINT8 sData[2] = {0xfd, 0x92};
UINT8 sRecv[16];
const C86CtlErr ret = GetDevice()->Transaction(sData, sizeof(sData), sRecv, sizeof(sRecv));
if (ret == C86CTL_ERR_NONE)
{
if (pnMajor != NULL)
{
*pnMajor = (sRecv[0] << 0) | (sRecv[1] << 8) | (sRecv[2] << 16) | (sRecv[3] << 24);
}
if (pnMinor != NULL)
{
*pnMinor = (sRecv[4] << 0) | (sRecv[5] << 8) | (sRecv[6] << 16) | (sRecv[7] << 24);
}
if (pnRev != NULL)
{
*pnRev = (sRecv[8] << 0) | (sRecv[9] << 8) | (sRecv[10] << 16) | (sRecv[11] << 24);
}
if (pnBuild != NULL)
{
*pnBuild = (sRecv[12] << 0) | (sRecv[13] << 8) | (sRecv[14] << 16) | (sRecv[15] << 24);
}
}
return ret;
}
 
/**
* Gets the informations of the mother
* @param[out] pInfo A pointer to the informations
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getMBInfo(Devinfo* pInfo)
{
return GetDevice()->GetInfo(0xff, pInfo);
}
 
/**
* Gets the informations of modules
* @param[out] pInfo A pointer to the informations
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getModuleInfo(Devinfo* pInfo)
{
return GetDevice()->GetInfo(0, pInfo);
}
 
/**
* Sets the volumes of SSG
* @param[in] cVolume The volume
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::setSSGVolume(UINT8 cVolume)
{
if (GetDevice()->m_nChipType != CHIP_OPNA)
{
return C86CTL_ERR_UNSUPPORTED;
}
 
UINT8 sData[3];
sData[0] = 0xfd;
sData[1] = 0x84;
sData[2] = cVolume;
return GetDevice()->Transaction(sData, sizeof(sData));
}
 
/**
* Gets the volume of SSG
* @param[out] pcVolume A pointer of the volume
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getSSGVolume(UINT8* pcVolume)
{
if (GetDevice()->m_nChipType != CHIP_OPNA)
{
return C86CTL_ERR_UNSUPPORTED;
}
 
static const UINT8 sData[2] = {0xfd, 0x86};
return GetDevice()->Transaction(sData, sizeof(sData), pcVolume, sizeof(*pcVolume));
}
 
/**
* Sets the clock
* @param[in] nClock The clock
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::setPLLClock(UINT nClock)
{
const ChipType nChipType = GetDevice()->m_nChipType;
if ((nChipType != CHIP_OPNA) && (nChipType != CHIP_OPM) && (nChipType != CHIP_OPL3))
{
return C86CTL_ERR_UNSUPPORTED;
}
 
UINT8 sData[6];
sData[0] = 0xfd;
sData[1] = 0x83;
sData[2] = static_cast<UINT8>((nClock >> 0) & 0xff);
sData[3] = static_cast<UINT8>((nClock >> 8) & 0xff);
sData[4] = static_cast<UINT8>((nClock >> 16) & 0xff);
sData[5] = static_cast<UINT8>((nClock >> 24) & 0xff);
return GetDevice()->Transaction(sData, sizeof(sData));
}
 
/**
* Gets the clock
* @param[out] pnClock A pointer to the clock
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getPLLClock(UINT* pnClock)
{
const ChipType nChipType = GetDevice()->m_nChipType;
if ((nChipType != CHIP_OPNA) && (nChipType != CHIP_OPM) && (nChipType != CHIP_OPL3))
{
return C86CTL_ERR_UNSUPPORTED;
}
 
static const UINT8 sData[2] = {0xfd, 0x85};
UINT8 sRecv[4];
const C86CtlErr ret = GetDevice()->Transaction(sData, sizeof(sData), sRecv, sizeof(sRecv));
if ((ret == C86CTL_ERR_NONE) && (pnClock != NULL))
{
*pnClock = (sRecv[0] << 0) | (sRecv[1] << 8) | (sRecv[2] << 16) | (sRecv[3] << 24);
}
return ret;
}
 
/**
* Gets the type of the modules
* @param[out] pnType The type
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Gimic2::getModuleType(ChipType* pnType)
{
if (pnType != NULL)
{
*pnType = GetDevice()->m_nChipType;
}
return C86CTL_ERR_NONE;
}
 
/* IRealChip3 */
 
/**
* Get the instance of the device
* @return The instance
*/
inline CGimic* CGimic::Chip3::GetDevice()
{
return reinterpret_cast<CGimic*>(reinterpret_cast<INTPTR>(this) - offsetof(CGimic, m_chip3));
}
 
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CGimic::Chip3::AddRef()
{
return GetDevice()->AddRef();
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CGimic::Chip3::Release()
{
return GetDevice()->Release();
}
 
/**
* Reset
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Chip3::reset()
{
memset(m_sReg, 0, sizeof(m_sReg));
return GetDevice()->Reset();
}
 
/**
* Output
* @param[in] nAddr The address
* @param[in] cData The data
*/
void CGimic::Chip3::out(UINT nAddr, UINT8 cData)
{
if (nAddr >= sizeof(m_sReg))
{
return;
}
m_sReg[nAddr] = cData;
 
GetDevice()->Out(nAddr, cData);
}
 
/**
* Input
* @param[in] nAddr The address of registers
* @return The data
*/
UINT8 CGimic::Chip3::in(UINT nAddr)
{
if (nAddr < sizeof(m_sReg))
{
return m_sReg[nAddr];
}
return 0xff;
}
 
/**
* Gets the current status
* @param[in] nAddr The address
* @param[out] pcStatus The status
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Chip3::getChipStatus(UINT nAddr, UINT8* pcStatus)
{
UINT8 sData[3];
sData[0] = 0xfd;
sData[1] = 0x93;
sData[2] = static_cast<UINT8>(nAddr & 1);
UINT8 sRecv[4];
const C86CtlErr ret = GetDevice()->Transaction(sData, sizeof(sData), sRecv, sizeof(sRecv));
if ((ret == C86CTL_ERR_NONE) && (pcStatus != NULL))
{
*pcStatus = sRecv[0];
}
return ret;
}
 
/**
* Output
* @param[in] nAddr The address
* @param[in] cData The data
*/
void CGimic::Chip3::directOut(UINT nAddr, UINT8 cData)
{
if (nAddr >= sizeof(m_sReg))
{
return;
}
m_sReg[nAddr] = cData;
 
nAddr = GetDevice()->GetChipAddr(nAddr);
if (nAddr < 0xfc)
{
UINT8 sData[2];
sData[0] = static_cast<UINT8>(nAddr & 0xff);
sData[1] = cData;
GetDevice()->Transaction(sData, sizeof(sData));
}
else if ((nAddr >= 0x100) && (nAddr <= 0x1fb))
{
UINT8 sData[3];
sData[0] = 0xfe;
sData[1] = static_cast<UINT8>(nAddr & 0xff);
sData[2] = cData;
GetDevice()->Transaction(sData, sizeof(sData));
}
}
 
/**
* Gets the type of the chip
* @param[out] pnType A pointer of type
* @return C86CTL_ERR
*/
C86CtlErr CGimic::Chip3::getChipType(ChipType* pnType)
{
if (pnType != NULL)
{
*pnType = GetDevice()->m_nChipType;
}
return C86CTL_ERR_NONE;
}
 
} // namespace c86ctl
/np21/x11/ext/c86ctl/c86ctlc86box.cpp
@@ -1,506 +1,506 @@
/**
* @file c86ctlc86box.cpp
* @brief Implementation of C86BOX
*/
 
#include "compiler.h"
#include "c86ctlc86box.h"
#include <algorithm>
 
namespace c86ctl
{
 
//! The maximum chips
#define NMAXCHIPS 4
 
/**
* @brief The information of sound baords
*/
struct BOARD_INFO
{
UINT type; //!< The type of boards
UINT nchips; //!< The numbers of chips
ChipType chiptype[NMAXCHIPS]; //!< The type of chips
};
 
/**
* @brief The board's names
*/
struct BoardName
{
CBUS_BOARD_TYPE nId; //!< The type of boards
const char* lpName; //!< The name of boards
};
 
/**
* The tables of baords
*/
static const BoardName s_names[] =
{
{CBUS_BOARD_14, "PC-9801-14"},
{CBUS_BOARD_26, "PC-9801-26K"},
{CBUS_BOARD_SOUND_ORCHESTRA, "ORCHESTRA"},
{CBUS_BOARD_SOUND_ORCHESTRA_L, "ORCHESTRA-L"},
{CBUS_BOARD_SOUND_ORCHESTRA_V, "ORCHESTRA-V"},
{CBUS_BOARD_SOUND_ORCHESTRA_VS, "ORCHESTRA-VS"},
{CBUS_BOARD_SOUND_ORCHESTRA_LS, "ORCHESTRA-LS"},
{CBUS_BOARD_SOUND_ORCHESTRA_MATE, "ORCHESTRA-MATE"},
{CBUS_BOARD_MULTIMEDIA_ORCHESTRA, "MMO"},
{CBUS_BOARD_LITTLE_ORCHESTRA, "LITTLE"},
{CBUS_BOARD_LITTLE_ORCHESTRA_L, "LITTLE-L"},
{CBUS_BOARD_LITTLE_ORCHESTRA_RS, "LITTLE-RS"},
{CBUS_BOARD_LITTLE_ORCHESTRA_LS, "LITTLE-LS"},
{CBUS_BOARD_LITTLE_ORCHESTRA_SS, "LITTLE-SS"},
{CBUS_BOARD_LITTLE_ORCHESTRA_MATE, "LITTLE-MATE"},
{CBUS_BOARD_LITTLE_ORCHESTRA_FELLOW, "LITTLE-FELLOW"},
{CBUS_BOARD_JOY2, "JOY2"},
{CBUS_BOARD_SOUND_GRANPRI, "GRANPRI"},
{CBUS_BOARD_TN_F3FM, "TN-F3FM"},
{CBUS_BOARD_73, "PC-9801-73"},
{CBUS_BOARD_86, "PC-9801-86"},
{CBUS_BOARD_ASB01, "ASB-01"},
{CBUS_BOARD_SPEAKBOARD, "SPEAKBOARD"},
{CBUS_BOARD_SOUNDPLAYER98, "SPB98"},
{CBUS_BOARD_SECONDBUS86, "SB86"},
{CBUS_BOARD_SOUNDEDGE, "SOUNDEDGE"},
{CBUS_BOARD_WINDUO, "WINDUO"},
{CBUS_BOARD_OTOMI, "OTOMI"},
{CBUS_BOARD_WAVEMASTER, "WAVEMASTER"},
{CBUS_BOARD_WAVESMIT, "WAVESIMIT"},
{CBUS_BOARD_WAVESTAR, "WAVESTAR"},
{CBUS_BOARD_WSN_A4F, "WSN-A4F"},
{CBUS_BOARD_SB16, "SB16"},
{CBUS_BOARD_SB16_2203, "SB16"},
{CBUS_BOARD_SB16VALUE, "SB16VALUE"},
{CBUS_BOARD_POWERWINDOW_T64S, "PW-T64S"},
{CBUS_BOARD_PCSB2, "PC-SB2"},
{CBUS_BOARD_WGS98S, "WGS-98S"},
{CBUS_BOARD_SXM_F, "SXM-F"},
{CBUS_BOARD_SRB_G, "SRB-G"},
{CBUS_BOARD_MIDI_ORCHESTRA_MIDI3 , "MIDI-3"},
{CBUS_BOARD_SB_AWE32, "SB-AWE32"},
{CBUS_BOARD_118, "PC-9801-118"},
};
 
/**
* Gets the name from type of boards
* @param[in] nType The type of boards
* @return The name of boards
*/
static const char* GetBoardName(CBUS_BOARD_TYPE nType)
{
const CBUS_BOARD_TYPE nId = static_cast<CBUS_BOARD_TYPE>(nType & 0xffff);
for (UINT i = 0; i < NELEMENTS(s_names); i++)
{
if (s_names[i].nId == nId)
{
return s_names[i].lpName;
}
}
return "UNKNOWN";
}
 
/**
* Constructor
* @param[in] nIndex The index
*/
CC86Box::CC86Box(UINT nIndex)
: m_nRef(1)
, m_nIndex(nIndex)
, m_nQueIndex(0)
, m_nQueCount(0)
{
}
 
/**
* Destructor
*/
CC86Box::~CC86Box()
{
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CC86Box::AddRef()
{
m_nRef++;
return m_nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CC86Box::Release()
{
m_nRef--;
return m_nRef;
}
 
/**
* Initialize
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::initialize()
{
if (!m_usb.Open(0x16c0, 0x27d8, m_nIndex))
{
return C86CTL_ERR_NODEVICE;
}
 
for (UINT i = 0; i < 2; i++)
{
BOARD_INFO info;
if (m_usb.CtrlXfer(0xc0, 0x81, 0, i, &info, sizeof(info)) != sizeof(info))
{
continue;
}
 
printf("Found %s in C86BOX-Slot#%c / chips: %d\n", GetBoardName(static_cast<CBUS_BOARD_TYPE>(info.type)), 'A' + i, info.nchips);
 
for (UINT j = 0; j < info.nchips; j++)
{
const UINT nDevId = (i << 3) | j;
m_chips.push_back(new Chip3(this, nDevId, info.chiptype[j]));
}
}
 
if (m_chips.empty())
{
m_usb.Close();
return C86CTL_ERR_NODEVICE;
}
 
m_nQueIndex = 0;
m_nQueCount = 0;
Start();
return C86CTL_ERR_NONE;
}
 
/**
* Deinitialize
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::deinitialize()
{
Stop();
m_usb.Close();
 
for (std::vector<Chip3*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
delete *it;
}
m_chips.clear();
 
return C86CTL_ERR_NONE;
}
 
/**
* Gets the count of chips
* @return The chips
*/
size_t CC86Box::getNumberOfChip()
{
return m_chips.size();
}
 
/**
* Gets interfaces
* @param[in] id ID
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::getChipInterface(size_t id, IID riid, void** ppi)
{
if (ppi == NULL)
{
return C86CTL_ERR_INVALID_PARAM;
}
 
if (id >= m_chips.size())
{
return C86CTL_ERR_NODEVICE;
}
 
IRealUnknown* pUnknown = NULL;
switch (riid)
{
case IID_IRealChip:
case IID_IRealChip2:
case IID_IRealChip3:
pUnknown = m_chips[id];
break;
 
default:
break;
}
 
if (pUnknown == NULL)
{
return C86CTL_ERR_UNSUPPORTED;
}
 
pUnknown->AddRef();
*ppi = pUnknown;
return C86CTL_ERR_NONE;
}
 
/**
* Sends and receives data from USB
* @param[in] lpOutput A pointer to the buffer that sends the data
* @param[in] cbOutput The number of bytes to be written
* @param[out] lpInput A pointer to the buffer that receives the data
* @param[in] cbInput The maximum number of bytes to be read
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Transaction(const void* lpOutput, int cbOutput, void* lpInput, int cbInput)
{
if (!m_usb.IsOpened())
{
return C86CTL_ERR_NODEVICE;
}
 
char sBuffer[64];
if ((lpOutput == NULL) || (cbOutput <= 0) || (cbOutput >= sizeof(sBuffer)))
{
return C86CTL_ERR_INVALID_PARAM;
}
 
::memcpy(sBuffer, lpOutput, cbOutput);
if (cbOutput < sizeof(sBuffer))
{
::memset(sBuffer + cbOutput, 0xff, sizeof(sBuffer) - cbOutput);
}
 
m_usbGuard.Enter();
int nResult = m_usb.WriteBulk(sBuffer, sizeof(sBuffer));
if ((nResult == sizeof(sBuffer)) && (cbInput > 0))
{
nResult = m_usb.ReadBulk(sBuffer, sizeof(sBuffer));
}
m_usbGuard.Leave();
 
if (nResult != sizeof(sBuffer))
{
return C86CTL_ERR_UNKNOWN;
}
 
if ((lpInput != NULL) && (cbInput > 0))
{
cbInput = (std::min)(cbInput, static_cast<int>(sizeof(sBuffer)));
::memcpy(lpInput, sBuffer, cbInput);
}
return C86CTL_ERR_NONE;
}
 
/**
* Reset
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Reset()
{
m_queGuard.Enter();
m_nQueIndex = 0;
m_nQueCount = 0;
m_queGuard.Leave();
 
m_usbGuard.Enter();
const int r = m_usb.CtrlXfer(0x40, 0x11);
m_usbGuard.Leave();
 
return (r >= 0) ? C86CTL_ERR_NONE : C86CTL_ERR_UNKNOWN;
}
 
/**
* Output
* @param[in] nDevId The id of chips
* @param[in] nAddr The address of registers
* @param[in] cData The data
*/
void CC86Box::Out(UINT nDevId, UINT nAddr, UINT8 cData)
{
m_queGuard.Enter();
while (m_nQueCount >= NELEMENTS(m_que))
{
m_queGuard.Leave();
Delay(1000);
m_queGuard.Enter();
}
 
m_que[(m_nQueIndex + m_nQueCount) % NELEMENTS(m_que)] = (nDevId << 17) | ((nAddr & 0x1ff) << 8) | cData;
m_nQueCount++;
 
m_queGuard.Leave();
}
 
/**
* Thread
* @retval true Cont.
*/
bool CC86Box::Task()
{
/* builds data */
UINT8 sData[64];
int nIndex = 0;
 
m_queGuard.Enter();
while ((m_nQueCount) && ((nIndex + 8) < NELEMENTS(sData)))
{
const UINT data = m_que[m_nQueIndex];
m_nQueIndex = (m_nQueIndex + 1) % NELEMENTS(m_que);
m_nQueCount--;
 
sData[nIndex++] = static_cast<UINT8>(data >> 0);
sData[nIndex++] = static_cast<UINT8>(data >> 8);
sData[nIndex++] = static_cast<UINT8>(data >> 16);
sData[nIndex++] = static_cast<UINT8>(data >> 24);
}
m_queGuard.Leave();
 
/* writes */
if (nIndex > 0)
{
Transaction(sData, nIndex);
}
else
{
Delay(1000);
}
return true;
}
 
/* IRealChip3 */
 
/**
* Constructor
* @param[in] pC86Box The instance of the device
* @param[in] nDevId The id of the chip
* @param[in] nChipType The type of the chip
*/
CC86Box::Chip3::Chip3(CC86Box* pC86Box, UINT nDevId, ChipType nChipType)
: m_pC86Box(pC86Box)
, m_nDevId(nDevId)
, m_nChipType(nChipType)
{
}
 
/**
* Get the instance of the device
* @return The instance
*/
inline CC86Box* CC86Box::Chip3::GetDevice()
{
return m_pC86Box;
}
 
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CC86Box::Chip3::AddRef()
{
return GetDevice()->AddRef();
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CC86Box::Chip3::Release()
{
return GetDevice()->Release();
}
 
/**
* Reset
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Chip3::reset()
{
memset(m_sReg, 0, sizeof(m_sReg));
return GetDevice()->Reset();
}
 
/**
* Output
* @param[in] nAddr The address of registers
* @param[in] cData The data
*/
void CC86Box::Chip3::out(UINT nAddr, UINT8 cData)
{
if (nAddr >= sizeof(m_sReg))
{
return;
}
m_sReg[nAddr] = cData;
 
GetDevice()->Out(m_nDevId, nAddr, cData);
}
 
/**
* Input
* @param[in] nAddr The address of registers
* @return The data
*/
UINT8 CC86Box::Chip3::in(UINT nAddr)
{
if (nAddr < sizeof(m_sReg))
{
return m_sReg[nAddr];
}
return 0xff;
}
 
/**
* Gets the current status
* @param[in] nAddr The address
* @param[out] pcStatus The status
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Chip3::getChipStatus(UINT nAddr, UINT8* pcStatus)
{
return C86CTL_ERR_NOT_IMPLEMENTED;
}
 
/**
* Output
* @param[in] nAddr The address
* @param[in] cData The data
*/
void CC86Box::Chip3::directOut(UINT nAddr, UINT8 cData)
{
if (nAddr >= sizeof(m_sReg))
{
return;
}
m_sReg[nAddr] = cData;
 
const UINT data = (m_nDevId << 17) | ((nAddr & 0x1ff) << 8) | cData;
 
UINT8 sData[4];
sData[0] = static_cast<UINT8>(data >> 0);
sData[1] = static_cast<UINT8>(data >> 8);
sData[2] = static_cast<UINT8>(data >> 16);
sData[3] = static_cast<UINT8>(data >> 24);
GetDevice()->Transaction(sData, sizeof(sData));
}
 
/**
* Gets the type of the chip
* @param[out] pnType A pointer of type
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Chip3::getChipType(ChipType* pnType)
{
if (pnType != NULL)
{
*pnType = m_nChipType;
}
return C86CTL_ERR_NONE;
}
 
} // namespace c86ctl
/**
* @file c86ctlc86box.cpp
* @brief Implementation of C86BOX
*/
 
#include "compiler.h"
#include "c86ctlc86box.h"
#include <algorithm>
 
namespace c86ctl
{
 
//! The maximum chips
#define NMAXCHIPS 4
 
/**
* @brief The information of sound baords
*/
struct BOARD_INFO
{
UINT type; //!< The type of boards
UINT nchips; //!< The numbers of chips
ChipType chiptype[NMAXCHIPS]; //!< The type of chips
};
 
/**
* @brief The board's names
*/
struct BoardName
{
CBUS_BOARD_TYPE nId; //!< The type of boards
const char* lpName; //!< The name of boards
};
 
/**
* The tables of baords
*/
static const BoardName s_names[] =
{
{CBUS_BOARD_14, "PC-9801-14"},
{CBUS_BOARD_26, "PC-9801-26K"},
{CBUS_BOARD_SOUND_ORCHESTRA, "ORCHESTRA"},
{CBUS_BOARD_SOUND_ORCHESTRA_L, "ORCHESTRA-L"},
{CBUS_BOARD_SOUND_ORCHESTRA_V, "ORCHESTRA-V"},
{CBUS_BOARD_SOUND_ORCHESTRA_VS, "ORCHESTRA-VS"},
{CBUS_BOARD_SOUND_ORCHESTRA_LS, "ORCHESTRA-LS"},
{CBUS_BOARD_SOUND_ORCHESTRA_MATE, "ORCHESTRA-MATE"},
{CBUS_BOARD_MULTIMEDIA_ORCHESTRA, "MMO"},
{CBUS_BOARD_LITTLE_ORCHESTRA, "LITTLE"},
{CBUS_BOARD_LITTLE_ORCHESTRA_L, "LITTLE-L"},
{CBUS_BOARD_LITTLE_ORCHESTRA_RS, "LITTLE-RS"},
{CBUS_BOARD_LITTLE_ORCHESTRA_LS, "LITTLE-LS"},
{CBUS_BOARD_LITTLE_ORCHESTRA_SS, "LITTLE-SS"},
{CBUS_BOARD_LITTLE_ORCHESTRA_MATE, "LITTLE-MATE"},
{CBUS_BOARD_LITTLE_ORCHESTRA_FELLOW, "LITTLE-FELLOW"},
{CBUS_BOARD_JOY2, "JOY2"},
{CBUS_BOARD_SOUND_GRANPRI, "GRANPRI"},
{CBUS_BOARD_TN_F3FM, "TN-F3FM"},
{CBUS_BOARD_73, "PC-9801-73"},
{CBUS_BOARD_86, "PC-9801-86"},
{CBUS_BOARD_ASB01, "ASB-01"},
{CBUS_BOARD_SPEAKBOARD, "SPEAKBOARD"},
{CBUS_BOARD_SOUNDPLAYER98, "SPB98"},
{CBUS_BOARD_SECONDBUS86, "SB86"},
{CBUS_BOARD_SOUNDEDGE, "SOUNDEDGE"},
{CBUS_BOARD_WINDUO, "WINDUO"},
{CBUS_BOARD_OTOMI, "OTOMI"},
{CBUS_BOARD_WAVEMASTER, "WAVEMASTER"},
{CBUS_BOARD_WAVESMIT, "WAVESIMIT"},
{CBUS_BOARD_WAVESTAR, "WAVESTAR"},
{CBUS_BOARD_WSN_A4F, "WSN-A4F"},
{CBUS_BOARD_SB16, "SB16"},
{CBUS_BOARD_SB16_2203, "SB16"},
{CBUS_BOARD_SB16VALUE, "SB16VALUE"},
{CBUS_BOARD_POWERWINDOW_T64S, "PW-T64S"},
{CBUS_BOARD_PCSB2, "PC-SB2"},
{CBUS_BOARD_WGS98S, "WGS-98S"},
{CBUS_BOARD_SXM_F, "SXM-F"},
{CBUS_BOARD_SRB_G, "SRB-G"},
{CBUS_BOARD_MIDI_ORCHESTRA_MIDI3 , "MIDI-3"},
{CBUS_BOARD_SB_AWE32, "SB-AWE32"},
{CBUS_BOARD_118, "PC-9801-118"},
};
 
/**
* Gets the name from type of boards
* @param[in] nType The type of boards
* @return The name of boards
*/
static const char* GetBoardName(CBUS_BOARD_TYPE nType)
{
const CBUS_BOARD_TYPE nId = static_cast<CBUS_BOARD_TYPE>(nType & 0xffff);
for (UINT i = 0; i < NELEMENTS(s_names); i++)
{
if (s_names[i].nId == nId)
{
return s_names[i].lpName;
}
}
return "UNKNOWN";
}
 
/**
* Constructor
* @param[in] nIndex The index
*/
CC86Box::CC86Box(UINT nIndex)
: m_nRef(1)
, m_nIndex(nIndex)
, m_nQueIndex(0)
, m_nQueCount(0)
{
}
 
/**
* Destructor
*/
CC86Box::~CC86Box()
{
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CC86Box::AddRef()
{
m_nRef++;
return m_nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CC86Box::Release()
{
m_nRef--;
return m_nRef;
}
 
/**
* Initialize
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::initialize()
{
if (!m_usb.Open(0x16c0, 0x27d8, m_nIndex))
{
return C86CTL_ERR_NODEVICE;
}
 
for (UINT i = 0; i < 2; i++)
{
BOARD_INFO info;
if (m_usb.CtrlXfer(0xc0, 0x81, 0, i, &info, sizeof(info)) != sizeof(info))
{
continue;
}
 
printf("Found %s in C86BOX-Slot#%c / chips: %d\n", GetBoardName(static_cast<CBUS_BOARD_TYPE>(info.type)), 'A' + i, info.nchips);
 
for (UINT j = 0; j < info.nchips; j++)
{
const UINT nDevId = (i << 3) | j;
m_chips.push_back(new Chip3(this, nDevId, info.chiptype[j]));
}
}
 
if (m_chips.empty())
{
m_usb.Close();
return C86CTL_ERR_NODEVICE;
}
 
m_nQueIndex = 0;
m_nQueCount = 0;
Start();
return C86CTL_ERR_NONE;
}
 
/**
* Deinitialize
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::deinitialize()
{
Stop();
m_usb.Close();
 
for (std::vector<Chip3*>::iterator it = m_chips.begin(); it != m_chips.end(); ++it)
{
delete *it;
}
m_chips.clear();
 
return C86CTL_ERR_NONE;
}
 
/**
* Gets the count of chips
* @return The chips
*/
size_t CC86Box::getNumberOfChip()
{
return m_chips.size();
}
 
/**
* Gets interfaces
* @param[in] id ID
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::getChipInterface(size_t id, IID riid, void** ppi)
{
if (ppi == NULL)
{
return C86CTL_ERR_INVALID_PARAM;
}
 
if (id >= m_chips.size())
{
return C86CTL_ERR_NODEVICE;
}
 
IRealUnknown* pUnknown = NULL;
switch (riid)
{
case IID_IRealChip:
case IID_IRealChip2:
case IID_IRealChip3:
pUnknown = m_chips[id];
break;
 
default:
break;
}
 
if (pUnknown == NULL)
{
return C86CTL_ERR_UNSUPPORTED;
}
 
pUnknown->AddRef();
*ppi = pUnknown;
return C86CTL_ERR_NONE;
}
 
/**
* Sends and receives data from USB
* @param[in] lpOutput A pointer to the buffer that sends the data
* @param[in] cbOutput The number of bytes to be written
* @param[out] lpInput A pointer to the buffer that receives the data
* @param[in] cbInput The maximum number of bytes to be read
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Transaction(const void* lpOutput, int cbOutput, void* lpInput, int cbInput)
{
if (!m_usb.IsOpened())
{
return C86CTL_ERR_NODEVICE;
}
 
char sBuffer[64];
if ((lpOutput == NULL) || (cbOutput <= 0) || (cbOutput >= sizeof(sBuffer)))
{
return C86CTL_ERR_INVALID_PARAM;
}
 
::memcpy(sBuffer, lpOutput, cbOutput);
if (cbOutput < sizeof(sBuffer))
{
::memset(sBuffer + cbOutput, 0xff, sizeof(sBuffer) - cbOutput);
}
 
m_usbGuard.Enter();
int nResult = m_usb.WriteBulk(sBuffer, sizeof(sBuffer));
if ((nResult == sizeof(sBuffer)) && (cbInput > 0))
{
nResult = m_usb.ReadBulk(sBuffer, sizeof(sBuffer));
}
m_usbGuard.Leave();
 
if (nResult != sizeof(sBuffer))
{
return C86CTL_ERR_UNKNOWN;
}
 
if ((lpInput != NULL) && (cbInput > 0))
{
cbInput = (std::min)(cbInput, static_cast<int>(sizeof(sBuffer)));
::memcpy(lpInput, sBuffer, cbInput);
}
return C86CTL_ERR_NONE;
}
 
/**
* Reset
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Reset()
{
m_queGuard.Enter();
m_nQueIndex = 0;
m_nQueCount = 0;
m_queGuard.Leave();
 
m_usbGuard.Enter();
const int r = m_usb.CtrlXfer(0x40, 0x11);
m_usbGuard.Leave();
 
return (r >= 0) ? C86CTL_ERR_NONE : C86CTL_ERR_UNKNOWN;
}
 
/**
* Output
* @param[in] nDevId The id of chips
* @param[in] nAddr The address of registers
* @param[in] cData The data
*/
void CC86Box::Out(UINT nDevId, UINT nAddr, UINT8 cData)
{
m_queGuard.Enter();
while (m_nQueCount >= NELEMENTS(m_que))
{
m_queGuard.Leave();
Delay(1000);
m_queGuard.Enter();
}
 
m_que[(m_nQueIndex + m_nQueCount) % NELEMENTS(m_que)] = (nDevId << 17) | ((nAddr & 0x1ff) << 8) | cData;
m_nQueCount++;
 
m_queGuard.Leave();
}
 
/**
* Thread
* @retval true Cont.
*/
bool CC86Box::Task()
{
/* builds data */
UINT8 sData[64];
int nIndex = 0;
 
m_queGuard.Enter();
while ((m_nQueCount) && ((nIndex + 8) < NELEMENTS(sData)))
{
const UINT data = m_que[m_nQueIndex];
m_nQueIndex = (m_nQueIndex + 1) % NELEMENTS(m_que);
m_nQueCount--;
 
sData[nIndex++] = static_cast<UINT8>(data >> 0);
sData[nIndex++] = static_cast<UINT8>(data >> 8);
sData[nIndex++] = static_cast<UINT8>(data >> 16);
sData[nIndex++] = static_cast<UINT8>(data >> 24);
}
m_queGuard.Leave();
 
/* writes */
if (nIndex > 0)
{
Transaction(sData, nIndex);
}
else
{
Delay(1000);
}
return true;
}
 
/* IRealChip3 */
 
/**
* Constructor
* @param[in] pC86Box The instance of the device
* @param[in] nDevId The id of the chip
* @param[in] nChipType The type of the chip
*/
CC86Box::Chip3::Chip3(CC86Box* pC86Box, UINT nDevId, ChipType nChipType)
: m_pC86Box(pC86Box)
, m_nDevId(nDevId)
, m_nChipType(nChipType)
{
}
 
/**
* Get the instance of the device
* @return The instance
*/
inline CC86Box* CC86Box::Chip3::GetDevice()
{
return m_pC86Box;
}
 
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CC86Box::Chip3::AddRef()
{
return GetDevice()->AddRef();
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CC86Box::Chip3::Release()
{
return GetDevice()->Release();
}
 
/**
* Reset
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Chip3::reset()
{
memset(m_sReg, 0, sizeof(m_sReg));
return GetDevice()->Reset();
}
 
/**
* Output
* @param[in] nAddr The address of registers
* @param[in] cData The data
*/
void CC86Box::Chip3::out(UINT nAddr, UINT8 cData)
{
if (nAddr >= sizeof(m_sReg))
{
return;
}
m_sReg[nAddr] = cData;
 
GetDevice()->Out(m_nDevId, nAddr, cData);
}
 
/**
* Input
* @param[in] nAddr The address of registers
* @return The data
*/
UINT8 CC86Box::Chip3::in(UINT nAddr)
{
if (nAddr < sizeof(m_sReg))
{
return m_sReg[nAddr];
}
return 0xff;
}
 
/**
* Gets the current status
* @param[in] nAddr The address
* @param[out] pcStatus The status
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Chip3::getChipStatus(UINT nAddr, UINT8* pcStatus)
{
return C86CTL_ERR_NOT_IMPLEMENTED;
}
 
/**
* Output
* @param[in] nAddr The address
* @param[in] cData The data
*/
void CC86Box::Chip3::directOut(UINT nAddr, UINT8 cData)
{
if (nAddr >= sizeof(m_sReg))
{
return;
}
m_sReg[nAddr] = cData;
 
const UINT data = (m_nDevId << 17) | ((nAddr & 0x1ff) << 8) | cData;
 
UINT8 sData[4];
sData[0] = static_cast<UINT8>(data >> 0);
sData[1] = static_cast<UINT8>(data >> 8);
sData[2] = static_cast<UINT8>(data >> 16);
sData[3] = static_cast<UINT8>(data >> 24);
GetDevice()->Transaction(sData, sizeof(sData));
}
 
/**
* Gets the type of the chip
* @param[out] pnType A pointer of type
* @return C86CTL_ERR
*/
C86CtlErr CC86Box::Chip3::getChipType(ChipType* pnType)
{
if (pnType != NULL)
{
*pnType = m_nChipType;
}
return C86CTL_ERR_NONE;
}
 
} // namespace c86ctl
/np21/x11/ext/c86ctl/c86ctlgimic.h
@@ -1,126 +1,126 @@
/**
* @file c86ctlgimic.h
* @brief Interface of G.I.M.I.C
*/
 
#pragma once
 
#include "c86ctlrealchipbase.h"
#include "misc/guard.h"
#include "misc/threadbase.h"
#include "misc/usbdev.h"
 
namespace c86ctl
{
 
/**
* @brief The class of G.I.M.I.C
*/
class CGimic : public CRealChipBase::CDevice, protected CThreadBase
{
public:
CGimic(UINT nIndex);
virtual ~CGimic();
 
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChipBase
virtual C86CtlErr initialize();
virtual C86CtlErr deinitialize();
virtual size_t getNumberOfChip();
virtual C86CtlErr getChipInterface(size_t id, IID riid, void** ppi);
 
protected:
virtual bool Task();
 
private:
/**
* @brief FM data
*/
struct FMDATA
{
UINT16 wAddr; /*!< address */
UINT8 cData; /*!< data */
UINT8 cPadding; /*!< padding */
};
 
/**
* @brief The class of the gimic
*/
class Gimic2 : public IGimic2
{
public:
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IGimic
C86CtlErr getFWVer(UINT* pnMajor, UINT* pnMinor, UINT* pnRev, UINT* pnBuild);
C86CtlErr getMBInfo(Devinfo* pInfo);
C86CtlErr getModuleInfo(Devinfo* pInfo);
C86CtlErr setSSGVolume(UINT8 cVolume);
C86CtlErr getSSGVolume(UINT8* pcVolume);
C86CtlErr setPLLClock(UINT nClock);
C86CtlErr getPLLClock(UINT* pnClock);
 
// IGimic2
C86CtlErr getModuleType(ChipType* pnType);
 
private:
CGimic* GetDevice();
};
 
/**
* @brief The class of the chip
*/
class Chip3 : public IRealChip3
{
public:
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChip
virtual C86CtlErr reset();
virtual void out(UINT nAddr, UINT8 cData);
virtual UINT8 in(UINT nAddr);
 
// IRealChip2
virtual C86CtlErr getChipStatus(UINT nAddr, UINT8* pcStatus);
virtual void directOut(UINT nAddr, UINT8 cData);
 
// IRealChip3
virtual C86CtlErr getChipType(ChipType* pnType);
 
private:
UINT8 m_sReg[0x200]; /*!< register */
 
CGimic* GetDevice();
};
 
size_t m_nRef; /*!< The reference counter */
UINT m_nIndex; /*!< The index of devices */
ChipType m_nChipType; /*!< The type of chip */
UINT m_nQueIndex; /*!< The position in que */
UINT m_nQueCount; /*!< The count in que */
CUsbDev m_usb; /*!< USB */
CGuard m_usbGuard; /*!< The guard of accessing USB */
CGuard m_queGuard; /*!< The guard of que */
Gimic2 m_gimic2; /*!< gimic2 */
Chip3 m_chip3; /*!< chip3 */
FMDATA m_que[0x400]; /*!< que */
 
C86CtlErr Transaction(const void* lpOutput, int cbOutput, void* lpInput = NULL, int cbInput = 0);
C86CtlErr Reset();
C86CtlErr GetInfo(UINT8 cParam, c86ctl::Devinfo* pInfo);
static void TailZeroFill(char* lpBuffer, size_t cbBuffer);
UINT GetChipAddr(UINT nAddr) const;
void Out(UINT nAddr, UINT8 cData);
 
friend class Gimic2;
friend class Chip3;
};
 
} // namespace c86ctl
/**
* @file c86ctlgimic.h
* @brief Interface of G.I.M.I.C
*/
 
#pragma once
 
#include "c86ctlrealchipbase.h"
#include "misc/guard.h"
#include "misc/threadbase.h"
#include "misc/usbdev.h"
 
namespace c86ctl
{
 
/**
* @brief The class of G.I.M.I.C
*/
class CGimic : public CRealChipBase::CDevice, protected CThreadBase
{
public:
CGimic(UINT nIndex);
virtual ~CGimic();
 
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChipBase
virtual C86CtlErr initialize();
virtual C86CtlErr deinitialize();
virtual size_t getNumberOfChip();
virtual C86CtlErr getChipInterface(size_t id, IID riid, void** ppi);
 
protected:
virtual bool Task();
 
private:
/**
* @brief FM data
*/
struct FMDATA
{
UINT16 wAddr; /*!< address */
UINT8 cData; /*!< data */
UINT8 cPadding; /*!< padding */
};
 
/**
* @brief The class of the gimic
*/
class Gimic2 : public IGimic2
{
public:
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IGimic
C86CtlErr getFWVer(UINT* pnMajor, UINT* pnMinor, UINT* pnRev, UINT* pnBuild);
C86CtlErr getMBInfo(Devinfo* pInfo);
C86CtlErr getModuleInfo(Devinfo* pInfo);
C86CtlErr setSSGVolume(UINT8 cVolume);
C86CtlErr getSSGVolume(UINT8* pcVolume);
C86CtlErr setPLLClock(UINT nClock);
C86CtlErr getPLLClock(UINT* pnClock);
 
// IGimic2
C86CtlErr getModuleType(ChipType* pnType);
 
private:
CGimic* GetDevice();
};
 
/**
* @brief The class of the chip
*/
class Chip3 : public IRealChip3
{
public:
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChip
virtual C86CtlErr reset();
virtual void out(UINT nAddr, UINT8 cData);
virtual UINT8 in(UINT nAddr);
 
// IRealChip2
virtual C86CtlErr getChipStatus(UINT nAddr, UINT8* pcStatus);
virtual void directOut(UINT nAddr, UINT8 cData);
 
// IRealChip3
virtual C86CtlErr getChipType(ChipType* pnType);
 
private:
UINT8 m_sReg[0x200]; /*!< register */
 
CGimic* GetDevice();
};
 
size_t m_nRef; /*!< The reference counter */
UINT m_nIndex; /*!< The index of devices */
ChipType m_nChipType; /*!< The type of chip */
UINT m_nQueIndex; /*!< The position in que */
UINT m_nQueCount; /*!< The count in que */
CUsbDev m_usb; /*!< USB */
CGuard m_usbGuard; /*!< The guard of accessing USB */
CGuard m_queGuard; /*!< The guard of que */
Gimic2 m_gimic2; /*!< gimic2 */
Chip3 m_chip3; /*!< chip3 */
FMDATA m_que[0x400]; /*!< que */
 
C86CtlErr Transaction(const void* lpOutput, int cbOutput, void* lpInput = NULL, int cbInput = 0);
C86CtlErr Reset();
C86CtlErr GetInfo(UINT8 cParam, c86ctl::Devinfo* pInfo);
static void TailZeroFill(char* lpBuffer, size_t cbBuffer);
UINT GetChipAddr(UINT nAddr) const;
void Out(UINT nAddr, UINT8 cData);
 
friend class Gimic2;
friend class Chip3;
};
 
} // namespace c86ctl
/np21/x11/ext/c86ctl/c86ctlc86box.h
@@ -1,90 +1,90 @@
/**
* @file c86ctlc86box.h
* @brief Interface of C86BOX
*/
 
#pragma once
 
#include <vector>
#include "c86ctlrealchipbase.h"
#include "misc/guard.h"
#include "misc/threadbase.h"
#include "misc/usbdev.h"
 
namespace c86ctl
{
 
/**
* @brief The class of C86BOX
*/
class CC86Box : public CRealChipBase::CDevice, protected CThreadBase
{
public:
CC86Box(UINT nIndex);
virtual ~CC86Box();
 
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChipBase
virtual C86CtlErr initialize();
virtual C86CtlErr deinitialize();
virtual size_t getNumberOfChip();
virtual C86CtlErr getChipInterface(size_t id, IID riid, void** ppi);
 
protected:
virtual bool Task();
 
private:
/**
* @brief The class of the chip
*/
class Chip3 : public IRealChip3
{
public:
Chip3(CC86Box* pC86Box, UINT nDevId, ChipType nChipType);
 
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChip
virtual C86CtlErr reset();
virtual void out(UINT nAddr, UINT8 cData);
virtual UINT8 in(UINT nAddr);
 
// IRealChip2
virtual C86CtlErr getChipStatus(UINT nAddr, UINT8* pcStatus);
virtual void directOut(UINT nAddr, UINT8 cData);
 
// IRealChip3
virtual C86CtlErr getChipType(ChipType* pnType);
 
private:
CC86Box* m_pC86Box; /*!< The instance of the device */
UINT m_nDevId; /*!< The type of devices */
ChipType m_nChipType; /*!< The type of chip */
UINT8 m_sReg[0x200]; /*!< register */
 
CC86Box* GetDevice();
};
 
size_t m_nRef; /*!< The reference counter */
UINT m_nIndex; /*!< The index of devices */
CUsbDev m_usb; /*!< USB */
CGuard m_usbGuard; /*!< The quard of accessing USB */
CGuard m_queGuard; /*!< The quard of que */
UINT m_nQueIndex; /*!< The position in que */
UINT m_nQueCount; /*!< The count in que */
UINT m_que[0x400]; /*!< que */
std::vector<Chip3*> m_chips; /*!< The list of chips */
 
C86CtlErr Transaction(const void* lpOutput, int cbOutput, void* lpInput = NULL, int cbInput = 0);
C86CtlErr Reset();
void Out(UINT nDevId, UINT nAddr, UINT8 cData);
 
friend class Chip3;
};
 
} // namespace c86ctl
/**
* @file c86ctlc86box.h
* @brief Interface of C86BOX
*/
 
#pragma once
 
#include <vector>
#include "c86ctlrealchipbase.h"
#include "misc/guard.h"
#include "misc/threadbase.h"
#include "misc/usbdev.h"
 
namespace c86ctl
{
 
/**
* @brief The class of C86BOX
*/
class CC86Box : public CRealChipBase::CDevice, protected CThreadBase
{
public:
CC86Box(UINT nIndex);
virtual ~CC86Box();
 
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChipBase
virtual C86CtlErr initialize();
virtual C86CtlErr deinitialize();
virtual size_t getNumberOfChip();
virtual C86CtlErr getChipInterface(size_t id, IID riid, void** ppi);
 
protected:
virtual bool Task();
 
private:
/**
* @brief The class of the chip
*/
class Chip3 : public IRealChip3
{
public:
Chip3(CC86Box* pC86Box, UINT nDevId, ChipType nChipType);
 
// IRealUnknown
virtual size_t AddRef();
virtual size_t Release();
 
// IRealChip
virtual C86CtlErr reset();
virtual void out(UINT nAddr, UINT8 cData);
virtual UINT8 in(UINT nAddr);
 
// IRealChip2
virtual C86CtlErr getChipStatus(UINT nAddr, UINT8* pcStatus);
virtual void directOut(UINT nAddr, UINT8 cData);
 
// IRealChip3
virtual C86CtlErr getChipType(ChipType* pnType);
 
private:
CC86Box* m_pC86Box; /*!< The instance of the device */
UINT m_nDevId; /*!< The type of devices */
ChipType m_nChipType; /*!< The type of chip */
UINT8 m_sReg[0x200]; /*!< register */
 
CC86Box* GetDevice();
};
 
size_t m_nRef; /*!< The reference counter */
UINT m_nIndex; /*!< The index of devices */
CUsbDev m_usb; /*!< USB */
CGuard m_usbGuard; /*!< The quard of accessing USB */
CGuard m_queGuard; /*!< The quard of que */
UINT m_nQueIndex; /*!< The position in que */
UINT m_nQueCount; /*!< The count in que */
UINT m_que[0x400]; /*!< que */
std::vector<Chip3*> m_chips; /*!< The list of chips */
 
C86CtlErr Transaction(const void* lpOutput, int cbOutput, void* lpInput = NULL, int cbInput = 0);
C86CtlErr Reset();
void Out(UINT nDevId, UINT nAddr, UINT8 cData);
 
friend class Chip3;
};
 
} // namespace c86ctl
/np21/x11/ext/c86ctl/c86ctlif.cpp
@@ -1,289 +1,289 @@
/**
* @file c86ctlif.cpp
* @brief G.I.M.I.C ƒAƒNƒZƒX ƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "c86ctlif.h"
#include "c86ctl.h"
 
using namespace c86ctl;
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
*/
C86CtlIf::C86CtlIf()
: m_pChipBase(NULL)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
C86CtlIf::~C86CtlIf()
{
Deinitialize();
}
 
/**
* ‰Šú‰»
* @retval true ¬Œ÷
* @retval false Ž¸”s
*/
bool C86CtlIf::Initialize()
{
if (m_pChipBase)
{
return false;
}
 
do
{
/* ƒCƒ“ƒXƒ^ƒ“ƒXì¬ */
CreateInstance(IID_IRealChipBase, reinterpret_cast<void**>(&m_pChipBase));
if (m_pChipBase == NULL)
{
break;
}
 
/* ‰Šú‰» */
if (m_pChipBase->initialize() != C86CTL_ERR_NONE)
{
break;
}
return true;
 
} while (0 /*CONSTCOND*/);
 
Deinitialize();
return false;
}
 
/**
* ‰ð•ú
*/
void C86CtlIf::Deinitialize()
{
if (m_pChipBase)
{
while (!m_chips.empty())
{
std::map<int, Chip*>::iterator it = m_chips.begin();
delete it->second;
}
 
m_pChipBase->deinitialize();
m_pChipBase = NULL;
}
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void C86CtlIf::Reset()
{
}
 
/**
* ƒCƒ“ƒ^[ƒtƒFƒCƒXŽæ“¾
* @param[in] nChipType ƒ^ƒCƒv
* @param[in] nClock ƒNƒƒbƒN
* @return ƒCƒ“ƒXƒ^ƒ“ƒX
*/
IExternalChip* C86CtlIf::GetInterface(IExternalChip::ChipType nChipType, UINT nClock)
{
const bool bInitialized = Initialize();
 
do
{
if (m_pChipBase == NULL)
{
break;
}
 
/* ‰¹Œ¹‚ð’T‚· */
const int nDeviceCount = static_cast<int>(m_pChipBase->getNumberOfChip());
for (int i = 0; i < nDeviceCount; i++)
{
/* Žg—p’†? */
if (m_chips.find(i) != m_chips.end())
{
continue;
}
 
/* ƒ`ƒbƒv‚ð’T‚· */
IRealChip* pRealChip = NULL;
m_pChipBase->getChipInterface(i, IID_IRealChip, reinterpret_cast<void**>(&pRealChip));
if (pRealChip == NULL)
{
continue;
}
 
/* G.I.M.I.C ”»’è */
IGimic* pGimic = NULL;
m_pChipBase->getChipInterface(i, IID_IGimic, reinterpret_cast<void**>(&pGimic));
if (pGimic)
{
Devinfo info;
if (pGimic->getModuleInfo(&info) == C86CTL_ERR_NONE)
{
IExternalChip::ChipType nRealChipType = IExternalChip::kNone;
if (!memcmp(info.Devname, "GMC-OPN3L", 9))
{
nRealChipType = IExternalChip::kYMF288;
}
else if (!memcmp(info.Devname, "GMC-OPNA", 8))
{
nRealChipType = IExternalChip::kYM2608;
}
else if (!memcmp(info.Devname, "GMC-OPL3", 8))
{
nRealChipType = IExternalChip::kYMF262;
}
else if (!memcmp(info.Devname, "GMC-OPM", 7))
{
nRealChipType = IExternalChip::kYM2151;
}
 
if (nChipType == nRealChipType)
{
/* ƒTƒEƒ“ƒhƒ`ƒbƒvŽæ“¾‚Å‚«‚½ */
Chip* pChip = new Chip(this, pRealChip, pGimic, nRealChipType, nClock);
m_chips[i] = pChip;
return pChip;
}
}
}
 
/* ‚»‚Ì‘¼‚Ì”»’è */
IRealChip3* pChip3 = NULL;
m_pChipBase->getChipInterface(i, IID_IRealChip3, reinterpret_cast<void**>(&pChip3));
if (pChip3 != NULL)
{
c86ctl::ChipType nType = CHIP_UNKNOWN;
pChip3->getChipType(&nType);
 
IExternalChip::ChipType nRealChipType = IExternalChip::kNone;
if (nType == CHIP_YM2203)
{
nRealChipType = IExternalChip::kYM2203;
}
else if (nType == CHIP_OPNA)
{
nRealChipType = IExternalChip::kYM2608;
}
else if ((nType == CHIP_YM2608NOADPCM) || (nType == CHIP_OPN3L))
{
nRealChipType = IExternalChip::kYMF288;
}
else if (nType == CHIP_Y8950ADPCM)
{
nRealChipType = IExternalChip::kY8950;
}
if (nChipType == nRealChipType)
{
/* ƒTƒEƒ“ƒhƒ`ƒbƒvŽæ“¾‚Å‚«‚½ */
Chip* pChip = new Chip(this, pChip3, NULL, nRealChipType, nClock);
m_chips[i] = pChip;
return pChip;
}
}
}
} while (false /*CONSTCOND*/);
 
if (bInitialized)
{
// Deinitialize();
}
return NULL;
}
 
/**
* ‰ð•ú
* @param[in] pChip ƒ`ƒbƒv
*/
void C86CtlIf::Detach(C86CtlIf::Chip* pChip)
{
std::map<int, Chip*>::iterator it = m_chips.begin();
while (it != m_chips.end())
{
if (it->second == pChip)
{
it = m_chips.erase(it);
}
else
{
++it;
}
}
}
 
/* ---- ƒ`ƒbƒv */
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pC86CtlIf C86CtlIf ƒCƒ“ƒXƒ^ƒ“ƒX
* @param[in] pRealChip ƒ`ƒbƒv ƒCƒ“ƒXƒ^ƒ“ƒX
* @param[in] pGimic G.I.M.I.C ƒCƒ“ƒXƒ^ƒ“ƒX
* @param[in] nChipType ƒ`ƒbƒv ƒ^ƒCƒv
* @param[in] nClock ƒNƒƒbƒN
*/
C86CtlIf::Chip::Chip(C86CtlIf* pC86CtlIf, c86ctl::IRealChip* pRealChip, c86ctl::IGimic* pGimic, ChipType nChipType, UINT nClock)
: m_pC86CtlIf(pC86CtlIf)
, m_pRealChip(pRealChip)
, m_pGimic(pGimic)
, m_nChipType(nChipType)
, m_nClock(nClock)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
C86CtlIf::Chip::~Chip()
{
m_pC86CtlIf->Detach(this);
}
 
/**
* Get chip type
* @return The type of the chip
*/
IExternalChip::ChipType C86CtlIf::Chip::GetChipType()
{
return m_nChipType;
}
 
/**
* ƒŠƒZƒbƒg
*/
void C86CtlIf::Chip::Reset()
{
m_pRealChip->reset();
if (m_pGimic)
{
m_pGimic->setPLLClock(m_nClock);
m_pGimic->setSSGVolume(31);
}
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void C86CtlIf::Chip::WriteRegister(UINT nAddr, UINT8 cData)
{
m_pRealChip->out(nAddr, cData);
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return ƒŠƒUƒ‹ƒg
*/
INTPTR C86CtlIf::Chip::Message(UINT nMessage, INTPTR nParameter)
{
return 0;
}
/**
* @file c86ctlif.cpp
* @brief G.I.M.I.C ƒAƒNƒZƒX ƒNƒ‰ƒX‚Ì“®ì‚Ì’è‹`‚ðs‚¢‚Ü‚·
*/
 
#include "compiler.h"
#include "c86ctlif.h"
#include "c86ctl.h"
 
using namespace c86ctl;
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
*/
C86CtlIf::C86CtlIf()
: m_pChipBase(NULL)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
C86CtlIf::~C86CtlIf()
{
Deinitialize();
}
 
/**
* ‰Šú‰»
* @retval true ¬Œ÷
* @retval false Ž¸”s
*/
bool C86CtlIf::Initialize()
{
if (m_pChipBase)
{
return false;
}
 
do
{
/* ƒCƒ“ƒXƒ^ƒ“ƒXì¬ */
CreateInstance(IID_IRealChipBase, reinterpret_cast<void**>(&m_pChipBase));
if (m_pChipBase == NULL)
{
break;
}
 
/* ‰Šú‰» */
if (m_pChipBase->initialize() != C86CTL_ERR_NONE)
{
break;
}
return true;
 
} while (0 /*CONSTCOND*/);
 
Deinitialize();
return false;
}
 
/**
* ‰ð•ú
*/
void C86CtlIf::Deinitialize()
{
if (m_pChipBase)
{
while (!m_chips.empty())
{
std::map<int, Chip*>::iterator it = m_chips.begin();
delete it->second;
}
 
m_pChipBase->deinitialize();
m_pChipBase = NULL;
}
}
 
/**
* ‰¹Œ¹ƒŠƒZƒbƒg
*/
void C86CtlIf::Reset()
{
}
 
/**
* ƒCƒ“ƒ^[ƒtƒFƒCƒXŽæ“¾
* @param[in] nChipType ƒ^ƒCƒv
* @param[in] nClock ƒNƒƒbƒN
* @return ƒCƒ“ƒXƒ^ƒ“ƒX
*/
IExternalChip* C86CtlIf::GetInterface(IExternalChip::ChipType nChipType, UINT nClock)
{
const bool bInitialized = Initialize();
 
do
{
if (m_pChipBase == NULL)
{
break;
}
 
/* ‰¹Œ¹‚ð’T‚· */
const int nDeviceCount = static_cast<int>(m_pChipBase->getNumberOfChip());
for (int i = 0; i < nDeviceCount; i++)
{
/* Žg—p’†? */
if (m_chips.find(i) != m_chips.end())
{
continue;
}
 
/* ƒ`ƒbƒv‚ð’T‚· */
IRealChip* pRealChip = NULL;
m_pChipBase->getChipInterface(i, IID_IRealChip, reinterpret_cast<void**>(&pRealChip));
if (pRealChip == NULL)
{
continue;
}
 
/* G.I.M.I.C ”»’è */
IGimic* pGimic = NULL;
m_pChipBase->getChipInterface(i, IID_IGimic, reinterpret_cast<void**>(&pGimic));
if (pGimic)
{
Devinfo info;
if (pGimic->getModuleInfo(&info) == C86CTL_ERR_NONE)
{
IExternalChip::ChipType nRealChipType = IExternalChip::kNone;
if (!memcmp(info.Devname, "GMC-OPN3L", 9))
{
nRealChipType = IExternalChip::kYMF288;
}
else if (!memcmp(info.Devname, "GMC-OPNA", 8))
{
nRealChipType = IExternalChip::kYM2608;
}
else if (!memcmp(info.Devname, "GMC-OPL3", 8))
{
nRealChipType = IExternalChip::kYMF262;
}
else if (!memcmp(info.Devname, "GMC-OPM", 7))
{
nRealChipType = IExternalChip::kYM2151;
}
 
if (nChipType == nRealChipType)
{
/* ƒTƒEƒ“ƒhƒ`ƒbƒvŽæ“¾‚Å‚«‚½ */
Chip* pChip = new Chip(this, pRealChip, pGimic, nRealChipType, nClock);
m_chips[i] = pChip;
return pChip;
}
}
}
 
/* ‚»‚Ì‘¼‚Ì”»’è */
IRealChip3* pChip3 = NULL;
m_pChipBase->getChipInterface(i, IID_IRealChip3, reinterpret_cast<void**>(&pChip3));
if (pChip3 != NULL)
{
c86ctl::ChipType nType = CHIP_UNKNOWN;
pChip3->getChipType(&nType);
 
IExternalChip::ChipType nRealChipType = IExternalChip::kNone;
if (nType == CHIP_YM2203)
{
nRealChipType = IExternalChip::kYM2203;
}
else if (nType == CHIP_OPNA)
{
nRealChipType = IExternalChip::kYM2608;
}
else if ((nType == CHIP_YM2608NOADPCM) || (nType == CHIP_OPN3L))
{
nRealChipType = IExternalChip::kYMF288;
}
else if (nType == CHIP_Y8950ADPCM)
{
nRealChipType = IExternalChip::kY8950;
}
if (nChipType == nRealChipType)
{
/* ƒTƒEƒ“ƒhƒ`ƒbƒvŽæ“¾‚Å‚«‚½ */
Chip* pChip = new Chip(this, pChip3, NULL, nRealChipType, nClock);
m_chips[i] = pChip;
return pChip;
}
}
}
} while (false /*CONSTCOND*/);
 
if (bInitialized)
{
// Deinitialize();
}
return NULL;
}
 
/**
* ‰ð•ú
* @param[in] pChip ƒ`ƒbƒv
*/
void C86CtlIf::Detach(C86CtlIf::Chip* pChip)
{
std::map<int, Chip*>::iterator it = m_chips.begin();
while (it != m_chips.end())
{
if (it->second == pChip)
{
it = m_chips.erase(it);
}
else
{
++it;
}
}
}
 
/* ---- ƒ`ƒbƒv */
 
/**
* ƒRƒ“ƒXƒgƒ‰ƒNƒ^
* @param[in] pC86CtlIf C86CtlIf ƒCƒ“ƒXƒ^ƒ“ƒX
* @param[in] pRealChip ƒ`ƒbƒv ƒCƒ“ƒXƒ^ƒ“ƒX
* @param[in] pGimic G.I.M.I.C ƒCƒ“ƒXƒ^ƒ“ƒX
* @param[in] nChipType ƒ`ƒbƒv ƒ^ƒCƒv
* @param[in] nClock ƒNƒƒbƒN
*/
C86CtlIf::Chip::Chip(C86CtlIf* pC86CtlIf, c86ctl::IRealChip* pRealChip, c86ctl::IGimic* pGimic, ChipType nChipType, UINT nClock)
: m_pC86CtlIf(pC86CtlIf)
, m_pRealChip(pRealChip)
, m_pGimic(pGimic)
, m_nChipType(nChipType)
, m_nClock(nClock)
{
}
 
/**
* ƒfƒXƒgƒ‰ƒNƒ^
*/
C86CtlIf::Chip::~Chip()
{
m_pC86CtlIf->Detach(this);
}
 
/**
* Get chip type
* @return The type of the chip
*/
IExternalChip::ChipType C86CtlIf::Chip::GetChipType()
{
return m_nChipType;
}
 
/**
* ƒŠƒZƒbƒg
*/
void C86CtlIf::Chip::Reset()
{
m_pRealChip->reset();
if (m_pGimic)
{
m_pGimic->setPLLClock(m_nClock);
m_pGimic->setSSGVolume(31);
}
}
 
/**
* ƒŒƒWƒXƒ^‘‚«ž‚Ý
* @param[in] nAddr ƒAƒhƒŒƒX
* @param[in] cData ƒf[ƒ^
*/
void C86CtlIf::Chip::WriteRegister(UINT nAddr, UINT8 cData)
{
m_pRealChip->out(nAddr, cData);
}
 
/**
* ƒƒbƒZ[ƒW
* @param[in] nMessage ƒƒbƒZ[ƒW
* @param[in] nParameter ƒpƒ‰ƒ[ƒ^
* @return ƒŠƒUƒ‹ƒg
*/
INTPTR C86CtlIf::Chip::Message(UINT nMessage, INTPTR nParameter)
{
return 0;
}
/np21/x11/ext/c86ctl/c86ctlrealchipbase.cpp
@@ -1,174 +1,174 @@
/**
* @file c86ctlrealchipbase.cpp
* @brief Implementation of IRealChipBase
*/
 
#include "compiler.h"
#include "c86ctlrealchipbase.h"
#include "c86ctlc86box.h"
#include "c86ctlgimic.h"
 
namespace c86ctl
{
 
/*! instance */
CRealChipBase CRealChipBase::sm_instance;
 
/**
* Gets interfaces
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
C86CtlErr CreateInstance(IID riid, void** ppi)
{
if (ppi == NULL)
{
return C86CTL_ERR_INVALID_PARAM;
}
 
if (riid != IID_IRealChipBase)
{
return C86CTL_ERR_UNSUPPORTED;
}
 
CRealChipBase* pBase = CRealChipBase::GetInstance();
pBase->AddRef();
*ppi = pBase;
return C86CTL_ERR_NONE;
}
 
/**
* Constructor
*/
CRealChipBase::CRealChipBase()
: m_nRef(0)
{
}
 
/**
* Destructor
*/
CRealChipBase::~CRealChipBase()
{
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CRealChipBase::AddRef()
{
m_nRef++;
return m_nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CRealChipBase::Release()
{
m_nRef--;
return m_nRef;
}
 
/**
* Initialize
* @return C86CTL_ERR
*/
C86CtlErr CRealChipBase::initialize()
{
for (UINT i = 0; i < 1; i++)
{
CGimic* pGimic = new CGimic(i);
if (pGimic->initialize() != C86CTL_ERR_NONE)
{
pGimic->deinitialize();
delete pGimic;
continue;
}
m_devices.push_back(pGimic);
}
 
for (UINT i = 0; i < 1; i++)
{
CC86Box* pC86Box = new CC86Box(i);
if (pC86Box->initialize() != C86CTL_ERR_NONE)
{
pC86Box->deinitialize();
delete pC86Box;
continue;
}
m_devices.push_back(pC86Box);
}
 
return C86CTL_ERR_NONE;
}
 
/**
* Deinitialize
* @return C86CTL_ERR
*/
C86CtlErr CRealChipBase::deinitialize()
{
for (std::vector<CDevice*>::iterator it = m_devices.begin(); it != m_devices.end(); ++it)
{
CDevice* pDevice = *it;
pDevice->deinitialize();
delete pDevice;
}
m_devices.clear();
 
return C86CTL_ERR_NONE;
}
 
/**
* Gets the count of chips
* @return The chips
*/
size_t CRealChipBase::getNumberOfChip()
{
size_t nChips = 0;
for (std::vector<CDevice*>::iterator it = m_devices.begin(); it != m_devices.end(); ++it)
{
nChips += (*it)->getNumberOfChip();
}
return nChips;
}
 
/**
* Gets interfaces
* @param[in] id ID
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
C86CtlErr CRealChipBase::getChipInterface(size_t id, IID riid, void** ppi)
{
if (ppi == NULL)
{
return C86CTL_ERR_INVALID_PARAM;
}
 
for (std::vector<CDevice*>::iterator it = m_devices.begin(); it != m_devices.end(); ++it)
{
CDevice* pDevice = *it;
const size_t nChips = pDevice->getNumberOfChip();
if (id < nChips)
{
return pDevice->getChipInterface(id, riid, ppi);
}
id -= nChips;
}
return C86CTL_ERR_NODEVICE;
}
 
/**
* Destructor
*/
CRealChipBase::CDevice::~CDevice()
{
}
 
} // namespace c86ctl
/**
* @file c86ctlrealchipbase.cpp
* @brief Implementation of IRealChipBase
*/
 
#include "compiler.h"
#include "c86ctlrealchipbase.h"
#include "c86ctlc86box.h"
#include "c86ctlgimic.h"
 
namespace c86ctl
{
 
/*! instance */
CRealChipBase CRealChipBase::sm_instance;
 
/**
* Gets interfaces
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
C86CtlErr CreateInstance(IID riid, void** ppi)
{
if (ppi == NULL)
{
return C86CTL_ERR_INVALID_PARAM;
}
 
if (riid != IID_IRealChipBase)
{
return C86CTL_ERR_UNSUPPORTED;
}
 
CRealChipBase* pBase = CRealChipBase::GetInstance();
pBase->AddRef();
*ppi = pBase;
return C86CTL_ERR_NONE;
}
 
/**
* Constructor
*/
CRealChipBase::CRealChipBase()
: m_nRef(0)
{
}
 
/**
* Destructor
*/
CRealChipBase::~CRealChipBase()
{
}
 
/**
* Increments the reference count
* @return The new reference count
*/
size_t CRealChipBase::AddRef()
{
m_nRef++;
return m_nRef;
}
 
/**
* Decrements the reference count
* @return The new reference count
*/
size_t CRealChipBase::Release()
{
m_nRef--;
return m_nRef;
}
 
/**
* Initialize
* @return C86CTL_ERR
*/
C86CtlErr CRealChipBase::initialize()
{
for (UINT i = 0; i < 1; i++)
{
CGimic* pGimic = new CGimic(i);
if (pGimic->initialize() != C86CTL_ERR_NONE)
{
pGimic->deinitialize();
delete pGimic;
continue;
}
m_devices.push_back(pGimic);
}
 
for (UINT i = 0; i < 1; i++)
{
CC86Box* pC86Box = new CC86Box(i);
if (pC86Box->initialize() != C86CTL_ERR_NONE)
{
pC86Box->deinitialize();
delete pC86Box;
continue;
}
m_devices.push_back(pC86Box);
}
 
return C86CTL_ERR_NONE;
}
 
/**
* Deinitialize
* @return C86CTL_ERR
*/
C86CtlErr CRealChipBase::deinitialize()
{
for (std::vector<CDevice*>::iterator it = m_devices.begin(); it != m_devices.end(); ++it)
{
CDevice* pDevice = *it;
pDevice->deinitialize();
delete pDevice;
}
m_devices.clear();
 
return C86CTL_ERR_NONE;
}
 
/**
* Gets the count of chips
* @return The chips
*/
size_t CRealChipBase::getNumberOfChip()
{
size_t nChips = 0;
for (std::vector<CDevice*>::iterator it = m_devices.begin(); it != m_devices.end(); ++it)
{
nChips += (*it)->getNumberOfChip();
}
return nChips;
}
 
/**
* Gets interfaces
* @param[in] id ID
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
C86CtlErr CRealChipBase::getChipInterface(size_t id, IID riid, void** ppi)
{
if (ppi == NULL)
{
return C86CTL_ERR_INVALID_PARAM;
}
 
for (std::vector<CDevice*>::iterator it = m_devices.begin(); it != m_devices.end(); ++it)
{
CDevice* pDevice = *it;
const size_t nChips = pDevice->getNumberOfChip();
if (id < nChips)
{
return pDevice->getChipInterface(id, riid, ppi);
}
id -= nChips;
}
return C86CTL_ERR_NODEVICE;
}
 
/**
* Destructor
*/
CRealChipBase::CDevice::~CDevice()
{
}
 
} // namespace c86ctl
/np21/x11/ext/c86ctl/c86ctlif.h
@@ -1,58 +1,58 @@
/**
* @file c86ctlif.h
* @brief G.I.M.I.C ƒAƒNƒZƒX ƒNƒ‰ƒX‚̐錾‚¨‚æ‚уCƒ“ƒ^[ƒtƒFƒCƒX‚Ì’è‹`‚ð‚µ‚Ü‚·
*/
 
#pragma once
 
#include <map>
#include "../externalchip.h"
 
namespace c86ctl
{
class IRealChipBase;
class IGimic;
class IRealChip;
}
 
/**
* @brief G.I.M.I.C ƒAƒNƒZƒX ƒNƒ‰ƒX
*/
class C86CtlIf
{
public:
C86CtlIf();
~C86CtlIf();
bool Initialize();
void Deinitialize();
void Reset();
IExternalChip* GetInterface(IExternalChip::ChipType nChipType, UINT nClock);
 
private:
c86ctl::IRealChipBase* m_pChipBase; /*!< ƒ`ƒbƒv ƒx[ƒX ƒCƒ“ƒXƒ^ƒ“ƒX */
 
/**
* @brief ƒ`ƒbƒv ƒNƒ‰ƒX
*/
class Chip : public IExternalChip
{
public:
Chip(C86CtlIf* pC86CtlIf, c86ctl::IRealChip* pRealChip, c86ctl::IGimic* pGimic, ChipType nChipType, UINT nClock);
virtual ~Chip();
virtual ChipType GetChipType();
virtual void Reset();
virtual void WriteRegister(UINT nAddr, UINT8 cData);
virtual INTPTR Message(UINT nMessage, INTPTR nParameter = 0);
 
private:
C86CtlIf* m_pC86CtlIf; /*!< C86Ctl ƒCƒ“ƒXƒ^ƒ“ƒX */
c86ctl::IRealChip* m_pRealChip; /*!< ƒ`ƒbƒv ƒCƒ“ƒXƒ^ƒ“ƒX */
c86ctl::IGimic* m_pGimic; /*!< G.I.M.I.C ƒCƒ“ƒXƒ^ƒ“ƒX */
ChipType m_nChipType; /*!< ƒ`ƒbƒv ƒ^ƒCƒv */
UINT m_nClock; /*!< ƒ`ƒbƒv ƒNƒƒbƒN */
};
 
std::map<int, Chip*> m_chips; /*!< ƒ`ƒbƒv */
void Detach(Chip* pChip);
friend class Chip;
};
/**
* @file c86ctlif.h
* @brief G.I.M.I.C ƒAƒNƒZƒX ƒNƒ‰ƒX‚̐錾‚¨‚æ‚уCƒ“ƒ^[ƒtƒFƒCƒX‚Ì’è‹`‚ð‚µ‚Ü‚·
*/
 
#pragma once
 
#include <map>
#include "../externalchip.h"
 
namespace c86ctl
{
class IRealChipBase;
class IGimic;
class IRealChip;
}
 
/**
* @brief G.I.M.I.C ƒAƒNƒZƒX ƒNƒ‰ƒX
*/
class C86CtlIf
{
public:
C86CtlIf();
~C86CtlIf();
bool Initialize();
void Deinitialize();
void Reset();
IExternalChip* GetInterface(IExternalChip::ChipType nChipType, UINT nClock);
 
private:
c86ctl::IRealChipBase* m_pChipBase; /*!< ƒ`ƒbƒv ƒx[ƒX ƒCƒ“ƒXƒ^ƒ“ƒX */
 
/**
* @brief ƒ`ƒbƒv ƒNƒ‰ƒX
*/
class Chip : public IExternalChip
{
public:
Chip(C86CtlIf* pC86CtlIf, c86ctl::IRealChip* pRealChip, c86ctl::IGimic* pGimic, ChipType nChipType, UINT nClock);
virtual ~Chip();
virtual ChipType GetChipType();
virtual void Reset();
virtual void WriteRegister(UINT nAddr, UINT8 cData);
virtual INTPTR Message(UINT nMessage, INTPTR nParameter = 0);
 
private:
C86CtlIf* m_pC86CtlIf; /*!< C86Ctl ƒCƒ“ƒXƒ^ƒ“ƒX */
c86ctl::IRealChip* m_pRealChip; /*!< ƒ`ƒbƒv ƒCƒ“ƒXƒ^ƒ“ƒX */
c86ctl::IGimic* m_pGimic; /*!< G.I.M.I.C ƒCƒ“ƒXƒ^ƒ“ƒX */
ChipType m_nChipType; /*!< ƒ`ƒbƒv ƒ^ƒCƒv */
UINT m_nClock; /*!< ƒ`ƒbƒv ƒNƒƒbƒN */
};
 
std::map<int, Chip*> m_chips; /*!< ƒ`ƒbƒv */
void Detach(Chip* pChip);
friend class Chip;
};
/np21/x11/ext/c86ctl/c86ctl.h
@@ -1,323 +1,323 @@
/**
* @file c86ctl.h
* @brief Defines of C86CTL
*/
 
#pragma once
 
namespace c86ctl
{
 
/**
* Status code
*/
enum C86CtlErr
{
C86CTL_ERR_NONE = 0, /*!< Succeeded */
C86CTL_ERR_UNKNOWN = -1, /*!< Unknown */
C86CTL_ERR_INVALID_PARAM = -2, /*!< Invalid parameter */
C86CTL_ERR_UNSUPPORTED = -3, /*!< Unspported */
C86CTL_ERR_NODEVICE = -1000, /*!< No devices */
C86CTL_ERR_NOT_IMPLEMENTED = -9999, /*!< Not implemented */
};
 
/**
* Chip type
*/
enum ChipType
{
CHIP_UNKNOWN = 0, /*!< Unknown */
CHIP_OPNA = 0x0001, /*!< OPNA */
CHIP_OPM = 0x0002, /*!< OPM */
CHIP_OPN3L = 0x0003, /*!< OPN3L */
CHIP_OPL3 = 0x0004, /*!< OPL3 */
CHIP_OPLL = 0x0005, /*!< OPLL */
CHIP_SN76489 = 0x0006,
CHIP_AY38910 = 0x0007,
CHIP_YM2203 = 0x0008,
CHIP_YM2612 = 0x0009,
CHIP_YM3526 = 0x000a,
CHIP_YM3812 = 0x000b,
CHIP_YMF271 = 0x000c,
CHIP_YMF278B = 0x000d,
CHIP_YMZ280B = 0x000e,
CHIP_YMF297 = 0x000f,
CHIP_YM2610B = 0x0010,
CHIP_Y8950 = 0x0020,
CHIP_YM3438 = 0x0021,
 
CHIP_YM2608NOADPCM = 0x10000 | CHIP_OPNA,
CHIP_SN76496 = 0x10000 | CHIP_SN76489,
CHIP_YM2149 = 0x10000 | CHIP_AY38910,
CHIP_Y8950ADPCM = 0x10020 | CHIP_Y8950
};
 
/**
* The type of CBUS boards
*/
enum CBUS_BOARD_TYPE
{
CBUS_BOARD_UNKNOWN = 0, /*!< Unknown */
CBUS_BOARD_14 = 0x0001, /*!< NEC PC-9801-14 */
CBUS_BOARD_AMD98 = 0x0011, /*!< SYSTEM SACOM AMD-98 */
CBUS_BOARD_26 = 0x0002, /*!< NEC PC-9801-26, 26K */
CBUS_BOARD_SOUND_ORCHESTRA = 0x0012, /*!< SNE Sound Orchestra */
CBUS_BOARD_SOUND_ORCHESTRA_L = 0x0022, /*!< SNE Sound Orchestra L */
CBUS_BOARD_SOUND_ORCHESTRA_V = 0x0032, /*!< SNE Sound Orchestra V */
CBUS_BOARD_SOUND_ORCHESTRA_VS = 0x0042, /*!< SNE Sound Orchestra VS */
CBUS_BOARD_SOUND_ORCHESTRA_LS = 0x0052, /*!< SNE Sound Orchestra LS */
CBUS_BOARD_SOUND_ORCHESTRA_MATE = 0x0062, /*!< SNE Sound Orchestra MATE */
CBUS_BOARD_MULTIMEDIA_ORCHESTRA = 0x0072, /*!< SNE Multimedia Orchestra */
CBUS_BOARD_LITTLE_ORCHESTRA = 0x0082, /*!< SNE Litte Orchestra */
CBUS_BOARD_LITTLE_ORCHESTRA_L = 0x0092, /*!< SNE Litte Orchestra L */
CBUS_BOARD_LITTLE_ORCHESTRA_RS = 0x00a2, /*!< SNE Litte Orchestra RS */
CBUS_BOARD_LITTLE_ORCHESTRA_LS = 0x00b2, /*!< SNE Litte Orchestra LS */
CBUS_BOARD_LITTLE_ORCHESTRA_SS = 0x00c2, /*!< SNE Litte Orchestra SS */
CBUS_BOARD_LITTLE_ORCHESTRA_MATE = 0x00d2, /*!< SNE Litte Orchestra MATE */
CBUS_BOARD_LITTLE_ORCHESTRA_FELLOW = 0x00e2, /*!< SNE Litte Orchestra FELLOW */
CBUS_BOARD_JOY2 = 0x00f2, /*!< SNE JOY-2 */
CBUS_BOARD_SOUND_GRANPRI = 0x0102, /*!< SNE SOUND GRANPRI */
CBUS_BOARD_TN_F3FM = 0x0112, /*!< TOKYO NEEDS TN-F3FM */
CBUS_BOARD_73 = 0x0003, /*!< NEC PC-9801-73 */
CBUS_BOARD_86 = 0x0023, /*!< NEC PC-9801-86 */
CBUS_BOARD_ASB01 = 0x0043, /*!< SIS Amusement Sound Board ASB-01 */
CBUS_BOARD_SPEAKBOARD = 0x0053, /*!< IDOL JAPAN SpeakBoard */
CBUS_BOARD_SOUNDPLAYER98 = 0x0063, /*!< SPB-98 */
CBUS_BOARD_SECONDBUS86 = 0x0073, /*!< second-bus86 */
CBUS_BOARD_SOUNDEDGE = 0x0083, /*!< sound-edge */
CBUS_BOARD_WINDUO = 0x0093, /*!< win-duo */
CBUS_BOARD_OTOMI = 0x00a3, /*!< MAD FACTORY OTOMI */
CBUS_BOARD_WAVEMASTER = 0x00b3, /*!< Q-Vision WaveMaster */
CBUS_BOARD_WAVESMIT = 0x00c3, /*!< Q-Vision WaveSMIT */
CBUS_BOARD_WAVESTAR = 0x00d3, /*!< Q-Vision WaveStar */
CBUS_BOARD_WSN_A4F = 0x00e3, /*!< Buffalo WSN-A4F/A2F */
CBUS_BOARD_SXM_F = 0x00f3, /*!< SXM-F */
CBUS_BOARD_SRN_F = 0x0103, /*!< SRN-F */
CBUS_BOARD_SB16 = 0x0004, /*!< sound-blaster 16 (CT2720) */
CBUS_BOARD_SB16_2203 = 0x0014, /*!< sound-blaster 16 with YM2203 (CT2720) */
CBUS_BOARD_SB16VALUE = 0x0024, /*!< sound-blaster 16Value (CT3720) */
CBUS_BOARD_POWERWINDOW_T64S = 0x0034, /*!< canopus PowerWindow T64S */
CBUS_BOARD_PCSB2 = 0x0044, /*!< EPSON PCSB2 */
CBUS_BOARD_WGS98S = 0x0054, /*!< COM.TECH WGS-98S */
CBUS_BOARD_SRB_G = 0x0064, /*!< buffalo SRB-G */
CBUS_BOARD_MIDI_ORCHESTRA_MIDI3 = 0x0074, /*!< SNE MIDI ORCHESTRA MIDI-3 */
CBUS_BOARD_SB_AWE32 = 0x0005, /*!< SoundBlaster AWE32 (CT3610) */
CBUS_BOARD_118 = 0x0006 /*!< NEC PC-9801-118 */
};
 
/**
* @brief Device information structure
*/
struct Devinfo
{
char Devname[16]; /*!< Device name */
char Rev; /*!< Revision */
char Serial[15]; /*!< Serial */
};
 
/**
* The interface ID
*/
enum IID
{
IID_IRealChipBase = 0,
IID_IRealChip,
IID_IRealChip2,
IID_IRealChip3,
IID_IGimic,
IID_IGimic2,
IID_IC86Usb
};
 
/**
* @brief The class of IUnknown
*/
class IRealUnknown
{
public:
/**
* Increments the reference count
* @return The new reference count
*/
virtual size_t AddRef() = 0;
 
/**
* Decrements the reference count
* @return The new reference count
*/
virtual size_t Release() = 0;
};
 
/**
* @brief The class of IRealChipBase
*/
class IRealChipBase : public IRealUnknown
{
public:
/**
* Initialize
* @return C86CTL_ERR
*/
virtual C86CtlErr initialize() = 0;
 
/**
* Deinitialize
* @return C86CTL_ERR
*/
virtual C86CtlErr deinitialize() = 0;
 
/**
* Gets the count of chips
* @return The chips
*/
virtual size_t getNumberOfChip() = 0;
 
/**
* Gets interfaces
* @param[in] id ID
* @param[in] riid The interface ID
* @param[out] ppi The pointer of the interface
* @return C86CTL_ERR
*/
virtual C86CtlErr getChipInterface(size_t id, IID riid, void** ppi) = 0;
};
 
/**
* @brief The class of IRealChip
*/
class IRealChip : public IRealUnknown
{
public:
/**
* Reset
* @return C86CTL_ERR
*/
virtual C86CtlErr reset() = 0;
 
/**
* Output
* @param[in] nAddr The address
* @param[in] cData The data
*/
virtual void out(UINT nAddr, UINT8 cData) = 0;
 
/**
* Input
* @param[in] nAddr The address of registers
* @return The data
*/
virtual UINT8 in(UINT nAddr) = 0;
};
 
/**
* @brief The class of IRealChip2
*/
class IRealChip2 : public IRealChip
{
public:
/**
* Gets the current status
* @param[in] nAddr The address
* @param[out] pcStatus The status
* @return C86CTL_ERR
*/
virtual C86CtlErr getChipStatus(UINT nAddr, UINT8* pcStatus) = 0;
 
/**
* Output
* @param[in] nAddr The address
* @param[in] cData The data
*/
virtual void directOut(UINT nAddr, UINT8 cData) = 0;
};
 
/**
* @brief The class of IRealChip3
*/
class IRealChip3 : public IRealChip2
{
public:
/**
* Gets the type of the chip
* @param[out] pnType A pointer of type
* @return C86CTL_ERR
*/
virtual C86CtlErr getChipType(ChipType* pnType) = 0;
};
 
/**
* @brief The class of IGimic
*/
class IGimic : public IRealUnknown
{
public:
/**
* Gets the informations of firm
* @param[out] pnMajor A pointer to the major
* @param[out] pnMinor A pointer to the minor
* @param[out] pnRev A pointer to the revision
* @param[out] pnBuild A pointer to the number of build
* @return C86CTL_ERR
*/
virtual C86CtlErr getFWVer(UINT* pnMajor, UINT* pnMinor, UINT* pnRev, UINT* pnBuild) = 0;
 
/**
* Gets the informations of the mother
* @param[out] pInfo A pointer to the informations
* @return C86CTL_ERR
*/
virtual C86CtlErr getMBInfo(Devinfo* pInfo) = 0;
 
/**
* Gets the informations of modules
* @param[out] pInfo A pointer to the informations
* @return C86CTL_ERR
*/
virtual C86CtlErr getModuleInfo(Devinfo* pInfo) = 0;
 
/**
* Sets the volumes of SSG
* @param[in] cVolume The volume
* @return C86CTL_ERR
*/
virtual C86CtlErr setSSGVolume(UINT8 cVolume) = 0;
 
/**
* Gets the volume of SSG
* @param[out] pcVolume A pointer of the volume
* @return C86CTL_ERR
*/
virtual C86CtlErr getSSGVolume(UINT8* pcVolume) = 0;
 
/**
* Sets the clock
* @param[in] nClock The clock
* @return C86CTL_ERR
*/
virtual C86CtlErr setPLLClock(UINT nClock) = 0;
 
/**
* Gets the clock
* @param[out] pnClock A pointer to the clock
* @return C86CTL_ERR
*/
virtual C86CtlErr getPLLClock(UINT* pnClock) = 0;
};
 
/**
* @brief The class of IGimic2
*/
class IGimic2 : public IGimic
{
public:
/**
* Gets the type of the modules
* @param[out] pnType The type
* @return C86CTL_ERR
*/
virtual C86CtlErr getModuleType(ChipType* pnType) = 0;
};
 
C86CtlErr CreateInstance(IID riid, void** ppi);
 
}
/**
* @file c86ctl.h
* @brief Defines of C86CTL
*/
 
#pragma once
 
namespace c86ctl
{
 
/**
* Status code
*/
enum C86CtlErr
{
C86CTL_ERR_NONE = 0, /*!< Succeeded */
C86CTL_ERR_UNKNOWN = -1, /*!< Unknown */
C86CTL_ERR_INVALID_PARAM = -2, /*!< Invalid parameter */
C86CTL_ERR_UNSUPPORTED = -3, /*!< Unspported */
C86CTL_ERR_NODEVICE = -1000, /*!< No devices */
C86CTL_ERR_NOT_IMPLEMENTED = -9999, /*!< Not implemented */
};
 
/**
* Chip type
*/
enum ChipType
{
CHIP_UNKNOWN = 0, /*!< Unknown */
CHIP_OPNA = 0x0001, /*!< OPNA */
CHIP_OPM = 0x0002, /*!< OPM */
CHIP_OPN3L = 0x0003, /*!< OPN3L */
CHIP_OPL3 = 0x0004, /*!< OPL3 */
CHIP_OPLL = 0x0005, /*!< OPLL */
CHIP_SN76489 = 0x0006,
CHIP_AY38910 = 0x0007,
CHIP_YM2203 = 0x0008,
CHIP_YM2612 = 0x0009,
CHIP_YM3526 = 0x000a,
CHIP_YM3812 = 0x000b,
CHIP_YMF271 = 0x000c,
CHIP_YMF278B = 0x000d,
CHIP_YMZ280B = 0x000e,
CHIP_YMF297 = 0x000f,
CHIP_YM2610B = 0x0010,
CHIP_Y8950 = 0x0020,
CHIP_YM3438 = 0x0021,
 
CHIP_YM2608NOADPCM = 0x10000 | CHIP_OPNA,
CHIP_SN76496 = 0x10000 | CHIP_SN76489,
CHIP_YM2149 = 0x10000 | CHIP_AY38910,
CHIP_Y8950ADPCM = 0x10020 | CHIP_Y8950
};
 
/**
* The type of CBUS boards
*/
enum CBUS_BOARD_TYPE
{
CBUS_BOARD_UNKNOWN = 0, /*!< Unknown */
CBUS_BOARD_14 = 0x0001, /*!< NEC PC-9801-14 */
CBUS_BOARD_AMD98 = 0x0011, /*!< SYSTEM SACOM AMD-98 */
CBUS_BOARD_26 = 0x0002, /*!< NEC PC-9801-26, 26K */
CBUS_BOARD_SOUND_ORCHESTRA = 0x0012, /*!< SNE Sound Orchestra */
CBUS_BOARD_SOUND_ORCHESTRA_L = 0x0022, /*!< SNE Sound Orchestra L */
CBUS_BOARD_SOUND_ORCHESTRA_V = 0x0032, /*!< SNE Sound Orchestra V */
CBUS_BOARD_SOUND_ORCHESTRA_VS = 0x0042, /*!< SNE Sound Orchestra VS */
CBUS_BOARD_SOUND_ORCHESTRA_LS = 0x0052, /*!< SNE Sound Orchestra LS */
CBUS_BOARD_SOUND_ORCHESTRA_MATE = 0x0062, /*!< SNE Sound Orchestra MATE */
CBUS_BOARD_MULTIMEDIA_ORCHESTRA = 0x0072, /*!< SNE Multimedia Orchestra */
CBUS_BOARD_LITTLE_ORCHESTRA = 0x0082, /*!< SNE Litte Orchestra */
CBUS_BOARD_LITTLE_ORCHESTRA_L = 0x0092, /*!< SNE Litte Orchestra L */
CBUS_BOARD_LITTLE_ORCHESTRA_RS = 0x00a2, /*!< SNE Litte Orchestra RS */
CBUS_BOARD_LITTLE_ORCHESTRA_LS = 0x00b2, /*!< SNE Litte Orchestra LS */
CBUS_BOARD_LITTLE_ORCHESTRA_SS = 0x00c2, /*!< SNE Litte Orchestra SS */
CBUS_BOARD_LITTLE_ORCHESTRA_MATE = 0x00d2, /*!< SNE Litte Orchestra MATE */
CBUS_BOARD_LITTLE_ORCHESTRA_FELLOW = 0x00e2, /*!< SNE Litte Orchestra FELLOW */
CBUS_BOARD_JOY2 = 0x00f2, /*!< SNE JOY-2 */
CBUS_BOARD_SOUND_GRANPRI = 0x0102, /*!< SNE SOUND GRANPRI */
CBUS_BOARD_TN_F3FM = 0x0112, /*!< TOKYO NEEDS TN-F3FM */
CBUS_BOARD_73 = 0x0003, /*!< NEC PC-9801-73 */
CBUS_BOARD_86 = 0x0023, /*!< NEC PC-9801-86 */
CBUS_BOARD_ASB01 = 0x0043, /*!< SIS Amusement Sound Board ASB-01 */
CBUS_BOARD_SPEAKBOARD = 0x0053, /*!< IDOL JAPAN SpeakBoard */
CBUS_BOARD_SOUNDPLAYER98 = 0x0063, /*!< SPB-98 */
CBUS_BOARD_SECONDBUS86 = 0x0073, /*!< second-bus86 */
CBUS_BOARD_SOUNDEDGE = 0x0083, /*!< sound-edge */
CBUS_BOARD_WINDUO = 0x0093, /*!< win-duo */
CBUS_BOARD_OTOMI = 0x00a3, /*!< MAD FACTORY OTOMI */
CBUS_BOARD_WAVEMASTER = 0x00b3, /*!< Q-Vision WaveMaster */
CBUS_BOARD_WAVESMIT = 0x00c3, /*!< Q-Vision WaveSMIT */