1996-02-01: Historic version 0.37

Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
Gwenhael Le Moine 2024-03-19 22:11:59 +01:00
commit c3ab4004ad
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
33 changed files with 5606 additions and 0 deletions

BIN
BITMAP1.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

95
DUMP.C Normal file
View file

@ -0,0 +1,95 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#include <stdlib.h>
#include <stdio.h>
FILE *in;
unsigned char A[16], B[16], C[16], D[16], ST[4];
unsigned char R0[16], R1[16], R2[16], R3[16], R4[16];
unsigned char HST, P, CARRY, MODE, INTP, INTE, INTD, SHUTDN;
unsigned char ioram[64];
unsigned long pc, d0, d1, OUT, IN, rstk[8], rstkp, t1, t2;
unsigned long ucfg[5], base[6], size[5];
unsigned short crc;
void Ndisp(unsigned char *a, int s) {
while (s--) putchar((a[s]<10)?(a[s]+'0'):(a[s]-10+'A'));
return;
}
int main(int argc, char *argv[]) {
int i;
if (argc!=2)
in = fopen("saturn", "rb");
else
in = fopen(argv[1], "rb");
if (in == NULL) return 1;
fread(A, 16, 1, in);
fread(B, 16, 1, in);
fread(C, 16, 1, in);
fread(D, 16, 1, in);
fread(R0, 16, 1, in);
fread(R1, 16, 1, in);
fread(R2, 16, 1, in);
fread(R3, 16, 1, in);
fread(R4, 16, 1, in);
fread(&pc, 4, 1, in);
fread(&d0, 4, 1, in);
fread(&d1, 4, 1, in);
fread(&OUT, 4, 1, in);
fread(&IN, 4, 1, in);
fread(ST, 4, 1, in);
HST = fgetc(in);
if (!P) P = fgetc(in); else fseek(in, 1, SEEK_CUR);
CARRY = fgetc(in);
MODE = fgetc(in);
INTP = fgetc(in);
INTE = fgetc(in);
INTD = fgetc(in);
SHUTDN = fgetc(in);
fread(rstk, 32, 1, in);
rstkp = fgetc(in);
for (i=0; i<5; i++) {
ucfg[i] = fgetc(in);
fread(&base[i], 4, 1, in);
fread(&size[i], 4, 1, in);
}
fread(ioram, 64, 1, in);
t1 = fgetc(in);
fread(&t2, 4, 1, in);
fread(&crc, 4, 1, in);
/* fread(&display, sizeof(display_t), 1, in);*/
fclose(in);
printf(" A="); Ndisp(A, 16); putchar('\t');
printf(" B="); Ndisp(B, 16); putchar('\t');
printf(" C="); Ndisp(C, 16); putchar('\n');
printf(" D="); Ndisp(D, 16); putchar('\t');
printf("R0="); Ndisp(R0, 16); putchar('\t');
printf("R1="); Ndisp(R1, 16); putchar('\n');
printf("R2="); Ndisp(R2, 16); putchar('\t');
printf("R3="); Ndisp(R3, 16); putchar('\t');
printf("R4="); Ndisp(R4, 16); putchar('\n');
printf("PC=%05lX\tD0=%05lX\tD1=%05lX\n", pc, d0, d1);
printf("OUT=%03lX\tIN=%04lX\tST=", OUT, IN); Ndisp(ST, 4); putchar('\n');
printf("HST=%X\tP=%i\tCARRY=%c\tMODE=%2i\n", HST, P, CARRY?'Y':'N', MODE);
printf("INTP=%c\tINTE=%c\tINTD=%c\tSHUTDN=%c\n", INTP?'Y':'N', INTE?'Y':'N',
INTD?'Y':'N', SHUTDN?'Y':'N');
printf("RSTK(%ld): ", rstkp);
for (i=0; i<8; i++) printf("%05lX ", rstk[i]); putchar('\n');
printf("IORAM: ");
for (i=0; i<64; i++) {
putchar((ioram[i]<10)?(ioram[i]+'0'):(ioram[i]-10+'A'));
if ((i&0xf) == 0xf) putchar(' ');
}
putchar('\n');
printf("T1=%1lX T2=%08lX CRC=%04X\n", t1, t2, crc);
for (i=0; i<5; i++)
printf("Module %d: cfg=%ld base=%05lX size=%05lX\n", i, ucfg[i], base[i], size[i]);
return 0;
}


100
DUMP2ROM.C Normal file
View file

