Add emulators: 'DosBox' (binary only), 'e80', 'fceu' (binary only).
git-svn-id: svn://kolibrios.org@1814 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
95261888a5
commit
b2ba8d7766
Binary file not shown.
|
@ -0,0 +1,233 @@
|
|||
# This is the configurationfile for DOSBox 0.73.
|
||||
# Lines starting with a # are commentlines.
|
||||
# They are used to (briefly) document the effect of each option.
|
||||
|
||||
[sdl]
|
||||
# fullscreen: Start dosbox directly in fullscreen.
|
||||
# fulldouble: Use double buffering in fullscreen.
|
||||
# fullresolution: What resolution to use for fullscreen: original or fixed size (e.g. 1024x768).
|
||||
# windowresolution: Scale the window to this size IF the output device supports hardware scaling.
|
||||
# output: What video system to use for output.
|
||||
# Possible values: surface, overlay, opengl, openglnb, ddraw.
|
||||
# autolock: Mouse will automatically lock, if you click on the screen.
|
||||
# sensitivity: Mouse sensitivity.
|
||||
# waitonerror: Wait before closing the console if dosbox has an error.
|
||||
# priority: Priority levels for dosbox. Second entry behind the comma is for when dosbox is not focused/minimized. (pause is only valid for the second entry)
|
||||
# Possible values: lowest, lower, normal, higher, highest, pause.
|
||||
# mapperfile: File used to load/save the key/event mappings from.
|
||||
# usescancodes: Avoid usage of symkeys, might not work on all operating systems.
|
||||
|
||||
fullscreen=false
|
||||
fulldouble=false
|
||||
fullresolution=original
|
||||
windowresolution=original
|
||||
output=surface
|
||||
autolock=true
|
||||
sensitivity=100
|
||||
waitonerror=true
|
||||
priority=higher,normal
|
||||
mapperfile=mapper.txt
|
||||
usescancodes=true
|
||||
|
||||
[dosbox]
|
||||
# language: Select another language file.
|
||||
# machine: The type of machine tries to emulate.
|
||||
# Possible values: hercules, cga, tandy, pcjr, ega, vgaonly, svga_s3, svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe.
|
||||
# captures: Directory where things like wave, midi, screenshot get captured.
|
||||
# memsize: Amount of memory DOSBox has in megabytes.
|
||||
# This value is best left at its default to avoid problems with some games,
|
||||
# though few games might require a higher value.
|
||||
# There is generally no speed advantage when raising this value.
|
||||
|
||||
language=
|
||||
machine=svga_s3
|
||||
captures=capture
|
||||
memsize=16
|
||||
|
||||
[render]
|
||||
# frameskip: How many frames DOSBox skips before drawing one.
|
||||
# aspect: Do aspect correction, if your output method doesn't support scaling this can slow things down!.
|
||||
# scaler: Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,the scaler will be used even if the result might not be desired.
|
||||
# Possible values: none, normal2x, normal3x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x.
|
||||
|
||||
frameskip=0
|
||||
aspect=false
|
||||
scaler=normal2x
|
||||
|
||||
[cpu]
|
||||
# core: CPU Core used in emulation. auto will switch to dynamic if available and appropriate.
|
||||
# Possible values: auto, dynamic, normal, simple.
|
||||
# cputype: CPU Type used in emulation. auto is the fastest choice.
|
||||
# Possible values: auto, 386, 386_slow, 486_slow, pentium_slow, 386_prefetch.
|
||||
# cycles: Amount of instructions DOSBox tries to emulate each millisecond. Setting this value too high results in sound dropouts and lags. Cycles can be set in 3 ways:
|
||||
# 'auto' tries to guess what a game needs.
|
||||
# It usually works, but can fail for certain games.
|
||||
# 'fixed #number' will set a fixed amount of cycles. This is what you usually need if 'auto' fails.
|
||||
# (Example: fixed 4000)
|
||||
# 'max' will allocate as much cycles as your computer is able to handle
|
||||
#
|
||||
# Possible values: auto, fixed, max.
|
||||
# cycleup: Amount of cycles to increase/decrease with keycombo.
|
||||
# cycledown: Setting it lower than 100 will be a percentage.
|
||||
|
||||
core=auto
|
||||
cputype=auto
|
||||
cycles=auto
|
||||
cycleup=500
|
||||
cycledown=20
|
||||
|
||||
[mixer]
|
||||
# nosound: Enable silent mode, sound is still emulated though.
|
||||
# rate: Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality.
|
||||
# Possible values: 22050, 44100, 48000, 32000, 16000, 11025, 8000, 49716.
|
||||
# blocksize: Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged.
|
||||
# Possible values: 2048, 4096, 8192, 1024, 512, 256.
|
||||
# prebuffer: How many milliseconds of data to keep on top of the blocksize.
|
||||
|
||||
nosound=false
|
||||
rate=22050
|
||||
blocksize=2048
|
||||
prebuffer=10
|
||||
|
||||
[midi]
|
||||
# mpu401: Type of MPU-401 to emulate.
|
||||
# Possible values: intelligent, uart, none.
|
||||
# mididevice: Device that will receive the MIDI data from MPU-401.
|
||||
# Possible values: default, win32, alsa, oss, coreaudio, coremidi, none.
|
||||
# midiconfig: Special configuration options for the device driver. This is usually the id of the device you want to use. See README for details.
|
||||
|
||||
mpu401=intelligent
|
||||
mididevice=default
|
||||
midiconfig=
|
||||
|
||||
[sblaster]
|
||||
# sbtype: Type of sblaster to emulate.
|
||||
# Possible values: sb1, sb2, sbpro1, sbpro2, sb16, none.
|
||||
# sbbase: The IO address of the soundblaster.
|
||||
# Possible values: 220, 240, 260, 280, 2a0, 2c0, 2e0, 300.
|
||||
# irq: The IRQ number of the soundblaster.
|
||||
# Possible values: 7, 5, 3, 9, 10, 11, 12.
|
||||
# dma: The DMA number of the soundblaster.
|
||||
# Possible values: 1, 5, 0, 3, 6, 7.
|
||||
# hdma: The High DMA number of the soundblaster.
|
||||
# Possible values: 1, 5, 0, 3, 6, 7.
|
||||
# sbmixer: Allow the soundblaster mixer to modify the DOSBox mixer.
|
||||
# oplmode: Type of OPL emulation. On 'auto' the mode is determined by sblaster type. All OPL modes are Adlib-compatible, except for 'cms'.
|
||||
# Possible values: auto, cms, opl2, dualopl2, opl3, none.
|
||||
# oplemu: Provider for the OPL emulation. compat or old might provide better quality (see oplrate as well).
|
||||
# Possible values: default, compat, fast, old.
|
||||
# oplrate: Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly).
|
||||
# Possible values: 22050, 49716, 44100, 48000, 32000, 16000, 11025, 8000.
|
||||
|
||||
sbtype=sb16
|
||||
sbbase=220
|
||||
irq=7
|
||||
dma=1
|
||||
hdma=5
|
||||
sbmixer=true
|
||||
oplmode=auto
|
||||
oplemu=default
|
||||
oplrate=22050
|
||||
|
||||
[gus]
|
||||
# gus: Enable the Gravis Ultrasound emulation.
|
||||
# gusrate: Sample rate of Ultrasound emulation.
|
||||
# Possible values: 22050, 44100, 48000, 32000, 16000, 11025, 8000, 49716.
|
||||
# gusbase: The IO base address of the Gravis Ultrasound.
|
||||
# Possible values: 240, 220, 260, 280, 2a0, 2c0, 2e0, 300.
|
||||
# gusirq: The IRQ number of the Gravis Ultrasound.
|
||||
# Possible values: 5, 3, 7, 9, 10, 11, 12.
|
||||
# gusdma: The DMA channel of the Gravis Ultrasound.
|
||||
# Possible values: 3, 0, 1, 5, 6, 7.
|
||||
# ultradir: Path to Ultrasound directory. In this directory
|
||||
# there should be a MIDI directory that contains
|
||||
# the patch files for GUS playback. Patch sets used
|
||||
# with Timidity should work fine.
|
||||
|
||||
gus=false
|
||||
gusrate=22050
|
||||
gusbase=240
|
||||
gusirq=5
|
||||
gusdma=3
|
||||
ultradir=C:\ULTRASND
|
||||
|
||||
[speaker]
|
||||
# pcspeaker: Enable PC-Speaker emulation.
|
||||
# pcrate: Sample rate of the PC-Speaker sound generation.
|
||||
# Possible values: 22050, 44100, 48000, 32000, 16000, 11025, 8000, 49716.
|
||||
# tandy: Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'.
|
||||
# Possible values: auto, on, off.
|
||||
# tandyrate: Sample rate of the Tandy 3-Voice generation.
|
||||
# Possible values: 22050, 44100, 48000, 32000, 16000, 11025, 8000, 49716.
|
||||
# disney: Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible).
|
||||
|
||||
pcspeaker=true
|
||||
pcrate=22050
|
||||
tandy=auto
|
||||
tandyrate=22050
|
||||
disney=true
|
||||
|
||||
[joystick]
|
||||
# joysticktype: Type of joystick to emulate: auto (default), none,
|
||||
# 2axis (supports two joysticks),
|
||||
# 4axis (supports one joystick, first joystick used),
|
||||
# 4axis_2 (supports one joystick, second joystick used),
|
||||
# fcs (Thrustmaster), ch (CH Flightstick).
|
||||
# none disables joystick emulation.
|
||||
# auto chooses emulation depending on real joystick(s).
|
||||
# Possible values: auto, 2axis, 4axis, 4axis_2, fcs, ch, none.
|
||||
# timed: enable timed intervals for axis. (false is old style behaviour).
|
||||
# autofire: continuously fires as long as you keep the button pressed.
|
||||
# swap34: swap the 3rd and the 4th axis. can be useful for certain joysticks.
|
||||
# buttonwrap: enable button wrapping at the number of emulated buttons.
|
||||
|
||||
joysticktype=auto
|
||||
timed=true
|
||||
autofire=false
|
||||
swap34=false
|
||||
buttonwrap=true
|
||||
|
||||
[serial]
|
||||
# serial1: set type of device connected to com port.
|
||||
# Can be disabled, dummy, modem, nullmodem, directserial.
|
||||
# Additional parameters must be in the same line in the form of
|
||||
# parameter:value. Parameter for all types is irq.
|
||||
# for directserial: realport (required), rxdelay (optional).
|
||||
# (realport:COM1 realport:ttyS0).
|
||||
# for modem: listenport (optional).
|
||||
# for nullmodem: server, rxdelay, txdelay, telnet, usedtr,
|
||||
# transparent, port, inhsocket (all optional).
|
||||
# Example: serial1=modem listenport:5000
|
||||
# Possible values: dummy, disabled, modem, nullmodem, directserial.
|
||||
# serial2: see serial1
|
||||
# Possible values: dummy, disabled, modem, nullmodem, directserial.
|
||||
# serial3: see serial1
|
||||
# Possible values: dummy, disabled, modem, nullmodem, directserial.
|
||||
# serial4: see serial1
|
||||
# Possible values: dummy, disabled, modem, nullmodem, directserial.
|
||||
|
||||
serial1=dummy
|
||||
serial2=dummy
|
||||
serial3=disabled
|
||||
serial4=disabled
|
||||
|
||||
[dos]
|
||||
# xms: Enable XMS support.
|
||||
# ems: Enable EMS support.
|
||||
# umb: Enable UMB support.
|
||||
# keyboardlayout: Language code of the keyboard layout (or none).
|
||||
|
||||
xms=true
|
||||
ems=true
|
||||
umb=true
|
||||
keyboardlayout=auto
|
||||
|
||||
[ipx]
|
||||
# ipx: Enable ipx over UDP/IP emulation.
|
||||
|
||||
ipx=false
|
||||
|
||||
[autoexec]
|
||||
# Lines in this section will be run at startup.
|
||||
keyb ru 866
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,39 @@
|
|||
|
||||
format MS COFF
|
||||
|
||||
public Start
|
||||
public _hStack
|
||||
public _KOL_PATH
|
||||
public _KOL_PARAM
|
||||
|
||||
extrn Memory
|
||||
extrn hEnd
|
||||
|
||||
extrn _kol_main
|
||||
|
||||
section ".text" code
|
||||
db "MENUET01"
|
||||
dd 1, Start, hEnd, Memory, _hStack, _KOL_PARAM, _KOL_PATH
|
||||
|
||||
Start:
|
||||
|
||||
; èíèöèàëèçàöèÿ êó÷è
|
||||
mov eax, 68
|
||||
mov ebx, 11
|
||||
int 0x40
|
||||
|
||||
; âûçîâ ãëàâíîé ïðîöåäóðû
|
||||
mov eax, _kol_main
|
||||
call eax
|
||||
|
||||
; çàâåðøåíèå ðàáîòû ïðîãðàììû
|
||||
mov eax, -1
|
||||
int 0x40
|
||||
|
||||
section ".bss"
|
||||
|
||||
_KOL_PARAM rb 256
|
||||
_KOL_PATH rb 256
|
||||
|
||||
rb 16*1024
|
||||
_hStack:
|
|
@ -0,0 +1,3 @@
|
|||
del e80.kex
|
||||
del backup.sna
|
||||
del *.o
|
|
@ -0,0 +1,11 @@
|
|||
del *.o
|
||||
fasm asm_code.asm start.o
|
||||
gcc -c z80/z80.c
|
||||
gcc -c system/kolibri.c
|
||||
gcc -c system/stdlib.c
|
||||
gcc -c system/string.c
|
||||
gcc -c e80.c
|
||||
ld -nostdlib -T kolibri.ld -o e80.kex start.o kolibri.o stdlib.o string.o z80.o e80.o
|
||||
objcopy e80.kex -O binary
|
||||
kpack e80.kex
|
||||
pause
|
|
@ -0,0 +1,534 @@
|
|||
|
||||
#include "system/kolibri.h"
|
||||
#include "system/stdlib.h"
|
||||
#include "system/string.h"
|
||||
#include "z80/z80.h"
|
||||
#include "48.h"
|
||||
|
||||
#include "system/msgbox.c"
|
||||
|
||||
///=============================
|
||||
|
||||
#define TYPE_NO 0
|
||||
#define TYPE_SNA 1
|
||||
#define TYPE_Z80 2
|
||||
|
||||
#define SCREEN_LEN 3*3*256*192*3
|
||||
|
||||
char WND_CAPTION[] = {"e80 v0.5.1"};
|
||||
|
||||
extern char KOL_PARAM[256];
|
||||
extern char KOL_PATH[256];
|
||||
|
||||
char szBackup[256];
|
||||
char szScreen[256];
|
||||
|
||||
int fila[5][5];
|
||||
int main_tecla, hay_tecla;
|
||||
int SSCS = 0;
|
||||
|
||||
int debug=0, scanl=0;
|
||||
int frame_counter;
|
||||
int target_cycle;
|
||||
Z80Regs spectrumZ80;
|
||||
|
||||
char *screen;
|
||||
unsigned screen_w, screen_h;
|
||||
#define screen_a_w 512
|
||||
#define screen_a_h 384
|
||||
int flash = 0;
|
||||
unsigned time = 0;
|
||||
|
||||
///=============================
|
||||
|
||||
#include "keyboard.c"
|
||||
|
||||
///=============================
|
||||
|
||||
int get_ext(char *filename)
|
||||
{
|
||||
|
||||
return TYPE_SNA;
|
||||
}
|
||||
|
||||
///=============================
|
||||
|
||||
void memory_print(Z80Regs *regs, char *filename)
|
||||
{
|
||||
kol_struct70 file;
|
||||
|
||||
file.p00 = 2;
|
||||
file.p04 = 0;
|
||||
file.p08 = 0;
|
||||
file.p12 = 64*1024;
|
||||
file.p16 = (unsigned)(regs->RAM);
|
||||
file.p20 = 0;
|
||||
file.p21 = filename;
|
||||
|
||||
kol_file_70(&file);
|
||||
}
|
||||
|
||||
|
||||
///=============================
|
||||
|
||||
void all_print(Z80Regs *regs, char *filename)
|
||||
{
|
||||
kol_struct70 file;
|
||||
|
||||
file.p00 = 2;
|
||||
file.p04 = 0;
|
||||
file.p08 = 0;
|
||||
file.p12 = sizeof (Z80Regs);
|
||||
file.p16 = (unsigned)regs;
|
||||
file.p20 = 0;
|
||||
file.p21 = filename;
|
||||
|
||||
kol_file_70(&file);
|
||||
}
|
||||
|
||||
///=============================
|
||||
|
||||
void screen_print(Z80Regs *regs)
|
||||
{
|
||||
|
||||
kol_struct70 file;
|
||||
|
||||
char palette[]=
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xB0, 0x00, 0x00, 0xB0, 0x00, 0x00,
|
||||
0x00, 0x00, 0xB0, 0x00, 0x00, 0xB0,
|
||||
0xB0, 0x00, 0xB0, 0xB0, 0x00, 0xB0,
|
||||
0x00, 0xB0, 0x00, 0x00, 0xB0, 0x00,
|
||||
0xB0, 0xB0, 0x00, 0xB0, 0xB0, 0x00,
|
||||
0x00, 0xB0, 0xB0, 0x00, 0xB0, 0xB0,
|
||||
0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
char *scr;
|
||||
char *atr;
|
||||
|
||||
char a, c, s;
|
||||
int i, j, k, l, m;
|
||||
unsigned bri;
|
||||
char *color;
|
||||
char *addr;
|
||||
int n = 0;
|
||||
int z = 0;
|
||||
int x, y;
|
||||
|
||||
scr = malloc(6144);
|
||||
atr = malloc(768);
|
||||
|
||||
memcpy(scr, regs->RAM + 0x4000 , 6144);
|
||||
memcpy(atr, regs->RAM + 0x5800 , 768);
|
||||
|
||||
for (j = 0; j < 3 ; j++)
|
||||
for (i = 0; i < 8; i++)
|
||||
for (k = 0; k < 8; k++)
|
||||
for (l = 0; l < 32; l++)
|
||||
{
|
||||
c = scr[j*2048 + k*256 + i*32 + l];
|
||||
for (m = 0; m < 8; m++)
|
||||
{
|
||||
s = (c & 128) >> 7;
|
||||
a = atr[j*256 + i*32 + l];
|
||||
|
||||
if ( (a & 64) == 64 )
|
||||
bri = 8;
|
||||
else
|
||||
bri = 0;
|
||||
|
||||
if ( 0 == s )
|
||||
{
|
||||
if (!(flash && (128 == (a&128))))
|
||||
color = &palette[6*(bri+((a>>3)&7))];
|
||||
else
|
||||
color = &palette[6*(bri+(a&7))];
|
||||
|
||||
addr = screen + 2*screen_a_w*3*z + 2*3*n;
|
||||
|
||||
for (y = 0; y < 2; y++)
|
||||
memcpy( addr + y*screen_a_w*3,
|
||||
color, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(flash && (128 == (a&128))))
|
||||
color = &palette[6*(bri+(a&7))];
|
||||
else
|
||||
color = &palette[6*(bri+((a>>3)&7))];
|
||||
|
||||
addr = screen + 2*screen_a_w*3*z + 2*3*n;
|
||||
|
||||
for (y = 0; y < 2; y++)
|
||||
memcpy( addr + y*screen_a_w*3,
|
||||
color, 6);
|
||||
}
|
||||
|
||||
n++;
|
||||
if (256 == n)
|
||||
{
|
||||
n = 0;
|
||||
z++;
|
||||
}
|
||||
|
||||
c <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 33 < (kol_time_tick() - time))
|
||||
{
|
||||
if (0 == flash)
|
||||
flash = 1;
|
||||
else
|
||||
flash = 0;
|
||||
time = kol_time_tick();
|
||||
}
|
||||
|
||||
free(scr);
|
||||
free(atr);
|
||||
|
||||
}
|
||||
|
||||
///=============================
|
||||
|
||||
void memory_load_z80(Z80Regs *regs, char *filename)
|
||||
{
|
||||
char header[30];
|
||||
kol_struct70 file;
|
||||
|
||||
file.p00 = 0;
|
||||
file.p04 = 0;
|
||||
file.p08 = 0;
|
||||
file.p12 = 30;
|
||||
file.p16 = (unsigned) header;
|
||||
file.p20 = 0;
|
||||
file.p21 = filename;
|
||||
}
|
||||
|
||||
///=============================
|
||||
|
||||
void memory_load_sna(Z80Regs *regs, char *filename)
|
||||
{
|
||||
char buffer[27];
|
||||
kol_struct70 file;
|
||||
|
||||
file.p00 = 0;
|
||||
file.p04 = 0;
|
||||
file.p08 = 0;
|
||||
file.p12 = 27;
|
||||
file.p16 = (unsigned) buffer;
|
||||
file.p20 = 0;
|
||||
file.p21 = filename;
|
||||
|
||||
kol_file_70(&file);
|
||||
|
||||
regs->I = buffer[ 0];
|
||||
regs->HLs.B.l = buffer[ 1];
|
||||
regs->HLs.B.h = buffer[ 2];
|
||||
regs->DEs.B.l = buffer[ 3];
|
||||
regs->DEs.B.h = buffer[ 4];
|
||||
regs->BCs.B.l = buffer[ 5];
|
||||
regs->BCs.B.h = buffer[ 6];
|
||||
regs->AFs.B.l = buffer[ 7];
|
||||
regs->AFs.B.h = buffer[ 8];
|
||||
regs->HL.B.l = buffer[ 9];
|
||||
regs->HL.B.h = buffer[10];
|
||||
regs->DE.B.l = buffer[11];
|
||||
regs->DE.B.h = buffer[12];
|
||||
regs->BC.B.l = buffer[13];
|
||||
regs->BC.B.h = buffer[14];
|
||||
regs->IY.B.l = buffer[15];
|
||||
regs->IY.B.h = buffer[16];
|
||||
regs->IX.B.l = buffer[17];
|
||||
regs->IX.B.h = buffer[18];
|
||||
regs->IFF1 = regs->IFF2 = (buffer[19]&0x04) >>2;
|
||||
regs->R.W = buffer[20];
|
||||
regs->AF.B.l = buffer[21];
|
||||
regs->AF.B.h = buffer[22];
|
||||
regs->SP.B.l =buffer[23];
|
||||
regs->SP.B.h =buffer[24];
|
||||
regs->IM = buffer[25];
|
||||
regs->BorderColor = buffer[26];
|
||||
|
||||
file.p00 = 0;
|
||||
file.p04 = 27;
|
||||
file.p08 = 0;
|
||||
file.p12 = 0x4000*3;
|
||||
file.p16 = (unsigned) regs->RAM+16384;
|
||||
file.p20 = 0;
|
||||
file.p21 = filename;
|
||||
|
||||
kol_file_70(&file);
|
||||
|
||||
regs->PC.B.l = Z80MemRead(regs->SP.W, regs);
|
||||
regs->SP.W++;
|
||||
regs->PC.B.h = Z80MemRead(regs->SP.W, regs);
|
||||
regs->SP.W++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
///=============================
|
||||
|
||||
void memory_save_sna(Z80Regs *regs, char *filename)
|
||||
{
|
||||
char buffer[27];
|
||||
unsigned char sptmpl, sptmph;
|
||||
kol_struct70 file;
|
||||
|
||||
buffer[ 0] = regs->I;
|
||||
buffer[ 1] = regs->HLs.B.l;
|
||||
buffer[ 2] = regs->HLs.B.h;
|
||||
buffer[ 3] = regs->DEs.B.l;
|
||||
buffer[ 4] = regs->DEs.B.h;
|
||||
buffer[ 5] = regs->BCs.B.l;
|
||||
buffer[ 6] = regs->BCs.B.h;
|
||||
buffer[ 7] = regs->AFs.B.l;
|
||||
buffer[ 8] = regs->AFs.B.h;
|
||||
buffer[ 9] = regs->HL.B.l;
|
||||
buffer[10] = regs->HL.B.h;
|
||||
buffer[11] = regs->DE.B.l;
|
||||
buffer[12] = regs->DE.B.h;
|
||||
buffer[13] = regs->BC.B.l;
|
||||
buffer[14] = regs->BC.B.h;
|
||||
buffer[15] = regs->IY.B.l;
|
||||
buffer[16] = regs->IY.B.h;
|
||||
buffer[17] = regs->IX.B.l;
|
||||
buffer[18] = regs->IX.B.h;
|
||||
buffer[19] = regs->IFF1 << 2;
|
||||
buffer[20] = regs->R.W & 0xFF;
|
||||
buffer[21] = regs->AF.B.l;
|
||||
buffer[22] = regs->AF.B.h;
|
||||
|
||||
sptmpl = Z80MemRead( regs->SP.W-1, regs );
|
||||
sptmph = Z80MemRead( regs->SP.W-2, regs );
|
||||
|
||||
Z80MemWrite( --(regs->SP.W), regs->PC.B.h, regs);
|
||||
Z80MemWrite( --(regs->SP.W), regs->PC.B.l, regs);
|
||||
|
||||
buffer[23] = regs->SP.B.l;
|
||||
buffer[24] = regs->SP.B.h;
|
||||
buffer[25] = regs->IM;
|
||||
buffer[26] = regs->BorderColor;
|
||||
|
||||
file.p00 = 2;
|
||||
file.p04 = 0;
|
||||
file.p08 = 0;
|
||||
file.p12 = 27;
|
||||
file.p16 = (unsigned) buffer;
|
||||
file.p20 = 0;
|
||||
file.p21 = filename;
|
||||
|
||||
kol_file_70(&file);
|
||||
|
||||
file.p00 = 3;
|
||||
file.p04 = 27;
|
||||
file.p08 = 0;
|
||||
file.p12 = 0x4000*3;
|
||||
file.p16 = (unsigned) regs->RAM+16384;
|
||||
file.p20 = 0;
|
||||
file.p21 = filename;
|
||||
|
||||
kol_file_70(&file);
|
||||
|
||||
regs->SP.W += 2;
|
||||
Z80MemWrite( regs->SP.W-1, sptmpl, regs );
|
||||
Z80MemWrite( regs->SP.W-2, sptmph, regs );
|
||||
|
||||
}
|
||||
|
||||
|
||||
///=============================
|
||||
|
||||
void memory_save_scr(Z80Regs *regs, char *filename)
|
||||
{
|
||||
kol_struct70 file;
|
||||
|
||||
|
||||
file.p00 = 2;
|
||||
file.p04 = 0x4000;
|
||||
file.p08 = 0;
|
||||
file.p12 = 6912;
|
||||
file.p16 = (unsigned) regs->RAM+16384;
|
||||
file.p20 = 0;
|
||||
file.p21 = filename;
|
||||
|
||||
kol_file_70(&file);
|
||||
|
||||
}
|
||||
|
||||
|
||||
///=============================
|
||||
|
||||
void wnd_draw()
|
||||
{
|
||||
kol_paint_start();
|
||||
kol_wnd_define( (screen_w-540)/2, (screen_h-440)/2, 540, 440, 0x34b0b0b0);
|
||||
kol_wnd_caption(WND_CAPTION);
|
||||
screen_print(&spectrumZ80);
|
||||
kol_paint_image((540 - screen_a_w)/2-5,
|
||||
(440 - screen_a_h-kol_skin_height())/2,
|
||||
screen_a_w, screen_a_h, screen);
|
||||
kol_paint_end();
|
||||
}
|
||||
|
||||
///=============================
|
||||
|
||||
void kol_main()
|
||||
{
|
||||
|
||||
unsigned event;
|
||||
unsigned key;
|
||||
|
||||
for (event = strlen(KOL_PATH); event > 0; --event)
|
||||
if ( '/' == KOL_PATH[event] )
|
||||
{
|
||||
KOL_PATH[event+1]=0;
|
||||
break;
|
||||
}
|
||||
|
||||
strcpy(szBackup, KOL_PATH);
|
||||
strcpy(szScreen, KOL_PATH);
|
||||
strcat(szBackup, "backup.sna");
|
||||
strcat(szScreen, "screen.scr");
|
||||
|
||||
kol_screen_get_size(&screen_w, &screen_h);
|
||||
|
||||
screen = malloc(SCREEN_LEN);
|
||||
spectrumZ80.RAM = (char*) malloc(64*1024);
|
||||
memcpy(spectrumZ80.RAM, BIOS48, 16*1024);
|
||||
|
||||
Z80Reset( &spectrumZ80, 69888 );
|
||||
Z80FlagTables();
|
||||
|
||||
fila[1][1] = fila[1][2] = fila[2][2] = fila[3][2] = fila[4][2] =
|
||||
fila[4][1] = fila[3][1] = fila[2][1] = 0xFF;
|
||||
|
||||
debug = 0;
|
||||
|
||||
if (KOL_PARAM != NULL)
|
||||
{
|
||||
int type = get_ext(KOL_PARAM);
|
||||
|
||||
if (TYPE_SNA == type)
|
||||
memory_load_sna(&spectrumZ80, KOL_PARAM);
|
||||
}
|
||||
|
||||
hay_tecla = main_tecla = 0;
|
||||
//keyboard_process(0);
|
||||
|
||||
kol_key_mode_set(1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
||||
// event = kol_event_check();
|
||||
event = kol_event_wait_time(1);
|
||||
|
||||
switch (event)
|
||||
{
|
||||
|
||||
case 1:
|
||||
wnd_draw();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
key = (kol_key_get()>>8)&0xff;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case 60: // F2
|
||||
if ( IDOK == MessageBox("Save snapshot?",
|
||||
WND_CAPTION, MB_OKCANCEL) )
|
||||
memory_save_sna(&spectrumZ80,
|
||||
szBackup);
|
||||
break;
|
||||
|
||||
case 61: // F3
|
||||
if ( IDOK == MessageBox("Load snapshot?",
|
||||
WND_CAPTION, MB_OKCANCEL) )
|
||||
memory_load_sna(&spectrumZ80,
|
||||
szBackup);
|
||||
break;
|
||||
|
||||
case 62: // F4
|
||||
if ( IDOK == MessageBox("Save screenshot?",
|
||||
WND_CAPTION, MB_OKCANCEL) )
|
||||
memory_save_scr(&spectrumZ80,
|
||||
szScreen);
|
||||
break;
|
||||
|
||||
case 88: // F12 Reset
|
||||
if ( IDOK == MessageBox("Reset?",
|
||||
WND_CAPTION, MB_OKCANCEL) )
|
||||
{
|
||||
Z80Reset( &spectrumZ80, 69888 );
|
||||
Z80FlagTables();
|
||||
fila[1][1] = fila[1][2] =
|
||||
fila[2][2] = fila[3][2] =
|
||||
fila[4][2] = fila[4][1] =
|
||||
fila[3][1] = fila[2][1] = 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
keyboard_process(key);
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if ( 1 == (kol_btn_get() & 0xff00)>>8 )
|
||||
{
|
||||
free(screen);
|
||||
free(spectrumZ80.RAM);
|
||||
kol_exit();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (0 == debug)
|
||||
{
|
||||
|
||||
Z80Run( &spectrumZ80, 224*64 );
|
||||
for( scanl=0; scanl<192; scanl++ )
|
||||
Z80Run( &spectrumZ80, 224 );
|
||||
|
||||
Z80Run( &spectrumZ80, 224*56 );
|
||||
|
||||
if( target_cycle < 2 || frame_counter == 0 )
|
||||
{
|
||||
screen_print(&spectrumZ80);
|
||||
kol_screen_wait_rr();
|
||||
kol_paint_image((540 - screen_a_w)/2-5,
|
||||
(440 - screen_a_h-kol_skin_height())/2,
|
||||
screen_a_w, screen_a_h, screen);
|
||||
}
|
||||
|
||||
while( target_cycle == 0 )
|
||||
{
|
||||
target_cycle--;
|
||||
frame_counter++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///=============================
|
||||
|
Binary file not shown.
|
@ -0,0 +1,408 @@
|
|||
|
||||
///=============================
|
||||
|
||||
void keyboard_process(unsigned key)
|
||||
{
|
||||
|
||||
switch (key)
|
||||
{
|
||||
|
||||
case 42: // L-Shift Down
|
||||
case 54: // R-Shift Down
|
||||
fila[4][1] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 42+128: // L-Shift Up
|
||||
case 54+128: // R-Shift Up
|
||||
fila[4][1] |= 1;
|
||||
break;
|
||||
|
||||
case 29: // Ctrl Down
|
||||
fila[4][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 29+128: // Ctrl Up
|
||||
fila[4][2] |= 2;
|
||||
break;
|
||||
|
||||
case 56: // Alt Down
|
||||
fila[4][1] &= 0xFE;
|
||||
fila[4][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 56+128: // Alt Up
|
||||
fila[4][1] |= 1;
|
||||
fila[4][2] |= 2;
|
||||
break;
|
||||
|
||||
case 28: // Enter Down
|
||||
fila[3][2] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 28+128: // Enter Up
|
||||
fila[3][2] |= 1;
|
||||
break;
|
||||
|
||||
|
||||
case 2: // 1 Down
|
||||
fila[1][1] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 2+128: // 1 Up
|
||||
fila[1][1] |= 1;
|
||||
break;
|
||||
|
||||
case 3: // 2 Down
|
||||
fila[1][1] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 3+128: // 2 Up
|
||||
fila[1][1] |= 2;
|
||||
break;
|
||||
|
||||
case 4: // 3 Down
|
||||
fila[1][1] &= 0xFB;
|
||||
break;
|
||||
|
||||
case 4+128: // 3 Up
|
||||
fila[1][1] |= 4;
|
||||
break;
|
||||
|
||||
case 5: // 4 Down
|
||||
fila[1][1] &= 0xF7;
|
||||
break;
|
||||
|
||||
case 5+128: // 4 Up
|
||||
fila[1][1] |= 8;
|
||||
break;
|
||||
|
||||
case 6: // 5 Down
|
||||
fila[1][1] &= 0xEF;
|
||||
break;
|
||||
|
||||
case 6+128: // 5 Up
|
||||
fila[1][1] |= 16;
|
||||
break;
|
||||
|
||||
case 7: // 6 Down
|
||||
fila[1][2] &= 0xEF;
|
||||
break;
|
||||
|
||||
case 7+128: // 6 Up
|
||||
fila[1][2] |= 16;
|
||||
break;
|
||||
|
||||
case 8: // 7 Down
|
||||
fila[1][2] &= 0xF7;
|
||||
break;
|
||||
|
||||
case 8+128: // 7 Up
|
||||
fila[1][2] |= 8;
|
||||
break;
|
||||
|
||||
case 9: // 8 Down
|
||||
fila[1][2] &= 0xFB;
|
||||
break;
|
||||
|
||||
case 9+128: // 8 Up
|
||||
fila[1][2] |= 4;
|
||||
break;
|
||||
|
||||
case 10: // 9 Down
|
||||
fila[1][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 10+128: // 9 Up
|
||||
fila[1][2] |= 2;
|
||||
break;
|
||||
|
||||
case 11: // 0 Down
|
||||
fila[1][2] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 11+128: // 0 Up
|
||||
fila[1][2] |= 1;
|
||||
break;
|
||||
|
||||
case 16: // Q Down
|
||||
fila[2][1] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 16+128: // Q Up
|
||||
fila[2][1] |= 1;
|
||||
break;
|
||||
|
||||
case 17: // W Down
|
||||
fila[2][1] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 17+128: // W Up
|
||||
fila[2][1] |= 2;
|
||||
break;
|
||||
|
||||
case 18: // E Down
|
||||
fila[2][1] &= 0xFB;
|
||||
break;
|
||||
|
||||
case 18+128: // E Up
|
||||
fila[2][1] |= 4;
|
||||
break;
|
||||
|
||||
case 19: // R Down
|
||||
fila[2][1] &= 0xF7;
|
||||
break;
|
||||
|
||||
case 19+128: // R Up
|
||||
fila[2][1] |= 8;
|
||||
break;
|
||||
|
||||
case 20: // T Down
|
||||
fila[2][1] &= 0xEF;
|
||||
break;
|
||||
|
||||
case 20+128: // T Up
|
||||
fila[2][1] |= 16;
|
||||
break;
|
||||
|
||||
case 21: // Y Down
|
||||
fila[2][2] &= 0xEF;
|
||||
break;
|
||||
|
||||
case 21+128: // Y Up
|
||||
fila[2][2] |= 16;
|
||||
break;
|
||||
|
||||
case 22: // U Down
|
||||
fila[2][2] &= 0xF7;
|
||||
break;
|
||||
|
||||
case 22+128: // U Up
|
||||
fila[2][2] |= 8;
|
||||
break;
|
||||
|
||||
case 23: // I Down
|
||||
fila[2][2] &= 0xFB;
|
||||
break;
|
||||
|
||||
case 23+128: // I Up
|
||||
fila[2][2] |= 4;
|
||||
break;
|
||||
|
||||
case 24: // O Down
|
||||
fila[2][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 24+128: // O Up
|
||||
fila[2][2] |= 2;
|
||||
break;
|
||||
|
||||
case 25: // P Down
|
||||
fila[2][2] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 25+128: // P Up
|
||||
fila[2][2] |= 1;
|
||||
break;
|
||||
|
||||
case 30: // A Down
|
||||
fila[3][1] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 30+128: // A Up
|
||||
fila[3][1] |= 1;
|
||||
break;
|
||||
|
||||
case 31: // S Down
|
||||
fila[3][1] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 31+128: // S Up
|
||||
fila[3][1] |= 2;
|
||||
break;
|
||||
|
||||
case 32: // D Down
|
||||
fila[3][1] &= 0xFB;
|
||||
break;
|
||||
|
||||
case 32+128: // D Up
|
||||
fila[3][1] |= 4;
|
||||
break;
|
||||
|
||||
case 33: // F Down
|
||||
fila[3][1] &= 0xF7;
|
||||
break;
|
||||
|
||||
case 33+128: // F Up
|
||||
fila[3][1] |= 8;
|
||||
break;
|
||||
|
||||
case 34: // G Down
|
||||
fila[3][1] &= 0xEF;
|
||||
break;
|
||||
|
||||
case 34+128: // G Up
|
||||
fila[3][1] |= 16;
|
||||
break;
|
||||
|
||||
case 35: // H Down
|
||||
fila[3][2] &= 0xEF;
|
||||
break;
|
||||
|
||||
case 35+128: // H Up
|
||||
fila[3][2] |= 16;
|
||||
break;
|
||||
|
||||
case 36: // J Down
|
||||
fila[3][2] &= 0xF7;
|
||||
break;
|
||||
|
||||
case 36+128: // J Up
|
||||
fila[3][2] |= 8;
|
||||
break;
|
||||
|
||||
case 37: // K Down
|
||||
fila[3][2] &= 0xFB;
|
||||
break;
|
||||
|
||||
case 37+128: // K Up
|
||||
fila[3][2] |= 4;
|
||||
break;
|
||||
|
||||
case 38: // L Down
|
||||
fila[3][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 38+128: // L Up
|
||||
fila[3][2] |= 2;
|
||||
break;
|
||||
|
||||
case 44: // Z Down
|
||||
fila[4][1] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 44+128: // Z Up
|
||||
fila[4][1] |= 2;
|
||||
break;
|
||||
|
||||
case 45: // X Down
|
||||
fila[4][1] &= 0xFB;
|
||||
break;
|
||||
|
||||
case 45+128: // X Up
|
||||
fila[4][1] |= 4;
|
||||
break;
|
||||
|
||||
case 46: // C Down
|
||||
fila[4][1] &= 0xF7;
|
||||
break;
|
||||
|
||||
case 46+128: // C Up
|
||||
fila[4][1] |= 8;
|
||||
break;
|
||||
|
||||
case 47: // V Down
|
||||
fila[4][1] &= 0xEF;
|
||||
break;
|
||||
|
||||
case 47+128: // V Up
|
||||
fila[4][1] |= 16;
|
||||
break;
|
||||
|
||||
case 48: // B Down
|
||||
fila[4][2] &= 0xEF;
|
||||
break;
|
||||
|
||||
case 48+128: // B Up
|
||||
fila[4][2] |= 16;
|
||||
break;
|
||||
|
||||
case 49: // N Down
|
||||
fila[4][2] &= 0xF7;
|
||||
break;
|
||||
|
||||
case 49+128: // N Up
|
||||
fila[4][2] |= 8;
|
||||
break;
|
||||
|
||||
case 50: // M Down
|
||||
fila[4][2] &= 0xFB;
|
||||
break;
|
||||
|
||||
case 50+128: // M Up
|
||||
fila[4][2] |= 4;
|
||||
break;
|
||||
|
||||
case 57: // Space Down
|
||||
fila[4][2] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 57+128: // Space Up
|
||||
fila[4][2] |= 1;
|
||||
break;
|
||||
|
||||
case 14: // Backspace Down
|
||||
fila[1][2] &= 0xFE;
|
||||
fila[4][1] &= 0xFE;
|
||||
break;
|
||||
|
||||
case 14+128: // Backspace Up
|
||||
fila[1][2] |= 1;
|
||||
fila[4][1] |= 1;
|
||||
break;
|
||||
|
||||
case 12: // - Down
|
||||
fila[3][2] &= 0xF7;
|
||||
fila[4][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 12+128: // - Up
|
||||
fila[3][2] |= 8;
|
||||
fila[4][2] |= 2;
|
||||
break;
|
||||
|
||||
case 53: // / Down
|
||||
fila[4][1] &= 0xEF;
|
||||
fila[4][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 53+128: // / Up
|
||||
fila[4][1] |= 16;
|
||||
fila[4][2] |= 2;
|
||||
break;
|
||||
|
||||
case 52: // . Down
|
||||
fila[4][2] &= 0xFB;
|
||||
fila[4][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 52+128: // . Up
|
||||
fila[4][2] |= 4;
|
||||
fila[4][2] |= 2;
|
||||
break;
|
||||
|
||||
case 51: // , Down
|
||||
fila[4][2] &= 0xF7;
|
||||
fila[4][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 51+128: // , Up
|
||||
fila[4][2] |= 8;
|
||||
fila[4][2] |= 2;
|
||||
break;
|
||||
|
||||
case 13: // = Down
|
||||
fila[3][2] &= 0xFD;
|
||||
fila[4][2] &= 0xFD;
|
||||
break;
|
||||
|
||||
case 13+128: // = Up
|
||||
fila[3][2] |= 2;
|
||||
fila[4][2] |= 2;
|
||||
break;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
///=============================
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 7.7 KiB |
|
@ -0,0 +1,20 @@
|
|||
/*OUTPUT_FORMAT("binary")*/
|
||||
ENTRY(Start)
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x000000:
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
|
||||
.data : {
|
||||
*(.data)
|
||||
hEnd = . ;
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
}
|
||||
Memory = . ;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
============================================
|
||||
e80. Версия 0.5.1 15 февраля 2010 года
|
||||
============================================
|
||||
|
||||
Эмулятор ZX-Spectrum для ОС Колибри.
|
||||
|
||||
Для запуска программ нужно в KFAR
|
||||
сделать ассоциацию с файлами SNA.
|
||||
|
||||
Автор ядра эмулятора Z80:
|
||||
Santiago Romero Iglesias,
|
||||
sromero@escomposlinux.org
|
||||
|
||||
============================================
|
||||
|
||||
Внимание!
|
||||
|
||||
Эмулятор повторяет клавиатуру
|
||||
реального Спектрума.
|
||||
|
||||
Поэтому см. файл keyboard.png
|
||||
|
||||
Клавиша Shift соответствует CS (CAPS SHIFT)
|
||||
Клавиша Ctrl соответствует SS (SYMBOL SHIFT)
|
||||
Клавиша Alt соответствует переключению CS+SS
|
||||
|
||||
============================================
|
||||
|
||||
Другие клавиши:
|
||||
|
||||
F12 - перезагрузка эмулятора
|
||||
|
||||
F2 - сохранение в текущую папку
|
||||
файла backup.sna
|
||||
|
||||
F3 - загрузка из текущей папки
|
||||
файла backup.sna
|
||||
|
||||
F4 - сохранение в текущую папку
|
||||
файла screen.scr
|
||||
|
||||
============================================
|
||||
Александр Богомаз, albom85@yandex.ru
|
||||
http://albom06.boom.ru
|
|
@ -0,0 +1,412 @@
|
|||
|
||||
#include "kolibri.h"
|
||||
#include "string.h"
|
||||
|
||||
|
||||
extern char KOL_PATH[256];
|
||||
extern char KOL_PARAM[256];
|
||||
extern char KOL_DIR[256];
|
||||
|
||||
|
||||
void kol_exit()
|
||||
{
|
||||
asm ("int $0x40"::"a"(-1));
|
||||
}
|
||||
|
||||
|
||||
void kol_sleep(unsigned d)
|
||||
{
|
||||
asm ("int $0x40"::"a"(5), "b"(d));
|
||||
}
|
||||
|
||||
|
||||
void kol_wnd_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c)
|
||||
{
|
||||
asm ("nop"::"a"(0), "b"(x*65536+w), "c"(y*65536+h), "d"(c));
|
||||
asm ("movl $0xffffff, %esi \n int $0x40");
|
||||
}
|
||||
|
||||
|
||||
void kol_wnd_move(unsigned x, unsigned y)
|
||||
{
|
||||
asm ("nop"::"a"(67), "b"(x), "c"(y));
|
||||
asm ("movl $-1, %edx \n movl $-1, %esi \n int $0x40");
|
||||
}
|
||||
|
||||
|
||||
void kol_event_mask(unsigned e)
|
||||
{
|
||||
asm ("int $0x40"::"a"(40), "b"(e));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_event_wait()
|
||||
{
|
||||
asm ("int $0x40"::"a"(10));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_event_wait_time(unsigned time)
|
||||
{
|
||||
asm ("int $0x40"::"a"(23), "b"(time));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_event_check()
|
||||
{
|
||||
asm ("int $0x40"::"a"(11));
|
||||
}
|
||||
|
||||
|
||||
void kol_paint_start()
|
||||
{
|
||||
asm ("int $0x40"::"a"(12), "b"(1));
|
||||
}
|
||||
|
||||
|
||||
void kol_paint_end()
|
||||
{
|
||||
asm ("int $0x40"::"a"(12), "b"(2));
|
||||
}
|
||||
|
||||
|
||||
void kol_paint_pixel(unsigned x, unsigned y, unsigned c)
|
||||
{
|
||||
asm ("int $0x40"::"a"(1), "b"(x), "c"(y), "d"(c));
|
||||
}
|
||||
|
||||
|
||||
void kol_paint_bar(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c)
|
||||
{
|
||||
asm ("int $0x40"::"a"(13), "b"(x*65536+w), "c"(y*65536+h), "d"(c));
|
||||
}
|
||||
|
||||
|
||||
void kol_paint_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned c)
|
||||
{
|
||||
asm ("int $0x40"::"a"(38), "b"(x1*65536+x2), "c"(y1*65536+y2), "d"(c));
|
||||
}
|
||||
|
||||
|
||||
void kol_paint_string(unsigned x, unsigned y, char *s, unsigned c)
|
||||
{
|
||||
asm ("int $0x40"::"a"(4), "b"(x*65536+y), "c"(c), "d"(s));
|
||||
}
|
||||
|
||||
|
||||
void kol_paint_image(unsigned x, unsigned y, unsigned w, unsigned h, char *d)
|
||||
{
|
||||
asm ("int $0x40"::"a"(7), "c"(w*65536+h), "d"(x*65536+y), "b"(d));
|
||||
}
|
||||
|
||||
|
||||
void kol_paint_image_pal(unsigned x, unsigned y, unsigned w, unsigned h, char *d, unsigned *palette)
|
||||
{
|
||||
asm ("nop"::"c"(w*65536+h), "d"(x*65536+y), "b"(d));
|
||||
asm ("nop"::"a"(palette));
|
||||
asm ("movl %eax, %edi");
|
||||
asm ("xor %eax, %eax");
|
||||
asm ("movl %eax, %ebp");
|
||||
asm ("pushl $8");
|
||||
asm ("popl %esi");
|
||||
asm ("int $0x40"::"a"(65));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_key_get()
|
||||
{
|
||||
asm ("int $0x40"::"a"(2));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_key_control()
|
||||
{
|
||||
asm ("int $0x40"::"a"(66), "b"(3));
|
||||
}
|
||||
|
||||
|
||||
void kol_key_lang_set(unsigned lang)
|
||||
{
|
||||
asm ("int $0x40"::"a"(21), "b"(2), "c"(9), "d"(lang));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_key_lang_get()
|
||||
{
|
||||
asm ("int $0x40"::"a"(26), "b"(2), "c"(9));
|
||||
}
|
||||
|
||||
|
||||
void kol_key_mode_set(unsigned mode)
|
||||
{
|
||||
asm ("int $0x40"::"a"(66), "b"(1), "c"(mode));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_key_mode_get()
|
||||
{
|
||||
asm ("int $0x40"::"a"(66), "b"(2));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_btn_get()
|
||||
{
|
||||
asm ("int $0x40"::"a"(17));
|
||||
}
|
||||
|
||||
|
||||
void kol_btn_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned d, unsigned c)
|
||||
{
|
||||
asm ("nop"::"b"(x*65536+w), "c"(y*65536+h), "d"(d));
|
||||
asm ("nop"::"a"(c));
|
||||
asm ("movl %eax, %esi");
|
||||
asm ("int $0x40"::"a"(8));
|
||||
}
|
||||
|
||||
|
||||
void kol_btn_type(unsigned t)
|
||||
{
|
||||
asm ("int $0x40"::"a"(48), "b"(1), "c"(t));
|
||||
}
|
||||
|
||||
|
||||
void kol_wnd_caption(char *s)
|
||||
{
|
||||
asm ("int $0x40"::"a"(71), "b"(1), "c"(s));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_mouse_pos()
|
||||
{
|
||||
asm ("int $0x40"::"a"(37), "b"(0));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_mouse_posw()
|
||||
{
|
||||
asm ("int $0x40"::"a"(37), "b"(1));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_mouse_btn()
|
||||
{
|
||||
asm ("int $0x40"::"a"(37), "b"(2));
|
||||
}
|
||||
|
||||
|
||||
void kol_board_putc(char c)
|
||||
{
|
||||
asm ("int $0x40"::"a"(63), "b"(1), "c"(c));
|
||||
}
|
||||
|
||||
|
||||
void kol_board_puts(char *s)
|
||||
{
|
||||
unsigned i;
|
||||
i = 0;
|
||||
while (*(s+i))
|
||||
{
|
||||
asm ("int $0x40"::"a"(63), "b"(1), "c"(*(s+i)));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void kol_board_puti(int n)
|
||||
{
|
||||
char c;
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
c = n % 10 + '0';
|
||||
asm ("int $0x40"::"a"(63), "b"(1), "c"(c));
|
||||
i++;
|
||||
}
|
||||
while ((n /= 10) > 0);
|
||||
}
|
||||
|
||||
|
||||
int kol_file_70(kol_struct70 *k)
|
||||
{
|
||||
asm ("int $0x40"::"a"(70), "b"(k));
|
||||
}
|
||||
|
||||
|
||||
kol_struct_import* kol_cofflib_load(char *name)
|
||||
{
|
||||
asm ("int $0x40"::"a"(68), "b"(19), "c"(name));
|
||||
}
|
||||
|
||||
|
||||
void* kol_cofflib_procload (kol_struct_import *imp, char *name)
|
||||
{
|
||||
int i;
|
||||
for (i=0;;i++)
|
||||
if ( NULL == ((imp+i) -> name))
|
||||
break;
|
||||
else
|
||||
if ( 0 == strcmp(name, (imp+i)->name) )
|
||||
return (imp+i)->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_cofflib_procnum (kol_struct_import *imp)
|
||||
{
|
||||
unsigned i, n;
|
||||
|
||||
for (i=n=0;;i++)
|
||||
if ( NULL == ((imp+i) -> name))
|
||||
break;
|
||||
else
|
||||
n++;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void kol_cofflib_procname (kol_struct_import *imp, char *name, unsigned n)
|
||||
{
|
||||
unsigned i;
|
||||
*name = 0;
|
||||
|
||||
for (i=0;;i++)
|
||||
if ( NULL == ((imp+i) -> name))
|
||||
break;
|
||||
else
|
||||
if ( i == n )
|
||||
{
|
||||
strcpy(name, ((imp+i)->name));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_system_cpufreq()
|
||||
{
|
||||
asm ("int $0x40"::"a"(18), "b"(5));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_system_mem()
|
||||
{
|
||||
asm ("int $0x40"::"a"(18), "b"(17));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_system_memfree()
|
||||
{
|
||||
asm ("int $0x40"::"a"(18), "b"(16));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_system_time_get()
|
||||
{
|
||||
asm ("int $0x40"::"a"(3));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_system_date_get()
|
||||
{
|
||||
asm ("int $0x40"::"a"(29));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_system_end(unsigned param)
|
||||
{
|
||||
asm ("int $0x40"::"a"(18), "b"(9), "c"(param));
|
||||
}
|
||||
|
||||
|
||||
void kol_path_file2dir(char *dir, char *fname)
|
||||
{
|
||||
unsigned i;
|
||||
strcpy (dir, fname);
|
||||
for ( i = strlen(dir);; --i)
|
||||
if ( '/' == dir[i])
|
||||
{
|
||||
dir[i] = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void kol_path_full(char *full, char *fname)
|
||||
{
|
||||
char temp[256];
|
||||
|
||||
switch (*fname)
|
||||
{
|
||||
|
||||
case '/':
|
||||
strncpy(temp, fname+1, 2);
|
||||
temp[2]=0;
|
||||
if ( (!strcmp("rd", temp)) || (!strcmp("hd", temp)) || (!strcmp("cd", temp)) )
|
||||
strcpy (full, fname);
|
||||
break;
|
||||
|
||||
case '.':
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void kol_screen_wait_rr()
|
||||
{
|
||||
asm ("int $0x40"::"a"(18), "b"(14));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void kol_screen_get_size(unsigned *w, unsigned *h)
|
||||
{
|
||||
unsigned size;
|
||||
asm ("int $0x40":"=a"(size):"a"(14));
|
||||
*w = size / 65536;
|
||||
*h = size % 65536;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned kol_skin_height()
|
||||
{
|
||||
asm ("int $0x40"::"a"(48), "b"(4));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_thread_start(unsigned start, unsigned stack)
|
||||
{
|
||||
asm ("int $0x40"::"a"(51), "b"(1), "c"(start), "d"(stack));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_time_tick()
|
||||
{
|
||||
asm ("int $0x40"::"a"(26), "b"(9));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_sound_speaker(char data[])
|
||||
{
|
||||
asm ("movl %0, %%esi"::"a"(data));
|
||||
asm ("int $0x40"::"a"(55), "b"(55));
|
||||
}
|
||||
|
||||
|
||||
unsigned kol_process_info(unsigned slot, char buf1k[])
|
||||
{
|
||||
asm ("int $0x40"::"a"(9), "b"(buf1k), "c"(slot));
|
||||
}
|
||||
|
||||
|
||||
int kol_process_kill_pid(unsigned process)
|
||||
{
|
||||
asm ("int $0x40"::"a"(18), "b"(18), "c"(process));
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
|
||||
#define NULL ((void*)0)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned p00 __attribute__((packed));
|
||||
unsigned p04 __attribute__((packed));
|
||||
unsigned p08 __attribute__((packed));
|
||||
unsigned p12 __attribute__((packed));
|
||||
unsigned p16 __attribute__((packed));
|
||||
char p20 __attribute__((packed));
|
||||
char *p21 __attribute__((packed));
|
||||
} kol_struct70 __attribute__((packed));
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned p00 __attribute__((packed));
|
||||
char p04 __attribute__((packed));
|
||||
char p05[3] __attribute__((packed));
|
||||
unsigned p08 __attribute__((packed));
|
||||
unsigned p12 __attribute__((packed));
|
||||
unsigned p16 __attribute__((packed));
|
||||
unsigned p20 __attribute__((packed));
|
||||
unsigned p24 __attribute__((packed));
|
||||
unsigned p28 __attribute__((packed));
|
||||
unsigned p32[2] __attribute__((packed));
|
||||
unsigned p40 __attribute__((packed));
|
||||
} kol_struct_BDVK __attribute__((packed));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name __attribute__((packed));
|
||||
void *data __attribute__((packed));
|
||||
} kol_struct_import __attribute__((packed));
|
||||
|
||||
|
||||
void kol_exit();
|
||||
void kol_sleep(unsigned d);
|
||||
void kol_wnd_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c);
|
||||
void kol_wnd_move(unsigned x, unsigned y);
|
||||
void kol_wnd_caption(char *s);
|
||||
void kol_event_mask(unsigned e);
|
||||
unsigned kol_event_wait();
|
||||
unsigned kol_event_wait_time(unsigned time);
|
||||
unsigned kol_event_check();
|
||||
void kol_paint_start();
|
||||
void kol_paint_end();
|
||||
void kol_paint_pixel(unsigned x, unsigned y, unsigned c);
|
||||
void kol_paint_bar(unsigned x, unsigned y, unsigned w, unsigned h, unsigned c);
|
||||
void kol_paint_line(unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned c);
|
||||
void kol_paint_string(unsigned x, unsigned y, char *s, unsigned c);
|
||||
void kol_paint_image(unsigned x, unsigned y, unsigned w, unsigned h, char *d);
|
||||
void kol_paint_image_pal(unsigned x, unsigned y, unsigned w, unsigned h, char *d, unsigned *palette);
|
||||
unsigned kol_key_get();
|
||||
unsigned kol_key_control();
|
||||
void kol_key_lang_set(unsigned lang);
|
||||
unsigned kol_key_lang_get();
|
||||
void kol_key_mode_set(unsigned mode);
|
||||
unsigned kol_key_mode_get();
|
||||
void kol_btn_define(unsigned x, unsigned y, unsigned w, unsigned h, unsigned d, unsigned c);
|
||||
unsigned kol_btn_get();
|
||||
void kol_btn_type(unsigned t);
|
||||
unsigned kol_mouse_pos();
|
||||
unsigned kol_mouse_posw();
|
||||
unsigned kol_mouse_btn();
|
||||
void kol_board_putc(char c);
|
||||
void kol_board_puts(char *s);
|
||||
void kol_board_puti(int n);
|
||||
int kol_file_70(kol_struct70 *k);
|
||||
kol_struct_import* kol_cofflib_load(char *name);
|
||||
void* kol_cofflib_procload (kol_struct_import *imp, char *name);
|
||||
unsigned kol_cofflib_procnum (kol_struct_import *imp);
|
||||
void kol_cofflib_procname (kol_struct_import *imp, char *name, unsigned n);
|
||||
unsigned kol_system_end(unsigned param);
|
||||
unsigned kol_system_cpufreq();
|
||||
unsigned kol_system_mem();
|
||||
unsigned kol_system_memfree();
|
||||
unsigned kol_system_time_get();
|
||||
unsigned kol_system_date_get();
|
||||
void kol_path_file2dir(char *dir, char *fname);
|
||||
void kol_path_full(char *full, char *fname);
|
||||
void kol_screen_wait_rr();
|
||||
void kol_screen_get_size(unsigned *w, unsigned *h);
|
||||
unsigned kol_skin_height();
|
||||
unsigned kol_thread_start(unsigned start, unsigned stack);
|
||||
unsigned kol_time_tick();
|
||||
unsigned kol_sound_speaker(char data[]);
|
||||
unsigned kol_process_info(unsigned slot, char buf1k[]);
|
||||
int kol_process_kill_pid(unsigned process);
|
|
@ -0,0 +1,167 @@
|
|||
|
||||
///=============================
|
||||
|
||||
#define MB_OK 0
|
||||
#define MB_OKCANCEL 1
|
||||
#define MB_ABORTRETRYIGNORE 2
|
||||
#define MB_YESNOCANCEL 3
|
||||
#define MB_YESNO 4
|
||||
#define MB_RETRYCANCEL 5
|
||||
|
||||
#define IDOK 1
|
||||
#define IDCANCEL 2
|
||||
#define IDABORT 3
|
||||
#define IDRETRY 4
|
||||
#define IDIGNORE 5
|
||||
#define IDYES 6
|
||||
#define IDNO 7
|
||||
|
||||
///=============================
|
||||
|
||||
#define LANG_EN
|
||||
|
||||
#ifdef LANG_RU
|
||||
char BTN_OK[]={"OK"};
|
||||
char BTN_CANCEL[]={"Žâ¬¥ "};
|
||||
char BTN_ABORT[]={"<EFBFBD>४à â¨âì"};
|
||||
char BTN_RETRY[]={"<EFBFBD>®¢â®à¨âì"};
|
||||
char BTN_INGNORE[]={"ˆ£®à¨à®¢ âì"};
|
||||
char BTN_NO[]={"<EFBFBD>¥â"};
|
||||
#endif
|
||||
|
||||
#ifdef LANG_EN
|
||||
char BTN_OK[]={"OK"};
|
||||
char BTN_CANCEL[]={"Cancel"};
|
||||
char BTN_ABORT[]={"Abort"};
|
||||
char BTN_RETRY[]={"Retry"};
|
||||
char BTN_INGNORE[]={"Ignore"};
|
||||
char BTN_NO[]={"No"};
|
||||
#endif
|
||||
|
||||
///=============================
|
||||
|
||||
kol_struct_import *MSG_BOX_IMPORT = NULL;
|
||||
int (* _stdcall mb_create)(char *m, char* t);
|
||||
|
||||
char msg[1024];
|
||||
char thread[1024];
|
||||
|
||||
|
||||
///=============================
|
||||
|
||||
char MessageBox(char *text, char *caption, int type)
|
||||
{
|
||||
|
||||
int i, j;
|
||||
|
||||
if (MSG_BOX_IMPORT == NULL)
|
||||
{
|
||||
MSG_BOX_IMPORT = kol_cofflib_load("/sys/lib/Msgbox.obj");
|
||||
if (MSG_BOX_IMPORT == NULL)
|
||||
kol_exit();
|
||||
|
||||
mb_create = kol_cofflib_procload (MSG_BOX_IMPORT, "mb_create");
|
||||
if (mb_create == NULL)
|
||||
kol_exit();
|
||||
|
||||
}
|
||||
|
||||
msg[0] = 255;
|
||||
msg[1] = 0;
|
||||
|
||||
for (i = 2, j = 0; ;i++, j++)
|
||||
{
|
||||
msg[i] = caption[j];
|
||||
if (0 == msg[i])
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
msg[i] = 0;
|
||||
|
||||
for (j = 0; ;i++, j++)
|
||||
{
|
||||
msg[i] = text[j];
|
||||
if (0 == msg[i])
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
msg[i] = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MB_OK:
|
||||
for (j = 0; ;i++, j++)
|
||||
{
|
||||
msg[i] = BTN_OK[j];
|
||||
if (0 == msg[i])
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MB_OKCANCEL:
|
||||
for (j = 0; ;i++, j++)
|
||||
{
|
||||
msg[i] = BTN_OK[j];
|
||||
if (0 == msg[i])
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
msg[i] = 0;
|
||||
|
||||
for (j = 0; ;i++, j++)
|
||||
{
|
||||
msg[i] = BTN_CANCEL[j];
|
||||
if (0 == msg[i])
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
i++;
|
||||
msg[i] = 0;
|
||||
|
||||
mb_create(msg, thread+1024);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( (unsigned char) msg[0] != 255 )
|
||||
switch (type)
|
||||
{
|
||||
case MB_OK:
|
||||
if (msg[0] == 1)
|
||||
return IDOK;
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case MB_OKCANCEL:
|
||||
switch(msg[0])
|
||||
{
|
||||
case 1:
|
||||
return IDOK;
|
||||
case 2:
|
||||
return IDCANCEL;
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
|
||||
};
|
||||
|
||||
kol_sleep(10);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
///=============================
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
unsigned int seed_o = 0x45168297;
|
||||
|
||||
|
||||
void srand (unsigned seed)
|
||||
{
|
||||
seed_o = seed;
|
||||
}
|
||||
|
||||
|
||||
int rand (void)
|
||||
{
|
||||
seed_o = seed_o * 0x15a4e35 + 1;
|
||||
return(seed_o >> 16);
|
||||
}
|
||||
|
||||
|
||||
void* malloc(unsigned s)
|
||||
{
|
||||
asm ("int $0x40"::"a"(68), "b"(12), "c"(s) );
|
||||
}
|
||||
|
||||
|
||||
void free(void *p)
|
||||
{
|
||||
asm ("int $0x40"::"a"(68), "b"(13), "c"(p) );
|
||||
}
|
||||
|
||||
|
||||
void* realloc(void *p, unsigned s)
|
||||
{
|
||||
asm ("int $0x40"::"a"(68), "b"(12), "c"(p), "d"(s) );
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#define RAND_MAX 0x7FFFU
|
||||
|
||||
#define isspace(c) ((c)==' ')
|
||||
#define abs(i) (((i)<0)?(-(i)):(i))
|
||||
|
||||
#define random(num) ((rand()*(num))/((RAND_MAX+1)))
|
||||
|
||||
void* malloc(unsigned size);
|
||||
void free(void *pointer);
|
||||
void* realloc(void* pointer, unsigned size);
|
||||
|
||||
void srand (unsigned seed);
|
||||
int rand (void);
|
|
@ -0,0 +1,124 @@
|
|||
|
||||
#include "string.h"
|
||||
|
||||
void* memset(void *mem, int c, unsigned size)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for ( i = 0; i < size; i++ )
|
||||
*((char *)mem+i) = (char) c;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void* memcpy(void *dst, const void *src, unsigned size)
|
||||
{
|
||||
|
||||
unsigned i;
|
||||
|
||||
for ( i = 0; i < size; i++)
|
||||
*(char *)(dst+i) = *(char *)(src+i);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int memcmp(const void* buf1, const void* buf2, int count)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<count;i++)
|
||||
{
|
||||
if (*(unsigned char*)buf1<*(unsigned char*)buf2)
|
||||
return -1;
|
||||
if (*(unsigned char*)buf1>*(unsigned char*)buf2)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void strcat(char strDest[], char strSource[])
|
||||
{
|
||||
|
||||
int i, j;
|
||||
|
||||
i = j = 0;
|
||||
while (strDest[i] != '\0')
|
||||
i++;
|
||||
|
||||
while ((strDest[i++] = strSource[j++]) != '\0')
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
int strcmp(const char* string1, const char* string2)
|
||||
{
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (*string1<*string2)
|
||||
return -1;
|
||||
if (*string1>*string2)
|
||||
return 1;
|
||||
|
||||
if (*string1=='\0')
|
||||
return 0;
|
||||
|
||||
string1++;
|
||||
string2++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void strcpy(char strDest[], const char strSource[])
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
i = 0;
|
||||
while ((strDest[i] = strSource[i]) != '\0')
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
char* strncpy(char *strDest, const char *strSource, unsigned n)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (! n )
|
||||
return strDest;
|
||||
|
||||
i = 0;
|
||||
while ((strDest[i] = strSource[i]) != '\0')
|
||||
if ( (n-1) == i )
|
||||
break;
|
||||
else
|
||||
i++;
|
||||
|
||||
return strDest;
|
||||
}
|
||||
|
||||
|
||||
int strlen(const char* string)
|
||||
{
|
||||
int i;
|
||||
|
||||
i=0;
|
||||
while (*string++) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char* strchr(const char* string, int c)
|
||||
{
|
||||
while (*string)
|
||||
{
|
||||
if (*string==c)
|
||||
return (char*)string;
|
||||
string++;
|
||||
}
|
||||
return (char*)0;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#ifndef NULL
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
void* memset(void *mem, int c, unsigned size);
|
||||
void* memcpy(void *dst, const void *src, unsigned size);
|
||||
int memcmp(const void* buf1, const void* buf2, int count);
|
||||
|
||||
void strcat(char strDest[], char strSource[]);
|
||||
int strcmp(const char* string1, const char* string2);
|
||||
void strcpy(char strDest[], const char strSource[]);
|
||||
char* strncpy(char *strDest, const char *strSource, unsigned n);
|
||||
int strlen(const char* string);
|
||||
char *strchr(const char* string, int c);
|
|
@ -0,0 +1,447 @@
|
|||
/*=====================================================================
|
||||
Macros.c -> Macros used on the opcode execution.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
======================================================================*/
|
||||
|
||||
/* defines for the registers: faster access to them when coding... */
|
||||
|
||||
#define r_PC regs->PC.W
|
||||
#define r_PCl regs->PC.B.l
|
||||
#define r_PCh regs->PC.B.h
|
||||
#define r_SP regs->SP.W
|
||||
#define r_IFF1 regs->IFF1
|
||||
#define r_IFF2 regs->IFF2
|
||||
#define r_R regs->R.W
|
||||
|
||||
#define r_AF regs->AF.W
|
||||
#define r_A regs->AF.B.h
|
||||
#define r_F regs->AF.B.l
|
||||
#define r_BC regs->BC.W
|
||||
#define r_B regs->BC.B.h
|
||||
#define r_C regs->BC.B.l
|
||||
#define r_DE regs->DE.W
|
||||
#define r_D regs->DE.B.h
|
||||
#define r_E regs->DE.B.l
|
||||
#define r_HL regs->HL.W
|
||||
#define r_H regs->HL.B.h
|
||||
#define r_L regs->HL.B.l
|
||||
#define r_IX regs->IX.W
|
||||
#define r_IXh regs->IX.B.h
|
||||
#define r_IXl regs->IX.B.l
|
||||
#define r_IY regs->IY.W
|
||||
#define r_IYh regs->IY.B.h
|
||||
#define r_IYl regs->IY.B.l
|
||||
|
||||
#define r_AFs regs->AFs.W
|
||||
#define r_As regs->AFs.B.h
|
||||
#define r_Fs regs->AFs.B.l
|
||||
#define r_BCs regs->BCs.W
|
||||
#define r_Bs regs->BCs.B.h
|
||||
#define r_Cs regs->BCs.B.l
|
||||
#define r_DEs regs->DEs.W
|
||||
#define r_Ds regs->DEs.B.h
|
||||
#define r_Es regs->DEs.B.l
|
||||
#define r_HLs regs->HLs.W
|
||||
#define r_Hs regs->HLs.B.h
|
||||
#define r_Ls regs->HLs.B.l
|
||||
#define r_IXs regs->IX.W
|
||||
#define r_IXhs regs->IX.B.h
|
||||
#define r_IXls regs->IX.B.l
|
||||
#define r_IYs regs->IY.W
|
||||
#define r_IYhs regs->IY.B.h
|
||||
#define r_IYls regs->IY.B.l
|
||||
|
||||
#define r_op ops.W
|
||||
#define r_oph ops.B.h
|
||||
#define r_opl ops.B.l
|
||||
#define r_tmp tmpreg2.W
|
||||
#define r_tmph tmpreg2.B.h
|
||||
#define r_tmpl tmpreg2.B.l
|
||||
#define r_mem mread.W
|
||||
#define r_memh mread.B.h
|
||||
#define r_meml mread.B.l
|
||||
|
||||
#ifndef _DISASM_
|
||||
/*--- Flag tables by Philip Kendall, taken from it's fuse emulator -*/
|
||||
/*--- I was having headache trying to emulate correctly the FLAGS,
|
||||
so I finished using the FLAG tables used by P. Kendall. ------*/
|
||||
#define FLAG_C 0x01
|
||||
#define FLAG_N 0x02
|
||||
#define FLAG_P 0x04
|
||||
#define FLAG_V FLAG_P
|
||||
#define FLAG_3 0x08
|
||||
#define FLAG_H 0x10
|
||||
#define FLAG_5 0x20
|
||||
#define FLAG_Z 0x40
|
||||
#define FLAG_S 0x80
|
||||
|
||||
/* Whether a half carry occured or not can be determined by looking at
|
||||
the 3rd bit of the two arguments and the result; these are hashed
|
||||
into this table in the form r12, where r is the 3rd bit of the
|
||||
result, 1 is the 3rd bit of the 1st argument and 2 is the
|
||||
third bit of the 2nd argument; the tables differ for add and subtract
|
||||
operations */
|
||||
|
||||
/* Whether a half carry occured or not can be determined by looking at
|
||||
the 3rd bit of the two arguments and the result; these are hashed
|
||||
into this table in the form r12, where r is the 3rd bit of the
|
||||
result, 1 is the 3rd bit of the 1st argument and 2 is the
|
||||
third bit of the 2nd argument; the tables differ for add and subtract
|
||||
operations */
|
||||
byte halfcarry_add_table[] = { 0, FLAG_H, FLAG_H, FLAG_H, 0, 0, 0, FLAG_H };
|
||||
byte halfcarry_sub_table[] = { 0, 0, FLAG_H, 0, FLAG_H, 0, FLAG_H, FLAG_H };
|
||||
|
||||
/* Similarly, overflow can be determined by looking at the 7th bits; again
|
||||
the hash into this table is r12 */
|
||||
byte overflow_add_table[] = { 0, 0, 0, FLAG_V, FLAG_V, 0, 0, 0 };
|
||||
byte overflow_sub_table[] = { 0, FLAG_V, 0, 0, 0, 0, FLAG_V, 0 };
|
||||
|
||||
/* Some more tables; initialised in z80_init_tables() */
|
||||
byte sz53_table[0x100]; /* The S, Z, 5 and 3 bits of the temp value */
|
||||
byte parity_table[0x100]; /* The parity of the temp value */
|
||||
byte sz53p_table[0x100]; /* OR the above two tables together */
|
||||
/*------------------------------------------------------------------*/
|
||||
|
||||
// Contributed by Metalbrain to implement OUTI, etc.
|
||||
byte ioblock_inc1_table[64];
|
||||
byte ioblock_dec1_table[64];
|
||||
byte ioblock_2_table[0x100];
|
||||
|
||||
/*--- Memory Write on the A address on no bank machines -------------*/
|
||||
void Z80WriteMem( word where, word A, Z80Regs *regs)
|
||||
{
|
||||
if( where >= 16384 )
|
||||
regs->RAM[where] = A;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*--- Memory Read from the A address on no bank machines -------------*/
|
||||
#define Z80ReadMem(A) ((regs->RAM[(A)]))
|
||||
|
||||
// return( regs->RAM[A] );
|
||||
|
||||
|
||||
/* macros to change the ICount register */
|
||||
#define AddCycles(n) regs->ICount-=(n)
|
||||
|
||||
#define SubCycles(n) regs->ICount+=(n)
|
||||
|
||||
//#define AddR(n) r_R = (r_R+(n))
|
||||
#define AddR(n) r_R = ((r_R & 0x80) | ((r_R+(n)) & 0x7f ))
|
||||
#define SubR(n) r_R = ((r_R & 0x80) | ((r_R-(n)) & 0x7f ))
|
||||
|
||||
|
||||
/* setting and resetting the flag bits: */
|
||||
#define SET_FLAG(flag) (r_F |= (flag))
|
||||
|
||||
#define RESET_FLAG(flag) (r_F &= ~(flag))
|
||||
|
||||
#define TEST_FLAG(flag) (r_F & (flag))
|
||||
|
||||
|
||||
/* store a given register in the stack (hi and lo bytes) */
|
||||
#define PUSH(rreg) \
|
||||
Z80WriteMem( --(r_SP), regs->rreg.B.h, regs); \
|
||||
Z80WriteMem( --(r_SP), regs->rreg.B.l, regs)
|
||||
|
||||
#define POP(rreg)\
|
||||
regs->rreg.B.l = Z80ReadMem(r_SP); r_SP++;\
|
||||
regs->rreg.B.h = Z80ReadMem(r_SP); r_SP++
|
||||
|
||||
#define PUSH_IXYr() \
|
||||
Z80WriteMem( --(r_SP), REGH, regs); \
|
||||
Z80WriteMem( --(r_SP), REGL, regs)
|
||||
|
||||
#define POP_IXYr()\
|
||||
REGL = Z80ReadMem(r_SP); r_SP++; \
|
||||
REGH = Z80ReadMem(r_SP); r_SP++
|
||||
|
||||
#define RST(rstval) PUSH(PC); r_PC=(rstval)
|
||||
|
||||
|
||||
/*--- Move data to mem or regs --------------------------------------*/
|
||||
#define LD_r_r(dreg, sreg) (dreg) = (sreg)
|
||||
|
||||
#define STORE_r(daddreg, sreg) Z80WriteMem((daddreg), (sreg), regs)
|
||||
|
||||
#define STORE_nn_rr(dreg) \
|
||||
r_opl = Z80ReadMem(r_PC); r_PC++;\
|
||||
r_oph = Z80ReadMem(r_PC); r_PC++; \
|
||||
r_tmp = dreg; \
|
||||
Z80WriteMem((r_op),r_tmpl, regs); \
|
||||
Z80WriteMem((r_op+1),r_tmph, regs)
|
||||
|
||||
#define STORE_nn_r(sreg) \
|
||||
r_opl = Z80ReadMem(r_PC); r_PC++; \
|
||||
r_oph = Z80ReadMem(r_PC); r_PC++; \
|
||||
Z80WriteMem((r_op),(sreg), regs)
|
||||
|
||||
#define LOAD_r(dreg, saddreg) (dreg)=Z80ReadMem((saddreg))
|
||||
|
||||
#define LOAD_rr_nn(dreg) r_opl = Z80ReadMem(r_PC); r_PC++; \
|
||||
r_oph = Z80ReadMem(r_PC); r_PC++; \
|
||||
r_tmpl = Z80ReadMem(r_op); \
|
||||
r_tmph = Z80ReadMem((r_op)+1); \
|
||||
dreg=r_tmp
|
||||
|
||||
|
||||
#define LOAD_r_nn(dreg) r_opl = Z80ReadMem(r_PC); r_PC++; \
|
||||
r_oph = Z80ReadMem(r_PC); r_PC++; \
|
||||
dreg = Z80ReadMem(r_op)
|
||||
|
||||
#define LD_r_n(reg) (reg) = Z80ReadMem(r_PC++)
|
||||
|
||||
#define LD_rr_nn(reg) r_opl = Z80ReadMem(r_PC); r_PC++; \
|
||||
r_oph = Z80ReadMem(r_PC); r_PC++; \
|
||||
reg = r_op
|
||||
|
||||
#define EX(reg1,reg2) r_opl=(reg1); (reg1)=(reg2); (reg2)=r_opl
|
||||
|
||||
#define EX_WORD(reg1,reg2) r_op=(reg1); (reg1)=(reg2); (reg2)=r_op
|
||||
|
||||
/*--- Increments/Decrements -----------------------------------------*/
|
||||
#define INC(reg) (reg)++; \
|
||||
r_F = ( r_F & FLAG_C ) | ( (reg)==0x80 ? FLAG_V : 0 ) | \
|
||||
( (reg)&0x0f ? 0 : FLAG_H ) | ( (reg) ? 0 : FLAG_Z ) | \
|
||||
sz53_table[(reg)]
|
||||
|
||||
#define DEC(reg) \
|
||||
r_F = ( r_F & FLAG_C ) | ( (reg)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(reg)--; \
|
||||
r_F |= ( (reg)==0x7f ? FLAG_V : 0 ) | sz53_table[(reg)]
|
||||
|
||||
// it was:
|
||||
// r_F |= ( (reg)==0x79 ? FLAG_V : 0 ) | sz53_table[(reg)]
|
||||
// But Kak pointed my was not 0x79 -> 0x7F, changed 7-3-2001
|
||||
|
||||
|
||||
/*--- Bit operations ------------------------------------------------*/
|
||||
#define BIT_RES(b,reg) reg &= ~(0x1<<b)
|
||||
|
||||
#define BIT_SET(b,reg) reg |= (0x1<<b)
|
||||
|
||||
#define BIT_mem_RES(b,addr) r_opl = Z80ReadMem(addr); \
|
||||
r_opl &= ~(0x1<<b); \
|
||||
Z80WriteMem(addr, r_opl, regs)
|
||||
|
||||
#define BIT_mem_SET(b,addr) r_opl = Z80ReadMem(addr); \
|
||||
r_opl |= (0x1<<b); \
|
||||
Z80WriteMem(addr, r_opl, regs)
|
||||
|
||||
#define BIT_RES_mem(b,addr,reg) reg &= ~(0x1<<b); \
|
||||
Z80WriteMem((addr), (reg), regs)
|
||||
|
||||
#define BIT_SET_mem(b,addr,reg) reg |= (0x1<<b); \
|
||||
Z80WriteMem((addr), (reg), regs)
|
||||
|
||||
#define BIT_BIT(b,reg) r_F = ( r_F & FLAG_C ) | \
|
||||
( (reg) & ( FLAG_3 | FLAG_5 ) ) |\
|
||||
(((reg) & ( 0x01 << b ) ) ? FLAG_H : \
|
||||
(FLAG_P|FLAG_H|FLAG_Z ) )
|
||||
|
||||
#define BIT_mem_BIT(b,reg) r_opl = Z80ReadMem(reg); \
|
||||
r_F = ( r_F & FLAG_C ) | \
|
||||
( (r_opl) & ( FLAG_3 | FLAG_5 ) ) |\
|
||||
(((r_opl) & ( 0x01 << b ) ) ? FLAG_H : \
|
||||
(FLAG_P|FLAG_H|FLAG_Z ) )
|
||||
|
||||
#define BIT_BIT7(reg) r_F = ( r_F & FLAG_C ) | ( (reg) & \
|
||||
( FLAG_3 | FLAG_5 ) ) |\
|
||||
(((reg) & 0x80 ) ? ( FLAG_H | FLAG_S ) :\
|
||||
( FLAG_P | FLAG_H | FLAG_Z ) )
|
||||
|
||||
#define BIT_mem_BIT7(reg) r_opl = Z80ReadMem(reg); \
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_opl) & \
|
||||
( FLAG_3 | FLAG_5 ) ) |\
|
||||
(((r_opl) & 0x80 ) ? ( FLAG_H | FLAG_S ) :\
|
||||
( FLAG_P | FLAG_H | FLAG_Z ) )
|
||||
|
||||
|
||||
#define RLC(reg) (reg) = ( (reg)<<1 ) | ( (reg)>>7 ); \
|
||||
r_F = ( (reg) & FLAG_C ) | sz53p_table[(reg)]
|
||||
|
||||
#define RRC(reg) r_F = (reg) & FLAG_C; \
|
||||
(reg) = ( (reg)>>1 ) | ( (reg)<<7 );\
|
||||
r_F |= sz53p_table[(reg)]
|
||||
|
||||
#define RL(reg) r_opl = (reg); \
|
||||
(reg) = ( (reg)<<1 ) | ( r_F & FLAG_C ); \
|
||||
r_F = ( r_opl >> 7 ) | sz53p_table[(reg)]
|
||||
|
||||
#define RR(reg) r_opl = (reg); \
|
||||
(reg) = ( (reg)>>1 ) | ( r_F << 7 );\
|
||||
r_F = ( r_opl & FLAG_C ) | sz53p_table[(reg)]
|
||||
|
||||
#define SLA(reg) r_F = (reg) >> 7;\
|
||||
(reg) <<= 1;\
|
||||
r_F |= sz53p_table[(reg)]
|
||||
|
||||
#define SRA(reg) r_F = (reg) & FLAG_C; \
|
||||
(reg) = ( (reg) & 0x80 ) | ( (reg) >> 1 );\
|
||||
r_F |= sz53p_table[(reg)]
|
||||
|
||||
#define SLL(reg) r_F = (reg) >> 7;\
|
||||
(reg) = ( (reg) << 1 ) | 0x01;\
|
||||
r_F |= sz53p_table[(reg)]
|
||||
|
||||
#define SRL(reg) r_F = (reg) & FLAG_C;\
|
||||
(reg) >>= 1;\
|
||||
r_F |= sz53p_table[(reg)]
|
||||
|
||||
|
||||
|
||||
/*--- JP operations -------------------------------------------------*/
|
||||
#define JP_nn() r_opl = Z80ReadMem(r_PC); \
|
||||
r_PC++; \
|
||||
r_oph = Z80ReadMem(r_PC); \
|
||||
r_PC = r_op
|
||||
|
||||
#define JR_n() r_PC += (offset) (Z80ReadMem(r_PC)); r_PC++
|
||||
|
||||
#define RET_nn() r_PCl = Z80ReadMem (r_SP); r_SP++; \
|
||||
r_PCh = Z80ReadMem (r_SP); r_SP++;
|
||||
|
||||
#define CALL_nn() r_opl = Z80ReadMem (r_PC); r_PC++; \
|
||||
r_oph = Z80ReadMem (r_PC); r_PC++; \
|
||||
Z80WriteMem( --(r_SP), r_PCh, regs ); \
|
||||
Z80WriteMem( --(r_SP), r_PCl, regs ); \
|
||||
r_PC = r_op
|
||||
|
||||
|
||||
/*--- ALU operations ------------------------------------------------*/
|
||||
#define AND(reg) r_A &= (reg); \
|
||||
r_F = FLAG_H | sz53p_table[r_A]
|
||||
|
||||
#define OR(reg) r_A |= (reg); \
|
||||
r_F = sz53p_table[r_A]
|
||||
|
||||
#define XOR(reg) r_A ^= (reg); \
|
||||
r_F = sz53p_table[r_A]
|
||||
|
||||
#define AND_mem(raddress) r_opl = Z80ReadMem(raddress); \
|
||||
r_A &= (r_opl); \
|
||||
r_F = FLAG_H | sz53p_table[r_A]
|
||||
|
||||
#define OR_mem(raddress) r_opl = Z80ReadMem(raddress); \
|
||||
r_A |= (r_opl); \
|
||||
r_F = sz53p_table[r_A]
|
||||
|
||||
#define XOR_mem(raddress) r_opl = Z80ReadMem(raddress); \
|
||||
r_A ^= (r_opl); \
|
||||
r_F = sz53p_table[r_A]
|
||||
|
||||
#define ADD(val) tempword = r_A + (val); \
|
||||
r_oph = ((r_A&0x88)>>3)|(((val)&0x88)>>2) | \
|
||||
( (tempword & 0x88) >> 1 ); \
|
||||
r_A = tempword; \
|
||||
r_F = ( tempword & 0x100 ? FLAG_C : 0 ) | \
|
||||
halfcarry_add_table[ r_oph & 0x07] | \
|
||||
overflow_add_table[ r_oph >> 4] | \
|
||||
sz53_table[r_A]
|
||||
|
||||
#define ADD_WORD(value1,value2) \
|
||||
tempdword = (value1) + (value2); \
|
||||
r_oph = ( ( (value1) & 0x0800 ) >> 11 ) | \
|
||||
( ( (value2) & 0x0800 ) >> 10 ) | \
|
||||
( ( tempdword & 0x0800 ) >> 9 ); \
|
||||
(value1) = tempdword; \
|
||||
r_F = ( r_F & ( FLAG_V | FLAG_Z | FLAG_S ) ) | \
|
||||
( tempdword & 0x10000 ? FLAG_C : 0 ) | \
|
||||
(( tempdword >> 8 ) & ( FLAG_3 | FLAG_5 ) ) | \
|
||||
halfcarry_add_table[r_oph]
|
||||
|
||||
#define ADC(value) \
|
||||
tempword = r_A + (value) + ( r_F & FLAG_C ); \
|
||||
r_oph = ( (r_A & 0x88) >> 3 ) | ( ( (value) & 0x88 ) >> 2 ) |\
|
||||
( (tempword & 0x88) >> 1 ); \
|
||||
r_A = tempword; \
|
||||
r_F = ( tempword & 0x100 ? FLAG_C : 0 ) | \
|
||||
halfcarry_add_table[r_oph & 0x07] | \
|
||||
overflow_add_table[r_oph >> 4] | \
|
||||
sz53_table[r_A]
|
||||
|
||||
#define ADC_WORD(value) \
|
||||
tempdword= r_HL + (value) + ( r_F & FLAG_C ); \
|
||||
r_oph = ( ( r_HL & 0x8800 ) >> 11 ) | \
|
||||
( ( (value) & 0x8800 ) >> 10 ) | \
|
||||
( ( tempdword & 0x8800 ) >> 9 ); \
|
||||
r_HL = tempdword; \
|
||||
r_F = ( tempdword & 0x10000 ? FLAG_C : 0 )| \
|
||||
overflow_add_table[r_oph >> 4] | \
|
||||
( r_H & ( FLAG_3 | FLAG_5 | FLAG_S ) ) | \
|
||||
halfcarry_add_table[ r_oph & 0x0f ]| \
|
||||
( r_HL ? 0 : FLAG_Z )
|
||||
|
||||
#define SUB(value) \
|
||||
tempword = r_A - (value);\
|
||||
r_opl = ( (r_A & 0x88) >> 3 ) | \
|
||||
( ( (value) & 0x88 ) >> 2 ) | \
|
||||
( (tempword & 0x88) >> 1 ); \
|
||||
r_A = tempword; \
|
||||
r_F = ( tempword & 0x100 ? FLAG_C : 0 ) | FLAG_N | \
|
||||
halfcarry_sub_table[r_opl & 0x07] | \
|
||||
overflow_sub_table[r_opl >> 4] | \
|
||||
sz53_table[r_A]
|
||||
|
||||
#define SBC(value) \
|
||||
tempword = r_A - (value) - ( r_F & FLAG_C ); \
|
||||
r_opl = ( (r_A & 0x88) >> 3 ) | \
|
||||
( ( (value) & 0x88 ) >> 2 ) | \
|
||||
( (tempword & 0x88) >> 1 ); \
|
||||
r_A = tempword; \
|
||||
r_F = ( tempword & 0x100 ? FLAG_C : 0 ) | FLAG_N | \
|
||||
halfcarry_sub_table[r_opl & 0x07] | \
|
||||
overflow_sub_table[r_opl >> 4] | \
|
||||
sz53_table[r_A]
|
||||
|
||||
|
||||
#define SBC_WORD(Rg) \
|
||||
tempword=r_F & C_FLAG; r_op=(r_HL-Rg-tempword)&0xFFFF; \
|
||||
r_F= \
|
||||
N_FLAG| \
|
||||
(((long)r_HL-(long)Rg-(long)tempword)&0x10000? C_FLAG:0)| \
|
||||
((r_HL^Rg)&(r_HL^r_op)&0x8000? O_FLAG:0)| \
|
||||
((r_HL^Rg^r_op)&0x1000? H_FLAG:0)| \
|
||||
(r_op? 0:Z_FLAG)|(r_oph&S_FLAG); \
|
||||
r_HL=r_op
|
||||
|
||||
#define CP(value) \
|
||||
tempword = r_A - (value);\
|
||||
r_opl = ( (r_A & 0x88) >> 3 ) | ( ( (value) & 0x88 ) >> 2 ) | \
|
||||
( (tempword & 0x88) >> 1 ); \
|
||||
r_F = ( tempword & 0x100 ? FLAG_C : ( tempword ? 0 : FLAG_Z ) ) | FLAG_N |\
|
||||
halfcarry_sub_table[r_opl & 0x07] | \
|
||||
overflow_sub_table[r_opl >> 4] | \
|
||||
( value & ( FLAG_3 | FLAG_5 ) ) | \
|
||||
( tempword & FLAG_S )
|
||||
|
||||
#define NEG_A() r_opl = r_A; r_A=0; SUB(r_opl)
|
||||
|
||||
/*--- MISC operations -----------------------------------------------*/
|
||||
#define IN(reg,port) (reg)=Z80InPort((port)); \
|
||||
r_F = ( r_F & FLAG_C) | sz53p_table[(reg)]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
/*====================================================================/*
|
||||
opcodes_cb.c -> This file executes the CB PREFIX opcodes.
|
||||
|
||||
When you find the CB opcode, it means that you must fetch another
|
||||
byte from memory and treat it as a new opcode with different
|
||||
meaning than the single-byte opcodes. This is a common way to extend
|
||||
the number of opcodes (8 bits of instruction word = just 256 opcodes)
|
||||
and it's called an OPCODE PREFIX (now we have another 256 new opcodes
|
||||
by using this trick).
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
=====================================================================*/
|
||||
|
||||
/* 8 clock cycles minimum = CB opcode = 4+4 */
|
||||
|
||||
opcode = Z80ReadMem( r_PC );
|
||||
r_PC++;
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
|
||||
case RLC_B : RLC(r_B); AddCycles( 4+4 ); break;
|
||||
case RLC_C : RLC(r_C); AddCycles( 4+4 ); break;
|
||||
case RLC_D : RLC(r_D); AddCycles( 4+4 ); break;
|
||||
case RLC_E : RLC(r_E); AddCycles( 4+4 ); break;
|
||||
case RLC_H : RLC(r_H); AddCycles( 4+4 ); break;
|
||||
case RLC_L : RLC(r_L); AddCycles( 4+4 ); break;
|
||||
case RLC_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
RLC(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+4+3+3+1 ); break;
|
||||
case RLC_A : RLC(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RRC_B : RRC(r_B); AddCycles( 4+4 ); break;
|
||||
case RRC_C : RRC(r_C); AddCycles( 4+4 ); break;
|
||||
case RRC_D : RRC(r_D); AddCycles( 4+4 ); break;
|
||||
case RRC_E : RRC(r_E); AddCycles( 4+4 ); break;
|
||||
case RRC_H : RRC(r_H); AddCycles( 4+4 ); break;
|
||||
case RRC_L : RRC(r_L); AddCycles( 4+4 ); break;
|
||||
case RRC_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
RRC(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+4+3+3+1 ); break;
|
||||
case RRC_A : RRC(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RL_B : RL(r_B); AddCycles( 4+4 ); break;
|
||||
case RL_C : RL(r_C); AddCycles( 4+4 ); break;
|
||||
case RL_D : RL(r_D); AddCycles( 4+4 ); break;
|
||||
case RL_E : RL(r_E); AddCycles( 4+4 ); break;
|
||||
case RL_H : RL(r_H); AddCycles( 4+4 ); break;
|
||||
case RL_L : RL(r_L); AddCycles( 4+4 ); break;
|
||||
case RL_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
RL(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+4+3+3+1 ); break;
|
||||
case RL_A : RL(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RR_B : RR(r_B); AddCycles( 4+4 ); break;
|
||||
case RR_C : RR(r_C); AddCycles( 4+4 ); break;
|
||||
case RR_D : RR(r_D); AddCycles( 4+4 ); break;
|
||||
case RR_E : RR(r_E); AddCycles( 4+4 ); break;
|
||||
case RR_H : RR(r_H); AddCycles( 4+4 ); break;
|
||||
case RR_L : RR(r_L); AddCycles( 4+4 ); break;
|
||||
case RR_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
RR(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+4+3+3+1 ); break;
|
||||
case RR_A : RR(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SLA_B : SLA(r_B); AddCycles( 4+4 ); break;
|
||||
case SLA_C : SLA(r_C); AddCycles( 4+4 ); break;
|
||||
case SLA_D : SLA(r_D); AddCycles( 4+4 ); break;
|
||||
case SLA_E : SLA(r_E); AddCycles( 4+4 ); break;
|
||||
case SLA_H : SLA(r_H); AddCycles( 4+4 ); break;
|
||||
case SLA_L : SLA(r_L); AddCycles( 4+4 ); break;
|
||||
case SLA_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
SLA(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+4+3+3+1 ); break;
|
||||
case SLA_A : SLA(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SRA_B : SRA(r_B); AddCycles( 4+4 ); break;
|
||||
case SRA_C : SRA(r_C); AddCycles( 4+4 ); break;
|
||||
case SRA_D : SRA(r_D); AddCycles( 4+4 ); break;
|
||||
case SRA_E : SRA(r_E); AddCycles( 4+4 ); break;
|
||||
case SRA_H : SRA(r_H); AddCycles( 4+4 ); break;
|
||||
case SRA_L : SRA(r_L); AddCycles( 4+4 ); break;
|
||||
case SRA_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
SRA(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+4+3+3+1 ); break;
|
||||
case SRA_A : SRA(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SLL_B : SLL(r_B); AddCycles( 4+4 ); break;
|
||||
case SLL_C : SLL(r_C); AddCycles( 4+4 ); break;
|
||||
case SLL_D : SLL(r_D); AddCycles( 4+4 ); break;
|
||||
case SLL_E : SLL(r_E); AddCycles( 4+4 ); break;
|
||||
case SLL_H : SLL(r_H); AddCycles( 4+4 ); break;
|
||||
case SLL_L : SLL(r_L); AddCycles( 4+4 ); break;
|
||||
case SLL_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
SLL(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+4+3+3+1 ); break;
|
||||
case SLL_A : SLL(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SRL_B : SRL(r_B); AddCycles( 4+4 ); break;
|
||||
case SRL_C : SRL(r_C); AddCycles( 4+4 ); break;
|
||||
case SRL_D : SRL(r_D); AddCycles( 4+4 ); break;
|
||||
case SRL_E : SRL(r_E); AddCycles( 4+4 ); break;
|
||||
case SRL_H : SRL(r_H); AddCycles( 4+4 ); break;
|
||||
case SRL_L : SRL(r_L); AddCycles( 4+4 ); break;
|
||||
case SRL_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
SRL(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+4+3+3+1 ); break;
|
||||
case SRL_A : SRL(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case BIT_0_B : BIT_BIT(0, r_B); AddCycles( 4+4 ); break;
|
||||
case BIT_0_C : BIT_BIT(0, r_C); AddCycles( 4+4 ); break;
|
||||
case BIT_0_D : BIT_BIT(0, r_D); AddCycles( 4+4 ); break;
|
||||
case BIT_0_E : BIT_BIT(0, r_E); AddCycles( 4+4 ); break;
|
||||
case BIT_0_H : BIT_BIT(0, r_H); AddCycles( 4+4 ); break;
|
||||
case BIT_0_L : BIT_BIT(0, r_L); AddCycles( 4+4 ); break;
|
||||
case BIT_0_xHL : BIT_mem_BIT(0, r_HL); AddCycles( 12 ); break;
|
||||
case BIT_0_A : BIT_BIT(0, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case BIT_1_B : BIT_BIT(1, r_B); AddCycles( 4+4 ); break;
|
||||
case BIT_1_C : BIT_BIT(1, r_C); AddCycles( 4+4 ); break;
|
||||
case BIT_1_D : BIT_BIT(1, r_D); AddCycles( 4+4 ); break;
|
||||
case BIT_1_E : BIT_BIT(1, r_E); AddCycles( 4+4 ); break;
|
||||
case BIT_1_H : BIT_BIT(1, r_H); AddCycles( 4+4 ); break;
|
||||
case BIT_1_L : BIT_BIT(1, r_L); AddCycles( 4+4 ); break;
|
||||
case BIT_1_xHL : BIT_mem_BIT(1, r_HL); AddCycles( 12 ); break;
|
||||
case BIT_1_A : BIT_BIT(1, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case BIT_2_B : BIT_BIT(2, r_B); AddCycles( 4+4 ); break;
|
||||
case BIT_2_C : BIT_BIT(2, r_C); AddCycles( 4+4 ); break;
|
||||
case BIT_2_D : BIT_BIT(2, r_D); AddCycles( 4+4 ); break;
|
||||
case BIT_2_E : BIT_BIT(2, r_E); AddCycles( 4+4 ); break;
|
||||
case BIT_2_H : BIT_BIT(2, r_H); AddCycles( 4+4 ); break;
|
||||
case BIT_2_L : BIT_BIT(2, r_L); AddCycles( 4+4 ); break;
|
||||
case BIT_2_xHL : BIT_mem_BIT(2, r_HL); AddCycles( 12 ); break;
|
||||
case BIT_2_A : BIT_BIT(2, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case BIT_3_B : BIT_BIT(3, r_B); AddCycles( 4+4 ); break;
|
||||
case BIT_3_C : BIT_BIT(3, r_C); AddCycles( 4+4 ); break;
|
||||
case BIT_3_D : BIT_BIT(3, r_D); AddCycles( 4+4 ); break;
|
||||
case BIT_3_E : BIT_BIT(3, r_E); AddCycles( 4+4 ); break;
|
||||
case BIT_3_H : BIT_BIT(3, r_H); AddCycles( 4+4 ); break;
|
||||
case BIT_3_L : BIT_BIT(3, r_L); AddCycles( 4+4 ); break;
|
||||
case BIT_3_xHL : BIT_mem_BIT(3, r_HL); AddCycles( 12 ); break;
|
||||
case BIT_3_A : BIT_BIT(3, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case BIT_4_B : BIT_BIT(4, r_B); AddCycles( 4+4 ); break;
|
||||
case BIT_4_C : BIT_BIT(4, r_C); AddCycles( 4+4 ); break;
|
||||
case BIT_4_D : BIT_BIT(4, r_D); AddCycles( 4+4 ); break;
|
||||
case BIT_4_E : BIT_BIT(4, r_E); AddCycles( 4+4 ); break;
|
||||
case BIT_4_H : BIT_BIT(4, r_H); AddCycles( 4+4 ); break;
|
||||
case BIT_4_L : BIT_BIT(4, r_L); AddCycles( 4+4 ); break;
|
||||
case BIT_4_xHL : BIT_mem_BIT(4, r_HL); AddCycles( 12 ); break;
|
||||
case BIT_4_A : BIT_BIT(4, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case BIT_5_B : BIT_BIT(5, r_B); AddCycles( 4+4 ); break;
|
||||
case BIT_5_C : BIT_BIT(5, r_C); AddCycles( 4+4 ); break;
|
||||
case BIT_5_D : BIT_BIT(5, r_D); AddCycles( 4+4 ); break;
|
||||
case BIT_5_E : BIT_BIT(5, r_E); AddCycles( 4+4 ); break;
|
||||
case BIT_5_H : BIT_BIT(5, r_H); AddCycles( 4+4 ); break;
|
||||
case BIT_5_L : BIT_BIT(5, r_L); AddCycles( 4+4 ); break;
|
||||
case BIT_5_xHL : BIT_mem_BIT(5, r_HL); AddCycles( 12 ); break;
|
||||
case BIT_5_A : BIT_BIT(5, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case BIT_6_B : BIT_BIT(6, r_B); AddCycles( 4+4 ); break;
|
||||
case BIT_6_C : BIT_BIT(6, r_C); AddCycles( 4+4 ); break;
|
||||
case BIT_6_D : BIT_BIT(6, r_D); AddCycles( 4+4 ); break;
|
||||
case BIT_6_E : BIT_BIT(6, r_E); AddCycles( 4+4 ); break;
|
||||
case BIT_6_H : BIT_BIT(6, r_H); AddCycles( 4+4 ); break;
|
||||
case BIT_6_L : BIT_BIT(6, r_L); AddCycles( 4+4 ); break;
|
||||
case BIT_6_xHL : BIT_mem_BIT(6, r_HL); AddCycles( 12 ); break;
|
||||
case BIT_6_A : BIT_BIT(6, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case BIT_7_B : BIT_BIT7(r_B); AddCycles( 4+4 ); break;
|
||||
case BIT_7_C : BIT_BIT7(r_C); AddCycles( 4+4 ); break;
|
||||
case BIT_7_D : BIT_BIT7(r_D); AddCycles( 4+4 ); break;
|
||||
case BIT_7_E : BIT_BIT7(r_E); AddCycles( 4+4 ); break;
|
||||
case BIT_7_H : BIT_BIT7(r_H); AddCycles( 4+4 ); break;
|
||||
case BIT_7_L : BIT_BIT7(r_L); AddCycles( 4+4 ); break;
|
||||
case BIT_7_xHL : BIT_mem_BIT7(r_HL); AddCycles( 12 ); break;
|
||||
case BIT_7_A : BIT_BIT7(r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RES_0_B : BIT_RES(0, r_B); AddCycles( 4+4 ); break;
|
||||
case RES_0_C : BIT_RES(0, r_C); AddCycles( 4+4 ); break;
|
||||
case RES_0_D : BIT_RES(0, r_D); AddCycles( 4+4 ); break;
|
||||
case RES_0_E : BIT_RES(0, r_E); AddCycles( 4+4 ); break;
|
||||
case RES_0_H : BIT_RES(0, r_H); AddCycles( 4+4 ); break;
|
||||
case RES_0_L : BIT_RES(0, r_L); AddCycles( 4+4 ); break;
|
||||
case RES_0_xHL : BIT_mem_RES(0, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case RES_0_A : BIT_RES(0, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RES_1_B : BIT_RES(1, r_B); AddCycles( 4+4 ); break;
|
||||
case RES_1_C : BIT_RES(1, r_C); AddCycles( 4+4 ); break;
|
||||
case RES_1_D : BIT_RES(1, r_D); AddCycles( 4+4 ); break;
|
||||
case RES_1_E : BIT_RES(1, r_E); AddCycles( 4+4 ); break;
|
||||
case RES_1_H : BIT_RES(1, r_H); AddCycles( 4+4 ); break;
|
||||
case RES_1_L : BIT_RES(1, r_L); AddCycles( 4+4 ); break;
|
||||
case RES_1_xHL : BIT_mem_RES(1, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case RES_1_A : BIT_RES(1, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RES_2_B : BIT_RES(2, r_B); AddCycles( 4+4 ); break;
|
||||
case RES_2_C : BIT_RES(2, r_C); AddCycles( 4+4 ); break;
|
||||
case RES_2_D : BIT_RES(2, r_D); AddCycles( 4+4 ); break;
|
||||
case RES_2_E : BIT_RES(2, r_E); AddCycles( 4+4 ); break;
|
||||
case RES_2_H : BIT_RES(2, r_H); AddCycles( 4+4 ); break;
|
||||
case RES_2_L : BIT_RES(2, r_L); AddCycles( 4+4 ); break;
|
||||
case RES_2_xHL : BIT_mem_RES(2, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case RES_2_A : BIT_RES(2, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RES_3_B : BIT_RES(3, r_B); AddCycles( 4+4 ); break;
|
||||
case RES_3_C : BIT_RES(3, r_C); AddCycles( 4+4 ); break;
|
||||
case RES_3_D : BIT_RES(3, r_D); AddCycles( 4+4 ); break;
|
||||
case RES_3_E : BIT_RES(3, r_E); AddCycles( 4+4 ); break;
|
||||
case RES_3_H : BIT_RES(3, r_H); AddCycles( 4+4 ); break;
|
||||
case RES_3_L : BIT_RES(3, r_L); AddCycles( 4+4 ); break;
|
||||
case RES_3_xHL : BIT_mem_RES(3, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case RES_3_A : BIT_RES(3, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RES_4_B : BIT_RES(4, r_B); AddCycles( 4+4 ); break;
|
||||
case RES_4_C : BIT_RES(4, r_C); AddCycles( 4+4 ); break;
|
||||
case RES_4_D : BIT_RES(4, r_D); AddCycles( 4+4 ); break;
|
||||
case RES_4_E : BIT_RES(4, r_E); AddCycles( 4+4 ); break;
|
||||
case RES_4_H : BIT_RES(4, r_H); AddCycles( 4+4 ); break;
|
||||
case RES_4_L : BIT_RES(4, r_L); AddCycles( 4+4 ); break;
|
||||
case RES_4_xHL : BIT_mem_RES(4, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case RES_4_A : BIT_RES(4, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RES_5_B : BIT_RES(5, r_B); AddCycles( 4+4 ); break;
|
||||
case RES_5_C : BIT_RES(5, r_C); AddCycles( 4+4 ); break;
|
||||
case RES_5_D : BIT_RES(5, r_D); AddCycles( 4+4 ); break;
|
||||
case RES_5_E : BIT_RES(5, r_E); AddCycles( 4+4 ); break;
|
||||
case RES_5_H : BIT_RES(5, r_H); AddCycles( 4+4 ); break;
|
||||
case RES_5_L : BIT_RES(5, r_L); AddCycles( 4+4 ); break;
|
||||
case RES_5_xHL : BIT_mem_RES(5, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case RES_5_A : BIT_RES(5, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RES_6_B : BIT_RES(6, r_B); AddCycles( 4+4 ); break;
|
||||
case RES_6_C : BIT_RES(6, r_C); AddCycles( 4+4 ); break;
|
||||
case RES_6_D : BIT_RES(6, r_D); AddCycles( 4+4 ); break;
|
||||
case RES_6_E : BIT_RES(6, r_E); AddCycles( 4+4 ); break;
|
||||
case RES_6_H : BIT_RES(6, r_H); AddCycles( 4+4 ); break;
|
||||
case RES_6_L : BIT_RES(6, r_L); AddCycles( 4+4 ); break;
|
||||
case RES_6_xHL : BIT_mem_RES(6, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case RES_6_A : BIT_RES(6, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case RES_7_B : BIT_RES(7, r_B); AddCycles( 4+4 ); break;
|
||||
case RES_7_C : BIT_RES(7, r_C); AddCycles( 4+4 ); break;
|
||||
case RES_7_D : BIT_RES(7, r_D); AddCycles( 4+4 ); break;
|
||||
case RES_7_E : BIT_RES(7, r_E); AddCycles( 4+4 ); break;
|
||||
case RES_7_H : BIT_RES(7, r_H); AddCycles( 4+4 ); break;
|
||||
case RES_7_L : BIT_RES(7, r_L); AddCycles( 4+4 ); break;
|
||||
case RES_7_xHL : BIT_mem_RES(7, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case RES_7_A : BIT_RES(7, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SET_0_B : BIT_SET(0, r_B); AddCycles( 4+4 ); break;
|
||||
case SET_0_C : BIT_SET(0, r_C); AddCycles( 4+4 ); break;
|
||||
case SET_0_D : BIT_SET(0, r_D); AddCycles( 4+4 ); break;
|
||||
case SET_0_E : BIT_SET(0, r_E); AddCycles( 4+4 ); break;
|
||||
case SET_0_H : BIT_SET(0, r_H); AddCycles( 4+4 ); break;
|
||||
case SET_0_L : BIT_SET(0, r_L); AddCycles( 4+4 ); break;
|
||||
case SET_0_xHL : BIT_mem_SET(0, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case SET_0_A : BIT_SET(0, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SET_1_B : BIT_SET(1, r_B); AddCycles( 4+4 ); break;
|
||||
case SET_1_C : BIT_SET(1, r_C); AddCycles( 4+4 ); break;
|
||||
case SET_1_D : BIT_SET(1, r_D); AddCycles( 4+4 ); break;
|
||||
case SET_1_E : BIT_SET(1, r_E); AddCycles( 4+4 ); break;
|
||||
case SET_1_H : BIT_SET(1, r_H); AddCycles( 4+4 ); break;
|
||||
case SET_1_L : BIT_SET(1, r_L); AddCycles( 4+4 ); break;
|
||||
case SET_1_xHL : BIT_mem_SET(1, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case SET_1_A : BIT_SET(1, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SET_2_B : BIT_SET(2, r_B); AddCycles( 4+4 ); break;
|
||||
case SET_2_C : BIT_SET(2, r_C); AddCycles( 4+4 ); break;
|
||||
case SET_2_D : BIT_SET(2, r_D); AddCycles( 4+4 ); break;
|
||||
case SET_2_E : BIT_SET(2, r_E); AddCycles( 4+4 ); break;
|
||||
case SET_2_H : BIT_SET(2, r_H); AddCycles( 4+4 ); break;
|
||||
case SET_2_L : BIT_SET(2, r_L); AddCycles( 4+4 ); break;
|
||||
case SET_2_xHL : BIT_mem_SET(2, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case SET_2_A : BIT_SET(2, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SET_3_B : BIT_SET(3, r_B); AddCycles( 4+4 ); break;
|
||||
case SET_3_C : BIT_SET(3, r_C); AddCycles( 4+4 ); break;
|
||||
case SET_3_D : BIT_SET(3, r_D); AddCycles( 4+4 ); break;
|
||||
case SET_3_E : BIT_SET(3, r_E); AddCycles( 4+4 ); break;
|
||||
case SET_3_H : BIT_SET(3, r_H); AddCycles( 4+4 ); break;
|
||||
case SET_3_L : BIT_SET(3, r_L); AddCycles( 4+4 ); break;
|
||||
case SET_3_xHL : BIT_mem_SET(3, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case SET_3_A : BIT_SET(3, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SET_4_B : BIT_SET(4, r_B); AddCycles( 4+4 ); break;
|
||||
case SET_4_C : BIT_SET(4, r_C); AddCycles( 4+4 ); break;
|
||||
case SET_4_D : BIT_SET(4, r_D); AddCycles( 4+4 ); break;
|
||||
case SET_4_E : BIT_SET(4, r_E); AddCycles( 4+4 ); break;
|
||||
case SET_4_H : BIT_SET(4, r_H); AddCycles( 4+4 ); break;
|
||||
case SET_4_L : BIT_SET(4, r_L); AddCycles( 4+4 ); break;
|
||||
case SET_4_xHL : BIT_mem_SET(4, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case SET_4_A : BIT_SET(4, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SET_5_B : BIT_SET(5, r_B); AddCycles( 4+4 ); break;
|
||||
case SET_5_C : BIT_SET(5, r_C); AddCycles( 4+4 ); break;
|
||||
case SET_5_D : BIT_SET(5, r_D); AddCycles( 4+4 ); break;
|
||||
case SET_5_E : BIT_SET(5, r_E); AddCycles( 4+4 ); break;
|
||||
case SET_5_H : BIT_SET(5, r_H); AddCycles( 4+4 ); break;
|
||||
case SET_5_L : BIT_SET(5, r_L); AddCycles( 4+4 ); break;
|
||||
case SET_5_xHL : BIT_mem_SET(5, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case SET_5_A : BIT_SET(5, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SET_6_B : BIT_SET(6, r_B); AddCycles( 4+4 ); break;
|
||||
case SET_6_C : BIT_SET(6, r_C); AddCycles( 4+4 ); break;
|
||||
case SET_6_D : BIT_SET(6, r_D); AddCycles( 4+4 ); break;
|
||||
case SET_6_E : BIT_SET(6, r_E); AddCycles( 4+4 ); break;
|
||||
case SET_6_H : BIT_SET(6, r_H); AddCycles( 4+4 ); break;
|
||||
case SET_6_L : BIT_SET(6, r_L); AddCycles( 4+4 ); break;
|
||||
case SET_6_xHL : BIT_mem_SET(6, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case SET_6_A : BIT_SET(6, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
case SET_7_B : BIT_SET(7, r_B); AddCycles( 4+4 ); break;
|
||||
case SET_7_C : BIT_SET(7, r_C); AddCycles( 4+4 ); break;
|
||||
case SET_7_D : BIT_SET(7, r_D); AddCycles( 4+4 ); break;
|
||||
case SET_7_E : BIT_SET(7, r_E); AddCycles( 4+4 ); break;
|
||||
case SET_7_H : BIT_SET(7, r_H); AddCycles( 4+4 ); break;
|
||||
case SET_7_L : BIT_SET(7, r_L); AddCycles( 4+4 ); break;
|
||||
case SET_7_xHL : BIT_mem_SET(7, r_HL); AddCycles( 4+4+7 ); break;
|
||||
case SET_7_A : BIT_SET(7, r_A); AddCycles( 4+4 ); break;
|
||||
|
||||
default:
|
||||
// exit(1);
|
||||
///!!! if( regs->DecodingErrors )
|
||||
///!!! printf("z80 core: Unknown instruction: CB %02Xh at PC=%04Xh.\n",
|
||||
///!!! Z80ReadMem(r_PC-1), r_PC-2 );
|
||||
break;
|
||||
}
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
/*====================================================================/*
|
||||
opcodes_dd_fd.c -> This file executes the DD/FD PREFIX opcodes.
|
||||
|
||||
The DD prefix "creates" some new instructions by changing HL to IX
|
||||
on the opcode defined by the next byte on memory.
|
||||
|
||||
The FD prefix "creates" some new instructions by changing HL to IY
|
||||
on the opcode defined by the next byte on memory.
|
||||
|
||||
Change the REGISTER variable to IX or HY before including this file.
|
||||
Something like:
|
||||
|
||||
#define REGISTER regs->IX
|
||||
#include "op_dd_fd.c"
|
||||
#undef REGISTER
|
||||
|
||||
On this code, this REGISTER variable is used as REGISTER.W or
|
||||
REGISTER.B.h and REGISTER.B.l ...
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
=====================================================================*/
|
||||
|
||||
/* 8 clock cycles minimum = DD opcode = FD opcode = 4 + 4 */
|
||||
|
||||
#define REG REGISTER.W
|
||||
#define REGL REGISTER.B.l
|
||||
#define REGH REGISTER.B.h
|
||||
|
||||
opcode = Z80ReadMem( r_PC );
|
||||
r_PC++;
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
case ADD_IXY_BC : ADD_WORD(REG, r_BC); AddCycles( 4+4+7 ); break;
|
||||
case ADD_IXY_DE : ADD_WORD(REG, r_DE); AddCycles( 4+4+7 ); break;
|
||||
case ADD_IXY_SP : ADD_WORD(REG, r_SP); AddCycles( 4+4+7 ); break;
|
||||
case ADD_IXY_IXY : ADD_WORD(REG, REG); AddCycles( 4+4+7 ); break;
|
||||
case DEC_IXY : REG--; AddCycles( 4+4+2 ); break;
|
||||
case INC_IXY : REG++; AddCycles( 4+4 ); break;
|
||||
|
||||
case JP_IXY : r_PC = REG; AddCycles( 4+4 );break;
|
||||
case LD_SP_IXY : r_SP = REG; AddCycles( 4+4+2 ); break;
|
||||
|
||||
case PUSH_IXY : PUSH_IXYr(); AddCycles( 4+4+3+3+1 ); break;
|
||||
case POP_IXY : POP_IXYr(); AddCycles( 4+4+3+3 ); break;
|
||||
|
||||
case EX_IXY_xSP : r_meml = Z80ReadMem(r_SP);
|
||||
r_memh = Z80ReadMem(r_SP+1);
|
||||
Z80WriteMem( r_SP, REGL, regs );
|
||||
Z80WriteMem( r_SP+1, REGH, regs );
|
||||
REGL=r_meml; REGH=r_memh;
|
||||
AddCycles( 4+4+3+3+3+3+3 ); break;
|
||||
|
||||
case LD_A_xIXY : r_A = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_B_xIXY : r_B = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_C_xIXY : r_C = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_D_xIXY : r_D = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_E_xIXY : r_E = Z80ReadMem( REG+ ((offset) Z80ReadMem(r_PC)) );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
|
||||
case LD_xIXY_A : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_A, regs );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_xIXY_B : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_B, regs );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_xIXY_C : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_C, regs );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_xIXY_D : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_D, regs );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_xIXY_E : Z80WriteMem( REG+(offset)Z80ReadMem(r_PC), r_E, regs );
|
||||
r_PC++; AddCycles( 4+3+3+3+3+3 ); break;
|
||||
|
||||
case INC_xIXY : r_mem = REG+(offset)Z80ReadMem(r_PC);
|
||||
r_PC++;
|
||||
tmpreg.B.l = Z80ReadMem(r_mem);
|
||||
INC(tmpreg.B.l);
|
||||
Z80WriteMem(r_mem, tmpreg.B.l, regs );
|
||||
AddCycles( 4+3+3 + 3+3+3+ 3+1); break;
|
||||
case DEC_xIXY : r_mem = REG+(offset)Z80ReadMem(r_PC);
|
||||
r_PC++;
|
||||
tmpreg.B.l = Z80ReadMem(r_mem);
|
||||
DEC(tmpreg.B.l);
|
||||
Z80WriteMem(r_mem, tmpreg.B.l, regs );
|
||||
AddCycles( 4+3+3 + 3+3+3+ 3+1); break;
|
||||
|
||||
case ADC_xIXY : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC)); r_PC++;
|
||||
ADC(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case SBC_xIXY : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
|
||||
r_PC++;
|
||||
SBC(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case ADD_xIXY : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
|
||||
r_PC++;
|
||||
ADD(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case SUB_xIXY : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
|
||||
r_PC++;
|
||||
SUB(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case AND_xIXY : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
|
||||
r_PC++;
|
||||
AND(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case OR_xIXY : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
|
||||
r_PC++;
|
||||
OR(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case XOR_xIXY : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
|
||||
r_PC++;
|
||||
XOR(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
|
||||
|
||||
case CP_xIXY : r_meml = Z80ReadMem(REG+(offset)Z80ReadMem(r_PC));
|
||||
r_PC++;
|
||||
CP(r_meml); AddCycles( 4+3+3+3+3+3 ); break;
|
||||
|
||||
case LD_IXY_NN : REGL = Z80ReadMem(r_PC); r_PC++;
|
||||
REGH = Z80ReadMem(r_PC); r_PC++;
|
||||
AddCycles( 4+1+3+3+3 ); break;
|
||||
|
||||
case LD_xIXY_N : r_mem = REG + (offset) Z80ReadMem(r_PC); r_PC++;
|
||||
Z80WriteMem( r_mem, Z80ReadMem(r_PC), regs ); r_PC++;
|
||||
AddCycles( 4+3+3+3+3+3 ); break;
|
||||
|
||||
case LD_IXY_xNN : LOAD_rr_nn(REG);
|
||||
AddCycles( 4+3+3+3+3+3+1 ); break;
|
||||
|
||||
case LD_xNN_IXY : STORE_nn_rr(REG);
|
||||
AddCycles( 4+3+3+ 3+3+3+1 ); break;
|
||||
|
||||
|
||||
/* some undocumented opcodes: may be wrong: */
|
||||
case LD_A_IXYh : r_A = REGH; AddCycles(4+4); break;
|
||||
case LD_A_IXYl : r_A = REGL; AddCycles(4+4); break;
|
||||
case LD_B_IXYh : r_B = REGH; AddCycles(4+4); break;
|
||||
case LD_B_IXYl : r_B = REGL; AddCycles(4+4); break;
|
||||
case LD_C_IXYh : r_C = REGH; AddCycles(4+4); break;
|
||||
case LD_C_IXYl : r_C = REGL; AddCycles(4+4); break;
|
||||
case LD_D_IXYh : r_D = REGH; AddCycles(4+4); break;
|
||||
case LD_D_IXYl : r_D = REGL; AddCycles(4+4); break;
|
||||
case LD_E_IXYh : r_E = REGH; AddCycles(4+4); break;
|
||||
case LD_E_IXYl : r_E = REGL; AddCycles(4+4); break;
|
||||
case LD_IXYh_A : REGH = r_A; AddCycles(4+4); break;
|
||||
case LD_IXYh_B : REGH = r_B; AddCycles(4+4); break;
|
||||
case LD_IXYh_C : REGH = r_C; AddCycles(4+4); break;
|
||||
case LD_IXYh_D : REGH = r_D; AddCycles(4+4); break;
|
||||
case LD_IXYh_E : REGH = r_E; AddCycles(4+4); break;
|
||||
case LD_IXYh_IXYh : AddCycles(4+4); break;
|
||||
case LD_IXYh_IXYl : REGH = REGL; AddCycles(4+4); break;
|
||||
case LD_IXYl_A : REGL = r_A; AddCycles(4+4); break;
|
||||
case LD_IXYl_B : REGL = r_B; AddCycles(4+4); break;
|
||||
case LD_IXYl_C : REGL = r_C; AddCycles(4+4); break;
|
||||
case LD_IXYl_D : REGL = r_D; AddCycles(4+4); break;
|
||||
case LD_IXYl_E : REGL = r_E; AddCycles(4+4); break;
|
||||
case LD_IXYl_IXYh : REGL = REGH; AddCycles(4+4); break;
|
||||
case LD_IXYl_IXYl : AddCycles(4+4); break;
|
||||
case LD_IXYh_N : REGH = Z80ReadMem(r_PC); r_PC++;
|
||||
AddCycles(4+4+3); break;
|
||||
case LD_IXYl_N : REGL = Z80ReadMem(r_PC); r_PC++;
|
||||
AddCycles(4+4+3); break;
|
||||
|
||||
|
||||
case ADD_IXYh : ADD(REGH); AddCycles(4+4); break;
|
||||
case ADD_IXYl : ADD(REGL); AddCycles(4+4); break;
|
||||
case ADC_IXYh : ADC(REGH); AddCycles(4+4); break;
|
||||
case ADC_IXYl : ADC(REGL); AddCycles(4+4); break;
|
||||
case SUB_IXYh : SUB(REGH); AddCycles(4+4); break;
|
||||
case SUB_IXYl : SUB(REGL); AddCycles(4+4); break;
|
||||
case SBC_IXYh : SBC(REGH); AddCycles(4+4); break;
|
||||
case SBC_IXYl : SBC(REGL); AddCycles(4+4); break;
|
||||
case AND_IXYh : AND(REGH); AddCycles(4+4); break;
|
||||
case AND_IXYl : AND(REGL); AddCycles(4+4); break;
|
||||
case XOR_IXYh : XOR(REGH); AddCycles(4+4); break;
|
||||
case XOR_IXYl : XOR(REGL); AddCycles(4+4); break;
|
||||
case OR_IXYh : OR(REGH); AddCycles(4+4); break;
|
||||
case OR_IXYl : OR(REGL); AddCycles(4+4); break;
|
||||
case CP_IXYh : CP(REGH); AddCycles(4+4); break;
|
||||
case CP_IXYl : CP(REGL); AddCycles(4+4); break;
|
||||
case INC_IXYh : INC(REGH); AddCycles(4+4); break;
|
||||
case INC_IXYl : INC(REGL); AddCycles(4+4); break;
|
||||
case DEC_IXYh : DEC(REGH); AddCycles(4+4); break;
|
||||
case DEC_IXYl : DEC(REGL); AddCycles(4+4); break;
|
||||
|
||||
case LD_xIXY_H : r_meml =Z80ReadMem(r_PC); r_PC++;
|
||||
Z80WriteMem( REG+(offset)(r_meml), r_H, regs );
|
||||
AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_xIXY_L : r_meml =Z80ReadMem(r_PC); r_PC++;
|
||||
Z80WriteMem( REG+(offset)(r_meml), r_L, regs );
|
||||
AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_H_xIXY : r_meml =Z80ReadMem(r_PC); r_PC++;
|
||||
r_H = Z80ReadMem( REG+(offset)(r_meml));
|
||||
AddCycles( 4+3+3+3+3+3 ); break;
|
||||
case LD_L_xIXY : r_meml =Z80ReadMem(r_PC); r_PC++;
|
||||
r_L = Z80ReadMem( REG+(offset)(r_meml));
|
||||
AddCycles( 4+3+3+3+3+3 ); break;
|
||||
|
||||
case PREFIX_CB:
|
||||
#include "opddfdcb.c"
|
||||
break;
|
||||
|
||||
/*
|
||||
case PREFIX_DD:
|
||||
case PREFIX_FD: AddCycles( 4 );
|
||||
r_PC--; // decode it the next time :)
|
||||
break;
|
||||
*/
|
||||
|
||||
default: AddCycles( 4 );
|
||||
r_PC--; /* decode it the next time :) */
|
||||
SubR(1);
|
||||
|
||||
// exit(1);
|
||||
// if( regs->DecodingErrors )
|
||||
// {
|
||||
// printf("z80 core: Unknown instruction: ");
|
||||
// if ( regs->we_are_on_ddfd == WE_ARE_ON_DD )
|
||||
// printf("DD ");
|
||||
// else
|
||||
// printf("FD ");
|
||||
// printf("%02Xh at PC=%04Xh.\n", Z80ReadMem(r_PC-1), r_PC-2 );
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
#undef REG
|
||||
#undef REGL
|
||||
#undef REGH
|
|
@ -0,0 +1,417 @@
|
|||
/*====================================================================/*
|
||||
opcodes_ed.c -> This file executes the ED opcodes.
|
||||
|
||||
Another prefix that "creates" new instructions. This prefix also
|
||||
introduces some undocumented opcodes that we've tried to include
|
||||
here. Maybe their implementation it's wrong: if you can find any
|
||||
mistake about how we have implemented/interpreted them, please
|
||||
let us know.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
=====================================================================*/
|
||||
|
||||
/* 8 clock cycles minimum = ED opcode = 4 + 4 */
|
||||
|
||||
opcode = Z80ReadMem( r_PC );
|
||||
r_PC++;
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
case LD_BC_xNNe : LOAD_rr_nn(r_BC); AddCycles( 4+4+12 ); break;
|
||||
case LD_DE_xNNe : LOAD_rr_nn(r_DE); AddCycles( 4+4+12 ); break;
|
||||
case LD_HL_xNNe : LOAD_rr_nn(r_HL); AddCycles( 4+4+12 ); break;
|
||||
case LD_SP_xNNe : LOAD_rr_nn(r_SP); AddCycles( 4+4+12 ); break;
|
||||
|
||||
case LD_xNNe_BC : STORE_nn_rr(r_BC); AddCycles( 4+4+12 ); break;
|
||||
case LD_xNNe_DE : STORE_nn_rr(r_DE); AddCycles( 4+4+12 ); break;
|
||||
case LD_xNNe_HL : STORE_nn_rr(r_HL); AddCycles( 4+4+12 ); break;
|
||||
case LD_xNNe_SP : STORE_nn_rr(r_SP); AddCycles( 4+4+12 ); break;
|
||||
|
||||
case NEG :
|
||||
case ED_5C :
|
||||
case ED_74 :
|
||||
case ED_7C :
|
||||
case ED_6C :
|
||||
case ED_54 :
|
||||
case ED_4C :
|
||||
case ED_64 : NEG_A(); AddCycles( 4+4 ); break;
|
||||
|
||||
case RETI :
|
||||
case RETN :
|
||||
case ED_65 :
|
||||
case ED_6D :
|
||||
case ED_75 :
|
||||
case ED_7D :
|
||||
case ED_5D :
|
||||
case ED_55 :
|
||||
r_IFF1 = r_IFF2;
|
||||
RET_nn();
|
||||
AddCycles( 4+4+6 ); break;
|
||||
|
||||
case IM_0 :
|
||||
case ED_4E : /* * IM 0/1 */
|
||||
case ED_6E :
|
||||
case ED_66 : regs->IM = 0;
|
||||
AddCycles( 4+4 ); break; /* * IM 0 */
|
||||
|
||||
|
||||
case IM_1 :
|
||||
case ED_76 : regs->IM = 1;
|
||||
AddCycles( 4+4 ); break;
|
||||
|
||||
case IM_2 :
|
||||
case ED_7E : regs->IM = 2;
|
||||
AddCycles( 4+4 ); break;
|
||||
|
||||
case ED_77 :
|
||||
case ED_7F : AddCycles( 4+4 ); break; /* * NOP */
|
||||
|
||||
case OUT_xC_B : Z80OutPort(regs,r_BC, r_B); AddCycles( 4+4+4 ); break;
|
||||
case OUT_xC_C : Z80OutPort(regs,r_BC, r_C); AddCycles( 4+4+4 ); break;
|
||||
case OUT_xC_D : Z80OutPort(regs,r_BC, r_D); AddCycles( 4+4+4 ); break;
|
||||
case OUT_xC_E : Z80OutPort(regs,r_BC, r_E); AddCycles( 4+4+4 ); break;
|
||||
case OUT_xC_H : Z80OutPort(regs,r_BC, r_H); AddCycles( 4+4+4 ); break;
|
||||
case OUT_xC_L : Z80OutPort(regs,r_BC, r_L); AddCycles( 4+4+4 ); break;
|
||||
case OUT_xC_A : Z80OutPort(regs,r_BC, r_A); AddCycles( 4+4+4 ); break;
|
||||
/* * OUT (C), 0 */
|
||||
case ED_71 : Z80OutPort(regs,r_BC, 0); AddCycles( 4+4+4 ); break;
|
||||
|
||||
case IN_B_xC : IN(r_B, r_BC); AddCycles( 4+4+4 ); break;
|
||||
case IN_C_xC : IN(r_C, r_BC); AddCycles( 4+4+4 ); break;
|
||||
case IN_D_xC : IN(r_D, r_BC); AddCycles( 4+4+4 ); break;
|
||||
case IN_E_xC : IN(r_E, r_BC); AddCycles( 4+4+4 ); break;
|
||||
case IN_L_xC : IN(r_L, r_BC); AddCycles( 4+4+4 ); break;
|
||||
case IN_H_xC : IN(r_H, r_BC); AddCycles( 4+4+4 ); break;
|
||||
case IN_A_xC : IN(r_A, r_BC); AddCycles( 4+4+4 ); break;
|
||||
case IN_F_xC : IN(r_meml, r_BC); AddCycles( 4+4+4 ); break;
|
||||
|
||||
case LD_A_I : r_A = regs->I;
|
||||
r_F = ( r_F & FLAG_C )|sz53_table[r_A]|
|
||||
( regs->IFF2 ? FLAG_V:0 );
|
||||
AddCycles( 4+4+1 ); break;
|
||||
|
||||
case LD_I_A : regs->I = r_A; AddCycles( 4+4+1 ); break;
|
||||
|
||||
|
||||
case LD_A_R : r_A = ( regs->R.W & 0x7f ) | (regs->R.W & 0x80);
|
||||
r_F = (r_F&FLAG_C)|sz53_table[r_A] | (regs->IFF2?FLAG_V:0);
|
||||
AddCycles( 4+4+1 ); break;
|
||||
|
||||
case LD_R_A : regs->R.W = r_A;
|
||||
AddCycles( 4+4+1 ); break;
|
||||
|
||||
|
||||
case ADC_HL_BC : ADC_WORD(r_BC); AddCycles( 4+4+4+1+2 ); break;
|
||||
case ADC_HL_DE : ADC_WORD(r_DE); AddCycles( 4+4+4+1+2 ); break;
|
||||
case ADC_HL_HL : ADC_WORD(r_HL); AddCycles( 4+4+4+1+2 ); break;
|
||||
case ADC_HL_SP : ADC_WORD(r_SP); AddCycles( 4+4+4+1+2 ); break;
|
||||
|
||||
case SBC_HL_BC : SBC_WORD(r_BC); AddCycles( 4+4+4+1+2 ); break;
|
||||
case SBC_HL_DE : SBC_WORD(r_DE); AddCycles( 4+4+4+1+2 ); break;
|
||||
case SBC_HL_HL : SBC_WORD(r_HL); AddCycles( 4+4+4+1+2 ); break;
|
||||
case SBC_HL_SP : SBC_WORD(r_SP); AddCycles( 4+4+4+1+2 ); break;
|
||||
|
||||
case RRD : r_meml = Z80ReadMem(r_HL);
|
||||
Z80WriteMem(r_HL, ( r_A << 4 ) | ( r_meml >> 4 ), regs );
|
||||
r_A = ( r_A & 0xf0 ) | ( r_meml & 0x0f );
|
||||
r_F = ( r_F & FLAG_C ) | sz53p_table[r_A];
|
||||
AddCycles( 4+4+10 ); break;
|
||||
|
||||
case RLD : r_meml = Z80ReadMem(r_HL);
|
||||
Z80WriteMem(r_HL, (r_meml << 4 ) | ( r_A & 0x0f ), regs );
|
||||
r_A = ( r_A & 0xf0 ) | ( r_meml >> 4 );
|
||||
r_F = ( r_F & FLAG_C ) | sz53p_table[r_A];
|
||||
AddCycles( 4+4+10 ); break;
|
||||
|
||||
case LDI : r_meml = Z80ReadMem(r_HL); r_HL++;
|
||||
Z80WriteMem( r_DE, r_meml, regs ); r_DE++;
|
||||
r_BC--; r_meml += r_A;
|
||||
r_F = ( r_F & ( FLAG_C|FLAG_Z|FLAG_S ) ) |
|
||||
( r_BC ? FLAG_V:0 ) | ( r_meml & FLAG_3 ) |
|
||||
((r_meml & 0x02) ? FLAG_5 : 0 );
|
||||
AddCycles( 4+4+4+4 ); break;
|
||||
|
||||
case LDIR : r_meml = Z80ReadMem(r_HL); r_HL++;
|
||||
Z80WriteMem( r_DE, r_meml, regs ); r_DE++;
|
||||
r_BC--; r_meml += r_A;
|
||||
r_F = ( r_F & ( FLAG_C|FLAG_Z|FLAG_S ) ) |
|
||||
( r_BC ? FLAG_V:0 ) | ( r_meml & FLAG_3 ) |
|
||||
((r_meml & 0x02) ? FLAG_5 : 0 );
|
||||
AddCycles( 4+4+4+4 );
|
||||
if( r_BC ) { r_PC-=2; AddCycles(5); }
|
||||
break;
|
||||
|
||||
case LDD : r_meml = Z80ReadMem(r_HL); r_HL--;
|
||||
Z80WriteMem( r_DE, r_meml, regs ); r_DE--;
|
||||
r_BC--; r_meml += r_A;
|
||||
r_F = ( r_F & ( FLAG_C | FLAG_Z | FLAG_S ) ) |
|
||||
(r_BC ? FLAG_V : 0 ) | ( r_meml & FLAG_3 ) |
|
||||
((r_meml & 0x02) ? FLAG_5 : 0 );
|
||||
AddCycles( 4+4+4+4 ); break;
|
||||
|
||||
|
||||
case LDDR : r_meml = Z80ReadMem(r_HL);
|
||||
Z80WriteMem( r_DE, r_meml, regs );
|
||||
r_HL--; r_DE--; r_BC--; r_meml += r_A;
|
||||
r_F = ( r_F & ( FLAG_C | FLAG_Z | FLAG_S ) ) |
|
||||
(r_BC ? FLAG_V : 0 ) | ( r_meml & FLAG_3 ) |
|
||||
((r_meml & 0x02) ? FLAG_5 : 0 );
|
||||
AddCycles( 4+4+4+4+1 );
|
||||
if( r_BC ) { r_PC-=2; AddCycles(4); }
|
||||
break;
|
||||
|
||||
// I had lots of problems with CPI, INI, CPD, IND, OUTI, OUTD and so...
|
||||
// Thanks a lot to Philip Kendall for letting me to take a look to his
|
||||
// fuse emulator and allowing me to use their flag routines :-)
|
||||
case CPI : r_meml = Z80ReadMem(r_HL);
|
||||
r_memh = r_A - r_meml;
|
||||
r_opl = ( (r_A & 0x08) >> 3 ) |
|
||||
( ( (r_meml) & 0x08 ) >> 2 ) |
|
||||
( (r_meml & 0x08) >> 1 );
|
||||
r_HL++; r_BC--;
|
||||
r_F = ( r_F & FLAG_C ) |
|
||||
( r_BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |
|
||||
halfcarry_sub_table[r_opl] |
|
||||
( r_memh ? 0 : FLAG_Z ) |
|
||||
( r_memh & FLAG_S );
|
||||
if( r_F & FLAG_H) r_memh--;
|
||||
r_F |= ( r_memh & FLAG_3 ) |
|
||||
( (r_memh&0x02) ? FLAG_5 : 0 );
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
case CPIR : r_meml = Z80ReadMem(r_HL);
|
||||
r_memh = r_A - r_meml;
|
||||
r_opl = ( (r_A & 0x08) >> 3 ) |
|
||||
( ( (r_meml) & 0x08 ) >> 2 ) |
|
||||
( (r_meml & 0x08) >> 1 );
|
||||
r_HL++; r_BC--;
|
||||
r_F = ( r_F & FLAG_C ) |
|
||||
( r_BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |
|
||||
halfcarry_sub_table[r_opl] |
|
||||
( r_memh ? 0 : FLAG_Z ) |
|
||||
( r_memh & FLAG_S );
|
||||
if( r_F & FLAG_H) r_memh--;
|
||||
r_F |= ( r_memh & FLAG_3 ) |
|
||||
( (r_memh&0x02) ? FLAG_5 : 0 );
|
||||
if( ( r_F & ( FLAG_V | FLAG_Z ) ) == FLAG_V )
|
||||
{ AddCycles(5); r_PC-=2; }
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
case CPD : r_meml = Z80ReadMem(r_HL);
|
||||
r_memh = r_A-r_meml;
|
||||
r_opl = ( (r_A & 0x08) >> 3 ) |
|
||||
( ( (r_meml) & 0x08 ) >> 2 ) |
|
||||
( (r_memh & 0x08) >> 1 );
|
||||
r_HL--; r_BC--;
|
||||
r_F = ( r_F & FLAG_C ) |
|
||||
( r_BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |
|
||||
halfcarry_sub_table[r_opl] |
|
||||
( r_memh ? 0 : FLAG_Z ) |
|
||||
( r_memh & FLAG_S );
|
||||
if(r_F & FLAG_H) r_memh--;
|
||||
r_F |= ( r_memh & FLAG_3 ) |
|
||||
( (r_memh&0x02) ? FLAG_5 : 0 );
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
case CPDR : r_meml = Z80ReadMem(r_HL);
|
||||
r_memh = r_A-r_meml;
|
||||
r_opl = ( (r_A & 0x08) >> 3 ) |
|
||||
( ( (r_meml) & 0x08 ) >> 2 ) |
|
||||
( (r_memh & 0x08) >> 1 );
|
||||
r_HL--; r_BC--;
|
||||
r_F = ( r_F & FLAG_C ) |
|
||||
( r_BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |
|
||||
halfcarry_sub_table[r_opl] |
|
||||
( r_memh ? 0 : FLAG_Z ) |
|
||||
( r_memh & FLAG_S );
|
||||
if(r_F & FLAG_H) r_memh--;
|
||||
r_F |= ( r_memh & FLAG_3 ) |
|
||||
( (r_memh&0x02) ? FLAG_5 : 0 );
|
||||
if( ( r_F & ( FLAG_V | FLAG_Z ) ) == FLAG_V )
|
||||
{ AddCycles(5); r_PC-=2; }
|
||||
AddCycles( 4+4+4+4 ); break;
|
||||
|
||||
/*
|
||||
// OUTI contributed by Alvaro Alea
|
||||
case OUTI : Z80OutPort( regs, r_BC, Z80ReadMem( r_HL )) ;
|
||||
r_HL++ ; r_B-- ;
|
||||
if (r_B==0)
|
||||
r_F |= FLAG_Z;
|
||||
else
|
||||
r_F &= !FLAG_Z;
|
||||
r_F |= FLAG_N;
|
||||
AddCycles( 4+4+4+4 ); break;
|
||||
*/
|
||||
|
||||
// I/O block instructions by Metalbrain - 14-5-2001
|
||||
case IND : r_meml = Z80InPort((r_BC)); r_memh=0;
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(r_B)--;
|
||||
r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
|
||||
r_F &= 0xE8;
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
r_F |= ( (r_meml & 0x80 ) >> 6);
|
||||
r_opl = r_C; r_oph = 0;
|
||||
r_opl--;
|
||||
r_op += r_mem;
|
||||
r_oph += (r_oph << 4);
|
||||
r_F |= r_oph;
|
||||
r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
|
||||
r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)] );
|
||||
r_HL--;
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
case INDR : r_meml = Z80InPort((r_BC)); r_memh=0;
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(r_B)--;
|
||||
r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
|
||||
r_F &= 0xE8;
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
r_F |= ( (r_meml & 0x80 ) >> 6);
|
||||
r_opl = r_C; r_oph = 0;
|
||||
r_opl--;
|
||||
r_op += r_mem;
|
||||
r_oph += (r_oph << 4);
|
||||
r_F |= r_oph;
|
||||
r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
|
||||
r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)] );
|
||||
r_HL--;
|
||||
if( r_B ) { r_PC-=2; AddCycles(5); }
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
case INI : r_meml = Z80InPort((r_BC)); r_memh=0;
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(r_B)--;
|
||||
r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
|
||||
r_F &= 0xE8;
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
r_F |= ( (r_meml & 0x80 ) >> 6);
|
||||
r_opl = r_C; r_oph = 0;
|
||||
r_opl++;
|
||||
r_op += r_mem;
|
||||
r_oph += (r_oph << 4);
|
||||
r_F |= r_oph;
|
||||
r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
|
||||
r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)] );
|
||||
r_HL++;
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
|
||||
case INIR : r_meml = Z80InPort((r_BC)); r_memh=0;
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(r_B)--;
|
||||
r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
|
||||
r_F &= 0xE8;
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
r_F |= ( (r_meml & 0x80 ) >> 6);
|
||||
r_opl = r_C; r_oph = 0;
|
||||
r_opl++;
|
||||
r_op += r_mem;
|
||||
r_oph += (r_oph << 4);
|
||||
r_F |= r_oph;
|
||||
r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
|
||||
r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)] );
|
||||
r_HL++;
|
||||
if( r_B ) { r_PC-=2; AddCycles(5); }
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
case OUTI : r_meml = Z80ReadMem(r_HL); r_memh = 0;
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(r_B)--;
|
||||
r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
|
||||
r_F &= 0xE8;
|
||||
Z80OutPort( regs, r_BC, r_meml);
|
||||
r_F |= ((r_meml & 0x80 ) >> 6);
|
||||
r_opl = r_C; r_oph=0;
|
||||
r_opl++;
|
||||
r_op += r_mem;
|
||||
r_oph += (r_oph<<4);
|
||||
r_F |= r_oph;
|
||||
r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
|
||||
r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)] );
|
||||
r_HL++;
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
case OTIR : r_meml = Z80ReadMem(r_HL); r_memh = 0;
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(r_B)--;
|
||||
r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
|
||||
r_F &= 0xE8;
|
||||
Z80OutPort( regs, r_BC, r_meml);
|
||||
r_F |= ((r_meml & 0x80 ) >> 6);
|
||||
r_opl = r_C; r_oph=0;
|
||||
r_opl++;
|
||||
r_op += r_mem;
|
||||
r_oph += (r_oph<<4);
|
||||
r_F |= r_oph;
|
||||
r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
|
||||
r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)] );
|
||||
r_HL++;
|
||||
if( r_B ) { r_PC-=2; AddCycles(5); }
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
|
||||
case OUTD : r_meml = Z80ReadMem(r_HL); r_memh = 0;
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(r_B)--;
|
||||
r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
|
||||
r_F &= 0xE8;
|
||||
Z80OutPort( regs, r_BC, r_meml);
|
||||
r_F |= ((r_meml & 0x80 ) >> 6);
|
||||
r_opl = r_C; r_oph=0;
|
||||
r_opl--;
|
||||
r_op += r_mem;
|
||||
r_oph += (r_oph<<4);
|
||||
r_F |= r_oph;
|
||||
r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
|
||||
r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)] );
|
||||
r_HL--;
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
case OTDR : r_meml = Z80ReadMem(r_HL); r_memh = 0;
|
||||
r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
|
||||
(r_B)--;
|
||||
r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
|
||||
r_F &= 0xE8;
|
||||
Z80OutPort( regs, r_BC, r_meml);
|
||||
r_F |= ((r_meml & 0x80 ) >> 6);
|
||||
r_opl = r_C; r_oph=0;
|
||||
r_opl--;
|
||||
r_op += r_mem;
|
||||
r_oph += (r_oph<<4);
|
||||
r_F |= r_oph;
|
||||
r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
|
||||
r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)] );
|
||||
r_HL--;
|
||||
if( r_B ) { r_PC-=2; AddCycles(5); }
|
||||
AddCycles( 4+4+4+4); break;
|
||||
|
||||
// End of Metalbrain's contribution
|
||||
|
||||
case PREFIX_ED: AddCycles( 4 ); /* ED ED xx = 12 cycles min = 4+8 */
|
||||
r_PC-- ;
|
||||
break;
|
||||
|
||||
default:
|
||||
// exit(1);
|
||||
AddCycles( 4+4 ); /* Just a NOP */
|
||||
///!!! if(regs->DecodingErrors)
|
||||
///!!! printf( "z80 core: Unknown instruction: ED %02Xh at PC=%04Xh.\n",
|
||||
///!!! Z80ReadMem(r_PC-1),r_PC-2 );
|
||||
break;
|
||||
}
|
|
@ -0,0 +1,901 @@
|
|||
/*====================================================================/*
|
||||
opcodes.c -> This file executes the single-byte Z80 opcodes.
|
||||
|
||||
The CPU fetchs the byte pointed by the PC register (Program Counter)
|
||||
into de IR (Instruction Register) and decodes it. The value of this
|
||||
fetched byte (opcode) determines what operation the CPU must do.
|
||||
On Z80 (which uses 8 bit for the IW register) this means that we
|
||||
can have 256 (2^8) different opcodes. The z80 uses a simple trick
|
||||
called PREFIXES to obtain more opcodes by using more than one byte
|
||||
in the decoding (see opcodes_cb.c to know how it does it).
|
||||
|
||||
This file executes the whole list of single-byte opcodes.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
=====================================================================*/
|
||||
|
||||
/* About the AddCycles(4) -> Remember that reading from memory
|
||||
takes 3 cycles plus 1 of the decoding.
|
||||
Add 3 cycles for each operand fetch, and
|
||||
3 more for each memory write/read. */
|
||||
|
||||
|
||||
case NOP : AddCycles( 4 ); break;
|
||||
case LD_BC_NN : LD_rr_nn(r_BC); AddCycles( 4+3+3 ); break;
|
||||
case LD_xBC_A : STORE_r(r_BC, r_A); AddCycles( 4+3 ); break;
|
||||
case INC_BC : r_BC++; AddCycles( 4+2 ); break;
|
||||
|
||||
case INC_B : INC(r_B); AddCycles( 4 ); break;
|
||||
case DEC_B : DEC(r_B); AddCycles( 4 ); break;
|
||||
|
||||
case LD_B_N : LD_r_n(r_B);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case EX_AF_AF : EX_WORD(r_AF, r_AFs);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_A_xBC : LOAD_r(r_A, r_BC);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case DEC_BC : r_BC--;
|
||||
AddCycles( 4+2 );
|
||||
break;
|
||||
|
||||
case INC_C : INC(r_C);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case DEC_C : DEC(r_C);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_C_N : LD_r_n(r_C);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_DE_NN : LD_rr_nn(r_DE);
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case LD_xDE_A : STORE_r(r_DE, r_A);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case INC_DE : r_DE++;
|
||||
AddCycles( 4+2 );
|
||||
break;
|
||||
|
||||
case INC_D : INC(r_D);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case DEC_D : DEC(r_D);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_D_N : LD_r_n(r_D);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case ADD_HL_BC : ADD_WORD(r_HL, r_BC); AddCycles( 4+3+3+1 ); break;
|
||||
case ADD_HL_DE : ADD_WORD(r_HL, r_DE); AddCycles( 4+3+3+1 ); break;
|
||||
case ADD_HL_HL : ADD_WORD(r_HL, r_HL); AddCycles( 4+3+3+1 ); break;
|
||||
case ADD_HL_SP : ADD_WORD(r_HL, r_SP); AddCycles( 4+3+3+1 ); break;
|
||||
|
||||
case LD_A_xDE : LOAD_r(r_A, r_DE);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case DEC_DE : r_DE--;
|
||||
AddCycles( 4+2 );
|
||||
break;
|
||||
|
||||
case INC_E : INC(r_E);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case DEC_E : DEC(r_E);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_E_N : LD_r_n(r_E);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_HL_NN : LD_rr_nn(r_HL);
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case LD_xNN_HL : STORE_nn_rr(r_HL);
|
||||
AddCycles( 4+3+3+3+3 );
|
||||
break;
|
||||
|
||||
case INC_HL : r_HL++;
|
||||
AddCycles( 4+2 );
|
||||
break;
|
||||
|
||||
case INC_H : INC(r_H);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case DEC_H : DEC(r_H);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_H_N : LD_r_n(r_H);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_HL_xNN : LOAD_rr_nn(r_HL);
|
||||
AddCycles( 4+3+3+3+3 );
|
||||
break;
|
||||
|
||||
case DEC_HL : r_HL--;
|
||||
AddCycles( 4+2 );
|
||||
break;
|
||||
|
||||
case INC_L : INC(r_L);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case DEC_L : DEC(r_L);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_L_N : LD_r_n(r_L);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_SP_NN : LD_rr_nn(r_SP);
|
||||
AddCycles( 10 );
|
||||
break;
|
||||
|
||||
case LD_xNN_A : STORE_nn_r(r_A);
|
||||
AddCycles( 13 );
|
||||
break;
|
||||
|
||||
case INC_SP : r_SP++;
|
||||
AddCycles( 6 );
|
||||
break;
|
||||
|
||||
case LD_xHL_N : r_meml = Z80ReadMem(r_PC); r_PC++;
|
||||
STORE_r( r_HL, r_meml );
|
||||
AddCycles( 10 );
|
||||
break;
|
||||
|
||||
case LD_A_xNN : LOAD_r_nn( r_A );
|
||||
AddCycles( 13 );
|
||||
break;
|
||||
|
||||
case DEC_SP : r_SP--;
|
||||
AddCycles( 6 );
|
||||
break;
|
||||
|
||||
case INC_A : INC(r_A);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case DEC_A : DEC(r_A);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_A_N : LD_r_n(r_A);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_B_B : LD_r_r( r_B, r_B );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_B_C : LD_r_r( r_B, r_C );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_B_D : LD_r_r( r_B, r_D );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_B_E : LD_r_r( r_B, r_E );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_B_H : LD_r_r( r_B, r_H );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_B_L : LD_r_r( r_B, r_L );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_B_xHL : LOAD_r(r_B, r_HL);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_B_A : LD_r_r( r_B, r_A );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_C_B : LD_r_r( r_C, r_B );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_C_C : LD_r_r( r_C, r_C );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_C_D : LD_r_r( r_C, r_D );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_C_E : LD_r_r( r_C, r_E );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
case LD_C_H : LD_r_r( r_C, r_H );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_C_L : LD_r_r( r_C, r_L );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_C_xHL : LOAD_r(r_C, r_HL);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_C_A : LD_r_r( r_C, r_A );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_D_B : LD_r_r( r_D, r_B );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_D_C : LD_r_r( r_D, r_C );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_D_D : LD_r_r( r_D, r_D );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_D_E : LD_r_r( r_D, r_E );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_D_H : LD_r_r( r_D, r_H );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_D_L : LD_r_r( r_D, r_L );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_D_xHL : LOAD_r(r_D, r_HL);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_D_A : LD_r_r( r_D, r_A );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_E_B : LD_r_r( r_E, r_B );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_E_C : LD_r_r( r_E, r_C );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_E_D : LD_r_r( r_E, r_D );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_E_E : LD_r_r( r_E, r_E );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_E_H : LD_r_r( r_E, r_H );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_E_L : LD_r_r( r_E, r_L );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_E_xHL : LOAD_r(r_E, r_HL);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_E_A : LD_r_r( r_E, r_A );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_H_B : LD_r_r( r_H, r_B );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_H_C : LD_r_r( r_H, r_C );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_H_D : LD_r_r( r_H, r_D );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_H_E : LD_r_r( r_H, r_E );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_H_H : LD_r_r( r_H, r_H );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_H_L : LD_r_r( r_H, r_L );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_H_xHL : LOAD_r(r_H, r_HL);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_H_A : LD_r_r( r_H, r_A );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_L_B : LD_r_r( r_L, r_B );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_L_C : LD_r_r( r_L, r_C );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_L_D : LD_r_r( r_L, r_D );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_L_E : LD_r_r( r_L, r_E );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_L_H : LD_r_r( r_L, r_H );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_L_L : LD_r_r( r_L, r_L );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_L_xHL : LOAD_r(r_L, r_HL);
|
||||
AddCycles( 7 );
|
||||
break;
|
||||
|
||||
case LD_L_A : LD_r_r( r_L, r_A );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_xHL_B : STORE_r( r_HL, r_B );
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_xHL_C : STORE_r( r_HL, r_C );
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_xHL_D : STORE_r( r_HL, r_D );
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_xHL_E : STORE_r( r_HL, r_E );
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_xHL_H : STORE_r( r_HL, r_H );
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_xHL_L : STORE_r( r_HL, r_L );
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_xHL_A : STORE_r(r_HL, r_A );
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_A_B : LD_r_r( r_A, r_B );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_A_C : LD_r_r( r_A, r_C );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_A_D : LD_r_r( r_A, r_D );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_A_E : LD_r_r( r_A, r_E );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_A_H : LD_r_r( r_A, r_H );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_A_L : LD_r_r( r_A, r_L );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_A_xHL : LOAD_r( r_A, r_HL);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case LD_A_A : LD_r_r( r_A, r_A );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case LD_SP_HL : LD_r_r( r_SP, r_HL );
|
||||
AddCycles( 6 ); break;
|
||||
|
||||
case ADD_B : ADD(r_B); AddCycles( 4 ); break;
|
||||
case ADD_C : ADD(r_C); AddCycles( 4 ); break;
|
||||
case ADD_D : ADD(r_D); AddCycles( 4 ); break;
|
||||
case ADD_E : ADD(r_E); AddCycles( 4 ); break;
|
||||
case ADD_H : ADD(r_H); AddCycles( 4 ); break;
|
||||
case ADD_L : ADD(r_L); AddCycles( 4 ); break;
|
||||
case ADD_xHL : r_meml = Z80ReadMem(r_HL);
|
||||
ADD(r_meml);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
case ADD_A : ADD(r_A); AddCycles( 4 ); break;
|
||||
case ADC_B : ADC(r_B); AddCycles( 4 ); break;
|
||||
case ADC_C : ADC(r_C); AddCycles( 4 ); break;
|
||||
case ADC_D : ADC(r_D); AddCycles( 4 ); break;
|
||||
case ADC_E : ADC(r_E); AddCycles( 4 ); break;
|
||||
case ADC_H : ADC(r_H); AddCycles( 4 ); break;
|
||||
case ADC_L : ADC(r_L); AddCycles( 4 ); break;
|
||||
case ADC_xHL : r_meml = Z80ReadMem(r_HL);
|
||||
ADC(r_meml);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
case ADC_A : ADC(r_A); AddCycles( 4 ); break;
|
||||
case ADC_N : r_meml = Z80ReadMem(r_PC); r_PC++;
|
||||
ADC(r_meml);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case SUB_A : SUB(r_A); AddCycles( 4 ); break;
|
||||
case SUB_B : SUB(r_B); AddCycles( 4 ); break;
|
||||
case SUB_C : SUB(r_C); AddCycles( 4 ); break;
|
||||
case SUB_D : SUB(r_D); AddCycles( 4 ); break;
|
||||
case SUB_E : SUB(r_E); AddCycles( 4 ); break;
|
||||
case SUB_H : SUB(r_H); AddCycles( 4 ); break;
|
||||
case SUB_L : SUB(r_L); AddCycles( 4 ); break;
|
||||
case SUB_xHL : r_meml = Z80ReadMem(r_HL);
|
||||
SUB(r_meml);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
case SUB_N : r_meml = Z80ReadMem(r_PC); r_PC++;
|
||||
SUB(r_meml);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case SBC_A : SBC(r_A); AddCycles( 4 ); break;
|
||||
case SBC_B : SBC(r_B); AddCycles( 4 ); break;
|
||||
case SBC_C : SBC(r_C); AddCycles( 4 ); break;
|
||||
case SBC_D : SBC(r_D); AddCycles( 4 ); break;
|
||||
case SBC_E : SBC(r_E); AddCycles( 4 ); break;
|
||||
case SBC_H : SBC(r_H); AddCycles( 4 ); break;
|
||||
case SBC_L : SBC(r_L); AddCycles( 4 ); break;
|
||||
case SBC_xHL : r_meml = Z80ReadMem(r_HL);
|
||||
SBC(r_meml);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
case SBC_N : r_meml = Z80ReadMem(r_PC); r_PC++;
|
||||
SBC(r_meml);
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case AND_B : AND( r_B ); AddCycles( 4 ); break;
|
||||
case AND_C : AND( r_C ); AddCycles( 4 ); break;
|
||||
case AND_D : AND( r_D ); AddCycles( 4 ); break;
|
||||
case AND_E : AND( r_E ); AddCycles( 4 ); break;
|
||||
case AND_H : AND( r_H ); AddCycles( 4 ); break;
|
||||
case AND_L : AND( r_L ); AddCycles( 4 ); break;
|
||||
case AND_xHL : AND_mem( r_HL ); AddCycles( 4+3 ); break;
|
||||
case AND_A : AND( r_A ); AddCycles( 4 ); break;
|
||||
case XOR_B : XOR( r_B ); AddCycles( 4 ); break;
|
||||
case XOR_C : XOR( r_C ); AddCycles( 4 ); break;
|
||||
case XOR_D : XOR( r_D ); AddCycles( 4 ); break;
|
||||
case XOR_E : XOR( r_E ); AddCycles( 4 ); break;
|
||||
case XOR_H : XOR( r_H ); AddCycles( 4 ); break;
|
||||
case XOR_L : XOR( r_L ); AddCycles( 4 ); break;
|
||||
case XOR_xHL : XOR_mem( r_HL ); AddCycles( 4+3 ); break;
|
||||
case XOR_A : XOR( r_A ); AddCycles( 4 ); break;
|
||||
case OR_B : OR( r_B ); AddCycles( 4 ); break;
|
||||
case OR_C : OR( r_C ); AddCycles( 4 ); break;
|
||||
case OR_D : OR( r_D ); AddCycles( 4 ); break;
|
||||
case OR_E : OR( r_E ); AddCycles( 4 ); break;
|
||||
case OR_H : OR( r_H ); AddCycles( 4 ); break;
|
||||
case OR_L : OR( r_L ); AddCycles( 4 ); break;
|
||||
case OR_xHL : OR_mem( r_HL ); AddCycles( 4+3 ); break;
|
||||
case OR_A : OR( r_A ); AddCycles( 4 ); break;
|
||||
case CP_A : CP(r_A); AddCycles( 4 ); break;
|
||||
case CP_B : CP(r_B); AddCycles( 4 ); break;
|
||||
case CP_C : CP(r_C); AddCycles( 4 ); break;
|
||||
case CP_D : CP(r_D); AddCycles( 4 ); break;
|
||||
case CP_E : CP(r_E); AddCycles( 4 ); break;
|
||||
case CP_H : CP(r_H); AddCycles( 4 ); break;
|
||||
case CP_L : CP(r_L); AddCycles( 4 ); break;
|
||||
case CP_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
CP(r_meml); AddCycles( 4+3 ); break;
|
||||
case CP_N : r_meml = Z80ReadMem(r_PC); r_PC++;
|
||||
CP(r_meml);
|
||||
AddCycles( 4+3);
|
||||
break;
|
||||
|
||||
case RET_Z : if( TEST_FLAG(Z_FLAG) )
|
||||
{ RET_nn(); AddCycles( 4+1+3+3 ); }
|
||||
else { AddCycles( 4+1 ); }
|
||||
break;
|
||||
|
||||
case RET_C : if( TEST_FLAG(C_FLAG) )
|
||||
{ RET_nn(); AddCycles( 4+1+3+3 ); }
|
||||
else { AddCycles( 4+1 ); }
|
||||
break;
|
||||
|
||||
case RET_M : if( TEST_FLAG(S_FLAG) )
|
||||
{ RET_nn(); AddCycles( 4+1+3+3 ); }
|
||||
else { AddCycles( 4+1 ); }
|
||||
break;
|
||||
|
||||
case RET_PE : if( TEST_FLAG(P_FLAG) )
|
||||
{ RET_nn(); AddCycles( 4+1+3+3 ); }
|
||||
else { AddCycles( 4+1 ); }
|
||||
break;
|
||||
|
||||
case RET_PO : if( TEST_FLAG(P_FLAG) )
|
||||
{ AddCycles( 4+1 ); }
|
||||
else { RET_nn(); AddCycles( 4+1+3+3 ); }
|
||||
break;
|
||||
|
||||
case RET_P : if( TEST_FLAG(S_FLAG) )
|
||||
{ AddCycles( 4+1 ); }
|
||||
else { RET_nn(); AddCycles( 4+1+3+3 ); }
|
||||
break;
|
||||
|
||||
case RET : RET_nn();
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case RET_NZ : if( TEST_FLAG(Z_FLAG) )
|
||||
{ AddCycles( 4+1 ); }
|
||||
else { RET_nn(); AddCycles( 4+1+3+3 ); }
|
||||
break;
|
||||
|
||||
case RET_NC : if( TEST_FLAG(C_FLAG) )
|
||||
{ AddCycles( 4+1 ); }
|
||||
else { RET_nn(); AddCycles( 4+1+3+3 ); }
|
||||
break;
|
||||
|
||||
case ADD_N : r_meml = Z80ReadMem(r_PC); r_PC++;
|
||||
ADD(r_meml);
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case JR : JR_n();
|
||||
AddCycles( 4+3+3+2 );
|
||||
break;
|
||||
|
||||
case JR_NZ : if( TEST_FLAG(Z_FLAG) )
|
||||
{ r_PC++; AddCycles( 4+3 ); }
|
||||
else
|
||||
{ JR_n(); AddCycles( 4+8 ); }
|
||||
break;
|
||||
|
||||
case JR_Z : if( TEST_FLAG(Z_FLAG) )
|
||||
{ JR_n(); AddCycles( 4+8 ); }
|
||||
else
|
||||
{ r_PC++; AddCycles( 4+3 ); }
|
||||
break;
|
||||
|
||||
case JR_NC : if( TEST_FLAG(C_FLAG) )
|
||||
{ r_PC++; AddCycles( 4+3 ); }
|
||||
else
|
||||
{ JR_n(); AddCycles( 4+8 ); }
|
||||
break;
|
||||
|
||||
case JR_C : if( TEST_FLAG(C_FLAG) )
|
||||
{ JR_n(); AddCycles( 4+8 ); }
|
||||
else
|
||||
{ r_PC++; AddCycles( 4+3 ); }
|
||||
break;
|
||||
|
||||
case JP_NZ : if( TEST_FLAG(Z_FLAG) ) { r_PC += 2; }
|
||||
else { JP_nn(); }
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case JP : JP_nn();
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case JP_Z : if( TEST_FLAG(Z_FLAG) ) { JP_nn(); }
|
||||
else { r_PC += 2; }
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case JP_NC : if( TEST_FLAG(C_FLAG) ) { r_PC += 2; }
|
||||
else { JP_nn(); }
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case JP_C : if( TEST_FLAG(C_FLAG) ) { JP_nn(); }
|
||||
else { r_PC += 2; }
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case JP_PO : if( TEST_FLAG(P_FLAG) ) { r_PC += 2; }
|
||||
else { JP_nn(); }
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case JP_PE : if( TEST_FLAG(P_FLAG) ) { JP_nn(); }
|
||||
else { r_PC += 2; }
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case JP_P : if( TEST_FLAG(S_FLAG) ) { r_PC += 2; }
|
||||
else { JP_nn(); }
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
|
||||
case JP_M : if( TEST_FLAG(S_FLAG) ) { JP_nn(); }
|
||||
else { r_PC += 2; }
|
||||
AddCycles( 4+3+3 );
|
||||
break;
|
||||
|
||||
case JP_xHL : r_PC = r_HL; AddCycles( 4 ); break;
|
||||
|
||||
case CPL : r_A ^= 0xFF;
|
||||
r_F = ( r_F & (FLAG_C|FLAG_P|FLAG_Z|FLAG_S)) |
|
||||
( r_A & (FLAG_3|FLAG_5))|(FLAG_N|FLAG_H);
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case INC_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
INC(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+3+3+1 ); break;
|
||||
|
||||
case DEC_xHL : r_meml = Z80ReadMem( r_HL );
|
||||
DEC(r_meml);
|
||||
Z80WriteMem( r_HL, r_meml, regs );
|
||||
AddCycles( 4+3+3+1 ); break;
|
||||
|
||||
case SCF : r_F = r_F | FLAG_C;
|
||||
r_F &= FLAG_Z | FLAG_S | FLAG_P;
|
||||
if(r_F & FLAG_H) r_F ^= FLAG_H;
|
||||
r_F |= FLAG_C;
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case CCF : r_F = (r_F & (FLAG_P|FLAG_Z|FLAG_S) ) |
|
||||
((r_F & FLAG_C) ? FLAG_H : FLAG_C) |
|
||||
( r_A & (FLAG_3 | FLAG_5) );
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case HALT : regs->halted = 1;
|
||||
AddCycles(4);
|
||||
break;
|
||||
|
||||
case POP_BC : POP(BC); AddCycles( 10 ); break;
|
||||
case PUSH_BC : PUSH(BC); AddCycles( 11 ); break;
|
||||
case POP_HL : POP(HL); AddCycles( 10 ); break;
|
||||
case PUSH_HL : PUSH(HL); AddCycles( 11 ); break;
|
||||
case POP_AF : POP(AF); AddCycles( 10 ); break;
|
||||
case PUSH_AF : PUSH(AF); AddCycles( 11 ); break;
|
||||
case POP_DE : POP(DE); AddCycles( 10 ); break;
|
||||
case PUSH_DE : PUSH(DE); AddCycles( 11 ); break;
|
||||
|
||||
case RLCA : r_A = (r_A << 1) | (r_A >> 7);
|
||||
r_F = ( r_F & (FLAG_P|FLAG_Z|FLAG_S)) |
|
||||
( r_A & (FLAG_C|FLAG_3|FLAG_5) );
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case RRCA : r_F = ( r_F & (FLAG_P|FLAG_Z|FLAG_S)) |
|
||||
( r_A & FLAG_C );
|
||||
r_A = ( r_A >> 1) | ( r_A << 7 );
|
||||
r_F |= ( r_A & ( FLAG_3 | FLAG_5 ) );
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case DJNZ : r_B--;
|
||||
if( r_B ) { JR_n(); AddCycles(13); }
|
||||
else { r_PC++ ; AddCycles(8); }
|
||||
break;
|
||||
|
||||
case RLA : r_meml = r_A;
|
||||
r_A = ( r_A << 1 ) | ( r_F & FLAG_C );
|
||||
r_F = ( r_F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |
|
||||
(r_A & ( FLAG_3 | FLAG_5 ) ) | ( r_meml >> 7);
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case RRA : r_meml = r_A;
|
||||
r_A = ( r_A >> 1 ) | ( r_F << 7 );
|
||||
r_F = ( r_F & ( FLAG_P | FLAG_Z | FLAG_S ) ) |
|
||||
( r_A & ( FLAG_3 | FLAG_5 ) ) | ( r_meml & FLAG_C );
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case DAA : r_meml = 0;
|
||||
r_memh = ( r_F & FLAG_C );
|
||||
if( ( r_F & FLAG_H ) || ( (r_A & 0x0f)>9 ) ) r_meml=6;
|
||||
if( r_memh || (r_A > 0x9f ) ) r_meml |= 0x60;
|
||||
if( r_A > 0x99 ) r_memh=1;
|
||||
if ( r_F & FLAG_N ) { SUB(r_meml); }
|
||||
else
|
||||
{
|
||||
if( (r_A>0x90) && ( (r_A & 0x0f)>9) ) r_meml|=0x60;
|
||||
ADD(r_meml);
|
||||
}
|
||||
r_F = ( r_F & ~( FLAG_C | FLAG_P) ) | r_memh |
|
||||
parity_table[r_A];
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case OUT_N_A : Z80OutPort( regs, Z80ReadMem( r_PC ), r_A ); r_PC++;
|
||||
AddCycles( 11 ); break;
|
||||
|
||||
case IN_A_N : r_A = Z80InPort( Z80ReadMem( r_PC ) + (r_A << 8));
|
||||
r_PC++; AddCycles( 11 ); break;
|
||||
|
||||
case EX_HL_xSP : r_meml = Z80ReadMem(r_SP);
|
||||
r_memh = Z80ReadMem(r_SP+1);
|
||||
Z80WriteMem(r_SP, r_L, regs);
|
||||
Z80WriteMem(r_SP+1, r_H, regs);
|
||||
r_L = r_meml;
|
||||
r_H = r_memh;
|
||||
AddCycles( 19 ); break;
|
||||
|
||||
case EXX : EX_WORD(r_BC, r_BCs); EX_WORD(r_DE, r_DEs);
|
||||
EX_WORD(r_HL, r_HLs);
|
||||
AddCycles( 4 ); break;
|
||||
|
||||
case EX_DE_HL : EX_WORD( r_DE, r_HL );
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case AND_N : AND_mem( r_PC );
|
||||
r_PC++;
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case XOR_N : XOR_mem( r_PC );
|
||||
r_PC++;
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case OR_N : OR_mem( r_PC );
|
||||
r_PC++;
|
||||
AddCycles( 4+3 );
|
||||
break;
|
||||
|
||||
case DI : r_IFF1 = r_IFF2 = 0;
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case CALL :
|
||||
CALL_nn();
|
||||
AddCycles( 4+3+3+3+3+1 );
|
||||
break;
|
||||
|
||||
case CALL_NZ : if( TEST_FLAG(Z_FLAG) )
|
||||
{ r_PC += 2; AddCycles( 4+3+3 ); }
|
||||
else
|
||||
{
|
||||
CALL_nn();
|
||||
AddCycles( 4+3+3+3+3+1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case CALL_NC : if( TEST_FLAG(C_FLAG) )
|
||||
{ r_PC += 2; AddCycles( 4+3+3 ); }
|
||||
else
|
||||
{ CALL_nn();
|
||||
AddCycles( 4+3+3+3+3+1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case CALL_PO : if( TEST_FLAG(P_FLAG) )
|
||||
{ r_PC += 2; AddCycles( 4+3+3 ); }
|
||||
else
|
||||
{ CALL_nn();
|
||||
AddCycles( 4+3+3+ 3+3+1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case CALL_P : if( TEST_FLAG(S_FLAG) )
|
||||
{ r_PC += 2; AddCycles( 4+3+3 ); }
|
||||
else
|
||||
{ CALL_nn();
|
||||
AddCycles( 4+3+3+3+3+1 );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CALL_Z : if( TEST_FLAG(Z_FLAG) )
|
||||
{ CALL_nn();
|
||||
AddCycles( 4+3+3+3+3+1 );
|
||||
}
|
||||
else
|
||||
{ r_PC += 2; AddCycles( 4+3+3 ); }
|
||||
break;
|
||||
|
||||
case CALL_C : if( TEST_FLAG(C_FLAG) )
|
||||
{ CALL_nn();
|
||||
AddCycles( 4+3+3+ 3+3+4 );
|
||||
}
|
||||
else
|
||||
{ r_PC += 2; AddCycles( 4+3+3 ); }
|
||||
break;
|
||||
|
||||
case CALL_PE : if( TEST_FLAG(P_FLAG) )
|
||||
{ CALL_nn();
|
||||
AddCycles( 4+3+3+3+3+1 );
|
||||
}
|
||||
else
|
||||
{ r_PC += 2; AddCycles( 4+3+3 ); }
|
||||
break;
|
||||
|
||||
case CALL_M : if( TEST_FLAG(S_FLAG) )
|
||||
{ CALL_nn();
|
||||
AddCycles( 4+3+3+3+3+1 );
|
||||
}
|
||||
else
|
||||
{ r_PC += 2; AddCycles( 4+3+3 ); }
|
||||
break;
|
||||
|
||||
case EI : r_IFF1 = r_IFF2 = 1;
|
||||
/*
|
||||
Why Marat Fayzullin does this? ->
|
||||
|
||||
regs->IFF2 |= 0x01;
|
||||
if( regs->IRequest != INT_NOINT )
|
||||
{
|
||||
regs->IBackup = regs->ICount;
|
||||
regs->ICount = 0x1;
|
||||
r_IFF |= 0x20;
|
||||
}*/
|
||||
AddCycles( 4 );
|
||||
break;
|
||||
|
||||
case RST_00 : RST(0x00); AddCycles( 11 ); break;
|
||||
case RST_08 : RST(0x08); AddCycles( 11 ); break;
|
||||
case RST_10 : RST(0x10); AddCycles( 11 ); break;
|
||||
case RST_18 : RST(0x18); AddCycles( 11 ); break;
|
||||
case RST_20 : RST(0x20); AddCycles( 11 ); break;
|
||||
case RST_28 : RST(0x28); AddCycles( 11 ); break;
|
||||
case RST_30 : RST(0x30); AddCycles( 11 ); break;
|
||||
case RST_38 : RST(0x38); AddCycles( 11 ); break;
|
||||
|
||||
default:
|
||||
// exit(1);
|
||||
///!!! if( regs->DecodingErrors )
|
||||
///!!! printf("z80 core: Unknown instruction: %02Xh at PC=%04Xh.\n",
|
||||
///!!! Z80ReadMem(r_PC-1), r_PC-1 );
|
||||
break;
|
|
@ -0,0 +1,196 @@
|
|||
/*====================================================================/*
|
||||
opcodes_ddfdcb.c -> This file executes the DD/FD CB PREFIX opcodes.
|
||||
|
||||
Those are the double prefix opcodes. We found the DD prefix, which
|
||||
means that we must treat HL as IX, and then we found the CB prefix,
|
||||
so we must apply this rule to the CB PREFIX list of opcodes. A
|
||||
signed byte displacement is also added, and it's located BEFORE
|
||||
the DD CB opcode:
|
||||
|
||||
ie: CB 2E = SRA (HL)
|
||||
DD CB xx 2E = SRA (IX+xx)
|
||||
|
||||
(or...)
|
||||
|
||||
Those are the double prefix opcodes. We found the FD prefix, which
|
||||
means that we must treat HL as IY, and then we found the CB prefix,
|
||||
so we must apply this rule to the CB PREFIX list of opcodes. A
|
||||
signed byte displacement is also added, and it's located BEFORE
|
||||
the FD CB opcode:
|
||||
|
||||
ie: CB 2E = SRA (HL)
|
||||
FD CB xx 2E = SRA (IY+xx)
|
||||
|
||||
Call here using something like #define REGISTER regs->IX
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
=====================================================================*/
|
||||
|
||||
/* 15 clock cycles minimum = FD/DD CB xx opcode = 4 + 4 + 3 + 4 */
|
||||
|
||||
tmpreg.W = REGISTER.W + (offset) Z80ReadMem( r_PC );
|
||||
r_PC++;
|
||||
r_meml = Z80ReadMem( tmpreg.W );
|
||||
opcode = Z80ReadMem( r_PC );
|
||||
r_PC++;
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
|
||||
case RLC_xIXY : RLC(r_meml); Z80WriteMem(tmpreg.W, r_meml, regs);
|
||||
AddCycles( 23 ); break;
|
||||
case RRC_xIXY : RRC(r_meml); Z80WriteMem(tmpreg.W, r_meml, regs);
|
||||
AddCycles( 23 ); break;
|
||||
case RL_xIXY : RL(r_meml); Z80WriteMem(tmpreg.W, r_meml, regs);
|
||||
AddCycles( 23 ); break;
|
||||
case RR_xIXY : RR(r_meml); Z80WriteMem(tmpreg.W, r_meml, regs);
|
||||
AddCycles( 23 ); break;
|
||||
case SLA_xIXY : SLA(r_meml); Z80WriteMem(tmpreg.W, r_meml, regs);
|
||||
AddCycles( 23 ); break;
|
||||
case SRA_xIXY : SRA(r_meml); Z80WriteMem(tmpreg.W, r_meml, regs);
|
||||
AddCycles( 23 ); break;
|
||||
case SLL_xIXY : SLL(r_meml); Z80WriteMem(tmpreg.W, r_meml, regs);
|
||||
AddCycles( 23 ); break;
|
||||
case SRL_xIXY : SRL(r_meml); Z80WriteMem(tmpreg.W, r_meml, regs);
|
||||
AddCycles( 23 ); break;
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
case 0x47:
|
||||
case BIT_0_xIXY : BIT_BIT(0, r_meml); AddCycles( 15+5 ); break;
|
||||
|
||||
case 0x48:
|
||||
case 0x49:
|
||||
case 0x4a:
|
||||
case 0x4b:
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4f:
|
||||
case BIT_1_xIXY :
|
||||
BIT_BIT(1, r_meml); AddCycles( 15+5 ); break;
|
||||
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x57:
|
||||
case BIT_2_xIXY : BIT_BIT(2, r_meml); AddCycles( 15+5 ); break;
|
||||
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5f:
|
||||
case BIT_3_xIXY : BIT_BIT(3, r_meml); AddCycles( 15+5 ); break;
|
||||
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
case 0x63:
|
||||
case 0x64:
|
||||
case 0x65:
|
||||
case 0x67:
|
||||
case BIT_4_xIXY : BIT_BIT(4, r_meml); AddCycles( 15+5 ); break;
|
||||
|
||||
case 0x68:
|
||||
case 0x69:
|
||||
case 0x6a:
|
||||
case 0x6b:
|
||||
case 0x6c:
|
||||
case 0x6d:
|
||||
case 0x6f:
|
||||
case BIT_5_xIXY : BIT_BIT(5, r_meml); AddCycles( 15+5 ); break;
|
||||
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x77:
|
||||
case BIT_6_xIXY : BIT_BIT(6, r_meml); AddCycles( 15+5 ); break;
|
||||
case 0x78:
|
||||
case 0x79:
|
||||
case 0x7a:
|
||||
case 0x7b:
|
||||
case 0x7c:
|
||||
case 0x7d:
|
||||
case 0x7f:
|
||||
case BIT_7_xIXY : BIT_BIT7(r_meml); AddCycles( 15+5 ); break;
|
||||
|
||||
case RES_0_xIXY : BIT_RES_mem(0, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case RES_1_xIXY : BIT_RES_mem(1, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case RES_2_xIXY : BIT_RES_mem(2, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case RES_3_xIXY : BIT_RES_mem(3, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case RES_4_xIXY : BIT_RES_mem(4, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case RES_5_xIXY : BIT_RES_mem(5, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case RES_6_xIXY : BIT_RES_mem(6, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case RES_7_xIXY : BIT_RES_mem(7, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case SET_0_xIXY : BIT_SET_mem(0, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case SET_1_xIXY : BIT_SET_mem(1, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case SET_2_xIXY : BIT_SET_mem(2, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case SET_3_xIXY : BIT_SET_mem(3, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case SET_4_xIXY : BIT_SET_mem(4, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case SET_5_xIXY : BIT_SET_mem(5, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case SET_6_xIXY : BIT_SET_mem(6, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
case SET_7_xIXY : BIT_SET_mem(7, tmpreg.W, r_meml );
|
||||
AddCycles( 15+5+3 ); break;
|
||||
|
||||
|
||||
/*
|
||||
I must still include the undocumented opcodes such as:
|
||||
LD B, RLC(REGISTER+dd) and so on ...
|
||||
|
||||
*/
|
||||
default:
|
||||
AddCycles( 15 );
|
||||
// exit(1);
|
||||
///!!! if(regs->DecodingErrors)
|
||||
///!!! {
|
||||
///!!! printf("z80 core: Unknown instruction: ");
|
||||
///!!! if( regs->we_are_on_ddfd == WE_ARE_ON_DD )
|
||||
///!!! printf("DD");
|
||||
///!!! else
|
||||
///!!! printf("FD");
|
||||
///!!! printf("CB %02Xh %02Xh at PC=%04Xh.\n",
|
||||
///!!! Z80ReadMem(r_PC-2), Z80ReadMem(r_PC-1), r_PC-4 );
|
||||
///!!! }
|
||||
break;
|
||||
}
|
|
@ -0,0 +1,829 @@
|
|||
/*=====================================================================
|
||||
tables.h -> Header file containing the defines for Z80 opcodes.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
======================================================================*/
|
||||
|
||||
#ifndef TABLES_H
|
||||
#define TABLES_H
|
||||
|
||||
/*--- One byte opcodes: ----------------------------------------------*/
|
||||
#define NOP 0
|
||||
#define LD_BC_NN 1
|
||||
#define LD_xBC_A 2
|
||||
#define INC_BC 3
|
||||
#define INC_B 4
|
||||
#define DEC_B 5
|
||||
#define LD_B_N 6
|
||||
#define RLCA 7
|
||||
#define EX_AF_AF 8
|
||||
#define ADD_HL_BC 9
|
||||
#define LD_A_xBC 10
|
||||
#define DEC_BC 11
|
||||
#define INC_C 12
|
||||
#define DEC_C 13
|
||||
#define LD_C_N 14
|
||||
#define RRCA 15
|
||||
#define DJNZ 16
|
||||
#define LD_DE_NN 17
|
||||
#define LD_xDE_A 18
|
||||
#define INC_DE 19
|
||||
#define INC_D 20
|
||||
#define DEC_D 21
|
||||
#define LD_D_N 22
|
||||
#define RLA 23
|
||||
#define JR 24
|
||||
#define ADD_HL_DE 25
|
||||
#define LD_A_xDE 26
|
||||
#define DEC_DE 27
|
||||
#define INC_E 28
|
||||
#define DEC_E 29
|
||||
#define LD_E_N 30
|
||||
#define RRA 31
|
||||
#define JR_NZ 32
|
||||
#define LD_HL_NN 33
|
||||
#define LD_xNN_HL 34
|
||||
#define INC_HL 35
|
||||
#define INC_H 36
|
||||
#define DEC_H 37
|
||||
#define LD_H_N 38
|
||||
#define DAA 39
|
||||
#define JR_Z 40
|
||||
#define ADD_HL_HL 41
|
||||
#define LD_HL_xNN 42
|
||||
#define DEC_HL 43
|
||||
#define INC_L 44
|
||||
#define DEC_L 45
|
||||
#define LD_L_N 46
|
||||
#define CPL 47
|
||||
#define JR_NC 48
|
||||
#define LD_SP_NN 49
|
||||
#define LD_xNN_A 50
|
||||
#define INC_SP 51
|
||||
#define INC_xHL 52
|
||||
#define DEC_xHL 53
|
||||
#define LD_xHL_N 54
|
||||
#define SCF 55
|
||||
#define JR_C 56
|
||||
#define ADD_HL_SP 57
|
||||
#define LD_A_xNN 58
|
||||
#define DEC_SP 59
|
||||
#define INC_A 60
|
||||
#define DEC_A 61
|
||||
#define LD_A_N 62
|
||||
#define CCF 63
|
||||
#define LD_B_B 64
|
||||
#define LD_B_C 65
|
||||
#define LD_B_D 66
|
||||
#define LD_B_E 67
|
||||
#define LD_B_H 68
|
||||
#define LD_B_L 69
|
||||
#define LD_B_xHL 70
|
||||
#define LD_B_A 71
|
||||
#define LD_C_B 72
|
||||
#define LD_C_C 73
|
||||
#define LD_C_D 74
|
||||
#define LD_C_E 75
|
||||
#define LD_C_H 76
|
||||
#define LD_C_L 77
|
||||
#define LD_C_xHL 78
|
||||
#define LD_C_A 79
|
||||
#define LD_D_B 80
|
||||
#define LD_D_C 81
|
||||
#define LD_D_D 82
|
||||
#define LD_D_E 83
|
||||
#define LD_D_H 84
|
||||
#define LD_D_L 85
|
||||
#define LD_D_xHL 86
|
||||
#define LD_D_A 87
|
||||
#define LD_E_B 88
|
||||
#define LD_E_C 89
|
||||
#define LD_E_D 90
|
||||
#define LD_E_E 91
|
||||
#define LD_E_H 92
|
||||
#define LD_E_L 93
|
||||
#define LD_E_xHL 94
|
||||
#define LD_E_A 95
|
||||
#define LD_H_B 96
|
||||
#define LD_H_C 97
|
||||
#define LD_H_D 98
|
||||
#define LD_H_E 99
|
||||
#define LD_H_H 100
|
||||
#define LD_H_L 101
|
||||
#define LD_H_xHL 102
|
||||
#define LD_H_A 103
|
||||
#define LD_L_B 104
|
||||
#define LD_L_C 105
|
||||
#define LD_L_D 106
|
||||
#define LD_L_E 107
|
||||
#define LD_L_H 108
|
||||
#define LD_L_L 109
|
||||
#define LD_L_xHL 110
|
||||
#define LD_L_A 111
|
||||
#define LD_xHL_B 112
|
||||
#define LD_xHL_C 113
|
||||
#define LD_xHL_D 114
|
||||
#define LD_xHL_E 115
|
||||
#define LD_xHL_H 116
|
||||
#define LD_xHL_L 117
|
||||
#define HALT 118
|
||||
#define LD_xHL_A 119
|
||||
#define LD_A_B 120
|
||||
#define LD_A_C 121
|
||||
#define LD_A_D 122
|
||||
#define LD_A_E 123
|
||||
#define LD_A_H 124
|
||||
#define LD_A_L 125
|
||||
#define LD_A_xHL 126
|
||||
#define LD_A_A 127
|
||||
#define ADD_B 128
|
||||
#define ADD_C 129
|
||||
#define ADD_D 130
|
||||
#define ADD_E 131
|
||||
#define ADD_H 132
|
||||
#define ADD_L 133
|
||||
#define ADD_xHL 134
|
||||
#define ADD_A 135
|
||||
#define ADC_B 136
|
||||
#define ADC_C 137
|
||||
#define ADC_D 138
|
||||
#define ADC_E 139
|
||||
#define ADC_H 140
|
||||
#define ADC_L 141
|
||||
#define ADC_xHL 142
|
||||
#define ADC_A 143
|
||||
#define SUB_B 144
|
||||
#define SUB_C 145
|
||||
#define SUB_D 146
|
||||
#define SUB_E 147
|
||||
#define SUB_H 148
|
||||
#define SUB_L 149
|
||||
#define SUB_xHL 150
|
||||
#define SUB_A 151
|
||||
#define SBC_B 152
|
||||
#define SBC_C 153
|
||||
#define SBC_D 154
|
||||
#define SBC_E 155
|
||||
#define SBC_H 156
|
||||
#define SBC_L 157
|
||||
#define SBC_xHL 158
|
||||
#define SBC_A 159
|
||||
#define AND_B 160
|
||||
#define AND_C 161
|
||||
#define AND_D 162
|
||||
#define AND_E 163
|
||||
#define AND_H 164
|
||||
#define AND_L 165
|
||||
#define AND_xHL 166
|
||||
#define AND_A 167
|
||||
#define XOR_B 168
|
||||
#define XOR_C 169
|
||||
#define XOR_D 170
|
||||
#define XOR_E 171
|
||||
#define XOR_H 172
|
||||
#define XOR_L 173
|
||||
#define XOR_xHL 174
|
||||
#define XOR_A 175
|
||||
#define OR_B 176
|
||||
#define OR_C 177
|
||||
#define OR_D 178
|
||||
#define OR_E 179
|
||||
#define OR_H 180
|
||||
#define OR_L 181
|
||||
#define OR_xHL 182
|
||||
#define OR_A 183
|
||||
#define CP_B 184
|
||||
#define CP_C 185
|
||||
#define CP_D 186
|
||||
#define CP_E 187
|
||||
#define CP_H 188
|
||||
#define CP_L 189
|
||||
#define CP_xHL 190
|
||||
#define CP_A 191
|
||||
#define RET_NZ 192
|
||||
#define POP_BC 193
|
||||
#define JP_NZ 194
|
||||
#define JP 195
|
||||
#define CALL_NZ 196
|
||||
#define PUSH_BC 197
|
||||
#define ADD_N 198
|
||||
#define RST_00 199
|
||||
#define RET_Z 200
|
||||
#define RET 201
|
||||
#define JP_Z 202
|
||||
#define PREFIX_CB 203
|
||||
#define CALL_Z 204
|
||||
#define CALL 205
|
||||
#define ADC_N 206
|
||||
#define RST_08 207
|
||||
#define RET_NC 208
|
||||
#define POP_DE 209
|
||||
#define JP_NC 210
|
||||
#define OUT_N_A 211
|
||||
#define CALL_NC 212
|
||||
#define PUSH_DE 213
|
||||
#define SUB_N 214
|
||||
#define RST_10 215
|
||||
#define RET_C 216
|
||||
#define EXX 217
|
||||
#define JP_C 218
|
||||
#define IN_A_N 219
|
||||
#define CALL_C 220
|
||||
#define PREFIX_DD 221
|
||||
#define SBC_N 222
|
||||
#define RST_18 223
|
||||
#define RET_PO 224
|
||||
#define POP_HL 225
|
||||
#define JP_PO 226
|
||||
#define EX_HL_xSP 227
|
||||
#define CALL_PO 228
|
||||
#define PUSH_HL 229
|
||||
#define AND_N 230
|
||||
#define RST_20 231
|
||||
#define RET_PE 232
|
||||
#define JP_xHL 233
|
||||
#define JP_PE 234
|
||||
#define EX_DE_HL 235
|
||||
#define CALL_PE 236
|
||||
#define PREFIX_ED 237
|
||||
#define XOR_N 238
|
||||
#define RST_28 239
|
||||
#define RET_P 240
|
||||
#define POP_AF 241
|
||||
#define JP_P 242
|
||||
#define DI 243
|
||||
#define CALL_P 244
|
||||
#define PUSH_AF 245
|
||||
#define OR_N 246
|
||||
#define RST_30 247
|
||||
#define RET_M 248
|
||||
#define LD_SP_HL 249
|
||||
#define JP_M 250
|
||||
#define EI 251
|
||||
#define CALL_M 252
|
||||
#define PREFIX_FD 253
|
||||
#define CP_N 254
|
||||
#define RST_38 255
|
||||
|
||||
|
||||
|
||||
/*--- CB Prefix opcodes: ---------------------------------------------*/
|
||||
#define RLC_B 0
|
||||
#define RLC_C 1
|
||||
#define RLC_D 2
|
||||
#define RLC_E 3
|
||||
#define RLC_H 4
|
||||
#define RLC_L 5
|
||||
#define RLC_xHL 6
|
||||
#define RLC_A 7
|
||||
#define RRC_B 8
|
||||
#define RRC_C 9
|
||||
#define RRC_D 10
|
||||
#define RRC_E 11
|
||||
#define RRC_H 12
|
||||
#define RRC_L 13
|
||||
#define RRC_xHL 14
|
||||
#define RRC_A 15
|
||||
#define RL_B 16
|
||||
#define RL_C 17
|
||||
#define RL_D 18
|
||||
#define RL_E 19
|
||||
#define RL_H 20
|
||||
#define RL_L 21
|
||||
#define RL_xHL 22
|
||||
#define RL_A 23
|
||||
#define RR_B 24
|
||||
#define RR_C 25
|
||||
#define RR_D 26
|
||||
#define RR_E 27
|
||||
#define RR_H 28
|
||||
#define RR_L 29
|
||||
#define RR_xHL 30
|
||||
#define RR_A 31
|
||||
#define SLA_B 32
|
||||
#define SLA_C 33
|
||||
#define SLA_D 34
|
||||
#define SLA_E 35
|
||||
#define SLA_H 36
|
||||
#define SLA_L 37
|
||||
#define SLA_xHL 38
|
||||
#define SLA_A 39
|
||||
#define SRA_B 40
|
||||
#define SRA_C 41
|
||||
#define SRA_D 42
|
||||
#define SRA_E 43
|
||||
#define SRA_H 44
|
||||
#define SRA_L 45
|
||||
#define SRA_xHL 46
|
||||
#define SRA_A 47
|
||||
#define SLL_B 48
|
||||
#define SLL_C 49
|
||||
#define SLL_D 50
|
||||
#define SLL_E 51
|
||||
#define SLL_H 52
|
||||
#define SLL_L 53
|
||||
#define SLL_xHL 54
|
||||
#define SLL_A 55
|
||||
#define SRL_B 56
|
||||
#define SRL_C 57
|
||||
#define SRL_D 58
|
||||
#define SRL_E 59
|
||||
#define SRL_H 60
|
||||
#define SRL_L 61
|
||||
#define SRL_xHL 62
|
||||
#define SRL_A 63
|
||||
#define BIT_0_B 64
|
||||
#define BIT_0_C 65
|
||||
#define BIT_0_D 66
|
||||
#define BIT_0_E 67
|
||||
#define BIT_0_H 68
|
||||
#define BIT_0_L 69
|
||||
#define BIT_0_xHL 70
|
||||
#define BIT_0_A 71
|
||||
#define BIT_1_B 72
|
||||
#define BIT_1_C 73
|
||||
#define BIT_1_D 74
|
||||
#define BIT_1_E 75
|
||||
#define BIT_1_H 76
|
||||
#define BIT_1_L 77
|
||||
#define BIT_1_xHL 78
|
||||
#define BIT_1_A 79
|
||||
#define BIT_2_B 80
|
||||
#define BIT_2_C 81
|
||||
#define BIT_2_D 82
|
||||
#define BIT_2_E 83
|
||||
#define BIT_2_H 84
|
||||
#define BIT_2_L 85
|
||||
#define BIT_2_xHL 86
|
||||
#define BIT_2_A 87
|
||||
#define BIT_3_B 88
|
||||
#define BIT_3_C 89
|
||||
#define BIT_3_D 90
|
||||
#define BIT_3_E 91
|
||||
#define BIT_3_H 92
|
||||
#define BIT_3_L 93
|
||||
#define BIT_3_xHL 94
|
||||
#define BIT_3_A 95
|
||||
#define BIT_4_B 96
|
||||
#define BIT_4_C 97
|
||||
#define BIT_4_D 98
|
||||
#define BIT_4_E 99
|
||||
#define BIT_4_H 100
|
||||
#define BIT_4_L 101
|
||||
#define BIT_4_xHL 102
|
||||
#define BIT_4_A 103
|
||||
#define BIT_5_B 104
|
||||
#define BIT_5_C 105
|
||||
#define BIT_5_D 106
|
||||
#define BIT_5_E 107
|
||||
#define BIT_5_H 108
|
||||
#define BIT_5_L 109
|
||||
#define BIT_5_xHL 110
|
||||
#define BIT_5_A 111
|
||||
#define BIT_6_B 112
|
||||
#define BIT_6_C 113
|
||||
#define BIT_6_D 114
|
||||
#define BIT_6_E 115
|
||||
#define BIT_6_H 116
|
||||
#define BIT_6_L 117
|
||||
#define BIT_6_xHL 118
|
||||
#define BIT_6_A 119
|
||||
#define BIT_7_B 120
|
||||
#define BIT_7_C 121
|
||||
#define BIT_7_D 122
|
||||
#define BIT_7_E 123
|
||||
#define BIT_7_H 124
|
||||
#define BIT_7_L 125
|
||||
#define BIT_7_xHL 126
|
||||
#define BIT_7_A 127
|
||||
#define RES_0_B 128
|
||||
#define RES_0_C 129
|
||||
#define RES_0_D 130
|
||||
#define RES_0_E 131
|
||||
#define RES_0_H 132
|
||||
#define RES_0_L 133
|
||||
#define RES_0_xHL 134
|
||||
#define RES_0_A 135
|
||||
#define RES_1_B 136
|
||||
#define RES_1_C 137
|
||||
#define RES_1_D 138
|
||||
#define RES_1_E 139
|
||||
#define RES_1_H 140
|
||||
#define RES_1_L 141
|
||||
#define RES_1_xHL 142
|
||||
#define RES_1_A 143
|
||||
#define RES_2_B 144
|
||||
#define RES_2_C 145
|
||||
#define RES_2_D 146
|
||||
#define RES_2_E 147
|
||||
#define RES_2_H 148
|
||||
#define RES_2_L 149
|
||||
#define RES_2_xHL 150
|
||||
#define RES_2_A 151
|
||||
#define RES_3_B 152
|
||||
#define RES_3_C 153
|
||||
#define RES_3_D 154
|
||||
#define RES_3_E 155
|
||||
#define RES_3_H 156
|
||||
#define RES_3_L 157
|
||||
#define RES_3_xHL 158
|
||||
#define RES_3_A 159
|
||||
#define RES_4_B 160
|
||||
#define RES_4_C 161
|
||||
#define RES_4_D 162
|
||||
#define RES_4_E 163
|
||||
#define RES_4_H 164
|
||||
#define RES_4_L 165
|
||||
#define RES_4_xHL 166
|
||||
#define RES_4_A 167
|
||||
#define RES_5_B 168
|
||||
#define RES_5_C 169
|
||||
#define RES_5_D 170
|
||||
#define RES_5_E 171
|
||||
#define RES_5_H 172
|
||||
#define RES_5_L 173
|
||||
#define RES_5_xHL 174
|
||||
#define RES_5_A 175
|
||||
#define RES_6_B 176
|
||||
#define RES_6_C 177
|
||||
#define RES_6_D 178
|
||||
#define RES_6_E 179
|
||||
#define RES_6_H 180
|
||||
#define RES_6_L 181
|
||||
#define RES_6_xHL 182
|
||||
#define RES_6_A 183
|
||||
#define RES_7_B 184
|
||||
#define RES_7_C 185
|
||||
#define RES_7_D 186
|
||||
#define RES_7_E 187
|
||||
#define RES_7_H 188
|
||||
#define RES_7_L 189
|
||||
#define RES_7_xHL 190
|
||||
#define RES_7_A 191
|
||||
#define SET_0_B 192
|
||||
#define SET_0_C 193
|
||||
#define SET_0_D 194
|
||||
#define SET_0_E 195
|
||||
#define SET_0_H 196
|
||||
#define SET_0_L 197
|
||||
#define SET_0_xHL 198
|
||||
#define SET_0_A 199
|
||||
#define SET_1_B 200
|
||||
#define SET_1_C 201
|
||||
#define SET_1_D 202
|
||||
#define SET_1_E 203
|
||||
#define SET_1_H 204
|
||||
#define SET_1_L 205
|
||||
#define SET_1_xHL 206
|
||||
#define SET_1_A 207
|
||||
#define SET_2_B 208
|
||||
#define SET_2_C 209
|
||||
#define SET_2_D 210
|
||||
#define SET_2_E 211
|
||||
#define SET_2_H 212
|
||||
#define SET_2_L 213
|
||||
#define SET_2_xHL 214
|
||||
#define SET_2_A 215
|
||||
#define SET_3_B 216
|
||||
#define SET_3_C 217
|
||||
#define SET_3_D 218
|
||||
#define SET_3_E 219
|
||||
#define SET_3_H 220
|
||||
#define SET_3_L 221
|
||||
#define SET_3_xHL 222
|
||||
#define SET_3_A 223
|
||||
#define SET_4_B 224
|
||||
#define SET_4_C 225
|
||||
#define SET_4_D 226
|
||||
#define SET_4_E 227
|
||||
#define SET_4_H 228
|
||||
#define SET_4_L 229
|
||||
#define SET_4_xHL 230
|
||||
#define SET_4_A 231
|
||||
#define SET_5_B 232
|
||||
#define SET_5_C 233
|
||||
#define SET_5_D 234
|
||||
#define SET_5_E 235
|
||||
#define SET_5_H 236
|
||||
#define SET_5_L 237
|
||||
#define SET_5_xHL 238
|
||||
#define SET_5_A 239
|
||||
#define SET_6_B 240
|
||||
#define SET_6_C 241
|
||||
#define SET_6_D 242
|
||||
#define SET_6_E 243
|
||||
#define SET_6_H 244
|
||||
#define SET_6_L 245
|
||||
#define SET_6_xHL 246
|
||||
#define SET_6_A 247
|
||||
#define SET_7_B 248
|
||||
#define SET_7_C 249
|
||||
#define SET_7_D 250
|
||||
#define SET_7_E 251
|
||||
#define SET_7_H 252
|
||||
#define SET_7_L 253
|
||||
#define SET_7_xHL 254
|
||||
#define SET_7_A 255
|
||||
|
||||
|
||||
/*--- ED opcodes: ----------------------------------------------------*/
|
||||
#define IN_B_xC 64
|
||||
#define OUT_xC_B 65
|
||||
#define SBC_HL_BC 66
|
||||
#define LD_xNNe_BC 67
|
||||
#define NEG 68
|
||||
#define RETN 69
|
||||
#define IM_0 70
|
||||
#define LD_I_A 71
|
||||
#define IN_C_xC 72
|
||||
#define OUT_xC_C 73
|
||||
#define ADC_HL_BC 74
|
||||
#define LD_BC_xNNe 75
|
||||
#define ED_4C 76 /* * NEG */
|
||||
#define RETI 77
|
||||
#define ED_4E 78 /* * IM 0/1 */
|
||||
#define LD_R_A 79
|
||||
#define IN_D_xC 80
|
||||
#define OUT_xC_D 81
|
||||
#define SBC_HL_DE 82
|
||||
#define LD_xNNe_DE 83
|
||||
#define ED_54 84 /* * NEG */
|
||||
#define ED_55 85 /* * RET */
|
||||
#define IM_1 86
|
||||
#define LD_A_I 87
|
||||
#define IN_E_xC 88
|
||||
#define OUT_xC_E 89
|
||||
#define ADC_HL_DE 90
|
||||
#define LD_DE_xNNe 91
|
||||
#define ED_5C 92 /* * NEG */
|
||||
#define ED_5D 93 /* * RET */
|
||||
#define IM_2 94
|
||||
#define LD_A_R 95
|
||||
#define IN_H_xC 96
|
||||
#define OUT_xC_H 97
|
||||
#define SBC_HL_HL 98
|
||||
#define LD_xNNe_HL 99
|
||||
#define ED_64 100 /* * NEG */
|
||||
#define ED_65 101 /* * RET */
|
||||
#define ED_66 102 /* * IM 0 */
|
||||
#define RRD 103
|
||||
#define IN_L_xC 104
|
||||
#define OUT_xC_L 105
|
||||
#define ADC_HL_HL 106
|
||||
#define LD_HL_xNNe 107
|
||||
#define ED_6C 108 /* * NEG */
|
||||
#define ED_6D 109 /* * RET */
|
||||
#define ED_6E 110 /* * IM 0 */
|
||||
#define RLD 111
|
||||
#define IN_F_xC 112
|
||||
#define ED_71 113 /* * OUT (C), 0 */
|
||||
#define SBC_HL_SP 114
|
||||
#define LD_xNNe_SP 115
|
||||
#define ED_74 116 /* * NEG */
|
||||
#define ED_75 117 /* * RET */
|
||||
#define ED_76 118 /* * IM 1 */
|
||||
#define ED_77 119 /* * NOP */
|
||||
#define IN_A_xC 120
|
||||
#define OUT_xC_A 121
|
||||
#define ADC_HL_SP 122
|
||||
#define LD_SP_xNNe 123
|
||||
#define ED_7C 124 /* * NEG */
|
||||
#define ED_7D 125 /* * RET */
|
||||
#define ED_7E 126 /* * IM 2 */
|
||||
#define ED_7F 127 /* * NOP */
|
||||
#define LDI 160
|
||||
#define CPI 161
|
||||
#define INI 162
|
||||
#define OUTI 163
|
||||
#define LDD 168
|
||||
#define CPD 169
|
||||
#define IND 170
|
||||
#define OUTD 171
|
||||
#define LDIR 176
|
||||
#define CPIR 177
|
||||
#define INIR 178
|
||||
#define OTIR 179
|
||||
#define LDDR 184
|
||||
#define CPDR 185
|
||||
#define INDR 186
|
||||
#define OTDR 187
|
||||
#define ED_FE 254
|
||||
|
||||
|
||||
/*--- DD xx opcodes: -------------------------------------------------*/
|
||||
/* Those are the DD xx opcodes where HL is treated as IX + a
|
||||
signed byte displacement n when required: DD opcode n: */
|
||||
|
||||
/*--- FD xx opcodes: -------------------------------------------------*/
|
||||
/* Those are the FD xx opcodes where HL is treated as IY + a
|
||||
signed byte displacement n when required: FD opcode n: */
|
||||
|
||||
#define ADD_IXY_BC 9
|
||||
#define ADD_IXY_DE 25
|
||||
#define LD_IXY_NN 33
|
||||
#define LD_xNN_IXY 34
|
||||
#define INC_IXY 35
|
||||
#define INC_IXYh 36
|
||||
#define DEC_IXYh 37
|
||||
#define LD_IXYh_N 38
|
||||
#define ADD_IXY_IXY 41
|
||||
#define LD_IXY_xNN 42
|
||||
#define DEC_IXY 43
|
||||
#define INC_IXYl 44
|
||||
#define DEC_IXYl 45
|
||||
#define LD_IXYl_N 46
|
||||
#define INC_xIXY 52
|
||||
#define DEC_xIXY 53
|
||||
#define LD_xIXY_N 54
|
||||
#define ADD_IXY_SP 57
|
||||
#define LD_B_IXYh 68
|
||||
#define LD_B_IXYl 69
|
||||
#define LD_B_xIXY 70
|
||||
#define LD_C_IXYh 76
|
||||
#define LD_C_IXYl 77
|
||||
#define LD_C_xIXY 78
|
||||
#define LD_D_IXYh 84
|
||||
#define LD_D_IXYl 85
|
||||
#define LD_D_xIXY 86
|
||||
#define LD_E_IXYh 92
|
||||
#define LD_E_IXYl 93
|
||||
#define LD_E_xIXY 94
|
||||
#define LD_IXYh_B 96
|
||||
#define LD_IXYh_C 97
|
||||
#define LD_IXYh_D 98
|
||||
#define LD_IXYh_E 99
|
||||
#define LD_IXYh_IXYh 100
|
||||
#define LD_IXYh_IXYl 101
|
||||
#define LD_H_xIXY 102
|
||||
#define LD_IXYh_A 103
|
||||
#define LD_IXYl_B 104
|
||||
#define LD_IXYl_C 105
|
||||
#define LD_IXYl_D 106
|
||||
#define LD_IXYl_E 107
|
||||
#define LD_IXYl_IXYh 108
|
||||
#define LD_IXYl_IXYl 109
|
||||
#define LD_L_xIXY 110
|
||||
#define LD_IXYl_A 111
|
||||
#define LD_xIXY_B 112
|
||||
#define LD_xIXY_C 113
|
||||
#define LD_xIXY_D 114
|
||||
#define LD_xIXY_E 115
|
||||
#define LD_xIXY_H 116
|
||||
#define LD_xIXY_L 117
|
||||
#define LD_xIXY_A 119
|
||||
#define LD_A_IXYh 124
|
||||
#define LD_A_IXYl 125
|
||||
#define LD_A_xIXY 126
|
||||
#define ADD_IXYh 132
|
||||
#define ADD_IXYl 133
|
||||
#define ADD_xIXY 134
|
||||
#define ADC_IXYh 140
|
||||
#define ADC_IXYl 141
|
||||
#define ADC_xIXY 142
|
||||
#define SUB_IXYh 148
|
||||
#define SUB_IXYl 149
|
||||
#define SUB_xIXY 150
|
||||
#define SBC_IXYh 156
|
||||
#define SBC_IXYl 157
|
||||
#define SBC_xIXY 158
|
||||
#define AND_IXYh 164
|
||||
#define AND_IXYl 165
|
||||
#define AND_xIXY 166
|
||||
#define XOR_IXYh 172
|
||||
#define XOR_IXYl 173
|
||||
#define XOR_xIXY 174
|
||||
#define OR_IXYh 180
|
||||
#define OR_IXYl 181
|
||||
#define OR_xIXY 182
|
||||
#define CP_IXYh 188
|
||||
#define CP_IXYl 189
|
||||
#define CP_xIXY 190
|
||||
#define POP_IXY 225
|
||||
#define EX_IXY_xSP 227
|
||||
#define PUSH_IXY 229
|
||||
#define JP_IXY 233
|
||||
#define LD_SP_IXY 249
|
||||
|
||||
|
||||
|
||||
|
||||
/*--- DD CB Prefix opcodes: ------------------------------------------*/
|
||||
/* Those are the CB xx opcodes where HL is treated as IX + a
|
||||
signed byte displacement n: DD CB n opcode: */
|
||||
/*--- FD CB Prefix opcodes: ------------------------------------------*/
|
||||
/* Those are the CB xx opcodes where HL is treated as IY + a
|
||||
signed byte displacement n: FD CB n opcode: */
|
||||
|
||||
#define RLC_IXYh 4
|
||||
#define RLC_IXYl 5
|
||||
#define RLC_xIXY 6
|
||||
#define RRC_IXYh 12
|
||||
#define RRC_IXYl 13
|
||||
#define RRC_xIXY 14
|
||||
#define RL_IXYh 20
|
||||
#define RL_IXYl 21
|
||||
#define RL_xIXY 22
|
||||
#define RR_IXYh 28
|
||||
#define RR_IXYl 29
|
||||
#define RR_xIXY 30
|
||||
#define SLA_IXYh 36
|
||||
#define SLA_IXYl 37
|
||||
#define SLA_xIXY 38
|
||||
#define SRA_IXYh 44
|
||||
#define SRA_IXYl 45
|
||||
#define SRA_xIXY 46
|
||||
#define SLL_IXYh 52
|
||||
#define SLL_IXYl 53
|
||||
#define SLL_xIXY 54
|
||||
#define SRL_IXYh 60
|
||||
#define SRL_IXYl 61
|
||||
#define SRL_xIXY 62
|
||||
#define BIT_0_IXYh 68
|
||||
#define BIT_0_IXYl 69
|
||||
#define BIT_0_xIXY 70
|
||||
#define BIT_1_IXYh 76
|
||||
#define BIT_1_IXYl 77
|
||||
#define BIT_1_xIXY 78
|
||||
#define BIT_2_IXYh 84
|
||||
#define BIT_2_IXYl 85
|
||||
#define BIT_2_xIXY 86
|
||||
#define BIT_3_IXYh 92
|
||||
#define BIT_3_IXYl 93
|
||||
#define BIT_3_xIXY 94
|
||||
#define BIT_4_IXYh 100
|
||||
#define BIT_4_IXYl 101
|
||||
#define BIT_4_xIXY 102
|
||||
#define BIT_5_IXYh 108
|
||||
#define BIT_5_IXYl 109
|
||||
#define BIT_5_xIXY 110
|
||||
#define BIT_6_IXYh 116
|
||||
#define BIT_6_IXYl 117
|
||||
#define BIT_6_xIXY 118
|
||||
#define BIT_7_IXYh 124
|
||||
#define BIT_7_IXYl 125
|
||||
#define BIT_7_xIXY 126
|
||||
#define RES_0_IXYh 132
|
||||
#define RES_0_IXYl 133
|
||||
#define RES_0_xIXY 134
|
||||
#define RES_1_IXYh 140
|
||||
#define RES_1_IXYl 141
|
||||
#define RES_1_xIXY 142
|
||||
#define RES_2_IXYh 148
|
||||
#define RES_2_IXYl 149
|
||||
#define RES_2_xIXY 150
|
||||
#define RES_3_IXYh 156
|
||||
#define RES_3_IXYl 157
|
||||
#define RES_3_xIXY 158
|
||||
#define RES_4_IXYh 164
|
||||
#define RES_4_IXYl 165
|
||||
#define RES_4_xIXY 166
|
||||
#define RES_5_IXYh 172
|
||||
#define RES_5_IXYl 173
|
||||
#define RES_5_xIXY 174
|
||||
#define RES_6_IXYh 180
|
||||
#define RES_6_IXYl 181
|
||||
#define RES_6_xIXY 182
|
||||
#define RES_7_IXYh 188
|
||||
#define RES_7_IXYl 189
|
||||
#define RES_7_xIXY 190
|
||||
#define SET_0_IXYh 196
|
||||
#define SET_0_IXYl 197
|
||||
#define SET_0_xIXY 198
|
||||
#define SET_1_IXYh 204
|
||||
#define SET_1_IXYl 205
|
||||
#define SET_1_xIXY 206
|
||||
#define SET_2_IXYh 212
|
||||
#define SET_2_IXYl 213
|
||||
#define SET_2_xIXY 214
|
||||
#define SET_3_IXYh 220
|
||||
#define SET_3_IXYl 221
|
||||
#define SET_3_xIXY 222
|
||||
#define SET_4_IXYh 228
|
||||
#define SET_4_IXYl 229
|
||||
#define SET_4_xIXY 230
|
||||
#define SET_5_IXYh 236
|
||||
#define SET_5_IXYl 237
|
||||
#define SET_5_xIXY 238
|
||||
#define SET_6_IXYh 244
|
||||
#define SET_6_IXYl 245
|
||||
#define SET_6_xIXY 246
|
||||
#define SET_7_IXYh 252
|
||||
#define SET_7_IXYl 253
|
||||
#define SET_7_xIXY 254
|
||||
|
||||
#endif
|
|
@ -0,0 +1,407 @@
|
|||
/*=====================================================================
|
||||
z80.c -> Main File related to the Z80 emulation code.
|
||||
|
||||
Please read documentation files to know how this works :)
|
||||
|
||||
Thanks go to Marat Fayzullin (read z80.h for more info), Raúl Gomez
|
||||
(check his great R80 Spectrum emulator!), Philip Kendall (some code
|
||||
of this emulator, such as the flags lookup tabled are from his fuse
|
||||
Spectrum emulator) and more people I forget to name here ...
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
======================================================================*/
|
||||
|
||||
#include "z80.h"
|
||||
#include "tables.h"
|
||||
|
||||
|
||||
/* RAM variable, debug toggle variable, pressed key and
|
||||
row variables for keyboard emulation */
|
||||
extern byte *RAM;
|
||||
extern int debug, main_tecla, scanl;
|
||||
|
||||
extern int fila[5][5];
|
||||
|
||||
//extern char *tapfile;
|
||||
//extern FILE *tapfile;
|
||||
extern char *tfont;
|
||||
|
||||
#include "macros.c"
|
||||
|
||||
|
||||
/*====================================================================
|
||||
void Z80Reset( Z80Regs *regs, int cycles )
|
||||
|
||||
This function simulates a z80 reset by setting the registers
|
||||
to the values they are supposed to take on a real z80 reset.
|
||||
You must pass it the Z80 register structure and the number
|
||||
of cycles required to check for interrupts and do special
|
||||
hardware checking/updating.
|
||||
===================================================================*/
|
||||
void Z80Reset( Z80Regs *regs, int int_cycles )
|
||||
{
|
||||
/* reset PC and the rest of main registers: */
|
||||
regs->PC.W = regs->R.W = 0x0000;
|
||||
|
||||
regs->AF.W = regs->BC.W = regs->DE.W = regs->HL.W =
|
||||
regs->AFs.W = regs->BCs.W = regs->DEs.W = regs->HLs.W =
|
||||
regs->IX.W = regs->IY.W = 0x0000;
|
||||
|
||||
/* Make the stack point to $F000 */
|
||||
regs->SP.W = 0xF000;
|
||||
|
||||
/* reset variables to their default values */
|
||||
regs->I = 0x00;
|
||||
regs->IFF1 = regs->IFF2 = regs->IM = regs->halted = 0x00;
|
||||
regs->ICount = regs->IPeriod = int_cycles;
|
||||
|
||||
regs->IRequest = INT_NOINT;
|
||||
regs->we_are_on_ddfd = regs->dobreak = regs->BorderColor = 0;
|
||||
|
||||
//#ifdef _DEBUG_
|
||||
regs->DecodingErrors = 1;
|
||||
//#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*====================================================================
|
||||
word Z80Run( Z80Regs *regs, int numopcodes )
|
||||
|
||||
This function does the whole Z80 simulation. It consists on a
|
||||
for(;;) loop (as stated on Marat's Fayzullin HOWTO -How to
|
||||
Write a Computer Emulator-) which fetchs the next opcode,
|
||||
interprets it (using a switch statement) and then it's
|
||||
executed in the right CASE: of that switch. I've put the different
|
||||
case statements into C files included here with #include to
|
||||
make this more readable (and programming easier! :).
|
||||
|
||||
This function will change regs->ICount register and will execute
|
||||
an interrupt when it reaches 0 (or <0). You can then do anything
|
||||
related to your machine emulation here, using the Z80Hardware()
|
||||
function. This function must be filled by yourself: put there
|
||||
the code related to the emulated machine hardware, such as
|
||||
screen redrawing, sound playing and so on. This functions can
|
||||
return an special value to make Z80Run stop the emulation (and
|
||||
return to the caller): that's INT_QUIT. If there is time to
|
||||
execute an interrupt, please return INT_IRQ or INT_NMI. Return
|
||||
INT_NOINT if there is no time for an interrupt :) .
|
||||
|
||||
Z80Execute() will change PC and all the z80 registers acording
|
||||
to the executed opcode, and those values will be returned when
|
||||
a INT_QUIT is received.
|
||||
|
||||
Pass as numcycles the number of clock cycle you want to execute
|
||||
z80 opcodes for or < 0 (negative) to execute "infinite" opcodes.
|
||||
===================================================================*/
|
||||
word Z80Run( Z80Regs *regs, int numcycles )
|
||||
{
|
||||
/* opcode and temp variables */
|
||||
register byte opcode;
|
||||
eword tmpreg, ops, mread, tmpreg2;
|
||||
unsigned long tempdword;
|
||||
register int loop;
|
||||
unsigned short tempword;
|
||||
|
||||
/* emulate <numcycles> cycles */
|
||||
loop = (regs->ICount - numcycles);
|
||||
|
||||
/* this is the emulation main loop */
|
||||
while( regs->ICount > loop )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
/* test if we have reached the trap address */
|
||||
if( regs->PC.W == regs->TrapAddress && regs->dobreak != 0 )
|
||||
return(regs->PC.W);
|
||||
#endif
|
||||
|
||||
if( regs->halted == 1 )
|
||||
{ r_PC--; AddCycles(4); }
|
||||
|
||||
/* read the opcode from memory (pointed by PC) */
|
||||
opcode = Z80ReadMem(regs->PC.W);
|
||||
regs->PC.W++;
|
||||
|
||||
/* increment the R register and decode the instruction */
|
||||
AddR(1);
|
||||
switch(opcode)
|
||||
{
|
||||
#include "opcodes.c"
|
||||
case PREFIX_CB:
|
||||
AddR(1);
|
||||
#include "op_cb.c"
|
||||
break;
|
||||
case PREFIX_ED:
|
||||
AddR(1);
|
||||
#include "op_ed.c"
|
||||
break;
|
||||
case PREFIX_DD:
|
||||
case PREFIX_FD:
|
||||
AddR(1);
|
||||
if( opcode == PREFIX_DD )
|
||||
{
|
||||
#define REGISTER regs->IX
|
||||
regs->we_are_on_ddfd = WE_ARE_ON_DD;
|
||||
#include "op_dd_fd.c"
|
||||
#undef REGISTER
|
||||
}
|
||||
else
|
||||
{
|
||||
#define REGISTER regs->IY
|
||||
regs->we_are_on_ddfd = WE_ARE_ON_FD;
|
||||
#include "op_dd_fd.c"
|
||||
#undef REGISTER
|
||||
}
|
||||
regs->we_are_on_ddfd = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* patch ROM loading routine */
|
||||
// address contributed by Ignacio Burgueño :)
|
||||
// if( r_PC == 0x0569 )
|
||||
if( r_PC >= 0x0556 && r_PC <= 0x056c )
|
||||
Z80Patch( regs );
|
||||
|
||||
/* check if it's time to do other hardware emulation */
|
||||
if( regs->ICount <= 0 )
|
||||
{
|
||||
tmpreg.W = Z80Hardware(regs);
|
||||
regs->ICount += regs->IPeriod;
|
||||
loop = regs->ICount + loop;
|
||||
|
||||
/* check if we must exit the emulation or there is an INT */
|
||||
if( tmpreg.W == INT_QUIT )
|
||||
return( regs->PC.W );
|
||||
if( tmpreg.W != INT_NOINT )
|
||||
Z80Interrupt( regs, tmpreg.W );
|
||||
}
|
||||
}
|
||||
|
||||
return(regs->PC.W);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*====================================================================
|
||||
void Z80Interrupt( Z80Regs *regs, word ivec )
|
||||
===================================================================*/
|
||||
void Z80Interrupt( Z80Regs *regs, word ivec )
|
||||
{
|
||||
word intaddress;
|
||||
|
||||
/* unhalt the computer */
|
||||
if( regs->halted == 1 )
|
||||
regs->halted = 0;
|
||||
|
||||
if( regs->IFF1 )
|
||||
{
|
||||
PUSH(PC);
|
||||
regs->IFF1 = 0;
|
||||
switch(regs->IM)
|
||||
{
|
||||
case 0: r_PC = 0x0038; AddCycles(12); break;
|
||||
case 1: r_PC = 0x0038; AddCycles(13); break;
|
||||
case 2: intaddress = (((regs->I & 0xFF)<<8) | 0xFF);
|
||||
regs->PC.B.l = Z80ReadMem(intaddress);
|
||||
regs->PC.B.h = Z80ReadMem(intaddress+1);
|
||||
AddCycles(19);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*====================================================================
|
||||
word Z80Hardware(register Z80Regs *regs)
|
||||
|
||||
Do here your emulated machine hardware emulation. Read Z80Execute()
|
||||
to know about how to quit emulation and generate interrupts.
|
||||
===================================================================*/
|
||||
word Z80Hardware( register Z80Regs *regs )
|
||||
{
|
||||
if(
|
||||
debug != 1 // && scanl >= 224
|
||||
)
|
||||
{
|
||||
;
|
||||
}
|
||||
return( INT_IRQ );
|
||||
}
|
||||
|
||||
|
||||
/*====================================================================
|
||||
void Z80Patch( register Z80Regs *regs )
|
||||
|
||||
Write here your patches to some z80 opcodes that are quite related
|
||||
to the emulated machines (i.e. maybe accessing to the I/O ports
|
||||
and so on), such as ED_FE opcode:
|
||||
|
||||
case ED_FE: Z80Patch(regs);
|
||||
break;
|
||||
|
||||
This allows "BIOS" patching (cassette loading, keyboard ...).
|
||||
===================================================================*/
|
||||
void Z80Patch( register Z80Regs *regs )
|
||||
{
|
||||
|
||||
///!!! if( tapfile != NULL )
|
||||
///!!! {
|
||||
///!!! LoadTAP( regs, tapfile );
|
||||
///!!! POP(PC);
|
||||
///!!! }
|
||||
|
||||
/*
|
||||
if( strlen(tapfile) != 0 )
|
||||
{
|
||||
if( LoadTapFile( regs, tapfile ) )
|
||||
{ POP(PC); }
|
||||
}
|
||||
else
|
||||
{
|
||||
FileMenu( tfont, 3, tapfile );
|
||||
if( strlen(tapfile) != 0 )
|
||||
if( LoadTapFile( regs, tapfile ) )
|
||||
{ POP(PC); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*====================================================================
|
||||
byte Z80Debug( register Z80Regs *regs )
|
||||
|
||||
This function is written for debugging purposes (it's supposed to
|
||||
be a debugger by itself!). It will debug a single opcode, given
|
||||
by the current PC address.
|
||||
|
||||
Return DEBUG_OK to state success and DEBUG_QUIT to quit emulation.
|
||||
===================================================================*/
|
||||
byte Z80Debug( register Z80Regs *regs )
|
||||
{
|
||||
return( DEBUG_QUIT );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*====================================================================
|
||||
byte Z80MemRead( register word address )
|
||||
|
||||
This function reads from the given memory address. It is not inlined,
|
||||
and it's written for debugging purposes.
|
||||
===================================================================*/
|
||||
byte Z80MemRead( register word address, Z80Regs *regs )
|
||||
{
|
||||
return(Z80ReadMem(address));
|
||||
}
|
||||
|
||||
|
||||
/*====================================================================
|
||||
void Z80MemWrite( register word address, register byte value )
|
||||
|
||||
This function writes on memory the given value. It is not inlined,
|
||||
ands it's written for debugging purposes.
|
||||
===================================================================*/
|
||||
void Z80MemWrite( register word address, register byte value, Z80Regs *regs )
|
||||
{
|
||||
Z80WriteMem( address, value, regs );
|
||||
}
|
||||
|
||||
|
||||
/*====================================================================
|
||||
byte Z80InPort( register word port )
|
||||
|
||||
This function reads from the given I/O port. It is not inlined,
|
||||
and it's written for debugging purposes.
|
||||
===================================================================*/
|
||||
byte Z80InPort( register word port )
|
||||
{
|
||||
int porth;
|
||||
int code = 0xFF;
|
||||
|
||||
porth = port >> 8;
|
||||
|
||||
if (!(porth & 0x01)) code &= fila[4][1];
|
||||
if (!(porth & 0x02)) code &= fila[3][1];
|
||||
if (!(porth & 0x04)) code &= fila[2][1];
|
||||
if (!(porth & 0x08)) code &= fila[1][1];
|
||||
if (!(porth & 0x10)) code &= fila[1][2];
|
||||
if (!(porth & 0x20)) code &= fila[2][2];
|
||||
if (!(porth & 0x40)) code &= fila[3][2];
|
||||
if (!(porth & 0x80)) code &= fila[4][2];
|
||||
|
||||
/*
|
||||
issue 2 emulation, thx to Raul Gomez!!!!!
|
||||
I should implement this also:
|
||||
if( !ear_on && mic_on )
|
||||
code &= 0xbf;
|
||||
where earon = bit 4 of the last OUT to the 0xFE port
|
||||
and micon = bit 3 of the last OUT to the 0xFE port
|
||||
*/
|
||||
code &= 0xbf;
|
||||
|
||||
if( (port & 0xFF) == 0xFF )
|
||||
{
|
||||
if( (rand() % 10) > 7 ) return(0xff);
|
||||
else return( rand()%0xFF );
|
||||
}
|
||||
|
||||
return( code );
|
||||
}
|
||||
|
||||
|
||||
/*====================================================================
|
||||
void Z80OutPort( register word port, register byte value )
|
||||
|
||||
This function outs a value to a given I/O port. It is not inlined,
|
||||
and it's written for debugging purposes.
|
||||
===================================================================*/
|
||||
void Z80OutPort( register Z80Regs *regs,
|
||||
register word port, register byte value )
|
||||
{
|
||||
/* change border colour */
|
||||
if( ! (port & 0x01) )
|
||||
regs->BorderColor = (value & 0x07);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*====================================================================
|
||||
static void Z80FlagTables ( void );
|
||||
|
||||
Creates a look-up table for future flag setting...
|
||||
Taken from fuse's sources. Thanks to Philip Kendall.
|
||||
===================================================================*/
|
||||
void Z80FlagTables(void)
|
||||
{
|
||||
int i,j,k;
|
||||
byte parity;
|
||||
|
||||
for(i=0;i<0x100;i++) {
|
||||
sz53_table[i]= i & ( FLAG_3 | FLAG_5 | FLAG_S );
|
||||
j=i; parity=0;
|
||||
for(k=0;k<8;k++) { parity ^= j & 1; j >>=1; }
|
||||
parity_table[i]= ( parity ? 0 : FLAG_P );
|
||||
sz53p_table[i] = sz53_table[i] | parity_table[i];
|
||||
}
|
||||
|
||||
sz53_table[0] |= FLAG_Z;
|
||||
sz53p_table[0] |= FLAG_Z;
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
/*=====================================================================
|
||||
z80.c -> Header file related to the Z80 emulation code.
|
||||
|
||||
Please read documentation files to know how this works :)
|
||||
|
||||
Thanks to Marat Fayzullin for writing the "How to write a Computer
|
||||
Eemulator" HOWTO. This emulator is based on his tutorials and the
|
||||
code organization (very readable!) of his "Z80 Portable Emulator".
|
||||
I've learnt a lot from it, and I've taken some ideas of his code
|
||||
to write this emulator.I think that almost all of the undocumented
|
||||
Z80 opcodes are covered on this emulator. I also asked Marat
|
||||
Fayzullin (by email) about ideas and so on (his Z80 emulator is
|
||||
quite good, so go check it :-).
|
||||
|
||||
Of course, I can't forget Raúl Gomez (he answered me thousands
|
||||
of email questions) and Philip Kendall. Whitout his ___kind___
|
||||
people surely you won't be reading this file now...
|
||||
|
||||
"Programming the Z80" (from Rodnay Zaks) and the comp.sys.sinclair
|
||||
FAQ were another excelent sources of info!
|
||||
|
||||
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.
|
||||
|
||||
Copyright (c) 2000 Santiago Romero Iglesias.
|
||||
Email: sromero@escomposlinux.org
|
||||
======================================================================*/
|
||||
|
||||
|
||||
#ifndef Z80_H
|
||||
#define Z80_H
|
||||
|
||||
#define USING_ALLEGRO
|
||||
|
||||
#define DEBUG
|
||||
#define _DEV_DEBUG_ /* development debugging */
|
||||
#define LOW_ENDIAN
|
||||
/*#define HI_ENDIAN */
|
||||
|
||||
/* Used by the Z80Debug() function */
|
||||
#define DEBUG_OK 1
|
||||
#define DEBUG_QUIT 0
|
||||
|
||||
|
||||
#define video vscreen
|
||||
|
||||
|
||||
/*=== Some common standard data types: ==============================*/
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned long dword;
|
||||
typedef signed char offset;
|
||||
|
||||
|
||||
/*--- Thanks to Philip Kendall for it's help using the flags --------*/
|
||||
extern byte halfcarry_add_table[];
|
||||
extern byte halfcarry_sub_table[];
|
||||
extern byte overflow_add_table[];
|
||||
extern byte overflow_sub_table[];
|
||||
extern byte sz53_table[];
|
||||
extern byte sz53p_table[];
|
||||
extern byte parity_table[];
|
||||
|
||||
extern byte ioblock_inc1_table[];
|
||||
extern byte ioblock_dec1_table[];
|
||||
extern byte ioblock_2_table[];
|
||||
|
||||
|
||||
/*=====================================================================
|
||||
Z80 Flag Register: ---------------------------------
|
||||
| 7 6 5 4 3 2 1 0 |
|
||||
---------------------------------
|
||||
| S Z x H x O/P N C |
|
||||
---------------------------------
|
||||
If (1) means that: S = Negative result.
|
||||
Z = Zero result.
|
||||
x = special cases (by opcode)
|
||||
H = Halfcarry/borrow.
|
||||
O/P = Overflow/Parity Flag.
|
||||
N = Substraction.
|
||||
C = Carry/borrow.
|
||||
====================================================================*/
|
||||
#define S_FLAG 0x80
|
||||
#define Z_FLAG 0x40
|
||||
#define H_FLAG 0x10
|
||||
#define P_FLAG 0x04
|
||||
#define O_FLAG 0x04
|
||||
#define N_FLAG 0x02
|
||||
#define C_FLAG 0x01
|
||||
|
||||
|
||||
/*
|
||||
Defines for interrupts and special Z80Hardware() codes:
|
||||
=======================================================================
|
||||
INT_QUIT = Exit the emulation (for Z80Run())
|
||||
INT_NOINT = No interrupt required
|
||||
INT_IRQ = Standard RST 38h interrupt
|
||||
INT_NMI = Non-maskerable interrupt
|
||||
*/
|
||||
#define INT_QUIT 0xFFFE
|
||||
#define INT_NOINT 0xFFFF
|
||||
#define INT_IRQ 0x0038
|
||||
#define INT_NMI 0x0066
|
||||
|
||||
|
||||
|
||||
/*=== A register is defined as follows: =============================*/
|
||||
typedef union
|
||||
{
|
||||
#ifdef LOW_ENDIAN
|
||||
struct
|
||||
{
|
||||
byte l,h;
|
||||
} B;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
byte h,l;
|
||||
} B;
|
||||
#endif
|
||||
word W;
|
||||
} eword;
|
||||
|
||||
|
||||
#define WE_ARE_ON_DD 1
|
||||
#define WE_ARE_ON_FD 2
|
||||
|
||||
/*=== Now we define the Z80 registers using the previous definition =*/
|
||||
typedef struct
|
||||
{
|
||||
char machine_type;
|
||||
byte *RAM;
|
||||
int we_are_on_ddfd;
|
||||
|
||||
/* general and shadow z80 registers */
|
||||
eword AF, BC, DE, HL, IX, IY, PC, SP, R,
|
||||
AFs, BCs, DEs, HLs;
|
||||
|
||||
/* IFF and I registers, used on interrupts. */
|
||||
byte IFF1, IFF2, I, halted;
|
||||
char IM;
|
||||
word IRequest;
|
||||
|
||||
/* the following is to take care of cycle counting */
|
||||
int IPeriod, ICount, IBackup;
|
||||
|
||||
/* DecodingErrors = set this to 1 for debugging purposes in order
|
||||
to trap undocumented or non implemented opcodes.
|
||||
Trace = set this to 1 to start tracing. It's also set
|
||||
when PC reaches TrapAddress value. */
|
||||
byte DecodingErrors;
|
||||
word TrapAddress;
|
||||
byte Trace, dobreak;
|
||||
byte BorderColor;
|
||||
|
||||
} Z80Regs;
|
||||
|
||||
|
||||
/*====================================================================
|
||||
Function declarations, read the .c file to know what they do.
|
||||
===================================================================*/
|
||||
void Z80Reset( register Z80Regs *regs, int );
|
||||
void Z80Interrupt( register Z80Regs *, register word );
|
||||
word Z80Run( register Z80Regs *, int );
|
||||
byte Z80MemRead( register word, Z80Regs * );
|
||||
void Z80MemWrite( register word, register byte, Z80Regs * );
|
||||
byte Z80InPort( register word );
|
||||
void Z80OutPort( register Z80Regs *regs, register word, register byte );
|
||||
void Z80Patch( register Z80Regs * );
|
||||
byte Z80Debug( register Z80Regs * );
|
||||
word Z80Hardware( register Z80Regs * );
|
||||
|
||||
void Z80FlagTables(void);
|
||||
word ParseOpcode( char *, char *, char *, word, Z80Regs * );
|
||||
word Z80Dissasembler ( Z80Regs *, char *, char * );
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,152 @@
|
|||
|
||||
*******************************RUSSIAN****************************************
|
||||
|
||||
==Î ïðîãðàììå FCEU==
|
||||
FCE Ultra - îäèí èç ëó÷øèõ ýìóëÿòîðîâ NES íà Linux, DOS, Windows,
|
||||
BeOS, Mac OS X, à òåïåðü è íà Kolibri è Menuet!
|
||||
|
||||
Ñàéò: http://fceultra.sourceforge.net
|
||||
|
||||
Ïîääåðæèâàåìûå ìàïïåðû: 0-11, 13, 15-19, 21-26, 32-34, 40-49, 51, 52, 57, 61, 64-80,
|
||||
82, 83, 85-90, 92-97, 99, 105, 107, 112-119, 140, 144,
|
||||
151-156, 180, 182, 184, 189, 225-229, 232, 234, 235, 240,
|
||||
242, 246, 248-250
|
||||
|
||||
Ïîñëå çàïóñêà ïðîãðàììû íóæíî ïðîïèñàòü ïîëíûé ïóòü ê íóæíîìó ôàéëó NES
|
||||
è íàæàòü Enter (ïóòü îòîáðàæàåòñÿ â âåðõíåé ÷àñòè îêíà).
|
||||
|
||||
Âåðñèÿ ýìóëÿòîðà: 0.96
|
||||
Âåðñèÿ ïîðòà: 0.3
|
||||
|
||||
==Ïîðòåð==
|
||||
Asper
|
||||
Ïèñàòü ñþäà: asper.85@mail.ru
|
||||
|
||||
Îñíîâíûå êëàâèøè:
|
||||
|
||||
Äëÿ ýìóëèðóåìîãî óñòðîéñòâà Family BASIC Keyboard:
|
||||
Âêëþ÷èòü/Âûêëþ÷èòü Ââîä Êëàâèàòóðû Scroll Lock
|
||||
(âêëþ÷åíèå ââîäà ñ ýìóëèðóåìîé êëàâèàòóðû îòêëþ÷àåò
|
||||
êîììàíäíûå êëàâèøè)
|
||||
Âñå ýìóëèðóåìûå êëàâèøè îòîáðàæàþòñÿ íà áëèæàéøóþ äîñòóïíóþ êëàâèøó
|
||||
íà êëàâèàòóðå ÏÊ çà íåáîëüøèìè èñêëþ÷åíèÿìè. Ýìóëèðóåìàÿ êëàâèøà "@"
|
||||
îòîáðàæàåòñÿ íà êëàâèøó "`"(grave), è ýìóëèðóåìàÿ êëàâèøà "kana"
|
||||
îòîáðàæàåòñÿ íà êëàâèøó "Insert" (â áëîêå êëàâèø ðàçìåðà 3x2 íàä
|
||||
êóðñîðíûìè êëàâèøàìè).
|
||||
|
||||
Äëÿ ýìóëèðóåìûõ óñòðîéñòâ game pads:
|
||||
A Turbo B
|
||||
S Turbo A
|
||||
Left Control or Z or Space B
|
||||
Left Alt or X A
|
||||
Enter/Return Ñòàðò
|
||||
Tab or BackSpace Ñåëåêò
|
||||
Cursor Down Âíèç
|
||||
Cursor Up Ââåðõ
|
||||
Cursor Left Âëåâî
|
||||
Cursor Right Âïðàâî
|
||||
|
||||
Äëÿ ýìóëèðóåìûõ óñòðîéñòâ power pads(êëàâèøè ñîîòâåòñòâóþò ðàñïîëîæåíèþ
|
||||
êíîïîê íà ñòîðîíå "B"):
|
||||
O P [ ]
|
||||
K L ; '
|
||||
M , . /
|
||||
|
||||
Äëÿ FDS èãð:
|
||||
F6 Âûáðàòü äèñê/ñòîðîíó äèñêà.
|
||||
F8 Èçâëå÷ü/Âñòàâèòü äèñê.
|
||||
|
||||
Äëÿ VS Unisystem èãð:
|
||||
F8 Âñòàâèòü ìîíåòó.
|
||||
F6 Îòîáðàçèòü/Ñêðûòü dip ïåðåêëþ÷àòåëè.
|
||||
1-8 Ïåðåêëþ÷èòü dip ïåðåêëþ÷àòåëè (êîãäà dip
|
||||
ïåðåêëþ÷àòåëè îòîáàæàþòñÿ).
|
||||
|
||||
0-9 Âûáðàòü ñëîò ñîõðàíåíèÿ.
|
||||
Caps Lock Âûáðàòü âèðòóàëüíûé äæîéñòèê.
|
||||
|
||||
F2 Ìàññøòàáèðîâàòü îêíî.
|
||||
F3 Îòêðûòü ôàéë.
|
||||
F5/F7 Ñîõðàíèòü/Çàãðóçèòü ñîõðàíåíèå.
|
||||
F9 Ñîõðàíèòü ñíèìîê ýêðàíà.
|
||||
F10 Ïåðåçàãðóçêà.
|
||||
F11 Âûêëþ÷èòü/Âêëþ÷èòü.
|
||||
ESC/F12 Âûõîä.
|
||||
|
||||
|
||||
*******************************ENGLISH****************************************
|
||||
|
||||
|
||||
==About program FCEU==
|
||||
FCE Ultra - is is one of the best emulators of NES on Linux, DOS, Windows,
|
||||
BeOS, Mac OS X, and now on Kolibri and Menuet!
|
||||
|
||||
Website: http://fceultra.sourceforge.net
|
||||
|
||||
Supported mappers: 0-11, 13, 15-19, 21-26, 32-34, 40-49, 51, 52, 57, 61, 64-80,
|
||||
82, 83, 85-90, 92-97, 99, 105, 107, 112-119, 140, 144,
|
||||
151-156, 180, 182, 184, 189, 225-229, 232, 234, 235, 240,
|
||||
242, 246, 248-250
|
||||
|
||||
After program executing you have to input full path to the NES file that you want
|
||||
to be executed and press Enter (the path echo on the upper part of the window).
|
||||
|
||||
Emulator version number: 0.96
|
||||
Port version 0.3
|
||||
|
||||
==Porter==
|
||||
Asper
|
||||
mailto: asper.85@mail.ru
|
||||
|
||||
|
||||
Main keys:
|
||||
|
||||
For emulated Family BASIC Keyboard:
|
||||
Enable/Disable Keyboard Input Scroll Lock
|
||||
(enabling emulated keyboard input will disable
|
||||
commands keys)
|
||||
All emulated keys are mapped to the closest open key on the PC
|
||||
keyboard, with a few exceptions. The emulated "@" key is
|
||||
mapped to the "`"(grave) key, and the emulated "kana" key
|
||||
is mapped to the "Insert" key(in the 3x2 key block above the
|
||||
cursor keys).
|
||||
|
||||
For emulated game pads:
|
||||
A Turbo B
|
||||
S Turbo A
|
||||
Left Control or Z or Space B
|
||||
Left Alt or X A
|
||||
Enter/Return Start
|
||||
Tab or BackSpace Select
|
||||
Cursor Down Down
|
||||
Cursor Up Up
|
||||
Cursor Left Left
|
||||
Cursor Right Right
|
||||
|
||||
For emulated power pads(keys correspond to button locations on
|
||||
side "B"):
|
||||
O P [ ]
|
||||
K L ; '
|
||||
M , . /
|
||||
|
||||
For FDS games:
|
||||
F6 Select disk/disk side.
|
||||
F8 Eject/Insert disk.
|
||||
|
||||
For VS Unisystem games:
|
||||
F8 Insert coin.
|
||||
F6 Show/Hide dip switches.
|
||||
1-8 Toggle dip switches(when dip switches
|
||||
are shown).
|
||||
|
||||
0-9 Select save state.
|
||||
Caps Lock Select virtual joystick.
|
||||
|
||||
F2 Scale window.
|
||||
F3 Open file.
|
||||
F5/F7 Save/Load state.
|
||||
F9 Save screen snapshot.
|
||||
F10 Reset.
|
||||
F11 Power off/on.
|
||||
ESC/F12 Exit.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
01.09.08 == Port v0.1 == Emulator v0.42
|
||||
- çàãðóçêà NES ôàéëîâ | - load NES files
|
||||
- èñïîëíåíèå NES ôàéëîâ | - execute NES files
|
||||
- ìàññøòàáèðîâàíèå ðàçìåðà îêíà | - scale window size
|
||||
- ðàáîòàåò â ÎÑ Kolibri è Menuet | - work in OS Kolibri and Menuet
|
||||
|
||||
|
||||
24.10.08 == Port v0.2 == Emulator v0.42
|
||||
- ðàáîòà ñ ñèñ. ôóíêöèåé 70 | - working with sys. function 70
|
||||
- ñîçäàíèå ñîõðàíåíèé | - make saves
|
||||
- çàãðóçêà ñîõðàíåíèé | - load saves
|
||||
- ñîçäàíèå ñêðèíøîòîâ | - make screenshots
|
||||
- äîáàâëåíû êëàâèøè Òóðáî A è Òóðáî B | - Turbo A and Turbo B keys were added
|
||||
- ðàáîòàåò òîëüêî â ÎÑ Kolibri èç-çà | - work in OS Kolibri only because of
|
||||
èñïîëüçîâàíèÿ ñèñ. ôóíêöèè 70 | using sys. function 70
|
||||
|
||||
09.07.09 == Port v0.3 == Emulator v0.96
|
||||
- äîáàâëåíî 33 íîâûõ ìàïïåðà | - 33 new mappers were add
|
||||
( 48, 51, 52, 57, 61, 72, 74, 77, 82, 83, 88, 92, 96, 114, 115-117, 140,
|
||||
144, 152-156, 189, 227, 232, 234, 235, 242, 248-250 )
|
||||
|
||||
- äîáàâëåíû íîâûå ýìóëèðóåìûå | - new emulated devices were add
|
||||
óñòðîéñòâà |
|
||||
( power pads, game pads, zapper, arkanoid, shadow, Family BASIC Keyboard )
|
||||
|
||||
- âûáîð âèðòóàëüíîãî äæîéñòèêà | - select virtual joysticks
|
||||
- óñêîðåííûé âûâîä ãðàôèêè | - faster graphics output
|
||||
- âûâîä fps | - fps output
|
||||
- ñîîáùåíèÿ òåïåðü âûâîäÿòñÿ íà äîñêó | - messages now output to the debug board
|
||||
îòëàäêè |
|
||||
- ñì. ôàéë "ChangeLog.txt" ÷òîáû | - see file "ChangeLog.txt" for full list of changes
|
||||
ïðîñìîòðåòü âåñü ñïèñîê èçìåíåíèé |
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue