First commit with most sources
This commit is contained in:
174
mmvm/dispbios.cpp
Normal file
174
mmvm/dispbios.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "../mmage/mmage.h"
|
||||
#include "mmvm.h"
|
||||
#include "wwbios.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../wonx/wonx_include/disp.h"
|
||||
}
|
||||
|
||||
enum {
|
||||
DISPLAY_CONTROL = 0,
|
||||
DISPLAY_STATUS,
|
||||
FONT_SET_MONODATA,
|
||||
FONT_SET_COLORDATA,
|
||||
FONT_GET_DATA,
|
||||
FONT_SET_COLOR,
|
||||
FONT_GET_COLOR,
|
||||
SCREEN_SET_CHAR,
|
||||
SCREEN_GET_CHAR,
|
||||
SCREEN_FILL_CHAR,
|
||||
SCREEN_FILL_ATTR,
|
||||
SPRITE_SET_RANGE,
|
||||
SPRITE_SET_CHAR,
|
||||
SPRITE_GET_CHAR,
|
||||
SPRITE_SET_LOCATION,
|
||||
SPRITE_GET_LOCATION,
|
||||
SPRITE_SET_CHAR_LOCATION,
|
||||
SPRITE_GET_CHAR_LOCATION,
|
||||
SPRITE_SET_DATA,
|
||||
SCREEN_SET_SCROLL,
|
||||
SCREEN_GET_SCROLL,
|
||||
SCREEN2_SET_WINDOW,
|
||||
SCREEN2_GET_WINDOW,
|
||||
SPRITE_SET_WINDOW,
|
||||
SPRITE_GET_WINDOW,
|
||||
PALETTE_SET_COLOR,
|
||||
PALETTE_GET_COLOR,
|
||||
LCD_SET_COLOR,
|
||||
LCD_GET_COLOR,
|
||||
LCD_SET_SEGMENTS,
|
||||
LCD_GET_SEGMENTS,
|
||||
LCD_SET_SLEEP,
|
||||
LCD_GET_SLEEP,
|
||||
SCREEN_SET_VRAM,
|
||||
SPRITE_SET_VRAM,
|
||||
};
|
||||
|
||||
void disp_handler(int func_no) {
|
||||
int tmp;
|
||||
|
||||
switch(func_no) {
|
||||
case DISPLAY_CONTROL:
|
||||
display_control(wregs[BX]);
|
||||
break;
|
||||
case DISPLAY_STATUS:
|
||||
wregs[AX] = display_status();
|
||||
break;
|
||||
case FONT_SET_MONODATA:
|
||||
font_set_monodata(wregs[BX], wregs[CX], c_ds + wregs[DX]);
|
||||
break;
|
||||
case FONT_SET_COLORDATA:
|
||||
font_set_colordata(wregs[BX], wregs[CX], c_ds + wregs[DX]);
|
||||
break;
|
||||
case FONT_GET_DATA:
|
||||
font_get_data(wregs[BX], wregs[CX], c_ds + wregs[DX]);
|
||||
break;
|
||||
case FONT_SET_COLOR:
|
||||
font_set_color(wregs[BX]);
|
||||
break;
|
||||
case FONT_GET_COLOR:
|
||||
wregs[AX] = font_get_color();
|
||||
break;
|
||||
case SCREEN_SET_CHAR:
|
||||
screen_set_char(*bregs[AL], *bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH],
|
||||
(unsigned short *)(c_ds + wregs[DX]));
|
||||
break;
|
||||
case SCREEN_GET_CHAR:
|
||||
screen_get_char(*bregs[AL], *bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH],
|
||||
(unsigned short *)(c_ds + wregs[DX]));
|
||||
break;
|
||||
case SCREEN_FILL_CHAR:
|
||||
screen_fill_char(*bregs[AL], *bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH], wregs[DX]);
|
||||
break;
|
||||
case SCREEN_FILL_ATTR:
|
||||
screen_fill_attr(*bregs[AL], *bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH], wregs[DX], wregs[SI]);
|
||||
break;
|
||||
case SPRITE_SET_RANGE:
|
||||
sprite_set_range(wregs[BX], wregs[CX]);
|
||||
break;
|
||||
case SPRITE_SET_CHAR:
|
||||
sprite_set_char(wregs[BX], wregs[CX]);
|
||||
break;
|
||||
case SPRITE_GET_CHAR:
|
||||
wregs[AX] = sprite_get_char(wregs[BX]);
|
||||
break;
|
||||
case SPRITE_SET_LOCATION:
|
||||
sprite_set_location(wregs[BX], *bregs[DL], *bregs[DH]);
|
||||
break;
|
||||
case SPRITE_GET_LOCATION:
|
||||
wregs[AX] = sprite_get_location(wregs[BX]);
|
||||
break;
|
||||
case SPRITE_SET_CHAR_LOCATION:
|
||||
sprite_set_char_location(wregs[BX], wregs[CX], *bregs[DL], *bregs[DH]);
|
||||
break;
|
||||
case SPRITE_GET_CHAR_LOCATION:
|
||||
tmp = sprite_get_char_location(wregs[BX]);
|
||||
wregs[DX] = (tmp >> 16) & 0xffff;
|
||||
wregs[AX] = tmp & 0xffff;
|
||||
break;
|
||||
case SPRITE_SET_DATA:
|
||||
sprite_set_data(wregs[BX], wregs[CX], (unsigned long *)(c_ds + wregs[DX]));
|
||||
break;
|
||||
case SCREEN_SET_SCROLL:
|
||||
screen_set_scroll(*bregs[AL], *bregs[BL], *bregs[BH]);
|
||||
break;
|
||||
case SCREEN_GET_SCROLL:
|
||||
wregs[AX] = screen_get_scroll(*bregs[AL]);
|
||||
break;
|
||||
case SCREEN2_SET_WINDOW:
|
||||
screen2_set_window(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH]);
|
||||
break;
|
||||
case SCREEN2_GET_WINDOW:
|
||||
tmp = screen2_get_window();
|
||||
wregs[DX] = (tmp >> 16) & 0xffff;
|
||||
wregs[AX] = tmp & 0xffff;
|
||||
break;
|
||||
case SPRITE_SET_WINDOW:
|
||||
sprite_set_window(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH]);
|
||||
break;
|
||||
case SPRITE_GET_WINDOW:
|
||||
tmp = sprite_get_window();
|
||||
wregs[DX] = (tmp >> 16) & 0xffff;
|
||||
wregs[AX] = tmp & 0xffff;
|
||||
break;
|
||||
case PALETTE_SET_COLOR:
|
||||
palette_set_color(wregs[BX], wregs[CX]);
|
||||
break;
|
||||
case PALETTE_GET_COLOR:
|
||||
wregs[AX] = palette_get_color(wregs[BX]);
|
||||
break;
|
||||
case LCD_SET_COLOR:
|
||||
lcd_set_color(wregs[BX], wregs[CX]);
|
||||
break;
|
||||
case LCD_GET_COLOR:
|
||||
tmp = lcd_get_color();
|
||||
wregs[DX] = (tmp >> 16) & 0xffff;
|
||||
wregs[AX] = tmp & 0xffff;
|
||||
break;
|
||||
case LCD_SET_SEGMENTS:
|
||||
// lcd_set_segments(wregs[BX]);
|
||||
mmvm->lcdseg = wregs[BX];
|
||||
InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
|
||||
UpdateWindow(wonw32ctx->hWnd);
|
||||
break;
|
||||
case LCD_GET_SEGMENTS:
|
||||
// wregs[AX] = lcd_get_segments();
|
||||
wregs[AX] = mmvm->lcdseg;
|
||||
break;
|
||||
case LCD_SET_SLEEP:
|
||||
lcd_set_sleep(wregs[BX]);
|
||||
break;
|
||||
case LCD_GET_SLEEP:
|
||||
wregs[AX] = lcd_get_sleep();
|
||||
break;
|
||||
case SCREEN_SET_VRAM:
|
||||
screen_set_vram(*bregs[AL], wregs[BX]);
|
||||
break;
|
||||
case SPRITE_SET_VRAM:
|
||||
sprite_set_vram(wregs[BX]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
745
mmvm/filesys.cpp
Normal file
745
mmvm/filesys.cpp
Normal file
@@ -0,0 +1,745 @@
|
||||
#ifdef _DEBUG
|
||||
#include "../mmage/mmage.h" // for ShowError()
|
||||
#endif
|
||||
|
||||
#include "../mmage/preference.h"
|
||||
#include "filesys.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if defined(_MBCS)
|
||||
#define _tmakepath _makepath
|
||||
#define _tsplitpath _splitpath
|
||||
#elif defined(_UNICODE)
|
||||
#define _tmakepath _wmakepath
|
||||
#define _tsplitpath _wplitpath
|
||||
#else
|
||||
#define _tmakepath _makepath
|
||||
#define _tsplitpath _splitpath
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern LPMMVM mmvm;
|
||||
|
||||
typedef struct {
|
||||
LPTSTR rom0names[ROM0FS_NUM_ENTRIES];
|
||||
LPTSTR ram0names[RAM0FS_NUM_ENTRIES];
|
||||
HANDLE fd[OPEN_MAX];
|
||||
TCHAR rom0dirname[MAX_PATH];
|
||||
TCHAR ram0dirname[MAX_PATH];
|
||||
} FILETABLE, *LPFILETABLE;
|
||||
|
||||
static TCHAR rom0names[ROM0FS_NUM_ENTRIES][MAX_PATH + 1];
|
||||
static TCHAR ram0names[RAM0FS_NUM_ENTRIES][MAX_PATH + 1];
|
||||
|
||||
static FILETABLE ftable_struct;
|
||||
static LPFILETABLE ftable = &ftable_struct;
|
||||
|
||||
static void InitFent(WW_FS fs);
|
||||
static WW_FARPTR wwfs_entries(WW_FS fs);
|
||||
static WW_INT wwfs_n_entries(WW_FS fs);
|
||||
static WW_INT wwfs_getent(WW_FS fs, WW_INT n, WW_FENT_T *fep);
|
||||
static WW_INT wwfs_findent(WW_FS fs, char *fname, WW_FENT_T *fep);
|
||||
static WW_FARPTR wwfs_mmap(WW_FS fs, char *fname);
|
||||
static WW_INT wwfs_open(WW_FS fs, char *fname, WW_INT mode, WW_INT perms);
|
||||
static WW_INT wwfs_close(WW_INT fd);
|
||||
static WW_INT wwfs_read(WW_INT fd, char *buf, WW_INT len);
|
||||
static WW_INT wwfs_write(WW_INT fd, char *buf, WW_INT len);
|
||||
static WW_LONG wwfs_lseek(WW_INT fd, WW_LONG offset, WW_INT origin);
|
||||
static WW_INT wwfs_chmod(WW_FS fs, char *fname, WW_INT mode);
|
||||
static WW_INT wwfs_freeze(WW_FS fs, char *fname);
|
||||
static WW_INT wwfs_melt(WW_FS fs, char *fname);
|
||||
static WW_INT wwfs_creat(WW_FS fs, WW_FENT_T *fep);
|
||||
static WW_INT wwfs_unlink(WW_FS fs, char *fname);
|
||||
static WW_INT wwfs_newfs(WW_FS fs);
|
||||
static WW_INT wwfs_defrag(WW_FS fs);
|
||||
static WW_LONG wwfs_space(WW_FS fs);
|
||||
|
||||
// fs からファイル名 fname のエントリを取得(内部関数)
|
||||
static WW_FENT_T *findent(WW_FS fs, char *fname, WW_INT *n);
|
||||
|
||||
void InitFilesys(LPMMVM mmvm) {
|
||||
HANDLE ffile;
|
||||
TCHAR ffind[MAX_PATH + 1];
|
||||
TCHAR w32path[MAX_PATH + 1];
|
||||
WIN32_FIND_DATA fdata;
|
||||
TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR];
|
||||
int i;
|
||||
|
||||
// initialize file entries
|
||||
for(i = 0; i < ROOTFS_NUM_ENTRIES; i++) {
|
||||
InitFent(&(mmvm->swork->_root_fs_entries[i]));
|
||||
}
|
||||
for(i = 0; i < ROM0FS_NUM_ENTRIES; i++) {
|
||||
InitFent(&(mmvm->swork->_rom0_fs_entries[i]));
|
||||
ftable->rom0names[i] = &rom0names[i][0];
|
||||
}
|
||||
for(i = 0; i < RAM0FS_NUM_ENTRIES; i++) {
|
||||
InitFent(&(mmvm->swork->_ram0_fs_entries[i]));
|
||||
ftable->ram0names[i] = &ram0names[i][0];
|
||||
}
|
||||
|
||||
// setup root fs
|
||||
for(i = 0; i < DIRENT_NUM; i++) {
|
||||
mmvm->swork->_root_fs_entries[i].mode = FMODE_DIR|FMODE_R|FMODE_W|FMODE_X;
|
||||
mmvm->swork->_root_fs_entries[i].handler.il = GETFARPTR(mmvm->il->fs);
|
||||
}
|
||||
strcpy(mmvm->swork->_root_fs_entries[DIRENT_ROOT].name, ".");
|
||||
mmvm->swork->_root_fs_entries[DIRENT_ROOT].count = DIRENT_NUM;
|
||||
strcpy(mmvm->swork->_root_fs_entries[DIRENT_KERN].name, "kern");
|
||||
mmvm->swork->_root_fs_entries[DIRENT_KERN].count = 0;
|
||||
strcpy(mmvm->swork->_root_fs_entries[DIRENT_ROM0].name, "rom0");
|
||||
mmvm->swork->_root_fs_entries[DIRENT_ROM0].count = ROM0FS_NUM_ENTRIES;
|
||||
strcpy(mmvm->swork->_root_fs_entries[DIRENT_RAM0].name, "ram0");
|
||||
mmvm->swork->_root_fs_entries[DIRENT_RAM0].count = RAM0FS_NUM_ENTRIES;
|
||||
|
||||
// initialize file handles
|
||||
for(i = 0; i < OPEN_MAX; i++) {
|
||||
if(ftable->fd[i] != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(ftable->fd[i]);
|
||||
ftable->fd[i] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
mmvm->swork->_openfiles[i].omode = 0;
|
||||
}
|
||||
|
||||
// initialize /rom0 file entries
|
||||
i = 0;
|
||||
if(_tcslen(mmconfig->rom0dir)) {
|
||||
_stprintf(ffind, TEXT("%s\\*"), mmconfig->rom0dir);
|
||||
_tcscpy(ftable->rom0dirname, mmconfig->rom0dir);
|
||||
} else {
|
||||
_stprintf(ffind, TEXT("%s\\rom0\\*"), mmconfig->workingdir);
|
||||
_stprintf(ftable->rom0dirname, TEXT("%s\\rom0\\"), mmconfig->workingdir);
|
||||
}
|
||||
_tsplitpath(ffind, drive, dir, NULL, NULL);
|
||||
ffile = FindFirstFile(ffind, &fdata);
|
||||
if(ffile != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if(!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
strncpy(mmvm->swork->_rom0_fs_entries[i].name, fdata.cFileName, MAXFNAME);
|
||||
mmvm->swork->_rom0_fs_entries[i].count = 0;
|
||||
mmvm->swork->_rom0_fs_entries[i].mode = FMODE_R;
|
||||
mmvm->swork->_rom0_fs_entries[i].count = (WW_INT)fdata.nFileSizeLow / 128;
|
||||
mmvm->swork->_rom0_fs_entries[i].len = fdata.nFileSizeLow;
|
||||
_tmakepath(w32path, drive, dir, fdata.cFileName, NULL);
|
||||
_tcscpy(ftable->rom0names[i], w32path);
|
||||
i++;
|
||||
if(i > ROM0FS_NUM_ENTRIES)
|
||||
break;
|
||||
}
|
||||
} while(FindNextFile(ffile, &fdata));
|
||||
FindClose(ffile);
|
||||
}
|
||||
|
||||
// initialize /ram0 file entries
|
||||
i = 0;
|
||||
if(_tcslen(mmconfig->ram0dir)) {
|
||||
_stprintf(ffind, TEXT("%s\\*"), mmconfig->ram0dir);
|
||||
_tcscpy(ftable->ram0dirname, mmconfig->ram0dir);
|
||||
} else {
|
||||
_stprintf(ffind, TEXT("%s\\ram0\\*"), mmconfig->workingdir);
|
||||
_stprintf(ftable->ram0dirname, TEXT("%s\\ram0\\"), mmconfig->workingdir);
|
||||
}
|
||||
_tsplitpath(ffind, drive, dir, NULL, NULL);
|
||||
ffile = FindFirstFile(ffind, &fdata);
|
||||
if(ffile != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if(!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
strncpy(mmvm->swork->_ram0_fs_entries[i].name, fdata.cFileName, MAXFNAME);
|
||||
mmvm->swork->_ram0_fs_entries[i].count = 0;
|
||||
mmvm->swork->_ram0_fs_entries[i].mode = FMODE_R|FMODE_W;
|
||||
mmvm->swork->_ram0_fs_entries[i].count = (WW_INT)fdata.nFileSizeLow / 128;
|
||||
mmvm->swork->_ram0_fs_entries[i].len = fdata.nFileSizeLow;
|
||||
_tmakepath(w32path, drive, dir, fdata.cFileName, NULL);
|
||||
_tcscpy(ftable->ram0names[i], w32path);
|
||||
i++;
|
||||
if(i > RAM0FS_NUM_ENTRIES)
|
||||
break;
|
||||
}
|
||||
} while(FindNextFile(ffile, &fdata));
|
||||
FindClose(ffile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CloseFilesys() {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < OPEN_MAX; i++) {
|
||||
if(ftable->fd[i] != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(ftable->fd[i]);
|
||||
ftable->fd[i] = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
mmvm->swork->_openfiles[i].omode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleFsIL(LPMMVM mmvm) {
|
||||
WW_FARPTR p, ret;
|
||||
WW_INT n, mode, perms, fd, len, origin;
|
||||
WW_FS fs, fep;
|
||||
char *fname, *buf;
|
||||
WW_LONG offset;
|
||||
|
||||
switch(ip) {
|
||||
case 0: // ILInfo far *super._get_info();
|
||||
wregs[DX] = GETSEG(mmvm->il->fs);
|
||||
wregs[AX] = 0x0100;
|
||||
break;
|
||||
|
||||
case 1: // fent_t far *(far *_entries)(FS fs);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
ret = wwfs_entries(fs);
|
||||
wregs[AX] = ret.segoff.off;
|
||||
wregs[DX] = ret.segoff.seg;
|
||||
|
||||
break;
|
||||
|
||||
case 2: // int (far *_n_entries)(FS fs);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_n_entries(fs);
|
||||
|
||||
break;
|
||||
|
||||
case 3: // int (far *_getent)(FS fs, int n, fent_t far *fep);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
n = *((WW_INT *)GetArgAddr(4));
|
||||
p = *((WW_FARPTR *)GetArgAddr(6));
|
||||
fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_getent(fs, n, fep);
|
||||
|
||||
break;
|
||||
|
||||
case 4: // int (far *_findent)(FS fs, char far *fname, fent_t far *fep);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(4));
|
||||
fname = (char *)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(8));
|
||||
fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_findent(fs, fname, fep);
|
||||
|
||||
break;
|
||||
|
||||
case 5: // void far *(far *_mmap)(FS fs, char far *fname);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(4));
|
||||
fname = (char *)&memory[FARPTR2ADDR(p)];
|
||||
ret = wwfs_mmap(fs, fname);
|
||||
wregs[AX] = ret.segoff.off;
|
||||
wregs[DX] = ret.segoff.seg;
|
||||
|
||||
break;
|
||||
|
||||
case 6: // int (far *_open)(FS fs, char far *fname, int mode, int perms);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(4));
|
||||
fname = (char *)&memory[FARPTR2ADDR(p)];
|
||||
mode = *((WW_INT *)GetArgAddr(8));
|
||||
perms = *((WW_INT *)GetArgAddr(10));
|
||||
wregs[AX] = wwfs_open(fs, fname, mode, perms);
|
||||
|
||||
break;
|
||||
|
||||
case 7: // int (far *_close)(int fd);
|
||||
fd = *((WW_INT *)GetArgAddr(0));
|
||||
wregs[AX] = wwfs_close(fd);
|
||||
|
||||
break;
|
||||
|
||||
case 8: // int (far *_read)(int fd, char far *buf, int len);
|
||||
fd = *((WW_INT *)GetArgAddr(0));
|
||||
p = *((WW_FARPTR *)GetArgAddr(2));
|
||||
buf = (char *)&memory[FARPTR2ADDR(p)];
|
||||
len = *((WW_INT *)GetArgAddr(6));
|
||||
wregs[AX] = wwfs_read(fd, buf, len);
|
||||
|
||||
break;
|
||||
|
||||
case 9: // int (far *_write)(int fd, char far *buf, int len);
|
||||
fd = *((WW_INT *)GetArgAddr(0));
|
||||
p = *((WW_FARPTR *)GetArgAddr(2));
|
||||
buf = (char *)&memory[FARPTR2ADDR(p)];
|
||||
len = *((WW_INT *)GetArgAddr(6));
|
||||
wregs[AX] = wwfs_write(fd, buf, len);
|
||||
|
||||
break;
|
||||
|
||||
case 10: // long (far *_lseek)(int fd, long offset, int origin);
|
||||
fd = *((WW_INT *)GetArgAddr(0));
|
||||
offset = *((WW_LONG *)GetArgAddr(2));
|
||||
origin = *((WW_INT *)GetArgAddr(6));
|
||||
ret.farptr = wwfs_lseek(fd, offset, origin);
|
||||
wregs[AX] = ret.segoff.off;
|
||||
wregs[DX] = ret.segoff.seg;
|
||||
|
||||
break;
|
||||
|
||||
case 11: // int (far *_chmod)(FS fs, char far *fname, int mode);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(4));
|
||||
fname = (char *)&memory[FARPTR2ADDR(p)];
|
||||
mode = *((WW_INT *)GetArgAddr(8));
|
||||
wregs[AX] = wwfs_chmod(fs, fname, mode);
|
||||
|
||||
break;
|
||||
|
||||
case 12: // int (far *_freeze)(FS fs, char far *fname);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(4));
|
||||
fname = (char *)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_freeze(fs, fname);
|
||||
|
||||
break;
|
||||
|
||||
case 13: // int (far *_melt)(FS fs, char far *fname);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(4));
|
||||
fname = (char *)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_melt(fs, fname);
|
||||
|
||||
break;
|
||||
|
||||
case 14: // int (far *_creat)(FS fs, fent_t far *fep);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(4));
|
||||
fep = (WW_FENT_T *)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_creat(fs, fep);
|
||||
|
||||
break;
|
||||
|
||||
case 15: // int (far *_unlink)(FS fs, char *fname);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
p = *((WW_FARPTR *)GetArgAddr(4));
|
||||
fname = (char *)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_unlink(fs, fname);
|
||||
|
||||
break;
|
||||
|
||||
case 16: // int (far *_newfs)(FS fs);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_newfs(fs);
|
||||
|
||||
break;
|
||||
|
||||
case 17: // int (far *_defrag)(FS fs);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
wregs[AX] = wwfs_defrag(fs);
|
||||
|
||||
break;
|
||||
|
||||
case 18: // unsigned long (far *_space)(FS fs);
|
||||
p = *((WW_FARPTR *)GetArgAddr(0));
|
||||
fs = (WW_FS)&memory[FARPTR2ADDR(p)];
|
||||
ret.farptr = wwfs_space(fs);
|
||||
wregs[AX] = ret.segoff.off;
|
||||
wregs[DX] = ret.segoff.seg;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ILReturn();
|
||||
}
|
||||
|
||||
static WW_FARPTR wwfs_entries(WW_FS fs) {
|
||||
WW_FARPTR ret;
|
||||
|
||||
if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
|
||||
ret.segoff.seg = SRAMWORK_SEG;
|
||||
ret.segoff.off = (LPBYTE)(mmvm->swork->_root_fs_entries) - (LPBYTE)(mmvm->swork);
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
|
||||
ret.segoff.seg = SRAMWORK_SEG;
|
||||
ret.segoff.off = (LPBYTE)(mmvm->swork->_rom0_fs_entries) - (LPBYTE)(mmvm->swork);
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
|
||||
ret.segoff.seg = SRAMWORK_SEG;
|
||||
ret.segoff.off = (LPBYTE)(mmvm->swork->_ram0_fs_entries) - (LPBYTE)(mmvm->swork);
|
||||
} else {
|
||||
ret.farptr = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_n_entries(WW_FS fs) {
|
||||
WW_INT ret;
|
||||
|
||||
if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
|
||||
ret = ROOTFS_NUM_ENTRIES;
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
|
||||
ret = ROM0FS_NUM_ENTRIES;
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
|
||||
ret = RAM0FS_NUM_ENTRIES;
|
||||
} else {
|
||||
ret = E_FS_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_getent(WW_FS fs, WW_INT n, WW_FENT_T *fep) {
|
||||
WW_INT ret;
|
||||
|
||||
if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
|
||||
if(n >= 0 && n < ROM0FS_NUM_ENTRIES) {
|
||||
memcpy(fep, &(mmvm->swork->_root_fs_entries[n]), sizeof(WW_FENT_T));
|
||||
ret = E_FS_SUCCESS;
|
||||
} else {
|
||||
ret = E_FS_OUT_OF_BOUNDS;
|
||||
}
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
|
||||
if(n >= 0 && n < ROM0FS_NUM_ENTRIES) {
|
||||
memcpy(fep, &(mmvm->swork->_rom0_fs_entries[n]), sizeof(WW_FENT_T));
|
||||
ret = E_FS_SUCCESS;
|
||||
} else {
|
||||
ret = E_FS_OUT_OF_BOUNDS;
|
||||
}
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
|
||||
if(n >= 0 && n < RAM0FS_NUM_ENTRIES) {
|
||||
memcpy(fep, &(mmvm->swork->_ram0_fs_entries[n]), sizeof(WW_FENT_T));
|
||||
ret = E_FS_SUCCESS;
|
||||
} else {
|
||||
ret = E_FS_OUT_OF_BOUNDS;
|
||||
}
|
||||
} else {
|
||||
ret = E_FS_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_findent(WW_FS fs, char *fname, WW_FENT_T *fep) {
|
||||
WW_INT ret;
|
||||
WW_FENT_T *fents;
|
||||
WW_INT n;
|
||||
|
||||
fents = findent(fs, fname, &n);
|
||||
if(fents) {
|
||||
memcpy(fep, &fents, sizeof(WW_FENT_T));
|
||||
ret = E_FS_SUCCESS;
|
||||
} else {
|
||||
ret = E_FS_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_FARPTR wwfs_mmap(WW_FS fs, char *fname) {
|
||||
WW_FARPTR ret;
|
||||
|
||||
// not supported
|
||||
ret.farptr = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_open(WW_FS fs, char *fname, WW_INT mode, WW_INT perms) {
|
||||
WW_INT ret;
|
||||
WW_FENT_T *fents;
|
||||
LPTSTR *fntable;
|
||||
DWORD w32mode;
|
||||
LPTSTR w32fname;
|
||||
WW_INT nfent;
|
||||
WW_FENT_T newfile;
|
||||
|
||||
switch(mode) {
|
||||
case FMODE_R:
|
||||
w32mode = GENERIC_READ;
|
||||
break;
|
||||
case FMODE_W:
|
||||
w32mode = GENERIC_WRITE;
|
||||
break;
|
||||
case (FMODE_R|FMODE_W):
|
||||
w32mode = (GENERIC_READ|GENERIC_WRITE);
|
||||
break;
|
||||
default:
|
||||
return E_FS_PERMISSION_DENIED;
|
||||
break;
|
||||
}
|
||||
|
||||
if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
|
||||
fntable = ftable->rom0names;
|
||||
if(mode & FMODE_W)
|
||||
return E_FS_PERMISSION_DENIED;
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
|
||||
fntable = ftable->ram0names;
|
||||
} else {
|
||||
return E_FS_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
fents = findent(fs, fname, &nfent);
|
||||
if(!fents) {
|
||||
// ファイルが見つからなかったら新しいファイルを作る
|
||||
InitFent(&newfile);
|
||||
strncpy(newfile.name, fname, MAXPATHLEN);
|
||||
newfile.mode = mode;
|
||||
|
||||
if(wwfs_creat(fs, &newfile) != E_FS_SUCCESS)
|
||||
return E_FS_FILE_NOT_FOUND;
|
||||
|
||||
fents = findent(fs, fname, &nfent);
|
||||
if(!fents)
|
||||
return E_FS_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
w32fname = fntable[nfent];
|
||||
for(ret = 0; ret < OPEN_MAX; ret++) {
|
||||
if(ftable->fd[ret] == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret == OPEN_MAX) {
|
||||
ret = E_FS_ERROR;
|
||||
} else {
|
||||
ftable->fd[ret] = CreateFile(w32fname, w32mode, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(ftable->fd[ret] == INVALID_HANDLE_VALUE) {
|
||||
ret = E_FS_PERMISSION_DENIED;
|
||||
} else {
|
||||
mmvm->swork->_openfiles[ret].fs = (WW_FS)mmvm->cwfs.farptr;
|
||||
mmvm->swork->_openfiles[ret].fentp.segoff.seg = SRAMWORK_SEG;
|
||||
mmvm->swork->_openfiles[ret].fentp.segoff.off = (LPBYTE)&fents - (LPBYTE)mmvm->swork;
|
||||
mmvm->swork->_openfiles[ret].omode = mode;
|
||||
mmvm->swork->_openfiles[ret].fpos = 0;
|
||||
mmvm->swork->_openfiles[ret].flen = 0;
|
||||
mmvm->swork->_openfiles[ret].floc.farptr = 0;
|
||||
mmvm->swork->_openfiles[ret].count = 0;
|
||||
mmvm->swork->_openfiles[ret].pcb = 1;
|
||||
mmvm->swork->_openfiles[ret].driver.farptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_close(WW_INT fd) {
|
||||
WW_INT ret;
|
||||
|
||||
if(!(mmvm->swork->_openfiles[fd].omode))
|
||||
return E_FS_ERROR;
|
||||
|
||||
if(ftable->fd[fd] != INVALID_HANDLE_VALUE) {
|
||||
if(CloseHandle(ftable->fd[fd]))
|
||||
ret = E_FS_SUCCESS;
|
||||
else
|
||||
ret = E_FS_FILE_NOT_OPEN;
|
||||
} else {
|
||||
ret = E_FS_FILE_NOT_OPEN;
|
||||
}
|
||||
ftable->fd[fd] = INVALID_HANDLE_VALUE;
|
||||
mmvm->swork->_openfiles[fd].omode = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_read(WW_INT fd, char *buf, WW_INT len) {
|
||||
WW_INT ret;
|
||||
DWORD nbytes;
|
||||
|
||||
if(!(mmvm->swork->_openfiles[fd].omode))
|
||||
return E_FS_ERROR;
|
||||
|
||||
if(!(mmvm->swork->_openfiles[fd].omode & FMODE_R))
|
||||
return E_FS_PERMISSION_DENIED;
|
||||
|
||||
if(ReadFile(ftable->fd[fd], buf, len, &nbytes, NULL)) {
|
||||
ret = (WW_INT)nbytes;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_write(WW_INT fd, char *buf, WW_INT len) {
|
||||
WW_INT ret;
|
||||
DWORD nbytes;
|
||||
|
||||
if(!(mmvm->swork->_openfiles[fd].omode))
|
||||
return E_FS_ERROR;
|
||||
|
||||
if(!(mmvm->swork->_openfiles[fd].omode & FMODE_W))
|
||||
return E_FS_PERMISSION_DENIED;
|
||||
|
||||
if(WriteFile(ftable->fd[fd], buf, len, &nbytes, NULL)) {
|
||||
ret = (WW_INT)nbytes;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WW_LONG wwfs_lseek(WW_INT fd, WW_LONG offset, WW_INT origin) {
|
||||
WW_LONG ret;
|
||||
DWORD w32off, w32org;
|
||||
|
||||
if(!(mmvm->swork->_openfiles[fd].omode))
|
||||
return E_FS_ERROR;
|
||||
|
||||
switch(origin) {
|
||||
case 0:
|
||||
w32org = FILE_BEGIN;
|
||||
break;
|
||||
case 1:
|
||||
w32org = FILE_CURRENT;
|
||||
break;
|
||||
case 2:
|
||||
w32org = FILE_END;
|
||||
break;
|
||||
default:
|
||||
return E_FS_OUT_OF_BOUNDS;
|
||||
break;
|
||||
}
|
||||
|
||||
if(ftable->fd[fd] == INVALID_HANDLE_VALUE) {
|
||||
ret = E_FS_FILE_NOT_OPEN;
|
||||
} else {
|
||||
w32off = SetFilePointer(ftable->fd[fd], offset, NULL, w32org);
|
||||
if(w32off != 0xFFFFFFFF)
|
||||
ret = w32off;
|
||||
else
|
||||
ret = E_FS_OUT_OF_BOUNDS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
// not yet.
|
||||
static WW_INT wwfs_chmod(WW_FS fs, char *fname, WW_INT mode) {
|
||||
return E_FS_ERROR;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_freeze(WW_FS fs, char *fname) {
|
||||
return E_FS_ERROR;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_melt(WW_FS fs, char *fname) {
|
||||
return E_FS_ERROR;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_creat(WW_FS fs, WW_FENT_T *fep) {
|
||||
WW_FENT_T *fent;
|
||||
WW_INT n;
|
||||
HANDLE newfile;
|
||||
int i;
|
||||
|
||||
if(fs->mode & FMODE_DIR && strncmp(fs->name, "ram0", MAXPATHLEN))
|
||||
return E_FS_PERMISSION_DENIED;
|
||||
|
||||
if(findent(fs, fep->name, &n))
|
||||
return E_FS_ERROR;
|
||||
|
||||
fent = NULL;
|
||||
for(i = 0; i < RAM0FS_NUM_ENTRIES; i++) {
|
||||
if(mmvm->swork->_ram0_fs_entries[i].count == (WW_INT)-1) {
|
||||
fent = &(mmvm->swork->_ram0_fs_entries[i]);
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!fent)
|
||||
return E_FS_ERROR;
|
||||
|
||||
strcat(ftable->ram0names[n], ftable->ram0dirname);
|
||||
strcat(ftable->ram0names[n], fep->name);
|
||||
|
||||
newfile = CreateFile(ftable->ram0names[n], GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(newfile == INVALID_HANDLE_VALUE)
|
||||
return E_FS_ERROR;
|
||||
|
||||
CloseHandle(newfile);
|
||||
memcpy(fent, fep, sizeof(WW_FENT_T));
|
||||
fent->count = 0;
|
||||
|
||||
return E_FS_SUCCESS;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_unlink(WW_FS fs, char *fname) {
|
||||
WW_FENT_T *fent;
|
||||
WW_INT n;
|
||||
|
||||
if(fs->mode & FMODE_DIR && strncmp(fs->name, "ram0", MAXPATHLEN))
|
||||
return E_FS_PERMISSION_DENIED;
|
||||
|
||||
fent = findent(fs, fname, &n);
|
||||
if(!fent)
|
||||
return E_FS_FILE_NOT_FOUND;
|
||||
|
||||
if(!DeleteFile(ftable->ram0names[n]))
|
||||
return E_FS_ERROR;
|
||||
|
||||
fent->count = (WW_INT)-1;
|
||||
|
||||
return E_FS_SUCCESS;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_newfs(WW_FS fs) {
|
||||
return E_FS_ERROR;
|
||||
}
|
||||
|
||||
static WW_INT wwfs_defrag(WW_FS fs) {
|
||||
return E_FS_SUCCESS;
|
||||
}
|
||||
|
||||
static WW_LONG wwfs_space(WW_FS fs) {
|
||||
return 0x7fffffff;
|
||||
}
|
||||
|
||||
static WW_FENT_T *findent(WW_FS fs, char *fname, WW_INT *n) {
|
||||
int n_entries;
|
||||
WW_FENT_T *fents;
|
||||
int i;
|
||||
|
||||
if(fs->mode & FMODE_DIR && !strncmp(fs->name, ".", MAXPATHLEN)) {
|
||||
n_entries = ROOTFS_NUM_ENTRIES;
|
||||
fents = mmvm->swork->_root_fs_entries;
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "rom0", MAXPATHLEN)) {
|
||||
n_entries = ROM0FS_NUM_ENTRIES;
|
||||
fents = mmvm->swork->_rom0_fs_entries;
|
||||
} else if(fs->mode & FMODE_DIR && !strncmp(fs->name, "ram0", MAXPATHLEN)) {
|
||||
n_entries = RAM0FS_NUM_ENTRIES;
|
||||
fents = mmvm->swork->_ram0_fs_entries;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < n_entries; i++) {
|
||||
if(fents[i].count != -1 && !strncmp(fname, fents[i].name, MAXPATHLEN)) {
|
||||
*n = i;
|
||||
return &fents[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void InitFent(WW_FS fent) {
|
||||
strcpy(fent->name, "");
|
||||
strcpy(fent->info, "");
|
||||
fent->loc = 0;
|
||||
fent->len = 0;
|
||||
fent->count = (WW_INT)-1;
|
||||
fent->mode = 0;
|
||||
fent->mtime = 0;
|
||||
fent->handler.appid = 0;
|
||||
fent->resource = 0xffffffff;
|
||||
}
|
||||
|
||||
11
mmvm/filesys.h
Normal file
11
mmvm/filesys.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef _MMVM_FILESYS_H
|
||||
#define _MMVM_FILESYS_H
|
||||
|
||||
#include "mmvm.h"
|
||||
#include "wwstruct.h"
|
||||
|
||||
void InitFilesys(LPMMVM mmvm);
|
||||
void CloseFilesys();
|
||||
void HandleFsIL(LPMMVM mmvm);
|
||||
|
||||
#endif // #ifdef _MMVM_FILESYS_H
|
||||
109
mmvm/kanjifont.cpp
Normal file
109
mmvm/kanjifont.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include <stdio.h>
|
||||
#include "kanjifont.h"
|
||||
|
||||
#define NUM_OF_KANJIFONT 6877
|
||||
#define KANJIFONT_SIZE 8
|
||||
|
||||
static unsigned char kfonts[NUM_OF_KANJIFONT * KANJIFONT_SIZE];
|
||||
static unsigned char notfound[KANJIFONT_SIZE] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
|
||||
static int font_loaded;
|
||||
|
||||
int InitKanjiFont(char *fontfile) {
|
||||
FILE *fp;
|
||||
int c, i;
|
||||
|
||||
font_loaded = 0;
|
||||
fp = fopen(fontfile, "rb");
|
||||
|
||||
if(fp != NULL) {
|
||||
i = 0;
|
||||
while((c = fgetc(fp)) >= 0) {
|
||||
kfonts[i++] = (unsigned char)c;
|
||||
}
|
||||
if(i == NUM_OF_KANJIFONT * KANJIFONT_SIZE)
|
||||
font_loaded = 1;
|
||||
}
|
||||
|
||||
return font_loaded;
|
||||
}
|
||||
|
||||
unsigned char *GetKanjiFont(int u, int d) {
|
||||
int c;
|
||||
if (u > 0x9f) u -= 0x40;
|
||||
if (d > 0x7f) d--;
|
||||
d -= 0x40;
|
||||
u -= 0x81;
|
||||
c = u * 0xbc + d;
|
||||
|
||||
if(!font_loaded)
|
||||
return notfound;
|
||||
|
||||
if (c >= 7806) {
|
||||
c = -1;
|
||||
} else if(c >= 4418) { /* 第二水準漢字 */
|
||||
c = c + (0xda1 - 4418);
|
||||
} else if (c >= 4375) { /* なし */
|
||||
c = -1;
|
||||
} else if (c >= 1410) { /* 第一水準漢字 */
|
||||
c = c + (0x20c - 1410);
|
||||
} else if (c >= 690) { /* 禁止領域の文字 */
|
||||
c = -1;
|
||||
} else if (c >= 658) { /* 罫線素 */
|
||||
c = c + (0x1ec - 658);
|
||||
} else if (c >= 612) { /* ロシア小 */
|
||||
c = c + (0x1cb - 612);
|
||||
} else if (c >= 564) { /* ロシア大 */
|
||||
c = c + (0x1aa - 564);
|
||||
} else if (c >= 502) { /* ギリシャ小 */
|
||||
c = c + (0x192 - 502);
|
||||
} else if (c >= 470) { /* ギリシャ大*/
|
||||
c = c + (0x17a - 470);
|
||||
} else if (c >= 376) { /* カタカナ */
|
||||
c = c + (0x124 - 376);
|
||||
} else if (c >= 282) { /* ひらがな */
|
||||
c = c + (0xd1 - 282);
|
||||
} else if (c >= 252) { /* 英小文字 */
|
||||
c = c + (0xb7 - 252);
|
||||
} else if (c >= 220) { /* 英大文字 */
|
||||
c = c + (0x9d - 220);
|
||||
} else if (c >= 203) { /* 数字 */
|
||||
c = c + (0x93 - 203);
|
||||
} else if (c >= 187) { /* 記号(◯) */
|
||||
c = 0x92;
|
||||
} else if (c >= 175) { /* 記号(ʼn♯♭♪†‡¶) */
|
||||
c = c + (0x8a - 203);
|
||||
} else if (c >= 153) { /* 記号(∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬) */
|
||||
c = c + (0x7b - 153);
|
||||
} else if (c >= 135) { /* 記号(∧∨¬⇒⇔∀∃) */
|
||||
c = c + (0x74 - 135);
|
||||
} else if (c >= 119) { /* 記号(∈∋⊆⊇⊂⊃∪∩) */
|
||||
c = c + (0x6c - 119);
|
||||
} // else {} /* 記号(その他) */
|
||||
|
||||
if(c == -1)
|
||||
return notfound;
|
||||
else
|
||||
return kfonts + (c * KANJIFONT_SIZE);
|
||||
|
||||
}
|
||||
|
||||
void GetKanjiFont16(int code, unsigned char *font) {
|
||||
unsigned char *font8;
|
||||
int i, j;
|
||||
|
||||
font8 = GetKanjiFont((code >> 8) & 0xff, code & 0xff);
|
||||
for(i = 0; i < 8; i++) {
|
||||
font[i * 2 + 1] = 0;
|
||||
for(j = 0; j < 4; j++) {
|
||||
font[i * 2 + 1] <<= 2;
|
||||
if((font8[i] >> j) & 1)
|
||||
font[i * 2 + 1] |= 3; // (11)2
|
||||
}
|
||||
font[i * 2] = 0;
|
||||
for(j = 4; j < 8; j++) {
|
||||
font[i * 2] <<= 2;
|
||||
if((font8[i] >> j) & 1)
|
||||
font[i * 2] |= 3; // (11)2
|
||||
}
|
||||
}
|
||||
}
|
||||
16
mmvm/kanjifont.h
Normal file
16
mmvm/kanjifont.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _KANJIFONT_H
|
||||
#define _KANJIFONT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int InitKanjiFont(char *fontfile);
|
||||
unsigned char *GetKanjiFont(int u, int d);
|
||||
void GetKanjiFont16(int code, unsigned char *font);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
49
mmvm/keybios.cpp
Normal file
49
mmvm/keybios.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "../mmage/mmage.h"
|
||||
#include "wwbios.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../wonx/wonx_include/key.h"
|
||||
}
|
||||
|
||||
enum {
|
||||
KEY_PRESS_CHECK = 0,
|
||||
KEY_HIT_CHECK,
|
||||
KEY_WAIT,
|
||||
KEY_SET_REPEAT,
|
||||
KEY_GET_REPEAT,
|
||||
KEY_HIT_CHECK_WITH_REPEAT,
|
||||
};
|
||||
|
||||
void key_handler(int func_no) {
|
||||
WORD ret;
|
||||
|
||||
switch(func_no) {
|
||||
case KEY_PRESS_CHECK:
|
||||
wregs[AX] = key_press_check();
|
||||
break;
|
||||
case KEY_HIT_CHECK:
|
||||
wregs[AX] = key_hit_check();
|
||||
break;
|
||||
case KEY_WAIT:
|
||||
// return 値が 0 のときは ip を -2 して見かけ上 wait してるようにみせかける
|
||||
ret = key_wait();
|
||||
if(ret) {
|
||||
wregs[AX] = ret;
|
||||
} else {
|
||||
WaitForSingleObject(wonw32ctx->syncevent, INFINITE);
|
||||
ip = ip - 2;
|
||||
}
|
||||
break;
|
||||
case KEY_SET_REPEAT:
|
||||
key_set_repeat(*bregs[BL], *bregs[BH]);
|
||||
break;
|
||||
case KEY_GET_REPEAT:
|
||||
wregs[AX] = key_get_repeat();
|
||||
break;
|
||||
case KEY_HIT_CHECK_WITH_REPEAT:
|
||||
wregs[AX] = key_hit_check_with_repeat();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
574
mmvm/mmvm.cpp
Normal file
574
mmvm/mmvm.cpp
Normal file
@@ -0,0 +1,574 @@
|
||||
#include "../mmage/mmage.h"
|
||||
#include "../mmage/preference.h"
|
||||
|
||||
#include "../resource/resource.h"
|
||||
#include "wwstruct.h"
|
||||
#include "mmvm.h"
|
||||
#include "filesys.h"
|
||||
#include "kanjifont.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <process.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if defined(_MBCS)
|
||||
#define _tmakepath _makepath
|
||||
#define _tsplitpath _splitpath
|
||||
#elif defined(_UNICODE)
|
||||
#define _tmakepath _wmakepath
|
||||
#define _tsplitpath _wplitpath
|
||||
#else
|
||||
#define _tmakepath _makepath
|
||||
#define _tsplitpath _splitpath
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
IL は CS:ip が特定アドレスになったところでトラップすることで実現する
|
||||
|
||||
IlibIL は 0100:0000 に配置。
|
||||
IlibIL の関数は 0100:0000 から 1byte ずつ順に配置されているように見せる。
|
||||
_get_info() は 0100:0000
|
||||
_open() は 0100:0001
|
||||
_open_system() は 0100:0002
|
||||
という具合に。
|
||||
Ilib の ILInfo は 0100:0100 に配置。
|
||||
Ilib の ILInfo が指す文字列は 0100:(0100 + ILInfo のサイズ) に配置。
|
||||
なので IL の関数の数は(_get_info() を含めて) 0x0100 個まで。
|
||||
|
||||
ProcIL は 0200:0000 から、FsIL は 0300:0000 から同じように配置。
|
||||
こんなんでええんか?
|
||||
*/
|
||||
|
||||
#define MMVM_ILIBILADDR 0x01000000
|
||||
#define MMVM_PROCILADDR 0x02000000
|
||||
#define MMVM_FSILADDR 0x03000000
|
||||
|
||||
static MMVM_IL mmvmil_struct;
|
||||
static MMVM mmvm_struct;
|
||||
static MMVM_APPINFO appinfo_struct;
|
||||
|
||||
LPMMVM mmvm;
|
||||
BYTE *memory;
|
||||
|
||||
static void HandleIlibIL();
|
||||
static void HandleProcIL();
|
||||
|
||||
static LRESULT CALLBACK GetArgument(HWND, UINT, WPARAM, LPARAM);
|
||||
static void StartThread(LPVOID arg);
|
||||
|
||||
BOOL CreateVM() {
|
||||
LPBYTE rom0;
|
||||
TCHAR fontfile[MAX_PATH + 1];
|
||||
char drive[_MAX_DRIVE + 1];
|
||||
char dir[_MAX_DIR + 1];
|
||||
|
||||
mmvm = &mmvm_struct;
|
||||
mmvm->memory = memory = (BYTE *)malloc(MEMORYSIZE);
|
||||
if(!memory) {
|
||||
return FALSE;
|
||||
}
|
||||
memset(memory, 0, MEMORYSIZE);
|
||||
|
||||
mmvm->il = &mmvmil_struct;
|
||||
mmvm->appinfo = &appinfo_struct;
|
||||
|
||||
mmvm->il->il.farptr = MMVM_ILIBILADDR;
|
||||
strcpy(mmvm->il->ilinfo.className, "ILibIL");
|
||||
strcpy(mmvm->il->ilinfo.name, "ILibIL");
|
||||
strcpy(mmvm->il->ilinfo.version, "1.0");
|
||||
strcpy(mmvm->il->ilinfo.description, "MMVM default ILibIL");
|
||||
mmvm->il->ilinfo.depends = NULL;
|
||||
|
||||
mmvm->il->proc.farptr = MMVM_PROCILADDR;
|
||||
strcpy(mmvm->il->procinfo.className, "ProcIL");
|
||||
strcpy(mmvm->il->procinfo.name, "ProcIL");
|
||||
strcpy(mmvm->il->procinfo.version, "1.0");
|
||||
strcpy(mmvm->il->procinfo.description, "MMVM default ProcIL");
|
||||
mmvm->il->procinfo.depends = NULL;
|
||||
|
||||
mmvm->il->fs.farptr = MMVM_FSILADDR;
|
||||
strcpy(mmvm->il->fsinfo.className, "FsIL");
|
||||
strcpy(mmvm->il->fsinfo.name, "FsIL");
|
||||
strcpy(mmvm->il->fsinfo.version, "1.0");
|
||||
strcpy(mmvm->il->fsinfo.description, "MMVM default FsIL");
|
||||
mmvm->il->fsinfo.depends = NULL;
|
||||
|
||||
mmvm->swork = (LPWW_SRAMWork)&memory[SRAMWORK_SEG << 4];
|
||||
rom0 = (LPBYTE)&(mmvm->swork->_root_fs_entries[DIRENT_ROM0]);
|
||||
mmvm->cwfs.segoff.seg = SRAMWORK_SEG;
|
||||
mmvm->cwfs.segoff.off = rom0 - (LPBYTE)(mmvm->swork);
|
||||
|
||||
mmvm->lcdseg = 0;
|
||||
|
||||
GetModuleFileName(NULL, fontfile, MAX_PATH);
|
||||
_tsplitpath(fontfile, drive, dir, NULL, NULL);
|
||||
_tmakepath(fontfile, drive, dir, ELISA_FONTFILE, NULL);
|
||||
InitKanjiFont(fontfile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void InitVM() {
|
||||
LPWW_IlibIL ilil;
|
||||
LPWW_ProcIL procil;
|
||||
LPWW_FsIL fsil;
|
||||
LPWW_ILInfo ilinfo, procinfo, fsinfo;
|
||||
unsigned int tmp1;
|
||||
|
||||
init_cpu();
|
||||
sregs[CS] = APP_CSEG;
|
||||
sregs[DS] = APP_CSEG; // ここでは何に設定しても同じ
|
||||
sregs[ES] = APP_CSEG; // ここでは何に設定しても同じ
|
||||
sregs[SS] = STACK_SEG;
|
||||
ip = 0;
|
||||
c_cs = SegToMemPtr(CS);
|
||||
c_ds = SegToMemPtr(DS);
|
||||
c_es = SegToMemPtr(ES);
|
||||
c_stack = c_ss = SegToMemPtr(SS);
|
||||
|
||||
// set return address
|
||||
tmp1 = (WORD)(ReadWord(&wregs[SP]) - 2);
|
||||
PutMemW(c_stack, tmp1, 0x0010);
|
||||
tmp1 = (WORD)(tmp1 - 2);
|
||||
PutMemW(c_stack, tmp1, 0x0000);
|
||||
WriteWord(&wregs[SP], tmp1);
|
||||
|
||||
ilil = (LPWW_IlibIL)&memory[FARPTR2ADDR(mmvm->il->il)];
|
||||
ilil->super.n_methods = 2;
|
||||
ilil->super.link_pos.farptr = GETFARPTR(mmvm->il->il);
|
||||
ilil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0);
|
||||
ilil->_open.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 1);
|
||||
ilil->_open_system.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 2);
|
||||
ilinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->il) << 4 | 0x0100];
|
||||
memcpy((LPBYTE)ilinfo + sizeof(WW_ILInfo), &mmvm->il->ilinfo, sizeof(mmvm->il->ilinfo));
|
||||
ilinfo->className.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) );
|
||||
ilinfo->name.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 32);
|
||||
ilinfo->version.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 64);
|
||||
ilinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->il), 0x0100 + sizeof(WW_ILInfo) + 96);
|
||||
ilinfo->depends.farptr = SEGOFF2FARPTR(0, 0);
|
||||
|
||||
procil = (LPWW_ProcIL)&memory[FARPTR2ADDR(mmvm->il->proc)];
|
||||
procil->super.n_methods = 8;
|
||||
procil->super.link_pos.farptr = GETFARPTR(mmvm->il->proc);
|
||||
procil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0);
|
||||
procil->_load.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 1);
|
||||
procil->_run.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 2);
|
||||
procil->_exec.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 3);
|
||||
procil->_exit.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 4);
|
||||
procil->_yield.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 5);
|
||||
procil->_suspend.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 6);
|
||||
procil->_resume.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 7);
|
||||
procil->_swap.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 8);
|
||||
procinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->proc) << 4 | 0x0100];
|
||||
memcpy((LPBYTE)procinfo + sizeof(WW_ILInfo), &mmvm->il->procinfo, sizeof(mmvm->il->procinfo));
|
||||
procinfo->className.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) );
|
||||
procinfo->name.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 32);
|
||||
procinfo->version.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 64);
|
||||
procinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->proc), 0x0100 + sizeof(WW_ILInfo) + 96);
|
||||
procinfo->depends.farptr = SEGOFF2FARPTR(0, 0);
|
||||
|
||||
fsil = (LPWW_FsIL)&memory[FARPTR2ADDR(mmvm->il->fs)];
|
||||
fsil->super.link_pos.farptr = GETFARPTR(mmvm->il->il);
|
||||
fsil->super.n_methods = 18;
|
||||
fsil->super._get_info.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0);
|
||||
fsil->_entries.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 1);
|
||||
fsil->_n_entries.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 2);
|
||||
fsil->_getent.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 3);
|
||||
fsil->_findent.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 4);
|
||||
fsil->_mmap.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 5);
|
||||
fsil->_open.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 6);
|
||||
fsil->_close.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 7);
|
||||
fsil->_read.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 8);
|
||||
fsil->_write.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 9);
|
||||
fsil->_lseek.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 10);
|
||||
fsil->_chmod.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 11);
|
||||
fsil->_freeze.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 12);
|
||||
fsil->_melt.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 13);
|
||||
fsil->_creat.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 14);
|
||||
fsil->_unlink.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 15);
|
||||
fsil->_newfs.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 16);
|
||||
fsil->_defrag.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 17);
|
||||
fsil->_space.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 18);
|
||||
fsinfo = (LPWW_ILInfo)&memory[GETSEG(mmvm->il->fs) << 4 | 0x0100];
|
||||
memcpy((LPBYTE)fsinfo + sizeof(WW_ILInfo), &mmvm->il->fsinfo, sizeof(mmvm->il->fsinfo));
|
||||
fsinfo->className.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) );
|
||||
fsinfo->name.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 32);
|
||||
fsinfo->version.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 64);
|
||||
fsinfo->description.farptr = SEGOFF2FARPTR(GETSEG(mmvm->il->fs), 0x0100 + sizeof(WW_ILInfo) + 96);
|
||||
fsinfo->depends.farptr = SEGOFF2FARPTR(0, 0);
|
||||
|
||||
mmvm->lcdseg = 0;
|
||||
|
||||
mmvm->appinfo->loadended = FALSE;
|
||||
mmvm->appinfo->maincalled = FALSE;
|
||||
}
|
||||
|
||||
void UpdateVM() {
|
||||
LPWW_PCB pcb;
|
||||
unsigned int tmp1;
|
||||
WORD argptr;
|
||||
WORD argc;
|
||||
WORD args[256];
|
||||
int i;
|
||||
BOOL quote;
|
||||
|
||||
if(sregs[CS] == GETSEG(mmvm->il->il)) {
|
||||
HandleIlibIL();
|
||||
return;
|
||||
}
|
||||
if(sregs[CS] == GETSEG(mmvm->il->proc)) {
|
||||
HandleProcIL();
|
||||
return;
|
||||
}
|
||||
if(sregs[CS] == GETSEG(mmvm->il->fs)) {
|
||||
HandleFsIL(mmvm);
|
||||
return;
|
||||
}
|
||||
|
||||
if(sregs[CS] == 0x0010 && ip == 0x0000) { // if load routine returned
|
||||
mmvm->appinfo->loadended = TRUE;
|
||||
ip = wregs[AX];
|
||||
sregs[CS] = wregs[DX];
|
||||
c_cs = SegToMemPtr(CS);
|
||||
c_ds = SegToMemPtr(DS);
|
||||
c_es = SegToMemPtr(ES);
|
||||
c_stack = c_ss = SegToMemPtr(SS);
|
||||
|
||||
pcb = (LPWW_PCB)SegToMemPtr(ES);
|
||||
// init dseg_start
|
||||
pcb->pid = 1;
|
||||
pcb->ppid = 0;
|
||||
pcb->pcbid = 1;
|
||||
pcb->ppcbid = 0;
|
||||
pcb->cwfs.farptr = GETFARPTR(mmvm->cwfs);
|
||||
pcb->ilib.farptr = GETFARPTR(mmvm->il->il);
|
||||
pcb->proc.farptr = GETFARPTR(mmvm->il->proc);
|
||||
pcb->resource.farptr = (sregs[CS] << 16) | mmvm->appinfo->fent.resource;
|
||||
strcpy(pcb->currentdir, "/rom0");
|
||||
|
||||
argptr = pcb->argv;
|
||||
argc = 0;
|
||||
args[0] = argptr;
|
||||
quote = FALSE;
|
||||
for(i = 0; i < (int)strlen(mmvm->appinfo->commandline) + 1; i++) {
|
||||
if(mmvm->appinfo->commandline[i] == TEXT('\\')) {
|
||||
if(i < (int)strlen(mmvm->appinfo->commandline)) {
|
||||
i++;
|
||||
memory[(FIRST_DSEG << 4) + argptr++] = mmvm->appinfo->commandline[i];
|
||||
}
|
||||
} else if(_istspace(mmvm->appinfo->commandline[i]) && !quote) {
|
||||
argc++;
|
||||
memory[(FIRST_DSEG << 4) + argptr++] = TEXT('\0');
|
||||
args[argc] = argptr;
|
||||
while(isspace(mmvm->appinfo->commandline[i]))
|
||||
i++;
|
||||
if(!mmvm->appinfo->commandline[i])
|
||||
argc--;
|
||||
i--;
|
||||
} else if(quote && (mmvm->appinfo->commandline[i] == TEXT('\"') || mmvm->appinfo->commandline[i] == TEXT('\''))) {
|
||||
quote = FALSE;
|
||||
} else if(!quote && (mmvm->appinfo->commandline[i] == TEXT('\"') || mmvm->appinfo->commandline[i] == TEXT('\''))) {
|
||||
quote = TRUE;
|
||||
} else {
|
||||
memory[(FIRST_DSEG << 4) + argptr++] = mmvm->appinfo->commandline[i];
|
||||
}
|
||||
}
|
||||
argc++;
|
||||
|
||||
// push argv
|
||||
tmp1 = (WORD)(ReadWord(&wregs[SP]) - 2);
|
||||
PutMemW(c_stack, tmp1, argptr);
|
||||
pcb->argv = argptr;
|
||||
|
||||
// set argv
|
||||
for(i = 0; i < argc; i++) {
|
||||
memory[(FIRST_DSEG << 4) + argptr++] = args[i] & 0xff;
|
||||
memory[(FIRST_DSEG << 4) + argptr++] = (args[i] >> 8) & 0xff;
|
||||
}
|
||||
|
||||
// push argc
|
||||
tmp1 = (WORD)(tmp1 - 2);
|
||||
PutMemW(c_stack, tmp1, argc);
|
||||
|
||||
// set _heap address
|
||||
pcb->heap = argptr;
|
||||
|
||||
// push return address
|
||||
tmp1 = (WORD)(tmp1 - 2);
|
||||
PutMemW(c_stack, tmp1, 0x0010);
|
||||
tmp1 = (WORD)(tmp1 - 2);
|
||||
PutMemW(c_stack, tmp1, 0x0000);
|
||||
WriteWord(&wregs[SP], tmp1);
|
||||
|
||||
memcpy(&memory[FINAL_DSEG << 4], &memory[FIRST_DSEG << 4], 0x10000);
|
||||
sregs[DS] = FINAL_DSEG; // どうせ run ルーチンで変更されるけど
|
||||
sregs[ES] = FINAL_DSEG; // どうせ run ルーチンで変更されるけど
|
||||
c_ds = SegToMemPtr(DS);
|
||||
c_es = SegToMemPtr(ES);
|
||||
|
||||
InitFilesys(mmvm);
|
||||
}
|
||||
|
||||
// main が呼ばれる直前に無理矢理 DS、ES を 0x2000 にする
|
||||
if(mmvm->appinfo->loadended && !mmvm->appinfo->maincalled && *(c_cs + ip) == 0xe8) {
|
||||
sregs[DS] = FINAL_DSEG;
|
||||
sregs[ES] = FINAL_DSEG;
|
||||
c_ds = SegToMemPtr(DS);
|
||||
c_es = SegToMemPtr(ES);
|
||||
mmvm->appinfo->maincalled = TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void OpenDlgAndRun() {
|
||||
OPENFILENAME ofn;
|
||||
TCHAR filename[MAX_PATH + 1];
|
||||
TCHAR wndName[1024];
|
||||
|
||||
filename[0] = TEXT('\0');
|
||||
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = wonw32ctx->hWnd;
|
||||
ofn.lpstrFilter = TEXT("WonderWitch 転送形式ファイル (*.fx)\0*.fx\0すべてのファイル (*.*)\0*.*\0\0");
|
||||
ofn.lpstrFile = filename;
|
||||
ofn.nMaxFile = sizeof(filename);
|
||||
ofn.Flags = OFN_FILEMUSTEXIST;
|
||||
if(GetOpenFileName(&ofn)) {
|
||||
if(wonw32ctx->running) {
|
||||
StopExecution(5000);
|
||||
}
|
||||
|
||||
wonw32ctx->loaded = LoadFXFile(filename, APP_CSEG, &(mmvm->appinfo->fent));
|
||||
|
||||
if(!wonw32ctx->loaded) {
|
||||
SetWindowText(wonw32ctx->hWnd, THIS_APP_TITLE);
|
||||
MessageBox(wonw32ctx->hWnd, "ファイルの読み込みに失敗しました", NULL, MB_OK);
|
||||
wonw32ctx->loaded = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
wsprintf(wndName, "%s - %s", (LPCTSTR)mmvm->appinfo->fent.info, THIS_APP_TITLE);
|
||||
SetWindowText(wonw32ctx->hWnd, wndName);
|
||||
|
||||
sprintf(mmvm->appinfo->commandline, "%s ", mmvm->appinfo->fent.name);
|
||||
if(mmconfig->queryarg) {
|
||||
DialogBoxParam(wonw32ctx->hInst, MAKEINTRESOURCE(IDD_ARGUMENT), wonw32ctx->hWnd,
|
||||
(DLGPROC)GetArgument, (LPARAM)mmvm->appinfo->commandline);
|
||||
} else {
|
||||
sprintf(mmvm->appinfo->commandline, "%s %s", mmvm->appinfo->fent.name, mmconfig->argument);
|
||||
}
|
||||
RunWWApp();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void OpenAndRun(LPCTSTR filename, LPCTSTR cmdline) {
|
||||
TCHAR wndName[1024];
|
||||
|
||||
if(wonw32ctx->running) {
|
||||
StopExecution(5000);
|
||||
}
|
||||
|
||||
wonw32ctx->loaded = LoadFXFile(filename, APP_CSEG, &(mmvm->appinfo->fent));
|
||||
|
||||
if(!wonw32ctx->loaded) {
|
||||
SetWindowText(wonw32ctx->hWnd, THIS_APP_TITLE);
|
||||
MessageBox(wonw32ctx->hWnd, "ファイルの読み込みに失敗しました", NULL, MB_OK);
|
||||
wonw32ctx->loaded = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
wsprintf(wndName, "%s - %s", (LPCTSTR)mmvm->appinfo->fent.info, THIS_APP_TITLE);
|
||||
SetWindowText(wonw32ctx->hWnd, wndName);
|
||||
|
||||
sprintf(mmvm->appinfo->commandline, "%s %s", mmvm->appinfo->fent.name, cmdline);
|
||||
|
||||
RunWWApp();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void RunWWApp() {
|
||||
wonw32ctx->cputhread = (HANDLE)_beginthread(StartThread, 0, NULL);
|
||||
}
|
||||
|
||||
BOOL LoadFXFile(LPCTSTR filename, WORD seg, WW_FENT_T *fentp) {
|
||||
LPBYTE b;
|
||||
int c;
|
||||
FILE *fp;
|
||||
int i;
|
||||
|
||||
b = (LPBYTE)fentp;
|
||||
fp = fopen(filename, "rb");
|
||||
if(!fp)
|
||||
goto error;
|
||||
for(i = 0; i < 64; i++) {
|
||||
if((c = fgetc(fp)) == EOF)
|
||||
goto error;
|
||||
b[i] = (BYTE)(c & 0xff);
|
||||
if((i == 0) && (b[i] != 0x23)) goto error;
|
||||
if((i == 1) && (b[i] != 0x21)) goto error;
|
||||
if((i == 2) && (b[i] != 0x77)) goto error;
|
||||
if((i == 3) && (b[i] != 0x73)) goto error;
|
||||
}
|
||||
for(i = 0; i < 64; i++) {
|
||||
if((c = fgetc(fp)) == EOF)
|
||||
goto error;
|
||||
b[i] = (BYTE)(c & 0xff);
|
||||
}
|
||||
|
||||
i = seg << 4;
|
||||
while((c = fgetc(fp)) != EOF)
|
||||
memory[i++] = (BYTE)(c & 0xff);
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
if(fp)
|
||||
fclose(fp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK GetArgument( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
static LPTSTR arg;
|
||||
HWND argwnd;
|
||||
HWND ok;
|
||||
|
||||
switch( message )
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
arg = (LPTSTR)lParam;
|
||||
argwnd = GetDlgItem(hDlg, IDC_ARGUMENT);
|
||||
SetWindowText(argwnd, arg);
|
||||
SendMessage(argwnd, EM_SETSEL, -1, 0);
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
argwnd = GetDlgItem(hDlg, IDC_ARGUMENT);
|
||||
GetWindowText(argwnd, arg, 1024);
|
||||
if( LOWORD(wParam) == IDOK) {
|
||||
if(lstrlen(arg) > 0)
|
||||
{
|
||||
EndDialog(hDlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
} else if(LOWORD(wParam) == IDC_ARGUMENT && HIWORD(wParam) == EN_UPDATE) {
|
||||
ok = GetDlgItem(hDlg, IDOK);
|
||||
if(lstrlen(arg) > 0) {
|
||||
EnableWindow(ok, TRUE);
|
||||
} else {
|
||||
EnableWindow(ok, FALSE);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void Restart() {
|
||||
if(wonw32ctx->running) {
|
||||
StopExecution(5000);
|
||||
}
|
||||
RunWWApp();
|
||||
}
|
||||
|
||||
void StopExecution(DWORD wait) {
|
||||
wonw32ctx->running = FALSE;
|
||||
PulseEvent(wonw32ctx->syncevent);
|
||||
TerminateThread(wonw32ctx->cputhread, 0);
|
||||
if(WaitForSingleObject(wonw32ctx->cputhread, wait) != WAIT_OBJECT_0) {
|
||||
MessageBox(wonw32ctx->hWnd, TEXT("MiracleMage 内部エラーです\nMiracleMage を再起動してください"), NULL, MB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void StartThread(LPVOID arg) {
|
||||
wonw32ctx->running = TRUE;
|
||||
InitVM();
|
||||
|
||||
InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
|
||||
UpdateWindow(wonw32ctx->hWnd);
|
||||
|
||||
while(wonw32ctx->running) {
|
||||
execute();
|
||||
UpdateVM();
|
||||
}
|
||||
|
||||
CloseFilesys();
|
||||
mmvm->lcdseg = 0;
|
||||
|
||||
InvalidateRect(wonw32ctx->hWnd, NULL, FALSE);
|
||||
UpdateWindow(wonw32ctx->hWnd);
|
||||
|
||||
_endthread();
|
||||
}
|
||||
|
||||
|
||||
static void HandleIlibIL() {
|
||||
WW_FARPTR ilname;
|
||||
WW_FARPTR ilbuf;
|
||||
|
||||
switch(ip) {
|
||||
case 0: // ILInfo far *super._get_info();
|
||||
wregs[DX] = GETSEG(mmvm->il->il);
|
||||
wregs[AX] = 0x0100;
|
||||
break;
|
||||
|
||||
case 1: // int _open(char far *ilname, IL far *ilbuf);
|
||||
case 2: // int _open_system(char far *ilname, IL far *ilbuf);
|
||||
ilname = *((WW_FARPTR *)GetArgAddr(0));
|
||||
ilbuf = *((WW_FARPTR *)GetArgAddr(4));
|
||||
|
||||
memory[FARPTR2ADDR(ilbuf) ] = 0;
|
||||
memory[FARPTR2ADDR(ilbuf) + 1] = 0;
|
||||
memory[FARPTR2ADDR(ilbuf) + 2] = 0;
|
||||
memory[FARPTR2ADDR(ilbuf) + 3] = 0;
|
||||
|
||||
wregs[AX] = 0xffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
wregs[AX] = 0xffff;
|
||||
break;
|
||||
}
|
||||
|
||||
ILReturn();
|
||||
}
|
||||
|
||||
static void HandleProcIL() {
|
||||
switch(ip) {
|
||||
case 0: // ILInfo far *super._get_info();
|
||||
wregs[DX] = GETSEG(mmvm->il->proc);
|
||||
wregs[AX] = 0x0100;
|
||||
break;
|
||||
|
||||
default:
|
||||
wregs[AX] = 0xffff;
|
||||
break;
|
||||
}
|
||||
|
||||
ILReturn();
|
||||
}
|
||||
|
||||
void ILReturn() {
|
||||
unsigned tmp = ReadWord(&wregs[SP]);
|
||||
ip = GetMemW(c_stack,tmp);
|
||||
tmp = (WORD)(tmp+2);
|
||||
sregs[CS] = GetMemW(c_stack,tmp);
|
||||
c_cs = SegToMemPtr(CS);
|
||||
tmp += 2;
|
||||
WriteWord(&wregs[SP],tmp);
|
||||
}
|
||||
|
||||
LPBYTE GetArgAddr(int pos) {
|
||||
return c_stack + ReadWord(&wregs[SP]) + 4 + pos;
|
||||
}
|
||||
|
||||
83
mmvm/mmvm.h
Normal file
83
mmvm/mmvm.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#ifndef _MMVM_H
|
||||
#define _MMVM_H
|
||||
|
||||
#include "wwstruct.h"
|
||||
extern "C" {
|
||||
#include "../cpu/mytypes.h"
|
||||
#include "../cpu/global.h"
|
||||
#include "../cpu/cpu.h"
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MEMORYSIZE (1 * 1024 * 1024)
|
||||
|
||||
#define ELISA_FONTFILE TEXT("elisa100.fnt")
|
||||
|
||||
#define SRAMWORK_SEG 0x1000
|
||||
#define APP_CSEG 0x3000
|
||||
#define FIRST_DSEG 0x1000
|
||||
#define FINAL_DSEG 0x2000
|
||||
#define STACK_SEG 0xF000
|
||||
|
||||
#define DIRENT_NUM 4
|
||||
#define DIRENT_ROOT 0
|
||||
#define DIRENT_KERN 1
|
||||
#define DIRENT_ROM0 2
|
||||
#define DIRENT_RAM0 3
|
||||
|
||||
typedef struct {
|
||||
char className[32];
|
||||
char name[32];
|
||||
char version[32];
|
||||
char description[32];
|
||||
char **depends;
|
||||
} MMVM_ILInfo, *LPMMVM_ILInfo;
|
||||
|
||||
typedef struct {
|
||||
WW_FARPTR il;
|
||||
MMVM_ILInfo ilinfo;
|
||||
WW_FARPTR proc;
|
||||
MMVM_ILInfo procinfo;
|
||||
WW_FARPTR fs;
|
||||
MMVM_ILInfo fsinfo;
|
||||
} MMVM_IL, *LPMMVM_IL;
|
||||
|
||||
typedef struct {
|
||||
WW_FENT_T fent;
|
||||
TCHAR commandline[MAX_WW_ARG];
|
||||
BOOL loadended;
|
||||
BOOL maincalled;
|
||||
} MMVM_APPINFO, *LPMMVM_APPINFO;
|
||||
|
||||
typedef struct {
|
||||
LPBYTE memory;
|
||||
LPMMVM_IL il;
|
||||
WW_FARPTR cwfs;
|
||||
LPWW_SRAMWork swork;
|
||||
LPMMVM_APPINFO appinfo;
|
||||
int lcdseg;
|
||||
} MMVM, *LPMMVM;
|
||||
|
||||
extern LPMMVM mmvm;
|
||||
|
||||
BOOL CreateVM();
|
||||
void InitVM();
|
||||
void UpdateVM();
|
||||
void OpenDlgAndRun();
|
||||
void OpenAndRun(LPCTSTR filename, LPCTSTR cmdline);
|
||||
void LoadAndRun();
|
||||
BOOL LoadFXFile(LPCTSTR filename, WORD addr, WW_FENT_T *fentp);
|
||||
void RunWWApp();
|
||||
void Restart();
|
||||
void StopExecution(DWORD wait);
|
||||
LPBYTE GetArgAddr(int pos);
|
||||
void ILReturn();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #ifndef _MMVM_H
|
||||
116
mmvm/systembios.cpp
Normal file
116
mmvm/systembios.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "../mmage/preference.h"
|
||||
#include "wwbios.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../wonx/wonx_include/system.h"
|
||||
}
|
||||
|
||||
enum {
|
||||
SYS_INTERRUPT_SET_HOOK = 0,
|
||||
SYS_INTERRUPT_RESET_HOOK,
|
||||
SYS_WAIT,
|
||||
SYS_GET_TICK_COUNT,
|
||||
SYS_SLEEP,
|
||||
SYS_SET_SLEEP_TIME,
|
||||
SYS_GET_SLEEP_TIME,
|
||||
SYS_SET_AWAKE_KEY,
|
||||
SYS_GET_AWAKE_KEY,
|
||||
SYS_SET_KEEPALIVE_INT,
|
||||
SYS_GET_OWNERINFO,
|
||||
SYS_SUSPEND,
|
||||
SYS_RESUME,
|
||||
SYS_SET_REMOTE,
|
||||
SYS_GET_REMOTE,
|
||||
SYS_ALLOC_IRAM,
|
||||
SYS_FREE_IRAM,
|
||||
SYS_GET_MY_IRAM,
|
||||
SYS_GET_VERSION,
|
||||
SYS_SWAP,
|
||||
SYS_SET_RESUME,
|
||||
SYS_GET_RESUME,
|
||||
};
|
||||
|
||||
void system_handler(int func_no) {
|
||||
int tmp;
|
||||
|
||||
switch(func_no) {
|
||||
case SYS_INTERRUPT_SET_HOOK:
|
||||
/*
|
||||
sys_interrupt_set_hook(*bregs[AL], (intvector_t *)(c_ds + wregs[BX]), (intvector_t *)(c_ds + wregs[DX]));
|
||||
*/
|
||||
break;
|
||||
case SYS_INTERRUPT_RESET_HOOK:
|
||||
/*
|
||||
sys_interrupt_reset_hook(*bregs[AL], (intvector_t *)(c_ds + wregs[BX]));
|
||||
*/
|
||||
break;
|
||||
case SYS_WAIT:
|
||||
sys_wait(wregs[CX]);
|
||||
break;
|
||||
case SYS_GET_TICK_COUNT:
|
||||
tmp = sys_get_tick_count();
|
||||
wregs[DX] = (tmp >> 16) & 0xffff;
|
||||
wregs[AX] = tmp & 0xffff;
|
||||
break;
|
||||
case SYS_SLEEP:
|
||||
sys_sleep();
|
||||
break;
|
||||
case SYS_SET_SLEEP_TIME:
|
||||
sys_set_sleep_time(*bregs[BL]);
|
||||
break;
|
||||
case SYS_GET_SLEEP_TIME:
|
||||
wregs[AX] = sys_get_sleep_time();
|
||||
break;
|
||||
case SYS_SET_AWAKE_KEY:
|
||||
sys_set_awake_key(wregs[BX]);
|
||||
break;
|
||||
case SYS_GET_AWAKE_KEY:
|
||||
wregs[AX] = sys_get_awake_key();
|
||||
break;
|
||||
case SYS_SET_KEEPALIVE_INT:
|
||||
sys_set_keepalive_int(*bregs[BL]);
|
||||
break;
|
||||
case SYS_GET_OWNERINFO:
|
||||
memcpy((void *)(c_ds + wregs[DX]), (void *)&mmconfig->ownerinfo,
|
||||
(wregs[CX] > sizeof(mmconfig->ownerinfo)) ? sizeof(mmconfig->ownerinfo) : wregs[CX]);
|
||||
// sys_get_ownerinfo(wregs[CX], (char *)(c_ds + wregs[DX]));
|
||||
break;
|
||||
case SYS_SUSPEND:
|
||||
wregs[AX] = sys_suspend(*bregs[AL]);
|
||||
break;
|
||||
case SYS_RESUME:
|
||||
sys_resume(*bregs[AL]);
|
||||
break;
|
||||
case SYS_SET_REMOTE:
|
||||
sys_set_remote(*bregs[AL]);
|
||||
break;
|
||||
case SYS_GET_REMOTE:
|
||||
wregs[AX] = sys_get_remote();
|
||||
break;
|
||||
case SYS_ALLOC_IRAM:
|
||||
wregs[AX] = (unsigned short)sys_alloc_iram((void *)wregs[BX], wregs[CX]);
|
||||
break;
|
||||
case SYS_FREE_IRAM:
|
||||
sys_free_iram((void *)wregs[BX]);
|
||||
break;
|
||||
case SYS_GET_MY_IRAM:
|
||||
wregs[AX] = (unsigned short)sys_get_my_iram();
|
||||
break;
|
||||
case SYS_GET_VERSION:
|
||||
wregs[AX] = sys_get_version();
|
||||
break;
|
||||
case SYS_SWAP:
|
||||
wregs[AX] = sys_swap(*bregs[AL]);
|
||||
break;
|
||||
case SYS_SET_RESUME:
|
||||
sys_set_resume(wregs[BX]);
|
||||
break;
|
||||
case SYS_GET_RESUME:
|
||||
wregs[AX] = sys_get_resume();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
117
mmvm/textbios.cpp
Normal file
117
mmvm/textbios.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "wwbios.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../wonx/wonx_include/text.h"
|
||||
}
|
||||
|
||||
enum {
|
||||
TEXT_SCREEN_INIT = 0,
|
||||
TEXT_WINDOW_INIT,
|
||||
TEXT_SET_MODE,
|
||||
TEXT_GET_MODE,
|
||||
TEXT_PUT_CHAR,
|
||||
TEXT_PUT_STRING,
|
||||
TEXT_PUT_SUBSTRING,
|
||||
TEXT_PUT_NUMERIC,
|
||||
TEXT_FILL_CHAR,
|
||||
TEXT_SET_PALETTE,
|
||||
TEXT_GET_PALETTE,
|
||||
TEXT_SET_ANK_FONT,
|
||||
TEXT_SET_SJIS_FONT,
|
||||
TEXT_GET_FONTDATA,
|
||||
TEXT_SET_SCREEN,
|
||||
TEXT_GET_SCREEN,
|
||||
CURSOR_DISPLAY,
|
||||
CURSOR_STATUS,
|
||||
CURSOR_SET_LOCATION,
|
||||
CURSOR_GET_LOCATION,
|
||||
CURSOR_SET_TYPE,
|
||||
CURSOR_GET_TYPE,
|
||||
};
|
||||
|
||||
void text_handler(int func_no) {
|
||||
int tmp;
|
||||
|
||||
switch(func_no) {
|
||||
case TEXT_SCREEN_INIT:
|
||||
text_screen_init();
|
||||
break;
|
||||
case TEXT_WINDOW_INIT:
|
||||
text_window_init(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH], wregs[DX]);
|
||||
break;
|
||||
case TEXT_SET_MODE:
|
||||
text_set_mode(wregs[BX]);
|
||||
break;
|
||||
case TEXT_GET_MODE:
|
||||
wregs[AX] = text_get_mode();
|
||||
break;
|
||||
case TEXT_PUT_CHAR:
|
||||
text_put_char(*bregs[BL], *bregs[BH], wregs[CX]);
|
||||
break;
|
||||
case TEXT_PUT_STRING:
|
||||
wregs[AX] = text_put_string(*bregs[BL], *bregs[BH], (char *)(c_ds + wregs[DX]));
|
||||
break;
|
||||
case TEXT_PUT_SUBSTRING:
|
||||
text_put_substring(*bregs[BL], *bregs[BH], (char *)(c_ds + wregs[DX]), wregs[CX]);
|
||||
break;
|
||||
case TEXT_PUT_NUMERIC:
|
||||
if((*bregs[CH]) & NUM_STORE) {
|
||||
text_store_numeric((char *)(c_ds + wregs[SI]), *bregs[CL], *bregs[CH], wregs[DX]);
|
||||
} else {
|
||||
text_put_numeric(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH], wregs[DX]);
|
||||
}
|
||||
break;
|
||||
case TEXT_FILL_CHAR:
|
||||
text_fill_char(*bregs[BL], *bregs[BH], wregs[CX], wregs[DX]);
|
||||
break;
|
||||
case TEXT_SET_PALETTE:
|
||||
text_set_palette(wregs[BX]);
|
||||
break;
|
||||
case TEXT_GET_PALETTE:
|
||||
wregs[AX] = text_get_palette();
|
||||
break;
|
||||
case TEXT_SET_ANK_FONT:
|
||||
text_set_ank_font(*bregs[BL], *bregs[BH], wregs[CX], c_ds + wregs[DX]);
|
||||
break;
|
||||
case TEXT_SET_SJIS_FONT:
|
||||
text_set_sjis_font((void *)(wregs[BX] << 4 | wregs[DX]));
|
||||
break;
|
||||
case TEXT_GET_FONTDATA:
|
||||
wregs[AX] = text_get_fontdata(wregs[CX], c_ds + wregs[DX]);
|
||||
break;
|
||||
case TEXT_SET_SCREEN:
|
||||
// text_set_screen(wregs[BX]); // マニュアル第 1 版は間違い
|
||||
text_set_screen(*bregs[AL]);
|
||||
break;
|
||||
case TEXT_GET_SCREEN:
|
||||
wregs[AX] = text_get_screen();
|
||||
break;
|
||||
case CURSOR_DISPLAY:
|
||||
cursor_display(*bregs[AL]);
|
||||
break;
|
||||
case CURSOR_STATUS:
|
||||
wregs[AX] = cursor_status();
|
||||
break;
|
||||
case CURSOR_SET_LOCATION:
|
||||
cursor_set_location(*bregs[BL], *bregs[BH], *bregs[CL], *bregs[CH]);
|
||||
break;
|
||||
case CURSOR_GET_LOCATION:
|
||||
tmp = cursor_get_location();
|
||||
wregs[DX] = (tmp >> 16) & 0xffff;
|
||||
wregs[AX] = tmp & 0xffff;
|
||||
break;
|
||||
case CURSOR_SET_TYPE:
|
||||
cursor_set_type(*bregs[BL], *bregs[CL]);
|
||||
break;
|
||||
case CURSOR_GET_TYPE:
|
||||
tmp = cursor_get_type();
|
||||
wregs[DX] = (tmp >> 16) & 0xffff;
|
||||
wregs[AX] = tmp & 0xffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
59
mmvm/timerbios.cpp
Normal file
59
mmvm/timerbios.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "wwbios.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../wonx/wonx_include/timer.h"
|
||||
}
|
||||
|
||||
enum {
|
||||
RTC_RESET = 0,
|
||||
RTC_SET_DATETIME,
|
||||
RTC_GET_DATETIME,
|
||||
RTC_SET_DATETIME_STRUCT,
|
||||
RTC_GET_DATETIME_STRUCT,
|
||||
RTC_ENABLE_ALARM,
|
||||
RTC_DISABLE_ALARM,
|
||||
TIMER_ENABLE,
|
||||
TIMER_DISABLE,
|
||||
TIMER_GET_COUNT,
|
||||
};
|
||||
|
||||
void timer_handler(int func_no) {
|
||||
|
||||
switch(func_no) {
|
||||
case RTC_RESET:
|
||||
/* WonX で未実装
|
||||
rtc_reset();
|
||||
*/
|
||||
break;
|
||||
case RTC_SET_DATETIME:
|
||||
rtc_set_datetime(wregs[BX], wregs[CX]);
|
||||
break;
|
||||
case RTC_GET_DATETIME:
|
||||
wregs[AX] = rtc_get_datetime(wregs[BX]);
|
||||
break;
|
||||
case RTC_SET_DATETIME_STRUCT:
|
||||
rtc_set_datetime_struct((datetime_t *)(c_ds + wregs[DX]));
|
||||
break;
|
||||
case RTC_GET_DATETIME_STRUCT:
|
||||
rtc_get_datetime_struct((datetime_t *)(c_ds + wregs[DX]));
|
||||
break;
|
||||
case RTC_ENABLE_ALARM:
|
||||
rtc_enable_alarm(*bregs[BL], *bregs[BH]);
|
||||
break;
|
||||
case RTC_DISABLE_ALARM:
|
||||
rtc_disable_alarm();
|
||||
break;
|
||||
case TIMER_ENABLE:
|
||||
timer_enable(*bregs[AL], *bregs[BL], wregs[CX]);
|
||||
break;
|
||||
case TIMER_DISABLE:
|
||||
timer_disable(*bregs[AL]);
|
||||
break;
|
||||
case TIMER_GET_COUNT:
|
||||
wregs[AX] = timer_get_count(*bregs[AL]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
51
mmvm/wwbios.cpp
Normal file
51
mmvm/wwbios.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "../mmage/mmage.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "wwbios.h"
|
||||
|
||||
void int_handler(int no) {
|
||||
int func_no;
|
||||
TCHAR msg[256];
|
||||
|
||||
func_no = *bregs[AH];
|
||||
|
||||
switch(no) {
|
||||
case INT_BIOS_EXIT:
|
||||
wonw32ctx->running = FALSE;
|
||||
wsprintf(msg, TEXT("アプリケーションは終了しました"));
|
||||
MessageBox(wonw32ctx->hWnd, msg, TEXT("終了"), MB_OK);
|
||||
break;
|
||||
|
||||
case INT_KEY:
|
||||
key_handler(func_no);
|
||||
break;
|
||||
case INT_DISP:
|
||||
disp_handler(func_no);
|
||||
break;
|
||||
case INT_TEXT:
|
||||
text_handler(func_no);
|
||||
break;
|
||||
case INT_SERIAL:
|
||||
// serial_handler(func_no);
|
||||
break;
|
||||
case INT_SOUND:
|
||||
// sound_handler(func_no);
|
||||
break;
|
||||
case INT_TIMER:
|
||||
timer_handler(func_no);
|
||||
break;
|
||||
case INT_SYSTEM:
|
||||
system_handler(func_no);
|
||||
break;
|
||||
case INT_BANK:
|
||||
// bank_handler(func_no);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
44
mmvm/wwbios.h
Normal file
44
mmvm/wwbios.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef _WWBIOS_H
|
||||
#define _WWBIOS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../cpu/mytypes.h"
|
||||
#include "../cpu/global.h"
|
||||
#include "../cpu/cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
INT_BIOS_EXIT=0x10,
|
||||
INT_KEY,
|
||||
INT_DISP,
|
||||
INT_TEXT,
|
||||
INT_SERIAL,
|
||||
INT_SOUND,
|
||||
INT_TIMER,
|
||||
INT_SYSTEM,
|
||||
INT_BANK,
|
||||
};
|
||||
|
||||
void int_handler(int no);
|
||||
|
||||
void key_handler(int func_no);
|
||||
void disp_handler(int func_no);
|
||||
void text_handler(int func_no);
|
||||
void serial_handler(int func_no);
|
||||
void sound_handler(int func_no);
|
||||
void timer_handler(int func_no);
|
||||
void system_handler(int func_no);
|
||||
void bank_handler(int func_no);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
214
mmvm/wwstruct.h
Normal file
214
mmvm/wwstruct.h
Normal file
@@ -0,0 +1,214 @@
|
||||
#ifndef _WWSTRUCT_H
|
||||
#define _WWSTRUCT_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define MAX_WW_ARG 256
|
||||
|
||||
#define MAXFNAME 16
|
||||
#define MAXPATHLEN 64
|
||||
#define MAXFINFO 24
|
||||
|
||||
#define OPEN_MAX 16 /* max open fils per process */
|
||||
|
||||
#define BLOCKSZ 128 /* size of file block */
|
||||
|
||||
#define FMODE_X (0x0001) /* executable */
|
||||
#define FMODE_W (0x0002) /* writable */
|
||||
#define FMODE_R (0x0004) /* readable */
|
||||
#define FMODE_MMAP (0x0008) /* disallow mmap */
|
||||
#define FMODE_STREAM (0x0010) /* StreamIL instance */
|
||||
#define FMODE_ILIB (0x0020) /* IL instance */
|
||||
#define FMODE_LINK (0x0040) /* symbolic link */
|
||||
#define FMODE_DIR (0x0080) /* directory */
|
||||
|
||||
#define E_FS_SUCCESS 0
|
||||
#define E_FS_ERROR 0x8000
|
||||
#define E_FS_FILE_NOT_FOUND 0x8001
|
||||
#define E_FS_PERMISSION_DENIED 0x8002
|
||||
#define E_FS_OUT_OF_BOUNDS 0x8003
|
||||
#define E_FS_NO_SPACE_LEFT 0x8004
|
||||
#define E_FS_FILE_NOT_OPEN 0x8005
|
||||
|
||||
typedef union {
|
||||
DWORD farptr;
|
||||
struct {
|
||||
WORD off;
|
||||
WORD seg;
|
||||
} segoff;
|
||||
} WW_FARPTR;
|
||||
|
||||
#define FARPTR2ADDR(X) ((X.segoff.seg << 4) | X.segoff.off)
|
||||
#define SEGOFF2FARPTR(SEG, OFF) ((SEG << 16 | OFF))
|
||||
#define GETSEG(X) (X.segoff.seg)
|
||||
#define GETOFF(X) (X.segoff.off)
|
||||
#define GETFARPTR(X) (X.farptr)
|
||||
|
||||
typedef WORD WW_NEARPTR;
|
||||
typedef WORD WW_SHORT;
|
||||
typedef WORD WW_INT;
|
||||
typedef DWORD WW_LONG;
|
||||
|
||||
#pragma pack( push, beforewwstruct )
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
/* from startup routine
|
||||
__id db 'TCC', 0
|
||||
__pid dw ?
|
||||
__ppid dw ?
|
||||
__pcbid dw ?
|
||||
__ppcbid dw ?
|
||||
__ilib dd ?
|
||||
__proc dd ?
|
||||
__cwfs dd ?
|
||||
__currentdir db MAXPATHLEN dup (?)
|
||||
__argv dw ?
|
||||
__resource dd ?
|
||||
__heap dw ?
|
||||
*/
|
||||
BYTE id[4];
|
||||
WW_INT pid;
|
||||
WW_INT ppid;
|
||||
WW_INT pcbid;
|
||||
WW_INT ppcbid;
|
||||
WW_FARPTR ilib;
|
||||
WW_FARPTR proc;
|
||||
WW_FARPTR cwfs;
|
||||
char currentdir[MAXPATHLEN];
|
||||
WW_NEARPTR argv;
|
||||
WW_FARPTR resource;
|
||||
WW_NEARPTR heap;
|
||||
} WW_PCB, *LPWW_PCB;
|
||||
|
||||
typedef struct {
|
||||
char name[MAXFNAME];
|
||||
char info[MAXFINFO];
|
||||
WW_LONG loc;
|
||||
WW_LONG len;
|
||||
WW_INT count;
|
||||
WW_INT mode;
|
||||
WW_LONG mtime;
|
||||
union {
|
||||
WW_LONG appid;
|
||||
WW_LONG il;
|
||||
} handler;
|
||||
WW_LONG resource;
|
||||
} WW_FENT_T, *WW_FS;
|
||||
|
||||
|
||||
typedef struct {
|
||||
BYTE magic[4];
|
||||
BYTE padding[60];
|
||||
WW_FENT_T fent;
|
||||
} WW_FXHEADER, *LPWW_FXHEADER;
|
||||
|
||||
|
||||
typedef struct {
|
||||
WW_FARPTR className; // char far *className;
|
||||
WW_FARPTR name; // char far *name;
|
||||
WW_FARPTR version; // char far *version;
|
||||
WW_FARPTR description; // char far *description;
|
||||
WW_FARPTR depends; // char far * far *depends;
|
||||
} WW_ILInfo, *LPWW_ILInfo;
|
||||
|
||||
typedef struct { // IL struct (see sys/indirect.h)
|
||||
WW_FARPTR link_pos; // void far *link_pos;
|
||||
WW_INT n_methods; // int n_methods;
|
||||
WW_FARPTR _get_info; // ILInfo far *(far *_get_info)(void);
|
||||
} WW_IL, *LPWW_IL;
|
||||
|
||||
typedef struct { // IlibIL struct (see sys/indeirect.h)
|
||||
WW_IL super;
|
||||
WW_FARPTR _open; // int (far *_open)(char far *ilname, IL far *ilbuf);
|
||||
WW_FARPTR _open_system; //int (far *_open_system)(char far *ilname, IL far *ilbuf);
|
||||
} WW_IlibIL, *LPWW_IlibIL;
|
||||
|
||||
typedef struct { // ProcIL struct (see sys/indeirect.h)
|
||||
WW_IL super;
|
||||
WW_FARPTR _load; // void far *(far *_load)(char far *command);
|
||||
WW_FARPTR _run; // int (far *_run)(void far *entry, int argc, char far * far *argv);
|
||||
WW_FARPTR _exec; // int (far *_exec)(char far *command, int argc, char far * far *argv);
|
||||
WW_FARPTR _exit; // void (far *_exit)(int exitcode);
|
||||
WW_FARPTR _yield; // void (far *_yield)(void);
|
||||
WW_FARPTR _suspend; // int (far *_suspend)(int pcbid);
|
||||
WW_FARPTR _resume; // void (far *_resume)(int pcbid);
|
||||
WW_FARPTR _swap; // int (far *_swap)(int pcbid);
|
||||
/*
|
||||
WW_FARPTR _kill; // int (far *_kill)(child);
|
||||
*/
|
||||
} WW_ProcIL, *LPWW_ProcIL;
|
||||
|
||||
typedef struct { // FsIL struct (see sys/indeirect.h)
|
||||
WW_IL super;
|
||||
WW_FARPTR _entries; // fent_t far *(far *_entries)(FS fs);
|
||||
WW_FARPTR _n_entries; // int (far *_n_entries)(FS fs);
|
||||
WW_FARPTR _getent; // int (far *_getent)(FS fs, int n, fent_t far *fep);
|
||||
WW_FARPTR _findent; // int (far *_findent)(FS fs, char far *fname, fent_t far *fep);
|
||||
WW_FARPTR _mmap; // void far *(far *_mmap)(FS fs, char far *fname);
|
||||
WW_FARPTR _open; // int (far *_open)(FS fs, char far *fname, int mode, int perms);
|
||||
WW_FARPTR _close; // int (far *_close)(int fd);
|
||||
WW_FARPTR _read; // int (far *_read)(int fd, char far *buf, int len);
|
||||
WW_FARPTR _write; // int (far *_write)(int fd, char far *buf, int len);
|
||||
WW_FARPTR _lseek; // long (far *_lseek)(int fd, long offset, int origin);
|
||||
WW_FARPTR _chmod; // int (far *_chmod)(FS fs, char far *fname, int mode);
|
||||
WW_FARPTR _freeze; // int (far *_freeze)(FS fs, char far *fname);
|
||||
WW_FARPTR _melt; // int (far *_melt)(FS fs, char far *fname);
|
||||
WW_FARPTR _creat; // int (far *_creat)(FS fs, fent_t far *fep);
|
||||
WW_FARPTR _unlink; // int (far *_unlink)(FS fs, char far *fname);
|
||||
WW_FARPTR _newfs; // int (far *_newfs)(FS fs);
|
||||
WW_FARPTR _defrag; // int (far *_defrag)(FS fs);
|
||||
WW_FARPTR _space; // unsigned long (far *_space)(FS fs);
|
||||
} WW_FsIL, *LPWW_FsIL;
|
||||
|
||||
typedef struct {
|
||||
WW_INT _status; // int _status; /* status of process */
|
||||
WW_INT _exit_code; // int _exit_code; /* process exit code */
|
||||
} WW_ProcControl, *LPWW_ProcControl;
|
||||
|
||||
typedef struct {
|
||||
WW_FS fs; // FS fs; /* FS which contains the fent */
|
||||
WW_FARPTR fentp; // fent_t far *fentp; /* original file entry */
|
||||
WW_SHORT omode; // fmode_t omode; /* open mode: 0 indicates free handle */
|
||||
WW_FARPTR floc; // floc_t floc; /* file location */
|
||||
WW_LONG flen; // flen_t flen; /* file length */
|
||||
WW_LONG fpos; // fpos_t fpos; /* current seek position */
|
||||
WW_INT count; // int count; /* total file block count */
|
||||
WW_FARPTR driver; // StreamIL_p driver; /* stream driver for the file */
|
||||
WW_INT pcb; // int pcb; /* opening process's pcb */
|
||||
WW_INT _reserved; // int _reserved; /* reserved */
|
||||
} WW_fhandle_t, *LPWW_fhandle_t;
|
||||
|
||||
#define MAXPROCESSES 3
|
||||
#define MAXFILES 16
|
||||
#define ROOTFS_NUM_ENTRIES 16
|
||||
#define RAM0FS_NUM_ENTRIES 24
|
||||
#define ROM0FS_NUM_ENTRIES 128
|
||||
|
||||
typedef struct { // SRAMWork struct (see sys/oswork.h)
|
||||
WW_PCB _opsc; // ProcContext _ospc;
|
||||
WW_ProcControl _pcb[MAXPROCESSES]; // ProcControl _pcb[MAXPROCESSES];
|
||||
WW_INT _os_version; // unsigned _os_version;
|
||||
WW_INT _last_pcb; // unsigned _last_pcb;
|
||||
WW_INT _freefd; // int _freefd;
|
||||
WW_fhandle_t _openfiles[MAXFILES]; // fhandle_t _openfiles[MAXFILES];
|
||||
char _shell_work[128];
|
||||
WW_FENT_T _root_fs_entries[ROOTFS_NUM_ENTRIES]; // fent_t _root_fs_entries[ROOTFS_NUM_ENTRIES];
|
||||
WW_FENT_T _ram0_fs_entries[RAM0FS_NUM_ENTRIES]; // fent_t _ram0_fs_entries[RAM0FS_NUM_ENTRIES];
|
||||
WW_FENT_T _rom0_fs_entries[ROM0FS_NUM_ENTRIES]; // fent_t _rom0_fs_entries[ROM0FS_NUM_ENTRIES];
|
||||
WW_FARPTR _saveports; // unsigned char far * _saveports;
|
||||
} WW_SRAMWork, *LPWW_SRAMWork;
|
||||
|
||||
|
||||
typedef struct { //
|
||||
char name[16];
|
||||
WW_INT birth_year;
|
||||
char birth_month;
|
||||
char birth_day;
|
||||
char sex;
|
||||
char bloodtype;
|
||||
} WW_OWNERINFO, *LPWW_OWNERINFO;
|
||||
|
||||
#pragma pack( pop, beforewwstruct )
|
||||
|
||||
#endif // #ifndef _WWSTRUCT_H
|
||||
Reference in New Issue
Block a user