@ -0,0 +1,100 @@
/*
* This file is part of Emu48, an emulator of the HP-48 Calculator.
* Copyright (C) 1995 Sebastien Carlier <sebc@cybera.anet.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#define word8 unsigned char
#define word16 unsigned short
#define word32 unsigned long
char in[32];
word8 out[8];
FILE *IN, *OUT;
void Ncode(word8 *a, word8 s) {
while (s--) {
if (a[s] < '0') { a[s] = 0; continue; }
if (a[s] <='9') { a[s]-= '0'; continue; }
if (a[s] < 'A') { a[s] = 0; continue; }
if (a[s] <='F') { a[s]-= ('A'-10); continue; }
a[s] = 0;
}
return;
}
word32 Nrpack(word8 *a, word8 s) {
word32 r = 0;
int i;
for (i=0; i<s; i++) r = (r<<4)|a[i];
return r;
}
int main(int argc, char *argv[]) {
word32 d, i;
if (argc < 2) {
fprintf(stderr, "usage: %s hp48-dump-file\n", argv[0]);
exit(1);
}
IN = fopen(argv[1], "r");
if (IN==NULL) {
fprintf(stderr, "%s: can\'t open %s\n", argv[0], argv[1]);
exit(1);
}
OUT = fopen("rom", "wb");
if (OUT==NULL) {
fprintf(stderr, "%s: can\'t open %s\n", argv[0], "rom");
exit(1);
}
for (i=0; i<0x100000; i+=0x10) {
if (feof(IN)) break;
fgets(in, 24, IN);
if (!in[0]) break;
if (in[5]!=':') {
fprintf(stderr, "%s: Illegal char at %05lX\n", argv[0], i);
fclose(OUT);
fclose(IN);
exit(1);
}
Ncode(in, 22);
d = Nrpack(in, 5);
if (i != d) {
fprintf(stderr, "%s: Wrong address %05lX, expected %05lX\n", argv[0], d, i);
fclose(OUT);
fclose(IN);
exit(1);
}
out[0] = ((in[7]<<4)|(in[6]));
out[1] = ((in[9]<<4)|(in[8]));
out[2] = ((in[11]<<4)|(in[10]));
out[3] = ((in[13]<<4)|(in[12]));
out[4] = ((in[15]<<4)|(in[14]));
out[5] = ((in[17]<<4)|(in[16]));
out[6] = ((in[19]<<4)|(in[18]));
out[7] = ((in[21]<<4)|(in[20]));
fwrite(out, 8, 1, OUT);
}
printf("ROM size: %05lX\n", i);
fclose(OUT);
fclose(IN);
return 0;
}

134
EMU48.H Normal file
View file

@ -0,0 +1,134 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#define VERSION "0.37"
#include "hardware.h"
#define XM 1
#define SB 2
#define SR 4
#define MP 8
#define CRC(nib) crc=(crc>>4)^(((crc^(nib))&0xf)*0x1081);
#define ISMODULE(n,d) ((!ucfg[n])&&(d>=base[n])&&(d<(base[n]+size[n])))
#define INTERRUPT(t) {INTP=1;rstkpush(pc);pc=0xf;}
#define PCHANGED {F_s[0]=P;F_l[1]=P+1;}
extern char A[16];
extern char B[16];
extern char C[16];
extern char D[16];
extern char R0[16];
extern char R1[16];
extern char R2[16];
extern char R3[16];
extern char R4[16];
extern char ST[4];
extern char HST, P;
extern int OUT, IN;
extern int SHUTDN, INTP, INTE, INTD, rstkp, MODE, CARRY;
extern long rstk[8];
extern long pc, d0, d1;
extern int F_s[16];
extern int F_l[16];
extern char CARDSTATUS;
extern char *rom, *ram, *port1, *port2, *data[6], ioram[64];
extern int ucfg[6], bank1, bank2;
extern long base[6], size[6];
extern unsigned short crc;
extern unsigned long t1, t2, saturn_speed;
extern int quit;
extern int load_state;
extern int load();
extern int save();
extern void bank_save(char *mem, char *bn, int bank);
extern void bank_load(char *mem, char *bn, int bank);
extern void bank_switch(int bank);
extern void emulate();
extern long rstkpop();
extern void rstkpush(long d);
extern char *nibble_ptr(long d);
extern char read_nibble(long d);
extern char read_nibble_crc(long d);
extern void write_nibble(long d, char c);
extern char read_io(long d);
extern void write_io(long d, char c);
extern void config();
extern void unconfig();
extern void reset();
extern void c_eq_id();
extern void calibrate_timer();
extern long Npack(char *a, int s);
extern void Nunpack(char *a, long b, int s);
extern void Nread(char *a, long b, int s);
extern void NCread(char *a, long b, int s);
extern void Nwrite(char *a, long b, int s);
extern void Ncopy(char *a, char *b, int s);
extern void Nxchg(char *a, char *b, int s);
extern void Ninc(char *a, int s);
extern void Ndec(char *a, int s);
extern void Nadd(char *a, char *b, int s);
extern void Nsub(char *a, char *b, int s);
extern void Nrsub(char *a, char *b, int s);
extern void Nand(char *a, char *b, int s);
extern void Nor(char *a, char *b, int s);
extern void Nzero(char *a, int s);
extern void Nnot(char *a, int s);
extern void Nneg(char *a, int s);
extern void Nsl(char *a, int s);
extern void Nsr(char *a, int s);
extern void Nbit0(char *a, char b);
extern void Nbit1(char *a, char b);
extern void Nslc(char *a, int s);
extern void Nsrc(char *a, int s);
extern void Nsrb(char *a, int s);
extern void Ndbl(char *a, int s);
extern void Tbit0(char *a, char b);
extern void Tbit1(char *a, char b);
extern void Te(char *a, char *b, int s);
extern void Tne(char *a, char *b, int s);
extern void Tz(char *a, int s);
extern void Tnz(char *a, int s);
extern void Ta(char *a, char *b, int s);
extern void Tae(char *a, char *b, int s);
extern void Tb(char *a, char *b, int s);
extern void Tbe(char *a, char *b, int s);
#define P_FIELDScl(t,fn) extern void t##F##fn(char *a, long b, int f);
#define P_FIELDScc(t,fn) extern void t##F##fn(char *a, char *b, int f);
#define P_FIELDSc(t,fn) extern void t##F##fn(char *a, int f);
P_FIELDScl(N,unpack)
P_FIELDScl(NC,read)
P_FIELDScl(N,write)
P_FIELDScc(N,copy)
P_FIELDScc(N,xchg)
P_FIELDSc(N,inc)
P_FIELDSc(N,dec)
P_FIELDScc(N,add)
P_FIELDScc(N,sub)
P_FIELDScc(N,rsub)
P_FIELDScc(N,and)
P_FIELDScc(N,or)
P_FIELDSc(N,zero)
P_FIELDSc(N,not)
P_FIELDSc(N,neg)
P_FIELDSc(N,sr)
P_FIELDSc(N,sl)
P_FIELDSc(N,srb)
P_FIELDSc(N,dbl)
P_FIELDScc(T,e)
P_FIELDScc(T,ne)
P_FIELDSc(T,z)
P_FIELDSc(T,nz)
P_FIELDScc(T,a)
P_FIELDScc(T,ae)
P_FIELDScc(T,b)
P_FIELDScc(T,be)


BIN
EMU48.ICO Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

297
EMU48.MAK Normal file
View file

@ -0,0 +1,297 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "EMU48.MAK" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Debug"
MTL=MkTypLib.exe
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : .\WinRel\EMU48.exe .\WinRel\EMU48.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /win32
MTL_PROJ=/nologo /D "NDEBUG" /win32
# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /c
# ADD CPP /nologo /G4 /Gr /Zp8 /MT /W3 /GX /YX /O2 /I "C:\Emu48\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /c
# SUBTRACT CPP /Z<none>
CPP_PROJ=/nologo /G4 /Gr /Zp8 /MT /W3 /GX /YX /O2 /I "C:\Emu48\win32" /D\
"WIN32" /D "NDEBUG" /D "_WINDOWS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"EMU48.pch"\
/Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /i "D:\MSVC20\MFC\INCLUDE" /d "NDEBUG"
RSC_PROJ=/l 0x409 /fo$(INTDIR)/"EMU48.res" /i "D:\MSVC20\MFC\INCLUDE" /d\
"NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"EMU48.bsc"
BSC32_SBRS= \
.\WinRel\HARDWARE.SBR \
.\WinRel\MEMORY.SBR \
.\WinRel\INSTR.SBR \
.\WinRel\SATURN.SBR \
.\WinRel\MAIN.SBR
.\WinRel\EMU48.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
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:windows /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib /NOLOGO /VERSION:0,37 /SUBSYSTEM:windows /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib /NOLOGO /VERSION:0,37\
/SUBSYSTEM:windows /INCREMENTAL:no /PDB:$(OUTDIR)/"EMU48.pdb" /MACHINE:I386\
/OUT:$(OUTDIR)/"EMU48.exe"
DEF_FILE=
LINK32_OBJS= \
.\WinRel\HARDWARE.OBJ \
.\WinRel\MEMORY.OBJ \
.\WinRel\INSTR.OBJ \
.\WinRel\SATURN.OBJ \
.\WinRel\MAIN.OBJ \
.\WinRel\EMU48.res
.\WinRel\EMU48.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : .\WinDebug\EMU48.exe .\WinDebug\EMU48.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /win32
MTL_PROJ=/nologo /D "_DEBUG" /win32
# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /c
# ADD CPP /nologo /W3 /WX /GX /Zi /YX /Od /I "C:\Emu48\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /c
CPP_PROJ=/nologo /W3 /WX /GX /Zi /YX /Od /I "C:\Emu48\win32" /D "WIN32" /D\
"_DEBUG" /D "_WINDOWS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"EMU48.pch" /Fo$(INTDIR)/\
/Fd$(OUTDIR)/"EMU48.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /i "D:\MSVC20\MFC\INCLUDE" /d "_DEBUG"
RSC_PROJ=/l 0x409 /fo$(INTDIR)/"EMU48.res" /i "D:\MSVC20\MFC\INCLUDE" /d\
"_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"EMU48.bsc"
BSC32_SBRS= \
.\WinDebug\HARDWARE.SBR \
.\WinDebug\MEMORY.SBR \
.\WinDebug\INSTR.SBR \
.\WinDebug\SATURN.SBR \
.\WinDebug\MAIN.SBR
.\WinDebug\EMU48.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
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:windows /DEBUG /MACHINE:I386
# ADD 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:windows /DEBUG /MACHINE:I386
LINK32_FLAGS=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:windows /INCREMENTAL:yes\
/PDB:$(OUTDIR)/"EMU48.pdb" /DEBUG /MACHINE:I386 /OUT:$(OUTDIR)/"EMU48.exe"
DEF_FILE=
LINK32_OBJS= \
.\WinDebug\HARDWARE.OBJ \
.\WinDebug\MEMORY.OBJ \
.\WinDebug\INSTR.OBJ \
.\WinDebug\SATURN.OBJ \
.\WinDebug\MAIN.OBJ \
.\WinDebug\EMU48.res
.\WinDebug\EMU48.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\HARDWARE.C
DEP_HARDW=\
..\SRC\EMU48.H
!IF "$(CFG)" == "Win32 Release"
.\WinRel\HARDWARE.OBJ : $(SOURCE) $(DEP_HARDW) $(INTDIR)
!ELSEIF "$(CFG)" == "Win32 Debug"
.\WinDebug\HARDWARE.OBJ : $(SOURCE) $(DEP_HARDW) $(INTDIR)
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=\EMU48\SRC\MEMORY.C
!IF "$(CFG)" == "Win32 Release"
.\WinRel\MEMORY.OBJ : $(SOURCE) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
!ELSEIF "$(CFG)" == "Win32 Debug"
.\WinDebug\MEMORY.OBJ : $(SOURCE) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=\EMU48\SRC\INSTR.C
!IF "$(CFG)" == "Win32 Release"
.\WinRel\INSTR.OBJ : $(SOURCE) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
!ELSEIF "$(CFG)" == "Win32 Debug"
.\WinDebug\INSTR.OBJ : $(SOURCE) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=\EMU48\SRC\SATURN.C
!IF "$(CFG)" == "Win32 Release"
.\WinRel\SATURN.OBJ : $(SOURCE) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
!ELSEIF "$(CFG)" == "Win32 Debug"
.\WinDebug\SATURN.OBJ : $(SOURCE) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=\EMU48\SRC\MAIN.C
!IF "$(CFG)" == "Win32 Release"
.\WinRel\MAIN.OBJ : $(SOURCE) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
!ELSEIF "$(CFG)" == "Win32 Debug"
.\WinDebug\MAIN.OBJ : $(SOURCE) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=.\EMU48.RC
DEP_EMU48=\
.\EMU48.ICO\
.\KEYBOARD.BMP\
.\PIX4.BMP
!IF "$(CFG)" == "Win32 Release"
.\WinRel\EMU48.res : $(SOURCE) $(DEP_EMU48) $(INTDIR)
$(RSC) $(RSC_PROJ) $(SOURCE)
!ELSEIF "$(CFG)" == "Win32 Debug"
.\WinDebug\EMU48.res : $(SOURCE) $(DEP_EMU48) $(INTDIR)
$(RSC) $(RSC_PROJ) $(SOURCE)
!ENDIF
# End Source File
# End Group
# End Project
################################################################################

88
EMU48.RC Normal file
View file

@ -0,0 +1,88 @@
//Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
EMU48_ICON ICON DISCARDABLE "Emu48.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
EMU48_KEYBOARD BITMAP DISCARDABLE "Keyboard.bmp"
EMU48_PIX4 BITMAP DISCARDABLE "Pix4.bmp"
EMU48_IDLE BITMAP DISCARDABLE "EMU48_ID.BMP"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
/////////////////////////////////////////////////////////////////////////////
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
EMU48_MENU MENU DISCARDABLE
BEGIN
POPUP "&System"
BEGIN
MENUITEM "&Run", ID_SYSTEM_RUN
MENUITEM "&Save RAM", ID_SAVE
MENUITEM "E&xit WITHOUT save", ID_SYSTEM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About", ID_HELP_ABOUT
END
END
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

BIN
EMU48_ID.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

454
FETCH.H Normal file
View file

@ -0,0 +1,454 @@
switch(I[0]) {
case 0x0: switch(I[1]) {
case 0x0: goto o00;
case 0x1: goto o01;
case 0x2: goto o02;
case 0x3: goto o03;
case 0x4: goto o04;
case 0x5: goto o05;
case 0x6: goto o06;
case 0x7: goto o07;
case 0x8: goto o08;
case 0x9: goto o09;
case 0xA: goto o0A;
case 0xB: goto o0B;
case 0xC: goto o0C;
case 0xD: goto o0D;
case 0xE: switch(I[3]) {
case 0x0: goto o0Ef0;
case 0x1: goto o0Ef1;
case 0x2: goto o0Ef2;
case 0x3: goto o0Ef3;
case 0x4: goto o0Ef4;
case 0x5: goto o0Ef5;
case 0x6: goto o0Ef6;
case 0x7: goto o0Ef7;
case 0x8: goto o0Ef8;
case 0x9: goto o0Ef9;
case 0xA: goto o0EfA;
case 0xB: goto o0EfB;
case 0xC: goto o0EfC;
case 0xD: goto o0EfD;
case 0xE: goto o0EfE;
case 0xF: goto o0EfF; } goto o_invalid;
case 0xF: goto o0F; } goto o_invalid;
case 0x1: switch(I[1]) {
case 0x0: switch(I[2]) {
case 0x0: goto o100;
case 0x1: goto o101;
case 0x2: goto o102;
case 0x3: goto o103;
case 0x4: goto o104;
case 0x8: goto o108;
case 0x9: goto o109;
case 0xA: goto o10A;
case 0xB: goto o10B;
case 0xC: goto o10C; } goto o_invalid3;
case 0x1: switch(I[2]) {
case 0x0: goto o110;
case 0x1: goto o111;
case 0x2: goto o112;
case 0x3: goto o113;
case 0x4: goto o114;
case 0x8: goto o118;
case 0x9: goto o119;
case 0xA: goto o11A;
case 0xB: goto o11B;
case 0xC: goto o11C; } goto o_invalid3;
case 0x2: switch(I[2]) {
case 0x0: goto o120;
case 0x1: goto o121;
case 0x2: goto o122;
case 0x3: goto o123;
case 0x4: goto o124;
case 0x8: goto o128;
case 0x9: goto o129;
case 0xA: goto o12A;
case 0xB: goto o12B;
case 0xC: goto o12C; } goto o_invalid3;
case 0x3: switch(I[2]) {
case 0x0: goto o130;
case 0x1: goto o131;
case 0x2: goto o132;
case 0x3: goto o133;
case 0x4: goto o134;
case 0x5: goto o135;
case 0x6: goto o136;
case 0x7: goto o137;
case 0x8: goto o138;
case 0x9: goto o139;
case 0xA: goto o13A;
case 0xB: goto o13B;
case 0xC: goto o13C;
case 0xD: goto o13D;
case 0xE: goto o13E;
case 0xF: goto o13F; } goto o_invalid;
case 0x4: switch(I[2]) {
case 0x0: goto o140;
case 0x1: goto o141;
case 0x2: goto o142;
case 0x3: goto o143;
case 0x4: goto o144;
case 0x5: goto o145;
case 0x6: goto o146;
case 0x7: goto o147;
case 0x8: goto o148;
case 0x9: goto o149;
case 0xA: goto o14A;
case 0xB: goto o14B;
case 0xC: goto o14C;
case 0xD: goto o14D;
case 0xE: goto o14E;
case 0xF: goto o14F; } goto o_invalid;
case 0x5: switch(I[2]) {
case 0x0: goto o150a;
case 0x1: goto o151a;
case 0x2: goto o152a;
case 0x3: goto o153a;
case 0x4: goto o154a;
case 0x5: goto o155a;
case 0x6: goto o156a;
case 0x7: goto o157a;
case 0x8: goto o158x;
case 0x9: goto o159x;
case 0xA: goto o15Ax;
case 0xB: goto o15Bx;
case 0xC: goto o15Cx;
case 0xD: goto o15Dx;
case 0xE: goto o15Ex;
case 0xF: goto o15Fx; } goto o_invalid;
case 0x6: goto o16x;
case 0x7: goto o17x;
case 0x8: goto o18x;
case 0x9: goto o19d2;
case 0xA: goto o1Ad4;
case 0xB: goto o1Bd5;
case 0xC: goto o1Cx;
case 0xD: goto o1Dd2;
case 0xE: goto o1Ed4;
case 0xF: goto o1Fd5; } goto o_invalid;
case 0x2: goto o2n;
case 0x3: goto o3X;
case 0x4: goto o4d2;
case 0x5: goto o5d2;
case 0x6: goto o6d3;
case 0x7: goto o7d3;
case 0x8: switch(I[1]) {
case 0x0: switch(I[2]) {
case 0x0: goto o800;
case 0x1: goto o801;
case 0x2: goto o802;
case 0x3: goto o803;
case 0x4: goto o804;
case 0x5: goto o805;
case 0x6: goto o806;
case 0x7: goto o807;
case 0x8: switch(I[3]) {
case 0x0: goto o8080;
case 0x1: if (I[4]) goto o_invalid5; goto o80810;
case 0x2: goto o8082X;
case 0x3: goto o8083;
case 0x4: goto o8084n;
case 0x5: goto o8085n;
case 0x6: goto o8086n;
case 0x7: goto o8087n;
case 0x8: goto o8088n;
case 0x9: goto o8089n;
case 0xA: goto o808An;
case 0xB: goto o808Bn;
case 0xC: goto o808C;
case 0xD: goto o808D;
case 0xE: goto o808E;
case 0xF: goto o808F; } goto o_invalid;
case 0x9: goto o809;
case 0xA: goto o80A;
case 0xB: goto o80B;
case 0xC: goto o80Cn;
case 0xD: goto o80Dn;
case 0xE: goto o80E;
case 0xF: goto o80Fn; } goto o_invalid;
case 0x1: switch(I[2]) {
case 0x0: goto o810;
case 0x1: goto o811;
case 0x2: goto o812;
case 0x3: goto o813;
case 0x4: goto o814;
case 0x5: goto o815;
case 0x6: goto o816;
case 0x7: goto o817;
case 0x8: switch(I[4]) {
case 0x0: goto o818f0x;
case 0x1: goto o818f1x;
case 0x2: goto o818f2x;
case 0x3: goto o818f3x;
case 0x8: goto o818f8x;
case 0x9: goto o818f9x;
case 0xA: goto o818fAx;
case 0xB: goto o818fBx; } goto o_invalid6;
case 0x9: switch(I[4]) {
case 0x0: goto o819f0;
case 0x1: goto o819f1;
case 0x2: goto o819f2;
case 0x3: goto o819f3; } goto o_invalid5;
case 0xA: switch(I[4]) {
case 0x0: switch(I[5]) {
case 0x0: goto o81Af00;
case 0x1: goto o81Af01;
case 0x2: goto o81Af02;
case 0x3: goto o81Af03;
case 0x4: goto o81Af04;
case 0x8: goto o81Af08;
case 0x9: goto o81Af09;
case 0xA: goto o81Af0A;
case 0xB: goto o81Af0B;
case 0xC: goto o81Af0C; } goto o_invalid6;
case 0x1: switch(I[5]) {
case 0x0: goto o81Af10;
case 0x1: goto o81Af11;
case 0x2: goto o81Af12;
case 0x3: goto o81Af13;
case 0x4: goto o81Af14;
case 0x8: goto o81Af18;
case 0x9: goto o81Af19;
case 0xA: goto o81Af1A;
case 0xB: goto o81Af1B;
case 0xC: goto o81Af1C; } goto o_invalid6;
case 0x2: switch(I[5]) {
case 0x0: goto o81Af20;
case 0x1: goto o81Af21;
case 0x2: goto o81Af22;
case 0x3: goto o81Af23;
case 0x4: goto o81Af24;
case 0x8: goto o81Af28;
case 0x9: goto o81Af29;
case 0xA: goto o81Af2A;
case 0xB: goto o81Af2B;
case 0xC: goto o81Af2C; } goto o_invalid6; } goto o_invalid5;
case 0xB: switch(I[3]) {
case 0x2: goto o81B2;
case 0x3: goto o81B3;
case 0x4: goto o81B4;
case 0x5: goto o81B5;
case 0x6: goto o81B6;
case 0x7: goto o81B7; } goto o_invalid4;
case 0xC: goto o81C;
case 0xD: goto o81D;
case 0xE: goto o81E;
case 0xF: goto o81F; } goto o_invalid;
case 0x2: goto o82n;
case 0x3: goto o83n;
case 0x4: goto o84n;
case 0x5: goto o85n;
case 0x6: goto o86n;
case 0x7: goto o87n;
case 0x8: goto o88n;
case 0x9: goto o89n;
case 0xA: switch(I[2]) {
case 0x0: goto o8A0;
case 0x1: goto o8A1;
case 0x2: goto o8A2;
case 0x3: goto o8A3;
case 0x4: goto o8A4;
case 0x5: goto o8A5;
case 0x6: goto o8A6;
case 0x7: goto o8A7;
case 0x8: goto o8A8;
case 0x9: goto o8A9;
case 0xA: goto o8AA;
case 0xB: goto o8AB;
case 0xC: goto o8AC;
case 0xD: goto o8AD;
case 0xE: goto o8AE;
case 0xF: goto o8AF;} goto o_invalid;
case 0xB: switch(I[2]) {
case 0x0: goto o8B0;
case 0x1: goto o8B1;
case 0x2: goto o8B2;
case 0x3: goto o8B3;
case 0x4: goto o8B4;
case 0x5: goto o8B5;
case 0x6: goto o8B6;
case 0x7: goto o8B7;
case 0x8: goto o8B8;
case 0x9: goto o8B9;
case 0xA: goto o8BA;
case 0xB: goto o8BB;
case 0xC: goto o8BC;
case 0xD: goto o8BD;
case 0xE: goto o8BE;
case 0xF: goto o8BF; } goto o_invalid;
case 0xC: goto o8Cd4;
case 0xD: goto o8Dd5;
case 0xE: goto o8Ed4;
case 0xF: goto o8Fd5; } goto o_invalid;
case 0x9: if (I[1]<8) { switch(I[2]) {
case 0x0: goto o9a0;
case 0x1: goto o9a1;
case 0x2: goto o9a2;
case 0x3: goto o9a3;
case 0x4: goto o9a4;
case 0x5: goto o9a5;
case 0x6: goto o9a6;
case 0x7: goto o9a7;
case 0x8: goto o9a8;
case 0x9: goto o9a9;
case 0xA: goto o9aA;
case 0xB: goto o9aB;
case 0xC: goto o9aC;
case 0xD: goto o9aD;
case 0xE: goto o9aE;
case 0xF: goto o9aF; } goto o_invalid;
} else { switch(I[2]) {
case 0x0: goto o9b0;
case 0x1: goto o9b1;
case 0x2: goto o9b2;
case 0x3: goto o9b3;
case 0x4: goto o9b4;
case 0x5: goto o9b5;
case 0x6: goto o9b6;
case 0x7: goto o9b7;
case 0x8: goto o9b8;
case 0x9: goto o9b9;
case 0xA: goto o9bA;
case 0xB: goto o9bB;
case 0xC: goto o9bC;
case 0xD: goto o9bD;
case 0xE: goto o9bE;
case 0xF: goto o9bF; } goto o_invalid; }
case 0xA: if (I[1]<8) { switch(I[2]) {
case 0x0: goto oAa0;
case 0x1: goto oAa1;
case 0x2: goto oAa2;
case 0x3: goto oAa3;
case 0x4: goto oAa4;
case 0x5: goto oAa5;
case 0x6: goto oAa6;
case 0x7: goto oAa7;
case 0x8: goto oAa8;
case 0x9: goto oAa9;
case 0xA: goto oAaA;
case 0xB: goto oAaB;
case 0xC: goto oAaC;
case 0xD: goto oAaD;
case 0xE: goto oAaE;
case 0xF: goto oAaF; } goto o_invalid;
} else { switch(I[2]) {
case 0x0: goto oAb0;
case 0x1: goto oAb1;
case 0x2: goto oAb2;
case 0x3: goto oAb3;
case 0x4: goto oAb4;
case 0x5: goto oAb5;
case 0x6: goto oAb6;
case 0x7: goto oAb7;
case 0x8: goto oAb8;
case 0x9: goto oAb9;
case 0xA: goto oAbA;
case 0xB: goto oAbB;
case 0xC: goto oAbC;
case 0xD: goto oAbD;
case 0xE: goto oAbE;
case 0xF: goto oAbF; } goto o_invalid; }
case 0xB: if (I[1]<8) { switch(I[2]) {
case 0x0: goto oBa0;
case 0x1: goto oBa1;
case 0x2: goto oBa2;
case 0x3: goto oBa3;
case 0x4: goto oBa4;
case 0x5: goto oBa5;
case 0x6: goto oBa6;
case 0x7: goto oBa7;
case 0x8: goto oBa8;
case 0x9: goto oBa9;
case 0xA: goto oBaA;
case 0xB: goto oBaB;
case 0xC: goto oBaC;
case 0xD: goto oBaD;
case 0xE: goto oBaE;
case 0xF: goto oBaF; } goto o_invalid;
} else { switch(I[2]) {
case 0x0: goto oBb0;
case 0x1: goto oBb1;
case 0x2: goto oBb2;
case 0x3: goto oBb3;
case 0x4: goto oBb4;
case 0x5: goto oBb5;
case 0x6: goto oBb6;
case 0x7: goto oBb7;
case 0x8: goto oBb8;
case 0x9: goto oBb9;
case 0xA: goto oBbA;
case 0xB: goto oBbB;
case 0xC: goto oBbC;
case 0xD: goto oBbD;
case 0xE: goto oBbE;
case 0xF: goto oBbF; } goto o_invalid;}
case 0xC: switch(I[1]) {
case 0x0: goto oC0;
case 0x1: goto oC1;
case 0x2: goto oC2;
case 0x3: goto oC3;
case 0x4: goto oC4;
case 0x5: goto oC5;
case 0x6: goto oC6;
case 0x7: goto oC7;
case 0x8: goto oC8;
case 0x9: goto oC9;
case 0xA: goto oCA;
case 0xB: goto oCB;
case 0xC: goto oCC;
case 0xD: goto oCD;
case 0xE: goto oCE;
case 0xF: goto oCF; } goto o_invalid;
case 0xD: switch(I[1]) {
case 0x0: goto oD0;
case 0x1: goto oD1;
case 0x2: goto oD2;
case 0x3: goto oD3;
case 0x4: goto oD4;
case 0x5: goto oD5;
case 0x6: goto oD6;
case 0x7: goto oD7;
case 0x8: goto oD8;
case 0x9: goto oD9;
case 0xA: goto oDA;
case 0xB: goto oDB;
case 0xC: goto oDC;
case 0xD: goto oDD;
case 0xE: goto oDE;
case 0xF: goto oDF; } goto o_invalid;
case 0xE: switch(I[1]) {
case 0x0: goto oE0;
case 0x1: goto oE1;
case 0x2: goto oE2;
case 0x3: goto oE3;
case 0x4: goto oE4;
case 0x5: goto oE5;
case 0x6: goto oE6;
case 0x7: goto oE7;
case 0x8: goto oE8;
case 0x9: goto oE9;
case 0xA: goto oEA;
case 0xB: goto oEB;
case 0xC: goto oEC;
case 0xD: goto oED;
case 0xE: goto oEE;
case 0xF: goto oEF; } goto o_invalid;
case 0xF: switch(I[1]) {
case 0x0: goto oF0;
case 0x1: goto oF1;
case 0x2: goto oF2;
case 0x3: goto oF3;
case 0x4: goto oF4;
case 0x5: goto oF5;
case 0x6: goto oF6;
case 0x7: goto oF7;
case 0x8: goto oF8;
case 0x9: goto oF9;
case 0xA: goto oFA;
case 0xB: goto oFB;
case 0xC: goto oFC;
case 0xD: goto oFD;
case 0xE: goto oFE;
case 0xF: goto oFF; } goto o_invalid; } goto o_invalid;


896
HARDWARE.C Normal file
View file

@ -0,0 +1,896 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#define NEW 1
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef IN
#undef OUT
#include <stdlib.h>
#include <memory.h>
#include "emu48.h"
#include "resource.h"
#include <stdio.h>
#include <stdarg.h>
#define DEBUG 1
#include "pcpdebug.h"
DEBUG_PRINTF_FUNCDEF("emu48.log")
#define W_WIDTH 264
#define W_HEIGHT 396
#define KBD_UP 144
#define KBD_DOWN 342
#define KBD_LEFT 30
#define KBD_RIGHT 234
HANDLE hInst;
HANDLE hWindow;
HANDLE hThreadEmulate;
HANDLE hKeyboard, hPix4, hIdle;
HANDLE hMemoryDC;
DWORD ThreadID1;
CHAR Buf[80];
display_t display;
char kbd_row[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int KDN, KDN_rising_edge, IR15X;
int thread_suspended = 0;
int keyprocessed = 0;
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void about_box();
/*************************************************************************\
*
* FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
*
\*************************************************************************/
int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
WNDCLASS wc;
UNREFERENCED_PARAMETER( lpCmdLine );
UNREFERENCED_PARAMETER( hPrevInstance );
// check if Win32s, if so, display notice and terminate
if(GetVersion()&0x80000000 && (GetVersion()&0xFF)==3) {
MessageBox( NULL,
"This application cannot run on Windows 3.1.\n"
"This application will now terminate.",
"HP48SX",
MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
return 1;
}
hInst = hInstance;
wc.style = CS_BYTEALIGNCLIENT;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, "Emu48_Icon");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = "Emu48_Menu";
wc.lpszClassName = "Emu48Class";
RegisterClass(&wc);
hWindow = CreateWindow("Emu48Class", "HP48SX",
WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
W_WIDTH, W_HEIGHT, NULL, NULL, hInstance, NULL);
ShowWindow(hWindow, nCmdShow);
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage (&msg); // Dispatch message to window.
Sleep(0);
}
return msg.wParam; // Returns value from PostQuitMessage.
}
/*************************************************************************\
*
* FUNCTION: MainWndProc (HWND, UINT, WPARAM, LPARAM)
*
\*************************************************************************/
LRESULT CALLBACK MainWndProc (HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
short x, y;
HDC hDC;
switch (message) {
case WM_CREATE :
/* about_box(); */
hKeyboard = LoadBitmap(hInst, "Emu48_Keyboard");
hPix4 = LoadBitmap(hInst, "Emu48_Pix4");
hIdle = LoadBitmap(hInst, "Emu48_Idle");
hDC = GetDC(hwnd);
hMemoryDC = CreateCompatibleDC(hDC);
SelectObject(hMemoryDC, hPix4);
ReleaseDC(hwnd, hDC);
load();
if (display.pointer==NULL) display.pointer = rom;
saturn_speed = 5000;
// Create the emulator thread
hThreadEmulate = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)emulate,
NULL, 0, (LPDWORD)&ThreadID1);
if (!hThreadEmulate) {
wsprintf(Buf, "Error in creating Emulator thread: %d", GetLastError());
MessageBox (hwnd, Buf, "WM_CREATE", MB_OK);
}
return 0;
case WM_RBUTTONDOWN:
case WM_LBUTTONDOWN: // Left mouse button pressed
x = ((short*)&lParam)[0];
y = ((short*)&lParam)[1];
if (x<KBD_LEFT) break;
if (x>KBD_RIGHT) break;
if (y<KBD_UP) break;
if (y>KBD_DOWN) break;
x = (x-KBD_LEFT)/34;
y = (y-KBD_UP)/22;
kbd_handler((y<<4)|x,1);
return 0;
#if NEW
case WM_CHAR:
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{
MSG msg; int i;
msg.hwnd = hwnd;
msg.message = message;
msg.wParam = wParam;
msg.lParam = lParam;
dsx(lParam);
dsx(wParam);
i = translatekeys(&msg);
/* capture system key */
if (i && message == WM_SYSKEYDOWN)
return 0;
}
break;
#else
case WM_CHAR:
ds(("WM_CHAR\n"))
dsx(lParam);
dsx(wParam);
presskeys(lParam, wParam, 1);
break;
case WM_KEYDOWN:
ds(("WM_KEYDOWN\n"))
dsx(lParam);
dsx(wParam);
if (lParam & 0x1000000L)
presskeys(lParam, wParam, 1);
break;
#endif
case WM_LBUTTONUP: // Left mouse button released
x = ((short*)&lParam)[0];
y = ((short*)&lParam)[1];
if (x<KBD_LEFT) break;
if (x>KBD_RIGHT) break;
if (y<KBD_UP) break;
if (y>KBD_DOWN) break;
x = (x-KBD_LEFT)/34;
y = (y-KBD_UP)/22;
kbd_handler((y<<4)|x,0);
return 0;
case WM_ERASEBKGND: // Erase background
hDC = GetDC(hwnd);
PatBlt(hDC, 0, 0, W_WIDTH, W_HEIGHT, BLACKNESS);
PatBlt(hDC, 0, 0, 262, 129, WHITENESS);
SelectObject(hMemoryDC, hKeyboard);
BitBlt(hDC, KBD_LEFT, KBD_UP, 204, 198, hMemoryDC, 0, 0, SRCCOPY);
if (thread_suspended) {
SelectObject(hMemoryDC, hIdle);
BitBlt(hDC, 0, 0, 262, 128, hMemoryDC, 0, 0, SRCCOPY);
}
ReleaseDC(hwnd, hDC);
SelectObject(hMemoryDC, hPix4);
if (!thread_suspended) {
display_redraw();
display_ann();
}
return 0;
case WM_CLOSE:
save();
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case ID_SYSTEM_EXIT:
DestroyWindow(hwnd);
break;
case ID_SAVE:
save();
break;
case ID_HELP_ABOUT:
about_box();
break;
}
return 0;
case WM_DESTROY:
TerminateThread(hThreadEmulate, 0);
DeleteDC(hMemoryDC);
DeleteObject(hKeyboard);
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
/*************************************************************************\
*
* FUNCTION: display_error()
*
\*************************************************************************/
void about_box() {
display_warning(
"Emu48 version "VERSION", Copyright (C) 1995 Sebastien Carlier\n"
"This is free software, and you are welcome to redistribute it\n"
"under certain conditions; see COPYING for details.\n");
return;
}
/*************************************************************************\
*
* FUNCTION: display_error()
*
\*************************************************************************/
void display_error(char *s) {
MessageBox(NULL,s,"Emu48",MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
exit(1);
}
/*************************************************************************\
*
* FUNCTION: display_warning()
*
\*************************************************************************/
void display_warning(char *s) {
MessageBox(NULL,s,"Emu48",MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND);
return;
}
/*************************************************************************\
*
* FUNCTION: display_redraw()
*
\*************************************************************************/
void display_redraw() {
int y;
display.line = 0;
display.lcounter = display.lcntsave;
display.pointer = nibble_ptr(display.start1);
display.disoffs = 0;
if (display.dispon)
for (y=0; y<64; y++) display_line();
else
display_clear();
if (display.boffset&4)
display.end1 = display.start1 + (display.lcntsave+1)*(display.loffset+36);
else
display.end1 = display.start1 + (display.lcntsave+1)*(display.loffset+34);
if (display.end1 < display.start1) {
display.start12 = display.end1;
display.end1 = display.start1;
} else display.start12 = display.start1;
display.end2 = display.start2 + (63 - display.lcntsave)*34;
display.touched = 0;
return;
}
/*************************************************************************\
*
* FUNCTION: display_line()
*
\*************************************************************************/
#define SET4PIXELS(x,y,m) BitBlt(hDC, 2*x, y, 8, 2, hMemoryDC,0, (m)*2, SRCCOPY);
void display_line() {
HDC hDC;
char *ptr;
int x, y;
if (!display.dispon) return;
// c = display.contrast;
y = 2*display.line;
hDC = GetDC(hWindow);
if (display.disoffs) {
ptr = display.pointer;
for (x=0; x<128; x+=4)
SET4PIXELS(x,y,*(ptr++));
SET4PIXELS(x,y,*ptr & 7);
} else {
if (display.boffset&4) display.pointer++;
ptr = display.pointer;
switch (display.boffset&3) {
case 0:
for (x=0; x<128; x+=4)
SET4PIXELS(x,y,*(ptr++));
SET4PIXELS(x,y,*ptr & 7);
break;
case 1:
SET4PIXELS(0,y, *(ptr++) >> 1);
for (x=3; x<127; x+=4)
SET4PIXELS(x,y,*(ptr++));
SET4PIXELS(x,y,*ptr);
break;
case 2:
SET4PIXELS(0,y, *(ptr++) >> 2);
for (x=2; x<130; x+=4)
SET4PIXELS(x,y,*(ptr++));
SET4PIXELS(x,y,*ptr & 1);
break;
case 3:
SET4PIXELS(0,y, *(ptr++) >> 3);
for (x=1; x<129; x+=4)
SET4PIXELS(x,y,*(ptr++));
SET4PIXELS(x,y,*ptr & 3);
break;
}
}
ReleaseDC(hWindow, hDC);
display_next();
return;
}
/*************************************************************************\
*
* FUNCTION: display_plot1(long d, char m)
*
\*************************************************************************/
void display_plot1(long d, char m) {
int x, y, w;
HDC hDC;
d -= display.start12;
w = 34 + display.loffset;
if (display.boffset&4) w+=2;
if (w==0) return;
if (w<0)
y = d / w + display.lcntsave + 1;
else
y = d / w;
if (y<0) return;
if (y>display.lcntsave) return;
x = (d % w) * 4;
if (display.boffset) {
x -= display.boffset;
if (x<0) return;
}
if (x>130) return;
hDC = GetDC(hWindow);
SET4PIXELS(x,y*2,m)
ReleaseDC(hWindow, hDC);
return;
}
/*************************************************************************\
*
* FUNCTION: display_plot2(long d, char m)
*
\*************************************************************************/
void display_plot2(long d, char m) {
int x, y;
HDC hDC;
d -= display.start2;
y = display.lcntsave + (d / 34) + 1;
x = (d % 34) * 4;
if (x==128) m&=7;
hDC = GetDC(hWindow);
SET4PIXELS(x,y*2,m)
ReleaseDC(hWindow, hDC);
return;
}
/*************************************************************************\
*
* FUNCTION: display_next()
*
\*************************************************************************/
void display_next() {
display.line++;
if (display.line >= 64) { /* new refresh cycle */
display.line = 0;
display.lcounter = display.lcntsave;
display.pointer = nibble_ptr(display.start1);
display.disoffs = 0;
return;
}
if (display.disoffs) {
display.pointer += 34;
return;
}
if (display.lcounter) {
display.lcounter--;
display.pointer += 34 + display.loffset;
if (display.boffset&4) display.pointer++;
return;
}
display.pointer = nibble_ptr(display.start2);
display.disoffs = 1;
return;
}
void init_lcd() {
display.pointer = rom;
return;
}
void exit_lcd() {
return;
}
/*************************************************************************\
*
* FUNCTION: display_çlear()
*
\*************************************************************************/
void display_clear() {
HDC hDC;
hDC = GetDC(hWindow);
PatBlt(hDC, 0, 0, 262, 128, WHITENESS);
ReleaseDC(hWindow, hDC);
return;
}
/*************************************************************************\
*
* FUNCTION: display_ann()
*
\*************************************************************************/
void display_ann() {
HDC hDC;
unsigned short c;
hDC = GetDC(hWindow);
c = *(unsigned short*)(ioram+0x0b);
if (!(c&0x0800)) c=0;
PatBlt(hDC, 16+32*1, 132, 4, 4, (c&0x001)?WHITENESS:BLACKNESS);
PatBlt(hDC, 16+32*2, 132, 4, 4, (c&0x002)?WHITENESS:BLACKNESS);
PatBlt(hDC, 16+32*3, 132, 4, 4, (c&0x004)?WHITENESS:BLACKNESS);
PatBlt(hDC, 16+32*4, 132, 4, 4, (c&0x008)?WHITENESS:BLACKNESS);
PatBlt(hDC, 16+32*5, 132, 4, 4, (c&0x100)?WHITENESS:BLACKNESS);
PatBlt(hDC, 16+32*6, 132, 4, 4, (c&0x200)?WHITENESS:BLACKNESS);
ReleaseDC(hWindow, hDC);
return;
}
/*************************************************************************\
*
* FUNCTION: keyboard_invert()
*
\*************************************************************************/
void kbd_invert(int x, int y) {
HDC hDC;
hDC = GetDC(hWindow);
PatBlt(hDC, 1+KBD_LEFT+34*x, 1+KBD_UP+22*y, 33, 21, DSTINVERT);
ReleaseDC(hWindow, hDC);
return;
}
/*************************************************************************\
*
* FUNCTION: keyboard_invert2()
*
\*************************************************************************/
void kbd_invert2(int x, int y) {
HDC hDC;
hDC = GetDC(hWindow);
PatBlt(hDC, 1+KBD_LEFT+34*x, 1+KBD_UP+22*y, 67, 21, DSTINVERT);
ReleaseDC(hWindow, hDC);
return;
}
/*************************************************************************\
*
* FUNCTION: keyboard_handler(unsigned char scancode, int press)
*
\*************************************************************************/
void kbd_handler(int scancode, int press)
{
int mask, row;
dsx(scancode);
if (scancode == 0x81) /*ON*/ {
if (press) {
if (!IR15X) { kbd_invert(scancode&0xf, scancode>>4); IR15X = 0x8000; }
} else {
if (IR15X) { kbd_invert(scancode&0xf, scancode>>4); IR15X = 0x0000; }
}
}
if (ioram[0x2f]&1 == 0) return;
switch (scancode) {
case 0x00: row = 1; mask = 0x0010; break;
case 0x01: row = 8; mask = 0x0010; break;
case 0x02: row = 8; mask = 0x0008; break;
case 0x03: row = 8; mask = 0x0004; break;
case 0x04: row = 8; mask = 0x0002; break;
case 0x05: row = 8; mask = 0x0001; break;
case 0x10: row = 2; mask = 0x0010; break;
case 0x11: row = 7; mask = 0x0010; break;
case 0x12: row = 7; mask = 0x0008; break;
case 0x13: row = 7; mask = 0x0004; break;
case 0x14: row = 7; mask = 0x0002; break;
case 0x15: row = 7; mask = 0x0001; break;
case 0x20: row = 0; mask = 0x0010; break;
case 0x21: row = 6; mask = 0x0010; break;
case 0x22: row = 6; mask = 0x0008; break;
case 0x23: row = 6; mask = 0x0004; break;
case 0x24: row = 6; mask = 0x0002; break;
case 0x25: row = 6; mask = 0x0001; break;
case 0x30: row = 3; mask = 0x0010; break;
case 0x31: row = 5; mask = 0x0010; break;
case 0x32: row = 5; mask = 0x0008; break;
case 0x33: row = 5; mask = 0x0004; break;
case 0x34: row = 5; mask = 0x0002; break;
case 0x35: row = 5; mask = 0x0001; break;
case 0x40: row = 4; mask = 0x0010; break;
case 0x41: row = 4; mask = 0x0010; break;
case 0x42: row = 4; mask = 0x0008; break;
case 0x43: row = 4; mask = 0x0004; break;
case 0x44: row = 4; mask = 0x0002; break;
case 0x45: row = 4; mask = 0x0001; break;
case 0x51: row = 3; mask = 0x0020; break;
case 0x52: row = 3; mask = 0x0008; break;
case 0x53: row = 3; mask = 0x0004; break;
case 0x54: row = 3; mask = 0x0002; break;
case 0x55: row = 3; mask = 0x0001; break;
case 0x61: row = 2; mask = 0x0020; break;
case 0x62: row = 2; mask = 0x0008; break;
case 0x63: row = 2; mask = 0x0004; break;
case 0x64: row = 2; mask = 0x0002; break;
case 0x65: row = 2; mask = 0x0001; break;
case 0x71: row = 1; mask = 0x0020; break;
case 0x72: row = 1; mask = 0x0008; break;
case 0x73: row = 1; mask = 0x0004; break;
case 0x74: row = 1; mask = 0x0002; break;
case 0x75: row = 1; mask = 0x0001; break;
case 0x82: row = 0; mask = 0x0008; break;
case 0x83: row = 0; mask = 0x0004; break;
case 0x84: row = 0; mask = 0x0002; break;
case 0x85: row = 0; mask = 0x0001; break;
case 0x50:
kbd_invert(scancode&0xf, scancode>>4);
if (press) {
HDC hDC;
SuspendThread(hThreadEmulate);
thread_suspended = 1;
hDC = GetDC(hWindow);
SelectObject(hMemoryDC, hIdle);
BitBlt(hDC, 0, 0, 262, 128, hMemoryDC, 0, 0, SRCCOPY);
ReleaseDC(hWindow, hDC);
SelectObject(hMemoryDC, hPix4);
}
return;
case 0x60:
kbd_invert(scancode&0xf, scancode>>4);
if (press) {
thread_suspended = 0;
ResumeThread(hThreadEmulate);
display_redraw();
display_ann();
}
return;
case 0x70:
kbd_invert(scancode&0xf, scancode>>4);
return;
case 0x80:
kbd_invert(scancode&0xf, scancode>>4);
return;
default: return;
}
if (press) {
if ((kbd_row[row]&mask)==0) {
KDN_rising_edge = 1;
KDN++;
if ((scancode==0x40)||(scancode==0x41))
kbd_invert2(0, 4);
else
kbd_invert(scancode&0xf, scancode>>4);
kbd_row[row]|=mask;
}
} else {
if (kbd_row[row]&mask) {
KDN--;
if ((scancode==0x40)||(scancode==0x41))
kbd_invert2(0, 4);
else
kbd_invert(scancode&0xf, scancode>>4);
kbd_row[row]&=~mask;
}
}
return;
}
void presskeys(unsigned lparam, unsigned wparam, int down)
{
int scancode = -1;
int state=0;
state = (GetKeyState(VK_LSHIFT) & 0x8000) ? 0x100 : 0;
state |= (GetKeyState(VK_RSHIFT) & 0x8000) ? 0x200 : 0;
state |= (GetKeyState(VK_CONTROL) & 0x8000) ? 0x400 : 0;
state |= (GetKeyState(VK_MENU) & 0x8000) ? 0x800 : 0;
dsx(wparam);
if (isalpha(wparam)) wparam = toupper(wparam);
dsx(wparam);
if (wparam >= 'A' && wparam <= 'X')
{
int row = (wparam - 'A') / 6;
int col = (wparam - 'A') % 6;
scancode = row * 0x10 + col;
}
else if (!(lparam & 0x1000000L) )
{
switch (wparam)
{
case '\n':
case '\r': scancode = 0x41; break;
case '0': scancode = 0x82; break;
case '1': scancode = 0x72; break;
case '2': scancode = 0x73; break;
case '3': scancode = 0x74; break;
case '4': scancode = 0x62; break;
case '5': scancode = 0x63; break;
case '6': scancode = 0x64; break;
case '7': scancode = 0x52; break;
case '8': scancode = 0x53; break;
case '9': scancode = 0x54; break;
case '.': scancode = 0x83; break;
case ' ': scancode = 0x84; break;
case '+': scancode = 0x85; break;
case '-': scancode = 0x75; break;
case '*': scancode = 0x65; break;
case '/': scancode = 0x55; break;
case 'Y': scancode = 0x42; break;
case '\'': scancode = 0x20; break;
case 'Z': scancode = 0x43; break;
case 0x1B: scancode = 0x81; break;
case '\b': scancode = 0x45; break;
case '\t': scancode = 0x15; break;
default:
break;
}
}
else if ((lparam & 0x1000000L) || (wparam >= VK_F1 && wparam <= VK_F6)) switch (wparam)
{
case VK_RETURN: scancode = 0x41; break;
case VK_LEFT: scancode = 0x23; break;
case VK_UP: scancode = 0x14; break;
case VK_RIGHT: scancode = 0x25; break;
case VK_DOWN: scancode = 0x24; break;
case VK_CONTROL: scancode = 0x51; break;
case VK_PRIOR: if (!(state & 0x300)) scancode = 0x61; break;
case VK_NEXT: if (!(state & 0x300)) scancode = 0x71; break;
case VK_F1: scancode = 0x00; break;
case VK_F2: scancode = 0x01; break;
case VK_F3: scancode = 0x02; break;
case VK_F4: scancode = 0x03; break;
case VK_F5: scancode = 0x04; break;
case VK_F6: scancode = 0x05; break;
}
dsx(state);
if (scancode != -1)
{
/* if (state & 0x100)
presskeys(0x01000000, VK_PRIOR, 0);
else if (state & 0x200)
presskeys(0x01000000, VK_NEXT, 0); */
kbd_handler(scancode, 1);
Sleep(100);
kbd_handler(scancode, 0);
}
}
void update_in() {
IN = IR15X;
if (OUT & 0x001) IN|=kbd_row[0];
if (OUT & 0x002) IN|=kbd_row[1];
if (OUT & 0x004) IN|=kbd_row[2];
if (OUT & 0x008) IN|=kbd_row[3];
if (OUT & 0x010) IN|=kbd_row[4];
if (OUT & 0x020) IN|=kbd_row[5];
if (OUT & 0x040) IN|=kbd_row[6];
if (OUT & 0x080) IN|=kbd_row[7];
if (OUT & 0x100) IN|=kbd_row[8];
return;
}
void init_keyboard() {
return;
}
void exit_keyboard() {
return;
}
#if NEW
#define IGNORE_WM_CHAR 0x8000
int keyevent(long key)
{
int scancode = -1, retval = 0;
dsx(key);
if (key >= 'a' && key <= 'z') key = toupper(key);
dsx(key);
dsx(KEYC_PGDN);
if (key >= 'A' && key <= 'X')
{
int row = (key - 'A') / 6;
int col = (key - 'A') % 6;
scancode = row * 0x10 + col;
}
else switch (key)
{
case '0': scancode = 0x82; break;
case '1': scancode = 0x72; break;
case '2': scancode = 0x73; break;
case '3': scancode = 0x74; break;
case '4': scancode = 0x62; break;
case '5': scancode = 0x63; break;
case '6': scancode = 0x64; break;
case '7': scancode = 0x52; break;
case '8': scancode = 0x53; break;
case '9': scancode = 0x54; break;
case '.': scancode = 0x83; break;
case ' ': scancode = 0x84; break;
case '+': scancode = 0x85; break;
case '-': scancode = 0x75; break;
case '*': scancode = 0x65; break;
case '/': scancode = 0x55; break;
case 'Y': scancode = 0x42; break;
case '\'': scancode = 0x20; break;
case 'Z': scancode = 0x43; break;
case '`': scancode = 0x51; break;
case '\n':
case '\r': scancode = 0x41; retval = 1; break;
case 0x1B: scancode = 0x81; retval = 1; break;
case '\b': scancode = 0x45; retval = 1; break;
case '\\':
case '\t': scancode = 0x15; retval = 1; break;
case KEYC_LEFT: scancode = 0x23; break;
case KEYC_UP: scancode = 0x14; break;
case KEYC_RIGHT: scancode = 0x25; break;
case KEYC_DOWN: scancode = 0x24; break;
case KEYC_DELETE: scancode = 0x44; break;
case KEYC_PGUP: scancode = 0x61; break;
case KEYC_PGDN: scancode = 0x71; break;
case KEYF_FKEY+1:
case KEYF_FKEY+2:
case KEYF_FKEY+3:
case KEYF_FKEY+4:
case KEYF_FKEY+5:
case KEYF_FKEY+6:
scancode = key-KEYF_FKEY-1; retval = 1; break;
default: break;
}
dsx(scancode);
if (scancode != -1)
{
/* if (state & 0x100)
presskeys(0x01000000, VK_PRIOR, 0);
else if (state & 0x200)
presskeys(0x01000000, VK_NEXT, 0); */
kbd_handler(scancode, 1);
Sleep(100);
kbd_handler(scancode, 0);
}
return retval;
}
int translatekeys(void * vmsg)
{
MSG *msg = (MSG*) vmsg;
int state=0;
switch(msg->message)
{
case WM_CHAR:
if (keyprocessed & IGNORE_WM_CHAR)
{
keyprocessed &= ~IGNORE_WM_CHAR;
return 1;
}
else
return keyevent(KEYFROMASCII(msg->wParam));
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
state = (GetKeyState(VK_SHIFT) & 0x8000) ? KEYF_SHIFT : 0;
state |= (GetKeyState(VK_CONTROL) & 0x8000) ? KEYF_CTRL : 0;
state |= (GetKeyState(VK_MENU) & 0x8000) ? KEYF_ALT: 0;
if (msg->wParam >= VK_F1 && msg->wParam <= VK_F12)
/* Return function key */
return keyevent((msg->wParam-(VK_F1-1)+KEYF_FKEY)|state);
else
{
int i;
long k;
switch (msg->wParam)
{
case VK_PRIOR:
k = (KEYC_PAGEUP|state); break;
case VK_NEXT:
k = (KEYC_PAGEDOWN|state); break;
case VK_END:
k = (KEYC_END|state); break;
case VK_HOME:
k = (KEYC_HOME|state); break;
case VK_LEFT:
k = (KEYC_LEFT|state); break;
case VK_UP:
k = (KEYC_UP|state); break;
case VK_RIGHT:
k = (KEYC_RIGHT|state); break;
case VK_DOWN:
k = (KEYC_DOWN|state); break;
case VK_INSERT:
k = (KEYC_INSERT|state); break;
case VK_DELETE:
k = (KEYC_DELETE|state); break;
default:
k = (KEYFROMSCAN(msg->wParam)|state); break;
}
i = keyevent(k);
if (i)
keyprocessed |= IGNORE_WM_CHAR;
return i;
}
}
return 0;
}
#endif
/******** BEEP ********/
void update_out() {
/* char c;
__asm__("inb $0x61, %0":"=a"(c));
if (OUT&0x800)
c|=0x02;
else
c&=0xfc;
__asm__("outb %0, $0x61"::"a"(c));
return;
*/
}

86
HARDWARE.H Normal file
View file

@ -0,0 +1,86 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#define keyboard_update() ;
#define INLINE _inline
typedef struct {
int line;
long start1, start12, end1;
long start2, end2;
int loffset;
int boffset;
int lcntsave;
int lcounter;
int dispon;
int contrast;
int noscan;
char *pointer;
int disoffs;
int touched;
} display_t;
extern display_t display;
extern int font[256];
extern int KDN, KDN_rising_edge;
extern int IR15X;
extern char Buf[80];
void setport1(const char *newstring);
extern void init_lcd();
extern void exit_lcd();
extern void display_redraw();
extern void display_line();
extern void display_next();
extern void display_clear();
extern void display_plot1(long d, char m);
extern void display_plot2(long d, char m);
extern void display_ann();
extern void init_keyboard();
extern void exit_keyboard();
extern void kbd_invert(int x, int y);
extern void kbd_handler(int scancode, int press);
extern void update_in();
extern void update_out();
extern void display_warning(char *s);
extern void display_error(char *s);
extern void presskeys(unsigned lparam, unsigned wparam, int down);
#if NEW
#define KEYFROMASCII(ascii) ((unsigned long)(unsigned char) (ascii))
#define KEYFROMSCAN(scan ) (((unsigned long)(unsigned char) (scan)) | KEYF_SCAN)
#define KEYFROMKEYC(scan ) (((unsigned long)(unsigned short) (keyc)) | KEYF_KEYC)
#define KEYFROMCOMMAND(command) (((unsigned long) (command)) | KEYF_COMMAND)
#define KEYF_COMMAND 0x10000L // Cannot be enumerated: compiler bug ?!?
#define KEYF_UP 0x20000L
enum KEYFLAGS { KEYF_SCAN=0x1000, KEYF_KEYC=0x2000, KEYF_FKEY=KEYF_KEYC+100,
KEYF_SHIFT=0x100, KEYF_CTRL=0x400, KEYF_ALT=0x800 } ;
#define KEYC_BACKSPACE 8
#define KEYC_BS KEYC_BACKSPACE
#define KEYC_TAB 9
#define KEYC_ENTER 13
#define KEYC_ESC 27
#define KEYC_DEL (KEYF_KEYC+146)
#define KEYC_DELETE KEYC_DEL
#define KEYC_INSERT (KEYF_KEYC+148)
#define KEYC_INS KEYC_INSERT
#define KEYC_END (KEYF_KEYC+149)
#define KEYC_DOWN (KEYF_KEYC+150)
#define KEYC_PAGEDOWN (KEYF_KEYC+151)
#define KEYC_PGDN KEYC_PAGEDOWN
#define KEYC_LEFT (KEYF_KEYC+152)
#define KEYC_RIGHT (KEYF_KEYC+154)
#define KEYC_HOME (KEYF_KEYC+155)
#define KEYC_UP (KEYF_KEYC+156)
#define KEYC_PAGEUP (KEYF_KEYC+157)
#define KEYC_PGUP KEYC_PAGEUP
int translatekeys(void *);
#endif

516
INSTR.C Normal file
View file

@ -0,0 +1,516 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#include <memory.h>
#include "emu48.h"
#define SIMPLE_DBL 1
#define SIMPLE_XCHG 1
#define FAST_WRITE 1
INLINE long Npack(char *a, int s) {
long r = 0;
while (s--) r = (r<<4)|a[s];
return r;
}
INLINE void Nunpack(char *a, long b, int s) {
int i;
for (i=0; i<s; i++) { a[i] = (char)(b&0xf); b>>=4; }
return;
}
INLINE void Ncopy(char *a, char *b, int s) {
memcpy(a,b,s);
return;
}
INLINE void Nxchg(char *a, char *b, int s) {
#if SIMPLE_XCHG
char X[16];
memcpy(X, b, s);
memcpy(b, a, s);
memcpy(a, X, s);
#else
char t;
while (s--) { t=a[s]; a[s]=b[s]; b[s]=t; }
#endif
return;
}
INLINE void Ninc(char *a, int s) {
int i;
for (i=0; i<s; i++) {
a[i]++;
if (a[i]<MODE) { CARRY = 0; return; }
a[i]-=((char)MODE);
}
CARRY = 1;
return;
}
INLINE void Ndec(char *a, int s) {
int i;
for (i=0; i<s; i++) {
if (a[i]) { a[i]--; CARRY = 0; return; }
a[i] = ((char)MODE)-1;
}
CARRY = 1;
return;
}
INLINE void Nadd(char *a, char *b, int s) {
char carry = 0;
int i;
for (i=0; i<s; i++) {
a[i] += (char)(b[i]+carry);
if (a[i] < MODE)
carry = 0;
else
{ a[i] -= (char)MODE; carry = 1; }
}
CARRY = carry;
return;
}
INLINE void Nsub(char *a, char *b, int s) {
char carry = 0;
int i;
for (i=0; i<s; i++) {
a[i]-=(char)(b[i]+carry);
if (a[i]<0)
{ a[i]+=(char)MODE; carry = 1; }
else
carry = 0;
}
CARRY = carry;
return;
}
INLINE void Nrsub(char *a, char *b, int s) {
char carry = 0;
int i;
for (i=0; i<s; i++) {
a[i]=(char)(b[i]-(a[i]+carry));
if (a[i]<0)
{ a[i]+=(char)MODE; carry = 1; }
else
carry = 0;
}
CARRY = carry;
return;
}
INLINE void Nand(char *a, char *b, int s) {
while (s--) a[s]&=b[s];
return;
}
INLINE void Nor(char *a, char *b, int s) {
while (s--) a[s]|=b[s];
return;
}
INLINE void Nzero(char *a, int s) {
memset(a, 0, s);
return;
}
INLINE void Nnot(char *a, int s) {
char c = ((char)MODE)-1;
while (s--) a[s]=(char)(c-a[s]);
CARRY = 0;
return;
}
INLINE void Nneg(char *a, int s) {
char c = ((char)MODE)-1;
int i;
for (i=0; i<s; i++) if (a[i]) break;
if (i==s) { CARRY=0; return; } /* it was 0 */
CARRY=1;
a[i] = ((char)MODE)-a[i]; /* first non-zero */
for (i++; i<s; i++) a[i]=(char)(c-a[i]);
return;
}
INLINE void Nsl(char *a, int s) {
if (a[s-1])
HST|=SB;
while (--s) a[s]=a[s-1];
(*a)=0;
return;
}
INLINE void Nsr(char *a, int s) {
if (*a) HST|=SB;
while (--s) { (*a)=a[1]; a++; }
(*a)=0;
return;
}
INLINE void Nbit0(char *a, char b) {
a[b>>2]&=~(1<<(b&3));
return;
}
INLINE void Nbit1(char *a, char b) {
a[b>>2]|=1<<(b&3);
return;
}
INLINE void Nslc(char *a, int s) {
char c;
c = a[s-1];
while (--s) a[s] = a[s-1];
*a = c;
return;
}
INLINE void Nsrc(char *a, int s) {
char c = *a;
while (--s) { *a=a[1]; a++; }
*a = c;
return;
}
INLINE void Nsrb(char *a, int s) {
if ((*a)&1) HST|=SB;
while (--s) {
(*a)>>=1;
if (a[1]&1) (*a)|=8;
a++;
}
*a>>=1;
return;
}
INLINE void Ndbl(char *a, int s) {
#if SIMPLE_DBL
char b[16];
memcpy(b, a, s);
Nadd(a, b, s);
#else
char c, carry = 0;
int i;
for (i=0; i<s; i++) {
c = a[i]*2 + carry;
if (c>=MODE)
{ c-=MODE; carry = 1; }
else
carry = 0;
a[i] = c;
}
CARRY = carry;
#endif
return;
}
INLINE void Tbit0(char *a, char b) {
if (a[b>>2]&(1<<(b&3)))
CARRY = 0;
else
CARRY = 1;
return;
}
INLINE void Tbit1(char *a, char b) {
if (a[b>>2]&(1<<(b&3)))
CARRY = 1;
else
CARRY = 0;
return;
}
INLINE void Te(char *a, char *b, int s) {
while (s--) if (a[s]!=b[s]) { CARRY = 0; return; }
CARRY = 1;
return;
}
INLINE void Tne(char *a, char *b, int s) {
while (s--) if (a[s]!=b[s]) { CARRY=1; return; }
CARRY = 0;
return;
}
INLINE void Tz(char *a, int s) {
while (s--) if (a[s]!=0) { CARRY = 0; return; }
CARRY = 1;
return;
}
INLINE void Tnz(char *a, int s) {
while (s--) if (a[s]!=0) { CARRY=1; return; }
CARRY = 0;
return;
}
INLINE void Ta(char *a, char *b, int s) {
while (--s) if (a[s]!=b[s]) break;
CARRY = (a[s]>b[s]);
return;
}
INLINE void Tb(char *a, char *b, int s) {
while (--s) if (a[s]!=b[s]) break;
CARRY = (a[s]<b[s]);
return;
}
INLINE void Tae(char *a, char *b, int s) {
while (--s) if (a[s]!=b[s]) break;
CARRY = (a[s]>=b[s]);
return;
}
INLINE void Tbe(char *a, char *b, int s) {
while (--s) if (a[s]!=b[s]) break;
CARRY = (a[s]<=b[s]);
return;
}
INLINE char read_nibble(long d) {
if (ISMODULE(1, d)) return data[1][d-base[1]];
if (CARDSTATUS&2) if (ISMODULE(3, d)) return data[3][d-base[3]];
if (CARDSTATUS&1) if (ISMODULE(4, d)) return data[4][d-base[4]];
return rom[d];
}
INLINE char* nibble_ptr(long d) {
if (ISMODULE(1, d)) return data[1]+d-base[1];
if (CARDSTATUS&2) if (ISMODULE(3, d)) return data[3]+d-base[3];
if (CARDSTATUS&1) if (ISMODULE(4, d)) return data[4]+d-base[4];
return rom+d;
}
INLINE char read_nibble_crc(long d) {
char n;
if (ISMODULE(0, d)) return read_io(d-base[0]);
if (ISMODULE(1, d)) {n=data[1][d-base[1]];CRC(n);return n;}
if (ISMODULE(2, d)) {bank_switch((int)((d-base[2])/2));return 7;}
if (CARDSTATUS&2) if (ISMODULE(3, d)) {n=data[3][d-base[3]];CRC(n);return n;}
if (CARDSTATUS&1) if (ISMODULE(4, d)) {n=data[4][d-base[4]];CRC(n);return n;}
n=rom[d];
CRC(n);
return n;
}
INLINE void write_nibble(long d, char c) {
#if FAST_WRITE
if (ISMODULE(1, d)) {
if (display.dispon) {
if ((d>=display.start12)&&(d<display.end1)) display_plot1(d, c);
if ((d>=display.start2)&&(d<display.end2)) display_plot2(d, c);
}
data[1][d-base[1]]=c;
return;
}
if (ISMODULE(0, d)) { write_io(d-0x100, c); return; }
#else
if (ISMODULE(0, d)) { write_io(d-0x100, c); return; }
if (ISMODULE(1, d)) {
if (display.dispon) {
if ((d>=display.start12)&&(d<display.end1)) display_plot1(d, c);
if ((d>=display.start2)&&(d<display.end2)) display_plot2(d, c);
}
data[1][d-base[1]]=c;
return;
}
#endif
if (CARDSTATUS&2) if (ISMODULE(3, d)) { data[3][d-base[3]]=c; return; }
if (CARDSTATUS&1) if (ISMODULE(4, d)) { data[4][d-base[4]]=c; return; }
return;
}
INLINE void config() {
int i;
long d;
for (i=0; i<=4; i++)
if (ucfg[i]) break;
if (i==5) return;
d = Npack(C, 5);
switch (i) {
case 0:
data[0] = ioram;
base[0] = d;
size[0] = 0x40;
ucfg[0] = 0;
break;
case 1:
case 2:
case 3:
case 4:
if (ucfg[i]==2) {
base[i] = d;
ucfg[i] = 0;
break;
}
size[i] = 0x100000 - Npack(C, 5);
ucfg[i] = 2;
break;
default:
break;
}
return;
}
INLINE void unconfig() {
int i;
long d;
d = Npack(C, 5);
for (i=0; i<=4; i++)
if (d==base[i]) break;
if (i==5) return;
ucfg[i] = 1;
base[i] = 0;
size[i] = 0;
return;
}
INLINE void reset() {
int i;
for (i=0; i<=4; i++)
ucfg[i] = 1;
return;
}
int chip_id[12] = {
0x00019, 0x00003, 0x00005, 0x00007, 0x00001, 0x00000,
0x00019, 0x000F4, 0x000F6, 0x000F8, 0x000F2, 0x00000
};
INLINE void c_eq_id() {
int i;
long id;
for (i=0; i<=4; i++)
if (ucfg[i]) break;
id = chip_id[(ucfg[i]==2)?(i+6):i];
Nunpack(C, id, 3);
return;
}
INLINE long rstkpop() {
long r;
int t;
t = rstkp;
t--;
t&=7;
rstkp = t;
r = rstk[t];
rstk[t] = 0;
return r;
}
INLINE void rstkpush(long d) {
int t;
t = rstkp;
rstk[t] = d;
t++;
t &= 7;
rstkp = t;
return;
}
INLINE void Nread(char *a, long b, int s) {
int i;
for (i=0; i<s; i++) a[i]=read_nibble(b+i);
return;
}
INLINE void NCread(char *a, long b, int s) {
int i;
for (i=0; i<s; i++) a[i]=read_nibble_crc(b+i);
return;
}
INLINE void Nwrite(char *a, long b, int s) {
int i;
for (i=0; i<s; i++) write_nibble(b+i, a[i]);
return;
}
int F_s[16] = {0/*P*/,0,2,0,15,3,0,0,0,0,0,0,0,0,0,0};
int F_l[16] = {1,0/*P+1*/,1,3,1,12,2,16,0,0,0,0,0,0,0,5};
#define FIELDScl(t,fn) INLINE void t##F##fn(char *a, long b, int f) { t##fn(a+F_s[(int)f],b,F_l[(int)f]); return; }
#define FIELDScc(t,fn) INLINE void t##F##fn(char *a, char *b, int f) { t##fn(a+F_s[(int)f],b+F_s[(int)f],F_l[(int)f]); return; }
#define FIELDSc(t,fn) INLINE void t##F##fn(char *a, int f) { t##fn(a+F_s[(int)f],F_l[(int)f]); return; }
FIELDScl(N,unpack)
FIELDScl(NC,read)
FIELDScl(N,write)
FIELDScc(N,copy)
FIELDScc(N,xchg)
FIELDSc(N,inc)
FIELDSc(N,dec)
FIELDScc(N,add)
FIELDScc(N,sub)
FIELDScc(N,rsub)
FIELDScc(N,and)
FIELDScc(N,or)
FIELDSc(N,zero)
FIELDSc(N,not)
FIELDSc(N,neg)
FIELDSc(N,sr)
FIELDSc(N,sl)
FIELDSc(N,srb)
FIELDSc(N,dbl)
FIELDScc(T,e)
FIELDScc(T,ne)
FIELDSc(T,z)
FIELDSc(T,nz)
FIELDScc(T,a)
FIELDScc(T,ae)
FIELDScc(T,b)
FIELDScc(T,be)


BIN
KEYBOARD.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

65
LST2C.C Normal file
View file

@ -0,0 +1,65 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 256
#define NEXTFIELD {s=p; while ((p<BUFSIZE)&&(ptr[p]!='\t')) p++; ptr[p] = 0; p++;}
char buffer[BUFSIZE];
int icnt, lcnt;
int main() {
char *ptr, array;
int s, p, ticks;
while (!feof(stdin)) {
lcnt++;
if (gets(buffer)==NULL) break;
if (buffer[0]==0) break;
if (buffer[0]=='#') {
if (buffer[1])
printf("/* %s */\n", buffer+1);
else
putchar('\n');
continue;
}
ptr = buffer; p = 0;
NEXTFIELD;
printf("o%s: ", ptr+s);
NEXTFIELD;
if (ptr[s+3]) {
array = ptr[s+3];
ptr[s+3] = 0;
ticks = atoi(ptr+s);
ptr[s+3] = array;
array = ptr[s+6];
ptr[s+6] = 0;
if (ticks)
printf("ticks-=%i+%s[(int)I[%i]];", ticks, ptr+s+3, array-'0');
else
printf("ticks-=%s[(int)I[%i]];", ptr+s+3, array-'0');
ptr[s+6] = array;
} else {
ticks = atoi(ptr+s);
printf("ticks-=%i; ", ticks);
}
NEXTFIELD;
NEXTFIELD;
NEXTFIELD;
printf("%s goto o_done;\n", ptr+s);
icnt++;
}
if (feof(stdin))
printf("/* %i lines, %i instructions */\n", lcnt, icnt);
else
fprintf(stderr, "Error at line %i\n", lcnt+1);
return 0;
}


86
MAIN.C Normal file
View file

@ -0,0 +1,86 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "emu48.h"
char A[16]={0,};
char B[16]={0,};
char C[16]={0,};
char D[16]={0,};
char R0[16]={0,};
char R1[16]={0,};
char R2[16]={0,};
char R3[16]={0,};
char R4[16]={0,};
char ST[4]={0,};
char HST=0, P=0;
int OUT = 0, IN = 0;
int SHUTDN=0, INTP=0, INTE=0, INTD=0, rstkp = 0, MODE = 16, CARRY=0;
long rstk[8] = {0,};
long pc=0, d0=0, d1=0;
char CARDSTATUS = 0;
char *eprom;
char *rom = NULL, *ram, *port1, *port2;
char *data[6]={NULL,NULL,NULL,NULL,NULL,NULL};
int ucfg[6]={1,1,1,1,1,0}, bank1, bank2;
long base[6]={0x00100,0x80000,0x7F000,0x7E000,0x7E000,0x00000};
long size[6]={0x00040,0x40000,0x01000,0x01000,0x01000,0x100000};
unsigned short crc;
unsigned long t1=0xf, t2=0xffffffff;
unsigned long saturn_speed = 0;
int quit = 0;
int load_state = 1;
void calibrate_timer() {
saturn_speed = 4000;
return;
}
int main(int argc, char *argv[]) {
int i;
char c;
printf("Emu48 version "VERSION", Copyright (C) 1995 Sebastien Carlier\n");
printf("This is free software, and you are welcome to redistribute it\n");
printf("under certain conditions; see COPYING for details.\n");
for (i=1; i<argc; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'W':
c = argv[i][2];
P = (char)((c==0)?3:((c<=9)?(c-'0'):(c-'A'+10)));
pc = 0x01FC6;
load_state = 0;
break;
case 's':
sscanf(argv[i]+2,"%ld",&saturn_speed);
break;
default:
printf("Ignoring option %s\n", argv[i]);
}
} else printf("Ignoring '%s'\n", argv[i]);
}
load();
if (!saturn_speed) calibrate_timer();
init_lcd();
init_keyboard();
display_redraw();
emulate();
exit_keyboard();
exit_lcd();
if (quit==1) save();
free(ram);
free(rom);
printf("Interrupts frequency was set to %ld\n", saturn_speed);
return 0;
}


