mirror of
https://github.com/libretro/xmil-libretro.git
synced 2024-11-23 08:09:42 +00:00
add nds-win32 simulation project
This commit is contained in:
parent
91661eadec
commit
fadc6cd6d9
48
nds/bss.x86
Normal file
48
nds/bss.x86
Normal 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
63
nds/fdd/d88head.h
Normal 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
113
nds/fdd/fdd_2d.c
Normal 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
12
nds/fdd/fdd_2d.h
Normal 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
256
nds/fdd/fdd_d88.c
Normal 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
12
nds/fdd/fdd_d88.h
Normal 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
8
nds/fdd/fdd_mtr.h
Normal 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
141
nds/fdd/fddfile.c
Normal 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
118
nds/fdd/fddfile.h
Normal 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
63
nds/ipcxfer.h
Normal 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
96
nds/joymng.cpp
Normal 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
5
nds/joymng.h
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
void joymng_setflags();
|
||||
|
||||
#define joymng_getstat() (0xff)
|
||||
|
11
nds/mousemng.cpp
Normal file
11
nds/mousemng.cpp
Normal 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
12
nds/mousemng.h
Normal 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
402
nds/patch/ctc.c
Normal 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
887
nds/patch/fdc.c
Normal 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
20
nds/patch/font.h
Normal 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
304
nds/patch/iocore.c
Normal 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
65
nds/patch/memio.c
Normal 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
127
nds/patch/ppi.c
Normal 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
155
nds/patch/sndboard.c
Normal 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
298
nds/patch/subcpu.c
Normal 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
162
nds/patch/vramio.c
Normal 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
5
nds/resource.h
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
extern const unsigned int g_sDemoBmp[];
|
||||
|
||||
extern const unsigned short g_sDemoPal[];
|
||||
|
194
nds/softkbd7.cpp
Normal file
194
nds/softkbd7.cpp
Normal 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
6
nds/softkbd7.h
Normal 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
34
nds/softkbd9.cpp
Normal 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
4
nds/softkbd9.h
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
void softkbd9_initialize(void);
|
||||
void softkbd9_sync(void);
|
||||
|
392
nds/sound/nds7psg.cpp
Normal file
392
nds/sound/nds7psg.cpp
Normal 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
51
nds/sound/nds7psg.h
Normal 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
67
nds/sound/nds9psg.cpp
Normal 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
46
nds/sound/nds9psg.h
Normal 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
8
nds/sound/sndctrl.h
Normal 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
17
nds/sound/sound.h
Normal 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
48
nds/sysmng.h
Normal 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
13
nds/timemng.cpp
Normal 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
28
nds/timemng.h
Normal 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
214
nds/vram/make15.cpp
Normal 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
237
nds/vram/makeatr.cpp
Normal 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
78
nds/vram/makec16.cpp
Normal 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
58
nds/vram/makec8.cpp
Normal 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
60
nds/vram/makecs.cpp
Normal 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
215
nds/vram/makemix.cpp
Normal 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
379
nds/vram/makescrn.cpp
Normal 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
82
nds/vram/makescrn.h
Normal 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
110
nds/vram/makesub.cpp
Normal 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
68
nds/vram/makesub.h
Normal 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
478
nds/vram/maketxtl.cpp
Normal 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
98
nds/vram/palettes.cpp
Normal 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
17
nds/vram/palettes.h
Normal 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
75
nds/vram/vram.h
Normal 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
56
nds/vram/vsyncff.cpp
Normal 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
14
nds/vram/vsyncff.h
Normal 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
83
nds/win32s/compiler.h
Normal 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
285
nds/win32s/dosio.cpp
Normal 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
78
nds/win32s/dosio.h
Normal 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
195
nds/win32s/extrom.cpp
Normal 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
25
nds/win32s/extrom.h
Normal 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
34
nds/win32s/libnds.h
Normal 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
17
nds/win32s/ndsconsole.cpp
Normal 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
4
nds/win32s/ndsconsole.h
Normal 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
8
nds/win32s/ndscore.cpp
Normal 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
16
nds/win32s/ndscore.h
Normal 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
39
nds/win32s/ndsdma.cpp
Normal 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
3
nds/win32s/ndsdma.h
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
void dmaCopy(LPCVOID lpvSrc, LPVOID lpvDst, int nSize);
|
||||
|
63
nds/win32s/ndsinput.cpp
Normal file
63
nds/win32s/ndsinput.cpp
Normal 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
28
nds/win32s/ndsinput.h
Normal 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
6
nds/win32s/ndsipc.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "compiler.h"
|
||||
#include "libnds.h"
|
||||
|
||||
|
||||
UINT8 g_sIPC[0x1000];
|
||||
|
75
nds/win32s/ndsipc.h
Normal file
75
nds/win32s/ndsipc.h
Normal 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
16
nds/win32s/ndsirq.cpp
Normal 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
33
nds/win32s/ndsirq.h
Normal 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
5
nds/win32s/ndsmem.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "compiler.h"
|
||||
#include "libnds.h"
|
||||
|
||||
unsigned char __ipcbase[0x1000];
|
||||
|
5
nds/win32s/ndsmem.h
Normal file
5
nds/win32s/ndsmem.h
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
extern unsigned char __ipcbase[0x1000];
|
||||
|
||||
#define IPCBASE __ipcbase
|
||||
|
16
nds/win32s/ndspower.h
Normal file
16
nds/win32s/ndspower.h
Normal 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
26
nds/win32s/ndsreg.cpp
Normal 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
101
nds/win32s/ndsreg.h
Normal 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
5
nds/win32s/ndssound.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "compiler.h"
|
||||
#include "libnds.h"
|
||||
|
||||
tagNdsSoundReg s_ndssound;
|
||||
|
43
nds/win32s/ndssound.h
Normal file
43
nds/win32s/ndssound.h
Normal 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
10
nds/win32s/ndsswi.cpp
Normal 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
3
nds/win32s/ndsswi.h
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
void swiWaitForVBlank(void);
|
||||
|
141
nds/win32s/ndssys.cpp
Normal file
141
nds/win32s/ndssys.cpp
Normal 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 ® = 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
9
nds/win32s/ndssys.h
Normal 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
13
nds/win32s/ndstouch.cpp
Normal 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
17
nds/win32s/ndstouch.h
Normal 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
516
nds/win32s/ndsvideo.cpp
Normal 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
189
nds/win32s/ndsvideo.h
Normal 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
16
nds/win32s/trace.cpp
Normal 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
25
nds/win32s/trace.h
Normal 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
91
nds/xmil7.cpp
Normal 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
1
nds/xmil7.h
Normal file
@ -0,0 +1 @@
|
||||
|
374
nds/xmil9.cpp
Normal file
374
nds/xmil9.cpp
Normal 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
20
nds/xmil9.h
Normal 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
452
nds/xmilw32.dsp
Normal 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
29
nds/xmilw32.dsw
Normal 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
207
z80ac/z80c.c
Normal 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
61
z80ac/z80c.h
Normal 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
612
z80ac/z80c.mcr
Normal 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
273
z80ac/z80c_cb.c
Normal 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
98
z80ac/z80c_i.mcr
Normal 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
215
z80ac/z80c_ix.c
Normal 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
Loading…
Reference in New Issue
Block a user