add nds-win32 simulation project

This commit is contained in:
yui 2009-03-24 13:52:54 +00:00
parent 91661eadec
commit fadc6cd6d9
109 changed files with 12605 additions and 0 deletions

48
nds/bss.x86 Normal file
View File

@ -0,0 +1,48 @@
section .bss
global _mainmem
global _gram
global _tram
global _pcg
global _font_ank
global _z80core
global _dma
global _z80flag
global _iocore
global _ppi
global _crtc
global _nds9psg
global _subcpu
global _ctc
global _cgrom
global _fdc
global _vramupd
align 4
_mainmem resb 0x10000
_gram resb 0xc000
_tram resd 0x800
_pcg resb 0x1800
_font_ank resb 0x800
_gram2 resb 0xc000
align 4
_z80core resb 0x40
_dma resb 0x40
_z80flag resb 0x300
_iocore resb 0x214
_ppi resb 0x4
_crtc resb 0x48
_nds9psg resb 0x18
resb 0x08
_subcpu resb 0x4c
resb 4
_ctc resb 0xe4
_cgrom resb 0xc
_fdc resb 0x40
_vramupd resb 0x800
ends

63
nds/fdd/d88head.h Normal file
View File

@ -0,0 +1,63 @@
enum {
D88_TRACKMAX = 164,
D88_HEADERSIZE = 0x20 + (D88_TRACKMAX * 4)
};
#if defined(__GNUC__)
// D88ヘッダ (size: 2b0h bytes)
typedef struct {
UINT8 fd_name[17]; // Disk Name
UINT8 reserved1[9]; // Reserved
UINT8 protect; // Write Protect bit:4
UINT8 fd_type; // Disk Format
UINT8 fd_size[4]; // Disk Size
UINT8 trkptr[D88_TRACKMAX][4];
} __attribute__ ((packed)) _D88HEAD, *D88HEAD;
// D88セクタ (size: 16bytes)
typedef struct {
UINT8 c;
UINT8 h;
UINT8 r;
UINT8 n;
UINT8 sectors[2]; // Sector Count
UINT8 mfm_flg; // sides
UINT8 del_flg; // DELETED DATA
UINT8 stat; // STATUS (FDC ret)
UINT8 seektime; // Seek Time
UINT8 reserved[3]; // Reserved
UINT8 rpm_flg; // rpm 0:1.2 1:1.44
UINT8 size[2]; // Sector Size
} __attribute__ ((packed)) _D88SEC, *D88SEC;
#else
#pragma pack(push, 1)
// D88ヘッダ (size: 2b0h bytes)
typedef struct {
UINT8 fd_name[17]; // Disk Name
UINT8 reserved1[9]; // Reserved
UINT8 protect; // Write Protect bit:4
UINT8 fd_type; // Disk Format
UINT8 fd_size[4]; // Disk Size
UINT8 trkptr[D88_TRACKMAX][4];
} _D88HEAD, *D88HEAD;
// D88セクタ (size: 16bytes)
typedef struct {
UINT8 c;
UINT8 h;
UINT8 r;
UINT8 n;
UINT8 sectors[2]; // Sector Count
UINT8 mfm_flg; // sides
UINT8 del_flg; // DELETED DATA
UINT8 stat; // STATUS (FDC ret)
UINT8 seektime; // Seek Time
UINT8 reserved[3]; // Reserved
UINT8 rpm_flg; // rpm 0:1.2 1:1.44
UINT8 size[2]; // Sector Size
} _D88SEC, *D88SEC;
#pragma pack(pop)
#endif

113
nds/fdd/fdd_2d.c Normal file
View File

@ -0,0 +1,113 @@
#include "compiler.h"
#include "pccore.h"
#include "fddfile.h"
#include "fdd_2d.h"
static const _XDFINFO supportxdf[] = {
{0, 80, 16, 1, DISKTYPE_2D},
{0, 154, 26, 1, DISKTYPE_2HD}};
static REG8 fdd2d_seek(FDDFILE fdd, REG8 media, UINT track) {
if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks)) {
return(FDDSTAT_SEEKERR);
}
return(0x00);
}
static REG8 fdd2d_readp(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
void **ptr, UINT *size) {
UINT secsize;
long pos;
if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) ||
(sc == 0) || (sc > fdd->inf.xdf.sectors)) {
goto fd2r_err;
}
secsize = 1 << (7 + fdd->inf.xdf.n);
*size = secsize;
if (ptr) {
pos = ((track * fdd->inf.xdf.sectors) + (sc - 1)) * secsize;
pos += fdd->inf.xdf.headersize;
*ptr = (void *)(fdd->romptr + pos);
}
return(0x00);
fd2r_err:
return(FDDSTAT_RECNFND);
}
static REG8 fdd2d_crc(FDDFILE fdd, REG8 media, UINT track, UINT num,
UINT8 *ptr) {
if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks) ||
(num >= fdd->inf.xdf.sectors)) {
return(FDDSTAT_RECNFND);
}
ptr[0] = (UINT8)(track >> 1);
ptr[1] = (UINT8)(track & 1);
ptr[2] = (UINT8)(num + 1);
ptr[3] = fdd->inf.xdf.n;
ptr[4] = 0; // CRC(Lo)
ptr[5] = 0; // CRC(Hi)
return(0x00);
}
#if defined(SUPPORT_DISKEXT)
static UINT32 fdd2d_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) {
UINT32 ret;
if ((media != fdd->inf.xdf.media) || (track >= fdd->inf.xdf.tracks)) {
return(0);
}
if ((sc == 0) || (sc > fdd->inf.xdf.sectors)) {
ret = fdd->inf.xdf.sectors;
}
else {
ret = sc;
}
return((16 << fdd->inf.xdf.sectors) + ret);
}
#endif
// ----
BRESULT fdd2d_set(FDDFILE fdd, const UINT8 *romptr, UINT romsize) {
const _XDFINFO *xdf;
const _XDFINFO *xdfterm;
UINT size;
xdf = supportxdf;
xdfterm = supportxdf + NELEMENTS(supportxdf);
while(xdf < xdfterm) {
size = xdf->tracks;
size *= xdf->sectors;
size <<= (7 + xdf->n);
if (size == romsize) {
fdd->type = DISKTYPE_BETA;
fdd->seek = fdd2d_seek;
fdd->readp = fdd2d_readp;
fdd->crc = fdd2d_crc;
#if defined(SUPPORT_DISKEXT)
fdd->sec = fdd2d_sec;
#endif
fdd->inf.xdf = *xdf;
return(SUCCESS);
}
xdf++;
}
return(FAILURE);
}
void fdd2d_eject(FDDFILE fdd) {
(void)fdd;
}

12
nds/fdd/fdd_2d.h Normal file
View File

@ -0,0 +1,12 @@
#ifdef __cplusplus
extern "C" {
#endif
BRESULT fdd2d_set(FDDFILE fdd, const UINT8 *romptr, UINT romsize);
void fdd2d_eject(FDDFILE fdd);
#ifdef __cplusplus
}
#endif

256
nds/fdd/fdd_d88.c Normal file
View File

@ -0,0 +1,256 @@
#include "compiler.h"
#include "pccore.h"
#include "fddfile.h"
#include "fdd_d88.h"
static UINT32 nexttrackptr(FDDFILE fdd, UINT32 fptr, UINT32 last) {
const UINT8 *ptr;
UINT t;
UINT32 cur;
ptr = fdd->inf.d88.hdr->trkptr[0];
for (t=0; t<164; t++) {
#if defined(BYTESEX_LITTLE)
cur = *(UINT32 *)ptr;
#else
cur = LOADINTELDWORD(ptr);
#endif
ptr += 4;
if ((cur > fptr) && (cur < last)) {
last = cur;
}
}
return(last);
}
static BRESULT trackseek(FDDFILE fdd, REG8 media, UINT track) {
const _D88HEAD *hdr;
UINT32 fptr;
UINT size;
const _D88SEC *sec;
UINT maxsectors;
UINT sectors;
UINT secsize;
if ((fdd->inf.d88.curtrkp != NULL) &&
(fdd->inf.d88.curmedia == media) &&
(fdd->inf.d88.curtrk == track)) {
return(SUCCESS);
}
fdd->inf.d88.curtrkp = NULL;
fdd->inf.d88.cursectors = 0;
hdr = fdd->inf.d88.hdr;
if (media != (REG8)((hdr->fd_type >> 4))) {
goto dtrd_err1;
}
if (track >= 164) {
goto dtrd_err1;
}
#if defined(BYTESEX_LITTLE)
fptr = *(UINT32 *)(hdr->trkptr + track);
#else
fptr = LOADINTELDWORD(hdr->trkptr + track);
#endif
if (fptr == 0) {
goto dtrd_err1;
}
size = nexttrackptr(fdd, fptr, fdd->inf.d88.fd_size) - fptr;
sec = (D88SEC)(((UINT8 *)hdr) + fptr);
fdd->inf.d88.curmedia = media;
fdd->inf.d88.curtrk = track;
fdd->inf.d88.curtrkp = sec;
fdd->inf.d88.cursecsize = size;
// セクタ数チェック
maxsectors = 0;
if (size >= sizeof(_D88SEC)) {
maxsectors = LOADINTELWORD(sec->sectors);
}
sectors = 0;
while(sectors < maxsectors) {
secsize = LOADINTELWORD(sec->size);
secsize += sizeof(_D88SEC);
if (size < secsize) {
break;
}
size -= secsize;
maxsectors = LOADINTELWORD(sec->sectors);
sec = (D88SEC)(((UINT8 *)sec) + secsize);
sectors++;
}
fdd->inf.d88.cursectors = sectors;
return(SUCCESS);
dtrd_err1:
return(FAILURE);
}
static D88SEC sectorseek(FDDFILE fdd, REG8 r) {
const _D88SEC *sec;
UINT sectors;
UINT size;
sec = fdd->inf.d88.curtrkp;
sectors = fdd->inf.d88.cursectors;
while(sectors) {
sectors--;
if (sec->r == r) {
return((D88SEC)sec);
}
size = LOADINTELWORD(sec->size);
size += sizeof(_D88SEC);
sec = (D88SEC)(((UINT8 *)sec) + size);
}
return(NULL);
}
// ----
static REG8 fddd88_seek(FDDFILE fdd, REG8 media, UINT track) {
if (trackseek(fdd, media, track) == SUCCESS) {
return(0x00);
}
else {
return(FDDSTAT_SEEKERR);
}
}
static REG8 fddd88_readp(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
void **ptr, UINT *size) {
const _D88SEC *sec;
REG8 ret;
TRACEOUT(("d88 read %d:%.2x", track, sc));
if (trackseek(fdd, media, track) != SUCCESS) {
goto fd8r_err;
}
sec = sectorseek(fdd, sc);
if (sec == NULL) {
goto fd8r_err;
}
ret = 0x00;
if (sec->del_flg) {
ret |= FDDSTAT_RECTYPE;
}
if (sec->stat) {
ret |= FDDSTAT_CRCERR;
}
if (ptr) {
*ptr = (void *)(sec + 1);
}
*size = LOADINTELWORD(sec->size);
return(ret);
fd8r_err:
return(FDDSTAT_RECNFND);
}
static REG8 fddd88_crc(FDDFILE fdd, REG8 media, UINT track, UINT num,
UINT8 *ptr) {
const _D88SEC *sec;
UINT sectors;
UINT size;
if (trackseek(fdd, media, track) != SUCCESS) {
return(FDDSTAT_RECNFND);
}
sec = fdd->inf.d88.curtrkp;
sectors = fdd->inf.d88.cursectors;
if (num >= sectors) {
return(FDDSTAT_RECNFND);
}
while(num) {
num--;
size = LOADINTELWORD(sec->size);
size += sizeof(_D88SEC);
sec = (D88SEC)(((UINT8 *)sec) + size);
}
ptr[0] = sec->c;
ptr[1] = sec->h;
ptr[2] = sec->r;
ptr[3] = sec->n;
ptr[4] = 0;
ptr[5] = 0;
// fdc.s.rreg = sec->c; // メルヘンヴェール
if (sec->stat) {
return(FDDSTAT_CRCERR);
}
return(0x00);
}
#if defined(SUPPORT_DISKEXT)
static UINT32 fddd88_sec(FDDFILE fdd, REG8 media, UINT track, REG8 sc) {
const _D88SEC *sec;
UINT sectors;
UINT num;
UINT size;
if (trackseek(fdd, media, track) != SUCCESS) {
return(0);
}
sec = fdd->inf.d88.curtrkp;
sectors = fdd->inf.d88.cursectors;
num = 0;
while(num < sectors) {
if (sec->r == sc) {
break;
}
size = LOADINTELWORD(sec->size);
size += sizeof(_D88SEC);
sec = (D88SEC)(((UINT8 *)sec) + size);
num++;
}
return((UINT32)(sectors << 16) + num);
}
#endif
// ----
BRESULT fddd88_set(FDDFILE fdd, const UINT8 *romptr, UINT romsize) {
const _D88HEAD *hdr;
UINT fd_size;
if (romsize < D88_HEADERSIZE) {
goto fdst_err;
}
hdr = (D88HEAD)romptr;
#if defined(BYTESEX_LITTLE)
fd_size = *(UINT32 *)hdr->fd_size;
#else
fd_size = LOADINTELDWORD(hdr->fd_size);
#endif
fd_size = min(fd_size, romsize);
fdd->inf.d88.hdr = (D88HEAD)romptr;
fdd->inf.d88.fd_size = fd_size;
fdd->type = DISKTYPE_D88;
fdd->seek = fddd88_seek;
fdd->readp = fddd88_readp;
fdd->crc = fddd88_crc;
#if defined(SUPPORT_DISKEXT)
fdd->sec = fddd88_sec;
#endif
return(SUCCESS);
fdst_err:
return(FAILURE);
}
void fddd88_eject(FDDFILE fdd) {
(void)fdd;
}

12
nds/fdd/fdd_d88.h Normal file
View File

@ -0,0 +1,12 @@
#ifdef __cplusplus
extern "C" {
#endif
BRESULT fddd88_set(FDDFILE fdd, const UINT8 *romptr, UINT romsize);
void fddd88_eject(FDDFILE fdd);
#ifdef __cplusplus
}
#endif

8
nds/fdd/fdd_mtr.h Normal file
View File

@ -0,0 +1,8 @@
#define fddmtr_initialize()
#define fddmtr_motormove()
#define fddmtr_callback(t)
#define fddmtr_waitsec(v)
#define fddmtr_drvset()
#define fddmtr_isbusy() (FALSE)

141
nds/fdd/fddfile.c Normal file
View File

@ -0,0 +1,141 @@
#include "compiler.h"
#include "pccore.h"
#include "iocore.h"
#include "fddfile.h"
#include "fdd_2d.h"
#include "fdd_d88.h"
_FDDFILE fddfile[MAX_FDDFILE];
static REG8 dummyseek(FDDFILE fdd, REG8 media, UINT track) {
(void)fdd;
(void)media;
(void)track;
return(FDDSTAT_SEEKERR);
}
static REG8 dummyreadp(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
void **ptr, UINT *size) {
(void)fdd;
(void)media;
(void)track;
(void)sc;
(void)ptr;
(void)size;
return(FDDSTAT_RECNFND);
}
static REG8 dummywrite(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
const UINT8 *ptr, UINT size) {
(void)fdd;
(void)media;
(void)track;
(void)sc;
(void)ptr;
(void)size;
return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT);
}
static REG8 dummycrc(FDDFILE fdd, REG8 media, UINT track, UINT num,
UINT8 *ptr) {
(void)fdd;
(void)media;
(void)track;
(void)num;
(void)ptr;
return(FDDSTAT_RECNFND);
}
static void setempty(FDDFILE fdd) {
ZeroMemory(fdd, sizeof(_FDDFILE));
fdd->seek = dummyseek;
fdd->readp = dummyreadp;
fdd->write = dummywrite;
fdd->crc = dummycrc;
}
// ----
void fddfile_initialize(void) {
UINT i;
for (i=0; i<MAX_FDDFILE; i++) {
setempty(fddfile + i);
}
}
BRESULT fddfile_diskready(REG8 drv) {
if ((drv >= MAX_FDDFILE) || (fddfile[drv].type == DISKTYPE_NOTREADY)) {
return(FALSE);
}
return(TRUE);
}
BRESULT fddfile_diskprotect(REG8 drv) {
if ((drv >= MAX_FDDFILE) || (!fddfile[drv].protect)) {
return(FALSE);
}
return(TRUE);
}
BRESULT fddfile_set(REG8 drv, UINT ftype, const UINT8 *romptr, UINT romsize) {
FDDFILE fdd;
BRESULT r;
if (drv >= MAX_FDDFILE) {
return(FAILURE);
}
fddfile_eject(drv);
fdd = fddfile + drv;
switch(ftype) {
case FTYPE_BETA:
r = fdd2d_set(fdd, romptr, romsize);
break;
case FTYPE_D88:
r = fddd88_set(fdd, romptr, romsize);
break;
default:
r = FAILURE;
break;
}
if (r == SUCCESS) {
fdd->romptr = romptr;
fdd->romsize = romsize;
fdd->ftype = ftype;
fdd->protect = TRUE;
}
return(r);
}
void fddfile_eject(REG8 drv) {
FDDFILE fdd;
if (drv >= MAX_FDDFILE) {
return;
}
fdd = fddfile + drv;
switch(fdd->type) {
case DISKTYPE_BETA:
fdd2d_eject(fdd);
case DISKTYPE_D88:
fddd88_eject(fdd);
}
setempty(fdd);
}

118
nds/fdd/fddfile.h Normal file
View File

@ -0,0 +1,118 @@
// #define SUPPORT_DISKEXT
#include "d88head.h"
enum {
MAX_FDDFILE = 4
};
enum {
DISKTYPE_NOTREADY = 0,
DISKTYPE_BETA,
DISKTYPE_D88
};
enum {
DISKTYPE_2D = 0,
DISKTYPE_2DD,
DISKTYPE_2HD
};
enum {
FDDSTAT_BUSY = 0x01,
FDDSTAT_INDEX = 0x02,
FDDSTAT_DRQ = 0x02,
FDDSTAT_TRACK00 = 0x04,
FDDSTAT_LOSTDATA = 0x04,
FDDSTAT_CRCERR = 0x08,
FDDSTAT_SEEKERR = 0x10,
FDDSTAT_RECNFND = 0x10,
FDDSTAT_HEADENG = 0x20,
FDDSTAT_RECTYPE = 0x20,
FDDSTAT_WRITEFAULT = 0x20,
FDDSTAT_WRITEP = 0x40,
FDDSTAT_NOTREADY = 0x80
};
typedef struct {
UINT8 c;
UINT8 h;
UINT8 r;
UINT8 n;
UINT size;
} TAOSEC;
typedef struct _fddfile _FDDFILE;
typedef struct _fddfile *FDDFILE;
typedef REG8 (*FDDSEEK)(FDDFILE fdd, REG8 media, UINT track);
typedef REG8 (*FDDREADP)(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
void **ptr, UINT *size);
typedef REG8 (*FDDWRITE)(FDDFILE fdd, REG8 media, UINT track, REG8 sc,
const UINT8 *ptr, UINT size);
typedef REG8 (*FDDCRC)(FDDFILE fdd, REG8 media, UINT track, UINT num,
UINT8 *ptr);
#if defined(SUPPORT_DISKEXT)
typedef UINT32 (*FDDSEC)(FDDFILE fdd, REG8 media, UINT track, REG8 sc);
#endif
typedef struct {
UINT32 headersize;
UINT8 tracks;
UINT8 sectors;
UINT8 n;
UINT8 media;
} _XDFINFO, *XDFINFO;
typedef struct {
const _D88HEAD *hdr;
UINT fd_size;
UINT curmedia;
UINT curtrk;
const _D88SEC *curtrkp;
UINT cursecsize;
UINT cursectors;
} _D88INFO, *D88INFO;
struct _fddfile {
UINT8 type;
UINT8 protect;
UINT8 padding[2];
const UINT8 *romptr;
UINT romsize;
UINT32 ftype;
FDDSEEK seek;
FDDREADP readp;
FDDWRITE write;
FDDCRC crc;
#if defined(SUPPORT_DISKEXT)
FDDSEC sec;
#endif
union {
_XDFINFO xdf;
_D88INFO d88;
} inf;
};
#ifdef __cplusplus
extern "C" {
#endif
extern _FDDFILE fddfile[MAX_FDDFILE];
void fddfile_initialize(void);
BRESULT fddfile_diskready(REG8 drv);
BRESULT fddfile_diskprotect(REG8 drv);
BRESULT fddfile_set(REG8 drv, UINT ftype, const UINT8 *romptr, UINT romsize);
void fddfile_eject(REG8 drv);
#ifdef __cplusplus
}
#endif

63
nds/ipcxfer.h Normal file
View File

@ -0,0 +1,63 @@
// ---- PSG
union tagNdsPsgReg
{
struct
{
UINT8 cTune[3][2]; // 0
UINT8 cNoise; // 6
UINT8 cMixer; // 7
UINT8 cVol[3]; // 8
UINT8 cEnvTime[2]; // b
UINT8 cEnv; // d
} r;
UINT8 b[0x0e];
};
typedef union tagNdsPsgReg NDSPSGREG;
struct tagNdsPsgXfer
{
NDSPSGREG reg;
UINT8 cUpdateReg;
UINT8 cUpdateEnv;
UINT32 uClock;
};
typedef struct tagNdsPsgXfer NDSPSGXFER;
typedef struct tagNdsPsgXfer *PNDSPSGXFER;
// --- Keyboard
#define SOFTKBD_KEYCODEMASK 0x7f
#define SOFTKBD_KEYDOWN 0x00
#define SOFTKBD_KEYUP 0x80
#define SOFTKBD_KEYFLAGBIT 0x80
#define SOFTKBD_NC 0xff
struct tagNdsKbdXfer
{
UINT8 cKey;
};
typedef struct tagNdsKbdXfer NDSKBDXFER;
typedef struct tagNdsKbdXfer *PNDSKBDXFER;
// ---- Master
struct tagNdsIpcXfer
{
NDSPSGXFER psg;
NDSKBDXFER kbd;
};
typedef struct tagNdsIpcXfer NDSIPCXFER;
typedef struct tagNdsIpcXfer *PNDSIPCXFER;
#define IPCXFERBASE ((PNDSIPCXFER)(IPCBASE))
#define IPCPSGXFER (&IPCXFERBASE->psg)
#define IPCKEYXFER (&IPCXFERBASE->kbd)

96
nds/joymng.cpp Normal file
View File

@ -0,0 +1,96 @@
#include "compiler.h"
#include "libnds.h"
#include "iocore.h"
#include "nds9psg.h"
#include "makescrn.h"
enum
{
JOY_LEFT_BIT = 0x04,
JOY_RIGHT_BIT = 0x08,
JOY_UP_BIT = 0x01,
JOY_DOWN_BIT = 0x02,
JOY_BTN1_BIT = 0x40,
JOY_BTN2_BIT = 0x20,
JOY_BTN3_BIT = 0x80,
JOY_BTN4_BIT = 0x10
};
static UINT s_uLastButton;
void joymng_setflags()
{
const REG16 wFlag = REG_KEYINPUT;
REG8 cJoy = 0xff;
if (!(wFlag & KEY_L))
{
const UINT uModify = s_uLastButton & (~wFlag);
s_uLastButton = wFlag;
if (uModify & KEY_RIGHT)
{
if (scrnpos.x < 80)
{
scrnpos.x++;
}
}
if (uModify & KEY_LEFT)
{
if (scrnpos.x)
{
scrnpos.x--;
}
}
if (uModify & KEY_UP)
{
if (scrnpos.y)
{
scrnpos.y--;
}
}
if (uModify & KEY_DOWN)
{
if (scrnpos.y < 25)
{
scrnpos.y++;
}
}
if (uModify & (KEY_RIGHT | KEY_LEFT | KEY_UP | KEY_DOWN))
{
crtc.e.scrnallflash = 1;
}
return;
}
s_uLastButton = 0;
if (!(wFlag & KEY_A))
{
cJoy ^= JOY_BTN1_BIT;
}
if (!(wFlag & KEY_B))
{
cJoy ^= JOY_BTN2_BIT;
}
if (!(wFlag & KEY_RIGHT))
{
cJoy ^= JOY_RIGHT_BIT;
}
if (!(wFlag & KEY_LEFT))
{
cJoy ^= JOY_LEFT_BIT;
}
if (!(wFlag & KEY_UP))
{
cJoy ^= JOY_UP_BIT;
}
if (!(wFlag & KEY_DOWN))
{
cJoy ^= JOY_DOWN_BIT;
}
// こっちからセットしてやる
nds9psg.reg.r.cIo1 = cJoy;
}

5
nds/joymng.h Normal file
View File

@ -0,0 +1,5 @@
void joymng_setflags();
#define joymng_getstat() (0xff)

11
nds/mousemng.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "compiler.h"
#include "mousemng.h"
REG8 mousemng_getstat(SINT16 *pwX, SINT16 *pwY, BRESULT bClear)
{
*pwX = 0;
*pwY = 0;
return 0;
}

12
nds/mousemng.h Normal file
View File

@ -0,0 +1,12 @@
#ifdef __cplusplus
extern "C"
{
#endif
REG8 mousemng_getstat(SINT16 *pwX, SINT16 *pwY, BRESULT bClear);
#ifdef __cplusplus
}
#endif

402
nds/patch/ctc.c Normal file
View File

@ -0,0 +1,402 @@
#define CTCFAST
#include "compiler.h"
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "nevent.h"
#include "ievent.h"
static SINT32 minclock(const CTCCH *pCh)
{
UINT32 uEvent;
UINT i;
UINT32 uClock;
uEvent = 0x01000000;
for (i=0; i<3; i++)
{
if ((pCh->s.cmd[i] & 0x82) == 0x80)
{
uClock = pCh->s.count[i];
uEvent = min(uEvent, uClock);
}
}
if ((pCh->s.cmd[3] & 0x82) == 0x80)
{
uClock = pCh->s.count[3];
if (pCh->s.cmd[3] & 0x40)
{
uClock = (uClock - 1) * pCh->s.countmax[0];
uClock += pCh->s.count[0];
}
uEvent = min(uEvent, uClock);
}
if (uEvent == 0)
{
uEvent = 1;
}
return uEvent;
}
#if defined(USE_ARMROUTINE)
extern REG8 LONG_CALL ctcwork(CTCCH *pCh);
#else /* defined(USE_ARMROUTINE) */
static REG8 ctcwork(CTCCH *pCh)
{
UINT32 uBaseClock;
SINT32 nStepClock;
REG8 cIntr;
SINT32 nPulse3;
SINT32 nPulse;
SINT32 nCount;
uBaseClock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
nStepClock = uBaseClock - pCh->s.baseclock;
#if defined(FIX_Z80A) /* 2x2MHz */
pCh->s.baseclock += nStepClock & (~1);
nStepClock = nStepClock >> 1;
#else /* defined(FIX_Z80A) */
nStepClock /= pccore.multiple;
pCh->s.baseclock += nStepClock * pccore.multiple;
#endif /* defined(FIX_Z80A) */
cIntr = 0;
nPulse3 = 0;
// 0
if (!(pCh->s.cmd[0] & 0x02))
{
nPulse = nStepClock;
nCount = pCh->s.count[0];
nCount -= nPulse;
if (nCount <= 0)
{
#if defined(CTCFAST)
nCount += pCh->s.countmax[0];
if (nCount <= 0)
{
nPulse3 = (0 - nCount) / pCh->s.countmax[0];
nPulse3 += 1;
nCount += nPulse3 * pCh->s.countmax[0];
}
nPulse3 += 1;
#else
nPulse3 = (0 - nCount) / pCh->s.countmax[0];
nPulse3 += 1;
nCount += nPulse3 * pCh->s.countmax[0];
#endif
cIntr |= (pCh->s.cmd[0] & 0x80) >> (7 - 0);
}
pCh->s.count[0] = nCount;
}
// 3
if (!(pCh->s.cmd[3] & 0x02))
{
if (!(pCh->s.cmd[3] & 0x40))
{
nPulse3 = nStepClock;
}
nCount = pCh->s.count[3];
nCount -= nPulse3;
if (nCount <= 0)
{
#if defined(CTCFAST)
nCount += pCh->s.countmax[3];
if (nCount <= 0)
{
nCount = pCh->s.countmax[3] - ((0 - nCount) % pCh->s.countmax[3]);
}
#else
nCount = pCh->s.countmax[3] - ((0 - nCount) % pCh->s.countmax[3]);
#endif
cIntr |= (pCh->s.cmd[3] & 0x80) >> (7 - 3);
/* TRACEOUT(("<- ch.3 %.8x [%.2x:%.2x %.2x:%.2x]", baseclock, pCh->s.basecnt[0], pCh->s.cmd[0], pCh->s.basecnt[3], pCh->s.cmd[3])); */
}
pCh->s.count[3] = nCount;
}
// 1
if (!(pCh->s.cmd[1] & 0x02))
{
nPulse = nStepClock;
nCount = pCh->s.count[1];
nCount -= nPulse;
if (nCount <= 0)
{
nCount = pCh->s.countmax[1] - ((0 - nCount) % pCh->s.countmax[1]);
cIntr |= (pCh->s.cmd[1] & 0x80) >> (7 - 1);
}
pCh->s.count[1] = nCount;
}
// 2
if (!(pCh->s.cmd[2] & 0x02))
{
nPulse = nStepClock;
nCount = pCh->s.count[2];
nCount -= nPulse;
if (nCount <= 0)
{
nCount = pCh->s.countmax[2] - ((0 - nCount) % pCh->s.countmax[2]);
cIntr |= (pCh->s.cmd[2] & 0x80) >> (7 - 2);
}
pCh->s.count[2] = nCount;
}
return cIntr;
}
#endif /* defined(USE_ARMROUTINE) */
static void ctcstep(CTCCH *pCh)
{
REG8 cIntr;
cIntr = ctcwork(pCh);
if (cIntr)
{
pCh->s.intr |= cIntr;
ievent_set(IEVENT_CTC0 + pCh->s.num);
}
}
static void ctcnextevent(CTCCH *pCh)
{
UINT32 uEvent;
if (pCh->s.intr)
{
return;
}
#if defined(FIX_Z80A)
uEvent = minclock(pCh) * 2;
#else
uEvent = minclock(pCh) * pccore.multiple;
#endif
nevent_set(NEVENT_CTC0 + pCh->s.num, uEvent, neitem_ctc, NEVENT_ABSOLUTE);
}
void neitem_ctc(UINT uId)
{
CTCCH *pCh;
REG8 cIntr;
pCh = ctc.ch + (uId - NEVENT_CTC0);
cIntr = ctcwork(pCh);
if (cIntr)
{
pCh->s.intr |= cIntr;
ievent_set(IEVENT_CTC0 + pCh->s.num);
}
else
{
ctcnextevent(pCh);
}
}
BRESULT ieitem_ctc(UINT uId)
{
CTCCH *pCh;
REG8 cIntr;
BRESULT r;
UINT i;
REG8 cBit;
pCh = ctc.ch + (uId - IEVENT_CTC0);
cIntr = ctcwork(pCh);
cIntr |= pCh->s.intr;
r = FALSE;
if (cIntr)
{
for (i=0, cBit=1; i<4; i++, cBit<<=1)
{
if (cIntr & cBit)
{
if (!(pCh->s.cmd[i] & 0x80))
{
cIntr ^= cBit;
}
else if (!r)
{
r = TRUE;
cIntr ^= cBit;
pCh->s.irq = (UINT8)i;
/* TRACEOUT(("ctc int %d %d [%.2x]", pCh->s.num, i, pCh->s.cmd[i])); */
Z80_INTERRUPT((REG8)(pCh->s.vector + (i << 1)));
}
}
}
}
pCh->s.intr = cIntr;
if (cIntr)
{
ievent_set(IEVENT_CTC0 + pCh->s.num);
}
else
{
ctcnextevent(pCh);
}
return r;
}
void ieeoi_ctc(UINT uId)
{
CTCCH *pCh;
REG8 cIntr;
UINT uCurIrq;
pCh = ctc.ch + (uId - IEVENT_CTC0);
cIntr = ctcwork(pCh) | pCh->s.intr;
uCurIrq = pCh->s.irq;
if (cIntr & (1 << uCurIrq)) /* 割り込み中に割り込んだ… */
{
/* カウンタが0でなければ割り込みを消す */
if ((pCh->s.countmax[uCurIrq] - pCh->s.count[uCurIrq]) >= pCh->s.range[uCurIrq])
{
cIntr ^= (1 << uCurIrq);
}
}
pCh->s.intr = cIntr;
if (cIntr)
{
ievent_set(uId);
}
else
{
ctcnextevent(pCh);
}
}
// ----
static void ctcch_o(CTCCH *pCh, UINT uPort, REG8 cValue)
{
SINT32 nCount;
REG8 cScale;
uPort &= 3;
if (pCh->s.cmd[uPort] & 0x04)
{
ctcstep(pCh);
pCh->s.basecnt[uPort] = cValue;
nCount = ((cValue - 1) & 0xff) + 1;
cScale = 0;
if (!(pCh->s.cmd[uPort] & 0x40))
{
if (pCh->s.cmd[uPort] & 0x20)
{
cScale = 8 - 1;
}
else
{
cScale = 4 - 1;
}
}
pCh->s.scale[uPort] = cScale;
pCh->s.countmax[uPort] = nCount << cScale;
pCh->s.count[uPort] = nCount << cScale;
pCh->s.range[uPort] = 1 << cScale;
pCh->s.cmd[uPort] &= ~6;
ctcnextevent(pCh);
}
else if (cValue & 1)
{
ctcstep(pCh);
pCh->s.cmd[uPort] = cValue;
ctcnextevent(pCh);
}
else if (!uPort)
{
pCh->s.vector = (UINT8)(cValue & 0xf8);
}
}
static REG8 ctcch_i(CTCCH *pCh, UINT uPort)
{
uPort &= 3;
if (uPort != 3)
{
return pCh->s.basecnt[uPort];
}
else
{
ctcstep(pCh);
return ((REG8)(pCh->s.count[3] >> pCh->s.scale[3]));
}
}
// ----
static CTCCH *getctcch(UINT uPort)
{
uPort &= ~3;
if (uPort == 0x1fa0)
{
return ctc.ch + CTC_TURBO1;
}
if (uPort == 0x1fa8)
{
return ctc.ch + CTC_TURBO2;
}
if (uPort == 0x0704)
{
return ctc.ch + CTC_OPM;
}
return NULL;
}
void IOOUTCALL ctc_o(UINT uPort, REG8 cValue)
{
CTCCH *pCh;
/* TRACEOUT(("ctc - %.4x %.2x [%.4x]", port, value, Z80_PC)); */
pCh = getctcch(uPort);
if (pCh != NULL)
{
ctcch_o(pCh, uPort, cValue);
}
}
REG8 IOINPCALL ctc_i(UINT uPort)
{
CTCCH *pCh;
pCh = getctcch(uPort);
if (pCh != NULL)
{
return ctcch_i(pCh, uPort);
}
else
{
return 0xff;
}
}
/* reset */
void ctc_reset(void)
{
UINT i;
UINT j;
ZeroMemory(&ctc, sizeof(ctc));
for (i=0; i<3; i++)
{
ctc.ch[i].s.num = (UINT8)i;
for (j=0; j<4; j++)
{
ctc.ch[i].s.cmd[j] = 0x23;
ctc.ch[i].s.scale[j] = 7;
ctc.ch[i].s.count[j] = 256 << 7;
ctc.ch[i].s.countmax[j] = 256 << 7;
}
}
}

887
nds/patch/fdc.c Normal file
View File