12
MAKEFILE Normal file
View file

@ -0,0 +1,12 @@
.c.obj:
cl -c -Z7 /nologo /G4 /Zp8 /MT /W3 /YX /I "C:\Emu48\win32" $*.c
!ifdef d
debug=-DEBUG:FULL
!endif
OBJ= hardware.obj instr.obj main.obj mem2.obj saturn.obj emu48.res
emu48.exe: $(OBJ)
link $(OBJ) $(debug) -SUBSYSTEM:WINDOWS kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib -out:$@

739
MEM2.C Normal file
View file

@ -0,0 +1,739 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <malloc.h>
#include <string.h>
#include "emu48.h"
/* Modules :
* 0 IO RAM
* 1 RAM
* 2 bank switcher
* 3 PORT 1
* 4 PORT 2
* 5 ROM
*/
/* ucfg value :
* 0 configured
* 1 unconfigured
* 2 got size only
*/
#define PORT1DEF "port1"
char PORT1[100] = PORT1DEF;
void setport1(const char *newstring)
{
if (newstring)
{
if (*newstring)
strcpy(PORT1, newstring);
else
strcpy(PORT1, PORT1DEF);
}
}
int readport1(const char *portname)
{
/* CARDSTATUS: P2W P1W P2C P1C */
long i, s;
unsigned char c;
FILE *in = fopen(PORT1, "rb");
if (in!=NULL)
{
fseek(in, 0, SEEK_END);
s = ftell(in) * 2;
fseek(in, 0, SEEK_SET);
#ifdef DOSX286
port1 = (char*)_halloc(262144L,1);
#else
port1 = (char*)malloc(262144L);
#endif
if (port1!=NULL) {
for (i=0; i<s;) {
c = (char)fgetc(in);
port1[i++] = (char)(c&0xf);
port1[i++] = (char)((c>>4)&0xf);
}
data[3] = port1;
CARDSTATUS |= 0xA;
if (s!=262144L) memset(port1, 0, 16);
}
else display_warning("Not enough memory for port1");
fclose(in);
return 0;
}
return -1;
}
int load()
{
FILE *in;
long i, s;
unsigned char c;
int swap;
if (load_state) {
in = fopen("saturn", "rb");
if (in != NULL) {
fread(A, 16, 1, in);
fread(B, 16, 1, in);
fread(C, 16, 1, in);
fread(D, 16, 1, in);
fread(R0, 16, 1, in);
fread(R1, 16, 1, in);
fread(R2, 16, 1, in);
fread(R3, 16, 1, in);
fread(R4, 16, 1, in);
if (!pc) fread(&pc, 4, 1, in); else fseek(in, 4, SEEK_CUR);
fread(&d0, 4, 1, in);
fread(&d1, 4, 1, in);
fread(&OUT, 4, 1, in);
fread(&IN, 4, 1, in);
fread(ST, 4, 1, in);
HST = (char)fgetc(in);
if (!P) P = (char)fgetc(in); else fseek(in, 1, SEEK_CUR);
CARRY = fgetc(in);
MODE = fgetc(in);
INTP = fgetc(in);
INTE = fgetc(in);
INTD = fgetc(in);
SHUTDN = fgetc(in);
fread(rstk, 32, 1, in);
rstkp = fgetc(in);
for (i=0; i<5; i++) {
ucfg[i] = fgetc(in);
fread(&base[i], 4, 1, in);
fread(&size[i], 4, 1, in);
}
fread(ioram, 64, 1, in);
t1 = fgetc(in);
fread(&t2, 4, 1, in);
fread(&crc, 4, 1, in);
fread(&display, sizeof(display_t), 1, in);
fclose(in);
}
}
#ifdef DOSX286
rom = (char*)_halloc(1048576L,1);
#else
rom = (char*)malloc(1048576L);
#endif
if (rom==NULL) display_error("Not enough memory for rom.\n");
in = fopen("rom", "rb");
if (in==NULL) {
free(rom);
display_error("The rom dump file 'rom' is missing.\n");
}
fseek(in,0,SEEK_END);
s = ftell(in)*2;
fseek(in,0,SEEK_SET);
c = (char)fgetc(in);
switch (c) {
case 0x32: swap = 0; break;
case 0x23: swap = 1; break;
default: swap = 0; break;
}
ungetc(c, in);
if (!swap)
for (i=0; i<s;) {
c = (char)fgetc(in);
rom[i++] = (char)(c&0xf);
rom[i++] = (char)((c>>4)&0xf);
}
else
for (i=0; i<s;) {
c = (char)fgetc(in);
rom[i++] = (char)((c>>4)&0xf);
rom[i++] = (char)(c&0xf);
}
fclose(in);
data[5] = rom;
#ifdef DOSX286
ram = (char*)_halloc(262144L,1);
#else
ram = (char*)malloc(262144L);
#endif
if (ram==NULL) display_error("Not enough memory for ram.\n");
in = fopen("ram", "rb");
if (in!=NULL) {
c = (char)fgetc(in);
switch (c) {
case 0x3F: swap = 0; break;
case 0xF3: swap = 1; break;
default: swap = 0; break;
}
ungetc(c, in);
if (!swap)
for (i=0; i<262144L;) {
c = (char)fgetc(in);
ram[i++] = (char)(c&0xf);
ram[i++] = (char)((c>>4)&0xf);
}
else
for (i=0; i<262144L;) {
c = (char)fgetc(in);
ram[i++] = (char)((c>>4)&0xf);
ram[i++] = (char)(c&0xf);
}
fclose(in);
}
data[1] = ram;
readport1(PORT1);
/* CARDSTATUS: P2W P1W P2C P1C */
in = fopen("port2", "rb");
if (in!=NULL) {
fseek(in, 0, SEEK_END);
s = ftell(in) * 2;
fseek(in, 0, SEEK_SET);
#ifdef DOSX286
port2 = (char*)_halloc(262144L,1);
#else
port2 = (char*)malloc(262144L);
#endif
if (port2!=NULL) {
for (i=0; i<s;) {
c = (char)fgetc(in);
port2[i++] = (char)(c&0xf);
port2[i++] = (char)((c>>4)&0xf);
}
data[4] = port2;
CARDSTATUS |= 0x5;
} else display_warning("Not enough memory for port2");
fclose(in);
}
return 0;
}
int save() {
FILE *out;
long i;
out = fopen("ram", "wb");
if (out==NULL) return 1;
for (i=0; i<262144L; i+=2) fputc(ram[i]|(ram[i+1]<<4), out);
fclose(out);
if (CARDSTATUS&2) bank_save(port1,PORT1,bank1);
if (CARDSTATUS&1) bank_save(port2,"port2",bank2);
out = fopen("saturn", "wb");
fwrite(A, 16, 1, out);
fwrite(B, 16, 1, out);
fwrite(C, 16, 1, out);
fwrite(D, 16, 1, out);
fwrite(R0, 16, 1, out);
fwrite(R1, 16, 1, out);
fwrite(R2, 16, 1, out);
fwrite(R3, 16, 1, out);
fwrite(R4, 16, 1, out);
fwrite(&pc, 4, 1, out);
fwrite(&d0, 4, 1, out);
fwrite(&d1, 4, 1, out);
fwrite(&OUT, 4, 1, out);
fwrite(&IN, 4, 1, out);
fwrite(ST, 4, 1, out);
fputc(HST, out);
fputc(P, out);
fputc(CARRY, out);
fputc(MODE, out);
fputc(INTP, out);
fputc(INTE, out);
fputc(INTD, out);
fputc(SHUTDN, out);
fwrite(rstk, 32, 1, out);
fputc(rstkp, out);
for (i=0; i<5; i++) {
fputc(ucfg[i], out);
fwrite(&base[i], 4, 1, out);
fwrite(&size[i], 4, 1, out);
}
fwrite(ioram, 64, 1, out);
fputc((int)t1, out);
fwrite(&t2, 4, 1, out);
fwrite(&crc, 4, 1, out);
fwrite(&display, sizeof(display_t), 1, out);
fclose(out);
return 0;
}
void bank_save(char *mem, char *bn, int bank) {
char name[12];
FILE *out;
long i;
if (bank)
sprintf(name,"%s.%i",bn,bank);
else
strcpy(name, bn);
out = fopen(name, "rb");
if (out==NULL) return;
fclose(out);
out = fopen(name, "wb");
if (out==NULL) {
printf("Failed to write %s\n", name);
return;
}
for (i=0; i<262144L; i+=2) fputc(mem[i]|(mem[i+1]<<4), out);
fclose(out);
return;
}
void bank_load(char *mem, char *bn, int bank) {
char name[12], c;
FILE *in;
long i, s;
if (bank)
sprintf(name,"%s.%i",bn,bank);
else
strcpy(name, bn);
in = fopen(name, "rb");
if (in==NULL) {
printf("Failed to read %s\n", name);
return;
}
fseek(in, 0, SEEK_END);
s = ftell(in) * 2;
fseek(in, 0, SEEK_SET);
for (i=0; i<s;) {
c = (char)fgetc(in);
mem[i++] = (char)(c&0xf);
mem[i++] = (char)((c>>4)&0xf);
}
fclose(in);
return;
}
void bank_switch(int bank) {
if (bank<32) /* port 1 */ {
if (bank1 == bank) return;
bank_save(port1,PORT1,bank1);
bank1 = bank;
bank_load(port1,PORT1,bank1);
} else {
bank -= 32;
if (bank2 == bank) return;
bank_save(port2,"port2",bank2);
bank2 = bank;
bank_load(port2,"port2",bank2);
}
return;
}
/******** IO RAM ********/
char ioram[64] = {
0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0xC,0x0,
0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xf, 0xf,0xf,0xf,0xf, 0xf,0xf,0xf,0xf
};
char read_io(long d) {
char c;
switch (d) {
case 0x04: c = (char)(crc); break;
case 0x05: c = (char)(crc>>4); break;
case 0x06: c = (char)(crc>>8); break;
case 0x07: c = (char)(crc>>12); break;
case 0x0F: c = CARDSTATUS; break;
case 0x14: return ioram[d];
case 0x15: ioram[0x11]&=0xe; return ioram[d];
case 0x16: /**/
case 0x17: /**/ return 3;
case 0x18: /**/
case 0x19: /**/ display_warning("Nibbles #118/#119 read.");
case 0x20: /**/
case 0x21: /**/
case 0x22: /**/
case 0x23: /**/
case 0x24: /**/
case 0x25: /**/
case 0x26: /**/
case 0x27: /**/ return 3;
case 0x28: c = (char)display.lcounter; break;
case 0x29: c = (char)(display.lcounter>>4); break;
case 0x30: /**/
case 0x31: /**/
case 0x32: /**/
case 0x33: /**/
case 0x34: /**/ c = 3; break;
case 0x37: c = (char)(t1); break;
case 0x38: c = (char)(t2); break;
case 0x39: c = (char)(t2>>4); break;
case 0x3A: c = (char)(t2>>8); break;
case 0x3B: c = (char)(t2>>12); break;
case 0x3C: c = (char)(t2>>16); break;
case 0x3D: c = (char)(t2>>20); break;
case 0x3E: c = (char)(t2>>24); break;
case 0x3F: c = (char)(t2>>28); break;
default:
return ioram[d];
}
return (char)(c&0xf);
}
void write_io(long d, char c) {
switch (d) {
/* 00100 = NS:DISPIO
* 00100 @ Display bit offset and DON [DON OFF2 OFF1 OFF0]
* 00100 @ 3 nibs for display offset (scrolling), DON=Display ON
*/
case 0x00:
if (display.boffset!=(c&7)) {
display.touched = 1;
display.boffset = c&7;
}
if (display.dispon!=(c>>3)) {
display.touched = 1;
display.dispon = c>>3;
}
break;
/* 00101 = NS:CONTRLSB
* 00101 @ Contrast Control [CON3 CON2 CON1 CON0]
* 00101 @ Higher value = darker screen
*/
case 0x01:
if ((display.contrast&0xf)!=c) {
display.contrast &= 0x10;
display.contrast |= c;
display.touched = 1;
}
break;
/* 00102 = NS:DISPTEST
* 00102 @ Display test [VDIG LID TRIM CON4] [LRT LRTD LRTC BIN]
* 00102 @ Normally zeros
*/
case 0x02:
if ((display.contrast>>4)!=(c&1)) {
display.contrast &= 0x0f;
display.contrast |= (c<<4)&0x10;
display.touched = 1;
}
break;
case 0x03:
/*display.noscan = (c>>3)&1;*/
/*display.touched = 1;*/
break;
/* 00104 = HP:CRC
* 00104 @ 16 bit hardware CRC (104-107) (X^16+X^12+X^5+1)
* 00104 @ crc = ( crc >> 4 ) ^ ( ( ( crc ^ nib ) & 0x000F ) * 0x1081 );
*/
case 0x04: crc=crc&0xfff0;crc|=(c); return;
case 0x05: crc=crc&0xff0f;crc|=(c<<4); return;
case 0x06: crc=crc&0xf0ff;crc|=(c<<8); return;
case 0x07: crc=crc&0x0fff;crc|=(c<<12); return;
/* 00108 = NS:POWERSTATUS
* 00108 @ Low power registers (108-109)
* 00108 @ [LB2 LB1 LB0 VLBI] (read only)
* 00108 @ LowBat(2) LowBat(1) LowBat(S) VeryLowBat
*/
case 0x08:
return;
/* 00109 = NS:POWERCTRL
* 00109 @ [ELBI EVLBI GRST RST] (read/write)
*/
case 0x09:
break;
/* 0010A = NS:MODE
* 0010A @ Mode Register (read-only)
*/
case 0x0A:
break;
/* 0010B = HP:ANNCTRL
* 0010B @ Annunciator control [LA4 LA3 LA2 LA1] = [ alarm alpha -> <- ]
*/
case 0x0B:
case 0x0C:
ioram[d] = c; display_ann(); return;
/* 0010D = NS:BAU
* 0010D @ Serial baud rate [UCK BD2 BD1 BD0] (bit 3 is read-only)
* 0010D @ 3 bits = {1200 1920 2400 3840 4800 7680 9600 15360}
*/
case 0x0D:
c &= 7;
break;
/* 0010E = NS:CARDCTRL
* 0010E @ [ECDT RCDT SMP SWINT] (read/write)
* 0010E @ Enable Card Det., Run Card Det., Set Module Pulled, Software interrupt
*/
case 0x0E:
if (c&1) INTERRUPT("SW");
if (c&2) { ioram[0x19] = 2; HST|=MP; INTERRUPT("MP"); }
if (c&8)
if (c&4) ioram[0x0F] = 0;
break;
/* 0010F = NS:CARDSTATUS
* 0010F @ [P2W P1W P2C P1C] (read-only) Port 2 writable .. Port 1 inserted
*/
case 0x0F:
return;
/* 00110 = HP:IOC
* 00110 @ Serial I/O Control [SON ETBE ERBF ERBZ]
* 00110 @ Serial On, Interrupt On Recv.Buf.Empty, Full, Buzy
*/
case 0x10:
break;
/* 00111 = HP:RCS
* 00111 @ Serial Receive Control/Status [RX RER RBZ RBF] (bit 3 is read-only)
*/
case 0x11:
c &= 7;
c |= ioram[0x11]&8;
break;
/* 00112 = HP:TCS
* 00112 @ Serial Transmit Control/Status [BRK LPB TBZ TBF]
*/
case 0x12:
break;
/* 00113 = HP:CRER
* 00113 @ Serial Clear RER (writing anything clears RER bit)
*/
case 0x13:
ioram[0x11]&=0xB;
return;
/* 00114 = HP:RBR
* 00114 @ Serial Receive Buffer Register (Reading clears RBF bit)
* 00114 @ [RX RER RBZ RBF]
*/
case 0x14:
case 0x15:
return;
/* 00116 = HP:TBR
* 00116 @ Serial Transmit Buffer Register (Writing sets TBF bit)
*/
case 0x016: break;
case 0x017:
ioram[0x12] |= 1;
break;
/* 00118 = NS:SRR
* 00118 @ Service Request Register (read-only)
* 00118 @ [ISQR TSQR USRQ VSRQ] [KDN NINT2 NINT LSRQ]
*/
case 0x18:
case 0x19:
return;
/* 0011A = HP:IRC
* 0011A @ IR Control Register [IRI EIRU EIRI IRE] (bit 3 is read-only)
* 0011A @ IR Input, Enable IR UART mode, Enable IR Interrupt, IR Event
*/
case 0x1A:
c &= 7;
c |= ioram[0x1A]&8;
break;
/* 0011B = NS:BASENIBOFF
* 0011B @ Used as addressto get BASENIB from 11F to the 5th nibble
*/
case 0x1B:
return;
/* 0011C = NS:LCR
* 0011C @ Led Control Register [LED ELBE LBZ LBF] (Setting LED is draining)
*/
case 0x1C:
break;
/* 0011D = NS:LBR
* 0011D @ Led Buffer Register [0 0 0 LBO] (bits 1-3 read zero)
*/
case 0x1D:
c &= 1;
break;
/* 0011E = NS:SCRATCHPAD
* 0011E @ Scratch pad (11F is BASEIB, 7 or F for base memory)
*/
case 0x1E:
break;
/* 0011F = NS:BASENIB
*/
case 0x1F:
break;
/* 00120 = NS:DISPADDR
* 00120 @ Display Start Address (write only)
* 00120 @ bit 0 is ignored (display must start on byte boundary)
*/
case 0x20:
if ((display.start1&0x0000F)!=c) {
display.start1 = (display.start1&0xFFFF0)|(c&0xE);
display.touched = 1;
}
break;
case 0x21:
if (((display.start1&0x000F0)>>4)!=c) {
display.start1=(display.start1&0xFFF0F)|(c<<4);
display.touched = 1;
}
break;
case 0x22:
if (((display.start1&0x00F00)>>8)!=c) {
display.start1=(display.start1&0xFF0FF)|(c<<8);
display.touched = 1;
}
break;
case 0x23:
if (((display.start1&0x0F000)>>12)!=c) {
display.start1=(display.start1&0xF0FFF)|(c<<12);
display.touched = 1;
}
break;
case 0x24:
if (((display.start1&0xF0000)>>16)!=c) {
display.start1=(display.start1&0x0FFFF)|(c<<16);
display.touched = 1;
}
break;
/* 00125 = NS:LINEOFFS
* 00125 @ Display Line offset (write only) (no of bytes skipped after each line)
* 00125 @ MSG sign extended
*/
case 0x25: c &= 0xe;
case 0x26:
case 0x27:
ioram[d] = c;
display.loffset = (int)Npack(ioram+0x25, 3);
if (display.loffset&0x800) display.loffset = display.loffset - 0x1000;
display.touched = 1;
return;
/* 00128 = NS:LINECOUNT
* 00128 @ Display Line Counter and miscellaneous (28-29)
* 00128 @ [LC3 LC2 LC1 LC0] [DA19 M32 LC5 LC4]
* 00128 @ Line counter 6 bits -> max = 2^6-1 = 63 = disp height
* 00128 @ Normally has 55 -> Menu starts at display row 56
*/
case 0x28:
if ((display.lcntsave&0xf)!=c) {
display.lcntsave=(display.lcntsave&0x30)|c;
display.touched = 1;
}
break;
case 0x29:
if ((display.lcntsave&0x30)!=((c&3)<<4)) {
display.lcntsave=(display.lcntsave&0x0f)|((c&3)<<4);
display.touched = 1;
}
break;
case 0x2A:
case 0x2B:
case 0x2C:
case 0x2D:
return;
/* 0012E = NS:TIMER1CTRL
* 0012E @ TIMER1 Control [SRQ WKE INT XTRA]
*/
case 0x2E:
c &= 0xE;
break;
/* 0012F = NS:TIMER2CTRL
* 0012F @ TIMER2 Control [SRQ WKE INT RUN]
*/
case 0x2F:
break;
/* 00130 = NS:MENUADDR
* 00130 @ Display Secondary Start Address (write only) (30-34)
* 00130 @ Menu Display Address, no line offsets
*/
case 0x30:
if ((display.start2&0x0000F)!=c) {
display.start2=(display.start2&0xFFFF0)|(c&0xE);
display.touched = 1;
}
break;
case 0x31:
if (((display.start2&0x000F0)>>4)!=c) {
display.start2=(display.start2&0xFFF0F)|(c<<4);
display.touched = 1;
}
break;
case 0x32:
if (((display.start2&0x00F00)>>8)!=c) {
display.start2=(display.start2&0xFF0FF)|(c<<8);
display.touched = 1;
}
break;
case 0x33:
if (((display.start2&0x0F000)>>12)!=c) {
display.start2=(display.start2&0xF0FFF)|(c<<12);
display.touched = 1;
}
break;
case 0x34:
if (((display.start2&0xF0000)>>16)!=c) {
display.start2=(display.start2&0x0FFFF)|(c<<16);
display.touched = 1;
}
break;
case 0x35:
case 0x36:
return;
/* 00137 = HP:TIMER1
* 00137 @ Decremented 16 times/s
*/
case 0x37:
t1 = c;
break;
/* 00138 = HP:TIMER2
* 00138 @ hardware timer (38-3F), decremented 8192 times/s
*/
case 0x38: t2=(t2&0xFFFFFFF0)|c; break;
case 0x39: t2=(t2&0xFFFFFF0F)|(c<<4); break;
case 0x3A: t2=(t2&0xFFFFF0FF)|(c<<8); break;
case 0x3B: t2=(t2&0xFFFF0FFF)|(c<<12); break;
case 0x3C: t2=(t2&0xFFF0FFFF)|(c<<16); break;
case 0x3D: t2=(t2&0xFF0FFFFF)|(c<<20); break;
case 0x3E: t2=(t2&0xF0FFFFFF)|(c<<24); break;
case 0x3F: t2=(t2&0x0FFFFFFF)|(c<<28); break;
default: return;
}
ioram[d] = c;
return;
}


