commit c3ab4004adbd2d8c2e766456f3e1257ac1bdf195 Author: Gwenhael Le Moine Date: Tue Mar 19 22:11:59 2024 +0100 1996-02-01: Historic version 0.37 Signed-off-by: Gwenhael Le Moine diff --git a/BITMAP1.BMP b/BITMAP1.BMP new file mode 100644 index 0000000..6e8e840 Binary files /dev/null and b/BITMAP1.BMP differ diff --git a/DUMP.C b/DUMP.C new file mode 100644 index 0000000..1bf3112 --- /dev/null +++ b/DUMP.C @@ -0,0 +1,95 @@ +/* + * Copyright (C) 1995 Sebastien Carlier + */ + +#include +#include + +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; +} + \ No newline at end of file diff --git a/DUMP2ROM.C b/DUMP2ROM.C new file mode 100644 index 0000000..c5e154b --- /dev/null +++ b/DUMP2ROM.C @@ -0,0 +1,100 @@ +/* + * This file is part of Emu48, an emulator of the HP-48 Calculator. + * Copyright (C) 1995 Sebastien Carlier + * + * 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 +#include + +#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>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) + \ No newline at end of file diff --git a/EMU48.ICO b/EMU48.ICO new file mode 100644 index 0000000..63834ed Binary files /dev/null and b/EMU48.ICO differ diff --git a/EMU48.MAK b/EMU48.MAK new file mode 100644 index 0000000..c097e33 --- /dev/null +++ b/EMU48.MAK @@ -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 +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 +################################################################################ diff --git a/EMU48.RC b/EMU48.RC new file mode 100644 index 0000000..4a5c86a --- /dev/null +++ b/EMU48.RC @@ -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 + diff --git a/EMU48_ID.BMP b/EMU48_ID.BMP new file mode 100644 index 0000000..1a0def3 Binary files /dev/null and b/EMU48_ID.BMP differ diff --git a/FETCH.H b/FETCH.H new file mode 100644 index 0000000..f2a8136 --- /dev/null +++ b/FETCH.H @@ -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; + \ No newline at end of file diff --git a/HARDWARE.C b/HARDWARE.C new file mode 100644 index 0000000..a21031f --- /dev/null +++ b/HARDWARE.C @@ -0,0 +1,896 @@ +/* + * Copyright (C) 1995 Sebastien Carlier + */ + +#define NEW 1 +#define WIN32_LEAN_AND_MEAN +#include +#undef IN +#undef OUT +#include +#include +#include "emu48.h" +#include "resource.h" +#include +#include + +#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 (xKBD_RIGHT) break; + if (yKBD_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 (xKBD_RIGHT) break; + if (yKBD_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; +*/ +} diff --git a/HARDWARE.H b/HARDWARE.H new file mode 100644 index 0000000..c2641a9 --- /dev/null +++ b/HARDWARE.H @@ -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 diff --git a/INSTR.C b/INSTR.C new file mode 100644 index 0000000..cde8cde --- /dev/null +++ b/INSTR.C @@ -0,0 +1,516 @@ +/* + * Copyright (C) 1995 Sebastien Carlier + */ + +#include +#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>=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>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=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 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.start2)&&(d=display.start12)&&(d=display.start2)&&(d +#include + +#define BUFSIZE 256 +#define NEXTFIELD {s=p; while ((p +#include +#include +#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 +#include +#include +#include +#include +#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>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>4)&0xf); + } + else + for (i=0; i>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>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>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; +} + \ No newline at end of file diff --git a/MEMORY.C b/MEMORY.C new file mode 100644 index 0000000..f1b7dc0 --- /dev/null +++ b/MEMORY.C @@ -0,0 +1,728 @@ +/* + * Copyright (C) 1995 Sebastien Carlier + */ + +#include +#include +#include +#include +#include +#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>4)&0xf); + } + else + for (i=0; i>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>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>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>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; +} + \ No newline at end of file diff --git a/OPCODES.H b/OPCODES.H new file mode 100644 index 0000000..96b5401 --- /dev/null +++ b/OPCODES.H @@ -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 */ + \ No newline at end of file diff --git a/PCPDBG.H b/PCPDBG.H new file mode 100644 index 0000000..cdddbbb --- /dev/null +++ b/PCPDBG.H @@ -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[] = ""; +#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 . + */ + +#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 +#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 diff --git a/PIX4.BMP b/PIX4.BMP new file mode 100644 index 0000000..a0e9333 Binary files /dev/null and b/PIX4.BMP differ diff --git a/README b/README new file mode 100644 index 0000000..5834337 --- /dev/null +++ b/README @@ -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 diff --git a/RESOURCE.H b/RESOURCE.H new file mode 100644 index 0000000..e685c44 --- /dev/null +++ b/RESOURCE.H @@ -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 diff --git a/ROM b/ROM new file mode 100644 index 0000000..74ade58 Binary files /dev/null and b/ROM differ diff --git a/ROMDUMP b/ROMDUMP new file mode 100644 index 0000000..a8f101e Binary files /dev/null and b/ROMDUMP differ diff --git a/RUNME.BAT b/RUNME.BAT new file mode 100644 index 0000000..f1e6e68 --- /dev/null +++ b/RUNME.BAT @@ -0,0 +1,3 @@ +@echo off +echo Building opcodes.h +..\bin\lst2c.com < ..\src\opcodes.lst > ..\src\opcodes.h diff --git a/SATURN.C b/SATURN.C new file mode 100644 index 0000000..29d6e96 --- /dev/null +++ b/SATURN.C @@ -0,0 +1,130 @@ +/* + * emu48/src/emulate.c + * + * Copyright (C) 1995 Sebastien Carlier + */ + +#include +#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; +} + + \ No newline at end of file diff --git a/SAVE.BAT b/SAVE.BAT new file mode 100644 index 0000000..2aeff1f --- /dev/null +++ b/SAVE.BAT @@ -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 diff --git a/dump2rom.exe b/dump2rom.exe new file mode 100644 index 0000000..99164f1 Binary files /dev/null and b/dump2rom.exe differ diff --git a/dump2rom.obj b/dump2rom.obj new file mode 100644 index 0000000..2050673 Binary files /dev/null and b/dump2rom.obj differ diff --git a/emu48w32.exe b/emu48w32.exe new file mode 100644 index 0000000..c8fbcd4 Binary files /dev/null and b/emu48w32.exe differ diff --git a/pcpdebug.h b/pcpdebug.h new file mode 100644 index 0000000..645a8f7 --- /dev/null +++ b/pcpdebug.h @@ -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 */ diff --git a/ram b/ram new file mode 100644 index 0000000..21ef633 Binary files /dev/null and b/ram differ