@ -0,0 +1,887 @@
#include "compiler.h"
#include "sysmng.h"
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "nevent.h"
#include "fddfile.h"
#include "fdd_mtr.h"
enum
{
FDCCTYPE_CMD1 = 0x01,
FDCCTYPE_CMD2 = 0x02,
FDCCTYPE_CMD3 = 0x04,
FDCCTYPE_CMD4 = 0x08,
FDCCTYPE_RO = 0x10,
FDCCTYPE_DATA = 0x80
};
static const UINT8 s_cFdcType[] = {
FDCCTYPE_CMD1,
FDCCTYPE_CMD1,
FDCCTYPE_CMD1,
FDCCTYPE_CMD1,
FDCCTYPE_CMD1,
FDCCTYPE_CMD1,
FDCCTYPE_CMD1,
FDCCTYPE_CMD1,
FDCCTYPE_CMD2 + FDCCTYPE_RO,
FDCCTYPE_CMD2 + FDCCTYPE_RO,
FDCCTYPE_CMD2,
FDCCTYPE_CMD2,
FDCCTYPE_CMD3 + FDCCTYPE_RO,
FDCCTYPE_CMD4,
FDCCTYPE_CMD3 + FDCCTYPE_RO,
FDCCTYPE_CMD3};
// write track
#if !defined(CONST_DISKIMAGE)
enum {
TAO_MODE_GAP = 0x4e,
TAO_MODE_SYNC = 0x00,
TAO_MODE_AM = 0xf5,
TAO_MODE_IM = 0xf6,
TAO_MODE_ID = 0xfe,
TAO_MODE_DATA = 0xfb,
TAO_ENDOFDATA = 0xf7,
TAO_CMD_GAP = 0x4e,
TAO_CMD_SYNC = 0x00,
TAO_CMD_IM_IN = 0xf6,
TAO_CMD_IM = 0xfc,
TAO_CMD_AM_IN = 0xf5,
TAO_CMD_IAM = 0xfe,
TAO_CMD_DAM = 0xfb,
TAO_CMD_DDAM = 0xf8,
TAO_CMD_CRC = 0xf7
};
static REG8 wrtrkstart(FDC *f) {
FDDFILE fdd;
fdd = fddfile + f->s.drv;
if ((fdd->type == DISKTYPE_NOTREADY) || (fdd->protect)) {
return(0);
}
f->s.bufdir = FDCDIR_TAO;
f->s.bufpos = 0;
f->s.bufmedia = f->s.media;
f->s.bufunit = f->s.drv;
f->s.buftrack = (f->s.c << 1) + f->s.h;
f->s.wt_mode = TAO_ENDOFDATA;
f->s.wt_sectors = 0;
f->s.wt_ptr = 0;
f->s.wt_datpos = 0;
f->s.wt_datsize = 0;
ZeroMemory(f->s.buffer, sizeof(f->s.buffer));
return(0);
}
static void wrtrkdata(FDC *f, REG8 data) {
TAOSEC *t;
REG8 n;
UINT datsize;
FDDFILE fdd;
switch(f->s.wt_mode) {
case TAO_ENDOFDATA:
if (data == TAO_MODE_GAP) {
f->s.wt_mode = TAO_MODE_GAP;
f->s.wt_ptr = 0;
}
break;
case TAO_MODE_GAP:
if (data == TAO_MODE_GAP) {
f->s.wt_ptr++;
if (f->s.wt_ptr >= 256) {
goto wtd_done;
}
}
else if (data == TAO_CMD_SYNC) {
f->s.wt_mode = TAO_MODE_SYNC;
}
else if (data == 0xf4) {
goto wtd_done;
}
else {
goto wtd_err;
}
break;
case TAO_MODE_SYNC:
if (data == TAO_CMD_AM_IN) {
f->s.wt_mode = TAO_MODE_AM;
}
else if (data == TAO_CMD_IM_IN) {
f->s.wt_mode = TAO_MODE_IM;
}
else if (data) {
goto wtd_err;
}
break;
case TAO_MODE_IM:
if (data == TAO_CMD_IM) {
f->s.wt_mode = TAO_ENDOFDATA;
}
else if (data != TAO_CMD_IM_IN) {
goto wtd_err;
}
break;
case TAO_MODE_AM:
if (data == TAO_CMD_IAM) {
f->s.wt_mode = TAO_MODE_ID;
f->s.wt_ptr = 0;
}
else if ((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM)) {
f->s.wt_mode = TAO_MODE_DATA;
f->s.wt_ptr = 0;
if (f->s.wt_datsize) {
t = (TAOSEC *)(f->s.buffer + f->s.wt_datpos);
t[-1].flag = (UINT8)(data == TAO_CMD_DDAM);
}
}
break;
case TAO_MODE_ID:
if ((f->s.wt_ptr == 0) && (data == TAO_CMD_IAM)) {
break;
}
else if (f->s.wt_ptr < 4) {
f->s.buffer[f->s.bufpos + f->s.wt_ptr] = data;
f->s.wt_ptr++;
}
else if (data == TAO_CMD_CRC) {
f->s.wt_mode = TAO_ENDOFDATA;
n = f->s.buffer[f->s.bufpos + 3];
if (n > 3) {
n = 3;
}
datsize = 128 << n;
if ((f->s.bufpos + (sizeof(TAOSEC) * 2) + datsize)
<= sizeof(f->s.buffer)) {
t = (TAOSEC *)(f->s.buffer + f->s.bufpos);
STOREINTELWORD(t->size, datsize);
f->s.wt_datpos = f->s.bufpos + sizeof(TAOSEC);
f->s.wt_datsize = datsize;
f->s.bufpos = f->s.wt_datpos + datsize;
f->s.wt_sectors += 1;
}
else {
goto wtd_err;
}
}
break;
case TAO_MODE_DATA: // DATA WRITE
if ((f->s.wt_ptr == 0) &&
((data == TAO_CMD_DAM) || (data == TAO_CMD_DDAM))) {
break;
}
else if (f->s.wt_ptr < f->s.wt_datsize) {
f->s.buffer[f->s.wt_datpos + f->s.wt_ptr] = data;
f->s.wt_ptr++;
}
else if (data == TAO_CMD_CRC) {
f->s.wt_mode = TAO_ENDOFDATA;
f->s.wt_datsize = 0;
}
break;
}
return;
wtd_done:
fdd = fddfile + f->s.bufunit;
TRACEOUT(("write! %d %dbytes", f->s.wt_sectors, f->s.bufpos));
f->s.stat = (*fdd->wrtrk)(fdd, f->s.bufmedia, f->s.buftrack,
f->s.wt_sectors, f->s.buffer, f->s.bufpos);
f->s.bufdir = FDCDIR_NONE;
dmac_sendready(FALSE);
return;
wtd_err:
f->s.stat = FDDSTAT_LOSTDATA;
f->s.bufdir = FDCDIR_NONE;
dmac_sendready(FALSE);
}
#endif
// ----
void neitem_fdcbusy(UINT id) {
fdc.s.busy = 0;
if (fdc.s.bufdir) {
// TRACEOUT(("dma ready!"));
dmac_sendready(TRUE);
}
(void)id;
}
static void setbusy(FDC *f, SINT32 clock) {
if (clock > 0) {
f->s.busy = FDDSTAT_BUSY;
nevent_set(NEVENT_FDC, clock, neitem_fdcbusy, NEVENT_ABSOLUTE);
}
else {
f->s.busy = 0;
nevent_reset(NEVENT_FDC);
}
}
#if defined(SUPPORT_MOTORRISEUP)
static void setmotor(FDC *f, REG8 drvcmd) {
UINT drv;
SINT32 clock;
drv = drvcmd & 3;
clock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
if (drvcmd & 0x80) {
if (f->s.motorevent[drv] == FDCMOTOR_STOP) {
f->s.motorevent[drv] = FDCMOTOR_STARTING;
f->s.motorclock[drv] = clock;
}
else if (f->s.motorevent[drv] == FDCMOTOR_STOPING) {
f->s.motorevent[drv] = FDCMOTOR_READY;
}
}
else {
if ((f->s.motorevent[drv] == FDCMOTOR_STARTING) ||
(f->s.motorevent[drv] == FDCMOTOR_READY)) {
f->s.motorevent[drv] = FDCMOTOR_STOPING;
f->s.motorclock[drv] = clock;
}
}
}
void fdc_callback(void) {
SINT32 clock;
UINT i;
clock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
for (i=0; i<4; i++) {
if (fdc.s.motorevent[i] == FDCMOTOR_STARTING) {
if ((clock - fdc.s.motorclock[i]) >= (SINT32)pccore.realclock) {
fdc.s.motorevent[i] = FDCMOTOR_READY;
}
}
else if (fdc.s.motorevent[i] == FDCMOTOR_STOPING) {
if ((clock - fdc.s.motorclock[i]) >= (SINT32)pccore.realclock) {
fdc.s.motorevent[i] = FDCMOTOR_STOP;
}
}
}
}
static SINT32 motorwait(const FDC *f) {
SINT32 curclock;
SINT32 nextclock;
if (f->s.motorevent[f->s.drv] == FDCMOTOR_STARTING) {
curclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
curclock -= f->s.motorclock[f->s.drv];
if (curclock < (SINT32)pccore.realclock) {
nextclock = pccore.realclock - curclock;
// TRACEOUT(("motor starting busy %d", nextclock));
return(nextclock);
}
}
return(0);
}
#endif
static REG8 getstat(FDC *f)
{
FDDFILE fdd;
REG8 cType;
REG8 cRet;
fdd = fddfile + f->s.drv;
cType = f->s.ctype;
if (fdd->type == DISKTYPE_NOTREADY)
{
cRet = FDDSTAT_NOTREADY;
}
else
{
cRet = f->s.stat;
}
if ((cType & FDCCTYPE_CMD1) && (f->s.c == 0))
{
cRet |= FDDSTAT_TRACK00;
}
if (!(cType & FDCCTYPE_RO))
{
if (fdd->protect)
{
cRet |= FDDSTAT_WRITEP;
}
}
if (cType & (FDCCTYPE_CMD1 | FDCCTYPE_CMD4))
{
f->s.hole++;
if (f->s.hole < 8)
{
cRet |= FDDSTAT_INDEX;
}
}
else if (!(cRet & 0xf0))
{
if (fddmtr_isbusy())
{
cRet |= FDDSTAT_BUSY;
}
if (f->s.bufdir)
{
cRet |= FDDSTAT_DRQ | FDDSTAT_BUSY;
}
}
return cRet;
}
static void seekcmd(FDC *f)
{
FDDFILE fdd;
UINT uTrack;
f->s.crcnum = 0;
f->s.creg = f->s.c;
fdd = fddfile + f->s.drv;
uTrack = (f->s.c << 1) + f->s.h;
f->s.stat = fdd->seek(fdd, f->s.media, uTrack) | FDDSTAT_HEADENG;
fddmtr_motormove();
}
static REG8 type2cmd(FDC *f, REG8 sc) {
REG8 dir;
UINT track;
UINT8 *p;
FDDFILE fdd;
UINT size;
REG8 stat;
SINT32 clock;
#if defined(SUPPORT_DISKEXT)
SINT32 curclock;
SINT32 nextclock;
UINT32 secinfo;
#endif
track = (f->s.c << 1) + f->s.h;
fdd = fddfile + f->s.drv;
#if !defined(CONST_DISKIMAGE)
if (!(f->s.cmd & 0x20)) {
p = f->s.buffer;
dir = FDCDIR_IN;
}
else {
p = NULL;
dir = FDCDIR_OUT;
}
size = sizeof(f->s.buffer);
stat = fdd->read(fdd, f->s.media, track, sc, p, &size);
if (stat & FDDSTAT_RECNFND) {
size = 0;
dir = FDCDIR_NONE;
}
else if (dir == FDCDIR_OUT) {
if (size) {
ZeroMemory(f->s.buffer, size);
}
stat = stat & (~FDDSTAT_RECTYPE);
}
#else
size = 0;
dir = FDCDIR_NONE;
if (!(f->s.cmd & 0x20)) {
stat = fdd->readp(fdd, f->s.media, track, sc, (void **)&p, &size);
if (!(stat & FDDSTAT_RECNFND)) {
f->e.buffer = p;
dir = FDCDIR_IN;
}
}
else {
stat = FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT;
}
#endif
f->s.bufmedia = f->s.media;
f->s.bufunit = f->s.drv;
f->s.buftrack = track;
f->s.bufsc = sc;
f->s.bufwrite = FALSE;
f->s.bufdir = dir;
f->s.bufmark = f->s.cmd & 1;
f->s.bufpos = 0;
f->s.bufsize = size;
f->s.curtime = 0;
clock = 0;
#if defined(SUPPORT_MOTORRISEUP)
clock += motorwait(f);
#endif
#if defined(SUPPORT_DISKEXT)
secinfo = fdd->sec(fdd, f->s.media, track, sc);
if (secinfo) {
nextclock = LOW16(secinfo);
nextclock *= f->s.loopclock;
nextclock /= LOW16(secinfo >> 16);
curclock = nevent_getwork(NEVENT_RTC);
nextclock -= curclock;
if (nextclock < 0) {
nextclock += f->s.loopclock;
}
// TRACEOUT(("wait clock -> %d [%d/%d]", nextclock,
// LOW16(secinfo), LOW16(secinfo >> 16)));
clock += nextclock;
}
#endif
setbusy(f, max(clock, 500));
return(stat);
}
static REG8 type2flash(FDC *f) {
#if !defined(CONST_DISKIMAGE)
FDDFILE fdd;
f->s.bufwrite = FALSE;
fdd = fddfile + f->s.bufunit;
if (fdd->protect) {
return(FDDSTAT_WRITEFAULT);
}
return(fdd->write(fdd, f->s.bufmedia, f->s.buftrack,
f->s.bufsc, f->s.buffer, f->s.bufpos));
#else
(void)f;
return(FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT);
#endif
}
static REG8 crccmd(FDC *f) {
UINT8 *crcbuf;
UINT track;
FDDFILE fdd;
REG8 stat;
#if !defined(CONST_DISKIMAGE)
crcbuf = f->s.buffer;
#else
crcbuf = f->s.crcbuf;
f->e.buffer = crcbuf;
#endif
track = (f->s.c << 1) + f->s.h;
fdd = fddfile + f->s.drv;
// TRACEOUT(("fdd->crc %d %d %d", f->s.drv, track, f->s.crcnum));
stat = fdd->crc(fdd, f->s.media, track, f->s.crcnum, crcbuf);
if (stat & FDDSTAT_RECNFND) {
f->s.crcnum = 0;
stat = fdd->crc(fdd, f->s.media, track, 0, crcbuf);
}
if (!(stat & FDDSTAT_RECNFND)) {
f->s.bufdir = FDCDIR_IN;
f->s.bufsize = 6;
f->s.rreg = crcbuf[0];
f->s.crcnum++;
}
else {
f->s.bufdir = FDCDIR_NONE;
f->s.bufsize = 0;
}
f->s.bufwrite = FALSE;
f->s.curtime = 0;
return(stat);
}
static void fdcenddata(FDC *f) {
BRESULT r;
REG8 stat;
r = FALSE;
if (f->s.ctype & FDCCTYPE_CMD2) {
stat = 0;
if (f->s.cmd & 0x10) {
r = TRUE;
}
if ((f->s.cmd & 0x20) && (f->s.bufwrite)) {
stat = type2flash(f);
if (stat & (FDDSTAT_RECNFND | FDDSTAT_WRITEFAULT)) {
r = FALSE;
}
f->s.stat = stat;
}
}
f->s.bufdir = FDCDIR_NONE;
dmac_sendready(FALSE);
if (r) {
f->s.rreg = f->s.r + 1;
stat = type2cmd(f, f->s.rreg);
if (!(stat & FDDSTAT_RECNFND)) {
f->s.r = f->s.r + 1;
f->s.stat = stat;
}
}
}
/* IO */
void IOOUTCALL fdc_o0ff8(FDC *f, REG8 cValue)
{
REG8 cCmd;
/* コマンド */
if (f->s.bufwrite)
{
f->s.stat = type2flash(f);
}
if (f->s.bufdir != FDCDIR_NONE)
{
f->s.bufdir = FDCDIR_NONE;
dmac_sendready(FALSE);
}
f->s.cmd = cValue;
cCmd = (REG8)(cValue >> 4);
f->s.ctype = s_cFdcType[cCmd];
/* TRACEOUT(("fdc cmd: %.2x", cValue)); */
// リストアコマンドにおいて
//  マリオは コマンド発行後にbusyを見張る
//  逆にソーサリアンとかは busyだとエラーになる…
// 条件は何?
setbusy(f, 20);
switch(cCmd)
{
case 0x00: // リストア
f->s.motor = 0x80; // モーターOn?
f->s.c = 0;
f->s.step = 1;
f->s.r = 0; // デゼニワールド
seekcmd(f);
f->s.rreg = 0;
sysmng_fddaccess(f->s.drv);
break;
case 0x01: // シーク
f->s.motor = 0x80; // モーターOn
f->s.step = (SINT8)((f->s.c <= f->s.data) ? 1 : -1);
f->s.c = f->s.data;
seekcmd(f);
sysmng_fddaccess(f->s.drv);
break;
case 0x02: // ステップ
case 0x03:
case 0x04: // ステップイン
case 0x05:
case 0x06: // ステップアウト
case 0x07:
f->s.stat = FDDSTAT_HEADENG;
if (f->s.motor)
{
if (cCmd & 0x04)
{
f->s.step = (cCmd & 0x02) ? -1 : 1;
}
f->s.c += f->s.step;
if (cCmd & 1)
{
seekcmd(f);
}
}
break;
case 0x08: // リードデータ
case 0x09:
case 0x0a: // ライトデータ
case 0x0b:
f->s.stat = type2cmd(f, f->s.r);
break;
case 0xc: // リードアドレス
setbusy(&fdc, 200);
f->s.stat = crccmd(&fdc);
break;
case 0x0d: // フォースインタラプト
setbusy(f, 0); // 必要ない?
// f->s.skip = 0; // 000330
f->s.stat = 0;
dmac_sendready(FALSE);
break;
case 0x0e: // リードトラック
#if !defined(CONST_DISKIMAGE)
setbusy(f, 200);
ZeroMemory(f->s.buffer, 0x1a00);
f->s.bufpos = 0;
f->s.bufsize = 0x1a00;
f->s.bufdir = FDCDIR_IN;
f->s.stat = 0;
#else
f->s.stat = FDDSTAT_SEEKERR;
#endif
break;
case 0x0f: // ライトトラック
#if !defined(CONST_DISKIMAGE)
setbusy(f, 200);
f->s.stat = wrtrkstart(f);
#else
f->s.stat = FDDSTAT_LOSTDATA;
#endif
break;
}
}
void IOOUTCALL fdc_o0ff9(FDC *f, REG8 cValue)
{
/* トラック */
f->s.creg = cValue;
}
void IOOUTCALL fdc_o0ffa(FDC *f, REG8 cValue)
{
/* セクタ */
fddmtr_waitsec(cValue);
f->s.r = cValue;
f->s.rreg = cValue;
}
void IOOUTCALL fdc_o0ffb(FDC *f, REG8 cValue)
{
/* データ */
f->s.data = cValue;
#if !defined(CONST_DISKIMAGE)
if (f->s.motor)
{
if (f->s.bufdir == FDCDIR_OUT)
{
f->s.bufwrite = TRUE;
f->s.curtime = 0;
f->s.buffer[f->s.bufpos] = cValue;
if (!f->s.busy)
{
f->s.bufpos++;
if (f->s.bufpos >= f->s.bufsize)
{
fdcenddata(f);
}
}
}
else if (f->s.bufdir == FDCDIR_TAO)
{
wrtrkdata(f, cValue);
}
}
#endif
}
void IOOUTCALL fdc_o0ffc(FDC *f, REG8 cValue)
{
/* ドライブ・サイド */
f->s.ctbl[f->s.drv] = f->s.c;
f->s.c = f->s.ctbl[cValue & 0x03];
f->s.motor = (UINT8)(cValue & 0x80);
f->s.drv = (UINT8)(cValue & 0x03);
f->s.h = (UINT8)((cValue >> 4) & 1);
f->s.cmd = 0; /* T&E SORCERIAN */
f->s.ctype = 0;
f->s.stat = 0;
fddmtr_drvset();
if (!f->s.motor)
{
f->s.r = 0; /* SACOM TELENET */
f->s.rreg = 0;
}
#if defined(SUPPORT_MOTORRISEUP)
setmotor(f, cValue);
#endif
if (f->s.motor)
{
sysmng_fddaccess(f->s.drv);
}
}
void IOOUTCALL fdc_o0(FDC *f, REG8 cValue)
{
}
REG8 IOINPCALL fdc_i0ff8(FDC *f)
{
REG8 cRet;
/* ステータス */
cRet = f->s.busy;
if (cRet)
{
return cRet;
}
if (f->s.bufdir >= FDCDIR_IN) /* YsII */
{
f->s.curtime++;
if (f->s.curtime >= 8)
{
f->s.curtime = 0;
f->s.stat |= FDDSTAT_LOSTDATA;
f->s.bufpos++;
if (f->s.bufpos >= f->s.bufsize)
{
fdcenddata(f);
}
}
}
cRet = getstat(f);
if (!(cRet & 0x02))
{
dmac_sendready(FALSE);
}
/* TRACEOUT(("ret->%.2x", cRet)); */
return cRet;
}
REG8 IOINPCALL fdc_i0ff9(FDC *f)
{
/* トラック */
TRACEOUT(("fdc inp %.4x,%.2x", 0xff9, f->s.creg));
return f->s.creg;
}
REG8 IOINPCALL fdc_i0ffa(FDC *f)
{
/* セクタ */
TRACEOUT(("fdc inp %.4x,%.2x", 0xffa, f->s.rreg));
return f->s.rreg;
}
REG8 IOINPCALL fdc_i0ffb(FDC *f)
{
/* データ */
if (f->s.motor)
{
if (f->s.bufdir == FDCDIR_IN)
{
f->s.curtime = 0;
#if !defined(CONST_DISKIMAGE)
f->s.data = f->s.buffer[f->s.bufpos];
#else
f->s.data = f->e.buffer[f->s.bufpos];
#endif
if (!f->s.busy)
{
f->s.bufpos++;
if (f->s.bufpos >= f->s.bufsize)
{
fdcenddata(f);
}
}
/* TRACEOUT(("read %.2x - %.2x [%.4x]", f->s.bufpos, f->s.data, Z80_PC)); */
}
}
return f->s.data;
}
REG8 IOINPCALL fdc_i0ffc(FDC *f)
{
/* FM */
return 0x00;
}
REG8 IOINPCALL fdc_i0ffd(FDC *f)
{
/* MFM */
return 0x00;
}
REG8 IOINPCALL fdc_i0ffe(FDC *f)
{
/* 1.6M */
f->s.media = DISKTYPE_2HD;
return 0xff;
}
REG8 IOINPCALL fdc_i0fff(FDC *f)
{
/* 500K/1M */
f->s.media = DISKTYPE_2D;
return 0xff;
}
#if !defined(USE_ARMROUTINE)
typedef void (IOINPCALL * FNFDCOUT)(FDC *f, REG8 cValue);
static const FNFDCOUT s_fnOut[] =
{
fdc_o0ff8, fdc_o0ff9, fdc_o0ffa, fdc_o0ffb,
fdc_o0ffc, fdc_o0, fdc_o0, fdc_o0,
};
typedef REG8 (IOINPCALL * FNFDCINP)(FDC *f);
static const FNFDCINP s_fnInp[] =
{
fdc_i0ff8, fdc_i0ff9, fdc_i0ffa, fdc_i0ffb,
fdc_i0ffc, fdc_i0ffd, fdc_i0ffe, fdc_i0fff,
};
void IOINPCALL fdc_o(UINT uPort, REG8 cValue)
{
if ((uPort & (~7)) != 0x0ff8)
{
return;
}
/* TRACEOUT(("fdc out %.4x,%.2x", uPort, cValue)); */
(s_fnOut[uPort & 7])(&fdc, cValue);
}
REG8 IOINPCALL fdc_i(UINT uPort)
{
if ((uPort & (~7)) != 0x0ff8)
{
return 0xff;
}
/* TRACEOUT(("fdc inp %.4x", uPort)); */
return (s_fnInp[uPort & 7])(&fdc);
}
#endif /* !defined(USE_ARMROUTINE) */
// ----
void fdc_reset(void)
{
fddmtr_initialize();
ZeroMemory(&fdc, sizeof(fdc));
fdc.s.step = 1;
fdc.s.equip = xmilcfg.fddequip;
#if defined(FIX_Z80A)
fdc.s.loopclock = 2000000 * 2 / 5;
#else
fdc.s.loopclock = pccore.realclock / 5;
#endif
}

20
nds/patch/font.h Normal file
View File