728
MEMORY.C Normal file
View file

@ -0,0 +1,728 @@
/*
* Copyright (C) 1995 Sebastien Carlier
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <malloc.h>
#include <string.h>
#include "emu48.h"
/* Modules :
* 0 IO RAM
* 1 RAM
* 2 bank switcher
* 3 PORT 1
* 4 PORT 2
* 5 ROM
*/
/* ucfg value :
* 0 configured
* 1 unconfigured
* 2 got size only
*/
#define PORT1DEF "port1"
char PORT1[100] = PORT1DEF;
void setport1(const char *newstring)
{
if (newstring)
{
if (*newstring)
strcpy(PORT1, newstring);
else
strcpy(PORT1, PORT1DEF);
}
}
int load() {
FILE *in;
long i, s;
unsigned char c;
int swap;
if (load_state) {
in = fopen("saturn", "rb");
if (in != NULL) {
fread(A, 16, 1, in);
fread(B, 16, 1, in);
fread(C, 16, 1, in);
fread(D, 16, 1, in);
fread(R0, 16, 1, in);
fread(R1, 16, 1, in);
fread(R2, 16, 1, in);
fread(R3, 16, 1, in);
fread(R4, 16, 1, in);
if (!pc) fread(&pc, 4, 1, in); else fseek(in, 4, SEEK_CUR);
fread(&d0, 4, 1, in);
fread(&d1, 4, 1, in);
fread(&OUT, 4, 1, in);
fread(&IN, 4, 1, in);
fread(ST, 4, 1, in);
HST = (char)fgetc(in);
if (!P) P = (char)fgetc(in); else fseek(in, 1, SEEK_CUR);
CARRY = fgetc(in);
MODE = fgetc(in);
INTP = fgetc(in);
INTE = fgetc(in);
INTD = fgetc(in);
SHUTDN = fgetc(in);
fread(rstk, 32, 1, in);
rstkp = fgetc(in);
for (i=0; i<5; i++) {
ucfg[i] = fgetc(in);
fread(&base[i], 4, 1, in);
fread(&size[i], 4, 1, in);
}
fread(ioram, 64, 1, in);
t1 = fgetc(in);
fread(&t2, 4, 1, in);
fread(&crc, 4, 1, in);
fread(&display, sizeof(display_t), 1, in);
fclose(in);
}
}
#ifdef DOSX286
rom = (char*)_halloc(1048576L,1);
#else
rom = (char*)malloc(1048576L);
#endif
if (rom==NULL) display_error("Not enough memory for rom.\n");
in = fopen("rom", "rb");
if (in==NULL) {
free(rom);
display_error("The rom dump file 'rom' is missing.\n");
}
fseek(in,0,SEEK_END);
s = ftell(in)*2;
fseek(in,0,SEEK_SET);
c = (char)fgetc(in);
switch (c) {
case 0x32: swap = 0; break;
case 0x23: swap = 1; break;
default: swap = 0; break;
}
ungetc(c, in);
if (!swap)
for (i=0; i<s;) {
c = (char)fgetc(in);
rom[i++] = (char)(c&0xf);
rom[i++] = (char)((c>>4)&0xf);
}
else
for (i=0; i<s;) {
c = (char)fgetc(in);
rom[i++] = (char)((c>>4)&0xf);
rom[i++] = (char)(c&0xf);
}
fclose(in);
data[5] = rom;
#ifdef DOSX286
ram = (char*)_halloc(262144L,1);
#else
ram = (char*)malloc(262144L);
#endif
if (ram==NULL) display_error("Not enough memory for ram.\n");
in = fopen("ram", "rb");
if (in!=NULL) {
c = (char)fgetc(in);
switch (c) {
case 0x3F: swap = 0; break;
case 0xF3: swap = 1; break;
default: swap = 0; break;
}
ungetc(c, in);
if (!swap)
for (i=0; i<262144L;) {
c = (char)fgetc(in);
ram[i++] = (char)(c&0xf);
ram[i++] = (char)((c>>4)&0xf);
}
else
for (i=0; i<262144L;) {
c = (char)fgetc(in);
ram[i++] = (char)((c>>4)&0xf);
ram[i++] = (char)(c&0xf);
}
fclose(in);
}
data[1] = ram;
/* CARDSTATUS: P2W P1W P2C P1C */
in = fopen(PORT1, "rb");
if (in!=NULL) {
fseek(in, 0, SEEK_END);
s = ftell(in) * 2;
fseek(in, 0, SEEK_SET);
#ifdef DOSX286
port1 = (char*)_halloc(262144L,1);
#else
port1 = (char*)malloc(262144L);
#endif
if (port1!=NULL) {
for (i=0; i<s;) {
c = (char)fgetc(in);
port1[i++] = (char)(c&0xf);
port1[i++] = (char)((c>>4)&0xf);
}
data[3] = port1;
CARDSTATUS |= 0xA;
if (s!=262144L) memset(port1, 0, 16);
} else display_warning("Not enough memory for port1");
fclose(in);
}
/* CARDSTATUS: P2W P1W P2C P1C */
in = fopen("port2", "rb");
if (in!=NULL) {
fseek(in, 0, SEEK_END);
s = ftell(in) * 2;
fseek(in, 0, SEEK_SET);
#ifdef DOSX286
port2 = (char*)_halloc(262144L,1);
#else
port2 = (char*)malloc(262144L);
#endif
if (port2!=NULL) {
for (i=0; i<s;) {
c = (char)fgetc(in);
port2[i++] = (char)(c&0xf);
port2[i++] = (char)((c>>4)&0xf);
}
data[4] = port2;
CARDSTATUS |= 0x5;
} else display_warning("Not enough memory for port2");
fclose(in);
}
return 0;
}
int save() {
FILE *out;
long i;
out = fopen("ram", "wb");
if (out==NULL) return 1;
for (i=0; i<262144L; i+=2) fputc(ram[i]|(ram[i+1]<<4), out);
fclose(out);
if (CARDSTATUS&2) bank_save(port1,PORT1,bank1);
if (CARDSTATUS&1) bank_save(port2,"port2",bank2);
out = fopen("saturn", "wb");
fwrite(A, 16, 1, out);
fwrite(B, 16, 1, out);
fwrite(C, 16, 1, out);
fwrite(D, 16, 1, out);
fwrite(R0, 16, 1, out);
fwrite(R1, 16, 1, out);
fwrite(R2, 16, 1, out);
fwrite(R3, 16, 1, out);
fwrite(R4, 16, 1, out);
fwrite(&pc, 4, 1, out);
fwrite(&d0, 4, 1, out);
fwrite(&d1, 4, 1, out);
fwrite(&OUT, 4, 1, out);
fwrite(&IN, 4, 1, out);
fwrite(ST, 4, 1, out);
fputc(HST, out);
fputc(P, out);
fputc(CARRY, out);
fputc(MODE, out);
fputc(INTP, out);
fputc(INTE, out);
fputc(INTD, out);
fputc(SHUTDN, out);
fwrite(rstk, 32, 1, out);
fputc(rstkp, out);
for (i=0; i<5; i++) {
fputc(ucfg[i], out);
fwrite(&base[i], 4, 1, out);
fwrite(&size[i], 4, 1, out);
}
fwrite(ioram, 64, 1, out);
fputc((int)t1, out);
fwrite(&t2, 4, 1, out);
fwrite(&crc, 4, 1, out);
fwrite(&display, sizeof(display_t), 1, out);
fclose(out);
return 0;
}
void bank_save(char *mem, char *bn, int bank) {
char name[12];
FILE *out;
long i;
if (bank)
sprintf(name,"%s.%i",bn,bank);
else
strcpy(name, bn);
out = fopen(name, "rb");
if (out==NULL) return;
fclose(out);
out = fopen(name, "wb");
if (out==NULL) {
printf("Failed to write %s\n", name);
return;
}
for (i=0; i<262144L; i+=2) fputc(mem[i]|(mem[i+1]<<4), out);
fclose(out);
return;
}
void bank_load(char *mem, char *bn, int bank) {
char name[12], c;
FILE *in;
long i, s;
if (bank)
sprintf(name,"%s.%i",bn,bank);
else
strcpy(name, bn);
in = fopen(name, "rb");
if (in==NULL) {
printf("Failed to read %s\n", name);
return;
}
fseek(in, 0, SEEK_END);
s = ftell(in) * 2;
fseek(in, 0, SEEK_SET);
for (i=0; i<s;) {
c = (char)fgetc(in);
mem[i++] = (char)(c&0xf);
mem[i++] = (char)((c>>4)&0xf);
}
fclose(in);
return;
}
void bank_switch(int bank) {
if (bank<32) /* port 1 */ {
if (bank1 == bank) return;
bank_save(port1,PORT1,bank1);
bank1 = bank;
bank_load(port1,PORT1,bank1);
} else {
bank -= 32;
if (bank2 == bank) return;
bank_save(port2,"port2",bank2);
bank2 = bank;
bank_load(port2,"port2",bank2);
}
return;
}
/******** IO RAM ********/
char ioram[64] = {
0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0xC,0x0,
0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0xf, 0xf,0xf,0xf,0xf, 0xf,0xf,0xf,0xf
};
char read_io(long d) {
char c;
switch (d) {
case 0x04: c = (char)(crc); break;
case 0x05: c = (char)(crc>>4); break;
case 0x06: c = (char)(crc>>8); break;
case 0x07: c = (char)(crc>>12); break;
case 0x0F: c = CARDSTATUS; break;
case 0x14: return ioram[d];
case 0x15: ioram[0x11]&=0xe; return ioram[d];
case 0x16: /**/
case 0x17: /**/ return 3;
case 0x18: /**/
case 0x19: /**/ display_warning("Nibbles #118/#119 read.");
case 0x20: /**/
case 0x21: /**/
case 0x22: /**/
case 0x23: /**/
case 0x24: /**/
case 0x25: /**/
case 0x26: /**/
case 0x27: /**/ return 3;
case 0x28: c = (char)display.lcounter; break;
case 0x29: c = (char)(display.lcounter>>4); break;
case 0x30: /**/
case 0x31: /**/
case 0x32: /**/
case 0x33: /**/
case 0x34: /**/ c = 3; break;
case 0x37: c = (char)(t1); break;
case 0x38: c = (char)(t2); break;
case 0x39: c = (char)(t2>>4); break;
case 0x3A: c = (char)(t2>>8); break;
case 0x3B: c = (char)(t2>>12); break;
case 0x3C: c = (char)(t2>>16); break;
case 0x3D: c = (char)(t2>>20); break;
case 0x3E: c = (char)(t2>>24); break;
case 0x3F: c = (char)(t2>>28); break;
default:
return ioram[d];
}
return (char)(c&0xf);
}
void write_io(long d, char c) {
switch (d) {
/* 00100 = NS:DISPIO
* 00100 @ Display bit offset and DON [DON OFF2 OFF1 OFF0]
* 00100 @ 3 nibs for display offset (scrolling), DON=Display ON
*/
case 0x00:
if (display.boffset!=(c&7)) {
display.touched = 1;
display.boffset = c&7;
}
if (display.dispon!=(c>>3)) {
display.touched = 1;
display.dispon = c>>3;
}
break;
/* 00101 = NS:CONTRLSB
* 00101 @ Contrast Control [CON3 CON2 CON1 CON0]
* 00101 @ Higher value = darker screen
*/
case 0x01:
if ((display.contrast&0xf)!=c) {
display.contrast &= 0x10;
display.contrast |= c;
display.touched = 1;
}
break;
/* 00102 = NS:DISPTEST
* 00102 @ Display test [VDIG LID TRIM CON4] [LRT LRTD LRTC BIN]
* 00102 @ Normally zeros
*/
case 0x02:
if ((display.contrast>>4)!=(c&1)) {
display.contrast &= 0x0f;
display.contrast |= (c<<4)&0x10;
display.touched = 1;
}
break;
case 0x03:
/*display.noscan = (c>>3)&1;*/
/*display.touched = 1;*/
break;
/* 00104 = HP:CRC
* 00104 @ 16 bit hardware CRC (104-107) (X^16+X^12+X^5+1)
* 00104 @ crc = ( crc >> 4 ) ^ ( ( ( crc ^ nib ) & 0x000F ) * 0x1081 );
*/
case 0x04: crc=crc&0xfff0;crc|=(c); return;
case 0x05: crc=crc&0xff0f;crc|=(c<<4); return;
case 0x06: crc=crc&0xf0ff;crc|=(c<<8); return;
case 0x07: crc=crc&0x0fff;crc|=(c<<12); return;
/* 00108 = NS:POWERSTATUS
* 00108 @ Low power registers (108-109)
* 00108 @ [LB2 LB1 LB0 VLBI] (read only)
* 00108 @ LowBat(2) LowBat(1) LowBat(S) VeryLowBat
*/
case 0x08:
return;
/* 00109 = NS:POWERCTRL
* 00109 @ [ELBI EVLBI GRST RST] (read/write)
*/
case 0x09:
break;
/* 0010A = NS:MODE
* 0010A @ Mode Register (read-only)
*/
case 0x0A:
break;
/* 0010B = HP:ANNCTRL
* 0010B @ Annunciator control [LA4 LA3 LA2 LA1] = [ alarm alpha -> <- ]
*/
case 0x0B:
case 0x0C:
ioram[d] = c; display_ann(); return;
/* 0010D = NS:BAU
* 0010D @ Serial baud rate [UCK BD2 BD1 BD0] (bit 3 is read-only)
* 0010D @ 3 bits = {1200 1920 2400 3840 4800 7680 9600 15360}
*/
case 0x0D:
c &= 7;
break;
/* 0010E = NS:CARDCTRL
* 0010E @ [ECDT RCDT SMP SWINT] (read/write)
* 0010E @ Enable Card Det., Run Card Det., Set Module Pulled, Software interrupt
*/
case 0x0E:
if (c&1) INTERRUPT("SW");
if (c&2) { ioram[0x19] = 2; HST|=MP; INTERRUPT("MP"); }
if (c&8)
if (c&4) ioram[0x0F] = 0;
break;
/* 0010F = NS:CARDSTATUS
* 0010F @ [P2W P1W P2C P1C] (read-only) Port 2 writable .. Port 1 inserted
*/
case 0x0F:
return;
/* 00110 = HP:IOC
* 00110 @ Serial I/O Control [SON ETBE ERBF ERBZ]
* 00110 @ Serial On, Interrupt On Recv.Buf.Empty, Full, Buzy
*/
case 0x10:
break;
/* 00111 = HP:RCS
* 00111 @ Serial Receive Control/Status [RX RER RBZ RBF] (bit 3 is read-only)
*/
case 0x11:
c &= 7;
c |= ioram[0x11]&8;
break;
/* 00112 = HP:TCS
* 00112 @ Serial Transmit Control/Status [BRK LPB TBZ TBF]
*/
case 0x12:
break;
/* 00113 = HP:CRER
* 00113 @ Serial Clear RER (writing anything clears RER bit)
*/
case 0x13:
ioram[0x11]&=0xB;
return;
/* 00114 = HP:RBR
* 00114 @ Serial Receive Buffer Register (Reading clears RBF bit)
* 00114 @ [RX RER RBZ RBF]
*/
case 0x14:
case 0x15:
return;
/* 00116 = HP:TBR
* 00116 @ Serial Transmit Buffer Register (Writing sets TBF bit)
*/
case 0x016: break;
case 0x017:
ioram[0x12] |= 1;
break;
/* 00118 = NS:SRR
* 00118 @ Service Request Register (read-only)
* 00118 @ [ISQR TSQR USRQ VSRQ] [KDN NINT2 NINT LSRQ]
*/
case 0x18:
case 0x19:
return;
/* 0011A = HP:IRC
* 0011A @ IR Control Register [IRI EIRU EIRI IRE] (bit 3 is read-only)
* 0011A @ IR Input, Enable IR UART mode, Enable IR Interrupt, IR Event
*/
case 0x1A:
c &= 7;
c |= ioram[0x1A]&8;
break;
/* 0011B = NS:BASENIBOFF
* 0011B @ Used as addressto get BASENIB from 11F to the 5th nibble
*/
case 0x1B:
return;
/* 0011C = NS:LCR
* 0011C @ Led Control Register [LED ELBE LBZ LBF] (Setting LED is draining)
*/
case 0x1C:
break;
/* 0011D = NS:LBR
* 0011D @ Led Buffer Register [0 0 0 LBO] (bits 1-3 read zero)
*/
case 0x1D:
c &= 1;
break;
/* 0011E = NS:SCRATCHPAD
* 0011E @ Scratch pad (11F is BASEIB, 7 or F for base memory)
*/
case 0x1E:
break;
/* 0011F = NS:BASENIB
*/
case 0x1F:
break;
/* 00120 = NS:DISPADDR
* 00120 @ Display Start Address (write only)
* 00120 @ bit 0 is ignored (display must start on byte boundary)
*/
case 0x20:
if ((display.start1&0x0000F)!=c) {
display.start1 = (display.start1&0xFFFF0)|(c&0xE);
display.touched = 1;
}
break;
case 0x21:
if (((display.start1&0x000F0)>>4)!=c) {
display.start1=(display.start1&0xFFF0F)|(c<<4);
display.touched = 1;
}
break;
case 0x22:
if (((display.start1&0x00F00)>>8)!=c) {
display.start1=(display.start1&0xFF0FF)|(c<<8);
display.touched = 1;
}
break;
case 0x23:
if (((display.start1&0x0F000)>>12)!=c) {
display.start1=(display.start1&0xF0FFF)|(c<<12);
display.touched = 1;
}
break;
case 0x24:
if (((display.start1&0xF0000)>>16)!=c) {
display.start1=(display.start1&0x0FFFF)|(c<<16);
display.touched = 1;
}
break;
/* 00125 = NS:LINEOFFS
* 00125 @ Display Line offset (write only) (no of bytes skipped after each line)
* 00125 @ MSG sign extended
*/
case 0x25: c &= 0xe;
case 0x26:
case 0x27:
ioram[d] = c;
display.loffset = (int)Npack(ioram+0x25, 3);
if (display.loffset&0x800) display.loffset = display.loffset - 0x1000;
display.touched = 1;
return;
/* 00128 = NS:LINECOUNT
* 00128 @ Display Line Counter and miscellaneous (28-29)
* 00128 @ [LC3 LC2 LC1 LC0] [DA19 M32 LC5 LC4]
* 00128 @ Line counter 6 bits -> max = 2^6-1 = 63 = disp height
* 00128 @ Normally has 55 -> Menu starts at display row 56
*/
case 0x28:
if ((display.lcntsave&0xf)!=c) {
display.lcntsave=(display.lcntsave&0x30)|c;
display.touched = 1;
}
break;
case 0x29:
if ((display.lcntsave&0x30)!=((c&3)<<4)) {
display.lcntsave=(display.lcntsave&0x0f)|((c&3)<<4);
display.touched = 1;
}
break;
case 0x2A:
case 0x2B:
case 0x2C:
case 0x2D:
return;
/* 0012E = NS:TIMER1CTRL
* 0012E @ TIMER1 Control [SRQ WKE INT XTRA]
*/
case 0x2E:
c &= 0xE;
break;
/* 0012F = NS:TIMER2CTRL
* 0012F @ TIMER2 Control [SRQ WKE INT RUN]
*/
case 0x2F:
break;
/* 00130 = NS:MENUADDR
* 00130 @ Display Secondary Start Address (write only) (30-34)
* 00130 @ Menu Display Address, no line offsets
*/
case 0x30:
if ((display.start2&0x0000F)!=c) {
display.start2=(display.start2&0xFFFF0)|(c&0xE);
display.touched = 1;
}
break;
case 0x31:
if (((display.start2&0x000F0)>>4)!=c) {
display.start2=(display.start2&0xFFF0F)|(c<<4);
display.touched = 1;
}
break;
case 0x32:
if (((display.start2&0x00F00)>>8)!=c) {
display.start2=(display.start2&0xFF0FF)|(c<<8);
display.touched = 1;
}
break;
case 0x33:
if (((display.start2&0x0F000)>>12)!=c) {
display.start2=(display.start2&0xF0FFF)|(c<<12);
display.touched = 1;
}
break;
case 0x34:
if (((display.start2&0xF0000)>>16)!=c) {
display.start2=(display.start2&0x0FFFF)|(c<<16);
display.touched = 1;
}
break;
case 0x35:
case 0x36:
return;
/* 00137 = HP:TIMER1
* 00137 @ Decremented 16 times/s
*/
case 0x37:
t1 = c;
break;
/* 00138 = HP:TIMER2
* 00138 @ hardware timer (38-3F), decremented 8192 times/s
*/
case 0x38: t2=(t2&0xFFFFFFF0)|c; break;
case 0x39: t2=(t2&0xFFFFFF0F)|(c<<4); break;
case 0x3A: t2=(t2&0xFFFFF0FF)|(c<<8); break;
case 0x3B: t2=(t2&0xFFFF0FFF)|(c<<12); break;
case 0x3C: t2=(t2&0xFFF0FFFF)|(c<<16); break;
case 0x3D: t2=(t2&0xFF0FFFFF)|(c<<20); break;
case 0x3E: t2=(t2&0xF0FFFFFF)|(c<<24); break;
case 0x3F: t2=(t2&0x0FFFFFFF)|(c<<28); break;
default: return;
}
ioram[d] = c;
return;
}


425
OPCODES.H Normal file
View file

@ -0,0 +1,425 @@
/* Copyright (C) 1995 Sebastien Carlier (sebc@cybera.anet.fr) */
o00: ticks-=60; HST|=XM; pc = rstkpop(); goto o_done;
o01: ticks-=60; pc = rstkpop(); goto o_done;
o02: ticks-=60; CARRY=1; pc = rstkpop(); goto o_done;
o03: ticks-=60; CARRY=0; pc = rstkpop(); goto o_done;
o04: ticks-=24; pc+=2; MODE=16; goto o_done;
o05: ticks-=24; pc+=2; MODE=10; goto o_done;
o06: ticks-=44; pc+=2; rstkpush(Npack(C,5)); goto o_done;
o07: ticks-=44; pc+=2; Nunpack(C, rstkpop(), 5); goto o_done;
o08: ticks-=32; pc+=2; Nzero(ST,4); goto o_done;
o09: ticks-=32; pc+=2; Ncopy(C, ST, 4); goto o_done;
o0A: ticks-=32; pc+=2; Ncopy(ST, C, 4); goto o_done;
o0B: ticks-=32; pc+=2; Nxchg(C, ST, 4); goto o_done;
o0C: ticks-=24; pc+=2; P++; if (P>15) { P=0; CARRY=1; } else CARRY=0; PCHANGED goto o_done;
o0D: ticks-=24; pc+=2; P--; if (P<0) { P=15; CARRY=1; } else CARRY=0; PCHANGED goto o_done;
o0Ef0: ticks-=40+F04[(int)I[2]];pc+=4; NFand(A,B,I[2]); goto o_done;
o0Ef1: ticks-=40+F04[(int)I[2]];pc+=4; NFand(B,C,I[2]); goto o_done;
o0Ef2: ticks-=40+F04[(int)I[2]];pc+=4; NFand(C,A,I[2]); goto o_done;
o0Ef3: ticks-=40+F04[(int)I[2]];pc+=4; NFand(D,C,I[2]); goto o_done;
o0Ef4: ticks-=40+F04[(int)I[2]];pc+=4; NFand(B,A,I[2]); goto o_done;
o0Ef5: ticks-=40+F04[(int)I[2]];pc+=4; NFand(C,B,I[2]); goto o_done;
o0Ef6: ticks-=40+F04[(int)I[2]];pc+=4; NFand(A,C,I[2]); goto o_done;
o0Ef7: ticks-=40+F04[(int)I[2]];pc+=4; NFand(C,D,I[2]); goto o_done;
o0Ef8: ticks-=40+F04[(int)I[2]];pc+=4; NFor(A,B,I[2]); goto o_done;
o0Ef9: ticks-=40+F04[(int)I[2]];pc+=4; NFor(B,C,I[2]); goto o_done;
o0EfA: ticks-=40+F04[(int)I[2]];pc+=4; NFor(C,A,I[2]); goto o_done;
o0EfB: ticks-=40+F04[(int)I[2]];pc+=4; NFor(D,C,I[2]); goto o_done;
o0EfC: ticks-=40+F04[(int)I[2]];pc+=4; NFor(B,A,I[2]); goto o_done;
o0EfD: ticks-=40+F04[(int)I[2]];pc+=4; NFor(C,B,I[2]); goto o_done;
o0EfE: ticks-=40+F04[(int)I[2]];pc+=4; NFor(A,C,I[2]); goto o_done;
o0EfF: ticks-=40+F04[(int)I[2]];pc+=4; NFor(C,D,I[2]); goto o_done;
o0F: ticks-=60; if (INTD&&INTE) {INTD=0;pc=0xf;} else {INTP=0;pc=rstkpop();} goto o_done;
o100: ticks-=93; pc+=3; Ncopy(R0, A, 16); goto o_done;
o101: ticks-=93; pc+=3; Ncopy(R1, A, 16); goto o_done;
o102: ticks-=93; pc+=3; Ncopy(R2, A, 16); goto o_done;
o103: ticks-=93; pc+=3; Ncopy(R3, A, 16); goto o_done;
o104: ticks-=93; pc+=3; Ncopy(R4, A, 16); goto o_done;
o108: ticks-=93; pc+=3; Ncopy(R0, C, 16); goto o_done;
o109: ticks-=93; pc+=3; Ncopy(R1, C, 16); goto o_done;
o10A: ticks-=93; pc+=3; Ncopy(R2, C, 16); goto o_done;
o10B: ticks-=93; pc+=3; Ncopy(R3, C, 16); goto o_done;
o10C: ticks-=93; pc+=3; Ncopy(R4, C, 16); goto o_done;
o110: ticks-=93; pc+=3; Ncopy(A, R0, 16); goto o_done;
o111: ticks-=93; pc+=3; Ncopy(A, R1, 16); goto o_done;
o112: ticks-=93; pc+=3; Ncopy(A, R2, 16); goto o_done;
o113: ticks-=93; pc+=3; Ncopy(A, R3, 16); goto o_done;
o114: ticks-=93; pc+=3; Ncopy(A, R4, 16); goto o_done;
o118: ticks-=93; pc+=3; Ncopy(C, R0, 16); goto o_done;
o119: ticks-=93; pc+=3; Ncopy(C, R1, 16); goto o_done;
o11A: ticks-=93; pc+=3; Ncopy(C, R2, 16); goto o_done;
o11B: ticks-=93; pc+=3; Ncopy(C, R3, 16); goto o_done;
o11C: ticks-=93; pc+=3; Ncopy(C, R4, 16); goto o_done;
o120: ticks-=93; pc+=3; Nxchg(A, R0, 16); goto o_done;
o121: ticks-=93; pc+=3; Nxchg(A, R1, 16); goto o_done;
o122: ticks-=93; pc+=3; Nxchg(A, R2, 16); goto o_done;
o123: ticks-=93; pc+=3; Nxchg(A, R3, 16); goto o_done;
o124: ticks-=93; pc+=3; Nxchg(A, R4, 16); goto o_done;
o128: ticks-=93; pc+=3; Nxchg(C, R0, 16); goto o_done;
o129: ticks-=93; pc+=3; Nxchg(C, R1, 16); goto o_done;
o12A: ticks-=93; pc+=3; Nxchg(C, R2, 16); goto o_done;
o12B: ticks-=93; pc+=3; Nxchg(C, R3, 16); goto o_done;
o12C: ticks-=93; pc+=3; Nxchg(C, R4, 16); goto o_done;
o130: ticks-=49; pc+=3; d0 = Npack(A, 5); goto o_done;
o131: ticks-=49; pc+=3; d1 = Npack(A, 5); goto o_done;
o132: ticks-=49; pc+=3; d = d0; d0=Npack(A, 5); Nunpack(A, d, 5); goto o_done;
o133: ticks-=49; pc+=3; d = d1; d1=Npack(A, 5); Nunpack(A, d, 5); goto o_done;
o134: ticks-=49; pc+=3; d0 = Npack(C, 5); goto o_done;
o135: ticks-=49; pc+=3; d1 = Npack(C, 5); goto o_done;
o136: ticks-=49; pc+=3; d = d0; d0=Npack(C, 5); Nunpack(C, d, 5); goto o_done;
o137: ticks-=49; pc+=3; d = d1; d1=Npack(C, 5); Nunpack(C, d, 5); goto o_done;
o138: ticks-=45; pc+=3; d0&=0xf0000; d0|=Npack(A, 4); goto o_done;
o139: ticks-=45; pc+=3; d1&=0xf0000; d1|=Npack(A, 4); goto o_done;
o13A: ticks-=45; pc+=3; d = d0; d0&=0xf0000; d0|=Npack(A, 4); Nunpack(A, d, 4); goto o_done;
o13B: ticks-=45; pc+=3; d = d1; d1&=0xf0000; d1|=Npack(A, 4); Nunpack(A, d, 4); goto o_done;
o13C: ticks-=45; pc+=3; d0&=0xf0000; d0|=Npack(C, 4); goto o_done;
o13D: ticks-=45; pc+=3; d1&=0xf0000; d1|=Npack(C, 4); goto o_done;
o13E: ticks-=45; pc+=3; d = d0; d0&=0xf0000; d0|=Npack(C, 4); Nunpack(C, d, 4); goto o_done;
o13F: ticks-=45; pc+=3; d = d1; d1&=0xf0000; d1|=Npack(C, 4); Nunpack(C, d, 4); goto o_done;
o140: ticks-=148; pc+=3; Nwrite(A, d0, 5); goto o_done;
o141: ticks-=148; pc+=3; Nwrite(A, d1, 5); goto o_done;
o142: ticks-=138; pc+=3; NCread(A, d0, 5); goto o_done;
o143: ticks-=138; pc+=3; NCread(A, d1, 5); goto o_done;
o144: ticks-=148; pc+=3; Nwrite(C, d0, 5); goto o_done;
o145: ticks-=148; pc+=3; Nwrite(C, d1, 5); goto o_done;
o146: ticks-=138; pc+=3; NCread(C, d0, 5); goto o_done;
o147: ticks-=138; pc+=3; NCread(C, d1, 5); goto o_done;
o148: ticks-=98; pc+=3; Nwrite(A, d0, 2); goto o_done;
o149: ticks-=98; pc+=3; Nwrite(A, d1, 2); goto o_done;
o14A: ticks-=114; pc+=3; NCread(A, d0, 2); goto o_done;
o14B: ticks-=114; pc+=3; NCread(A, d1, 2); goto o_done;
o14C: ticks-=98; pc+=3; Nwrite(C, d0, 2); goto o_done;
o14D: ticks-=98; pc+=3; Nwrite(C, d1, 2); goto o_done;
o14E: ticks-=114; pc+=3; NCread(C, d0, 2); goto o_done;
o14F: ticks-=114; pc+=3; NCread(C, d1, 2); goto o_done;
o150a: ticks-=FWR[(int)I[3]];pc+=4; NFwrite(A, d0, I[3]); goto o_done;
o151a: ticks-=FWR[(int)I[3]];pc+=4; NFwrite(A, d1, I[3]); goto o_done;
o152a: ticks-=FRD[(int)I[3]];pc+=4; NCFread(A, d0, I[3]); goto o_done;
o153a: ticks-=FRD[(int)I[3]];pc+=4; NCFread(A, d1, I[3]); goto o_done;
o154a: ticks-=FWR[(int)I[3]];pc+=4; NFwrite(C, d0, I[3]); goto o_done;
o155a: ticks-=FWR[(int)I[3]];pc+=4; NFwrite(C, d1, I[3]); goto o_done;
o156a: ticks-=FRD[(int)I[3]];pc+=4; NCFread(C, d0, I[3]); goto o_done;
o157a: ticks-=FRD[(int)I[3]];pc+=4; NCFread(C, d1, I[3]); goto o_done;
o158x: ticks-=NWR[(int)I[3]];pc+=4; Nwrite(A, d0, I[3]+1); goto o_done;
o159x: ticks-=NWR[(int)I[3]];pc+=4; Nwrite(A, d1, I[3]+1); goto o_done;
o15Ax: ticks-=NRD[(int)I[3]];pc+=4; NCread(A, d0, I[3]+1); goto o_done;
o15Bx: ticks-=NRD[(int)I[3]];pc+=4; NCread(A, d1, I[3]+1); goto o_done;
o15Cx: ticks-=NWR[(int)I[3]];pc+=4; Nwrite(C, d0, I[3]+1); goto o_done;
o15Dx: ticks-=NWR[(int)I[3]];pc+=4; Nwrite(C, d1, I[3]+1); goto o_done;
o15Ex: ticks-=NRD[(int)I[3]];pc+=4; NCread(C, d0, I[3]+1); goto o_done;
o15Fx: ticks-=NRD[(int)I[3]];pc+=4; NCread(C, d1, I[3]+1); goto o_done;
o16x: ticks-=45; pc+=3; d0+=I[2]+1; if (d0>0xfffff) { d0&=0xfffff; CARRY=1; } else CARRY=0; goto o_done;
o17x: ticks-=45; pc+=3; d1+=I[2]+1; if (d1>0xfffff) { d1&=0xfffff; CARRY=1; } else CARRY=0; goto o_done;
o18x: ticks-=45; pc+=3; d0-=I[2]+1; if (d0<0) { d0&=0xfffff; CARRY=1; } else CARRY=0; goto o_done;
o19d2: ticks-=40; pc+=4; d0&=0xfff00; d0|=Npack(I+2, 2); goto o_done;
o1Ad4: ticks-=60; pc+=6; d0&=0xf0000; d0|=Npack(I+2, 4); goto o_done;
o1Bd5: ticks-=70; pc+=7; d0=Npack(I+2, 5); goto o_done;
o1Cx: ticks-=45; pc+=3; d1-=I[2]+1; if (d1<0) { d1&=0xfffff; CARRY=1; } else CARRY=0; goto o_done;
o1Dd2: ticks-=40; pc+=4; d1&=0xfff00; d1|=Npack(I+2, 2); goto o_done;
o1Ed4: ticks-=60; pc+=6; d1&=0xf0000; d1|=Npack(I+2, 4); goto o_done;
o1Fd5: ticks-=70; pc+=7; d1=Npack(I+2, 5); goto o_done;
o2n: ticks-=20; pc+=2; P=I[1]; PCHANGED goto o_done;
o3X: ticks-=30+D10[(int)I[1]];n=I[1]+1; pc+=2+n; if (P+n<=16) Ncopy(C+P, I+2, n); else { Ncopy(C+P, I+2, 16-P); Ncopy(C, I+2+(16-P), n-(16-P)); } goto o_done;
o4d2: ticks-=30; if ( CARRY) { d=Npack(I+1,2); if (d) { ticks-=40; if (d&0x80) pc-=(d^0xff); else pc+=d+1;} else pc=rstkpop(); } else pc+=3; goto o_done;
o5d2: ticks-=30; if (!CARRY) { d=Npack(I+1,2); if (d) { ticks-=40; if (d&0x80) pc-=(d^0xff); else pc+=d+1;} else pc=rstkpop(); } else pc+=3; goto o_done;
o6d3: ticks-=80; d=Npack(I+1,3); if (d&0x800) pc-=(d^0xfff); else pc+=d+1; goto o_done;
o7d3: ticks-=82; rstkpush(pc+4); d=Npack(I+1,3); if (d&0x800) pc-=(d^0xfff)-3; else pc+=d+4; goto o_done;
o800: ticks-=33; pc+=3; OUT&=0xff0; OUT|=C[0]; goto o_done;
o801: ticks-=41; pc+=3; OUT = Npack(C, 3); update_out(); goto o_done;
o802: ticks-=70; pc+=3; update_in(); Nunpack(A, IN, 4); goto o_done;
o803: ticks-=70; pc+=3; update_in(); Nunpack(C, IN, 4); goto o_done;
o804: ticks-=73; pc+=3; unconfig(); goto o_done;
o805: ticks-=73; pc+=3; config(); goto o_done;
o806: ticks-=73; pc+=3; c_eq_id(); goto o_done;
o807: ticks-=60; pc+=3; SHUTDN = 1; goto o_done;
o8080: ticks-=42; pc+=4; INTE=1; if (INTD&&(!INTP)) {INTD=0;INTERRUPT("DL");} goto o_done;
o80810: ticks-=53; pc+=5; if (IN) {if (!INTP) INTERRUPT("RS") else INTD=1;} goto o_done;
o8082X: ticks-=60+D10[(int)I[1]];n=I[4]+1; pc+=5+n; if (P+n<=16) Ncopy(A+P, I+5, n); else { Ncopy(A+P, I+5, 16-P); Ncopy(A, I+5+(16-P), n-(16-P)); } goto o_done;
o8083: ticks-=73; pc+=4; goto o_done;
o8084n: ticks-=53; pc+=5; Nbit0(A, I[4]); goto o_done;
o8085n: ticks-=53; pc+=5; Nbit1(A, I[4]); goto o_done;
o8086n: ticks-=117; pc+=5; Tbit0(A, I[4]); goyes(5); goto o_done;
o8087n: ticks-=117; pc+=5; Tbit1(A, I[4]); goyes(5); goto o_done;
o8088n: ticks-=53; pc+=5; Nbit0(C, I[4]); goto o_done;
o8089n: ticks-=53; pc+=5; Nbit1(C, I[4]); goto o_done;
o808An: ticks-=117; pc+=5; Tbit0(C, I[4]); goyes(5); goto o_done;
o808Bn: ticks-=117; pc+=5; Tbit1(C, I[4]); goyes(5); goto o_done;
o808C: ticks-=230; pc = Npack(nibble_ptr(Npack(A,5)), 5); goto o_done;
o808D: ticks-=73; pc+=4; goto o_done;
o808E: ticks-=230; pc = Npack(nibble_ptr(Npack(C,5)), 5); goto o_done;
o808F: ticks-=42; pc+=4; INTE = 0; goto o_done;
o809: ticks-=49; pc+=3; d=Npack(C, 5); d+=P+1; if (d>0xfffff) { d&=0xfffff; CARRY=1; } else CARRY=0; Nunpack(C, d, 5); goto o_done;
o80A: ticks-=73; pc+=3; reset(); goto o_done;
o80B: ticks-=73; pc+=3; goto o_done;
o80Cn: ticks-=48; pc+=4; C[(int)I[3]] = P; goto o_done;
o80Dn: ticks-=48; pc+=4; P = C[(int)I[3]]; PCHANGED goto o_done;
o80E: ticks-=58; pc+=3; C[0]=0; goto o_done;
o80Fn: ticks-=48; pc+=4; n = P; P = C[(int)I[3]]; C[(int)I[3]] = n; PCHANGED goto o_done;
o810: ticks-=101; pc+=3; Nslc(A, 16); goto o_done;
o811: ticks-=101; pc+=3; Nslc(B, 16); goto o_done;
o812: ticks-=101; pc+=3; Nslc(C, 16); goto o_done;
o813: ticks-=101; pc+=3; Nslc(D, 16); goto o_done;
o814: ticks-=101; pc+=3; Nsrc(A, 16); goto o_done;
o815: ticks-=101; pc+=3; Nsrc(B, 16); goto o_done;
o816: ticks-=101; pc+=3; Nsrc(C, 16); goto o_done;
o817: ticks-=101; pc+=3; Nsrc(D, 16); goto o_done;
o818f0x: ticks-=S00[(int)I[3]];pc+=6; NFunpack(X,I[5]+1,I[3]); NFadd(A, X, I[3]); goto o_done;
o818f1x: ticks-=S00[(int)I[3]];pc+=6; NFunpack(X,I[5]+1,I[3]); NFadd(B, X, I[3]); goto o_done;
o818f2x: ticks-=S00[(int)I[3]];pc+=6; NFunpack(X,I[5]+1,I[3]); NFadd(C, X, I[3]); goto o_done;
o818f3x: ticks-=S00[(int)I[3]];pc+=6; NFunpack(X,I[5]+1,I[3]); NFadd(D, X, I[3]); goto o_done;
o818f8x: ticks-=S00[(int)I[3]];pc+=6; NFunpack(X,I[5]+1,I[3]); NFsub(A, X, I[3]); goto o_done;
o818f9x: ticks-=S00[(int)I[3]];pc+=6; NFunpack(X,I[5]+1,I[3]); NFsub(B, X, I[3]); goto o_done;
o818fAx: ticks-=S00[(int)I[3]];pc+=6; NFunpack(X,I[5]+1,I[3]); NFsub(C, X, I[3]); goto o_done;
o818fBx: ticks-=S00[(int)I[3]];pc+=6; NFunpack(X,I[5]+1,I[3]); NFsub(D, X, I[3]); goto o_done;
o819f0: ticks-=53+F04[(int)I[3]];pc+=5; NFsrb(A, I[3]); goto o_done;
o819f1: ticks-=53+F04[(int)I[3]];pc+=5; NFsrb(B, I[3]); goto o_done;
o819f2: ticks-=53+F04[(int)I[3]];pc+=5; NFsrb(C, I[3]); goto o_done;
o819f3: ticks-=53+F04[(int)I[3]];pc+=5; NFsrb(D, I[3]); goto o_done;
o81Af00: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R0, A, I[3]); goto o_done;
o81Af01: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R1, A, I[3]); goto o_done;
o81Af02: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R2, A, I[3]); goto o_done;
o81Af03: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R3, A, I[3]); goto o_done;
o81Af04: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R4, A, I[3]); goto o_done;
o81Af08: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R0, C, I[3]); goto o_done;
o81Af09: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R1, C, I[3]); goto o_done;
o81Af0A: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R2, C, I[3]); goto o_done;
o81Af0B: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R3, C, I[3]); goto o_done;
o81Af0C: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(R4, C, I[3]); goto o_done;
o81Af10: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(A, R0, I[3]); goto o_done;
o81Af11: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(A, R1, I[3]); goto o_done;
o81Af12: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(A, R2, I[3]); goto o_done;
o81Af13: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(A, R3, I[3]); goto o_done;
o81Af14: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(A, R4, I[3]); goto o_done;
o81Af18: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(C, R0, I[3]); goto o_done;
o81Af19: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(C, R1, I[3]); goto o_done;
o81Af1A: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(C, R2, I[3]); goto o_done;
o81Af1B: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(C, R3, I[3]); goto o_done;
o81Af1C: ticks-=60+F04[(int)I[3]];pc+=6; NFcopy(C, R4, I[3]); goto o_done;
o81Af20: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(A, R0, I[3]); goto o_done;
o81Af21: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(A, R1, I[3]); goto o_done;
o81Af22: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(A, R2, I[3]); goto o_done;
o81Af23: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(A, R3, I[3]); goto o_done;
o81Af24: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(A, R4, I[3]); goto o_done;
o81Af28: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(C, R0, I[3]); goto o_done;
o81Af29: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(C, R1, I[3]); goto o_done;
o81Af2A: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(C, R2, I[3]); goto o_done;
o81Af2B: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(C, R3, I[3]); goto o_done;
o81Af2C: ticks-=60+F04[(int)I[3]];pc+=6; NFxchg(C, R4, I[3]); goto o_done;
o81B2: ticks-=100; pc = Npack(A, 5); goto o_done;
o81B3: ticks-=100; pc = Npack(C, 5); goto o_done;
o81B4: ticks-=60; pc+=4; Nunpack(A, pc, 5); goto o_done;
o81B5: ticks-=60; pc+=4; Nunpack(C, pc, 5); goto o_done;
o81B6: ticks-=100; d = pc+4; pc = Npack(A, 5); Nunpack(A, d, 5); goto o_done;
o81B7: ticks-=100; d = pc+4; pc = Npack(C, 5); Nunpack(C, d, 5); goto o_done;
o81C: ticks-=97; pc+=3; Nsrb(A, 16); goto o_done;
o81D: ticks-=97; pc+=3; Nsrb(B, 16); goto o_done;
o81E: ticks-=97; pc+=3; Nsrb(C, 16); goto o_done;
o81F: ticks-=97; pc+=3; Nsrb(D, 16); goto o_done;
o82n: ticks-=30; pc+=3; HST&=~I[2]; goto o_done;
o83n: ticks-=53; pc+=3; CARRY=(HST&I[2])?0:1; goyes(3); goto o_done;
o84n: ticks-=33; pc+=3; Nbit0(ST, I[2]); goto o_done;
o85n: ticks-=33; pc+=3; Nbit1(ST, I[2]); goto o_done;
o86n: ticks-=57; pc+=3; Tbit0(ST, I[2]); goyes(3); goto o_done;
o87n: ticks-=57; pc+=3; Tbit1(ST, I[2]); goyes(3); goto o_done;
o88n: ticks-=53; pc+=3; if (P!=I[2]) CARRY=1; else CARRY=0; goyes(3); goto o_done;
o89n: ticks-=53; pc+=3; if (P==I[2]) CARRY=1; else CARRY=0; goyes(3); goto o_done;
o8A0: ticks-=73; pc+=3; Te(A, B, 5); goyes(3); goto o_done;
o8A1: ticks-=73; pc+=3; Te(B, C, 5); goyes(3); goto o_done;
o8A2: ticks-=73; pc+=3; Te(C, A, 5); goyes(3); goto o_done;
o8A3: ticks-=73; pc+=3; Te(D, C, 5); goyes(3); goto o_done;
o8A4: ticks-=73; pc+=3; Tne(A, B, 5); goyes(3); goto o_done;
o8A5: ticks-=73; pc+=3; Tne(B, C, 5); goyes(3); goto o_done;
o8A6: ticks-=73; pc+=3; Tne(C, A, 5); goyes(3); goto o_done;
o8A7: ticks-=73; pc+=3; Tne(D, C, 5); goyes(3); goto o_done;
o8A8: ticks-=73; pc+=3; Tz(A, 5); goyes(3); goto o_done;
o8A9: ticks-=73; pc+=3; Tz(B, 5); goyes(3); goto o_done;
o8AA: ticks-=73; pc+=3; Tz(C, 5); goyes(3); goto o_done;
o8AB: ticks-=73; pc+=3; Tz(D, 5); goyes(3); goto o_done;
o8AC: ticks-=73; pc+=3; Tnz(A, 5); goyes(3); goto o_done;
o8AD: ticks-=73; pc+=3; Tnz(B, 5); goyes(3); goto o_done;
o8AE: ticks-=73; pc+=3; Tnz(C, 5); goyes(3); goto o_done;
o8AF: ticks-=73; pc+=3; Tnz(D, 5); goyes(3); goto o_done;
o8B0: ticks-=73; pc+=3; Ta(A, B, 5); goyes(3); goto o_done;
o8B1: ticks-=73; pc+=3; Ta(B, C, 5); goyes(3); goto o_done;
o8B2: ticks-=73; pc+=3; Ta(C, A, 5); goyes(3); goto o_done;
o8B3: ticks-=73; pc+=3; Ta(D, C, 5); goyes(3); goto o_done;
o8B4: ticks-=73; pc+=3; Tb(A, B, 5); goyes(3); goto o_done;
o8B5: ticks-=73; pc+=3; Tb(B, C, 5); goyes(3); goto o_done;
o8B6: ticks-=73; pc+=3; Tb(C, A, 5); goyes(3); goto o_done;
o8B7: ticks-=73; pc+=3; Tb(D, C, 5); goyes(3); goto o_done;
o8B8: ticks-=73; pc+=3; Tae(A, B, 5); goyes(3); goto o_done;
o8B9: ticks-=73; pc+=3; Tae(B, C, 5); goyes(3); goto o_done;
o8BA: ticks-=73; pc+=3; Tae(C, A, 5); goyes(3); goto o_done;
o8BB: ticks-=73; pc+=3; Tae(D, C, 5); goyes(3); goto o_done;
o8BC: ticks-=73; pc+=3; Tbe(A, B, 5); goyes(3); goto o_done;
o8BD: ticks-=73; pc+=3; Tbe(B, C, 5); goyes(3); goto o_done;
o8BE: ticks-=73; pc+=3; Tbe(C, A, 5); goyes(3); goto o_done;
o8BF: ticks-=73; pc+=3; Tbe(D, C, 5); goyes(3); goto o_done;
o8Cd4: ticks-=100; d=Npack(I+2, 4); if (d&0x8000) pc-=(d^0xffff)-1; else pc+=d+2; goto o_done;
o8Dd5: ticks-=109; pc=Npack(I+2, 5);; goto o_done;
o8Ed4: ticks-=104; rstkpush(pc+6); d=Npack(I+2,4); if (d&0x8000) pc-=(d^0xffff)-5; else pc+=d+6; goto o_done;
o8Fd5: ticks-=113; rstkpush(pc+7); pc=Npack(I+2, 5); goto o_done;
o9a0: ticks-=53+F04[(int)I[1]];pc+=3; TFe(A, B, I[1]); goyes(3); goto o_done;
o9a1: ticks-=53+F04[(int)I[1]];pc+=3; TFe(B, C, I[1]); goyes(3); goto o_done;
o9a2: ticks-=53+F04[(int)I[1]];pc+=3; TFe(C, A, I[1]); goyes(3); goto o_done;
o9a3: ticks-=53+F04[(int)I[1]];pc+=3; TFe(D, C, I[1]); goyes(3); goto o_done;
o9a4: ticks-=53+F04[(int)I[1]];pc+=3; TFne(A, B, I[1]); goyes(3); goto o_done;
o9a5: ticks-=53+F04[(int)I[1]];pc+=3; TFne(B, C, I[1]); goyes(3); goto o_done;
o9a6: ticks-=53+F04[(int)I[1]];pc+=3; TFne(C, A, I[1]); goyes(3); goto o_done;
o9a7: ticks-=53+F04[(int)I[1]];pc+=3; TFne(D, C, I[1]); goyes(3); goto o_done;
o9a8: ticks-=53+F04[(int)I[1]];pc+=3; TFz(A, I[1]); goyes(3); goto o_done;
o9a9: ticks-=53+F04[(int)I[1]];pc+=3; TFz(B, I[1]); goyes(3); goto o_done;
o9aA: ticks-=53+F04[(int)I[1]];pc+=3; TFz(C, I[1]); goyes(3); goto o_done;
o9aB: ticks-=53+F04[(int)I[1]];pc+=3; TFz(D, I[1]); goyes(3); goto o_done;
o9aC: ticks-=53+F04[(int)I[1]];pc+=3; TFnz(A, I[1]); goyes(3); goto o_done;
o9aD: ticks-=53+F04[(int)I[1]];pc+=3; TFnz(B, I[1]); goyes(3); goto o_done;
o9aE: ticks-=53+F04[(int)I[1]];pc+=3; TFnz(C, I[1]); goyes(3); goto o_done;
o9aF: ticks-=53+F04[(int)I[1]];pc+=3; TFnz(D, I[1]); goyes(3); goto o_done;
o9b0: ticks-=53+F04[(int)I[1]];pc+=3; TFa(A, B, I[1]&7); goyes(3); goto o_done;
o9b1: ticks-=53+F04[(int)I[1]];pc+=3; TFa(B, C, I[1]&7); goyes(3); goto o_done;
o9b2: ticks-=53+F04[(int)I[1]];pc+=3; TFa(C, A, I[1]&7); goyes(3); goto o_done;
o9b3: ticks-=53+F04[(int)I[1]];pc+=3; TFa(D, C, I[1]&7); goyes(3); goto o_done;
o9b4: ticks-=53+F04[(int)I[1]];pc+=3; TFb(A, B, I[1]&7); goyes(3); goto o_done;
o9b5: ticks-=53+F04[(int)I[1]];pc+=3; TFb(B, C, I[1]&7); goyes(3); goto o_done;
o9b6: ticks-=53+F04[(int)I[1]];pc+=3; TFb(C, A, I[1]&7); goyes(3); goto o_done;
o9b7: ticks-=53+F04[(int)I[1]];pc+=3; TFb(D, C, I[1]&7); goyes(3); goto o_done;
o9b8: ticks-=53+F04[(int)I[1]];pc+=3; TFae(A, B, I[1]&7); goyes(3); goto o_done;
o9b9: ticks-=53+F04[(int)I[1]];pc+=3; TFae(B, C, I[1]&7); goyes(3); goto o_done;
o9bA: ticks-=53+F04[(int)I[1]];pc+=3; TFae(C, A, I[1]&7); goyes(3); goto o_done;
o9bB: ticks-=53+F04[(int)I[1]];pc+=3; TFae(D, C, I[1]&7); goyes(3); goto o_done;
o9bC: ticks-=53+F04[(int)I[1]];pc+=3; TFbe(A, B, I[1]&7); goyes(3); goto o_done;
o9bD: ticks-=53+F04[(int)I[1]];pc+=3; TFbe(B, C, I[1]&7); goyes(3); goto o_done;
o9bE: ticks-=53+F04[(int)I[1]];pc+=3; TFbe(C, A, I[1]&7); goyes(3); goto o_done;
o9bF: ticks-=53+F04[(int)I[1]];pc+=3; TFbe(D, C, I[1]&7); goyes(3); goto o_done;
oAa0: ticks-=33+F04[(int)I[1]];pc+=3; NFadd(A, B, I[1]); goto o_done;
oAa1: ticks-=33+F04[(int)I[1]];pc+=3; NFadd(B, C, I[1]); goto o_done;
oAa2: ticks-=33+F04[(int)I[1]];pc+=3; NFadd(C, A, I[1]); goto o_done;
oAa3: ticks-=33+F04[(int)I[1]];pc+=3; NFadd(D, C, I[1]); goto o_done;
oAa4: ticks-=33+F04[(int)I[1]];pc+=3; NFdbl(A, I[1]); goto o_done;
oAa5: ticks-=33+F04[(int)I[1]];pc+=3; NFdbl(B, I[1]); goto o_done;
oAa6: ticks-=33+F04[(int)I[1]];pc+=3; NFdbl(C, I[1]); goto o_done;
oAa7: ticks-=33+F04[(int)I[1]];pc+=3; NFdbl(D, I[1]); goto o_done;
oAa8: ticks-=33+F04[(int)I[1]];pc+=3; NFadd(B, A, I[1]); goto o_done;
oAa9: ticks-=33+F04[(int)I[1]];pc+=3; NFadd(C, B, I[1]); goto o_done;
oAaA: ticks-=33+F04[(int)I[1]];pc+=3; NFadd(A, C, I[1]); goto o_done;
oAaB: ticks-=33+F04[(int)I[1]];pc+=3; NFadd(C, D, I[1]); goto o_done;
oAaC: ticks-=33+F04[(int)I[1]];pc+=3; NFdec(A, I[1]); goto o_done;
oAaD: ticks-=33+F04[(int)I[1]];pc+=3; NFdec(B, I[1]); goto o_done;
oAaE: ticks-=33+F04[(int)I[1]];pc+=3; NFdec(C, I[1]); goto o_done;
oAaF: ticks-=33+F04[(int)I[1]];pc+=3; NFdec(D, I[1]); goto o_done;
oAb0: ticks-=33+F04[(int)I[1]];pc+=3; NFzero(A, I[1]&7); goto o_done;
oAb1: ticks-=33+F04[(int)I[1]];pc+=3; NFzero(B, I[1]&7); goto o_done;
oAb2: ticks-=33+F04[(int)I[1]];pc+=3; NFzero(C, I[1]&7); goto o_done;
oAb3: ticks-=33+F04[(int)I[1]];pc+=3; NFzero(D, I[1]&7); goto o_done;
oAb4: ticks-=33+F04[(int)I[1]];pc+=3; NFcopy(A, B, I[1]&7); goto o_done;
oAb5: ticks-=33+F04[(int)I[1]];pc+=3; NFcopy(B, C, I[1]&7); goto o_done;
oAb6: ticks-=33+F04[(int)I[1]];pc+=3; NFcopy(C, A, I[1]&7); goto o_done;
oAb7: ticks-=33+F04[(int)I[1]];pc+=3; NFcopy(D, C, I[1]&7); goto o_done;
oAb8: ticks-=33+F04[(int)I[1]];pc+=3; NFcopy(B, A, I[1]&7); goto o_done;
oAb9: ticks-=33+F04[(int)I[1]];pc+=3; NFcopy(C, B, I[1]&7); goto o_done;
oAbA: ticks-=33+F04[(int)I[1]];pc+=3; NFcopy(A, C, I[1]&7); goto o_done;
oAbB: ticks-=33+F04[(int)I[1]];pc+=3; NFcopy(C, D, I[1]&7); goto o_done;
oAbC: ticks-=33+F04[(int)I[1]];pc+=3; NFxchg(A, B, I[1]&7); goto o_done;
oAbD: ticks-=33+F04[(int)I[1]];pc+=3; NFxchg(B, C, I[1]&7); goto o_done;
oAbE: ticks-=33+F04[(int)I[1]];pc+=3; NFxchg(C, A, I[1]&7); goto o_done;
oAbF: ticks-=33+F04[(int)I[1]];pc+=3; NFxchg(D, C, I[1]&7); goto o_done;
oBa0: ticks-=33+F04[(int)I[1]];pc+=3; NFsub(A, B, I[1]); goto o_done;
oBa1: ticks-=33+F04[(int)I[1]];pc+=3; NFsub(B, C, I[1]); goto o_done;
oBa2: ticks-=33+F04[(int)I[1]];pc+=3; NFsub(C, A, I[1]); goto o_done;
oBa3: ticks-=33+F04[(int)I[1]];pc+=3; NFsub(D, C, I[1]); goto o_done;
oBa4: ticks-=33+F04[(int)I[1]];pc+=3; NFinc(A, I[1]); goto o_done;
oBa5: ticks-=33+F04[(int)I[1]];pc+=3; NFinc(B, I[1]); goto o_done;
oBa6: ticks-=33+F04[(int)I[1]];pc+=3; NFinc(C, I[1]); goto o_done;
oBa7: ticks-=33+F04[(int)I[1]];pc+=3; NFinc(D, I[1]); goto o_done;
oBa8: ticks-=33+F04[(int)I[1]];pc+=3; NFsub(B, A, I[1]); goto o_done;
oBa9: ticks-=33+F04[(int)I[1]];pc+=3; NFsub(C, B, I[1]); goto o_done;
oBaA: ticks-=33+F04[(int)I[1]];pc+=3; NFsub(A, C, I[1]); goto o_done;
oBaB: ticks-=33+F04[(int)I[1]];pc+=3; NFsub(C, D, I[1]); goto o_done;
oBaC: ticks-=33+F04[(int)I[1]];pc+=3; NFrsub(A, B, I[1]); goto o_done;
oBaD: ticks-=33+F04[(int)I[1]];pc+=3; NFrsub(B, C, I[1]); goto o_done;
oBaE: ticks-=33+F04[(int)I[1]];pc+=3; NFrsub(C, A, I[1]); goto o_done;
oBaF: ticks-=33+F04[(int)I[1]];pc+=3; NFrsub(D, C, I[1]); goto o_done;
oBb0: ticks-=33+F04[(int)I[1]];pc+=3; NFsl(A, I[1]&7); goto o_done;
oBb1: ticks-=33+F04[(int)I[1]];pc+=3; NFsl(B, I[1]&7); goto o_done;
oBb2: ticks-=33+F04[(int)I[1]];pc+=3; NFsl(C, I[1]&7); goto o_done;
oBb3: ticks-=33+F04[(int)I[1]];pc+=3; NFsl(D, I[1]&7); goto o_done;
oBb4: ticks-=33+F04[(int)I[1]];pc+=3; NFsr(A, I[1]&7); goto o_done;
oBb5: ticks-=33+F04[(int)I[1]];pc+=3; NFsr(B, I[1]&7); goto o_done;
oBb6: ticks-=33+F04[(int)I[1]];pc+=3; NFsr(C, I[1]&7); goto o_done;
oBb7: ticks-=33+F04[(int)I[1]];pc+=3; NFsr(D, I[1]&7); goto o_done;
oBb8: ticks-=33+F04[(int)I[1]];pc+=3; NFneg(A, I[1]&7); goto o_done;
oBb9: ticks-=33+F04[(int)I[1]];pc+=3; NFneg(B, I[1]&7); goto o_done;
oBbA: ticks-=33+F04[(int)I[1]];pc+=3; NFneg(C, I[1]&7); goto o_done;
oBbB: ticks-=33+F04[(int)I[1]];pc+=3; NFneg(D, I[1]&7); goto o_done;
oBbC: ticks-=33+F04[(int)I[1]];pc+=3; NFnot(A, I[1]&7); goto o_done;
oBbD: ticks-=33+F04[(int)I[1]];pc+=3; NFnot(B, I[1]&7); goto o_done;
oBbE: ticks-=33+F04[(int)I[1]];pc+=3; NFnot(C, I[1]&7); goto o_done;
oBbF: ticks-=33+F04[(int)I[1]];pc+=3; NFnot(D, I[1]&7); goto o_done;
oC0: ticks-=40; pc+=2; Nadd(A, B, 5); goto o_done;
oC1: ticks-=40; pc+=2; Nadd(B, C, 5); goto o_done;
oC2: ticks-=40; pc+=2; Nadd(C, A, 5); goto o_done;
oC3: ticks-=40; pc+=2; Nadd(D, C, 5); goto o_done;
oC4: ticks-=40; pc+=2; Ndbl(A, 5); goto o_done;
oC5: ticks-=40; pc+=2; Ndbl(B, 5); goto o_done;
oC6: ticks-=40; pc+=2; Ndbl(C, 5); goto o_done;
oC7: ticks-=40; pc+=2; Ndbl(D, 5); goto o_done;
oC8: ticks-=40; pc+=2; Nadd(B, A, 5); goto o_done;
oC9: ticks-=40; pc+=2; Nadd(C, B, 5); goto o_done;
oCA: ticks-=40; pc+=2; Nadd(A, C, 5); goto o_done;
oCB: ticks-=40; pc+=2; Nadd(C, D, 5); goto o_done;
oCC: ticks-=40; pc+=2; Ndec(A, 5); goto o_done;
oCD: ticks-=40; pc+=2; Ndec(B, 5); goto o_done;
oCE: ticks-=40; pc+=2; Ndec(C, 5); goto o_done;
oCF: ticks-=40; pc+=2; Ndec(D, 5); goto o_done;
oD0: ticks-=40; pc+=2; Nzero(A, 5); goto o_done;
oD1: ticks-=40; pc+=2; Nzero(B, 5); goto o_done;
oD2: ticks-=40; pc+=2; Nzero(C, 5); goto o_done;
oD3: ticks-=40; pc+=2; Nzero(D, 5); goto o_done;
oD4: ticks-=40; pc+=2; Ncopy(A, B, 5); goto o_done;
oD5: ticks-=40; pc+=2; Ncopy(B, C, 5); goto o_done;
oD6: ticks-=40; pc+=2; Ncopy(C, A, 5); goto o_done;
oD7: ticks-=40; pc+=2; Ncopy(D, C, 5); goto o_done;
oD8: ticks-=40; pc+=2; Ncopy(B, A, 5); goto o_done;
oD9: ticks-=40; pc+=2; Ncopy(C, B, 5); goto o_done;
oDA: ticks-=40; pc+=2; Ncopy(A, C, 5); goto o_done;
oDB: ticks-=40; pc+=2; Ncopy(C, D, 5); goto o_done;
oDC: ticks-=40; pc+=2; Nxchg(A, B, 5); goto o_done;
oDD: ticks-=40; pc+=2; Nxchg(B, C, 5); goto o_done;
oDE: ticks-=40; pc+=2; Nxchg(C, A, 5); goto o_done;
oDF: ticks-=40; pc+=2; Nxchg(D, C, 5); goto o_done;
oE0: ticks-=40; pc+=2; Nsub(A, B, 5); goto o_done;
oE1: ticks-=40; pc+=2; Nsub(B, C, 5); goto o_done;
oE2: ticks-=40; pc+=2; Nsub(C, A, 5); goto o_done;
oE3: ticks-=40; pc+=2; Nsub(D, C, 5); goto o_done;
oE4: ticks-=40; pc+=2; Ninc(A, 5); goto o_done;
oE5: ticks-=40; pc+=2; Ninc(B, 5); goto o_done;
oE6: ticks-=40; pc+=2; Ninc(C, 5); goto o_done;
oE7: ticks-=40; pc+=2; Ninc(D, 5); goto o_done;
oE8: ticks-=40; pc+=2; Nsub(B, A, 5); goto o_done;
oE9: ticks-=40; pc+=2; Nsub(C, B, 5); goto o_done;
oEA: ticks-=40; pc+=2; Nsub(A, C, 5); goto o_done;
oEB: ticks-=40; pc+=2; Nsub(C, D, 5); goto o_done;
oEC: ticks-=40; pc+=2; Nrsub(A, B, 5); goto o_done;
oED: ticks-=40; pc+=2; Nrsub(B, C, 5); goto o_done;
oEE: ticks-=40; pc+=2; Nrsub(C, A, 5); goto o_done;
oEF: ticks-=40; pc+=2; Nrsub(D, C, 5); goto o_done;
oF0: ticks-=44; pc+=2; Nsl(A, 5); goto o_done;
oF1: ticks-=44; pc+=2; Nsl(B, 5); goto o_done;
oF2: ticks-=44; pc+=2; Nsl(C, 5); goto o_done;
oF3: ticks-=44; pc+=2; Nsl(D, 5); goto o_done;
oF4: ticks-=44; pc+=2; Nsr(A, 5); goto o_done;
oF5: ticks-=44; pc+=2; Nsr(B, 5); goto o_done;
oF6: ticks-=44; pc+=2; Nsr(C, 5); goto o_done;
oF7: ticks-=44; pc+=2; Nsr(D, 5); goto o_done;
oF8: ticks-=40; pc+=2; Nneg(A, 5); goto o_done;
oF9: ticks-=40; pc+=2; Nneg(B, 5); goto o_done;
oFA: ticks-=40; pc+=2; Nneg(C, 5); goto o_done;
oFB: ticks-=40; pc+=2; Nneg(D, 5); goto o_done;
oFC: ticks-=40; pc+=2; Nnot(A, 5); goto o_done;
oFD: ticks-=40; pc+=2; Nnot(B, 5); goto o_done;
oFE: ticks-=40; pc+=2; Nnot(C, 5); goto o_done;
oFF: ticks-=40; pc+=2; Nnot(D, 5); goto o_done;
/* 424 lines, 1 instructions */