@ -0,0 +1,20 @@
#define FONTX1_LR 0x10000
#define FONTX1T_LR 0x20000
#if defined(__cplusplus)
extern "C"
{
#endif /* defined(__cplusplus) */
extern UINT8 font_ank[];
#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */
#define font_txt __extromimage.txt
#define font_knjx1 __extromimage.knjx1
#define font_knjx1t __extromimage.knjx1t
#define font_load(f, p) do { } while(0)

304
nds/patch/iocore.c Normal file
View File

@ -0,0 +1,304 @@
#include "compiler.h"
#include "pccore.h"
#include "iocore.h"
CMT cmt;
SIO sio;
// ----
#if !defined(USE_ARMROUTINE)
static void IOOUTCALL dummy_out(UINT uPort, REG8 cValue)
{
(void)uPort;
(void)cValue;
}
static REG8 IOINPCALL dummy_inp(UINT uPort)
{
(void)uPort;
return 0xff;
}
#else // !defined(USE_ARMROUTINE)
void IOOUTCALL dummy_out(UINT uPort, REG8 cValue);
REG8 IOINPCALL dummy_inp(UINT uPort);
#endif // !defined(USE_ARMROUTINE)
// ----
static void IOOUTCALL port1fxx_o(UINT uPort, REG8 cValue)
{
REG8 lsb;
REG8 msb6;
lsb = (UINT8)uPort;
if (lsb == 0xd0)
{
scrn_o(uPort, cValue);
return;
}
if (lsb < 0x80)
{
return;
}
msb6 = lsb & (~3);
if (lsb < 0x90)
{
dmac_o(uPort, cValue);
return;
}
if (msb6 == 0x90)
{
sio_o(uPort, cValue);
return;
}
if ((msb6 == 0xa0) || (msb6 == 0xa8))
{
ctc_o(uPort, cValue);
return;
}
if (lsb == 0xe0)
{
blackctrl_o(uPort, cValue);
return;
}
#if defined(SUPPORT_TURBOZ)
if (pccore.ROM_TYPE >= 3)
{
if (lsb == 0xb0)
{
extpal_o(uPort, cValue);
return;
}
if (lsb == 0xc0)
{
exttextdisp_o(uPort, cValue);
return;
}
if (lsb == 0xc5)
{
extgrphpal_o(uPort, cValue);
return;
}
if ((lsb >= 0xb9) && (lsb < 0xc0))
{
exttextpal_o(uPort, cValue);
return;
}
}
#endif // defined(SUPPORT_TURBOZ)
}
static REG8 IOINPCALL port1fxx_i(UINT uPort)
{
REG8 lsb;
REG8 msb6;
lsb = (UINT8)uPort;
if (lsb < 0x80)
{
return 0xff;
}
msb6 = lsb & (~3);
if (lsb < 0x90)
{
return dmac_i(uPort);
}
if (msb6 == 0x90)
{
return sio_i(uPort);
}
if ((msb6 == 0xa0) || (msb6 == 0xa8))
{
return ctc_i(uPort);
}
if (lsb == 0xd0)
{
return scrn_i(uPort);
}
if (lsb >= 0xf0)
{
return dipsw_i(uPort);
}
#if defined(SUPPORT_TURBOZ)
if (pccore.ROM_TYPE >= 3)
{
if (lsb == 0xb0)
{
return extpal_i(uPort);
}
if (lsb == 0xc0)
{
return exttextdisp_i(uPort);
}
if (lsb == 0xc5)
{
return extgrphpal_i(uPort);
}
if ((lsb >= 0xb9) && (lsb < 0xc0))
{
return exttextpal_i(uPort);
}
if (lsb == 0xe0)
{
return(blackctrl_i(uPort);
}
}
#endif // defined(SUPPORT_TURBOZ)
return 0xff;
}
// ----
static const IOINP s_fnDefInp[0x20] =
{
dummy_inp, dummy_inp,
dummy_inp, dummy_inp,
dummy_inp, dummy_inp,
dummy_inp, dummy_inp,
dummy_inp, dummy_inp,
dummy_inp, dummy_inp,
dummy_inp, dummy_inp,
cgrom_i, fdc_i,
dummy_inp, dummy_inp,
dummy_inp, dummy_inp,
pcg_i, pcg_i,
pcg_i, pcg_i,
dummy_inp, subcpu_i,
ppi_i, sndboard_psgsta,
dummy_inp, dummy_inp,
dummy_inp, dummy_inp
};
static const IOOUT s_fnDefOut[0x20] =
{
dummy_out, dummy_out,
dummy_out, dummy_out,
dummy_out, dummy_out,
dummy_out, dummy_out,
dummy_out, dummy_out,
dummy_out, dummy_out,
dummy_out, dummy_out,
cgrom_o, fdc_o,
palette_o, palette_o,
palette_o, ply_o,
dummy_out, pcg_o,
pcg_o, pcg_o,
crtc_o, subcpu_o,
ppi_o, sndboard_psgdat,
sndboard_psgreg, memio_rom,
memio_ram, dummy_out
};
typedef void (*INITFN)(void);
static const INITFN s_fnInit[] =
{
cgrom_reset, cmt_reset, crtc_reset,
ctc_reset, dmac_reset, fdc_reset,
memio_reset, pcg_reset, ppi_reset,
sio_reset, sndboard_reset, subcpu_reset,
vramio_reset
};
// ----
void iocore_reset(void)
{
UINT i;
ZeroMemory(&iocore, sizeof(iocore));
CopyMemory(iocore.f.inpfn, s_fnDefInp, sizeof(s_fnDefInp));
CopyMemory(iocore.f.outfn, s_fnDefOut, sizeof(s_fnDefOut));
for (i=0; i<0x10; i++) {
iocore.f.inpfn[i+0x20] = tram_atr_i;
iocore.f.inpfn[i+0x30] = tram_ank_i;
iocore.f.outfn[i+0x20] = tram_atr_o;
iocore.f.outfn[i+0x30] = tram_ank_o;
}
if (pccore.ROM_TYPE >= 2) {
#if defined(SUPPORT_BANKMEM)
iocore.f.inpfn[0x0b] = memio_bank_i;
iocore.f.outfn[0x0b] = memio_bank_o;
#endif
iocore.f.inpfn[0x1f] = port1fxx_i;
iocore.f.outfn[0x1f] = port1fxx_o;
for (i=0; i<8; i++) {
iocore.f.inpfn[i+0x38] = tram_knj_i;
iocore.f.outfn[i+0x38] = tram_knj_o;
}
}
#if defined(SUPPORT_TURBOZ)
if (pccore.ROM_TYPE >= 3) {
iocore.f.inpfn[0x10] = palette_i;
iocore.f.inpfn[0x11] = palette_i;
iocore.f.inpfn[0x12] = palette_i;
iocore.f.inpfn[0x13] = ply_i;
}
#endif // defined(SUPPORT_TURBOZ)
#if defined(SUPPORT_ROMEO2)
#if defined(SUPPORT_TURBOZ) || defined(SUPPORT_OPM)
if (pccore.SOUND_SW) {
iocore.f.inpfn[0x07] = opm_i;
iocore.f.outfn[0x07] = opm_o;
}
#endif // defined(SUPPORT_TURBOZ) || defined(SUPPORT_OPM)
#endif // defined(SUPPORT_ROMEO2)
for (i=0; i<NELEMENTS(s_fnInit); i++)
{
(s_fnInit[i])();
}
}
// ----
#if !defined(USE_ARMROUTINE)
void IOOUTCALL iocore_out(UINT uPort, REG8 cValue)
{
UINT msb;
msb = uPort >> 8;
if (iocore.s.mode)
{
gram2_o(uPort, cValue);
}
else if (msb >= 0x40)
{
gram_o(uPort, cValue);
}
else
{
(*iocore.f.outfn[msb])(uPort, cValue);
}
}
REG8 IOINPCALL iocore_inp(UINT uPort)
{
UINT msb;
msb = uPort >> 8;
iocore.s.mode = 0;
if (msb >= 0x40)
{
return gram_i(uPort);
}
else
{
return (*iocore.f.inpfn[msb])(uPort);
}
}
#endif // !defined(USE_ARMROUTINE)

65
nds/patch/memio.c Normal file
View File

@ -0,0 +1,65 @@
#include "compiler.h"
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "nevent.h"
#if defined(SUPPORT_BANKMEM)
#error defined SUPPORT_BANKMEM!
#endif
static const UINT8 *s_pcsIpl;
void memio_update(void)
{
if (!(iocore.s.ppib & 0x10))
{
z80core.e.memread = s_pcsIpl;
}
else
{
z80core.e.memread = mainmem;
}
}
void IOOUTCALL memio_rom(UINT uPort, REG8 cValue)
{
if (iocore.s.ppib & 0x10)
{
iocore.s.ppib &= ~0x10;
z80core.e.memread = s_pcsIpl;
nevent_forceexit();
}
(void)uPort;
(void)cValue;
}
void IOOUTCALL memio_ram(UINT uPort, REG8 cValue)
{
if (!(iocore.s.ppib & 0x10))
{
iocore.s.ppib |= 0x10;
z80core.e.memread = mainmem;
nevent_forceexit();
}
(void)uPort;
(void)cValue;
}
/* reset */
void memio_reset(void)
{
if (pccore.ROM_TYPE >= 2)
{
s_pcsIpl = __extromimage.bios2;
}
else
{
s_pcsIpl = __extromimage.bios1;
}
memio_update();
}

127
nds/patch/ppi.c Normal file
View File

@ -0,0 +1,127 @@
#include "compiler.h"
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
/* 8255 PPI<50>` */
#if !defined(USE_ARMROUTINE)
static REG8 getportb(void)
{
REG8 cPpib;
REG8 cRet;
cPpib = iocore.s.ppib;
cRet = cPpib;
iocore.s.ppib = (UINT8)((cPpib & (~0x40)) | 0x01);
return cRet;
}
#endif /* !defined(USE_ARMROUTINE) */
void ppi_setportc(PPI *pPpi, REG8 cValue)
{
REG8 cModify;
cModify = pPpi->portc ^ cValue;
pPpi->portc = cValue;
// cmt_write((REG8)(cValue & 1));
if ((cModify & 0x20) && (!(cValue & 0x20)))
{
iocore.s.mode = 1;
}
if (cModify & 0x40)
{
crtc_setwidth((REG8)(cValue & 0x40));
}
}
// ----
#if !defined(USE_ARMROUTINE)
void IOOUTCALL ppi_o(UINT uPort, REG8 cValue)
{
REG8 cBit;
switch(uPort & 0x0f)
{
case 0:
ppi.porta = cValue;
return;
case 1:
ppi.portb = cValue;
return;
case 2:
ppi_setportc(&ppi, cValue);
break;
case 3:
if (cValue & 0x80)
{
ppi.mode = cValue;
return;
}
else
{
cBit = 1 << ((cValue >> 1) & 7);
if (cValue & 0x01)
{
ppi_setportc(&ppi, (REG8)(ppi.portc | cBit));
}
else
{
ppi_setportc(&ppi, (REG8)(ppi.portc & (~cBit)));
}
}
break;
}
}
REG8 IOINPCALL ppi_i(UINT uPort)
{
switch(uPort & 0x0f)
{
case 0:
return ppi.porta;
case 1:
if (!(ppi.mode & 0x02))
{
return ppi.portb;
}
return getportb();
case 2:
/* mode? */
return ppi.portc;
case 3:
return ppi.mode;
}
return 0xff;
}
#endif /* !defined(USE_ARMROUTINE) */
/* initialize & reset */
void ppi_initialize(void)
{
ppi.porta = 0x00;
ppi.portb = 0xff;
ppi.portc = 0xff;
ppi.mode = 0x82;
}
void ppi_reset(void)
{
ppi.porta = 0x00;
ppi.portc |= 0x40;
ppi.mode = 0x82;
}

155
nds/patch/sndboard.c Normal file
View File

@ -0,0 +1,155 @@
#include "compiler.h"
#include "pccore.h"
#include "iocore.h"
#include"z80core.h"
#include "nds9psg.h"
#if defined(SUPPORT_ROMEO2)
#include <nds/registers_alt.h>
#include "romeo2.h"
#include "romeo2_x1.h"
#endif // defined(SUPPORT_ROMEO2)
// --- psg
#if !defined(USE_ARMROUTINE)
void IOOUTCALL sndboard_psgreg(UINT uPort, REG8 cValue)
{
nds9psg.cAddr = cValue;
(void)uPort;
}
void IOOUTCALL sndboard_psgdat(UINT uPort, REG8 cValue)
{
nds9psg_setreg(&nds9psg, nds9psg.cAddr, cValue);
(void)uPort;
}
REG8 IOINPCALL sndboard_psgsta(UINT uPort)
{
if (nds9psg.cAddr < 0x10)
{
// ¼<E28099>ÚæÞæÞ
return nds9psg.reg.b[nds9psg.cAddr];
}
else
{
(void)uPort;
return 0xff;
}
}
#endif // !defined(USE_ARMROUTINE)
// ---- romeo2
#if defined(SUPPORT_ROMEO2)
#if defined(ROMEO2_WFIFO)
static SINT32 s_nFifoLastClock;
#else // defined(ROMEO2_WFIFO)
static unsigned char s_cRomeo2Addr;
#endif // defined(ROMEO2_WFIFO)
static void IOOUTCALL romeo2_psgdat(UINT uPort, REG8 cValue)
{
const REG8 cReg = nds9psg.cAddr;
if (cReg >= 14)
{
return;
}
#if defined(ROMEO2_WFIFO)
// sync sound write
const SINT32 nCurClock = CPU_CLOCKCOUNT - iocore.e.framestartclock;
const SINT32 nPast = nCurClock - s_nFifoLastClock;
if (nPast > 0)
{
s_nFifoLastClock = nCurClock;
x1sound_sw_sync(nPast);
}
x1sound_ssg_write(0, cReg); // 1cxx
x1sound_ssg_write(1, cValue); // 1bxx
#else // defined(ROMEO2_WFIFO)
ROMEO2SsgWriteReg(0, cReg, cValue);
#endif // defined(ROMEO2_WFIFO)
(void)uPort;
}
#if defined(SUPPORT_OPM)
void IOOUTCALL opm_o(UINT uPort, REG8 cDat)
{
UINT uLsb = uPort & 0xff;
if (uLsb == 0x00) /* 0700 */
{
#if defined(ROMEO2_WFIFO)
x1sound_fm_write(0, cDat);
#else // defined(ROMEO2_WFIFO)
s_cRomeo2Addr = cDat;
#endif // defined(ROMEO2_WFIFO)
}
else if (uLsb == 0x01) /* 0701 */
{
#if defined(ROMEO2_WFIFO)
// sync sound write
const SINT32 nCurClock = CPU_CLOCKCOUNT - iocore.e.framestartclock;
const SINT32 nPast = nCurClock - s_nFifoLastClock;
if (nPast > 0)
{
s_nFifoLastClock = nCurClock;
x1sound_sw_sync(nPast);
}
x1sound_fm_write(1, cDat);
#else // defined(ROMEO2_WFIFO)
ROMEO2FmmWriteReg(0, s_cRomeo2Addr, cDat);
#endif // defined(ROMEO2_WFIFO)
}
else if ((uLsb & (~3)) == 0x04)
{
/* 0704-0707 */
ctc_o(uPort, cDat);
}
}
REG8 IOINPCALL opm_i(UINT uPort)
{
UINT uLsb = uPort & 0xff;
if (uLsb == 0x00) /* 0700 */
{
return 0x00;
}
else if (uLsb == 0x01) /* 0701 */
{
return 0x00;
}
else if ((uLsb & (~3)) == 0x04) /* 0704-0707 */
{
return ctc_i(uPort);
}
else
{
return 0xff;
}
}
#endif // defined(SUPPORT_OPM)
#endif // defined(SUPPORT_ROMEO2)
// ----
void sndboard_reset()
{
#if defined(SUPPORT_ROMEO2)
if (xmilcfg.SOUND_SW)
{
romeo2_x1_setup();
iocore.f.outfn[0x1b] = romeo2_psgdat;
}
#endif // defined(SUPPORT_ROMEO2)
nds9psg_reset(&nds9psg);
}

298
nds/patch/subcpu.c Normal file
View File

@ -0,0 +1,298 @@
#include "compiler.h"
#include "timemng.h"
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "nevent.h"
#include "ievent.h"
#include "keystat.h"
#include "calendar.h"
void neitem_scpu(UINT uId)
{
BRESULT bIntr;
bIntr = FALSE;
/* こうすると同時押しが判定できないのでキーバッファを持つべし */
if (keystat.req_int)
{
keystat.req_int = 0;
bIntr = TRUE;
}
else if (subcpu.s.keydata)
{
subcpu.s.keycount++;
if (subcpu.s.keycount >= subcpu.s.keycountrep)
{
subcpu.s.keycount = 0;
bIntr = TRUE;
}
nevent_set(NEVENT_SUBCPU, subcpu.e.intrclock, neitem_scpu, NEVENT_RELATIVE);
}
if (bIntr)
{
ievent_set(IEVENT_SUBCPU);
}
}
BRESULT ieitem_scpu(UINT uId)
{
UINT uKey;
REG8 cKeyData;
if ((subcpu.s.cmdcnt) || (subcpu.s.datcnt))
{
keystat.req_int = 1; /* 再送しる */
subcpu_sendkey();
return FALSE;
}
if (subcpu.s.vect == 0) /* 割り込み不要だったら捨てる */
{
return FALSE;
}
uKey = keystat_getflag();
cKeyData = (UINT8)(uKey >> 8);
if (subcpu.s.keydata != cKeyData)
{
subcpu.s.keydata = cKeyData;
subcpu.s.keycount = 0;
subcpu.s.keycountrep = 480;
}
else
{
if (cKeyData == 0)
{
return FALSE;
}
uKey = uKey & (~0x20); // rep
subcpu.s.keycountrep = 48; // 0.1sec
}
subcpu.s.work[1] = (UINT8)uKey;
subcpu.s.work[0] = cKeyData;
subcpu.s.cmdptr = offsetof(SUBCPU, s.zero);
subcpu.s.datptr = offsetof(SUBCPU, s.work);
subcpu.s.mode = 0xe6;
subcpu.s.cmdcnt = 0;
subcpu.s.datcnt = 2;
// subcpu.s.OBF = 0;
// subcpu.s.IBF = 1;
iocore.s.ppib = (UINT8)((iocore.s.ppib & (~0x20)) | 0x40);
Z80_INTERRUPT(subcpu.s.vect);
(void)uId;
return TRUE;
}
// ----
void subcpusetbuffer(SUBCPU *s, REG8 cMode)
{
UINT32 uKey;
switch(cMode)
{
case 0xe3:
uKey = keystat_gete3();
s->s.work[2] = (UINT8)(uKey >> 16);
s->s.work[1] = (UINT8)(uKey >> 8);
s->s.work[0] = (UINT8)(uKey >> 0);
break;
case 0xe6:
uKey = keystat_getflag();
s->s.work[1] = (UINT8)(uKey >> 0);
s->s.work[0] = (UINT8)(uKey >> 8);
break;
case 0xea:
s->s.work[0] = cmt_ctrl_stat();
break;
case 0xeb:
s->s.work[0] = cmt_tape_stat();
break;
case 0xed:
calendar_getdate(s->s.work);
break;
case 0xef:
calendar_gettime(s->s.work);
break;
}
}
void subcpusendctrl(SUBCPU *s)
{
switch(s->s.mode)
{
case 0xe9:
cmt_ctrl(s->s.work[0]);
break;
case 0xec:
calendar_setdate(s->s.work);
break;
case 0xee:
calendar_settime(s->s.work);
break;
}
}
typedef struct
{
UINT8 cFlag;
UINT8 cPos;
} SCPUTBL;
enum
{
SCPU_CNTMASK = 0x07,
SCPU_OUTPUT = 0x08,
SCPU_INPUT = 0x00,
SCPU_IODIR = 0x08
};
static const SCPUTBL s_scputbl[0x20] =
{
{6 | SCPU_OUTPUT, offsetof(SUBCPU, s.timer[0])}, // d0: timer0 set
{6 | SCPU_OUTPUT, offsetof(SUBCPU, s.timer[1])}, // d1: timer1 set
{6 | SCPU_OUTPUT, offsetof(SUBCPU, s.timer[2])}, // d2: timer2 set
{6 | SCPU_OUTPUT, offsetof(SUBCPU, s.timer[3])}, // d3: timer3 set
{6 | SCPU_OUTPUT, offsetof(SUBCPU, s.timer[4])}, // d4: timer4 set
{6 | SCPU_OUTPUT, offsetof(SUBCPU, s.timer[5])}, // d5: timer5 set
{6 | SCPU_OUTPUT, offsetof(SUBCPU, s.timer[6])}, // d6: timer6 set
{6 | SCPU_OUTPUT, offsetof(SUBCPU, s.timer[7])}, // d7: timer7 set
{6 | SCPU_INPUT, offsetof(SUBCPU, s.timer[0])}, // d8: timer0 get
{6 | SCPU_INPUT, offsetof(SUBCPU, s.timer[1])}, // d9: timer1 get
{6 | SCPU_INPUT, offsetof(SUBCPU, s.timer[2])}, // da: timer2 get
{6 | SCPU_INPUT, offsetof(SUBCPU, s.timer[3])}, // db: timer3 get
{6 | SCPU_INPUT, offsetof(SUBCPU, s.timer[4])}, // dc: timer4 get
{6 | SCPU_INPUT, offsetof(SUBCPU, s.timer[5])}, // dd: timer5 get
{6 | SCPU_INPUT, offsetof(SUBCPU, s.timer[6])}, // de: timer6 get
{6 | SCPU_INPUT, offsetof(SUBCPU, s.timer[7])}, // df: timer7 get
{0 | SCPU_OUTPUT, offsetof(SUBCPU, s.zero)}, // e0:
{0 | SCPU_OUTPUT, offsetof(SUBCPU, s.zero)}, // e1:
{0 | SCPU_OUTPUT, offsetof(SUBCPU, s.zero)}, // e2:
{3 | SCPU_INPUT, offsetof(SUBCPU, s.work)}, // e3: game keys
{1 | SCPU_OUTPUT, offsetof(SUBCPU, s.vect)}, // e4: intr vector
{0 | SCPU_OUTPUT, offsetof(SUBCPU, s.zero)}, // e5:
{2 | SCPU_INPUT, offsetof(SUBCPU, s.work)}, // e6: game keys
{1 | SCPU_OUTPUT, offsetof(SUBCPU, s.tvctrl)}, // e7: set TV ctrl
{1 | SCPU_INPUT, offsetof(SUBCPU, s.tvctrl)}, // e8: get TV ctrl
{1 | SCPU_OUTPUT, offsetof(SUBCPU, s.work)}, // e9: cmt ctrl
{1 | SCPU_INPUT, offsetof(SUBCPU, s.work)}, // ea: cmtctrlstat
{1 | SCPU_INPUT, offsetof(SUBCPU, s.work)}, // eb: cmttypestat
{3 | SCPU_OUTPUT, offsetof(SUBCPU, s.work)}, // ec: date set
{3 | SCPU_INPUT, offsetof(SUBCPU, s.work)}, // ed: date set
{3 | SCPU_OUTPUT, offsetof(SUBCPU, s.work)}, // ee: time set
{3 | SCPU_INPUT, offsetof(SUBCPU, s.work)}, // ef: time set
};
#if !defined(USE_ARMROUTINE)
void IOOUTCALL subcpu_o(UINT uPort, REG8 cValue)
{
UINT uTblPos;
const SCPUTBL *p;
if (iocore.s.ppib & 0x40)
{
return;
}
if (!subcpu.s.cmdcnt)
{
subcpu.s.mode = (UINT8)cValue;
uTblPos = cValue - 0xd0;
if (uTblPos >= 0x20)
{
uTblPos = 0x10;
}
p = s_scputbl + uTblPos;
iocore.s.ppib = (UINT8)(iocore.s.ppib & (~0x60));
if ((p->cFlag & SCPU_IODIR) == SCPU_INPUT)
{
subcpu.s.cmdptr = offsetof(SUBCPU, s.zero);
subcpu.s.datptr = p->cPos;
// subcpu.s.cmdcnt = 0;
subcpu.s.datcnt = p->cFlag & SCPU_CNTMASK;
iocore.s.ppib |= 0x40;
subcpusetbuffer(&subcpu, cValue);
}
else
{
subcpu.s.cmdptr = p->cPos;
subcpu.s.datptr = offsetof(SUBCPU, s.zero);
subcpu.s.cmdcnt = p->cFlag & SCPU_CNTMASK;
subcpu.s.datcnt = 0;
iocore.s.ppib |= 0x20;
}
}
else
{
subcpu.s.cmdcnt--;
((UINT8 *)(&subcpu))[subcpu.s.cmdptr + subcpu.s.cmdcnt] = cValue;
if (subcpu.s.cmdcnt == 0)
{
subcpusendctrl(&subcpu);
}
}
(void)uPort;
}
REG8 IOINPCALL subcpu_i(UINT uPort)
{
if (subcpu.s.datcnt)
{
subcpu.s.datcnt--;
}
else /* D-SIDE で通るように… */
{
subcpusetbuffer(&subcpu, subcpu.s.mode);
}
iocore.s.ppib = (UINT8)(iocore.s.ppib & (~0x60));
if (subcpu.s.datcnt)
{
iocore.s.ppib |= 0x40;
}
else
{
iocore.s.ppib |= 0x20;
}
(void)uPort;
return (((UINT8 *)(&subcpu))[subcpu.s.datptr + subcpu.s.datcnt]);
}
#endif /* !defined(USE_ARMROUTINE) */
/* reset */
void subcpu_reset(void)
{
ZeroMemory(&subcpu, sizeof(subcpu));
/* subcpu.OBF = 1; */
iocore.s.ppib = (UINT8)(iocore.s.ppib | 0x20);
#if defined(FIX_Z80A)
subcpu.e.intrclock = 2000000 * 2 / 480;
#else /* defined(FIX_Z80A) */
subcpu.e.intrclock = pccore.realclock / 480;
#endif /* defined(FIX_Z80A) */
}
void subcpu_sendkey(void)
{
if (!nevent_iswork(NEVENT_SUBCPU))
{
nevent_set(NEVENT_SUBCPU, subcpu.e.intrclock, neitem_scpu, NEVENT_ABSOLUTE);
}
}

162
nds/patch/vramio.c Normal file
View File

@ -0,0 +1,162 @@
#include "compiler.h"
#include "pccore.h"
#include "iocore.h"
#include "vram.h"
#include "makescrn.h"
// ---- text
void IOOUTCALL tram_atr_o(UINT uPort, REG8 cValue)
{
UINT uAddr;
uAddr = LOW11(uPort);
if (TRAM_ATR(uAddr) == cValue)
{
return;
}
if ((TRAM_ATR(uAddr) ^ cValue) & (TRAMATR_Yx2 | TRAMATR_Xx2))
{
crtc.e.remakeattr = 1;
}
if (cValue & TRAMATR_BLINK)
{
crtc.e.existblink = 1;
}
TRAM_ATR(uAddr) = cValue;
crtc.e.scrnflash = 1;
if (TRAM_ATR(uAddr) & TRAMATR_Xx2)
{
TRAMUPDATE(LOW11(uAddr + 1)) |= UPDATE_TRAM;
}
TRAMUPDATE(uAddr) |= UPDATE_TRAM;
}
#if !defined(USE_ARMROUTINE)
void IOOUTCALL tram_ank_o(UINT uPort, REG8 cValue)
{
UINT uAddr;
uAddr = LOW11(uPort);
if (TRAM_ANK(uAddr) == cValue)
{
return;
}
TRAM_ANK(uAddr) = cValue;
crtc.e.scrnflash = 1;
if (TRAM_ATR(uAddr) & TRAMATR_Xx2)
{
TRAMUPDATE(LOW11(uAddr + 1)) |= UPDATE_TRAM;
}
TRAMUPDATE(uAddr) |= UPDATE_TRAM;
}
#endif // !defined(USE_ARMROUTINE)
void IOOUTCALL tram_knj_o(UINT uPort, REG8 cValue)
{
UINT uAddr;
uAddr = LOW11(uPort);
if (TRAM_KNJ(uAddr) == cValue)
{
return;
}
TRAM_KNJ(uAddr) = cValue;
crtc.e.scrnflash = 1;
if (TRAM_ATR(uAddr) & TRAMATR_Xx2)
{
TRAMUPDATE(LOW11(uAddr + 1)) |= UPDATE_TRAM;
}
TRAMUPDATE(uAddr) |= UPDATE_TRAM;
}
REG8 IOINPCALL tram_atr_i(UINT uPort)
{
return TRAM_ATR(LOW11(uPort));
}
REG8 IOINPCALL tram_ank_i(UINT uPort)
{
return TRAM_ANK(LOW11(uPort));
}
REG8 IOINPCALL tram_knj_i(UINT uPort)
{
return TRAM_KNJ(LOW11(uPort));
}
// ---------------------------------------------------------------------- grph
#if !defined(USE_ARMROUTINE)
void IOOUTCALL gram_o(UINT uPort, REG8 cValue)
{
UINT8 *p;
p = crtc.e.gramacc + PORT2GRAM(uPort);
if (*p == cValue)
{
return;
}
*p = cValue;
TRAMUPDATE(uPort & crtc.e.updatemask) |= crtc.e.updatebit;
crtc.e.scrnflash = 1;
}
REG8 IOINPCALL gram_i(UINT uPort)
{
return crtc.e.gramacc[PORT2GRAM(uPort)];
}
void IOOUTCALL gram2_o(UINT uPort, REG8 cValue)
{
UINT8 *p;
p = crtc.e.gramacc + PORT2GRAM2(uPort);
switch((uPort >> 14) & 3)
{
case 0:
p[GRAM_B] = cValue;
p[GRAM_R] = cValue;
p[GRAM_G] = cValue;
break;
case 1:
p[GRAM_R] = cValue;
p[GRAM_G] = cValue;
break;
case 2:
p[GRAM_B] = cValue;
p[GRAM_G] = cValue;
break;
case 3:
p[GRAM_B] = cValue;
p[GRAM_R] = cValue;
break;
}
TRAMUPDATE(uPort & crtc.e.updatemask) |= crtc.e.updatebit;
crtc.e.scrnflash = 1;
}
#endif // !defined(USE_ARMROUTINE)
// ----
void vramio_reset(void)
{
UINT i;
ZeroMemory(gram + GRAM_BANK0, 0xc000);
ZeroMemory(gram + GRAM_BANK1, 0xc000);
for (i=0; i<0x800; i++)
{
TRAM_ATR(i) = 0x07;
TRAM_ANK(i) = 0x20;
TRAM_KNJ(i) = 0x00;
TRAMUPDATE(i) = 0;
}
}

5
nds/resource.h Normal file
View File

@ -0,0 +1,5 @@
extern const unsigned int g_sDemoBmp[];
extern const unsigned short g_sDemoPal[];

194
nds/softkbd7.cpp Normal file
View File

@ -0,0 +1,194 @@
#include "compiler.h"
#include "libnds.h"
#include "ipcxfer.h"
#include "softkbd7.h"
static UINT8 getKey(int x, int y)
{
x = x - 10;
y = y - 118;
if ((y < 0) || (y >= 72))
{
return SOFTKBD_NC;
}
const int nPosY = y / 12;
if ((x >= 0) && (x < 186))
{
// full-key
if (nPosY == 0)
{
if (x < 90)
{
return 0x62 + (x / 18); /* Function */
}
else if (x < 93)
{
return 0x37; /* ROLLUP */
}
else if (x < 123)
{
return 0x36; /* ROLLDOWN */
}
else if (x < 125)
{
return SOFTKBD_NC;
}
else if (x < 140)
{
return 0x3f; /* HELP */
}
else if (x < 155)
{
return 0x61; /* COPY */
}
}
else if (nPosY == 5)
{
if (x < 24)
{
return SOFTKBD_NC;
}
else if (x < 36)
{
return 0x73; /* GRPH */
}
else if (x < 48)
{
return 0x71; /* CAPS */
}
else if (x < 138)
{
return 0x34; /* SPACE */
}
else if (x < 150)
{
return 0x72; /* KANA */
}
else if (x < 162)
{
return 0x35; /* XFER */
}
}
else
{
struct tagFullKey
{
UINT8 cWidth;
UINT8 cCtrl;
UINT8 cKey[14];
};
static const tagFullKey fkTable[4] =
{
/* ESC 1 2 3 4 5 6 7 8 9 0 - ^ \ BRK*/
{12,0x00,{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x60}},
/* HTAB Q W E R T Y U I O P @ [ INS RET*/
{18,0x0f,{0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x38,0x1c}},
/* CTRL A S D F G H J K L ; : ] RET RET*/
{20,0x0f,{0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x1c,0x1c}},
/* SFT Z X C V B N M , . / _ SFT SFT SFT*/
{24,0x70,{0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x70,0x70,0x70}},
};
const tagFullKey *pcFK = fkTable + (nPosY - 1);
int nPosX = x - pcFK->cWidth;
if (x < 0)
{
return pcFK->cCtrl;
}
else
{
return pcFK->cKey[nPosX / 12];
}
}
}
else if ((x >= 191) && (x < 249))
{
const int nPosX = (x - 191) / 12;
static const UINT8 sTenKey[6][4] =
{
/* HOME / * - */
{0x3e,0x41,0x45,0x40},
/* 7 8 9 + */
{0x42,0x43,0x44,0x49},
/* 4 5 6 = */
{0x46,0x47,0x48,0x4d},
/* 1 2 3 . */
{0x4a,0x4b,0x4c,0x50},
/* 0 , U RET */
{0x4e,0x4f,0x3a,0x1c},
/* L R D RET */
{0x3b,0x3c,0x3d,0x1c},
};
return sTenKey[nPosY][nPosX];
}
return SOFTKBD_NC;
}
// ----
#define KEYBUFFERS (1 << 4)
struct tagSoftKeyBuffer
{
int nPos;
int nCount;
UINT8 cLastKey;
UINT8 sBuffer[KEYBUFFERS];
};
static tagSoftKeyBuffer s_skb;
void softkbd7_initialize(void)
{
tagSoftKeyBuffer *pSkb = &s_skb;
ZeroMemory(pSkb, sizeof(*pSkb));
pSkb->cLastKey = SOFTKBD_NC;
}
bool softkbd7_down(int x, int y)
{
tagSoftKeyBuffer *pSkb = &s_skb;
const UINT8 cKey = getKey(x, y);
const bool bResult = ((cKey != SOFTKBD_NC) && (cKey != pSkb->cLastKey) && ((pSkb->nCount + 2) < KEYBUFFERS));
if (bResult)
{
softkbd7_up();
pSkb->cLastKey = cKey;
pSkb->sBuffer[(pSkb->nPos + pSkb->nCount) % KEYBUFFERS] = cKey | SOFTKBD_KEYDOWN;
pSkb->nCount++;
}
return bResult;
}
bool softkbd7_up(void)
{
tagSoftKeyBuffer *pSkb = &s_skb;
const UINT8 cLastKey = pSkb->cLastKey;
const bool bResult = (cLastKey != SOFTKBD_NC);
if (bResult)
{
pSkb->cLastKey = SOFTKBD_NC;
pSkb->sBuffer[(pSkb->nPos + pSkb->nCount) % KEYBUFFERS] = cLastKey | SOFTKBD_KEYUP;
pSkb->nCount++;
}
return bResult;
}
void softkbd7_sync(void)
{
tagSoftKeyBuffer *pSkb = &s_skb;
PNDSKBDXFER pKbd = IPCKEYXFER;
if ((pSkb->nCount) && (pKbd->cKey == SOFTKBD_NC))
{
pKbd->cKey = pSkb->sBuffer[pSkb->nPos];
pSkb->nPos = (pSkb->nPos + 1) % KEYBUFFERS;
pSkb->nCount--;
}
}

6
nds/softkbd7.h Normal file
View File

@ -0,0 +1,6 @@
void softkbd7_initialize(void);
bool softkbd7_down(int x, int y);
bool softkbd7_up(void);
void softkbd7_sync(void);

34
nds/softkbd9.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "compiler.h"
#include "libnds.h"
#include "ipcxfer.h"
#include "softkbd9.h"
#include "keystat.h"
void softkbd9_initialize(void)
{
PNDSKBDXFER pKbd = IPCKEYXFER;
pKbd->cKey = SOFTKBD_NC;
}
void softkbd9_sync(void)
{
PNDSKBDXFER pKbd = IPCKEYXFER;
const UINT8 cKey = pKbd->cKey;
if (pKbd->cKey != SOFTKBD_NC)
{
pKbd->cKey = SOFTKBD_NC;
const REG8 cCode = cKey & SOFTKBD_KEYCODEMASK;
const REG8 cFlag = cKey & SOFTKBD_KEYFLAGBIT;
if (cFlag == SOFTKBD_KEYDOWN)
{
keystat_keydown(cCode);
}
else
{
keystat_keyup(cCode);
}
}
}

4
nds/softkbd9.h Normal file
View File

@ -0,0 +1,4 @@
void softkbd9_initialize(void);
void softkbd9_sync(void);

392
nds/sound/nds7psg.cpp Normal file
View File

@ -0,0 +1,392 @@
#include "compiler.h"
#include "libnds.h"
#include "pccore.h"
#include "ipcxfer.h"
#include "nds7psg.h"
// #define PSG1_DISABLE
// #define PSG2_DISABLE
// #define PSG3_DISABLE
// #define PSGNOISE_DISABLE
enum
{
PSGENV_INC = 15,
PSGENV_ONESHOT = 16,
PSGENV_LASTON = 32,
PSGENV_ONECYCLE = 64
};
// <20>G<EFBFBD><EFBFBD>x<EFBFBD>Ť<EFBFBD>[<5B>v<EFBFBD>p<EFBFBD>^<5E>[<5B>
static const UINT8 s_psgenv_pat[16] =
{
PSGENV_ONESHOT,
PSGENV_ONESHOT,
PSGENV_ONESHOT,
PSGENV_ONESHOT,
PSGENV_ONESHOT | PSGENV_INC,
PSGENV_ONESHOT | PSGENV_INC,
PSGENV_ONESHOT | PSGENV_INC,
PSGENV_ONESHOT | PSGENV_INC,
PSGENV_ONECYCLE,
PSGENV_ONESHOT,
0,
PSGENV_ONESHOT | PSGENV_LASTON,
PSGENV_ONECYCLE | PSGENV_INC,
PSGENV_ONESHOT | PSGENV_INC | PSGENV_LASTON,
PSGENV_INC,
PSGENV_ONESHOT | PSGENV_INC
};
// ----
static void updatevolume(PNDS7PSG pPsg, REG8 cBitmap)
{
// with SCHANNEL_ENABLE | (3 << 24) | SOUND_PAN(64) | SOUND_FORMAT_PSG
static const UINT32 s_dwVolReg[16] =
{
#if 1
0x00000000, 0xe340030c, 0xe3400310, 0xe3400318,
0xe3400321, 0xe3400330, 0xe3400343, 0xe3400360,
0xe3400221, 0xe3400230, 0xe3400243, 0xe3400260,
0xe3400143, 0xe3400160, 0xe3400043, 0xe3400060,
#else
0x00000000, 0xe3400308, 0xe340030b, 0xe3400310,
0xe3400316, 0xe3400320, 0xe340032d, 0xe3400340,
0xe340035a, 0xe3400220, 0xe340022d, 0xe3400240,
0xe340025a, 0xe3400140, 0xe340015a, 0xe3400040,
#endif
};
const REG8 cMix = pPsg->reg.r.cMixer;
#if !defined(PSG1_DISABLE)
if (cBitmap & 0x01)
{
REG8 cVol = 0;
if (!(cMix & 0x01))
{
cVol = pPsg->reg.r.cVol[0];
if (cVol & 0x10)
{
cVol = pPsg->cEnvVol;
}
else
{
cVol = cVol & 0x0f;
}
}
if (pPsg->cVol[0] != cVol)
{
pPsg->cVol[0] = cVol;
SCHANNEL_CR(8 + 0) = s_dwVolReg[cVol];
}
}
#endif // !defined(PSG1_DISABLE)
#if !defined(PSG2_DISABLE)
if (cBitmap & 0x02)
{
REG8 cVol = 0;
if (!(cMix & 0x02))
{
cVol = pPsg->reg.r.cVol[1];
if (cVol & 0x10)
{
cVol = pPsg->cEnvVol;
}
else
{
cVol = cVol & 0x0f;
}
}
if (pPsg->cVol[1] != cVol)
{
pPsg->cVol[1] = cVol;
SCHANNEL_CR(8 + 1) = s_dwVolReg[cVol];
}
}
#endif // !defined(PSG2_DISABLE)
#if !defined(PSG3_DISABLE)
if (cBitmap & 0x04)
{
REG8 cVol = 0;
if (!(cMix & 0x04))
{
cVol = pPsg->reg.r.cVol[2];
if (cVol & 0x10)
{
cVol = pPsg->cEnvVol;
}
else
{
cVol = cVol & 0x0f;
}
}
if (pPsg->cVol[2] != cVol)
{
pPsg->cVol[2] = cVol;
SCHANNEL_CR(8 + 2) = s_dwVolReg[cVol];
}
}
#endif // !defined(PSG3_DISABLE)
#if !defined(PSGNOISE_DISABLE)
if (cBitmap & 0x38)
{
REG8 cNoise = 0;
if (!(cMix & 0x08))
{
REG8 cVol = pPsg->reg.r.cVol[0];
if (cVol & 0x10)
{
cVol = pPsg->cEnvVol;
}
else
{
cVol = cVol & 0x0f;
}
cNoise = max(cNoise, cVol);
}
if (!(cMix & 0x10))
{
REG8 cVol = pPsg->reg.r.cVol[1];
if (cVol & 0x10)
{
cVol = pPsg->cEnvVol;
}
else
{
cVol = cVol & 0x0f;
}
cNoise = max(cNoise, cVol);
}
if (!(cMix & 0x20))
{
REG8 cVol = pPsg->reg.r.cVol[2];
if (cVol & 0x10)
{
cVol = pPsg->cEnvVol;
}
else
{
cVol = cVol & 0x0f;
}
cNoise = max(cNoise, cVol);
}
if (pPsg->cVol[3] != cNoise)
{
pPsg->cVol[3] = cNoise;
SCHANNEL_CR(14) = s_dwVolReg[cNoise];
}
}
#endif // !defined(PSGNOISE_DISABLE)
}
static void sync(PNDS7PSG pPsg)
{
if (pPsg->cEnvVolCount < 0)
{
return;
}
UINT uClock = pPsg->uClock;
uClock -= pPsg->uLastClock;
if (uClock < pPsg->uEnvMax)
{
return;
}
int nStep = uClock / pPsg->uEnvMax;
pPsg->uLastClock += nStep * pPsg->uEnvMax;
if (pPsg->cEnvVolCount >= nStep)
{
pPsg->cEnvVolCount -= nStep;
pPsg->cEnvVol = (pPsg->cEnvVolCount ^ pPsg->cEnvMode) & 0x0f;
}
else
{
if (pPsg->cEnvMode & PSGENV_ONESHOT)
{
pPsg->cEnvVolCount = -1;
pPsg->cEnvVol = (pPsg->cEnvMode & PSGENV_LASTON) ? 15 : 0;
}
else
{
pPsg->cEnvVolCount -= (nStep & 0x1f);
while(pPsg->cEnvVolCount < 0)
{
pPsg->cEnvVolCount += 16;
if (!(pPsg->cEnvMode & PSGENV_ONECYCLE))
{
pPsg->cEnvMode ^= PSGENV_INC;
}
}
pPsg->cEnvVol = (pPsg->cEnvVolCount ^ pPsg->cEnvMode) & 0x0f;
}
}
updatevolume(pPsg, 0x3f);
}
static void setreg(PNDS7PSG pPsg, REG8 cReg, REG8 cValue)
{
const REG8 cModify = pPsg->reg.b[cReg] ^ cValue;
if ((!cModify) && (cReg != 13))
{
return;
}
pPsg->reg.b[cReg] = cValue;
switch(cReg)
{
#if !defined(PSG1_DISABLE) || !defined(PSG2_DISABLE) || !defined(PSG3_DISABLE)
#if !defined(PSG1_DISABLE)
case 0:
case 1:
#endif
#if !defined(PSG2_DISABLE)
case 2:
case 3:
#endif
#if !defined(PSG3_DISABLE)
case 4:
case 5:
#endif
{
const UINT uCh = cReg >> 1;
UINT uFreq = pPsg->reg.r.cTune[uCh][0] + ((pPsg->reg.r.cTune[uCh][1] & 0x0f) << 8);
// Rate = (4MHz / 72) / Tune
// uFreq = (33513982 / 2) * uFreq / 125000 / 8; (16.756991)
#if 1
uFreq = (uFreq * 17159 /*.08864*/) >> 10;
#else
uFreq = (uFreq * 0x10 * 9 / 8);
#endif
uFreq = 0 - uFreq;
SCHANNEL_TIMER(uCh + 8) = uFreq;
}
break;
#endif // !defined(PSG1_DISABLE) || !defined(PSG2_DISABLE) || !defined(PSG3_DISABLE)
#if !defined(PSGNOISE_DISABLE)
case 6:
{
UINT uFreq = cValue & 0x1f;
// Rate = 2MHz / (16 * Noise)
// Freq = 0x1000000 * (16 * Noise) / 2MHz
// Freq = 0x10 * 16 * Noise / 2Hz
if (uFreq)
{
uFreq = (0x10 * uFreq);
}
else
{
uFreq = (0x10 / 2);
}
uFreq = 0 - uFreq;
// pPsg->uFreq[3] = uFreq;
SCHANNEL_TIMER(14) = uFreq;
}
break;
#endif // !defined(PSGNOISE_DISABLE)
case 7:
if (cModify & 0x3f)
{
updatevolume(pPsg, cModify);
}
break;
#if !defined(PSG1_DISABLE) || !defined(PSG2_DISABLE) || !defined(PSG3_DISABLE)
#if !defined(PSG1_DISABLE)
case 8:
#endif
#if !defined(PSG2_DISABLE)
case 9:
#endif
#if !defined(PSG3_DISABLE)
case 10:
#endif
updatevolume(pPsg, (REG8)(0x09 << (cReg - 8)));
break;
#endif // !defined(PSG1_DISABLE) || !defined(PSG2_DISABLE) || !defined(PSG3_DISABLE)
case 11:
case 12:
{
UINT uFreq = LOADINTELWORD(pPsg->reg.r.cEnvTime);
if (uFreq == 0)
{
uFreq = 1 << 16;
}
#if defined(FIX_Z80A)
uFreq = uFreq * 16 * 2;
#else // defined(FIX_Z80A)
uFreq = uFreq * 16 * pccore.multiple;
#endif // defined(FIX_Z80A)
pPsg->uEnvMax = uFreq;
}
break;
case 13:
pPsg->cEnvMode = s_psgenv_pat[cValue & 0x0f];
pPsg->cEnvVolCount = 15;
pPsg->cEnvVol = (~pPsg->cEnvMode) & 15;
pPsg->uLastClock = pPsg->uClock;
updatevolume(pPsg, 0x3f);
break;
}
}
// ----
void nds7psg_reset(PNDS7PSG pPsg)
{
ZeroMemory(pPsg, sizeof(*pPsg));
pPsg->reg.r.cMixer = 0x3f;
pPsg->cEnvMode = PSGENV_ONESHOT;
pPsg->cEnvVolCount = 15;
pPsg->cEnvVol = 15;
pPsg->uLastClock = 0;
pPsg->uEnvMax = (1 << 16) * 32;
SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7f);
// *REG_SOUNDBIAS = 0x200; // 504
SCHANNEL_CR(8) = 0;
SCHANNEL_CR(9) = 0;
SCHANNEL_CR(10) = 0;
SCHANNEL_CR(14) = 0;
}
void nds7psg_sync(PNDS7PSG pPsg)
{
PNDSPSGXFER pXfer = IPCPSGXFER;
const UINT uClock = pXfer->uClock;
if (uClock)
{
pPsg->uClock += uClock;
if (pXfer->cUpdateReg)
{
for (REG8 i=0; i<=12; i++)
{
setreg(pPsg, i, pXfer->reg.b[i]);
}
}
if (pXfer->cUpdateEnv)
{
setreg(pPsg, 13, pXfer->reg.b[13]);
}
sync(pPsg);
pXfer->uClock = 0;
}
}

51
nds/sound/nds7psg.h Normal file
View File

@ -0,0 +1,51 @@
union tagNds7PsgReg
{
struct
{
UINT8 cTune[3][2]; // 0
UINT8 cNoise; // 6
UINT8 cMixer; // 7
UINT8 cVol[3]; // 8
UINT8 cEnvTime[2]; // b
UINT8 cEnv; // d
UINT8 _cIo1;
UINT8 _cIo2;
} r;
UINT8 b[0x10];
};
typedef union tagNds7PsgReg NDS7PSGREG;
struct tagNds7Psg
{
NDS7PSGREG reg;
UINT uClock;
UINT8 cVol[4];
// UINT uFreq[4];
UINT32 uLastClock;
UINT32 uEnvCount;
UINT32 uEnvMax;
UINT8 __mixer; // unused
UINT8 cEnvMode;
UINT8 cEnvVol;
SINT8 cEnvVolCount;
};
typedef struct tagNds7Psg NDS7PSG;
typedef struct tagNds7Psg *PNDS7PSG;
#ifdef __cplusplus
extern "C"
{
#endif
extern NDS7PSG nds7psg;
void nds7psg_reset(PNDS7PSG pPsg);
void nds7psg_sync(PNDS7PSG pPsg);
#ifdef __cplusplus
}
#endif

67
nds/sound/nds9psg.cpp Normal file
View File

@ -0,0 +1,67 @@
#include "compiler.h"
#include "libnds.h"
#include "z80core.h"
#include "pccore.h"
#include "ipcxfer.h"
#include "nds9psg.h"
#if !defined(USE_ARMROUTINE)
void nds9psg_setreg(PNDS9PSG pPsg, REG8 cReg, REG8 cValue)
{
if (cReg >= 14)
{
return;
}
if (cReg == 13)
{
pPsg->reg.b[cReg] = cValue;
pPsg->cUpdateEnv = 1;
}
else if (pPsg->reg.b[cReg] != cValue)
{
pPsg->reg.b[cReg] = cValue;
pPsg->cUpdateReg = 1;
}
}
REG8 nds9psg_getreg(PNDS9PSG pPsg, REG8 cReg)
{
return pPsg->reg.b[cReg & 15];
}
#endif // !defined(USE_ARMROUTINE)
// ----
void nds9psg_reset(PNDS9PSG pPsg)
{
ZeroMemory(pPsg, sizeof(*pPsg));
pPsg->reg.r.cMixer = 0x3f;
pPsg->reg.r.cIo1 = 0xff;
pPsg->reg.r.cIo2 = 0xff;
pPsg->uClock = CPU_CLOCK;
}
void nds9psg_sync(PNDS9PSG pPsg)
{
const UINT uClock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
const UINT uPast = uClock - pPsg->uClock;
if (uPast)
{
PNDSPSGXFER pXfer = IPCPSGXFER;
if (!pXfer->uClock)
{
CopyMemory(pXfer->reg.b, pPsg->reg.b, sizeof(pXfer->reg));
pXfer->cUpdateReg = pPsg->cUpdateReg;
pXfer->cUpdateEnv = pPsg->cUpdateEnv;
pXfer->uClock = uPast;
pPsg->uClock = uClock;
pPsg->cUpdateReg = 0;
pPsg->cUpdateEnv = 0;
}
}
}

46
nds/sound/nds9psg.h Normal file
View File

@ -0,0 +1,46 @@
union tagNds9PsgReg
{
struct
{
UINT8 cTune[3][2]; // 0
UINT8 cNoise; // 6
UINT8 cMixer; // 7
UINT8 cVol[3]; // 8
UINT8 cEnvTime[2]; // b
UINT8 cEnv; // d
UINT8 cIo1;
UINT8 cIo2;
} r;
UINT8 b[0x10];
};
typedef union tagNds9PsgReg NDS9PSGREG;
struct tagNds9Psg
{
NDS9PSGREG reg;
UINT32 uClock;
UINT8 cAddr;
UINT8 cUpdateReg;
UINT8 cUpdateEnv;
};
typedef struct tagNds9Psg NDS9PSG;
typedef struct tagNds9Psg *PNDS9PSG;
#ifdef __cplusplus
extern "C"
{
#endif
extern NDS9PSG nds9psg;
void nds9psg_reset(PNDS9PSG pPsg);
void nds9psg_sync(PNDS9PSG pPsg);
void nds9psg_setreg(PNDS9PSG pPsg, REG8 cReg, REG8 cValue);
REG8 nds9psg_getreg(PNDS9PSG pPsg, REG8 cReg);
#ifdef __cplusplus
}
#endif

8
nds/sound/sndctrl.h Normal file
View File

@ -0,0 +1,8 @@
// #include "opmgen.h"
// #include "psggen.h"
#define sndctrl_initialize()
#define sndctrl_deinitialize()
#define sndctrl_reset()

17
nds/sound/sound.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef SOUNDCALL
#define SOUNDCALL
#endif
typedef void (SOUNDCALL * SOUNDCB)(void *hdl, SINT32 *pcm, UINT count);
#define sound_create(r, m) (FAILURE)
#define sound_destroy()
#define sound_reset()
#define sound_changeclock()
#define sound_streamregist(h, c)
#define sound_sync()
#define sound_makesample(l)
#define sound_pcmlock() (NULL)
#define sound_pcmunlock(h)

48
nds/sysmng.h Normal file
View File

@ -0,0 +1,48 @@
#define DISPCLOCK
// Ç<E2809A>[ÅࢢÊmŒn
enum
{
SYS_UPDATECFG = 0x0001,
SYS_UPDATEOSCFG = 0x0002,
SYS_UPDATEFDD = 0x0004
};
#define sysmng_cpureset()
#if defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
void sysmng_initialize();
void sysmng_clockreset();
void sysmng_dispclock();
#else // defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
#define sysmng_initialize() do { } while(0)
#define sysmng_clockreset() do { } while(0)
#define sysmng_dispclock() do { } while(0)
#endif // defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
#if !defined(TRACE)
#ifdef __cplusplus
extern "C"
{
#endif
void sysmng_fddaccess(UINT8 cDrv);
void sysmng_fddsync(UINT uFrames);
#ifdef __cplusplus
}
#endif
#else // !defined(TRACE)
#define sysmng_fddaccess(cDrv) do { } while(0)
#define sysmng_fddsync(uFrames) do { } while(0)
#endif // !defined(TRACE)

13
nds/timemng.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "compiler.h"
#include "timemng.h"
static const _SYSTIME deftime = {1990, 1, 0, 1, 0, 0, 0, 0};
BRESULT timemng_gettime(_SYSTIME *pSysTime)
{
CopyMemory(pSysTime, &deftime, sizeof(deftime));
return(SUCCESS);
}

28
nds/timemng.h Normal file
View File

@ -0,0 +1,28 @@
// Win32 SYSTEMTIME ストラクチャ
typedef struct
{
UINT16 year;
UINT16 month;
UINT16 week;
UINT16 day;
UINT16 hour;
UINT16 minute;
UINT16 second;
UINT16 milli;
} _SYSTIME;
#ifdef __cplusplus
extern "C"
{
#endif
BRESULT timemng_gettime(_SYSTIME *pSysTime);
#ifdef __cplusplus
}
#endif

214
nds/vram/make15.cpp Normal file
View File

@ -0,0 +1,214 @@
#include "compiler.h"
#include "libnds.h"
#include "pccore.h"
#include "vram.h"
#include "makescrn.h"
#include "makesub.h"
#include "font.h"
// ---- 25lines
// pos_cy
// fedcba9876543210fedcba9876543210
// ppppppppppp00???????????yyyyyyyy
#if !defined(USE_ARMROUTINE)
void width40x25_200l(UINT _pos) { // 40x25 200line
UINT pos_cy;
UINT8 *dst;
UINT y;
UINT x;
REG8 udtmp;
REG8 dirty;
UINT8 work[MAKETEXT_ROW * 3];
pos_cy = _pos << 21;
pos_cy += min(makescrn.fontcy, MAKETEXT_ROW);
dst = reinterpret_cast<UINT8 *>(BG_GFX);
y = makescrn.surfcy;
do {
x = makescrn.surfcx;
do {
udtmp = TRAMUPDATE(pos_cy >> 21);
dirty = (udtmp & makescrn.dispflag);
if (dirty) {
TRAMUPDATE(pos_cy >> 21) = (UINT8)(udtmp ^ dirty);
if (dirty & UPDATE_TRAM) {
makechr8(work, &makescrn, pos_cy, udtmp);
makemix_mixtext40(dst, work, pos_cy & 0xff);
}
if (dirty & UPDATE_VRAM) {
makemix_mixgrph40(dst,
makescrn.disp1 + TRAM2GRAM(pos_cy >> 21),
pos_cy & 0xff);
}
}
pos_cy += (1 << 21);
dst += 8;
} while(--x);
if (udtmp & 4) { // 縦倍角描画だったら
makescrn.fontycnt += makescrn.charcy;
}
else {
makescrn.fontycnt = makescrn.charcy * 2;
}
makescrn.fontycnt &= 15;
dst += makescrn.surfstep;
pos_cy += makescrn.surfrx << 21;
} while(--y);
}
void width80x25_200l(UINT _pos) { // 80x25 200line
UINT32 pos_cy;
UINT8 *dst;
UINT y;
UINT x;
REG8 udtmp;
REG8 dirty;
UINT8 work[MAKETEXT_ROW * 3];
pos_cy = _pos << 21;
pos_cy += min(makescrn.fontcy, MAKETEXT_ROW);
dst = reinterpret_cast<UINT8 *>(BG_GFX);
y = makescrn.surfcy;
do {
x = makescrn.surfcx;
do {
udtmp = TRAMUPDATE(pos_cy >> 21);
dirty = (udtmp & makescrn.dispflag);
if (dirty) {
TRAMUPDATE(pos_cy >> 21) = (UINT8)(udtmp ^ dirty);
if (dirty & UPDATE_TRAM) {
makechr8(work, &makescrn, pos_cy, udtmp);
makemix_mixtext80(dst, work, pos_cy & 0xff);
}
if (dirty & UPDATE_VRAM) {
makemix_mixgrph80(dst,
makescrn.disp1 + TRAM2GRAM(pos_cy >> 21),
pos_cy & 0xff);
}
}
pos_cy += (1 << 21);
dst += 4;
} while(--x);
if (udtmp & 4) { // 縦倍角描画だったら
makescrn.fontycnt += makescrn.charcy;
}
else {
makescrn.fontycnt = makescrn.charcy * 2;
}
makescrn.fontycnt &= 15;
dst += makescrn.surfstep;
pos_cy += makescrn.surfrx << 21;
} while(--y);
}
#endif // !defined(USE_ARMROUTINE)
// ---- 12lines
void width40x12_200l(UINT pos) { // 40x12 200line
UINT fontcy;
UINT8 *dst;
UINT y;
UINT x;
REG8 udtmp;
REG8 dirty;
UINT8 work[MAKETEXT_STEP * 2];
const UINT8 *src;
fontcy = min(makescrn.fontcy, MAKETEXT_ROW);
dst = reinterpret_cast<UINT8 *>(BG_GFX);
y = makescrn.surfcy;
do {
x = makescrn.surfcx;
do {
udtmp = TRAMUPDATE(pos);
dirty = (udtmp & makescrn.dispflag);
if (dirty) {
TRAMUPDATE(pos) = (UINT8)(udtmp ^ dirty);
if (dirty & UPDATE_TRAM) {
makechr16(work, pos, fontcy, udtmp);
makemix_mixtext40(dst, work, fontcy);
makemix_mixtext40(dst + MAKESCRN_VIDEOYALIGN,
work + MAKETEXT_STEP, fontcy);
}
if (dirty & UPDATE_VRAM) {
src = makescrn.disp1 + TRAM2GRAM(LOW10(pos));
makemix_mixgrph40(dst, src, fontcy);
makemix_mixgrph40(dst + MAKESCRN_VIDEOYALIGN,
src + GRAM_HALFSTEP, fontcy);
}
}
pos = LOW11(pos + 1);
dst += 8;
} while(--x);
if (udtmp & 4) { // 縦倍角描画だったら
makescrn.fontycnt += makescrn.charcy;
}
else {
makescrn.fontycnt = makescrn.charcy * 2;
}
makescrn.fontycnt &= 15;
dst += makescrn.surfstep;
pos = LOW11(pos + makescrn.surfrx);
} while(--y);
}
void width80x12_200l(UINT pos) { // 80x12 200line
UINT fontcy;
UINT8 *dst;
UINT y;
UINT x;
REG8 udtmp;
REG8 dirty;
UINT8 work[MAKETEXT_STEP * 2];
const UINT8 *src;
fontcy = min(makescrn.fontcy, MAKETEXT_ROW);
dst = reinterpret_cast<UINT8 *>(BG_GFX);
y = makescrn.surfcy;
do {
x = makescrn.surfcx;
do {
udtmp = TRAMUPDATE(pos);
dirty = (udtmp & makescrn.dispflag);
if (dirty) {
TRAMUPDATE(pos) = (UINT8)(udtmp ^ dirty);
if (dirty & UPDATE_TRAM) {
makechr16(work, pos, fontcy, udtmp);
makemix_mixtext80(dst, work, fontcy);
makemix_mixtext80(dst + MAKESCRN_VIDEOYALIGN,
work + MAKETEXT_STEP, fontcy);
}
if (dirty & UPDATE_VRAM) {
src = makescrn.disp1 + TRAM2GRAM(LOW10(pos));
makemix_mixgrph80(dst, src, fontcy);
makemix_mixgrph80(dst + MAKESCRN_VIDEOYALIGN,
src + GRAM_HALFSTEP, fontcy);
}
}
pos = LOW11(pos + 1);
dst += 4;
} while(--x);
if (udtmp & 4) { // 縦倍角描画だったら
makescrn.fontycnt += makescrn.charcy;
}
else {
makescrn.fontycnt = makescrn.charcy * 2;
}
makescrn.fontycnt &= 15;
dst += makescrn.surfstep;
pos = LOW11(pos + makescrn.surfrx);
} while(--y);
}

237
nds/vram/makeatr.cpp Normal file
View File

@ -0,0 +1,237 @@
#include "compiler.h"
#include "vram.h"
#include "makescrn.h"
#include "makesub.h"
static LONG_CALL void atrb0(UINT8 *dst, UINT8 *term) {
do {
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = 0;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = 0;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = 0;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb1(UINT8 *dst, UINT8 *term) {
do {
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = 0;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = 0;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb2(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = 0;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = 0;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb3(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = 0;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb4(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = 0;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = 0;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = dat;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb5(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = 0;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = dat;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb6(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = 0;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = dat;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb7(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = dat;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb0r(UINT8 *dst, UINT8 *term) {
do {
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = (UINT32)-1;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb1r(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = ~dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = (UINT32)-1;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb2r(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = ~dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = (UINT32)-1;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb3r(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = (UINT32)-1;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb4r(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = ~dat;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb5r(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = ~dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = ~dat;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb6r(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = ~dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = ~dat;
dst += 4;
} while(dst < term);
}
static LONG_CALL void atrb7r(UINT8 *dst, UINT8 *term) {
UINT32 dat;
do {
dat = *(UINT32 *)(dst + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) = ~dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) = ~dat;
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) = ~dat;
dst += 4;
} while(dst < term);
}
const MAKEATRFN makeatr8[16] = {
atrb0, atrb1, atrb2, atrb3, atrb4, atrb5, atrb6, atrb7,
atrb0r, atrb1r, atrb2r, atrb3r, atrb4r, atrb5r, atrb6r, atrb7r};
// ----
void makeatr_pcg16(UINT8 *dst, UINT cnt,
const UINT8 *src, REG8 atr, MAKETXTFN fn) {
if (atr & 1) {
(*fn)(dst, dst + cnt, src);
}
dst += MAKETEXT_ROW;
if (atr & 2) {
(*fn)(dst, dst + cnt, src + 0x800);
}
dst += MAKETEXT_ROW;
if (atr & 4) {
(*fn)(dst, dst + cnt, src + 0x1000);
}
if (atr & TRAMATR_REVERSE) {
dst -= MAKETEXT_ROW * 2;
cnt = (cnt + 3) >> 2;
do {
*(UINT32 *)(dst + (MAKETEXT_ROW*0)) ^= (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW*1)) ^= (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_ROW*2)) ^= (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_STEP + MAKETEXT_ROW*0)) ^= (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_STEP + MAKETEXT_ROW*1)) ^= (UINT32)-1;
*(UINT32 *)(dst + (MAKETEXT_STEP + MAKETEXT_ROW*2)) ^= (UINT32)-1;
dst += 4;
} while(--cnt);
}
}

78
nds/vram/makec16.cpp Normal file
View File

@ -0,0 +1,78 @@
#include "compiler.h"
#include "pccore.h"
#include "iocore.h"
#include "vram.h"
#include "makescrn.h"
#include "makesub.h"
#include "font.h"
static void copy2odd(UINT8 *dst, UINT8 *term) {
do {
*(UINT32 *)(dst + (MAKETEXT_ROW * 0)) =
*(UINT32 *)(dst + MAKETEXT_STEP + (MAKETEXT_ROW * 0));
*(UINT32 *)(dst + (MAKETEXT_ROW * 1)) =
*(UINT32 *)(dst + MAKETEXT_STEP + (MAKETEXT_ROW * 1));
*(UINT32 *)(dst + (MAKETEXT_ROW * 2)) =
*(UINT32 *)(dst + MAKETEXT_STEP + (MAKETEXT_ROW * 2));
dst += 4;
} while(dst < term);
}
void makechr16(UINT8 *dst, UINT pos, UINT count, REG8 udtmp) {
REG8 atr;
REG8 ank;
REG8 knj;
const UINT8 *pat;
REG8 func;
UINT8 *term;
atr = TRAM_ATR(pos);
if (atr & makescrn.blinktest) {
atr ^= TRAMATR_REVERSE;
}
if (udtmp & 0x10) {
pos = LOW11(pos - 1);
}
ank = TRAM_ANK(pos);
knj = TRAM_KNJ(pos);
func = udtmp & 0x0f;
term = dst + count;
if (!(TRAM_ATR(pos) & 0x20)) { // CHR
if (!(knj & 0x80)) { // ASCII
pat = font_txt + (ank << 4);
}
else { // KANJI
pat = font_knjx1t;
pat += (knj & 0x1f) << 12;
pat += ank << 4;
if (knj & 0x40) {
pat += FONTX1T_LR;
}
}
func += 0x10;
maketxt8_make(dst, term, pat, func, atr);
maketxt8_make(dst + MAKETEXT_STEP, term + MAKETEXT_STEP,
pat + 1, func, atr);
}
else { // PCG
if (!(knj & 0x90)) { // PCGÌ<E2809A>o—Í
pat = pcg.d + (ank << 3);
}
else { // 16ƒhƒbƒgPCGÌ<E2809A>o—Í
pat = pcg.d + ((ank & (~1)) << 3);
func += 0x10;
}
makepcg8_make(dst, term, pat, func, atr);
if (!(func & 0x10)) {
copy2odd(dst, term);
}
else {
makepcg8_make(dst + MAKETEXT_STEP, term + MAKETEXT_STEP,
pat + 1, func, atr);
}
}
}

58
nds/vram/makec8.cpp Normal file
View File

@ -0,0 +1,58 @@
#include "compiler.h"
#include "pccore.h"
#include "iocore.h"
#include "vram.h"
#include "makescrn.h"
#include "makesub.h"
#include "font.h"
void makechr8(UINT8 *dst, const MAKESCRN *m, UINT32 pos_cy, REG8 udtmp) {
UINT pos;
UINT count;
REG8 atr;
REG8 ank;
REG8 knj;
const UINT8 *pat;
REG8 func;
pos = pos_cy >> 21;
count = pos_cy & 0xff;
atr = TRAM_ATR(pos);
if (atr & m->blinktest) {
atr ^= TRAMATR_REVERSE;
}
if (udtmp & 0x10) {
pos = LOW11(pos - 1);
}
ank = TRAM_ANK(pos);
knj = TRAM_KNJ(pos);
func = udtmp & 0x0f;
if (!(TRAM_ATR(pos) & 0x20)) { // CHR
if (!(knj & 0x80)) { // ASCII
pat = font_ank + (ank << 3);
}
else { // KANJI
pat = font_knjx1t;
pat += (knj & 0x1f) << 12;
pat += ank << 4;
if (knj & 0x40) {
pat += FONTX1T_LR;
}
func += 16;
}
maketxt8_make(dst, dst + count, pat, func, atr);
}
else { // PCG
if (!(knj & 0x90)) { // PCGÌ<E2809A>o—Í
pat = pcg.d + (ank << 3);
}
else { // 16ƒhƒbƒgPCGÌ<E2809A>o—Í
pat = pcg.d + ((ank & (~1)) << 3);
func += 16;
}
makepcg8_make(dst, dst + count, pat, func, atr);
}
}

60
nds/vram/makecs.cpp Normal file
View File

@ -0,0 +1,60 @@
#include "compiler.h"
#include "vram.h"
#include "makescrn.h"
#include "makesub.h"
void maketxt8_make(UINT8 *dst, UINT8 *term, const UINT8 *src,
REG8 func, REG8 attr) {
(*maketxtlfn[func])(dst, term, src);
(*makeatr8[attr & 15])(dst, term);
}
static void cls8(UINT8 *dst, UINT8 *term) {
do {
*(UINT32 *)dst = 0;
dst += 4;
} while(dst < term);
}
void makepcg8_make(UINT8 *dst, UINT8 *term, const UINT8 *src,
REG8 func, REG8 attr) {
MAKETXTFN fn;
fn = maketxtlfn[func];
if (attr & 1) {
(*fn)(dst, term, src);
}
else {
cls8(dst, term);
}
dst += MAKETEXT_ROW;
term += MAKETEXT_ROW;
if (attr & 2) {
(*fn)(dst, term, src + 0x800);
}
else {
cls8(dst, term);
}
dst += MAKETEXT_ROW;
term += MAKETEXT_ROW;
if (attr & 4) {
(*fn)(dst, term, src + 0x1000);
}
else {
cls8(dst, term);
}
if (attr & TRAMATR_REVERSE) {
do {
*(UINT32 *)(dst - (MAKETEXT_ROW * 2)) ^= (UINT32)-1;
*(UINT32 *)(dst - (MAKETEXT_ROW * 1)) ^= (UINT32)-1;
*(UINT32 *)(dst - (MAKETEXT_ROW * 0)) ^= (UINT32)-1;
dst += 4;
} while(dst < term);
}
}

215
nds/vram/makemix.cpp Normal file
View File

@ -0,0 +1,215 @@
#include "compiler.h"
#include "libnds.h"
#include "vram.h"
#include "makescrn.h"
#include "makesub.h"
// 遅いのが嫌なら後でインラインにすればいい
// to256colex
// bit0 = normal left
// bit3 = normal right
// bit4 = interleaf 0
// bit7 = interleaf 1
static UINT vramstep = MAKESCRN_VIDEOYALIGN;
void makemix_mixstep(BRESULT x2) {
vramstep = (x2)?(MAKESCRN_VIDEOYALIGN * 2):(MAKESCRN_VIDEOYALIGN * 1);
}
void makemix_mixtext40(UINT8 *dst, const UINT8 *txt, UINT count) {
UINT32 datl;
UINT32 datr;
REG8 dat;
do {
datl = (*(UINT32 *)(dst + 0)) & 0x38383838;
datr = (*(UINT32 *)(dst + 4)) & 0x38383838;
dat = txt[MAKETEXT_ROW * 0];
datl |= (to256colex[dat] & 0x01010101) << 0;
datr |= (to256colex[dat] & 0x08080808) >> 3;
dat = txt[MAKETEXT_ROW * 1];
datl |= (to256colex[dat] & 0x01010101) << 1;
datr |= (to256colex[dat] & 0x08080808) >> 2;
dat = txt[MAKETEXT_ROW * 2];
datl |= (to256colex[dat] & 0x01010101) << 2;
datr |= (to256colex[dat] & 0x08080808) >> 1;
*(UINT32 *)(dst + 0) = datl;
*(UINT32 *)(dst + 4) = datr;
txt++;
dst += vramstep;
} while(--count);
}
void makemix_mixgrph40(UINT8 *dst, const UINT8 *grp, UINT count) {
UINT pos;
UINT32 datl;
UINT32 datr;
REG8 dat;
pos = 0;
do {
datl = (*(UINT32 *)(dst + 0)) & 0x07070707;
datr = (*(UINT32 *)(dst + 4)) & 0x07070707;
dat = grp[pos + GRAM_B];
datl |= (to256colex[dat] & 0x01010101) << 3;
datr |= (to256colex[dat] & 0x08080808) << 0;
dat = grp[pos + GRAM_R];
datl |= (to256colex[dat] & 0x01010101) << 4;
datr |= (to256colex[dat] & 0x08080808) << 1;
dat = grp[pos + GRAM_G];
datl |= (to256colex[dat] & 0x01010101) << 5;
datr |= (to256colex[dat] & 0x08080808) << 2;
*(UINT32 *)(dst + 0) = datl;
*(UINT32 *)(dst + 4) = datr;
pos = (pos + GRAM_LINESTEP) & (GRAM_LINESTEP * 7);
dst += vramstep;
} while(--count);
}
void makemix_mixtext80(UINT8 *dst, const UINT8 *txt, UINT count) {
UINT32 dat0;
UINT32 dat1;
REG8 dat;
do {
dat0 = (*(UINT32 *)(dst + (MAKESCRN_VIDEOPAGE * 0))) & 0x38383838;
dat1 = (*(UINT32 *)(dst + (MAKESCRN_VIDEOPAGE * 1))) & 0x38383838;
dat = txt[MAKETEXT_ROW * 0];
dat0 |= (to256colex[dat] & 0x10101010) >> 4;
dat1 |= (to256colex[dat] & 0x80808080) >> 7;
dat = txt[MAKETEXT_ROW * 1];
dat0 |= (to256colex[dat] & 0x10101010) >> 3;
dat1 |= (to256colex[dat] & 0x80808080) >> 6;
dat = txt[MAKETEXT_ROW * 2];
dat0 |= (to256colex[dat] & 0x10101010) >> 2;
dat1 |= (to256colex[dat] & 0x80808080) >> 5;
*(UINT32 *)(dst + (MAKESCRN_VIDEOPAGE * 0)) = dat0;
*(UINT32 *)(dst + (MAKESCRN_VIDEOPAGE * 1)) = dat1;
txt++;
dst += vramstep;
} while(--count);
}
void makemix_mixgrph80(UINT8 *dst, const UINT8 *grp, UINT count) {
UINT pos;
UINT32 dat0;
UINT32 dat1;
REG8 dat;
pos = 0;
do {
dat0 = (*(UINT32 *)(dst + (MAKESCRN_VIDEOPAGE * 0))) & 0x07070707;
dat1 = (*(UINT32 *)(dst + (MAKESCRN_VIDEOPAGE * 1))) & 0x07070707;
dat = grp[pos + GRAM_B];
dat0 |= (to256colex[dat] & 0x10101010) >> 1;
dat1 |= (to256colex[dat] & 0x80808080) >> 4;
dat = grp[pos + GRAM_R];
dat0 |= (to256colex[dat] & 0x10101010) << 0;
dat1 |= (to256colex[dat] & 0x80808080) >> 3;
dat = grp[pos + GRAM_G];
dat0 |= (to256colex[dat] & 0x10101010) << 1;
dat1 |= (to256colex[dat] & 0x80808080) >> 2;
*(UINT32 *)(dst + (MAKESCRN_VIDEOPAGE * 0)) = dat0;
*(UINT32 *)(dst + (MAKESCRN_VIDEOPAGE * 1)) = dat1;
pos = (pos + GRAM_LINESTEP) & (GRAM_LINESTEP * 7);
dst += vramstep;
} while(--count);
}
#if 0
void makemix_settext(UINT8 *dst, UINT align, const UINT8 *txt, UINT count) {
REG8 dat;
UINT32 datl;
UINT32 datr;
do {
dat = txt[MAKETEXT_ROW * 0];
datl = TO256COLL(dat, 3);
datr = TO256COLR(dat, 3);
dat = txt[MAKETEXT_ROW * 1];
datl |= TO256COLL(dat, 4);
datr |= TO256COLR(dat, 4);
dat = txt[MAKETEXT_ROW * 2];
datl |= TO256COLL(dat, 5);
datr |= TO256COLR(dat, 5);
*(UINT32 *)(dst + 0) = datl;
*(UINT32 *)(dst + 4) = datr;
txt++;
dst += align;
} while(--count);
}
void makemix_ul20(UINT8 *dst, UINT pos) {
UINT32 dat;
dat = (TRAM_KNJ(pos) & TRAMKNJ_ULINE)?0x01010101:0x00000000;
*(UINT32 *)(dst + (SURFACE_WIDTH * 0) + 0) = dat;
*(UINT32 *)(dst + (SURFACE_WIDTH * 0) + 4) = dat;
*(UINT32 *)(dst + (SURFACE_WIDTH * 1) + 0) = dat;
*(UINT32 *)(dst + (SURFACE_WIDTH * 1) + 4) = dat;
*(UINT32 *)(dst + (SURFACE_WIDTH * 2) + 0) = 0;
*(UINT32 *)(dst + (SURFACE_WIDTH * 2) + 4) = 0;
*(UINT32 *)(dst + (SURFACE_WIDTH * 3) + 0) = 0;
*(UINT32 *)(dst + (SURFACE_WIDTH * 3) + 4) = 0;
}
void makemix_ul10(UINT8 *dst, UINT pos) {
UINT32 dat;
dat = (TRAM_KNJ(pos) & TRAMKNJ_ULINE)?0x01010101:0x00000000;
*(UINT32 *)(dst + (SURFACE_WIDTH * 0) + 0) = dat;
*(UINT32 *)(dst + (SURFACE_WIDTH * 0) + 4) = dat;
// *(UINT32 *)(dst + (SURFACE_WIDTH * 1) + 0) = dat;
// *(UINT32 *)(dst + (SURFACE_WIDTH * 1) + 4) = dat;
*(UINT32 *)(dst + (SURFACE_WIDTH * 2) + 0) = dat;
*(UINT32 *)(dst + (SURFACE_WIDTH * 2) + 4) = dat;
// *(UINT32 *)(dst + (SURFACE_WIDTH * 3) + 0) = dat;
// *(UINT32 *)(dst + (SURFACE_WIDTH * 3) + 4) = dat;
*(UINT32 *)(dst + (SURFACE_WIDTH * 4) + 0) = 0;
*(UINT32 *)(dst + (SURFACE_WIDTH * 4) + 4) = 0;
// *(UINT32 *)(dst + (SURFACE_WIDTH * 5) + 0) = 0;
// *(UINT32 *)(dst + (SURFACE_WIDTH * 5) + 4) = 0;
*(UINT32 *)(dst + (SURFACE_WIDTH * 6) + 0) = 0;
*(UINT32 *)(dst + (SURFACE_WIDTH * 6) + 4) = 0;
// *(UINT32 *)(dst + (SURFACE_WIDTH * 7) + 0) = 0;
// *(UINT32 *)(dst + (SURFACE_WIDTH * 7) + 4) = 0;
}
void makemix_cpy200(UINT8 *dst, UINT pos, UINT count) {
count -= pos;
pos = pos * SURFACE_WIDTH * 2;
do {
*(UINT32 *)(dst + pos + 0) = *(UINT32 *)(dst + 0);
*(UINT32 *)(dst + pos + 4) = *(UINT32 *)(dst + 4);
dst += SURFACE_WIDTH * 2;
} while(--count);
}
void makemix_cpy400(UINT8 *dst, UINT pos, UINT count) {
count -= pos;
pos = pos * SURFACE_WIDTH;
do {
*(UINT32 *)(dst + pos + 0) = *(UINT32 *)(dst + 0);
*(UINT32 *)(dst + pos + 4) = *(UINT32 *)(dst + 4);
dst += SURFACE_WIDTH;
} while(--count);
}
#endif

379
nds/vram/makescrn.cpp Normal file
View File

@ -0,0 +1,379 @@
#include "compiler.h"
#include "libnds.h"
#include "pccore.h"
#include "iocore.h"
#include "vram.h"
#include "palettes.h"
#include "makescrn.h"
#include "makesub.h"
#include "vsyncff.h"
#define SUPPORT_WIDTH80
SCRNPOS scrnpos;
MAKESCRN makescrn;
static void fillupdatetmp(void)
{
for (UINT i=0; i<0x800; i++)
{
TRAMUPDATE(i) |= UPDATE_TVRAM;
}
}
static void flashupdatetmp(void)
{
BRESULT y2;
REG16 atr;
REG16 udtbase;
REG16 udt;
if (!makescrn.vramsize)
{
return;
}
UINT posl = crtc.e.pos;
UINT y = crtc.e.yl;
do
{
UINT x;
for (x=0; x<crtc.s.reg[CRTCREG_HDISP]; x++)
{
if (!(TRAM_ATR(LOW11(posl + x)) & TRAMATR_Yx2))
{
break;
}
}
y2 = (x < crtc.s.reg[CRTCREG_HDISP])?FALSE:TRUE;
udtbase = (x < crtc.s.reg[CRTCREG_HDISP])?0x0000:0x0404;
UINT r = (crtc.s.reg[CRTCREG_HDISP] + 1) >> 1;
do
{
UINT posr = LOW11(posl + 1);
atr = (TRAM_ATR(posl) << 8) | TRAM_ATR(posr);
udt = udtbase;
if (!y2)
{
if (atr & (TRAMATR_Yx2 << 8))
{
udt |= (UPDATE_TRAM | 1) << 8; // 左潰れ縦倍角
}
else
{
y2 = TRUE;
}
}
if (!y2)
{
if (atr & (TRAMATR_Yx2 << 0))
{
udt |= (UPDATE_TRAM | 1) << 0; // 右潰れ縦倍角
}
else
{
y2 = TRUE;
}
}
if (atr & (TRAMATR_Xx2 << 8)) // 左側倍角?
{
udt |= 0x0812;
}
if (atr & (TRAMATR_Xx2 << 0)) // 右側倍角?
{
udt |= 0x0008;
}
if ((TRAMUPDATE(posl) ^ (udt >> 8)) & 0x1f)
{
TRAMUPDATE(posl) = (UINT8)((udt >> 8) | UPDATE_TRAM);
}
if ((TRAMUPDATE(posr) ^ (udt >> 0)) & 0x1f)
{
TRAMUPDATE(posr) = (UINT8)((udt >> 0) | UPDATE_TRAM);
}
posl = LOW11(posl + 2);
} while(--r);
if (crtc.s.reg[CRTCREG_HDISP] & 1)
{
posl = LOW11(posl - 1);
}
} while(--y);
}
static BRESULT updateblink(void)
{
UINT uPos = makescrn.vramtop;
makescrn.blinktest ^= 0x10;
REG8 cUpdate = 0;
UINT r = makescrn.vramsize;
while(r)
{
r--;
if (TRAM_ATR(uPos) & 0x10)
{
TRAMUPDATE(uPos) |= UPDATE_TRAM;
cUpdate = UPDATE_TRAM;
}
uPos = LOW11(uPos + 1);
}
if (cUpdate)
{
return TRUE;
}
else
{
return FALSE;
}
}
// ----
typedef void (LONG_CALL * MAKEFN)(UINT uPos);
static void LONG_CALL width_dummy(UINT uPos) { }
static const MAKEFN screenmake[] = {
width40x25_200l, width_dummy,
width40x25_200l, width40x25_200l,
width40x12_200l, width_dummy,
width40x12_200l, width40x12_200l,
width_dummy, width_dummy,
width_dummy, width_dummy,
width_dummy, width_dummy,
width_dummy, width_dummy,
width80x25_200l, width_dummy,
width80x25_200l, width80x25_200l,
width80x12_200l, width_dummy,
width80x12_200l, width80x12_200l,
width_dummy, width_dummy,
width_dummy, width_dummy,
width_dummy, width_dummy,
width_dummy, width_dummy,
};
static void changemodes(void)
{
REG8 cDispMode = crtc.e.dispmode;
makescrn.dispmode = cDispMode;
makescrn.drawmode = cDispMode & DISPMODE_MASKMODE;
makemix_mixstep((BRESULT)(cDispMode & 4));
#if defined(SUPPORT_WIDTH80)
if (cDispMode & DISPMODE_WIDTH80)
{
makescrn.drawmode += 16;
vsyncff_turn(1);
}
else
{
vsyncff_turn(0);
}
#endif
if (!(cDispMode & DISPMODE_BANK1))
{
makescrn.disp1 = gram + GRAM_BANK0;
makescrn.disp2 = gram + GRAM_BANK1;
makescrn.dispflag = UPDATE_TRAM + UPDATE_VRAM0;
}
else
{
makescrn.disp1 = gram + GRAM_BANK1;
makescrn.disp2 = gram + GRAM_BANK0;
makescrn.dispflag = UPDATE_TRAM + UPDATE_VRAM1;
}
}
static void changecrtc(void)
{
makescrn.vramtop = crtc.e.pos;
UINT uScrnXMax;
UINT uCharCx;
#if defined(SUPPORT_WIDTH80)
if (makescrn.dispmode & DISPMODE_WIDTH80)
{
uScrnXMax = MAKESCRN_VIDEOWIDTH >> 2;
uCharCx = 4;
}
else
{
uScrnXMax = MAKESCRN_VIDEOWIDTH >> 3;
uCharCx = 8;
}
#else
uScrnXMax = MAKESCRN_VIDEOWIDTH >> 3;
uCharCx = 8;
#endif
UINT uScrnYMax = MAKESCRN_VIDEOHEIGHT;
UINT uTextXl = crtc.s.reg[CRTCREG_HDISP];
UINT uSurfCx = min(uScrnXMax, uTextXl);
const UINT uPosX = uTextXl - uSurfCx;
#if 1
scrnpos.x = uPosX / 2;
#else
if (scrnpos.x > uPosX)
{
scrnpos.x = uPosX;
}
#endif
UINT uFontCy = crtc.e.fonty;
UINT uUnderLines = (makescrn.dispmode & DISPMODE_UNDERLINE)?2:0;
if (uFontCy > uUnderLines)
{
uFontCy -= uUnderLines;
}
else
{
uFontCy = 0;
}
const REG8 y2 = (makescrn.dispmode & DISPMODE_TEXTYx2)?1:0;
uFontCy >>= y2;
if (!uFontCy)
{
uFontCy = 1;
}
if (uFontCy > 8)
{
uFontCy = 8;
}
UINT uCharCy = uFontCy + uUnderLines;
makescrn.fontcy = uFontCy;
makescrn.charcy = uCharCy;
uCharCy <<= y2;
UINT uSurfCy = uScrnYMax / uCharCy;
if (uSurfCy > crtc.e.yl)
{
uSurfCy = crtc.e.yl;
}
const UINT uPosY = crtc.e.yl - uSurfCy;
if (scrnpos.y > uPosY)
{
scrnpos.y = uPosY;
}
makescrn.surfcx = uSurfCx;
makescrn.surfrx = uTextXl - uSurfCx;
makescrn.surfcy = uSurfCy;
makescrn.surfstep = (MAKESCRN_VIDEOYALIGN * uCharCy) - (uSurfCx * uCharCx);
makescrn.vramsize = min(0x800, uSurfCy * uTextXl);
}
void scrnupdate(void)
{
REG8 flag;
REG8 existblink;
UINT fontycnt;
UINT pos;
UINT y;
REG8 udtmp;
if (!corestat.drawframe)
{
return;
}
corestat.drawframe = 0;
flag = 0;
if (crtc.e.scrnflash)
{
crtc.e.scrnflash = 0;
flag |= SCRNUPD_FLASH;
}
if (crtc.e.scrnallflash)
{
crtc.e.scrnallflash = 0;
flag |= SCRNUPD_ALLFLASH;
}
if (crtc.e.palandply)
{
crtc.e.palandply = 0;
flag |= SCRNUPD_PALANDPLY;
}
if (makescrn.dispmode != crtc.e.dispmode)
{
TRACEOUT(("change mode!"));
changemodes();
flag |= SCRNUPD_ALLFLASH | SCRNUPD_PALANDPLY;
}
if (flag & SCRNUPD_ALLFLASH)
{
changecrtc();
fillupdatetmp();
}
if (crtc.e.remakeattr)
{
crtc.e.remakeattr = 0;
flashupdatetmp();
}
if (flag & SCRNUPD_PALANDPLY)
{
pal_update();
}
if (crtc.e.blinktime)
{
crtc.e.blinktime--;
}
else
{
crtc.e.blinktime = 30 - 1;
if (crtc.e.existblink)
{
existblink = updateblink();
crtc.e.existblink = existblink;
flag |= existblink;
}
}
if (flag & (SCRNUPD_FLASH | SCRNUPD_ALLFLASH))
{
if (makescrn.vramsize)
{
fontycnt = 0;
pos = makescrn.vramtop;
y = scrnpos.y;
if (y)
{
do
{
udtmp = TRAMUPDATE(pos);
if (udtmp & 4)
{
fontycnt += makescrn.charcy;
}
else
{
fontycnt = makescrn.charcy * 2;
}
pos = LOW11(pos + crtc.s.reg[CRTCREG_HDISP]);
} while(--y);
fontycnt = fontycnt & 15;
}
makescrn.fontycnt = fontycnt;
pos += scrnpos.x;
screenmake[makescrn.drawmode](pos);
ndsvideo_vramnotify();
}
}
}
void makescrn_initialize(void)
{
CopyMemory(makescrn.patx2, patx2, 0x100);
vsyncff_init();
}
void makescrn_reset(void)
{
changemodes();
changecrtc();
flashupdatetmp();
}

82
nds/vram/makescrn.h Normal file
View File

@ -0,0 +1,82 @@
enum {
SCRNUPD_FLASH = (1 << 0),
SCRNUPD_ALLFLASH = (1 << 1),
SCRNUPD_PALANDPLY = (1 << 2)
};
enum {
MAKESCRN_320x200S = 0,
MAKESCRN_640x200S = 1,
MAKESCRN_320x200H = 2,
MAKESCRN_640x200H = 3,
MAKESCRN_320x400 = 4,
MAKESCRN_640x400 = 5,
MAKESCRN_4096 = 6
};
typedef struct {
UINT x;
UINT y;
} SCRNPOS;
typedef struct {
UINT8 *disp1;
UINT8 *disp2;
UINT8 dispflag;
UINT8 dispmode;
UINT8 drawmode;
UINT8 blinktest;
UINT vramtop;
UINT fontycnt;
UINT fontcy;
UINT charcy;
UINT surfcx;
UINT surfrx;
UINT surfcy;
// UINT surfsy;
UINT surfstep;
UINT vramsize;
UINT8 patx2[0x100];
} MAKESCRN;
#if MAKESCRN_VRAMFF
enum
{
MAKESCRN_VIDEOWIDTH = 256,
MAKESCRN_VIDEOHEIGHT = 192,
MAKESCRN_VIDEOPAGE = 256,
MAKESCRN_VIDEOYALIGN = 512,
};
#else /* MAKESCRN_VRAMFF */
enum
{
MAKESCRN_VIDEOWIDTH = 256,
MAKESCRN_VIDEOHEIGHT = 192,
MAKESCRN_VIDEOPAGE = (256 * 192),
MAKESCRN_VIDEOYALIGN = 256,
};
#endif /* MAKESCRN_VRAMFF */
#ifdef __cplusplus
extern "C" {
#endif
extern SCRNPOS scrnpos;
extern MAKESCRN makescrn;
void scrnupdate(void);
void makescrn_initialize(void);
void makescrn_reset(void);
#ifdef __cplusplus
}
#endif

110
nds/vram/makesub.cpp Normal file
View File

@ -0,0 +1,110 @@
#include "compiler.h"
#include "makescrn.h"
#include "makesub.h"
const UINT8 patx2[256] = {
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff,
0x00,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff};
#if defined(BYTESEX_LITTLE)
const UINT32 to256colex[256] = {
0x00000000, 0x18000000, 0x80080000, 0x98080000,
0x00800800, 0x18800800, 0x80880800, 0x98880800,
0x00100008, 0x18100008, 0x80180008, 0x98180008,
0x00900808, 0x18900808, 0x80980808, 0x98980808,
0x01001000, 0x19001000, 0x81081000, 0x99081000,
0x01801800, 0x19801800, 0x81881800, 0x99881800,
0x01101008, 0x19101008, 0x81181008, 0x99181008,
0x01901808, 0x19901808, 0x81981808, 0x99981808,
0x00018000, 0x18018000, 0x80098000, 0x98098000,
0x00818800, 0x18818800, 0x80898800, 0x98898800,
0x00118008, 0x18118008, 0x80198008, 0x98198008,
0x00918808, 0x18918808, 0x80998808, 0x98998808,
0x01019000, 0x19019000, 0x81099000, 0x99099000,
0x01819800, 0x19819800, 0x81899800, 0x99899800,
0x01119008, 0x19119008, 0x81199008, 0x99199008,
0x01919808, 0x19919808, 0x81999808, 0x99999808,
0x00000180, 0x18000180, 0x80080180, 0x98080180,
0x00800980, 0x18800980, 0x80880980, 0x98880980,
0x00100188, 0x18100188, 0x80180188, 0x98180188,
0x00900988, 0x18900988, 0x80980988, 0x98980988,
0x01001180, 0x19001180, 0x81081180, 0x99081180,
0x01801980, 0x19801980, 0x81881980, 0x99881980,
0x01101188, 0x19101188, 0x81181188, 0x99181188,
0x01901988, 0x19901988, 0x81981988, 0x99981988,
0x00018180, 0x18018180, 0x80098180, 0x98098180,
0x00818980, 0x18818980, 0x80898980, 0x98898980,
0x00118188, 0x18118188, 0x80198188, 0x98198188,
0x00918988, 0x18918988, 0x80998988, 0x98998988,
0x01019180, 0x19019180, 0x81099180, 0x99099180,
0x01819980, 0x19819980, 0x81899980, 0x99899980,
0x01119188, 0x19119188, 0x81199188, 0x99199188,
0x01919988, 0x19919988, 0x81999988, 0x99999988,
0x00000011, 0x18000011, 0x80080011, 0x98080011,
0x00800811, 0x18800811, 0x80880811, 0x98880811,
0x00100019, 0x18100019, 0x80180019, 0x98180019,
0x00900819, 0x18900819, 0x80980819, 0x98980819,
0x01001011, 0x19001011, 0x81081011, 0x99081011,
0x01801811, 0x19801811, 0x81881811, 0x99881811,
0x01101019, 0x19101019, 0x81181019, 0x99181019,
0x01901819, 0x19901819, 0x81981819, 0x99981819,
0x00018011, 0x18018011, 0x80098011, 0x98098011,
0x00818811, 0x18818811, 0x80898811, 0x98898811,
0x00118019, 0x18118019, 0x80198019, 0x98198019,
0x00918819, 0x18918819, 0x80998819, 0x98998819,
0x01019011, 0x19019011, 0x81099011, 0x99099011,
0x01819811, 0x19819811, 0x81899811, 0x99899811,
0x01119019, 0x19119019, 0x81199019, 0x99199019,
0x01919819, 0x19919819, 0x81999819, 0x99999819,
0x00000191, 0x18000191, 0x80080191, 0x98080191,
0x00800991, 0x18800991, 0x80880991, 0x98880991,
0x00100199, 0x18100199, 0x80180199, 0x98180199,
0x00900999, 0x18900999, 0x80980999, 0x98980999,
0x01001191, 0x19001191, 0x81081191, 0x99081191,
0x01801991, 0x19801991, 0x81881991, 0x99881991,
0x01101199, 0x19101199, 0x81181199, 0x99181199,
0x01901999, 0x19901999, 0x81981999, 0x99981999,
0x00018191, 0x18018191, 0x80098191, 0x98098191,
0x00818991, 0x18818991, 0x80898991, 0x98898991,
0x00118199, 0x18118199, 0x80198199, 0x98198199,
0x00918999, 0x18918999, 0x80998999, 0x98998999,
0x01019191, 0x19019191, 0x81099191, 0x99099191,
0x01819991, 0x19819991, 0x81899991, 0x99899991,
0x01119199, 0x19119199, 0x81199199, 0x99199199,
0x01919999, 0x19919999, 0x81999999, 0x99999999};
#else
// big endian!
#endif

68
nds/vram/makesub.h Normal file
View File

@ -0,0 +1,68 @@
enum {
MAKETEXT_ROW = 8,
MAKETEXT_STEP = 24
};
#ifdef __cplusplus
extern "C" {
#endif
extern const UINT8 patx2[256];
extern const UINT32 to256colex[256];
#define PATx2LEFT(p) (makescrn.patx2[(p) >> 4])
#define PATx2RIGHT(p) (makescrn.patx2[(p) >> 0])
// ---- make pattern
typedef void (LONG_CALL * MAKETXTFN)(UINT8 *dst, UINT8 *term, const UINT8 *src);
extern const MAKETXTFN maketxtlfn[32];
void LONG_CALL maketxt8_make(UINT8 *dst, UINT8 *term, const UINT8 *src, REG8 type, REG8 attr);
void LONG_CALL makepcg8_make(UINT8 *dst, UINT8 *term, const UINT8 *src, REG8 type, REG8 attr);
// ---- make attributes
typedef void (LONG_CALL * MAKEATRFN)(UINT8 *dst, UINT8 *term);
extern const MAKEATRFN makeatr8[16];
// ---- make character
void makechr8(UINT8 *dst, const MAKESCRN *m, UINT32 pos_cy, REG8 udtmp);
void makechr16(UINT8 *dst, UINT pos, UINT count, REG8 udtmp);
// ---- make mixer
void LONG_CALL makemix_mixstep(BRESULT x2);
void LONG_CALL makemix_mixtext40(UINT8 *dst, const UINT8 *txt, UINT count);
void LONG_CALL makemix_mixgrph40(UINT8 *dst, const UINT8 *grp, UINT count);
void LONG_CALL makemix_mixtext80(UINT8 *dst, const UINT8 *txt, UINT count);
void LONG_CALL makemix_mixgrph80(UINT8 *dst, const UINT8 *grp, UINT count);
// ---- make screens
void LONG_CALL width40x25_200l(UINT pos); // 40x25 200line
void LONG_CALL width80x25_200l(UINT pos); // 80x25 200line
void LONG_CALL width40x12_200l(UINT pos); // 40x12 200line
void LONG_CALL width80x12_200l(UINT pos); // 80x12 200line
#if 0
void width80x20l(void); // 80x20
void width80x10l(void); // 80x10
void width80x25_400h(void); // 80x25 400line
void width80x12_400h(void); // 80x12 400line
void width80x20h(void); // 80x20
void width80x10h(void); // 80x10
#endif
#ifdef __cplusplus
}
#endif

478
nds/vram/maketxtl.cpp Normal file
View File

@ -0,0 +1,478 @@
#include "compiler.h"
#include "makescrn.h"
#include "makesub.h"
// ---------------------------------------------------- 8ライン ANK キャラクタ
// ノーマル
static void LONG_CALL txt8_nor(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
pos = 0; // カウンタは戻る
do {
*dst = src[pos];
pos = (pos + 1) & 7;
dst++;
} while(dst < term);
}
// 横倍角左
static void LONG_CALL txt8_x2left(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
pos = 0; // カウンタは戻る
do {
*dst = PATx2LEFT(src[pos]);
pos = (pos + 1) & 7;
dst++;
} while(dst < term);
}
// 横倍角右
static void LONG_CALL txt8_x2right(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
pos = 0; // カウンタは戻る
do {
*dst = PATx2RIGHT(src[pos]);
pos = (pos + 1) & 7;
dst++;
} while(dst < term);
}
// 縦倍角上
static void LONG_CALL txt8_Yx2(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt >> 1; // レジューム
do {
dat = src[pos];
pos = (pos + 1) & 7;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
} while(dst < term);
}
// 4倍角左
static void LONG_CALL txt8_x4left(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt >> 1; // レジューム
do {
dat = PATx2LEFT(src[pos]);
pos = (pos + 1) & 7;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
} while(dst < term);
}
// 4倍角右
static void LONG_CALL txt8_x4right(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt >> 1; // レジューム
do {
dat = PATx2RIGHT(src[pos]);
pos = (pos + 1) & 7;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
} while(dst < term);
}
// 右4ドット
static void LONG_CALL txt8_right4dot(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
pos = 0; // カウンタは戻る
do {
*dst = (UINT8)(src[pos] << 4);
pos = (pos + 1) & 7;
dst++;
} while(dst < term);
}
// 潰れ右4ドット
static void LONG_CALL txt8_right4half(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt >> 1; // レジューム
if (pos) { // 最初の1回だけ
dat = src[pos] << 4;
pos = 0;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
while(dst < term) {
dat = src[pos] << 4;
pos = (pos + 2) & 7;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
}
// 右4ドット縦倍角上
static void LONG_CALL txt8_right4x2(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt >> 1; // レジューム
do {
dat = src[pos] << 4;
pos = (pos + 1) & 7;
dst[0] = (UINT)dat;
dst[1] = (UINT)dat;
dst += 2;
} while(dst < term);
}
// 潰して縦倍角
static void LONG_CALL txt8_halfx2(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt >> 1; // レジューム
if (pos) { // 最初の1回だけ
dat = src[pos];
pos = 0;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
while(dst < term) {
dat = src[pos];
pos = (pos + 2) & 7;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
}
// 潰して4倍角左
static void LONG_CALL txt8_halfx4left(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt >> 1; // レジューム
if (pos) { // 最初の1回だけ
dat = PATx2LEFT(src[pos]);
pos = 0;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
while(dst < term) {
dat = PATx2LEFT(src[pos]);
pos = (pos + 2) & 7;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
}
// 潰して4倍角右
static void LONG_CALL txt8_halfx4right(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt >> 1; // レジューム
if (pos) { // 最初の1回だけ
dat = PATx2RIGHT(src[pos]);
pos = 0;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
while(dst < term) {
dat = PATx2RIGHT(src[pos]);
pos = (pos + 2) & 7;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
}
// ---------------------------------------------------- 8ライン 漢字キャラクタ
// ノーマル
static void LONG_CALL knj8_nor(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
pos = 0; // カウンタは戻る
do {
*dst = src[pos];
pos = (pos + 2) & 15;
dst++;
} while(dst < term);
}
// 横倍角左
static void LONG_CALL knj8_x2left(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
pos = 0; // カウンタは戻る
do {
*dst = PATx2LEFT(src[pos]);
pos = (pos + 2) & 15;
dst++;
} while(dst < term);
}
// 横倍角右
static void LONG_CALL knj8_x2right(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
pos = 0; // カウンタは戻る
do {
*dst = PATx2RIGHT(src[pos]);
pos = (pos + 2) & 15;
dst++;
} while(dst < term);
}
// 縦倍角
static void LONG_CALL knj8_Yx2(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt; // レジューム
do {
dat = src[pos];
pos = (pos + 1) & 15;
*dst = (UINT8)dat;
dst++;
} while(dst < term);
}
// 4倍角左
static void LONG_CALL knj8_x4left(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt; // レジューム
do {
dat = PATx2LEFT(src[pos]);
pos = (pos + 1) & 15;
*dst = (UINT8)dat;
dst++;
} while(dst < term);
}
// 4倍角右
static void LONG_CALL knj8_x4right(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt; // レジューム
do {
dat = PATx2RIGHT(src[pos]);
pos = (pos + 1) & 15;
*dst = (UINT8)dat;
dst++;
} while(dst < term);
}
// 右4ドット
static void LONG_CALL knj8_right4dot(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
pos = 0; // カウンタは戻る
do {
*dst = (UINT8)(src[pos] << 4);
pos = (pos + 2) & 15;
dst++;
} while(dst < term);
}
// 潰れ右4ドット
static void LONG_CALL knj8_right4half(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt; // レジューム
if (pos) { // 最初の1回だけ
dat = src[pos] << 4;
pos = 0;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
while(dst < term) {
dat = src[pos] << 4;
pos = (pos + 4) & 15;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
}
// 右4ドット縦倍角
static void LONG_CALL knj8_right4x2(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt; // レジューム
do {
dat = src[pos] << 4;
pos = (pos + 1) & 15;
*dst = (UINT)dat;
dst++;
} while(dst < term);
}
// 潰して縦倍角
static void LONG_CALL knj8_halfx2(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt; // レジューム
if (pos) { // 最初の1回だけ
dat = src[pos];
pos = 0;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
while(dst < term) {
dat = src[pos];
pos = (pos + 4) & 15;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
}
// 潰して4倍角左
static void LONG_CALL knj8_halfx4left(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt; // レジューム
if (pos) { // 最初の1回だけ
dat = PATx2LEFT(src[pos]);
pos = 0;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
while(dst < term) {
dat = PATx2LEFT(src[pos]);
pos = (pos + 4) & 15;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
}
// 潰して4倍角右
static void LONG_CALL knj8_halfx4right(UINT8 *dst, UINT8 *term, const UINT8 *src) {
UINT pos;
REG8 dat;
pos = makescrn.fontycnt; // レジューム ?
if (pos) { // 最初の1回だけ
dat = PATx2RIGHT(src[pos]);
pos = 0;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
while(dst < term) {
dat = PATx2RIGHT(src[pos]);
pos = (pos + 4) & 15;
dst[0] = (UINT8)dat;
dst[1] = (UINT8)dat;
dst += 2;
}
}
// ----
static void LONG_CALL draw_nop(UINT8 *dst, UINT8 *term, const UINT8 *src) {
(void)dst;
(void)term;
(void)src;
}
// --------------------------------------------------------------------------
const MAKETXTFN maketxtlfn[32] = {
txt8_nor, // ノーマル
txt8_halfx2, // 潰して縦倍角
txt8_right4dot, // 右4ドット
txt8_right4half, // 潰れ右4ドット
txt8_Yx2, // 縦倍角
draw_nop, // ありえない
txt8_right4x2, // 右4ドット縦倍角
draw_nop, // ありえない
txt8_x2left, // 横倍角左
txt8_halfx4left, // 潰して4倍角左
txt8_x2right, // 横倍角右
txt8_halfx4right, // 潰して4倍角右
txt8_x4left, // 4倍角左
draw_nop, // ありえない
txt8_x4right, // 4倍角右
draw_nop, // ありえない
knj8_nor, // ノーマル
knj8_halfx2, // 潰して縦倍角
knj8_right4dot, // 右4ドット
knj8_right4half, // 潰れ右4ドット
knj8_Yx2, // 縦倍角
draw_nop, //
knj8_right4x2, // 右4ドット縦倍角
draw_nop, //
knj8_x2left, // 横倍角左
knj8_halfx4left, // 潰して4倍角左
knj8_x2right, // 横倍角右
knj8_halfx4right, // 潰して4倍角右
knj8_x4left, // 4倍角左
draw_nop, //
knj8_x4right, // 4倍角右
draw_nop //
};

98
nds/vram/palettes.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "compiler.h"
#include "libnds.h"
#include "pccore.h"
#include "iocore.h"
#include "palettes.h"
#include "makescrn.h"
// ----
typedef struct
{
UINT16 text[8];
} PALS;
static PALS pals;
static void pal_settext(REG8 num)
{
REG16 rgb;
rgb = (num & 1)?(0x1f << 10):0;
rgb += (num & 4)?(0x1f << 5):0;
rgb += (num & 2)?(0x1f << 0):0;
pals.text[num] = rgb;
crtc.e.palandply = 1;
}
// ----
void pal_update1(const UINT8 *rgbp)
{
static UINT16 pal[64];
UINT16 *advpal;
UINT i;
UINT j;
REG8 bit;
UINT c;
UINT bcnt;
REG16 txtpal;
advpal = pal;
for (i=0, bit=1; i<8; i++, bit<<=1) {
c = 0;
if (rgbp[CRTC_PALB] & bit) {
c += 1;
}
if (rgbp[CRTC_PALR] & bit) {
c += 2;
}
if (rgbp[CRTC_PALG] & bit) {
c += 4;
}
txtpal = pals.text[c];
*advpal++ = (UINT16)txtpal;
if (rgbp[CRTC_PLY] & bit) {
for (j=1; j<8; j++) {
*advpal++ = (UINT16)txtpal;
}
}
else {
bcnt = (rgbp[CRTC_BLACK] & 15) - 8;
for (j=1; j<8; j++) {
bcnt--;
if (bcnt) {
c = j;
}
else {
c = 0;
}
*advpal++ = pals.text[c];
}
}
}
for (i=0; i<64; i++)
{
BG_PALETTE[i] = pal[i];
}
}
void pal_update()
{
pal_update1(crtc.s.rgbp);
}
// ----
void pal_reset()
{
for (REG8 i=0; i<8; i++)
{
pal_settext(i);
}
}

17
nds/vram/palettes.h Normal file
View File

@ -0,0 +1,17 @@
#ifdef __cplusplus
extern "C"
{
#endif
void pal_update1(const UINT8 *rgbp);
void pal_update();
void pal_reset();
#ifdef __cplusplus
}
#endif
#define pal_eventclear()

75
nds/vram/vram.h Normal file
View File

@ -0,0 +1,75 @@
// ---- TRAM
enum
{
TRAMATR_COLOR = 0x07,
TRAMATR_REVERSE = 0x08,
TRAMATR_BLINK = 0x10,
TRAMATR_PCG = 0x20,
TRAMATR_Yx2 = 0x40,
TRAMATR_Xx2 = 0x80,
TRAMKNJ_ULINE = 0x20
};
enum
{
UPDATE_TRAM = (1 << 5),
UPDATE_VRAM0 = (1 << 6),
UPDATE_VRAM1 = (1 << 7),
UPDATE_VRAM = UPDATE_VRAM0 | UPDATE_VRAM1,
UPDATE_TVRAM = UPDATE_VRAM0 | UPDATE_VRAM1 | UPDATE_TRAM
};
typedef struct
{
UINT8 atr;
UINT8 ank;
UINT8 knj;
UINT8 _udt;
} TRAM;
// ---- GRAM
enum
{
GRAM_BANK0 = 0x00000,
GRAM_BANK1 = 0x10000,
GRAM_BANK0L = 0x00000,
GRAM_BANK0H = 0x00400,
GRAM_BANK1L = 0x10000,
GRAM_BANK1H = 0x10400,
GRAM_HALFSTEP = 0x00400,
GRAM_LINESTEP = 0x0800,
GRAM_B = 0x0000,
GRAM_R = 0x4000,
GRAM_G = 0x8000,
GRAM_RGBMASK = 0xc000
};
#define PORT2GRAM(port) ((port) - 0x4000)
#define PORT2GRAM2(port) ((port) & (~0xc000))
#define TRAM2GRAM(addr) (addr)
#ifdef __cplusplus
extern "C"
{
#endif
extern TRAM tram[0x800];
extern UINT8 gram[];
extern UINT8 vramupd[0x800];
#ifdef __cplusplus
}
#endif
#define TRAM_ANK(addr) tram[addr].ank
#define TRAM_KNJ(addr) tram[addr].knj
#define TRAM_ATR(addr) tram[addr].atr
#define TRAMUPDATE(addr) vramupd[addr]

56
nds/vram/vsyncff.cpp Normal file
View File

@ -0,0 +1,56 @@
#include "compiler.h"
#include "libnds.h"
#include "makescrn.h"
#include "vsyncff.h"
#if MAKESCRN_VRAMFF
static UINT8 s_cEnable = 0;
static UINT8 s_cPage = 0;
void vsyncff_init()
{
s_cEnable = 0;
s_cPage = 0;
}
void vsyncff_int()
{
if (s_cEnable)
{
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = (s_cPage * 256) << 8;
BG3_CY = 0 << 8;
s_cPage ^= 1;
}
}
void vsyncff_turn(REG8 en)
{
en = en & 1;
s_cEnable = en;
if (!en)
{
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = 0 << 8;
BG3_CY = 0 << 8;
}
}
#else // MAKESCRN_VRAMFF
// ƒ_ƒ~<7E>[
void vsyncff_init() { }
void vsyncff_int() { }
void vsyncff_turn(REG8 en) { }
#endif // MAKESCRN_VRAMFF

14
nds/vram/vsyncff.h Normal file
View File

@ -0,0 +1,14 @@
#ifdef __cplusplus
extern "C"
{
#endif
void vsyncff_init();
void vsyncff_int();
void vsyncff_turn(REG8 en);
#ifdef __cplusplus
}
#endif

83
nds/win32s/compiler.h Normal file
View File

@ -0,0 +1,83 @@
#define _WIN32_IE 0x0200
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
#include "ndscore.h"
#define BYTESEX_LITTLE
#define OSLANG_SJIS
#define OSLINEBREAK_CRLF
#define NDS_SIMULATE
#ifndef __GNUC__
typedef signed int SINT;
typedef signed char SINT8;
typedef unsigned char UINT8;
typedef signed short SINT16;
typedef unsigned short UINT16;
typedef signed int SINT32;
typedef unsigned int UINT32;
typedef signed __int64 SINT64;
typedef unsigned __int64 UINT64;
#define INLINE __inline
#define QWORD_CONST(v) ((UINT64)(v))
#define SQWORD_CONST(v) ((SINT64)(v))
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#else
#include <stdlib.h>
typedef signed char SINT8;
typedef unsigned char UINT8;
typedef short SINT16;
typedef unsigned short UINT16;
typedef int SINT32;
typedef signed __int64 SINT64;
#define INLINE inline
#endif
#define FASTCALL __fastcall
#define LOADINTELDWORD(a) (*((UINT32 *)(a)))
#define LOADINTELWORD(a) (*((UINT16 *)(a)))
#define STOREINTELDWORD(a, b) *(UINT32 *)(a) = (b)
#define STOREINTELWORD(a, b) *(UINT16 *)(a) = (b)
#define STRCALL __stdcall
#define BRESULT UINT8
#define OEMCHAR TCHAR
#define OEMTEXT(string) _T(string)
#define OEMSPRINTF wsprintf
#define OEMSTRLEN lstrlen
#include "common.h"
#include "milstr.h"
#include "_memory.h"
#include "trace.h"
#include "rect.h"
#include "extrom.h"
#define GETTICK() GetTickCount()
#define __ASSERT(s)
#define SPRINTF wsprintf
#define STRLEN lstrlen
#define SUPPORT_SJIS
#define DISABLE_SOUND
#define DISABLE_MAKEFONT
#define DISABLE_MOUSE
#define CONST_DISKIMAGE
#define FIX_Z80A
#define SUPPORT_8BPP
#define SUPPORT_16BPP
#define SUPPORT_24BPP
#define SUPPORT_32BPP
#define LONG_CALL

285
nds/win32s/dosio.cpp Normal file
View File

@ -0,0 +1,285 @@
#include "compiler.h"
#include "dosio.h"
static TCHAR s_szCurPath[MAX_PATH];
static LPTSTR s_lpszFile = s_szCurPath;
// ----
void dosio_init() { }
void dosio_term() { }
// ファイル操作
FILEH __stdcall file_open(LPCTSTR lpcszPath)
{
FILEH fhRet = CreateFile(lpcszPath, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fhRet == INVALID_HANDLE_VALUE)
{
fhRet = CreateFile(lpcszPath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
if (fhRet == INVALID_HANDLE_VALUE)
{
return FILEH_INVALID;
}
return fhRet;
}
FILEH __stdcall file_open_rb(LPCTSTR lpcszPath)
{
FILEH fhRet = CreateFile(lpcszPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fhRet == INVALID_HANDLE_VALUE)
{
return FILEH_INVALID;
}
return fhRet;
}
FILEH __stdcall file_create(LPCTSTR lpcszPath)
{
FILEH fhRet = CreateFile(lpcszPath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fhRet == INVALID_HANDLE_VALUE)
{
return FILEH_INVALID;
}
return fhRet;
}
long __stdcall file_seek(FILEH handle, long lPointer, int nMethod)
{
return SetFilePointer(handle, lPointer, 0, nMethod);
}
UINT __stdcall file_read(FILEH handle, LPVOID lpvData, UINT uLength)
{
DWORD dwReadSize;
if (!ReadFile(handle, lpvData, uLength, &dwReadSize, NULL))
{
return 0;
}
return dwReadSize;
}
UINT __stdcall file_write(FILEH handle, LPCVOID lpcvData, UINT uLength)
{
if (uLength)
{
DWORD dwWriteSize;
if (WriteFile(handle, lpcvData, uLength, &dwWriteSize, NULL))
{
return dwWriteSize;
}
}
else
{
SetEndOfFile(handle);
}
return 0;
}
BRESULT __stdcall file_close(FILEH handle)
{
CloseHandle(handle);
return 0;
}
UINT __stdcall file_getsize(FILEH handle)
{
return GetFileSize(handle, NULL);
}
static BRESULT cnvdatetime(LPFILETIME lpFt, PDOSDATE pDosDate, PDOSTIME pDosTime)
{
FILETIME localtime;
if (FileTimeToLocalFileTime(lpFt, &localtime) == 0)
{
return FAILURE;
}
SYSTEMTIME systime;
if (FileTimeToSystemTime(&localtime, &systime) == 0)
{
return FAILURE;
}
if (pDosDate)
{
pDosDate->year = (UINT16)systime.wYear;
pDosDate->month = (UINT8)systime.wMonth;
pDosDate->day = (UINT8)systime.wDay;
}
if (pDosTime)
{
pDosTime->hour = (UINT8)systime.wHour;
pDosTime->minute = (UINT8)systime.wMinute;
pDosTime->second = (UINT8)systime.wSecond;
}
return SUCCESS;
}
BRESULT __stdcall file_getdatetime(FILEH handle, PDOSDATE pDosDate, PDOSTIME pDosTime)
{
FILETIME lastwrite;
if ((GetFileTime(handle, NULL, NULL, &lastwrite) == 0) ||
(cnvdatetime(&lastwrite, pDosDate, pDosTime) != SUCCESS))
{
return FAILURE;
}
return SUCCESS;
}
BRESULT __stdcall file_delete(LPCTSTR lpcszPath)
{
return (DeleteFile(lpcszPath) ? SUCCESS : FAILURE);
}
SINT16 __stdcall file_attr(LPCTSTR lpcszPath)
{
return static_cast<SINT16>(GetFileAttributes(lpcszPath));
}
BRESULT __stdcall file_dircreate(LPCTSTR lpcszPath)
{
return (CreateDirectory(lpcszPath, NULL) ? SUCCESS : FAILURE);
}
// カレントファイル操作
void __stdcall file_setcd(LPCTSTR lpcszExePath)
{
file_cpyname(s_szCurPath, lpcszExePath, NELEMENTS(s_szCurPath));
s_lpszFile = file_getname(s_szCurPath);
*s_lpszFile = '\0';
}
OEMCHAR * __stdcall file_getcd(LPCTSTR lpcszPath)
{
*s_lpszFile = '\0';
file_catname(s_szCurPath, lpcszPath, NELEMENTS(s_szCurPath));
return s_szCurPath;
}
FILEH __stdcall file_open_c(LPCTSTR lpcszPath)
{
*s_lpszFile = '\0';
file_catname(s_szCurPath, lpcszPath, NELEMENTS(s_szCurPath));
return file_open(s_szCurPath);
}
FILEH __stdcall file_open_rb_c(LPCTSTR lpcszPath)
{
*s_lpszFile = '\0';
file_catname(s_szCurPath, lpcszPath, NELEMENTS(s_szCurPath));
return file_open_rb(s_szCurPath);
}
FILEH __stdcall file_create_c(LPCTSTR lpcszPath)
{
*s_lpszFile = '\0';
file_catname(s_szCurPath, lpcszPath, NELEMENTS(s_szCurPath));
return file_create(s_szCurPath);
}
BRESULT __stdcall file_delete_c(LPCTSTR lpcszPath)
{
*s_lpszFile = '\0';
file_catname(s_szCurPath, lpcszPath, NELEMENTS(s_szCurPath));
return file_delete(s_szCurPath);
}
SINT16 __stdcall file_attr_c(LPCTSTR lpcszPath)
{
*s_lpszFile = '\0';
file_catname(s_szCurPath, lpcszPath, NELEMENTS(s_szCurPath));
return file_attr(s_szCurPath);
}
LPTSTR __stdcall file_getname(LPCTSTR lpcszPath)
{
LPCTSTR lpcszRet = lpcszPath;
int nSize;
while((nSize = milstr_charsize(lpcszPath)) != 0)
{
if (nSize == 1)
{
if ((*lpcszPath == '\\') || (*lpcszPath == '/') || (*lpcszPath == ':'))
{
lpcszRet = lpcszPath + 1;
}
}
lpcszPath += nSize;
}
return const_cast<LPTSTR>(lpcszRet);
}
void __stdcall file_cutname(LPTSTR lpszPath)
{
LPTSTR p = file_getname(lpszPath);
p[0] = '\0';
}
LPTSTR __stdcall file_getext(LPCTSTR lpcszPath)
{
LPCTSTR p = file_getname(lpcszPath);
LPCTSTR q = 0;
while(*p != '\0')
{
if (*p == '.')
{
q = p + 1;
}
p++;
}
if (!q)
{
q = p;
}
return const_cast<LPTSTR>(q);
}
void __stdcall file_cutext(LPTSTR lpszPath)
{
LPTSTR p = file_getname(lpszPath);
LPTSTR q = 0;
while(*p != '\0')
{
if (*p == '.')
{
q = p;
}
p++;
}
if (q)
{
*q = '\0';
}
}
void __stdcall file_cutseparator(LPTSTR lpszPath)
{
int nPos = lstrlen(lpszPath) - 1;
if ((nPos > 0) && // 2文字以上でー
(lpszPath[nPos] == '\\') && // ケツが \ でー
(!milstr_kanji2nd(lpszPath, nPos)) && // 漢字の2バイト目ぢゃなくてー
((nPos != 1) || (lpszPath[0] != '\\')) && // '\\' ではなくてー
((nPos != 2) || (lpszPath[1] != ':'))) // '?:\' ではなかったら
{
lpszPath[nPos] = '\0';
}
}
void __stdcall file_setseparator(LPTSTR lpszPath, int nMaxLen)
{
const int nPos = lstrlen(lpszPath) - 1;
if ((nPos < 0) ||
((nPos == 1) && (lpszPath[1] == ':')) ||
((lpszPath[nPos] == '\\') && (!milstr_kanji2nd(lpszPath, nPos))) ||
((nPos + 2) >= nMaxLen))
{
return;
}
lpszPath[nPos + 1] = '\\';
lpszPath[nPos + 2] = '\0';
}

78
nds/win32s/dosio.h Normal file
View File

@ -0,0 +1,78 @@
#define FILEH HANDLE
#define FILEH_INVALID (INVALID_HANDLE_VALUE)
enum
{
FSEEK_SET = 0,
FSEEK_CUR = 1,
FSEEK_END = 2
};
struct tagDosDate
{
UINT16 year; // cx
UINT8 month; // dh
UINT8 day; // dl
};
typedef struct tagDosDate DOSDATE;
typedef struct tagDosDate *PDOSDATE;
struct tagDosTime
{
UINT8 hour; // ch
UINT8 minute; // cl
UINT8 second; // dh
};
typedef struct tagDosTime DOSTIME;
typedef struct tagDosTime *PDOSTIME;
#ifdef __cplusplus
extern "C"
{
#endif
// DOSIO:関数の準備
void dosio_init();
void dosio_term();
// ファイル操作
FILEH __stdcall file_open(LPCTSTR lpcszPath);
FILEH __stdcall file_open_rb(LPCTSTR lpcszPath);
FILEH __stdcall file_create(LPCTSTR lpcszPath);
long __stdcall file_seek(FILEH handle, long lPointer, int nMethod);
UINT __stdcall file_read(FILEH handle, LPVOID lpvData, UINT uLength);
UINT __stdcall file_write(FILEH handle, LPCVOID lpcvData, UINT uLength);
BRESULT __stdcall file_close(FILEH handle);
UINT __stdcall file_getsize(FILEH handle);
BRESULT __stdcall file_getdatetime(FILEH handle, PDOSDATE pDosDate, PDOSTIME pDosTime);
BRESULT __stdcall file_delete(LPCTSTR lpcszPath);
SINT16 __stdcall file_attr(LPCTSTR lpcszPath);
BRESULT __stdcall file_dircreate(LPCTSTR lpcszPath);
// カレントファイル操作
void __stdcall file_setcd(LPCTSTR lpcszExeName);
LPTSTR __stdcall file_getcd(LPCTSTR lpcszPath);
FILEH __stdcall file_open_c(LPCTSTR lpcszPath);
FILEH __stdcall file_open_rb_c(LPCTSTR lpcszPath);
FILEH __stdcall file_create_c(LPCTSTR lpcszPath);
BRESULT __stdcall file_delete_c(LPCTSTR lpcszPath);
SINT16 __stdcall file_attr_c(LPCTSTR lpcszPath);
#define file_cpyname(a, b, c) milstr_ncpy(a, b, c)
#define file_catname(a, b, c) milstr_ncat(a, b, c)
#define file_cmpname(a, b) milstr_cmp(a, b)
LPTSTR __stdcall file_getname(LPCTSTR lpcszPath);
void __stdcall file_cutname(LPTSTR lpszPath);
LPTSTR __stdcall file_getext(LPCTSTR lpcszPath);
void __stdcall file_cutext(LPTSTR lpszPath);
void __stdcall file_cutseparator(LPTSTR lpszPath);
void __stdcall file_setseparator(LPTSTR lpszPath, int nMaxLen);
#ifdef __cplusplus
}
#endif
#define file_createex(p, t) file_create(p)
#define file_createex_c(p, t) file_create_c(p)

195
nds/win32s/extrom.cpp Normal file
View File

@ -0,0 +1,195 @@
#include "compiler.h"
#include "parts.h"
#include "dosio.h"
#include "font.h"
#include "defipl.res"
ROMIMG __extromimage;
// ---- bios
static void loadbios(ROMIMG *pImg)
{
CopyMemory(pImg->bios1, defaultiplrom, sizeof(defaultiplrom));
CopyMemory(pImg->bios2, defaultiplrom, sizeof(defaultiplrom));
static const TCHAR s_iplx1[] = _T("IPLROM.X1");
FILEH fh = file_open_rb_c(s_iplx1);
if (fh != FILEH_INVALID)
{
file_read(fh, pImg->bios1, 0x1000);
file_close(fh);
}
static const TCHAR s_iplx1t[] = _T("IPLROM.X1T");
fh = file_open_rb_c(s_iplx1t);
if (fh != FILEH_INVALID)
{
file_read(fh, pImg->bios2, 0x8000);
file_close(fh);
}
}
// ---- font
static UINT32 fadrsx1t(UINT uJis)
{
static const UINT8 s_jis2x1t[64] =
{
0xff, 0xff, 0xff, 0xff, // 0x00
0xff, 0xff, 0xff, 0xff, // 0x08
0xff, 0xff, 0xff, 0xff, // 0x10
0xff, 0xff, 0xff, 0xff, // 0x18
0xff, 0x00, 0x02, 0x01, // 0x20
0xff, 0xff, 0xff, 0xff, // 0x28
0xff, 0x04, 0x06, 0x08, // 0x30
0xff, 0x05, 0x07, 0x09, // 0x38
0xff, 0x0a, 0x0c, 0x0e, // 0x40
0xff, 0x0b, 0x0d, 0x0f, // 0x48
0xff, 0x10, 0x12, 0x14, // 0x50
0xff, 0x11, 0x13, 0x15, // 0x58
0xff, 0x16, 0x18, 0x1a, // 0x60
0xff, 0x17, 0x19, 0x1b, // 0x68
0xff, 0x1c, 0x1e, 0x1d, // 0x70
0xff, 0xff, 0xff, 0xff, // 0x78
};
const UINT uAddr = s_jis2x1t[((uJis >> 9) & 0x3c) + ((uJis >> 5) & 3)];
if (uAddr & 0xc0)
{
return static_cast<UINT32>(-1);
}
UINT32 uRet = (uAddr << 12);
uRet += ((uJis & 0x700) << 1);
uRet += ((uJis & 0x01f) << 4);
return uRet;
}
static void knjcpy(ROMIMG *pImg, const UINT8 *pcSrc, UINT uFrom, UINT uTo)
{
for (UINT i=uFrom; i<uTo; i++)
{
const UINT h = i << 8;
for (UINT l=0x21; l<0x7f; l++)
{
const UINT uSjis = jis2sjis(h + l);
const UINT8 *p = 0;
if ((uSjis >= 0x8140) && (uSjis < 0x84c0))
{
p = pcSrc + 0x00000 + ((uSjis - 0x8140) << 5);
}
else if ((uSjis >= 0x8890) && (uSjis < 0xa000))
{
p = pcSrc + 0x07000 + ((uSjis - 0x8890) << 5);
}
else if ((uSjis >= 0xe040) && (uSjis < 0xeab0))
{
p = pcSrc + 0x35e00 + ((uSjis - 0xe040) << 5);
}
if (p)
{
UINT32 dwAddr = fadrsx1t(h + l);
if (dwAddr != static_cast<UINT32>(-1))
{
// ƒRƒs<C692>[‚·‚é
UINT8 *q = pImg->knjx1t + dwAddr;
for (UINT j=0; j<16; j++)
{
q[0] = p[0];
q[FONTX1T_LR] = p[1];
p += 2;
q += 1;
}
}
}
}
}
}
static void cnvx1t2x1(ROMIMG *img) {
UINT i;
UINT j;
UINT32 addr;
const UINT8 *src;
UINT8 *dst;
dst = img->knjx1 + 0x0100;
for (i=0x2100; i<0x2800; i+=0x100) {
for (j=0x20; j<0x80; j+=0x20) {
addr = fadrsx1t(i + j);
if (addr != (UINT32)-1) {
src = img->knjx1t + addr;
CopyMemory(dst, src, 0x200);
CopyMemory(dst + FONTX1_LR, src + FONTX1T_LR, 0x200);
}
dst += 0x200;
}
}
dst = img->knjx1 + 0x4000;
for (i=0x3000; i<0x5000; i+=0x100) {
for (j=0x20; j<0x80; j+=0x20) {
addr = fadrsx1t(i + j);
if (addr != (UINT32)-1) {
src = img->knjx1t + addr;
CopyMemory(dst, src, 0x200);
CopyMemory(dst + FONTX1_LR, src + FONTX1T_LR, 0x200);
}
dst += 0x200;
}
}
}
static void loadfont(ROMIMG *pImg)
{
static const TCHAR s_font0808[] = _T("FNT0808.X1");
FILEH fh = file_open_rb_c(s_font0808);
if (fh != FILEH_INVALID)
{
file_read(fh, pImg->ank, 0x800);
file_close(fh);
}
static const TCHAR s_font0816[] = _T("FNT0816.X1");
fh = file_open_rb_c(s_font0816);
if (fh != FILEH_INVALID)
{
file_read(fh, pImg->txt, 0x1000);
file_close(fh);
}
UINT8 *pWork = new UINT8 [306176];
if (pWork)
{
static const OEMCHAR s_font1616[] = OEMTEXT("FNT1616.X1");
fh = file_open_rb_c(s_font1616);
if (fh != FILEH_INVALID)
{
file_read(fh, pWork, 306176);
file_close(fh);
knjcpy(pImg, pWork, 0x21, 0x50);
knjcpy(pImg, pWork, 0x50, 0x78);
CopyMemory(pImg->knjx1t + 0x03000, pImg->knjx1t + 0x02000, 0x1000);
CopyMemory(pImg->knjx1t + 0x23000, pImg->knjx1t + 0x22000, 0x1000);
CopyMemory(pImg->knjx1t + 0x1f000, pImg->knjx1t + 0x1e000, 0x1000);
CopyMemory(pImg->knjx1t + 0x3f000, pImg->knjx1t + 0x3e000, 0x1000);
cnvx1t2x1(pImg);
}
delete[] pWork;
}
}
// ----
void extrom_initialize()
{
loadbios(&__extromimage);
loadfont(&__extromimage);
}

25
nds/win32s/extrom.h Normal file
View File

@ -0,0 +1,25 @@
typedef struct
{
UINT8 bios1[0x1000];
UINT8 bios2[0x8000];
UINT8 ank[0x0800];
UINT8 txt[0x1000];
UINT8 knjx1[0x20000];
UINT8 knjx1t[0x40000];
} ROMIMG;
#ifdef __cplusplus
extern "C"
{
#endif
extern ROMIMG __extromimage;
#ifdef __cplusplus
}
#endif
void extrom_initialize();

34
nds/win32s/libnds.h Normal file
View File

@ -0,0 +1,34 @@
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
#include "ndsreg.h"
#include "ndsmem.h"
#include "ndssys.h"
#include "ndsirq.h"
#include "ndsswi.h"
#include "ndsdma.h"
#include "ndsvideo.h"
#include "ndssound.h"
#include "ndsinput.h"
#include "ndspower.h"
#include "ndsconsole.h"
#include "ndsipc.h"
#include "ndstouch.h"
#if defined(__cplusplus)
extern "C"
{
#endif /* defined(__cplusplus) */
int nds9main();
int nds7main();
#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */

17
nds/win32s/ndsconsole.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "compiler.h"
#include "libnds.h"
void consoleInitDefault(u16* map, u16* charBase, u8 bitDepth)
{
}
void iprintf(const char *lpcszFormat, ...)
{
va_list ap;
va_start(ap, lpcszFormat);
vprintf(lpcszFormat, ap);
va_end(ap);
}

4
nds/win32s/ndsconsole.h Normal file
View File

@ -0,0 +1,4 @@
void consoleInitDefault(u16* map, u16* charBase, u8 bitDepth);
void iprintf(const char *lpcszFormat, ...);

8
nds/win32s/ndscore.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "compiler.h"
void ndscore_timer3init() { }
void ndscore_timer3int() { }
void ndscore_sleep(unsigned int uCount) { Sleep(uCount); }
void ndscore_rest(unsigned int uCount) { Sleep(uCount / 512); }
unsigned int ndscore_gettick() { return GetTickCount(); }

16
nds/win32s/ndscore.h Normal file
View File

@ -0,0 +1,16 @@
#if defined(__cplusplus)
extern "C"
{
#endif // defined(__cplusplus)
void ndscore_timer3init();
void ndscore_timer3int();
void ndscore_sleep(unsigned int uCount);
void ndscore_rest(unsigned int uCount);
unsigned int ndscore_gettick();
#if defined(__cplusplus)
}
#endif // defined(__cplusplus)

39
nds/win32s/ndsdma.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "compiler.h"
#include "libnds.h"
static int checkMemory(LPCVOID lpcvDst, LPCVOID lpcvSrc, int nSize)
{
const UINT_PTR uDst = reinterpret_cast<UINT_PTR>(lpcvDst);
const UINT_PTR uSrc = reinterpret_cast<UINT_PTR>(lpcvSrc);
int nRet = 0;
if (uDst <= uSrc)
{
nRet = (uDst + nSize) - uSrc;
nRet = max(nRet, 0);
}
return nRet;
}
void dmaCopy(LPCVOID lpcvSrc, LPVOID lpvDst, int nSize)
{
int nLength = checkMemory(g_vram, lpvDst, sizeof(g_vram));
if (nLength)
{
nSize = min(nLength, nSize);
CopyMemory(lpvDst, lpcvSrc, nLength);
CNdsRegUpdate::getInstance().set(RT_VRAM);
return;
}
nLength = checkMemory(g_pal, lpvDst, sizeof(g_pal));
if (nLength)
{
nSize = min(nLength, nSize);
CopyMemory(lpvDst, lpcvSrc, nLength);
CNdsRegUpdate::getInstance().set(RT_PALETTE);
return;
}
}

3
nds/win32s/ndsdma.h Normal file
View File

@ -0,0 +1,3 @@
void dmaCopy(LPCVOID lpvSrc, LPVOID lpvDst, int nSize);

63
nds/win32s/ndsinput.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "compiler.h"
#include "libnds.h"
struct tagKeyBind
{
UINT16 wKey;
UINT16 wBit;
};
static const tagKeyBind keybind[10] =
{
{'X', KEY_A},
{'Z', KEY_B},
{'A', KEY_SELECT},
{'S', KEY_START},
{VK_RIGHT, KEY_RIGHT},
{VK_LEFT, KEY_LEFT},
{VK_UP, KEY_UP},
{VK_DOWN, KEY_DOWN},
{'W', KEY_R},
{'Q', KEY_L},
};
UINT16 g_wKeyReg;
// ----
void ndsinput_initialize()
{
REG_KEYINPUT = 0xffff;
}
void ndsinput_keydown(UINT16 wKey)
{
const tagKeyBind *pKb = keybind;
const tagKeyBind *pKbEnd = keybind + NELEMENTS(keybind);
do
{
if (wKey == pKb->wKey)
{
REG_KEYINPUT &= ~pKb->wBit;
break;
}
pKb++;
} while(pKb < pKbEnd);
}
void ndsinput_keyup(UINT16 wKey)
{
const tagKeyBind *pKb = keybind;
const tagKeyBind *pKbEnd = keybind + NELEMENTS(keybind);
do
{
if (wKey == pKb->wKey)
{
REG_KEYINPUT |= pKb->wBit;
break;
}
pKb++;
} while(pKb < pKbEnd);
}

28
nds/win32s/ndsinput.h Normal file
View File

@ -0,0 +1,28 @@
enum
{
KEY_A = 1 << 0,
KEY_B = 1 << 1,
KEY_SELECT = 1 << 2,
KEY_START = 1 << 3,
KEY_RIGHT = 1 << 4,
KEY_LEFT = 1 << 5,
KEY_UP = 1 << 6,
KEY_DOWN = 1 << 7,
KEY_R = 1 << 8,
KEY_L = 1 << 9,
KEY_X = 1 << 10,
KEY_Y = 1 << 11,
KEY_TOUCH = 1 << 12,
KEY_LID = 1 << 13,
};
extern UINT16 g_wKeyReg;
#define REG_KEYINPUT g_wKeyReg
void ndsinput_initialize();
void ndsinput_keydown(UINT16 wKey);
void ndsinput_keyup(UINT16 wKey);

6
nds/win32s/ndsipc.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "compiler.h"
#include "libnds.h"
UINT8 g_sIPC[0x1000];

75
nds/win32s/ndsipc.h Normal file
View File

@ -0,0 +1,75 @@
struct tagTransferSoundData
{
const void *data;
UINT32 len;
UINT32 rate;
UINT8 vol;
UINT8 pan;
UINT8 format;
UINT8 PADDING;
};
typedef struct tagTransferSoundData TransferSoundData;
typedef struct tagTransferSoundData *pTransferSoundData;
struct tagTransferSound
{
TransferSoundData data[16];
UINT8 count;
UINT8 PADDING[3];
};
typedef struct tagTransferSound TransferSound;
typedef struct tagTransferSound *pTransferSound;
struct tagTransferRegion
{
SINT16 touchX, touchY; // TSC X, Y
SINT16 touchXpx, touchYpx; // TSC X, Y pixel values
SINT16 touchZ1, touchZ2; // TSC x-panel measurements
UINT16 tdiode1, tdiode2; // TSC temperature diodes
UINT32 temperature; // TSC computed temperature
UINT16 buttons; // X, Y, /PENIRQ buttons
union
{
UINT8 curtime[8]; // current time response from RTC
struct
{
UINT8 command;
UINT8 year; //add 2000 to get 4 digit year
UINT8 month; //1 to 12
UINT8 day; //1 to (days in month)
UINT8 weekday; // day of week
UINT8 hours; //0 to 11 for AM, 52 to 63 for PM
UINT8 minutes; //0 to 59
UINT8 seconds; //0 to 59
} rtc;
} time;
SINT32 unixTime;
uint16 battery; // battery life ?? hopefully. :)
uint16 aux; // i have no idea...
pTransferSound soundData;
UINT32 mailAddr;
UINT32 mailData;
UINT8 mailRead;
UINT8 mailBusy;
UINT32 mailSize;
};
typedef struct tagTransferRegion TransferRegion;
typedef struct tagTransferRegion *pTransferRegion;
extern UINT8 g_sIPC[0x1000];
static TransferRegion *getIPC() { return reinterpret_cast<TransferRegion *>(g_sIPC); }
#define IPC getIPC()

16
nds/win32s/ndsirq.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "compiler.h"
#include "libnds.h"
void irqInit()
{
}
void irqSet(tagNdsIrq nMask, void (*handler)())
{
}
void irqEnable(uint32 uMask)
{
}

33
nds/win32s/ndsirq.h Normal file
View File

@ -0,0 +1,33 @@
enum tagNdsIrq
{
IRQ_VBLANK = 1 << 0,
IRQ_TIMER3 = 1 << 6,
IRQ_ALL = (~0)
};
// Power management registers
#define PM_CONTROL_REG 0
#define PM_BATTERY_REG 1
#define PM_AMPLIFIER_REG 2
#define PM_READ_REGISTER (1 << 7)
// PM control register bits - power control
#define PM_SOUND_AMP (1 << 0)
#define PM_SOUND_MUTE (1 << 1)
#define PM_BACKLIGHT_BOTTOM (1 << 2)
#define PM_BACKLIGHT_TOP (1 << 3)
#define PM_SYSTEM_PWR (1 << 6)
#define PM_POWER_DOWN (1 << 6)
void irqInit();
void irqSet(tagNdsIrq nMask, void (*handler)());
void irqEnable(uint32 uMask);
static inline void initClockIRQ() { }
// Read/write a power management register
static inline int writePowerManagement(int reg, int command) { return 0; }
static inline int readPowerManagement(int reg) { return 0; }

5
nds/win32s/ndsmem.cpp Normal file
View File

@ -0,0 +1,5 @@
#include "compiler.h"
#include "libnds.h"
unsigned char __ipcbase[0x1000];

5
nds/win32s/ndsmem.h Normal file
View File

@ -0,0 +1,5 @@
extern unsigned char __ipcbase[0x1000];
#define IPCBASE __ipcbase

16
nds/win32s/ndspower.h Normal file
View File

@ -0,0 +1,16 @@
#define POWER_LCD (1 << 0)
#define POWER_2D_A (1 << 1)
#define POWER_MATRIX (1 << 2)
#define POWER_3D_CORE (1 << 3)
#define POWER_2D_B (1 << 9)
#define POWER_SWAP_LCDS (1 << 15)
#define POWER_ALL_2D (POWER_LCD |POWER_2D_A |POWER_2D_B)
#define POWER_ALL (POWER_ALL_2D | POWER_3D_CORE | POWER_MATRIX)
#define POWER_SOUND (1 << 0)
#define POWER_UNKNOWN (1 << 1)
#define powerON(on) do { } while(0)

26
nds/win32s/ndsreg.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "compiler.h"
#include "libnds.h"
CNdsRegUpdate CNdsRegUpdate::m_self;
static bool s_bUpdate[RT_MAX];
void CNdsReg8Base::set(UINT8 cValue, tagRegType nType)
{
m_cValue = cValue;
CNdsRegUpdate::getInstance().set(nType);
}
void CNdsReg16Base::set(UINT16 wValue, tagRegType nType)
{
m_wValue = wValue;
CNdsRegUpdate::getInstance().set(nType);
}
void CNdsReg32Base::set(UINT32 dwValue, tagRegType nType)
{
m_dwValue = dwValue;
CNdsRegUpdate::getInstance().set(nType);
}

101
nds/win32s/ndsreg.h Normal file
View File

@ -0,0 +1,101 @@
enum tagRegType
{
RT_SCREEN = 0,
RT_VRAM = 0,
RT_PALETTE = 0,
RT_MAX = 1
};
// ----
class CNdsRegUpdate
{
public:
static CNdsRegUpdate& getInstance() { return m_self; }
CNdsRegUpdate()
{
ZeroMemory(m_bUpdate, sizeof(m_bUpdate));
}
void set(tagRegType nType) { m_bUpdate[nType] = true; }
void reset(tagRegType nType) { m_bUpdate[nType] = false; }
bool get(tagRegType nType) const { return m_bUpdate[nType]; }
private:
static CNdsRegUpdate m_self;
bool m_bUpdate[RT_MAX];
};
class CNdsReg8Base
{
public:
operator UINT8() const { return m_cValue; }
void set(UINT8 cValue, tagRegType nType);
private:
UINT8 m_cValue;
};
class CNdsReg16Base
{
public:
operator UINT16() const { return m_wValue; }
void set(UINT16 wValue, tagRegType nType);
private:
UINT16 m_wValue;
};
class CNdsReg32Base
{
public:
operator UINT32() const { return m_dwValue; }
void set(UINT32 dwValue, tagRegType nType);
private:
UINT32 m_dwValue;
};
// ----
template<tagRegType T>
class CNdsReg8 : public CNdsReg8Base
{
public:
const CNdsReg8<T>& operator=(UINT8 cValue)
{
set(wValue, T);
return *this:
}
};
template<tagRegType T>
class CNdsReg16 : public CNdsReg16Base
{
public:
const CNdsReg16<T>& operator=(UINT16 wValue)
{
set(wValue, T);
return *this;
}
};
template<tagRegType T>
class CNdsReg32 : public CNdsReg32Base
{
public:
const CNdsReg32<T>& operator=(UINT32 dwValue)
{
set(dwValue, T);
return *this;
}
};
#define CRegScreen16 CNdsReg16<RT_SCREEN>
#define CRegScreen32 CNdsReg32<RT_SCREEN>
#define CRegVram16 CNdsReg16<RT_VRAM>
#define CRegPalette16 CNdsReg16<RT_PALETTE>

5
nds/win32s/ndssound.cpp Normal file
View File

@ -0,0 +1,5 @@
#include "compiler.h"
#include "libnds.h"
tagNdsSoundReg s_ndssound;

43
nds/win32s/ndssound.h Normal file
View File

@ -0,0 +1,43 @@
struct tagNdsSoundChannelReg
{
UINT32 uControl;
UINT32 uSource;
UINT16 wTimer;
UINT16 wRepeat;
UINT32 uLength;
};
struct tagNdsSoundReg
{
UINT16 uControl;
tagNdsSoundChannelReg ch[16];
};
extern tagNdsSoundReg s_ndssound;
#define SCHANNEL_CR(n) s_ndssound.ch[(n)].uControl
// #define SCHANNEL_VOL(n) (*(vuint8*)(0x04000400 + ((n)<<4)))
// #define SCHANNEL_PAN(n) (*(vuint8*)(0x04000402 + ((n)<<4)))
#define SCHANNEL_SOURCE(n) s_ndssound.ch[(n)].uSource
#define SCHANNEL_TIMER(n) s_ndssound.ch[(n)].wTimer
#define SCHANNEL_REPEAT_POINT(n) s_ndssound.ch[(n)].wRepeat
#define SCHANNEL_LENGTH(n) s_ndssound.ch[(n)].uLength
#define SOUND_CR s_ndssound.uControl
#define SOUND_VOL(n) (n)
#define SOUND_FREQ(n) ((-0x1000000 / (n)))
#define SOUND_ENABLE (1 << 15)
#define SOUND_REPEAT (1 << 27)
#define SOUND_ONE_SHOT (1 << 28)
#define SOUND_FORMAT_16BIT (1 << 29)
#define SOUND_FORMAT_8BIT (0 << 29)
#define SOUND_FORMAT_PSG (3 << 29)
#define SOUND_FORMAT_ADPCM (2 << 29)
#define SOUND_16BIT (1 << 29)
#define SOUND_8BIT (0)
#define SOUND_PAN(n) ((n) << 16)
#define SCHANNEL_ENABLE (1 << 31)

10
nds/win32s/ndsswi.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "compiler.h"
#include "libnds.h"
void swiWaitForVBlank(void)
{
ndssys_task();
Sleep(100);
}

3
nds/win32s/ndsswi.h Normal file
View File

@ -0,0 +1,3 @@
void swiWaitForVBlank(void);

141
nds/win32s/ndssys.cpp Normal file
View File

@ -0,0 +1,141 @@
#include "compiler.h"
#include "libnds.h"
#include "dosio.h"
bool __nds_avail;
HWND __nds_hWnd;
static const TCHAR s_szClassName[] = _T("Windebug-NDS");
static const TCHAR s_szCaptionName[] = _T("NDS-Window");
static LRESULT CALLBACK __NdsProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
ndsvideo_update();
EndPaint(hWnd, &ps);
}
break;
case WM_KEYDOWN:
ndsinput_keydown(static_cast<UINT16>(LOWORD(wParam)));
break;
case WM_KEYUP:
ndsinput_keyup(static_cast<UINT16>(LOWORD(wParam)));
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
// ----
int _tmain(int argc, TCHAR **argv, char **envp)
{
HWND hWnd = FindWindow(s_szClassName, NULL);
if (hWnd != NULL)
{
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
return 0;
}
TCHAR szModuleFile[MAX_PATH];
GetModuleFileName(NULL, szModuleFile, NELEMENTS(szModuleFile));
dosio_init();
file_setcd(szModuleFile);
HINSTANCE hInstance = reinterpret_cast<HINSTANCE>(GetWindowLong(HWND_DESKTOP, GWL_HINSTANCE));
WNDCLASS wc;
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_BYTEALIGNCLIENT | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = __NdsProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
wc.lpszMenuName = NULL;
wc.lpszClassName = s_szClassName;
if (!RegisterClass(&wc))
{
return 0;
}
hWnd = CreateWindow(s_szClassName, s_szCaptionName,
WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION |
WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 160,
NULL, NULL, hInstance, NULL);
__nds_hWnd = hWnd;
if (hWnd == NULL)
{
return -1;
}
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
ndsinput_initialize();
__nds_avail = true;
do
{
if (!ndsvideo_initialize(hWnd))
{
DestroyWindow(hWnd);
break;
}
nds9main();
} while(0);
// ndsvideo_deinitialize();
dosio_term();
return 0;
}
bool ndssys_task()
{
if (__nds_avail)
{
CNdsRegUpdate &reg = CNdsRegUpdate::getInstance();
if (reg.get(RT_SCREEN))
{
ndsvideo_bufferupdate();
reg.reset(RT_SCREEN);
}
MSG msg;
while(PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, 0, 0))
{
__nds_avail = false;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return __nds_avail;
}

9
nds/win32s/ndssys.h Normal file
View File

@ -0,0 +1,9 @@
extern bool __nds_avail;
extern HWND __nds_hWnd;
bool ndssys_task();
static inline void readUserSettings() { }

13
nds/win32s/ndstouch.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "compiler.h"
#include "libnds.h"
UINT16 g_wRegKeyXY = 0;
touchPosition touchReadXY()
{
touchPosition pos;
ZeroMemory(&pos, sizeof(pos));
return pos;
}

17
nds/win32s/ndstouch.h Normal file
View File

@ -0,0 +1,17 @@
struct tagTouchPosition
{
SINT16 x;
SINT16 y;
SINT16 px;
SINT16 py;
SINT16 z1;
SINT16 z2;
};
typedef struct tagTouchPosition touchPosition;
extern UINT16 g_wRegKeyXY;
#define REG_KEYXY g_wRegKeyXY;
touchPosition touchReadXY();

516
nds/win32s/ndsvideo.cpp Normal file
View File

@ -0,0 +1,516 @@
#include "compiler.h"
#include "libnds.h"
#include <ddraw.h>
#pragma comment(lib, "ddraw.lib")
#pragma comment(lib, "dxguid.lib")
#define NDSVIDEO_WIDTH SCREEN_WIDTH
#define NDSVIDEO_HEIGHT SCREEN_HEIGHT
CRegScreen16 g_bgpalettesub;
CRegVram16 g_vram[0x80000];
CRegPalette16 g_pal[256];
CRegPalette16 g_palsub[256];
tagNdsBgReg g_bg[4];
tagNdsBgReg g_subbg[4];
static UINT s_uMode;
void videoSetMode(uint32 mode)
{
s_uMode = mode;
}
void videoSetModeSub(uint32 mode)
{
}
uint32 vramSetMainBanks(VRAM_A_TYPE a, VRAM_B_TYPE b, VRAM_C_TYPE c, VRAM_D_TYPE d)
{
return 0;
}
// ----
struct tagDDraw
{
HWND hWnd;
UINT uBitColor;
LPDIRECTDRAW pDDraw;
LPDIRECTDRAW2 pDDraw2;
LPDIRECTDRAWSURFACE pPrimSurf;
LPDIRECTDRAWSURFACE pBackSurf;
LPDIRECTDRAWCLIPPER pClipper;
};
union tagPalTable
{
UINT16 pal16[0x8000];
UINT32 pal32[0x8000];
};
struct tagVideoParam
{
tagPalTable p;
};
static tagDDraw s_ddraw;
static tagVideoParam *s_pVideo;
static void setwindowsize(HWND hWnd, int nWidth, int nHeight)
{
RECT rcWorkArea;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0);
const int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
const int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
int nCount = 2;
do
{
RECT rcWindow;
GetWindowRect(hWnd, &rcWindow);
RECT rcClient;
GetClientRect(hWnd, &rcClient);
int nNewWidth = nWidth;
nNewWidth += rcWindow.right - rcWindow.left;
nNewWidth -= rcClient.right - rcClient.left;
int nNewHeight = nHeight;
nNewHeight += rcWindow.bottom - rcWindow.top;
nNewHeight -= rcClient.bottom - rcClient.top;
int nPosX = rcWindow.left;
if (nScreenWidth < nNewWidth)
{
nPosX = (nScreenWidth - nNewWidth) / 2;
}
else
{
if ((nPosX + nNewWidth) > rcWorkArea.right)
{
nPosX = rcWorkArea.right - nNewWidth;
}
if (nPosX < rcWorkArea.left)
{
nPosX = rcWorkArea.left;
}
}
int nPosY = rcWindow.top;
if (nScreenHeight < nNewHeight)
{
nPosY = (nScreenHeight - nNewHeight) / 2;
}
else
{
if ((nPosY + nNewHeight) > rcWorkArea.bottom)
{
nPosY = rcWorkArea.bottom - nNewHeight;
}
if (nPosY < rcWorkArea.top)
{
nPosY = rcWorkArea.top;
}
}
MoveWindow(hWnd, nPosX, nPosY, nNewWidth, nNewHeight, TRUE);
} while(--nCount);
}
static void initPal16(tagPalTable &pal, const DDPIXELFORMAT &ddpf)
{
UINT32 bmask = ddpf.dwBBitMask;
UINT b16r = 0;
while((!(bmask & 0x80)) && (b16r < 32))
{
bmask <<= 1;
b16r++;
}
UINT32 rmask = ddpf.dwRBitMask;
UINT r16l = 0;
while((rmask & 0xffffff00) && (r16l < 32))
{
rmask >>= 1;
r16l++;
}
UINT32 gmask = ddpf.dwGBitMask;
UINT g16l = 0;
while((gmask & 0xffffff00) && (g16l < 32))
{
gmask >>= 1;
g16l++;
}
// …で、全パレット作る(ぉ
for (UINT i=0; i<0x8000; i++)
{
UINT r = (i << 3) & 0xf8;
UINT g = (i >> 2) & 0xf8;
UINT b = (i >> 7) & 0xf8;
r = (r + (r >> 5)) & rmask;
g = (g + (g >> 5)) & gmask;
b = (b + (b >> 5)) & bmask;
pal.pal16[i] = (r << r16l) + (g << g16l) + (b >> b16r);
}
}
static void initPal32(tagPalTable &pal)
{
// …やっぱりパレット作る
for (UINT i=0; i<0x8000; i++)
{
UINT r = (i << 3) & 0xf8;
UINT g = (i >> 2) & 0xf8;
UINT b = (i >> 7) & 0xf8;
r = (r + (r >> 5));
g = (g + (g >> 5));
b = (b + (b >> 5));
pal.pal32[i] = (r << 16) + (g << 8) + b;
}
}
// ----
static void drawext_16(const tagVideoParam &video, tagNdsBgReg &bg, const DDSURFACEDESC &dsd)
{
// 先にスタックにつっこんどいて…
UINT16 pal[256];
for (int i=0; i<256; i++)
{
pal[i] = video.p.pal16[g_pal[i] & 0x7fff];
}
UINT uWidth = 0;
UINT uHeight = 0;
switch((bg.cr >> 14) & 3)
{
case BG_RS_16x16 >> 14:
uWidth = 128;
uHeight = 128;
break;
case BG_RS_32x32 >> 14:
uWidth = 256;
uHeight = 256;
break;
case BG_RS_64x64 >> 14:
uWidth = 512;
uHeight = 256;
break;
case BG_RS_128x128 >> 14:
uWidth = 512;
uHeight = 512;
break;
}
UINT uAlign = uWidth;
uWidth = min(uWidth, NDSVIDEO_WIDTH);
uHeight = min(uHeight, NDSVIDEO_HEIGHT);
const UINT8 *p = reinterpret_cast<UINT8 *>(g_vram);
UINT8 *q = reinterpret_cast<UINT8 *>(dsd.lpSurface);
for (UINT y=0; y<uHeight; y++)
{
for (UINT x=0; x<uWidth; x++)
{
(reinterpret_cast<UINT16 *>(q))[x] = pal[p[x]];
}
p += uAlign;
q += dsd.lPitch;
}
}
static void drawext_32(const tagVideoParam &video, tagNdsBgReg &bg, const DDSURFACEDESC &dsd)
{
// 先にスタックにつっこんどいて…
UINT32 pal[256];
for (int i=0; i<256; i++)
{
pal[i] = video.p.pal32[g_pal[i] & 0x7fff];
}
UINT uWidth = 0;
UINT uHeight = 0;
switch((bg.cr >> 14) & 3)
{
case BG_RS_16x16 >> 14:
uWidth = 128;
uHeight = 128;
break;
case BG_RS_32x32 >> 14:
uWidth = 256;
uHeight = 256;
break;
case BG_RS_64x64 >> 14:
uWidth = 512;
uHeight = 256;
break;
case BG_RS_128x128 >> 14:
uWidth = 512;
uHeight = 512;
break;
}
UINT uAlign = uWidth;
uWidth = min(uWidth, NDSVIDEO_WIDTH);
uHeight = min(uHeight, NDSVIDEO_HEIGHT);
const UINT8 *p = reinterpret_cast<UINT8 *>(g_vram);
UINT8 *q = reinterpret_cast<UINT8 *>(dsd.lpSurface);
for (UINT y=0; y<uHeight; y++)
{
for (UINT x=0; x<uWidth; x++)
{
(reinterpret_cast<UINT32 *>(q))[x] = pal[p[x]];
}
p += uAlign;
q += dsd.lPitch;
}
}
// ----
static void mode5_16(const tagVideoParam &video, const DDSURFACEDESC &dsd)
{
drawext_16(video, g_bg[3], dsd);
}
static void mode5_32(const tagVideoParam &video, const DDSURFACEDESC &dsd)
{
drawext_32(video, g_bg[3], dsd);
}
// ----
typedef void (*DRAWFN)(const tagVideoParam &video, const DDSURFACEDESC &dsd);
struct tagNdsDraw
{
DRAWFN draw16;
DRAWFN draw32;
};
static const tagNdsDraw ndsdraw[6] =
{
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{0, 0},
{mode5_16, mode5_32},
};
void ndsvideo_bufferupdate()
{
tagDDraw &ddraw = s_ddraw;
if (!ddraw.pBackSurf)
{
return;
}
const UINT uMode = s_uMode & 0x0f;
if (uMode >= NELEMENTS(ndsdraw))
{
return;
}
const tagNdsDraw &draw = ndsdraw[uMode];
DRAWFN fn = 0;
if (ddraw.uBitColor == 16)
{
fn = draw.draw16;
}
else if (ddraw.uBitColor == 32)
{
fn = draw.draw32;
}
if (!fn)
{
return;
}
DDSURFACEDESC dsd;
ZeroMemory(&dsd, sizeof(dsd));
dsd.dwSize = sizeof(dsd);
HRESULT hResult = ddraw.pBackSurf->Lock(NULL, &dsd, DDLOCK_WAIT, NULL);
if (hResult != DD_OK)
{
return;
}
(*fn)(*s_pVideo, dsd);
ddraw.pBackSurf->Unlock(NULL);
ndsvideo_update();
}
// ----
static bool _initialize(HWND hWnd)
{
DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
dwStyle |= WS_SYSMENU | WS_CAPTION;
dwStyle &= ~WS_POPUP;
dwExStyle &= ~WS_EX_TOPMOST;
SetWindowLong(hWnd, GWL_STYLE, dwStyle);
SetWindowLong(hWnd, GWL_EXSTYLE, dwExStyle);
setwindowsize(hWnd, NDSVIDEO_WIDTH, NDSVIDEO_HEIGHT);
tagVideoParam *pVideo = new tagVideoParam;
s_pVideo = pVideo;
if (!pVideo)
{
return false;
}
ZeroMemory(pVideo, sizeof(*pVideo));
tagDDraw &ddraw = s_ddraw;
if (DirectDrawCreate(NULL, &ddraw.pDDraw, NULL) != DD_OK)
{
return false;
}
LPDIRECTDRAW2 pDDraw2;
ddraw.pDDraw->QueryInterface(IID_IDirectDraw2, (void **)&pDDraw2);
ddraw.pDDraw2 = pDDraw2;
pDDraw2->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if (pDDraw2->CreateSurface(&ddsd, &ddraw.pPrimSurf, NULL) != DD_OK)
{
return false;
}
pDDraw2->CreateClipper(0, &ddraw.pClipper, NULL);
ddraw.pClipper->SetHWnd(0, hWnd);
ddraw.pPrimSurf->SetClipper(ddraw.pClipper);
DDPIXELFORMAT ddpf;
ZeroMemory(&ddpf, sizeof(ddpf));
ddpf.dwSize = sizeof(DDPIXELFORMAT);
if (ddraw.pPrimSurf->GetPixelFormat(&ddpf) != DD_OK)
{
return false;
}
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = NDSVIDEO_WIDTH;
ddsd.dwHeight = NDSVIDEO_HEIGHT;
if (pDDraw2->CreateSurface(&ddsd, &ddraw.pBackSurf, NULL) != DD_OK)
{
return false;
}
UINT uBitColor = ddpf.dwRGBBitCount;
if (uBitColor == 16)
{
initPal16(pVideo->p, ddpf);
}
else if (uBitColor == 32)
{
initPal32(pVideo->p);
}
else
{
return false;
}
ddraw.hWnd = hWnd;
ddraw.uBitColor = uBitColor;
return true;
}
static void _deinitialize()
{
tagDDraw &ddraw = s_ddraw;
if (ddraw.pBackSurf)
{
ddraw.pBackSurf->Release();
}
if (ddraw.pClipper)
{
ddraw.pClipper->Release();
}
if (ddraw.pPrimSurf)
{
ddraw.pPrimSurf->Release();
}
if (ddraw.pDDraw2)
{
ddraw.pDDraw2->Release();
}
if (ddraw.pDDraw)
{
ddraw.pDDraw->Release();
}
ZeroMemory(&ddraw, sizeof(ddraw));
if (s_pVideo)
{
delete s_pVideo;
s_pVideo = 0;
}
}
bool ndsvideo_initialize(HWND hWnd)
{
bool bResult = _initialize(hWnd);
if (!bResult)
{
_deinitialize();
}
return bResult;
}
void ndsvideo_deinitialize()
{
_deinitialize();
}
void ndsvideo_update()
{
tagDDraw &ddraw = s_ddraw;
if (ddraw.pBackSurf)
{
POINT ptClip;
ptClip.x = 0;
ptClip.y = 0;
ClientToScreen(ddraw.hWnd, &ptClip);
RECT rtDst;
rtDst.left = ptClip.x;
rtDst.top = ptClip.y;
rtDst.right = ptClip.x + NDSVIDEO_WIDTH;
rtDst.bottom = ptClip.y + NDSVIDEO_HEIGHT;
RECT rtSrc;
rtSrc.left = 0;
rtSrc.top = 0;
rtSrc.right = NDSVIDEO_WIDTH;
rtSrc.bottom = NDSVIDEO_HEIGHT;
HRESULT hResult = ddraw.pPrimSurf->Blt(&rtDst, ddraw.pBackSurf, &rtSrc, DDBLT_WAIT, NULL);
if (hResult == DDERR_SURFACELOST)
{
ddraw.pBackSurf->Restore();
ddraw.pPrimSurf->Restore();
ddraw.pPrimSurf->Blt(&rtDst, ddraw.pBackSurf, &rtSrc, DDBLT_WAIT, NULL);
}
}
}

189
nds/win32s/ndsvideo.h Normal file
View File

@ -0,0 +1,189 @@
#define RGB15(r,g,b) ((r) | ((g) << 5) | ((b) << 10))
#define VRAM_OFFSET(n) ((n)<<3)
#define SCREEN_HEIGHT 192
#define SCREEN_WIDTH 256
enum VRAM_A_TYPE
{
VRAM_A_LCD = 0,
VRAM_A_MAIN_BG = 1,
VRAM_A_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0),
VRAM_A_MAIN_BG_0x06020000 = 1 | VRAM_OFFSET(1),
VRAM_A_MAIN_BG_0x06040000 = 1 | VRAM_OFFSET(2),
VRAM_A_MAIN_BG_0x06060000 = 1 | VRAM_OFFSET(3),
VRAM_A_MAIN_SPRITE = 2,
VRAM_A_MAIN_SPRITE_0x06400000 = 2,
VRAM_A_MAIN_SPRITE_0x06420000 = 2 | VRAM_OFFSET(1),
VRAM_A_TEXTURE = 3,
VRAM_A_TEXTURE_SLOT0 = 3 | VRAM_OFFSET(0),
VRAM_A_TEXTURE_SLOT1 = 3 | VRAM_OFFSET(1),
VRAM_A_TEXTURE_SLOT2 = 3 | VRAM_OFFSET(2),
VRAM_A_TEXTURE_SLOT3 = 3 | VRAM_OFFSET(3)
};
enum VRAM_B_TYPE
{
VRAM_B_LCD = 0,
VRAM_B_MAIN_BG = 1 | VRAM_OFFSET(1),
VRAM_B_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0),
VRAM_B_MAIN_BG_0x06020000 = 1 | VRAM_OFFSET(1),
VRAM_B_MAIN_BG_0x06040000 = 1 | VRAM_OFFSET(2),
VRAM_B_MAIN_BG_0x06060000 = 1 | VRAM_OFFSET(3),
VRAM_B_MAIN_SPRITE = 2 | VRAM_OFFSET(1),
VRAM_B_MAIN_SPRITE_0x06400000 = 2,
VRAM_B_MAIN_SPRITE_0x06420000 = 2 | VRAM_OFFSET(1),
VRAM_B_TEXTURE = 3 | VRAM_OFFSET(1),
VRAM_B_TEXTURE_SLOT0 = 3 | VRAM_OFFSET(0),
VRAM_B_TEXTURE_SLOT1 = 3 | VRAM_OFFSET(1),
VRAM_B_TEXTURE_SLOT2 = 3 | VRAM_OFFSET(2),
VRAM_B_TEXTURE_SLOT3 = 3 | VRAM_OFFSET(3)
};
enum VRAM_C_TYPE
{
VRAM_C_LCD = 0,
VRAM_C_MAIN_BG = 1 | VRAM_OFFSET(2),
VRAM_C_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0),
VRAM_C_MAIN_BG_0x06020000 = 1 | VRAM_OFFSET(1),
VRAM_C_MAIN_BG_0x06040000 = 1 | VRAM_OFFSET(2),
VRAM_C_MAIN_BG_0x06060000 = 1 | VRAM_OFFSET(3),
VRAM_C_ARM7 = 2,
VRAM_C_ARM7_0x06000000 = 2,
VRAM_C_ARM7_0x06020000 = 2 | VRAM_OFFSET(1),
VRAM_C_SUB_BG = 4,
VRAM_C_SUB_BG_0x06200000 = 4 | VRAM_OFFSET(0),
VRAM_C_SUB_BG_0x06220000 = 4 | VRAM_OFFSET(1),
VRAM_C_SUB_BG_0x06240000 = 4 | VRAM_OFFSET(2),
VRAM_C_SUB_BG_0x06260000 = 4 | VRAM_OFFSET(3),
VRAM_C_TEXTURE = 3 | VRAM_OFFSET(2),
VRAM_C_TEXTURE_SLOT0 = 3 | VRAM_OFFSET(0),
VRAM_C_TEXTURE_SLOT1 = 3 | VRAM_OFFSET(1),
VRAM_C_TEXTURE_SLOT2 = 3 | VRAM_OFFSET(2),
VRAM_C_TEXTURE_SLOT3 = 3 | VRAM_OFFSET(3)
};
enum VRAM_D_TYPE
{
VRAM_D_LCD = 0,
VRAM_D_MAIN_BG = 1 | VRAM_OFFSET(3),
VRAM_D_MAIN_BG_0x06000000 = 1 | VRAM_OFFSET(0),
VRAM_D_MAIN_BG_0x06020000 = 1 | VRAM_OFFSET(1),
VRAM_D_MAIN_BG_0x06040000 = 1 | VRAM_OFFSET(2),
VRAM_D_MAIN_BG_0x06060000 = 1 | VRAM_OFFSET(3),
VRAM_D_ARM7 = 2 | VRAM_OFFSET(1),
VRAM_D_ARM7_0x06000000 = 2,
VRAM_D_ARM7_0x06020000 = 2 | VRAM_OFFSET(1),
VRAM_D_SUB_SPRITE = 4,
VRAM_D_TEXTURE = 3 | VRAM_OFFSET(3),
VRAM_D_TEXTURE_SLOT0 = 3 | VRAM_OFFSET(0),
VRAM_D_TEXTURE_SLOT1 = 3 | VRAM_OFFSET(1),
VRAM_D_TEXTURE_SLOT2 = 3 | VRAM_OFFSET(2),
VRAM_D_TEXTURE_SLOT3 = 3 | VRAM_OFFSET(3)
};
enum
{
MODE_0_2D = 0x10000,
MODE_1_2D = 0x10001,
MODE_2_2D = 0x10002,
MODE_3_2D = 0x10003,
MODE_4_2D = 0x10004,
MODE_5_2D = 0x10005
};
enum
{
DISPLAY_BG0_ACTIVE = (1 << 8),
DISPLAY_BG1_ACTIVE = (1 << 9),
DISPLAY_BG2_ACTIVE = (1 << 10),
DISPLAY_BG3_ACTIVE = (1 << 11),
DISPLAY_SPR_ACTIVE = (1 << 12),
DISPLAY_WIN0_ON = (1 << 13),
DISPLAY_WIN1_ON = (1 << 14),
DISPLAY_SPR_WIN_ON = (1 << 15)
};
#define BG_MAP_BASE(base) ((base) << 8)
enum
{
BG_16_COLOR = (0 << 7),
BG_256_COLOR = (1 << 7),
BG_RS_16x16 = (0 << 14),
BG_RS_32x32 = (1 << 14),
BG_RS_64x64 = (2 << 14),
BG_RS_128x128 = (3 << 14),
};
enum
{
BG_BMP8_128x128 = (BG_RS_16x16 | BG_256_COLOR),
BG_BMP8_256x256 = (BG_RS_32x32 | BG_256_COLOR),
BG_BMP8_512x256 = (BG_RS_64x64 | BG_256_COLOR),
BG_BMP8_512x512 = (BG_RS_128x128 | BG_256_COLOR),
BG_BMP8_1024x512 = (1 << 14),
BG_BMP8_512x1024 = 0,
BG_BMP16_128x12 = (BG_RS_16x16 | BG_256_COLOR | (1 << 2)),
BG_BMP16_256x256 = (BG_RS_32x32 | BG_256_COLOR | (1 << 2)),
BG_BMP16_512x256 = (BG_RS_64x64 | BG_256_COLOR | (1 << 2)),
BG_BMP16_512x512 = (BG_RS_128x128 | BG_256_COLOR | (1 << 2)),
};
extern CRegScreen16 g_bgpalettesub;
extern CRegVram16 g_vram[0x80000];
extern CRegPalette16 g_pal[256];
extern CRegPalette16 g_palsub[256];
struct tagNdsBgReg
{
CRegScreen16 cr;
CRegScreen16 xdx;
CRegScreen16 xdy;
CRegScreen16 ydx;
CRegScreen16 ydy;
CRegScreen32 cx;
CRegScreen32 cy;
};
extern tagNdsBgReg g_bg[4];
extern tagNdsBgReg g_subbg[4];
#define BG3_CR g_bg[3].cr
#define BG3_XDX g_bg[3].xdx
#define BG3_XDY g_bg[3].xdy
#define BG3_YDX g_bg[3].ydx
#define BG3_YDY g_bg[3].ydy
#define BG3_CX g_bg[3].cx
#define BG3_CY g_bg[3].cy
#define SUB_BG0_CR g_subbg[0].cr
#define BG_GFX g_vram
#define BG_PALETTE g_pal
#define BG_PALETTE_SUB g_palsub
void videoSetMode(uint32 mode);
void videoSetModeSub(uint32 mode);
uint32 vramSetMainBanks(VRAM_A_TYPE a, VRAM_B_TYPE b, VRAM_C_TYPE c, VRAM_D_TYPE d);
#define CHAR_BASE_BLOCK(n) (((n)*0x4000)+ 0x06000000)
#define CHAR_BASE_BLOCK_SUB(n) (((n)*0x4000)+ 0x06200000)
#define SCREEN_BASE_BLOCK(n) (((n)*0x800) + 0x06000000)
#define SCREEN_BASE_BLOCK_SUB(n) (((n)*0x800) + 0x06200000)
#define ndsvideo_vramnotify() do { CNdsRegUpdate::getInstance().set(RT_VRAM); } while(0)
// ---- for win
bool ndsvideo_initialize(HWND hWnd);
void ndsvideo_deinitialize();
void ndsvideo_update();
void ndsvideo_bufferupdate();

16
nds/win32s/trace.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "compiler.h"
#include <stdarg.h>
#include "libnds.h"
#ifdef TRACE
void trace_fmt(const char *lpcszFormat, ...)
{
va_list ap;
va_start(ap, lpcszFormat);
char szWork[256];
vsprintf(szWork, lpcszFormat, ap);
va_end(ap);
iprintf("%s\n", szWork);
}
#endif

25
nds/win32s/trace.h Normal file
View File

@ -0,0 +1,25 @@
#define TRACEINIT()
#define TRACETERM()
#ifndef TRACE
#define TRACEOUT(a)
#else
#ifdef __cplusplus
extern "C"
{
#endif
void trace_fmt(const char *str, ...);
#define TRACEOUT(arg) trace_fmt arg
#ifdef __cplusplus
}
#endif
#endif

91
nds/xmil7.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "compiler.h"
#include "libnds.h"
#include "xmil7.h"
#if defined(_WIN32) && defined(NDS_SIMULATE)
#include "dosio.h"
#endif
#include "nds7psg.h"
#include "softkbd7.h"
static void touch()
{
static uint16 s_wLastButtons = (uint16)-1;
touchPosition pos;
ZeroMemory(&pos, sizeof(pos));
uint16 wButtons = REG_KEYXY;
if (!((wButtons ^ s_wLastButtons) & (1 << 6)))
{
pos = touchReadXY();
if ((pos.x == 0) || (pos.y == 0))
{
wButtons |= (1 << 6);
s_wLastButtons = wButtons;
}
}
else
{
s_wLastButtons = wButtons;
wButtons |= (1 << 6);
}
IPC->touchX = pos.x;
IPC->touchY = pos.y;
IPC->touchXpx = pos.px;
IPC->touchYpx = pos.py;
IPC->touchZ1 = pos.z1;
IPC->touchZ2 = pos.z2;
IPC->buttons = wButtons;
}
static void VblankHandler()
{
touch();
const uint16 wButtons = IPC->buttons;
if (!(wButtons & (1 << 6)))
{
softkbd7_down(IPC->touchXpx, IPC->touchYpx);
}
else
{
softkbd7_up();
}
softkbd7_sync();
}
int nds7main()
{
// read User Settings from firmware
readUserSettings();
//enable sound
powerON(POWER_SOUND);
writePowerManagement(PM_CONTROL_REG, (readPowerManagement(PM_CONTROL_REG) & (~PM_SOUND_MUTE)) | PM_SOUND_AMP);
SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
softkbd7_initialize();
irqInit();
// Start the RTC tracking IRQ
initClockIRQ();
irqSet(IRQ_VBLANK, VblankHandler);
irqEnable(IRQ_VBLANK);
NDS7PSG psg;
nds7psg_reset(&psg);
while(1)
{
swiWaitForVBlank();
nds7psg_sync(&psg);
}
return 0;
}

1
nds/xmil7.h Normal file
View File

@ -0,0 +1 @@

374
nds/xmil9.cpp Normal file
View File

@ -0,0 +1,374 @@
#include "compiler.h"
#include "libnds.h"
#include "xmil9.h"
#if defined(_WIN32) && defined(NDS_SIMULATE)
#include "dosio.h"
#endif
#include "sysmng.h"
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "joymng.h"
#include "timing.h"
#include "makescrn.h"
#include "fddfile.h"
#include "font.h"
#include "nds9psg.h"
#include "vram.h"
#include "vsyncff.h"
#include "resource.h"
#include "softkbd9.h"
#if defined(SUPPORT_ROMEO2)
#include "ds_fpga.h"
#include "nds_fpga_raw.h"
#endif // defined(SUPPORT_ROMEO2)
#if 0 && defined(TRACE)
XMILOSCFG xmiloscfg = {1, 1};
#else
XMILOSCFG xmiloscfg = {0, 0};
#endif
#define MAX_FRAMESKIP 4
#if defined(NDS_SIMULATE)
static bool diskimgset1(REG8 cDrv, LPCTSTR lpcszFile)
{
FILEH fh = FILEH_INVALID;
UINT8 *pWork = 0;
do
{
fh = file_open_rb_c(lpcszFile);
if (fh == FILEH_INVALID)
{
break;
}
const UINT uSize = file_getsize(fh);
if (uSize == 0)
{
break;
}
pWork = new UINT8 [uSize];
if (!pWork)
{
break;
}
if (file_read(fh, pWork, uSize) != uSize)
{
break;
}
file_close(fh);
fddfile_set(cDrv, FTYPE_D88, pWork, uSize);
return true;
} while(0 /*CONSTCOND*/);
if (pWork)
{
delete[] pWork;
}
if (fh != FILEH_INVALID)
{
file_close(fh);
}
return false;
}
static void diskimgset()
{
diskimgset1(0, _T("disk1.d88"));
diskimgset1(1, _T("disk2.d88"));
}
#else // defined(NDS_SIMULATE)
static bool diskimgset1(REG8 cDrv, const unsigned char *lpcsData, UINT uSize)
{
if ((lpcsData) && (uSize))
{
fddfile_set(cDrv, FTYPE_D88, lpcsData, uSize);
return true;
}
return false;
}
static void diskimgset()
{
diskimgset1(0, __extromimage.sDisk1, __extromimage.uDisk1Size);
diskimgset1(1, __extromimage.sDisk2, __extromimage.uDisk2Size);
}
#endif // defined(NDS_SIMULATE)
// ---- bitmap
#if defined(SUPPORT_ROMEO2)
static void withRomeo2()
{
const unsigned char *p = reinterpret_cast<const unsigned char *>(g_sDemoBmp);
p = p + 16 + (192 * 256);
unsigned char *q = reinterpret_cast<unsigned char *>(BG_GFX_SUB);
q = q + 188 + (64 * 256);
for (int y=0; y<8; y++)
{
for (int x=0; x<68; x+=2)
{
*(reinterpret_cast<uint16 *>(q + x)) = *(reinterpret_cast<const uint16 *>(p + x));
}
p = p + 256;
q = q + 256;
}
}
#endif // defined(SUPPORT_ROMEO2)
// ----
struct tagXmilMain
{
UINT uFrameCount;
UINT uWaitCount;
UINT uFrameMax;
};
typedef struct tagXmilMain XMILMAIN;
typedef struct tagXmilMain *PXMILMAIN;
static void framereset(XMILMAIN &xmm, UINT uCount)
{
xmm.uFrameCount = 0;
sysmng_dispclock();
sysmng_fddsync(uCount);
}
static void processwait(XMILMAIN &xmm, UINT uCount)
{
if (timing_getcount() >= uCount)
{
timing_setcount(0);
framereset(xmm, uCount);
}
else
{
Sleep(1);
}
}
static void exec1frame(XMILMAIN &xmm)
{
joymng_setflags();
pccore_exec((BRESULT)(xmm.uFrameCount == 0));
xmm.uFrameCount++;
nds9psg_sync(&nds9psg);
softkbd9_sync();
}
int nds9main()
{
XMILMAIN xmilmain;
if ((sizeof(z80core) != 0x40) ||
(sizeof(dma) != 0x40) ||
(sizeof(iocore) != 0x214) ||
(sizeof(ppi) != 0x4) ||
(sizeof(crtc) != 0x44) ||
(sizeof(nds9psg) != 0x18) ||
(sizeof(subcpu) != 0x4c) ||
(sizeof(ctc) != 0xe4) ||
(sizeof(cgrom) != 0xc) ||
(sizeof(fdc) != 0x40))
{
while(1) { Sleep(1000); }
}
TRACEINIT();
// xmilopen();
irqInit();
irqSet(IRQ_VBLANK, vsyncff_int);
irqSet(IRQ_TIMER3, ndscore_timer3int);
ndscore_timer3init();
vsyncff_init();
irqEnable(IRQ_VBLANK | IRQ_TIMER3);
#if defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
#define VRAMBPARAM VRAM_B_MAIN_SPRITE_0x06400000
#else // defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
#define VRAMBPARAM VRAM_B_LCD
#endif // defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
#if defined(TRACE)
#define VRAMCPARAM VRAM_C_SUB_BG
#else // defined(TRACE)
#define VRAMCPARAM VRAM_C_SUB_BG_0x06200000
#endif // defined(TRACE)
vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAMBPARAM, VRAMCPARAM, VRAM_D_LCD);
#if defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
videoSetMode(MODE_5_2D | DISPLAY_SPR_ACTIVE | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_1D);
#else // defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
#endif // defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
#if MAKESCRN_VRAMFF
BG3_CR = BG_BMP8_512x256;
#else // MAKESCRN_VRAMFF
BG3_CR = BG_BMP8_256x256;
#endif // MAKESCRN_VRAMFF
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = 0;
BG3_CY = 0 << 8;
#if defined(TRACE)
videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
SUB_BG0_CR = BG_MAP_BASE(31);
BG_PALETTE_SUB[255] = RGB15(31,31,31);
consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
#else // defined(TRACE)
videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
SUB_BG3_CR = BG_BMP8_256x256;
SUB_BG3_XDX = 1 << 8;
SUB_BG3_XDY = 0;
SUB_BG3_YDX = 0;
SUB_BG3_YDY = 1 << 8;
SUB_BG3_CX = 0;
SUB_BG3_CY = 0 << 8;
dmaCopy(g_sDemoBmp, BG_GFX_SUB, 256*192);
dmaCopy(g_sDemoPal, BG_PALETTE_SUB, 256*2);
#endif // defined(TRACE)
#if defined(SUPPORT_ROMEO2)
ds_fpga_bus_init();
const int nFpgaError = ds_fpga_configration(g_nds_fpga_raw, g_nds_fpga_raw_size);
if (nFpgaError == FPGA_NO_ERR)
{
/* Enable OPM Sound */
xmilcfg.SOUND_SW = 1;
withRomeo2();
}
#endif // defined(SUPPORT_ROMEO2)
softkbd9_initialize();
extrom_initialize();
sysmng_initialize();
pccore_initialize();
pccore_reset();
diskimgset();
xmilmain.uFrameCount = 0;
xmilmain.uWaitCount = 0;
xmilmain.uFrameMax = 1;
sysmng_clockreset();
CopyMemory(font_ank, __extromimage.ank, 0x800);
#if 1
while(ndssys_task())
{
if (xmiloscfg.NOWAIT)
{
exec1frame(xmilmain);
if (xmiloscfg.DRAW_SKIP)
{
// nowait frame skip
if (xmilmain.uFrameCount >= xmiloscfg.DRAW_SKIP)
{
processwait(xmilmain, 0);
}
}
else
{
// nowait auto skip
if (timing_getcount())
{
processwait(xmilmain, 0);
}
}
}
else if (xmiloscfg.DRAW_SKIP)
{
// frame skip
if (xmilmain.uFrameCount < xmiloscfg.DRAW_SKIP)
{
exec1frame(xmilmain);
}
else
{
processwait(xmilmain, xmiloscfg.DRAW_SKIP);
}
}
else
{
// auto skip
if (!xmilmain.uWaitCount)
{
exec1frame(xmilmain);
const UINT uCount = timing_getcount();
if (xmilmain.uFrameCount > uCount)
{
xmilmain.uWaitCount = xmilmain.uFrameCount;
if (xmilmain.uFrameMax > 1)
{
xmilmain.uFrameMax--;
}
}
else if (xmilmain.uFrameCount >= xmilmain.uFrameMax)
{
if (xmilmain.uFrameMax < MAX_FRAMESKIP)
{
xmilmain.uFrameMax++;
}
if (uCount >= MAX_FRAMESKIP)
{
timing_reset();
}
else
{
timing_setcount(uCount - xmilmain.uFrameCount);
}
framereset(xmilmain, 0);
}
}
else
{
processwait(xmilmain, xmilmain.uWaitCount);
xmilmain.uWaitCount = xmilmain.uFrameCount;
}
}
}
#else
while(ndssys_task())
{
if (xmilmain.uFrameCount < 2)
{
exec1frame(xmilmain);
}
else
{
processwait(xmilmain, 2);
}
}
#endif
pccore_deinitialize();
TRACETERM();
return 0;
}

20
nds/xmil9.h Normal file
View File

@ -0,0 +1,20 @@
struct tagXmilOsCfg
{
UINT8 NOWAIT;
UINT8 DRAW_SKIP;
};
typedef struct tagXmilOsCfg XMILOSCFG;
#ifdef __cplusplus
extern "C"
{
#endif
extern XMILOSCFG xmiloscfg;
#ifdef __cplusplus
}
#endif

452
nds/xmilw32.dsp Normal file
View File

@ -0,0 +1,452 @@
# Microsoft Developer Studio Project File - Name="xmilw32" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** 編集しないでください **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=xmilw32 - Win32 Debug
!MESSAGE これは有効なメイクファイルではありません。 このプロジェクトをビルドするためには NMAKE を使用してください。
!MESSAGE [メイクファイルのエクスポート] コマンドを使用して実行してください
!MESSAGE
!MESSAGE NMAKE /f "xmilw32.mak".
!MESSAGE
!MESSAGE NMAKE の実行時に構成を指定できます
!MESSAGE コマンド ライン上でマクロの設定を定義します。例:
!MESSAGE
!MESSAGE NMAKE /f "xmilw32.mak" CFG="xmilw32 - Win32 Debug"
!MESSAGE
!MESSAGE 選択可能なビルド モード:
!MESSAGE
!MESSAGE "xmilw32 - Win32 Release" ("Win32 (x86) Application" 用)
!MESSAGE "xmilw32 - Win32 Debug" ("Win32 (x86) Application" 用)
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "xmilw32 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\bin"
# PROP Intermediate_Dir "..\obj\vc\xmilnds"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I ".\\" /I ".\patch" /I ".\win32s" /I "..\\" /I "..\common" /I "..\z80ac" /I "..\io" /I ".\vram" /I ".\sound" /I ".\fdd" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "TRACE" /D MAKESCRN_VRAMFF=1 /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x411 /d "NDEBUG"
# ADD RSC /l 0x411 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib ddraw.lib dxguid.lib dsound.lib /nologo /subsystem:console /map /machine:I386 /out:"..\bin/xmilnds/xmilw32.exe"
!ELSEIF "$(CFG)" == "xmilw32 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\bin"
# PROP Intermediate_Dir "..\obj\vc\xmilndsd"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I ".\\" /I ".\patch" /I ".\win32s" /I "..\\" /I "..\common" /I "..\z80ac" /I "..\io" /I ".\vram" /I ".\sound" /I ".\fdd" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D MAKESCRN_VRAMFF=1 /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x411 /d "_DEBUG"
# ADD RSC /l 0x411 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib ddraw.lib dxguid.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /out:"..\bin/xmilnds/xmilw32d.exe" /pdbtype:sept
!ENDIF
# Begin Target
# Name "xmilw32 - Win32 Release"
# Name "xmilw32 - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Group "common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\COMMON\MILSTR.C
# End Source File
# Begin Source File
SOURCE=..\COMMON\PARTS.C
# End Source File
# Begin Source File
SOURCE=..\COMMON\STRRES.C
# End Source File
# End Group
# Begin Group "cpu"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\z80ac\z80c.c
# End Source File
# Begin Source File
SOURCE=..\z80ac\z80c_cb.c
# End Source File
# Begin Source File
SOURCE=..\z80ac\z80c_ix.c
# End Source File
# Begin Source File
SOURCE=..\z80ac\z80c_iy.c
# End Source File
# Begin Source File
SOURCE=..\z80ac\z80c_mn.c
# End Source File
# Begin Source File
SOURCE=..\z80ac\z80c_sb.c
# End Source File
# Begin Source File
SOURCE=..\z80ac\z80dmap.c
# End Source File
# Begin Source File
SOURCE=..\z80ac\z80mem.c
# End Source File
# End Group
# Begin Group "io"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\IO\CGROM.C
# End Source File
# Begin Source File
SOURCE=..\IO\CMT.C
# End Source File
# Begin Source File
SOURCE=..\IO\CRTC.C
# End Source File
# Begin Source File
SOURCE=.\patch\CTC.C
# End Source File
# Begin Source File
SOURCE=..\IO\DIPSW.C
# End Source File
# Begin Source File
SOURCE=..\IO\DMAC.C
# End Source File
# Begin Source File
SOURCE=.\patch\FDC.C
# End Source File
# Begin Source File
SOURCE=.\PATCH\IOCORE.C
# End Source File
# Begin Source File
SOURCE=.\patch\MEMIO.C
# End Source File
# Begin Source File
SOURCE=..\IO\PCG.C
# End Source File
# Begin Source File
SOURCE=.\patch\PPI.C
# End Source File
# Begin Source File
SOURCE=..\IO\SIO.C
# End Source File
# Begin Source File
SOURCE=.\patch\SNDBOARD.C
# End Source File
# Begin Source File
SOURCE=.\patch\SUBCPU.C
# End Source File
# Begin Source File
SOURCE=.\patch\VRAMIO.C
# End Source File
# End Group
# Begin Group "vram"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\vram\make15.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\makeatr.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\makec16.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\makec8.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\makecs.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\makemix.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\makescrn.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\makesub.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\maketxtl.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\palettes.cpp
# End Source File
# Begin Source File
SOURCE=.\vram\vsyncff.cpp
# End Source File
# End Group
# Begin Group "fdd"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\fdd\FDD_2D.C
# End Source File
# Begin Source File
SOURCE=.\fdd\FDD_D88.C
# End Source File
# Begin Source File
SOURCE=.\fdd\FDDFILE.C
# End Source File
# End Group
# Begin Group "nds"
# PROP Default_Filter ""
# Begin Group "sound"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\sound\nds7psg.cpp
# End Source File
# Begin Source File
SOURCE=.\sound\nds9psg.cpp
# End Source File
# End Group
# Begin Group "win32s"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\win32s\dosio.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\extrom.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsconsole.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndscore.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsdma.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsinput.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsipc.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsirq.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsmem.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsreg.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndssound.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsswi.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndssys.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndstouch.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\ndsvideo.cpp
# End Source File
# Begin Source File
SOURCE=.\win32s\trace.cpp
# End Source File
# End Group
# Begin Source File
SOURCE=.\bss.x86
!IF "$(CFG)" == "xmilw32 - Win32 Release"
# Begin Custom Build - アセンブル中... $(InputPath)
IntDir=.\..\obj\vc\xmilnds
InputPath=.\bss.x86
InputName=bss
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
nasmw -f win32 -o $(IntDir)\$(InputName).obj -i.\x86\ -i..\i286x\ -i..\io\x86\ $(InputPath)
# End Custom Build
!ELSEIF "$(CFG)" == "xmilw32 - Win32 Debug"
# Begin Custom Build - アセンブル中... $(InputPath)
IntDir=.\..\obj\vc\xmilndsd
InputPath=.\bss.x86
InputName=bss
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
nasmw -f win32 -o $(IntDir)\$(InputName).obj -i.\x86\ -i..\i286x\ -i..\io\x86\ $(InputPath)
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\joymng.cpp
# End Source File
# Begin Source File
SOURCE=.\mousemng.cpp
# End Source File
# Begin Source File
SOURCE=.\softkbd7.cpp
# End Source File
# Begin Source File
SOURCE=.\softkbd9.cpp
# End Source File
# Begin Source File
SOURCE=.\timemng.cpp
# End Source File
# Begin Source File
SOURCE=.\xmil7.cpp
# End Source File
# Begin Source File
SOURCE=.\xmil9.cpp
# End Source File
# End Group
# Begin Source File
SOURCE=..\CALENDAR.C
# End Source File
# Begin Source File
SOURCE=..\DEBUGSUB.C
# End Source File
# Begin Source File
SOURCE=..\IEVENT.C
# End Source File
# Begin Source File
SOURCE=..\KEYSTAT.C
# End Source File
# Begin Source File
SOURCE=..\NEVENT.C
# End Source File
# Begin Source File
SOURCE=..\PCCORE.C
# End Source File
# Begin Source File
SOURCE=..\TIMING.C
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

29
nds/xmilw32.dsw Normal file
View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# 警告: このワークスペース ファイル を編集または削除しないでください!
###############################################################################
Project: "xmilw32"=.\xmilw32.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

207
z80ac/z80c.c Normal file
View File

@ -0,0 +1,207 @@
/* -----------------------------------------------------------------------
*
* Z80C : Z80 Engine - GENERIC
*
* Copyright by Studio Milmake 1999-2000,2004
*
*------------------------------------------------------------------------ */
#include "compiler.h"
#include "parts.h"
#include "z80core.h"
#include "z80c.h"
#include "pccore.h"
#include "iocore.h"
#include "z80c.mcr"
// UINT8 z80inc_flag2[256];
// UINT8 z80dec_flag2[256];
UINT8 z80szc_flag[512];
// UINT8 z80szp_flag[256];
const UINT8 cycles_main[256] = {
4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4,
8,10, 7, 6, 4, 4, 7, 4, 7,11, 7, 6, 4, 4, 7, 4,
7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4,
7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4,
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4,
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4,
5,10,10,10,10,11, 7,11, 5, 4,10, 0,10,10, 7,11,
5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11,
5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11,
5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11};
const UINT8 cycles_xx[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0,
0,14,20,10, 9, 9, 9, 0, 0,15,20,10, 9, 9, 9, 0,
0, 0, 0, 0,23,23,19, 0, 0,15, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
9, 9, 9, 9, 9, 9,19, 9, 9, 9, 9, 9, 9, 9,19, 9,
19,19,19,19,19,19,19,19, 0, 0, 0, 0, 9, 9,19, 0,
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
0, 0, 0, 0, 9, 9,19, 0, 0, 0, 0, 0, 9, 9,19, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,14, 0,23, 0,15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0};
const UINT8 cycles_ed[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12,12,15,20, 8, 8, 8, 9,12,12,15,20, 8, 8, 8, 9,
12,12,15,20, 8, 8, 8, 9,12,12,15,20, 8, 8, 8, 9,
12,12,15,20, 8, 8, 8,18,12,12,15,20, 8, 8, 8,18,
12,12,15,20, 8, 8, 8, 0,12,12,15,20, 8, 8, 8, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16,16,16,16, 0, 0, 0, 0,16,16,16,16, 0, 0, 0, 0,
16,16,16,16, 0, 0, 0, 0,16,16,16,16, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void CPUCALL z80ac_initialize(void) {
UINT i;
REG8 f;
REG8 c;
for (i=0; i<256; i++) {
f = V_FLAG;
if (!i) {
f |= Z_FLAG;
}
if (i & 0x80) {
f |= S_FLAG;
}
for (c=0x80; c; c>>=1) {
if (i & c) {
f ^= V_FLAG;
}
}
z80szp_flag[i] = (UINT8)f;
z80inc_flag2[(i - 1) & 0xff] = (UINT8)(f & (~V_FLAG));
if (!(i & 0x0f)) {
z80inc_flag2[(i - 1) & 0xff] |= H_FLAG;
}
z80dec_flag2[(i + 1) & 0xff] = (UINT8)(f & (~V_FLAG)) | N_FLAG;
if ((i & 0x0f) == 0x0f) {
z80dec_flag2[(i + 1) & 0xff] |= H_FLAG;
}
z80szc_flag[i] = (UINT8)(f & (~V_FLAG));
z80szc_flag[i+256] = (UINT8)(f & (~V_FLAG)) | C_FLAG;
}
z80inc_flag2[0x80 - 1] |= V_FLAG;
z80dec_flag2[0x7f + 1] |= V_FLAG;
}
void CPUCALL z80ac_reset(void) {
ZeroMemory(&z80core.s, sizeof(z80core.s));
R_Z80R = rand_get();
}
void CPUCALL z80ac_interrupt(REG8 vect) {
REG16 pc;
if (Z80_IFF & (1 << IFF_HALT)) {
Z80_IFF ^= (1 << IFF_HALT);
R_Z80PC++;
}
Z80_IFF |= (1 << IFF_IFLAG);
switch(R_Z80IM) {
case 0:
if ((vect != 0xdd) && (vect != 0xed) && (vect != 0xfd)) {
Z80_COUNT(cycles_main[vect]);
z80c_mainop[vect]();
}
break;
case 1:
Z80_COUNT(11);
R_Z80SP -= 2;
mem_write16(R_Z80SP, R_Z80PC);
R_Z80PC = 0x38;
break;
case 2:
pc = mem_read16((R_Z80I << 8) + vect);
R_Z80SP -= 2;
mem_write16(R_Z80SP, R_Z80PC);
R_Z80PC = pc;
break;
}
}
void CPUCALL z80ac_nonmaskedinterrupt(void) {
if (!(Z80_IFF & (1 << IFF_NMI))) {
Z80_IFF |= (1 << IFF_NMI);
if (Z80_IFF & (1 << IFF_HALT)) {
Z80_IFF ^= (1 << IFF_HALT);
R_Z80PC++;
}
R_Z80SP -= 2;
mem_write16(R_Z80SP, R_Z80PC);
R_Z80PC = 0x66;
}
}
void CPUCALL z80ac_execute(void) {
UINT op;
#if !defined(DMAS_STOIC)
if (!dma.working)
#else
if (!(dma.flag & DMAF_WORKING))
#endif
{
do {
R_Z80R++;
GET_PC_BYTE(op);
Z80_COUNT(cycles_main[op]);
z80c_mainop[op]();
} while(CPU_REMCLOCK > 0);
}
else {
do {
R_Z80R++;
GET_PC_BYTE(op);
Z80_COUNT(cycles_main[op]);
z80c_mainop[op]();
z80dmap();
} while(CPU_REMCLOCK > 0);
}
}
void CPUCALL z80ac_step(void) {
UINT op;
R_Z80R++;
GET_PC_BYTE(op);
Z80_COUNT(cycles_main[op]);
z80c_mainop[op]();
z80dmap();
}

61
z80ac/z80c.h Normal file
View File

@ -0,0 +1,61 @@
/* -----------------------------------------------------------------------
*
* Z80C : Z80 Engine - GENERIC
*
* Copyright by Studio Milmake 1999-2000,2004
*
*------------------------------------------------------------------------ */
#define z80inc_flag2 z80flag.inc
#define z80dec_flag2 z80flag.dec
#define z80szp_flag z80flag.szp
extern UINT8 z80szc_flag[512];
extern const UINT8 cycles_main[256];
extern const UINT8 cycles_xx[256];
extern const UINT8 cycles_ed[256];
#define Z80FN static void
#define Z80EXT void
typedef void (*Z80OP)(void);
extern const Z80OP z80c_mainop[256];
extern void z80c_cb(void);
extern void z80c_ix(void);
extern void z80c_sub(void);
extern void z80c_iy(void);
extern void z80c_ixcb(void);
extern void z80c_iycb(void);
#define R_Z80A z80core.s.af.b.a
#define R_Z80F z80core.s.af.b.f
#define R_Z80B z80core.s.r.b.b
#define R_Z80C z80core.s.r.b.c
#define R_Z80D z80core.s.r.b.d
#define R_Z80E z80core.s.r.b.e
#define R_Z80H z80core.s.r.b.h
#define R_Z80L z80core.s.r.b.l
#define R_Z80AF z80core.s.af.w
#define R_Z80BC z80core.s.r.w.bc
#define R_Z80DE z80core.s.r.w.de
#define R_Z80HL z80core.s.r.w.hl
#define R_Z80IX z80core.s.r.w.ix
#define R_Z80IY z80core.s.r.w.iy
#define R_Z80PC z80core.s.pc
#define R_Z80SP z80core.s.sp
#define R_Z80AF2 z80core.s.r.w.af2
#define R_Z80BC2 z80core.s.bc2
#define R_Z80DE2 z80core.s.de2
#define R_Z80HL2 z80core.s.hl2
#define R_Z80I z80core.s.i
#define R_Z80IM z80core.s.im
#define R_Z80R z80core.s.r1
#define R_Z80R2 z80core.s.r2
#define R_Z80IFF z80core.s.iff

612
z80ac/z80c.mcr Normal file
View File

@ -0,0 +1,612 @@
/* -----------------------------------------------------------------------
*
* Z80C : Z80 Engine - GENERIC
*
* Copyright by Studio Milmake 1999-2000,2004
*
*------------------------------------------------------------------------ */
/* #define PCCOUNTER */
#if defined(TRACE) && defined(PCCOUNTER)
extern UINT pccnt;
extern UINT pccnt2;
extern UINT pccnt3;
extern UINT lastpc;
#endif
#define Z80_COUNT(clock) \
do { \
CPU_REMCLOCK -= (clock); \
} while (/*CONSTCOND*/ 0)
#if defined(TRACE) && defined(PCCOUNTER)
#define GET_PC_BYTE(b) \
do { \
if ((lastpc ^ R_Z80PC) & 0x8000) { \
TRACEOUT(("%.4x->%.4x", lastpc, R_Z80PC)); \
lastpc = R_Z80PC; \
pccnt2++; \
} \
pccnt++; \
(b) = mem_read8(R_Z80PC++); \
} while (/*CONSTCOND*/ 0)
#define GET_PC_WORD(w) \
do { \
pccnt3++; \
(w) = mem_read16(R_Z80PC); \
R_Z80PC += 2; \
} while (/*CONSTCOND*/ 0)
#else
#define GET_PC_BYTE(b) \
do { \
(b) = mem_read8(R_Z80PC++); \
} while (/*CONSTCOND*/ 0)
#define GET_PC_WORD(w) \
do { \
(w) = mem_read16(R_Z80PC); \
R_Z80PC += 2; \
} while (/*CONSTCOND*/ 0)
#endif
#define MCR_EX1(r1, r2) \
do { \
REG16 tmp; \
tmp = (r1); \
(r1) = (r2); \
(r2) = tmp; \
} while (/*CONSTCOND*/ 0)
#define JRBYFLAG(flg) \
do { \
if ((flg)) { \
SINT ofst; \
ofst = mem_read8s(R_Z80PC++); \
R_Z80PC += ofst; \
Z80_COUNT(5); \
} \
else { \
R_Z80PC++; \
} \
} while (/*CONSTCOND*/ 0)
#define LDW_w(reg) { \
(reg) = mem_read16(R_Z80PC); \
R_Z80PC += 2; \
}
#define LDx_B(dst, src) { \
mem_write8((dst), (src)); \
}
#define MCR_INC_W(reg) { \
(reg)++; \
}
#define MCR_INC(reg) { \
R_Z80F &= C_FLAG; \
R_Z80F |= z80inc_flag2[(reg)]; \
(reg)++; \
}
#define MCR_DEC(reg) { \
R_Z80F &= C_FLAG; \
R_Z80F |= z80dec_flag2[(reg)]; \
(reg)--; \
}
#define LDB_b(reg) { \
(reg) = mem_read8(R_Z80PC++); \
}
#define MCR_RLCA { \
REG8 tmp; \
tmp = (UINT8)(R_Z80A >> 7); \
R_Z80A = (R_Z80A << 1) | tmp; \
R_Z80F &= 0xec; \
R_Z80F |= tmp; \
}
#define MCR_EX(reg1, reg2) { \
MCR_EX1(reg1, reg2); \
}
#define MCR_ADD_W(dst, src) { \
UINT32 tmp; \
R_Z80F &= (S_FLAG | Z_FLAG | V_FLAG); \
tmp = (dst) + (src); \
R_Z80F |= (UINT8)(tmp >> 16); \
R_Z80F |= ((tmp ^ (dst) ^ (src)) >> 8) & H_FLAG; \
(dst) = (UINT16)tmp; \
}
#define LDB_x(b, w) { \
(b) = mem_read8((w)); \
}
#define MCR_DEC_W(reg) { \
(reg)--; \
}
#define MCR_RRCA { \
REG8 tmp; \
tmp = (UINT8)(R_Z80A & 1); \
R_Z80F &= 0xec; \
R_Z80F |= tmp; \
R_Z80A = (R_Z80A >> 1) | (tmp << 7); \
}
#define MCR_DJNZ { \
R_Z80B--; \
JRBYFLAG(R_Z80B); \
}
#define MCR_RLA { \
REG8 tmp; \
tmp = (UINT8)(R_Z80A >> 7); \
R_Z80A = (R_Z80A << 1) | (R_Z80F & 1); \
R_Z80F &= 0xec; \
R_Z80F |= tmp; \
}
#define MCR_JR { \
SINT ofst; \
ofst = mem_read8s(R_Z80PC++); \
R_Z80PC += ofst; \
Z80_COUNT(5); \
}
#define MCR_RRA { \
REG8 tmp; \
tmp = (UINT8)(R_Z80A & 1); \
R_Z80A = (R_Z80A >> 1) | (R_Z80F << 7); \
R_Z80F &= 0xec; \
R_Z80F |= tmp; \
}
#define MCR_JRNFLG(flg) { \
JRBYFLAG(!(R_Z80F & (flg))); \
}
#define LDx_W(reg) { \
UINT adrs; \
GET_PC_WORD(adrs); \
mem_write16(adrs, (reg)); \
}
#define MCR_DDA { \
SINT dst; \
REG8 flg; \
SINT alow; \
dst = R_Z80A; \
alow = R_Z80A & 0x0f; \
flg = R_Z80F & N_FLAG; \
if (!flg) { \
if (alow >= 10) { \
flg |= H_FLAG; \
dst += 6; \
} \
else if (R_Z80F & H_FLAG) { \
dst += 6; \
} \
if ((dst >= 0xa0) || (R_Z80F & C_FLAG)) { \
flg |= C_FLAG; \
dst += 0x60; \
} \
} \
else { \
if ((dst > 0x99) || (R_Z80F & C_FLAG)) { \
dst -= 0x60; \
flg |= C_FLAG; \
} \
if ((alow > 9) || (R_Z80F & H_FLAG)) { \
if (alow < 6) { \
flg |= H_FLAG; \
} \
dst -= 6; \
if ((dst < 0) && (!(R_Z80F & H_FLAG))) { \
flg |= C_FLAG; \
} \
} \
} \
R_Z80A = (UINT8)dst; \
R_Z80F = flg | z80szp_flag[dst & 0xff]; \
}
#define MCR_JRFLG(flg) { \
JRBYFLAG(R_Z80F & (flg)); \
}
#define MCR_ADDx2(reg) { \
R_Z80F &= (S_FLAG | Z_FLAG | V_FLAG); \
R_Z80F |= (UINT8)((reg) >> 15); \
(reg) <<= 1; \
R_Z80F |= ((reg) >> 8) & H_FLAG; \
}
#define LDW_x(reg) { \
UINT adrs; \
GET_PC_WORD(adrs); \
(reg) = mem_read16(adrs); \
}
#define MCR_CPL { \
R_Z80A = (UINT8)(~R_Z80A); \
R_Z80F |= (H_FLAG | N_FLAG); \
}
#define LDB_x_a { \
UINT adrs; \
GET_PC_WORD(adrs); \
mem_write8(adrs, R_Z80A); \
}
#define MCR_INC_MEM(adrs) { \
REG8 tmp; \
tmp = mem_read8((adrs)); \
R_Z80F &= C_FLAG; \
R_Z80F |= z80inc_flag2[tmp]; \
mem_write8((adrs), (REG8)(tmp + 1)); \
}
#define MCR_DEC_MEM(adrs) { \
REG8 tmp; \
tmp = mem_read8((adrs)); \
R_Z80F &= C_FLAG; \
R_Z80F |= z80dec_flag2[tmp]; \
mem_write8((adrs), (REG8)(tmp - 1)); \
}
#define LDB_xhl_b { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
mem_write8(R_Z80HL, tmp); \
}
#define MCR_SCF { \
R_Z80F &= ~(H_FLAG | N_FLAG); \
R_Z80F |= C_FLAG; \
}
#define LDB_a_x { \
UINT adrs; \
GET_PC_WORD(adrs); \
R_Z80A = mem_read8(adrs); \
}
#define MCR_CCF { \
R_Z80F &= ~(H_FLAG | N_FLAG); \
if (R_Z80F & C_FLAG) { \
R_Z80F |= H_FLAG; \
} \
R_Z80F ^= C_FLAG; \
}
#define MCR_LD(d, s) { \
(d) = (s); \
}
#define MCR_HALT { \
R_Z80PC--; \
Z80_IFF |= (1 << IFF_HALT); \
CPU_REMCLOCK = 0; \
}
#define MCR_ADD(b) { \
UINT res; \
res = R_Z80A + (b); \
R_Z80F = z80szc_flag[res & 0x1ff]; \
R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG; \
R_Z80F |= (((res ^ R_Z80A) & (res ^ (b))) >> 5) & V_FLAG; \
R_Z80A = (UINT8)res; \
}
#define MCR_ADD_XHL { \
REG8 tmp; \
tmp = mem_read8(R_Z80HL); \
MCR_ADD(tmp) \
}
#define MCR_ADC(b) { \
UINT res; \
res = R_Z80A + (b) + (R_Z80F & 1); \
R_Z80F = z80szc_flag[res & 0x1ff]; \
R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG; \
R_Z80F |= (((res ^ R_Z80A) & (res ^ (b))) >> 5) & V_FLAG; \
R_Z80A = (UINT8)res; \
}
#define MCR_ADC_XHL { \
REG8 tmp; \
tmp = mem_read8(R_Z80HL); \
MCR_ADC(tmp) \
}
#define MCR_SUB(b) { \
UINT res; \
res = R_Z80A - (b); \
R_Z80F = z80szc_flag[res & 0x1ff] | N_FLAG; \
R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG; \
R_Z80F |= (((R_Z80A ^ res) & (R_Z80A ^ (b))) >> 5) & V_FLAG; \
R_Z80A = (UINT8)res; \
}
#define MCR_SUB_XHL { \
REG8 tmp; \
tmp = mem_read8(R_Z80HL); \
MCR_SUB(tmp) \
}
#define MCR_SBC(b) { \
UINT res; \
res = R_Z80A - (b) - (R_Z80F & 1); \
R_Z80F = z80szc_flag[res & 0x1ff] | N_FLAG; \
R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG; \
R_Z80F |= (((R_Z80A ^ res) & (R_Z80A ^ (b))) >> 5) & V_FLAG; \
R_Z80A = (UINT8)res; \
}
#define MCR_SBC_XHL { \
REG8 tmp; \
tmp = mem_read8(R_Z80HL); \
MCR_SBC(tmp) \
}
#define MCR_AND(b) { \
R_Z80A &= (b); \
R_Z80F = z80szp_flag[R_Z80A]; \
}
#define MCR_AND_XHL { \
REG8 tmp; \
tmp = mem_read8(R_Z80HL); \
MCR_AND(tmp) \
}
#define MCR_XOR(b) { \
R_Z80A ^= (b); \
R_Z80F = z80szp_flag[R_Z80A]; \
}
#define MCR_XOR_XHL { \
REG8 tmp; \
tmp = mem_read8(R_Z80HL); \
MCR_XOR(tmp) \
}
#define MCR_OR(b) { \
R_Z80A |= (b); \
R_Z80F = z80szp_flag[R_Z80A]; \
}
#define MCR_OR_XHL { \
REG8 tmp; \
tmp = mem_read8(R_Z80HL); \
MCR_OR(tmp) \
}
#define MCR_CP(b) { \
UINT res; \
res = R_Z80A - (b); \
R_Z80F = z80szc_flag[res & 0x1ff] | N_FLAG; \
R_Z80F |= (res ^ R_Z80A ^ (b)) & H_FLAG; \
R_Z80F |= (((R_Z80A ^ res) & (R_Z80A ^ (b))) >> 5) & V_FLAG; \
}
#define MCR_CP_XHL { \
REG8 tmp; \
tmp = mem_read8(R_Z80HL); \
MCR_CP(tmp) \
}
#define MCR_RETNFLG(flg) { \
if (!(R_Z80F & (flg))) { \
R_Z80PC = mem_read16(R_Z80SP); \
R_Z80SP += 2; \
Z80_COUNT(6); \
} \
}
#define MCR_POP(reg) { \
(reg) = mem_read16(R_Z80SP); \
R_Z80SP += 2; \
}
#define MCR_JPNFLG(flg) { \
if (!(R_Z80F & (flg))) { \
R_Z80PC = mem_read16(R_Z80PC); \
} \
else { \
R_Z80PC += 2; \
} \
}
#define MCR_JP { \
R_Z80PC = mem_read16(R_Z80PC); \
}
#define MCR_CALLNFLG(flg) { \
if (!(R_Z80F & (flg))) { \
REG16 tmp; \
GET_PC_WORD(tmp); \
R_Z80SP -= 2; \
mem_write16(R_Z80SP, R_Z80PC); \
R_Z80PC = tmp; \
Z80_COUNT(7); \
} \
else { \
R_Z80PC += 2; \
} \
}
#define MCR_PUSH(reg) { \
R_Z80SP -= 2; \
mem_write16(R_Z80SP, (reg)); \
}
#define MCR_ADD_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
MCR_ADD(tmp) \
}
#define MCR_RST(vect) { \
R_Z80SP -= 2; \
mem_write16(R_Z80SP, R_Z80PC); \
R_Z80PC = (vect); \
}
#define MCR_RETFLG(flg) { \
if (R_Z80F & (flg)) { \
R_Z80PC = mem_read16(R_Z80SP); \
R_Z80SP += 2; \
Z80_COUNT(6); \
} \
}
#define MCR_RET { \
R_Z80PC = mem_read16(R_Z80SP); \
R_Z80SP += 2; \
Z80_COUNT(6); \
}
#define MCR_JPFLG(flg) { \
if (R_Z80F & (flg)) { \
R_Z80PC = mem_read16(R_Z80PC); \
} \
else { \
R_Z80PC += 2; \
} \
}
#define MCR_CALLFLG(flg) { \
if (R_Z80F & (flg)) { \
REG16 tmp; \
GET_PC_WORD(tmp); \
R_Z80SP -= 2; \
mem_write16(R_Z80SP, R_Z80PC); \
R_Z80PC = tmp; \
Z80_COUNT(7); \
} \
else { \
R_Z80PC += 2; \
} \
}
#define MCR_CALL { \
REG16 tmp; \
GET_PC_WORD(tmp); \
R_Z80SP -= 2; \
mem_write16(R_Z80SP, R_Z80PC); \
R_Z80PC = tmp; \
Z80_COUNT(7); \
}
#define MCR_ADC_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
MCR_ADC(tmp) \
}
#define MCR_OUT_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
iocore_out((R_Z80A << 8) + tmp, tmp); \
}
#define MCR_SUB_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
MCR_SUB(tmp) \
}
#define MCR_EXX { \
MCR_EX(R_Z80BC, R_Z80BC2) \
MCR_EX(R_Z80DE, R_Z80DE2) \
MCR_EX(R_Z80HL, R_Z80HL2) \
}
#define MCR_IN_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
R_Z80A = iocore_inp((R_Z80A << 8) | tmp); \
}
#define MCR_SBC_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
MCR_SBC(tmp) \
}
#define MCR_EX_XSP(reg) { \
REG16 tmp; \
tmp = mem_read16(R_Z80SP); \
mem_write16(R_Z80SP, (reg)); \
(reg) = tmp; \
}
#define MCR_AND_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
MCR_AND(tmp) \
}
#define MCR_LD_W(dst, src) { \
(dst) = (src); \
}
#define MCR_XOR_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
MCR_XOR(tmp) \
}
#define MCR_DI { \
Z80_IFF |= (1 << IFF_IFLAG); \
}
#define MCR_OR_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
MCR_OR(tmp) \
}
#define MCR_EI { \
REG8 iff; \
SINT32 rem; \
iff = Z80_IFF; \
if (iff & (1 << IFF_IFLAG)) { \
Z80_IFF = (UINT8)(iff & (~(1 << IFF_IFLAG))); \
rem = CPU_REMCLOCK - 1; \
if ((rem < 0) || \
((!(iff & (1 << IFF_NMI))) && (CPU_REQIRQ != 0))) { \
CPU_BASECLOCK -= rem; \
CPU_REMCLOCK = 1; \
} \
} \
}
#define MCR_CP_BYTE { \
REG8 tmp; \
GET_PC_BYTE(tmp); \
MCR_CP(tmp) \
}

273
z80ac/z80c_cb.c Normal file
View File

@ -0,0 +1,273 @@
/* -----------------------------------------------------------------------
*
* Z80C : Z80 Engine - GENERIC
*
* Copyright by Studio Milmake 1999-2000,2004
*
*------------------------------------------------------------------------ */
#include "compiler.h"
#include "z80core.h"
#include "z80c.h"
#include "z80c.mcr"
static REG8 CPUCALL _cb_rlc(REG8 v) {
REG8 ret;
R_Z80F = v >> 7;
ret = (v << 1) | R_Z80F;
R_Z80F |= z80szp_flag[(UINT8)ret];
return(ret);
}
static REG8 CPUCALL _cb_rrc(REG8 v) {
REG8 ret;
R_Z80F = v & 1;
ret = (v >> 1) | (R_Z80F << 7);
R_Z80F |= z80szp_flag[(UINT8)ret];
return(ret);
}
static REG8 CPUCALL _cb_rl(REG8 v) {
REG8 ret;
ret = (v << 1) | (R_Z80F & 1);
R_Z80F = z80szp_flag[(UINT8)ret] | (v >> 7);
return(ret);
}
static REG8 CPUCALL _cb_rr(REG8 v) {
REG8 ret;
ret = (v >> 1) | (R_Z80F << 7);
R_Z80F = z80szp_flag[(UINT8)ret] | (v & 1);
return(ret);
}
static REG8 CPUCALL _cb_sla(REG8 v) {
REG8 ret;
ret = (v << 1);
R_Z80F = z80szp_flag[(UINT8)ret] | (v >> 7);
return(ret);
}
static REG8 CPUCALL _cb_sra(REG8 v) {
REG8 ret;
ret = (((SINT8)v) >> 1);
R_Z80F = z80szp_flag[(UINT8)ret] | (v & 1);
return(ret);
}
static REG8 CPUCALL _cb_sll(REG8 v) {
REG8 ret;
ret = (v << 1) | 1;
R_Z80F = z80szp_flag[(UINT8)ret] | (v >> 7);
return(ret);
}
static REG8 CPUCALL _cb_srl(REG8 v) {
REG8 ret;
ret = v >> 1;
R_Z80F = z80szp_flag[ret] | (v & 1);
return(ret);
}
static REG8 (CPUCALL * rolsft_proc[8])(REG8 value) = {
_cb_rlc, _cb_rrc, _cb_rl, _cb_rr,
_cb_sla, _cb_sra, _cb_sll, _cb_srl};
static UINT8 *cb_reg[8] = {
&R_Z80B, &R_Z80C, &R_Z80D, &R_Z80E,
&R_Z80H, &R_Z80L, NULL, &R_Z80A};
void z80c_cb(void) {
UINT op;
UINT8 *reg;
REG8 xhl;
UINT bit;
R_Z80R++;
GET_PC_BYTE(op);
reg = cb_reg[op & 7];
bit = (op >> 3) & 7;
if (reg) {
Z80_COUNT(8);
switch(op & 0xc0) {
case 0x00:
*reg = rolsft_proc[bit](*reg);
break;
case 0x40: /* bit */
R_Z80F &= C_FLAG;
if ((*reg) & (1 << bit)) {
if (bit != 7) {
R_Z80F |= H_FLAG;
}
else {
R_Z80F |= (H_FLAG | S_FLAG);
}
}
else {
R_Z80F |= (H_FLAG | Z_FLAG);
}
break;
case 0x80: /* reset */
(*reg) &= ~(1 << bit);
break;
case 0xc0: /* set */
(*reg) |= 1 << bit;
break;
}
}
else {
xhl = mem_read8(R_Z80HL);
switch(op & 0xc0) {
case 0x00:
Z80_COUNT(15);
xhl = rolsft_proc[bit](xhl);
break;
case 0x40: /* bit */
Z80_COUNT(12);
R_Z80F &= C_FLAG;
if (xhl & (1 << bit)) {
if (bit != 7) {
R_Z80F |= H_FLAG;
}
else {
R_Z80F |= (H_FLAG | S_FLAG);
}
}
else {
R_Z80F |= (H_FLAG | Z_FLAG);
}
return;
case 0x80: /* reset */
Z80_COUNT(15);
xhl &= ~(1 << bit);
break;
case 0xc0: /* set */
Z80_COUNT(15);
xhl |= 1 << bit;
break;
}
mem_write8(R_Z80HL, xhl);
}
}
void z80c_ixcb(void) {
UINT op;
UINT adrs;
REG8 xi;
UINT bit;
R_Z80R++;
adrs = LOW16(mem_read8s(R_Z80PC++) + R_Z80IX);
xi = mem_read8(adrs);
GET_PC_BYTE(op);
bit = (op >> 3) & 7;
switch(op & 0xc0) {
case 0x00:
Z80_COUNT(23);
xi = rolsft_proc[bit](xi);
break;
case 0x40: /* bit */
Z80_COUNT(20);
R_Z80F &= C_FLAG;
if (xi & (1 << bit)) {
if (bit != 7) {
R_Z80F |= H_FLAG;
}
else {
R_Z80F |= (H_FLAG | S_FLAG);
}
}
else {
R_Z80F |= (H_FLAG | Z_FLAG);
}
return;
case 0x80: /* reset */
Z80_COUNT(23);
xi &= ~(1 << bit);
break;
case 0xc0: /* set */
Z80_COUNT(23);
xi |= 1 << bit;
break;
}
mem_write8(adrs, xi);
}
void z80c_iycb(void) {
UINT op;
UINT adrs;
REG8 xi;
UINT bit;
R_Z80R++;
adrs = LOW16(mem_read8s(R_Z80PC++) + R_Z80IY);
xi = mem_read8(adrs);
GET_PC_BYTE(op);
bit = (op >> 3) & 7;
switch(op & 0xc0) {
case 0x00:
Z80_COUNT(23);
xi = rolsft_proc[bit](xi);
break;
case 0x40: /* bit */
Z80_COUNT(20);
R_Z80F &= C_FLAG;
if (xi & (1 << bit)) {
if (bit != 7) {
R_Z80F |= H_FLAG;
}
else {
R_Z80F |= (H_FLAG | S_FLAG);
}
}
else {
R_Z80F |= (H_FLAG | Z_FLAG);
}
return;
case 0x80: /* reset */
Z80_COUNT(23);
xi &= ~(1 << bit);
break;
case 0xc0: /* set */
Z80_COUNT(23);
xi |= 1 << bit;
break;
}
mem_write8(adrs, xi);
}