354
PCPDBG.H Normal file
View file

@ -0,0 +1,354 @@
/* UCMS_VERSION_ID("@(#)pcpdbg.h 61EX:6 readonly 17/05/95 12:59(#)@") */
#ifndef PCPDBG_H
/*****************************************************************************
*
* $Workfile:: PCPDBG.H $
*
* $Logfile:: $
*
* Library:: CLASSLIB.LIB
*
* Makefile:: MAKEFILE
*
* $Date:: $
*
* $Revision:: 0.00 $
*
* $Author:: Klaas van Ditzhuyzen $
*
* Functions::
*
* $Log:: $
*
* NOTES: DEBUG_PRINTF should be defined as a standard printf routine
* to a debug port or file.
* DEBUG_ON() is a macro which returns the debug level. When
* zero, all runtime debugging is turned off.
*
*****************************************************************************/
/*****************************************************************************
* Definitions
*****************************************************************************/
#ifndef EXTERN_C
/* Allow usage of C++ compiler */
#ifdef __cplusplus /* Move this to "software.h" */
#define EXTERN_C extern "C"
#define EXTERN_C_BEGIN EXTERN_C {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif /* C++ */
#endif /* EXTERN_C */
#ifndef NULL
#define NULL ((void*) 0)
#endif
#if DEBUG
#ifdef _MSC_VER
#pragma message("DEBUG SHIT ENABLED")
#endif
#ifndef DEBUG_PRINTF_FUNCDEF
#define DEBUG_PRINTF_FUNCDEF(file) \
EXTERN_C int DEBUG_PRINTF(const char *s, ...) \
{ \
va_list array; \
char *p = file; \
int i; \
static FILE * fp; \
va_start(array,s); \
if (!fp) \
{ \
if (!file) \
{ \
char fbuf[100]; \
strcpy(fbuf, __FILE__); \
p = strchr(fbuf, '.'); \
strcpy(p, ".log"); \
p = fbuf; \
} \
fp = fopen(p, "w"); \
} \
i = vfprintf(fp, s, array); \
fflush(fp); \
return i; \
}
#endif
EXTERN_C void DEBUG_DUMPDATA(const char *name, const void *ptr, int nbytes, int flags);
/*
* Log current value of STACK in hex (consumes two words of stack space !).
*/
#ifndef DEBUG_LOGSTACK
#define DEBUG_LOGSTACK() { int _stack, *STACK=&_stack; dsx(STACK); }
#endif
/*
* Makes always an acceptable string
*/
#ifndef DEBUG_STR
#define DEBUG_STR(x) (char*)(x) ? (*((char*)x) ? (char*)(x) : "\\0") : _nullname
#endif
/*
* Opens the debug environment. Can be redefined.
*/
#ifndef DEBUG_OPEN
#define DEBUG_OPEN(file) fopen(file, "w",stdout)
#endif
/*
* Does a printf() to a debug file or port.
*/
#ifndef DEBUG_PRINTF
#define DEBUG_PRINTF printf
#endif
#ifndef zprintf
#define zprintf DEBUG_PRINTF
#endif
/*
* Logs return value and return it.
*/
#ifndef DEBUG_RETURN
#define DEBUG_RETURN(x) { ds(("Returning %s\n",#x)) return x; }
#endif
/*
* Can be replaced by a variable which holds the debug level.
*/
#ifndef DEBUG_ON
#if DEBUG==2
int _debug_on=1;
#elif DEBUG==3
extern int _debug_on;
#elif DEBUG==1
static int _debug_on=1;
#endif
#define DEBUG_ON() (_debug_on)
#endif
/*
* Can be replaced by a variable which holds the debug level.
* Used for tracing function entries.
*/
#ifndef DEBUG_ENTRYON
#define DEBUG_ENTRYON() DEBUG_ON()
#endif
/*
* Cleans up the debug environment.
*/
#ifndef DEBUG_CLOSE
#define DEBUG_CLOSE() fclose(stdout)
#endif
/*
* Log file name and line number
*/
#ifndef DEBUG_LOGFILELINE
static char __fileline__[]="%-10s %4d :";
/* #define DEBUG_LOGFILELINE(file, line) DEBUG_PRINTF("%-10s %4d :",file,line) */
#define DEBUG_LOGFILELINE(file, line) DEBUG_PRINTF(__fileline__,file,line)
#endif
#ifndef DL
#define DL() DEBUG_LOGFILELINE(__FILE__,__LINE__);
#endif
#ifndef DEBUG_ENTRY
/*
* Function entry and exit
*/
#define _DEBUG_STACKTAG 0xFEDCBA98 /* magic number */
#ifdef __cplusplus
class debug_logentry
{
private:
long stacktag;
char *funcname;
public:
char *getfuncname() { return funcname; } // function name
void * getstack() { int hello; return (void*) &hello; } // return current stack
void * unwindstack(); // unwind stack
debug_logentry(char *name)
{
funcname = name;
stacktag = _DEBUG_STACKTAG; // magic number
if (DEBUG_ENTRYON()) DEBUG_PRINTF("Entering [%s]\n", funcname);
}
~debug_logentry()
{
if (DEBUG_ENTRYON()) DEBUG_PRINTF("Leaving [%s]\n", funcname);
}
} ;
#define __FUNCENTRY__(a,b) debug_logentry __FUNC__(a);
#else
/*
* Sets the name of a function in a local variable called __FUNC__.
* Can be replaced by logging the name.
*/
typedef struct
{
long stacktag;
char *funcname;
} debug_logentry;
#define __FUNCENTRY__(a,b) debug_logentry __FUNC__ = {_DEBUG_STACKTAG, a} ;
#endif /* C++ */
#define DEBUG_ENTRY(a,b) __FUNCENTRY__(#a,b)
#endif /* DEBUG_ENTRY */
#define D(x) x
#define d(x) {if (DEBUG_ON()) {x} }
#define dd(x) {if (DEBUG_ON()) {DL() x} }
#define ds(x) dd(DEBUG_PRINTF x; )
#define dsx(x) ds(( #x "=0x%08lX\n", (long)(x)))
#define dsd(x) ds(( #x "=%ld\n", (long)(x)))
#define dsxd(x) ds(( #x "=0x%08lX %ld\n", (long)(x), (long)(x)))
#define dsf(x) ds(( #x "=%16g\n", (double)(x)))
#define dsm(s,n) DL() DEBUG_DUMPDATA(#s, s, n, 0)
static const char _nullname[] = "<NULL>";
#define dss(x) ds(( #x "=[%s]\n", (const char*)((char*)(x) ? (char*)(x) : _nullname)))
#define dsxs(x) ds(( #x "=0x%08lX [%s]\n", (long)(x), (const char*)((char*)(x) ? (char*)(x) : _nullname)))
#if __cplusplus
#define dcp(x) { dd((x)->debug(#x);) } // class debug function
/*
* For debugging of existing structures: make a derived class of it.
* NOTE: private members are not accessible by this class !
*/
#define DEBUG_DCLASS(type, statements) \
class _DEBUG_##type : public type \
{ \
public: \
inline operator type & () { return (type &) *this; } \
inline _DEBUG_##type & operator = (type & par) { *this = (_DEBUG_##type &) par; return *this; } \
DEBUG_LOGSTRUCT(statements) \
} ; \
DEBUG_LOGSTRUCTFUNC(type,var)
#define ddcp(var) { dd(_debug_logstruct(var, #var); ) }
/*
* For debugging of nonstruct scalar types: make a class containing one data element
* of the specified type named <var>.
*/
#define DEBUG_VCLASS(type,statements) \
class _DEBUG_##type \
{ \
protected: \
type var; \
public: \
_DEBUG_##type(const type init) { var = init; } \
inline operator type & () const { return (type&) var ; } \
DEBUG_LOGSTRUCT(statements) \
} ; \
DEBUG_LOGSTRUCTFUNC(type,var)
#else /* Standard Regular C */
#define DEBUG_VCLASS(y,x)
#define DEBUG_DCLASS(y,x)
#define ddcp(x) /* not defined */
#define dcp(x) /* not defined */
#endif /* if C++ */
#else /* DEBUG off */
/* stub out DEBUG_PRINTF */
#define DEBUG_PRINTF_FUNCDEF(file) \
EXTERN_C int DEBUG_PRINTF(const char *s, ...) { return 0; }
#define DEBUG_STR(s) s
#define DEBUG_LOGSTACK()
#define DEBUG_VCLASS(y,x)
#define DEBUG_DCLASS(y,x)
#define DEBUG_OPEN(file)
#define DEBUG_CLOSE()
#define DEBUG_ENTRY(a,b)
#define DEBUG_LOGFILELINE(x,y)
#define DEBUG_RETURN(x) return x
#define __FUNCENTRY__(a,b)
#define D(x)
#define DL()
#define d(x)
#define dd(x)
#define ds(x)
#define dsx(x)
#define dsd(x)
#define dsxd(x)
#define dsf(x)
#define dsm(s,n)
#define dss(x)
#define dcp(x)
#define ddcp(x)
#define dsxs(x)
#endif /* if DEBUG */
#ifndef assert
#include <assert.h>
#endif
#if !DEBUG
#define _assert(exp, file, line) _assert(NULL, file, line)
#endif
/*
* DEBUG member function in a struct or class (C++ only)
* To be put as last item in a struct or class definition.
*/
#if DEBUG && __cplusplus
/*
* This nonclass function allows type specific versions to allow
* automatic invocation of the type specific debug function without
* specifying the type in the macro.
*/
#define DEBUG_LOGSTRUCTFUNC(type, var) \
inline void _debug_logstruct(const type * var, char * str) \
{ \
((_DEBUG_##type*)var)->debug(str, #type); \
}
#ifndef DEBUG_LOGSTRUCT
#define DEBUG_LOGSTRUCT(x) \
public: void debug(const char *s, const char *typestr=NULL) { \
DEBUG_PRINTF("%s [%s]: ptr=%08lXh\n", typestr ? typestr : "?", s, this); \
if (this) { x ; } }
#endif
#else
#define DEBUG_LOGSTRUCTFUNC(type, var)
#define DEBUG_LOGSTRUCT(x)
#endif /* if C++ */
#define PCPDBG_H
#endif

BIN
PIX4.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

239
README Normal file
View file

@ -0,0 +1,239 @@
Emu48 - an HP48 emulator
Copyright (C) 1995 Sebastien Carlier (sebc@cybera.anet.fr)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Emu48 - an HP48 emulator
========================
This is Emu48, another HP48 CPU emulator. This is Version 0.37
It's at least 25% faster than a real HP48GX on an Intel DX2-66,
and it's very small. Though I did nothing to allow that, Emu48
can emulate BOTH HP48G/GX and HP48S/SX. You've just to give it
the proper rom dump file.
Emu48 is now compatible with Emul48 rom and ram files, but it
will always write them in its own style.
NOTE (from x48 by Eddie C. Dost, from EM48 README by Paul Fox)
===================================
This emulator is capable of providing a faithful replication of the
HP48. In order to do so, it requires a copy of the ROM software
from YOUR calculator. In order to avoid breaking copyright laws,
and upsetting HP, you MUST BE THE PROUD OWNER OF AN HP48 before
running this program. Of course you can run this program without a
copy of the ROM software in order to write trivial machine code
programs but you will not be able to access any of the calculator
functionality.
Instructions on how to download a copy of the ROM are provided
later in this document.
CREDITS
=======
Thanks to all these friendly guys I met on the #hp48 channel on IRC :
alonzo (Alonzo Gariepy - helped a lot in optimizing Emu48)
fin (Mika Heiskanen - his Jazz is great)
moyer |
BeeF | helpful ideas, documentations, testing programs...
hideki |
and the others I might have forgotten.
Some parts of this README come from x48 README by Eddie C. Dost.
COMPILING THE SOURCES
=====================
Copy the proper makefile into the main directory and run 'make'.
Supported plateforms :
Linux/svgalib
MsDos/go32
MsDos/PharLap
Windows 95/NT
HOW TO DOWNLOAD A COPY OF THE ROM
=================================
The emulator works by executing an image of the HP48s ROM. In order
to run the emulator you must have a version of your ROM on the system.
**********************************************************************
* This includes the HIDDEN ROM. Please don't use DUMP programs, that *
* don't dump the HIDDEN ROM. The emulator won't run. *
**********************************************************************
To get a memory dump you need to do the following:
- Download the file 'romdump/ROMDump' to your HP.
- To capture a complete ROM, start kermit on your computer, set the
line so it fits your HP, set the speed to 9600 baud and type
'log session', then 'connect'.
- On a HP48 S/SX type '#0h #7FFFFh ROMDump',
on a HP48 G/GX type '#0h #FFFFFh ROMDump'.
This will take about 15 minutes on the S/SX, 30 minutes on the G/GX.
- When done, type the kermit-Escape (usually CTRL-\) followed
by 'C' on your Computer. Say 'quit' to the kermit.
Your ROM should now be in the file 'session.log'.
Now you have a file containing lines like
#00000:2369B108DADF1008
...
This has to be converted to a binary ROM for x48.
Run the command: `dump2rom session.log`
This will convert your dump into a rom file readable by the emulator
called 'rom.dump'.
CHECK the file with the program 'checkrom'.
Type: `checkrom rom.dump`. It should say:
ROM Version is HP48-A
ROM CRC reads 0xcb76 (for Rev. A, will be different for other ROMs)
IROM OK: ROM CRC test passed.
or
ROM Version is HP48-R
ROM CRC 1 reads 0xdfed (for Rev. R, will be different for other ROMs)
ROM CRC 2 reads 0xf0b1 ( --- " --- )
IROM OK: ROM CRC test passed.
If the test failed, something went wrong transfering the ROM. Don't
start thinking about the size or the nibbles in 'rom.dump'. That's
all correct. Do the Transfer again.
If you know how to do it, you could of course only transfer the
'broken' part of the dump, using e.g. '#60000h #60080h ROMDump'
and fix these lines in 'session.log'.
USING THE EMULATOR
==================
* Press the RIGHT Control key to quit the emulator.
* Press the RIGHT Alt key to quit the emulator WITHOUT SAVING its state.
* If(When?) the emulator crashes, quit it with [RightCtrl], and run
emu48 -W
If it doesn't work, try using -WC instead of -W.
If this fails, delete the file named 'saturn' and run emu48.
USING RAM CARDS
===============
To get a RAM card, just create files named 'port1' and 'port2' with
something like this :
echo > port1
or echo > port2
You can now create files named 'port2.1', 'port2.2'...'port2.31' to have
a card bigger than 128k in port 2.
KEYBOARD SUPPORT
================
ON = Esc
A = A, Insert B = B, Home
C = C, PageUp D = D, Delete
E = E, End F = F, PageDown
G,MTH = G H,PRG = H
I,CST = I J,VAR = J
K,UP = K, Up Arrow L,NXT = L
M,' = M, ' N,STO = N
O,EVAL = O P,LEFT = P, Left Arrow
Q,DOWN = Q, Down Arrow R,RIGHT= E, Right Arrow
S,SIN = S T,COS = T
U,TAN = U V,SQRT = V
W,Y^X = W X,1/X = X
ENTER = ENTER Y,+/- = Y
Z,EEX = Z DEL = Keypad Del
<= = BackSpace ALPHA = Left Shift, Right Shift
<~| = Left Crtl |~> = Left Alt
0 = 0, Keypad 0 1 = 1, Keypad 1
2 = 2, Keypad 2 3 = 3, Keypad 3
4 = 4, Keypad 4 5 = 5, Keypad 5
6 = 6, Keypad 6 7 = 7, Keypad 7
8 = 8, Keypad 8 9 = 9, Keypad 9
. = . SPC = Space
/ = /, Keypad / * = Keypad *
- = -, Keypad - + = Keypad +
TALKING TO THE OUTSIDE WORLD
============================
* To load a kermit file from disk, name it as 'port1' in the directory
in which the emulator is. Then run the emulator, type the following
program and store it as 'GET1' :
<< GROB 8 3 0100C0 #4017h SYSEVAL #56B6h SYSEVAL DROP NEWOB >>
When you execute this program, it will put on the stack the content
of the file you renamed as 'port1'.
This works only for binary files.
* Serial ports aren't emulated. Instead, the XMIT command will write
its output to a file named 'wire'. You can use the 'SND.PRG' file
along with the DEV library (download them 'GET1') to send an object
on the stack to the file 'wire', which will be exactly like a kermit
binary file. You must quit the emulator and rename 'wire' before
sending another file, otherwise you'll only be able to recover the
first file.
KNOWN BUGS
==========
Timer handling isn't really good. I'm fixing that.
I must also provide different keyboard mappings.
Someone told me Emu48 didn't display anything on his computer. This should
be checked.
ACCESS TO THE AUTHOR
====================
Please send any bug reports, context-diffs or suggestions to
sebc@cybera.anet.fr
Sebastien Carlier
10, Allee des bergeronnettes
35340 LIFFRE
FRANCE

21
RESOURCE.H Normal file
View file

@ -0,0 +1,21 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by EMU48.RC
//
#define IDI_APP 101
#define IDB_KEYBOARD 102
#define ID_SYSTEM_RUN 40001
#define ID_SYSTEM_EXIT 40002
#define ID_SAVE 40004
#define ID_HELP_ABOUT 40003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40004
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

BIN
ROM Normal file

Binary file not shown.

BIN
ROMDUMP Normal file

Binary file not shown.

3
RUNME.BAT Normal file
View file

@ -0,0 +1,3 @@
@echo off
echo Building opcodes.h
..\bin\lst2c.com < ..\src\opcodes.lst > ..\src\opcodes.h

130
SATURN.C Normal file
View file

@ -0,0 +1,130 @@
/*
* emu48/src/emulate.c
*
* Copyright (C) 1995 Sebastien Carlier
*/
#include <stdio.h>
#include "emu48.h"
#define goyes(n) GOJMP = I+n; goto o_goyes;
/* P WP* XS X S M B W P WP XS X S M B W*/
int F04[16] = { 4, 32, 4, 12, 4, 48, 8, 64, 4, 4, 4, 12, 4, 48, 8, 64};
int FRD[16] = {132,202,132,152,132,248,142,288,132,202,132,152,132,248,142,288};
int FWR[16] = {142,212,142,162,142,232,152,272,142,212,142,162,142,232,152,272};
/* P WP XS X S M B W - - - - - - - A*/
int S00[16] = {124,124,124, 68,124,124, 64,120, 0, 0, 0, 0, 0, 0, 0, 76};
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F*/
int D10[16] = { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90,100,110,120,130,140,150};
int NWR[16] = {142,132,162,152,182,172,202,192,222,212,242,232,262,252,282,272};
int NRD[16] = {132,148,152,168,172,188,192,208,212,228,232,248,252,268,272,288};
/*108 874*/
char X[16];
FILE *wire;
void emulate() {
long ticks, update_lcd, update_kbd;
long d;
char *I, *GOJMP, n;
signed char jmp;
wire = fopen("wire", "wb");
ticks = saturn_speed;
update_lcd=0;
update_kbd=128;
while (!quit) {
if (SHUTDN) { ticks-=12; goto o_done; }
if (pc<0x7E000) { I = rom+pc; goto o_fetch; }
if (ISMODULE(1, pc)) { I = data[1]+pc-base[1]; goto o_fetch; }
if (CARDSTATUS&2) if (ISMODULE(3, pc)) { I = data[3]+pc-base[3]; goto o_fetch; }
if (CARDSTATUS&1) if (ISMODULE(4, pc)) { I = data[4]+pc-base[4]; goto o_fetch; }
I = rom+pc;
o_fetch:
#include "fetch.h"
#include "opcodes.h"
o_goyes:
if (!CARRY) { pc+=2; goto o_done; }
ticks -= 40;
jmp = GOJMP[0] | (GOJMP[1]<<4);
if (jmp) pc+=jmp; else pc=rstkpop();
goto o_done;
o_invalid:
sprintf(Buf, "Invalid Opcode at #%05lX\n", pc);
display_warning(Buf);
fclose(wire);
quit = 1;
return;
o_invalid3: pc+=3; ticks--; goto o_done;
o_invalid4: pc+=4; ticks--; goto o_done;
o_invalid5: pc+=5; ticks--; goto o_done;
o_invalid6: pc+=6; ticks--; goto o_done;
o_done:
if (ticks>0) continue;
/* 1/8192s has elapsed */
ticks = saturn_speed;
update_lcd^=1;
if (update_lcd) { /* LCD_REFRESH 4096Hz */
display_next();
if (display.touched) display_redraw();
if (ioram[0x10]&8) {
if (ioram[0x12]&1) {
fputc((char)Npack(ioram+0x16, 2), wire);
ioram[0x12] = 0;
if (ioram[0x10]&4) INTERRUPT("IO");
}
}
}
update_kbd--;
if (update_kbd<=0) { /* KBD_UPDATE 64Hz */
if ((ioram[0x2f]&1) == 0) update_kbd = 128;
keyboard_update();
if (IR15X) {
SHUTDN = 0;
if (!INTP) INTERRUPT("ON");
}
}
if ((ioram[0x2f]&1) == 0) continue; /* T2, T1, KBD_POLL disabled ? */
if (t2) /* T2 8192Hz */
t2--;
else {
t2 = 0xffffffff;
if (ioram[0x2f]&4) { ioram[0x2f]|=8; SHUTDN = 0; }
if (ioram[0x2f]&2) { ioram[0x2f]|=8; if (!INTP) INTERRUPT("T2"); }
}
if ((t2&0x1ff) == 0) { /* T1 16Hz */
if (t1)
t1--;
else { /* 1s has elapsed */
t1 = 0xf;
if (ioram[0x2e]&4) { ioram[0x2e]|=8; SHUTDN = 0; }
if (ioram[0x2e]&2) { ioram[0x2e]|=8; if (!INTP) INTERRUPT("T1"); }
}
}
if (update_kbd<=0) { /* KBD_POLL 64Hz */
update_kbd = 128;
if (KDN_rising_edge) {
KDN_rising_edge = 0;
SHUTDN = 0;
if (INTE&&(!INTP)) INTERRUPT("KP");
}
}
}
fclose(wire);
return;
}


15
SAVE.BAT Normal file
View file

@ -0,0 +1,15 @@
@echo off
if %1z == z goto err
ctty nul
call renlower *.*
ctty con
arj u EMU48 ram.1 readme rom *.html *.dat *.bat *.c *.h *.rc *.ico *.bmp *.mak makefile romdump dump2rom.c
arj t EMU48
echo Insert EMU48 diskette in %1:
pause
copy EMU48.arj %1: /v
chkdsk %1:
goto end
:err
echo SAVE drive
:end

BIN
dump2rom.exe Normal file

Binary file not shown.

BIN
dump2rom.obj Normal file

Binary file not shown.

BIN
emu48w32.exe Normal file

Binary file not shown.

123
pcpdebug.h Normal file
View file

@ -0,0 +1,123 @@
/* UCMS_VERSION_ID("@(#)pcpdebug.h 61EX:1 readonly 17/05/95 12:58(#)@") */
/*****************************************************************************
*
* $Workfile:: PCPDEBUG.H $
*
* $Logfile:: $
*
* Library:: CLASSLIB
*
* Makefile:: MAKEFILE
*
* $Date:: 5-7-1993 $
*
* $Revision:: 0.00 $
*
* $Author:: Klaas van Ditzhuyzen $
*
* Functions:: DEBUG_PRINTF
*
* Logging of debug strings under OS/2 PM. Uses DBLOG.H when debug macros
* wanted.
* INCLUDE in the application's .DEF file:
*
IMPORTS
DEBUG_PRINTF=PMDEBUG.PMDEBUG
*
*
* $Log:: $
*
*****************************************************************************/
#ifndef PCPDEBUG_H
#ifdef UDEBUG
/* Use Uniface debug macros from Leen Kuiper .... */
#undef DEBUG /* Set to ONE anyway ... */
#define DEBUG 1
#define DEBUG_PRINTF_FUNCDEF(x)
#define DEBUG_ON() (utraDbg('I'))
#define DEBUG_PRINTF utraTrace
#include "utra.h"
#define UCONSTANT
#else
#define UCONSTANT const
#endif
#ifdef __IBMC__
#define SYSCALL _Optlink
#else
#define SYSCALL
#endif
#ifndef DEBUG_PRINTF /* define it to prevent later redefinition */
#define DEBUG_PRINTF DEBUG_PRINTF
#endif
#ifdef __cplusplus
#define _CFUNC_ extern "C"
#else
#define _CFUNC_
#endif
#ifndef UDEBUG
_CFUNC_ int SYSCALL DEBUG_PRINTF(const char *, ...);
#endif
#define _D_PREFIX "@#`~$"
#define _D_PMDEBUG1 _D_PREFIX "PMMSG"
#define _D_PMDEBUG2 _D_PREFIX "ASSERT"
#define _D_PMDEBUG6 _D_PREFIX "MSGINF"
#define _D_PMDEBUG7 _D_PREFIX "BSEERR%d"
#define _D_PMDEBUG8 _D_PREFIX "PMERR%d"
#define _D_PMDEBUG9 _D_PREFIX "PMWIN0x%08lX"
#ifndef assert
#ifndef NDEBUG
#if DEBUG
#define assert( expr ) \
( ( expr ) ? ( void )0 : (void) DEBUG_PRINTF( _D_PMDEBUG2, #expr, __FILE__, __LINE__ ) )
#else /* do not save expression */
#define assert( expr ) \
( ( expr ) ? ( void )0 : (void) DEBUG_PRINTF( _D_PMDEBUG2, NULL , __FILE__, __LINE__ ) )
#endif /* DEBUG */
#else
#define assert( ignore ) ( ( void )0 )
#endif /* NDEBUG */
#endif /* assert */
/* These two lines can be commented out when */
#include "pcpdbg.h"
/* debug macros are not needed. */
#if DEBUG
EXTERN_C void DEBUG_SETPARAMETERS(const char * envstr, const char * logfile, void * winconsole, void * reserved) ;
static char _debug_tmpbuf[50];
#define DEBUG_GETPMMESSAGE(msg) ((char*)DEBUG_PRINTF( _D_PMDEBUG6 , msg, _debug_tmpbuf))
#define DEBUG_GETBSEERR(msg) ((char*)DEBUG_PRINTF( _D_PMDEBUG7 , msg, _debug_tmpbuf))
#define DEBUG_GETPMERR(msg) ((char*)DEBUG_PRINTF( _D_PMDEBUG8 , msg, _debug_tmpbuf))
#define DEBUG_LOGWINDATA(hwnd,text) ( (void)DEBUG_PRINTF( _D_PMDEBUG9 , hwnd, text))
#define DEBUG_LOGPMMSG(qmsg) if (DEBUG_ON()) DEBUG_PRINTF( _D_PMDEBUG1 , (void*)qmsg)
#else
#define DEBUG_SETPARAMETERS(a,b,c,d)
#define DEBUG_GETPMMESSAGE(msg)
#define DEBUG_GETBSEERR(msg)
#define DEBUG_GETPMERR(msg)
#define DEBUG_LOGWINDATA(hwnd,text)
#define DEBUG_LOGPMMSG(qmsg)
#endif
#endif /* PCPDEBUG_H */

BIN
ram Normal file

Binary file not shown.