98
z80ac/z80c_i.mcr Normal file
View File

@ -0,0 +1,98 @@
#define GET_I(base) LOW16((base) + mem_read8s(R_Z80PC++))
#define MCR_INC_XI(base) { \
UINT adrs; \
adrs = GET_I((base)); \
MCR_INC_MEM(adrs) \
}
#define MCR_DEC_XI(base) { \
UINT adrs; \
adrs = GET_I((base)); \
MCR_DEC_MEM(adrs) \
}
#define MCR_LDXIBYTE(base) { \
UINT adrs; \
adrs = GET_I((base)); \
mem_write8(adrs, mem_read8(R_Z80PC++)); \
}
#define MCR_LD_RXI(reg, base) { \
UINT adrs; \
adrs = GET_I((base)); \
(reg) = mem_read8(adrs); \
}
#define MCR_LD_XIR(reg, base) { \
UINT adrs; \
adrs = GET_I((base)); \
mem_write8(adrs, (reg)); \
}
#define MCR_ADD_XI(base) { \
UINT adrs; \
REG8 tmp; \
adrs = GET_I((base)); \
tmp = mem_read8(adrs); \
MCR_ADD(tmp) \
}
#define MCR_ADC_XI(base) { \
UINT adrs; \
REG8 tmp; \
adrs = GET_I((base)); \
tmp = mem_read8(adrs); \
MCR_ADC(tmp) \
}
#define MCR_SUB_XI(base) { \
UINT adrs; \
REG8 tmp; \
adrs = GET_I((base)); \
tmp = mem_read8(adrs); \
MCR_SUB(tmp) \
}
#define MCR_SBC_XI(base) { \
UINT adrs; \
REG8 tmp; \
adrs = GET_I((base)); \
tmp = mem_read8(adrs); \
MCR_SBC(tmp) \
}
#define MCR_AND_XI(base) { \
UINT adrs; \
REG8 tmp; \
adrs = GET_I((base)); \
tmp = mem_read8(adrs); \
MCR_AND(tmp) \
}
#define MCR_XOR_XI(base) { \
UINT adrs; \
REG8 tmp; \
adrs = GET_I((base)); \
tmp = mem_read8(adrs); \
MCR_XOR(tmp) \
}
#define MCR_OR_XI(base) { \
UINT adrs; \
REG8 tmp; \
adrs = GET_I((base)); \
tmp = mem_read8(adrs); \
MCR_OR(tmp) \
}
#define MCR_CP_XI(base) { \
UINT adrs; \
REG8 tmp; \
adrs = GET_I((base)); \
tmp = mem_read8(adrs); \
MCR_CP(tmp) \
}

215
z80ac/z80c_ix.c Normal file
View File

@ -0,0 +1,215 @@
/* -----------------------------------------------------------------------
*
* Z80C : Z80 Engine - GENERIC
*
* Copyright by Studio Milmake 1999-2000,2004
*
*------------------------------------------------------------------------ */
#include "compiler.h"
#include "z80core.h"
#include "z80c.h"
#include "z80c.mcr"
#include "z80c_i.mcr"
#define R_Z80IXL z80core.s.r.b.ixl
#define R_Z80IXH z80core.s.r.b.ixh
#undef R_Z80IY
Z80FN _ld_nop(void) { }
Z80FN _no_op(void) MCR_DEC_W(R_Z80PC)
Z80FN _add_ix_bc(void) MCR_ADD_W(R_Z80IX, R_Z80BC)
Z80FN _add_ix_de(void) MCR_ADD_W(R_Z80IX, R_Z80DE)
Z80FN _ld_ix_word(void) LDW_w(R_Z80IX)
Z80FN _ld_xword_ix(void) LDx_W(R_Z80IX)
Z80FN _inc_ix(void) MCR_INC_W(R_Z80IX)
Z80FN _inc_ixh(void) MCR_INC(R_Z80IXH)
Z80FN _dec_ixh(void) MCR_DEC(R_Z80IXH)
Z80FN _ld_ixh_byte(void) LDB_b(R_Z80IXH)
Z80FN _add_ix_ix(void) MCR_ADDx2(R_Z80IX)
Z80FN _ld_ix_xword(void) LDW_x(R_Z80IX)
Z80FN _dec_ix(void) MCR_DEC_W(R_Z80IX)
Z80FN _inc_ixl(void) MCR_INC(R_Z80IXL)
Z80FN _dec_ixl(void) MCR_DEC(R_Z80IXL)
Z80FN _ld_ixl_byte(void) LDB_b(R_Z80IXL)
Z80FN _inc_xix(void) MCR_INC_XI(R_Z80IX)
Z80FN _dec_xix(void) MCR_DEC_XI(R_Z80IX)
Z80FN _ld_xix_byte(void) MCR_LDXIBYTE(R_Z80IX)
Z80FN _add_ix_sp(void) MCR_ADD_W(R_Z80IX, R_Z80SP)
Z80FN _ld_b_ixh(void) MCR_LD(R_Z80B, R_Z80IXH)
Z80FN _ld_b_ixl(void) MCR_LD(R_Z80B, R_Z80IXL)
Z80FN _ld_b_xix(void) MCR_LD_RXI(R_Z80B, R_Z80IX)
Z80FN _ld_c_ixh(void) MCR_LD(R_Z80C, R_Z80IXH)
Z80FN _ld_c_ixl(void) MCR_LD(R_Z80C, R_Z80IXL)
Z80FN _ld_c_xix(void) MCR_LD_RXI(R_Z80C, R_Z80IX)
Z80FN _ld_d_ixh(void) MCR_LD(R_Z80D, R_Z80IXH)
Z80FN _ld_d_ixl(void) MCR_LD(R_Z80D, R_Z80IXL)
Z80FN _ld_d_xix(void) MCR_LD_RXI(R_Z80D, R_Z80IX)
Z80FN _ld_e_ixh(void) MCR_LD(R_Z80E, R_Z80IXH)
Z80FN _ld_e_ixl(void) MCR_LD(R_Z80E, R_Z80IXL)
Z80FN _ld_e_xix(void) MCR_LD_RXI(R_Z80E, R_Z80IX)
Z80FN _ld_ixh_b(void) MCR_LD(R_Z80IXH, R_Z80B)
Z80FN _ld_ixh_c(void) MCR_LD(R_Z80IXH, R_Z80C)
Z80FN _ld_ixh_d(void) MCR_LD(R_Z80IXH, R_Z80D)
Z80FN _ld_ixh_e(void) MCR_LD(R_Z80IXH, R_Z80E)
Z80FN _ld_ixh_ixl(void) MCR_LD(R_Z80IXH, R_Z80IXL)
Z80FN _ld_h_xix(void) MCR_LD_RXI(R_Z80H, R_Z80IX)
Z80FN _ld_ixh_a(void) MCR_LD(R_Z80IXH, R_Z80A)
Z80FN _ld_ixl_b(void) MCR_LD(R_Z80IXL, R_Z80B)
Z80FN _ld_ixl_c(void) MCR_LD(R_Z80IXL, R_Z80C)
Z80FN _ld_ixl_d(void) MCR_LD(R_Z80IXL, R_Z80D)
Z80FN _ld_ixl_e(void) MCR_LD(R_Z80IXL, R_Z80E)
Z80FN _ld_ixl_ixh(void) MCR_LD(R_Z80IXL, R_Z80IXH)
Z80FN _ld_l_xix(void) MCR_LD_RXI(R_Z80L, R_Z80IX)
Z80FN _ld_ixl_a(void) MCR_LD(R_Z80IXL, R_Z80A)
Z80FN _ld_xix_b(void) MCR_LD_XIR(R_Z80B, R_Z80IX)
Z80FN _ld_xix_c(void) MCR_LD_XIR(R_Z80C, R_Z80IX)
Z80FN _ld_xix_d(void) MCR_LD_XIR(R_Z80D, R_Z80IX)
Z80FN _ld_xix_e(void) MCR_LD_XIR(R_Z80E, R_Z80IX)
Z80FN _ld_xix_h(void) MCR_LD_XIR(R_Z80H, R_Z80IX)
Z80FN _ld_xix_l(void) MCR_LD_XIR(R_Z80L, R_Z80IX)
Z80FN _ld_xix_a(void) MCR_LD_XIR(R_Z80A, R_Z80IX)
Z80FN _ld_a_ixh(void) MCR_LD(R_Z80A, R_Z80IXH)
Z80FN _ld_a_ixl(void) MCR_LD(R_Z80A, R_Z80IXL)
Z80FN _ld_a_xix(void) MCR_LD_RXI(R_Z80A, R_Z80IX)
Z80FN _add_a_ixh(void) MCR_ADD(R_Z80IXH)
Z80FN _add_a_ixl(void) MCR_ADD(R_Z80IXL)
Z80FN _add_a_xix(void) MCR_ADD_XI(R_Z80IX)
Z80FN _adc_a_ixh(void) MCR_ADC(R_Z80IXH)
Z80FN _adc_a_ixl(void) MCR_ADC(R_Z80IXL)
Z80FN _adc_a_xix(void) MCR_ADC_XI(R_Z80IX)
Z80FN _sub_ixh(void) MCR_SUB(R_Z80IXH)
Z80FN _sub_ixl(void) MCR_SUB(R_Z80IXL)
Z80FN _sub_xix(void) MCR_SUB_XI(R_Z80IX)
Z80FN _sbc_a_ixh(void) MCR_SBC(R_Z80IXH)
Z80FN _sbc_a_ixl(void) MCR_SBC(R_Z80IXL)
Z80FN _sbc_a_xix(void) MCR_SBC_XI(R_Z80IX)
Z80FN _and_ixh(void) MCR_AND(R_Z80IXH)
Z80FN _and_ixl(void) MCR_AND(R_Z80IXL)
Z80FN _and_xix(void) MCR_AND_XI(R_Z80IX)
Z80FN _xor_ixh(void) MCR_XOR(R_Z80IXH)
Z80FN _xor_ixl(void) MCR_XOR(R_Z80IXL)
Z80FN _xor_xix(void) MCR_XOR_XI(R_Z80IX)
Z80FN _or_ixh(void) MCR_OR(R_Z80IXH)
Z80FN _or_ixl(void) MCR_OR(R_Z80IXL)
Z80FN _or_xix(void) MCR_OR_XI(R_Z80IX)
Z80FN _cp_ixh(void) MCR_CP(R_Z80IXH)
Z80FN _cp_ixl(void) MCR_CP(R_Z80IXL)
Z80FN _cp_xix(void) MCR_CP_XI(R_Z80IX)
Z80FN _pop_ix(void) MCR_POP(R_Z80IX)
Z80FN _ex_xsp_ix(void) MCR_EX_XSP(R_Z80IX)
Z80FN _push_ix(void) MCR_PUSH(R_Z80IX)
Z80FN _jp_ix(void) MCR_LD_W(R_Z80PC, R_Z80IX)
Z80FN _ld_sp_ix(void) MCR_LD_W(R_Z80SP, R_Z80IX)
static const Z80OP z80c_ixp[256] = {
_no_op, _no_op, _no_op, _no_op, /* 00 */
_no_op, _no_op, _no_op, _no_op,
_no_op, _add_ix_bc, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op, /* 10 */
_no_op, _no_op, _no_op, _no_op,
_no_op, _add_ix_de, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op,
_no_op, _ld_ix_word, _ld_xword_ix, _inc_ix, /* 20 */
_inc_ixh, _dec_ixh, _ld_ixh_byte, _no_op,
_no_op, _add_ix_ix, _ld_ix_xword, _dec_ix,
_inc_ixl, _dec_ixl, _ld_ixl_byte, _no_op,
_no_op, _no_op, _no_op, _no_op, /* 30 */
_inc_xix, _dec_xix, _ld_xix_byte, _no_op,
_no_op, _add_ix_sp, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op, /* 40 */
_ld_b_ixh, _ld_b_ixl, _ld_b_xix, _no_op,
_no_op, _no_op, _no_op, _no_op,
_ld_c_ixh, _ld_c_ixl, _ld_c_xix, _no_op,
_no_op, _no_op, _no_op, _no_op, /* 50 */
_ld_d_ixh, _ld_d_ixl, _ld_d_xix, _no_op,
_no_op, _no_op, _no_op, _no_op,
_ld_e_ixh, _ld_e_ixl, _ld_e_xix, _no_op,
_ld_ixh_b, _ld_ixh_c, _ld_ixh_d, _ld_ixh_e, /* 60 */
_ld_nop, _ld_ixh_ixl, _ld_h_xix, _ld_ixh_a,
_ld_ixl_b, _ld_ixl_c, _ld_ixl_d, _ld_ixl_e,
_ld_ixl_ixh, _ld_nop, _ld_l_xix, _ld_ixl_a,
_ld_xix_b, _ld_xix_c, _ld_xix_d, _ld_xix_e, /* 70 */
_ld_xix_h, _ld_xix_l, _no_op, _ld_xix_a,
_no_op, _no_op, _no_op, _no_op,
_ld_a_ixh, _ld_a_ixl, _ld_a_xix, _no_op,
_no_op, _no_op, _no_op, _no_op, /* 80 */
_add_a_ixh, _add_a_ixl, _add_a_xix, _no_op,
_no_op, _no_op, _no_op, _no_op,
_adc_a_ixh, _adc_a_ixl, _adc_a_xix, _no_op,
_no_op, _no_op, _no_op, _no_op, /* 90 */
_sub_ixh, _sub_ixl, _sub_xix, _no_op,
_no_op, _no_op, _no_op, _no_op,
_sbc_a_ixh, _sbc_a_ixl, _sbc_a_xix, _no_op,
_no_op, _no_op, _no_op, _no_op, /* a0 */
_and_ixh, _and_ixl, _and_xix, _no_op,
_no_op, _no_op, _no_op, _no_op,
_xor_ixh, _xor_ixl, _xor_xix, _no_op,
_no_op, _no_op, _no_op, _no_op, /* b0 */
_or_ixh, _or_ixl, _or_xix, _no_op,
_no_op, _no_op, _no_op, _no_op,
_cp_ixh, _cp_ixl, _cp_xix, _no_op,
_no_op, _no_op, _no_op, _no_op, /* c0 */
_no_op, _no_op, _no_op, _no_op,
_no_op, _no_op, _no_op, z80c_ixcb,
_no_op, _no_op, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op, /* d0 */
_no_op, _no_op, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op,
_no_op, _pop_ix, _no_op, _ex_xsp_ix, /* e0 */
_no_op, _push_ix, _no_op, _no_op,
_no_op, _jp_ix, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op, /* f0 */
_no_op, _no_op, _no_op, _no_op,
_no_op, _ld_sp_ix, _no_op, _no_op,
_no_op, _no_op, _no_op, _no_op
};
void z80c_ix(void) {
UINT tmp;
R_Z80R++;
GET_PC_BYTE(tmp);
Z80_COUNT(cycles_xx[tmp]);
z80c_ixp[tmp]();
}

Some files were not shown because too many files have changed in this diff Show More