Previous 15994 Revisions Next

r2822 Friday 6th June, 2008 at 00:38:01 UTC by Nathan Woods
Updated to MAME 0.125u4 core
[ROOT]makefile
[docs]messnew.txt
[src/emu]cheat.c cpuexec.h cpuintrf.c inptport.c inputseq.c memory.c romload.c tilemap.c validity.c video.c
[src/emu/cpu]cpu.mak drcbec.c drcbex64.c drcbex86.c drcfe.c drcuml.c drcuml.h drcumld.c drcumlsh.h ssp1610 x64drc.c x64drc.h x86drc.c x86drc.h
[src/emu/cpu/cop400]410ops.c cop400.h cop410.c cop420.c
[src/emu/cpu/i386]i386dasm.c
[src/emu/cpu/minx]minx.c minxfunc.h minxopce.h minxopcf.h minxops.h
[src/emu/cpu/mips]mdrc64.c mdrcold.c mips3drc.c
[src/emu/cpu/powerpc]ppc.c ppc.h ppc403.c ppc_dasm.c ppc_mem.c ppccom.c* ppccom.h* ppcdrc.c ppcdrco.c ppcfe.c* ppcfe.h*
[src/emu/cpu/saturn]sat.h
[src/emu/machine]53c810.c 53c810.h
[src/emu/sound]c352.c discrete.h scsp.c segapcm.c
[src/mame]mame.mak mamedriv.c
[src/mame/audio]asteroid.c atarijsa.c canyon.c cclimber.c fghtbskt.c seibu.c suna8.c
[src/mame/drivers]20pacgal.c 2mindril.c 8080bw.c acommand.c actfancr.c alpha68k.c ampoker2.c amspdwy.c angelkds.c aquarium.c arabian.c artmagic.c asterix.c astinvad.c astrof.c atarig1.c atarig42.c atarigx2.c atarisy1.c atarisy2.c attckufo.c aztarac.c backfire.c badlands.c bagman.c balsente.c batman.c beathead.c bfcobra.c blackt96.c* bloodbro.c bmcbowl.c bnstars.c boogwing.c brkthru.c btime.c calomega.c carpolo.c cave.c cbasebal.c cclimber.c champbas.c cidelsa.c cinemat.c circusc.c cischeat.c cloak.c cojag.c coolpool.c coolridr.c cosmic.c cps3.c crystal.c cshooter.c cvs.c dambustr.c darkmist.c dblewing.c ddragon.c deco156.c deco32.c deco_mlc.c dgpix.c dietgo.c dreamwld.c dwarfd.c dynadice.c dynax.c enigma2.c epos.c eprom.c equites.c exidy440.c filetto.c finalizr.c firebeat.c galaga.c galaxold.c galdrvr.c gameplan.c gatron.c gauntlet.c gbusters.c gladiatr.c goodejan.c gstream.c gticlub.c gyruss.c homerun.c hornet.c hyperspt.c hyprduel.c imolagp.c itech8.c itgambl2.c* itgamble.c* jack.c jailbrek.c junofrst.c kaneko16.c karnov.c kinstb.c konamim2.c lethalj.c looping.c ltcasino.c lvcards.c lwings.c maxaflex.c mazerbla.c mcr3.c mcr68.c meadows.c megasys1.c megazone.c midtunit.c mitchell.c mlanding.c model2.c model3.c mpu4drvr.c ms32.c multigam.c mw8080bw.c namcona1.c namcos21.c namcos23.c neogeo.c nmg5.c nmk16.c nwk-tr.c nycaptor.c offtwall.c omegrace.c pacman.c pgm.c pktgaldx.c playmark.c plygonet.c policetr.c quizo.c raiden2.c rainbow.c rampart.c realbrk.c redclash.c rocnrope.c rollrace.c royalmah.c rpunch.c sbasketb.c scobra.c segahang.c segaorun.c segas16a.c segas16b.c segas24.c seibuspi.c seta.c shadfrce.c sidearms.c simpl156.c skydiver.c sliver.c snk.c snookr10.c snowbros.c srmp5.c srmp6.c sspeedr.c sstrangr.c superqix.c supertnk.c suprnova.c system1.c taito_f2.c tank8.c tatsumi.c tattack.c tcl.c tecmosys.c tetriunk.c thayers.c thedeep.c thunderj.c tmaster.c tmnt.c tnzs.c toki.c toobin.c trackfld.c tryout.c tumbleb.c ultrsprt.c unico.c viper.c vsnes.c warriorb.c wecleman.c wilytowr.c wldarrow.c zaccaria.c zaxxon.c zr107.c
[src/mame/includes]cps1.h decocrpt.h ms32.h* pgm.h* tecmosys.h*
[src/mame/layout]snookr10.lay*
[src/mame/machine]ajax.c arkanoid.c asteroid.c atarifb.c deco102.c deco156.c fd1089.c fd1089.h* galaxold.c konami.c konami1.c* konami1.h* midwunit.c namcos1.c pckeybrd.c pgmcrypt.c pgmprot.c pgmy2ks.c playch10.c scramble.c tecmosys.c* vsnes.c
[src/mame/video]8080bw.c aeroboto.c epos.c fuukifg2.c fuukifg3.c galaxian.c galaxold.c ginganin.c hyhoo.c konamiic.c mitchell.c model3.c ms32.c mystwarr.c nbmj8688.c nbmj8891.c nbmj8991.c nbmj9195.c neogeo.c niyanpai.c nmk16.c pastelg.c pgm.c segaic16.c snookr10.c ssv.c st0016.c suprnova.c taitojc.c tmnt.c tubep.c xevious.c
[src/mess]mess.mak
[src/mess/drivers]bebox.c
[src/mess/machine]bebox.c

src/mame/audio/suna8.c
r2821r2822
3535
3636void suna8_sh_start(void)
3737{
38   int i;
38   int i, len = memory_region_length(REGION_SOUND1);
3939   UINT8 *ROM = memory_region(REGION_SOUND1);
4040
41   samplebuf = auto_malloc(memory_region_length(REGION_SOUND1) * sizeof(samplebuf[0]));
41   samplebuf = auto_malloc(len * sizeof(samplebuf[0]));
4242
43   for(i=0;i<memory_region_length(REGION_SOUND1);i++)
43   for(i=0;i<len;i++)
4444      samplebuf[i] = (INT8)(ROM[i] ^ 0x80) * 256;
4545}
src/mame/audio/canyon.c
r2821r2822
1616
1717WRITE8_HANDLER( canyon_motor_w )
1818{
19   discrete_sound_w(machine, CANYON_MOTOR1_DATA + (offset & 0x01), data & 0x0f);
19   discrete_sound_w(machine, NODE_RELATIVE(CANYON_MOTOR1_DATA, (offset & 0x01)), data & 0x0f);
2020}
2121
2222
r2821r2822
2828
2929WRITE8_HANDLER( canyon_attract_w )
3030{
31   discrete_sound_w(machine, CANYON_ATTRACT1_EN + (offset & 0x01), offset & 0x02);
31   discrete_sound_w(machine, NODE_RELATIVE(CANYON_ATTRACT1_EN, (offset & 0x01)), offset & 0x02);
3232}
3333
3434
3535WRITE8_HANDLER( canyon_whistle_w )
3636{
37   discrete_sound_w(machine, CANYON_WHISTLE1_EN + (offset & 0x01), offset & 0x02);
37   discrete_sound_w(machine, NODE_RELATIVE(CANYON_WHISTLE1_EN, (offset & 0x01)), offset & 0x02);
3838}
3939
4040
src/mame/audio/atarijsa.c
r2821r2822
107107void atarijsa_init(running_machine *machine, int testport, int testmask)
108108{
109109   int i;
110   UINT8 *rgn;
110111
111112   /* copy in the parameters */
112113   cpu_num = mame_find_cpu_index(machine, "jsa");
r2821r2822
115116   test_mask = testmask;
116117
117118   /* predetermine the bank base */
118   bank_base = &memory_region(REGION_CPU1+cpu_num)[0x03000];
119   bank_source_data = &memory_region(REGION_CPU1+cpu_num)[0x10000];
119   rgn = memory_region(REGION_CPU1+cpu_num);
120   bank_base = &rgn[0x03000];
121   bank_source_data = &rgn[0x10000];
120122
121123   /* determine which sound hardware is installed */
122124   has_tms5220 = has_oki6295 = has_pokey = has_ym2151 = 0;
src/mame/audio/asteroid.c
r2821r2822
308308
309309WRITE8_HANDLER( asteroid_sounds_w )
310310{
311   discrete_sound_w(machine, ASTEROID_SAUCER_SND_EN + offset, data & 0x80);
311   discrete_sound_w(machine, NODE_RELATIVE(ASTEROID_SAUCER_SND_EN, offset), data & 0x80);
312312}
313313
314314WRITE8_HANDLER( astdelux_sounds_w )
src/mame/audio/cclimber.c
r2821r2822
2424static void cclimber_play_sample(int start,int freq,int volume)
2525{
2626   int len;
27   int romlen = memory_region_length(REGION_SOUND1);
2728   const UINT8 *rom = memory_region(REGION_SOUND1);
2829
2930
r2821r2822
3132
3233   /* decode the rom samples */
3334   len = 0;
34   while (start + len < memory_region_length(REGION_SOUND1) && rom[start+len] != 0x70)
35   while (start + len < romlen && rom[start+len] != 0x70)
3536   {
3637      int sample;
3738
src/mame/audio/seibu.c
r2821r2822
33    Seibu Sound System v1.02, designed 1986 by Seibu Kaihatsu
44
55    The Seibu sound system comprises of a Z80A, a YM3812, a YM3931*, and
6    an Oki MSM6205.  As well as sound the Z80 can controls coins and pass
6    an Oki MSM6295.  As well as sound the Z80 can controls coins and pass
77    data to the main cpu.  There are a few little quirks that make it
88    worthwhile emulating in a seperate file:
99
r2821r2822
198198void seibu_adpcm_decrypt(int region)
199199{
200200   UINT8 *ROM = memory_region(region);
201   int len = memory_region_length(region);
201202   int i;
202203
203   for (i = 0; i < memory_region_length(region); i++)
204   for (i = 0; i < len; i++)
204205   {
205206      ROM[i] = BITSWAP8(ROM[i], 7, 5, 3, 1, 6, 4, 2, 0);
206207   }
src/mame/audio/fghtbskt.c
r2821r2822
1717
1818void fghtbskt_sh_start(void)
1919{
20   int i;
20   int i, len = memory_region_length(REGION_SOUND1);
2121   UINT8 *ROM = memory_region(REGION_SOUND1);
2222
23   samplebuf = auto_malloc(memory_region_length(REGION_SOUND1) * 2);
23   samplebuf = auto_malloc(len * 2);
2424
25   for(i=0;i<memory_region_length(REGION_SOUND1);i++)
25   for(i=0;i<len;i++)
2626      samplebuf[i] = ((INT8)(ROM[i] ^ 0x80)) * 256;
2727}
src/mame/machine/konami.c
r2821r2822
1/***************************************************************************
2
3  The Konami_1 CPU is a 6809 with opcodes scrambled. Here is how to
4  descramble them.
5
6***************************************************************************/
7
8#include "driver.h"
9
10
11UINT8 *konami1_decrypted;
12
13UINT8 konami1_decodebyte( UINT8 opcode, UINT16 address )
14{
15/*
16>
17> CPU_D7 = (EPROM_D7 & ~ADDRESS_1) | (~EPROM_D7 & ADDRESS_1)  >
18> CPU_D6 = EPROM_D6
19>
20> CPU_D5 = (EPROM_D5 & ADDRESS_1) | (~EPROM_D5 & ~ADDRESS_1) >
21> CPU_D4 = EPROM_D4
22>
23> CPU_D3 = (EPROM_D3 & ~ADDRESS_3) | (~EPROM_D3 & ADDRESS_3) >
24> CPU_D2 = EPROM_D2
25>
26> CPU_D1 = (EPROM_D1 & ADDRESS_3) | (~EPROM_D1 & ~ADDRESS_3) >
27> CPU_D0 = EPROM_D0
28>
29*/
30   UINT8 xormask;
31
32
33   xormask = 0;
34   if (address & 0x02) xormask |= 0x80;
35   else xormask |= 0x20;
36   if (address & 0x08) xormask |= 0x08;
37   else xormask |= 0x02;
38
39   return opcode ^ xormask;
40}
41
42
43
44static void decode(int cpu)
45{
46   UINT8 *rom = memory_region(REGION_CPU1+cpu);
47   int size = memory_region_length(REGION_CPU1+cpu);
48   int A;
49
50   konami1_decrypted = auto_malloc(size);
51   memory_set_decrypted_region(cpu, 0x0000, 0xffff, konami1_decrypted);
52
53   for (A = 0;A < size;A++)
54   {
55      konami1_decrypted[A] = konami1_decodebyte(rom[A],A);
56   }
57}
58
59void konami1_decode(void)
60{
61   decode(0);
62}
63
64void konami1_decode_cpu2(void)
65{
66   decode(1);
67}
src/mame/machine/fd1089.c
r2821r2822
7070***************************************************************************/
7171
7272#include "driver.h"
73#include "fd1089.h"
7374
7475
7576/* 317-0013A FD1089B */
src/mame/machine/fd1089.h
r0r2822
1void *fd1089_get_decrypted_base(void);
2void fd1089_decrypt_0013A(void);
3void fd1089_decrypt_0018(void);
4void fd1089_decrypt_alexkidd(void);
5void fd1089_decrypt_0022(void);
6void fd1089_decrypt_0024(void);
7void fd1089_decrypt_0027(void);
8void fd1089_decrypt_0028(void);
9void fd1089_decrypt_0033(void);
10void fd1089_decrypt_0034(void);
11void fd1089_decrypt_0037(void);
12void fd1089_decrypt_0167(void);
13void fd1089_decrypt_0168(void);
14void fd1089_decrypt_5021(void);
src/mame/machine/playch10.c
r2821r2822
397397         case 3:   /* program banking */
398398            {
399399               int bank = ( mmc1_shiftreg & mmc1_rom_mask ) * 0x4000;
400               UINT8 *prg = memory_region( REGION_CPU2 );
400401
401402               if ( !size16k )
402403               {
403404                  /* switch 32k */
404                  memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x010000+bank], 0x8000 );
405                  memcpy( &prg[0x08000], &prg[0x010000+bank], 0x8000 );
405406               }
406407               else
407408               {
r2821r2822
409410                  if ( switchlow )
410411                  {
411412                     /* low */
412                     memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x010000+bank], 0x4000 );
413                     memcpy( &prg[0x08000], &prg[0x010000+bank], 0x4000 );
413414                  }
414415                  else
415416                  {
416417                     /* high */
417                     memcpy( &memory_region( REGION_CPU2 )[0x0c000], &memory_region( REGION_CPU2 )[0x010000+bank], 0x4000 );
418                     memcpy( &prg[0x0c000], &prg[0x010000+bank], 0x4000 );
418419                  }
419420               }
420421            }
r2821r2822
451452static WRITE8_HANDLER( bboard_rom_switch_w )
452453{
453454   int bankoffset = 0x10000 + ( ( data & 7 ) * 0x4000 );
455   UINT8 *prg = memory_region( REGION_CPU2 );
454456
455   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[bankoffset], 0x4000 );
457   memcpy( &prg[0x08000], &prg[bankoffset], 0x4000 );
456458}
457459
458460DRIVER_INIT( pcbboard )
459461{
462   UINT8 *prg = memory_region( REGION_CPU2 );
463
460464   /* We do manual banking, in case the code falls through */
461465   /* Copy the initial banks */
462   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x28000], 0x8000 );
466   memcpy( &prg[0x08000], &prg[0x28000], 0x8000 );
463467
464468   /* Roms are banked at $8000 to $bfff */
465469   memory_install_write8_handler(machine, 1, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, bboard_rom_switch_w );
r2821r2822
495499
496500DRIVER_INIT( pcdboard )
497501{
502   UINT8 *prg = memory_region( REGION_CPU2 );
503
498504   /* We do manual banking, in case the code falls through */
499505   /* Copy the initial banks */
500   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x28000], 0x8000 );
506   memcpy( &prg[0x08000], &prg[0x28000], 0x8000 );
501507
502508   mmc1_rom_mask = 0x07;
503509
r2821r2822
557563      case 0x2000: /* code bank switching */
558564         {
559565            int bankoffset = 0x10000 + ( data & 0x0f ) * 0x2000;
560            memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[bankoffset], 0x2000 );
566            UINT8 *prg = memory_region( REGION_CPU2 );
567            memcpy( &prg[0x08000], &prg[bankoffset], 0x2000 );
561568         }
562569      break;
563570
r2821r2822
594601
595602DRIVER_INIT( pceboard )
596603{
604   UINT8 *prg = memory_region( REGION_CPU2 );
605
597606   /* We do manual banking, in case the code falls through */
598607   /* Copy the initial banks */
599   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x28000], 0x8000 );
608   memcpy( &prg[0x08000], &prg[0x28000], 0x8000 );
600609
601610   /* basically a mapper 9 on a nes */
602611   memory_install_write8_handler(machine, 1, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, eboard_rom_switch_w );
r2821r2822
618627
619628DRIVER_INIT( pcfboard )
620629{
630   UINT8 *prg = memory_region( REGION_CPU2 );
631
621632   /* We do manual banking, in case the code falls through */
622633   /* Copy the initial banks */
623   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x28000], 0x8000 );
634   memcpy( &prg[0x08000], &prg[0x28000], 0x8000 );
624635
625636   mmc1_rom_mask = 0x07;
626637
r2821r2822
678689         if ( gboard_last_bank != ( data & 0xc0 ) )
679690         {
680691            int bank;
692            UINT8 *prg = memory_region( REGION_CPU2 );
681693
682694            /* reset the banks */
683695            if ( gboard_command & 0x40 )
r2821r2822
685697               /* high bank */
686698               bank = gboard_banks[0] * 0x2000 + 0x10000;
687699
688               memcpy( &memory_region( REGION_CPU2 )[0x0c000], &memory_region( REGION_CPU2 )[bank], 0x2000 );
689               memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x4c000], 0x2000 );
700               memcpy( &prg[0x0c000], &prg[bank], 0x2000 );
701               memcpy( &prg[0x08000], &prg[0x4c000], 0x2000 );
690702            }
691703            else
692704            {
693705               /* low bank */
694706               bank = gboard_banks[0] * 0x2000 + 0x10000;
695707
696               memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[bank], 0x2000 );
697               memcpy( &memory_region( REGION_CPU2 )[0x0c000], &memory_region( REGION_CPU2 )[0x4c000], 0x2000 );
708               memcpy( &prg[0x08000], &prg[bank], 0x2000 );
709               memcpy( &prg[0x0c000], &prg[0x4c000], 0x2000 );
698710            }
699711
700712            /* mid bank */
701713            bank = gboard_banks[1] * 0x2000 + 0x10000;
702            memcpy( &memory_region( REGION_CPU2 )[0x0a000], &memory_region( REGION_CPU2 )[bank], 0x2000 );
714            memcpy( &prg[0x0a000], &prg[bank], 0x2000 );
703715
704716            gboard_last_bank = data & 0xc0;
705717         }
r2821r2822
729741               break;
730742
731743               case 6: /* program banking */
744               {
745                  UINT8 *prg = memory_region( REGION_CPU2 );
732746                  if ( gboard_command & 0x40 )
733747                  {
734748                     /* high bank */
735749                     gboard_banks[0] = data & 0x1f;
736750                     bank = ( gboard_banks[0] ) * 0x2000 + 0x10000;
737751
738                     memcpy( &memory_region( REGION_CPU2 )[0x0c000], &memory_region( REGION_CPU2 )[bank], 0x2000 );
739                     memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x4c000], 0x2000 );
752                     memcpy( &prg[0x0c000], &prg[bank], 0x2000 );
753                     memcpy( &prg[0x08000], &prg[0x4c000], 0x2000 );
740754                  }
741755                  else
742756                  {
r2821r2822
744758                     gboard_banks[0] = data & 0x1f;
745759                     bank = ( gboard_banks[0] ) * 0x2000 + 0x10000;
746760
747                     memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[bank], 0x2000 );
748                     memcpy( &memory_region( REGION_CPU2 )[0x0c000], &memory_region( REGION_CPU2 )[0x4c000], 0x2000 );
761                     memcpy( &prg[0x08000], &prg[bank], 0x2000 );
762                     memcpy( &prg[0x0c000], &prg[0x4c000], 0x2000 );
749763                  }
764               }
750765               break;
751766
752767               case 7: /* program banking */
753768                  {
754769                     /* mid bank */
770                     UINT8 *prg = memory_region( REGION_CPU2 );
755771                     gboard_banks[1] = data & 0x1f;
756772                     bank = gboard_banks[1] * 0x2000 + 0x10000;
757773
758                     memcpy( &memory_region( REGION_CPU2 )[0x0a000], &memory_region( REGION_CPU2 )[bank], 0x2000 );
774                     memcpy( &prg[0x0a000], &prg[bank], 0x2000 );
759775                  }
760776               break;
761777            }
r2821r2822
796812
797813DRIVER_INIT( pcgboard )
798814{
815   UINT8 *prg = memory_region( REGION_CPU2 );
816
799817   /* We do manual banking, in case the code falls through */
800818   /* Copy the initial banks */
801   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x4c000], 0x4000 );
802   memcpy( &memory_region( REGION_CPU2 )[0x0c000], &memory_region( REGION_CPU2 )[0x4c000], 0x4000 );
819   memcpy( &prg[0x08000], &prg[0x4c000], 0x4000 );
820   memcpy( &prg[0x0c000], &prg[0x4c000], 0x4000 );
803821
804822   /* MMC3 mapper at writes to $8000-$ffff */
805823   memory_install_write8_handler(machine, 1, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, gboard_rom_switch_w );
r2821r2822
834852static WRITE8_HANDLER( iboard_rom_switch_w )
835853{
836854   int bank = data & 7;
855   UINT8 *prg = memory_region( REGION_CPU2 );
837856
838857   if ( data & 0x10 )
839858      ppu2c0x_set_mirroring( 0, PPU_MIRROR_HIGH );
840859   else
841860      ppu2c0x_set_mirroring( 0, PPU_MIRROR_LOW );
842861
843   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[bank * 0x8000 + 0x10000], 0x8000 );
862   memcpy( &prg[0x08000], &prg[bank * 0x8000 + 0x10000], 0x8000 );
844863}
845864
846865DRIVER_INIT( pciboard )
847866{
867   UINT8 *prg = memory_region( REGION_CPU2 );
868
848869   /* We do manual banking, in case the code falls through */
849870   /* Copy the initial banks */
850   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x10000], 0x8000 );
871   memcpy( &prg[0x08000], &prg[0x10000], 0x8000 );
851872
852873   /* Roms are banked at $8000 to $bfff */
853874   memory_install_write8_handler(machine, 1, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, iboard_rom_switch_w );
r2821r2822
908929
909930DRIVER_INIT( pchboard )
910931{
911   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x4c000], 0x4000 );
912   memcpy( &memory_region( REGION_CPU2 )[0x0c000], &memory_region( REGION_CPU2 )[0x4c000], 0x4000 );
932   UINT8 *prg = memory_region( REGION_CPU2 );
933   memcpy( &prg[0x08000], &prg[0x4c000], 0x4000 );
934   memcpy( &prg[0x0c000], &prg[0x4c000], 0x4000 );
913935
914936   /* Roms are banked at $8000 to $bfff */
915937   memory_install_write8_handler(machine, 1, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, hboard_rom_switch_w );
r2821r2822
933955
934956DRIVER_INIT( pckboard )
935957{
958   UINT8 *prg = memory_region( REGION_CPU2 );
959
936960   /* We do manual banking, in case the code falls through */
937961   /* Copy the initial banks */
938   memcpy( &memory_region( REGION_CPU2 )[0x08000], &memory_region( REGION_CPU2 )[0x48000], 0x8000 );
962   memcpy( &prg[0x08000], &prg[0x48000], 0x8000 );
939963
940964   mmc1_rom_mask = 0x0f;
941965
src/mame/machine/pgmcrypt.c
r2821r2822
11/* IGS PGM System Encryptions */
22
33#include "driver.h"
4#include "includes/pgm.h"
45
6
57static const UINT8 kov_tab[256] = {
68   0x17, 0x1c, 0xe3, 0x02, 0x62, 0x59, 0x97, 0x4a, 0x67, 0x4d, 0x1f, 0x11, 0x76, 0x64, 0xc1, 0xe1,
79   0xd2, 0x41, 0x9f, 0xfd, 0xfa, 0x04, 0xfe, 0xab, 0x89, 0xeb, 0xc0, 0xf5, 0xac, 0x2b, 0x64, 0x22,
src/mame/machine/asteroid.c
r2821r2822
1717INTERRUPT_GEN( asteroid_interrupt )
1818{
1919   /* Turn off interrupts if self-test is enabled */
20   if (!(input_port_read_indexed(machine, 0) & 0x80))
20   if (!(input_port_read(machine, "IN0") & 0x80))
2121      cpunum_set_input_line(machine, 0, INPUT_LINE_NMI, PULSE_LINE);
2222}
2323
2424INTERRUPT_GEN( asterock_interrupt )
2525{
2626   /* Turn off interrupts if self-test is enabled */
27   if ((input_port_read_indexed(machine, 0) & 0x80))
27   if ((input_port_read(machine, "IN0") & 0x80))
2828      cpunum_set_input_line(machine, 0, INPUT_LINE_NMI, PULSE_LINE);
2929}
3030
3131INTERRUPT_GEN( llander_interrupt )
3232{
3333   /* Turn off interrupts if self-test is enabled */
34   if (input_port_read_indexed(machine, 0) & 0x02)
34   if (input_port_read(machine, "IN0") & 0x02)
3535      cpunum_set_input_line(machine, 0, INPUT_LINE_NMI, PULSE_LINE);
3636}
3737
r2821r2822
4242   int res;
4343   int bitmask;
4444
45   res=input_port_read_indexed(machine, 0);
45   res=input_port_read(machine, "IN0");
4646
4747   bitmask = (1 << offset);
4848
r2821r2822
6464{
6565   int res;
6666
67   res=input_port_read_indexed(machine, 0);
67   res=input_port_read(machine, "IN0");
6868
6969//  if (activecpu_gettotalcycles() & 0x100)
7070//      res |= 0x02;
r2821r2822
7979   int res;
8080   int bitmask;
8181
82   res=input_port_read_indexed(machine, 0);
82   res=input_port_read(machine, "IN0");
8383
8484   bitmask = (1 << offset);
8585
r2821r2822
106106   int res;
107107   int bitmask;
108108
109   res=input_port_read_indexed(machine, 1);
109   res=input_port_read(machine, "IN1");
110110   bitmask = (1 << (offset & 0x7));
111111
112112   if (res & bitmask)
r2821r2822
122122   int res;
123123   int res1;
124124
125   res1 = input_port_read_indexed(machine, 2);
125   res1 = input_port_read(machine, "DSW");
126126
127127   res = 0xfc | ((res1 >> (2 * (3 - (offset & 0x3)))) & 0x3);
128128   return res;
r2821r2822
182182{
183183   int res;
184184
185   res = input_port_read_indexed(machine, 0);
185   res = input_port_read(machine, "IN0");
186186
187187   if (avgdvg_done())
188188      res |= 0x01;
src/mame/machine/scramble.c
r2821r2822
590590
591591DRIVER_INIT( anteater )
592592{
593   offs_t i;
593   offs_t i, len;
594594   UINT8 *RAM;
595595   UINT8 *scratch;
596596
r2821r2822
603603    */
604604
605605   RAM = memory_region(REGION_GFX1);
606   len = memory_region_length(REGION_GFX1);
606607
607   scratch = malloc_or_die(memory_region_length(REGION_GFX1));
608   scratch = malloc_or_die(len);
608609
609      memcpy(scratch, RAM, memory_region_length(REGION_GFX1));
610      memcpy(scratch, RAM, len);
610611
611      for (i = 0; i < memory_region_length(REGION_GFX1); i++)
612      for (i = 0; i < len; i++)
612613      {
613614         int j;
614615
r2821r2822
626627
627628DRIVER_INIT( rescue )
628629{
629   offs_t i;
630   offs_t i, len;
630631   UINT8 *RAM;
631632   UINT8 *scratch;
632633
r2821r2822
639640    */
640641
641642   RAM = memory_region(REGION_GFX1);
643   len = memory_region_length(REGION_GFX1);
642644
643   scratch = malloc_or_die(memory_region_length(REGION_GFX1));
645   scratch = malloc_or_die(len);
644646
645      memcpy(scratch, RAM, memory_region_length(REGION_GFX1));
647      memcpy(scratch, RAM, len);
646648
647      for (i = 0; i < memory_region_length(REGION_GFX1); i++)
649      for (i = 0; i < len; i++)
648650      {
649651         int j;
650652
r2821r2822
662664
663665DRIVER_INIT( minefld )
664666{
665   offs_t i;
667   offs_t i, len;
666668   UINT8 *RAM;
667669   UINT8 *scratch;
668670
r2821r2822
674676    */
675677
676678   RAM = memory_region(REGION_GFX1);
679   len = memory_region_length(REGION_GFX1);
677680
678   scratch = malloc_or_die(memory_region_length(REGION_GFX1));
681   scratch = malloc_or_die(len);
679682
680      memcpy(scratch, RAM, memory_region_length(REGION_GFX1));
683      memcpy(scratch, RAM, len);
681684
682      for (i = 0; i < memory_region_length(REGION_GFX1); i++)
685      for (i = 0; i < len; i++)
683686      {
684687         int j;
685688
r2821r2822
698701
699702DRIVER_INIT( losttomb )
700703{
701   offs_t i;
704   offs_t i, len;
702705   UINT8 *RAM;
703706   UINT8 *scratch;
704707
r2821r2822
711714    */
712715
713716   RAM = memory_region(REGION_GFX1);
717   len = memory_region_length(REGION_GFX1);
714718
715   scratch = malloc_or_die(memory_region_length(REGION_GFX1));
719   scratch = malloc_or_die(len);
716720
717      memcpy(scratch, RAM, memory_region_length(REGION_GFX1));
721      memcpy(scratch, RAM, len);
718722
719      for (i = 0; i < memory_region_length(REGION_GFX1); i++)
723      for (i = 0; i < len; i++)
720724      {
721725         int j;
722726
r2821r2822
866870DRIVER_INIT( ad2083 )
867871{
868872   UINT8 c;
869   int i;
870
873   int i, len = memory_region_length(REGION_CPU1);
871874   UINT8 *ROM = memory_region(REGION_CPU1);
872875
873   for (i=0; i<memory_region_length(REGION_CPU1); i++)
876   for (i=0; i<len; i++)
874877   {
875878      c = ROM[i] ^ 0x35;
876879      c = BITSWAP8(c, 6,2,5,1,7,3,4,0); /* also swapped inside of the bigger module */
src/mame/machine/konami1.c
r0r2822
1/***************************************************************************
2
3  The Konami_1 CPU is a 6809 with opcodes scrambled. Here is how to
4  descramble them.
5
6***************************************************************************/
7
8#include "driver.h"
9#include "konami1.h"
10
11
12static UINT8 konami1_decodebyte( UINT8 opcode, UINT16 address )
13{
14/*
15>
16> CPU_D7 = (EPROM_D7 & ~ADDRESS_1) | (~EPROM_D7 & ADDRESS_1)  >
17> CPU_D6 = EPROM_D6
18>
19> CPU_D5 = (EPROM_D5 & ADDRESS_1) | (~EPROM_D5 & ~ADDRESS_1) >
20> CPU_D4 = EPROM_D4
21>
22> CPU_D3 = (EPROM_D3 & ~ADDRESS_3) | (~EPROM_D3 & ADDRESS_3) >
23> CPU_D2 = EPROM_D2
24>
25> CPU_D1 = (EPROM_D1 & ADDRESS_3) | (~EPROM_D1 & ~ADDRESS_3) >
26> CPU_D0 = EPROM_D0
27>
28*/
29   UINT8 xormask;
30
31
32   xormask = 0;
33   if (address & 0x02) xormask |= 0x80;
34   else xormask |= 0x20;
35   if (address & 0x08) xormask |= 0x08;
36   else xormask |= 0x02;
37
38   return opcode ^ xormask;
39}
40
41
42
43UINT8 *konami1_decode(int cpu)
44{
45   const UINT8 *rom = memory_region(REGION_CPU1+cpu);
46   int size = memory_region_length(REGION_CPU1+cpu);
47   int A;
48
49   UINT8 *decrypted = auto_malloc(size);
50   memory_set_decrypted_region(cpu, 0x0000, 0xffff, decrypted);
51
52   for (A = 0;A < size;A++)
53   {
54      decrypted[A] = konami1_decodebyte(rom[A],A);
55   }
56   return decrypted;
57}
src/mame/machine/namcos1.c
r2821r2822
13301330      if (inp == 4) res = input_port_read(machine, "CONTROL0");
13311331      else
13321332      {
1333         char portname[4];
1333         char portname[40];
13341334
13351335#ifdef PRESSURE_SENSITIVE
13361336         static int counter[4];
src/mame/machine/pckeybrd.c
r2821r2822
321321void at_keyboard_init(AT_KEYBOARD_TYPE type)
322322{
323323   int i;
324   char buf[32];
325324
326325   memset(&keyboard, 0, sizeof(keyboard));
327326   keyboard.type = type;
r2821r2822
342341   /* locate the keyboard ports */
343342   for (i = 0; i < sizeof(keyboard.ports) / sizeof(keyboard.ports[0]); i++)
344343   {
344      char buf[40];
345345      sprintf(buf, "pc_keyboard_%d", i);
346346      keyboard.ports[i] = input_port_by_tag(Machine->portconfig, buf);
347347   }
src/mame/machine/konami1.h
src/mame/machine/deco156.c
r2821r2822
121121}
122122
123123
124void decrypt156(void)
124void deco156_decrypt(void)
125125{
126126   UINT32 *rom = (UINT32 *)memory_region(REGION_CPU1);
127127   int length = memory_region_length(REGION_CPU1);
src/mame/machine/pgmy2ks.c
r2821r2822
1818// The actual decryption algorithm is unknown.
1919
2020#include "driver.h"
21#include "includes/pgm.h"
2122
2223const UINT32 pgmy2ks[0x3c00] = {
2324   0x000000, 0x00007c, 0x0000f8, 0x000174, 0x0001f0, 0x00026c, 0x0002e8, 0x000364,
src/mame/machine/deco102.c
r2821r2822
99
1010#include "driver.h"
1111#include "cpu/m68000/m68000.h"
12#include "decocrpt.h"
1213
13extern void deco102_decrypt(int region, int address_xor, int data_select_xor, int opcode_select_xor);
14
1514static UINT16 decrypt(UINT16 data, int address, int select_xor)
1615{
1716   static const UINT16 xors[16] =
src/mame/machine/vsnes.c
r2821r2822
405405   switch( reg )
406406   {
407407      case 0: /* code bank 0 */
408         memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[bankoffset], 0x2000 );
409      break;
410
411408      case 2: /* code bank 1 */
412         memcpy( &memory_region( REGION_CPU1 )[0x0a000], &memory_region( REGION_CPU1 )[bankoffset], 0x2000 );
413      break;
414
415409      case 4: /* code bank 2 */
416         memcpy( &memory_region( REGION_CPU1 )[0x0c000], &memory_region( REGION_CPU1 )[bankoffset], 0x2000 );
410      {
411         UINT8 *prg = memory_region( REGION_CPU1 );
412         memcpy( &prg[0x08000 + reg*0x1000], &prg[bankoffset], 0x2000 );
413      }
417414      break;
418415
419416      case 6: /* vrom bank 0 */
r2821r2822
430427{
431428   /* We do manual banking, in case the code falls through */
432429   /* Copy the initial banks */
433   memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x18000], 0x8000 );
430   UINT8 *prg = memory_region( REGION_CPU1 );
431   memcpy( &prg[0x08000], &prg[0x18000], 0x8000 );
434432
435433   /* banking is done with writes to the $8000-$ffff area */
436434   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, goonies_rom_banking );
r2821r2822
446444{
447445   /* We do manual banking, in case the code falls through */
448446   /* Copy the initial banks */
449   memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x18000], 0x8000 );
447   UINT8 *prg = memory_region( REGION_CPU1 );
448   memcpy( &prg[0x08000], &prg[0x18000], 0x8000 );
450449
451450   /* banking is done with writes to the $8000-$ffff area */
452451   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, goonies_rom_banking );
r2821r2822
504503   int addr;
505504   if((data & 0x04) != old_bank)
506505   {
506      UINT8 *prg = memory_region( REGION_CPU1 );
507507      old_bank = data & 0x04;
508508      addr = old_bank ? 0x12000: 0x10000;
509      memcpy (&memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[addr], 0x2000);
509      memcpy (&prg[0x08000], &prg[addr], 0x2000);
510510   }
511511
512512   gun_in0_w(machine, offset, data);
r2821r2822
515515DRIVER_INIT( vsgshoe )
516516{
517517   /* set up the default bank */
518   memcpy (&memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x12000], 0x2000);
518   UINT8 *prg = memory_region( REGION_CPU1 );
519   memcpy (&prg[0x08000], &prg[0x12000], 0x2000);
519520
520521   /* Protection */
521522   memory_install_read8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x2002, 0x2002, 0, 0, vsgshoe_security_r );
r2821r2822
620621         case 3:   /* program banking */
621622            {
622623               int bank = ( drmario_shiftreg & 0x03 ) * 0x4000;
624               UINT8 *prg = memory_region( REGION_CPU1 );
623625
624626               if ( !size16k )
625627               {
626628                  /* switch 32k */
627                  memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x010000+bank], 0x8000 );
629                  memcpy( &prg[0x08000], &prg[0x010000+bank], 0x8000 );
628630               }
629631               else
630632               {
r2821r2822
632634                  if ( switchlow )
633635                  {
634636                     /* low */
635                     memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x010000+bank], 0x4000 );
637                     memcpy( &prg[0x08000], &prg[0x010000+bank], 0x4000 );
636638                  }
637639                  else
638640                  {
639641                     /* high */
640                     memcpy( &memory_region( REGION_CPU1 )[0x0c000], &memory_region( REGION_CPU1 )[0x010000+bank], 0x4000 );
642                     memcpy( &prg[0x0c000], &prg[0x010000+bank], 0x4000 );
641643                  }
642644               }
643645            }
r2821r2822
652654{
653655   /* We do manual banking, in case the code falls through */
654656   /* Copy the initial banks */
655   memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x10000], 0x4000 );
656   memcpy( &memory_region( REGION_CPU1 )[0x0c000], &memory_region( REGION_CPU1 )[0x1c000], 0x4000 );
657   UINT8 *prg = memory_region( REGION_CPU1 );
658   memcpy( &prg[0x08000], &prg[0x10000], 0x4000 );
659   memcpy( &prg[0x0c000], &prg[0x1c000], 0x4000 );
657660
658661   /* MMC1 mapper at writes to $8000-$ffff */
659662   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, drmario_rom_banking );
r2821r2822
741744static WRITE8_HANDLER( castlevania_rom_banking )
742745{
743746   int rombank = 0x10000 + ( data & 7 ) * 0x4000;
747   UINT8 *prg = memory_region( REGION_CPU1 );
744748
745   memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[rombank], 0x4000 );
749   memcpy( &prg[0x08000], &prg[rombank], 0x4000 );
746750}
747751
748752DRIVER_INIT( cstlevna )
749753{
750754   /* when starting the game, the 1st 16k and the last 16k are loaded into the 2 banks */
751   memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x28000], 0x8000 );
755   UINT8 *prg = memory_region( REGION_CPU1 );
756   memcpy( &prg[0x08000], &prg[0x28000], 0x8000 );
752757
753758      /* banking is done with writes to the $8000-$ffff area */
754759   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, castlevania_rom_banking );
r2821r2822
775780DRIVER_INIT( topgun )
776781{
777782   /* when starting the game, the 1st 16k and the last 16k are loaded into the 2 banks */
778   memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x28000], 0x8000 );
783   UINT8 *prg = memory_region( REGION_CPU1 );
784   memcpy( &prg[0x08000], &prg[0x28000], 0x8000 );
779785
780786      /* banking is done with writes to the $8000-$ffff area */
781787   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, castlevania_rom_banking );
r2821r2822
797803
798804static void mapper4_set_prg (void)
799805{
806   UINT8 *prg = memory_region( REGION_CPU1 );
800807   MMC3_prg0 &= MMC3_prg_mask;
801808   MMC3_prg1 &= MMC3_prg_mask;
802809
803810   if (MMC3_cmd & 0x40)
804811   {
805      memcpy( &memory_region( REGION_CPU1 )[0x8000], &memory_region( REGION_CPU1 )[(MMC3_prg_chunks-1) * 0x4000 + 0x10000], 0x2000 );
806      memcpy( &memory_region( REGION_CPU1 )[0xc000], &memory_region( REGION_CPU1 )[0x2000 * (MMC3_prg0) + 0x10000], 0x2000 );
812      memcpy( &prg[0x8000], &prg[(MMC3_prg_chunks-1) * 0x4000 + 0x10000], 0x2000 );
813      memcpy( &prg[0xc000], &prg[0x2000 * (MMC3_prg0) + 0x10000], 0x2000 );
807814   }
808815   else
809816   {
810      memcpy( &memory_region( REGION_CPU1 )[0x8000], &memory_region( REGION_CPU1 )[0x2000 * (MMC3_prg0) + 0x10000], 0x2000 );
811      memcpy( &memory_region( REGION_CPU1 )[0xc000], &memory_region( REGION_CPU1 )[(MMC3_prg_chunks-1) * 0x4000 + 0x10000], 0x2000 );
817      memcpy( &prg[0x8000], &prg[0x2000 * (MMC3_prg0) + 0x10000], 0x2000 );
818      memcpy( &prg[0xc000], &prg[(MMC3_prg_chunks-1) * 0x4000 + 0x10000], 0x2000 );
812819   }
813   memcpy( &memory_region( REGION_CPU1 )[0xa000], &memory_region( REGION_CPU1 )[0x2000 * (MMC3_prg1) + 0x10000], 0x2000 );
820   memcpy( &prg[0xa000], &prg[0x2000 * (MMC3_prg1) + 0x10000], 0x2000 );
814821}
815822
816823static void mapper4_set_chr (void)
r2821r2822
945952
946953DRIVER_INIT( MMC3 )
947954{
955   UINT8 *prg = memory_region( REGION_CPU1 );
948956   IRQ_enable = IRQ_count = IRQ_count_latch = 0;
949957   MMC3_prg0 = 0xfe;
950958   MMC3_prg1 = 0xff;
r2821r2822
954962
955963   MMC3_prg_mask = ((MMC3_prg_chunks << 1) - 1);
956964
957   memcpy( &memory_region( REGION_CPU1 )[0x8000], &memory_region( REGION_CPU1 )[(MMC3_prg_chunks-1) * 0x4000 + 0x10000], 0x2000 );
958   memcpy( &memory_region( REGION_CPU1 )[0xa000], &memory_region( REGION_CPU1 )[(MMC3_prg_chunks-1) * 0x4000 + 0x12000], 0x2000 );
959   memcpy( &memory_region( REGION_CPU1 )[0xc000], &memory_region( REGION_CPU1 )[(MMC3_prg_chunks-1) * 0x4000 + 0x10000], 0x2000 );
960   memcpy( &memory_region( REGION_CPU1 )[0xe000], &memory_region( REGION_CPU1 )[(MMC3_prg_chunks-1) * 0x4000 + 0x12000], 0x2000 );
965   memcpy( &prg[0x8000], &prg[(MMC3_prg_chunks-1) * 0x4000 + 0x10000], 0x2000 );
966   memcpy( &prg[0xa000], &prg[(MMC3_prg_chunks-1) * 0x4000 + 0x12000], 0x2000 );
967   memcpy( &prg[0xc000], &prg[(MMC3_prg_chunks-1) * 0x4000 + 0x10000], 0x2000 );
968   memcpy( &prg[0xe000], &prg[(MMC3_prg_chunks-1) * 0x4000 + 0x12000], 0x2000 );
961969
962970   /* MMC3 mapper at writes to $8000-$ffff */
963971   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, mapper4_w );
r2821r2822
11401148      break;
11411149
11421150      case 0x7000:
1143      memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x10000 +data*0x4000], 0x4000 );
1151      {
1152         UINT8 *prg = memory_region( REGION_CPU1 );
1153         memcpy( &prg[0x08000], &prg[0x10000 +data*0x4000], 0x4000 );
1154      }
11441155      break;
11451156
11461157   }
r2821r2822
11531164   /* when starting a mapper 68 game  the first 16K ROM bank in the cart is loaded into $8000
11541165    the LAST 16K ROM bank is loaded into $C000. The last 16K of ROM cannot be swapped. */
11551166
1156   memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_CPU1 )[0x10000], 0x4000 );
1157   memcpy( &memory_region( REGION_CPU1 )[0x0c000], &memory_region( REGION_CPU1 )[0x2c000], 0x4000 );
1167   UINT8 *prg = memory_region( REGION_CPU1 );
1168   memcpy( &prg[0x08000], &prg[0x10000], 0x4000 );
1169   memcpy( &prg[0x0c000], &prg[0x2c000], 0x4000 );
11581170
11591171   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xffff, 0, 0, mapper68_rom_banking );
11601172
r2821r2822
12681280
12691281DRIVER_INIT( vstennis )
12701282{
1283   UINT8 *prg = memory_region( REGION_CPU1 );
1284
12711285   /* vrom switching is enabled with bit 2 of $4016 */
12721286   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x4016, 0x4016, 0, 0, vstennis_vrom_banking );
12731287   memory_install_write8_handler(machine, 1, ADDRESS_SPACE_PROGRAM, 0x4016, 0x4016, 0, 0, vstennis_vrom_banking );
r2821r2822
12761290   memory_install_readwrite8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x6000, 0x7fff, 0, 0, SMH_BANK1, SMH_BANK1 );
12771291   memory_install_readwrite8_handler(machine, 1, ADDRESS_SPACE_PROGRAM, 0x6000, 0x7fff, 0, 0, SMH_BANK1, SMH_BANK1 );
12781292
1279   memory_set_bankptr(1, &memory_region(REGION_CPU1)[0x6000]);
1293   memory_set_bankptr(1, &prg[0x6000]);
12801294}
12811295
12821296/**********************************************************************/
src/mame/machine/midwunit.c
r2821r2822
370370static void init_wunit_generic(void)
371371{
372372   UINT8 *base;
373   int i, j;
373   int i, j, len;
374374
375375   /* register for state saving */
376376   register_state_saving();
377377
378378   /* load the graphics ROMs -- quadruples */
379379   midyunit_gfx_rom = base = memory_region(REGION_GFX1);
380   for (i = 0; i < memory_region_length(REGION_GFX1) / 0x400000; i++)
380   len = memory_region_length(REGION_GFX1);
381   for (i = 0; i < len / 0x400000; i++)
381382   {
382383      memcpy(midwunit_decode_memory, base, 0x400000);
383384      for (j = 0; j < 0x100000; j++)
r2821r2822
575576DRIVER_INIT( revx )
576577{
577578   UINT8 *base;
578   int i, j;
579   int i, j, len;
579580
580581   /* register for state saving */
581582   register_state_saving();
582583
583584   /* load the graphics ROMs -- quadruples */
584585   midyunit_gfx_rom = base = memory_region(REGION_GFX1);
585   for (i = 0; i < memory_region_length(REGION_GFX1) / 0x200000; i++)
586   len = memory_region_length(REGION_GFX1);
587   for (i = 0; i < len / 0x200000; i++)
586588   {
587589      memcpy(midwunit_decode_memory, base, 0x200000);
588590      for (j = 0; j < 0x80000; j++)
src/mame/machine/tecmosys.c
r0r2822
1/* tecmosys protection related functions */
2
3/*
4    The device validates a password,
5    then uploads the size of a code upload followed by the code upload itself.
6    After that, it uploads 4 ranges of code to checksum, followed by the 4 checksums.
7    The 68K does the checksumming, and returns the results to the protection device.
8
9    Apart from inital protection calls and code upload, the vblank in both games writes
10    info to the protection but they seem to ignore the returned data.
11    Maybe the protection is tied to something else, or maybe it was preliminary work on
12    further security.
13    This is what happens in the vblank:
14    - prot_w( 0xff )
15    - val = prot_r()
16    - prot_w( checksum1[val] )
17    (The area following checksum1 is the code upload in deroon, and active RAM in tkdensho,
18    so the value sent may be meaningless.)
19
20    There is provision for calling the protection read/write functions from two of the trap 0xf switch
21    statements in the 68K, but I don't see it being used anywhere.
22
23    It looks like the code upload is very plain, it can only be 0xff bytes long, and not contain the byte 0xff.
24    The checksum ranges can't contain 0xff either, although the checksum values can.
25    I'd be very interested in putting some trojan ROMs together if anyone has a board to run them on.
26    It might be possible to use one set of ROMs to get the checksum ranges,
27    and another set with dump code places outside those ranges.
28    You can get me at nuapete@hotmail.com
29*/
30
31#include "driver.h"
32#include "tecmosys.h"
33
34UINT8 device_read_ptr;
35UINT8 device_status;
36struct prot_data* device_data;
37static UINT8 device_value = 0xff;
38
39// deroon prot data
40static UINT8 deroon_passwd[] = {'L','U','N','A',0};
41static UINT8 deroon_upload[] = {0x02, 0x4e, 0x75, 0x00 }; // code length, code, 0x00 trailer
42struct prot_data deroon_data =
43{
44   5,
45   deroon_passwd,
46   deroon_upload,
47   {
48      0x10,0x11,0x12,0x13,   // range 1 using static ranges from the ROM to avoid calculating sums.
49      0x24,0x25,0x26,0x27,   // range 2
50      0x38,0x39,0x3a,0x3b,   // range 3
51      0x4c,0x4d,0x4e,0x4f,   // range 4
52      0x00,               // trailer
53   },
54   { 0xa6, 0x29, 0x4b, 0x3f }
55};
56
57// tkdensho prot data
58static UINT8 tkdensho_passwd[] = {'A','G','E','P','R','O','T','E','C','T',' ','S','T','A','R','T',0};
59static UINT8 tkdensho_upload[] = {0x06, 0x4e, 0xf9, 0x00, 0x00, 0x22, 0xc4,0x00};
60struct prot_data tkdensho_data =
61{
62   0x11,
63   tkdensho_passwd,
64   tkdensho_upload,
65   {
66      0x10,0x11,0x12,0x13,   // range 1
67      0x24,0x25,0x26,0x27,   // range 2
68      0x38,0x39,0x3a,0x3b,   // range 3
69      0x4c,0x4d,0x4e,0x4f,   // range 4
70      0x00,               // trailer
71   },
72   { 0xbf, 0xfa, 0xda, 0xda }
73};
74
75struct prot_data tkdensha_data =
76{
77   0x11,
78   tkdensho_passwd,
79   tkdensho_upload,
80   {
81      0x10,0x11,0x12,0x13,   // range 1
82      0x24,0x25,0x26,0x27,   // range 2
83      0x38,0x39,0x3a,0x3b,   // range 3
84      0x4c,0x4d,0x4e,0x4f,   // range 4
85      0x00,               // trailer
86   },
87   { 0xbf, 0xfa, 0x21, 0x5d }
88};
89
90
91READ16_HANDLER(prot_status_r)
92{
93   if (ACCESSING_BITS_8_15)
94   {
95      // Bit 7: 0 = ready to write
96      // Bit 6: 0 = ready to read
97      return 0;
98   }
99
100   return 0xc0; // simulation is always ready
101}
102
103WRITE16_HANDLER(prot_status_w)
104{
105   // deroon clears the status in one place.
106}
107
108
109READ16_HANDLER(prot_data_r)
110{
111   // prot appears to be read-ready for two consecutive reads
112   // but returns 0xff for subsequent reads.
113   UINT8 ret = device_value;
114   device_value = 0xff;
115   //logerror("- prot_r = 0x%02x\n", ret );
116   return ret << 8;
117}
118
119
120WRITE16_HANDLER(prot_data_w)
121{
122   // Only LSB
123   data >>= 8;
124
125   //logerror("+ prot_w( 0x%02x )\n", data );
126
127   switch( device_status )
128   {
129      case DS_IDLE:
130         if( data == 0x13 )
131         {
132            device_status = DS_LOGIN;
133            device_value = device_data->passwd_len;
134            device_read_ptr = 0;
135            break;
136         }
137         break;
138
139      case DS_LOGIN:
140         if( device_read_ptr >= device_data->passwd_len)
141         {
142            device_status = DS_SEND_CODE;
143            device_value = device_data->code[0];
144            device_read_ptr = 1;
145         }
146         else
147            device_value = device_data->passwd[device_read_ptr++] == data ? 0 : 0xff;
148         break;
149
150      case DS_SEND_CODE:
151         if( device_read_ptr >= device_data->code[0]+2 ) // + code_len + trailer
152         {
153            device_status = DS_SEND_ADRS;
154            device_value = device_data->checksum_ranges[0];
155            device_read_ptr = 1;
156         }
157         else
158            device_value = data == device_data->code[device_read_ptr-1] ? device_data->code[device_read_ptr++] : 0xff;
159         break;
160
161      case DS_SEND_ADRS:
162         if( device_read_ptr >= 16+1 ) //+ trailer
163         {
164            device_status = DS_SEND_CHKSUMS;
165            device_value = 0;
166            device_read_ptr = 0;
167         }
168         else
169         {
170            device_value = data == device_data->checksum_ranges[device_read_ptr-1] ? device_data->checksum_ranges[device_read_ptr++] : 0xff;
171         }
172         break;
173
174      case DS_SEND_CHKSUMS:
175         if( device_read_ptr >= 5 )
176         {
177            device_status = DS_DONE;
178            device_value = 0;
179         }
180         else
181            device_value = data == device_data->checksums[device_read_ptr] ? device_data->checksums[device_read_ptr++] : 0xff;
182         break;
183
184      case DS_DONE:
185         switch( data )
186         {
187            case 0xff: // trigger
188            case 0x00: // checksum1[val] tkdensho
189            case 0x20: // checksum1[val] deroon \ This is active RAM, so there may be more cases
190            case 0x01: // checksum1[val] deroon / that can be ignored
191               break;
192
193            default:
194               logerror( "Protection still in use??? w=%02x\n", data );
195               break;
196         }
197         break;
198   }
199}
src/mame/machine/arkanoid.c
r2821r2822
121121
122122READ8_HANDLER( arkanoid_68705_input_0_r )
123123{
124   int res = input_port_read_indexed(machine,0) & 0x3f;
124   int res = input_port_read(machine, "IN0") & 0x3f;
125125
126126   /* bit 0x40 comes from the sticky bit */
127127   if (!z80write) res |= 0x40;
r2821r2822
136136{
137137   if (arkanoid_paddle_select)
138138   {
139      arkanoid_paddle_value = input_port_read_indexed(machine,3);
139      arkanoid_paddle_value = input_port_read(machine, "IN3");
140140   }
141141   else
142142   {
143      arkanoid_paddle_value = input_port_read_indexed(machine,2);
143      arkanoid_paddle_value = input_port_read(machine, "IN2");
144144   }
145145
146146   return arkanoid_paddle_value;
src/mame/machine/galaxold.c
r2821r2822
381381
382382DRIVER_INIT( mooncrst )
383383{
384   offs_t i;
384   offs_t i, len = memory_region_length(REGION_CPU1);
385385   UINT8 *rom = memory_region(REGION_CPU1);
386386
387387
388   for (i = 0;i < memory_region_length(REGION_CPU1);i++)
388   for (i = 0;i < len;i++)
389389      rom[i] = decode_mooncrst(rom[i],i);
390390
391391   DRIVER_INIT_CALL(mooncrsu);
r2821r2822
457457      { 1,4,1,4 }
458458   };
459459
460   offs_t i;
460   offs_t i, len = memory_region_length(REGION_CPU1);
461461   UINT8 *rom = memory_region(REGION_CPU1);
462462
463463
464   for (i = 0; i < memory_region_length(REGION_CPU1); i++)
464   for (i = 0; i < len; i++)
465465   {
466466      UINT8 data_xor;
467467      int line = i & 0x07;
r2821r2822
483483
484484DRIVER_INIT( 4in1 )
485485{
486   offs_t i;
486   offs_t i, len = memory_region_length(REGION_CPU1);
487487   UINT8 *RAM = memory_region(REGION_CPU1);
488488
489489   /* Decrypt Program Roms */
490   for (i = 0; i < memory_region_length(REGION_CPU1); i++)
490   for (i = 0; i < len; i++)
491491      RAM[i] = RAM[i] ^ (i & 0xff);
492492
493493   /* games are banked at 0x0000 - 0x3fff */
src/mame/machine/pgmprot.c
r2821r2822
11#include "driver.h"
2#include "includes/pgm.h"
23
3extern UINT16 *pgm_mainram;
4
54/*** ASIC27a (Puzzle Star) -- ARM but with no external rom? behaves a bit like KOV ***/
65
76
r2821r2822
539538
540539      case 0x21: // PhotoY2k spritenum conversion 3/4
541540         if(!ASIC28RCNT) {
542            extern const UINT32 pgmy2ks[];
543541            photoy2k_trf[2] = val & 0xffff;
544542            logerror("ASIC28: PhotoY2K spr3 %04x %06x (%06x)\n", val & 0xffff, photoy2k_trf[1], activecpu_get_pc());
545543            if(photoy2k_trf[0] < 0x3c00)
src/mame/machine/atarifb.c
r2821r2822
152152           (sign_x_2 >> 6) |
153153           (sign_y_1 >> 5) |
154154           (sign_x_1 >> 4) |
155           input_port_read_indexed(machine,0);
155           input_port_read(machine, "IN0");
156156      return val;
157157   }
158158   else
r2821r2822
161161      int new_x,new_y;
162162
163163      /* Read player 1 trackball */
164      new_x = input_port_read_indexed(machine, 3);
164      new_x = input_port_read(machine, "IN3");
165165      if (new_x != counter_x)
166166      {
167167         sign_x_1 = (new_x - counter_x) & 0x80;
168168         counter_x = new_x;
169169      }
170170
171      new_y = input_port_read_indexed(machine, 2);
171      new_y = input_port_read(machine, "IN2");
172172      if (new_y != counter_y)
173173      {
174174         sign_y_1 = (new_y - counter_y) & 0x80;
r2821r2822
184184{
185185   if ((CTRLD & 0x20)==0x00)
186186   {
187      return input_port_read_indexed(machine,1);
187      return input_port_read(machine, "IN1");
188188   }
189189   else
190190   {
r2821r2822
192192      int new_x,new_y;
193193
194194      /* Read player 2 trackball */
195      new_x = input_port_read_indexed(machine, 5);
195      new_x = input_port_read(machine, "IN5");
196196      if (new_x != counter_x)
197197      {
198198         sign_x_2 = (new_x - counter_x) & 0x80;
199199         counter_x = new_x;
200200      }
201201
202      new_y = input_port_read_indexed(machine, 4);
202      new_y = input_port_read(machine, "IN4");
203203      if (new_y != counter_y)
204204      {
205205         sign_y_2 = (new_y - counter_y) & 0x80;
r2821r2822
234234      int new_x,new_y;
235235
236236      /* Read player 1 trackball */
237      new_x = input_port_read_indexed(machine, 4);
237      new_x = input_port_read(machine, "IN4");
238238      if (new_x != counter_x)
239239      {
240240         sign_x_1 = (new_x - counter_x) & 0x80;
241241         counter_x = new_x;
242242      }
243243
244      new_y = input_port_read_indexed(machine, 3);
244      new_y = input_port_read(machine, "IN3");
245245      if (new_y != counter_y)
246246      {
247247         sign_y_1 = (new_y - counter_y) & 0x80;
r2821r2822
257257      int new_x,new_y;
258258
259259      /* Read player 2 trackball */
260      new_x = input_port_read_indexed(machine, 6);
260      new_x = input_port_read(machine, "IN6");
261261      if (new_x != counter_x)
262262      {
263263         sign_x_2 = (new_x - counter_x) & 0x80;
264264         counter_x = new_x;
265265      }
266266
267      new_y = input_port_read_indexed(machine, 5);
267      new_y = input_port_read(machine, "IN5");
268268      if (new_y != counter_y)
269269      {
270270         sign_y_2 = (new_y - counter_y) & 0x80;
r2821r2822
282282{
283283   if ((CTRLD & 0x40)==0x00)
284284   {
285      return input_port_read_indexed(machine,2);
285      return input_port_read(machine, "IN2");
286286   }
287287   else if ((CTRLD & 0x60) == 0x60)
288288   /* LD1 and LD2 both high, return Team 2 right player (player 3) */
r2821r2822
291291      int new_x,new_y;
292292
293293      /* Read player 3 trackball */
294      new_x = input_port_read_indexed(machine, 8);
294      new_x = input_port_read(machine, "IN8");
295295      if (new_x != counter_x)
296296      {
297297         sign_x_3 = (new_x - counter_x) & 0x80;
298298         counter_x = new_x;
299299      }
300300
301      new_y = input_port_read_indexed(machine, 7);
301      new_y = input_port_read(machine, "IN7");
302302      if (new_y != counter_y)
303303      {
304304         sign_y_3 = (new_y - counter_y) & 0x80;
r2821r2822
314314      int new_x,new_y;
315315
316316      /* Read player 4 trackball */
317      new_x = input_port_read_indexed(machine, 10);
317      new_x = input_port_read(machine, "IN10");
318318      if (new_x != counter_x)
319319      {
320320         sign_x_4 = (new_x - counter_x) & 0x80;
321321         counter_x = new_x;
322322      }
323323
324      new_y = input_port_read_indexed(machine, 9);
324      new_y = input_port_read(machine, "IN9");
325325      if (new_y != counter_y)
326326      {
327327         sign_y_4 = (new_y - counter_y) & 0x80;
src/mame/machine/ajax.c
r2821r2822
108108
109109READ8_HANDLER( ajax_ls138_f10_r )
110110{
111   int data = 0;
111   int data = 0, index;
112   char port[5];
112113
113   switch ((offset & 0x01c0) >> 6){
114   switch ((offset & 0x01c0) >> 6)
115   {
114116      case 0x00:   /* ??? */
115117         data = mame_rand(machine);
116118         break;
117119      case 0x04:   /* 2P inputs */
118         data = input_port_read_indexed(machine, 5);
120         data = input_port_read(machine, "IN2");
119121         break;
120122      case 0x06:   /* 1P inputs + DIPSW #1 & #2 */
121         if (offset & 0x02)
122            data = input_port_read_indexed(machine, offset & 0x01);
123         else
124            data = input_port_read_indexed(machine, 3 + (offset & 0x01));
123         index = offset & 0x01;
124         sprintf(port, "%s%d", (offset & 0x02) ? "DSW" : "IN", (offset & 0x02) ? index+1 : index);
125         data = input_port_read(machine, port);
125126         break;
126127      case 0x07:   /* DIPSW #3 */
127         data = input_port_read_indexed(machine, 2);
128         data = input_port_read(machine, "DSW3");
128129         break;
129130
130131      default:
src/mame/mamedriv.c
r2821r2822
44374437   DRIVER( ginkun )   /* (c) 1995 Tecmo */
44384438   DRIVER( deroon )   /* (c) 1996 Tecmo */
44394439   DRIVER( tkdensho )   /* (c) 1996 Tecmo */
4440   DRIVER( tkdensha )   /* (c) 1996 Tecmo */
44404441
44414442   /* Konami bitmap games */
44424443   DRIVER( tutankhm )   /* GX350 (c) 1982 Konami */
r2821r2822
58215822   DRIVER( ddragonb )   /* bootleg */
58225823   DRIVER( ddragnba )   /* bootleg */
58235824   DRIVER( ddgn6809 )   /* bootleg */
5825   DRIVER( dd6809a )   /* bootleg */
58245826   DRIVER( spdodgeb )   /* TA-0022 (c) 1987 */
58255827   DRIVER( nkdodge )   /* TA-0022 (c) 1987 (Japan) */
58265828   DRIVER( nkdodgeb )   /* TA-0022 (c) 1987 (Japan) */
r2821r2822
62886290   DRIVER( rdft2a )   /* (c) 1997 Seibu Kaihatsu (Metrotainment license) */
62896291   DRIVER( rdft2a2 )   /* (c) 1997 Seibu Kaihatsu (Dream Island license) */
62906292   DRIVER( rdft2j )   /* (c) 1997 Seibu Kaihatsu */
6293   DRIVER( rdft2t )   /* (c) 1997 Seibu Kaihatsu */
62916294   DRIVER( rdft2us )   /* (c) 1997 Seibu Kaihatsu (Fabtek license) */
62926295   DRIVER( rdft22kc )   /* (c) 2000 Seibu Kaihatsu */
62936296
r2821r2822
63946397   DRIVER( rodlndjb )   /* bootleg */
63956398   DRIVER( avspirit )   /* (c) 1991 */
63966399   DRIVER( phantasm )   /* (c) 1991 (Japan) */
6400   DRIVER( monkelf )   /* bootleg */
63976401   DRIVER( edf )      /* (c) 1991 */
63986402   DRIVER( edfu )      /* (c) 1991 */
63996403   DRIVER( 64street )   /* (c) 1991 */
r2821r2822
71327136   DRIVER( sprtmtch )   /* "31" (c) 1989 Dynax + Fabtek license */
71337137   DRIVER( maya )      /* (c) 1994 Promat */
71347138   DRIVER( inca )      /* (c) 199? ???? */
7139   DRIVER( blktouch )   /* (c) Yang Gi Co Ltd. */
71357140   DRIVER( mcnpshnt )   /* "33" Mahjong Campus Hunting 1990 Dynax */
71367141   DRIVER( 7jigen )   /* "37" 7jigen no Youseitachi 1990 Dynax */
71377142   DRIVER( neruton )   /* "45" Neruton Haikujiradan 1990 Dynax */
r2821r2822
74797484   DRIVER( crysbios )
74807485   DRIVER( crysking )   /* 2001 Brezzasoft. Crystal of the kings */
74817486   DRIVER( evosocc )   /* 2001 Evoga. Evolution Soccer */
7487   DRIVER( topbladv )
7488   DRIVER( officeye )
74827489
74837490   /* Bell Fruit Cobra Hardware */
74847491   DRIVER( inquiztr )   /* 1989 BFM */
r2821r2822
79117918   DRIVER( gotya )      /* (c) 1981 Game-A-Tron */
79127919   DRIVER( sbugger )   /* (c) 1981 Game-A-Tron */
79137920   DRIVER( sbuggera )   /* (c) 1981 Game-A-Tron */
7914   DRIVER( gatcards )   /* (c) 1983 Game-A-Tron */
7915   DRIVER( gatslots )   /* (c) 1983 Game-A-Tron */
7921   DRIVER( poker41 )   /* (c) 1983 Game-A-Tron */
7922   DRIVER( pulltabs )   /* (c) 1983 Game-A-Tron */
79167923
79177924   DRIVER( vroulet )   /* (c) 1989 World Game */
79187925   DRIVER( rcasino )   /* (c) 1984 Dyna Electronics */
r2821r2822
80408047   DRIVER( good )      /* (c) 1983 Kiwako */
80418048   DRIVER( filetto )
80428049   DRIVER( quizo )      /* (c) 1985 Seoul Coin Corp. */
8050   DRIVER( quizoa )   /* (c) 1985 Seoul Coin Corp. */
80438051   DRIVER( gstream )   /* (c) 2002, Oriental Soft Japan */
80448052   DRIVER( miniboy7 )   /* (c) 1983, Bonanza Enterprises */
80458053   DRIVER( 39in1 )      /* MAME based bootleg */
r2821r2822
80778085   DRIVER( paranoia )
80788086   DRIVER( vcombat )   /* (c) 1993 VR8 Inc. */
80798087   DRIVER( shadfgtr )  /* (c) 1989 Sega? */
8088   DRIVER( blackt96 )
80808089
8090   /* H8/3048 italian gambling games */
8091   DRIVER( laperla )   /* (c) 2002 Nazionale Elettronica */
8092   DRIVER( laperlag )   /* (c) 2001 Nazionale Elettronica */
8093   DRIVER( capunc )   /* (c) 2000 Nazionale Elettronica */
8094   DRIVER( capcor )   /* (c) 2001 Nazionale Elettronica */
8095   DRIVER( euro2k2 )   /* (c) 2001 Nazionale Elettronica */
8096   DRIVER( euro2k2a )   /* (c) 2001 Nazionale Elettronica */
8097
8098   /* H8/3337 italian gambling games */
8099   DRIVER( laser2k1 )   /* 200? unknown */
8100   DRIVER( mdrink )   /* 200? unknown */
8101   DRIVER( ntcash )   /* 200? unknown */
8102   DRIVER( wizard )   /* 200? unknown */
8103   DRIVER( te0144 )   /* 200? unknown */
8104   DRIVER( cmagica )   /* 200? unknown */
8105   DRIVER( millsun )   /* 200? unknown */
8106   DRIVER( sspac2k1 )   /* 200? unknown */
8107   DRIVER( elvis )      /* 200? unknown */
8108
80818109   /* Astro Corp. */
80828110   DRIVER( showhand )
80838111
src/mame/includes/cps1.h
r2821r2822
3232
3333/*----------- defined in machine/kabuki.c -----------*/
3434
35void mgakuen2_decode(void);
36void pang_decode(void);
37void cworld_decode(void);
38void hatena_decode(void);
39void spang_decode(void);
40void spangj_decode(void);
41void sbbros_decode(void);
42void marukin_decode(void);
43void qtono1_decode(void);
44void qsangoku_decode(void);
45void block_decode(void);
46
3547void wof_decode(void);
3648void dino_decode(void);
3749void punisher_decode(void);
src/mame/includes/pgm.h
r0r2822
1/*----------- defined in drivers/pgm.c -----------*/
2
3extern UINT16 *pgm_mainram, *pgm_bg_videoram, *pgm_tx_videoram, *pgm_videoregs, *pgm_rowscrollram;
4
5extern UINT8 *pgm_sprite_a_region;
6extern size_t   pgm_sprite_a_region_allocate;
7
8
9/*----------- defined in machine/pgmcrypt.c -----------*/
10
11
12void pgm_kov_decrypt(void);
13void pgm_kovsh_decrypt(void);
14void pgm_kov2_decrypt(void);
15void pgm_mm_decrypt(void);
16void pgm_dw2_decrypt(void);
17void pgm_djlzz_decrypt(void);
18void pgm_dw3_decrypt(void);
19void pgm_killbld_decrypt(void);
20void pgm_pstar_decrypt(void);
21void pgm_puzzli2_decrypt(void);
22
23
24/*----------- defined in machine/pgmprot.c -----------*/
25
26READ16_HANDLER (PSTARS_protram_r);
27READ16_HANDLER (PSTARS_r16);
28
29READ16_HANDLER( pgm_asic3_r );
30WRITE16_HANDLER( pgm_asic3_w );
31WRITE16_HANDLER( pgm_asic3_reg_w );
32
33READ16_HANDLER (sango_protram_r);
34READ16_HANDLER (ASIC28_r16);
35WRITE16_HANDLER (ASIC28_w16);
36
37READ16_HANDLER (dw2_d80000_r );
38
39
40/*----------- defined in machine/pgmy2ks.c -----------*/
41
42extern const UINT32 pgmy2ks[0x3c00];
43
44
45/*----------- defined in video/pgm.c -----------*/
46
47
48WRITE16_HANDLER( pgm_tx_videoram_w );
49WRITE16_HANDLER( pgm_bg_videoram_w );
50VIDEO_START( pgm );
51VIDEO_EOF( pgm );
52VIDEO_UPDATE( pgm );
src/mame/includes/tecmosys.h
r0r2822
1/***************************************************************************
2
3    tecmosys protection simulation
4
5***************************************************************************/
6
7enum DEV_STATUS
8{
9   DS_IDLE,
10   DS_LOGIN,
11   DS_SEND_CODE,
12   DS_SEND_ADRS,
13   DS_SEND_CHKSUMS,
14   DS_DONE
15};
16
17struct prot_data
18{
19   UINT8 passwd_len;
20   UINT8* passwd;
21   UINT8* code;
22   UINT8 checksum_ranges[17];
23   UINT8 checksums[4];
24};
25
26/*----------- defined in machine/tecmosys.c -----------*/
27
28READ16_HANDLER(prot_status_r);
29WRITE16_HANDLER(prot_status_w);
30READ16_HANDLER(prot_data_r);
31WRITE16_HANDLER(prot_data_w);
32
33extern UINT8 device_read_ptr;
34extern UINT8 device_status;
35extern struct prot_data* device_data;
36extern struct prot_data deroon_data;
37extern struct prot_data tkdensho_data;
38extern struct prot_data tkdensha_data;
39
40
41
src/mame/includes/ms32.h
r0r2822
1/*----------- defined in drivers/ms32.c -----------*/
2
3extern void ms32_rearrange_sprites(int region);
4extern void decrypt_ms32_tx(int addr_xor,int data_xor, int region);
5extern void decrypt_ms32_bg(int addr_xor,int data_xor, int region);
6
7
8/*----------- defined in video/ms32.c -----------*/
9
10//extern UINT32 *ms32_fce00000;
11extern UINT32 *ms32_roz_ctrl;
12extern UINT32 *ms32_tx_scroll;
13extern UINT32 *ms32_bg_scroll;
14extern UINT32 *ms32_priram;
15extern UINT32 *ms32_palram;
16extern UINT32 *ms32_bgram;
17extern UINT32 *ms32_rozram;
18extern UINT32 *ms32_lineram;
19extern UINT32 *ms32_spram;
20extern UINT32 *ms32_txram;
21extern UINT32 *ms32_mainram;
22
23WRITE32_HANDLER( ms32_brightness_w );
24WRITE32_HANDLER( ms32_palram_w );
25READ32_HANDLER( ms32_txram_r );
26WRITE32_HANDLER( ms32_txram_w );
27READ32_HANDLER( ms32_rozram_r );
28WRITE32_HANDLER( ms32_rozram_w );
29READ32_HANDLER( ms32_lineram_r );
30WRITE32_HANDLER( ms32_lineram_w );
31READ32_HANDLER( ms32_bgram_r );
32WRITE32_HANDLER( ms32_bgram_w );
33READ32_HANDLER( ms32_spram_r );
34WRITE32_HANDLER( ms32_spram_w );
35READ32_HANDLER( ms32_priram_r );
36WRITE32_HANDLER( ms32_priram_w );
37WRITE32_HANDLER( ms32_gfxctrl_w );
38VIDEO_START( ms32 );
39VIDEO_UPDATE( ms32 );
src/mame/includes/decocrpt.h
r2821r2822
33void deco56_decrypt(int region);
44void deco74_decrypt(int region);
55void deco56_remap(int region);
6
7
8/*----------- defined in machine/deco102.c -----------*/
9
10void deco102_decrypt(int region, int address_xor, int data_select_xor, int opcode_select_xor);
11
12
13/*----------- defined in machine/deco156.c -----------*/
14
15void deco156_decrypt(void);
src/mame/mame.mak
r2821r2822
168168CPUS += V810
169169CPUS += M37702
170170CPUS += M37710
171CPUS += PPC403
171CPUS += PPC403GA
172CPUS += PPC403GCX
172173CPUS += PPC601
173174CPUS += PPC602
174175CPUS += PPC603
176CPUS += PPC603E
177CPUS += PPC603R
175178CPUS += MPC8240
176179CPUS += SE3208
177180CPUS += MC68HC11
r2821r2822
730733$(MAMEOBJ)/gametron.a: \
731734   $(DRIVERS)/gotya.o $(AUDIO)/gotya.o $(VIDEO)/gotya.o \
732735   $(DRIVERS)/sbugger.o $(VIDEO)/sbugger.o \
736   $(DRIVERS)/gatron.o \
733737
734738$(MAMEOBJ)/gottlieb.a: \
735739   $(DRIVERS)/exterm.o $(VIDEO)/exterm.o \
r2821r2822
895899   $(DRIVERS)/timeplt.o $(AUDIO)/timeplt.o $(VIDEO)/timeplt.o \
896900   $(DRIVERS)/tmnt.o $(VIDEO)/tmnt.o \
897901   $(DRIVERS)/tp84.o $(VIDEO)/tp84.o \
898   $(DRIVERS)/trackfld.o $(MACHINE)/konami.o $(AUDIO)/trackfld.o $(VIDEO)/trackfld.o \
902   $(DRIVERS)/trackfld.o $(MACHINE)/konami1.o $(AUDIO)/trackfld.o $(VIDEO)/trackfld.o \
899903   $(DRIVERS)/tutankhm.o $(VIDEO)/tutankhm.o \
900904   $(DRIVERS)/twin16.o $(VIDEO)/twin16.o \
901905   $(DRIVERS)/ultrsprt.o \
r2821r2822
14071411   $(DRIVERS)/tbowl.o $(VIDEO)/tbowl.o \
14081412   $(DRIVERS)/tecmo.o $(VIDEO)/tecmo.o \
14091413   $(DRIVERS)/tecmo16.o $(VIDEO)/tecmo16.o \
1410   $(DRIVERS)/tecmosys.o \
1414   $(DRIVERS)/tecmosys.o $(MACHINE)/tecmosys.o \
14111415   $(DRIVERS)/tehkanwc.o $(VIDEO)/tehkanwc.o \
14121416   $(DRIVERS)/wc90.o $(VIDEO)/wc90.o \
14131417   $(DRIVERS)/wc90b.o $(VIDEO)/wc90b.o \
r2821r2822
15101514   $(DRIVERS)/attckufo.o $(AUDIO)/attckufo.o $(VIDEO)/attckufo.o \
15111515   $(DRIVERS)/aztarac.o $(AUDIO)/aztarac.o $(VIDEO)/aztarac.o \
15121516   $(DRIVERS)/beaminv.o \
1517   $(DRIVERS)/blackt96.o \
15131518   $(DRIVERS)/bmcbowl.o \
15141519   $(DRIVERS)/calomega.o $(VIDEO)/calomega.o \
15151520   $(DRIVERS)/carrera.o \
r2821r2822
15431548   $(DRIVERS)/freekick.o $(VIDEO)/freekick.o \
15441549   $(DRIVERS)/funworld.o $(VIDEO)/funworld.o \
15451550   $(DRIVERS)/gamecstl.o \
1546   $(DRIVERS)/gatron.o \
15471551   $(DRIVERS)/gtipoker.o \
15481552   $(DRIVERS)/go2000.o \
15491553   $(DRIVERS)/good.o \
r2821r2822
15571561   $(DRIVERS)/imolagp.o \
15581562   $(DRIVERS)/intrscti.o \
15591563   $(DRIVERS)/istellar.o \
1564   $(DRIVERS)/itgambl2.o \
1565   $(DRIVERS)/itgamble.o \
15601566   $(DRIVERS)/jackpool.o \
15611567   $(DRIVERS)/jongkyo.o \
15621568   $(DRIVERS)/kingpin.o \
r2821r2822
17231729
17241730$(DRIVERS)/sbrkout.o:   $(LAYOUT)/sbrkout.lh
17251731
1732$(DRIVERS)/snookr10.o:   $(LAYOUT)/snookr10.lh
1733
17261734$(DRIVERS)/sspeedr.o:   $(LAYOUT)/sspeedr.lh
17271735
17281736$(DRIVERS)/stactics.o:   $(LAYOUT)/stactics.lh
src/mame/video/mitchell.c
r2821r2822
154154{
155155logerror("PC %04x: pang_gfxctrl_w %02x\n",activecpu_get_pc(),data);
156156{
157#if 0
157158   char baf[40];
158159   sprintf(baf,"%02x",data);
159//  popmessage(baf);
160   popmessage(baf);
161#endif
160162}
161163
162164   /* bit 0 is unknown (used, maybe back color enable?) */
src/mame/video/xevious.c
r2821r2822
329329READ8_HANDLER( xevious_bb_r )
330330{
331331   UINT8 *rom2a = memory_region(REGION_GFX4);
332   UINT8 *rom2b = memory_region(REGION_GFX4)+0x1000;
333   UINT8 *rom2c = memory_region(REGION_GFX4)+0x3000;
332   UINT8 *rom2b = rom2a+0x1000;
333   UINT8 *rom2c = rom2a+0x3000;
334334   int adr_2b,adr_2c;
335335   int dat1,dat2;
336336
src/mame/video/nbmj9195.c
r2821r2822
242242   int skipx, skipy;
243243   int ctrx, ctry;
244244   UINT16 color, color1, color2;
245   int gfxaddr;
245   int gfxaddr, gfxlen;
246246
247247   nb19010_busyctr = 0;
248248
r2821r2822
279279      skipy = -1;
280280   }
281281
282   gfxlen = memory_region_length(REGION_GFX1);
282283   gfxaddr = ((blitter_src_addr[vram] + 2) & 0x00ffffff);
283284
284285   for (y = starty, ctry = sizey; ctry >= 0; y += skipy, ctry--)
285286   {
286287      for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
287288      {
288         if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1)))
289         if ((gfxaddr > (gfxlen - 1)))
289290         {
290291#ifdef MAME_DEBUG
291292            popmessage("GFXROM ADDR OVER:%08X DX,%d,DY:%d,SX:%d,SY:%d", gfxaddr, startx, starty, sizex,sizey);
292293            logerror("GFXROM ADDR OVER:%08X DX,%d,DY:%d,SX:%d,SY:%d\n", gfxaddr, startx, starty, sizex,sizey);
293294#endif
294            gfxaddr &= (memory_region_length(REGION_GFX1) - 1);
295            gfxaddr &= (gfxlen - 1);
295296         }
296297
297298         color = GFX[gfxaddr++];
src/mame/video/niyanpai.c
r2821r2822
207207   int skipx, skipy;
208208   int ctrx, ctry;
209209   UINT16 color, color1, color2;
210   int gfxaddr;
210   int gfxaddr, gfxlen;
211211
212212   nb19010_busyctr = 0;
213213
r2821r2822
244244      skipy = -1;
245245   }
246246
247   gfxlen = memory_region_length(REGION_GFX1);
247248   gfxaddr = ((blitter_src_addr[vram] + 2) & 0x00ffffff);
248249
249250   for (y = starty, ctry = sizey; ctry >= 0; y += skipy, ctry--)
250251   {
251252      for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
252253      {
253         if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1)))
254         if ((gfxaddr > (gfxlen - 1)))
254255         {
255256#ifdef MAME_DEBUG
256257            popmessage("GFXROM ADDR OVER:%08X DX,%d,DY:%d,SX:%d,SY:%d", gfxaddr, startx, starty, sizex,sizey);
257258            logerror("GFXROM ADDR OVER:%08X DX,%d,DY:%d,SX:%d,SY:%d\n", gfxaddr, startx, starty, sizex,sizey);
258259#endif
259            gfxaddr &= (memory_region_length(REGION_GFX1) - 1);
260            gfxaddr &= (gfxlen - 1);
260261         }
261262
262263         color = GFX[gfxaddr++];
src/mame/video/suprnova.c
r2821r2822
1616
1717#include "driver.h"
1818
19static bitmap_t *sprite_bitmap;
20
21
1922#define SUPRNOVA_DECODE_BUFFER_SIZE 0x2000
2023
2124extern UINT32 *skns_tilemapA_ram, *skns_tilemapB_ram, *skns_v3slc_ram;
r2821r2822
3235static int sprite_kludge_x=0, sprite_kludge_y=0;
3336static int use_spc_bright, use_v3_bright;
3437static UINT8 bright_spc_b=0x00, bright_spc_g=0x00, bright_spc_r=0x00;
38
39static UINT8 bright_spc_b_trans=0x00, bright_spc_g_trans=0x00, bright_spc_r_trans=0x00;
40
41
3542static UINT8 bright_v3_b=0x00,  bright_v3_g=0x00,  bright_v3_r=0x00;
3643
3744
r2821r2822
5663         bright_spc_g = data&0xff;
5764         spc_changed = 1;
5865      }
66      bright_spc_g_trans = (data>>8) &0xff;
67
68
5969      break;
6070   case (0x08/4): // RWRA2
6171      if( bright_spc_r != (data&0xff) ) {
6272         bright_spc_r = data&0xff;
6373         spc_changed = 1;
6474      }
75      bright_spc_r_trans = (data>>8) &0xff;
76
6577      break;
6678   case (0x0C/4): // RWRA3
6779      if( bright_spc_b != (data&0xff) ) {
6880         bright_spc_b = data&0xff;
6981         spc_changed = 1;
7082      }
83      bright_spc_b_trans = (data>>8)&0xff;
84
85
7186      break;
7287
7388   case (0x10/4): // RWRB0
r2821r2822
436451   int disabled = skns_spc_regs[0x04/4] & 0x08; // RWR1
437452   int xsize,ysize, size, xpos=0,ypos=0, pri=0, romoffset, colour=0, xflip,yflip, joint;
438453   int sx,sy;
439   int endromoffs=0;
454   int endromoffs=0, gfxlen;
440455   UINT16 zoomx, zoomy;
441456
442457
r2821r2822
488503      sprite_y_scroll += sprite_kludge_y;
489504
490505
506      gfxlen = memory_region_length (REGION_GFX1);
491507      while( source<finish )
492508      {
493509         xflip = (source[0] & 0x00000200) >> 9;
r2821r2822
575591         zoomx = source[2] >> 16;
576592         zoomy = source[3] >> 16;
577593
578         romoffset &= memory_region_length (REGION_GFX1)-1;
594         romoffset &= gfxlen-1;
579595
580596         endromoffs = skns_rle_decode ( romoffset, size );
581597
r2821r2822
761777   skns_tilemap_B = tilemap_create(get_tilemap_B_tile_info,tilemap_scan_rows,16,16,64, 64);
762778      tilemap_set_transparent_pen(skns_tilemap_B,0);
763779
780   sprite_bitmap = auto_bitmap_alloc(1024,1024,BITMAP_FORMAT_INDEXED16);
781
782
764783   machine->gfx[2]->color_granularity=256;
765784   machine->gfx[3]->color_granularity=256;
766785}
r2821r2822
962981
963982   }
964983
984   fillbitmap(sprite_bitmap, 0x0000, cliprect);
985   skns_draw_sprites(screen->machine, sprite_bitmap, cliprect);
965986
966   skns_draw_sprites(screen->machine, bitmap, cliprect);
987   {
988      int x,y;
989      const pen_t *paldata = screen->machine->pens;
990
991      for (y=0;y<240;y++)
992      {
993         UINT16* src;
994         UINT32* dst;
995
996         src = BITMAP_ADDR16(sprite_bitmap,y,0);
997         dst = BITMAP_ADDR32(bitmap,y,0);
998
999         for (x=0;x<320;x++)
1000         {
1001            UINT16 pen = src[x]&0x7fff;
1002            UINT16 palvalue = skns_palette_ram[pen];
1003
1004            if (palvalue&0x8000)
1005            {
1006               UINT32 srccolour = dst[x];
1007               UINT32 dstcolour = paldata[pen];
1008
1009               int r,g,b;
1010               int r2,g2,b2;
1011
1012               r = (srccolour & 0x000000ff)>> 0;
1013               g = (srccolour & 0x0000ff00)>> 8;
1014               b = (srccolour & 0x00ff0000)>> 16;
1015
1016               r2 = (dstcolour & 0x000000ff)>> 0;
1017               g2 = (dstcolour & 0x0000ff00)>> 8;
1018               b2 = (dstcolour & 0x00ff0000)>> 16;
1019
1020               r2 = (r2 * bright_spc_r_trans) >> 8;
1021               g2 = (g2 * bright_spc_g_trans) >> 8;
1022               b2 = (b2 * bright_spc_b_trans) >> 8;
1023
1024               r = (r+r2);
1025               if (r>255) r = 255;
1026
1027               g = (g+g2);
1028               if (g>255) g = 255;
1029
1030               b = (b+b2);
1031               if (b>255) b = 255;
1032
1033               if (pen) dst[x] = (r << 0) | (g << 8) | (b << 16);
1034
1035            }
1036            else
1037            {
1038               if (pen) dst[x] = paldata[pen];
1039            }
1040
1041         }
1042      }
1043
1044   }
1045
9671046   return 0;
9681047}
9691048
src/mame/video/ms32.c
r2821r2822
1414
1515#include "driver.h"
1616#include "deprecat.h"
17#include "includes/ms32.h"
1718
19
1820//UINT32 *ms32_fce00000;
1921UINT32 *ms32_roz_ctrl;
2022UINT32 *ms32_tx_scroll;
src/mame/video/galaxian.c
r2821r2822
308308{
309309   static const int rgb_resistances[3] = { 1000, 470, 220 };
310310   double rweights[3], gweights[3], bweights[2];
311   int i, minval, midval, maxval;
311   int i, minval, midval, maxval, len;
312312   UINT8 starmap[4];
313313
314314   /*
r2821r2822
343343         2, &rgb_resistances[1], bweights, 470, 0);
344344
345345   /* decode the palette first */
346   for (i = 0; i < memory_region_length(REGION_PROMS); i++)
346   len = memory_region_length(REGION_PROMS);
347   for (i = 0; i < len; i++)
347348   {
348349      UINT8 bit0, bit1, bit2, r, g, b;
349350
src/mame/video/tmnt.c
r2821r2822
424424   if (glfgreat_roz_rom_mode)
425425      return memory_region(REGION_GFX3)[glfgreat_roz_char_bank * 0x80000 + offset];
426426   else if (offset < 0x40000)
427      return memory_region(REGION_USER1)[offset + 0x80000 + glfgreat_roz_rom_bank * 0x40000] +
428            256 * memory_region(REGION_USER1)[offset + glfgreat_roz_rom_bank * 0x40000];
427   {
428      UINT8 *usr = memory_region(REGION_USER1);
429      return usr[offset + 0x80000 + glfgreat_roz_rom_bank * 0x40000] +
430            256 * usr[offset + glfgreat_roz_rom_bank * 0x40000];
431   }
429432   else
430433      return memory_region(REGION_USER1)[((offset & 0x3ffff) >> 2) + 0x100000 + glfgreat_roz_rom_bank * 0x10000];
431434}
r2821r2822
525528   if(glfgreat_roz_char_bank)
526529      return memory_region(REGION_GFX3)[offset];
527530   else
528      return 256 * memory_region(REGION_USER1)[offset] + memory_region(REGION_USER1)[offset + 0x020000];
531   {
532      UINT8 *usr = memory_region(REGION_USER1);
533      return 256 * usr[offset] + usr[offset + 0x020000];
534   }
529535}
530536
531537WRITE16_HANDLER( tmnt_priority_w )
src/mame/video/taitojc.c
r2821r2822
282282   taitojc_tile_update(screen->machine);
283283   tilemap_draw(bitmap, cliprect, taitojc_tilemap, 0,0);
284284
285   /*
285#if 0
286286    if (debug_tex_pal > 0)
287287    {
288288        int j;
r2821r2822
309309            popmessage("%s", string);
310310        }
311311    }
312    */
312#endif
313313
314314   return 0;
315315}
src/mame/video/segaic16.c
r2821r2822
19911991   const UINT16 *spritebase;
19921992     UINT16 *data;
19931993
1994   if (!memory_region(REGION_GFX2))
1994   spritebase = (const UINT16 *)memory_region(REGION_GFX2);
1995   if (!spritebase)
19951996      return;
19961997
1997   spritebase = (const UINT16 *)memory_region(REGION_GFX2);
19981998   numbanks = memory_region_length(REGION_GFX2) / 0x20000;
19991999
20002000   /* first scan forward to find the end of the list */
r2821r2822
28952895static void segaic16_road_hangon_decode(struct road_info *info)
28962896{
28972897   int x, y;
2898   const UINT8 *gfx = memory_region(REGION_GFX3);
2899   int len = memory_region_length(REGION_GFX3);
28982900
28992901   /* allocate memory for the unpacked road data */
29002902   info->gfx = auto_malloc(256 * 512);
r2821r2822
29022904   /* loop over rows */
29032905   for (y = 0; y < 256; y++)
29042906   {
2905      UINT8 *src = memory_region(REGION_GFX3) + ((y & 0xff) * 0x40) % memory_region_length(REGION_GFX3);
2907      const UINT8 *src = gfx + ((y & 0xff) * 0x40) % len;
29062908      UINT8 *dst = info->gfx + y * 512;
29072909
29082910      /* loop over columns */
r2821r2822
31543156static void segaic16_road_outrun_decode(struct road_info *info)
31553157{
31563158   int x, y;
3159   const UINT8 *gfx = memory_region(REGION_GFX3);
3160   int len = memory_region_length(REGION_GFX3);
31573161
31583162   /* allocate memory for the unpacked road data */
31593163   info->gfx = auto_malloc((256 * 2 + 1) * 512);
r2821r2822
31613165   /* loop over rows */
31623166   for (y = 0; y < 256 * 2; y++)
31633167   {
3164      UINT8 *src = memory_region(REGION_GFX3) + ((y & 0xff) * 0x40 + (y >> 8) * 0x8000) % memory_region_length(REGION_GFX3);
3168      const UINT8 *src = gfx + ((y & 0xff) * 0x40 + (y >> 8) * 0x8000) % len;
31653169      UINT8 *dst = info->gfx + y * 512;
31663170
31673171      /* loop over columns */
src/mame/video/pgm.c
r2821r2822
22/* see drivers/pgm.c for notes on where improvements can be made */
33
44#include "driver.h"
5#include "includes/pgm.h"
56
6extern UINT16 *pgm_mainram, *pgm_bg_videoram, *pgm_tx_videoram, *pgm_videoregs, *pgm_rowscrollram;
77static tilemap *pgm_tx_tilemap, *pgm_bg_tilemap;
88static UINT16 *pgm_spritebufferram; // buffered spriteram
99static UINT16 *sprite_temp_render;
1010
11extern UINT8 *pgm_sprite_a_region;   /* = memory_region       ( REGION_GFX4 ); */
12extern size_t   pgm_sprite_a_region_allocate;
13
1411/* Sprites - These are a pain! */
1512
1613/* this decodes one of the funky sprites to a bitmap so we can draw it more easily -- slow but easier to use*/
src/mame/video/model3.c
r2821r2822
7575
7676/*****************************************************************************/
7777
78extern int model3_irq_state;
78/* in drivers/model3.c */
79void model3_set_irq_line(running_machine *machine, UINT8 bit, int state);
7980
8081extern int model3_step;
8182
r2821r2822
476477   {
477478      case 0x00/8:   logerror("vid_reg0: %08X%08X\n", (UINT32)(data>>32),(UINT32)(data)); vid_reg0 = data; break;
478479      case 0x08/8:   break;      /* ??? */
479      case 0x10/8:   model3_irq_state &= ~(data >> 56); break;      /* VBL IRQ Ack */
480      case 0x10/8:   model3_set_irq_line(machine, (data >> 56) & 0x0f, CLEAR_LINE); break;      /* VBL IRQ Ack */
480481
481482      case 0x20/8:   model3_layer_enable = (data >> 52);   break;
482483
src/mame/video/st0016.c
r2821r2822
190190      UINT32 srcadr=(st0016_vregs[0xa0]|(st0016_vregs[0xa1]<<8)|(st0016_vregs[0xa2]<<16))<<1;
191191      UINT32 dstadr=(st0016_vregs[0xa3]|(st0016_vregs[0xa4]<<8)|(st0016_vregs[0xa5]<<16))<<1;
192192      UINT32 length=((st0016_vregs[0xa6]|(st0016_vregs[0xa7]<<8)|((st0016_vregs[0xa8]&0x1f)<<16))+1)<<1;
193      UINT32 srclen = (memory_region_length(REGION_CPU1)-0x10000);
193194      while(length>0)
194195      {
195         if( srcadr < (memory_region_length(REGION_CPU1)-0x10000) && (dstadr < ST0016_MAX_CHAR_BANK*ST0016_CHAR_BANK_SIZE))
196         if( srcadr < srclen && (dstadr < ST0016_MAX_CHAR_BANK*ST0016_CHAR_BANK_SIZE))
196197         {
197198            st0016_char_bank=dstadr>>5;
198199            st0016_character_ram_w(machine,dstadr&0x1f,memory_region(REGION_CPU1)[0x10000+srcadr]);
src/mame/video/epos.c
r2821r2822
2929static void get_pens(pen_t *pens)
3030{
3131   offs_t i;
32   const UINT8 *prom = memory_region(REGION_PROMS);
33   int len = memory_region_length(REGION_PROMS);
3234
33   for (i = 0; i < memory_region_length(REGION_PROMS); i++)
35   for (i = 0; i < len; i++)
3436   {
3537      int bit0, bit1, bit2, r, g, b;
3638
37      UINT8 data = memory_region(REGION_PROMS)[i];
39      UINT8 data = prom[i];
3840
3941      bit0 = (data >> 7) & 0x01;
4042      bit1 = (data >> 6) & 0x01;
src/mame/video/pastelg.c
r2821r2822
9898
9999WRITE8_HANDLER( pastelg_romsel_w )
100100{
101   int gfxlen = memory_region_length(REGION_GFX1);
101102   pastelg_gfxrom = ((data & 0xc0) >> 6);
102103   pastelg_palbank = ((data & 0x10) >> 4);
103104   nb1413m3_sndrombank1_w(machine, 0, data);
104105
105   if ((pastelg_gfxrom << 16) > (memory_region_length(REGION_GFX1) - 1))
106   if ((pastelg_gfxrom << 16) > (gfxlen - 1))
106107   {
107108#ifdef MAME_DEBUG
108109      popmessage("GFXROM BANK OVER!!");
109110#endif
110      pastelg_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1);
111      pastelg_gfxrom &= (gfxlen / 0x20000 - 1);
111112   }
112113}
113114
r2821r2822
156157   int skipx, skipy;
157158   int ctrx, ctry;
158159   int readflag;
159   int gfxaddr;
160   int gfxaddr, gfxlen;
160161   UINT8 color;
161162
162163   nb1413m3_busyctr = 0;
r2821r2822
186187      skipy = -1;
187188   }
188189
190   gfxlen = memory_region_length(REGION_GFX1);
189191   gfxaddr = (pastelg_gfxrom << 16) + blitter_src_addr;
190192
191193   readflag = 0;
r2821r2822
194196   {
195197      for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
196198      {
197         if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1)))
199         if ((gfxaddr > (gfxlen - 1)))
198200         {
199201#ifdef MAME_DEBUG
200202            popmessage("GFXROM ADDRESS OVER!!");
src/mame/video/galaxold.c
r2821r2822
166166***************************************************************************/
167167PALETTE_INIT( galaxold )
168168{
169   int i;
169   int i, len;
170170
171171
172172   /* first, the character/sprite palette */
173
174   for (i = 0;i < memory_region_length(REGION_PROMS);i++)
173   len = memory_region_length(REGION_PROMS);
174   for (i = 0;i < len;i++)
175175   {
176176      int bit0,bit1,bit2,r,g,b;
177177
r2821r2822
247247
248248PALETTE_INIT( rockclim )
249249{
250   int i;
250   int i, len;
251251
252252
253253   /* first, the character/sprite palette */
254
255   for (i = 0;i < memory_region_length(REGION_PROMS);i++)
254   len = memory_region_length(REGION_PROMS);
255   for (i = 0;i < len;i++)
256256   {
257257      int bit0,bit1,bit2,r,g,b;
258258
src/mame/video/ssv.c
r2821r2822
893893
894894            #ifdef MAME_DEBUG
895895            if (input_code_pressed(KEYCODE_Z))   /* Display some info on each sprite */
896            {   char buf[10];
896            {   char buf[30];
897897               sprintf(buf, "%02X",/*(s2[2] & ~0x3ff)>>8*/mode>>8);
898898               ui_draw_text(buf, sx, sy);
899899            }
src/mame/video/nbmj8891.c
r2821r2822
273273
274274WRITE8_HANDLER( nbmj8891_romsel_w )
275275{
276   int gfxlen = memory_region_length(REGION_GFX1);
276277   nbmj8891_gfxrom = (data & 0x0f);
277278
278   if ((0x20000 * nbmj8891_gfxrom) > (memory_region_length(REGION_GFX1) - 1))
279   if ((0x20000 * nbmj8891_gfxrom) > (gfxlen - 1))
279280   {
280281#ifdef MAME_DEBUG
281282      popmessage("GFXROM BANK OVER!!");
282283#endif
283      nbmj8891_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1);
284      nbmj8891_gfxrom &= (gfxlen / 0x20000 - 1);
284285   }
285286}
286287
r2821r2822
347348   int skipx, skipy;
348349   int ctrx, ctry;
349350   UINT8 color, color1, color2;
350   int gfxaddr;
351   int gfxaddr, gfxlen;
351352
352353   nb1413m3_busyctr = 0;
353354
r2821r2822
376377      skipy = -1;
377378   }
378379
380   gfxlen = memory_region_length(REGION_GFX1);
379381   gfxaddr = (nbmj8891_gfxrom << 17) + (blitter_src_addr << 1);
380382
381383   for (y = starty, ctry = sizey; ctry >= 0; y += skipy, ctry--)
382384   {
383385      for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
384386      {
385         if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1)))
387         if ((gfxaddr > (gfxlen - 1)))
386388         {
387389#ifdef MAME_DEBUG
388390            popmessage("GFXROM ADDRESS OVER!!");
389391#endif
390            gfxaddr &= (memory_region_length(REGION_GFX1) - 1);
392            gfxaddr &= (gfxlen - 1);
391393         }
392394
393395         color = GFX[gfxaddr++];
src/mame/video/nbmj8688.c
r2821r2822
184184
185185WRITE8_HANDLER( mjsikaku_romsel_w )
186186{
187   int gfxlen = memory_region_length(REGION_GFX1);
187188   mjsikaku_gfxrom = (data & 0x0f);
188189
189   if ((mjsikaku_gfxrom << 17) > (memory_region_length(REGION_GFX1) - 1))
190   if ((mjsikaku_gfxrom << 17) > (gfxlen - 1))
190191   {
191192#ifdef MAME_DEBUG
192193      popmessage("GFXROM BANK OVER!!");
193194#endif
194      mjsikaku_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1);
195      mjsikaku_gfxrom &= (gfxlen / 0x20000 - 1);
195196   }
196197}
197198
198199WRITE8_HANDLER( secolove_romsel_w )
199200{
201   int gfxlen = memory_region_length(REGION_GFX1);
200202   mjsikaku_gfxrom = ((data & 0xc0) >> 4) + (data & 0x03);
201203   mjsikaku_gfxflag2_w(machine, 0, data);
202204
203   if ((mjsikaku_gfxrom << 17) > (memory_region_length(REGION_GFX1) - 1))
205   if ((mjsikaku_gfxrom << 17) > (gfxlen - 1))
204206   {
205207#ifdef MAME_DEBUG
206208      popmessage("GFXROM BANK OVER!!");
207209#endif
208      mjsikaku_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1);
210      mjsikaku_gfxrom &= (gfxlen / 0x20000 - 1);
209211   }
210212}
211213
212214WRITE8_HANDLER( crystalg_romsel_w )
213215{
216   int gfxlen = memory_region_length(REGION_GFX1);
214217   mjsikaku_gfxrom = (data & 0x03);
215218   mjsikaku_gfxflag2_w(machine, 0, data);
216219
217   if ((mjsikaku_gfxrom << 17) > (memory_region_length(REGION_GFX1) - 1))
220   if ((mjsikaku_gfxrom << 17) > (gfxlen - 1))
218221   {
219222#ifdef MAME_DEBUG
220223      popmessage("GFXROM BANK OVER!!");
221224#endif
222      mjsikaku_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1);
225      mjsikaku_gfxrom &= (gfxlen / 0x20000 - 1);
223226   }
224227}
225228
226229WRITE8_HANDLER( seiha_romsel_w )
227230{
231   int gfxlen = memory_region_length(REGION_GFX1);
228232   mjsikaku_gfxrom = (data & 0x1f);
229233   mjsikaku_gfxflag3_w(machine, 0, data);
230234
231   if ((mjsikaku_gfxrom << 17) > (memory_region_length(REGION_GFX1) - 1))
235   if ((mjsikaku_gfxrom << 17) > (gfxlen - 1))
232236   {
233237#ifdef MAME_DEBUG
234238      popmessage("GFXROM BANK OVER!!");
235239#endif
236      mjsikaku_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1);
240      mjsikaku_gfxrom &= (gfxlen / 0x20000 - 1);
237241   }
238242}
239243
r2821r2822
300304   int sizex, sizey;
301305   int skipx, skipy;
302306   int ctrx, ctry;
303   int gfxaddr;
307   int gfxaddr, gfxlen;
304308   UINT16 color, color1, color2;
305309
306310   if (gfxtype == GFXTYPE_PURE_12BIT)
r2821r2822
335339      skipy = -1;
336340   }
337341
342   gfxlen = memory_region_length(REGION_GFX1);
338343   gfxaddr = (mjsikaku_gfxrom << 17) + (blitter_src_addr << 1);
339344//popmessage("ADDR:%08X DX:%03d DY:%03d SX:%03d SY:%03d", gfxaddr, startx, starty, sizex, sizey);
340345//if (blitter_direction_x|blitter_direction_y) popmessage("ADDR:%08X FX:%01d FY:%01d", gfxaddr, blitter_direction_x, blitter_direction_y);
r2821r2822
343348   {
344349      for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
345350      {
346         if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1)))
351         if ((gfxaddr > (gfxlen - 1)))
347352         {
348353#ifdef MAME_DEBUG
349354            popmessage("GFXROM ADDRESS OVER!!");
src/mame/video/8080bw.c
r2821r2822
130130{
131131   pen_t pens[NUM_PENS];
132132   offs_t offs;
133   UINT8 *prom;
133134   UINT8 *color_map_base;
134135
135136   invadpt2_get_pens(pens);
136137
137   color_map_base = color_map ? &memory_region(REGION_PROMS)[0x0400] : memory_region(REGION_PROMS);
138   prom = memory_region(REGION_PROMS);
139   color_map_base = color_map ? &prom[0x0400] : &prom[0x0000];
138140
139141   for (offs = 0; offs < mw8080bw_ram_size; offs++)
140142   {
r2821r2822
160162   pen_t pens[NUM_PENS];
161163   offs_t offs;
162164   UINT8 *color_map_base;
165   UINT8 *prom;
163166
164167   invadpt2_get_pens(pens);
165168
166   color_map_base = color_map ? &memory_region(REGION_PROMS)[0x0400] : memory_region(REGION_PROMS);
169   prom = memory_region(REGION_PROMS);
170   color_map_base = color_map ? &prom[0x0400] : &prom[0x0000];
167171
168172   for (offs = 0; offs < mw8080bw_ram_size; offs++)
169173   {
r2821r2822
400404   pen_t pens[NUM_PENS];
401405   offs_t offs;
402406   UINT8 *color_map_base;
407   UINT8 *prom;
403408
404409   cosmo_get_pens(pens);
405410
406   color_map_base = color_map ? &memory_region(REGION_PROMS)[0x0400] : memory_region(REGION_PROMS);
411   prom = memory_region(REGION_PROMS);
412   color_map_base = color_map ? &prom[0x0400] : &prom[0x0000];
407413
408414   for (offs = 0; offs < mw8080bw_ram_size; offs++)
409415   {
src/mame/video/ginganin.c
r2821r2822
8484
8585static TILE_GET_INFO( get_bg_tile_info )
8686{
87   int code = memory_region(REGION_GFX5)[2*tile_index + 0] * 256 + memory_region(REGION_GFX5)[2*tile_index + 1];
87   UINT8 *gfx = memory_region(REGION_GFX5);
88   int code = gfx[2*tile_index + 0] * 256 + gfx[2*tile_index + 1];
8889   SET_TILE_INFO(
8990         BG_GFX,
9091         code,
src/mame/video/nbmj8991.c
r2821r2822
9494******************************************************************************/
9595WRITE8_HANDLER( nbmj8991_blitter_w )
9696{
97   int gfxlen = memory_region_length(REGION_GFX1);
98
9799   switch (offset)
98100   {
99101      case 0x00:   blitter_src_addr = (blitter_src_addr & 0xff00) | data; break;
r2821r2822
125127      case 0x70:   nbmj8991_clutsel = data; break;
126128   }
127129
128   if ((0x20000 * nbmj8991_gfxrom) > (memory_region_length(REGION_GFX1) - 1))
130   if ((0x20000 * nbmj8991_gfxrom) > (gfxlen - 1))
129131   {
130132#ifdef MAME_DEBUG
131133      popmessage("GFXROM BANK OVER!!");
132134#endif
133      nbmj8991_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1);
135      nbmj8991_gfxrom &= (gfxlen / 0x20000 - 1);
134136   }
135137}
136138
r2821r2822
202204   int skipx, skipy;
203205   int ctrx, ctry;
204206   UINT8 color, color1, color2;
205   int gfxaddr;
207   int gfxaddr, gfxlen;
206208
207209   nb1413m3_busyctr = 0;
208210
r2821r2822
232234      skipy = -1;
233235   }
234236
237   gfxlen = memory_region_length(REGION_GFX1);
235238   gfxaddr = (nbmj8991_gfxrom << 17) + (blitter_src_addr << 1);
236239
237240   for (y = starty, ctry = sizey; ctry >= 0; y += skipy, ctry--)
238241   {
239242      for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
240243      {
241         if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1)))
244         if ((gfxaddr > (gfxlen - 1)))
242245         {
243246#ifdef MAME_DEBUG
244247            popmessage("GFXROM ADDRESS OVER!!");
245248#endif
246            gfxaddr &= (memory_region_length(REGION_GFX1) - 1);
249            gfxaddr &= (gfxlen - 1);
247250         }
248251
249252         color = GFX[gfxaddr++];
src/mame/video/konamiic.c
r2821r2822
53675367
53685368// locally cached values
53695369static int K056832_LayerAssociatedWithPage[K056832_PAGE_COUNT];
5370static int K056832_LayerOffset[4][2];
5371static int K056832_LSRAMPage[4][2];
5372static INT32 K056832_X[4];   // 0..3 left
5373static INT32 K056832_Y[4];   // 0..3 top
5374static INT32 K056832_W[4];   // 0..3 width  -> 1..4 pages
5375static INT32 K056832_H[4];   // 0..3 height -> 1..4 pages
5376static INT32 K056832_dx[4];   // scroll
5377static INT32 K056832_dy[4];   // scroll
5370static int K056832_LayerOffset[8][2];
5371static int K056832_LSRAMPage[8][2];
5372static INT32 K056832_X[8];   // 0..3 left
5373static INT32 K056832_Y[8];   // 0..3 top
5374static INT32 K056832_W[8];   // 0..3 width  -> 1..4 pages
5375static INT32 K056832_H[8];   // 0..3 height -> 1..4 pages
5376static INT32 K056832_dx[8];   // scroll
5377static INT32 K056832_dy[8];   // scroll
53785378static UINT32 K056832_LineDirty[K056832_PAGE_COUNT][8];
53795379static UINT8 K056832_AllLinesDirty[K056832_PAGE_COUNT];
53805380static UINT8 K056832_PageTileMode[K056832_PAGE_COUNT];
5381static UINT8 K056832_LayerTileMode[4];
5381static UINT8 K056832_LayerTileMode[8];
53825382static int K056832_DefaultLayerAssociation;
53835383static int K056832_LayerAssociation;
53845384static int K056832_ActiveLayer;
src/mame/video/aeroboto.c
r2821r2822
7575
7676READ8_HANDLER( aeroboto_in0_r )
7777{
78   return input_port_read_indexed(machine, flip_screen_get() ? 1 : 0);
78   char port[4];
79
80   sprintf(port, "IN%d", flip_screen_get() ? 1 : 0);
81   return input_port_read(machine, port);
7982}
8083
8184WRITE8_HANDLER( aeroboto_3000_w )
src/mame/video/mystwarr.c
r2821r2822
2121static void mystwarr_save_orig_tiles(void)
2222{
2323   UINT8 *s = memory_region(REGION_GFX1);
24   UINT8 *pFinish = s+memory_region_length(REGION_GFX1)-3;
24   int len = memory_region_length(REGION_GFX1);
25   UINT8 *pFinish = s+len-3;
2526
26   orig_roms = malloc_or_die(memory_region_length(REGION_GFX1));
27   memcpy(orig_roms, s, memory_region_length(REGION_GFX1));
27   orig_roms = malloc_or_die(len);
28   memcpy(orig_roms, s, len);
2829
2930   // now convert the data into a drawable format so we can decode it
3031   while (s < pFinish)
r2821r2822
5455static void mystwarr_rest_orig_tiles(void)
5556{
5657   UINT8 *s = memory_region(REGION_GFX1);
58   int len = memory_region_length(REGION_GFX1);
5759
5860   // restore the original data so the ROM test can pass
59   memcpy(s, orig_roms, memory_region_length(REGION_GFX1));
61   memcpy(s, orig_roms, len);
6062   free(orig_roms);
6163}
6264
src/mame/video/neogeo.c
r2821r2822
693693   /* convert the sprite graphics data into a format that
694694       allows faster blitting */
695695   int i;
696   int len;
696697   UINT8 *src;
697698   UINT8 *dest;
698699   UINT32 bit;
r2821r2822
713714   memset(sprite_gfx, 0, sprite_gfx_address_mask + 1);
714715
715716   src = memory_region(NEOGEO_REGION_SPRITES);
717   len = memory_region_length(NEOGEO_REGION_SPRITES);
716718   dest = sprite_gfx;
717719
718   for (i = 0; i < memory_region_length(NEOGEO_REGION_SPRITES); i += 0x80, src += 0x80)
720   for (i = 0; i < len; i += 0x80, src += 0x80)
719721   {
720722      int y;
721723
src/mame/video/snookr10.c
r2821r2822
1313    * Ten Balls (Ver 1.05),  unknown, 1997.
1414
1515
16***********************************************************************************
17
18
19    Resistor Network for all PCBs:
20
21
22     74LS373
23    +-------+
24    |     02|--> 1  KOhms resistor --> \
25    |     05|--> 470 Ohms resistor -->  > 100 Ohms pull-down resistor --> RED
26    |     06|--> 220 Ohms resistor --> /
27    |       |
28    |     09|--> 1  KOhms resistor --> \
29    |     12|--> 470 Ohms resistor -->  > 100 Ohms pull-down resistor --> BLUE
30    |     15|--> 220 Ohms resistor --> /
31    |       |
32    |     16|--> 470 Ohms resistor --> \  100 Ohms pull-down resistor --> GREEN
33    |     19|--> 220 Ohms resistor --> /
34    +-------+
35
36
1637**********************************************************************************/
1738
1839
1940#include "driver.h"
41#include "video/resnet.h"
2042
2143static tilemap *bg_tilemap;
2244
r2821r2822
3355   tilemap_mark_tile_dirty(bg_tilemap, offset);
3456}
3557
58
3659PALETTE_INIT( snookr10 )
3760{
61   /* GGBBBRRR */
62
3863   int i;
64   static const int resistances_rb[3] = { 1000, 470, 220 };
65   static const int resistances_g [2] = { 470, 220 };
66   double weights_r[3], weights_b[3], weights_g[2];
3967
40   /* GGBBBRRR */
41   if (color_prom == 0) return;
68   compute_resistor_weights(0,   255,   -1.0,
69         3,   resistances_rb,   weights_r,   100,   0,
70         3,   resistances_rb,   weights_b,   100,   0,
71         2,   resistances_g,   weights_g,   100,   0);
4272
43   for (i = 0;i < machine->config->total_colors;i++)
73
74   for (i = 0; i < machine->config->total_colors; i++)
4475   {
45      int bit0,bit1,bit2,r,g,b;
76      int bit0, bit1, bit2, r, g, b;
4677
4778      /* red component */
4879      bit0 = (color_prom[i] >> 0) & 0x01;
4980      bit1 = (color_prom[i] >> 1) & 0x01;
5081      bit2 = (color_prom[i] >> 2) & 0x01;
51      r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
82      r = combine_3_weights(weights_r, bit0, bit1, bit2);
5283      /* blue component */
5384      bit0 = (color_prom[i] >> 3) & 0x01;
5485      bit1 = (color_prom[i] >> 4) & 0x01;
5586      bit2 = (color_prom[i] >> 5) & 0x01;
56      b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
87      b = combine_3_weights(weights_b, bit0, bit1, bit2);
5788      /* green component */
58      bit0 = 0;
59      bit1 = (color_prom[i] >> 6) & 0x01;
60      bit2 = (color_prom[i] >> 7) & 0x01;
61      g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
89      bit0 = (color_prom[i] >> 6) & 0x01;
90      bit1 = (color_prom[i] >> 7) & 0x01;
91      g = combine_2_weights(weights_g, bit0, bit1);
6292
6393      palette_set_color(machine, i, MAKE_RGB(r,g,b));
6494   }
r2821r2822
79109   SET_TILE_INFO(0, code, color, 0);
80110}
81111
82/*********************************************************
83* Apple10 color and tile matrix are encrypted/scrambled. *
84*     For more information, see the driver notes.        *
85*********************************************************/
86112
113/**********************************************************
114* Apple10 colors and tile matrix are encrypted/scrambled. *
115*     For more information, see the driver notes.         *
116**********************************************************/
117
87118PALETTE_INIT( apple10 )
88119{
89   int i;
90
91120   /* GGBBBRRR */
92   if (color_prom == 0) return;
93121
94   for (i = 0;i < machine->config->total_colors;i++)
122   int i, cn;
123   static const int resistances_rb[3] = { 1000, 470, 220 };
124   static const int resistances_g [2] = { 470, 220 };
125   double weights_r[3], weights_b[3], weights_g[2];
126
127   compute_resistor_weights(0,   255,   -1.0,
128         3,   resistances_rb,   weights_r,   100,   0,
129         3,   resistances_rb,   weights_b,   100,   0,
130         2,   resistances_g,   weights_g,   100,   0);
131
132
133   for (i = 0; i < machine->config->total_colors; i++)
95134   {
96      int bit0,bit1,bit2,r,g,b,cn;
135      int bit0, bit1, bit2, r, g, b;
97136
98137      /* red component */
99138      bit0 = (color_prom[i] >> 0) & 0x01;
100139      bit1 = (color_prom[i] >> 1) & 0x01;
101140      bit2 = (color_prom[i] >> 2) & 0x01;
102      r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
141      r = combine_3_weights(weights_r, bit0, bit1, bit2);
103142      /* blue component */
104143      bit0 = (color_prom[i] >> 3) & 0x01;
105144      bit1 = (color_prom[i] >> 4) & 0x01;
106145      bit2 = (color_prom[i] >> 5) & 0x01;
107      b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
146      b = combine_3_weights(weights_b, bit0, bit1, bit2);
108147      /* green component */
109      bit0 = 0;
110      bit1 = (color_prom[i] >> 6) & 0x01;
111      bit2 = (color_prom[i] >> 7) & 0x01;
112      g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
148      bit0 = (color_prom[i] >> 6) & 0x01;
149      bit1 = (color_prom[i] >> 7) & 0x01;
150      g = combine_2_weights(weights_g, bit0, bit1);
113151
114152      /* encrypted color matrix */
115153      cn = BITSWAP8(i,4,5,6,7,2,3,0,1);
r2821r2822
133171   SET_TILE_INFO(0, code, color, 0);
134172}
135173
174
136175VIDEO_START( snookr10 )
137176{
138177   bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_rows, 4, 8, 128, 32);
src/mame/video/tubep.c
r2821r2822
436436   UINT32   XDOT;
437437   UINT32   YDOT;
438438   UINT8 * romCxx  = memory_region(REGION_USER2)+0x00000;
439   UINT8 * romD10  = memory_region(REGION_USER2)+0x10000;
440   UINT8 * romEF13 = memory_region(REGION_USER2)+0x12000;
441   UINT8 * romHI2  = memory_region(REGION_USER2)+0x14000;
439   UINT8 * romD10  = romCxx+0x10000;
440   UINT8 * romEF13 = romCxx+0x12000;
441   UINT8 * romHI2  = romCxx+0x14000;
442442
443443
444444   for (YDOT=0; (YDOT^YSize) != 0x00; YDOT++)
r2821r2822
739739   UINT32 v;
740740   UINT8 *text_gfx_base = memory_region(REGION_GFX1);
741741   UINT8 *rom13D  = memory_region(REGION_USER1);
742   UINT8 *rom11BD = memory_region(REGION_USER1)+0x1000;
743   UINT8 *rom19C  = memory_region(REGION_USER1)+0x5000;
742   UINT8 *rom11BD = rom13D+0x1000;
743   UINT8 *rom19C  = rom13D+0x5000;
744744
745745   /* this can be optimized further by extracting constants out of the loop */
746746   /* especially read from ROM19C can be done once per 8 pixels*/
src/mame/video/hyhoo.c
r2821r2822
5252
5353WRITE8_HANDLER( hyhoo_romsel_w )
5454{
55   int gfxlen = memory_region_length(REGION_GFX1);
5556   hyhoo_gfxrom = (((data & 0xc0) >> 4) + (data & 0x03));
5657   hyhoo_highcolorflag = data;
5758   nb1413m3_gfxrombank_w(machine, 0, data);
5859
59   if ((0x20000 * hyhoo_gfxrom) > (memory_region_length(REGION_GFX1) - 1))
60   if ((0x20000 * hyhoo_gfxrom) > (gfxlen - 1))
6061   {
6162#ifdef MAME_DEBUG
6263      popmessage("GFXROM BANK OVER!!");
6364#endif
64      hyhoo_gfxrom &= (memory_region_length(REGION_GFX1) / 0x20000 - 1);
65      hyhoo_gfxrom &= (gfxlen / 0x20000 - 1);
6566   }
6667}
6768
r2821r2822
8182   int sizex, sizey;
8283   int skipx, skipy;
8384   int ctrx, ctry;
84   int gfxaddr;
85   int gfxaddr, gfxlen;
8586   UINT8 color, color1, color2;
8687   int r, g, b;
8788   pen_t pen;
r2821r2822
115116      skipy = -1;
116117   }
117118
119   gfxlen = memory_region_length(REGION_GFX1);
118120   gfxaddr = (hyhoo_gfxrom << 17) + (blitter_src_addr << 1);
119121
120122   for (y = starty, ctry = sizey; ctry >= 0; y += skipy, ctry--)
121123   {
122124      for (x = startx, ctrx = sizex; ctrx >= 0; x += skipx, ctrx--)
123125      {
124         if ((gfxaddr > (memory_region_length(REGION_GFX1) - 1)))
126         if ((gfxaddr > (gfxlen - 1)))
125127         {
126128#ifdef MAME_DEBUG
127129            popmessage("GFXROM ADDRESS OVER!!");
src/mame/video/fuukifg2.c
r2821r2822
225225#if 0
226226if (input_code_pressed(KEYCODE_X))
227227{   /* Display some info on each sprite */
228   char buf[10];
228   char buf[40];
229229   sprintf(buf, "%Xx%X %X",xnum,ynum,(attr>>6)&3);
230230   ui_draw_text(buf, sx, sy);
231231}
src/mame/video/fuukifg3.c
r2821r2822
257257#if 0
258258if (input_code_pressed(KEYCODE_X))
259259{   /* Display some info on each sprite */
260   char buf[10];
260   char buf[40];
261261   sprintf(buf, "%Xx%X %X",xnum,ynum,(attr>>6)&3);
262262   ui_draw_text(buf, sx, sy);
263263}
src/mame/video/nmk16.c
r2821r2822
1010#include "driver.h"
1111
1212UINT16 *nmk_bgvideoram,*nmk_fgvideoram,*nmk_txvideoram;
13UINT16 *gunnail_scrollram;
14static UINT16 gunnail_scrolly;
13UINT16 *gunnail_scrollram, *gunnail_scrollramy;
1514
1615static int redraw_bitmap;
1716
r2821r2822
403402   }
404403}
405404
406WRITE16_HANDLER( gunnail_scrollx_w )
407{
408   COMBINE_DATA(&gunnail_scrollram[offset]);
409}
410
411WRITE16_HANDLER( gunnail_scrolly_w )
412{
413   COMBINE_DATA(&gunnail_scrolly);
414}
415
416405/***************************************************************************
417406
418407  Display refresh
r2821r2822
746735
747736VIDEO_UPDATE( gunnail )
748737{
749   int i;
738   int y1, i;
739   rectangle bgclip = *cliprect;
750740
751   for (i = 0;i < 256;i++)
741   // the hardware supports per-scanline X *and* Y scroll which isn't
742   // supported by tilemaps so we have to draw the tilemap one line at a time
743   y1 = cliprect->min_y;
744   while (y1 <= cliprect->max_y)
752745   {
753      tilemap_set_scrollx(bg_tilemap,(i+gunnail_scrolly) & 0x1ff,gunnail_scrollram[0] + gunnail_scrollram[i] - videoshift);
746      int const yscroll = gunnail_scrollramy[0] + gunnail_scrollramy[y1];
747      int y2;
748
749      // group all consecutive lines with the same y scroll to reduce overhead
750      y2 = y1+1;
751      while (y2 <= cliprect->max_y && gunnail_scrollramy[y2] == gunnail_scrollramy[y1])
752         y2++;
753
754      bgclip.min_y = y1;
755      bgclip.max_y = y2-1;
756
757      tilemap_set_scrolly(bg_tilemap, 0, yscroll);
758      for (i = y1; i < y2; i++)
759         tilemap_set_scrollx(bg_tilemap,(i + yscroll) & 0x1ff, gunnail_scrollram[0] + gunnail_scrollram[i] - videoshift);
760
761      tilemap_draw(bitmap,&bgclip,bg_tilemap,0,0);
762
763      y1 = y2;
754764   }
755   tilemap_set_scrolly(bg_tilemap,0,gunnail_scrolly);
756765
757   VIDEO_UPDATE_CALL(macross);
766   nmk16_draw_sprites(screen->machine, bitmap,cliprect,3);
767   nmk16_draw_sprites(screen->machine, bitmap,cliprect,2);
768   nmk16_draw_sprites(screen->machine, bitmap,cliprect,1);
769   nmk16_draw_sprites(screen->machine, bitmap,cliprect,0);
770
771   tilemap_set_scrollx(tx_tilemap,0,-videoshift);
772   tilemap_draw(bitmap,cliprect,tx_tilemap,0,0);
758773   return 0;
759774}
760775
src/mame/layout/snookr10.lay
r0r2822
1<?xml version="1.0"?>
2<mamelayout version="2">
3   <element name="L0" defstate="1">
4      <rect>
5         <color red="1.0" green="1.0" blue="1.0" />
6      </rect>
7      <text string="START" state="1">
8         <color red="0.0" green="0.0" blue="0.0" />
9         <bounds x="0" y="0.1" width="1" height="0.8" />
10      </text>
11   </element>
12
13   <element name="L1" defstate="1">
14      <rect>
15         <color red="1.0" green="1.0" blue="1.0" />
16      </rect>
17      <text string="CANCEL" state="1">
18         <color red="0.0" green="0.0" blue="0.0" />
19         <bounds x="0" y="0.1" width="1" height="0.8" />
20      </text>
21   </element>
22
23   <element name="L2" defstate="1">
24      <rect>
25         <color red="1.0" green="0.0" blue="0.0" />
26      </rect>
27      <text string="STOP1" state="1">
28         <color red="0.0" green="0.0" blue="0.0" />
29         <bounds x="0" y="0.1" width="1" height="0.8" />
30      </text>
31   </element>
32
33   <element name="L3" defstate="1">
34      <rect>
35         <color red="1.0" green="0.0" blue="0.0" />
36      </rect>
37      <text string="STOP2" state="1">
38         <color red="0.0" green="0.0" blue="0.0" />
39         <bounds x="0" y="0.1" width="1" height="0.8" />
40      </text>
41   </element>
42
43   <element name="L4" defstate="1">
44      <rect>
45         <color red="1.0" green="0.0" blue="0.0" />
46      </rect>
47      <text string="STOP3" state="1">
48         <color red="0.0" green="0.0" blue="0.0" />
49         <bounds x="0" y="0.1" width="1" height="0.8" />
50      </text>
51   </element>
52
53   <element name="L5" defstate="1">
54      <rect>
55         <color red="1.0" green="0.0" blue="0.0" />
56      </rect>
57      <text string="STOP4" state="1">
58         <color red="0.0" green="0.0" blue="0.0" />
59         <bounds x="0" y="0.1" width="1" height="0.8" />
60      </text>
61   </element>
62
63   <element name="L6" defstate="1">
64      <rect>
65         <color red="1.0" green="0.0" blue="0.0" />
66      </rect>
67      <text string="STOP5" state="1">
68         <color red="0.0" green="0.0" blue="0.0" />
69         <bounds x="0" y="0.1" width="1" height="0.8" />
70      </text>
71   </element>
72
73   <view name="Button Lamps">
74      <screen index="0">
75         <bounds left="0" top="0" right="4" bottom="3" />
76      </screen>
77      <bezel name="lamp0" element="L0">
78         <bounds x="0" y="3.13" width="0.40" height="0.24" />
79      </bezel>
80      <bezel name="lamp1" element="L1">
81         <bounds x="0.5" y="3.13" width="0.40" height="0.24" />
82      </bezel>
83      <bezel name="lamp2" element="L2">
84         <bounds x="1.5" y="3.13" width="0.40" height="0.24" />
85      </bezel>
86      <bezel name="lamp3" element="L3">
87         <bounds x="2.0" y="3.13" width="0.40" height="0.24" />
88      </bezel>
89      <bezel name="lamp4" element="L4">
90         <bounds x="2.5" y="3.13" width="0.40" height="0.24" />
91      </bezel>
92      <bezel name="lamp5" element="L5">
93         <bounds x="3.0" y="3.13" width="0.40" height="0.24" />
94      </bezel>
95      <bezel name="lamp6" element="L6">
96         <bounds x="3.5" y="3.13" width="0.40" height="0.24" />
97      </bezel>
98   </view>
99</mamelayout>
src/mame/drivers/bfcobra.c
r2821r2822
15001500   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
15011501   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
15021502   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1503   PORT_BIT( 0xF8, IP_ACTIVE_HIGH, IPT_UNKNOWN )
15041503
15051504   PORT_START_TAG("STROBE4")
15061505   PORT_BIT( 0xFF, IP_ACTIVE_HIGH, IPT_UNKNOWN )
src/mame/drivers/nycaptor.c
r2821r2822
13161316static DRIVER_INIT(bronx)
13171317{
13181318   int i;
1319   UINT8 *rom = memory_region(REGION_CPU1);
13191320   for(i=0;i<0x20000;i++)
1320      memory_region(REGION_CPU1)[i]=BITSWAP8(memory_region(REGION_CPU1)[i],0,1,2,3,4,5,6,7);
1321      rom[i]=BITSWAP8(rom[i],0,1,2,3,4,5,6,7);
13211322   nyc_gametype=1;
13221323}
13231324
13241325static DRIVER_INIT(colt)
13251326{
13261327   int i;
1328   UINT8 *rom = memory_region(REGION_CPU1);
13271329   for(i=0;i<0x20000;i++)
1328      memory_region(REGION_CPU1)[i]=BITSWAP8(memory_region(REGION_CPU1)[i],0,1,2,3,4,5,6,7);
1330      rom[i]=BITSWAP8(rom[i],0,1,2,3,4,5,6,7);
13291331   nyc_gametype=2;
13301332}
13311333
src/mame/drivers/mitchell.c
r2821r2822
8080#include "driver.h"
8181#include "deprecat.h"
8282#include "machine/eeprom.h"
83#include "includes/cps1.h"
8384#include "sound/okim6295.h"
8485#include "sound/3812intf.h"
8586#include "sound/2413intf.h"
8687#include "sound/msm5205.h"
8788
88/* in machine/kabuki.c */
89void mgakuen2_decode(void);
90void pang_decode(void);
91void cworld_decode(void);
92void hatena_decode(void);
93void spang_decode(void);
94void spangj_decode(void);
95void sbbros_decode(void);
96void marukin_decode(void);
97void qtono1_decode(void);
98void qsangoku_decode(void);
99void block_decode(void);
10089
101
10290VIDEO_START( pang );
10391VIDEO_UPDATE( pang );
10492
r2821r2822
826814   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
827815   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
828816   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
829   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Deal") PORT_CODE(KEYCODE_LCONTROL)
830   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 E") PORT_CODE(KEYCODE_E)
831   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 A") PORT_CODE(KEYCODE_A)
817   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Deal") PORT_CODE(KEYCODE_LCONTROL)
818   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 E") PORT_CODE(KEYCODE_E)
819   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 A") PORT_CODE(KEYCODE_A)
832820
833821   PORT_START      /* IN1 */
834822   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
r2821r2822
836824   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
837825   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
838826   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
839   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Cancel") PORT_CODE(KEYCODE_LALT)
827   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Cancel") PORT_CODE(KEYCODE_LALT)
840828   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
841   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 B") PORT_CODE(KEYCODE_B)
829   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 B") PORT_CODE(KEYCODE_B)
842830
843831   PORT_START      /* IN1 */
844832   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
r2821r2822
846834   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
847835   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
848836   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
849   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Flip") PORT_CODE(KEYCODE_SPACE)
837   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Flip") PORT_CODE(KEYCODE_SPACE)
850838   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
851   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 C") PORT_CODE(KEYCODE_C)
839   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 C") PORT_CODE(KEYCODE_C)
852840
853841   PORT_START      /* IN1 */
854842   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
855843   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
856844   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
857845   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
858   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
859846   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
860847   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
861848   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
862   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 D") PORT_CODE(KEYCODE_D)
849   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 D") PORT_CODE(KEYCODE_D)
863850
864851   PORT_START      /* IN1 */
865852   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
r2821r2822
877864   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
878865   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
879866   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
880   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 Deal") PORT_CODE(KEYCODE_LCONTROL)
881   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 E") PORT_CODE(KEYCODE_E)
882   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 A") PORT_CODE(KEYCODE_A)
867   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 Deal") PORT_CODE(KEYCODE_LCONTROL)
868   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 E") PORT_CODE(KEYCODE_E)
869   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 A") PORT_CODE(KEYCODE_A)
883870
884871   PORT_START      /* IN2 */
885872   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
r2821r2822
887874   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
888875   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
889876   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
890   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 Cancel") PORT_CODE(KEYCODE_LALT)
877   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 Cancel") PORT_CODE(KEYCODE_LALT)
891878   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
892   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 B") PORT_CODE(KEYCODE_B)
879   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 B") PORT_CODE(KEYCODE_B)
893880
894881   PORT_START      /* IN2 */
895882   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
r2821r2822
897884   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
898885   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
899886   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
900   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 Flip") PORT_CODE(KEYCODE_SPACE)
887   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 Flip") PORT_CODE(KEYCODE_SPACE)
901888   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
902   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 C") PORT_CODE(KEYCODE_C)
889   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 C") PORT_CODE(KEYCODE_C)
903890
904891   PORT_START      /* IN2 */
905892   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
906893   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
907894   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
908895   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
909   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
910896   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
911897   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
912898   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
913   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 D") PORT_CODE(KEYCODE_D)
899   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P2 D") PORT_CODE(KEYCODE_D)
914900
915901   PORT_START      /* IN2 */
916902   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
r2821r2822
23602346static DRIVER_INIT( mstworld )
23612347{
23622348   /* descramble the program rom .. */
2363   UINT8* source = malloc_or_die(memory_region_length(REGION_CPU1));
2349   int len = memory_region_length(REGION_CPU1);
2350   UINT8* source = malloc_or_die(len);
23642351   UINT8* dst    = memory_region(REGION_CPU1) ;
23652352   int x;
23662353
r2821r2822
23882375      /* bank f     */12, 12,
23892376   };
23902377
2391   memcpy(source, dst, memory_region_length(REGION_CPU1));
2378   memcpy(source, dst, len);
23922379   for (x=0;x<40;x+=2)
23932380   {
23942381      if (tablebank[x]!=-1)
src/mame/drivers/rainbow.c
r2821r2822
809809
810810static DRIVER_INIT( jumping )
811811{
812   int i;
812   int i, len = memory_region_length(REGION_GFX2);
813   UINT8 *rom = memory_region(REGION_GFX2);
813814
814815   /* Sprite colour map is reversed - switch to normal */
815816
816   for (i = 0;i < memory_region_length(REGION_GFX2);i++)
817      memory_region(REGION_GFX2)[i] ^= 0xff;
817   for (i = 0;i < len;i++)
818      rom[i] ^= 0xff;
818819
819820   state_save_register_global(jumping_latch);
820821}
src/mame/drivers/deco_mlc.c
r2821r2822
9696***************************************************************************/
9797
9898#include "driver.h"
99#include "includes/decocrpt.h"
99100#include "machine/eeprom.h"
100101#include "sound/ymz280b.h"
101102#include "decoprot.h"
102103#include "cpu/arm/arm.h"
103104
104extern void decrypt156(void);
105
106105VIDEO_START( mlc );
107106VIDEO_UPDATE( mlc );
108107VIDEO_EOF( mlc );
r2821r2822
735734        Skull Fung where there probably shouldn't be. */
736735   cpunum_set_clockscale(machine, 0, 2.0f);
737736   mainCpuIsArm=1;
738   decrypt156();
737   deco156_decrypt();
739738   descramble_sound();
740739}
741740
src/mame/drivers/tryout.c
r2821r2822
113113   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
114114   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
115115   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
116   PORT_BIT( 0x19, IP_ACTIVE_LOW, IPT_BUTTON1 )
116   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
117117   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
118118   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
119119   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
src/mame/drivers/crystal.c
r2821r2822
866866   ROM_REGION( 0x10000, REGION_USER2,   ROMREGION_ERASEFF )   //Unmapped flash
867867ROM_END
868868
869ROM_START( topbladv )
870   ROM_REGION( 0x20000, REGION_CPU1, 0 ) // bios
871   ROM_LOAD("mx27l1000.u14",  0x000000, 0x020000, CRC(BEFF39A9) SHA1(b6f6dda58d9c82273f9422c1bd623411e58982cb))
869872
873   ROM_REGION32_LE( 0x1000000, REGION_USER1, 0 ) // Flash
874   ROM_LOAD("flash.u1",  0x0000000, 0x1000000, CRC(bd23f640) SHA1(1d22aa2c828642bb7c1dfea4e13f777f95acc701) )
875
876   ROM_REGION( 0x10000, REGION_USER2,   ROMREGION_ERASEFF )   //Unmapped flash
877ROM_END
878
879
880ROM_START( officeye )
881   ROM_REGION( 0x20000, REGION_CPU1, 0 ) // bios (not the standard one)
882   ROM_LOAD("bios.u14",  0x000000, 0x020000, CRC(ffc57e90) SHA1(6b6a17fd4798dea9c7b880f3063be8494e7db302) )
883
884   ROM_REGION32_LE( 0x2000000, REGION_USER1, 0 ) // Flash
885   ROM_LOAD("flash.u1",  0x0000000, 0x1000000, CRC(d3f3eec4) SHA1(ea728415bd4906964b7d37f4379a8a3bd42a1c2d) )
886   ROM_LOAD("flash.u2",  0x1000000, 0x1000000, CRC(e4f85d0a) SHA1(2ddfa6b3a30e69754aa9d96434ff3d37784bfa57) )
887
888   ROM_REGION( 0x10000, REGION_USER2,   ROMREGION_ERASEFF )   //Unmapped flash
889ROM_END
890
891
870892static DRIVER_INIT(crysking)
871893{
872894   UINT16 *Rom=(UINT16*) memory_region(REGION_USER1);
r2821r2822
907929GAME( 2001, crysbios,        0, crystal, crystal,        0, ROT0, "Brezzasoft", "Crystal System BIOS", GAME_IS_BIOS_ROOT )
908930GAME( 2001, crysking, crysbios, crystal, crystal, crysking, ROT0, "Brezzasoft", "The Crystal of Kings", 0 )
909931GAME( 2001, evosocc,  crysbios, crystal, crystal,  evosocc, ROT0, "Evoga", "Evolution Soccer", 0 )
932GAME( 2001, topbladv, crysbios, crystal, crystal,  0,       ROT0, "unknown", "Top Blade V", GAME_NOT_WORKING ) // protection
933
934GAME( 2001, officeye,        0, crystal, crystal,  0,       ROT0, "unknown", "Office Yeo ln Cheon Ha", GAME_NOT_WORKING ) // protection
935
936
src/mame/drivers/eprom.c
r2821r2822
244244static INPUT_PORTS_START( eprom )
245245   PORT_START      /* 26000 */
246246   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
247   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
248247   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
249248   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
250249   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
258257   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) /* Output buffer full (@360030) */
259258   PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_UNUSED ) /* ADEOC, end of conversion */
260259   PORT_BIT( 0x00e0, IP_ACTIVE_LOW, IPT_UNUSED )
261   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START2 )
262260   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
263261   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
264262   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
288286static INPUT_PORTS_START( klaxp )
289287   PORT_START      /* 26000 */
290288   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
291   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
292289   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
293290   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
294291   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
r2821r2822
305302   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) /* Output buffer full (@360030) */
306303   PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_UNUSED ) /* ADEOC, end of conversion */
307304   PORT_BIT( 0x00e0, IP_ACTIVE_LOW, IPT_UNUSED )
308   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START2 )
309305   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
310306   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
311307   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
r2821r2822
322318static INPUT_PORTS_START( guts )
323319   PORT_START      /* 26000 */
324320   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
325   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
326321   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
327322   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
328323   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
336331   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED ) /* Output buffer full (@360030) */
337332   PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_UNUSED ) /* ADEOC, end of conversion */
338333   PORT_BIT( 0x00e0, IP_ACTIVE_LOW, IPT_UNUSED )
339   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START2 )
340334   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
341335   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
342336   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
src/mame/drivers/cshooter.c
r2821r2822
469469GFXDECODE_END
470470
471471static MACHINE_DRIVER_START( cshooter )
472   MDRV_CPU_ADD(Z80,6000000)       /* ? MHz */
472   MDRV_CPU_ADD(Z80,XTAL_12MHz/2)       /* verified on pcb */
473473   MDRV_CPU_PROGRAM_MAP(readmem,writemem)
474474   MDRV_CPU_IO_MAP(readport,writeport)
475475   MDRV_CPU_VBLANK_INT_HACK(cshooter_interrupt,2)
476476
477   MDRV_CPU_ADD(Z80,6000000)       /* ? MHz */
477   MDRV_CPU_ADD(Z80,XTAL_14_31818MHz/4)       /* verified on pcb */
478478   MDRV_CPU_PROGRAM_MAP(s_readmem,s_writemem)
479479   MDRV_CPU_IO_MAP(s_readport,s_writeport)
480480
r2821r2822
495495   MDRV_VIDEO_UPDATE(cshooter)
496496
497497   /* sound hardware */
498   /* YM2151 and ym3931 seibu custom cpu running at XTAL_14_31818MHz/4 */
499
498500MACHINE_DRIVER_END
499501
500502static MACHINE_DRIVER_START( airraid )
501   MDRV_CPU_ADD(Z80,6000000)       /* ? MHz */
503   MDRV_CPU_ADD(Z80,XTAL_12MHz/2)       /* verified on pcb */
502504   MDRV_CPU_PROGRAM_MAP(arreadmem,arwritemem)
503505   MDRV_CPU_IO_MAP(readport,writeport)
504506   MDRV_CPU_VBLANK_INT_HACK(cshooter_interrupt,2)
505507
506   MDRV_CPU_ADD(Z80,6000000)       /* ? MHz */
508   MDRV_CPU_ADD(Z80,XTAL_14_31818MHz/4)       /* verified on pcb */
507509   MDRV_CPU_PROGRAM_MAP(s2_readmem,s2_writemem)
508510   MDRV_CPU_IO_MAP(s_readport,s_writeport)
509511
r2821r2822
524526   MDRV_VIDEO_UPDATE(cshooter)
525527
526528   /* sound hardware */
529   /* YM2151 and ym3931 seibu custom cpu running at XTAL_14_31818MHz/4 */
527530MACHINE_DRIVER_END
528531
529532
src/mame/drivers/rocnrope.c
r2821r2822
66
77#include "driver.h"
88#include "cpu/m6809/m6809.h"
9#include "machine/konami1.h"
910#include "audio/timeplt.h"
1011
1112
12extern void konami1_decode(void);
13
1413extern WRITE8_HANDLER( rocnrope_videoram_w );
1514extern WRITE8_HANDLER( rocnrope_colorram_w );
1615extern WRITE8_HANDLER( rocnrope_flipscreen_w );
r2821r2822
310309
311310static DRIVER_INIT( rocnrope )
312311{
313   extern UINT8 *konami1_decrypted;
312   UINT8 *decrypted = konami1_decode(0);
314313
315   konami1_decode();
316
317   konami1_decrypted[0x703d] = 0x98;   /* fix one instruction */
314   decrypted[0x703d] = 0x98;   /* fix one instruction */
318315}
319316
320317static DRIVER_INIT( rocnropk )
321318{
322   konami1_decode();
319   konami1_decode(0);
323320}
324321
325322
src/mame/drivers/ultrsprt.c
r2821r2822
207207   eeprom_handler(file, read_or_write);
208208}
209209
210static const ppc_config ultrsprt_ppc_cfg =
211{
212   PPC_MODEL_403GA
213};
214
215210static const struct K054539interface k054539_interface =
216211{
217212   REGION_SOUND1
r2821r2822
225220
226221static MACHINE_DRIVER_START( ultrsprt )
227222   /* basic machine hardware */
228   MDRV_CPU_ADD(PPC403, 25000000)      /* PowerPC 403GA 25MHz */
229   MDRV_CPU_CONFIG(ultrsprt_ppc_cfg)
223   MDRV_CPU_ADD(PPC403GA, 25000000)      /* PowerPC 403GA 25MHz */
230224   MDRV_CPU_PROGRAM_MAP(ultrsprt_map, 0)
231225   MDRV_CPU_VBLANK_INT("main", ultrsprt_vblank)
232226
src/mame/drivers/rampart.c
r2821r2822
532532      0x01FF,0x0E00,0x01FF,0x0E00,0x01FF,0x0E00,0x01FF,0x0E00,
533533      0x0000
534534   };
535   UINT8 *rom = memory_region(REGION_CPU1);
535536
536537   atarigen_eeprom_default = compressed_default_eeprom;
537   memcpy(&memory_region(REGION_CPU1)[0x140000], &memory_region(REGION_CPU1)[0x40000], 0x8000);
538   memcpy(&rom[0x140000], &rom[0x40000], 0x8000);
538539   atarigen_slapstic_init(0, 0x140000, 0x438000, 118);
539540}
540541
src/mame/drivers/snowbros.c
r2821r2822
411411
412412static void sb3_play_music(int data)
413413{
414   UINT8 *snd;
415
414416   /* sample is actually played in interrupt function so it loops */
415417   sb3_music = data;
416418
417419   switch (data)
418420   {
419421      case 0x23:
420      memcpy(memory_region(REGION_SOUND1)+0x20000, memory_region(REGION_SOUND1)+0x80000, 0x20000);
422      case 0x26:
423      snd = memory_region(REGION_SOUND1);
424      memcpy(snd+0x20000, snd+0x80000+0x00000, 0x20000);
421425      sb3_music_is_playing = 1;
422426      break;
423427
424428      case 0x24:
425      memcpy(memory_region(REGION_SOUND1)+0x20000, memory_region(REGION_SOUND1)+0x80000+0x20000, 0x20000);
429      snd = memory_region(REGION_SOUND1);
430      memcpy(snd+0x20000, snd+0x80000+0x20000, 0x20000);
426431      sb3_music_is_playing = 1;
427432      break;
428433
429434      case 0x25:
430      memcpy(memory_region(REGION_SOUND1)+0x20000, memory_region(REGION_SOUND1)+0x80000+0x40000, 0x20000);
431      sb3_music_is_playing = 1;
432      break;
433
434      case 0x26:
435      memcpy(memory_region(REGION_SOUND1)+0x20000, memory_region(REGION_SOUND1)+0x80000, 0x20000);
436      sb3_music_is_playing = 1;
437      break;
438
439435      case 0x27:
440436      case 0x28:
441437      case 0x29:
r2821r2822
443439      case 0x2b:
444440      case 0x2c:
445441      case 0x2d:
446      memcpy(memory_region(REGION_SOUND1)+0x20000, memory_region(REGION_SOUND1)+0x80000+0x40000, 0x20000);
442      snd = memory_region(REGION_SOUND1);
443      memcpy(snd+0x20000, snd+0x80000+0x40000, 0x20000);
447444      sb3_music_is_playing = 1;
448445      break;
449446
src/mame/drivers/simpl156.c
r2821r2822
8888
8989*/
9090
91extern void decrypt156(void);
92
9391#include "driver.h"
9492#include "decocrpt.h"
9593#include "deco32.h"
r2821r2822
578576   free (buf1);
579577
580578   deco56_decrypt(REGION_GFX1);
581   decrypt156();
579   deco156_decrypt();
582580
583581   simpl156_default_eeprom = NULL;
584582}
src/mame/drivers/artmagic.c
r2821r2822
148148      hack_irq = 0;
149149      update_irq_state(machine);
150150   }
151   return input_port_read_indexed(machine, 0);
151   return input_port_read(machine, "300000");
152152}
153153
154154
r2821r2822
378378
379379static READ16_HANDLER( special_port5_r )
380380{
381   return input_port_read_indexed(machine, 5) | prot_output_bit;
381   return input_port_read(machine, "300008") | prot_output_bit;
382382}
383383
384384
src/mame/drivers/dblewing.c
r2821r2822
1616#include "sound/2151intf.h"
1717#include "sound/okim6295.h"
1818
19extern void deco102_decrypt(int region, int address_xor, int data_select_xor, int opcode_select_xor);
20
2119/*
2220
2321offs +0
src/mame/drivers/arabian.c
r2821r2822
133133   /* alternate CPU's RAM space while the CPU is running. If the CPU is not     */
134134   /* running (i.e., the /SRES line is low), it needs to look like RAM to pass  */
135135   /* the self-tests */
136   char port[5];
136137
137138   /* if the CPU reset line is being held down, just return RAM */
138139   if (custom_cpu_reset)
r2821r2822
148149      case 3:
149150      case 4:
150151      case 5:
151         return input_port_read_indexed(machine, 2 + offset);
152         sprintf(port, "COM%d", offset);
153         return input_port_read(machine, port);
152154
153155      /* busy flag; this is polled to check the custom CPU's readiness */
154156      /* we just toggle it on and off until the main CPU gets the result */
src/mame/drivers/hornet.c
r2821r2822
683683}
684684
685685/*****************************************************************************/
686static UINT32 *workram;
686687
687static READ32_HANDLER( sysreg_r )
688static READ8_HANDLER( sysreg_r )
688689{
689   UINT32 r = 0;
690   if (offset == 0)
690   UINT8 r = 0;
691
692   switch (offset)
691693   {
692      if (ACCESSING_BITS_24_31)
693      {
694         //printf("read sysreg 0\n");
695         r |= input_port_read_indexed(machine, 0) << 24;
696      }
697      if (ACCESSING_BITS_16_23)
698      {
699         r |= input_port_read_indexed(machine, 1) << 16;
700      }
701      if (ACCESSING_BITS_8_15)
702      {
703         r |= input_port_read_indexed(machine, 2) << 8;
704      }
705      if (ACCESSING_BITS_0_7)
706      {
707         r |= 0xf7;
708      }
694      case 0:
695      case 1:
696      case 2:
697         r = input_port_read_indexed(machine, offset);
698         break;
699
700      case 3:
701         r = 0xf7;
702         break;
703
704      case 4:
705         r = input_port_read_indexed(machine, 3);
706         break;
709707   }
710   else if (offset == 1)
711   {
712      if (ACCESSING_BITS_24_31)
713      {
714         r |= input_port_read_indexed(machine, 3) << 24;
715      }
716   }
717708   return r;
718709}
719710
720static WRITE32_HANDLER( sysreg_w )
711static WRITE8_HANDLER( sysreg_w )
721712{
722   if( offset == 0 ) {
723      if (ACCESSING_BITS_24_31)
724      {
725         led_reg0 = (data >> 24) & 0xff;
726      }
727      if (ACCESSING_BITS_16_23)
728      {
729         led_reg1 = (data >> 16) & 0xff;
730      }
731      return;
732   }
733   if( offset == 1 )
713   switch (offset)
734714   {
735      if (ACCESSING_BITS_24_31)
736      {
737      }
738      if (ACCESSING_BITS_0_7)
739      {
715      case 0:
716         led_reg0 = data;
717         break;
718
719      case 1:
720         led_reg1 = data;
721         break;
722
723      case 7:
740724         if (data & 0x80)   /* CG Board 1 IRQ Ack */
741         {
742725            cpunum_set_input_line(machine, 0, INPUT_LINE_IRQ1, CLEAR_LINE);
743         }
726
744727         if (data & 0x40)   /* CG Board 0 IRQ Ack */
745         {
746728            cpunum_set_input_line(machine, 0, INPUT_LINE_IRQ0, CLEAR_LINE);
747         }
729
748730         set_cgboard_id((data >> 4) & 0x3);
749      }
750      return;
731         break;
751732   }
752733}
753734
r2821r2822
761742static WRITE32_HANDLER( comm_rombank_w )
762743{
763744   int bank = data >> 24;
764   if (memory_region(REGION_USER3))
745   UINT8 *usr3 = memory_region(REGION_USER3);
746   if (usr3)
765747      if( bank != comm_rombank ) {
766748         printf("rombank %02X\n", bank);
767749         comm_rombank = bank & 0x7f;
768         memory_set_bankptr(1, memory_region(REGION_USER3) + (comm_rombank * 0x10000));
750         memory_set_bankptr(1, usr3 + (comm_rombank * 0x10000));
769751      }
770752}
771753
r2821r2822
778760/*****************************************************************************/
779761
780762static ADDRESS_MAP_START( hornet_map, ADDRESS_SPACE_PROGRAM, 32 )
781   AM_RANGE(0x00000000, 0x003fffff) AM_MIRROR(0x80000000) AM_RAM      /* Work RAM */
763   AM_RANGE(0x00000000, 0x003fffff) AM_MIRROR(0x80000000) AM_RAM AM_BASE(&workram)      /* Work RAM */
782764   AM_RANGE(0x74000000, 0x740000ff) AM_MIRROR(0x80000000) AM_READWRITE(K037122_reg_r, K037122_reg_w)
783765   AM_RANGE(0x74020000, 0x7403ffff) AM_MIRROR(0x80000000) AM_READWRITE(K037122_sram_r, K037122_sram_w)
784766   AM_RANGE(0x74040000, 0x7407ffff) AM_MIRROR(0x80000000) AM_READWRITE(K037122_char_r, K037122_char_w)
785767   AM_RANGE(0x78000000, 0x7800ffff) AM_MIRROR(0x80000000) AM_READWRITE(cgboard_dsp_shared_r_ppc, cgboard_dsp_shared_w_ppc)
786768   AM_RANGE(0x780c0000, 0x780c0003) AM_MIRROR(0x80000000) AM_READWRITE(cgboard_dsp_comm_r_ppc, cgboard_dsp_comm_w_ppc)
787   AM_RANGE(0x7d000000, 0x7d00ffff) AM_MIRROR(0x80000000) AM_READ(sysreg_r)
788   AM_RANGE(0x7d010000, 0x7d01ffff) AM_MIRROR(0x80000000) AM_WRITE(sysreg_w)
769   AM_RANGE(0x7d000000, 0x7d00ffff) AM_MIRROR(0x80000000) AM_READ8(sysreg_r, 0xffffffff)
770   AM_RANGE(0x7d010000, 0x7d01ffff) AM_MIRROR(0x80000000) AM_WRITE8(sysreg_w, 0xffffffff)
789771   AM_RANGE(0x7d020000, 0x7d021fff) AM_MIRROR(0x80000000) AM_READWRITE(timekeeper_0_32be_r, timekeeper_0_32be_w)   /* M48T58Y RTC/NVRAM */
790772   AM_RANGE(0x7d030000, 0x7d030007) AM_MIRROR(0x80000000) AM_READWRITE(K056800_host_r, K056800_host_w)
791773   AM_RANGE(0x7d042000, 0x7d043fff) AM_MIRROR(0x80000000) AM_RAM            /* COMM BOARD 0 */
r2821r2822
963945   REGION_SOUND1
964946};
965947
966static const ppc_config hornet_ppc_cfg =
967{
968   PPC_MODEL_403GA
969};
970
971948static sharc_config sharc_cfg =
972949{
973950   BOOT_MODE_EPROM
r2821r2822
983960
984961*/
985962
963static MACHINE_START( hornet )
964{
965   /* set conservative DRC options */
966   cpunum_set_info_int(0, CPUINFO_INT_PPC_DRC_OPTIONS, PPCDRC_COMPATIBLE_OPTIONS);
967
968   /* configure fast RAM regions for DRC */
969   cpunum_set_info_int(0, CPUINFO_INT_PPC_FASTRAM_SELECT, 0);
970   cpunum_set_info_int(0, CPUINFO_INT_PPC_FASTRAM_START, 0x80000000);
971   cpunum_set_info_int(0, CPUINFO_INT_PPC_FASTRAM_END, 0x803fffff);
972   cpunum_set_info_ptr(0, CPUINFO_PTR_PPC_FASTRAM_BASE, workram);
973   cpunum_set_info_int(0, CPUINFO_INT_PPC_FASTRAM_READONLY, 0);
974}
975
986976static MACHINE_RESET( hornet )
987977{
988   if (memory_region(REGION_USER3))
989      memory_set_bankptr(1, memory_region(REGION_USER3));
978   UINT8 *usr3 = memory_region(REGION_USER3);
979   UINT8 *usr5 = memory_region(REGION_USER5);
980   if (usr3)
981      memory_set_bankptr(1, usr3);
990982   cpunum_set_input_line(machine, 2, INPUT_LINE_RESET, ASSERT_LINE);
991983
992   if (memory_region(REGION_USER5))
993      memory_set_bankptr(5, memory_region(REGION_USER5));
984   if (usr5)
985      memory_set_bankptr(5, usr5);
994986}
995987
996988static MACHINE_DRIVER_START( hornet )
997989
998990   /* basic machine hardware */
999   MDRV_CPU_ADD_TAG("main", PPC403, 64000000/2)   /* PowerPC 403GA 32MHz */
1000   MDRV_CPU_CONFIG(hornet_ppc_cfg)
991   MDRV_CPU_ADD_TAG("main", PPC403GA, 64000000/2)   /* PowerPC 403GA 32MHz */
1001992   MDRV_CPU_PROGRAM_MAP(hornet_map, 0)
1002993
1003994   MDRV_CPU_ADD(M68000, 64000000/4)   /* 16MHz */
r2821r2822
10091000
10101001   MDRV_INTERLEAVE(100)
10111002
1003   MDRV_MACHINE_START( hornet )
10121004   MDRV_MACHINE_RESET( hornet )
10131005
10141006   MDRV_NVRAM_HANDLER( timekeeper_0 )
r2821r2822
10361028
10371029static MACHINE_RESET( hornet_2board )
10381030{
1039   if (memory_region(REGION_USER3))
1040      memory_set_bankptr(1, memory_region(REGION_USER3));
1031   UINT8 *usr3 = memory_region(REGION_USER3);
1032   UINT8 *usr5 = memory_region(REGION_USER5);
1033
1034   if (usr3)
1035      memory_set_bankptr(1, usr3);
10411036   cpunum_set_input_line(machine, 2, INPUT_LINE_RESET, ASSERT_LINE);
10421037   cpunum_set_input_line(machine, 3, INPUT_LINE_RESET, ASSERT_LINE);
10431038
1044   if (memory_region(REGION_USER5))
1045      memory_set_bankptr(5, memory_region(REGION_USER5));
1039   if (usr5)
1040      memory_set_bankptr(5, usr5);
10461041}
10471042
10481043static MACHINE_DRIVER_START( hornet_2board )
r2821r2822
10791074
10801075/*****************************************************************************/
10811076
1077static void jamma_jvs_cmd_exec(void);
1078
10821079static UINT8 jvs_rdata[1024];
10831080static UINT8 jvs_sdata[1024];
10841081
10851082static int jvs_rdata_ptr = 0;
10861083static int jvs_sdata_ptr = 0;
1084static int jvs_rdata_count = 0;
10871085
1088static UINT8 jamma_jvs_r(void)
1086static int jamma_jvs_r(UINT8 *data)
10891087{
1090   UINT8 r;
1091   r = jvs_rdata[jvs_rdata_ptr];
1092   jvs_rdata_ptr++;
1093
1094   return r;
1088   if (jvs_rdata_ptr < jvs_rdata_count)
1089   {
1090      *data = jvs_rdata[jvs_rdata_ptr++];
1091      return TRUE;
1092   }
1093   return FALSE;
10951094}
10961095
10971096static void jamma_jvs_w(UINT8 data)
10981097{
1098   if (jvs_sdata_ptr == 0 && data != 0xe0)
1099      return;
10991100   jvs_sdata[jvs_sdata_ptr] = data;
11001101   jvs_sdata_ptr++;
1102
1103   if (jvs_sdata_ptr >= 3 && jvs_sdata_ptr >= 3 + jvs_sdata[2])
1104      jamma_jvs_cmd_exec();
11011105}
11021106
11031107static int jvs_encode_data(UINT8 *in, UINT8 *out, int length)
r2821r2822
11611165   node = jvs_sdata[1];
11621166   byte_num = jvs_sdata[2];
11631167
1164   if (sync != 0xe0)
1165   {
1166      printf("jamma_jvs_cmd_exec: SYNC byte not found! (%02X)\n", sync);
1167      return;
1168   }
1169
11701168   length = jvs_decode_data(&jvs_sdata[3], data, byte_num-1);
11711169
11721170   /*
r2821r2822
12311229   // write sum
12321230   jvs_rdata[3+length] = (UINT8)(sum-1);
12331231
1232   jvs_rdata_count = length + 4;
12341233   jvs_rdata_ptr = 0;
12351234   jvs_sdata_ptr = 0;
12361235}
r2821r2822
12381237/*****************************************************************************/
12391238
12401239
1241static UINT8 jamma_rdata[1024];
1242static void jamma_r(int length)
1243{
1244   int i;
1245//  printf("jamma_r %d\n", length);
1246   for (i=0; i < length; i++)
1247   {
1248      jamma_rdata[i] = jamma_jvs_r();
1249   }
1250}
1251
1252static UINT8 jamma_wdata[1024];
1253static void jamma_w(int length)
1254{
1255   int i;
1256//  printf("jamma_w %d\n", length);
1257   for (i=0; i < length; i++)
1258   {
1259      jamma_jvs_w(jamma_wdata[i]);
1260   }
1261
1262   jamma_jvs_cmd_exec();
1263}
1264
12651240static void sound_irq_callback(running_machine *machine, int irq)
12661241{
12671242   if (irq == 0)
r2821r2822
12831258
12841259   timekeeper_init(0, TIMEKEEPER_M48T58, backup_ram);
12851260
1286   ppc403_install_spu_tx_dma_handler(jamma_w, jamma_wdata);
1287   ppc403_install_spu_rx_dma_handler(jamma_r, jamma_rdata);
1261   cpunum_set_info_fct(0, CPUINFO_PTR_SPU_TX_HANDLER, (genf *)jamma_jvs_w);
1262   cpunum_set_info_fct(0, CPUINFO_PTR_SPU_RX_HANDLER, (genf *)jamma_jvs_r);
12881263}
12891264
12901265static void init_hornet_2board(running_machine *machine)
r2821r2822
13011276
13021277   timekeeper_init(0, TIMEKEEPER_M48T58, backup_ram);
13031278
1304   ppc403_install_spu_tx_dma_handler(jamma_w, jamma_wdata);
1305   ppc403_install_spu_rx_dma_handler(jamma_r, jamma_rdata);
1279   cpunum_set_info_fct(0, CPUINFO_PTR_SPU_TX_HANDLER, (genf *)jamma_jvs_w);
1280   cpunum_set_info_fct(0, CPUINFO_PTR_SPU_RX_HANDLER, (genf *)jamma_jvs_r);
13061281}
13071282
13081283static DRIVER_INIT(gradius4)
src/mame/drivers/policetr.c
r2821r2822
597597      instead of green.  But, the listed checksums on the screen match the
598598      checksums printed on the ROM labels... this seems wierd to me.
599599      However, this has been verified to happen on a real PCB
600
601      There was a PCB on eBay that used mask roms for the program roms with the following checksum
602      values printed on the labels
603
604      U110  050C
605      u111  F343
606      U112  201D
607      U113  FB4x (x maybe 0, 6 or 8.  The picture wasn't clear for this last number)
608
609      These are different then the current set and might have the checksum test corrected.
610
600611*/
601612   ROM_LOAD32_BYTE( "ptb-u113.v13", 0x00000, 0x20000, CRC(d636c00d) SHA1(ef989eb85b51a64ca640297c1286514c8d7f8f76) )
602613   ROM_LOAD32_BYTE( "ptb-u112.v13", 0x00001, 0x20000, CRC(86f0497e) SHA1(d177023f7cb2e01de60ef072212836dc94759c1a) )
src/mame/drivers/seibuspi.c
r2821r2822
12881288   Start - 000111 port 0
12891289*/
12901290
1291static CUSTOM_INPUT( ejanhs_encode )
1292{
1293   static const UINT8 encoding[] = { 0x02, 0x10, 0x03, 0x18, 0x04, 0x20, 0x05, 0x28, 0x06, 0x30, 0x07 };
1294   input_port_value state = input_port_read(field->port->machine, param);
1295   int bit;
1296
1297   for (bit = 0; bit < ARRAY_LENGTH(encoding); bit++)
1298      if (state & (1 << bit))
1299         return encoding[bit];
1300   return 0;
1301}
1302
12911303static INPUT_PORTS_START( spi_ejanhs )
12921304   PORT_START_TAG("IN0")
1293   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 A") PORT_CODE(KEYCODE_A)
1294   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 B") PORT_CODE(KEYCODE_B)
1295   PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 E") PORT_CODE(KEYCODE_E)
1296   PORT_BIT( 0x18, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 F") PORT_CODE(KEYCODE_F)
1297   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 I") PORT_CODE(KEYCODE_I)
1298   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 J") PORT_CODE(KEYCODE_J)
1299   PORT_BIT( 0x05, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 M") PORT_CODE(KEYCODE_M)
1300   PORT_BIT( 0x28, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 N") PORT_CODE(KEYCODE_N)
1301   PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Kan") PORT_CODE(KEYCODE_LCONTROL)
1302   PORT_BIT( 0x30, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Reach") PORT_CODE(KEYCODE_LSHIFT)
1303   PORT_BIT( 0x07, IP_ACTIVE_LOW, IPT_START1 ) PORT_PLAYER(1)
1305   PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM(ejanhs_encode, "IN0BITS")
13041306
13051307   PORT_START_TAG("IN1")
1306   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 C") PORT_CODE(KEYCODE_C)
1307   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 D") PORT_CODE(KEYCODE_D)
1308   PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 G") PORT_CODE(KEYCODE_G)
1309   PORT_BIT( 0x18, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 H") PORT_CODE(KEYCODE_H)
1310   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 K") PORT_CODE(KEYCODE_K)
1311   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 L") PORT_CODE(KEYCODE_L)
1312   PORT_BIT( 0x05, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Chi") PORT_CODE(KEYCODE_SPACE)
1313   PORT_BIT( 0x28, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Pon") PORT_CODE(KEYCODE_LALT)
1314   PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("P1 Ron") PORT_CODE(KEYCODE_Z)
1308   PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM(ejanhs_encode, "IN1BITS")
13151309
13161310   PORT_START_TAG("IN2")
13171311   PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW )
r2821r2822
13291323   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
13301324   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
13311325   PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED )
1326
1327   PORT_START_TAG("IN0BITS")
1328   PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 A") PORT_CODE(KEYCODE_A)
1329   PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 B") PORT_CODE(KEYCODE_B)
1330   PORT_BIT( 0x004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 E") PORT_CODE(KEYCODE_E)
1331   PORT_BIT( 0x008, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 F") PORT_CODE(KEYCODE_F)
1332   PORT_BIT( 0x010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 I") PORT_CODE(KEYCODE_I)
1333   PORT_BIT( 0x020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 J") PORT_CODE(KEYCODE_J)
1334   PORT_BIT( 0x040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 M") PORT_CODE(KEYCODE_M)
1335   PORT_BIT( 0x080, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 N") PORT_CODE(KEYCODE_N)
1336   PORT_BIT( 0x100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Kan") PORT_CODE(KEYCODE_LCONTROL)
1337   PORT_BIT( 0x200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Reach") PORT_CODE(KEYCODE_LSHIFT)
1338   PORT_BIT( 0x400, IP_ACTIVE_HIGH, IPT_START1 ) PORT_PLAYER(1)
1339
1340   PORT_START_TAG("IN1BITS")
1341   PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 C") PORT_CODE(KEYCODE_C)
1342   PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 D") PORT_CODE(KEYCODE_D)
1343   PORT_BIT( 0x004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 G") PORT_CODE(KEYCODE_G)
1344   PORT_BIT( 0x008, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 H") PORT_CODE(KEYCODE_H)
1345   PORT_BIT( 0x010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 K") PORT_CODE(KEYCODE_K)
1346   PORT_BIT( 0x020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 L") PORT_CODE(KEYCODE_L)
1347   PORT_BIT( 0x040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Chi") PORT_CODE(KEYCODE_SPACE)
1348   PORT_BIT( 0x080, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Pon") PORT_CODE(KEYCODE_LALT)
1349   PORT_BIT( 0x100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Ron") PORT_CODE(KEYCODE_Z)
13321350INPUT_PORTS_END
13331351
13341352/********************************************************************/
r2821r2822
28582876   ROM_LOAD("sound1.u0222", 0x200000, 0x080000, CRC(b7bd3703) SHA1(6427a7e6de10d6743d6e64b984a1d1c647f5643a) )
28592877ROM_END
28602878
2879ROM_START(rdft2t) /* SPI Cart, Asia */
2880   ROM_REGION32_LE(0x200000, REGION_USER1, 0)   /* i386 program */
2881   ROM_LOAD32_BYTE("prg0", 0x000000, 0x80000, CRC(7e8c3acc) SHA1(63f4f9f7df7fa028737d9f7dfae96795cde58541) )
2882   ROM_LOAD32_BYTE("prg1", 0x000001, 0x80000, CRC(22cb5b68) SHA1(35f86ad7771fe9aaac3904ed34a96d0cc10ef21c) )
2883   ROM_LOAD32_BYTE("prg2", 0x000002, 0x80000, CRC(3eca68dd) SHA1(98378654adf055d72ae685f90e36643c9d6419d7) )
2884   ROM_LOAD32_BYTE("prg3", 0x000003, 0x80000, CRC(4124daa4) SHA1(42f225c0328df59ffeacc215d37010f825bf507e) )
2885
2886   ROM_REGION( 0x30000, REGION_GFX1, 0)
2887   ROM_LOAD24_BYTE("rf2_5.bin", 0x000001, 0x10000, CRC(377cac2f) SHA1(f7c9323d79b77f6c8c02ba2c6cdca127d6e5cb5c) )
2888   ROM_LOAD24_BYTE("rf2_6.bin", 0x000000, 0x10000, CRC(42bd5372) SHA1(c38df85b25070db9640eac541f71c0511bab0c98) )
2889   ROM_LOAD24_BYTE("rf2_7.bin", 0x000002, 0x10000, CRC(1efaac7e) SHA1(8252af56dcb7a6306dc3422070176778e3c511c2) )
2890
2891   ROM_REGION( 0xc00000, REGION_GFX2, 0)   /* background layer roms */
2892   ROM_LOAD24_WORD("bg-1d.u0535", 0x000000, 0x400000, CRC(6143f576) SHA1(c034923d0663d9ef24357a03098b8cb81dbab9f8) )
2893   ROM_LOAD24_BYTE("bg-1p.u0537", 0x000002, 0x200000, CRC(55e64ef7) SHA1(aae991268948d07342ee8ba1b3761bd180aab8ec) )
2894   ROM_LOAD24_WORD("bg-2d.u0536", 0x600000, 0x400000, CRC(c607a444) SHA1(dc1aa96a42e9394ca6036359670a4ec6f830c96d) )
2895   ROM_LOAD24_BYTE("bg-2p.u0538", 0x600002, 0x200000, CRC(f0830248) SHA1(6075df96b49e70d2243fef691e096119e7a4d044) )
2896
2897   ROM_REGION( 0x1200000, REGION_GFX3, 0)   /* sprites */
2898   ROM_LOAD("obj3.u0434",  0x0000000, 0x400000, CRC(e08f42dc) SHA1(5188d71d4355eaf43ea8893b4cfc4fe80cc24f41) )
2899   ROM_LOAD("obj3b.u0433", 0x0400000, 0x200000, CRC(1b6a523c) SHA1(99a420dbc8e22e7832ccda7cec9fa661a2a2687a) )
2900   ROM_LOAD("obj2.u0431",  0x0600000, 0x400000, CRC(7aeadd8e) SHA1(47103c0579240c5b1add4d0b164eaf76f5fa97f0) )
2901   ROM_LOAD("obj2b.u0432", 0x0a00000, 0x200000, CRC(5d790a5d) SHA1(1ed5d4ad4c9a7e505ce35dcc90d184c26ce891dc) )
2902   ROM_LOAD("obj1.u0429",  0x0c00000, 0x400000, CRC(c2c50f02) SHA1(b81397b5800c6d49f58b7ac7ff6eac56da3c5257) )
2903   ROM_LOAD("obj1b.u0430", 0x1000000, 0x200000, CRC(5259321f) SHA1(3c70c1147e49f81371d0f60f7108d9718d56faf4) )
2904
2905   ROM_REGION(0x200000, REGION_SOUND1, ROMREGION_ERASE00)
2906
2907   ROM_REGION(0x280000, REGION_USER2, ROMREGION_ERASE00)   /* sound roms */
2908   ROM_LOAD("pcm.u0217",    0x000000, 0x200000, CRC(2edc30b5) SHA1(c25d690d633657fc3687636b9070f36bd305ae06) )
2909   ROM_LOAD("sound1.u0222", 0x200000, 0x080000, CRC(b7bd3703) SHA1(6427a7e6de10d6743d6e64b984a1d1c647f5643a) )
2910ROM_END
2911
28612912ROM_START(rfjet) /* SPI Cart, Europe */
28622913   ROM_REGION32_LE(0x200000, REGION_USER1, 0)   /* i386 program */
28632914   ROM_LOAD32_BYTE("prg0.u0211", 0x000000, 0x80000, CRC(e5a3b304) SHA1(f7285f9c69c589fcc71082dc0b9225fdccec855f) )
r2821r2822
30783129GAME( 1997, rdft2a2,   rdft2,   spi,      spi_2button, rdft2,  ROT270, "Seibu Kaihatsu (Dream Island license)", "Raiden Fighters 2 (Asia, Dream Island license, SPI)",  GAME_IMPERFECT_GRAPHICS|GAME_IMPERFECT_SOUND )
30793130GAME( 1997, rdft2a,    rdft2,   spi,      spi_2button, rdft2,  ROT270, "Seibu Kaihatsu (Metrotainment license)", "Raiden Fighters 2 (Asia, Metrotainment license, SPI)",  GAME_IMPERFECT_GRAPHICS|GAME_IMPERFECT_SOUND )
30803131GAME( 1997, rdft2j,    rdft2,   spi,      spi_2button, rdft2,  ROT270, "Seibu Kaihatsu", "Raiden Fighters 2 (Japan, SPI)",  GAME_IMPERFECT_GRAPHICS|GAME_IMPERFECT_SOUND )
3132GAME( 1997, rdft2t,    rdft2,   spi,      spi_2button, rdft2,  ROT270, "Seibu Kaihatsu", "Raiden Fighters 2 (Taiwan, SPI)",  GAME_IMPERFECT_GRAPHICS|GAME_IMPERFECT_SOUND )
30813133
30823134GAME( 1998, rfjet,     0,       spi,      spi_2button, rfjet,    ROT270, "Seibu Kaihatsu (Tuning license)", "Raiden Fighters Jet",  GAME_IMPERFECT_GRAPHICS|GAME_IMPERFECT_SOUND )
30833135GAME( 1998, rfjetu,    rfjet,   spi,      spi_2button, rfjet,    ROT270, "Seibu Kaihatsu (Fabtek license)", "Raiden Fighters Jet (US)",  GAME_IMPERFECT_GRAPHICS|GAME_IMPERFECT_SOUND )
src/mame/drivers/coolpool.c
r2821r2822
940940
941941static DRIVER_INIT( 9ballsht )
942942{
943   int a;
943   int a, len;
944944   UINT16 *rom;
945945
946946   /* decrypt the main program ROMs */
947947   rom = (UINT16 *)memory_region(REGION_USER1);
948   for (a = 0;a < memory_region_length(REGION_USER1)/2;a++)
948   len = memory_region_length(REGION_USER1);
949   for (a = 0;a < len/2;a++)
949950   {
950951      int hi,lo,nhi,nlo;
951952
r2821r2822
968969
969970   /* decrypt the sub data ROMs */
970971   rom = (UINT16 *)memory_region(REGION_USER2);
971   for (a = 1;a < memory_region_length(REGION_USER2)/2;a+=4)
972   len = memory_region_length(REGION_USER2);
973   for (a = 1;a < len/2;a+=4)
972974   {
973975      /* just swap bits 1 and 2 of the address */
974976      UINT16 tmp = rom[a];
src/mame/drivers/midtunit.c
r2821r2822
205205   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
206206   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1)
207207   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1)
208   PORT_BIT( 0x000c, IP_ACTIVE_LOW, IPT_UNUSED )
208   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
209209   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
210210   PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2)
211211   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2)
212   PORT_BIT( 0xffc0, IP_ACTIVE_LOW, IPT_UNUSED )
212   PORT_BIT( 0xff80, IP_ACTIVE_LOW, IPT_UNUSED )
213213   /*Note-the real MK2 board has a special cable designed for SF2 cab conversions that has the 2 SF2
214214          Medium punch/kick buttons as block buttons for MK2. The secondary block button registers in test mode,
215215          but does not have an indicator light show up. During gameplay, the second block only functions temporarily.
src/mame/drivers/carpolo.c
r2821r2822
311311
312312static DRIVER_INIT( carpolo )
313313{
314   size_t i;
314   size_t i, len;
315315   UINT8 *ROM;
316316
317317
318318   /* invert gfx PROM since the bits are active LO */
319319   ROM = memory_region(REGION_GFX2);
320   for (i = 0;i < memory_region_length(REGION_GFX2); i++)
320   len = memory_region_length(REGION_GFX2);
321   for (i = 0;i < len; i++)
321322      ROM[i] ^= 0x0f;
322323}
323324
src/mame/drivers/system1.c
r2821r2822
15071507   PORT_START  /* trigger is in here */
15081508   PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
15091509   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 )
1510   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
15111510
15121511   PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
15131512   PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
src/mame/drivers/tetriunk.c
r2821r2822
221221   int i,j,k;
222222   int index=0;
223223   UINT8 *region = memory_region(REGION_USER1);
224   UINT8 *gfx = memory_region(REGION_GFX2);
225
224226   for(i=0;i<0x20000;i++)
225227   {
226228      //8 pixels/byte
r2821r2822
230232         int pixel=0;
231233         for(k=0;k<4;k++)
232234         {
233            if(memory_region(REGION_GFX2)[k*0x20000+i]&mask)
235            if(gfx[k*0x20000+i]&mask)
234236            {
235237               pixel|=(1<<k);
236238            }
src/mame/drivers/quizo.c
r2821r2822
141141   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN2 )
142142   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_TILT )
143143   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 )
144
145   PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown) )
146   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
147   PORT_DIPSETTING(    0x02, DEF_STR( On ) )
148144   PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown) )
149145   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
150146   PORT_DIPSETTING(    0x20, DEF_STR( On ) )
r2821r2822
230226   ROM_LOAD( "82s123",   0x0000, 0x0020, CRC(c3f15914) SHA1(19fd8e6f2a1256ae51c500a3bf1d7358810ef97e) )
231227ROM_END
232228
229ROM_START( quizoa )
230   ROM_REGION( 0x10000, REGION_CPU1, 0 )
231   ROM_LOAD( "7.bin",   0x0000, 0x4000, CRC(1579ae31) SHA1(b23539413d108223001a9fe827ea151d20682b7b) )
232
233   ROM_REGION( 0x18000, REGION_USER1, 0 )
234   ROM_LOAD( "6.bin",   0x00000, 0x4000, CRC(f00f6356) SHA1(f306ec26ddbb503214e266cc9b74304af86bdbc6) )
235   ROM_LOAD( "5.bin",   0x04000, 0x4000, CRC(39e577e3) SHA1(430d9fe916dfeecdb94c23be89f79a6408ff444e) )
236   ROM_LOAD( "4.bin",   0x08000, 0x4000, CRC(a977bd3a) SHA1(22f1158253a31cf5513eed3537a6096b993b0919) )
237   ROM_LOAD( "3.bin",   0x0c000, 0x4000, CRC(4411bcff) SHA1(2f6692e082b335c3af8b92108f757d333599dd29) )
238   ROM_LOAD( "2.bin",   0x10000, 0x4000, CRC(4a0df776) SHA1(4a7dc2347b33843c0a6bb497be56ccae1af1dae0) )
239   ROM_LOAD( "1.bin",   0x14000, 0x4000, CRC(d9566c1a) SHA1(2495c071d077e5a359c2d7541d8b7c175b398b56) )
240
241   ROM_REGION( 0x0020,  REGION_PROMS, 0 )
242   ROM_LOAD( "82s123",   0x0000, 0x0020, CRC(c3f15914) SHA1(19fd8e6f2a1256ae51c500a3bf1d7358810ef97e) )
243ROM_END
244
245
233246static DRIVER_INIT(quizo)
234247{
235248   videoram=auto_malloc(0x4000*2);
236249}
237250
238GAME( 1985, quizo,  0,       quizo,  quizo,  quizo, ROT0, "Seoul Coin Corp.", "Quiz Olympic", 0 )
251GAME( 1985, quizo,  0,       quizo,  quizo,  quizo, ROT0, "Seoul Coin Corp.", "Quiz Olympic (set 1)", 0 )
252GAME( 1985, quizoa, quizo,   quizo,  quizo,  quizo, ROT0, "Seoul Coin Corp.", "Quiz Olympic (set 2)", 0 )
src/mame/drivers/suprnova.c
r2821r2822
961961   MDRV_SCREEN_ADD("main", RASTER)
962962   MDRV_SCREEN_REFRESH_RATE(60)
963963   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
964   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
964   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
965965   MDRV_SCREEN_SIZE(64*16,64*16)
966966   MDRV_SCREEN_VISIBLE_AREA(0,319,0,239)
967967
src/mame/drivers/dynax.c
r2821r2822
44464446   ROM_LOAD( "n82s147n.1",  0x200, 0x200, CRC(618dbeb3) SHA1(10c8a558430fd1c2cabf9133d3e4f0a5f80eab83) )
44474447ROM_END
44484448
4449/*
44494450
4451Black Touch
4452
4453
4454PCB Layout
4455----------
4456
4457YANG GI CO LTD
4458432605-0003
4459|----------------------------------------|
4460|      DSW1    DSW2   DIP40              |
4461|      YM2203                            |
4462|                 41264  41264           |
4463| 82S147          41264  41264           |
4464| 82S147          41264  41264           |
4465|       22.1184MHz                       |
4466|J        Z80                            |
4467|A        10D                            |
4468|M        8D           DIP40             |
4469|M        6264                           |
4470|A                                       |
4471|         GM68B45S                       |
4472|                                        |
4473|                                        |
4474|                                        |
4475|                                        |
4476|                        G1   H1    I1   |
4477|----------------------------------------|
4478Notes:
4479      Z80 clock 5.5296MHz [22.1184/4]
4480      YM2203 clock 2.7648MHz [22.1184/8]
4481      DIP40 - surface scratched, unknown
4482
4483 */
4484
4485ROM_START( blktouch )
4486   ROM_REGION( 0x90000, REGION_CPU1, 0 )   // Z80 Code
4487   ROM_LOAD( "u43_d8",  0x00000, 0x10000, CRC(0972ab8c) SHA1(ff751fbb37562f216a4fddebd9190acee1f357c8) )
4488   ROM_LOAD( "u45_d10", 0x28000, 0x10000, CRC(5745424a) SHA1(d244d9a9b4c49d255f114842147ba0a795a3e9ac) )
4489
4490   ROM_REGION( 0xc0000, REGION_GFX1, 0 )
4491   ROM_LOAD( "u33_g1", 0x80000, 0x40000, CRC(88737a8b) SHA1(9d812ee732f6cc43c78d8585dabf1b51ed4b89ba) )
4492   ROM_LOAD( "u34_h1", 0x40000, 0x40000, CRC(07216e11) SHA1(402b201c665503a2c9bb1b2f74da0c3db5c3f660) )
4493   ROM_LOAD( "u35_i1", 0x00000, 0x40000, CRC(4ae52ccb) SHA1(84c9466e6f574ec99947084a2e8a336935ad4186) )
4494
4495   ROM_REGION( 0x400, REGION_PROMS, ROMREGION_DISPOSE )   // Color PROMs
4496   ROM_LOAD( "u12",  0x200, 0x200, CRC(80d282ff) SHA1(3ad8dc61fe098ceac3a4be8742c1b360dfa7223a) )
4497   ROM_LOAD( "u13",  0x000, 0x200, CRC(6984aaa9) SHA1(91645cd944cb21266edd13e55a8dc846f6edc419) )
4498ROM_END
4499
4500static DRIVER_INIT( blktouch )
4501{
4502   // fearsome encryption ;-)
4503   UINT8   *src = (UINT8 *)memory_region(REGION_CPU1);
4504   int i;
4505
4506   for (i=0;i<0x90000;i++)
4507   {
4508      src[i] = BITSWAP8(src[i],7,6,5,3,4,2,1,0);
4509
4510   }
4511
4512   src = (UINT8 *)memory_region(REGION_GFX1);
4513
4514   for (i=0;i<0xc0000;i++)
4515   {
4516      src[i] = BITSWAP8(src[i],7,6,5,3,4,2,1,0);
4517
4518   }
4519}
4520
44504521static DRIVER_INIT( maya )
44514522{
44524523   /* Address lines scrambling on 1 z80 rom */
r2821r2822
60786149GAME( 1989, hnoridur, 0,        hnoridur, hnoridur, 0,        ROT180, "Dynax",                    "Hana Oriduru (Japan)",                                         0 )
60796150GAME( 1989, drgpunch, 0,        sprtmtch, sprtmtch, 0,        ROT0,   "Dynax",                    "Dragon Punch (Japan)",                                         0 )
60806151GAME( 1989, sprtmtch, drgpunch, sprtmtch, sprtmtch, 0,        ROT0,   "Dynax (Fabtek license)",   "Sports Match",                                                 0 )
6152/* these 3 are Korean hacks / bootlegs of Dragon Punch / Sports Match */
6153GAME( 1994, maya,     0,        sprtmtch, sprtmtch, maya,     ROT0,   "Promat",                   "Maya",                                                         0 )
6154GAME( 199?, inca,     0,        sprtmtch, sprtmtch, maya,     ROT0,   "<unknown>",                "Inca",                                                         0 )
6155GAME( 199?, blktouch, 0,        sprtmtch, sprtmtch, blktouch, ROT0,   "Yang Gi Co Ltd.",          "Black Touch (Korea)",                                          0 )
6156
60816157GAME( 1989, mjfriday, 0,        mjfriday, mjfriday, 0,        ROT180, "Dynax",                    "Mahjong Friday (Japan)",                                       0 )
60826158GAME( 1990, mcnpshnt, 0,        mcnpshnt, mcnpshnt, 0,        ROT0,   "Dynax",                    "Mahjong Campus Hunting (Japan)",                               0 )
60836159GAME( 1990, 7jigen,   0,        nanajign, nanajign, 0,        ROT180, "Dynax",                    "7jigen no Youseitachi - Mahjong 7 Dimensions (Japan)",         GAME_IMPERFECT_GRAPHICS )
r2821r2822
60856161GAME( 1991, yarunara, 0,        yarunara, yarunara, 0,        ROT180, "Dynax",                    "Mahjong Yarunara (Japan)",                                     0 )
60866162GAME( 1991, mjangels, 0,        yarunara, yarunara, 0,        ROT180, "Dynax",                    "Mahjong Angels - Comic Theater Vol.2 (Japan)",                 0 )
60876163GAME( 1992, quiztvqq, 0,        yarunara, quiztvqq, 0,        ROT180, "Dynax",                    "Quiz TV Gassyuukoku Q&Q (Japan)",                              0 )
6088GAME( 1994, maya,     0,        sprtmtch, sprtmtch, maya,     ROT0,   "Promat",                   "Maya",                                                         0 )
6089GAME( 199?, inca,     maya,     sprtmtch, sprtmtch, maya,     ROT0,   "<unknown>",                "Inca",                                                         0 )
60906164GAME( 1990, jantouki, 0,        jantouki, jantouki, 0,        ROT0,   "Dynax",                    "Jong Tou Ki (Japan)",                                          0 )
60916165GAME( 1993, mjelctrn, 0,        mjelctrn, mjelctrn, mjelct3,  ROT180, "Dynax",                    "Mahjong Electron Base (parts 2 & 4, Japan)",                   0 )
60926166GAME( 1990, mjelct3,  mjelctrn, mjelctrn, mjelct3,  mjelct3,  ROT180, "Dynax",                    "Mahjong Electron Base (parts 2 & 3, Japan)",                   0 )
src/mame/drivers/balsente.c
r2821r2822
18621862   UINT8 *temp = malloc_or_die(0x20000);
18631863   {
18641864      UINT8 *rom = memory_region(REGION_CPU1);
1865      UINT32 len = memory_region_length(REGION_CPU1);
18651866      UINT32 base;
18661867
1867      for (base = 0x10000; base < memory_region_length(REGION_CPU1); base += 0x30000)
1868      for (base = 0x10000; base < len; base += 0x30000)
18681869      {
18691870         UINT8 *ab_base = &temp[0x00000];
18701871         UINT8 *cd_base = &temp[0x10000];
r2821r2822
19281929static DRIVER_INIT( triviag1 ) { expand_roms(EXPAND_ALL);  balsente_shooter = 0; /* noanalog */ }
19291930static DRIVER_INIT( triviag2 )
19301931{
1931   memcpy(&memory_region(REGION_CPU1)[0x20000], &memory_region(REGION_CPU1)[0x28000], 0x4000);
1932   memcpy(&memory_region(REGION_CPU1)[0x24000], &memory_region(REGION_CPU1)[0x28000], 0x4000);
1932   UINT8 *rom = memory_region(REGION_CPU1);
1933   memcpy(&rom[0x20000], &rom[0x28000], 0x4000);
1934   memcpy(&rom[0x24000], &rom[0x28000], 0x4000);
19331935   expand_roms(EXPAND_NONE); balsente_shooter = 0; /* noanalog */
19341936}
19351937static DRIVER_INIT( triviaes )
src/mame/drivers/itgambl2.c
r0r2822
1/************************************************************************
2
3  Italian Gambling games based on H8/3337 MCU + NEC D7759GC (sound).
4
5  Written by Roberto Fresca.
6
7
8  All these games use MCUs with internal ROM for their programs.
9
10  They have 60KB of internal (normally flash) ROM that can't be dumped
11  easily, and thus we can't emulate them at the moment because there is
12  nothing to emulate.
13
14  This driver is just a placeholder for the graphics/sound ROM loading
15
16
17*************************************************************************
18
19  --- Hardware Notes ---
20
21  The hardware is normally composed by:
22
23
24  CPU:   1x H8/3337 (HD64F3337CP16 or HD64F3337F16).
25           (60KB ROM; 2KB RAM)
26
27  Sound: 1x NEC D7759GC.
28         1x TDA2003 (audio amplifier).
29
30  PLDs:  2x ispLSI1032E-70JL.
31
32  Clock: 1x Xtal 16.000 MHz.
33         1x Xtal 14.318180 MHz.
34
35  ROMs:  1x (up to) 27C2000 or similar (sound).
36         3x or 4x 27C4001 or similar (graphics).
37
38  Connectors: 1x 28x2 edge connector.
39              1x RS232 connector.
40              1x 14 legs connector.
41              1x 34 legs connector (optional).
42
43  Other: 1x battery.
44         1x red led.
45         2x 8 DIP switches.
46         2x trimmer.
47
48
49************************************************************************/
50
51#define MAIN_CLOCK   XTAL_16MHz
52#define SND_CLOCK   XTAL_14_31818MHz
53
54#include "driver.h"
55#include "cpu/h83002/h83002.h"
56#include "sound/upd7759.h"
57
58
59/*************************
60*     Video Hardware     *
61*************************/
62
63VIDEO_START( itgambl2 )
64{
65}
66
67
68VIDEO_UPDATE( itgambl2 )
69{
70   return 0;
71}
72
73
74/*************************
75* Memory map information *
76*************************/
77
78static ADDRESS_MAP_START( itgambl2_map, ADDRESS_SPACE_PROGRAM, 16 )
79   ADDRESS_MAP_GLOBAL_MASK(0xffffff)
80   AM_RANGE(0x000000, 0xffffff) AM_ROM
81ADDRESS_MAP_END
82
83
84/*************************
85*      Input ports       *
86*************************/
87
88static INPUT_PORTS_START( itgambl2 )
89    PORT_START
90    PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) )
91    PORT_DIPSETTING(      0x0001, DEF_STR( Off ) )
92    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
93    PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
94    PORT_DIPSETTING(      0x0002, DEF_STR( Off ) )
95    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
96    PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
97    PORT_DIPSETTING(      0x0004, DEF_STR( Off ) )
98    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
99    PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
100    PORT_DIPSETTING(      0x0008, DEF_STR( Off ) )
101    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
102    PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
103    PORT_DIPSETTING(      0x0010, DEF_STR( Off ) )
104    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
105    PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
106    PORT_DIPSETTING(      0x0020, DEF_STR( Off ) )
107    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
108    PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
109    PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
110    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
111    PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
112    PORT_DIPSETTING(      0x0080, DEF_STR( Off ) )
113    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
114    PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
115    PORT_DIPSETTING(      0x0100, DEF_STR( Off ) )
116    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
117    PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
118    PORT_DIPSETTING(      0x0200, DEF_STR( Off ) )
119    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
120    PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
121    PORT_DIPSETTING(      0x0400, DEF_STR( Off ) )
122    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
123    PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
124    PORT_DIPSETTING(      0x0800, DEF_STR( Off ) )
125    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
126    PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
127    PORT_DIPSETTING(      0x1000, DEF_STR( Off ) )
128    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
129    PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
130    PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
131    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
132    PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
133    PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
134    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
135    PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
136    PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
137    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
138INPUT_PORTS_END
139
140
141/*************************
142*    Graphics Layouts    *
143*************************/
144
145static const gfx_layout gfxlayout_8x8x8 =
146{
147/* this is wrong and need to be fixed */
148
149   8,8,
150   RGN_FRAC(1,1),
151   8,
152   { 0, 1, 2, 3, 4, 5, 6, 7 },
153   { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
154   { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 },
155   8*64
156};
157
158
159/******************************
160* Graphics Decode Information *
161******************************/
162
163static GFXDECODE_START( itgambl2 )
164    GFXDECODE_ENTRY( REGION_GFX1, 0, gfxlayout_8x8x8,   0, 16  )
165GFXDECODE_END
166
167
168/**************************
169*      Machine Reset      *
170**************************/
171
172MACHINE_RESET( itgambl2 )
173{
174   /* stop the CPU, we have no code for it anyway */
175   cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, ASSERT_LINE);
176}
177
178
179/**************************
180*     Sound Interface     *
181**************************/
182
183static const struct upd7759_interface upd7759_interface =
184{
185   REGION_SOUND1
186};
187
188
189/**************************
190*     Machine Drivers     *
191**************************/
192
193static MACHINE_DRIVER_START( itgambl2 )
194
195    /* basic machine hardware */
196   MDRV_CPU_ADD_TAG("main", H83044, MAIN_CLOCK)   /* wrong CPU, but we have not a H8/3337 core ATM */
197   MDRV_CPU_PROGRAM_MAP(itgambl2_map,0)
198
199    /* video hardware */
200   MDRV_SCREEN_ADD("main", RASTER)
201   MDRV_SCREEN_REFRESH_RATE(60)
202   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
203   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
204   MDRV_SCREEN_SIZE(512, 256)
205   MDRV_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
206   MDRV_MACHINE_RESET( itgambl2 )
207
208   MDRV_GFXDECODE(itgambl2)
209   MDRV_PALETTE_LENGTH(0x200)
210   MDRV_VIDEO_START( itgambl2 )
211   MDRV_VIDEO_UPDATE( itgambl2 )
212
213    /* sound hardware */
214   MDRV_SPEAKER_STANDARD_MONO("mono")
215   MDRV_SOUND_ADD(UPD7759, UPD7759_STANDARD_CLOCK)
216   MDRV_SOUND_CONFIG(upd7759_interface)
217   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
218MACHINE_DRIVER_END
219
220
221/*************************
222*        Rom Load        *
223*************************/
224
225/* Laser 2001 (Ver 1.2)
226
227CPU:
228
2291x HD64F3337CP16 (main)
2302x ispLSI1032E-70JL (PLD)
2311x NEC D7759GC (sound)
2321x TDA2003 (audio amp)
2331x oscillator 14.318180 MHz
2341x oscillator 16.000 MHz
235
236ROMs:
237
2381x M27C1001 (0)
2394x M27C4001 (1, 2, 3, 4)
240
241Note:
242
2431x 28x2 edge connector
2441x RS232 connector
2451x 14 legs isp connector
2461x battery
2471x red led
2482x 8x2 switches dip
2492x trimmer
250
251*/
252
253ROM_START( laser2k1 )
254   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
255   ROM_LOAD( "laser2k1_ver1.2_hd64f3337cp16.mcu", 0x00000, 0x4000, NO_DUMP )
256
257   ROM_REGION( 0x200000, REGION_GFX1, 0 )
258   ROM_LOAD( "xlep1.bin", 0x000000, 0x80000, CRC(b45c9491) SHA1(1fa0572d3efb847dcf49bb99f429322dcb72b0d1) )
259   ROM_LOAD( "xlep2.bin", 0x080000, 0x80000, CRC(75c82293) SHA1(e6d847a2259393ef8877e9237c7624bf2e36f197) )
260   ROM_LOAD( "xlep3.bin", 0x100000, 0x80000, CRC(3a45d626) SHA1(c804916b6bfe04bacd7ac6f32e5041ed65e7b91e) )
261   ROM_LOAD( "xlep4.bin", 0x180000, 0x80000, CRC(d0381819) SHA1(30bab7e1c68192a2e1c324ef4c8a3d3b5696eb2b) )
262
263   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
264   ROM_LOAD( "xlmsg0.bin", 0x00000, 0x20000, CRC(36287068) SHA1(d964837cb5370c7b878e1e531ef6d8c3840f776c) )
265ROM_END
266
267
268/* Magic Drink (Ver 1.2)
269
270CPU:
271
2721x HD64F3337CP16 (main)
2732x ispLSI1032E-70JL (PLD)
2741x NEC D7759GC (sound)
2751x TDA2003 (audio amp)
2761x oscillator 14.318180 MHz
2771x oscillator 16.000 MHz
278
279ROMs:
280
2811x 27C2000 (s)
2823x M27C4001 (1, 2, 3)
283
284Note:
285
2861x 28x2 edge connector
2871x RS232 connector
2881x 14 legs isp connector
2891x battery
2901x red led
2912x 8x2 switches dip
2922x trimmer
293
294*/
295
296ROM_START( mdrink )
297   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
298   ROM_LOAD( "mdrink_ver1.2_hd64f3337cp16.mcu", 0x00000, 0x4000, NO_DUMP )
299
300   ROM_REGION( 0x180000, REGION_GFX1, 0 ) /* only 3 ROMs?? */
301   ROM_LOAD( "mdrink-1.bin", 0x000000, 0x80000, CRC(25a7cea9) SHA1(d67a7264501699c8f7a48c3f3956903a5c95898f) )
302   ROM_LOAD( "mdrink-2.bin", 0x080000, 0x80000, CRC(c2a14bca) SHA1(8d0095333c34d81d103f15ee5731e2e4aa4d1fac) )
303   ROM_LOAD( "mdrink-3.bin", 0x100000, 0x80000, CRC(ff593676) SHA1(b21bb85df0b7b79c07ded2c4b950c94719e08302) )
304
305   ROM_REGION( 0x40000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
306   ROM_LOAD( "mdrink-s.bin", 0x00000, 0x40000, CRC(d78b7823) SHA1(ca01e4aa3e25c3a40517b4fe07c31915e79af650) )
307ROM_END
308
309
310/* NtCash
311
312CPU:
313
3141x HD64F3337CP16 (main)
3152x ispLSI1032E-70JL (PLD)
3161x NEC D7759GC (sound)
3171x TDA2003 (audio amp)
3181x oscillator 14.318180 MHz
3191x oscillator 16.000 MHz
320
321ROMs:
322
3231x M27C1001 (0)
3244x M27C4001 (1, 2, 3, 4)
325
326Note:
327
3281x 28x2 edge connector
3291x RS232 connector
3301x 14 legs isp connector
3311x battery
3321x red led
3332x 8x2 switches dip
3342x trimmer
335
336*/
337
338ROM_START( ntcash )
339   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
340   ROM_LOAD( "ntcash_hd64f3337cp16.mcu", 0x00000, 0x4000, NO_DUMP )
341
342   ROM_REGION( 0x200000, REGION_GFX1, 0 )
343   ROM_LOAD( "ntcashep1.bin", 0x000000, 0x80000, CRC(f1e8b74d) SHA1(b84e36ab101d6b5b1f60d9778bd8e5d89b3d437d) )
344   ROM_LOAD( "ntcashep2.bin", 0x080000, 0x80000, CRC(b51513c8) SHA1(27b6469daecb92d8a8ed6e9ab317d20f49dd6475) )
345   ROM_LOAD( "ntcashep3.bin", 0x100000, 0x80000, CRC(ba46f1b2) SHA1(61f5b2f1732bbdb2bd21835d2c6e2890c1f0fc8c) )
346   ROM_LOAD( "ntcashep4.bin", 0x180000, 0x80000, CRC(1e42142d) SHA1(82444584b1d61ff0a34d7767f70cab995d26e1e1) )
347
348   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
349   ROM_LOAD( "ntcashmsg0.bin", 0x00000, 0x20000, CRC(e3022f30) SHA1(859bdf0ce871c0b39224dc93b8005a5e0a5552b1) )
350ROM_END
351
352
353/* Wizard (Ver 1.0)
354
355CPU:
356
3571x HD64F3337CP16 (main)
3582x ispLSI1032E-70JL (PLD)
3591x NEC D7759GC (sound)
3601x TDA2003 (audio amp)
3611x oscillator 14.318180 MHz
3621x oscillator 16.000 MHz
363
364ROMs:
365
3661x M27C1001 (0)
3674x M27C4001 (1, 2, 3, 4)
368
369Note:
370
3711x 28x2 edge connector
3721x RS232 connector
3731x 14 legs isp connector
3741x battery
3751x red led
3762x 8x2 DIP switches
3772x trimmer
378
379*/
380
381ROM_START( wizard )
382   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
383   ROM_LOAD( "wizard_ver1.2_hd64f3337cp16.mcu", 0x00000, 0x4000, NO_DUMP )
384
385   ROM_REGION( 0x200000, REGION_GFX1, 0 )
386   ROM_LOAD( "wizardep1.bin", 0x000000, 0x80000, CRC(a99af86f) SHA1(4bf32df74e93a6b40cf8213e99ec6ef538d9802d) )
387   ROM_LOAD( "wizardep2.bin", 0x080000, 0x80000, CRC(bc52566d) SHA1(ecd4f3852c3ba8981316686042dfc2c0013f139f) )
388   ROM_LOAD( "wizardep3.bin", 0x100000, 0x80000, CRC(98e1905a) SHA1(805df94fef011b48d5eb2abbd294b7cd338d7124) )
389   ROM_LOAD( "wizardep4.bin", 0x180000, 0x80000, CRC(f129916a) SHA1(c1c0fcb04622dde196299c2e88a807b2aa00bf5e) )
390
391   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
392   ROM_LOAD( "wizardmsg0.bin", 0x00000, 0x20000, CRC(94b28a4b) SHA1(2c10462cd7c8dc79dba735a061841a9c8b423091) )
393ROM_END
394
395
396/* Unknown... (Ver 1.2)
397
398CPU
399
4001x H8/3337-HDY1A3-64F3337F16 (main)
4011x NEC D7759GC-0124XY007 (sound)
4022x ispLSI1032E-70LJ-C110AA02 (main)
4031x oscillator 14.318180 MHz
4041x oscillator 16.000 MHz
405
406ROMs
407
4081x M27C1001 (0)
4091x 27C4000 (1)
4103x M27C4001 (2, 3, 4)
411
412Note
413
4141x 28x2 edge connector (not JAMMA)
4151x RS232 connector
4161x 14 legs connector
4171x 34 legs connector
4182x 8 DIP switches
4191x battery
4201x trimmer (volume)
4211x trimmer (unknown)
422
423--------------------------
424
425Silkscreened on PCB:
426"CE Angelo Arena - Via Vighi, 26  40026 - Imola (BO)"
427
428PCB n. 2-0276 TE04.01
429
430Formely named "videopoker1"
431
432*/
433
434ROM_START( te0144 )
435   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
436   ROM_LOAD( "te0144_ver1.2_hdy1a3-64f3337f16.mcu", 0x00000, 0x4000, NO_DUMP )
437
438   ROM_REGION( 0x200000, REGION_GFX1, 0 )
439   ROM_LOAD( "pb1.bin", 0x000000, 0x80000, CRC(b7b4ea0f) SHA1(d11096684059e6063747f3e082d70aef1ee8d259) )
440   ROM_LOAD( "pb2.bin", 0x080000, 0x80000, CRC(b02fd07e) SHA1(415a834cd47fdcb180b2a5fa267c1566b9ca0b61) )
441   ROM_LOAD( "pb3.bin", 0x100000, 0x80000, CRC(1984427e) SHA1(0200360f083019235f464ed9b96bf7f78a07df37) )
442   ROM_LOAD( "pb4.bin", 0x180000, 0x80000, CRC(ac513c2d) SHA1(aedc29b12157f02a014359ceae71a2a7892afa72) )
443
444   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
445   ROM_LOAD( "pb0.bin", 0x00000, 0x20000, CRC(123ef964) SHA1(b36d91b58119c15211a54ff7d78c7137d638ea88) )
446ROM_END
447
448
449/* Carta Magica (Ver 1.8)
450
451CPU:
452
4531x H8/3337-HD64F3337CP16 (main)
4541x NEC D7759GC (sound)
4551x TDA2003 (sound)
4562x ispLSI1032E-70LJ-E011J02
4571x oscillator 14.318180 MHz
4581x oscillator 16.000 MHz
459
460ROMs:
461
4621x 27C1001 or similar (0)
4633x 27C4001 or similar (1, 2, 3)
464
465Note:
466
4671x 28x2 edge connector (not JAMMA)
4681x RS232 connector
4691x 14 legs connector
4702x 8 DIP switches
4711x battery
4721x trimmer (volume)
4731x trimmer (unknown)
474
475--------------------------
476
477Silkscreened on PCB:
478"SMS distribuzione"
479"Base 2 Synth Rev.1"
480"APM1"
481
482*/
483
484ROM_START( cmagica )
485   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
486   ROM_LOAD( "cmagica_ver1.8_hd64f3337cp16.mcu", 0x00000, 0x4000, NO_DUMP )
487
488   ROM_REGION( 0x180000, REGION_GFX1, 0 ) /* gfx seems 3bpp, not separated bitplanes? */
489   ROM_LOAD( "1.u6", 0x000000, 0x80000, CRC(3e7e6c9f) SHA1(53a7c4422d9a7c63a21cf4d35d4d883dc2d0eac0) )
490   ROM_LOAD( "2.u7", 0x080000, 0x80000, CRC(6339b62d) SHA1(160030e07600c8db365429c27a33081cfa7d3d61) )
491   ROM_LOAD( "3.u4", 0x100000, 0x80000, CRC(ba636099) SHA1(3d3d9eee5d6808d7666dbf113d7c17a03b6b461e) )
492
493   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
494   ROM_LOAD( "sound.bin", 0x00000, 0x20000, CRC(9dab99a6) SHA1(ce34056dd964be32359acd2e53a6101cb4d9ddff) )
495ROM_END
496
497
498/* Millennium Sun
499
500CPU:
501
5021x H8/3337-HD64F3337F16 (main)
5031x maybe NEC D7759GC (sound)
5041x TDA2003 (audio amp)
5052x ispLSI1032E-70LJ
5061x oscillator 14.318180 MHz
5071x oscillator 16.000 MHz
508
509ROMs:
510
5111x 27C1001 or similar (msg0)
5124x 27C4001 or similar (ep1, ep2, ep3)
513
514Note:
515
5161x 28x2 edge connector (not JAMMA)
5171x RS232 connector
5181x 14 legs connector
5191x 34 legs connector
5202x 8 DIP switches
5211x battery
5221x trimmer (volume)
5231x trimmer (unknown)
524
525--------------------------
526
527Silkscreened on PCB:
528"BV 2-0257/A"
529
530*/
531
532ROM_START( millsun )
533   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
534   ROM_LOAD( "millsun_hd64f3337f16.mcu", 0x00000, 0x4000, NO_DUMP )
535
536   ROM_REGION( 0x200000, REGION_GFX1, 0 ) /* gfx seems 4bpp */
537   ROM_LOAD( "msun_ep1.bin", 0x000000, 0x80000, CRC(06f10795) SHA1(f88a36e11f8ba38439aa066dc013427f204be3d7) )
538   ROM_LOAD( "msun_ep2.bin", 0x080000, 0x80000, CRC(f85d10e6) SHA1(d33017c4a4883a4c9c76132deb5c57eb38f9fdb3) )
539   ROM_LOAD( "msun_ep3.bin", 0x100000, 0x80000, CRC(329d380c) SHA1(618a7010fca8be6c368c3cc09fe129d8a4c72087) )
540   ROM_LOAD( "msun_ep4.bin", 0x180000, 0x80000, CRC(071f5257) SHA1(891116086f5ce99327d9752c99465c25bd6dd69e) )
541
542   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
543   ROM_LOAD( "msun_msg0.bin", 0x00000, 0x20000, CRC(b4bfbbb9) SHA1(ba2d6555f169273fa43de320614a5ea3ba2857e8) )
544ROM_END
545
546
547/* Super Space 2001
548
549CPU:
550
5511x H8/3337-HD64F3337F16 (main)
5521x maybe NEC D7759GC (sound)
5531x TDA2003 (audio amp)
5542x ispLSI1032E-70LJ
5551x oscillator 14.318180 MHz
5561x oscillator 16.000 MHz
557
558ROMs:
559
5601x 27C1001 or similar (msg0)
5614x 27C4001 or similar (ep1, ep2, ep3)
562
563Note:
564
5651x 28x2 edge connector (not JAMMA)
5661x RS232 connector
5671x 14 legs connector
5681x 34 legs connector
5692x 8 DIP switches
5701x battery
5711x trimmer (volume)
5721x trimmer (unknown)
573
574--------------------------
575
576Silkscreened on PCB:
577"BV 2-0257/A"
578
579*/
580
581ROM_START( sspac2k1 )
582   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
583   ROM_LOAD( "sspac2k1_hd64f3337f16.mcu", 0x00000, 0x4000, NO_DUMP )
584
585   ROM_REGION( 0x200000, REGION_GFX1, 0 ) /* gfx seems 4bpp */
586   ROM_LOAD( "sup_spaces_ep1.bin", 0x000000, 0x80000, CRC(d512ee80) SHA1(f113218899394bf1dfe81518746414c4eda9a94c) )
587   ROM_LOAD( "sup_spaces_ep2.bin", 0x080000, 0x80000, CRC(775eb938) SHA1(a83851ea6d90aaf3cad064cdbcc8379eed3d90ca) )
588   ROM_LOAD( "sup_spaces_ep3.bin", 0x100000, 0x80000, CRC(d1d9c06c) SHA1(64993b5572201cc2c29d8900a89f036e96221e05) )
589   ROM_LOAD( "sup_spaces_ep4.bin", 0x180000, 0x80000, CRC(0c02ad49) SHA1(64b382bf6dabf08229324807c6b66e600f38039d) )
590
591   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
592   ROM_LOAD( "sup_spaces_msg0.bin", 0x00000, 0x20000, CRC(93edd0ad) SHA1(f122e147c918c6cb12043008ede729d6e0a4e543) )
593ROM_END
594
595
596/* Elvis?
597
598CPU:
599
6001x H8/3337-HD64F3337CP16
6011x NEC D7759GC (sound)
6021x TDA2003 (audio amp)
6032x ispLSI1032E-70LJ
6041x oscillator 14.318180 MHz
6051x oscillator 16.000 MHz
606
607ROMs:
608
6091x 27C1001 or similar (0)
6103x 27C4001 or similar (1, 2, 3)
611
612Note:
613
6141x 28x2 edge connector (not JAMMA)
6151x RS232 connector
6161x 14 legs connector
6172x 8 DIP switches
6181x battery
6191x trimmer (volume)
6201x trimmer (unknown)
621
622--------------------------
623
624Silkscreened on PCB:
625"2-0250"
626
627*/
628
629ROM_START( elvis )
630   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
631   ROM_LOAD( "elvis_hd64f3337cp16.mcu", 0x00000, 0x4000, NO_DUMP )
632
633   ROM_REGION( 0x180000, REGION_GFX1, 0 )
634   ROM_LOAD( "1.bin", 0x000000, 0x80000, CRC(9e15983f) SHA1(272673ac9685cf0f5cc8a9263c91e4f93c30197f) )
635   ROM_LOAD( "2.bin", 0x080000, 0x80000, CRC(c420af73) SHA1(fb0e03456a4b2f18c35d5ee2efeb29e3f2f26eae) )
636   ROM_LOAD( "3.bin", 0x100000, 0x80000, CRC(bc10b1b6) SHA1(ef25f974cd0b44b91a8db215ff8d2dd3f4313bd8) )
637
638   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* NEC D7759GC samples */
639   ROM_LOAD( "0.bin", 0x00000, 0x20000, CRC(833c5be5) SHA1(89110cb52265ee5bfdf73c0af343b7ce2356e394) )
640ROM_END
641
642
643/*************************
644*      Game Drivers      *
645*************************/
646
647/*    YEAR  NAME      PARENT  MACHINE   INPUT     INIT ROT    COMPANY    FULLNAME                          FLAGS  */
648GAME( 2001, laser2k1, 0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "Laser 2001 (Ver 1.2)",            GAME_NOT_WORKING )
649GAME( 2001, mdrink,   0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "Magic Drink (Ver 1.2)",           GAME_NOT_WORKING )
650GAME( 2001, ntcash,   0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "NtCash",                          GAME_NOT_WORKING )
651GAME( 2001, wizard,   0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "Wizard (Ver 1.0)",                GAME_NOT_WORKING )
652GAME( 2001, te0144,   0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "Unknown italian gambling game",   GAME_NOT_WORKING )
653GAME( 200?, cmagica,  0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "Carta Magica (Ver 1.8)",          GAME_NOT_WORKING )
654GAME( 200?, millsun,  0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "Millennium Sun",                  GAME_NOT_WORKING )
655GAME( 200?, sspac2k1, 0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "Super Space 2001",                GAME_NOT_WORKING )
656GAME( 200?, elvis,    0,      itgambl2, itgambl2, 0,   ROT0, "Unknown", "Elvis?",                          GAME_NOT_WORKING )
src/mame/drivers/sspeedr.c
r2821r2822
8181
8282static WRITE8_HANDLER( sspeedr_score_w )
8383{
84   char buf[10];
84   char buf[20];
8585   sprintf(buf, "LED%02d", offset);
8686   data = ~data & 15;
8787   output_set_digit_value(offset, ls48_map[data]);
src/mame/drivers/filetto.c
r2821r2822
584584static INPUT_PORTS_START( filetto )
585585   PORT_START
586586   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //START1
587   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(1)
588   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(1)
589   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
587   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(1)
588   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(1)
589   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
590590   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) //START2
591591   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2)
592592   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2)
src/mame/drivers/deco32.c
r2821r2822
241241static emu_timer *raster_irq_timer;
242242static UINT8 nslasher_sound_irq;
243243
244extern void decrypt156(void);
245
246244/**********************************************************************************/
247245
248246static TIMER_CALLBACK( interrupt_gen )
r2821r2822
32773275   deco56_decrypt(REGION_GFX1); /* 141 */
32783276   deco74_decrypt(REGION_GFX2);
32793277
3280   decrypt156();
3278   deco156_decrypt();
32813279
32823280   soundlatch_setclearedvalue(0xff);
32833281
src/mame/drivers/goodejan.c
r2821r2822
176176   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
177177   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
178178
179   PORT_START
179180   PORT_DIPNAME( 0x0001, 0x0001, "4" )
180181    PORT_DIPSETTING(      0x0001, DEF_STR( Off ) )
181182    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
src/mame/drivers/zaxxon.c
r2821r2822
470470static INPUT_CHANGED( zaxxon_coin_inserted )
471471{
472472   if (newval)
473      coin_status[(int)param] = coin_enable[(int)param];
473      coin_status[(int)(FPTR)param] = coin_enable[(int)(FPTR)param];
474474}
475475
476476
477477static CUSTOM_INPUT( zaxxon_coin_r )
478478{
479   return coin_status[(int)param];
479   return coin_status[(int)(FPTR)param];
480480}
481481
482482
src/mame/drivers/trackfld.c
r2821r2822
1818***************************************************************************/
1919
2020#include "driver.h"
21#include "machine/konami1.h"
2122#include "cpu/m6809/m6809.h"
2223#include "sound/sn76496.h"
2324#include "sound/vlm5030.h"
r2821r2822
2526#include "sound/msm5205.h"
2627
2728
28void konami1_decode(void);
29UINT8 konami1_decodebyte( UINT8 opcode, UINT16 address );
30
31
3229extern UINT8 *trackfld_scroll;
3330extern UINT8 *trackfld_scroll2;
3431
r2821r2822
12511248
12521249static DRIVER_INIT( trackfld )
12531250{
1254   konami1_decode();
1251   konami1_decode(0);
12551252}
12561253
12571254static DRIVER_INIT( atlantol )
12581255{
12591256   UINT8 *rom = memory_region(REGION_CPU1);
1260   int size = memory_region_length(REGION_CPU1);
1261   UINT8 *decrypt = auto_malloc(size);
1257   UINT8 *decrypt;
12621258   int A;
12631259
1264   memory_set_decrypted_region(0, 0x0000, 0xffff, decrypt);
1260   /* "konami1" encrypted opcodes */
1261   decrypt = konami1_decode(0);
12651262
12661263   /* not encrypted opcodes */
12671264   for (A = 0;A < 0x6000;A++)
12681265      decrypt[A] = rom[A];
12691266
1270   /* "konami1" encrypted opcodes */
1271   for (A = 0x6000;A < size;A++)
1272      decrypt[A] = konami1_decodebyte(rom[A],A);
1267   memory_set_decrypted_region(0, 0x0000, 0xffff, decrypt);
12731268
12741269   memory_install_write8_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x1000, 0x1000, 0, 0, SMH_NOP );
12751270}
src/mame/drivers/astrof.c
r2821r2822
605605   PORT_START_TAG("COIN")
606606   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED(coin_inserted, 0)
607607   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_CHANGED(service_coin_inserted, 0)
608   PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
608   PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNUSED )
609609INPUT_PORTS_END
610610
611611
r2821r2822
658658   PORT_START_TAG("COIN")
659659   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED(coin_inserted, 0)
660660   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_CHANGED(service_coin_inserted, 0)
661   PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
661   PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNUSED )
662662INPUT_PORTS_END
663663
664664
r2821r2822
712712   PORT_START_TAG("COIN")
713713   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED(coin_inserted, 0)
714714   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_CHANGED(service_coin_inserted, 0)
715   PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
715   PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNUSED )
716716INPUT_PORTS_END
717717
718718
r2821r2822
766766   PORT_START_TAG("COIN")
767767   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED(coin_inserted, 0)
768768   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_CHANGED(service_coin_inserted, 0)
769   PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
769   PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNUSED )
770770INPUT_PORTS_END
771771
772772
r2821r2822
823823   PORT_START_TAG("COIN")
824824   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED(coin_inserted, 0)
825825   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_CHANGED(service_coin_inserted, 0)
826   PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
826   PORT_BIT( 0xfc, IP_ACTIVE_HIGH, IPT_UNUSED )
827827INPUT_PORTS_END
828828
829829
src/mame/drivers/karnov.c
r2821r2822
508508   PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
509509   PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
510510   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
511   PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Difficulty ) )
512   PORT_DIPSETTING(    0x08, DEF_STR( Easy ) )
513   PORT_DIPSETTING(    0x0c, DEF_STR( Normal ) )
514   PORT_DIPSETTING(    0x04, DEF_STR( Hard ) )
511   PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Difficulty ) )
512   PORT_DIPSETTING(    0x80, DEF_STR( Easy ) )
513   PORT_DIPSETTING(    0xc0, DEF_STR( Normal ) )
514   PORT_DIPSETTING(    0x40, DEF_STR( Hard ) )
515515   PORT_DIPSETTING(    0x00, DEF_STR( Hardest ) )
516516INPUT_PORTS_END
517517
src/mame/drivers/lwings.c
r2821r2822
574574   PORT_DIPSETTING(    0x00, DEF_STR( None ) )
575575   PORT_DIPUNUSED_DIPLOC( 0x20, 0x20, "SWB:3" )
576576   PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SWB:2" )
577   PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SWB:1" )
577   PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SWB:1" )
578578
579579   PORT_START_TAG("DSWA")
580580   PORT_DIPNAME( 0x03, 0x03, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SWA:8,7")
src/mame/drivers/maxaflex.c
r2821r2822
531531
532532static DRIVER_INIT( a600xl )
533533{
534   memcpy( memory_region(REGION_CPU1) + 0x5000, memory_region(REGION_CPU1) + 0xd000, 0x800 );
534   UINT8 *rom = memory_region(REGION_CPU1);
535   memcpy( rom + 0x5000, rom + 0xd000, 0x800 );
535536}
536537
537538GAME( 1984, maxaflex, 0,        maxaflex, a600xl, a600xl, ROT0, "Exidy", "Max-A-Flex", GAME_IS_BIOS_ROOT )
src/mame/drivers/finalizr.c
r2821r2822
88
99#include "driver.h"
1010#include "deprecat.h"
11#include "machine/konami1.h"
1112#include "cpu/m6809/m6809.h"
1213#include "cpu/i8039/i8039.h"
1314#include "sound/sn76496.h"
1415#include "sound/dac.h"
1516
1617
17void konami1_decode(void);
18
1918extern UINT8 *finalizr_scroll;
2019extern UINT8 *finalizr_videoram2,*finalizr_colorram2;
2120static UINT8 *finalizr_interrupt_enable;
r2821r2822
500499
501500static DRIVER_INIT( finalizr )
502501{
503   konami1_decode();
502   konami1_decode(0);
504503}
505504
506505
src/mame/drivers/cclimber.c
r2821r2822
826826   PORT_DIPSETTING(    0xc0, DEF_STR( 1C_6C ) )
827827
828828   PORT_START_TAG("DSW1")
829   PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED )
829   PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNUSED )
830830   PORT_DIPNAME( 0x10, 0x10, DEF_STR( Cabinet ) )
831831   PORT_DIPSETTING(    0x10, DEF_STR( Upright ) )
832832   PORT_DIPSETTING(    0x00, DEF_STR( Cocktail ) )
src/mame/drivers/enigma2.c
r2821r2822
170170   pen_t pens[NUM_PENS];
171171
172172   const rectangle *visarea = video_screen_get_visible_area(screen);
173   UINT8 *color_map_base = engima2_flip_screen ? &memory_region(REGION_PROMS)[0x0400] : memory_region(REGION_PROMS);
174   UINT8 *star_map_base = (blink_count & 0x08) ? &memory_region(REGION_PROMS)[0x0c00] : &memory_region(REGION_PROMS)[0x0800];
173   UINT8 *prom = memory_region(REGION_PROMS);
174   UINT8 *color_map_base = engima2_flip_screen ? &prom[0x0400] : &prom[0x0000];
175   UINT8 *star_map_base = (blink_count & 0x08) ? &prom[0x0c00] : &prom[0x0800];
175176
176177   UINT8 x = 0;
177178   UINT16 bitmap_y = visarea->min_y;
r2821r2822
655656static DRIVER_INIT(enigma2)
656657{
657658   offs_t i;
659   UINT8 *rom = memory_region(REGION_CPU2);
658660
659661   for(i = 0; i < 0x2000; i++)
660662   {
661      memory_region(REGION_CPU2)[i] = BITSWAP8(memory_region(REGION_CPU2)[i],4,5,6,0,7,1,3,2);
663      rom[i] = BITSWAP8(rom[i],4,5,6,0,7,1,3,2);
662664   }
663665}
664666
src/mame/drivers/segaorun.c
r2821r2822
1616#include "driver.h"
1717#include "deprecat.h"
1818#include "system16.h"
19#include "machine/fd1089.h"
1920#include "machine/segaic16.h"
2021#include "machine/8255ppi.h"
2122#include "cpu/m68000/m68000.h"
r2821r2822
17351736
17361737static DRIVER_INIT( shangon3 )
17371738{
1738   extern void fd1089_decrypt_0034(void);
17391739   outrun_generic_init(machine);
17401740   fd1089_decrypt_0034();
17411741   custom_io_r = shangon_custom_io_r;
src/mame/drivers/gticlub.c
r2821r2822
366366}
367367
368368/* Konami K056230 (LANC) */
369static UINT8 K056230_r(int reg)
369READ8_HANDLER( K056230_r )
370370{
371   switch (reg)
371   switch (offset)
372372   {
373373      case 0:      // Status register
374374      {
r2821r2822
376376      }
377377   }
378378
379//  mame_printf_debug("K056230_r: %d at %08X\n", reg, activecpu_get_pc());
379//  mame_printf_debug("K056230_r: %d at %08X\n", offset, activecpu_get_pc());
380380
381381   return 0;
382382}
383383
384static void K056230_w(int reg, UINT8 data)
384TIMER_CALLBACK( network_irq_gen )
385385{
386   switch (reg)
386   cpunum_set_input_line(Machine, 0, INPUT_LINE_IRQ2, ASSERT_LINE);
387}
388
389WRITE8_HANDLER( K056230_w )
390{
391   switch (offset)
387392   {
388393      case 0:      // Mode register
389394      {
r2821r2822
396401            // Thunder Hurricane breaks otherwise...
397402            if (mame_stricmp(Machine->gamedrv->name, "thunderh") != 0)
398403            {
399               cpunum_set_input_line(Machine, 0, INPUT_LINE_IRQ2, ASSERT_LINE);
404//                  timer_set(ATTOTIME_IN_MSEC(1), NULL, 0, network_irq_gen);
405//                  cpunum_set_input_line(Machine, 0, INPUT_LINE_IRQ2, ASSERT_LINE);
400406            }
401407         }
408         else
409            cpunum_set_input_line(Machine, 0, INPUT_LINE_IRQ2, CLEAR_LINE);
402410         break;
403411      }
404412      case 2:      // Sub ID register
r2821r2822
406414         break;
407415      }
408416   }
409//  mame_printf_debug("K056230_w: %d, %02X at %08X\n", reg, data, activecpu_get_pc());
417//  mame_printf_debug("K056230_w: %d, %02X at %08X\n", offset, data, activecpu_get_pc());
410418}
411419
412READ32_HANDLER( lanc_r )
413{
414   UINT32 r = 0;
415   int reg = offset * 4;
416
417   if (ACCESSING_BITS_24_31)
418   {
419      r |= K056230_r(reg+0) << 24;
420   }
421   if (ACCESSING_BITS_16_23)
422   {
423      r |= K056230_r(reg+1) << 16;
424   }
425   if (ACCESSING_BITS_8_15)
426   {
427      r |= K056230_r(reg+2) << 8;
428   }
429   if (ACCESSING_BITS_0_7)
430   {
431      r |= K056230_r(reg+3) << 0;
432   }
433
434   return r;
435}
436
437WRITE32_HANDLER( lanc_w )
438{
439   int reg = offset * 4;
440
441   if (ACCESSING_BITS_24_31)
442   {
443      K056230_w(reg+0, (data >> 24) & 0xff);
444   }
445   if (ACCESSING_BITS_16_23)
446   {
447      K056230_w(reg+1, (data >> 16) & 0xff);
448   }
449   if (ACCESSING_BITS_8_15)
450   {
451      K056230_w(reg+2, (data >> 8) & 0xff);
452   }
453   if (ACCESSING_BITS_0_7)
454   {
455      K056230_w(reg+3, (data >> 0) & 0xff);
456   }
457}
458
459420static UINT32 lanc_ram[0x2000/4];
460421READ32_HANDLER( lanc_ram_r )
461422{
r2821r2822
482443   AM_RANGE(0x78080000, 0x7808000f) AM_MIRROR(0x80000000) AM_READWRITE(K001006_1_r, K001006_1_w)
483444   AM_RANGE(0x780c0000, 0x780c0003) AM_MIRROR(0x80000000) AM_READWRITE(cgboard_dsp_comm_r_ppc, cgboard_dsp_comm_w_ppc)
484445   AM_RANGE(0x7e000000, 0x7e003fff) AM_MIRROR(0x80000000) AM_READWRITE(sysreg_r, sysreg_w)
485   AM_RANGE(0x7e008000, 0x7e009fff) AM_MIRROR(0x80000000) AM_READWRITE(lanc_r, lanc_w)
446   AM_RANGE(0x7e008000, 0x7e009fff) AM_MIRROR(0x80000000) AM_READWRITE8(K056230_r, K056230_w, 0xffffffff)
486447   AM_RANGE(0x7e00a000, 0x7e00bfff) AM_MIRROR(0x80000000) AM_READWRITE(lanc_ram_r, lanc_ram_w)
487448   AM_RANGE(0x7e00c000, 0x7e00c007) AM_MIRROR(0x80000000) AM_WRITE(K056800_host_w)
488449   AM_RANGE(0x7e00c000, 0x7e00c007) AM_MIRROR(0x80000000) AM_READ(K056800_host_r)      // Hang Pilot
r2821r2822
747708}
748709
749710
750static const ppc_config gticlub_ppc_cfg =
751{
752   PPC_MODEL_403GA
753};
754
755711static const sharc_config sharc_cfg =
756712{
757713   BOOT_MODE_EPROM
r2821r2822
770726static MACHINE_DRIVER_START( gticlub )
771727
772728   /* basic machine hardware */
773   MDRV_CPU_ADD(PPC403, 64000000/2)   /* PowerPC 403GA 32MHz */
774   MDRV_CPU_CONFIG(gticlub_ppc_cfg)
729   MDRV_CPU_ADD(PPC403GA, 64000000/2)   /* PowerPC 403GA 32MHz */
775730   MDRV_CPU_PROGRAM_MAP(gticlub_map, 0)
776731   MDRV_CPU_VBLANK_INT("main", gticlub_vblank)
777732
r2821r2822
816771static MACHINE_DRIVER_START( hangplt )
817772
818773   /* basic machine hardware */
819   MDRV_CPU_ADD(PPC403, 64000000/2)   /* PowerPC 403GA 32MHz */
820   MDRV_CPU_CONFIG(gticlub_ppc_cfg)
774   MDRV_CPU_ADD(PPC403GA, 64000000/2)   /* PowerPC 403GA 32MHz */
821775   MDRV_CPU_PROGRAM_MAP(gticlub_map, 0)
822776
823777   MDRV_CPU_ADD(M68000, 64000000/4)   /* 16MHz */
r2821r2822
1043997   DRIVER_INIT_CALL(gticlub);
1044998
1045999   // enable self-modifying code checks
1046   cpunum_set_info_int(0, CPUINFO_INT_PPC_DRC_OPTIONS, PPCDRC_OPTIONS_CHECK_SELFMOD_CODE);
1000   cpunum_set_info_int(0, CPUINFO_INT_PPC_DRC_OPTIONS, PPCDRC_STRICT_VERIFY);
10471001}
10481002
10491003/*************************************************************************/
src/mame/drivers/cloak.c
r2821r2822
242242   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
243243
244244   PORT_START   /* IN3 */
245   PORT_BIT( 0x2f, IP_ACTIVE_LOW, IPT_UNUSED )      // not connected
245   PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED )      // not connected
246246   PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_UNUSED )   // pulled high
247247   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_START2 )
248248   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START1 )
src/mame/drivers/mazerbla.c
r2821r2822
14521452
14531453static MACHINE_RESET( greatgun )
14541454{
1455   UINT8 *rom = memory_region(REGION_CPU3);
14551456   game_id = GREATGUN;
14561457   zpu_int_vector = 0xff;
14571458   cpunum_set_irq_callback(0, irq_callback);
r2821r2822
14591460
14601461//patch VCU test
14611462//VCU test starts at PC=0x56f
1462   memory_region(REGION_CPU3)[0x05b6] = 0;
1463   memory_region(REGION_CPU3)[0x05b7] = 0;
1463   rom[0x05b6] = 0;
1464   rom[0x05b7] = 0;
14641465//so we also need to patch ROM checksum test
1465   memory_region(REGION_CPU3)[0x037f] = 0;
1466   memory_region(REGION_CPU3)[0x0380] = 0;
1466   rom[0x037f] = 0;
1467   rom[0x0380] = 0;
14671468}
14681469
14691470
src/mame/drivers/namcona1.c
r2821r2822
13121312   /* sound hardware */
13131313   MDRV_SPEAKER_STANDARD_STEREO("left", "right")
13141314
1315   MDRV_SOUND_ADD(C140, 42667)
1315   MDRV_SOUND_ADD(C140, 44100)
13161316   MDRV_SOUND_CONFIG(C140_interface_typeA)
13171317   MDRV_SOUND_ROUTE(0, "right", 1.00)
13181318   MDRV_SOUND_ROUTE(1, "left", 1.00)
src/mame/drivers/kaneko16.c
r2821r2822
14301430
14311431   PORT_START   // Fake IN1 - To be pressed during boot sequence - Code at 0x000c9e
14321432   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("IN 1-0") PORT_CODE(KEYCODE_H)   // "sound test"
1433   PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
1434   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
1435   PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
1433   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN )
1434   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNKNOWN )
1435   PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNKNOWN )
14361436   PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("IN 1-4") PORT_CODE(KEYCODE_J)   // "view tiles"
14371437   PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("IN 1-5") PORT_CODE(KEYCODE_K)   // "view memory"
14381438   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("IN 1-6") PORT_CODE(KEYCODE_L)   // "view sprites ?"
src/mame/drivers/gauntlet.c
r2821r2822
16331633
16341634static void gauntlet_common_init(int slapstic, int vindctr2)
16351635{
1636   UINT8 *rom = memory_region(REGION_CPU1);
16361637   atarigen_eeprom_default = NULL;
16371638   atarigen_slapstic_init(0, 0x038000, 0, slapstic);
16381639
16391640   /* swap the top and bottom halves of the main CPU ROM images */
1640   atarigen_swap_mem(memory_region(REGION_CPU1) + 0x000000, memory_region(REGION_CPU1) + 0x008000, 0x8000);
1641   atarigen_swap_mem(memory_region(REGION_CPU1) + 0x040000, memory_region(REGION_CPU1) + 0x048000, 0x8000);
1642   atarigen_swap_mem(memory_region(REGION_CPU1) + 0x050000, memory_region(REGION_CPU1) + 0x058000, 0x8000);
1643   atarigen_swap_mem(memory_region(REGION_CPU1) + 0x060000, memory_region(REGION_CPU1) + 0x068000, 0x8000);
1644   atarigen_swap_mem(memory_region(REGION_CPU1) + 0x070000, memory_region(REGION_CPU1) + 0x078000, 0x8000);
1641   atarigen_swap_mem(rom + 0x000000, rom + 0x008000, 0x8000);
1642   atarigen_swap_mem(rom + 0x040000, rom + 0x048000, 0x8000);
1643   atarigen_swap_mem(rom + 0x050000, rom + 0x058000, 0x8000);
1644   atarigen_swap_mem(rom + 0x060000, rom + 0x068000, 0x8000);
1645   atarigen_swap_mem(rom + 0x070000, rom + 0x078000, 0x8000);
16451646
16461647   /* indicate whether or not we are vindicators 2 */
16471648   vindctr2_screen_refresh = vindctr2;
src/mame/drivers/ms32.c
r2821r2822
170170#include "driver.h"
171171#include "deprecat.h"
172172#include "sound/ymf271.h"
173#include "includes/ms32.h"
173174
174extern UINT32 *ms32_fce00000;
175extern UINT32 *ms32_roz_ctrl;
176extern UINT32 *ms32_tx_scroll;
177extern UINT32 *ms32_bg_scroll;
178extern UINT32 *ms32_priram;
179extern UINT32 *ms32_palram;
180extern UINT32 *ms32_bgram;
181extern UINT32 *ms32_rozram;
182extern UINT32 *ms32_lineram;
183extern UINT32 *ms32_spram;
184extern UINT32 *ms32_txram;
185extern UINT32 *ms32_mainram;
186
187WRITE32_HANDLER( ms32_brightness_w );
188WRITE32_HANDLER( ms32_palram_w );
189READ32_HANDLER( ms32_txram_r );
190WRITE32_HANDLER( ms32_txram_w );
191READ32_HANDLER( ms32_rozram_r );
192WRITE32_HANDLER( ms32_rozram_w );
193READ32_HANDLER( ms32_lineram_r );
194WRITE32_HANDLER( ms32_lineram_w );
195READ32_HANDLER( ms32_bgram_r );
196WRITE32_HANDLER( ms32_bgram_w );
197READ32_HANDLER( ms32_spram_r );
198WRITE32_HANDLER( ms32_spram_w );
199READ32_HANDLER( ms32_priram_r );
200WRITE32_HANDLER( ms32_priram_w );
201WRITE32_HANDLER( ms32_gfxctrl_w );
202VIDEO_START( ms32 );
203VIDEO_UPDATE( ms32 );
204
205175static UINT32 *ms32_fc000000;
206176
207177static UINT32 *ms32_mahjong_input_select;
r2821r2822
11071077
11081078INPUT_PORTS_END
11091079
1080
1081static INPUT_PORTS_START( wpksocv2 )
1082   PORT_INCLUDE( ms32 )
1083
1084   PORT_MODIFY("IN1")
1085   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
1086   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
1087
1088   PORT_MODIFY("IN2")
1089   /* Still missing the correct input for begin the left right movement */
1090   PORT_BIT( 0x0f, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(7) PORT_PLAYER(1)
1091   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
1092   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
1093   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
1094   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
1095
1096   PORT_MODIFY("IN3")
1097   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
1098   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
1099   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
1100   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
1101   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
1102   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
1103   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
1104   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
1105
1106   PORT_MODIFY("DSW1")
1107   PORT_DIPNAME( 0xe0, 0xe0, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:3,2,1")
1108   PORT_DIPSETTING(    0x80, DEF_STR( 4C_1C ) )
1109   PORT_DIPSETTING(    0x40, DEF_STR( 3C_1C ) )
1110   PORT_DIPSETTING(    0xc0, DEF_STR( 2C_1C ) )
1111   PORT_DIPSETTING(    0xe0, DEF_STR( 1C_1C ) )
1112   PORT_DIPSETTING(    0x00, DEF_STR( 2C_3C ) )
1113   PORT_DIPSETTING(    0x60, DEF_STR( 1C_2C ) )
1114   PORT_DIPSETTING(    0xa0, DEF_STR( 1C_3C ) )
1115   PORT_DIPSETTING(    0x20, DEF_STR( 1C_4C ) )
1116   PORT_DIPNAME( 0x10, 0x10, DEF_STR( Demo_Sounds) ) PORT_DIPLOCATION("SW1:4")
1117   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
1118   PORT_DIPSETTING(    0x10, DEF_STR( On ) )
1119   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:5")
1120   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
1121   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1122   PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:6")
1123   PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
1124   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1125   PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:7")
1126   PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
1127   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1128   PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:8")
1129   PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
1130   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1131
1132   PORT_MODIFY("DSW3")
1133   PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Region ) ) PORT_DIPLOCATION("SW3:2,1")
1134   PORT_DIPSETTING(    0x40, DEF_STR( USA ) )
1135   PORT_DIPSETTING(    0x00, DEF_STR( World ) )
1136//  PORT_DIPSETTING(    0x80, "?" )
1137   PORT_DIPSETTING(    0xc0, DEF_STR( Japan ) )
1138   PORT_DIPNAME( 0x20, 0x00, "Tickets" ) PORT_DIPLOCATION("SW3:3")
1139   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
1140   PORT_DIPSETTING(    0x20, DEF_STR( On ) )
1141
1142INPUT_PORTS_END
1143
1144
11101145static INPUT_PORTS_START( f1superb )   // Mostly wrong !
11111146   PORT_INCLUDE( ms32 )
11121147
r2821r2822
23552390GAME( 1996, kirarast, 0,        ms32, kirarast, kirarast,   ROT0,   "Jaleco", "Ryuusei Janshi Kirara Star", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
23562391GAME( 1997, tp2m32,   tetrisp2, ms32, tp2m32,   ss91022_10, ROT0,   "Jaleco", "Tetris Plus 2 (MegaSystem 32 Version)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
23572392GAME( 1997, bnstars,  bnstars1, ms32, 47pie2,   bnstars,    ROT0,   "Jaleco", "Vs. Janshi Brandnew Stars (MegaSystem32 Version)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
2358GAME( 1996, wpksocv2, 0,        ms32, ms32,     ss92046_01, ROT0,   "Jaleco", "World PK Soccer V2 (ver 1.1)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE | GAME_NOT_WORKING ) // custom IO board not emulated
2393GAME( 1996, wpksocv2, 0,        ms32, wpksocv2, ss92046_01, ROT0,   "Jaleco", "World PK Soccer V2 (ver 1.1)", GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
23592394
23602395
23612396/* these boot and show something */
src/mame/drivers/20pacgal.c
r2821r2822
165165   state->game_selected = data & 1;
166166
167167   if (state->game_selected == 0)
168      memcpy(memory_region(REGION_CPU1)+0x48000, memory_region(REGION_CPU1)+0x8000, 0x2000);
168   {
169      UINT8 *rom = memory_region(REGION_CPU1);
170      memcpy(rom+0x48000, rom+0x8000, 0x2000);
171   }
169172}
170173
171174
src/mame/drivers/mcr3.c
r2821r2822
874874   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Oil Slick")
875875   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("Missiles")
876876   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Weapon Truck")
877   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 )
878877   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Smoke Screen")
879878   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Machine Guns")
880879   PORT_BIT( 0x60, IP_ACTIVE_HIGH, IPT_SPECIAL )   /* status from CS deluxe, never read */
r2821r2822
953952
954953   PORT_START_TAG("SSIO.IP1")   /* J4 10-13,15-18 */
955954   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Left Button")
956   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
957955   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("Left Trigger")
958956   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Center Button")
959957   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Right Button")
src/mame/drivers/actfancr.c
r2821r2822
4747
4848static READ8_HANDLER( actfan_control_0_r )
4949{
50   return input_port_read_indexed(machine, 2); /* VBL */
50   return input_port_read(machine, "IN2"); /* VBL */
5151}
5252
5353static READ8_HANDLER( actfan_control_1_r )
5454{
5555   switch (offset) {
56      case 0: return input_port_read_indexed(machine, 0); /* Player 1 */
57      case 1: return input_port_read_indexed(machine, 1); /* Player 2 */
58      case 2: return input_port_read_indexed(machine, 3); /* Dip 1 */
59      case 3: return input_port_read_indexed(machine, 4); /* Dip 2 */
56      case 0: return input_port_read(machine, "IN0"); /* Player 1 */
57      case 1: return input_port_read(machine, "IN1"); /* Player 2 */
58      case 2: return input_port_read(machine, "DSW1"); /* Dip 1 */
59      case 3: return input_port_read(machine, "DSW2"); /* Dip 2 */
6060   }
6161   return 0xff;
6262}
src/mame/drivers/tank8.c
r2821r2822
9090
9191static WRITE8_HANDLER( tank8_motor_w )
9292{
93   discrete_sound_w(machine, TANK8_MOTOR1_EN+offset, data);
93   discrete_sound_w(machine, NODE_RELATIVE(TANK8_MOTOR1_EN, offset), data);
9494}
9595
9696static ADDRESS_MAP_START( tank8_cpu_map, ADDRESS_SPACE_PROGRAM, 8 )
src/mame/drivers/viper.c
r2821r2822
610610/*****************************************************************************/
611611
612612
613static INPUT_PORTS_START(viper)
614613
615INPUT_PORTS_END
616
617static const ppc_config viper_ppc_cfg =
614static const powerpc_config viper_ppc_cfg =
618615{
619   PPC_MODEL_MPC8240,
620   0x30,
621   BUS_FREQUENCY_66MHZ
616   66000000
622617};
623618
624619static INTERRUPT_GEN(viper_vblank)
r2821r2822
10181013/*****************************************************************************/
10191014
10201015/* Viper BIOS */
1021GAME(1999, kviper,   0, viper, viper, viper, ROT0, "Konami", "Konami Viper BIOS", GAME_IS_BIOS_ROOT)
1016GAME(1999, kviper,   0,       viper, 0, viper,    ROT0, "Konami", "Konami Viper BIOS", GAME_IS_BIOS_ROOT)
10221017
1023GAME(2001, ppp2nd,   kviper, viper, viper, ppp2nd,   ROT0,  "Konami", "ParaParaParadise 2nd Mix", GAME_NOT_WORKING|GAME_NO_SOUND)
1018GAME(2001, ppp2nd,   kviper, viper, 0, ppp2nd,   ROT0,  "Konami", "ParaParaParadise 2nd Mix", GAME_NOT_WORKING|GAME_NO_SOUND)
10241019
1025GAME(2001, boxingm,  kviper, viper, viper, vipercf,  ROT0,  "Konami", "Boxing Mania", GAME_NOT_WORKING|GAME_NO_SOUND)
1026GAME(2000, code1d,   kviper, viper, viper, vipercf,  ROT0,  "Konami", "Code One Dispatch", GAME_NOT_WORKING|GAME_NO_SOUND)
1027GAME(2000, code1db,  code1d, viper, viper, vipercf,  ROT0,  "Konami", "Code One Dispatch (ver B)", GAME_NOT_WORKING|GAME_NO_SOUND)
1028GAME(2001, gticlub2, kviper, viper, viper, vipercf,  ROT0,  "Konami", "GTI Club 2", GAME_NOT_WORKING|GAME_NO_SOUND)
1029GAME(2001, jpark3,   kviper, viper, viper, vipercf,  ROT0,  "Konami", "Jurassic Park 3", GAME_NOT_WORKING|GAME_NO_SOUND)
1030GAME(2001, mocapglf, kviper, viper, viper, vipercf,  ROT0,  "Konami", "Mocap Golf", GAME_NOT_WORKING|GAME_NO_SOUND)
1031GAME(2001, mocapb,   kviper, viper, viper, vipercf,  ROT0,  "Konami", "Mocap Boxing (ver AAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1032GAME(2001, mocapbj,  mocapb, viper, viper, vipercf,  ROT0,  "Konami", "Mocap Boxing (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1033GAME(2001, p911,     kviper, viper, viper, vipercf,  ROT0,  "Konami", "Police 911", GAME_NOT_WORKING|GAME_NO_SOUND)
1034GAME(2001, p911uc,   p911, viper, viper, vipercf,  ROT0,  "Konami", "Police 911 (ver UAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
1035GAME(2001, p911e,    p911, viper, viper, vipercf,  ROT0,  "Konami", "Police 24/7 (ver EAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1036GAME(2001, p911j,    p911, viper, viper, vipercf,  ROT0,  "Konami", "Keisatsukan Shinjuku 24ji (ver JAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
1037GAME(2001, p9112,    kviper, viper, viper, vipercf,  ROT0,  "Konami", "Police 911 2", GAME_NOT_WORKING|GAME_NO_SOUND)
1038GAME(2003, popn9,    kviper, viper, viper, vipercf,  ROT0,  "Konami", "Pop'n Music 9", GAME_NOT_WORKING|GAME_NO_SOUND)
1039GAME(2001, sscopex,  kviper, viper, viper, vipercf,  ROT0,  "Konami", "Silent Scope EX (ver UAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1040GAME(2001, sogeki,   sscopex, viper, viper, vipercf,  ROT0,  "Konami", "Sogeki (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1041GAME(2001, thrild2,  kviper, viper, viper, vipercf,  ROT0,  "Konami", "Thrill Drive 2", GAME_NOT_WORKING|GAME_NO_SOUND)
1042GAME(2001, thrild2a, thrild2, viper, viper, vipercf,  ROT0,  "Konami", "Thrill Drive 2 (ver A)", GAME_NOT_WORKING|GAME_NO_SOUND)
1043GAME(2001, tsurugi,  kviper, viper, viper, vipercf,  ROT0,  "Konami", "Tsurugi (ver EAB)", GAME_NOT_WORKING|GAME_NO_SOUND)
1044GAME(2001, tsurugij, tsurugi, viper, viper, vipercf,  ROT0,  "Konami", "Tsurugi (ver JAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
1045GAME(2002, wcombat,  kviper, viper, viper, vipercf,  ROT0,  "Konami", "World Combat", GAME_NOT_WORKING|GAME_NO_SOUND)
1046GAME(2002, wcombak,  wcombat, viper, viper, vipercf,  ROT0,  "Konami", "World Combat (ver KBC)", GAME_NOT_WORKING|GAME_NO_SOUND)
1047GAME(2002, wcombaj,  wcombat, viper, viper, vipercf,  ROT0,  "Konami", "World Combat (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1048GAME(2002, xtrial,   kviper, viper, viper, vipercf,  ROT0,  "Konami", "Xtrial Racing", GAME_NOT_WORKING|GAME_NO_SOUND)
1020GAME(2001, boxingm,  kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Boxing Mania", GAME_NOT_WORKING|GAME_NO_SOUND)
1021GAME(2000, code1d,   kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Code One Dispatch", GAME_NOT_WORKING|GAME_NO_SOUND)
1022GAME(2000, code1db,  code1d,  viper, 0, vipercf,  ROT0,  "Konami", "Code One Dispatch (ver B)", GAME_NOT_WORKING|GAME_NO_SOUND)
1023GAME(2001, gticlub2, kviper,  viper, 0, vipercf,  ROT0,  "Konami", "GTI Club 2", GAME_NOT_WORKING|GAME_NO_SOUND)
1024GAME(2001, jpark3,   kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Jurassic Park 3", GAME_NOT_WORKING|GAME_NO_SOUND)
1025GAME(2001, mocapglf, kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Mocap Golf", GAME_NOT_WORKING|GAME_NO_SOUND)
1026GAME(2001, mocapb,   kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Mocap Boxing (ver AAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1027GAME(2001, mocapbj,  mocapb,  viper, 0, vipercf,  ROT0,  "Konami", "Mocap Boxing (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1028GAME(2001, p911,     kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Police 911", GAME_NOT_WORKING|GAME_NO_SOUND)
1029GAME(2001, p911uc,   p911,    viper, 0, vipercf,  ROT0,  "Konami", "Police 911 (ver UAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
1030GAME(2001, p911e,    p911,    viper, 0, vipercf,  ROT0,  "Konami", "Police 24/7 (ver EAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1031GAME(2001, p911j,    p911,    viper, 0, vipercf,  ROT0,  "Konami", "Keisatsukan Shinjuku 24ji (ver JAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
1032GAME(2001, p9112,    kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Police 911 2", GAME_NOT_WORKING|GAME_NO_SOUND)
1033GAME(2003, popn9,    kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Pop'n Music 9", GAME_NOT_WORKING|GAME_NO_SOUND)
1034GAME(2001, sscopex,  kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Silent Scope EX (ver UAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1035GAME(2001, sogeki,   sscopex, viper, 0, vipercf,  ROT0,  "Konami", "Sogeki (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1036GAME(2001, thrild2,  kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Thrill Drive 2", GAME_NOT_WORKING|GAME_NO_SOUND)
1037GAME(2001, thrild2a, thrild2, viper, 0, vipercf,  ROT0,  "Konami", "Thrill Drive 2 (ver A)", GAME_NOT_WORKING|GAME_NO_SOUND)
1038GAME(2001, tsurugi,  kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Tsurugi (ver EAB)", GAME_NOT_WORKING|GAME_NO_SOUND)
1039GAME(2001, tsurugij, tsurugi, viper, 0, vipercf,  ROT0,  "Konami", "Tsurugi (ver JAC)", GAME_NOT_WORKING|GAME_NO_SOUND)
1040GAME(2002, wcombat,  kviper,  viper, 0, vipercf,  ROT0,  "Konami", "World Combat", GAME_NOT_WORKING|GAME_NO_SOUND)
1041GAME(2002, wcombak,  wcombat, viper, 0, vipercf,  ROT0,  "Konami", "World Combat (ver KBC)", GAME_NOT_WORKING|GAME_NO_SOUND)
1042GAME(2002, wcombaj,  wcombat, viper, 0, vipercf,  ROT0,  "Konami", "World Combat (ver JAA)", GAME_NOT_WORKING|GAME_NO_SOUND)
1043GAME(2002, xtrial,   kviper,  viper, 0, vipercf,  ROT0,  "Konami", "Xtrial Racing", GAME_NOT_WORKING|GAME_NO_SOUND)
10491044
1050GAME(2002, mfightc,  kviper, viper, viper, vipercf,  ROT0,  "Konami", "Mahjong Fight Club (ver D)", GAME_NOT_WORKING|GAME_NO_SOUND)
1051GAME(2002, mfightcc, mfightc, viper, viper, vipercf,  ROT0,  "Konami", "Mahjong Fight Club (ver C)", GAME_NOT_WORKING|GAME_NO_SOUND)
1045GAME(2002, mfightc,  kviper, viper,  0, vipercf,  ROT0,  "Konami", "Mahjong Fight Club (ver D)", GAME_NOT_WORKING|GAME_NO_SOUND)
1046GAME(2002, mfightcc, mfightc, viper, 0, vipercf,  ROT0,  "Konami", "Mahjong Fight Club (ver C)", GAME_NOT_WORKING|GAME_NO_SOUND)
src/mame/drivers/mw8080bw.c
r2821r2822
19481948   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
19491949   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 )
19501950   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 )
1951   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
1951   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
19521952   PORT_BIT( 0x70, 0x30, IPT_POSITIONAL_V ) PORT_POSITIONS(7) PORT_REMAP_TABLE(dogpatch_controller_table) PORT_SENSITIVITY(5) PORT_KEYDELTA(10) PORT_CODE_DEC(KEYCODE_M) PORT_CODE_INC(KEYCODE_J) PORT_CENTERDELTA(0) PORT_REVERSE PORT_PLAYER(2)
19531953   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
19541954
r2821r2822
19561956   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
19571957   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
19581958   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
1959   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
1959   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
19601960   PORT_BIT( 0x70, 0x30, IPT_POSITIONAL_V ) PORT_POSITIONS(7) PORT_REMAP_TABLE(dogpatch_controller_table) PORT_SENSITIVITY(5) PORT_KEYDELTA(10) PORT_CODE_DEC(KEYCODE_N) PORT_CODE_INC(KEYCODE_H) PORT_CENTERDELTA(0) PORT_PLAYER(1)
19611961   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
19621962
src/mame/drivers/btime.c
r2821r2822
504504   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
505505   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL
506506   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_COCKTAIL
507   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
508507   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
509508   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
510509
r2821r2822
902901   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_VBLANK  )
903902
904903   PORT_START_TAG("DSW2")
905   PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNKNOWN )
906904   PORT_DIPNAME( 0x01, 0x01, DEF_STR( Lives ) )
907905   PORT_DIPSETTING(    0x01, "3" )
908906   PORT_DIPSETTING(    0x00, "5" )
r2821r2822
10581056   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_VBLANK  )
10591057
10601058   PORT_START_TAG("DSW2")
1061   PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNKNOWN )
10621059   PORT_DIPNAME( 0x01, 0x01, DEF_STR( Lives ) )
10631060   PORT_DIPSETTING(    0x00, "1" )
10641061   PORT_DIPSETTING(    0x01, "2" )
src/mame/drivers/scobra.c
r2821r2822
749749/* cocktail mode is N/A */
750750static INPUT_PORTS_START( darkplnt )
751751   PORT_START_TAG("IN0")
752   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )
753   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 )
754   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON3 )
755   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 )
756   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 )
752   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 )
753   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 )   // and START1
754   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 )   // and START2
757755   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
758756   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
759757   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
src/mame/drivers/lethalj.c
r2821r2822
284284   PORT_DIPSETTING(      0x0400, DEF_STR( Easy ) )
285285   PORT_DIPSETTING(      0x0800, DEF_STR( Medium ) )
286286   PORT_DIPSETTING(      0x0000, DEF_STR( Hard ) )
287   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_UNUSED )
288287   PORT_BIT( 0xe000, IP_ACTIVE_LOW, IPT_UNUSED )
289288
290289   PORT_START
r2821r2822
425424   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE1 )
426425   PORT_SERVICE_NO_TOGGLE( 0x0002, IP_ACTIVE_HIGH )
427426   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_COIN1 )
428   PORT_BIT( 0x0018, IP_ACTIVE_LOW, IPT_UNUSED )
427   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
429428    PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
430429    PORT_DIPSETTING(      0x0010, DEF_STR( Off ) )
431430    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
src/mame/drivers/itech8.c
r2821r2822
10881088INPUT_PORTS_END
10891089
10901090
1091static CUSTOM_INPUT( gtg_mux )
1092{
1093   const char *tag1 = param;
1094   const char *tag2 = tag1 + strlen(tag1) + 1;
1095   return input_port_read(field->port->machine, tag1) & input_port_read(field->port->machine, tag2);
1096}
1097
10911098static INPUT_PORTS_START( gtg )
10921099   PORT_START   /* 40 */
10931100   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL )   /* input from sound board */
r2821r2822
11011108   PORT_START   /* 60 */
11021109   /* it is still unknown how the second player inputs are muxed in */
11031110   /* currently we map both sets of controls to the same inputs */
1104   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
1105   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_COCKTAIL PORT_PLAYER(2)
1106   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
1107   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL PORT_PLAYER(2)
1108   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
1109   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_PLAYER(2)
1110   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
1111   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_PLAYER(2)
1112   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Swing") PORT_PLAYER(1)
1113   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 Swing") PORT_COCKTAIL PORT_PLAYER(2)
1111   PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(gtg_mux, "P1\0P2")
11141112   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
11151113   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
11161114   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
r2821r2822
11221120   UNUSED_ANALOG   /* analog D */
11231121   UNUSED_ANALOG   /* analog E */
11241122   UNUSED_ANALOG   /* analog F */
1123
1124   PORT_START_TAG("P1")
1125   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
1126   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
1127   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
1128   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
1129   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Swing") PORT_PLAYER(1)
1130
1131   PORT_START_TAG("P2")
1132   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_COCKTAIL PORT_PLAYER(2)
1133   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL PORT_PLAYER(2)
1134   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL PORT_PLAYER(2)
1135   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL PORT_PLAYER(2)
1136   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 Swing") PORT_COCKTAIL PORT_PLAYER(2)
11251137INPUT_PORTS_END
11261138
11271139
src/mame/drivers/snk.c
r2821r2822
35423542   BERMWW_COMMON
35433543
35443544   PORT_START_TAG("DSW2")
3545   PORT_DIPNAME( 0x01, 0x00, DEF_STR( Allow_Continue ) )
3546   PORT_DIPSETTING(    0x01, DEF_STR( No ) )
3547   PORT_DIPSETTING(    0x00, DEF_STR( Yes ) )
35483545   PORT_DIPNAME( 0x03, 0x02, DEF_STR( Difficulty ) )
35493546   PORT_DIPSETTING(    0x03, DEF_STR( Easy ) )
35503547   PORT_DIPSETTING(    0x02, DEF_STR( Normal ) )
src/mame/drivers/hyprduel.c
r2821r2822
802802
803803static DRIVER_INIT( hyprduel )
804804{
805   int i;
805   int i, len = memory_region_length(REGION_GFX1);
806806   UINT8 *ROM = memory_region(REGION_GFX1);
807807
808808   /*
r2821r2822
811811      tilemap.c handle that, we invert gfx data so the transparent pen becomes 0
812812      for both tile depths.
813813    */
814   for (i = 0;i < memory_region_length(REGION_GFX1);i++)
814   for (i = 0;i < len;i++)
815815      ROM[i] ^= 0xff;
816816
817817//  ROM[(0x174b9*0x20)+0x1f] |= 0x0e;       /* I */
src/mame/drivers/calomega.c
r2821r2822
549549//  PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Bit 3") PORT_CODE(KEYCODE_F)
550550//  PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Bit 4") PORT_CODE(KEYCODE_G)
551551//  PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Bit 5") PORT_CODE(KEYCODE_H)
552   PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Test Mode") PORT_CODE(KEYCODE_F2)   /* should be splitted? */
553   PORT_BIT( 0x14, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Hopper SW") PORT_CODE(KEYCODE_9)   /* should be splitted? */
554   PORT_BIT( 0x24, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Show Stats") PORT_CODE(KEYCODE_0)   /* should be splitted? */
552   PORT_BIT( 0x08/*0x0c*/, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Test Mode") PORT_CODE(KEYCODE_F2)   /* should be splitted? */
553   PORT_BIT( 0x10/*0x14*/, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Hopper SW") PORT_CODE(KEYCODE_9)   /* should be splitted? */
554   PORT_BIT( 0x20/*0x24*/, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Show Stats") PORT_CODE(KEYCODE_0)   /* should be splitted? */
555555   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
556556   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
557557
r2821r2822
619619//  PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Bit 3") PORT_CODE(KEYCODE_F)
620620//  PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Bit 4") PORT_CODE(KEYCODE_G)
621621//  PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Bit 5") PORT_CODE(KEYCODE_H)
622   PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Unk.")   PORT_CODE(KEYCODE_8)   /* should be splitted? */
623   PORT_BIT( 0x14, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Hopper SW") PORT_CODE(KEYCODE_9)   /* should be splitted? */
624   PORT_BIT( 0x24, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Test Mode") PORT_CODE(KEYCODE_F2)   /* should be splitted? */
622   PORT_BIT( 0x08/*0x0c*/, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Unk.")   PORT_CODE(KEYCODE_8)   /* should be splitted? */
623   PORT_BIT( 0x10/*0x14*/, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Hopper SW") PORT_CODE(KEYCODE_9)   /* should be splitted? */
624   PORT_BIT( 0x20/*0x24*/, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Test Mode") PORT_CODE(KEYCODE_F2)   /* should be splitted? */
625625   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
626626   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
627627
r2821r2822
18681868   ROM_REGION( 0x1800, REGION_GFX2, ROMREGION_DISPOSE )
18691869   ROM_LOAD( "d1.u70",   0x0000, 0x0800, CRC(4f12d424) SHA1(c43f1df757ac7dd76875245e73d47451d1f7f6f2) )
18701870   ROM_LOAD( "d1.u69",   0x0800, 0x0800, CRC(ed3c83b7) SHA1(93e2134de3d9f79a6cff0391c1a32fccd3840c3f) )
1871   ROM_LOAD( "d1.u68",   0x1000, 0x0800, BAD_DUMP CRC(3ab70570) SHA1(5ff84015a78d15a5207499f84ce637e49bca136f) ) /* bad bits */
1871   ROM_LOAD( "d1.u68",   0x1000, 0x0800, BAD_DUMP CRC(81d07f12) SHA1(c14226f8bc1d08fcdfc5cb71fcaf6e070fa2d4a8) ) /* some bad bits */
18721872
18731873   ROM_REGION( 0x400, REGION_PROMS, 0 )
1874   ROM_LOAD( "d1.u28",      0x0000, 0x0200, CRC(a6d43709) SHA1(cbff2cb60137462dc0b7c7719a64574218d96c62) )
1875   ROM_RELOAD(            0x0200, 0x0200 )
1874   ROM_LOAD( "d1.u28",      0x0000, 0x0100, CRC(a26a8fae) SHA1(d570fe9443a0912bd34b81ac4c3e4c5f8901f523) )
1875   ROM_RELOAD(            0x0100, 0x0100 )
1876   ROM_RELOAD(            0x0200, 0x0100 )
1877   ROM_RELOAD(            0x0300, 0x0100 )
18761878ROM_END
18771879
18781880ROM_START( jjpoker )   /* tuni-83 */
r2821r2822
20212023{
20222024   int x;
20232025   UINT8 *BPR = memory_region( REGION_PROMS );
2024   UINT8 *ROM = memory_region( REGION_GFX2 );
20252026
20262027   /* Palette transformed by PLDs? */
20272028   for (x=0x0000;x<0x0400;x++)
r2821r2822
20302031         BPR[x] = 0x00; /* black background */
20312032   }
20322033
2033   /* Temporary patch to fix some bad bits in ROM d1.u68 till a correct dump appear */
2034   ROM[0x171c] = 0xff;
2035   ROM[0x171d] = 0xff;
2036   ROM[0x171e] = 0xff;
2037   ROM[0x1737] = 0xff;
2038   ROM[0x173d] = 0xff;
2039
20402034   /* Initializing PIAs... */
20412035   pia_config(0, &pia0_intf);
20422036   pia_config(1, &pia1_intf);
src/mame/drivers/dgpix.c
r2821r2822
257257   PORT_BIT( 0x00004000, IP_ACTIVE_LOW, IPT_UNUSED )
258258   PORT_BIT( 0x00008000, IP_ACTIVE_LOW, IPT_UNUSED )
259259   PORT_SERVICE_NO_TOGGLE( 0x00010000, IP_ACTIVE_LOW )
260   PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_UNUSED )
261260   PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_UNUSED )
262261   PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_SERVICE1 )
263262   PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_UNUSED )
src/mame/drivers/cosmic.c
r2821r2822
14601460{
14611461   /* Program ROMs have data pins connected different from normal */
14621462
1463   offs_t offs;
1463   offs_t offs, len;
1464   UINT8 *rom;
14641465
1465    for (offs =0; offs < memory_region_length(REGION_CPU1); offs++)
1466   {
1467        UINT8 scrambled = memory_region(REGION_CPU1)[offs];
1466    len = memory_region_length(REGION_CPU1);
1467    rom = memory_region(REGION_CPU1);
1468    for (offs =0; offs < len; offs++)
1469    {
1470        UINT8 scrambled = rom[offs];
14681471
14691472        UINT8 normal = (scrambled >> 3 & 0x11)
14701473                       | (scrambled >> 1 & 0x22)
14711474                       | (scrambled << 1 & 0x44)
14721475                       | (scrambled << 3 & 0x88);
14731476
1474        memory_region(REGION_CPU1)[offs] = normal;
1477        rom[offs] = normal;
14751478    }
14761479}
14771480
src/mame/drivers/model2.c
r2821r2822
16621662   // handle sample banking
16631663   if (memory_region_length(REGION_SOUND1) > 0x800000)
16641664   {
1665      UINT8 *snd = memory_region(REGION_SOUND1);
16651666      if (data & 0x20)
16661667      {
1667           memory_set_bankptr(4, memory_region(REGION_SOUND1) + 0x200000);
1668         memory_set_bankptr(5, memory_region(REGION_SOUND1) + 0x600000);
1668           memory_set_bankptr(4, snd + 0x200000);
1669         memory_set_bankptr(5, snd + 0x600000);
16691670      }
16701671      else
16711672      {
1672         memory_set_bankptr(4, memory_region(REGION_SOUND1) + 0x800000);
1673         memory_set_bankptr(5, memory_region(REGION_SOUND1) + 0xa00000);
1673         memory_set_bankptr(4, snd + 0x800000);
1674         memory_set_bankptr(5, snd + 0xa00000);
16741675      }
16751676   }
16761677}
src/mame/drivers/bmcbowl.c
r2821r2822
373373   PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Confirm") PORT_CODE(KEYCODE_N)
374374
375375
376   PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("Start")
377376   PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Start")
378377   PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Take") PORT_CODE(KEYCODE_A)
379378   PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("HP") PORT_CODE(KEYCODE_S)
src/mame/drivers/gstream.c
r2821r2822
232232   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_COIN1 )
233233   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_START1 )
234234   PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_SERVICE1 )
235   PORT_BIT( 0xe000, IP_ACTIVE_LOW, IPT_UNUSED )
235   PORT_BIT( 0x7000, IP_ACTIVE_LOW, IPT_UNUSED )
236236   PORT_SERVICE_NO_TOGGLE( 0x8000, IP_ACTIVE_LOW )
237237
238238   PORT_START
r2821r2822
248248   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_COIN2 )
249249   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_START2 )
250250   PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_SERVICE2 )
251   PORT_BIT( 0xe000, IP_ACTIVE_LOW, IPT_UNUSED )
251   PORT_BIT( 0x7000, IP_ACTIVE_LOW, IPT_UNUSED )
252252   PORT_SERVICE_NO_TOGGLE( 0x8000, IP_ACTIVE_LOW )
253253
254254   PORT_START
src/mame/drivers/hyperspt.c
r2821r2822
55***************************************************************************/
66
77#include "driver.h"
8#include "machine/konami1.h"
89#include "cpu/m6809/m6809.h"
910#include "sound/vlm5030.h"
1011#include "sound/dac.h"
1112
1213
13extern void konami1_decode(void);
14
1514extern UINT8 *hyperspt_scroll;
1615
1716extern WRITE8_HANDLER( hyperspt_videoram_w );
r2821r2822
592591
593592static DRIVER_INIT( hyperspt )
594593{
595   konami1_decode();
594   konami1_decode(0);
596595}
597596
598597
src/mame/drivers/tmnt.c
r2821r2822
20422042   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
20432043   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START2 )
20442044   PORT_SERVICE_NO_TOGGLE( 0x0400, IP_ACTIVE_LOW )
2045   PORT_DIPNAME( 0x8000, 0x0000, "Freeze" )   /* ?? VBLANK ?? */
2045   PORT_DIPNAME( 0x0800, 0x0000, "Freeze" )   /* ?? VBLANK ?? */
20462046   PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
2047   PORT_DIPSETTING(      0x8000, DEF_STR( On ) )
2047   PORT_DIPSETTING(      0x0800, DEF_STR( On ) )
20482048   PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Flip_Screen ) )
20492049   PORT_DIPSETTING(      0x1000, DEF_STR( Off ) )
20502050   PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
src/mame/drivers/raiden2.c
r2821r2822
21672167
21682168static DRIVER_INIT(rdx_v33)
21692169{
2170   memory_set_bankptr(1,&memory_region(REGION_CPU1)[0x020000]);
2171   memory_set_bankptr(2,&memory_region(REGION_CPU1)[0x030000]);
2172   memory_set_bankptr(3,&memory_region(REGION_CPU1)[0x040000]);
2173   memory_set_bankptr(4,&memory_region(REGION_CPU1)[0x050000]);
2174   memory_set_bankptr(5,&memory_region(REGION_CPU1)[0x060000]);
2175   memory_set_bankptr(6,&memory_region(REGION_CPU1)[0x070000]);
2176   memory_set_bankptr(7,&memory_region(REGION_CPU1)[0x080000]);
2177   memory_set_bankptr(8,&memory_region(REGION_CPU1)[0x090000]);
2178   memory_set_bankptr(9,&memory_region(REGION_CPU1)[0x0a0000]);
2179   memory_set_bankptr(10,&memory_region(REGION_CPU1)[0x0b0000]);
2180   memory_set_bankptr(11,&memory_region(REGION_CPU1)[0x0c0000]);
2181   memory_set_bankptr(12,&memory_region(REGION_CPU1)[0x0d0000]);
2182   memory_set_bankptr(13,&memory_region(REGION_CPU1)[0x0e0000]);
2183   memory_set_bankptr(14,&memory_region(REGION_CPU1)[0x0f0000]);
2170   UINT8 *prg = memory_region(REGION_CPU1);
2171   memory_set_bankptr(1,&prg[0x020000]);
2172   memory_set_bankptr(2,&prg[0x030000]);
2173   memory_set_bankptr(3,&prg[0x040000]);
2174   memory_set_bankptr(4,&prg[0x050000]);
2175   memory_set_bankptr(5,&prg[0x060000]);
2176   memory_set_bankptr(6,&prg[0x070000]);
2177   memory_set_bankptr(7,&prg[0x080000]);
2178   memory_set_bankptr(8,&prg[0x090000]);
2179   memory_set_bankptr(9,&prg[0x0a0000]);
2180   memory_set_bankptr(10,&prg[0x0b0000]);
2181   memory_set_bankptr(11,&prg[0x0c0000]);
2182   memory_set_bankptr(12,&prg[0x0d0000]);
2183   memory_set_bankptr(13,&prg[0x0e0000]);
2184   memory_set_bankptr(14,&prg[0x0f0000]);
21842185
21852186   raiden2_decrypt_sprites();
21862187}
src/mame/drivers/ampoker2.c
r2821r2822
9494    The rest of Sigma poker games (2001 onwards) were developed for B-52 mainboards.
9595    (2x 6809; HD63484 video controller).
9696
97    Sigma 2000 has better graphics and use 4 times more tiles than other games running
97
98    Sigma Poker 2000:
99
100    This game has better graphics and use 4 times more tiles than other games running
98101    on this hardware. To manage this, the game use 2 extra bits from the color RAM.
99102
103    To init the game:
100104
105    1) Turn ON the Supervisor Key (0).
106    2) Press HOLD5 3 times to enter into page 4 (setup) of the supervisor menu.
107    3) Press HOLD3 to navegate between options, and highlight "Clear All Informations"
108    4) Keep pressed HOLD1 for more than 3 seconds.
109    5) Turn OFF the Supervisor Key (0).
101110
111
102112*********************************************************************************
103113
104114
r2821r2822
266276    --- DRIVER UPDATES ---
267277
268278
279    [2008-06-02]
280
281    - Reworked the input system for Sigma Poker 2000.
282    - Promoted Sigma Poker 2000 to 'WORKING' state.
283    - Updated technical notes.
284
285
269286    [2008-05-23]
270287
271288    - Reworked the color routines switching to resnet system.
r2821r2822
836853   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Clear Credits") PORT_CODE(KEYCODE_4)
837854INPUT_PORTS_END
838855
856static INPUT_PORTS_START( sigma2k )
857   PORT_START_TAG("IN0")
858   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
859   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
860   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
861   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
862   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
863   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
864   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
865   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
866   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
867   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
839868
869   PORT_START_TAG("IN1")
870   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
871   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Hold 1") PORT_CODE(KEYCODE_Z)
872   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Operator Key") PORT_TOGGLE PORT_CODE(KEYCODE_9)
873   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
874   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
875   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
876   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("Hold 4") PORT_CODE(KEYCODE_V)
877   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
878   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
879   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
880
881   PORT_START_TAG("IN2")
882   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
883   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
884   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
885   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
886   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
887   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
888   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
889   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
890   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
891   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
892
893   PORT_START_TAG("IN3")
894   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
895   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
896   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Supervisor Key") PORT_TOGGLE PORT_CODE(KEYCODE_0)
897   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
898   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
899   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
900   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Half Gamble") PORT_CODE(KEYCODE_S)
901   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
902   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
903   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
904
905   PORT_START_TAG("IN4")
906   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
907   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
908   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("Hold 2") PORT_CODE(KEYCODE_X)
909   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
910   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
911   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
912   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Deal / Take") PORT_CODE(KEYCODE_1)
913   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
914   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
915   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
916
917   PORT_START_TAG("IN5")
918   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
919   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
920   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
921   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
922   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
923   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
924   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("Hold 3") PORT_CODE(KEYCODE_C)
925   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
926   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
927   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
928
929   PORT_START_TAG("IN6")
930   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
931   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Bet") PORT_CODE(KEYCODE_A)
932   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("Hold 5") PORT_CODE(KEYCODE_B)
933   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
934   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
935   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
936   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
937   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
938   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
939   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
940
941   PORT_START_TAG("IN7")
942   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
943   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Credits IN") PORT_CODE(KEYCODE_5)
944   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
945   PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
946   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
947   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
948   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Clear Credits") PORT_CODE(KEYCODE_M)
949   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
950   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
951   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
952INPUT_PORTS_END
953
954
840955/*************************
841956*    Graphics Layouts    *
842957*************************/
r2821r2822
10391154*      Game Drivers      *
10401155*************************/
10411156
1042/*     YEAR  NAME      PARENT    MACHINE   INPUT     INIT  ROT    COMPANY       FULLNAME                             FLAGS             LAYOUT      */
1043GAMEL( 1990, ampoker2, 0,        ampoker2, ampoker2, 0,    ROT0, "Novomatic",  "American Poker II",                  0,                layout_ampoker2 )
1044GAMEL( 1990, ampkr2b1, ampoker2, ampoker2, ampoker2, 0,    ROT0, "Bootleg",    "American Poker II (bootleg, set 1)", 0,                layout_ampoker2 )
1045GAMEL( 1990, ampkr2b2, ampoker2, ampoker2, ampoker2, 0,    ROT0, "Bootleg",    "American Poker II (bootleg, set 2)", 0,                layout_ampoker2 )
1046GAMEL( 1994, ampkr2b3, ampoker2, ampoker2, ampoker2, 0,    ROT0, "Bootleg",    "American Poker II (bootleg, set 3)", 0,                layout_ampoker2 )
1047GAMEL( 1995, ampkr95,  ampoker2, ampoker2, ampkr95,  0,    ROT0, "Bootleg",    "American Poker 95",                  0,                layout_ampoker2 )
1048GAMEL( 1990, pkrdewin, ampoker2, ampoker2, ampoker2, 0,    ROT0, "Bootleg",    "Poker De Win",                       0,                layout_ampoker2 )
1049GAMEL( 1995, sigmapkr, 0,        ampoker2, sigmapkr, 0,    ROT0, "Sigma Inc.", "Sigma Poker",                        0,                layout_sigmapkr )
1050GAMEL( 1998, sigma2k,  0,        sigma2k,  sigmapkr, 0,    ROT0, "Sigma Inc.", "Sigma Poker 2000",                   GAME_NOT_WORKING, layout_sigmapkr )
1157/*     YEAR  NAME      PARENT    MACHINE   INPUT     INIT  ROT    COMPANY       FULLNAME                             FLAGS  LAYOUT      */
1158GAMEL( 1990, ampoker2, 0,        ampoker2, ampoker2, 0,    ROT0, "Novomatic",  "American Poker II",                  0,     layout_ampoker2 )
1159GAMEL( 1990, ampkr2b1, ampoker2, ampoker2, ampoker2, 0,    ROT0, "Bootleg",    "American Poker II (bootleg, set 1)", 0,     layout_ampoker2 )
1160GAMEL( 1990, ampkr2b2, ampoker2, ampoker2, ampoker2, 0,    ROT0, "Bootleg",    "American Poker II (bootleg, set 2)", 0,     layout_ampoker2 )
1161GAMEL( 1994, ampkr2b3, ampoker2, ampoker2, ampoker2, 0,    ROT0, "Bootleg",    "American Poker II (bootleg, set 3)", 0,     layout_ampoker2 )
1162GAMEL( 1995, ampkr95,  ampoker2, ampoker2, ampkr95,  0,    ROT0, "Bootleg",    "American Poker 95",                  0,     layout_ampoker2 )
1163GAMEL( 1990, pkrdewin, ampoker2, ampoker2, ampoker2, 0,    ROT0, "Bootleg",    "Poker De Win",                       0,     layout_ampoker2 )
1164GAMEL( 1995, sigmapkr, 0,        ampoker2, sigmapkr, 0,    ROT0, "Sigma Inc.", "Sigma Poker",                        0,     layout_sigmapkr )
1165GAMEL( 1998, sigma2k,  0,        sigma2k,  sigma2k,  0,    ROT0, "Sigma Inc.", "Sigma Poker 2000",                   0,     layout_sigmapkr )
src/mame/drivers/dynadice.c
r2821r2822
250250static DRIVER_INIT( dynadice )
251251{
252252   int i,j;
253   memory_region(REGION_CPU2)[0x0b]=0x23;   /* bug in game code  Dec HL -> Inc HL*/
253   UINT8 *usr1 = memory_region(REGION_USER1);
254   UINT8 *cpu2 = memory_region(REGION_CPU2);
255   UINT8 *gfx1 = memory_region(REGION_GFX1);
256   UINT8 *gfx2 = memory_region(REGION_GFX2);
254257
258   cpu2[0x0b]=0x23;   /* bug in game code  Dec HL -> Inc HL*/
259
255260   /* 1bpp tiles -> 3bpp tiles (dy_5.bin  contains bg/fg color data for each tile line) */
256261   for(i=0;i<0x800;i++)
257262      for(j=0;j<8;j++)
258         memory_region(REGION_GFX2)[(i<<3)+j]=(memory_region(REGION_GFX1)[i]&(0x80>>j))?(memory_region(REGION_USER1)[i]&7):(memory_region(REGION_USER1)[i]>>4);
263         gfx2[(i<<3)+j]=(gfx1[i]&(0x80>>j))?(usr1[i]&7):(usr1[i]>>4);
259264
260265}
261266
src/mame/drivers/playmark.c
r2821r2822
645645   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
646646   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
647647   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
648   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
649   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
650648   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
651649   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )
652650   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
src/mame/drivers/model3.c
r2821r2822
365365#include "machine/53c810.h"
366366#include "sound/scsp.h"
367367
368static int model3_irq_enable;
369int model3_irq_state;
368static UINT8 irq_enable;
369static UINT8 irq_state;
370static UINT8 scsi_irq_state;
371
370372int model3_step;
371373UINT32 *model3_vrom;
372374
r2821r2822
412414
413415static UINT16 *model3_soundram;
414416
417
418static void update_irq_state(running_machine *machine)
419{
420   if ((irq_enable & irq_state) || scsi_irq_state)
421      cpunum_set_input_line(machine, 0, PPC_IRQ, ASSERT_LINE);
422   else
423      cpunum_set_input_line(machine, 0, PPC_IRQ, CLEAR_LINE);
424}
425
426void model3_set_irq_line(running_machine *machine, UINT8 bit, int state)
427{
428   if (state != CLEAR_LINE)
429      irq_state |= bit;
430   else
431      irq_state &= ~bit;
432   update_irq_state(machine);
433}
434
435
415436#define BYTE_REVERSE32(x)      (((x >> 24) & 0xff) | \
416437                        ((x >> 8) & 0xff00) | \
417438                        ((x << 8) & 0xff0000) | \
r2821r2822
787808   return BYTE_REVERSE32(result);
788809}
789810
790static void scsi_irq_callback(running_machine *machine)
811static void scsi_irq_callback(running_machine *machine, int state)
791812{
792   model3_irq_state |= model3_irq_enable & ~0x60;   /* FIXME: enable only SCSI interrupt */
793   cpunum_set_input_line(machine, 0, INPUT_LINE_IRQ1, ASSERT_LINE);
813   scsi_irq_state = state;
814//  model3_irq_state |= irq_enable & ~0x60; /* FIXME: enable only SCSI interrupt */
815   update_irq_state(machine);
794816}
795817
796818/*****************************************************************************/
r2821r2822
846868               real3d_dma_callback(dma_source, dma_dest, length, 1);
847869            }
848870            dma_irq |= 0x01;
849            scsi_irq_callback(machine);
871            scsi_irq_callback(machine, 1);
850872            return;
851873         }
852874         else if(ACCESSING_BITS_16_23)
853875         {
854876            if(data & 0x10000) {
855877               dma_irq &= ~0x1;
878               scsi_irq_callback(machine, 0);
856879            }
857880            return;
858881         }
r2821r2822
12361259         }
12371260         else if (ACCESSING_BITS_24_31)
12381261         {
1239            return (model3_irq_enable<<24);
1262            return (irq_enable<<24);
12401263         }
12411264         else logerror("m3_sys: Unk sys_r @ 0x10: mask = %x\n", (UINT32)mem_mask);
12421265         break;
12431266      case 0x18/8:
1244         return (UINT64)model3_irq_state<<56 | 0xff000000;
1267         return (UINT64)irq_state<<56 | 0xff000000;
12451268         break;
12461269   }
12471270
r2821r2822
12561279      case 0x10/8:
12571280         if (ACCESSING_BITS_24_31)
12581281         {
1259            model3_irq_enable = (data>>24)&0xff;
1282            irq_enable = (data>>24)&0xff;
12601283         }
12611284         else logerror("m3_sys: unknown mask on IRQen write\n");
12621285         break;
r2821r2822
13201343
13211344static WRITE64_HANDLER(model3_sound_w)
13221345{
1323   model3_irq_state &= ~0x40;
1346   model3_set_irq_line(machine, 0x40, CLEAR_LINE);
13241347
13251348   // serial configuration writes
13261349   if ((mem_mask == U64(0xff00000000000000)) && (offset == 0))
r2821r2822
15901613   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )   /* View Button 2 */
15911614   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 )   /* View Button 3 */
15921615   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 )   /* View Button 4 */
1593   PORT_BIT( 0x50, IP_ACTIVE_LOW, IPT_BUTTON5 )   /* Shift 1 */
1594   PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_BUTTON6 )   /* Shift 2 */
1616   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON5 )   /* Shift 1 */
1617   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON6 )   /* Shift 2 */
15951618   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON7 )   /* Shift 3 */
15961619   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON8 )   /* Shift 4 */
15971620
r2821r2822
16841707   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )   /* View Button 2 */
16851708   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 )   /* View Button 3 */
16861709   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 )   /* View Button 4 */
1687   PORT_BIT( 0x50, IP_ACTIVE_LOW, IPT_BUTTON5 )   /* Shift 1 */
1688   PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_BUTTON6 )   /* Shift 2 */
1710   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON5 )   /* Shift 1 */
1711   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON6 )   /* Shift 2 */
16891712   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON7 )   /* Shift 3 */
16901713   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON8 )   /* Shift 4 */
16911714
r2821r2822
17351758   PORT_START
17361759   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )   /* View Change */
17371760   PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED )
1738   PORT_BIT( 0x50, IP_ACTIVE_LOW, IPT_BUTTON2 )   /* Shift Up */
1739   PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_BUTTON3 )   /* Shift Down */
1761   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 )   /* Shift Up */
1762   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON3 )   /* Shift Down */
17401763
17411764   PORT_START
17421765   PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
39834006   // handle sample banking
39844007   if (memory_region_length(REGION_SOUND1) > 0x800000)
39854008   {
4009      UINT8 *snd = memory_region(REGION_SOUND1);
39864010      if (data & 0x20)
39874011      {
3988           memory_set_bankptr(4, memory_region(REGION_SOUND1) + 0x200000);
3989         memory_set_bankptr(5, memory_region(REGION_SOUND1) + 0x600000);
4012           memory_set_bankptr(4, snd + 0x200000);
4013         memory_set_bankptr(5, snd + 0x600000);
39904014      }
39914015      else
39924016      {
3993         memory_set_bankptr(4, memory_region(REGION_SOUND1) + 0x800000);
3994         memory_set_bankptr(5, memory_region(REGION_SOUND1) + 0xa00000);
4017         memory_set_bankptr(4, snd + 0x800000);
4018         memory_set_bankptr(5, snd + 0xa00000);
39954019      }
39964020   }
39974021}
r2821r2822
40354059
40364060/* IRQs */
40374061/*
4038    0x80: Unused ?
4062    0x80: Unknown (no clearing logic in scud)
40394063    0x40: SCSP
4040    0x20: Unused ?
4064    0x20: Unknown (no clearing logic in scud)
40414065    0x10: Network
4042    0x08: V-blank end ?
4043    0x04: ???
4044    0x02: V-blank start
4045    0x01: Unused ?
4066    0x08: Video (unknown -- has callback hook in scud)
4067    0x04: Video (unknown -- has callback hook in scud)
4068    0x02: Video (VBLANK start?)
4069    0x01: Video (unused?)
40464070*/
40474071static int model3_vblank = 0;
40484072static INTERRUPT_GEN(model3_interrupt)
40494073{
40504074   if (model3_vblank == 0) {
4051      model3_irq_state = 0x42;
4075      model3_set_irq_line(machine, 0x42, ASSERT_LINE);
40524076   } else {
4053      model3_irq_state = 0x0d;
4077      model3_set_irq_line(machine, 0x0d, ASSERT_LINE);
40544078   }
4055   cpunum_set_input_line(machine, 0, INPUT_LINE_IRQ1, ASSERT_LINE);
40564079
40574080   model3_vblank++;
40584081   model3_vblank &= 1;
40594082}
40604083
4061static const ppc_config model3_10 =
4084static const powerpc_config model3_10 =
40624085{
4063   PPC_MODEL_603E,      /* 603e, Stretch, 1.3 */
4064   0x10,            /* Multiplier 1, Bus = 66MHz, Core = 66MHz */
4065   BUS_FREQUENCY_66MHZ
4086   /* 603e, Stretch, 1.3 */
4087   66000000      /* Multiplier 1, Bus = 66MHz, Core = 66MHz */
40664088};
40674089
4068static const ppc_config model3_15 =
4090static const powerpc_config model3_15 =
40694091{
4070   PPC_MODEL_603E,      /* 603e, Stretch, 1.3 */
4071   0x15,            /* Multiplier 1.5, Bus = 66MHz, Core = 100MHz */
4072   BUS_FREQUENCY_66MHZ
4092   /* 603e, Stretch, 1.3 */
4093   66000000      /* Multiplier 1.5, Bus = 66MHz, Core = 100MHz */
40734094};
40744095
4075static const ppc_config model3_2x =
4096static const powerpc_config model3_2x =
40764097{
4077   PPC_MODEL_603R,      /* 603e-PID7t, Goldeneye, 2.1 */
4078   0x25,            /* Multiplier 2.5, Bus = 66MHz, Core = 166MHz */
4079   BUS_FREQUENCY_66MHZ
4098   /* 603e-PID7t, Goldeneye, 2.1 */
4099   66000000      /* Multiplier 2.5, Bus = 66MHz, Core = 166MHz */
40804100};
40814101
40824102static MACHINE_DRIVER_START( model3_10 )
4083   MDRV_CPU_ADD(PPC603, 66000000)
4103   MDRV_CPU_ADD(PPC603E, 66000000)
40844104   MDRV_CPU_CONFIG(model3_10)
40854105   MDRV_CPU_PROGRAM_MAP(model3_mem, 0)
40864106    MDRV_CPU_VBLANK_INT_HACK(model3_interrupt,2)
r2821r2822
41204140MACHINE_DRIVER_END
41214141
41224142static MACHINE_DRIVER_START( model3_15 )
4123   MDRV_CPU_ADD(PPC603, 100000000)
4143   MDRV_CPU_ADD(PPC603E, 100000000)
41244144   MDRV_CPU_CONFIG(model3_15)
41254145   MDRV_CPU_PROGRAM_MAP(model3_mem, 0)
41264146    MDRV_CPU_VBLANK_INT_HACK(model3_interrupt,2)
r2821r2822
41584178MACHINE_DRIVER_END
41594179
41604180static MACHINE_DRIVER_START( model3_20 )
4161   MDRV_CPU_ADD(PPC603, 166000000)
4181   MDRV_CPU_ADD(PPC603R, 166000000)
41624182   MDRV_CPU_CONFIG(model3_2x)
41634183   MDRV_CPU_PROGRAM_MAP(model3_mem, 0)
41644184    MDRV_CPU_VBLANK_INT_HACK(model3_interrupt,2)
r2821r2822
41954215MACHINE_DRIVER_END
41964216
41974217static MACHINE_DRIVER_START( model3_21 )
4198   MDRV_CPU_ADD(PPC603, 166000000)
4218   MDRV_CPU_ADD(PPC603R, 166000000)
41994219   MDRV_CPU_CONFIG(model3_2x)
42004220   MDRV_CPU_PROGRAM_MAP(model3_mem, 0)
42014221    MDRV_CPU_VBLANK_INT_HACK(model3_interrupt,2)
src/mame/drivers/namcos21.c
r2821r2822
23362336/* "SCI - ? */
23372337static INPUT_PORTS_START( winrun )
23382338   PORT_START      /* 63B05Z0 - PORT B */
2339   PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
2339   PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED )
23402340   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 ) /* ? */
23412341   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 ) /* ? */
23422342   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) /* ? */
src/mame/drivers/pgm.c
r2821r2822
284284#include "deprecat.h"
285285#include "sound/ics2115.h"
286286#include "cpu/arm7/arm7core.h"
287#include "includes/pgm.h"
287288
288289
289290UINT16 *pgm_mainram, *pgm_bg_videoram, *pgm_tx_videoram, *pgm_videoregs, *pgm_rowscrollram;
290291static UINT8 *z80_mainram;
291292static UINT32 *arm7_shareram;
292293static UINT32 arm7_latch;
293WRITE16_HANDLER( pgm_tx_videoram_w );
294WRITE16_HANDLER( pgm_bg_videoram_w );
295VIDEO_START( pgm );
296VIDEO_EOF( pgm );
297VIDEO_UPDATE( pgm );
298void pgm_kov_decrypt(void);
299void pgm_kovsh_decrypt(void);
300void pgm_kov2_decrypt(void);
301void pgm_mm_decrypt(void);
302void pgm_dw2_decrypt(void);
303void pgm_djlzz_decrypt(void);
304void pgm_dw3_decrypt(void);
305void pgm_killbld_decrypt(void);
306void pgm_pstar_decrypt(void);
307void pgm_puzzli2_decrypt(void);
308294
309READ16_HANDLER( pgm_asic3_r );
310WRITE16_HANDLER( pgm_asic3_w );
311WRITE16_HANDLER( pgm_asic3_reg_w );
312295
313READ16_HANDLER (sango_protram_r);
314READ16_HANDLER (ASIC28_r16);
315WRITE16_HANDLER (ASIC28_w16);
316
317READ16_HANDLER (dw2_d80000_r );
318
319
320296static READ16_HANDLER ( z80_ram_r )
321297{
322298   return (z80_mainram[offset*2] << 8)|z80_mainram[offset*2+1];
src/mame/drivers/itgamble.c
r0r2822
1/******************************************************************
2
3  Nazionale Elettronica + others (mostly Italian) Gambling games
4  based on H8/3048 + OKI 6295 or similar.
5.
6  These all use MCUs with internal ROM for their programs,
7  they can't be dumped easily, and thus we can't emulate
8  them at the moment because there is nothing to emulate
9
10  This driver is just a placeholder for the graphic / sound
11  ROM loading
12
13*******************************************************************
14
15  --- Hardware Notes ---
16
17  The hardware is normally composed by:
18
19
20  CPU:   1x H8/3048 (HD64F3048F16).
21           (128KB ROM; 4KB RAM)
22
23  Sound: 1x AD-65 (OKI 6295)
24         1x TDA2003 (audio amplifier).
25
26  PLDs:  1x ispLSI2064-80LJ.
27
28  Clock: 1x Xtal 30.000 MHz.
29         1x Resonator ZTB1000J (1000 kHz) or similar.
30
31  ROMs:  1x (up to) 27C2001 or similar (sound).
32         2x or more 27C4001 or similar (graphics).
33
34  Timekeeping: 1x Dallas DS1302 Trickle Charge Timekeeping Chip (optional).
35
36  Connectors: 1x 28x2 edge connector.
37              1x 12 legs connector.
38              1x 24 legs female connector.
39              1x 50 legs flat cable connector.
40
41  Other: 1x battery.
42         2x 12 DIP switches.
43         2x trimmer.
44
45
46*******************************************************************/
47
48#define MAIN_CLOCK   XTAL_30MHz
49#define SND_CLOCK   XTAL_1MHz
50
51#include "driver.h"
52#include "cpu/h83002/h83002.h"
53#include "sound/okim6295.h"
54
55
56/*************************
57*     Video Hardware     *
58*************************/
59
60VIDEO_START( itgamble )
61{
62}
63
64VIDEO_UPDATE( itgamble )
65{
66   return 0;
67}
68
69
70/*************************
71* Memory map information *
72*************************/
73
74static ADDRESS_MAP_START( itgamble_map, ADDRESS_SPACE_PROGRAM, 16 )
75   ADDRESS_MAP_GLOBAL_MASK(0xffffff)
76   AM_RANGE(0x000000, 0xffffff) AM_ROM
77ADDRESS_MAP_END
78
79
80/*************************
81*      Input ports       *
82*************************/
83
84static INPUT_PORTS_START( itgamble )
85    PORT_START
86    PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) )
87    PORT_DIPSETTING(      0x0001, DEF_STR( Off ) )
88    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
89    PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
90    PORT_DIPSETTING(      0x0002, DEF_STR( Off ) )
91    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
92    PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
93    PORT_DIPSETTING(      0x0004, DEF_STR( Off ) )
94    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
95    PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) )
96    PORT_DIPSETTING(      0x0008, DEF_STR( Off ) )
97    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
98    PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
99    PORT_DIPSETTING(      0x0010, DEF_STR( Off ) )
100    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
101    PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
102    PORT_DIPSETTING(      0x0020, DEF_STR( Off ) )
103    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
104    PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
105    PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
106    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
107    PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
108    PORT_DIPSETTING(      0x0080, DEF_STR( Off ) )
109    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
110    PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
111    PORT_DIPSETTING(      0x0100, DEF_STR( Off ) )
112    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
113    PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
114    PORT_DIPSETTING(      0x0200, DEF_STR( Off ) )
115    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
116    PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
117    PORT_DIPSETTING(      0x0400, DEF_STR( Off ) )
118    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
119    PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
120    PORT_DIPSETTING(      0x0800, DEF_STR( Off ) )
121    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
122    PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
123    PORT_DIPSETTING(      0x1000, DEF_STR( Off ) )
124    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
125    PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
126    PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
127    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
128    PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
129    PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
130    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
131    PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
132    PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
133    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
134INPUT_PORTS_END
135
136
137/*************************
138*    Graphics Layouts    *
139*************************/
140
141static const gfx_layout gfxlayout_8x8x8 =
142{
143   8,8,
144   RGN_FRAC(1,1),
145   8,
146   { 0, 1, 2, 3, 4, 5, 6, 7 },
147   { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
148   { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 },
149   8*64
150};
151
152
153/******************************
154* Graphics Decode Information *
155******************************/
156
157static GFXDECODE_START( itgamble )
158    GFXDECODE_ENTRY( REGION_GFX1, 0, gfxlayout_8x8x8,   0, 16  )
159GFXDECODE_END
160
161
162/**************************
163*      Machine Reset      *
164**************************/
165
166MACHINE_RESET( itgamble )
167{
168   /* stop the CPU, we have no code for it anyway */
169   cpunum_set_input_line(machine, 0, INPUT_LINE_HALT, ASSERT_LINE);
170}
171
172
173/**************************
174*     Machine Drivers     *
175**************************/
176
177static MACHINE_DRIVER_START( itgamble )
178
179    /* basic machine hardware */
180   MDRV_CPU_ADD_TAG("main", H83044, MAIN_CLOCK/2)   /* probably the wrong CPU */
181   MDRV_CPU_PROGRAM_MAP(itgamble_map,0)
182
183    /* video hardware */
184   MDRV_SCREEN_ADD("main", RASTER)
185   MDRV_SCREEN_REFRESH_RATE(60)
186   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
187   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
188   MDRV_SCREEN_SIZE(512, 256)
189   MDRV_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1)
190   MDRV_MACHINE_RESET( itgamble )
191
192   MDRV_GFXDECODE(itgamble)
193   MDRV_PALETTE_LENGTH(0x200)
194   MDRV_VIDEO_START( itgamble )
195   MDRV_VIDEO_UPDATE( itgamble )
196
197    /* sound hardware */
198   MDRV_SPEAKER_STANDARD_MONO("mono")
199   MDRV_SOUND_ADD(OKIM6295, SND_CLOCK)   /* 1MHz resonator */
200   MDRV_SOUND_CONFIG(okim6295_interface_region_1_pin7high)
201   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
202MACHINE_DRIVER_END
203
204
205/*************************
206*        Rom Load        *
207*************************/
208
209/* Capitan Uncino (Ver 1.2)
210
211CPU:
212
2131x HD64F3048F16 (main)(ic1)
2141x ispLSI2064-80LJ (ic12)
2151x AD-65 (equivalent to M6295) (ic24)(sound)
2161x oscillator 30.00MHz (close to main)
2171x blu resonator 1000J (close to sound)
218
219ROMs:
220
2211x M27C2001 (1)
2222x M27C4001 (2,3)
223
224Note:
225
2261x 28x2 edge connector
2271x 12 legs connector
2281x 50 legs flat cable connector
2291x 12x2 jumpers
2301x trimmer (volume)
2311x trimmer (spark)
232
233--------------------
234
235PCB is labeled Ver 1.3, while EPROMs are labeled Ver 1.2
236
237*/
238
239ROM_START( capunc )
240   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
241   ROM_LOAD( "capunc.ver1.2.mcu", 0x00000, 0x4000, NO_DUMP )
242
243   ROM_REGION( 0x100000, REGION_GFX1, 0 )
244   ROM_LOAD( "2.ver.1.2.ic18", 0x000000, 0x80000, CRC(5030f7eb) SHA1(106b61c84e3647b8d68d6c30ee7e63ec2df1f5fd) )
245   ROM_LOAD( "3.ver.1.2.ic17", 0x080000, 0x80000, CRC(2b50e312) SHA1(dc901540a5e1a25fe6e7deb58b0fe01f116aaf63) )
246
247   ROM_REGION( 0x40000, REGION_SOUND1, 0 ) /* M6295 samples */
248   ROM_LOAD( "1.ic25", 0x00000, 0x40000, CRC(4fe79e43) SHA1(7c154cb00e9b64fbdcc218280f2183b816cef20b) )
249ROM_END
250
251
252/* Capitani Coraggiosi (Ver 1.3)
253
254CPU:
255
2561x HD64F3048F16 (main)(ic1)
2571x ispLSI2064-80LJ (ic12)
2581x AD-65 (equivalent to M6295) (ic24)(sound)
2591x oscillator 30MHz (close to main)
2601x orange resonator ZTB1000J (close to sound)
261
262ROMs:
263
2641x M27C2001 (1)
2652x M27C4001 (2,3)
266
267Note:
268
2691x 28x2 edge connector
2701x 12 legs connector
2711x 50 legs flat cable connector
2721x 12x2 switches dip
2731x trimmer (volume)
2741x trimmer (spark)
275
276
277The differences between this set and the alternate one, are only 4 bytes
278in the samples ROM header. Replaced the sound ROM with the clean one.
279
2803 and 3 files
2812.ic18                  2.ic18                  IDENTICAL
2823.ic17                  3.ic17                  IDENTICAL
2831.ic25                  1.ic25                  99.998474%
284
285*/
286
287ROM_START( capcor )
288   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
289   ROM_LOAD( "capcor.ver1.3.mcu", 0x00000, 0x4000, NO_DUMP )
290
291   ROM_REGION( 0x100000, REGION_GFX1, 0 )
292   ROM_LOAD( "2.ic18", 0x000000, 0x80000, CRC(342bea85) SHA1(885080a9b55d64f9a93e3d5e31e6b13f272bdb93) )
293   ROM_LOAD( "3.ic17", 0x080000, 0x80000, CRC(ac530eff) SHA1(7c3a6e322311a1cd93801639a0498d5947fb14f2) )
294
295   ROM_REGION( 0x40000, REGION_SOUND1, 0 ) /* M6295 samples */
296   ROM_LOAD( "1.ic25", 0x00000, 0x40000, CRC(4fe79e43) SHA1(7c154cb00e9b64fbdcc218280f2183b816cef20b) )
297ROM_END
298
299
300/* La Perla Nera (Ver 2.0)
301
302CPU:
303
3041x HD64F3048F16 (main)(ic1)
3051x ispLSI2064-80LJ (ic12)
3061x AD-65 (equivalent to M6295) (ic24)(sound)
3071x oscillator 30.00MHz (close to main)
3081x red resonator ZTB1000J (close to sound)
309
310ROMs:
311
3121x M27C2001 (1)
3132x M27C4001 (2,3)
314
315Note:
316
3171x 28x2 edge connector
3181x 12 legs connector
3191x 50 legs flat cable connector
3201x 12x2 jumper
3211x trimmer (volume)
3221x trimmer (spark)
323
324*/
325
326ROM_START( laperla )
327   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
328   ROM_LOAD( "laperla_ver2.0_hd64f3048f16.mcu", 0x00000, 0x4000, NO_DUMP )
329
330   ROM_REGION( 0x100000, REGION_GFX1, 0 )
331   ROM_LOAD( "2jolly.ic18", 0x000000, 0x80000, CRC(7bf3d5f2) SHA1(f3a51dd642358a20f6324f28fdf458e8ceaca7a1) )
332   ROM_LOAD( "3jolly.ic17", 0x080000, 0x80000, CRC(c3a8d9a0) SHA1(cc95c56ebc6137e11c82ed17be7c9f83ed7b6cfc) )
333
334   ROM_REGION( 0x40000, REGION_SOUND1, 0 ) /* M6295 samples */
335   ROM_LOAD( "1.ic25", 0x00000, 0x40000, CRC(4fe79e43) SHA1(7c154cb00e9b64fbdcc218280f2183b816cef20b) )
336ROM_END
337
338
339/* La Perla Nera Gold (Ver 2.0)
340
341CPU:
342
3431x HD64F3048F16 (main)(ic1)
3441x ispLSI2064-80LJ (ic12)
3451x AD-65 (equivalent to M6295) (ic24)(sound)
3461x oscillator 30.00MHz (close to main)
3471x red resonator ZTB1000J (close to sound)
348
349ROMs:
350
3511x M27C2001 (1)
3522x M27C4001 (2,3)
353
354Note:
355
3561x 28x2 edge connector
3571x 12 legs connector
3581x 50 legs flat cable connector
3591x 12x2 jumper
3601x trimmer (volume)
3611x trimmer (spark)
362
363---------------------------------------------
364
365laperla vs. laperlag
366
3673 and 3 files
3683jolly.ic17             ic17-laperlanera            11.018181%
3692jolly.ic18             ic18-laperlanera            10.766602%
3701.ic25                                          NO MATCH
371                        ic25-uno.bin            NO MATCH
372*/
373
374ROM_START( laperlag )
375   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
376   ROM_LOAD( "laperlag_ver2.0_hd64f3048f16.mcu", 0x00000, 0x4000, NO_DUMP )
377
378   ROM_REGION( 0x100000, REGION_GFX1, 0 )
379   ROM_LOAD( "ic18-laperlaneragold2.bin", 0x000000, 0x80000, CRC(ae37de44) SHA1(089f97678fa39aee1885d7c63c4bc7c88e7fe553) )
380   ROM_LOAD( "ic17-laperlaneragold3.bin", 0x080000, 0x80000, CRC(86da6d11) SHA1(e6b7f9ccbf2e91a60fdf38067ec7ac7e73dea8cd) )
381
382   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* M6295 samples */
383   ROM_LOAD( "ic25-uno.bin", 0x00000, 0x20000, CRC(e6a0854b) SHA1(394e01bb24abd1e0d2c447b4d620fc5d02257d8a) )
384ROM_END
385
386
387/* Europa 2002 (Ver 2.0, set 1)
388
389CPU:
390
3911x HD64F3048F16 (main)(ic1)
3921x ispLSI2064-80LJ (ic12)
3931x AD-65 (equivalent to M6295) (ic24)(sound)
3941x oscillator 30MHz (close to main)
3951x blu resonator 1000J (close to sound)
396
397ROMs:
398
3993x M27C2001 (1,2,3)
4002x M27C4001 (4,5)
401
402Note:
403
4041x 28x2 edge connector
4051x 12 legs connector
4061x 50 legs flat cable connector
4071x 12x2 switches dip
4081x trimmer (volume)
4091x trimmer (spark)
410
411*/
412
413ROM_START( euro2k2 )
414   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
415   ROM_LOAD( "euro2k2_ver2.0_hd64f3048f16.mcu", 0x00000, 0x4000, NO_DUMP )
416
417   ROM_REGION( 0x180000, REGION_GFX1, 0 )
418   ROM_LOAD( "4a.ic18", 0x000000, 0x80000, CRC(5decae2d) SHA1(d918aad0e2a1249b18677833f743c92fb678050a) )
419   ROM_LOAD( "5a.ic17", 0x080000, 0x80000, CRC(8f1bbbf3) SHA1(5efcf77674f8737fc1b98881acebacb26b10adc1) )
420   ROM_LOAD( "2a.ic20", 0x100000, 0x40000, CRC(f9bffb07) SHA1(efba175189d99a4548739a72f8a1f03c2782a3d0) )
421   ROM_LOAD( "3a.ic19", 0x140000, 0x40000, CRC(8b29cd56) SHA1(8a09e307271bceef6e9f863153d0f7a9bc6dc6bd) )
422
423   ROM_REGION( 0x40000, REGION_SOUND1, 0 ) /* M6295 samples */
424   ROM_LOAD( "1.ic25", 0x00000, 0x40000, CRC(b9b1aff0) SHA1(35622d7d099a10e5c6bcae152fded1f50692f740) )
425ROM_END
426
427
428/* Europa 2002 (Ver 2.0, set 2)
429
430CPU:
431
4321x HD64F3048F16 (main)(ic1)
4331x ispLSI2064-80LJ (ic12)
4341x U6295 (equivalent to M6295) (ic24)(sound)
4351x oscillator 30.00MHz (close to main)
4361x orange resonator ZTB1000J (close to sound)
437
438ROMs:
439
4402x M27C2001 (1,2)
4413x M27C4001 (3,4,5)
442
443Note:
444
4451x 28x2 edge connector
4461x 12 legs connector
4471x 50 legs flat cable connector
4481x 12x2 switches dip
4491x trimmer (volume)
4501x trimmer (spark)
451
452---------------------------------------
453
454euro2k2 vs. euro2k2a
455
4565 and 5 files
4574a.ic18                                         FIXED BITS (xxxxxxx0)
458                        3a.ic19                 1ST AND 2ND HALF IDENTICAL
459                        4a.ic18                 FIXED BITS (xxxxxxx0)
4602a.ic20                 2a.ic20                 IDENTICAL
4614a.ic18                 4a.ic18                 IDENTICAL
4625a.ic17                 5a.ic17                 IDENTICAL
4631.ic25                  1.ic25                  99.998474%
4643a.ic19                                         NO MATCH
465                        3a.ic19                 NO MATCH
466*/
467
468ROM_START( euro2k2a )
469   ROM_REGION( 0x1000000, REGION_CPU1, 0 ) /* all the program code is in here */
470   ROM_LOAD( "euro2k2a_ver2.0_hd64f3048f16.mcu", 0x00000, 0x4000, NO_DUMP )
471
472   ROM_REGION( 0x1c0000, REGION_GFX1, 0 ) /* M6295 samples */
473   ROM_LOAD( "4a.ic18", 0x000000, 0x80000, CRC(5decae2d) SHA1(d918aad0e2a1249b18677833f743c92fb678050a) )
474   ROM_LOAD( "5a.ic17", 0x080000, 0x80000, CRC(8f1bbbf3) SHA1(5efcf77674f8737fc1b98881acebacb26b10adc1) )
475   ROM_LOAD( "2a.ic20", 0x100000, 0x40000, CRC(f9bffb07) SHA1(efba175189d99a4548739a72f8a1f03c2782a3d0) )
476   ROM_LOAD( "3a.ic19", 0x140000, 0x80000, CRC(56c8a73d) SHA1(49b44e5604cd8675d8f9770e5fb68dad4394e11d) ) /* identical halves */
477
478   ROM_REGION( 0x40000, REGION_SOUND1, 0 )
479   ROM_LOAD( "1.ic25", 0x00000, 0x40000, CRC(4fe79e43) SHA1(7c154cb00e9b64fbdcc218280f2183b816cef20b) )
480ROM_END
481
482
483/*************************
484*      Game Drivers      *
485*************************/
486
487/*    YEAR  NAME      PARENT   MACHINE   INPUT     INIT ROT    COMPANY                  FULLNAME                        FLAGS  */
488GAME( 2000, capunc,   0,       itgamble, itgamble, 0,   ROT0, "Nazionale Elettronica", "Capitan Uncino (Ver 1.2)",      GAME_NOT_WORKING )
489GAME( 2001, capcor,   0,       itgamble, itgamble, 0,   ROT0, "Nazionale Elettronica", "Capitani Coraggiosi (Ver 1.3)", GAME_NOT_WORKING )
490GAME( 2002, laperla,  0,       itgamble, itgamble, 0,   ROT0, "Nazionale Elettronica", "La Perla Nera (Ver 2.0)",       GAME_NOT_WORKING )
491GAME( 2001, laperlag, 0,       itgamble, itgamble, 0,   ROT0, "Nazionale Elettronica", "La Perla Nera Gold (Ver 2.0)",  GAME_NOT_WORKING )
492GAME( 2001, euro2k2,  0,       itgamble, itgamble, 0,   ROT0, "Nazionale Elettronica", "Europa 2002 (Ver 2.0, set 1)",  GAME_NOT_WORKING )
493GAME( 2001, euro2k2a, euro2k2, itgamble, itgamble, 0,   ROT0, "Nazionale Elettronica", "Europa 2002 (Ver 2.0, set 2)",  GAME_NOT_WORKING )
src/mame/drivers/gameplan.c
r2821r2822
871871   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_TILT )
872872   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Do Tests") PORT_CODE(KEYCODE_F1)
873873   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Select Test") PORT_CODE(KEYCODE_F2)
874   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
874875   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_COIN2 )
875876   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 )
876   PORT_BIT( 0x23, IP_ACTIVE_LOW, IPT_UNUSED )
877877
878878   PORT_START      /* COL. B - from "TEST NO.7 - status locator - start sws." */
879879   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
10141014   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_TILT )
10151015   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Do Tests") PORT_CODE(KEYCODE_F1)
10161016   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Select Test") PORT_CODE(KEYCODE_F2)
1017   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
10171018   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_COIN2 )
10181019   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 )
1019   PORT_BIT( 0x23, IP_ACTIVE_LOW, IPT_UNUSED )
10201020
10211021   PORT_START      /* COL. B - from "TEST NO.7 - status locator - start sws." */
10221022   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
src/mame/drivers/cbasebal.c
r2821r2822
1313***************************************************************************/
1414
1515#include "driver.h"
16#include "includes/cps1.h"
1617#include "machine/eeprom.h"
1718#include "sound/okim6295.h"
1819#include "sound/2413intf.h"
1920
2021
21/* in machine/kabuki.c */
22void pang_decode(void);
23
24
2522VIDEO_START( cbasebal );
2623WRITE8_HANDLER( cbasebal_textram_w );
2724READ8_HANDLER( cbasebal_textram_r );
src/mame/drivers/beathead.c
r2821r2822
381381   PORT_START
382382   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
383383   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
384   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START2 )
385384   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED )
386385   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
387386   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
r2821r2822
394393   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
395394   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
396395   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
397   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START1 )
398396   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
399397   PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED )
400398   PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
src/mame/drivers/sbasketb.c
r2821r2822
1616***************************************************************************/
1717
1818#include "driver.h"
19#include "machine/konami1.h"
1920#include "cpu/m6809/m6809.h"
2021#include "sound/vlm5030.h"
2122#include "sound/dac.h"
r2821r2822
2526extern UINT8 *sbasketb_palettebank;
2627extern UINT8 *sbasketb_spriteram_select;
2728
28void konami1_decode(void);
29
3029WRITE8_HANDLER( sbasketb_videoram_w );
3130WRITE8_HANDLER( sbasketb_colorram_w );
3231WRITE8_HANDLER( sbasketb_flipscreen_w );
r2821r2822
382381
383382static DRIVER_INIT( sbasketb )
384383{
385   konami1_decode();
384   konami1_decode(0);
386385}
387386
388387
src/mame/drivers/sliver.c
r2821r2822
256256static void blit_gfx(void)
257257{
258258   int tmpptr=0;
259   const UINT8 *rom = memory_region(REGION_USER1);
260
259261   while(tmpptr<fptr)
260262   {
261263      int x,y,romdata;
r2821r2822
271273         {
272274            for (x=0;x<w;x++)
273275            {
274               romdata = memory_region(REGION_USER1)[romoffs&0x1fffff];
276               romdata = rom[romoffs&0x1fffff];
275277               if(romdata)
276278               {
277279                  plot_pixel_pal(fifo[tmpptr+5]+fifo[tmpptr+3]-x, fifo[tmpptr+6]+fifo[tmpptr+4]-y, romdata);
r2821r2822
306308{
307309   int x,y;
308310   int addr=jpeg_addr;
311   UINT8 *rom;
312
309313   fillbitmap(sliver_bitmap_bg, 0,0);
310314   if(jpeg_addr<0)
311315   {
312316      return;
313317   }
318   rom = memory_region(REGION_USER3);
314319   for (y=0;y<jpeg_h;y++)
315320   {
316321      for (x=0;x<jpeg_w;x++)
317322      {
318         plot_pixel_rgb(x-x_offset+jpeg_x,jpeg_h-y-y_offset-jpeg_y,memory_region(REGION_USER3)[addr],memory_region(REGION_USER3)[addr+1],memory_region(REGION_USER3)[addr+2]);
323         plot_pixel_rgb(x-x_offset+jpeg_x,jpeg_h-y-y_offset-jpeg_y,rom[addr],rom[addr+1],rom[addr+2]);
319324         addr+=3;
320325      }
321326   }
src/mame/drivers/epos.c
r2821r2822
3333#include "sound/ay8910.h"
3434#include "epos.h"
3535
36
37static int counter = 0;
38
36static int counter;
3937static MACHINE_RESET( dealer );
4038
4139static WRITE8_HANDLER( dealer_decrypt_rom )
r2821r2822
5048//  logerror("PC %08x: ctr=%04x\n",activecpu_get_pc(),counter);
5149
5250   memory_set_bankptr(1, rom + 0x10000 * counter);
51
52   // is the 2nd bank changed by the counter or it always uses the 1st key?
5353}
5454
5555
r2821r2822
7373
7474
7575static ADDRESS_MAP_START( dealer_readmem, ADDRESS_SPACE_PROGRAM, 8 )
76   AM_RANGE(0x0000, 0x6fff) AM_READ(SMH_BANK1)
76   AM_RANGE(0x0000, 0x5fff) AM_READ(SMH_BANK1)
77   AM_RANGE(0x6000, 0x6fff) AM_READ(SMH_BANK2)
7778   AM_RANGE(0x7000, 0xffff) AM_READ(SMH_RAM)
7879ADDRESS_MAP_END
7980
r2821r2822
120121//  AM_RANGE(0x40, 0x40) AM_WRITE(watchdog_reset_w)
121122ADDRESS_MAP_END
122123
124/*
125   ROMs U01-U03 are checked with the same code in a loop.
126   There's a separate ROM check for banked U04 at 30F3.
127   It looks like dealer/revenger uses ppi8255 to control bankswitching.
128*/
129static WRITE8_HANDLER( write_prtc )
130{
131   UINT8 *rom = memory_region(REGION_CPU1);
132   memory_set_bankptr(2, rom + 0x6000 + (0x1000 * (data & 1)));
133}
134
123135static const ppi8255_interface ppi8255_intf =
124136{
125137   input_port_2_r,   /* Port A read */
r2821r2822
127139   NULL,         /* Port C read */
128140   NULL,         /* Port A write */
129141   NULL,         /* Port B write */
130   NULL,         /* Port C write */
142   write_prtc,      /* Port C write */
131143};
132144
133145/*************************************
r2821r2822
332344   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 )
333345   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 ) //play
334346   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON6 )
335   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON7 ) //coin in
336   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON8 )
347   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) //coin in
348   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE )
337349INPUT_PORTS_END
338350
339351
r2821r2822
520532   ROM_LOAD( "u1.bin",         0x0000, 0x2000, CRC(e06f3563) SHA1(0d58cd1f2e1ca89adb9c64d7dd520bb1f2d50f1a) )
521533   ROM_LOAD( "u2.bin",         0x2000, 0x2000, CRC(726bbbd6) SHA1(3538f3d655899c2a0f984c43fb7545ea4be1b231) )
522534   ROM_LOAD( "u3.bin",         0x4000, 0x2000, CRC(ab721455) SHA1(a477da0590e0431172baae972e765473e19dcbff) )
523   ROM_LOAD( "u4.bin",         0x6000, 0x2000, BAD_DUMP CRC(ddb903e4) SHA1(4c06a2048b1c6989c363b110a17c33180025b9c8) )
535   ROM_LOAD( "u4.bin",         0x6000, 0x2000, CRC(ddb903e4) SHA1(4c06a2048b1c6989c363b110a17c33180025b9c8) )
524536
525537   ROM_REGION( 0x0020, REGION_PROMS, 0 )
526538   ROM_LOAD( "82s123.u66",      0x0000, 0x0020, NO_DUMP )   /* missing */
r2821r2822
559571
560572static MACHINE_RESET( dealer )
561573{
574   counter = 0;
562575   memory_set_bankptr(1, memory_region(REGION_CPU1));
576   memory_set_bankptr(2, ((UINT8*)memory_region(REGION_CPU1)) + 0x6000);
563577}
564578
565579static DRIVER_INIT( dealer )
r2821r2822
616630GAME( 1983, theglob2, suprglob, epos,   suprglob, 0,        ROT270, "Epos Corporation", "The Glob (earlier)", 0 )
617631GAME( 1983, theglob3, suprglob, epos,   suprglob, 0,        ROT270, "Epos Corporation", "The Glob (set 3)", 0 )
618632GAME( 1984, igmo,     0,        epos,   igmo,     0,        ROT270, "Epos Corporation", "IGMO", GAME_WRONG_COLORS )
619GAME( 19??, dealer,   0,        dealer, dealer,   dealer,   ROT270, "Epos Corporation", "The Dealer", GAME_NOT_WORKING)
620GAME( 1984, revenger, 0,        dealer, dealer,   dealer,   ROT270, "Epos Corporation", "Revenger", GAME_NOT_WORKING)
633GAME( 1984, dealer,   0,        dealer, dealer,   dealer,   ROT270, "Epos Corporation", "The Dealer", GAME_WRONG_COLORS )
634GAME( 1984, revenger, 0,        dealer, dealer,   dealer,   ROT270, "Epos Corporation", "Revenger", GAME_NOT_WORKING )
src/mame/drivers/cps3.c
r2821r2822
25152515
25162516   /* precopy gfx roms, good, tests pass */
25172517   {
2518      UINT32 thebase;
2518      UINT32 thebase, len = memory_region_length(REGION_USER5);
25192519      int flashnum = 8;
25202520      UINT32* romdata = (UINT32*)memory_region(REGION_USER5);
25212521
2522      for (thebase = 0;thebase < memory_region_length(REGION_USER5)/2; thebase+=0x200000)
2522      for (thebase = 0;thebase < len/2; thebase+=0x200000)
25232523      {
25242524      //  printf("flashnums %d. %d\n",flashnum, flashnum+1);
25252525
r2821r2822
25872587
25882588   /* copy gfx from loaded flashroms to user reigon 5, where it's used */
25892589   {
2590      UINT32 thebase;
2590      UINT32 thebase, len = memory_region_length(REGION_USER5);
25912591      int flashnum = 8;
25922592      UINT32* romdata = (UINT32*)memory_region(REGION_USER5);
25932593      int countoffset = 0;
25942594
2595      for (thebase = 0;thebase < memory_region_length(REGION_USER5)/2; thebase+=0x200000)
2595      for (thebase = 0;thebase < len/2; thebase+=0x200000)
25962596      {
25972597      //  printf("flashnums %d. %d\n",flashnum, flashnum+1);
25982598
src/mame/drivers/cinemat.c
r2821r2822
751751
752752static INPUT_PORTS_START( solarq )
753753   PORT_START_TAG("INPUTS")
754   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START2 )
755754   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) /* nova */
756755   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) /* fire */
757756   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) /* thrust */
758   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_START1 )
759757   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) /* hyperspace */
760758   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(1)
761759   PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(1)
r2821r2822
788786   PORT_BIT( 0x0001, IP_ACTIVE_LOW,  IPT_BUTTON1 ) PORT_PLAYER(2)
789787   PORT_BIT( 0x0002, IP_ACTIVE_LOW,  IPT_BUTTON2 ) PORT_PLAYER(2)
790788   PORT_BIT( 0x0004, IP_ACTIVE_LOW,  IPT_BUTTON3 ) PORT_PLAYER(2)
791   PORT_BIT( 0x0004, IP_ACTIVE_LOW,  IPT_START2 )
792789   PORT_BIT( 0x0008, IP_ACTIVE_LOW,  IPT_BUTTON3 ) PORT_PLAYER(1)
793   PORT_BIT( 0x0008, IP_ACTIVE_LOW,  IPT_START1 )
794790   PORT_BIT( 0x0010, IP_ACTIVE_LOW,  IPT_BUTTON2 ) PORT_PLAYER(1)
795791   PORT_BIT( 0x0020, IP_ACTIVE_LOW,  IPT_BUTTON1 ) PORT_PLAYER(1)
796792   PORT_BIT( 0x0fc0, IP_ACTIVE_LOW,  IPT_UNUSED )
src/mame/drivers/jailbrek.c
r2821r2822
2121
2222
2323#include "driver.h"
24#include "machine/konami1.h"
2425#include "cpu/m6809/m6809.h"
2526#include "sound/sn76496.h"
2627#include "sound/vlm5030.h"
2728
2829
29void konami1_decode(void);
30
3130extern UINT8 *jailbrek_scroll_x;
3231extern UINT8 *jailbrek_scroll_dir;
3332
r2821r2822
413412        }
414413    }
415414
416    konami1_decode();
415    konami1_decode(0);
417416}
418417
419418GAME( 1986, jailbrek, 0,        jailbrek, jailbrek, jailbrek, ROT0, "Konami", "Jail Break", GAME_SUPPORTS_SAVE )
src/mame/drivers/mlanding.c
r2821r2822
436436
437437static DRIVER_INIT(mlanding)
438438{
439   memory_region(REGION_CPU3)[0x88b]=0x4e;
440   memory_region(REGION_CPU3)[0x88a]=0x71;
439   UINT8 *rom = memory_region(REGION_CPU3);
440   rom[0x88b]=0x4e;
441   rom[0x88a]=0x71;
441442}
442443
443444GAME( 1990, mlanding, 0,        mlanding,   mlanding, mlanding,        ROT0,    "Taito Corporation", "Midnight Landing", GAME_NOT_WORKING|GAME_NO_SOUND )
src/mame/drivers/wecleman.c
r2821r2822
12961296/* Unpack sprites data and do some patching */
12971297static DRIVER_INIT( wecleman )
12981298{
1299   int i;
1299   int i, len;
13001300   UINT8 *RAM;
13011301//  UINT16 *RAM1 = (UINT16 *) memory_region(REGION_CPU1);   /* Main CPU patches */
13021302//  RAM1[0x08c2/2] = 0x601e;    // faster self test
r2821r2822
13091309
13101310   /* let's swap even and odd *pixels* of the sprites */
13111311   RAM = memory_region(REGION_GFX1);
1312   for (i = 0; i < memory_region_length(REGION_GFX1); i ++)
1312   len = memory_region_length(REGION_GFX1);
1313   for (i = 0; i < len; i ++)
13131314   {
13141315      /* TODO: could be wrong, colors have to be fixed.       */
13151316      /* The only certain thing is that 87 must convert to f0 */
src/mame/drivers/alpha68k.c
r2821r2822
273273   if (invert_controls)
274274      return ~(input_port_read(machine, "IN0") + (input_port_read(machine, "IN1") << 8));
275275
276   return (input_port_read_indexed(machine, 0) + (input_port_read_indexed(machine, 1) << 8));
276   return (input_port_read(machine, "IN0") + (input_port_read(machine, "IN1") << 8));
277277}
278278
279279static READ16_HANDLER( control_2_r )
src/mame/drivers/tmaster.c
r2821r2822
12531253
12541254static DRIVER_INIT( galgames )
12551255{
1256   UINT8 *ROM = memory_region(REGION_CPU1);
12561257   // configure memory banks
1257   memory_configure_bank(1, 0, 2, memory_region(REGION_CPU1)+0x1c0000, 0x40000);
1258   memory_configure_bank(3, 0, 2, memory_region(REGION_CPU1)+0x1c0000, 0x40000);
1258   memory_configure_bank(1, 0, 2, ROM+0x1c0000, 0x40000);
1259   memory_configure_bank(3, 0, 2, ROM+0x1c0000, 0x40000);
12591260
1260   memory_configure_bank(2, 0, 1, memory_region(REGION_CPU1)+0x200000, 0x40000);
1261   memory_configure_bank(4, 0, 1, memory_region(REGION_CPU1)+0x200000, 0x40000);
1261   memory_configure_bank(2, 0, 1, ROM+0x200000, 0x40000);
1262   memory_configure_bank(4, 0, 1, ROM+0x200000, 0x40000);
12621263}
12631264
12641265GAME( 1996, tm,       0,    tm,       tm,       0,        ROT0, "Midway",                         "Touchmaster (v3.00 Euro)",           0 )
src/mame/drivers/tcl.c
r2821r2822
179179   /* only the first part is decrypted (and verified)*/
180180
181181   UINT8 *dest = memory_region(REGION_CPU1);
182   UINT8 *src = malloc_or_die(memory_region_length(REGION_CPU1));
182   int len = memory_region_length(REGION_CPU1);
183   UINT8 *src = malloc_or_die(len);
183184
184185   int i,idx=0;
185   memcpy(src, dest, memory_region_length(REGION_CPU1));
186   memcpy(src, dest, len);
186187   for(i=0;i<64*1024;i+=4)
187188   {
188189      if(i&0x8000)
src/mame/drivers/cischeat.c
r2821r2822
19741974static void cischeat_untangle_sprites(int region)
19751975{
19761976   UINT8      *src = memory_region(region);
1977   const UINT8   *end = memory_region(region) + memory_region_length(region);
1977   const UINT8   *end = src + memory_region_length(region);
19781978
19791979   while (src < end)
19801980   {
src/mame/drivers/redclash.c
r2821r2822
507507static DRIVER_INIT( redclash )
508508{
509509   int i,j;
510   const UINT8 *src = memory_region(REGION_GFX2);
511   UINT8 *dst = memory_region(REGION_GFX3);
512   int len = memory_region_length(REGION_GFX3);
510513
511514   /* rearrange the sprite graphics */
512   for (i = 0;i < memory_region_length(REGION_GFX3);i++)
515   for (i = 0;i < len;i++)
513516   {
514517      j = (i & ~0x003e) | ((i & 0x0e) << 2) | ((i & 0x30) >> 3);
515      memory_region(REGION_GFX3)[i] = memory_region(REGION_GFX2)[j];
518      dst[i] = src[j];
516519   }
517520}
518521
src/mame/drivers/galaxold.c
r2821r2822
10501050   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 )
10511051   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
10521052   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
1053    PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
1054    PORT_DIPSETTING(      0x0040, DEF_STR( Off ) )
1055    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
1053   PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
1054   PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
1055   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
10561056    PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
10571057
10581058   PORT_START_TAG("IN1")
r2821r2822
10691069   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )
10701070
10711071   PORT_START_TAG("IN2")
1072   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
1072   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
10731073   PORT_DIPNAME( 0x06, 0x00, DEF_STR( Coinage ) )
10741074   PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
10751075   PORT_DIPSETTING(    0x02, DEF_STR( 1C_2C ) )
r2821r2822
10791079   PORT_DIPSETTING(    0x00, DEF_STR( Upright ) )
10801080   PORT_DIPSETTING(    0x08, DEF_STR( Cocktail ) )
10811081   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
1082    PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) )
1083    PORT_DIPSETTING(      0x0020, DEF_STR( Off ) )
1084    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
1085   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
1086    PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
1087    PORT_DIPSETTING(      0x0080, DEF_STR( Off ) )
1088    PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
1082   PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
1083   PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
1084   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1085   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
1086   PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
1087   PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
1088   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
10891089INPUT_PORTS_END
10901090
10911091
src/mame/drivers/atarisy1.c
r2821r2822
211211static READ16_HANDLER( joystick_r )
212212{
213213   int newval = 0xff;
214   char port[4];
214215
215216   /* digital joystick type */
216217   if (joystick_type == 1)
217      newval = (input_port_read_indexed(machine, 0) & (0x80 >> offset)) ? 0xf0 : 0x00;
218      newval = (input_port_read(machine, "IN0") & (0x80 >> offset)) ? 0xf0 : 0x00;
218219
219220   /* Hall-effect analog joystick */
220221   else if (joystick_type == 2)
221      newval = input_port_read_indexed(machine, offset & 1);
222   {
223      sprintf(port, "IN%d", offset & 1);
224      newval = input_port_read(machine, port);
225   }
222226
223227   /* Road Blasters gas pedal */
224228   else if (joystick_type == 3)
225      newval = input_port_read_indexed(machine, 1);
229      newval = input_port_read(machine, "IN1");
226230
227231   /* the A4 bit enables/disables joystick IRQs */
228232   joystick_int_enable = ((offset >> 3) & 1) ^ 1;
r2821r2822
268272
269273         if (player == 0)
270274         {
271            posx = (INT8)input_port_read_indexed(machine, 0);
272            posy = (INT8)input_port_read_indexed(machine, 1);
275            posx = (INT8)input_port_read(machine, "IN0");
276            posy = (INT8)input_port_read(machine, "IN1");
273277         }
274278         else
275279         {
276            posx = (INT8)input_port_read_indexed(machine, 2);
277            posy = (INT8)input_port_read_indexed(machine, 3);
280            posx = (INT8)input_port_read(machine, "IN2");
281            posy = (INT8)input_port_read(machine, "IN3");
278282         }
279283
280284         cur[player][0] = posx + posy;
r2821r2822
286290
287291   /* Road Blasters steering wheel */
288292   else if (trackball_type == 2)
289      result = input_port_read_indexed(machine, 0);
293      result = input_port_read(machine, "IN0");
290294
291295   return result;
292296}
r2821r2822
301305
302306static READ16_HANDLER( port4_r )
303307{
304   int temp = input_port_read_indexed(machine, 4);
308   int temp = input_port_read(machine, "F60000");
305309   if (atarigen_cpu_to_sound_ready) temp ^= 0x0080;
306310   return temp;
307311}
r2821r2822
316320
317321static READ8_HANDLER( switch_6502_r )
318322{
319   int temp = input_port_read_indexed(machine, 5);
323   int temp = input_port_read(machine, "1820");
320324
321325   if (atarigen_cpu_to_sound_ready) temp ^= 0x08;
322326   if (atarigen_sound_to_cpu_ready) temp ^= 0x10;
323   if (!(input_port_read_indexed(machine, 4) & 0x0040)) temp ^= 0x80;
327   if (!(input_port_read(machine, "F60000") & 0x0040)) temp ^= 0x80;
324328
325329   return temp;
326330}
r2821r2822
470474 *************************************/
471475
472476static INPUT_PORTS_START( marble )
473   PORT_START  /* F20000 */
477   PORT_START_TAG("IN0")  /* F20000 */
474478    PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_REVERSE PORT_PLAYER(1)
475479
476   PORT_START  /* F20002 */
480   PORT_START_TAG("IN1")  /* F20002 */
477481    PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(1)
478482
479   PORT_START  /* F20004 */
483   PORT_START_TAG("IN2")  /* F20004 */
480484    PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_REVERSE PORT_PLAYER(2)
481485
482   PORT_START  /* F20006 */
486   PORT_START_TAG("IN3")  /* F20006 */
483487    PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(30) PORT_KEYDELTA(30) PORT_PLAYER(2)
484488
485   PORT_START   /* F60000 */
489   PORT_START_TAG("F60000")   /* F60000 */
486490   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START1 )
487491   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START2 )
488492   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
493497   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_SPECIAL )
494498   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
495499
496   PORT_START   /* 1820 (sound) */
500   PORT_START_TAG("1820")   /* 1820 (sound) */
497501   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
498502   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
499503   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 )
r2821r2822
505509
506510
507511static INPUT_PORTS_START( peterpak )
508   PORT_START   /* F40000 */
512   PORT_START_TAG("IN0")   /* F40000 */
509513   PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNUSED )
510514   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
511515   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
512516   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
513517   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
514518
515   PORT_START   /* n/a */
519   PORT_START_TAG("IN1")   /* n/a */
516520   PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
517521
518   PORT_START   /* n/a */
522   PORT_START_TAG("IN2")   /* n/a */
519523   PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
520524
521   PORT_START   /* n/a */
525   PORT_START_TAG("IN3")   /* n/a */
522526   PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
523527
524   PORT_START   /* F60000 */
525   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START1 )
528   PORT_START_TAG("F60000")   /* F60000 */
526529   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 )
527530   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START2 )
528531   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON2 )
r2821r2822
533536   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_SPECIAL )
534537   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
535538
536   PORT_START   /* 1820 (sound) */
539   PORT_START_TAG("1820")   /* 1820 (sound) */
537540   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
538541   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
539542   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 )
r2821r2822
545548
546549
547550static INPUT_PORTS_START( indytemp )
548   PORT_START   /* F40000 */
551   PORT_START_TAG("IN0")   /* F40000 */
549552   PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNUSED )
550553   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
551554   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
552555   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
553556   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
554557
555   PORT_START   /* n/a */
558   PORT_START_TAG("IN1")   /* n/a */
556559   PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
557560
558   PORT_START   /* n/a */
561   PORT_START_TAG("IN2")   /* n/a */
559562   PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
560563
561   PORT_START   /* n/a */
564   PORT_START_TAG("IN3")   /* n/a */
562565   PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
563566
564   PORT_START   /* F60000 */
565   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START1 )
567   PORT_START_TAG("F60000")   /* F60000 */
566568   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 )
567569   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START2 )
568570   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )   /* freeze? */
r2821r2822
573575   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_SPECIAL )
574576   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
575577
576   PORT_START   /* 1820 (sound) */
578   PORT_START_TAG("1820")   /* 1820 (sound) */
577579   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
578580   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
579581   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 )
r2821r2822
585587
586588
587589static INPUT_PORTS_START( roadrunn )
588   PORT_START   /* F40000 */
590   PORT_START_TAG("IN0")   /* F40000 */
589591   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1)
590592
591   PORT_START   /* F40002 */
593   PORT_START_TAG("IN1")   /* F40002 */
592594   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(1)
593595
594   PORT_START   /* n/a */
596   PORT_START_TAG("IN2")   /* n/a */
595597   PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
596598
597   PORT_START   /* n/a */
599   PORT_START_TAG("IN3")   /* n/a */
598600   PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
599601
600   PORT_START   /* F60000 */
601   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_START1 )
602   PORT_START_TAG("F60000")   /* F60000 */
602603   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 )
603604   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_START2 )
604605   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON2 )
r2821r2822
609610   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_SPECIAL )
610611   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
611612
612   PORT_START   /* 1820 (sound) */
613   PORT_START_TAG("1820")   /* 1820 (sound) */
613614   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
614615   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
615616   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 )
r2821r2822
621622
622623
623624static INPUT_PORTS_START( roadblst )
624   PORT_START   /* F20000 */
625   PORT_START_TAG("IN0")   /* F20000 */
625626   PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_REVERSE
626627
627   PORT_START   /* F40000 */
628   PORT_START_TAG("IN1")   /* F40000 */
628629   PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(64)
629630
630   PORT_START   /* n/a */
631   PORT_START_TAG("IN2")   /* n/a */
631632   PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
632633
633   PORT_START   /* n/a */
634   PORT_START_TAG("IN3")   /* n/a */
634635   PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
635636
636   PORT_START   /* F60000 */
637   PORT_START_TAG("F60000")   /* F60000 */
637638   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON3 )
638639   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 )
639640   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
644645   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_SPECIAL )
645646   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
646647
647   PORT_START   /* 1820 (sound) */
648   PORT_START_TAG("1820")   /* 1820 (sound) */
648649   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
649650   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
650651   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 )
src/mame/drivers/atarig42.c
r2821r2822
8383
8484static READ16_HANDLER( special_port2_r )
8585{
86   int temp = input_port_read_indexed(machine, 2);
86   int temp = input_port_read(machine, "IN2");
8787   if (atarigen_cpu_to_sound_ready) temp ^= 0x0020;
8888   if (atarigen_sound_to_cpu_ready) temp ^= 0x0010;
8989   temp ^= 0x0008;      /* A2D.EOC always high for now */
r2821r2822
9393
9494static WRITE16_HANDLER( a2d_select_w )
9595{
96   analog_data = input_port_read_indexed(machine, 4 + (offset != 0));
96   char port[5];
97
98   sprintf(port, "A2D%d", (offset != 0));
99   analog_data = input_port_read(machine, port);
97100}
98101
99102
r2821r2822
381384 *************************************/
382385
383386static INPUT_PORTS_START( roadriot )
384   PORT_START      /* e00000 */
387   PORT_START_TAG("IN0")      /* e00000 */
385388   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
386389   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
387390   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
388391   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
389392   PORT_BIT( 0xf800, IP_ACTIVE_LOW, IPT_UNUSED )
390393
391   PORT_START      /* e00002 */
394   PORT_START_TAG("IN1")      /* e00002 */
392395   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
393396
394   PORT_START      /* e00010 */
397   PORT_START_TAG("IN2")      /* e00010 */
395398   PORT_BIT( 0x003f, IP_ACTIVE_LOW, IPT_UNUSED )
396399   PORT_SERVICE( 0x0040, IP_ACTIVE_LOW )
397400   PORT_BIT(  0x0080, IP_ACTIVE_LOW, IPT_VBLANK )
r2821r2822
399402
400403   JSA_III_PORT   /* audio board port */
401404
402   PORT_START      /* analog 0 */
405   PORT_START_TAG("A2D0")      /* analog 0 */
403406   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10)
404407
405   PORT_START      /* analog 1 */
408   PORT_START_TAG("A2D1")      /* analog 1 */
406409   PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(16)
407410INPUT_PORTS_END
408411
409412
410413static INPUT_PORTS_START( guardian )
411   PORT_START      /* e00000 */
414   PORT_START_TAG("IN0")      /* e00000 */
412415   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED )
413416   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(3)
414417   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3)
r2821r2822
426429   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
427430   PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
428431
429   PORT_START      /* e00002 */
432   PORT_START_TAG("IN1")      /* e00002 */
430433   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
431434   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
432435   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
r2821r2822
442445   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
443446   PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
444447
445   PORT_START      /* e00010 */
448   PORT_START_TAG("IN2")      /* e00010 */
446449   PORT_BIT( 0x003f, IP_ACTIVE_LOW, IPT_UNUSED )
447450   PORT_SERVICE( 0x0040, IP_ACTIVE_LOW )
448451   PORT_BIT(  0x0080, IP_ACTIVE_LOW, IPT_VBLANK )
r2821r2822
450453
451454   JSA_III_PORT   /* audio board port */
452455
453   PORT_START      /* analog 0 */
456   PORT_START_TAG("A2D0")      /* analog 0 */
454457   PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
455458
456   PORT_START      /* analog 1 */
459   PORT_START_TAG("A2D1")      /* analog 1 */
457460   PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
458461INPUT_PORTS_END
459462
src/mame/drivers/mpu4drvr.c
r2821r2822
15671567
15681568static PALETTE_INIT( dealem )
15691569{
1570   int i;
1570   int i, len;
15711571   static const int resistances_rg[3] = { 1000, 470, 220 };
15721572   static const int resistances_b [2] = { 470, 220 };
15731573   double weights_r[3], weights_g[3], weights_b[2];
r2821r2822
15771577         3,   resistances_rg,   weights_g,   1000,   0,
15781578         2,   resistances_b,   weights_b,   1000,   0);
15791579
1580   for (i = 0; i < memory_region_length(REGION_PROMS); i++)
1580   len = memory_region_length(REGION_PROMS);
1581   for (i = 0; i < len; i++)
15811582   {
15821583      int bit0,bit1,bit2,r,g,b;
15831584
src/mame/drivers/aquarium.c
r2821r2822
8686static READ16_HANDLER( aquarium_coins_r )
8787{
8888   int data;
89   data = (input_port_read_indexed(machine,2) & 0x7fff);   /* IN1 */
89   data = (input_port_read(machine, "IN1") & 0x7fff);
9090   data |= aquarium_snd_ack;
9191   aquarium_snd_ack = 0;
9292   return data;
r2821r2822
212212   PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Demo_Sounds ) )
213213   PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
214214   PORT_DIPSETTING(      0x2000, DEF_STR( On ) )
215   PORT_DIPUNUSED( 0x0400, IP_ACTIVE_LOW )
216   PORT_DIPUNUSED( 0x0800, IP_ACTIVE_LOW )
215   PORT_DIPUNUSED( 0x4000, IP_ACTIVE_LOW )
216   PORT_DIPUNUSED( 0x8000, IP_ACTIVE_LOW )
217217
218218   PORT_START_TAG("IN0")
219219   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
src/mame/drivers/angelkds.c
r2821r2822
180180
181181static READ8_HANDLER( angelkds_input_r )
182182{
183   int fake = input_port_read_indexed(machine, 6+offset);
183   int fake;
184   char port1[4], port2[6];
184185
185   return ((fake & 0x01) ? fake  : input_port_read_indexed(machine, 4+offset));
186   sprintf(port1, "I8%d", 1 + offset);
187   sprintf(port2, "FAKE%d", 1 + offset);
188   fake = input_port_read(machine, port2);
189
190   return ((fake & 0x01) ? fake  : input_port_read(machine, port1));
186191}
187192
188193#else
189194
190195static READ8_HANDLER( angelkds_input_r )
191196{
192   return input_port_read_indexed(machine, 4+offset);
197   char port[4];
198
199   sprintf(port, "I8%d", 1 + offset);
200   return input_port_read(machine, port);
193201}
194202
195203#endif
r2821r2822
235243   AM_RANGE(0x00, 0x00) AM_WRITE(SMH_NOP) // 00 on start-up, not again
236244   AM_RANGE(0x42, 0x42) AM_WRITE(angelkds_cpu_bank_write)
237245   AM_RANGE(0x43, 0x43) AM_WRITE(SMH_NOP) // 9a on start-up, not again
238   AM_RANGE(0x40, 0x40) AM_READ(input_port_0_r)   /* "Coinage" Dip Switches */
239   AM_RANGE(0x41, 0x41) AM_READ(input_port_1_r)   /* Other Dip Switches */
240   AM_RANGE(0x42, 0x42) AM_READ(input_port_2_r)   /* Players inputs (not needed ?) */
241   AM_RANGE(0x80, 0x80) AM_READ(input_port_3_r)   /* System inputs */
246   AM_RANGE(0x40, 0x40) AM_READ_PORT("I40")   /* "Coinage" Dip Switches */
247   AM_RANGE(0x41, 0x41) AM_READ_PORT("I41")   /* Other Dip Switches */
248   AM_RANGE(0x42, 0x42) AM_READ_PORT("I42")   /* Players inputs (not needed ?) */
249   AM_RANGE(0x80, 0x80) AM_READ_PORT("I80")   /* System inputs */
242250   AM_RANGE(0x81, 0x82) AM_READ(angelkds_input_r)   /* Players inputs */
243251   AM_RANGE(0x83, 0x83) AM_WRITE(SMH_NOP) // 9b on start-up, not again
244252   AM_RANGE(0xc0, 0xc3) AM_READWRITE(angelkds_main_sound_r, angelkds_main_sound_w) // 02 various points
src/mame/drivers/circusc.c
r2821r2822
1414***************************************************************************/
1515
1616#include "driver.h"
17#include "machine/konami1.h"
1718#include "cpu/m6809/m6809.h"
1819#include "sound/dac.h"
1920#include "sound/sn76496.h"
2021#include "sound/discrete.h"
2122
22void konami1_decode(void);
23
2423extern UINT8 *circusc_spritebank;
2524extern UINT8 *circusc_scroll;
2625extern UINT8 *circusc_videoram,*circusc_colorram;
r2821r2822
525524
526525static DRIVER_INIT( circusc )
527526{
528   konami1_decode();
527   konami1_decode(0);
529528}
530529
531530
src/mame/drivers/zaccaria.c
r2821r2822
453453   PORT_START_TAG("IN2")
454454   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
455455   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
456   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
457   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
456   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
457   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
458458   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
459459   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
460460   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
r2821r2822
563563   PORT_START_TAG("IN2")
564564   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
565565   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
566   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
567   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
566   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
567   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
568568   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
569569   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
570570   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
src/mame/drivers/shadfrce.c
r2821r2822
351351   PORT_START   /* Fake IN5 (misc) */
352352   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_VBLANK )                  /* guess */
353353   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )                 /* must be ACTIVE_LOW or 'shadfrcj' jumps to the end (code at 0x04902e) */
354   PORT_BIT( 0xec, IP_ACTIVE_LOW, IPT_UNUSED )
354   PORT_BIT( 0xeb, IP_ACTIVE_LOW, IPT_UNUSED )
355355
356356   PORT_START   /* Fake IN6 (DIP1) */
357357   PORT_DIPNAME( 0x01, 0x01, "Unused DIP 1-1" )
src/mame/drivers/attckufo.c
r2821r2822
6464{
6565   switch(offset)
6666   {
67      case 0: return input_port_read_indexed(machine, 0);
68      case 2: return input_port_read_indexed(machine, 1);
67      case 0: return input_port_read(machine, "DSW");
68      case 2: return input_port_read(machine, "INPUT");
6969   }
7070   return 0xff;
7171}
r2821r2822
9292ADDRESS_MAP_END
9393
9494static INPUT_PORTS_START( attckufo )
95   PORT_START
95   PORT_START_TAG("DSW")
9696   PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) )
9797   PORT_DIPSETTING(    0x00, "3" )
9898   PORT_DIPSETTING(    0x01, "4" )
r2821r2822
115115   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
116116   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
117117
118   PORT_START
118   PORT_START_TAG("INPUT")
119119   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
120120   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
121121   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(1)
src/mame/drivers/firebeat.c
r2821r2822
19851985   cdda_set_cdrom(0, cd);
19861986}
19871987
1988static const ppc_config firebeat_ppc_cfg =
1989{
1990   PPC_MODEL_403GCX
1991};
1992
19931988static MACHINE_DRIVER_START(firebeat)
19941989
19951990   /* basic machine hardware */
1996   MDRV_CPU_ADD(PPC403, 66000000)
1997   MDRV_CPU_CONFIG(firebeat_ppc_cfg)
1991   MDRV_CPU_ADD(PPC403GCX, 66000000)
19981992   MDRV_CPU_PROGRAM_MAP(firebeat_map, 0)
19991993   MDRV_CPU_VBLANK_INT("main", firebeat_interrupt)
20001994
r2821r2822
20322026static MACHINE_DRIVER_START(firebeat2)
20332027
20342028   /* basic machine hardware */
2035   MDRV_CPU_ADD(PPC403, 66000000)
2036   MDRV_CPU_CONFIG(firebeat_ppc_cfg)
2029   MDRV_CPU_ADD(PPC403GCX, 66000000)
20372030   MDRV_CPU_PROGRAM_MAP(firebeat_map, 0)
20382031   MDRV_CPU_VBLANK_INT("left", firebeat_interrupt)
20392032
r2821r2822
22322225{
22332226   int r = ibutton_w(data);
22342227   if (r >= 0)
2235   {
2236      ppc403_spu_rx(r & 0xff);
2237   }
2228      cpunum_set_info_int(0, CPUINFO_INT_PPC_RX_DATA, r & 0xff);
22382229}
22392230
22402231/*****************************************************************************/
r2821r2822
22692260
22702261   cur_cab_data = cab_data;
22712262
2272   ppc403_install_spu_tx_handler(security_w);
2263   cpunum_set_info_fct(0, CPUINFO_PTR_SPU_TX_HANDLER, (genf *)security_w);
22732264
22742265   set_ibutton(rom);
22752266
src/mame/drivers/bagman.c
r2821r2822
311311   PORT_INCLUDE( bagman )
312312
313313   PORT_MODIFY("IN0")
314   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 )
315314   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) /* double-function button, start and shoot */
316315
317316   PORT_MODIFY("IN1")
318   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 )
319317   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL /* double-function button, start and shoot */
320318INPUT_PORTS_END
321319
src/mame/drivers/namcos23.c
r2821r2822
964964   AM_RANGE(H8_ADC_3_H, H8_ADC_3_L) AM_NOP
965965ADDRESS_MAP_END
966966
967static INPUT_PORTS_START( ss23 )
968INPUT_PORTS_END
969967
970968
971969static DRIVER_INIT(ss23)
r2821r2822
12641262ROM_END
12651263
12661264/* Games */
1267//GAME( 199?, downhbkr,  0,      s23, ss23, ss23, ROT0, "Namco",  "Downhill Bikers (DH3 Ver.A)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1268GAME( 1997, timecrs2, 0,         s23, ss23, ss23, ROT0, "Namco", "Time Crisis 2", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1269GAME( 1999, gp500,    0,        ss23, ss23, ss23, ROT0, "Namco", "GP500", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1270GAME( 1999, finfurl2, 0,        ss23, ss23, ss23, ROT0, "Namco", "Final Furlong 2 (World)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1271GAME( 1999, finfrl2j, finfurl2, ss23, ss23, ss23, ROT0, "Namco", "Final Furlong 2 (Japan)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1265//GAME( 199?, downhbkr,  0,      s23, 0, ss23, ROT0, "Namco",  "Downhill Bikers (DH3 Ver.A)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1266GAME( 1997, timecrs2, 0,         s23, 0, ss23, ROT0, "Namco", "Time Crisis 2", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1267GAME( 1999, gp500,    0,        ss23, 0, ss23, ROT0, "Namco", "GP500", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1268GAME( 1999, finfurl2, 0,        ss23, 0, ss23, ROT0, "Namco", "Final Furlong 2 (World)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
1269GAME( 1999, finfrl2j, finfurl2, ss23, 0, ss23, ROT0, "Namco", "Final Furlong 2 (Japan)", GAME_NOT_WORKING | GAME_UNEMULATED_PROTECTION | GAME_IMPERFECT_SOUND )
src/mame/drivers/tattack.c
r2821r2822
9393   PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
9494   PORT_DIPSETTING(    0x02, DEF_STR( 1C_2C ) )
9595
96   PORT_DIPNAME( 0x02, 0x00, "DSW1 2" )
97   PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
98   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
9996   PORT_DIPNAME( 0x04, 0x00, "Time" )
10097   PORT_DIPSETTING(    0x04, "112" )
10198   PORT_DIPSETTING(    0x00, "5" )
src/mame/drivers/atarisy2.c
r2821r2822
374374
375375static READ16_HANDLER( switch_r )
376376{
377   int result = input_port_read_indexed(machine, 1) | (input_port_read_indexed(machine, 2) << 8);
377   int result = input_port_read(machine, "1800") | (input_port_read(machine, "1801") << 8);
378378
379379   if (atarigen_cpu_to_sound_ready) result ^= 0x20;
380380   if (atarigen_sound_to_cpu_ready) result ^= 0x10;
r2821r2822
385385
386386static READ8_HANDLER( switch_6502_r )
387387{
388   int result = input_port_read_indexed(machine, 0);
388   int result = input_port_read(machine, "1840");
389389
390390   if (atarigen_cpu_to_sound_ready) result ^= 0x01;
391391   if (atarigen_sound_to_cpu_ready) result ^= 0x02;
392392   if (!has_tms5220 || tms5220_ready_r()) result ^= 0x04;
393   if (!(input_port_read_indexed(machine, 2) & 0x80)) result ^= 0x10;
393   if (!(input_port_read(machine, "1801") & 0x80)) result ^= 0x10;
394394
395395   return result;
396396}
r2821r2822
423423
424424static READ16_HANDLER( adc_r )
425425{
426   char port[5];
427
428   sprintf(port, "ADC%d", which_adc);
426429   if (which_adc < pedal_count)
427      return ~input_port_read_indexed(machine, 3 + which_adc);
430      return ~input_port_read(machine, port);
428431
429   return input_port_read_indexed(machine, 3 + which_adc) | 0xff00;
432   return input_port_read(machine, port) | 0xff00;
430433}
431434
432435
433436static READ8_HANDLER( leta_r )
434437{
438   char port[6];
439
435440    if (pedal_count == -1)   /* 720 */
436441   {
437442      /* special thanks to MAME Analog+ for the mapping code */
r2821r2822
443448            static double last_angle;
444449            static int rotations;
445450
446            int analogx = input_port_read_indexed(machine, 7) - 128;
447            int analogy = input_port_read_indexed(machine, 8) - 128;
451            int analogx = input_port_read(machine, "LETA0") - 128;
452            int analogy = input_port_read(machine, "LETA1") - 128;
448453            double angle;
449454
450455            /* if the joystick is centered, leave the rest of this alone */
r2821r2822
480485      }
481486   }
482487
483   return input_port_read_indexed(machine, 7 + (offset & 3));
488   sprintf(port, "LETA%d", (offset & 3));
489   return input_port_read(machine, port);
484490}
485491
486492
r2821r2822
786792   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_SPECIAL )
787793   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SPECIAL )
788794   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 )
789   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
790795   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 )
791   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 )
792796
793797   PORT_START_TAG("1801")
794798   PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
30283032      0x0000
30293033   };
30303034   int i;
3035   UINT8 *cpu1 = memory_region(REGION_CPU1);
30313036
30323037   atarigen_eeprom_default = compressed_default_eeprom;
30333038   slapstic_init(105);
r2821r2822
30353040   /* expand the 16k program ROMs into full 64k chunks */
30363041   for (i = 0x10000; i < 0x90000; i += 0x20000)
30373042   {
3038      memcpy(&memory_region(REGION_CPU1)[i + 0x08000], &memory_region(REGION_CPU1)[i], 0x8000);
3039      memcpy(&memory_region(REGION_CPU1)[i + 0x10000], &memory_region(REGION_CPU1)[i], 0x8000);
3040      memcpy(&memory_region(REGION_CPU1)[i + 0x18000], &memory_region(REGION_CPU1)[i], 0x8000);
3043      memcpy(&cpu1[i + 0x08000], &cpu1[i], 0x8000);
3044      memcpy(&cpu1[i + 0x10000], &cpu1[i], 0x8000);
3045      memcpy(&cpu1[i + 0x18000], &cpu1[i], 0x8000);
30413046   }
30423047
30433048   pedal_count = 0;
r2821r2822
30843089}
30853090
30863091
3087static void ssprint_init_common(const UINT16 *default_eeprom)
3092static void ssprint_init_common(running_machine *machine, const UINT16 *default_eeprom)
30883093{
30893094   int i;
3095   UINT8 *cpu1 = memory_region(REGION_CPU1);
30903096
30913097   atarigen_eeprom_default = default_eeprom;
30923098   slapstic_init(108);
30933099
30943100   /* expand the 32k program ROMs into full 64k chunks */
30953101   for (i = 0x10000; i < 0x90000; i += 0x20000)
3096      memcpy(&memory_region(REGION_CPU1)[i + 0x10000], &memory_region(REGION_CPU1)[i], 0x10000);
3102      memcpy(&cpu1[i + 0x10000], &cpu1[i], 0x10000);
30973103
30983104   pedal_count = 3;
30993105   has_tms5220 = 0;
r2821r2822
31283134      0x01D0,0x0125,0x0186,0x0102,0x01C6,0x011D,0x011F,0xFF00,
31293135      0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0x0800,0x0000
31303136   };
3131   ssprint_init_common(compressed_default_eeprom);
3137   ssprint_init_common(machine, compressed_default_eeprom);
31323138}
31333139
31343140static DRIVER_INIT( ssprint1 )
r2821r2822
31733179      0x012c,0x0132,0x0102,0x01d0,0x0125,0x0186,0x0102,0x01c6,
31743180      0x011d,0x011f,0x0200,0x0000
31753181   };
3176   ssprint_init_common(compressed_default_eeprom);
3182   ssprint_init_common(machine, compressed_default_eeprom);
31773183}
31783184
31793185
r2821r2822
32103216      0x0186,0x0100,0x011B,0x01BC,0x011D,0x011F,0x0000
32113217   };
32123218   int i;
3219   UINT8 *cpu1 = memory_region(REGION_CPU1);
32133220
32143221   atarigen_eeprom_default = compressed_default_eeprom;
32153222   slapstic_init(109);
32163223
32173224   /* expand the 32k program ROMs into full 64k chunks */
32183225   for (i = 0x10000; i < 0x90000; i += 0x20000)
3219      memcpy(&memory_region(REGION_CPU1)[i + 0x10000], &memory_region(REGION_CPU1)[i], 0x10000);
3226      memcpy(&cpu1[i + 0x10000], &cpu1[i], 0x10000);
32203227
32213228   pedal_count = 2;
32223229   has_tms5220 = 0;
src/mame/drivers/skydiver.c
r2821r2822
170170
171171static WRITE8_HANDLER( skydiver_whistle_w )
172172{
173   discrete_sound_w(machine, SKYDIVER_WHISTLE1_EN + (offset >> 1), offset & 0x01);
173   discrete_sound_w(machine, NODE_RELATIVE(SKYDIVER_WHISTLE1_EN, (offset >> 1)), offset & 0x01);
174174}
175175
176176
src/mame/drivers/cvs.c
r2821r2822
15351535
15361536static DRIVER_INIT( huncholy )
15371537{
1538   UINT8 *ROM = memory_region(REGION_CPU1);
1539
15381540   /* patch out protection */
1539   memory_region(REGION_CPU1)[0x0082] = 0xc0;
1540   memory_region(REGION_CPU1)[0x0083] = 0xc0;
1541   memory_region(REGION_CPU1)[0x0084] = 0xc0;
1542   memory_region(REGION_CPU1)[0x00b7] = 0xc0;
1543   memory_region(REGION_CPU1)[0x00b8] = 0xc0;
1544   memory_region(REGION_CPU1)[0x00b9] = 0xc0;
1545   memory_region(REGION_CPU1)[0x00d9] = 0xc0;
1546   memory_region(REGION_CPU1)[0x00da] = 0xc0;
1547   memory_region(REGION_CPU1)[0x00db] = 0xc0;
1548   memory_region(REGION_CPU1)[0x4456] = 0xc0;
1549   memory_region(REGION_CPU1)[0x4457] = 0xc0;
1550   memory_region(REGION_CPU1)[0x4458] = 0xc0;
1541   ROM[0x0082] = 0xc0;
1542   ROM[0x0083] = 0xc0;
1543   ROM[0x0084] = 0xc0;
1544   ROM[0x00b7] = 0xc0;
1545   ROM[0x00b8] = 0xc0;
1546   ROM[0x00b9] = 0xc0;
1547   ROM[0x00d9] = 0xc0;
1548   ROM[0x00da] = 0xc0;
1549   ROM[0x00db] = 0xc0;
1550   ROM[0x4456] = 0xc0;
1551   ROM[0x4457] = 0xc0;
1552   ROM[0x4458] = 0xc0;
15511553}
15521554
15531555
r2821r2822
15651567
15661568static DRIVER_INIT( superbik )
15671569{
1570   UINT8 *ROM = memory_region(REGION_CPU1);
1571
15681572   /* patch out protection */
1569   memory_region(REGION_CPU1)[0x0079] = 0xc0;
1570   memory_region(REGION_CPU1)[0x007a] = 0xc0;
1571   memory_region(REGION_CPU1)[0x007b] = 0xc0;
1572   memory_region(REGION_CPU1)[0x0081] = 0xc0;
1573   memory_region(REGION_CPU1)[0x0082] = 0xc0;
1574   memory_region(REGION_CPU1)[0x0083] = 0xc0;
1575   memory_region(REGION_CPU1)[0x00b6] = 0xc0;
1576   memory_region(REGION_CPU1)[0x00b7] = 0xc0;
1577   memory_region(REGION_CPU1)[0x00b8] = 0xc0;
1578   memory_region(REGION_CPU1)[0x0168] = 0xc0;
1579   memory_region(REGION_CPU1)[0x0169] = 0xc0;
1580   memory_region(REGION_CPU1)[0x016a] = 0xc0;
1573   ROM[0x0079] = 0xc0;
1574   ROM[0x007a] = 0xc0;
1575   ROM[0x007b] = 0xc0;
1576   ROM[0x0081] = 0xc0;
1577   ROM[0x0082] = 0xc0;
1578   ROM[0x0083] = 0xc0;
1579   ROM[0x00b6] = 0xc0;
1580   ROM[0x00b7] = 0xc0;
1581   ROM[0x00b8] = 0xc0;
1582   ROM[0x0168] = 0xc0;
1583   ROM[0x0169] = 0xc0;
1584   ROM[0x016a] = 0xc0;
15811585
15821586   /* and speed up the protection check */
1583   memory_region(REGION_CPU1)[0x0099] = 0xc0;
1584   memory_region(REGION_CPU1)[0x009a] = 0xc0;
1585   memory_region(REGION_CPU1)[0x009b] = 0xc0;
1586   memory_region(REGION_CPU1)[0x00bb] = 0xc0;
1587   memory_region(REGION_CPU1)[0x00bc] = 0xc0;
1588   memory_region(REGION_CPU1)[0x00bd] = 0xc0;
1587   ROM[0x0099] = 0xc0;
1588   ROM[0x009a] = 0xc0;
1589   ROM[0x009b] = 0xc0;
1590   ROM[0x00bb] = 0xc0;
1591   ROM[0x00bc] = 0xc0;
1592   ROM[0x00bd] = 0xc0;
15891593}
15901594
15911595
15921596static DRIVER_INIT( hero )
15931597{
1598   UINT8 *ROM = memory_region(REGION_CPU1);
1599
15941600   /* patch out protection */
1595   memory_region(REGION_CPU1)[0x0087] = 0xc0;
1596   memory_region(REGION_CPU1)[0x0088] = 0xc0;
1597   memory_region(REGION_CPU1)[0x0aa1] = 0xc0;
1598   memory_region(REGION_CPU1)[0x0aa2] = 0xc0;
1599   memory_region(REGION_CPU1)[0x0aa3] = 0xc0;
1600   memory_region(REGION_CPU1)[0x0aaf] = 0xc0;
1601   memory_region(REGION_CPU1)[0x0ab0] = 0xc0;
1602   memory_region(REGION_CPU1)[0x0ab1] = 0xc0;
1603   memory_region(REGION_CPU1)[0x0abd] = 0xc0;
1604   memory_region(REGION_CPU1)[0x0abe] = 0xc0;
1605   memory_region(REGION_CPU1)[0x0abf] = 0xc0;
1606   memory_region(REGION_CPU1)[0x4de0] = 0xc0;
1607   memory_region(REGION_CPU1)[0x4de1] = 0xc0;
1608   memory_region(REGION_CPU1)[0x4de2] = 0xc0;
1601   ROM[0x0087] = 0xc0;
1602   ROM[0x0088] = 0xc0;
1603   ROM[0x0aa1] = 0xc0;
1604   ROM[0x0aa2] = 0xc0;
1605   ROM[0x0aa3] = 0xc0;
1606   ROM[0x0aaf] = 0xc0;
1607   ROM[0x0ab0] = 0xc0;
1608   ROM[0x0ab1] = 0xc0;
1609   ROM[0x0abd] = 0xc0;
1610   ROM[0x0abe] = 0xc0;
1611   ROM[0x0abf] = 0xc0;
1612   ROM[0x4de0] = 0xc0;
1613   ROM[0x4de1] = 0xc0;
1614   ROM[0x4de2] = 0xc0;
16091615}
16101616
16111617
r2821r2822
16201626      ROM[offs] = BITSWAP8(ROM[offs],7,1,5,4,3,2,6,0);
16211627
16221628   /* patch out protection */
1623   memory_region(REGION_CPU1)[0x010a] = 0xc0;
1624   memory_region(REGION_CPU1)[0x010b] = 0xc0;
1625   memory_region(REGION_CPU1)[0x010c] = 0xc0;
1629   ROM[0x010a] = 0xc0;
1630   ROM[0x010b] = 0xc0;
1631   ROM[0x010c] = 0xc0;
16261632}
16271633
16281634
src/mame/drivers/seta.c
r2821r2822
47374737   PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW1:1")
47384738   PORT_DIPSETTING(      0x0100, DEF_STR( Off ) )
47394739   PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
4740   PORT_SERVICE( 0x0200, IP_ACTIVE_LOW )
47414740   PORT_SERVICE_DIPLOC(  0x0200, IP_ACTIVE_LOW, "SW1:2" )
47424741   PORT_DIPNAME( 0x1c00, 0x1c00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:3,4,5")
47434742   PORT_DIPSETTING(      0x1c00, DEF_STR( None ) )
r2821r2822
61826181   PORT_DIPSETTING(    0x08, "1 Coin/10 Credits" )
61836182   PORT_DIPSETTING(    0x04, "1 Coin/20 Credits" )
61846183   PORT_DIPSETTING(    0x00, "1 Coin/50 Credits" )
6185   PORT_DIPNAME( 0x08, 0x08, "Unknown 1-3" )
6186   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
6187   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
6188   PORT_DIPNAME( 0x10, 0x10, "Unknown 1-4" )
6189   PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
6190   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
61916184   PORT_DIPNAME( 0x20, 0x20, "Unknown 1-5" )
61926185   PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
61936186   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
src/mame/drivers/tnzs.c
r2821r2822
23542354ROM_START( insectx )
23552355   ROM_REGION( 0x30000, REGION_CPU1, 0 )   /* 64k + bankswitch areas for the first CPU */
23562356   ROM_LOAD( "b97-03.u32", 0x00000, 0x08000, CRC(18eef387) SHA1(b22633930d39be1e72fbd5b080972122da3cb3ef) )
2357   ROM_CONTINUE(             0x18000, 0x18000 )      /* banked at 8000-bfff */
2357   ROM_CONTINUE(           0x18000, 0x18000 )      /* banked at 8000-bfff */
23582358
23592359   ROM_REGION( 0x18000, REGION_CPU2, 0 )   /* 64k for the second CPU */
23602360   ROM_LOAD( "b97-07.u38", 0x00000, 0x08000, CRC(324b28c9) SHA1(db77a4ac60196d0f0f35dbc5c951ec29d6392463) )
2361   ROM_CONTINUE(             0x10000, 0x08000 )      /* banked at 8000-9fff */
2361   ROM_CONTINUE(           0x10000, 0x08000 )      /* banked at 8000-9fff */
23622362
2363   ROM_REGION( 0x100000, REGION_GFX1, ROMREGION_DISPOSE )
2364   ROM_LOAD( "b97-02.u1", 0x00000, 0x80000, CRC(d00294b1) SHA1(f43a4f7d13193ddbbcdef71a5085c1db0fc062d4) )
2363   ROM_REGION( 0x100000, REGION_GFX1, ROMREGION_DISPOSE ) /* Mask roms */
2364   ROM_LOAD( "b97-01.u1", 0x00000, 0x80000, CRC(d00294b1) SHA1(f43a4f7d13193ddbbcdef71a5085c1db0fc062d4) )
23652365   ROM_LOAD( "b97-02.u2", 0x80000, 0x80000, CRC(db5a7434) SHA1(71fac872b19a13a7ad25c8ad895c322ec9573fdc) )
23662366ROM_END
23672367
src/mame/drivers/plygonet.c
r2821r2822
740740   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START3)
741741   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START4)
742742
743   PORT_START
743744   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
744745   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
745746   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
src/mame/drivers/batman.c
r2821r2822
172172static INPUT_PORTS_START( batman )
173173   PORT_START      /* 26000 */
174174   PORT_BIT( 0x01ff, IP_ACTIVE_LOW, IPT_UNUSED )
175   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START1 )
176175   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
177176   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
178177   PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED )
src/mame/drivers/warriorb.c
r2821r2822
313313   PORT_BIT( 0x01, IP_ACTIVE_LOW,  IPT_UNKNOWN )
314314   PORT_BIT( 0x02, IP_ACTIVE_LOW,  IPT_UNKNOWN )
315315   PORT_BIT( 0x04, IP_ACTIVE_LOW,  IPT_UNKNOWN )
316   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Freeze") PORT_CODE(KEYCODE_F1)
316   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Freeze") PORT_CODE(KEYCODE_F1)
317317   PORT_BIT( 0x10, IP_ACTIVE_LOW,  IPT_BUTTON1 ) PORT_PLAYER(1)
318318   PORT_BIT( 0x20, IP_ACTIVE_LOW,  IPT_BUTTON2 ) PORT_PLAYER(1)
319319   PORT_BIT( 0x40, IP_ACTIVE_LOW,  IPT_BUTTON1 ) PORT_PLAYER(2)
src/mame/drivers/bloodbro.c
r2821r2822
633633static DRIVER_INIT( weststry )
634634{
635635   UINT8 *gfx = memory_region(REGION_GFX3);
636   int len = memory_region_length(REGION_GFX3);
636637   int i;
637638
638639   // invert sprite data
639   for (i = 0; i < memory_region_length(REGION_GFX3); i++)
640   for (i = 0; i < len; i++)
640641      gfx[i] = ~gfx[i];
641642}
642643
src/mame/drivers/bnstars.c
r2821r2822
9090#include "deprecat.h"
9191#include "sound/ymf271.h"
9292#include "rendlay.h"
93#include "includes/ms32.h"
9394
94/* drivers/ms32/c */
95extern void ms32_rearrange_sprites(int region);
96extern void decrypt_ms32_tx(int addr_xor,int data_xor, int region);
97extern void decrypt_ms32_bg(int addr_xor,int data_xor, int region);
95#define ms32_roz_ctrl bnstars_roz_ctrl
96#define ms32_spram bnstars_spram
9897
9998static tilemap *ms32_tx_tilemap[2];
10099static tilemap *ms32_bg_tilemap[2];
src/mame/drivers/unico.c
r2821r2822
357357   PORT_BIT(  0x0020, IP_ACTIVE_LOW, IPT_START2   )
358358   PORT_BIT(  0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN  )
359359   PORT_BIT(  0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN  )
360   PORT_BIT(  0x00ff, IP_ACTIVE_LOW, IPT_UNKNOWN  )
360   PORT_BIT(  0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN  )
361361
362362   PORT_START_TAG("DSW1")   //$80001a.b
363363   PORT_BIT(     0x00ff, IP_ACTIVE_LOW, IPT_UNKNOWN )
src/mame/drivers/blackt96.c
r0r2822
1/*
2
3    Black Touch '96
4
5
6Black Touch 96
7D.G.R.M. of Korea, 1996
8
9This game is a beat'em-up like Double Dragon
10
11PCB Layout
12----------
13
14D.G.R.M. NO 1947
15|---------------------------------------------|
16| M6295    1     8MHz                         |
17| M6295    2              2018  2018          |
18|         16C57           2018  2018          |
19|HA13001                  2018  2018          |
20|                         2018  2018          |
21|                       PAL     PAL           |
22|    6116                 5      6            |
23|J   6116                 7      8            |
24|A                                            |
25|M                                            |
26|M                                            |
27|A                                            |
28|                               9  10         |
29|    DSW1           24MHz               PAL   |
30|    DSW2                                     |
31|   PAL PAL           ACTEL     6116    11    |
32|   62256    62256    A1020B            12    |
33|   3        4        PL84C     6264    13    |
34|                               6264    14    |
35|18MHz 68000                    6264          |
36|---------------------------------------------|
37Notes:
38      68000 clock 9.000MHz [18/2]
39      M6295 clocks 1.000MHz [8/8] pin 7 high
40
41
42*/
43
44#include "driver.h"
45#include "sound/okim6295.h"
46
47VIDEO_START( blackt96 )
48{
49
50}
51
52VIDEO_UPDATE( blackt96 )
53{
54   return 0;
55}
56
57static READ16_HANDLER( blackt96_80000_r )
58{
59   return 0x0000;
60}
61
62static READ16_HANDLER( blackt96_c0000_r )
63{
64   return 0x0000;
65}
66
67static READ16_HANDLER( blackt96_e0000_r )
68{
69   return 0x0000;
70}
71
72static READ16_HANDLER( blackt96_e8000_r )
73{
74   return 0x0000;
75}
76
77static READ16_HANDLER( blackt96_f0000_r )
78{
79   return 0x0000;
80}
81
82static READ16_HANDLER( blackt96_f0008_r )
83{
84   return 0x0000;
85}
86
87static WRITE16_HANDLER( blackt96_c0000_w )
88{
89   printf("blackt96_c0000_w %04x %04x\n",data,mem_mask);
90}
91
92static ADDRESS_MAP_START( blackt96_map, ADDRESS_SPACE_PROGRAM, 16 )
93   AM_RANGE(0x000000, 0x07ffff) AM_ROM
94   AM_RANGE(0x080000, 0x080001) AM_READ(blackt96_80000_r) AM_WRITE(SMH_NOP)
95   AM_RANGE(0x0c0000, 0x0c0001) AM_READ(blackt96_c0000_r) AM_WRITE(blackt96_c0000_w)
96   AM_RANGE(0x0e0000, 0x0e0001) AM_READ(blackt96_e0000_r)
97   AM_RANGE(0x0e8000, 0x0e8001) AM_READ(blackt96_e8000_r)
98   AM_RANGE(0x0f0000, 0x0f0001) AM_READ(blackt96_f0000_r)
99   AM_RANGE(0x0f0008, 0x0f0009) AM_READ(blackt96_f0008_r)
100
101   AM_RANGE(0x100000, 0x100fff) AM_RAM
102   AM_RANGE(0x200000, 0x207fff) AM_RAM
103   AM_RANGE(0x400000, 0x400fff) AM_RAM
104   AM_RANGE(0xc00000, 0xc03fff) AM_RAM // main ram
105
106ADDRESS_MAP_END
107
108
109
110static INPUT_PORTS_START( blackt96 )
111   PORT_START
112   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
113INPUT_PORTS_END
114
115
116
117static const gfx_layout blackt96_layout =
118{
119   16,16,
120   RGN_FRAC(1,1),
121   8,
122   { 0,1,2,3,4,5,6,7 },
123   {  1024+32, 1024+40, 1024+48, 1024+56, 1024+0, 1024+8, 1024+16, 1024+24,
124      32,40,48,56,0,8,16,24 },
125   { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 8*64,9*64,10*64,11*64,12*64,13*64,14*64,15*64 },
126   32*64
127};
128
129
130static GFXDECODE_START( blackt96 )
131   GFXDECODE_ENTRY( REGION_GFX1, 0, blackt96_layout,   0x0, 2  )
132   GFXDECODE_ENTRY( REGION_GFX2, 0, blackt96_layout,   0x0, 2  )
133   GFXDECODE_ENTRY( REGION_GFX3, 0, blackt96_layout,   0x0, 2  )
134GFXDECODE_END
135
136
137static MACHINE_DRIVER_START( blackt96 )
138   MDRV_CPU_ADD_TAG("main", M68000, 18000000 /2)
139   MDRV_CPU_PROGRAM_MAP(blackt96_map,0)
140   MDRV_CPU_VBLANK_INT("main", irq1_line_hold)
141
142   MDRV_GFXDECODE(blackt96)
143
144   MDRV_SCREEN_ADD("main", RASTER)
145   MDRV_SCREEN_REFRESH_RATE(60)
146   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
147   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
148   MDRV_SCREEN_SIZE(64*8, 32*8)
149   MDRV_SCREEN_VISIBLE_AREA(8*8, 48*8-1, 2*8, 30*8-1)
150
151   MDRV_PALETTE_LENGTH(0x200)
152
153   MDRV_VIDEO_START(blackt96)
154   MDRV_VIDEO_UPDATE(blackt96)
155
156   MDRV_SPEAKER_STANDARD_STEREO("left", "right")
157
158   MDRV_SOUND_ADD(OKIM6295, 8000000/8)
159   MDRV_SOUND_CONFIG(okim6295_interface_region_1_pin7high)
160   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.47)
161   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.47)
162
163   MDRV_SOUND_ADD(OKIM6295, 8000000/8)
164   MDRV_SOUND_CONFIG(okim6295_interface_region_1_pin7high)
165   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.47)
166   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.47)
167MACHINE_DRIVER_END
168
169
170ROM_START( blackt96 )
171   ROM_REGION( 0x80000, REGION_CPU1, 0 ) /* 68000 Code */
172   ROM_LOAD16_BYTE( "3", 0x00001, 0x40000, CRC(fc2c1d79) SHA1(742478237819af16d3fd66039283202b3c07eedd) )
173   ROM_LOAD16_BYTE( "4", 0x00000, 0x40000, CRC(caff5b4a) SHA1(9a388cbb07211fa66f27082a8a5b847168c86a4f) )
174
175   ROM_REGION( 0x080000, REGION_SOUND1, 0 ) /* Samples */
176   ROM_LOAD( "1", 0x00000, 0x80000, CRC(6a934174) SHA1(087f5fa226dc68ee217f99c64d16cdf14372d44c) )
177
178   ROM_REGION( 0x040000, REGION_SOUND2, 0 ) /* Samples */
179   ROM_LOAD( "2", 0x00000, 0x40000, CRC(94009cd4) SHA1(aa36298e280c20bf86d70f3eb3fb33aca4df07e3) )
180
181   ROM_REGION( 0x180000, REGION_GFX1, 0 ) // tiles, 16x16x8
182   ROM_LOAD16_BYTE( "5", 0x00000, 0x40000, CRC(6e52c331) SHA1(31ef1d352d4ee5f7b3ef336b1f052c3a1468f22e) )
183   ROM_LOAD16_BYTE( "6", 0x00001, 0x40000, CRC(69637a5a) SHA1(a5731478856d8bb91d34b747838b2b47772864ef) )
184   ROM_LOAD16_BYTE( "7", 0x80000, 0x80000, CRC(6b04e8a8) SHA1(309ba1efd60600a30e1ae8f6e8b92939c23cd9c6) )
185   ROM_LOAD16_BYTE( "8", 0x80001, 0x80000, CRC(16c656be) SHA1(06c40c16080a97b01a638776d28f36594ce4fb3b) )
186
187   ROM_REGION( 0x100000, REGION_GFX2, 0 ) // not tiles?
188   ROM_LOAD( "11", 0x00000, 0x40000, CRC(9eb773a3) SHA1(9c91ee938438a61f5fa650ced6249e34aa5321bd) )
189   ROM_LOAD( "12", 0x40000, 0x40000, CRC(8894e608) SHA1(389974a0b208b7cbf7d5f83641ddc058ad5ebe87) )
190   ROM_LOAD( "13", 0x80000, 0x40000, CRC(0acceb9d) SHA1(e8a85c7eab45d84613ac37a9b7ffbc45b44eb2e5) )
191   ROM_LOAD( "14", 0xc0000, 0x40000, CRC(b5e3de25) SHA1(33ac5602ab6bcadc8b0d1aa805a3bdce0b67c215) )
192
193   ROM_REGION( 0x100000, REGION_GFX3, 0 ) // not tiles?
194   ROM_LOAD( "9",  0x00000, 0x10000, CRC(81a4cf4c) SHA1(94b2bbcbc8327d9babbc3b222bd88954c7e7b80e) )
195   ROM_LOAD( "10", 0x10000, 0x10000, CRC(b78232a2) SHA1(36a4f01011faf64e46b73f0082ab04843ac8b0e2) )
196ROM_END
197
198GAME( 1996, blackt96,    0,        blackt96,    blackt96,    0, ROT0,  "D.G.R.M.", "Black Touch '96", GAME_NOT_WORKING )
src/mame/drivers/realbrk.c
r2821r2822
324324   PORT_BIT(  0x8000, IP_ACTIVE_HIGH, IPT_UNKNOWN )
325325
326326   PORT_START
327   PORT_BIT(     0x00bf, IP_ACTIVE_LOW, IPT_UNUSED )
327   PORT_BIT(     0x003f, IP_ACTIVE_LOW, IPT_UNUSED )
328328   PORT_BIT(     0x00c0, IP_ACTIVE_HIGH, IPT_UNUSED )/*pkgnsh wants these two bits to be 0*/
329329   PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
330330   PORT_DIPSETTING(      0x0100, DEF_STR( Off ) )
src/mame/drivers/gatron.c
r2821r2822
88
99    Games running on this hardware:
1010
11    * Card Games??,  1983, Game-A-Tron.
12    * Slots Game??,  1983, Game-A-Tron.
11    * Poker 4-1,  1983, Game-A-Tron.
12    * Pull Tabs,  1983, Game-A-Tron.
1313
1414
15    The names of both games are unknown. Only were arbitrary called "Card Games"
16    and "Slot Game" till we can find some evidence of the real names.
15    The names of both games are not confirmed. We are calling them "Poker 4-1"
16    and "Pull Tabs" till we can find some evidence of the real names.
1717
1818
1919*******************************************************************************
r2821r2822
2323    ---------------
2424
2525
26    * PCB1: SLOTS GAME?.
26    * PCB1: PULL TABS.
2727
2828    Board silkscreend:
2929
r2821r2822
5050
5151
5252
53    * PCB2: CARD GAMES?.
53    * PCB2: POKER 4-1.
5454
5555    Board silkscreend:
5656
r2821r2822
8989    You must to RESET (F3) the machine to initialize the NVRAM properly.
9090
9191
92    * Card Games:
92    * Poker 4-1:
9393
9494    Pressing SERVICE 1 (key 9) you enter the Test/Setting Mode. You can test
9595    inputs there, and change all the game settings. Press "DISCARD 1" (key Z)
r2821r2822
120120    The rest of buttons are self-explanatory.
121121
122122
123    * Slots Game:
123    * Pull Tabs:
124124
125125    Pressing SERVICE 1 (key 9) you enter the Test/Setting Mode. You can test
126126    inputs there, and change all the game settings. Press "SUPER STAR TICKET"
r2821r2822
160160    DRIVER UPDATES:
161161
162162
163    [2008-05-31]
164
165    - Renamed the games to "Poker 4-1" and "Pull Tabs"
166      as shown in the ROMs stickers.
167    - Renamed the ROMs in each set according to their own stickers.
168    - Moved the driver into gametron.a group.
169    - Added the missing input port C to 8255 PPI I/O chip.
170      Poker41 and pulltabs don't make use of it, but is present in the Test/Setting Mode.
171    - Updated technical notes.
172
163173    [2008-05-10]
164174
165175    - Initial release.
r2821r2822
242252{
243253   input_port_0_r,   /* Port A read */
244254   input_port_1_r,   /* Port B read */
245   NULL,         /* Port C read */
255   input_port_2_r,   /* Port C read */
246256   NULL,         /* Port A write */
247257   NULL,         /* Port B write */
248258   NULL,         /* Port C write */
r2821r2822
292302*      Input Ports       *
293303*************************/
294304
295static INPUT_PORTS_START( gatcards )
305static INPUT_PORTS_START( poker41 )
296306   PORT_START_TAG("IN0")
297307   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("Discard 4") PORT_CODE(KEYCODE_V)
298308   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Bet/Ante") PORT_CODE(KEYCODE_N)
r2821r2822
312322   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Service 1 (Test/Settings)") PORT_CODE(KEYCODE_9)
313323   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
314324   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON5 )  PORT_NAME("Discard 1") PORT_CODE(KEYCODE_Z)
325
326   PORT_START_TAG("IN2")   /* disabled */
327   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
328   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
329   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
330   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
331   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
332   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
333   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
334   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
315335INPUT_PORTS_END
316336
317static INPUT_PORTS_START( gatslots )
337static INPUT_PORTS_START( pulltabs )
318338   PORT_START_TAG("IN0")
319339   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
320340   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Ante") PORT_CODE(KEYCODE_1)
r2821r2822
334354   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Service 1 (Test/Settings)") PORT_CODE(KEYCODE_9)
335355   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
336356   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 )  PORT_NAME("Super Star Ticket") PORT_CODE(KEYCODE_Z)
357
358   PORT_START_TAG("IN2")   /* disabled */
359   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
360   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
361   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
362   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
363   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
364   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
365   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
366   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
337367INPUT_PORTS_END
338368
339369
r2821r2822
405435*        Rom Load        *
406436*************************/
407437
408ROM_START( gatcards )
438ROM_START( poker41 )
409439   ROM_REGION( 0x10000, REGION_CPU1, 0 )
410   ROM_LOAD( "gat1.0",      0x0000, 0x2000, CRC(8361fccd) SHA1(4faae6bb3104c1f4a0939d613966085d7e34c1df))
411   ROM_LOAD( "gat1.8",      0x2000, 0x1000, CRC(61e71f31) SHA1(b8d162a47752cff7412b3920ec9dd7a469e81e62) )
440   ROM_LOAD( "poker.u00",      0x0000, 0x2000, CRC(8361fccd) SHA1(4faae6bb3104c1f4a0939d613966085d7e34c1df))
441   ROM_LOAD( "poker-4-1.u08",   0x2000, 0x1000, CRC(61e71f31) SHA1(b8d162a47752cff7412b3920ec9dd7a469e81e62) )
412442
413443   ROM_REGION( 0x3000, REGION_GFX1, ROMREGION_DISPOSE )
414   ROM_LOAD( "gat1.33",      0x0000, 0x1000, CRC(3f8a2d59) SHA1(d61dce33aa8637105905830e2f37c1052c441194) )
415   ROM_LOAD( "gat1.32",      0x1000, 0x1000, CRC(3e7772b2) SHA1(c7499ff148e5a9cbf0958820c41ea09a843ab355) )
416   ROM_LOAD( "gat1.31",      0x2000, 0x1000, CRC(18d090ec) SHA1(3504f18b3984d16545dbe61a03fbf6b8e2027150) )
444   ROM_LOAD( "black.u33",      0x0000, 0x1000, CRC(3f8a2d59) SHA1(d61dce33aa8637105905830e2f37c1052c441194) )
445   ROM_LOAD( "poker-g.u32",   0x1000, 0x1000, CRC(3e7772b2) SHA1(c7499ff148e5a9cbf0958820c41ea09a843ab355) )
446   ROM_LOAD( "poker-r.u31",   0x2000, 0x1000, CRC(18d090ec) SHA1(3504f18b3984d16545dbe61a03fbf6b8e2027150) )
417447ROM_END
418448
419ROM_START( gatslots )
449ROM_START( pulltabs )
420450   ROM_REGION( 0x10000, REGION_CPU1, 0 )
421   ROM_LOAD( "gat.0",      0x0000, 0x2000, CRC(7cfd490d) SHA1(8eb360f8f4806a4281dae12236d30aa86d00993d) )
451   ROM_LOAD( "pull-tabs-1-90.u00",   0x0000, 0x2000, CRC(7cfd490d) SHA1(8eb360f8f4806a4281dae12236d30aa86d00993d) )
422452
423453   ROM_REGION( 0x3000, REGION_GFX1, ROMREGION_DISPOSE )
424   ROM_LOAD( "gat.33",      0x0000, 0x1000, CRC(3505cec1) SHA1(98ab0383c4be382aea81ab93433f2f29a075f65d) )
425   ROM_LOAD( "gat.32",      0x1000, 0x1000, CRC(4a3f4f36) SHA1(3dc29f78b7df1a433d0b39bfeaa227615e70ceed) )
426   ROM_LOAD( "gat.31",      0x2000, 0x1000, CRC(6d1b80f4) SHA1(f2da4b4ae1eb05f9ea02e7495ee8110698cc5d1b) )
454   ROM_LOAD( "pt-3b-v.u33",   0x0000, 0x1000, CRC(3505cec1) SHA1(98ab0383c4be382aea81ab93433f2f29a075f65d) )
455   ROM_LOAD( "pt-2g-v.u32",   0x1000, 0x1000, CRC(4a3f4f36) SHA1(3dc29f78b7df1a433d0b39bfeaa227615e70ceed) )
456   ROM_LOAD( "pt-1r-v.u31",   0x2000, 0x1000, CRC(6d1b80f4) SHA1(f2da4b4ae1eb05f9ea02e7495ee8110698cc5d1b) )
427457ROM_END
428458
429459
r2821r2822
432462*************************/
433463
434464/*    YEAR  NAME      PARENT  MACHINE  INPUT     INIT  ROT    COMPANY        FULLNAME      FLAGS */
435GAME( 1983, gatcards, 0,      gat,     gatcards, 0,    ROT0, "Game-A-Tron", "Card Games?", GAME_NO_SOUND )
436GAME( 1983, gatslots, 0,      gat,     gatslots, 0,    ROT0, "Game-A-Tron", "Slots Game?", GAME_NO_SOUND )
465GAME( 1983, poker41,  0,      gat,     poker41,  0,    ROT0, "Game-A-Tron", "Poker 4-1",   GAME_NO_SOUND )
466GAME( 1983, pulltabs, 0,      gat,     pulltabs, 0,    ROT0, "Game-A-Tron", "Pull Tabs",   GAME_NO_SOUND )
src/mame/drivers/dreamwld.c
r2821r2822
239239{
240240   /* 0x30000-0x3ffff is banked.
241241        banks are at 0x30000,0x40000,0x50000 and 0x60000 in rom */
242   UINT8 *sound = chip?memory_region(REGION_SOUND1):memory_region(REGION_SOUND2);
242   UINT8 *sound = memory_region(chip ? REGION_SOUND1 : REGION_SOUND2);
243243   logerror("OKI%d: set bank %02x\n",chip,bank);
244244   memcpy(sound+0x30000, sound+0xb0000+0x10000*bank, 0x10000);
245245}
src/mame/drivers/galdrvr.c
r2821r2822
19711971   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
19721972   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
19731973   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
1974   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
1974   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
19751975INPUT_PORTS_END
19761976
19771977
src/mame/drivers/megazone.c
r2821r2822
77***************************************************************************/
88
99#include "driver.h"
10#include "machine/konami1.h"
1011#include "cpu/m6809/m6809.h"
1112#include "cpu/i8039/i8039.h"
1213#include "cpu/z80/z80.h"
r2821r2822
1516#include "sound/flt_rc.h"
1617
1718
18void konami1_decode(void);
19
2019extern UINT8 *megazone_scrollx;
2120extern UINT8 *megazone_scrolly;
2221
r2821r2822
588587
589588static DRIVER_INIT( megazone )
590589{
591   konami1_decode();
590   konami1_decode(0);
592591}
593592
594593/* these just display a Konami copyright, no logo */
src/mame/drivers/deco156.c
r2821r2822
1313*/
1414
1515#define DE156CPU ARM
16extern void decrypt156(void);
17
1816#include "driver.h"
1917#include "decocrpt.h"
2018#include "deco32.h"
r2821r2822
690688static DRIVER_INIT( hvysmsh )
691689{
692690   deco56_decrypt(REGION_GFX1); /* 141 */
693   decrypt156();
691   deco156_decrypt();
694692   descramble_sound(REGION_SOUND2);
695693}
696694
697695static DRIVER_INIT( wcvol95 )
698696{
699697   deco56_decrypt(REGION_GFX1); /* 141 */
700   decrypt156();
698   deco156_decrypt();
701699   descramble_sound(REGION_SOUND1);
702700}
703701
src/mame/drivers/toki.c
r2821r2822
750750static DRIVER_INIT( tokib )
751751{
752752   UINT8 *temp = malloc_or_die(65536 * 2);
753   int i, offs;
753   int i, offs, len;
754   UINT8 *rom;
754755
755756   /* invert the sprite data in the ROMs */
756   for (i = 0; i < memory_region_length(REGION_GFX2); i++)
757      memory_region(REGION_GFX2)[i] ^= 0xff;
757   len = memory_region_length(REGION_GFX2);
758   rom = memory_region(REGION_GFX2);
759   for (i = 0; i < len; i++)
760      rom[i] ^= 0xff;
758761
759762   /* merge background tile graphics together */
760      for (offs = 0; offs < memory_region_length(REGION_GFX3); offs += 0x20000)
763      len = memory_region_length(REGION_GFX3);
764      rom = memory_region(REGION_GFX3);
765      for (offs = 0; offs < len; offs += 0x20000)
761766      {
762         UINT8 *base = &memory_region(REGION_GFX3)[offs];
767         UINT8 *base = &rom[offs];
763768         memcpy (temp, base, 65536 * 2);
764769         for (i = 0; i < 16; i++)
765770         {
r2821r2822
769774            memcpy (&base[0x18000 + i * 0x800], &temp[0x1800 + i * 0x2000], 0x800);
770775         }
771776      }
772      for (offs = 0; offs < memory_region_length(REGION_GFX4); offs += 0x20000)
777      len = memory_region_length(REGION_GFX4);
778      rom = memory_region(REGION_GFX4);
779      for (offs = 0; offs < len; offs += 0x20000)
773780      {
774         UINT8 *base = &memory_region(REGION_GFX4)[offs];
781         UINT8 *base = &rom[offs];
775782         memcpy (temp, base, 65536 * 2);
776783         for (i = 0; i < 16; i++)
777784         {
src/mame/drivers/dwarfd.c
r2821r2822
743743static DRIVER_INIT(dwarfd)
744744{
745745   int i;
746   UINT8 *src, *dst;
746747
747748   /* expand gfx roms */
749   src    = memory_region       ( REGION_GFX1 );
750   dst    = memory_region       ( REGION_GFX2 );
748751   for (i=0;i<0x4000;i++)
749752   {
750      UINT8 *src    = memory_region       ( REGION_GFX1 );
751      UINT8 *dst    = memory_region       ( REGION_GFX2 );
752
753753      UINT8 dat;
754754      dat = (src[i]&0xf0)>>0;
755755      dst[i*2] = dat;
r2821r2822
759759   }
760760
761761   /* use low bit as 'interpolation' bit */
762   src    = memory_region       ( REGION_GFX2 );
762763   for (i=0;i<0x8000;i++)
763764   {
764      UINT8 *src    = memory_region       ( REGION_GFX2 );
765765      if (src[i]&0x10)
766766      {
767767         src[i] = src[i]&0xe0;
src/mame/drivers/junofrst.c
r2821r2822
7979
8080#include "driver.h"
8181#include "tutankhm.h"
82#include "machine/konami1.h"
8283#include "cpu/m6809/m6809.h"
8384#include "cpu/i8039/i8039.h"
8485#include "cpu/z80/z80.h"
r2821r2822
8788#include "sound/flt_rc.h"
8889
8990
90void konami1_decode(void);
91
9291static int i8039_status;
9392
9493WRITE8_HANDLER( tutankhm_sh_irqtrigger_w );
r2821r2822
435434
436435static DRIVER_INIT( junofrst )
437436{
438   extern UINT8 *konami1_decrypted;
437   UINT8 *decrypt = konami1_decode(0);
439438
440   konami1_decode();
441
442439   memory_configure_bank(1, 0, 16, memory_region(REGION_CPU1) + 0x10000, 0x1000);
443   memory_configure_bank_decrypted(1, 0, 16, konami1_decrypted + 0x10000, 0x1000);
440   memory_configure_bank_decrypted(1, 0, 16, decrypt + 0x10000, 0x1000);
444441}
445442
446443
src/mame/drivers/galaga.c
r2821r2822
30503050{
30513051   /* swap bytes for flipped character so we can decode them together with normal characters */
30523052   UINT8 *rom = memory_region(REGION_GFX1);
3053   int i;
3053   int i, len = memory_region_length(REGION_GFX1);
30543054
3055   for (i = 0;i < memory_region_length(REGION_GFX1);i++)
3055   for (i = 0;i < len;i++)
30563056   {
30573057      if ((i & 0x0808) == 0x0800)
30583058      {
src/mame/drivers/8080bw.c
r2821r2822
893893static READ8_HANDLER( sfl_input_r )
894894{
895895   sfl_int^=0x80;//vblank flag ?
896   return sfl_int|input_port_read_indexed(machine, 1);
896   return sfl_int|input_port_read(machine, "DSW0");
897897}
898898
899899static ADDRESS_MAP_START( sflush_map, ADDRESS_SPACE_PROGRAM, 8 )
src/mame/drivers/vsnes.c
r2821r2822
14231423   PORT_BIT ( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )   /* bit 0 of dsw goes here */
14241424   PORT_BIT ( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )   /* bit 1 of dsw goes here */
14251425   PORT_BIT ( 0x20, IP_ACTIVE_HIGH, IPT_COIN1 )
1426   PORT_BIT ( 0x60, IP_ACTIVE_HIGH, IPT_COIN2 )
1426   PORT_BIT ( 0x40, IP_ACTIVE_HIGH, IPT_COIN2 )
14271427   PORT_BIT ( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
14281428
14291429   PORT_START /* DSW0 - bit 0 and 1 read from bit 3 and 4 on $4016, rest of the bits read on $4017 */
src/mame/drivers/rollrace.c
r2821r2822
101101   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) // Punch
102102   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
103103   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
104
104105   PORT_START
105106   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
106107   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
r2821r2822
108109   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
109110   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL // Jump
110111   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_COCKTAIL // Punch
112   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
111113   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
112   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
113114
114115   PORT_START
115116   PORT_BIT( 0x01, IP_ACTIVE_HIGH,IPT_COIN1 )
src/mame/drivers/sidearms.c
r2821r2822
596596   PORT_START_TAG("IN6")
597597   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
598598   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
599   PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_BUTTON4 )
600599   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
601600   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
602601   PORT_BIT( 0x10, IP_ACTIVE_HIGH,IPT_VBLANK )
r2821r2822
12281227GAME( 1988, turtshik, turtship, turtship, turtship, turtship, ROT0,   "Philko", "Turtle Ship (Korea)", 0 )
12291228GAME( 1989, dyger,    0,        turtship, dyger,    dyger,    ROT270, "Philko", "Dyger (Korea set 1)", 0 )
12301229GAME( 1989, dygera,   dyger,    turtship, dyger,    dyger,    ROT270, "Philko", "Dyger (Korea set 2)", 0 )
1231GAME( 1989, twinfalc, 0,        whizz,      whizz,    whizz,    ROT0,   "Philko (Poara Enterprises license)", "Twin Falcons", 0 )
1232GAME( 1989, whizz,    twinfalc, whizz,      whizz,    whizz,    ROT0,   "Philko", "Whizz", 0 )
1230GAME( 1989, twinfalc, 0,        whizz,    whizz,    whizz,    ROT0,   "Philko (Poara Enterprises license)", "Twin Falcons", 0 )
1231GAME( 1989, whizz,    twinfalc, whizz,    whizz,    whizz,    ROT0,   "Philko", "Whizz", 0 )
12331232
12341233
src/mame/drivers/jack.c
r2821r2822
386386   PORT_START_TAG("IN2")
387387   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 )
388388   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 )
389   PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
389   PORT_BIT( 0x1c, IP_ACTIVE_HIGH, IPT_UNUSED )
390390   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN1 )
391   PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
391   PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_UNUSED )
392392
393393   PORT_START_TAG("IN3")
394394   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_2WAY
src/mame/drivers/dietgo.c
r2821r2822
1616READ16_HANDLER( dietgo_104_prot_r );
1717WRITE16_HANDLER( dietgo_104_prot_w );
1818
19extern void deco102_decrypt(int region, int address_xor, int data_select_xor, int opcode_select_xor);
2019
21
2220static ADDRESS_MAP_START( dietgo_map, ADDRESS_SPACE_PROGRAM, 16 )
2321   AM_RANGE(0x000000, 0x07ffff) AM_ROM
2422   AM_RANGE(0x200000, 0x20000f) AM_WRITE(SMH_RAM) AM_BASE(&deco16_pf12_control)
src/mame/drivers/lvcards.c
r2821r2822
399399   PORT_DIPSETTING(    0x07, "90%" )
400400   PORT_DIPSETTING(    0x01, "94%" )
401401   PORT_DIPSETTING(    0x00, "98%" )
402   PORT_BIT( 0x38, IP_ACTIVE_LOW, IPT_UNUSED )
402   PORT_BIT( 0x18, IP_ACTIVE_LOW, IPT_UNUSED )
403403   PORT_DIPNAME( 0x60, 0x20, "Payment Method" )
404404   PORT_DIPSETTING(    0x00, "Credit In/Coin Out" )
405405   PORT_DIPSETTING(    0x20, "Coin In/Coin Out" )
src/mame/drivers/tecmosys.c
r2821r2822
11/* Tecmo System
2 Driver by Farfetch & David Haywood
2 Driver by Farfetch, David Haywood & Tomasz Slanina
3  Protection simulation by nuapete
34
4can't do anything with this, its protected and expects to read back 68k code :-(
5 ToDo:
6  Dump / Decap MCUs to allow for proper protection emulation.
7  Fix Sound (sound roms should be good, do they need descrambling, or is our sound core bad?
8     some YMZ280B samples sound -terrible-)
59
10
611T.Slanina 20040530 :
712 - preliminary gfx decode,
813 - Angel Eyes - patched interrupt level1 vector
r2821r2822
1116 - added hacks to see more gfx (press Z or X)
1217 - palette (press X in angel eyes to see 'color bar chack'(!))
1318 - watchdog (?) simulation
19
20 20080528
21 - Removed ROM patches and debug keypresses
22 - Added protection simulation in machine/tecmosys.c
23 - Fixed inputs
24 - Added watchdog
25
26   To enter test mode, you have to press the test switch before you insert any coins.
27
1428*/
1529
1630
r2821r2822
2640
2741TECMO SYSTEM BOARD A
2842|-------------------------------------------------------------------------|
29|  LM324  UPC452C      16.9MHz        |--------|    |--------|  6264  |
30| TA8205 LM324  YAC513  YMF262 YMZ280B  |TECMO  |    |TECMO  |  6264  |
31|        LM324  M6295  UPC452C          |AA03-8431    |AA02-1927        |
32|                      YAC512          |        |    |        |        |
33|                                        |--------|    |--------|        |
34|        Z80  6264 28MHz 14.31818MHz                  |--------|        |
35|                    16MHz              62256          |TECMO  |        |
36|            TA8030                    62256          |AA02-1927  6264  |
37|                                                      |        |  6264  |
38|J  93C46                              |--------|    |--------|        |
39|A                                      |TECMO  |    |--------|        |
40|M                                      |AA03-8431    |TECMO  |        |
41|M          68000                        |        |    |AA02-1927        |
42|A                                      |--------|    |        |  6264  |
43|                  PAL              6116              |--------|  6264  |
44|                                    6116              |--------|        |
45|  |--------|                                          |TECMO  |        |
46|  |TECMO  |                      PAL                |AA02-1927        |
47|  |AA03-8431  62256                                  |        |  6264  |
48|  |        |  62256                                  |--------|  6264  |
49|  |--------|                                |---------|                |
43|  LM324  UPC452C      16.9MHz          |--------|    |--------|    6264  |
44| TA8205 LM324  YAC513 YMF262 YMZ280B   |TECMO   |    |TECMO   |    6264  |
45|        LM324  M6295  UPC452C          |AA03-8431    |AA02-1927          |
46|                      YAC512           |        |    |        |          |
47|                                       |--------|    |--------|          |
48|        Z80  6264 28MHz 14.31818MHz                  |--------|          |
49|                    16MHz             62256          |TECMO   |          |
50|            TA8030                    62256          |AA02-1927    6264  |
51|                                                     |        |    6264  |
52|J  93C46                               |--------|    |--------|          |
53|A                                      |TECMO   |    |--------|          |
54|M                                      |AA03-8431    |TECMO   |          |
55|M          68000                       |        |    |AA02-1927          |
56|A                                      |--------|    |        |    6264  |
57|                  PAL              6116              |--------|    6264  |
58|                                    6116             |--------|          |
59|  |--------|                                         |TECMO   |          |
60|  |TECMO   |                     PAL                 |AA02-1927          |
61|  |AA03-8431  62256                                  |        |    6264  |
62|  |        |  62256                                  |--------|    6264  |
63|  |--------|                                  |---------|                |
5064|                                              |TECMO    |                |
5165|                                              |AA03-8431|                |
52|                                              |        |                |
66|                                              |        |                |
5367|                                              |---------|          424260|
5468|                                              62256 62256          424260|
5569|-------------------------------------------------------------------------|
r2821r2822
6579
6680TECMO SYSTEM BOARD B2
6781|-------------------------------------------------------------------------|
68|    T201_DIP42_MASK.UBB1                                                |
82|    T201_DIP42_MASK.UBB1                                                |
6983| |----|                                              T202_DIP42_MASK.UBC1|
70| |*  |                                                                  |
84| |*  |                                                                  |
7185| |----|                                                                  |
72|                                                                        |
73|  T003_2M_EPROM.UZ1                        T101_SOP44.UAH1            |
74|                                                                        |
75|                                            T301_DIP42_MASK.UBD1        |
76|                                                                        |
77|                                                                        |
78|                                                                        |
79|  T401_DIP42_MASK.UYA1      T104_SOP44.UCL1    T001_4M_EPROM.UPAU1    |
86|                                                                         |
87|  T003_2M_EPROM.UZ1                        T101_SOP44.UAH1               |
88|                                                                         |
89|                                            T301_DIP42_MASK.UBD1         |
90|                                                                         |
91|                                                                         |
92|                                                                         |
93|  T401_DIP42_MASK.UYA1      T104_SOP44.UCL1    T001_4M_EPROM.UPAU1       |
8094|                              T103_SOP44.UBL1                            |
81|  T501_DIP32_MASK.UAD1      T102_SOP44.UAL1                            |
95|  T501_DIP32_MASK.UAD1      T102_SOP44.UAL1                              |
8296|                                                  T002_4M_EPROM.UPAL1    |
8397|-------------------------------------------------------------------------|
8498Notes:
85      * - Unknown QFP64 microcontroller marked 'TECMO SC432146FU E23D 185 SSAB9540B'
99      * - QFP64 microcontroller marked 'TECMO SC432146FU E23D 185 SSAB9540B'
100          this is a 68HC11A8 with 8k ROM, 512 bytes EEPROM and 256 bytes on-chip RAM.
86101          Clocks: pin 33 - 8MHz, pin 31: 8MHz, pin 29 - 2MHz
87102          GND on pins 49, 23, 24, 27
88103          Power on pins 55, 25
r2821r2822
100115Others:
10111693C46 EEPROM (settings are stored to this)
102117
103EPROMs:
104t001upau.bin - Main program (even) (27c4001)
105t002upal.bin - Main program (odd)  (27c4001)
118ROMs:
106119
107t003uz1.bin - Sound program (27c2001)
120name            type
121t001.upau1      27c040 dip32 eprom
122t002.upal1      27c040 dip32 eprom
123t003.uz1        27c2001 dip32 eprom
108124
109Mask ROMs:
110t101uah1.j66 - Graphics (23c16000 SOP)
111t102ual1.j67 |
112t103ubl1.j08 |
113t104ucl1.j68 /
125t101.uah1       23c16000 sop44 maskrom
126t102.ual1       23c16000 sop44 maskrom
127t103.ubl1       23c32000 sop44 maskrom
128t104.ucl1       23c16000 sop44 maskrom
129t201.ubb1       23c8000 dip42 maskrom
130t202.ubc1       23c8000 dip42 maskrom
131t301.ubd1       23c8000 dip42 maskrom
132t401.uya1       23c16000 dip42 maskrom
133t501.uad1       23c4001 dip32 maskrom
114134
115t201ubb1.w61 - Graphics (23c8000)
116t202ubc1.w62 /
117
118t301ubd1.w63 - Graphics (23c8000)
119
120t401uya1.w16 - YMZ280B Samples (23c16000)
121
122t501uad1.w01 - M6295 Samples (23c4001)
123
124135*/
125136
126137/*
r2821r2822
172183
173184#include "driver.h"
174185#include "machine/eeprom.h"
186#include "tecmosys.h"
175187#include "cpu/m68000/m68k.h"
176188#include "sound/okim6295.h"
177189#include "sound/262intf.h"
178190#include "sound/ymz280b.h"
191#include "deprecat.h"
179192
180static int gametype;
193static UINT16* tecmosys_spriteram;
194static UINT16* tilemap_paletteram16;
195static UINT16* bg2tilemap_ram;
196static UINT16* bg1tilemap_ram;
197static UINT16* bg0tilemap_ram;
198static UINT16* fgtilemap_ram;
199static UINT16* bg0tilemap_lineram;
200static UINT16* bg1tilemap_lineram;
201static UINT16* bg2tilemap_lineram;
181202
182static tilemap *txt_tilemap;
183static TILE_GET_INFO( get_tile_info )
203static UINT16* tecmosys_a80000regs;
204static UINT16* tecmosys_b00000regs;
205
206static UINT16* tecmosys_c00000regs;
207static UINT16* tecmosys_c80000regs;
208static UINT16* tecmosys_880000regs;
209static int tecmosys_spritelist;
210
211static bitmap_t *sprite_bitmap;
212static bitmap_t *tmp_tilemap_composebitmap;
213static bitmap_t *tmp_tilemap_renderbitmap;
214
215
216static MACHINE_RESET( deroon );
217
218static tilemap *bg0tilemap;
219static TILE_GET_INFO( get_bg0tile_info )
184220{
185221
186222   SET_TILE_INFO(
187         0,
188         videoram16[2*tile_index+1],
189         videoram16[2*tile_index]&0xf,
190         0);
223         1,
224         bg0tilemap_ram[2*tile_index+1],
225         (bg0tilemap_ram[2*tile_index]&0x3f),
226         TILE_FLIPYX((bg0tilemap_ram[2*tile_index]&0xc0)>>6));
191227}
192228
229static WRITE16_HANDLER( bg0_tilemap_w )
230{
231   COMBINE_DATA(&bg0tilemap_ram[offset]);
232   tilemap_mark_tile_dirty(bg0tilemap,offset/2);
233}
193234
235static tilemap *bg1tilemap;
236static TILE_GET_INFO( get_bg1tile_info )
237{
194238
195static UINT16* protram;
239   SET_TILE_INFO(
240         2,
241         bg1tilemap_ram[2*tile_index+1],
242         (bg1tilemap_ram[2*tile_index]&0x3f),
243         TILE_FLIPYX((bg1tilemap_ram[2*tile_index]&0xc0)>>6));
244}
196245
197static UINT8 device[0x10000];
198static UINT32 device_read_ptr = 0;
199static UINT32 device_write_ptr = 0;
246static WRITE16_HANDLER( bg1_tilemap_w )
247{
248   COMBINE_DATA(&bg1tilemap_ram[offset]);
249   tilemap_mark_tile_dirty(bg1tilemap,offset/2);
250}
200251
201enum DEV_STATUS
252static tilemap *bg2tilemap;
253static TILE_GET_INFO( get_bg2tile_info )
202254{
203   DS_CMD,
204   DS_WRITE,
205   DS_WRITE_ACK,
206   DS_READ,
207   DS_READ_ACK
208};
209255
210static UINT8 device_status = DS_CMD;
256   SET_TILE_INFO(
257         3,
258         bg2tilemap_ram[2*tile_index+1],
259         (bg2tilemap_ram[2*tile_index]&0x3f),
260         TILE_FLIPYX((bg2tilemap_ram[2*tile_index]&0xc0)>>6));
261}
211262
212static READ16_HANDLER(reg_f80000_r)
263static WRITE16_HANDLER( bg2_tilemap_w )
213264{
214   UINT16 dt;
215   // 0 means ok, no errors. -1 means error
216   if (device_status == DS_CMD)
217      return 0;
265   COMBINE_DATA(&bg2tilemap_ram[offset]);
266   tilemap_mark_tile_dirty(bg2tilemap,offset/2);
267}
218268
219   if (device_status == DS_WRITE_ACK)
220   {
221      // Notice, this is the maximum. I think the device lets 68k just writes 4/5 bytes,
222      // they contain "LUNA". Then, it starts sending to the 68k a bunch of stuff, including
223      // 68k code.
224      if (device_write_ptr == 0x10000)
225      {
226//          logerror("DEVICE write finished\n");
227         device_status = DS_READ_ACK;
228         device_write_ptr = 0;
229         device_read_ptr = 0;
230      }
231      else
232         device_status = DS_WRITE;
269static tilemap *txt_tilemap;
270static TILE_GET_INFO( get_tile_info )
271{
233272
234      return 0;
235   }
273   SET_TILE_INFO(
274         0,
275         fgtilemap_ram[2*tile_index+1],
276         (fgtilemap_ram[2*tile_index]&0x3f),
277         TILE_FLIPYX((fgtilemap_ram[2*tile_index]&0xc0)>>6));
278}
236279
237   if (device_status == DS_WRITE)
280static WRITE16_HANDLER( fg_tilemap_w )
281{
282   COMBINE_DATA(&fgtilemap_ram[offset]);
283   tilemap_mark_tile_dirty(txt_tilemap,offset/2);
284}
285
286
287// It looks like this needs a synch between z80 and 68k ??? See z80:006A-0091
288static READ16_HANDLER( sound_r )
289{
290   if (ACCESSING_BITS_0_7)
238291   {
239      logerror("UNEXPECTED read DS_WRITE (write ptr %x)\n", device_write_ptr);
240      return 0;
292      return soundlatch2_r( machine,  0 );
241293   }
242294
295   return 0;
296}
243297
244   if (device_status == DS_READ_ACK)
298static WRITE16_HANDLER( sound_w )
299{
300   if (ACCESSING_BITS_0_7)
245301   {
246//      logerror("Read ACK\n");
247      device_status = DS_READ;
248      return 0;
302      soundlatch_w(machine,0x00,data & 0xff);
303      cpunum_set_input_line(machine, 1,INPUT_LINE_NMI,PULSE_LINE);
249304   }
305}
250306
251   dt = device[device_read_ptr];
307/*
308    880000 and 880002 might be video related,
309    see sub @ 68k:002e5e where they are written if the screen is set to inverted.
310    Also, irq code at 22c4 :
311    - 880000 & 00, execute irq code
312    - 880000 & 01, scroll?
313    - 880000 & 03, crash
314*/
252315
253//  logerror("DEVICE read %x: %x (at %x)\n", device_read_ptr, dt, cpunum_get_pc(0));
254316
255   device_read_ptr++;
256   device_read_ptr &= 0xFFFF;
317static WRITE16_HANDLER( unk880000_w )
318{
319   COMBINE_DATA(&tecmosys_880000regs[offset]);
257320
258   device_status = DS_READ_ACK;
321   switch( offset )
322   {
323      case 0x00/2:
324         break; // global x scroll for sprites?
259325
260   return dt<<8;
261}
326      case 0x02/2:
327         break; // global y scroll for sprites
262328
263// Write 0x13
264// Read something (acknowledge? If -1, write -1 and restart)
265// Write data
266// Read value (!=1 is ok)
329      case 0x08/2:
330         tecmosys_spritelist = data & 0x3; // which of the 4 spritelists to use (buffering)
331         break;
267332
268static READ16_HANDLER(reg_b80000_r)
269{
270   if (ACCESSING_BITS_8_15)
271   {
272      // Bit 7: 0 = ready to write
273      // Bit 6: 0 = ready to read
274      return 0;
333      case 0x22/2:
334         watchdog_reset( machine );
335         //logerror( "watchdog_w( %06x, %04x ) @ %06x\n", (offset * 2)+0x880000, data, activecpu_get_pc() );
336         break;
337
338      default:
339         logerror( "unk880000_w( %06x, %04x ) @ %06x\n", (offset * 2)+0x880000, data, activecpu_get_pc() );
340         break;
275341   }
276
277   return 0;
278342}
279343
280static WRITE16_HANDLER(reg_e80000_w)
344static READ16_HANDLER( unk880000_r )
281345{
282   // Only LSB
283   data >>= 8;
346   //UINT16 ret = tecmosys_880000regs[offset];
284347
285   if (device_status == DS_CMD)
286   {
287      switch (data)
288      {
289      case 0x13:
290//          logerror("DEVICE mode WRITE (cmd 0x13)\n");
291         device_status = DS_WRITE;
292         device_write_ptr = 0;
293         break;
294      }
348   logerror( "unk880000_r( %06x ) @ %06x = %04x\n", (offset * 2 ) +0x880000, activecpu_get_pc(), tecmosys_880000regs[offset] );
295349
296      return;
297   }
350   /* this code allows scroll regs to be updated, but tkdensho at least resets perodically */
298351
299   // @@@ Should skip the writes while in read mode?
300   if (device_status == DS_READ || device_status == DS_READ_ACK)
352   switch( offset )
301353   {
302//      logerror("EEPROM write %x: %x\n", device_write_ptr, data);
303      return;
354      case 0:
355         if ( video_screen_get_vpos(machine->primary_screen) >= 240) return 0;
356         else return 1;
357
358      default:
359         return 0;
304360   }
361}
305362
306   device[device_write_ptr] = (UINT8)data;
307   device_write_ptr++;
308   device_status = DS_WRITE_ACK;
309363
310}
311
312364static READ16_HANDLER( eeprom_r )
313365{
314366    return ((eeprom_read_bit() & 0x01) << 11);
r2821r2822
317369
318370static ADDRESS_MAP_START( readmem, ADDRESS_SPACE_PROGRAM, 16 )
319371   AM_RANGE(0x000000, 0x0fffff) AM_READ(SMH_ROM)
320   AM_RANGE(0x200000, 0x20ffff) AM_READ(SMH_RAM)
321   AM_RANGE(0x210000, 0x210001) AM_READ(SMH_RAM)
322   AM_RANGE(0x300000, 0x3013ff) AM_READ(SMH_RAM)
323   AM_RANGE(0x400000, 0x4013ff) AM_READ(SMH_RAM)
324   AM_RANGE(0x500000, 0x5013ff) AM_READ(SMH_RAM)
325   AM_RANGE(0x700000, 0x703fff) AM_READ(SMH_RAM)
326   AM_RANGE(0x880000, 0x880001) AM_READ(input_port_0_word_r)
327   AM_RANGE(0x880002, 0x880007) AM_READ(input_port_1_word_r) /* test */
328   AM_RANGE(0x900000, 0x907fff) AM_READ(SMH_RAM)
329   AM_RANGE(0x980000, 0x980fff) AM_READ(SMH_RAM)
330   AM_RANGE(0xb80000, 0xb80001) AM_READ(reg_b80000_r)
331   AM_RANGE(0xd00000, 0xd80003) AM_READ(SMH_RAM)
372   AM_RANGE(0x200000, 0x20ffff) AM_READ(SMH_RAM) // work ram
373   AM_RANGE(0x210000, 0x210001) AM_READ(SMH_NOP) // single byte overflow on stack defined as 0x210000
374   AM_RANGE(0x300000, 0x3013ff) AM_READ(SMH_RAM) // bg0 ram
375   AM_RANGE(0x400000, 0x4013ff) AM_READ(SMH_RAM) // bg1 ram
376   AM_RANGE(0x500000, 0x5013ff) AM_READ(SMH_RAM) // bg2 ram
377   AM_RANGE(0x700000, 0x703fff) AM_READ(SMH_RAM) // fix ram   (all these names from test screen)
378   AM_RANGE(0x800000, 0x80ffff) AM_READ(SMH_RAM) // obj ram
379   AM_RANGE(0x880000, 0x88000b) AM_READ(unk880000_r)
380   AM_RANGE(0x900000, 0x907fff) AM_READ(SMH_RAM) // obj pal
381   AM_RANGE(0x980000, 0x9807ff) AM_READ(SMH_RAM) // bg pal
382   AM_RANGE(0x980800, 0x980fff) AM_READ(SMH_RAM) // fix pal
383   AM_RANGE(0xb80000, 0xb80001) AM_READ(prot_status_r)
384   AM_RANGE(0xd00000, 0xd00001) AM_READ(input_port_0_word_r)
385   AM_RANGE(0xd00002, 0xd00003) AM_READ(input_port_1_word_r)
332386   AM_RANGE(0xd80000, 0xd80001) AM_READ(eeprom_r)
333   AM_RANGE(0xf00000, 0xf00001) AM_READ(SMH_RAM)
334   AM_RANGE(0xf80000, 0xf80001) AM_READ(reg_f80000_r)
335
387   AM_RANGE(0xf00000, 0xf00001) AM_READ( sound_r )
388   AM_RANGE(0xf80000, 0xf80001) AM_READ(prot_data_r)
336389ADDRESS_MAP_END
337390
338391static WRITE16_HANDLER( eeprom_w )
r2821r2822
345398   }
346399}
347400
401
402INLINE void set_color_555(pen_t color, int rshift, int gshift, int bshift, UINT16 data)
403{
404   palette_set_color_rgb(Machine, color, pal5bit(data >> rshift), pal5bit(data >> gshift), pal5bit(data >> bshift));
405}
406
407
408WRITE16_HANDLER( tilemap_paletteram16_xGGGGGRRRRRBBBBB_word_w )
409{
410   COMBINE_DATA(&tilemap_paletteram16[offset]);
411   set_color_555(offset+0x4000, 5, 10, 0, tilemap_paletteram16[offset]);
412}
413
414static WRITE16_HANDLER( bg0_tilemap_lineram_w )
415{
416   COMBINE_DATA(&bg0tilemap_lineram[offset]);
417   if (data!=0x0000) popmessage("non 0 write to bg0 lineram %04x %04x",offset,data);
418}
419
420static WRITE16_HANDLER( bg1_tilemap_lineram_w )
421{
422   COMBINE_DATA(&bg1tilemap_lineram[offset]);
423   if (data!=0x0000) popmessage("non 0 write to bg1 lineram %04x %04x",offset,data);
424}
425
426static WRITE16_HANDLER( bg2_tilemap_lineram_w )
427{
428   COMBINE_DATA(&bg2tilemap_lineram[offset]);
429   if (data!=0x0000) popmessage("non 0 write to bg2 lineram %04x %04x",offset,data);
430}
431
432
348433static ADDRESS_MAP_START( writemem, ADDRESS_SPACE_PROGRAM, 16 )
349434   AM_RANGE(0x000000, 0x0fffff) AM_WRITE(SMH_ROM)
350   AM_RANGE(0x200000, 0x20ffff) AM_WRITE(SMH_RAM) AM_BASE(&protram)
351   AM_RANGE(0x300000, 0x3013ff) AM_WRITE(SMH_RAM)
352   AM_RANGE(0x400000, 0x4013ff) AM_WRITE(SMH_RAM)
353   AM_RANGE(0x500000, 0x5013ff) AM_WRITE(SMH_RAM)
354   AM_RANGE(0x700000, 0x703fff) AM_WRITE(SMH_RAM) AM_BASE(&videoram16)
355   AM_RANGE(0x800000, 0x80ffff) AM_WRITE(SMH_RAM)
356   AM_RANGE(0x900000, 0x907fff) AM_WRITE(SMH_RAM)
357   AM_RANGE(0x980000, 0x980fff) AM_WRITE(paletteram16_xGGGGGRRRRRBBBBB_word_w) AM_BASE(&paletteram16)
435   AM_RANGE(0x200000, 0x20ffff) AM_WRITE(SMH_RAM) // work ram
436   AM_RANGE(0x300000, 0x300fff) AM_WRITE(bg0_tilemap_w) AM_BASE(&bg0tilemap_ram) // bg0 ram
437   AM_RANGE(0x301000, 0x3013ff) AM_WRITE(bg0_tilemap_lineram_w) AM_BASE(&bg0tilemap_lineram)// bg0 linescroll? (guess)
358438
359   AM_RANGE(0x880000, 0x88002f) AM_WRITE(SMH_RAM )
439   AM_RANGE(0x400000, 0x400fff) AM_WRITE(bg1_tilemap_w) AM_BASE(&bg1tilemap_ram) // bg1 ram
440   AM_RANGE(0x401000, 0x4013ff) AM_WRITE(bg1_tilemap_lineram_w) AM_BASE(&bg1tilemap_lineram)// bg1 linescroll? (guess)
441
442   AM_RANGE(0x500000, 0x500fff) AM_WRITE(bg2_tilemap_w) AM_BASE(&bg2tilemap_ram) // bg2 ram
443   AM_RANGE(0x501000, 0x5013ff) AM_WRITE(bg2_tilemap_lineram_w) AM_BASE(&bg2tilemap_lineram) // bg2 linescroll? (guess)
444
445   AM_RANGE(0x700000, 0x703fff) AM_WRITE(fg_tilemap_w) AM_BASE(&fgtilemap_ram) // fix ram
446   AM_RANGE(0x800000, 0x80ffff) AM_WRITE(SMH_RAM) AM_BASE(&tecmosys_spriteram) // obj ram
447   AM_RANGE(0x900000, 0x907fff) AM_WRITE(paletteram16_xGGGGGRRRRRBBBBB_word_w) AM_BASE(&paletteram16) // AM_WRITE(SMH_RAM) // obj pal
448
449   //AM_RANGE(0x980000, 0x9807ff) AM_WRITE(SMH_RAM) // bg pal
450   //AM_RANGE(0x980800, 0x980fff) AM_WRITE(paletteram16_xGGGGGRRRRRBBBBB_word_w) AM_BASE(&paletteram16) // fix pal
451   // the two above are as tested by the game code, I've only rolled them into one below to get colours to show right.
452   AM_RANGE(0x980000, 0x980fff) AM_WRITE(tilemap_paletteram16_xGGGGGRRRRRBBBBB_word_w) AM_BASE(&tilemap_paletteram16)
453
454   AM_RANGE(0x880000, 0x88002f) AM_WRITE( unk880000_w ) AM_BASE(&tecmosys_880000regs)   // 10 byte dta@88000c, 880022=watchdog?
360455   AM_RANGE(0xa00000, 0xa00001) AM_WRITE(eeprom_w   )
361   AM_RANGE(0xa80000, 0xa80005) AM_WRITE(SMH_RAM   )
362   AM_RANGE(0xb00000, 0xb00005) AM_WRITE(SMH_RAM   )
363   AM_RANGE(0xb80000, 0xb80005) AM_WRITE(SMH_RAM   )
364   AM_RANGE(0xc00000, 0xc00005) AM_WRITE(SMH_RAM   )
365   AM_RANGE(0xc80000, 0xc80005) AM_WRITE(SMH_RAM   )
366   AM_RANGE(0xe00000, 0xe00001) AM_WRITE(SMH_RAM )
367   AM_RANGE(0xe80000, 0xe80001) AM_WRITE(reg_e80000_w)
456   AM_RANGE(0xa80000, 0xa80005) AM_WRITE(SMH_RAM   ) AM_BASE(&tecmosys_a80000regs)   // a80000-3 scroll? a80004 inverted ? 3 : 0
457   AM_RANGE(0xb00000, 0xb00005) AM_WRITE(SMH_RAM   ) AM_BASE(&tecmosys_b00000regs)   // b00000-3 scrool?, b00004 inverted ? 3 : 0
458   AM_RANGE(0xb80000, 0xb80001) AM_WRITE(prot_status_w)
459   AM_RANGE(0xc00000, 0xc00005) AM_WRITE(SMH_RAM   ) AM_BASE(&tecmosys_c00000regs)   // c00000-3 scroll? c00004 inverted ? 13 : 10
460   AM_RANGE(0xc80000, 0xc80005) AM_WRITE(SMH_RAM   ) AM_BASE(&tecmosys_c80000regs)   // c80000-3 scrool? c80004 inverted ? 3 : 0
461   AM_RANGE(0xe00000, 0xe00001) AM_WRITE( sound_w )
462   AM_RANGE(0xe80000, 0xe80001) AM_WRITE(prot_data_w)
368463ADDRESS_MAP_END
369464
465
370466static INPUT_PORTS_START( deroon )
371467   PORT_START
372   PORT_BIT(  0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1)
373   PORT_BIT(  0x0002, IP_ACTIVE_HIGH,IPT_UNKNOWN )
468   PORT_BIT(  0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )      PORT_8WAY PORT_PLAYER(1)
469   PORT_BIT(  0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )   PORT_8WAY PORT_PLAYER(1)
470   PORT_BIT(  0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )   PORT_8WAY PORT_PLAYER(1)
471   PORT_BIT(  0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )   PORT_8WAY PORT_PLAYER(1)
472   PORT_BIT(  0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 )         PORT_PLAYER(1)
473   PORT_BIT(  0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 )         PORT_PLAYER(1)
474   PORT_BIT(  0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 )         PORT_PLAYER(1)
475   PORT_BIT(  0x0080, IP_ACTIVE_LOW, IPT_START1 )
374476
375   PORT_BIT(  0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
376   PORT_BIT(  0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
377   PORT_BIT(  0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
378   PORT_BIT(  0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
379   PORT_BIT(  0x0040, IP_ACTIVE_LOW, IPT_START1 )
477   PORT_BIT(  0x0100, IP_ACTIVE_LOW, IPT_COIN1 )
478   PORT_BIT(  0x0200, IP_ACTIVE_LOW, IPT_SERVICE )
479   PORT_BIT(  0x0400, IP_ACTIVE_LOW, IPT_BUTTON4 )       PORT_PLAYER(1)
480   PORT_BIT(  0x0800, IP_ACTIVE_LOW, IPT_UNUSED )
481   PORT_BIT(  0x1000, IP_ACTIVE_LOW, IPT_UNUSED )
482   PORT_BIT(  0x2000, IP_ACTIVE_LOW, IPT_UNUSED )
483   PORT_BIT(  0x4000, IP_ACTIVE_LOW, IPT_UNUSED )
484   PORT_BIT(  0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
485
486   PORT_START
487   PORT_BIT(  0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )      PORT_8WAY PORT_PLAYER(2)
488   PORT_BIT(  0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )   PORT_8WAY PORT_PLAYER(2)
489   PORT_BIT(  0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )   PORT_8WAY PORT_PLAYER(2)
490   PORT_BIT(  0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )   PORT_8WAY PORT_PLAYER(2)
491   PORT_BIT(  0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 )         PORT_PLAYER(2)
492   PORT_BIT(  0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 )         PORT_PLAYER(2)
493   PORT_BIT(  0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 )         PORT_PLAYER(2)
380494   PORT_BIT(  0x0080, IP_ACTIVE_LOW, IPT_START2 )
381   PORT_BIT(  0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
382   PORT_BIT(  0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
383   PORT_BIT(  0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
384   PORT_BIT(  0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
385   PORT_BIT(  0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
386   PORT_BIT(  0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
387   PORT_BIT(  0x4000, IP_ACTIVE_LOW, IPT_START1 )
388   PORT_BIT(  0x8000, IP_ACTIVE_LOW, IPT_START2 )
495
496   PORT_BIT(  0x0100, IP_ACTIVE_LOW, IPT_UNUSED )
497   PORT_BIT(  0x0200, IP_ACTIVE_LOW, IPT_SERVICE1 )
498   PORT_BIT(  0x0400, IP_ACTIVE_LOW, IPT_BUTTON4 )         PORT_PLAYER(2)
499   PORT_BIT(  0x0800, IP_ACTIVE_LOW, IPT_UNUSED )
500   PORT_BIT(  0x1000, IP_ACTIVE_LOW, IPT_UNUSED )
501   PORT_BIT(  0x2000, IP_ACTIVE_LOW, IPT_UNUSED )
502   PORT_BIT(  0x4000, IP_ACTIVE_LOW, IPT_UNUSED )
503   PORT_BIT(  0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
389504INPUT_PORTS_END
390505
391506static const gfx_layout gfxlayout =
r2821r2822
413528};
414529
415530
531
532
416533static GFXDECODE_START( tecmosys )
417   GFXDECODE_ENTRY( REGION_GFX2, 0, gfxlayout,   0x40*16, 16 )
418   GFXDECODE_ENTRY( REGION_GFX3, 0, gfxlayout2,   0, 16 )
534   GFXDECODE_ENTRY( REGION_GFX2, 0, gfxlayout,   0x4400, 0x40 )
535   GFXDECODE_ENTRY( REGION_GFX3, 0, gfxlayout2,  0x4000, 0x40 )
536   GFXDECODE_ENTRY( REGION_GFX4, 0, gfxlayout2,  0x4000, 0x40 )
537   GFXDECODE_ENTRY( REGION_GFX5, 0, gfxlayout2,  0x4000, 0x40 )
538
419539GFXDECODE_END
420540
421
422
423541static WRITE8_HANDLER( deroon_bankswitch_w )
424542{
425543   memory_set_bankptr( 1, memory_region(REGION_CPU2) + ((data-2) & 0x0f) * 0x4000 + 0x10000 );
r2821r2822
429547   AM_RANGE(0x0000, 0x7fff) AM_READ(SMH_ROM)
430548   AM_RANGE(0x8000, 0xbfff) AM_READ(SMH_BANK1)
431549   AM_RANGE(0xe000, 0xf7ff) AM_READ(SMH_RAM)
432
433550ADDRESS_MAP_END
434551
435552static ADDRESS_MAP_START( sound_writemem, ADDRESS_SPACE_PROGRAM, 8 )
r2821r2822
437554   AM_RANGE(0xe000, 0xf7ff) AM_WRITE(SMH_RAM)
438555ADDRESS_MAP_END
439556
440
441
442557static ADDRESS_MAP_START( readport, ADDRESS_SPACE_IO, 8 )
443558   ADDRESS_MAP_GLOBAL_MASK(0xff)
444559   AM_RANGE(0x00, 0x00) AM_READ(YMF262_status_0_r)
445560   AM_RANGE(0x40, 0x40) AM_READ(soundlatch_r)
446   //AM_RANGE(0x60, 0x60) AM_READ(YMZ280B_status_0_r)
561   AM_RANGE(0x60, 0x60) AM_READ(YMZ280B_status_0_r)
447562ADDRESS_MAP_END
448563
564
565static WRITE8_HANDLER( tecmosys_oki_bank_w )
566{
567   UINT8 upperbank = (data & 0x30) >> 4;
568   UINT8 lowerbank = (data & 0x03) >> 0;
569   UINT8* region = memory_region(REGION_SOUND2);
570
571   memcpy( region+0x00000, region+0x80000 + lowerbank * 0x20000, 0x20000  );
572   memcpy( region+0x20000, region+0x80000 + upperbank * 0x20000, 0x20000  );
573}
574
449575static ADDRESS_MAP_START( writeport, ADDRESS_SPACE_IO, 8 )
450576   ADDRESS_MAP_GLOBAL_MASK(0xff)
451577   AM_RANGE(0x00, 0x00) AM_WRITE(YMF262_register_A_0_w)
r2821r2822
454580   AM_RANGE(0x03, 0x03) AM_WRITE(YMF262_data_B_0_w)
455581
456582   AM_RANGE(0x10, 0x10) AM_WRITE(OKIM6295_data_0_w)
457   AM_RANGE(0x20, 0x20) AM_NOP
583   AM_RANGE(0x20, 0x20) AM_WRITE(tecmosys_oki_bank_w)
458584
459585   AM_RANGE(0x30, 0x30) AM_WRITE(deroon_bankswitch_w)
460586
461   //AM_RANGE(0x50, 0x50) AM_WRITE(to_main_cpu_latch_w)
462   AM_RANGE(0x50, 0x50) AM_WRITE(SMH_NOP)
587   AM_RANGE(0x50, 0x50) AM_WRITE(soundlatch2_w)
463588
464589   AM_RANGE(0x60, 0x60) AM_WRITE(YMZ280B_register_0_w)
465590   AM_RANGE(0x61, 0x61) AM_WRITE(YMZ280B_data_0_w)
466591ADDRESS_MAP_END
467592
593static VIDEO_START(deroon)
594{
595   sprite_bitmap = auto_bitmap_alloc(320,240,BITMAP_FORMAT_INDEXED16);
596   fillbitmap(sprite_bitmap, 0x4000, NULL);
468597
598   tmp_tilemap_composebitmap = auto_bitmap_alloc(320,240,BITMAP_FORMAT_INDEXED16);
599   tmp_tilemap_renderbitmap = auto_bitmap_alloc(320,240,BITMAP_FORMAT_INDEXED16);
469600
470static VIDEO_START(deroon)
471{
601   fillbitmap(tmp_tilemap_composebitmap, 0x0000, NULL);
602   fillbitmap(tmp_tilemap_renderbitmap, 0x0000, NULL);
603
604
472605   txt_tilemap = tilemap_create(get_tile_info,tilemap_scan_rows,8,8,32*2,32*2);
473606   tilemap_set_transparent_pen(txt_tilemap,0);
474}
475607
608   bg0tilemap = tilemap_create(get_bg0tile_info,tilemap_scan_rows,16,16,32,32);
609   tilemap_set_transparent_pen(bg0tilemap,0);
476610
611   bg1tilemap = tilemap_create(get_bg1tile_info,tilemap_scan_rows,16,16,32,32);
612   tilemap_set_transparent_pen(bg1tilemap,0);
477613
614   bg2tilemap = tilemap_create(get_bg2tile_info,tilemap_scan_rows,16,16,32,32);
615   tilemap_set_transparent_pen(bg2tilemap,0);
478616
479static VIDEO_UPDATE(deroon)
617}
618
619static void tecmosys_render_sprites_to_bitmap(bitmap_t *bitmap, UINT16 extrax, UINT16 extray )
480620{
621   UINT8 *gfxsrc    = memory_region       ( REGION_GFX1 );
622   int i;
481623
624   /* render sprites (with priority information) to temp bitmap */
625   fillbitmap(sprite_bitmap, 0x0000, NULL);
626   /* there are multiple spritelists in here, to allow for buffering */
627   for (i=(tecmosys_spritelist*0x4000)/2;i<((tecmosys_spritelist+1)*0x4000)/2;i+=8)
628   {
629      int xcnt,ycnt;
630      int drawx, drawy;
631      UINT16* dstptr;
482632
633      int x, y;
634      int address;
635      int xsize = 16;
636      int ysize = 16;
637      int colour;
638      int flipx, flipy;
639      int priority;
640      int zoomx, zoomy;
483641
484#if 0
485/* simulate sound commands writes here ... to test OPL3 emulator */
486   int j;
487   char buf[64];
488   static int command_data=0;
642      x = tecmosys_spriteram[i+0]+386;
643      y = (tecmosys_spriteram[i+1]+1);
489644
490   if (input_code_pressed_once(KEYCODE_Q))
491   {
492      command_data++;
493   }
494   if (input_code_pressed_once(KEYCODE_A))
495   {
496      command_data--;
497   }
498   command_data &= 0xff;
645      x-= extrax;
646      y-= extray;
499647
500   sprintf(buf,"keys: Q,A and C\ncommand code: %2x", command_data);
501   ui_draw_text(buf,10,20);
648      y&=0x1ff;
649      x&=0x3ff;
502650
503   if (input_code_pressed_once(KEYCODE_C))
504   {
505      soundlatch_w(0,command_data);
506      cpunum_set_input_line(machine, 1, INPUT_LINE_NMI, PULSE_LINE);
507      popmessage("command write=%2x",command_data);
508   }
509#endif
651      if (x&0x200) x-=0x400;
652      if (y&0x100) y-=0x200;
510653
654      address =  tecmosys_spriteram[i+5]| ((tecmosys_spriteram[i+4]&0x000f)<<16);
511655
656      address<<=8;
512657
658      flipx = (tecmosys_spriteram[i+4]&0x0040)>>6;
659      flipy = (tecmosys_spriteram[i+4]&0x0080)>>7; // used by some move effects in tkdensho
513660
514   // bg color , to see text in deroon
515   if(!gametype)
516         palette_set_color(screen->machine,0x800,MAKE_RGB(0x80,0x80,0x80));
517   else
518         palette_set_color(screen->machine,0x800,MAKE_RGB(0x0,0x0,0x0));
519661
520   fillbitmap(bitmap,0x800,cliprect);
662      zoomx = (tecmosys_spriteram[i+2] & 0x0fff)>>0; // zoom?
663      zoomy = (tecmosys_spriteram[i+3] & 0x0fff)>>0; // zoom?
521664
522   tilemap_mark_all_tiles_dirty(txt_tilemap);
523   tilemap_draw(bitmap,cliprect,txt_tilemap,0,0);
665      if ((!zoomx) || (!zoomy)) continue;
524666
667      ysize =  ((tecmosys_spriteram[i+6] & 0x00ff))*16;
668      xsize =  (((tecmosys_spriteram[i+6] & 0xff00)>>8))*16;
525669
526//hacks
670      colour =  ((tecmosys_spriteram[i+4] & 0x3f00))>>8;
527671
528   if(input_code_pressed_once(KEYCODE_Z))
672      priority = ((tecmosys_spriteram[i+4] & 0x0030))>>4;
673
674
675      if (tecmosys_spriteram[i+4] & 0x8000) continue;
676
677      for (ycnt = 0; ycnt < ysize; ycnt++)
678      {
679         int actualycnt = (ycnt * zoomy) >> 8;
680         int actualysize = (ysize * zoomy) >> 8;
681
682         if (flipy) drawy = y + (actualysize-1) - actualycnt;
683         else drawy = y + actualycnt;
684
685
686         for (xcnt = 0; xcnt < xsize; xcnt++)
687         {
688            int actualxcnt = (xcnt * zoomx) >> 8;
689            int actualxsize = (xsize *zoomx) >> 8;
690
691            if (flipx) drawx = x + (actualxsize-1) - actualxcnt;
692            else drawx = x + actualxcnt;
693
694            if ((drawx>=0 && drawx<320) && (drawy>=0 && drawy<240))
695            {
696               UINT8 data;
697
698               dstptr = BITMAP_ADDR16(sprite_bitmap, drawy, drawx);
699
700
701               data =  (gfxsrc[address]);
702
703
704               if(data) dstptr[0] = (data + (colour*0x100)) | (priority << 14);
705            }
706
707
708
709            address++;
710
711         }
712      }
713
714   }
715}
716
717void tecmosys_tilemap_copy_to_compose(UINT16 pri)
718{
719   int y,x;
720   UINT16 *srcptr;
721   UINT16 *dstptr;
722   for (y=0;y<240;y++)
529723   {
530      if(!gametype)
531         cpunum_set_reg(0, M68K_PC, 0x23ae8); /* deroon */
532      else
724      srcptr = BITMAP_ADDR16(tmp_tilemap_renderbitmap, y, 0);
725      dstptr = BITMAP_ADDR16(tmp_tilemap_composebitmap, y, 0);
726      for (x=0;x<320;x++)
533727      {
534         UINT16 *ROM = (UINT16 *)memory_region(REGION_CPU1);
535         ROM[0x3aaa/2] = 0x4e73; // rte (trap 0)
536         cpunum_set_reg(0, M68K_PC, 0x182a0); /* angel eyes */
728         if ((srcptr[x]&0xf)!=0x0)
729             dstptr[x] =  (srcptr[x]&0x7ff) | pri;
537730      }
538731   }
732}
539733
540   if(input_code_pressed_once(KEYCODE_X))
734void tecmosys_do_final_mix(bitmap_t* bitmap)
735{
736   const pen_t *paldata = Machine->pens;
737   int y,x;
738   UINT16 *srcptr;
739   UINT16 *srcptr2;
740   UINT32 *dstptr;
741
742
743   for (y=0;y<240;y++)
541744   {
542      if(gametype)
745
746      srcptr = BITMAP_ADDR16(tmp_tilemap_composebitmap, y, 0);
747      srcptr2 = BITMAP_ADDR16(sprite_bitmap, y, 0);
748
749
750      dstptr = BITMAP_ADDR32(bitmap, y, 0);
751      for (x=0;x<320;x++)
543752      {
544         UINT16 *ROM = (UINT16 *)memory_region(REGION_CPU1);
545         ROM[0x3aaa/2] = 0x4e73; // rte (trap 0)
546         cpunum_set_reg(0, M68K_PC, 0x17d2a); /* angel eyes */
753         UINT16 pri, pri2;
754         UINT16 penvalue;
755         UINT16 penvalue2;
756         UINT32 colour;
757         UINT32 colour2;
758
759         pri = srcptr[x] & 0xc000;
760         pri2 = srcptr2[x] & 0xc000;
761
762         penvalue = tilemap_paletteram16[srcptr[x]&0x7ff];
763         colour =   paldata[(srcptr[x]&0x7ff) | 0x4000];
764
765         if (srcptr2[x]&0x3fff)
766         {
767            penvalue2 = paletteram16[srcptr2[x]&0x3fff];
768            colour2 = paldata[srcptr2[x]&0x3fff];
769         }
770         else
771         {
772            penvalue2 = tilemap_paletteram16[srcptr[x]&0x7ff];
773            colour2 =   paldata[(srcptr[x]&0x7ff) | 0x4000];
774         }
775
776         if ((penvalue & 0x8000) && (penvalue2 & 0x8000)) // blend
777         {
778            int r,g,b;
779            int r2,g2,b2;
780            b = (colour & 0x000000ff) >> 0;
781            g = (colour & 0x0000ff00) >> 8;
782            r = (colour & 0x00ff0000) >> 16;
783
784            b2 = (colour2 & 0x000000ff) >> 0;
785            g2 = (colour2 & 0x0000ff00) >> 8;
786            r2 = (colour2 & 0x00ff0000) >> 16;
787
788            r = (r + r2) >> 1;
789            g = (g + g2) >> 1;
790            b = (b + b2) >> 1;
791
792            dstptr[x] = b | (g<<8) | (r<<16);
793         }
794         else if (pri2 >= pri)
795         {
796            dstptr[x] = colour2;
797         }
798         else
799         {
800            dstptr[x] = colour;
801         }
547802      }
548803   }
804}
805
806static VIDEO_UPDATE(deroon)
807{
808
809   fillbitmap(bitmap,Machine->pens[0x4000],cliprect);
810
811
812   tilemap_set_scrolly( bg0tilemap, 0, tecmosys_c80000regs[1]+16);
813   tilemap_set_scrollx( bg0tilemap, 0, tecmosys_c80000regs[0]+104);
814
815   tilemap_set_scrolly( bg1tilemap, 0, tecmosys_a80000regs[1]+17);
816   tilemap_set_scrollx( bg1tilemap, 0, tecmosys_a80000regs[0]+106);
817
818   tilemap_set_scrolly( bg2tilemap, 0, tecmosys_b00000regs[1]+17);
819   tilemap_set_scrollx( bg2tilemap, 0, tecmosys_b00000regs[0]+106);
820
821   fillbitmap(tmp_tilemap_composebitmap,0,cliprect);
822
823   fillbitmap(tmp_tilemap_renderbitmap,0,cliprect);
824   tilemap_draw(tmp_tilemap_renderbitmap,cliprect,bg0tilemap,0,0);
825   tecmosys_tilemap_copy_to_compose(0x0000);
826
827   fillbitmap(tmp_tilemap_renderbitmap,0,cliprect);
828   tilemap_draw(tmp_tilemap_renderbitmap,cliprect,bg1tilemap,0,0);
829   tecmosys_tilemap_copy_to_compose(0x4000);
830
831   fillbitmap(tmp_tilemap_renderbitmap,0,cliprect);
832   tilemap_draw(tmp_tilemap_renderbitmap,cliprect,bg2tilemap,0,0);
833   tecmosys_tilemap_copy_to_compose(0x8000);
834
835   fillbitmap(tmp_tilemap_renderbitmap,0,cliprect);
836   tilemap_draw(tmp_tilemap_renderbitmap,cliprect,txt_tilemap,0,0);
837   tecmosys_tilemap_copy_to_compose(0xc000);
838
839
840   tecmosys_do_final_mix(bitmap);
841
842/*
843    popmessage("%04x %04x %04x %04x | %04x %04x %04x %04x | %04x %04x %04x %04x  | %04x %04x %04x %04x  | %04x %04x %04x %04x  | %04x %04x %04x %04x",
844        tecmosys_880000regs[0x0],  tecmosys_880000regs[0x1],  tecmosys_880000regs[0x2],  tecmosys_880000regs[0x3],
845        tecmosys_880000regs[0x4],  tecmosys_880000regs[0x5],  tecmosys_880000regs[0x6],  tecmosys_880000regs[0x7],
846        tecmosys_880000regs[0x8],  tecmosys_880000regs[0x9],  tecmosys_880000regs[0xa],  tecmosys_880000regs[0xb],
847        tecmosys_880000regs[0xc],  tecmosys_880000regs[0xd],  tecmosys_880000regs[0xe],  tecmosys_880000regs[0xf],
848        tecmosys_880000regs[0x10], tecmosys_880000regs[0x11], tecmosys_880000regs[0x12], tecmosys_880000regs[0x13],
849        tecmosys_880000regs[0x14], tecmosys_880000regs[0x15], tecmosys_880000regs[0x16], tecmosys_880000regs[0x17]);
850*/
851
852//  popmessage("%04x %04x %04x | %04x %04x %04x",
853//    tecmosys_c00000regs[0],     tecmosys_c00000regs[1],     tecmosys_c00000regs[2],
854//    tecmosys_c80000regs[0],     tecmosys_c80000regs[1],     tecmosys_c80000regs[2]);
855
856//  popmessage("%04x %04x %04x | %04x %04x %04x",
857//    tecmosys_b00000regs[0],     tecmosys_b00000regs[1],     tecmosys_b00000regs[2],
858//    tecmosys_a80000regs[0],     tecmosys_a80000regs[1],     tecmosys_a80000regs[2]);
859
860   // prepare sprites for NEXT frame - causes 1 frame palette errors, but prevents sprite lag in tkdensho, which is correct?
861   tecmosys_render_sprites_to_bitmap(bitmap, tecmosys_880000regs[0x0], tecmosys_880000regs[0x1]);
862
863
549864   return 0;
550865}
551866
552867/*
553>>> Richard wrote:
868>>> R.Belmont wrote:
554869> Here's the sound info (I got it playing in M1, I
555870> didn't bother "porting" it since the main game doesn't
556871> even boot).
r2821r2822
602917   0   /* irq */
603918};
604919
920
605921static MACHINE_DRIVER_START( deroon )
606   MDRV_CPU_ADD(M68000, 16000000/8) /* the /8 divider is here only for OPL3 testing */
922   MDRV_CPU_ADD(M68000, 16000000)
607923   MDRV_CPU_PROGRAM_MAP(readmem,writemem)
608924   MDRV_CPU_VBLANK_INT("main", irq1_line_hold)
925   MDRV_WATCHDOG_VBLANK_INIT(400) // guess
609926
927   /* audio CPU */
610928   MDRV_CPU_ADD(Z80, 16000000/2 )   /* 8 MHz ??? */
611   /* audio CPU */
612929   MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem)
613930   MDRV_CPU_IO_MAP(readport,writeport)
614931
r2821r2822
620937
621938   MDRV_SCREEN_ADD("main", RASTER)
622939   MDRV_SCREEN_REFRESH_RATE(60)
623   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
624   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
940   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(3000))
941   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
625942   MDRV_SCREEN_SIZE(64*8, 64*8)
626   MDRV_SCREEN_VISIBLE_AREA(0*8, 42*8-1, 0*8, 32*8-1)
943   MDRV_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 0*8, 30*8-1)
627944
628   MDRV_PALETTE_LENGTH(0x800+1)
945   MDRV_PALETTE_LENGTH(0x4000+0x800)
629946
630947   MDRV_VIDEO_START(deroon)
948   MDRV_MACHINE_RESET(deroon)
631949   MDRV_VIDEO_UPDATE(deroon)
632950
633951   /* sound hardware */
r2821r2822
635953
636954   MDRV_SOUND_ADD(YMF262, 14318180)
637955   MDRV_SOUND_CONFIG(ymf262_interface)
638   MDRV_SOUND_ROUTE(0, "left", 1.0)
639   MDRV_SOUND_ROUTE(1, "right", 1.0)
640   MDRV_SOUND_ROUTE(2, "left", 1.0)
641   MDRV_SOUND_ROUTE(3, "right", 1.0)
956   MDRV_SOUND_ROUTE(0, "left", 1.00)
957   MDRV_SOUND_ROUTE(1, "right", 1.00)
958   MDRV_SOUND_ROUTE(2, "left", 1.00)
959   MDRV_SOUND_ROUTE(3, "right", 1.00)
642960
643   MDRV_SOUND_ADD(OKIM6295, 14318180/2048*132)
644   MDRV_SOUND_CONFIG(okim6295_interface_region_1_pin7high) // clock frequency & pin 7 not verified
961   MDRV_SOUND_ADD(OKIM6295, 16000000/8)
962   MDRV_SOUND_CONFIG(okim6295_interface_region_2_pin7high)
645963   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.50)
646964   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.50)
647965
r2821r2822
654972
655973ROM_START( deroon )
656974   ROM_REGION( 0x100000, REGION_CPU1, 0 ) // Main Program
657   ROM_LOAD16_BYTE( "t001upau.bin", 0x00000, 0x80000, CRC(14b92c18) SHA1(b47b8c828222a3f7c0fe9271899bd38171d972fb) )
658   ROM_LOAD16_BYTE( "t002upal.bin", 0x00001, 0x80000, CRC(0fb05c68) SHA1(5140592e15414770fb46d5ac9ba8f76e3d4ab323) )
975   ROM_LOAD16_BYTE( "t001.upau1", 0x00000, 0x80000, CRC(14b92c18) SHA1(b47b8c828222a3f7c0fe9271899bd38171d972fb) )
976   ROM_LOAD16_BYTE( "t002.upal1", 0x00001, 0x80000, CRC(0fb05c68) SHA1(5140592e15414770fb46d5ac9ba8f76e3d4ab323) )
659977
660978   ROM_REGION( 0x048000, REGION_CPU2, 0 ) // Sound Porgram
661   ROM_LOAD( "t003uz1.bin", 0x000000, 0x008000, CRC(8bdfafa0) SHA1(c0cf3eb7a65d967958fe2aace171859b0faf7753) )
662   ROM_CONTINUE(            0x010000, 0x038000 ) /* banked part */
979   ROM_LOAD( "t003.uz1", 0x000000, 0x008000, CRC(8bdfafa0) SHA1(c0cf3eb7a65d967958fe2aace171859b0faf7753) )
980   ROM_CONTINUE(         0x010000, 0x038000 ) /* banked part */
663981
664   ROM_REGION( 0x800000, REGION_GFX1, 0 ) // Graphics - mostly (maybe all?) not tile based
665   ROM_LOAD( "t101uah1.j66", 0x000000, 0x200000, CRC(74baf845) SHA1(935d2954ba227a894542be492654a2750198e1bc) )
666   ROM_LOAD( "t102ual1.j67", 0x200000, 0x200000, CRC(1a02c4a3) SHA1(5155eeaef009fc9a9f258e3e54ca2a7f78242df5) )
667   ROM_LOAD( "t103ubl1.j08", 0x400000, 0x200000, CRC(75431ec5) SHA1(c03e724c15e1fe7a0a385332f849e9ac9d149887) )
668   ROM_LOAD( "t104ucl1.j68", 0x600000, 0x200000, CRC(66eb611a) SHA1(64435d35677fea3c06fdb03c670f3f63ee481c02) )
982   ROM_REGION( 0x2200, REGION_CPU3, 0 ) // MCU is a 68HC11A8 with 8k ROM, 512 bytes EEPROM
983   ROM_LOAD( "deroon_68hc11a8.rom",    0x0000, 0x2000, NO_DUMP )
984   ROM_LOAD( "deroon_68hc11a8.eeprom", 0x2000, 0x0200, NO_DUMP )
669985
986   ROM_REGION( 0x2000000, REGION_GFX1, ROMREGION_ERASE00 ) // Sprites (non-tile based)
987   /* all these roms need verifying, they could be half size */
988
989   ROM_LOAD16_BYTE( "t101.uah1", 0x0000000, 0x200000, CRC(74baf845) SHA1(935d2954ba227a894542be492654a2750198e1bc) )
990   ROM_LOAD16_BYTE( "t102.ual1", 0x0000001, 0x200000, CRC(1a02c4a3) SHA1(5155eeaef009fc9a9f258e3e54ca2a7f78242df5) )
991   /*                            0x8000000, 0x400000 - no rom loaded here, these gfx are 4bpp */
992   ROM_LOAD16_BYTE( "t103.ubl1", 0x0800001, 0x400000, CRC(84e7da88) SHA1(b5c3234f33bb945cc9762b91db087153a0589cfb) )
993   /*                            0x1000000, 0x400000 - no rom loaded here, these gfx are 4bpp */
994   ROM_LOAD16_BYTE( "t104.ucl1", 0x1000001, 0x200000, CRC(66eb611a) SHA1(64435d35677fea3c06fdb03c670f3f63ee481c02) )
995
670996   ROM_REGION( 0x100000, REGION_GFX2, ROMREGION_DISPOSE ) // 8x8 4bpp tiles
671   ROM_LOAD( "t301ubd1.w63", 0x000000, 0x100000, CRC(8b026177) SHA1(3887856bdaec4d9d3669fe3bc958ef186fbe9adb) )
997   ROM_LOAD( "t301.ubd1", 0x000000, 0x100000, CRC(8b026177) SHA1(3887856bdaec4d9d3669fe3bc958ef186fbe9adb) )
672998
673   ROM_REGION( 0x300000, REGION_GFX3, ROMREGION_DISPOSE ) // 16x16 4bpp tiles
674   ROM_LOAD( "t201ubb1.w61", 0x000000, 0x100000, CRC(d5a087ac) SHA1(5098160ce7719d93e3edae05f6edd317d4c61f0d) )
675   ROM_LOAD( "t202ubc1.w62", 0x100000, 0x100000, CRC(f051dae1) SHA1(f5677c07fe644b3838657370f0309fb09244c619) )
999   ROM_REGION( 0x100000, REGION_GFX3, ROMREGION_ERASE00) // 16x16 4bpp tiles
1000   /* not used? */
6761001
1002   ROM_REGION( 0x100000, REGION_GFX4, ROMREGION_ERASE00 ) // 16x16 4bpp tiles
1003   ROM_LOAD( "t201.ubb1", 0x000000, 0x100000, CRC(d5a087ac) SHA1(5098160ce7719d93e3edae05f6edd317d4c61f0d) )
6771004
1005   ROM_REGION( 0x100000, REGION_GFX5, ROMREGION_ERASE00 ) // 16x16 4bpp tiles
1006   ROM_LOAD( "t202.ubc1", 0x000000, 0x100000, CRC(f051dae1) SHA1(f5677c07fe644b3838657370f0309fb09244c619) )
1007
6781008   ROM_REGION( 0x200000, REGION_SOUND1, 0 ) // YMZ280B Samples
679   ROM_LOAD( "t401uya1.w16", 0x000000, 0x200000, CRC(92111992) SHA1(ae27e11ae76dec0b9892ad32e1a8bf6ab11f2e6c) )
1009   ROM_LOAD( "t401.uya1", 0x000000, 0x200000, CRC(92111992) SHA1(ae27e11ae76dec0b9892ad32e1a8bf6ab11f2e6c) )
6801010
681   ROM_REGION( 0x080000, REGION_SOUND2, 0 ) // M6295 Samples
682   ROM_LOAD( "t501uad1.w01", 0x000000, 0x080000, CRC(2fbcfe27) SHA1(f25c830322423f0959a36955edb563a6150f2142) )
1011   ROM_REGION( 0x100000, REGION_SOUND2, 0 ) // M6295 Samples
1012   ROM_LOAD( "t501.uad1", 0x080000, 0x080000, CRC(2fbcfe27) SHA1(f25c830322423f0959a36955edb563a6150f2142) )
6831013ROM_END
6841014
6851015ROM_START( tkdensho )
r2821r2822
6911021   ROM_LOAD( "aesprg-2.z1", 0x000000, 0x008000, CRC(43550ab6) SHA1(2580129ef8ebd9295249175de4ba985c752e06fe) )
6921022   ROM_CONTINUE(            0x010000, 0x018000 ) /* banked part */
6931023
694   ROM_REGION( 0x1e00000, REGION_GFX1, 0 ) // Graphics - mostly (maybe all?) not tile based
695   ROM_LOAD( "ae100h.ah1",    0x0000000, 0x0400000, CRC(06be252b) SHA1(08d1bb569fd2e66e2c2f47da7780b31945232e62) )
696   ROM_LOAD( "ae100.al1",     0x0400000, 0x0400000, CRC(009cdff4) SHA1(fd88f07313d14fd4429b09a1e8d6b595df3b98e5) )
697   ROM_LOAD( "ae101h.bh1",    0x0800000, 0x0400000, CRC(f2469eff) SHA1(ba49d15cc7949437ba9f56d9b425a5f0e62137df) )
698   ROM_LOAD( "ae101.bl1",     0x0c00000, 0x0400000, CRC(db7791bb) SHA1(1fe40b747b7cee7a9200683192b1d60a735a0446) )
699   ROM_LOAD( "ae102h.ch1",    0x1000000, 0x0200000, CRC(f9d2a343) SHA1(d141ac0b20be587e77a576ef78f15d269d9c84e5) )
700   ROM_LOAD( "ae102.cl1",     0x1200000, 0x0200000, CRC(681be889) SHA1(8044ca7cbb325e6dcadb409f91e0c01b88a1bca7) )
701   ROM_LOAD( "ae104.el1",     0x1400000, 0x0400000, CRC(e431b798) SHA1(c2c24d4f395bba8c78a45ecf44009a830551e856) )
702   ROM_LOAD( "ae105.fl1",     0x1800000, 0x0400000, CRC(b7f9ebc1) SHA1(987f664072b43a578b39fa6132aaaccc5fe5bfc2) )
703   ROM_LOAD( "ae106.gl1",     0x1c00000, 0x0200000, CRC(7c50374b) SHA1(40865913125230122072bb13f46fb5fb60c088ea) )
1024   ROM_REGION( 0x2200, REGION_CPU3, 0 ) // MCU is a 68HC11A8 with 8k ROM, 512 bytes EEPROM
1025   ROM_LOAD( "tkdensho_68hc11a8.rom",    0x0000, 0x2000, NO_DUMP )
1026   ROM_LOAD( "tkdensho_68hc11a8.eeprom", 0x2000, 0x0200, NO_DUMP )
7041027
1028   ROM_REGION( 0x4000000, REGION_GFX1, ROMREGION_ERASE00 ) // Graphics - mostly (maybe all?) not tile based
1029   ROM_LOAD16_BYTE( "ae100h.ah1",    0x0000000, 0x0400000, CRC(06be252b) SHA1(08d1bb569fd2e66e2c2f47da7780b31945232e62) )
1030   ROM_LOAD16_BYTE( "ae100.al1",     0x0000001, 0x0400000, CRC(009cdff4) SHA1(fd88f07313d14fd4429b09a1e8d6b595df3b98e5) )
1031   ROM_LOAD16_BYTE( "ae101h.bh1",    0x0800000, 0x0400000, CRC(f2469eff) SHA1(ba49d15cc7949437ba9f56d9b425a5f0e62137df) )
1032   ROM_LOAD16_BYTE( "ae101.bl1",     0x0800001, 0x0400000, CRC(db7791bb) SHA1(1fe40b747b7cee7a9200683192b1d60a735a0446) )
1033   ROM_LOAD16_BYTE( "ae102h.ch1",    0x1000000, 0x0200000, CRC(f9d2a343) SHA1(d141ac0b20be587e77a576ef78f15d269d9c84e5) )
1034   ROM_LOAD16_BYTE( "ae102.cl1",     0x1000001, 0x0200000, CRC(681be889) SHA1(8044ca7cbb325e6dcadb409f91e0c01b88a1bca7) )
1035   ROM_LOAD16_BYTE( "ae104.el1",     0x2000001, 0x0400000, CRC(e431b798) SHA1(c2c24d4f395bba8c78a45ecf44009a830551e856) )
1036   ROM_LOAD16_BYTE( "ae105.fl1",     0x2800001, 0x0400000, CRC(b7f9ebc1) SHA1(987f664072b43a578b39fa6132aaaccc5fe5bfc2) )
1037   ROM_LOAD16_BYTE( "ae106.gl1",     0x3000001, 0x0200000, CRC(7c50374b) SHA1(40865913125230122072bb13f46fb5fb60c088ea) )
1038
7051039   ROM_REGION( 0x080000, REGION_GFX2, ROMREGION_DISPOSE ) // 8x8 4bpp tiles
7061040   ROM_LOAD( "ae300w36.bd1",  0x000000, 0x0080000, CRC(e829f29e) SHA1(e56bfe2669ed1d1ae394c644def426db129d97e3) )
7071041
708   ROM_REGION( 0x300000, REGION_GFX3, ROMREGION_DISPOSE ) // 16x16 4bpp tiles
1042   ROM_REGION( 0x100000, REGION_GFX3, ROMREGION_DISPOSE ) // 16x16 4bpp tiles
7091043   ROM_LOAD( "ae200w74.ba1",  0x000000, 0x0100000, CRC(c1645041) SHA1(323670a6aa2a4524eb968cc0b4d688098ffeeb12) )
710   ROM_LOAD( "ae201w75.bb1",  0x100000, 0x0100000, CRC(3f63bdff) SHA1(0d3d57fdc0ec4bceef27c11403b3631d23abadbf) )
711   ROM_LOAD( "ae202w76.bc1",  0x200000, 0x0100000, CRC(5cc857ca) SHA1(2553fb5220433acc15dfb726dc064fe333e51d88) )
7121044
713   ROM_REGION( 0x400000, REGION_SOUND1, 0 ) // YMZ280B Samples
1045   ROM_REGION( 0x100000, REGION_GFX4, ROMREGION_DISPOSE ) // 16x16 4bpp tiles
1046   ROM_LOAD( "ae201w75.bb1",  0x000000, 0x0100000, CRC(3f63bdff) SHA1(0d3d57fdc0ec4bceef27c11403b3631d23abadbf) )
1047
1048   ROM_REGION( 0x100000, REGION_GFX5, ROMREGION_DISPOSE ) // 16x16 4bpp tiles
1049   ROM_LOAD( "ae202w76.bc1",  0x000000, 0x0100000, CRC(5cc857ca) SHA1(2553fb5220433acc15dfb726dc064fe333e51d88) )
1050
1051   ROM_REGION( 0x800000, REGION_SOUND1, 0 ) // YMZ280B Samples
7141052   ROM_LOAD( "ae400t23.ya1", 0x000000, 0x200000, CRC(c6ffb043) SHA1(e0c6c5f6b840f63c9a685a2c3be66efa4935cbeb) )
7151053   ROM_LOAD( "ae401t24.yb1", 0x200000, 0x200000, CRC(d83f1a73) SHA1(412b7ac9ff09a984c28b7d195330d78c4aac3dc5) )
7161054
717   ROM_REGION( 0x080000, REGION_SOUND2, 0 ) // M6295 Samples
718   ROM_LOAD( "ae500w07.ad1", 0x000000, 0x080000, CRC(3734f92c) SHA1(048555b5aa89eaf983305c439ba08d32b4a1bb80) )
1055   ROM_REGION( 0x100000, REGION_SOUND2, 0 ) // M6295 Samples
1056   ROM_LOAD( "ae500w07.ad1", 0x080000, 0x080000, CRC(3734f92c) SHA1(048555b5aa89eaf983305c439ba08d32b4a1bb80) )
7191057ROM_END
7201058
721static TIMER_CALLBACK( reset_callback )
722{
723   cpunum_set_input_line(machine, 0, INPUT_LINE_RESET, PULSE_LINE);
724}
1059ROM_START( tkdensha )
1060   ROM_REGION( 0x600000, REGION_CPU1, 0 )
1061   ROM_LOAD16_BYTE( "aeprge.pal", 0x00000, 0x80000, CRC(17a209ff) SHA1(b5dbea9868cbb89d4e27bf19fdb616ac256985b4) )
1062   ROM_LOAD16_BYTE( "aeprgo.pau", 0x00001, 0x80000, CRC(d265e6a1) SHA1(f39d8ce115f197a660f5210b2483108854eb12a9) )
7251063
1064   ROM_REGION( 0x038000, REGION_CPU2, 0 ) // Sound Porgram
1065   ROM_LOAD( "aesprg-2.z1", 0x000000, 0x008000, CRC(43550ab6) SHA1(2580129ef8ebd9295249175de4ba985c752e06fe) )
1066   ROM_CONTINUE(            0x010000, 0x018000 ) /* banked part */
7261067
727static DRIVER_INIT( deroon )
1068   ROM_REGION( 0x2200, REGION_CPU3, 0 ) // MCU is a 68HC11A8 with 8k ROM, 512 bytes EEPROM
1069   ROM_LOAD( "tkdensho_68hc11a8.rom",    0x0000, 0x2000, NO_DUMP )
1070   ROM_LOAD( "tkdensho_68hc11a8.eeprom", 0x2000, 0x0200, NO_DUMP )
1071
1072   ROM_REGION( 0x4000000, REGION_GFX1, ROMREGION_ERASE00 ) // Graphics - mostly (maybe all?) not tile based
1073   ROM_LOAD16_BYTE( "ae100h.ah1",    0x0000000, 0x0400000, CRC(06be252b) SHA1(08d1bb569fd2e66e2c2f47da7780b31945232e62) )
1074   ROM_LOAD16_BYTE( "ae100.al1",     0x0000001, 0x0400000, CRC(009cdff4) SHA1(fd88f07313d14fd4429b09a1e8d6b595df3b98e5) )
1075   ROM_LOAD16_BYTE( "ae101h.bh1",    0x0800000, 0x0400000, CRC(f2469eff) SHA1(ba49d15cc7949437ba9f56d9b425a5f0e62137df) )
1076   ROM_LOAD16_BYTE( "ae101.bl1",     0x0800001, 0x0400000, CRC(db7791bb) SHA1(1fe40b747b7cee7a9200683192b1d60a735a0446) )
1077   ROM_LOAD16_BYTE( "ae102h.ch1",    0x1000000, 0x0200000, CRC(f9d2a343) SHA1(d141ac0b20be587e77a576ef78f15d269d9c84e5) )
1078   ROM_LOAD16_BYTE( "ae102.cl1",     0x1000001, 0x0200000, CRC(681be889) SHA1(8044ca7cbb325e6dcadb409f91e0c01b88a1bca7) )
1079   ROM_LOAD16_BYTE( "ae104.el1",     0x2000001, 0x0400000, CRC(e431b798) SHA1(c2c24d4f395bba8c78a45ecf44009a830551e856) )
1080   ROM_LOAD16_BYTE( "ae105.fl1",     0x2800001, 0x0400000, CRC(b7f9ebc1) SHA1(987f664072b43a578b39fa6132aaaccc5fe5bfc2) )
1081   ROM_LOAD16_BYTE( "ae106.gl1",     0x3000001, 0x0200000, CRC(7c50374b) SHA1(40865913125230122072bb13f46fb5fb60c088ea) )
1082
1083   ROM_REGION( 0x080000, REGION_GFX2, ROMREGION_DISPOSE ) // 8x8 4bpp tiles
1084   ROM_LOAD( "ae300w36.bd1",  0x000000, 0x0080000, CRC(e829f29e) SHA1(e56bfe2669ed1d1ae394c644def426db129d97e3) )
1085
1086   ROM_REGION( 0x100000, REGION_GFX3, ROMREGION_DISPOSE ) // 16x16 4bpp tiles
1087   ROM_LOAD( "ae200w74.ba1",  0x000000, 0x0100000, CRC(c1645041) SHA1(323670a6aa2a4524eb968cc0b4d688098ffeeb12) )
1088
1089   ROM_REGION( 0x100000, REGION_GFX4, ROMREGION_DISPOSE ) // 16x16 4bpp tiles
1090   ROM_LOAD( "ae201w75.bb1",  0x000000, 0x0100000, CRC(3f63bdff) SHA1(0d3d57fdc0ec4bceef27c11403b3631d23abadbf) )
1091
1092   ROM_REGION( 0x100000, REGION_GFX5, ROMREGION_DISPOSE ) // 16x16 4bpp tiles
1093   ROM_LOAD( "ae202w76.bc1",  0x000000, 0x0100000, CRC(5cc857ca) SHA1(2553fb5220433acc15dfb726dc064fe333e51d88) )
1094
1095   ROM_REGION( 0x800000, REGION_SOUND1, 0 ) // YMZ280B Samples
1096   ROM_LOAD( "ae400t23.ya1", 0x000000, 0x200000, CRC(c6ffb043) SHA1(e0c6c5f6b840f63c9a685a2c3be66efa4935cbeb) )
1097   ROM_LOAD( "ae401t24.yb1", 0x200000, 0x200000, CRC(d83f1a73) SHA1(412b7ac9ff09a984c28b7d195330d78c4aac3dc5) )
1098
1099   ROM_REGION( 0x100000, REGION_SOUND2, 0 ) // M6295 Samples
1100   ROM_LOAD( "ae500w07.ad1", 0x080000, 0x080000, CRC(3734f92c) SHA1(048555b5aa89eaf983305c439ba08d32b4a1bb80) )
1101ROM_END
1102
1103static MACHINE_RESET( deroon )
7281104{
729   UINT16 *ROM = (UINT16 *)memory_region(REGION_CPU1);
730   ROM[0x39C2/2] = 0x0001;
731   ROM[0x0448/2] = 0x4E71;
732   ROM[0x044A/2] = 0x4E71;
733   ROM[0x04bc/2] = 0x0000;
734   ROM[0x302c/2] = 0x60a4;
735   timer_set(ATTOTIME_IN_SEC(2), NULL,0,reset_callback);
736   gametype=0;
1105   device_read_ptr = 0;
1106   device_status = DS_IDLE;
7371107}
7381108
739static DRIVER_INIT( tkdensho )
1109void tecmosys_decramble(void)
7401110{
741   UINT16 *ROM = (UINT16 *)memory_region(REGION_CPU1);
742   ROM[0x222c/2] = 0x4E71;
743   ROM[0x222c/2] = 0x4E71;
1111   UINT8 *gfxsrc    = memory_region       ( REGION_GFX1 );
1112   size_t  srcsize = memory_region_length( REGION_GFX1 );
1113   int i;
7441114
745   /* interrupt vector */
746   ROM[0x64/2] = 0x0000;
747   ROM[0x66/2] = 0x22c4;
1115   for (i=0; i < srcsize; i+=4)
1116   {
1117      UINT8 tmp[4];
7481118
749   /* protection ? */
750   ROM[0x3a3c/2] = 0x4E71;
751   ROM[0x3a84/2] = 0x4E71;
1119      tmp[2] = ((gfxsrc[i+0]&0xf0)>>0) | ((gfxsrc[i+1]&0xf0)>>4); //  0,1,2,3  8,9,10, 11
1120      tmp[3] = ((gfxsrc[i+0]&0x0f)<<4) | ((gfxsrc[i+1]&0x0f)<<0); // 4,5,6,7, 12,13,14,15
1121      tmp[0] = ((gfxsrc[i+2]&0xf0)>>0) | ((gfxsrc[i+3]&0xf0)>>4);// 16,17,18,19,24,25,26,27
1122      tmp[1] = ((gfxsrc[i+2]&0x0f)<<4) | ((gfxsrc[i+3]&0x0f)>>0);// 20,21,22,23, 28,29,30,31
7521123
753   ROM[0x1759a/2] = 0x4E71; //trap 0
754   ROM[0x04822/2] = 0x4E71;
755   ROM[0x04862/2] = 0x4E71;
1124      gfxsrc[i+0] = tmp[0];
1125      gfxsrc[i+1] = tmp[1];
1126      gfxsrc[i+2] = tmp[2];
1127      gfxsrc[i+3] = tmp[3];
7561128
757   timer_set(ATTOTIME_IN_SEC(2), NULL,0,reset_callback);
758   gametype=1;
1129   }
7591130
7601131}
7611132
762GAME( 1996, deroon,      0, deroon, deroon, deroon,     ROT0, "Tecmo", "Deroon DeroDero", GAME_NOT_WORKING | GAME_NO_SOUND )
763GAME( 1996, tkdensho,    0, deroon, deroon, tkdensho,   ROT0, "Tecmo", "Touki Denshou -Angel Eyes-", GAME_NOT_WORKING | GAME_NO_SOUND )
1133static DRIVER_INIT( deroon )
1134{
1135   tecmosys_decramble();
1136   device_data = &deroon_data;
1137}
7641138
1139static DRIVER_INIT( tkdensho )
1140{
1141   tecmosys_decramble();
1142   device_data = &tkdensho_data;
1143}
1144
1145static DRIVER_INIT( tkdensha )
1146{
1147   tecmosys_decramble();
1148   device_data = &tkdensha_data;
1149}
1150GAME( 1995, deroon,      0, deroon, deroon, deroon,     ROT0, "Tecmo", "Deroon DeroDero", 0 )
1151GAME( 1996, tkdensho,    0, deroon, deroon, tkdensho,   ROT0, "Tecmo", "Touki Denshou -Angel Eyes- (VER. 960614)", 0 )
1152GAME( 1996, tkdensha,    tkdensho, deroon, deroon, tkdensha,   ROT0, "Tecmo", "Touki Denshou -Angel Eyes- (VER. 960427)", 0 )
1153
src/mame/drivers/exidy440.c
r2821r2822
241241
242242static NVRAM_HANDLER( exidy440 )
243243{
244   UINT8 *rom = memory_region(REGION_CPU1);
244245   if (read_or_write)
245246      /* the EEROM lives in the uppermost 8k of the top bank */
246      mame_fwrite(file, &memory_region(REGION_CPU1)[0x10000 + 15 * 0x4000 + 0x2000], 0x2000);
247      mame_fwrite(file, &rom[0x10000 + 15 * 0x4000 + 0x2000], 0x2000);
247248   else
248249   {
249250      if (file)
250         mame_fread(file, &memory_region(REGION_CPU1)[0x10000 + 15 * 0x4000 + 0x2000], 0x2000);
251         mame_fread(file, &rom[0x10000 + 15 * 0x4000 + 0x2000], 0x2000);
251252      else
252         memset(&memory_region(REGION_CPU1)[0x10000 + 15 * 0x4000 + 0x2000], 0, 0x2000);
253         memset(&rom[0x10000 + 15 * 0x4000 + 0x2000], 0, 0x2000);
253254   }
254255}
255256
src/mame/drivers/thayers.c
r2821r2822
77      a COP404L - A ROMless COP420 with 1k of RAM.  I wonder which one is correct?
88
99Todo:
10    Add SIO to the cop420 core.
1110    Fix up my poor interpretation of the hard-to-read schematics.
1211    Write a real SC-01 (SSI-263) emulator for MAME.
1312    Convert to tilemaps.
r2821r2822
293292   }
294293}
295294
296static WRITE8_HANDLER(cop_sk_write)
295static int kb_bit;
296
297static READ8_HANDLER(cop_si_r)
297298{
298   /* I think this data falls off into a black hole - the pins aren't hooked up.
299       The COP400 XAS instruction writes to both SK and SIO, that's why the CPU writes data here at all. */
299   UINT8 data;
300   char port[4];
301   int row = kb_bit / 8;
302   int col = kb_bit % 8;
303
304   sprintf(port, "R%d", row);
305
306   switch (col)
307   {
308   case 0:
309   case 1:
310   case 2:
311   case 3:
312      data = input_port_read(machine, port);
313      return BIT(data, col);
314
315   case 4:
316      return (row == 9);
317
318   default:
319      return 1;
320   }
300321}
301322
302static WRITE8_HANDLER(cop_sio_write)
323static WRITE8_HANDLER(cop_so_w)
303324{
304   /* This data is sent to the CLK pin of the keyboard handling logic.  We don't need to emulate it here. */
325   if (data)
326   {
327      kb_bit++;
328
329      if (kb_bit == 80)
330      {
331         kb_bit = 0;
332      }
333   }
305334}
306335
307
308
309336/* PROGRAM MAPS */
310337static ADDRESS_MAP_START( mainmem, ADDRESS_SPACE_PROGRAM, 8 )
311338   AM_RANGE(0x0000, 0x7fff) AM_ROM
r2821r2822
342369   AM_RANGE(COP400_PORT_L,  COP400_PORT_L)   AM_READWRITE(cop_l_read,cop_l_write)
343370   AM_RANGE(COP400_PORT_G,  COP400_PORT_G)   AM_READWRITE(cop_g_read,cop_g_write)
344371   AM_RANGE(COP400_PORT_D,  COP400_PORT_D)   AM_WRITE(cop_d_write)
345   AM_RANGE(COP400_PORT_SK, COP400_PORT_SK)  AM_WRITE(cop_sk_write)
346   AM_RANGE(COP400_PORT_SIO,COP400_PORT_SIO) AM_READ_PORT("THAYERS_LETTERS") AM_WRITE(cop_sio_write)   /* Unemulated in COP40x core, so nothing happens ATM */
347ADDRESS_MAP_END                                                                              /* This is also very wrong.  The keyboard interface needs to
348                                                                                                                       be understood much better than what I have here */
372   AM_RANGE(COP400_PORT_SK, COP400_PORT_SK)  AM_WRITENOP
373   AM_RANGE(COP400_PORT_SIO,COP400_PORT_SIO) AM_READ(cop_si_r) AM_WRITE(cop_so_w)
374ADDRESS_MAP_END
349375
350376/* PORTS */
351377static INPUT_PORTS_START( thayers )
r2821r2822
388414   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(laserdisc_command_r, 0 )   /* Enter pin on LD player */
389415   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(laserdisc_status_r, 0 )   /* Ready pin on LD player */
390416
391   /* The following 3 port definitions can be combined into one (thus making this scheme work) if the port bit limit is raised from 32 to 64 */
392   /* But maybe there's a better way to do it than what I have here? */
393   /* Or maybe this doesn't even work at all :) */
394417   /* "Scan codes" heisted from Daphne - need to be tested! */
395   PORT_START_TAG("THAYERS_ACTIONS")
396   PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( DEF_STR( No ) ) PORT_CODE( KEYCODE_DEL_PAD )
397   PORT_BIT( 0x31, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( DEF_STR( Yes ) ) PORT_CODE( KEYCODE_0_PAD )
398   PORT_BIT( 0x32, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Items" ) PORT_CODE( KEYCODE_1_PAD )
399   PORT_BIT( 0x33, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Drop Item" ) PORT_CODE( KEYCODE_2_PAD )
400   PORT_BIT( 0x34, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Give Score" ) PORT_CODE( KEYCODE_3_PAD )
401   PORT_BIT( 0x35, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Replay" ) PORT_CODE( KEYCODE_4_PAD )
402   PORT_BIT( 0x36, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Combine Action" ) PORT_CODE( KEYCODE_6_PAD )
403   PORT_BIT( 0x37, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Save Game" ) PORT_CODE( KEYCODE_7_PAD )
404   PORT_BIT( 0x38, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Update" ) PORT_CODE( KEYCODE_8_PAD )
405   PORT_BIT( 0x39, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Hint" ) PORT_CODE( KEYCODE_9_PAD )
418/*
419    PORT_START_TAG("THAYERS_ACTIONS")
420    PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( DEF_STR( No ) ) PORT_CODE( KEYCODE_DEL_PAD )
421    PORT_BIT( 0x31, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( DEF_STR( Yes ) ) PORT_CODE( KEYCODE_0_PAD )
422    PORT_BIT( 0x32, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Items" ) PORT_CODE( KEYCODE_1_PAD )
423    PORT_BIT( 0x33, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Drop Item" ) PORT_CODE( KEYCODE_2_PAD )
424    PORT_BIT( 0x34, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Give Score" ) PORT_CODE( KEYCODE_3_PAD )
425    PORT_BIT( 0x35, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Replay" ) PORT_CODE( KEYCODE_4_PAD )
426    PORT_BIT( 0x36, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Combine Action" ) PORT_CODE( KEYCODE_6_PAD )
427    PORT_BIT( 0x37, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Save Game" ) PORT_CODE( KEYCODE_7_PAD )
428    PORT_BIT( 0x38, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Update" ) PORT_CODE( KEYCODE_8_PAD )
429    PORT_BIT( 0x39, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Hint" ) PORT_CODE( KEYCODE_9_PAD )
406430
407   PORT_START_TAG("THAYERS_LETTERS")
408   PORT_BIT( 0x41, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "A" ) PORT_CODE( KEYCODE_A )
409   PORT_BIT( 0x42, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "B - Silver Wheat" ) PORT_CODE( KEYCODE_B )
410   PORT_BIT( 0x43, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "C - Spell of Seeing" ) PORT_CODE( KEYCODE_C )
411   PORT_BIT( 0x44, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "D - Great Circlet" ) PORT_CODE( KEYCODE_D )
412   PORT_BIT( 0x45, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "E - Black Mace" ) PORT_CODE( KEYCODE_E )
413   PORT_BIT( 0x46, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F - Hunting Horn" ) PORT_CODE( KEYCODE_F )
414   PORT_BIT( 0x47, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "G - Long Bow" ) PORT_CODE( KEYCODE_G )
415   PORT_BIT( 0x48, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "H - Medallion" ) PORT_CODE( KEYCODE_H )
416   PORT_BIT( 0x49, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "I - Crown" ) PORT_CODE( KEYCODE_I )
417   PORT_BIT( 0x4a, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "J - Onyx Seal" ) PORT_CODE( KEYCODE_J )
418   PORT_BIT( 0x4b, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "K - Orb of Quoid" ) PORT_CODE( KEYCODE_K )
419   PORT_BIT( 0x4c, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "L" ) PORT_CODE( KEYCODE_L )
420   PORT_BIT( 0x4d, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "M - Spell of Understanding" ) PORT_CODE( KEYCODE_M )
421   PORT_BIT( 0x4e, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "N - Staff" ) PORT_CODE( KEYCODE_N )
422   PORT_BIT( 0x4f, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "O - Crystal" ) PORT_CODE( KEYCODE_O )
423   PORT_BIT( 0x50, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "P" ) PORT_CODE( KEYCODE_P )
424   PORT_BIT( 0x51, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Q" ) PORT_CODE( KEYCODE_Q )
425   PORT_BIT( 0x52, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "R - Blood Sword" ) PORT_CODE( KEYCODE_R )
426   PORT_BIT( 0x53, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "S - Dagger" ) PORT_CODE( KEYCODE_S )
427   PORT_BIT( 0x54, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "T - Chalice" ) PORT_CODE( KEYCODE_T )
428   PORT_BIT( 0x55, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "U - Cold Fire" ) PORT_CODE( KEYCODE_U )
429   PORT_BIT( 0x56, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "V - Shield" ) PORT_CODE( KEYCODE_V )
430   PORT_BIT( 0x57, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "W - Amulet" ) PORT_CODE( KEYCODE_W )
431   PORT_BIT( 0x58, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "X - Scepter" ) PORT_CODE( KEYCODE_X )
432   PORT_BIT( 0x59, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Y - Coins" ) PORT_CODE( KEYCODE_Y )
433   PORT_BIT( 0x5a, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Z - Spell of Release" ) PORT_CODE( KEYCODE_Z )
431    PORT_START_TAG("THAYERS_LETTERS")
432    PORT_BIT( 0x41, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "A" ) PORT_CODE( KEYCODE_A )
433    PORT_BIT( 0x42, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "B - Silver Wheat" ) PORT_CODE( KEYCODE_B )
434    PORT_BIT( 0x43, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "C - Spell of Seeing" ) PORT_CODE( KEYCODE_C )
435    PORT_BIT( 0x44, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "D - Great Circlet" ) PORT_CODE( KEYCODE_D )
436    PORT_BIT( 0x45, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "E - Black Mace" ) PORT_CODE( KEYCODE_E )
437    PORT_BIT( 0x46, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "F - Hunting Horn" ) PORT_CODE( KEYCODE_F )
438    PORT_BIT( 0x47, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "G - Long Bow" ) PORT_CODE( KEYCODE_G )
439    PORT_BIT( 0x48, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "H - Medallion" ) PORT_CODE( KEYCODE_H )
440    PORT_BIT( 0x49, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "I - Crown" ) PORT_CODE( KEYCODE_I )
441    PORT_BIT( 0x4a, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "J - Onyx Seal" ) PORT_CODE( KEYCODE_J )
442    PORT_BIT( 0x4b, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "K - Orb of Quoid" ) PORT_CODE( KEYCODE_K )
443    PORT_BIT( 0x4c, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "L" ) PORT_CODE( KEYCODE_L )
444    PORT_BIT( 0x4d, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "M - Spell of Understanding" ) PORT_CODE( KEYCODE_M )
445    PORT_BIT( 0x4e, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "N - Staff" ) PORT_CODE( KEYCODE_N )
446    PORT_BIT( 0x4f, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "O - Crystal" ) PORT_CODE( KEYCODE_O )
447    PORT_BIT( 0x50, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "P" ) PORT_CODE( KEYCODE_P )
448    PORT_BIT( 0x51, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Q" ) PORT_CODE( KEYCODE_Q )
449    PORT_BIT( 0x52, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "R - Blood Sword" ) PORT_CODE( KEYCODE_R )
450    PORT_BIT( 0x53, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "S - Dagger" ) PORT_CODE( KEYCODE_S )
451    PORT_BIT( 0x54, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "T - Chalice" ) PORT_CODE( KEYCODE_T )
452    PORT_BIT( 0x55, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "U - Cold Fire" ) PORT_CODE( KEYCODE_U )
453    PORT_BIT( 0x56, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "V - Shield" ) PORT_CODE( KEYCODE_V )
454    PORT_BIT( 0x57, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "W - Amulet" ) PORT_CODE( KEYCODE_W )
455    PORT_BIT( 0x58, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "X - Scepter" ) PORT_CODE( KEYCODE_X )
456    PORT_BIT( 0x59, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Y - Coins" ) PORT_CODE( KEYCODE_Y )
457    PORT_BIT( 0x5a, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "Z - Spell of Release" ) PORT_CODE( KEYCODE_Z )
434458
435   PORT_START_TAG("THAYERS_NUMBERS")
436   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "1 - Clear" ) PORT_CODE( KEYCODE_LCONTROL )
437   PORT_BIT( 0x81, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "2" ) PORT_CODE( KEYCODE_RCONTROL )
438   PORT_BIT( 0x82, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "3 - Enter" ) PORT_CODE( KEYCODE_ENTER )
439   PORT_BIT( 0x83, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "4 - Space" ) PORT_CODE( KEYCODE_SPACE )
459    PORT_START_TAG("THAYERS_NUMBERS")
460    PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "1 - Clear" ) PORT_CODE( KEYCODE_LCONTROL )
461    PORT_BIT( 0x81, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "2" ) PORT_CODE( KEYCODE_RCONTROL )
462    PORT_BIT( 0x82, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "3 - Enter" ) PORT_CODE( KEYCODE_ENTER )
463    PORT_BIT( 0x83, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME( "4 - Space" ) PORT_CODE( KEYCODE_SPACE )
464*/
465   PORT_START_TAG("R0")
466   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
467   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
468   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
469   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
470
471   PORT_START_TAG("R1")
472   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
473   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
474   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
475   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
476
477   PORT_START_TAG("R2")
478   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
479   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
480   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
481   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
482
483   PORT_START_TAG("R3")
484   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
485   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
486   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
487   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
488
489   PORT_START_TAG("R4")
490   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
491   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
492   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
493   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
494
495   PORT_START_TAG("R5")
496   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
497   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
498   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
499   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
500
501   PORT_START_TAG("R6")
502   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
503   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
504   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
505   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
506
507   PORT_START_TAG("R7")
508   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
509   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
510   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
511   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
512
513   PORT_START_TAG("R8")
514   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
515   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
516   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
517   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
518
519   PORT_START_TAG("R9")
520   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER )
521   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER )
522   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER )
523   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER )
440524INPUT_PORTS_END
441525
442
443526static MACHINE_START( thayers )
444527{
445528   discinfo = laserdisc_init(LASERDISC_TYPE_LDV1000, get_disk_handle(0), 0);
446   return;
447529}
448530
449531static INTERRUPT_GEN( vblank_callback_thayers )
r2821r2822
451533   laserdisc_vsync(discinfo);
452534}
453535
536static COP400_INTERFACE( thayers_cop_intf )
537{
538   COP400_CKI_DIVISOR_16, // ???
539   COP400_CKO_OSCILLATOR_OUTPUT, // ???
540   COP400_MICROBUS_DISABLED
541};
454542
455543/* DRIVER */
456544static MACHINE_DRIVER_START( thayers )
r2821r2822
466554   MDRV_CPU_ADD(COP420, SCHEMATIC_CLOCK/2/8)      /* Can't read the schematics, but this is what daphne says */
467555   MDRV_CPU_PROGRAM_MAP(copmem,0)
468556   MDRV_CPU_IO_MAP(copio,0)
557   MDRV_CPU_CONFIG(thayers_cop_intf)
469558
470559/*  video */
471560
src/mame/drivers/dambustr.c
r2821r2822
147147{
148148   int i, j, tmp;
149149   int tmpram[16];
150   UINT8 *rom = memory_region(REGION_CPU1);
151   UINT8 *usr = memory_region(REGION_USER1);
152   UINT8 *gfx = memory_region(REGION_GFX1);
150153
151154   // Bit swap addresses
152155   for(i=0; i<4096*4; i++) {
153      memory_region(REGION_CPU1)[i] =
154      memory_region(REGION_USER1)[BITSWAP16(i,15,14,13,12, 4,10,9,8,7,6,5,3,11,2,1,0)];
156      rom[i] = usr[BITSWAP16(i,15,14,13,12, 4,10,9,8,7,6,5,3,11,2,1,0)];
155157   };
156158
157159   // Swap program ROMs
158160   for(i=0; i<0x1000; i++) {
159      tmp = memory_region(REGION_CPU1)[0x5000+i];
160      memory_region(REGION_CPU1)[0x5000+i] = memory_region(REGION_CPU1)[0x6000+i];
161      memory_region(REGION_CPU1)[0x6000+i] = memory_region(REGION_CPU1)[0x1000+i];
162      memory_region(REGION_CPU1)[0x1000+i] = tmp;
161      tmp = rom[0x5000+i];
162      rom[0x5000+i] = rom[0x6000+i];
163      rom[0x6000+i] = rom[0x1000+i];
164      rom[0x1000+i] = tmp;
163165   };
164166
165167   // Bit swap in $1000-$1fff and $4000-$5fff
166168   for(i=0; i<0x1000; i++) {
167      memory_region(REGION_CPU1)[0x1000+i] =
168      BITSWAP8(memory_region(REGION_CPU1)[0x1000+i],7,6,5,1,3,2,4,0);
169      memory_region(REGION_CPU1)[0x4000+i] =
170      BITSWAP8(memory_region(REGION_CPU1)[0x4000+i],7,6,5,1,3,2,4,0);
171      memory_region(REGION_CPU1)[0x5000+i] =
172      BITSWAP8(memory_region(REGION_CPU1)[0x5000+i],7,6,5,1,3,2,4,0);
169      rom[0x1000+i] =   BITSWAP8(rom[0x1000+i],7,6,5,1,3,2,4,0);
170      rom[0x4000+i] =   BITSWAP8(rom[0x4000+i],7,6,5,1,3,2,4,0);
171      rom[0x5000+i] =   BITSWAP8(rom[0x5000+i],7,6,5,1,3,2,4,0);
173172   };
174173
175174   // Swap graphics ROMs
176175   for(i=0;i<0x4000;i+=16)   {
177176      for(j=0; j<16; j++)
178         tmpram[j] = memory_region(REGION_GFX1)[i+j];
177         tmpram[j] = gfx[i+j];
179178      for(j=0; j<8; j++) {
180         memory_region(REGION_GFX1)[i+j] = tmpram[j*2];
181         memory_region(REGION_GFX1)[i+j+8] = tmpram[j*2+1];
179         gfx[i+j] = tmpram[j*2];
180         gfx[i+j+8] = tmpram[j*2+1];
182181      };
183182   };
184183}
src/mame/drivers/aztarac.c
r2821r2822
6060
6161static READ16_HANDLER( joystick_r )
6262{
63    return (((input_port_read_indexed(machine, 0) - 0xf) << 8) |
64            ((input_port_read_indexed(machine, 1) - 0xf) & 0xff));
63    return (((input_port_read(machine, "IN0") - 0xf) << 8) |
64            ((input_port_read(machine, "IN1") - 0xf) & 0xff));
6565}
6666
6767
src/mame/drivers/tatsumi.c
r2821r2822
12411241{
12421242   UINT8 *dst = memory_region(REGION_GFX1);
12431243   UINT8 *src1 = memory_region(REGION_GFX2);
1244   int len1 = memory_region_length(REGION_GFX2);
12441245   UINT8 *src2 = memory_region(REGION_GFX3);
1246   int len2 = memory_region_length(REGION_GFX3);
12451247   int i;
1246   for (i=0; i<memory_region_length(REGION_GFX2); i+=32) {
1248   for (i=0; i<len2; i+=32) {
12471249      memcpy(dst,src1,32);
12481250      src1+=32;
12491251      dst+=32;
r2821r2822
12541256
12551257   dst = memory_region(REGION_CPU1);
12561258   memcpy(cyclwarr_cpua_ram,dst,8);
1257   memory_set_bankptr(1, memory_region(REGION_CPU1));
1259   memory_set_bankptr(1, dst);
12581260
12591261   dst = memory_region(REGION_CPU2);
12601262   memcpy(cyclwarr_cpub_ram,dst,8);
1261   memory_set_bankptr(2, memory_region(REGION_CPU2));
1263   memory_set_bankptr(2, dst);
12621264
12631265   // Copy sprite & palette data out of GFX rom area
1264   tatsumi_rom_sprite_lookup1 = memory_region(REGION_GFX2);
1265   tatsumi_rom_sprite_lookup2 = memory_region(REGION_GFX3);
1266   tatsumi_rom_clut0 = memory_region(REGION_GFX2)+ memory_region_length(REGION_GFX2) - 0x1000;
1267   tatsumi_rom_clut1 = memory_region(REGION_GFX3)+ memory_region_length(REGION_GFX3) - 0x1000;
1266   tatsumi_rom_sprite_lookup1 = src1;
1267   tatsumi_rom_sprite_lookup2 = src2;
1268   tatsumi_rom_clut0 = src1 + len1 - 0x1000;
1269   tatsumi_rom_clut1 = src2 + len2 - 0x1000;
12681270
12691271   tatsumi_reset();
12701272}
src/mame/drivers/gbusters.c
r2821r2822
8080   /* other bits unused/unknown */
8181   if (data & 0xf8)
8282   {
83#if 0
8384      char baf[40];
85      sprintf(baf,"ccnt = %02x", data);
86      popmessage(baf);
87#endif
8488      logerror("%04x: (ccount) write %02x\n",activecpu_get_pc(), data);
85      sprintf(baf,"ccnt = %02x", data);
86//      popmessage(baf);
8789   }
8890}
8991
src/mame/drivers/meadows.c
r2821r2822
791791      0x01,0x80, 0x03,0xc0, 0x03,0xc0, 0x01,0x80
792792   };
793793   int i;
794   UINT8 *gfx2 = memory_region(REGION_GFX2);
795   UINT8 *gfx3 = memory_region(REGION_GFX3);
796   UINT8 *gfx4 = memory_region(REGION_GFX4);
797   UINT8 *gfx5 = memory_region(REGION_GFX5);
798   int len3 = memory_region_length(REGION_GFX3);
799   int len4 = memory_region_length(REGION_GFX4);
794800
795   memcpy(memory_region(REGION_GFX3),memory_region(REGION_GFX2),memory_region_length(REGION_GFX3));
801   memcpy(gfx3,gfx2,len3);
796802
797   for (i = 0; i < memory_region_length(REGION_GFX4); i += 16*2)
803   for (i = 0; i < len4; i += 16*2)
798804   {
799      memcpy(memory_region(REGION_GFX4) + i, ball, sizeof(ball));
800      memcpy(memory_region(REGION_GFX5) + i, ball, sizeof(ball));
805      memcpy(gfx4 + i, ball, sizeof(ball));
806      memcpy(gfx5 + i, ball, sizeof(ball));
801807   }
802808}
803809
src/mame/drivers/thedeep.c
r2821r2822
8383      case 0x32:
8484      case 0x33:
8585      {
86         UINT8 *rom;
8687         int new_rombank = protection_command & 3;
8788         if (rombank == new_rombank)   break;
8889         rombank = new_rombank;
89         memory_set_bankptr(1, memory_region(REGION_CPU1) + 0x10000 + rombank * 0x4000);
90         rom = memory_region(REGION_CPU1);
91         memory_set_bankptr(1, rom + 0x10000 + rombank * 0x4000);
9092         /* there's code which falls through from the fixed ROM to bank #1, I have to */
9193         /* copy it there otherwise the CPU bank switching support will not catch it. */
92         memcpy(memory_region(REGION_CPU1) + 0x08000,memory_region(REGION_CPU1) + 0x10000 + rombank * 0x4000, 0x4000);
94         memcpy(rom + 0x08000, rom + 0x10000 + rombank * 0x4000, 0x4000);
9395      }
9496      break;
9597
src/mame/drivers/zr107.c
r2821r2822
5656
5757
5858// defined in drivers/gticlub.c
59extern READ32_HANDLER(lanc_r);
60extern WRITE32_HANDLER(lanc_w);
59extern READ8_HANDLER(K056230_r);
60extern WRITE8_HANDLER(K056230_w);
6161extern READ32_HANDLER(lanc_ram_r);
6262extern WRITE32_HANDLER(lanc_ram_w);
6363
r2821r2822
312312   AM_RANGE(0x78040000, 0x7804000f) AM_MIRROR(0x80000000) AM_READWRITE(K001006_0_r, K001006_0_w)
313313   AM_RANGE(0x780c0000, 0x780c0007) AM_MIRROR(0x80000000) AM_READWRITE(cgboard_dsp_comm_r_ppc, cgboard_dsp_comm_w_ppc)
314314   AM_RANGE(0x7e000000, 0x7e003fff) AM_MIRROR(0x80000000) AM_READWRITE(sysreg_r, sysreg_w)
315   AM_RANGE(0x7e008000, 0x7e009fff) AM_MIRROR(0x80000000) AM_READWRITE(lanc_r, lanc_w)            /* LANC registers */
315   AM_RANGE(0x7e008000, 0x7e009fff) AM_MIRROR(0x80000000) AM_READWRITE8(K056230_r, K056230_w, 0xffffffff)            /* LANC registers */
316316   AM_RANGE(0x7e00a000, 0x7e00bfff) AM_MIRROR(0x80000000) AM_READWRITE(lanc_ram_r, lanc_ram_w)      /* LANC Buffer RAM (27E) */
317317   AM_RANGE(0x7e00c000, 0x7e00c007) AM_MIRROR(0x80000000) AM_WRITE(K056800_host_w)
318318   AM_RANGE(0x7e00c008, 0x7e00c00f) AM_MIRROR(0x80000000) AM_READ(K056800_host_r)
r2821r2822
340340   AM_RANGE(0x78080000, 0x7808000f) AM_MIRROR(0x80000000) AM_READWRITE(K001006_1_r, K001006_1_w)
341341   AM_RANGE(0x780c0000, 0x780c0007) AM_MIRROR(0x80000000) AM_READWRITE(cgboard_dsp_comm_r_ppc, cgboard_dsp_comm_w_ppc)
342342   AM_RANGE(0x7e000000, 0x7e003fff) AM_MIRROR(0x80000000) AM_READWRITE(sysreg_r, sysreg_w)
343   AM_RANGE(0x7e008000, 0x7e009fff) AM_MIRROR(0x80000000) AM_READWRITE(lanc_r, lanc_w)            /* LANC registers */
343   AM_RANGE(0x7e008000, 0x7e009fff) AM_MIRROR(0x80000000) AM_READWRITE8(K056230_r, K056230_w, 0xffffffff)            /* LANC registers */
344344   AM_RANGE(0x7e00a000, 0x7e00bfff) AM_MIRROR(0x80000000) AM_READWRITE(lanc_ram_r, lanc_ram_w)      /* LANC Buffer RAM (27E) */
345345   AM_RANGE(0x7e00c000, 0x7e00c007) AM_MIRROR(0x80000000) AM_WRITE(K056800_host_w)
346346   AM_RANGE(0x7e00c008, 0x7e00c00f) AM_MIRROR(0x80000000) AM_READ(K056800_host_r)
r2821r2822
541541
542542INPUT_PORTS_END
543543
544static const ppc_config zr107_ppc_cfg =
545{
546   PPC_MODEL_403GA
547};
548
549544static sharc_config sharc_cfg =
550545{
551546   BOOT_MODE_EPROM
r2821r2822
570565static MACHINE_DRIVER_START( zr107 )
571566
572567   /* basic machine hardware */
573   MDRV_CPU_ADD(PPC403, 64000000/2)   /* PowerPC 403GA 32MHz */
574   MDRV_CPU_CONFIG(zr107_ppc_cfg)
568   MDRV_CPU_ADD(PPC403GA, 64000000/2)   /* PowerPC 403GA 32MHz */
575569   MDRV_CPU_PROGRAM_MAP(zr107_map, 0)
576570   MDRV_CPU_VBLANK_INT("main", zr107_vblank)
577571
r2821r2822
615609static MACHINE_DRIVER_START( jetwave )
616610
617611   /* basic machine hardware */
618   MDRV_CPU_ADD(PPC403, 64000000/2)   /* PowerPC 403GA 32MHz */
619   MDRV_CPU_CONFIG(zr107_ppc_cfg)
612   MDRV_CPU_ADD(PPC403GA, 64000000/2)   /* PowerPC 403GA 32MHz */
620613   MDRV_CPU_PROGRAM_MAP(jetwave_map, 0)
621614   MDRV_CPU_VBLANK_INT("main", zr107_vblank)
622615
src/mame/drivers/amspdwy.c
r2821r2822
4646static READ8_HANDLER( amspdwy_wheel_##_n_##_r ) \
4747{ \
4848   static UINT8 wheel_old, ret; \
49   UINT8 wheel = input_port_read_indexed(machine, 5 + _n_); \
49   char port1[4], port2[4]; \
50   UINT8 wheel; \
51   sprintf(port1, "IN%d", 5 + _n_); \
52   wheel = input_port_read(machine, port1); \
5053   if (wheel != wheel_old) \
5154   { \
5255      wheel = (wheel & 0x7fff) - (wheel & 0x8000); \
r2821r2822
5457      else               ret = ((-wheel) & 0xf) | 0x10; \
5558      wheel_old = wheel; \
5659   } \
57   return ret | input_port_read_indexed(machine, 2 + _n_); \
60   sprintf(port2, "IN%d", 2 + _n_); \
61   return ret | input_port_read(machine, port2); \
5862}
5963AMSPDWY_WHEEL_R( 0 )
6064AMSPDWY_WHEEL_R( 1 )
r2821r2822
6266
6367static READ8_HANDLER( amspdwy_sound_r )
6468{
65   return (YM2151_status_port_0_r(machine,0) & ~ 0x30) | input_port_read_indexed(machine, 4);
69   return (YM2151_status_port_0_r(machine,0) & ~ 0x30) | input_port_read(machine, "IN4");
6670}
6771
6872static WRITE8_HANDLER( amspdwy_sound_w )
src/mame/drivers/atarig1.c
r2821r2822
110110
111111static READ16_HANDLER( special_port0_r )
112112{
113   int temp = input_port_read_indexed(machine, 0);
113   int temp = input_port_read(machine, "IN0");
114114   if (atarigen_cpu_to_sound_ready) temp ^= 0x1000;
115115   temp ^= 0x2000;      /* A2DOK always high for now */
116116   return temp;
r2821r2822
125125
126126static READ16_HANDLER( a2d_data_r )
127127{
128   char port[5];
129
128130   /* Pit Fighter has no A2D, just another input port */
129131   if (atarig1_pitfight)
130      return input_port_read_indexed(machine, 1);
132      return input_port_read(machine, "ADC0");
131133
132134   /* otherwise, assume it's hydra */
133135   if (which_input < 3)
134      return input_port_read_indexed(machine, 1 + which_input) << 8;
136   {
137      sprintf(port, "ADC%d", which_input);
138      return input_port_read(machine, port) << 8;
139   }
135140
136141   return 0;
137142}
r2821r2822
250255 *************************************/
251256
252257static INPUT_PORTS_START( hydra )
253   PORT_START      /* fc0000 */
258   PORT_START_TAG("IN0")      /* fc0000 */
254259   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON5 )
255260   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 )
256261   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON6 )
r2821r2822
262267   PORT_SERVICE( 0x4000, IP_ACTIVE_LOW )
263268   PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_VBLANK )
264269
265   PORT_START      /* ADC 0 @ fc8000 */
270   PORT_START_TAG("ADC0")      /* ADC 0 @ fc8000 */
266271   PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10)
267272   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
268273
269   PORT_START      /* ADC 1 @ fc8000 */
274   PORT_START_TAG("ADC1")      /* ADC 1 @ fc8000 */
270275   PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_Y ) PORT_SENSITIVITY(70) PORT_KEYDELTA(10)
271276   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
272277
273   PORT_START      /* ADC 2 @ fc8000 */
278   PORT_START_TAG("ADC2")      /* ADC 2 @ fc8000 */
274279   PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(16)
275280
276281   JSA_II_PORT      /* audio board port */
r2821r2822
280285
281286
282287static INPUT_PORTS_START( pitfight )
283   PORT_START      /* fc0000 */
288   PORT_START_TAG("IN0")      /* fc0000 */
284289   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
285290   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
286291   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
r2821r2822
288293   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
289294   PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
290295   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
291   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_START1 )
292296   PORT_BIT( 0x0f80, IP_ACTIVE_LOW, IPT_UNUSED )
293297   PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNUSED )
294298   PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_UNUSED )
295299   PORT_SERVICE( 0x4000, IP_ACTIVE_LOW )
296300   PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_VBLANK )
297301
298   PORT_START      /* fc8000 */
302   PORT_START_TAG("ADC0")      /* fc8000 */
299303   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3)
300304   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(3)
301305   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3)
r2821r2822
303307   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3)
304308   PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3)
305309   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3)
306   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_START3 )
307310   PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )
308311   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
309312   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
r2821r2822
312315   PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
313316   PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
314317   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
315   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_START2 )
316318   PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
317319
318   PORT_START      /* not used */
320   PORT_START_TAG("ADC1")      /* not used */
319321   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
320322
321   PORT_START      /* not used */
323   PORT_START_TAG("ADC2")      /* not used */
322324   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
323325
324326   JSA_II_PORT      /* audio board port */
r2821r2822
328330
329331
330332static INPUT_PORTS_START( pitfighj )
331   PORT_START      /* fc0000 */
333   PORT_START_TAG("IN0")      /* fc0000 */
332334   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
333335   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
334336   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
r2821r2822
336338   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
337339   PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
338340   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
339   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_START1 )
340341   PORT_BIT( 0x0f80, IP_ACTIVE_LOW, IPT_UNUSED )
341342   PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNUSED )
342343   PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_UNUSED )
343344   PORT_SERVICE( 0x4000, IP_ACTIVE_LOW )
344345   PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_VBLANK )
345346
346   PORT_START      /* fc8000 */
347   PORT_START_TAG("ADC0")      /* fc8000 */
347348   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNKNOWN )
348349   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
349350   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
r2821r2822
352353   PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
353354   PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
354355   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
355   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_START2 )
356356   PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
357357
358   PORT_START      /* not used */
358   PORT_START_TAG("ADC1")      /* not used */
359359   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
360360
361   PORT_START      /* not used */
361   PORT_START_TAG("ADC2")      /* not used */
362362   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
363363
364364   JSA_II_PORT      /* audio board port */
src/mame/drivers/toobin.c
r2821r2822
152152
153153static INPUT_PORTS_START( toobin )
154154   PORT_START   /* ff8800 */
155   PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 R Paddle Forward") PORT_CODE(KEYCODE_L) PORT_PLAYER(2)
156   PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 L Paddle Forward") PORT_CODE(KEYCODE_J) PORT_PLAYER(2)
157   PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 L Paddle Backward") PORT_CODE(KEYCODE_U) PORT_PLAYER(2)
158   PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 R Paddle Backward") PORT_CODE(KEYCODE_O) PORT_PLAYER(2)
159   PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 R Paddle Forward") PORT_CODE(KEYCODE_D) PORT_PLAYER(1)
160   PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 L Paddle Forward") PORT_CODE(KEYCODE_A) PORT_PLAYER(1)
161   PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 L Paddle Backward") PORT_CODE(KEYCODE_Q) PORT_PLAYER(1)
162   PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 R Paddle Backward") PORT_CODE(KEYCODE_E) PORT_PLAYER(1)
163   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
164   PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Throw") PORT_CODE(KEYCODE_LCONTROL) PORT_PLAYER(1)
165   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START2 )
166   PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 Throw") PORT_CODE(KEYCODE_RCONTROL) PORT_PLAYER(2)
155   PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 R Paddle Forward") PORT_CODE(KEYCODE_L) PORT_PLAYER(2)
156   PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 L Paddle Forward") PORT_CODE(KEYCODE_J) PORT_PLAYER(2)
157   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 L Paddle Backward") PORT_CODE(KEYCODE_U) PORT_PLAYER(2)
158   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 R Paddle Backward") PORT_CODE(KEYCODE_O) PORT_PLAYER(2)
159   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 R Paddle Forward") PORT_CODE(KEYCODE_D) PORT_PLAYER(1)
160   PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 L Paddle Forward") PORT_CODE(KEYCODE_A) PORT_PLAYER(1)
161   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 L Paddle Backward") PORT_CODE(KEYCODE_Q) PORT_PLAYER(1)
162   PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 R Paddle Backward") PORT_CODE(KEYCODE_E) PORT_PLAYER(1)
163   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Throw") PORT_CODE(KEYCODE_LCONTROL) PORT_PLAYER(1)
164   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 Throw") PORT_CODE(KEYCODE_RCONTROL) PORT_PLAYER(2)
167165   PORT_BIT( 0xfc00, IP_ACTIVE_LOW, IPT_UNUSED )
168166
169167   PORT_START   /* ff9000 */
src/mame/drivers/mcr68.c
r2821r2822
591591   PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_SERVICE1 )
592592   PORT_SERVICE( 0x0080, IP_ACTIVE_LOW )
593593   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
594   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
595594   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
596   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_START2 )
597595   PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED/* credit 1 w/bill */ )
598596   PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED/* credit 2 w/bill */ )
599597   PORT_BIT( 0xf000, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
770768   PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
771769   PORT_BIT( 0x0f00, IP_ACTIVE_LOW, IPT_UNUSED )
772770   PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
773   PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_START1 )
774771   PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
775772   PORT_BIT( 0xc000, IP_ACTIVE_LOW, IPT_UNUSED )
776773
src/mame/drivers/nmg5.c
r2821r2822
561561   PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Demo_Sounds ) )  PORT_DIPLOCATION("SW1:7")
562562   PORT_DIPSETTING(      0x0000, DEF_STR( Off ) )
563563   PORT_DIPSETTING(      0x0002, DEF_STR( On ) )
564   PORT_DIPNAME( 0x0020, 0x0020, "1P Vs 2P Rounds" )       PORT_DIPLOCATION("SW1:6")     // See notes
564   PORT_DIPNAME( 0x0004, 0x0004, "1P Vs 2P Rounds" )       PORT_DIPLOCATION("SW1:6")     // See notes
565565   PORT_DIPSETTING(      0x0000, "Best of 1" )             /* 1 winning round needed */
566   PORT_DIPSETTING(      0x0020, "Best of 3" )             /* 2 winning rounds needed */
566   PORT_DIPSETTING(      0x0004, "Best of 3" )             /* 2 winning rounds needed */
567567   PORT_DIPNAME( 0x0008, 0x0000, "Nudity" )                PORT_DIPLOCATION("SW1:5")     // See notes
568568   PORT_DIPSETTING(      0x0008, "Soft only" )
569569   PORT_DIPSETTING(      0x0000, "Soft and Hard" )
src/mame/drivers/2mindril.c
r2821r2822
238238static DRIVER_INIT( drill )
239239{
240240   // rearrange gfx roms to something we can decode, two of the roms form 4bpp of the graphics, the third forms another 2bpp but is in a different format
241   UINT32 *src    = (UINT32*)memory_region       ( REGION_GFX2 );
242   UINT32 *dst    = (UINT32*)memory_region       ( REGION_GFX1 );// + 0x400000;
241   UINT32 *src = (UINT32*)memory_region( REGION_GFX2 );
242   UINT32 *dst = (UINT32*)memory_region( REGION_GFX1 );// + 0x400000;
243   UINT8 *rom = memory_region( REGION_CPU1 );
243244   int i;
244245
245246   for (i=0; i< 0x400000/4; i++)
r2821r2822
250251   }
251252
252253   //enable some kind of debug mode (ignore errors)
253   memory_region( REGION_CPU1)[0x7fffb]=0;
254   memory_region( REGION_CPU1)[0x7fffc]=0;
255   memory_region( REGION_CPU1)[0x7fffd]=0;
256   memory_region( REGION_CPU1)[0x7fffe]=0;
254   rom[0x7fffb]=0;
255   rom[0x7fffc]=0;
256   rom[0x7fffd]=0;
257   rom[0x7fffe]=0;
257258}
258259
259260GAME( 1993, 2mindril,    0,        drill,    drill,    drill, ROT0,  "Taito", "Two Minute Drill", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS )
src/mame/drivers/tumbleb.c
r2821r2822
12971297   PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) )      PORT_DIPLOCATION("SW2:1")
12981298   PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
12991299   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
1300   PORT_SERVICE( 0x01, IP_ACTIVE_LOW )
13011300INPUT_PORTS_END
13021301
13031302static INPUT_PORTS_START( chokchok )
r2821r2822
21692168   /* copy protection data every reset */
21702169
21712170   UINT16 *PROTDATA = (UINT16*)memory_region(REGION_USER1);
2172   int i;
2171   int i, len = memory_region_length(REGION_USER1);
21732172
2174   for (i = 0;i < memory_region_length( REGION_USER1 )/2;i++)
2173   for (i = 0;i < len/2;i++)
21752174      tumblepb_mainram[0x000/2 + i] = PROTDATA[i];
21762175
21772176}
r2821r2822
33753374
33763375//  UINT16 *HCROM = (UINT16*)memory_region(REGION_CPU1);
33773376   UINT16 *PROTDATA = (UINT16*)memory_region(REGION_USER1);
3378   int i;
3377   int i, len = memory_region_length(REGION_USER1);
33793378   /* simulate RAM initialization done by the protection MCU */
33803379   /* verified on real hardware */
33813380//  static UINT16 htchctch_mcu68k[] =
r2821r2822
33873386//  for (i = 0;i < sizeof(htchctch_mcu68k)/sizeof(htchctch_mcu68k[0]);i++)
33883387//      tumblepb_mainram[0x000/2 + i] = htchctch_mcu68k[i];
33893388
3390   for (i = 0;i < memory_region_length( REGION_USER1 )/2;i++)
3389   for (i = 0;i < len/2;i++)
33913390      tumblepb_mainram[0x000/2 + i] = PROTDATA[i];
33923391
33933392
src/mame/drivers/superqix.c
r2821r2822
136136static void pbillian_sh_start(void)
137137{
138138   UINT8 *src = memory_region(REGION_SOUND1);
139   int i;
139   int i, len = memory_region_length(REGION_SOUND1);
140140
141141   /* convert 8-bit unsigned samples to 8-bit signed */
142   samplebuf = auto_malloc(memory_region_length(REGION_SOUND1) * 2);
143   for (i = 0;i < memory_region_length(REGION_SOUND1);i++)
142   samplebuf = auto_malloc(len * 2);
143   for (i = 0;i < len;i++)
144144      samplebuf[i] = (INT8)(src[i] ^ 0x80) * 256;
145145}
146146
src/mame/drivers/cojag.c
r2821r2822
219219
220220static MACHINE_RESET( cojag )
221221{
222   UINT8 *rom = memory_region(REGION_USER2);
223
222224   /* 68020 only: copy the interrupt vectors into RAM */
223225   if (!cojag_is_r3000)
224226      memcpy(jaguar_shared_ram, rom_base, 0x10);
225227
226228   /* configure banks for gfx/sound ROMs */
227   if (memory_region(REGION_USER2))
229   if (rom)
228230   {
229231      /* graphics banks */
230232      if (cojag_is_r3000)
231233      {
232         memory_configure_bank(1, 0, 2, memory_region(REGION_USER2) + 0x800000, 0x400000);
234         memory_configure_bank(1, 0, 2, rom + 0x800000, 0x400000);
233235         memory_set_bank(1, 0);
234236      }
235      memory_configure_bank(8, 0, 2, memory_region(REGION_USER2) + 0x800000, 0x400000);
237      memory_configure_bank(8, 0, 2, rom + 0x800000, 0x400000);
236238      memory_set_bank(8, 0);
237239
238240      /* sound banks */
239      memory_configure_bank(2, 0, 8, memory_region(REGION_USER2) + 0x000000, 0x200000);
240      memory_configure_bank(9, 0, 8, memory_region(REGION_USER2) + 0x000000, 0x200000);
241      memory_configure_bank(2, 0, 8, rom + 0x000000, 0x200000);
242      memory_configure_bank(9, 0, 8, rom + 0x000000, 0x200000);
241243      memory_set_bank(2, 0);
242244      memory_set_bank(9, 0);
243245   }
src/mame/drivers/wilytowr.c
r2821r2822
392392   PORT_DIPNAME( 0x10, 0x00, "Stop Mode (Cheat)")      PORT_DIPLOCATION("SW2:!5")
393393   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
394394   PORT_DIPSETTING(    0x10, DEF_STR( On ) )
395   PORT_DIPUNUSED_DIPLOC( 0x08, 0x00, "SW2:!6" )      /* Listed as "Unused" */
395   PORT_DIPUNUSED_DIPLOC( 0x20, 0x00, "SW2:!6" )      /* Listed as "Unused" */
396396   PORT_DIPNAME( 0x40, 0x00, "Invulnerability (Cheat)") PORT_DIPLOCATION("SW2:!7")
397397   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
398398   PORT_DIPSETTING(    0x40, DEF_STR( On ) )
src/mame/drivers/looping.c
r2821r2822
5656#include "sound/dac.h"
5757#include "sound/5220intf.h"
5858#include "video/resnet.h"
59#include "cpu/cop400/cop400.h"
5960
6061
6162/*************************************
r2821r2822
570571   NULL
571572};
572573
574static COP400_INTERFACE( looping_cop_intf )
575{
576   COP400_CKI_DIVISOR_16, // ???
577   COP400_CKO_OSCILLATOR_OUTPUT, // ???
578   COP400_MICROBUS_DISABLED
579};
573580
574
575581/*************************************
576582 *
577583 *  Machine drivers
r2821r2822
594600   MDRV_CPU_ADD(COP420, COP_CLOCK)
595601   MDRV_CPU_PROGRAM_MAP(looping_cop_map,0)
596602   MDRV_CPU_DATA_MAP(looping_cop_data_map,0)
603   MDRV_CPU_CONFIG(looping_cop_intf)
597604
598605   MDRV_MACHINE_START(looping)
599606
src/mame/drivers/badlands.c
r2821r2822
359359   PORT_START      /* fe4000 */
360360   PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED )
361361   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
362   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_START1 )
363362   PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
364   PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_START2 )
365363   PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_VBLANK )
366364   PORT_SERVICE( 0x0080, IP_ACTIVE_LOW )
367365   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
387385   PORT_START      /* fake for pedals */
388386   PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1)
389387   PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
390   PORT_BIT( 0xfffe, IP_ACTIVE_HIGH, IPT_UNUSED )
388   PORT_BIT( 0xfffc, IP_ACTIVE_HIGH, IPT_UNUSED )
391389INPUT_PORTS_END
392390
393391
src/mame/drivers/astinvad.c
r2821r2822
280280   if (bits_gone_hi & 0x08) sample_start(5, SND_FLEET4, 0);
281281   if (bits_gone_hi & 0x10) sample_start(4, SND_UFOHIT, 0);
282282
283   screen_flip = (input_port_read_indexed(machine, 3) & data & 0x20) ? 0xff : 0x00;
283   screen_flip = (input_port_read(machine, "IN3") & data & 0x20) ? 0xff : 0x00;
284284}
285285
286286
r2821r2822
311311
312312   if (bits_gone_hi & 0x04) sample_start(3, SND_INVADERHIT, 0);
313313
314   screen_flip = (input_port_read_indexed(machine, 3) & data & 0x80) ? 0xff : 0x00;
314   screen_flip = (input_port_read(machine, "IN3") & data & 0x80) ? 0xff : 0x00;
315315}
316316
317317
src/mame/drivers/boogwing.c
r2821r2822
8383#include "sound/2151intf.h"
8484#include "sound/okim6295.h"
8585
86extern void deco102_decrypt(int region, int address_xor, int data_select_xor, int opcode_select_xor);
8786VIDEO_START(boogwing);
8887VIDEO_UPDATE(boogwing);
8988
src/mame/drivers/supertnk.c
r2821r2822
218218static void get_pens(pen_t *pens)
219219{
220220   offs_t i;
221   const UINT8 *prom = memory_region(REGION_PROMS);
221222
222223   for (i = 0; i < NUM_PENS; i++)
223224   {
224      UINT8 data = memory_region(REGION_PROMS)[i];
225      UINT8 data = prom[i];
225226
226227      pens[i] = MAKE_RGB(pal1bit(data >> 2), pal1bit(data >> 5), pal1bit(data >> 6));
227228   }
r2821r2822
475476{
476477   /* decode the TMS9980 ROMs */
477478   offs_t offs;
479   UINT8 *rom = memory_region(REGION_CPU1);
480   size_t len = memory_region_length(REGION_CPU1);
478481
479   for (offs = 0; offs < memory_region_length(REGION_CPU1); offs++)
482   for (offs = 0; offs < len; offs++)
480483   {
481      memory_region(REGION_CPU1)[offs] = BITSWAP8(memory_region(REGION_CPU1)[offs],0,1,2,3,4,5,6,7);
484      rom[offs] = BITSWAP8(rom[offs],0,1,2,3,4,5,6,7);
482485   };
483486}
484487
src/mame/drivers/offtwall.c
r2821r2822
312312static INPUT_PORTS_START( offtwall )
313313   PORT_START   /* 260000 */
314314   PORT_BIT(  0x0001, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
315   PORT_BIT(  0x0002, IP_ACTIVE_LOW, IPT_START2 )
316315   PORT_BIT(  0x0002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
317316   PORT_BIT(  0x0004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
318317   PORT_BIT(  0x0008, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
r2821r2822
321320   PORT_BIT(  0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
322321   PORT_BIT(  0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
323322   PORT_BIT(  0x0100, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
324   PORT_BIT(  0x0200, IP_ACTIVE_LOW, IPT_START1 )
325323   PORT_BIT(  0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
326324   PORT_BIT(  0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
327325   PORT_BIT(  0x0800, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
r2821r2822
333331   PORT_START   /* 260002 */
334332   PORT_BIT(  0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
335333   PORT_BIT(  0x0100, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(3)
336   PORT_BIT(  0x0200, IP_ACTIVE_LOW, IPT_START3 )
337334   PORT_BIT(  0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3)
338335   PORT_BIT(  0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3)
339336   PORT_BIT(  0x0800, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3)
src/mame/drivers/equites.c
r2821r2822
373373#include "equites.h"
374374
375375#define HVOLTAGE_DEBUG   0
376#define EASY_TEST_MODE   1
376#define EASY_TEST_MODE   
377377
378378#define FRQ_ADJUSTER_TAG   "FRQ"
379379
src/mame/drivers/omegrace.c
r2821r2822
568568
569569static DRIVER_INIT( omegrace )
570570{
571   int i;
571   int i, len = memory_region_length(REGION_USER1);
572572   UINT8 *prom = memory_region(REGION_USER1);
573573
574574   /* Omega Race has two pairs of the state PROM output
r2821r2822
576576     * Since all other avg/dvg games connect the PROM
577577     * in a consistent way to the decoder, we swap the bits
578578     * here. */
579   for (i=0; i<memory_region_length(REGION_USER1); i++)
579   for (i=0; i<len; i++)
580580      prom[i] = BITSWAP8(prom[i],7,6,5,4,1,0,3,2);
581581}
582582
src/mame/drivers/segas24.c
r2821r2822
12571257
12581258static MACHINE_START( system24 )
12591259{
1260   if (memory_region(REGION_USER1))
1260   UINT8 *usr1 = memory_region(REGION_USER1);
1261   if (usr1)
12611262   {
1262      memory_configure_bank(1, 0, 16, memory_region(REGION_USER1), 0x40000);
1263      memory_configure_bank(2, 0, 16, memory_region(REGION_USER1), 0x40000);
1263      memory_configure_bank(1, 0, 16, usr1, 0x40000);
1264      memory_configure_bank(2, 0, 16, usr1, 0x40000);
12641265   }
12651266}
12661267
src/mame/drivers/segas16a.c
r2821r2822
146146#include "driver.h"
147147#include "system16.h"
148148#include "machine/8255ppi.h"
149#include "machine/fd1089.h"
149150#include "cpu/i8039/i8039.h"
150151#include "sound/dac.h"
151152#include "sound/2151intf.h"
r2821r2822
30683069
30693070static DRIVER_INIT( afighter )
30703071{
3071   void fd1089_decrypt_0018(void);
30723072   system16a_generic_init(machine);
30733073   fd1089_decrypt_0018();
30743074}
r2821r2822
30763076
30773077static DRIVER_INIT( alexkid1 )
30783078{
3079   void fd1089_decrypt_alexkidd(void);
30803079   system16a_generic_init(machine);
30813080   fd1089_decrypt_alexkidd();
30823081}
r2821r2822
30843083
30853084static DRIVER_INIT( aliensy1 )
30863085{
3087   void fd1089_decrypt_0033(void);
30883086   system16a_generic_init(machine);
30893087   fd1089_decrypt_0033();
30903088}
30913089
30923090static DRIVER_INIT( aliensy5 )
30933091{
3094   void fd1089_decrypt_0037(void);
30953092   system16a_generic_init(machine);
30963093   fd1089_decrypt_0037();
30973094}
r2821r2822
31243121
31253122static DRIVER_INIT( sdi )
31263123{
3127   void fd1089_decrypt_0027(void);
31283124   system16a_generic_init(machine);
31293125   fd1089_decrypt_0027();
31303126   custom_io_r = sdi_custom_io_r;
r2821r2822
31333129
31343130static DRIVER_INIT( sjryukoa )
31353131{
3136   void fd1089_decrypt_5021(void);
31373132   system16a_generic_init(machine);
31383133   fd1089_decrypt_5021();
31393134   custom_io_r = sjryuko_custom_io_r;
r2821r2822
31433138
31443139static DRIVER_INIT( timesca1 )
31453140{
3146   void fd1089_decrypt_0024(void);
31473141   system16a_generic_init(machine);
31483142   fd1089_decrypt_0024();
31493143}
src/mame/drivers/neogeo.c
r2821r2822
328328
329329static CUSTOM_INPUT( multiplexed_controller_r )
330330{
331   char tag[6];
331   char tag[40];
332332
333333   sprintf(tag, "IN%s-%d", (const char *)param, controller_select & 0x01);
334334
r2821r2822
647647static WRITE16_HANDLER( main_cpu_bank_select_w )
648648{
649649   UINT32 bank_address;
650
651   if ((memory_region_length(NEOGEO_REGION_MAIN_CPU_CARTRIDGE) <= 0x100000) && (data & 0x07))
650   UINT32 len = memory_region_length(NEOGEO_REGION_MAIN_CPU_CARTRIDGE);
651   if ((len <= 0x100000) && (data & 0x07))
652652      logerror("PC %06x: warning: bankswitch to %02x but no banks available\n", activecpu_get_pc(), data);
653653   else
654654   {
655655      bank_address = ((data & 0x07) + 1) * 0x100000;
656656
657      if (bank_address >= memory_region_length(NEOGEO_REGION_MAIN_CPU_CARTRIDGE))
657      if (bank_address >= len)
658658      {
659659         logerror("PC %06x: warning: bankswitch to empty bank %02x\n", activecpu_get_pc(), data);
660660         bank_address = 0x100000;
src/mame/drivers/snookr10.c
r2821r2822
108108    You have 1 attempt for each 100 earned points. If you lose the game, you lose the points.
109109
110110
111    NOTE: Bit 7 of input port 0x3004 is tied to bit 7 of input port 0x3003 (DIP switch 1).
112          This allow to use the PAYOUT button to trigger the Supper Game instead of STOP 5.
111113
112    ***** Issues / Protection *****
113114
115***************************************************************************************
116
117
118    Issues / Protection
119    -------------------
120
114121    * Apple 10
115122
116123    - Tile matrix and color palette are totally encrypted/scrambled.
r2821r2822
275282    $3001 - $3001   Input Port 1   ;R
276283    $3002 - $3002   Input Port 2   ;R
277284    $3003 - $3003   Input Port 3   ;R  , DIP switches.
278    $3004 - $3004   (unknown)      ;R  , the code is constantly polling bit 7.
285    $3004 - $3004   Input Port 4   ;R  , bit 7 in parallel with DIP switch 1.
279286    $5000 - $5000   Output Port A  ;W  , lamps.
280287    $5001 - $5001   Output Port B  ;W  , lamps.
281288    $6000 - $6FFF   Video RAM
r2821r2822
289296    *** Driver Updates ***
290297
291298
299    [2008/06/01]
300    - Switched the color system to RESNET calculations.
301    - Hooked the infamous bit7 of Input Port 0x3004 in parallel to DIP switch 1.
302      This allow to use the PAYOUT button to trigger the Super Game instead of STOP 5.
303    - Demultiplexed lamps matrix.
304    - Added lamps support, but is still imperfect.
305    - Updated technical notes.
306
292307    [2008/05/22]
293308    - Confirmed the CPU clock after some PCB measurements.
294309    - Changed the SND clock to 1MHz to match the PCB measurement.
r2821r2822
326341
327342    *** TO DO ***
328343
329    - Figure out the unknown reads to offset $3004, bit 7.
330    - Hook lamps.
331    - Turn the color system to resnet calculation.
344    - Fix lamps.
332345
333346
334347***********************************************************************************/
r2821r2822
338351
339352#include "driver.h"
340353#include "sound/okim6295.h"
354#include "snookr10.lh"
341355
342356
343357/* from video */
r2821r2822
352366
353367/**********************
354368* Read/Write Handlers *
369*   - Input Ports -   *
370**********************/
371
372static READ8_HANDLER( dsw_port_1_r )
373/*-----------------------------------
374    PORT 0x3004 ;INPUT PORT 4
375-------------------------------------
376    BIT 0 =
377    BIT 1 =
378    BIT 2 =
379    BIT 3 =
380    BIT 4 =
381    BIT 5 =
382    BIT 6 =
383    BIT 7 = Complement of DS1, bit 7
384------------------------------------*/
385{
386return input_port_read_indexed(machine,3);
387}
388
389/**********************
390* Read/Write Handlers *
355391*  - Output Ports -   *
356***********************
392**********************/
357393
394/*  Lamps are multiplexed using a 5 bit matrix.
395    The first 4 bits are from Port A, and the
396    remaining one is from Port B.
397
358398    LAMPS components:
359399
360400    START  = bit1 & bit3
361401    CANCEL = bit0 & bit3
362    STOP1  = bit1
402    STOP1  = bit1 only
363403    STOP2  = bit1 & bit2
364    STOP3  = bit1
404    STOP3  = bit1 only
365405    STOP4  = bit1 & bit4
366406    STOP5  = bit0 & bit4
367407*/
r2821r2822
371411    PORT 0x5000 ;OUTPUT PORT A
372412-------------------------------
373413    BIT 0 =
374    BIT 1 = Lamps, bit0
414    BIT 1 = Lamps matrix, bit0
375415    BIT 2 =
376    BIT 3 = Lamps, bit1
416    BIT 3 = Lamps matrix, bit1
377417    BIT 4 =
378    BIT 5 = Lamps, bit2
418    BIT 5 = Lamps matrix, bit2
379419    BIT 6 =
380    BIT 7 = Lamps, bit3
420    BIT 7 = Lamps matrix, bit3
381421------------------------------*/
382422{
383//  (data >> 1) & 1;    /* lamps, bit0 */
384//  (data >> 3) & 1;    /* lamps, bit1 */
385//  (data >> 5) & 1;    /* lamps, bit2 */
386//  (data >> 7) & 1;    /* lamps, bit3 */
423   int bit0, bit1, bit2, bit3, bit4;
424
425   bit0 = (data >> 1) & 1;
426   bit1 = (data >> 3) & 1;
427   bit2 = (data >> 5) & 1;
428   bit3 = (data >> 7) & 1;
429   bit4 = (input_port_read_indexed(machine,5) & 1);
430
431   output_set_lamp_value(1, (bit1 & bit3));   /* Lamp 1 - START  */
432   output_set_lamp_value(2, (bit0 & bit3));   /* Lamp 2 - CANCEL */
433   output_set_lamp_value(3, (bit1 | bit3));   /* Lamp 3 - STOP1  */
434   output_set_lamp_value(4, (bit1 & bit2));   /* Lamp 4 - STOP2  */
435   output_set_lamp_value(5, (bit1 | bit3));   /* Lamp 5 - STOP3  */
387436}
388437
389438static WRITE8_HANDLER( output_port_1_w )
390439/*-----------------------------
391440    PORT 0x5001 ;OUTPUT PORT B
392441-------------------------------
393    BIT 0 = Lamps, bit4
442    BIT 0 = Lamps matrix, bit4
394443    BIT 1 =
395444    BIT 2 =
396445    BIT 3 =
r2821r2822
400449    BIT 7 =
401450------------------------------*/
402451{
403//  (data & 1);         /* lamps, bit4 */
452   int bit0, bit1, bit4;
453
454   bit0 = (input_port_read_indexed(machine,4) >> 1) & 1;
455   bit1 = (input_port_read_indexed(machine,4) >> 3) & 1;
456   bit4 = (data & 1);
457
458   output_set_lamp_value(6, (bit1 & bit4));   /* Lamp 6 - STOP4  */
459   output_set_lamp_value(7, (bit0 & bit4));   /* Lamp 7 - STOP5  */
404460}
405461
406462
r2821r2822
415471   AM_RANGE(0x3001, 0x3001) AM_READ(input_port_1_r)   /* IN1 */
416472   AM_RANGE(0x3002, 0x3002) AM_READ(input_port_2_r)   /* IN2 */
417473   AM_RANGE(0x3003, 0x3003) AM_READ(input_port_3_r)   /* DS1 */
418   AM_RANGE(0x3004, 0x3004) AM_READNOP /* unknown reads comparing bit 7 */
474   AM_RANGE(0x3004, 0x3004) AM_READ(dsw_port_1_r)      /* complement of DS1, bit 7 */
419475   AM_RANGE(0x5000, 0x5000) AM_WRITE(output_port_0_w)   /* OUT0 */
420476   AM_RANGE(0x5001, 0x5001) AM_WRITE(output_port_1_w)   /* OUT1 */
421477   AM_RANGE(0x6000, 0x6fff) AM_RAM_WRITE(snookr10_videoram_w) AM_BASE(&videoram)
r2821r2822
442498*      Input ports       *
443499*************************/
444500
445/*  Do the stops & cancel buttons need PORT_IMPULSE
446    to just trigger only 1 sound each time they are pressed? */
501/*  Eliminated all PORT_IMPULSE limitations.
502    All Hold & Cancel buttons have a rattle sound in the real PCB. */
447503
448504static INPUT_PORTS_START( snookr10 )
449505   PORT_START_TAG("IN0")
r2821r2822
495551   PORT_DIPSETTING(    0x20, "Manual - Coins" )
496552   PORT_DIPSETTING(    0x40, "Manual - Tickets" )
497553   PORT_DIPSETTING(    0x60, "Automatic" )
498   PORT_DIPNAME( 0x80, 0x80, "Super Game" )            PORT_DIPLOCATION("SW1:1")
499   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
500   PORT_DIPSETTING(    0x80, DEF_STR( On ) )
554   PORT_DIPNAME( 0x80, 0x80, "Super Game Button" )         PORT_DIPLOCATION("SW1:1")
555   PORT_DIPSETTING(    0x00, "PAYOUT button" )
556   PORT_DIPSETTING(    0x80, "STOP 5 button" )
501557INPUT_PORTS_END
502558
503559static INPUT_PORTS_START( apple10 )
560
561/*  Eliminated all PORT_IMPULSE limitations.
562    All Hold & Cancel buttons have a rattle sound in the real PCB. */
563
504564   PORT_START_TAG("IN0")
505565   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE )   PORT_NAME("Remote x100") PORT_CODE(KEYCODE_Q)
506566   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 )   PORT_NAME("Stop 1") PORT_CODE(KEYCODE_Z)   /* Input Test in stats mode */
r2821r2822
550610   PORT_DIPSETTING(    0x20, "Manual - Coins 2" )
551611   PORT_DIPSETTING(    0x40, "Disable Payment/Game" )
552612   PORT_DIPSETTING(    0x60, "Automatic" )
553   PORT_DIPNAME( 0x80, 0x80, "Super Game" )            PORT_DIPLOCATION("SW1:1")
554   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
555   PORT_DIPSETTING(    0x80, DEF_STR( On ) )
613   PORT_DIPNAME( 0x80, 0x80, "Super Game Button" )         PORT_DIPLOCATION("SW1:1")
614   PORT_DIPSETTING(    0x00, "PAYOUT button" )
615   PORT_DIPSETTING(    0x80, "STOP 5 button" )
556616INPUT_PORTS_END
557617
558618static INPUT_PORTS_START( tenballs )
619
620/*  Eliminated all PORT_IMPULSE limitations.
621    All Hold & Cancel buttons have a rattle sound in the real PCB. */
622
559623   PORT_START_TAG("IN0")
560624   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE )   PORT_NAME("Remote x100") PORT_CODE(KEYCODE_Q)
561625   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 )   PORT_NAME("Stop 1") PORT_CODE(KEYCODE_Z)   /* no Input Test in stats mode */
r2821r2822
669733
670734   MDRV_GFXDECODE(snookr10)
671735
672   MDRV_PALETTE_LENGTH(0x100)
736   MDRV_PALETTE_LENGTH(256)
673737   MDRV_PALETTE_INIT(snookr10)
674738   MDRV_VIDEO_START(snookr10)
675739   MDRV_VIDEO_UPDATE(snookr10)
r2821r2822
677741   /* sound hardware */
678742   MDRV_SPEAKER_STANDARD_MONO("mono")
679743   MDRV_SOUND_ADD(OKIM6295, MASTER_CLOCK/16)   /* 1 MHz (995.5 kHz measured) */
680   MDRV_SOUND_CONFIG(okim6295_interface_region_1_pin7high)   /* pin7 checked on PCB */
744   MDRV_SOUND_CONFIG(okim6295_interface_region_1_pin7high)   /* pin7 checked HIGH on PCB */
681745   MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.8)
682746
683747MACHINE_DRIVER_END
r2821r2822
760824*      Game Drivers      *
761825*************************/
762826
763/*    YEAR  NAME      PARENT    MACHINE   INPUT     INIT ROT    COMPANY    FULLNAME                FLAGS  */
764GAME( 1998, snookr10, 0,        snookr10, snookr10, 0,   ROT0, "Sandii'", "Snooker 10 (Ver 1.11)", 0 )
765GAME( 1998, apple10,  0,        apple10,  apple10,  0,   ROT0, "Sandii'", "Apple 10 (Ver 1.21)",   0 )
766GAME( 1997, tenballs, snookr10, tenballs, tenballs, 0,   ROT0, "unknown", "Ten Balls (Ver 1.05)",  0 )
827/*     YEAR  NAME      PARENT    MACHINE   INPUT     INIT ROT    COMPANY    FULLNAME                FLAGS  LAYOUT */
828GAMEL( 1998, snookr10, 0,        snookr10, snookr10, 0,   ROT0, "Sandii'", "Snooker 10 (Ver 1.11)", 0,     layout_snookr10 )
829GAMEL( 1998, apple10,  0,        apple10,  apple10,  0,   ROT0, "Sandii'", "Apple 10 (Ver 1.21)",   0,     layout_snookr10 )
830GAMEL( 1997, tenballs, snookr10, tenballs, tenballs, 0,   ROT0, "unknown", "Ten Balls (Ver 1.05)",  0,     layout_snookr10 )
src/mame/drivers/segahang.c
r2821r2822
1717#include "deprecat.h"
1818#include "system16.h"
1919#include "machine/segaic16.h"
20#include "machine/fd1089.h"
2021#include "machine/8255ppi.h"
2122#include "cpu/m68000/m68000.h"
2223#include "sound/2203intf.h"
r2821r2822
12891290   ROM_LOAD( "epr-7181.ic2", 0x0000, 0x8000, CRC(b4740419) SHA1(8ece2dc85692e32d0ba0b427c260c3d10ac0b7cc) )
12901291
12911292   ROM_REGION( 0x10000, REGION_CPU3, 0 ) /* sound CPU */
1292   ROM_LOAD( "epr-72xx.ic73", 0x00000, 0x004000, CRC(d6397933) SHA1(b85bb47efb6c113b3676b10ab86f1798a89d45b4) ) /* epr-7233? & epr-2734? (not verified) */
1293   ROM_LOAD( "epr-72xx.ic72", 0x04000, 0x004000, CRC(504e76d9) SHA1(302af9101da01c97ca4be6acd21fb5b8e8f0b7ef) )
1293   ROM_LOAD( "epr-7234.ic73", 0x00000, 0x004000, CRC(d6397933) SHA1(b85bb47efb6c113b3676b10ab86f1798a89d45b4) )
1294   ROM_LOAD( "epr-7233.ic72", 0x04000, 0x004000, CRC(504e76d9) SHA1(302af9101da01c97ca4be6acd21fb5b8e8f0b7ef) )
12941295
12951296   ROM_REGION( 0x10000, REGION_SOUND1, 0 ) /* Sega PCM sound data */
12961297   ROM_LOAD( "epr-7231.ic5", 0x00000, 0x8000, CRC(871c6b14) SHA1(6d04ddc32fdf1db409cb519890821bd10fc9e58b) )
r2821r2822
13691370   ROM_LOAD( "epr-7181.ic2", 0x0000, 0x8000, CRC(b4740419) SHA1(8ece2dc85692e32d0ba0b427c260c3d10ac0b7cc) )
13701371
13711372   ROM_REGION( 0x10000, REGION_CPU3, 0 ) /* sound CPU */
1372   ROM_LOAD( "epr-72xx.ic73", 0x00000, 0x004000, CRC(d6397933) SHA1(b85bb47efb6c113b3676b10ab86f1798a89d45b4) ) /* epr-7233? & epr-2734? (not verified) */
1373   ROM_LOAD( "epr-72xx.ic72", 0x04000, 0x004000, CRC(504e76d9) SHA1(302af9101da01c97ca4be6acd21fb5b8e8f0b7ef) )
1373   ROM_LOAD( "epr-7234.ic73", 0x00000, 0x004000, CRC(d6397933) SHA1(b85bb47efb6c113b3676b10ab86f1798a89d45b4) )
1374   ROM_LOAD( "epr-7233.ic72", 0x04000, 0x004000, CRC(504e76d9) SHA1(302af9101da01c97ca4be6acd21fb5b8e8f0b7ef) )
13741375
13751376   ROM_REGION( 0x10000, REGION_SOUND1, 0 ) /* Sega PCM sound data */
13761377   ROM_LOAD( "epr-7231.ic5", 0x00000, 0x8000, CRC(871c6b14) SHA1(6d04ddc32fdf1db409cb519890821bd10fc9e58b) )
r2821r2822
17101711
17111712static DRIVER_INIT( enduror )
17121713{
1713   void fd1089_decrypt_0013A(void);
17141714   hangon_generic_init();
17151715   fd1089_decrypt_0013A();
17161716}
src/mame/drivers/thunderj.c
r2821r2822
257257
258258   PORT_START      /* 260010 */
259259   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
260   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
261260   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
262261   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
263262   PORT_BIT( 0x0c00, IP_ACTIVE_LOW, IPT_UNUSED )
r2821r2822
273272   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )   /* Output buffer full (@360030) */
274273   PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_UNUSED )
275274   PORT_BIT( 0x00e0, IP_ACTIVE_LOW, IPT_UNUSED )
276   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START2 )
277275   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
278276   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
279277   PORT_BIT( 0x0c00, IP_ACTIVE_LOW, IPT_UNUSED )
src/mame/drivers/taito_f2.c
r2821r2822
58885888
58895889static DRIVER_INIT( mjnquest )
58905890{
5891   int i;
5891   int i, len = memory_region_length(REGION_GFX2);
58925892   UINT8 *gfx = memory_region(REGION_GFX2);
58935893
58945894   /* the bytes in each longword are in reversed order, put them in the
58955895       order used by the other games. */
5896   for (i = 0;i < memory_region_length(REGION_GFX2);i += 2)
5896   for (i = 0;i < len;i += 2)
58975897   {
58985898      int t;
58995899
src/mame/drivers/ddragon.c
r2821r2822
801801   PORT_DIPSETTING(    0x01, "2" )
802802   PORT_DIPSETTING(    0x02, "3" )
803803   PORT_DIPSETTING(    0x03, "4" )
804   PORT_DIPUNUSED( 0x04, IP_ACTIVE_LOW )
804805   PORT_DIPUNUSED( 0x08, IP_ACTIVE_LOW )
805   PORT_DIPUNUSED( 0x10, IP_ACTIVE_LOW )
806806   PORT_DIPNAME( 0xf0, 0x90, DEF_STR( Difficulty ) )
807807   PORT_DIPSETTING(    0xf0, DEF_STR( Easy ) )
808808   PORT_DIPSETTING(    0x90, DEF_STR( Medium ) )
r2821r2822
14451445 in terms of code the game code has been heavily modified, banking writes appear to have been removed, and
14461446 the graphic roms are all scrambled.  The game also runs on 3x M6809 rather than the original CPUs.
14471447
1448 I'm not 100% convinced the program roms are good dumps, apprently ROM3 fails on the original board (could just
1449 be due to the rom hacking, as the game runs fine) but there is a jump to the 0x2000 region in the code, although
1450 this could be additional protection / rom scrambling.  Also the sound roms seem too small.  If you have this
1451 PCB please verify.
1452
14531448 */
14541449ROM_START( ddgn6809 )
14551450   ROM_REGION( 0x30000, REGION_CPU1, 0 )   /* 64k for code + bankswitched memory */
r2821r2822
14921487   ROM_LOAD( "11.bin",        0x20000, 0x10000, CRC(4171b70d) SHA1(dc300c9bca6481417e97ad03c973e47389f261c1) )
14931488   ROM_LOAD( "12.bin",        0x30000, 0x10000, CRC(5f6a6d6f) SHA1(7d546a226cda81c28e7ccfb4c5daebc65072198d) )
14941489
1495   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* adpcm samples -- roms too small? (please check) */
1496   ROM_LOAD( "14.bin",        0x00000, 0x08000, BAD_DUMP CRC(678f8657) SHA1(2652fdc6719d2c889ca87802f6e2cefae59fc2eb) )
1497   ROM_LOAD( "15.bin",        0x10000, 0x08000, BAD_DUMP CRC(10f21dea) SHA1(739cf649f91490384297a81a2cc9855acb58a1c0) )
1490   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* adpcm samples  */
1491   ROM_LOAD( "14.bin",        0x00000, 0x08000, CRC(678f8657) SHA1(2652fdc6719d2c889ca87802f6e2cefae59fc2eb) )
1492   ROM_LOAD( "15.bin",        0x10000, 0x08000, CRC(10f21dea) SHA1(739cf649f91490384297a81a2cc9855acb58a1c0) )
14981493ROM_END
14991494
1495/*
1496CPU
15001497
14983x EF68B09EP (main)
14992x YM2203C (sound)
15002x OKI M5202 (sound)
15012x Y3014B (sound)
15022x LM324N (sound)
15031x TDA2003 (sound)
15041x oscillator 20.000
15051x oscillator 24.575 (24.000 on another PCB)
15061x orange resonator CSB445E (CSB500E on another PCB)
1507
1508ROMs
1509
151012x 27C512 (1-12)
15119x 27256 (13-21)
15122x AM27S21PC
15131x N82S123N
15141x AM27S29PC
15151x PAL16r4
15161x PAL16R6
1517
1518Note
1519
15201x JAMMA edge connector
15211x trimmer (volume)
15222x 8x2 switches dip
1523
1524*/
1525
1526ROM_START( dd6809a )
1527   ROM_REGION( 0x30000, REGION_CPU1, 0 )   /* 64k for code + bankswitched memory */
1528   ROM_LOAD( "20.7f",   0x08000, 0x08000, CRC(c804819f) SHA1(cc570a90b7bef1c6263f5e1fd96ed377c508fe2b) )
1529   ROM_LOAD( "19.7g",   0x10000, 0x08000, CRC(de08db4d) SHA1(e63b90c3bb3af01d2855de9a996b51068bed7b52) ) /* banked at 0x4000-0x8000 */
1530   ROM_LOAD( "18.7h",   0x18000, 0x08000, CRC(154d50c4) SHA1(4ffdd29406b6c6b552344f820f83715b1c7727d1) ) /* banked at 0x4000-0x8000 */
1531   ROM_LOAD( "17.7j",   0x20000, 0x08000, CRC(4052f37a) SHA1(9444a30ce32a2d35c601324d79c0ba602be4f288) ) /* banked at 0x4000-0x8000 */
1532
1533   ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* sprite cpu */
1534   ROM_LOAD( "21.7d",   0x08000, 0x8000, CRC(4437fc51) SHA1(fffcf2bec50d0b79861904b4abc607206b7794e6) )
1535
1536   ROM_REGION( 0x10000, REGION_CPU3, 0 ) /* audio cpu */
1537   ROM_LOAD( "16.7n",   0x08000, 0x08000, CRC(f4c72690) SHA1(c70d032355acf3f7f6586b6e57a94f80e099bf1a) )
1538
1539   /* all the gfx roms are scrambled on this set */
1540   ROM_REGION( 0x08000, REGION_GFX1, ROMREGION_DISPOSE )
1541   ROM_LOAD( "13.5f",   0x00000, 0x08000, CRC(b5a54537) SHA1(a6157cde4f9738565008d11a4a6d8576ae3abfef) )   /* chars */
1542
1543   ROM_REGION( 0x80000, REGION_GFX2, ROMREGION_DISPOSE )
1544   ROM_LOAD( "1.1t",         0x00000, 0x10000, CRC(5e810a6d) SHA1(5eba3e982b271bc284ca333429cd0b3759c9c8d1) )
1545   ROM_LOAD( "1.1r",         0x10000, 0x10000, CRC(7300b785) SHA1(6d3b72bd7208e2bd790517a753c9d5192c88d20f) )
1546   ROM_LOAD( "3.1q",         0x20000, 0x10000, CRC(19405de8) SHA1(ac1aa40478b92af5ccdde89812be78b7c9f7d20d) )
1547   ROM_LOAD( "4.1p",         0x30000, 0x10000, CRC(4b10defd) SHA1(fb43eba7c8a7f77f0fdd6253d51b40b0e64598f5) )
1548   ROM_LOAD( "5.1n",         0x40000, 0x10000, CRC(5b1bb493) SHA1(dd947d7d381af5952acece4b2cefc9fc4847ec68) )
1549   ROM_LOAD( "6.1m",         0x50000, 0x10000, CRC(e8a2d2e7) SHA1(abc871e57a5280728b9f90625fb91011b848a4d8) )
1550   ROM_LOAD( "7.1l",         0x60000, 0x10000, CRC(8010fcca) SHA1(9401c41088776beea91c32aaff8eb2fbe92b5e37) )
1551   ROM_LOAD( "8.1j",         0x70000, 0x10000, CRC(bfa4da27) SHA1(68a649aec43e18dc79b4690c1dff2e2a6fc0065a) )
1552
1553   ROM_REGION( 0x40000, REGION_GFX3, ROMREGION_DISPOSE )
1554   ROM_LOAD( "9.2e",         0x00000, 0x10000, CRC(736eff0f) SHA1(ae2ec2d5c8ab1db579a08256d874426dc5d889c6) )
1555   ROM_LOAD( "10.2d",        0x10000, 0x10000, CRC(a670d088) SHA1(27e7b49645753dd039f104c3e0a7e6513a98710d) )
1556   ROM_LOAD( "11.2b",        0x20000, 0x10000, CRC(4171b70d) SHA1(dc300c9bca6481417e97ad03c973e47389f261c1) )
1557   ROM_LOAD( "12.2a",        0x30000, 0x10000, CRC(5f6a6d6f) SHA1(7d546a226cda81c28e7ccfb4c5daebc65072198d) )
1558
1559   ROM_REGION( 0x20000, REGION_SOUND1, 0 ) /* adpcm samples (yes these really are smaller than the original game..)  */
1560   ROM_LOAD( "14.7q",        0x00000, 0x08000, CRC(678f8657) SHA1(2652fdc6719d2c889ca87802f6e2cefae59fc2eb) )
1561   ROM_LOAD( "15.7o",        0x10000, 0x08000, CRC(10f21dea) SHA1(739cf649f91490384297a81a2cc9855acb58a1c0) )
1562
1563   ROM_REGION( 0x20000, REGION_USER1, 0 ) /* PROMs */
1564   ROM_LOAD( "27s21.5o",        0x00000, 0x100, CRC(673f68c3) SHA1(9381453e8f868d80b6069264509a339e20e2b6b1) )
1565   ROM_LOAD( "27s21.5p",        0x00000, 0x100, CRC(2dc270f2) SHA1(9f124ab2c98680bcc249218ee0de09ba49c09a84) )
1566   ROM_LOAD( "27s29.6g",        0x00000, 0x200, CRC(095fb461) SHA1(7fd213fd8b8bbe30334523ccf06d4606c67b472e) )
1567   ROM_LOAD( "82s129.4h",       0x00000, 0x100, CRC(7683cadd) SHA1(ff6fecf273c1d8812814cacc72fb71642ec32b6d) )
1568
1569   ROM_REGION( 0x20000, REGION_USER2, 0 ) /* PALs */
1570   ROM_LOAD( "pal16r4.8g",        0x00000, 0x104, CRC(5b0263fd) SHA1(ddca425f82f5eb06b56f2ab116fb9a9b192e1097) )
1571   ROM_LOAD( "pal16r6.2f",        0x00000, 0x104, CRC(bd76fb53) SHA1(2d0634e8edb3289a103719466465e9777606086e) )
1572ROM_END
1573
1574
15011575ROM_START( ddragon2 )
15021576   ROM_REGION( 0x30000, REGION_CPU1, 0 )
15031577   ROM_LOAD( "26a9-04.bin",  0x08000, 0x8000, CRC(f2cfc649) SHA1(d3f1e0bae02472914a940222e4f600170a91736d) )
r2821r2822
18811955GAME( 1987, ddragoua, ddragon,  ddragon,  ddragon,  ddragon,  ROT0, "[Technos] (Taito America license)", "Double Dragon (US Set 2)", GAME_SUPPORTS_SAVE )
18821956GAME( 1987, ddragonb, ddragon,  ddragonb, ddragon,  ddragon,  ROT0, "bootleg", "Double Dragon (bootleg with HD6309)", GAME_SUPPORTS_SAVE ) // according to dump notes
18831957GAME( 1987, ddragnba, ddragon,  ddragnba, ddragon,  ddragon,  ROT0, "bootleg", "Double Dragon (bootleg with M6803)", GAME_SUPPORTS_SAVE )
1884GAME( 1987, ddgn6809, ddragon,  ddgn6809, ddragon,  ddgn6809,  ROT0, "bootleg", "Double Dragon (bootleg with 3xM6809)", GAME_NOT_WORKING )
1958GAME( 1987, ddgn6809, ddragon,  ddgn6809, ddragon,  ddgn6809, ROT0, "bootleg", "Double Dragon (bootleg with 3xM6809, set 1)", GAME_NOT_WORKING )
1959GAME( 1987, dd6809a,  ddragon,  ddgn6809, ddragon,  ddgn6809, ROT0, "bootleg", "Double Dragon (bootleg with 3xM6809, set 2)", GAME_NOT_WORKING )
18851960
1961
1962
18861963GAME( 1988, ddragon2, 0,        ddragon2, ddragon2, ddragon2, ROT0, "Technos", "Double Dragon II - The Revenge (World)", GAME_SUPPORTS_SAVE )
18871964GAME( 1988, ddragn2u, ddragon2, ddragon2, ddragon2, ddragon2, ROT0, "Technos", "Double Dragon II - The Revenge (US)", GAME_SUPPORTS_SAVE )
18881965
src/mame/drivers/acommand.c
r2821r2822
281281                ---- ---- ---- --x- (Activate Test)
282282                ---- ---- ---- ---x (Advance Thru Tests)
283283            */
284         return input_port_read_indexed(machine,0);
284         return input_port_read(machine, "IN0");
285285      case 0x0014/2:
286286         /*
287287                write 0x40,read (~0x08)
r2821r2822
315315                xxxx xxxx ---- ---- DIPSW4
316316                ---- ---- xxxx xxxx DIPSW3
317317            */
318         return input_port_read_indexed(machine,1);
318         return input_port_read(machine, "IN1");
319319   }
320320   return ac_devram[offset];
321321}
r2821r2822
375375ADDRESS_MAP_END
376376
377377static INPUT_PORTS_START( acommand )
378   PORT_START
378   PORT_START_TAG("IN0")
379379   PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) )
380380   PORT_DIPSETTING(      0x0001, DEF_STR( Off ) )
381381   PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
r2821r2822
425425   PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
426426   PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
427427
428   PORT_START
428   PORT_START_TAG("IN1")
429429   PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) )
430430   PORT_DIPSETTING(      0x0001, DEF_STR( Off ) )
431431   PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
src/mame/drivers/asterix.c
r2821r2822
6767   /* bit 8  is EEPROM data */
6868   /* bit 9  is EEPROM ready */
6969   /* bit 10 is service button */
70   res = (eeprom_read_bit()<<8) | input_port_read_indexed(machine,1);
70   res = (eeprom_read_bit()<<8) | input_port_read(machine, "IN1");
7171
7272   if (init_eeprom_count)
7373   {
src/mame/drivers/gladiatr.c
r2821r2822
468468
469469
470470
471static INPUT_PORTS_START( ppking )
472
473INPUT_PORTS_END
474
475
476471static INPUT_PORTS_START( gladiatr )
477472   PORT_START_TAG("DSW1")      /* (8741-0 parallel port)*/
478473   PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) )
r2821r2822
553548   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
554549   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
555550   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
556   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
557551   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* COINS */
558552
559553   PORT_START_TAG("COINS")   /*(8741-3 parallel port bit7) */
r2821r2822
10541048
10551049
10561050
1057GAME( 1985, ppking,   0,        ppking,   ppking,   ppking,   ROT90, "Taito America Corporation", "Ping-Pong King", GAME_NOT_WORKING)
1051GAME( 1985, ppking,   0,        ppking,   0,        ppking,   ROT90, "Taito America Corporation", "Ping-Pong King", GAME_NOT_WORKING)
10581052GAME( 1986, gladiatr, 0,        gladiatr, gladiatr, gladiatr, ROT0,  "Taito America Corporation", "Gladiator (US)", 0 )
10591053GAME( 1986, ogonsiro, gladiatr, gladiatr, gladiatr, gladiatr, ROT0,  "Taito Corporation", "Ohgon no Siro (Japan)", 0 )
10601054GAME( 1986, greatgur, gladiatr, gladiatr, gladiatr, gladiatr, ROT0,  "Taito Corporation", "Great Gurianos (Japan?)", 0 )
src/mame/drivers/imolagp.c
r2821r2822
487487   PORT_DIPSETTING(    0x80, DEF_STR( On ) )
488488
489489   PORT_START /* 2800 */ /* speed: 08 00 0F 1C 0F 00 1E 3D */
490   PORT_DIPNAME( 0x03, 0x03, "Pedal" )
491   PORT_DIPSETTING( 0x01, "STOPPED" )
492   PORT_DIPSETTING( 0x00, "SLOW" )
493   PORT_DIPSETTING( 0x02, "MEDIUM" )
494   PORT_DIPSETTING( 0x03, "FAST" )
490//  PORT_DIPNAME( 0x03, 0x03, "Pedal" )
491//  PORT_DIPSETTING( 0x01, "STOPPED" )
492//  PORT_DIPSETTING( 0x00, "SLOW" )
493//  PORT_DIPSETTING( 0x02, "MEDIUM" )
494//  PORT_DIPSETTING( 0x03, "FAST" )
495495   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )
496496   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )
497   PORT_DIPNAME( 0x04, 0x04, "Stick Shift" )
498   PORT_DIPSETTING( 0x0, DEF_STR(Low) )
499   PORT_DIPSETTING( 0x4, DEF_STR(High) )
497//  PORT_DIPNAME( 0x04, 0x04, "Stick Shift" )
498//  PORT_DIPSETTING( 0x0, DEF_STR(Low) )
499//  PORT_DIPSETTING( 0x4, DEF_STR(High) )
500500   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 )
501501   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 )
502502   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 )
src/mame/drivers/kinstb.c
r2821r2822
240240static DRIVER_INIT(kinstb)
241241{
242242   INT32 i;
243   UINT8 *rom = memory_region(REGION_USER3);
244
243245   for(i=0;i<0x400000;i++)
244246   {
245      memory_region(REGION_USER3)[i]=BITSWAP8(memory_region(REGION_USER3)[i],5,0,6,1,7,4,3,2 );
247      rom[i]=BITSWAP8(rom[i],5,0,6,1,7,4,3,2);
246248   }
247249   DRIVER_INIT_CALL(snes_hirom);
248250}
src/mame/drivers/gyruss.c
r2821r2822
5656***************************************************************************/
5757
5858#include "driver.h"
59#include "machine/konami1.h"
5960#include "cpu/i8039/i8039.h"
6061#include "sound/ay8910.h"
6162#include "sound/discrete.h"
r2821r2822
6566extern UINT8 *gyruss_spriteram;
6667extern UINT8 *gyruss_flipscreen;
6768
68void konami1_decode_cpu2(void);
6969WRITE8_HANDLER( gyruss_spriteram_w );
7070READ8_HANDLER( gyruss_scanline_r );
7171VIDEO_START( gyruss );
r2821r2822
701701
702702static DRIVER_INIT( gyruss )
703703{
704   konami1_decode_cpu2();
704   konami1_decode(1);
705705}
706706
707707
src/mame/drivers/wldarrow.c
r2821r2822
289289   PORT_DIPNAME( 0x08, 0x00, "Bit Switch 4" ) PORT_DIPLOCATION("BITSWITCH:4") PORT_CODE(KEYCODE_4_PAD) PORT_TOGGLE
290290   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
291291   PORT_DIPSETTING(    0x08, DEF_STR( On ) )
292   PORT_DIPNAME( 0x08, 0x00, "Bit Switch 5" ) PORT_DIPLOCATION("BITSWITCH:5") PORT_CODE(KEYCODE_5_PAD) PORT_TOGGLE
292   PORT_DIPNAME( 0x10, 0x00, "Bit Switch 5" ) PORT_DIPLOCATION("BITSWITCH:5") PORT_CODE(KEYCODE_5_PAD) PORT_TOGGLE
293293   PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
294294   PORT_DIPSETTING(    0x10, DEF_STR( On ) )
295295   PORT_DIPNAME( 0x20, 0x00, "Bit Switch 6" ) PORT_DIPLOCATION("BITSWITCH:6") PORT_CODE(KEYCODE_6_PAD) PORT_TOGGLE
r2821r2822
453453static DRIVER_INIT( wldarrow )
454454{
455455   offs_t i;
456   UINT8 *rom = memory_region(REGION_CPU1);
456457
457458   for (i = 0; i < 0x3000; i++)
458      memory_region(REGION_CPU1)[i] ^= 0xff;
459      rom[i] ^= 0xff;
459460}
460461
461462
src/mame/drivers/cidelsa.c
r2821r2822
289289   NULL
290290};
291291
292/* COP400 Interface */
293
294static COP400_INTERFACE( draco_cop_intf )
295{
296   COP400_CKI_DIVISOR_16, // ???
297   COP400_CKO_OSCILLATOR_OUTPUT, // ???
298   COP400_MICROBUS_DISABLED
299};
300
292301/* Memory Maps */
293302
294303// Destroyer
r2821r2822
683692   MDRV_CPU_ADD(COP420, DRACO_SND_CHR1) // COP402N
684693   MDRV_CPU_PROGRAM_MAP(draco_sound_map, 0)
685694   MDRV_CPU_IO_MAP(draco_sound_io_map, 0)
695   MDRV_CPU_CONFIG(draco_cop_intf)
686696
687697   // input/output hardware
688698
src/mame/drivers/srmp5.c
r2821r2822
157157static READ32_HANDLER(data_r)
158158{
159159   UINT32 data;
160   const UINT8 *usr = memory_region(REGION_USER2);
160161   data=((databank>>4)&0xf)*0x100000; //guess
161   data=memory_region(REGION_USER2)[data+offset*2]+memory_region(REGION_USER2)[data+offset*2+1]*256;
162   data=usr[data+offset*2]+usr[data+offset*2+1]*256;
162163   return data|(data<<16);
163164}
164165
src/mame/drivers/segas16b.c
r2821r2822
871871#include "deprecat.h"
872872#include "system16.h"
873873#include "machine/segaic16.h"
874#include "machine/fd1089.h"
874875#include "machine/fd1094.h"
875876#include "machine/mc8123.h"
876877#include "sound/2151intf.h"
r2821r2822
61276128
61286129static DRIVER_INIT( aliensy3_5358 )
61296130{
6130   void fd1089_decrypt_0033(void);
61316131   DRIVER_INIT_CALL(generic_5358);
61326132   fd1089_decrypt_0033();
61336133}
r2821r2822
61636163
61646164static DRIVER_INIT( aurail1_5704 )
61656165{
6166   void fd1089_decrypt_0168(void);
61676166   DRIVER_INIT_CALL(generic_5704);
61686167   fd1089_decrypt_0168();
61696168}
r2821r2822
61716170
61726171static DRIVER_INIT( aurailj_5704 )
61736172{
6174   void fd1089_decrypt_0167(void);
61756173   DRIVER_INIT_CALL(generic_5704);
61766174   fd1089_decrypt_0167();
61776175}
r2821r2822
61866184
61876185static DRIVER_INIT( dunkshot_5358 )
61886186{
6189   void fd1089_decrypt_0022(void);
61906187   DRIVER_INIT_CALL(generic_5358);
61916188   fd1089_decrypt_0022();
61926189   custom_io_r = dunkshot_custom_io_r;
r2821r2822
62326229
62336230static DRIVER_INIT( defense_5358 )
62346231{
6235   void fd1089_decrypt_0028(void);
62366232   DRIVER_INIT_CALL(generic_5358);
62376233   fd1089_decrypt_0028();
62386234   custom_io_r = sdi_custom_io_r;
r2821r2822
62556251
62566252static DRIVER_INIT( sjryuko_5358 )
62576253{
6258   void fd1089_decrypt_5021(void);
62596254   DRIVER_INIT_CALL(generic_5358);
62606255   fd1089_decrypt_5021();
62616256   custom_io_r = sjryuko_custom_io_r;
src/mame/drivers/pktgaldx.c
r2821r2822
6464VIDEO_START(pktgaldb);
6565VIDEO_UPDATE(pktgaldb);
6666
67extern void deco102_decrypt(int region, int address_xor, int data_select_xor, int opcode_select_xor);
68
6967extern UINT16* pcktgaldb_fgram;
7068extern UINT16* pcktgaldb_sprites;
7169
src/mame/drivers/multigam.c
r2821r2822
232232         if ( multigam3_mmc3_last_bank != ( data & 0xc0 ) )
233233         {
234234            int bank;
235            UINT8 *prg = memory_region( REGION_CPU1 );
235236
236237            /* reset the banks */
237238            if ( multigam3_mmc3_command & 0x40 )
r2821r2822
239240               /* high bank */
240241               bank = multigam3_mmc3_banks[0] * 0x2000 + 0xa0000;
241242
242               memcpy( &memory_region( REGION_CPU1 )[0x0c000], &memory_region( REGION_USER1 )[bank], 0x2000 );
243               memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_USER1 )[0xa0000 + 0x3c000], 0x2000 );
243               memcpy( &prg[0x0c000], &prg[bank], 0x2000 );
244               memcpy( &prg[0x08000], &prg[0xa0000 + 0x3c000], 0x2000 );
244245            }
245246            else
246247            {
247248               /* low bank */
248249               bank = multigam3_mmc3_banks[0] * 0x2000 + 0xa0000;
249250
250               memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_USER1 )[bank], 0x2000 );
251               memcpy( &memory_region( REGION_CPU1 )[0x0c000], &memory_region( REGION_USER1 )[0xa0000 + 0x3c000], 0x2000 );
251               memcpy( &prg[0x08000], &prg[bank], 0x2000 );
252               memcpy( &prg[0x0c000], &prg[0xa0000 + 0x3c000], 0x2000 );
252253            }
253254
254255            /* mid bank */
255256            bank = multigam3_mmc3_banks[1] * 0x2000 + 0xa0000;
256            memcpy( &memory_region( REGION_CPU1 )[0x0a000], &memory_region( REGION_USER1 )[bank], 0x2000 );
257            memcpy( &prg[0x0a000], &prg[bank], 0x2000 );
257258
258259            multigam3_mmc3_last_bank = data & 0xc0;
259260         }
r2821r2822
283284               break;
284285
285286               case 6: /* program banking */
287               {
288                  UINT8 *prg = memory_region( REGION_CPU1 );
286289                  if ( multigam3_mmc3_command & 0x40 )
287290                  {
288291                     /* high bank */
289292                     multigam3_mmc3_banks[0] = data & 0x1f;
290293                     bank = ( multigam3_mmc3_banks[0] ) * 0x2000 + 0xa0000;
291294
292                     memcpy( &memory_region( REGION_CPU1 )[0x0c000], &memory_region( REGION_USER1 )[bank], 0x2000 );
293                     memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_USER1 )[0xa0000 + 0x3c000], 0x2000 );
295                     memcpy( &prg[0x0c000], &prg[bank], 0x2000 );
296                     memcpy( &prg[0x08000], &prg[0xa0000 + 0x3c000], 0x2000 );
294297                  }
295298                  else
296299                  {
r2821r2822
298301                     multigam3_mmc3_banks[0] = data & 0x1f;
299302                     bank = ( multigam3_mmc3_banks[0] ) * 0x2000 + 0xa0000;
300303
301                     memcpy( &memory_region( REGION_CPU1 )[0x08000], &memory_region( REGION_USER1 )[bank], 0x2000 );
302                     memcpy( &memory_region( REGION_CPU1 )[0x0c000], &memory_region( REGION_USER1 )[0xa0000 + 0x3c000], 0x2000 );
304                     memcpy( &prg[0x08000], &prg[bank], 0x2000 );
305                     memcpy( &prg[0x0c000], &prg[0xa0000 + 0x3c000], 0x2000 );
303306                  }
307               }
304308               break;
305309
306310               case 7: /* program banking */
307311                  {
308312                     /* mid bank */
313                     UINT8 *prg = memory_region( REGION_CPU1 );
309314                     multigam3_mmc3_banks[1] = data & 0x1f;
310315                     bank = multigam3_mmc3_banks[1] * 0x2000 + 0xa0000;
311316
312                     memcpy( &memory_region( REGION_CPU1 )[0x0a000], &memory_region( REGION_USER1 )[bank], 0x2000 );
317                     memcpy( &prg[0x0a000], &prg[bank], 0x2000 );
313318                  }
314319               break;
315320            }
src/mame/drivers/atarigx2.c
r2821r2822
8181
8282static READ32_HANDLER( special_port2_r )
8383{
84   int temp = input_port_read_indexed(machine, 2);
84   int temp = input_port_read(machine, "IN2");
8585   if (atarigen_cpu_to_sound_ready) temp ^= 0x0020;
8686   if (atarigen_sound_to_cpu_ready) temp ^= 0x0010;
8787   temp ^= 0x0008;      /* A2D.EOC always high for now */
r2821r2822
9191
9292static READ32_HANDLER( special_port3_r )
9393{
94   int temp = input_port_read_indexed(machine, 3);
94   int temp = input_port_read(machine, "IN3");
9595   return (temp << 16) | temp;
9696}
9797
r2821r2822
111111   switch (offset)
112112   {
113113      case 0:
114         return (input_port_read_indexed(machine, 5) << 24) | (input_port_read_indexed(machine, 6) << 8);
114         return (input_port_read(machine, "A2D0") << 24) | (input_port_read(machine, "A2D1") << 8);
115115      case 1:
116         return (input_port_read_indexed(machine, 7) << 24) | (input_port_read_indexed(machine, 8) << 8);
116         return (input_port_read(machine, "A2D2") << 24) | (input_port_read(machine, "A2D3") << 8);
117117   }
118118
119119   return 0;
r2821r2822
11691169
11701170static READ32_HANDLER( inputs_01_r )
11711171{
1172   return (input_port_read_indexed(machine, 0) << 16) | input_port_read_indexed(machine, 1);
1172   return (input_port_read(machine, "IN0") << 16) | input_port_read(machine, "IN1");
11731173}
11741174
11751175
r2821r2822
12151215 *************************************/
12161216
12171217static INPUT_PORTS_START( spclords )
1218   PORT_START      /* 68.SW (A1=0) */
1218   PORT_START_TAG("IN0")      /* 68.SW (A1=0) */
12191219   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
12201220   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )                  /* BLUE button */
12211221   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)      /* Left thumb */
r2821r2822
12261226   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)      /* Throttle button */
12271227   PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
12281228
1229   PORT_START      /* 68.SW (A1=1) */
1229   PORT_START_TAG("IN1")      /* 68.SW (A1=1) */
12301230   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
12311231   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START2 )                  /* RED button */
12321232   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)      /* Right thumb */
r2821r2822
12371237   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
12381238   PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
12391239
1240   PORT_START      /* 68.STATUS (A2=0) */
1240   PORT_START_TAG("IN2")      /* 68.STATUS (A2=0) */
12411241   PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_SPECIAL )   /* +5V */
12421242   PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_SPECIAL )   /* A2D.EOC */
12431243   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /AUDIRQ */
r2821r2822
12461246   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_VBLANK )
12471247   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
12481248
1249   PORT_START      /* 68.STATUS (A2=1) */
1249   PORT_START_TAG("IN3")      /* 68.STATUS (A2=1) */
12501250   PORT_BIT( 0x0003, IP_ACTIVE_LOW, IPT_SPECIAL )   /* +5V */
12511251   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /XIRQ */
12521252   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /XFULL */
r2821r2822
12571257
12581258   JSA_III_PORT   /* audio board port */
12591259
1260   PORT_START      /* A2D @ 0xD00000 */
1260   PORT_START_TAG("A2D0")      /* A2D @ 0xD00000 */
12611261   PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1)
12621262   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
12631263
1264   PORT_START      /* A2D @ 0xD00002 */
1264   PORT_START_TAG("A2D1")      /* A2D @ 0xD00002 */
12651265   PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_Y ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1)
12661266   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
12671267
1268   PORT_START      /* A2D @ 0xD00004 */
1268   PORT_START_TAG("A2D2")      /* A2D @ 0xD00004 */
12691269   PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(2)
12701270   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
12711271
1272   PORT_START      /* A2D @ 0xD00006 */
1272   PORT_START_TAG("A2D3")      /* A2D @ 0xD00006 */
12731273   PORT_BIT ( 0x00ff, 0x0080, IPT_AD_STICK_Y ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(2)
12741274   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
12751275INPUT_PORTS_END
12761276
12771277
12781278static INPUT_PORTS_START( motofren )
1279   PORT_START      /* 68.SW (A1=0) */
1279   PORT_START_TAG("IN0")      /* 68.SW (A1=0) */
12801280   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
12811281   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )                  /* Start/fire */
12821282   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)      /* AUX3 */
r2821r2822
12841284   PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)      /* AUX1 */
12851285   PORT_BIT( 0xf000, IP_ACTIVE_LOW, IPT_UNUSED )
12861286
1287   PORT_START      /* 68.SW (A1=1) */
1287   PORT_START_TAG("IN1")      /* 68.SW (A1=1) */
12881288   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
12891289
1290   PORT_START      /* 68.STATUS (A2=0) */
1290   PORT_START_TAG("IN2")      /* 68.STATUS (A2=0) */
12911291   PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED )   /* +5V */
12921292   PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_SPECIAL )   /* A2D.EOC */
12931293   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /AUDIRQ */
r2821r2822
12961296   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_VBLANK )
12971297   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
12981298
1299   PORT_START      /* 68.STATUS (A2=1) */
1299   PORT_START_TAG("IN3")      /* 68.STATUS (A2=1) */
13001300   PORT_BIT( 0x0003, IP_ACTIVE_LOW, IPT_SPECIAL )   /* +5V */
13011301   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /XIRQ */
13021302   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /XFULL */
r2821r2822
13071307
13081308   JSA_III_PORT   /* audio board port */
13091309
1310   PORT_START      /* A2D @ 0xD00000 */
1310   PORT_START_TAG("A2D0")      /* A2D @ 0xD00000 */
13111311   PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(16)
13121312
1313   PORT_START      /* A2D @ 0xD00002 */
1313   PORT_START_TAG("A2D1")      /* A2D @ 0xD00002 */
13141314   PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
13151315
1316   PORT_START      /* A2D @ 0xD00004 */
1316   PORT_START_TAG("A2D2")      /* A2D @ 0xD00004 */
13171317   PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10)
13181318
1319   PORT_START      /* A2D @ 0xD00006 */
1319   PORT_START_TAG("A2D3")      /* A2D @ 0xD00006 */
13201320   PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
13211321INPUT_PORTS_END
13221322
13231323
13241324static INPUT_PORTS_START( rrreveng )
1325   PORT_START      /* 68.SW (A1=0) */
1325   PORT_START_TAG("IN0")      /* 68.SW (A1=0) */
13261326   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
13271327   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
13281328   PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
r2821r2822
13321332   PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
13331333   PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
13341334
1335   PORT_START      /* 68.SW (A1=1) */
1335   PORT_START_TAG("IN1")      /* 68.SW (A1=1) */
13361336   PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNUSED )
13371337   PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START2 )
13381338   PORT_BIT( 0xfe00, IP_ACTIVE_LOW, IPT_UNUSED )
13391339
1340   PORT_START      /* 68.STATUS (A2=0) */
1340   PORT_START_TAG("IN2")      /* 68.STATUS (A2=0) */
13411341   PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_SPECIAL )   /* +5V */
13421342   PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_SPECIAL )   /* A2D.EOC */
13431343   PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /AUDIRQ */
r2821r2822
13461346   PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_VBLANK )
13471347   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
13481348
1349   PORT_START      /* 68.STATUS (A2=1) */
1349   PORT_START_TAG("IN3")      /* 68.STATUS (A2=1) */
13501350   PORT_BIT( 0x0003, IP_ACTIVE_LOW, IPT_SPECIAL )   /* +5V */
13511351   PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /XIRQ */
13521352   PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_SPECIAL )   /* /XFULL */
r2821r2822
13571357
13581358   JSA_III_PORT   /* audio board port */
13591359
1360   PORT_START      /* A2D @ 0xD00000 */
1360   PORT_START_TAG("A2D0")      /* A2D @ 0xD00000 */
13611361   PORT_BIT ( 0x00ff, 0x0010, IPT_PEDAL ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
13621362   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
13631363
1364   PORT_START      /* A2D @ 0xD00002 */
1364   PORT_START_TAG("A2D1")      /* A2D @ 0xD00002 */
13651365   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
13661366
1367   PORT_START      /* A2D @ 0xD00004 */
1367   PORT_START_TAG("A2D2")      /* A2D @ 0xD00004 */
13681368   PORT_BIT ( 0x00ff, 0x0080, IPT_PADDLE ) PORT_MINMAX(0x10,0xf0) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
13691369   PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED )
13701370
1371   PORT_START      /* A2D @ 0xD00006 */
1371   PORT_START_TAG("A2D3")      /* A2D @ 0xD00006 */
13721372   PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED )
13731373INPUT_PORTS_END
13741374
src/mame/drivers/nwk-tr.c
r2821r2822
881881   REGION_SOUND1
882882};
883883
884static const ppc_config nwktr_ppc_cfg =
885{
886   PPC_MODEL_403GA
887};
888
889884static const sharc_config sharc_cfg =
890885{
891886   BOOT_MODE_EPROM
r2821r2822
899894static MACHINE_DRIVER_START( nwktr )
900895
901896   /* basic machine hardware */
902   MDRV_CPU_ADD(PPC403, 64000000/2)   /* PowerPC 403GA 32MHz */
903   MDRV_CPU_CONFIG(nwktr_ppc_cfg)
897   MDRV_CPU_ADD(PPC403GA, 64000000/2)   /* PowerPC 403GA 32MHz */
904898   MDRV_CPU_PROGRAM_MAP(nwktr_map, 0)
905899
906900   MDRV_CPU_ADD(M68000, 64000000/4)   /* 16MHz */
r2821r2822
938932
939933/*****************************************************************************/
940934
941static UINT8 jamma_rdata[1024];
942static void jamma_r(int length)
943{
944   int i;
945   //printf("jamma_r %d\n", length);
946   for (i=0; i < length; i++)
947   {
948      jamma_rdata[i] = 0;
949   }
950}
951
952static UINT8 jamma_wdata[1024];
953static void jamma_w(int length)
954{
955   int i;
956   //printf("jamma_w %d\n", length);
957   for (i=0; i < length; i++)
958   {
959      //jamma_jvs_w(jamma_wdata[i]);
960   }
961
962   //jamma_jvs_cmd_exec();
963}
964
965935static void sound_irq_callback(running_machine *machine, int irq)
966936{
967937   if (irq == 0)
r2821r2822
981951   K056800_init(sound_irq_callback);
982952   K033906_init();
983953
984   ppc403_install_spu_tx_dma_handler(jamma_w, jamma_wdata);
985   ppc403_install_spu_rx_dma_handler(jamma_r, jamma_rdata);
954//  cpunum_set_info_fct(0, CPUINFO_PTR_SPU_TX_HANDLER, (genf *)jamma_jvs_w);
955//  cpunum_set_info_fct(0, CPUINFO_PTR_SPU_RX_HANDLER, (genf *)jamma_jvs_r);
986956
987957   adc1213x_init(0, adc12138_input_callback);
988958}
src/mame/drivers/homerun.c
r2821r2822
161161   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN  )
162162   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
163163   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
164   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
164165   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START1   )
166   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
165167   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 )
166168
167   PORT_BIT( 0x77, IP_ACTIVE_HIGH, IPT_UNUSED )
168
169169   PORT_START
170170   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2  )
171171   PORT_BIT( 0xdf, IP_ACTIVE_HIGH, IPT_UNUSED )
src/mame/drivers/champbas.c
r2821r2822
349349   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
350350   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
351351   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
352   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
353352INPUT_PORTS_END
354353
355354
src/mame/drivers/megasys1.c
r2821r2822
12781278   ROM_LOAD( "ph.bin",        0x0000, 0x0200, CRC(8359650a) SHA1(97d0105f06c64340fb19a541db03481a7e0b5e05) )
12791279ROM_END
12801280
1281/*
12811282
1283Monky Elf
1284
1285PCB Layout
1286----------
1287
1288|---------------------------------------------|
1289|     1   62256   62256  62256  62256     8   |
1290|     2    3      4                           |
1291| M6295     68000                         9   |
1292| M6295                                       |
1293|YM2151                                   10  |
1294|                                             |
1295|J  6116                                      |
1296|A  6116                                      |
1297|M                                       12MHz|
1298|M                                            |
1299|A                                            |
1300|                                             |
1301|                                             |
1302|                                  62256      |
1303|     62256   62256                62256      |
1304|      5        6    6264                     |
1305|DSW1    68000       6264                     |
1306|                                  62256      |
1307|DSW2         16MHz      7         62256      |
1308|---------------------------------------------|
1309Notes:
1310     68000 clocks 8.000MHz [16/2]
1311     YM2151 clock 3.000MHz [12/4]
1312     M6295 clocks 3.000MHz [12/4] pin 7 high
1313
1314*/
1315
1316ROM_START( monkelf )
1317   ROM_REGION( 0xc0000, REGION_CPU1, 0 )      /* Main CPU Code: 00000-3ffff & 80000-bffff */
1318   ROM_LOAD16_BYTE( "6",  0x000000, 0x020000, CRC(40b80914) SHA1(103dd3531b6b270e0d756801ff5ac69db5c6b82f) )
1319   ROM_CONTINUE (                   0x080000, 0x020000 )
1320   ROM_LOAD16_BYTE(  "5", 0x000001, 0x020000, CRC(6c45465d) SHA1(ae30c3f14617ffe99622a019eb64880ac14bf7cf) )
1321   ROM_CONTINUE (                   0x080001, 0x020000 )
1322
1323   ROM_REGION( 0x40000, REGION_CPU2, 0 )      /* Sound CPU Code */
1324   ROM_LOAD16_BYTE( "4",  0x000000, 0x020000, CRC(d02ec045) SHA1(465b61d89ca06e7e0a42c42efb6919c964ad0f93) )
1325   ROM_LOAD16_BYTE( "3",  0x000001, 0x020000, CRC(30213390) SHA1(9334978d3568b36215ed29789501f7cbaf6651ea) )
1326
1327   ROM_REGION( 0x80000, REGION_GFX1, ROMREGION_DISPOSE ) /* Scroll 0 */
1328   ROM_LOAD( "8",  0x000000, 0x080000, CRC(728335d4) SHA1(bbf13378ac0bff5e732eb30081b421ed89d12fa2) )
1329
1330   ROM_REGION( 0x80000, REGION_GFX2, ROMREGION_DISPOSE ) /* Scroll 1 */
1331   ROM_LOAD( "9",  0x000000, 0x080000, CRC(7896f6b0) SHA1(f09c1592aaa34eb5b7fe096ad4ccdcb155a5cadd) )
1332
1333   ROM_REGION( 0x20000, REGION_GFX3, ROMREGION_DISPOSE ) /* Scroll 2 */
1334   ROM_LOAD( "10",  0x000000, 0x020000, CRC(0c37edf7) SHA1(4074377f756b231b905b9b6a087c6d6ad3d49f52) )
1335
1336   ROM_REGION( 0x80000, REGION_GFX4, ROMREGION_DISPOSE ) /* Sprites */
1337   ROM_LOAD( "7",  0x000000, 0x080000, CRC(2b1180b3) SHA1(6d62b6bd73b9dd23670a0683f28609be29ac1d98) )
1338
1339   ROM_REGION( 0x40000, REGION_SOUND1, 0 )      /* Samples */
1340   ROM_LOAD( "1",  0x000000, 0x040000, CRC(13be9979) SHA1(828ae745867e25834e51d08308b4ab5d8e80f2c8) )
1341
1342   ROM_REGION( 0x40000, REGION_SOUND2, 0 )      /* Samples */
1343   ROM_LOAD( "2",  0x000000, 0x040000, CRC(05bc04d9) SHA1(b903edf39393cad2b4b6b58b10651304793aaa3e) )
1344
1345   ROM_REGION( 0x0200, REGION_PROMS, 0 )      /* Priority PROM */
1346   ROM_LOAD( "ph.bin",        0x0000, 0x0200, CRC(8359650a) SHA1(97d0105f06c64340fb19a541db03481a7e0b5e05) )
1347ROM_END
1348
1349
12821350static INPUT_PORTS_START( avspirit )
12831351   COINS
12841352   PORT_START_TAG("IN1")
r2821r2822
39273995   memory_install_readwrite16_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x8c000, 0x8cfff, 0, 0, soldamj_spriteram16_r, soldamj_spriteram16_w);
39283996}
39293997
3998
39303999static DRIVER_INIT( stdragon )
39314000{
39324001   UINT16 *RAM;
r2821r2822
39374006   RAM[0x00045e/2] = 0x0098;   // protection
39384007}
39394008
4009static READ16_HANDLER( monkelf_input_r )
4010{
4011   return 0xffff;
4012}
39404013
4014static DRIVER_INIT( monkelf )
4015{
4016   UINT16 *ROM = (UINT16*)memory_region(REGION_CPU1);
4017   ROM[0x00744/2] = 0x4e71;
39414018
4019   memory_install_read16_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0xe0000, 0xe000f, 0, 0, monkelf_input_r);
4020
4021   megasys1_ram += 0x10000/2;
4022
4023}
4024
4025
4026
39424027GAME( 1988, lomakai,  0,        system_Z,          lomakai,  0,        ROT0,   "Jaleco", "Legend of Makai (World)", 0 )
39434028GAME( 1988, makaiden, lomakai,  system_Z,          lomakai,  0,        ROT0,   "Jaleco", "Makai Densetsu (Japan)", 0 )
39444029GAME( 1988, p47,      0,        system_A,          p47,      0,        ROT0,   "Jaleco", "P-47 - The Phantom Fighter (World)", 0 )
r2821r2822
39594044GAME( 1990, rodlndjb, rodland,  system_A,          rodland,  0,        ROT0,   "Jaleco", "Rod-Land (Japan bootleg)", 0 )
39604045GAME( 1991, avspirit, 0,        system_B,          avspirit, avspirit, ROT0,   "Jaleco", "Avenging Spirit", 0 )
39614046GAME( 1990, phantasm, avspirit, system_A,          avspirit, phantasm, ROT0,   "Jaleco", "Phantasm (Japan)", 0 )
4047GAME( 1990, monkelf,  avspirit, system_B,          avspirit, monkelf,  ROT0,   "bootleg", "Monky Elf (Korean bootleg of Avenging Spirit)", GAME_NOT_WORKING )
39624048GAME( 1991, edf,      0,        system_B,          edf,      edf,      ROT0,   "Jaleco", "E.D.F. : Earth Defense Force", 0 )
39634049GAME( 1991, edfu,     edf,      system_B,          edf,      edf,      ROT0,   "Jaleco", "E.D.F. : Earth Defense Force (North America)", 0 )
39644050GAME( 1991, 64street, 0,        system_C,          64street, 64street, ROT0,   "Jaleco", "64th. Street - A Detective Story (World)", 0 )
src/mame/drivers/pacman.c
r2821r2822
52165216
52175217static DRIVER_INIT( eyes )
52185218{
5219   int i;
5219   int i, len;
52205220   UINT8 *RAM;
52215221
52225222   /* CPU ROMs */
r2821r2822
52335233
52345234   /* Data lines D4 and D6 and address lines A0 and A2 are swapped */
52355235   RAM = memory_region(REGION_GFX1);
5236   for (i = 0;i < memory_region_length(REGION_GFX1);i += 8)
5236   len = memory_region_length(REGION_GFX1);
5237   for (i = 0;i < len;i += 8)
52375238      eyes_decode(&RAM[i]);
52385239}
52395240
52405241static DRIVER_INIT( woodpek )
52415242{
5242   int i;
5243   int i, len;
52435244   UINT8 *RAM;
52445245
52455246   /* Graphics ROMs */
52465247
52475248   /* Data lines D4 and D6 and address lines A0 and A2 are swapped */
52485249   RAM = memory_region(REGION_GFX1);
5249   for (i = 0;i < memory_region_length(REGION_GFX1);i += 8)
5250   len = memory_region_length(REGION_GFX1);
5251   for (i = 0;i < len;i += 8)
52505252      eyes_decode(&RAM[i]);
52515253}
52525254
src/mame/drivers/srmp6.c
r2821r2822
455455   COMBINE_DATA(&dmaram[offset]);
456456   if(offset==13 && dmaram[offset]==0x40)
457457   {
458      const UINT8 *rom = memory_region(REGION_USER2);
458459      UINT32 srctab=2*((((UINT32)dmaram[5])<<16)|dmaram[4]);
459460      UINT32 srcdata=2*((((UINT32)dmaram[11])<<16)|dmaram[10]);
460461      UINT32 len=4*(((((UINT32)dmaram[7]&3)<<16)|dmaram[6])+1); //??? WRONG!
r2821r2822
485486      while(1)
486487      {
487488         int i;
488         UINT8 ctrl=memory_region(REGION_USER2)[srcdata];
489         UINT8 ctrl=rom[srcdata];
489490          ++srcdata;
490491
491492         for(i=0;i<8;++i)
492493         {
493            UINT8 p=memory_region(REGION_USER2)[srcdata];
494            UINT8 p=rom[srcdata];
494495
495496            if(ctrl&0x80)
496497            {
497498               UINT8 real_byte;
498               real_byte = memory_region(REGION_USER2)[srctab+p*2];
499               real_byte = rom[srctab+p*2];
499500               tempidx+=process(real_byte,tempidx);
500               real_byte = memory_region(REGION_USER2)[srctab+p*2+1];//px[DMA_XOR((current_table_address+p*2+1))];
501               real_byte = rom[srctab+p*2+1];//px[DMA_XOR((current_table_address+p*2+1))];
501502               tempidx+=process(real_byte,tempidx);
502503             }
503504             else
src/mame/drivers/konamim2.c
r2821r2822
11101110INPUT_PORTS_END
11111111
11121112
1113static const ppc_config ppc602_config =
1113static const powerpc_config ppc602_config =
11141114{
1115   PPC_MODEL_602,
1116   0x20,            /* Multiplier 2, Bus = 33MHz, Core = 66MHz */
1117   BUS_FREQUENCY_33MHZ
1115   33000000         /* Multiplier 2, Bus = 33MHz, Core = 66MHz */
11181116};
11191117
11201118static INTERRUPT_GEN(m2)
src/mame/drivers/cave.c
r2821r2822
26212621   const int region      =   REGION_GFX1;   // sprites
26222622
26232623   const UINT32 len   =   memory_region_length(region);
2624   UINT8 *src      =   memory_region(region) + len / 2 - 1;
2625   UINT8 *dst      =   memory_region(region) + len - 1;
2624   UINT8 *rgn      =   memory_region(region);
2625   UINT8 *src      =   rgn + len / 2 - 1;
2626   UINT8 *dst      =   rgn + len - 1;
26262627
26272628   while(dst > src)
26282629   {
r2821r2822
26462647   const int region      =   REGION_GFX1;   // sprites
26472648
26482649   UINT8 *src      =   memory_region(region);
2649   UINT8 *dst      =   memory_region(region) + memory_region_length(region);
2650   UINT8 *dst      =   src + memory_region_length(region);
26502651
26512652   while(src < dst)
26522653   {
r2821r2822
40474048   Expand the 2 bit part into a 4 bit layout, so we can decode it */
40484049static void sailormn_unpack_tiles( const int region )
40494050{
4050   UINT8 *src      =   memory_region(region) + (memory_region_length(region)/4)*3 - 1;
4051   UINT8 *dst      =   memory_region(region) + (memory_region_length(region)/4)*4 - 2;
4051   const UINT32 len   =   memory_region_length(region);
4052   UINT8 *rgn      =   memory_region(region);
4053   UINT8 *src      =   rgn + (len/4)*3 - 1;
4054   UINT8 *dst      =   rgn + (len/4)*4 - 2;
40524055
40534056   while(src <= dst)
40544057   {
src/mame/drivers/brkthru.c
r2821r2822
276276   PORT_DIPSETTING(    0x08, DEF_STR( Medium ) )
277277   PORT_DIPSETTING(    0x04, DEF_STR( Hard ) )
278278   PORT_DIPSETTING(    0x00, DEF_STR( Hardest ) )
279   PORT_DIPNAME( 0x20, 0x20, DEF_STR( Flip_Screen ) )
280   PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
281   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
279//  PORT_DIPNAME( 0x20, 0x20, DEF_STR( Flip_Screen ) )
280//  PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
281//  PORT_DIPSETTING(    0x00, DEF_STR( On ) )
282282   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CHANGED(coin_inserted, 0)
283283   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_CHANGED(coin_inserted, 0)
284284   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_CHANGED(coin_inserted, 0)
src/mame/drivers/rpunch.c
r2821r2822
151151
152152static MACHINE_RESET( rpunch )
153153{
154   memcpy(memory_region(REGION_SOUND1), memory_region(REGION_SOUND1) + 0x20000, 0x20000);
154   UINT8 *snd = memory_region(REGION_SOUND1);
155   memcpy(snd, snd + 0x20000, 0x20000);
155156}
156157
157158
r2821r2822
215216{
216217   if ((data & 1) != upd_rom_bank)
217218   {
219      UINT8 *snd = memory_region(REGION_SOUND1);
218220      upd_rom_bank = data & 1;
219      memcpy(memory_region(REGION_SOUND1), memory_region(REGION_SOUND1) + 0x20000 * (upd_rom_bank + 1), 0x20000);
221      memcpy(snd, snd + 0x20000 * (upd_rom_bank + 1), 0x20000);
220222   }
221223   upd7759_reset_w(0, data >> 7);
222224}
src/mame/drivers/sstrangr.c
r2821r2822
8080
8181   get_pens(pens);
8282
83   color_map_base = sstrngr_flip_screen ?  memory_region(REGION_PROMS) : &memory_region(REGION_PROMS)[0x0200];
83   color_map_base = &memory_region(REGION_PROMS)[sstrngr_flip_screen ? 0x0000 : 0x0200];
8484
8585   for (offs = 0; offs < sstrngr_ram_size; offs++)
8686   {
src/mame/drivers/backfire.c
r2821r2822
1111*/
1212
1313#define DE156CPU ARM
14extern void decrypt156(void);
15
1614#include "driver.h"
1715#include "decocrpt.h"
1816#include "deco32.h"
r2821r2822
685683{
686684   deco56_decrypt(REGION_GFX1); /* 141 */
687685   deco56_decrypt(REGION_GFX2); /* 141 */
688   decrypt156();
686   deco156_decrypt();
689687   cpunum_set_clockscale(machine, 0, 4.0f); /* core timings aren't accurate */
690688   descramble_sound();
691689   memory_install_read32_handler(machine, 0, ADDRESS_SPACE_PROGRAM, 0x0170018, 0x017001b, 0, 0, backfire_speedup_r );
src/mame/drivers/ltcasino.c
r2821r2822
716716static DRIVER_INIT(mv4in1)
717717{
718718   int i;
719   UINT8 *rom = memory_region(REGION_CPU1);
719720   for(i=0;i<0x10000;i++)
720      memory_region(REGION_CPU1)[i]=BITSWAP8(memory_region(REGION_CPU1)[i],7,6,5,4,3,1,2,0);
721      rom[i]=BITSWAP8(rom[i],7,6,5,4,3,1,2,0);
721722}
722723
723724
src/mame/drivers/royalmah.c
r2821r2822
9898static PALETTE_INIT( royalmah )
9999{
100100   offs_t i;
101   const UINT8 *prom = memory_region(REGION_PROMS);
102   int len = memory_region_length(REGION_PROMS);
101103
102   for (i = 0; i < memory_region_length(REGION_PROMS); i++)
104   for (i = 0; i < len; i++)
103105   {
104106      UINT8 bit0, bit1, bit2, r, g, b;
105107
106      UINT8 data = memory_region(REGION_PROMS)[i];
108      UINT8 data = prom[i];
107109
108110      /* red component */
109111      bit0 = (data >> 0) & 0x01;
r2821r2822
131133static PALETTE_INIT( mjderngr )
132134{
133135   offs_t i;
136   const UINT8 *prom = memory_region(REGION_PROMS);
137   int len = memory_region_length(REGION_PROMS);
134138
135   for (i = 0; i < memory_region_length(REGION_PROMS) / 2; i++)
139   for (i = 0; i < len / 2; i++)
136140   {
137      UINT16 data = (memory_region(REGION_PROMS)[i] << 8) | memory_region(REGION_PROMS)[i + 0x200];
141      UINT16 data = (prom[i] << 8) | prom[i + 0x200];
138142
139143      /* the bits are in reverse order */
140144      UINT8 r = BITSWAP8((data >>  0) & 0x1f,7,6,5,0,1,2,3,4 );
r2821r2822
30873091   PORT_DIPNAME( 0x04, 0x04, "Allow Bets" )
30883092   PORT_DIPSETTING(    0x00, DEF_STR( No ) )
30893093   PORT_DIPSETTING(    0x04, DEF_STR( Yes ) )
3090   PORT_DIPNAME( 0x08, 0x08, "Unknown 2-2" )
3091   PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
3092   PORT_DIPSETTING(    0x00, DEF_STR( On ) )
30933094   PORT_DIPNAME( 0x18, 0x18, "Unknown 2-3&4*" )
30943095   PORT_DIPSETTING(    0x00, DEF_STR( No ) )
30953096   PORT_DIPSETTING(    0x18, "2" )
src/mame/drivers/coolridr.c
r2821r2822
9797   AM_RANGE(0x300000, 0x300fff) AM_READWRITE(SCSP_1_r, SCSP_1_w)
9898ADDRESS_MAP_END
9999
100static INPUT_PORTS_START( coolridr )
101INPUT_PORTS_END
102100
101
103102static const gfx_layout tiles8x8_layout =
104103{
105104   16,16,
r2821r2822
225224   ROMX_LOAD( "mp17649.10",0x0000009, 0x0200000, CRC(567fbc0a) SHA1(3999c99b26f13d97ac1c58de00a44049ee7775fd), ROM_SKIP(9) )
226225ROM_END
227226
228GAME( 1995, coolridr,    0, coolridr,    coolridr,    0, ROT0,  "Sega", "Cool Riders",GAME_NOT_WORKING|GAME_NO_SOUND )
227GAME( 1995, coolridr,    0, coolridr,    0,    0, ROT0,  "Sega", "Cool Riders",GAME_NOT_WORKING|GAME_NO_SOUND )
src/mame/drivers/darkmist.c
r2821r2822
422422
423423static DRIVER_INIT(darkmist)
424424{
425   int i;
425   int i, len;
426426   UINT8 *ROM = memory_region(REGION_CPU1);
427427   UINT8 *buffer = malloc_or_die(0x10000);
428428   UINT8 *decrypt = auto_malloc(0x8000);
r2821r2822
460460
461461   /* adr line swaps */
462462   ROM = memory_region(REGION_USER1);
463   memcpy( buffer, ROM, memory_region_length(REGION_USER1) );
463   len = memory_region_length(REGION_USER1);
464   memcpy( buffer, ROM, len );
464465
465   for(i=0;i<memory_region_length(REGION_USER1);i++)
466   for(i=0;i<len;i++)
466467   {
467468      ROM[i]=buffer[BITSWAP24(i,23,22,21,20,19,18,17,16,15,6,5,4,3,2,14,13,12,11,8,7,1,0,10,9)];
468469   }
469470
470471   ROM = memory_region(REGION_USER2);
471   memcpy( buffer, ROM, memory_region_length(REGION_USER2) );
472   for(i=0;i<memory_region_length(REGION_USER2);i++)
472   len = memory_region_length(REGION_USER2);
473   memcpy( buffer, ROM, len );
474   for(i=0;i<len;i++)
473475   {
474476      ROM[i]=buffer[BITSWAP24(i,23,22,21,20,19,18,17,16,15,6,5,4,3,2,14,13,12,11,8,7,1,0,10,9)];
475477   }
476478
477479   ROM = memory_region(REGION_USER3);
478   memcpy( buffer, ROM, memory_region_length(REGION_USER3) );
479   for(i=0;i<memory_region_length(REGION_USER3);i++)
480   len = memory_region_length(REGION_USER3);
481   memcpy( buffer, ROM, len );
482   for(i=0;i<len;i++)
480483   {
481484      ROM[i]=buffer[BITSWAP24(i,23,22,21,20,19,18,17,16,15,14 ,5,4,3,2,11,10,9,8,13,12,1,0,7,6)];
482485   }
483486
484487   ROM = memory_region(REGION_USER4);
485   memcpy( buffer, ROM, memory_region_length(REGION_USER4) );
486   for(i=0;i<memory_region_length(REGION_USER4);i++)
488   len = memory_region_length(REGION_USER4);
489   memcpy( buffer, ROM, len );
490   for(i=0;i<len;i++)
487491   {
488492      ROM[i]=buffer[BITSWAP24(i,23,22,21,20,19,18,17,16,15,14 ,5,4,3,2,11,10,9,8,13,12,1,0,7,6)];
489493   }
src/mame/drivers/nmk16.c
r2821r2822
201201}
202202
203203extern UINT16 *nmk_bgvideoram,*nmk_fgvideoram,*nmk_txvideoram;
204extern UINT16 *gunnail_scrollram;
204extern UINT16 *gunnail_scrollram, *gunnail_scrollramy;
205205
206206READ16_HANDLER( nmk_bgvideoram_r );
207207WRITE16_HANDLER( nmk_bgvideoram_w );
r2821r2822
212212WRITE16_HANDLER( nmk_scroll_w );
213213WRITE16_HANDLER( nmk_scroll_2_w );
214214WRITE16_HANDLER( nmk_scroll_3_w );
215WRITE16_HANDLER( gunnail_scrollx_w );
216WRITE16_HANDLER( gunnail_scrolly_w );
217215WRITE16_HANDLER( nmk_flipscreen_w );
218216WRITE16_HANDLER( nmk_tilebank_w );
219217WRITE16_HANDLER( bioship_scroll_w );
r2821r2822
991989   AM_RANGE(0x09c000, 0x09c7ff) AM_WRITE(nmk_txvideoram_w) AM_BASE(&nmk_txvideoram)
992990ADDRESS_MAP_END
993991
994static ADDRESS_MAP_START( gunnail_readmem, ADDRESS_SPACE_PROGRAM, 16 )
995   AM_RANGE(0x000000, 0x07ffff) AM_READ(SMH_ROM)
992static ADDRESS_MAP_START( gunnail_map, ADDRESS_SPACE_PROGRAM, 16 )
993   AM_RANGE(0x000000, 0x07ffff) AM_ROM
996994   AM_RANGE(0x080000, 0x080001) AM_READ(input_port_0_word_r)
997995   AM_RANGE(0x080002, 0x080003) AM_READ(input_port_1_word_r)
998996   AM_RANGE(0x080008, 0x080009) AM_READ(input_port_2_word_r)
999997   AM_RANGE(0x08000a, 0x08000b) AM_READ(input_port_3_word_r)
1000998   AM_RANGE(0x08000e, 0x08000f) AM_READ(NMK004_r)
1001   AM_RANGE(0x088000, 0x0887ff) AM_READ(SMH_RAM) /* palette ram */
1002   AM_RANGE(0x090000, 0x093fff) AM_READ(nmk_bgvideoram_r)
1003   AM_RANGE(0x09c000, 0x09cfff) AM_READ(nmk_txvideoram_r)
1004   AM_RANGE(0x09d000, 0x09dfff) AM_READ(nmk_txvideoram_r)   /* mirror */
1005   AM_RANGE(0x0f0000, 0x0fffff) AM_RAM AM_BASE(&nmk16_mainram)
1006ADDRESS_MAP_END
1007
1008static ADDRESS_MAP_START( gunnail_writemem, ADDRESS_SPACE_PROGRAM, 16 )
1009   AM_RANGE(0x000000, 0x07ffff) AM_WRITE(SMH_ROM)
1010999   AM_RANGE(0x080014, 0x080015) AM_WRITE(nmk_flipscreen_w)
10111000   AM_RANGE(0x080016, 0x080017) AM_WRITE(SMH_NOP)   /* IRQ enable? */
10121001   AM_RANGE(0x080018, 0x080019) AM_WRITE(nmk_tilebank_w)
10131002   AM_RANGE(0x08001e, 0x08001f) AM_WRITE(NMK004_w)
1014   AM_RANGE(0x088000, 0x0887ff) AM_WRITE(paletteram16_RRRRGGGGBBBBRGBx_word_w) AM_BASE(&paletteram16)
1015   AM_RANGE(0x08c000, 0x08c1ff) AM_RAM_WRITE(gunnail_scrollx_w) AM_BASE(&gunnail_scrollram)
1016   AM_RANGE(0x08c200, 0x08c201) AM_WRITE(gunnail_scrolly_w)
1017   AM_RANGE(0x08c202, 0x08c7ff) AM_RAM // extra scroll registers (used after a boss is killed and in level 5)
1018   AM_RANGE(0x090000, 0x093fff) AM_WRITE(nmk_bgvideoram_w) AM_BASE(&nmk_bgvideoram)
1019   AM_RANGE(0x09c000, 0x09cfff) AM_WRITE(nmk_txvideoram_w) AM_BASE(&nmk_txvideoram)
1020   AM_RANGE(0x09d000, 0x09dfff) AM_WRITE(nmk_txvideoram_w)   /* mirror */
1003   AM_RANGE(0x088000, 0x0887ff) AM_RAM_WRITE(paletteram16_RRRRGGGGBBBBRGBx_word_w) AM_BASE(&paletteram16)
1004   AM_RANGE(0x08c000, 0x08c1ff) AM_WRITEONLY AM_BASE(&gunnail_scrollram)
1005   AM_RANGE(0x08c200, 0x08c3ff) AM_WRITEONLY AM_BASE(&gunnail_scrollramy)
1006   AM_RANGE(0x08c400, 0x08c7ff) AM_WRITEONLY   // unknown
1007   AM_RANGE(0x090000, 0x093fff) AM_RAM_WRITE(nmk_bgvideoram_w) AM_BASE(&nmk_bgvideoram)
1008   AM_RANGE(0x09c000, 0x09cfff) AM_RAM_WRITE(nmk_txvideoram_w) AM_MIRROR(0x001000) AM_BASE(&nmk_txvideoram)
1009   AM_RANGE(0x0f0000, 0x0fffff) AM_RAM AM_BASE(&nmk16_mainram)
10211010ADDRESS_MAP_END
10221011
10231012static ADDRESS_MAP_START( macross2_readmem, ADDRESS_SPACE_PROGRAM, 16 )
r2821r2822
43524341static MACHINE_DRIVER_START( gunnail )
43534342
43544343   /* basic machine hardware */
4355   MDRV_CPU_ADD(M68000, 10000000) /* 10 MHz? */
4356   MDRV_CPU_PROGRAM_MAP(gunnail_readmem,gunnail_writemem)
4344   MDRV_CPU_ADD(M68000, 12000000) /* 12 MHz? */
4345   MDRV_CPU_PROGRAM_MAP(gunnail_map, 0)
43574346   MDRV_CPU_VBLANK_INT("main", irq4_line_hold)
43584347   MDRV_CPU_PERIODIC_INT(irq1_line_hold,112)
43594348
r2821r2822
43624351   /* video hardware */
43634352   MDRV_SCREEN_ADD("main", RASTER)
43644353   MDRV_SCREEN_REFRESH_RATE(56)
4365   MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
4354//  MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
43664355   MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
43674356   MDRV_SCREEN_SIZE(512, 256)
43684357   MDRV_SCREEN_VISIBLE_AREA(0*8, 48*8-1, 2*8, 30*8-1)
r2821r2822
46074596{
46084597   /* GFX are scrambled.  We decode them here.  (BIG Thanks to Antiriad for descrambling info) */
46094598   UINT8 *rom;
4610   int A;
4599   int A, len;
46114600
46124601   static const UINT8 decode_data_bg[8][8] =
46134602   {
r2821r2822
46374626
46384627   /* background */
46394628   rom = memory_region(REGION_GFX2);
4640   for (A = 0;A < memory_region_length(REGION_GFX2);A++)
4629   len = memory_region_length(REGION_GFX2);
4630   for (A = 0;A < len;A++)
46414631   {
46424632      rom[A] = decode_byte( rom[A], decode_data_bg[bjtwin_address_map_bg0(A)]);
46434633   }
46444634
46454635   /* sprites */
46464636   rom = memory_region(REGION_GFX3);
4647   for (A = 0;A < memory_region_length(REGION_GFX3);A += 2)
4637   len = memory_region_length(REGION_GFX3);
4638   for (A = 0;A < len;A += 2)
46484639   {
46494640      UINT16 tmp = decode_word( rom[A+1]*256 + rom[A], decode_data_sprite[bjtwin_address_map_sprites(A)]);
46504641      rom[A+1] = tmp >> 8;
r2821r2822
46584649       going Open Source, best of luck in future development. */
46594650
46604651   UINT8 *rom;
4661   int A;
4652   int A, len;
46624653
46634654   /* The Main 68k Program of the Bootleg is Bitswapped */
46644655   static const UINT8 decode_data_tdragonb[1][16] =
r2821r2822
46734664   };
46744665
46754666   rom = memory_region(REGION_CPU1);
4676   for (A = 0;A < memory_region_length(REGION_CPU1);A += 2)
4667   len = memory_region_length(REGION_CPU1);
4668   for (A = 0;A < len;A += 2)
46774669   {
46784670#ifdef LSB_FIRST
46794671      UINT16 tmp = decode_word( rom[A+1]*256 + rom[A], decode_data_tdragonb[0]);
r2821r2822
46874679   }
46884680
46894681   rom = memory_region(REGION_GFX2);
4690   for (A = 0;A < memory_region_length(REGION_GFX2);A++)
4682   len = memory_region_length(REGION_GFX2);
4683   for (A = 0;A < len;A++)
46914684   {
46924685      rom[A] = decode_byte( rom[A], decode_data_tdragonbgfx[0]);
46934686   }
46944687
46954688   rom = memory_region(REGION_GFX3);
4696   for (A = 0;A < memory_region_length(REGION_GFX3);A++)
4689   len = memory_region_length(REGION_GFX3);
4690   for (A = 0;A < len;A++)
46974691   {
46984692      rom[A] = decode_byte( rom[A], decode_data_tdragonbgfx[0]);
46994693   }
r2821r2822
47034697{
47044698   /* Like Thunder Dragon Bootleg without the Program Rom Swapping */
47054699   UINT8 *rom;
4706   int A;
4700   int A, len;
47074701
47084702   /* Graphic Roms Could Also Do With Rearranging to make things simpler */
47094703   static const UINT8 decode_data_tdragonbgfx[1][8] =
r2821r2822
47124706   };
47134707
47144708   rom = memory_region(REGION_GFX2);
4715   for (A = 0;A < memory_region_length(REGION_GFX2);A++)
4709   len = memory_region_length(REGION_GFX2);
4710   for (A = 0;A < len;A++)
47164711   {
47174712      rom[A] = decode_byte( rom[A], decode_data_tdragonbgfx[0]);
47184713   }
47194714
47204715   rom = memory_region(REGION_GFX3);
4721   for (A = 0;A < memory_region_length(REGION_GFX3);A++)
4716   len = memory_region_length(REGION_GFX3);
4717   for (A = 0;A < len;A++)
47224718   {
47234719      rom[A] = decode_byte( rom[A], decode_data_tdragonbgfx[0]);
47244720   }
r2821r2822
59735969   ROM_LOAD( "921a10",      0x0200, 0x0020, CRC(8371e42d) SHA1(6cfd70dfa00e85ec1df8832d41df331cc3e3733a) )   /* unknown */
59745970ROM_END
59755971
5972/*
5973Gunnail (JPN Ver.)
5974(c)1992 NMK
5975AK92077
5976
5977CPU  :MC68000P12
5978Sound:YM2203C,OKI M6295 x2
5979OSC  :12.0000MHz,16.0000MHz,10.0000MHz
5980Other:NMK 111 x3,214 x2,901,903 x2,902,005,004,215,008,009 x2
5981*/
59765982ROM_START( gunnail )
59775983   ROM_REGION( 0x80000, REGION_CPU1, 0 )      /* 68000 code */
59785984   ROM_LOAD16_BYTE( "3e.bin",  0x00000, 0x40000, CRC(61d985b2) SHA1(96daca603f18accb47f98a3e584b2c84fc5a2ca4) )
src/emu/cpu/x86drc.c
r2821r2822
1/***************************************************************************
2
3    x86drc.c
4
5    x86 Dynamic recompiler support routines.
6
7    Copyright Nicola Salmoria and the MAME Team.
8    Visit http://mamedev.org for licensing and usage restrictions.
9
10***************************************************************************/
11
12#include "debugger.h"
13#include "deprecat.h"
14#include "x86drc.h"
15
16#define LOG_DISPATCHES            0
17#define BREAK_ON_MODIFIED_CODE      0
18
19
20
21
22static const UINT16 fp_control[4] = { 0x023f, 0x063f, 0x0a3f, 0x0e3f };
23static const UINT32 sse_control[4] = { 0x9fc0, 0xbfc0, 0xdfc0, 0xffc0 };
24
25
26static void append_entry_point(drc_core *drc);
27static void append_recompile(drc_core *drc);
28static void append_flush(drc_core *drc);
29static void append_out_of_cycles(drc_core *drc);
30
31#if LOG_DISPATCHES
32static void log_dispatch(drc_core *drc);
33#endif
34
35
36
37/***************************************************************************
38    EXTERNAL INTERFACES
39***************************************************************************/
40
41/*-------------------------------------------------
42    drc_init - initialize the DRC core
43-------------------------------------------------*/
44
45drc_core *drc_init(UINT8 cpunum, drc_config *config)
46{
47   int address_bits = config->address_bits;
48   int effective_address_bits = address_bits - config->lsbs_to_ignore;
49   UINT8 cache_allocated = FALSE;
50   drc_core *drc = NULL;
51
52   /* allocate memory */
53   if (config->cache_base == NULL)
54   {
55      config->cache_base = osd_alloc_executable(config->cache_size);
56      if (config->cache_base == NULL)
57         goto error;
58      cache_allocated = TRUE;
59   }
60
61   /* the drc structure lives at the start of the cache */
62   drc = (drc_core *)config->cache_base;
63   memset(drc, 0, sizeof(*drc));
64
65   /* copy in relevant data from the config */
66   drc->pcptr        = config->pcptr;
67   drc->icountptr    = config->icountptr;
68   drc->esiptr       = config->esiptr;
69   drc->cb_reset     = config->cb_reset;
70   drc->cb_recompile = config->cb_recompile;
71   drc->cb_entrygen  = config->cb_entrygen;
72   drc->uses_fp      = config->uses_fp;
73   drc->uses_sse     = config->uses_sse;
74   drc->pc_in_memory = config->pc_in_memory;
75   drc->icount_in_memory = config->icount_in_memory;
76   drc->fpcw_curr    = fp_control[0];
77   drc->mxcsr_curr   = sse_control[0];
78
79   /* configure cache */
80   drc->cache_base = (UINT8 *)config->cache_base + sizeof(*drc);
81   drc->cache_size = config->cache_size - sizeof(*drc);
82   drc->cache_end = drc->cache_base + drc->cache_size;
83   drc->cache_danger = drc->cache_end - 65536;
84   drc->cache_allocated = cache_allocated;
85
86   /* compute shifts and masks */
87   drc->l1bits = effective_address_bits/2;
88   drc->l2bits = effective_address_bits - drc->l1bits;
89   drc->l1shift = config->lsbs_to_ignore + drc->l2bits;
90   drc->l2mask = ((1 << drc->l2bits) - 1) << config->lsbs_to_ignore;
91   drc->l2scale = 4 >> config->lsbs_to_ignore;
92
93   /* allocate lookup tables */
94   drc->lookup_l1 = malloc(sizeof(*drc->lookup_l1) * (1 << drc->l1bits));
95   drc->lookup_l2_recompile = malloc(sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits));
96   if (drc->lookup_l1 == NULL || drc->lookup_l2_recompile == NULL)
97      goto error;
98   memset(drc->lookup_l1, 0, sizeof(*drc->lookup_l1) * (1 << drc->l1bits));
99   memset(drc->lookup_l2_recompile, 0, sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits));
100
101   /* allocate the sequence and tentative lists */
102   drc->sequence_count_max = config->max_instructions;
103   drc->sequence_list = malloc(drc->sequence_count_max * sizeof(*drc->sequence_list));
104   if (drc->sequence_list == NULL)
105      goto error;
106
107   drc->tentative_count_max = config->max_instructions;
108   drc->tentative_list = malloc(drc->tentative_count_max * sizeof(*drc->tentative_list));
109   if (!drc->tentative_list)
110      return NULL;
111
112   return drc;
113
114error:
115   if (drc != NULL)
116      drc_exit(drc);
117   return NULL;
118}
119
120
121/*-------------------------------------------------
122    drc_alloc - allocate memory from the top of
123    the DRC cache
124-------------------------------------------------*/
125
126void *drc_alloc(drc_core *drc, size_t amount)
127{
128   /* if we don't have enough space, reset the cache */
129   if (drc->cache_top >= drc->cache_danger - amount)
130      drc_cache_reset(drc);
131
132   /* if we still don't have enough space, fail */
133   if (drc->cache_top >= drc->cache_danger - amount)
134      return NULL;
135
136   /* adjust the end and danger values downward */
137   drc->cache_end -= amount;
138   drc->cache_danger -= amount;
139   return drc->cache_end;
140}
141
142
143/*-------------------------------------------------
144    drc_cache_reset - reset the DRC cache
145-------------------------------------------------*/
146
147void drc_cache_reset(drc_core *drc)
148{
149   int i;
150
151   /* reset the cache and add the basics */
152   drc->cache_top = drc->cache_base;
153
154   /* append the core entry points to the fresh cache */
155   drc->entry_point = (void (*)(void))(UINT32)drc->cache_top;
156   append_entry_point(drc);
157   drc->out_of_cycles = drc->cache_top;
158   append_out_of_cycles(drc);
159
160   /* append an INT 3 before the recompile so that BREAK_ON_MODIFIED_CODE works */
161   emit_int_3(DRCTOP);
162   drc->recompile = drc->cache_top;
163   append_recompile(drc);
164   drc->dispatch = drc->cache_top;
165   drc_append_dispatcher(drc);
166   drc->flush = drc->cache_top;
167   append_flush(drc);
168
169   /* populate the recompile table */
170   for (i = 0; i < (1 << drc->l2bits); i++)
171      drc->lookup_l2_recompile[i] = drc->recompile;
172
173   /* reset all the l1 tables */
174   for (i = 0; i < (1 << drc->l1bits); i++)
175   {
176      /* point NULL entries to the generic recompile table */
177      if (drc->lookup_l1[i] == NULL)
178         drc->lookup_l1[i] = drc->lookup_l2_recompile;
179
180      /* reset allocated tables to point all entries back to the recompiler */
181      else if (drc->lookup_l1[i] != drc->lookup_l2_recompile)
182         memcpy(drc->lookup_l1[i], drc->lookup_l2_recompile, sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits));
183   }
184
185   /* call back to the host */
186   if (drc->cb_reset)
187      (*drc->cb_reset)(drc);
188}
189
190
191/*------------------------------------------------------------------
192    drc_execute
193------------------------------------------------------------------*/
194
195void drc_execute(drc_core *drc)
196{
197   (*drc->entry_point)();
198}
199
200
201/*------------------------------------------------------------------
202    drc_exit
203------------------------------------------------------------------*/
204
205void drc_exit(drc_core *drc)
206{
207   int i;
208
209   /* free all the l2 tables allocated */
210   for (i = 0; i < (1 << drc->l1bits); i++)
211      if (drc->lookup_l1[i] != drc->lookup_l2_recompile)
212         free(drc->lookup_l1[i]);
213
214   /* free the l1 table */
215   if (drc->lookup_l1)
216      free(drc->lookup_l1);
217
218   /* free the default l2 table */
219   if (drc->lookup_l2_recompile)
220      free(drc->lookup_l2_recompile);
221
222   /* free the lists */
223   if (drc->sequence_list)
224      free(drc->sequence_list);
225   if (drc->tentative_list)
226      free(drc->tentative_list);
227
228   /* and the drc itself */
229   if (drc->cache_allocated)
230      osd_free_executable(drc, drc->cache_size + sizeof(*drc));
231}
232
233
234/*------------------------------------------------------------------
235    drc_begin_sequence
236------------------------------------------------------------------*/
237
238void drc_begin_sequence(drc_core *drc, UINT32 pc)
239{
240   UINT32 l1index = pc >> drc->l1shift;
241   UINT32 l2index = ((pc & drc->l2mask) * drc->l2scale) / 4;
242
243   /* reset the sequence and tentative counts */
244   drc->sequence_count = 0;
245   drc->tentative_count = 0;
246
247   /* allocate memory if necessary */
248   if (drc->lookup_l1[l1index] == drc->lookup_l2_recompile)
249   {
250      /* create a new copy of the recompile table */
251      drc->lookup_l1[l1index] = malloc_or_die(sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits));
252
253      memcpy(drc->lookup_l1[l1index], drc->lookup_l2_recompile, sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits));
254   }
255
256   /* nuke any previous link to this instruction */
257   if (drc->lookup_l1[l1index][l2index] != drc->recompile)
258   {
259      UINT8 *cache_save = drc->cache_top;
260      drc->cache_top = drc->lookup_l1[l1index][l2index];
261      emit_jmp(DRCTOP, drc->dispatch);
262      drc->cache_top = cache_save;
263   }
264
265   /* note the current location for this instruction */
266   drc->lookup_l1[l1index][l2index] = drc->cache_top;
267}
268
269
270/*------------------------------------------------------------------
271    drc_end_sequence
272------------------------------------------------------------------*/
273
274void drc_end_sequence(drc_core *drc)
275{
276   int i, j;
277
278   /* fix up any internal links */
279   for (i = 0; i < drc->tentative_count; i++)
280      for (j = 0; j < drc->sequence_count; j++)
281         if (drc->tentative_list[i].pc == drc->sequence_list[j].pc)
282         {
283            UINT8 *cache_save = drc->cache_top;
284            drc->cache_top = drc->tentative_list[i].target;
285            emit_jmp(DRCTOP, drc->sequence_list[j].target);
286            drc->cache_top = cache_save;
287            break;
288         }
289}
290
291
292/*------------------------------------------------------------------
293    drc_register_code_at_cache_top
294------------------------------------------------------------------*/
295
296void drc_register_code_at_cache_top(drc_core *drc, UINT32 pc)
297{
298   pc_ptr_pair *pair = &drc->sequence_list[drc->sequence_count++];
299   assert_always(drc->sequence_count <= drc->sequence_count_max, "drc_register_code_at_cache_top: too many instructions!");
300
301   pair->target = drc->cache_top;
302   pair->pc = pc;
303}
304
305
306/*------------------------------------------------------------------
307    drc_get_code_at_pc
308------------------------------------------------------------------*/
309
310void *drc_get_code_at_pc(drc_core *drc, UINT32 pc)
311{
312   UINT32 l1index = pc >> drc->l1shift;
313   UINT32 l2index = ((pc & drc->l2mask) * drc->l2scale) / 4;
314   return (drc->lookup_l1[l1index][l2index] != drc->recompile) ? drc->lookup_l1[l1index][l2index] : NULL;
315}
316
317
318/*------------------------------------------------------------------
319    drc_append_verify_code
320------------------------------------------------------------------*/
321
322void drc_append_verify_code(drc_core *drc, void *code, UINT8 length)
323{
324#if BREAK_ON_MODIFIED_CODE
325   x86code *recompile = drc->recompile - 1;
326#else
327   x86code *recompile = drc->recompile;
328#endif
329
330   if (length > 8)
331   {
332      UINT32 *codeptr = code, sum = 0;
333      void *target;
334      int i;
335
336      for (i = 0; i < length / 4; i++)
337      {
338         sum = (sum >> 1) | (sum << 31);
339         sum += *codeptr++;
340      }
341
342      emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                        // xor  eax,eax
343      emit_mov_r32_imm(DRCTOP, REG_EBX, (FPTR)code);                     // mov  ebx,code
344      emit_mov_r32_imm(DRCTOP, REG_ECX, length / 4);                     // mov  ecx,length / 4
345      target = drc->cache_top;                                 // target:
346      emit_ror_r32_imm(DRCTOP, REG_EAX, 1);                           // ror  eax,1
347      emit_add_r32_m32(DRCTOP, REG_EAX, MBD(REG_EBX, 0));                  // add  eax,[ebx]
348      emit_sub_r32_imm(DRCTOP, REG_ECX, 1);                           // sub  ecx,1
349      emit_lea_r32_m32(DRCTOP, REG_EBX, MBD(REG_EBX, 4));                  // lea  ebx,[ebx+4]
350      emit_jcc(DRCTOP, COND_NZ, target);                              // jnz  target
351      emit_cmp_r32_imm(DRCTOP, REG_EAX, sum);                           // cmp  eax,sum
352      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
353   }
354   else if (length >= 12)
355   {
356      emit_cmp_m32_imm(DRCTOP, MABS(code), *(UINT32 *)code);               // cmp  [pc],opcode
357      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
358      emit_cmp_m32_imm(DRCTOP, MABS((UINT8 *)code + 4), ((UINT32 *)code)[1]);   // cmp  [pc+4],opcode+4
359      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
360      emit_cmp_m32_imm(DRCTOP, MABS((UINT8 *)code + 8), ((UINT32 *)code)[2]);   // cmp  [pc+8],opcode+8
361      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
362   }
363   else if (length >= 8)
364   {
365      emit_cmp_m32_imm(DRCTOP, MABS(code), *(UINT32 *)code);               // cmp  [pc],opcode
366      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
367      emit_cmp_m32_imm(DRCTOP, MABS((UINT8 *)code + 4), ((UINT32 *)code)[1]);   // cmp  [pc+4],opcode+4
368      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
369   }
370   else if (length >= 4)
371   {
372      emit_cmp_m32_imm(DRCTOP, MABS(code), *(UINT32 *)code);               // cmp  [pc],opcode
373      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
374   }
375   else if (length >= 2)
376   {
377      emit_cmp_m16_imm(DRCTOP, MABS(code), *(UINT16 *)code);               // cmp  [pc],opcode
378      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
379   }
380   else
381   {
382      emit_cmp_m8_imm(DRCTOP, MABS(code), *(UINT8 *)code);               // cmp  [pc],opcode
383      emit_jcc(DRCTOP, COND_NE, recompile);                           // jne  recompile
384   }
385}
386
387
388/*------------------------------------------------------------------
389    drc_append_call_debugger
390------------------------------------------------------------------*/
391
392void drc_append_call_debugger(drc_core *drc)
393{
394#ifdef ENABLE_DEBUGGER
395   if (Machine->debug_mode)
396   {
397      emit_link link;
398      emit_cmp_m32_imm(DRCTOP, MABS(&Machine->debug_mode), 0);               // cmp  [Machine->debug_mode],0
399      emit_jcc_short_link(DRCTOP, COND_E, &link);                        // je   skip
400      emit_sub_r32_imm(DRCTOP, REG_ESP, 12);                           // align stack
401      drc_append_save_call_restore(drc, (x86code *)mame_debug_hook, 12);         // save volatiles
402      resolve_link(DRCTOP, &link);
403   }
404#endif
405}
406
407
408/*------------------------------------------------------------------
409    drc_append_save_volatiles
410------------------------------------------------------------------*/
411
412void drc_append_save_volatiles(drc_core *drc)
413{
414   if (drc->icountptr && !drc->icount_in_memory)
415      emit_mov_m32_r32(DRCTOP, MABS(drc->icountptr), REG_EBP);
416   if (drc->pcptr && !drc->pc_in_memory)
417      emit_mov_m32_r32(DRCTOP, MABS(drc->pcptr), REG_EDI);
418   if (drc->esiptr)
419      emit_mov_m32_r32(DRCTOP, MABS(drc->esiptr), REG_ESI);
420}
421
422
423/*------------------------------------------------------------------
424    drc_append_restore_volatiles
425------------------------------------------------------------------*/
426
427void drc_append_restore_volatiles(drc_core *drc)
428{
429   if (drc->icountptr && !drc->icount_in_memory)
430      emit_mov_r32_m32(DRCTOP, REG_EBP, MABS(drc->icountptr));
431   if (drc->pcptr && !drc->pc_in_memory)
432      emit_mov_r32_m32(DRCTOP, REG_EDI, MABS(drc->pcptr));
433   if (drc->esiptr)
434      emit_mov_r32_m32(DRCTOP, REG_ESI, MABS(drc->esiptr));
435}
436
437
438/*------------------------------------------------------------------
439    drc_append_save_call_restore
440------------------------------------------------------------------*/
441
442void drc_append_save_call_restore(drc_core *drc, x86code *target, UINT32 stackadj)
443{
444   drc_append_save_volatiles(drc);                                    // save volatiles
445   emit_call(DRCTOP, target);                                       // call target
446   drc_append_restore_volatiles(drc);                                 // restore volatiles
447   if (stackadj)
448      emit_add_r32_imm(DRCTOP, REG_ESP, stackadj);                     // adjust stack
449}
450
451
452/*------------------------------------------------------------------
453    drc_append_standard_epilogue
454------------------------------------------------------------------*/
455
456void drc_append_standard_epilogue(drc_core *drc, INT32 cycles, INT32 pcdelta, int allow_exit)
457{
458   if (pcdelta != 0 && drc->pc_in_memory)
459      emit_add_m32_imm(DRCTOP, MABS(drc->pcptr), pcdelta);                  // add  [pc],pcdelta
460   if (cycles != 0)
461   {
462      if (drc->icount_in_memory)
463         emit_sub_m32_imm(DRCTOP, MABS(drc->icountptr), cycles);            // sub  [icount],cycles
464      else
465         emit_sub_r32_imm(DRCTOP, REG_EBP, cycles);               // sub  ebp,cycles
466   }
467   if (pcdelta != 0 && !drc->pc_in_memory)
468      emit_lea_r32_m32(DRCTOP, REG_EDI, MBD(REG_EDI, pcdelta));               // lea  edi,[edi+pcdelta]
469   if (allow_exit && cycles != 0)
470      emit_jcc(DRCTOP, COND_S, drc->out_of_cycles);                     // js   out_of_cycles
471}
472
473
474/*------------------------------------------------------------------
475    drc_append_dispatcher
476------------------------------------------------------------------*/
477
478void drc_append_dispatcher(drc_core *drc)
479{
480#if LOG_DISPATCHES
481   emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                              // align stack
482   emit_push_imm(DRCTOP, drc);                                       // push drc
483   drc_append_save_call_restore(drc, (x86code *)log_dispatch, 12);            // call log_dispatch
484#endif
485   if (drc->pc_in_memory)
486      emit_mov_r32_m32(DRCTOP, REG_EDI, MABS(drc->pcptr));                  // mov  edi,[pc]
487   emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EDI);                           // mov  eax,edi
488   emit_shr_r32_imm(DRCTOP, REG_EAX, drc->l1shift);                     // shr  eax,l1shift
489   emit_mov_r32_r32(DRCTOP, REG_EDX, REG_EDI);                           // mov  edx,edi
490   emit_mov_r32_m32(DRCTOP, REG_EAX, MISD(REG_EAX, 4, (FPTR)drc->lookup_l1));      // mov  eax,[eax*4 + l1lookup]
491   emit_and_r32_imm(DRCTOP, REG_EDX, drc->l2mask);                        // and  edx,l2mask
492   emit_jmp_m32(DRCTOP, MBISD(REG_EAX, REG_EDX, drc->l2scale, 0));            // jmp  [eax+edx*l2scale]
493}
494
495
496/*------------------------------------------------------------------
497    drc_append_fixed_dispatcher
498------------------------------------------------------------------*/
499
500void drc_append_fixed_dispatcher(drc_core *drc, UINT32 newpc)
501{
502   x86code **base = drc->lookup_l1[newpc >> drc->l1shift];
503   if (base == drc->lookup_l2_recompile)
504   {
505      emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(&drc->lookup_l1[newpc >> drc->l1shift]));
506                                                            // mov eax,[(newpc >> l1shift)*4 + l1lookup]
507      emit_jmp_m32(DRCTOP, MBD(REG_EAX, (newpc & drc->l2mask) * drc->l2scale));
508                                                            // jmp  [eax+(newpc & l2mask)*l2scale]
509   }
510   else
511      emit_jmp_m32(DRCTOP, MABS((UINT8 *)base + (newpc & drc->l2mask) * drc->l2scale));
512                                                            // jmp  [eax+(newpc & l2mask)*l2scale]
513}
514
515
516/*------------------------------------------------------------------
517    drc_append_tentative_fixed_dispatcher
518------------------------------------------------------------------*/
519
520void drc_append_tentative_fixed_dispatcher(drc_core *drc, UINT32 newpc)
521{
522   pc_ptr_pair *pair = &drc->tentative_list[drc->tentative_count++];
523   assert_always(drc->tentative_count <= drc->tentative_count_max, "drc_append_tentative_fixed_dispatcher: too many tentative branches!");
524
525   pair->target = drc->cache_top;
526   pair->pc = newpc;
527   drc_append_fixed_dispatcher(drc, newpc);
528}
529
530
531/*------------------------------------------------------------------
532    drc_append_set_fp_rounding
533------------------------------------------------------------------*/
534
535void drc_append_set_fp_rounding(drc_core *drc, UINT8 regindex)
536{
537   emit_fldcw_m16(DRCTOP, MISD(regindex, 2, (INT32)&fp_control[0]));            // fldcw [fp_control + reg*2]
538   emit_fstcw_m16(DRCTOP, MABS(&drc->fpcw_curr));                           // fnstcw [fpcw_curr]
539}
540
541
542
543/*------------------------------------------------------------------
544    drc_append_set_temp_fp_rounding
545------------------------------------------------------------------*/
546
547void drc_append_set_temp_fp_rounding(drc_core *drc, UINT8 rounding)
548{
549   emit_fldcw_m16(DRCTOP, MABS(&fp_control[rounding]));                     // fldcw [fp_control]
550}
551
552
553
554/*------------------------------------------------------------------
555    drc_append_restore_fp_rounding
556------------------------------------------------------------------*/
557
558void drc_append_restore_fp_rounding(drc_core *drc)
559{
560   emit_fldcw_m16(DRCTOP, MABS(&drc->fpcw_curr));                           // fldcw [fpcw_curr]
561}
562
563
564
565/*------------------------------------------------------------------
566    drc_append_set_sse_rounding
567------------------------------------------------------------------*/
568
569void drc_append_set_sse_rounding(drc_core *drc, UINT8 regindex)
570{
571   emit_ldmxcsr_m32(DRCTOP, MISD(regindex, 4, (INT32)&sse_control[0]));         // ldmxcsr [sse_control + reg*2]
572   emit_stmxcsr_m32(DRCTOP, MABS(&drc->mxcsr_curr));                        // stmxcsr [mxcsr_curr]
573}
574
575
576
577/*------------------------------------------------------------------
578    drc_append_set_temp_sse_rounding
579------------------------------------------------------------------*/
580
581void drc_append_set_temp_sse_rounding(drc_core *drc, UINT8 rounding)
582{
583   emit_ldmxcsr_m32(DRCTOP, MABS(&sse_control[rounding]));                  // ldmxcsr [sse_control]
584}
585
586
587
588/*------------------------------------------------------------------
589    drc_append_restore_sse_rounding
590------------------------------------------------------------------*/
591
592void drc_append_restore_sse_rounding(drc_core *drc)
593{
594   emit_ldmxcsr_m32(DRCTOP, MABS(&drc->mxcsr_curr));                        // ldmxcsr [mxcsr_curr]
595}
596
597
598
599/*------------------------------------------------------------------
600    drc_dasm
601
602    An attempt to make a disassembler for DRC code; currently limited
603    by the functionality of DasmI386
604------------------------------------------------------------------*/
605
606void drc_dasm(FILE *f, const void *begin, const void *end)
607{
608   extern int i386_dasm_one(char *buffer, UINT32 eip, UINT8 *oprom, int mode);
609
610   char buffer[256];
611   const UINT8 *begin_ptr = (const UINT8 *) begin;
612   const UINT8 *end_ptr = (const UINT8 *) end;
613   UINT32 pc = (UINT32) begin;
614   int length;
615
616   while(begin_ptr < end_ptr)
617   {
618#if defined(ENABLE_DEBUGGER) && HAS_I386
619      length = i386_dasm_one(buffer, pc, (UINT8 *) begin_ptr, 32) & DASMFLAG_LENGTHMASK;
620#else
621      sprintf(buffer, "%02X", *begin_ptr);
622      length = 1;
623#endif
624
625      fprintf(f, "%08X:\t%s\n", (unsigned) pc, buffer);
626      begin_ptr += length;
627      pc += length;
628   }
629}
630
631
632
633
634/***************************************************************************
635    INTERNAL CODEGEN
636***************************************************************************/
637
638/*------------------------------------------------------------------
639    append_entry_point
640------------------------------------------------------------------*/
641
642static void append_entry_point(drc_core *drc)
643{
644   emit_pushad(DRCTOP);                                          // pushad
645   if (drc->uses_fp)
646   {
647      emit_fstcw_m16(DRCTOP, MABS(&drc->fpcw_save));                        // fstcw [fpcw_save]
648      emit_fldcw_m16(DRCTOP, MABS(&drc->fpcw_curr));                        // fldcw [fpcw_curr]
649   }
650   if (drc->uses_sse)
651   {
652      emit_stmxcsr_m32(DRCTOP, MABS(&drc->mxcsr_save));                     // stmxcsr [mxcsr_save]
653      emit_ldmxcsr_m32(DRCTOP, MABS(&drc->mxcsr_curr));                     // ldmxcsr [mxcsr_curr]
654   }
655   drc_append_restore_volatiles(drc);                                 // load volatiles
656   if (drc->cb_entrygen)
657      (*drc->cb_entrygen)(drc);                                    // additional entry point duties
658   drc_append_dispatcher(drc);                                       // dispatch
659}
660
661
662/*------------------------------------------------------------------
663    recompile_code
664------------------------------------------------------------------*/
665
666static void recompile_code(drc_core *drc)
667{
668   if (drc->cache_top >= drc->cache_danger)
669      drc_cache_reset(drc);
670   (*drc->cb_recompile)(drc);
671}
672
673
674/*------------------------------------------------------------------
675    append_recompile
676------------------------------------------------------------------*/
677
678static void append_recompile(drc_core *drc)
679{
680   emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                              // align stack
681   emit_push_imm(DRCTOP, (FPTR)drc);                                       // push drc
682   drc_append_save_call_restore(drc, (x86code *)recompile_code, 12);         // call recompile_code
683   drc_append_dispatcher(drc);                                       // dispatch
684}
685
686
687/*------------------------------------------------------------------
688    append_flush
689------------------------------------------------------------------*/
690
691static void append_flush(drc_core *drc)
692{
693   emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                              // align stack
694   emit_push_imm(DRCTOP, (FPTR)drc);                                       // push drc
695   drc_append_save_call_restore(drc, (x86code *)drc_cache_reset, 12);         // call drc_cache_reset
696   drc_append_dispatcher(drc);                                       // dispatch
697}
698
699
700/*------------------------------------------------------------------
701    append_out_of_cycles
702------------------------------------------------------------------*/
703
704static void append_out_of_cycles(drc_core *drc)
705{
706   drc_append_save_volatiles(drc);                                    // save volatiles
707   if (drc->uses_fp)
708   {
709      emit_fclex(DRCTOP);                                          // fnclex
710      emit_fldcw_m16(DRCTOP, MABS(&drc->fpcw_save));                        // fldcw [fpcw_save]
711   }
712   if (drc->uses_sse)
713      emit_ldmxcsr_m32(DRCTOP, MABS(&drc->mxcsr_save));                     // ldmxcsr [mxcsr_save]
714   emit_popad(DRCTOP);                                             // popad
715   emit_ret(DRCTOP);                                             // ret
716}
717
718
719
720/*------------------------------------------------------------------
721    drc_x86_get_features()
722------------------------------------------------------------------*/
723UINT32 drc_x86_get_features(void)
724{
725   UINT32 features = 0;
726#ifdef _MSC_VER
727   __asm
728   {
729      mov eax, 1
730      xor ebx, ebx
731      xor ecx, ecx
732      xor edx, edx
733      __asm _emit 0Fh __asm _emit 0A2h   // cpuid
734      mov features, edx
735   }
736#else /* !_MSC_VER */
737   __asm__
738   (
739      "pushl %%ebx         ; "
740      "movl $1,%%eax       ; "
741      "xorl %%ebx,%%ebx    ; "
742      "xorl %%ecx,%%ecx    ; "
743      "xorl %%edx,%%edx    ; "
744      "cpuid               ; "
745      "movl %%edx,%0       ; "
746      "popl %%ebx          ; "
747   : "=&a" (features)      /* result has to go in eax */
748   :             /* no inputs */
749   : "%ecx", "%edx"   /* clobbers ebx, ecx and edx */
750   );
751#endif /* MSC_VER */
752   return features;
753}
754
755
756
757/*------------------------------------------------------------------
758    log_dispatch
759------------------------------------------------------------------*/
760
761#if LOG_DISPATCHES
762static void log_dispatch(drc_core *drc)
763{
764   if (input_code_pressed(KEYCODE_D))
765      logerror("Disp:%08X\n", *drc->pcptr);
766}
767#endif
src/emu/cpu/x86drc.h
r2821r2822
1/***************************************************************************
2
3    x86drc.h
4
5    x86 Dynamic recompiler support routines.
6
7    Copyright Nicola Salmoria and the MAME Team.
8    Visit http://mamedev.org for licensing and usage restrictions.
9
10***************************************************************************/
11
12#pragma once
13
14#ifndef __X86DRC_H__
15#define __X86DRC_H__
16
17#include "cpuintrf.h"
18#include "x86emit.h"
19
20
21/***************************************************************************
22    TYPE DEFINITIONS
23***************************************************************************/
24
25/* PC and pointer pair */
26typedef struct _pc_ptr_pair pc_ptr_pair;
27struct _pc_ptr_pair
28{
29   UINT32      pc;
30   x86code *   target;
31};
32
33
34/* core interface structure for the drc common code */
35typedef struct _drc_core drc_core;
36struct _drc_core
37{
38   UINT8 *      cache_base;            /* base pointer to the compiler cache */
39   UINT8 *      cache_top;            /* current top of cache */
40   UINT8 *      cache_danger;         /* high water mark for the end */
41   UINT8 *      cache_end;            /* end of cache memory */
42   size_t      cache_size;            /* cache allocated size */
43   UINT8      cache_allocated;      /* did the DRC core allocate the cache? */
44
45   x86code ***   lookup_l1;            /* level 1 lookup */
46   x86code **   lookup_l2_recompile;   /* level 2 lookup populated with recompile pointers */
47   UINT8      l1bits;               /* number of bits in level 1 lookup */
48   UINT8      l2bits;               /* number of bits in level 2 lookup */
49   UINT8      l1shift;            /* shift to go from PC to level 1 lookup */
50   UINT32      l2mask;               /* mask to go from PC to level 2 lookup */
51   UINT8      l2scale;            /* scale to get from masked PC value to final level 2 lookup */
52
53   void       (*entry_point)(void);   /* pointer to asm entry point */
54   x86code *   out_of_cycles;         /* pointer to out of cycles jump point */
55   x86code *   recompile;            /* pointer to recompile jump point */
56   x86code *   dispatch;            /* pointer to dispatch jump point */
57   x86code *   flush;               /* pointer to flush jump point */
58
59   UINT32 *   pcptr;               /* pointer to where the PC is stored */
60   UINT32 *   icountptr;            /* pointer to where the icount is stored */
61   UINT32 *   esiptr;               /* pointer to where the volatile data in ESI is stored */
62   UINT8      pc_in_memory;         /* true if the PC is stored in memory */
63   UINT8      icount_in_memory;      /* true if the icount is stored in memory */
64
65   UINT8      uses_fp;            /* true if we need the FP unit */
66   UINT8      uses_sse;            /* true if we need the SSE unit */
67   UINT16      fpcw_curr;            /* current FPU control word */
68   UINT32      mxcsr_curr;            /* current SSE control word */
69   UINT16      fpcw_save;            /* saved FPU control word */
70   UINT32      mxcsr_save;            /* saved SSE control word */
71
72   pc_ptr_pair *sequence_list;         /* PC/pointer sets for the current instruction sequence */
73   UINT32      sequence_count;         /* number of instructions in the current sequence */
74   UINT32      sequence_count_max;      /* max number of instructions in the current sequence */
75   pc_ptr_pair *tentative_list;      /* PC/pointer sets for tentative branches */
76   UINT32      tentative_count;      /* number of tentative branches */
77   UINT32      tentative_count_max;   /* max number of tentative branches */
78
79   void       (*cb_reset)(struct _drc_core *drc);      /* callback when the cache is reset */
80   void       (*cb_recompile)(struct _drc_core *drc);   /* callback when code needs to be recompiled */
81   void       (*cb_entrygen)(struct _drc_core *drc);   /* callback before generating the dispatcher on entry */
82};
83
84
85/* configuration structure for the drc common code */
86typedef struct _drc_config drc_config;
87struct _drc_config
88{
89   UINT8 *      cache_base;            /* base pointer to the compiler cache */
90   UINT32      cache_size;            /* size of cache to allocate */
91   UINT32      max_instructions;      /* maximum instructions per sequence */
92   UINT8      address_bits;         /* number of live address bits in the PC */
93   UINT8      lsbs_to_ignore;         /* number of LSBs to ignore on the PC */
94   UINT8      uses_fp;            /* true if we need the FP unit */
95   UINT8      uses_sse;            /* true if we need the SSE unit */
96   UINT8      pc_in_memory;         /* true if the PC is stored in memory */
97   UINT8      icount_in_memory;      /* true if the icount is stored in memory */
98
99   UINT32 *   pcptr;               /* pointer to where the PC is stored */
100   UINT32 *   icountptr;            /* pointer to where the icount is stored */
101   UINT32 *   esiptr;               /* pointer to where the volatile data in ESI is stored */
102
103   void       (*cb_reset)(drc_core *drc);      /* callback when the cache is reset */
104   void       (*cb_recompile)(drc_core *drc);   /* callback when code needs to be recompiled */
105   void       (*cb_entrygen)(drc_core *drc);   /* callback before generating the dispatcher on entry */
106};
107
108
109/* structure to hold link data to be filled in later */
110typedef struct _link_info link_info;
111struct _link_info
112{
113   UINT8       size;
114   UINT8 *      target;
115};
116
117
118
119/***************************************************************************
120    MACROS
121***************************************************************************/
122
123/* use this macro in emit_* instructions to make them shorter */
124#define DRCTOP               &drc->cache_top
125
126
127
128/***************************************************************************
129    HELPER MACROS
130***************************************************************************/
131
132/* useful macros for accessing hi/lo portions of 64-bit values */
133#define LO(x)      (&(((UINT32 *)(UINT32)(x))[0]))
134#define HI(x)      (&(((UINT32 *)(UINT32)(x))[1]))
135
136
137
138/***************************************************************************
139    CONSTANTS
140***************************************************************************/
141
142/* features */
143#define CPUID_FEATURES_MMX      (1 << 23)
144#define CPUID_FEATURES_SSE      (1 << 26)
145#define CPUID_FEATURES_SSE2      (1 << 25)
146#define CPUID_FEATURES_CMOV      (1 << 15)
147#define CPUID_FEATURES_TSC      (1 << 4)
148
149
150
151/***************************************************************************
152    FUNCTION PROTOTYPES
153***************************************************************************/
154
155/* init/shutdown */
156drc_core *drc_init(UINT8 cpunum, drc_config *config);
157void *drc_alloc(drc_core *drc, size_t amount);
158void drc_cache_reset(drc_core *drc);
159void drc_execute(drc_core *drc);
160void drc_exit(drc_core *drc);
161
162/* code management */
163void drc_begin_sequence(drc_core *drc, UINT32 pc);
164void drc_end_sequence(drc_core *drc);
165void drc_register_code_at_cache_top(drc_core *drc, UINT32 pc);
166void *drc_get_code_at_pc(drc_core *drc, UINT32 pc);
167
168/* standard appendages */
169void drc_append_dispatcher(drc_core *drc);
170void drc_append_fixed_dispatcher(drc_core *drc, UINT32 newpc);
171void drc_append_tentative_fixed_dispatcher(drc_core *drc, UINT32 newpc);
172void drc_append_call_debugger(drc_core *drc);
173void drc_append_standard_epilogue(drc_core *drc, INT32 cycles, INT32 pcdelta, int allow_exit);
174void drc_append_save_volatiles(drc_core *drc);
175void drc_append_restore_volatiles(drc_core *drc);
176void drc_append_save_call_restore(drc_core *drc, x86code *target, UINT32 stackadj);
177void drc_append_verify_code(drc_core *drc, void *code, UINT8 length);
178
179void drc_append_set_fp_rounding(drc_core *drc, UINT8 regindex);
180void drc_append_set_temp_fp_rounding(drc_core *drc, UINT8 rounding);
181void drc_append_restore_fp_rounding(drc_core *drc);
182
183void drc_append_set_sse_rounding(drc_core *drc, UINT8 regindex);
184void drc_append_set_temp_sse_rounding(drc_core *drc, UINT8 rounding);
185void drc_append_restore_sse_rounding(drc_core *drc);
186
187/* disassembling drc code */
188void drc_dasm(FILE *f, const void *begin, const void *end);
189
190/* x86 CPU features */
191UINT32 drc_x86_get_features(void);
192
193
194#endif   /* __X86DRC_H__ */
src/emu/cpu/x64drc.c
r2821r2822
1/***************************************************************************
2
3    x64drc.c
4
5    x64 Dynamic recompiler support routines.
6
7    Copyright Nicola Salmoria and the MAME Team.
8    Visit http://mamedev.org for licensing and usage restrictions.
9
10****************************************************************************
11
12    Windows x64 conventions:
13
14        Register        Status          Use
15        --------        ------          ---
16        RAX             Volatile        Return value register
17        RCX             Volatile        First integer argument
18        RDX             Volatile        Second integer argument
19        R8              Volatile        Third integer argument
20        R9              Volatile        Fourth integer argument
21        R10:R11         Volatile        Must be preserved as needed by caller; used in syscall/sysret instructions
22        R12:R15         Nonvolatile     Must be preserved by callee
23        RDI             Nonvolatile     Must be preserved by callee
24        RSI             Nonvolatile     Must be preserved by callee
25        RBX             Nonvolatile     Must be preserved by callee
26        RBP             Nonvolatile     May be used as a frame pointer; must be preserved by callee
27        RSP             Nonvolatile     Stack pointer
28
29        XMM0            Volatile        First FP argument
30        XMM1            Volatile        Second FP argument
31        XMM2            Volatile        Third FP argument
32        XMM3            Volatile        Fourth FP argument
33        XMM4:XMM5       Volatile        Must be preserved as needed by caller
34        XMM6:XMM15      Nonvolatile     Must be preserved as needed by callee.
35
36
37    Linux/MacOS x64 conventions:
38
39        Register        Status          Use
40        --------        ------          ---
41        RAX             Volatile        Return value register
42        RDI             Volatile        First integer argument
43        RSI             Volatile        Second integer argument
44        RDX             Volatile        Third integer argument
45        RCX             Volatile        Fourth integer argument
46        R8              Volatile        Fifth integer argument
47        R9              Volatile        Sixth integer argument
48        R10:R11         Volatile        Must be preserved as needed by caller
49        R12:R15         Nonvolatile     Must be preserved by callee
50        RBX             Nonvolatile     Must be preserved by callee
51        RBP             Nonvolatile     Must be preserved by callee
52        RSP             Nonvolatile     Stack pointer
53
54        XMM0            Volatile        First FP argument
55        XMM1            Volatile        Second FP argument
56        XMM2            Volatile        Third FP argument
57        XMM3            Volatile        Fourth FP argument
58        XMM4            Volatile        Fifth FP argument
59        XMM5            Volatile        Sixth FP argument
60        XMM6:XMM15      Volatile        Must be preserved as needed by caller.
61
62***************************************************************************/
63
64#include "cpuintrf.h"
65#include "x64drc.h"
66#include "debugger.h"
67
68#ifdef ENABLE_DEBUGGER
69#include "deprecat.h"
70#endif
71
72
73
74/***************************************************************************
75    MACROS
76***************************************************************************/
77
78#define MXCSR_VALUE(x)      (0x1fc0 | ((x) << 14))
79
80
81
82/***************************************************************************
83    FUNCTION PROTOTYPES
84***************************************************************************/
85
86static void append_entry_point(drc_core *drc);
87static void append_exit_point(drc_core *drc);
88static void recompile_code(drc_core *drc);
89static void append_recompile(drc_core *drc);
90static void append_flush(drc_core *drc);
91
92
93
94/***************************************************************************
95    INLINE FUNCTIONS
96***************************************************************************/
97
98/*-------------------------------------------------
99    allocate_l2_table - allocate an L2 table
100    if necessary
101-------------------------------------------------*/
102
103INLINE void allocate_l2_table(drc_core *drc, UINT32 l1index)
104{
105   if (drc->lookup_l1[l1index] == drc->lookup_l2_recompile)
106   {
107      /* create a new copy of the recompile table */
108      drc->lookup_l1[l1index] = drc_alloc(drc, sizeof(*drc->lookup_l2_recompile) << drc->l2bits);
109      memcpy(drc->lookup_l1[l1index], drc->lookup_l2_recompile, sizeof(*drc->lookup_l2_recompile) << drc->l2bits);
110   }
111}
112
113
114/***************************************************************************
115    EXTERNAL INTERFACES
116***************************************************************************/
117
118/*-------------------------------------------------
119    drc_init - initialize the DRC core
120-------------------------------------------------*/
121
122drc_core *drc_init(UINT8 cpunum, drc_config *config)
123{
124   int address_bits = config->address_bits;
125   int effective_address_bits = address_bits - config->lsbs_to_ignore;
126   drc_core *drc;
127   int i;
128
129   /* the drc structure lives at the start of the cache */
130   drc = (drc_core *)config->cache_base;
131   memset(drc, 0, sizeof(*drc));
132
133   /* copy in relevant data from the config */
134   drc->baseptr      = config->baseptr;
135   drc->pcptr        = config->pcptr;
136   drc->cb_reset     = config->cb_reset;
137   drc->cb_recompile = config->cb_recompile;
138   drc->cb_entrygen  = config->cb_entrygen;
139   drc->mxcsr_curr   = MXCSR_VALUE(FPRND_NEAR);
140
141   /* configure cache */
142   drc->cache_base = (UINT8 *)config->cache_base + sizeof(*drc);
143   drc->cache_size = config->cache_size - sizeof(*drc);
144   drc->cache_end = drc->cache_base + drc->cache_size;
145   drc->cache_danger = drc->cache_end - 65536;
146
147   /* compute shifts and masks */
148   drc->l1bits = effective_address_bits / 2;
149   drc->l2bits = effective_address_bits - drc->l1bits;
150   drc->l1shift = config->lsbs_to_ignore + drc->l2bits;
151   drc->l2mask = ((1 << drc->l2bits) - 1) << config->lsbs_to_ignore;
152   drc->l2scale = sizeof(x86code *) >> config->lsbs_to_ignore;
153
154   /* configure the MXCSR states */
155   for (i = 0; i < 4; i++)
156      drc->mxcsr_values[i] = MXCSR_VALUE(i);
157
158   /* allocate lookup tables out of the cache */
159   drc->lookup_l1 = drc_alloc(drc, sizeof(*drc->lookup_l1) << drc->l1bits);
160   drc->lookup_l2_recompile = drc_alloc(drc, sizeof(*drc->lookup_l2_recompile) << drc->l2bits);
161   if (drc->lookup_l1 == NULL || drc->lookup_l2_recompile == NULL)
162      goto error;
163   memset(drc->lookup_l1, 0, sizeof(*drc->lookup_l1) << drc->l1bits);
164   memset(drc->lookup_l2_recompile, 0, sizeof(*drc->lookup_l2_recompile) << drc->l2bits);
165
166   /* allocate the sequence and tentative lists */
167   drc->sequence_count_max = config->max_instructions * 2;
168   drc->sequence_list = malloc(drc->sequence_count_max * sizeof(*drc->sequence_list));
169   if (drc->sequence_list == NULL)
170      goto error;
171
172   drc->tentative_count_max = config->max_instructions * 2;
173   drc->tentative_list = malloc(drc->tentative_count_max * sizeof(*drc->tentative_list));
174   if (drc->tentative_list == NULL)
175      goto error;
176
177   /* get pointers to external C functions */
178#ifdef ENABLE_DEBUGGER
179   drc->mame_debug_hook = (x86code *)mame_debug_hook;
180#endif
181   drc->recompile_code = (x86code *)recompile_code;
182   drc->drc_cache_reset = (x86code *)drc_cache_reset;
183   return drc;
184
185error:
186   if (drc != NULL)
187      drc_exit(drc);
188   return NULL;
189}
190
191
192/*-------------------------------------------------
193    drc_alloc - allocate memory from the top of
194    the DRC cache
195-------------------------------------------------*/
196
197void *drc_alloc(drc_core *drc, size_t amount)
198{
199   /* if we don't have enough space, reset the cache */
200   if (drc->cache_top >= drc->cache_danger - amount)
201      drc_cache_reset(drc);
202
203   /* if we still don't have enough space, fail */
204   if (drc->cache_top >= drc->cache_danger - amount)
205      return NULL;
206
207   /* adjust the end and danger values downward */
208   drc->cache_end -= amount;
209   drc->cache_danger -= amount;
210   return drc->cache_end;
211}
212
213
214/*-------------------------------------------------
215    drc_cache_reset - reset the DRC cache
216-------------------------------------------------*/
217
218void drc_cache_reset(drc_core *drc)
219{
220   int i;
221
222   /* reset the cache and add the basics */
223   drc->cache_top = drc->cache_base;
224
225   /* append the core entry points to the fresh cache */
226   drc->entry_point = (void (*)(void *))(FPTR)drc->cache_top;
227   append_entry_point(drc);
228   drc->exit_point = drc->cache_top;
229   append_exit_point(drc);
230   drc->recompile = drc->cache_top;
231   append_recompile(drc);
232   drc->dispatch = drc->cache_top;
233   drc_append_dispatcher(drc);
234   drc->flush = drc->cache_top;
235   append_flush(drc);
236
237   /* populate the recompile table */
238   for (i = 0; i < (1 << drc->l2bits); i++)
239      drc->lookup_l2_recompile[i] = drc->recompile;
240
241   /* reset all the l1 tables */
242   for (i = 0; i < (1 << drc->l1bits); i++)
243   {
244      /* point NULL entries to the generic recompile table */
245      if (drc->lookup_l1[i] == NULL)
246         drc->lookup_l1[i] = drc->lookup_l2_recompile;
247
248      /* reset allocated tables to point all entries back to the recompiler */
249      else if (drc->lookup_l1[i] != drc->lookup_l2_recompile)
250         memcpy(drc->lookup_l1[i], drc->lookup_l2_recompile, sizeof(*drc->lookup_l2_recompile) << drc->l2bits);
251   }
252
253   /* call back to the host */
254   if (drc->cb_reset != NULL)
255      (*drc->cb_reset)(drc);
256}
257
258
259/*-------------------------------------------------
260    drc_execute - execute generated code
261-------------------------------------------------*/
262
263void drc_execute(drc_core *drc)
264{
265   (*drc->entry_point)(drc->baseptr);
266}
267
268
269/*-------------------------------------------------
270    drc_exit - release resources allocated by
271    the DRC core
272-------------------------------------------------*/
273
274void drc_exit(drc_core *drc)
275{
276   /* free the lists */
277   if (drc->sequence_list != NULL)
278      free(drc->sequence_list);
279   if (drc->tentative_list != NULL)
280      free(drc->tentative_list);
281}
282
283
284/*-------------------------------------------------
285    drc_begin_sequence - begin code generation
286    for a particular PC
287-------------------------------------------------*/
288
289void drc_begin_sequence(drc_core *drc, UINT32 pc)
290{
291   /* reset the sequence and tentative counts */
292   drc->sequence_count = 0;
293   drc->tentative_count = 0;
294}
295
296
297/*-------------------------------------------------
298    drc_add_entry_point - add a new external
299    entry point for a given PC
300-------------------------------------------------*/
301
302int drc_add_entry_point(drc_core *drc, UINT32 pc, int override)
303{
304   UINT32 l1index = pc >> drc->l1shift;
305   UINT32 l2index = ((pc & drc->l2mask) * drc->l2scale) / sizeof(x86code *);
306   int was_occupied;
307
308   /* allocate memory if necessary */
309   allocate_l2_table(drc, l1index);
310
311   /* in case anybody was jumping directly to this code entry, replace
312       the code with a jmp to the new code */
313    was_occupied = (drc->lookup_l1[l1index][l2index] != drc->recompile);
314   if (was_occupied && override)
315   {
316      x86code *dest = drc->lookup_l1[l1index][l2index];
317      emit_jmp(&dest, drc->cache_top);
318   }
319
320   /* note the current location for this instruction */
321   if (!was_occupied || override)
322      drc->lookup_l1[l1index][l2index] = drc->cache_top;
323   return was_occupied;
324}
325
326
327/*------------------------------------------------------------------
328    drc_end_sequence
329------------------------------------------------------------------*/
330
331void drc_end_sequence(drc_core *drc)
332{
333   int i, j;
334
335   /* fix up any internal links */
336   for (i = 0; i < drc->tentative_count; i++)
337   {
338      for (j = 0; j < drc->sequence_count; j++)
339         if (drc->tentative_list[i].pc == drc->sequence_list[j].pc)
340         {
341            x86code *dest = drc->tentative_list[i].target;
342            emit_jmp(&dest, drc->sequence_list[j].target);
343            while (dest < drc->tentative_list[i].end)
344               emit_int_3(&dest);
345            break;
346         }
347   }
348}
349
350
351/*------------------------------------------------------------------
352    drc_register_code_at_cache_top
353------------------------------------------------------------------*/
354
355void drc_register_code_at_cache_top(drc_core *drc, UINT32 pc)
356{
357   pc_ptr_pair *pair = &drc->sequence_list[drc->sequence_count++];
358   assert_always(drc->sequence_count <= drc->sequence_count_max, "drc_register_code_at_cache_top: too many instructions!");
359
360   pair->target = drc->cache_top;
361   pair->pc = pc;
362}
363
364
365/*------------------------------------------------------------------
366    drc_get_code_at_pc
367------------------------------------------------------------------*/
368
369x86code *drc_get_code_at_pc(drc_core *drc, UINT32 pc)
370{
371   UINT32 l1index = pc >> drc->l1shift;
372   UINT32 l2index = ((pc & drc->l2mask) * drc->l2scale) / sizeof(x86code *);
373   x86code *codeptr = drc->lookup_l1[l1index][l2index];
374   return (codeptr != drc->recompile) ? codeptr : NULL;
375}
376
377
378/*------------------------------------------------------------------
379    drc_invalidate_code_range
380------------------------------------------------------------------*/
381
382void drc_invalidate_code_range(drc_core *drc, UINT32 startpc, UINT32 endpc)
383{
384   UINT32 startl1index = startpc >> drc->l1shift;
385   UINT32 startl2index = ((startpc & drc->l2mask) * drc->l2scale) / sizeof(x86code *);
386   UINT32 endl1index = endpc >> drc->l1shift;
387   UINT32 endl2index = ((endpc & drc->l2mask) * drc->l2scale) / sizeof(x86code *);
388   UINT32 curl1;
389
390   /* iterate over l1 bunches */
391   for (curl1 = startl1index; curl1 <= endl1index; curl1++)
392   {
393      x86code **l2table = drc->lookup_l1[curl1];
394      UINT32 l2start, l2end, curl2;
395
396      /* if this is already empty, skip it */
397      if (l2table == drc->lookup_l2_recompile)
398         continue;
399
400      /* determine start/stop for this range */
401      l2start = (curl1 == startl1index) ? startl2index : 0;
402      l2end = (curl1 == endl1index) ? endl2index : ((1 << drc->l2bits) - 1);
403
404      /* invalidate any code entries here */
405      for (curl2 = l2start; curl2 <= l2end; curl2++)
406         if (l2table[curl2] != drc->recompile)
407         {
408            /* overwrite code there with a jump to the recompiler in case we ever get there */
409            x86code *dest = l2table[curl2];
410//              emit_int_3(&dest);
411            emit_jmp(&dest, drc->recompile);
412            l2table[curl2] = drc->recompile;
413         }
414   }
415}
416
417
418/*------------------------------------------------------------------
419    drc_append_call_debugger
420------------------------------------------------------------------*/
421
422void drc_append_call_debugger(drc_core *drc)
423{
424#ifdef ENABLE_DEBUGGER
425   if (Machine->debug_mode)
426      emit_call_m64(DRCTOP, MDRC(&drc->mame_debug_hook));                     // call mame_debug_hook
427#endif
428}
429
430
431/*------------------------------------------------------------------
432    drc_append_dispatcher
433------------------------------------------------------------------*/
434
435void drc_append_dispatcher(drc_core *drc)
436{
437   /* target PC is in P1 on entry; we must keep P1 intact in case we jump to the recompile callback */
438   emit_mov_r32_r32(DRCTOP, REG_P2, REG_P1);                              // mov  p2,p1
439   emit_mov_r32_r32(DRCTOP, REG_EAX, REG_P1);                              // mov  eax,p1
440   emit_shr_r32_imm(DRCTOP, REG_P2, drc->l1shift);                           // shr  p2,l1shift
441   emit_mov_r64_m64(DRCTOP, REG_P2, MDRCISD(drc->lookup_l1, REG_P2, 8, 0));      // mov  p2,[rbp+p2*8+l1lookup]
442   emit_and_r32_imm(DRCTOP, REG_EAX, drc->l2mask);                           // and  eax,l2mask
443   emit_jmp_m64(DRCTOP, MBISD(REG_P2, REG_EAX, drc->l2scale, 0));               // jmp  [p2 + eax*l2scale]
444}
445
446
447/*------------------------------------------------------------------
448    drc_append_fixed_dispatcher
449------------------------------------------------------------------*/
450
451void drc_append_fixed_dispatcher(drc_core *drc, UINT32 pc, int loadpc)
452{
453   UINT32 l1index = pc >> drc->l1shift;
454   UINT32 l2index = ((pc & drc->l2mask) * drc->l2scale) / sizeof(x86code *);
455
456   /* make sure we have an L2 table for this entry */
457   allocate_l2_table(drc, l1index);
458
459   /* emit a jump through the table entry */
460   if (loadpc)
461      emit_mov_r32_imm(DRCTOP, REG_P1, pc);                              // mov  p1,pc
462   emit_jmp_m64(DRCTOP, MDRC(&drc->lookup_l1[l1index][l2index]));               // jmp  [lookup[l1index][l2index]]
463}
464
465
466/*------------------------------------------------------------------
467    drc_append_tentative_fixed_dispatcher
468------------------------------------------------------------------*/
469
470void drc_append_tentative_fixed_dispatcher(drc_core *drc, UINT32 newpc, int loadpc)
471{
472   pc_ptr_pair *pair = &drc->tentative_list[drc->tentative_count++];
473   assert_always(drc->tentative_count <= drc->tentative_count_max, "drc_append_tentative_fixed_dispatcher: too many tentative branches!");
474
475   pair->target = drc->cache_top;
476   pair->pc = newpc;
477   drc_append_fixed_dispatcher(drc, newpc, loadpc);
478   pair->end = drc->cache_top;
479}
480
481
482/*------------------------------------------------------------------
483    drc_append_set_sse_rounding
484------------------------------------------------------------------*/
485
486void drc_append_set_sse_rounding(drc_core *drc, UINT8 regindex)
487{
488   emit_ldmxcsr_m32(DRCTOP, MDRCISD(&drc->mxcsr_values[0], regindex, 4, 0));      // ldmxcsr [mxcsr_values + reg*4]
489   emit_stmxcsr_m32(DRCTOP, MDRC(&drc->mxcsr_curr));                        // stmxcsr [mxcsr_curr]
490}
491
492
493
494/*------------------------------------------------------------------
495    drc_append_set_temp_sse_rounding
496------------------------------------------------------------------*/
497
498void drc_append_set_temp_sse_rounding(drc_core *drc, UINT8 rounding)
499{
500   emit_ldmxcsr_m32(DRCTOP, MDRC(&drc->mxcsr_values[rounding]));               // ldmxcsr mxcsr_values[rounding]
501}
502
503
504
505/*------------------------------------------------------------------
506    drc_append_restore_sse_rounding
507------------------------------------------------------------------*/
508
509void drc_append_restore_sse_rounding(drc_core *drc)
510{
511   emit_ldmxcsr_m32(DRCTOP, MDRC(&drc->mxcsr_curr));                        // ldmxcsr [mxcsr_curr]
512}
513
514
515
516/***************************************************************************
517    INTERNAL CODEGEN
518***************************************************************************/
519
520/*------------------------------------------------------------------
521    append_entry_point
522------------------------------------------------------------------*/
523
524static void append_entry_point(drc_core *drc)
525{
526   int pushbytes = 8 * (6 + (REG_NV5 != REG_NONE) + (REG_NV6 != REG_NONE));
527
528   /* save non-volatile registers */
529   emit_push_r64(DRCTOP, REG_DRC);                                       // push drc
530   emit_push_r64(DRCTOP, REG_NV0);                                       // push nv0
531   emit_push_r64(DRCTOP, REG_NV1);                                     // push nv1
532   emit_push_r64(DRCTOP, REG_NV2);                                       // push nv2
533   emit_push_r64(DRCTOP, REG_NV3);                                       // push nv3
534   emit_push_r64(DRCTOP, REG_NV4);                                       // push nv4
535   if (REG_NV5 != REG_NONE) emit_push_r64(DRCTOP, REG_NV5);                  // push nv5
536   if (REG_NV6 != REG_NONE) emit_push_r64(DRCTOP, REG_NV6);                  // push nv6
537
538   /* stack frame:
539        0x40/0x48 bytes of scratch space/alignment
540        0x20 bytes for register parameter spilling in Windows ABI
541    */
542   emit_sub_r64_imm(DRCTOP, REG_RSP, 0x68 + (pushbytes % 16));                  // sub  rsp,0x68/0x70
543
544   /* parameter 1 is the baseptr; copy to RBP */
545   emit_mov_r64_r64(DRCTOP, REG_DRC, REG_P1);                              // mov  rbp,p1
546
547   /* update the MXCSR register */
548   emit_stmxcsr_m32(DRCTOP, MDRC(&drc->mxcsr_save));                        // stmxcsr [mxcsr_save]
549   emit_ldmxcsr_m32(DRCTOP, MDRC(&drc->mxcsr_curr));                        // ldmxcsr [mxcsr_curr]
550
551   /* continue performing entry generation duties */
552   if (drc->cb_entrygen != NULL)
553      (*drc->cb_entrygen)(drc);                                       // additional entry point duties
554
555   /* reload the PC into P1 and dispatch */
556   emit_mov_r32_m32(DRCTOP, REG_P1, MDRC(drc->pcptr));                        // mov  p1,[pc]
557   drc_append_dispatcher(drc);                                          // dispatch
558}
559
560
561/*------------------------------------------------------------------
562    append_exit_point
563------------------------------------------------------------------*/
564
565static void append_exit_point(drc_core *drc)
566{
567   int pushbytes = 8 * (6 + (REG_NV5 != REG_NONE) + (REG_NV6 != REG_NONE));
568
569   /* on exit, P1 must contain the final PC */
570   emit_mov_m32_r32(DRCTOP, MDRC(drc->pcptr), REG_P1);                        // mov  [pc],p1
571
572   /* restore the MXCSR state */
573   emit_ldmxcsr_m32(DRCTOP, MDRC(&drc->mxcsr_save));                        // ldmxcsr [mxcsr_save]
574
575   /* add 0x18 to RSP to get us back to the original stack pointer */
576   emit_add_r64_imm(DRCTOP, REG_RSP, 0x68 + (pushbytes % 16));                  // add  rsp,0x68/0x70
577
578   /* save non-volatile registers */
579   if (REG_NV6 != REG_NONE) emit_pop_r64(DRCTOP, REG_NV6);                     // pop nv6
580   if (REG_NV5 != REG_NONE) emit_pop_r64(DRCTOP, REG_NV5);                     // pop nv5
581   emit_pop_r64(DRCTOP, REG_NV4);                                       // pop nv4
582   emit_pop_r64(DRCTOP, REG_NV3);                                       // pop nv3
583   emit_pop_r64(DRCTOP, REG_NV2);                                       // pop nv2
584   emit_pop_r64(DRCTOP, REG_NV1);                                       // pop nv1
585   emit_pop_r64(DRCTOP, REG_NV0);                                       // pop nv0
586   emit_pop_r64(DRCTOP, REG_DRC);                                       // pop drc
587   emit_ret(DRCTOP);                                                // ret
588}
589
590
591/*------------------------------------------------------------------
592    recompile_code
593------------------------------------------------------------------*/
594
595static void recompile_code(drc_core *drc)
596{
597   /* if we're above the danger line, flush the cache before recompiling */
598   if (drc->cache_top >= drc->cache_danger)
599      drc_cache_reset(drc);
600
601   /* call the recompile callback */
602   (*drc->cb_recompile)(drc);
603}
604
605
606/*------------------------------------------------------------------
607    append_recompile
608------------------------------------------------------------------*/
609
610static void append_recompile(drc_core *drc)
611{
612   /* on entry, P1 must contain the PC that needs recompilation */
613   emit_mov_m32_r32(DRCTOP, MDRC(drc->pcptr), REG_P1);                        // mov  [pc],p1
614   emit_lea_r64_m64(DRCTOP, REG_P1, MDRC(drc));                           // lea  p1,drc
615   emit_call_m64(DRCTOP, MDRC(&drc->recompile_code));                        // call recompile_code
616   emit_mov_r32_m32(DRCTOP, REG_P1, MDRC(drc->pcptr));                        // mov  p1,[pc]
617   drc_append_dispatcher(drc);                                          // dispatch
618}
619
620
621/*------------------------------------------------------------------
622    append_flush
623------------------------------------------------------------------*/
624
625static void append_flush(drc_core *drc)
626{
627   /* on entry, P1 must contain the PC that needs recompilation */
628   emit_mov_m32_r32(DRCTOP, MDRC(drc->pcptr), REG_P1);                        // mov  [pc],p1
629   emit_lea_r64_m64(DRCTOP, REG_P1, MDRC(drc));                           // lea  p1,drc
630   emit_call_m64(DRCTOP, MDRC(&drc->drc_cache_reset));                        // call drc_cache_reset
631   emit_mov_r32_m32(DRCTOP, REG_P1, MDRC(drc->pcptr));                        // mov  p1,[pc]
632   drc_append_dispatcher(drc);                                          // dispatch
633}
src/emu/cpu/x64drc.h
r2821r2822
1/***************************************************************************
2
3    x64drc.h
4
5    x64 Dynamic recompiler support routines.
6
7    Copyright Nicola Salmoria and the MAME Team.
8    Visit http://mamedev.org for licensing and usage restrictions.
9
10***************************************************************************/
11
12#pragma once
13
14#ifndef __X64DRC_H__
15#define __X64DRC_H__
16
17#include "cpuintrf.h"
18#include "x86emit.h"
19
20
21
22/***************************************************************************
23    CONSTANTS
24***************************************************************************/
25
26/* ABI-specific configuration */
27#define REG_DRC            REG_RBP         /* pointer to DRC base */
28
29#ifdef X64_WINDOWS_ABI
30
31#define REG_P1            REG_RCX         /* 1st function parameter */
32#define REG_P2            REG_RDX         /* 2nd function parameter */
33#define REG_P3            REG_R8         /* 3rd function parameter */
34#define REG_P4            REG_R9         /* 4th function parameter */
35#define REG_V5            REG_R10         /* volatile register 5 */
36#define REG_V6            REG_R11         /* volatile register 6 */
37
38#define NUM_NVREG         7            /* number of non-volatile registers */
39#define REG_NV0            REG_RBX         /* non-volatile reg 0 */
40#define REG_NV1            REG_RDI         /* non-volatile reg 1 */
41#define REG_NV2            REG_RSI         /* non-volatile reg 2 */
42#define REG_NV3            REG_R12         /* non-volatile reg 3 */
43#define REG_NV4            REG_R13         /* non-volatile reg 4 */
44#define REG_NV5            REG_R14         /* non-volatile reg 5 */
45#define REG_NV6            REG_R15         /* non-volatile reg 6 */
46
47#else
48
49#define REG_P1            REG_RDI         /* 1st function parameter */
50#define REG_P2            REG_RSI         /* 2nd function parameter */
51#define REG_P3            REG_RDX         /* 3rd function parameter */
52#define REG_P4            REG_RCX         /* 4th function parameter */
53#define REG_V5            REG_R10         /* volatile register 5 */
54#define REG_V6            REG_R11         /* volatile register 6 */
55
56#define NUM_NVREG         5            /* number of non-volatile registers */
57#define REG_NV0            REG_RBX         /* non-volatile reg 0 */
58#define REG_NV1            REG_R12         /* non-volatile reg 1 */
59#define REG_NV2            REG_R13         /* non-volatile reg 2 */
60#define REG_NV3            REG_R14         /* non-volatile reg 3 */
61#define REG_NV4            REG_R15         /* non-volatile reg 4 */
62#define REG_NV5            REG_NONE      /* non-volatile reg 5 */
63#define REG_NV6            REG_NONE      /* non-volatile reg 6 */
64
65#endif
66
67
68
69/***************************************************************************
70    TYPE DEFINITIONS
71***************************************************************************/
72
73/* PC and pointer pair */
74typedef struct _pc_ptr_pair pc_ptr_pair;
75struct _pc_ptr_pair
76{
77   UINT32         pc;
78   x86code *      target;
79   x86code *      end;
80};
81
82
83/* core interface structure for the drc common code */
84typedef struct _drc_core drc_core;
85struct _drc_core
86{
87   /* cache parameters */
88   x86code *      cache_base;               /* base pointer to the compiler cache */
89   x86code *      cache_top;               /* current top of cache */
90   x86code *      cache_danger;            /* high water mark for the end */
91   x86code *      cache_end;               /* end of cache memory */
92   size_t         cache_size;               /* cache allocated size */
93
94   /* hash table lookups */
95   x86code ***      lookup_l1;               /* level 1 lookup */
96   x86code **      lookup_l2_recompile;      /* level 2 lookup populated with recompile pointers */
97   UINT8         l1bits;                  /* number of bits in level 1 lookup */
98   UINT8         l2bits;                  /* number of bits in level 2 lookup */
99   UINT8         l1shift;               /* shift to go from PC to level 1 lookup */
100   UINT32         l2mask;                  /* mask to go from PC to level 2 lookup */
101   UINT8         l2scale;               /* scale to get from masked PC value to final level 2 lookup */
102
103   /* entry point for calling from C code */
104   void          (*entry_point)(void *);      /* pointer to asm entry point */
105
106   /* base pointer for memory accesses */
107   void *         baseptr;               /* pointer to base; all cache must be accessible from here */
108
109   /* internal subroutines generated in the cache */
110   x86code *      exit_point;               /* exit out of the DRC engine */
111   x86code *      recompile;               /* pointer to recompile jump point */
112   x86code *      dispatch;               /* pointer to dispatch jump point */
113   x86code *      flush;                  /* pointer to flush jump point */
114
115   /* pointers to external C code */
116   x86code *      mame_debug_hook;         /* pointer to mame_debug_hook function */
117   x86code *      recompile_code;            /* pointer to recompile_code function */
118   x86code *      drc_cache_reset;         /* pointer to drc_cache_reset function */
119
120   /* pointers to the PC */
121   UINT32 *      pcptr;                  /* pointer to where the PC is stored */
122
123   /* save areas for the MXCSR register */
124   UINT32         mxcsr_curr;               /* current SSE control word */
125   UINT32         mxcsr_save;               /* saved SSE control word */
126   UINT32         mxcsr_values[4];         /* array of values for different modes */
127
128   /* internal lists of sequences and tentative branches */
129   pc_ptr_pair *   sequence_list;            /* PC/pointer sets for the current instruction sequence */
130   UINT32         sequence_count;            /* number of instructions in the current sequence */
131   UINT32         sequence_count_max;         /* max number of instructions in the current sequence */
132   pc_ptr_pair *   tentative_list;            /* PC/pointer sets for tentative branches */
133   UINT32         tentative_count;         /* number of tentative branches */
134   UINT32         tentative_count_max;      /* max number of tentative branches */
135
136   /* CPU-specific callbacks */
137   void          (*cb_reset)(struct _drc_core *drc);      /* callback when the cache is reset */
138   void          (*cb_recompile)(struct _drc_core *drc);   /* callback when code needs to be recompiled */
139   void          (*cb_entrygen)(struct _drc_core *drc);   /* callback before generating the dispatcher on entry */
140};
141
142
143/* configuration structure for the drc common code */
144typedef struct _drc_config drc_config;
145struct _drc_config
146{
147   void *         cache_base;               /* base of cache */
148   UINT32         cache_size;               /* size of cache */
149   UINT32         max_instructions;         /* maximum instructions per sequence */
150   UINT8         address_bits;            /* number of live address bits in the PC */
151   UINT8         lsbs_to_ignore;            /* number of LSBs to ignore on the PC */
152
153   void *         baseptr;               /* pointer to base; all cache must be accessible from here */
154   UINT32 *      pcptr;                  /* pointer to where the PC is stored */
155
156   void          (*cb_reset)(drc_core *drc);      /* callback when the cache is reset */
157   void          (*cb_recompile)(drc_core *drc);   /* callback when code needs to be recompiled */
158   void          (*cb_entrygen)(drc_core *drc);   /* callback before generating the dispatcher on entry */
159};
160
161
162
163/***************************************************************************
164    MACROS
165***************************************************************************/
166
167/* use this macro in emit_* instructions to make them shorter */
168#define DRCTOP               &drc->cache_top
169
170/* memory references to DRC-relative data */
171#define MDRC(x)                     MBD(REG_DRC, drcrel32(drc->baseptr, (x)))
172#define MDRCD(x, disp)               MBD(REG_DRC, drcrel32(drc->baseptr, (x)) + (disp))
173#define MDRCISD(x, index, scale, disp)   MBISD(REG_DRC, (index), (scale), drcrel32(drc->baseptr, (x)) + (disp))
174
175
176
177/***************************************************************************
178    FUNCTION PROTOTYPES
179***************************************************************************/
180
181/* init/shutdown */
182drc_core *drc_init(UINT8 cpunum, drc_config *config);
183void *drc_alloc(drc_core *drc, size_t amount);
184void drc_cache_reset(drc_core *drc);
185void drc_execute(drc_core *drc);
186void drc_exit(drc_core *drc);
187
188/* code management */
189void drc_begin_sequence(drc_core *drc, UINT32 pc);
190int drc_add_entry_point(drc_core *drc, UINT32 pc, int override);
191void drc_end_sequence(drc_core *drc);
192void drc_register_code_at_cache_top(drc_core *drc, UINT32 pc);
193x86code *drc_get_code_at_pc(drc_core *drc, UINT32 pc);
194void drc_invalidate_code_range(drc_core *drc, UINT32 startpc, UINT32 endpc);
195
196/* standard appendages */
197void drc_append_dispatcher(drc_core *drc);
198void drc_append_fixed_dispatcher(drc_core *drc, UINT32 newpc, int loadpc);
199void drc_append_tentative_fixed_dispatcher(drc_core *drc, UINT32 newpc, int loadpc);
200void drc_append_call_debugger(drc_core *drc);
201void drc_append_set_sse_rounding(drc_core *drc, UINT8 regindex);
202void drc_append_set_temp_sse_rounding(drc_core *drc, UINT8 rounding);
203void drc_append_restore_sse_rounding(drc_core *drc);
204
205
206
207/***************************************************************************
208    INLINE FUNCTIONS
209***************************************************************************/
210
211INLINE INT32 drcrel32(void *base, void *ptr)
212{
213   INT64 delta = (UINT8 *)ptr - (UINT8 *)base;
214   assert((INT32)delta == delta);
215   return (INT32)delta;
216}
217
218INLINE void *drcrelptr(drc_core *drc, INT32 offset)
219{
220   return (UINT8 *)drc + offset;
221}
222
223#endif   /* __X64DRC_H__ */
src/emu/cpu/cpu.mak
r2821r2822
4141
4242DRCOBJ += \
4343   $(CPUOBJ)/drcbex64.o \
44   $(CPUOBJ)/x64drc.o \
45   $(CPUOBJ)/x86log.o \
44   $(CPUOBJ)/x86log.o
4645
4746DRCDEPS += \
48   $(CPUSRC)/x86emit.h \
49   $(CPUSRC)/x64drc.c \
50   $(CPUSRC)/x64drc.h \
47   $(CPUSRC)/x86emit.h
5148
5249DEFS += -DNATIVE_DRC=drcbe_x64_be_interface
5350
r2821r2822
5552
5653DRCOBJ += \
5754   $(CPUOBJ)/drcbex86.o \
58   $(CPUOBJ)/x86drc.o \
59   $(CPUOBJ)/x86log.o \
55   $(CPUOBJ)/x86log.o
6056
6157DRCDEPS += \
62   $(CPUSRC)/x86emit.h \
63   $(CPUSRC)/x86drc.c \
64   $(CPUSRC)/x86drc.h \
58   $(CPUSRC)/x86emit.h
6559
6660DEFS += -DNATIVE_DRC=drcbe_x86_be_interface
6761
r2821r2822
839833
840834ifneq ($(filter R4600 R4650 R4700 R5000 QED5271 RM7000,$(CPUS)),)
841835OBJDIRS += $(CPUOBJ)/mips
842CPUOBJS += $(CPUOBJ)/mips/mips3com.o $(CPUOBJ)/mips/mips3drc.o $(CPUOBJ)/mips/mips3fe.o $(DRCOBJ)
836CPUOBJS += $(CPUOBJ)/mips/mips3com.o $(CPUOBJ)/mips/mips3fe.o $(CPUOBJ)/mips/mips3drc.o $(DRCOBJ)
843837DBGOBJS += $(CPUOBJ)/mips/mips3dsm.o
844838endif
845839
r2821r2822
11251119# Motorola PowerPC series
11261120#-------------------------------------------------
11271121
1128CPUDEFS += -DHAS_PPC403=$(if $(filter PPC403,$(CPUS)),1,0)
1122CPUDEFS += -DHAS_PPC403GA=$(if $(filter PPC403GA,$(CPUS)),1,0)
1123CPUDEFS += -DHAS_PPC403GCX=$(if $(filter PPC403GCX,$(CPUS)),1,0)
11291124CPUDEFS += -DHAS_PPC601=$(if $(filter PPC601,$(CPUS)),1,0)
11301125CPUDEFS += -DHAS_PPC602=$(if $(filter PPC602,$(CPUS)),1,0)
11311126CPUDEFS += -DHAS_PPC603=$(if $(filter PPC603,$(CPUS)),1,0)
1127CPUDEFS += -DHAS_PPC603E=$(if $(filter PPC603E,$(CPUS)),1,0)
1128CPUDEFS += -DHAS_PPC603R=$(if $(filter PPC603R,$(CPUS)),1,0)
11321129CPUDEFS += -DHAS_PPC604=$(if $(filter PPC604,$(CPUS)),1,0)
11331130CPUDEFS += -DHAS_MPC8240=$(if $(filter MPC8240,$(CPUS)),1,0)
11341131
1135ifneq ($(filter PPC403 PPC601 PPC602 PPC603 PPC604 MPC8240,$(CPUS)),)
1132ifneq ($(filter PPC403GA PPC403GCX PPC601 PPC602 PPC603 PPC603E PPC603R PPC604 MPC8240,$(CPUS)),)
11361133OBJDIRS += $(CPUOBJ)/powerpc
1134CPUOBJS += $(CPUOBJ)/powerpc/ppccom.o $(CPUOBJ)/powerpc/ppcfe.o $(CPUOBJ)/powerpc/ppcdrc.o $(DRCOBJ)
11371135DBGOBJS += $(CPUOBJ)/powerpc/ppc_dasm.o
1138
1139ifdef X86_PPC_DRC
1140CPUOBJS += $(CPUOBJ)/powerpc/ppcdrco.o $(DRCOBJ)
1141else
1142CPUOBJS += $(CPUOBJ)/powerpc/ppc.o
11431136endif
1144endif
11451137
1146$(CPUOBJ)/powerpc/ppc.o:   $(CPUSRC)/powerpc/ppc.c \
1138$(CPUOBJ)/powerpc/ppcdrc.o:   $(CPUSRC)/powerpc/ppcdrc.c \
11471139                     $(CPUSRC)/powerpc/ppc.h \
1148                     $(CPUSRC)/powerpc/ppc_ops.c \
1149                     $(CPUSRC)/powerpc/ppc_mem.c \
1150                     $(CPUSRC)/powerpc/ppc403.c \
1151                     $(CPUSRC)/powerpc/ppc602.c \
1152                     $(CPUSRC)/powerpc/ppc603.c
1153
1154$(CPUOBJ)/powerpc/ppcdrco.o:$(CPUSRC)/powerpc/ppcdrco.c \
1155                     $(CPUSRC)/powerpc/ppc.h \
1156                     $(CPUSRC)/powerpc/drc_ops.c \
1157                     $(CPUSRC)/powerpc/drc_ops.h \
1158                     $(CPUSRC)/powerpc/ppc_ops.c \
1159                     $(CPUSRC)/powerpc/ppc_mem.c \
1160                     $(CPUSRC)/powerpc/ppc403.c \
1161                     $(CPUSRC)/powerpc/ppc602.c \
1162                     $(CPUSRC)/powerpc/ppc603.c \
1140                     $(CPUSRC)/powerpc/ppccom.h \
1141                     $(CPUSRC)/powerpc/ppcfe.h \
11631142                     $(DRCDEPS)
11641143
11651144
src/emu/cpu/drcfe.c
r2821r2822
6363   /* CPU parameters */
6464   offs_t            pageshift;               /* shift to convert address to a page index */
6565   cpu_translate_func   translate;               /* pointer to translation function */
66   offs_t            codexor;               /* XOR to reach code */
6667
6768   /* opcode descriptor arrays */
6869   opcode_desc *      desc_live_list;            /* head of list of live descriptions */
r2821r2822
149150   /* initialize the state */
150151   drcfe->pageshift = activecpu_page_shift(ADDRESS_SPACE_PROGRAM);
151152   drcfe->translate = (cpu_translate_func)activecpu_get_info_fct(CPUINFO_PTR_TRANSLATE);
153#ifdef LSB_FIRST
154   if (activecpu_endianness() == CPU_IS_BE)
155#else
156   if (activecpu_endianness() == CPU_IS_LE)
157#endif
158      drcfe->codexor = (activecpu_databus_width(ADDRESS_SPACE_PROGRAM) / 8 / activecpu_min_instruction_bytes() - 1) * activecpu_min_instruction_bytes();
152159
153160   return drcfe;
154161}
r2821r2822
225232      }
226233
227234      /* loop until we exit the block */
228      for (curpc = curstack->targetpc; curpc < maxpc && drcfe->desc_array[curpc - minpc] == NULL; curpc += drcfe->desc_array[curpc - minpc]->length)
235      for (curpc = curstack->targetpc; curpc >= minpc && curpc < maxpc && drcfe->desc_array[curpc - minpc] == NULL; curpc += drcfe->desc_array[curpc - minpc]->length)
229236      {
230237         /* allocate a new description and describe this instruction */
231238         drcfe->desc_array[curpc - minpc] = curdesc = describe_one(drcfe, curpc);
r2821r2822
297304
298305   /* get a pointer to the physical address */
299306   memory_set_opbase(desc->physpc);
300   desc->opptr.v = cpu_opptr(desc->physpc);
307   desc->opptr.v = cpu_opptr(desc->physpc ^ drcfe->codexor);
301308   assert(desc->opptr.v != NULL);
302309   if (desc->opptr.v == NULL)
303310   {
src/emu/cpu/drcuml.c
r2821r2822
1212
1313    Future improvements/changes:
1414
15    * UML optimizer:
16        - detects constant operations, converts to MOV
17        - eliminates no-ops (add i0,i0,0)
18        - determines flags automatically
19        - constant folding
20
1521    * Write a back-end validator:
1622        - checks all combinations of memory/register/immediate on all params
1723        - checks behavior of all opcodes
r2821r2822
2127    * Support for FPU exceptions
2228
2329    * New instructions?
24        - FDRNDS dst,src
25            round to single-precision
26
2730        - FCOPYI, ICOPYF
2831            copy raw between float and integer registers
2932
r2821r2822
201204   OPVALID_ENTRY_1(SETFMOD, 4,   NONE,  IANY)
202205   OPVALID_ENTRY_1(GETFMOD, 4,   NONE,  IRM)
203206   OPVALID_ENTRY_1(GETEXP,  4,   NONE,  IRM)
207   OPVALID_ENTRY_1(GETFLGS, 4,   NONE,  IRM)
204208   OPVALID_ENTRY_1(SAVE,    4,   NONE,  ANYMEM)
205209   OPVALID_ENTRY_1(RESTORE, 4,   NONE,  ANYMEM)
206210
207211   /* Integer Operations */
208   OPVALID_ENTRY_3(LOAD1U,  4|8, NONE,  IRM,   ANYMEM,IANY4)
209   OPVALID_ENTRY_3(LOAD1S,  4|8, NONE,  IRM,   ANYMEM,IANY4)
210   OPVALID_ENTRY_3(LOAD2U,  4|8, NONE,  IRM,   ANYMEM,IANY4)
211   OPVALID_ENTRY_3(LOAD2S,  4|8, NONE,  IRM,   ANYMEM,IANY4)
212   OPVALID_ENTRY_3(LOAD4U,  4|8, NONE,  IRM,   ANYMEM,IANY4)
213   OPVALID_ENTRY_3(LOAD4S,    8, NONE,  IRM,   ANYMEM,IANY4)
214   OPVALID_ENTRY_3(LOAD8U,    8, NONE,  IRM,   ANYMEM,IANY4)
215   OPVALID_ENTRY_3(STORE1,  4|8, NONE,  ANYMEM,IANY4, IANY)
216   OPVALID_ENTRY_3(STORE2,  4|8, NONE,  ANYMEM,IANY4, IANY)
217   OPVALID_ENTRY_3(STORE4,  4|8, NONE,  ANYMEM,IANY4, IANY)
218   OPVALID_ENTRY_3(STORE8,    8, NONE,  ANYMEM,IANY4, IANY)
219   OPVALID_ENTRY_3(READ1U,  4|8, NONE,  IRM,   IMV4,  IANY4)
220   OPVALID_ENTRY_3(READ1S,  4|8, NONE,  IRM,   IMV4,  IANY4)
221   OPVALID_ENTRY_3(READ2U,  4|8, NONE,  IRM,   IMV4,  IANY4)
222   OPVALID_ENTRY_3(READ2S,  4|8, NONE,  IRM,   IMV4,  IANY4)
223   OPVALID_ENTRY_4(READ2M,  4|8, NONE,  IRM,   IMV4,  IANY4, IANY)
224   OPVALID_ENTRY_3(READ4U,  4|8, NONE,  IRM,   IMV4,  IANY4)
225   OPVALID_ENTRY_3(READ4S,    8, NONE,  IRM,   IMV4,  IANY4)
226   OPVALID_ENTRY_4(READ4M,  4|8, NONE,  IRM,   IMV4,  IANY4, IANY)
227   OPVALID_ENTRY_3(READ8U,    8, NONE,  IRM,   IMV4,  IANY4)
228   OPVALID_ENTRY_4(READ8M,    8, NONE,  IRM,   IMV4,  IANY4, IANY)
229   OPVALID_ENTRY_3(WRITE1,  4|8, NONE,  IMV4,  IANY4, IANY)
230   OPVALID_ENTRY_3(WRITE2,  4|8, NONE,  IMV4,  IANY4, IANY)
231   OPVALID_ENTRY_4(WRIT2M,  4|8, NONE,  IMV4,  IANY4, IANY,  IANY)
232   OPVALID_ENTRY_3(WRITE4,  4|8, NONE,  IMV4,  IANY4, IANY)
233   OPVALID_ENTRY_4(WRIT4M,  4|8, NONE,  IMV4,  IANY4, IANY,  IANY)
234   OPVALID_ENTRY_3(WRITE8,    8, NONE,  IMV4,  IANY4, IANY)
235   OPVALID_ENTRY_4(WRIT8M,    8, NONE,  IMV4,  IANY4, IANY,  IANY)
236   OPVALID_ENTRY_3(FLAGS,   4|8, NONE,  IRM,   IMV,   MEM)
237   OPVALID_ENTRY_2(SETC,    4|8, NONE,  IANY,  IANY)
212   OPVALID_ENTRY_4(LOAD,    4|8, NONE,  IRM,   ANYMEM,IANY4, IMV)
213   OPVALID_ENTRY_4(LOADS,   4|8, NONE,  IRM,   ANYMEM,IANY4, IMV)
214   OPVALID_ENTRY_4(STORE,   4|8, NONE,  ANYMEM,IANY4, IANY,  IMV)
215   OPVALID_ENTRY_3(READ,    4|8, NONE,  IRM,   IANY4, IMV)
216   OPVALID_ENTRY_4(READM,   4|8, NONE,  IRM,   IANY4, IANY,  IMV)
217   OPVALID_ENTRY_3(WRITE,   4|8, NONE,  IANY4, IANY,  IMV)
218   OPVALID_ENTRY_4(WRITEM,  4|8, NONE,  IANY4, IANY,  IANY,  IMV)
219   OPVALID_ENTRY_2(CARRY,   4|8, NONE,  IANY,  IANY)
238220   OPVALID_ENTRY_2(MOV,     4|8, COND,  IRM,   IANY)
239   OPVALID_ENTRY_2(ZEXT1,   4|8, NONE,  IRM,   IANY4)
240   OPVALID_ENTRY_2(ZEXT2,   4|8, NONE,  IRM,   IANY4)
241   OPVALID_ENTRY_2(ZEXT4,     8, NONE,  IRM,   IANY4)
242   OPVALID_ENTRY_2(SEXT1,   4|8, NONE,  IRM,   IANY4)
243   OPVALID_ENTRY_2(SEXT2,   4|8, NONE,  IRM,   IANY4)
244   OPVALID_ENTRY_2(SEXT4,     8, NONE,  IRM,   IANY4)
245   OPVALID_ENTRY_4(XTRACT,  4|8, NONE,  IRM,   IANY,  IANY,  IANY)
246   OPVALID_ENTRY_4(INSERT,  4|8, NONE,  IRM,   IANY,  IANY,  IANY)
221   OPVALID_ENTRY_1(SET,     4|8, COND,  IRM)
222   OPVALID_ENTRY_3(SEXT,    4|8, NONE,  IRM,   IANY4, IMV)
223   OPVALID_ENTRY_4(ROLAND,  4|8, NONE,  IRM,   IANY,  IANY,  IANY)
224   OPVALID_ENTRY_4(ROLINS,  4|8, NONE,  IRM,   IANY,  IANY,  IANY)
247225   OPVALID_ENTRY_3(ADD,     4|8, SZVC,  IRM,   IANY,  IANY)
248226   OPVALID_ENTRY_3(ADDC,    4|8, SZVC,  IRM,   IANY,  IANY)
249227   OPVALID_ENTRY_3(SUB,     4|8, SZVC,  IRM,   IANY,  IANY)
r2821r2822
270248   /* Floating Point Operations */
271249   OPVALID_ENTRY_3(FLOAD,   4|8, NONE,  FRM,   ANYMEM,IANY4)
272250   OPVALID_ENTRY_3(FSTORE,  4|8, NONE,  ANYMEM,IANY4, FANY)
273   OPVALID_ENTRY_3(FREAD,   4|8, NONE,  FRM,   IMV4,  IANY4)
274   OPVALID_ENTRY_3(FWRITE,  4|8, NONE,  IMV4,  IANY4, FANY)
251   OPVALID_ENTRY_3(FREAD,   4|8, NONE,  FRM,   IANY4, IMV4)
252   OPVALID_ENTRY_3(FWRITE,  4|8, NONE,  IANY4, FANY,  IMV4)
275253   OPVALID_ENTRY_2(FMOV,    4|8, COND,  FRM,   FANY)
276   OPVALID_ENTRY_2(FTOI4,   4|8, NONE,  IRM4,  FANY)
277   OPVALID_ENTRY_2(FTOI4T,  4|8, NONE,  IRM4,  FANY)
278   OPVALID_ENTRY_2(FTOI4R,  4|8, NONE,  IRM4,  FANY)
279   OPVALID_ENTRY_2(FTOI4F,  4|8, NONE,  IRM4,  FANY)
280   OPVALID_ENTRY_2(FTOI4C,  4|8, NONE,  IRM4,  FANY)
281   OPVALID_ENTRY_2(FTOI8,   4|8, NONE,  IRM8,  FANY)
282   OPVALID_ENTRY_2(FTOI8T,  4|8, NONE,  IRM8,  FANY)
283   OPVALID_ENTRY_2(FTOI8R,  4|8, NONE,  IRM8,  FANY)
284   OPVALID_ENTRY_2(FTOI8F,  4|8, NONE,  IRM8,  FANY)
285   OPVALID_ENTRY_2(FTOI8C,  4|8, NONE,  IRM8,  FANY)
286   OPVALID_ENTRY_2(FFRFS,     8, NONE,  FRM,   FANY4)
287   OPVALID_ENTRY_2(FFRFD,   4  , NONE,  FRM,   FANY8)
288   OPVALID_ENTRY_2(FFRI4,   4|8, NONE,  FRM,   IANY4)
289   OPVALID_ENTRY_2(FFRI8,   4|8, NONE,  FRM,   IANY8)
254   OPVALID_ENTRY_4(FTOINT,  4|8, NONE,  IRM,   FANY,  IMM,  IMM)
255   OPVALID_ENTRY_3(FFRINT,  4|8, NONE,  FRM,   IANY,  IMM)
256   OPVALID_ENTRY_3(FFRFLT,  4|8, NONE,  FRM,   FANY,  IMM)
257   OPVALID_ENTRY_2(FRNDS,     8, NONE,  FRM,   FANY)
290258   OPVALID_ENTRY_3(FADD,    4|8, NONE,  FRM,   FANY,  FANY)
291259   OPVALID_ENTRY_3(FSUB,    4|8, NONE,  FRM,   FANY,  FANY)
292260   OPVALID_ENTRY_2(FCMP,    4|8, UZC,   FANY,  FANY)
src/emu/cpu/minx/minxops.h
r2821r2822
55OP(00) { regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), ( regs.BA & 0xFF ) ); }
66OP(01) { regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ); }
77OP(02) { regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rdop() ); }
8OP(03) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
9OP(04) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
10OP(05) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
11OP(06) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
12OP(07) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
8OP(03) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
9OP(04) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
10OP(05) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
11OP(06) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
12OP(07) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
1313OP(08) { regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), ( regs.BA & 0xFF ) ); }
1414OP(09) { regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ); }
1515OP(0A) { regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rdop() ); }
16OP(0B) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
17OP(0C) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
18OP(0D) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
19OP(0E) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
20OP(0F) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
16OP(0B) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
17OP(0C) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
18OP(0D) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
19OP(0E) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
20OP(0F) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
2121
2222OP(10) { regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), ( regs.BA & 0xFF ) ); }
2323OP(11) { regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ); }
2424OP(12) { regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rdop() ); }
25OP(13) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
26OP(14) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
27OP(15) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
28OP(16) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
29OP(17) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
25OP(13) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
26OP(14) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
27OP(15) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
28OP(16) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
29OP(17) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
3030OP(18) { regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), ( regs.BA & 0xFF ) ); }
3131OP(19) { regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ); }
3232OP(1A) { regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rdop() ); }
33OP(1B) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
34OP(1C) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
35OP(1D) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
36OP(1E) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
37OP(1F) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
33OP(1B) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
34OP(1C) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
35OP(1D) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
36OP(1E) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
37OP(1F) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
3838
3939OP(20) { regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), ( regs.BA & 0xFF ) ); }
4040OP(21) { regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ); }
4141OP(22) { regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rdop() ); }
42OP(23) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
43OP(24) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
44OP(25) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
45OP(26) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
46OP(27) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
42OP(23) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
43OP(24) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
44OP(25) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
45OP(26) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
46OP(27) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
4747OP(28) { regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), ( regs.BA & 0xFF ) ); }
4848OP(29) { regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ); }
4949OP(2A) { regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rdop() ); }
50OP(2B) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
51OP(2C) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
52OP(2D) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
53OP(2E) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
54OP(2F) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
50OP(2B) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
51OP(2C) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
52OP(2D) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
53OP(2E) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
54OP(2F) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
5555
5656OP(30) { SUB8( ( regs.BA & 0x00FF ), ( regs.BA & 0xFF ) ); }
5757OP(31) { SUB8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ); }
5858OP(32) { SUB8( ( regs.BA & 0x00FF ), rdop() ); }
59OP(33) { AD2_IHL; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
60OP(34) { AD2_IN8; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
61OP(35) { AD2_I16; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
62OP(36) { AD2_XIX; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
63OP(37) { AD2_YIY; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
59OP(33) { AD2_IHL; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
60OP(34) { AD2_IN8; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
61OP(35) { AD2_I16; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
62OP(36) { AD2_XIX; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
63OP(37) { AD2_YIY; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
6464OP(38) { regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), ( regs.BA & 0xFF ) ); }
6565OP(39) { regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ); }
6666OP(3A) { regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rdop() ); }
67OP(3B) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
68OP(3C) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
69OP(3D) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
70OP(3E) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
71OP(3F) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
67OP(3B) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
68OP(3C) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
69OP(3D) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
70OP(3E) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
71OP(3F) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
7272
7373OP(40) { regs.BA = ( regs.BA & 0xFF00 ) | ( regs.BA & 0x00FF); }
7474OP(41) { regs.BA = ( regs.BA & 0xFF00 ) | ( regs.BA >> 8 ); }
7575OP(42) { regs.BA = ( regs.BA & 0xFF00 ) | ( regs.HL & 0x00FF); }
7676OP(43) { regs.BA = ( regs.BA & 0xFF00 ) | ( regs.HL >> 8 ); }
77OP(44) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
78OP(45) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
79OP(46) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
80OP(47) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
77OP(44) { AD2_IN8; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
78OP(45) { AD2_IHL; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
79OP(46) { AD2_XIX; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
80OP(47) { AD2_YIY; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
8181OP(48) { regs.BA = ( regs.BA & 0x00FF ) | ( ( regs.BA & 0x00FF) << 8 ); }
8282OP(49) { regs.BA = ( regs.BA & 0x00FF ) | ( ( regs.BA >> 8 ) << 8 ); }
8383OP(4A) { regs.BA = ( regs.BA & 0x00FF ) | ( ( regs.HL & 0x00FF) << 8 ); }
8484OP(4B) { regs.BA = ( regs.BA & 0x00FF ) | ( ( regs.HL >> 8 ) << 8 ); }
85OP(4C) { AD2_IN8; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
86OP(4D) { AD2_I16; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
87OP(4E) { AD2_XIX; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
88OP(4F) { AD2_YIY; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
85OP(4C) { AD2_IN8; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
86OP(4D) { AD2_IHL; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
87OP(4E) { AD2_XIX; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
88OP(4F) { AD2_YIY; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
8989
9090OP(50) { regs.HL = ( regs.HL & 0xFF00 ) | ( regs.BA & 0x00FF); }
9191OP(51) { regs.HL = ( regs.HL & 0xFF00 ) | ( regs.BA >> 8 ); }
9292OP(52) { regs.HL = ( regs.HL & 0xFF00 ) | ( regs.HL & 0x00FF); }
9393OP(53) { regs.HL = ( regs.HL & 0xFF00 ) | ( regs.HL >> 8 ); }
94OP(54) { AD2_IN8; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
95OP(55) { AD2_I16; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
96OP(56) { AD2_XIX; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
97OP(57) { AD2_YIY; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
94OP(54) { AD2_IN8; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
95OP(55) { AD2_IHL; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
96OP(56) { AD2_XIX; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
97OP(57) { AD2_YIY; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
9898OP(58) { regs.HL = ( regs.HL & 0x00FF ) | ( ( regs.BA & 0x00FF) << 8 ); }
9999OP(59) { regs.HL = ( regs.HL & 0x00FF ) | ( ( regs.BA >> 8 ) << 8 ); }
100100OP(5A) { regs.HL = ( regs.HL & 0x00FF ) | ( ( regs.HL & 0x00FF) << 8 ); }
101101OP(5B) { regs.HL = ( regs.HL & 0x00FF ) | ( ( regs.HL >> 8 ) << 8 ); }
102OP(5C) { AD2_IN8; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
103OP(5D) { AD2_I16; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
104OP(5E) { AD2_XIX; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
105OP(5F) { AD2_YIY; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
102OP(5C) { AD2_IN8; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
103OP(5D) { AD2_IHL; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
104OP(5E) { AD2_XIX; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
105OP(5F) { AD2_YIY; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
106106
107OP(60) { AD1_XIX; wr( addr1, ( regs.BA & 0x00FF ) ); }
108OP(61) { AD1_XIX; wr( addr1, ( regs.BA >> 8 ) ); }
109OP(62) { AD1_XIX; wr( addr1, ( regs.HL & 0x00FF ) ); }
110OP(63) { AD1_XIX; wr( addr1, ( regs.HL >> 8 ) ); }
111OP(64) { AD1_XIX; AD2_IN8; wr( addr1, rd( addr2 ) ); }
112OP(65) { AD1_XIX; AD2_IHL; wr( addr1, rd( addr2 ) ); }
113OP(66) { AD1_XIX; AD2_XIX; wr( addr1, rd( addr2 ) ); }
114OP(67) { AD1_XIX; AD2_YIY; wr( addr1, rd( addr2 ) ); }
115OP(68) { AD1_IHL; wr( addr1, ( regs.BA & 0x00FF ) ); }
116OP(69) { AD1_IHL; wr( addr1, ( regs.BA >> 8 ) ); }
117OP(6A) { AD1_IHL; wr( addr1, ( regs.HL & 0x00FF ) ); }
118OP(6B) { AD1_IHL; wr( addr1, ( regs.HL >> 8 ) ); }
119OP(6C) { AD1_IHL; AD2_IN8; wr( addr1, rd( addr2 ) ); }
120OP(6D) { AD1_IHL; AD2_IHL; wr( addr1, rd( addr2 ) ); }
121OP(6E) { AD1_IHL; AD2_XIX; wr( addr1, rd( addr2 ) ); }
122OP(6F) { AD1_IHL; AD2_YIY; wr( addr1, rd( addr2 ) ); }
107OP(60) { AD1_XIX; WR( addr1, ( regs.BA & 0x00FF ) ); }
108OP(61) { AD1_XIX; WR( addr1, ( regs.BA >> 8 ) ); }
109OP(62) { AD1_XIX; WR( addr1, ( regs.HL & 0x00FF ) ); }
110OP(63) { AD1_XIX; WR( addr1, ( regs.HL >> 8 ) ); }
111OP(64) { AD1_XIX; AD2_IN8; WR( addr1, RD( addr2 ) ); }
112OP(65) { AD1_XIX; AD2_IHL; WR( addr1, RD( addr2 ) ); }
113OP(66) { AD1_XIX; AD2_XIX; WR( addr1, RD( addr2 ) ); }
114OP(67) { AD1_XIX; AD2_YIY; WR( addr1, RD( addr2 ) ); }
115OP(68) { AD1_IHL; WR( addr1, ( regs.BA & 0x00FF ) ); }
116OP(69) { AD1_IHL; WR( addr1, ( regs.BA >> 8 ) ); }
117OP(6A) { AD1_IHL; WR( addr1, ( regs.HL & 0x00FF ) ); }
118OP(6B) { AD1_IHL; WR( addr1, ( regs.HL >> 8 ) ); }
119OP(6C) { AD1_IHL; AD2_IN8; WR( addr1, RD( addr2 ) ); }
120OP(6D) { AD1_IHL; AD2_IHL; WR( addr1, RD( addr2 ) ); }
121OP(6E) { AD1_IHL; AD2_XIX; WR( addr1, RD( addr2 ) ); }
122OP(6F) { AD1_IHL; AD2_YIY; WR( addr1, RD( addr2 ) ); }
123123
124OP(70) { AD1_YIY; wr( addr1, ( regs.BA & 0x00FF ) ); }
125OP(71) { AD1_YIY; wr( addr1, ( regs.BA >> 8 ) ); }
126OP(72) { AD1_YIY; wr( addr1, ( regs.HL & 0x00FF ) ); }
127OP(73) { AD1_YIY; wr( addr1, ( regs.HL >> 8 ) ); }
128OP(74) { AD1_YIY; AD2_IN8; wr( addr1, rd( addr2 ) ); }
129OP(75) { AD1_YIY; AD2_IHL; wr( addr1, rd( addr2 ) ); }
130OP(76) { AD1_YIY; AD2_XIX; wr( addr1, rd( addr2 ) ); }
131OP(77) { AD1_YIY; AD2_YIY; wr( addr1, rd( addr2 ) ); }
132OP(78) { AD1_IN8; wr( addr1, ( regs.BA & 0x00FF ) ); }
133OP(79) { AD1_IN8; wr( addr1, ( regs.BA >> 8 ) ); }
134OP(7A) { AD1_IN8; wr( addr1, ( regs.HL & 0x00FF ) ); }
135OP(7B) { AD1_IN8; wr( addr1, ( regs.HL >> 8 ) ); }
124OP(70) { AD1_YIY; WR( addr1, ( regs.BA & 0x00FF ) ); }
125OP(71) { AD1_YIY; WR( addr1, ( regs.BA >> 8 ) ); }
126OP(72) { AD1_YIY; WR( addr1, ( regs.HL & 0x00FF ) ); }
127OP(73) { AD1_YIY; WR( addr1, ( regs.HL >> 8 ) ); }
128OP(74) { AD1_YIY; AD2_IN8; WR( addr1, RD( addr2 ) ); }
129OP(75) { AD1_YIY; AD2_IHL; WR( addr1, RD( addr2 ) ); }
130OP(76) { AD1_YIY; AD2_XIX; WR( addr1, RD( addr2 ) ); }
131OP(77) { AD1_YIY; AD2_YIY; WR( addr1, RD( addr2 ) ); }
132OP(78) { AD1_IN8; WR( addr1, ( regs.BA & 0x00FF ) ); }
133OP(79) { AD1_IN8; WR( addr1, ( regs.BA >> 8 ) ); }
134OP(7A) { AD1_IN8; WR( addr1, ( regs.HL & 0x00FF ) ); }
135OP(7B) { AD1_IN8; WR( addr1, ( regs.HL >> 8 ) ); }
136136OP(7C) { /* illegal operation? */ }
137OP(7D) { AD1_IN8; AD2_IHL; wr( addr1, rd( addr2 ) ); }
138OP(7E) { AD1_IN8; AD2_XIX; wr( addr1, rd( addr2 ) ); }
139OP(7F) { AD1_IN8; AD2_YIY; wr( addr1, rd( addr2 ) ); }
137OP(7D) { AD1_IN8; AD2_IHL; WR( addr1, RD( addr2 ) ); }
138OP(7E) { AD1_IN8; AD2_XIX; WR( addr1, RD( addr2 ) ); }
139OP(7F) { AD1_IN8; AD2_YIY; WR( addr1, RD( addr2 ) ); }
140140
141141OP(80) { regs.BA = ( regs.BA & 0xFF00 ) | INC8( regs.BA & 0x00FF ); }
142142OP(81) { regs.BA = ( regs.BA & 0x00FF ) | ( INC8( regs.BA >> 8 ) << 8 ); }
143143OP(82) { regs.HL = ( regs.HL & 0xFF00 ) | INC8( regs.HL & 0x00FF ); }
144144OP(83) { regs.HL = ( regs.HL & 0x00FF ) | ( INC8( regs.HL >> 8 ) << 8 ); }
145145OP(84) { regs.N = INC8( regs.N ); }
146OP(85) { AD1_IN8; wr( addr1, INC8( rd( addr1 ) ) ); }
147OP(86) { AD1_IHL; wr( addr1, INC8( rd( addr1 ) ) ); }
146OP(85) { AD1_IN8; WR( addr1, INC8( RD( addr1 ) ) ); }
147OP(86) { AD1_IHL; WR( addr1, INC8( RD( addr1 ) ) ); }
148148OP(87) { regs.SP = INC16( regs.SP ); }
149149OP(88) { regs.BA = ( regs.BA & 0xFF00 ) | DEC8( regs.BA & 0x00FF ); }
150150OP(89) { regs.BA = ( regs.BA & 0x00FF ) | ( DEC8( regs.BA >> 8 ) << 8 ); }
151151OP(8A) { regs.HL = ( regs.HL & 0xFF00 ) | DEC8( regs.HL & 0x00FF ); }
152152OP(8B) { regs.HL = ( regs.HL & 0x00FF ) | ( DEC8( regs.HL >> 8 ) << 8 ); }
153153OP(8C) { regs.N = DEC8( regs.N ); }
154OP(8D) { AD1_IN8; wr( addr1, DEC8( rd( addr1 ) ) ); }
155OP(8E) { AD1_IHL; wr( addr1, DEC8( rd( addr1 ) ) ); }
154OP(8D) { AD1_IN8; WR( addr1, DEC8( RD( addr1 ) ) ); }
155OP(8E) { AD1_IHL; WR( addr1, DEC8( RD( addr1 ) ) ); }
156156OP(8F) { regs.SP = DEC8( regs.SP ); }
157157
158158OP(90) { regs.BA = INC16( regs.BA ); }
r2821r2822
160160OP(92) { regs.X = INC16( regs.X ); }
161161OP(93) { regs.Y = INC16( regs.Y ); }
162162OP(94) { regs.F = ( AND8( ( regs.BA & 0x00FF ), ( regs.BA >> 8 ) ) ) ? regs.F & ~FLAG_Z : regs.F | FLAG_Z;}
163OP(95) { AD1_IHL; regs.F = ( AND8( rd( addr1 ), rdop() ) ) ? regs.F & ~FLAG_Z : regs.F | FLAG_Z; }
163OP(95) { AD1_IHL; regs.F = ( AND8( RD( addr1 ), rdop() ) ) ? regs.F & ~FLAG_Z : regs.F | FLAG_Z; }
164164OP(96) { regs.F = ( AND8( ( regs.BA & 0x00FF ), rdop() ) ) ? regs.F & ~FLAG_Z : regs.F | FLAG_Z; }
165165OP(97) { regs.F = ( AND8( ( regs.BA >> 8 ), rdop() ) ) ? regs.F & ~FLAG_Z : regs.F | FLAG_Z; }
166166OP(98) { regs.BA = DEC16( regs.BA ); }
r2821r2822
194194OP(B2) { UINT8 op = rdop(); regs.HL = ( regs.HL & 0xFF00 ) | op; }
195195OP(B3) { UINT8 op = rdop(); regs.HL = ( regs.HL & 0x00FF ) | ( op << 8 ); }
196196OP(B4) { UINT8 op = rdop(); regs.N = op; }
197OP(B5) { UINT8 op = rdop(); wr( ( regs.I << 16 ) | regs.HL, op); }
198OP(B6) { UINT8 op = rdop(); wr( ( regs.X << 16 ), op ); }
199OP(B7) { UINT8 op = rdop(); wr( ( regs.Y << 16 ), op ); }
197OP(B5) { AD1_IHL; UINT8 op = rdop(); WR( addr1, op); }
198OP(B6) { AD1_XIX; UINT8 op = rdop(); WR( addr1, op ); }
199OP(B7) { AD1_YIY; UINT8 op = rdop(); WR( addr1, op ); }
200200OP(B8) { AD2_I16; regs.BA = rd16( addr2 ); }
201201OP(B9) { AD2_I16; regs.HL = rd16( addr2 ); }
202202OP(BA) { AD2_I16; regs.X = rd16( addr2 ); }
203203OP(BB) { AD2_I16; regs.Y = rd16( addr2 ); }
204OP(BC) { AD1_I16; wr( addr1, regs.BA ); }
205OP(BD) { AD1_I16; wr( addr1, regs.HL ); }
204OP(BC) { AD1_I16; wr16( addr1, regs.BA ); }
205OP(BD) { AD1_I16; wr16( addr1, regs.HL ); }
206206OP(BE) { AD1_I16; wr16( addr1, regs.X ); }
207207OP(BF) { AD1_I16; wr16( addr1, regs.Y ); }
208208
r2821r2822
219219OP(CA) { UINT16 t = regs.BA; regs.BA = regs.Y; regs.Y = t; }
220220OP(CB) { UINT16 t = regs.BA; regs.BA = regs.SP; regs.SP = t; }
221221OP(CC) { regs.BA = ( regs.BA >> 8 ) | ( ( regs.BA & 0x00FF ) << 8 ); }
222OP(CD) { UINT8 t; AD2_IHL; t = rd( addr2 ); wr( addr2, ( regs.BA & 0x00FF ) ); regs.BA = ( regs.BA & 0xFF00 ) | t; }
222OP(CD) { UINT8 t; AD2_IHL; t = RD( addr2 ); WR( addr2, ( regs.BA & 0x00FF ) ); regs.BA = ( regs.BA & 0xFF00 ) | t; }
223223OP(CE) { UINT8 op = rdop(); insnminx_CE[op](); minx_icount -= insnminx_cycles_CE[op]; }
224224OP(CF) { UINT8 op = rdop(); insnminx_CF[op](); minx_icount -= insnminx_cycles_CF[op]; }
225225
r2821r2822
231231OP(D5) { SUB16( regs.HL, rdop16() ); }
232232OP(D6) { SUB16( regs.X, rdop16() ); }
233233OP(D7) { SUB16( regs.Y, rdop16() ); }
234OP(D8) { AD1_IN8; wr( addr1, AND8( rd( addr1 ), rdop() ) ); }
235OP(D9) { AD1_IN8; wr( addr1, OR8( rd( addr1 ), rdop() ) ); }
236OP(DA) { AD1_IN8; wr( addr1, XOR8( rd( addr1 ), rdop() ) ); }
237OP(DB) { AD1_IN8; SUB8( rd( addr1 ), rdop() ); }
238OP(DC) { AD1_IN8; regs.F = ( AND8( rd( addr1 ), rdop() ) ) ? regs.F & ~FLAG_Z : regs.F | FLAG_Z; }
239OP(DD) { AD1_IN8; wr( addr1, rdop() ); }
234OP(D8) { AD1_IN8; WR( addr1, AND8( RD( addr1 ), rdop() ) ); }
235OP(D9) { AD1_IN8; WR( addr1, OR8( RD( addr1 ), rdop() ) ); }
236OP(DA) { AD1_IN8; WR( addr1, XOR8( RD( addr1 ), rdop() ) ); }
237OP(DB) { AD1_IN8; SUB8( RD( addr1 ), rdop() ); }
238OP(DC) { AD1_IN8; regs.F = ( AND8( RD( addr1 ), rdop() ) ) ? regs.F & ~FLAG_Z : regs.F | FLAG_Z; }
239OP(DD) { AD1_IN8; WR( addr1, rdop() ); }
240240OP(DE) { regs.BA = ( regs.BA & 0xFF00 ) | ( ( regs.BA & 0x000F ) | ( ( regs.BA & 0x0F00 ) >> 4 ) ); }
241241OP(DF) { regs.BA = ( ( regs.BA & 0x0080 ) ? 0xFF00 : 0x0000 ) | ( regs.BA & 0x000F ); }
242242
243OP(E0) { INT8 d8 = rdop(); if ( regs.F & FLAG_C ) { CALL( regs.PC + d8 - 1 ); } }
244OP(E1) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_C ) ) { CALL( regs.PC + d8- 1  ); } }
245OP(E2) { INT8 d8 = rdop(); if ( regs.F & FLAG_Z ) { CALL( regs.PC + d8 - 1 ); } }
246OP(E3) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_Z ) ) { CALL( regs.PC + d8 - 1 ); } }
243OP(E0) { INT8 d8 = rdop(); if ( regs.F & FLAG_C ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
244OP(E1) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_C ) ) { CALL( regs.PC + d8- 1  ); minx_icount -= 12; } }
245OP(E2) { INT8 d8 = rdop(); if ( regs.F & FLAG_Z ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
246OP(E3) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_Z ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
247247OP(E4) { INT8 d8 = rdop(); if ( regs.F & FLAG_C ) { JMP( regs.PC + d8 - 1 ); } }
248248OP(E5) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_C ) ) { JMP( regs.PC + d8 - 1 ); } }
249249OP(E6) { INT8 d8 = rdop(); if ( regs.F & FLAG_Z ) { JMP( regs.PC + d8 - 1 ); } }
250250OP(E7) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_Z ) ) { JMP( regs.PC + d8 - 1 ); } }
251OP(E8) { UINT16 d16 = rdop16(); if ( regs.F & FLAG_C ) { CALL( regs.PC + d16 - 1 ); } }
252OP(E9) { UINT16 d16 = rdop16(); if ( ! ( regs.F & FLAG_C ) ) { CALL( regs.PC + d16 - 1 ); } }
253OP(EA) { UINT16 d16 = rdop16(); if ( regs.F & FLAG_Z ) { CALL( regs.PC + d16 - 1 ); } }
254OP(EB) { UINT16 d16 = rdop16(); if ( ! ( regs.F & FLAG_Z ) ) { CALL( regs.PC + d16 - 1 ); } }
251OP(E8) { UINT16 d16 = rdop16(); if ( regs.F & FLAG_C ) { CALL( regs.PC + d16 - 1 ); minx_icount -= 12; } }
252OP(E9) { UINT16 d16 = rdop16(); if ( ! ( regs.F & FLAG_C ) ) { CALL( regs.PC + d16 - 1 ); minx_icount -= 12; } }
253OP(EA) { UINT16 d16 = rdop16(); if ( regs.F & FLAG_Z ) { CALL( regs.PC + d16 - 1 ); minx_icount -= 12; } }
254OP(EB) { UINT16 d16 = rdop16(); if ( ! ( regs.F & FLAG_Z ) ) { CALL( regs.PC + d16 - 1 ); minx_icount -= 12; } }
255255OP(EC) { UINT16 d16 = rdop16(); if ( regs.F & FLAG_C ) { JMP( regs.PC + d16 - 1 ); } }
256256OP(ED) { UINT16 d16 = rdop16(); if ( ! ( regs.F & FLAG_C ) ) { JMP( regs.PC + d16 - 1 ); } }
257257OP(EE) { UINT16 d16 = rdop16(); if ( regs.F & FLAG_Z ) { JMP( regs.PC + d16 - 1 ); } }
r2821r2822
264264OP(F4) { JMP( regs.HL ); }
265265OP(F5) { INT8 d8 = rdop(); regs.BA = regs.BA - 0x0100; if ( regs.BA & 0xFF00 ) { JMP( regs.PC + d8 - 1 ); } }
266266OP(F6) { regs.BA = ( regs.BA & 0xFF00 ) | ( ( regs.BA & 0x00F0 ) >> 4 ) | ( ( regs.BA & 0x000F ) << 4 ); }
267OP(F7) { UINT8 d; AD1_IHL; d = rd( addr1 ); wr( addr1, ( ( d & 0xF0 ) >> 4 ) | ( ( d & 0x0F ) << 4 ) ); }
267OP(F7) { UINT8 d; AD1_IHL; d = RD( addr1 ); WR( addr1, ( ( d & 0xF0 ) >> 4 ) | ( ( d & 0x0F ) << 4 ) ); }
268268OP(F8) { regs.PC = POP16(); regs.V = POP8(); }
269269OP(F9) { regs.F = POP8(); regs.PC = POP16(); regs.V = POP8(); }
270270OP(FA) { regs.PC = POP16() + 2; regs.V = POP8(); }
271271OP(FB) { AD1_I16; CALL( rd16( addr1 ) ); }
272OP(FC) { UINT16 i = rdop() << 1; CALL( i ); PUSH8( regs.F ); }
273OP(FD) { UINT16 i = rdop() << 1; JMP( i ); /* PUSH8( regs.F );?? */ }
272OP(FC) { UINT8 i = rdop() & 0xFE; CALL( rd16(i) ); PUSH8( regs.F ); }
273OP(FD) { UINT8 i = rdop() & 0xFE; JMP( rd16(i) ); /* PUSH8( regs.F );?? */ }
274274OP(FE) { /* illegal operation? */ }
275275OP(FF) { }
276276
r2821r2822
310310};
311311
312312static const int insnminx_cycles[256] = {
313   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
314   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
315   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
316   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
317   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
318   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
319   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
320   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
321   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
322   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
323   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
324   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
325   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
326   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
327   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
328   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
313    8,  8,  8,  8, 12, 16,  8,  8,  8,  8,  8,  8, 12, 16,  8,  8,
314    8,  8,  8,  8, 12, 16,  8,  8,  8,  8,  8,  8, 12, 16,  8,  8,
315    8,  8,  8,  8, 12, 16,  8,  8,  8,  8,  8,  8, 12, 16,  8,  8,
316    8,  8,  8,  8, 12, 16,  8,  8,  8,  8,  8,  8, 12, 16,  8,  8,
317
318    4,  4,  4,  4, 12,  8,  8,  8,  4,  4,  4,  4, 12,  8,  8,  8,
319    4,  4,  4,  4, 12,  8,  8,  8,  4,  4,  4,  4, 12,  8,  8,  8,
320    8,  8,  8,  8, 16, 12, 12, 12,  8,  8,  8,  8, 16, 12, 12, 12,
321    8,  8,  8,  8, 16, 12, 12, 12, 12, 12, 12, 12,  1, 16, 16, 16,
322
323    8,  8,  8,  8,  8, 16, 12,  8,  8,  8,  8,  8,  8, 16, 12,  8,
324    8,  8,  8,  8,  8, 12,  8,  8,  8,  8,  8,  8, 12, 12, 12, 12,
325   16, 16, 16, 16, 12, 12, 16, 12, 12, 12, 12, 12,  8,  8, 12,  8,
326    8,  8,  8,  8,  8, 12, 12, 12, 20, 20, 20, 20,  1,  1,  1,  1,
327
328   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  8, 12,  0,  0,
329   12, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 16, 16, 16,  8,  8,
330    8,  8,  8,  8,  8,  8,  8,  8, 12, 12, 12, 12, 12, 12, 12, 12,
331   20,  8, 24, 12,  8,  1,  8, 12,  8,  8,  8, 20, 20,  1,  1,  8
329332};
330333
src/emu/cpu/minx/minxopce.h
r2821r2822
22#undef OP
33#define OP(nn) INLINE void minx_CE_##nn(void)
44
5OP(00) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
6OP(01) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
7OP(02) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
8OP(03) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
9OP(04) { AD1_IHL; wr( addr1, ADD8( rd( addr1 ), ( regs.BA & 0x00FF ) ) ); }
10OP(05) { AD1_IHL; wr( addr1, ADD8( rd( addr1 ), rdop() ) ); }
11OP(06) { AD1_IHL; AD2_XIX; wr( addr1, ADD8( rd( addr1 ), rd( addr2 ) ) ); }
12OP(07) { AD1_IHL; AD2_YIY; wr( addr1, ADD8( rd( addr1 ), rd( addr2 ) ) ); }
13OP(08) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
14OP(09) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
15OP(0A) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
16OP(0B) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
17OP(0C) { AD1_IHL; wr( addr1, ADDC8( rd( addr1 ), ( regs.BA & 0x00FF ) ) ); }
18OP(0D) { AD1_IHL; wr( addr1, ADDC8( rd( addr1 ), rdop() ) ); }
19OP(0E) { AD1_IHL; AD2_XIX; wr( addr1, ADDC8( rd( addr1 ), rd( addr2 ) ) ); }
20OP(0F) { AD1_IHL; AD2_YIY; wr( addr1, ADDC8( rd( addr1 ), rd( addr2 ) ) ); }
5OP(00) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
6OP(01) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
7OP(02) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
8OP(03) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | ADD8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
9OP(04) { AD1_IHL; WR( addr1, ADD8( RD( addr1 ), ( regs.BA & 0x00FF ) ) ); }
10OP(05) { AD1_IHL; WR( addr1, ADD8( RD( addr1 ), rdop() ) ); }
11OP(06) { AD1_IHL; AD2_XIX; WR( addr1, ADD8( RD( addr1 ), RD( addr2 ) ) ); }
12OP(07) { AD1_IHL; AD2_YIY; WR( addr1, ADD8( RD( addr1 ), RD( addr2 ) ) ); }
13OP(08) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
14OP(09) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
15OP(0A) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
16OP(0B) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | ADDC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
17OP(0C) { AD1_IHL; WR( addr1, ADDC8( RD( addr1 ), ( regs.BA & 0x00FF ) ) ); }
18OP(0D) { AD1_IHL; WR( addr1, ADDC8( RD( addr1 ), rdop() ) ); }
19OP(0E) { AD1_IHL; AD2_XIX; WR( addr1, ADDC8( RD( addr1 ), RD( addr2 ) ) ); }
20OP(0F) { AD1_IHL; AD2_YIY; WR( addr1, ADDC8( RD( addr1 ), RD( addr2 ) ) ); }
2121
22OP(10) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
23OP(11) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
24OP(12) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
25OP(13) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
26OP(14) { AD1_IHL; wr( addr1, SUB8( rd( addr1 ), ( regs.BA & 0x00FF ) ) ); }
27OP(15) { AD1_IHL; wr( addr1, SUB8( rd( addr1 ), rdop() ) ); }
28OP(16) { AD1_IHL; AD2_XIX; wr( addr1, SUB8( rd( addr1 ), rd( addr2 ) ) ); }
29OP(17) { AD1_IHL; AD2_YIY; wr( addr1, SUB8( rd( addr1 ), rd( addr2 ) ) ); }
30OP(18) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
31OP(19) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
32OP(1A) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
33OP(1B) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
34OP(1C) { AD1_IHL; wr( addr1, SUBC8( rd( addr1 ), ( regs.BA & 0x00FF ) ) ); }
35OP(1D) { AD1_IHL; wr( addr1, SUBC8( rd( addr1 ), rdop() ) ); }
36OP(1E) { AD1_IHL; AD2_XIX; wr( addr1, SUBC8( rd( addr1 ), rd( addr2 ) ) ); }
37OP(1F) { AD1_IHL; AD2_YIY; wr( addr1, SUBC8( rd( addr1 ), rd( addr2 ) ) ); }
22OP(10) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
23OP(11) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
24OP(12) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
25OP(13) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
26OP(14) { AD1_IHL; WR( addr1, SUB8( RD( addr1 ), ( regs.BA & 0x00FF ) ) ); }
27OP(15) { AD1_IHL; WR( addr1, SUB8( RD( addr1 ), rdop() ) ); }
28OP(16) { AD1_IHL; AD2_XIX; WR( addr1, SUB8( RD( addr1 ), RD( addr2 ) ) ); }
29OP(17) { AD1_IHL; AD2_YIY; WR( addr1, SUB8( RD( addr1 ), RD( addr2 ) ) ); }
30OP(18) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
31OP(19) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
32OP(1A) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
33OP(1B) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | SUBC8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
34OP(1C) { AD1_IHL; WR( addr1, SUBC8( RD( addr1 ), ( regs.BA & 0x00FF ) ) ); }
35OP(1D) { AD1_IHL; WR( addr1, SUBC8( RD( addr1 ), rdop() ) ); }
36OP(1E) { AD1_IHL; AD2_XIX; WR( addr1, SUBC8( RD( addr1 ), RD( addr2 ) ) ); }
37OP(1F) { AD1_IHL; AD2_YIY; WR( addr1, SUBC8( RD( addr1 ), RD( addr2 ) ) ); }
3838
39OP(20) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
40OP(21) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
41OP(22) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
42OP(23) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
43OP(24) { AD1_IHL; wr( addr1, AND8( rd( addr1 ), ( regs.BA & 0x00FF ) ) ); }
44OP(25) { AD1_IHL; wr( addr1, AND8( rd( addr1 ), rdop() ) ); }
45OP(26) { AD1_IHL; AD2_XIX; wr( addr1, AND8( rd( addr1 ), rd( addr2 ) ) ); }
46OP(27) { AD1_IHL; AD2_YIY; wr( addr1, AND8( rd( addr1 ), rd( addr2 ) ) ); }
47OP(28) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
48OP(29) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
49OP(2A) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
50OP(2B) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
51OP(2C) { AD1_IHL; wr( addr1, OR8( rd( addr1 ), ( regs.BA & 0x00FF ) ) ); }
52OP(2D) { AD1_IHL; wr( addr1, OR8( rd( addr1 ), rdop() ) ); }
53OP(2E) { AD1_IHL; AD2_XIX; wr( addr1, OR8( rd( addr1 ), rd( addr2 ) ) ); }
54OP(2F) { AD1_IHL; AD2_YIY; wr( addr1, OR8( rd( addr1 ), rd( addr2 ) ) ); }
39OP(20) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
40OP(21) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
41OP(22) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
42OP(23) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | AND8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
43OP(24) { AD1_IHL; WR( addr1, AND8( RD( addr1 ), ( regs.BA & 0x00FF ) ) ); }
44OP(25) { AD1_IHL; WR( addr1, AND8( RD( addr1 ), rdop() ) ); }
45OP(26) { AD1_IHL; AD2_XIX; WR( addr1, AND8( RD( addr1 ), RD( addr2 ) ) ); }
46OP(27) { AD1_IHL; AD2_YIY; WR( addr1, AND8( RD( addr1 ), RD( addr2 ) ) ); }
47OP(28) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
48OP(29) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
49OP(2A) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
50OP(2B) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | OR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
51OP(2C) { AD1_IHL; WR( addr1, OR8( RD( addr1 ), ( regs.BA & 0x00FF ) ) ); }
52OP(2D) { AD1_IHL; WR( addr1, OR8( RD( addr1 ), rdop() ) ); }
53OP(2E) { AD1_IHL; AD2_XIX; WR( addr1, OR8( RD( addr1 ), RD( addr2 ) ) ); }
54OP(2F) { AD1_IHL; AD2_YIY; WR( addr1, OR8( RD( addr1 ), RD( addr2 ) ) ); }
5555
56OP(30) { AD2_X8; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
57OP(31) { AD2_Y8; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
58OP(32) { AD2_XL; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
59OP(33) { AD2_YL; SUB8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
60OP(34) { AD1_IHL; SUB8( rd( addr1 ), ( regs.BA & 0x00FF ) ); }
61OP(35) { AD1_IHL; SUB8( rd( addr1 ), rdop() ); }
62OP(36) { AD1_IHL; AD2_XIX; SUB8( rd( addr1 ), rd( addr2 ) ); }
63OP(37) { AD1_IHL; AD2_YIY; SUB8( rd( addr1 ), rd( addr2 ) ); }
64OP(38) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
65OP(39) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
66OP(3A) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
67OP(3B) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), rd( addr2 ) ); }
68OP(3C) { AD1_IHL; wr( addr1, XOR8( rd( addr1 ), ( regs.BA & 0x00FF ) ) ); }
69OP(3D) { AD1_IHL; wr( addr1, XOR8( rd( addr1 ), rdop() ) ); }
70OP(3E) { AD1_IHL; AD2_XIX; wr( addr1, XOR8( rd( addr1 ), rd( addr2 ) ) ); }
71OP(3F) { AD1_IHL; AD2_YIY; wr( addr1, XOR8( rd( addr1 ), rd( addr2 ) ) ); }
56OP(30) { AD2_X8; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
57OP(31) { AD2_Y8; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
58OP(32) { AD2_XL; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
59OP(33) { AD2_YL; SUB8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
60OP(34) { AD1_IHL; SUB8( RD( addr1 ), ( regs.BA & 0x00FF ) ); }
61OP(35) { AD1_IHL; SUB8( RD( addr1 ), rdop() ); }
62OP(36) { AD1_IHL; AD2_XIX; SUB8( RD( addr1 ), RD( addr2 ) ); }
63OP(37) { AD1_IHL; AD2_YIY; SUB8( RD( addr1 ), RD( addr2 ) ); }
64OP(38) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
65OP(39) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
66OP(3A) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
67OP(3B) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | XOR8( ( regs.BA & 0x00FF ), RD( addr2 ) ); }
68OP(3C) { AD1_IHL; WR( addr1, XOR8( RD( addr1 ), ( regs.BA & 0x00FF ) ) ); }
69OP(3D) { AD1_IHL; WR( addr1, XOR8( RD( addr1 ), rdop() ) ); }
70OP(3E) { AD1_IHL; AD2_XIX; WR( addr1, XOR8( RD( addr1 ), RD( addr2 ) ) ); }
71OP(3F) { AD1_IHL; AD2_YIY; WR( addr1, XOR8( RD( addr1 ), RD( addr2 ) ) ); }
7272
73OP(40) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
74OP(41) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
75OP(42) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
76OP(43) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
77OP(44) { AD1_X8; wr( addr1, ( regs.BA & 0x00FF ) ); }
78OP(45) { AD1_Y8; wr( addr1, ( regs.BA & 0x00FF ) ); }
79OP(46) { AD1_XL; wr( addr1, ( regs.BA & 0x00FF ) ); }
80OP(47) { AD1_YL; wr( addr1, ( regs.BA & 0x00FF ) ); }
81OP(48) { AD2_X8; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
82OP(49) { AD2_Y8; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
83OP(4A) { AD2_XL; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
84OP(4B) { AD2_YL; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
85OP(4C) { AD1_X8; wr( addr1, ( regs.BA >> 8 ) ); }
86OP(4D) { AD1_Y8; wr( addr1, ( regs.BA >> 8 ) ); }
87OP(4E) { AD1_XL; wr( addr1, ( regs.BA >> 8 ) ); }
88OP(4F) { AD1_YL; wr( addr1, ( regs.BA >> 8 ) ); }
73OP(40) { AD2_X8; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
74OP(41) { AD2_Y8; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
75OP(42) { AD2_XL; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
76OP(43) { AD2_YL; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
77OP(44) { AD1_X8; WR( addr1, ( regs.BA & 0x00FF ) ); }
78OP(45) { AD1_Y8; WR( addr1, ( regs.BA & 0x00FF ) ); }
79OP(46) { AD1_XL; WR( addr1, ( regs.BA & 0x00FF ) ); }
80OP(47) { AD1_YL; WR( addr1, ( regs.BA & 0x00FF ) ); }
81OP(48) { AD2_X8; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
82OP(49) { AD2_Y8; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
83OP(4A) { AD2_XL; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
84OP(4B) { AD2_YL; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
85OP(4C) { AD1_X8; WR( addr1, ( regs.BA >> 8 ) ); }
86OP(4D) { AD1_Y8; WR( addr1, ( regs.BA >> 8 ) ); }
87OP(4E) { AD1_XL; WR( addr1, ( regs.BA >> 8 ) ); }
88OP(4F) { AD1_YL; WR( addr1, ( regs.BA >> 8 ) ); }
8989
90OP(50) { AD2_X8; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
91OP(51) { AD2_Y8; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
92OP(52) { AD2_XL; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
93OP(53) { AD2_YL; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
94OP(54) { AD1_X8; wr( addr1, ( regs.HL & 0x00FF ) ); }
95OP(55) { AD1_Y8; wr( addr1, ( regs.HL & 0x00FF ) ); }
96OP(56) { AD1_XL; wr( addr1, ( regs.HL & 0x00FF ) ); }
97OP(57) { AD1_YL; wr( addr1, ( regs.HL & 0x00FF ) ); }
98OP(58) { AD2_X8; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
99OP(59) { AD2_Y8; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
100OP(5A) { AD2_XL; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
101OP(5B) { AD2_YL; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
102OP(5C) { AD1_X8; wr( addr1, ( regs.HL >> 8 ) ); }
103OP(5D) { AD1_Y8; wr( addr1, ( regs.HL >> 8 ) ); }
104OP(5E) { AD1_XL; wr( addr1, ( regs.HL >> 8 ) ); }
105OP(5F) { AD1_YL; wr( addr1, ( regs.HL >> 8 ) ); }
90OP(50) { AD2_X8; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
91OP(51) { AD2_Y8; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
92OP(52) { AD2_XL; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
93OP(53) { AD2_YL; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
94OP(54) { AD1_X8; WR( addr1, ( regs.HL & 0x00FF ) ); }
95OP(55) { AD1_Y8; WR( addr1, ( regs.HL & 0x00FF ) ); }
96OP(56) { AD1_XL; WR( addr1, ( regs.HL & 0x00FF ) ); }
97OP(57) { AD1_YL; WR( addr1, ( regs.HL & 0x00FF ) ); }
98OP(58) { AD2_X8; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
99OP(59) { AD2_Y8; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
100OP(5A) { AD2_XL; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
101OP(5B) { AD2_YL; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
102OP(5C) { AD1_X8; WR( addr1, ( regs.HL >> 8 ) ); }
103OP(5D) { AD1_Y8; WR( addr1, ( regs.HL >> 8 ) ); }
104OP(5E) { AD1_XL; WR( addr1, ( regs.HL >> 8 ) ); }
105OP(5F) { AD1_YL; WR( addr1, ( regs.HL >> 8 ) ); }
106106
107OP(60) { AD1_IHL; AD2_X8; wr( addr1, rd( addr2 ) ); }
108OP(61) { AD1_IHL; AD2_Y8; wr( addr1, rd( addr2 ) ); }
109OP(62) { AD1_IHL; AD2_XL; wr( addr1, rd( addr2 ) ); }
110OP(63) { AD1_IHL; AD2_YL; wr( addr1, rd( addr2 ) ); }
107OP(60) { AD1_IHL; AD2_X8; WR( addr1, RD( addr2 ) ); }
108OP(61) { AD1_IHL; AD2_Y8; WR( addr1, RD( addr2 ) ); }
109OP(62) { AD1_IHL; AD2_XL; WR( addr1, RD( addr2 ) ); }
110OP(63) { AD1_IHL; AD2_YL; WR( addr1, RD( addr2 ) ); }
111111OP(64) { /* illegal operation? */ }
112112OP(65) { /* illegal operation? */ }
113113OP(66) { /* illegal operation? */ }
114114OP(67) { /* illegal operation? */ }
115OP(68) { AD1_XIX; AD2_X8; wr( addr1, rd( addr2 ) ); }
116OP(69) { AD1_XIX; AD2_Y8; wr( addr1, rd( addr2 ) ); }
117OP(6A) { AD1_XIX; AD2_XL; wr( addr1, rd( addr2 ) ); }
118OP(6B) { AD1_XIX; AD2_YL; wr( addr1, rd( addr2 ) ); }
115OP(68) { AD1_XIX; AD2_X8; WR( addr1, RD( addr2 ) ); }
116OP(69) { AD1_XIX; AD2_Y8; WR( addr1, RD( addr2 ) ); }
117OP(6A) { AD1_XIX; AD2_XL; WR( addr1, RD( addr2 ) ); }
118OP(6B) { AD1_XIX; AD2_YL; WR( addr1, RD( addr2 ) ); }
119119OP(6C) { /* illegal operation? */ }
120120OP(6D) { /* illegal operation? */ }
121121OP(6E) { /* illegal operation? */ }
r2821r2822
129129OP(75) { /* illegal operation? */ }
130130OP(76) { /* illegal operation? */ }
131131OP(77) { /* illegal operation? */ }
132OP(78) { AD1_YIY; AD2_X8; wr( addr1, rd( addr2 ) ); }
133OP(79) { AD1_YIY; AD2_Y8; wr( addr1, rd( addr2 ) ); }
134OP(7A) { AD1_YIY; AD2_XL; wr( addr1, rd( addr2 ) ); }
135OP(7B) { AD1_YIY; AD2_YL; wr( addr1, rd( addr2 ) ); }
132OP(78) { AD1_YIY; AD2_X8; WR( addr1, RD( addr2 ) ); }
133OP(79) { AD1_YIY; AD2_Y8; WR( addr1, RD( addr2 ) ); }
134OP(7A) { AD1_YIY; AD2_XL; WR( addr1, RD( addr2 ) ); }
135OP(7B) { AD1_YIY; AD2_YL; WR( addr1, RD( addr2 ) ); }
136136OP(7C) { /* illegal operation? */ }
137137OP(7D) { /* illegal operation? */ }
138138OP(7E) { /* illegal operation? */ }
r2821r2822
140140
141141OP(80) { regs.BA = ( regs.BA & 0xFF00 ) | SAL8( regs.BA & 0x00FF ); }
142142OP(81) { regs.BA = ( regs.BA & 0x00FF ) | ( SAL8( regs.BA >> 8 )<< 8 ); }
143OP(82) { AD1_IN8; wr( addr1, SAL8( rd( addr1 ) ) ); }
144OP(83) { AD1_IHL; wr( addr1, SAL8( rd( addr1 ) ) ); }
143OP(82) { AD1_IN8; WR( addr1, SAL8( RD( addr1 ) ) ); }
144OP(83) { AD1_IHL; WR( addr1, SAL8( RD( addr1 ) ) ); }
145145OP(84) { regs.BA = ( regs.BA & 0xFF00 ) | SHL8( regs.BA & 0x00FF ); }
146146OP(85) { regs.BA = ( regs.BA & 0x00FF ) | ( SHL8( regs.BA >> 8 ) << 8 ); }
147OP(86) { AD1_IN8; wr( addr1, SHL8( rd( addr1 ) ) ); }
148OP(87) { AD1_IHL; wr( addr1, SHL8( rd( addr1 ) ) ); }
147OP(86) { AD1_IN8; WR( addr1, SHL8( RD( addr1 ) ) ); }
148OP(87) { AD1_IHL; WR( addr1, SHL8( RD( addr1 ) ) ); }
149149OP(88) { regs.BA = ( regs.BA & 0xFF00 ) | SAR8( regs.BA & 0x00FF ); }
150150OP(89) { regs.BA = ( regs.BA & 0x00FF ) | ( SAR8( regs.BA >> 8 ) << 8 ); }
151OP(8A) { AD1_IN8; wr( addr1, SAR8( rd( addr1 ) ) ); }
152OP(8B) { AD1_IHL; wr( addr1, SAR8( rd( addr1 ) ) ); }
151OP(8A) { AD1_IN8; WR( addr1, SAR8( RD( addr1 ) ) ); }
152OP(8B) { AD1_IHL; WR( addr1, SAR8( RD( addr1 ) ) ); }
153153OP(8C) { regs.BA = ( regs.BA & 0xFF00 ) | SHR8( regs.BA & 0x00FF ); }
154154OP(8D) { regs.BA = ( regs.BA & 0x00FF ) | ( SHR8( regs.BA >> 8 ) << 8 ); }
155OP(8E) { AD1_IN8; wr( addr1, SHR8( rd( addr1 ) ) ); }
156OP(8F) { AD1_IHL; wr( addr1, SHR8( rd( addr1 ) ) ); }
155OP(8E) { AD1_IN8; WR( addr1, SHR8( RD( addr1 ) ) ); }
156OP(8F) { AD1_IHL; WR( addr1, SHR8( RD( addr1 ) ) ); }
157157
158158OP(90) { regs.BA = ( regs.BA & 0xFF00 ) | ROLC8( regs.BA & 0x00FF ); }
159159OP(91) { regs.BA = ( regs.BA & 0x00FF ) | ( ROLC8( regs.BA >> 8 ) << 8 ); }
160OP(92) { AD1_IN8; wr( addr1, ROLC8( rd( addr1 ) ) ); }
161OP(93) { AD1_IHL; wr( addr1, ROLC8( rd( addr1 ) ) ); }
160OP(92) { AD1_IN8; WR( addr1, ROLC8( RD( addr1 ) ) ); }
161OP(93) { AD1_IHL; WR( addr1, ROLC8( RD( addr1 ) ) ); }
162162OP(94) { regs.BA = ( regs.BA & 0xFF00 ) | ROL8( regs.BA & 0x00FF ); }
163163OP(95) { regs.BA = ( regs.BA & 0x00FF ) | ( ROL8( regs.BA >> 8 ) << 8 ); }
164OP(96) { AD1_IN8; wr( addr1, ROL8( rd( addr1 ) ) ); }
165OP(97) { AD1_IHL; wr( addr1, ROL8( rd( addr1 ) ) ); }
164OP(96) { AD1_IN8; WR( addr1, ROL8( RD( addr1 ) ) ); }
165OP(97) { AD1_IHL; WR( addr1, ROL8( RD( addr1 ) ) ); }
166166OP(98) { regs.BA = ( regs.BA & 0xFF00 ) | RORC8( regs.BA & 0x00FF ); }
167167OP(99) { regs.BA = ( regs.BA & 0x00FF ) | ( RORC8( regs.BA >> 8 ) << 8 ); }
168OP(9A) { AD1_IN8; wr( addr1, RORC8( rd( addr1 ) ) ); }
169OP(9B) { AD1_IHL; wr( addr1, RORC8( rd( addr1 ) ) ); }
168OP(9A) { AD1_IN8; WR( addr1, RORC8( RD( addr1 ) ) ); }
169OP(9B) { AD1_IHL; WR( addr1, RORC8( RD( addr1 ) ) ); }
170170OP(9C) { regs.BA = ( regs.BA & 0xFF00 ) | ROR8( regs.BA & 0x00FF ); }
171171OP(9D) { regs.BA = ( regs.BA & 0x00FF ) | ( ROR8( regs.BA >> 8 ) << 8 ); }
172OP(9E) { AD1_IN8; wr( addr1, ROR8( rd( addr1 ) ) ); }
173OP(9F) { AD1_IHL; wr( addr1, ROR8( rd( addr1 ) ) ); }
172OP(9E) { AD1_IN8; WR( addr1, ROR8( RD( addr1 ) ) ); }
173OP(9F) { AD1_IHL; WR( addr1, ROR8( RD( addr1 ) ) ); }
174174
175175OP(A0) { regs.BA = ( regs.BA & 0xFF00 ) | NOT8( regs.BA & 0x00FF ); }
176176OP(A1) { regs.BA = ( regs.BA & 0x00FF ) | ( NOT8( regs.BA >> 8 ) << 8 ); }
177OP(A2) { AD1_IN8; wr( addr1, NOT8( rd( addr1 ) ) ); }
178OP(A3) { AD1_IHL; wr( addr1, NOT8( rd( addr1 ) ) ); }
177OP(A2) { AD1_IN8; WR( addr1, NOT8( RD( addr1 ) ) ); }
178OP(A3) { AD1_IHL; WR( addr1, NOT8( RD( addr1 ) ) ); }
179179OP(A4) { regs.BA = ( regs.BA & 0xFF00 ) | NEG8( regs.BA & 0x00FF ); }
180180OP(A5) { regs.BA = ( regs.BA & 0x00FF ) | ( NEG8( regs.BA >> 8 ) << 8 ); }
181OP(A6) { AD1_IN8; wr( addr1, NEG8( rd( addr1 ) ) ); }
182OP(A7) { AD1_IHL; wr( addr1, NEG8( rd( addr1 ) ) ); }
181OP(A6) { AD1_IN8; WR( addr1, NEG8( RD( addr1 ) ) ); }
182OP(A7) { AD1_IHL; WR( addr1, NEG8( RD( addr1 ) ) ); }
183183OP(A8) { regs.BA = ( ( regs.BA & 0x0080 ) ? ( 0xFF00 | regs.BA ) : ( regs.BA & 0x00FF ) ); }
184184OP(A9) { /* illegal operation? */ }
185185OP(AA) { /* illegal operation? */ }
186186OP(AB) { /* illegal operation? */ }
187187OP(AC) { /* illegal operation? */ }
188188OP(AD) { /* illegal operation? */ }
189OP(AE) { /* HALT */ }
189OP(AE) { /* HALT */ regs.halted = 1; }
190190OP(AF) { }
191191
192192OP(B0) { regs.BA = ( regs.BA & 0x00FF ) | ( AND8( ( regs.BA >> 8 ), rdop() ) << 8 ); }
r2821r2822
223223OP(CE) { regs.XI = ( regs.BA & 0x00FF ); }
224224OP(CF) { regs.YI = ( regs.BA & 0x00FF ); }
225225
226OP(D0) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | rd( addr2 ); }
227OP(D1) { AD2_I16; regs.BA = ( regs.BA & 0x00FF ) | ( rd( addr2 ) << 8 ); }
228OP(D2) { AD2_I16; regs.HL = ( regs.HL & 0xFF00 ) | rd( addr2 ); }
229OP(D3) { AD2_I16; regs.HL = ( regs.HL & 0x00FF ) | ( rd( addr2 ) << 8 ); }
230OP(D4) { AD1_I16; wr( addr1, ( regs.BA & 0x00FF ) ); }
231OP(D5) { AD1_I16; wr( addr1, ( regs.BA >> 8 ) ); }
232OP(D6) { AD1_I16; wr( addr1, ( regs.HL & 0x00FF ) ); }
233OP(D7) { AD1_I16; wr( addr1, ( regs.HL >> 8 ) ); }
234OP(D8) { }
235OP(D9) { }
226OP(D0) { AD2_I16; regs.BA = ( regs.BA & 0xFF00 ) | RD( addr2 ); }
227OP(D1) { AD2_I16; regs.BA = ( regs.BA & 0x00FF ) | ( RD( addr2 ) << 8 ); }
228OP(D2) { AD2_I16; regs.HL = ( regs.HL & 0xFF00 ) | RD( addr2 ); }
229OP(D3) { AD2_I16; regs.HL = ( regs.HL & 0x00FF ) | ( RD( addr2 ) << 8 ); }
230OP(D4) { AD1_I16; WR( addr1, ( regs.BA & 0x00FF ) ); }
231OP(D5) { AD1_I16; WR( addr1, ( regs.BA >> 8 ) ); }
232OP(D6) { AD1_I16; WR( addr1, ( regs.HL & 0x00FF ) ); }
233OP(D7) { AD1_I16; WR( addr1, ( regs.HL >> 8 ) ); }
234OP(D8) { regs.HL = ( regs.HL & 0x00FF ) * ( regs.BA & 0x00FF );  }
235OP(D9) { int d = regs.HL / ( regs.BA & 0x00FF ); regs.HL = ( ( regs.HL - ( ( regs.BA & 0x00FF ) * d ) ) << 8 ) | d; }
236236OP(DA) { /* illegal operation? */ }
237237OP(DB) { /* illegal operation? */ }
238238OP(DC) { /* illegal operation? */ }
r2821r2822
257257OP(EE) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_X2 ) ) { JMP( regs.PC + d8 - 1 ); } }
258258OP(EF) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_DZ ) ) { JMP( regs.PC + d8 - 1 ); } }
259259
260OP(F0) { INT8 d8 = rdop(); if ( ( ( regs.F & ( FLAG_S | FLAG_O ) ) == FLAG_S ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == FLAG_O ) ) { CALL( regs.PC + d8 - 1 ); } }
261OP(F1) { INT8 d8 = rdop(); if ( ( regs.F & FLAG_Z ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == FLAG_S ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == FLAG_O ) ) { CALL( regs.PC + d8 - 1 ); } }
262OP(F2) { INT8 d8 = rdop(); if ( !( regs.F & FLAG_Z ) && ( ( ( regs.F & ( FLAG_S | FLAG_O ) ) == 0 ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == ( FLAG_S | FLAG_O ) ) ) ) { CALL( regs.PC + d8 - 1 ); } }
260OP(F0) { INT8 d8 = rdop(); if ( ( ( regs.F & ( FLAG_S | FLAG_O ) ) == FLAG_S ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == FLAG_O ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
261OP(F1) { INT8 d8 = rdop(); if ( ( regs.F & FLAG_Z ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == FLAG_S ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == FLAG_O ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
262OP(F2) { INT8 d8 = rdop(); if ( !( regs.F & FLAG_Z ) && ( ( ( regs.F & ( FLAG_S | FLAG_O ) ) == 0 ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == ( FLAG_S | FLAG_O ) ) ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
263263OP(F3) { INT8 d8 = rdop(); if ( ( ( regs.F & ( FLAG_S | FLAG_O ) ) == 0 ) || ( ( regs.F & ( FLAG_S | FLAG_O ) ) == ( FLAG_S | FLAG_O ) ) ) { CALL( regs.PC + d8 - 1 ); } }
264OP(F4) { INT8 d8 = rdop(); if ( ( regs.F & FLAG_O ) ) { CALL( regs.PC + d8 - 1 ); } }
265OP(F5) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_O ) ) { CALL( regs.PC + d8 - 1 ); } }
266OP(F6) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_S ) ) { CALL( regs.PC + d8 - 1 ); } }
267OP(F7) { INT8 d8 = rdop(); if ( ( regs.F & FLAG_S ) ) { CALL( regs.PC + d8 - 1 ); } }
268OP(F8) { INT8 d8 = rdop(); if ( ! ( regs.E & EXEC_X0 ) ) { CALL( regs.PC + d8 - 1 ); } }
269OP(F9) { INT8 d8 = rdop(); if ( ! ( regs.E & EXEC_X1 ) ) { CALL( regs.PC + d8 - 1 ); } }
270OP(FA) { INT8 d8 = rdop(); if ( ! ( regs.E & EXEC_X2 ) ) { CALL( regs.PC + d8 - 1 ); } }
271OP(FB) { INT8 d8 = rdop(); if ( ! ( regs.E & EXEC_DZ ) ) { CALL( regs.PC + d8 - 1 ); } }
272OP(FC) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_X0 ) ) { CALL( regs.PC + d8 - 1 ); } }
273OP(FD) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_X1 ) ) { CALL( regs.PC + d8 - 1 ); } }
274OP(FE) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_X2 ) ) { CALL( regs.PC + d8 - 1 ); } }
275OP(FF) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_DZ ) ) { CALL( regs.PC + d8 - 1 ); } }
264OP(F4) { INT8 d8 = rdop(); if ( ( regs.F & FLAG_O ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
265OP(F5) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_O ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
266OP(F6) { INT8 d8 = rdop(); if ( ! ( regs.F & FLAG_S ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
267OP(F7) { INT8 d8 = rdop(); if ( ( regs.F & FLAG_S ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
268OP(F8) { INT8 d8 = rdop(); if ( ! ( regs.E & EXEC_X0 ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
269OP(F9) { INT8 d8 = rdop(); if ( ! ( regs.E & EXEC_X1 ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
270OP(FA) { INT8 d8 = rdop(); if ( ! ( regs.E & EXEC_X2 ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
271OP(FB) { INT8 d8 = rdop(); if ( ! ( regs.E & EXEC_DZ ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
272OP(FC) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_X0 ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
273OP(FD) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_X1 ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
274OP(FE) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_X2 ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
275OP(FF) { INT8 d8 = rdop(); if ( ( regs.E & EXEC_DZ ) ) { CALL( regs.PC + d8 - 1 ); minx_icount -= 12; } }
276276
277277static void (*const insnminx_CE[256])(void) = {
278278   minx_CE_00, minx_CE_01, minx_CE_02, minx_CE_03, minx_CE_04, minx_CE_05, minx_CE_06, minx_CE_07,
r2821r2822
310310};
311311
312312static const int insnminx_cycles_CE[256] = {
313        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
314        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
315        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
316        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
317        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
318        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
319        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
320        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
321        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
322        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
323        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
324        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
325        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
326        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
327        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
328        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
313   16, 16, 16, 16, 16, 20, 20, 20, 16, 16, 16, 16, 16, 20, 20, 20,
314   16, 16, 16, 16, 16, 20, 20, 20, 16, 16, 16, 16, 16, 20, 20, 20,
315   16, 16, 16, 16, 16, 20, 20, 20, 16, 16, 16, 16, 16, 20, 20, 20,
316   16, 16, 16, 16, 16, 20, 20, 20, 16, 16, 16, 16, 16, 20, 20, 20,
317
318   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
319   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
320   20, 20, 20, 20,  1,  1,  1,  1, 20, 20, 20, 20,  1,  1,  1,  1,
321    1,  1,  1,  1,  1,  1,  1,  1, 20, 20, 20, 20,  1,  1,  1,  1,
322
323   12, 12, 20, 16, 12, 12, 20, 16, 12, 12, 20, 16, 12, 12, 20, 16,
324   12, 12, 20, 16, 12, 12, 20, 16, 12, 12, 20, 16, 12, 12, 20, 16,
325   12, 12, 20, 16, 12, 12, 20, 16, 12,  1,  1,  1,  1,  1,  8,  8,
326   12, 12, 12,  1, 12, 12, 12,  1, 20, 20, 20, 20, 12, 12, 12,  1,
327
328    8,  8,  8, 12, 16, 12, 12, 12,  8,  8,  8,  8, 12,  8,  8,  8,
329   20, 20, 20, 20, 20, 20, 20, 20, 48, 52,  1,  1,  1,  1,  1,  1,
330   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
331   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
329332};
330333
331334
src/emu/cpu/minx/minxopcf.h
r2821r2822
121121OP(6E) { regs.SP = rdop16(); }
122122OP(6F) { /* illegal instruction? */ }
123123
124OP(70) { UINT8 ofs8 = rdop(); regs.BA = rd( regs.SP + ofs8 ); }
125OP(71) { UINT8 ofs8 = rdop(); regs.HL = rd( regs.SP + ofs8 ); }
126OP(72) { UINT8 ofs8 = rdop(); regs.X = rd( regs.SP + ofs8 ); }
127OP(73) { UINT8 ofs8 = rdop(); regs.Y = rd( regs.SP + ofs8 ); }
128OP(74) { UINT8 ofs8 = rdop(); wr( regs.SP + ofs8, regs.BA ); }
129OP(75) { UINT8 ofs8 = rdop(); wr( regs.SP + ofs8, regs.HL ); }
130OP(76) { UINT8 ofs8 = rdop(); wr( regs.SP + ofs8, regs.X ); }
131OP(77) { UINT8 ofs8 = rdop(); wr( regs.SP + ofs8, regs.Y ); }
124OP(70) { UINT8 ofs8 = rdop(); regs.BA = rd16( regs.SP + ofs8 ); }
125OP(71) { UINT8 ofs8 = rdop(); regs.HL = rd16( regs.SP + ofs8 ); }
126OP(72) { UINT8 ofs8 = rdop(); regs.X = rd16( regs.SP + ofs8 ); }
127OP(73) { UINT8 ofs8 = rdop(); regs.Y = rd16( regs.SP + ofs8 ); }
128OP(74) { UINT8 ofs8 = rdop(); wr16( regs.SP + ofs8, regs.BA ); }
129OP(75) { UINT8 ofs8 = rdop(); wr16( regs.SP + ofs8, regs.HL ); }
130OP(76) { UINT8 ofs8 = rdop(); wr16( regs.SP + ofs8, regs.X ); }
131OP(77) { UINT8 ofs8 = rdop(); wr16( regs.SP + ofs8, regs.Y ); }
132132OP(78) { AD2_I16; regs.SP = rd16( addr2 ); }
133133OP(79) { /* illegal instruction? */ }
134134OP(7A) { /* illegal instruction? */ }
r2821r2822
310310};
311311
312312static const int insnminx_cycles_CF[256] = {
313        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
314        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
315        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
316        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
317        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
318        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
319        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
320        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
321        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
322        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
323        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
324        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
325        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
326        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
327        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
328        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
313   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
314    1,  1,  1,  1,  1,  1,  1,  1, 16, 16, 16, 16,  1,  1,  1,  1,
315   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
316    1,  1,  1,  1,  1,  1,  1,  1, 16, 16, 16, 16,  1,  1,  1,  1,
317
318   16, 16, 16, 16, 16, 16,  1,  1, 16, 16, 16, 16, 16, 16,  1,  1,
319    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 16, 16,  1,  1,
320   16, 16, 16, 16,  1,  1,  1,  1, 16,  1, 16,  1, 16,  1, 16,  1,
321   24, 24, 24, 24, 24, 24, 24, 24, 24,  1,  1,  1, 24,  1,  1,  1,
322
323    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
324    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
325    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
326   12, 12, 12, 12, 12, 12, 12, 12, 48, 60,  1,  1, 32, 40,  1,  1,
327
328   20, 20, 20, 20, 20, 20, 20, 20,  1,  1,  1,  1,  1,  1,  1,  1,
329   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
330    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
331    8,  8,  8,  8,  8,  8,  1,  1,  8,  8,  8,  1,  1,  1,  8,  1
329332};
330333
src/emu/cpu/minx/minx.c
r2821r2822
3737
3838TODO:
3939- Add support for O and C flags in NEG8 instruction
40- Add support for CE D8 (MUL) and CE D9 (DIV)
41- Add support for CF xx instructions
40- Verify MUL (CE D8) and DIV (CE D9)
4241- Doublecheck behaviour of CMPN instructions ( CF 60 .. CF 63 )
43- Figure out the number of cycles taken by each instruction (this
44  information is currently not known/available).
4542
4643*/
4744
r2821r2822
6966
7067typedef struct {
7168//  MINX_CONFIG  config;
72   UINT16 PC;
73   UINT16 SP;
74   UINT16 BA;
75   UINT16 HL;
76   UINT16 X;
77   UINT16 Y;
78   UINT8  U;
79   UINT8  V;
80   UINT8  F;
81   UINT8  E;
82   UINT8  N;
83   UINT8  I;
84   UINT8  XI;
85   UINT8  YI;
86   UINT8  check_interrupt;
69   UINT16   PC;
70   UINT16   SP;
71   UINT16   BA;
72   UINT16   HL;
73   UINT16   X;
74   UINT16   Y;
75   UINT8   U;
76   UINT8   V;
77   UINT8   F;
78   UINT8   E;
79   UINT8   N;
80   UINT8   I;
81   UINT8   XI;
82   UINT8   YI;
83   UINT8   halted;
84   UINT8   interrupt_pending;
85   int      (*irq_callback)(int irqline);
8786} minx_regs;
8887
8988static minx_regs regs;
9089static int minx_icount;
9190
92#define rd(offset)   program_read_byte_8be( offset )
93#define wr(offset,data)   program_write_byte_8be( offset, data )
94#define minx_PC      ( ( regs.PC & 0x8000 ) ? ( regs.V << 15 ) | (regs.PC & 0x7FFF ) : regs.PC )
91#define RD(offset)      program_read_byte_8be( offset )
92#define WR(offset,data)   program_write_byte_8be( offset, data )
93#define GET_MINX_PC      ( ( regs.PC & 0x8000 ) ? ( regs.V << 15 ) | (regs.PC & 0x7FFF ) : regs.PC )
9594
96INLINE UINT16 rd16( UINT32 offset ) {
97   return rd( offset ) | ( rd( offset + 1 ) << 8 );
95
96INLINE UINT16 rd16( UINT32 offset )
97{
98   return RD( offset ) | ( RD( offset + 1 ) << 8 );
9899}
99100
100INLINE void wr16( UINT32 offset, UINT16 data ) {
101   wr( offset, ( data & 0x00FF ) );
102   wr( offset + 1, ( data >> 8 ) );
101
102INLINE void wr16( UINT32 offset, UINT16 data )
103{
104   WR( offset, ( data & 0x00FF ) );
105   WR( offset + 1, ( data >> 8 ) );
103106}
104107
105static void minx_init(int index, int clock, const void *config, int (*irqcallback)(int)) {
106   if ( config != NULL ) {
107   } else {
108
109static void minx_init(int index, int clock, const void *config, int (*irqcallback)(int))
110{
111   regs.irq_callback = irqcallback;
112   if ( config != NULL )
113   {
108114   }
115   else
116   {
117   }
109118}
110119
111static void minx_reset( void ) {
112   memset( &regs, 0, sizeof(regs) );
113   regs.PC = ( rd( 1 ) << 8 ) | rd( 0 );
120
121static void minx_reset( void )
122{
123   regs.SP = regs.BA = regs.HL = regs.X = regs.Y = 0;
124   regs.U = regs.V = regs.F = regs.E = regs.I = regs.XI = regs.YI = 0;
125   regs.halted = regs.interrupt_pending = 0;
126
127   regs.PC = rd16( 0 );
114128   change_pc( regs.PC );
115129}
116130
117static void minx_exit( void ) {
131
132static void minx_exit( void )
133{
118134}
119135
120INLINE UINT8 rdop( void ) {
121   UINT8 op = rd( minx_PC );
136
137INLINE UINT8 rdop( void )
138{
139   UINT8 op = RD( GET_MINX_PC );
122140   regs.PC++;
123141   return op;
124142}
125143
126INLINE UINT16 rdop16( void ) {
144
145INLINE UINT16 rdop16( void )
146{
127147   UINT16 op = rdop();
128148   op = op | ( rdop() << 8 );
129149   return op;
130150}
131151
152
132153#include "minxfunc.h"
133154#include "minxopce.h"
134155#include "minxopcf.h"
135156#include "minxops.h"
136157
137static int minx_execute( int cycles ) {
158
159static int minx_execute( int cycles )
160{
138161   UINT32   oldpc;
139162   UINT8   op;
140163
141164   minx_icount = cycles;
142165
143   do {
144      CALL_DEBUGGER(minx_PC);
145      oldpc = minx_PC;
146      op = rdop();
147      insnminx[op]();
148      minx_icount -= insnminx_cycles[op];
166   do
167   {
168      CALL_DEBUGGER(GET_MINX_PC);
169      oldpc = GET_MINX_PC;
170
171      if ( regs.interrupt_pending )
172      {
173         regs.halted = 0;
174         if ( ! ( regs.F & 0xc0 ) )
175         {
176            //logerror("minx_execute(): taking IRQ\n");
177            PUSH8( regs.V );
178            PUSH16( regs.PC );
179            PUSH8( regs.F );
180
181            /* Set Interrupt Branch flag */
182            regs.F |= 0x80;
183            regs.V = 0;
184            regs.PC = rd16( regs.irq_callback( 0 ) << 1 );
185            minx_icount -= 28;      /* This cycle count is a guess */
186         }
187      }
188
189      if ( regs.halted )
190      {
191         minx_icount -= insnminx_cycles_CE[0xAE];
192      }
193      else
194      {
195         op = rdop();
196         insnminx[op]();
197         minx_icount -= insnminx_cycles[op];
198      }
149199   } while ( minx_icount > 0 );
150200   return cycles - minx_icount;
151201}
152202
153static void minx_burn( int cycles ) {
203
204static void minx_burn( int cycles )
205{
154206   minx_icount = 0;
155207}
156208
157static void minx_set_context( void *src ) {
209
210static void minx_set_context( void *src )
211{
158212}
159213
160static void minx_get_context( void *dst ) {
214
215static void minx_get_context( void *dst )
216{
161217}
162218
163static unsigned minx_get_reg( int regnum ) {
164   switch( regnum ) {
165   case REG_PC:   return (regs.PC & 0x8000) ? ( regs.V << 15 ) | ( regs.PC & 0x7FFF ) : regs.PC;
219
220static unsigned minx_get_reg( int regnum )
221{
222   switch( regnum )
223   {
224   case REG_PC:   return GET_MINX_PC;
166225   case MINX_PC:   return regs.PC;
167226   case REG_SP:
168227   case MINX_SP:   return regs.SP;
r2821r2822
182241   return 0;
183242}
184243
185static void minx_set_reg( int regnum, unsigned val ) {
186   switch( regnum ) {
187   case REG_PC:
244
245static void minx_set_reg( int regnum, unsigned val )
246{
247   switch( regnum )
248   {
249   case REG_PC:   break;
188250   case MINX_PC:   regs.PC = val; break;
189251   case REG_SP:
190252   case MINX_SP:   regs.SP = val; break;
r2821r2822
203265   }
204266}
205267
206static void minx_set_irq_line( int irqline, int state ) {
207   if ( state == ASSERT_LINE ) {
208   } else {
268
269static void minx_set_irq_line( int irqline, int state )
270{
271   if ( state == ASSERT_LINE )
272   {
273      regs.interrupt_pending = 1;
209274   }
275   else
276   {
277      regs.interrupt_pending = 0;
278   }
210279}
211280
212static void minx_set_info( UINT32 state, cpuinfo *info ) {
213   switch( state ) {
281
282static void minx_set_info( UINT32 state, cpuinfo *info )
283{
284   switch( state )
285   {
214286   case CPUINFO_INT_INPUT_STATE + 0:
215287      minx_set_irq_line( state - CPUINFO_INT_INPUT_STATE, info->i ); break;
216288
r2821r2822
232304   }
233305}
234306
235void minx_get_info( UINT32 state, cpuinfo *info ) {
236   switch( state ) {
237   case CPUINFO_INT_CONTEXT_SIZE:            info->i = sizeof(minx_regs); break;
238   case CPUINFO_INT_INPUT_LINES:            info->i = 1; break;
239   case CPUINFO_INT_DEFAULT_IRQ_VECTOR:         info->i = 0xff; break;
240   case CPUINFO_INT_ENDIANNESS:            info->i = CPU_IS_BE; break;
241   case CPUINFO_INT_CLOCK_MULTIPLIER:         info->i = 1; break;
242   case CPUINFO_INT_CLOCK_DIVIDER:            info->i = 1; break;
243   case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 1; break;
244   case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 5; break;
245   case CPUINFO_INT_MIN_CYCLES:            info->i = 1; break;
246   case CPUINFO_INT_MAX_CYCLES:            info->i = 4; break;
247   case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 8; break;
248   case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 23; break;
249   case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
250   case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA:   info->i = 0; break;
251   case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA:   info->i = 0; break;
252   case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA:   info->i = 0; break;
253   case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO:   info->i = 0; break;
254   case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO:   info->i = 0; break;
255   case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO:   info->i = 0; break;
256   case CPUINFO_INT_INPUT_STATE + 0:         info->i = 0; break;
257   case CPUINFO_INT_REGISTER + REG_PC:
307
308void minx_get_info( UINT32 state, cpuinfo *info )
309{
310   switch( state )
311   {
312   case CPUINFO_INT_CONTEXT_SIZE:                        info->i = sizeof(minx_regs); break;
313   case CPUINFO_INT_INPUT_LINES:                        info->i = 1; break;
314   case CPUINFO_INT_DEFAULT_IRQ_VECTOR:                  info->i = 0x00; break;
315   case CPUINFO_INT_ENDIANNESS:                        info->i = CPU_IS_BE; break;
316   case CPUINFO_INT_CLOCK_MULTIPLIER:                     info->i = 1; break;
317   case CPUINFO_INT_CLOCK_DIVIDER:                        info->i = 1; break;
318   case CPUINFO_INT_MIN_INSTRUCTION_BYTES:                  info->i = 1; break;
319   case CPUINFO_INT_MAX_INSTRUCTION_BYTES:                  info->i = 5; break;
320   case CPUINFO_INT_MIN_CYCLES:                        info->i = 1; break;
321   case CPUINFO_INT_MAX_CYCLES:                        info->i = 4; break;
322   case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:      info->i = 8; break;
323   case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM:      info->i = 24; break;
324   case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM:      info->i = 0; break;
325   case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA:      info->i = 0; break;
326   case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA:      info->i = 0; break;
327   case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA:      info->i = 0; break;
328   case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO:         info->i = 0; break;
329   case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO:         info->i = 0; break;
330   case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO:         info->i = 0; break;
331   case CPUINFO_INT_INPUT_STATE + 0:                     info->i = 0; break;
332   case CPUINFO_INT_REGISTER + REG_PC:                     info->i = GET_MINX_PC; break;
258333   case CPUINFO_INT_REGISTER + REG_SP:
259334   case CPUINFO_INT_REGISTER + MINX_PC:
260335   case CPUINFO_INT_REGISTER + MINX_SP:
r2821r2822
269344   case CPUINFO_INT_REGISTER + MINX_N:
270345   case CPUINFO_INT_REGISTER + MINX_I:
271346   case CPUINFO_INT_REGISTER + MINX_XI:
272   case CPUINFO_INT_REGISTER + MINX_YI:         info->i = minx_get_reg( state - CPUINFO_INT_REGISTER ); break;
273   case CPUINFO_INT_PREVIOUSPC:            info->i = 0x0000; break;
274   case CPUINFO_PTR_SET_INFO:            info->setinfo = minx_set_info; break;
275   case CPUINFO_PTR_GET_CONTEXT:            info->getcontext = minx_get_context; break;
276   case CPUINFO_PTR_SET_CONTEXT:            info->setcontext = minx_set_context; break;
277   case CPUINFO_PTR_INIT:               info->init = minx_init; break;
278   case CPUINFO_PTR_RESET:               info->reset = minx_reset; break;
279   case CPUINFO_PTR_EXIT:               info->exit = minx_exit; break;
280   case CPUINFO_PTR_EXECUTE:            info->execute = minx_execute; break;
281   case CPUINFO_PTR_BURN:               info->burn = minx_burn; break;
347   case CPUINFO_INT_REGISTER + MINX_YI:                  info->i = minx_get_reg( state - CPUINFO_INT_REGISTER ); break;
348   case CPUINFO_INT_PREVIOUSPC:                        info->i = 0x0000; break;
349   case CPUINFO_PTR_SET_INFO:                           info->setinfo = minx_set_info; break;
350   case CPUINFO_PTR_GET_CONTEXT:                        info->getcontext = minx_get_context; break;
351   case CPUINFO_PTR_SET_CONTEXT:                        info->setcontext = minx_set_context; break;
352   case CPUINFO_PTR_INIT:                              info->init = minx_init; break;
353   case CPUINFO_PTR_RESET:                              info->reset = minx_reset; break;
354   case CPUINFO_PTR_EXIT:                              info->exit = minx_exit; break;
355   case CPUINFO_PTR_EXECUTE:                           info->execute = minx_execute; break;
356   case CPUINFO_PTR_BURN:                              info->burn = minx_burn; break;
282357#ifdef ENABLE_DEBUGGER
283   case CPUINFO_PTR_DISASSEMBLE:            info->disassemble = minx_dasm; break;
358   case CPUINFO_PTR_DISASSEMBLE:                        info->disassemble = minx_dasm; break;
284359#endif
285   case CPUINFO_PTR_INSTRUCTION_COUNTER:         info->icount = &minx_icount; break;
286   case CPUINFO_STR_NAME:               strcpy( info->s = cpuintrf_temp_str(), "Minx" ); break;
287   case CPUINFO_STR_CORE_FAMILY:            strcpy( info->s = cpuintrf_temp_str(), "Nintendo Minx" ); break;
288   case CPUINFO_STR_CORE_VERSION:            strcpy( info->s = cpuintrf_temp_str(), "0.1" ); break;
289   case CPUINFO_STR_CORE_FILE:            strcpy( info->s = cpuintrf_temp_str(), __FILE__ ); break;
290   case CPUINFO_STR_CORE_CREDITS:            strcpy( info->s = cpuintrf_temp_str(), "Copyright The MESS Team." ); break;
360   case CPUINFO_PTR_INSTRUCTION_COUNTER:                  info->icount = &minx_icount; break;
361   case CPUINFO_STR_NAME:                              strcpy( info->s = cpuintrf_temp_str(), "Minx" ); break;
362   case CPUINFO_STR_CORE_FAMILY:                        strcpy( info->s = cpuintrf_temp_str(), "Nintendo Minx" ); break;
363   case CPUINFO_STR_CORE_VERSION:                        strcpy( info->s = cpuintrf_temp_str(), "0.1" ); break;
364   case CPUINFO_STR_CORE_FILE:                           strcpy( info->s = cpuintrf_temp_str(), __FILE__ ); break;
365   case CPUINFO_STR_CORE_CREDITS:                        strcpy( info->s = cpuintrf_temp_str(), "Copyright The MESS Team." ); break;
291366   case CPUINFO_STR_FLAGS:
292367      sprintf( info->s = cpuintrf_temp_str(), "%c%c%c%c%c%c%c%c-%c%c%c%c%c",
293368         regs.F & FLAG_I ? 'I' : '.',
r2821r2822
304379         regs.E & EXEC_DZ ? 'z' : '.',
305380         regs.E & EXEC_EN ? 'E' : '.' );
306381      break;
307   case CPUINFO_STR_REGISTER + MINX_PC:         sprintf( info->s = cpuintrf_temp_str(), "PC:%04X", regs.PC ); break;
308   case CPUINFO_STR_REGISTER + MINX_SP:         sprintf( info->s = cpuintrf_temp_str(), "SP:%04X", regs.SP ); break;
309   case CPUINFO_STR_REGISTER + MINX_BA:         sprintf( info->s = cpuintrf_temp_str(), "BA:%04X", regs.BA ); break;
310   case CPUINFO_STR_REGISTER + MINX_HL:         sprintf( info->s = cpuintrf_temp_str(), "HL:%04X", regs.HL ); break;
311   case CPUINFO_STR_REGISTER + MINX_X:         sprintf( info->s = cpuintrf_temp_str(), "X:%04X", regs.X ); break;
312   case CPUINFO_STR_REGISTER + MINX_Y:         sprintf( info->s = cpuintrf_temp_str(), "Y:%04X", regs.Y ); break;
313   case CPUINFO_STR_REGISTER + MINX_U:         sprintf( info->s = cpuintrf_temp_str(), "U:%02X", regs.U ); break;
314   case CPUINFO_STR_REGISTER + MINX_V:         sprintf( info->s = cpuintrf_temp_str(), "V:%02X", regs.V ); break;
315   case CPUINFO_STR_REGISTER + MINX_F:         sprintf( info->s = cpuintrf_temp_str(), "F:%02X", regs.F ); break;
316   case CPUINFO_STR_REGISTER + MINX_E:         sprintf( info->s = cpuintrf_temp_str(), "E:%02X", regs.E ); break;
317   case CPUINFO_STR_REGISTER + MINX_N:         sprintf( info->s = cpuintrf_temp_str(), "N:%02X", regs.N ); break;
318   case CPUINFO_STR_REGISTER + MINX_I:         sprintf( info->s = cpuintrf_temp_str(), "I:%02X", regs.I ); break;
319   case CPUINFO_STR_REGISTER + MINX_XI:         sprintf( info->s = cpuintrf_temp_str(), "XI:%02X", regs.XI ); break;
320   case CPUINFO_STR_REGISTER + MINX_YI:         sprintf( info->s = cpuintrf_temp_str(), "YI:%02X", regs.YI ); break;
382   case CPUINFO_STR_REGISTER + MINX_PC:                  sprintf( info->s = cpuintrf_temp_str(), "PC:%04X", regs.PC ); break;
383   case CPUINFO_STR_REGISTER + MINX_SP:                  sprintf( info->s = cpuintrf_temp_str(), "SP:%04X", regs.SP ); break;
384   case CPUINFO_STR_REGISTER + MINX_BA:                  sprintf( info->s = cpuintrf_temp_str(), "BA:%04X", regs.BA ); break;
385   case CPUINFO_STR_REGISTER + MINX_HL:                  sprintf( info->s = cpuintrf_temp_str(), "HL:%04X", regs.HL ); break;
386   case CPUINFO_STR_REGISTER + MINX_X:                     sprintf( info->s = cpuintrf_temp_str(), "X:%04X", regs.X ); break;
387   case CPUINFO_STR_REGISTER + MINX_Y:                     sprintf( info->s = cpuintrf_temp_str(), "Y:%04X", regs.Y ); break;
388   case CPUINFO_STR_REGISTER + MINX_U:                     sprintf( info->s = cpuintrf_temp_str(), "U:%02X", regs.U ); break;
389   case CPUINFO_STR_REGISTER + MINX_V:                     sprintf( info->s = cpuintrf_temp_str(), "V:%02X", regs.V ); break;
390   case CPUINFO_STR_REGISTER + MINX_F:                     sprintf( info->s = cpuintrf_temp_str(), "F:%02X", regs.F ); break;
391   case CPUINFO_STR_REGISTER + MINX_E:                     sprintf( info->s = cpuintrf_temp_str(), "E:%02X", regs.E ); break;
392   case CPUINFO_STR_REGISTER + MINX_N:                     sprintf( info->s = cpuintrf_temp_str(), "N:%02X", regs.N ); break;
393   case CPUINFO_STR_REGISTER + MINX_I:                     sprintf( info->s = cpuintrf_temp_str(), "I:%02X", regs.I ); break;
394   case CPUINFO_STR_REGISTER + MINX_XI:                  sprintf( info->s = cpuintrf_temp_str(), "XI:%02X", regs.XI ); break;
395   case CPUINFO_STR_REGISTER + MINX_YI:                  sprintf( info->s = cpuintrf_temp_str(), "YI:%02X", regs.YI ); break;
321396   }
322397}
323398
324
325
326
src/emu/cpu/minx/minxfunc.h
r2821r2822
11
2INLINE UINT8 ADD8( UINT8 arg1, UINT8 arg2 ) {
2INLINE UINT8 ADD8( UINT8 arg1, UINT8 arg2 )
3{
34   UINT32 res = arg1 + arg2;
45   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
56      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
1011   return res & 0xFF;
1112}
1213
13INLINE UINT16 ADD16( UINT16 arg1, UINT16 arg2 ) {
14
15INLINE UINT16 ADD16( UINT16 arg1, UINT16 arg2 )
16{
1417   UINT32 res = arg1 + arg2;
1518   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
1619      | ( ( res & 0x8000 ) ? FLAG_S : 0 )
r2821r2822
2124   return res & 0xFFFF;
2225}
2326
24INLINE UINT8 ADDC8( UINT8 arg1, UINT8 arg2 ) {
27
28INLINE UINT8 ADDC8( UINT8 arg1, UINT8 arg2 )
29{
2530        UINT32 res = arg1 + arg2 + ( ( regs.F & FLAG_C ) ? 1 : 0 );
2631   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
2732      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
3237   return res & 0xFF;
3338}
3439
35INLINE UINT16 ADDC16( UINT16 arg1, UINT16 arg2 ) {
40
41INLINE UINT16 ADDC16( UINT16 arg1, UINT16 arg2 )
42{
3643   UINT32 res = arg1 + arg2 + ( ( regs.F & FLAG_C ) ? 1 : 0 );
3744   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
3845      | ( ( res & 0x8000 ) ? FLAG_S : 0 )
r2821r2822
4350   return res & 0xFFFF;
4451}
4552
46INLINE UINT8 INC8( UINT8 arg ) {
47   return ADD8( arg, 1 );
53
54INLINE UINT8 INC8( UINT8 arg )
55{
56   UINT8 old_F = regs.F;
57   UINT8 res = ADD8( arg, 1 );
58   regs.F = ( old_F & ~ ( FLAG_Z ) )
59      | ( ( res ) ? 0 : FLAG_Z )
60   ;
61   return res;
4862}
4963
50INLINE UINT16 INC16( UINT16 arg ) {
51   return ADD16( arg, 1 );
64
65INLINE UINT16 INC16( UINT16 arg )
66{
67   UINT8 old_F = regs.F;
68   UINT16 res = ADD16( arg, 1 );
69   regs.F = ( old_F & ~ ( FLAG_Z ) )
70      | ( ( res ) ? 0 : FLAG_Z )
71   ;
72   return res;
5273}
5374
54INLINE UINT8 SUB8( UINT8 arg1, UINT8 arg2 ) {
75
76INLINE UINT8 SUB8( UINT8 arg1, UINT8 arg2 )
77{
5578   UINT32 res = arg1 - arg2;
5679   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
5780      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
6285   return res & 0xFF;
6386}
6487
65INLINE UINT16 SUB16( UINT16 arg1, UINT16 arg2 ) {
88
89INLINE UINT16 SUB16( UINT16 arg1, UINT16 arg2 )
90{
6691   UINT32 res = arg1 - arg2;
6792   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
6893      | ( ( res & 0x8000 ) ? FLAG_S : 0 )
r2821r2822
7398   return res & 0xFFFF;
7499}
75100
76INLINE UINT8 SUBC8( UINT8 arg1, UINT8 arg2 ) {
101
102INLINE UINT8 SUBC8( UINT8 arg1, UINT8 arg2 )
103{
77104   UINT32 res = arg1 - arg2 - ( ( regs.F & FLAG_C ) ? 1 : 0 );
78105   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
79106      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
84111   return res & 0xFF;
85112}
86113
87INLINE UINT16 SUBC16( UINT16 arg1, UINT16 arg2 ) {
114
115INLINE UINT16 SUBC16( UINT16 arg1, UINT16 arg2 )
116{
88117   UINT32 res = arg1 - arg2 - ( ( regs.F & FLAG_C ) ? 1 : 0 );
89118   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
90119      | ( ( res & 0x8000 ) ? FLAG_S : 0 )
r2821r2822
95124   return res & 0xFFFF;
96125}
97126
98INLINE UINT8 DEC8( UINT8 arg ) {
99   return SUB8( arg, 1 );
127
128INLINE UINT8 DEC8( UINT8 arg )
129{
130   UINT8 old_F = regs.F;
131   UINT8 res = SUB8( arg, 1 );
132   regs.F = ( old_F & ~ ( FLAG_Z ) )
133      | ( ( res ) ? 0 : FLAG_Z )
134   ;
135   return res;
100136}
101137
102INLINE UINT16 DEC16( UINT16 arg ) {
103   return SUB16( arg, 1 );
138
139INLINE UINT16 DEC16( UINT16 arg )
140{
141   UINT8 old_F = regs.F;
142   UINT16 res = SUB16( arg, 1 );
143   regs.F = ( old_F & ~ ( FLAG_Z ) )
144      | ( ( res ) ? 0 : FLAG_Z )
145   ;
146   return res;
104147}
105148
106INLINE UINT8 AND8( UINT8 arg1, UINT8 arg2 ) {
149
150INLINE UINT8 AND8( UINT8 arg1, UINT8 arg2 )
151{
107152   UINT8 res = arg1 & arg2;
153   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_Z ) )
154      | ( ( res & 0x80 ) ? FLAG_S : 0 )
155      | ( ( res ) ? 0 : FLAG_Z )
156   ;
108157   return res;
109158}
110159
111INLINE UINT8 OR8( UINT8 arg1, UINT8 arg2 ) {
160
161INLINE UINT8 OR8( UINT8 arg1, UINT8 arg2 )
162{
112163   UINT8 res = arg1 | arg2;
164   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_Z ) )
165      | ( ( res & 0x80 ) ? FLAG_S : 0 )
166      | ( ( res ) ? 0 : FLAG_Z )
167   ;
113168   return res;
114169}
115170
116INLINE UINT8 XOR8( UINT8 arg1, UINT8 arg2 ) {
171
172INLINE UINT8 XOR8( UINT8 arg1, UINT8 arg2 )
173{
117174   UINT8 res = arg1 ^ arg2;
175   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_Z ) )
176      | ( ( res & 0x80 ) ? FLAG_S : 0 )
177      | ( ( res ) ? 0 : FLAG_Z )
178   ;
118179   return res;
119180}
120181
121INLINE UINT8 NOT8( UINT8 arg ) {
182
183INLINE UINT8 NOT8( UINT8 arg )
184{
122185   UINT8 res = ~arg;
123186   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_Z ) )
124187      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
127190   return res;
128191}
129192
130INLINE UINT8 NEG8( UINT8 arg ) {
193
194INLINE UINT8 NEG8( UINT8 arg )
195{
131196   UINT8 res = -arg;
132197   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
133198      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
136201   return res;
137202}
138203
139INLINE UINT8 SAL8( UINT8 arg ) {
204
205INLINE UINT8 SAL8( UINT8 arg )
206{
140207   UINT16 res = arg << 1;
141208   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
142209      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
147214   return res;
148215}
149216
150INLINE UINT8 SAR8( UINT8 arg ) {
217
218INLINE UINT8 SAR8( UINT8 arg )
219{
151220   UINT16 res = ( arg >> 1 ) | ( arg & 0x80 );
152221   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_O | FLAG_C | FLAG_Z ) )
153222      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
158227   return res & 0xFF;
159228}
160229
161INLINE UINT8 SHL8( UINT8 arg ) {
230
231INLINE UINT8 SHL8( UINT8 arg )
232{
162233   UINT16 res = arg << 1;
163234   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_C | FLAG_Z ) )
164235      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
168239   return res;
169240}
170241
171INLINE UINT8 SHR8( UINT8 arg ) {
242
243INLINE UINT8 SHR8( UINT8 arg )
244{
172245   UINT16 res = arg >> 1;
173246   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_C | FLAG_Z ) )
174247      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
178251   return res & 0xFF;
179252}
180253
181INLINE UINT8 ROLC8( UINT8 arg ) {
254
255INLINE UINT8 ROLC8( UINT8 arg )
256{
182257   UINT16 res = ( arg << 1 ) | ( ( regs.F & FLAG_C ) ? 1 : 0 );
183258   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_C | FLAG_Z ) )
184259      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
188263   return res & 0xFF;
189264}
190265
191INLINE UINT8 RORC8( UINT8 arg ) {
266
267INLINE UINT8 RORC8( UINT8 arg )
268{
192269   UINT16 res = ( arg >> 1 ) | ( ( regs.F & FLAG_C ) ? 0x80 : 0 );
193270   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_C | FLAG_Z ) )
194271      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
198275   return res & 0xFF;
199276}
200277
201INLINE UINT8 ROL8( UINT8 arg ) {
278
279INLINE UINT8 ROL8( UINT8 arg )
280{
202281   UINT16 res = ( arg << 1 ) | ( ( arg & 0x80 ) ? 1 : 0 );
203282   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_C | FLAG_Z ) )
204283      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
208287   return res & 0xFF;
209288}
210289
211INLINE UINT8 ROR8( UINT8 arg ) {
290
291INLINE UINT8 ROR8( UINT8 arg )
292{
212293   UINT16 res = ( arg >> 1 ) | ( ( arg & 0x01 ) ? 0x80 : 0 );
213294   regs.F = ( regs.F & ~ ( FLAG_S | FLAG_C | FLAG_Z ) )
214295      | ( ( res & 0x80 ) ? FLAG_S : 0 )
r2821r2822
218299   return res & 0xFF;
219300}
220301
221INLINE void PUSH8( UINT8 arg ) {
302
303INLINE void PUSH8( UINT8 arg )
304{
222305   regs.SP = regs.SP - 1;
223   wr( regs.SP, arg );
306   WR( regs.SP, arg );
224307}
225308
226INLINE void PUSH16( UINT16 arg ) {
309
310INLINE void PUSH16( UINT16 arg )
311{
227312   PUSH8( arg >> 8 );
228313   PUSH8( arg & 0x00FF );
229314}
230315
231INLINE UINT8 POP8( void ) {
232   UINT8 res = rd( regs.SP );
316
317INLINE UINT8 POP8( void )
318{
319   UINT8 res = RD( regs.SP );
233320   regs.SP = regs.SP + 1;
234321   return res;
235322}
236323
237INLINE UINT16 POP16( void ) {
324
325INLINE UINT16 POP16( void )
326{
238327   return POP8() | ( POP8() << 8 );
239328}
240329
241INLINE void JMP( UINT16 arg ) {
330
331INLINE void JMP( UINT16 arg )
332{
242333   regs.V = regs.U;
243334   regs.PC = arg;
335   change_pc( GET_MINX_PC );
244336}
245337
246INLINE void CALL( UINT16 arg ) {
338
339INLINE void CALL( UINT16 arg )
340{
247341   PUSH8( regs.V );
248342   PUSH16( regs.PC );
249343   JMP( arg );
250344}
251345
252static UINT32 addr1, addr2;
253346
254#define AD1_IHL   addr1 = ( regs.I << 16 ) | regs.HL;
255#define AD1_IN8   addr1 = ( regs.I << 16 ) | ( regs.N << 8 ) | rdop();
256#define AD1_I16   addr1 = ( regs.I << 16 ) | rdop(); addr1 |= ( rdop() << 8 );
257#define AD1_XIX   addr1 = ( regs.XI << 16 ) | regs.X;
258#define AD1_YIY   addr1 = ( regs.YI << 16 ) | regs.Y;
259#define AD1_X8   addr1 = ( regs.XI << 16 ) | ( regs.X + rdop() );
260#define AD1_Y8   addr1 = ( regs.YI << 16 ) | ( regs.Y + rdop() );
261#define AD1_XL   addr1 = ( regs.XI << 16 ) | ( regs.X + ( regs.HL & 0x00FF ) );
262#define AD1_YL   addr1 = ( regs.YI << 16 ) | ( regs.Y + ( regs.HL & 0x00FF ) );
263#define AD2_IHL   addr2 = ( regs.I << 16 ) | regs.HL;
264#define AD2_IN8   addr2 = ( regs.I << 16 ) | ( regs.N << 8 ) | rdop();
265#define AD2_I16   addr2 = ( regs.I << 16 ) | rdop(); addr2 |= ( rdop() << 8 );
266#define AD2_XIX   addr2 = ( regs.XI << 16 ) | regs.X;
267#define AD2_YIY   addr2 = ( regs.YI << 16 ) | regs.Y;
268#define AD2_X8   addr2 = ( regs.XI << 16 ) | ( regs.X + rdop() );
269#define AD2_Y8   addr2 = ( regs.YI << 16 ) | ( regs.Y + rdop() );
270#define AD2_XL   addr2 = ( regs.XI << 16 ) | ( regs.X + ( regs.HL & 0x00FF ) );
271#define AD2_YL   addr2 = ( regs.YI << 16 ) | ( regs.Y + ( regs.HL & 0x00FF ) );
347#define AD1_IHL   UINT32 addr1 = ( regs.I << 16 ) | regs.HL
348#define AD1_IN8   UINT32 addr1 = ( regs.I << 16 ) | ( regs.N << 8 ) | rdop()
349#define AD1_I16   UINT32 addr1 = ( regs.I << 16 ) | rdop16()
350#define AD1_XIX   UINT32 addr1 = ( regs.XI << 16 ) | regs.X
351#define AD1_YIY   UINT32 addr1 = ( regs.YI << 16 ) | regs.Y
352#define AD1_X8   UINT32 addr1 = ( regs.XI << 16 ) | ( regs.X + rdop() )
353#define AD1_Y8   UINT32 addr1 = ( regs.YI << 16 ) | ( regs.Y + rdop() )
354#define AD1_XL   UINT32 addr1 = ( regs.XI << 16 ) | ( regs.X + ( regs.HL & 0x00FF ) )
355#define AD1_YL   UINT32 addr1 = ( regs.YI << 16 ) | ( regs.Y + ( regs.HL & 0x00FF ) )
356#define AD2_IHL   UINT32 addr2 = ( regs.I << 16 ) | regs.HL
357#define AD2_IN8   UINT32 addr2 = ( regs.I << 16 ) | ( regs.N << 8 ) | rdop()
358#define AD2_I16   UINT32 addr2 = ( regs.I << 16 ) | rdop(); addr2 |= ( rdop() << 8 )
359#define AD2_XIX   UINT32 addr2 = ( regs.XI << 16 ) | regs.X
360#define AD2_YIY   UINT32 addr2 = ( regs.YI << 16 ) | regs.Y
361#define AD2_X8   UINT32 addr2 = ( regs.XI << 16 ) | ( regs.X + rdop() )
362#define AD2_Y8   UINT32 addr2 = ( regs.YI << 16 ) | ( regs.Y + rdop() )
363#define AD2_XL   UINT32 addr2 = ( regs.XI << 16 ) | ( regs.X + ( regs.HL & 0x00FF ) )
364#define AD2_YL   UINT32 addr2 = ( regs.YI << 16 ) | ( regs.Y + ( regs.HL & 0x00FF ) )
272365
src/emu/cpu/drcuml.h
r2821r2822
142142/* floating point modes */
143143enum
144144{
145   DRCUML_FMOD_TRUNC,      /* truncate */
145   DRCUML_FMOD_TRUNC = 0,   /* truncate */
146146   DRCUML_FMOD_ROUND,      /* round */
147147   DRCUML_FMOD_CEIL,      /* round up */
148   DRCUML_FMOD_FLOOR      /* round down */
148   DRCUML_FMOD_FLOOR,      /* round down */
149   DRCUML_FMOD_DEFAULT
149150};
150151
151152
153/* sizes */
154enum
155{
156   DRCUML_SIZE_BYTE = 0,   /* 1-byte */
157   DRCUML_SIZE_WORD,      /* 2-byte */
158   DRCUML_SIZE_DWORD,      /* 4-byte */
159   DRCUML_SIZE_QWORD,      /* 8-byte */
160   DRCUML_SIZE_SHORT = DRCUML_SIZE_DWORD,
161   DRCUML_SIZE_DOUBLE = DRCUML_SIZE_QWORD
162};
163
164
165/* size/space combinations */
166enum
167{
168   DRCUML_SPSIZE_PROGRAM_BYTE = (ADDRESS_SPACE_PROGRAM * 16) + DRCUML_SIZE_BYTE,
169   DRCUML_SPSIZE_PROGRAM_WORD = (ADDRESS_SPACE_PROGRAM * 16) + DRCUML_SIZE_WORD,
170   DRCUML_SPSIZE_PROGRAM_DWORD = (ADDRESS_SPACE_PROGRAM * 16) + DRCUML_SIZE_DWORD,
171   DRCUML_SPSIZE_PROGRAM_QWORD = (ADDRESS_SPACE_PROGRAM * 16) + DRCUML_SIZE_QWORD,
172   DRCUML_SPSIZE_DATA_BYTE = (ADDRESS_SPACE_DATA * 16) + DRCUML_SIZE_BYTE,
173   DRCUML_SPSIZE_DATA_WORD = (ADDRESS_SPACE_DATA * 16) + DRCUML_SIZE_WORD,
174   DRCUML_SPSIZE_DATA_DWORD = (ADDRESS_SPACE_DATA * 16) + DRCUML_SIZE_DWORD,
175   DRCUML_SPSIZE_DATA_QWORD = (ADDRESS_SPACE_DATA * 16) + DRCUML_SIZE_QWORD,
176   DRCUML_SPSIZE_IO_BYTE = (ADDRESS_SPACE_IO * 16) + DRCUML_SIZE_BYTE,
177   DRCUML_SPSIZE_IO_WORD = (ADDRESS_SPACE_IO * 16) + DRCUML_SIZE_WORD,
178   DRCUML_SPSIZE_IO_DWORD = (ADDRESS_SPACE_IO * 16) + DRCUML_SIZE_DWORD,
179   DRCUML_SPSIZE_IO_QWORD = (ADDRESS_SPACE_IO * 16) + DRCUML_SIZE_QWORD
180};
181
182
152183/* these define the opcodes for the UML */
153184enum _drcuml_opcode
154185{
r2821r2822
175206   /* Internal Register Operations */
176207   DRCUML_OP_SETFMOD,      /* SETFMOD src                    */
177208   DRCUML_OP_GETFMOD,      /* GETFMOD dst                    */
178   DRCUML_OP_GETEXP,      /* GETEXP  dst,index              */
209   DRCUML_OP_GETEXP,      /* GETEXP  dst                    */
210   DRCUML_OP_GETFLGS,      /* GETFLGS dst[,f]                */
179211   DRCUML_OP_SAVE,         /* SAVE    mem                    */
180212   DRCUML_OP_RESTORE,      /* RESTORE mem                    */
181213
182214   /* Integer Operations */
183   DRCUML_OP_LOAD1U,      /* LOAD1U  dst,base,index         */
184   DRCUML_OP_LOAD1S,      /* LOAD1S  dst,base,index         */
185   DRCUML_OP_LOAD2U,      /* LOAD2U  dst,base,index         */
186   DRCUML_OP_LOAD2S,      /* LOAD2S  dst,base,index         */
187   DRCUML_OP_LOAD4U,      /* LOAD4U  dst,base,index         */
188   DRCUML_OP_LOAD4S,      /* LOAD4S  dst,base,index         */
189   DRCUML_OP_LOAD8U,      /* LOAD8U  dst,base,index         */
190   DRCUML_OP_STORE1,      /* STORE1  base,index,src         */
191   DRCUML_OP_STORE2,      /* STORE2  base,index,src         */
192   DRCUML_OP_STORE4,      /* STORE4  base,index,src         */
193   DRCUML_OP_STORE8,      /* STORE8  base,index,src         */
194   DRCUML_OP_READ1U,      /* READ1U  dst,space,src1         */
195   DRCUML_OP_READ1S,      /* READ1S  dst,space,src1         */
196   DRCUML_OP_READ2U,      /* READ2U  dst,space,src1         */
197   DRCUML_OP_READ2S,      /* READ2S  dst,space,src1         */
198   DRCUML_OP_READ2M,      /* READ2M  dst,space,src1,mask    */
199   DRCUML_OP_READ4U,      /* READ4U  dst,space,src1         */
200   DRCUML_OP_READ4S,      /* READ4S  dst,space,src1         */
201   DRCUML_OP_READ4M,      /* READ4M  dst,space,src1,mask    */
202   DRCUML_OP_READ8U,      /* READ8U  dst,space,src1         */
203   DRCUML_OP_READ8M,      /* READ8M  dst,space,src1,mask    */
204   DRCUML_OP_WRITE1,      /* WRITE1  space,dst,src1         */
205   DRCUML_OP_WRITE2,      /* WRITE2  space,dst,src1         */
206   DRCUML_OP_WRIT2M,      /* WRIT2M  space,dst,mask,src1    */
207   DRCUML_OP_WRITE4,      /* WRITE4  space,dst,src1         */
208   DRCUML_OP_WRIT4M,      /* WRIT4M  space,dst,mask,src1    */
209   DRCUML_OP_WRITE8,      /* WRITE8  space,dst,src1         */
210   DRCUML_OP_WRIT8M,      /* WRIT8M  space,dst,mask,src1    */
211   DRCUML_OP_SETC,         /* SETC    src,bitnum             */
212   DRCUML_OP_FLAGS,      /* FLAGS   dst,mask,table         */
215   DRCUML_OP_LOAD,         /* LOAD    dst,base,index,size    */
216   DRCUML_OP_LOADS,      /* LOADS   dst,base,index,size    */
217   DRCUML_OP_STORE,      /* STORE   base,index,src,size    */
218   DRCUML_OP_READ,         /* READ    dst,src1,space/size    */
219   DRCUML_OP_READM,      /* READM   dst,src1,mask,space/size */
220   DRCUML_OP_WRITE,      /* WRITE   dst,src1,space/size    */
221   DRCUML_OP_WRITEM,      /* WRITEM  dst,mask,src1,space/size */
222   DRCUML_OP_CARRY,      /* CARRY   src,bitnum             */
223   DRCUML_OP_SET,         /* SET     dst,c                  */
213224   DRCUML_OP_MOV,         /* MOV     dst,src[,c]            */
214   DRCUML_OP_ZEXT1,      /* ZEXT1   dst,src                */
215   DRCUML_OP_ZEXT2,      /* ZEXT2   dst,src                */
216   DRCUML_OP_ZEXT4,      /* ZEXT4   dst,src                */
217   DRCUML_OP_SEXT1,      /* SEXT1   dst,src                */
218   DRCUML_OP_SEXT2,      /* SEXT2   dst,src                */
219   DRCUML_OP_SEXT4,      /* SEXT4   dst,src                */
220   DRCUML_OP_XTRACT,      /* XTRACT  dst,src,shift,mask     */
221   DRCUML_OP_INSERT,      /* INSERT  dst,src,shift,mask     */
225   DRCUML_OP_SEXT,         /* SEXT    dst,src,size           */
226   DRCUML_OP_ROLAND,      /* ROLAND  dst,src,shift,mask     */
227   DRCUML_OP_ROLINS,      /* ROLINS  dst,src,shift,mask     */
222228   DRCUML_OP_ADD,         /* ADD     dst,src1,src2[,f]      */
223229   DRCUML_OP_ADDC,         /* ADDC    dst,src1,src2[,f]      */
224230   DRCUML_OP_SUB,         /* SUB     dst,src1,src2[,f]      */
r2821r2822
247253   DRCUML_OP_FSTORE,      /* FSTORE  base,index,src         */
248254   DRCUML_OP_FREAD,      /* FREAD   dst,space,src1         */
249255   DRCUML_OP_FWRITE,      /* FWRITE  space,dst,src1         */
250   DRCUML_OP_FMOV,         /* FSMOV   dst,src1[,c]           */
251   DRCUML_OP_FTOI4,      /* FTOI4   dst,src1               */
252   DRCUML_OP_FTOI4T,      /* FTOI4T  dst,src1               */
253   DRCUML_OP_FTOI4R,      /* FTOI4R  dst,src1               */
254   DRCUML_OP_FTOI4F,      /* FTOI4F  dst,src1               */
255   DRCUML_OP_FTOI4C,      /* FTOI4C  dst,src1               */
256   DRCUML_OP_FTOI8,      /* FTOI8   dst,src1               */
257   DRCUML_OP_FTOI8T,      /* FTOI8T  dst,src1               */
258   DRCUML_OP_FTOI8R,      /* FTOI8R  dst,src1               */
259   DRCUML_OP_FTOI8F,      /* FTOI8F  dst,src1               */
260   DRCUML_OP_FTOI8C,      /* FTOI8C  dst,src1               */
261   DRCUML_OP_FFRFS,      /* FFRFS   dst,src1               */
262   DRCUML_OP_FFRFD,      /* FFRFD   dst,src1               */
263   DRCUML_OP_FFRI4,      /* FFRI4   dst,src1               */
264   DRCUML_OP_FFRI8,      /* FFRI8   dst,src1               */
256   DRCUML_OP_FMOV,         /* FMOV    dst,src1[,c]           */
257   DRCUML_OP_FTOINT,      /* FTOINT  dst,src1,size,round    */
258   DRCUML_OP_FFRINT,      /* FFRINT  dst,src1,size          */
259   DRCUML_OP_FFRFLT,      /* FFRFLT  dst,src1,size          */
260   DRCUML_OP_FRNDS,      /* FRNDS   dst,src1               */
265261   DRCUML_OP_FADD,         /* FADD    dst,src1,src2          */
266262   DRCUML_OP_FSUB,         /* FSUB    dst,src1,src2          */
267263   DRCUML_OP_FCMP,         /* FCMP    src1,src2              */
src/emu/cpu/i386/i386dasm.c
r2821r2822
17641764            switch ((op2 >> 3) & 0x7)
17651765            {
17661766               case 0: sprintf(s, "fild    dword ptr %s", modrm_string); break;
1767               case 1: sprintf(s, "??? (FPU)"); break;
1767               case 1: sprintf(s, "fisttp dword ptr %s", modrm_string); break;
17681768               case 2: sprintf(s, "fist    dword ptr %s", modrm_string); break;
17691769               case 3: sprintf(s, "fistp   dword ptr %s", modrm_string); break;
17701770               case 4: sprintf(s, "??? (FPU)"); break;
r2821r2822
18611861            switch ((op2 >> 3) & 0x7)
18621862            {
18631863               case 0: sprintf(s, "fld     qword ptr %s", modrm_string); break;
1864               case 1: sprintf(s, "??? (FPU)"); break;
1864               case 1: sprintf(s, "fisttp qword ptr %s", modrm_string); break;
18651865               case 2: sprintf(s, "fst     qword ptr %s", modrm_string); break;
18661866               case 3: sprintf(s, "fstp    qword ptr %s", modrm_string); break;
18671867               case 4: sprintf(s, "frstor  %s", modrm_string); break;
r2821r2822
19541954            switch ((op2 >> 3) & 0x7)
19551955            {
19561956               case 0: sprintf(s, "fild    word ptr %s", modrm_string); break;
1957               case 1: sprintf(s, "??? (FPU)"); break;
1957               case 1: sprintf(s, "fisttp word ptr %s", modrm_string); break;
19581958               case 2: sprintf(s, "fist    word ptr %s", modrm_string); break;
19591959               case 3: sprintf(s, "fistp   word ptr %s", modrm_string); break;
19601960               case 4: sprintf(s, "fbld    %s", modrm_string); break;
src/emu/cpu/drcbex64.c
r2821r2822
1818
1919    * Identify common pairs and optimize output
2020
21    * Convert AND 0xff/0xffff to movzx
22
2123****************************************************************************
2224
2325    -------------------------
r2821r2822
396398static x86code *op_setfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
397399static x86code *op_getfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
398400static x86code *op_getexp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
401static x86code *op_getflgs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
399402static x86code *op_save(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
400403static x86code *op_restore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
401404
402static x86code *op_load1u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
403static x86code *op_load1s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
404static x86code *op_load2u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
405static x86code *op_load2s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
406static x86code *op_load4u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
407static x86code *op_load4s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
408static x86code *op_load8u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
409static x86code *op_store1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
410static x86code *op_store2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
411static x86code *op_store4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
412static x86code *op_store8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
413static x86code *op_read1u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
414static x86code *op_read1s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
415static x86code *op_read2u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
416static x86code *op_read2s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
417static x86code *op_read2m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
418static x86code *op_read4u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
419static x86code *op_read4s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
420static x86code *op_read4m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
421static x86code *op_read8u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
422static x86code *op_read8m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
423static x86code *op_write1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
424static x86code *op_write2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
425static x86code *op_writ2m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
426static x86code *op_write4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
427static x86code *op_writ4m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
428static x86code *op_write8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
429static x86code *op_writ8m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
430static x86code *op_flags(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
431static x86code *op_setc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
405static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
406static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
407static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
408static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
409static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
410static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
411static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
412static x86code *op_carry(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
413static x86code *op_set(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
432414static x86code *op_mov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
433static x86code *op_zext1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
434static x86code *op_zext2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
435static x86code *op_zext4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
436static x86code *op_sext1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
437static x86code *op_sext2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
438static x86code *op_sext4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
439static x86code *op_xtract(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
440static x86code *op_insert(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
415static x86code *op_sext(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
416static x86code *op_roland(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
417static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
441418static x86code *op_add(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
442419static x86code *op_addc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
443420static x86code *op_sub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
r2821r2822
466443static x86code *op_fread(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
467444static x86code *op_fwrite(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
468445static x86code *op_fmov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
469static x86code *op_ftoi4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
470static x86code *op_ftoi4t(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
471static x86code *op_ftoi4r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
472static x86code *op_ftoi4f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
473static x86code *op_ftoi4c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
474static x86code *op_ftoi8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
475static x86code *op_ftoi8t(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
476static x86code *op_ftoi8r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
477static x86code *op_ftoi8f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
478static x86code *op_ftoi8c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
479static x86code *op_ffrfs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
480static x86code *op_ffrfd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
481static x86code *op_ffri4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
482static x86code *op_ffri8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
446static x86code *op_ftoint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
447static x86code *op_ffrint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
448static x86code *op_ffrflt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
449static x86code *op_frnds(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
483450static x86code *op_fadd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
484451static x86code *op_fsub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
485452static x86code *op_fcmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
r2821r2822
514481   /* Internal Register Operations */
515482   { DRCUML_OP_SETFMOD, op_setfmod },   /* SETFMOD src                    */
516483   { DRCUML_OP_GETFMOD, op_getfmod },   /* GETFMOD dst                    */
517   { DRCUML_OP_GETEXP,  op_getexp },   /* GETEXP  dst,index              */
518   { DRCUML_OP_SAVE,    op_save },      /* SAVE    dst,index              */
519   { DRCUML_OP_RESTORE, op_restore },   /* RESTORE dst,index              */
484   { DRCUML_OP_GETEXP,  op_getexp },   /* GETEXP  dst                    */
485   { DRCUML_OP_GETFLGS, op_getflgs },   /* GETFLGS dst[,f]                */
486   { DRCUML_OP_SAVE,    op_save },      /* SAVE    dst                    */
487   { DRCUML_OP_RESTORE, op_restore },   /* RESTORE dst                    */
520488
521489   /* Integer Operations */
522   { DRCUML_OP_LOAD1U,  op_load1u },   /* LOAD1U  dst,base,index         */
523   { DRCUML_OP_LOAD1S,  op_load1s },   /* LOAD1S  dst,base,index         */
524   { DRCUML_OP_LOAD2U,  op_load2u },   /* LOAD2U  dst,base,index         */
525   { DRCUML_OP_LOAD2S,  op_load2s },   /* LOAD2S  dst,base,index         */
526   { DRCUML_OP_LOAD4U,  op_load4u },   /* LOAD4U  dst,base,index         */
527   { DRCUML_OP_LOAD4S,  op_load4s },   /* LOAD4S  dst,base,index         */
528   { DRCUML_OP_LOAD8U,  op_load8u },   /* LOAD8U  dst,base,index         */
529   { DRCUML_OP_STORE1,  op_store1 },   /* STORE1  base,index,src         */
530   { DRCUML_OP_STORE2,  op_store2 },   /* STORE2  base,index,src         */
531   { DRCUML_OP_STORE4,  op_store4 },   /* STORE4  base,index,src         */
532   { DRCUML_OP_STORE8,  op_store8 },   /* STORE8  base,index,src         */
533   { DRCUML_OP_READ1U,  op_read1u },   /* READ1U  dst,space,src1         */
534   { DRCUML_OP_READ1S,  op_read1s },   /* READ1S  dst,space,src1         */
535   { DRCUML_OP_READ2U,  op_read2u },   /* READ2U  dst,space,src1         */
536   { DRCUML_OP_READ2S,  op_read2s },   /* READ2S  dst,space,src1         */
537   { DRCUML_OP_READ2M,  op_read2m },   /* READ2M  dst,space,src1,mask    */
538   { DRCUML_OP_READ4U,  op_read4u },   /* READ4U  dst,space,src1         */
539   { DRCUML_OP_READ4S,  op_read4s },   /* READ4S  dst,space,src1         */
540   { DRCUML_OP_READ4M,  op_read4m },   /* READ4M  dst,space,src1,mask    */
541   { DRCUML_OP_READ8U,  op_read8u },   /* READ8U  dst,space,src1         */
542   { DRCUML_OP_READ8M,  op_read8m },   /* READ8M  dst,space,src1,mask    */
543   { DRCUML_OP_WRITE1,  op_write1 },   /* WRITE1  space,dst,src1         */
544   { DRCUML_OP_WRITE2,  op_write2 },   /* WRITE2  space,dst,src1         */
545   { DRCUML_OP_WRIT2M,  op_writ2m },   /* WRIT2M  space,dst,src1         */
546   { DRCUML_OP_WRITE4,  op_write4 },   /* WRITE4  space,dst,src1         */
547   { DRCUML_OP_WRIT4M,  op_writ4m },   /* WRIT4M  space,dst,mask,src1    */
548   { DRCUML_OP_WRITE8,  op_write8 },   /* WRITE8  space,dst,src1         */
549   { DRCUML_OP_WRIT8M,  op_writ8m },   /* WRIT8M  space,dst,mask,src1    */
550   { DRCUML_OP_FLAGS,   op_flags },   /* FLAGS   dst,mask,table         */
551   { DRCUML_OP_SETC,    op_setc },      /* FLAGS   src,bitnum             */
490   { DRCUML_OP_LOAD,    op_load },      /* LOAD    dst,base,index,size    */
491   { DRCUML_OP_LOADS,   op_loads },   /* LOADS   dst,base,index,size    */
492   { DRCUML_OP_STORE,   op_store },   /* STORE   base,index,src,size    */
493   { DRCUML_OP_READ,    op_read },      /* READ    dst,src1,spacesize     */
494   { DRCUML_OP_READM,   op_readm },   /* READM   dst,src1,mask,spacesize */
495   { DRCUML_OP_WRITE,   op_write },   /* WRITE   dst,src1,spacesize     */
496   { DRCUML_OP_WRITEM,  op_writem },   /* WRITEM  dst,src1,spacesize     */
497   { DRCUML_OP_CARRY,   op_carry },   /* CARRY   src,bitnum             */
498   { DRCUML_OP_SET,     op_set },      /* SET     dst,c                  */
552499   { DRCUML_OP_MOV,     op_mov },      /* MOV     dst,src[,c]            */
553   { DRCUML_OP_ZEXT1,   op_zext1 },   /* ZEXT1   dst,src                */
554   { DRCUML_OP_ZEXT2,   op_zext2 },   /* ZEXT2   dst,src                */
555   { DRCUML_OP_ZEXT4,   op_zext4 },   /* ZEXT4   dst,src                */
556   { DRCUML_OP_SEXT1,   op_sext1 },   /* SEXT1   dst,src                */
557   { DRCUML_OP_SEXT2,   op_sext2 },   /* SEXT2   dst,src                */
558   { DRCUML_OP_SEXT4,   op_sext4 },   /* SEXT4   dst,src                */
559   { DRCUML_OP_XTRACT,  op_xtract },   /* XTRACT  dst,src1,src2,src3     */
560   { DRCUML_OP_INSERT,  op_insert },   /* INSERT  dst,src1,src2,src3     */
500   { DRCUML_OP_SEXT,    op_sext },      /* SEXT    dst,src                */
501   { DRCUML_OP_ROLAND,  op_roland },   /* ROLAND  dst,src1,src2,src3     */
502   { DRCUML_OP_ROLINS,  op_rolins },   /* ROLINS  dst,src1,src2,src3     */
561503   { DRCUML_OP_ADD,     op_add },      /* ADD     dst,src1,src2[,f]      */
562504   { DRCUML_OP_ADDC,    op_addc },      /* ADDC    dst,src1,src2[,f]      */
563505   { DRCUML_OP_SUB,     op_sub },      /* SUB     dst,src1,src2[,f]      */
r2821r2822
587529   { DRCUML_OP_FREAD,   op_fread },   /* FREAD   dst,space,src1         */
588530   { DRCUML_OP_FWRITE,  op_fwrite },   /* FWRITE  space,dst,src1         */
589531   { DRCUML_OP_FMOV,    op_fmov },      /* FMOV    dst,src1[,c]           */
590   { DRCUML_OP_FTOI4,   op_ftoi4 },   /* FTOI4   dst,src1               */
591   { DRCUML_OP_FTOI4T,  op_ftoi4t },   /* FTOI4T  dst,src1               */
592   { DRCUML_OP_FTOI4R,  op_ftoi4r },   /* FTOI4R  dst,src1               */
593   { DRCUML_OP_FTOI4F,  op_ftoi4f },   /* FTOI4F  dst,src1               */
594   { DRCUML_OP_FTOI4C,  op_ftoi4c },   /* FTOI4C  dst,src1               */
595   { DRCUML_OP_FTOI8,   op_ftoi8 },   /* FTOI8   dst,src1               */
596   { DRCUML_OP_FTOI8T,  op_ftoi8t },   /* FTOI8T  dst,src1               */
597   { DRCUML_OP_FTOI8R,  op_ftoi8r },   /* FTOI8R  dst,src1               */
598   { DRCUML_OP_FTOI8F,  op_ftoi8f },   /* FTOI8F  dst,src1               */
599   { DRCUML_OP_FTOI8C,  op_ftoi8c },   /* FTOI8C  dst,src1               */
600   { DRCUML_OP_FFRFS,   op_ffrfs },   /* FFRFS   dst,src1               */
601   { DRCUML_OP_FFRFD,   op_ffrfd },   /* FFRFD   dst,src1               */
602   { DRCUML_OP_FFRI4,   op_ffri4 },   /* FFRI4   dst,src1               */
603   { DRCUML_OP_FFRI8,   op_ffri8 },   /* FFRI8   dst,src1               */
532   { DRCUML_OP_FTOINT,  op_ftoint },   /* FTOINT  dst,src1,size,round    */
533   { DRCUML_OP_FFRINT,  op_ffrint },   /* FFRINT  dst,src1,size          */
534   { DRCUML_OP_FFRFLT,  op_ffrflt },   /* FFRFLT  dst,src1,size          */
535   { DRCUML_OP_FRNDS,   op_frnds },   /* FRNDS   dst,src1               */
604536   { DRCUML_OP_FADD,    op_fadd },      /* FADD    dst,src1,src2          */
605537   { DRCUML_OP_FSUB,    op_fsub },      /* FSUB    dst,src1,src2          */
606538   { DRCUML_OP_FCMP,    op_fcmp },      /* FCMP    src1,src2              */
r2821r2822
35533485
35543486
35553487/*-------------------------------------------------
3488    op_getflgs - process a GETFLGS opcode
3489-------------------------------------------------*/
3490
3491static x86code *op_getflgs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3492{
3493   drcuml_parameter dstp;
3494   int dstreg;
3495
3496   /* validate instruction */
3497   assert(inst->size == 4);
3498   assert(inst->condflags != DRCUML_COND_ALWAYS);
3499
3500   /* normalize parameters */
3501   param_normalize_1(drcbe, inst, &dstp, PTYPE_MR);
3502
3503   /* pick a target register for the general case */
3504   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3505
3506   switch (inst->condflags)
3507   {
3508      /* single flags only */
3509      case DRCUML_FLAG_C:
3510         emit_setcc_r8(&dst, COND_C, REG_AL);                              // setc   al
3511         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3512         break;
3513
3514      case DRCUML_FLAG_V:
3515         emit_setcc_r8(&dst, COND_O, REG_AL);                              // seto   al
3516         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3517         emit_shl_r32_imm(&dst, dstreg, 1);                                 // shl    dstreg,1
3518         break;
3519
3520      case DRCUML_FLAG_Z:
3521         emit_setcc_r8(&dst, COND_Z, REG_AL);                              // setz   al
3522         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3523         emit_shl_r32_imm(&dst, dstreg, 2);                                 // shl    dstreg,2
3524         break;
3525
3526      case DRCUML_FLAG_S:
3527         emit_setcc_r8(&dst, COND_S, REG_AL);                              // sets   al
3528         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3529         emit_shl_r32_imm(&dst, dstreg, 3);                                 // shl    dstreg,3
3530         break;
3531
3532      case DRCUML_FLAG_U:
3533         emit_setcc_r8(&dst, COND_P, REG_AL);                              // setp   al
3534         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3535         emit_shl_r32_imm(&dst, dstreg, 4);                                 // shl    dstreg,4
3536         break;
3537
3538      /* carry plus another flag */
3539      case DRCUML_FLAG_C | DRCUML_FLAG_V:
3540         emit_setcc_r8(&dst, COND_C, REG_AL);                              // setc   al
3541         emit_setcc_r8(&dst, COND_O, REG_CL);                              // seto   cl
3542         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3543         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3544         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0));            // lea    dstreg,[eax+ecx*2]
3545         break;
3546
3547      case DRCUML_FLAG_C | DRCUML_FLAG_Z:
3548         emit_setcc_r8(&dst, COND_C, REG_AL);                              // setc   al
3549         emit_setcc_r8(&dst, COND_Z, REG_CL);                              // setz   cl
3550         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3551         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3552         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0));            // lea    dstreg,[eax+ecx*4]
3553         break;
3554
3555      case DRCUML_FLAG_C | DRCUML_FLAG_S:
3556         emit_setcc_r8(&dst, COND_C, REG_AL);                              // setc   al
3557         emit_setcc_r8(&dst, COND_S, REG_CL);                              // sets   cl
3558         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3559         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3560         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 8, 0));            // lea    dstreg,[eax+ecx*8]
3561         break;
3562
3563      /* overflow plus another flag */
3564      case DRCUML_FLAG_V | DRCUML_FLAG_Z:
3565         emit_setcc_r8(&dst, COND_O, REG_AL);                              // seto   al
3566         emit_setcc_r8(&dst, COND_Z, REG_CL);                              // setz   cl
3567         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3568         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3569         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0));            // lea    dstreg,[eax+ecx*2]
3570         emit_shl_r32_imm(&dst, dstreg, 1);                                 // shl    dstreg,1
3571         break;
3572
3573      case DRCUML_FLAG_V | DRCUML_FLAG_S:
3574         emit_setcc_r8(&dst, COND_O, REG_AL);                              // seto   al
3575         emit_setcc_r8(&dst, COND_S, REG_CL);                              // sets   cl
3576         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3577         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3578         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0));            // lea    dstreg,[eax+ecx*4]
3579         emit_shl_r32_imm(&dst, dstreg, 1);                                 // shl    dstreg,1
3580         break;
3581
3582      /* zero plus another flag */
3583      case DRCUML_FLAG_Z | DRCUML_FLAG_S:
3584         emit_setcc_r8(&dst, COND_Z, REG_AL);                              // setz   al
3585         emit_setcc_r8(&dst, COND_S, REG_CL);                              // sets   cl
3586         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3587         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3588         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0));            // lea    dstreg,[eax+ecx*2]
3589         emit_shl_r32_imm(&dst, dstreg, 2);                                 // shl    dstreg,2
3590         break;
3591
3592      /* default cases */
3593      default:
3594         emit_pushf(&dst);                                             // pushf
3595         emit_pop_r64(&dst, REG_EAX);                                    // pop    eax
3596         emit_and_r32_imm(&dst, REG_EAX, 0x8c5);                              // and    eax,0x8c5
3597         emit_movzx_r32_m8(&dst, dstreg, MBISD(REG_RBP, REG_RAX, 1, offset_from_rbp(drcbe, (FPTR)&drcbe->flagsmap[0])));
3598                                                                  // movzx  dstreg,[flags_map]
3599         break;
3600   }
3601
3602   /* 32-bit form */
3603   if (inst->size == 4)
3604      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3605
3606   /* 64-bit form */
3607   else if (inst->size == 8)
3608      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3609
3610   return dst;
3611}
3612
3613
3614/*-------------------------------------------------
35563615    op_save - process a SAVE opcode
35573616-------------------------------------------------*/
35583617
r2821r2822
36803739***************************************************************************/
36813740
36823741/*-------------------------------------------------
3683    op_load1u - process a LOAD1U opcode
3742    op_load - process a LOAD opcode
36843743-------------------------------------------------*/
36853744
3686static x86code *op_load1u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3745static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
36873746{
3688   drcuml_parameter dstp, basep, indp;
3747   drcuml_parameter dstp, basep, indp, sizep;
36893748   int basereg, dstreg;
36903749   INT32 baseoffs;
36913750
r2821r2822
36943753   assert(inst->condflags == DRCUML_COND_ALWAYS);
36953754
36963755   /* normalize parameters */
3697   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3756   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI, &sizep, PTYPE_I);
36983757
3699   /* pick a target register for the general case */
3700   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3701
37023758   /* determine the pointer base */
37033759   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
37043760
3761   /* pick a target register for the general case */
3762   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3763
37053764   /* immediate index */
37063765   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3707      emit_movzx_r32_m8(&dst, dstreg, MBD(basereg, baseoffs + 1*indp.value));         // movzx dstreg,[basep + 1*indp]
3766   {
3767      if (sizep.value == DRCUML_SIZE_BYTE)
3768         emit_movzx_r32_m8(&dst, dstreg, MBD(basereg, baseoffs + 1*indp.value));      // movzx dstreg,[basep + 1*indp]
3769      else if (sizep.value == DRCUML_SIZE_WORD)
3770         emit_movzx_r32_m16(&dst, dstreg, MBD(basereg, baseoffs + 2*indp.value));   // movzx dstreg,[basep + 2*indp]
3771      else if (sizep.value == DRCUML_SIZE_DWORD)
3772         emit_mov_r32_m32(&dst, dstreg, MBD(basereg, baseoffs + 4*indp.value));      // mov   dstreg,[basep + 4*indp]
3773      else if (sizep.value == DRCUML_SIZE_QWORD)
3774         emit_mov_r64_m64(&dst, dstreg, MBD(basereg, baseoffs + 8*indp.value));      // mov   dstreg,[basep + 8*indp]
3775   }
37083776
37093777   /* other index */
37103778   else
37113779   {
37123780      int indreg = param_select_register(REG_ECX, &indp, NULL);
37133781      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3714      emit_movzx_r32_m8(&dst, dstreg, MBISD(basereg, indreg, 1, baseoffs));         // movzx dstreg,[basep + 1*indp]
3782      if (sizep.value == DRCUML_SIZE_BYTE)
3783         emit_movzx_r32_m8(&dst, dstreg, MBISD(basereg, indreg, 1, baseoffs));      // movzx dstreg,[basep + 1*indp]
3784      else if (sizep.value == DRCUML_SIZE_WORD)
3785         emit_movzx_r32_m16(&dst, dstreg, MBISD(basereg, indreg, 2, baseoffs));      // movzx dstreg,[basep + 2*indp]
3786      else if (sizep.value == DRCUML_SIZE_DWORD)
3787         emit_mov_r32_m32(&dst, dstreg, MBISD(basereg, indreg, 4, baseoffs));      // mov   dstreg,[basep + 4*indp]
3788      else if (sizep.value == DRCUML_SIZE_QWORD)
3789         emit_mov_r64_m64(&dst, dstreg, MBISD(basereg, indreg, 8, baseoffs));      // mov   dstreg,[basep + 8*indp]
37153790   }
37163791
3717   /* store to appropriate target size */
3792   /* store result */
37183793   if (inst->size == 4)
37193794      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3720   else if (inst->size == 8)
3795   else
37213796      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
37223797
37233798   return dst;
r2821r2822
37253800
37263801
37273802/*-------------------------------------------------
3728    op_load1s - process a LOAD1S opcode
3803    op_loads - process a LOADS opcode
37293804-------------------------------------------------*/
37303805
3731static x86code *op_load1s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3806static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
37323807{
3733   drcuml_parameter dstp, basep, indp;
3808   drcuml_parameter dstp, basep, indp, sizep;
37343809   int basereg, dstreg;
37353810   INT32 baseoffs;
37363811
r2821r2822
37393814   assert(inst->condflags == DRCUML_COND_ALWAYS);
37403815
37413816   /* normalize parameters */
3742   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3817   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI, &sizep, PTYPE_I);
37433818
3744   /* pick a target register for the general case */
3745   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3746
37473819   /* determine the pointer base */
37483820   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
37493821
3750   /* 32-bit form */
3751   if (inst->size == 4)
3752   {
3753      /* immediate index */
3754      if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3755         emit_movsx_r32_m8(&dst, dstreg, MBD(basereg, baseoffs + 1*indp.value));      // movsx eax,[basep + 1*indp]
3756
3757      /* other index */
3758      else
3759      {
3760         int indreg = param_select_register(REG_ECX, &indp, NULL);
3761         emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3762         emit_movsx_r32_m8(&dst, dstreg, MBISD(basereg, indreg, 1, baseoffs));      // movsx eax,[basep + 1*indp]
3763      }
3764
3765      /* general case */
3766      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3767   }
3768
3769   /* 64-bit form */
3770   else
3771   {
3772      /* immediate index */
3773      if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3774         emit_movsx_r64_m8(&dst, dstreg, MBD(basereg, baseoffs + 1*indp.value));      // movsx rax,[basep + 1*indp]
3775
3776      /* other index */
3777      else
3778      {
3779         int indreg = param_select_register(REG_ECX, &indp, NULL);
3780         emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3781         emit_movsx_r64_m8(&dst, dstreg, MBISD(basereg, indreg, 1, baseoffs));      // movsx rax,[basep + 1*indp]
3782      }
3783
3784      /* general case */
3785      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3786   }
3787   return dst;
3788}
3789
3790
3791/*-------------------------------------------------
3792    op_load2u - process a LOAD2U opcode
3793-------------------------------------------------*/
3794
3795static x86code *op_load2u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3796{
3797   drcuml_parameter dstp, basep, indp;
3798   int basereg, dstreg;
3799   INT32 baseoffs;
3800
3801   /* validate instruction */
3802   assert(inst->size == 4 || inst->size == 8);
3803   assert(inst->condflags == DRCUML_COND_ALWAYS);
3804
3805   /* normalize parameters */
3806   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3807
38083822   /* pick a target register for the general case */
38093823   dstreg = param_select_register(REG_EAX, &dstp, NULL);
38103824
3811   /* determine the pointer base */
3812   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
3813
38143825   /* immediate index */
38153826   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3816      emit_movzx_r32_m16(&dst, dstreg, MBD(basereg, baseoffs + 2*indp.value));      // movzx dstreg,[basep + 2*indp]
3817
3818   /* other index */
3819   else
38203827   {
3821      int indreg = param_select_register(REG_ECX, &indp, NULL);
3822      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3823      emit_movzx_r32_m16(&dst, dstreg, MBISD(basereg, indreg, 2, baseoffs));         // movzx dstreg,[basep + 2*indp]
3824   }
3825
3826   /* store to appropriate target size */
3827   if (inst->size == 4)
3828      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3829   else if (inst->size == 8)
3830      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3831
3832   return dst;
3833}
3834
3835
3836/*-------------------------------------------------
3837    op_load2s - process a LOAD2S opcode
3838-------------------------------------------------*/
3839
3840static x86code *op_load2s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3841{
3842   drcuml_parameter dstp, basep, indp;
3843   int basereg, dstreg;
3844   INT32 baseoffs;
3845
3846   /* validate instruction */
3847   assert(inst->size == 4 || inst->size == 8);
3848   assert(inst->condflags == DRCUML_COND_ALWAYS);
3849
3850   /* normalize parameters */
3851   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3852
3853   /* pick a target register for the general case */
3854   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3855
3856   /* determine the pointer base */
3857   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
3858
3859   /* 32-bit form */
3860   if (inst->size == 4)
3861   {
3862      /* immediate index */
3863      if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3864         emit_movsx_r32_m16(&dst, dstreg, MBD(basereg, baseoffs + 2*indp.value));   // movsx eax,[basep + 2*indp]
3865
3866      /* other index */
3867      else
3828      if (inst->size == 4)
38683829      {
3869         int indreg = param_select_register(REG_ECX, &indp, NULL);
3870         emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3871         emit_movsx_r32_m16(&dst, dstreg, MBISD(basereg, indreg, 2, baseoffs));      // movsx eax,[basep + 2*indp]
3830         if (sizep.value == DRCUML_SIZE_BYTE)
3831            emit_movsx_r32_m8(&dst, dstreg, MBD(basereg, baseoffs + 1*indp.value));   // movsx dstreg,[basep + 1*indp]
3832         else if (sizep.value == DRCUML_SIZE_WORD)
3833            emit_movsx_r32_m16(&dst, dstreg, MBD(basereg, baseoffs + 2*indp.value));// movsx dstreg,[basep + 2*indp]
3834         else if (sizep.value == DRCUML_SIZE_DWORD)
3835            emit_mov_r32_m32(&dst, dstreg, MBD(basereg, baseoffs + 4*indp.value));   // mov   dstreg,[basep + 4*indp]
38723836      }
3873
3874      /* general case */
3875      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3876   }
3877
3878   /* 64-bit form */
3879   else
3880   {
3881      /* immediate index */
3882      if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3883         emit_movsx_r64_m16(&dst, dstreg, MBD(basereg, baseoffs + 2*indp.value));   // movsx rax,[basep + 2*indp]
3884
3885      /* other index */
3886      else
3837      else if (inst->size == 8)
38873838      {
3888         int indreg = param_select_register(REG_ECX, &indp, NULL);
3889         emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3890         emit_movsx_r64_m16(&dst, dstreg, MBISD(basereg, indreg, 2, baseoffs));      // movsx rax,[basep + 2*indp]
3839         if (sizep.value == DRCUML_SIZE_BYTE)
3840            emit_movsx_r64_m8(&dst, dstreg, MBD(basereg, baseoffs + 1*indp.value));   // movzx dstreg,[basep + 1*indp]
3841         else if (sizep.value == DRCUML_SIZE_WORD)
3842            emit_movsx_r64_m16(&dst, dstreg, MBD(basereg, baseoffs + 2*indp.value));// movzx dstreg,[basep + 2*indp]
3843         else if (sizep.value == DRCUML_SIZE_DWORD)
3844            emit_movsxd_r64_m32(&dst, dstreg, MBD(basereg, baseoffs + 4*indp.value));// movsxd dstreg,[basep + 4*indp]
3845         else if (sizep.value == DRCUML_SIZE_QWORD)
3846            emit_mov_r64_m64(&dst, dstreg, MBD(basereg, baseoffs + 8*indp.value));   // mov   dstreg,[basep + 8*indp]
38913847      }
3892
3893      /* general case */
3894      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
38953848   }
3896   return dst;
3897}
38983849
3899
3900/*-------------------------------------------------
3901    op_load4u - process a LOAD4U opcode
3902-------------------------------------------------*/
3903
3904static x86code *op_load4u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3905{
3906   drcuml_parameter dstp, basep, indp;
3907   int basereg, dstreg;
3908   INT32 baseoffs;
3909
3910   /* validate instruction */
3911   assert(inst->size == 4 || inst->size == 8);
3912   assert(inst->condflags == DRCUML_COND_ALWAYS);
3913
3914   /* normalize parameters */
3915   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3916
3917   /* pick a target register for the general case */
3918   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3919
3920   /* determine the pointer base */
3921   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
3922
3923   /* immediate index */
3924   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3925      emit_mov_r32_m32(&dst, dstreg, MBD(basereg, baseoffs + 4*indp.value));         // mov   dstreg,[basep + 4*indp]
3926
39273850   /* other index */
39283851   else
39293852   {
39303853      int indreg = param_select_register(REG_ECX, &indp, NULL);
39313854      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3932      emit_mov_r32_m32(&dst, dstreg, MBISD(basereg, indreg, 4, baseoffs));         // mov   dstreg,[basep + 4*indp]
3855      if (inst->size == 4)
3856      {
3857         if (sizep.value == DRCUML_SIZE_BYTE)
3858            emit_movsx_r32_m8(&dst, dstreg, MBISD(basereg, indreg, 1, baseoffs));   // movsx dstreg,[basep + 1*indp]
3859         else if (sizep.value == DRCUML_SIZE_WORD)
3860            emit_movsx_r32_m16(&dst, dstreg, MBISD(basereg, indreg, 2, baseoffs));   // movsx dstreg,[basep + 2*indp]
3861         else if (sizep.value == DRCUML_SIZE_DWORD)
3862            emit_mov_r32_m32(&dst, dstreg, MBISD(basereg, indreg, 4, baseoffs));   // mov   dstreg,[basep + 4*indp]
3863      }
3864      else if (inst->size == 8)
3865      {
3866         if (sizep.value == DRCUML_SIZE_BYTE)
3867            emit_movsx_r64_m8(&dst, dstreg, MBISD(basereg, indreg, 1, baseoffs));   // movsx dstreg,[basep + 1*indp]
3868         else if (sizep.value == DRCUML_SIZE_WORD)
3869            emit_movsx_r64_m16(&dst, dstreg, MBISD(basereg, indreg, 2, baseoffs));   // movsx dstreg,[basep + 2*indp]
3870         else if (sizep.value == DRCUML_SIZE_DWORD)
3871            emit_movsxd_r64_m32(&dst, dstreg, MBISD(basereg, indreg, 4, baseoffs));   // movsxd dstreg,[basep + 4*indp]
3872         else if (sizep.value == DRCUML_SIZE_QWORD)
3873            emit_mov_r64_m64(&dst, dstreg, MBISD(basereg, indreg, 8, baseoffs));   // mov   dstreg,[basep + 8*indp]
3874      }
39333875   }
39343876
3935   /* store to appropriate target size */
3877   /* store result */
39363878   if (inst->size == 4)
39373879      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3938   else if (inst->size == 8)
3880   else
39393881      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
39403882
39413883   return dst;
r2821r2822
39433885
39443886
39453887/*-------------------------------------------------
3946    op_load4s - process a LOAD4S opcode
3888    op_store - process a STORE opcode
39473889-------------------------------------------------*/
39483890
3949static x86code *op_load4s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3891static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
39503892{
3951   drcuml_parameter dstp, basep, indp;
3952   int basereg, dstreg;
3893   drcuml_parameter srcp, basep, indp, sizep;
3894   int srcreg, basereg;
39533895   INT32 baseoffs;
39543896
39553897   /* validate instruction */
3956   assert(inst->size == 8);
3898   assert(inst->size == 4 || inst->size == 8);
39573899   assert(inst->condflags == DRCUML_COND_ALWAYS);
39583900
39593901   /* normalize parameters */
3960   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3902   param_normalize_4(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI, &sizep, PTYPE_I);
39613903
3962   /* pick a target register for the general case */
3963   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3964
39653904   /* determine the pointer base */
39663905   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
39673906
3968   /* immediate index */
3969   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3970      emit_movsxd_r64_m32(&dst, dstreg, MBD(basereg, baseoffs + 4*indp.value));      // mov   dstreg,[basep + 4*indp]
3971
3972   /* other index */
3973   else
3974   {
3975      int indreg = param_select_register(REG_ECX, &indp, NULL);
3976      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3977      emit_movsxd_r64_m32(&dst, dstreg, MISD(indreg, 4, basep.value));            // movsx dstreg,[basep + 4*indp]
3978   }
3979
3980   /* general case */
3981   emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
3982
3983   return dst;
3984}
3985
3986
3987/*-------------------------------------------------
3988    op_load8u - process a LOAD8U opcode
3989-------------------------------------------------*/
3990
3991static x86code *op_load8u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3992{
3993   drcuml_parameter dstp, basep, indp;
3994   int basereg, dstreg;
3995   INT32 baseoffs;
3996
3997   /* validate instruction */
3998   assert(inst->size == 8);
3999   assert(inst->condflags == DRCUML_COND_ALWAYS);
4000
4001   /* normalize parameters */
4002   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
4003
4004   /* pick a target register for the general case */
4005   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4006
4007   /* determine the pointer base */
4008   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
4009
4010   /* immediate index */
4011   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
4012      emit_mov_r64_m64(&dst, dstreg, MBD(basereg, baseoffs + 8*indp.value));         // mov   dstreg,[basep + 8*indp]
4013
4014   /* other index */
4015   else
4016   {
4017      int indreg = param_select_register(REG_ECX, &indp, NULL);
4018      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
4019      emit_mov_r64_m64(&dst, dstreg, MBISD(basereg, indreg, 8, baseoffs));         // mov   dstreg,[basep + 8*indp]
4020   }
4021
4022   /* general case */
4023   emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,edx:dstreg
4024
4025   return dst;
4026}
4027
4028
4029/*-------------------------------------------------
4030    op_store1 - process a STORE1 opcode
4031-------------------------------------------------*/
4032
4033static x86code *op_store1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4034{
4035   drcuml_parameter srcp, basep, indp;
4036   int basereg, srcreg;
4037   INT32 baseoffs;
4038
4039   /* validate instruction */
4040   assert(inst->size == 4 || inst->size == 8);
4041   assert(inst->condflags == DRCUML_COND_ALWAYS);
4042
4043   /* normalize parameters */
4044   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI);
4045
40463907   /* pick a source register for the general case */
40473908   srcreg = param_select_register(REG_EAX, &srcp, NULL);
40483909
4049   /* determine the pointer base */
4050   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
4051
40523910   /* degenerate case: constant index */
40533911   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
40543912   {
3913      /* immediate source */
40553914      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4056         emit_mov_m8_imm(&dst, MBD(basereg, baseoffs + 1*indp.value), srcp.value);   // mov   [basep + 1*indp],srcp
4057      else
40583915      {
4059         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4060         emit_mov_m8_r8(&dst, MBD(basereg, baseoffs + 1*indp.value), srcreg);      // mov   [basep + 1*indp],srcreg
3916         if (sizep.value == DRCUML_SIZE_BYTE)
3917            emit_mov_m8_imm(&dst, MBD(basereg, baseoffs + 1*indp.value), srcp.value);   // mov   [basep + 1*indp],srcp
3918         else if (sizep.value == DRCUML_SIZE_WORD)
3919            emit_mov_m16_imm(&dst, MBD(basereg, baseoffs + 2*indp.value), srcp.value);   // mov   [basep + 2*indp],srcp
3920         else if (sizep.value == DRCUML_SIZE_DWORD)
3921            emit_mov_m32_imm(&dst, MBD(basereg, baseoffs + 4*indp.value), srcp.value);   // mov   [basep + 4*indp],srcp
3922         else if (sizep.value == DRCUML_SIZE_QWORD)
3923         {
3924            if (short_immediate(srcp.value))
3925               emit_mov_m64_imm(&dst, MBD(basereg, baseoffs + 8*indp.value), srcp.value);// mov   [basep + 8*indp],srcp
3926            else
3927            {
3928               emit_mov_m32_imm(&dst, MBD(basereg, baseoffs + 8*indp.value), srcp.value);// mov   [basep + 8*indp],srcp
3929               emit_mov_m32_imm(&dst, MBD(basereg, baseoffs + 8*indp.value + 4), srcp.value >> 32);
3930                                                                  // mov   [basep + 8*indp + 4],srcp >> 32
3931            }
3932         }
40613933      }
4062   }
40633934
4064   /* normal case: variable index */
4065   else
4066   {
4067      int indreg = param_select_register(REG_ECX, &indp, NULL);
4068      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);                           // mov   indreg,indp
4069      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4070         emit_mov_m8_imm(&dst, MBISD(basereg, indreg, 1, baseoffs), srcp.value);      // mov   [basep + 1*ecx],srcp
3935      /* variable source */
40713936      else
40723937      {
4073         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4074         emit_mov_m8_r8(&dst, MBISD(basereg, indreg, 1, baseoffs), srcreg);         // mov   [basep + 1*ecx],srcreg
3938         if (sizep.value != DRCUML_SIZE_QWORD)
3939            emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                     // mov   srcreg,srcp
3940         else
3941            emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp);                     // mov   srcreg,srcp
3942         if (sizep.value == DRCUML_SIZE_BYTE)
3943            emit_mov_m8_r8(&dst, MBD(basereg, baseoffs + 1*indp.value), srcreg);   // mov   [basep + 1*indp],srcreg
3944         else if (sizep.value == DRCUML_SIZE_WORD)
3945            emit_mov_m16_r16(&dst, MBD(basereg, baseoffs + 2*indp.value), srcreg);   // mov   [basep + 2*indp],srcreg
3946         else if (sizep.value == DRCUML_SIZE_DWORD)
3947            emit_mov_m32_r32(&dst, MBD(basereg, baseoffs + 4*indp.value), srcreg);   // mov   [basep + 4*indp],srcreg
3948         else if (sizep.value == DRCUML_SIZE_QWORD)
3949            emit_mov_m64_r64(&dst, MBD(basereg, baseoffs + 8*indp.value), srcreg);   // mov   [basep + 8*indp],srcreg
40753950      }
40763951   }
4077   return dst;
4078}
40793952
4080
4081/*-------------------------------------------------
4082    op_store2 - process a STORE2 opcode
4083-------------------------------------------------*/
4084
4085static x86code *op_store2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4086{
4087   drcuml_parameter srcp, basep, indp;
4088   int basereg, srcreg;
4089   INT32 baseoffs;
4090
4091   /* validate instruction */
4092   assert(inst->size == 4 || inst->size == 8);
4093   assert(inst->condflags == DRCUML_COND_ALWAYS);
4094
4095   /* normalize parameters */
4096   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI);
4097
4098   /* pick a source register for the general case */
4099   srcreg = param_select_register(REG_EAX, &srcp, NULL);
4100
4101   /* determine the pointer base */
4102   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
4103
4104   /* degenerate case: constant index */
4105   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
4106   {
4107      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4108         emit_mov_m16_imm(&dst, MBD(basereg, baseoffs + 2*indp.value), srcp.value);   // mov   [basep + 2*indp],srcp
4109      else
4110      {
4111         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4112         emit_mov_m16_r16(&dst, MBD(basereg, baseoffs + 2*indp.value), srcreg);      // mov   [basep + 2*indp],srcreg
4113      }
4114   }
4115
41163953   /* normal case: variable index */
41173954   else
41183955   {
41193956      int indreg = param_select_register(REG_ECX, &indp, NULL);
41203957      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);                           // mov   indreg,indp
4121      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4122         emit_mov_m16_imm(&dst, MBISD(basereg, indreg, 2, baseoffs), srcp.value);   // mov   [basep + 2*ecx],srcp
4123      else
4124      {
4125         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4126         emit_mov_m16_r16(&dst, MBISD(basereg, indreg, 2, baseoffs), srcreg);      // mov   [basep + 2*ecx],srcreg
4127      }
4128   }
4129   return dst;
4130}
41313958
4132
4133/*-------------------------------------------------
4134    op_store4 - process a STORE4 opcode
4135-------------------------------------------------*/
4136
4137static x86code *op_store4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4138{
4139   drcuml_parameter srcp, basep, indp;
4140   int basereg, srcreg;
4141   INT32 baseoffs;
4142
4143   /* validate instruction */
4144   assert(inst->size == 4 || inst->size == 8);
4145   assert(inst->condflags == DRCUML_COND_ALWAYS);
4146
4147   /* normalize parameters */
4148   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI);
4149
4150   /* pick a source register for the general case */
4151   srcreg = param_select_register(REG_EAX, &srcp, NULL);
4152
4153   /* determine the pointer base */
4154   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
4155
4156   /* degenerate case: constant index */
4157   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
4158   {
3959      /* immediate source */
41593960      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4160         emit_mov_m32_imm(&dst, MBD(basereg, baseoffs + 4*indp.value), srcp.value);   // mov   [basep + 4*indp],srcp
4161      else
41623961      {
4163         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4164         emit_mov_m32_r32(&dst, MBD(basereg, baseoffs + 4*indp.value), srcreg);      // mov   [basep + 4*indp],srcreg
3962         if (sizep.value == DRCUML_SIZE_BYTE)
3963            emit_mov_m8_imm(&dst, MBISD(basereg, indreg, 1, baseoffs), srcp.value);   // mov   [basep + 1*ecx],srcp
3964         else if (sizep.value == DRCUML_SIZE_WORD)
3965            emit_mov_m16_imm(&dst, MBISD(basereg, indreg, 2, baseoffs), srcp.value);// mov   [basep + 2*ecx],srcp
3966         else if (sizep.value == DRCUML_SIZE_DWORD)
3967            emit_mov_m32_imm(&dst, MBISD(basereg, indreg, 4, baseoffs), srcp.value);// mov   [basep + 4*ecx],srcp
3968         else if (sizep.value == DRCUML_SIZE_QWORD)
3969         {
3970            if (short_immediate(srcp.value))
3971               emit_mov_m64_imm(&dst, MBISD(basereg, indreg, 8, baseoffs), srcp.value);// mov   [basep + 8*indp],srcp
3972            else
3973            {
3974               emit_mov_m32_imm(&dst, MBISD(basereg, indreg, 8, baseoffs), srcp.value);// mov   [basep + 8*ecx],srcp
3975               emit_mov_m32_imm(&dst, MBISD(basereg, indreg, 8, baseoffs + 4), srcp.value >> 32);
3976                                                                  // mov   [basep + 8*ecx + 4],srcp >> 32
3977            }
3978         }
41653979      }
4166   }
41673980
4168   /* normal case: variable index */
4169   else
4170   {
4171      int indreg = param_select_register(REG_ECX, &indp, NULL);
4172      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);                           // mov   indreg,indp
4173      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4174         emit_mov_m32_imm(&dst, MBISD(basereg, indreg, 4, baseoffs), srcp.value);   // mov   [basep + 4*ecx],srcp
3981      /* variable source */
41753982      else
41763983      {
4177         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4178         emit_mov_m32_r32(&dst, MBISD(basereg, indreg, 4, baseoffs), srcreg);      // mov   [basep + 4*ecx],srcreg
3984         if (sizep.value != DRCUML_SIZE_QWORD)
3985            emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                     // mov   srcreg,srcp
3986         else
3987            emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp);                     // mov   edx:srcreg,srcp
3988         if (sizep.value == DRCUML_SIZE_BYTE)
3989            emit_mov_m8_r8(&dst, MBISD(basereg, indreg, 1, baseoffs), srcreg);      // mov   [basep + 1*ecx],srcreg
3990         else if (sizep.value == DRCUML_SIZE_WORD)
3991            emit_mov_m16_r16(&dst, MBISD(basereg, indreg, 2, baseoffs), srcreg);   // mov   [basep + 2*ecx],srcreg
3992         else if (sizep.value == DRCUML_SIZE_DWORD)
3993            emit_mov_m32_r32(&dst, MBISD(basereg, indreg, 4, baseoffs), srcreg);   // mov   [basep + 4*ecx],srcreg
3994         else if (sizep.value == DRCUML_SIZE_QWORD)
3995            emit_mov_m64_r64(&dst, MBISD(basereg, indreg, 8, baseoffs), srcreg);   // mov   [basep + 8*ecx],srcreg
41793996      }
41803997   }
41813998   return dst;
r2821r2822
41834000
41844001
41854002/*-------------------------------------------------
4186    op_store8 - process a STORE8 opcode
4003    op_read - process a READ opcode
41874004-------------------------------------------------*/
41884005
4189static x86code *op_store8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4006static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
41904007{
4191   drcuml_parameter srcp, basep, indp;
4192   int basereg, srcreg;
4193   INT32 baseoffs;
4194
4195   /* validate instruction */
4196   assert(inst->size == 8);
4197   assert(inst->condflags == DRCUML_COND_ALWAYS);
4198
4199   /* normalize parameters */
4200   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI);
4201
4202   /* pick a source register for the general case */
4203   srcreg = param_select_register(REG_EAX, &srcp, NULL);
4204
4205   /* determine the pointer base */
4206   basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs);
4207
4208   /* degenerate case: constant index */
4209   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
4210   {
4211      if (srcp.type == DRCUML_PTYPE_IMMEDIATE && short_immediate(srcp.value))
4212         emit_mov_m64_imm(&dst, MBD(basereg, baseoffs + 8*indp.value), srcp.value);   // mov   [basep + 8*indp],srcp
4213      else
4214      {
4215         emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4216         emit_mov_m64_r64(&dst, MBD(basereg, baseoffs + 8*indp.value), srcreg);      // mov   [basep + 8*indp],srcreg
4217      }
4218   }
4219
4220   /* normal case: variable index */
4221   else
4222   {
4223      int indreg = param_select_register(REG_ECX, &indp, NULL);
4224      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);                           // mov   indreg,indp
4225      if (srcp.type == DRCUML_PTYPE_IMMEDIATE && short_immediate(srcp.value))
4226         emit_mov_m64_imm(&dst, MBISD(basereg, indreg, 8, baseoffs), srcp.value);   // mov   [basep + 8*ecx],srcp
4227      else
4228      {
4229         emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4230         emit_mov_m64_r64(&dst, MBISD(basereg, indreg, 8, baseoffs), srcreg);      // mov   [basep + 8*ecx],srcreg
4231      }
4232   }
4233   return dst;
4234}
4235
4236
4237/*-------------------------------------------------
4238    op_read1u - process a READ1U opcode
4239-------------------------------------------------*/
4240
4241static x86code *op_read1u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4242{
4243   drcuml_parameter dstp, spacep, addrp;
4008   drcuml_parameter dstp, addrp, spacesizep;
42444009   int dstreg;
42454010
42464011   /* validate instruction */
r2821r2822
42484013   assert(inst->condflags == DRCUML_COND_ALWAYS);
42494014
42504015   /* normalize parameters */
4251   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4016   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &addrp, PTYPE_MRI, &spacesizep, PTYPE_I);
42524017
42534018   /* pick a target register for the general case */
42544019   dstreg = param_select_register(REG_EAX, &dstp, NULL);
42554020
42564021   /* set up a call to the read byte handler */
42574022   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4258   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_byte);// call   read_byte
4259   emit_movzx_r32_r8(&dst, dstreg, REG_AL);                                 // movzx  dstreg,al
4260
4261   /* store to appropriate target size */
4262   if (inst->size == 4)
4263      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4264   else if (inst->size == 8)
4265      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4266
4267   return dst;
4268}
4269
4270
4271/*-------------------------------------------------
4272    op_read1s - process a READ1S opcode
4273-------------------------------------------------*/
4274
4275static x86code *op_read1s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4276{
4277   drcuml_parameter dstp, spacep, addrp;
4278   int dstreg;
4279
4280   /* validate instruction */
4281   assert(inst->size == 4 || inst->size == 8);
4282   assert(inst->condflags == DRCUML_COND_ALWAYS);
4283
4284   /* normalize parameters */
4285   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4286
4287   /* pick a target register for the general case */
4288   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4289
4290   /* set up a call to the read byte handler */
4291   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4292   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_byte);// call   read_byte
4293
4294   /* 32-bit form */
4295   if (inst->size == 4)
4023   if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE)
42964024   {
4297      /* general case */
4298      emit_movsx_r32_r8(&dst, dstreg, REG_AL);                              // movsx  dstreg,al
4299      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov    dstp,dstreg
4025      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_byte);
4026                                                                  // call   read_byte
4027      emit_movzx_r32_r8(&dst, dstreg, REG_AL);                              // movzx  dstreg,al
43004028   }
4301
4302   /* 64-bit form */
4303   else
4029   else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
43044030   {
4305      /* general case */
4306      emit_movsx_r64_r8(&dst, dstreg, REG_AL);                              // movsx  dstreg,al
4307      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov    dstp,dstreg
4031      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_word);
4032                                                                  // call   read_word
4033      emit_movzx_r32_r16(&dst, dstreg, REG_AX);                              // movzx  dstreg,ax
43084034   }
4309   return dst;
4310}
4035   else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
4036   {
4037      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_dword);
4038                                                                  // call   read_dword
4039      if (dstreg != REG_EAX || inst->size == 8)
4040         emit_mov_r32_r32(&dst, dstreg, REG_EAX);                           // mov    dstreg,eax
4041   }
4042   else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
4043   {
4044      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_qword);
4045                                                                  // call   read_qword
4046      if (dstreg != REG_RAX)
4047         emit_mov_r64_r64(&dst, dstreg, REG_RAX);                           // mov    dstreg,rax
4048   }
43114049
4312
4313/*-------------------------------------------------
4314    op_read2u - process a READ2U opcode
4315-------------------------------------------------*/
4316
4317static x86code *op_read2u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4318{
4319   drcuml_parameter dstp, spacep, addrp;
4320   int dstreg;
4321
4322   /* validate instruction */
4323   assert(inst->size == 4 || inst->size == 8);
4324   assert(inst->condflags == DRCUML_COND_ALWAYS);
4325
4326   /* normalize parameters */
4327   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4328
4329   /* pick a target register for the general case */
4330   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4331
4332   /* set up a call to the read word handler */
4333   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4334   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_word);// call   read_word
4335   emit_movzx_r32_r16(&dst, dstreg, REG_AX);                                 // movzx  dstreg,ax
4336
4337   /* store to appropriate target size */
4050   /* store result */
43384051   if (inst->size == 4)
43394052      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4340   else if (inst->size == 8)
4053   else
43414054      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
43424055
43434056   return dst;
r2821r2822
43454058
43464059
43474060/*-------------------------------------------------
4348    op_read2s - process a READ2S opcode
4061    op_readm - process a READM opcode
43494062-------------------------------------------------*/
43504063
4351static x86code *op_read2s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4064static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
43524065{
4353   drcuml_parameter dstp, spacep, addrp;
4066   drcuml_parameter dstp, addrp, maskp, spacesizep;
43544067   int dstreg;
43554068
43564069   /* validate instruction */
r2821r2822
43584071   assert(inst->condflags == DRCUML_COND_ALWAYS);
43594072
43604073   /* normalize parameters */
4361   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4074   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &spacesizep, PTYPE_I);
43624075
43634076   /* pick a target register for the general case */
43644077   dstreg = param_select_register(REG_EAX, &dstp, NULL);
43654078
4366   /* set up a call to the read word handler */
4079   /* set up a call to the read byte handler */
43674080   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4368   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_word);// call   read_word
4369
4370   /* 32-bit form */
4371   if (inst->size == 4)
4081   if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD)
4082      emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &maskp);                        // mov    param2,maskp
4083   else
4084      emit_mov_r64_p64(drcbe, &dst, REG_PARAM2, &maskp);                        // mov    param2,maskp
4085   if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
43724086   {
4373      /* general case */
4374      emit_movsx_r32_r16(&dst, dstreg, REG_AX);                              // movsx  dstreg,ax
4375      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov    dstp,dstreg
4087      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_word_masked);
4088                                                                  // call   read_word_masked
4089      emit_movzx_r32_r16(&dst, dstreg, REG_AX);                              // movzx  dstreg,ax
43764090   }
4377
4378   /* 64-bit form */
4379   else
4091   else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
43804092   {
4381      /* general case */
4382      emit_movsx_r64_r16(&dst, dstreg, REG_AX);                              // movsx  dstreg,ax
4383      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov    dstp,dstreg
4093      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_dword_masked);
4094                                                                  // call   read_dword_masked
4095      if (dstreg != REG_EAX || inst->size == 8)
4096         emit_mov_r32_r32(&dst, dstreg, REG_EAX);                           // mov    dstreg,eax
43844097   }
4385   return dst;
4386}
4098   else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
4099   {
4100      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_qword_masked);
4101                                                                  // call   read_qword_masked
4102      if (dstreg != REG_RAX)
4103         emit_mov_r64_r64(&dst, dstreg, REG_RAX);                           // mov    dstreg,rax
4104   }
43874105
4388
4389/*-------------------------------------------------
4390    op_read2m - process a READ2M opcode
4391-------------------------------------------------*/
4392
4393static x86code *op_read2m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4394{
4395   drcuml_parameter dstp, spacep, addrp, maskp;
4396   int dstreg;
4397
4398   /* validate instruction */
4399   assert(inst->size == 4 || inst->size == 8);
4400   assert(inst->condflags == DRCUML_COND_ALWAYS);
4401
4402   /* normalize parameters */
4403   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI);
4404
4405   /* pick a target register for the general case */
4406   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4407
4408   /* set up a call to the read dword masked handler */
4409   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4410   emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &maskp);                           // mov    param1,maskp
4411   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_word_masked);// call   read_word_masked
4412   emit_movzx_r32_r16(&dst, dstreg, REG_AX);                                 // movzx  dstreg,ax
4413
4414   /* store to appropriate target size */
4106   /* store result */
44154107   if (inst->size == 4)
44164108      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4417   else if (inst->size == 8)
4109   else
44184110      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
44194111
44204112   return dst;
r2821r2822
44224114
44234115
44244116/*-------------------------------------------------
4425    op_read4u - process a READ4U opcode
4117    op_write - process a WRITE opcode
44264118-------------------------------------------------*/
44274119
4428static x86code *op_read4u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4120static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
44294121{
4430   drcuml_parameter dstp, spacep, addrp;
4122   drcuml_parameter addrp, srcp, spacesizep;
44314123
44324124   /* validate instruction */
44334125   assert(inst->size == 4 || inst->size == 8);
44344126   assert(inst->condflags == DRCUML_COND_ALWAYS);
44354127
44364128   /* normalize parameters */
4437   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4129   param_normalize_3(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI, &spacesizep, PTYPE_I);
44384130
4439   /* set up a call to the read dword handler */
4131   /* set up a call to the write byte handler */
44404132   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4441   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_dword);// call   read_dword
4442
4443   /* store to appropriate target size */
4444   if (inst->size == 4)
4445      emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX);                           // mov   dstp,eax
4446   else if (inst->size == 8)
4447      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX);                           // mov   dstp,rax
4448
4133   if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD)
4134      emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &srcp);                        // mov    param1,srcp
4135   else
4136      emit_mov_r64_p64(drcbe, &dst, REG_PARAM2, &srcp);                        // mov    param1,srcp
4137   if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE)
4138      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_byte);
4139                                                                  // call   write_byte
4140   else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
4141      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_word);
4142                                                                  // call   write_word
4143   else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
4144      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_dword);
4145                                                                  // call   write_dword
4146   else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
4147      emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_qword);
4148                                                                  // call   write_qword
44494149   return dst;
44504150}
44514151
44524152
44534153/*-------------------------------------------------
4454    op_read4s - process a READ4S opcode
4154    op_writem - process a WRITEM opcode
44554155-------------------------------------------------*/
44564156
4457static x86code *op_read4s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4157static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
44584158{
4459   drcuml_parameter dstp, spacep, addrp;
4460   int dstreg;
4159   drcuml_parameter addrp, srcp, maskp, spacesizep;
44614160
44624161   /* validate instruction */
4463   assert(inst->size == 8);
4464   assert(inst->condflags == DRCUML_COND_ALWAYS);
4465
4466   /* normalize parameters */
4467   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4468
4469   /* pick a target register for the general case */
4470   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4471
4472   /* set up a call to the read dword handler */
4473   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4474   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_dword);// call   read_dword
4475
4476   /* 64-bit form */
4477   emit_movsxd_r64_r32(&dst, dstreg, REG_EAX);                                 // movsxd dstreg,eax
4478   emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
4479
4480   return dst;
4481}
4482
4483
4484/*-------------------------------------------------
4485    op_read4m - process a READ4M opcode
4486-------------------------------------------------*/
4487
4488static x86code *op_read4m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4489{
4490   drcuml_parameter dstp, spacep, addrp, maskp;
4491
4492   /* validate instruction */
44934162   assert(inst->size == 4 || inst->size == 8);
44944163   assert(inst->condflags == DRCUML_COND_ALWAYS);
44954164
44964165   /* normalize parameters */
4497   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI);
4166   param_normalize_4(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI, &maskp, PTYPE_MRI, &spacesizep, PTYPE_I);
44984167
4499   /* set up a call to the read dword masked handler */
4500   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4501   emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &maskp);                           // mov    param2,maskp
4502   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_dword_masked);// call   read_dword_masked
4503
4504   /* store to appropriate target size */
4505   if (inst->size == 4)
4506      emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX);                           // mov   dstp,eax
4507   else if (inst->size == 8)
4508      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX);                           // mov   dstp,rax
4509
4510   return dst;
4511}
4512
4513
4514/*-------------------------------------------------
4515    op_read8u - process a READ8U opcode
4516-------------------------------------------------*/
4517
4518static x86code *op_read8u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4519{
4520   drcuml_parameter dstp, spacep, addrp;
4521
4522   /* validate instruction */
4523   assert(inst->size == 8);
4524   assert(inst->condflags == DRCUML_COND_ALWAYS);
4525
4526   /* normalize parameters */
4527   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4528
4529   /* set up a call to the read qword handler */
4530   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4531   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_qword);// call   read_qword
4532
4533   /* 64-bit form */
4534   emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX);                              // mov   dstp,rax
4535
4536   return dst;
4537}
4538
4539
4540/*-------------------------------------------------
4541    op_read8m - process a READ8M opcode
4542-------------------------------------------------*/
4543
4544static x86code *op_read8m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4545{
4546   drcuml_parameter dstp, spacep, addrp, maskp;
4547
4548   /* validate instruction */
4549   assert(inst->size == 8);
4550   assert(inst->condflags == DRCUML_COND_ALWAYS);
4551
4552   /* normalize parameters */
4553   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI);
4554
4555   /* set up a call to the read qword masked handler */
4556   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4557   emit_mov_r64_p64(drcbe, &dst, REG_PARAM2, &maskp);                           // mov    param2,maskp
4558   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_qword_masked);// call   read_qword_masked
4559
4560   /* 64-bit form */
4561   emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX);                              // mov   dstp,rax
4562
4563   return dst;
4564}
4565
4566
4567/*-------------------------------------------------
4568    op_write1 - process a WRITE1 opcode
4569-------------------------------------------------*/
4570
4571static x86code *op_write1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4572{
4573   drcuml_parameter spacep, addrp, srcp;
4574
4575   /* validate instruction */
4576   assert(inst->size == 4 || inst->size == 8);
4577   assert(inst->condflags == DRCUML_COND_ALWAYS);
4578
4579   /* normalize parameters */
4580   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI);
4581
45824168   /* set up a call to the write byte handler */
45834169   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4584   emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &srcp);                           // mov    param2,srcp
4585   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_byte);// call   write_byte
4586
4587   return dst;
4588}
4589
4590
4591/*-------------------------------------------------
4592    op_write2 - process a WRITE2 opcode
4593-------------------------------------------------*/
4594
4595static x86code *op_write2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4596{
4597   drcuml_parameter spacep, addrp, srcp;
4598
4599   /* validate instruction */
4600   assert(inst->size == 4 || inst->size == 8);
4601   assert(inst->condflags == DRCUML_COND_ALWAYS);
4602
4603   /* normalize parameters */
4604   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI);
4605
4606   /* set up a call to the write word handler */
4607   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4608   emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &srcp);                           // mov    param2,srcp
4609   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_word);// call   write_word
4610
4611   return dst;
4612}
4613
4614
4615/*-------------------------------------------------
4616    op_writ2m - process a WRIT2M opcode
4617-------------------------------------------------*/
4618
4619static x86code *op_writ2m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4620{
4621   drcuml_parameter spacep, addrp, maskp, srcp;
4622
4623   /* validate instruction */
4624   assert(inst->size == 4 || inst->size == 8);
4625   assert(inst->condflags == DRCUML_COND_ALWAYS);
4626
4627   /* normalize parameters */
4628   param_normalize_4(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &srcp, PTYPE_MRI);
4629
4630   /* set up a call to the write word handler */
4631   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4632   emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &srcp);                           // mov    param2,srcp
4633   emit_mov_r32_p32(drcbe, &dst, REG_PARAM3, &maskp);                           // mov    param3,maskp
4634   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_word_masked);// call   write_word_masked
4635   return dst;
4636}
4637
4638
4639/*-------------------------------------------------
4640    op_write4 - process a WRITE4 opcode
4641-------------------------------------------------*/
4642
4643static x86code *op_write4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4644{
4645   drcuml_parameter spacep, addrp, srcp;
4646
4647   /* validate instruction */
4648   assert(inst->size == 4 || inst->size == 8);
4649   assert(inst->condflags == DRCUML_COND_ALWAYS);
4650
4651   /* normalize parameters */
4652   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI);
4653
4654   /* set up a call to the write dword handler */
4655   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4656   emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &srcp);                           // mov    param2,srcp
4657   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_dword);// call   write_dword
4658
4659   return dst;
4660}
4661
4662
4663/*-------------------------------------------------
4664    op_writ4m - process a WRIT4M opcode
4665-------------------------------------------------*/
4666
4667static x86code *op_writ4m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4668{
4669   drcuml_parameter spacep, addrp, maskp, srcp;
4670
4671   /* validate instruction */
4672   assert(inst->size == 4 || inst->size == 8);
4673   assert(inst->condflags == DRCUML_COND_ALWAYS);
4674
4675   /* normalize parameters */
4676   param_normalize_4(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &srcp, PTYPE_MRI);
4677
4678   /* set up a call to the write word handler */
4679   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4680   emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &srcp);                           // mov    param2,srcp
4681   emit_mov_r32_p32(drcbe, &dst, REG_PARAM3, &maskp);                           // mov    param3,maskp
4682   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_dword_masked);// call   write_dword_masked
4683   return dst;
4684}
4685
4686
4687/*-------------------------------------------------
4688    op_write8 - process a WRITE8 opcode
4689-------------------------------------------------*/
4690
4691static x86code *op_write8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4692{
4693   drcuml_parameter spacep, addrp, srcp;
4694
4695   /* validate instruction */
4696   assert(inst->size == 8);
4697   assert(inst->condflags == DRCUML_COND_ALWAYS);
4698
4699   /* normalize parameters */
4700   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI);
4701
4702   /* set up a call to the write qword handler */
4703   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4704   emit_mov_r64_p64(drcbe, &dst, REG_PARAM2, &srcp);                           // mov    param2,srcp
4705   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_qword);// call   write_qword
4706
4707   return dst;
4708}
4709
4710
4711/*-------------------------------------------------
4712    op_writ8m - process a WRIT8M opcode
4713-------------------------------------------------*/
4714
4715static x86code *op_writ8m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4716{
4717   drcuml_parameter spacep, addrp, maskp, srcp;
4718
4719   /* validate instruction */
4720   assert(inst->size == 8);
4721   assert(inst->condflags == DRCUML_COND_ALWAYS);
4722
4723   /* normalize parameters */
4724   param_normalize_4(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &srcp, PTYPE_MRI);
4725
4726   /* set up a call to the write word handler */
4727   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
4728   emit_mov_r64_p64(drcbe, &dst, REG_PARAM2, &srcp);                           // mov    param2,srcp
4729   emit_mov_r64_p64(drcbe, &dst, REG_PARAM3, &maskp);                           // mov    param3,maskp
4730   emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_qword_masked);// call   write_qword_masked
4731   return dst;
4732}
4733
4734
4735/*-------------------------------------------------
4736    op_flags - process a FLAGS opcode
4737-------------------------------------------------*/
4738
4739static x86code *op_flags(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4740{
4741   drcuml_parameter dstp, maskp, tablep;
4742   int dstreg;
4743
4744   /* validate instruction */
4745   assert(inst->size == 4 || inst->size == 8);
4746   assert(inst->condflags == DRCUML_COND_ALWAYS);
4747
4748   /* normalize parameters */
4749   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &maskp, PTYPE_I, &tablep, PTYPE_M);
4750
4751   /* pick a target register for the general case */
4752   dstreg = param_select_register(REG_ECX, &dstp, NULL);
4753
4754   /* translate live flags into UML flags */
4755   emit_pushf(&dst);                                                   // pushf
4756   emit_pop_r64(&dst, REG_RAX);                                          // pop    rax
4757   emit_and_r32_imm(&dst, REG_EAX, 0x8c5);                                    // and    eax,0x8c5
4758   emit_movzx_r32_m8(&dst, REG_EAX, MBISD(REG_RBP, REG_RAX, 1, offset_from_rbp(drcbe, (FPTR)&drcbe->flagsmap[0])));
4759                                                                  // movzx  eax,[flags_map]
4760
4761   /* 32-bit form */
4762   if (inst->size == 4)
4170   if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD)
47634171   {
4764      /* no masking */
4765      if (maskp.value == 0xffffffff)
4766      {
4767         emit_mov_r32_m32(&dst, dstreg, MBISD(REG_RBP, REG_EAX, 4, offset_from_rbp(drcbe, tablep.value)));
4768                                                                  // mov    dstreg,[eax*4+table]
4769         emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                        // mov    dstp,dstreg
4770      }
4771
4772      /* general case */
4773      else
4774      {
4775         emit_mov_r32_p32(drcbe, &dst, dstreg, &dstp);                        // mov    dstreg,dstp
4776         emit_mov_r32_m32(&dst, REG_EDX, MBISD(REG_RBP, REG_EAX, 4, offset_from_rbp(drcbe, tablep.value)));
4777                                                                  // mov    edx,[eax*4+table]
4778         emit_and_r32_imm(&dst, dstreg, ~maskp.value);                        // and    dstreg,~mask
4779         emit_and_r32_imm(&dst, REG_EDX, maskp.value);                        // and    edx,mask
4780         emit_or_r32_r32(&dst, dstreg, REG_EDX);                              // or     dstreg,edx
4781         emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                        // mov    dstp,dstreg
4782      }
4172      emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &srcp);                        // mov    param2,srcp
4173      emit_mov_r32_p32(drcbe, &dst, REG_PARAM3, &maskp);                        // mov    param3,maskp
47834174   }
4784
4785   /* 64-bit form */
47864175   else
47874176   {
4788      /* no masking */
4789      if (maskp.value == U64(0xffffffffffffffff))
4790      {
4791         emit_mov_r64_m64(&dst, dstreg, MBISD(REG_RBP, REG_EAX, 8, offset_from_rbp(drcbe, tablep.value)));
4792                                                                  // mov    dstreg,[eax*8+table]
4793         emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                        // mov    dstp,dstreg
4794      }
4795
4796      /* general case */
4797      else
4798      {
4799         emit_mov_r64_p64(drcbe, &dst, dstreg, &dstp);                        // mov    dstreg,dstp
4800         emit_mov_r64_m64(&dst, REG_EDX, MBISD(REG_RBP, REG_EAX, 8, offset_from_rbp(drcbe, tablep.value)));
4801                                                                  // mov    edx,[eax*84+table]
4802         if (short_immediate(~maskp.value))
4803            emit_and_r64_imm(&dst, dstreg, ~maskp.value);                     // and    dstreg,~mask
4804         else
4805         {
4806            emit_mov_r64_imm(&dst, REG_R11, ~maskp.value);                     // mov    r11,~mask
4807            emit_and_r64_r64(&dst, dstreg, REG_R11);                        // and    dstreg,r11
4808         }
4809         if (short_immediate(maskp.value))
4810            emit_and_r64_imm(&dst, REG_EDX, maskp.value);                     // and    edx,mask
4811         else
4812         {
4813            emit_mov_r64_imm(&dst, REG_R11, maskp.value);                     // mov    r11,mask
4814            emit_and_r64_r64(&dst, REG_EDX, REG_R11);                        // and    edx,r11
4815         }
4816         emit_or_r64_r64(&dst, dstreg, REG_EDX);                              // or     dstreg,edx
4817         emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                        // mov    dstp,dstreg
4818      }
4177      emit_mov_r64_p64(drcbe, &dst, REG_PARAM2, &srcp);                        // mov    param2,srcp
4178      emit_mov_r64_p64(drcbe, &dst, REG_PARAM3, &maskp);                        // mov    param3,maskp
48194179   }
4180   if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
4181      emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_word_masked);
4182                                                                  // call   write_word_masked
4183   else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
4184      emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_dword_masked);
4185                                                                  // call   write_dword_masked
4186   else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
4187      emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_qword_masked);
4188                                                                  // call   write_qword_masked
48204189   return dst;
48214190}
48224191
48234192
48244193/*-------------------------------------------------
4825    op_setc - process a SETC opcode
4194    op_carry - process a CARRY opcode
48264195-------------------------------------------------*/
48274196
4828static x86code *op_setc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4197static x86code *op_carry(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
48294198{
48304199   drcuml_parameter srcp, bitp;
48314200
r2821r2822
48594228      if (bitp.type == DRCUML_PTYPE_IMMEDIATE)
48604229      {
48614230         if (srcp.type == DRCUML_PTYPE_MEMORY)
4862            emit_bt_m32_imm(&dst, MABS(srcp.value), bitp.value);               // bt     [srcp],bitp
4231            emit_bt_m32_imm(&dst, MABS(drcbe, srcp.value), bitp.value);            // bt     [srcp],bitp
48634232         else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
48644233            emit_bt_r32_imm(&dst, srcp.value, bitp.value);                     // bt     srcp,bitp
48654234      }
48664235      else
48674236      {
48684237         if (srcp.type == DRCUML_PTYPE_MEMORY)
4869            emit_bt_m32_r32(&dst, MABS(srcp.value), REG_ECX);                  // bt     [srcp],ecx
4238            emit_bt_m32_r32(&dst, MABS(drcbe, srcp.value), REG_ECX);            // bt     [srcp],ecx
48704239         else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
48714240            emit_bt_r32_r32(&dst, srcp.value, REG_ECX);                        // bt     srcp,ecx
48724241      }
r2821r2822
48784247      if (bitp.type == DRCUML_PTYPE_IMMEDIATE)
48794248      {
48804249         if (srcp.type == DRCUML_PTYPE_MEMORY)
4881            emit_bt_m64_imm(&dst, MABS(srcp.value), bitp.value);               // bt     [srcp],bitp
4250            emit_bt_m64_imm(&dst, MABS(drcbe, srcp.value), bitp.value);            // bt     [srcp],bitp
48824251         else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
48834252            emit_bt_r64_imm(&dst, srcp.value, bitp.value);                     // bt     srcp,bitp
48844253      }
48854254      else
48864255      {
48874256         if (srcp.type == DRCUML_PTYPE_MEMORY)
4888            emit_bt_m64_r64(&dst, MABS(srcp.value), REG_ECX);                  // bt     [srcp],ecx
4257            emit_bt_m64_r64(&dst, MABS(drcbe, srcp.value), REG_ECX);            // bt     [srcp],ecx
48894258         else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
48904259            emit_bt_r64_r64(&dst, srcp.value, REG_ECX);                        // bt     srcp,ecx
48914260      }
r2821r2822
48954264
48964265
48974266/*-------------------------------------------------
4267    op_set - process a SET opcode
4268-------------------------------------------------*/
4269
4270static x86code *op_set(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4271{
4272   drcuml_parameter dstp;
4273   int dstreg;
4274
4275   /* validate instruction */
4276   assert(inst->size == 4 || inst->size == 8);
4277   assert(inst->condflags >= DRCUML_COND_Z && inst->condflags < DRCUML_COND_MAX);
4278
4279   /* normalize parameters */
4280   param_normalize_1(drcbe, inst, &dstp, PTYPE_MR);
4281
4282   /* pick a target register for the general case */
4283   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4284
4285   /* set to AL */
4286   emit_setcc_r8(&dst, X86_CONDITION(inst->condflags), REG_AL);                  // setcc  al
4287   emit_movzx_r32_r8(&dst, dstreg, REG_AL);                                 // movzx  dstreg,al
4288
4289   /* 32-bit form */
4290   if (inst->size == 4)
4291      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4292
4293   /* 64-bit form */
4294   else if (inst->size == 8)
4295      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4296
4297   return dst;
4298}
4299
4300
4301/*-------------------------------------------------
48984302    op_mov - process a MOV opcode
48994303-------------------------------------------------*/
49004304
r2821r2822
50124416
50134417
50144418/*-------------------------------------------------
5015    op_zext1 - process a ZEXT1 opcode
4419    op_sext - process a SEXT opcode
50164420-------------------------------------------------*/
50174421
5018static x86code *op_zext1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4422static x86code *op_sext(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
50194423{
5020   drcuml_parameter dstp, srcp;
4424   drcuml_parameter dstp, srcp, sizep;
50214425   int dstreg;
50224426
50234427   /* validate instruction */
r2821r2822
50254429   assert(inst->condflags == DRCUML_COND_ALWAYS);
50264430
50274431   /* normalize parameters */
5028   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
4432   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI, &sizep, PTYPE_I);
50294433
50304434   /* degenerate cases -- convert to a move */
50314435   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5032      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (UINT8)srcp.value);
5033
5034   /* pick a target register for the general case */
5035   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5036
5037   /* general case */
5038   if (srcp.type == DRCUML_PTYPE_MEMORY)
5039      emit_movzx_r32_m8(&dst, dstreg, MABS(drcbe, srcp.value));                  // movzx dstreg,[srcp]
5040   else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5041      emit_movzx_r32_r8(&dst, dstreg, srcp.value);                           // movzx dstreg,srcp
5042
5043   /* 32-bit form */
5044   if (inst->size == 4)
5045      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5046
5047   /* 64-bit form */
5048   else if (inst->size == 8)
5049      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5050
5051   return dst;
5052}
5053
5054
5055/*-------------------------------------------------
5056    op_zext2 - process a ZEXT2 opcode
5057-------------------------------------------------*/
5058
5059static x86code *op_zext2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5060{
5061   drcuml_parameter dstp, srcp;
5062   int dstreg;
5063
5064   /* validate instruction */
5065   assert(inst->size == 4 || inst->size == 8);
5066   assert(inst->condflags == DRCUML_COND_ALWAYS);
5067
5068   /* normalize parameters */
5069   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5070
5071   /* degenerate cases -- convert to a move */
5072   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5073      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (UINT16)srcp.value);
5074
5075   /* pick a target register for the general case */
5076   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5077
5078   /* general case */
5079   if (srcp.type == DRCUML_PTYPE_MEMORY)
5080      emit_movzx_r32_m16(&dst, dstreg, MABS(drcbe, srcp.value));                  // movzx dstreg,[srcp]
5081   else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5082      emit_movzx_r32_r16(&dst, dstreg, srcp.value);                           // movzx dstreg,srcp
5083
5084   /* 32-bit form */
5085   if (inst->size == 4)
5086      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5087
5088   /* 64-bit form */
5089   else if (inst->size == 8)
5090      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5091
5092   return dst;
5093}
5094
5095
5096/*-------------------------------------------------
5097    op_zext4 - process a ZEXT4 opcode
5098-------------------------------------------------*/
5099
5100static x86code *op_zext4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5101{
5102   drcuml_parameter dstp, srcp;
5103   int dstreg;
5104
5105   /* validate instruction */
5106   assert(inst->size == 8);
5107   assert(inst->condflags == DRCUML_COND_ALWAYS);
5108
5109   /* normalize parameters */
5110   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5111
5112   /* degenerate cases -- convert to a move */
5113   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5114      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (UINT32)srcp.value);
5115
5116   /* pick a target register for the general case */
5117   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5118
5119   /* general case */
5120   if (srcp.type == DRCUML_PTYPE_MEMORY)
5121      emit_mov_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value));                  // mov   dstreg,[srcp]
5122   else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5123      emit_mov_r32_r32(&dst, dstreg, srcp.value);                              // mov   dstreg,srcp
5124   emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
5125
5126   return dst;
5127}
5128
5129
5130/*-------------------------------------------------
5131    op_sext1 - process a SEXT1 opcode
5132-------------------------------------------------*/
5133
5134static x86code *op_sext1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5135{
5136   drcuml_parameter dstp, srcp;
5137   int dstreg;
5138
5139   /* validate instruction */
5140   assert(inst->size == 4 || inst->size == 8);
5141   assert(inst->condflags == DRCUML_COND_ALWAYS);
5142
5143   /* normalize parameters */
5144   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5145
5146   /* degenerate cases -- convert to a move */
5147   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5148      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT8)srcp.value);
5149
5150   /* pick a target register for the general case */
5151   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5152
5153   /* convert 8-bit source registers */
5154   if (srcp.type == DRCUML_PTYPE_INT_REGISTER && (srcp.value & 4))
51554436   {
5156      emit_mov_r32_r32(&dst, REG_EAX, srcp.value);                           // mov   eax,srcp
5157      srcp.value = REG_EAX;
4437      if (sizep.value == DRCUML_SIZE_BYTE)
4438         return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT8)srcp.value);
4439      else if (sizep.value == DRCUML_SIZE_WORD)
4440         return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT16)srcp.value);
4441      else if (sizep.value == DRCUML_SIZE_DWORD)
4442         return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT32)srcp.value);
51584443   }
51594444
5160   /* 32-bit form */
5161   if (inst->size == 4)
5162   {
5163      /* general case */
5164      if (srcp.type == DRCUML_PTYPE_MEMORY)
5165         emit_movsx_r32_m8(&dst, dstreg, MABS(drcbe, srcp.value));               // movsx dstreg,[srcp]
5166      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5167         emit_movsx_r32_r8(&dst, dstreg, srcp.value);                        // movsx dstreg,srcp
5168      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5169   }
5170
5171   /* 64-bit form */
5172   else if (inst->size == 8)
5173   {
5174      /* general case */
5175      if (srcp.type == DRCUML_PTYPE_MEMORY)
5176         emit_movsx_r64_m8(&dst, dstreg, MABS(drcbe, srcp.value));               // movsx dstreg,[srcp]
5177      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5178         emit_movsx_r64_r8(&dst, dstreg, srcp.value);                        // movsx dstreg,srcp
5179      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5180   }
5181   return dst;
5182}
5183
5184
5185/*-------------------------------------------------
5186    op_sext2 - process a SEXT2 opcode
5187-------------------------------------------------*/
5188
5189static x86code *op_sext2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5190{
5191   drcuml_parameter dstp, srcp;
5192   int dstreg;
5193
5194   /* validate instruction */
5195   assert(inst->size == 4 || inst->size == 8);
5196   assert(inst->condflags == DRCUML_COND_ALWAYS);
5197
5198   /* normalize parameters */
5199   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5200
5201   /* degenerate cases -- convert to a move */
5202   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5203      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT16)srcp.value);
5204
52054445   /* pick a target register for the general case */
52064446   dstreg = param_select_register(REG_EAX, &dstp, NULL);
52074447
r2821r2822
52104450   {
52114451      /* general case */
52124452      if (srcp.type == DRCUML_PTYPE_MEMORY)
5213         emit_movsx_r32_m16(&dst, dstreg, MABS(drcbe, srcp.value));               // movsx dstreg,[srcp]
4453      {
4454         if (sizep.value == DRCUML_SIZE_BYTE)
4455            emit_movsx_r32_m8(&dst, dstreg, MABS(drcbe, srcp.value));            // movsx dstreg,[srcp]
4456         else if (sizep.value == DRCUML_SIZE_WORD)
4457            emit_movsx_r32_m16(&dst, dstreg, MABS(drcbe, srcp.value));            // movsx dstreg,[srcp]
4458         else if (sizep.value == DRCUML_SIZE_DWORD)
4459            emit_mov_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // mov   dstreg,[srcp]
4460      }
52144461      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5215         emit_movsx_r32_r16(&dst, dstreg, srcp.value);                        // movsx dstreg,srcp
4462      {
4463         if (sizep.value == DRCUML_SIZE_BYTE)
4464            emit_movsx_r32_r8(&dst, dstreg, srcp.value);                     // movsx dstreg,srcp
4465         else if (sizep.value == DRCUML_SIZE_WORD)
4466            emit_movsx_r32_r16(&dst, dstreg, srcp.value);                     // movsx dstreg,srcp
4467         else if (sizep.value == DRCUML_SIZE_DWORD)
4468            emit_mov_r32_r32(&dst, dstreg, srcp.value);                        // mov   dstreg,srcp
4469      }
52164470      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
52174471   }
52184472
r2821r2822
52214475   {
52224476      /* general case */
52234477      if (srcp.type == DRCUML_PTYPE_MEMORY)
5224         emit_movsx_r64_m16(&dst, dstreg, MABS(drcbe, srcp.value));               // movsx dstreg,[srcp]
4478      {
4479         if (sizep.value == DRCUML_SIZE_BYTE)
4480            emit_movsx_r64_m8(&dst, dstreg, MABS(drcbe, srcp.value));            // movsx dstreg,[srcp]
4481         else if (sizep.value == DRCUML_SIZE_WORD)
4482            emit_movsx_r64_m16(&dst, dstreg, MABS(drcbe, srcp.value));            // movsx dstreg,[srcp]
4483         else if (sizep.value == DRCUML_SIZE_DWORD)
4484            emit_movsxd_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // movsxd dstreg,[srcp]
4485         else if (sizep.value == DRCUML_SIZE_QWORD)
4486            emit_mov_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value));            // mov   dstreg,[srcp]
4487      }
52254488      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5226         emit_movsx_r64_r16(&dst, dstreg, srcp.value);                        // movsx dstreg,srcp
4489      {
4490         if (sizep.value == DRCUML_SIZE_BYTE)
4491            emit_movsx_r64_r8(&dst, dstreg, srcp.value);                     // movsx dstreg,srcp
4492         else if (sizep.value == DRCUML_SIZE_WORD)
4493            emit_movsx_r64_r16(&dst, dstreg, srcp.value);                     // movsx dstreg,srcp
4494         else if (sizep.value == DRCUML_SIZE_DWORD)
4495            emit_movsxd_r64_r32(&dst, dstreg, srcp.value);                     // movsxd dstreg,srcp
4496         else if (sizep.value == DRCUML_SIZE_QWORD)
4497            emit_mov_r64_r64(&dst, dstreg, srcp.value);                        // mov   dstreg,srcp
4498      }
52274499      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
52284500   }
52294501   return dst;
r2821r2822
52314503
52324504
52334505/*-------------------------------------------------
5234    op_sext4 - process a SEXT4 opcode
4506    op_roland - process an ROLAND opcode
52354507-------------------------------------------------*/
52364508
5237static x86code *op_sext4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4509static x86code *op_roland(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
52384510{
5239   drcuml_parameter dstp, srcp;
5240   int dstreg;
5241
5242   /* validate instruction */
5243   assert(inst->size == 8);
5244   assert(inst->condflags == DRCUML_COND_ALWAYS);
5245
5246   /* normalize parameters */
5247   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5248
5249   /* degenerate cases -- convert to a move */
5250   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5251      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT32)srcp.value);
5252
5253   /* pick a target register for the general case */
5254   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5255
5256   /* 64-bit form */
5257   if (inst->size == 8)
5258   {
5259      /* general case */
5260      if (srcp.type == DRCUML_PTYPE_MEMORY)
5261         emit_movsxd_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value));               // movsxd dstreg,[srcp]
5262      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5263         emit_movsxd_r64_r32(&dst, dstreg, srcp.value);                        // movsxd dstreg,srcp
5264      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5265   }
5266   return dst;
5267}
5268
5269
5270/*-------------------------------------------------
5271    op_xtract - process an XTRACT opcode
5272-------------------------------------------------*/
5273
5274static x86code *op_xtract(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5275{
52764511   drcuml_parameter dstp, srcp, shiftp, maskp;
52774512   int dstreg;
52784513
r2821r2822
53334568
53344569
53354570/*-------------------------------------------------
5336    op_insert - process an INSERT opcode
4571    op_rolins - process an ROLINS opcode
53374572-------------------------------------------------*/
53384573
5339static x86code *op_insert(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4574static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
53404575{
53414576   drcuml_parameter dstp, srcp, shiftp, maskp;
53424577   int dstreg;
r2821r2822
57534988      emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX);                           // mov   dstp,eax
57544989      if (compute_hi)
57554990         emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX);                        // mov   edstp,edx
4991
4992      /* compute flags */
4993      if (inst->condflags != 0)
4994      {
4995         if (compute_hi)
4996         {
4997            if (inst->condflags == DRCUML_FLAG_Z)
4998               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
4999            else if (inst->condflags == DRCUML_FLAG_S)
5000               emit_test_r32_r32(&dst, REG_EDX, REG_EDX);                     // test  edx,edx
5001            else
5002            {
5003               emit_movzx_r32_r16(&dst, REG_ECX, REG_AX);                     // movzx ecx,ax
5004               emit_shr_r32_imm(&dst, REG_EAX, 16);                        // shr   eax,16
5005               emit_or_r32_r32(&dst, REG_EDX, REG_ECX);                     // or    edx,ecx
5006               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5007            }
5008         }
5009         else
5010            emit_test_r32_r32(&dst, REG_EAX, REG_EAX);                        // test  eax,eax
5011      }
57565012   }
57575013
57585014   /* 64-bit form */
r2821r2822
57725028      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX);                           // mov   dstp,rax
57735029      if (compute_hi)
57745030         emit_mov_p64_r64(drcbe, &dst, &edstp, REG_RDX);                        // mov   edstp,rdx
5031
5032      /* compute flags */
5033      if (inst->condflags != 0)
5034      {
5035         if (compute_hi)
5036         {
5037            if (inst->condflags == DRCUML_FLAG_Z)
5038               emit_or_r64_r64(&dst, REG_RDX, REG_RAX);                     // or    rdx,rax
5039            else if (inst->condflags == DRCUML_FLAG_S)
5040               emit_test_r64_r64(&dst, REG_RDX, REG_RDX);                     // test  rdx,rdx
5041            else
5042            {
5043               emit_mov_r32_r32(&dst, REG_ECX, REG_EAX);                     // mov   ecx,eax
5044               emit_shr_r64_imm(&dst, REG_RAX, 32);                        // shr   rax,32
5045               emit_or_r64_r64(&dst, REG_RDX, REG_RCX);                     // or    rdx,rcx
5046               emit_or_r64_r64(&dst, REG_RDX, REG_RAX);                     // or    rdx,rax
5047            }
5048         }
5049         else
5050            emit_test_r64_r64(&dst, REG_RAX, REG_RAX);                        // test  rax,rax
5051      }
57755052   }
57765053   return dst;
57775054}
r2821r2822
58505127         emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX);                        // mov   dstp,eax
58515128         emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX);                        // mov   edstp,edx
58525129      }
5130
5131      /* compute flags */
5132      if (inst->condflags != 0)
5133      {
5134         if (compute_hi)
5135         {
5136            if (inst->condflags == DRCUML_FLAG_Z)
5137               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5138            else if (inst->condflags == DRCUML_FLAG_S)
5139               emit_test_r32_r32(&dst, REG_EDX, REG_EDX);                     // test  edx,edx
5140            else
5141            {
5142               emit_movzx_r32_r16(&dst, REG_ECX, REG_AX);                     // movzx ecx,ax
5143               emit_shr_r32_imm(&dst, REG_EAX, 16);                        // shr   eax,16
5144               emit_or_r32_r32(&dst, REG_EDX, REG_ECX);                     // or    edx,ecx
5145               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5146            }
5147         }
5148         else
5149            emit_test_r32_r32(&dst, REG_EAX, REG_EAX);                        // test  eax,eax
5150      }
58535151   }
58545152
58555153   /* 64-bit form */
r2821r2822
58925190         emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX);                        // mov   dstp,rax
58935191         emit_mov_p64_r64(drcbe, &dst, &edstp, REG_RDX);                        // mov   edstp,rdx
58945192      }
5193
5194      /* compute flags */
5195      if (inst->condflags != 0)
5196      {
5197         if (compute_hi)
5198         {
5199            if (inst->condflags == DRCUML_FLAG_Z)
5200               emit_or_r64_r64(&dst, REG_RDX, REG_RAX);                     // or    rdx,rax
5201            else if (inst->condflags == DRCUML_FLAG_S)
5202               emit_test_r64_r64(&dst, REG_RDX, REG_RDX);                     // test  rdx,rdx
5203            else
5204            {
5205               emit_mov_r32_r32(&dst, REG_ECX, REG_EAX);                     // mov   ecx,eax
5206               emit_shr_r64_imm(&dst, REG_RAX, 32);                        // shr   rax,32
5207               emit_or_r64_r64(&dst, REG_RDX, REG_RCX);                     // or    rdx,rcx
5208               emit_or_r64_r64(&dst, REG_RDX, REG_RAX);                     // or    rdx,rax
5209            }
5210         }
5211         else
5212            emit_test_r64_r64(&dst, REG_RAX, REG_RAX);                        // test  rax,rax
5213      }
58955214   }
58965215   return dst;
58975216}
r2821r2822
69456264   assert(inst->condflags == DRCUML_COND_ALWAYS);
69466265
69476266   /* normalize parameters */
6948   param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
6267   param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &addrp, PTYPE_MRI, &spacep, PTYPE_I);
69496268
69506269   /* set up a call to the read dword/qword handler */
69516270   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
r2821r2822
69866305   assert(inst->condflags == DRCUML_COND_ALWAYS);
69876306
69886307   /* normalize parameters */
6989   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MF);
6308   param_normalize_3(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MF, &spacep, PTYPE_I);
69906309
69916310   /* general case */
69926311   emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &addrp);                           // mov    param1,addrp
r2821r2822
70616380
70626381
70636382/*-------------------------------------------------
7064    op_ftoi4 - process a FTOI4 opcode
6383    op_ftoint - process a FTOINT opcode
70656384-------------------------------------------------*/
70666385
7067static x86code *op_ftoi4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
6386static x86code *op_ftoint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
70686387{
7069   drcuml_parameter dstp, srcp;
6388   drcuml_parameter dstp, srcp, sizep, roundp;
70706389   int dstreg;
70716390
70726391   /* validate instruction */
r2821r2822
70746393   assert(inst->condflags == DRCUML_COND_ALWAYS);
70756394
70766395   /* normalize parameters */
7077   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
6396   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF, &sizep, PTYPE_I, &roundp, PTYPE_I);
70786397
70796398   /* pick a target register for the general case */
70806399   dstreg = param_select_register(REG_EAX, &dstp, NULL);
70816400
7082   /* 32-bit form */
7083   if (inst->size == 4)
6401   /* set rounding mode if necessary */
6402   if (roundp.value != DRCUML_FMOD_DEFAULT && roundp.value != DRCUML_FMOD_TRUNC)
70846403   {
7085      if (srcp.type == DRCUML_PTYPE_MEMORY)
7086         emit_cvtss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtss2si dstreg,[srcp]
7087      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7088         emit_cvtss2si_r32_r128(&dst, dstreg, srcp.value);                     // cvtss2si dstreg,srcp
6404      emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave));                  // stmxcsr [ssemodesave]
6405      emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[roundp.value]));         // ldmxcsr fpcontrol[mode]
70896406   }
70906407
7091   /* 64-bit form */
7092   else if (inst->size == 8)
7093   {
7094      if (srcp.type == DRCUML_PTYPE_MEMORY)
7095         emit_cvtsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtsd2si dstreg,[srcp]
7096      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7097         emit_cvtsd2si_r32_r128(&dst, dstreg, srcp.value);                     // cvtsd2si dstreg,srcp
7098   }
7099
7100   /* general case */
7101   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
7102   return dst;
7103}
7104
7105
7106/*-------------------------------------------------
7107    op_ftoi4t - process a FTOI4T opcode
7108-------------------------------------------------*/
7109
7110static x86code *op_ftoi4t(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7111{
7112   drcuml_parameter dstp, srcp;
7113   int dstreg;
7114
7115   /* validate instruction */
7116   assert(inst->size == 4 || inst->size == 8);
7117   assert(inst->condflags == DRCUML_COND_ALWAYS);
7118
7119   /* normalize parameters */
7120   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7121
7122   /* pick a target register for the general case */
7123   dstreg = param_select_register(REG_EAX, &dstp, NULL);
7124
71256408   /* 32-bit form */
71266409   if (inst->size == 4)
71276410   {
7128      if (srcp.type == DRCUML_PTYPE_MEMORY)
7129         emit_cvttss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // cvttss2si dstreg,[srcp]
7130      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7131         emit_cvttss2si_r32_r128(&dst, dstreg, srcp.value);                     // cvttss2si dstreg,srcp
6411      /* 32-bit integer source */
6412      if (sizep.value == DRCUML_SIZE_DWORD)
6413      {
6414         if (srcp.type == DRCUML_PTYPE_MEMORY)
6415         {
6416            if (roundp.value != DRCUML_FMOD_TRUNC)
6417               emit_cvtss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value));      // cvtss2si dstreg,[srcp]
6418            else
6419               emit_cvttss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value));      // cvttss2si dstreg,[srcp]
6420         }
6421         else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
6422         {
6423            if (roundp.value != DRCUML_FMOD_TRUNC)
6424               emit_cvtss2si_r32_r128(&dst, dstreg, srcp.value);               // cvtss2si dstreg,srcp
6425            else
6426               emit_cvttss2si_r32_r128(&dst, dstreg, srcp.value);               // cvttss2si dstreg,srcp
6427         }
6428      }
6429
6430      /* 64-bit integer source */
6431      else if (sizep.value == DRCUML_SIZE_QWORD)
6432      {
6433         if (srcp.type == DRCUML_PTYPE_MEMORY)
6434         {
6435            if (roundp.value != DRCUML_FMOD_TRUNC)
6436               emit_cvtss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value));      // cvtss2si dstreg,[srcp]
6437            else
6438               emit_cvttss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value));      // cvttss2si dstreg,[srcp]
6439         }
6440         else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
6441         {
6442            if (roundp.value != DRCUML_FMOD_TRUNC)
6443               emit_cvtss2si_r64_r128(&dst, dstreg, srcp.value);               // cvtss2si dstreg,srcp
6444            else
6445               emit_cvttss2si_r64_r128(&dst, dstreg, srcp.value);               // cvttss2si dstreg,srcp
6446         }
6447      }
71326448   }
71336449
71346450   /* 64-bit form */
71356451   else if (inst->size == 8)
71366452   {
7137      if (srcp.type == DRCUML_PTYPE_MEMORY)
7138         emit_cvttsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value));            // cvttsd2si dstreg,[srcp]
7139      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7140         emit_cvttsd2si_r32_r128(&dst, dstreg, srcp.value);                     // cvttsd2si dstreg,srcp
7141   }
7142
7143   /* general case */
7144   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
7145   return dst;
7146}
7147
7148
7149/*-------------------------------------------------
7150    op_ftoi4x - process a FTOI4R/F/C opcode
7151-------------------------------------------------*/
7152
7153static x86code *op_ftoi4x(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst, int mode)
7154{
7155   drcuml_parameter dstp, srcp;
7156   int dstreg;
7157
7158   /* validate instruction */
7159   assert(inst->size == 4 || inst->size == 8);
7160   assert(inst->condflags == DRCUML_COND_ALWAYS);
7161
7162   /* normalize parameters */
7163   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7164
7165   /* pick a target register for the general case */
7166   dstreg = param_select_register(REG_EAX, &dstp, NULL);
7167
7168   /* non-SSE4.1 case */
7169   if (!drcbe->sse41 || inst->size == 8)
7170   {
7171      /* save and set the control word */
7172      emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave));                  // stmxcsr [ssemodesave]
7173      emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[mode]));               // ldmxcsr fpcontrol[mode]
7174
7175      /* 32-bit form */
7176      if (inst->size == 4)
6453      /* 32-bit integer source */
6454      if (sizep.value == DRCUML_SIZE_DWORD)
71776455      {
71786456         if (srcp.type == DRCUML_PTYPE_MEMORY)
7179            emit_cvtss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value));         // cvtss2si dstreg,[srcp]
6457         {
6458            if (roundp.value != DRCUML_FMOD_TRUNC)
6459               emit_cvtsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value));      // cvtsd2si dstreg,[srcp]
6460            else
6461               emit_cvttsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value));      // cvttsd2si dstreg,[srcp]
6462         }
71806463         else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7181            emit_cvtss2si_r32_r128(&dst, dstreg, srcp.value);                  // cvtss2si dstreg,srcp
6464         {
6465            if (roundp.value != DRCUML_FMOD_TRUNC)
6466               emit_cvtsd2si_r32_r128(&dst, dstreg, srcp.value);               // cvtsd2si dstreg,srcp
6467            else
6468               emit_cvttsd2si_r32_r128(&dst, dstreg, srcp.value);               // cvttsd2si dstreg,srcp
6469         }
71826470      }
71836471
7184      /* 64-bit form */
7185      else if (inst->size == 8)
6472      /* 64-bit integer source */
6473      else if (sizep.value == DRCUML_SIZE_QWORD)
71866474      {
71876475         if (srcp.type == DRCUML_PTYPE_MEMORY)
7188            emit_cvtsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value));         // cvtsd2si dstreg,[srcp]
6476         {
6477            if (roundp.value != DRCUML_FMOD_TRUNC)
6478               emit_cvtsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value));      // cvtsd2si dstreg,[srcp]
6479            else
6480               emit_cvttsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value));      // cvttsd2si dstreg,[srcp]
6481         }
71896482         else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7190            emit_cvtsd2si_r32_r128(&dst, dstreg, srcp.value);                  // cvtsd2si dstreg,srcp
6483         {
6484            if (roundp.value != DRCUML_FMOD_TRUNC)
6485               emit_cvtsd2si_r64_r128(&dst, dstreg, srcp.value);               // cvtsd2si dstreg,srcp
6486            else
6487               emit_cvttsd2si_r64_r128(&dst, dstreg, srcp.value);               // cvttsd2si dstreg,srcp
6488         }
71916489      }
7192
7193      /* restore control word and proceed */
7194      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
7195      emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave));                  // ldmxcsr [ssemodesave]
71966490   }
71976491
7198   /* SSE4.1 case */
6492   /* general case */
6493   if (sizep.value == DRCUML_SIZE_DWORD)
6494      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
71996495   else
7200   {
7201      /* 32-bit form */
7202      if (srcp.type == DRCUML_PTYPE_MEMORY)
7203         emit_roundss_r128_m32_imm(&dst, REG_XMM0, MABS(drcbe, srcp.value), fprnd_map[mode]);
7204                                                                  // roundss  xmm0,[srcp],mode
7205      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7206         emit_roundss_r128_r128_imm(&dst, REG_XMM0, srcp.value, fprnd_map[mode]);   // roundss  xmm0,srcp,mode
6496      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
72076497
7208      /* store to the destination */
7209      if (dstp.type == DRCUML_PTYPE_MEMORY)
7210         emit_movd_m32_r128(&dst, MABS(drcbe, dstp.value), REG_XMM0);            // movd     [dstp],xmm0
7211      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
7212         emit_movd_r32_r128(&dst, dstp.value, REG_XMM0);                        // movd     dstp,xmm0
7213   }
7214   return dst;
6498   /* restore rounding mode */
6499   if (roundp.value != DRCUML_FMOD_DEFAULT && roundp.value != DRCUML_FMOD_TRUNC)
6500      emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave));                  // ldmxcsr [ssemodesave]
72156501
6502   return dst;
72166503}
72176504
7218static x86code *op_ftoi4r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7219{
7220   return op_ftoi4x(drcbe, dst, inst, DRCUML_FMOD_ROUND);
7221}
72226505
7223static x86code *op_ftoi4f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7224{
7225   return op_ftoi4x(drcbe, dst, inst, DRCUML_FMOD_FLOOR);
7226}
7227
7228static x86code *op_ftoi4c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7229{
7230   return op_ftoi4x(drcbe, dst, inst, DRCUML_FMOD_CEIL);
7231}
7232
7233
72346506/*-------------------------------------------------
7235    op_ftoi8 - process a FTOI8 opcode
6507    op_ffrint - process a FFRINT opcode
72366508-------------------------------------------------*/
72376509
7238static x86code *op_ftoi8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
6510static x86code *op_ffrint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
72396511{
7240   drcuml_parameter dstp, srcp;
6512   drcuml_parameter dstp, srcp, sizep;
72416513   int dstreg;
72426514
72436515   /* validate instruction */
r2821r2822
72456517   assert(inst->condflags == DRCUML_COND_ALWAYS);
72466518
72476519   /* normalize parameters */
7248   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
6520   param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MRI, &sizep, PTYPE_I);
72496521
72506522   /* pick a target register for the general case */
7251   dstreg = param_select_register(REG_EAX, &dstp, NULL);
6523   dstreg = param_select_register(REG_XMM0, &dstp, NULL);
72526524
72536525   /* 32-bit form */
72546526   if (inst->size == 4)
72556527   {
7256      if (srcp.type == DRCUML_PTYPE_MEMORY)
7257         emit_cvtss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtss2si dstreg,[srcp]
7258      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7259         emit_cvtss2si_r64_r128(&dst, dstreg, srcp.value);                     // cvtss2si dstreg,srcp
7260   }
6528      /* 32-bit integer source */
6529      if (sizep.value == DRCUML_SIZE_DWORD)
6530      {
6531         if (srcp.type == DRCUML_PTYPE_MEMORY)
6532            emit_cvtsi2ss_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value));         // cvtsi2ss dstreg,[srcp]
6533         else
6534         {
6535            int srcreg = param_select_register(REG_EAX, &srcp, NULL);
6536            emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                     // mov      srcreg,srcp
6537            emit_cvtsi2ss_r128_r32(&dst, dstreg, srcreg);                     // cvtsi2ss dstreg,srcreg
6538         }
6539      }
72616540
7262   /* 64-bit form */
7263   else if (inst->size == 8)
7264   {
7265      if (srcp.type == DRCUML_PTYPE_MEMORY)
7266         emit_cvtsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtsd2si dstreg,[srcp]
7267      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7268         emit_cvtsd2si_r64_r128(&dst, dstreg, srcp.value);                     // cvtsd2si dstreg,srcp
6541      /* 64-bit integer source */
6542      else
6543      {
6544         if (srcp.type == DRCUML_PTYPE_MEMORY)
6545            emit_cvtsi2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value));         // cvtsi2ss dstreg,[srcp]
6546         else
6547         {
6548            int srcreg = param_select_register(REG_RAX, &srcp, NULL);
6549            emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp);                     // mov      srcreg,srcp
6550            emit_cvtsi2ss_r128_r64(&dst, dstreg, srcreg);                     // cvtsi2ss dstreg,srcreg
6551         }
6552      }
6553      emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg);                        // movss    dstp,dstreg
72696554   }
72706555
7271   /* general case */
7272   emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
7273   return dst;
7274}
7275
7276
7277/*-------------------------------------------------
7278    op_ftoi8t - process a FTOI8T opcode
7279-------------------------------------------------*/
7280
7281static x86code *op_ftoi8t(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7282{
7283   drcuml_parameter dstp, srcp;
7284   int dstreg;
7285
7286   /* validate instruction */
7287   assert(inst->size == 4 || inst->size == 8);
7288   assert(inst->condflags == DRCUML_COND_ALWAYS);
7289
7290   /* normalize parameters */
7291   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7292
7293   /* pick a target register for the general case */
7294   dstreg = param_select_register(REG_EAX, &dstp, NULL);
7295
7296   /* 32-bit form */
7297   if (inst->size == 4)
7298   {
7299      if (srcp.type == DRCUML_PTYPE_MEMORY)
7300         emit_cvttss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // cvttss2si dstreg,[srcp]
7301      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7302         emit_cvttss2si_r64_r128(&dst, dstreg, srcp.value);                     // cvttss2si dstreg,srcp
7303   }
7304
73056556   /* 64-bit form */
73066557   else if (inst->size == 8)
73076558   {
7308      if (srcp.type == DRCUML_PTYPE_MEMORY)
7309         emit_cvttsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value));            // cvttsd2si dstreg,[srcp]
7310      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7311         emit_cvttsd2si_r64_r128(&dst, dstreg, srcp.value);                     // cvttsd2si dstreg,srcp
7312   }
7313
7314   /* general case */
7315   emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
7316   return dst;
7317}
7318
7319
7320/*-------------------------------------------------
7321    op_ftoi8x - process a FTOI8R/F/C opcode
7322-------------------------------------------------*/
7323
7324static x86code *op_ftoi8x(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst, int mode)
7325{
7326   drcuml_parameter dstp, srcp;
7327   int dstreg;
7328
7329   /* validate instruction */
7330   assert(inst->size == 4 || inst->size == 8);
7331   assert(inst->condflags == DRCUML_COND_ALWAYS);
7332
7333   /* normalize parameters */
7334   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7335
7336   /* pick a target register for the general case */
7337   dstreg = param_select_register(REG_EAX, &dstp, NULL);
7338
7339   /* non-SSE4.1 case */
7340   if (!drcbe->sse41 || inst->size == 4)
7341   {
7342      /* save and set the control word */
7343      emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave));                  // stmxcsr [ssemodesave]
7344      emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[mode]));               // ldmxcsr fpcontrol[mode]
7345
7346      /* 32-bit form */
7347      if (inst->size == 4)
6559      /* 32-bit integer source */
6560      if (sizep.value == DRCUML_SIZE_DWORD)
73486561      {
73496562         if (srcp.type == DRCUML_PTYPE_MEMORY)
7350            emit_cvtss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value));         // cvtss2si dstreg,[srcp]
7351         else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7352            emit_cvtss2si_r64_r128(&dst, dstreg, srcp.value);                  // cvtss2si dstreg,srcp
6563            emit_cvtsi2sd_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value));         // cvtsi2sd dstreg,[srcp]
6564         else
6565         {
6566            int srcreg = param_select_register(REG_EAX, &srcp, NULL);
6567            emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                     // mov      srcreg,srcp
6568            emit_cvtsi2sd_r128_r32(&dst, dstreg, srcreg);                     // cvtsi2sd dstreg,srcreg
6569         }
73536570      }
73546571
7355      /* 64-bit form */
7356      else if (inst->size == 8)
6572      /* 64-bit integer source */
6573      else
73576574      {
73586575         if (srcp.type == DRCUML_PTYPE_MEMORY)
7359            emit_cvtsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value));         // cvtsd2si dstreg,[srcp]
7360         else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7361            emit_cvtsd2si_r64_r128(&dst, dstreg, srcp.value);                  // cvtsd2si dstreg,srcp
6576            emit_cvtsi2sd_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value));         // cvtsi2sd dstreg,[srcp]
6577         else
6578         {
6579            int srcreg = param_select_register(REG_EAX, &srcp, NULL);
6580            emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp);                     // mov      srcreg,srcp
6581            emit_cvtsi2sd_r128_r64(&dst, dstreg, srcreg);                     // cvtsi2sd dstreg,srcreg
6582         }
73626583      }
7363
7364      /* restore control word and proceed */
7365      emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
7366      emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave));                  // ldmxcsr [ssemodesave]
6584      emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg);                        // movsd    dstp,dstreg
73676585   }
7368
7369   /* SSE4.1 case */
7370   else
7371   {
7372      /* 64-bit form */
7373      if (srcp.type == DRCUML_PTYPE_MEMORY)
7374         emit_roundsd_r128_m64_imm(&dst, REG_XMM0, MABS(drcbe, srcp.value), fprnd_map[mode]);
7375                                                                  // roundsd  xmm0,[srcp],mode
7376      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7377         emit_roundsd_r128_r128_imm(&dst, REG_XMM0, srcp.value, fprnd_map[mode]);   // roundsd  xmm0,srcp,mode
7378
7379      /* store to the destination */
7380      if (dstp.type == DRCUML_PTYPE_MEMORY)
7381         emit_movq_m64_r128(&dst, MABS(drcbe, dstp.value), REG_XMM0);            // movq     [dstp],xmm0
7382      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
7383         emit_movq_r64_r128(&dst, dstp.value, REG_XMM0);                        // movq     dstp,xmm0
7384   }
73856586   return dst;
7386
73876587}
73886588
7389static x86code *op_ftoi8r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7390{
7391   return op_ftoi8x(drcbe, dst, inst, DRCUML_FMOD_ROUND);
7392}
73936589
7394static x86code *op_ftoi8f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7395{
7396   return op_ftoi8x(drcbe, dst, inst, DRCUML_FMOD_FLOOR);
7397}
7398
7399static x86code *op_ftoi8c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7400{
7401   return op_ftoi8x(drcbe, dst, inst, DRCUML_FMOD_CEIL);
7402}
7403
7404
74056590/*-------------------------------------------------
7406    op_ffrfs - process a FFRFS opcode
6591    op_ffrflt - process a FFRFLT opcode
74076592-------------------------------------------------*/
74086593
7409static x86code *op_ffrfs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
6594static x86code *op_ffrflt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
74106595{
7411   drcuml_parameter dstp, srcp;
6596   drcuml_parameter dstp, srcp, sizep;
74126597   int dstreg;
74136598
74146599   /* validate instruction */
7415   assert(inst->size == 8);
7416   assert(inst->condflags == DRCUML_COND_ALWAYS);
7417
7418   /* normalize parameters */
7419   param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF);
7420
7421   /* pick a target register for the general case */
7422   dstreg = param_select_register(REG_XMM0, &dstp, NULL);
7423
7424   /* general case */
7425   if (srcp.type == DRCUML_PTYPE_MEMORY)
7426      emit_cvtss2sd_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value));               // cvtss2sd dstreg,[srcp]
7427   else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7428      emit_cvtss2sd_r128_r128(&dst, dstreg, srcp.value);                        // cvtss2sd dstreg,srcp
7429   emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg);                           // movsd    dstp,dstreg
7430
7431   return dst;
7432}
7433
7434
7435/*-------------------------------------------------
7436    op_ffrfd - process a FFRFD opcode
7437-------------------------------------------------*/
7438
7439static x86code *op_ffrfd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7440{
7441   drcuml_parameter dstp, srcp;
7442   int dstreg;
7443
7444   /* validate instruction */
7445   assert(inst->size == 4);
7446   assert(inst->condflags == DRCUML_COND_ALWAYS);
7447
7448   /* normalize parameters */
7449   param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF);
7450
7451   /* pick a target register for the general case */
7452   dstreg = param_select_register(REG_XMM0, &dstp, NULL);
7453
7454   /* general case */
7455   if (srcp.type == DRCUML_PTYPE_MEMORY)
7456      emit_cvtsd2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value));               // cvtsd2ss dstreg,[srcp]
7457   else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
7458      emit_cvtsd2ss_r128_r128(&dst, dstreg, srcp.value);                        // cvtsd2ss dstreg,srcp
7459   emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg);                           // movss    dstp,dstreg
7460
7461   return dst;
7462}
7463
7464
7465/*-------------------------------------------------
7466    op_ffri4 - process a FFRI4 opcode
7467-------------------------------------------------*/
7468
7469static x86code *op_ffri4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7470{
7471   drcuml_parameter dstp, srcp;
7472   int dstreg;
7473
7474   /* validate instruction */
74756600   assert(inst->size == 4 || inst->size == 8);
74766601   assert(inst->condflags == DRCUML_COND_ALWAYS);
74776602
74786603   /* normalize parameters */
7479   param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF);
6604   param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF, &sizep, PTYPE_I);
74806605
74816606   /* pick a target register for the general case */
74826607   dstreg = param_select_register(REG_XMM0, &dstp, NULL);
74836608
7484   /* 32-bit form */
7485   if (inst->size == 4)
6609   /* single-to-double */
6610   if (inst->size == 8 && sizep.value == DRCUML_SIZE_DWORD)
74866611   {
74876612      if (srcp.type == DRCUML_PTYPE_MEMORY)
7488         emit_cvtsi2ss_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtsi2ss dstreg,[srcp]
7489      else
7490      {
7491         int srcreg = param_select_register(REG_EAX, &srcp, NULL);
7492         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov      srcreg,srcp
7493         emit_cvtsi2ss_r128_r32(&dst, dstreg, srcreg);                        // cvtsi2ss dstreg,srcreg
7494      }
7495      emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg);                        // movss    dstp,dstreg
6613         emit_cvtss2sd_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtss2sd dstreg,[srcp]
6614      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
6615         emit_cvtss2sd_r128_r128(&dst, dstreg, srcp.value);                     // cvtss2sd dstreg,srcp
6616      emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg);                        // movsd    dstp,dstreg
74966617   }
74976618
7498   /* 64-bit form */
7499   else if (inst->size == 8)
6619   /* double-to-single */
6620   else if (inst->size == 4 && sizep.value == DRCUML_SIZE_QWORD)
75006621   {
75016622      if (srcp.type == DRCUML_PTYPE_MEMORY)
7502         emit_cvtsi2sd_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtsi2sd dstreg,[srcp]
7503      else
7504      {
7505         int srcreg = param_select_register(REG_EAX, &srcp, NULL);
7506         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov      srcreg,srcp
7507         emit_cvtsi2sd_r128_r32(&dst, dstreg, srcreg);                        // cvtsi2sd dstreg,srcreg
7508      }
7509      emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg);                        // movsd    dstp,dstreg
6623         emit_cvtsd2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtsd2ss dstreg,[srcp]
6624      else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
6625         emit_cvtsd2ss_r128_r128(&dst, dstreg, srcp.value);                     // cvtsd2ss dstreg,srcp
6626      emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg);                        // movss    dstp,dstreg
75106627   }
75116628   return dst;
75126629}
75136630
75146631
75156632/*-------------------------------------------------
7516    op_ffri8 - process a FFRI8 opcode
6633    op_frnds - process a FRNDS opcode
75176634-------------------------------------------------*/
75186635
7519static x86code *op_ffri8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
6636static x86code *op_frnds(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
75206637{
75216638   drcuml_parameter dstp, srcp;
75226639   int dstreg;
75236640
75246641   /* validate instruction */
7525   assert(inst->size == 4 || inst->size == 8);
6642   assert(inst->size == 8);
75266643   assert(inst->condflags == DRCUML_COND_ALWAYS);
75276644
75286645   /* normalize parameters */
r2821r2822
75316648   /* pick a target register for the general case */
75326649   dstreg = param_select_register(REG_XMM0, &dstp, NULL);
75336650
7534   /* 32-bit form */
7535   if (inst->size == 4)
7536   {
7537      if (srcp.type == DRCUML_PTYPE_MEMORY)
7538         emit_cvtsi2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtsi2ss dstreg,[srcp]
7539      else
7540      {
7541         int srcreg = param_select_register(REG_EAX, &srcp, NULL);
7542         emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp);                        // mov      srcreg,srcp
7543         emit_cvtsi2ss_r128_r64(&dst, dstreg, srcreg);                        // cvtsi2ss dstreg,srcreg
7544      }
7545      emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg);                        // movss    dstp,dstreg
7546   }
7547
75486651   /* 64-bit form */
7549   else if (inst->size == 8)
7550   {
7551      if (srcp.type == DRCUML_PTYPE_MEMORY)
7552         emit_cvtsi2sd_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value));            // cvtsi2sd dstreg,[srcp]
7553      else
7554      {
7555         int srcreg = param_select_register(REG_EAX, &srcp, NULL);
7556         emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp);                        // mov      srcreg,srcp
7557         emit_cvtsi2sd_r128_r64(&dst, dstreg, srcreg);                        // cvtsi2sd dstreg,srcreg
7558      }
7559      emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg);                        // movsd    dstp,dstreg
7560   }
6652   if (srcp.type == DRCUML_PTYPE_MEMORY)
6653      emit_cvtsd2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value));               // cvtsd2ss dstreg,[srcp]
6654   else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
6655      emit_cvtsd2ss_r128_r128(&dst, dstreg, srcp.value);                        // cvtsd2ss dstreg,srcp
6656   emit_cvtss2sd_r128_r128(&dst, dstreg, dstreg);                              // cvtss2sd dstreg,dstreg
6657   emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg);                           // movsd    dstp,dstreg
75616658   return dst;
75626659}
75636660
src/emu/cpu/drcbec.c
r2821r2822
4747#define LEBIT         (0x1000 << (DRCUML_COND_LE & 15))
4848
4949
50/* internal opcodes */
51enum
52{
53   DRCUML_OP_LOAD1 = DRCUML_OP_MAX,
54   DRCUML_OP_LOAD2,
55   DRCUML_OP_LOAD4,
56   DRCUML_OP_LOAD8,
57   DRCUML_OP_LOADS1,
58   DRCUML_OP_LOADS2,
59   DRCUML_OP_LOADS4,
60   DRCUML_OP_LOADS8,
61   DRCUML_OP_STORE1,
62   DRCUML_OP_STORE2,
63   DRCUML_OP_STORE4,
64   DRCUML_OP_STORE8,
65   DRCUML_OP_READ1,
66   DRCUML_OP_READ2,
67   DRCUML_OP_READ4,
68   DRCUML_OP_READ8,
69   DRCUML_OP_READM1,
70   DRCUML_OP_READM2,
71   DRCUML_OP_READM4,
72   DRCUML_OP_READM8,
73   DRCUML_OP_WRITE1,
74   DRCUML_OP_WRITE2,
75   DRCUML_OP_WRITE4,
76   DRCUML_OP_WRITE8,
77   DRCUML_OP_WRITEM1,
78   DRCUML_OP_WRITEM2,
79   DRCUML_OP_WRITEM4,
80   DRCUML_OP_WRITEM8,
81   DRCUML_OP_SEXT1,
82   DRCUML_OP_SEXT2,
83   DRCUML_OP_SEXT4,
84   DRCUML_OP_SEXT8,
85   DRCUML_OP_FTOI4T,
86   DRCUML_OP_FTOI4R,
87   DRCUML_OP_FTOI4C,
88   DRCUML_OP_FTOI4F,
89   DRCUML_OP_FTOI4,
90   DRCUML_OP_FTOI8T,
91   DRCUML_OP_FTOI8R,
92   DRCUML_OP_FTOI8C,
93   DRCUML_OP_FTOI8F,
94   DRCUML_OP_FTOI8,
95   DRCUML_OP_FFRI4,
96   DRCUML_OP_FFRI8,
97   DRCUML_OP_FFRFS,
98   DRCUML_OP_FFRFD,
99};
50100
101
102
51103/***************************************************************************
52104    MACROS
53105***************************************************************************/
r2821r2822
337389      UINT8 psize[ARRAY_LENGTH(instlist->param)];
338390      drcuml_instruction modified_inst;
339391      int immedbytes, immedwords, pnum;
392      drcuml_opcode opcode = inst->opcode;
340393      void *immed;
341394
342395      /* handle most instructions generally, but a few special cases */
343      switch (inst->opcode)
396      switch (opcode)
344397      {
345398         /* when we hit a HANDLE opcode, register the current pointer for the handle */
346399         case DRCUML_OP_HANDLE:
r2821r2822
378431         case DRCUML_OP_JMP:
379432            assert(inst->numparams == 1);
380433            assert(inst->param[0].type == DRCUML_PTYPE_IMMEDIATE);
381            (dst++)->i = MAKE_OPCODE_FULL(inst->opcode, inst->size, inst->condflags, 1);
434            (dst++)->i = MAKE_OPCODE_FULL(opcode, inst->size, inst->condflags, 1);
382435            dst->inst = (drcbec_instruction *)drclabel_get_codeptr(drcbe->labels, inst->param[0].value, fixup_label, dst);
383436            dst++;
384437            break;
r2821r2822
387440         default:
388441
389442            /* for RECOVER opcodes, we need to fixup the second parameter into an immediate */
390            if (inst->opcode == DRCUML_OP_RECOVER)
443            if (opcode == DRCUML_OP_RECOVER)
391444            {
392445               assert(inst->param[1].type == DRCUML_PTYPE_MAPVAR);
393446               modified_inst = *inst;
r2821r2822
398451            /* determine the operand size for each operand; mostly this is just the instruction size */
399452            for (pnum = 0; pnum < inst->numparams; pnum++)
400453               psize[pnum] = inst->size;
401            if ((inst->opcode >= DRCUML_OP_LOAD1U && inst->opcode <= DRCUML_OP_LOAD8U) || inst->opcode == DRCUML_OP_FLOAD)
454            if (opcode == DRCUML_OP_LOAD || opcode == DRCUML_OP_FLOAD)
402455               psize[2] = 4;
403            if ((inst->opcode >= DRCUML_OP_STORE1 && inst->opcode <= DRCUML_OP_STORE8) || inst->opcode == DRCUML_OP_FSTORE)
456            if (opcode == DRCUML_OP_STORE || opcode == DRCUML_OP_FSTORE)
404457               psize[1] = 4;
405            if ((inst->opcode >= DRCUML_OP_READ1U && inst->opcode <= DRCUML_OP_READ8M) || inst->opcode == DRCUML_OP_FREAD)
406               psize[1] = psize[2] = 4;
407            if ((inst->opcode >= DRCUML_OP_WRITE1 && inst->opcode <= DRCUML_OP_WRIT8M) || inst->opcode == DRCUML_OP_FWRITE)
458            if (opcode == DRCUML_OP_READ || opcode == DRCUML_OP_READM || opcode == DRCUML_OP_FREAD)
408459               psize[0] = psize[1] = 4;
409            if (inst->opcode >= DRCUML_OP_FTOI4 && inst->opcode <= DRCUML_OP_FTOI4C)
410               psize[0] = 4;
411            if (inst->opcode >= DRCUML_OP_FTOI8 && inst->opcode <= DRCUML_OP_FTOI8C)
412               psize[0] = 8;
413            if ((inst->opcode >= DRCUML_OP_ZEXT1 && inst->opcode <= DRCUML_OP_SEXT4) || inst->opcode == DRCUML_OP_FFRFS || inst->opcode == DRCUML_OP_FFRI4)
460            if (opcode == DRCUML_OP_WRITE || opcode == DRCUML_OP_WRITEM || opcode == DRCUML_OP_FWRITE)
461               psize[0] = psize[1] = 4;
462            if (opcode == DRCUML_OP_SEXT && inst->param[2].value != DRCUML_SIZE_QWORD)
414463               psize[1] = 4;
415            if (inst->opcode == DRCUML_OP_FFRFD || inst->opcode == DRCUML_OP_FFRI8)
416               psize[1] = 8;
464            if (opcode == DRCUML_OP_FTOINT)
465               psize[0] = 1 << inst->param[2].value;
466            if (opcode == DRCUML_OP_FFRINT || opcode == DRCUML_OP_FFRFLT)
467               psize[1] = 1 << inst->param[2].value;
417468
469            /* pre-expand opcodes that encode size in them */
470            if (opcode == DRCUML_OP_LOAD)
471               opcode = DRCUML_OP_LOAD1 + (inst->param[3].value & 3);
472            if (opcode == DRCUML_OP_LOADS)
473               opcode = DRCUML_OP_LOADS1 + (inst->param[3].value & 3);
474            if (opcode == DRCUML_OP_STORE)
475               opcode = DRCUML_OP_STORE1 + (inst->param[3].value & 3);
476            if (opcode == DRCUML_OP_READ)
477               opcode = DRCUML_OP_READ1 + (inst->param[2].value & 3);
478            if (opcode == DRCUML_OP_READM)
479               opcode = DRCUML_OP_READM1 + (inst->param[3].value & 3);
480            if (opcode == DRCUML_OP_WRITE)
481               opcode = DRCUML_OP_WRITE1 + (inst->param[2].value & 3);
482            if (opcode == DRCUML_OP_WRITEM)
483               opcode = DRCUML_OP_WRITEM1 + (inst->param[3].value & 3);
484            if (opcode == DRCUML_OP_SEXT)
485               opcode = DRCUML_OP_SEXT1 + (inst->param[2].value & 3);
486            if (opcode == DRCUML_OP_FTOINT)
487               opcode = DRCUML_OP_FTOI4T + 5 * ((inst->param[2].value & 3) - 2) + inst->param[3].value;
488            if (opcode == DRCUML_OP_FFRINT)
489               opcode = DRCUML_OP_FFRI4 + ((inst->param[2].value & 3) - 2);
490            if (opcode == DRCUML_OP_FFRFLT)
491               opcode = DRCUML_OP_FFRFS + ((inst->param[2].value & 3) - 2);
492
418493            /* count how many bytes of immediates we need */
419494            immedbytes = 0;
420495            for (pnum = 0; pnum < inst->numparams; pnum++)
r2821r2822
426501            immedwords = (immedbytes + sizeof(drcbec_instruction) - 1) / sizeof(drcbec_instruction);
427502
428503            /* first item is the opcode, size, condition flags and length */
429            (dst++)->i = MAKE_OPCODE_FULL(inst->opcode, inst->size, inst->condflags, inst->numparams + immedwords);
504            (dst++)->i = MAKE_OPCODE_FULL(opcode, inst->size, inst->condflags, inst->numparams + immedwords);
430505
431506            /* immediates start after parameters */
432507            immed = dst + inst->numparams;
r2821r2822
504579   while (TRUE)
505580   {
506581      UINT32 opcode = (inst++)->i;
582
507583      switch (OPCODE_GET_SHORT(opcode))
508584      {
509585         /* ----------------------- Control Flow Operations ----------------------- */
r2821r2822
623699            PARAM0 = drcbe->state.exp;
624700            break;
625701
702         case MAKE_OPCODE_SHORT(DRCUML_OP_GETFLGS, 4, 0):   /* GETFLGS dst[,f]                */
703         case MAKE_OPCODE_SHORT(DRCUML_OP_GETFLGS, 4, 1):   /* GETFLGS dst[,f]                */
704            PARAM0 = flags;
705            break;
706
626707         case MAKE_OPCODE_SHORT(DRCUML_OP_SAVE, 4, 0):      /* SAVE    dst                    */
627708            *inst[0].state = drcbe->state;
628709            inst[0].state->flags = flags;
r2821r2822
636717
637718         /* ----------------------- 32-Bit Integer Operations ----------------------- */
638719
639         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1U, 4, 0):      /* LOAD1U  dst,base,index         */
720         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1, 4, 0):      /* LOAD    dst,base,index,BYTE    */
640721            PARAM0 = inst[1].puint8[PARAM2];
641722            break;
642723
643         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1S, 4, 0):      /* LOAD1S  dst,base,index         */
644            PARAM0 = inst[1].pint8[PARAM2];
724         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2, 4, 0):      /* LOAD    dst,base,index,WORD    */
725            PARAM0 = inst[1].puint16[PARAM2];
645726            break;
646727
647         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2U, 4, 0):      /* LOAD2U  dst,base,index         */
648            PARAM0 = inst[1].puint16[PARAM2];
728         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4, 4, 0):      /* LOAD    dst,base,index,DWORD   */
729            PARAM0 = inst[1].puint32[PARAM2];
649730            break;
650731
651         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2S, 4, 0):      /* LOAD2S  dst,base,index         */
732         case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1, 4, 0):      /* LOADS   dst,base,index,BYTE    */
733            PARAM0 = inst[1].pint8[PARAM2];
734            break;
735
736         case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2, 4, 0):      /* LOADS   dst,base,index,WORD    */
652737            PARAM0 = inst[1].pint16[PARAM2];
653738            break;
654739
655         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4U, 4, 0):      /* LOAD4U  dst,base,index         */
656            PARAM0 = inst[1].puint32[PARAM2];
740         case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4, 4, 0):      /* LOADS   dst,base,index,DWORD   */
741            PARAM0 = inst[1].pint32[PARAM2];
657742            break;
658743
659         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1, 4, 0):      /* STORE1  dst,base,index         */
744         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1, 4, 0):      /* STORE  dst,base,index,BYTE    */
660745            inst[0].puint8[PARAM1] = PARAM2;
661746            break;
662747
663         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2, 4, 0):      /* STORE2  dst,base,index         */
748         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2, 4, 0):      /* STORE  dst,base,index,WORD    */
664749            inst[0].puint16[PARAM1] = PARAM2;
665750            break;
666751
667         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4, 4, 0):      /* STORE4  dst,base,index         */
752         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4, 4, 0):      /* STORE  dst,base,index,DWORD   */
668753            inst[0].puint32[PARAM1] = PARAM2;
669754            break;
670755
671         case MAKE_OPCODE_SHORT(DRCUML_OP_READ1U, 4, 0):      /* READ1U  dst,space,src1         */
672            PARAM0 = (UINT8)(*active_address_space[PARAM1].accessors->read_byte)(PARAM2);
756         case MAKE_OPCODE_SHORT(DRCUML_OP_READ1, 4, 0):      /* READ    dst,src1,space_BYTE    */
757            PARAM0 = (UINT8)(*active_address_space[PARAM2 / 16].accessors->read_byte)(PARAM1);
673758            break;
674759
675         case MAKE_OPCODE_SHORT(DRCUML_OP_READ1S, 4, 0):      /* READ1S  dst,space,src1         */
676            PARAM0 = (INT8)(*active_address_space[PARAM1].accessors->read_byte)(PARAM2);
760         case MAKE_OPCODE_SHORT(DRCUML_OP_READ2, 4, 0):      /* READ    dst,src1,space_WORD    */
761            PARAM0 = (UINT16)(*active_address_space[PARAM2 / 16].accessors->read_word)(PARAM1);
677762            break;
678763
679         case MAKE_OPCODE_SHORT(DRCUML_OP_READ2U, 4, 0):      /* READ2U  dst,space,src1         */
680            PARAM0 = (UINT16)(*active_address_space[PARAM1].accessors->read_word)(PARAM2);
764         case MAKE_OPCODE_SHORT(DRCUML_OP_READ4, 4, 0):      /* READ    dst,src1,space_DWORD   */
765            PARAM0 = (UINT32)(*active_address_space[PARAM2 / 16].accessors->read_dword)(PARAM1);
681766            break;
682767
683         case MAKE_OPCODE_SHORT(DRCUML_OP_READ2S, 4, 0):      /* READ2S  dst,space,src1         */
684            PARAM0 = (INT16)(*active_address_space[PARAM1].accessors->read_word)(PARAM2);
768         case MAKE_OPCODE_SHORT(DRCUML_OP_READM2, 4, 0):      /* READM   dst,src1,mask,space_WORD */
769            PARAM0 = (UINT16)(*active_address_space[PARAM3 / 16].accessors->read_word_masked)(PARAM1, PARAM2);
685770            break;
686771
687         case MAKE_OPCODE_SHORT(DRCUML_OP_READ2M, 4, 0):      /* READ2M  dst,space,src1,mask    */
688            PARAM0 = (UINT16)(*active_address_space[PARAM1].accessors->read_word_masked)(PARAM2, PARAM3);
772         case MAKE_OPCODE_SHORT(DRCUML_OP_READM4, 4, 0):      /* READM   dst,src1,mask,space_DWORD */
773            PARAM0 = (UINT32)(*active_address_space[PARAM3 / 16].accessors->read_dword_masked)(PARAM1, PARAM2);
689774            break;
690775
691         case MAKE_OPCODE_SHORT(DRCUML_OP_READ4U, 4, 0):      /* READ4U  dst,space,src1         */
692            PARAM0 = (UINT32)(*active_address_space[PARAM1].accessors->read_dword)(PARAM2);
776         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE1, 4, 0):      /* WRITE   dst,src1,space_BYTE     */
777            (*active_address_space[PARAM2 / 16].accessors->write_byte)(PARAM0, PARAM1);
693778            break;
694779
695         case MAKE_OPCODE_SHORT(DRCUML_OP_READ4M, 4, 0):      /* READ4M  dst,space,src1,mask    */
696            PARAM0 = (UINT32)(*active_address_space[PARAM1].accessors->read_dword_masked)(PARAM2, PARAM3);
780         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE2, 4, 0):      /* WRITE   dst,src1,space_WORD     */
781            (*active_address_space[PARAM2 / 16].accessors->write_word)(PARAM0, PARAM1);
697782            break;
698783
699         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE1, 4, 0):      /* WRITE1  space,dst,src1         */
700            (*active_address_space[PARAM0].accessors->write_byte)(PARAM1, PARAM2);
784         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE4, 4, 0):      /* WRITE   dst,src1,space_DWORD    */
785            (*active_address_space[PARAM2 / 16].accessors->write_dword)(PARAM0, PARAM1);
701786            break;
702787
703         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE2, 4, 0):      /* WRITE2  space,dst,src1         */
704            (*active_address_space[PARAM0].accessors->write_word)(PARAM1, PARAM2);
788         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM2, 4, 0):   /* WRITEM  dst,src1,mask,space_WORD */
789            (*active_address_space[PARAM3 / 16].accessors->write_word_masked)(PARAM0, PARAM1, PARAM2);
705790            break;
706791
707         case MAKE_OPCODE_SHORT(DRCUML_OP_WRIT2M, 4, 0):      /* WRIT2M  space,dst,mask,src1    */
708            (*active_address_space[PARAM0].accessors->write_word_masked)(PARAM1, PARAM2, PARAM3);
792         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM4, 4, 0):   /* WRITEM  dst,src1,mask,space_DWORD */
793            (*active_address_space[PARAM3 / 16].accessors->write_dword_masked)(PARAM0, PARAM1, PARAM2);
709794            break;
710795
711         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE4, 4, 0):      /* WRITE4  space,dst,src1         */
712            (*active_address_space[PARAM0].accessors->write_dword)(PARAM1, PARAM2);
713            break;
714
715         case MAKE_OPCODE_SHORT(DRCUML_OP_WRIT4M, 4, 0):      /* WRIT4M  space,dst,mask,src1    */
716            (*active_address_space[PARAM0].accessors->write_dword_masked)(PARAM1, PARAM2, PARAM3);
717            break;
718
719         case MAKE_OPCODE_SHORT(DRCUML_OP_FLAGS, 4, 0):      /* FLAGS   dst,mask,table         */
720            PARAM0 = (PARAM0 & ~PARAM1) | (inst[2].puint32[flags & 0x1f] & PARAM1);
721            break;
722
723         case MAKE_OPCODE_SHORT(DRCUML_OP_SETC, 4, 0):      /* SETC    src,bitnum             */
796         case MAKE_OPCODE_SHORT(DRCUML_OP_CARRY, 4, 0):      /* CARRY   src,bitnum             */
724797            flags = (flags & ~DRCUML_FLAG_C) | ((PARAM0 >> (PARAM1 & 31)) & DRCUML_FLAG_C);
725798            break;
726799
r2821r2822
733806            PARAM0 = PARAM1;
734807            break;
735808
736         case MAKE_OPCODE_SHORT(DRCUML_OP_ZEXT1, 4, 0):      /* ZEXT1   dst,src                */
737            PARAM0 = (UINT8)PARAM1;
809         case MAKE_OPCODE_SHORT(DRCUML_OP_SET, 4, 1):      /* SET     dst,c                  */
810            PARAM0 = OPCODE_FAIL_CONDITION(opcode, flags) ? 0 : 1;
738811            break;
739812
740         case MAKE_OPCODE_SHORT(DRCUML_OP_ZEXT2, 4, 0):      /* ZEXT2   dst,src                */
741            PARAM0 = (UINT16)PARAM1;
742            break;
743
744813         case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT1, 4, 0):      /* SEXT1   dst,src                */
745814            PARAM0 = (INT8)PARAM1;
746815            break;
r2821r2822
749818            PARAM0 = (INT16)PARAM1;
750819            break;
751820
752         case MAKE_OPCODE_SHORT(DRCUML_OP_XTRACT, 4, 0):      /* XTRACT  dst,src,count,mask[,f] */
821         case MAKE_OPCODE_SHORT(DRCUML_OP_ROLAND, 4, 0):      /* ROLAND  dst,src,count,mask[,f] */
753822            shift = PARAM2 & 31;
754823            PARAM0 = ((PARAM1 << shift) | (PARAM1 >> (32 - shift))) & PARAM3;
755824            break;
756825
757         case MAKE_OPCODE_SHORT(DRCUML_OP_INSERT, 4, 0):      /* INSERT  dst,src,count,mask[,f] */
826         case MAKE_OPCODE_SHORT(DRCUML_OP_ROLINS, 4, 0):      /* ROLINS  dst,src,count,mask[,f] */
758827            shift = PARAM2 & 31;
759828            PARAM0 = (PARAM0 & ~PARAM3) | (((PARAM1 << shift) | (PARAM1 >> (32 - shift))) & PARAM3);
760829            break;
r2821r2822
10251094
10261095         /* ----------------------- 64-Bit Integer Operations ----------------------- */
10271096
1028         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1U, 8, 0):      /* DLOAD1U dst,base,index         */
1097         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1, 8, 0):      /* DLOAD   dst,base,index,BYTE    */
10291098            DPARAM0 = inst[1].puint8[PARAM2];
10301099            break;
10311100
1032         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1S, 8, 0):      /* DLOAD1S dst,base,index         */
1033            DPARAM0 = inst[1].pint8[PARAM2];
1101         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2, 8, 0):      /* DLOAD   dst,base,index,WORD    */
1102            DPARAM0 = inst[1].puint16[PARAM2];
10341103            break;
10351104
1036         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2U, 8, 0):      /* DLOAD2U dst,base,index         */
1037            DPARAM0 = inst[1].puint16[PARAM2];
1105         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4, 8, 0):      /* DLOAD   dst,base,index,DWORD   */
1106            DPARAM0 = inst[1].puint32[PARAM2];
10381107            break;
10391108
1040         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2S, 8, 0):      /* DLOAD2S dst,base,index         */
1041            DPARAM0 = inst[1].pint16[PARAM2];
1109         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD8, 8, 0):      /* DLOAD   dst,base,index,QWORD   */
1110            DPARAM0 = inst[1].puint64[PARAM2];
10421111            break;
10431112
1044         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4U, 8, 0):      /* DLOAD4U dst,base,index         */
1045            DPARAM0 = inst[1].puint32[PARAM2];
1113         case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1, 8, 0):      /* DLOADS  dst,base,index,BYTE    */
1114            DPARAM0 = inst[1].pint8[PARAM2];
10461115            break;
10471116
1048         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4S, 8, 0):      /* DLOAD4S dst,base,index         */
1049            DPARAM0 = inst[1].pint32[PARAM2];
1117         case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2, 8, 0):      /* DLOADS  dst,base,index,WORD    */
1118            DPARAM0 = inst[1].pint16[PARAM2];
10501119            break;
10511120
1052         case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD8U, 8, 0):      /* DLOAD8U dst,base,index         */
1053            DPARAM0 = inst[1].puint64[PARAM2];
1121         case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4, 8, 0):      /* DLOADS  dst,base,index,DWORD   */
1122            DPARAM0 = inst[1].pint32[PARAM2];
10541123            break;
10551124
1056         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1, 8, 0):      /* DSTORE1 dst,base,index         */
1125         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1, 8, 0):      /* DSTORE dst,base,index,BYTE    */
10571126            inst[0].puint8[PARAM1] = DPARAM2;
10581127            break;
10591128
1060         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2, 8, 0):      /* DSTORE2 dst,base,index         */
1129         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2, 8, 0):      /* DSTORE dst,base,index,WORD    */
10611130            inst[0].puint16[PARAM1] = DPARAM2;
10621131            break;
10631132
1064         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4, 8, 0):      /* DSTORE4 dst,base,index         */
1133         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4, 8, 0):      /* DSTORE dst,base,index,DWORD   */
10651134            inst[0].puint32[PARAM1] = DPARAM2;
10661135            break;
10671136
1068         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE8, 8, 0):      /* DSTORE8 dst,base,index         */
1137         case MAKE_OPCODE_SHORT(DRCUML_OP_STORE8, 8, 0):      /* DSTORE dst,base,index,QWORD   */
10691138            inst[0].puint64[PARAM1] = DPARAM2;
10701139            break;
10711140
1072         case MAKE_OPCODE_SHORT(DRCUML_OP_READ1U, 8, 0):      /* DREAD1U dst,space,src1         */
1073            DPARAM0 = (UINT8)(*active_address_space[PARAM1].accessors->read_byte)(PARAM2);
1141         case MAKE_OPCODE_SHORT(DRCUML_OP_READ1, 8, 0):      /* DREAD   dst,src1,space_BYTE    */
1142            DPARAM0 = (UINT8)(*active_address_space[PARAM2 / 16].accessors->read_byte)(PARAM1);
10741143            break;
10751144
1076         case MAKE_OPCODE_SHORT(DRCUML_OP_READ1S, 8, 0):      /* DREAD1S dst,space,src1         */
1077            DPARAM0 = (INT8)(*active_address_space[PARAM1].accessors->read_byte)(PARAM2);
1145         case MAKE_OPCODE_SHORT(DRCUML_OP_READ2, 8, 0):      /* DREAD   dst,src1,space_WORD    */
1146            DPARAM0 = (UINT16)(*active_address_space[PARAM2 / 16].accessors->read_word)(PARAM1);
10781147            break;
10791148
1080         case MAKE_OPCODE_SHORT(DRCUML_OP_READ2U, 8, 0):      /* DREAD2U dst,space,src1         */
1081            DPARAM0 = (UINT16)(*active_address_space[PARAM1].accessors->read_word)(PARAM2);
1149         case MAKE_OPCODE_SHORT(DRCUML_OP_READ4, 8, 0):      /* DREAD   dst,src1,space_DWORD   */
1150            DPARAM0 = (UINT32)(*active_address_space[PARAM2 / 16].accessors->read_dword)(PARAM1);
10821151            break;
10831152
1084         case MAKE_OPCODE_SHORT(DRCUML_OP_READ2S, 8, 0):      /* DREAD2S dst,space,src1         */
1085            DPARAM0 = (INT16)(*active_address_space[PARAM1].accessors->read_word)(PARAM2);
1153         case MAKE_OPCODE_SHORT(DRCUML_OP_READ8, 8, 0):      /* DREAD   dst,src1,space_QOWRD   */
1154            DPARAM0 = (UINT64)(*active_address_space[PARAM2 / 16].accessors->read_qword)(PARAM1);
10861155            break;
10871156
1088         case MAKE_OPCODE_SHORT(DRCUML_OP_READ2M, 8, 0):      /* DREAD2M dst,space,src1,mask    */
1089            DPARAM0 = (UINT16)(*active_address_space[PARAM1].accessors->read_word_masked)(PARAM2, DPARAM3);
1157         case MAKE_OPCODE_SHORT(DRCUML_OP_READM2, 8, 0):      /* DREADM  dst,src1,mask,space_WORD */
1158            DPARAM0 = (UINT16)(*active_address_space[PARAM3 / 16].accessors->read_word_masked)(PARAM1, PARAM2);
10901159            break;
10911160
1092         case MAKE_OPCODE_SHORT(DRCUML_OP_READ4U, 8, 0):      /* DREAD4U dst,space,src1         */
1093            DPARAM0 = (UINT32)(*active_address_space[PARAM1].accessors->read_dword)(PARAM2);
1161         case MAKE_OPCODE_SHORT(DRCUML_OP_READM4, 8, 0):      /* DREADM  dst,src1,mask,space_DWORD */
1162            DPARAM0 = (UINT32)(*active_address_space[PARAM3 / 16].accessors->read_dword_masked)(PARAM1, PARAM2);
10941163            break;
10951164
1096         case MAKE_OPCODE_SHORT(DRCUML_OP_READ4S, 8, 0):      /* DREAD4S dst,space,src1         */
1097            DPARAM0 = (INT32)(*active_address_space[PARAM1].accessors->read_dword)(PARAM2);
1165         case MAKE_OPCODE_SHORT(DRCUML_OP_READM8, 8, 0):      /* DREADM  dst,src1,mask,space_QWORD */
1166            DPARAM0 = (UINT64)(*active_address_space[PARAM3 / 16].accessors->read_qword_masked)(PARAM1, PARAM2);
10981167            break;
10991168
1100         case MAKE_OPCODE_SHORT(DRCUML_OP_READ4M, 8, 0):      /* DREAD4M dst,space,src1,mask    */
1101            DPARAM0 = (UINT32)(*active_address_space[PARAM1].accessors->read_dword_masked)(PARAM2, DPARAM3);
1169         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE1, 8, 0):      /* DWRITE  dst,src1,space_BYTE    */
1170            (*active_address_space[PARAM2 / 16].accessors->write_byte)(PARAM0, PARAM1);
11021171            break;
11031172
1104         case MAKE_OPCODE_SHORT(DRCUML_OP_READ8U, 8, 0):      /* DREAD8U dst,space,src1         */
1105            DPARAM0 = (UINT64)(*active_address_space[PARAM1].accessors->read_qword)(PARAM2);
1173         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE2, 8, 0):      /* DWRITE  dst,src1,space_WORD    */
1174            (*active_address_space[PARAM2 / 16].accessors->write_word)(PARAM0, PARAM1);
11061175            break;
11071176
1108         case MAKE_OPCODE_SHORT(DRCUML_OP_READ8M, 8, 0):      /* DREAD8M dst,space,src1,mask    */
1109            DPARAM0 = (UINT64)(*active_address_space[PARAM1].accessors->read_qword_masked)(PARAM2, DPARAM3);
1177         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE4, 8, 0):      /* DWRITE  dst,src1,space_DWORD   */
1178            (*active_address_space[PARAM2 / 16].accessors->write_dword)(PARAM0, PARAM1);
11101179            break;
11111180
1112         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE1, 8, 0):      /* DWRITE1 space,dst,src1         */
1113            (*active_address_space[PARAM0].accessors->write_byte)(PARAM1, DPARAM2);
1181         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE8, 8, 0):      /* DWRITE  dst,src1,space_QWORD   */
1182            (*active_address_space[PARAM2 / 16].accessors->write_qword)(PARAM0, PARAM1);
11141183            break;
11151184
1116         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE2, 8, 0):      /* DWRITE2 space,dst,src1         */
1117            (*active_address_space[PARAM0].accessors->write_word)(PARAM1, DPARAM2);
1185         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM2, 8, 0):   /* DWRITEM dst,src1,mask,space_WORD */
1186            (*active_address_space[PARAM3 / 16].accessors->write_word_masked)(PARAM0, DPARAM1, DPARAM2);
11181187            break;
11191188
1120         case MAKE_OPCODE_SHORT(DRCUML_OP_WRIT2M, 8, 0):      /* DWRIT2M space,dst,mask,src1    */
1121            (*active_address_space[PARAM0].accessors->write_word_masked)(PARAM1, DPARAM3, DPARAM2);
1189         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM4, 8, 0):   /* DWRITEM dst,src1,mask,space_DWORD */
1190            (*active_address_space[PARAM3 / 16].accessors->write_dword_masked)(PARAM0, DPARAM1, DPARAM2);
11221191            break;
11231192
1124         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE4, 8, 0):      /* DWRITE4 space,dst,src1         */
1125            (*active_address_space[PARAM0].accessors->write_dword)(PARAM1, DPARAM2);
1193         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM8, 8, 0):   /* DWRITEM dst,src1,mask,space_QWORD */
1194            (*active_address_space[PARAM3 / 16].accessors->write_qword_masked)(PARAM0, DPARAM1, DPARAM2);
11261195            break;
11271196
1128         case MAKE_OPCODE_SHORT(DRCUML_OP_WRIT4M, 8, 0):      /* DWRIT4M space,dst,mask,src1    */
1129            (*active_address_space[PARAM0].accessors->write_dword_masked)(PARAM1, DPARAM3, DPARAM2);
1130            break;
1131
1132         case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE8, 8, 0):      /* DWRITE8 space,dst,src1         */
1133            (*active_address_space[PARAM0].accessors->write_qword)(PARAM1, DPARAM2);
1134            break;
1135
1136         case MAKE_OPCODE_SHORT(DRCUML_OP_WRIT8M, 8, 0):      /* DWRIT8M space,dst,mask,src1    */
1137            (*active_address_space[PARAM0].accessors->write_qword_masked)(PARAM1, DPARAM3, DPARAM2);
1138            break;
1139
1140         case MAKE_OPCODE_SHORT(DRCUML_OP_FLAGS, 8, 0):      /* DFLAGS  dst,mask,table         */
1141            DPARAM0 = (DPARAM0 & ~DPARAM1) | (inst[2].puint64[flags & 0x0f] & DPARAM1);
1142            break;
1143
1144         case MAKE_OPCODE_SHORT(DRCUML_OP_SETC, 8, 0):      /* DSETC   src,bitnum             */
1197         case MAKE_OPCODE_SHORT(DRCUML_OP_CARRY, 8, 0):      /* DCARRY  src,bitnum             */
11451198            flags = (flags & ~DRCUML_FLAG_C) | ((DPARAM0 >> (DPARAM1 & 63)) & DRCUML_FLAG_C);
11461199            break;
11471200
r2821r2822
11541207            DPARAM0 = DPARAM1;
11551208            break;
11561209
1157         case MAKE_OPCODE_SHORT(DRCUML_OP_ZEXT1, 8, 0):      /* DZEXT1  dst,src                */
1158            DPARAM0 = (UINT8)PARAM1;
1210         case MAKE_OPCODE_SHORT(DRCUML_OP_SET, 8, 1):      /* DSET    dst,c                  */
1211            DPARAM0 = OPCODE_FAIL_CONDITION(opcode, flags) ? 0 : 1;
11591212            break;
11601213
1161         case MAKE_OPCODE_SHORT(DRCUML_OP_ZEXT2, 8, 0):      /* DZEXT2  dst,src                */
1162            DPARAM0 = (UINT16)PARAM1;
1163            break;
1164
1165         case MAKE_OPCODE_SHORT(DRCUML_OP_ZEXT4, 8, 0):      /* DZEXT4  dst,src                */
1166            DPARAM0 = (UINT32)PARAM1;
1167            break;
1168
1169         case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT1, 8, 0):      /* DSEXT1  dst,src                */
1214         case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT1, 8, 0):      /* DSEXT   dst,src,BYTE           */
11701215            DPARAM0 = (INT8)PARAM1;
11711216            break;
11721217
1173         case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT2, 8, 0):      /* DSEXT2  dst,src                */
1218         case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT2, 8, 0):      /* DSEXT  dst,src,WORD           */
11741219            DPARAM0 = (INT16)PARAM1;
11751220            break;
11761221
1177         case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT4, 8, 0):      /* DSEXT4  dst,src                */
1222         case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT4, 8, 0):      /* DSEXT  dst,src,DWORD          */
11781223            DPARAM0 = (INT32)PARAM1;
11791224            break;
11801225
1181         case MAKE_OPCODE_SHORT(DRCUML_OP_XTRACT, 8, 0):      /* DXTRACT dst,src,count,mask[,f] */
1226         case MAKE_OPCODE_SHORT(DRCUML_OP_ROLAND, 8, 0):      /* DROLAND dst,src,count,mask[,f] */
11821227            shift = DPARAM2 & 63;
11831228            DPARAM0 = ((DPARAM1 << shift) | (DPARAM1 >> (64 - shift))) & DPARAM3;
11841229            break;
11851230
1186         case MAKE_OPCODE_SHORT(DRCUML_OP_INSERT, 8, 0):      /* DINSERT dst,src,count,mask[,f] */
1231         case MAKE_OPCODE_SHORT(DRCUML_OP_ROLINS, 8, 0):      /* DROLINS dst,src,count,mask[,f] */
11871232            shift = DPARAM2 & 63;
11881233            DPARAM0 = (DPARAM0 & ~DPARAM3) | (((DPARAM1 << shift) | (DPARAM1 >> (64 - shift))) & DPARAM3);
11891234            break;
r2821r2822
14551500            inst[0].pfloat[PARAM1] = FSPARAM2;
14561501            break;
14571502
1458         case MAKE_OPCODE_SHORT(DRCUML_OP_FREAD, 4, 0):      /* FSREAD  dst,space,src1         */
1459            PARAM0 = (UINT32)(*active_address_space[PARAM1].accessors->read_dword)(PARAM2);
1503         case MAKE_OPCODE_SHORT(DRCUML_OP_FREAD, 4, 0):      /* FSREAD  dst,src1,space         */
1504            PARAM0 = (UINT32)(*active_address_space[PARAM2].accessors->read_dword)(PARAM1);
14601505            break;
14611506
1462         case MAKE_OPCODE_SHORT(DRCUML_OP_FWRITE, 4, 0):      /* FSWRITE space,dst,src1         */
1463            (*active_address_space[PARAM0].accessors->write_dword)(PARAM1, PARAM2);
1507         case MAKE_OPCODE_SHORT(DRCUML_OP_FWRITE, 4, 0):      /* FSWRITE dst,src1,space         */
1508            (*active_address_space[PARAM2].accessors->write_dword)(PARAM0, PARAM1);
14641509            break;
14651510
14661511         case MAKE_OPCODE_SHORT(DRCUML_OP_FMOV, 4, 1):      /* FSMOV   dst,src[,c]            */
r2821r2822
14721517            FSPARAM0 = FSPARAM1;
14731518            break;
14741519
1475         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4, 4, 0):      /* FSTOI4  dst,src1               */
1476            *inst[0].pint32 = FSPARAM1;
1477            break;
1478
14791520         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4T, 4, 0):      /* FSTOI4T dst,src1               */
14801521            if (FSPARAM1 >= 0)
14811522               *inst[0].pint32 = floor(FSPARAM1);
r2821r2822
14981539            *inst[0].pint32 = ceil(FSPARAM1);
14991540            break;
15001541
1501         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8, 4, 0):      /* FSTOI8  dst,src1               */
1502            *inst[0].pint64 = FSPARAM1;
1542         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4, 4, 0):      /* FSTOI4  dst,src1               */
1543            *inst[0].pint32 = FSPARAM1;
15031544            break;
15041545
15051546         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8T, 4, 0):      /* FSTOI8T dst,src1               */
r2821r2822
15241565            *inst[0].pint64 = ceil(FSPARAM1);
15251566            break;
15261567
1527         case MAKE_OPCODE_SHORT(DRCUML_OP_FFRFD, 4, 0):      /* FSFRFD  dst,src1               */
1528            FSPARAM0 = FDPARAM1;
1568         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8, 4, 0):      /* FSTOI8  dst,src1               */
1569            *inst[0].pint64 = FSPARAM1;
15291570            break;
15301571
15311572         case MAKE_OPCODE_SHORT(DRCUML_OP_FFRI4, 4, 0):      /* FSFRI4  dst,src1               */
r2821r2822
15361577            FSPARAM0 = *inst[1].pint64;
15371578            break;
15381579
1580         case MAKE_OPCODE_SHORT(DRCUML_OP_FFRFD, 4, 0):      /* FSFRFD  dst,src1               */
1581            FSPARAM0 = FDPARAM1;
1582            break;
1583
15391584         case MAKE_OPCODE_SHORT(DRCUML_OP_FADD, 4, 0):      /* FSADD   dst,src1,src2          */
15401585            FSPARAM0 = FSPARAM1 + FSPARAM2;
15411586            break;
r2821r2822
15901635            inst[0].pdouble[PARAM1] = FDPARAM2;
15911636            break;
15921637
1593         case MAKE_OPCODE_SHORT(DRCUML_OP_FREAD, 8, 0):      /* FDREAD  dst,space,src1         */
1594            DPARAM0 = (UINT64)(*active_address_space[PARAM1].accessors->read_qword)(PARAM2);
1638         case MAKE_OPCODE_SHORT(DRCUML_OP_FREAD, 8, 0):      /* FDREAD  dst,src1,space         */
1639            DPARAM0 = (UINT64)(*active_address_space[PARAM2].accessors->read_qword)(PARAM1);
15951640            break;
15961641
1597         case MAKE_OPCODE_SHORT(DRCUML_OP_FWRITE, 8, 0):      /* FDWRITE space,dst,src1         */
1598            (*active_address_space[PARAM0].accessors->write_qword)(PARAM1, DPARAM2);
1642         case MAKE_OPCODE_SHORT(DRCUML_OP_FWRITE, 8, 0):      /* FDWRITE dst,src1,space         */
1643            (*active_address_space[PARAM2].accessors->write_qword)(PARAM0, DPARAM1);
15991644            break;
16001645
16011646         case MAKE_OPCODE_SHORT(DRCUML_OP_FMOV, 8, 1):      /* FDMOV   dst,src[,c]            */
r2821r2822
16071652            FDPARAM0 = FDPARAM1;
16081653            break;
16091654
1610         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4, 8, 0):      /* FDTOI4  dst,src1               */
1611            *inst[0].pint32 = FDPARAM1;
1612            break;
1613
16141655         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4T, 8, 0):      /* FDTOI4T dst,src1               */
16151656            if (FDPARAM1 >= 0)
16161657               *inst[0].pint32 = floor(FDPARAM1);
r2821r2822
16331674            *inst[0].pint32 = ceil(FDPARAM1);
16341675            break;
16351676
1636         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8, 8, 0):      /* FDTOI8  dst,src1               */
1637            *inst[0].pint64 = FDPARAM1;
1677         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4, 8, 0):      /* FDTOI4  dst,src1               */
1678            *inst[0].pint32 = FDPARAM1;
16381679            break;
16391680
16401681         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8T, 8, 0):      /* FDTOI8T dst,src1               */
r2821r2822
16591700            *inst[0].pint64 = ceil(FDPARAM1);
16601701            break;
16611702
1662         case MAKE_OPCODE_SHORT(DRCUML_OP_FFRFS, 8, 0):      /* FDFRFS  dst,src1               */
1663            FDPARAM0 = FSPARAM1;
1703         case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8, 8, 0):      /* FDTOI8  dst,src1               */
1704            *inst[0].pint64 = FDPARAM1;
16641705            break;
16651706
16661707         case MAKE_OPCODE_SHORT(DRCUML_OP_FFRI4, 8, 0):      /* FDFRI4  dst,src1               */
r2821r2822
16711712            FDPARAM0 = *inst[1].pint64;
16721713            break;
16731714
1715         case MAKE_OPCODE_SHORT(DRCUML_OP_FFRFS, 8, 0):      /* FDFRFS  dst,src1               */
1716            FDPARAM0 = FSPARAM1;
1717            break;
1718
1719         case MAKE_OPCODE_SHORT(DRCUML_OP_FRNDS, 8, 0):      /* FDRNDS  dst,src1               */
1720            FDPARAM0 = (float)FDPARAM1;
1721            break;
1722
16741723         case MAKE_OPCODE_SHORT(DRCUML_OP_FADD, 8, 0):      /* FDADD   dst,src1,src2          */
16751724            FDPARAM0 = FDPARAM1 + FDPARAM2;
16761725            break;
src/emu/cpu/cop400/410ops.c
r2821r2822
492492
493493/*
494494
495   Processor:         COP410C/COP411C
495    Processor:          COP410C/COP411C
496496
497497    Mnemonic:           HALT
498498
r2821r2822
528528{
529529   /*
530530
531      Excerpt from the COP410L data sheet:
531        Excerpt from the COP410L data sheet:
532532
533      False states may be generated on L0-L7 during the execution of the CAMQ instruction.
534      The L-ports should not be used as clocks for edge sensitive devices such as flip-flops,
535      counters, shift registers, etc. the following short program that illustrates this situation.
533        False states may be generated on L0-L7 during the execution of the CAMQ instruction.
534        The L-ports should not be used as clocks for edge sensitive devices such as flip-flops,
535        counters, shift registers, etc. the following short program that illustrates this situation.
536536
537      START:
538         CLRA      ;ENABLE THE Q
539         LEI 4      ;REGISTER TO L LINES
540         LBI TEST
541         STII 3
542         AISC 12
543      LOOP:
544         LBI TEST   ;LOAD Q WITH X'C3
545         CAMQ
546         JP LOOP
537        START:
538            CLRA        ;ENABLE THE Q
539            LEI 4       ;REGISTER TO L LINES
540            LBI TEST
541            STII 3
542            AISC 12
543        LOOP:
544            LBI TEST    ;LOAD Q WITH X'C3
545            CAMQ
546            JP LOOP
547547
548      In this program the internal Q register is enabled onto the L lines and a steady bit
549      pattern of logic highs is output on L0,   L1, L6, L7, and logic lows on L2-L5 via the
550      two-byte CAMQ instruction. Timing constraints on the device are such that the Q
551      register may be temporarily loaded with the second byte of the CAMQ opcode (3C) prior
552      to receiving the valid data pattern. If this occurs, the opcode will ripple onto the L
553      lines and cause negative-going glitches on L0, L1, L6, L7, and positive glitches on
554      L2-L5. Glitch durations are under 2 ms, although the exact value may vary due to data
555      patterns, processing parameters, and L line loading. These false states are peculiar
556      only to the CAMQ instruction and the L lines.
548        In this program the internal Q register is enabled onto the L lines and a steady bit
549        pattern of logic highs is output on L0, L1, L6, L7, and logic lows on L2-L5 via the
550        two-byte CAMQ instruction. Timing constraints on the device are such that the Q
551        register may be temporarily loaded with the second byte of the CAMQ opcode (3C) prior
552        to receiving the valid data pattern. If this occurs, the opcode will ripple onto the L
553        lines and cause negative-going glitches on L0, L1, L6, L7, and positive glitches on
554        L2-L5. Glitch durations are under 2 ms, although the exact value may vary due to data
555        patterns, processing parameters, and L line loading. These false states are peculiar
556        only to the CAMQ instruction and the L lines.
557557
558   */
558    */
559559
560560   UINT8 data = (A << 4) | RAM_R(B);
561561
src/emu/cpu/cop400/cop410.c
r2821r2822
1515
1616    - run interrupt test suite
1717    - run production test suite
18   - run microbus test suite
18    - run microbus test suite
1919    - remove LBIops
2020
2121*/
src/emu/cpu/cop400/cop420.c
r2821r2822
1313
1414    TODO:
1515
16   - when is the microbus int cleared?
16    - when is the microbus int cleared?
1717    - run interrupt test suite
1818    - run production test suite
19   - run microbus test suite
19    - run microbus test suite
2020    - remove LBIops
21   - move cop440 stuff to cop440.c
21    - move cop440 stuff to cop440.c
2222
2323*/
2424
src/emu/cpu/cop400/cop400.h
r2821r2822
6767
6868/*
6969
70   Prefix      Temperature Range
70    Prefix      Temperature Range
7171
72   COP4xx      0C to 70C
73   COP3xx      -40C to +85C
74   COP2xx      -55C to +125C
72    COP4xx      0C to 70C
73    COP3xx      -40C to +85C
74    COP2xx      -55C to +125C
7575
7676*/
7777
src/emu/cpu/powerpc/ppcdrco.c
r2821r2822
1/*
2    PowerPC 4xx/6xx Dynamic Recompiler for x86
3
4    Written by Ville Linde
5*/
6
7#include "debugger.h"
8#include "ppc.h"
9#include "cpu/x86drc.h"
10
11
12#define PPC_DRC
13#define LOG_CODE         (0)
14
15#define CACHE_SIZE         (16 * 1024 * 1024)
16#define MAX_INSTRUCTIONS   512
17
18
19#if (HAS_PPC603)
20static void ppcdrc603_init(int index, int clock, const void *_config, int (*irqcallback)(int));
21static void ppcdrc603_exit(void);
22#endif
23#if (HAS_PPC601 || HAS_PPC603 || HAS_MPC8240 || HAS_PPC604)
24static void ppcdrc603_reset(void);
25static int ppcdrc603_execute(int cycles);
26static void ppcdrc603_set_irq_line(int irqline, int state);
27#endif
28#if (HAS_PPC602)
29static void ppcdrc602_init(int index, int clock, const void *_config, int (*irqcallback)(int));
30static void ppcdrc602_exit(void);
31static void ppcdrc602_reset(void);
32static int ppcdrc602_execute(int cycles);
33static void ppcdrc602_set_irq_line(int irqline, int state);
34#endif
35#if (HAS_PPC403)
36static UINT8 ppc403_spu_r(UINT32 a);
37static void ppc403_spu_w(UINT32 a, UINT8 d);
38static void ppcdrc403_init(int index, int clock, const void *_config, int (*irqcallback)(int));
39static void ppcdrc403_exit(void);
40static void ppcdrc403_reset(void);
41static int ppcdrc403_execute(int cycles);
42static void ppcdrc403_set_irq_line(int irqline, int state);
43#endif
44
45static void ppcdrc_init(void);
46static void ppcdrc_reset(drc_core *drc);
47static void ppcdrc_recompile(drc_core *drc);
48static void ppcdrc_entrygen(drc_core *drc);
49
50#define RD            ((op >> 21) & 0x1F)
51#define RT            ((op >> 21) & 0x1f)
52#define RS            ((op >> 21) & 0x1f)
53#define RA            ((op >> 16) & 0x1f)
54#define RB            ((op >> 11) & 0x1f)
55#define RC            ((op >> 6) & 0x1f)
56
57#define MB            ((op >> 6) & 0x1f)
58#define ME            ((op >> 1) & 0x1f)
59#define SH            ((op >> 11) & 0x1f)
60#define BO            ((op >> 21) & 0x1f)
61#define BI            ((op >> 16) & 0x1f)
62#define CRFD         ((op >> 23) & 0x7)
63#define CRFA         ((op >> 18) & 0x7)
64#define FXM            ((op >> 12) & 0xff)
65#define SPR            (((op >> 16) & 0x1f) | ((op >> 6) & 0x3e0))
66
67#define SIMM16         (INT32)(INT16)(op & 0xffff)
68#define UIMM16         (UINT32)(op & 0xffff)
69
70#define RCBIT         (op & 0x1)
71#define OEBIT         (op & 0x400)
72#define AABIT         (op & 0x2)
73#define LKBIT         (op & 0x1)
74
75#define REG(x)         (ppc.r[x])
76#define LR            (ppc.lr)
77#define CTR            (ppc.ctr)
78#define XER            (ppc.xer)
79#define CR(x)         (ppc.cr[x])
80#define MSR            (ppc.msr)
81#define SRR0         (ppc.srr0)
82#define SRR1         (ppc.srr1)
83#define SRR2         (ppc.srr2)
84#define SRR3         (ppc.srr3)
85#define EVPR         (ppc.evpr)
86#define EXIER         (ppc.exier)
87#define EXISR         (ppc.exisr)
88#define DEC            (ppc.dec)
89
90
91// Stuff added for the 6xx
92#define FPR(x)         (ppc.fpr[x])
93#define FM            ((op >> 17) & 0xFF)
94#define SPRF         (((op >> 6) & 0x3E0) | ((op >> 16) & 0x1F))
95
96
97#define CHECK_SUPERVISOR()         \
98   if((ppc.msr & 0x4000) != 0){   \
99   }
100
101#define CHECK_FPU_AVAILABLE()      \
102   if((ppc.msr & 0x2000) == 0){   \
103   }
104
105#if (HAS_PPC601||HAS_PPC602||HAS_PPC603||HAS_PPC604||HAS_MPC8240)
106static UINT32      ppc_field_xlat[256];
107#endif
108
109
110
111#define FPSCR_FX      0x80000000
112#define FPSCR_FEX      0x40000000
113#define FPSCR_VX      0x20000000
114#define FPSCR_OX      0x10000000
115#define FPSCR_UX      0x08000000
116#define FPSCR_ZX      0x04000000
117#define FPSCR_XX      0x02000000
118
119
120
121#define BITMASK_0(n)   (UINT32)(((UINT64)1 << n) - 1)
122#define CRBIT(x)      ((ppc.cr[x / 4] & (1 << (3 - (x % 4)))) ? 1 : 0)
123#define _BIT(n)         (1 << (n))
124#define GET_ROTATE_MASK(mb,me)      (ppc_rotate_mask[mb][me])
125#define ADD_CA(r,a,b)      ((UINT32)r < (UINT32)a)
126#define SUB_CA(r,a,b)      (!((UINT32)a < (UINT32)b))
127#define ADD_OV(r,a,b)      ((~((a) ^ (b)) & ((a) ^ (r))) & 0x80000000)
128#define SUB_OV(r,a,b)      (( ((a) ^ (b)) & ((a) ^ (r))) & 0x80000000)
129
130#define XER_SO         0x80000000
131#define XER_OV         0x40000000
132#define XER_CA         0x20000000
133
134#define MSR_AP         0x00800000   /* Access privilege state (PPC602) */
135#define MSR_SA         0x00400000   /* Supervisor access mode (PPC602) */
136#define MSR_POW         0x00040000   /* Power Management Enable */
137#define MSR_WE         0x00040000
138#define MSR_CE         0x00020000
139#define MSR_ILE         0x00010000   /* Interrupt Little Endian Mode */
140#define MSR_EE         0x00008000   /* External Interrupt Enable */
141#define MSR_PR         0x00004000   /* Problem State */
142#define MSR_FP         0x00002000   /* Floating Point Available */
143#define MSR_ME         0x00001000   /* Machine Check Enable */
144#define MSR_FE0         0x00000800
145#define MSR_SE         0x00000400   /* Single Step Trace Enable */
146#define MSR_BE         0x00000200   /* Branch Trace Enable */
147#define MSR_DE         0x00000200
148#define MSR_FE1         0x00000100
149#define MSR_IP         0x00000040   /* Interrupt Prefix */
150#define MSR_IR         0x00000020   /* Instruction Relocate */
151#define MSR_DR         0x00000010   /* Data Relocate */
152#define MSR_PE         0x00000008
153#define MSR_PX         0x00000004
154#define MSR_RI         0x00000002   /* Recoverable Interrupt Enable */
155#define MSR_LE         0x00000001
156
157#define TSR_ENW         0x80000000
158#define TSR_WIS         0x40000000
159
160#define BYTE_REVERSE16(x)   ((((x) >> 8) & 0xff) | (((x) << 8) & 0xff00))
161#define BYTE_REVERSE32(x)   ((((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000))
162
163typedef struct {
164   UINT32 cr;
165   UINT32 da;
166   UINT32 sa;
167   UINT32 ct;
168   UINT32 cc;
169} DMA_REGS;
170
171typedef struct {
172   UINT8 spls;
173   UINT8 sphs;
174   UINT16 brd;
175   UINT8 spctl;
176   UINT8 sprc;
177   UINT8 sptc;
178   UINT8 sprb;
179   UINT8 sptb;
180   emu_timer *rx_timer;
181   emu_timer *tx_timer;
182} SPU_REGS;
183
184typedef union {
185   UINT64   id;
186   double   fd;
187} FPR;
188
189typedef union {
190   UINT32 i;
191   float f;
192} FPR32;
193
194typedef struct {
195   UINT32 u;
196   UINT32 l;
197} BATENT;
198
199
200typedef struct {
201   UINT32 r[32];
202   UINT32 pc;
203   UINT32 npc;
204
205   UINT32 lr;
206   UINT32 ctr;
207   UINT32 xer;
208   UINT32 msr;
209   UINT8 cr[8];
210   UINT32 pvr;
211   UINT32 srr0;
212   UINT32 srr1;
213   UINT32 srr2;
214   UINT32 srr3;
215   UINT32 hid0;
216   UINT32 hid1;
217   UINT32 hid2;
218   UINT32 sdr1;
219   UINT32 sprg[4];
220
221   UINT32 dsisr;
222   UINT32 dar;
223   UINT32 ear;
224   UINT32 dmiss;
225   UINT32 dcmp;
226   UINT32 hash1;
227   UINT32 hash2;
228   UINT32 imiss;
229   UINT32 icmp;
230   UINT32 rpa;
231
232   BATENT ibat[4];
233   BATENT dbat[4];
234
235   UINT32 evpr;
236   UINT32 exier;
237   UINT32 exisr;
238   UINT32 bear;
239   UINT32 besr;
240   UINT32 iocr;
241   UINT32 br[8];
242   UINT32 iabr;
243   UINT32 esr;
244   UINT32 iccr;
245   UINT32 dccr;
246   UINT32 pit;
247   UINT32 tsr;
248   UINT32 tcr;
249   UINT32 dbsr;
250   UINT32 sgr;
251   UINT32 pid;
252   UINT32 pbl1, pbl2, pbu1, pbu2;
253   UINT32 fit_bit;
254   UINT32 fit_int_enable;
255   UINT32 wdt_bit;
256   UINT32 wdt_int_enable;
257   UINT32 dac1, dac2;
258   UINT32 iac1, iac2;
259
260   SPU_REGS spu;
261   DMA_REGS dma[4];
262   UINT32 dmasr;
263
264   int reserved;
265   UINT32 reserved_address;
266
267   int exception_pending;
268
269   UINT64 tb;         /* 56-bit timebase register */
270
271   int (*irq_callback)(int irqline);
272   drc_core *drc;
273   UINT32 drcoptions;
274
275   x86code *      invoke_exception_handler;
276   x86code *      generate_interrupt_exception;
277   x86code *      generate_syscall_exception;
278   x86code *      generate_decrementer_exception;
279   x86code *      generate_trap_exception;
280   x86code *      generate_dsi_exception;
281   x86code *      generate_isi_exception;
282   x86code *      generate_fit_exception;
283
284   // PowerPC 60x specific registers */
285   UINT32 dec, dec_frac;
286   UINT32 fpscr;
287
288   FPR   fpr[32];
289   UINT32 sr[16];
290
291   int is603;
292   int is602;
293
294   /* PowerPC 602 specific registers */
295   UINT32 lt;
296   UINT32 sp;
297   UINT32 ibr;
298   UINT32 esasrr;
299   UINT32 sebr;
300   UINT32 ser;
301
302   /* PowerPC function pointers for memory accesses/exceptions */
303   UINT8 (*read8)(offs_t address);
304   UINT16 (*read16)(offs_t address);
305   UINT32 (*read32)(offs_t address);
306   UINT64 (*read64)(offs_t address);
307   void (*write8)(offs_t address, UINT8 data);
308   void (*write16)(offs_t address, UINT16 data);
309   void (*write32)(offs_t address, UINT32 data);
310   void (*write64)(offs_t address, UINT64 data);
311   UINT16 (*read16_unaligned)(offs_t address);
312   UINT32 (*read32_unaligned)(offs_t address);
313   UINT64 (*read64_unaligned)(offs_t address);
314   void (*write16_unaligned)(offs_t address, UINT16 data);
315   void (*write32_unaligned)(offs_t address, UINT32 data);
316   void (*write64_unaligned)(offs_t address, UINT64 data);
317
318   /* saved ESP when entering entry point */
319   UINT32 host_esp;
320
321   UINT32 (* optable19[1024])(drc_core *, UINT32);
322   UINT32 (* optable31[1024])(drc_core *, UINT32);
323   UINT32 (* optable59[1024])(drc_core *, UINT32);
324   UINT32 (* optable63[1024])(drc_core *, UINT32);
325   UINT32 (* optable[64])(drc_core *, UINT32);
326} PPC_REGS;
327
328
329
330typedef struct {
331   int code;
332   int subcode;
333   UINT32 (* handler)(drc_core *, UINT32);
334} PPC_OPCODE;
335
336
337/* code logging info */
338typedef struct _code_log_entry code_log_entry;
339struct _code_log_entry
340{
341   UINT32      pc;
342   UINT32      op;
343   void *      base;
344};
345
346
347
348static int ppc_icount;
349static int ppc_tb_base_icount;
350static int ppc_dec_base_icount;
351static int ppc_dec_trigger_cycle;
352static int bus_freq_multiplier = 1;
353static int ppc_fit_trigger_cycle;
354static PPC_REGS ppc;
355static UINT32 ppc_rotate_mask[32][32];
356
357#define ROPCODE(pc)         cpu_readop32(pc)
358#define ROPCODE64(pc)      cpu_readop64(DWORD_XOR_BE(pc))
359
360INLINE void SET_CR0(INT32 rd)
361{
362   if( rd < 0 ) {
363      CR(0) = 0x8;
364   } else if( rd > 0 ) {
365      CR(0) = 0x4;
366   } else {
367      CR(0) = 0x2;
368   }
369
370   if( XER & XER_SO )
371      CR(0) |= 0x1;
372}
373
374INLINE void SET_CR1(void)
375{
376   CR(1) = (ppc.fpscr >> 28) & 0xf;
377}
378
379INLINE void SET_ADD_OV(UINT32 rd, UINT32 ra, UINT32 rb)
380{
381   if( ADD_OV(rd, ra, rb) )
382      XER |= XER_SO | XER_OV;
383   else
384      XER &= ~XER_OV;
385}
386
387INLINE void SET_SUB_OV(UINT32 rd, UINT32 ra, UINT32 rb)
388{
389   if( SUB_OV(rd, ra, rb) )
390      XER |= XER_SO | XER_OV;
391   else
392      XER &= ~XER_OV;
393}
394
395INLINE void SET_ADD_CA(UINT32 rd, UINT32 ra, UINT32 rb)
396{
397   if( ADD_CA(rd, ra, rb) )
398      XER |= XER_CA;
399   else
400      XER &= ~XER_CA;
401}
402
403INLINE void SET_SUB_CA(UINT32 rd, UINT32 ra, UINT32 rb)
404{
405   if( SUB_CA(rd, ra, rb) )
406      XER |= XER_CA;
407   else
408      XER &= ~XER_CA;
409}
410
411INLINE UINT32 check_condition_code(UINT32 bo, UINT32 bi)
412{
413   UINT32 ctr_ok;
414   UINT32 condition_ok;
415   UINT32 bo0 = (bo & 0x10) ? 1 : 0;
416   UINT32 bo1 = (bo & 0x08) ? 1 : 0;
417   UINT32 bo2 = (bo & 0x04) ? 1 : 0;
418   UINT32 bo3 = (bo & 0x02) ? 1 : 0;
419
420   if( bo2 == 0 )
421      --CTR;
422
423   ctr_ok = bo2 | ((CTR != 0) ^ bo3);
424   condition_ok = bo0 | (CRBIT(bi) ^ (~bo1 & 0x1));
425
426   return ctr_ok && condition_ok;
427}
428
429INLINE UINT64 ppc_read_timebase(void)
430{
431   int cycles = ppc_tb_base_icount - ppc_icount;
432
433   if (ppc.is603 || ppc.is602)
434   {
435      // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly
436      return ppc.tb + (cycles / 4);
437   }
438   else
439   {
440      // timebase is incremented once every core cycle on PPC403
441      return ppc.tb + cycles;
442   }
443}
444
445INLINE void ppc_write_timebase_l(UINT32 tbl)
446{
447   ppc_tb_base_icount = ppc_icount;
448
449   ppc.tb &= ~0xffffffff;
450   ppc.tb |= tbl;
451}
452
453INLINE void ppc_write_timebase_h(UINT32 tbh)
454{
455   ppc_tb_base_icount = ppc_icount;
456
457   ppc.tb &= 0xffffffff;
458   ppc.tb |= (UINT64)(tbh) << 32;
459}
460
461INLINE UINT32 read_decrementer(void)
462{
463   int cycles = ppc_dec_base_icount - ppc_icount;
464
465   // decrementer is decremented once every four bus clock cycles, so adjust the cycles accordingly
466   return DEC - (cycles / (bus_freq_multiplier * 2));
467}
468
469INLINE void write_decrementer(UINT32 value)
470{
471   ppc_dec_base_icount = ppc_icount + (ppc_dec_base_icount - ppc_icount) % (bus_freq_multiplier * 2);
472
473   DEC = value;
474
475   // check if decrementer exception occurs during execution
476   if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC))
477   {
478      ppc_dec_trigger_cycle = ppc_icount - DEC;
479   }
480   else
481   {
482      ppc_dec_trigger_cycle = 0x7fffffff;
483   }
484}
485
486/*********************************************************************/
487
488INLINE void ppc_exception(int exception_type)
489{
490   void *exception_code = NULL;
491   void (*invoke_exception_handler)(void *handler);
492
493   switch(exception_type)
494   {
495      case EXCEPTION_DECREMENTER:
496         exception_code = ppc.generate_decrementer_exception;
497         break;
498      case EXCEPTION_DSI:
499         exception_code = ppc.generate_dsi_exception;
500         break;
501      case EXCEPTION_ISI:
502         exception_code = ppc.generate_isi_exception;
503         break;
504      default:
505         fatalerror("Unknown exception %d", exception_type);
506         break;
507   }
508
509   memcpy(&invoke_exception_handler, &ppc.invoke_exception_handler, sizeof(invoke_exception_handler));
510   invoke_exception_handler(exception_code);
511}
512
513/*********************************************************************/
514
515INLINE void ppc_set_spr(int spr, UINT32 value)
516{
517   switch (spr)
518   {
519      case SPR_LR:      LR = value; return;
520      case SPR_CTR:      CTR = value; return;
521      case SPR_XER:      XER = value; return;
522      case SPR_SRR0:      ppc.srr0 = value; return;
523      case SPR_SRR1:      ppc.srr1 = value; return;
524      case SPR_SPRG0:      ppc.sprg[0] = value; return;
525      case SPR_SPRG1:      ppc.sprg[1] = value; return;
526      case SPR_SPRG2:      ppc.sprg[2] = value; return;
527      case SPR_SPRG3:      ppc.sprg[3] = value; return;
528      case SPR_PVR:      return;
529   }
530
531#if (HAS_PPC603 || HAS_PPC602 || HAS_PPC601 || HAS_PPC604)
532   if(ppc.is603 || ppc.is602) {
533      switch(spr)
534      {
535         case SPR603E_DEC:
536            if((value & 0x80000000) && !(DEC & 0x80000000))
537            {
538               /* trigger interrupt */
539               if( MSR & MSR_EE )
540                  ppc_exception(EXCEPTION_DECREMENTER);
541            }
542            write_decrementer(value);
543            return;
544
545         case SPR603E_TBL_W:
546         case SPR603E_TBL_R: // special 603e case
547            ppc_write_timebase_l(value);
548            return;
549
550         case SPR603E_TBU_R:
551         case SPR603E_TBU_W: // special 603e case
552            ppc_write_timebase_h(value);
553            return;
554
555         case SPR603E_HID0:
556            ppc.hid0 = value;
557            return;
558
559         case SPR603E_HID1:
560            ppc.hid1 = value;
561            return;
562
563         case SPR603E_HID2:
564            ppc.hid1 = value;
565            return;
566
567         case SPR603E_DSISR:         ppc.dsisr = value; return;
568         case SPR603E_DAR:         ppc.dar = value; return;
569         case SPR603E_EAR:         ppc.ear = value; return;
570         case SPR603E_DMISS:         ppc.dmiss = value; return;
571         case SPR603E_DCMP:         ppc.dcmp = value; return;
572         case SPR603E_HASH1:         ppc.hash1 = value; return;
573         case SPR603E_HASH2:         ppc.hash2 = value; return;
574         case SPR603E_IMISS:         ppc.imiss = value; return;
575         case SPR603E_ICMP:         ppc.icmp = value; return;
576         case SPR603E_RPA:         ppc.rpa = value; return;
577
578         case SPR603E_IBAT0L:      ppc.ibat[0].l = value; return;
579         case SPR603E_IBAT0U:      ppc.ibat[0].u = value; return;
580         case SPR603E_IBAT1L:      ppc.ibat[1].l = value; return;
581         case SPR603E_IBAT1U:      ppc.ibat[1].u = value; return;
582         case SPR603E_IBAT2L:      ppc.ibat[2].l = value; return;
583         case SPR603E_IBAT2U:      ppc.ibat[2].u = value; return;
584         case SPR603E_IBAT3L:      ppc.ibat[3].l = value; return;
585         case SPR603E_IBAT3U:      ppc.ibat[3].u = value; return;
586         case SPR603E_DBAT0L:      ppc.dbat[0].l = value; return;
587         case SPR603E_DBAT0U:      ppc.dbat[0].u = value; return;
588         case SPR603E_DBAT1L:      ppc.dbat[1].l = value; return;
589         case SPR603E_DBAT1U:      ppc.dbat[1].u = value; return;
590         case SPR603E_DBAT2L:      ppc.dbat[2].l = value; return;
591         case SPR603E_DBAT2U:      ppc.dbat[2].u = value; return;
592         case SPR603E_DBAT3L:      ppc.dbat[3].l = value; return;
593         case SPR603E_DBAT3U:      ppc.dbat[3].u = value; return;
594
595         case SPR603E_SDR1:
596            ppc.sdr1 = value;
597            return;
598
599         case SPR603E_IABR:         ppc.iabr = value; return;
600      }
601   }
602#endif
603
604#if (HAS_PPC602)
605   if (ppc.is602) {
606      switch(spr)
607      {
608         case SPR602_LT:         ppc.lt = value; return;
609         case SPR602_IBR:      ppc.ibr = value; return;
610         case SPR602_SP:         ppc.sp = value; return;
611         case SPR602_SEBR:      ppc.sebr = value; return;
612         case SPR602_SER:      ppc.ser = value; return;
613         case SPR602_TCR:      ppc.tcr = value; return;
614      }
615   }
616#endif
617
618#if (HAS_PPC403)
619   if (!ppc.is603 && !ppc.is602) {
620      switch(spr)
621      {
622         case SPR403_TBHI:      ppc_write_timebase_h(value); return;
623         case SPR403_TBLO:      ppc_write_timebase_l(value); return;
624
625         case SPR403_TSR:
626            ppc.tsr &= ~value; // 1 clears, 0 does nothing
627            return;
628
629         case SPR403_TCR:
630            switch((value >> 24) & 0x3)
631            {
632               case 0: ppc.fit_bit = 1 << 8; break;
633               case 1: ppc.fit_bit = 1 << 12; break;
634               case 2: ppc.fit_bit = 1 << 16; break;
635               case 3: ppc.fit_bit = 1 << 20; break;
636            }
637            switch((value >> 30) & 0x3)
638            {
639               case 0: ppc.wdt_bit = 1 << 16; break;
640               case 1: ppc.wdt_bit = 1 << 20; break;
641               case 2: ppc.wdt_bit = 1 << 24; break;
642               case 3: ppc.wdt_bit = 1 << 28; break;
643            }
644            ppc.fit_int_enable = (value >> 23) & 0x1;
645            ppc.wdt_int_enable = (value >> 27) & 0x1;
646            ppc.tcr = value;
647
648            if (!ppc.fit_int_enable)
649            {
650               ppc.exception_pending &= ~0x4;
651            }
652            return;
653
654         case SPR403_ESR:      ppc.esr = value; return;
655         case SPR403_ICCR:      ppc.iccr = value; return;
656         case SPR403_DCCR:      ppc.dccr = value; return;
657         case SPR403_EVPR:      EVPR = value & 0xffff0000; return;
658         case SPR403_PIT:      ppc.pit = value; return;
659         case SPR403_SGR:      ppc.sgr = value; return;
660         case SPR403_DBSR:      ppc.dbsr = value; return;
661         case SPR403_DCWR:      return;
662         case SPR403_PID:      ppc.pid = value; return;
663         case SPR403_PBL1:      ppc.pbl1 = value; return;
664         case SPR403_PBU1:      ppc.pbu1 = value; return;
665         case SPR403_PBL2:      ppc.pbl2 = value; return;
666         case SPR403_PBU2:      ppc.pbu2 = value; return;
667         case SPR403_SRR2:      ppc.srr2 = value; return;
668         case SPR403_SRR3:      ppc.srr3 = value; return;
669         case SPR403_DAC1:      ppc.dac1 = value; return;
670         case SPR403_DAC2:      ppc.dac2 = value; return;
671         case SPR403_IAC1:      ppc.iac1 = value; return;
672         case SPR403_IAC2:      ppc.iac2 = value; return;
673      }
674   }
675#endif
676
677   fatalerror("ppc: set_spr: unknown spr %d (%03X) !", spr, spr);
678}
679
680INLINE UINT32 ppc_get_spr(int spr)
681{
682   switch(spr)
683   {
684      case SPR_LR:      return LR;
685      case SPR_CTR:      return CTR;
686      case SPR_XER:      return XER;
687      case SPR_SRR0:      return ppc.srr0;
688      case SPR_SRR1:      return ppc.srr1;
689      case SPR_SPRG0:      return ppc.sprg[0];
690      case SPR_SPRG1:      return ppc.sprg[1];
691      case SPR_SPRG2:      return ppc.sprg[2];
692      case SPR_SPRG3:      return ppc.sprg[3];
693      case SPR_PVR:      return ppc.pvr;
694   }
695
696#if (HAS_PPC403)
697   if (!ppc.is603 && !ppc.is602)
698   {
699      switch (spr)
700      {
701         case SPR403_TBLU:
702         case SPR403_TBLO:      return (UINT32)(ppc_read_timebase());
703         case SPR403_TBHU:
704         case SPR403_TBHI:      return (UINT32)(ppc_read_timebase() >> 32);
705
706         case SPR403_EVPR:      return EVPR;
707         case SPR403_ESR:      return ppc.esr;
708         case SPR403_TCR:      return ppc.tcr;
709         case SPR403_ICCR:      return ppc.iccr;
710         case SPR403_DCCR:      return ppc.dccr;
711         case SPR403_PIT:      return ppc.pit;
712         case SPR403_DBSR:      return ppc.dbsr;
713         case SPR403_SGR:      return ppc.sgr;
714         case SPR403_TSR:      return ppc.tsr;
715         case SPR403_PBL1:      return ppc.pbl1;
716         case SPR403_PBU1:      return ppc.pbu1;
717         case SPR403_PBL2:      return ppc.pbl2;
718         case SPR403_PBU2:      return ppc.pbu2;
719         case SPR403_SRR2:      return ppc.srr2;
720         case SPR403_SRR3:      return ppc.srr3;
721         case SPR403_DAC1:      return ppc.dac1;
722         case SPR403_DAC2:      return ppc.dac2;
723         case SPR403_IAC1:      return ppc.iac1;
724         case SPR403_IAC2:      return ppc.iac2;
725      }
726   }
727#endif
728
729#if (HAS_PPC602)
730   if (ppc.is602) {
731      switch(spr)
732      {
733         case SPR602_LT:         return ppc.lt;
734         case SPR602_IBR:      return ppc.ibr;
735         case SPR602_ESASRR:      return ppc.esasrr;
736         case SPR602_SEBR:      return ppc.sebr;
737         case SPR602_SER:      return ppc.ser;
738         case SPR602_SP:         return ppc.sp;
739         case SPR602_TCR:      return ppc.tcr;
740      }
741   }
742#endif
743
744#if (HAS_PPC603 || HAS_PPC602 || HAS_PPC601 || HAS_PPC604)
745   if (ppc.is603 || ppc.is602)
746   {
747      switch (spr)
748      {
749         case SPR603E_TBL_R:
750            fatalerror("ppc: get_spr: TBL_R ");
751            break;
752
753         case SPR603E_TBU_R:
754            fatalerror("ppc: get_spr: TBU_R ");
755            break;
756
757         case SPR603E_TBL_W:      return (UINT32)(ppc_read_timebase());
758         case SPR603E_TBU_W:      return (UINT32)(ppc_read_timebase() >> 32);
759         case SPR603E_HID0:      return ppc.hid0;
760         case SPR603E_HID1:      return ppc.hid1;
761         case SPR603E_HID2:      return ppc.hid2;
762         case SPR603E_DEC:      return read_decrementer();
763         case SPR603E_SDR1:      return ppc.sdr1;
764         case SPR603E_DSISR:      return ppc.dsisr;
765         case SPR603E_DAR:      return ppc.dar;
766         case SPR603E_EAR:      return ppc.ear;
767         case SPR603E_IBAT0L:   return ppc.ibat[0].l;
768         case SPR603E_IBAT0U:   return ppc.ibat[0].u;
769         case SPR603E_IBAT1L:   return ppc.ibat[1].l;
770         case SPR603E_IBAT1U:   return ppc.ibat[1].u;
771         case SPR603E_IBAT2L:   return ppc.ibat[2].l;
772         case SPR603E_IBAT2U:   return ppc.ibat[2].u;
773         case SPR603E_IBAT3L:   return ppc.ibat[3].l;
774         case SPR603E_IBAT3U:   return ppc.ibat[3].u;
775         case SPR603E_DBAT0L:   return ppc.dbat[0].l;
776         case SPR603E_DBAT0U:   return ppc.dbat[0].u;
777         case SPR603E_DBAT1L:   return ppc.dbat[1].l;
778         case SPR603E_DBAT1U:   return ppc.dbat[1].u;
779         case SPR603E_DBAT2L:   return ppc.dbat[2].l;
780         case SPR603E_DBAT2U:   return ppc.dbat[2].u;
781         case SPR603E_DBAT3L:   return ppc.dbat[3].l;
782         case SPR603E_DBAT3U:   return ppc.dbat[3].u;
783      }
784   }
785#endif
786
787   fatalerror("ppc: get_spr: unknown spr %d (%03X) !", spr, spr);
788   return 0;
789}
790
791static UINT8 ppc_read8_translated(offs_t address);
792static UINT16 ppc_read16_translated(offs_t address);
793static UINT32 ppc_read32_translated(offs_t address);
794static UINT64 ppc_read64_translated(offs_t address);
795static void ppc_write8_translated(offs_t address, UINT8 data);
796static void ppc_write16_translated(offs_t address, UINT16 data);
797static void ppc_write32_translated(offs_t address, UINT32 data);
798static void ppc_write64_translated(offs_t address, UINT64 data);
799
800INLINE void ppc_set_msr(UINT32 value)
801{
802   if( value & (MSR_ILE | MSR_LE) )
803      fatalerror("ppc: set_msr: little_endian mode not supported !");
804
805   MSR = value;
806
807   if (ppc.is603 || ppc.is602)
808   {
809      if (!(MSR & MSR_DR))
810      {
811         ppc.read8 = program_read_byte_64be;
812         ppc.read16 = program_read_word_64be;
813         ppc.read32 = program_read_dword_64be;
814         ppc.read64 = program_read_qword_64be;
815         ppc.write8 = program_write_byte_64be;
816         ppc.write16 = program_write_word_64be;
817         ppc.write32 = program_write_dword_64be;
818         ppc.write64 = program_write_qword_64be;
819      }
820      else
821      {
822         ppc.read8 = ppc_read8_translated;
823         ppc.read16 = ppc_read16_translated;
824         ppc.read32 = ppc_read32_translated;
825         ppc.read64 = ppc_read64_translated;
826         ppc.write8 = ppc_write8_translated;
827         ppc.write16 = ppc_write16_translated;
828         ppc.write32 = ppc_write32_translated;
829         ppc.write64 = ppc_write64_translated;
830      }
831   }
832}
833
834INLINE UINT32 ppc_get_msr(void)
835{
836   return MSR;
837}
838
839INLINE void ppc_set_cr(UINT32 value)
840{
841   CR(0) = (value >> 28) & 0xf;
842   CR(1) = (value >> 24) & 0xf;
843   CR(2) = (value >> 20) & 0xf;
844   CR(3) = (value >> 16) & 0xf;
845   CR(4) = (value >> 12) & 0xf;
846   CR(5) = (value >> 8) & 0xf;
847   CR(6) = (value >> 4) & 0xf;
848   CR(7) = (value >> 0) & 0xf;
849}
850
851INLINE UINT32 ppc_get_cr(void)
852{
853   return CR(0) << 28 | CR(1) << 24 | CR(2) << 20 | CR(3) << 16 | CR(4) << 12 | CR(5) << 8 | CR(6) << 4 | CR(7);
854}
855
856#ifdef UNUSED_FUNCTION
857static void log_code(drc_core *drc)
858{
859#if LOG_CODE
860   FILE *temp;
861   temp = fopen("code.bin", "wb");
862   fwrite(drc->cache_base, 1, drc->cache_top - drc->cache_base, temp);
863   fclose(temp);
864#endif
865}
866#endif
867
868/***********************************************************************/
869
870#include "ppc_mem.c"
871
872#if (HAS_PPC403)
873#include "ppc403.c"
874#endif
875
876#if (HAS_PPC602)
877#include "ppc602.c"
878#endif
879
880/***************************************************************************
881    CODE LOGGING
882***************************************************************************/
883
884#if LOG_CODE
885
886static code_log_entry code_log_buffer[MAX_INSTRUCTIONS*2];
887static int code_log_index;
888static FILE *logfile;
889
890
891/*-------------------------------------------------
892    open_logfile - open the log file if it is
893    not already opened
894-------------------------------------------------*/
895
896INLINE int open_logfile(void)
897{
898   if (logfile == NULL)
899      logfile = fopen("ppcdrc.asm", "w");
900   return (logfile != NULL);
901}
902
903
904/*-------------------------------------------------
905    code_log_reset - reset the logging index
906-------------------------------------------------*/
907
908INLINE void code_log_reset(void)
909{
910   code_log_index = 0;
911}
912
913
914/*-------------------------------------------------
915    code_log_add_entry - add an entry to the log
916-------------------------------------------------*/
917
918INLINE void code_log_add_entry(UINT32 pc, UINT32 op, void *base)
919{
920   code_log_buffer[code_log_index].pc = pc;
921   code_log_buffer[code_log_index].op = op;
922   code_log_buffer[code_log_index].base = base;
923   code_log_index++;
924}
925
926
927/*-------------------------------------------------
928    code_log - actually log some code
929-------------------------------------------------*/
930
931static void code_log(const char *label, x86code *start, x86code *stop)
932{
933   extern int i386_dasm_one(char *buffer, UINT32 eip, UINT8 *oprom, int mode);
934   offs_t ppc_dasm_one(char *buffer, UINT32 pc, UINT32 op);
935   UINT8 *cur = start;
936
937   /* open the file, creating it if necessary */
938   if (!open_logfile())
939      return;
940   fprintf(logfile, "\n%s\n", label);
941
942   /* loop from the start until the cache top */
943   while (cur < stop)
944   {
945      char buffer[100];
946      int bytes;
947      int op;
948
949      /* skip filler opcodes */
950      if (*cur == 0xcc)
951      {
952         cur++;
953         continue;
954      }
955
956      /* disassemble this instruction */
957#ifdef PTR64
958      bytes = i386_dasm_one(buffer, (UINT32)(FPTR)cur, cur, 64) & DASMFLAG_LENGTHMASK;
959#else
960      bytes = i386_dasm_one(buffer, (UINT32)cur, cur, 32) & DASMFLAG_LENGTHMASK;
961#endif
962
963      /* look for a match in the registered opcodes */
964      for (op = 0; op < code_log_index; op++)
965         if (code_log_buffer[op].base == (void *)cur)
966            break;
967
968      /* if no match, just output the current instruction */
969      if (op == code_log_index)
970         fprintf(logfile, "%p: %s\n", cur, buffer);
971
972      /* otherwise, output with the original instruction to the right */
973      else
974      {
975         char buffer2[100];
976         ppc_dasm_one(buffer2, code_log_buffer[op].pc, code_log_buffer[op].op);
977         fprintf(logfile, "%p: %-50s %08X: %s\n", cur, buffer, code_log_buffer[op].pc, buffer2);
978      }
979
980      /* advance past this instruction */
981      cur += bytes;
982   }
983
984   /* flush the file */
985   fflush(logfile);
986}
987
988#else
989
990#define code_log_reset()
991#define code_log_add_entry(a,b,c)
992#define code_log(a,b,c)
993
994#endif
995
996
997/********************************************************************/
998
999#include "ppc_ops.c"
1000#include "drc_ops.c"
1001#include "drc_ops.h"
1002
1003/* Initialization and shutdown */
1004
1005static void ppc_init(void)
1006{
1007   int i,j;
1008
1009   for( i=0; i < 64; i++ ) {
1010      ppc.optable[i] = recompile_invalid;
1011   }
1012   for( i=0; i < 1024; i++ ) {
1013      ppc.optable19[i] = recompile_invalid;
1014      ppc.optable31[i] = recompile_invalid;
1015      ppc.optable59[i] = recompile_invalid;
1016      ppc.optable63[i] = recompile_invalid;
1017   }
1018
1019   /* Fill the opcode tables */
1020   for( i=0; i < (sizeof(ppcdrc_opcode_common) / sizeof(PPC_OPCODE)); i++ ) {
1021
1022      switch(ppcdrc_opcode_common[i].code)
1023      {
1024         case 19:
1025            ppc.optable19[ppcdrc_opcode_common[i].subcode] = ppcdrc_opcode_common[i].handler;
1026            break;
1027
1028         case 31:
1029            ppc.optable31[ppcdrc_opcode_common[i].subcode] = ppcdrc_opcode_common[i].handler;
1030            break;
1031
1032         case 59:
1033         case 63:
1034            break;
1035
1036         default:
1037            ppc.optable[ppcdrc_opcode_common[i].code] = ppcdrc_opcode_common[i].handler;
1038      }
1039
1040   }
1041
1042   /* Calculate rotate mask table */
1043   for( i=0; i < 32; i++ ) {
1044      for( j=0; j < 32; j++ ) {
1045         UINT32 mask;
1046         int mb = i;
1047         int me = j;
1048         mask = ((UINT32)0xFFFFFFFF >> mb) ^ ((me >= 31) ? 0 : ((UINT32)0xFFFFFFFF >> (me + 1)));
1049         if( mb > me )
1050            mask = ~mask;
1051
1052         ppc_rotate_mask[i][j] = mask;
1053      }
1054   }
1055}
1056
1057#if (HAS_PPC403)
1058static void ppcdrc403_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1059{
1060   const ppc_config *config = _config;
1061
1062   ppc_init();
1063   ppcdrc_init();
1064
1065   /* PPC403 specific opcodes */
1066   ppc.optable31[454] = recompile_dccci;
1067   ppc.optable31[486] = recompile_dcread;
1068   ppc.optable31[262] = recompile_icbt;
1069   ppc.optable31[966] = recompile_iccci;
1070   ppc.optable31[998] = recompile_icread;
1071   ppc.optable31[323] = recompile_mfdcr;
1072   ppc.optable31[451] = recompile_mtdcr;
1073   ppc.optable31[131] = recompile_wrtee;
1074   ppc.optable31[163] = recompile_wrteei;
1075   ppc.optable19[51] = recompile_rfci;
1076
1077   ppc.spu.rx_timer = timer_alloc(ppc403_spu_rx_callback, NULL);
1078   ppc.spu.tx_timer = timer_alloc(ppc403_spu_tx_callback, NULL);
1079
1080   ppc.is603 = 0;
1081   ppc.is602 = 0;
1082
1083   ppc.read8 = ppc403_read8;
1084   ppc.read16 = ppc403_read16;
1085   ppc.read32 = ppc403_read32;
1086   ppc.write8 = ppc403_write8;
1087   ppc.write16 = ppc403_write16;
1088   ppc.write32 = ppc403_write32;
1089   ppc.read16_unaligned = ppc403_read16_unaligned;
1090   ppc.read32_unaligned = ppc403_read32_unaligned;
1091   ppc.write16_unaligned = ppc403_write16_unaligned;
1092   ppc.write32_unaligned = ppc403_write32_unaligned;
1093
1094   ppc.irq_callback = irqcallback;
1095
1096   ppc.pvr = config->pvr;
1097}
1098
1099static void ppcdrc403_exit(void)
1100{
1101#if LOG_CODE
1102   //if (symfile) fclose(symfile);
1103#endif
1104   ppcdrc_exit();
1105}
1106
1107static void ppcdrc403_reset(void)
1108{
1109   ppc.pc = ppc.npc = 0xfffffffc;
1110
1111   ppc_set_msr(0);
1112   change_pc(ppc.pc);
1113
1114   /* reset the DRC */
1115   drc_cache_reset(ppc.drc);
1116}
1117
1118static int ppcdrc403_execute(int cycles)
1119{
1120   /* count cycles and interrupt cycles */
1121   ppc_icount = cycles;
1122   ppc_tb_base_icount = cycles;
1123
1124   ppc_fit_trigger_cycle = 0x7fffffff;
1125
1126   if (ppc.fit_int_enable)
1127   {
1128      UINT32 tb = (UINT32)ppc.tb;
1129      UINT32 fit_cycles = 0;
1130
1131      if (ppc.tb & ppc.fit_bit)
1132      {
1133         fit_cycles += ppc.fit_bit;
1134         tb += fit_cycles;
1135      }
1136
1137      fit_cycles += ppc.fit_bit - (tb & (ppc.fit_bit-1));
1138
1139      ppc_fit_trigger_cycle = ppc_icount - fit_cycles;
1140   }
1141
1142   drc_execute(ppc.drc);
1143
1144   // update timebase
1145   ppc.tb += (ppc_tb_base_icount - ppc_icount);
1146
1147   return cycles - ppc_icount;
1148}
1149
1150static void ppcdrc403_set_irq_line(int irqline, int state)
1151{
1152   if (irqline >= INPUT_LINE_IRQ0 && irqline <= INPUT_LINE_IRQ4)
1153   {
1154      UINT32 mask = (1 << (4 - irqline));
1155      if( state == ASSERT_LINE) {
1156         if (EXIER & mask)
1157         {
1158            ppc.exisr |= mask;
1159            ppc.exception_pending |= 0x1;
1160
1161            if (ppc.irq_callback)
1162            {
1163               ppc.irq_callback(irqline);
1164            }
1165         }
1166      }
1167      // clear line is used to clear the interrupt when the interrupts are level-sensitive
1168      else if (state == CLEAR_LINE)
1169      {
1170         ppc.exisr &= ~mask;
1171      }
1172   }
1173   else if (irqline == PPC403_SPU_RX)
1174   {
1175      UINT32 mask = 0x08000000;
1176      if (state) {
1177         if( EXIER & mask ) {
1178            ppc.exisr |= mask;
1179            ppc.exception_pending |= 0x1;
1180         }
1181      }
1182   }
1183   else if (irqline == PPC403_SPU_TX)
1184   {
1185      UINT32 mask = 0x04000000;
1186      if (state) {
1187         if( EXIER & mask ) {
1188            ppc.exisr |= mask;
1189            ppc.exception_pending |= 0x1;
1190         }
1191      }
1192   }
1193   else
1194   {
1195      fatalerror("PPC: Unknown IRQ line %d", irqline);
1196   }
1197}
1198#endif
1199
1200#if (HAS_PPC603)
1201static void ppcdrc603_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1202{
1203   int pll_config = 0;
1204   float multiplier;
1205   const ppc_config *config = _config;
1206   int i;
1207
1208   ppc_init();
1209   ppcdrc_init();
1210
1211   ppc.optable[48] = recompile_lfs;
1212   ppc.optable[49] = recompile_lfsu;
1213   ppc.optable[50] = recompile_lfd;
1214   ppc.optable[51] = recompile_lfdu;
1215   ppc.optable[52] = recompile_stfs;
1216   ppc.optable[53] = recompile_stfsu;
1217   ppc.optable[54] = recompile_stfd;
1218   ppc.optable[55] = recompile_stfdu;
1219   ppc.optable31[631] = recompile_lfdux;
1220   ppc.optable31[599] = recompile_lfdx;
1221   ppc.optable31[567] = recompile_lfsux;
1222   ppc.optable31[535] = recompile_lfsx;
1223   ppc.optable31[595] = recompile_mfsr;
1224   ppc.optable31[659] = recompile_mfsrin;
1225   ppc.optable31[371] = recompile_mftb;
1226   ppc.optable31[210] = recompile_mtsr;
1227   ppc.optable31[242] = recompile_mtsrin;
1228   ppc.optable31[758] = recompile_dcba;
1229   ppc.optable31[759] = recompile_stfdux;
1230   ppc.optable31[727] = recompile_stfdx;
1231   ppc.optable31[983] = recompile_stfiwx;
1232   ppc.optable31[695] = recompile_stfsux;
1233   ppc.optable31[663] = recompile_stfsx;
1234   ppc.optable31[370] = recompile_tlbia;
1235   ppc.optable31[306] = recompile_tlbie;
1236   ppc.optable31[566] = recompile_tlbsync;
1237   ppc.optable31[310] = recompile_eciwx;
1238   ppc.optable31[438] = recompile_ecowx;
1239
1240   ppc.optable63[264] = recompile_fabsx;
1241   ppc.optable63[21] = recompile_faddx;
1242   ppc.optable63[32] = recompile_fcmpo;
1243   ppc.optable63[0] = recompile_fcmpu;
1244   ppc.optable63[14] = recompile_fctiwx;
1245   ppc.optable63[15] = recompile_fctiwzx;
1246   ppc.optable63[18] = recompile_fdivx;
1247   ppc.optable63[72] = recompile_fmrx;
1248   ppc.optable63[136] = recompile_fnabsx;
1249   ppc.optable63[40] = recompile_fnegx;
1250   ppc.optable63[12] = recompile_frspx;
1251   ppc.optable63[26] = recompile_frsqrtex;
1252   ppc.optable63[22] = recompile_fsqrtx;
1253   ppc.optable63[20] = recompile_fsubx;
1254   ppc.optable63[583] = recompile_mffsx;
1255   ppc.optable63[70] = recompile_mtfsb0x;
1256   ppc.optable63[38] = recompile_mtfsb1x;
1257   ppc.optable63[711] = recompile_mtfsfx;
1258   ppc.optable63[134] = recompile_mtfsfix;
1259   ppc.optable63[64] = recompile_mcrfs;
1260
1261   ppc.optable59[21] = recompile_faddsx;
1262   ppc.optable59[18] = recompile_fdivsx;
1263   ppc.optable59[24] = recompile_fresx;
1264   ppc.optable59[22] = recompile_fsqrtsx;
1265   ppc.optable59[20] = recompile_fsubsx;
1266
1267   for(i = 0; i < 32; i++)
1268   {
1269      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1270      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1271      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1272      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1273      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1274      ppc.optable63[i * 32 | 23] = recompile_fselx;
1275
1276      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1277      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1278      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1279      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1280      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
1281   }
1282
1283#if (HAS_PPC602 || HAS_MPC8240)
1284   ppc.optable31[978] = recompile_tlbld;
1285#endif /* (HAS_PPC602 || HAS_MPC8240) */
1286
1287   for(i = 0; i < 256; i++)
1288   {
1289      ppc_field_xlat[i] =
1290         ((i & 0x80) ? 0xF0000000 : 0) |
1291         ((i & 0x40) ? 0x0F000000 : 0) |
1292         ((i & 0x20) ? 0x00F00000 : 0) |
1293         ((i & 0x10) ? 0x000F0000 : 0) |
1294         ((i & 0x08) ? 0x0000F000 : 0) |
1295         ((i & 0x04) ? 0x00000F00 : 0) |
1296         ((i & 0x02) ? 0x000000F0 : 0) |
1297         ((i & 0x01) ? 0x0000000F : 0);
1298   }
1299
1300   ppc.is603 = 1;
1301
1302   ppc.read8 = program_read_byte_64be;
1303   ppc.read16 = program_read_word_64be;
1304   ppc.read32 = program_read_dword_64be;
1305   ppc.read64 = program_read_qword_64be;
1306   ppc.write8 = program_write_byte_64be;
1307   ppc.write16 = program_write_word_64be;
1308   ppc.write32 = program_write_dword_64be;
1309   ppc.write64 = program_write_qword_64be;
1310   ppc.read16_unaligned = ppc_read16_unaligned;
1311   ppc.read32_unaligned = ppc_read32_unaligned;
1312   ppc.read64_unaligned = ppc_read64_unaligned;
1313   ppc.write16_unaligned = ppc_write16_unaligned;
1314   ppc.write32_unaligned = ppc_write32_unaligned;
1315   ppc.write64_unaligned = ppc_write64_unaligned;
1316
1317   ppc.irq_callback = irqcallback;
1318
1319   ppc.pvr = config->pvr;
1320
1321   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1322             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1323   bus_freq_multiplier = (int)(multiplier * 2);
1324
1325   switch(config->pvr)
1326   {
1327      case PPC_MODEL_603E:   pll_config = mpc603e_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1328      case PPC_MODEL_603EV:   pll_config = mpc603ev_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1329      case PPC_MODEL_603R:   pll_config = mpc603r_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1330      default: break;
1331   }
1332
1333   if (pll_config == -1)
1334   {
1335      fatalerror("PPC: Invalid bus/multiplier combination (bus frequency = %d, multiplier = %1.1f)", config->bus_frequency, multiplier);
1336   }
1337
1338   ppc.hid1 = pll_config << 28;
1339}
1340
1341static void ppcdrc603_exit(void)
1342{
1343#if LOG_CODE
1344   //if (symfile) fclose(symfile);
1345#endif
1346   ppcdrc_exit();
1347}
1348#endif
1349
1350#if (HAS_PPC601 || HAS_PPC603 || HAS_MPC8240 || HAS_PPC604)
1351static void ppcdrc603_reset(void)
1352{
1353   ppc.pc = ppc.npc = 0xfff00100;
1354
1355   ppc_set_msr(0x40);
1356   change_pc(ppc.pc);
1357
1358   /* reset the DRC */
1359   drc_cache_reset(ppc.drc);
1360}
1361
1362static int ppcdrc603_execute(int cycles)
1363{
1364   /* count cycles and interrupt cycles */
1365   ppc_icount = cycles;
1366   ppc_tb_base_icount = cycles;
1367   ppc_dec_base_icount = cycles + ppc.dec_frac;
1368
1369   // check if decrementer exception occurs during execution
1370   if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC))
1371   {
1372      ppc_dec_trigger_cycle = ppc_icount - DEC;
1373   }
1374   else
1375   {
1376      ppc_dec_trigger_cycle = 0x7fffffff;
1377   }
1378
1379   drc_execute(ppc.drc);
1380
1381   // update timebase
1382   // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly
1383   ppc.tb += ((ppc_tb_base_icount - ppc_icount) / 4);
1384
1385   // update decrementer
1386   ppc.dec_frac = ((ppc_dec_base_icount - ppc_icount) % (bus_freq_multiplier * 2));
1387   DEC -= ((ppc_dec_base_icount - ppc_icount) / (bus_freq_multiplier * 2));
1388
1389   return cycles - ppc_icount;
1390}
1391
1392static void ppcdrc603_set_irq_line(int irqline, int state)
1393{
1394   if( state ) {
1395      ppc.exception_pending |= 0x1;
1396      if (ppc.irq_callback)
1397      {
1398         ppc.irq_callback(irqline);
1399      }
1400   }
1401}
1402#endif
1403
1404#if (HAS_PPC602)
1405static void ppcdrc602_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1406{
1407   float multiplier;
1408   const ppc_config *config = _config;
1409   int i;
1410
1411   ppc_init();
1412   ppcdrc_init();
1413
1414   ppc.optable[48] = recompile_lfs;
1415   ppc.optable[49] = recompile_lfsu;
1416   ppc.optable[50] = recompile_lfd;
1417   ppc.optable[51] = recompile_lfdu;
1418   ppc.optable[52] = recompile_stfs;
1419   ppc.optable[53] = recompile_stfsu;
1420   ppc.optable[54] = recompile_stfd;
1421   ppc.optable[55] = recompile_stfdu;
1422   ppc.optable31[631] = recompile_lfdux;
1423   ppc.optable31[599] = recompile_lfdx;
1424   ppc.optable31[567] = recompile_lfsux;
1425   ppc.optable31[535] = recompile_lfsx;
1426   ppc.optable31[595] = recompile_mfsr;
1427   ppc.optable31[659] = recompile_mfsrin;
1428   ppc.optable31[371] = recompile_mftb;
1429   ppc.optable31[210] = recompile_mtsr;
1430   ppc.optable31[242] = recompile_mtsrin;
1431   ppc.optable31[758] = recompile_dcba;
1432   ppc.optable31[759] = recompile_stfdux;
1433   ppc.optable31[727] = recompile_stfdx;
1434   ppc.optable31[983] = recompile_stfiwx;
1435   ppc.optable31[695] = recompile_stfsux;
1436   ppc.optable31[663] = recompile_stfsx;
1437   ppc.optable31[370] = recompile_tlbia;
1438   ppc.optable31[306] = recompile_tlbie;
1439   ppc.optable31[566] = recompile_tlbsync;
1440   ppc.optable31[310] = recompile_eciwx;
1441   ppc.optable31[438] = recompile_ecowx;
1442
1443   ppc.optable63[264] = recompile_fabsx;
1444   ppc.optable63[21] = recompile_faddx;
1445   ppc.optable63[32] = recompile_fcmpo;
1446   ppc.optable63[0] = recompile_fcmpu;
1447   ppc.optable63[14] = recompile_fctiwx;
1448   ppc.optable63[15] = recompile_fctiwzx;
1449   ppc.optable63[18] = recompile_fdivx;
1450   ppc.optable63[72] = recompile_fmrx;
1451   ppc.optable63[136] = recompile_fnabsx;
1452   ppc.optable63[40] = recompile_fnegx;
1453   ppc.optable63[12] = recompile_frspx;
1454   ppc.optable63[26] = recompile_frsqrtex;
1455   ppc.optable63[22] = recompile_fsqrtx;
1456   ppc.optable63[20] = recompile_fsubx;
1457   ppc.optable63[583] = recompile_mffsx;
1458   ppc.optable63[70] = recompile_mtfsb0x;
1459   ppc.optable63[38] = recompile_mtfsb1x;
1460   ppc.optable63[711] = recompile_mtfsfx;
1461   ppc.optable63[134] = recompile_mtfsfix;
1462   ppc.optable63[64] = recompile_mcrfs;
1463
1464   ppc.optable59[21] = recompile_faddsx;
1465   ppc.optable59[18] = recompile_fdivsx;
1466   ppc.optable59[24] = recompile_fresx;
1467   ppc.optable59[22] = recompile_fsqrtsx;
1468   ppc.optable59[20] = recompile_fsubsx;
1469
1470   for(i = 0; i < 32; i++)
1471   {
1472      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1473      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1474      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1475      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1476      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1477      ppc.optable63[i * 32 | 23] = recompile_fselx;
1478
1479      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1480      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1481      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1482      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1483      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
1484   }
1485
1486   for(i = 0; i < 256; i++)
1487   {
1488      ppc_field_xlat[i] =
1489         ((i & 0x80) ? 0xF0000000 : 0) |
1490         ((i & 0x40) ? 0x0F000000 : 0) |
1491         ((i & 0x20) ? 0x00F00000 : 0) |
1492         ((i & 0x10) ? 0x000F0000 : 0) |
1493         ((i & 0x08) ? 0x0000F000 : 0) |
1494         ((i & 0x04) ? 0x00000F00 : 0) |
1495         ((i & 0x02) ? 0x000000F0 : 0) |
1496         ((i & 0x01) ? 0x0000000F : 0);
1497   }
1498
1499   // PPC602 specific opcodes
1500   ppc.optable31[596] = recompile_esa;
1501   ppc.optable31[628] = recompile_dsa;
1502   ppc.optable31[1010] = recompile_tlbli;
1503   ppc.optable31[978] = recompile_tlbld;
1504
1505   ppc.is603 = 0;
1506   ppc.is602 = 1;
1507
1508   ppc.read8 = program_read_byte_64be;
1509   ppc.read16 = program_read_word_64be;
1510   ppc.read32 = program_read_dword_64be;
1511   ppc.read64 = program_read_qword_64be;
1512   ppc.write8 = program_write_byte_64be;
1513   ppc.write16 = program_write_word_64be;
1514   ppc.write32 = program_write_dword_64be;
1515   ppc.write64 = program_write_qword_64be;
1516   ppc.read16_unaligned = ppc_read16_unaligned;
1517   ppc.read32_unaligned = ppc_read32_unaligned;
1518   ppc.read64_unaligned = ppc_read64_unaligned;
1519   ppc.write16_unaligned = ppc_write16_unaligned;
1520   ppc.write32_unaligned = ppc_write32_unaligned;
1521   ppc.write64_unaligned = ppc_write64_unaligned;
1522
1523   ppc.irq_callback = irqcallback;
1524
1525   ppc.pvr = config->pvr;
1526
1527   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1528             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1529   bus_freq_multiplier = (int)(multiplier * 2);
1530}
1531
1532static void ppcdrc602_exit(void)
1533{
1534#if LOG_CODE
1535   //if (symfile) fclose(symfile);
1536#endif
1537   ppcdrc_exit();
1538}
1539
1540static void ppcdrc602_reset(void)
1541{
1542   ppc.pc = ppc.npc = 0xfff00100;
1543
1544   ppc_set_msr(0x40);
1545   change_pc(ppc.pc);
1546
1547   ppc.hid0 = 1;
1548
1549   /* reset the DRC */
1550   drc_cache_reset(ppc.drc);
1551}
1552
1553static int ppcdrc602_execute(int cycles)
1554{
1555   /* count cycles and interrupt cycles */
1556   ppc_icount = cycles;
1557   ppc_tb_base_icount = cycles;
1558   ppc_dec_base_icount = cycles;
1559
1560   // check if decrementer exception occurs during execution
1561   if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC))
1562   {
1563      ppc_dec_trigger_cycle = ppc_icount - DEC;
1564   }
1565   else
1566   {
1567      ppc_dec_trigger_cycle = 0x7fffffff;
1568   }
1569
1570   drc_execute(ppc.drc);
1571
1572   // update timebase
1573   // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly
1574   ppc.tb += ((ppc_tb_base_icount - ppc_icount) / 4);
1575
1576   // update decrementer
1577   DEC -= ((ppc_dec_base_icount - ppc_icount) / (bus_freq_multiplier * 2));
1578
1579   return cycles - ppc_icount;
1580}
1581
1582static void ppcdrc602_set_irq_line(int irqline, int state)
1583{
1584   if( state ) {
1585      ppc.exception_pending |= 0x1;
1586      if (ppc.irq_callback)
1587      {
1588         ppc.irq_callback(irqline);
1589      }
1590   }
1591}
1592#endif
1593
1594#if (HAS_MPC8240)
1595static void mpc8240drc_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1596{
1597   float multiplier;
1598   const ppc_config *config = _config;
1599   int i;
1600
1601   ppc_init();
1602   ppcdrc_init();
1603
1604   ppc.optable[48] = recompile_lfs;
1605   ppc.optable[49] = recompile_lfsu;
1606   ppc.optable[50] = recompile_lfd;
1607   ppc.optable[51] = recompile_lfdu;
1608   ppc.optable[52] = recompile_stfs;
1609   ppc.optable[53] = recompile_stfsu;
1610   ppc.optable[54] = recompile_stfd;
1611   ppc.optable[55] = recompile_stfdu;
1612   ppc.optable31[631] = recompile_lfdux;
1613   ppc.optable31[599] = recompile_lfdx;
1614   ppc.optable31[567] = recompile_lfsux;
1615   ppc.optable31[535] = recompile_lfsx;
1616   ppc.optable31[595] = recompile_mfsr;
1617   ppc.optable31[659] = recompile_mfsrin;
1618   ppc.optable31[371] = recompile_mftb;
1619   ppc.optable31[210] = recompile_mtsr;
1620   ppc.optable31[242] = recompile_mtsrin;
1621   ppc.optable31[758] = recompile_dcba;
1622   ppc.optable31[759] = recompile_stfdux;
1623   ppc.optable31[727] = recompile_stfdx;
1624   ppc.optable31[983] = recompile_stfiwx;
1625   ppc.optable31[695] = recompile_stfsux;
1626   ppc.optable31[663] = recompile_stfsx;
1627   ppc.optable31[370] = recompile_tlbia;
1628   ppc.optable31[306] = recompile_tlbie;
1629   ppc.optable31[566] = recompile_tlbsync;
1630   ppc.optable31[310] = recompile_eciwx;
1631   ppc.optable31[438] = recompile_ecowx;
1632
1633   ppc.optable63[264] = recompile_fabsx;
1634   ppc.optable63[21] = recompile_faddx;
1635   ppc.optable63[32] = recompile_fcmpo;
1636   ppc.optable63[0] = recompile_fcmpu;
1637   ppc.optable63[14] = recompile_fctiwx;
1638   ppc.optable63[15] = recompile_fctiwzx;
1639   ppc.optable63[18] = recompile_fdivx;
1640   ppc.optable63[72] = recompile_fmrx;
1641   ppc.optable63[136] = recompile_fnabsx;
1642   ppc.optable63[40] = recompile_fnegx;
1643   ppc.optable63[12] = recompile_frspx;
1644   ppc.optable63[26] = recompile_frsqrtex;
1645   ppc.optable63[22] = recompile_fsqrtx;
1646   ppc.optable63[20] = recompile_fsubx;
1647   ppc.optable63[583] = recompile_mffsx;
1648   ppc.optable63[70] = recompile_mtfsb0x;
1649   ppc.optable63[38] = recompile_mtfsb1x;
1650   ppc.optable63[711] = recompile_mtfsfx;
1651   ppc.optable63[134] = recompile_mtfsfix;
1652   ppc.optable63[64] = recompile_mcrfs;
1653
1654   ppc.optable59[21] = recompile_faddsx;
1655   ppc.optable59[18] = recompile_fdivsx;
1656   ppc.optable59[24] = recompile_fresx;
1657   ppc.optable59[22] = recompile_fsqrtsx;
1658   ppc.optable59[20] = recompile_fsubsx;
1659
1660   for(i = 0; i < 32; i++)
1661   {
1662      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1663      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1664      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1665      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1666      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1667      ppc.optable63[i * 32 | 23] = recompile_fselx;
1668
1669      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1670      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1671      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1672      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1673      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
1674   }
1675
1676   for(i = 0; i < 256; i++)
1677   {
1678      ppc_field_xlat[i] =
1679         ((i & 0x80) ? 0xF0000000 : 0) |
1680         ((i & 0x40) ? 0x0F000000 : 0) |
1681         ((i & 0x20) ? 0x00F00000 : 0) |
1682         ((i & 0x10) ? 0x000F0000 : 0) |
1683         ((i & 0x08) ? 0x0000F000 : 0) |
1684         ((i & 0x04) ? 0x00000F00 : 0) |
1685         ((i & 0x02) ? 0x000000F0 : 0) |
1686         ((i & 0x01) ? 0x0000000F : 0);
1687   }
1688
1689   // MPC8240 specific opcodes
1690   ppc.optable31[978] = recompile_tlbld;
1691   ppc.optable31[1010] = recompile_tlbli;
1692
1693   ppc.is603 = 1;
1694
1695   ppc.read8 = program_read_byte_64be;
1696   ppc.read16 = program_read_word_64be;
1697   ppc.read32 = program_read_dword_64be;
1698   ppc.read64 = program_read_qword_64be;
1699   ppc.write8 = program_write_byte_64be;
1700   ppc.write16 = program_write_word_64be;
1701   ppc.write32 = program_write_dword_64be;
1702   ppc.write64 = program_write_qword_64be;
1703   ppc.read16_unaligned = ppc_read16_unaligned;
1704   ppc.read32_unaligned = ppc_read32_unaligned;
1705   ppc.read64_unaligned = ppc_read64_unaligned;
1706   ppc.write16_unaligned = ppc_write16_unaligned;
1707   ppc.write32_unaligned = ppc_write32_unaligned;
1708   ppc.write64_unaligned = ppc_write64_unaligned;
1709
1710   ppc.irq_callback = irqcallback;
1711
1712   ppc.pvr = config->pvr;
1713
1714   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1715             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1716   bus_freq_multiplier = (int)(multiplier * 2);
1717}
1718
1719static void mpc8240drc_exit(void)
1720{
1721   ppcdrc_exit();
1722}
1723#endif
1724
1725
1726#if (HAS_PPC601)
1727static void ppc601drc_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1728{
1729   int pll_config = 0;
1730   float multiplier;
1731   const ppc_config *config = _config;
1732   int i;
1733
1734   ppc_init();
1735   ppcdrc_init();
1736
1737   ppc.optable[48] = recompile_lfs;
1738   ppc.optable[49] = recompile_lfsu;
1739   ppc.optable[50] = recompile_lfd;
1740   ppc.optable[51] = recompile_lfdu;
1741   ppc.optable[52] = recompile_stfs;
1742   ppc.optable[53] = recompile_stfsu;
1743   ppc.optable[54] = recompile_stfd;
1744   ppc.optable[55] = recompile_stfdu;
1745   ppc.optable31[631] = recompile_lfdux;
1746   ppc.optable31[599] = recompile_lfdx;
1747   ppc.optable31[567] = recompile_lfsux;
1748   ppc.optable31[535] = recompile_lfsx;
1749   ppc.optable31[595] = recompile_mfsr;
1750   ppc.optable31[659] = recompile_mfsrin;
1751   ppc.optable31[371] = recompile_mftb;
1752   ppc.optable31[210] = recompile_mtsr;
1753   ppc.optable31[242] = recompile_mtsrin;
1754   ppc.optable31[758] = recompile_dcba;
1755   ppc.optable31[759] = recompile_stfdux;
1756   ppc.optable31[727] = recompile_stfdx;
1757   ppc.optable31[983] = recompile_stfiwx;
1758   ppc.optable31[695] = recompile_stfsux;
1759   ppc.optable31[663] = recompile_stfsx;
1760   ppc.optable31[370] = recompile_tlbia;
1761   ppc.optable31[306] = recompile_tlbie;
1762   ppc.optable31[566] = recompile_tlbsync;
1763   ppc.optable31[310] = recompile_eciwx;
1764   ppc.optable31[438] = recompile_ecowx;
1765
1766   ppc.optable63[264] = recompile_fabsx;
1767   ppc.optable63[21] = recompile_faddx;
1768   ppc.optable63[32] = recompile_fcmpo;
1769   ppc.optable63[0] = recompile_fcmpu;
1770   ppc.optable63[14] = recompile_fctiwx;
1771   ppc.optable63[15] = recompile_fctiwzx;
1772   ppc.optable63[18] = recompile_fdivx;
1773   ppc.optable63[72] = recompile_fmrx;
1774   ppc.optable63[136] = recompile_fnabsx;
1775   ppc.optable63[40] = recompile_fnegx;
1776   ppc.optable63[12] = recompile_frspx;
1777   ppc.optable63[26] = recompile_frsqrtex;
1778   ppc.optable63[22] = recompile_fsqrtx;
1779   ppc.optable63[20] = recompile_fsubx;
1780   ppc.optable63[583] = recompile_mffsx;
1781   ppc.optable63[70] = recompile_mtfsb0x;
1782   ppc.optable63[38] = recompile_mtfsb1x;
1783   ppc.optable63[711] = recompile_mtfsfx;
1784   ppc.optable63[134] = recompile_mtfsfix;
1785   ppc.optable63[64] = recompile_mcrfs;
1786
1787   ppc.optable59[21] = recompile_faddsx;
1788   ppc.optable59[18] = recompile_fdivsx;
1789   ppc.optable59[24] = recompile_fresx;
1790   ppc.optable59[22] = recompile_fsqrtsx;
1791   ppc.optable59[20] = recompile_fsubsx;
1792
1793   for(i = 0; i < 32; i++)
1794   {
1795      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1796      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1797      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1798      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1799      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1800      ppc.optable63[i * 32 | 23] = recompile_fselx;
1801
1802      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1803      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1804      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1805      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1806      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
1807   }
1808
1809   for(i = 0; i < 256; i++)
1810   {
1811      ppc_field_xlat[i] =
1812         ((i & 0x80) ? 0xF0000000 : 0) |
1813         ((i & 0x40) ? 0x0F000000 : 0) |
1814         ((i & 0x20) ? 0x00F00000 : 0) |
1815         ((i & 0x10) ? 0x000F0000 : 0) |
1816         ((i & 0x08) ? 0x0000F000 : 0) |
1817         ((i & 0x04) ? 0x00000F00 : 0) |
1818         ((i & 0x02) ? 0x000000F0 : 0) |
1819         ((i & 0x01) ? 0x0000000F : 0);
1820   }
1821
1822   ppc.is603 = 1;
1823
1824   ppc.read8 = program_read_byte_64be;
1825   ppc.read16 = program_read_word_64be;
1826   ppc.read32 = program_read_dword_64be;
1827   ppc.read64 = program_read_qword_64be;
1828   ppc.write8 = program_write_byte_64be;
1829   ppc.write16 = program_write_word_64be;
1830   ppc.write32 = program_write_dword_64be;
1831   ppc.write64 = program_write_qword_64be;
1832   ppc.read16_unaligned = ppc_read16_unaligned;
1833   ppc.read32_unaligned = ppc_read32_unaligned;
1834   ppc.read64_unaligned = ppc_read64_unaligned;
1835   ppc.write16_unaligned = ppc_write16_unaligned;
1836   ppc.write32_unaligned = ppc_write32_unaligned;
1837   ppc.write64_unaligned = ppc_write64_unaligned;
1838
1839   ppc.irq_callback = irqcallback;
1840
1841   ppc.pvr = config->pvr;
1842
1843   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1844             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1845   bus_freq_multiplier = (int)(multiplier * 2);
1846
1847   switch(config->pvr)
1848   {
1849      case PPC_MODEL_603E:   pll_config = mpc603e_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1850      case PPC_MODEL_603EV:   pll_config = mpc603ev_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1851      case PPC_MODEL_603R:   pll_config = mpc603r_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1852      default: break;
1853   }
1854
1855   if (pll_config == -1)
1856   {
1857      fatalerror("PPC: Invalid bus/multiplier combination (bus frequency = %d, multiplier = %1.1f)", config->bus_frequency, multiplier);
1858   }
1859
1860   ppc.hid1 = pll_config << 28;
1861}
1862
1863static void ppc601drc_exit(void)
1864{
1865#if LOG_CODE
1866   //if (symfile) fclose(symfile);
1867#endif
1868   ppcdrc_exit();
1869}
1870#endif
1871
1872
1873#if (HAS_PPC604)
1874static void ppc604drc_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1875{
1876   float multiplier;
1877   const ppc_config *config = _config;
1878   int i;
1879
1880   ppc_init();
1881   ppcdrc_init();
1882
1883   ppc.optable[48] = recompile_lfs;
1884   ppc.optable[49] = recompile_lfsu;
1885   ppc.optable[50] = recompile_lfd;
1886   ppc.optable[51] = recompile_lfdu;
1887   ppc.optable[52] = recompile_stfs;
1888   ppc.optable[53] = recompile_stfsu;
1889   ppc.optable[54] = recompile_stfd;
1890   ppc.optable[55] = recompile_stfdu;
1891   ppc.optable31[631] = recompile_lfdux;
1892   ppc.optable31[599] = recompile_lfdx;
1893   ppc.optable31[567] = recompile_lfsux;
1894   ppc.optable31[535] = recompile_lfsx;
1895   ppc.optable31[595] = recompile_mfsr;
1896   ppc.optable31[659] = recompile_mfsrin;
1897   ppc.optable31[371] = recompile_mftb;
1898   ppc.optable31[210] = recompile_mtsr;
1899   ppc.optable31[242] = recompile_mtsrin;
1900   ppc.optable31[758] = recompile_dcba;
1901   ppc.optable31[759] = recompile_stfdux;
1902   ppc.optable31[727] = recompile_stfdx;
1903   ppc.optable31[983] = recompile_stfiwx;
1904   ppc.optable31[695] = recompile_stfsux;
1905   ppc.optable31[663] = recompile_stfsx;
1906   ppc.optable31[370] = recompile_tlbia;
1907   ppc.optable31[306] = recompile_tlbie;
1908   ppc.optable31[566] = recompile_tlbsync;
1909   ppc.optable31[310] = recompile_eciwx;
1910   ppc.optable31[438] = recompile_ecowx;
1911
1912   ppc.optable63[264] = recompile_fabsx;
1913   ppc.optable63[21] = recompile_faddx;
1914   ppc.optable63[32] = recompile_fcmpo;
1915   ppc.optable63[0] = recompile_fcmpu;
1916   ppc.optable63[14] = recompile_fctiwx;
1917   ppc.optable63[15] = recompile_fctiwzx;
1918   ppc.optable63[18] = recompile_fdivx;
1919   ppc.optable63[72] = recompile_fmrx;
1920   ppc.optable63[136] = recompile_fnabsx;
1921   ppc.optable63[40] = recompile_fnegx;
1922   ppc.optable63[12] = recompile_frspx;
1923   ppc.optable63[26] = recompile_frsqrtex;
1924   ppc.optable63[22] = recompile_fsqrtx;
1925   ppc.optable63[20] = recompile_fsubx;
1926   ppc.optable63[583] = recompile_mffsx;
1927   ppc.optable63[70] = recompile_mtfsb0x;
1928   ppc.optable63[38] = recompile_mtfsb1x;
1929   ppc.optable63[711] = recompile_mtfsfx;
1930   ppc.optable63[134] = recompile_mtfsfix;
1931   ppc.optable63[64] = recompile_mcrfs;
1932
1933   ppc.optable59[21] = recompile_faddsx;
1934   ppc.optable59[18] = recompile_fdivsx;
1935   ppc.optable59[24] = recompile_fresx;
1936   ppc.optable59[22] = recompile_fsqrtsx;
1937   ppc.optable59[20] = recompile_fsubsx;
1938
1939   for(i = 0; i < 32; i++)
1940   {
1941      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1942      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1943      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1944      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1945      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1946      ppc.optable63[i * 32 | 23] = recompile_fselx;
1947
1948      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1949      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1950      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1951      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1952      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
1953   }
1954
1955   ppc.optable31[978] = recompile_tlbld;
1956
1957   for(i = 0; i < 256; i++)
1958   {
1959      ppc_field_xlat[i] =
1960         ((i & 0x80) ? 0xF0000000 : 0) |
1961         ((i & 0x40) ? 0x0F000000 : 0) |
1962         ((i & 0x20) ? 0x00F00000 : 0) |
1963         ((i & 0x10) ? 0x000F0000 : 0) |
1964         ((i & 0x08) ? 0x0000F000 : 0) |
1965         ((i & 0x04) ? 0x00000F00 : 0) |
1966         ((i & 0x02) ? 0x000000F0 : 0) |
1967         ((i & 0x01) ? 0x0000000F : 0);
1968   }
1969
1970   ppc.is603 = 1;
1971
1972   ppc.read8 = program_read_byte_64be;
1973   ppc.read16 = program_read_word_64be;
1974   ppc.read32 = program_read_dword_64be;
1975   ppc.read64 = program_read_qword_64be;
1976   ppc.write8 = program_write_byte_64be;
1977   ppc.write16 = program_write_word_64be;
1978   ppc.write32 = program_write_dword_64be;
1979   ppc.write64 = program_write_qword_64be;
1980   ppc.read16_unaligned = ppc_read16_unaligned;
1981   ppc.read32_unaligned = ppc_read32_unaligned;
1982   ppc.read64_unaligned = ppc_read64_unaligned;
1983   ppc.write16_unaligned = ppc_write16_unaligned;
1984   ppc.write32_unaligned = ppc_write32_unaligned;
1985   ppc.write64_unaligned = ppc_write64_unaligned;
1986
1987   ppc.irq_callback = irqcallback;
1988
1989   ppc.pvr = config->pvr;
1990
1991   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1992             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1993   bus_freq_multiplier = (int)(multiplier * 2);
1994}
1995
1996static void ppc604drc_exit(void)
1997{
1998#if LOG_CODE
1999   //if (symfile) fclose(symfile);
2000#endif
2001   ppcdrc_exit();
2002}
2003#endif
2004
2005
2006static void ppc_get_context(void *dst)
2007{
2008   /* copy the context */
2009   if (dst)
2010      *(PPC_REGS *)dst = ppc;
2011}
2012
2013
2014static void ppc_set_context(void *src)
2015{
2016   /* copy the context */
2017   if (src)
2018      ppc = *(PPC_REGS *)src;
2019
2020   change_pc(ppc.pc);
2021}
2022
2023
2024/**************************************************************************
2025 * Generic set_info
2026 **************************************************************************/
2027
2028static void ppc_set_info(UINT32 state, cpuinfo *info)
2029{
2030   switch (state)
2031   {
2032      case CPUINFO_INT_PC:
2033      case CPUINFO_INT_REGISTER + PPC_PC:            ppc.pc = info->i;                  break;
2034      case CPUINFO_INT_REGISTER + PPC_MSR:         ppc_set_msr(info->i);                break;
2035      case CPUINFO_INT_REGISTER + PPC_CR:            ppc_set_cr(info->i);                break;
2036      case CPUINFO_INT_REGISTER + PPC_LR:            LR = info->i;                     break;
2037      case CPUINFO_INT_REGISTER + PPC_CTR:         CTR = info->i;                     break;
2038      case CPUINFO_INT_REGISTER + PPC_XER:         XER = info->i;                      break;
2039      case CPUINFO_INT_REGISTER + PPC_SRR0:         SRR0 = info->i;                     break;
2040      case CPUINFO_INT_REGISTER + PPC_SRR1:         SRR1 = info->i;                     break;
2041
2042      case CPUINFO_INT_REGISTER + PPC_R0:            ppc.r[0] = info->i;                  break;
2043      case CPUINFO_INT_REGISTER + PPC_R1:            ppc.r[1] = info->i;                  break;
2044      case CPUINFO_INT_REGISTER + PPC_R2:            ppc.r[2] = info->i;                  break;
2045      case CPUINFO_INT_REGISTER + PPC_R3:            ppc.r[3] = info->i;                  break;
2046      case CPUINFO_INT_REGISTER + PPC_R4:            ppc.r[4] = info->i;                  break;
2047      case CPUINFO_INT_REGISTER + PPC_R5:            ppc.r[5] = info->i;                  break;
2048      case CPUINFO_INT_REGISTER + PPC_R6:            ppc.r[6] = info->i;                  break;
2049      case CPUINFO_INT_REGISTER + PPC_R7:            ppc.r[7] = info->i;                  break;
2050      case CPUINFO_INT_REGISTER + PPC_R8:            ppc.r[8] = info->i;                  break;
2051      case CPUINFO_INT_REGISTER + PPC_R9:            ppc.r[9] = info->i;                  break;
2052      case CPUINFO_INT_REGISTER + PPC_R10:         ppc.r[10] = info->i;               break;
2053      case CPUINFO_INT_REGISTER + PPC_R11:         ppc.r[11] = info->i;               break;
2054      case CPUINFO_INT_REGISTER + PPC_R12:         ppc.r[12] = info->i;               break;
2055      case CPUINFO_INT_REGISTER + PPC_R13:         ppc.r[13] = info->i;               break;
2056      case CPUINFO_INT_REGISTER + PPC_R14:         ppc.r[14] = info->i;               break;
2057      case CPUINFO_INT_REGISTER + PPC_R15:         ppc.r[15] = info->i;               break;
2058      case CPUINFO_INT_REGISTER + PPC_R16:         ppc.r[16] = info->i;               break;
2059      case CPUINFO_INT_REGISTER + PPC_R17:         ppc.r[17] = info->i;               break;
2060      case CPUINFO_INT_REGISTER + PPC_R18:         ppc.r[18] = info->i;               break;
2061      case CPUINFO_INT_REGISTER + PPC_R19:         ppc.r[19] = info->i;               break;
2062      case CPUINFO_INT_REGISTER + PPC_R20:         ppc.r[20] = info->i;               break;
2063      case CPUINFO_INT_REGISTER + PPC_R21:         ppc.r[21] = info->i;               break;
2064      case CPUINFO_INT_REGISTER + PPC_R22:         ppc.r[22] = info->i;               break;
2065      case CPUINFO_INT_REGISTER + PPC_R23:         ppc.r[23] = info->i;               break;
2066      case CPUINFO_INT_REGISTER + PPC_R24:         ppc.r[24] = info->i;               break;
2067      case CPUINFO_INT_REGISTER + PPC_R25:         ppc.r[25] = info->i;               break;
2068      case CPUINFO_INT_REGISTER + PPC_R26:         ppc.r[26] = info->i;               break;
2069      case CPUINFO_INT_REGISTER + PPC_R27:         ppc.r[27] = info->i;               break;
2070      case CPUINFO_INT_REGISTER + PPC_R28:         ppc.r[28] = info->i;               break;
2071      case CPUINFO_INT_REGISTER + PPC_R29:         ppc.r[29] = info->i;               break;
2072      case CPUINFO_INT_REGISTER + PPC_R30:         ppc.r[30] = info->i;               break;
2073      case CPUINFO_INT_REGISTER + PPC_R31:         ppc.r[31] = info->i;               break;
2074
2075      case CPUINFO_INT_PPC_DRC_OPTIONS:            ppc.drcoptions = info->i;            break;
2076   }
2077}
2078
2079static void ppc_get_info(UINT32 state, cpuinfo *info)
2080{
2081   switch(state)
2082   {
2083      /* --- the following bits of info are returned as 64-bit signed integers --- */
2084      case CPUINFO_INT_CONTEXT_SIZE:               info->i = sizeof(ppc);               break;
2085      case CPUINFO_INT_INPUT_LINES:               info->i = 1;                     break;
2086      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:         info->i = 0;                     break;
2087      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2088      case CPUINFO_INT_CLOCK_MULTIPLIER:            info->i = 1;                     break;
2089      case CPUINFO_INT_CLOCK_DIVIDER:               info->i = 1;                     break;
2090      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 4;                     break;
2091      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 4;                     break;
2092      case CPUINFO_INT_MIN_CYCLES:               info->i = 1;                     break;
2093      case CPUINFO_INT_MAX_CYCLES:               info->i = 40;                     break;
2094
2095      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 32;               break;
2096      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2097      case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0;               break;
2098      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA:   info->i = 0;               break;
2099      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA:    info->i = 0;               break;
2100      case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA:    info->i = 0;               break;
2101      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO:      info->i = 0;               break;
2102      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO:       info->i = 0;               break;
2103      case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO:       info->i = 0;               break;
2104
2105      case CPUINFO_INT_INPUT_STATE:               info->i = CLEAR_LINE;               break;
2106
2107      case CPUINFO_INT_PREVIOUSPC:               /* not implemented */               break;
2108
2109      case CPUINFO_INT_PC:   /* intentional fallthrough */
2110      case CPUINFO_INT_REGISTER + PPC_PC:            info->i = ppc.pc;                  break;
2111      case CPUINFO_INT_REGISTER + PPC_MSR:         info->i = ppc_get_msr();            break;
2112      case CPUINFO_INT_REGISTER + PPC_CR:            info->i = ppc_get_cr();               break;
2113      case CPUINFO_INT_REGISTER + PPC_LR:            info->i = LR;                     break;
2114      case CPUINFO_INT_REGISTER + PPC_CTR:         info->i = CTR;                     break;
2115      case CPUINFO_INT_REGISTER + PPC_XER:         info->i = XER;                     break;
2116      case CPUINFO_INT_REGISTER + PPC_SRR0:         info->i = SRR0;                     break;
2117      case CPUINFO_INT_REGISTER + PPC_SRR1:         info->i = SRR1;                     break;
2118
2119      case CPUINFO_INT_REGISTER + PPC_R0:            info->i = ppc.r[0];                  break;
2120      case CPUINFO_INT_REGISTER + PPC_R1:            info->i = ppc.r[1];                  break;
2121      case CPUINFO_INT_REGISTER + PPC_R2:            info->i = ppc.r[2];                  break;
2122      case CPUINFO_INT_REGISTER + PPC_R3:            info->i = ppc.r[3];                  break;
2123      case CPUINFO_INT_REGISTER + PPC_R4:            info->i = ppc.r[4];                  break;
2124      case CPUINFO_INT_REGISTER + PPC_R5:            info->i = ppc.r[5];                  break;
2125      case CPUINFO_INT_REGISTER + PPC_R6:            info->i = ppc.r[6];                  break;
2126      case CPUINFO_INT_REGISTER + PPC_R7:            info->i = ppc.r[7];                  break;
2127      case CPUINFO_INT_REGISTER + PPC_R8:            info->i = ppc.r[8];                  break;
2128      case CPUINFO_INT_REGISTER + PPC_R9:            info->i = ppc.r[9];                  break;
2129      case CPUINFO_INT_REGISTER + PPC_R10:         info->i = ppc.r[10];               break;
2130      case CPUINFO_INT_REGISTER + PPC_R11:         info->i = ppc.r[11];               break;
2131      case CPUINFO_INT_REGISTER + PPC_R12:         info->i = ppc.r[12];               break;
2132      case CPUINFO_INT_REGISTER + PPC_R13:         info->i = ppc.r[13];               break;
2133      case CPUINFO_INT_REGISTER + PPC_R14:         info->i = ppc.r[14];               break;
2134      case CPUINFO_INT_REGISTER + PPC_R15:         info->i = ppc.r[15];               break;
2135      case CPUINFO_INT_REGISTER + PPC_R16:         info->i = ppc.r[16];               break;
2136      case CPUINFO_INT_REGISTER + PPC_R17:         info->i = ppc.r[17];               break;
2137      case CPUINFO_INT_REGISTER + PPC_R18:         info->i = ppc.r[18];               break;
2138      case CPUINFO_INT_REGISTER + PPC_R19:         info->i = ppc.r[19];               break;
2139      case CPUINFO_INT_REGISTER + PPC_R20:         info->i = ppc.r[20];               break;
2140      case CPUINFO_INT_REGISTER + PPC_R21:         info->i = ppc.r[21];               break;
2141      case CPUINFO_INT_REGISTER + PPC_R22:         info->i = ppc.r[22];               break;
2142      case CPUINFO_INT_REGISTER + PPC_R23:         info->i = ppc.r[23];               break;
2143      case CPUINFO_INT_REGISTER + PPC_R24:         info->i = ppc.r[24];               break;
2144      case CPUINFO_INT_REGISTER + PPC_R25:         info->i = ppc.r[25];               break;
2145      case CPUINFO_INT_REGISTER + PPC_R26:         info->i = ppc.r[26];               break;
2146      case CPUINFO_INT_REGISTER + PPC_R27:         info->i = ppc.r[27];               break;
2147      case CPUINFO_INT_REGISTER + PPC_R28:         info->i = ppc.r[28];               break;
2148      case CPUINFO_INT_REGISTER + PPC_R29:         info->i = ppc.r[29];               break;
2149      case CPUINFO_INT_REGISTER + PPC_R30:         info->i = ppc.r[30];               break;
2150      case CPUINFO_INT_REGISTER + PPC_R31:         info->i = ppc.r[31];               break;
2151
2152      /* --- the following bits of info are returned as pointers to data or functions --- */
2153      case CPUINFO_PTR_GET_CONTEXT:               info->getcontext = ppc_get_context;      break;
2154      case CPUINFO_PTR_SET_CONTEXT:               info->setcontext = ppc_set_context;      break;
2155      case CPUINFO_PTR_BURN:                     info->burn = NULL;                  break;
2156#ifdef ENABLE_DEBUGGER
2157      case CPUINFO_PTR_DISASSEMBLE:               info->disassemble = ppc_dasm;         break;
2158#endif /* ENABLE_DEBUGGER */
2159      case CPUINFO_PTR_INSTRUCTION_COUNTER:         info->icount = &ppc_icount;            break;
2160
2161      /* --- the following bits of info are returned as NULL-terminated strings --- */
2162      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC403");            break;
2163      case CPUINFO_STR_CORE_FAMILY:               strcpy(info->s, "PowerPC");            break;
2164      case CPUINFO_STR_CORE_VERSION:               strcpy(info->s, "1.0");               break;
2165      case CPUINFO_STR_CORE_FILE:                  strcpy(info->s, __FILE__);            break;
2166      case CPUINFO_STR_CORE_CREDITS:               strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team");   break;
2167
2168      case CPUINFO_STR_FLAGS:                     strcpy(info->s, " ");               break;
2169
2170      case CPUINFO_STR_REGISTER + PPC_PC:            sprintf(info->s, "PC: %08X", ppc.pc);   break;
2171      case CPUINFO_STR_REGISTER + PPC_MSR:         sprintf(info->s, "MSR: %08X", ppc_get_msr()); break;
2172      case CPUINFO_STR_REGISTER + PPC_CR:            sprintf(info->s, "CR: %08X", ppc_get_cr()); break;
2173      case CPUINFO_STR_REGISTER + PPC_LR:            sprintf(info->s, "LR: %08X", LR);      break;
2174      case CPUINFO_STR_REGISTER + PPC_CTR:         sprintf(info->s, "CTR: %08X", CTR);      break;
2175      case CPUINFO_STR_REGISTER + PPC_XER:         sprintf(info->s, "XER: %08X", XER);      break;
2176      case CPUINFO_STR_REGISTER + PPC_SRR0:         sprintf(info->s, "SRR0: %08X", SRR0);   break;
2177      case CPUINFO_STR_REGISTER + PPC_SRR1:         sprintf(info->s, "SRR1: %08X", SRR1);   break;
2178
2179      case CPUINFO_STR_REGISTER + PPC_R0:            sprintf(info->s, "R0: %08X", ppc.r[0]); break;
2180      case CPUINFO_STR_REGISTER + PPC_R1:            sprintf(info->s, "R1: %08X", ppc.r[1]); break;
2181      case CPUINFO_STR_REGISTER + PPC_R2:            sprintf(info->s, "R2: %08X", ppc.r[2]); break;
2182      case CPUINFO_STR_REGISTER + PPC_R3:            sprintf(info->s, "R3: %08X", ppc.r[3]); break;
2183      case CPUINFO_STR_REGISTER + PPC_R4:            sprintf(info->s, "R4: %08X", ppc.r[4]); break;
2184      case CPUINFO_STR_REGISTER + PPC_R5:            sprintf(info->s, "R5: %08X", ppc.r[5]); break;
2185      case CPUINFO_STR_REGISTER + PPC_R6:            sprintf(info->s, "R6: %08X", ppc.r[6]); break;
2186      case CPUINFO_STR_REGISTER + PPC_R7:            sprintf(info->s, "R7: %08X", ppc.r[7]); break;
2187      case CPUINFO_STR_REGISTER + PPC_R8:            sprintf(info->s, "R8: %08X", ppc.r[8]); break;
2188      case CPUINFO_STR_REGISTER + PPC_R9:            sprintf(info->s, "R9: %08X", ppc.r[9]); break;
2189      case CPUINFO_STR_REGISTER + PPC_R10:         sprintf(info->s, "R10: %08X", ppc.r[10]); break;
2190      case CPUINFO_STR_REGISTER + PPC_R11:         sprintf(info->s, "R11: %08X", ppc.r[11]); break;
2191      case CPUINFO_STR_REGISTER + PPC_R12:         sprintf(info->s, "R12: %08X", ppc.r[12]); break;
2192      case CPUINFO_STR_REGISTER + PPC_R13:         sprintf(info->s, "R13: %08X", ppc.r[13]); break;
2193      case CPUINFO_STR_REGISTER + PPC_R14:         sprintf(info->s, "R14: %08X", ppc.r[14]); break;
2194      case CPUINFO_STR_REGISTER + PPC_R15:         sprintf(info->s, "R15: %08X", ppc.r[15]); break;
2195      case CPUINFO_STR_REGISTER + PPC_R16:         sprintf(info->s, "R16: %08X", ppc.r[16]); break;
2196      case CPUINFO_STR_REGISTER + PPC_R17:         sprintf(info->s, "R17: %08X", ppc.r[17]); break;
2197      case CPUINFO_STR_REGISTER + PPC_R18:         sprintf(info->s, "R18: %08X", ppc.r[18]); break;
2198      case CPUINFO_STR_REGISTER + PPC_R19:         sprintf(info->s, "R19: %08X", ppc.r[19]); break;
2199      case CPUINFO_STR_REGISTER + PPC_R20:         sprintf(info->s, "R20: %08X", ppc.r[20]); break;
2200      case CPUINFO_STR_REGISTER + PPC_R21:         sprintf(info->s, "R21: %08X", ppc.r[21]); break;
2201      case CPUINFO_STR_REGISTER + PPC_R22:         sprintf(info->s, "R22: %08X", ppc.r[22]); break;
2202      case CPUINFO_STR_REGISTER + PPC_R23:         sprintf(info->s, "R23: %08X", ppc.r[23]); break;
2203      case CPUINFO_STR_REGISTER + PPC_R24:         sprintf(info->s, "R24: %08X", ppc.r[24]); break;
2204      case CPUINFO_STR_REGISTER + PPC_R25:         sprintf(info->s, "R25: %08X", ppc.r[25]); break;
2205      case CPUINFO_STR_REGISTER + PPC_R26:         sprintf(info->s, "R26: %08X", ppc.r[26]); break;
2206      case CPUINFO_STR_REGISTER + PPC_R27:         sprintf(info->s, "R27: %08X", ppc.r[27]); break;
2207      case CPUINFO_STR_REGISTER + PPC_R28:         sprintf(info->s, "R28: %08X", ppc.r[28]); break;
2208      case CPUINFO_STR_REGISTER + PPC_R29:         sprintf(info->s, "R29: %08X", ppc.r[29]); break;
2209      case CPUINFO_STR_REGISTER + PPC_R30:         sprintf(info->s, "R30: %08X", ppc.r[30]); break;
2210      case CPUINFO_STR_REGISTER + PPC_R31:         sprintf(info->s, "R31: %08X", ppc.r[31]); break;
2211   }
2212}
2213
2214
2215
2216/* PowerPC 403 */
2217#if (HAS_PPC403)
2218static void ppc403_set_info(UINT32 state, cpuinfo *info)
2219{
2220   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2221   {
2222      ppcdrc403_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2223      return;
2224   }
2225   switch(state)
2226   {
2227      default:   ppc_set_info(state, info);      break;
2228   }
2229}
2230
2231void ppc403_get_info(UINT32 state, cpuinfo *info)
2232{
2233   switch(state)
2234   {
2235      /* --- the following bits of info are returned as 64-bit signed integers --- */
2236      case CPUINFO_INT_INPUT_LINES:               info->i = 7;                     break;
2237      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2238
2239      /* --- the following bits of info are returned as pointers to data or functions --- */
2240      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc403_set_info;      break;
2241      case CPUINFO_PTR_INIT:                     info->init = ppcdrc403_init;         break;
2242      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc403_reset;         break;
2243      case CPUINFO_PTR_EXIT:                     info->exit = ppcdrc403_exit;         break;
2244      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc403_execute;      break;
2245
2246      /* --- the following bits of info are returned as NULL-terminated strings --- */
2247      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC403");            break;
2248
2249      default:                              ppc_get_info(state, info);            break;
2250   }
2251}
2252#endif
2253
2254/* PowerPC 603 */
2255#if (HAS_PPC603)
2256static void ppc603_set_info(UINT32 state, cpuinfo *info)
2257{
2258   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2259   {
2260      ppcdrc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2261      return;
2262   }
2263   switch(state)
2264   {
2265      case CPUINFO_INT_REGISTER + PPC_DEC:         write_decrementer(info->i);            break;
2266      default:                              ppc_set_info(state, info);            break;
2267   }
2268}
2269
2270void ppc603_get_info(UINT32 state, cpuinfo *info)
2271{
2272   switch(state)
2273   {
2274      /* --- the following bits of info are returned as 64-bit signed integers --- */
2275      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2276      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2277      case CPUINFO_INT_REGISTER + PPC_DEC:         info->i = read_decrementer();         break;
2278
2279      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2280      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2281      case CPUINFO_INT_LOGADDR_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2282      case CPUINFO_INT_PAGE_SHIFT + ADDRESS_SPACE_PROGRAM:    info->i = 17;               break;
2283
2284      /* --- the following bits of info are returned as pointers to data or functions --- */
2285      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc603_set_info;      break;
2286      case CPUINFO_PTR_INIT:                     info->init = ppcdrc603_init;         break;
2287      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc603_reset;         break;
2288      case CPUINFO_PTR_EXIT:                     info->exit = ppcdrc603_exit;         break;
2289      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc603_execute;      break;
2290      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2291      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2292      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
2293      case CPUINFO_PTR_TRANSLATE:                  info->translate = ppc_translate_address_cb;   break;
2294
2295      /* --- the following bits of info are returned as NULL-terminated strings --- */
2296      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC603");            break;
2297      case CPUINFO_STR_REGISTER + PPC_DEC:         sprintf(info->s, "DEC: %08X", read_decrementer()); break;
2298
2299      default:                              ppc_get_info(state, info);            break;
2300   }
2301}
2302#endif
2303
2304/* PowerPC 602 */
2305#if (HAS_PPC602)
2306static void ppc602_set_info(UINT32 state, cpuinfo *info)
2307{
2308   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2309   {
2310      ppcdrc602_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2311      return;
2312   }
2313   switch(state)
2314   {
2315      default:   ppc_set_info(state, info);      break;
2316   }
2317}
2318
2319void ppc602_get_info(UINT32 state, cpuinfo *info)
2320{
2321   switch(state)
2322   {
2323      /* --- the following bits of info are returned as 64-bit signed integers --- */
2324      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2325      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2326
2327      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2328      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2329      case CPUINFO_INT_LOGADDR_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2330      case CPUINFO_INT_PAGE_SHIFT + ADDRESS_SPACE_PROGRAM:    info->i = 17;               break;
2331
2332      /* --- the following bits of info are returned as pointers to data or functions --- */
2333      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc602_set_info;      break;
2334      case CPUINFO_PTR_INIT:                     info->init = ppcdrc602_init;         break;
2335      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc602_reset;         break;
2336      case CPUINFO_PTR_EXIT:                     info->exit = ppcdrc602_exit;         break;
2337      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc602_execute;      break;
2338      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2339      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2340      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
2341      case CPUINFO_PTR_TRANSLATE:                  info->translate = ppc_translate_address_cb;   break;
2342
2343      /* --- the following bits of info are returned as NULL-terminated strings --- */
2344      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC602");            break;
2345
2346      default:                              ppc_get_info(state, info);            break;
2347   }
2348}
2349#endif
2350
2351/* Motorola MPC8240 */
2352
2353#if (HAS_MPC8240)
2354static void mpc8240_set_info(UINT32 state, cpuinfo *info)
2355{
2356   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2357   {
2358      ppcdrc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2359      return;
2360   }
2361   switch(state)
2362   {
2363      default:                              ppc_set_info(state, info);            break;
2364   }
2365}
2366
2367void mpc8240_get_info(UINT32 state, cpuinfo *info)
2368{
2369   switch(state)
2370   {
2371      /* --- the following bits of info are returned as 64-bit signed integers --- */
2372      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2373      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2374
2375      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2376      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2377
2378      /* --- the following bits of info are returned as pointers to data or functions --- */
2379      case CPUINFO_PTR_SET_INFO:                  info->setinfo = mpc8240_set_info;      break;
2380      case CPUINFO_PTR_INIT:                     info->init = mpc8240drc_init;         break;
2381      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc603_reset;         break;
2382      case CPUINFO_PTR_EXIT:                     info->exit = mpc8240drc_exit;         break;
2383      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc603_execute;      break;
2384      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2385      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2386      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
2387
2388      /* --- the following bits of info are returned as NULL-terminated strings --- */
2389      case CPUINFO_STR_NAME:                     strcpy(info->s, "MPC8240");            break;
2390
2391      default:                              ppc_get_info(state, info);            break;
2392   }
2393}
2394#endif
2395
2396
2397/* PPC601 */
2398
2399#if (HAS_PPC601)
2400static void ppc601_set_info(UINT32 state, cpuinfo *info)
2401{
2402   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2403   {
2404      ppcdrc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2405      return;
2406   }
2407   switch(state)
2408   {
2409      default:                              ppc_set_info(state, info);            break;
2410   }
2411}
2412
2413void ppc601_get_info(UINT32 state, cpuinfo *info)
2414{
2415   switch(state)
2416   {
2417      /* --- the following bits of info are returned as 64-bit signed integers --- */
2418      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2419      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2420
2421      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2422      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2423
2424      /* --- the following bits of info are returned as pointers to data or functions --- */
2425      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc601_set_info;      break;
2426      case CPUINFO_PTR_INIT:                     info->init = ppc601drc_init;         break;
2427      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc603_reset;         break;
2428      case CPUINFO_PTR_EXIT:                     info->exit = ppc601drc_exit;         break;
2429      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc603_execute;      break;
2430      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2431      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2432      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
2433
2434      /* --- the following bits of info are returned as NULL-terminated strings --- */
2435      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC601");            break;
2436
2437      default:                              ppc_get_info(state, info);            break;
2438   }
2439}
2440#endif
2441
2442/* PPC604 */
2443
2444#if (HAS_PPC604)
2445static void ppc604_set_info(UINT32 state, cpuinfo *info)
2446{
2447   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2448   {
2449      ppcdrc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2450      return;
2451   }
2452   switch(state)
2453   {
2454      default:                              ppc_set_info(state, info);            break;
2455   }
2456}
2457
2458void ppc604_get_info(UINT32 state, cpuinfo *info)
2459{
2460   switch(state)
2461   {
2462      /* --- the following bits of info are returned as 64-bit signed integers --- */
2463      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2464      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2465
2466      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2467      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2468
2469      /* --- the following bits of info are returned as pointers to data or functions --- */
2470      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc604_set_info;      break;
2471      case CPUINFO_PTR_INIT:                     info->init = ppc604drc_init;         break;
2472      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc603_reset;         break;
2473      case CPUINFO_PTR_EXIT:                     info->exit = ppc604drc_exit;         break;
2474      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc603_execute;      break;
2475      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2476      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2477      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
2478
2479      /* --- the following bits of info are returned as NULL-terminated strings --- */
2480      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC604");            break;
2481
2482      default:                              ppc_get_info(state, info);            break;
2483   }
2484}
2485#endif
src/emu/cpu/powerpc/ppcfe.h
r0r2822
1/***************************************************************************
2
3    ppcfe.h
4
5    Front-end for PowerPC recompiler
6
7    Copyright Aaron Giles
8    Released for general non-commercial use under the MAME license
9    Visit http://mamedev.org for licensing and usage restrictions.
10
11***************************************************************************/
12
13#ifndef __PPCFE_H__
14#define __PPCFE_H__
15
16#include "cpu/drcfe.h"
17
18
19/***************************************************************************
20    CONSTANTS
21***************************************************************************/
22
23/* register flags */
24#define REGFLAG_R(n)               ((UINT64)1 << (n))
25#define REGFLAG_RZ(n)               (((n) == 0) ? 0 : REGFLAG_R(n))
26#define REGFLAG_CR(n)               REGFLAG_R(32 + (n))
27#define REGFLAG_XER                  REGFLAG_R(40)
28#define REGFLAG_CTR                  REGFLAG_R(41)
29#define REGFLAG_LR                  REGFLAG_R(42)
30#define REGFLAG_FPSCR               REGFLAG_R(32)
31
32
33
34/***************************************************************************
35    FUNCTION PROTOTYPES
36***************************************************************************/
37
38int ppcfe_describe(void *param, opcode_desc *desc);
39
40#endif
src/emu/cpu/powerpc/ppc403.c
r2821r2822
434434         ppc.exisr &= ~mask;
435435      }
436436   }
437   else if (irqline == PPC403_SPU_RX)
437   else if (irqline == PPC_IRQ_SPU_RX)
438438   {
439439      UINT32 mask = 0x08000000;
440440      if (state) {
r2821r2822
444444         }
445445      }
446446   }
447   else if (irqline == PPC403_SPU_TX)
447   else if (irqline == PPC_IRQ_SPU_TX)
448448   {
449449      UINT32 mask = 0x04000000;
450450      if (state) {
r2821r2822
454454         }
455455      }
456456   }
457   else if (irqline == PPC403_CRITICAL_IRQ)
457   else if (irqline == PPC_IRQ_CRITICAL)
458458   {
459459      if (state) {
460460         if (EXIER & 0x80000000) {
r2821r2822
661661               ppc.spu.spls = 0x80;
662662
663663#ifndef PPC_DRC
664               ppc403_set_irq_line(PPC403_SPU_RX, ASSERT_LINE);
664               ppc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE);
665665#else
666               ppcdrc403_set_irq_line(PPC403_SPU_RX, ASSERT_LINE);
666               ppcdrc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE);
667667#endif
668668            }
669669         }
r2821r2822
698698   /* generate interrupt if DMA is disabled and RBR interrupt is enabled */
699699   if (((ppc.spu.sprc >> 5) & 0x3) == 0x01) {
700700#ifndef PPC_DRC
701      ppc403_set_irq_line(PPC403_SPU_RX, ASSERT_LINE);
701      ppc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE);
702702#else
703      ppcdrc403_set_irq_line(PPC403_SPU_RX, ASSERT_LINE);
703      ppcdrc403_set_irq_line(PPC_IRQ_SPU_RX, ASSERT_LINE);
704704#endif
705705   }
706706}
r2821r2822
722722      /* generate interrupt if DMA is disabled and TBR interrupt is enabled */
723723      if (((ppc.spu.sptc >> 5) & 0x3) == 0x01) {
724724#ifndef PPC_DRC
725         ppc403_set_irq_line(PPC403_SPU_TX, ASSERT_LINE);
725         ppc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE);
726726#else
727         ppcdrc403_set_irq_line(PPC403_SPU_TX, ASSERT_LINE);
727         ppcdrc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE);
728728#endif
729729      }
730730   }
r2821r2822
826826                  }
827827
828828#ifndef PPC_DRC
829                  ppc403_set_irq_line(PPC403_SPU_TX, ASSERT_LINE);
829                  ppc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE);
830830#else
831                  ppcdrc403_set_irq_line(PPC403_SPU_TX, ASSERT_LINE);
831                  ppcdrc403_set_irq_line(PPC_IRQ_SPU_TX, ASSERT_LINE);
832832#endif
833833               }
834834               else {
src/emu/cpu/powerpc/ppcdrc.c
r2821r2822
1/*
2    PowerPC 4xx/6xx Dynamic Recompiler for x86
1/***************************************************************************
32
4    Written by Ville Linde
5*/
3    ppcdrc.c
64
5    Universal machine language-based PowerPC emulator.
6
7    Copyright Aaron Giles
8    Released for general non-commercial use under the MAME license
9    Visit http://mamedev.org for licensing and usage restrictions.
10
11****************************************************************************
12
13    Future improvements/changes:
14
15    * Timing for long instructions (stmw/lmw/mul/div/stswi)
16
17    * Eliminate unnecessary flag calculations using information from the
18        frontend
19
20***************************************************************************/
21
22#include <stddef.h>
23#include "cpuintrf.h"
724#include "debugger.h"
8#include "ppc.h"
9#include "cpu/x86drc.h"
25#include "ppccom.h"
26#include "ppcfe.h"
27#include "deprecat.h"
28#include "cpu/drcfe.h"
29#include "cpu/drcuml.h"
30#include "cpu/drcumlsh.h"
1031
32extern offs_t ppc_dasm_one(char *buffer, UINT32 pc, UINT32 op);
1133
12#define PPC_DRC
13#define LOG_CODE         (0)
1434
15#define CACHE_SIZE         (16 * 1024 * 1024)
16#define MAX_INSTRUCTIONS   512
1735
36/***************************************************************************
37    DEBUGGING
38***************************************************************************/
1839
19#if (HAS_PPC603)
20static void ppcdrc603_init(int index, int clock, const void *_config, int (*irqcallback)(int));
21static void ppcdrc603_exit(void);
22#endif
23#if (HAS_PPC601 || HAS_PPC603 || HAS_MPC8240 || HAS_PPC604)
24static void ppcdrc603_reset(void);
25static int ppcdrc603_execute(int cycles);
26static void ppcdrc603_set_irq_line(int irqline, int state);
27#endif
28#if (HAS_PPC602)
29static void ppcdrc602_init(int index, int clock, const void *_config, int (*irqcallback)(int));
30static void ppcdrc602_exit(void);
31static void ppcdrc602_reset(void);
32static int ppcdrc602_execute(int cycles);
33static void ppcdrc602_set_irq_line(int irqline, int state);
34#endif
35#if (HAS_PPC403)
36static UINT8 ppc403_spu_r(UINT32 a);
37static void ppc403_spu_w(UINT32 a, UINT8 d);
38static void ppcdrc403_init(int index, int clock, const void *_config, int (*irqcallback)(int));
39static void ppcdrc403_exit(void);
40static void ppcdrc403_reset(void);
41static int ppcdrc403_execute(int cycles);
42static void ppcdrc403_set_irq_line(int irqline, int state);
43#endif
40#define FORCE_C_BACKEND               (0)
41#define LOG_UML                     (0)
42#define LOG_NATIVE                  (0)
4443
45static void ppcdrc_init(void);
46static void ppcdrc_reset(drc_core *drc);
47static void ppcdrc_recompile(drc_core *drc);
48static void ppcdrc_entrygen(drc_core *drc);
44#define DISABLE_FAST_REGISTERS         (0)
45#define SINGLE_INSTRUCTION_MODE         (0)
4946
50#define RD            ((op >> 21) & 0x1F)
51#define RT            ((op >> 21) & 0x1f)
52#define RS            ((op >> 21) & 0x1f)
53#define RA            ((op >> 16) & 0x1f)
54#define RB            ((op >> 11) & 0x1f)
55#define RC            ((op >> 6) & 0x1f)
47#define PRINTF_EXCEPTIONS            (0)
48#define PRINTF_MMU                  (0)
5649
57#define MB            ((op >> 6) & 0x1f)
58#define ME            ((op >> 1) & 0x1f)
59#define SH            ((op >> 11) & 0x1f)
60#define BO            ((op >> 21) & 0x1f)
61#define BI            ((op >> 16) & 0x1f)
62#define CRFD         ((op >> 23) & 0x7)
63#define CRFA         ((op >> 18) & 0x7)
64#define FXM            ((op >> 12) & 0xff)
65#define SPR            (((op >> 16) & 0x1f) | ((op >> 6) & 0x3e0))
50#define PROBE_ADDRESS               ~0
6651
67#define SIMM16         (INT32)(INT16)(op & 0xffff)
68#define UIMM16         (UINT32)(op & 0xffff)
6952
70#define RCBIT         (op & 0x1)
71#define OEBIT         (op & 0x400)
72#define AABIT         (op & 0x2)
73#define LKBIT         (op & 0x1)
7453
75#define REG(x)         (ppc.r[x])
76#define LR            (ppc.lr)
77#define CTR            (ppc.ctr)
78#define XER            (ppc.xer)
79#define CR(x)         (ppc.cr[x])
80#define MSR            (ppc.msr)
81#define SRR0         (ppc.srr0)
82#define SRR1         (ppc.srr1)
83#define SRR2         (ppc.srr2)
84#define SRR3         (ppc.srr3)
85#define EVPR         (ppc.evpr)
86#define EXIER         (ppc.exier)
87#define EXISR         (ppc.exisr)
88#define DEC            (ppc.dec)
54/***************************************************************************
55    CONSTANTS
56***************************************************************************/
8957
58/* map variables */
59#define MAPVAR_PC                  MVAR(0)
60#define MAPVAR_CYCLES               MVAR(1)
61#define MAPVAR_DSISR               MVAR(2)
9062
91// Stuff added for the 6xx
92#define FPR(x)         (ppc.fpr[x])
93#define FM            ((op >> 17) & 0xFF)
94#define SPRF         (((op >> 6) & 0x3E0) | ((op >> 16) & 0x1F))
63/* mode bits */
64#define MODE_LITTLE_ENDIAN            0x01
65#define MODE_DATA_TRANSLATION         0x02
66#define MODE_USER                  0x04
9567
68/* size of the execution code cache */
69#define CACHE_SIZE                  (32 * 1024 * 1024)
9670
97#define CHECK_SUPERVISOR()         \
98   if((ppc.msr & 0x4000) != 0){   \
99   }
71/* compilation boundaries -- how far back/forward does the analysis extend? */
72#define COMPILE_BACKWARDS_BYTES         128
73#define COMPILE_FORWARDS_BYTES         512
74#define COMPILE_MAX_INSTRUCTIONS      ((COMPILE_BACKWARDS_BYTES/4) + (COMPILE_FORWARDS_BYTES/4))
75#define COMPILE_MAX_SEQUENCE         64
10076
101#define CHECK_FPU_AVAILABLE()      \
102   if((ppc.msr & 0x2000) == 0){   \
103   }
77/* exit codes */
78#define EXECUTE_OUT_OF_CYCLES         0
79#define EXECUTE_MISSING_CODE         1
80#define EXECUTE_UNMAPPED_CODE         2
81#define EXECUTE_RESET_CACHE            3
10482
105#if (HAS_PPC601||HAS_PPC602||HAS_PPC603||HAS_PPC604||HAS_MPC8240)
106static UINT32      ppc_field_xlat[256];
107#endif
10883
10984
85/***************************************************************************
86    MACROS
87***************************************************************************/
11088
111#define FPSCR_FX      0x80000000
112#define FPSCR_FEX      0x40000000
113#define FPSCR_VX      0x20000000
114#define FPSCR_OX      0x10000000
115#define FPSCR_UX      0x08000000
116#define FPSCR_ZX      0x04000000
117#define FPSCR_XX      0x02000000
89#define R32(reg)            ppc->impstate->regmap[reg].type, ppc->impstate->regmap[reg].value
90#define R32Z(reg)            (((reg) == 0) ? DRCUML_PTYPE_IMMEDIATE : ppc->impstate->regmap[reg].type), (((reg) == 0) ? 0 : ppc->impstate->regmap[reg].value)
91#define F64(reg)            ppc->impstate->fdregmap[reg].type, ppc->impstate->fdregmap[reg].value
92#define CR32               MEM(&ppc->cr)
93#define FPSCR32               MEM(&ppc->fpscr)
94#define MSR32               MEM(&ppc->msr)
95#define SR32(reg)            MEM(&ppc->sr[reg])
96#define SPR32(reg)            MEM(&ppc->spr[reg])
11897
98#define CRMASK(reg)            (0xf0000000 >> ((reg) * 4))
11999
100#define FLAGS_RC(op)         ((op & M_RC) ? (DRCUML_FLAG_S | DRCUML_FLAG_Z) : 0)
101#define FLAGS_OE(op)         ((op & M_OE) ? DRCUML_FLAG_V : 0)
102#define FLAGS_RCOE(op)         (FLAGS_RC(op) | FLAGS_OE(op))
103#define FLAGS_RCOECA(op)      (FLAGS_RCOE(op) | DRCUML_FLAG_C)
120104
121#define BITMASK_0(n)   (UINT32)(((UINT64)1 << n) - 1)
122#define CRBIT(x)      ((ppc.cr[x / 4] & (1 << (3 - (x % 4)))) ? 1 : 0)
123#define _BIT(n)         (1 << (n))
124#define GET_ROTATE_MASK(mb,me)      (ppc_rotate_mask[mb][me])
125#define ADD_CA(r,a,b)      ((UINT32)r < (UINT32)a)
126#define SUB_CA(r,a,b)      (!((UINT32)a < (UINT32)b))
127#define ADD_OV(r,a,b)      ((~((a) ^ (b)) & ((a) ^ (r))) & 0x80000000)
128#define SUB_OV(r,a,b)      (( ((a) ^ (b)) & ((a) ^ (r))) & 0x80000000)
105/* DSISR values for various addressing types */
106#define DSISR_IMM(op)   ((0) |                              /* bits 15-16: cleared */         \
107                   ((((op) >> (31- 5)) & 0x01) << (31-17)) |   /* bit  17:    opcode bit 5 */      \
108                   ((((op) >> (31- 4)) & 0x0f) << (31-21)) |    /* bits 18-21: opcode bits 1-4 */   \
109                   ((((op) >> (31-10)) & 0x1f) << (31-26)) |   /* bits 22-26: opcode bits 6-10 */   \
110                   (0))                              /* bits 27-31: undefined */
129111
130#define XER_SO         0x80000000
131#define XER_OV         0x40000000
132#define XER_CA         0x20000000
112#define DSISR_IMMU(op)   ((0) |                              /* bits 15-16: cleared */         \
113                   ((((op) >> (31- 5)) & 0x01) << (31-17)) |   /* bit  17:    opcode bit 5 */      \
114                   ((((op) >> (31- 4)) & 0x0f) << (31-21)) |    /* bits 18-21: opcode bits 1-4 */   \
115                   ((((op) >> (31-10)) & 0x1f) << (31-26)) |   /* bits 22-26: opcode bits 6-10 */   \
116                   ((((op) >> (31-15)) & 0x1f) << (31-31)))   /* bits 27-31: opcode bits 11-15 */
133117
134#define MSR_AP         0x00800000   /* Access privilege state (PPC602) */
135#define MSR_SA         0x00400000   /* Supervisor access mode (PPC602) */
136#define MSR_POW         0x00040000   /* Power Management Enable */
137#define MSR_WE         0x00040000
138#define MSR_CE         0x00020000
139#define MSR_ILE         0x00010000   /* Interrupt Little Endian Mode */
140#define MSR_EE         0x00008000   /* External Interrupt Enable */
141#define MSR_PR         0x00004000   /* Problem State */
142#define MSR_FP         0x00002000   /* Floating Point Available */
143#define MSR_ME         0x00001000   /* Machine Check Enable */
144#define MSR_FE0         0x00000800
145#define MSR_SE         0x00000400   /* Single Step Trace Enable */
146#define MSR_BE         0x00000200   /* Branch Trace Enable */
147#define MSR_DE         0x00000200
148#define MSR_FE1         0x00000100
149#define MSR_IP         0x00000040   /* Interrupt Prefix */
150#define MSR_IR         0x00000020   /* Instruction Relocate */
151#define MSR_DR         0x00000010   /* Data Relocate */
152#define MSR_PE         0x00000008
153#define MSR_PX         0x00000004
154#define MSR_RI         0x00000002   /* Recoverable Interrupt Enable */
155#define MSR_LE         0x00000001
118#define DSISR_IDX(op)   (((((op) >> (31-30)) & 0x03) << (31-16)) |   /* bits 15-16: opcode bits 29-30 */   \
119                   ((((op) >> (31-25)) & 0x01) << (31-17)) |   /* bit  17:    opcode bit 25 */      \
120                   ((((op) >> (31-24)) & 0x0f) << (31-21)) |    /* bits 18-21: opcode bits 21-24 */   \
121                   ((((op) >> (31-10)) & 0x1f) << (31-26)) |   /* bits 22-26: opcode bits 6-10 */   \
122                   (0))                              /* bits 27-31: undefined */
156123
157#define TSR_ENW         0x80000000
158#define TSR_WIS         0x40000000
124#define DSISR_IDXU(op)   (((((op) >> (31-30)) & 0x03) << (31-16)) |   /* bits 15-16: opcode bits 29-30 */   \
125                   ((((op) >> (31-25)) & 0x01) << (31-17)) |   /* bit  17:    opcode bit 25 */      \
126                   ((((op) >> (31-24)) & 0x0f) << (31-21)) |    /* bits 18-21: opcode bits 21-24 */   \
127                   ((((op) >> (31-10)) & 0x1f) << (31-26)) |   /* bits 22-26: opcode bits 6-10 */   \
128                   ((((op) >> (31-15)) & 0x1f) << (31-31)))   /* bits 27-31: opcode bits 11-15 */
159129
160#define BYTE_REVERSE16(x)   ((((x) >> 8) & 0xff) | (((x) << 8) & 0xff00))
161#define BYTE_REVERSE32(x)   ((((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000))
162130
163typedef struct {
164   UINT32 cr;
165   UINT32 da;
166   UINT32 sa;
167   UINT32 ct;
168   UINT32 cc;
169} DMA_REGS;
170131
171typedef struct {
172   UINT8 spls;
173   UINT8 sphs;
174   UINT16 brd;
175   UINT8 spctl;
176   UINT8 sprc;
177   UINT8 sptc;
178   UINT8 sprb;
179   UINT8 sptb;
180   emu_timer *rx_timer;
181   emu_timer *tx_timer;
182} SPU_REGS;
132/***************************************************************************
133    STRUCTURES & TYPEDEFS
134***************************************************************************/
183135
184typedef union {
185   UINT64   id;
186   double   fd;
187} FPR;
136/* fast RAM info */
137typedef struct _fast_ram_info fast_ram_info;
138struct _fast_ram_info
139{
140   offs_t            start;                  /* start of the RAM block */
141   offs_t            end;                  /* end of the RAM block */
142   UINT8            readonly;               /* TRUE if read-only */
143   void *            base;                  /* base in memory where the RAM lives */
144};
188145
189typedef union {
190   UINT32 i;
191   float f;
192} FPR32;
193146
194typedef struct {
195   UINT32 u;
196   UINT32 l;
197} BATENT;
147/* hotspot info */
148typedef struct _hotspot_info hotspot_info;
149struct _hotspot_info
150{
151   offs_t            pc;                     /* PC to consider */
152   UINT32            opcode;                  /* required opcode at that PC */
153   UINT32            cycles;                  /* number of cycles to eat when hit */
154};
198155
199156
200typedef struct {
201   UINT32 r[32];
202   UINT32 pc;
203   UINT32 npc;
157/* internal compiler state */
158typedef struct _compiler_state compiler_state;
159struct _compiler_state
160{
161   UINT32            cycles;                  /* accumulated cycles */
162   UINT8            checkints;               /* need to check interrupts before next instruction */
163   UINT8            checksoftints;            /* need to check software interrupts before next instruction */
164   drcuml_codelabel   labelnum;               /* index for local labels */
165};
204166
205   UINT32 lr;
206   UINT32 ctr;
207   UINT32 xer;
208   UINT32 msr;
209   UINT8 cr[8];
210   UINT32 pvr;
211   UINT32 srr0;
212   UINT32 srr1;
213   UINT32 srr2;
214   UINT32 srr3;
215   UINT32 hid0;
216   UINT32 hid1;
217   UINT32 hid2;
218   UINT32 sdr1;
219   UINT32 sprg[4];
220167
221   UINT32 dsisr;
222   UINT32 dar;
223   UINT32 ear;
224   UINT32 dmiss;
225   UINT32 dcmp;
226   UINT32 hash1;
227   UINT32 hash2;
228   UINT32 imiss;
229   UINT32 icmp;
230   UINT32 rpa;
168/* PowerPC implementation state */
169struct _ppcimp_state
170{
171   /* core state */
172   drccache *         cache;                  /* pointer to the DRC code cache */
173   drcuml_state *      drcuml;                  /* DRC UML generator state */
174   drcfe_state *      drcfe;                  /* pointer to the DRC front-end state */
175   UINT32            drcoptions;               /* configurable DRC options */
231176
232   BATENT ibat[4];
233   BATENT dbat[4];
177   /* parameters for subroutines */
178   UINT64            numcycles;               /* return value from gettotalcycles */
179   UINT32            mode;                  /* current global mode */
180   UINT32            arg0;                  /* print_debug argument 1 */
181   UINT32            arg1;                  /* print_debug argument 2 */
182   UINT32            updateaddr;               /* update address storage */
183   UINT32            swcount;               /* counter for sw instructions */
184   UINT32            swreg;                  /* reg index for sw instructions */
185   UINT32            tempaddr;               /* temporary address storage */
186   UINT64            tempdata;               /* temporary data storage */
187   double            fp0;                  /* floating point 0 */
234188
235   UINT32 evpr;
236   UINT32 exier;
237   UINT32 exisr;
238   UINT32 bear;
239   UINT32 besr;
240   UINT32 iocr;
241   UINT32 br[8];
242   UINT32 iabr;
243   UINT32 esr;
244   UINT32 iccr;
245   UINT32 dccr;
246   UINT32 pit;
247   UINT32 tsr;
248   UINT32 tcr;
249   UINT32 dbsr;
250   UINT32 sgr;
251   UINT32 pid;
252   UINT32 pbl1, pbl2, pbu1, pbu2;
253   UINT32 fit_bit;
254   UINT32 fit_int_enable;
255   UINT32 wdt_bit;
256   UINT32 wdt_int_enable;
257   UINT32 dac1, dac2;
258   UINT32 iac1, iac2;
189   /* tables */
190   UINT8            fpmode[4];               /* FPU mode table */
191   UINT32            sz_cr_table[32];         /* SZ CR table */
192   UINT32            cmp_cr_table[32];         /* CMP CR table */
193   UINT32            cmpl_cr_table[32];         /* CMPL CR table */
194   UINT32            fcmp_cr_table[32];         /* FCMP CR table */
259195
260   SPU_REGS spu;
261   DMA_REGS dma[4];
262   UINT32 dmasr;
196   /* internal stuff */
197   UINT8            cache_dirty;            /* true if we need to flush the cache */
263198
264   int reserved;
265   UINT32 reserved_address;
199   /* register mappings */
200   drcuml_parameter   regmap[32];               /* parameter to register mappings for all 32 integer registers */
201   drcuml_parameter   fsregmap[32];            /* parameter to register mappings for all 32 floating point registers */
202   drcuml_parameter   fdregmap[32];            /* parameter to register mappings for all 32 floating point registers */
266203
267   int exception_pending;
204   /* subroutines */
205   drcuml_codehandle *   entry;                  /* entry point */
206   drcuml_codehandle *   nocode;                  /* nocode exception handler */
207   drcuml_codehandle *   out_of_cycles;            /* out of cycles exception handler */
208   drcuml_codehandle *   tlb_mismatch;            /* tlb mismatch handler */
209   drcuml_codehandle *   swap_tgpr;               /* swap TGPR handler */
210   drcuml_codehandle *   read8[4];               /* read byte */
211   drcuml_codehandle *   write8[4];               /* write byte */
212   drcuml_codehandle *   read16[4];               /* read half */
213   drcuml_codehandle *   read16mask[4];            /* read half */
214   drcuml_codehandle *   write16[4];               /* write half */
215   drcuml_codehandle *   write16mask[4];            /* write half */
216   drcuml_codehandle *   read32[4];               /* read word */
217   drcuml_codehandle *   read32align[4];            /* read word aligned */
218   drcuml_codehandle *   read32mask[4];            /* read word */
219   drcuml_codehandle *   write32[4];               /* write word */
220   drcuml_codehandle *   write32align[4];         /* write word aligned */
221   drcuml_codehandle *   write32mask[4];            /* write word */
222   drcuml_codehandle *   read64[4];               /* read double */
223   drcuml_codehandle *   read64mask[4];            /* read double */
224   drcuml_codehandle *   write64[4];               /* write double */
225   drcuml_codehandle *   write64mask[4];            /* write double */
226   drcuml_codehandle *   exception[EXCEPTION_COUNT];   /* array of exception handlers */
227   drcuml_codehandle *   exception_norecover[EXCEPTION_COUNT];   /* array of exception handlers */
268228
269   UINT64 tb;         /* 56-bit timebase register */
229   /* fast RAM */
230   UINT32            fastram_select;
231   fast_ram_info      fastram[PPC_MAX_FASTRAM];
270232
271   int (*irq_callback)(int irqline);
272   drc_core *drc;
273   UINT32 drcoptions;
233   /* hotspots */
234   UINT32            hotspot_select;
235   hotspot_info      hotspot[PPC_MAX_HOTSPOTS];
236};
274237
275   x86code *      invoke_exception_handler;
276   x86code *      generate_interrupt_exception;
277   x86code *      generate_syscall_exception;
278   x86code *      generate_decrementer_exception;
279   x86code *      generate_trap_exception;
280   x86code *      generate_dsi_exception;
281   x86code *      generate_isi_exception;
282   x86code *      generate_fit_exception;
283238
284   // PowerPC 60x specific registers */
285   UINT32 dec, dec_frac;
286   UINT32 fpscr;
287239
288   FPR   fpr[32];
289   UINT32 sr[16];
240/***************************************************************************
241    FUNCTION PROTOTYPES
242***************************************************************************/
290243
291   int is603;
292   int is602;
244static void code_flush_cache(drcuml_state *drcuml);
245static void code_compile_block(drcuml_state *drcuml, UINT8 mode, offs_t pc);
293246
294   /* PowerPC 602 specific registers */
295   UINT32 lt;
296   UINT32 sp;
297   UINT32 ibr;
298   UINT32 esasrr;
299   UINT32 sebr;
300   UINT32 ser;
247static void cfunc_printf_exception(void *param);
248static void cfunc_printf_probe(void *param);
301249
302   /* PowerPC function pointers for memory accesses/exceptions */
303   UINT8 (*read8)(offs_t address);
304   UINT16 (*read16)(offs_t address);
305   UINT32 (*read32)(offs_t address);
306   UINT64 (*read64)(offs_t address);
307   void (*write8)(offs_t address, UINT8 data);
308   void (*write16)(offs_t address, UINT16 data);
309   void (*write32)(offs_t address, UINT32 data);
310   void (*write64)(offs_t address, UINT64 data);
311   UINT16 (*read16_unaligned)(offs_t address);
312   UINT32 (*read32_unaligned)(offs_t address);
313   UINT64 (*read64_unaligned)(offs_t address);
314   void (*write16_unaligned)(offs_t address, UINT16 data);
315   void (*write32_unaligned)(offs_t address, UINT32 data);
316   void (*write64_unaligned)(offs_t address, UINT64 data);
250static void static_generate_entry_point(drcuml_state *drcuml);
251static void static_generate_nocode_handler(drcuml_state *drcuml);
252static void static_generate_out_of_cycles(drcuml_state *drcuml);
253static void static_generate_tlb_mismatch(drcuml_state *drcuml);
254static void static_generate_exception(drcuml_state *drcuml, UINT8 exception, int recover, const char *name);
255static void static_generate_memory_accessor(drcuml_state *drcuml, int mode, int size, int iswrite, int ismasked, const char *name, drcuml_codehandle **handleptr, drcuml_codehandle *masked);
256static void static_generate_swap_tgpr(drcuml_state *drcuml);
317257
318   /* saved ESP when entering entry point */
319   UINT32 host_esp;
258static void generate_update_mode(drcuml_block *block);
259static void generate_update_cycles(drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception);
260static void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast);
261static void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
262static int generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
263static int generate_instruction_13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
264static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
265static int generate_instruction_3b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
266static int generate_instruction_3f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
320267
321   UINT32 (* optable19[1024])(drc_core *, UINT32);
322   UINT32 (* optable31[1024])(drc_core *, UINT32);
323   UINT32 (* optable59[1024])(drc_core *, UINT32);
324   UINT32 (* optable63[1024])(drc_core *, UINT32);
325   UINT32 (* optable[64])(drc_core *, UINT32);
326} PPC_REGS;
268static void log_add_disasm_comment(drcuml_block *block, UINT32 pc, UINT32 op);
269static const char *log_desc_flags_to_string(UINT32 flags);
270static void log_register_list(drcuml_state *drcuml, const char *string, UINT64 gprmask, UINT64 fprmask);
271static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent);
327272
328273
329274
330typedef struct {
331   int code;
332   int subcode;
333   UINT32 (* handler)(drc_core *, UINT32);
334} PPC_OPCODE;
275/***************************************************************************
276    PRIVATE GLOBAL VARIABLES
277***************************************************************************/
335278
279static powerpc_state *ppc;
336280
337/* code logging info */
338typedef struct _code_log_entry code_log_entry;
339struct _code_log_entry
281
282/* lookup table for FP modes */
283static const UINT8 fpmode_source[4] =
340284{
341   UINT32      pc;
342   UINT32      op;
343   void *      base;
285   DRCUML_FMOD_ROUND,
286   DRCUML_FMOD_TRUNC,
287   DRCUML_FMOD_CEIL,
288   DRCUML_FMOD_FLOOR
344289};
345290
291/* flag lookup table for SZ */
292static const UINT32 sz_cr_table_source[32] =
293{
294   /* ..... */   0x40000000,
295   /* ....C */   0x42000000,
296   /* ...V. */   0x4c000000,
297   /* ...VC */   0x4e000000,
298   /* ..Z.. */   0x20000000,
299   /* ..Z.C */   0x22000000,
300   /* ..ZV. */   0x2c000000,
301   /* ..ZVC */   0x2e000000,
302   /* .S... */   0x80000000,
303   /* .S..C */   0x82000000,
304   /* .S.V. */   0x8c000000,
305   /* .S.VC */   0x8e000000,
306   /* .SZ.. */   0x20000000,
307   /* .SZ.C */   0x22000000,
308   /* .SZV. */   0x2c000000,
309   /* .SZVC */   0x2e000000,
310   /* U.... */   0x40000000,
311   /* U...C */   0x42000000,
312   /* U..V. */   0x4c000000,
313   /* U..VC */   0x4e000000,
314   /* U.Z.. */   0x20000000,
315   /* U.Z.C */   0x22000000,
316   /* U.ZV. */   0x2c000000,
317   /* U.ZVC */   0x2e000000,
318   /* US... */   0x80000000,
319   /* US..C */   0x82000000,
320   /* US.V. */   0x8c000000,
321   /* US.VC */   0x8e000000,
322   /* USZ.. */   0x20000000,
323   /* USZ.C */   0x22000000,
324   /* USZV. */   0x2c000000,
325   /* USZVC */   0x2e000000
326};
346327
328/* flag lookup table for CMP */
329static const UINT32 cmp_cr_table_source[32] =
330{
331   /* ..... */   0x44444444,
332   /* ....C */   0x44444444,
333   /* ...V. */   0x88888888,
334   /* ...VC */   0x88888888,
335   /* ..Z.. */   0x22222222,
336   /* ..Z.C */   0x22222222,
337   /* ..ZV. */   0x22222222,
338   /* ..ZVC */   0x22222222,
339   /* .S... */   0x88888888,
340   /* .S..C */   0x88888888,
341   /* .S.V. */   0x44444444,
342   /* .S.VC */   0x44444444,
343   /* .SZ.. */   0x22222222,
344   /* .SZ.C */   0x22222222,
345   /* .SZV. */   0x22222222,
346   /* .SZVC */   0x22222222,
347   /* U.... */   0x44444444,
348   /* U...C */   0x44444444,
349   /* U..V. */   0x88888888,
350   /* U..VC */   0x88888888,
351   /* U.Z.. */   0x22222222,
352   /* U.Z.C */   0x22222222,
353   /* U.ZV. */   0x22222222,
354   /* U.ZVC */   0x22222222,
355   /* US... */   0x88888888,
356   /* US..C */   0x88888888,
357   /* US.V. */   0x44444444,
358   /* US.VC */   0x44444444,
359   /* USZ.. */   0x22222222,
360   /* USZ.C */   0x22222222,
361   /* USZV. */   0x22222222,
362   /* USZVC */   0x22222222
363};
347364
348static int ppc_icount;
349static int ppc_tb_base_icount;
350static int ppc_dec_base_icount;
351static int ppc_dec_trigger_cycle;
352static int bus_freq_multiplier = 1;
353static int ppc_fit_trigger_cycle;
354static PPC_REGS ppc;
355static UINT32 ppc_rotate_mask[32][32];
365/* flag lookup table for CMPL */
366static const UINT32 cmpl_cr_table_source[32] =
367{
368   /* ..... */   0x44444444,
369   /* ....C */   0x88888888,
370   /* ...V. */   0x44444444,
371   /* ...VC */   0x88888888,
372   /* ..Z.. */   0x22222222,
373   /* ..Z.C */   0x22222222,
374   /* ..ZV. */   0x22222222,
375   /* ..ZVC */   0x22222222,
376   /* .S... */   0x44444444,
377   /* .S..C */   0x88888888,
378   /* .S.V. */   0x44444444,
379   /* .S.VC */   0x88888888,
380   /* .SZ.. */   0x22222222,
381   /* .SZ.C */   0x22222222,
382   /* .SZV. */   0x22222222,
383   /* .SZVC */   0x22222222,
384   /* U.... */   0x44444444,
385   /* U...C */   0x88888888,
386   /* U..V. */   0x44444444,
387   /* U..VC */   0x88888888,
388   /* U.Z.. */   0x22222222,
389   /* U.Z.C */   0x22222222,
390   /* U.ZV. */   0x22222222,
391   /* U.ZVC */   0x22222222,
392   /* US... */   0x44444444,
393   /* US..C */   0x88888888,
394   /* US.V. */   0x44444444,
395   /* US.VC */   0x88888888,
396   /* USZ.. */   0x22222222,
397   /* USZ.C */   0x22222222,
398   /* USZV. */   0x22222222,
399   /* USZVC */   0x22222222
400};
356401
357#define ROPCODE(pc)         cpu_readop32(pc)
358#define ROPCODE64(pc)      cpu_readop64(DWORD_XOR_BE(pc))
359
360INLINE void SET_CR0(INT32 rd)
402/* flag lookup table for FCMP */
403static const UINT32 fcmp_cr_table_source[32] =
361404{
362   if( rd < 0 ) {
363      CR(0) = 0x8;
364   } else if( rd > 0 ) {
365      CR(0) = 0x4;
366   } else {
367      CR(0) = 0x2;
368   }
405   /* ..... */   0x44444444,
406   /* ....C */   0x88888888,
407   /* ...V. */   0x44444444,
408   /* ...VC */   0x88888888,
409   /* ..Z.. */   0x22222222,
410   /* ..Z.C */   0xaaaaaaaa,
411   /* ..ZV. */   0x22222222,
412   /* ..ZVC */   0xaaaaaaaa,
413   /* .S... */   0x44444444,
414   /* .S..C */   0x88888888,
415   /* .S.V. */   0x44444444,
416   /* .S.VC */   0x88888888,
417   /* .SZ.. */   0x22222222,
418   /* .SZ.C */   0xaaaaaaaa,
419   /* .SZV. */   0x22222222,
420   /* .SZVC */   0xaaaaaaaa,
421   /* U.... */   0x55555555,
422   /* U...C */   0x99999999,
423   /* U..V. */   0x55555555,
424   /* U..VC */   0x99999999,
425   /* U.Z.. */   0x33333333,
426   /* U.Z.C */   0xbbbbbbbb,
427   /* U.ZV. */   0x33333333,
428   /* U.ZVC */   0xbbbbbbbb,
429   /* US... */   0x55555555,
430   /* US..C */   0x99999999,
431   /* US.V. */   0x55555555,
432   /* US.VC */   0x99999999,
433   /* USZ.. */   0x33333333,
434   /* USZ.C */   0xbbbbbbbb,
435   /* USZV. */   0x33333333,
436   /* USZVC */   0xbbbbbbbb
437};
369438
370   if( XER & XER_SO )
371      CR(0) |= 0x1;
372}
373439
374INLINE void SET_CR1(void)
440
441/***************************************************************************
442    INLINE FUNCTIONS
443***************************************************************************/
444
445/*-------------------------------------------------
446    alloc_handle - allocate a handle if not
447    already allocated
448-------------------------------------------------*/
449
450INLINE void alloc_handle(drcuml_state *drcuml, drcuml_codehandle **handleptr, const char *name)
375451{
376   CR(1) = (ppc.fpscr >> 28) & 0xf;
452   if (*handleptr == NULL)
453      *handleptr = drcuml_handle_alloc(drcuml, name);
377454}
378455
379INLINE void SET_ADD_OV(UINT32 rd, UINT32 ra, UINT32 rb)
456
457/*-------------------------------------------------
458    load_fast_iregs - load any fast integer
459    registers
460-------------------------------------------------*/
461
462INLINE void load_fast_iregs(drcuml_block *block)
380463{
381   if( ADD_OV(rd, ra, rb) )
382      XER |= XER_SO | XER_OV;
383   else
384      XER &= ~XER_OV;
464   int regnum;
465
466   for (regnum = 0; regnum < ARRAY_LENGTH(ppc->impstate->regmap); regnum++)
467      if (ppc->impstate->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER)
468         UML_MOV(block, IREG(ppc->impstate->regmap[regnum].value - DRCUML_REG_I0), MEM(&ppc->r[regnum]));
385469}
386470
387INLINE void SET_SUB_OV(UINT32 rd, UINT32 ra, UINT32 rb)
471
472/*-------------------------------------------------
473    save_fast_iregs - save any fast integer
474    registers
475-------------------------------------------------*/
476
477INLINE void save_fast_iregs(drcuml_block *block)
388478{
389   if( SUB_OV(rd, ra, rb) )
390      XER |= XER_SO | XER_OV;
391   else
392      XER &= ~XER_OV;
479   int regnum;
480
481   for (regnum = 0; regnum < ARRAY_LENGTH(ppc->impstate->regmap); regnum++)
482      if (ppc->impstate->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER)
483         UML_MOV(block, MEM(&ppc->r[regnum]), IREG(ppc->impstate->regmap[regnum].value - DRCUML_REG_I0));
393484}
394485
395INLINE void SET_ADD_CA(UINT32 rd, UINT32 ra, UINT32 rb)
486
487/*-------------------------------------------------
488    compute_rlw_mask - compute the 32-bit mask
489    for an rlw* instruction
490-------------------------------------------------*/
491
492INLINE UINT32 compute_rlw_mask(UINT8 mb, UINT8 me)
396493{
397   if( ADD_CA(rd, ra, rb) )
398      XER |= XER_CA;
494   if (mb <= me)
495      return (0xffffffff >> mb) & (0xffffffff << (31 - me));
399496   else
400      XER &= ~XER_CA;
497      return (0xffffffff >> mb) | (0xffffffff << (31 - me));
401498}
402499
403INLINE void SET_SUB_CA(UINT32 rd, UINT32 ra, UINT32 rb)
500
501/*-------------------------------------------------
502    compute_crf_mask - compute the 32-bit mask
503    for a mtcrf/mfcrf instruction
504-------------------------------------------------*/
505
506INLINE UINT32 compute_crf_mask(UINT8 crm)
404507{
405   if( SUB_CA(rd, ra, rb) )
406      XER |= XER_CA;
407   else
408      XER &= ~XER_CA;
508   UINT32 mask = 0;
509   if (crm & 0x80) mask |= 0xf0000000;
510   if (crm & 0x40) mask |= 0x0f000000;
511   if (crm & 0x20) mask |= 0x00f00000;
512   if (crm & 0x10) mask |= 0x000f0000;
513   if (crm & 0x08) mask |= 0x0000f000;
514   if (crm & 0x04) mask |= 0x00000f00;
515   if (crm & 0x02) mask |= 0x000000f0;
516   if (crm & 0x01) mask |= 0x0000000f;
517   return mask;
409518}
410519
411INLINE UINT32 check_condition_code(UINT32 bo, UINT32 bi)
520
521/*-------------------------------------------------
522    compute_spr - compute the SPR index from the
523    SPR field of an opcode
524-------------------------------------------------*/
525
526INLINE UINT32 compute_spr(UINT32 spr)
412527{
413   UINT32 ctr_ok;
414   UINT32 condition_ok;
415   UINT32 bo0 = (bo & 0x10) ? 1 : 0;
416   UINT32 bo1 = (bo & 0x08) ? 1 : 0;
417   UINT32 bo2 = (bo & 0x04) ? 1 : 0;
418   UINT32 bo3 = (bo & 0x02) ? 1 : 0;
528   return ((spr >> 5) | (spr << 5)) & 0x3ff;
529}
419530
420   if( bo2 == 0 )
421      --CTR;
422531
423   ctr_ok = bo2 | ((CTR != 0) ^ bo3);
424   condition_ok = bo0 | (CRBIT(bi) ^ (~bo1 & 0x1));
425532
426   return ctr_ok && condition_ok;
427}
533/***************************************************************************
534    CORE CALLBACKS
535***************************************************************************/
428536
429INLINE UINT64 ppc_read_timebase(void)
537/*-------------------------------------------------
538    ppcdrc_init - initialize the processor
539-------------------------------------------------*/
540
541static void ppcdrc_init(powerpc_flavor flavor, UINT8 cap, int tb_divisor, int clock, const powerpc_config *config, int (*irqcallback)(int))
430542{
431   int cycles = ppc_tb_base_icount - ppc_icount;
543   drcfe_config feconfig =
544   {
545      COMPILE_BACKWARDS_BYTES,   /* code window start offset = startpc - window_start */
546      COMPILE_FORWARDS_BYTES,      /* code window end offset = startpc + window_end */
547      COMPILE_MAX_SEQUENCE,      /* maximum instructions to include in a sequence */
548      ppcfe_describe            /* callback to describe a single instruction */
549   };
550   drcbe_info beinfo;
551   UINT32 flags = 0;
552   size_t extrasize;
553   drccache *cache;
554   void *extramem;
555   int regnum;
432556
433   if (ppc.is603 || ppc.is602)
557   /* determine how much memory beyond the core size we need */
558    extrasize = ppccom_init(NULL, flavor, cap, tb_divisor, clock, config, irqcallback, NULL);
559
560   /* allocate enough space for the cache and the core */
561   cache = drccache_alloc(CACHE_SIZE + sizeof(*ppc) + extrasize);
562   if (cache == NULL)
563      fatalerror("Unable to allocate cache of size %d", (UINT32)(CACHE_SIZE + sizeof(*ppc) + extrasize));
564
565   /* allocate the core from the near cache, and the extra memory from the full cache */
566   ppc = drccache_memory_alloc_near(cache, sizeof(*ppc));
567   memset(ppc, 0, sizeof(*ppc));
568   extramem = drccache_memory_alloc(cache, extrasize);
569   memset(extramem, 0, extrasize);
570
571   /* initialize the core */
572   ppccom_init(ppc, flavor, cap, tb_divisor, clock, config, irqcallback, extramem);
573
574   /* allocate the implementation-specific state from the full cache */
575   ppc->impstate = drccache_memory_alloc_near(cache, sizeof(*ppc->impstate));
576   memset(ppc->impstate, 0, sizeof(*ppc->impstate));
577   ppc->impstate->cache = cache;
578
579   /* initialize the UML generator */
580   if (FORCE_C_BACKEND)
581      flags |= DRCUML_OPTION_USE_C;
582   if (LOG_UML)
583      flags |= DRCUML_OPTION_LOG_UML;
584   if (LOG_NATIVE)
585      flags |= DRCUML_OPTION_LOG_NATIVE;
586   ppc->impstate->drcuml = drcuml_alloc(cache, flags, 8, 32, 2);
587   if (ppc->impstate->drcuml == NULL)
588      fatalerror("Error initializing the UML");
589
590   /* initialize the front-end helper */
591   if (SINGLE_INSTRUCTION_MODE)
592      feconfig.max_sequence = 1;
593   ppc->impstate->drcfe = drcfe_init(&feconfig, ppc);
594
595   /* initialize the implementation state tables */
596   memcpy(ppc->impstate->fpmode, fpmode_source, sizeof(fpmode_source));
597   memcpy(ppc->impstate->sz_cr_table, sz_cr_table_source, sizeof(sz_cr_table_source));
598   memcpy(ppc->impstate->cmp_cr_table, cmp_cr_table_source, sizeof(cmp_cr_table_source));
599   memcpy(ppc->impstate->cmpl_cr_table, cmpl_cr_table_source, sizeof(cmpl_cr_table_source));
600   memcpy(ppc->impstate->fcmp_cr_table, fcmp_cr_table_source, sizeof(fcmp_cr_table_source));
601
602   /* compute the register parameters */
603   for (regnum = 0; regnum < 32; regnum++)
434604   {
435      // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly
436      return ppc.tb + (cycles / 4);
605      ppc->impstate->regmap[regnum].type = DRCUML_PTYPE_MEMORY;
606      ppc->impstate->regmap[regnum].value = (FPTR)&ppc->r[regnum];
607      ppc->impstate->fsregmap[regnum].type = DRCUML_PTYPE_MEMORY;
608      ppc->impstate->fsregmap[regnum].value = (FPTR)((UINT32 *)&ppc->f[regnum] + BYTE_XOR_LE(0));
609      ppc->impstate->fdregmap[regnum].type = DRCUML_PTYPE_MEMORY;
610      ppc->impstate->fdregmap[regnum].value = (FPTR)&ppc->f[regnum];
437611   }
438   else
612
613   /* if we have registers to spare, assign r0, r1, r2 to leftovers */
614   if (!DISABLE_FAST_REGISTERS)
439615   {
440      // timebase is incremented once every core cycle on PPC403
441      return ppc.tb + cycles;
616      drcuml_get_backend_info(ppc->impstate->drcuml, &beinfo);
617      if (beinfo.direct_iregs > 5)
618      {
619         ppc->impstate->regmap[0].type = DRCUML_PTYPE_INT_REGISTER;
620         ppc->impstate->regmap[0].value = DRCUML_REG_I5;
621      }
622      if (beinfo.direct_iregs > 6)
623      {
624         ppc->impstate->regmap[1].type = DRCUML_PTYPE_INT_REGISTER;
625         ppc->impstate->regmap[1].value = DRCUML_REG_I6;
626      }
627      if (beinfo.direct_iregs > 7)
628      {
629         ppc->impstate->regmap[2].type = DRCUML_PTYPE_INT_REGISTER;
630         ppc->impstate->regmap[2].value = DRCUML_REG_I7;
631      }
442632   }
633
634   /* mark the cache dirty so it is updated on next execute */
635   ppc->impstate->cache_dirty = TRUE;
443636}
444637
445INLINE void ppc_write_timebase_l(UINT32 tbl)
638
639/*-------------------------------------------------
640    ppcdrc_reset - reset the processor
641-------------------------------------------------*/
642
643static void ppcdrc_reset(void)
446644{
447   ppc_tb_base_icount = ppc_icount;
448
449   ppc.tb &= ~0xffffffff;
450   ppc.tb |= tbl;
645   /* reset the common code and mark the cache dirty */
646   ppccom_reset(ppc);
647   ppc->impstate->mode = 0;
648   ppc->impstate->cache_dirty = TRUE;
451649}
452650
453INLINE void ppc_write_timebase_h(UINT32 tbh)
651
652/*-------------------------------------------------
653    ppcdrc_execute - execute the CPU for the
654    specified number of cycles
655-------------------------------------------------*/
656
657static int ppcdrc_execute(int cycles)
454658{
455   ppc_tb_base_icount = ppc_icount;
659   drcuml_state *drcuml = ppc->impstate->drcuml;
660   int execute_result;
456661
457   ppc.tb &= 0xffffffff;
458   ppc.tb |= (UINT64)(tbh) << 32;
662   /* reset the cache if dirty */
663   if (ppc->impstate->cache_dirty)
664      code_flush_cache(drcuml);
665   ppc->impstate->cache_dirty = FALSE;
666
667   /* execute */
668   ppc->icount = cycles;
669   do
670   {
671      /* run as much as we can */
672      execute_result = drcuml_execute(drcuml, ppc->impstate->entry);
673
674      /* if we need to recompile, do it */
675      if (execute_result == EXECUTE_MISSING_CODE)
676         code_compile_block(drcuml, ppc->impstate->mode, ppc->pc);
677      else if (execute_result == EXECUTE_UNMAPPED_CODE)
678         fatalerror("Attempted to execute unmapped code at PC=%08X\n", ppc->pc);
679      else if (execute_result == EXECUTE_RESET_CACHE)
680         code_flush_cache(drcuml);
681
682   } while (execute_result != EXECUTE_OUT_OF_CYCLES);
683
684   /* return the number of cycles executed */
685   return cycles - ppc->icount;
459686}
460687
461INLINE UINT32 read_decrementer(void)
688
689/*-------------------------------------------------
690    ppcdrc_exit - cleanup from execution
691-------------------------------------------------*/
692
693static void ppcdrc_exit(void)
462694{
463   int cycles = ppc_dec_base_icount - ppc_icount;
464
465   // decrementer is decremented once every four bus clock cycles, so adjust the cycles accordingly
466   return DEC - (cycles / (bus_freq_multiplier * 2));
695   /* clean up the DRC */
696   drcfe_exit(ppc->impstate->drcfe);
697   drcuml_free(ppc->impstate->drcuml);
698   drccache_free(ppc->impstate->cache);
467699}
468700
469INLINE void write_decrementer(UINT32 value)
701
702/*-------------------------------------------------
703    ppcdrc_get_context - return a copy of the
704    current context
705-------------------------------------------------*/
706
707static void ppcdrc_get_context(void *dst)
470708{
471   ppc_dec_base_icount = ppc_icount + (ppc_dec_base_icount - ppc_icount) % (bus_freq_multiplier * 2);
709   if (dst != NULL)
710      *(powerpc_state **)dst = ppc;
711}
472712
473   DEC = value;
474713
475   // check if decrementer exception occurs during execution
476   if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC))
477   {
478      ppc_dec_trigger_cycle = ppc_icount - DEC;
479   }
480   else
481   {
482      ppc_dec_trigger_cycle = 0x7fffffff;
483   }
714/*-------------------------------------------------
715    ppcdrc_set_context - copy the current context
716    into the global state
717-------------------------------------------------*/
718
719static void ppcdrc_set_context(void *src)
720{
721   if (src != NULL)
722      ppc = *(powerpc_state **)src;
484723}
485724
486/*********************************************************************/
487725
488INLINE void ppc_exception(int exception_type)
726/*-------------------------------------------------
727    ppcdrc_translate - perform virtual-to-physical
728    address translation
729-------------------------------------------------*/
730
731static int ppcdrc_translate(int space, int intention, offs_t *address)
489732{
490   void *exception_code = NULL;
491   void (*invoke_exception_handler)(void *handler);
733   return ppccom_translate_address(ppc, space, intention, address);
734}
492735
493   switch(exception_type)
494   {
495      case EXCEPTION_DECREMENTER:
496         exception_code = ppc.generate_decrementer_exception;
497         break;
498      case EXCEPTION_DSI:
499         exception_code = ppc.generate_dsi_exception;
500         break;
501      case EXCEPTION_ISI:
502         exception_code = ppc.generate_isi_exception;
503         break;
504      default:
505         fatalerror("Unknown exception %d", exception_type);
506         break;
507   }
508736
509   memcpy(&invoke_exception_handler, &ppc.invoke_exception_handler, sizeof(invoke_exception_handler));
510   invoke_exception_handler(exception_code);
737/*-------------------------------------------------
738    ppcdrc_dasm - disassemble an instruction
739-------------------------------------------------*/
740
741#ifdef ENABLE_DEBUGGER
742static offs_t ppcdrc_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
743{
744   return ppccom_dasm(ppc, buffer, pc, oprom, opram);
511745}
746#endif /* ENABLE_DEBUGGER */
512747
513/*********************************************************************/
514748
515INLINE void ppc_set_spr(int spr, UINT32 value)
749/*-------------------------------------------------
750    ppcdrc_set_info - set information about a given
751    CPU instance
752-------------------------------------------------*/
753
754static void ppcdrc_set_info(UINT32 state, cpuinfo *info)
516755{
517   switch (spr)
756   switch (state)
518757   {
519      case SPR_LR:      LR = value; return;
520      case SPR_CTR:      CTR = value; return;
521      case SPR_XER:      XER = value; return;
522      case SPR_SRR0:      ppc.srr0 = value; return;
523      case SPR_SRR1:      ppc.srr1 = value; return;
524      case SPR_SPRG0:      ppc.sprg[0] = value; return;
525      case SPR_SPRG1:      ppc.sprg[1] = value; return;
526      case SPR_SPRG2:      ppc.sprg[2] = value; return;
527      case SPR_SPRG3:      ppc.sprg[3] = value; return;
528      case SPR_PVR:      return;
529   }
758      /* --- the following bits of info are set as 64-bit signed integers --- */
759      case CPUINFO_INT_PPC_DRC_OPTIONS:            ppc->impstate->drcoptions = info->i;            break;
530760
531#if (HAS_PPC603 || HAS_PPC602 || HAS_PPC601 || HAS_PPC604)
532   if(ppc.is603 || ppc.is602) {
533      switch(spr)
534      {
535         case SPR603E_DEC:
536            if((value & 0x80000000) && !(DEC & 0x80000000))
537            {
538               /* trigger interrupt */
539               if( MSR & MSR_EE )
540                  ppc_exception(EXCEPTION_DECREMENTER);
541            }
542            write_decrementer(value);
543            return;
761      case CPUINFO_INT_PPC_FASTRAM_SELECT:         if (info->i >= 0 && info->i < PPC_MAX_FASTRAM) ppc->impstate->fastram_select = info->i; ppc->impstate->cache_dirty = TRUE; break;
762      case CPUINFO_INT_PPC_FASTRAM_START:            ppc->impstate->fastram[ppc->impstate->fastram_select].start = info->i; ppc->impstate->cache_dirty = TRUE; break;
763      case CPUINFO_INT_PPC_FASTRAM_END:            ppc->impstate->fastram[ppc->impstate->fastram_select].end = info->i; ppc->impstate->cache_dirty = TRUE; break;
764      case CPUINFO_INT_PPC_FASTRAM_READONLY:         ppc->impstate->fastram[ppc->impstate->fastram_select].readonly = info->i; ppc->impstate->cache_dirty = TRUE; break;
544765
545         case SPR603E_TBL_W:
546         case SPR603E_TBL_R: // special 603e case
547            ppc_write_timebase_l(value);
548            return;
766      case CPUINFO_INT_PPC_HOTSPOT_SELECT:         if (info->i >= 0 && info->i < PPC_MAX_HOTSPOTS) ppc->impstate->hotspot_select = info->i; ppc->impstate->cache_dirty = TRUE; break;
767      case CPUINFO_INT_PPC_HOTSPOT_PC:            ppc->impstate->hotspot[ppc->impstate->hotspot_select].pc = info->i; ppc->impstate->cache_dirty = TRUE; break;
768      case CPUINFO_INT_PPC_HOTSPOT_OPCODE:         ppc->impstate->hotspot[ppc->impstate->hotspot_select].opcode = info->i; ppc->impstate->cache_dirty = TRUE; break;
769      case CPUINFO_INT_PPC_HOTSPOT_CYCLES:         ppc->impstate->hotspot[ppc->impstate->hotspot_select].cycles = info->i; ppc->impstate->cache_dirty = TRUE; break;
549770
550         case SPR603E_TBU_R:
551         case SPR603E_TBU_W: // special 603e case
552            ppc_write_timebase_h(value);
553            return;
771      /* --- the following bits of info are set as pointers to data or functions --- */
772      case CPUINFO_PTR_PPC_FASTRAM_BASE:            ppc->impstate->fastram[ppc->impstate->fastram_select].base = info->p;   break;
554773
555         case SPR603E_HID0:
556            ppc.hid0 = value;
557            return;
774      /* --- everything else is handled generically --- */
775      default:                              ppccom_set_info(ppc, state, info);   break;
776   }
777}
558778
559         case SPR603E_HID1:
560            ppc.hid1 = value;
561            return;
562779
563         case SPR603E_HID2:
564            ppc.hid1 = value;
565            return;
780/*-------------------------------------------------
781    ppcdrc_get_info - return information about a given
782    CPU instance
783-------------------------------------------------*/
566784
567         case SPR603E_DSISR:         ppc.dsisr = value; return;
568         case SPR603E_DAR:         ppc.dar = value; return;
569         case SPR603E_EAR:         ppc.ear = value; return;
570         case SPR603E_DMISS:         ppc.dmiss = value; return;
571         case SPR603E_DCMP:         ppc.dcmp = value; return;
572         case SPR603E_HASH1:         ppc.hash1 = value; return;
573         case SPR603E_HASH2:         ppc.hash2 = value; return;
574         case SPR603E_IMISS:         ppc.imiss = value; return;
575         case SPR603E_ICMP:         ppc.icmp = value; return;
576         case SPR603E_RPA:         ppc.rpa = value; return;
785static void ppcdrc_get_info(UINT32 state, cpuinfo *info)
786{
787   switch (state)
788   {
789      /* --- the following bits of info are returned as 64-bit signed integers --- */
790      case CPUINFO_INT_CONTEXT_SIZE:               info->i = sizeof(ppc);               break;
791      case CPUINFO_INT_PREVIOUSPC:               /* not implemented */               break;
577792
578         case SPR603E_IBAT0L:      ppc.ibat[0].l = value; return;
579         case SPR603E_IBAT0U:      ppc.ibat[0].u = value; return;
580         case SPR603E_IBAT1L:      ppc.ibat[1].l = value; return;
581         case SPR603E_IBAT1U:      ppc.ibat[1].u = value; return;
582         case SPR603E_IBAT2L:      ppc.ibat[2].l = value; return;
583         case SPR603E_IBAT2U:      ppc.ibat[2].u = value; return;
584         case SPR603E_IBAT3L:      ppc.ibat[3].l = value; return;
585         case SPR603E_IBAT3U:      ppc.ibat[3].u = value; return;
586         case SPR603E_DBAT0L:      ppc.dbat[0].l = value; return;
587         case SPR603E_DBAT0U:      ppc.dbat[0].u = value; return;
588         case SPR603E_DBAT1L:      ppc.dbat[1].l = value; return;
589         case SPR603E_DBAT1U:      ppc.dbat[1].u = value; return;
590         case SPR603E_DBAT2L:      ppc.dbat[2].l = value; return;
591         case SPR603E_DBAT2U:      ppc.dbat[2].u = value; return;
592         case SPR603E_DBAT3L:      ppc.dbat[3].l = value; return;
593         case SPR603E_DBAT3U:      ppc.dbat[3].u = value; return;
793      /* --- the following bits of info are returned as pointers to data or functions --- */
794      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppcdrc_set_info;      break;
795      case CPUINFO_PTR_GET_CONTEXT:               info->getcontext = ppcdrc_get_context;   break;
796      case CPUINFO_PTR_SET_CONTEXT:               info->setcontext = ppcdrc_set_context;   break;
797      case CPUINFO_PTR_INIT:                     /* provided per-CPU */               break;
798      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc_reset;            break;
799      case CPUINFO_PTR_EXIT:                     info->exit = ppcdrc_exit;            break;
800      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc_execute;         break;
801#ifdef ENABLE_DEBUGGER
802      case CPUINFO_PTR_DISASSEMBLE:               info->disassemble = ppcdrc_dasm;      break;
803#endif /* ENABLE_DEBUGGER */
804      case CPUINFO_PTR_TRANSLATE:                  info->translate = ppcdrc_translate;      break;
805      case CPUINFO_PTR_CONTEXT:                  info->p = ppc;                     break;
594806
595         case SPR603E_SDR1:
596            ppc.sdr1 = value;
597            return;
807      /* --- the following bits of info are returned as NULL-terminated strings --- */
808      case CPUINFO_STR_CORE_FILE:                  strcpy(info->s, __FILE__);            break;
598809
599         case SPR603E_IABR:         ppc.iabr = value; return;
600      }
810      /* --- everything else is handled generically --- */
811      default:                              ppccom_get_info(ppc, state, info); break;
601812   }
602#endif
813}
603814
604#if (HAS_PPC602)
605   if (ppc.is602) {
606      switch(spr)
607      {
608         case SPR602_LT:         ppc.lt = value; return;
609         case SPR602_IBR:      ppc.ibr = value; return;
610         case SPR602_SP:         ppc.sp = value; return;
611         case SPR602_SEBR:      ppc.sebr = value; return;
612         case SPR602_SER:      ppc.ser = value; return;
613         case SPR602_TCR:      ppc.tcr = value; return;
614      }
615   }
616#endif
617815
618#if (HAS_PPC403)
619   if (!ppc.is603 && !ppc.is602) {
620      switch(spr)
621      {
622         case SPR403_TBHI:      ppc_write_timebase_h(value); return;
623         case SPR403_TBLO:      ppc_write_timebase_l(value); return;
624816
625         case SPR403_TSR:
626            ppc.tsr &= ~value; // 1 clears, 0 does nothing
627            return;
817/***************************************************************************
818    CACHE MANAGEMENT
819***************************************************************************/
628820
629         case SPR403_TCR:
630            switch((value >> 24) & 0x3)
631            {
632               case 0: ppc.fit_bit = 1 << 8; break;
633               case 1: ppc.fit_bit = 1 << 12; break;
634               case 2: ppc.fit_bit = 1 << 16; break;
635               case 3: ppc.fit_bit = 1 << 20; break;
636            }
637            switch((value >> 30) & 0x3)
638            {
639               case 0: ppc.wdt_bit = 1 << 16; break;
640               case 1: ppc.wdt_bit = 1 << 20; break;
641               case 2: ppc.wdt_bit = 1 << 24; break;
642               case 3: ppc.wdt_bit = 1 << 28; break;
643            }
644            ppc.fit_int_enable = (value >> 23) & 0x1;
645            ppc.wdt_int_enable = (value >> 27) & 0x1;
646            ppc.tcr = value;
821/*-------------------------------------------------
822    code_flush_cache - flush the cache and
823    regenerate static code
824-------------------------------------------------*/
647825
648            if (!ppc.fit_int_enable)
649            {
650               ppc.exception_pending &= ~0x4;
651            }
652            return;
826static void code_flush_cache(drcuml_state *drcuml)
827{
828   int mode;
653829
654         case SPR403_ESR:      ppc.esr = value; return;
655         case SPR403_ICCR:      ppc.iccr = value; return;
656         case SPR403_DCCR:      ppc.dccr = value; return;
657         case SPR403_EVPR:      EVPR = value & 0xffff0000; return;
658         case SPR403_PIT:      ppc.pit = value; return;
659         case SPR403_SGR:      ppc.sgr = value; return;
660         case SPR403_DBSR:      ppc.dbsr = value; return;
661         case SPR403_DCWR:      return;
662         case SPR403_PID:      ppc.pid = value; return;
663         case SPR403_PBL1:      ppc.pbl1 = value; return;
664         case SPR403_PBU1:      ppc.pbu1 = value; return;
665         case SPR403_PBL2:      ppc.pbl2 = value; return;
666         case SPR403_PBU2:      ppc.pbu2 = value; return;
667         case SPR403_SRR2:      ppc.srr2 = value; return;
668         case SPR403_SRR3:      ppc.srr3 = value; return;
669         case SPR403_DAC1:      ppc.dac1 = value; return;
670         case SPR403_DAC2:      ppc.dac2 = value; return;
671         case SPR403_IAC1:      ppc.iac1 = value; return;
672         case SPR403_IAC2:      ppc.iac2 = value; return;
673      }
674   }
675#endif
830   /* empty the transient cache contents */
831   drcuml_reset(drcuml);
676832
677   fatalerror("ppc: set_spr: unknown spr %d (%03X) !", spr, spr);
678}
833   /* generate the entry point and out-of-cycles handlers */
834   static_generate_entry_point(drcuml);
835   static_generate_nocode_handler(drcuml);
836   static_generate_out_of_cycles(drcuml);
837   static_generate_tlb_mismatch(drcuml);
838   if (ppc->cap & PPCCAP_603_MMU)
839      static_generate_swap_tgpr(drcuml);
679840
680INLINE UINT32 ppc_get_spr(int spr)
681{
682   switch(spr)
841   /* append exception handlers for various types */
842   static_generate_exception(drcuml, EXCEPTION_RESET,     TRUE,  "exception_reset");
843   static_generate_exception(drcuml, EXCEPTION_MACHCHECK, TRUE,  "exception_machine_check");
844   static_generate_exception(drcuml, EXCEPTION_DSI,       TRUE,  "exception_dsi");
845   static_generate_exception(drcuml, EXCEPTION_ISI,       TRUE,  "exception_isi");
846   static_generate_exception(drcuml, EXCEPTION_EI,        TRUE,  "exception_ei");
847   static_generate_exception(drcuml, EXCEPTION_EI,        FALSE, "exception_ei_norecover");
848   static_generate_exception(drcuml, EXCEPTION_ALIGN,     TRUE,  "exception_align");
849   static_generate_exception(drcuml, EXCEPTION_PROGRAM,   TRUE,  "exception_program");
850   static_generate_exception(drcuml, EXCEPTION_NOFPU,     TRUE,  "exception_fpu_unavailable");
851   static_generate_exception(drcuml, EXCEPTION_DECREMENT, TRUE,  "exception_decrementer");
852   static_generate_exception(drcuml, EXCEPTION_SYSCALL,   TRUE,  "exception_syscall");
853   static_generate_exception(drcuml, EXCEPTION_TRACE,     TRUE,  "exception_trace");
854   static_generate_exception(drcuml, EXCEPTION_FPASSIST,  TRUE,  "exception_floating_point_assist");
855   if (ppc->cap & PPCCAP_603_MMU)
683856   {
684      case SPR_LR:      return LR;
685      case SPR_CTR:      return CTR;
686      case SPR_XER:      return XER;
687      case SPR_SRR0:      return ppc.srr0;
688      case SPR_SRR1:      return ppc.srr1;
689      case SPR_SPRG0:      return ppc.sprg[0];
690      case SPR_SPRG1:      return ppc.sprg[1];
691      case SPR_SPRG2:      return ppc.sprg[2];
692      case SPR_SPRG3:      return ppc.sprg[3];
693      case SPR_PVR:      return ppc.pvr;
857      static_generate_exception(drcuml, EXCEPTION_ITLBMISS,  TRUE,  "exception_itlb_miss");
858      static_generate_exception(drcuml, EXCEPTION_DTLBMISSL, TRUE,  "exception_dtlb_miss_load");
859      static_generate_exception(drcuml, EXCEPTION_DTLBMISSS, TRUE,  "exception_dtlb_miss_store");
694860   }
695861
696#if (HAS_PPC403)
697   if (!ppc.is603 && !ppc.is602)
862   /* add subroutines for memory accesses */
863   for (mode = 0; mode < 4; mode++)
698864   {
699      switch (spr)
700      {
701         case SPR403_TBLU:
702         case SPR403_TBLO:      return (UINT32)(ppc_read_timebase());
703         case SPR403_TBHU:
704         case SPR403_TBHI:      return (UINT32)(ppc_read_timebase() >> 32);
705
706         case SPR403_EVPR:      return EVPR;
707         case SPR403_ESR:      return ppc.esr;
708         case SPR403_TCR:      return ppc.tcr;
709         case SPR403_ICCR:      return ppc.iccr;
710         case SPR403_DCCR:      return ppc.dccr;
711         case SPR403_PIT:      return ppc.pit;
712         case SPR403_DBSR:      return ppc.dbsr;
713         case SPR403_SGR:      return ppc.sgr;
714         case SPR403_TSR:      return ppc.tsr;
715         case SPR403_PBL1:      return ppc.pbl1;
716         case SPR403_PBU1:      return ppc.pbu1;
717         case SPR403_PBL2:      return ppc.pbl2;
718         case SPR403_PBU2:      return ppc.pbu2;
719         case SPR403_SRR2:      return ppc.srr2;
720         case SPR403_SRR3:      return ppc.srr3;
721         case SPR403_DAC1:      return ppc.dac1;
722         case SPR403_DAC2:      return ppc.dac2;
723         case SPR403_IAC1:      return ppc.iac1;
724         case SPR403_IAC2:      return ppc.iac2;
725      }
865      static_generate_memory_accessor(drcuml, mode, 1, FALSE, FALSE, "read8",       &ppc->impstate->read8[mode],       NULL);
866      static_generate_memory_accessor(drcuml, mode, 1, TRUE,  FALSE, "write8",      &ppc->impstate->write8[mode],      NULL);
867      static_generate_memory_accessor(drcuml, mode, 2, FALSE, TRUE,  "read16mask",  &ppc->impstate->read16mask[mode],  NULL);
868      static_generate_memory_accessor(drcuml, mode, 2, FALSE, FALSE, "read16",      &ppc->impstate->read16[mode],      ppc->impstate->read16mask[mode]);
869      static_generate_memory_accessor(drcuml, mode, 2, TRUE,  TRUE,  "write16mask", &ppc->impstate->write16mask[mode], NULL);
870      static_generate_memory_accessor(drcuml, mode, 2, TRUE,  FALSE, "write16",     &ppc->impstate->write16[mode],     ppc->impstate->write16mask[mode]);
871      static_generate_memory_accessor(drcuml, mode, 4, FALSE, TRUE,  "read32mask",  &ppc->impstate->read32mask[mode],  NULL);
872      static_generate_memory_accessor(drcuml, mode, 4, FALSE, FALSE, "read32align", &ppc->impstate->read32align[mode], NULL);
873      static_generate_memory_accessor(drcuml, mode, 4, FALSE, FALSE, "read32",      &ppc->impstate->read32[mode],      ppc->impstate->read32mask[mode]);
874      static_generate_memory_accessor(drcuml, mode, 4, TRUE,  TRUE,  "write32mask", &ppc->impstate->write32mask[mode], NULL);
875      static_generate_memory_accessor(drcuml, mode, 4, TRUE,  FALSE, "write32align",&ppc->impstate->write32align[mode],NULL);
876      static_generate_memory_accessor(drcuml, mode, 4, TRUE,  FALSE, "write32",     &ppc->impstate->write32[mode],     ppc->impstate->write32mask[mode]);
877      static_generate_memory_accessor(drcuml, mode, 8, FALSE, TRUE,  "read64mask",  &ppc->impstate->read64mask[mode],  NULL);
878      static_generate_memory_accessor(drcuml, mode, 8, FALSE, FALSE, "read64",      &ppc->impstate->read64[mode],      ppc->impstate->read64mask[mode]);
879      static_generate_memory_accessor(drcuml, mode, 8, TRUE,  TRUE,  "write64mask", &ppc->impstate->write64mask[mode], NULL);
880      static_generate_memory_accessor(drcuml, mode, 8, TRUE,  FALSE, "write64",     &ppc->impstate->write64[mode],     ppc->impstate->write64mask[mode]);
726881   }
727#endif
882}
728883
729#if (HAS_PPC602)
730   if (ppc.is602) {
731      switch(spr)
732      {
733         case SPR602_LT:         return ppc.lt;
734         case SPR602_IBR:      return ppc.ibr;
735         case SPR602_ESASRR:      return ppc.esasrr;
736         case SPR602_SEBR:      return ppc.sebr;
737         case SPR602_SER:      return ppc.ser;
738         case SPR602_SP:         return ppc.sp;
739         case SPR602_TCR:      return ppc.tcr;
740      }
741   }
742#endif
743884
744#if (HAS_PPC603 || HAS_PPC602 || HAS_PPC601 || HAS_PPC604)
745   if (ppc.is603 || ppc.is602)
746   {
747      switch (spr)
748      {
749         case SPR603E_TBL_R:
750            fatalerror("ppc: get_spr: TBL_R ");
751            break;
885/*-------------------------------------------------
886    code_compile_block - compile a block of the
887    given mode at the specified pc
888-------------------------------------------------*/
752889
753         case SPR603E_TBU_R:
754            fatalerror("ppc: get_spr: TBU_R ");
755            break;
890static void code_compile_block(drcuml_state *drcuml, UINT8 mode, offs_t pc)
891{
892   compiler_state compiler = { 0 };
893   const opcode_desc *seqhead, *seqlast;
894   const opcode_desc *desclist;
895   int override = FALSE;
896   drcuml_block *block;
897   jmp_buf errorbuf;
756898
757         case SPR603E_TBL_W:      return (UINT32)(ppc_read_timebase());
758         case SPR603E_TBU_W:      return (UINT32)(ppc_read_timebase() >> 32);
759         case SPR603E_HID0:      return ppc.hid0;
760         case SPR603E_HID1:      return ppc.hid1;
761         case SPR603E_HID2:      return ppc.hid2;
762         case SPR603E_DEC:      return read_decrementer();
763         case SPR603E_SDR1:      return ppc.sdr1;
764         case SPR603E_DSISR:      return ppc.dsisr;
765         case SPR603E_DAR:      return ppc.dar;
766         case SPR603E_EAR:      return ppc.ear;
767         case SPR603E_IBAT0L:   return ppc.ibat[0].l;
768         case SPR603E_IBAT0U:   return ppc.ibat[0].u;
769         case SPR603E_IBAT1L:   return ppc.ibat[1].l;
770         case SPR603E_IBAT1U:   return ppc.ibat[1].u;
771         case SPR603E_IBAT2L:   return ppc.ibat[2].l;
772         case SPR603E_IBAT2U:   return ppc.ibat[2].u;
773         case SPR603E_IBAT3L:   return ppc.ibat[3].l;
774         case SPR603E_IBAT3U:   return ppc.ibat[3].u;
775         case SPR603E_DBAT0L:   return ppc.dbat[0].l;
776         case SPR603E_DBAT0U:   return ppc.dbat[0].u;
777         case SPR603E_DBAT1L:   return ppc.dbat[1].l;
778         case SPR603E_DBAT1U:   return ppc.dbat[1].u;
779         case SPR603E_DBAT2L:   return ppc.dbat[2].l;
780         case SPR603E_DBAT2U:   return ppc.dbat[2].u;
781         case SPR603E_DBAT3L:   return ppc.dbat[3].l;
782         case SPR603E_DBAT3U:   return ppc.dbat[3].u;
783      }
784   }
785#endif
899   /* get a description of this sequence */
900   desclist = drcfe_describe_code(ppc->impstate->drcfe, pc);
901   if (LOG_UML || LOG_NATIVE)
902      log_opcode_desc(drcuml, desclist, 0);
786903
787   fatalerror("ppc: get_spr: unknown spr %d (%03X) !", spr, spr);
788   return 0;
789}
904   /* if we get an error back, flush the cache and try again */
905   if (setjmp(errorbuf) != 0)
906      code_flush_cache(drcuml);
790907
791static UINT8 ppc_read8_translated(offs_t address);
792static UINT16 ppc_read16_translated(offs_t address);
793static UINT32 ppc_read32_translated(offs_t address);
794static UINT64 ppc_read64_translated(offs_t address);
795static void ppc_write8_translated(offs_t address, UINT8 data);
796static void ppc_write16_translated(offs_t address, UINT16 data);
797static void ppc_write32_translated(offs_t address, UINT32 data);
798static void ppc_write64_translated(offs_t address, UINT64 data);
908   /* start the block */
909   block = drcuml_block_begin(drcuml, 4096, &errorbuf);
799910
800INLINE void ppc_set_msr(UINT32 value)
801{
802   if( value & (MSR_ILE | MSR_LE) )
803      fatalerror("ppc: set_msr: little_endian mode not supported !");
911   /* loop until we get through all instruction sequences */
912   for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next)
913   {
914      const opcode_desc *curdesc;
915      UINT32 nextpc;
804916
805   MSR = value;
917      /* add a code log entry */
918      if (LOG_UML)
919         UML_COMMENT(block, "-------------------------");                        // comment
806920
807   if (ppc.is603 || ppc.is602)
808   {
809      if (!(MSR & MSR_DR))
921      /* determine the last instruction in this sequence */
922      for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next)
923         if (seqlast->flags & OPFLAG_END_SEQUENCE)
924            break;
925      assert(seqlast != NULL);
926
927      /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */
928      if (override || !drcuml_hash_exists(drcuml, mode, seqhead->pc))
929         UML_HASH(block, mode, seqhead->pc);                                    // hash    mode,pc
930
931      /* if we already have a hash, and this is the first sequence, assume that we */
932      /* are recompiling due to being out of sync and allow future overrides */
933      else if (seqhead == desclist)
810934      {
811         ppc.read8 = program_read_byte_64be;
812         ppc.read16 = program_read_word_64be;
813         ppc.read32 = program_read_dword_64be;
814         ppc.read64 = program_read_qword_64be;
815         ppc.write8 = program_write_byte_64be;
816         ppc.write16 = program_write_word_64be;
817         ppc.write32 = program_write_dword_64be;
818         ppc.write64 = program_write_qword_64be;
935         override = TRUE;
936         UML_HASH(block, mode, seqhead->pc);                                    // hash    mode,pc
819937      }
938
939      /* otherwise, redispatch to that fixed PC and skip the rest of the processing */
820940      else
821941      {
822         ppc.read8 = ppc_read8_translated;
823         ppc.read16 = ppc_read16_translated;
824         ppc.read32 = ppc_read32_translated;
825         ppc.read64 = ppc_read64_translated;
826         ppc.write8 = ppc_write8_translated;
827         ppc.write16 = ppc_write16_translated;
828         ppc.write32 = ppc_write32_translated;
829         ppc.write64 = ppc_write64_translated;
942         UML_LABEL(block, seqhead->pc | 0x80000000);                              // label   seqhead->pc | 0x80000000
943         UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(seqhead->pc), ppc->impstate->nocode);
944                                                                     // hashjmp <mode>,seqhead->pc,nocode
945         continue;
830946      }
947
948      /* validate this code block if we're not pointing into ROM */
949      if (memory_get_write_ptr(cpu_getactivecpu(), ADDRESS_SPACE_PROGRAM, seqhead->physpc) != NULL)
950         generate_checksum_block(block, &compiler, seqhead, seqlast);               // <checksum>
951
952      /* label this instruction, if it may be jumped to locally */
953      if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
954         UML_LABEL(block, seqhead->pc | 0x80000000);                              // label   seqhead->pc | 0x80000000
955
956      /* iterate over instructions in the sequence and compile them */
957      for (curdesc = seqhead; curdesc != seqlast->next; curdesc = curdesc->next)
958         generate_sequence_instruction(block, &compiler, curdesc);                  // <instruction>
959
960      /* if we need to return to the start, do it */
961      if (seqlast->flags & OPFLAG_RETURN_TO_START)
962         nextpc = pc;
963
964      /* otherwise we just go to the next instruction */
965      else
966         nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4;
967
968      /* count off cycles and go there */
969      generate_update_cycles(block, &compiler, IMM(nextpc), TRUE);                  // <subtract cycles>
970
971      /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */
972      if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES)
973         UML_HASHJMP(block, MEM(&ppc->impstate->mode), IMM(nextpc), ppc->impstate->nocode);// hashjmp <mode>,nextpc,nocode
974      else if (seqlast->next == NULL || seqlast->next->pc != nextpc)
975         UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(nextpc), ppc->impstate->nocode);// hashjmp <mode>,nextpc,nocode
831976   }
977
978   /* end the sequence */
979   drcuml_block_end(block);
832980}
833981
834INLINE UINT32 ppc_get_msr(void)
982
983
984/***************************************************************************
985    C FUNCTION CALLBACKS
986***************************************************************************/
987
988/*-------------------------------------------------
989    cfunc_printf_exception - log any exceptions that
990    aren't interrupts
991-------------------------------------------------*/
992
993static void cfunc_printf_exception(void *param)
835994{
836   return MSR;
995   printf("Exception: type=%2d EPC=%08X MSR=%08X\n", ppc->param0, ppc->spr[SPROEA_SRR0], ppc->spr[SPROEA_SRR1]);
996   cfunc_printf_probe((void *)(FPTR)ppc->spr[SPROEA_SRR0]);
837997}
838998
839INLINE void ppc_set_cr(UINT32 value)
999
1000/*-------------------------------------------------
1001    cfunc_printf_debug - generic printf for
1002    debugging
1003-------------------------------------------------*/
1004
1005static void cfunc_printf_debug(void *param)
8401006{
841   CR(0) = (value >> 28) & 0xf;
842   CR(1) = (value >> 24) & 0xf;
843   CR(2) = (value >> 20) & 0xf;
844   CR(3) = (value >> 16) & 0xf;
845   CR(4) = (value >> 12) & 0xf;
846   CR(5) = (value >> 8) & 0xf;
847   CR(6) = (value >> 4) & 0xf;
848   CR(7) = (value >> 0) & 0xf;
1007   const char *format = param;
1008   printf(format, ppc->impstate->arg0, ppc->impstate->arg1);
8491009}
8501010
851INLINE UINT32 ppc_get_cr(void)
1011
1012/*-------------------------------------------------
1013    cfunc_printf_probe - print the current CPU
1014    state and return
1015-------------------------------------------------*/
1016
1017static void cfunc_printf_probe(void *param)
8521018{
853   return CR(0) << 28 | CR(1) << 24 | CR(2) << 20 | CR(3) << 16 | CR(4) << 12 | CR(5) << 8 | CR(6) << 4 | CR(7);
1019   UINT32 pc = (UINT32)(FPTR)param;
1020
1021   printf(" PC=%08X\n", pc);
1022   printf(" r0=%08X  r1=%08X  r2=%08X  r3=%08X\n",
1023      ppc->r[0], ppc->r[1], ppc->r[2], ppc->r[3]);
1024   printf(" r4=%08X  r5=%08X  r6=%08X  r7=%08X\n",
1025      ppc->r[4], ppc->r[5], ppc->r[6], ppc->r[7]);
1026   printf(" r8=%08X  r9=%08X r10=%08X r11=%08X\n",
1027      ppc->r[8], ppc->r[9], ppc->r[10], ppc->r[11]);
1028   printf("r12=%08X r13=%08X r14=%08X r15=%08X\n",
1029      ppc->r[12], ppc->r[13], ppc->r[14], ppc->r[15]);
1030   printf("r16=%08X r17=%08X r18=%08X r19=%08X\n",
1031      ppc->r[16], ppc->r[17], ppc->r[18], ppc->r[19]);
1032   printf("r20=%08X r21=%08X r22=%08X r23=%08X\n",
1033      ppc->r[20], ppc->r[21], ppc->r[22], ppc->r[23]);
1034   printf("r24=%08X r25=%08X r26=%08X r27=%08X\n",
1035      ppc->r[24], ppc->r[25], ppc->r[26], ppc->r[27]);
1036   printf("r28=%08X r29=%08X r30=%08X r31=%08X\n",
1037      ppc->r[28], ppc->r[29], ppc->r[30], ppc->r[31]);
8541038}
8551039
856#ifdef UNUSED_FUNCTION
857static void log_code(drc_core *drc)
1040
1041/*-------------------------------------------------
1042    cfunc_unimplemented - handler for
1043    unimplemented opcdes
1044-------------------------------------------------*/
1045
1046static void cfunc_unimplemented(void *param)
8581047{
859#if LOG_CODE
860   FILE *temp;
861   temp = fopen("code.bin", "wb");
862   fwrite(drc->cache_base, 1, drc->cache_top - drc->cache_base, temp);
863   fclose(temp);
864#endif
1048   UINT32 opcode = (FPTR)param;
1049   fatalerror("PC=%08X: Unimplemented op %08X", ppc->pc, opcode);
8651050}
866#endif
8671051
868/***********************************************************************/
8691052
870#include "ppc_mem.c"
8711053
872#if (HAS_PPC403)
873#include "ppc403.c"
874#endif
875
876#if (HAS_PPC602)
877#include "ppc602.c"
878#endif
879
8801054/***************************************************************************
881    CODE LOGGING
1055    STATIC CODEGEN
8821056***************************************************************************/
8831057
884#if LOG_CODE
1058/*-------------------------------------------------
1059    static_generate_entry_point - generate a
1060    static entry point
1061-------------------------------------------------*/
8851062
886static code_log_entry code_log_buffer[MAX_INSTRUCTIONS*2];
887static int code_log_index;
888static FILE *logfile;
1063static void static_generate_entry_point(drcuml_state *drcuml)
1064{
1065   drcuml_codelabel skip = 1;
1066   drcuml_block *block;
1067   jmp_buf errorbuf;
8891068
1069   /* if we get an error back, we're screwed */
1070   if (setjmp(errorbuf) != 0)
1071      fatalerror("Unrecoverable error in static_generate_entry_point");
8901072
1073   /* begin generating */
1074   block = drcuml_block_begin(drcuml, 20, &errorbuf);
1075
1076   /* forward references */
1077   alloc_handle(drcuml, &ppc->impstate->nocode, "nocode");
1078   alloc_handle(drcuml, &ppc->impstate->exception_norecover[EXCEPTION_EI], "exception_ei_norecover");
1079
1080   alloc_handle(drcuml, &ppc->impstate->entry, "entry");
1081   UML_HANDLE(block, ppc->impstate->entry);                                    // handle  entry
1082
1083   /* reset the FPU mode */
1084   UML_AND(block, IREG(0), FPSCR32, IMM(3));                                    // and     i0,fpscr,3
1085   UML_LOAD(block, IREG(0), &ppc->impstate->fpmode[0], IREG(0), BYTE);                  // load    i0,fpmode,i0,byte
1086   UML_SETFMOD(block, IREG(0));                                             // setfmod i0
1087
1088   /* load fast integer registers */
1089   load_fast_iregs(block);                                                   // <load fastregs>
1090
1091   /* check for interrupts */
1092   UML_TEST(block, MEM(&ppc->irq_pending), IMM(~0));                              // test    [irq_pending],0
1093   UML_JMPc(block, IF_Z, skip);                                             // jmp     skip,Z
1094   UML_TEST(block, MSR32, IMM(MSR_EE));                                       // test    msr,MSR_EE
1095   UML_JMPc(block, IF_Z, skip);                                             // jmp     skip,Z
1096   UML_MOV(block, IREG(0), MEM(&ppc->pc));                                       // mov     i0,pc
1097   UML_MOV(block, IREG(1), IMM(0));                                          // mov     i1,0
1098   UML_CALLH(block, ppc->impstate->exception_norecover[EXCEPTION_EI]);                  // callh   exception_norecover
1099   UML_LABEL(block, skip);                                                // skip:
1100
1101   /* generate a hash jump via the current mode and PC */
1102   UML_HASHJMP(block, MEM(&ppc->impstate->mode), MEM(&ppc->pc), ppc->impstate->nocode);   // hashjmp <mode>,<pc>,nocode
1103
1104   drcuml_block_end(block);
1105}
1106
1107
8911108/*-------------------------------------------------
892    open_logfile - open the log file if it is
893    not already opened
1109    static_generate_nocode_handler - generate an
1110    exception handler for "out of code"
8941111-------------------------------------------------*/
8951112
896INLINE int open_logfile(void)
1113static void static_generate_nocode_handler(drcuml_state *drcuml)
8971114{
898   if (logfile == NULL)
899      logfile = fopen("ppcdrc.asm", "w");
900   return (logfile != NULL);
1115   drcuml_block *block;
1116   jmp_buf errorbuf;
1117
1118   /* if we get an error back, we're screwed */
1119   if (setjmp(errorbuf) != 0)
1120      fatalerror("Unrecoverable error in static_generate_nocode_handler");
1121
1122   /* begin generating */
1123   block = drcuml_block_begin(drcuml, 10, &errorbuf);
1124
1125   /* generate a hash jump via the current mode and PC */
1126   alloc_handle(drcuml, &ppc->impstate->nocode, "nocode");
1127   UML_HANDLE(block, ppc->impstate->nocode);                                    // handle  nocode
1128   UML_GETEXP(block, IREG(0));                                                // getexp  i0
1129   UML_MOV(block, MEM(&ppc->pc), IREG(0));                                       // mov     [pc],i0
1130   save_fast_iregs(block);                                                   // <save fastregs>
1131   UML_EXIT(block, IMM(EXECUTE_MISSING_CODE));                                    // exit    EXECUTE_MISSING_CODE
1132
1133   drcuml_block_end(block);
9011134}
9021135
9031136
9041137/*-------------------------------------------------
905    code_log_reset - reset the logging index
1138    static_generate_out_of_cycles - generate an
1139    out of cycles exception handler
9061140-------------------------------------------------*/
9071141
908INLINE void code_log_reset(void)
1142static void static_generate_out_of_cycles(drcuml_state *drcuml)
9091143{
910   code_log_index = 0;
1144   drcuml_block *block;
1145   jmp_buf errorbuf;
1146
1147   /* if we get an error back, we're screwed */
1148   if (setjmp(errorbuf) != 0)
1149      fatalerror("Unrecoverable error in static_generate_out_of_cycles");
1150
1151   /* begin generating */
1152   block = drcuml_block_begin(drcuml, 10, &errorbuf);
1153
1154   /* generate a hash jump via the current mode and PC */
1155   alloc_handle(drcuml, &ppc->impstate->out_of_cycles, "out_of_cycles");
1156   UML_HANDLE(block, ppc->impstate->out_of_cycles);                              // handle  out_of_cycles
1157   UML_GETEXP(block, IREG(0));                                                // getexp  i0
1158   UML_MOV(block, MEM(&ppc->pc), IREG(0));                                       // mov     <pc>,i0
1159   save_fast_iregs(block);                                                   // <save fastregs>
1160   UML_EXIT(block, IMM(EXECUTE_OUT_OF_CYCLES));                                 // exit    EXECUTE_OUT_OF_CYCLES
1161
1162   drcuml_block_end(block);
9111163}
9121164
9131165
9141166/*-------------------------------------------------
915    code_log_add_entry - add an entry to the log
1167    static_generate_tlb_mismatch - generate a
1168    TLB mismatch handler
9161169-------------------------------------------------*/
9171170
918INLINE void code_log_add_entry(UINT32 pc, UINT32 op, void *base)
1171static void static_generate_tlb_mismatch(drcuml_state *drcuml)
9191172{
920   code_log_buffer[code_log_index].pc = pc;
921   code_log_buffer[code_log_index].op = op;
922   code_log_buffer[code_log_index].base = base;
923   code_log_index++;
1173   drcuml_block *block;
1174   jmp_buf errorbuf;
1175   int isi, label = 1;
1176
1177   /* if we get an error back, we're screwed */
1178   if (setjmp(errorbuf) != 0)
1179      fatalerror("Unrecoverable error in static_generate_tlb_mismatch");
1180
1181   /* forward references */
1182   alloc_handle(drcuml, &ppc->impstate->exception[EXCEPTION_ISI], "exception_isi");
1183   if (ppc->cap & PPCCAP_603_MMU)
1184      alloc_handle(drcuml, &ppc->impstate->exception[EXCEPTION_ITLBMISS], "exception_itlb_miss");
1185
1186   /* begin generating */
1187   block = drcuml_block_begin(drcuml, 20, &errorbuf);
1188
1189   /* generate a hash jump via the current mode and PC */
1190   alloc_handle(drcuml, &ppc->impstate->tlb_mismatch, "tlb_mismatch");
1191   UML_HANDLE(block, ppc->impstate->tlb_mismatch);                                 // handle  tlb_mismatch
1192   UML_RECOVER(block, IREG(0), MAPVAR_PC);                                       // recover i0,PC
1193   UML_MOV(block, MEM(&ppc->param0), IREG(0));                                    // mov     [param0],i0
1194   UML_MOV(block, MEM(&ppc->param1), IMM(TRANSLATE_FETCH));                        // mov     [param1],TRANSLATE_FETCH
1195   UML_CALLC(block, ppccom_tlb_fill, ppc);                                       // callc   tlbfill,ppc
1196   UML_CMP(block, MEM(&ppc->param0), IMM(1));                                    // cmp     [param0],1
1197   UML_JMPc(block, IF_A, isi = label++);                                       // jmp     isi,A
1198   save_fast_iregs(block);                                                   // <save fastregs>
1199   UML_EXIT(block, IMM(EXECUTE_MISSING_CODE));                                    // exit    EXECUTE_MISSING_CODE
1200   UML_LABEL(block, isi);                                                // isi:
1201   if (!(ppc->cap & PPCCAP_603_MMU))
1202   {
1203      UML_MOV(block, SPR32(SPROEA_DSISR), MEM(&ppc->param0));                        // mov     [dsisr],[param0]
1204      UML_EXH(block, ppc->impstate->exception[EXCEPTION_ISI], IREG(0));               // exh     isi,i0
1205   }
1206   else
1207   {
1208      UML_MOV(block, SPR32(SPR603_IMISS), IREG(0));                              // mov     [imiss],i0
1209      UML_MOV(block, SPR32(SPR603_ICMP), MEM(&ppc->mmu603_cmp));                     // mov     [icmp],[mmu603_cmp]
1210      UML_MOV(block, SPR32(SPR603_HASH1), MEM(&ppc->mmu603_hash[0]));                  // mov     [hash1],[mmu603_hash][0]
1211      UML_MOV(block, SPR32(SPR603_HASH2), MEM(&ppc->mmu603_hash[1]));                  // mov     [hash2],[mmu603_hash][1]
1212      UML_EXH(block, ppc->impstate->exception[EXCEPTION_ITLBMISS], IREG(0));            // exh     itlbmiss,i0
1213   }
1214
1215   drcuml_block_end(block);
9241216}
9251217
9261218
9271219/*-------------------------------------------------
928    code_log - actually log some code
1220    static_generate_exception - generate a static
1221    exception handler
9291222-------------------------------------------------*/
9301223
931static void code_log(const char *label, x86code *start, x86code *stop)
1224static void static_generate_exception(drcuml_state *drcuml, UINT8 exception, int recover, const char *name)
9321225{
933   extern int i386_dasm_one(char *buffer, UINT32 eip, UINT8 *oprom, int mode);
934   offs_t ppc_dasm_one(char *buffer, UINT32 pc, UINT32 op);
935   UINT8 *cur = start;
1226   drcuml_codehandle **exception_handle = recover ? &ppc->impstate->exception[exception] : &ppc->impstate->exception_norecover[exception];
1227   UINT32 vector = exception << 8;
1228   drcuml_codelabel label = 1;
1229   drcuml_block *block;
1230   jmp_buf errorbuf;
9361231
937   /* open the file, creating it if necessary */
938   if (!open_logfile())
939      return;
940   fprintf(logfile, "\n%s\n", label);
1232   /* if we get an error back, we're screwed */
1233   if (setjmp(errorbuf) != 0)
1234      fatalerror("Unrecoverable error in static_generate_exception");
9411235
942   /* loop from the start until the cache top */
943   while (cur < stop)
1236   /* begin generating */
1237   block = drcuml_block_begin(drcuml, 1024, &errorbuf);
1238
1239   /* add a global entry for this */
1240   alloc_handle(drcuml, exception_handle, name);
1241   UML_HANDLE(block, *exception_handle);                                       // handle  name
1242
1243   /* exception parameter is expected to be the fault address in this case */
1244   if (exception == EXCEPTION_ISI || exception == EXCEPTION_DSI)
9441245   {
945      char buffer[100];
946      int bytes;
947      int op;
1246      UML_GETEXP(block, IREG(0));                                             // getexp  i0
1247      UML_MOV(block, SPR32(SPROEA_DAR), IREG(0));                                 // mov     [dar],i0
1248   }
9481249
949      /* skip filler opcodes */
950      if (*cur == 0xcc)
1250   /* fetch the PC and uncounted cycles */
1251   if (recover)
1252   {
1253      UML_RECOVER(block, IREG(0), MAPVAR_PC);                                    // recover i0,PC
1254      UML_RECOVER(block, IREG(1), MAPVAR_CYCLES);                                 // recover i1,CYCLES
1255   }
1256
1257   /* OEA handling of SRR exceptions */
1258   if (ppc->cap & PPCCAP_OEA)
1259   {
1260      UINT32 msrandmask = MSROEA_POW | MSR_EE | MSR_PR | MSROEA_FP | MSROEA_FE0 | MSROEA_SE | MSROEA_BE | MSROEA_FE1 | MSROEA_IR | MSROEA_DR | MSROEA_RI | MSR_LE;
1261      UINT32 msrormask = 0;
1262
1263      /* check registers to see the real source of our exception (EI exceptions only) */
1264      UML_MOV(block, IREG(3), IMM(vector));                                    // mov     i3,vector
1265      if (exception == EXCEPTION_EI)
9511266      {
952         cur++;
953         continue;
1267         drcuml_codelabel not_decrementer;
1268
1269         UML_TEST(block, MEM(&ppc->irq_pending), IMM(0x01));                        // test    [irq_pending],0x01
1270         UML_JMPc(block, IF_NZ, not_decrementer = label++);                        // jmp     not_decrementer,nz
1271         UML_MOV(block, IREG(3), IMM(EXCEPTION_DECREMENT << 8));                     // mov     i3,EXCEPTION_DECREMENT << 8
1272         UML_AND(block, MEM(&ppc->irq_pending), MEM(&ppc->irq_pending), IMM(~0x02));      // and     [irq_pending],[irq_pending],~0x02
1273         UML_LABEL(block, not_decrementer);                                 // not_decrementer:
9541274      }
9551275
956      /* disassemble this instruction */
957#ifdef PTR64
958      bytes = i386_dasm_one(buffer, (UINT32)(FPTR)cur, cur, 64) & DASMFLAG_LENGTHMASK;
959#else
960      bytes = i386_dasm_one(buffer, (UINT32)cur, cur, 32) & DASMFLAG_LENGTHMASK;
961#endif
1276      /* exception PC goes into SRR0 */
1277      UML_MOV(block, SPR32(SPROEA_SRR0), IREG(0));                              // mov     [srr0],i0
9621278
963      /* look for a match in the registered opcodes */
964      for (op = 0; op < code_log_index; op++)
965         if (code_log_buffer[op].base == (void *)cur)
966            break;
1279      /* MSR bits go into SRR1, along with some exception-specific data */
1280      UML_AND(block, SPR32(SPROEA_SRR1), MSR32, IMM(0x87c0ffff));                     // and     [srr1],[msr],0x87c0ffff
1281      if (exception == EXCEPTION_PROGRAM)
1282      {
1283         UML_GETEXP(block, IREG(1));                                          // getexp  i1
1284         UML_OR(block, SPR32(SPROEA_SRR1), SPR32(SPROEA_SRR1), IREG(1));               // or      [srr1],[srr1],i1
1285      }
1286      if (ppc->cap & PPCCAP_603_MMU)
1287      {
1288         if (exception == EXCEPTION_ITLBMISS)
1289            UML_OR(block, SPR32(SPROEA_SRR1), SPR32(SPROEA_SRR1), IMM(0x00040000));      // or      [srr1],0x00040000
1290         else if (exception == EXCEPTION_DTLBMISSL)
1291            UML_OR(block, SPR32(SPROEA_SRR1), SPR32(SPROEA_SRR1), IMM(0x00010000));      // or      [srr1],0x00010000
1292         if (exception == EXCEPTION_ITLBMISS || exception == EXCEPTION_DTLBMISSL || exception == EXCEPTION_DTLBMISSS)
1293            UML_ROLINS(block, SPR32(SPROEA_SRR1), CR32, IMM(0), IMM(CRMASK(0)));      // rolins  [srr1],[cr],0,crmask(0)
1294      }
9671295
968      /* if no match, just output the current instruction */
969      if (op == code_log_index)
970         fprintf(logfile, "%p: %s\n", cur, buffer);
1296      /* update MSR */
1297      if (ppc->cap & PPCCAP_603_MMU)
1298      {
1299         if (exception == EXCEPTION_ITLBMISS || exception == EXCEPTION_DTLBMISSL || exception == EXCEPTION_DTLBMISSS)
1300            msrormask |= MSR603_TGPR;
1301         else
1302            msrandmask |= MSR603_TGPR;
1303         UML_MOV(block, IREG(0), MSR32);                                       // mov     i0,[msr]
1304      }
1305      UML_AND(block, IREG(2), MSR32, IMM(~msrandmask));                           // and     i2,[msr],~andmask
1306      UML_OR(block, IREG(2), IREG(2), IMM(msrormask));                           // or      i2,i2,ormask
1307      UML_ROLINS(block, IREG(2), IREG(2), IMM(16), IMM(MSR_LE));                     // rolins  i2,u2,16,MSR_LE
1308      UML_MOV(block, MSR32, IREG(2));                                          // mov     [msr],i2
1309      if (ppc->cap & PPCCAP_603_MMU)
1310      {
1311         UML_XOR(block, IREG(0), IREG(0), IREG(2));                              // xor     i0,i0,i2
1312         UML_TEST(block, IREG(0), IMM(MSR603_TGPR));                              // test    i0,tgpr
1313         UML_CALLHc(block, IF_NZ, ppc->impstate->swap_tgpr);                        // callh   swap_tgpr,nz
1314      }
1315      generate_update_mode(block);                                          // <update mode>
9711316
972      /* otherwise, output with the original instruction to the right */
1317      /* determine our target PC */
1318      UML_MOV(block, IREG(0), IMM(0x00000000));                                 // mov     i0,0x00000000
1319      UML_TEST(block, MSR32, IMM(MSROEA_IP));                                    // test    [msr],IP
1320      UML_MOVc(block, IF_NZ, IREG(0), IMM(0xfff00000));                           // mov     i0,0xfff00000,nz
1321      UML_OR(block, IREG(0), IREG(0), IREG(3));                                 // or      i0,i0,i3
1322   }
1323
1324   /* 4XX handling of exceptions */
1325   if (ppc->cap & PPCCAP_4XX)
1326   {
1327      /* check registers to see the real source of our exception (EI exceptions only) */
1328      UML_MOV(block, IREG(3), IMM(vector));                                    // mov     i3,vector
1329      if (exception == EXCEPTION_EI)
1330      {
1331         drcuml_codelabel notwdog, common;
1332
1333         UML_TEST(block, SPR32(SPR4XX_TSR), IMM(PPC4XX_TSR_PIS));                  // test    [tsr],PIS
1334         UML_MOVc(block, IF_NZ, IREG(3), IMM(0x1000));                           // mov     i3,0x1000,NZ
1335         UML_TEST(block, SPR32(SPR4XX_TSR), IMM(PPC4XX_TSR_FIS));                  // test    [tsr],FIS
1336         UML_MOVc(block, IF_NZ, IREG(3), IMM(0x1010));                           // mov     i3,0x1010,NZ
1337         UML_TEST(block, SPR32(DCR4XX_EXISR), SPR32(DCR4XX_EXIER));                  // test    [exisr],[exier]
1338         UML_MOVc(block, IF_NZ, IREG(3), IMM(vector));                           // mov     i3,vector,NZ
1339         UML_TEST(block, SPR32(SPR4XX_TSR), IMM(PPC4XX_TSR_WIS));                  // test    [tsr],WIS
1340         UML_JMPc(block, IF_Z, notwdog = label++);                              // jz      notwdog
1341         UML_MOV(block, IREG(3), IMM(0x1020));                                 // mov     i3,0x1020
1342
1343         /* exception PC goes into SRR2, MSR goes to SRR3 */
1344         UML_MOV(block, SPR32(SPR4XX_SRR2), IREG(0));                           // mov     [srr2],i0
1345         UML_MOV(block, SPR32(SPR4XX_SRR3), MSR32);                              // mov     [srr3],[msr]
1346         UML_AND(block, IREG(2), MSR32, IMM(~(MSR4XX_WE | MSR_PR | MSR4XX_CE | MSR_EE | MSR4XX_DE | MSR4XX_PE)));
1347         UML_JMP(block, common = label++);                                    // jmp     common
1348
1349         /* exception PC goes into SRR0, MSR goes to SRR1 */
1350         UML_LABEL(block, notwdog);                                       // notwdog:
1351         UML_MOV(block, SPR32(SPR4XX_SRR0), IREG(0));                           // mov     [srr0],i0
1352         UML_MOV(block, SPR32(SPR4XX_SRR1), MSR32);                              // mov     [srr1],[msr]
1353         UML_AND(block, IREG(2), MSR32, IMM(~(MSR4XX_WE | MSR_PR | MSR_EE | MSR4XX_PE)));// and     i2,[msr],~(bunch-o-flags)
1354         UML_LABEL(block, common);                                       // common:
1355      }
9731356      else
9741357      {
975         char buffer2[100];
976         ppc_dasm_one(buffer2, code_log_buffer[op].pc, code_log_buffer[op].op);
977         fprintf(logfile, "%p: %-50s %08X: %s\n", cur, buffer, code_log_buffer[op].pc, buffer2);
1358         /* exception PC goes into SRR0, MSR goes to SRR1 */
1359         UML_MOV(block, SPR32(SPR4XX_SRR0), IREG(0));                           // mov     [srr0],i0
1360         UML_MOV(block, SPR32(SPR4XX_SRR1), MSR32);                              // mov     [srr1],[msr]
1361         UML_AND(block, IREG(2), MSR32, IMM(~(MSR4XX_WE | MSR_PR | MSR_EE | MSR4XX_PE)));// and     i2,[msr],~(bunch-o-flags)
9781362      }
9791363
980      /* advance past this instruction */
981      cur += bytes;
1364      /* finish updating MSR */
1365      UML_ROLINS(block, IREG(2), IREG(2), IMM(16), IMM(MSR_LE));                     // rolins  i2,u2,16,MSR_LE
1366      UML_MOV(block, MSR32, IREG(2));                                          // mov     [msr],i2
1367      generate_update_mode(block);                                          // <update mode>
1368
1369      /* program exception flags go to ESR */
1370      if (exception == EXCEPTION_PROGRAM)
1371      {
1372         UML_GETEXP(block, IREG(1));                                          // getexp  i1
1373         UML_SHL(block, SPR32(SPR4XX_ESR), IREG(1), IMM(8));                        // shl     [esr],i1,8
1374      }
1375
1376      /* determine our target PC */
1377      UML_ROLINS(block, IREG(3), SPR32(SPR4XX_EVPR), IMM(0), IMM(0xffff0000));         // rolins  i3,[evpr],0,0xffff0000
1378      UML_MOV(block, IREG(0), IREG(3));                                       // mov     i0,i3
9821379   }
9831380
984   /* flush the file */
985   fflush(logfile);
1381   /* optionally print exceptions */
1382   if ((PRINTF_EXCEPTIONS && exception != EXCEPTION_EI && exception != EXCEPTION_SYSCALL) ||
1383      (PRINTF_MMU && (exception == EXCEPTION_ISI || exception == EXCEPTION_DSI)))
1384   {
1385      UML_MOV(block, MEM(&ppc->param0), IMM(exception));                           // mov     [param0],exception
1386      UML_CALLC(block, cfunc_printf_exception, NULL);                              // callc   cfunc_printf_exception,NULL
1387   }
1388
1389   /* adjust cycles */
1390   UML_SUBf(block, MEM(&ppc->icount), MEM(&ppc->icount), IREG(1), FLAGS_S);             // sub     icount,icount,cycles,S
1391   UML_EXHc(block, IF_S, ppc->impstate->out_of_cycles, IREG(0));                     // exh     out_of_cycles,i0
1392   UML_HASHJMP(block, MEM(&ppc->impstate->mode), IREG(0), ppc->impstate->nocode);         // hashjmp <mode>,i0,nocode
1393
1394   drcuml_block_end(block);
9861395}
9871396
988#else
9891397
990#define code_log_reset()
991#define code_log_add_entry(a,b,c)
992#define code_log(a,b,c)
1398/*------------------------------------------------------------------
1399    static_generate_memory_accessor
1400------------------------------------------------------------------*/
9931401
994#endif
1402static void static_generate_memory_accessor(drcuml_state *drcuml, int mode, int size, int iswrite, int ismasked, const char *name, drcuml_codehandle **handleptr, drcuml_codehandle *masked)
1403{
1404   /* on entry, address is in I0; data for writes is in I1; masks are in I2 */
1405   /* on exit, read result is in I0 */
1406   /* routine trashes I0-I3 */
1407   int fastxor = BYTE8_XOR_BE(0) >> (activecpu_databus_width(ADDRESS_SPACE_PROGRAM) < 64);
1408   drcuml_block *block;
1409   jmp_buf errorbuf;
1410   int tlbreturn = 0;
1411   int unaligned = 0;
1412   int alignex = 0;
1413   int tlbmiss = 0;
1414   int label = 1;
1415   int ramnum;
9951416
1417   /* if we get an error back, we're screwed */
1418   if (setjmp(errorbuf) != 0)
1419      fatalerror("Unrecoverable error in static_generate_exception");
9961420
997/********************************************************************/
1421   /* begin generating */
1422   block = drcuml_block_begin(drcuml, 1024, &errorbuf);
9981423
999#include "ppc_ops.c"
1000#include "drc_ops.c"
1001#include "drc_ops.h"
1424   /* add a global entry for this */
1425   alloc_handle(drcuml, handleptr, name);
1426   UML_HANDLE(block, *handleptr);                                             // handle  *handleptr
10021427
1003/* Initialization and shutdown */
1428   /* check for unaligned accesses and break into two */
1429   if (!ismasked && size != 1)
1430   {
1431      /* in little-endian mode, anything misaligned generates an exception */
1432      if ((mode & MODE_LITTLE_ENDIAN) || masked == NULL || !(ppc->cap & PPCCAP_MISALIGNED))
1433      {
1434         UML_TEST(block, IREG(0), IMM(size - 1));                              // test    i0,size-1
1435         UML_JMPc(block, IF_NZ, alignex = label++);                              // jmp     alignex,nz
1436      }
10041437
1005static void ppc_init(void)
1006{
1007   int i,j;
1438      /* in big-endian mode, it's more complicated */
1439      else
1440      {
1441         /* 8-byte accesses must be word-aligned */
1442         if (size == 8)
1443         {
1444            UML_TEST(block, IREG(0), IMM(3));                                 // test    i0,3
1445            UML_JMPc(block, IF_NZ, alignex = label++);                           // jmp     alignex,nz
1446         }
10081447
1009   for( i=0; i < 64; i++ ) {
1010      ppc.optable[i] = recompile_invalid;
1448         /* unaligned 2 and 4 byte accesses need to be broken up */
1449         else
1450         {
1451            UML_TEST(block, IREG(0), IMM(size - 1));                           // test    i0,size-1
1452            UML_JMPc(block, IF_NZ, unaligned = label++);                        // jmp     unaligned,nz
1453         }
1454      }
10111455   }
1012   for( i=0; i < 1024; i++ ) {
1013      ppc.optable19[i] = recompile_invalid;
1014      ppc.optable31[i] = recompile_invalid;
1015      ppc.optable59[i] = recompile_invalid;
1016      ppc.optable63[i] = recompile_invalid;
1456
1457   /* general case: assume paging and perform a translation */
1458   if ((ppc->cap & PPCCAP_OEA) && (mode & MODE_DATA_TRANSLATION))
1459   {
1460      UML_SHR(block, IREG(3), IREG(0), IMM(12));                                 // shr     i3,i0,12
1461      UML_LOAD(block, IREG(3), ppc->tlb_table, IREG(3), DWORD);                     // load    i3,[tlb_table],i3,dword
1462      UML_TEST(block, IREG(3), IMM(iswrite ? TLB_WRITE : TLB_READ));                  // test    i3,iswrite ? TLB_WRITE : TLB_READ
1463      UML_JMPc(block, IF_Z, tlbmiss = label++);                                 // jmp     tlbmiss,z
1464      UML_LABEL(block, tlbreturn = label++);                                 // tlbreturn:
1465      UML_ROLINS(block, IREG(0), IREG(3), IMM(0), IMM(0xfffff000));                  // rolins  i0,i3,0,0xfffff000
10171466   }
1467   UML_XOR(block, IREG(0), IREG(0), IMM((mode & MODE_LITTLE_ENDIAN) ? (8 - size) : 0));   // xor     i0,i0,8-size
10181468
1019   /* Fill the opcode tables */
1020   for( i=0; i < (sizeof(ppcdrc_opcode_common) / sizeof(PPC_OPCODE)); i++ ) {
1021
1022      switch(ppcdrc_opcode_common[i].code)
1469   for (ramnum = 0; ramnum < PPC_MAX_FASTRAM; ramnum++)
1470      if (!Machine->debug_mode && ppc->impstate->fastram[ramnum].base != NULL && (!iswrite || !ppc->impstate->fastram[ramnum].readonly))
10231471      {
1024         case 19:
1025            ppc.optable19[ppcdrc_opcode_common[i].subcode] = ppcdrc_opcode_common[i].handler;
1026            break;
1472         void *fastbase = (UINT8 *)ppc->impstate->fastram[ramnum].base - ppc->impstate->fastram[ramnum].start;
1473         UINT32 skip = label++;
10271474
1028         case 31:
1029            ppc.optable31[ppcdrc_opcode_common[i].subcode] = ppcdrc_opcode_common[i].handler;
1030            break;
1475         if (ppc->impstate->fastram[ramnum].end != 0xffffffff)
1476         {
1477            UML_CMP(block, IREG(0), IMM(ppc->impstate->fastram[ramnum].end));         // cmp     i0,end
1478            UML_JMPc(block, IF_A, skip);                                    // ja      skip
1479         }
1480         if (ppc->impstate->fastram[ramnum].start != 0x00000000)
1481         {
1482            UML_CMP(block, IREG(0), IMM(ppc->impstate->fastram[ramnum].start));         // cmp     i0,fastram_start
1483            UML_JMPc(block, IF_B, skip);                                    // jb      skip
1484         }
10311485
1032         case 59:
1033         case 63:
1034            break;
1486         if (!iswrite)
1487         {
1488            if (size == 1)
1489            {
1490               UML_XOR(block, IREG(0), IREG(0), IMM(fastxor >> 0));               // xor     i0,i0,fastxor >> 0
1491               UML_LOAD(block, IREG(0), fastbase, IREG(0), BYTE);                  // load    i0,fastbase,i0,byte
1492            }
1493            else if (size == 2)
1494            {
1495               UML_SHR(block, IREG(0), IREG(0), IMM(1));                        // shr     i0,i0,1
1496               UML_XOR(block, IREG(0), IREG(0), IMM(fastxor >> 1));               // xor     i0,i0,fastxor >> 1
1497               UML_LOAD(block, IREG(0), fastbase, IREG(0), WORD);                  // load    i0,fastbase,i0,word
1498            }
1499            else if (size == 4)
1500            {
1501               UML_SHR(block, IREG(0), IREG(0), IMM(2));                        // shr     i0,i0,2
1502               UML_XOR(block, IREG(0), IREG(0), IMM(fastxor >> 2));               // xor     i0,i0,fastxor >> 2
1503               UML_LOAD(block, IREG(0), fastbase, IREG(0), DWORD);                  // load    i0,fastbase,i0,dword
1504            }
1505            else if (size == 8)
1506            {
1507               UML_SHR(block, IREG(0), IREG(0), IMM(3));                        // shr     i0,i0,3
1508               UML_DLOAD(block, IREG(0), fastbase, IREG(0), QWORD);               // dload   i0,fastbase,i0,qword
1509            }
1510            UML_RET(block);                                                // ret
1511         }
1512         else
1513         {
1514            if (size == 1)
1515            {
1516               UML_XOR(block, IREG(0), IREG(0), IMM(fastxor >> 0));               // xor     i0,i0,fastxor >> 0
1517               UML_STORE(block, fastbase, IREG(0), IREG(1), BYTE);                  // store   fastbase,i0,i1,byte
1518            }
1519            else if (size == 2)
1520            {
1521               UML_SHR(block, IREG(0), IREG(0), IMM(1));                        // shr     i0,i0,1
1522               UML_XOR(block, IREG(0), IREG(0), IMM(fastxor >> 1));               // xor     i0,i0,fastxor >> 1
1523               UML_STORE(block, fastbase, IREG(0), IREG(1), WORD);                  // store   fastbase,i0,i1,word
1524            }
1525            else if (size == 4)
1526            {
1527               UML_SHR(block, IREG(0), IREG(0), IMM(2));                        // shr     i0,i0,2
1528               UML_XOR(block, IREG(0), IREG(0), IMM(fastxor >> 2));               // xor     i0,i0,fastxor >> 2
1529               if (ismasked)
1530               {
1531                  UML_LOAD(block, IREG(3), fastbase, IREG(0), DWORD);               // load    i3,fastbase,i0,dword
1532                  UML_AND(block, IREG(1), IREG(1), IREG(2));                     // and     i1,i1,i2
1533                  UML_XOR(block, IREG(2), IREG(2), IMM(0xffffffff));               // xor     i2,i2,0xfffffffff
1534                  UML_AND(block, IREG(3), IREG(3), IREG(2));                     // and     i3,i3,i2
1535                  UML_OR(block, IREG(1), IREG(1), IREG(3));                     // or      i1,i1,i3
1536               }
1537               UML_STORE(block, fastbase, IREG(0), IREG(1), DWORD);               // store   fastbase,i0,i1,dword
1538            }
1539            else if (size == 8)
1540            {
1541               UML_SHR(block, IREG(0), IREG(0), IMM(3));                        // shr     i0,i0,3
1542               if (ismasked)
1543               {
1544                  UML_DLOAD(block, IREG(3), fastbase, IREG(0), QWORD);            // dload   i3,fastbase,i0,qword
1545                  UML_DAND(block, IREG(1), IREG(1), IREG(2));                     // dand    i1,i1,i2
1546                  UML_DXOR(block, IREG(2), IREG(2), IMM(U64(0xffffffffffffffff)));   // dxor    i2,i2,0xfffffffffffffffff
1547                  UML_DAND(block, IREG(3), IREG(3), IREG(2));                     // dand    i3,i3,i2
1548                  UML_DOR(block, IREG(1), IREG(1), IREG(3));                     // dor     i1,i1,i3
1549               }
1550               UML_DSTORE(block, fastbase, IREG(0), IREG(1), QWORD);               // dstore  fastbase,i0,i1,qword
1551            }
1552            UML_RET(block);                                                // ret
1553         }
10351554
1036         default:
1037            ppc.optable[ppcdrc_opcode_common[i].code] = ppcdrc_opcode_common[i].handler;
1555         UML_LABEL(block, skip);                                          // skip:
10381556      }
10391557
1558   switch (size)
1559   {
1560      case 1:
1561         if (iswrite)
1562            UML_WRITE(block, IREG(0), IREG(1), PROGRAM_BYTE);                     // write   i0,i1,program_byte
1563         else
1564            UML_READ(block, IREG(0), IREG(0), PROGRAM_BYTE);                     // read    i0,i0,program_byte
1565         break;
1566
1567      case 2:
1568         if (iswrite)
1569         {
1570            if (!ismasked)
1571               UML_WRITE(block, IREG(0), IREG(1), PROGRAM_WORD);                  // write   i0,i1,program_word
1572            else
1573               UML_WRITEM(block, IREG(0), IREG(2), IREG(1), PROGRAM_WORD);            // writem  i0,i2,i1,program_word
1574         }
1575         else
1576         {
1577            if (!ismasked)
1578               UML_READ(block, IREG(0), IREG(0), PROGRAM_WORD);                  // read    i0,i0,program_word
1579            else
1580               UML_READM(block, IREG(0), IREG(0), IREG(2), PROGRAM_WORD);            // readm   i0,i0,i2,program_word
1581         }
1582         break;
1583
1584      case 4:
1585         if (iswrite)
1586         {
1587            if (!ismasked)
1588               UML_WRITE(block, IREG(0), IREG(1), PROGRAM_DWORD);                  // write   i0,i1,program_dword
1589            else
1590               UML_WRITEM(block, IREG(0), IREG(2), IREG(1), PROGRAM_DWORD);         // writem  i0,i2,i1,program_dword
1591         }
1592         else
1593         {
1594            if (!ismasked)
1595               UML_READ(block, IREG(0), IREG(0), PROGRAM_DWORD);                  // read    i0,i0,program_dword
1596            else
1597               UML_READM(block, IREG(0), IREG(0), IREG(2), PROGRAM_DWORD);            // readm   i0,i0,i2,program_dword
1598         }
1599         break;
1600
1601      case 8:
1602         if (iswrite)
1603         {
1604            if (!ismasked)
1605               UML_DWRITE(block, IREG(0), IREG(1), PROGRAM_QWORD);                  // dwrite  i0,i1,program_qword
1606            else
1607               UML_DWRITEM(block, IREG(0), IREG(2), IREG(1), PROGRAM_QWORD);         // dwritem i0,i2,i1,program_qword
1608         }
1609         else
1610         {
1611            if (!ismasked)
1612               UML_DREAD(block, IREG(0), IREG(0), PROGRAM_QWORD);                  // dread   i0,i0,program_qword
1613            else
1614               UML_DREADM(block, IREG(0), IREG(0), IREG(2), PROGRAM_QWORD);         // dreadm  i0,i0,i2,program_qword
1615         }
1616         break;
10401617   }
1618   UML_RET(block);                                                         // ret
10411619
1042   /* Calculate rotate mask table */
1043   for( i=0; i < 32; i++ ) {
1044      for( j=0; j < 32; j++ ) {
1045         UINT32 mask;
1046         int mb = i;
1047         int me = j;
1048         mask = ((UINT32)0xFFFFFFFF >> mb) ^ ((me >= 31) ? 0 : ((UINT32)0xFFFFFFFF >> (me + 1)));
1049         if( mb > me )
1050            mask = ~mask;
1620   /* handle unaligned accesses */
1621   if (unaligned != 0)
1622   {
1623      UML_LABEL(block, unaligned);                                       // unaligned:
1624      if (size == 2)
1625      {
1626         if (iswrite)
1627         {
1628            UML_MOV(block, MEM(&ppc->impstate->tempaddr), IREG(0));                  // mov     [tempaddr],i0
1629            UML_MOV(block, MEM(&ppc->impstate->tempdata), IREG(1));                  // mov     [tempdata],i1
1630            UML_SUB(block, IREG(0), IREG(0), IMM(1));                           // sub     i0,i0,1
1631            UML_SHR(block, IREG(1), IREG(1), IMM(8));                           // shr     i1,i1,8
1632            UML_MOV(block, IREG(2), IMM(0x00ff));                              // mov     i2,0x00ff
1633            UML_CALLH(block, masked);                                       // callh   masked
1634            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(1));            // add     i0,[tempaddr],1
1635            UML_SHL(block, IREG(1), MEM(&ppc->impstate->tempdata), IMM(8));            // shl     i1,[tempdata],8
1636            UML_MOV(block, IREG(2), IMM(0xff00));                              // mov     i2,0xff00
1637            UML_CALLH(block, masked);                                       // callh   masked
1638         }
1639         else
1640         {
1641            UML_MOV(block, MEM(&ppc->impstate->tempaddr), IREG(0));                  // mov     [tempaddr],i0
1642            UML_SUB(block, IREG(0), IREG(0), IMM(1));                           // sub     i0,i0,1
1643            UML_MOV(block, IREG(2), IMM(0x00ff));                              // mov     i2,0x00ff
1644            UML_CALLH(block, masked);                                       // callh   masked
1645            UML_SHL(block, MEM(&ppc->impstate->tempdata), IREG(0), IMM(8));            // shl     [tempdata],i0,8
1646            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(1));            // add     i0,[tempaddr],1
1647            UML_MOV(block, IREG(2), IMM(0xff00));                              // mov     i2,0xff00
1648            UML_CALLH(block, masked);                                       // callh   masked
1649            UML_SHR(block, IREG(0), IREG(0), IMM(8));                           // shr     i0,i0,8
1650            UML_OR(block, IREG(0), IREG(0), MEM(&ppc->impstate->tempdata));            // or      i0,i0,[tempdata]
1651         }
1652      }
1653      else if (size == 4)
1654      {
1655         int offs2, offs3;
1656         if (iswrite)
1657         {
1658            UML_MOV(block, MEM(&ppc->impstate->tempaddr), IREG(0));                  // mov     [tempaddr],i0
1659            UML_MOV(block, MEM(&ppc->impstate->tempdata), IREG(1));                  // mov     [tempdata],i1
1660            UML_TEST(block, IREG(0), IMM(2));                                 // test    i0,i0,2
1661            UML_JMPc(block, IF_NZ, offs2 = label++);                           // jnz     offs2
1662            UML_SUB(block, IREG(0), IREG(0), IMM(1));                           // sub     i0,i0,1
1663            UML_SHR(block, IREG(1), IREG(1), IMM(8));                           // shr     i1,i1,8
1664            UML_MOV(block, IREG(2), IMM(0x00ffffff));                           // mov     i2,0x00ffffff
1665            UML_CALLH(block, masked);                                       // callh   masked
1666            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(3));            // add     i0,[tempaddr],3
1667            UML_SHL(block, IREG(1), MEM(&ppc->impstate->tempdata), IMM(24));         // shl     i1,[tempdata],24
1668            UML_MOV(block, IREG(2), IMM(0xff000000));                           // mov     i2,0xff000000
1669            UML_CALLH(block, masked);                                       // callh   masked
1670            UML_RET(block);                                                // ret
1671            UML_LABEL(block, offs2);                                    // offs2:
1672            UML_TEST(block, IREG(0), IMM(1));                                 // test    i0,i0,1
1673            UML_JMPc(block, IF_NZ, offs3 = label++);                           // jnz     offs3
1674            UML_SUB(block, IREG(0), IREG(0), IMM(2));                           // sub     i0,i0,2
1675            UML_SHR(block, IREG(1), IREG(1), IMM(16));                           // shr     i1,i1,16
1676            UML_MOV(block, IREG(2), IMM(0x0000ffff));                           // mov     i2,0x0000ffff
1677            UML_CALLH(block, masked);                                       // callh   masked
1678            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(2));            // add     i0,[tempaddr],2
1679            UML_SHL(block, IREG(1), MEM(&ppc->impstate->tempdata), IMM(16));         // shl     i1,[tempdata],16
1680            UML_MOV(block, IREG(2), IMM(0xffff0000));                           // mov     i2,0xffff0000
1681            UML_CALLH(block, masked);                                       // callh   masked
1682            UML_RET(block);                                                // ret
1683            UML_LABEL(block, offs3);                                    // offs3:
1684            UML_SUB(block, IREG(0), IREG(0), IMM(3));                           // sub     i0,i0,3
1685            UML_SHR(block, IREG(1), IREG(1), IMM(24));                           // shr     i1,i1,24
1686            UML_MOV(block, IREG(2), IMM(0x000000ff));                           // mov     i2,0x000000ff
1687            UML_CALLH(block, masked);                                       // callh   masked
1688            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(1));            // add     i0,[tempaddr],1
1689            UML_SHL(block, IREG(1), MEM(&ppc->impstate->tempdata), IMM(8));            // shl     i1,[tempdata],8
1690            UML_MOV(block, IREG(2), IMM(0xffffff00));                           // mov     i2,0xffffff00
1691            UML_CALLH(block, masked);                                       // callh   masked
1692         }
1693         else
1694         {
1695            UML_MOV(block, MEM(&ppc->impstate->tempaddr), IREG(0));                  // mov     [tempaddr],i0
1696            UML_TEST(block, IREG(0), IMM(2));                                 // test    i0,i0,2
1697            UML_JMPc(block, IF_NZ, offs2 = label++);                           // jnz     offs2
1698            UML_SUB(block, IREG(0), IREG(0), IMM(1));                           // sub     i0,i0,1
1699            UML_MOV(block, IREG(2), IMM(0x00ffffff));                           // mov     i2,0x00ffffff
1700            UML_CALLH(block, masked);                                       // callh   masked
1701            UML_SHL(block, MEM(&ppc->impstate->tempdata), IREG(0), IMM(8));            // shl     [tempdata],i0,8
1702            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(3));            // add     i0,[tempaddr],3
1703            UML_MOV(block, IREG(2), IMM(0xff000000));                           // mov     i2,0xff000000
1704            UML_CALLH(block, masked);                                       // callh   masked
1705            UML_SHR(block, IREG(0), IREG(0), IMM(24));                           // shr     i0,i0,24
1706            UML_OR(block, IREG(0), IREG(0), MEM(&ppc->impstate->tempdata));            // or      i0,i0,[tempdata]
1707            UML_RET(block);                                                // ret
1708            UML_LABEL(block, offs2);                                    // offs2:
1709            UML_TEST(block, IREG(0), IMM(1));                                 // test    i0,i0,1
1710            UML_JMPc(block, IF_NZ, offs3 = label++);                           // jnz     offs3
1711            UML_SUB(block, IREG(0), IREG(0), IMM(2));                           // sub     i0,i0,2
1712            UML_MOV(block, IREG(2), IMM(0x0000ffff));                           // mov     i2,0x0000ffff
1713            UML_CALLH(block, masked);                                       // callh   masked
1714            UML_SHL(block, MEM(&ppc->impstate->tempdata), IREG(0), IMM(16));         // shl     [tempdata],i0,16
1715            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(2));            // add     i0,[tempaddr],2
1716            UML_MOV(block, IREG(2), IMM(0xffff0000));                           // mov     i2,0xffff0000
1717            UML_CALLH(block, masked);                                       // callh   masked
1718            UML_SHR(block, IREG(0), IREG(0), IMM(16));                           // shr     i0,i0,16
1719            UML_OR(block, IREG(0), IREG(0), MEM(&ppc->impstate->tempdata));            // or      i0,i0,[tempdata]
1720            UML_RET(block);                                                // ret
1721            UML_LABEL(block, offs3);                                    // offs3:
1722            UML_SUB(block, IREG(0), IREG(0), IMM(3));                           // sub     i0,i0,3
1723            UML_MOV(block, IREG(2), IMM(0x000000ff));                           // mov     i2,0x000000ff
1724            UML_CALLH(block, masked);                                       // callh   masked
1725            UML_SHL(block, MEM(&ppc->impstate->tempdata), IREG(0), IMM(24));         // shl     [tempdata],i0,24
1726            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(1));            // add     i0,[tempaddr],1
1727            UML_MOV(block, IREG(2), IMM(0xffffff00));                           // mov     i2,0xffffff00
1728            UML_CALLH(block, masked);                                       // callh   masked
1729            UML_SHR(block, IREG(0), IREG(0), IMM(8));                           // shr     i0,i0,8
1730            UML_OR(block, IREG(0), IREG(0), MEM(&ppc->impstate->tempdata));            // or      i0,i0,[tempdata]
1731         }
1732      }
1733      UML_RET(block);                                                      // ret
1734   }
10511735
1052         ppc_rotate_mask[i][j] = mask;
1736   /* handle an alignment exception */
1737   if (alignex != 0)
1738   {
1739      UML_LABEL(block, alignex);                                          // alignex:
1740      UML_RECOVER(block, SPR32(SPROEA_DSISR), MAPVAR_DSISR);                        // recover [dsisr],DSISR
1741      UML_EXH(block, ppc->impstate->exception[EXCEPTION_ALIGN], IREG(0));               // exh     align,i0
1742   }
1743
1744   /* handle a TLB miss */
1745   if (tlbmiss != 0)
1746   {
1747      int dsi;
1748
1749      UML_LABEL(block, tlbmiss);                                          // tlbmiss:
1750      UML_MOV(block, MEM(&ppc->param0), IREG(0));                                 // mov     [param0],i0
1751      UML_MOV(block, MEM(&ppc->param1), IMM(iswrite ? TRANSLATE_WRITE : TRANSLATE_READ));   // mov     [param1],TRANSLATE_READ/WRITE
1752      UML_CALLC(block, ppccom_tlb_fill, ppc);                                    // callc   tlbfill,ppc
1753      UML_CMP(block, MEM(&ppc->param0), IMM(1));                                 // cmp     [param0],1
1754      UML_JMPc(block, IF_A, dsi = label++);                                    // jmp     dsi,A
1755      UML_SHR(block, IREG(3), IREG(0), IMM(12));                                 // shr     i3,i0,12
1756      UML_LOAD(block, IREG(3), ppc->tlb_table, IREG(3), DWORD);                     // load    i3,[tlb_table],i3,dword
1757      UML_JMP(block, tlbreturn);                                             // jmp     tlbreturn
1758      UML_LABEL(block, dsi);                                             // dsi:
1759      if (!(ppc->cap & PPCCAP_603_MMU))
1760      {
1761         UML_MOV(block, SPR32(SPROEA_DSISR), MEM(&ppc->param0));                     // mov     [dsisr],[param0]
1762         UML_EXH(block, ppc->impstate->exception[EXCEPTION_DSI], IREG(0));            // exh     dsi,i0
10531763      }
1764      else
1765      {
1766         UML_MOV(block, SPR32(SPR603_DMISS), IREG(0));                           // mov     [dmiss],i0
1767         UML_MOV(block, SPR32(SPR603_DCMP), MEM(&ppc->mmu603_cmp));                  // mov     [dcmp],[mmu603_cmp]
1768         UML_MOV(block, SPR32(SPR603_HASH1), MEM(&ppc->mmu603_hash[0]));               // mov     [hash1],[mmu603_hash][0]
1769         UML_MOV(block, SPR32(SPR603_HASH2), MEM(&ppc->mmu603_hash[1]));               // mov     [hash2],[mmu603_hash][1]
1770         if (iswrite)
1771            UML_EXH(block, ppc->impstate->exception[EXCEPTION_DTLBMISSS], IREG(0));      // exh     dtlbmisss,i0
1772         else
1773            UML_EXH(block, ppc->impstate->exception[EXCEPTION_DTLBMISSL], IREG(0));      // exh     dtlbmissl,i0
1774      }
10541775   }
1776
1777   drcuml_block_end(block);
10551778}
10561779
1057#if (HAS_PPC403)
1058static void ppcdrc403_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1780
1781/*-------------------------------------------------
1782    static_generate_swap_tgpr - generate a
1783    subroutine to swap GPR0-3 with TGPR0-3
1784-------------------------------------------------*/
1785
1786static void static_generate_swap_tgpr(drcuml_state *drcuml)
10591787{
1060   const ppc_config *config = _config;
1788   drcuml_block *block;
1789   jmp_buf errorbuf;
1790   int regnum;
10611791
1062   ppc_init();
1063   ppcdrc_init();
1792   /* if we get an error back, we're screwed */
1793   if (setjmp(errorbuf) != 0)
1794      fatalerror("Unrecoverable error in static_generate_swap_tgpr");
10641795
1065   /* PPC403 specific opcodes */
1066   ppc.optable31[454] = recompile_dccci;
1067   ppc.optable31[486] = recompile_dcread;
1068   ppc.optable31[262] = recompile_icbt;
1069   ppc.optable31[966] = recompile_iccci;
1070   ppc.optable31[998] = recompile_icread;
1071   ppc.optable31[323] = recompile_mfdcr;
1072   ppc.optable31[451] = recompile_mtdcr;
1073   ppc.optable31[131] = recompile_wrtee;
1074   ppc.optable31[163] = recompile_wrteei;
1075   ppc.optable19[51] = recompile_rfci;
1796   /* begin generating */
1797   block = drcuml_block_begin(drcuml, 30, &errorbuf);
10761798
1077   ppc.spu.rx_timer = timer_alloc(ppc403_spu_rx_callback, NULL);
1078   ppc.spu.tx_timer = timer_alloc(ppc403_spu_tx_callback, NULL);
1799   /* generate a hash jump via the current mode and PC */
1800   alloc_handle(drcuml, &ppc->impstate->swap_tgpr, "swap_tgpr");
1801   UML_HANDLE(block, ppc->impstate->swap_tgpr);                                 // handle  swap_tgpr
1802   for (regnum = 0; regnum < 4; regnum++)
1803   {
1804      UML_MOV(block, IREG(1), R32(regnum));                                    // mov     i1,r[regnum]
1805      UML_MOV(block, R32(regnum), MEM(&ppc->mmu603_r[regnum]));                     // mov     r[regnum],mmu603_r[regnum]
1806      UML_MOV(block, MEM(&ppc->mmu603_r[regnum]), IREG(1));                        // mov     mmu603_r[regnum],i1
1807   }
1808   UML_RET(block);                                                         // ret
10791809
1080   ppc.is603 = 0;
1081   ppc.is602 = 0;
1810   drcuml_block_end(block);
1811}
10821812
1083   ppc.read8 = ppc403_read8;
1084   ppc.read16 = ppc403_read16;
1085   ppc.read32 = ppc403_read32;
1086   ppc.write8 = ppc403_write8;
1087   ppc.write16 = ppc403_write16;
1088   ppc.write32 = ppc403_write32;
1089   ppc.read16_unaligned = ppc403_read16_unaligned;
1090   ppc.read32_unaligned = ppc403_read32_unaligned;
1091   ppc.write16_unaligned = ppc403_write16_unaligned;
1092   ppc.write32_unaligned = ppc403_write32_unaligned;
10931813
1094   ppc.irq_callback = irqcallback;
10951814
1096   ppc.pvr = config->pvr;
1097}
1815/***************************************************************************
1816    CODE GENERATION
1817***************************************************************************/
10981818
1099static void ppcdrc403_exit(void)
1819/*-------------------------------------------------
1820    generate_update_mode - update the mode based
1821    on the MSR
1822-------------------------------------------------*/
1823
1824static void generate_update_mode(drcuml_block *block)
11001825{
1101#if LOG_CODE
1102   //if (symfile) fclose(symfile);
1103#endif
1104   ppcdrc_exit();
1826   UML_AND(block, IREG(0), MSR32, IMM(MSR_LE));                                 // and     i0,msr,MSR_LE
1827   UML_AND(block, IREG(1), MSR32, IMM(MSROEA_DR));                                 // and     i1,msr,MSR_DR
1828   UML_SHR(block, IREG(1), IREG(1), IMM(3));                                    // shr     i1,i1,3
1829   UML_OR(block, IREG(0), IREG(0), IREG(1));                                    // or      i0,i0,i1
1830   UML_AND(block, IREG(1), MSR32, IMM(MSR_PR));                                 // and     i1,msr,MSR_PR
1831   UML_SHR(block, IREG(1), IREG(1), IMM(12));                                    // shr     i1,i1,12
1832   UML_OR(block, MEM(&ppc->impstate->mode), IREG(0), IREG(1));                        // or      [mode],i0,i1
11051833}
11061834
1107static void ppcdrc403_reset(void)
1835
1836/*-------------------------------------------------
1837    generate_update_cycles - generate code to
1838    subtract cycles from the icount and generate
1839    an exception if out
1840-------------------------------------------------*/
1841
1842static void generate_update_cycles(drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception)
11081843{
1109   ppc.pc = ppc.npc = 0xfffffffc;
1844   /* check full interrupts if pending */
1845   if (compiler->checkints)
1846   {
1847      drcuml_codelabel skip;
11101848
1111   ppc_set_msr(0);
1112   change_pc(ppc.pc);
1849      compiler->checkints = FALSE;
1850      UML_TEST(block, MEM(&ppc->irq_pending), IMM(~0));                           // test    [irq_pending],0
1851      UML_JMPc(block, IF_Z, skip = compiler->labelnum++);                           // jmp     skip,Z
1852      UML_TEST(block, MSR32, IMM(MSR_EE));                                    // test    [msr],MSR_EE
1853      UML_JMPc(block, IF_Z, skip);                                          // jmp     skip,Z
1854      UML_MOV(block, IREG(0), PARAM(ptype, pvalue));                              // mov     i0,nextpc
1855      UML_MOV(block, IREG(1), IMM(compiler->cycles));                              // mov     i1,cycles
1856      UML_CALLH(block, ppc->impstate->exception_norecover[EXCEPTION_EI]);               // callh   interrupt_norecover
1857      UML_LABEL(block, skip);                                             // skip:
1858   }
11131859
1114   /* reset the DRC */
1115   drc_cache_reset(ppc.drc);
1860   /* account for cycles */
1861   if (compiler->cycles > 0)
1862   {
1863      UML_SUBf(block, MEM(&ppc->icount), MEM(&ppc->icount), MAPVAR_CYCLES, allow_exception ? FLAGS_S : 0);
1864                                                                     // sub     icount,icount,cycles,S
1865      UML_MAPVAR(block, MAPVAR_CYCLES, 0);                                    // mapvar  cycles,0
1866      if (allow_exception)
1867         UML_EXHc(block, IF_S, ppc->impstate->out_of_cycles, PARAM(ptype, pvalue));      // exh     out_of_cycles,nextpc
1868   }
1869   compiler->cycles = 0;
11161870}
11171871
1118static int ppcdrc403_execute(int cycles)
1872
1873/*-------------------------------------------------
1874    generate_checksum_block - generate code to
1875    validate a sequence of opcodes
1876-------------------------------------------------*/
1877
1878static void generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast)
11191879{
1120   /* count cycles and interrupt cycles */
1121   ppc_icount = cycles;
1122   ppc_tb_base_icount = cycles;
1880   const opcode_desc *curdesc;
1881   if (LOG_UML)
1882      UML_COMMENT(block, "[Validation for %08X]", seqhead->pc);                     // comment
11231883
1124   ppc_fit_trigger_cycle = 0x7fffffff;
1884   /* loose verify or single instruction: just compare and fail */
1885   if (!(ppc->impstate->drcoptions & PPCDRC_STRICT_VERIFY) || seqhead->next == NULL)
1886   {
1887      if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
1888      {
1889         UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD);                  // load    i0,*opptr,dword
1890         UML_CMP(block, IREG(0), IMM(*seqhead->opptr.l));                        // cmp     i0,*opptr
1891         UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc));            // exne    nocode,seqhead->pc
1892      }
1893   }
11251894
1126   if (ppc.fit_int_enable)
1895   /* full verification; sum up everything */
1896   else
11271897   {
1128      UINT32 tb = (UINT32)ppc.tb;
1129      UINT32 fit_cycles = 0;
1898#if 0
1899      for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
1900         if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
1901         {
1902            UML_LOAD(block, IREG(0), curdesc->opptr.l, IMM(0), DWORD);               // load    i0,*opptr,dword
1903            UML_CMP(block, IREG(0), IMM(*curdesc->opptr.l));                     // cmp     i0,*opptr
1904            UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc));         // exne    nocode,seqhead->pc
1905         }
1906#else
1907      UINT32 sum = 0;
1908      UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD);                     // load    i0,*opptr,dword
1909      sum += *seqhead->opptr.l;
1910      for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
1911         if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
1912         {
1913            UML_LOAD(block, IREG(1), curdesc->opptr.l, IMM(0), DWORD);               // load    i1,*opptr,dword
1914            UML_ADD(block, IREG(0), IREG(0), IREG(1));                           // add     i0,i0,i1
1915            sum += *curdesc->opptr.l;
1916         }
1917      UML_CMP(block, IREG(0), IMM(sum));                                       // cmp     i0,sum
1918      UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc));               // exne    nocode,seqhead->pc
1919#endif
1920   }
1921}
11301922
1131      if (ppc.tb & ppc.fit_bit)
1923
1924/*-------------------------------------------------
1925    generate_sequence_instruction - generate code
1926    for a single instruction in a sequence
1927-------------------------------------------------*/
1928
1929static void generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1930{
1931   int hotnum;
1932
1933   /* add an entry for the log */
1934   if (LOG_UML && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
1935      log_add_disasm_comment(block, desc->pc, *desc->opptr.l);
1936
1937   /* set the PC map variable */
1938   UML_MAPVAR(block, MAPVAR_PC, desc->pc);                                       // mapvar  PC,desc->pc
1939
1940   /* accumulate total cycles */
1941   compiler->cycles += desc->cycles;
1942
1943   /* is this a hotspot? */
1944   for (hotnum = 0; hotnum < PPC_MAX_HOTSPOTS; hotnum++)
1945      if (ppc->impstate->hotspot[hotnum].pc != 0 && desc->pc == ppc->impstate->hotspot[hotnum].pc && *desc->opptr.l == ppc->impstate->hotspot[hotnum].opcode)
11321946      {
1133         fit_cycles += ppc.fit_bit;
1134         tb += fit_cycles;
1947         compiler->cycles += ppc->impstate->hotspot[hotnum].cycles;
1948         break;
11351949      }
11361950
1137      fit_cycles += ppc.fit_bit - (tb & (ppc.fit_bit-1));
1951   /* update the icount map variable */
1952   UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles);                              // mapvar  CYCLES,compiler->cycles
11381953
1139      ppc_fit_trigger_cycle = ppc_icount - fit_cycles;
1954   /* if we want a probe, add it here */
1955   if (desc->pc == PROBE_ADDRESS)
1956      UML_CALLC(block, cfunc_printf_probe, desc->pc);                              // callc   cfunc_printf_probe,desc->pc
1957
1958   /* if we are debugging, call the debugger */
1959   if (Machine->debug_mode)
1960   {
1961      UML_MOV(block, MEM(&ppc->pc), IMM(desc->pc));                              // mov     [pc],desc->pc
1962      save_fast_iregs(block);                                                // <save fastregs>
1963      UML_DEBUG(block, IMM(desc->pc));                                       // debug   desc->pc
11401964   }
11411965
1142   drc_execute(ppc.drc);
1966   /* if we hit an unmapped address, fatal error */
1967   if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
1968   {
1969      UML_MOV(block, MEM(&ppc->pc), IMM(desc->pc));                              // mov     [pc],desc->pc
1970      save_fast_iregs(block);                                                // <save fastregs>
1971      UML_EXIT(block, IMM(EXECUTE_UNMAPPED_CODE));                              // exit    EXECUTE_UNMAPPED_CODE
1972   }
11431973
1144   // update timebase
1145   ppc.tb += (ppc_tb_base_icount - ppc_icount);
1974   /* if we hit a compiler page fault, it's just like a TLB mismatch */
1975   if (desc->flags & OPFLAG_COMPILER_PAGE_FAULT)
1976   {
1977      if (PRINTF_MMU)
1978      {
1979         UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(desc->pc));                  // mov     [arg0],desc->pc
1980         UML_CALLC(block, cfunc_printf_debug, "Compiler page fault @ %08X\n");         // callc   printf_debug
1981      }
1982      UML_EXH(block, ppc->impstate->tlb_mismatch, IMM(0));                        // exh     tlb_mismatch,0
1983   }
11461984
1147   return cycles - ppc_icount;
1148}
1149
1150static void ppcdrc403_set_irq_line(int irqline, int state)
1151{
1152   if (irqline >= INPUT_LINE_IRQ0 && irqline <= INPUT_LINE_IRQ4)
1985   /* validate our TLB entry at this PC; if we fail, we need to handle it */
1986   if ((desc->flags & OPFLAG_VALIDATE_TLB) && (ppc->impstate->mode & MODE_DATA_TRANSLATION))
11531987   {
1154      UINT32 mask = (1 << (4 - irqline));
1155      if( state == ASSERT_LINE) {
1156         if (EXIER & mask)
1988      /* if we currently have a valid TLB read entry, we just verify */
1989      if (ppc->tlb_table[desc->pc >> 12] != 0)
1990      {
1991         if (PRINTF_MMU)
11571992         {
1158            ppc.exisr |= mask;
1159            ppc.exception_pending |= 0x1;
1160
1161            if (ppc.irq_callback)
1162            {
1163               ppc.irq_callback(irqline);
1164            }
1993            UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(desc->pc));               // mov     [arg0],desc->pc
1994            UML_CALLC(block, cfunc_printf_debug, "Checking TLB at @ %08X\n");         // callc   printf_debug
11651995         }
1996         UML_LOAD(block, IREG(0), &ppc->tlb_table[desc->pc >> 12], IMM(0), DWORD);      // load    i0,tlb_table[desc->pc >> 12],dword
1997         UML_CMP(block, IREG(0), IMM(ppc->tlb_table[desc->pc >> 12]));               // cmp     i0,*tlbentry
1998         UML_EXHc(block, IF_NE, ppc->impstate->tlb_mismatch, IMM(0));               // exh     tlb_mismatch,0,NE
11661999      }
1167      // clear line is used to clear the interrupt when the interrupts are level-sensitive
1168      else if (state == CLEAR_LINE)
2000
2001      /* otherwise, we generate an unconditional exception */
2002      else
11692003      {
1170         ppc.exisr &= ~mask;
1171      }
1172   }
1173   else if (irqline == PPC403_SPU_RX)
1174   {
1175      UINT32 mask = 0x08000000;
1176      if (state) {
1177         if( EXIER & mask ) {
1178            ppc.exisr |= mask;
1179            ppc.exception_pending |= 0x1;
2004         if (PRINTF_MMU)
2005         {
2006            UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(desc->pc));                  // mov     [arg0],desc->pc
2007            UML_CALLC(block, cfunc_printf_debug, "No valid TLB @ %08X\n");            // callc   printf_debug
11802008         }
2009         UML_EXH(block, ppc->impstate->tlb_mismatch, IMM(0));                              // exh     tlb_mismatch,0
11812010      }
11822011   }
1183   else if (irqline == PPC403_SPU_TX)
2012
2013   /* if this is an invalid opcode, generate the exception now */
2014   if (desc->flags & OPFLAG_INVALID_OPCODE)
2015      UML_EXH(block, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x80000));                  // exh    exception_program,0x80000
2016
2017   /* if this is a privileged opcode in user mode, generate the exception */
2018   else if ((desc->flags & OPFLAG_PRIVILEGED) && (ppc->impstate->mode & MODE_USER))
2019      UML_EXH(block, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x40000));                  // exh    exception_program,0x40000
2020
2021   /* otherwise, unless this is a virtual no-op, it's a regular instruction */
2022   else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
11842023   {
1185      UINT32 mask = 0x04000000;
1186      if (state) {
1187         if( EXIER & mask ) {
1188            ppc.exisr |= mask;
1189            ppc.exception_pending |= 0x1;
1190         }
2024      /* compile the instruction */
2025      if (!generate_opcode(block, compiler, desc))
2026      {
2027         UML_MOV(block, MEM(&ppc->pc), IMM(desc->pc));                        // mov     [pc],desc->pc
2028         UML_CALLC(block, cfunc_unimplemented, (void *)(FPTR)*desc->opptr.l);         // callc   cfunc_unimplemented
11912029      }
11922030   }
1193   else
1194   {
1195      fatalerror("PPC: Unknown IRQ line %d", irqline);
1196   }
11972031}
1198#endif
11992032
1200#if (HAS_PPC603)
1201static void ppcdrc603_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1202{
1203   int pll_config = 0;
1204   float multiplier;
1205   const ppc_config *config = _config;
1206   int i;
12072033
1208   ppc_init();
1209   ppcdrc_init();
2034/*------------------------------------------------------------------
2035    generate_compute_flags - compute CR0 and/or XER flags
2036------------------------------------------------------------------*/
12102037
1211   ppc.optable[48] = recompile_lfs;
1212   ppc.optable[49] = recompile_lfsu;
1213   ppc.optable[50] = recompile_lfd;
1214   ppc.optable[51] = recompile_lfdu;
1215   ppc.optable[52] = recompile_stfs;
1216   ppc.optable[53] = recompile_stfsu;
1217   ppc.optable[54] = recompile_stfd;
1218   ppc.optable[55] = recompile_stfdu;
1219   ppc.optable31[631] = recompile_lfdux;
1220   ppc.optable31[599] = recompile_lfdx;
1221   ppc.optable31[567] = recompile_lfsux;
1222   ppc.optable31[535] = recompile_lfsx;
1223   ppc.optable31[595] = recompile_mfsr;
1224   ppc.optable31[659] = recompile_mfsrin;
1225   ppc.optable31[371] = recompile_mftb;
1226   ppc.optable31[210] = recompile_mtsr;
1227   ppc.optable31[242] = recompile_mtsrin;
1228   ppc.optable31[758] = recompile_dcba;
1229   ppc.optable31[759] = recompile_stfdux;
1230   ppc.optable31[727] = recompile_stfdx;
1231   ppc.optable31[983] = recompile_stfiwx;
1232   ppc.optable31[695] = recompile_stfsux;
1233   ppc.optable31[663] = recompile_stfsx;
1234   ppc.optable31[370] = recompile_tlbia;
1235   ppc.optable31[306] = recompile_tlbie;
1236   ppc.optable31[566] = recompile_tlbsync;
1237   ppc.optable31[310] = recompile_eciwx;
1238   ppc.optable31[438] = recompile_ecowx;
2038static void generate_compute_flags(drcuml_block *block, int updatecr, UINT32 xermask, int invertcarry)
2039{
2040   int xerflags = ((xermask & XER_OV) ? DRCUML_FLAG_V : 0) | ((xermask & XER_CA) ? DRCUML_FLAG_C : 0);
2041   UINT32 xermask_so = xermask | ((xermask & XER_OV) ? XER_SO : 0);
12392042
1240   ppc.optable63[264] = recompile_fabsx;
1241   ppc.optable63[21] = recompile_faddx;
1242   ppc.optable63[32] = recompile_fcmpo;
1243   ppc.optable63[0] = recompile_fcmpu;
1244   ppc.optable63[14] = recompile_fctiwx;
1245   ppc.optable63[15] = recompile_fctiwzx;
1246   ppc.optable63[18] = recompile_fdivx;
1247   ppc.optable63[72] = recompile_fmrx;
1248   ppc.optable63[136] = recompile_fnabsx;
1249   ppc.optable63[40] = recompile_fnegx;
1250   ppc.optable63[12] = recompile_frspx;
1251   ppc.optable63[26] = recompile_frsqrtex;
1252   ppc.optable63[22] = recompile_fsqrtx;
1253   ppc.optable63[20] = recompile_fsubx;
1254   ppc.optable63[583] = recompile_mffsx;
1255   ppc.optable63[70] = recompile_mtfsb0x;
1256   ppc.optable63[38] = recompile_mtfsb1x;
1257   ppc.optable63[711] = recompile_mtfsfx;
1258   ppc.optable63[134] = recompile_mtfsfix;
1259   ppc.optable63[64] = recompile_mcrfs;
2043   /* easy case: nothing to do */
2044   if (!updatecr && xermask == 0)
2045      return;
12602046
1261   ppc.optable59[21] = recompile_faddsx;
1262   ppc.optable59[18] = recompile_fdivsx;
1263   ppc.optable59[24] = recompile_fresx;
1264   ppc.optable59[22] = recompile_fsqrtsx;
1265   ppc.optable59[20] = recompile_fsubsx;
1266
1267   for(i = 0; i < 32; i++)
2047   /* semi-easy case: crfield only */
2048   if (xermask == 0)
12682049   {
1269      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1270      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1271      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1272      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1273      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1274      ppc.optable63[i * 32 | 23] = recompile_fselx;
1275
1276      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1277      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1278      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1279      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1280      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
2050      UML_MOV(block, IREG(0), CR32);                                          // mov     i0,cr32
2051      UML_GETFLGS(block, IREG(1), DRCUML_FLAG_S | DRCUML_FLAG_Z);                     // getflgs i1,sz
2052      UML_LOAD(block, IREG(1), ppc->impstate->sz_cr_table, IREG(1), DWORD);            // load    i1,sz_cr_table,i1,dword
2053      UML_ROLINS(block, IREG(0), IREG(1), IMM(0), IMM(CRMASK(0)));                  // rolins  i0,i1,0,crmask(field)
2054      UML_AND(block, IREG(1), SPR32(SPR_XER), IMM(XER_SO));                        // and     i1,[xer],XER_SO
2055      UML_SHR(block, IREG(1), IREG(1), IMM(3));                                 // shr     i1,i1,3
2056      UML_OR(block, CR32, IREG(0), IREG(1));                                    // or      [cr],i0,i1
2057      return;
12812058   }
12822059
1283#if (HAS_PPC602 || HAS_MPC8240)
1284   ppc.optable31[978] = recompile_tlbld;
1285#endif /* (HAS_PPC602 || HAS_MPC8240) */
1286
1287   for(i = 0; i < 256; i++)
2060   /* semi-easy case: xer only */
2061   if (!updatecr)
12882062   {
1289      ppc_field_xlat[i] =
1290         ((i & 0x80) ? 0xF0000000 : 0) |
1291         ((i & 0x40) ? 0x0F000000 : 0) |
1292         ((i & 0x20) ? 0x00F00000 : 0) |
1293         ((i & 0x10) ? 0x000F0000 : 0) |
1294         ((i & 0x08) ? 0x0000F000 : 0) |
1295         ((i & 0x04) ? 0x00000F00 : 0) |
1296         ((i & 0x02) ? 0x000000F0 : 0) |
1297         ((i & 0x01) ? 0x0000000F : 0);
2063      if (xermask & XER_OV)
2064      {
2065         UML_MOV(block, IREG(0), SPR32(SPR_XER));                              // mov     i0,[xer]
2066         UML_GETFLGS(block, IREG(1), xerflags);                                 // getflgs i1,xerflags
2067         if (invertcarry && (xermask & XER_CA))
2068            UML_XOR(block, IREG(1), IREG(1), IMM(DRCUML_FLAG_C));                  // xor     i1,i1,FLAG_C
2069         UML_ROLINS(block, IREG(0), IREG(1), IMM(29), IMM(xermask));                  // rolins  i0,i1,29,crmask(xermask)
2070         UML_AND(block, IREG(1), SPR32(SPR_XER), IMM(XER_OV));                     // and     i1,[xer],XER_OV
2071         UML_SHL(block, IREG(1), IREG(1), IMM(1));                              // shl     i1,i1,1
2072         UML_OR(block, SPR32(SPR_XER), IREG(0), IREG(1));                        // or      [xer],i0,i1
2073      }
2074      else
2075      {
2076         UML_SETc(block, invertcarry ? IF_NC : IF_C, IREG(0));                     // setc    i0,nc/c
2077         UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(XER_CA));            // rolins  [xer],i0,29,XER_CA
2078      }
2079      return;
12982080   }
12992081
1300   ppc.is603 = 1;
2082   /* tricky case: both */
2083   UML_GETFLGS(block, IREG(0), DRCUML_FLAG_S | DRCUML_FLAG_Z | xerflags);               // getflgs i0,sz|xerflags
2084   if (invertcarry)
2085      UML_XOR(block, IREG(2), IREG(2), IMM(DRCUML_FLAG_C));                        // xor     i2,i2,FLAG_C
2086   UML_LOAD(block, IREG(0), ppc->impstate->sz_cr_table, IREG(0), DWORD);               // load    i0,sz_cr_table,i0,dword
2087   UML_AND(block, IREG(1), SPR32(SPR_XER), IMM(~xermask));                           // and     i1,[xer],~xermask
2088   UML_SHL(block, IREG(2), IREG(0), IMM(4));                                    // shl     i2,i0,4
2089   if (xermask_so != (XER_CA | XER_OV | XER_SO))
2090      UML_AND(block, IREG(2), IREG(2), IMM(xermask_so));                           // and     i2,i2,xermask
2091   UML_OR(block, IREG(1), IREG(1), IREG(2));                                    // or      i1,i1,i2
2092   UML_MOV(block, SPR32(SPR_XER), IREG(1));                                    // mov     [xer],i1
2093   UML_SHR(block, IREG(1), IREG(1), IMM(3));                                    // shr     i1,i1,3
2094   UML_OR(block, IREG(0), IREG(0), IREG(1));                                    // or      i0,i0,i1
2095   UML_AND(block, IREG(1), CR32, IMM(~CRMASK(0)));                                 // and     i1,[cr],~crmask(0)
2096   UML_AND(block, IREG(0), IREG(0), IMM(CRMASK(0)));                              // and     i0,i0,crmask(0)
2097   UML_OR(block, CR32, IREG(0), IREG(1));                                       // or      cr32,i0,i1
2098}
13012099
1302   ppc.read8 = program_read_byte_64be;
1303   ppc.read16 = program_read_word_64be;
1304   ppc.read32 = program_read_dword_64be;
1305   ppc.read64 = program_read_qword_64be;
1306   ppc.write8 = program_write_byte_64be;
1307   ppc.write16 = program_write_word_64be;
1308   ppc.write32 = program_write_dword_64be;
1309   ppc.write64 = program_write_qword_64be;
1310   ppc.read16_unaligned = ppc_read16_unaligned;
1311   ppc.read32_unaligned = ppc_read32_unaligned;
1312   ppc.read64_unaligned = ppc_read64_unaligned;
1313   ppc.write16_unaligned = ppc_write16_unaligned;
1314   ppc.write32_unaligned = ppc_write32_unaligned;
1315   ppc.write64_unaligned = ppc_write64_unaligned;
13162100
1317   ppc.irq_callback = irqcallback;
2101/*-------------------------------------------------
2102    generate_branch - generate an unconditional
2103    branch
2104-------------------------------------------------*/
13182105
1319   ppc.pvr = config->pvr;
2106static void generate_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int source, UINT8 link)
2107{
2108   compiler_state compiler_temp = *compiler;
13202109
1321   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1322             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1323   bus_freq_multiplier = (int)(multiplier * 2);
2110   /* set the link if needed */
2111   if (link)
2112      UML_MOV(block, SPR32(SPR_LR), IMM(desc->pc + 4));                           // mov     [lr],desc->pc + 4
13242113
1325   switch(config->pvr)
2114   /* update the cycles and jump through the hash table to the target */
2115   if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
13262116   {
1327      case PPC_MODEL_603E:   pll_config = mpc603e_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1328      case PPC_MODEL_603EV:   pll_config = mpc603ev_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1329      case PPC_MODEL_603R:   pll_config = mpc603r_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1330      default: break;
2117      generate_update_cycles(block, &compiler_temp, IMM(desc->targetpc), TRUE);         // <subtract cycles>
2118      if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
2119         UML_JMP(block, desc->targetpc | 0x80000000);                           // jmp     desc->targetpc | 0x80000000
2120      else
2121         UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(desc->targetpc), ppc->impstate->nocode);      // hashjmp <mode>,desc->targetpc,nocode
13312122   }
2123   else
2124   {
2125UML_CMP(block, SPR32(source), IMM(0xb032));
2126UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(desc->pc));
2127UML_CALLCc(block, IF_E, cfunc_printf_debug, "b032 @ PC=%08X\n");
13322128
1333   if (pll_config == -1)
1334   {
1335      fatalerror("PPC: Invalid bus/multiplier combination (bus frequency = %d, multiplier = %1.1f)", config->bus_frequency, multiplier);
2129      generate_update_cycles(block, &compiler_temp, SPR32(source), TRUE);               // <subtract cycles>
2130      UML_HASHJMP(block, IMM(ppc->impstate->mode), SPR32(source), ppc->impstate->nocode);            // hashjmp <mode>,<rsreg>,nocode
13362131   }
13372132
1338   ppc.hid1 = pll_config << 28;
1339}
2133   /* update the label */
2134   compiler->labelnum = compiler_temp.labelnum;
13402135
1341static void ppcdrc603_exit(void)
1342{
1343#if LOG_CODE
1344   //if (symfile) fclose(symfile);
1345#endif
1346   ppcdrc_exit();
2136   /* reset the mapvar to the current cycles */
2137   UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles);                              // mapvar  CYCLES,compiler->cycles
13472138}
1348#endif
13492139
1350#if (HAS_PPC601 || HAS_PPC603 || HAS_MPC8240 || HAS_PPC604)
1351static void ppcdrc603_reset(void)
1352{
1353   ppc.pc = ppc.npc = 0xfff00100;
13542140
1355   ppc_set_msr(0x40);
1356   change_pc(ppc.pc);
2141/*-------------------------------------------------
2142    generate_branch_bo - generate a conditional
2143    branch based on the BO and BI fields
2144-------------------------------------------------*/
13572145
1358   /* reset the DRC */
1359   drc_cache_reset(ppc.drc);
1360}
1361
1362static int ppcdrc603_execute(int cycles)
2146static void generate_branch_bo(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 bo, UINT32 bi, int source, int link)
13632147{
1364   /* count cycles and interrupt cycles */
1365   ppc_icount = cycles;
1366   ppc_tb_base_icount = cycles;
1367   ppc_dec_base_icount = cycles + ppc.dec_frac;
2148   int skip = compiler->labelnum++;
13682149
1369   // check if decrementer exception occurs during execution
1370   if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC))
2150   if (!(bo & 0x04))
13712151   {
1372      ppc_dec_trigger_cycle = ppc_icount - DEC;
2152      UML_SUBf(block, SPR32(SPR_CTR), SPR32(SPR_CTR), IMM(1), FLAGS_Z);               // sub   [ctr],[ctr],1,z
2153      UML_JMPc(block, (bo & 0x02) ? IF_NZ : IF_Z, skip);                           // jmp   skip,nz/z
13732154   }
1374   else
2155   if (!(bo & 0x10))
13752156   {
1376      ppc_dec_trigger_cycle = 0x7fffffff;
2157      UML_TEST(block, CR32, IMM(0x80000000 >> bi));                              // test  cr32,0x80000000 >> bi
2158      UML_JMPc(block, (bo & 0x08) ? IF_Z : IF_NZ, skip);                           // jmp   skip,z/nz
13772159   }
2160   generate_branch(block, compiler, desc, source, link);                           // <branch>
2161   UML_LABEL(block, skip);                                                // skip:
2162}
13782163
1379   drc_execute(ppc.drc);
13802164
1381   // update timebase
1382   // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly
1383   ppc.tb += ((ppc_tb_base_icount - ppc_icount) / 4);
2165/*-------------------------------------------------
2166    generate_opcode - generate code for a specific
2167    opcode
2168-------------------------------------------------*/
13842169
1385   // update decrementer
1386   ppc.dec_frac = ((ppc_dec_base_icount - ppc_icount) % (bus_freq_multiplier * 2));
1387   DEC -= ((ppc_dec_base_icount - ppc_icount) / (bus_freq_multiplier * 2));
2170static int generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
2171{
2172   UINT32 op = *desc->opptr.l;
2173   UINT32 opswitch = op >> 26;
2174   int regnum;
13882175
1389   return cycles - ppc_icount;
1390}
2176   switch (opswitch)
2177   {
2178      case 0x02:   /* TDI - 64-bit only */
2179      case 0x1e:   /* 0x1e group - 64-bit only */
2180      case 0x3a:   /* 0x3a group - 64-bit only */
2181      case 0x3e:   /* 0x3e group - 64-bit only */
2182         return FALSE;
13912183
1392static void ppcdrc603_set_irq_line(int irqline, int state)
1393{
1394   if( state ) {
1395      ppc.exception_pending |= 0x1;
1396      if (ppc.irq_callback)
1397      {
1398         ppc.irq_callback(irqline);
1399      }
1400   }
1401}
1402#endif
2184      case 0x03:   /* TWI */
2185         UML_CMP(block, R32(G_RA(op)), IMM((INT16)G_SIMM(op)));                     // cmp     ra,simm
2186         if (G_TO(op) & 0x10)
2187            UML_EXHc(block, IF_L, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,l
2188         if (G_TO(op) & 0x08)
2189            UML_EXHc(block, IF_G, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,g
2190         if (G_TO(op) & 0x04)
2191            UML_EXHc(block, IF_E, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,e
2192         if (G_TO(op) & 0x02)
2193            UML_EXHc(block, IF_B,  ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,b
2194         if (G_TO(op) & 0x01)
2195            UML_EXHc(block, IF_A,  ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,a
2196         return TRUE;
14032197
1404#if (HAS_PPC602)
1405static void ppcdrc602_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1406{
1407   float multiplier;
1408   const ppc_config *config = _config;
1409   int i;
2198      case 0x07:   /* MULLI */
2199         UML_MULS(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));
2200                                                                     // muls    rd,rd,ra,simm
2201         return TRUE;
14102202
1411   ppc_init();
1412   ppcdrc_init();
2203      case 0x0e:   /* ADDI */
2204         UML_ADD(block, R32(G_RD(op)), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));         // add     rd,ra,simm
2205         return TRUE;
14132206
1414   ppc.optable[48] = recompile_lfs;
1415   ppc.optable[49] = recompile_lfsu;
1416   ppc.optable[50] = recompile_lfd;
1417   ppc.optable[51] = recompile_lfdu;
1418   ppc.optable[52] = recompile_stfs;
1419   ppc.optable[53] = recompile_stfsu;
1420   ppc.optable[54] = recompile_stfd;
1421   ppc.optable[55] = recompile_stfdu;
1422   ppc.optable31[631] = recompile_lfdux;
1423   ppc.optable31[599] = recompile_lfdx;
1424   ppc.optable31[567] = recompile_lfsux;
1425   ppc.optable31[535] = recompile_lfsx;
1426   ppc.optable31[595] = recompile_mfsr;
1427   ppc.optable31[659] = recompile_mfsrin;
1428   ppc.optable31[371] = recompile_mftb;
1429   ppc.optable31[210] = recompile_mtsr;
1430   ppc.optable31[242] = recompile_mtsrin;
1431   ppc.optable31[758] = recompile_dcba;
1432   ppc.optable31[759] = recompile_stfdux;
1433   ppc.optable31[727] = recompile_stfdx;
1434   ppc.optable31[983] = recompile_stfiwx;
1435   ppc.optable31[695] = recompile_stfsux;
1436   ppc.optable31[663] = recompile_stfsx;
1437   ppc.optable31[370] = recompile_tlbia;
1438   ppc.optable31[306] = recompile_tlbie;
1439   ppc.optable31[566] = recompile_tlbsync;
1440   ppc.optable31[310] = recompile_eciwx;
1441   ppc.optable31[438] = recompile_ecowx;
2207      case 0x0f:   /* ADDIS */
2208         UML_ADD(block, R32(G_RD(op)), R32Z(G_RA(op)), IMM(G_SIMM(op) << 16));         // add     rd,ra,simm << 16
2209         return TRUE;
14422210
1443   ppc.optable63[264] = recompile_fabsx;
1444   ppc.optable63[21] = recompile_faddx;
1445   ppc.optable63[32] = recompile_fcmpo;
1446   ppc.optable63[0] = recompile_fcmpu;
1447   ppc.optable63[14] = recompile_fctiwx;
1448   ppc.optable63[15] = recompile_fctiwzx;
1449   ppc.optable63[18] = recompile_fdivx;
1450   ppc.optable63[72] = recompile_fmrx;
1451   ppc.optable63[136] = recompile_fnabsx;
1452   ppc.optable63[40] = recompile_fnegx;
1453   ppc.optable63[12] = recompile_frspx;
1454   ppc.optable63[26] = recompile_frsqrtex;
1455   ppc.optable63[22] = recompile_fsqrtx;
1456   ppc.optable63[20] = recompile_fsubx;
1457   ppc.optable63[583] = recompile_mffsx;
1458   ppc.optable63[70] = recompile_mtfsb0x;
1459   ppc.optable63[38] = recompile_mtfsb1x;
1460   ppc.optable63[711] = recompile_mtfsfx;
1461   ppc.optable63[134] = recompile_mtfsfix;
1462   ppc.optable63[64] = recompile_mcrfs;
2211      case 0x0a:   /* CMPLI */
2212         UML_CMP(block, R32(G_RA(op)), IMM(G_UIMM(op)));                           // cmp     ra,uimm
2213         UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C);                  // getflgs i0,zc
2214         UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), DWORD);         // load    i0,cmpl_cr_table,i0,dword
2215         UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op))));            // rolins  cr,i0,0,crmask[cr]
2216         return TRUE;
14632217
1464   ppc.optable59[21] = recompile_faddsx;
1465   ppc.optable59[18] = recompile_fdivsx;
1466   ppc.optable59[24] = recompile_fresx;
1467   ppc.optable59[22] = recompile_fsqrtsx;
1468   ppc.optable59[20] = recompile_fsubsx;
2218      case 0x0b:   /* CMPI */
2219         UML_CMP(block, R32(G_RA(op)), IMM((INT16)G_SIMM(op)));                     // cmp     ra,uimm
2220         UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C | DRCUML_FLAG_S);      // getflgs i0,zcs
2221         UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), DWORD);         // load    i0,cmp_cr_table,i0,dword
2222         UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op))));            // rolins  cr,i0,0,crmask[cr]
2223         return TRUE;
14692224
1470   for(i = 0; i < 32; i++)
1471   {
1472      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1473      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1474      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1475      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1476      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1477      ppc.optable63[i * 32 | 23] = recompile_fselx;
2225      case 0x08:   /* SUBFIC */
2226         UML_SUBf(block, R32(G_RD(op)), IMM((INT16)G_SIMM(op)), R32(G_RA(op)), FLAGS_C);   // sub     rd,simm,ra,c
2227         generate_compute_flags(block, FALSE, XER_CA, TRUE);                        // <update flags>
2228         return TRUE;
14782229
1479      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1480      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1481      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1482      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1483      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
1484   }
2230      case 0x0c:   /* ADDIC */
2231         UML_ADDf(block, R32(G_RD(op)), R32(G_RA(op)), IMM((INT16)G_SIMM(op)), FLAGS_C);   // add     rd,ra,simm,c
2232         generate_compute_flags(block, FALSE, XER_CA, FALSE);                     // <update flags>
2233         return TRUE;
14852234
1486   for(i = 0; i < 256; i++)
1487   {
1488      ppc_field_xlat[i] =
1489         ((i & 0x80) ? 0xF0000000 : 0) |
1490         ((i & 0x40) ? 0x0F000000 : 0) |
1491         ((i & 0x20) ? 0x00F00000 : 0) |
1492         ((i & 0x10) ? 0x000F0000 : 0) |
1493         ((i & 0x08) ? 0x0000F000 : 0) |
1494         ((i & 0x04) ? 0x00000F00 : 0) |
1495         ((i & 0x02) ? 0x000000F0 : 0) |
1496         ((i & 0x01) ? 0x0000000F : 0);
1497   }
2235      case 0x0d:   /* ADDIC. */
2236         UML_ADDf(block, R32(G_RD(op)), R32(G_RA(op)), IMM((INT16)G_SIMM(op)), FLAGS_C);   // add     rd,ra,simm,c
2237         generate_compute_flags(block, TRUE, XER_CA, FALSE);                        // <update flags>
2238         return TRUE;
14982239
1499   // PPC602 specific opcodes
1500   ppc.optable31[596] = recompile_esa;
1501   ppc.optable31[628] = recompile_dsa;
1502   ppc.optable31[1010] = recompile_tlbli;
1503   ppc.optable31[978] = recompile_tlbld;
2240      case 0x10:   /* BCx */
2241         generate_branch_bo(block, compiler, desc, G_BO(op), G_BI(op), 0, op & M_LK);   // <branch conditional>
2242         return TRUE;
15042243
1505   ppc.is603 = 0;
1506   ppc.is602 = 1;
2244      case 0x11:   /* SC */
2245         UML_EXH(block, ppc->impstate->exception[EXCEPTION_SYSCALL], IMM(0));         // exh     syscall,0
2246         return TRUE;
15072247
1508   ppc.read8 = program_read_byte_64be;
1509   ppc.read16 = program_read_word_64be;
1510   ppc.read32 = program_read_dword_64be;
1511   ppc.read64 = program_read_qword_64be;
1512   ppc.write8 = program_write_byte_64be;
1513   ppc.write16 = program_write_word_64be;
1514   ppc.write32 = program_write_dword_64be;
1515   ppc.write64 = program_write_qword_64be;
1516   ppc.read16_unaligned = ppc_read16_unaligned;
1517   ppc.read32_unaligned = ppc_read32_unaligned;
1518   ppc.read64_unaligned = ppc_read64_unaligned;
1519   ppc.write16_unaligned = ppc_write16_unaligned;
1520   ppc.write32_unaligned = ppc_write32_unaligned;
1521   ppc.write64_unaligned = ppc_write64_unaligned;
2248      case 0x12:   /* Bx */
2249         generate_branch(block, compiler, desc, 0, op & M_LK);                     // <branch>
2250         return TRUE;
15222251
1523   ppc.irq_callback = irqcallback;
2252      case 0x13:   /* 0x13 group */
2253         return generate_instruction_13(block, compiler, desc);                     // <group13>
15242254
1525   ppc.pvr = config->pvr;
2255      case 0x14:   /* RLWIMIx */
2256         UML_ROLINS(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_SH(op)), IMM(compute_rlw_mask(G_MB(op), G_ME(op))));
2257                                                                     // rolins ra,rs,sh,mask
2258         if (op & M_RC)
2259         {
2260            UML_TEST(block, R32(G_RA(op)), IMM(~0));                           // test    ra,~0
2261            generate_compute_flags(block, TRUE, 0, FALSE);                        // <update flags>
2262         }
2263         return TRUE;
15262264
1527   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1528             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1529   bus_freq_multiplier = (int)(multiplier * 2);
1530}
2265      case 0x15:   /* RLWINMx */
2266         UML_ROLAND(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_SH(op)), IMM(compute_rlw_mask(G_MB(op), G_ME(op))));
2267                                                                     // roland ra,rs,sh,mask
2268         if (op & M_RC)
2269         {
2270            UML_TEST(block, R32(G_RA(op)), IMM(~0));                           // test    ra,~0
2271            generate_compute_flags(block, TRUE, 0, FALSE);                        // <update flags>
2272         }
2273         return TRUE;
15312274
1532static void ppcdrc602_exit(void)
1533{
1534#if LOG_CODE
1535   //if (symfile) fclose(symfile);
1536#endif
1537   ppcdrc_exit();
2275      case 0x17:   /* RLWNMx */
2276         UML_ROLAND(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), IMM(compute_rlw_mask(G_MB(op), G_ME(op))));
2277                                                                     // roland ra,rs,rb,mask
2278         if (op & M_RC)
2279         {
2280            UML_TEST(block, R32(G_RA(op)), IMM(~0));                           // test    ra,~0
2281            generate_compute_flags(block, TRUE, 0, FALSE);                        // <update flags>
2282         }
2283         return TRUE;
2284
2285      case 0x18:   /* ORI */
2286         UML_OR(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op)));               // or      ra,rs,uimm
2287         return TRUE;
2288
2289      case 0x19:   /* ORIS */
2290         UML_OR(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op) << 16));            // or      ra,rs,uimm << 16
2291         return TRUE;
2292
2293      case 0x1a:   /* XORI */
2294         UML_XOR(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op)));               // xor     ra,rs,uimm
2295         return TRUE;
2296
2297      case 0x1b:   /* XORIS */
2298         UML_XOR(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op) << 16));         // xor     ra,rs,uimm << 16
2299         return TRUE;
2300
2301      case 0x1c:   /* ANDI. */
2302         UML_ANDf(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op)), FLAGS_RC(op));   // and     ra,rs,uimm,FLAGS_RC
2303         generate_compute_flags(block, TRUE, 0, FALSE);                           // <update flags>
2304         return TRUE;
2305
2306      case 0x1d:   /* ANDIS. */
2307         UML_ANDf(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op) << 16), FLAGS_RC(op));// and  ra,rs,uimm << 16,FLAGS_RC
2308         generate_compute_flags(block, TRUE, 0, FALSE);                           // <update flags>
2309         return TRUE;
2310
2311      case 0x1f:   /* 0x1f group */
2312         return generate_instruction_1f(block, compiler, desc);                     // <group1f>
2313
2314      case 0x22:   /* LBZ */
2315         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2316         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2317         UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode & 3]);            // callh   read8
2318         UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xff));                        // and     rd,i0,0xff
2319         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2320         return TRUE;
2321
2322      case 0x28:   /* LHZ */
2323         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2324         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2325         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
2326         UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xffff));                     // and     rd,i0,0xffff
2327         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2328         return TRUE;
2329
2330      case 0x2a:   /* LHA */
2331         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2332         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2333         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
2334         UML_SEXT(block, R32(G_RD(op)), IREG(0), WORD);                           // sext    rd,i0,word
2335         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2336         return TRUE;
2337
2338      case 0x20:   /* LWZ */
2339         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2340         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2341         UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode & 3]);            // callh   read32
2342         UML_MOV(block, R32(G_RD(op)), IREG(0));                                 // mov     rd,i0
2343         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2344         return TRUE;
2345
2346      case 0x23:   /* LBZU */
2347         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2348         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2349         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2350         UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode & 3]);            // callh   read8
2351         UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xff));                        // and     rd,i0,0xff
2352         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2353         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2354         return TRUE;
2355
2356      case 0x29:   /* LHZU */
2357         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2358         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2359         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2360         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
2361         UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xffff));                     // and     rd,i0,0xffff
2362         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2363         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2364         return TRUE;
2365
2366      case 0x2b:   /* LHAU */
2367         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2368         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2369         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2370         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
2371         UML_SEXT(block, R32(G_RD(op)), IREG(0), WORD);                           // sext    rd,i0,word
2372         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2373         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2374         return TRUE;
2375
2376      case 0x21:   /* LWZU */
2377         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2378         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2379         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2380         UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode & 3]);            // callh   read32
2381         UML_MOV(block, R32(G_RD(op)), IREG(0));                                 // mov     rd,i0
2382         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2383         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2384         return TRUE;
2385
2386      case 0x26:   /* STB */
2387         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2388         UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xff));                        // and     i1,rs,0xff
2389         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2390         UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode & 3]);            // callh   write8
2391         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2392         return TRUE;
2393
2394      case 0x2c:   /* STH */
2395         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2396         UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xffff));                     // and     i1,rs,0xffff
2397         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2398         UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode & 3]);            // callh   write16
2399         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2400         return TRUE;
2401
2402      case 0x24:   /* STW */
2403         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2404         UML_MOV(block, IREG(1), R32(G_RS(op)));                                 // mov     i1,rs
2405         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2406         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
2407         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2408         return TRUE;
2409
2410      case 0x27:   /* STBU */
2411         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2412         UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xff));                        // and     i1,rs,0xff
2413         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2414         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2415         UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode & 3]);            // callh   write8
2416         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2417         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2418         return TRUE;
2419
2420      case 0x2d:   /* STHU */
2421         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2422         UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xffff));                     // and     i1,rs,0xffff
2423         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2424         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2425         UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode & 3]);            // callh   write16
2426         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2427         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2428         return TRUE;
2429
2430      case 0x25:   /* STWU */
2431         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2432         UML_MOV(block, IREG(1), R32(G_RS(op)));                                 // mov     i1,rs
2433         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2434         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2435         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
2436         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2437         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2438         return TRUE;
2439
2440      case 0x2e:   /* LMW */
2441         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2442         for (regnum = G_RD(op); regnum < 32; regnum++)
2443         {
2444            UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op) + 4 * (regnum - G_RD(op))));
2445                                                                     // add     i0,ra,simm + 4*(regnum-rd)
2446            UML_CALLH(block, ppc->impstate->read32align[ppc->impstate->mode & 3]);      // callh   read32align
2447            UML_MOV(block, R32(regnum), IREG(0));                              // mov     regnum,i0
2448         }
2449         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2450         return TRUE;
2451
2452      case 0x2f:   /* STMW */
2453         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2454         for (regnum = G_RS(op); regnum < 32; regnum++)
2455         {
2456            UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op) + 4 * (regnum - G_RS(op))));
2457                                                                     // add     i0,ra,simm + 4*(regnum-rs)
2458            UML_MOV(block, IREG(1), R32(regnum));                              // mov     i1,regnum
2459            UML_CALLH(block, ppc->impstate->write32align[ppc->impstate->mode & 3]);      // callh   write32align
2460         }
2461         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2462         return TRUE;
2463
2464      case 0x30:   /* LFS */
2465         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2466         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2467         UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode & 3]);            // callh   read32
2468         UML_MOV(block, MEM(&ppc->impstate->tempdata), IREG(0));                     // mov     [tempdata],i0
2469         UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata), DWORD);      // fdfrflt fd,[tempdata],dword
2470         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2471         return TRUE;
2472
2473      case 0x32:   /* LFD */
2474         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2475         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2476         UML_CALLH(block, ppc->impstate->read64[ppc->impstate->mode & 3]);            // callh   read64
2477         UML_DMOV(block, MEM(&ppc->impstate->tempdata), IREG(0));                  // dmov    [tempdata],i0
2478         UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata));               // fdmov   fd,[tempdata]
2479         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2480         return TRUE;
2481
2482      case 0x31:   /* LFSU */
2483         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2484         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2485         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2486         UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode & 3]);            // callh   read32
2487         UML_MOV(block, MEM(&ppc->impstate->tempdata), IREG(0));                     // mov     [tempdata],i0
2488         UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata), DWORD);      // fdfrflt fd,[tempdata],dword
2489         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2490         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2491         return TRUE;
2492
2493      case 0x33:   /* LFDU */
2494         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2495         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2496         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2497         UML_CALLH(block, ppc->impstate->read64[ppc->impstate->mode & 3]);            // callh   read64
2498         UML_DMOV(block, MEM(&ppc->impstate->tempdata), IREG(0));                  // dmov    [tempdata],i0
2499         UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata));               // fdmov   fd,[tempdata]
2500         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2501         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2502         return TRUE;
2503
2504      case 0x34:   /* STFS */
2505         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2506         UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)), QWORD);      // fsfrflt [tempdata],rs,qword
2507         UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata));                     // mov     i1,[tempdata]
2508         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2509         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
2510         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2511         return TRUE;
2512
2513      case 0x36:   /* STFD */
2514         UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op)));            // add     i0,ra,simm
2515         UML_FDMOV(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)));               // fdmov   [tempdata],rs
2516         UML_DMOV(block, IREG(1), MEM(&ppc->impstate->tempdata));                  // dmov    i1,[tempdata]
2517         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op));                           // mapvar  dsisr,DSISR_IMM(op)
2518         UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode & 3]);            // callh   write64
2519         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2520         return TRUE;
2521
2522      case 0x35:   /* STFSU */
2523         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2524         UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)), QWORD);      // fsfrflt [tempdata],rs,qword
2525         UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata));                     // mov     i1,[tempdata]
2526         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2527         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2528         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
2529         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2530         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2531         return TRUE;
2532
2533      case 0x37:   /* STFDU */
2534         UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op)));               // add     i0,ra,simm
2535         UML_FDMOV(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)));               // fdmov   [tempdata],rs
2536         UML_DMOV(block, IREG(1), MEM(&ppc->impstate->tempdata));                  // dmov    i1,[tempdata]
2537         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
2538         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op));                        // mapvar  dsisr,DSISR_IMMU(op)
2539         UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode & 3]);            // callh   write64
2540         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
2541         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2542         return TRUE;
2543
2544      case 0x3b:   /* 0x3b group */
2545         return generate_instruction_3b(block, compiler, desc);                     // <group3b>
2546
2547      case 0x3f:   /* 0x3f group */
2548         return generate_instruction_3f(block, compiler, desc);                     // <group3f>
2549   }
2550
2551   return FALSE;
15382552}
15392553
1540static void ppcdrc602_reset(void)
2554
2555/*-------------------------------------------------
2556    generate_instruction_13 - compile opcodes in
2557    the 0x13 group
2558-------------------------------------------------*/
2559
2560static int generate_instruction_13(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
15412561{
1542   ppc.pc = ppc.npc = 0xfff00100;
2562   UINT32 op = *desc->opptr.l;
2563   UINT32 opswitch = (op >> 1) & 0x3ff;
15432564
1544   ppc_set_msr(0x40);
1545   change_pc(ppc.pc);
2565   switch (opswitch)
2566   {
2567      case 0x010:   /* BCLRx */
2568         generate_branch_bo(block, compiler, desc, G_BO(op), G_BI(op), SPR_LR, op & M_LK);// <branch conditional>
2569         return TRUE;
15462570
1547   ppc.hid0 = 1;
2571      case 0x210:   /* BCCTRx */
2572         generate_branch_bo(block, compiler, desc, G_BO(op), G_BI(op), SPR_CTR, op & M_LK);
2573                                                                     // <branch conditional>
2574         return TRUE;
15482575
1549   /* reset the DRC */
1550   drc_cache_reset(ppc.drc);
2576      case 0x000:   /* MCRF */
2577         UML_ROLINS(block, CR32, CR32, IMM(((G_CRFS(op) - G_CRFD(op)) & 7) * 4), IMM(CRMASK(G_CRFD(op))));
2578                                                                     // rolins  cr,cr,4*(crfs-crfd),crmask[crfd]
2579         return TRUE;
2580
2581      case 0x101:   /* CRAND */
2582         UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op)));                           // shl     i0,cr,crba(op)
2583         UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op)));                           // shl     i1,cr,crbb(op)
2584         UML_AND(block, IREG(0), IREG(0), IREG(1));                              // and     i0,i1
2585         UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
2586                                                                     // rolins  cr,i0,32-crbd,1<<crbd
2587         return TRUE;
2588
2589      case 0x081:   /* CRANDC */
2590         UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op)));                           // shl     i0,cr,crba(op)
2591         UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op)));                           // shl     i1,cr,crbb(op)
2592         UML_XOR(block, IREG(1), IREG(1), IMM(~0));                              // xor     i1,~0
2593         UML_AND(block, IREG(0), IREG(0), IREG(1));                              // and     i0,i1
2594         UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
2595                                                                     // rolins  cr,i0,32-crbd,1<<crbd
2596         return TRUE;
2597
2598      case 0x0e1:   /* CRNAND */
2599         UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op)));                           // shl     i0,cr,crba(op)
2600         UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op)));                           // shl     i1,cr,crbb(op)
2601         UML_AND(block, IREG(0), IREG(0), IREG(1));                              // and     i0,i1
2602         UML_XOR(block, IREG(0), IREG(0), IMM(~0));                              // xor     i0,~0
2603         UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
2604                                                                     // rolins  cr,i0,32-crbd,1<<crbd
2605         return TRUE;
2606
2607      case 0x1c1:   /* CROR */
2608         UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op)));                           // shl     i0,cr,crba(op)
2609         UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op)));                           // shl     i1,cr,crbb(op)
2610         UML_OR(block, IREG(0), IREG(0), IREG(1));                              // or      i0,i1
2611         UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
2612                                                                     // rolins  cr,i0,32-crbd,1<<crbd
2613         return TRUE;
2614
2615      case 0x1a1:   /* CRORC */
2616         UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op)));                           // shl     i0,cr,crba(op)
2617         UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op)));                           // shl     i1,cr,crbb(op)
2618         UML_XOR(block, IREG(1), IREG(1), IMM(~0));                              // xor     i1,~0
2619         UML_OR(block, IREG(0), IREG(0), IREG(1));                              // or      i0,i1
2620         UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
2621                                                                     // rolins  cr,i0,32-crbd,1<<crbd
2622         return TRUE;
2623
2624      case 0x021:   /* CRNOR */
2625         UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op)));                           // shl     i0,cr,crba(op)
2626         UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op)));                           // shl     i1,cr,crbb(op)
2627         UML_OR(block, IREG(0), IREG(0), IREG(1));                              // or      i0,i1
2628         UML_XOR(block, IREG(0), IREG(0), IMM(~0));                              // xor     i0,~0
2629         UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
2630                                                                     // rolins  cr,i0,32-crbd,1<<crbd
2631         return TRUE;
2632
2633      case 0x0c1:   /* CRXOR */
2634         UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op)));                           // shl     i0,cr,crba(op)
2635         UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op)));                           // shl     i1,cr,crbb(op)
2636         UML_XOR(block, IREG(0), IREG(0), IREG(1));                              // xor     i0,i1
2637         UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
2638                                                                     // rolins  cr,i0,32-crbd,1<<crbd
2639         return TRUE;
2640
2641      case 0x121:   /* CREQV */
2642         UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op)));                           // shl     i0,cr,crba(op)
2643         UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op)));                           // shl     i1,cr,crbb(op)
2644         UML_XOR(block, IREG(0), IREG(0), IREG(1));                              // xor     i0,i1
2645         UML_XOR(block, IREG(0), IREG(0), IMM(~0));                              // xor     i0,~0
2646         UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
2647                                                                     // rolins  cr,i0,32-crbd,1<<crbd
2648         return TRUE;
2649
2650      case 0x032:   /* RFI */
2651         if (ppc->cap & PPCCAP_OEA)
2652         {
2653            if (!(ppc->cap & PPCCAP_603_MMU))
2654               UML_ROLINS(block, MSR32, SPR32(SPROEA_SRR1), IMM(0), IMM(0x87c0ffff));   // rolins  [msr],[srr1],0,0x87c0ffff
2655            else
2656            {
2657               UML_MOV(block, IREG(0), MSR32);                                 // mov     i0,[msr]
2658               UML_ROLINS(block, MSR32, SPR32(SPROEA_SRR1), IMM(0), IMM(0x87c0ffff |  MSR603_TGPR));
2659                                                                     // rolins  [msr],[srr1],0,0x87c0ffff | MSR603_TGPR
2660               UML_XOR(block, IREG(0), IREG(0), MSR32);                        // xor     i0,i0,[msr]
2661               UML_TEST(block, IREG(0), IMM(MSR603_TGPR));                        // test    i0,tgpr
2662               UML_CALLHc(block, IF_NZ, ppc->impstate->swap_tgpr);                  // callh   swap_tgpr,nz
2663            }
2664         }
2665         else if (ppc->cap & PPCCAP_4XX)
2666            UML_MOV(block, MSR32, SPR32(SPR4XX_SRR1));                           // mov     [msr],[srr1]
2667         generate_update_mode(block);                                       // <update mode>
2668         compiler->checkints = TRUE;
2669         generate_update_cycles(block, compiler, SPR32(SPROEA_SRR0), TRUE);            // <subtract cycles>
2670         UML_HASHJMP(block, MEM(&ppc->impstate->mode), SPR32(SPROEA_SRR0), ppc->impstate->nocode);
2671                                                                     // hashjmp mode,[srr0],nocode
2672         return TRUE;
2673
2674      case 0x033:   /* RFCI */
2675         assert(ppc->cap & PPCCAP_4XX);
2676         UML_MOV(block, MSR32, SPR32(SPR4XX_SRR3));                              // mov     [msr],[srr3]
2677         generate_update_mode(block);                                       // <update mode>
2678         compiler->checkints = TRUE;
2679         generate_update_cycles(block, compiler, SPR32(SPR4XX_SRR2), TRUE);            // <subtract cycles>
2680         UML_HASHJMP(block, MEM(&ppc->impstate->mode), SPR32(SPR4XX_SRR2), ppc->impstate->nocode);
2681                                                                     // hashjmp mode,[srr2],nocode
2682         return TRUE;
2683
2684      case 0x096:   /* ISYNC */
2685         /* effective no-op */
2686         return TRUE;
2687   }
2688
2689   return FALSE;
15512690}
15522691
1553static int ppcdrc602_execute(int cycles)
2692
2693/*-------------------------------------------------
2694    generate_instruction_1f - compile opcodes in
2695    the 0x1f group
2696-------------------------------------------------*/
2697
2698static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
15542699{
1555   /* count cycles and interrupt cycles */
1556   ppc_icount = cycles;
1557   ppc_tb_base_icount = cycles;
1558   ppc_dec_base_icount = cycles;
2700   UINT32 op = *desc->opptr.l;
2701   UINT32 opswitch = (op >> 1) & 0x3ff;
2702   drcuml_codelabel swloop, swloopend;
2703   int item;
15592704
1560   // check if decrementer exception occurs during execution
1561   if ((UINT32)(DEC - ppc_icount) > (UINT32)(DEC))
2705   switch (opswitch)
15622706   {
1563      ppc_dec_trigger_cycle = ppc_icount - DEC;
1564   }
1565   else
1566   {
1567      ppc_dec_trigger_cycle = 0x7fffffff;
1568   }
2707      case 0x009:   /* MULHDUx - 64-bit only */
2708      case 0x015:   /* LDX - 64-bit only */
2709      case 0x01b:   /* SLDx - 64-bit only */
2710      case 0x035:   /* LDUX - 64-bit only */
2711      case 0x03a:   /* CNTLZDx - 64-bit only */
2712      case 0x044:   /* TD - 64-bit only */
2713      case 0x049:   /* MULHDx - 64-bit only */
2714      case 0x054:   /* LDARX - 64-bit only */
2715      case 0x095:   /* STDX - 64-bit only */
2716      case 0x0b5:   /* STDUX - 64-bit only */
2717      case 0x0d6:   /* STDCX. - 64-bit only */
2718      case 0x0e9:   /* MULLD - 64-bit only */
2719      case 0x2e9:   /* MULLDO - 64-bit only */
2720      case 0x155:   /* LWAX - 64-bit only */
2721      case 0x175:   /* LWAUX - 64-bit only */
2722      case 0x33a: /* SRADIx - 64-bit only */
2723      case 0x33b: /* SRADIx - 64-bit only */
2724      case 0x1b2:   /* SLBIE - 64-bit only */
2725      case 0x1c9:   /* DIVDUx - 64-bit only */
2726      case 0x3c9:   /* DIVDUOx - 64-bit only */
2727      case 0x1e9:   /* DIVDx - 64-bit only */
2728      case 0x3e9:   /* DIVDOx - 64-bit only */
2729      case 0x1f2:   /* SLBIA - 64-bit only */
2730      case 0x21b:   /* SRDx - 64-bit only */
2731      case 0x31a:   /* SRADx - 64-bit only */
2732      case 0x3da:   /* EXTSW - 64-bit only */
2733         return FALSE;
15692734
1570   drc_execute(ppc.drc);
2735      case 0x004:   /* TW */
2736         UML_CMP(block, R32(G_RA(op)), R32(G_RB(op)));                           // cmp     ra,rb
2737         if (G_TO(op) & 0x10)
2738            UML_EXHc(block, IF_L, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,l
2739         if (G_TO(op) & 0x08)
2740            UML_EXHc(block, IF_G, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,g
2741         if (G_TO(op) & 0x04)
2742            UML_EXHc(block, IF_E, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,e
2743         if (G_TO(op) & 0x02)
2744            UML_EXHc(block, IF_B,  ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,b
2745         if (G_TO(op) & 0x01)
2746            UML_EXHc(block, IF_A,  ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,a
2747         return TRUE;
15712748
1572   // update timebase
1573   // timebase is incremented once every four core clock cycles, so adjust the cycles accordingly
1574   ppc.tb += ((ppc_tb_base_icount - ppc_icount) / 4);
2749      case 0x10a:   /* ADDx */
2750      case 0x30a:   /* ADDOx */
2751         UML_ADDf(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOE(op));   // add     rd,ra,rb,FLAGS_RCOE(op)
2752         generate_compute_flags(block, op & M_RC, ((op & M_OE) ? XER_OV : 0), FALSE);   // <update flags>
2753         return TRUE;
15752754
1576   // update decrementer
1577   DEC -= ((ppc_dec_base_icount - ppc_icount) / (bus_freq_multiplier * 2));
2755      case 0x00a:   /* ADDCx */
2756      case 0x20a:   /* ADDCOx */
2757         UML_ADDf(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOECA(op));   // add     rd,ra,rb,FLAGS_RCOECA(op)
2758         generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), FALSE);// <update flags>
2759         return TRUE;
15782760
1579   return cycles - ppc_icount;
1580}
2761      case 0x08a:   /* ADDEx */
2762      case 0x28a:   /* ADDEOx */
2763         UML_CARRY(block, SPR32(SPR_XER), IMM(29));                              // carry   [xer],XER_CA
2764         UML_ADDCf(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOECA(op));// addc    rd,ra,rb,FLAGS_RCOECA(op)
2765         generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), FALSE);// <update flags>
2766         return TRUE;
15812767
1582static void ppcdrc602_set_irq_line(int irqline, int state)
1583{
1584   if( state ) {
1585      ppc.exception_pending |= 0x1;
1586      if (ppc.irq_callback)
2768      case 0x0ca:   /* ADDZEx */
2769      case 0x2ca:   /* ADDZEOx */
2770         UML_CARRY(block, SPR32(SPR_XER), IMM(29));                              // carry   [xer],XER_CA
2771         UML_ADDCf(block, R32(G_RD(op)), R32(G_RA(op)), IMM(0), FLAGS_RCOECA(op));      // addc    rd,ra,0,FLAGS_RCOECA(op)
2772         generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), FALSE);// <update flags>
2773         return TRUE;
2774
2775      case 0x0ea:   /* ADDMEx */
2776      case 0x2ea:   /* ADDMEOx */
2777         UML_CARRY(block, SPR32(SPR_XER), IMM(29));                              // carry   [xer],XER_CA
2778         UML_ADDCf(block, R32(G_RD(op)), R32(G_RA(op)), IMM(-1), FLAGS_RCOE(op));      // addc    rd,ra,-1,FLAGS_RCOECA(op)
2779         generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), FALSE);// <update flags>
2780         return TRUE;
2781
2782      case 0x028:   /* SUBFx */
2783      case 0x228:   /* SUBFOx */
2784         UML_SUBf(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op)), FLAGS_RCOE(op));   // sub     rd,rb,ra,FLAGS_RCOE(op)
2785         generate_compute_flags(block, op & M_RC, (op & M_OE) ? XER_OV : 0, TRUE);      // <update flags>
2786         return TRUE;
2787
2788      case 0x008:   /* SUBFCx */
2789      case 0x208:   /* SUBFCOx */
2790         UML_SUBf(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op)), FLAGS_RCOECA(op));   // sub     rd,rb,ra,FLAGS_RCOECA(op)
2791         generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), TRUE);// <update flags>
2792         return TRUE;
2793
2794      case 0x088:   /* SUBFEx */
2795      case 0x288:   /* SUBFEOx */
2796         UML_XOR(block, IREG(0), SPR32(SPR_XER), IMM(XER_CA));                     // xor     i0,[xer],XER_CA
2797         UML_CARRY(block, IREG(0), IMM(29));                                    // carry   i0,XER_CA
2798         UML_SUBBf(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op)), FLAGS_RCOECA(op));// subc    rd,rb,ra,FLAGS_RCOECA(op)
2799         generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), TRUE);// <update flags>
2800         return TRUE;
2801
2802      case 0x0c8:   /* SUBFZEx */
2803      case 0x2c8:   /* SUBFZEOx */
2804         UML_XOR(block, IREG(0), SPR32(SPR_XER), IMM(XER_CA));                     // xor     i0,[xer],XER_CA
2805         UML_CARRY(block, IREG(0), IMM(29));                                    // carry   i0,XER_CA
2806         UML_SUBBf(block, R32(G_RD(op)), IMM(0), R32(G_RA(op)), FLAGS_RCOECA(op));      // subc    rd,0,ra,FLAGS_RCOECA(op)
2807         generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), TRUE);// <update flags>
2808         return TRUE;
2809
2810      case 0x0e8:   /* SUBFMEx */
2811      case 0x2e8:   /* SUBFMEOx */
2812         UML_XOR(block, IREG(0), SPR32(SPR_XER), IMM(XER_CA));                     // xor     i0,[xer],XER_CA
2813         UML_CARRY(block, IREG(0), IMM(29));                                    // carry   i0,XER_CA
2814         UML_SUBBf(block, R32(G_RD(op)), IMM(-1), R32(G_RA(op)), FLAGS_RCOECA(op));      // subc    rd,-1,ra,,FLAGS_RCOECA(op)
2815         generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), TRUE);// <update flags>
2816         return TRUE;
2817
2818      case 0x068:   /* NEGx */
2819      case 0x268:   /* NEGOx */
2820         UML_SUBf(block, R32(G_RD(op)), IMM(0), R32(G_RA(op)), FLAGS_RCOE(op));         // sub     rd,0,ra,FLAGS_RCOE(op)
2821         generate_compute_flags(block, op & M_RC, (op & M_OE) ? XER_OV : 0, TRUE);      // <update flags>
2822         return TRUE;
2823
2824      case 0x000:   /* CMP */
2825         UML_CMP(block, R32(G_RA(op)), R32(G_RB(op)));                           // cmp     ra,rb
2826         UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C | DRCUML_FLAG_S);      // getflgs i0,zcs
2827         UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), DWORD);         // load    i0,cmp_cr_table,i0,dword
2828         UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op))));            // rolins  cr,i0,0,crmask[cr]
2829         return TRUE;
2830
2831      case 0x020:   /* CMPL */
2832         UML_CMP(block, R32(G_RA(op)), R32(G_RB(op)));                           // cmp     ra,rb
2833         UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C);                  // getflgs i0,zc
2834         UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), DWORD);         // load    i0,cmpl_cr_table,i0,dword
2835         UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op))));            // rolins  cr,i0,0,crmask[cr]
2836         return TRUE;
2837
2838      case 0x00b:   /* MULHWUx */
2839         UML_MULUf(block, IREG(0), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RC(op));
2840                                                                     // mulu    i0,rd,ra,rb,FLAGS_RC(op)
2841         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2842         return TRUE;
2843
2844      case 0x04b:   /* MULHWx */
2845         UML_MULSf(block, IREG(0), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RC(op));
2846                                                                     // muls    i0,rd,ra,rb,,FLAGS_RC(op)
2847         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2848         return TRUE;
2849
2850      case 0x0eb:   /* MULLWx */
2851      case 0x2eb:   /* MULLWOx */
2852         if (!(op & M_OE))
2853         {
2854            UML_MULSf(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RC(op));
2855                                                                     // muls    rd,rd,ra,rb,FLAGS_RC(op)
2856            generate_compute_flags(block, op & M_RC, 0, FALSE);                     // <update flags>
2857         }
2858         else
2859         {
2860            UML_MULSf(block, IREG(0), IREG(1), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RC(op));
2861                                                                     // muls    i0,i1,ra,rb
2862            generate_compute_flags(block, op & M_RC, 0, FALSE);                     // <update flags>
2863            UML_MOV(block, R32(G_RD(op)), IREG(0));                              // mov     rd,i0
2864            UML_SAR(block, IREG(0), IREG(0), IMM(31));                           // sar     i0,i0,31
2865            UML_AND(block, SPR32(SPR_XER), SPR32(SPR_XER), IMM(XER_OV));            // and     [xer],[xer],XER_OV
2866            UML_XORf(block, IREG(0), IREG(0), IREG(1), FLAGS_Z);                  // xor     i0,i0,i1,Z
2867            UML_MOVc(block, IF_NZ, IREG(0), IMM(XER_OV | XER_SO));                  // mov     i0,XER_OV | XER_SO,NZ
2868            UML_OR(block, SPR32(SPR_XER), SPR32(SPR_XER), IREG(0));                  // or      [xer],[xer],i0
2869         }
2870         return TRUE;
2871
2872      case 0x1cb:   /* DIVWUx */
2873      case 0x3cb:   /* DIVWUOx */
2874         UML_DIVUf(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOE(op));
2875                                                                     // divu    rd,rd,ra,rb,FLAGS_RCOE(op)
2876         generate_compute_flags(block, op & M_RC, ((op & M_OE) ? XER_OV : 0), FALSE);   // <update flags>
2877         return TRUE;
2878
2879      case 0x1eb:   /* DIVWx */
2880      case 0x3eb:   /* DIVWOx */
2881         UML_DIVSf(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOE(op));
2882                                                                     // divs    rd,rd,ra,rb,FLAGS_RCOE(op)
2883         generate_compute_flags(block, op & M_RC, ((op & M_OE) ? XER_OV : 0), FALSE);   // <update flags>
2884         return TRUE;
2885
2886      case 0x01c:   /* ANDx */
2887         UML_ANDf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op));      // and     ra,rs,rb,FLAGS_RC(op)
2888         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2889         return TRUE;
2890
2891      case 0x03c:   /* ANDCx */
2892         UML_XOR(block, IREG(0), R32(G_RB(op)), IMM(~0));                        // xor     i0,rb,~0
2893         UML_ANDf(block, R32(G_RA(op)), R32(G_RS(op)), IREG(0), FLAGS_RC(op));         // and     ra,rs,i0,FLAGS_RC(op)
2894         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2895         return TRUE;
2896
2897      case 0x1dc:   /* NANDx */
2898         UML_AND(block, IREG(0), R32(G_RS(op)), R32(G_RB(op)));                     // and     i0,rs,rb
2899         UML_XORf(block, R32(G_RA(op)), IREG(0), IMM(~0), FLAGS_RC(op));               // xor     ra,i0,~0,FLAGS_RC(op)
2900         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2901         return TRUE;
2902
2903      case 0x1bc:   /* ORx */
2904         UML_ORf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op));      // or      ra,rs,rb,FLAGS_RC(op)
2905         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2906         return TRUE;
2907
2908      case 0x19c:   /* ORCx */
2909         UML_XORf(block, IREG(0), R32(G_RB(op)), IMM(~0), FLAGS_RC(op));               // xor     i0,rb,~0,FLAGS_RC(op)
2910         UML_OR(block, R32(G_RA(op)), R32(G_RS(op)), IREG(0));                     // or      ra,rs,i0
2911         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2912         return TRUE;
2913
2914      case 0x07c:   /* NORx */
2915         UML_OR(block, IREG(0), R32(G_RS(op)), R32(G_RB(op)));                     // or      i0,rs,rb
2916         UML_XORf(block, R32(G_RA(op)), IREG(0), IMM(~0), FLAGS_RC(op));               // xor     ra,i0,~0,FLAGS_RC(op)
2917         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2918         return TRUE;
2919
2920      case 0x13c:   /* XORx */
2921         UML_XORf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op));      // xor     ra,rs,rb,FLAGS_RC(op)
2922         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2923         return TRUE;
2924
2925      case 0x11c:   /* EQVx */
2926         UML_XOR(block, IREG(0), R32(G_RS(op)), R32(G_RB(op)));                     // xor     i0,rs,rb
2927         UML_XORf(block, R32(G_RA(op)), IREG(0), IMM(~0), FLAGS_RC(op));               // xor     ra,i0,~0,FLAGS_RC(op)
2928         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2929         return TRUE;
2930
2931      case 0x018:   /* SLWx */
2932         UML_SHL(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)));               // shl     ra,rs,rb
2933         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2934         return TRUE;
2935
2936      case 0x218:   /* SRWx */
2937         UML_SHRf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op));      // shr     ra,rs,rb,FLAGS_RC(op)
2938         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2939         return TRUE;
2940
2941      case 0x318:   /* SRAWx */
2942         UML_SHL(block, IREG(1), IMM(0xffffffff), R32(G_RB(op)));                  // shl     i1,0xffffffff,rb
2943         UML_XOR(block, IREG(1), IREG(1), IMM(~0));                              // xor     i1,i1,~0
2944         UML_AND(block, IREG(0), R32(G_RS(op)), IREG(1));                        // and     i0,rs,i1
2945         UML_SAR(block, IREG(1), R32(G_RS(op)), IMM(31));                        // sar     i1,rs,31
2946         UML_ANDf(block, IREG(0), IREG(0), IREG(1), DRCUML_FLAG_Z);                  // and     i0,i0,i1,z
2947         UML_SETc(block, IF_NZ, IREG(0));                                    // set     i0,nz
2948         UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(XER_CA));            // rolins  [xer],i0,29,XER_CA
2949         UML_SARf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op));      // sar     ra,rs,rb,FLAGS_RC(op)
2950         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2951         return TRUE;
2952
2953      case 0x338:   /* SRAWIx */
2954         UML_AND(block, IREG(0), R32(G_RS(op)), IMM(~(0xffffffff << (G_SH(op) & 31))));   // and     i0,rs,~(0xffffffff << (sh & 31))
2955         UML_SAR(block, IREG(1), R32(G_RS(op)), IMM(31));                        // sar     i1,rs,31
2956         UML_ANDf(block, IREG(0), IREG(0), IREG(1), DRCUML_FLAG_Z);                  // and     i0,i0,i1,z
2957         UML_SETc(block, IF_NZ, IREG(0));                                    // set     i0,nz
2958         UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(XER_CA));            // rolins  [xer],i0,29,XER_CA
2959         UML_SARf(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_SH(op)), FLAGS_RC(op));      // sar     ra,rs,sh,FLAGS_RC(op)
2960         generate_compute_flags(block, op & M_RC, 0, FALSE);                        // <update flags>
2961         return TRUE;
2962
2963      case 0x01a:   /* CNTLZWx */
2964         UML_LZCNT(block, R32(G_RA(op)), R32(G_RS(op)));                           // lzcnt   ra,rs,rb
2965         if (op & M_RC)
2966         {
2967            UML_TEST(block, R32(G_RA(op)), IMM(~0));                           // test    ra,~0
2968            generate_compute_flags(block, op & M_RC, 0, FALSE);                     // <update flags>
2969         }
2970         return TRUE;
2971
2972      case 0x3ba:   /* EXTSBx */
2973         UML_SEXT(block, R32(G_RA(op)), R32(G_RS(op)), BYTE);                     // sext    ra,rs,byte
2974         if (op & M_RC)
2975         {
2976            UML_TEST(block, R32(G_RA(op)), IMM(~0));                           // test    ra,~0
2977            generate_compute_flags(block, op & M_RC, 0, FALSE);                     // <update flags>
2978         }
2979         return TRUE;
2980
2981      case 0x39a:   /* EXTSHx */
2982         UML_SEXT(block, R32(G_RA(op)), R32(G_RS(op)), WORD);                     // sext    ra,rs,word
2983         if (op & M_RC)
2984         {
2985            UML_TEST(block, R32(G_RA(op)), IMM(~0));                           // test    ra,~0
2986            generate_compute_flags(block, op & M_RC, 0, FALSE);                     // <update flags>
2987         }
2988         return TRUE;
2989
2990      case 0x057:   /* LBZX */
2991         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
2992         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
2993         UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode & 3]);            // callh   read8
2994         UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xff));                        // and     rd,i0,0xff
2995         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
2996         return TRUE;
2997
2998      case 0x117:   /* LHZX */
2999         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3000         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3001         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
3002         UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xffff));                     // and     rd,i0,0xffff
3003         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3004         return TRUE;
3005
3006      case 0x157:   /* LHAX */
3007         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3008         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3009         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
3010         UML_SEXT(block, R32(G_RD(op)), IREG(0), WORD);                           // sext    rd,i0,word
3011         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3012         return TRUE;
3013
3014      case 0x017:   /* LWZX */
3015         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3016         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3017         UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode & 3]);            // callh   read32
3018         UML_MOV(block, R32(G_RD(op)), IREG(0));                                 // mov     rd,i0
3019         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3020         return TRUE;
3021
3022      case 0x217:   /* LFSX */
3023         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3024         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3025         UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode & 3]);            // callh   read32
3026         UML_MOV(block, MEM(&ppc->impstate->tempdata), IREG(0));                     // mov     [tempdata],i0
3027         UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata), DWORD);      // fdfrflt fd,[tempdata],dword
3028         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3029         return TRUE;
3030
3031      case 0x257:   /* LFDX */
3032         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3033         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3034         UML_CALLH(block, ppc->impstate->read64[ppc->impstate->mode & 3]);            // callh   read64
3035         UML_DMOV(block, MEM(&ppc->impstate->tempdata), IREG(0));                  // dmov    [tempdata],i0
3036         UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata));               // fdmov   fd,[tempdata]
3037         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3038         return TRUE;
3039
3040      case 0x316:   /* LHBRX */
3041         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3042         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3043         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
3044         UML_BSWAP(block, IREG(0), IREG(0));                                    // bswap   i0,i0
3045         UML_SHR(block, R32(G_RD(op)), IREG(0), IMM(16));                        // shr     rd,i0,16
3046         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3047         return TRUE;
3048
3049      case 0x216:   /* LWBRX */
3050         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3051         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3052         UML_CALLH(block, ppc->impstate->read32align[ppc->impstate->mode & 3]);         // callh   read32align
3053         UML_BSWAP(block, R32(G_RD(op)), IREG(0));                              // bswap   rd,i0
3054         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3055         return TRUE;
3056
3057      case 0x077:   /* LBZUX */
3058         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3059         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3060         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op));                        // mapvar  dsisr,DSISR_IDXU(op)
3061         UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode & 3]);            // callh   read8
3062         UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xff));                        // and     rd,i0,0xff
3063         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3064         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3065         return TRUE;
3066
3067      case 0x137:   /* LHZUX */
3068         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3069         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3070         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op));                        // mapvar  dsisr,DSISR_IDXU(op)
3071         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
3072         UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xffff));                     // and     rd,i0,0xffff
3073         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3074         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3075         return TRUE;
3076
3077      case 0x177:   /* LHAUX */
3078         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3079         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3080         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op));                        // mapvar  dsisr,DSISR_IDXU(op)
3081         UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode & 3]);            // callh   read16
3082         UML_SEXT(block, R32(G_RD(op)), IREG(0), WORD);                           // sext    rd,i0,word
3083         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3084         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3085         return TRUE;
3086
3087      case 0x037:   /* LWZUX */
3088         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3089         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3090         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op));                        // mapvar  dsisr,DSISR_IDXU(op)
3091         UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode & 3]);            // callh   read32
3092         UML_MOV(block, R32(G_RD(op)), IREG(0));                                 // mov     rd,i0
3093         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3094         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3095         return TRUE;
3096
3097      case 0x237:   /* LFSUX */
3098         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3099         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3100         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3101         UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode & 3]);            // callh   read32
3102         UML_MOV(block, MEM(&ppc->impstate->tempdata), IREG(0));                     // mov     [tempdata],i0
3103         UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata), DWORD);      // fdfrflt fd,[tempdata],dword
3104         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3105         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3106         return TRUE;
3107
3108      case 0x277:   /* LFDUX */
3109         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3110         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3111         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3112         UML_CALLH(block, ppc->impstate->read64[ppc->impstate->mode & 3]);            // callh   read64
3113         UML_DMOV(block, MEM(&ppc->impstate->tempdata), IREG(0));                  // dmov    [tempdata],i0
3114         UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata));               // fdmov   fd,[tempdata]
3115         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3116         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3117         return TRUE;
3118
3119      case 0x014:   /* LWARX */
3120         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3121         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3122         UML_CALLH(block, ppc->impstate->read32align[ppc->impstate->mode & 3]);         // callh   read32align
3123         UML_MOV(block, R32(G_RD(op)), IREG(0));                                 // mov     rd,i0
3124         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3125         return TRUE;
3126
3127      case 0x255:   /* LSWI */
3128         UML_MOV(block, MEM(&ppc->impstate->swcount), IMM(((G_NB(op) - 1) & 0x1f) + 1));   // mov     [swcount],[xer],G_NB
3129         UML_MOV(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op)));            // mov     [updateaddr],ra
3130         UML_MOV(block, MEM(&ppc->impstate->swreg), IMM(4 * G_RD(op)));               // mov     [swreg],4*G_RD(op)
3131         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3132         save_fast_iregs(block);                                             // <save fastregs>
3133         UML_LABEL(block, swloop = compiler->labelnum++);                     // swloop:
3134         UML_MOV(block, IREG(0), MEM(&ppc->impstate->updateaddr));                  // mov     i0,[updateaddr]
3135         UML_ADD(block, MEM(&ppc->impstate->updateaddr), IREG(0), IMM(1));            // add     [updateaddr],i0,1
3136         UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode & 3]);            // callh   read8
3137         UML_MOV(block, IREG(1), MEM(&ppc->impstate->swreg));                     // mov     i1,[swreg]
3138         UML_ADD(block, IREG(2), IREG(1), IMM(1));                              // add     i2,i1,1
3139         UML_AND(block, MEM(&ppc->impstate->swreg), IREG(2), IMM(0x7f));               // and     [swreg],i2,0x7f
3140         UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));                     // xor     i1,i1,be_xor(0)
3141         UML_STORE(block, &ppc->r[0], IREG(1), IREG(0), BYTE);                     // store   &r0,i1,i0,byte
3142         UML_SUBf(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1), FLAGS_Z);
3143                                                                     // sub     [swcount],[swcount],1,Z
3144         UML_JMPc(block, IF_NZ, swloop);                                       // jmp     swloop,NZ
3145         load_fast_iregs(block);                                             // <load fastregs>
3146         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3147         return TRUE;
3148
3149      case 0x215:   /* LSWX */
3150         UML_ANDf(block, FLAGS_Z, MEM(&ppc->impstate->swcount), SPR32(SPR_XER), IMM(0x7f));// and   [swcount],[xer],0x7f,Z
3151         UML_JMPc(block, IF_Z, swloopend = compiler->labelnum++);                  // jmp     swloopend,Z
3152         UML_ADD(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op)), R32(G_RB(op)));   // add     [updateaddr],ra,rb
3153         UML_MOV(block, MEM(&ppc->impstate->swreg), IMM(4 * G_RD(op)));               // mov     [swreg],4*G_RD(op)
3154         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3155         save_fast_iregs(block);                                             // <save fastregs>
3156         UML_LABEL(block, swloop = compiler->labelnum++);                     // swloop:
3157         UML_MOV(block, IREG(0), MEM(&ppc->impstate->updateaddr));                  // mov     i0,[updateaddr]
3158         UML_ADD(block, MEM(&ppc->impstate->updateaddr), IREG(0), IMM(1));            // add     [updateaddr],i0,1
3159         UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode & 3]);            // callh   read8
3160         UML_MOV(block, IREG(1), MEM(&ppc->impstate->swreg));                     // mov     i1,[swreg]
3161         UML_ADD(block, IREG(2), IREG(1), IMM(1));                              // add     i2,i1,1
3162         UML_AND(block, MEM(&ppc->impstate->swreg), IREG(2), IMM(0x7f));               // and     [swreg],i2,0x7f
3163         UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));                     // xor     i1,i1,be_xor(0)
3164         UML_STORE(block, &ppc->r[0], IREG(1), IREG(0), BYTE);                     // store   &r0,i1,i0,byte
3165         UML_SUBf(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1), FLAGS_Z);
3166                                                                     // sub     [swcount],[swcount],1,Z
3167         UML_JMPc(block, IF_NZ, swloop);                                       // jmp     swloop,NZ
3168         UML_LABEL(block, swloopend);                                    // swloopend:
3169         load_fast_iregs(block);                                             // <load fastregs>
3170         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3171         return TRUE;
3172
3173      case 0x136:   /* ECIWX */
3174         /* not implemented */
3175         return FALSE;
3176
3177      case 0x0d7:   /* STBX */
3178         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3179         UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xff));                        // and     i1,rs,0xff
3180         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3181         UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode & 3]);            // callh   write8
3182         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3183         return TRUE;
3184
3185      case 0x197:   /* STHX */
3186         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3187         UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xffff));                     // and     i1,rs
3188         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3189         UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode & 3]);            // callh   write16
3190         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3191         return TRUE;
3192
3193      case 0x097:   /* STWX */
3194         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3195         UML_MOV(block, IREG(1), R32(G_RS(op)));                                 // mov     i1,rs
3196         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3197         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
3198         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3199         return TRUE;
3200
3201      case 0x297:   /* STFSX */
3202         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3203         UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)), QWORD);      // fsfrflt [tempdata],rs,qword
3204         UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata));                     // mov     i1,[tempdata]
3205         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3206         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
3207         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3208         return TRUE;
3209
3210      case 0x3d7:   /* STFIWX */
3211         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3212         UML_FDMOV(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)));               // fdmov   [tempdata],rs
3213         UML_MOV(block, IREG(1), MEM((UINT32 *)&ppc->impstate->tempdata + BYTE_XOR_LE(0)));// mov   i1,[tempdata.lo]
3214         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3215         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
3216         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3217         return TRUE;
3218
3219      case 0x2d7:   /* STFDX */
3220         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3221         UML_FDMOV(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)));               // fdmov   [tempdata],rs
3222         UML_DMOV(block, IREG(1), MEM(&ppc->impstate->tempdata));                  // dmov    i1,[tempdata]
3223         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3224         UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode & 3]);            // callh   write64
3225         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3226         return TRUE;
3227
3228      case 0x396:   /* STHBRX */
3229         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3230         UML_BSWAP(block, IREG(1), R32(G_RS(op)));                              // bswap   i1,rs
3231         UML_SHR(block, IREG(1), IREG(1), IMM(16));                              // shr     i1,i1,16
3232         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3233         UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode & 3]);            // callh   write16
3234         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3235         return TRUE;
3236
3237      case 0x296:   /* STWBRX */
3238         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3239         UML_BSWAP(block, IREG(1), R32(G_RS(op)));                              // bswap   i1,rs
3240         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3241         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
3242         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3243         return TRUE;
3244
3245      case 0x0f7:   /* STBUX */
3246         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3247         UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xff));                        // and     i1,rs,0xff
3248         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3249         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3250         UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode & 3]);            // callh   write8
3251         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3252         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3253         return TRUE;
3254
3255      case 0x1b7:   /* STHUX */
3256         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3257         UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xffff));                     // and     i1,rs,0xffff
3258         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3259         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3260         UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode & 3]);            // callh   write16
3261         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3262         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3263         return TRUE;
3264
3265      case 0x0b7:   /* STWUX */
3266         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3267         UML_MOV(block, IREG(1), R32(G_RS(op)));                                 // mov     i1,rs
3268         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3269         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op));                        // mapvar  dsisr,DSISR_IDXU(op)
3270         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
3271         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3272         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3273         return TRUE;
3274
3275      case 0x2b7:   /* STFSUX */
3276         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3277         UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)), QWORD);      // fsfrflt [tempdata],rs,qword
3278         UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata));                     // mov     i1,[tempdata]
3279         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3280         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3281         UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode & 3]);            // callh   write32
3282         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3283         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3284         return TRUE;
3285
3286      case 0x2f7:   /* STFDUX */
3287         UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3288         UML_FDMOV(block, MEM(&ppc->impstate->tempdata), F64(G_RS(op)));               // fdmov   [tempdata],rs
3289         UML_DMOV(block, IREG(1), MEM(&ppc->impstate->tempdata));                  // dmov    i1,[tempdata]
3290         UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0));                  // mov     [updateaddr],i0
3291         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3292         UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode & 3]);            // callh   write64
3293         UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr));               // mov     ra,[updateaddr]
3294         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3295         return TRUE;
3296
3297      case 0x096:   /* STWCX. */
3298         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3299         UML_MOV(block, IREG(1), R32(G_RS(op)));                                 // mov     i1,rs
3300         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3301         UML_CALLH(block, ppc->impstate->write32align[ppc->impstate->mode & 3]);         // callh   write32align
3302         UML_AND(block, IREG(0), CR32, IMM(~CRMASK(0)));                           // and     i0,cr,~crmask(0)
3303         UML_ROLINS(block, IREG(0), SPR32(SPR_XER), IMM(29), IMM(0x10000000));         // rolins  i0,[xer],29,0x10000000
3304         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3305         return TRUE;
3306
3307      case 0x2d5:   /* STSWI */
3308         UML_MOV(block, MEM(&ppc->impstate->swcount), IMM(((G_NB(op) - 1) & 0x1f) + 1));   // mov     [swcount],[xer],G_NB
3309         UML_MOV(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op)));            // mov     [updateaddr],ra
3310         UML_MOV(block, MEM(&ppc->impstate->swreg), IMM(4 * G_RS(op)));               // mov     [swreg],4*G_RS(op)
3311         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3312         save_fast_iregs(block);                                             // <save fastregs>
3313         UML_LABEL(block, swloop = compiler->labelnum++);                     // swloop:
3314         UML_MOV(block, IREG(0), MEM(&ppc->impstate->updateaddr));                  // mov     i0,[updateaddr]
3315         UML_ADD(block, MEM(&ppc->impstate->updateaddr), IREG(0), IMM(1));            // add     [updateaddr],i0,1
3316         UML_MOV(block, IREG(1), MEM(&ppc->impstate->swreg));                     // mov     i1,[swreg]
3317         UML_ADD(block, IREG(2), IREG(1), IMM(1));                              // add     i2,i1,1
3318         UML_AND(block, MEM(&ppc->impstate->swreg), IREG(2), IMM(0x7f));               // and     [swreg],i2,0x7f
3319         UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));                     // xor     i1,i1,be_xor(0)
3320         UML_LOAD(block, IREG(1), &ppc->r[0], IREG(1), BYTE);                     // load    i1,&r0,i1,byte
3321         UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode & 3]);            // callh   write8
3322         UML_SUBf(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1), FLAGS_Z);
3323                                                                     // sub     [swcount],[swcount],1,Z
3324         UML_JMPc(block, IF_NZ, swloop);                                       // jmp     swloop,NZ
3325         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3326         return TRUE;
3327
3328      case 0x295:   /* STSWX */
3329         UML_ANDf(block, FLAGS_Z, MEM(&ppc->impstate->swcount), SPR32(SPR_XER), IMM(0x7f));// and   [swcount],[xer],0x7f,Z
3330         UML_JMPc(block, IF_Z, swloopend = compiler->labelnum++);                  // jmp     swloopend,Z
3331         UML_ADD(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op)), R32(G_RB(op)));   // add     [updateaddr],ra,rb
3332         UML_MOV(block, MEM(&ppc->impstate->swreg), IMM(4 * G_RS(op)));               // mov     [swreg],4*G_RS(op)
3333         UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op));                           // mapvar  dsisr,DSISR_IDX(op)
3334         save_fast_iregs(block);                                             // <save fastregs>
3335         UML_LABEL(block, swloop = compiler->labelnum++);                     // swloop:
3336         UML_MOV(block, IREG(0), MEM(&ppc->impstate->updateaddr));                  // mov     i0,[updateaddr]
3337         UML_ADD(block, MEM(&ppc->impstate->updateaddr), IREG(0), IMM(1));            // add     [updateaddr],i0,1
3338         UML_MOV(block, IREG(1), MEM(&ppc->impstate->swreg));                     // mov     i1,[swreg]
3339         UML_ADD(block, IREG(2), IREG(1), IMM(1));                              // add     i2,i1,1
3340         UML_AND(block, MEM(&ppc->impstate->swreg), IREG(2), IMM(0x7f));               // and     [swreg],i2,0x7f
3341         UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));                     // xor     i1,i1,be_xor(0)
3342         UML_LOAD(block, IREG(1), &ppc->r[0], IREG(1), BYTE);                     // load    i1,&r0,i1,byte
3343         UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode & 3]);            // callh   write8
3344         UML_SUBf(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1), FLAGS_Z);
3345                                                                     // sub     [swcount],[swcount],1,Z
3346         UML_JMPc(block, IF_NZ, swloop);                                       // jmp     swloop,NZ
3347         UML_LABEL(block, swloopend);                                    // swloopend:
3348         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3349         return TRUE;
3350
3351      case 0x1b6:   /* ECOWX */
3352         /* not implemented */
3353         return FALSE;
3354
3355      case 0x036:   /* DCBST */
3356      case 0x056:   /* DCBF */
3357      case 0x0f6:   /* DCBTST */
3358      case 0x116:   /* DCBT */
3359      case 0x3d6:   /* ICBI */
3360      case 0x256:   /* SYNC */
3361      case 0x356:   /* EIEIO */
3362      case 0x1d6:   /* DCBI */
3363      case 0x236:   /* TLBSYNC */
3364         /* effective no-ops */
3365         return TRUE;
3366
3367      case 0x3f6:   /* DCBZ */
3368         UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op)));                     // add     i0,ra,rb
3369         UML_AND(block, MEM(&ppc->impstate->tempaddr), IREG(0), IMM(~(ppc->cache_line_size - 1)));
3370                                                                     // and     [tempaddr],i0,~(cache_line_size - 1)
3371         for (item = 0; item < ppc->cache_line_size / 8; item++)
3372         {
3373            UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(8 * item));      // add     i0,[tempaddr],8*item
3374            UML_DMOV(block, IREG(1), IMM(0));                                 // dmov    i1,0
3375            UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode & 3]);         // callh   write64
3376         }
3377         return TRUE;
3378
3379      case 0x132:   /* TLBIE */
3380         UML_MOV(block, MEM(&ppc->param0), R32(G_RB(op)));                        // mov     [param0],rb
3381         UML_CALLC(block, ppccom_execute_tlbie, ppc);                           // callc   ppccom_execute_tlbie,ppc
3382         return TRUE;
3383
3384      case 0x172:   /* TLBIA */
3385         UML_CALLC(block, ppccom_execute_tlbia, ppc);                           // callc   ppccom_execute_tlbia,ppc
3386         return TRUE;
3387
3388      case 0x3d2:   /* TLBLD */
3389         assert(ppc->cap & PPCCAP_603_MMU);
3390         UML_MOV(block, MEM(&ppc->param0), R32(G_RB(op)));                        // mov     [param0],rb
3391         UML_MOV(block, MEM(&ppc->param1), IMM(0));                              // mov     [param1],0
3392         UML_CALLC(block, ppccom_execute_tlbl, ppc);                              // callc   ppccom_execute_tlbl,ppc
3393         return TRUE;
3394
3395      case 0x3f2:   /* TLBLI */
3396         assert(ppc->cap & PPCCAP_603_MMU);
3397         UML_MOV(block, MEM(&ppc->param0), R32(G_RB(op)));                        // mov     [param0],rb
3398         UML_MOV(block, MEM(&ppc->param1), IMM(1));                              // mov     [param1],1
3399         UML_CALLC(block, ppccom_execute_tlbl, ppc);                              // callc   ppccom_execute_tlbl,ppc
3400         return TRUE;
3401
3402      case 0x013:   /* MFCR */
3403         UML_MOV(block, R32(G_RD(op)), CR32);                                 // mov     rd,cr
3404         return TRUE;
3405
3406      case 0x053:   /* MFMSR */
3407         UML_MOV(block, R32(G_RD(op)), MSR32);                                 // mov     rd,msr
3408         return TRUE;
3409
3410      case 0x153:   /* MFSPR */
15873411      {
1588         ppc.irq_callback(irqline);
3412         UINT32 spr = compute_spr(G_SPR(op));
3413         if (spr == SPR_LR || spr == SPR_CTR || spr == SPR_XER || (spr >= SPROEA_SPRG0 && spr <= SPROEA_SPRG3))
3414            UML_MOV(block, R32(G_RD(op)), SPR32(spr));                           // mov     rd,spr
3415         else if (spr == SPROEA_PVR)
3416            UML_MOV(block, R32(G_RD(op)), IMM(ppc->flavor));                     // mov     rd,flavor
3417         else
3418         {
3419            generate_update_cycles(block, compiler, IMM(desc->pc), TRUE);            // <update cycles>
3420            UML_MOV(block, MEM(&ppc->param0), IMM(spr));                        // mov     [param0],spr
3421            UML_CALLC(block, ppccom_execute_mfspr, ppc);                        // callc   ppccom_execute_mfspr,ppc
3422            UML_MOV(block, R32(G_RD(op)), MEM(&ppc->param1));                     // mov     rd,[param1]
3423         }
3424         return TRUE;
15893425      }
1590   }
1591}
1592#endif
15933426
1594#if (HAS_MPC8240)
1595static void mpc8240drc_init(int index, int clock, const void *_config, int (*irqcallback)(int))
1596{
1597   float multiplier;
1598   const ppc_config *config = _config;
1599   int i;
3427      case 0x253:   /* MFSR */
3428         UML_MOV(block, R32(G_RD(op)), SR32(G_SR(op)));                           // mov     rd,sr
3429         return TRUE;
16003430
1601   ppc_init();
1602   ppcdrc_init();
3431      case 0x293:   /* MFSRIN */
3432         UML_SHR(block, IREG(0), R32(G_RB(op)), IMM(28));                        // shr     i0,G_RB,28
3433         UML_LOAD(block, R32(G_RD(op)), &ppc->sr[0], IREG(0), DWORD);               // load    rd,sr,i0,dword
3434         return TRUE;
16033435
1604   ppc.optable[48] = recompile_lfs;
1605   ppc.optable[49] = recompile_lfsu;
1606   ppc.optable[50] = recompile_lfd;
1607   ppc.optable[51] = recompile_lfdu;
1608   ppc.optable[52] = recompile_stfs;
1609   ppc.optable[53] = recompile_stfsu;
1610   ppc.optable[54] = recompile_stfd;
1611   ppc.optable[55] = recompile_stfdu;
1612   ppc.optable31[631] = recompile_lfdux;
1613   ppc.optable31[599] = recompile_lfdx;
1614   ppc.optable31[567] = recompile_lfsux;
1615   ppc.optable31[535] = recompile_lfsx;
1616   ppc.optable31[595] = recompile_mfsr;
1617   ppc.optable31[659] = recompile_mfsrin;
1618   ppc.optable31[371] = recompile_mftb;
1619   ppc.optable31[210] = recompile_mtsr;
1620   ppc.optable31[242] = recompile_mtsrin;
1621   ppc.optable31[758] = recompile_dcba;
1622   ppc.optable31[759] = recompile_stfdux;
1623   ppc.optable31[727] = recompile_stfdx;
1624   ppc.optable31[983] = recompile_stfiwx;
1625   ppc.optable31[695] = recompile_stfsux;
1626   ppc.optable31[663] = recompile_stfsx;
1627   ppc.optable31[370] = recompile_tlbia;
1628   ppc.optable31[306] = recompile_tlbie;
1629   ppc.optable31[566] = recompile_tlbsync;
1630   ppc.optable31[310] = recompile_eciwx;
1631   ppc.optable31[438] = recompile_ecowx;
3436      case 0x173:   /* MFTB */
3437      {
3438         UINT32 tbr = compute_spr(G_SPR(op));
3439         if (tbr != SPRVEA_TBL_R && tbr != SPRVEA_TBU_R)
3440            return FALSE;
3441         generate_update_cycles(block, compiler, IMM(desc->pc), TRUE);               // <update cycles>
3442         UML_MOV(block, MEM(&ppc->param0), IMM(tbr));                           // mov     [param0],tbr
3443         UML_CALLC(block, ppccom_execute_mftb, ppc);                              // callc   ppccom_execute_mftb,ppc
3444         UML_MOV(block, R32(G_RD(op)), MEM(&ppc->param1));                        // mov     rd,[param1]
3445         return TRUE;
3446      }
16323447
1633   ppc.optable63[264] = recompile_fabsx;
1634   ppc.optable63[21] = recompile_faddx;
1635   ppc.optable63[32] = recompile_fcmpo;
1636   ppc.optable63[0] = recompile_fcmpu;
1637   ppc.optable63[14] = recompile_fctiwx;
1638   ppc.optable63[15] = recompile_fctiwzx;
1639   ppc.optable63[18] = recompile_fdivx;
1640   ppc.optable63[72] = recompile_fmrx;
1641   ppc.optable63[136] = recompile_fnabsx;
1642   ppc.optable63[40] = recompile_fnegx;
1643   ppc.optable63[12] = recompile_frspx;
1644   ppc.optable63[26] = recompile_frsqrtex;
1645   ppc.optable63[22] = recompile_fsqrtx;
1646   ppc.optable63[20] = recompile_fsubx;
1647   ppc.optable63[583] = recompile_mffsx;
1648   ppc.optable63[70] = recompile_mtfsb0x;
1649   ppc.optable63[38] = recompile_mtfsb1x;
1650   ppc.optable63[711] = recompile_mtfsfx;
1651   ppc.optable63[134] = recompile_mtfsfix;
1652   ppc.optable63[64] = recompile_mcrfs;
3448      case 0x090:   /* MTCRF */
3449         UML_ROLINS(block, CR32, R32(G_RS(op)), IMM(0), IMM(compute_crf_mask(G_CRM(op))));// rolins cr,rs,0,G_CRM
3450         return TRUE;
16533451
1654   ppc.optable59[21] = recompile_faddsx;
1655   ppc.optable59[18] = recompile_fdivsx;
1656   ppc.optable59[24] = recompile_fresx;
1657   ppc.optable59[22] = recompile_fsqrtsx;
1658   ppc.optable59[20] = recompile_fsubsx;
3452      case 0x092:   /* MTMSR */
3453         if (ppc->cap & PPCCAP_603_MMU)
3454            UML_XOR(block, IREG(0), MSR32, R32(G_RS(op)));                        // xor     i0,msr32,rs
3455         UML_MOV(block, MSR32, R32(G_RS(op)));                                 // mov     msr,rs
3456         if (ppc->cap & PPCCAP_603_MMU)
3457         {
3458            UML_TEST(block, IREG(0), IMM(MSR603_TGPR));                           // test    i0,tgpr
3459            UML_CALLHc(block, IF_NZ, ppc->impstate->swap_tgpr);                     // callh   swap_tgpr,nz
3460         }
3461         generate_update_mode(block);                                       // <update mode>
3462         return TRUE;
16593463
1660   for(i = 0; i < 32; i++)
1661   {
1662      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1663      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1664      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1665      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1666      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1667      ppc.optable63[i * 32 | 23] = recompile_fselx;
3464      case 0x1d3:   /* MTSPR */
3465      {
3466         UINT32 spr = compute_spr(G_SPR(op));
3467         if (spr == SPR_LR || spr == SPR_CTR || spr == SPR_XER || (spr >= SPROEA_SPRG0 && spr <= SPROEA_SPRG3))
3468            UML_MOV(block, SPR32(spr), R32(G_RS(op)));                           // mov     spr,rs
3469         else if (spr == SPROEA_PVR)
3470            ;                                                         // read only
3471         else
3472         {
3473            generate_update_cycles(block, compiler, IMM(desc->pc), TRUE);            // <update cycles>
3474            UML_MOV(block, MEM(&ppc->param0), IMM(spr));                        // mov     [param0],spr
3475            UML_MOV(block, MEM(&ppc->param1), R32(G_RS(op)));                     // mov     [param1],rs
3476            UML_CALLC(block, ppccom_execute_mtspr, ppc);                        // callc   ppccom_execute_mtspr,ppc
3477            compiler->checkints = TRUE;
3478            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);         // <update cycles>
3479         }
3480         return TRUE;
3481      }
16683482
1669      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1670      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1671      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1672      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1673      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
1674   }
3483      case 0x0d2:   /* MTSR */
3484         UML_MOV(block, SR32(G_SR(op)), R32(G_RS(op)));                           // mov     sr[G_SR],rs
3485         UML_CALLC(block, ppccom_tlb_flush, ppc);                              // callc   ppccom_tlb_flush,ppc
3486         return TRUE;
16753487
1676   for(i = 0; i < 256; i++)
1677   {
1678      ppc_field_xlat[i] =
1679         ((i & 0x80) ? 0xF0000000 : 0) |
1680         ((i & 0x40) ? 0x0F000000 : 0) |
1681         ((i & 0x20) ? 0x00F00000 : 0) |
1682         ((i & 0x10) ? 0x000F0000 : 0) |
1683         ((i & 0x08) ? 0x0000F000 : 0) |
1684         ((i & 0x04) ? 0x00000F00 : 0) |
1685         ((i & 0x02) ? 0x000000F0 : 0) |
1686         ((i & 0x01) ? 0x0000000F : 0);
1687   }
3488      case 0x0f2:   /* MTSRIN */
3489         UML_SHR(block, IREG(0), R32(G_RB(op)), IMM(28));                        // shr     i0,G_RB,28
3490         UML_STORE(block, &ppc->sr[0], IREG(0), R32(G_RS(op)), DWORD);               // store   sr,i0,rs,dword
3491         UML_CALLC(block, ppccom_tlb_flush, ppc);                              // callc   ppccom_tlb_flush,ppc
3492         return TRUE;
16883493
1689   // MPC8240 specific opcodes
1690   ppc.optable31[978] = recompile_tlbld;
1691   ppc.optable31[1010] = recompile_tlbli;
3494      case 0x200:   /* MCRXR */
3495         UML_ROLINS(block, CR32, SPR32(SPR_XER), IMM(32 - 4 * G_CRFD(op)), IMM(CRMASK(G_CRFD(op))));
3496                                                                     // rolins  cr,[xer],32-4*crfd,crmask(crfd)
3497         UML_AND(block, SPR32(SPR_XER), SPR32(SPR_XER), IMM(~0xf0000000));            // and     [xer],[xer],~0xf0000000
3498         return TRUE;
16923499
1693   ppc.is603 = 1;
3500      case 0x106:   /* ICBT */
3501      case 0x1c6:   /* DCCCI */
3502      case 0x3c6:   /* ICCCI */
3503         assert(ppc->cap & PPCCAP_4XX);
3504         /* effective no-nop */
3505         return TRUE;
16943506
1695   ppc.read8 = program_read_byte_64be;
1696   ppc.read16 = program_read_word_64be;
1697   ppc.read32 = program_read_dword_64be;
1698   ppc.read64 = program_read_qword_64be;
1699   ppc.write8 = program_write_byte_64be;
1700   ppc.write16 = program_write_word_64be;
1701   ppc.write32 = program_write_dword_64be;
1702   ppc.write64 = program_write_qword_64be;
1703   ppc.read16_unaligned = ppc_read16_unaligned;
1704   ppc.read32_unaligned = ppc_read32_unaligned;
1705   ppc.read64_unaligned = ppc_read64_unaligned;
1706   ppc.write16_unaligned = ppc_write16_unaligned;
1707   ppc.write32_unaligned = ppc_write32_unaligned;
1708   ppc.write64_unaligned = ppc_write64_unaligned;
3507      case 0x1e6:   /* DCREAD */
3508      case 0x3e6:   /* ICREAD */
3509         assert(ppc->cap & PPCCAP_4XX);
3510         UML_MOV(block, R32(G_RT(op)), IMM(0));                                 // mov     rt,0
3511         return TRUE;
17093512
1710   ppc.irq_callback = irqcallback;
3513      case 0x143:   /* MFDCR */
3514      {
3515         UINT32 spr = compute_spr(G_SPR(op));
3516         assert(ppc->cap & PPCCAP_4XX);
3517         generate_update_cycles(block, compiler, IMM(desc->pc), TRUE);               // <update cycles>
3518         UML_MOV(block, MEM(&ppc->param0), IMM(spr));                           // mov     [param0],spr
3519         UML_CALLC(block, ppccom_execute_mfdcr, ppc);                           // callc   ppccom_execute_mfdcr,ppc
3520         UML_MOV(block, R32(G_RD(op)), MEM(&ppc->param1));                        // mov     rd,[param1]
3521         return TRUE;
3522      }
17113523
1712   ppc.pvr = config->pvr;
3524      case 0x1c3:   /* MTDCR */
3525      {
3526         UINT32 spr = compute_spr(G_SPR(op));
3527         assert(ppc->cap & PPCCAP_4XX);
3528         generate_update_cycles(block, compiler, IMM(desc->pc), TRUE);               // <update cycles>
3529         UML_MOV(block, MEM(&ppc->param0), IMM(spr));                           // mov     [param0],spr
3530         UML_MOV(block, MEM(&ppc->param1), R32(G_RS(op)));                        // mov     [param1],rs
3531         UML_CALLC(block, ppccom_execute_mtdcr, ppc);                           // callc   ppccom_execute_mtdcr,ppc
3532         compiler->checkints = TRUE;
3533         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3534         return TRUE;
3535      }
17133536
1714   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1715             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1716   bus_freq_multiplier = (int)(multiplier * 2);
1717}
3537      case 0x083:   /* WRTEE */
3538         assert(ppc->cap & PPCCAP_4XX);
3539         UML_ROLINS(block, MSR32, R32(G_RS(op)), IMM(0), IMM(MSR_EE));               // rolins  msr,rs,0,MSR_EE
3540         compiler->checkints = TRUE;
3541         generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);            // <update cycles>
3542         return TRUE;
17183543
1719static void mpc8240drc_exit(void)
1720{
1721   ppcdrc_exit();
3544      case 0x0a3:   /* WRTEEI */
3545         assert(ppc->cap & PPCCAP_4XX);
3546         if (op & MSR_EE)
3547         {
3548            UML_OR(block, MSR32, MSR32, IMM(MSR_EE));                           // or      msr,msr,MSR_EE
3549            compiler->checkints = TRUE;
3550            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);         // <update cycles>
3551         }
3552         else
3553            UML_AND(block, MSR32, MSR32, IMM(~MSR_EE));                           // and     msr,msr,~MSR_EE
3554         return TRUE;
3555   }
3556
3557   return FALSE;
17223558}
1723#endif
17243559
17253560
1726#if (HAS_PPC601)
1727static void ppc601drc_init(int index, int clock, const void *_config, int (*irqcallback)(int))
3561/*-------------------------------------------------
3562    generate_instruction_3b - compile opcodes in
3563    the 0x3b group
3564-------------------------------------------------*/
3565
3566static int generate_instruction_3b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
17283567{
1729   int pll_config = 0;
1730   float multiplier;
1731   const ppc_config *config = _config;
1732   int i;
3568   UINT32 op = *desc->opptr.l;
3569   UINT32 opswitch = (op >> 1) & 0x1f;
17333570
1734   ppc_init();
1735   ppcdrc_init();
3571   switch (opswitch)
3572   {
3573      case 0x15:   /* FADDSx */
3574         UML_FDADD(block, FREG(0), F64(G_RA(op)), F64(G_RB(op)));                  // fdadd   f0,ra,rb
3575         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3576         return TRUE;
17363577
1737   ppc.optable[48] = recompile_lfs;
1738   ppc.optable[49] = recompile_lfsu;
1739   ppc.optable[50] = recompile_lfd;
1740   ppc.optable[51] = recompile_lfdu;
1741   ppc.optable[52] = recompile_stfs;
1742   ppc.optable[53] = recompile_stfsu;
1743   ppc.optable[54] = recompile_stfd;
1744   ppc.optable[55] = recompile_stfdu;
1745   ppc.optable31[631] = recompile_lfdux;
1746   ppc.optable31[599] = recompile_lfdx;
1747   ppc.optable31[567] = recompile_lfsux;
1748   ppc.optable31[535] = recompile_lfsx;
1749   ppc.optable31[595] = recompile_mfsr;
1750   ppc.optable31[659] = recompile_mfsrin;
1751   ppc.optable31[371] = recompile_mftb;
1752   ppc.optable31[210] = recompile_mtsr;
1753   ppc.optable31[242] = recompile_mtsrin;
1754   ppc.optable31[758] = recompile_dcba;
1755   ppc.optable31[759] = recompile_stfdux;
1756   ppc.optable31[727] = recompile_stfdx;
1757   ppc.optable31[983] = recompile_stfiwx;
1758   ppc.optable31[695] = recompile_stfsux;
1759   ppc.optable31[663] = recompile_stfsx;
1760   ppc.optable31[370] = recompile_tlbia;
1761   ppc.optable31[306] = recompile_tlbie;
1762   ppc.optable31[566] = recompile_tlbsync;
1763   ppc.optable31[310] = recompile_eciwx;
1764   ppc.optable31[438] = recompile_ecowx;
3578      case 0x14:   /* FSUBSx */
3579         UML_FDSUB(block, FREG(0), F64(G_RA(op)), F64(G_RB(op)));                  // fdsub   f0,ra,rb
3580         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3581         return TRUE;
17653582
1766   ppc.optable63[264] = recompile_fabsx;
1767   ppc.optable63[21] = recompile_faddx;
1768   ppc.optable63[32] = recompile_fcmpo;
1769   ppc.optable63[0] = recompile_fcmpu;
1770   ppc.optable63[14] = recompile_fctiwx;
1771   ppc.optable63[15] = recompile_fctiwzx;
1772   ppc.optable63[18] = recompile_fdivx;
1773   ppc.optable63[72] = recompile_fmrx;
1774   ppc.optable63[136] = recompile_fnabsx;
1775   ppc.optable63[40] = recompile_fnegx;
1776   ppc.optable63[12] = recompile_frspx;
1777   ppc.optable63[26] = recompile_frsqrtex;
1778   ppc.optable63[22] = recompile_fsqrtx;
1779   ppc.optable63[20] = recompile_fsubx;
1780   ppc.optable63[583] = recompile_mffsx;
1781   ppc.optable63[70] = recompile_mtfsb0x;
1782   ppc.optable63[38] = recompile_mtfsb1x;
1783   ppc.optable63[711] = recompile_mtfsfx;
1784   ppc.optable63[134] = recompile_mtfsfix;
1785   ppc.optable63[64] = recompile_mcrfs;
3583      case 0x19:   /* FMULSx */
3584         UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_RB(op)));                  // fdmul   f0,ra,rb
3585         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3586         return TRUE;
17863587
1787   ppc.optable59[21] = recompile_faddsx;
1788   ppc.optable59[18] = recompile_fdivsx;
1789   ppc.optable59[24] = recompile_fresx;
1790   ppc.optable59[22] = recompile_fsqrtsx;
1791   ppc.optable59[20] = recompile_fsubsx;
3588      case 0x12:   /* FDIVSx */
3589         UML_FDDIV(block, FREG(0), F64(G_RA(op)), F64(G_RB(op)));                  // fddiv   f0,ra,rb
3590         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3591         return TRUE;
17923592
1793   for(i = 0; i < 32; i++)
1794   {
1795      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1796      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1797      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1798      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1799      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1800      ppc.optable63[i * 32 | 23] = recompile_fselx;
3593      case 0x16:   /* FSQRTSx */
3594         UML_FDSQRT(block, FREG(0), F64(G_RB(op)));                              // fdsqrt  f0,rb
3595         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3596         return TRUE;
18013597
1802      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1803      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1804      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1805      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1806      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
3598      case 0x18:   /* FRESx */
3599         UML_FSFRFLT(block, FREG(0), F64(G_RB(op)), QWORD);                        // fsfrlt  f0,rb,qword
3600         UML_FSRECIP(block, FREG(0), FREG(0));                                 // fsrecip f0,f0
3601         UML_FDFRFLT(block, F64(G_RD(op)), FREG(0), DWORD);                        // fdfrflt rd,f0,dword
3602         return TRUE;
3603
3604      case 0x1d:   /* FMADDSx */
3605         UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op)));                  // fdmul   f0,ra,rc
3606         UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op)));                        // fdadd   f0,f0,rb
3607         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3608         return TRUE;
3609
3610      case 0x1c:   /* FMSUBSx */
3611         UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op)));                  // fdmul   f0,ra,rc
3612         UML_FDSUB(block, FREG(0), FREG(0), F64(G_RB(op)));                        // fdsub   f0,f0,rb
3613         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3614         return TRUE;
3615
3616      case 0x1f:   /* FNMADDSx */
3617         UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op)));                  // fdmul   f0,ra,rc
3618         UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op)));                        // fdadd   f0,f0,rb
3619         UML_FDNEG(block, FREG(0), FREG(0));                                    // fdneg   f0,f0
3620         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3621         return TRUE;
3622
3623      case 0x1e:   /* FNMSUBSx */
3624         UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op)));                  // fdmul   f0,ra,rc
3625         UML_FDSUB(block, FREG(0), F64(G_RB(op)), FREG(0));                        // fdsub   f0,rb,f0
3626         UML_FDRNDS(block, F64(G_RD(op)), FREG(0));                              // fdrnds  rd,f0
3627         return TRUE;
18073628   }
18083629
1809   for(i = 0; i < 256; i++)
3630   return FALSE;
3631}
3632
3633
3634
3635/*-------------------------------------------------
3636    generate_instruction_3f - compile opcodes in
3637    the 0x3f group
3638-------------------------------------------------*/
3639
3640static int generate_instruction_3f(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
3641{
3642   UINT32 op = *desc->opptr.l;
3643   UINT32 opswitch = (op >> 1) & 0x3ff;
3644
3645   if (opswitch & 0x10)
18103646   {
1811      ppc_field_xlat[i] =
1812         ((i & 0x80) ? 0xF0000000 : 0) |
1813         ((i & 0x40) ? 0x0F000000 : 0) |
1814         ((i & 0x20) ? 0x00F00000 : 0) |
1815         ((i & 0x10) ? 0x000F0000 : 0) |
1816         ((i & 0x08) ? 0x0000F000 : 0) |
1817         ((i & 0x04) ? 0x00000F00 : 0) |
1818         ((i & 0x02) ? 0x000000F0 : 0) |
1819         ((i & 0x01) ? 0x0000000F : 0);
1820   }
3647      opswitch &= 0x1f;
3648      switch (opswitch)
3649      {
3650         case 0x15:   /* FADDx */
3651            UML_FDADD(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op)));            // fdadd   rd,ra,rb
3652            return TRUE;
18213653
1822   ppc.is603 = 1;
3654         case 0x14:   /* FSUBx */
3655            UML_FDSUB(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op)));            // fdsub   rd,ra,rb
3656            return TRUE;
18233657
1824   ppc.read8 = program_read_byte_64be;
1825   ppc.read16 = program_read_word_64be;
1826   ppc.read32 = program_read_dword_64be;
1827   ppc.read64 = program_read_qword_64be;
1828   ppc.write8 = program_write_byte_64be;
1829   ppc.write16 = program_write_word_64be;
1830   ppc.write32 = program_write_dword_64be;
1831   ppc.write64 = program_write_qword_64be;
1832   ppc.read16_unaligned = ppc_read16_unaligned;
1833   ppc.read32_unaligned = ppc_read32_unaligned;
1834   ppc.read64_unaligned = ppc_read64_unaligned;
1835   ppc.write16_unaligned = ppc_write16_unaligned;
1836   ppc.write32_unaligned = ppc_write32_unaligned;
1837   ppc.write64_unaligned = ppc_write64_unaligned;
3658         case 0x19:   /* FMULx */
3659            UML_FDMUL(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op)));            // fdmul   rd,ra,rb
3660            return TRUE;
18383661
1839   ppc.irq_callback = irqcallback;
3662         case 0x12:   /* FDIVx */
3663            UML_FDDIV(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op)));            // fddiv   rd,ra,rb
3664            return TRUE;
18403665
1841   ppc.pvr = config->pvr;
3666         case 0x16:   /* FSQRTx */
3667            UML_FDSQRT(block, F64(G_RD(op)), F64(G_RB(op)));                     // fdsqrt  rd,rb
3668            return TRUE;
18423669
1843   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1844             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1845   bus_freq_multiplier = (int)(multiplier * 2);
3670         case 0x1a:   /* FRSQRTEx */
3671            UML_FDRSQRT(block, F64(G_RD(op)), F64(G_RB(op)));                     // fdrsqrt rd,rb
3672            return TRUE;
18463673
1847   switch(config->pvr)
3674         case 0x17:   /* FSELx */
3675            UML_FDCMP(block, F64(G_RA(op)), MEM(&ppc->impstate->fp0));               // fdcmp   f0,ra,[fp0]
3676            UML_FDMOVc(block, IF_AE, F64(G_RD(op)), F64(G_REGC(op)));               // fdmov   rd,rc,AE
3677            UML_FDMOVc(block, IF_B, F64(G_RD(op)), F64(G_RB(op)));                  // fdmov   rd,rb,B
3678            return TRUE;
3679
3680         case 0x1d:   /* FMADDx */
3681            UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op)));               // fdmul   f0,ra,rc
3682            UML_FDADD(block, F64(G_RD(op)), FREG(0), F64(G_RB(op)));               // fdadd   rd,f0,rb
3683            return TRUE;
3684
3685         case 0x1f:   /* FNMADDx */
3686            UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op)));               // fdmul   f0,ra,rc
3687            UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op)));                     // fdadd   f0,f0,rb
3688            UML_FDNEG(block, F64(G_RD(op)), FREG(0));                           // fdneg   rd,f0
3689            return TRUE;
3690
3691         case 0x1c:   /* FMSUBx */
3692            UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op)));               // fdmul   f0,ra,rc
3693            UML_FDSUB(block, F64(G_RD(op)), FREG(0), F64(G_RB(op)));               // fdsub   rd,f0,rb
3694            return TRUE;
3695
3696         case 0x1e:   /* FNMSUBx */
3697            UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op)));               // fdmul   f0,ra,rc
3698            UML_FDSUB(block, F64(G_RD(op)), F64(G_RB(op)), FREG(0));               // fdsub   rd,rb,f0
3699            return TRUE;
3700      }
3701   }
3702   else
18483703   {
1849      case PPC_MODEL_603E:   pll_config = mpc603e_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1850      case PPC_MODEL_603EV:   pll_config = mpc603ev_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1851      case PPC_MODEL_603R:   pll_config = mpc603r_pll_config[bus_freq_multiplier-1][config->bus_frequency]; break;
1852      default: break;
1853   }
3704      switch (opswitch)
3705      {
3706         case 0x32e:   /* FCTIDx - 64-bit only */
3707         case 0x32f:   /* FCTIDZx - 64-bit only */
3708         case 0x34e:   /* FCFIDx - 64-bit only */
3709            return FALSE;
18543710
1855   if (pll_config == -1)
1856   {
1857      fatalerror("PPC: Invalid bus/multiplier combination (bus frequency = %d, multiplier = %1.1f)", config->bus_frequency, multiplier);
3711         case 0x000:   /* FCMPU */
3712         case 0x020:   /* FCMPO */
3713            UML_FDCMP(block, F64(G_RA(op)), F64(G_RB(op)));                        // fdcmp   ra,rb
3714            UML_GETFLGS(block, IREG(0), DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_U);   // getflgs i0,czu
3715            UML_LOAD(block, IREG(0), ppc->impstate->fcmp_cr_table, IREG(0), DWORD);      // load    i0,fcmp_cr_table,i0,dword
3716            UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op))));         // rolins  cr,i0,0,crmask[cr]
3717            return TRUE;
3718
3719         case 0x00c:   /* FRSPx */
3720            UML_FDRNDS(block, F64(G_RD(op)), F64(G_RB(op)));                     // fdrnds  rd,rb
3721            return TRUE;
3722
3723         case 0x00e:   /* FCTIWx */
3724            UML_FDTOINT(block, IREG(0), F64(G_RB(op)), DWORD, DEFAULT);               // fdtoint i0,rb,dword,default
3725            UML_DAND(block, MEM(&ppc->impstate->tempdata), IREG(0), IMM(0xffffffff));   // dand    i0,i0,0xffffffff
3726            UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata));            // fdmovr  rd,i0
3727            return TRUE;
3728
3729         case 0x00f:   /* FCTIWZx */
3730            UML_FDTOINT(block, IREG(0), F64(G_RB(op)), DWORD, TRUNC);               // fdtoint i0,rb,dword,default
3731            UML_DAND(block, MEM(&ppc->impstate->tempdata), IREG(0), IMM(0xffffffff));   // dand    i0,i0,0xffffffff
3732            UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata));            // fdmovr  rd,i0
3733            return TRUE;
3734
3735         case 0x028:   /* FNEGx */
3736            UML_FDNEG(block, F64(G_RD(op)), F64(G_RB(op)));                        // fdneg   rd,rb
3737            return TRUE;
3738
3739         case 0x048:   /* FMRx */
3740            UML_FDMOV(block, F64(G_RD(op)), F64(G_RB(op)));                        // fdmov   rd,rb
3741            return TRUE;
3742
3743         case 0x088:   /* FNABSx */
3744            UML_FDABS(block, FREG(0), F64(G_RB(op)));                           // fdabs   f0,rb
3745            UML_FDNEG(block, F64(G_RD(op)), FREG(0));                           // fdneg   rd,f0
3746            return TRUE;
3747
3748         case 0x108:   /* FABSx */
3749            UML_FDABS(block, F64(G_RD(op)), F64(G_RB(op)));                        // fdabs   rd,rb
3750            return TRUE;
3751
3752         case 0x046:   /* MTFSB0x */
3753            UML_AND(block, FPSCR32, FPSCR32, IMM(~(0x80000000 >> G_CRBD(op))));         // and     fpscr32,fpscr32,~(0x80000000 >> G_CRBD)
3754            return TRUE;
3755
3756         case 0x026:   /* MTFSB1x */
3757            UML_OR(block, FPSCR32, FPSCR32, IMM(0x80000000 >> G_CRBD(op)));            // or      fpscr32,fpscr32,(0x80000000 >> G_CRBD)
3758            return TRUE;
3759
3760         case 0x040:   /* MCRFS */
3761            UML_ROLINS(block, CR32, FPSCR32, IMM(((G_CRFS(op) - G_CRFD(op)) & 7) * 4), IMM(CRMASK(G_CRFD(op))));
3762                                                                     // rolins  cr,fpscr,shift,crmask[crfd]
3763            UML_AND(block, FPSCR32, FPSCR32, IMM(~CRMASK(G_CRFS(op))));               // and     fpscr,fpscr,~crmask[crfs]
3764            return TRUE;
3765
3766         case 0x247:   /* MFFSx */
3767            UML_MOV(block, R32(G_RD(op)), FPSCR32);                              // mov     rd,fpscr
3768            return TRUE;
3769
3770         case 0x2c7:   /* MTFSFx */
3771            UML_ROLINS(block, FPSCR32, R32(G_RB(op)), IMM(0), IMM(compute_crf_mask(G_FM(op))));
3772                                                                     // rolins  fpscr,rb,0,crf_mask
3773            return TRUE;
3774
3775         case 0x086:   /* MTFSFIx */
3776            UML_ROLINS(block, FPSCR32, R32(G_IMM(op)), IMM(28 - 4 * G_CRFD(op)), IMM(CRMASK(G_CRFD(op))));
3777                                                                     // rolins  fpscr,rb,0,crf_mask
3778            return TRUE;
3779      }
18583780   }
18593781
1860   ppc.hid1 = pll_config << 28;
3782   return FALSE;
18613783}
18623784
1863static void ppc601drc_exit(void)
3785
3786
3787/***************************************************************************
3788    CODE LOGGING HELPERS
3789***************************************************************************/
3790
3791/*-------------------------------------------------
3792    log_add_disasm_comment - add a comment
3793    including disassembly of a PowerPC instruction
3794-------------------------------------------------*/
3795
3796static void log_add_disasm_comment(drcuml_block *block, UINT32 pc, UINT32 op)
18643797{
1865#if LOG_CODE
1866   //if (symfile) fclose(symfile);
3798#if (LOG_UML)
3799   char buffer[100];
3800   ppc_dasm_one(buffer, pc, op);
3801   UML_COMMENT(block, "%08X: %s", pc, buffer);                              // comment
18673802#endif
1868   ppcdrc_exit();
18693803}
1870#endif
18713804
18723805
1873#if (HAS_PPC604)
1874static void ppc604drc_init(int index, int clock, const void *_config, int (*irqcallback)(int))
3806/*-------------------------------------------------
3807    log_desc_flags_to_string - generate a string
3808    representing the instruction description
3809    flags
3810-------------------------------------------------*/
3811
3812static const char *log_desc_flags_to_string(UINT32 flags)
18753813{
1876   float multiplier;
1877   const ppc_config *config = _config;
1878   int i;
3814   static char tempbuf[30];
3815   char *dest = tempbuf;
18793816
1880   ppc_init();
1881   ppcdrc_init();
3817   /* branches */
3818   if (flags & OPFLAG_IS_UNCONDITIONAL_BRANCH)
3819      *dest++ = 'U';
3820   else if (flags & OPFLAG_IS_CONDITIONAL_BRANCH)
3821      *dest++ = 'C';
3822   else
3823      *dest++ = '.';
18823824
1883   ppc.optable[48] = recompile_lfs;
1884   ppc.optable[49] = recompile_lfsu;
1885   ppc.optable[50] = recompile_lfd;
1886   ppc.optable[51] = recompile_lfdu;
1887   ppc.optable[52] = recompile_stfs;
1888   ppc.optable[53] = recompile_stfsu;
1889   ppc.optable[54] = recompile_stfd;
1890   ppc.optable[55] = recompile_stfdu;
1891   ppc.optable31[631] = recompile_lfdux;
1892   ppc.optable31[599] = recompile_lfdx;
1893   ppc.optable31[567] = recompile_lfsux;
1894   ppc.optable31[535] = recompile_lfsx;
1895   ppc.optable31[595] = recompile_mfsr;
1896   ppc.optable31[659] = recompile_mfsrin;
1897   ppc.optable31[371] = recompile_mftb;
1898   ppc.optable31[210] = recompile_mtsr;
1899   ppc.optable31[242] = recompile_mtsrin;
1900   ppc.optable31[758] = recompile_dcba;
1901   ppc.optable31[759] = recompile_stfdux;
1902   ppc.optable31[727] = recompile_stfdx;
1903   ppc.optable31[983] = recompile_stfiwx;
1904   ppc.optable31[695] = recompile_stfsux;
1905   ppc.optable31[663] = recompile_stfsx;
1906   ppc.optable31[370] = recompile_tlbia;
1907   ppc.optable31[306] = recompile_tlbie;
1908   ppc.optable31[566] = recompile_tlbsync;
1909   ppc.optable31[310] = recompile_eciwx;
1910   ppc.optable31[438] = recompile_ecowx;
3825   /* intrablock branches */
3826   *dest++ = (flags & OPFLAG_INTRABLOCK_BRANCH) ? 'i' : '.';
19113827
1912   ppc.optable63[264] = recompile_fabsx;
1913   ppc.optable63[21] = recompile_faddx;
1914   ppc.optable63[32] = recompile_fcmpo;
1915   ppc.optable63[0] = recompile_fcmpu;
1916   ppc.optable63[14] = recompile_fctiwx;
1917   ppc.optable63[15] = recompile_fctiwzx;
1918   ppc.optable63[18] = recompile_fdivx;
1919   ppc.optable63[72] = recompile_fmrx;
1920   ppc.optable63[136] = recompile_fnabsx;
1921   ppc.optable63[40] = recompile_fnegx;
1922   ppc.optable63[12] = recompile_frspx;
1923   ppc.optable63[26] = recompile_frsqrtex;
1924   ppc.optable63[22] = recompile_fsqrtx;
1925   ppc.optable63[20] = recompile_fsubx;
1926   ppc.optable63[583] = recompile_mffsx;
1927   ppc.optable63[70] = recompile_mtfsb0x;
1928   ppc.optable63[38] = recompile_mtfsb1x;
1929   ppc.optable63[711] = recompile_mtfsfx;
1930   ppc.optable63[134] = recompile_mtfsfix;
1931   ppc.optable63[64] = recompile_mcrfs;
3828   /* branch targets */
3829   *dest++ = (flags & OPFLAG_IS_BRANCH_TARGET) ? 'B' : '.';
19323830
1933   ppc.optable59[21] = recompile_faddsx;
1934   ppc.optable59[18] = recompile_fdivsx;
1935   ppc.optable59[24] = recompile_fresx;
1936   ppc.optable59[22] = recompile_fsqrtsx;
1937   ppc.optable59[20] = recompile_fsubsx;
3831   /* delay slots */
3832   *dest++ = (flags & OPFLAG_IN_DELAY_SLOT) ? 'D' : '.';
19383833
1939   for(i = 0; i < 32; i++)
1940   {
1941      ppc.optable63[i * 32 | 29] = recompile_fmaddx;
1942      ppc.optable63[i * 32 | 28] = recompile_fmsubx;
1943      ppc.optable63[i * 32 | 25] = recompile_fmulx;
1944      ppc.optable63[i * 32 | 31] = recompile_fnmaddx;
1945      ppc.optable63[i * 32 | 30] = recompile_fnmsubx;
1946      ppc.optable63[i * 32 | 23] = recompile_fselx;
3834   /* exceptions */
3835   if (flags & OPFLAG_WILL_CAUSE_EXCEPTION)
3836      *dest++ = 'E';
3837   else if (flags & OPFLAG_CAN_CAUSE_EXCEPTION)
3838      *dest++ = 'e';
3839   else
3840      *dest++ = '.';
19473841
1948      ppc.optable59[i * 32 | 29] = recompile_fmaddsx;
1949      ppc.optable59[i * 32 | 28] = recompile_fmsubsx;
1950      ppc.optable59[i * 32 | 25] = recompile_fmulsx;
1951      ppc.optable59[i * 32 | 31] = recompile_fnmaddsx;
1952      ppc.optable59[i * 32 | 30] = recompile_fnmsubsx;
1953   }
3842   /* read/write */
3843   if (flags & OPFLAG_READS_MEMORY)
3844      *dest++ = 'R';
3845   else if (flags & OPFLAG_WRITES_MEMORY)
3846      *dest++ = 'W';
3847   else
3848      *dest++ = '.';
19543849
1955   ppc.optable31[978] = recompile_tlbld;
3850   /* TLB validation */
3851   *dest++ = (flags & OPFLAG_VALIDATE_TLB) ? 'V' : '.';
19563852
1957   for(i = 0; i < 256; i++)
1958   {
1959      ppc_field_xlat[i] =
1960         ((i & 0x80) ? 0xF0000000 : 0) |
1961         ((i & 0x40) ? 0x0F000000 : 0) |
1962         ((i & 0x20) ? 0x00F00000 : 0) |
1963         ((i & 0x10) ? 0x000F0000 : 0) |
1964         ((i & 0x08) ? 0x0000F000 : 0) |
1965         ((i & 0x04) ? 0x00000F00 : 0) |
1966         ((i & 0x02) ? 0x000000F0 : 0) |
1967         ((i & 0x01) ? 0x0000000F : 0);
1968   }
3853   /* TLB modification */
3854   *dest++ = (flags & OPFLAG_MODIFIES_TRANSLATION) ? 'T' : '.';
19693855
1970   ppc.is603 = 1;
3856   /* redispatch */
3857   *dest++ = (flags & OPFLAG_REDISPATCH) ? 'R' : '.';
3858   return tempbuf;
3859}
19713860
1972   ppc.read8 = program_read_byte_64be;
1973   ppc.read16 = program_read_word_64be;
1974   ppc.read32 = program_read_dword_64be;
1975   ppc.read64 = program_read_qword_64be;
1976   ppc.write8 = program_write_byte_64be;
1977   ppc.write16 = program_write_word_64be;
1978   ppc.write32 = program_write_dword_64be;
1979   ppc.write64 = program_write_qword_64be;
1980   ppc.read16_unaligned = ppc_read16_unaligned;
1981   ppc.read32_unaligned = ppc_read32_unaligned;
1982   ppc.read64_unaligned = ppc_read64_unaligned;
1983   ppc.write16_unaligned = ppc_write16_unaligned;
1984   ppc.write32_unaligned = ppc_write32_unaligned;
1985   ppc.write64_unaligned = ppc_write64_unaligned;
19863861
1987   ppc.irq_callback = irqcallback;
3862/*-------------------------------------------------
3863    log_register_list - log a list of GPR registers
3864-------------------------------------------------*/
19883865
1989   ppc.pvr = config->pvr;
3866static void log_register_list(drcuml_state *drcuml, const char *string, UINT64 gprmask, UINT64 fprmask)
3867{
3868   int count = 0;
3869   int regnum;
19903870
1991   multiplier = (float)((config->bus_frequency_multiplier >> 4) & 0xf) +
1992             (float)(config->bus_frequency_multiplier & 0xf) / 10.0f;
1993   bus_freq_multiplier = (int)(multiplier * 2);
3871   /* skip if nothing */
3872   if ((gprmask & ~1) == 0 && fprmask == 0)
3873      return;
3874
3875   drcuml_log_printf(drcuml, "[%s:", string);
3876
3877   for (regnum = 0; regnum < 32; regnum++)
3878      if (gprmask & ((UINT64)1 << regnum))
3879         drcuml_log_printf(drcuml, "%sr%d", (count++ == 0) ? "" : ",", regnum);
3880   for (regnum = 0; regnum < 8; regnum++)
3881      if (gprmask & ((UINT64)1 << (32 + regnum)))
3882         drcuml_log_printf(drcuml, "%scr%d", (count++ == 0) ? "" : ",", regnum);
3883   if (gprmask & ((UINT64)1 << 40))
3884      drcuml_log_printf(drcuml, "%sxer", (count++ == 0) ? "" : ",");
3885   if (gprmask & ((UINT64)1 << 41))
3886      drcuml_log_printf(drcuml, "%sctr", (count++ == 0) ? "" : ",");
3887   if (gprmask & ((UINT64)1 << 42))
3888      drcuml_log_printf(drcuml, "%slr", (count++ == 0) ? "" : ",");
3889
3890   for (regnum = 0; regnum < 32; regnum++)
3891      if (fprmask & ((UINT64)1 << regnum))
3892         drcuml_log_printf(drcuml, "%sfpr%d", (count++ == 0) ? "" : ",", regnum);
3893   if (fprmask & ((UINT64)1 << 32))
3894      drcuml_log_printf(drcuml, "%sfpscr", (count++ == 0) ? "" : ",");
3895   drcuml_log_printf(drcuml, "] ");
19943896}
19953897
1996static void ppc604drc_exit(void)
3898
3899/*-------------------------------------------------
3900    log_opcode_desc - log a list of descriptions
3901-------------------------------------------------*/
3902
3903static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, int indent)
19973904{
1998#if LOG_CODE
1999   //if (symfile) fclose(symfile);
3905   /* open the file, creating it if necessary */
3906   if (indent == 0)
3907      drcuml_log_printf(drcuml, "\nDescriptor list @ %08X\n", desclist->pc);
3908
3909   /* output each descriptor */
3910   for ( ; desclist != NULL; desclist = desclist->next)
3911   {
3912      char buffer[100];
3913
3914      /* disassemle the current instruction and output it to the log */
3915#if (LOG_UML || LOG_NATIVE)
3916      if (desclist->flags & OPFLAG_VIRTUAL_NOOP)
3917         strcpy(buffer, "<virtual nop>");
3918      else
3919         ppc_dasm_one(buffer, desclist->pc, *desclist->opptr.l);
3920#else
3921      strcpy(buffer, "???");
20003922#endif
2001   ppcdrc_exit();
3923      drcuml_log_printf(drcuml, "%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), buffer);
3924
3925      /* output register states */
3926      log_register_list(drcuml, "use", desclist->gpr.used, desclist->fpr.used);
3927      log_register_list(drcuml, "mod", desclist->gpr.modified, desclist->fpr.modified);
3928      log_register_list(drcuml, "lrd", desclist->gpr.liveread, desclist->fpr.liveread);
3929      log_register_list(drcuml, "lwr", desclist->gpr.livewrite, desclist->fpr.livewrite);
3930      drcuml_log_printf(drcuml, "\n");
3931
3932      /* if we have a delay slot, output it recursively */
3933      if (desclist->delay != NULL)
3934         log_opcode_desc(drcuml, desclist->delay, indent + 1);
3935
3936      /* at the end of a sequence add a dividing line */
3937      if (desclist->flags & OPFLAG_END_SEQUENCE)
3938         drcuml_log_printf(drcuml, "-----\n");
3939   }
20023940}
2003#endif
20043941
20053942
2006static void ppc_get_context(void *dst)
3943
3944/***************************************************************************
3945    PPC 4XX VARIANTS
3946***************************************************************************/
3947
3948#if (HAS_PPC403GA || HAS_PPC403GCX)
3949
3950/*-------------------------------------------------
3951    ppcdrc4xx_get_info - PowerPC 4XX-specific
3952    information getter
3953-------------------------------------------------*/
3954
3955static void ppcdrc4xx_get_info(UINT32 state, cpuinfo *info)
20073956{
2008   /* copy the context */
2009   if (dst)
2010      *(PPC_REGS *)dst = ppc;
3957   ppcdrc_get_info(state, info);
3958   ppc4xx_get_info(ppc, state, info);
20113959}
20123960
20133961
2014static void ppc_set_context(void *src)
3962/*-------------------------------------------------
3963    ppcdrc4xx_set_info - PowerPC 4XX-specific
3964    information setter
3965-------------------------------------------------*/
3966
3967static void ppcdrc4xx_set_info(UINT32 state, cpuinfo *info)
20153968{
2016   /* copy the context */
2017   if (src)
2018      ppc = *(PPC_REGS *)src;
3969   ppcdrc_set_info(state, info);
3970   ppc4xx_set_info(ppc, state, info);
3971}
20193972
2020   change_pc(ppc.pc);
3973#endif
3974
3975
3976#if (HAS_PPC403GA)
3977
3978/*-------------------------------------------------
3979    ppc403ga_init - PowerPC 403GA-specific
3980    initialization
3981-------------------------------------------------*/
3982
3983static void ppc403ga_init(int index, int clock, const void *config, int (*irqcallback)(int))
3984{
3985   ppcdrc_init(PPC_MODEL_403GA, PPCCAP_4XX, 1, clock, config, irqcallback);
20213986}
20223987
20233988
2024/**************************************************************************
2025 * Generic set_info
2026 **************************************************************************/
3989/*-------------------------------------------------
3990    ppc403ga_get_info - PowerPC 403GA-specific
3991    information getter
3992-------------------------------------------------*/
20273993
2028static void ppc_set_info(UINT32 state, cpuinfo *info)
3994void ppc403ga_get_info(UINT32 state, cpuinfo *info)
20293995{
20303996   switch (state)
20313997   {
2032      case CPUINFO_INT_PC:
2033      case CPUINFO_INT_REGISTER + PPC_PC:            ppc.pc = info->i;                  break;
2034      case CPUINFO_INT_REGISTER + PPC_MSR:         ppc_set_msr(info->i);                break;
2035      case CPUINFO_INT_REGISTER + PPC_CR:            ppc_set_cr(info->i);                break;
2036      case CPUINFO_INT_REGISTER + PPC_LR:            LR = info->i;                     break;
2037      case CPUINFO_INT_REGISTER + PPC_CTR:         CTR = info->i;                     break;
2038      case CPUINFO_INT_REGISTER + PPC_XER:         XER = info->i;                      break;
2039      case CPUINFO_INT_REGISTER + PPC_SRR0:         SRR0 = info->i;                     break;
2040      case CPUINFO_INT_REGISTER + PPC_SRR1:         SRR1 = info->i;                     break;
3998      /* --- the following bits of info are returned as 64-bit signed integers --- */
20413999
2042      case CPUINFO_INT_REGISTER + PPC_R0:            ppc.r[0] = info->i;                  break;
2043      case CPUINFO_INT_REGISTER + PPC_R1:            ppc.r[1] = info->i;                  break;
2044      case CPUINFO_INT_REGISTER + PPC_R2:            ppc.r[2] = info->i;                  break;
2045      case CPUINFO_INT_REGISTER + PPC_R3:            ppc.r[3] = info->i;                  break;
2046      case CPUINFO_INT_REGISTER + PPC_R4:            ppc.r[4] = info->i;                  break;
2047      case CPUINFO_INT_REGISTER + PPC_R5:            ppc.r[5] = info->i;                  break;
2048      case CPUINFO_INT_REGISTER + PPC_R6:            ppc.r[6] = info->i;                  break;
2049      case CPUINFO_INT_REGISTER + PPC_R7:            ppc.r[7] = info->i;                  break;
2050      case CPUINFO_INT_REGISTER + PPC_R8:            ppc.r[8] = info->i;                  break;
2051      case CPUINFO_INT_REGISTER + PPC_R9:            ppc.r[9] = info->i;                  break;
2052      case CPUINFO_INT_REGISTER + PPC_R10:         ppc.r[10] = info->i;               break;
2053      case CPUINFO_INT_REGISTER + PPC_R11:         ppc.r[11] = info->i;               break;
2054      case CPUINFO_INT_REGISTER + PPC_R12:         ppc.r[12] = info->i;               break;
2055      case CPUINFO_INT_REGISTER + PPC_R13:         ppc.r[13] = info->i;               break;
2056      case CPUINFO_INT_REGISTER + PPC_R14:         ppc.r[14] = info->i;               break;
2057      case CPUINFO_INT_REGISTER + PPC_R15:         ppc.r[15] = info->i;               break;
2058      case CPUINFO_INT_REGISTER + PPC_R16:         ppc.r[16] = info->i;               break;
2059      case CPUINFO_INT_REGISTER + PPC_R17:         ppc.r[17] = info->i;               break;
2060      case CPUINFO_INT_REGISTER + PPC_R18:         ppc.r[18] = info->i;               break;
2061      case CPUINFO_INT_REGISTER + PPC_R19:         ppc.r[19] = info->i;               break;
2062      case CPUINFO_INT_REGISTER + PPC_R20:         ppc.r[20] = info->i;               break;
2063      case CPUINFO_INT_REGISTER + PPC_R21:         ppc.r[21] = info->i;               break;
2064      case CPUINFO_INT_REGISTER + PPC_R22:         ppc.r[22] = info->i;               break;
2065      case CPUINFO_INT_REGISTER + PPC_R23:         ppc.r[23] = info->i;               break;
2066      case CPUINFO_INT_REGISTER + PPC_R24:         ppc.r[24] = info->i;               break;
2067      case CPUINFO_INT_REGISTER + PPC_R25:         ppc.r[25] = info->i;               break;
2068      case CPUINFO_INT_REGISTER + PPC_R26:         ppc.r[26] = info->i;               break;
2069      case CPUINFO_INT_REGISTER + PPC_R27:         ppc.r[27] = info->i;               break;
2070      case CPUINFO_INT_REGISTER + PPC_R28:         ppc.r[28] = info->i;               break;
2071      case CPUINFO_INT_REGISTER + PPC_R29:         ppc.r[29] = info->i;               break;
2072      case CPUINFO_INT_REGISTER + PPC_R30:         ppc.r[30] = info->i;               break;
2073      case CPUINFO_INT_REGISTER + PPC_R31:         ppc.r[31] = info->i;               break;
4000      /* --- the following bits of info are returned as pointers to data or functions --- */
4001      case CPUINFO_PTR_INIT:                     info->init = ppc403ga_init;            break;
4002      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppcdrc4xx_set_info;      break;
20744003
2075      case CPUINFO_INT_PPC_DRC_OPTIONS:            ppc.drcoptions = info->i;            break;
4004      /* --- the following bits of info are returned as NULL-terminated strings --- */
4005      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC 403GA");      break;
4006
4007      /* --- everything else is handled generically --- */
4008      default:                              ppcdrc4xx_get_info(state, info);      break;
20764009   }
20774010}
20784011
2079static void ppc_get_info(UINT32 state, cpuinfo *info)
4012#endif
4013
4014
4015#if (HAS_PPC403GCX)
4016
4017/*-------------------------------------------------
4018    ppc403gcx_init - PowerPC 403GCX-specific
4019    initialization
4020-------------------------------------------------*/
4021
4022static void ppc403gcx_init(int index, int clock, const void *config, int (*irqcallback)(int))
20804023{
2081   switch(state)
4024   ppcdrc_init(PPC_MODEL_403GCX, PPCCAP_4XX, 1, clock, config, irqcallback);
4025}
4026
4027
4028/*-------------------------------------------------
4029    ppc403gcx_get_info - PowerPC 403GCX-specific
4030    information getter
4031-------------------------------------------------*/
4032
4033void ppc403gcx_get_info(UINT32 state, cpuinfo *info)
4034{
4035   switch (state)
20824036   {
20834037      /* --- the following bits of info are returned as 64-bit signed integers --- */
2084      case CPUINFO_INT_CONTEXT_SIZE:               info->i = sizeof(ppc);               break;
2085      case CPUINFO_INT_INPUT_LINES:               info->i = 1;                     break;
2086      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:         info->i = 0;                     break;
2087      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2088      case CPUINFO_INT_CLOCK_MULTIPLIER:            info->i = 1;                     break;
2089      case CPUINFO_INT_CLOCK_DIVIDER:               info->i = 1;                     break;
2090      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 4;                     break;
2091      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 4;                     break;
2092      case CPUINFO_INT_MIN_CYCLES:               info->i = 1;                     break;
2093      case CPUINFO_INT_MAX_CYCLES:               info->i = 40;                     break;
20944038
2095      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 32;               break;
2096      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2097      case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0;               break;
2098      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA:   info->i = 0;               break;
2099      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA:    info->i = 0;               break;
2100      case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA:    info->i = 0;               break;
2101      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO:      info->i = 0;               break;
2102      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO:       info->i = 0;               break;
2103      case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO:       info->i = 0;               break;
4039      /* --- the following bits of info are returned as pointers to data or functions --- */
4040      case CPUINFO_PTR_INIT:                     info->init = ppc403gcx_init;         break;
4041      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppcdrc4xx_set_info;      break;
21044042
2105      case CPUINFO_INT_INPUT_STATE:               info->i = CLEAR_LINE;               break;
4043      /* --- the following bits of info are returned as NULL-terminated strings --- */
4044      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC 403GCX");      break;
21064045
2107      case CPUINFO_INT_PREVIOUSPC:               /* not implemented */               break;
4046      /* --- everything else is handled generically --- */
4047      default:                              ppcdrc4xx_get_info(state, info);      break;
4048   }
4049}
21084050
2109      case CPUINFO_INT_PC:   /* intentional fallthrough */
2110      case CPUINFO_INT_REGISTER + PPC_PC:            info->i = ppc.pc;                  break;
2111      case CPUINFO_INT_REGISTER + PPC_MSR:         info->i = ppc_get_msr();            break;
2112      case CPUINFO_INT_REGISTER + PPC_CR:            info->i = ppc_get_cr();               break;
2113      case CPUINFO_INT_REGISTER + PPC_LR:            info->i = LR;                     break;
2114      case CPUINFO_INT_REGISTER + PPC_CTR:         info->i = CTR;                     break;
2115      case CPUINFO_INT_REGISTER + PPC_XER:         info->i = XER;                     break;
2116      case CPUINFO_INT_REGISTER + PPC_SRR0:         info->i = SRR0;                     break;
2117      case CPUINFO_INT_REGISTER + PPC_SRR1:         info->i = SRR1;                     break;
4051#endif
21184052
2119      case CPUINFO_INT_REGISTER + PPC_R0:            info->i = ppc.r[0];                  break;
2120      case CPUINFO_INT_REGISTER + PPC_R1:            info->i = ppc.r[1];                  break;
2121      case CPUINFO_INT_REGISTER + PPC_R2:            info->i = ppc.r[2];                  break;
2122      case CPUINFO_INT_REGISTER + PPC_R3:            info->i = ppc.r[3];                  break;
2123      case CPUINFO_INT_REGISTER + PPC_R4:            info->i = ppc.r[4];                  break;
2124      case CPUINFO_INT_REGISTER + PPC_R5:            info->i = ppc.r[5];                  break;
2125      case CPUINFO_INT_REGISTER + PPC_R6:            info->i = ppc.r[6];                  break;
2126      case CPUINFO_INT_REGISTER + PPC_R7:            info->i = ppc.r[7];                  break;
2127      case CPUINFO_INT_REGISTER + PPC_R8:            info->i = ppc.r[8];                  break;
2128      case CPUINFO_INT_REGISTER + PPC_R9:            info->i = ppc.r[9];                  break;
2129      case CPUINFO_INT_REGISTER + PPC_R10:         info->i = ppc.r[10];               break;
2130      case CPUINFO_INT_REGISTER + PPC_R11:         info->i = ppc.r[11];               break;
2131      case CPUINFO_INT_REGISTER + PPC_R12:         info->i = ppc.r[12];               break;
2132      case CPUINFO_INT_REGISTER + PPC_R13:         info->i = ppc.r[13];               break;
2133      case CPUINFO_INT_REGISTER + PPC_R14:         info->i = ppc.r[14];               break;
2134      case CPUINFO_INT_REGISTER + PPC_R15:         info->i = ppc.r[15];               break;
2135      case CPUINFO_INT_REGISTER + PPC_R16:         info->i = ppc.r[16];               break;
2136      case CPUINFO_INT_REGISTER + PPC_R17:         info->i = ppc.r[17];               break;
2137      case CPUINFO_INT_REGISTER + PPC_R18:         info->i = ppc.r[18];               break;
2138      case CPUINFO_INT_REGISTER + PPC_R19:         info->i = ppc.r[19];               break;
2139      case CPUINFO_INT_REGISTER + PPC_R20:         info->i = ppc.r[20];               break;
2140      case CPUINFO_INT_REGISTER + PPC_R21:         info->i = ppc.r[21];               break;
2141      case CPUINFO_INT_REGISTER + PPC_R22:         info->i = ppc.r[22];               break;
2142      case CPUINFO_INT_REGISTER + PPC_R23:         info->i = ppc.r[23];               break;
2143      case CPUINFO_INT_REGISTER + PPC_R24:         info->i = ppc.r[24];               break;
2144      case CPUINFO_INT_REGISTER + PPC_R25:         info->i = ppc.r[25];               break;
2145      case CPUINFO_INT_REGISTER + PPC_R26:         info->i = ppc.r[26];               break;
2146      case CPUINFO_INT_REGISTER + PPC_R27:         info->i = ppc.r[27];               break;
2147      case CPUINFO_INT_REGISTER + PPC_R28:         info->i = ppc.r[28];               break;
2148      case CPUINFO_INT_REGISTER + PPC_R29:         info->i = ppc.r[29];               break;
2149      case CPUINFO_INT_REGISTER + PPC_R30:         info->i = ppc.r[30];               break;
2150      case CPUINFO_INT_REGISTER + PPC_R31:         info->i = ppc.r[31];               break;
21514053
2152      /* --- the following bits of info are returned as pointers to data or functions --- */
2153      case CPUINFO_PTR_GET_CONTEXT:               info->getcontext = ppc_get_context;      break;
2154      case CPUINFO_PTR_SET_CONTEXT:               info->setcontext = ppc_set_context;      break;
2155      case CPUINFO_PTR_BURN:                     info->burn = NULL;                  break;
2156#ifdef ENABLE_DEBUGGER
2157      case CPUINFO_PTR_DISASSEMBLE:               info->disassemble = ppc_dasm;         break;
2158#endif /* ENABLE_DEBUGGER */
2159      case CPUINFO_PTR_INSTRUCTION_COUNTER:         info->icount = &ppc_icount;            break;
21604054
2161      /* --- the following bits of info are returned as NULL-terminated strings --- */
2162      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC403");            break;
2163      case CPUINFO_STR_CORE_FAMILY:               strcpy(info->s, "PowerPC");            break;
2164      case CPUINFO_STR_CORE_VERSION:               strcpy(info->s, "1.0");               break;
2165      case CPUINFO_STR_CORE_FILE:                  strcpy(info->s, __FILE__);            break;
2166      case CPUINFO_STR_CORE_CREDITS:               strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team");   break;
4055/***************************************************************************
4056    PPC 6XX VARIANTS
4057***************************************************************************/
21674058
2168      case CPUINFO_STR_FLAGS:                     strcpy(info->s, " ");               break;
4059#if (HAS_PPC601)
21694060
2170      case CPUINFO_STR_REGISTER + PPC_PC:            sprintf(info->s, "PC: %08X", ppc.pc);   break;
2171      case CPUINFO_STR_REGISTER + PPC_MSR:         sprintf(info->s, "MSR: %08X", ppc_get_msr()); break;
2172      case CPUINFO_STR_REGISTER + PPC_CR:            sprintf(info->s, "CR: %08X", ppc_get_cr()); break;
2173      case CPUINFO_STR_REGISTER + PPC_LR:            sprintf(info->s, "LR: %08X", LR);      break;
2174      case CPUINFO_STR_REGISTER + PPC_CTR:         sprintf(info->s, "CTR: %08X", CTR);      break;
2175      case CPUINFO_STR_REGISTER + PPC_XER:         sprintf(info->s, "XER: %08X", XER);      break;
2176      case CPUINFO_STR_REGISTER + PPC_SRR0:         sprintf(info->s, "SRR0: %08X", SRR0);   break;
2177      case CPUINFO_STR_REGISTER + PPC_SRR1:         sprintf(info->s, "SRR1: %08X", SRR1);   break;
4061/*-------------------------------------------------
4062    ppc601_init - PowerPC 601-specific
4063    initialization
4064-------------------------------------------------*/
21784065
2179      case CPUINFO_STR_REGISTER + PPC_R0:            sprintf(info->s, "R0: %08X", ppc.r[0]); break;
2180      case CPUINFO_STR_REGISTER + PPC_R1:            sprintf(info->s, "R1: %08X", ppc.r[1]); break;
2181      case CPUINFO_STR_REGISTER + PPC_R2:            sprintf(info->s, "R2: %08X", ppc.r[2]); break;
2182      case CPUINFO_STR_REGISTER + PPC_R3:            sprintf(info->s, "R3: %08X", ppc.r[3]); break;
2183      case CPUINFO_STR_REGISTER + PPC_R4:            sprintf(info->s, "R4: %08X", ppc.r[4]); break;
2184      case CPUINFO_STR_REGISTER + PPC_R5:            sprintf(info->s, "R5: %08X", ppc.r[5]); break;
2185      case CPUINFO_STR_REGISTER + PPC_R6:            sprintf(info->s, "R6: %08X", ppc.r[6]); break;
2186      case CPUINFO_STR_REGISTER + PPC_R7:            sprintf(info->s, "R7: %08X", ppc.r[7]); break;
2187      case CPUINFO_STR_REGISTER + PPC_R8:            sprintf(info->s, "R8: %08X", ppc.r[8]); break;
2188      case CPUINFO_STR_REGISTER + PPC_R9:            sprintf(info->s, "R9: %08X", ppc.r[9]); break;
2189      case CPUINFO_STR_REGISTER + PPC_R10:         sprintf(info->s, "R10: %08X", ppc.r[10]); break;
2190      case CPUINFO_STR_REGISTER + PPC_R11:         sprintf(info->s, "R11: %08X", ppc.r[11]); break;
2191      case CPUINFO_STR_REGISTER + PPC_R12:         sprintf(info->s, "R12: %08X", ppc.r[12]); break;
2192      case CPUINFO_STR_REGISTER + PPC_R13:         sprintf(info->s, "R13: %08X", ppc.r[13]); break;
2193      case CPUINFO_STR_REGISTER + PPC_R14:         sprintf(info->s, "R14: %08X", ppc.r[14]); break;
2194      case CPUINFO_STR_REGISTER + PPC_R15:         sprintf(info->s, "R15: %08X", ppc.r[15]); break;
2195      case CPUINFO_STR_REGISTER + PPC_R16:         sprintf(info->s, "R16: %08X", ppc.r[16]); break;
2196      case CPUINFO_STR_REGISTER + PPC_R17:         sprintf(info->s, "R17: %08X", ppc.r[17]); break;
2197      case CPUINFO_STR_REGISTER + PPC_R18:         sprintf(info->s, "R18: %08X", ppc.r[18]); break;
2198      case CPUINFO_STR_REGISTER + PPC_R19:         sprintf(info->s, "R19: %08X", ppc.r[19]); break;
2199      case CPUINFO_STR_REGISTER + PPC_R20:         sprintf(info->s, "R20: %08X", ppc.r[20]); break;
2200      case CPUINFO_STR_REGISTER + PPC_R21:         sprintf(info->s, "R21: %08X", ppc.r[21]); break;
2201      case CPUINFO_STR_REGISTER + PPC_R22:         sprintf(info->s, "R22: %08X", ppc.r[22]); break;
2202      case CPUINFO_STR_REGISTER + PPC_R23:         sprintf(info->s, "R23: %08X", ppc.r[23]); break;
2203      case CPUINFO_STR_REGISTER + PPC_R24:         sprintf(info->s, "R24: %08X", ppc.r[24]); break;
2204      case CPUINFO_STR_REGISTER + PPC_R25:         sprintf(info->s, "R25: %08X", ppc.r[25]); break;
2205      case CPUINFO_STR_REGISTER + PPC_R26:         sprintf(info->s, "R26: %08X", ppc.r[26]); break;
2206      case CPUINFO_STR_REGISTER + PPC_R27:         sprintf(info->s, "R27: %08X", ppc.r[27]); break;
2207      case CPUINFO_STR_REGISTER + PPC_R28:         sprintf(info->s, "R28: %08X", ppc.r[28]); break;
2208      case CPUINFO_STR_REGISTER + PPC_R29:         sprintf(info->s, "R29: %08X", ppc.r[29]); break;
2209      case CPUINFO_STR_REGISTER + PPC_R30:         sprintf(info->s, "R30: %08X", ppc.r[30]); break;
2210      case CPUINFO_STR_REGISTER + PPC_R31:         sprintf(info->s, "R31: %08X", ppc.r[31]); break;
2211   }
4066static void ppc601_init(int index, int clock, const void *config, int (*irqcallback)(int))
4067{
4068   ppcdrc_init(PPC_MODEL_601, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED, 0/* no TB */, clock, config, irqcallback);
22124069}
22134070
22144071
4072/*-------------------------------------------------
4073    ppc601_get_info - PowerPC 601-specific
4074    information getter
4075-------------------------------------------------*/
22154076
2216/* PowerPC 403 */
2217#if (HAS_PPC403)
2218static void ppc403_set_info(UINT32 state, cpuinfo *info)
4077void ppc601_get_info(UINT32 state, cpuinfo *info)
22194078{
2220   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
4079   switch (state)
22214080   {
2222      ppcdrc403_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2223      return;
4081      /* --- the following bits of info are returned as 64-bit signed integers --- */
4082
4083      /* --- the following bits of info are returned as pointers to data or functions --- */
4084      case CPUINFO_PTR_INIT:                     info->init = ppc601_init;            break;
4085
4086      /* --- the following bits of info are returned as NULL-terminated strings --- */
4087      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC 601");         break;
4088
4089      /* --- everything else is handled generically --- */
4090      default:                              ppcdrc_get_info(state, info);         break;
22244091   }
2225   switch(state)
2226   {
2227      default:   ppc_set_info(state, info);      break;
2228   }
22294092}
22304093
2231void ppc403_get_info(UINT32 state, cpuinfo *info)
4094#endif
4095
4096
4097#if (HAS_PPC602)
4098
4099/*-------------------------------------------------
4100    ppc602_init - PowerPC 602-specific
4101    initialization
4102-------------------------------------------------*/
4103
4104static void ppc602_init(int index, int clock, const void *config, int (*irqcallback)(int))
22324105{
2233   switch(state)
4106   ppcdrc_init(PPC_MODEL_602, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED, 1/* unknown */, clock, config, irqcallback);
4107}
4108
4109
4110/*-------------------------------------------------
4111    ppc602_get_info - PowerPC 602-specific
4112    information getter
4113-------------------------------------------------*/
4114
4115void ppc602_get_info(UINT32 state, cpuinfo *info)
4116{
4117   switch (state)
22344118   {
22354119      /* --- the following bits of info are returned as 64-bit signed integers --- */
2236      case CPUINFO_INT_INPUT_LINES:               info->i = 7;                     break;
2237      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
22384120
22394121      /* --- the following bits of info are returned as pointers to data or functions --- */
2240      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc403_set_info;      break;
2241      case CPUINFO_PTR_INIT:                     info->init = ppcdrc403_init;         break;
2242      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc403_reset;         break;
2243      case CPUINFO_PTR_EXIT:                     info->exit = ppcdrc403_exit;         break;
2244      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc403_execute;      break;
4122      case CPUINFO_PTR_INIT:                     info->init = ppc602_init;            break;
22454123
22464124      /* --- the following bits of info are returned as NULL-terminated strings --- */
2247      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC403");            break;
4125      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC 602");         break;
22484126
2249      default:                              ppc_get_info(state, info);            break;
4127      /* --- everything else is handled generically --- */
4128      default:                              ppcdrc_get_info(state, info);         break;
22504129   }
22514130}
4131
22524132#endif
22534133
2254/* PowerPC 603 */
4134
22554135#if (HAS_PPC603)
2256static void ppc603_set_info(UINT32 state, cpuinfo *info)
4136
4137/*-------------------------------------------------
4138    ppc603_init - PowerPC 603-specific
4139    initialization
4140-------------------------------------------------*/
4141
4142static void ppc603_init(int index, int clock, const void *config, int (*irqcallback)(int))
22574143{
2258   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2259   {
2260      ppcdrc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2261      return;
2262   }
2263   switch(state)
2264   {
2265      case CPUINFO_INT_REGISTER + PPC_DEC:         write_decrementer(info->i);            break;
2266      default:                              ppc_set_info(state, info);            break;
2267   }
4144   ppcdrc_init(PPC_MODEL_603, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4, clock, config, irqcallback);
22684145}
22694146
4147
4148/*-------------------------------------------------
4149    ppc603_get_info - PowerPC 603-specific
4150    information getter
4151-------------------------------------------------*/
4152
22704153void ppc603_get_info(UINT32 state, cpuinfo *info)
22714154{
2272   switch(state)
4155   switch (state)
22734156   {
22744157      /* --- the following bits of info are returned as 64-bit signed integers --- */
2275      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2276      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
2277      case CPUINFO_INT_REGISTER + PPC_DEC:         info->i = read_decrementer();         break;
22784158
2279      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2280      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2281      case CPUINFO_INT_LOGADDR_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2282      case CPUINFO_INT_PAGE_SHIFT + ADDRESS_SPACE_PROGRAM:    info->i = 17;               break;
2283
22844159      /* --- the following bits of info are returned as pointers to data or functions --- */
2285      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc603_set_info;      break;
2286      case CPUINFO_PTR_INIT:                     info->init = ppcdrc603_init;         break;
2287      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc603_reset;         break;
2288      case CPUINFO_PTR_EXIT:                     info->exit = ppcdrc603_exit;         break;
2289      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc603_execute;      break;
2290      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2291      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2292      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
2293      case CPUINFO_PTR_TRANSLATE:                  info->translate = ppc_translate_address_cb;   break;
4160      case CPUINFO_PTR_INIT:                     info->init = ppc603_init;            break;
22944161
22954162      /* --- the following bits of info are returned as NULL-terminated strings --- */
2296      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC603");            break;
2297      case CPUINFO_STR_REGISTER + PPC_DEC:         sprintf(info->s, "DEC: %08X", read_decrementer()); break;
4163      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC 603");         break;
22984164
2299      default:                              ppc_get_info(state, info);            break;
4165      /* --- everything else is handled generically --- */
4166      default:                              ppcdrc_get_info(state, info);         break;
23004167   }
23014168}
4169
23024170#endif
23034171
2304/* PowerPC 602 */
2305#if (HAS_PPC602)
2306static void ppc602_set_info(UINT32 state, cpuinfo *info)
4172
4173#if (HAS_PPC603E)
4174
4175/*-------------------------------------------------
4176    ppc603e_init - PowerPC 603e-specific
4177    initialization
4178-------------------------------------------------*/
4179
4180static void ppc603e_init(int index, int clock, const void *config, int (*irqcallback)(int))
23074181{
2308   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2309   {
2310      ppcdrc602_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2311      return;
2312   }
2313   switch(state)
2314   {
2315      default:   ppc_set_info(state, info);      break;
2316   }
4182   ppcdrc_init(PPC_MODEL_603E, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4, clock, config, irqcallback);
23174183}
23184184
2319void ppc602_get_info(UINT32 state, cpuinfo *info)
4185
4186/*-------------------------------------------------
4187    ppc603e_get_info - PowerPC 603e-specific
4188    information getter
4189-------------------------------------------------*/
4190
4191void ppc603e_get_info(UINT32 state, cpuinfo *info)
23204192{
2321   switch(state)
4193   switch (state)
23224194   {
23234195      /* --- the following bits of info are returned as 64-bit signed integers --- */
2324      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2325      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
23264196
2327      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2328      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2329      case CPUINFO_INT_LOGADDR_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2330      case CPUINFO_INT_PAGE_SHIFT + ADDRESS_SPACE_PROGRAM:    info->i = 17;               break;
2331
23324197      /* --- the following bits of info are returned as pointers to data or functions --- */
2333      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc602_set_info;      break;
2334      case CPUINFO_PTR_INIT:                     info->init = ppcdrc602_init;         break;
2335      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc602_reset;         break;
2336      case CPUINFO_PTR_EXIT:                     info->exit = ppcdrc602_exit;         break;
2337      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc602_execute;      break;
2338      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2339      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2340      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
2341      case CPUINFO_PTR_TRANSLATE:                  info->translate = ppc_translate_address_cb;   break;
4198      case CPUINFO_PTR_INIT:                     info->init = ppc603e_init;            break;
23424199
23434200      /* --- the following bits of info are returned as NULL-terminated strings --- */
2344      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC602");            break;
4201      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC 603e");      break;
23454202
2346      default:                              ppc_get_info(state, info);            break;
4203      /* --- everything else is handled generically --- */
4204      default:                              ppcdrc_get_info(state, info);         break;
23474205   }
23484206}
4207
23494208#endif
23504209
2351/* Motorola MPC8240 */
23524210
2353#if (HAS_MPC8240)
2354static void mpc8240_set_info(UINT32 state, cpuinfo *info)
4211#if (HAS_PPC603R)
4212
4213/*-------------------------------------------------
4214    ppc603r_init - PowerPC 603r-specific
4215    initialization
4216-------------------------------------------------*/
4217
4218static void ppc603r_init(int index, int clock, const void *config, int (*irqcallback)(int))
23554219{
2356   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2357   {
2358      ppcdrc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2359      return;
2360   }
2361   switch(state)
2362   {
2363      default:                              ppc_set_info(state, info);            break;
2364   }
4220   ppcdrc_init(PPC_MODEL_603R, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED | PPCCAP_603_MMU, 4, clock, config, irqcallback);
23654221}
23664222
2367void mpc8240_get_info(UINT32 state, cpuinfo *info)
4223
4224/*-------------------------------------------------
4225    ppc603r_get_info - PowerPC 603r-specific
4226    information getter
4227-------------------------------------------------*/
4228
4229void ppc603r_get_info(UINT32 state, cpuinfo *info)
23684230{
2369   switch(state)
4231   switch (state)
23704232   {
23714233      /* --- the following bits of info are returned as 64-bit signed integers --- */
2372      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2373      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
23744234
2375      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2376      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2377
23784235      /* --- the following bits of info are returned as pointers to data or functions --- */
2379      case CPUINFO_PTR_SET_INFO:                  info->setinfo = mpc8240_set_info;      break;
2380      case CPUINFO_PTR_INIT:                     info->init = mpc8240drc_init;         break;
2381      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc603_reset;         break;
2382      case CPUINFO_PTR_EXIT:                     info->exit = mpc8240drc_exit;         break;
2383      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc603_execute;      break;
2384      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2385      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2386      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
4236      case CPUINFO_PTR_INIT:                     info->init = ppc603r_init;            break;
23874237
23884238      /* --- the following bits of info are returned as NULL-terminated strings --- */
2389      case CPUINFO_STR_NAME:                     strcpy(info->s, "MPC8240");            break;
4239      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC 603R");      break;
23904240
2391      default:                              ppc_get_info(state, info);            break;
4241      /* --- everything else is handled generically --- */
4242      default:                              ppcdrc_get_info(state, info);         break;
23924243   }
23934244}
4245
23944246#endif
23954247
23964248
2397/* PPC601 */
4249#if (HAS_PPC604)
23984250
2399#if (HAS_PPC601)
2400static void ppc601_set_info(UINT32 state, cpuinfo *info)
4251/*-------------------------------------------------
4252    ppc604_init - PowerPC 604-specific
4253    initialization
4254-------------------------------------------------*/
4255
4256static void ppc604_init(int index, int clock, const void *config, int (*irqcallback)(int))
24014257{
2402   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2403   {
2404      ppcdrc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2405      return;
2406   }
2407   switch(state)
2408   {
2409      default:                              ppc_set_info(state, info);            break;
2410   }
4258   ppcdrc_init(PPC_MODEL_604, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED, 4, clock, config, irqcallback);
24114259}
24124260
2413void ppc601_get_info(UINT32 state, cpuinfo *info)
4261
4262/*-------------------------------------------------
4263    ppc604_get_info - PowerPC 604-specific
4264    information getter
4265-------------------------------------------------*/
4266
4267void ppc604_get_info(UINT32 state, cpuinfo *info)
24144268{
2415   switch(state)
4269   switch (state)
24164270   {
24174271      /* --- the following bits of info are returned as 64-bit signed integers --- */
2418      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2419      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
24204272
2421      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2422      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2423
24244273      /* --- the following bits of info are returned as pointers to data or functions --- */
2425      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc601_set_info;      break;
2426      case CPUINFO_PTR_INIT:                     info->init = ppc601drc_init;         break;
2427      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc603_reset;         break;
2428      case CPUINFO_PTR_EXIT:                     info->exit = ppc601drc_exit;         break;
2429      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc603_execute;      break;
2430      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2431      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2432      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
4274      case CPUINFO_PTR_INIT:                     info->init = ppc604_init;            break;
24334275
24344276      /* --- the following bits of info are returned as NULL-terminated strings --- */
2435      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC601");            break;
4277      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC 604");         break;
24364278
2437      default:                              ppc_get_info(state, info);            break;
4279      /* --- everything else is handled generically --- */
4280      default:                              ppcdrc_get_info(state, info);         break;
24384281   }
24394282}
4283
24404284#endif
24414285
2442/* PPC604 */
24434286
2444#if (HAS_PPC604)
2445static void ppc604_set_info(UINT32 state, cpuinfo *info)
4287
4288/***************************************************************************
4289    PPC 6XX VARIANTS
4290***************************************************************************/
4291
4292#if (HAS_MPC8240)
4293
4294/*-------------------------------------------------
4295    mpc8240_init - PowerPC MPC8240-specific
4296    initialization
4297-------------------------------------------------*/
4298
4299static void mpc8240_init(int index, int clock, const void *config, int (*irqcallback)(int))
24464300{
2447   if (state >= CPUINFO_INT_INPUT_STATE && state <= CPUINFO_INT_INPUT_STATE + 5)
2448   {
2449      ppcdrc603_set_irq_line(state-CPUINFO_INT_INPUT_STATE, info->i);
2450      return;
2451   }
2452   switch(state)
2453   {
2454      default:                              ppc_set_info(state, info);            break;
2455   }
4301   ppcdrc_init(PPC_MODEL_MPC8240, PPCCAP_OEA | PPCCAP_VEA | PPCCAP_FPU | PPCCAP_MISALIGNED, 4/* unknown */, clock, config, irqcallback);
24564302}
24574303
2458void ppc604_get_info(UINT32 state, cpuinfo *info)
4304
4305/*-------------------------------------------------
4306    mpc8240_get_info - PowerPC MPC8240-specific
4307    information getter
4308-------------------------------------------------*/
4309
4310void mpc8240_get_info(UINT32 state, cpuinfo *info)
24594311{
2460   switch(state)
4312   switch (state)
24614313   {
24624314      /* --- the following bits of info are returned as 64-bit signed integers --- */
2463      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
2464      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
24654315
2466      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
2467      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
2468
24694316      /* --- the following bits of info are returned as pointers to data or functions --- */
2470      case CPUINFO_PTR_SET_INFO:                  info->setinfo = ppc604_set_info;      break;
2471      case CPUINFO_PTR_INIT:                     info->init = ppc604drc_init;         break;
2472      case CPUINFO_PTR_RESET:                     info->reset = ppcdrc603_reset;         break;
2473      case CPUINFO_PTR_EXIT:                     info->exit = ppc604drc_exit;         break;
2474      case CPUINFO_PTR_EXECUTE:                  info->execute = ppcdrc603_execute;      break;
2475      case CPUINFO_PTR_READ:                     info->read = ppc_read;               break;
2476      case CPUINFO_PTR_WRITE:                     info->write = ppc_write;            break;
2477      case CPUINFO_PTR_READOP:                  info->readop = ppc_readop;            break;
4317      case CPUINFO_PTR_INIT:                     info->init = mpc8240_init;            break;
24784318
24794319      /* --- the following bits of info are returned as NULL-terminated strings --- */
2480      case CPUINFO_STR_NAME:                     strcpy(info->s, "PPC604");            break;
4320      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC MPC8240");      break;
24814321
2482      default:                              ppc_get_info(state, info);            break;
4322      /* --- everything else is handled generically --- */
4323      default:                              ppcdrc_get_info(state, info);         break;
24834324   }
24844325}
4326
24854327#endif
4328
4329
4330
4331/***************************************************************************
4332    DISASSEMBLERS
4333***************************************************************************/
4334
4335#if !defined(MAME_DEBUG) && (LOG_UML || LOG_NATIVE)
4336#include "ppc_dasm.c"
4337#endif
src/emu/cpu/powerpc/ppc_mem.c
r2821r2822
297297}
298298
299299#if (HAS_PPC602||HAS_PPC603)
300static int ppc_translate_address_cb(int space, int intention, offs_t *addr)
300static int ppc_translate_address_cb(int space, offs_t *addr)
301301{
302302   int success = 1;
303303
src/emu/cpu/powerpc/ppccom.c
r0r2822
1/***************************************************************************
2 
3    ppccom.c
4 
5    Common PowerPC definitions and functions
6 
7***************************************************************************/
8 
9#include "ppccom.h"
10#include "deprecat.h"
11 
12 
13/***************************************************************************
14    DEBUGGING
15***************************************************************************/
16 
17#define PRINTF_TLB_FILL         (0)
18#define PRINTF_SPU            (0)
19#define PRINTF_DECREMENTER      (0)
20 
21 
22 
23/***************************************************************************
24    FUNCTION PROTOTYPES
25***************************************************************************/
26 
27static TIMER_CALLBACK( ppc4xx_fit_callback );
28static TIMER_CALLBACK( ppc4xx_pit_callback );
29static TIMER_CALLBACK( ppc4xx_spu_callback );
30static TIMER_CALLBACK( decrementer_int_callback );
31 
32static void ppc4xx_set_irq_line(powerpc_state *ppc, UINT32 bitmask, int state);
33 
34static void ppc4xx_dma_update_irq_states(powerpc_state *ppc);
35static int ppc4xx_dma_fetch_transmit_byte(powerpc_state *ppc, int dmachan, UINT8 *byte);
36static int ppc4xx_dma_handle_receive_byte(powerpc_state *ppc, int dmachan, UINT8 byte);
37static void ppc4xx_dma_exec(powerpc_state *ppc, int dmachan);
38 
39static void ppc4xx_spu_update_irq_states(powerpc_state *ppc);
40static void ppc4xx_spu_timer_reset(powerpc_state *ppc);
41 
42 
43 
44/***************************************************************************
45    INLINE FUNCTIONS
46***************************************************************************/
47 
48/*-------------------------------------------------
49    page_access_allowed - return true if we are
50    allowed to access memory based on the type
51    of access and the protection bits
52-------------------------------------------------*/
53 
54INLINE int page_access_allowed(int transtype, UINT8 key, UINT8 protbits)
55{
56   if (key == 0)
57      return (transtype == TRANSLATE_WRITE) ? (protbits != 3) : TRUE;
58   else
59      return (transtype == TRANSLATE_WRITE) ? (protbits == 2) : (protbits != 0);
60}
61 
62 
63/*-------------------------------------------------
64    tlb_entry_free - free an entry from the TLB,
65    by index
66-------------------------------------------------*/
67 
68INLINE void tlb_entry_free(powerpc_state *ppc, int entrynum)
69{
70   int oldentry = ppc->tlb_entries[entrynum];
71 
72   /* if we're mapped to something, free the entry in the table */
73   if (oldentry != 0)
74   {
75      ppc->tlb_table[oldentry - 1] = 0;
76      ppc->tlb_entries[entrynum] = 0;
77   }
78}
79 
80 
81/*-------------------------------------------------
82    tlb_entry_allocate - allocate a TLB entry
83    for the given address, if needed, and set its
84    new value
85-------------------------------------------------*/
86 
87INLINE int tlb_entry_allocate(powerpc_state *ppc, int entrynum, offs_t address, UINT32 value)
88{
89   UINT32 *entry = &ppc->tlb_table[address >> 12];
90   int allocated = FALSE;
91 
92   /* only need to allocate if we are empty */
93   if (*entry == 0)
94   {
95      /* if there's already a TLB entry at the current index, zap it */
96      tlb_entry_free(ppc, entrynum);
97 
98      /* allocate a new entry and advance to the next one */
99      ppc->tlb_entries[entrynum] = (address >> 12) + 1;
100      allocated = TRUE;
101   }
102   *entry = value;
103 
104   return allocated;
105}
106 
107 
108/*-------------------------------------------------
109    get_timebase - return the current timebase
110    value
111-------------------------------------------------*/
112 
113INLINE UINT64 get_timebase(powerpc_state *ppc)
114{
115   return (cpunum_gettotalcycles(ppc->cpunum) - ppc->tb_zero_cycles) / ppc->tb_divisor;
116}
117 
118 
119/*-------------------------------------------------
120    set_timebase - set the timebase
121-------------------------------------------------*/
122 
123INLINE void set_timebase(powerpc_state *ppc, UINT64 newtb)
124{
125   ppc->tb_zero_cycles = activecpu_gettotalcycles() - newtb * ppc->tb_divisor;
126}
127 
128 
129/*-------------------------------------------------
130    get_decremeter - return the current
131    decrementer value
132-------------------------------------------------*/
133 
134INLINE UINT32 get_decrementer(powerpc_state *ppc)
135{
136   INT64 cycles_until_zero = ppc->dec_zero_cycles - cpunum_gettotalcycles(ppc->cpunum);
137   cycles_until_zero = MAX(cycles_until_zero, 0);
138   return cycles_until_zero / ppc->tb_divisor;
139}
140 
141 
142/*-------------------------------------------------
143    set_decrementer - set the decremeter
144-------------------------------------------------*/
145 
146INLINE void set_decrementer(powerpc_state *ppc, UINT32 newdec)
147{
148   UINT64 cycles_until_done = ((UINT64)newdec + 1) * ppc->tb_divisor;
149   UINT32 curdec = get_decrementer(ppc);
150 
151   if (PRINTF_DECREMENTER)
152   {
153      UINT64 total = cpunum_gettotalcycles(ppc->cpunum);
154      mame_printf_debug("set_decrementer: olddec=%08X newdec=%08X divisor=%d totalcyc=%08X%08X timer=%08X%08X\n",
155            curdec, newdec, ppc->tb_divisor,
156            (UINT32)(total >> 32), (UINT32)total, (UINT32)(cycles_until_done >> 32), (UINT32)cycles_until_done);
157   }
158 
159   ppc->dec_zero_cycles = cpunum_gettotalcycles(ppc->cpunum) + cycles_until_done;
160   timer_adjust_oneshot(ppc->decrementer_int_timer, ATTOTIME_IN_CYCLES(cycles_until_done, ppc->cpunum), 0);
161 
162   if ((INT32)curdec >= 0 && (INT32)newdec < 0)
163      ppc->irq_pending |= 0x02;
164}
165 
166 
167 
168/***************************************************************************
169    INITIALIZATION AND SHUTDOWN
170***************************************************************************/
171 
172/*-------------------------------------------------
173    ppccom_init - initialize the powerpc_state
174    structure based on the configured type
175-------------------------------------------------*/
176 
177size_t ppccom_init(powerpc_state *ppc, powerpc_flavor flavor, UINT8 cap, int tb_divisor, int clock, const powerpc_config *config, int (*irqcallback)(int), void *memory)
178{
179   /* if no memory, return the amount needed */
180   if (memory == NULL)
181      return sizeof(ppc->tlb_table[0]) * (POWERPC_TLB_ENTRIES + PPC603_FIXED_TLB_ENTRIES + (1 << (32 - POWERPC_MIN_PAGE_SHIFT)));
182 
183   /* initialize based on the config */
184   memset(ppc, 0, sizeof(*ppc));
185   ppc->cpunum = cpu_getactivecpu();
186   ppc->flavor = flavor;
187   ppc->cap = cap;
188   ppc->cache_line_size = 32;
189   ppc->tb_divisor = tb_divisor;
190   ppc->cpu_clock = clock;
191   ppc->irq_callback = irqcallback;
192   ppc->system_clock = (config != NULL) ? config->bus_frequency : clock;
193   ppc->tb_divisor = (ppc->tb_divisor * clock + ppc->system_clock / 2 - 1) / ppc->system_clock;
194 
195   /* initialize the TLB state */
196   ppc->tlb_entries = memory;
197   ppc->tlb_table = ppc->tlb_entries + POWERPC_TLB_ENTRIES + PPC603_FIXED_TLB_ENTRIES;
198 
199   /* allocate a timer for the compare interrupt */
200   if (cap & PPCCAP_OEA)
201      ppc->decrementer_int_timer = timer_alloc(decrementer_int_callback, ppc);
202 
203   /* and for the 4XX interrupts if needed */
204   if (cap & PPCCAP_4XX)
205   {
206      ppc->fit_timer = timer_alloc(ppc4xx_fit_callback, ppc);
207      ppc->pit_timer = timer_alloc(ppc4xx_pit_callback, ppc);
208      ppc->spu.timer = timer_alloc(ppc4xx_spu_callback, ppc);
209   }
210 
211   /* reset the state */
212   ppccom_reset(ppc);
213   return 0;
214}
215 
216 
217/*-------------------------------------------------
218    ppccom_reset - reset the state of all the
219    registers
220-------------------------------------------------*/
221 
222void ppccom_reset(powerpc_state *ppc)
223{
224   /* initialize the OEA state */
225   if (ppc->cap & PPCCAP_OEA)
226   {
227      /* PC to the reset vector; MSR has IP set to start */
228      ppc->pc = 0xfff00100;
229      ppc->msr = MSROEA_IP;
230 
231      /* reset the decrementer */
232      ppc->dec_zero_cycles = cpunum_gettotalcycles(ppc->cpunum);
233      decrementer_int_callback(Machine, ppc, 0);
234   }
235 
236   /* initialize the 4XX state */
237   if (ppc->cap & PPCCAP_4XX)
238   {
239      /* PC to the last word; MSR to 0 */
240      ppc->pc = 0xfffffffc;
241      ppc->msr = 0;
242 
243      /* reset the SPU status */
244      ppc->spr[SPR4XX_TCR] &= ~PPC4XX_TCR_WRC_MASK;
245      ppc->spu.regs[SPU4XX_LINE_STATUS] = 0x06;
246   }
247 
248   /* time base starts here */
249   ppc->tb_zero_cycles = cpunum_gettotalcycles(ppc->cpunum);
250 
251   /* clear interrupts */
252   ppc->irq_pending = 0;
253 
254   /* flush the TLB */
255   ppc->tlb_index = 0;
256   memset(ppc->tlb_entries, 0, sizeof(ppc->tlb_entries[0]) * (POWERPC_TLB_ENTRIES + PPC603_FIXED_TLB_ENTRIES));
257   memset(ppc->tlb_table, 0, sizeof(ppc->tlb_table[0]) * (1 << (32 - POWERPC_MIN_PAGE_SHIFT)));
258}
259 
260 
261/*-------------------------------------------------
262    ppccom_dasm - handle disassembly for a
263    CPU
264-------------------------------------------------*/
265 
266#ifdef ENABLE_DEBUGGER
267offs_t ppccom_dasm(powerpc_state *ppc, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
268{
269   extern offs_t ppc_dasm_one(char *buffer, UINT32 pc, UINT32 op);
270   UINT32 op = *(UINT32 *)oprom;
271   op = BIG_ENDIANIZE_INT32(op);
272   return ppc_dasm_one(buffer, pc, op);
273}
274#endif /* ENABLE_DEBUGGER */
275 
276 
277 
278/***************************************************************************
279    TLB HANDLING
280***************************************************************************/
281 
282/*-------------------------------------------------
283    ppccom_translate_address_internal - translate
284    an address from logical to physical; shared
285    between external requests and internal TLB
286    filling
287-------------------------------------------------*/
288 
289static UINT32 ppccom_translate_address_internal(powerpc_state *ppc, int intention, offs_t *address)
290{
291   int transpriv = ((intention & TRANSLATE_USER_MASK) == 0);
292   int transtype = intention & TRANSLATE_TYPE_MASK;
293   offs_t hash, hashbase, hashmask;
294   int batbase, batnum, hashnum;
295   UINT32 segreg;
296 
297   /* only applies if we support the OEA */
298   if (!(ppc->cap & PPCCAP_OEA))
299      return 0x001;
300 
301   /* also no translation necessary if translation is disabled */
302   if ((transtype == TRANSLATE_FETCH && (ppc->msr & MSROEA_IR) == 0) || (transtype != TRANSLATE_FETCH && (ppc->msr & MSROEA_DR) == 0))
303      return 0x001;
304 
305   /* first scan the appropriate BAT */
306   batbase = (transtype == TRANSLATE_FETCH) ? SPROEA_IBAT0U : SPROEA_DBAT0U;
307   for (batnum = 0; batnum < 4; batnum++)
308   {
309      UINT32 upper = ppc->spr[batbase + 2*batnum + 0];
310 
311      /* check user/supervisor valid bit */
312      if ((upper >> transpriv) & 0x01)
313      {
314         UINT32 mask = (~upper << 15) & 0xfffe0000;
315 
316         /* check for a hit against this bucket */
317         if ((*address & mask) == (upper & mask))
318         {
319            UINT32 lower = ppc->spr[batbase + 2*batnum + 1];
320 
321            /* verify protection; if we fail, return false and indicate a protection violation */
322            if (!page_access_allowed(transtype, 1, lower & 3))
323               return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
324 
325            /* otherwise we're good */
326            *address = (lower & mask) | (*address & ~mask);
327            return 0x001;
328         }
329      }
330   }
331 
332   /* look up the segment register */
333   segreg = ppc->sr[*address >> 28];
334   if (transtype == TRANSLATE_FETCH && (segreg & 0x10000000))
335      return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
336 
337   /* get hash table information from SD1 */
338   hashbase = ppc->spr[SPROEA_SDR1] & 0xffff0000;
339   hashmask = ((ppc->spr[SPROEA_SDR1] & 0x1ff) << 16) | 0xffff;
340   hash = (segreg & 0x7ffff) ^ ((*address >> 12) & 0xffff);
341 
342   /* if we're simulating the 603 MMU, fill in the data and stop here */
343   if (ppc->cap & PPCCAP_603_MMU)
344   {
345      ppc->mmu603_cmp = 0x80000000 | ((segreg & 0xffffff) << 7) | (0 << 6) | ((*address >> 22) & 0x3f);
346      ppc->mmu603_hash[0] = hashbase | ((hash << 6) & hashmask);
347      ppc->mmu603_hash[1] = hashbase | ((~hash << 6) & hashmask);
348      return DSISR_NOT_FOUND | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
349   }
350 
351   /* loop twice over hashes */
352   for (hashnum = 0; hashnum < 2; hashnum++)
353   {
354      offs_t ptegaddr = hashbase | ((hash << 6) & hashmask);
355      UINT32 *ptegptr = memory_get_read_ptr(cpu_getactivecpu(), ADDRESS_SPACE_PROGRAM, ptegaddr);
356 
357      /* should only have valid memory here, but make sure */
358      if (ptegptr != NULL)
359      {
360         UINT32 targetupper = 0x80000000 | ((segreg & 0xffffff) << 7) | (hashnum << 6) | ((*address >> 22) & 0x3f);
361         int ptenum;
362 
363         /* scan PTEs */
364         for (ptenum = 0; ptenum < 8; ptenum++)
365            if (ptegptr[BYTE_XOR_BE(ptenum * 2)] == targetupper)
366            {
367               UINT32 pteglower = ptegptr[BYTE_XOR_BE(ptenum * 2 + 1)];
368 
369               /* verify protection; if we fail, return false and indicate a protection violation */
370               if (!page_access_allowed(transtype, (segreg >> (29 + transpriv)) & 1, pteglower & 3))
371                  return DSISR_PROTECTED | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
372 
373               /* update page table bits */
374               if (!(intention & TRANSLATE_DEBUG_MASK))
375               {
376                  pteglower |= 0x100;
377                  if (transtype == TRANSLATE_WRITE)
378                     pteglower |= 0x080;
379                  ptegptr[BYTE_XOR_BE(ptenum * 2 + 1)] = pteglower;
380               }
381 
382               /* otherwise we're good */
383               *address = (pteglower & 0xfffff000) | (*address & 0x00000fff);
384               return (pteglower >> 7) & 1;
385            }
386      }
387 
388      /* invert the hash after the first round */
389      hash = ~hash;
390   }
391 
392   /* we failed to find any match: not found */
393   return DSISR_NOT_FOUND | ((transtype == TRANSLATE_WRITE) ? DSISR_STORE : 0);
394}
395 
396 
397/*-------------------------------------------------
398    ppccom_translate_address - translate an address
399    from logical to physical
400-------------------------------------------------*/
401 
402int ppccom_translate_address(powerpc_state *ppc, int space, int intention, offs_t *address)
403{
404   /* only applies to the program address space */
405   if (space != ADDRESS_SPACE_PROGRAM)
406      return TRUE;
407 
408   /* translation is successful if the internal routine returns 0 or 1 */
409   return (ppccom_translate_address_internal(ppc, intention, address) <= 1);
410}
411 
412 
413/*-------------------------------------------------
414    ppccom_tlb_fill - handle a missing TLB entry
415-------------------------------------------------*/
416 
417void ppccom_tlb_fill(powerpc_state *ppc)
418{
419   int transuser = (ppc->msr & MSR_PR) ? TRANSLATE_USER_MASK : 0;
420   offs_t address = ppc->param0;
421   int transtype = ppc->param1;
422   offs_t transaddr = address;
423   UINT32 entryval;
424 
425   /* allow for an implementation-specific override */
426   if (ppc->tlb_fill != NULL && (*ppc->tlb_fill)(ppc))
427      return;
428 
429   /* if we can't translate the address, just return (and fail) */
430   ppc->param0 = ppccom_translate_address_internal(ppc, transtype | transuser, &transaddr);
431   if (PRINTF_TLB_FILL)
432      printf("tlb_fill: %08X (%s%s) -> ", address, (transtype == TRANSLATE_READ) ? "R" : (transtype == TRANSLATE_WRITE) ? "W" : "F", transuser ? " U" : "S");
433   if (ppc->param0 > 1)
434   {
435      if (PRINTF_TLB_FILL)
436         printf("failed(%08X)\n", ppc->param0);
437      return;
438   }
439 
440   /* if we did translate the address, get a pointer to our entry in the TLB table and fill it in */
441   if (PRINTF_TLB_FILL)
442      printf("succeeded(%d) -> %08X\n", ppc->param0, transaddr);
443   entryval = (transaddr & 0xfffff000) | TLB_READ | ((ppc->param0 & 1) ? TLB_WRITE : 0);
444   if (tlb_entry_allocate(ppc, ppc->tlb_index, address, entryval))
445      ppc->tlb_index = (ppc->tlb_index + 1) % POWERPC_TLB_ENTRIES;
446}
447 
448 
449/*-------------------------------------------------
450    ppccom_tlb_flush - flush the entire TLB,
451    including fixed entries
452-------------------------------------------------*/
453 
454void ppccom_tlb_flush(powerpc_state *ppc)
455{
456   int entnum;
457 
458   /* iterate over entries and invalidate them */
459   for (entnum = 0; entnum < POWERPC_TLB_ENTRIES; entnum++)
460      tlb_entry_free(ppc, entnum);
461}
462 
463 
464 
465/***************************************************************************
466    OPCODE HANDLING
467***************************************************************************/
468 
469/*-------------------------------------------------
470    ppccom_execute_tlbie - execute a TLBIE
471    instruction
472-------------------------------------------------*/
473 
474void ppccom_execute_tlbie(powerpc_state *ppc)
475{
476   offs_t address = ppc->param0;
477 
478   /* just nuke it in the table; we may have spare entries referencing it, but no harm */
479   ppc->tlb_table[address >> 12] = 0;
480}
481 
482 
483/*-------------------------------------------------
484    ppccom_execute_tlbia - execute a TLBIA
485    instruction
486-------------------------------------------------*/
487 
488void ppccom_execute_tlbia(powerpc_state *ppc)
489{
490   ppccom_tlb_flush(ppc);
491}
492 
493 
494/*-------------------------------------------------
495    ppccom_execute_tlbl - execute a TLBLD/TLBLI
496    instruction
497-------------------------------------------------*/
498 
499void ppccom_execute_tlbl(powerpc_state *ppc)
500{
501   UINT32 address = ppc->param0;
502   int isitlb = ppc->param1;
503   UINT32 entrynum, entryval;
504 
505   /* determine entry number; we use rand() for associativity */
506   entrynum = ((address >> 12) & 0x1f) | (mame_rand(Machine) & 0x20) | (isitlb ? 0x40 : 0);
507 
508   /* invalidate any existing TLB entry here */
509   ppc->tlb_table[address >> 12] = 0;
510 
511   /* allocate this entry */
512   entryval = (ppc->spr[SPR603_RPA] & 0xfffff000) | TLB_READ | ((ppc->spr[SPR603_RPA] & 0x80) ? TLB_WRITE : 0);
513   tlb_entry_allocate(ppc, POWERPC_TLB_ENTRIES + entrynum, address, entryval);
514   if (PRINTF_TLB_FILL)
515      printf("tlb_load: %08X (%sS) -> %08X\n", address, isitlb ? "F" : "R", ppc->spr[SPR603_RPA] & 0xfffff000);
516}
517 
518 
519/*-------------------------------------------------
520    ppccom_execute_mftb - execute an MFTB
521    instruction
522-------------------------------------------------*/
523 
524void ppccom_execute_mftb(powerpc_state *ppc)
525{
526   switch (ppc->param0)
527   {
528      /* user mode timebase read */
529      case SPRVEA_TBL_R:
530         ppc->param1 = get_timebase(ppc);
531         break;
532      case SPRVEA_TBU_R:
533         ppc->param1 = get_timebase(ppc) >> 32;
534         break;
535   }
536}
537 
538 
539/*-------------------------------------------------
540    ppccom_execute_mfspr - execute an MFSPR
541    instruction
542-------------------------------------------------*/
543 
544void ppccom_execute_mfspr(powerpc_state *ppc)
545{
546   /* handle OEA SPRs */
547   if (ppc->cap & PPCCAP_OEA)
548   {
549      switch (ppc->param0)
550      {
551         /* read-through no-ops */
552         case SPROEA_DSISR:
553         case SPROEA_DAR:
554         case SPROEA_SDR1:
555         case SPROEA_SRR0:
556         case SPROEA_SRR1:
557         case SPROEA_EAR:
558         case SPROEA_IBAT0L:
559         case SPROEA_IBAT0U:
560         case SPROEA_IBAT1L:
561         case SPROEA_IBAT1U:
562         case SPROEA_IBAT2L:
563         case SPROEA_IBAT2U:
564         case SPROEA_IBAT3L:
565         case SPROEA_IBAT3U:
566         case SPROEA_DBAT0L:
567         case SPROEA_DBAT0U:
568         case SPROEA_DBAT1L:
569         case SPROEA_DBAT1U:
570         case SPROEA_DBAT2L:
571         case SPROEA_DBAT2U:
572         case SPROEA_DBAT3L:
573         case SPROEA_DBAT3U:
574         case SPROEA_DABR:
575            ppc->param1 = ppc->spr[ppc->param0];
576            return;
577 
578         /* decrementer */
579         case SPROEA_DEC:
580            ppc->param1 = get_decrementer(ppc);
581            return;
582      }
583   }
584 
585   /* handle 603 SPRs */
586   if (ppc->cap & PPCCAP_603_MMU)
587   {
588      switch (ppc->param0)
589      {
590         /* read-through no-ops */
591         case SPR603_DMISS:
592         case SPR603_DCMP:
593         case SPR603_HASH1:
594         case SPR603_HASH2:
595         case SPR603_IMISS:
596         case SPR603_ICMP:
597         case SPR603_RPA:
598         case SPR603_HID0:
599         case SPR603_HID1:
600         case SPR603_IABR:
601         case SPR603_HID2:
602            ppc->param1 = ppc->spr[ppc->param0];
603            return;
604 
605         /* timebase */
606         case SPR603_TBL_R:
607            ppc->param1 = get_timebase(ppc);
608            return;
609         case SPR603_TBU_R:
610            ppc->param1 = (get_timebase(ppc) >> 32) & 0xffffff;
611            return;
612      }
613   }
614 
615   /* handle 4XX SPRs */
616   if (ppc->cap & PPCCAP_4XX)
617   {
618      switch (ppc->param0)
619      {
620         /* read-through no-ops */
621         case SPR4XX_EVPR:
622         case SPR4XX_ESR:
623         case SPR4XX_DCCR:
624         case SPR4XX_ICCR:
625         case SPR4XX_SRR0:
626         case SPR4XX_SRR1:
627         case SPR4XX_SRR2:
628         case SPR4XX_SRR3:
629         case SPR4XX_TCR:
630         case SPR4XX_TSR:
631            ppc->param1 = ppc->spr[ppc->param0];
632            return;
633 
634         /* timebase */
635         case SPR4XX_TBLO:
636         case SPR4XX_TBLU:
637            ppc->param1 = get_timebase(ppc);
638            return;
639         case SPR4XX_TBHI:
640         case SPR4XX_TBHU:
641            ppc->param1 = (get_timebase(ppc) >> 32) & 0xffffff;
642            return;
643      }
644   }
645 
646   /* default handling */
647   mame_printf_debug("SPR %03X read\n", ppc->param0);
648   ppc->param1 = ppc->spr[ppc->param0];
649}
650 
651 
652/*-------------------------------------------------
653    ppccom_execute_mtspr - execute an MTSPR
654    instruction
655-------------------------------------------------*/
656 
657void ppccom_execute_mtspr(powerpc_state *ppc)
658{
659   /* handle OEA SPRs */
660   if (ppc->cap & PPCCAP_OEA)
661   {
662      switch (ppc->param0)
663      {
664         /* write-through no-ops */
665         case SPROEA_DSISR:
666         case SPROEA_DAR:
667         case SPROEA_SRR0:
668         case SPROEA_SRR1:
669         case SPROEA_EAR:
670         case SPROEA_DABR:
671            ppc->spr[ppc->param0] = ppc->param1;
672            return;
673 
674         /* registers that affect the memory map */
675         case SPROEA_SDR1:
676         case SPROEA_IBAT0L:
677         case SPROEA_IBAT0U:
678         case SPROEA_IBAT1L:
679         case SPROEA_IBAT1U:
680         case SPROEA_IBAT2L:
681         case SPROEA_IBAT2U:
682         case SPROEA_IBAT3L:
683         case SPROEA_IBAT3U:
684         case SPROEA_DBAT0L:
685         case SPROEA_DBAT0U:
686         case SPROEA_DBAT1L:
687         case SPROEA_DBAT1U:
688         case SPROEA_DBAT2L:
689         case SPROEA_DBAT2U:
690         case SPROEA_DBAT3L:
691         case SPROEA_DBAT3U:
692            ppc->spr[ppc->param0] = ppc->param1;
693            ppccom_tlb_flush(ppc);
694            return;
695 
696         /* decrementer */
697         case SPROEA_DEC:
698            set_decrementer(ppc, ppc->param1);
699            return;
700      }
701   }
702 
703   /* handle 603 SPRs */
704   if (ppc->cap & PPCCAP_603_MMU)
705   {
706      switch (ppc->param0)
707      {
708         /* read-only */
709         case SPR603_DMISS:
710         case SPR603_DCMP:
711         case SPR603_HASH1:
712         case SPR603_HASH2:
713         case SPR603_IMISS:
714         case SPR603_ICMP:
715            return;
716 
717         /* write-through no-ops */
718         case SPR603_RPA:
719         case SPR603_HID0:
720         case SPR603_HID1:
721         case SPR603_IABR:
722         case SPR603_HID2:
723            ppc->spr[ppc->param0] = ppc->param1;
724            return;
725 
726         /* timebase */
727         case SPR603_TBL_W:
728            set_timebase(ppc, (get_timebase(ppc) & ~U64(0xffffffff00000000)) | ppc->param1);
729            return;
730         case SPR603_TBU_W:
731            set_timebase(ppc, (get_timebase(ppc) & ~U64(0x00000000ffffffff)) | ((UINT64)ppc->param1 << 32));
732            return;
733      }
734   }
735 
736   /* handle 4XX SPRs */
737   if (ppc->cap & PPCCAP_4XX)
738   {
739      UINT32 oldval = ppc->spr[ppc->param0];
740      switch (ppc->param0)
741      {
742         /* write-through no-ops */
743         case SPR4XX_EVPR:
744         case SPR4XX_ESR:
745         case SPR4XX_DCCR:
746         case SPR4XX_ICCR:
747         case SPR4XX_SRR0:
748         case SPR4XX_SRR1:
749         case SPR4XX_SRR2:
750         case SPR4XX_SRR3:
751            ppc->spr[ppc->param0] = ppc->param1;
752            return;
753 
754         /* timer control register */
755         case SPR4XX_TCR:
756            ppc->spr[SPR4XX_TCR] = ppc->param1 | (oldval & PPC4XX_TCR_WRC_MASK);
757            if ((oldval ^ ppc->spr[SPR4XX_TCR]) & PPC4XX_TCR_FIE)
758               ppc4xx_fit_callback(Machine, ppc, FALSE);
759            if ((oldval ^ ppc->spr[SPR4XX_TCR]) & PPC4XX_TCR_PIE)
760               ppc4xx_pit_callback(Machine, ppc, FALSE);
761            return;
762 
763         /* timer status register */
764         case SPR4XX_TSR:
765            ppc->spr[SPR4XX_TSR] &= ~ppc->param1;
766            ppc4xx_set_irq_line(ppc, 0, 0);
767            return;
768 
769         /* PIT */
770         case SPR4XX_PIT:
771            ppc->spr[SPR4XX_PIT] = ppc->param1;
772            ppc->pit_reload = ppc->param1;
773            ppc4xx_pit_callback(Machine, ppc, FALSE);
774            return;
775 
776         /* timebase */
777         case SPR4XX_TBLO:
778            set_timebase(ppc, (get_timebase(ppc) & ~U64(0x00ffffff00000000)) | ppc->param1);
779            return;
780         case SPR4XX_TBHI:
781            set_timebase(ppc, (get_timebase(ppc) & ~U64(0x00000000ffffffff)) | ((UINT64)(ppc->param1 & 0x00ffffff) << 32));
782            return;
783      }
784   }
785 
786   /* default handling */
787   mame_printf_debug("SPR %03X write = %08X\n", ppc->param0, ppc->param1);
788   ppc->spr[ppc->param0] = ppc->param1;
789}
790 
791 
792/*-------------------------------------------------
793    ppccom_execute_mfdcr - execute an MFDCR
794    instruction
795-------------------------------------------------*/
796 
797void ppccom_execute_mfdcr(powerpc_state *ppc)
798{
799   /* handle various DCRs */
800   switch (ppc->param0)
801   {
802      /* read-through no-ops */
803      case DCR4XX_BR0:
804      case DCR4XX_BR1:
805      case DCR4XX_BR2:
806      case DCR4XX_BR3:
807      case DCR4XX_BR4:
808      case DCR4XX_BR5:
809      case DCR4XX_BR6:
810      case DCR4XX_BR7:
811      case DCR4XX_BESR:
812      case DCR4XX_DMASR:
813      case DCR4XX_DMACT0:
814      case DCR4XX_DMADA0:
815      case DCR4XX_DMASA0:
816      case DCR4XX_DMACC0:
817      case DCR4XX_DMACT1:
818      case DCR4XX_DMADA1:
819      case DCR4XX_DMASA1:
820      case DCR4XX_DMACC1:
821      case DCR4XX_DMACT2:
822      case DCR4XX_DMADA2:
823      case DCR4XX_DMASA2:
824      case DCR4XX_DMACC2:
825      case DCR4XX_DMACT3:
826      case DCR4XX_DMADA3:
827      case DCR4XX_DMASA3:
828      case DCR4XX_DMACC3:
829      case DCR4XX_EXIER:
830      case DCR4XX_EXISR:
831      case DCR4XX_IOCR:
832         ppc->param1 = ppc->dcr[ppc->param0];
833         return;
834   }
835 
836   /* default handling */
837   mame_printf_debug("DCR %03X read\n", ppc->param0);
838   if (ppc->param0 < ARRAY_LENGTH(ppc->dcr))
839      ppc->param1 = ppc->dcr[ppc->param0];
840   else
841      ppc->param1 = 0;
842}
843 
844 
845/*-------------------------------------------------
846    ppccom_execute_mtdcr - execute an MTDCR
847    instruction
848-------------------------------------------------*/
849 
850void ppccom_execute_mtdcr(powerpc_state *ppc)
851{
852   UINT8 oldval;
853 
854   /* handle various DCRs */
855   switch (ppc->param0)
856   {
857      /* write-through no-ops */
858      case DCR4XX_BR0:
859      case DCR4XX_BR1:
860      case DCR4XX_BR2:
861      case DCR4XX_BR3:
862      case DCR4XX_BR4:
863      case DCR4XX_BR5:
864      case DCR4XX_BR6:
865      case DCR4XX_BR7:
866      case DCR4XX_BESR:
867      case DCR4XX_DMACT0:
868      case DCR4XX_DMADA0:
869      case DCR4XX_DMASA0:
870      case DCR4XX_DMACC0:
871      case DCR4XX_DMACT1:
872      case DCR4XX_DMADA1:
873      case DCR4XX_DMASA1:
874      case DCR4XX_DMACC1:
875      case DCR4XX_DMACT2:
876      case DCR4XX_DMADA2:
877      case DCR4XX_DMASA2:
878      case DCR4XX_DMACC2:
879      case DCR4XX_DMACT3:
880      case DCR4XX_DMADA3:
881      case DCR4XX_DMASA3:
882      case DCR4XX_DMACC3:
883         ppc->dcr[ppc->param0] = ppc->param1;
884         return;
885 
886      /* DMA status */
887      case DCR4XX_DMASR:
888         ppc->dcr[DCR4XX_DMASR] &= ~(ppc->param1 & 0xfff80070);
889         ppc4xx_dma_update_irq_states(ppc);
890         return;
891 
892      /* interrupt enables */
893      case DCR4XX_EXIER:
894         ppc->dcr[DCR4XX_EXIER] = ppc->param1;
895         ppc4xx_set_irq_line(ppc, 0, 0);
896         return;
897 
898      /* interrupt clear */
899      case DCR4XX_EXISR:
900         ppc->dcr[ppc->param0] &= ~ppc->param1;
901         ppc4xx_set_irq_line(ppc, 0, 0);
902         return;
903 
904      /* DMA controls */
905      case DCR4XX_DMACR0:
906      case DCR4XX_DMACR1:
907      case DCR4XX_DMACR2:
908      case DCR4XX_DMACR3:
909         ppc->dcr[ppc->param0] = ppc->param1;
910         if (ppc->param1 & PPC4XX_DMACR_CE)
911            ppc4xx_dma_exec(ppc, (ppc->param0 - DCR4XX_DMACR0) / 8);
912         ppc4xx_dma_update_irq_states(ppc);
913         return;
914 
915      /* I/O control */
916      case DCR4XX_IOCR:
917         oldval = ppc->dcr[ppc->param0];
918         ppc->dcr[ppc->param0] = ppc->param1;
919         if ((oldval ^ ppc->param1) & 0x02)
920            ppc4xx_spu_timer_reset(ppc);
921         return;
922   }
923 
924   /* default handling */
925   mame_printf_debug("DCR %03X write = %08X\n", ppc->param0, ppc->param1);
926   if (ppc->param0 < ARRAY_LENGTH(ppc->dcr))
927      ppc->dcr[ppc->param0] = ppc->param1;
928}
929 
930 
931 
932/***************************************************************************
933    COMMON GET/SET INFO
934***************************************************************************/
935 
936/*-------------------------------------------------
937    ppccom_set_info - set information about
938    a PowerPC CPU
939-------------------------------------------------*/
940 
941void ppccom_set_info(powerpc_state *ppc, UINT32 state, cpuinfo *info)
942{
943   switch (state)
944   {
945      /* --- the following bits of info are set as 64-bit signed integers --- */
946      case CPUINFO_INT_INPUT_STATE + PPC_IRQ:         ppc->irq_pending = (ppc->irq_pending & ~1) | (info->i  != CLEAR_LINE); break;
947 
948      case CPUINFO_INT_PC:
949      case CPUINFO_INT_REGISTER + PPC_PC:            ppc->pc = info->i;                  break;
950      case CPUINFO_INT_REGISTER + PPC_MSR:         ppc->msr = info->i;                  break;
951      case CPUINFO_INT_REGISTER + PPC_CR:            ppc->cr = info->i;                  break;
952      case CPUINFO_INT_REGISTER + PPC_LR:            ppc->spr[SPR_LR] = info->i;            break;
953      case CPUINFO_INT_REGISTER + PPC_CTR:         ppc->spr[SPR_CTR] = info->i;         break;
954      case CPUINFO_INT_REGISTER + PPC_XER:         ppc->spr[SPR_XER] = info->i;          break;
955      case CPUINFO_INT_REGISTER + PPC_SRR0:         ppc->spr[SPROEA_SRR0] = info->i;      break;
956      case CPUINFO_INT_REGISTER + PPC_SRR1:         ppc->spr[SPROEA_SRR1] = info->i;      break;
957      case CPUINFO_INT_REGISTER + PPC_SPRG0:         ppc->spr[SPROEA_SPRG0] = info->i;      break;
958      case CPUINFO_INT_REGISTER + PPC_SPRG1:         ppc->spr[SPROEA_SPRG1] = info->i;      break;
959      case CPUINFO_INT_REGISTER + PPC_SPRG2:         ppc->spr[SPROEA_SPRG2] = info->i;      break;
960      case CPUINFO_INT_REGISTER + PPC_SPRG3:         ppc->spr[SPROEA_SPRG3] = info->i;      break;
961      case CPUINFO_INT_REGISTER + PPC_SDR1:         ppc->spr[SPROEA_SDR1] = info->i;      break;
962      case CPUINFO_INT_REGISTER + PPC_EXIER:         ppc->dcr[DCR4XX_EXIER] = info->i;      break;
963      case CPUINFO_INT_REGISTER + PPC_EXISR:         ppc->dcr[DCR4XX_EXISR] = info->i;      break;
964      case CPUINFO_INT_REGISTER + PPC_EVPR:         ppc->spr[SPR4XX_EVPR] = info->i;      break;
965      case CPUINFO_INT_REGISTER + PPC_IOCR:         ppc->dcr[DCR4XX_IOCR] = info->i;      break;
966 
967      case CPUINFO_INT_REGISTER + PPC_R0:            ppc->r[0] = info->i;               break;
968      case CPUINFO_INT_REGISTER + PPC_R1:            ppc->r[1] = info->i;               break;
969      case CPUINFO_INT_REGISTER + PPC_R2:            ppc->r[2] = info->i;               break;
970      case CPUINFO_INT_REGISTER + PPC_R3:            ppc->r[3] = info->i;               break;
971      case CPUINFO_INT_REGISTER + PPC_R4:            ppc->r[4] = info->i;               break;
972      case CPUINFO_INT_REGISTER + PPC_R5:            ppc->r[5] = info->i;               break;
973      case CPUINFO_INT_REGISTER + PPC_R6:            ppc->r[6] = info->i;               break;
974      case CPUINFO_INT_REGISTER + PPC_R7:            ppc->r[7] = info->i;               break;
975      case CPUINFO_INT_REGISTER + PPC_R8:            ppc->r[8] = info->i;               break;
976      case CPUINFO_INT_REGISTER + PPC_R9:            ppc->r[9] = info->i;               break;
977      case CPUINFO_INT_REGISTER + PPC_R10:         ppc->r[10] = info->i;               break;
978      case CPUINFO_INT_REGISTER + PPC_R11:         ppc->r[11] = info->i;               break;
979      case CPUINFO_INT_REGISTER + PPC_R12:         ppc->r[12] = info->i;               break;
980      case CPUINFO_INT_REGISTER + PPC_R13:         ppc->r[13] = info->i;               break;
981      case CPUINFO_INT_REGISTER + PPC_R14:         ppc->r[14] = info->i;               break;
982      case CPUINFO_INT_REGISTER + PPC_R15:         ppc->r[15] = info->i;               break;
983      case CPUINFO_INT_REGISTER + PPC_R16:         ppc->r[16] = info->i;               break;
984      case CPUINFO_INT_REGISTER + PPC_R17:         ppc->r[17] = info->i;               break;
985      case CPUINFO_INT_REGISTER + PPC_R18:         ppc->r[18] = info->i;               break;
986      case CPUINFO_INT_REGISTER + PPC_R19:         ppc->r[19] = info->i;               break;
987      case CPUINFO_INT_REGISTER + PPC_R20:         ppc->r[20] = info->i;               break;
988      case CPUINFO_INT_REGISTER + PPC_R21:         ppc->r[21] = info->i;               break;
989      case CPUINFO_INT_REGISTER + PPC_R22:         ppc->r[22] = info->i;               break;
990      case CPUINFO_INT_REGISTER + PPC_R23:         ppc->r[23] = info->i;               break;
991      case CPUINFO_INT_REGISTER + PPC_R24:         ppc->r[24] = info->i;               break;
992      case CPUINFO_INT_REGISTER + PPC_R25:         ppc->r[25] = info->i;               break;
993      case CPUINFO_INT_REGISTER + PPC_R26:         ppc->r[26] = info->i;               break;
994      case CPUINFO_INT_REGISTER + PPC_R27:         ppc->r[27] = info->i;               break;
995      case CPUINFO_INT_REGISTER + PPC_R28:         ppc->r[28] = info->i;               break;
996      case CPUINFO_INT_REGISTER + PPC_R29:         ppc->r[29] = info->i;               break;
997      case CPUINFO_INT_REGISTER + PPC_R30:         ppc->r[30] = info->i;               break;
998      case CPUINFO_INT_SP:
999      case CPUINFO_INT_REGISTER + PPC_R31:         ppc->r[31] = info->i;               break;
1000   }
1001}
1002 
1003 
1004/*-------------------------------------------------
1005    ppccom_get_info - get information about
1006    a PowerPC CPU
1007-------------------------------------------------*/
1008 
1009void ppccom_get_info(powerpc_state *ppc, UINT32 state, cpuinfo *info)
1010{
1011   switch (state)
1012   {
1013      /* --- the following bits of info are returned as 64-bit signed integers --- */
1014      case CPUINFO_INT_CONTEXT_SIZE:               /* provided by core */               break;
1015      case CPUINFO_INT_INPUT_LINES:               info->i = 1;                     break;
1016      case CPUINFO_INT_DEFAULT_IRQ_VECTOR:         info->i = 0;                     break;
1017      case CPUINFO_INT_ENDIANNESS:               info->i = CPU_IS_BE;               break;
1018      case CPUINFO_INT_CLOCK_MULTIPLIER:            info->i = 1;                     break;
1019      case CPUINFO_INT_CLOCK_DIVIDER:               info->i = 1;                     break;
1020      case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 4;                     break;
1021      case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 4;                     break;
1022      case CPUINFO_INT_MIN_CYCLES:               info->i = 1;                     break;
1023      case CPUINFO_INT_MAX_CYCLES:               info->i = 40;                     break;
1024 
1025      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 64;               break;
1026      case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
1027      case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0;               break;
1028      case CPUINFO_INT_LOGADDR_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32;               break;
1029      case CPUINFO_INT_PAGE_SHIFT + ADDRESS_SPACE_PROGRAM:    info->i = POWERPC_MIN_PAGE_SHIFT;break;
1030 
1031      case CPUINFO_INT_INPUT_STATE + PPC_IRQ:         info->i = ppc->irq_pending ? ASSERT_LINE : CLEAR_LINE; break;
1032 
1033      case CPUINFO_INT_PREVIOUSPC:               /* optionally implemented */         break;
1034 
1035      case CPUINFO_INT_PC:
1036      case CPUINFO_INT_REGISTER + PPC_PC:            info->i = ppc->pc;                  break;
1037      case CPUINFO_INT_REGISTER + PPC_MSR:         info->i = ppc->msr;                  break;
1038      case CPUINFO_INT_REGISTER + PPC_CR:            info->i = ppc->cr;                  break;
1039      case CPUINFO_INT_REGISTER + PPC_LR:            info->i = ppc->spr[SPR_LR];            break;
1040      case CPUINFO_INT_REGISTER + PPC_CTR:         info->i = ppc->spr[SPR_CTR];         break;
1041      case CPUINFO_INT_REGISTER + PPC_XER:         info->i = ppc->spr[SPR_XER];          break;
1042      case CPUINFO_INT_REGISTER + PPC_SRR0:         info->i = ppc->spr[SPROEA_SRR0];      break;
1043      case CPUINFO_INT_REGISTER + PPC_SRR1:         info->i = ppc->spr[SPROEA_SRR1];      break;
1044      case CPUINFO_INT_REGISTER + PPC_SPRG0:         info->i = ppc->spr[SPROEA_SPRG0];      break;
1045      case CPUINFO_INT_REGISTER + PPC_SPRG1:         info->i = ppc->spr[SPROEA_SPRG1];      break;
1046      case CPUINFO_INT_REGISTER + PPC_SPRG2:         info->i = ppc->spr[SPROEA_SPRG2];      break;
1047      case CPUINFO_INT_REGISTER + PPC_SPRG3:         info->i = ppc->spr[SPROEA_SPRG3];      break;
1048      case CPUINFO_INT_REGISTER + PPC_SDR1:         info->i = ppc->spr[SPROEA_SDR1];      break;
1049      case CPUINFO_INT_REGISTER + PPC_EXIER:         info->i = ppc->dcr[DCR4XX_EXIER];      break;
1050      case CPUINFO_INT_REGISTER + PPC_EXISR:         info->i = ppc->dcr[DCR4XX_EXISR];      break;
1051      case CPUINFO_INT_REGISTER + PPC_EVPR:         info->i = ppc->spr[SPR4XX_EVPR];      break;
1052      case CPUINFO_INT_REGISTER + PPC_IOCR:         info->i = ppc->dcr[DCR4XX_IOCR];      break;
1053 
1054      case CPUINFO_INT_REGISTER + PPC_R0:            info->i = ppc->r[0];               break;
1055      case CPUINFO_INT_REGISTER + PPC_R1:            info->i = ppc->r[1];               break;
1056      case CPUINFO_INT_REGISTER + PPC_R2:            info->i = ppc->r[2];               break;
1057      case CPUINFO_INT_REGISTER + PPC_R3:            info->i = ppc->r[3];               break;
1058      case CPUINFO_INT_REGISTER + PPC_R4:            info->i = ppc->r[4];               break;
1059      case CPUINFO_INT_REGISTER + PPC_R5:            info->i = ppc->r[5];               break;
1060      case CPUINFO_INT_REGISTER + PPC_R6:            info->i = ppc->r[6];               break;
1061      case CPUINFO_INT_REGISTER + PPC_R7:            info->i = ppc->r[7];               break;
1062      case CPUINFO_INT_REGISTER + PPC_R8:            info->i = ppc->r[8];               break;
1063      case CPUINFO_INT_REGISTER + PPC_R9:            info->i = ppc->r[9];               break;
1064      case CPUINFO_INT_REGISTER + PPC_R10:         info->i = ppc->r[10];               break;
1065      case CPUINFO_INT_REGISTER + PPC_R11:         info->i = ppc->r[11];               break;
1066      case CPUINFO_INT_REGISTER + PPC_R12:         info->i = ppc->r[12];               break;
1067      case CPUINFO_INT_REGISTER + PPC_R13:         info->i = ppc->r[13];               break;
1068      case CPUINFO_INT_REGISTER + PPC_R14:         info->i = ppc->r[14];               break;
1069      case CPUINFO_INT_REGISTER + PPC_R15:         info->i = ppc->r[15];               break;
1070      case CPUINFO_INT_REGISTER + PPC_R16:         info->i = ppc->r[16];               break;
1071      case CPUINFO_INT_REGISTER + PPC_R17:         info->i = ppc->r[17];               break;
1072      case CPUINFO_INT_REGISTER + PPC_R18:         info->i = ppc->r[18];               break;
1073      case CPUINFO_INT_REGISTER + PPC_R19:         info->i = ppc->r[19];               break;
1074      case CPUINFO_INT_REGISTER + PPC_R20:         info->i = ppc->r[20];               break;
1075      case CPUINFO_INT_REGISTER + PPC_R21:         info->i = ppc->r[21];               break;
1076      case CPUINFO_INT_REGISTER + PPC_R22:         info->i = ppc->r[22];               break;
1077      case CPUINFO_INT_REGISTER + PPC_R23:         info->i = ppc->r[23];               break;
1078      case CPUINFO_INT_REGISTER + PPC_R24:         info->i = ppc->r[24];               break;
1079      case CPUINFO_INT_REGISTER + PPC_R25:         info->i = ppc->r[25];               break;
1080      case CPUINFO_INT_REGISTER + PPC_R26:         info->i = ppc->r[26];               break;
1081      case CPUINFO_INT_REGISTER + PPC_R27:         info->i = ppc->r[27];               break;
1082      case CPUINFO_INT_REGISTER + PPC_R28:         info->i = ppc->r[28];               break;
1083      case CPUINFO_INT_REGISTER + PPC_R29:         info->i = ppc->r[29];               break;
1084      case CPUINFO_INT_REGISTER + PPC_R30:         info->i = ppc->r[30];               break;
1085      case CPUINFO_INT_SP:
1086      case CPUINFO_INT_REGISTER + PPC_R31:         info->i = ppc->r[31];               break;
1087 
1088      /* --- the following bits of info are returned as pointers to data or functions --- */
1089      case CPUINFO_PTR_SET_INFO:                  /* provided by core */               break;
1090      case CPUINFO_PTR_GET_CONTEXT:               /* provided by core */               break;
1091      case CPUINFO_PTR_SET_CONTEXT:               /* provided by core */               break;
1092      case CPUINFO_PTR_INIT:                     /* provided by core */               break;
1093      case CPUINFO_PTR_RESET:                     /* provided by core */               break;
1094      case CPUINFO_PTR_EXIT:                     /* provided by core */               break;
1095      case CPUINFO_PTR_EXECUTE:                  /* provided by core */               break;
1096      case CPUINFO_PTR_TRANSLATE:                  /* provided by core */               break;
1097      case CPUINFO_PTR_DISASSEMBLE:               /* provided by core */               break;
1098      case CPUINFO_PTR_INSTRUCTION_COUNTER:         info->icount = &ppc->icount;         break;
1099 
1100      /* --- the following bits of info are returned as NULL-terminated strings --- */
1101      case CPUINFO_STR_NAME:                     strcpy(info->s, "PowerPC");            break;
1102      case CPUINFO_STR_CORE_FAMILY:               strcpy(info->s, "PowerPC");            break;
1103      case CPUINFO_STR_CORE_VERSION:               strcpy(info->s, "2.0");               break;
1104      case CPUINFO_STR_CORE_FILE:                  /* provided by core */               break;
1105      case CPUINFO_STR_CORE_CREDITS:               strcpy(info->s, "Copyright Aaron Giles"); break;
1106 
1107      case CPUINFO_STR_FLAGS:                     strcpy(info->s, " ");               break;
1108 
1109      case CPUINFO_STR_REGISTER + PPC_PC:            sprintf(info->s, "PC: %08X", ppc->pc);            break;
1110      case CPUINFO_STR_REGISTER + PPC_MSR:         sprintf(info->s, "MSR:%08X", ppc->msr);            break;
1111      case CPUINFO_STR_REGISTER + PPC_CR:            sprintf(info->s, "CR: %08X", ppc->cr);            break;
1112      case CPUINFO_STR_REGISTER + PPC_LR:            sprintf(info->s, "LR: %08X", ppc->spr[SPR_LR]);      break;
1113      case CPUINFO_STR_REGISTER + PPC_CTR:         sprintf(info->s, "CTR:%08X", ppc->spr[SPR_CTR]);   break;
1114      case CPUINFO_STR_REGISTER + PPC_XER:         sprintf(info->s, "XER:%08X", ppc->spr[SPR_XER]);    break;
1115      case CPUINFO_STR_REGISTER + PPC_SRR0:         sprintf(info->s, "SRR0: %08X", ppc->spr[SPROEA_SRR0]);   break;
1116      case CPUINFO_STR_REGISTER + PPC_SRR1:         sprintf(info->s, "SRR1: %08X", ppc->spr[SPROEA_SRR1]);   break;
1117      case CPUINFO_STR_REGISTER + PPC_SPRG0:         sprintf(info->s, "SPRG0: %08X", ppc->spr[SPROEA_SPRG0]); break;
1118      case CPUINFO_STR_REGISTER + PPC_SPRG1:         sprintf(info->s, "SPRG1: %08X", ppc->spr[SPROEA_SPRG1]); break;
1119      case CPUINFO_STR_REGISTER + PPC_SPRG2:         sprintf(info->s, "SPRG2: %08X", ppc->spr[SPROEA_SPRG2]); break;
1120      case CPUINFO_STR_REGISTER + PPC_SPRG3:         sprintf(info->s, "SPRG3: %08X", ppc->spr[SPROEA_SPRG3]); break;
1121      case CPUINFO_STR_REGISTER + PPC_SDR1:         sprintf(info->s, "SDR1: %08X", ppc->spr[SPROEA_SDR1]); break;
1122      case CPUINFO_STR_REGISTER + PPC_EXIER:         sprintf(info->s, "EXIER: %08X", ppc->dcr[DCR4XX_EXIER]); break;
1123      case CPUINFO_STR_REGISTER + PPC_EXISR:         sprintf(info->s, "EXISR: %08X", ppc->dcr[DCR4XX_EXISR]); break;
1124      case CPUINFO_STR_REGISTER + PPC_EVPR:         sprintf(info->s, "EVPR: %08X", ppc->spr[SPR4XX_EVPR]); break;
1125      case CPUINFO_STR_REGISTER + PPC_IOCR:         sprintf(info->s, "IOCR: %08X", ppc->dcr[DCR4XX_EXISR]); break;
1126 
1127      case CPUINFO_STR_REGISTER + PPC_R0:            sprintf(info->s, "R0: %08X", ppc->r[0]); break;
1128      case CPUINFO_STR_REGISTER + PPC_R1:            sprintf(info->s, "R1: %08X", ppc->r[1]); break;
1129      case CPUINFO_STR_REGISTER + PPC_R2:            sprintf(info->s, "R2: %08X", ppc->r[2]); break;
1130      case CPUINFO_STR_REGISTER + PPC_R3:            sprintf(info->s, "R3: %08X", ppc->r[3]); break;
1131      case CPUINFO_STR_REGISTER + PPC_R4:            sprintf(info->s, "R4: %08X", ppc->r[4]); break;
1132      case CPUINFO_STR_REGISTER + PPC_R5:            sprintf(info->s, "R5: %08X", ppc->r[5]); break;
1133      case CPUINFO_STR_REGISTER + PPC_R6:            sprintf(info->s, "R6: %08X", ppc->r[6]); break;
1134      case CPUINFO_STR_REGISTER + PPC_R7:            sprintf(info->s, "R7: %08X", ppc->r[7]); break;
1135      case CPUINFO_STR_REGISTER + PPC_R8:            sprintf(info->s, "R8: %08X", ppc->r[8]); break;
1136      case CPUINFO_STR_REGISTER + PPC_R9:            sprintf(info->s, "R9: %08X", ppc->r[9]); break;
1137      case CPUINFO_STR_REGISTER + PPC_R10:         sprintf(info->s, "R10:%08X", ppc->r[10]); break;
1138      case CPUINFO_STR_REGISTER + PPC_R11:         sprintf(info->s, "R11:%08X", ppc->r[11]); break;
1139      case CPUINFO_STR_REGISTER + PPC_R12:         sprintf(info->s, "R12:%08X", ppc->r[12]); break;
1140      case CPUINFO_STR_REGISTER + PPC_R13:         sprintf(info->s, "R13:%08X", ppc->r[13]); break;
1141      case CPUINFO_STR_REGISTER + PPC_R14:         sprintf(info->s, "R14:%08X", ppc->r[14]); break;
1142      case CPUINFO_STR_REGISTER + PPC_R15:         sprintf(info->s, "R15:%08X", ppc->r[15]); break;
1143      case CPUINFO_STR_REGISTER + PPC_R16:         sprintf(info->s, "R16:%08X", ppc->r[16]); break;
1144      case CPUINFO_STR_REGISTER + PPC_R17:         sprintf(info->s, "R17:%08X", ppc->r[17]); break;
1145      case CPUINFO_STR_REGISTER + PPC_R18:         sprintf(info->s, "R18:%08X", ppc->r[18]); break;
1146      case CPUINFO_STR_REGISTER + PPC_R19:         sprintf(info->s, "R19:%08X", ppc->r[19]); break;
1147      case CPUINFO_STR_REGISTER + PPC_R20:         sprintf(info->s, "R20:%08X", ppc->r[20]); break;
1148      case CPUINFO_STR_REGISTER + PPC_R21:         sprintf(info->s, "R21:%08X", ppc->r[21]); break;
1149      case CPUINFO_STR_REGISTER + PPC_R22:         sprintf(info->s, "R22:%08X", ppc->r[22]); break;
1150      case CPUINFO_STR_REGISTER + PPC_R23:         sprintf(info->s, "R23:%08X", ppc->r[23]); break;
1151      case CPUINFO_STR_REGISTER + PPC_R24:         sprintf(info->s, "R24:%08X", ppc->r[24]); break;
1152      case CPUINFO_STR_REGISTER + PPC_R25:         sprintf(info->s, "R25:%08X", ppc->r[25]); break;
1153      case CPUINFO_STR_REGISTER + PPC_R26:         sprintf(info->s, "R26:%08X", ppc->r[26]); break;
1154      case CPUINFO_STR_REGISTER + PPC_R27:         sprintf(info->s, "R27:%08X", ppc->r[27]); break;
1155      case CPUINFO_STR_REGISTER + PPC_R28:         sprintf(info->s, "R28:%08X", ppc->r[28]); break;
1156      case CPUINFO_STR_REGISTER + PPC_R29:         sprintf(info->s, "R29:%08X", ppc->r[29]); break;
1157      case CPUINFO_STR_REGISTER + PPC_R30:         sprintf(info->s, "R30:%08X", ppc->r[30]); break;
1158      case CPUINFO_STR_REGISTER + PPC_R31:         sprintf(info->s, "R31:%08X", ppc->r[31]); break;
1159   }
1160}
1161 
1162 
1163 
1164/***************************************************************************
1165    OEA HELPERS
1166***************************************************************************/
1167 
1168/*-------------------------------------------------
1169    decrementer_int_callback - callback that fires
1170    whenever a decrementer interrupt is generated
1171-------------------------------------------------*/
1172 
1173static TIMER_CALLBACK( decrementer_int_callback )
1174{
1175   powerpc_state *ppc = ptr;
1176   UINT64 cycles_until_next;
1177 
1178   /* set the decrementer IRQ state */
1179   ppc->irq_pending |= 0x02;
1180 
1181   /* advance by another full rev */
1182   ppc->dec_zero_cycles += (UINT64)ppc->tb_divisor << 32;
1183   cycles_until_next = ppc->dec_zero_cycles - cpunum_gettotalcycles(ppc->cpunum);
1184   timer_adjust_oneshot(ppc->decrementer_int_timer, ATTOTIME_IN_CYCLES(cycles_until_next, ppc->cpunum), 0);
1185}
1186 
1187 
1188 
1189/***************************************************************************
1190    EMBEDDED 4XX HELPERS
1191***************************************************************************/
1192 
1193/*-------------------------------------------------
1194    ppc4xx_set_irq_line - PowerPC 4XX-specific
1195    IRQ line management
1196-------------------------------------------------*/
1197 
1198static void ppc4xx_set_irq_line(powerpc_state *ppc, UINT32 bitmask, int state)
1199{
1200   UINT32 oldstate = ppc->irqstate;
1201   UINT32 levelmask;
1202 
1203   /* set or clear the appropriate bit */
1204   if (state != CLEAR_LINE)
1205      ppc->irqstate |= bitmask;
1206   else
1207      ppc->irqstate &= ~bitmask;
1208 
1209   /* if the state changed to on, edge trigger the interrupt */
1210   if (((ppc->irqstate ^ oldstate) & bitmask) && (ppc->irqstate & bitmask))
1211      ppc->dcr[DCR4XX_EXISR] |= bitmask;
1212 
1213   /* pass through all level-triggered interrupts */
1214   levelmask = PPC4XX_IRQ_BIT_CRITICAL | PPC4XX_IRQ_BIT_SPUR | PPC4XX_IRQ_BIT_SPUT;
1215   levelmask |= PPC4XX_IRQ_BIT_JTAGR | PPC4XX_IRQ_BIT_JTAGT;
1216   levelmask |= PPC4XX_IRQ_BIT_DMA0 | PPC4XX_IRQ_BIT_DMA1 | PPC4XX_IRQ_BIT_DMA2 | PPC4XX_IRQ_BIT_DMA3;
1217   if (!(ppc->dcr[DCR4XX_IOCR] & 0x80000000)) levelmask |= PPC4XX_IRQ_BIT_EXT0;
1218   if (!(ppc->dcr[DCR4XX_IOCR] & 0x20000000)) levelmask |= PPC4XX_IRQ_BIT_EXT1;
1219   if (!(ppc->dcr[DCR4XX_IOCR] & 0x08000000)) levelmask |= PPC4XX_IRQ_BIT_EXT2;
1220   if (!(ppc->dcr[DCR4XX_IOCR] & 0x02000000)) levelmask |= PPC4XX_IRQ_BIT_EXT3;
1221   if (!(ppc->dcr[DCR4XX_IOCR] & 0x00800000)) levelmask |= PPC4XX_IRQ_BIT_EXT4;
1222   ppc->dcr[DCR4XX_EXISR] = (ppc->dcr[DCR4XX_EXISR] & ~levelmask) | (ppc->irqstate & levelmask);
1223 
1224   /* update the IRQ status */
1225   ppc->irq_pending = ((ppc->dcr[DCR4XX_EXISR] & ppc->dcr[DCR4XX_EXIER]) != 0);
1226   if ((ppc->spr[SPR4XX_TCR] & PPC4XX_TCR_FIE) && (ppc->spr[SPR4XX_TSR] & PPC4XX_TSR_FIS))
1227      ppc->irq_pending = TRUE;
1228   if ((ppc->spr[SPR4XX_TCR] & PPC4XX_TCR_PIE) && (ppc->spr[SPR4XX_TSR] & PPC4XX_TSR_PIS))
1229      ppc->irq_pending = TRUE;
1230}
1231 
1232 
1233/*-------------------------------------------------
1234    ppc4xx_get_irq_line - PowerPC 4XX-specific
1235    IRQ line state getter
1236-------------------------------------------------*/
1237 
1238static int ppc4xx_get_irq_line(powerpc_state *ppc, UINT32 bitmask)
1239{
1240   return (ppc->irqstate & bitmask) ? ASSERT_LINE : CLEAR_LINE;
1241}
1242 
1243 
1244/*-------------------------------------------------
1245    ppc4xx_dma_update_irq_states - update the IRQ
1246    state for each DMA channel
1247-------------------------------------------------*/
1248 
1249static void ppc4xx_dma_update_irq_states(powerpc_state *ppc)
1250{
1251   int dmachan;
1252 
1253   /* update the IRQ state for each DMA channel */
1254   for (dmachan = 0; dmachan < 4; dmachan++)
1255      if ((ppc->dcr[DCR4XX_DMACR0 + 8 * dmachan] & PPC4XX_DMACR_CIE) && (ppc->dcr[DCR4XX_DMASR] & (1 << (27 - dmachan))))
1256         ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_DMA(dmachan), ASSERT_LINE);
1257      else
1258         ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_DMA(dmachan), CLEAR_LINE);
1259}
1260 
1261 
1262/*-------------------------------------------------
1263    ppc4xx_dma_decrement_count - decrement the
1264    count on a channel and interrupt if configured
1265    to do so
1266-------------------------------------------------*/
1267 
1268static int ppc4xx_dma_decrement_count(powerpc_state *ppc, int dmachan)
1269{
1270   UINT32 *dmaregs = &ppc->dcr[8 * dmachan];
1271 
1272   /* decrement the counter */
1273   dmaregs[DCR4XX_DMACT0]--;
1274 
1275   /* if non-zero, we keep going */
1276   if ((dmaregs[DCR4XX_DMACT0] & 0xffff) != 0)
1277      return FALSE;
1278 
1279   /* set the complete bit and handle interrupts */
1280   ppc->dcr[DCR4XX_DMASR] |= 1 << (27 - dmachan);
1281   ppc4xx_dma_update_irq_states(ppc);
1282   return TRUE;
1283}
1284 
1285 
1286/*-------------------------------------------------
1287    ppc4xx_dma_fetch_transmit_byte - fetch a byte
1288    to send to a peripheral
1289-------------------------------------------------*/
1290 
1291static int ppc4xx_dma_fetch_transmit_byte(powerpc_state *ppc, int dmachan, UINT8 *byte)
1292{
1293   UINT32 *dmaregs = &ppc->dcr[8 * dmachan];
1294 
1295   /* if the channel is not enabled, fail */
1296   if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CE))
1297      return FALSE;
1298 
1299   /* if no transfers remaining, fail */
1300   if ((dmaregs[DCR4XX_DMACT0] & 0xffff) == 0)
1301      return FALSE;
1302 
1303   /* fetch the data */
1304   cpuintrf_push_context(ppc->cpunum);
1305   *byte = program_read_byte(dmaregs[DCR4XX_DMADA0]++);
1306   ppc4xx_dma_decrement_count(ppc, dmachan);
1307   cpuintrf_pop_context();
1308   return TRUE;
1309}
1310 
1311 
1312/*-------------------------------------------------
1313    ppc4xx_dma_handle_receive_byte - receive a byte
1314    transmitted by a peripheral
1315-------------------------------------------------*/
1316 
1317static int ppc4xx_dma_handle_receive_byte(powerpc_state *ppc, int dmachan, UINT8 byte)
1318{
1319   UINT32 *dmaregs = &ppc->dcr[8 * dmachan];
1320 
1321   /* if the channel is not enabled, fail */
1322   if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CE))
1323      return FALSE;
1324 
1325   /* if no transfers remaining, fail */
1326   if ((dmaregs[DCR4XX_DMACT0] & 0xffff) == 0)
1327      return FALSE;
1328 
1329   /* store the data */
1330   cpuintrf_push_context(ppc->cpunum);
1331   program_write_byte(dmaregs[DCR4XX_DMADA0]++, byte);
1332   ppc4xx_dma_decrement_count(ppc, dmachan);
1333   cpuintrf_pop_context();
1334   return TRUE;
1335}
1336 
1337 
1338/*-------------------------------------------------
1339    ppc4xx_dma_execute - execute a DMA operation
1340    if one is pending
1341-------------------------------------------------*/
1342 
1343static void ppc4xx_dma_exec(powerpc_state *ppc, int dmachan)
1344{
1345   static const UINT8 dma_transfer_width[4] = { 1, 2, 4, 16 };
1346   UINT32 *dmaregs = &ppc->dcr[8 * dmachan];
1347   INT32 destinc, srcinc;
1348   UINT8 width;
1349 
1350   /* skip if not enabled */
1351   if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CE))
1352      return;
1353 
1354   /* check for unsupported features */
1355   if (!(dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TCE))
1356      fatalerror("ppc4xx_dma_exec: DMA_TCE == 0");
1357   if (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_CH)
1358      fatalerror("ppc4xx_dma_exec: DMA chaining not implemented");
1359 
1360   /* transfer mode */
1361   switch ((dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_TM_MASK) >> 21)
1362   {
1363      /* buffered mode DMA */
1364      case 0:
1365         /* nothing to do; this happens asynchronously and is driven by the SPU */
1366         break;
1367 
1368      /* fly-by mode DMA */
1369      case 1:
1370         fatalerror("ppc4xx_dma_exec: fly-by DMA not implemented");
1371         break;
1372 
1373      /* software initiated memory-to-memory mode DMA */
1374      case 2:
1375         width = dma_transfer_width[(dmaregs[DCR4XX_DMACR0] >> 26) & 0x3];
1376         srcinc = (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_SAI) ? width : 0;
1377         destinc = (dmaregs[DCR4XX_DMACR0] & PPC4XX_DMACR_DAI) ? width : 0;
1378 
1379         switch (width)
1380         {
1381            /* byte transfer */
1382            case 1:
1383               do
1384               {
1385                  program_write_byte(dmaregs[DCR4XX_DMADA0], program_read_byte(dmaregs[DCR4XX_DMASA0]));
1386                  dmaregs[DCR4XX_DMASA0] += srcinc;
1387                  dmaregs[DCR4XX_DMADA0] += destinc;
1388               } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1389               break;
1390 
1391            /* word transfer */
1392            case 2:
1393               do
1394               {
1395                  program_write_word(dmaregs[DCR4XX_DMADA0], program_read_word(dmaregs[DCR4XX_DMASA0]));
1396                  dmaregs[DCR4XX_DMASA0] += srcinc;
1397                  dmaregs[DCR4XX_DMADA0] += destinc;
1398               } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1399               break;
1400 
1401            /* dword transfer */
1402            case 4:
1403               do
1404               {
1405                  program_write_dword(dmaregs[DCR4XX_DMADA0], program_read_dword(dmaregs[DCR4XX_DMASA0]));
1406                  dmaregs[DCR4XX_DMASA0] += srcinc;
1407                  dmaregs[DCR4XX_DMADA0] += destinc;
1408               } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1409               break;
1410 
1411            /* 16-byte transfer */
1412            case 16:
1413               do
1414               {
1415                  program_write_qword(dmaregs[DCR4XX_DMADA0], program_read_qword(dmaregs[DCR4XX_DMASA0]));
1416                  program_write_qword(dmaregs[DCR4XX_DMADA0] + 8, program_read_qword(dmaregs[DCR4XX_DMASA0] + 8));
1417                  dmaregs[DCR4XX_DMASA0] += srcinc;
1418                  dmaregs[DCR4XX_DMADA0] += destinc;
1419               } while (!ppc4xx_dma_decrement_count(ppc, dmachan));
1420               break;
1421         }
1422         break;
1423 
1424      /* hardware initiated memory-to-memory mode DMA */
1425      case 3:
1426         fatalerror("ppc4xx_dma_exec: HW mem-to-mem DMA not implemented");
1427         break;
1428   }
1429}
1430 
1431 
1432/*-------------------------------------------------
1433    ppc4xx_fit_callback - FIT timer callback
1434-------------------------------------------------*/
1435 
1436static TIMER_CALLBACK( ppc4xx_fit_callback )
1437{
1438   powerpc_state *ppc = ptr;
1439 
1440   /* if this is a real callback and we are enabled, signal an interrupt */
1441   if (param)
1442   {
1443      ppc->spr[SPR4XX_TSR] |= PPC4XX_TSR_FIS;
1444      ppc4xx_set_irq_line(ppc, 0, 0);
1445   }
1446 
1447   /* update ourself for the next interval if we are enabled */
1448   if (ppc->spr[SPR4XX_TCR] & PPC4XX_TCR_FIE)
1449   {
1450      UINT32 timebase = get_timebase(ppc);
1451      UINT32 interval = 0x200 << (4 * ((ppc->spr[SPR4XX_TCR] & PPC4XX_TCR_FP_MASK) >> 24));
1452      UINT32 target = (timebase + interval) & ~(interval - 1);
1453      timer_adjust_oneshot(ppc->fit_timer, ATTOTIME_IN_CYCLES((target + 1 - timebase) / ppc->tb_divisor, ppc->cpunum), TRUE);
1454   }
1455 
1456   /* otherwise, turn ourself off */
1457   else
1458      timer_adjust_oneshot(ppc->fit_timer, attotime_never, FALSE);
1459}
1460 
1461 
1462/*-------------------------------------------------
1463    ppc4xx_pit_callback - PIT timer callback
1464-------------------------------------------------*/
1465 
1466static TIMER_CALLBACK( ppc4xx_pit_callback )
1467{
1468   powerpc_state *ppc = ptr;
1469 
1470   /* if this is a real callback and we are enabled, signal an interrupt */
1471   if (param)
1472   {
1473      ppc->spr[SPR4XX_TSR] |= PPC4XX_TSR_PIS;
1474      ppc4xx_set_irq_line(ppc, 0, 0);
1475   }
1476 
1477   /* update ourself for the next interval if we are enabled and we are either being
1478       forced to update, or we are in auto-reload mode */
1479   if ((ppc->spr[SPR4XX_TCR] & PPC4XX_TCR_PIE) && ppc->pit_reload != 0 && (!param || (ppc->spr[SPR4XX_TCR] & PPC4XX_TCR_ARE)))
1480   {
1481      UINT32 timebase = get_timebase(ppc);
1482      UINT32 interval = ppc->pit_reload;
1483      UINT32 target = timebase + interval;
1484      timer_adjust_oneshot(ppc->pit_timer, ATTOTIME_IN_CYCLES((target + 1 - timebase) / ppc->tb_divisor, ppc->cpunum), TRUE);
1485   }
1486 
1487   /* otherwise, turn ourself off */
1488   else
1489      timer_adjust_oneshot(ppc->pit_timer, attotime_never, FALSE);
1490}
1491 
1492 
1493/*-------------------------------------------------
1494    ppc4xx_spu_update_irq_states - update the IRQ
1495    state for the SPU
1496-------------------------------------------------*/
1497 
1498static void ppc4xx_spu_update_irq_states(powerpc_state *ppc)
1499{
1500   /* check for receive buffer full interrupt */
1501   if ((ppc->spu.regs[SPU4XX_RX_COMMAND] & 0x60) == 0x20 && (ppc->spu.regs[SPU4XX_LINE_STATUS] & 0x80))
1502      ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_SPUR, ASSERT_LINE);
1503 
1504   /* check for receive error interrupt */
1505   else if ((ppc->spu.regs[SPU4XX_RX_COMMAND] & 0x10) && (ppc->spu.regs[SPU4XX_LINE_STATUS] & 0x78))
1506      ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_SPUR, ASSERT_LINE);
1507 
1508   /* clear otherwise */
1509   else
1510      ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_SPUR, CLEAR_LINE);
1511 
1512   /* check for transmit buffer empty interrupt */
1513   if ((ppc->spu.regs[SPU4XX_TX_COMMAND] & 0x60) == 0x20 && (ppc->spu.regs[SPU4XX_LINE_STATUS] & 0x04))
1514      ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_SPUT, ASSERT_LINE);
1515 
1516   /* check for shift register empty interrupt */
1517   else if ((ppc->spu.regs[SPU4XX_TX_COMMAND] & 0x10) && (ppc->spu.regs[SPU4XX_LINE_STATUS] & 0x02))
1518      ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_SPUT, ASSERT_LINE);
1519 
1520   /* clear otherwise */
1521   else
1522      ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_SPUT, CLEAR_LINE);
1523}
1524 
1525 
1526/*-------------------------------------------------
1527    ppc4xx_spu_rx_data - serial port data receive
1528-------------------------------------------------*/
1529 
1530static void ppc4xx_spu_rx_data(powerpc_state *ppc, UINT8 data)
1531{
1532   fatalerror("ppc4xx_spu_rx_data unimplemented\n");
1533}
1534 
1535 
1536/*-------------------------------------------------
1537    ppc4xx_spu_timer_reset - reset and recompute
1538    the transmit/receive timer
1539-------------------------------------------------*/
1540 
1541static void ppc4xx_spu_timer_reset(powerpc_state *ppc)
1542{
1543   UINT8 enabled = (ppc->spu.regs[SPU4XX_RX_COMMAND] | ppc->spu.regs[SPU4XX_TX_COMMAND]) & 0x80;
1544 
1545   /* if we're enabled, reset at the current baud rate */
1546   if (enabled)
1547   {
1548      attotime clockperiod = ATTOTIME_IN_HZ((ppc->dcr[DCR4XX_IOCR] & 0x02) ? 3686400 : 33333333);
1549      int divisor = ((ppc->spu.regs[SPU4XX_BAUD_DIVISOR_H] * 256 + ppc->spu.regs[SPU4XX_BAUD_DIVISOR_L]) & 0xfff) + 1;
1550      int bpc = 7 + ((ppc->spu.regs[SPU4XX_CONTROL] & 8) >> 3) + 1 + (ppc->spu.regs[SPU4XX_CONTROL] & 1);
1551      attotime charperiod = attotime_mul(clockperiod, divisor * 16 * bpc);
1552      timer_adjust_periodic(ppc->spu.timer, charperiod, 0, charperiod);
1553      if (PRINTF_SPU)
1554         mame_printf_debug("ppc4xx_spu_timer_reset: baud rate = %.0f\n", ATTOSECONDS_TO_HZ(charperiod.attoseconds) * bpc);
1555   }
1556 
1557   /* otherwise, disable the timer */
1558   else
1559      timer_adjust_oneshot(ppc->spu.timer, attotime_never, 0);
1560}
1561 
1562 
1563/*-------------------------------------------------
1564    ppc4xx_spu_callback - serial port send/receive
1565    timer
1566-------------------------------------------------*/
1567 
1568static TIMER_CALLBACK( ppc4xx_spu_callback )
1569{
1570   powerpc_state *ppc = ptr;
1571   UINT8 rxbyte;
1572 
1573   /* transmit enabled? */
1574   if (ppc->spu.regs[SPU4XX_TX_COMMAND] & 0x80)
1575   {
1576      int operation = (ppc->spu.regs[SPU4XX_TX_COMMAND] >> 5) & 3;
1577 
1578      /* if we have data to transmit, do it now */
1579      if (!(ppc->spu.regs[SPU4XX_LINE_STATUS] & 0x04))
1580      {
1581         /* if we have a transmit handler, send it that way */
1582         if (ppc->spu.tx_handler != NULL)
1583            (*ppc->spu.tx_handler)(ppc->spu.txbuf);
1584 
1585         /* indicate that we have moved it to the shift register */
1586         ppc->spu.regs[SPU4XX_LINE_STATUS] |= 0x04;
1587         ppc->spu.regs[SPU4XX_LINE_STATUS] &= ~0x02;
1588      }
1589 
1590      /* otherwise, clear the shift register */
1591      else if (!(ppc->spu.regs[SPU4XX_LINE_STATUS] & 0x02))
1592         ppc->spu.regs[SPU4XX_LINE_STATUS] |= 0x02;
1593 
1594      /* handle DMA */
1595      if (operation >= 2 && ppc4xx_dma_fetch_transmit_byte(ppc, operation, &ppc->spu.txbuf))
1596         ppc->spu.regs[SPU4XX_LINE_STATUS] &= ~0x04;
1597   }
1598 
1599   /* receive enabled? */
1600   if (ppc->spu.regs[SPU4XX_RX_COMMAND] & 0x80)
1601      if (ppc->spu.rx_handler != NULL && (*ppc->spu.rx_handler)(&rxbyte))
1602      {
1603         int operation = (ppc->spu.regs[SPU4XX_RX_COMMAND] >> 5) & 3;
1604 
1605         /* if we're not full, copy data to the buffer and update the line status */
1606         if (!(ppc->spu.regs[SPU4XX_LINE_STATUS] & 0x80))
1607         {
1608            ppc->spu.rxbuf = rxbyte;
1609            ppc->spu.regs[SPU4XX_LINE_STATUS] |= 0x80;
1610         }
1611 
1612         /* otherwise signal an overrun */
1613         else
1614         {
1615            ppc->spu.regs[SPU4XX_LINE_STATUS] |= 0x20;
1616            goto updateirq;
1617         }
1618 
1619         /* handle DMA */
1620         if (operation >= 2 && ppc4xx_dma_handle_receive_byte(ppc, operation, ppc->spu.rxbuf))
1621            ppc->spu.regs[SPU4XX_LINE_STATUS] &= ~0x80;
1622      }
1623 
1624   /* update the final IRQ states */
1625updateirq:
1626   ppc4xx_spu_update_irq_states(ppc);
1627}
1628 
1629 
1630/*-------------------------------------------------
1631    ppc4xx_spu_r - serial port read handler
1632-------------------------------------------------*/
1633 
1634static READ8_HANDLER( ppc4xx_spu_r )
1635{
1636   powerpc_state *ppc = activecpu_get_info_ptr(CPUINFO_PTR_CONTEXT);
1637   UINT8 result = 0xff;
1638 
1639   switch (offset)
1640   {
1641      case SPU4XX_BUFFER:
1642         result = ppc->spu.rxbuf;
1643         ppc->spu.regs[SPU4XX_LINE_STATUS] &= ~0x80;
1644         break;
1645 
1646      default:
1647         if (offset < ARRAY_LENGTH(ppc->spu.regs))
1648            result = ppc->spu.regs[offset];
1649         break;
1650   }
1651   if (PRINTF_SPU)
1652      mame_printf_debug("spu_r(%d) = %02X\n", offset, result);
1653   return result;
1654}
1655 
1656 
1657/*-------------------------------------------------
1658    ppc4xx_spu_w - serial port write handler
1659-------------------------------------------------*/
1660 
1661static WRITE8_HANDLER( ppc4xx_spu_w )
1662{
1663   powerpc_state *ppc = activecpu_get_info_ptr(CPUINFO_PTR_CONTEXT);
1664   UINT8 oldstate, newstate;
1665 
1666   if (PRINTF_SPU)
1667      mame_printf_debug("spu_w(%d) = %02X\n", offset, data);
1668   switch (offset)
1669   {
1670      /* clear error bits */
1671      case SPU4XX_LINE_STATUS:
1672         ppc->spu.regs[SPU4XX_LINE_STATUS] &= ~(data & 0xf8);
1673         ppc4xx_spu_update_irq_states(ppc);
1674         break;
1675 
1676      /* enable/disable the timer if one of these is enabled */
1677      case SPU4XX_RX_COMMAND:
1678      case SPU4XX_TX_COMMAND:
1679         oldstate = ppc->spu.regs[SPU4XX_RX_COMMAND] | ppc->spu.regs[SPU4XX_TX_COMMAND];
1680         ppc->spu.regs[offset] = data;
1681         newstate = ppc->spu.regs[SPU4XX_RX_COMMAND] | ppc->spu.regs[SPU4XX_TX_COMMAND];
1682         if ((oldstate ^ newstate) & 0x80)
1683            ppc4xx_spu_timer_reset(ppc);
1684         ppc4xx_spu_update_irq_states(ppc);
1685         break;
1686 
1687      /* if the divisor changes, we need to update the timer */
1688      case SPU4XX_BAUD_DIVISOR_H:
1689      case SPU4XX_BAUD_DIVISOR_L:
1690         if (data != ppc->spu.regs[offset])
1691         {
1692            ppc->spu.regs[offset] = data;
1693            ppc4xx_spu_timer_reset(ppc);
1694         }
1695         break;
1696 
1697      /* if the number of data bits or stop bits changes, we need to update the timer */
1698      case SPU4XX_CONTROL:
1699         oldstate = ppc->spu.regs[offset];
1700         ppc->spu.regs[offset] = data;
1701         if ((oldstate ^ data) & 0x09)
1702            ppc4xx_spu_timer_reset(ppc);
1703         break;
1704 
1705         break;
1706 
1707      case SPU4XX_BUFFER:
1708         /* write to the transmit buffer and mark it full */
1709         ppc->spu.txbuf = data;
1710         ppc->spu.regs[SPU4XX_LINE_STATUS] &= ~0x04;
1711         break;
1712 
1713      default:
1714         if (offset < ARRAY_LENGTH(ppc->spu.regs))
1715            ppc->spu.regs[offset] = data;
1716         break;
1717   }
1718}
1719 
1720 
1721 
1722/*-------------------------------------------------
1723    internal_ppc4xx - internal address map for
1724    the 4XX
1725-------------------------------------------------*/
1726 
1727static ADDRESS_MAP_START( internal_ppc4xx, ADDRESS_SPACE_PROGRAM, 32 )
1728   AM_RANGE(0x40000000, 0x4000000f) AM_READWRITE8(ppc4xx_spu_r, ppc4xx_spu_w, 0xffffffff)
1729ADDRESS_MAP_END
1730 
1731 
1732 
1733/*-------------------------------------------------
1734    ppc4xx_set_info - PowerPC 4XX-specific
1735    information setter
1736-------------------------------------------------*/
1737 
1738void ppc4xx_set_info(powerpc_state *ppc, UINT32 state, cpuinfo *info)
1739{
1740   switch (state)
1741   {
1742      /* --- the following bits of info are returned as 64-bit signed integers --- */
1743      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_0:   ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_EXT0, info->i);      break;
1744      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_1:   ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_EXT1, info->i);      break;
1745      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_2:   ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_EXT2, info->i);      break;
1746      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_3:   ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_EXT3, info->i);      break;
1747      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_4:   ppc4xx_set_irq_line(ppc, PPC4XX_IRQ_BIT_EXT4, info->i);      break;
1748      case CPUINFO_INT_PPC_RX_DATA:               ppc4xx_spu_rx_data(ppc, info->i);               break;
1749 
1750      /* --- the following bits of info are returned as pointers to data or functions --- */
1751      case CPUINFO_PTR_SPU_RX_HANDLER:            ppc->spu.rx_handler = (ppc4xx_spu_rx_handler)info->f; break;
1752      case CPUINFO_PTR_SPU_TX_HANDLER:            ppc->spu.tx_handler = (ppc4xx_spu_tx_handler)info->f; break;
1753 
1754      /* --- everything else is handled generically --- */
1755      default:                              ppccom_set_info(ppc, state, info);      break;
1756   }
1757}
1758 
1759 
1760/*-------------------------------------------------
1761    ppc4xx_get_info - PowerPC 4XX-specific
1762    information getter
1763-------------------------------------------------*/
1764 
1765void ppc4xx_get_info(powerpc_state *ppc, UINT32 state, cpuinfo *info)
1766{
1767   switch (state)
1768   {
1769      /* --- the following bits of info are returned as 64-bit signed integers --- */
1770      case CPUINFO_INT_INPUT_LINES:               info->i = 5;                     break;
1771      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_0:   info->i = ppc4xx_get_irq_line(ppc, PPC4XX_IRQ_BIT_EXT0);      break;
1772      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_1:   info->i = ppc4xx_get_irq_line(ppc, PPC4XX_IRQ_BIT_EXT1);      break;
1773      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_2:   info->i = ppc4xx_get_irq_line(ppc, PPC4XX_IRQ_BIT_EXT2);      break;
1774      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_3:   info->i = ppc4xx_get_irq_line(ppc, PPC4XX_IRQ_BIT_EXT3);      break;
1775      case CPUINFO_INT_INPUT_STATE + PPC_IRQ_LINE_4:   info->i = ppc4xx_get_irq_line(ppc, PPC4XX_IRQ_BIT_EXT4);      break;
1776 
1777      case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM:   info->i = 32;               break;
1778      case CPUINFO_INT_LOGADDR_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 0;               break;
1779      case CPUINFO_INT_PAGE_SHIFT + ADDRESS_SPACE_PROGRAM:    info->i = 0;               break;
1780 
1781      /* --- the following bits of info are returned as pointers to data or functions --- */
1782      case CPUINFO_PTR_INIT:                     /* provided per-CPU */               break;
1783      case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map32 = address_map_internal_ppc4xx; break;
1784 
1785      /* --- everything else is handled generically --- */
1786      default:                              ppccom_get_info(ppc, state, info);      break;
1787   }
1788}
1789 
src/emu/cpu/powerpc/ppc.c
r2821r2822
44#include "ppc.h"
55#include "debugger.h"
66
7// PLL Configuration based on the table in MPC603EUM page 7-31
8static const int mpc603e_pll_config[12][9] =
9{
10   // 16,  20,  25,  33,  40,  50,  60,  66,  75
11   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
12   { 0x2, 0x2, 0x2, 0x1, 0x1, 0x1,  -1, 0x0,  -1 },
13   {  -1,  -1,  -1,  -1,  -1, 0xc,  -1, 0xc,  -1 },
14   { 0x5, 0x5, 0x5, 0x4, 0x4, 0x4,  -1,  -1,  -1 },
15   {  -1,   -1,  -1, 0x6, 0x6,  -1,  -1,  -1,  -1 },
16   {  -1,  -1, 0x8, 0x8,  -1,  -1,  -1,  -1,  -1 },
17   {  -1, 0xe, 0xe,  -1,  -1,  -1,  -1,  -1,  -1 },
18   { 0xa, 0xa, 0xa,  -1,  -1,  -1,  -1,  -1,  -1 },
19   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
20   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
21   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
22   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
23};
24
25// PLL Configuration based on the table in MPC603E7VEC page 29
26static const int mpc603ev_pll_config[12][9] =
27{
28   // 16,  20,  25,  33,  40,  50,  60,  66,  75
29   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
30   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
31   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
32   // 2:1
33   {  -1,  -1,  -1,  -1,  -1,  -1,  -1, 0x4, 0x4 },
34   // 2.5:1
35   {  -1,  -1,  -1,  -1,  -1, 0x6, 0x6, 0x6, 0x6 },
36   // 3:1
37   {  -1,  -1,  -1,  -1, 0x8, 0x8, 0x8, 0x8, 0x8 },
38   // 3.5:1
39   {  -1,  -1,  -1,  -1, 0xe, 0xe, 0xe, 0xe,  -1 },
40   // 4:1
41   {  -1,  -1,  -1, 0xa, 0xa, 0xa, 0xa,  -1,  -1 },
42   // 4.5:1
43   {  -1,  -1,  -1, 0x7, 0x7, 0x7,  -1,  -1,  -1 },
44   // 5:1
45   {  -1,  -1, 0xb, 0xb, 0xb,  -1,  -1,  -1,  -1 },
46   // 5.5:1
47   {  -1,  -1, 0x9, 0x9, 0x9,  -1,  -1,  -1,  -1 },
48   // 6:1
49   {  -1,  -1, 0xd, 0xd, 0xd,  -1,  -1,  -1,  -1 }
50};
51
52// PLL Configuration based on the table in MPC603E7TEC page 23
53static const int mpc603r_pll_config[12][9] =
54{
55   // 16,  20,  25,  33,  40,  50,  60,  66,  75
56   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
57   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
58   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
59   // 2:1
60   {  -1,  -1,  -1,  -1, 0x5, 0x5, 0x5, 0x5, 0x5 },
61   // 2.5:1
62   {  -1,  -1,  -1,  -1,  -1,  -1, 0x6, 0x6, 0x6 },
63   // 3:1
64   {  -1,  -1,  -1,  -1,  -1, 0x8, 0x8, 0x8, 0x8 },
65   // 3.5:1
66   {  -1,  -1,  -1,  -1,  -1, 0xe, 0xe, 0xe, 0xe },
67   // 4:1
68   {  -1,  -1,  -1,  -1, 0xa, 0xa, 0xa, 0xa, 0xa },
69   // 4.5:1
70   {  -1,  -1,  -1, 0x7, 0x7, 0x7, 0x7, 0x7,  -1 },
71   // 5:1
72   {  -1,  -1,  -1, 0xb, 0xb, 0xb, 0xb,  -1,  -1 },
73   // 5.5:1
74   {  -1,  -1,  -1, 0x9, 0x9, 0x9,  -1,  -1,  -1 },
75   // 6:1
76   {  -1,  -1, 0xd, 0xd, 0xd, 0xd,  -1,  -1,  -1 },
77};
78
79
780#if (HAS_PPC603 || HAS_PPC601 || HAS_PPC604)
881static void ppc603_exception(int exception);
982#endif
src/emu/cpu/powerpc/ppccom.h
r0r2822
1/***************************************************************************
2 
3    ppccom.h
4 
5    Common PowerPC definitions and functions
6 
7***************************************************************************/
8 
9#ifndef __PPCCOM_H__
10#define __PPCCOM_H__
11 
12#include "cpuintrf.h"
13#include "ppc.h"
14 
15 
16/***************************************************************************
17    WIDE-SCALE CONTROLS
18***************************************************************************/
19 
20#define SIMULATE_603_TLB            (0)
21 
22 
23 
24/***************************************************************************
25    CONSTANTS
26***************************************************************************/
27 
28/* core parameters */
29#define POWERPC_MIN_PAGE_SHIFT      12
30#define POWERPC_MIN_PAGE_SIZE      (1 << POWERPC_MIN_PAGE_SHIFT)
31#define POWERPC_MIN_PAGE_MASK      (POWERPC_MIN_PAGE_SIZE - 1)
32#define POWERPC_TLB_ENTRIES         128
33#define PPC603_FIXED_TLB_ENTRIES   128
34 
35 
36/* internal capabilities flags */
37#define PPCCAP_OEA               0x01      /* TRUE if we conform to the OEA */
38#define PPCCAP_VEA               0x02      /* TRUE if we conform to the VEA */
39#define PPCCAP_FPU               0x04      /* TRUE if we have an FPU */
40#define PPCCAP_MISALIGNED         0x08      /* TRUE if misaligned accesses are supported */
41#define PPCCAP_4XX               0x10      /* TRUE if we are a non-OEA 4XX class chip */
42#define PPCCAP_603_MMU            0x20      /* TRUE if we have 603-class MMU features */
43 
44 
45/* bits in our internal TLB */
46#define TLB_READ               0x01      /* reads are allowed */
47#define TLB_WRITE               0x02      /* writes are allowed */
48 
49 
50/* PowerPC flavors */
51enum _powerpc_flavor
52{
53   PPC_MODEL_403GA            = 0x00200000,
54   PPC_MODEL_403GB            = 0x00200100,
55   PPC_MODEL_403GC            = 0x00200200,
56   PPC_MODEL_403GCX         = 0x00201400,
57   PPC_MODEL_405GP            = 0x40110000,
58   PPC_MODEL_601            = 0x00010000,
59   PPC_MODEL_603            = 0x00030000,   /* "Wart" */
60   PPC_MODEL_604            = 0x00040000,   /* "Zephyr" */
61   PPC_MODEL_602            = 0x00050200,   /* "Galahad" */
62   PPC_MODEL_603E            = 0x00060103,   /* "Stretch", version 1.3 */
63   PPC_MODEL_603EV            = 0x00070000,   /* "Valiant" */
64   PPC_MODEL_603R            = 0x00071202,   /* "Goldeneye", version 2.1 */
65   PPC_MODEL_740            = 0x00080301,   /* "Arthur", version 3.1 */
66   PPC_MODEL_750            = PPC_MODEL_740,
67   PPC_MODEL_740P            = 0x00080202,   /* "Conan Doyle", version 1.2 */
68   PPC_MODEL_750P            = PPC_MODEL_740P,
69   PPC_MODEL_755            = 0x00083203,   /* "Goldfinger", version 2.3 */
70   PPC_MODEL_7400            = 0x000c0209,   /* "Max", version 2.9 */
71   PPC_MODEL_7410            = 0x800c1104,   /* "Nitro", version 3.4 */
72   PPC_MODEL_7450            = 0x80000201,   /* "Vger", version 2.1 */
73   PPC_MODEL_7451            = 0x80000203,   /* "Vger", version 2.3 */
74   PPC_MODEL_7441            = PPC_MODEL_7451,
75   PPC_MODEL_7455            = 0x80010303,   /* "Apollo 6", version 3.3 */
76   PPC_MODEL_7445            = PPC_MODEL_7455,
77   PPC_MODEL_7457            = 0x80020101,   /* "Apollo 7", version 1.1 */
78   PPC_MODEL_MPC8240         = 0x00810101,   /* "Kahlua" */
79   PPC_MODEL_MPC8241         = 0x80811014,   /* "Kahlua Lt" */
80   PPC_MODEL_MPC8245         = 0x80811014,   /* "Kahlua II" */
81};
82typedef enum _powerpc_flavor powerpc_flavor;
83 
84 
85/* exception types */
86enum
87{
88   EXCEPTION_RESET      = 1,
89   EXCEPTION_MACHCHECK   = 2,
90   EXCEPTION_DSI      = 3,
91   EXCEPTION_ISI      = 4,
92   EXCEPTION_EI      = 5,
93   EXCEPTION_ALIGN      = 6,
94   EXCEPTION_PROGRAM   = 7,
95   EXCEPTION_NOFPU      = 8,
96   EXCEPTION_DECREMENT   = 9,
97   EXCEPTION_SYSCALL   = 12,
98   EXCEPTION_TRACE      = 13,
99   EXCEPTION_FPASSIST   = 14,
100   EXCEPTION_ITLBMISS   = 16,      /* PPCCAP_603_MMU */
101   EXCEPTION_DTLBMISSL   = 17,      /* PPCCAP_603_MMU */
102   EXCEPTION_DTLBMISSS   = 18,      /* PPCCAP_603_MMU */
103   EXCEPTION_COUNT
104};
105 
106 
107/* SPRs */
108enum
109{
110   /* UISA SPR register indexes */
111   SPR_XER            = 0x001,   /* R/W  Fixed Point Exception Register */
112   SPR_LR            = 0x008,   /* R/W  Link Register */
113   SPR_CTR            = 0x009,   /* R/W  Count Register */
114 
115   /* VEA SPR register indexes */
116   SPRVEA_TBL_R      = 0x10c,   /* R    Time Base Low */
117   SPRVEA_TBU_R      = 0x10d,   /* R    Time Base High */
118 
119   /* OEA SPR register indexes */
120   SPROEA_DSISR      = 0x012,   /* R/W  DSI Status Register */
121   SPROEA_DAR         = 0x013,   /* R/W  Data Address Register */
122   SPROEA_DEC         = 0x016,   /* R/W  Decrementer Register */
123   SPROEA_SDR1         = 0x019,   /* R/W  Page Table Configuration */
124   SPROEA_SRR0         = 0x01a,   /* R/W  Machine Status Save/Restore Register 0 */
125   SPROEA_SRR1         = 0x01b,   /* R/W  Machine Status Save/Restore Register 1 */
126   SPROEA_SPRG0      = 0x110,   /* R/W  SPR General 0 */
127   SPROEA_SPRG1      = 0x111,   /* R/W  SPR General 1 */
128   SPROEA_SPRG2      = 0x112,   /* R/W  SPR General 2 */
129   SPROEA_SPRG3      = 0x113,   /* R/W  SPR General 3 */
130   SPROEA_ASR         = 0x118,   /* R/W  Address Space Register (64-bit only) */
131   SPROEA_EAR         = 0x11a,   /* R/W  External Access Register */
132   SPROEA_PVR         = 0x11f,   /* R    Processor Version Number */
133   SPROEA_IBAT0U      = 0x210,   /* R/W  Instruction BAT 0 Upper */
134   SPROEA_IBAT0L      = 0x211,   /* R/W  Instruction BAT 0 Lower */
135   SPROEA_IBAT1U      = 0x212,   /* R/W  Instruction BAT 1 Upper */
136   SPROEA_IBAT1L      = 0x213,   /* R/W  Instruction BAT 1 Lower */
137   SPROEA_IBAT2U      = 0x214,   /* R/W  Instruction BAT 2 Upper */
138   SPROEA_IBAT2L      = 0x215,   /* R/W  Instruction BAT 2 Lower */
139   SPROEA_IBAT3U      = 0x216,   /* R/W  Instruction BAT 3 Upper */
140   SPROEA_IBAT3L      = 0x217,   /* R/W  Instruction BAT 3 Lower */
141   SPROEA_DBAT0U      = 0x218,   /* R/W  Data BAT 0 Upper */
142   SPROEA_DBAT0L      = 0x219,   /* R/W  Data BAT 0 Lower */
143   SPROEA_DBAT1U      = 0x21a,   /* R/W  Data BAT 1 Upper */
144   SPROEA_DBAT1L      = 0x21b,   /* R/W  Data BAT 1 Lower */
145   SPROEA_DBAT2U      = 0x21c,   /* R/W  Data BAT 2 Upper */
146   SPROEA_DBAT2L      = 0x21d,   /* R/W  Data BAT 2 Lower */
147   SPROEA_DBAT3U      = 0x21e,   /* R/W  Data BAT 3 Upper */
148   SPROEA_DBAT3L      = 0x21f,   /* R/W  Data BAT 3 Lower */
149   SPROEA_DABR         = 0x3f5,   /* R/W  Data Address Breakpoint Register */
150 
151   /* PowerPC 4XX SPR register indexes */
152   SPR4XX_SRR0         = 0x01a,   /* R/W  403GA Machine Status Save/Restore Register 0 */
153   SPR4XX_SRR1         = 0x01b,   /* R/W  403GA Machine Status Save/Restore Register 1 */
154   SPR4XX_SPRG0      = 0x110,   /* R/W  403GA SPR General 0 */
155   SPR4XX_SPRG1      = 0x111,   /* R/W  403GA SPR General 1 */
156   SPR4XX_SPRG2      = 0x112,   /* R/W  403GA SPR General 2 */
157   SPR4XX_SPRG3      = 0x113,   /* R/W  403GA SPR General 3 */
158   SPR4XX_PVR         = 0x11f,   /* R    403GA Processor Version Number */
159   SPR4XX_SGR         = 0x3b9,   /* R/W  403GCX Storage Guarded Register */
160   SPR4XX_DCWR         = 0x3ba,   /* R/W  403GCX Data Cache Write Through */
161   SPR4XX_PID         = 0x3b1,   /* R/W  403GCX Process ID */
162   SPR4XX_TBHU         = 0x3cc,   /* R/W  403GCX Time Base High User-mode */
163   SPR4XX_TBLU         = 0x3cd,   /* R/W  403GCX Time Base Low User-mode */
164   SPR4XX_ICDBDR      = 0x3d3,   /* R    403GA 406GA Instruction Cache Debug Data Register */
165   SPR4XX_ESR         = 0x3d4,   /* R/W  403GA 406GA Exception Syndrome Register */
166   SPR4XX_DEAR         = 0x3d5,   /* R    403GA 406GA Data Exception Address Register */
167   SPR4XX_EVPR         = 0x3d6,   /* R/W  403GA 406GA Exception Vector Prefix Register */
168   SPR4XX_CDBCR      = 0x3d7,   /* R/W  403GA 406GA Cache Debug Control Register */
169   SPR4XX_TSR         = 0x3d8,   /* R/C  403GA 406GA Timer Status Register */
170   SPR4XX_TCR         = 0x3da,   /* R/W  403GA 406GA Timer Control Register */
171   SPR4XX_PIT         = 0x3db,   /* R/W  403GA 406GA Programmable Interval Timer */
172   SPR4XX_TBHI         = 0x3dc,   /* R/W  403GA 406GA Time Base High */
173   SPR4XX_TBLO         = 0x3dd,   /* R/W  403GA 406GA Time Base Low */
174   SPR4XX_SRR2         = 0x3de,   /* R/W  403GA 406GA Machine Status Save/Restore Register 2 */
175   SPR4XX_SRR3         = 0x3df,   /* R/W  403GA 406GA Machine Status Save/Restore Register 3 */
176   SPR4XX_DBSR         = 0x3f0,   /* R/C  403GA 406GA Debug Status Register */
177   SPR4XX_DBCR         = 0x3f2,   /* R/W  403GA 406GA Debug Control Register */
178   SPR4XX_IAC1         = 0x3f4,   /* R/W  403GA 406GA Instruction Address Compare 1 */
179   SPR4XX_IAC2         = 0x3f5,   /* R/W  403GA 406GA Instruction Address Compare 2 */
180   SPR4XX_DAC1         = 0x3f6,   /* R/W  403GA 406GA Data Address Compare 1 */
181   SPR4XX_DAC2         = 0x3f7,   /* R/W  403GA 406GA Data Address Compare 2 */
182   SPR4XX_DCCR         = 0x3fa,   /* R/W  403GA 406GA Data Cache Cacheability Register */
183   SPR4XX_ICCR         = 0x3fb,   /* R/W  403GA 406GA Instruction Cache Cacheability Registe */
184   SPR4XX_PBL1         = 0x3fc,   /* R/W  403GA 406GA Protection Bound Lower 1 */
185   SPR4XX_PBU1         = 0x3fd,   /* R/W  403GA 406GA Protection Bound Upper 1 */
186   SPR4XX_PBL2         = 0x3fe,   /* R/W  403GA 406GA Protection Bound Lower 2 */
187   SPR4XX_PBU2         = 0x3ff,   /* R/W  403GA 406GA Protection Bound Upper 2 */
188 
189   /* PowerPC 602 SPR register indexes */
190   SPR602_TCR         = 0x3d8,   /* 602 */
191   SPR602_IBR         = 0x3da,   /* 602 */
192   SPR602_ESASRR      = 0x3db,   /* 602 */
193   SPR602_SEBR         = 0x3de,   /* 602 */
194   SPR602_SER         = 0x3df,   /* 602 */
195   SPR602_SP         = 0x3fd,   /* 602 */
196   SPR602_LT         = 0x3fe,   /* 602 */
197 
198   /* PowerPC 603 SPR register indexes */
199   SPR603_TBL_R      = 0x10c,   /* R   603 Time Base Low (Read-only) */
200   SPR603_TBU_R      = 0x10d,   /* R   603 Time Base High (Read-only) */
201   SPR603_TBL_W      = 0x11c,   /* W   603 Time Base Low (Write-only) */
202   SPR603_TBU_W      = 0x11d,   /* W   603 Time Base Hight (Write-only) */
203   SPR603_DMISS      = 0x3d0,   /* R   603 Data TLB Miss Address Register */
204   SPR603_DCMP         = 0x3d1,   /* R   603 Data TLB Compare Register */
205   SPR603_HASH1      = 0x3d2,   /* R   603 Primary Hash Address Register */
206   SPR603_HASH2      = 0x3d3,   /* R   603 Secondary Hash Address Register */
207   SPR603_IMISS      = 0x3d4,   /* R   603 Instruction TLB Miss Address Register */
208   SPR603_ICMP         = 0x3d5,   /* R   603 Instruction TLB Compare Register */
209   SPR603_RPA         = 0x3d6,   /* R/W 603 Required Physical Address Register */
210   SPR603_HID0         = 0x3f0,   /* R/W 603 Hardware Implementation Register 0 */
211   SPR603_HID1         = 0x3f1,   /* R/W 603 Hardware Implementation Register 1 */
212   SPR603_IABR         = 0x3f2,   /* R/W 603 Instruction Address Breakpoint Register */
213   SPR603_HID2         = 0x3f3      /* R/W 603 */
214};
215 
216 
217/* PowerPC 4XX DCR register indexes */
218enum
219{
220   DCR4XX_EXISR      = 0x040,   /* external interrupt status */
221   DCR4XX_EXIER      = 0x042,   /* external interrupt enable */
222   DCR4XX_BR0         = 0x080,   /* bank */
223   DCR4XX_BR1         = 0x081,   /* bank */
224   DCR4XX_BR2         = 0x082,   /* bank */
225   DCR4XX_BR3         = 0x083,   /* bank */
226   DCR4XX_BR4         = 0x084,   /* bank */
227   DCR4XX_BR5         = 0x085,   /* bank */
228   DCR4XX_BR6         = 0x086,   /* bank */
229   DCR4XX_BR7         = 0x087,   /* bank */
230   DCR4XX_BEAR         = 0x090,   /* bus error address */
231   DCR4XX_BESR         = 0x091,   /* bus error syndrome */
232   DCR4XX_IOCR         = 0x0a0,   /* io configuration */
233   DCR4XX_DMACR0      = 0x0c0,   /* dma channel control */
234   DCR4XX_DMACT0      = 0x0c1,   /* dma destination address */
235   DCR4XX_DMADA0      = 0x0c2,   /* dma destination address */
236   DCR4XX_DMASA0      = 0x0c3,   /* dma source address */
237   DCR4XX_DMACC0      = 0x0c4,   /* dma chained count */
238   DCR4XX_DMACR1      = 0x0c8,   /* dma channel control */
239   DCR4XX_DMACT1      = 0x0c9,   /* dma destination address */
240   DCR4XX_DMADA1      = 0x0ca,   /* dma destination address */
241   DCR4XX_DMASA1      = 0x0cb,   /* dma source address */
242   DCR4XX_DMACC1      = 0x0cc,   /* dma chained count */
243   DCR4XX_DMACR2      = 0x0d0,   /* dma channel control */
244   DCR4XX_DMACT2      = 0x0d1,   /* dma destination address */
245   DCR4XX_DMADA2      = 0x0d2,   /* dma source address */
246   DCR4XX_DMASA2      = 0x0d3,   /* dma source address */
247   DCR4XX_DMACC2      = 0x0d4,   /* dma chained count */
248   DCR4XX_DMACR3      = 0x0d8,   /* dma channel control */
249   DCR4XX_DMACT3      = 0x0d9,   /* dma destination address */
250   DCR4XX_DMADA3      = 0x0da,   /* dma source address */
251   DCR4XX_DMASA3      = 0x0db,   /* dma source address */
252   DCR4XX_DMACC3      = 0x0dc,   /* dma chained count */
253   DCR4XX_DMASR      = 0x0e0      /* dma status */
254};
255 
256 
257/* PowerPC 4XX SPU register indexes */
258enum
259{
260   SPU4XX_LINE_STATUS      = 0x00,
261   SPU4XX_HANDSHAKE_STATUS   = 0x02,
262   SPU4XX_BAUD_DIVISOR_H   = 0x04,
263   SPU4XX_BAUD_DIVISOR_L   = 0x05,
264   SPU4XX_CONTROL         = 0x06,
265   SPU4XX_RX_COMMAND      = 0x07,
266   SPU4XX_TX_COMMAND      = 0x08,
267   SPU4XX_BUFFER         = 0x09
268};
269 
270 
271/* FPSCR register bits */
272#define FPSCR_FX         0x80000000
273#define FPSCR_FEX         0x40000000
274#define FPSCR_VX         0x20000000
275#define FPSCR_OX         0x10000000
276#define FPSCR_UX         0x08000000
277#define FPSCR_ZX         0x04000000
278#define FPSCR_XX         0x02000000
279 
280 
281/* XER register bits */
282#define XER_SO            0x80000000
283#define XER_OV            0x40000000
284#define XER_CA            0x20000000
285 
286 
287/* Machine State Register bits - common */
288#define MSR_ILE            0x00010000   /* Interrupt Little Endian Mode */
289#define MSR_EE            0x00008000   /* External Interrupt Enable */
290#define MSR_PR            0x00004000   /* Problem State */
291#define MSR_ME            0x00001000   /* Machine Check Enable */
292#define MSR_LE            0x00000001   /* Little Endian */
293 
294/* Machine State Register bits - OEA */
295#define MSROEA_POW         0x00040000   /* Power Management Enable */
296#define MSROEA_FP         0x00002000   /* Floating Point Available */
297#define MSROEA_FE0         0x00000800   /* FP Exception Mode 0 */
298#define MSROEA_SE         0x00000400   /* Single Step Trace Enable */
299#define MSROEA_BE         0x00000200   /* Branch Trace Enable */
300#define MSROEA_FE1         0x00000100   /* FP Exception Mode 1 */
301#define MSROEA_IP         0x00000040   /* Interrupt Prefix */
302#define MSROEA_IR         0x00000020   /* Instruction Relocate */
303#define MSROEA_DR         0x00000010   /* Data Relocate */
304#define MSROEA_RI         0x00000002   /* Recoverable Interrupt Enable */
305 
306/* Machine State Register bits - 4XX */
307#define MSR4XX_WE         0x00040000   /* Wait State Enable */
308#define MSR4XX_CE         0x00020000   /* Critical Interrupt Enable */
309#define MSR4XX_DE         0x00000200   /* Debug Exception Enable */
310#define MSR4XX_PE         0x00000008   /* Protection Enable (reserved for others) */
311#define MSR4XX_PX         0x00000004   /* Protection Exclusive Mode (reserved for others) */
312 
313/* Machine State Register bits - 602 */
314#define MSR602_AP         0x00800000   /* Access privilege state */
315#define MSR602_SA         0x00400000   /* Supervisor access mode */
316 
317/* Machine State Register bits - 603 */
318#define MSR603_TGPR         0x00020000   /* Temporary GPR Remapping */
319 
320 
321/* DSISR bits for DSI/alignment exceptions */
322#define DSISR_DIRECT      0x00000001      /* DSI: direct-store exception? */
323#define DSISR_NOT_FOUND      0x00000002      /* DSI: not found in HTEG or DBAT */
324#define DSISR_PROTECTED      0x00000010      /* DSI: exception due to protection */
325#define DSISR_CACHE_ERROR   0x00000020      /* DSI: operation on incorrect cache type */
326#define DSISR_STORE         0x00000040      /* DSI: store (1) or load (0) */
327#define DSISR_DABR         0x00000200      /* DSI: DABR match occurred */
328#define DSISR_NO_SEGMENT   0x00000400      /* DSI: no segment match found (64-bit only) */
329#define DSISR_INVALID_ECWX   0x00000800      /* DSI: ECIWX or ECOWX used with EAR[E] = 0 */
330#define DSISR_INSTRUCTION   0xfffff000      /* align: instruction decoding bits */
331 
332 
333/* PowerPC 4XX IRQ bits */
334#define PPC4XX_IRQ_BIT_CRITICAL      (0x80000000 >> 0)
335#define PPC4XX_IRQ_BIT_SPUR         (0x80000000 >> 4)
336#define PPC4XX_IRQ_BIT_SPUT         (0x80000000 >> 5)
337#define PPC4XX_IRQ_BIT_JTAGR      (0x80000000 >> 6)
338#define PPC4XX_IRQ_BIT_JTAGT      (0x80000000 >> 7)
339#define PPC4XX_IRQ_BIT_DMA0         (0x80000000 >> 8)
340#define PPC4XX_IRQ_BIT_DMA1         (0x80000000 >> 9)
341#define PPC4XX_IRQ_BIT_DMA2         (0x80000000 >> 10)
342#define PPC4XX_IRQ_BIT_DMA3         (0x80000000 >> 11)
343#define PPC4XX_IRQ_BIT_EXT0         (0x80000000 >> 27)
344#define PPC4XX_IRQ_BIT_EXT1         (0x80000000 >> 28)
345#define PPC4XX_IRQ_BIT_EXT2         (0x80000000 >> 29)
346#define PPC4XX_IRQ_BIT_EXT3         (0x80000000 >> 30)
347#define PPC4XX_IRQ_BIT_EXT4         (0x80000000 >> 31)
348 
349#define PPC4XX_IRQ_BIT_EXT(n)      (PPC4XX_IRQ_BIT_EXT0 >> (n))
350#define PPC4XX_IRQ_BIT_DMA(n)      (PPC4XX_IRQ_BIT_DMA0 >> (n))
351 
352 
353/* PowerPC 4XX DMA control bits */
354#define PPC4XX_DMACR_CE            0x80000000      /* channel enable */
355#define PPC4XX_DMACR_CIE         0x40000000      /* channel interrupt enable */
356#define PPC4XX_DMACR_TD            0x20000000      /* transfer direction */
357#define PPC4XX_DMACR_PL            0x10000000      /* peripheral location */
358#define PPC4XX_DMACR_PW_MASK      0x0c000000      /* peripheral width */
359#define PPC4XX_DMACR_DAI         0x02000000      /* destination address increment */
360#define PPC4XX_DMACR_SAI         0x01000000      /* source address increment */
361#define PPC4XX_DMACR_CP            0x00800000      /* channel priority */
362#define PPC4XX_DMACR_TM_MASK      0x00600000      /* transfer mode */
363#define PPC4XX_DMACR_PSC_MASK      0x00180000      /* peripheral setup cycles */
364#define PPC4XX_DMACR_PWC_MASK      0x0007e000      /* peripheral wait cycles */
365#define PPC4XX_DMACR_PHC_MASK      0x00001c00      /* peripheral hold cycles */
366#define PPC4XX_DMACR_ETD         0x00000200      /* end-of-transfer pin direction */
367#define PPC4XX_DMACR_TCE         0x00000100      /* terminal count enable */
368#define PPC4XX_DMACR_CH            0x00000080      /* chaining enable */
369#define PPC4XX_DMACR_BME         0x00000040      /* burst mode enable */
370#define PPC4XX_DMACR_ECE         0x00000020      /* EOT chain mode enable */
371#define PPC4XX_DMACR_TCD         0x00000010      /* TC chain mode disable */
372#define PPC4XX_DMACR_PCE         0x00000008
373 
374 
375/* PowerPC 4XX Timer control register bits */
376#define PPC4XX_TCR_WP_MASK         0xc0000000      /* watchdog period */
377#define PPC4XX_TCR_WRC_MASK         0x30000000      /* watchdog reset control */
378#define PPC4XX_TCR_WIE            0x08000000      /* watchdog interrupt enable */
379#define PPC4XX_TCR_PIE            0x04000000      /* PIT interrupt enable */
380#define PPC4XX_TCR_FP_MASK         0x03000000      /* FIT period */
381#define PPC4XX_TCR_FIE            0x00800000      /* FIT interrupt enable */
382#define PPC4XX_TCR_ARE            0x00400000      /* auto reload enable */
383 
384 
385/* PowerPC 4XX Timer status register bits */
386#define PPC4XX_TSR_ENW            0x80000000      /* enable next watchdog */
387#define PPC4XX_TSR_WIS            0x40000000      /* watchdog interrupt status */
388#define PPC4XX_TSR_WRS_MASK         0x30000000      /* watchdog reset status */
389#define PPC4XX_TSR_PIS            0x08000000      /* PIT interrupt status */
390#define PPC4XX_TSR_FIS            0x04000000      /* FIT interrupt status */
391 
392 
393/* instruction decoding masks */
394#define M_LI             0x03fffffc
395#define M_AA             0x00000002
396#define M_LK             0x00000001
397#define M_BO             0x03e00000
398#define M_BI             0x001f0000
399#define M_BD             0x0000fffc
400#define M_RT             0x03e00000
401#define M_RD             0x03e00000
402#define M_RS             0x03e00000
403#define M_RA             0x001f0000
404#define M_RB             0x0000f800
405#define M_CRFD           0x03800000
406#define M_L              0x00200000
407#define M_TO             0x03e00000
408#define M_D              0x0000ffff
409#define M_SIMM           0x0000ffff
410#define M_UIMM           0x0000ffff
411#define M_NB             0x0000f800
412#define M_SR             0x000f0000
413#define M_SH             0x0000f800
414#define M_CRFS           0x001c0000
415#define M_IMM            0x0000f000
416#define M_CRBD           0x03e00000
417#define M_RC             0x00000001
418#define M_CRBA           0x001f0000
419#define M_CRBB           0x0000f800
420#define M_SPR            0x001FF800
421#define M_TBR            0x001FF800
422#define M_CRM            0x000FF000
423#define M_DCR            0x001FF800
424#define M_FM             0x01FE0000
425#define M_OE             0x00000400
426#define M_REGC           0x000007c0
427#define M_MB             0x000007c0
428#define M_ME             0x0000003e
429#define M_XO             0x000007fe
430 
431 
432 
433/***************************************************************************
434    HELPER MACROS
435***************************************************************************/
436 
437/*
438 * Field Defining Macros
439 *
440 * These macros generate instruction words with their associated fields filled
441 * in with the passed value.
442 */
443 
444#define D_OP(op)         ((op & 0x3f) << 26)
445#define D_XO(xo)         ((xo & 0x3ff) << 1)
446#define D_RT(r)            ((r & 0x1f) << (31 - 10))
447#define D_RA(r)            ((r & 0x1f) << (31 - 15))
448#define D_UIMM(u)         (u & 0xffff)
449 
450/*
451 * Macros to Get Field Values
452 *
453 * These macros return the values of fields in an opcode. They all return
454 * unsigned values and do not perform any sign extensions.
455 */
456 
457#define G_RT(op)         ((op & M_RT) >> (31 - 10))
458#define G_RD(op)         ((op & M_RD) >> (31 - 10))
459#define G_RS(op)         ((op & M_RS) >> (31 - 10))
460#define G_RA(op)         ((op & M_RA) >> (31 - 15))
461#define G_RB(op)         ((op & M_RB) >> (31 - 20))
462#define G_SIMM(op)         (op & M_SIMM)
463#define G_UIMM(op)         (op & M_UIMM)
464#define G_LI(op)         ((op & M_LI) >> 2)
465#define G_BO(op)         ((op & M_BO) >> (31 - 10))
466#define G_BI(op)         ((op & M_BI) >> (31 - 15))
467#define G_BD(op)         ((op & M_BD) >> 2)
468#define G_CRFD(op)         ((op & M_CRFD) >> (31 - 8))
469#define G_L(op)            ((op & M_L) >> (31 - 10))
470#define G_CRBD(op)         ((op & M_CRBD) >> (31 - 10))
471#define G_CRBA(op)         ((op & M_CRBA) >> (31 - 15))
472#define G_CRBB(op)         ((op & M_CRBB) >> (31 - 20))
473#define G_REGC(op)         ((op & M_REGC) >> (31 - 25))
474#define G_D(op)            (op & M_D)
475#define G_NB(op)         ((op & M_NB) >> (31 - 20))
476#define G_CRFS(op)         ((op & M_CRFS) >> (31 - 13))
477#define G_SPR(op)         ((op & M_SPR) >> (31 - 20))
478#define G_TBR(op)         ((op & M_TBR) >> (31 - 20))
479#define G_DCR(op)         ((op & M_DCR) >> (31 - 20))
480#define G_SR(op)         ((op & M_SR) >> (31 - 15))
481#define G_CRM(op)         ((op & M_CRM) >> (31 - 19))
482#define G_FM(op)         ((op & M_FM) >> (31 - 14))
483#define G_IMM(op)         ((op & M_IMM) >> (31 - 19))
484#define G_SH(op)         ((op & M_SH) >> (31 - 20))
485#define G_MB(op)         ((op & M_MB) >> (31 - 25))
486#define G_ME(op)         ((op & M_ME) >> 1)
487#define G_TO(op)         ((op & M_TO) >> (31 - 10))
488#define G_XO(op)         ((op & M_XO) >> (31 - 30))
489 
490 
491 
492/***************************************************************************
493    STRUCTURES & TYPEDEFS
494***************************************************************************/
495 
496typedef int (*ppc4xx_spu_rx_handler)(UINT8 *data);
497typedef void (*ppc4xx_spu_tx_handler)(UINT8 data);
498 
499 
500/* PowerPC 4XX-specific serial port state */
501typedef struct _ppc4xx_spu_state ppc4xx_spu_state;
502struct _ppc4xx_spu_state
503{
504   UINT8         regs[9];
505   UINT8         txbuf;
506   UINT8         rxbuf;
507   emu_timer *      timer;
508   ppc4xx_spu_rx_handler rx_handler;
509   ppc4xx_spu_tx_handler tx_handler;
510};
511 
512 
513/* forward declaration of implementation-specific state */
514typedef struct _ppcimp_state ppcimp_state;
515 
516 
517/* PowerPC state */
518typedef struct _powerpc_state powerpc_state;
519struct _powerpc_state
520{
521   /* core registers */
522   UINT32         pc;
523   int            icount;
524   UINT32         r[32];
525   double         f[32];
526   UINT32         cr;
527   UINT32         fpscr;
528   UINT32         msr;
529   UINT32         sr[16];
530   UINT32         spr[1024];
531   UINT32         dcr[256];
532 
533   /* parameters for calls */
534   UINT32         param0;
535   UINT32         param1;
536 
537   /* MMU */
538   UINT32 *      tlb_table;
539   UINT32 *      tlb_entries;
540   UINT32         tlb_index;
541 
542   /* architectural distinctions */
543   powerpc_flavor   flavor;
544   UINT8         cap;
545   UINT8         cache_line_size;
546   UINT32         tb_divisor;
547   int            (*spr_read)(powerpc_state *ppc);
548   int            (*spr_write)(powerpc_state *ppc);
549   int            (*tlb_fill)(powerpc_state *ppc);
550 
551   /* PowerPC 4xx-specific state */
552   ppc4xx_spu_state spu;
553   emu_timer *      fit_timer;
554   emu_timer *      pit_timer;
555   emu_timer *      wdog_timer;
556   UINT32         pit_reload;
557   UINT32         irqstate;
558 
559   /* PowerPC 603-specific state */
560   UINT32         mmu603_cmp;
561   UINT32         mmu603_hash[2];
562   UINT32         mmu603_r[4];
563 
564   /* internal stuff */
565   int            cpunum;
566   int          (*irq_callback)(int irqline);
567   UINT32         irq_pending;
568   UINT32         system_clock;
569   UINT32         cpu_clock;
570   UINT64         tb_zero_cycles;
571   UINT64         dec_zero_cycles;
572   emu_timer *      decrementer_int_timer;
573 
574   /* for use by specific implementations */
575   ppcimp_state *   impstate;
576};
577 
578 
579 
580/***************************************************************************
581    FUNCTION PROTOTYPES
582***************************************************************************/
583 
584size_t ppccom_init(powerpc_state *ppc, powerpc_flavor flavor, UINT8 cap, int tb_divisor, int clock, const powerpc_config *config, int (*irqcallback)(int), void *memory);
585void ppccom_reset(powerpc_state *ppc);
586#ifdef ENABLE_DEBUGGER
587offs_t ppccom_dasm(powerpc_state *ppc, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
588#endif
589void ppccom_update_cycle_counting(powerpc_state *ppc);
590 
591int ppccom_translate_address(powerpc_state *ppc, int space, int intention, offs_t *address);
592 
593void ppccom_set_info(powerpc_state *ppc, UINT32 state, cpuinfo *info);
594void ppccom_get_info(powerpc_state *ppc, UINT32 state, cpuinfo *info);
595 
596void ppccom_tlb_fill(powerpc_state *ppc);
597void ppccom_tlb_flush(powerpc_state *ppc);
598 
599void ppccom_execute_tlbie(powerpc_state *ppc);
600void ppccom_execute_tlbia(powerpc_state *ppc);
601void ppccom_execute_tlbl(powerpc_state *ppc);
602void ppccom_execute_mftb(powerpc_state *ppc);
603void ppccom_execute_mfspr(powerpc_state *ppc);
604void ppccom_execute_mtspr(powerpc_state *ppc);
605void ppccom_execute_mfdcr(powerpc_state *ppc);
606void ppccom_execute_mtdcr(powerpc_state *ppc);
607 
608void ppc4xx_set_info(powerpc_state *ppc, UINT32 state, cpuinfo *info);
609void ppc4xx_get_info(powerpc_state *ppc, UINT32 state, cpuinfo *info);
610 
611#endif
src/emu/cpu/powerpc/ppc_dasm.c
r2821r2822
1515
1616#include "cpuintrf.h"
1717#include "debugger.h"
18#include "ppccom.h"
1819
1920/*
20 * Masks
21 *
22 * These masks isolate fields in an instruction word.
23 */
24
25#define M_LI    0x03fffffc
26#define M_AA    0x00000002
27#define M_LK    0x00000001
28#define M_BO    0x03e00000
29#define M_BI    0x001f0000
30#define M_BD    0x0000fffc
31#define M_RT    0x03e00000
32#define M_RA    0x001f0000
33#define M_RB    0x0000f800
34#define M_CRFD  0x03800000
35#define M_L     0x00200000
36#define M_TO    0x03e00000
37#define M_D     0x0000ffff
38#define M_SIMM  0x0000ffff
39#define M_UIMM  0x0000ffff
40#define M_NB    0x0000f800
41#define M_SR    0x000f0000
42#define M_SH    0x0000f800
43#define M_CRFS  0x001c0000
44#define M_IMM   0x0000f000
45#define M_CRBD  0x03e00000
46#define M_RC    0x00000001
47#define M_CRBA  0x001f0000
48#define M_CRBB  0x0000f800
49#define M_SPR   0x001FF800
50#define M_TBR   0x001FF800
51#define M_CRM   0x000FF000
52#define M_DCR   0x001FF800
53#define M_FM    0x01FE0000
54#define M_OE    0x00000400
55#define M_REGC  0x000007c0
56#define M_MB    0x000007c0
57#define M_ME    0x0000003e
58#define M_XO    0x000007fe
59
60/*
61 * Field Defining Macros
62 *
63 * These macros generate instruction words with their associated fields filled
64 * in with the passed value.
65 */
66
67#define D_OP(op)    ((op & 0x3f) << 26)
68#define D_XO(xo)    ((xo & 0x3ff) << 1)
69#define D_RT(r)     ((r & 0x1f) << (31 - 10))
70#define D_RA(r)      ((r & 0x1f) << (31 - 15))
71#define D_UIMM(u)   (u & 0xffff)
72
73/*
74 * Macros to Get Field Values
75 *
76 * These macros return the values of fields in an opcode. They all return
77 * unsigned values and do not perform any sign extensions.
78 */
79
80#define G_RT(op)    ((op & M_RT) >> (31 - 10))
81#define G_RA(op)    ((op & M_RA) >> (31 - 15))
82#define G_RB(op)    ((op & M_RB) >> (31 - 20))
83#define G_SIMM(op)  (op & M_SIMM)
84#define G_UIMM(op)  (op & M_UIMM)
85#define G_LI(op)    ((op & M_LI) >> 2)
86#define G_BO(op)    ((op & M_BO) >> (31 - 10))
87#define G_BI(op)    ((op & M_BI) >> (31 - 15))
88#define G_BD(op)    ((op & M_BD) >> 2)
89#define G_CRFD(op)  ((op & M_CRFD) >> (31 - 8))
90#define G_L(op)     ((op & M_L) >> (31 - 10))
91#define G_CRBD(op)  ((op & M_CRBD) >> (31 - 10))
92#define G_CRBA(op)  ((op & M_CRBA) >> (31 - 15))
93#define G_CRBB(op)  ((op & M_CRBB) >> (31 - 20))
94#define G_REGC(op)  ((op & M_REGC) >> (31 - 25))
95#define G_D(op)     (op & M_D)
96#define G_NB(op)    ((op & M_NB) >> (31 - 20))
97#define G_CRFS(op)  ((op & M_CRFS) >> (31 - 13))
98#define G_SPR(op)   ((op & M_SPR) >> (31 - 20))
99#define G_DCR(op)   ((op & M_DCR) >> (31 - 20))
100#define G_SR(op)    ((op & M_SR) >> (31 - 15))
101#define G_CRM(op)   ((op & M_CRM) >> (31 - 19))
102#define G_FM(op)    ((op & M_FM) >> (31 - 14))
103#define G_IMM(op)   ((op & M_IMM) >> (31 - 19))
104#define G_SH(op)    ((op & M_SH) >> (31 - 20))
105#define G_MB(op)    ((op & M_MB) >> (31 - 25))
106#define G_ME(op)    ((op & M_ME) >> 1)
107#define G_TO(op)    ((op & M_TO) >> (31 - 10))
108
109/*
11021 * Operand Formats
11122 *
11223 * These convey information on what operand fields are present and how they
r2821r2822
227138    { "bc",     D_OP(16),           M_BO|M_BI|M_BD|M_AA|M_LK,   F_BCx,          FL_AA|FL_LK },
228139    { "bcctr",  D_OP(19)|D_XO(528), M_BO|M_BI|M_LK,             F_BO_BI,        FL_LK       },
229140    { "bclr",   D_OP(19)|D_XO(16),  M_BO|M_BI|M_LK,             F_BO_BI,        FL_LK|FL_SO },
230    { "cmp",    D_OP(31)|D_XO(0),   M_CRFD|M_L|M_RA|M_RB,       F_CMP,          0           },
231    { "cmpi",   D_OP(11),           M_CRFD|M_L|M_RA|M_SIMM,     F_CMP_SIMM,     0           },
232    { "cmpl",   D_OP(31)|D_XO(32),  M_CRFD|M_L|M_RA|M_RB,       F_CMP,          0           },
233    { "cmpli",  D_OP(10),           M_CRFD|M_L|M_RA|M_UIMM,     F_CMP_UIMM,     0           },
141    { "cmp",    D_OP(31)|D_XO(0),   M_CRFD|M_RA|M_RB,           F_CMP,          0           },
142    { "cmpd",   D_OP(31)|D_XO(0)|M_L,M_CRFD|M_RA|M_RB,          F_CMP,          0           },
143    { "cmpi",   D_OP(11),           M_CRFD|M_RA|M_SIMM,         F_CMP_SIMM,     0           },
144    { "cmpdi",  D_OP(11)|M_L,       M_CRFD|M_RA|M_SIMM,         F_CMP_SIMM,     0           },
145    { "cmpl",   D_OP(31)|D_XO(32),  M_CRFD|M_RA|M_RB,           F_CMP,          0           },
146    { "cmpld",  D_OP(31)|D_XO(32)|M_L,M_CRFD|M_RA|M_RB,         F_CMP,          0           },
147    { "cmpli",  D_OP(10),           M_CRFD|M_RA|M_UIMM,         F_CMP_UIMM,     0           },
148    { "cmpldi", D_OP(10)|M_L,       M_CRFD|M_RA|M_UIMM,         F_CMP_UIMM,     0           },
234149    { "cntlzw", D_OP(31)|D_XO(26),  M_RT|M_RA|M_RC,             F_RA_RT,        FL_RC       },
235150    { "crand",  D_OP(19)|D_XO(257), M_CRBD|M_CRBA|M_CRBB,       F_CRBD_CRBA_CRBB,   0       },
236151    { "crandc", D_OP(19)|D_XO(129), M_CRBD|M_CRBA|M_CRBB,       F_CRBD_CRBA_CRBB,   0       },
r2821r2822
424339 */
425340
426341static const char *const crbit[4] = { "lt", "gt", "eq", "so" };
342static const char *const crnbit[4] = { "ge", "le", "ne", "nso" };
427343
428344
429345/*
r2821r2822
450366
451367   switch (spr)
452368   {
453      case 1:      strcat(dest, "xer");   break;
454      case 8:      strcat(dest, "lr");      break;
455      case 9:      strcat(dest, "ctr");   break;
456      case 18:   strcat(dest, "dsisr");   break;
457      case 19:   strcat(dest, "dar");   break;
458      case 22:   strcat(dest, "dec");   break;
459      case 25:   strcat(dest, "sdr1");   break;
460      case 26:   strcat(dest, "srr0");   break;
461      case 27:   strcat(dest, "srr1");   break;
462      case 272:   strcat(dest, "sprg0");   break;
463      case 273:   strcat(dest, "sprg1");   break;
464      case 274:   strcat(dest, "sprg2");   break;
465      case 275:   strcat(dest, "sprg3");   break;
466      case 282:   strcat(dest, "ear");   break;
467      case 287:   strcat(dest, "pvr");   break;
468      case 528:   strcat(dest, "ibat0u");   break;
469      case 529:   strcat(dest, "ibat0l");   break;
470      case 530:   strcat(dest, "ibat1u");   break;
471      case 531:   strcat(dest, "ibat1l");   break;
472      case 532:   strcat(dest, "ibat2u");   break;
473      case 533:   strcat(dest, "ibat2l");   break;
474      case 534:   strcat(dest, "ibat3u");   break;
475      case 535:   strcat(dest, "ibat3l");   break;
476      case 536:   strcat(dest, "dbat0u");   break;
477      case 537:   strcat(dest, "dbat0l");   break;
478      case 538:   strcat(dest, "dbat1u");   break;
479      case 539:   strcat(dest, "dbat1l");   break;
480      case 540:   strcat(dest, "dbat2u");   break;
481      case 541:   strcat(dest, "dbat2l");   break;
482      case 542:   strcat(dest, "dbat3u");   break;
483      case 543:   strcat(dest, "dbat3l");   break;
484      case 1013:   strcat(dest, "dabr");   break;  // unsupported on 603e/EC603e
369      /* UISA SPR register indexes */
370      case SPR_XER:      strcat(dest, "xer");   break;
371      case SPR_LR:      strcat(dest, "lr");      break;
372      case SPR_CTR:      strcat(dest, "ctr");   break;
485373
486      /*
487         * Some PowerPC implementations may implement MFTB and MFSPR identically,
488         * therefore TBR registers are also decoded here
489         */
374      /* VEA SPR register indexes */
375      case SPRVEA_TBL_R:   strcat(dest, "tbl");   break;
376      case SPRVEA_TBU_R:   strcat(dest, "tbu");   break;
490377
491      case 268:   strcat(dest, "tbl");   break;
492      case 269:   strcat(dest, "tbu");   break;
378      /* OEA SPR register indexes */
379      case SPROEA_DSISR:   strcat(dest, "dsisr");   break;
380      case SPROEA_DAR:   strcat(dest, "dar");   break;
381      case SPROEA_DEC:   strcat(dest, "dec");   break;
382      case SPROEA_SDR1:   strcat(dest, "sdr1");   break;
383      case SPROEA_SRR0:   strcat(dest, "srr0");   break;
384      case SPROEA_SRR1:   strcat(dest, "srr1");   break;
385      case SPROEA_SPRG0:   strcat(dest, "sprg0");   break;
386      case SPROEA_SPRG1:   strcat(dest, "sprg1");   break;
387      case SPROEA_SPRG2:   strcat(dest, "sprg2");   break;
388      case SPROEA_SPRG3:   strcat(dest, "sprg3");   break;
389      case SPROEA_ASR:   strcat(dest, "asr");   break;
390      case SPROEA_EAR:   strcat(dest, "ear");   break;
391      case SPROEA_PVR:   strcat(dest, "pvr");   break;
392      case SPROEA_IBAT0U:   strcat(dest, "ibat0u");   break;
393      case SPROEA_IBAT0L:   strcat(dest, "ibat0l");   break;
394      case SPROEA_IBAT1U:   strcat(dest, "ibat1u");   break;
395      case SPROEA_IBAT1L:   strcat(dest, "ibat1l");   break;
396      case SPROEA_IBAT2U:   strcat(dest, "ibat2u");   break;
397      case SPROEA_IBAT2L:   strcat(dest, "ibat2l");   break;
398      case SPROEA_IBAT3U:   strcat(dest, "ibat3u");   break;
399      case SPROEA_IBAT3L:   strcat(dest, "ibat3l");   break;
400      case SPROEA_DBAT0U:   strcat(dest, "dbat0u");   break;
401      case SPROEA_DBAT0L:   strcat(dest, "dbat0l");   break;
402      case SPROEA_DBAT1U:   strcat(dest, "dbat1u");   break;
403      case SPROEA_DBAT1L:   strcat(dest, "dbat1l");   break;
404      case SPROEA_DBAT2U:   strcat(dest, "dbat2u");   break;
405      case SPROEA_DBAT2L:   strcat(dest, "dbat2l");   break;
406      case SPROEA_DBAT3U:   strcat(dest, "dbat3u");   break;
407      case SPROEA_DBAT3L:   strcat(dest, "dbat3l");   break;
408      case SPROEA_DABR:   strcat(dest, "dabr/iac2");   break;  // unsupported on 603e/EC603e
493409
494      /*
495         * PowerPC 603e/EC603e-specific registers
496         */
410      /* PowerPC 603E SPR register indexes */
411      case SPR603_HID0:   strcat(dest, "hid0/dbsr");   break;
412      case SPR603_HID1:   strcat(dest, "hid1");   break;
413      case SPR603_DMISS:   strcat(dest, "dmiss");   break;
414      case SPR603_DCMP:   strcat(dest, "dcmp");   break;
415      case SPR603_HASH1:   strcat(dest, "hash1");   break;
416      case SPR603_HASH2:   strcat(dest, "hash2/icdbdr");   break;
417      case SPR603_IMISS:   strcat(dest, "imiss");   break;
418      case SPR603_ICMP:   strcat(dest, "icmp/dear");   break;
419      case SPR603_RPA:   strcat(dest, "rpa/evpr");   break;
420      case SPR603_IABR:   strcat(dest, "iabr/dbcr");   break;
497421
498      case 1008:   strcat(dest, "hid0");   break;
499      case 1009:   strcat(dest, "hid1");   break;
500      case 976:   strcat(dest, "dmiss");   break;
501      case 977:   strcat(dest, "dcmp");   break;
502      case 978:   strcat(dest, "hash2");   break;
503      case 979:   strcat(dest, "hash2");   break;
504      case 980:   strcat(dest, "imiss");   break;
505      case 981:   strcat(dest, "icmp");   break;
506      case 982:   strcat(dest, "rpa");   break;
507      case 1010:   strcat(dest, "iabr");   break;
422      /* PowerPC 4XX SPR register indexes */
423      case SPR4XX_SGR:   strcat(dest, "sgr");   break;
424      case SPR4XX_DCWR:   strcat(dest, "dcwr");   break;
425      case SPR4XX_PID:   strcat(dest, "pid");   break;
426      case SPR4XX_TBHU:   strcat(dest, "tbhu");   break;
427      case SPR4XX_TBLU:   strcat(dest, "tblu");   break;
428//      case SPR4XX_ICDBDR: strcat(dest, "icdbdr"); break;  // same as SPR603E_HASH2
429//      case SPR4XX_DEAR:   strcat(dest, "dear");   break;  // same as SPR603E_ICMP
430//      case SPR4XX_EVPR:   strcat(dest, "evpr");   break;  // same as SPR603E_RPA
431      case SPR4XX_CDBCR:   strcat(dest, "cdbcr");   break;
432      case SPR4XX_TSR:   strcat(dest, "tsr");   break;
433      case SPR4XX_TCR:   strcat(dest, "tcr");   break;
434      case SPR4XX_PIT:   strcat(dest, "pit");   break;
435      case SPR4XX_TBHI:   strcat(dest, "tbhi");   break;
436      case SPR4XX_TBLO:   strcat(dest, "tblo");   break;
437      case SPR4XX_SRR2:   strcat(dest, "srr2");   break;
438      case SPR4XX_SRR3:   strcat(dest, "srr3");   break;
439//      case SPR4XX_DBSR:   strcat(dest, "dbsr");   break;  // same as SPR603E_HID0
440//      case SPR4XX_DBCR:   strcat(dest, "dbcr");   break;  // same as SPR603E_IABR
441      case SPR4XX_IAC1:   strcat(dest, "iac1");   break;
442//      case SPR4XX_IAC2:   strcat(dest, "iac2");   break;  // same as SPROEA_DABR
443      case SPR4XX_DAC1:   strcat(dest, "dac1");   break;
444      case SPR4XX_DAC2:   strcat(dest, "dac2");   break;
445      case SPR4XX_DCCR:   strcat(dest, "dccr");   break;
446      case SPR4XX_ICCR:   strcat(dest, "iccr");   break;
447      case SPR4XX_PBL1:   strcat(dest, "pbl1");   break;
448      case SPR4XX_PBU1:   strcat(dest, "pbu1");   break;
449      case SPR4XX_PBL2:   strcat(dest, "pbl2");   break;
450      case SPR4XX_PBU2:   strcat(dest, "pbu2");   break;
508451
509452      default:   sprintf(dest, "%s%d", dest, spr); break;
510453   }
r2821r2822
805748
806749      switch (G_BO(op))
807750      {
808         case 0x04:  // branch if condition is false
809         case 0x05:
810         case 0x06:
811         case 0x07:
812            strcat(mnem, "bf");
751         case 0x04:   case 0x05:   case 0x06:   case 0x07:
752            strcat(mnem, "b");
753            strcat(mnem, crnbit[G_BI(op) & 3]);
813754            break;
814         case 0x0c:
815         case 0x0d:
816         case 0x0e:
817         case 0x0f:
818            strcat(mnem, "bt");
755         case 0x0c:   case 0x0d:   case 0x0e:   case 0x0f:
756            strcat(mnem, "b");
757            strcat(mnem, crbit[G_BI(op) & 3]);
819758            break;
759         case 0x10:   case 0x11:   case 0x18:   case 0x19:
760            strcat(mnem, "bdnz");
761            break;
762         case 0x12:   case 0x13:   case 0x1a:   case 0x1b:
763            strcat(mnem, "bdz");
764            break;
765         case 0x14:   case 0x15:   case 0x16:   case 0x17:
766         case 0x1c:   case 0x1d:   case 0x1e:   case 0x1f:
767            strcat(mnem, "b");
768            break;
820769         default:
821770            return 0;
822771      }
r2821r2822
824773      if (op & M_LK)  strcat(mnem, "l");
825774      if (op & M_AA)  strcat(mnem, "a");
826775
827      sprintf(oprs, "cr%d[%s],0x%08X", G_BI(op) / 4, crbit[G_BI(op) & 3], disp + ((op & M_AA) ? 0 : vpc));
776      if (!(G_BO(op) & 0x10) && G_BI(op) / 4 != 0)
777         sprintf(oprs, "cr%d,0x%08X", G_BI(op) / 4, disp + ((op & M_AA) ? 0 : vpc));
778      else
779         sprintf(oprs, "0x%08X", disp + ((op & M_AA) ? 0 : vpc));
828780   }
781   else if ((op & ~(M_BO|M_BI|M_LK)) == (D_OP(19)|D_XO(528)) || (op & ~(M_BO|M_BI|M_LK)) == (D_OP(19)|D_XO(16)))
782   {
783      switch (G_BO(op))
784      {
785         case 0x04:   case 0x05:   case 0x06:   case 0x07:
786            strcat(mnem, "b");
787            strcat(mnem, crnbit[G_BI(op) & 3]);
788            break;
789         case 0x0c:   case 0x0d:   case 0x0e:   case 0x0f:
790            strcat(mnem, "b");
791            strcat(mnem, crbit[G_BI(op) & 3]);
792            break;
793         case 0x10:   case 0x11:   case 0x18:   case 0x19:
794            strcat(mnem, "bdnz");
795            break;
796         case 0x12:   case 0x13:   case 0x1a:   case 0x1b:
797            strcat(mnem, "bdz");
798            break;
799         case 0x14:   case 0x15:   case 0x16:   case 0x17:
800         case 0x1c:   case 0x1d:   case 0x1e:   case 0x1f:
801            strcat(mnem, "b");
802            break;
803         default:
804            return 0;
805      }
806
807      strcat(mnem, (G_XO(op) == 528) ? "ctr" : "lr");
808      if (op & M_LK)  strcat(mnem, "l");
809      if (op & M_AA)  strcat(mnem, "a");
810
811      if (!(G_BO(op) & 0x10) && G_BI(op) / 4 != 0)
812         sprintf(oprs, "cr%d", G_BI(op) / 4);
813   }
829814   else if ((op & ~(M_RT|M_RA|M_RB|M_OE|M_RC)) == (D_OP(31)|D_XO(40)))
830815   {
831816      strcat(mnem, "sub");
r2821r2822
961946            break;
962947
963948         case F_CMP:
964            sprintf(oprs, "cr%d,%d,r%d,r%d", G_CRFD(op), G_L(op), G_RA(op), G_RB(op));
949            if (G_L(op))
950               strcat(mnem, "d");
951            if (G_CRFD(op) == 0)
952               sprintf(oprs, "r%d,r%d", G_RA(op), G_RB(op));
953            else
954               sprintf(oprs, "cr%d,r%d,r%d", G_CRFD(op), G_RA(op), G_RB(op));
965955            break;
966956
967957         case F_CMP_SIMM:
968            sprintf(oprs, "cr%d,%d,r%d,%s", G_CRFD(op), G_L(op), G_RA(op), signed16);
958            if (G_L(op))
959               strcat(mnem, "d");
960            if (G_CRFD(op) == 0)
961               sprintf(oprs, "r%d,%s", G_RA(op), signed16);
962            else
963               sprintf(oprs, "cr%d,r%d,%s", G_CRFD(op), G_RA(op), signed16);
969964            break;
970965
971966         case F_CMP_UIMM:
972            sprintf(oprs, "cr%d,%d,r%d,0x%04X", G_CRFD(op), G_L(op), G_RA(op), G_UIMM(op));
967            if (G_L(op))
968               strcat(mnem, "d");
969            if (G_CRFD(op) == 0)
970               sprintf(oprs, "r%d,0x%04X", G_RA(op), G_UIMM(op));
971            else
972               sprintf(oprs, "cr%d,r%d,0x%04X", G_CRFD(op), G_RA(op), G_UIMM(op));
973973            break;
974974
975975         case F_RA_RT:
src/emu/cpu/powerpc/ppc.h
r2821r2822
1#ifndef _PPC_H
2#define _PPC_H
1/***************************************************************************
32
4#include "cpuintrf.h"
3    ppc.h
4    Interface file for the portable MIPS III/IV emulator.
5    Written by Aaron Giles
56
6#define SPR_XER            1      /* Fixed Point Exception Register               Read / Write */
7#define SPR_LR            8      /* Link Register                                Read / Write */
8#define SPR_CTR            9      /* Count Register                               Read / Write */
9#define SPR_SRR0         26      /* Save/Restore Register 0                      Read / Write */
10#define SPR_SRR1         27      /* Save/Restore Register 1                      Read / Write */
11#define SPR_SPRG0         272      /* SPR General 0                                Read / Write */
12#define SPR_SPRG1         273      /* SPR General 1                                Read / Write */
13#define SPR_SPRG2         274      /* SPR General 2                                Read / Write */
14#define SPR_SPRG3         275      /* SPR General 3                                Read / Write */
15#define SPR_PVR            287      /* Processor Version Number                     Read Only */
7***************************************************************************/
168
17#define SPR403_ICDBDR      0x3D3   /* 406GA Instruction Cache Debug Data Register  Rad Only */
18#define SPR403_ESR         0x3D4   /* 406GA Exception Syndrome Register            Read / Write */
19#define SPR403_DEAR         0x3D5   /* 406GA Data Exception Address Register        Read Only */
20#define SPR403_EVPR         0x3D6   /* 406GA Exception Vector Prefix Register       Read / Write */
21#define SPR403_CDBCR      0x3D7   /* 406GA Cache Debug Control Register           Read/Write */
22#define SPR403_TSR         0x3D8   /* 406GA Timer Status Register                  Read / Clear */
23#define SPR403_TCR         0x3DA   /* 406GA Timer Control Register                 Read / Write */
24#define SPR403_PIT         0x3DB   /* 406GA Programmable Interval Timer            Read / Write */
25#define SPR403_TBHI         988      /* 406GA Time Base High                         Read / Write */
26#define SPR403_TBLO         989      /* 406GA Time Base Low                          Read / Write */
27#define SPR403_SRR2         0x3DE   /* 406GA Save/Restore Register 2                Read / Write */
28#define SPR403_SRR3         0x3DF   /* 406GA Save/Restore Register 3                Read / Write */
29#define SPR403_DBSR         0x3F0   /* 406GA Debug Status Register                  Read / Clear */
30#define SPR403_DBCR         0x3F2   /* 406GA Debug Control Register                 Read / Write */
31#define SPR403_IAC1         0x3F4   /* 406GA Instruction Address Compare 1          Read / Write */
32#define SPR403_IAC2         0x3F5   /* 406GA Instruction Address Compare 2          Read / Write */
33#define SPR403_DAC1         0x3F6   /* 406GA Data Address Compare 1                 Read / Write */
34#define SPR403_DAC2         0x3F7   /* 406GA Data Address Compare 2                 Read / Write */
35#define SPR403_DCCR         0x3FA   /* 406GA Data Cache Cacheability Register       Read / Write */
36#define SPR403_ICCR         0x3FB   /* 406GA I Cache Cacheability Registe           Read / Write */
37#define SPR403_PBL1         0x3FC   /* 406GA Protection Bound Lower 1               Read / Write */
38#define SPR403_PBU1         0x3FD   /* 406GA Protection Bound Upper 1               Read / Write */
39#define SPR403_PBL2         0x3FE   /* 406GA Protection Bound Lower 2               Read / Write */
40#define SPR403_PBU2         0x3FF   /* 406GA Protection Bound Upper 2               Read / Write */
9#ifndef __PPC_H__
10#define __PPC_H__
4111
42#define SPR403_SGR         0x3b9   /* 403GCX Storage Guarded Register */
43#define SPR403_DCWR         0x3ba   /* 403GCX Data Cache Write Through */
44#define SPR403_PID         0x3b1   /* 403GCX Process ID */
45#define SPR403_TBHU         0x3cc   /* 403GCX Time Base High User-mode */
46#define SPR403_TBLU         0x3cd   /* 403GCX Time Base Low User-mode */
12#include "cpuintrf.h"
4713
48#define SPR603E_DSISR      18      /* 603E */
49#define SPR603E_DAR         19      /* 603E */
50#define SPR603E_DEC         22      /* 603E */
51#define SPR603E_SDR1      25      /* 603E */
52#define SPR603E_TBL_R      268      /* 603E Time Base Low (Read-only) */
53#define SPR603E_TBU_R      269      /* 603E Time Base High (Read-only) */
54#define SPR603E_TBL_W      284      /* 603E Time Base Low (Write-only) */
55#define SPR603E_TBU_W      285      /* 603E Time Base Hight (Write-only) */
56#define SPR603E_EAR         282      /* 603E */
57#define SPR603E_IBAT0U      528      /* 603E */
58#define SPR603E_IBAT0L      529      /* 603E */
59#define SPR603E_IBAT1U      530      /* 603E */
60#define SPR603E_IBAT1L      531      /* 603E */
61#define SPR603E_IBAT2U      532      /* 603E */
62#define SPR603E_IBAT2L      533      /* 603E */
63#define SPR603E_IBAT3U      534      /* 603E */
64#define SPR603E_IBAT3L      535      /* 603E */
65#define SPR603E_DBAT0U      536      /* 603E */
66#define SPR603E_DBAT0L      537      /* 603E */
67#define SPR603E_DBAT1U      538      /* 603E */
68#define SPR603E_DBAT1L      539      /* 603E */
69#define SPR603E_DBAT2U      540      /* 603E */
70#define SPR603E_DBAT2L      541      /* 603E */
71#define SPR603E_DBAT3U      542      /* 603E */
72#define SPR603E_DBAT3L      543      /* 603E */
73#define SPR603E_DABR      1013   /* 603E */
74#define SPR603E_DMISS      0x3d0   /* 603E */
75#define SPR603E_DCMP      0x3d1   /* 603E */
76#define SPR603E_HASH1      0x3d2   /* 603E */
77#define SPR603E_HASH2      0x3d3   /* 603E */
78#define SPR603E_IMISS      0x3d4   /* 603E */
79#define SPR603E_ICMP      0x3d5   /* 603E */
80#define SPR603E_RPA         0x3d6   /* 603E */
81#define SPR603E_HID0      1008   /* 603E */
82#define SPR603E_HID1      1009   /* 603E */
83#define SPR603E_IABR      1010   /* 603E */
84#define SPR603E_HID2      1011   /* 603E */
8514
86#define SPR602_TCR         984      /* 602 */
87#define SPR602_IBR         986      /* 602 */
88#define SPR602_ESASRR      987      /* 602 */
89#define SPR602_SEBR         990      /* 602 */
90#define SPR602_SER         991      /* 602 */
91#define SPR602_SP         1021   /* 602 */
92#define SPR602_LT         1022   /* 602 */
15/***************************************************************************
16    REGISTER ENUMERATION
17***************************************************************************/
9318
94
95#define DCR_BEAR      0x90   /* bus error address */
96#define DCR_BESR      0x91   /* bus error syndrome */
97#define DCR_BR0         0x80   /* bank */
98#define DCR_BR1         0x81   /* bank */
99#define DCR_BR2         0x82   /* bank */
100#define DCR_BR3         0x83   /* bank */
101#define DCR_BR4         0x84   /* bank */
102#define DCR_BR5         0x85   /* bank */
103#define DCR_BR6         0x86   /* bank */
104#define DCR_BR7         0x87   /* bank */
105#define DCR_DMACC0      0xc4   /* dma chained count */
106#define DCR_DMACC1      0xcc   /* dma chained count */
107#define DCR_DMACC2      0xd4   /* dma chained count */
108#define DCR_DMACC3      0xdc   /* dma chained count */
109#define DCR_DMACR0      0xc0   /* dma channel control */
110#define DCR_DMACR1      0xc8   /* dma channel control */
111#define DCR_DMACR2      0xd0   /* dma channel control */
112#define DCR_DMACR3      0xd8   /* dma channel control */
113#define DCR_DMACT0      0xc1   /* dma destination address */
114#define DCR_DMACT1      0xc9   /* dma destination address */
115#define DCR_DMACT2      0xd1   /* dma destination address */
116#define DCR_DMACT3      0xd9   /* dma destination address */
117#define DCR_DMADA0      0xc2   /* dma destination address */
118#define DCR_DMADA1      0xca   /* dma destination address */
119#define DCR_DMADA2      0xd2   /* dma source address */
120#define DCR_DMADA3      0xda   /* dma source address */
121#define DCR_DMASA0      0xc3   /* dma source address */
122#define DCR_DMASA1      0xcb   /* dma source address */
123#define DCR_DMASA2      0xd3   /* dma source address */
124#define DCR_DMASA3      0xdb   /* dma source address */
125#define DCR_DMASR      0xe0   /* dma status */
126#define DCR_EXIER      0x42   /* external interrupt enable */
127#define DCR_EXISR      0x40   /* external interrupt status */
128#define DCR_IOCR      0xa0   /* io configuration */
129
130enum {
131   EXCEPTION_IRQ                  = 1,
132   EXCEPTION_DECREMENTER            = 2,
133   EXCEPTION_TRAP                  = 3,
134   EXCEPTION_SYSTEM_CALL            = 4,
135   EXCEPTION_SMI                  = 5,
136   EXCEPTION_DSI                  = 6,
137   EXCEPTION_ISI                  = 7,
138   EXCEPTION_PROGRAMMABLE_INTERVAL_TIMER   = 20,
139   EXCEPTION_FIXED_INTERVAL_TIMER      = 21,
140   EXCEPTION_WATCHDOG_TIMER         = 22,
141   EXCEPTION_CRITICAL_INTERRUPT         = 23,
142};
143
144enum {
145   PPC_INPUT_LINE_SMI = 10,
146   PPC_INPUT_LINE_TLBISYNC
147};
148
149enum {
150   PPC_PC=1,
151   PPC_MSR,
152   PPC_CR,
153   PPC_LR,
154   PPC_CTR,
155   PPC_XER,
156   PPC_DEC,
157   PPC_SRR0,
158   PPC_SRR1,
159   PPC_EXIER,
160   PPC_EXISR,
161   PPC_IBR,
19enum
20{
21   PPC_PC = 1,
16222   PPC_R0,
16323   PPC_R1,
16424   PPC_R2,
r2821r2822
19050   PPC_R28,
19151   PPC_R29,
19252   PPC_R30,
193   PPC_R31
53   PPC_R31,
54   PPC_CR,
55   PPC_LR,
56   PPC_CTR,
57   PPC_XER,
58   PPC_MSR,
59   PPC_SRR0,
60   PPC_SRR1,
61   PPC_SPRG0,
62   PPC_SPRG1,
63   PPC_SPRG2,
64   PPC_SPRG3,
65   PPC_SDR1,
66   PPC_EXIER,
67   PPC_EXISR,
68   PPC_EVPR,
69   PPC_IOCR
19470};
19571
196typedef enum {
197   PPC_MODEL_403GA            = 0x00200000,
198   PPC_MODEL_403GB            = 0x00200100,
199   PPC_MODEL_403GC            = 0x00200200,
200   PPC_MODEL_403GCX         = 0x00201400,
201   PPC_MODEL_405GP            = 0x40110000,
202   PPC_MODEL_601            = 0x00010000,
203   PPC_MODEL_603            = 0x00030000,   /* "Wart" */
204   PPC_MODEL_604            = 0x00040000,   /* "Zephyr" */
205   PPC_MODEL_602            = 0x00050200,   /* "Galahad" */
206   PPC_MODEL_603E            = 0x00060103,   /* "Stretch", version 1.3 */
207   PPC_MODEL_603EV            = 0x00070000,   /* "Valiant" */
208   PPC_MODEL_603R            = 0x00071202,   /* "Goldeneye", version 2.1 */
209   PPC_MODEL_740            = 0x00080301,   /* "Arthur", version 3.1 */
210   PPC_MODEL_750            = PPC_MODEL_740,
211   PPC_MODEL_740P            = 0x00080202,   /* "Conan Doyle", version 1.2 */
212   PPC_MODEL_750P            = PPC_MODEL_740P,
213   PPC_MODEL_755            = 0x00083203,   /* "Goldfinger", version 2.3 */
214   PPC_MODEL_7400            = 0x000c0209,   /* "Max", version 2.9 */
215   PPC_MODEL_7410            = 0x800c1104,   /* "Nitro", version 3.4 */
216   PPC_MODEL_7450            = 0x80000201,   /* "Vger", version 2.1 */
217   PPC_MODEL_7451            = 0x80000203,   /* "Vger", version 2.3 */
218   PPC_MODEL_7441            = PPC_MODEL_7451,
219   PPC_MODEL_7455            = 0x80010303,   /* "Apollo 6", version 3.3 */
220   PPC_MODEL_7445            = PPC_MODEL_7455,
221   PPC_MODEL_7457            = 0x80020101,   /* "Apollo 7", version 1.1 */
222   PPC_MODEL_MPC8240         = 0x00810101,   /* "Kahlua" */
223   PPC_MODEL_MPC8241         = 0x80811014,   /* "Kahlua Lt" */
224   PPC_MODEL_MPC8245         = 0x80811014,   /* "Kahlua II" */
225} PPC_MODEL;
22672
227typedef enum {
228   BUS_FREQUENCY_16MHZ = 0,
229   BUS_FREQUENCY_20MHZ,
230   BUS_FREQUENCY_25MHZ,
231   BUS_FREQUENCY_33MHZ,
232   BUS_FREQUENCY_40MHZ,
233   BUS_FREQUENCY_50MHZ,
234   BUS_FREQUENCY_60MHZ,
235   BUS_FREQUENCY_66MHZ,
236   BUS_FREQUENCY_75MHZ,
237} PPC_BUS_FREQUENCY;
73#define PPC_MAX_FASTRAM         4
74#define PPC_MAX_HOTSPOTS      16
23875
239// PLL Configuration based on the table in MPC603EUM page 7-31
240static const int mpc603e_pll_config[12][9] =
241{
242   // 16,  20,  25,  33,  40,  50,  60,  66,  75
243   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
244   { 0x2, 0x2, 0x2, 0x1, 0x1, 0x1,  -1, 0x0,  -1 },
245   {  -1,  -1,  -1,  -1,  -1, 0xc,  -1, 0xc,  -1 },
246   { 0x5, 0x5, 0x5, 0x4, 0x4, 0x4,  -1,  -1,  -1 },
247   {  -1,   -1,  -1, 0x6, 0x6,  -1,  -1,  -1,  -1 },
248   {  -1,  -1, 0x8, 0x8,  -1,  -1,  -1,  -1,  -1 },
249   {  -1, 0xe, 0xe,  -1,  -1,  -1,  -1,  -1,  -1 },
250   { 0xa, 0xa, 0xa,  -1,  -1,  -1,  -1,  -1,  -1 },
251   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
252   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
253   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
254   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
255};
25676
257// PLL Configuration based on the table in MPC603E7VEC page 29
258static const int mpc603ev_pll_config[12][9] =
77enum
25978{
260   // 16,  20,  25,  33,  40,  50,  60,  66,  75
261   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
262   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
263   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
264   // 2:1
265   {  -1,  -1,  -1,  -1,  -1,  -1,  -1, 0x4, 0x4 },
266   // 2.5:1
267   {  -1,  -1,  -1,  -1,  -1, 0x6, 0x6, 0x6, 0x6 },
268   // 3:1
269   {  -1,  -1,  -1,  -1, 0x8, 0x8, 0x8, 0x8, 0x8 },
270   // 3.5:1
271   {  -1,  -1,  -1,  -1, 0xe, 0xe, 0xe, 0xe,  -1 },
272   // 4:1
273   {  -1,  -1,  -1, 0xa, 0xa, 0xa, 0xa,  -1,  -1 },
274   // 4.5:1
275   {  -1,  -1,  -1, 0x7, 0x7, 0x7,  -1,  -1,  -1 },
276   // 5:1
277   {  -1,  -1, 0xb, 0xb, 0xb,  -1,  -1,  -1,  -1 },
278   // 5.5:1
279   {  -1,  -1, 0x9, 0x9, 0x9,  -1,  -1,  -1,  -1 },
280   // 6:1
281   {  -1,  -1, 0xd, 0xd, 0xd,  -1,  -1,  -1,  -1 }
282};
79   CPUINFO_INT_PPC_DRC_OPTIONS = CPUINFO_INT_CPU_SPECIFIC,
28380
284// PLL Configuration based on the table in MPC603E7TEC page 23
285static const int mpc603r_pll_config[12][9] =
286{
287   // 16,  20,  25,  33,  40,  50,  60,  66,  75
288   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
289   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
290   {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1 },
291   // 2:1
292   {  -1,  -1,  -1,  -1, 0x5, 0x5, 0x5, 0x5, 0x5 },
293   // 2.5:1
294   {  -1,  -1,  -1,  -1,  -1,  -1, 0x6, 0x6, 0x6 },
295   // 3:1
296   {  -1,  -1,  -1,  -1,  -1, 0x8, 0x8, 0x8, 0x8 },
297   // 3.5:1
298   {  -1,  -1,  -1,  -1,  -1, 0xe, 0xe, 0xe, 0xe },
299   // 4:1
300   {  -1,  -1,  -1,  -1, 0xa, 0xa, 0xa, 0xa, 0xa },
301   // 4.5:1
302   {  -1,  -1,  -1, 0x7, 0x7, 0x7, 0x7, 0x7,  -1 },
303   // 5:1
304   {  -1,  -1,  -1, 0xb, 0xb, 0xb, 0xb,  -1,  -1 },
305   // 5.5:1
306   {  -1,  -1,  -1, 0x9, 0x9, 0x9,  -1,  -1,  -1 },
307   // 6:1
308   {  -1,  -1, 0xd, 0xd, 0xd, 0xd,  -1,  -1,  -1 },
81   CPUINFO_INT_PPC_FASTRAM_SELECT,
82   CPUINFO_INT_PPC_FASTRAM_START,
83   CPUINFO_INT_PPC_FASTRAM_END,
84   CPUINFO_INT_PPC_FASTRAM_READONLY,
85
86   CPUINFO_INT_PPC_HOTSPOT_SELECT,
87   CPUINFO_INT_PPC_HOTSPOT_PC,
88   CPUINFO_INT_PPC_HOTSPOT_OPCODE,
89   CPUINFO_INT_PPC_HOTSPOT_CYCLES,
90
91   CPUINFO_INT_PPC_RX_DATA,
92
93   CPUINFO_PTR_PPC_FASTRAM_BASE = CPUINFO_PTR_CPU_SPECIFIC,
94
95   CPUINFO_PTR_SPU_RX_HANDLER,
96   CPUINFO_PTR_SPU_TX_HANDLER,
97
98   CPUINFO_PTR_CONTEXT         /* temporary */
30999};
310100
311#define PPCDRC_OPTIONS_CHECK_SELFMOD_CODE            0x1
312101
313enum
102
103/***************************************************************************
104    INTERRUPT CONSTANTS
105***************************************************************************/
106
107#define PPC_IRQ            0      /* external IRQ */
108#define PPC_IRQ_LINE_0      0      /* (4XX) external IRQ0 */
109#define PPC_IRQ_LINE_1      1      /* (4XX) external IRQ1 */
110#define PPC_IRQ_LINE_2      2      /* (4XX) external IRQ2 */
111#define PPC_IRQ_LINE_3      3      /* (4XX) external IRQ3 */
112#define PPC_IRQ_LINE_4      4      /* (4XX) external IRQ4 */
113
114
115
116/***************************************************************************
117    STRUCTURES
118***************************************************************************/
119
120typedef struct _powerpc_config powerpc_config;
121struct _powerpc_config
314122{
315   CPUINFO_INT_PPC_DRC_OPTIONS = CPUINFO_INT_CPU_SPECIFIC,
123   UINT32      bus_frequency;
316124};
317125
318typedef struct {
319   PPC_MODEL pvr;
320   int bus_frequency_multiplier;
321   PPC_BUS_FREQUENCY bus_frequency;
322} ppc_config;
323126
324#if (HAS_PPC403)
325typedef UINT8 (* SPU_RX_HANDLER)(void);
326typedef void  (* SPU_TX_HANDLER)(UINT8);
327typedef void (* PPC_DMA_HANDLER)(int);
328127
329void ppc403_spu_rx(UINT8 data);
330void ppc403_install_spu_rx_handler(SPU_RX_HANDLER rx_handler);
331void ppc403_install_spu_tx_handler(SPU_TX_HANDLER tx_handler);
332void ppc403_install_spu_rx_dma_handler(PPC_DMA_HANDLER rx_dma_handler, UINT8 *buffer);
333void ppc403_install_spu_tx_dma_handler(PPC_DMA_HANDLER tx_dma_handler, UINT8 *buffer);
334void ppc403_install_dma_read_handler(int ch, PPC_DMA_HANDLER dma_handler, UINT8 *buffer);
335void ppc403_install_dma_write_handler(int ch, PPC_DMA_HANDLER dma_handler, UINT8 *buffer);
128/***************************************************************************
129    PUBLIC FUNCTIONS
130***************************************************************************/
336131
337#define PPC403_SPU_RX      5
338#define PPC403_SPU_TX      6
339#define PPC403_CRITICAL_IRQ      7
132#if (HAS_PPC403GA)
133void ppc403ga_get_info(UINT32 state, cpuinfo *info);
134#endif
340135
136#if (HAS_PPC403GCX)
137void ppc403gcx_get_info(UINT32 state, cpuinfo *info);
341138#endif
342139
343#if (HAS_PPC403)
344void ppc403_get_info(UINT32 state, cpuinfo *info);
140#if (HAS_PPC601)
141void ppc601_get_info(UINT32 state, cpuinfo *info);
345142#endif
346143
347144#if (HAS_PPC602)
r2821r2822
352149void ppc603_get_info(UINT32 state, cpuinfo *info);
353150#endif
354151
355#if (HAS_MPC8240)
356void mpc8240_get_info(UINT32 state, cpuinfo *info);
152#if (HAS_PPC603E)
153void ppc603e_get_info(UINT32 state, cpuinfo *info);
357154#endif
358155
359#if (HAS_PPC601)
360void ppc601_get_info(UINT32 state, cpuinfo *info);
156#if (HAS_PPC603R)
157void ppc603r_get_info(UINT32 state, cpuinfo *info);
361158#endif
362159
363160#if (HAS_PPC604)
364161void ppc604_get_info(UINT32 state, cpuinfo *info);
365162#endif
366163
367#ifdef ENABLE_DEBUGGER
368extern offs_t ppc_dasm_one(char *buffer, offs_t pc, UINT32 op);
164#if (HAS_MPC8240)
165void mpc8240_get_info(UINT32 state, cpuinfo *info);
369166#endif
370167
371#endif   /* _PPC_H */
168
169
170/***************************************************************************
171    COMPILER-SPECIFIC OPTIONS
172***************************************************************************/
173
174#define PPCDRC_STRICT_VERIFY      0x0001         /* verify all instructions */
175#define PPCDRC_FLUSH_PC            0x0002         /* flush the PC value before each memory access */
176
177#define PPCDRC_COMPATIBLE_OPTIONS   (PPCDRC_STRICT_VERIFY | PPCDRC_FLUSH_PC)
178#define PPCDRC_FASTEST_OPTIONS      (0)
179
180#endif   /* __PPC_H__ */
src/emu/cpu/powerpc/ppcfe.c
r0r2822
1/***************************************************************************
2 
3    ppcfe.c
4 
5    Front-end for PowerPC recompiler
6 
7    Copyright Aaron Giles
8    Released for general non-commercial use under the MAME license
9    Visit http://mamedev.org for licensing and usage restrictions.
10 
11***************************************************************************/
12 
13#include <stddef.h>
14#include "cpuintrf.h"
15#include "ppcfe.h"
16#include "ppccom.h"
17 
18 
19/***************************************************************************
20    FUNCTION PROTOTYPES
21***************************************************************************/
22 
23static int describe_instruction_13(powerpc_state *ppc, UINT32 op, opcode_desc *desc);
24static int describe_instruction_1f(powerpc_state *ppc, UINT32 op, opcode_desc *desc);
25static int describe_instruction_3b(powerpc_state *ppc, UINT32 op, opcode_desc *desc);
26static int describe_instruction_3f(powerpc_state *ppc, UINT32 op, opcode_desc *desc);
27 
28 
29 
30/***************************************************************************
31    INSTRUCTION PARSERS
32***************************************************************************/
33 
34/*-------------------------------------------------
35    ppcfe_describe - build a description
36    of a single instruction
37-------------------------------------------------*/
38 
39int ppcfe_describe(void *param, opcode_desc *desc)
40{
41   powerpc_state *ppc = param;
42   UINT32 op = *desc->opptr.l;
43   UINT32 opswitch = op >> 26;
44 
45   /* all instructions are 4 bytes and default to a single cycle each */
46   desc->length = 4;
47   desc->cycles = 1;
48 
49   /* parse the instruction */
50   switch (opswitch)
51   {
52      case 0x02:   /* TDI - 64-bit only */
53      case 0x1e:   /* 0x1e group - 64-bit only */
54      case 0x3a:   /* 0x3a group - 64-bit only */
55      case 0x3e:   /* 0x3e group - 64-bit only */
56         return FALSE;
57 
58      case 0x03:   /* TWI */
59         desc->gpr.used |= REGFLAG_R(G_RA(op));
60         desc->flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
61         return TRUE;
62 
63      case 0x07:   /* MULLI */
64         desc->gpr.used |= REGFLAG_R(G_RA(op));
65         desc->gpr.modified |= REGFLAG_R(G_RD(op));
66         return TRUE;
67 
68      case 0x0e:   /* ADDI */
69      case 0x0f:   /* ADDIS */
70         desc->gpr.used |= REGFLAG_RZ(G_RA(op));
71         desc->gpr.modified |= REGFLAG_R(G_RD(op));
72         return TRUE;
73 
74      case 0x0a:   /* CMPLI */
75      case 0x0b:   /* CMPI */
76         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_XER;
77         desc->gpr.modified |= REGFLAG_CR(G_CRFD(op));
78         return TRUE;
79 
80      case 0x08:   /* SUBFIC */
81      case 0x0c:   /* ADDIC */
82         desc->gpr.used |= REGFLAG_R(G_RA(op));
83         desc->gpr.modified |= REGFLAG_R(G_RD(op)) | REGFLAG_XER;
84         return TRUE;
85 
86      case 0x0d:   /* ADDIC. */
87         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_XER;
88         desc->gpr.modified |= REGFLAG_R(G_RT(op)) | REGFLAG_CR(0) | REGFLAG_XER;
89         return TRUE;
90 
91      case 0x10:   /* BCx */
92         desc->gpr.used |= REGFLAG_CR(G_BI(op) / 4);
93         if (op & M_LK) desc->gpr.modified |= REGFLAG_LR;
94         if (!(G_BO(op) & 4))
95         {
96            desc->gpr.used |= REGFLAG_CTR;
97            desc->gpr.modified |= REGFLAG_CTR;
98         }
99         if ((G_BO(op) & 0x14) == 0x14)
100            desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
101         else
102            desc->flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
103         desc->targetpc = (INT16)(G_BD(op) << 2) + ((op & M_AA) ? 0 : desc->pc);
104         return TRUE;
105 
106      case 0x11:   /* SC */
107         if (!(ppc->cap & (PPCCAP_OEA | PPCCAP_4XX)))
108            return FALSE;
109         desc->flags |= OPFLAG_WILL_CAUSE_EXCEPTION;
110         return TRUE;
111 
112      case 0x12:   /* Bx */
113         if (op & M_LK) desc->gpr.modified |= REGFLAG_LR;
114         desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
115         desc->targetpc = ((INT32)(G_LI(op) << 8) >> 6) + ((op & M_AA) ? 0 : desc->pc);
116         return TRUE;
117 
118      case 0x13:   /* 0x13 group */
119         return describe_instruction_13(ppc, op, desc);
120 
121      case 0x14:   /* RLWIMIx */
122         desc->gpr.used |= REGFLAG_R(G_RS(op)) | REGFLAG_R(G_RA(op));
123         desc->gpr.modified |= REGFLAG_R(G_RA(op));
124         if (op & M_RC)
125         {
126            desc->gpr.used |= REGFLAG_XER;
127            desc->gpr.modified |= REGFLAG_CR(0);
128         }
129         return TRUE;
130 
131      case 0x15:   /* RLWINMx */
132         desc->gpr.used |= REGFLAG_R(G_RS(op));
133         desc->gpr.modified |= REGFLAG_R(G_RA(op));
134         if (op & M_RC)
135         {
136            desc->gpr.used |= REGFLAG_XER;
137            desc->gpr.modified |= REGFLAG_CR(0);
138         }
139         return TRUE;
140 
141      case 0x17:   /* RLWNMx */
142         desc->gpr.used |= REGFLAG_R(G_RS(op)) | REGFLAG_R(G_RB(op));
143         desc->gpr.modified |= REGFLAG_R(G_RA(op));
144         if (op & M_RC)
145         {
146            desc->gpr.used |= REGFLAG_XER;
147            desc->gpr.modified |= REGFLAG_CR(0);
148         }
149         return TRUE;
150 
151      case 0x18:   /* ORI */
152      case 0x19:   /* ORIS */
153      case 0x1a:   /* XORI */
154      case 0x1b:   /* XORIS */
155         desc->gpr.used |= REGFLAG_R(G_RS(op));
156         desc->gpr.modified |= REGFLAG_R(G_RA(op));
157         return TRUE;
158 
159      case 0x1c:   /* ANDI. */
160      case 0x1d:   /* ANDIS. */
161         desc->gpr.used |= REGFLAG_R(G_RS(op)) | REGFLAG_XER;
162         desc->gpr.modified |= REGFLAG_R(G_RA(op)) | REGFLAG_CR(0);
163         return TRUE;
164 
165      case 0x1f:   /* 0x1f group */
166         return describe_instruction_1f(ppc, op, desc);
167 
168      case 0x20:   /* LWZ */
169      case 0x22:   /* LBZ */
170      case 0x28:   /* LHZ */
171      case 0x2a:   /* LHA */
172         desc->gpr.used |= REGFLAG_RZ(G_RA(op));
173         desc->gpr.modified |= REGFLAG_R(G_RD(op));
174         desc->flags |= OPFLAG_READS_MEMORY;
175         return TRUE;
176 
177      case 0x21:   /* LWZU */
178      case 0x23:   /* LBZU */
179      case 0x29:   /* LHZU */
180      case 0x2b:   /* LHAU */
181         if (G_RA(op) == 0)
182            return FALSE;
183         desc->gpr.used |= REGFLAG_R(G_RA(op));
184         desc->gpr.modified |= REGFLAG_R(G_RD(op)) | REGFLAG_R(G_RA(op));
185         desc->flags |= OPFLAG_READS_MEMORY;
186         return TRUE;
187 
188      case 0x24:   /* STW */
189      case 0x26:   /* STB */
190      case 0x2c:   /* STH */
191         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RS(op));
192         desc->flags |= OPFLAG_WRITES_MEMORY;
193         return TRUE;
194 
195      case 0x25:   /* STWU */
196      case 0x27:   /* STBU */
197      case 0x2d:   /* STHU */
198         if (G_RA(op) == 0)
199            return FALSE;
200         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RS(op));
201         desc->gpr.modified |= REGFLAG_R(G_RA(op));
202         desc->flags |= OPFLAG_WRITES_MEMORY;
203         return TRUE;
204 
205      case 0x2e:   /* LMW */
206         desc->gpr.used |= REGFLAG_RZ(G_RA(op));
207         desc->gpr.modified |= ((REGFLAG_R(31) << 1) - 1) & ~(REGFLAG_R(G_RD(op)) - 1);
208         desc->flags |= OPFLAG_READS_MEMORY;
209         return TRUE;
210 
211      case 0x2f:   /* STMW */
212         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | (((REGFLAG_R(31) << 1) - 1) & ~(REGFLAG_R(G_RS(op)) - 1));
213         desc->flags |= OPFLAG_WRITES_MEMORY;
214         return TRUE;
215 
216      case 0x30:   /* LFS */
217      case 0x32:   /* LFD */
218         if (!(ppc->cap & PPCCAP_FPU))
219            return FALSE;
220         desc->gpr.used |= REGFLAG_RZ(G_RA(op));
221         desc->fpr.modified |= REGFLAG_R(G_RD(op));
222         desc->flags |= OPFLAG_READS_MEMORY;
223         return TRUE;
224 
225      case 0x31:   /* LFSU */
226      case 0x33:   /* LFDU */
227         if (!(ppc->cap & PPCCAP_FPU))
228            return FALSE;
229         desc->gpr.used |= REGFLAG_RZ(G_RA(op));
230         desc->gpr.modified |= REGFLAG_R(G_RA(op));
231         desc->fpr.modified |= REGFLAG_R(G_RD(op));
232         desc->flags |= OPFLAG_READS_MEMORY;
233         return TRUE;
234 
235      case 0x34:   /* STFS */
236      case 0x36:   /* STFD */
237         if (!(ppc->cap & PPCCAP_FPU))
238            return FALSE;
239         desc->gpr.used |= REGFLAG_RZ(G_RA(op));
240         desc->fpr.used |= REGFLAG_R(G_RS(op));
241         desc->flags |= OPFLAG_WRITES_MEMORY;
242         return TRUE;
243 
244      case 0x35:   /* STFSU */
245      case 0x37:   /* STFDU */
246         if (!(ppc->cap & PPCCAP_FPU))
247            return FALSE;
248         desc->gpr.used |= REGFLAG_RZ(G_RA(op));
249         desc->gpr.modified |= REGFLAG_R(G_RA(op));
250         desc->fpr.used |= REGFLAG_R(G_RS(op));
251         desc->flags |= OPFLAG_WRITES_MEMORY;
252         return TRUE;
253 
254      case 0x3b:   /* 0x3b group */
255         return describe_instruction_3b(ppc, op, desc);
256 
257      case 0x3f:   /* 0x3f group */
258         return describe_instruction_3f(ppc, op, desc);
259   }
260 
261   return FALSE;
262}
263 
264 
265/*-------------------------------------------------
266    describe_instruction_13 - build a
267    description of a single instruction in the
268    0x13 group
269-------------------------------------------------*/
270 
271static int describe_instruction_13(powerpc_state *ppc, UINT32 op, opcode_desc *desc)
272{
273   UINT32 opswitch = (op >> 1) & 0x3ff;
274 
275   switch (opswitch)
276   {
277      case 0x000:   /* MTCRF */
278         desc->gpr.used |= REGFLAG_CR(G_CRFS(op));
279         desc->gpr.modified |= REGFLAG_CR(G_CRFD(op));
280         return TRUE;
281 
282      case 0x010:   /* BCLRx */
283         desc->gpr.used |= REGFLAG_CR(G_BI(op) / 4) | REGFLAG_LR;
284         if (op & M_LK) desc->gpr.modified |= REGFLAG_LR;
285         if (!(G_BO(op) & 4))
286         {
287            desc->gpr.used |= REGFLAG_CTR;
288            desc->gpr.modified |= REGFLAG_CTR;
289         }
290         if ((G_BO(op) & 0x14) == 0x14)
291            desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
292         else
293            desc->flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
294         desc->targetpc = BRANCH_TARGET_DYNAMIC;
295         return TRUE;
296 
297      case 0x021:   /* CRNOR */
298      case 0x081:   /* CRANDC */
299      case 0x0c1:   /* CRXOR */
300      case 0x0e1:   /* CRNAND */
301      case 0x101:   /* CRAND */
302      case 0x121:   /* CREQV */
303      case 0x1a1:   /* CRORC */
304      case 0x1c1:   /* CROR */
305         desc->gpr.used |= REGFLAG_CR(G_CRBA(op) / 4) | REGFLAG_CR(G_CRBB(op) / 4);
306         desc->gpr.modified |= REGFLAG_CR(G_CRBD(op) / 4);
307         return TRUE;
308 
309      case 0x032:   /* RFI */
310         if (!(ppc->cap & (PPCCAP_OEA | PPCCAP_4XX)))
311            return FALSE;
312         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CHANGE_MODES | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
313         desc->targetpc = BRANCH_TARGET_DYNAMIC;
314         return TRUE;
315 
316      case 0x033:   /* RFCI */
317         if (!(ppc->cap & PPCCAP_4XX))
318            return FALSE;
319         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CHANGE_MODES | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
320         desc->targetpc = BRANCH_TARGET_DYNAMIC;
321         return TRUE;
322 
323      case 0x096:   /* ISYNC */
324         if (!(ppc->cap & (PPCCAP_VEA | PPCCAP_4XX)))
325            return FALSE;
326         return TRUE;
327 
328      case 0x210:   /* BCCTRx */
329         desc->gpr.used |= REGFLAG_CR(G_BI(op) / 4) | REGFLAG_CTR;
330         if (op & M_LK) desc->gpr.modified |= REGFLAG_LR;
331         if ((G_BO(op) & 0x14) == 0x14)
332            desc->flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
333         else
334            desc->flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
335         desc->targetpc = BRANCH_TARGET_DYNAMIC;
336         return TRUE;
337   }
338 
339   return FALSE;
340}
341 
342 
343/*-------------------------------------------------
344    describe_instruction_1f - build a
345    description of a single instruction in the
346    0x1f group
347-------------------------------------------------*/
348 
349static int describe_instruction_1f(powerpc_state *ppc, UINT32 op, opcode_desc *desc)
350{
351   UINT32 opswitch = (op >> 1) & 0x3ff;
352 
353   switch (opswitch)
354   {
355      case 0x009:   /* MULHDUx - 64-bit only */
356      case 0x015:   /* LDX - 64-bit only */
357      case 0x01b:   /* SLDx - 64-bit only */
358      case 0x035:   /* LDUX - 64-bit only */
359      case 0x03a:   /* CNTLZDx - 64-bit only */
360      case 0x044:   /* TD - 64-bit only */
361      case 0x049:   /* MULHDx - 64-bit only */
362      case 0x054:   /* LDARX - 64-bit only */
363      case 0x095:   /* STDX - 64-bit only */
364      case 0x0b5:   /* STDUX - 64-bit only */
365      case 0x0d6:   /* STDCX. - 64-bit only */
366      case 0x0e9:   /* MULLD - 64-bit only */
367      case 0x2e9:   /* MULLDO - 64-bit only */
368      case 0x155:   /* LWAX - 64-bit only */
369      case 0x175:   /* LWAUX - 64-bit only */
370      case 0x33a: /* SRADIx - 64-bit only */
371      case 0x33b: /* SRADIx - 64-bit only */
372      case 0x1b2:   /* SLBIE - 64-bit only */
373      case 0x1c9:   /* DIVDUx - 64-bit only */
374      case 0x3c9:   /* DIVDUOx - 64-bit only */
375      case 0x1e9:   /* DIVDx - 64-bit only */
376      case 0x3e9:   /* DIVDOx - 64-bit only */
377      case 0x1f2:   /* SLBIA - 64-bit only */
378      case 0x21b:   /* SRDx - 64-bit only */
379      case 0x31a:   /* SRADx - 64-bit only */
380      case 0x3da:   /* EXTSW - 64-bit only */
381         return FALSE;
382 
383      case 0x000:   /* CMP */
384      case 0x020:   /* CMPL */
385         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op)) | REGFLAG_XER;
386         desc->gpr.modified |= REGFLAG_CR(G_CRFD(op));
387         return TRUE;
388 
389      case 0x004:   /* TW */
390         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op));
391         desc->flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
392         return TRUE;
393 
394      case 0x008:   /* SUBFCx */
395      case 0x00a:   /* ADDCx */
396      case 0x00b:   /* MULHWUx */
397      case 0x028:   /* SUBFx */
398      case 0x04b:   /* MULHWx */
399      case 0x088:   /* SUBFEx */
400      case 0x08a:   /* ADDEx */
401      case 0x0c8:   /* SUBFZEx */
402      case 0x0ca:   /* ADDZEx */
403      case 0x0e8:   /* SUBFMEx */
404      case 0x0ea:   /* ADDMEx */
405      case 0x0eb:   /* MULLWx */
406      case 0x10a:   /* ADDx */
407      case 0x1cb:   /* DIVWUx */
408      case 0x1eb:   /* DIVWx */
409         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op));
410         desc->gpr.modified |= REGFLAG_R(G_RD(op));
411         if (op & M_RC)
412         {
413            desc->gpr.used |= REGFLAG_XER;
414            desc->gpr.modified |= REGFLAG_CR(0);
415         }
416         return TRUE;
417 
418      case 0x208:   /* SUBFCOx */
419      case 0x20a:   /* ADDCOx */
420      case 0x228:   /* SUBFOx */
421      case 0x288:   /* SUBFEOx */
422      case 0x28a:   /* ADDEOx */
423      case 0x2c8:   /* SUBFZEOx */
424      case 0x2ca:   /* ADDZEOx */
425      case 0x2e8:   /* SUBFMEOx */
426      case 0x2ea:   /* ADDMEOx */
427      case 0x2eb:   /* MULLWOx */
428      case 0x30a:   /* ADDOx */
429      case 0x3cb:   /* DIVWUOx */
430      case 0x3eb:   /* DIVWOx */
431         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op));
432         desc->gpr.modified |= REGFLAG_R(G_RD(op)) | REGFLAG_XER;
433         if (op & M_RC)
434         {
435            desc->gpr.used |= REGFLAG_XER;
436            desc->gpr.modified |= REGFLAG_CR(0);
437         }
438         return TRUE;
439 
440      case 0x013:   /* MFCR */
441         desc->gpr.used |= ((REGFLAG_CR(7) << 1) - 1) & ~(REGFLAG_CR(0) - 1);
442         desc->gpr.modified |= REGFLAG_R(G_RD(op));
443         return TRUE;
444 
445      case 0x136:   /* ECIWX */
446         if (!(ppc->cap & PPCCAP_VEA))
447            return FALSE;
448      case 0x014:   /* LWARX */
449      case 0x017:   /* LWZX */
450      case 0x057:   /* LBZX */
451      case 0x117:   /* LHZX */
452      case 0x157:   /* LHAX */
453      case 0x216:   /* LWBRX */
454      case 0x316:   /* LHBRX */
455         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
456         desc->gpr.modified |= REGFLAG_R(G_RD(op));
457         desc->flags |= OPFLAG_READS_MEMORY;
458         return TRUE;
459 
460      case 0x018:   /* SLWx */
461      case 0x01c:   /* ANDx */
462      case 0x03c:   /* ANDCx */
463      case 0x07c:   /* NORx */
464      case 0x11c:   /* EQVx */
465      case 0x13c:   /* XORx */
466      case 0x19c:   /* ORCx */
467      case 0x1bc:   /* ORx */
468      case 0x1dc:   /* NANDx */
469      case 0x218:   /* SRWx */
470      case 0x318:   /* SRAWx */
471         desc->gpr.used |= REGFLAG_RZ(G_RS(op)) | REGFLAG_R(G_RB(op));
472         desc->gpr.modified |= REGFLAG_R(G_RA(op));
473         return TRUE;
474 
475      case 0x01a:   /* CNTLZWx */
476      case 0x39a:   /* EXTSHx */
477      case 0x3ba:   /* EXTSBx */
478         desc->gpr.used |= REGFLAG_RZ(G_RS(op));
479         desc->gpr.modified |= REGFLAG_R(G_RA(op));
480         return TRUE;
481 
482      case 0x036:   /* DCBST */
483      case 0x056:   /* DCBF */
484      case 0x0f6:   /* DCBTST */
485      case 0x116:   /* DCBT */
486      case 0x2f6:   /* DCBA */
487      case 0x3d6:   /* ICBI */
488         if (!(ppc->cap & (PPCCAP_VEA | PPCCAP_4XX)))
489            return FALSE;
490         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
491         return TRUE;
492 
493      case 0x1d6:   /* DCBI */
494         if (!(ppc->cap & (PPCCAP_OEA | PPCCAP_4XX)))
495            return FALSE;
496         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
497         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
498         return TRUE;
499 
500      case 0x037:   /* LWZUX */
501      case 0x077:   /* LBZUX */
502      case 0x137:   /* LHZUX */
503      case 0x177:   /* LHAUX */
504         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op));
505         desc->gpr.modified |= REGFLAG_R(G_RD(op)) | REGFLAG_R(G_RA(op));
506         desc->flags |= OPFLAG_READS_MEMORY;
507         return TRUE;
508 
509      case 0x153:   /* MFSPR */
510         desc->gpr.modified |= REGFLAG_R(G_RD(op));
511         if (G_SPR(op) & 0x200)
512            desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
513         return TRUE;
514 
515      case 0x053:   /* MFMSR */
516         desc->gpr.modified |= REGFLAG_R(G_RD(op));
517         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
518         return TRUE;
519 
520      case 0x253:   /* MFSR */
521      case 0x293:   /* MFSRIN */
522         desc->gpr.modified |= REGFLAG_R(G_RD(op));
523         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
524         return TRUE;
525 
526      case 0x173:   /* MFTB */
527         if (!(ppc->cap & PPCCAP_VEA))
528            return FALSE;
529         desc->gpr.modified |= REGFLAG_R(G_RD(op));
530         return TRUE;
531 
532      case 0x068:   /* NEGx */
533         desc->gpr.used |= REGFLAG_R(G_RA(op));
534         desc->gpr.modified |= REGFLAG_R(G_RD(op));
535         if (op & M_RC)
536         {
537            desc->gpr.used |= REGFLAG_XER;
538            desc->gpr.modified |= REGFLAG_CR(0);
539         }
540         return TRUE;
541 
542      case 0x268:   /* NEGOx */
543         desc->gpr.used |= REGFLAG_R(G_RA(op));
544         desc->gpr.modified |= REGFLAG_R(G_RD(op)) | REGFLAG_XER;
545         if (op & M_RC)
546         {
547            desc->gpr.used |= REGFLAG_XER;
548            desc->gpr.modified |= REGFLAG_CR(0);
549         }
550         return TRUE;
551 
552      case 0x090:   /* MTCRF */
553         desc->gpr.used |= REGFLAG_R(G_RS(op));
554         if (G_CRM(op) & 0x01) desc->gpr.modified |= REGFLAG_CR(0);
555         if (G_CRM(op) & 0x02) desc->gpr.modified |= REGFLAG_CR(1);
556         if (G_CRM(op) & 0x04) desc->gpr.modified |= REGFLAG_CR(2);
557         if (G_CRM(op) & 0x08) desc->gpr.modified |= REGFLAG_CR(3);
558         if (G_CRM(op) & 0x10) desc->gpr.modified |= REGFLAG_CR(4);
559         if (G_CRM(op) & 0x20) desc->gpr.modified |= REGFLAG_CR(5);
560         if (G_CRM(op) & 0x40) desc->gpr.modified |= REGFLAG_CR(6);
561         if (G_CRM(op) & 0x80) desc->gpr.modified |= REGFLAG_CR(7);
562         return TRUE;
563 
564      case 0x092:   /* MTMSR */
565         desc->gpr.used |= REGFLAG_R(G_RS(op));
566         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_CHANGE_MODES | OPFLAG_END_SEQUENCE;
567         return TRUE;
568 
569      case 0x0d2:   /* MTSR */
570         if (!(ppc->cap & PPCCAP_OEA))
571            return FALSE;
572         desc->gpr.used |= REGFLAG_R(G_RS(op));
573         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
574         return TRUE;
575 
576      case 0x1d3:   /* MTSPR */
577         desc->gpr.used |= REGFLAG_R(G_RS(op));
578         if (G_SPR(op) & 0x200)
579            desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
580         return TRUE;
581 
582      case 0x1b6:   /* ECOWX */
583         if (!(ppc->cap & PPCCAP_VEA))
584            return FALSE;
585      case 0x096:   /* STWCX. */
586      case 0x097:   /* STWX */
587      case 0x0d7:   /* STBX */
588      case 0x197:   /* STHX */
589      case 0x296:   /* STWBRX */
590      case 0x396:   /* STHBRX */
591         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op)) | REGFLAG_R(G_RS(op));
592         desc->flags |= OPFLAG_WRITES_MEMORY;
593         return TRUE;
594 
595      case 0x0b7:   /* STWUX */
596      case 0x0f7:   /* STBUX */
597      case 0x1b7:   /* STHUX */
598         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op)) | REGFLAG_R(G_RS(op));
599         desc->gpr.modified |= REGFLAG_R(G_RA(op));
600         desc->flags |= OPFLAG_WRITES_MEMORY;
601         return TRUE;
602 
603      case 0x0f2:   /* MTSRIN */
604         if (!(ppc->cap & PPCCAP_OEA))
605            return FALSE;
606         desc->gpr.used |= REGFLAG_R(G_RS(op)) | REGFLAG_R(G_RB(op));
607         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
608         return TRUE;
609 
610      case 0x132:   /* TLBIE */
611         if (!(ppc->cap & PPCCAP_OEA))
612            return FALSE;
613         desc->gpr.used |= REGFLAG_R(G_RB(op));
614         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
615         return TRUE;
616 
617      case 0x172:   /* TLBIA */
618         if (!(ppc->cap & PPCCAP_OEA) || (ppc->cap & PPCCAP_603_MMU))
619            return FALSE;
620         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
621         return TRUE;
622 
623      case 0x3d2:   /* TLBLD */
624      case 0x3f2:   /* TLBLI */
625         if (!(ppc->cap & PPCCAP_603_MMU))
626            return FALSE;
627         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
628         return TRUE;
629 
630      case 0x200:   /* MCRXR */
631         desc->gpr.used |= REGFLAG_XER;
632         desc->gpr.modified |= REGFLAG_CR(G_CRFD(op));
633         return TRUE;
634 
635      case 0x215:   /* LSWX */
636         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op)) | REGFLAG_XER;
637         desc->gpr.modified |= ((REGFLAG_R(31) << 1) - 1) & ~(REGFLAG_R(0) - 1);
638         desc->flags |= OPFLAG_READS_MEMORY;
639         return TRUE;
640 
641      case 0x217:   /* LFSX */
642      case 0x257:   /* LFDX */
643         if (!(ppc->cap & PPCCAP_FPU))
644            return FALSE;
645         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
646         desc->fpr.modified |= REGFLAG_R(G_RD(op));
647         desc->flags |= OPFLAG_READS_MEMORY;
648         return TRUE;
649 
650      case 0x236:   /* TLBSYNC */
651         if (!(ppc->cap & PPCCAP_OEA))
652            return FALSE;
653         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
654         return TRUE;
655 
656      case 0x256:   /* SYNC */
657         return TRUE;
658 
659      case 0x356:   /* EIEIO */
660         if (!(ppc->cap & PPCCAP_VEA))
661            return FALSE;
662         return TRUE;
663 
664      case 0x237:   /* LFSUX */
665      case 0x277:   /* LFDUX */
666         if (!(ppc->cap & PPCCAP_FPU))
667            return FALSE;
668         desc->gpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op));
669         desc->gpr.modified |= REGFLAG_R(G_RA(op));
670         desc->fpr.modified |= REGFLAG_R(G_RD(op));
671         desc->flags |= OPFLAG_READS_MEMORY;
672         return TRUE;
673 
674      case 0x255:   /* LSWI */
675         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
676         desc->gpr.modified |= ((REGFLAG_R(31) << 1) - 1) & ~(REGFLAG_R(0) - 1);
677         desc->flags |= OPFLAG_READS_MEMORY;
678         return TRUE;
679 
680      case 0x295:   /* STSWX */
681      case 0x2d5:   /* STSWI */
682         desc->gpr.used |= (((REGFLAG_R(31) << 1) - 1) & ~(REGFLAG_R(0) - 1)) | REGFLAG_XER;
683         desc->flags |= OPFLAG_WRITES_MEMORY;
684         return TRUE;
685 
686      case 0x297:   /* STFSX */
687      case 0x2d7:   /* STFDX */
688      case 0x3d7:   /* STFIWX */
689         if (!(ppc->cap & PPCCAP_FPU))
690            return FALSE;
691         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
692         desc->fpr.used |= REGFLAG_R(G_RS(op));
693         desc->flags |= OPFLAG_WRITES_MEMORY;
694         return TRUE;
695 
696      case 0x2b7:   /* STFSUX */
697      case 0x2f7:   /* STFDUX */
698         if (!(ppc->cap & PPCCAP_FPU))
699            return FALSE;
700         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
701         desc->gpr.modified |= REGFLAG_RZ(G_RA(op));
702         desc->fpr.used |= REGFLAG_R(G_RS(op));
703         desc->flags |= OPFLAG_WRITES_MEMORY;
704         return TRUE;
705 
706      case 0x338:   /* SRAWIx */
707         desc->gpr.used |= REGFLAG_RZ(G_RS(op));
708         desc->gpr.modified |= REGFLAG_R(G_RA(op));
709         return TRUE;
710 
711      case 0x3f6:   /* DCBZ */
712         if (!(ppc->cap & (PPCCAP_VEA | PPCCAP_4XX)))
713            return FALSE;
714         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
715         desc->flags |= OPFLAG_WRITES_MEMORY;
716         return TRUE;
717 
718      case 0x106:   /* ICBT */
719      case 0x1c6:   /* DCCCI */
720      case 0x3c6:   /* ICCCI */
721         if (!(ppc->cap & PPCCAP_4XX))
722            return FALSE;
723         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
724         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
725         return TRUE;
726 
727      case 0x1e6:   /* DCREAD */
728      case 0x3e6:   /* ICREAD */
729         if (!(ppc->cap & PPCCAP_4XX))
730            return FALSE;
731         desc->gpr.used |= REGFLAG_RZ(G_RA(op)) | REGFLAG_R(G_RB(op));
732         desc->gpr.modified |= REGFLAG_R(G_RT(op));
733         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
734         return TRUE;
735 
736      case 0x143:   /* MFDCR */
737         if (!(ppc->cap & PPCCAP_4XX))
738            return FALSE;
739         desc->gpr.modified |= REGFLAG_R(G_RD(op));
740         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
741         return TRUE;
742 
743      case 0x1c3:   /* MTDCR */
744         if (!(ppc->cap & PPCCAP_4XX))
745            return FALSE;
746         desc->gpr.used |= REGFLAG_R(G_RS(op));
747         desc->flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
748         return TRUE;
749 
750      case 0x083:   /* WRTEE */
751         if (!(ppc->cap & PPCCAP_4XX))
752            return FALSE;
753         desc->gpr.used |= REGFLAG_R(G_RS(op));
754         desc->flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
755         return TRUE;
756 
757      case 0x0a3:   /* WRTEEI */
758         if (!(ppc->cap & PPCCAP_4XX))
759            return FALSE;
760         if (op & MSR_EE)
761            desc->flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
762         return TRUE;
763   }
764 
765   return FALSE;
766}
767 
768 
769/*-------------------------------------------------
770    describe_instruction_3b - build a
771    description of a single instruction in the
772    0x3b group
773-------------------------------------------------*/
774 
775static int describe_instruction_3b(powerpc_state *ppc, UINT32 op, opcode_desc *desc)
776{
777   UINT32 opswitch = (op >> 1) & 0x1f;
778 
779   if (!(ppc->cap & PPCCAP_FPU))
780      return FALSE;
781 
782   switch (opswitch)
783   {
784      case 0x12:   /* FDIVSx */
785      case 0x14:   /* FSUBSx */
786      case 0x15:   /* FADDSx */
787      case 0x19:   /* FMULSx */
788         desc->fpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op));
789         desc->fpr.modified |= REGFLAG_R(G_RD(op));
790         if (op & M_RC)
791         {
792            desc->gpr.used |= REGFLAG_XER;
793            desc->gpr.modified |= REGFLAG_CR(1);
794         }
795         return TRUE;
796 
797      case 0x16:   /* FSQRTSx */
798      case 0x18:   /* FRESx */
799         desc->fpr.used |= REGFLAG_R(G_RB(op));
800         desc->fpr.modified |= REGFLAG_R(G_RD(op));
801         if (op & M_RC)
802         {
803            desc->gpr.used |= REGFLAG_XER;
804            desc->gpr.modified |= REGFLAG_CR(1);
805         }
806         return TRUE;
807 
808      case 0x1c:   /* FMSUBSx */
809      case 0x1d:   /* FMADDSx */
810      case 0x1e:   /* FNMSUBSx */
811      case 0x1f:   /* FNMADDSx */
812         desc->fpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op)) | REGFLAG_R(G_REGC(op));
813         desc->fpr.modified |= REGFLAG_R(G_RD(op));
814         if (op & M_RC)
815         {
816            desc->gpr.used |= REGFLAG_XER;
817            desc->gpr.modified |= REGFLAG_CR(1);
818         }
819         return TRUE;
820   }
821 
822   return FALSE;
823}
824 
825 
826/*-------------------------------------------------
827    describe_instruction_3f - build a
828    description of a single instruction in the
829    0x3f group
830-------------------------------------------------*/
831 
832static int describe_instruction_3f(powerpc_state *ppc, UINT32 op, opcode_desc *desc)
833{
834   UINT32 opswitch = (op >> 1) & 0x3ff;
835 
836   if (!(ppc->cap & PPCCAP_FPU))
837      return FALSE;
838 
839   if (opswitch & 0x10)
840   {
841      opswitch &= 0x1f;
842      switch (opswitch)
843      {
844         case 0x12:   /* FDIVx */
845         case 0x14:   /* FSUBx */
846         case 0x15:   /* FADDx */
847         case 0x19:   /* FMULx */
848            desc->fpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op));
849            desc->fpr.modified |= REGFLAG_R(G_RD(op));
850            if (op & M_RC)
851            {
852               desc->gpr.used |= REGFLAG_XER;
853               desc->gpr.modified |= REGFLAG_CR(1);
854            }
855            return TRUE;
856 
857         case 0x16:   /* FSQRTx */
858         case 0x1a:   /* FSQRTEx */
859            desc->fpr.used |= REGFLAG_R(G_RB(op));
860            desc->fpr.modified |= REGFLAG_R(G_RD(op));
861            if (op & M_RC)
862            {
863               desc->gpr.used |= REGFLAG_XER;
864               desc->gpr.modified |= REGFLAG_CR(1);
865            }
866            return TRUE;
867 
868         case 0x17:   /* FSELx */
869         case 0x1c:   /* FMSUBx */
870         case 0x1d:   /* FMADDx */
871         case 0x1e:   /* FNMSUBx */
872         case 0x1f:   /* FNMADDx */
873            desc->fpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op)) | REGFLAG_R(G_REGC(op));
874            desc->fpr.modified |= REGFLAG_R(G_RD(op));
875            if (op & M_RC)
876            {
877               desc->gpr.used |= REGFLAG_XER;
878               desc->gpr.modified |= REGFLAG_CR(1);
879            }
880            return TRUE;
881      }
882   }
883   else
884   {
885      switch (opswitch)
886      {
887         case 0x32e:   /* FCTIDx - 64-bit only */
888         case 0x32f:   /* FCTIDZx - 64-bit only */
889         case 0x34e:   /* FCFIDx - 64-bit only */
890            return FALSE;
891 
892         case 0x000:   /* FCMPU */
893         case 0x020:   /* FCMPO */
894            desc->gpr.used |= REGFLAG_XER;
895            desc->fpr.used |= REGFLAG_R(G_RA(op)) | REGFLAG_R(G_RB(op));
896            desc->gpr.modified |= REGFLAG_CR(G_CRFD(op));
897            return TRUE;
898 
899         case 0x00c:   /* FRSPx */
900         case 0x00e:   /* FCTIWx */
901         case 0x00f:   /* FCTIWZx */
902         case 0x028:   /* FNEGx */
903         case 0x048:   /* FMRx */
904         case 0x088:   /* FNABSx */
905         case 0x108:   /* FABSx */
906            desc->fpr.used |= REGFLAG_R(G_RB(op));
907            desc->fpr.modified |= REGFLAG_R(G_RD(op));
908            if (op & M_RC)
909            {
910               desc->gpr.used |= REGFLAG_XER;
911               desc->gpr.modified |= REGFLAG_CR(1);
912            }
913            return TRUE;
914 
915         case 0x026:   /* MTFSB1x */
916         case 0x046:   /* MTFSB0x */
917            desc->fpr.modified |= REGFLAG_FPSCR;
918            return TRUE;
919 
920         case 0x040:   /* MCRFS */
921            desc->fpr.used |= REGFLAG_FPSCR;
922            desc->gpr.modified |= REGFLAG_CR(G_CRFD(op));
923            return TRUE;
924 
925         case 0x086:   /* MTFSFIx */
926            desc->fpr.modified |= REGFLAG_FPSCR;
927            return TRUE;
928 
929         case 0x247:   /* MFFSx */
930            desc->fpr.used |= REGFLAG_FPSCR;
931            desc->fpr.modified |= REGFLAG_R(G_RD(op));
932            return TRUE;
933 
934         case 0x2c7:   /* MTFSFx */
935            desc->fpr.used |= REGFLAG_R(G_RB(op));
936            desc->fpr.modified |= REGFLAG_FPSCR;
937            return TRUE;
938      }
939   }
940 
941   return FALSE;
942}
src/emu/cpu/drcumlsh.h
r2821r2822
132132#define UML_SETFMOD(block, mode)                     do { drcuml_block_append_1(block, DRCUML_OP_SETFMOD, 4, IF_ALWAYS,  mode); } while (0)
133133#define UML_GETFMOD(block, dst)                        do { drcuml_block_append_1(block, DRCUML_OP_GETFMOD, 4, IF_ALWAYS,  dst); } while (0)
134134#define UML_GETEXP(block, dst)                        do { drcuml_block_append_1(block, DRCUML_OP_GETEXP,  4, IF_ALWAYS,  dst); } while (0)
135#define UML_GETFLGS(block, dst, flags)                  do { drcuml_block_append_1(block, DRCUML_OP_GETFLGS, 4, flags,      dst); } while (0)
135136#define UML_SAVE(block, dst)                        do { drcuml_block_append_1(block, DRCUML_OP_SAVE,    4, IF_ALWAYS,  MEM(dst)); } while (0)
136137#define UML_RESTORE(block, src)                        do { drcuml_block_append_1(block, DRCUML_OP_RESTORE, 4, IF_ALWAYS,  MEM(src)); } while (0)
137138
138139
139140/* ----- 32-Bit Integer Operations ----- */
140#define UML_LOAD1U(block, dst, base, index)               do { drcuml_block_append_3(block, DRCUML_OP_LOAD1U,  4, IF_ALWAYS,  dst, MEM(base), index); } while (0)
141#define UML_LOAD1S(block, dst, base, index)               do { drcuml_block_append_3(block, DRCUML_OP_LOAD1S,  4, IF_ALWAYS,  dst, MEM(base), index); } while (0)
142#define UML_LOAD2U(block, dst, base, index)               do { drcuml_block_append_3(block, DRCUML_OP_LOAD2U,  4, IF_ALWAYS,  dst, MEM(base), index); } while (0)
143#define UML_LOAD2S(block, dst, base, index)               do { drcuml_block_append_3(block, DRCUML_OP_LOAD2S,  4, IF_ALWAYS,  dst, MEM(base), index); } while (0)
144#define UML_LOAD4(block, dst, base, index)               do { drcuml_block_append_3(block, DRCUML_OP_LOAD4U,  4, IF_ALWAYS,  dst, MEM(base), index); } while (0)
141#define UML_LOAD(block, dst, base, index, size)            do { drcuml_block_append_4(block, DRCUML_OP_LOAD,    4, IF_ALWAYS,  dst, MEM(base), index, IMM(DRCUML_SIZE_##size)); } while (0)
142#define UML_LOADS(block, dst, base, index, size)         do { drcuml_block_append_4(block, DRCUML_OP_LOADS,   4, IF_ALWAYS,  dst, MEM(base), index, IMM(DRCUML_SIZE_##size)); } while (0)
143#define UML_STORE(block, base, index, src1, size)         do { drcuml_block_append_4(block, DRCUML_OP_STORE,   4, IF_ALWAYS,  MEM(base), index, src1, IMM(DRCUML_SIZE_##size)); } while (0)
144#define UML_READ(block, dst, src1, spsize)               do { drcuml_block_append_3(block, DRCUML_OP_READ,    4, IF_ALWAYS,  dst, src1, IMM(DRCUML_SPSIZE_##spsize)); } while (0)
145#define UML_READM(block, dst, src1, mask, spsize)         do { drcuml_block_append_4(block, DRCUML_OP_READM,   4, IF_ALWAYS,  dst, src1, mask, IMM(DRCUML_SPSIZE_##spsize)); } while (0)
146#define UML_WRITE(block, dst, src1, spsize)               do { drcuml_block_append_3(block, DRCUML_OP_WRITE,   4, IF_ALWAYS,  dst, src1, IMM(DRCUML_SPSIZE_##spsize)); } while (0)
147#define UML_WRITEM(block, dst, src1, mask, spsize)         do { drcuml_block_append_4(block, DRCUML_OP_WRITEM,  4, IF_ALWAYS,  dst, src1, mask, IMM(DRCUML_SPSIZE_##spsize)); } while (0)
145148
146#define UML_STORE1(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_STORE1,  4, IF_ALWAYS,  MEM(base), index, src1); } while (0)
147#define UML_STORE2(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_STORE2,  4, IF_ALWAYS,  MEM(base), index, src1); } while (0)
148#define UML_STORE4(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_STORE4,  4, IF_ALWAYS,  MEM(base), index, src1); } while (0)
149#define UML_CARRY(block, src, bitnum)                  do { drcuml_block_append_2(block, DRCUML_OP_CARRY,   4, IF_ALWAYS,  src, bitnum); } while (0)
150#define UML_SETc(block, cond, dst)                     do { drcuml_block_append_1(block, DRCUML_OP_SET,     4, cond,       dst); } while (0)
149151
150#define UML_READ1U(block, dst, space, src1)               do { drcuml_block_append_3(block, DRCUML_OP_READ1U,  4, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
151#define UML_READ1S(block, dst, space, src1)               do { drcuml_block_append_3(block, DRCUML_OP_READ1S,  4, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
152#define UML_READ2U(block, dst, space, src1)               do { drcuml_block_append_3(block, DRCUML_OP_READ2U,  4, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
153#define UML_READ2S(block, dst, space, src1)               do { drcuml_block_append_3(block, DRCUML_OP_READ2S,  4, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
154#define UML_READ2M(block, dst, space, src1, mask)         do { drcuml_block_append_4(block, DRCUML_OP_READ2M,  4, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1, mask); } while (0)
155#define UML_READ4(block, dst, space, src1)               do { drcuml_block_append_3(block, DRCUML_OP_READ4U,  4, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
156#define UML_READ4M(block, dst, space, src1, mask)         do { drcuml_block_append_4(block, DRCUML_OP_READ4M,  4, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1, mask); } while (0)
157
158#define UML_WRITE1(block, space, dst, src1)               do { drcuml_block_append_3(block, DRCUML_OP_WRITE1,  4, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
159#define UML_WRITE2(block, space, dst, src1)               do { drcuml_block_append_3(block, DRCUML_OP_WRITE2,  4, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
160#define UML_WRIT2M(block, space, dst, mask, src1)         do { drcuml_block_append_4(block, DRCUML_OP_WRIT2M,  4, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, mask, src1); } while (0)
161#define UML_WRITE4(block, space, dst, src1)               do { drcuml_block_append_3(block, DRCUML_OP_WRITE4,  4, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
162#define UML_WRIT4M(block, space, dst, mask, src1)         do { drcuml_block_append_4(block, DRCUML_OP_WRIT4M,  4, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, mask, src1); } while (0)
163
164#define UML_FLAGS(block, dst, mask, table)               do { drcuml_block_append_3(block, DRCUML_OP_FLAGS,   4, IF_ALWAYS,  dst, IMM(mask), MEM(table)); } while (0)
165#define UML_SETC(block, src, bitnum)                  do { drcuml_block_append_2(block, DRCUML_OP_SETC,    4, IF_ALWAYS,  src, bitnum); } while (0)
166
167152#define UML_MOV(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_MOV,     4, IF_ALWAYS,  dst, src1); } while (0)
168153#define UML_MOVc(block, cond, dst, src1)               do { drcuml_block_append_2(block, DRCUML_OP_MOV,     4, cond,       dst, src1); } while (0)
154#define UML_SEXT(block, dst, src1, size)               do { drcuml_block_append_3(block, DRCUML_OP_SEXT,    4, IF_ALWAYS,  dst, src1, IMM(DRCUML_SIZE_##size)); } while (0)
169155
170#define UML_ZEXT1(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_ZEXT1,   4, IF_ALWAYS,  dst, src1); } while (0)
171#define UML_ZEXT2(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_ZEXT2,   4, IF_ALWAYS,  dst, src1); } while (0)
156#define UML_ROLAND(block, dst, src, shift, mask)         do { drcuml_block_append_4(block, DRCUML_OP_ROLAND,  4, IF_ALWAYS,  dst, src, shift, mask); } while (0)
157#define UML_ROLINS(block, dst, src, shift, mask)         do { drcuml_block_append_4(block, DRCUML_OP_ROLINS,  4, IF_ALWAYS,  dst, src, shift, mask); } while (0)
172158
173#define UML_SEXT1(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_SEXT1,   4, IF_ALWAYS,  dst, src1); } while (0)
174#define UML_SEXT2(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_SEXT2,   4, IF_ALWAYS,  dst, src1); } while (0)
175
176#define UML_XTRACT(block, dst, src, shift, mask)         do { drcuml_block_append_4(block, DRCUML_OP_XTRACT,  4, IF_ALWAYS,  dst, src, shift, mask); } while (0)
177#define UML_INSERT(block, dst, src, shift, mask)         do { drcuml_block_append_4(block, DRCUML_OP_INSERT,  4, IF_ALWAYS,  dst, src, shift, mask); } while (0)
178
179159#define UML_NEG(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_NEG,     4, FLAGS_NONE, dst, src1); } while (0)
180160#define UML_NEGf(block, dst, src1, flags)               do { drcuml_block_append_2(block, DRCUML_OP_NEG,     4, flags,      dst, src1); } while (0)
181161
r2821r2822
238218
239219
240220/* ----- 64-Bit Integer Operations ----- */
241#define UML_DLOAD1U(block, dst, base, index)            do { drcuml_block_append_3(block, DRCUML_OP_LOAD1U,  8, IF_ALWAYS,  dst, MEM(base), index); } while (0)
242#define UML_DLOAD1S(block, dst, base, index)            do { drcuml_block_append_3(block, DRCUML_OP_LOAD1S,  8, IF_ALWAYS,  dst, MEM(base), index); } while (0)
243#define UML_DLOAD2U(block, dst, base, index)            do { drcuml_block_append_3(block, DRCUML_OP_LOAD2U,  8, IF_ALWAYS,  dst, MEM(base), index); } while (0)
244#define UML_DLOAD2S(block, dst, base, index)            do { drcuml_block_append_3(block, DRCUML_OP_LOAD2S,  8, IF_ALWAYS,  dst, MEM(base), index); } while (0)
245#define UML_DLOAD4U(block, dst, base, index)            do { drcuml_block_append_3(block, DRCUML_OP_LOAD4U,  8, IF_ALWAYS,  dst, MEM(base), index); } while (0)
246#define UML_DLOAD4S(block, dst, base, index)            do { drcuml_block_append_3(block, DRCUML_OP_LOAD4S,  8, IF_ALWAYS,  dst, MEM(base), index); } while (0)
247#define UML_DLOAD8(block, dst, base, index)               do { drcuml_block_append_3(block, DRCUML_OP_LOAD8U,  8, IF_ALWAYS,  dst, MEM(base), index); } while (0)
221#define UML_DLOAD(block, dst, base, index, size)         do { drcuml_block_append_4(block, DRCUML_OP_LOAD,    8, IF_ALWAYS,  dst, MEM(base), index, IMM(DRCUML_SIZE_##size)); } while (0)
222#define UML_DLOADS(block, dst, base, index, size)         do { drcuml_block_append_4(block, DRCUML_OP_LOADS,   8, IF_ALWAYS,  dst, MEM(base), index, IMM(DRCUML_SIZE_##size)); } while (0)
223#define UML_DSTORE(block, base, index, src1, size)         do { drcuml_block_append_4(block, DRCUML_OP_STORE,   8, IF_ALWAYS,  MEM(base), index, src1, IMM(DRCUML_SIZE_##size)); } while (0)
224#define UML_DREAD(block, dst, src1, spsize)               do { drcuml_block_append_3(block, DRCUML_OP_READ,    8, IF_ALWAYS,  dst, src1, IMM(DRCUML_SPSIZE_##spsize)); } while (0)
225#define UML_DREADM(block, dst, src1, mask, spsize)         do { drcuml_block_append_4(block, DRCUML_OP_READM,   8, IF_ALWAYS,  dst, src1, mask, IMM(DRCUML_SPSIZE_##spsize)); } while (0)
226#define UML_DWRITE(block, dst, src1, spsize)            do { drcuml_block_append_3(block, DRCUML_OP_WRITE,   8, IF_ALWAYS,  dst, src1, IMM(DRCUML_SPSIZE_##spsize)); } while (0)
227#define UML_DWRITEM(block, dst, src1, mask, spsize)         do { drcuml_block_append_4(block, DRCUML_OP_WRITEM,  8, IF_ALWAYS,  dst, src1, mask, IMM(DRCUML_SPSIZE_##spsize)); } while (0)
248228
249#define UML_DSTORE1(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_STORE1,  8, IF_ALWAYS,  MEM(base), index, src1); } while (0)
250#define UML_DSTORE2(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_STORE2,  8, IF_ALWAYS,  MEM(base), index, src1); } while (0)
251#define UML_DSTORE4(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_STORE4,  8, IF_ALWAYS,  MEM(base), index, src1); } while (0)
252#define UML_DSTORE8(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_STORE8,  8, IF_ALWAYS,  MEM(base), index, src1); } while (0)
229#define UML_DCARRY(block, src, bitnum)                  do { drcuml_block_append_2(block, DRCUML_OP_CARRY,   8, IF_ALWAYS,  src, bitnum); } while (0)
230#define UML_DSETc(block, cond, dst)                     do { drcuml_block_append_1(block, DRCUML_OP_SET,     8, cond,       dst); } while (0)
253231
254#define UML_DREAD1U(block, dst, space, src1)            do { drcuml_block_append_3(block, DRCUML_OP_READ1U,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
255#define UML_DREAD1S(block, dst, space, src1)            do { drcuml_block_append_3(block, DRCUML_OP_READ1S,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
256#define UML_DREAD2U(block, dst, space, src1)            do { drcuml_block_append_3(block, DRCUML_OP_READ2U,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
257#define UML_DREAD2S(block, dst, space, src1)            do { drcuml_block_append_3(block, DRCUML_OP_READ2S,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
258#define UML_DREAD2M(block, dst, space, src1, mask)         do { drcuml_block_append_4(block, DRCUML_OP_READ2M,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1, mask); } while (0)
259#define UML_DREAD4U(block, dst, space, src1)            do { drcuml_block_append_3(block, DRCUML_OP_READ4U,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
260#define UML_DREAD4S(block, dst, space, src1)            do { drcuml_block_append_3(block, DRCUML_OP_READ4S,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
261#define UML_DREAD4M(block, dst, space, src1, mask)         do { drcuml_block_append_4(block, DRCUML_OP_READ4M,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1, mask); } while (0)
262#define UML_DREAD8(block, dst, space, src1)               do { drcuml_block_append_3(block, DRCUML_OP_READ8U,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
263#define UML_DREAD8M(block, dst, space, src1, mask)         do { drcuml_block_append_4(block, DRCUML_OP_READ8M,  8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1, mask); } while (0)
264
265#define UML_DWRITE1(block, space, dst, src1)            do { drcuml_block_append_3(block, DRCUML_OP_WRITE1,  8, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
266#define UML_DWRITE2(block, space, dst, src1)            do { drcuml_block_append_3(block, DRCUML_OP_WRITE2,  8, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
267#define UML_DWRIT2M(block, space, dst, mask, src1)         do { drcuml_block_append_4(block, DRCUML_OP_WRIT2M,  8, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, mask, src1); } while (0)
268#define UML_DWRITE4(block, space, dst, src1)            do { drcuml_block_append_3(block, DRCUML_OP_WRITE4,  8, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
269#define UML_DWRIT4M(block, space, dst, mask, src1)         do { drcuml_block_append_4(block, DRCUML_OP_WRIT4M,  8, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, mask, src1); } while (0)
270#define UML_DWRITE8(block, space, dst, src1)            do { drcuml_block_append_3(block, DRCUML_OP_WRITE8,  8, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
271#define UML_DWRIT8M(block, space, dst, mask, src1)         do { drcuml_block_append_4(block, DRCUML_OP_WRIT8M,  8, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, mask, src1); } while (0)
272
273#define UML_DFLAGS(block, dst, mask, table)               do { drcuml_block_append_3(block, DRCUML_OP_FLAGS,   8, IF_ALWAYS,  dst, IMM(mask), MEM(table)); } while (0)
274
275232#define UML_DMOV(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_MOV,     8, IF_ALWAYS,  dst, src1); } while (0)
276233#define UML_DMOVc(block, cond, dst, src1)               do { drcuml_block_append_2(block, DRCUML_OP_MOV,     8, cond,       dst, src1); } while (0)
234#define UML_DSEXT(block, dst, src1, size)               do { drcuml_block_append_3(block, DRCUML_OP_SEXT,    8, IF_ALWAYS,  dst, src1, IMM(DRCUML_SIZE_##size)); } while (0)
277235
278#define UML_DZEXT1(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_ZEXT1,   8, IF_ALWAYS,  dst, src1); } while (0)
279#define UML_DZEXT2(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_ZEXT2,   8, IF_ALWAYS,  dst, src1); } while (0)
280#define UML_DZEXT4(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_ZEXT4,   8, IF_ALWAYS,  dst, src1); } while (0)
236#define UML_DROLAND(block, dst, src, shift, mask)         do { drcuml_block_append_4(block, DRCUML_OP_ROLAND,  8, IF_ALWAYS,  dst, src, shift, mask); } while (0)
237#define UML_DROLINS(block, dst, src, shift, mask)         do { drcuml_block_append_4(block, DRCUML_OP_ROLINS,  8, IF_ALWAYS,  dst, src, shift, mask); } while (0)
281238
282#define UML_DSEXT1(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_SEXT1,   8, IF_ALWAYS,  dst, src1); } while (0)
283#define UML_DSEXT2(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_SEXT2,   8, IF_ALWAYS,  dst, src1); } while (0)
284#define UML_DSEXT4(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_SEXT4,   8, IF_ALWAYS,  dst, src1); } while (0)
285
286#define UML_DXTRACT(block, dst, src, shift, mask)         do { drcuml_block_append_4(block, DRCUML_OP_XTRACT,  8, IF_ALWAYS,  dst, src, shift, mask); } while (0)
287#define UML_DINSERT(block, dst, src, shift, mask)         do { drcuml_block_append_4(block, DRCUML_OP_INSERT,  8, IF_ALWAYS,  dst, src, shift, mask); } while (0)
288
289239#define UML_DNEG(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_NEG,     8, FLAGS_NONE, dst, src1); } while (0)
290240#define UML_DNEGf(block, dst, src1, flags)               do { drcuml_block_append_2(block, DRCUML_OP_NEG,     8, flags,      dst, src1); } while (0)
291241
r2821r2822
348298#define UML_FSLOAD(block, dst, base, index)               do { drcuml_block_append_3(block, DRCUML_OP_FLOAD,   4, IF_ALWAYS,  dst, MEM(base), index); } while (0)
349299#define UML_FSSTORE(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_FSTORE,  4, IF_ALWAYS,  MEM(base), index, src1); } while (0)
350300
351#define UML_FSREAD(block, dst, space, src1)               do { drcuml_block_append_3(block, DRCUML_OP_FREAD,   4, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
352#define UML_FSWRITE(block, space, dst, src1)            do { drcuml_block_append_3(block, DRCUML_OP_FWRITE,  4, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
301#define UML_FSREAD(block, dst, src1, space)               do { drcuml_block_append_3(block, DRCUML_OP_FREAD,   4, IF_ALWAYS,  dst, src1, IMM(ADDRESS_SPACE_##space)); } while (0)
302#define UML_FSWRITE(block, dst, src1, space)            do { drcuml_block_append_3(block, DRCUML_OP_FWRITE,  4, IF_ALWAYS,  dst, src1, IMM(ADDRESS_SPACE_##space)); } while (0)
353303
354304#define UML_FSMOV(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_FMOV,    4, IF_ALWAYS,  dst, src1); } while (0)
355305#define UML_FSMOVc(block, cond, dst, src1)               do { drcuml_block_append_2(block, DRCUML_OP_FMOV,    4, cond,       dst, src1); } while (0)
356306
357#define UML_FSTOI4(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4,   4, IF_ALWAYS,  dst, src1); } while (0)
358#define UML_FSTOI4T(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4T,  4, IF_ALWAYS,  dst, src1); } while (0)
359#define UML_FSTOI4R(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4R,  4, IF_ALWAYS,  dst, src1); } while (0)
360#define UML_FSTOI4C(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4C,  4, IF_ALWAYS,  dst, src1); } while (0)
361#define UML_FSTOI4F(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4F,  4, IF_ALWAYS,  dst, src1); } while (0)
362#define UML_FSTOI8(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8,   4, IF_ALWAYS,  dst, src1); } while (0)
363#define UML_FSTOI8T(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8T,  4, IF_ALWAYS,  dst, src1); } while (0)
364#define UML_FSTOI8R(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8R,  4, IF_ALWAYS,  dst, src1); } while (0)
365#define UML_FSTOI8C(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8C,  4, IF_ALWAYS,  dst, src1); } while (0)
366#define UML_FSTOI8F(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8F,  4, IF_ALWAYS,  dst, src1); } while (0)
307#define UML_FSTOINT(block, dst, src1, size, round)         do { drcuml_block_append_4(block, DRCUML_OP_FTOINT,  4, IF_ALWAYS,  dst, src1, IMM(DRCUML_SIZE_##size), IMM(DRCUML_FMOD_##round)); } while (0)
308#define UML_FSFRINT(block, dst, src1, size)               do { drcuml_block_append_3(block, DRCUML_OP_FFRINT,  4, IF_ALWAYS,  dst, src1, IMM(DRCUML_SIZE_##size)); } while (0)
309#define UML_FSFRFLT(block, dst, src1, size)               do { drcuml_block_append_3(block, DRCUML_OP_FFRFLT,  4, IF_ALWAYS,  dst, src1, IMM(DRCUML_SIZE_##size)); } while (0)
367310
368#define UML_FSFRFD(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FFRFD,   4, IF_ALWAYS,  dst, src1); } while (0)
369#define UML_FSFRI4(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FFRI4,   4, IF_ALWAYS,  dst, src1); } while (0)
370#define UML_FSFRI8(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FFRI8,   4, IF_ALWAYS,  dst, src1); } while (0)
371
372311#define UML_FSADD(block, dst, src1, src2)               do { drcuml_block_append_3(block, DRCUML_OP_FADD,    4, FLAGS_NONE, dst, src1, src2); } while (0)
373312#define UML_FSSUB(block, dst, src1, src2)               do { drcuml_block_append_3(block, DRCUML_OP_FSUB,    4, FLAGS_NONE, dst, src1, src2); } while (0)
374313#define UML_FSCMP(block, src1, src2)                  do { drcuml_block_append_2(block, DRCUML_OP_FCMP,    4, FLAGS_ALLF, src1, src2); } while (0)
r2821r2822
385324#define UML_FDLOAD(block, dst, base, index)               do { drcuml_block_append_3(block, DRCUML_OP_FLOAD,   8, IF_ALWAYS,  dst, MEM(base), index); } while (0)
386325#define UML_FDSTORE(block, base, index, src1)            do { drcuml_block_append_3(block, DRCUML_OP_FSTORE,  8, IF_ALWAYS,  MEM(base), index, src1); } while (0)
387326
388#define UML_FDREAD(block, dst, space, src1)               do { drcuml_block_append_3(block, DRCUML_OP_FREAD,   8, IF_ALWAYS,  dst, IMM(ADDRESS_SPACE_##space), src1); } while (0)
389#define UML_FDWRITE(block, space, dst, src1)            do { drcuml_block_append_3(block, DRCUML_OP_FWRITE,  8, IF_ALWAYS,  IMM(ADDRESS_SPACE_##space), dst, src1); } while (0)
327#define UML_FDREAD(block, dst, src1, space)               do { drcuml_block_append_3(block, DRCUML_OP_FREAD,   8, IF_ALWAYS,  dst, src1, IMM(ADDRESS_SPACE_##space)); } while (0)
328#define UML_FDWRITE(block, dst, src1, space)            do { drcuml_block_append_3(block, DRCUML_OP_FWRITE,  8, IF_ALWAYS,  dst, src1, IMM(ADDRESS_SPACE_##space)); } while (0)
390329
391330#define UML_FDMOV(block, dst, src1)                     do { drcuml_block_append_2(block, DRCUML_OP_FMOV,    8, IF_ALWAYS,  dst, src1); } while (0)
392331#define UML_FDMOVc(block, cond, dst, src1)               do { drcuml_block_append_2(block, DRCUML_OP_FMOV,    8, cond,       dst, src1); } while (0)
393332
394#define UML_FDTOI4(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4,   8, IF_ALWAYS,  dst, src1); } while (0)
395#define UML_FDTOI4T(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4T,  8, IF_ALWAYS,  dst, src1); } while (0)
396#define UML_FDTOI4R(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4R,  8, IF_ALWAYS,  dst, src1); } while (0)
397#define UML_FDTOI4C(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4C,  8, IF_ALWAYS,  dst, src1); } while (0)
398#define UML_FDTOI4F(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI4F,  8, IF_ALWAYS,  dst, src1); } while (0)
399#define UML_FDTOI8(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8,   8, IF_ALWAYS,  dst, src1); } while (0)
400#define UML_FDTOI8T(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8T,  8, IF_ALWAYS,  dst, src1); } while (0)
401#define UML_FDTOI8R(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8R,  8, IF_ALWAYS,  dst, src1); } while (0)
402#define UML_FDTOI8C(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8C,  8, IF_ALWAYS,  dst, src1); } while (0)
403#define UML_FDTOI8F(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FTOI8F,  8, IF_ALWAYS,  dst, src1); } while (0)
333#define UML_FDTOINT(block, dst, src1, size, round)         do { drcuml_block_append_4(block, DRCUML_OP_FTOINT,  8, IF_ALWAYS,  dst, src1, IMM(DRCUML_SIZE_##size), IMM(DRCUML_FMOD_##round)); } while (0)
334#define UML_FDFRINT(block, dst, src1, size)               do { drcuml_block_append_3(block, DRCUML_OP_FFRINT,  8, IF_ALWAYS,  dst, src1, IMM(DRCUML_SIZE_##size)); } while (0)
335#define UML_FDFRFLT(block, dst, src1, size)               do { drcuml_block_append_3(block, DRCUML_OP_FFRFLT,  8, IF_ALWAYS,  dst, src1, IMM(DRCUML_SIZE_##size)); } while (0)
404336
405#define UML_FDFRFS(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FFRFS,   8, IF_ALWAYS,  dst, src1); } while (0)
406#define UML_FDFRI4(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FFRI4,   8, IF_ALWAYS,  dst, src1); } while (0)
407#define UML_FDFRI8(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FFRI8,   8, IF_ALWAYS,  dst, src1); } while (0)
337#define UML_FDRNDS(block, dst, src1)                  do { drcuml_block_append_2(block, DRCUML_OP_FRNDS,   8, FLAGS_NONE, dst, src1); } while (0)
408338
409339#define UML_FDADD(block, dst, src1, src2)               do { drcuml_block_append_3(block, DRCUML_OP_FADD,    8, FLAGS_NONE, dst, src1, src2); } while (0)
410340#define UML_FDSUB(block, dst, src1, src2)               do { drcuml_block_append_3(block, DRCUML_OP_FSUB,    8, FLAGS_NONE, dst, src1, src2); } while (0)
src/emu/cpu/mips/mdrc64.c
r2821r2822
1/***************************************************************************
2
3    mdrc64.c
4
5    x64 MIPS III recompiler.
6
7    Copyright Aaron Giles
8    Released for general use under the MAME license
9    Visit http://mamedev.org for licensing and usage restrictions.
10
11****************************************************************************
12
13    Conventions/rules:
14
15        * Instructions are grouped into sequences by mips3fe; each
16          sequence of instructions is guaranteed to not contain any
17          branches to any instructions within the sequence apart from
18          the first.
19
20        * Because of the above rule, assumptions are made during the
21          execution of a sequence in order to optimize the generated
22          code.
23
24        * Because some state may be live and not flushed to memory at
25          the time an exception is generated, all exception-generating
26          instructions must jump to stub code that is appended to each
27          group of instructions which cleans up live registers before
28          running the exception code.
29
30        * Page faults are trickier because they are detected in a
31          subroutine. In order to handle this, special markers are added
32          to the code consisting of one qword EXCEPTION_ADDRESS_COOKIE
33          followed by the return address of the call. When a page fault
34          needs to be generated, the common code scans forward from
35          the return address for this cookie/address pair and jumps to
36          the code immediately following.
37
38        * Convention: jumps to non-constant addresses have their target
39          PC stored at [sp+SPOFFS_NEXTPC]
40
41****************************************************************************
42
43    Future improvements:
44        * problem:
45            lui  r3,$b000
46            lw   r3,$100(r3)
47          if exception happens, then r3 is trashed
48
49        * register allocator can use non-volatile registers if the
50            lifetime is only for this one instruction (only for
51            registers where (gpr.used & ~gpr.modified)
52
53        * spec says if registers aren't sign-extended, then 32-bit ops have
54            undefined results; this can simplify our code
55
56        * track which results are 32-bit sign extended versus 64-bit and
57            only promote when necessary
58
59        * register aliasing - move from one to another either doesn't do
60            anything and tracks both, or else shifts ownership to new
61            target
62
63        * generic drc:
64            * common code to load registers prior to instruction
65                - each register has a callback that generates the load
66            * generate code
67            * common code to write registers afterwards
68            * common register allocation routines (64 integer, 64 FPU)
69            * common OOB mechanism
70            * common self-mod code detection (via write bitmask)
71            * common code validation routines
72
73****************************************************************************
74
75    Temporary stack usage:
76        [esp+32].b  = storage for CL in LWL/LWR/SWL/SWR
77        [esp+36].l  = storage for new target PC in JR/JALR
78
79***************************************************************************/
80
81#include "mips3fe.h"
82#include "deprecat.h"
83
84
85/***************************************************************************
86    DEBUGGING
87***************************************************************************/
88
89#define DISABLE_FIXED_RAM_LOAD         (0)
90#define DISABLE_FIXED_RAM_STORE         (0)
91#define FLUSH_AFTER_EACH_INSTRUCTION   (0)
92#define PRINTF_EXCEPTIONS            (0)
93#define PROBE_ADDRESS               (0)
94#define LOG_HOTSPOTS               (0)
95
96
97
98/***************************************************************************
99    CONSTANTS
100***************************************************************************/
101
102/* extra "conditions" used to augment the basic conditions for OOB handlers */
103#define COND_NONE                  16
104#define COND_NO_JUMP               17
105
106/* 64-bit cookie that is scanned for during exception processing */
107#define EXCEPTION_ADDRESS_COOKIE      U64(0xcc90cc90cc90cc90)
108
109/* append_readwrite flags */
110#define ARW_READ                  0x0000
111#define ARW_WRITE                  0x0001
112#define ARW_UNSIGNED               0x0000
113#define ARW_SIGNED                  0x0002
114#define ARW_MASKED                  0x0004
115#define ARW_CACHED                  0x0008
116#define ARW_UNCACHED               0x0010
117
118/* compiler_register_allocate flags */
119#define ALLOC_SRC                  0x0001
120#define ALLOC_DST                  0x0002
121#define ALLOC_DIRTY                  0x0004
122
123/* x86 register tracking flags */
124#define X86REG_LIVE                  0x80      /* register is live and contains something */
125#define X86REG_MIPSMASK               0x3f      /* low 6 bits indicate which MIPS register we hold */
126
127/* MIPS register tracking flags */
128#define MIPSREG_CONSTANT            0x8000      /* register is constant; low 10 bits select which one */
129#define MIPSREG_DIRTY               0x4000      /* register has been modified and needs to be flushed */
130#define MIPSREG_LIVE               0x2000      /* register is live in an x86 register */
131#define MIPSREG_X86MASK               0x000f      /* low 4 bits indicate which x86 register holds us */
132
133
134
135/***************************************************************************
136    MACROS
137***************************************************************************/
138
139#define SPOFFS_SAVECL         32
140#define SPOFFS_NEXTPC         36
141
142#define REGADDR(reg)         MDRC(&mips3.core->r[reg])
143#define HIADDR               MDRC(&mips3.core->r[REG_HI])
144#define LOADDR               MDRC(&mips3.core->r[REG_LO])
145#define CPR0ADDR(reg)         MDRC(&mips3.core->cpr[0][reg])
146#define CCR0ADDR(reg)         MDRC(&mips3.core->ccr[0][reg])
147#define CPR1ADDR(reg)         MDRC(&mips3.core->cpr[1][reg])
148#define CCR1ADDR(reg)         MDRC(&mips3.core->ccr[1][reg])
149#define CPR2ADDR(reg)         MDRC(&mips3.core->cpr[2][reg])
150#define CCR2ADDR(reg)         MDRC(&mips3.core->ccr[2][reg])
151#define FPR32(reg)            (IS_FR0 ? &((float *)&mips3.core->cpr[1][0])[reg] : (float *)&mips3.core->cpr[1][reg])
152#define FPR32ADDR(reg)         MDRC(FPR32(reg))
153#define FPR64(reg)            (IS_FR0 ? (double *)&mips3.core->cpr[1][(reg)/2] : (double *)&mips3.core->cpr[1][reg])
154#define FPR64ADDR(reg)         MDRC(FPR64(reg))
155#define CF1ADDR(which)         MDRC(&mips3.core->cf[1][(mips3.core->flavor < MIPS3_TYPE_MIPS_IV) ? 0 : (which)])
156#define PCADDR               MDRC(&mips3.core->pc)
157#define ICOUNTADDR            MDRC(&mips3.core->icount)
158#define COREADDR            MDRC(mips3.core)
159
160/* macros for querying/accessing the tracking flags */
161#define ISCONST(x)            (((x) & MIPSREG_CONSTANT) != 0)
162#define ISDIRTY(x)            (((x) & MIPSREG_DIRTY) != 0)
163#define ISLIVE(x)            (((x) & MIPSREG_LIVE) != 0)
164#define CONSTVAL(x)            ((INT32)((x) >> 32))
165#define X86REG(x)            ((x) & MIPSREG_X86MASK)
166
167/* macro for defining a small positivec constant inline */
168#define MAKE_CONST(x)         (MIPSREG_CONSTANT | ((INT64)(x) << 32))
169#define MAKE_DESTREG(x)         (MIPSREG_DIRTY | ((x) & MIPSREG_X86MASK))
170
171
172
173/***************************************************************************
174    TYPEDEFS
175***************************************************************************/
176
177typedef struct _readwrite_handlers readwrite_handlers;
178struct _readwrite_handlers
179{
180   x86code *      read_byte_signed;
181   x86code *      read_byte_unsigned;
182   x86code *      read_half_signed;
183   x86code *      read_half_unsigned;
184   x86code *      read_word_signed;
185   x86code *      read_word_unsigned;
186   x86code *      read_word_masked;
187   x86code *      read_double;
188   x86code *      read_double_masked;
189   x86code *      write_byte;
190   x86code *      write_half;
191   x86code *      write_word;
192   x86code *      write_word_masked;
193   x86code *      write_double;
194   x86code *      write_double_masked;
195};
196
197
198typedef INT64       mipsreg_state;
199typedef UINT8      x86reg_state;
200
201
202typedef struct _compiler_state compiler_state;
203struct _compiler_state
204{
205   UINT32         cycles;               /* accumulated cycles */
206   x86reg_state   x86regs[REG_MAX];      /* tracking what is in the x86 registers */
207   mipsreg_state   mipsregs[35];         /* tracking what is in the MIPS registers */
208};
209
210
211typedef struct _oob_handler oob_handler;
212
213typedef void (*oob_callback_func)(drc_core *drc, oob_handler *oob, void *param);
214
215struct _oob_handler
216{
217   oob_callback_func      callback;         /* pointer to callback function */
218   void *            param;            /* callback parameter */
219   const opcode_desc *   desc;            /* pointer to description of relevant instruction */
220   emit_link         link;            /* link to source of the branch */
221   compiler_state      compiler;         /* state of the compiler at this time */
222};
223
224
225struct _mips3drc_data
226{
227   /* misc data */
228   UINT64            abs64mask[2];
229   UINT32            abs32mask[4];
230
231   /* C functions */
232   x86code *         activecpu_gettotalcycles;
233   x86code *         mips3com_update_cycle_counting;
234   x86code *         mips3com_tlbr;
235   x86code *         mips3com_tlbwi;
236   x86code *         mips3com_tlbwr;
237   x86code *         mips3com_tlbp;
238
239   /* internal functions */
240   x86code *         generate_interrupt_exception;
241   x86code *         generate_cop_exception;
242   x86code *         generate_overflow_exception;
243   x86code *         generate_invalidop_exception;
244   x86code *         generate_syscall_exception;
245   x86code *         generate_break_exception;
246   x86code *         generate_trap_exception;
247   x86code *         generate_tlbload_exception;
248   x86code *         generate_tlbstore_exception;
249   x86code *         handle_pc_tlb_mismatch;
250   x86code *         find_exception_handler;
251   x86code *         explode_ccr31;
252   x86code *         recover_ccr31;
253
254   /* read/write handlers */
255   readwrite_handlers    general;
256   readwrite_handlers    cached;
257   readwrite_handlers    uncached;
258
259   /* out of bounds handlers */
260   oob_handler         ooblist[COMPILE_MAX_INSTRUCTIONS*2];
261   int               oobcount;
262
263   /* C functions */
264   x86code *         execute_c_version;
265
266   /* hotspot tracking */
267#if LOG_HOTSPOTS
268   struct
269   {
270      offs_t         pc;
271      UINT32         opcode;
272      UINT64         count;
273   } hotspot[100000];
274   int               next_hotspot;
275#endif
276};
277
278
279
280/***************************************************************************
281    FUNCTION PROTOTYPES
282***************************************************************************/
283
284static void drc_reset_callback(drc_core *drc);
285static void drc_recompile_callback(drc_core *drc);
286static void drc_entrygen_callback(drc_core *drc);
287
288static void compile_one(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
289
290static void oob_exception_cleanup(drc_core *drc, oob_handler *oob, void *param);
291static void oob_interrupt_cleanup(drc_core *drc, oob_handler *oob, void *param);
292
293static void compiler_register_set_constant(compiler_state *compiler, UINT8 mipsreg, UINT64 constval);
294static mipsreg_state compiler_register_allocate(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 mipsreg, UINT8 flags);
295static void compiler_register_flush(drc_core *drc, compiler_state *compiler, UINT8 mipsreg, int free);
296static void compiler_register_flush_all(drc_core *drc, compiler_state *compiler);
297
298static void probe_printf(void);
299
300static void generate_read_write_handlers(drc_core *drc, readwrite_handlers *handlers, const char *type, UINT8 flags);
301static void append_generate_exception(drc_core *drc, UINT8 exception);
302static void append_readwrite_and_translate(drc_core *drc, int size, UINT8 flags, UINT32 ptroffs);
303static void append_handle_pc_tlb_mismatch(drc_core *drc);
304static void append_find_exception_handler(drc_core *drc);
305static void append_explode_ccr31(drc_core *drc);
306static void append_recover_ccr31(drc_core *drc);
307static void append_check_interrupts(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
308//static void append_check_sw_interrupts(drc_core *drc, int inline_generate);
309
310static void emit_update_cycles_pc_and_flush(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, offs_t destpc);
311
312static int compile_instruction(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
313static int compile_special(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
314static int compile_regimm(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
315static int compile_idt(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
316static int compile_cop0(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
317static int compile_cop1(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
318static int compile_cop1x(drc_core *drc, compiler_state *compiler, const opcode_desc *desc);
319
320static int compile_shift(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int shift_type, int shift_variable);
321static int compile_dshift(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int shift_type, int shift_variable, int shift_const_plus32);
322static int compile_movzn(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_movn);
323static int compile_trapcc(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int condition, int immediate);
324static int compile_branchcc(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int condition);
325static int compile_branchcz(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int condition, int link);
326static int compile_add(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int suppress_exceptions, int immediate);
327static int compile_dadd(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int suppress_exceptions, int immediate);
328static int compile_sub(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int suppress_exceptions);
329static int compile_dsub(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int suppress_exceptions);
330static int compile_mult(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned);
331static int compile_dmult(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned);
332static int compile_div(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned);
333static int compile_ddiv(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned);
334static int compile_logical(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int operation, int immediate);
335static int compile_slt(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned, int immediate);
336static int compile_load(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, int is_unsigned);
337static int compile_load_cop(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, void *dest);
338static int compile_loadx_cop(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, void *dest);
339static int compile_load_word_partial(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_right);
340static int compile_load_double_partial(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_right);
341static int compile_store(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size);
342static int compile_store_cop(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, void *src);
343static int compile_storex_cop(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, void *src);
344static int compile_store_word_partial(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_right);
345static int compile_store_double_partial(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_right);
346
347
348
349/***************************************************************************
350    PRIVATE GLOBAL VARIABLES
351***************************************************************************/
352
353static const UINT8 nvreg[] = { REG_NV0, REG_NV1, REG_NV2, REG_NV3, REG_NV4, REG_NV5, REG_NV6 };
354
355static const char *const x86regname[] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15"};
356
357
358
359/***************************************************************************
360    INLINE FUNCTIONS
361***************************************************************************/
362
363/*-------------------------------------------------
364    oob_request_callback - request an out-of-
365    bounds callback for later
366-------------------------------------------------*/
367
368INLINE void oob_request_callback(drc_core *drc, UINT8 condition, oob_callback_func callback, const compiler_state *compiler, const opcode_desc *desc, void *param)
369{
370   oob_handler *oob = &mips3.drcdata->ooblist[mips3.drcdata->oobcount++];
371
372   /* fill in the next handler */
373   oob->callback = callback;
374   oob->desc = desc;
375   oob->compiler = *compiler;
376   oob->param = param;
377
378   /* emit an appropriate jump */
379   if (condition == COND_NO_JUMP)
380   {
381      oob->link.size = 0;
382      oob->link.target = drc->cache_top;
383   }
384   else if (condition == COND_NONE)
385      emit_jmp_near_link(DRCTOP, &oob->link);                                    // jmp  <target>
386   else
387      emit_jcc_near_link(DRCTOP, condition, &oob->link);                           // jcc  <target>
388}
389
390
391/*-------------------------------------------------
392    compiler_state_reset - reset the compiler
393    state
394-------------------------------------------------*/
395
396INLINE void compiler_state_reset(compiler_state *compiler)
397{
398   memset(compiler, 0, sizeof(*compiler));
399   compiler_register_set_constant(compiler, 0, 0);
400}
401
402
403
404/***************************************************************************
405    CORE RECOMPILER SYSTEMS
406***************************************************************************/
407
408/*-------------------------------------------------
409    mips3drc_init - initialize the drc-specific
410    state
411-------------------------------------------------*/
412
413static void mips3drc_init(void)
414{
415   drc_config drconfig;
416
417   /* fill in the config */
418   memset(&drconfig, 0, sizeof(drconfig));
419   drconfig.cache_base       = mips3.cache;
420   drconfig.cache_size       = CACHE_SIZE;
421   drconfig.max_instructions = (512 + 128) / 4;
422   drconfig.address_bits     = 32;
423   drconfig.lsbs_to_ignore   = 2;
424   drconfig.baseptr         = &mips3.core->r[17];
425   drconfig.pcptr            = (UINT32 *)&mips3.core->pc;
426   drconfig.cb_reset         = drc_reset_callback;
427   drconfig.cb_recompile     = drc_recompile_callback;
428   drconfig.cb_entrygen      = drc_entrygen_callback;
429
430   /* initialize the compiler */
431   mips3.drc = drc_init(cpu_getactivecpu(), &drconfig);
432   mips3.drcoptions = MIPS3DRC_FASTEST_OPTIONS;
433
434   /* allocate our data out of the cache */
435   mips3.drcdata = drc_alloc(mips3.drc, sizeof(*mips3.drcdata) + 16);
436   mips3.drcdata = (mips3drc_data *)((((FPTR)mips3.drcdata + 15) >> 4) << 4);
437   memset(mips3.drcdata, 0, sizeof(*mips3.drcdata));
438
439   /* set up constants */
440   mips3.drcdata->abs64mask[0] = U64(0x7fffffffffffffff);
441   mips3.drcdata->abs32mask[0] = 0x7fffffff;
442
443   /* get pointers to C functions */
444   mips3.drcdata->activecpu_gettotalcycles = (x86code *)activecpu_gettotalcycles;
445   mips3.drcdata->mips3com_update_cycle_counting = (x86code *)mips3com_update_cycle_counting;
446   mips3.drcdata->mips3com_tlbr = (x86code *)mips3com_tlbr;
447   mips3.drcdata->mips3com_tlbwi = (x86code *)mips3com_tlbwi;
448   mips3.drcdata->mips3com_tlbwr = (x86code *)mips3com_tlbwr;
449   mips3.drcdata->mips3com_tlbp = (x86code *)mips3com_tlbp;
450
451#if COMPARE_AGAINST_C
452   mips3.drcdata->execute_c_version = (x86code *)execute_c_version;
453#endif
454}
455
456
457/*-------------------------------------------------
458    mips3drc_exit - clean up the drc-specific
459    state
460-------------------------------------------------*/
461
462static void mips3drc_exit(void)
463{
464   printf("Final code size = %d\n", (int)(mips3.drc->cache_top - mips3.drc->cache_base));
465#if LOG_HOTSPOTS
466   /* print top hotspots */
467   {
468      int maxspot = 0;
469      int hotnum;
470      int count;
471
472      for (count = 0; count < 10; count++)
473      {
474         for (hotnum = 1; hotnum < mips3.drcdata->next_hotspot; hotnum++)
475            if (mips3.drcdata->hotspot[hotnum].count > mips3.drcdata->hotspot[maxspot].count)
476               maxspot = hotnum;
477         printf("%08X%08X hits: add_speedup(0x%08X, 0x%08X);\n",
478               (UINT32)(mips3.drcdata->hotspot[maxspot].count >> 32),
479               (UINT32)mips3.drcdata->hotspot[maxspot].count,
480               mips3.drcdata->hotspot[maxspot].pc,
481               mips3.drcdata->hotspot[maxspot].opcode);
482         mips3.drcdata->hotspot[maxspot].count = 0;
483      }
484   }
485#endif
486   drc_exit(mips3.drc);
487}
488
489
490
491/***************************************************************************
492    RECOMPILER CALLBACKS
493***************************************************************************/
494
495/*------------------------------------------------------------------
496    drc_reset_callback
497------------------------------------------------------------------*/
498
499static void drc_reset_callback(drc_core *drc)
500{
501   if (LOG_CODE)
502   {
503      x86log_disasm_code_range(mips3.log, "entry_point:", (x86code *)drc->entry_point, drc->exit_point);
504      x86log_disasm_code_range(mips3.log, "exit_point:", drc->exit_point, drc->recompile);
505      x86log_disasm_code_range(mips3.log, "recompile:", drc->recompile, drc->dispatch);
506      x86log_disasm_code_range(mips3.log, "dispatch:", drc->dispatch, drc->flush);
507      x86log_disasm_code_range(mips3.log, "flush:", drc->flush, drc->cache_top);
508   }
509
510   mips3.drcdata->generate_interrupt_exception = drc->cache_top;
511   append_generate_exception(drc, EXCEPTION_INTERRUPT);
512   if (LOG_CODE)
513      x86log_disasm_code_range(mips3.log, "generate_interrupt_exception:", mips3.drcdata->generate_interrupt_exception, drc->cache_top);
514
515   mips3.drcdata->generate_cop_exception = drc->cache_top;
516   append_generate_exception(drc, EXCEPTION_BADCOP);
517   if (LOG_CODE)
518      x86log_disasm_code_range(mips3.log, "generate_cop_exception:", mips3.drcdata->generate_cop_exception, drc->cache_top);
519
520   mips3.drcdata->generate_overflow_exception = drc->cache_top;
521   append_generate_exception(drc, EXCEPTION_OVERFLOW);
522   if (LOG_CODE)
523      x86log_disasm_code_range(mips3.log, "generate_overflow_exception:", mips3.drcdata->generate_overflow_exception, drc->cache_top);
524
525   mips3.drcdata->generate_invalidop_exception = drc->cache_top;
526   append_generate_exception(drc, EXCEPTION_INVALIDOP);
527   if (LOG_CODE)
528      x86log_disasm_code_range(mips3.log, "generate_invalidop_exception:", mips3.drcdata->generate_invalidop_exception, drc->cache_top);
529
530   mips3.drcdata->generate_syscall_exception = drc->cache_top;
531   append_generate_exception(drc, EXCEPTION_SYSCALL);
532   if (LOG_CODE)
533      x86log_disasm_code_range(mips3.log, "generate_syscall_exception:", mips3.drcdata->generate_syscall_exception, drc->cache_top);
534
535   mips3.drcdata->generate_break_exception = drc->cache_top;
536   append_generate_exception(drc, EXCEPTION_BREAK);
537   if (LOG_CODE)
538      x86log_disasm_code_range(mips3.log, "generate_break_exception:", mips3.drcdata->generate_break_exception, drc->cache_top);
539
540   mips3.drcdata->generate_trap_exception = drc->cache_top;
541   append_generate_exception(drc, EXCEPTION_TRAP);
542   if (LOG_CODE)
543      x86log_disasm_code_range(mips3.log, "generate_trap_exception:", mips3.drcdata->generate_trap_exception, drc->cache_top);
544
545   mips3.drcdata->generate_tlbload_exception = drc->cache_top;
546   append_generate_exception(drc, EXCEPTION_TLBLOAD);
547   if (LOG_CODE)
548      x86log_disasm_code_range(mips3.log, "generate_tlbload_exception:", mips3.drcdata->generate_tlbload_exception, drc->cache_top);
549
550   mips3.drcdata->generate_tlbstore_exception = drc->cache_top;
551   append_generate_exception(drc, EXCEPTION_TLBSTORE);
552   if (LOG_CODE)
553      x86log_disasm_code_range(mips3.log, "generate_tlbstore_exception:", mips3.drcdata->generate_tlbstore_exception, drc->cache_top);
554
555   mips3.drcdata->handle_pc_tlb_mismatch = drc->cache_top;
556   append_handle_pc_tlb_mismatch(drc);
557   if (LOG_CODE)
558      x86log_disasm_code_range(mips3.log, "handle_pc_tlb_mismatch:", mips3.drcdata->handle_pc_tlb_mismatch, drc->cache_top);
559
560   mips3.drcdata->find_exception_handler = drc->cache_top;
561   append_find_exception_handler(drc);
562   if (LOG_CODE)
563      x86log_disasm_code_range(mips3.log, "find_exception_handler:", mips3.drcdata->find_exception_handler, drc->cache_top);
564
565   mips3.drcdata->explode_ccr31 = drc->cache_top;
566   append_explode_ccr31(drc);
567   if (LOG_CODE)
568      x86log_disasm_code_range(mips3.log, "explode_ccr31:", mips3.drcdata->explode_ccr31, drc->cache_top);
569
570   mips3.drcdata->recover_ccr31 = drc->cache_top;
571   append_recover_ccr31(drc);
572   if (LOG_CODE)
573      x86log_disasm_code_range(mips3.log, "recover_ccr31:", mips3.drcdata->recover_ccr31, drc->cache_top);
574
575   generate_read_write_handlers(drc, &mips3.drcdata->general, "general", 0);
576   generate_read_write_handlers(drc, &mips3.drcdata->cached, "cached", ARW_CACHED);
577   generate_read_write_handlers(drc, &mips3.drcdata->uncached, "uncached", ARW_UNCACHED);
578}
579
580
581/*------------------------------------------------------------------
582    drc_recompile_callback
583------------------------------------------------------------------*/
584
585static void drc_recompile_callback(drc_core *drc)
586{
587   int compiled_last_sequence = FALSE;
588   const opcode_desc *seqhead, *seqlast;
589   const opcode_desc *desclist;
590   void *start = drc->cache_top;
591   int override = FALSE;
592   int oobnum;
593
594   (void)start;
595
596   /* begin the sequence */
597   drc_begin_sequence(drc, mips3.core->pc);
598   mips3.drcdata->oobcount = 0;
599
600   /* get a description of this sequence */
601   desclist = drcfe_describe_code(mips3.drcfe, mips3.core->pc);
602   if (LOG_CODE)
603      log_opcode_desc(mips3.log, desclist, 0);
604
605   /* loop until we get through all instruction sequences */
606   for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next)
607   {
608      const opcode_desc *curdesc;
609      compiler_state compiler;
610
611      /* determine the last instruction in this sequence */
612      for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next)
613         if (seqlast->flags & OPFLAG_END_SEQUENCE)
614            break;
615      assert(seqlast != NULL);
616
617      /* add this as an entry point */
618      if (drc_add_entry_point(drc, seqhead->pc, override) && !override)
619      {
620         /* if this is the first sequence, it is a recompile request; allow overrides */
621         if (seqhead == desclist)
622         {
623            override = TRUE;
624            drc_add_entry_point(drc, seqhead->pc, override);
625         }
626
627         /* otherwise, just emit a jump to existing code */
628         else
629         {
630            if (compiled_last_sequence)
631               drc_append_fixed_dispatcher(drc, seqhead->pc, TRUE);
632            compiled_last_sequence = FALSE;
633            continue;
634         }
635      }
636      compiled_last_sequence = TRUE;
637
638      /* add a code log entry */
639      if (LOG_CODE)
640         x86log_add_comment(mips3.log, drc->cache_top, "-------------------------");
641
642      /* validate this code block if we're not pointing into ROM */
643      /* note that we assume P1 still contains the PC */
644      if (memory_get_write_ptr(cpu_getactivecpu(), ADDRESS_SPACE_PROGRAM, seqhead->physpc) != NULL)
645      {
646         if (LOG_CODE)
647            x86log_add_comment(mips3.log, drc->cache_top, "[Validation for %08X]", seqhead->pc);
648         emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)seqhead->opptr.v);                  // mov  rax,seqhead->opptr
649         for (curdesc = seqhead; curdesc != seqlast->next; curdesc = curdesc->next)
650         {
651            emit_cmp_m32_imm(DRCTOP, MBD(REG_RAX, curdesc->opptr.b - seqhead->opptr.b), *curdesc->opptr.l);
652                                                                        // cmp  [code],val
653            emit_jcc(DRCTOP, COND_NE, mips3.drc->recompile);                        // jne  recompile
654         }
655      }
656
657      /* initialize the compiler state */
658      compiler_state_reset(&compiler);
659
660#if LOG_HOTSPOTS
661      /* add hotspot tracking */
662      {
663         int hotnum;
664
665         drc_register_code_at_cache_top(drc, seqhead->pc);
666
667         for (hotnum = 0; hotnum < mips3.drcdata->next_hotspot; hotnum++)
668            if (mips3.drcdata->hotspot[hotnum].pc == seqhead->pc && mips3.drcdata->hotspot[hotnum].opcode == *seqhead->opptr.l)
669               break;
670         if (hotnum == mips3.drcdata->next_hotspot)
671         {
672            assert(hotnum < ARRAY_LENGTH(mips3.drcdata->hotspot));
673            mips3.drcdata->hotspot[hotnum].pc = seqhead->pc;
674            mips3.drcdata->hotspot[hotnum].opcode = *seqhead->opptr.l;
675            mips3.drcdata->hotspot[hotnum].count = 0;
676            mips3.drcdata->next_hotspot++;
677         }
678         emit_add_m64_imm(DRCTOP, MDRC(&mips3.drcdata->hotspot[hotnum].count), 1);
679      }
680#endif
681
682      /* iterate over instructions in the sequence and compile them */
683      for (curdesc = seqhead; curdesc != seqlast->next; curdesc = curdesc->next)
684         compile_one(drc, &compiler, curdesc);
685
686      /* at the end of the sequence; update the PC in memory and check cycle counts */
687      if (!(seqlast->flags & (OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_WILL_CAUSE_EXCEPTION)))
688      {
689         UINT32 nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4;
690         emit_update_cycles_pc_and_flush(drc, &compiler, NULL, nextpc);
691      }
692
693      /* if this is a likely branch, the fall through case needs to skip the next instruction */
694      if ((seqlast->flags & OPFLAG_IS_CONDITIONAL_BRANCH) && seqlast->skipslots > 0)
695         if (seqlast->next != NULL && seqlast->next->pc != seqlast->pc + 8)
696         {
697            compiler_register_flush_all(drc, &compiler);
698            drc_append_tentative_fixed_dispatcher(drc, seqlast->pc + 8, TRUE);         // jmp  <pc+8>
699         }
700
701      /* if we need a redispatch, do it now */
702      if (seqlast->flags & OPFLAG_REDISPATCH)
703      {
704         UINT32 nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4;
705         compiler_register_flush_all(drc, &compiler);
706          drc_append_tentative_fixed_dispatcher(drc, nextpc, TRUE);                  // jmp  <nextpc>
707       }
708
709       /* if we need to return to the start, do it */
710      if (seqlast->flags & OPFLAG_RETURN_TO_START)
711      {
712         compiler_register_flush_all(drc, &compiler);
713          drc_append_tentative_fixed_dispatcher(drc, mips3.core->pc, FALSE);            // jmp  <startpc>
714      }
715   }
716
717   /* end the sequence */
718   drc_end_sequence(drc);
719
720   /* run the out-of-bounds handlers */
721   for (oobnum = 0; oobnum < mips3.drcdata->oobcount; oobnum++)
722   {
723      oob_handler *oob = &mips3.drcdata->ooblist[oobnum];
724      (*oob->callback)(drc, oob, oob->param);
725   }
726
727   /* log the generated code */
728   if (LOG_CODE)
729   {
730      char label[60];
731      sprintf(label, "Code @ %08X (%08X physical)", desclist->pc, desclist->physpc);
732      x86log_disasm_code_range(mips3.log, label, start, drc->cache_top);
733   }
734}
735
736
737/*------------------------------------------------------------------
738    drc_entrygen_callback
739------------------------------------------------------------------*/
740
741static void drc_entrygen_callback(drc_core *drc)
742{
743   append_check_interrupts(drc, NULL, NULL);
744}
745
746
747
748/***************************************************************************
749    RECOMPILER CORE
750***************************************************************************/
751
752/*------------------------------------------------------------------
753    compile_one
754------------------------------------------------------------------*/
755
756static void compile_one(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
757{
758   int hotnum;
759
760   /* register this instruction */
761   if (!(desc->flags & OPFLAG_IN_DELAY_SLOT))
762      drc_register_code_at_cache_top(drc, desc->pc);
763
764   /* add an entry for the log */
765   if (LOG_CODE)
766      log_add_disasm_comment(mips3.log, drc->cache_top, desc->pc, *desc->opptr.l);
767
768   /* if we want a probe, add it here */
769   if (desc->pc == PROBE_ADDRESS)
770   {
771      emit_mov_m32_imm(DRCTOP, PCADDR, desc->pc);                                 // mov  [pc],desc->pc
772      compiler_register_flush_all(drc, compiler);
773      emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)probe_printf);
774      emit_call_r64(DRCTOP, REG_RAX);
775   }
776
777   /* if we are debugging, call the debugger */
778   if (Machine->debug_mode || COMPARE_AGAINST_C)
779   {
780      emit_mov_m32_imm(DRCTOP, PCADDR, desc->pc);                                 // mov  [pc],desc->pc
781      if (COMPARE_AGAINST_C && !(desc->flags & OPFLAG_IN_DELAY_SLOT))
782         emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->execute_c_version));
783      if (Machine->debug_mode)
784         drc_append_call_debugger(drc);                                       // <call debugger>
785   }
786
787   /* validate our TLB entry at this PC; if we fail, we need to recompile */
788   if ((desc->flags & OPFLAG_VALIDATE_TLB) && (desc->pc < 0x80000000 || desc->pc >= 0xc0000000))
789   {
790      emit_cmp_m32_imm(DRCTOP, MDRC(&mips3.core->tlb_table[desc->pc >> 12]), mips3.core->tlb_table[desc->pc >> 12]);
791                                                                     // cmp  tlb_table[pc>>12],<original value>
792      oob_request_callback(drc, COND_NE, oob_exception_cleanup, compiler, desc, mips3.drcdata->handle_pc_tlb_mismatch);
793                                                                     // jne  handle_pc_tlb_mismatch
794   }
795
796   /* accumulate total cycles */
797   compiler->cycles += desc->cycles;
798
799   /* is this a hotspot? */
800   for (hotnum = 0; hotnum < MIPS3_MAX_HOTSPOTS; hotnum++)
801      if (desc->pc == mips3.hotspot[hotnum].pc && *desc->opptr.l == mips3.hotspot[hotnum].opcode)
802      {
803         compiler->cycles += mips3.hotspot[hotnum].cycles;
804         break;
805      }
806
807   /* if this is an invalid opcode, generate the exception now */
808   if (desc->flags & OPFLAG_INVALID_OPCODE)
809      oob_request_callback(drc, COND_NONE, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_invalidop_exception);
810
811   /* otherwise, it's a regular instruction */
812   else
813   {
814      /* compile the instruction */
815      if (!compile_instruction(drc, compiler, desc))
816         fatalerror("Unimplemented op %08X (%02X,%02X)", *desc->opptr.l, *desc->opptr.l >> 26, *desc->opptr.l & 0x3f);
817
818      /* flush */
819      if (FLUSH_AFTER_EACH_INSTRUCTION)
820         compiler_register_flush_all(drc, compiler);
821   }
822}
823
824
825
826/***************************************************************************
827    OUT-OF-BOUNDS CODEGEN
828***************************************************************************/
829
830/*-------------------------------------------------
831    oob_exception_cleanup - out-of-bounds code
832    generator for cleaning up and generating an
833    exception with the EPC pointing to the
834    current instruction
835-------------------------------------------------*/
836
837static void oob_exception_cleanup(drc_core *drc, oob_handler *oob, void *param)
838{
839   /* if this is non-jumping error, emit a unique signature */
840   if (oob->link.size == 0)
841   {
842      /* align to an 8-byte boundary */
843      while (((UINT64)drc->cache_top & 7) != 0)
844         emit_int_3(DRCTOP);
845
846      /* logging */
847      if (LOG_CODE)
848      {
849         x86log_add_comment(mips3.log, drc->cache_top, "[Exception path for %08X]", oob->desc->pc);
850         x86log_mark_as_data(mips3.log, drc->cache_top, drc->cache_top + 15, 8);
851      }
852
853      /* output a pair of qwords */
854      emit_qword(DRCTOP, EXCEPTION_ADDRESS_COOKIE);
855      emit_qword(DRCTOP, (UINT64)oob->link.target);
856   }
857
858   /* otherwise, just resolve the link */
859   else
860   {
861      resolve_link(DRCTOP, &oob->link);
862      if (LOG_CODE)
863         x86log_add_comment(mips3.log, drc->cache_top, "[Exception path for %08X]", oob->desc->pc);
864   }
865
866   /* adjust for cycles */
867   if (oob->compiler.cycles != 0)
868      emit_sub_m32_imm(DRCTOP, ICOUNTADDR, oob->compiler.cycles);                     // sub  [icount],cycles
869
870   /* update the PC with the instruction PC */
871   if (!(oob->desc->flags & OPFLAG_IN_DELAY_SLOT))
872      emit_mov_r32_imm(DRCTOP, REG_P1, oob->desc->pc);                           // mov  p1,pc
873   else
874      emit_mov_r32_imm(DRCTOP, REG_P1, oob->desc->pc | 1);                        // mov  p1,pc | 1
875
876   /* flush any dirty registers */
877   compiler_register_flush_all(drc, &oob->compiler);                              // <flush registers>
878
879   /* jump to the exception generator */
880   emit_jmp(DRCTOP, param);                                                // jmp  <generate exception>
881}
882
883
884/*-------------------------------------------------
885    oob_interrupt_cleanup - out-of-bounds code
886    generator for cleaning up and generating an
887    interrupt with the EPC pointing to the
888    following instruction
889-------------------------------------------------*/
890
891static void oob_interrupt_cleanup(drc_core *drc, oob_handler *oob, void *param)
892{
893   /* resolve the link */
894   resolve_link(DRCTOP, &oob->link);
895
896   /* add a code log entry */
897   if (LOG_CODE)
898      x86log_add_comment(mips3.log, drc->cache_top, "[Interrupt path for %08X]", oob->desc->pc);
899
900   /* adjust for cycles */
901   if (oob->compiler.cycles != 0)
902      emit_sub_m32_imm(DRCTOP, ICOUNTADDR, oob->compiler.cycles);                     // sub  [icount],cycles
903
904   /* update the PC with the following instruction PC */
905   if (!(oob->desc->flags & OPFLAG_IN_DELAY_SLOT))
906   {
907      assert(!(oob->desc->flags & OPFLAG_IS_BRANCH));
908      emit_mov_r32_imm(DRCTOP, REG_P1, oob->desc->pc + 4);                        // mov  p1,pc + 4
909   }
910   else
911   {
912      assert(oob->desc->branch != NULL);
913      if (oob->desc->branch->targetpc != BRANCH_TARGET_DYNAMIC)
914         emit_mov_r32_imm(DRCTOP, REG_P1, oob->desc->branch->targetpc);               // mov  p1,<targetpc>
915      else
916         emit_mov_r32_m32(DRCTOP, REG_P1, MBD(REG_RSP, SPOFFS_NEXTPC));               // mov  p1,[rsp + nextpc]
917   }
918
919   /* flush any dirty registers */
920   compiler_register_flush_all(drc, &oob->compiler);                              // <flush registers>
921
922   /* jump to the exception generator */
923   emit_jmp(DRCTOP, param);                                                // jmp  <generate exception>
924}
925
926
927
928/***************************************************************************
929    REGISTER ALLOCATION ROUTINES
930***************************************************************************/
931
932/*-------------------------------------------------
933    compiler_register_set_constant - set a MIPS
934    register to a constant value
935-------------------------------------------------*/
936
937static void compiler_register_set_constant(compiler_state *compiler, UINT8 mipsreg, UINT64 constval)
938{
939   mipsreg_state reg = compiler->mipsregs[mipsreg];
940
941   assert((INT32)constval == (INT64)constval);
942
943   /* if the register was previously live, free it */
944   if (ISLIVE(reg))
945   {
946      assert(compiler->x86regs[X86REG(reg)] & X86REG_LIVE);
947      compiler->x86regs[X86REG(reg)] = 0;
948   }
949
950   /* set up the constant */
951   compiler->mipsregs[mipsreg] = MAKE_CONST(constval) | ((mipsreg == 0) ? 0 : MIPSREG_DIRTY);
952}
953
954
955/*-------------------------------------------------
956    compiler_register_allocate - allocate an x86
957    register to hold a MIPS register
958-------------------------------------------------*/
959
960static mipsreg_state compiler_register_allocate(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 mipsreg, UINT8 flags)
961{
962   UINT8 regindex, regnum = 0;
963   UINT64 livemask = 0;
964
965   /* register 0 is always constant */
966   if (mipsreg == 0)
967      return MAKE_CONST(0);
968
969   /* first see if we are already allocated */
970   if (ISLIVE(compiler->mipsregs[mipsreg]))
971   {
972      /* if we're not a source, make sure we are marked dirty */
973      if (flags & ALLOC_DIRTY)
974         compiler->mipsregs[mipsreg] |= MIPSREG_DIRTY;
975      return compiler->mipsregs[mipsreg];
976   }
977
978   /* if we just want a source register, return a constant directly */
979   if (flags == ALLOC_SRC && ISCONST(compiler->mipsregs[mipsreg]))
980      return compiler->mipsregs[mipsreg];
981
982   /* first look for a free entry */
983   for (regindex = 0; regindex < NUM_NVREG; regindex++)
984   {
985      regnum = nvreg[regindex];
986      if (!(compiler->x86regs[regnum] & X86REG_LIVE))
987         goto allocateit;
988      else
989         livemask |= (UINT64)1 << (compiler->x86regs[regnum] & X86REG_MIPSMASK);
990   }
991
992   /* can't have anything we need for this instruction, however */
993   livemask &= ~desc->gpr.used & ~desc->gpr.modified;
994   desc = desc->next;
995
996   /* next loop over the registers, figuring out who has the longest until being used */
997   while (desc != NULL && livemask != 0)
998   {
999      /* if this instruction uses the last remaining register, we have to pick from among those */
1000      if ((livemask & ~desc->gpr.used) == 0)
1001         break;
1002      livemask &= ~desc->gpr.used;
1003
1004      /* if this instruction modifies any of the registers, we want those */
1005      if ((livemask & desc->gpr.modified) != 0)
1006      {
1007         livemask &= desc->gpr.modified;
1008         break;
1009      }
1010
1011      /* advance to the next instruction; stop if we hit end-of-sequence */
1012      if (desc->flags & OPFLAG_END_SEQUENCE)
1013         break;
1014      desc = desc->next;
1015   }
1016
1017   /* pick the first one */
1018   for (regindex = 0; regindex < NUM_NVREG; regindex++)
1019   {
1020      regnum = nvreg[regindex];
1021      if (livemask & ((UINT64)1 << (compiler->x86regs[regnum] & X86REG_MIPSMASK)))
1022         break;
1023   }
1024   assert(regindex != NUM_NVREG);
1025
1026   /* flush it */
1027   compiler_register_flush(drc, compiler, compiler->x86regs[regnum] & X86REG_MIPSMASK, TRUE);
1028
1029allocateit:
1030   /* load the contents if we are a source */
1031   if (LOG_CODE)
1032      x86log_add_comment(mips3.log, drc->cache_top, "allocate r%d (%s)", mipsreg, x86regname[regnum]);
1033   if (flags & ALLOC_SRC)
1034   {
1035      mipsreg_state state = compiler->mipsregs[mipsreg];
1036      if (ISCONST(state))
1037         emit_mov_r64_imm(DRCTOP, regnum, CONSTVAL(state));                        // mov  <x86reg>,constant
1038      else
1039         emit_mov_r64_m64(DRCTOP, regnum, REGADDR(mipsreg));                        // mov  <x86reg>,[reg]
1040   }
1041
1042   /* mark it allocated */
1043   assert(!(compiler->x86regs[regnum] & X86REG_LIVE));
1044   compiler->x86regs[regnum] = X86REG_LIVE | mipsreg;
1045   compiler->mipsregs[mipsreg] = MIPSREG_LIVE | regnum | ((flags & ALLOC_DIRTY) ? MIPSREG_DIRTY : 0);
1046   return compiler->mipsregs[mipsreg];
1047}
1048
1049
1050/*-------------------------------------------------
1051    compiler_register_flush - flush and optionally
1052    free a single MIPS register
1053-------------------------------------------------*/
1054
1055static void compiler_register_flush(drc_core *drc, compiler_state *compiler, UINT8 mipsreg, int free)
1056{
1057   mipsreg_state reg = compiler->mipsregs[mipsreg];
1058
1059   assert(ISCONST(reg) || ISLIVE(reg));
1060
1061   /* flush the value if dirty */
1062   if (ISDIRTY(reg))
1063   {
1064      if (LOG_CODE)
1065         x86log_add_comment(mips3.log, drc->cache_top, "flush r%d (%s)", mipsreg, ISCONST(reg) ? "constant" : x86regname[X86REG(reg)]);
1066
1067      /* flush a constant value */
1068      if (ISCONST(reg))
1069         emit_mov_m64_imm(DRCTOP, REGADDR(mipsreg), CONSTVAL(reg));                     // mov  [reg],constant
1070
1071      /* flush a live value */
1072      else if (ISLIVE(reg))
1073         emit_mov_m64_r64(DRCTOP, REGADDR(mipsreg), X86REG(reg));                     // mov  [reg],<x86reg>
1074   }
1075
1076   /* clear the dirty flag */
1077   if (!free)
1078      compiler->mipsregs[mipsreg] &= ~MIPSREG_DIRTY;
1079   else
1080   {
1081      if (ISLIVE(reg))
1082         compiler->x86regs[X86REG(reg)] = 0;
1083      compiler->mipsregs[mipsreg] = 0;
1084   }
1085}
1086
1087
1088/*-------------------------------------------------
1089    compiler_register_flush_all - flush all dirty
1090    registers
1091-------------------------------------------------*/
1092
1093static void compiler_register_flush_all(drc_core *drc, compiler_state *compiler)
1094{
1095   int mipsreg;
1096
1097   /* flush all dirty registers */
1098   for (mipsreg = 1; mipsreg < 35; mipsreg++)
1099      if (ISDIRTY(compiler->mipsregs[mipsreg]))
1100         compiler_register_flush(drc, compiler, mipsreg, FALSE);
1101}
1102
1103
1104
1105/***************************************************************************
1106    COMPILER CALLBACKS
1107***************************************************************************/
1108
1109/*-------------------------------------------------
1110    probe_printf - print the current CPU state
1111    and return
1112-------------------------------------------------*/
1113
1114static void probe_printf(void)
1115{
1116   printf(" PC=%08X          r1=%08X%08X  r2=%08X%08X  r3=%08X%08X\n",
1117      mips3.core->pc,
1118      (UINT32)(mips3.core->r[1] >> 32), (UINT32)mips3.core->r[1],
1119      (UINT32)(mips3.core->r[2] >> 32), (UINT32)mips3.core->r[2],
1120      (UINT32)(mips3.core->r[3] >> 32), (UINT32)mips3.core->r[3]);
1121   printf(" r4=%08X%08X  r5=%08X%08X  r6=%08X%08X  r7=%08X%08X\n",
1122      (UINT32)(mips3.core->r[4] >> 32), (UINT32)mips3.core->r[4],
1123      (UINT32)(mips3.core->r[5] >> 32), (UINT32)mips3.core->r[5],
1124      (UINT32)(mips3.core->r[6] >> 32), (UINT32)mips3.core->r[6],
1125      (UINT32)(mips3.core->r[7] >> 32), (UINT32)mips3.core->r[7]);
1126   printf(" r8=%08X%08X  r9=%08X%08X r10=%08X%08X r11=%08X%08X\n",
1127      (UINT32)(mips3.core->r[8] >> 32), (UINT32)mips3.core->r[8],
1128      (UINT32)(mips3.core->r[9] >> 32), (UINT32)mips3.core->r[9],
1129      (UINT32)(mips3.core->r[10] >> 32), (UINT32)mips3.core->r[10],
1130      (UINT32)(mips3.core->r[11] >> 32), (UINT32)mips3.core->r[11]);
1131   printf("r12=%08X%08X r13=%08X%08X r14=%08X%08X r15=%08X%08X\n",
1132      (UINT32)(mips3.core->r[12] >> 32), (UINT32)mips3.core->r[12],
1133      (UINT32)(mips3.core->r[13] >> 32), (UINT32)mips3.core->r[13],
1134      (UINT32)(mips3.core->r[14] >> 32), (UINT32)mips3.core->r[14],
1135      (UINT32)(mips3.core->r[15] >> 32), (UINT32)mips3.core->r[15]);
1136   printf("r16=%08X%08X r17=%08X%08X r18=%08X%08X r19=%08X%08X\n",
1137      (UINT32)(mips3.core->r[16] >> 32), (UINT32)mips3.core->r[16],
1138      (UINT32)(mips3.core->r[17] >> 32), (UINT32)mips3.core->r[17],
1139      (UINT32)(mips3.core->r[18] >> 32), (UINT32)mips3.core->r[18],
1140      (UINT32)(mips3.core->r[19] >> 32), (UINT32)mips3.core->r[19]);
1141   printf("r20=%08X%08X r21=%08X%08X r22=%08X%08X r23=%08X%08X\n",
1142      (UINT32)(mips3.core->r[20] >> 32), (UINT32)mips3.core->r[20],
1143      (UINT32)(mips3.core->r[21] >> 32), (UINT32)mips3.core->r[21],
1144      (UINT32)(mips3.core->r[22] >> 32), (UINT32)mips3.core->r[22],
1145      (UINT32)(mips3.core->r[23] >> 32), (UINT32)mips3.core->r[23]);
1146   printf("r24=%08X%08X r25=%08X%08X r26=%08X%08X r27=%08X%08X\n",
1147      (UINT32)(mips3.core->r[24] >> 32), (UINT32)mips3.core->r[24],
1148      (UINT32)(mips3.core->r[25] >> 32), (UINT32)mips3.core->r[25],
1149      (UINT32)(mips3.core->r[26] >> 32), (UINT32)mips3.core->r[26],
1150      (UINT32)(mips3.core->r[27] >> 32), (UINT32)mips3.core->r[27]);
1151   printf("r28=%08X%08X r29=%08X%08X r30=%08X%08X r31=%08X%08X\n",
1152      (UINT32)(mips3.core->r[28] >> 32), (UINT32)mips3.core->r[28],
1153      (UINT32)(mips3.core->r[29] >> 32), (UINT32)mips3.core->r[29],
1154      (UINT32)(mips3.core->r[30] >> 32), (UINT32)mips3.core->r[30],
1155      (UINT32)(mips3.core->r[31] >> 32), (UINT32)mips3.core->r[31]);
1156   printf(" hi=%08X%08X  lo=%08X%08X\n",
1157      (UINT32)(mips3.core->r[REG_HI] >> 32), (UINT32)mips3.core->r[REG_HI],
1158      (UINT32)(mips3.core->r[REG_LO] >> 32), (UINT32)mips3.core->r[REG_LO]);
1159}
1160
1161
1162/*-------------------------------------------------
1163    exception_trap - log any exceptions that
1164    aren't interrupts
1165-------------------------------------------------*/
1166
1167static void exception_trap(void)
1168{
1169   if ((mips3.core->cpr[0][COP0_Cause] & 0xff) != 0)
1170      printf("Exception: EPC=%08X Cause=%08X BadVAddr=%08X Jmp=%08X\n", (UINT32)mips3.core->cpr[0][COP0_EPC], (UINT32)mips3.core->cpr[0][COP0_Cause], (UINT32)mips3.core->cpr[0][COP0_BadVAddr], mips3.core->pc);
1171}
1172
1173
1174
1175/***************************************************************************
1176    COMMON ROUTINES
1177***************************************************************************/
1178
1179/*------------------------------------------------------------------
1180    generate_read_write_handlers
1181------------------------------------------------------------------*/
1182
1183static void generate_read_write_handlers(drc_core *drc, readwrite_handlers *handlers, const char *type, UINT8 flags)
1184{
1185   char buffer[100];
1186
1187   handlers->read_byte_signed = drc->cache_top;
1188   append_readwrite_and_translate(drc, 1, ARW_READ | ARW_SIGNED | flags, offsetof(readwrite_handlers, read_byte_signed));
1189   sprintf(buffer, "%s.read_byte_signed:", type);
1190   if (LOG_CODE)
1191      x86log_disasm_code_range(mips3.log, buffer, handlers->read_byte_signed, drc->cache_top);
1192
1193   handlers->read_byte_unsigned = drc->cache_top;
1194   append_readwrite_and_translate(drc, 1, ARW_READ | ARW_UNSIGNED | flags, offsetof(readwrite_handlers, read_byte_unsigned));
1195   sprintf(buffer, "%s.read_byte_unsigned:", type);
1196   if (LOG_CODE)
1197      x86log_disasm_code_range(mips3.log, buffer, handlers->read_byte_unsigned, drc->cache_top);
1198
1199   handlers->read_half_signed = drc->cache_top;
1200   append_readwrite_and_translate(drc, 2, ARW_READ | ARW_SIGNED | flags, offsetof(readwrite_handlers, read_half_signed));
1201   sprintf(buffer, "%s.read_half_signed:", type);
1202   if (LOG_CODE)
1203      x86log_disasm_code_range(mips3.log, buffer, handlers->read_half_signed, drc->cache_top);
1204
1205   handlers->read_half_unsigned = drc->cache_top;
1206   append_readwrite_and_translate(drc, 2, ARW_READ | ARW_UNSIGNED | flags, offsetof(readwrite_handlers, read_half_unsigned));
1207   sprintf(buffer, "%s.read_half_unsigned:", type);
1208   if (LOG_CODE)
1209      x86log_disasm_code_range(mips3.log, buffer, handlers->read_half_unsigned, drc->cache_top);
1210
1211   handlers->read_word_signed = drc->cache_top;
1212   append_readwrite_and_translate(drc, 4, ARW_READ | ARW_SIGNED | flags, offsetof(readwrite_handlers, read_word_signed));
1213   sprintf(buffer, "%s.read_word_signed:", type);
1214   if (LOG_CODE)
1215      x86log_disasm_code_range(mips3.log, buffer, handlers->read_word_signed, drc->cache_top);
1216
1217   handlers->read_word_unsigned = drc->cache_top;
1218   append_readwrite_and_translate(drc, 4, ARW_READ | ARW_UNSIGNED | flags, offsetof(readwrite_handlers, read_word_unsigned));
1219   sprintf(buffer, "%s.read_word_unsigned:", type);
1220   if (LOG_CODE)
1221      x86log_disasm_code_range(mips3.log, buffer, handlers->read_word_unsigned, drc->cache_top);
1222
1223   handlers->read_word_masked = drc->cache_top;
1224   append_readwrite_and_translate(drc, 4, ARW_READ | ARW_UNSIGNED | ARW_MASKED | flags, offsetof(readwrite_handlers, read_word_masked));
1225   sprintf(buffer, "%s.read_word_masked:", type);
1226   if (LOG_CODE)
1227      x86log_disasm_code_range(mips3.log, buffer, handlers->read_word_masked, drc->cache_top);
1228
1229   handlers->read_double = drc->cache_top;
1230   append_readwrite_and_translate(drc, 8, ARW_READ | flags, offsetof(readwrite_handlers, read_double));
1231   sprintf(buffer, "%s.read_double:", type);
1232   if (LOG_CODE)
1233      x86log_disasm_code_range(mips3.log, buffer, handlers->read_double, drc->cache_top);
1234
1235   handlers->read_double_masked = drc->cache_top;
1236   append_readwrite_and_translate(drc, 8, ARW_READ | ARW_MASKED | flags, offsetof(readwrite_handlers, read_double_masked));
1237   sprintf(buffer, "%s.read_double_masked:", type);
1238   if (LOG_CODE)
1239      x86log_disasm_code_range(mips3.log, buffer, handlers->read_double_masked, drc->cache_top);
1240
1241   handlers->write_byte = drc->cache_top;
1242   append_readwrite_and_translate(drc, 1, ARW_WRITE | flags, offsetof(readwrite_handlers, write_byte));
1243   sprintf(buffer, "%s.write_byte:", type);
1244   if (LOG_CODE)
1245      x86log_disasm_code_range(mips3.log, buffer, handlers->write_byte, drc->cache_top);
1246
1247   handlers->write_half = drc->cache_top;
1248   append_readwrite_and_translate(drc, 2, ARW_WRITE | flags, offsetof(readwrite_handlers, write_half));
1249   sprintf(buffer, "%s.write_half:", type);
1250   if (LOG_CODE)
1251      x86log_disasm_code_range(mips3.log, buffer, handlers->write_half, drc->cache_top);
1252
1253   handlers->write_word = drc->cache_top;
1254   append_readwrite_and_translate(drc, 4, ARW_WRITE | flags, offsetof(readwrite_handlers, write_word));
1255   sprintf(buffer, "%s.write_word:", type);
1256   if (LOG_CODE)
1257      x86log_disasm_code_range(mips3.log, buffer, handlers->write_word, drc->cache_top);
1258
1259   handlers->write_word_masked = drc->cache_top;
1260   append_readwrite_and_translate(drc, 4, ARW_WRITE | ARW_MASKED | flags, offsetof(readwrite_handlers, write_word_masked));
1261   sprintf(buffer, "%s.write_word_masked:", type);
1262   if (LOG_CODE)
1263      x86log_disasm_code_range(mips3.log, buffer, handlers->write_word_masked, drc->cache_top);
1264
1265   handlers->write_double = drc->cache_top;
1266   append_readwrite_and_translate(drc, 8, ARW_WRITE | flags, offsetof(readwrite_handlers, write_double));
1267   sprintf(buffer, "%s.write_double:", type);
1268   if (LOG_CODE)
1269      x86log_disasm_code_range(mips3.log, buffer, handlers->write_double, drc->cache_top);
1270
1271   handlers->write_double_masked = drc->cache_top;
1272   append_readwrite_and_translate(drc, 8, ARW_WRITE | ARW_MASKED | flags, offsetof(readwrite_handlers, write_double_masked));
1273   sprintf(buffer, "%s.write_double_masked:", type);
1274   if (LOG_CODE)
1275      x86log_disasm_code_range(mips3.log, buffer, handlers->write_double_masked, drc->cache_top);
1276}
1277
1278
1279/*------------------------------------------------------------------
1280    append_generate_exception
1281------------------------------------------------------------------*/
1282
1283static void append_generate_exception(drc_core *drc, UINT8 exception)
1284{
1285   UINT32 offset = (exception >= EXCEPTION_TLBMOD && exception <= EXCEPTION_TLBSTORE) ? 0x00 : 0x180;
1286   emit_link link1, link2;
1287
1288   if (exception == EXCEPTION_TLBLOAD || exception == EXCEPTION_TLBSTORE)
1289   {
1290      /* assumes failed address is in P2 */
1291      emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_BadVAddr), REG_P2);                     // mov  [BadVAddr],p2
1292      emit_and_m32_imm(DRCTOP, CPR0ADDR(COP0_EntryHi), 0x000000ff);                  // and  [EntryHi],0x000000ff
1293      emit_and_r32_imm(DRCTOP, REG_P2, 0xffffe000);                              // and  p2,0xffffe000
1294      emit_or_m32_r32(DRCTOP, CPR0ADDR(COP0_EntryHi), REG_P2);                     // or   [EntryHi],p2
1295      emit_and_m32_imm(DRCTOP, CPR0ADDR(COP0_Context), 0xff800000);                  // and  [Context],0xff800000
1296      emit_shr_r32_imm(DRCTOP, REG_P2, 9);                                    // shr  p2,9
1297      emit_or_m32_r32(DRCTOP, CPR0ADDR(COP0_Context), REG_P2);                     // or   [Context],p2
1298   }
1299
1300   /* on entry, exception PC must be in REG_P1, and low bit set if in a delay slot */
1301   emit_mov_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Cause));                        // mov  eax,[Cause]
1302   emit_and_r32_imm(DRCTOP, REG_EAX, ~0x800000ff);                                 // and  eax,~0x800000ff
1303   emit_test_r32_imm(DRCTOP, REG_P1, 1);                                       // test p1,1
1304   emit_jcc_short_link(DRCTOP, COND_Z, &link1);                                 // jz   skip
1305   emit_or_r32_imm(DRCTOP, REG_EAX, 0x80000000);                                 // or   eax,0x80000000
1306   emit_sub_r32_imm(DRCTOP, REG_P1, 5);                                       // sub  p1,5
1307
1308   resolve_link(DRCTOP, &link1);                                          // skip:
1309   emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_EPC), REG_P1);                           // mov  [EPC],p1
1310   if (exception)
1311      emit_or_r32_imm(DRCTOP, REG_EAX, exception << 2);                           // or   eax,exception << 2
1312   emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Cause), REG_EAX);                        // mov  [Cause],eax
1313   emit_mov_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Status));                        // mov  eax,[SR]
1314   emit_or_r32_imm(DRCTOP, REG_EAX, SR_EXL);                                    // or   eax,SR_EXL
1315   emit_test_r32_imm(DRCTOP, REG_EAX, SR_BEV);                                    // test eax,SR_BEV
1316   emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Status), REG_EAX);                        // mov  [SR],eax
1317   emit_mov_r32_imm(DRCTOP, REG_P1, 0xbfc00200 + offset);                           // mov  p1,0xbfc00200+offset
1318   emit_jcc_short_link(DRCTOP, COND_NZ, &link2);                                 // jnz  skip2
1319   emit_mov_r32_imm(DRCTOP, REG_P1, 0x80000000 + offset);                           // mov  p1,0x80000000+offset
1320
1321   resolve_link(DRCTOP, &link2);                                          // skip2:
1322   if (PRINTF_EXCEPTIONS)
1323   {
1324      emit_mov_m32_r32(DRCTOP, PCADDR, REG_P1);                                 // mov  [PC],p1
1325      emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)exception_trap);                     // mov  rax,exception_trap
1326      emit_call_r64(DRCTOP, REG_RAX);                                          // call rax
1327      emit_mov_r32_m32(DRCTOP, REG_P1, PCADDR);                                 // mov  p1,[PC]
1328   }
1329   drc_append_dispatcher(drc);                                                // dispatch
1330}
1331
1332
1333/*------------------------------------------------------------------
1334    append_handle_pc_tlb_mismatch
1335------------------------------------------------------------------*/
1336
1337static void append_handle_pc_tlb_mismatch(drc_core *drc)
1338{
1339#if 0
1340   emit_mov_r32_r32(DRCTOP, REG_EAX, REG_R15D);                                 // mov  eax,edi
1341   emit_shr_r32_imm(DRCTOP, REG_EAX, 12);                                       // shr  eax,12
1342   emit_mov_r32_m32(DRCTOP, REG_EDX, MISD(REG_EAX, 4, &mips3.core->tlb_table));         // mov  edx,tlb_table[eax*4]
1343   emit_test_r32_imm(DRCTOP, REG_EDX, 2);                                       // test edx,2
1344   emit_mov_r32_r32(DRCTOP, REG_EAX, REG_R15D);                                 // mov  eax,edi
1345   emit_jcc(DRCTOP, COND_NZ, mips3.drcdata->generate_tlbload_exception);               // jnz  generate_tlbload_exception
1346   emit_mov_m32bd_r32(DRCTOP, drc->pcptr, REG_R15D);                              // mov  [pcptr],edi
1347   emit_jmp(DRCTOP, drc->recompile);                                          // call recompile
1348#endif
1349}
1350
1351
1352/*------------------------------------------------------------------
1353    append_find_exception_handler
1354------------------------------------------------------------------*/
1355
1356static void append_find_exception_handler(drc_core *drc)
1357{
1358   x86code *loop;
1359
1360   emit_mov_r64_m64(DRCTOP, REG_RAX, MBD(REG_RSP, 0));                              // mov  rax,[rsp]
1361   emit_mov_r64_imm(DRCTOP, REG_V5, EXCEPTION_ADDRESS_COOKIE);                        // mov  v5,EXCEPTION_ADDRESS_COOKIE
1362   emit_mov_r64_r64(DRCTOP, REG_V6, REG_RAX);                                    // mov  v6,rax
1363   emit_and_r64_imm(DRCTOP, REG_RAX, ~7);                                       // and  rax,~7
1364   emit_add_r64_imm(DRCTOP, REG_RSP, 8);                                       // add  rsp,8
1365   emit_add_r64_imm(DRCTOP, REG_RAX, 8);                                       // add  rax,8
1366   loop = drc->cache_top;                                                // loop:
1367   emit_cmp_m64_r64(DRCTOP, MBD(REG_RAX, 0), REG_V5);                              // cmp  [rax],v5
1368   emit_lea_r64_m64(DRCTOP, REG_RAX, MBD(REG_RAX, 8));                              // lea  rax,[rax+8]
1369   emit_jcc(DRCTOP, COND_NE, loop);                                          // jne  loop
1370   emit_cmp_m64_r64(DRCTOP, MBD(REG_RAX, 0), REG_V6);                              // cmp  [rax],v6
1371   emit_lea_r64_m64(DRCTOP, REG_RAX, MBD(REG_RAX, 8));                              // lea  rax,[rax+8]
1372   emit_jcc(DRCTOP, COND_NE, loop);                                          // jne  loop
1373   emit_jmp_r64(DRCTOP, REG_RAX);                                             // jmp  rax
1374}
1375
1376
1377/*------------------------------------------------------------------
1378    append_direct_ram_read
1379------------------------------------------------------------------*/
1380
1381static void append_direct_ram_read(drc_core *drc, int size, UINT8 flags, void *rambase, offs_t ramstart)
1382{
1383   void *adjbase = (UINT8 *)rambase - ramstart;
1384   INT64 adjdisp = (UINT8 *)adjbase - (UINT8 *)drc->baseptr;
1385   int raxrel = ((INT32)adjdisp != adjdisp);
1386
1387   /* if we can't fit the delta to adjbase within an INT32, load RAX with the full address here */
1388   if (raxrel)
1389      emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)adjbase);
1390
1391   /* fast RAM byte read */
1392   if (size == 1)
1393   {
1394      /* adjust for endianness */
1395      if (mips3.core->bigendian)
1396         emit_xor_r32_imm(DRCTOP, REG_P1, 3);                                 // xor   p1,3
1397
1398      /* read rax-relative */
1399      if (raxrel)
1400      {
1401         if (flags & ARW_SIGNED)
1402            emit_movsx_r64_m8(DRCTOP, REG_RAX, MBISD(REG_RAX, REG_P1, 1, 0));         // movsx rax,byte ptr [p1 + rax]
1403         else
1404            emit_movzx_r64_m8(DRCTOP, REG_RAX, MBISD(REG_RAX, REG_P1, 1, 0));         // movzx rax,byte ptr [p1 + rax]
1405      }
1406
1407      /* read drc-relative */
1408      else
1409      {
1410         if (flags & ARW_SIGNED)
1411            emit_movsx_r64_m8(DRCTOP, REG_RAX, MDRCISD(adjbase, REG_P1, 1, 0));         // movsx rax,byte ptr [p1 + adjbase]
1412         else
1413            emit_movzx_r64_m8(DRCTOP, REG_RAX, MDRCISD(adjbase, REG_P1, 1, 0));         // movzx rax,byte ptr [p1 + adjbase]
1414      }
1415   }
1416
1417   /* fast RAM halfword read */
1418   else if (size == 2)
1419   {
1420      /* adjust for endianness */
1421      if (mips3.core->bigendian)
1422         emit_xor_r32_imm(DRCTOP, REG_P1, 2);                                 // xor   p1,2
1423
1424      /* read rax-relative */
1425      if (raxrel)
1426      {
1427         if (flags & ARW_SIGNED)
1428            emit_movsx_r64_m16(DRCTOP, REG_RAX, MBISD(REG_RAX, REG_P1, 1, 0));         // movsx rax,word ptr [p1 + rax]
1429         else
1430            emit_movzx_r64_m16(DRCTOP, REG_EAX, MBISD(REG_RAX, REG_P1, 1, 0));         // movzx rax,word ptr [p1 + rax]
1431      }
1432
1433      /* read drc-relative */
1434      else
1435      {
1436         if (flags & ARW_SIGNED)
1437            emit_movsx_r64_m16(DRCTOP, REG_RAX, MDRCISD(adjbase, REG_P1, 1, 0));      // movsx rax,word ptr [p1 + adjbase]
1438         else
1439            emit_movzx_r64_m16(DRCTOP, REG_EAX, MDRCISD(adjbase, REG_P1, 1, 0));      // movzx rax,word ptr [p1 + adjbase]
1440      }
1441   }
1442
1443   /* fast RAM dword read */
1444   else if (size == 4)
1445   {
1446      /* read rax-relative */
1447      if (raxrel)
1448      {
1449         if (flags & ARW_SIGNED)
1450            emit_movsxd_r64_m32(DRCTOP, REG_RAX, MBISD(REG_RAX, REG_P1, 1, 0));         // movsxd rax,dword ptr [p1 + rax]
1451         else
1452            emit_mov_r32_m32(DRCTOP, REG_EAX, MBISD(REG_RAX, REG_P1, 1, 0));         // mov   eax,word ptr [p1 + rax]
1453      }
1454
1455      /* read drc-relative */
1456      else
1457      {
1458         if (flags & ARW_SIGNED)
1459            emit_movsxd_r64_m32(DRCTOP, REG_RAX, MDRCISD(adjbase, REG_P1, 1, 0));      // movsxd rax,dword ptr [p1 + adjbase]
1460         else
1461            emit_mov_r32_m32(DRCTOP, REG_EAX, MDRCISD(adjbase, REG_P1, 1, 0));         // mov   eax,word ptr [p1 + adjbase]
1462      }
1463   }
1464
1465   /* fast RAM qword read */
1466   else if (size == 8)
1467   {
1468      /* read rax-relative */
1469      if (raxrel)
1470         emit_mov_r64_m64(DRCTOP, REG_RAX, MBISD(REG_RAX, REG_P1, 1, 0));            // mov   rax,[p1 + rax]
1471
1472      /* read drc-relative */
1473      else
1474         emit_mov_r64_m64(DRCTOP, REG_RAX, MDRCISD(adjbase, REG_P1, 1, 0));            // mov   rax,[p1 + adjbase]
1475
1476      /* adjust for endianness */
1477      if (mips3.core->bigendian)
1478         emit_ror_r64_imm(DRCTOP, REG_RAX, 32);                                 // ror   rax,32
1479   }
1480}
1481
1482
1483/*------------------------------------------------------------------
1484    append_direct_ram_write
1485------------------------------------------------------------------*/
1486
1487static void append_direct_ram_write(drc_core *drc, int size, UINT8 flags, void *rambase, offs_t ramstart)
1488{
1489   void *adjbase = (UINT8 *)rambase - ramstart;
1490   INT64 adjdisp = (UINT8 *)adjbase - (UINT8 *)drc->baseptr;
1491   int raxrel = ((INT32)adjdisp != adjdisp);
1492
1493   /* if we can't fit the delta to adjbase within an INT32, load RAX with the full address here */
1494   if (raxrel)
1495      emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)adjbase);
1496
1497   /* fast RAM byte write */
1498   if (size == 1)
1499   {
1500      /* adjust for endianness */
1501      if (mips3.core->bigendian)
1502         emit_xor_r32_imm(DRCTOP, REG_P1, 3);                                 // xor   p1,3
1503
1504      /* write either rax-relative or drc-relative */
1505      if (raxrel)
1506         emit_mov_m8_r8(DRCTOP, MBISD(REG_RAX, REG_P1, 1, 0), REG_P2);               // mov   [p1 + rax],p2
1507      else
1508         emit_mov_m8_r8(DRCTOP, MDRCISD(adjbase, REG_P1, 1, 0), REG_P2);               // mov   [p1 + adjbase],p2
1509   }
1510
1511   /* fast RAM halfword write */
1512   else if (size == 2)
1513   {
1514      /* adjust for endianness */
1515      if (mips3.core->bigendian)
1516         emit_xor_r32_imm(DRCTOP, REG_P1, 2);                                 // xor   p1,2
1517
1518      /* write either rax-relative or drc-relative */
1519      if (raxrel)
1520         emit_mov_m16_r16(DRCTOP, MBISD(REG_RAX, REG_P1, 1, 0), REG_P2);               // mov   [p1 + rax],p2
1521      else
1522         emit_mov_m16_r16(DRCTOP, MDRCISD(adjbase, REG_P1, 1, 0), REG_P2);            // mov   [p1 + adjbase],p2
1523   }
1524
1525   /* fast RAM dword write */
1526   else if (size == 4)
1527   {
1528      /* unmasked */
1529      if (!(flags & ARW_MASKED))
1530      {
1531         if (raxrel)
1532            emit_mov_m32_r32(DRCTOP, MBISD(REG_RAX, REG_P1, 1, 0), REG_P2);            // mov   [p1 + rax],p2
1533         else
1534            emit_mov_m32_r32(DRCTOP, MDRCISD(adjbase, REG_P1, 1, 0), REG_P2);         // mov   [p1 + adjbase],p2
1535      }
1536
1537      /* masked */
1538      else
1539      {
1540         emit_mov_r32_r32(DRCTOP, REG_P4, REG_P3);                              // mov   p4,p3
1541         emit_not_r32(DRCTOP, REG_P3);                                       // not   p3
1542         emit_and_r32_r32(DRCTOP, REG_P4, REG_P2);                              // and   p4,p2
1543         if (raxrel)
1544            emit_and_r32_m32(DRCTOP, REG_P3, MBISD(REG_RAX, REG_P1, 1, 0));            // and   p3,[p1 + rax]
1545         else
1546            emit_and_r32_m32(DRCTOP, REG_P3, MDRCISD(adjbase, REG_P1, 1, 0));         // and   p3,[p1 + adjbase]
1547         emit_or_r32_r32(DRCTOP, REG_P4, REG_P3);                              // or    p4,p3
1548         if (raxrel)
1549            emit_mov_m32_r32(DRCTOP, MBISD(REG_RAX, REG_P1, 1, 0), REG_P4);            // mov   [p1 + rax],p4
1550         else
1551            emit_mov_m32_r32(DRCTOP, MDRCISD(adjbase, REG_P1, 1, 0), REG_P4);         // mov   [p1 + adjbase],p4
1552      }
1553   }
1554
1555   /* fast RAM qword write */
1556   else if (size == 8)
1557   {
1558      /* adjust for endianness */
1559      if (mips3.core->bigendian)
1560         emit_ror_r64_imm(DRCTOP, REG_P2, 32);                                 // ror  p2,32
1561
1562      /* unmasked */
1563      if (!(flags & ARW_MASKED))
1564      {
1565         if (raxrel)
1566            emit_mov_m64_r64(DRCTOP, MBISD(REG_RAX, REG_P1, 1, 0), REG_P2);            // mov   [p1 + rax],p2
1567         else
1568            emit_mov_m64_r64(DRCTOP, MDRCISD(adjbase, REG_P1, 1, 0), REG_P2);         // mov   [p1 + adjbase],p2
1569      }
1570
1571      /* masked */
1572      else
1573      {
1574         if (mips3.core->bigendian)
1575            emit_ror_r64_imm(DRCTOP, REG_P3, 32);                              // ror   p3,32
1576         emit_mov_r64_r64(DRCTOP, REG_P4, REG_P3);                              // mov   p4,p3
1577         emit_not_r64(DRCTOP, REG_P3);                                       // not   p3
1578         emit_and_r64_r64(DRCTOP, REG_P4, REG_P2);                              // and   p4,p2
1579         if (raxrel)
1580            emit_and_r64_m64(DRCTOP, REG_P3, MBISD(REG_RAX, REG_P1, 1, 0));            // and   p3,[p1 + rax]
1581         else
1582            emit_and_r64_m64(DRCTOP, REG_P3, MDRCISD(adjbase, REG_P1, 1, 0));         // and   p3,[p1 + adjbase]
1583         emit_or_r64_r64(DRCTOP, REG_P4, REG_P3);                              // or    p4,p3
1584         if (raxrel)
1585            emit_mov_m64_r64(DRCTOP, MBISD(REG_RAX, REG_P1, 1, 0), REG_P4);            // mov   [p1 + rax],p4
1586         else
1587            emit_mov_m64_r64(DRCTOP, MDRCISD(adjbase, REG_P1, 1, 0), REG_P4);         // mov   [p1 + adjbase],p4
1588      }
1589   }
1590}
1591
1592
1593/*------------------------------------------------------------------
1594    append_readwrite_and_translate
1595------------------------------------------------------------------*/
1596
1597static void append_readwrite_and_translate(drc_core *drc, int size, UINT8 flags, UINT32 ptroffs)
1598{
1599   UINT32 base = ((flags & ARW_CACHED) ? 0x80000000 : (flags & ARW_UNCACHED) ? 0xa0000000 : 0);
1600   emit_link page_fault = { 0 }, handle_kernel = { 0 }, wrong_handler = { 0 };
1601   x86code *continue_mapped = NULL;
1602   int ramnum;
1603
1604   /* if the base is 0, this is a general case which may be paged; perform the translation first */
1605   /* the result of the translation produces the physical address inline in P1 */
1606   /* if a page fault occurs, we have to keep an original copy of the address in EAX */
1607   /* note that we use RAX and P4 as scratch registers */
1608   if (base == 0)
1609   {
1610      emit_test_r32_r32(DRCTOP, REG_P1, REG_P1);                                 // test p1,p1
1611      emit_mov_r32_r32(DRCTOP, REG_P4, REG_P1);                                 // mov  p4,p1d
1612      emit_jcc_near_link(DRCTOP, COND_S, &handle_kernel);                           // js   handle_kernel
1613      continue_mapped = drc->cache_top;                                    // continue_mapped:
1614      emit_mov_r32_r32(DRCTOP, REG_V5, REG_P1);                                 // mov  v5,p1
1615      emit_shr_r32_imm(DRCTOP, REG_P1, 12);                                    // shr  p1,12
1616      emit_mov_r32_m32(DRCTOP, REG_P1, MDRCISD(mips3.core->tlb_table, REG_P1, 4, 0));      // mov  p1,tlb_table[p1*4]
1617      emit_and_r32_imm(DRCTOP, REG_P4, 0xfff);                                 // and  p4,0xfff
1618      emit_shr_r32_imm(DRCTOP, REG_P1, (flags & ARW_WRITE) ? 1 : 2);                  // shr  p1,2/1 (read/write)
1619      emit_lea_r32_m32(DRCTOP, REG_P1, MBISD(REG_P4, REG_P1, (flags & ARW_WRITE) ? 2 : 4, 0));
1620                                                                     // lea  p1,[p4 + p1 * 4/2 (read/write)]
1621      emit_jcc_near_link(DRCTOP, COND_C, &page_fault);                           // jc   page_fault
1622   }
1623
1624   /* if the base is non-zero, this is a cached/uncached direct-mapped case; no translation necessary */
1625   /* just subtract the base from the address to get the physcial address */
1626   else
1627      emit_sub_r32_imm(DRCTOP, REG_P1, base);                                    // sub  p1,base
1628
1629   /* iterate over all fast RAM ranges looking for matches that can be handled directly */
1630   for (ramnum = 0; ramnum < MIPS3_MAX_FASTRAM; ramnum++)
1631   {
1632      const fast_ram_info *raminfo = &mips3.fastram[ramnum];
1633      if (!COMPARE_AGAINST_C && !Machine->debug_mode && raminfo->base != NULL && (!(flags & ARW_WRITE) || !raminfo->readonly))
1634      {
1635         emit_link notram1 = { 0 }, notram2 = { 0 };
1636
1637         /* if we have an end, check it first */
1638         if (raminfo->end != 0xffffffff)
1639         {
1640            emit_cmp_r32_imm(DRCTOP, REG_P1, raminfo->end);                        // cmp  p1,fastram_end
1641            emit_jcc_short_link(DRCTOP, COND_A, &notram1);                        // ja   notram1
1642         }
1643
1644         /* if we have a non-0 start, check it next */
1645         if (raminfo->start != 0x00000000)
1646         {
1647            emit_cmp_r32_imm(DRCTOP, REG_P1, raminfo->start);                     // cmp  p1,fastram_start
1648            emit_jcc_short_link(DRCTOP, COND_B, &notram2);                        // jb   notram2
1649         }
1650
1651         /* handle a fast RAM read */
1652         if (!(flags & ARW_WRITE))
1653         {
1654            append_direct_ram_read(drc, size, flags, raminfo->base, raminfo->start);   // <direct read>
1655            emit_ret(DRCTOP);                                             // ret
1656         }
1657
1658         /* handle a fast RAM write */
1659         else
1660         {
1661            append_direct_ram_write(drc, size, flags, raminfo->base, raminfo->start);   // <direct write>
1662            emit_ret(DRCTOP);                                             // ret
1663         }
1664
1665         /* resolve links that skipped over us */
1666         if (raminfo->end != 0xffffffff)
1667            resolve_link(DRCTOP, &notram1);                                 // notram1:
1668         if (raminfo->start != 0x00000000)
1669            resolve_link(DRCTOP, &notram2);                                 // notram2:
1670      }
1671   }
1672
1673   /* failed to find it in fast RAM; make sure we are within our expected range */
1674   if (base != 0)
1675   {
1676      emit_cmp_r32_imm(DRCTOP, REG_P1, 0x20000000);                              // cmp  p1,0x20000000
1677      emit_jcc_short_link(DRCTOP, COND_AE, &wrong_handler);                        // jae  wrong_handler
1678   }
1679
1680   /* handle a write */
1681   if (flags & ARW_WRITE)
1682   {
1683      if (size == 1)
1684         emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.writebyte));                  // jmp  writebyte
1685      else if (size == 2)
1686         emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.writehalf));                  // jmp  writehalf
1687      else if (size == 4)
1688      {
1689         if (!(flags & ARW_MASKED))
1690            emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.writeword));               // jmp  writeword
1691         else
1692            emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.writeword_masked));         // jmp  writeword_masked
1693      }
1694      else
1695      {
1696         if (!(flags & ARW_MASKED))
1697            emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.writedouble));            // jmp  writedouble
1698         else
1699            emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.writedouble_masked));         // jmp  writedouble_masked
1700      }
1701   }
1702
1703   /* handle a read */
1704   else
1705   {
1706      if (size == 1)
1707      {
1708         emit_sub_r64_imm(DRCTOP, REG_RSP, 0x28);                              // sub   rsp,0x28
1709         emit_call_m64(DRCTOP, MDRC(&mips3.core->memory.readbyte));                  // call  readbyte
1710         if (flags & ARW_SIGNED)
1711            emit_movsx_r64_r8(DRCTOP, REG_RAX, REG_AL);                           // movsx rax,al
1712         else
1713            emit_movzx_r64_r8(DRCTOP, REG_RAX, REG_AL);                           // movzx rax,al
1714         emit_add_r64_imm(DRCTOP, REG_RSP, 0x28);                              // add   rsp,0x28
1715         emit_ret(DRCTOP);                                                // ret
1716      }
1717      else if (size == 2)
1718      {
1719         emit_sub_r64_imm(DRCTOP, REG_RSP, 0x28);                              // sub   rsp,0x28
1720         emit_call_m64(DRCTOP, MDRC(&mips3.core->memory.readhalf));                  // call  readhalf
1721         if (flags & ARW_SIGNED)
1722            emit_movsx_r64_r16(DRCTOP, REG_RAX, REG_AX);                        // movsx rax,ax
1723         else
1724            emit_movzx_r64_r16(DRCTOP, REG_RAX, REG_AX);                        // movzx rax,ax
1725         emit_add_r64_imm(DRCTOP, REG_RSP, 0x28);                              // add   rsp,0x28
1726         emit_ret(DRCTOP);                                                // ret
1727      }
1728      else if (size == 4)
1729      {
1730         if (!(flags & ARW_MASKED))
1731         {
1732            if (!(flags & ARW_SIGNED))
1733               emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.readword));            // jmp  readword
1734            else
1735            {
1736               emit_sub_r64_imm(DRCTOP, REG_RSP, 0x28);                        // sub  rsp,0x28
1737               emit_call_m64(DRCTOP, MDRC(&mips3.core->memory.readword));            // call readword
1738               emit_movsxd_r64_r32(DRCTOP, REG_RAX, REG_EAX);                     // movsxd rax,eax
1739               emit_add_r64_imm(DRCTOP, REG_RSP, 0x28);                        // add  rsp,0x28
1740               emit_ret(DRCTOP);                                          // ret
1741            }
1742         }
1743         else
1744            emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.readword_masked));         // jmp  readword_masked
1745      }
1746      else
1747      {
1748         if (!(flags & ARW_MASKED))
1749            emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.readdouble));               // jmp  readdouble
1750         else
1751            emit_jmp_m64(DRCTOP, MDRC(&mips3.core->memory.readdouble_masked));         // jmp  readdouble_masked
1752      }
1753   }
1754
1755   /* handle wrong handlers */
1756   if (base == 0)
1757   {
1758      resolve_link(DRCTOP, &handle_kernel);                                 // handle_kernel:
1759      emit_cmp_r32_imm(DRCTOP, REG_P1, 0xc0000000);                              // cmp  p1,0xc0000000
1760      emit_jcc(DRCTOP, COND_AE, continue_mapped);                                 // jae  continue_mapped
1761      emit_test_r32_imm(DRCTOP, REG_P1, 0x20000000);                              // test p1,0x20000000
1762      emit_cmovcc_r64_m64(DRCTOP, COND_Z, REG_RAX, MDRCD(&mips3.drcdata->cached, ptroffs));
1763                                                                     // mov  rax,<cached version>
1764      emit_cmovcc_r64_m64(DRCTOP, COND_NZ, REG_RAX, MDRCD(&mips3.drcdata->uncached, ptroffs));
1765                                                                     // mov  rax,<uncached version>
1766      emit_mov_r64_m64(DRCTOP, REG_P4, MBD(REG_RSP, 0));                           // mov  p4,[rsp]
1767      emit_push_r64(DRCTOP, REG_RAX);                                          // push rax
1768      emit_sub_r64_r64(DRCTOP, REG_RAX, REG_P4);                                 // sub  rax,p4
1769      emit_mov_m32_r32(DRCTOP, MBD(REG_P4, -4), REG_EAX);                           // mov  [p4-4],eax
1770      emit_ret(DRCTOP);                                                   // ret
1771   }
1772   else
1773   {
1774      resolve_link(DRCTOP, &wrong_handler);                                 // wrong_handler:
1775      emit_mov_r64_m64(DRCTOP, REG_RAX, MDRCD(&mips3.drcdata->general, ptroffs));
1776                                                                     // mov  rax,<general version>
1777      emit_mov_r64_m64(DRCTOP, REG_P4, MBD(REG_RSP, 0));                           // mov  p4,[rsp]
1778      emit_push_r64(DRCTOP, REG_RAX);                                          // push rax
1779      emit_sub_r64_r64(DRCTOP, REG_RAX, REG_P4);                                 // sub  rax,p4
1780      emit_mov_m32_r32(DRCTOP, MBD(REG_P4, -4), REG_EAX);                           // mov  [p4-4],eax
1781      emit_add_r32_imm(DRCTOP, REG_P1, base);                                    // add  p1,base
1782      emit_ret(DRCTOP);                                                   // ret
1783   }
1784
1785   /* handle page faults */
1786   if (base == 0)
1787   {
1788      resolve_link(DRCTOP, &page_fault);                                    // page_fault:
1789      emit_mov_r32_r32(DRCTOP, REG_P2, REG_V5);                                 // mov  p2,v5
1790      emit_jmp(DRCTOP, mips3.drcdata->find_exception_handler);                     // jmp  find_exception_handler
1791   }
1792}
1793
1794
1795/*------------------------------------------------------------------
1796    append_explode_ccr31
1797------------------------------------------------------------------*/
1798
1799static void append_explode_ccr31(drc_core *drc)
1800{
1801   emit_link link1;
1802   int i;
1803
1804   /* new CCR31 value in EAX */
1805   emit_test_r32_imm(DRCTOP, REG_EAX, 1 << 23);                                 // test eax,1 << 23
1806   emit_mov_m32_r32(DRCTOP, CCR1ADDR(31), REG_EAX);                              // mov  ccr[31],eax
1807   emit_setcc_m8(DRCTOP, COND_NZ, CF1ADDR(0));                                    // setnz fcc[0]
1808   if (mips3.core->flavor >= MIPS3_TYPE_MIPS_IV)
1809      for (i = 1; i <= 7; i++)
1810      {
1811         emit_test_r32_imm(DRCTOP, REG_EAX, 1 << (24 + i));                        // test eax,1 << (24+i)
1812         emit_setcc_m8(DRCTOP, COND_NZ, CF1ADDR(i));                              // setnz fcc[i]
1813      }
1814   emit_and_r32_imm(DRCTOP, REG_EAX, 3);                                       // and  eax,3
1815   emit_test_r32_imm(DRCTOP, REG_EAX, 1);                                       // test eax,1
1816   emit_jcc_near_link(DRCTOP, COND_Z, &link1);                                    // jz   skip
1817   emit_xor_r32_imm(DRCTOP, REG_EAX, 2);                                       // xor  eax,2
1818   resolve_link(DRCTOP, &link1);                                          // skip:
1819   drc_append_set_sse_rounding(drc, REG_EAX);                                    // set_rounding(EAX)
1820   emit_ret(DRCTOP);                                                      // ret
1821}
1822
1823
1824/*------------------------------------------------------------------
1825    append_recover_ccr31
1826------------------------------------------------------------------*/
1827
1828static void append_recover_ccr31(drc_core *drc)
1829{
1830   int i;
1831
1832   emit_movsxd_r64_m32(DRCTOP, REG_RAX, CCR1ADDR(31));                              // movsxd rax,ccr1[rd]
1833   emit_and_r64_imm(DRCTOP, REG_RAX, ~0xfe800000);                                 // and  rax,~0xfe800000
1834   emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                                    // xor  edx,edx
1835   emit_cmp_m8_imm(DRCTOP, CF1ADDR(0), 0);                                       // cmp  fcc[0],0
1836   emit_setcc_r8(DRCTOP, COND_NZ, REG_DL);                                       // setnz dl
1837   emit_shl_r32_imm(DRCTOP, REG_EDX, 23);                                       // shl  edx,23
1838   emit_or_r64_r64(DRCTOP, REG_RAX, REG_RDX);                                    // or   rax,rdx
1839   if (mips3.core->flavor >= MIPS3_TYPE_MIPS_IV)
1840      for (i = 1; i <= 7; i++)
1841      {
1842         emit_cmp_m8_imm(DRCTOP, CF1ADDR(i), 0);                                 // cmp  fcc[i],0
1843         emit_setcc_r8(DRCTOP, COND_NZ, REG_DL);                                 // setnz dl
1844         emit_shl_r32_imm(DRCTOP, REG_EDX, 24+i);                              // shl  edx,24+i
1845         emit_or_r64_r64(DRCTOP, REG_RAX, REG_RDX);                              // or   rax,rdx
1846      }
1847   emit_ret(DRCTOP);                                                      // ret
1848}
1849
1850
1851/*------------------------------------------------------------------
1852    append_check_interrupts
1853------------------------------------------------------------------*/
1854
1855static void append_check_interrupts(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
1856{
1857   emit_link link1, link2, link3 = { 0 };
1858
1859   emit_mov_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Cause));                        // mov  eax,[Cause]
1860   emit_and_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Status));                        // and  eax,[Status]
1861   emit_and_r32_imm(DRCTOP, REG_EAX, 0xfc00);                                    // and  eax,0xfc00
1862   emit_jcc_short_link(DRCTOP, COND_Z, &link1);                                 // jz   skip
1863   emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_IE);                        // test [Status],SR_IE
1864   emit_jcc_short_link(DRCTOP, COND_Z, &link2);                                 // jz   skip
1865   emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_EXL | SR_ERL);                  // test [Status],SR_EXL | SR_ERL
1866   if (desc == NULL)
1867   {
1868      emit_mov_r32_m32(DRCTOP, REG_P1, MDRC(drc->pcptr));                           // mov  p1,[pc]
1869      emit_jcc_short_link(DRCTOP, COND_NZ, &link3);                              // jnz  skip
1870      emit_jmp_m64(DRCTOP, MDRC(&mips3.drcdata->generate_interrupt_exception));         // jmp  generate_interrupt_exception
1871   }
1872   else
1873      oob_request_callback(drc, COND_Z, oob_interrupt_cleanup, compiler, desc, mips3.drcdata->generate_interrupt_exception);
1874   resolve_link(DRCTOP, &link1);                                          // skip:
1875   resolve_link(DRCTOP, &link2);
1876   if (desc == NULL)
1877      resolve_link(DRCTOP, &link3);
1878}
1879
1880
1881
1882/***************************************************************************
1883    RECOMPILATION HELPERS
1884***************************************************************************/
1885
1886/*-------------------------------------------------
1887    emit_load_register_value - load a register
1888    either as a constant or as a register
1889-------------------------------------------------*/
1890
1891static void emit_load_register_value(drc_core *drc, compiler_state *compiler, UINT8 dstreg, mipsreg_state regstate)
1892{
1893   /* must be live or constant */
1894   assert(ISCONST(regstate) || ISLIVE(regstate));
1895
1896   /* if the register is constant, do an immediate load */
1897   if (ISCONST(regstate))
1898   {
1899      INT32 mipsval = CONSTVAL(regstate);
1900      if (mipsval != 0)
1901         emit_mov_r64_imm(DRCTOP, dstreg, mipsval);
1902      else
1903         emit_xor_r32_r32(DRCTOP, dstreg, dstreg);
1904   }
1905
1906   /* otherwise, load from the allocated register, but only if different */
1907   else
1908   {
1909      UINT8 srcreg = X86REG(regstate);
1910      if (dstreg != srcreg)
1911         emit_mov_r64_r64(DRCTOP, dstreg, srcreg);
1912   }
1913}
1914
1915
1916/*-------------------------------------------------
1917    emit_set_constant_value - set a constant
1918    value; if it is too large, allocate a
1919    register and populate it
1920-------------------------------------------------*/
1921
1922static void emit_set_constant_value(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 mipsreg, UINT64 constval)
1923{
1924   /* ignore reigster 0 destination */
1925   if (mipsreg == 0)
1926      return;
1927
1928   /* if we fit in 32-bits, just continue the constant charade */
1929   if ((INT32)constval == (INT64)constval)
1930      compiler_register_set_constant(compiler, mipsreg, constval);
1931
1932   /* otherwise, allocate a new register and move the result into it */
1933   else
1934   {
1935      mipsreg_state resultreg = compiler_register_allocate(drc, compiler, desc, mipsreg, ALLOC_DST | ALLOC_DIRTY);
1936      emit_mov_r64_imm(DRCTOP, X86REG(resultreg), constval);                        // mov  <rt>,result
1937   }
1938}
1939
1940
1941/*------------------------------------------------------------------
1942    emit_flush_cycles_before_instruction
1943------------------------------------------------------------------*/
1944
1945static void emit_flush_cycles_before_instruction(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT32 cycles_to_leave)
1946{
1947   /* if we have cycles, subtract them now */
1948   if (compiler->cycles - cycles_to_leave != 0)
1949      emit_sub_m32_imm(DRCTOP, ICOUNTADDR, compiler->cycles - cycles_to_leave);         // sub  [icount],cycles
1950
1951   /* clear out compiler counts */
1952   compiler->cycles = cycles_to_leave;
1953}
1954
1955
1956/*------------------------------------------------------------------
1957    emit_update_cycles_pc_and_flush
1958------------------------------------------------------------------*/
1959
1960static void emit_update_cycles_pc_and_flush(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, offs_t destpc)
1961{
1962   /* if we have cycles, subtract them now */
1963   emit_sub_m32_imm(DRCTOP, ICOUNTADDR, compiler->cycles);                           // sub  [icount],cycles
1964
1965   /* clear out compiler counts */
1966   compiler->cycles = 0;
1967
1968   /* if we have an opcode descriptor, make this an oob */
1969   if (desc != NULL)
1970      oob_request_callback(drc, COND_S, oob_interrupt_cleanup, compiler, desc, mips3.drc->exit_point);
1971
1972   /* otherwise, do it inline */
1973   else
1974   {
1975      /* load the target PC into P1 */
1976      if (destpc != BRANCH_TARGET_DYNAMIC)
1977         emit_mov_r32_imm(DRCTOP, REG_P1, destpc);                              // mov  p1,destpc
1978      else
1979         emit_mov_r32_m32(DRCTOP, REG_P1, MBD(REG_RSP, SPOFFS_NEXTPC));               // mov  p1,[esp+nextpc]
1980
1981      /* flush any live registers */
1982      compiler_register_flush_all(drc, compiler);
1983
1984      /* if we subtracted cycles and went negative, time to exit */
1985      emit_jcc(DRCTOP, COND_S, mips3.drc->exit_point);                           // js   exit_point
1986   }
1987}
1988
1989
1990/*------------------------------------------------------------------
1991    emit_delay_slot_and_branch
1992------------------------------------------------------------------*/
1993
1994static void emit_delay_slot_and_branch(drc_core *drc, const compiler_state *compiler, const opcode_desc *desc, UINT8 linkreg)
1995{
1996   compiler_state compiler_temp = *compiler;
1997
1998   /* set the link if needed */
1999   if (linkreg != 0)
2000      compiler_register_set_constant(&compiler_temp, linkreg, (INT32)(desc->pc + 8));      // <link> = pc + 8
2001
2002   /* compile the delay slot using temporary compiler state */
2003   assert(desc->delay != NULL);
2004   compile_one(drc, &compiler_temp, desc->delay);                                 // <next instruction>
2005
2006   /* update the cycles and load the new PC in case we need to stop here */
2007   emit_update_cycles_pc_and_flush(drc, &compiler_temp, NULL, desc->targetpc);
2008
2009   /* otherwise, append a dispatcher */
2010   if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
2011      drc_append_tentative_fixed_dispatcher(drc, desc->targetpc, FALSE);               // <redispatch>
2012   else
2013      drc_append_dispatcher(drc);                                             // <redispatch>
2014}
2015
2016
2017/*------------------------------------------------------------------
2018    emit_fixed_byte_read
2019------------------------------------------------------------------*/
2020
2021static int emit_fixed_byte_read(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 destreg, int is_unsigned, offs_t address)
2022{
2023   void *fastram = fastram_ptr(address, 1, FALSE);
2024
2025   /* if we can't do fast RAM, we need to make the call */
2026   if (fastram == NULL)
2027   {
2028      emit_mov_r32_imm(DRCTOP, REG_P1, address);                                 // mov  p1,address
2029      if (is_unsigned)
2030         emit_call(DRCTOP, mips3.drcdata->general.read_byte_unsigned);               // call read_byte_unsigned
2031      else
2032         emit_call(DRCTOP, mips3.drcdata->general.read_byte_signed);                  // call read_byte_signed
2033
2034      /* handle exceptions */
2035      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
2036      if (destreg != REG_RAX)
2037         emit_mov_r64_r64(DRCTOP, destreg, REG_RAX);                              // mov  <rt>,rax
2038   }
2039
2040   /* if we can do fastram, emit the right form */
2041   else
2042   {
2043      INT64 fastdisp = (UINT8 *)fastram - (UINT8 *)drc->baseptr;
2044      int raxrel = ((INT32)fastdisp != fastdisp);
2045
2046      /* if we can't fit the delta to fastram within an INT32, load RAX with the full address here */
2047      if (raxrel)
2048      {
2049         emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                        // mov  rax,fastram
2050         if (is_unsigned)
2051            emit_movzx_r64_m8(DRCTOP, destreg, MBD(REG_RAX, 0));                  // movzx destreg,byte ptr [rax]
2052         else
2053            emit_movsx_r64_m8(DRCTOP, destreg, MBD(REG_RAX, 0));                  // movsx destreg,byte ptr [rax]
2054      }
2055
2056      /* read drc-relative */
2057      else
2058      {
2059         if (is_unsigned)
2060            emit_movzx_r64_m8(DRCTOP, destreg, MDRC(fastram));                     // movzx destreg,byte ptr [p1 + adjbase]
2061         else
2062            emit_movsx_r64_m8(DRCTOP, destreg, MDRC(fastram));                     // movsx destreg,byte ptr [p1 + adjbase]
2063      }
2064   }
2065   return (fastram != NULL);
2066}
2067
2068
2069/*------------------------------------------------------------------
2070    emit_fixed_half_read
2071------------------------------------------------------------------*/
2072
2073static int emit_fixed_half_read(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 destreg, int is_unsigned, offs_t address)
2074{
2075   void *fastram = fastram_ptr(address & ~1, 2, FALSE);
2076
2077   /* if we can't do fast RAM, we need to make the call */
2078   if (fastram == NULL)
2079   {
2080      emit_mov_r32_imm(DRCTOP, REG_P1, address & ~1);                              // mov  p1,address & ~1
2081      if (is_unsigned)
2082         emit_call(DRCTOP, mips3.drcdata->general.read_half_unsigned);               // call read_half_unsigned
2083      else
2084         emit_call(DRCTOP, mips3.drcdata->general.read_half_signed);                  // call read_half_signed
2085
2086      /* handle exceptions */
2087      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
2088      if (destreg != REG_RAX)
2089         emit_mov_r64_r64(DRCTOP, destreg, REG_RAX);                              // mov  <rt>,rax
2090   }
2091
2092   /* if we can do fastram, emit the right form */
2093   else
2094   {
2095      INT64 fastdisp = (UINT8 *)fastram - (UINT8 *)drc->baseptr;
2096      int raxrel = ((INT32)fastdisp != fastdisp);
2097
2098      /* read rax-relative */
2099      if (raxrel)
2100      {
2101         emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                        // mov  rax,fastram
2102         if (is_unsigned)
2103            emit_movzx_r64_m16(DRCTOP, destreg, MBD(REG_RAX, 0));                  // movzx destreg,word ptr [rax]
2104         else
2105            emit_movsx_r64_m16(DRCTOP, destreg, MBD(REG_RAX, 0));                  // movsx destreg,word ptr [rax]
2106      }
2107
2108      /* read drc-relative */
2109      else
2110      {
2111         if (is_unsigned)
2112            emit_movzx_r64_m16(DRCTOP, destreg, MDRC(fastram));                     // movzx destreg,word ptr [p1 + adjbase]
2113         else
2114            emit_movsx_r64_m16(DRCTOP, destreg, MDRC(fastram));                     // movsx destreg,word ptr [p1 + adjbase]
2115      }
2116   }
2117   return (fastram != NULL);
2118}
2119
2120
2121/*------------------------------------------------------------------
2122    emit_fixed_word_read
2123------------------------------------------------------------------*/
2124
2125static int emit_fixed_word_read(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 destreg, int is_unsigned, offs_t address, UINT32 mask)
2126{
2127   void *fastram = fastram_ptr(address & ~3, 4, FALSE);
2128
2129   /* if we can't do fast RAM, we need to make the call */
2130   if (fastram == NULL)
2131   {
2132      emit_mov_r32_imm(DRCTOP, REG_P1, address & ~3);                              // mov  p1,address & ~3
2133      if (mask != 0xffffffff)
2134      {
2135         emit_mov_r32_imm(DRCTOP, REG_P2, (INT32)mask);                           // mov  p2,mask
2136         emit_call(DRCTOP, mips3.drcdata->general.read_word_masked);                  // call read_word_masked
2137      }
2138      else if (is_unsigned)
2139         emit_call(DRCTOP, mips3.drcdata->general.read_word_unsigned);               // call read_word_unsigned
2140      else
2141         emit_call(DRCTOP, mips3.drcdata->general.read_word_signed);                  // call read_word_signed
2142
2143      /* handle exceptions */
2144      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
2145      if (destreg != REG_RAX)
2146         emit_mov_r64_r64(DRCTOP, destreg, REG_RAX);                              // mov  <rt>,rax
2147   }
2148
2149   /* if we can do fastram, emit the right form */
2150   else
2151   {
2152      INT64 fastdisp = (UINT8 *)fastram - (UINT8 *)drc->baseptr;
2153      int raxrel = ((INT32)fastdisp != fastdisp);
2154
2155      /* if we can't fit the delta to fastram within an INT32, load RAX with the full address here */
2156      if (raxrel)
2157      {
2158         emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                        // mov  rax,fastram
2159         if (is_unsigned)
2160            emit_mov_r32_m32(DRCTOP, destreg, MBD(REG_RAX, 0));                     // mov   destreg,word ptr [rax]
2161         else
2162            emit_movsxd_r64_m32(DRCTOP, destreg, MBD(REG_RAX, 0));                  // movsxd destreg,dword ptr [rax]
2163      }
2164
2165      /* read drc-relative */
2166      else
2167      {
2168         if (is_unsigned)
2169            emit_mov_r32_m32(DRCTOP, destreg, MDRC(fastram));                     // mov   destreg,word ptr [p1 + adjbase]
2170         else
2171            emit_movsxd_r64_m32(DRCTOP, destreg, MDRC(fastram));                  // movsxd destreg,dword ptr [p1 + adjbase]
2172      }
2173   }
2174   return (fastram != NULL);
2175}
2176
2177
2178/*------------------------------------------------------------------
2179    emit_fixed_double_read
2180------------------------------------------------------------------*/
2181
2182static int emit_fixed_double_read(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 destreg, offs_t address, UINT64 mask)
2183{
2184   void *fastram = fastram_ptr(address & ~7, 8, FALSE);
2185
2186   /* if we can't do fast RAM, we need to make the call */
2187   if (fastram == NULL)
2188   {
2189      emit_mov_r32_imm(DRCTOP, REG_P1, address & ~7);                              // mov  p1,address & ~7
2190      if (mask != U64(0xffffffffffffffff))
2191      {
2192         emit_mov_r64_imm(DRCTOP, REG_P2, mask);                                 // mov  p2,mask
2193         emit_call(DRCTOP, mips3.drcdata->general.read_double_masked);               // call read_double_masked
2194      }
2195      else
2196         emit_call(DRCTOP, mips3.drcdata->general.read_double);                     // call read_double
2197
2198      /* handle exceptions */
2199      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
2200      if (destreg != REG_RAX)
2201         emit_mov_r64_r64(DRCTOP, destreg, REG_RAX);                              // mov  <rt>,rax
2202   }
2203
2204   /* if we can do fastram, emit the right form */
2205   else
2206   {
2207      INT64 fastdisp = (UINT8 *)fastram - (UINT8 *)drc->baseptr;
2208      int raxrel = ((INT32)fastdisp != fastdisp);
2209
2210      /* if we can't fit the delta to fastram within an INT32, load RAX with the full address here */
2211      if (raxrel)
2212      {
2213         emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                        // mov  rax,fastram
2214         emit_mov_r64_m64(DRCTOP, destreg, MBD(REG_RAX, 0));                        // mov  destreg,[rax]
2215      }
2216
2217      /* read drc-relative */
2218      else
2219         emit_mov_r64_m64(DRCTOP, destreg, MDRC(fastram));                        // mov  destreg,[p1 + adjbase]
2220
2221      /* adjust for endianness */
2222      if (mips3.core->bigendian)
2223         emit_ror_r64_imm(DRCTOP, destreg, 32);                                 // ror  destreg,32
2224   }
2225   return (fastram != NULL);
2226}
2227
2228
2229/*------------------------------------------------------------------
2230    emit_fixed_byte_write
2231------------------------------------------------------------------*/
2232
2233static int emit_fixed_byte_write(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, mipsreg_state srcreg, offs_t address)
2234{
2235   void *fastram = fastram_ptr(address, 1, TRUE);
2236
2237   assert(ISCONST(srcreg) || X86REG(srcreg != REG_P1));
2238
2239   /* if we can't do fast RAM, we need to make the call */
2240   if (fastram == NULL)
2241   {
2242      emit_mov_r32_imm(DRCTOP, REG_P1, address);                                 // mov  p1,address
2243      if (ISCONST(srcreg))
2244         emit_mov_r64_imm(DRCTOP, REG_P2, CONSTVAL(srcreg));                        // mov  p2,<srcreg>
2245      else if (X86REG(srcreg) != REG_P2)
2246         emit_mov_r64_r64(DRCTOP, REG_P2, X86REG(srcreg));                        // mov  p2,<srcreg>
2247      emit_call(DRCTOP, mips3.drcdata->general.write_byte);                        // call write_byte
2248
2249      /* handle exceptions */
2250      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
2251   }
2252
2253   /* if we can do fastram, emit the right form */
2254   else
2255   {
2256      INT64 fastdisp = (UINT8 *)fastram - (UINT8 *)drc->baseptr;
2257      int raxrel = ((INT32)fastdisp != fastdisp);
2258
2259      /* if we can't fit the delta to fastram within an INT32, load RAX with the full address here */
2260      if (raxrel)
2261      {
2262         emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                        // mov  rax,fastram
2263         if (ISCONST(srcreg))
2264            emit_mov_m8_imm(DRCTOP, MBD(REG_RAX, 0), CONSTVAL(srcreg));               // mov  [rax],constval
2265         else
2266            emit_mov_m8_r8(DRCTOP, MBD(REG_RAX, 0), X86REG(srcreg));               // mov  [rax],<srcreg>
2267      }
2268
2269      /* write drc-relative */
2270      else
2271      {
2272         if (ISCONST(srcreg))
2273            emit_mov_m8_imm(DRCTOP, MDRC(fastram), CONSTVAL(srcreg));               // mov  [fastram],constval
2274         else
2275            emit_mov_m8_r8(DRCTOP, MDRC(fastram), X86REG(srcreg));                  // mov  [fastram],srcreg
2276      }
2277   }
2278   return (fastram != NULL);
2279}
2280
2281
2282/*------------------------------------------------------------------
2283    emit_fixed_half_write
2284------------------------------------------------------------------*/
2285
2286static int emit_fixed_half_write(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, mipsreg_state srcreg, offs_t address)
2287{
2288   void *fastram = fastram_ptr(address & ~1, 2, TRUE);
2289
2290   assert(ISCONST(srcreg) || X86REG(srcreg) != REG_P1);
2291
2292   /* if we can't do fast RAM, we need to make the call */
2293   if (fastram == NULL)
2294   {
2295      emit_mov_r32_imm(DRCTOP, REG_P1, address & ~1);                              // mov  p1,address & ~1
2296      if (ISCONST(srcreg))
2297         emit_mov_r64_imm(DRCTOP, REG_P2, CONSTVAL(srcreg));                        // mov  p2,constval
2298      else if (X86REG(srcreg) != REG_P2)
2299         emit_mov_r64_r64(DRCTOP, REG_P2, X86REG(srcreg));                        // mov  p2,srcreg
2300      emit_call(DRCTOP, mips3.drcdata->general.write_half);                        // call write_half
2301
2302      /* handle exceptions */
2303      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
2304   }
2305
2306   /* if we can do fastram, emit the right form */
2307   else
2308   {
2309      INT64 fastdisp = (UINT8 *)fastram - (UINT8 *)drc->baseptr;
2310      int raxrel = ((INT32)fastdisp != fastdisp);
2311
2312      /* if we can't fit the delta to fastram within an INT32, load RAX with the full address here */
2313      if (raxrel)
2314      {
2315         emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                        // mov  rax,fastram
2316         if (ISCONST(srcreg))
2317            emit_mov_m16_imm(DRCTOP, MBD(REG_RAX, 0), CONSTVAL(srcreg));            // mov  [rax],constval
2318         else
2319            emit_mov_m16_r16(DRCTOP, MBD(REG_RAX, 0), X86REG(srcreg));               // mov  [rax],srcreg
2320      }
2321
2322      /* write drc-relative */
2323      else
2324      {
2325         if (ISCONST(srcreg))
2326            emit_mov_m16_imm(DRCTOP, MDRC(fastram), CONSTVAL(srcreg));               // mov  [fastram],constval
2327         else
2328            emit_mov_m16_r16(DRCTOP, MDRC(fastram), X86REG(srcreg));               // mov  [fastram],srcreg
2329      }
2330   }
2331   return (fastram != NULL);
2332}
2333
2334
2335/*------------------------------------------------------------------
2336    emit_fixed_word_write
2337------------------------------------------------------------------*/
2338
2339static int emit_fixed_word_write(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, mipsreg_state srcreg, offs_t address, UINT32 mask)
2340{
2341   void *fastram = fastram_ptr(address & ~3, 4, TRUE);
2342
2343   assert(ISCONST(srcreg) || X86REG(srcreg) != REG_P1);
2344   assert(ISCONST(srcreg) || X86REG(srcreg) != REG_P3);
2345
2346   /* if we can't do fast RAM, we need to make the call */
2347   if (fastram == NULL)
2348   {
2349      emit_mov_r32_imm(DRCTOP, REG_P1, address & ~3);                              // mov  p1,address & ~3
2350      if (ISCONST(srcreg))
2351         emit_mov_r64_imm(DRCTOP, REG_P2, CONSTVAL(srcreg));                        // mov  p2,constval
2352      else if (X86REG(srcreg) != REG_P2)
2353         emit_mov_r64_r64(DRCTOP, REG_P2, X86REG(srcreg));                        // mov  p2,srcreg
2354      if (mask == 0xffffffff)
2355         emit_call(DRCTOP, mips3.drcdata->general.write_word);                     // call write_word
2356      else
2357      {
2358         emit_mov_r32_imm(DRCTOP, REG_P3, mask);                                 // mov  p3,mask
2359         emit_call(DRCTOP, mips3.drcdata->general.write_word_masked);               // call write_word_masked
2360      }
2361
2362      /* handle exceptions */
2363      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
2364   }
2365
2366   /* if we can do fastram, emit the right form */
2367   else
2368   {
2369      INT64 fastdisp = (UINT8 *)fastram - (UINT8 *)drc->baseptr;
2370      int raxrel = ((INT32)fastdisp != fastdisp);
2371
2372      /* non-masked case */
2373      if (mask == 0xffffffff)
2374      {
2375         /* if we can't fit the delta to fastram within an INT32, load RAX with the full address here */
2376         if (raxrel)
2377         {
2378            emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                     // mov  rax,fastram
2379            if (ISCONST(srcreg))
2380               emit_mov_m32_imm(DRCTOP, MBD(REG_RAX, 0), CONSTVAL(srcreg));         // mov  [rax],constval
2381            else
2382               emit_mov_m32_r32(DRCTOP, MBD(REG_RAX, 0), X86REG(srcreg));            // mov  [rax],srcreg
2383         }
2384
2385         /* write drc-relative */
2386         else
2387         {
2388            if (ISCONST(srcreg))
2389               emit_mov_m32_imm(DRCTOP, MDRC(fastram), CONSTVAL(srcreg));            // mov  [fastram],constval
2390            else
2391               emit_mov_m32_r32(DRCTOP, MDRC(fastram), X86REG(srcreg));            // mov  [fastram],srcreg
2392         }
2393      }
2394
2395      /* masked case */
2396      else
2397      {
2398         if (raxrel)
2399            emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                     // mov  rax,fastram
2400         else
2401            emit_lea_r64_m64(DRCTOP, REG_RAX, MDRC(fastram));                     // lea   rax,[fastram]
2402
2403         /* always write rax-relative */
2404         if (ISCONST(srcreg))
2405         {
2406            emit_mov_r32_m32(DRCTOP, REG_P2, MBD(REG_RAX, 0));                     // mov  p2,[rax]
2407            emit_and_r32_imm(DRCTOP, REG_P2, ~mask);                           // and  p2,~mask
2408            emit_or_r32_imm(DRCTOP, REG_P2, CONSTVAL(srcreg) & mask);               // or   p2,constval & mask
2409            emit_mov_m32_r32(DRCTOP, MBD(REG_RAX, 0), REG_P2);                     // mov  [rax],p2
2410         }
2411         else
2412         {
2413            emit_mov_r32_m32(DRCTOP, REG_P3, MBD(REG_RAX, 0));                     // mov  p3,[rax]
2414            if (X86REG(srcreg) != REG_P2)
2415               emit_mov_r32_r32(DRCTOP, REG_P2, X86REG(srcreg));                  // mov  p2,srcreg
2416            emit_and_r32_imm(DRCTOP, REG_P3, ~mask);                           // and  p3,~mask
2417            emit_and_r32_imm(DRCTOP, REG_P2, mask);                              // and  p2,mask
2418            emit_or_r32_r32(DRCTOP, REG_P3, REG_P2);                           // or   p3,p2
2419            emit_mov_m32_r32(DRCTOP, MBD(REG_RAX, 0), REG_P3);                     // mov  [rax],p3
2420         }
2421      }
2422   }
2423   return (fastram != NULL);
2424}
2425
2426
2427/*------------------------------------------------------------------
2428    emit_fixed_double_write
2429------------------------------------------------------------------*/
2430
2431static int emit_fixed_double_write(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, mipsreg_state srcreg, offs_t address, UINT64 mask)
2432{
2433   void *fastram = fastram_ptr(address & ~7, 8, TRUE);
2434
2435   assert(ISCONST(srcreg) || X86REG(srcreg) != REG_P1);
2436   assert(ISCONST(srcreg) || X86REG(srcreg) != REG_P3);
2437   assert((INT32)CONSTVAL(srcreg) == (INT64)CONSTVAL(srcreg));
2438
2439   /* if we can't do fast RAM, we need to make the call */
2440   if (fastram == NULL)
2441   {
2442      emit_mov_r32_imm(DRCTOP, REG_P1, address & ~7);                              // mov  p1,address & ~7
2443      if (ISCONST(srcreg))
2444         emit_mov_r64_imm(DRCTOP, REG_P2, CONSTVAL(srcreg));                        // mov  p2,constval
2445      else if (X86REG(srcreg) != REG_P2)
2446         emit_mov_r64_r64(DRCTOP, REG_P2, X86REG(srcreg));                        // mov  p2,srcreg
2447      if (mask == U64(0xffffffffffffffff))
2448         emit_call(DRCTOP, mips3.drcdata->general.write_double);                     // call write_double
2449      else
2450      {
2451         emit_mov_r64_imm(DRCTOP, REG_P3, mask);                                 // mov  p3,mask
2452         emit_call(DRCTOP, mips3.drcdata->general.write_double_masked);               // call write_double_masked
2453      }
2454
2455      /* handle exceptions */
2456      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
2457   }
2458
2459   /* if we can do fastram, emit the right form */
2460   else
2461   {
2462      INT64 fastdisp = (UINT8 *)fastram - (UINT8 *)drc->baseptr;
2463      int raxrel = ((INT32)fastdisp != fastdisp);
2464      INT64 constval = CONSTVAL(srcreg);
2465
2466      /* adjust values for endianness */
2467      if (mips3.core->bigendian)
2468      {
2469         if (ISCONST(srcreg))
2470            constval = (constval << 32) | (constval >> 32);
2471         else
2472         {
2473            emit_mov_r64_r64(DRCTOP, REG_P2, X86REG(srcreg));                     // mov  p2,srcreg
2474            emit_ror_r64_imm(DRCTOP, REG_P2, 32);                              // ror  p2,32
2475            srcreg = REG_P2;
2476         }
2477         mask = (mask << 32) | (mask >> 32);
2478      }
2479
2480      /* non-masked case */
2481      if (mask == U64(0xffffffffffffffff))
2482      {
2483         /* if we can't fit the delta to fastram within an INT32, load RAX with the full address here */
2484         if (raxrel)
2485         {
2486            emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                     // mov  rax,fastram
2487            if (ISCONST(srcreg))
2488               emit_mov_m64_imm(DRCTOP, MBD(REG_RAX, 0), constval);               // mov  [rax],constval
2489            else
2490               emit_mov_m64_r64(DRCTOP, MBD(REG_RAX, 0), X86REG(srcreg));            // mov  [rax],srcreg
2491         }
2492
2493         /* write drc-relative */
2494         else
2495         {
2496            if (ISCONST(srcreg))
2497               emit_mov_m64_imm(DRCTOP, MDRC(fastram), constval);                  // mov  [fastram],constval
2498            else
2499               emit_mov_m64_r64(DRCTOP, MDRC(fastram), X86REG(srcreg));                  // mov  [fastram],srcreg
2500         }
2501      }
2502
2503      /* masked case */
2504      else
2505      {
2506         if (raxrel)
2507            emit_mov_r64_imm(DRCTOP, REG_RAX, (UINT64)fastram);                     // mov  rax,fastram
2508         else
2509            emit_lea_r64_m64(DRCTOP, REG_RAX, MDRC(fastram));                     // lea  rax,[fastram]
2510         emit_mov_r64_imm(DRCTOP, REG_P4, ~mask);                              // mov  p4,~mask
2511
2512         /* always write rax-relative */
2513         if (ISCONST(srcreg))
2514         {
2515            emit_and_r64_m64(DRCTOP, REG_P4, MBD(REG_RAX, 0));                     // and  p4,[rax]
2516            emit_mov_r64_imm(DRCTOP, REG_P3, constval & mask);                     // mov  p3,constval & mask
2517            emit_or_r64_r64(DRCTOP, REG_P4, REG_P3);                           // or   p4,p3
2518            emit_mov_m64_r64(DRCTOP, MBD(REG_RAX, 0), REG_P4);                     // mov  [rax],p4
2519         }
2520         else
2521         {
2522            emit_mov_r64_m64(DRCTOP, REG_P3, MBD(REG_RAX, 0));                     // mov  p3,[rax]
2523            if (X86REG(srcreg) != REG_P2)
2524               emit_mov_r64_r64(DRCTOP, REG_P2, X86REG(srcreg));                  // mov  p2,srcreg
2525            emit_and_r64_r64(DRCTOP, REG_P3, REG_P4);                           // and  p3,p4
2526            emit_not_r64(DRCTOP, REG_P4);                                    // not  p4
2527            emit_and_r64_r64(DRCTOP, REG_P2, REG_P4);                           // and  p2,p4
2528            emit_or_r64_r64(DRCTOP, REG_P3, REG_P2);                           // or   p3,p2
2529            emit_mov_m64_r64(DRCTOP, MBD(REG_RAX, 0), REG_P3);                     // mov  [rax],p3
2530         }
2531      }
2532   }
2533   return (fastram != NULL);
2534}
2535
2536
2537
2538/***************************************************************************
2539    CORE RECOMPILATION
2540***************************************************************************/
2541
2542/*-------------------------------------------------
2543    compile_instruction - master switch statement
2544    for compiling a given opcode
2545-------------------------------------------------*/
2546
2547static int compile_instruction(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
2548{
2549   UINT32 op = *desc->opptr.l;
2550   UINT8 opswitch = op >> 26;
2551
2552   switch (opswitch)
2553   {
2554      /* ----- sub-groups ----- */
2555
2556      case 0x00:   /* SPECIAL */
2557         return compile_special(drc, compiler, desc);
2558
2559      case 0x01:   /* REGIMM */
2560         return compile_regimm(drc, compiler, desc);
2561
2562      case 0x1c:   /* IDT-specific */
2563         return compile_idt(drc, compiler, desc);
2564
2565
2566      /* ----- jumps and branches ----- */
2567
2568      case 0x02:   /* J */
2569      case 0x03:   /* JAL */
2570         emit_delay_slot_and_branch(drc, compiler, desc, (opswitch == 0x02) ? 0 : 31);   // <next instruction + redispatch>
2571         return TRUE;
2572
2573      case 0x04:   /* BEQ */
2574      case 0x14:   /* BEQL */
2575      case 0x05:   /* BNE */
2576      case 0x15:   /* BNEL */
2577         return compile_branchcc(drc, compiler, desc, (opswitch & 1) ? COND_NE : COND_E);
2578
2579      case 0x06:   /* BLEZ */
2580      case 0x16:   /* BLEZL */
2581      case 0x07:   /* BGTZ */
2582      case 0x17:   /* BGTZL */
2583         return compile_branchcz(drc, compiler, desc, (opswitch & 1) ? COND_G : COND_LE, FALSE);
2584
2585
2586      /* ----- immediate arithmetic ----- */
2587
2588      case 0x0f:   /* LUI */
2589         if (RTREG != 0)
2590            emit_set_constant_value(drc, compiler, desc, RTREG, SIMMVAL << 16);
2591         return TRUE;
2592
2593      case 0x08:   /* ADDI */
2594      case 0x09:   /* ADDIU */
2595         return compile_add(drc, compiler, desc, opswitch & 1, TRUE);
2596
2597      case 0x18:   /* DADDI */
2598      case 0x19:   /* DADDIU */
2599         return compile_dadd(drc, compiler, desc, opswitch & 1, TRUE);
2600
2601      case 0x0c:   /* ANDI */
2602      case 0x0d:   /* ORI */
2603      case 0x0e:   /* XORI */
2604         return compile_logical(drc, compiler, desc, opswitch & 3, TRUE);
2605
2606      case 0x0a:   /* SLTI */
2607      case 0x0b:   /* SLTIU */
2608         return compile_slt(drc, compiler, desc, opswitch & 1, TRUE);
2609
2610
2611      /* ----- memory load operations ----- */
2612
2613      case 0x20:   /* LB */
2614      case 0x21:   /* LH */
2615      case 0x23:   /* LW */
2616      case 0x24:   /* LBU */
2617      case 0x25:   /* LHU */
2618      case 0x27:   /* LWU */
2619         return compile_load(drc, compiler, desc, (opswitch & 3) + 1, opswitch & 4);
2620
2621      case 0x37:   /* LD */
2622         return compile_load(drc, compiler, desc, 8, FALSE);
2623
2624      case 0x31:   /* LWC1 */
2625         return compile_load_cop(drc, compiler, desc, 4, FPR32(RTREG));
2626
2627      case 0x35:   /* LDC1 */
2628         return compile_load_cop(drc, compiler, desc, 8, FPR64(RTREG));
2629
2630      case 0x32:   /* LWC2 */
2631      case 0x36:   /* LDC2 */
2632         return compile_load_cop(drc, compiler, desc, (opswitch & 4) ? 8 : 4, &mips3.core->cpr[2][RTREG]);
2633
2634      case 0x1a:   /* LDL */
2635      case 0x1b:   /* LDR */
2636         return compile_load_double_partial(drc, compiler, desc, opswitch & 1);
2637
2638      case 0x22:   /* LWL */
2639      case 0x26:   /* LWR */
2640         return compile_load_word_partial(drc, compiler, desc, opswitch & 4);
2641
2642
2643      /* ----- memory store operations ----- */
2644
2645      case 0x28:   /* SB */
2646      case 0x29:   /* SH */
2647      case 0x2b:   /* SW */
2648         return compile_store(drc, compiler, desc, (opswitch & 3) + 1);
2649
2650      case 0x3f:   /* SD */
2651         return compile_store(drc, compiler, desc, 8);
2652
2653      case 0x39:   /* SWC1 */
2654         return compile_store_cop(drc, compiler, desc, 4, FPR32(RTREG));
2655
2656      case 0x3d:   /* SDC1 */
2657         return compile_store_cop(drc, compiler, desc, 8, FPR64(RTREG));
2658
2659      case 0x3a:   /* SWC2 */
2660         return compile_store_cop(drc, compiler, desc, (opswitch & 4) ? 8 : 4, &mips3.core->cpr[2][RTREG]);
2661
2662      case 0x2a:   /* SWL */
2663      case 0x2e:   /* SWR */
2664         return compile_store_word_partial(drc, compiler, desc, opswitch & 4);
2665
2666      case 0x2c:   /* SDL */
2667      case 0x2d:   /* SDR */
2668         return compile_store_double_partial(drc, compiler, desc, opswitch & 1);
2669
2670
2671      /* ----- effective no-ops ----- */
2672
2673      case 0x2f:   /* CACHE */
2674      case 0x33:   /* PREF */
2675         return TRUE;
2676
2677
2678      /* ----- coprocessor instructions ----- */
2679
2680      case 0x10:   /* COP0 */
2681         return compile_cop0(drc, compiler, desc);
2682
2683      case 0x11:   /* COP1 */
2684         return compile_cop1(drc, compiler, desc);
2685
2686      case 0x13:   /* COP1X - R5000 */
2687         return compile_cop1x(drc, compiler, desc);
2688
2689      case 0x12:   /* COP2 */
2690         oob_request_callback(drc, COND_NONE, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_invalidop_exception);
2691                                                                     // jmp  generate_invalidop_exception
2692         return TRUE;
2693
2694
2695      /* ----- unimplemented/illegal instructions ----- */
2696
2697//      case 0x30:  /* LL */        logerror("mips3 Unhandled op: LL\n");                                   break;
2698//      case 0x34:  /* LLD */       logerror("mips3 Unhandled op: LLD\n");                                  break;
2699//      case 0x38:  /* SC */        logerror("mips3 Unhandled op: SC\n");                                   break;
2700//      case 0x3c:  /* SCD */       logerror("mips3 Unhandled op: SCD\n");                                  break;
2701//      case 0x3b:  /* SWC3 */      invalid_instruction(op);                                                break;
2702//      default:    /* ??? */       invalid_instruction(op);                                                break;
2703   }
2704
2705   return FALSE;
2706}
2707
2708
2709/*-------------------------------------------------
2710    compile_special - compile opcodes in the
2711    'SPECIAL' group
2712-------------------------------------------------*/
2713
2714static int compile_special(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
2715{
2716   UINT32 op = *desc->opptr.l;
2717   UINT8 opswitch = op & 63;
2718   emit_link link1 = { 0 };
2719
2720   switch (opswitch)
2721   {
2722      /* ----- shift instructions ----- */
2723
2724      case 0x00:   /* SLL - MIPS I */
2725      case 0x02:   /* SRL - MIPS I */
2726      case 0x03:   /* SRA - MIPS I */
2727      case 0x04:   /* SLLV - MIPS I */
2728      case 0x06:   /* SRLV - MIPS I */
2729      case 0x07:   /* SRAV - MIPS I */
2730         return compile_shift(drc, compiler, desc, opswitch & 0x03, opswitch & 0x04);
2731
2732      case 0x14:   /* DSLLV - MIPS III */
2733      case 0x16:   /* DSRLV - MIPS III */
2734      case 0x17:   /* DSRAV - MIPS III */
2735      case 0x38:   /* DSLL - MIPS III */
2736      case 0x3a:   /* DSRL - MIPS III */
2737      case 0x3b:   /* DSRA - MIPS III */
2738      case 0x3c:   /* DSLL32 - MIPS III */
2739      case 0x3e:   /* DSRL32 - MIPS III */
2740      case 0x3f:   /* DSRA32 - MIPS III */
2741         return compile_dshift(drc, compiler, desc, opswitch & 0x03, ~opswitch & 0x20, opswitch & 0x04);
2742
2743
2744      /* ----- basic arithmetic ----- */
2745
2746      case 0x20:   /* ADD - MIPS I */
2747      case 0x21:   /* ADDU - MIPS I */
2748         return compile_add(drc, compiler, desc, opswitch & 1, FALSE);
2749
2750      case 0x2c:   /* DADD - MIPS III */
2751      case 0x2d:   /* DADDU - MIPS III */
2752         return compile_dadd(drc, compiler, desc, opswitch & 1, FALSE);
2753
2754      case 0x22:   /* SUB - MIPS I */
2755      case 0x23:   /* SUBU - MIPS I */
2756         return compile_sub(drc, compiler, desc, opswitch & 1);
2757
2758      case 0x2e:   /* DSUB - MIPS III */
2759      case 0x2f:   /* DSUBU - MIPS III */
2760         return compile_dsub(drc, compiler, desc, opswitch & 1);
2761
2762      case 0x18:   /* MULT - MIPS I */
2763      case 0x19:   /* MULTU - MIPS I */
2764         return compile_mult(drc, compiler, desc, opswitch & 1);
2765
2766      case 0x1c:   /* DMULT - MIPS III */
2767      case 0x1d:   /* DMULTU - MIPS III */
2768         return compile_dmult(drc, compiler, desc, opswitch & 1);
2769
2770      case 0x1a:   /* DIV - MIPS I */
2771      case 0x1b:   /* DIVU - MIPS I */
2772         return compile_div(drc, compiler, desc, opswitch & 1);
2773
2774      case 0x1e:   /* DDIV - MIPS III */
2775      case 0x1f:   /* DDIVU - MIPS III */
2776         return compile_ddiv(drc, compiler, desc, opswitch & 1);
2777
2778
2779      /* ----- basic logical ops ----- */
2780
2781      case 0x24:   /* AND - MIPS I */
2782      case 0x25:   /* OR - MIPS I */
2783      case 0x26:   /* XOR - MIPS I */
2784      case 0x27:   /* NOR - MIPS I */
2785         return compile_logical(drc, compiler, desc, opswitch & 3, FALSE);
2786
2787
2788      /* ----- basic comparisons ----- */
2789
2790      case 0x2a:   /* SLT - MIPS I */
2791      case 0x2b:   /* SLTU - MIPS I */
2792         return compile_slt(drc, compiler, desc, opswitch & 1, FALSE);
2793
2794
2795      /* ----- conditional traps ----- */
2796
2797      case 0x30:   /* TGE - MIPS II */
2798      case 0x31:   /* TGEU - MIPS II */
2799      case 0x32:   /* TLT - MIPS II */
2800      case 0x33:   /* TLTU - MIPS II */
2801      case 0x34:   /* TEQ - MIPS II */
2802      case 0x36:   /* TNE - MIPS II */
2803         return compile_trapcc(drc, compiler, desc, opswitch & 7, FALSE);
2804
2805
2806      /* ----- conditional moves ----- */
2807
2808      case 0x0a:   /* MOVZ - MIPS IV */
2809      case 0x0b:   /* MOVN - MIPS IV */
2810         return compile_movzn(drc, compiler, desc, opswitch & 1);
2811
2812      case 0x01:   /* MOVF - MIPS IV */
2813         if (RDREG != 0)
2814         {
2815            mipsreg_state rs, rd;
2816
2817            /* allocate source registers */
2818            rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
2819            rd = compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_SRC | ALLOC_DST | ALLOC_DIRTY);
2820
2821            emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);                  // cmp  fcc[x],0
2822            emit_jcc_short_link(DRCTOP, ((op >> 16) & 1) ? COND_Z : COND_NZ, &link1);   // jz/nz skip
2823            emit_load_register_value(drc, compiler, X86REG(rd), rs);               // mov  <rd>,<rs>
2824         }
2825         resolve_link(DRCTOP, &link1);                                    // skip:
2826         return TRUE;
2827
2828
2829      /* ----- jumps and branches ----- */
2830
2831      case 0x08:   /* JR - MIPS I */
2832      case 0x09:   /* JALR - MIPS I */
2833         {
2834            mipsreg_state rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
2835            if (ISCONST(rs))
2836               emit_mov_m32_imm(DRCTOP, MBD(REG_RSP, SPOFFS_NEXTPC), CONSTVAL(rs));   // mov  [esp+nextpc],rs
2837            else
2838               emit_mov_m32_r32(DRCTOP, MBD(REG_RSP, SPOFFS_NEXTPC), X86REG(rs));      // mov  [esp+nextpc],rs
2839            emit_delay_slot_and_branch(drc, compiler, desc, (opswitch == 0x09) ? RDREG : 0);
2840                                                                     // <next instruction + redispatch>
2841         }
2842         return TRUE;
2843
2844
2845      /* ----- system calls ----- */
2846
2847      case 0x0c:   /* SYSCALL - MIPS I */
2848         oob_request_callback(drc, COND_NONE, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_syscall_exception);
2849                                                                     // jmp  generate_syscall_exception
2850         return TRUE;
2851
2852      case 0x0d:   /* BREAK - MIPS I */
2853         oob_request_callback(drc, COND_NONE, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_break_exception);
2854                                                                     // jmp  generate_break_exception
2855         return TRUE;
2856
2857
2858      /* ----- effective no-ops ----- */
2859
2860      case 0x0f:   /* SYNC - MIPS II */
2861         return TRUE;
2862
2863
2864      /* ----- hi/lo register access ----- */
2865
2866      case 0x10:   /* MFHI - MIPS I */
2867         if (RDREG != 0)
2868         {
2869            mipsreg_state hi = compiler_register_allocate(drc, compiler, desc, REG_HI, ALLOC_SRC);
2870            mipsreg_state rd = compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_DST | ALLOC_DIRTY);
2871            emit_load_register_value(drc, compiler, X86REG(rd), hi);               // mov  <rd>,<hi>
2872         }
2873         return TRUE;
2874
2875      case 0x11:   /* MTHI - MIPS I */
2876         if (RSREG != 0)
2877         {
2878            mipsreg_state rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
2879            mipsreg_state hi = compiler_register_allocate(drc, compiler, desc, REG_HI, ALLOC_DST | ALLOC_DIRTY);
2880            emit_load_register_value(drc, compiler, X86REG(hi), rs);               // mov  hi,<rs>
2881         }
2882         return TRUE;
2883
2884      case 0x12:   /* MFLO - MIPS I */
2885         if (RDREG != 0)
2886         {
2887            mipsreg_state lo = compiler_register_allocate(drc, compiler, desc, REG_LO, ALLOC_SRC);
2888            mipsreg_state rd = compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_DST | ALLOC_DIRTY);
2889            emit_load_register_value(drc, compiler, X86REG(rd), lo);               // mov  <rd>,<lo>
2890         }
2891         return TRUE;
2892
2893      case 0x13:   /* MTLO - MIPS I */
2894         if (RSREG != 0)
2895         {
2896            mipsreg_state rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
2897            mipsreg_state lo = compiler_register_allocate(drc, compiler, desc, REG_LO, ALLOC_DST | ALLOC_DIRTY);
2898            emit_load_register_value(drc, compiler, X86REG(lo), rs);               // mov  lo,<rs>
2899         }
2900         return TRUE;
2901   }
2902   return FALSE;
2903}
2904
2905
2906/*-------------------------------------------------
2907    compile_regimm - compile opcodes in the
2908    'REGIMM' group
2909-------------------------------------------------*/
2910
2911static int compile_regimm(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
2912{
2913   UINT32 op = *desc->opptr.l;
2914   UINT8 opswitch = RTREG;
2915
2916   switch (opswitch)
2917   {
2918      case 0x00:   /* BLTZ */
2919      case 0x01:   /* BGEZ */
2920      case 0x02:   /* BLTZL */
2921      case 0x03:   /* BGEZL */
2922      case 0x10:   /* BLTZAL */
2923      case 0x11:   /* BGEZAL */
2924      case 0x12:   /* BLTZALL */
2925      case 0x13:   /* BGEZALL */
2926         return compile_branchcz(drc, compiler, desc, (opswitch & 1) ? COND_GE : COND_L, opswitch & 0x10);
2927
2928      case 0x08:   /* TGEI */
2929      case 0x09:   /* TGEIU */
2930      case 0x0a:   /* TLTI */
2931      case 0x0b:   /* TLTIU */
2932      case 0x0c:   /* TEQI */
2933      case 0x0e:   /* TNEI */
2934         return compile_trapcc(drc, compiler, desc, opswitch & 7, TRUE);
2935   }
2936   return FALSE;
2937}
2938
2939
2940/*-------------------------------------------------
2941    compile_idt - compile opcodes in the IDT-
2942    specific group
2943-------------------------------------------------*/
2944
2945static int compile_idt(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
2946{
2947   fatalerror("Unimplemented IDT instructions");
2948#if 0
2949   UINT32 op = *desc->opptr.l;
2950   UINT8 opswitch = op & 0x1f;
2951
2952   switch (opswitch)
2953   {
2954      case 0: /* MAD */
2955         if (RSREG != 0 && RTREG != 0)
2956         {
2957            emit_mov_r32_m32(REG_EAX, REGADDR(RSREG));                     // mov  eax,[rsreg]
2958            emit_mov_r32_m32(REG_EDX, REGADDR(RTREG));                     // mov  edx,[rtreg]
2959            emit_imul_r32(DRCTOP, REG_EDX);                              // imul edx
2960            emit_add_r32_m32(DRCTOP, LOADDR);                           // add  eax,[lo]
2961            emit_adc_r32_m32(DRCTOP, HIADDR);                           // adc  edx,[hi]
2962            emit_mov_r32_r32(DRCTOP, REG_EBX, REG_EDX);                     // mov  ebx,edx
2963            emit_cdq(DRCTOP);                                       // cdq
2964            emit_mov_m64_r64(DRCTOP, LOADDR, REG_EAX);                     // mov  [lo],edx:eax
2965            emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EBX);                     // mov  eax,ebx
2966            emit_cdq(DRCTOP);                                       // cdq
2967            emit_mov_m64_r64(DRCTOP, HIADDR, REG_EAX);                     // mov  [hi],edx:eax
2968         }
2969         return compile_SUCCESSFUL_CP(3,4);
2970
2971      case 1: /* MADU */
2972         if (RSREG != 0 && RTREG != 0)
2973         {
2974            emit_mov_r32_m32(REG_EAX, REGADDR(RSREG));                     // mov  eax,[rsreg]
2975            emit_mov_r32_m32(REG_EDX, REGADDR(RTREG));                     // mov  edx,[rtreg]
2976            emit_mul_r32(DRCTOP, REG_EDX);                              // mul  edx
2977            emit_add_r32_m32(DRCTOP, LOADDR);                           // add  eax,[lo]
2978            emit_adc_r32_m32(DRCTOP, HIADDR);                           // adc  edx,[hi]
2979            emit_mov_r32_r32(DRCTOP, REG_EBX, REG_EDX);                     // mov  ebx,edx
2980            emit_cdq(DRCTOP);                                       // cdq
2981            emit_mov_m64_r64(DRCTOP, LOADDR, REG_EDX, REG_EAX);               // mov  [lo],edx:eax
2982            emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EBX);                     // mov  eax,ebx
2983            emit_cdq(DRCTOP);                                       // cdq
2984            emit_mov_m64_r64(DRCTOP, HIADDR, REG_EDX, REG_EAX);               // mov  [hi],edx:eax
2985         }
2986         return compile_SUCCESSFUL_CP(3,4);
2987
2988      case 2: /* MUL */
2989         if (RDREG != 0)
2990         {
2991            if (RSREG != 0 && RTREG != 0)
2992            {
2993               emit_mov_r32_m32(REG_EAX, REGADDR(RSREG));                  // mov  eax,[rsreg]
2994               emit_imul_r32_m32(REG_EAX, REGADDR(RTREG));                  // imul eax,[rtreg]
2995               emit_cdq(DRCTOP);                                    // cdq
2996               emit_mov_m64_r64(REG_ESI, REGADDR(RDREG), REG_EDX, REG_EAX);   // mov  [rd],edx:eax
2997            }
2998            else
2999               emit_zero_m64(REG_ESI, REGADDR(RDREG));
3000         }
3001         return compile_SUCCESSFUL_CP(3,4);
3002   }
3003#endif
3004   return FALSE;
3005}
3006
3007
3008
3009/***************************************************************************
3010    COP0 RECOMPILATION
3011***************************************************************************/
3012
3013/*-------------------------------------------------
3014    compile_set_cop0_reg - generate code to
3015    handle special COP0 registers
3016-------------------------------------------------*/
3017
3018static int compile_set_cop0_reg(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 reg)
3019{
3020   emit_link link1;
3021
3022   switch (reg)
3023   {
3024      case COP0_Cause:
3025         emit_mov_r32_m32(DRCTOP, REG_EDX, CPR0ADDR(COP0_Cause));                  // mov  edx,[Cause]
3026         emit_and_r32_imm(DRCTOP, REG_EAX, ~0xfc00);                              // and  eax,~0xfc00
3027         emit_and_r32_imm(DRCTOP, REG_EDX, 0xfc00);                              // and  edx,0xfc00
3028         emit_or_r32_r32(DRCTOP, REG_EAX, REG_EDX);                              // or   eax,edx
3029         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Cause), REG_EAX);                  // mov  [Cause],eax
3030         emit_and_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Status));                  // and  eax,[SR]
3031         emit_test_r32_imm(DRCTOP, REG_EAX, 0x300);                              // test eax,0x300
3032         oob_request_callback(drc, COND_NZ, oob_interrupt_cleanup, compiler, desc, mips3.drcdata->generate_interrupt_exception);
3033                                                                     // jnz  generate_interrupt_exception
3034         return TRUE;
3035
3036      case COP0_Status:
3037         emit_flush_cycles_before_instruction(drc, compiler, desc, 1);
3038         emit_mov_r32_m32(DRCTOP, REG_EDX, CPR0ADDR(COP0_Status));                  // mov  edx,[Status]
3039         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Status), REG_EAX);                  // mov  [Status],eax
3040         emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EAX);                              // xor  edx,eax
3041         emit_test_r32_imm(DRCTOP, REG_EDX, SR_IMEX5);                              // test edx,0x8000
3042         emit_jcc_short_link(DRCTOP, COND_Z, &link1);                           // jz   skip
3043         emit_lea_r64_m64(DRCTOP, REG_P1, COREADDR);                              // lea  p1,[mips3.core]
3044         emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->mips3com_update_cycle_counting));   // call mips3com_update_cycle_counting
3045         resolve_link(DRCTOP, &link1);                                    // skip:
3046         append_check_interrupts(drc, compiler, desc);                           // <check interrupts>
3047         return TRUE;
3048
3049      case COP0_Count:
3050         emit_flush_cycles_before_instruction(drc, compiler, desc, 1);
3051         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Count), REG_EAX);                  // mov  [Count],eax
3052         emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->activecpu_gettotalcycles));         // call activecpu_gettotalcycles
3053         emit_mov_r32_m32(DRCTOP, REG_EDX, CPR0ADDR(COP0_Count));                  // mov  edx,[Count]
3054         emit_sub_r64_r64(DRCTOP, REG_RAX, REG_RDX);                              // sub  rax,rdx
3055         emit_sub_r64_r64(DRCTOP, REG_RAX, REG_RDX);                              // sub  rax,rdx
3056         emit_mov_m64_r64(DRCTOP, MDRC(&mips3.core->count_zero_time), REG_RAX);         // mov  [count_zero_time],rax
3057         emit_lea_r64_m64(DRCTOP, REG_P1, COREADDR);                              // lea  p1,[mips3.core]
3058         emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->mips3com_update_cycle_counting));   // call mips3com_update_cycle_counting
3059         return TRUE;
3060
3061      case COP0_Compare:
3062         emit_flush_cycles_before_instruction(drc, compiler, desc, 1);
3063         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Compare), REG_EAX);                  // mov  [Compare],eax
3064         emit_and_m32_imm(DRCTOP, CPR0ADDR(COP0_Cause), ~0x8000);                  // and  [Cause],~0x8000
3065         emit_lea_r64_m64(DRCTOP, REG_P1, COREADDR);                              // lea  p1,[mips3.core]
3066         emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->mips3com_update_cycle_counting));   // call mips3com_update_cycle_counting
3067         return TRUE;
3068
3069      case COP0_PRId:
3070         return TRUE;
3071
3072      case COP0_Config:
3073         emit_mov_r32_m32(DRCTOP, REG_EDX, CPR0ADDR(COP0_Config));                  // mov  edx,[Config]
3074         emit_and_r32_imm(DRCTOP, REG_EAX, 0x0007);                              // and  eax,0x0007
3075         emit_and_r32_imm(DRCTOP, REG_EDX, ~0x0007);                              // and  edx,~0x0007
3076         emit_or_r32_r32(DRCTOP, REG_EAX, REG_EDX);                              // or   eax,edx
3077         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Config), REG_EAX);                  // mov  [Config],eax
3078         return TRUE;
3079
3080      default:
3081         emit_mov_m32_r32(DRCTOP, CPR0ADDR(reg), REG_EAX);                        // mov  cpr0[reg],eax
3082         return TRUE;
3083   }
3084}
3085
3086
3087/*-------------------------------------------------
3088    compile_get_cop0_reg - generate code to
3089    read special COP0 registers
3090-------------------------------------------------*/
3091
3092static int compile_get_cop0_reg(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, UINT8 reg)
3093{
3094   emit_link link1, link2;
3095
3096   switch (reg)
3097   {
3098      case COP0_Count:
3099         compiler->cycles += MIPS3_COUNT_READ_CYCLES;
3100         emit_flush_cycles_before_instruction(drc, compiler, desc, MIPS3_COUNT_READ_CYCLES);
3101         emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->activecpu_gettotalcycles));         // call activecpu_gettotalcycles
3102         emit_sub_r64_m64(DRCTOP, REG_RAX, MDRC(&mips3.core->count_zero_time));         // sub  rax,[count_zero_time]
3103         emit_shr_r64_imm(DRCTOP, REG_RAX, 1);                                 // shr  rax,1
3104         emit_movsxd_r64_r32(DRCTOP, REG_RAX, REG_EAX);                           // movsxd rax,eax
3105         return TRUE;
3106
3107      case COP0_Cause:
3108         compiler->cycles += MIPS3_CAUSE_READ_CYCLES;
3109         emit_movsxd_r64_m32(DRCTOP, REG_RAX, CPR0ADDR(COP0_Cause));                  // movsxd rax,[Cause]
3110         return TRUE;
3111
3112      case COP0_Random:
3113         emit_flush_cycles_before_instruction(drc, compiler, desc, 1);
3114         emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->activecpu_gettotalcycles));         // call activecpu_gettotalcycles
3115         emit_mov_r32_m32(DRCTOP, REG_ECX, CPR0ADDR(COP0_Wired));                  // mov  ecx,[Wired]
3116         emit_mov_r32_imm(DRCTOP, REG_R8D, 48);                                 // mov  r8d,48
3117         emit_and_r32_imm(DRCTOP, REG_ECX, 0x3f);                              // and  ecx,0x3f
3118         emit_sub_r64_m64(DRCTOP, REG_RAX, MDRC(&mips3.core->count_zero_time));         // sub  rax,[count_zero_time]
3119         emit_sub_r32_r32(DRCTOP, REG_R8D, REG_ECX);                              // sub  r8d,ecx
3120         emit_jcc_short_link(DRCTOP, COND_BE, &link1);                           // jbe  link1
3121         emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                              // xor  edx,edx
3122         emit_div_r64(DRCTOP, REG_R8);                                       // div  r8
3123         emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EDX);                              // mov  eax,edx
3124         emit_add_r32_r32(DRCTOP, REG_EAX, REG_ECX);                              // add  eax,ecx
3125         emit_and_r32_imm(DRCTOP, REG_EAX, 0x3f);                              // and  eax,0x3f
3126         emit_jmp_short_link(DRCTOP, &link2);                                 // jmp  link2
3127         resolve_link(DRCTOP, &link1);                                    // link1:
3128         emit_mov_r32_imm(DRCTOP, REG_EAX, 47);                                 // mov  eax,47
3129         resolve_link(DRCTOP, &link2);                                    // link2:
3130         return TRUE;
3131
3132      default:
3133         emit_movsxd_r64_m32(DRCTOP, REG_RAX, CPR0ADDR(reg));                     // movsxd rax,cpr0[reg]
3134         return TRUE;
3135   }
3136}
3137
3138
3139/*-------------------------------------------------
3140    compile_cop0 - compile COP0 opcodes
3141-------------------------------------------------*/
3142
3143static int compile_cop0(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
3144{
3145   UINT32 op = *desc->opptr.l;
3146   UINT8 opswitch = RSREG;
3147
3148   /* generate an exception if COP0 is disabled or we are not in kernel mode */
3149   if (mips3.drcoptions & MIPS3DRC_STRICT_COP0)
3150   {
3151      emit_link checklink;
3152
3153      emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_KSU_MASK);                  // test [SR],SR_KSU_MASK
3154      emit_jcc_short_link(DRCTOP, COND_Z, &checklink);                           // jz   okay
3155      emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_COP0);                     // test [SR],SR_COP0
3156      oob_request_callback(drc, COND_Z, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_cop_exception);
3157                                                                     // jz   generate_cop_exception
3158      resolve_link(DRCTOP, &checklink);                                    // okay:
3159   }
3160
3161   switch (opswitch)
3162   {
3163      case 0x00:   /* MFCz */
3164      case 0x01:   /* DMFCz */
3165         if (RTREG != 0)
3166         {
3167            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_DST | ALLOC_DIRTY);
3168            compile_get_cop0_reg(drc, compiler, desc, RDREG);                     // mov  eax,cpr0[rd])
3169            if (!(opswitch & 1))
3170               emit_movsxd_r64_r32(DRCTOP, X86REG(rt), REG_EAX);                  // movsxd <rt>,eax
3171            else
3172               emit_mov_r64_r64(DRCTOP, X86REG(rt), REG_RAX);                     // mov  <rt>,rax
3173         }
3174         return TRUE;
3175
3176      case 0x02:   /* CFCz */
3177         if (RTREG != 0)
3178         {
3179            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_DST | ALLOC_DIRTY);
3180            emit_movsxd_r64_m32(DRCTOP, X86REG(rt), CCR0ADDR(RDREG));               // movsxd <rt>,ccr1[rd]
3181         }
3182         return TRUE;
3183
3184      case 0x04:   /* MTCz */
3185      case 0x05:   /* DMTCz */
3186         {
3187            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
3188            emit_load_register_value(drc, compiler, REG_EAX, rt);                  // mov  eax,<rt>
3189            compile_set_cop0_reg(drc, compiler, desc, RDREG);                     // mov  cpr0[rd],rax
3190         }
3191         return TRUE;
3192
3193      case 0x06:   /* CTCz */
3194         {
3195            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
3196            emit_load_register_value(drc, compiler, REG_EAX, rt);                  // mov  eax,<rt>
3197            emit_mov_m32_r32(DRCTOP, CCR0ADDR(RDREG), REG_EAX);                     // mov  ccr1[rd],eax
3198         }
3199         return TRUE;
3200
3201      case 0x10:
3202      case 0x11:
3203      case 0x12:
3204      case 0x13:
3205      case 0x14:
3206      case 0x15:
3207      case 0x16:
3208      case 0x17:
3209      case 0x18:
3210      case 0x19:
3211      case 0x1a:
3212      case 0x1b:
3213      case 0x1c:
3214      case 0x1d:
3215      case 0x1e:
3216      case 0x1f:   /* COP */
3217         switch (op & 0x01ffffff)
3218         {
3219            case 0x01:   /* TLBR */
3220               emit_lea_r64_m64(DRCTOP, REG_P1, COREADDR);                        // lea  p1,[mips3.core]
3221               emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->mips3com_tlbr));            // call mips3com_tlbr
3222               return TRUE;
3223
3224            case 0x02:   /* TLBWI */
3225               emit_lea_r64_m64(DRCTOP, REG_P1, COREADDR);                        // lea  p1,[mips3.core]
3226               emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->mips3com_tlbwi));         // call mips3com_tlbwi
3227               return TRUE;
3228
3229            case 0x06:   /* TLBWR */
3230               emit_lea_r64_m64(DRCTOP, REG_P1, COREADDR);                        // lea  p1,[mips3.core]
3231               emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->mips3com_tlbwr));         // call mips3com_tlbwr
3232               return TRUE;
3233
3234            case 0x08:   /* TLBP */
3235               emit_lea_r64_m64(DRCTOP, REG_P1, COREADDR);                        // lea  p1,[mips3.core]
3236               emit_call_m64(DRCTOP, MDRC(&mips3.drcdata->mips3com_tlbp));            // call mips3com_tlbp
3237               return TRUE;
3238
3239            case 0x18:   /* ERET */
3240               emit_mov_r32_m32(DRCTOP, REG_P1, CPR0ADDR(COP0_EPC));               // mov  p1,[EPC]
3241               emit_and_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), ~SR_EXL);            // and  [SR],~SR_EXL
3242               compiler_register_flush_all(drc, compiler);                        // <flush registers>
3243               drc_append_dispatcher(drc);                                    // <dispatch>
3244               return TRUE;
3245
3246            case 0x20:   /* WAIT */
3247               return TRUE;
3248         }
3249         break;
3250   }
3251
3252   return FALSE;
3253}
3254
3255
3256
3257/***************************************************************************
3258    COP1 RECOMPILATION
3259***************************************************************************/
3260
3261/*-------------------------------------------------
3262    compile_cop1 - compile COP1 opcodes
3263-------------------------------------------------*/
3264
3265static int compile_cop1(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
3266{
3267   UINT32 op = *desc->opptr.l;
3268   emit_link link1;
3269
3270   /* generate an exception if COP1 is disabled */
3271   if (mips3.drcoptions & MIPS3DRC_STRICT_COP1)
3272   {
3273      emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_COP1);                     // test [mips3.core->cpr[0][COP0_Status]],SR_COP1
3274      oob_request_callback(drc, COND_Z, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_cop_exception);
3275                                                                     // jz   generate_cop_exception
3276   }
3277
3278   switch (RSREG)
3279   {
3280      case 0x00:   /* MFCz */
3281         if (RTREG != 0)
3282         {
3283            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_DST | ALLOC_DIRTY);
3284            emit_movsxd_r64_m32(DRCTOP, X86REG(rt), FPR32ADDR(RDREG));                  // movsxd <rt>,cpr[rd]
3285         }
3286         return TRUE;
3287
3288      case 0x01:   /* DMFCz */
3289         if (RTREG != 0)
3290         {
3291            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_DST | ALLOC_DIRTY);
3292            emit_mov_r64_m64(DRCTOP, X86REG(rt), FPR64ADDR(RDREG));                     // mov  <rt>,cpr[rd]
3293         }
3294         return TRUE;
3295
3296      case 0x02:   /* CFCz */
3297         if (RTREG != 0)
3298         {
3299            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_DST | ALLOC_DIRTY);
3300            if (RDREG != 31)
3301               emit_movsxd_r64_m32(DRCTOP, X86REG(rt), CCR1ADDR(RDREG));               // movsxd <rt>,ccr1[rd]
3302            else
3303            {
3304               emit_call(DRCTOP, mips3.drcdata->recover_ccr31);                     // call recover_ccr31
3305               emit_mov_r64_r64(DRCTOP, X86REG(rt), REG_RAX);                        // mov  [X86REG(rt)],rax
3306            }
3307         }
3308         return TRUE;
3309
3310      case 0x04:   /* MTCz */
3311         {
3312            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
3313            UINT8 tempreg = ISCONST(rt) ? REG_EAX : X86REG(rt);
3314            emit_load_register_value(drc, compiler, tempreg, rt);                     // mov  <tempreg>,<rt>
3315            emit_mov_m32_r32(DRCTOP, FPR32ADDR(RDREG), tempreg);                     // mov  cpr1[rd],<tempreg>
3316         }
3317         return TRUE;
3318
3319      case 0x05:   /* DMTCz */
3320         {
3321            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
3322            UINT8 tempreg = ISCONST(rt) ? REG_EAX : X86REG(rt);
3323            emit_load_register_value(drc, compiler, tempreg, rt);                     // mov  <tempreg>,<rt>
3324            emit_mov_m64_r64(DRCTOP, FPR64ADDR(RDREG), tempreg);                     // mov  cpr1[rd],<tempreg>
3325         }
3326         return TRUE;
3327
3328      case 0x06:   /* CTCz */
3329         {
3330            mipsreg_state rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
3331            emit_load_register_value(drc, compiler, REG_EAX, rt);                     // mov  eax,<rt>
3332            if (RDREG != 31)
3333               emit_mov_m32_r32(DRCTOP, CCR1ADDR(RDREG), REG_EAX);                     // mov  ccr1[rd],eax
3334            else
3335               emit_call(DRCTOP, mips3.drcdata->explode_ccr31);                     // call explode_ccr31
3336         }
3337         return TRUE;
3338
3339      case 0x08:   /* BC */
3340         switch ((op >> 16) & 3)
3341         {
3342            case 0x00:   /* BCzF */
3343            case 0x02:   /* BCzFL */
3344               emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);               // cmp  fcc[which],0
3345               emit_jcc_near_link(DRCTOP, COND_NZ, &link1);                     // jnz  link1
3346               emit_delay_slot_and_branch(drc, compiler, desc, 0);                  // <next instruction + redispatch>
3347               resolve_link(DRCTOP, &link1);                              // skip:
3348               return TRUE;
3349
3350            case 0x01:   /* BCzT */
3351            case 0x03:   /* BCzTL */
3352               emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);               // cmp  fcc[which],0
3353               emit_jcc_near_link(DRCTOP, COND_Z, &link1);                        // jz  link1
3354               emit_delay_slot_and_branch(drc, compiler, desc, 0);                  // <next instruction + redispatch>
3355               resolve_link(DRCTOP, &link1);                              // skip:
3356               return TRUE;
3357         }
3358         break;
3359
3360      default:
3361         switch (op & 0x3f)
3362         {
3363            case 0x00:
3364               if (IS_SINGLE(op))   /* ADD.S */
3365               {
3366                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3367                  emit_addss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // addss xmm0,[ftreg]
3368                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3369               }
3370               else            /* ADD.D */
3371               {
3372                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3373                  emit_addsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // addsd xmm0,[ftreg]
3374                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3375               }
3376               return TRUE;
3377
3378            case 0x01:
3379               if (IS_SINGLE(op))   /* SUB.S */
3380               {
3381                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3382                  emit_subss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // subss xmm0,[ftreg]
3383                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3384               }
3385               else            /* SUB.D */
3386               {
3387                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3388                  emit_subsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // subsd xmm0,[ftreg]
3389                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3390               }
3391               return TRUE;
3392
3393            case 0x02:
3394               if (IS_SINGLE(op))   /* MUL.S */
3395               {
3396                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3397                  emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // mulss xmm0,[ftreg]
3398                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3399               }
3400               else            /* MUL.D */
3401               {
3402                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3403                  emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // mulsd xmm0,[ftreg]
3404                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3405               }
3406               return TRUE;
3407
3408            case 0x03:
3409               if (IS_SINGLE(op))   /* DIV.S */
3410               {
3411                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3412                  emit_divss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // divss xmm0,[ftreg]
3413                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3414               }
3415               else            /* DIV.D */
3416               {
3417                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3418                  emit_divsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // divsd xmm0,[ftreg]
3419                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3420               }
3421               return TRUE;
3422
3423            case 0x04:
3424               if (IS_SINGLE(op))   /* SQRT.S */
3425               {
3426                  emit_sqrtss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // sqrtss xmm0,[fsreg]
3427                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3428               }
3429               else            /* SQRT.D */
3430               {
3431                  emit_sqrtsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // sqrtsd xmm0,[fsreg]
3432                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3433               }
3434               return TRUE;
3435
3436            case 0x05:
3437               if (IS_SINGLE(op))   /* ABS.S */
3438               {
3439                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3440                  emit_andps_r128_m128(DRCTOP, REG_XMM0, MDRC(mips3.drcdata->abs32mask));
3441                                                                     // andps xmm0,[abs32mask]
3442                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3443               }
3444               else            /* ABS.D */
3445               {
3446                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3447                  emit_andps_r128_m128(DRCTOP, REG_XMM0, MDRC(mips3.drcdata->abs64mask));
3448                                                                     // andpd xmm0,[abs64mask]
3449                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3450               }
3451               return TRUE;
3452
3453            case 0x06:
3454               if (IS_SINGLE(op))   /* MOV.S */
3455               {
3456                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3457                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3458               }
3459               else            /* MOV.D */
3460               {
3461                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3462                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3463               }
3464               return TRUE;
3465
3466            case 0x07:
3467               if (IS_SINGLE(op))   /* NEG.S */
3468               {
3469                  emit_xorps_r128_r128(DRCTOP, REG_XMM0, REG_XMM0);               // xorps xmm0,xmm0
3470                  emit_subss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // subss xmm0,[fsreg]
3471                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3472               }
3473               else            /* NEG.D */
3474               {
3475                  emit_xorps_r128_r128(DRCTOP, REG_XMM0, REG_XMM0);               // xorps xmm0,xmm0
3476                  emit_subsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // subsd xmm0,[fsreg]
3477                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3478               }
3479               return TRUE;
3480
3481            case 0x08:
3482               /* FUTURE: On Penryn, we can use ROUNDPS/ROUNDPD */
3483               drc_append_set_temp_sse_rounding(drc, FPRND_NEAR);                  // ldmxcsr [round]
3484               if (IS_SINGLE(op))   /* ROUND.L.S */
3485                  emit_cvtss2si_r64_m32(DRCTOP, REG_RAX, FPR32ADDR(FSREG));         // cvtss2si rax,[fsreg]
3486               else            /* ROUND.L.D */
3487                  emit_cvtsd2si_r64_m64(DRCTOP, REG_RAX, FPR64ADDR(FSREG));         // cvtsd2si rax,[fsreg]
3488               emit_mov_m64_r64(DRCTOP, FPR64ADDR(FDREG), REG_RAX);               // mov  [fdreg],rax
3489               drc_append_restore_sse_rounding(drc);                           // ldmxcsr [mode]
3490               return TRUE;
3491
3492            case 0x09:
3493               if (IS_SINGLE(op))   /* TRUNC.L.S */
3494                  emit_cvttss2si_r64_m32(DRCTOP, REG_RAX, FPR32ADDR(FSREG));         // cvttss2si rax,[fsreg]
3495               else            /* TRUNC.L.D */
3496                  emit_cvttsd2si_r64_m64(DRCTOP, REG_RAX, FPR64ADDR(FSREG));         // cvttsd2si rax,[fsreg]
3497               emit_mov_m64_r64(DRCTOP, FPR64ADDR(FDREG), REG_RAX);               // mov  [fdreg],rax
3498               return TRUE;
3499
3500            case 0x0a:
3501               /* FUTURE: On Penryn, we can use ROUNDPS/ROUNDPD */
3502               drc_append_set_temp_sse_rounding(drc, FPRND_UP);                  // ldmxcsr [round]
3503               if (IS_SINGLE(op))   /* CEIL.L.S */
3504                  emit_cvtss2si_r64_m32(DRCTOP, REG_RAX, FPR32ADDR(FSREG));         // cvtss2si rax,[fsreg]
3505               else            /* CEIL.L.D */
3506                  emit_cvtsd2si_r64_m64(DRCTOP, REG_RAX, FPR64ADDR(FSREG));         // cvtsd2si rax,[fsreg]
3507               emit_mov_m64_r64(DRCTOP, FPR64ADDR(FDREG), REG_RAX);               // mov  [fdreg],rax
3508               drc_append_restore_sse_rounding(drc);                           // ldmxcsr [mode]
3509               return TRUE;
3510
3511            case 0x0b:
3512               /* FUTURE: On Penryn, we can use ROUNDPS/ROUNDPD */
3513               drc_append_set_temp_sse_rounding(drc, FPRND_DOWN);                  // ldmxcsr [round]
3514               if (IS_SINGLE(op))   /* FLOOR.L.S */
3515                  emit_cvtss2si_r64_m32(DRCTOP, REG_RAX, FPR32ADDR(FSREG));         // cvtss2si rax,[fsreg]
3516               else            /* FLOOR.L.D */
3517                  emit_cvtsd2si_r64_m64(DRCTOP, REG_RAX, FPR64ADDR(FSREG));         // cvtsd2si rax,[fsreg]
3518               emit_mov_m64_r64(DRCTOP, FPR64ADDR(FDREG), REG_RAX);               // mov  [fdreg],rax
3519               drc_append_restore_sse_rounding(drc);                           // ldmxcsr [mode]
3520               return TRUE;
3521
3522            case 0x0c:
3523               /* FUTURE: On Penryn, we can use ROUNDPS/ROUNDPD */
3524               drc_append_set_temp_sse_rounding(drc, FPRND_NEAR);                  // ldmxcsr [round]
3525               if (IS_SINGLE(op))   /* ROUND.W.S */
3526                  emit_cvtss2si_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));         // cvtss2si eax,[fsreg]
3527               else            /* ROUND.W.D */
3528                  emit_cvtsd2si_r32_m64(DRCTOP, REG_EAX, FPR64ADDR(FSREG));         // cvtsd2si eax,[fsreg]
3529               emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);               // mov  [fdreg],eax
3530               drc_append_restore_sse_rounding(drc);                           // ldmxcsr [mode]
3531               return TRUE;
3532
3533            case 0x0d:
3534               if (IS_SINGLE(op))   /* TRUNC.W.S */
3535                  emit_cvttss2si_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));         // cvttss2si eax,[fsreg]
3536               else            /* TRUNC.W.D */
3537                  emit_cvttsd2si_r32_m64(DRCTOP, REG_EAX, FPR64ADDR(FSREG));         // cvttsd2si eax,[fsreg]
3538               emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);               // mov  [fdreg],eax
3539               return TRUE;
3540
3541            case 0x0e:
3542               /* FUTURE: On Penryn, we can use ROUNDPS/ROUNDPD */
3543               drc_append_set_temp_sse_rounding(drc, FPRND_UP);                  // ldmxcsr [round]
3544               if (IS_SINGLE(op))   /* CEIL.W.S */
3545                  emit_cvtss2si_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));         // cvtss2si eax,[fsreg]
3546               else            /* CEIL.W.D */
3547                  emit_cvtsd2si_r32_m64(DRCTOP, REG_EAX, FPR64ADDR(FSREG));         // cvtsd2si eax,[fsreg]
3548               emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);               // mov  [fdreg],eax
3549               drc_append_restore_sse_rounding(drc);                           // ldmxcsr [mode]
3550               return TRUE;
3551
3552            case 0x0f:
3553               /* FUTURE: On Penryn, we can use ROUNDPS/ROUNDPD */
3554               drc_append_set_temp_sse_rounding(drc, FPRND_DOWN);                  // ldmxcsr [round]
3555               if (IS_SINGLE(op))   /* FLOOR.W.S */
3556                  emit_cvtss2si_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));         // cvtss2si eax,[fsreg]
3557               else            /* FLOOR.W.D */
3558                  emit_cvtsd2si_r32_m64(DRCTOP, REG_EAX, FPR64ADDR(FSREG));         // cvtsd2si eax,[fsreg]
3559               emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);               // mov  [fdreg],eax
3560               drc_append_restore_sse_rounding(drc);                           // ldmxcsr [mode]
3561               return TRUE;
3562
3563            case 0x11:   /* R5000 */
3564               emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);               // cmp  fcc[which],0
3565               emit_jcc_short_link(DRCTOP, ((op >> 16) & 1) ? COND_Z : COND_NZ, &link1);
3566                                                                     // jz/nz skip
3567               if (IS_SINGLE(op))   /* MOVT/F.S */
3568               {
3569                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3570                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3571               }
3572               else            /* MOVT/F.D */
3573               {
3574                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3575                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3576               }
3577               resolve_link(DRCTOP, &link1);                              // skip:
3578               return TRUE;
3579
3580            case 0x12:   /* R5000 */
3581               emit_cmp_m64_imm(DRCTOP, REGADDR(RTREG), 0);                     // cmp  [X86REG(rt)],0
3582               emit_jcc_short_link(DRCTOP, COND_NZ, &link1);                     // jnz  skip
3583               if (IS_SINGLE(op))   /* MOVZ.S */
3584               {
3585                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3586                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3587               }
3588               else            /* MOVZ.D */
3589               {
3590                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3591                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3592               }
3593               resolve_link(DRCTOP, &link1);                              // skip:
3594               return TRUE;
3595
3596            case 0x13:   /* R5000 */
3597               emit_cmp_m64_imm(DRCTOP, REGADDR(RTREG), 0);                     // cmp  [X86REG(rt)],0
3598               emit_jcc_short_link(DRCTOP, COND_Z, &link1);                     // jz  skip
3599               if (IS_SINGLE(op))   /* MOVN.S */
3600               {
3601                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3602                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3603               }
3604               else            /* MOVN.D */
3605               {
3606                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3607                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3608               }
3609               resolve_link(DRCTOP, &link1);                              // skip:
3610               return TRUE;
3611
3612            case 0x15:   /* R5000 */
3613               if (IS_SINGLE(op))   /* RECIP.S */
3614               {
3615                  emit_rcpss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // rcpss xmm0,[fsreg]
3616                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3617               }
3618               else            /* RECIP.D */
3619               {
3620                  emit_cvtsd2ss_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // cvtsd2ss xmm0,[fsreg]
3621                  emit_rcpss_r128_r128(DRCTOP, REG_XMM0, REG_XMM0);               // rcpss xmm0,xmm0
3622                  emit_cvtss2sd_r128_r128(DRCTOP, REG_XMM0, REG_XMM0);            // cvtss2sd xmm0,xmm0
3623                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3624               }
3625               return TRUE;
3626
3627            case 0x16:   /* R5000 */
3628               if (IS_SINGLE(op))   /* RSQRT.S */
3629               {
3630                  emit_rsqrtss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // rsqrtss xmm0,[fsreg]
3631                  emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);         // movss [fdreg],xmm0
3632               }
3633               else            /* RSQRT.D */
3634               {
3635                  emit_cvtsd2ss_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // cvtss2sd xmm0,[fsreg]
3636                  emit_rsqrtss_r128_r128(DRCTOP, REG_XMM0, REG_XMM0);               // rsqrtss xmm0,xmm0
3637                  emit_cvtss2sd_r128_r128(DRCTOP, REG_XMM0, REG_XMM0);            // cvtsd2ss xmm0,xmm0
3638                  emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);         // movsd [fdreg],xmm0
3639               }
3640               return TRUE;
3641
3642            case 0x20:
3643               if (IS_INTEGRAL(op))
3644               {
3645                  if (IS_SINGLE(op))   /* CVT.S.W */
3646                     emit_cvtsi2ss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // cvtsi2ss xmm0,[fsreg]
3647                  else            /* CVT.S.L */
3648                     emit_cvtsi2ss_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // cvtsi2ss xmm0,[fsreg]
3649               }
3650               else               /* CVT.S.D */
3651                  emit_cvtsd2ss_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // cvtsd2ss xmm0,[fsreg]
3652               emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);            // movss [fdreg],xmm0
3653               return TRUE;
3654
3655            case 0x21:
3656               if (IS_INTEGRAL(op))
3657               {
3658                  if (IS_SINGLE(op))   /* CVT.D.W */
3659                     emit_cvtsi2sd_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // cvtsi2sd xmm0,[fsreg]
3660                  else            /* CVT.D.L */
3661                     emit_cvtsi2sd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // cvtsi2sd xmm0,[fsreg]
3662               }
3663               else               /* CVT.D.S */
3664                  emit_cvtss2sd_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // cvtss2sd xmm0,[fsreg]
3665               emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);            // movsd [fdreg],xmm0
3666               return TRUE;
3667
3668            case 0x24:
3669               if (IS_SINGLE(op))   /* CVT.W.S */
3670                  emit_cvtss2si_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));         // cvtss2si eax,[fsreg]
3671               else            /* CVT.W.D */
3672                  emit_cvtsd2si_r32_m64(DRCTOP, REG_EAX, FPR64ADDR(FSREG));         // cvtsd2si eax,[fsreg]
3673               emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);               // mov  [fdreg],eax
3674               return TRUE;
3675
3676            case 0x25:
3677               if (IS_SINGLE(op))   /* CVT.L.S */
3678                  emit_cvtss2si_r64_m32(DRCTOP, REG_RAX, FPR32ADDR(FSREG));         // cvtss2si rax,[fsreg]
3679               else            /* CVT.L.D */
3680                  emit_cvtsd2si_r64_m64(DRCTOP, REG_RAX, FPR64ADDR(FSREG));         // cvtsd2si rax,[fsreg]
3681               emit_mov_m64_r64(DRCTOP, FPR32ADDR(FDREG), REG_RAX);               // mov  [fdreg],rax
3682               return TRUE;
3683
3684            case 0x30:
3685            case 0x38:
3686               emit_mov_m8_imm(DRCTOP, CF1ADDR((op >> 8) & 7), 0);                  /* C.F.S/D */
3687               return TRUE;
3688
3689            case 0x31:
3690            case 0x39:
3691               emit_mov_m8_imm(DRCTOP, CF1ADDR((op >> 8) & 7), 0);                  /* C.F.S/D */
3692               return TRUE;
3693
3694            case 0x32:
3695            case 0x3a:
3696               if (IS_SINGLE(op))   /* C.EQ.S */
3697               {
3698                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3699                  emit_comiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // comiss xmm0,[ftreg]
3700               }
3701               else            /* C.EQ.D */
3702               {
3703                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3704                  emit_comisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // comisd xmm0,[ftreg]
3705               }
3706               emit_setcc_m8(DRCTOP, COND_E, CF1ADDR((op >> 8) & 7));               // sete fcc[x]
3707               return TRUE;
3708
3709            case 0x33:
3710            case 0x3b:
3711               if (IS_SINGLE(op))   /* C.UEQ.S */
3712               {
3713                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3714                  emit_ucomiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // ucomiss xmm0,[ftreg]
3715               }
3716               else            /* C.UEQ.D */
3717               {
3718                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3719                  emit_ucomisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // ucomisd xmm0,[ftreg]
3720               }
3721               emit_setcc_m8(DRCTOP, COND_E, CF1ADDR((op >> 8) & 7));               // sete fcc[x]
3722               return TRUE;
3723
3724            case 0x34:
3725            case 0x3c:
3726               if (IS_SINGLE(op))   /* C.OLT.S */
3727               {
3728                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3729                  emit_comiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // comiss xmm0,[ftreg]
3730               }
3731               else            /* C.OLT.D */
3732               {
3733                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3734                  emit_comisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // comisd xmm0,[ftreg]
3735               }
3736               emit_setcc_m8(DRCTOP, COND_B, CF1ADDR((op >> 8) & 7));               // setb fcc[x]
3737               return TRUE;
3738
3739            case 0x35:
3740            case 0x3d:
3741               if (IS_SINGLE(op))   /* C.ULT.S */
3742               {
3743                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3744                  emit_ucomiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // ucomiss xmm0,[ftreg]
3745               }
3746               else            /* C.ULT.D */
3747               {
3748                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3749                  emit_ucomisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // ucomisd xmm0,[ftreg]
3750               }
3751               emit_setcc_m8(DRCTOP, COND_B, CF1ADDR((op >> 8) & 7));               // setb fcc[x]
3752               return TRUE;
3753
3754            case 0x36:
3755            case 0x3e:
3756               if (IS_SINGLE(op))   /* C.OLE.S */
3757               {
3758                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3759                  emit_comiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // comiss xmm0,[ftreg]
3760               }
3761               else            /* C.OLE.D */
3762               {
3763                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3764                  emit_comisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // comisd xmm0,[ftreg]
3765               }
3766               emit_setcc_m8(DRCTOP, COND_BE, CF1ADDR((op >> 8) & 7));               // setbe fcc[x]
3767               return TRUE;
3768
3769            case 0x37:
3770            case 0x3f:
3771               if (IS_SINGLE(op))   /* C.ULE.S */
3772               {
3773                  emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));         // movss xmm0,[fsreg]
3774                  emit_ucomiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));         // ucomiss xmm0,[ftreg]
3775               }
3776               else            /* C.ULE.D */
3777               {
3778                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));         // movsd xmm0,[fsreg]
3779                  emit_ucomisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));         // ucomisd xmm0,[ftreg]
3780               }
3781               emit_setcc_m8(DRCTOP, COND_BE, CF1ADDR((op >> 8) & 7));               // setbe fcc[x]
3782               return TRUE;
3783         }
3784         break;
3785   }
3786   return FALSE;
3787}
3788
3789
3790
3791/***************************************************************************
3792    COP1X RECOMPILATION
3793***************************************************************************/
3794
3795/*-------------------------------------------------
3796    compile_cop1x - compile COP1X opcodes
3797-------------------------------------------------*/
3798
3799static int compile_cop1x(drc_core *drc, compiler_state *compiler, const opcode_desc *desc)
3800{
3801   UINT32 op = *desc->opptr.l;
3802
3803   if (mips3.drcoptions & MIPS3DRC_STRICT_COP1)
3804   {
3805      emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_COP1);                     // test [mips3.core->cpr[0][COP0_Status]],SR_COP1
3806      oob_request_callback(drc, COND_Z, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_cop_exception);
3807                                                                     // jz   generate_cop_exception
3808   }
3809
3810   switch (op & 0x3f)
3811   {
3812      case 0x00:      /* LWXC1 */
3813         return compile_loadx_cop(drc, compiler, desc, 4, FPR32(FDREG));
3814
3815      case 0x01:      /* LDXC1 */
3816         return compile_loadx_cop(drc, compiler, desc, 8, FPR64(FDREG));
3817
3818      case 0x08:      /* SWXC1 */
3819         return compile_storex_cop(drc, compiler, desc, 4, FPR32(FDREG));
3820
3821      case 0x09:      /* SDXC1 */
3822         return compile_storex_cop(drc, compiler, desc, 8, FPR64(FDREG));
3823
3824      case 0x0f:      /* PREFX */
3825         return TRUE;
3826
3827      case 0x20:      /* MADD.S */
3828         emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));                  // movss xmm0,[fsreg]
3829         emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));                  // mulss xmm0,[ftreg]
3830         emit_addss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FRREG));                  // addss xmm0,[frreg]
3831         emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);                  // movss [fdreg],xmm0
3832         return TRUE;
3833
3834      case 0x21:      /* MADD.D */
3835         emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));                  // movsd xmm0,[fsreg]
3836         emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));                  // mulsd xmm0,[ftreg]
3837         emit_addsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FRREG));                  // addsd xmm0,[frreg]
3838         emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);                  // movsd [fdreg],xmm0
3839         return TRUE;
3840
3841      case 0x28:      /* MSUB.S */
3842         emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));                  // movss xmm0,[fsreg]
3843         emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));                  // mulss xmm0,[ftreg]
3844         emit_subss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FRREG));                  // subss xmm0,[frreg]
3845         emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);                  // movss [fdreg],xmm0
3846         return TRUE;
3847
3848      case 0x29:      /* MSUB.D */
3849         emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));                  // movsd xmm0,[fsreg]
3850         emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));                  // mulsd xmm0,[ftreg]
3851         emit_subsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FRREG));                  // subsd xmm0,[frreg]
3852         emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);                  // movsd [fdreg],xmm0
3853         return TRUE;
3854
3855      case 0x30:      /* NMADD.S */
3856         emit_xorps_r128_r128(DRCTOP, REG_XMM1, REG_XMM1);                        // xorps xmm1,xmm1
3857         emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));                  // movss xmm0,[fsreg]
3858         emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));                  // mulss xmm0,[ftreg]
3859         emit_addss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FRREG));                  // addss xmm0,[frreg]
3860         emit_subss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0);                        // subss xmm1,xmm0
3861         emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM1);                  // movss [fdreg],xmm1
3862         return TRUE;
3863
3864      case 0x31:      /* NMADD.D */
3865         emit_xorps_r128_r128(DRCTOP, REG_XMM1, REG_XMM1);                        // xorps xmm1,xmm1
3866         emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));                  // movsd xmm0,[fsreg]
3867         emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));                  // mulsd xmm0,[ftreg]
3868         emit_addsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FRREG));                  // addsd xmm0,[frreg]
3869         emit_subsd_r128_r128(DRCTOP, REG_XMM1, REG_XMM0);                        // subsd xmm1,xmm0
3870         emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM1);                  // movsd [fdreg],xmm1
3871         return TRUE;
3872
3873      case 0x38:      /* NMSUB.S */
3874         emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));                  // movss xmm0,[fsreg]
3875         emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));                  // mulss xmm0,[ftreg]
3876         emit_movss_r128_m32(DRCTOP, REG_XMM1, FPR32ADDR(FRREG));                  // movss xmm1,[frreg]
3877         emit_subss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0);                        // subss xmm1,xmm0
3878         emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM1);                  // movss [fdreg],xmm1
3879         return TRUE;
3880
3881      case 0x39:      /* NMSUB.D */
3882         emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));                  // movsd xmm0,[fsreg]
3883         emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));                  // mulsd xmm0,[ftreg]
3884         emit_movsd_r128_m64(DRCTOP, REG_XMM1, FPR64ADDR(FRREG));                  // movsd xmm1,[frreg]
3885         emit_subsd_r128_r128(DRCTOP, REG_XMM1, REG_XMM0);                        // subsd xmm1,xmm0
3886         emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM1);                  // movsd [fdreg],xmm1
3887         return TRUE;
3888
3889      case 0x24:      /* MADD.W */
3890      case 0x25:      /* MADD.L */
3891      case 0x2c:      /* MSUB.W */
3892      case 0x2d:      /* MSUB.L */
3893      case 0x34:      /* NMADD.W */
3894      case 0x35:      /* NMADD.L */
3895      case 0x3c:      /* NMSUB.W */
3896      case 0x3d:      /* NMSUB.L */
3897      default:
3898         fprintf(stderr, "cop1x %X\n", op);
3899         break;
3900   }
3901   return FALSE;
3902}
3903
3904
3905
3906/***************************************************************************
3907    INDIVIDUAL INSTRUCTION COMPILATION
3908***************************************************************************/
3909
3910/*-------------------------------------------------
3911    compile_shift - compile a 32-bit
3912    shift, both fixed and variable counts
3913
3914    0: sll/sllv rD,rT,rS
3915    2: srl/srlv rD,rT,rS
3916    3: sra/srav rD,rT,rS
3917-------------------------------------------------*/
3918
3919static int compile_shift(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int shift_type, int shift_variable)
3920{
3921   UINT32 op = *desc->opptr.l;
3922   mipsreg_state rd, rs, rt;
3923
3924   assert(shift_type == 0 || shift_type == 2 || shift_type == 3);
3925
3926   /* if the destination is r0, bail */
3927   if (RDREG == 0)
3928      return TRUE;
3929
3930   /* allocate source registers */
3931   rs = shift_variable ? compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC) : MAKE_CONST(SHIFT);
3932   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
3933
3934   /* if rS and rT are both constant, we can compute the constant result */
3935   if (ISCONST(rs) && ISCONST(rt))
3936   {
3937      if (shift_type == 0)
3938         emit_set_constant_value(drc, compiler, desc, RDREG, (INT32)((UINT32)CONSTVAL(rt) << CONSTVAL(rs)));
3939      else if (shift_type == 2)
3940         emit_set_constant_value(drc, compiler, desc, RDREG, (INT32)((UINT32)CONSTVAL(rt) >> CONSTVAL(rs)));
3941      else
3942         emit_set_constant_value(drc, compiler, desc, RDREG, (INT32)((INT32)CONSTVAL(rt) >> CONSTVAL(rs)));
3943   }
3944
3945   /* otherwise, handle generically */
3946   else
3947   {
3948      /* allocate the register and load rT into it */
3949      /* if rS is non-const, must load it first in case rD == rS */
3950      rd = compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_DST | ALLOC_DIRTY);
3951      if (!ISCONST(rs))
3952         emit_load_register_value(drc, compiler, REG_ECX, rs);                     // mov  ecx,<rs>
3953      emit_load_register_value(drc, compiler, X86REG(rd), rt);                     // mov  <rd>,<rt>
3954
3955      /* if rs is constant, use immediate forms of the shift */
3956      if (ISCONST(rs))
3957      {
3958         if (shift_type == 0)
3959            emit_shl_r32_imm(DRCTOP, X86REG(rd), CONSTVAL(rs) & 31);               // shl  <rd>,<rs>
3960         else if (shift_type == 2)
3961            emit_shr_r32_imm(DRCTOP, X86REG(rd), CONSTVAL(rs) & 31);               // shr  <rd>,<rs>
3962         else
3963            emit_sar_r32_imm(DRCTOP, X86REG(rd), CONSTVAL(rs) & 31);               // sar  <rd>,<rs>
3964      }
3965
3966      /* otherwise, load rs into cl so we can do a variable shift */
3967      else
3968      {
3969         if (shift_type == 0)
3970            emit_shl_r32_cl(DRCTOP, X86REG(rd));                              // shl  <rd>,cl
3971         else if (shift_type == 2)
3972            emit_shr_r32_cl(DRCTOP, X86REG(rd));                              // shr  <rd>,cl
3973         else
3974            emit_sar_r32_cl(DRCTOP, X86REG(rd));                              // sar  <rd>,cl
3975      }
3976      emit_movsxd_r64_r32(DRCTOP, X86REG(rd), X86REG(rd));                        // movsxd <rd>,<rd>
3977   }
3978   return TRUE;
3979}
3980
3981
3982/*-------------------------------------------------
3983    compile_dshift - compile a 64-bit
3984    shift, both fixed and variable counts
3985
3986    0: dsll/dsll32/dsllv rD,rT,rS
3987    2: dsrl/dsrl32/dsrlv rD,rT,rS
3988    3: dsra/dsra32/dsrav rD,rT,rS
3989-------------------------------------------------*/
3990
3991static int compile_dshift(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int shift_type, int shift_variable, int shift_const_plus32)
3992{
3993   UINT32 op = *desc->opptr.l;
3994   mipsreg_state rd, rs, rt;
3995
3996   assert(shift_type == 0 || shift_type == 2 || shift_type == 3);
3997
3998   /* if the destination is r0, bail */
3999   if (RDREG == 0)
4000      return TRUE;
4001
4002   /* allocate source registers */
4003   rs = shift_variable ? compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC) : MAKE_CONST(SHIFT + (shift_const_plus32 ? 32 : 0));
4004   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4005
4006   /* if rS and rT are both constant, we can compute the constant result */
4007   if (ISCONST(rs) && ISCONST(rt))
4008   {
4009      if (shift_type == 0)
4010         emit_set_constant_value(drc, compiler, desc, RDREG, (UINT64)CONSTVAL(rt) << CONSTVAL(rs));
4011      else if (shift_type == 2)
4012         emit_set_constant_value(drc, compiler, desc, RDREG, (UINT64)CONSTVAL(rt) >> CONSTVAL(rs));
4013      else
4014         emit_set_constant_value(drc, compiler, desc, RDREG, (INT64)CONSTVAL(rt) >> CONSTVAL(rs));
4015   }
4016
4017   /* otherwise, handle generically */
4018   else
4019   {
4020      /* allocate the register and load rT into it */
4021      /* if rS is non-const, must load it first in case rD == rS */
4022      rd = compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_DST | ALLOC_DIRTY);
4023      if (!ISCONST(rs))
4024         emit_load_register_value(drc, compiler, REG_ECX, rs);                     // mov  ecx,<rs>
4025      emit_load_register_value(drc, compiler, X86REG(rd), rt);                     // mov  <rd>,<rt>
4026
4027      /* if rs is constant, use immediate forms of the shift */
4028      if (ISCONST(rs))
4029      {
4030         if (shift_type == 0)
4031            emit_shl_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rs) & 63);               // shl  <rd>,<rs>
4032         else if (shift_type == 2)
4033            emit_shr_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rs) & 63);               // shr  <rd>,<rs>
4034         else
4035            emit_sar_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rs) & 63);               // sar  <rd>,<rs>
4036      }
4037
4038      /* otherwise, load rs into cl so we can do a variable shift */
4039      else
4040      {
4041         if (shift_type == 0)
4042            emit_shl_r64_cl(DRCTOP, X86REG(rd));                              // shl  <rd>,cl
4043         else if (shift_type == 2)
4044            emit_shr_r64_cl(DRCTOP, X86REG(rd));                              // shr  <rd>,cl
4045         else
4046            emit_sar_r64_cl(DRCTOP, X86REG(rd));                              // sar  <rd>,cl
4047      }
4048   }
4049   return TRUE;
4050}
4051
4052
4053/*-------------------------------------------------
4054    compile_movzn - compile a conditional
4055    move based on compare against 0
4056
4057    movz/movn rD,rS,rT
4058-------------------------------------------------*/
4059
4060static int compile_movzn(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_movn)
4061{
4062   UINT32 op = *desc->opptr.l;
4063   mipsreg_state rd, rs, rt;
4064   emit_link skip = { 0 };
4065
4066   /* if the destination is r0, bail */
4067   if (RDREG == 0)
4068      return TRUE;
4069
4070   /* allocate source registers */
4071   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4072   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4073   rd = compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_SRC | ALLOC_DST | ALLOC_DIRTY);
4074
4075   /* if rT is constant and fails the condition, we're done */
4076   if (ISCONST(rt))
4077   {
4078      INT32 rtval = CONSTVAL(rt);
4079      if ((is_movn && rtval == 0) || (!is_movn && rtval != 0))
4080         return TRUE;
4081   }
4082
4083   /* if rT is not constant, check the condition */
4084   else
4085   {
4086      emit_test_r64_r64(DRCTOP, X86REG(rt), X86REG(rt));                           // test <rt>,<rt>
4087      emit_jcc_short_link(DRCTOP, is_movn ? COND_Z : COND_NZ, &skip);                  // jz/nz skip
4088   }
4089
4090   /* load rS into rD */
4091   emit_load_register_value(drc, compiler, X86REG(rd), rs);                        // mov  <rd>,<rs>
4092   if (!ISCONST(rt))
4093      resolve_link(DRCTOP, &skip);                                       // skip:
4094
4095   return TRUE;
4096}
4097
4098
4099/*-------------------------------------------------
4100    compile_trapcc - compile a conditional
4101    trap comparing two registers
4102
4103    0/1: tge/tgeu rS,rT / tgei/tgeiu rS,SIMM
4104    2/3: tlt/tltu rS,rT / tlti/tltiu rS,SIMM
4105      4: teq      rS,rT / teqi       rS,SIMM
4106      6: tne      rS,rT / tnei       rS,SIMM
4107-------------------------------------------------*/
4108
4109static int compile_trapcc(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int condition, int immediate)
4110{
4111   static const UINT8 condtype[] = { COND_GE, COND_AE, COND_L, COND_B, COND_E, COND_NONE, COND_NE, COND_NONE };
4112   UINT32 op = *desc->opptr.l;
4113   mipsreg_state rs, rt;
4114
4115   assert(condition < ARRAY_LENGTH(condtype) && condtype[condition] != COND_NONE);
4116
4117   /* allocate source registers */
4118   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4119   rt = immediate ? MAKE_CONST(SIMMVAL) : compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4120
4121   /* if both constant, we know the answer up front */
4122   if (ISCONST(rs) && ISCONST(rt))
4123   {
4124      INT32 rsval = CONSTVAL(rs);
4125      INT32 rtval = CONSTVAL(rt);
4126      int result = FALSE;
4127
4128      /* determine the fixed answer */
4129      switch (condition)
4130      {
4131         case 0:      result = ((INT64)rsval >= (INT64)rtval);      break;
4132         case 1:      result = ((UINT64)rsval >= (UINT64)rtval);      break;
4133         case 2:      result = ((INT64)rsval < (INT64)rtval);         break;
4134         case 3:      result = ((UINT64)rsval < (UINT64)rtval);      break;
4135         case 4:      result = (rsval == rtval);                  break;
4136         case 6:      result = (rsval != rtval);                  break;
4137      }
4138
4139      /* if we're not trapping, just return; otherwise, always trap */
4140      if (!result)
4141         return TRUE;
4142      condition = COND_NONE;
4143   }
4144
4145   /* if rT is constant do an immediate compare */
4146   else if (ISCONST(rt))
4147   {
4148      emit_cmp_r64_imm(DRCTOP, X86REG(rs), CONSTVAL(rt));                           // cmp  <rs>,<rt>
4149      condition = condtype[condition];
4150   }
4151
4152   /* if rS is constant do an immediate compare with opposite condition */
4153   else if (ISCONST(rs))
4154   {
4155      emit_cmp_r64_imm(DRCTOP, X86REG(rt), CONSTVAL(rs));                           // cmp  <rt>,<rs>
4156      condition = condtype[condition] ^ 1;
4157   }
4158
4159   /* otherwise, compare the two registers with a normal condition */
4160   else
4161   {
4162      emit_cmp_r64_imm(DRCTOP, X86REG(rs), X86REG(rt));                           // cmp  <rs>,<rt>
4163      condition = condtype[condition];
4164   }
4165
4166   /* generate an OOB request if the trap is taken */
4167   oob_request_callback(drc, condition, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_trap_exception);
4168   return TRUE;
4169}
4170
4171
4172/*-------------------------------------------------
4173    compile_branchcc - compile a conditional
4174    branch comparing two registers
4175
4176    beq rS,rT,dest
4177    bne rS,rT,dest
4178-------------------------------------------------*/
4179
4180static int compile_branchcc(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int condition)
4181{
4182   UINT32 op = *desc->opptr.l;
4183   emit_link skip = { 0 };
4184   mipsreg_state rs, rt;
4185
4186   assert(condition == COND_E || condition == COND_NE);
4187
4188   /* allocate source registers */
4189   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4190   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4191
4192   /* if both constant, we know the answer up front */
4193   if (ISCONST(rs) && ISCONST(rt))
4194   {
4195      INT32 rsval = CONSTVAL(rs);
4196      INT32 rtval = CONSTVAL(rt);
4197      if ((condition == COND_E && rsval != rtval) || (condition == COND_NE && rsval == rtval))
4198         return TRUE;
4199   }
4200
4201   /* if rT is constant do an immediate compare */
4202   else if (ISCONST(rt))
4203   {
4204      emit_cmp_r64_imm(DRCTOP, X86REG(rs), CONSTVAL(rt));                           // cmp  <rs>,<rt>
4205      emit_jcc_near_link(DRCTOP, condition ^ 1, &skip);                           // jncc skip
4206   }
4207
4208   /* if rS is constant do an immediate compare */
4209   else if (ISCONST(rs))
4210   {
4211      emit_cmp_r64_imm(DRCTOP, X86REG(rt), CONSTVAL(rs));                           // cmp  <rt>,<rs>
4212      emit_jcc_near_link(DRCTOP, condition ^ 1, &skip);                           // jncc skip
4213   }
4214
4215   /* otherwise, compare the two registers with a normal condition */
4216   else
4217   {
4218      emit_cmp_r64_r64(DRCTOP, X86REG(rs), X86REG(rt));                           // cmp  <rs>,<rt>
4219      emit_jcc_near_link(DRCTOP, condition ^ 1, &skip);                           // jncc skip
4220   }
4221
4222   /* append the branch logic */
4223   emit_delay_slot_and_branch(drc, compiler, desc, 0);                              // <next instruction + redispatch>
4224
4225   if (!(ISCONST(rs) && ISCONST(rt)))
4226      resolve_link(DRCTOP, &skip);                                       // skip:
4227   return TRUE;
4228}
4229
4230
4231/*-------------------------------------------------
4232    compile_branchcz - compile a conditional
4233    branch comparing one register against 0
4234
4235    blez    rS,dest
4236    blezl   rS,dest
4237    bgtz    rS,dest
4238    bgtzl   rS,dest
4239    bltz    rS,dest
4240    bltzl   rS,dest
4241    bltzal  rS,dest
4242    bltzall rS,dest
4243    bgez    rS,dest
4244    bgezl   rS,dest
4245    bgezal  rS,dest
4246    bgezall rS,dest
4247-------------------------------------------------*/
4248
4249static int compile_branchcz(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int condition, int link)
4250{
4251   UINT32 op = *desc->opptr.l;
4252   emit_link skip = { 0 };
4253   mipsreg_state rs;
4254
4255   /* allocate source registers */
4256   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4257
4258   /* if the register is constant, we know the answer up front */
4259   if (ISCONST(rs))
4260   {
4261      INT32 rsval = CONSTVAL(rs);
4262      if ((condition == COND_LE && rsval > 0) || (condition == COND_G && rsval <= 0) ||
4263         (condition == COND_L && rsval >= 0) || (condition == COND_GE && rsval < 0))
4264         return TRUE;
4265   }
4266
4267   /* otherwise, perform the compare */
4268   else
4269   {
4270      emit_cmp_r64_imm(DRCTOP, X86REG(rs), 0);                                 // cmp  <rs>,0
4271      emit_jcc_near_link(DRCTOP, condition ^ 1, &skip);                           // jncc skip
4272   }
4273
4274   /* append the branch logic */
4275   emit_delay_slot_and_branch(drc, compiler, desc, link ? 31 : 0);                     // <next instruction + redispatch>
4276
4277   if (!ISCONST(rs))
4278      resolve_link(DRCTOP, &skip);                                       // skip:
4279   return TRUE;
4280}
4281
4282
4283/*-------------------------------------------------
4284    compile_add - compile an add with or without
4285    overflow
4286
4287    add  rD,rS,rT / addi  rT,rS,SIMM
4288    addu rD,rS,rT / addiu rT,rS,SIMM
4289-------------------------------------------------*/
4290
4291static int compile_add(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int suppress_exceptions, int immediate)
4292{
4293   UINT32 op = *desc->opptr.l;
4294   UINT8 destreg = immediate ? RTREG : RDREG;
4295   mipsreg_state rd, rs, rt;
4296
4297   /* note that we still must perform this operation even if destreg == 0
4298       in the overflow case */
4299   if (destreg == 0 && suppress_exceptions)
4300      return TRUE;
4301
4302   /* allocate source registers */
4303   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4304   rt = immediate ? MAKE_CONST(SIMMVAL) : compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4305
4306   /* if both constant, we know the answer up front */
4307   if (ISCONST(rs) && ISCONST(rt))
4308   {
4309      INT64 result = (INT64)CONSTVAL(rs) + (INT64)CONSTVAL(rt);
4310
4311      /* if we overflow, always generate an exception */
4312      if (!suppress_exceptions && (INT32)result != result)
4313         oob_request_callback(drc, COND_NONE, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_overflow_exception);
4314
4315      /* else just set the new constant value */
4316      else if (destreg != 0)
4317         emit_set_constant_value(drc, compiler, desc, destreg, (INT32)result);
4318   }
4319
4320   /* otherwise, handle generically */
4321   else
4322   {
4323      rd = compiler_register_allocate(drc, compiler, desc, destreg, ALLOC_DST);
4324
4325      /* perform the operating in EAX so we don't trash rD if an exception happens */
4326      if (!suppress_exceptions)
4327      {
4328         emit_load_register_value(drc, compiler, REG_EAX, rs);                     // mov  eax,<rs>
4329         if (!ISCONST(rt))
4330            emit_add_r32_r32(DRCTOP, REG_EAX, X86REG(rt));                        // add  eax,<rt>
4331         else if (CONSTVAL(rt) != 0)
4332            emit_add_r32_imm(DRCTOP, REG_EAX, CONSTVAL(rt));                     // add  eax,<rt>
4333         oob_request_callback(drc, COND_O, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_overflow_exception);
4334                                                                     // jo   generate_overflow_exception
4335         if (destreg != 0)
4336            emit_movsxd_r64_r32(DRCTOP, X86REG(rd), REG_EAX);                     // movsxd <rd>,eax
4337      }
4338      else
4339      {
4340         if (ISCONST(rs) && CONSTVAL(rs) == 0)
4341            emit_movsxd_r64_r32(DRCTOP, X86REG(rd), X86REG(rt));                  // movsxd <rd>,<rt>
4342         else if (ISCONST(rt) && CONSTVAL(rt) == 0)
4343            emit_movsxd_r64_r32(DRCTOP, X86REG(rd), X86REG(rs));                  // movsxd <rd>,<rs>
4344         else if (ISCONST(rs))
4345         {
4346            emit_lea_r32_m32(DRCTOP, X86REG(rd), MBD(X86REG(rt), CONSTVAL(rs)));      // lea  <rd>,[<rt> + <rs>]
4347            emit_movsxd_r64_r32(DRCTOP, X86REG(rd), X86REG(rd));                  // movsxd <rd>,<rd>
4348         }
4349         else if (ISCONST(rt))
4350         {
4351            emit_lea_r32_m32(DRCTOP, X86REG(rd), MBD(X86REG(rs), CONSTVAL(rt)));      // lea  <rd>,[<rs> + <rt>]
4352            emit_movsxd_r64_r32(DRCTOP, X86REG(rd), X86REG(rd));                  // movsxd <rd>,<rd>
4353         }
4354         else
4355         {
4356            emit_lea_r32_m32(DRCTOP, X86REG(rd), MBISD(X86REG(rs), X86REG(rt), 1, 0));   // lea  <rd>,[<rs> + <rt>]
4357            emit_movsxd_r64_r32(DRCTOP, X86REG(rd), X86REG(rd));                  // movsxd <rd>,<rd>
4358         }
4359      }
4360
4361      /* only mark it dirty after the exception risk is over */
4362      compiler_register_allocate(drc, compiler, desc, destreg, ALLOC_DIRTY);
4363   }
4364   return TRUE;
4365}
4366
4367
4368/*-------------------------------------------------
4369    compile_dadd - compile an add with or without
4370    overflow
4371
4372    dadd  rD,rS,rT
4373    daddu rD,rS,rT
4374-------------------------------------------------*/
4375
4376static int compile_dadd(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int suppress_exceptions, int immediate)
4377{
4378   UINT32 op = *desc->opptr.l;
4379   UINT8 destreg = immediate ? RTREG : RDREG;
4380   mipsreg_state rd, rs, rt;
4381
4382   /* note that we still must perform this operation even if destreg == 0
4383       in the overflow case */
4384   if (destreg == 0 && suppress_exceptions)
4385      return TRUE;
4386
4387   /* allocate source registers */
4388   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4389   rt = immediate ? MAKE_CONST(SIMMVAL) : compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4390
4391   /* if both constant, we know the answer up front */
4392   if (ISCONST(rs) && ISCONST(rt))
4393   {
4394      INT64 result = (INT64)CONSTVAL(rs) + (INT64)CONSTVAL(rt);
4395
4396      /* if we overflow, always generate an exception */
4397      if (!suppress_exceptions && (INT32)result != result)
4398         oob_request_callback(drc, COND_NONE, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_overflow_exception);
4399
4400      /* else just set the new constant value */
4401      else if (destreg != 0)
4402         emit_set_constant_value(drc, compiler, desc, destreg, result);
4403   }
4404
4405   /* otherwise, handle generically */
4406   else
4407   {
4408      rd = compiler_register_allocate(drc, compiler, desc, destreg, ALLOC_DST);
4409
4410      /* perform the operating in EAX so we don't trash RTREG if an exception happens */
4411      if (!suppress_exceptions)
4412      {
4413         emit_load_register_value(drc, compiler, REG_RAX, rs);                     // mov  rax,<rs>
4414         if (!ISCONST(rt))
4415            emit_add_r64_r64(DRCTOP, REG_RAX, X86REG(rt));                        // add  rax,<rt>
4416         else if (CONSTVAL(rt) != 0)
4417            emit_add_r64_imm(DRCTOP, REG_RAX, CONSTVAL(rt));                     // add  rax,<rt>
4418         oob_request_callback(drc, COND_O, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_overflow_exception);
4419                                                                     // jo   generate_overflow_exception
4420         if (destreg != 0)
4421            emit_mov_r64_r64(DRCTOP, X86REG(rd), REG_RAX);                        // mov  <rd>,rax
4422      }
4423      else
4424      {
4425         if (ISCONST(rs))
4426            emit_lea_r64_m64(DRCTOP, X86REG(rd), MBD(X86REG(rt), CONSTVAL(rs)));      // lea  <rd>,[<rt> + <rs>]
4427         else if (ISCONST(rt))
4428            emit_lea_r64_m64(DRCTOP, X86REG(rd), MBD(X86REG(rs), CONSTVAL(rt)));      // lea  <rd>,[<rs> + <rt>]
4429         else
4430            emit_lea_r64_m64(DRCTOP, X86REG(rd), MBISD(X86REG(rs), X86REG(rt), 1, 0));   // lea  <rd>,[<rs> + <rt>]
4431      }
4432
4433      /* only mark it dirty after the exception risk is over */
4434      compiler_register_allocate(drc, compiler, desc, destreg, ALLOC_DIRTY);
4435   }
4436   return TRUE;
4437}
4438
4439
4440/*-------------------------------------------------
4441    compile_sub - compile an add with or without
4442    overflow
4443
4444    sub  rD,rS,rT
4445    subu rD,rS,rT
4446-------------------------------------------------*/
4447
4448static int compile_sub(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int suppress_exceptions)
4449{
4450   UINT32 op = *desc->opptr.l;
4451   mipsreg_state rd, rs, rt;
4452
4453   /* note that we still must perform this operation even if RDREG == 0
4454       in the overflow case */
4455   if (RDREG == 0 && suppress_exceptions)
4456      return TRUE;
4457
4458   /* allocate source registers */
4459   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4460   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4461
4462   /* if both constant, we know the answer up front */
4463   if (ISCONST(rs) && ISCONST(rt))
4464   {
4465      INT64 result = (INT64)CONSTVAL(rs) - (INT64)CONSTVAL(rt);
4466
4467      /* if we overflow, always generate an exception */
4468      if (!suppress_exceptions && (INT32)result != result)
4469         oob_request_callback(drc, COND_NONE, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_overflow_exception);
4470
4471      /* else just set the new constant value */
4472      else if (RDREG != 0)
4473         emit_set_constant_value(drc, compiler, desc, RDREG, (INT32)result);
4474   }
4475
4476   /* if rS == rT, the result is 0 */
4477   else if (RSREG == RTREG)
4478   {
4479      if (RDREG != 0)
4480         emit_set_constant_value(drc, compiler, desc, RDREG, 0);
4481   }
4482
4483   /* otherwise, handle generically */
4484   else
4485   {
4486      rd = compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_DST);
4487
4488      /* perform the operating in EAX so we don't trash RTREG if an exception happens */
4489      if (!suppress_exceptions)
4490      {
4491         emit_load_register_value(drc, compiler, REG_EAX, rs);                     // mov  eax,<rs>
4492         if (!ISCONST(rt))
4493            emit_sub_r32_r32(DRCTOP, REG_EAX, X86REG(rt));                        // sub  eax,<rt>
4494         else if (CONSTVAL(rt) != 0)
4495            emit_sub_r32_imm(DRCTOP, REG_EAX, CONSTVAL(rt));                     // sub  eax,<rt>
4496         if (!ISCONST(rt) || CONSTVAL(rt) != 0)
4497            oob_request_callback(drc, COND_O, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_overflow_exception);
4498                                                                     // jo   generate_overflow_exception
4499         if (RDREG != 0)
4500            emit_movsxd_r64_r32(DRCTOP, X86REG(rd), REG_EAX);                     // movsxd <rd>,eax
4501      }
4502      else
4503      {
4504         /* if rD and rT aren't the same, it is pretty basic */
4505         if (X86REG(rd) != X86REG(rt))
4506         {
4507            emit_load_register_value(drc, compiler, X86REG(rd), rs);               // mov  <rd>,<rs>
4508            if (!ISCONST(rt))
4509               emit_sub_r32_r32(DRCTOP, X86REG(rd), X86REG(rt));                  // sub  <rd>,<rt>
4510            else if (CONSTVAL(rt) != 0)
4511               emit_sub_r32_imm(DRCTOP, X86REG(rd), CONSTVAL(rt));                  // sub  <rd>,<rt>
4512         }
4513
4514         /* otherwise, we negate rT and add rS */
4515         else
4516         {
4517            emit_neg_r32(DRCTOP, X86REG(rd));                                 // neg  <rd>
4518            if (!ISCONST(rs))
4519               emit_add_r32_r32(DRCTOP, X86REG(rd), X86REG(rs));                  // add  <rd>,<rs>
4520            else if (CONSTVAL(rs) != 0)
4521               emit_add_r32_imm(DRCTOP, X86REG(rd), CONSTVAL(rs));                  // add  <rd>,<rs>
4522         }
4523         emit_movsxd_r64_r32(DRCTOP, X86REG(rd), X86REG(rd));                     // movsxd <rd>,<rd>
4524      }
4525
4526      /* only mark it dirty after the exception risk is over */
4527      compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_DIRTY);
4528   }
4529   return TRUE;
4530}
4531
4532
4533/*-------------------------------------------------
4534    compile_dsub - compile an add with or without
4535    overflow
4536
4537    dsub  rD,rS,rT
4538    dsubu rD,rS,rT
4539-------------------------------------------------*/
4540
4541static int compile_dsub(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int suppress_exceptions)
4542{
4543   UINT32 op = *desc->opptr.l;
4544   mipsreg_state rd, rs, rt;
4545
4546   /* note that we still must perform this operation even if RDREG == 0
4547       in the overflow case */
4548   if (RDREG == 0 && suppress_exceptions)
4549      return TRUE;
4550
4551   /* allocate source registers */
4552   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4553   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4554
4555   /* if both constant, we know the answer up front */
4556   if (ISCONST(rs) && ISCONST(rt))
4557   {
4558      INT64 result = (INT64)CONSTVAL(rs) - (INT64)CONSTVAL(rt);
4559
4560      /* if we overflow, always generate an exception */
4561      if (!suppress_exceptions && (INT32)result != result)
4562         oob_request_callback(drc, COND_NONE, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_overflow_exception);
4563
4564      /* else just set the new constant value */
4565      else if (RDREG != 0)
4566         emit_set_constant_value(drc, compiler, desc, RDREG, result);
4567   }
4568
4569   /* if rS == rT, the result is 0 */
4570   else if (RSREG == RTREG)
4571   {
4572      if (RDREG != 0)
4573         emit_set_constant_value(drc, compiler, desc, RDREG, 0);
4574   }
4575
4576   /* otherwise, handle generically */
4577   else
4578   {
4579      rd = compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_DST);
4580
4581      /* perform the operating in EAX so we don't trash RTREG if an exception happens */
4582      if (!suppress_exceptions)
4583      {
4584         emit_load_register_value(drc, compiler, REG_EAX, rs);                  // mov  eax,<rs>
4585         if (!ISCONST(rt))
4586            emit_sub_r64_r64(DRCTOP, REG_RAX, X86REG(rt));                        // sub  rax,<rt>
4587         else if (CONSTVAL(rt) != 0)
4588            emit_sub_r64_imm(DRCTOP, REG_RAX, CONSTVAL(rt));                     // sub  rax,<rt>
4589         if (!ISCONST(rt) || CONSTVAL(rt) != 0)
4590            oob_request_callback(drc, COND_O, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_overflow_exception);
4591                                                                     // jo   generate_overflow_exception
4592         if (RDREG != 0)
4593            emit_mov_r64_r64(DRCTOP, X86REG(rd), REG_RAX);                        // mov  <rd>,rax
4594      }
4595      else
4596      {
4597         /* if rD and rT aren't the same, it is pretty basic */
4598         if (X86REG(rd) != X86REG(rt))
4599         {
4600            emit_load_register_value(drc, compiler, X86REG(rd), rs);               // mov  <rd>,<rs>
4601            if (!ISCONST(rt))
4602               emit_sub_r64_r64(DRCTOP, X86REG(rd), X86REG(rt));                  // sub  <rd>,<rt>
4603            else if (CONSTVAL(rt) != 0)
4604               emit_sub_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rt));                  // sub  <rd>,<rt>
4605         }
4606
4607         /* otherwise, we negate rT and add rS */
4608         else
4609         {
4610            emit_neg_r64(DRCTOP, X86REG(rd));                                 // neg  <rd>
4611            if (!ISCONST(rs))
4612               emit_add_r64_r64(DRCTOP, X86REG(rd), X86REG(rs));                  // add  <rd>,<rs>
4613            else if (CONSTVAL(rs) != 0)
4614               emit_add_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rs));                  // add  <rd>,<rs>
4615         }
4616      }
4617
4618      /* only mark it dirty after the exception risk is over */
4619      compiler_register_allocate(drc, compiler, desc, RDREG, ALLOC_DIRTY);
4620   }
4621   return TRUE;
4622}
4623
4624
4625/*-------------------------------------------------
4626    compile_mult - compile a 32-bit multiply
4627    instruction
4628
4629    mult  rS,rT
4630    multu rS,rT
4631-------------------------------------------------*/
4632
4633static int compile_mult(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned)
4634{
4635   UINT32 op = *desc->opptr.l;
4636   mipsreg_state rs, rt, lo, hi;
4637
4638   /* allocate source registers */
4639   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4640   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4641
4642   /* if both constant, we know the answer up front */
4643   if (ISCONST(rs) && ISCONST(rt))
4644   {
4645      UINT64 result = is_unsigned ? ((UINT64)CONSTVAL(rs) * (UINT64)CONSTVAL(rt)) : ((INT64)CONSTVAL(rs) * (INT64)CONSTVAL(rt));
4646      emit_set_constant_value(drc, compiler, desc, REG_LO, (INT32)result);
4647      emit_set_constant_value(drc, compiler, desc, REG_HI, (INT32)(result >> 32));
4648   }
4649
4650   /* otherwise, handle generically */
4651   else
4652   {
4653      UINT8 mulreg = ISCONST(rt) ? REG_ECX : X86REG(rt);
4654
4655      hi = compiler_register_allocate(drc, compiler, desc, REG_HI, ALLOC_DST | ALLOC_DIRTY);
4656      lo = compiler_register_allocate(drc, compiler, desc, REG_LO, ALLOC_DST | ALLOC_DIRTY);
4657
4658      emit_load_register_value(drc, compiler, REG_EAX, rs);                        // mov  eax,<rs>
4659      emit_load_register_value(drc, compiler, mulreg, rt);                        // mov  <mulreg>,<rt>
4660      if (is_unsigned)
4661         emit_mul_r32(DRCTOP, mulreg);                                       // mul  <mulreg>
4662      else
4663         emit_imul_r32(DRCTOP, mulreg);                                       // imul <mulreg>
4664      emit_movsxd_r64_r32(DRCTOP, X86REG(hi), REG_EDX);                           // movsxd <hireg>,edx
4665      emit_movsxd_r64_r32(DRCTOP, X86REG(lo), REG_EAX);                           // movsxd <loreg>,eax
4666   }
4667   return TRUE;
4668}
4669
4670
4671/*-------------------------------------------------
4672    compile_dmult - compile a 64-bit multiply
4673    instruction
4674
4675    dmult  rS,rT
4676    dmultu rS,rT
4677-------------------------------------------------*/
4678
4679static int compile_dmult(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned)
4680{
4681   UINT32 op = *desc->opptr.l;
4682   mipsreg_state rs, rt, lo, hi;
4683
4684   /* allocate source registers */
4685   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4686   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4687
4688   /* if both constant, we know the answer up front */
4689   if (ISCONST(rs) && ISCONST(rt))
4690   {
4691      UINT64 result = is_unsigned ? ((UINT64)CONSTVAL(rs) * (UINT64)CONSTVAL(rt)) : ((INT64)CONSTVAL(rs) * (INT64)CONSTVAL(rt));
4692      emit_set_constant_value(drc, compiler, desc, REG_LO, (INT64)result);
4693      emit_set_constant_value(drc, compiler, desc, REG_HI, (INT64)(result >> 63));
4694   }
4695
4696   /* otherwise, handle generically */
4697   else
4698   {
4699      UINT8 mulreg = ISCONST(rt) ? REG_ECX : X86REG(rt);
4700
4701      hi = compiler_register_allocate(drc, compiler, desc, REG_HI, ALLOC_DST | ALLOC_DIRTY);
4702      lo = compiler_register_allocate(drc, compiler, desc, REG_LO, ALLOC_DST | ALLOC_DIRTY);
4703
4704      emit_load_register_value(drc, compiler, REG_RAX, rs);                        // mov  rax,<rs>
4705      emit_load_register_value(drc, compiler, mulreg, rt);                        // mov  <mulreg>,<rt>
4706      if (is_unsigned)
4707         emit_mul_r64(DRCTOP, mulreg);                                       // mul  <mulreg>
4708      else
4709         emit_imul_r64(DRCTOP, mulreg);                                       // imul <mulreg>
4710      emit_mov_r64_r64(DRCTOP, X86REG(hi), REG_RDX);                              // mov  <hi>,rdx
4711      emit_mov_r64_r64(DRCTOP, X86REG(lo), REG_RAX);                              // mov  <lo>,rax
4712   }
4713   return TRUE;
4714}
4715
4716
4717/*-------------------------------------------------
4718    compile_div - compile a 32-bit divide
4719    instruction
4720
4721    div   rS,rT
4722    divu  rS,rT
4723-------------------------------------------------*/
4724
4725static int compile_div(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned)
4726{
4727   UINT32 op = *desc->opptr.l;
4728   mipsreg_state rs, rt, lo, hi;
4729
4730   /* allocate source registers */
4731   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4732   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4733
4734   /* if rT is constant and 0, just skip */
4735   if (ISCONST(rt) && CONSTVAL(rt) == 0)
4736      return TRUE;
4737
4738   /* if both constant, we know the answer up front */
4739   if (ISCONST(rs) && ISCONST(rt))
4740   {
4741      UINT32 result = is_unsigned ? ((UINT32)CONSTVAL(rs) / (UINT32)CONSTVAL(rt)) : ((INT32)CONSTVAL(rs) / (INT32)CONSTVAL(rt));
4742      UINT32 remainder = is_unsigned ? ((UINT32)CONSTVAL(rs) % (UINT32)CONSTVAL(rt)) : ((INT32)CONSTVAL(rs) % (INT32)CONSTVAL(rt));
4743
4744      emit_set_constant_value(drc, compiler, desc, REG_LO, (INT32)result);
4745      emit_set_constant_value(drc, compiler, desc, REG_HI, (INT32)remainder);
4746   }
4747
4748   /* otherwise, handle generically */
4749   else
4750   {
4751      UINT8 divreg = ISCONST(rt) ? REG_ECX : X86REG(rt);
4752      emit_link skip = { 0 };
4753
4754      hi = compiler_register_allocate(drc, compiler, desc, REG_HI, ALLOC_DST | ALLOC_DIRTY);
4755      lo = compiler_register_allocate(drc, compiler, desc, REG_LO, ALLOC_DST | ALLOC_DIRTY);
4756
4757      emit_load_register_value(drc, compiler, REG_RAX, rs);                        // mov  rax,<rs>
4758      emit_load_register_value(drc, compiler, divreg, rt);                        // mov  <divreg>,<rt>
4759      if (!ISCONST(rt))
4760      {
4761         emit_test_r32_r32(DRCTOP, divreg, divreg);                              // test <divreg>,<divreg>
4762         emit_jcc_short_link(DRCTOP, COND_Z, &skip);                              // jz   skip
4763      }
4764      if (is_unsigned)
4765      {
4766         emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                              // xor  edx,edx
4767         emit_div_r32(DRCTOP, divreg);                                       // div  <divreg>
4768      }
4769      else
4770      {
4771         emit_cdq(DRCTOP);                                                // cdq
4772         emit_idiv_r32(DRCTOP, divreg);                                       // idiv <divreg>
4773      }
4774      emit_movsxd_r64_r32(DRCTOP, X86REG(hi), REG_EDX);                           // movsxd <hi>,edx
4775      emit_movsxd_r64_r32(DRCTOP, X86REG(lo), REG_EAX);                           // movsxd <lo>,eax
4776      if (!ISCONST(rt))
4777         resolve_link(DRCTOP, &skip);                                    // skip:
4778   }
4779   return TRUE;
4780}
4781
4782
4783/*-------------------------------------------------
4784    compile_ddiv - compile a 64-bit divide
4785    instruction
4786
4787    ddiv   rS,rT
4788    ddivu  rS,rT
4789-------------------------------------------------*/
4790
4791static int compile_ddiv(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned)
4792{
4793   UINT32 op = *desc->opptr.l;
4794   mipsreg_state rs, rt, lo, hi;
4795
4796   /* allocate source registers */
4797   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4798   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4799
4800   /* if rT is constant and 0, just skip */
4801   if (ISCONST(rt) && CONSTVAL(rt) == 0)
4802      return TRUE;
4803
4804   /* if both constant, we know the answer up front */
4805   if (ISCONST(rs) && ISCONST(rt))
4806   {
4807      UINT32 result = is_unsigned ? ((UINT32)CONSTVAL(rs) / (UINT32)CONSTVAL(rt)) : ((INT32)CONSTVAL(rs) / (INT32)CONSTVAL(rt));
4808      UINT32 remainder = is_unsigned ? ((UINT32)CONSTVAL(rs) % (UINT32)CONSTVAL(rt)) : ((INT32)CONSTVAL(rs) % (INT32)CONSTVAL(rt));
4809
4810      emit_set_constant_value(drc, compiler, desc, REG_LO, (INT32)result);
4811      emit_set_constant_value(drc, compiler, desc, REG_HI, (INT32)remainder);
4812   }
4813
4814   /* if one is a constant, load the constant into EAX and multiple from there */
4815   else
4816   {
4817      UINT8 divreg = ISCONST(rt) ? REG_ECX : X86REG(rt);
4818      emit_link skip = { 0 };
4819
4820      hi = compiler_register_allocate(drc, compiler, desc, REG_HI, ALLOC_DST | ALLOC_DIRTY);
4821      lo = compiler_register_allocate(drc, compiler, desc, REG_LO, ALLOC_DST | ALLOC_DIRTY);
4822
4823      emit_load_register_value(drc, compiler, REG_RAX, rs);                        // mov  rax,<rs>
4824      emit_load_register_value(drc, compiler, divreg, rt);                        // mov  <divreg>,<rt>
4825      emit_test_r64_r64(DRCTOP, divreg, divreg);                                 // test <divreg>,<divreg>
4826      emit_jcc_short_link(DRCTOP, COND_Z, &skip);                                 // jz   skip
4827      if (is_unsigned)
4828      {
4829         emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                              // xor  edx,edx
4830         emit_div_r64(DRCTOP, divreg);                                       // div  <divreg>
4831      }
4832      else
4833      {
4834         emit_cqo(DRCTOP);                                                // cqo
4835         emit_idiv_r64(DRCTOP, divreg);                                       // idiv <divreg>
4836      }
4837      emit_mov_r64_r64(DRCTOP, X86REG(hi), REG_EDX);                              // mov  <hi>,edx
4838      emit_mov_r64_r64(DRCTOP, X86REG(lo), REG_EAX);                              // mov  <loreg>,eax
4839      resolve_link(DRCTOP, &skip);                                       // skip:
4840   }
4841   return TRUE;
4842}
4843
4844
4845/*-------------------------------------------------
4846    compile_logical - compile a logical
4847    operation between two registers
4848
4849    0: and rD,rS,rT / and rT,rS,UIMM
4850    1: or  rD,rS,rT / or  rT,rS,UIMM
4851    2: xor rD,rS,rT / xor rT,rS,UIMM
4852    3: nor rD,rS,rT
4853-------------------------------------------------*/
4854
4855static int compile_logical(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int operation, int immediate)
4856{
4857   UINT32 op = *desc->opptr.l;
4858   UINT8 destreg = immediate ? RTREG : RDREG;
4859   mipsreg_state rd, rs, rt;
4860
4861   assert(operation >= 0 && operation <= 3);
4862   assert(!immediate || operation != 3);
4863
4864   /* if the destination is r0, bail */
4865   if (destreg == 0)
4866      return TRUE;
4867
4868   /* allocate source registers */
4869   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4870   rt = immediate ? MAKE_CONST(UIMMVAL) : compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4871
4872   /* if both constant, we know the answer up front */
4873   if (ISCONST(rs) && ISCONST(rt))
4874   {
4875      UINT64 result = (operation == 0) ? (CONSTVAL(rs) & CONSTVAL(rt)) : (operation == 1) ? (CONSTVAL(rs) | CONSTVAL(rt)) : (operation == 2) ? (CONSTVAL(rs) ^ CONSTVAL(rt)) : ~(CONSTVAL(rs) | CONSTVAL(rt));
4876      emit_set_constant_value(drc, compiler, desc, destreg, result);
4877   }
4878
4879   /* an AND against 0 is constant as well */
4880   else if (operation == 0 && ISCONST(rt) && CONSTVAL(rt) == 0)
4881      emit_set_constant_value(drc, compiler, desc, destreg, 0);
4882
4883   /* else do the operation in code */
4884   else
4885   {
4886      rd = compiler_register_allocate(drc, compiler, desc, destreg, ALLOC_DST | ALLOC_DIRTY);
4887
4888      /* if rD matches rT, or if rS is const and rT isn't, then swap rT and rS */
4889      if (X86REG(rd) == X86REG(rt) || (ISCONST(rs) && !ISCONST(rt)))
4890      {
4891         mipsreg_state temp = rs;
4892         rs = rt;
4893         rt = temp;
4894      }
4895
4896      /* load rS into rD */
4897      emit_load_register_value(drc, compiler, X86REG(rd), rs);                     // mov  <rd>,<rs>
4898
4899      /* if rD does not match rT, we can work directly in rD */
4900      if (!ISCONST(rt))
4901      {
4902         if (operation == 0)
4903            emit_and_r64_r64(DRCTOP, X86REG(rd), X86REG(rt));                     // and  <rd>,<rt>
4904         else if (operation == 1)
4905            emit_or_r64_r64(DRCTOP, X86REG(rd), X86REG(rt));                     // or   <rd>,<rt>
4906         else if (operation == 2)
4907            emit_xor_r64_r64(DRCTOP, X86REG(rd), X86REG(rt));                     // xor  <rd>,<rt>
4908         else if (operation == 3)
4909         {
4910            emit_or_r64_r64(DRCTOP, X86REG(rd), X86REG(rt));                     // or   <rd>,<rt>
4911            emit_not_r64(DRCTOP, X86REG(rd));                                 // not  <rd>
4912         }
4913      }
4914      else
4915      {
4916         if (operation == 0)
4917            emit_and_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rt));                     // and  <rd>,CONSTVAL(rt)
4918         else if (operation == 1 && CONSTVAL(rt) != 0)
4919            emit_or_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rt));                     // or   <rd>,CONSTVAL(rt)
4920         else if (operation == 2 && CONSTVAL(rt) != 0)
4921            emit_xor_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rt));                     // xor  <rd>,CONSTVAL(rt)
4922         else if (operation == 3)
4923         {
4924            if (CONSTVAL(rt) != 0)
4925               emit_or_r64_imm(DRCTOP, X86REG(rd), CONSTVAL(rt));                  // or   <rd>,CONSTVAL(rt)
4926            emit_not_r64(DRCTOP, X86REG(rd));                                 // not  <rd>
4927         }
4928      }
4929   }
4930   return TRUE;
4931}
4932
4933
4934/*-------------------------------------------------
4935    compile_slt - compile a set if less
4936    than btween two registers
4937
4938    slti  rD,rS,rT / slti  rT,rS,SIMM
4939    sltiu rD,rS,rT / sltiu rT,rS,SIMM
4940-------------------------------------------------*/
4941
4942static int compile_slt(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_unsigned, int immediate)
4943{
4944   UINT32 op = *desc->opptr.l;
4945   UINT8 destreg = immediate ? RTREG : RDREG;
4946   mipsreg_state rd, rs, rt;
4947
4948   /* if the destination is r0, bail */
4949   if (destreg == 0)
4950      return TRUE;
4951
4952   /* allocate source registers */
4953   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
4954   rt = immediate ? MAKE_CONST(SIMMVAL) : compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
4955
4956   /* if the source is constant, compute as constant */
4957   if (ISCONST(rs) && ISCONST(rt))
4958   {
4959      INT64 result = is_unsigned ? ((UINT32)CONSTVAL(rs) < (UINT32)CONSTVAL(rt)) : ((INT32)CONSTVAL(rs) < (INT32)CONSTVAL(rt));
4960      emit_set_constant_value(drc, compiler, desc, destreg, result);
4961   }
4962
4963   /* else do the operation in code */
4964   else
4965   {
4966      UINT8 rsreg = ISCONST(rs) ? REG_RAX : X86REG(rs);
4967
4968      rd = compiler_register_allocate(drc, compiler, desc, destreg, ALLOC_DST | ALLOC_DIRTY);
4969
4970      emit_load_register_value(drc, compiler, rsreg, rs);                           // mov  <rsreg>,<rs>
4971      if (ISCONST(rt))
4972         emit_cmp_r64_imm(DRCTOP, rsreg, CONSTVAL(rt));                           // cmp  <rsreg>,<rt>
4973      else
4974         emit_cmp_r64_r64(DRCTOP, rsreg, X86REG(rt));                           // cmp  <rsreg>,<rt>
4975      emit_setcc_r8(DRCTOP, is_unsigned ? COND_B : COND_L, X86REG(rd));               // setb/l <rd>
4976      emit_movzx_r32_r8(DRCTOP, X86REG(rd), X86REG(rd));                           // movzx <rd>,<rd>
4977   }
4978   return TRUE;
4979}
4980
4981
4982/*-------------------------------------------------
4983    compile_load - compile a memory load
4984    instruction
4985
4986    lb   rT,SIMM(rS)
4987    lbu  rT,SIMM(rS)
4988    lh   rT,SIMM(rS)
4989    lhu  rT,SIMM(rS)
4990    lw   rT,SIMM(rS)
4991    lwu  rT,SIMM(rS)
4992    ld   rT,SIMM(rS)
4993-------------------------------------------------*/
4994
4995static int compile_load(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, int is_unsigned)
4996{
4997   UINT32 op = *desc->opptr.l;
4998   mipsreg_state rs, rt;
4999   int was_fixed = FALSE;
5000
5001   /* allocate source registers */
5002   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5003   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_DST);
5004
5005   /* if rS is constant, we know the address at compile time; this simplifies the code */
5006   if (ISCONST(rs) && !DISABLE_FIXED_RAM_LOAD)
5007   {
5008      UINT8 destreg = (RTREG == 0) ? REG_RAX : X86REG(rt);
5009
5010      /* perform a fixed read if we can */
5011      if (size == 1)
5012         was_fixed = emit_fixed_byte_read(drc, compiler, desc, destreg, is_unsigned, CONSTVAL(rs) + SIMMVAL);
5013      else if (size == 2)
5014         was_fixed = emit_fixed_half_read(drc, compiler, desc, destreg, is_unsigned, CONSTVAL(rs) + SIMMVAL);
5015      else if (size == 4)
5016         was_fixed = emit_fixed_word_read(drc, compiler, desc, destreg, is_unsigned, CONSTVAL(rs) + SIMMVAL, 0xffffffff);
5017      else
5018         was_fixed = emit_fixed_double_read(drc, compiler, desc, destreg, CONSTVAL(rs) + SIMMVAL, U64(0xffffffffffffffff));
5019   }
5020
5021   /* otherwise, we just need to call the appropriate subroutine */
5022   else
5023   {
5024      if (ISCONST(rs))
5025         emit_mov_r32_imm(DRCTOP, REG_P1, CONSTVAL(rs) + SIMMVAL);                  // mov  p1,<rs> + SIMMVAL
5026      else
5027         emit_lea_r32_m32(DRCTOP, REG_P1, MBD(X86REG(rs), SIMMVAL));                  // lea  p1,[<rs> + SIMMVAL]
5028      if (size == 1 && is_unsigned)
5029         emit_call(DRCTOP, mips3.drcdata->general.read_byte_unsigned);               // call general.read_byte_unsigned
5030      else if (size == 1 && !is_unsigned)
5031         emit_call(DRCTOP, mips3.drcdata->general.read_byte_signed);                  // call general.read_byte_signed
5032      else if (size == 2 && is_unsigned)
5033         emit_call(DRCTOP, mips3.drcdata->general.read_half_unsigned);               // call general.read_half_unsigned
5034      else if (size == 2 && !is_unsigned)
5035         emit_call(DRCTOP, mips3.drcdata->general.read_half_signed);                  // call general.read_half_signed
5036      else if (size == 4 && is_unsigned)
5037         emit_call(DRCTOP, mips3.drcdata->general.read_word_unsigned);               // call general.read_word_unsigned
5038      else if (size == 4 && !is_unsigned)
5039         emit_call(DRCTOP, mips3.drcdata->general.read_word_signed);                  // call general.read_word_signed
5040      else
5041         emit_call(DRCTOP, mips3.drcdata->general.read_double);                     // call general.read_double
5042      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
5043      if (RTREG != 0)
5044         emit_mov_r64_r64(DRCTOP, X86REG(rt), REG_RAX);                           // mov  <rt>,rax
5045   }
5046
5047   /* only mark dirty after the exception risk is over */
5048   compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_DIRTY);
5049
5050   /* update cycle counts */
5051   if (!was_fixed)
5052      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5053   return TRUE;
5054}
5055
5056
5057/*-------------------------------------------------
5058    compile_load_cop - compile a COP memory load
5059    instruction
5060
5061    lwc1 rT,SIMM(rs)
5062    lwc2 rT,SIMM(rs)
5063    ldc1 rT,SIMM(rs)
5064    ldc2 rT,SIMM(rs)
5065-------------------------------------------------*/
5066
5067static int compile_load_cop(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, void *dest)
5068{
5069   UINT32 op = *desc->opptr.l;
5070   int was_fixed = FALSE;
5071   mipsreg_state rs;
5072
5073   /* allocate source registers */
5074   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5075
5076   /* if rS is constant, we know the address at compile time; this simplifies the code */
5077   if (ISCONST(rs) && !DISABLE_FIXED_RAM_LOAD)
5078   {
5079      /* perform a fixed read if we can */
5080      if (size == 4)
5081         was_fixed = emit_fixed_word_read(drc, compiler, desc, REG_RAX, FALSE, CONSTVAL(rs) + SIMMVAL, 0xffffffff);
5082      else
5083         was_fixed = emit_fixed_double_read(drc, compiler, desc, REG_RAX, CONSTVAL(rs) + SIMMVAL, U64(0xffffffffffffffff));
5084   }
5085
5086   /* otherwise, we just need to call the appropriate subroutine */
5087   else
5088   {
5089      if (ISCONST(rs))
5090         emit_mov_r32_imm(DRCTOP, REG_P1, CONSTVAL(rs) + SIMMVAL);                  // mov  p1,<rs> + SIMMVAL
5091      else
5092         emit_lea_r32_m32(DRCTOP, REG_P1, MBD(X86REG(rs), SIMMVAL));                  // lea  p1,[<rs> + SIMMVAL]
5093      if (size == 4)
5094         emit_call(DRCTOP, mips3.drcdata->general.read_word_unsigned);               // call general.read_word_unsigned
5095      else
5096         emit_call(DRCTOP, mips3.drcdata->general.read_double);                     // call general.read_double
5097      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
5098   }
5099
5100   /* complete the load by moving to the destination address */
5101   if (size == 4)
5102      emit_mov_m32_r32(DRCTOP, MDRC(dest), REG_EAX);                              // mov  [dest],eax
5103   else
5104      emit_mov_m64_r64(DRCTOP, MDRC(dest), REG_RAX);                              // mov  [dest],rax
5105
5106   /* update cycle counts */
5107   if (!was_fixed)
5108      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5109   return TRUE;
5110}
5111
5112
5113/*-------------------------------------------------
5114    compile_loadx_cop - compile a COP indexed
5115    memory load instruction
5116
5117    lwxc1 fD,rS,rT
5118    ldxc1 fD,rS,rT
5119-------------------------------------------------*/
5120
5121static int compile_loadx_cop(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, void *dest)
5122{
5123   UINT32 op = *desc->opptr.l;
5124   int was_fixed = FALSE;
5125   mipsreg_state rs, rt;
5126
5127   /* allocate source registers */
5128   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5129   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
5130
5131   /* if rS is constant, we know the address at compile time; this simplifies the code */
5132   if (ISCONST(rs) && ISCONST(rt) && !DISABLE_FIXED_RAM_LOAD)
5133   {
5134      /* perform a fixed read if we can */
5135      if (size == 4)
5136         was_fixed = emit_fixed_word_read(drc, compiler, desc, REG_RAX, FALSE, CONSTVAL(rs) + CONSTVAL(rt), 0xffffffff);
5137      else
5138         was_fixed = emit_fixed_double_read(drc, compiler, desc, REG_RAX, CONSTVAL(rs) + CONSTVAL(rt), U64(0xffffffffffffffff));
5139   }
5140
5141   /* otherwise, we just need to call the appropriate subroutine */
5142   else
5143   {
5144      if (ISCONST(rs) && ISCONST(rt))
5145         emit_mov_r32_imm(DRCTOP, REG_P1, CONSTVAL(rs) + CONSTVAL(rt));               // mov  p1,<rs> + <rt>
5146      else if (ISCONST(rs))
5147         emit_lea_r32_m32(DRCTOP, REG_P1, MBD(X86REG(rt), CONSTVAL(rs)));            // lea  p1,[<rt> + <rs>]
5148      else if (ISCONST(rt))
5149         emit_lea_r32_m32(DRCTOP, REG_P1, MBD(X86REG(rs), CONSTVAL(rt)));            // lea  p1,[<rs> + <rt>]
5150      else
5151         emit_lea_r32_m32(DRCTOP, REG_P1, MBISD(X86REG(rs), X86REG(rt), 1, 0));         // lea  p1,[<rs> + <rt>]
5152      if (size == 4)
5153         emit_call(DRCTOP, mips3.drcdata->general.read_word_unsigned);               // call general.read_word_unsigned
5154      else
5155         emit_call(DRCTOP, mips3.drcdata->general.read_double);                     // call general.read_double
5156      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
5157   }
5158
5159   /* complete the load by moving to the destination address */
5160   if (size == 4)
5161      emit_mov_m32_r32(DRCTOP, MDRC(dest), REG_EAX);                              // mov  [dest],eax
5162   else
5163      emit_mov_m64_r64(DRCTOP, MDRC(dest), REG_RAX);                              // mov  [dest],rax
5164
5165   /* update cycle counts */
5166   if (!was_fixed)
5167      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5168   return TRUE;
5169}
5170
5171
5172/*-------------------------------------------------
5173    compile_load_word_partial - compile a lwl/lwr
5174    instruction
5175
5176    lwl   rT,SIMM(rS)
5177    lwr   rT,SIMM(rS)
5178-------------------------------------------------*/
5179
5180static int compile_load_word_partial(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_right)
5181{
5182   UINT32 op = *desc->opptr.l;
5183   int was_fixed = FALSE;
5184   mipsreg_state rs, rt;
5185
5186   /* allocate source/dest registers */
5187   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5188   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC | ALLOC_DST | ALLOC_DIRTY);
5189
5190   /* if rS is constant, we know the address at compile time; this simplifies the code */
5191   if (ISCONST(rs) && !DISABLE_FIXED_RAM_LOAD)
5192   {
5193      INT32 addr = CONSTVAL(rs) + SIMMVAL;
5194      int shift = (addr & 3) * 8;
5195
5196      /* shift the opposite amount depending on right/left and endianness */
5197      if ((!mips3.core->bigendian && !is_right) || (mips3.core->bigendian && is_right))
5198         shift ^= 0x18;
5199
5200      /* read the double value into rax, handling exceptions */
5201      was_fixed = emit_fixed_word_read(drc, compiler, desc, REG_RAX, FALSE, addr, is_right ? ((UINT32)-1 << shift) : ((UINT32)-1 >> shift));
5202
5203      /* handle writing back the register */
5204      if (RTREG != 0)
5205      {
5206         UINT32 mask = is_right ? (~((UINT32)-1 >> shift)) : (~((UINT32)-1 << shift));
5207
5208         /* AND rT with the mask */
5209         emit_and_r32_imm(DRCTOP, X86REG(rt), mask);                              // and  <rt>,mask
5210
5211         /* shift and merge rax into the X86REG(rt) */
5212         if (!is_right)
5213            emit_shl_r32_imm(DRCTOP, REG_EAX, shift);                           // shl  eax,shift
5214         else
5215            emit_shr_r32_imm(DRCTOP, REG_EAX, shift);                           // shr  eax,shift
5216         emit_or_r32_r32(DRCTOP, X86REG(rt), REG_EAX);                           // or   <rtdst>,eax
5217         emit_movsxd_r64_r32(DRCTOP, X86REG(rt), X86REG(rt));                     // movsxd <rt>,<rt>
5218      }
5219   }
5220
5221   /* otherwise, we need to compute everything at runtime */
5222   else
5223   {
5224      /* compute the address and mask values */
5225      if (ISCONST(rs))
5226         emit_mov_r32_imm(DRCTOP, REG_EAX, CONSTVAL(rs) + SIMMVAL);                  // mov  eax,<rs> + SIMMVAL
5227      else
5228         emit_lea_r32_m32(DRCTOP, REG_EAX, MBD(X86REG(rs), SIMMVAL));               // lea  eax,[<rs> + SIMMVAL]
5229      emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_RAX, 8, 0));                        // lea  ecx,[rax*8]
5230      emit_or_r32_imm(DRCTOP, REG_P2, -1);                                    // or   p2,-1
5231      if ((!mips3.core->bigendian && !is_right) || (mips3.core->bigendian && is_right))
5232         emit_xor_r32_imm(DRCTOP, REG_ECX, 0x18);                              // xor  ecx,0x18
5233      emit_and_r32_imm(DRCTOP, REG_EAX, ~3);                                    // and  eax,~3
5234      if (!is_right)
5235         emit_shr_r32_cl(DRCTOP, REG_P2);                                    // shr  p2,cl
5236      else
5237         emit_shl_r32_cl(DRCTOP, REG_P2);                                    // shl  p2,cl
5238      emit_mov_m8_r8(DRCTOP, MBD(REG_RSP, SPOFFS_SAVECL), REG_CL);                  // mov  [sp+savecl],cl
5239      emit_mov_r32_r32(DRCTOP, REG_P1, REG_EAX);                                 // mov  p1,eax
5240      emit_call(DRCTOP, mips3.drcdata->general.read_word_masked);                     // call general.read_word_masked
5241      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
5242
5243      /* handle writing back the register */
5244      if (RTREG != 0)
5245      {
5246         /* recompute the mask */
5247         emit_mov_r8_m8(DRCTOP, REG_CL, MBD(REG_RSP, SPOFFS_SAVECL));               // mov  cl,[sp+savecl]
5248         emit_or_r32_imm(DRCTOP, REG_P2, -1);                                 // or   p2,-1
5249         if (!is_right)
5250            emit_shl_r32_cl(DRCTOP, REG_P2);                                 // shl  p2,cl
5251         else
5252            emit_shr_r32_cl(DRCTOP, REG_P2);                                 // shr  p2,cl
5253
5254         /* apply the shifts and masks */
5255         emit_not_r32(DRCTOP, REG_P2);                                       // not  p2
5256         if (!is_right)
5257            emit_shl_r32_cl(DRCTOP, REG_RAX);                                 // shl  rax,cl
5258         else
5259            emit_shr_r32_cl(DRCTOP, REG_RAX);                                 // shr  rax,cl
5260         emit_and_r32_r32(DRCTOP, X86REG(rt), REG_P2);                           // and  <rt>,p2
5261         emit_or_r32_r32(DRCTOP, X86REG(rt), REG_RAX);                           // or   <rt>,rax
5262         emit_movsxd_r64_r32(DRCTOP, X86REG(rt), X86REG(rt));                     // movsxd <rt>,<rt>
5263      }
5264   }
5265
5266   /* update cycle counts */
5267   if (!was_fixed)
5268      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5269   return TRUE;
5270}
5271
5272
5273/*-------------------------------------------------
5274    compile_load_double_partial - compile a
5275    ldl/ldr instruction
5276
5277    ldl   rT,SIMM(rS)
5278    ldr   rT,SIMM(rS)
5279-------------------------------------------------*/
5280
5281static int compile_load_double_partial(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_right)
5282{
5283   UINT32 op = *desc->opptr.l;
5284   int was_fixed = FALSE;
5285   mipsreg_state rs, rt;
5286
5287   /* allocate source/dest registers */
5288   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5289   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC | ALLOC_DST | ALLOC_DIRTY);
5290
5291   /* if rS is constant, we know the address at compile time; this simplifies the code */
5292   if (ISCONST(rs) && !DISABLE_FIXED_RAM_LOAD)
5293   {
5294      INT32 addr = CONSTVAL(rs) + SIMMVAL;
5295      int shift = (addr & 7) * 8;
5296
5297      /* shift the opposite amount depending on right/left and endianness */
5298      if ((!mips3.core->bigendian && !is_right) || (mips3.core->bigendian && is_right))
5299         shift ^= 0x38;
5300
5301      /* read the double value into rax, handling exceptions */
5302      was_fixed = emit_fixed_double_read(drc, compiler, desc, REG_RAX, addr, is_right ? ((UINT64)-1 << shift) : ((UINT64)-1 >> shift));
5303
5304      /* handle writing back the register */
5305      if (RTREG != 0)
5306      {
5307         UINT64 mask = is_right ? (~((UINT64)-1 >> shift)) : (~((UINT64)-1 << shift));
5308
5309         /* AND rT with the mask, using 32 bits if we can */
5310         if ((INT32)mask == (INT64)mask)
5311            emit_and_r64_imm(DRCTOP, X86REG(rt), (INT32)mask);                     // and  <rt>,mask
5312         else
5313         {
5314            emit_mov_r64_imm(DRCTOP, REG_P2, mask);                              // mov  p2,mask
5315            emit_and_r64_r64(DRCTOP, X86REG(rt), REG_P2);                        // and  <rt>,p2
5316         }
5317
5318         /* shift and merge rax into the X86REG(rt) */
5319         if (!is_right)
5320            emit_shl_r64_imm(DRCTOP, REG_RAX, shift);                           // shl  rax,shift
5321         else
5322            emit_shr_r64_imm(DRCTOP, REG_RAX, shift);                           // shr  rax,shift
5323         emit_or_r64_r64(DRCTOP, X86REG(rt), REG_RAX);                           // or   <rt>,rax
5324      }
5325   }
5326
5327   /* otherwise, we need to compute everything at runtime */
5328   else
5329   {
5330      /* compute the address and mask values */
5331      if (ISCONST(rs))
5332         emit_mov_r32_imm(DRCTOP, REG_EAX, CONSTVAL(rs) + SIMMVAL);                  // mov  eax,<rs> + SIMMVAL
5333      else
5334         emit_lea_r32_m32(DRCTOP, REG_EAX, MBD(X86REG(rs), SIMMVAL));               // lea  eax,[<rs> + SIMMVAL]
5335      emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_RAX, 8, 0));                        // lea  ecx,[rax*8]
5336      emit_or_r64_imm(DRCTOP, REG_P2, -1);                                    // or   p2,-1
5337      if ((!mips3.core->bigendian && !is_right) || (mips3.core->bigendian && is_right))
5338         emit_xor_r32_imm(DRCTOP, REG_ECX, 0x38);                              // xor  ecx,0x38
5339      emit_and_r32_imm(DRCTOP, REG_EAX, ~7);                                    // and  eax,~7
5340      if (!is_right)
5341         emit_shr_r64_cl(DRCTOP, REG_P2);                                    // shr  p2,cl
5342      else
5343         emit_shl_r64_cl(DRCTOP, REG_P2);                                    // shl  p2,cl
5344      emit_mov_m8_r8(DRCTOP, MBD(REG_RSP, SPOFFS_SAVECL), REG_CL);                  // mov  [sp+savecl],cl
5345      emit_mov_r32_r32(DRCTOP, REG_P1, REG_EAX);                                 // mov  p1,eax
5346      emit_call(DRCTOP, mips3.drcdata->general.read_double_masked);                  // call general.read_double_masked
5347      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbload_exception);
5348
5349      /* handle writing back the register */
5350      if (RTREG != 0)
5351      {
5352         /* recompute the mask */
5353         emit_mov_r8_m8(DRCTOP, REG_CL, MBD(REG_RSP, SPOFFS_SAVECL));               // mov  cl,[sp+savecl]
5354         emit_or_r64_imm(DRCTOP, REG_P2, -1);                                 // or   p2,-1
5355         if (!is_right)
5356            emit_shl_r64_cl(DRCTOP, REG_P2);                                 // shl  p2,cl
5357         else
5358            emit_shr_r64_cl(DRCTOP, REG_P2);                                 // shr  p2,cl
5359
5360         /* apply the shifts and masks */
5361         emit_not_r64(DRCTOP, REG_P2);                                       // not  p2
5362         if (!is_right)
5363            emit_shl_r64_cl(DRCTOP, REG_RAX);                                 // shl  rax,cl
5364         else
5365            emit_shr_r64_cl(DRCTOP, REG_RAX);                                 // shr  rax,cl
5366         emit_and_r64_r64(DRCTOP, X86REG(rt), REG_P2);                           // and  <rt>,p2
5367         emit_or_r64_r64(DRCTOP, X86REG(rt), REG_RAX);                           // or   <rt>,rax
5368      }
5369   }
5370
5371   /* update cycle counts */
5372   if (!was_fixed)
5373      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5374   return TRUE;
5375}
5376
5377
5378/*-------------------------------------------------
5379    compile_store - compile a memory store
5380    instruction
5381
5382    sb   rT,SIMM(rS)
5383    sh   rT,SIMM(rS)
5384    sw   rT,SIMM(rS)
5385    sd   rT,SIMM(rS)
5386-------------------------------------------------*/
5387
5388static int compile_store(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size)
5389{
5390   UINT32 op = *desc->opptr.l;
5391   int was_fixed = FALSE;
5392   mipsreg_state rs, rt;
5393
5394   /* allocate source registers */
5395   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5396   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
5397
5398   /* if rS is constant, we know the address at compile time; this simplifies the code */
5399   if (ISCONST(rs) && !DISABLE_FIXED_RAM_STORE)
5400   {
5401      /* perform a fixed write if we can */
5402      if (size == 1)
5403         was_fixed = emit_fixed_byte_write(drc, compiler, desc, rt, CONSTVAL(rs) + SIMMVAL);
5404      else if (size == 2)
5405         was_fixed = emit_fixed_half_write(drc, compiler, desc, rt, CONSTVAL(rs) + SIMMVAL);
5406      else if (size == 4)
5407         was_fixed = emit_fixed_word_write(drc, compiler, desc, rt, CONSTVAL(rs) + SIMMVAL, 0xffffffff);
5408      else
5409         was_fixed = emit_fixed_double_write(drc, compiler, desc, rt, CONSTVAL(rs) + SIMMVAL, U64(0xffffffffffffffff));
5410   }
5411
5412   /* otherwise, we just need to call the appropriate subroutine */
5413   else
5414   {
5415      if (ISCONST(rs))
5416         emit_mov_r32_imm(DRCTOP, REG_P1, CONSTVAL(rs) + SIMMVAL);                  // mov  p1,<rs> + SIMMVAL
5417      else
5418         emit_lea_r32_m32(DRCTOP, REG_P1, MBD(X86REG(rs), SIMMVAL));                  // lea  p1,[<rs> + SIMMVAL]
5419      emit_load_register_value(drc, compiler, REG_P2, rt);                        // mov  p2,<rt>
5420      if (size == 1)
5421         emit_call(DRCTOP, mips3.drcdata->general.write_byte);                     // call general.write_byte
5422      else if (size == 2)
5423         emit_call(DRCTOP, mips3.drcdata->general.write_half);                     // call general.write_half
5424      else if (size == 4)
5425         emit_call(DRCTOP, mips3.drcdata->general.write_word);                     // call general.write_word
5426      else if (size == 8)
5427         emit_call(DRCTOP, mips3.drcdata->general.write_double);                     // call general.write_double
5428      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
5429   }
5430
5431   /* update cycle counts */
5432   if (!was_fixed)
5433      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5434   return TRUE;
5435}
5436
5437
5438/*-------------------------------------------------
5439    compile_store_cop - compile a COP memory
5440    store instruction
5441
5442    swc1 rT,SIMM(rs)
5443    swc2 rT,SIMM(rs)
5444    sdc1 rT,SIMM(rs)
5445    sdc2 rT,SIMM(rs)
5446-------------------------------------------------*/
5447
5448static int compile_store_cop(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, void *src)
5449{
5450   UINT32 op = *desc->opptr.l;
5451   int was_fixed = FALSE;
5452   mipsreg_state rs;
5453
5454   /* allocate source registers */
5455   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5456
5457   /* load the value into P2 */
5458   if (size == 4)
5459      emit_mov_r32_m32(DRCTOP, REG_P2, MDRC(src));                              // mov  p2,[src]
5460   else
5461      emit_mov_r64_m64(DRCTOP, REG_P2, MDRC(src));                              // mov  p2,[src]
5462
5463   /* if rS is constant, we know the address at compile time; this simplifies the code */
5464   if (ISCONST(rs) && !DISABLE_FIXED_RAM_STORE)
5465   {
5466      /* perform a fixed write if we can */
5467      if (size == 4)
5468         was_fixed = emit_fixed_word_write(drc, compiler, desc, REG_P2, CONSTVAL(rs) + SIMMVAL, 0xffffffff);
5469      else
5470         was_fixed = emit_fixed_double_write(drc, compiler, desc, REG_P2, CONSTVAL(rs) + SIMMVAL, U64(0xffffffffffffffff));
5471   }
5472
5473   /* otherwise, we just need to call the appropriate subroutine */
5474   else
5475   {
5476      if (ISCONST(rs))
5477         emit_mov_r32_imm(DRCTOP, REG_P1, CONSTVAL(rs) + SIMMVAL);                  // mov  p1,<rs> + SIMMVAL
5478      else
5479         emit_lea_r32_m32(DRCTOP, REG_P1, MBD(X86REG(rs), SIMMVAL));                  // lea  p1,[<rs> + SIMMVAL]
5480      if (size == 4)
5481         emit_call(DRCTOP, mips3.drcdata->general.write_word);                     // call general.write_word
5482      else if (size == 8)
5483         emit_call(DRCTOP, mips3.drcdata->general.write_double);                     // call general.write_double
5484      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
5485   }
5486
5487   /* update cycle counts */
5488   if (!was_fixed)
5489      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5490   return TRUE;
5491}
5492
5493
5494/*-------------------------------------------------
5495    compile_storex_cop - compile a COP indexed
5496    memory store instruction
5497
5498    swxc1 fD,rS,rT
5499    sdxc1 fD,rS,rT
5500-------------------------------------------------*/
5501
5502static int compile_storex_cop(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int size, void *src)
5503{
5504   UINT32 op = *desc->opptr.l;
5505   int was_fixed = FALSE;
5506   mipsreg_state rs, rt;
5507
5508   /* allocate source registers */
5509   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5510   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
5511
5512   /* load the value into P2 */
5513   if (size == 4)
5514      emit_mov_r32_m32(DRCTOP, REG_P2, MDRC(src));                              // mov  p2,[src]
5515   else
5516      emit_mov_r64_m64(DRCTOP, REG_P2, MDRC(src));                              // mov  p2,[src]
5517
5518   /* if rS is constant, we know the address at compile time; this simplifies the code */
5519   if (ISCONST(rs) && ISCONST(rt) && !DISABLE_FIXED_RAM_STORE)
5520   {
5521      /* perform a fixed write if we can */
5522      if (size == 4)
5523         was_fixed = emit_fixed_word_write(drc, compiler, desc, REG_P2, CONSTVAL(rs) + CONSTVAL(rt), 0xffffffff);
5524      else
5525         was_fixed = emit_fixed_double_write(drc, compiler, desc, REG_P2, CONSTVAL(rs) + CONSTVAL(rt), U64(0xffffffffffffffff));
5526   }
5527
5528   /* otherwise, we just need to call the appropriate subroutine */
5529   else
5530   {
5531      if (ISCONST(rs) && ISCONST(rt))
5532         emit_mov_r32_imm(DRCTOP, REG_P1, CONSTVAL(rs) + CONSTVAL(rt));               // mov  p1,<rs> + <rt>
5533      else if (ISCONST(rs))
5534         emit_lea_r32_m32(DRCTOP, REG_P1, MBD(X86REG(rt), CONSTVAL(rs)));            // lea  p1,[<rt> + <rs>]
5535      else if (ISCONST(rt))
5536         emit_lea_r32_m32(DRCTOP, REG_P1, MBD(X86REG(rs), CONSTVAL(rt)));            // lea  p1,[<rs> + <rt>]
5537      else
5538         emit_lea_r32_m32(DRCTOP, REG_P1, MBISD(X86REG(rs), X86REG(rt), 1, 0));         // lea  p1,[<rs> + <rt>]
5539      if (size == 4)
5540         emit_call(DRCTOP, mips3.drcdata->general.write_word);                     // call general.write_word
5541      else if (size == 8)
5542         emit_call(DRCTOP, mips3.drcdata->general.write_double);                     // call general.write_double
5543      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
5544   }
5545
5546   /* update cycle counts */
5547   if (!was_fixed)
5548      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5549   return TRUE;
5550}
5551
5552
5553/*-------------------------------------------------
5554    compile_store_word_partial - compile a swl/swr
5555    instruction
5556
5557    swl   rT,SIMM(rS)
5558    swr   rT,SIMM(rS)
5559-------------------------------------------------*/
5560
5561static int compile_store_word_partial(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_right)
5562{
5563   UINT32 op = *desc->opptr.l;
5564   int was_fixed = FALSE;
5565   mipsreg_state rs, rt;
5566
5567   /* allocate source registers */
5568   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5569   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
5570
5571   /* if rS is constant, we know the address at compile time; this simplifies the code */
5572   if (ISCONST(rs) && !DISABLE_FIXED_RAM_STORE)
5573   {
5574      INT32 addr = CONSTVAL(rs) + SIMMVAL;
5575      int shift = (addr & 3) * 8;
5576      UINT32 mask;
5577
5578      /* shift the opposite amount depending on right/left and endianness */
5579      if ((!mips3.core->bigendian && !is_right) || (mips3.core->bigendian && is_right))
5580         shift ^= 0x18;
5581
5582      /* if rT is not constant, load and shift it */
5583      if (!ISCONST(rt))
5584      {
5585         emit_mov_r32_r32(DRCTOP, REG_EAX, X86REG(rt));                           // mov  eax,X86REG(rt)
5586         emit_shr_r32_imm(DRCTOP, REG_EAX, shift);                              // shr  eax,shift
5587         rt = MAKE_DESTREG(REG_EAX);
5588      }
5589
5590      /* compute shifted value and mask */
5591      if (!is_right)
5592      {
5593         if (ISCONST(rt))
5594            rt = MAKE_CONST((UINT32)CONSTVAL(rt) >> shift);
5595         mask = (UINT32)-1 >> shift;
5596      }
5597      else
5598      {
5599         if (ISCONST(rt))
5600            rt = MAKE_CONST((UINT32)CONSTVAL(rt) << shift);
5601         mask = (UINT32)-1 << shift;
5602      }
5603
5604      /* perform a fixed write */
5605      was_fixed = emit_fixed_word_write(drc, compiler, desc, rt, addr & ~3, mask);
5606   }
5607
5608   /* otherwise, we need to compute everything at runtime */
5609   else
5610   {
5611      /* compute the address and mask values */
5612      emit_lea_r32_m32(DRCTOP, REG_EAX, MBD(X86REG(rs), SIMMVAL));                  // lea  eax,[<rs> + SIMMVAL]
5613      emit_or_r32_imm(DRCTOP, REG_P3, -1);                                    // or   p3,-1
5614      emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_RAX, 8, 0));                        // lea  ecx,[rax*8]
5615      emit_load_register_value(drc, compiler, REG_P2, rt);                        // mov  p2,<rt>
5616      if ((!mips3.core->bigendian && !is_right) || (mips3.core->bigendian && is_right))
5617         emit_xor_r32_imm(DRCTOP, REG_ECX, 0x18);                              // xor  ecx,0x18
5618      emit_and_r32_imm(DRCTOP, REG_EAX, ~3);                                    // and  eax,~3
5619      if (!is_right)
5620      {
5621         emit_shr_r32_cl(DRCTOP, REG_P3);                                    // shr  p3,cl
5622         emit_shr_r32_cl(DRCTOP, REG_P2);                                    // shr  p2,cl
5623      }
5624      else
5625      {
5626         emit_shl_r32_cl(DRCTOP, REG_P3);                                    // shl  p3,cl
5627         emit_shl_r32_cl(DRCTOP, REG_P2);                                    // shl  p2,cl
5628      }
5629      emit_mov_r32_r32(DRCTOP, REG_P1, REG_EAX);                                 // mov  p1,eax
5630
5631      /* perform the write */
5632      emit_call(DRCTOP, mips3.drcdata->general.write_word_masked);                  // call general.write_word_masked
5633      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
5634   }
5635
5636   /* update cycle counts */
5637   if (!was_fixed)
5638      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5639   return TRUE;
5640}
5641
5642
5643/*-------------------------------------------------
5644    compile_store_double_partial - compile a
5645    sdl/sdr instruction
5646
5647    sdl   rT,SIMM(rS)
5648    sdr   rT,SIMM(rS)
5649-------------------------------------------------*/
5650
5651static int compile_store_double_partial(drc_core *drc, compiler_state *compiler, const opcode_desc *desc, int is_right)
5652{
5653   UINT32 op = *desc->opptr.l;
5654   int was_fixed = FALSE;
5655   mipsreg_state rs, rt;
5656
5657   /* allocate source registers */
5658   rs = compiler_register_allocate(drc, compiler, desc, RSREG, ALLOC_SRC);
5659   rt = compiler_register_allocate(drc, compiler, desc, RTREG, ALLOC_SRC);
5660
5661   /* if rS is constant, we know the address at compile time; this simplifies the code */
5662   if (ISCONST(rs) && !DISABLE_FIXED_RAM_STORE)
5663   {
5664      INT32 addr = CONSTVAL(rs) + SIMMVAL;
5665      int shift = (addr & 7) * 8;
5666      UINT64 mask;
5667
5668      /* shift the opposite amount depending on right/left and endianness */
5669      if ((!mips3.core->bigendian && !is_right) || (mips3.core->bigendian && is_right))
5670         shift ^= 0x38;
5671
5672      /* if rT is not constant, load and shift it */
5673      if (!ISCONST(rt))
5674      {
5675         emit_mov_r64_r64(DRCTOP, REG_RAX, X86REG(rt));                              // mov  rax,X86REG(rt)
5676         emit_shr_r64_imm(DRCTOP, REG_RAX, shift);                              // shr  rax,shift
5677         rt = MAKE_DESTREG(REG_RAX);
5678      }
5679
5680      /* compute shifted value and mask */
5681      if (!is_right)
5682      {
5683         if (ISCONST(rt))
5684            rt = MAKE_CONST((UINT64)CONSTVAL(rt) >> shift);
5685         mask = (UINT64)-1 >> shift;
5686      }
5687      else
5688      {
5689         if (ISCONST(rt))
5690            rt = MAKE_CONST((UINT64)CONSTVAL(rt) << shift);
5691         mask = (UINT64)-1 << shift;
5692      }
5693
5694      /* perform a fixed write */
5695      was_fixed = emit_fixed_double_write(drc, compiler, desc, rt, addr & ~7, mask);
5696   }
5697
5698   /* otherwise, we need to compute everything at runtime */
5699   else
5700   {
5701      /* compute the address and mask values */
5702      emit_lea_r32_m32(DRCTOP, REG_EAX, MBD(X86REG(rs), SIMMVAL));            // lea  eax,[<rs> + SIMMVAL]
5703      emit_or_r64_imm(DRCTOP, REG_P3, -1);                              // or   p3,-1
5704      emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_RAX, 8, 0));                  // lea  ecx,[rax*8]
5705      emit_load_register_value(drc, compiler, REG_P2, rt);                  // mov  p2,<rt>
5706      if ((!mips3.core->bigendian && !is_right) || (mips3.core->bigendian && is_right))
5707         emit_xor_r32_imm(DRCTOP, REG_ECX, 0x38);                        // xor  ecx,0x38
5708      emit_and_r32_imm(DRCTOP, REG_EAX, ~7);                              // and  eax,~7
5709      if (!is_right)
5710      {
5711         emit_shr_r64_cl(DRCTOP, REG_P3);                              // shr  p3,cl
5712         emit_shr_r64_cl(DRCTOP, REG_P2);                              // shr  p2,cl
5713      }
5714      else
5715      {
5716         emit_shl_r64_cl(DRCTOP, REG_P3);                              // shl  p3,cl
5717         emit_shl_r64_cl(DRCTOP, REG_P2);                              // shl  p2,cl
5718      }
5719      emit_mov_r32_r32(DRCTOP, REG_P1, REG_EAX);                           // mov  p1,eax
5720
5721      /* perform the write */
5722      emit_call(DRCTOP, mips3.drcdata->general.write_double_masked);            // call general.write_double_masked
5723      oob_request_callback(drc, COND_NO_JUMP, oob_exception_cleanup, compiler, desc, mips3.drcdata->generate_tlbstore_exception);
5724   }
5725
5726   /* update cycle counts */
5727   if (!was_fixed)
5728      emit_update_cycles_pc_and_flush(drc, compiler, desc, 0);
5729   return TRUE;
5730}
src/emu/cpu/mips/mdrcold.c
r2821r2822
1
2
3/***************************************************************************
4    CONFIGURATION
5***************************************************************************/
6
7#define STRIP_NOPS         1      /* 1 is faster */
8#define USE_SSE            0      /* can't tell any speed difference here */
9
10
11
12/***************************************************************************
13    CONSTANTS
14***************************************************************************/
15
16#define MAX_INSTRUCTIONS            ((512 + 128) / 4)
17
18/* recompiler flags */
19#define RECOMPILE_UNIMPLEMENTED         0x0000
20#define RECOMPILE_SUCCESSFUL         0x0001
21#define RECOMPILE_SUCCESSFUL_CP(c,p)   (RECOMPILE_SUCCESSFUL | (((c) & 0xfff) << 8) | (((p) & 0xfff) << 20))
22#define RECOMPILE_MAY_CAUSE_EXCEPTION   0x0002
23#define RECOMPILE_END_OF_STRING         0x0004
24#define RECOMPILE_CHECK_INTERRUPTS      0x0008
25#define RECOMPILE_CHECK_SW_INTERRUPTS   0x0010
26#define RECOMPILE_ADD_DISPATCH         0x0020
27
28/* append_readwrite flags */
29#define ARW_READ                  0x0000
30#define ARW_WRITE                  0x0001
31#define ARW_UNSIGNED               0x0000
32#define ARW_SIGNED                  0x0002
33#define ARW_MASKED                  0x0004
34
35
36
37/***************************************************************************
38    MACROS
39***************************************************************************/
40
41#define REGDISP(reg)      (offsetof(mips3_state, r[reg]) - offsetof(mips3_state, r[17]))
42#define REGADDR(reg)      MBD(REG_ESI, REGDISP(reg))
43#define REGADDRLO(reg)      MBD(REG_ESI, REGDISP(reg))
44#define REGADDRHI(reg)      MBD(REG_ESI, REGDISP(reg)+4)
45
46#define HIADDR            REGADDR(REG_HI)
47#define HIADDRLO         REGADDRLO(REG_HI)
48#define HIADDRHI         REGADDRHI(REG_HI)
49
50#define LOADDR            REGADDR(REG_LO)
51#define LOADDRLO         REGADDRLO(REG_LO)
52#define LOADDRHI         REGADDRHI(REG_LO)
53
54#define CPR0ADDR(reg)      MABS((UINT8 *)&mips3.core->cpr[0][reg])
55#define CPR0ADDRLO(reg)      MABS((UINT8 *)&mips3.core->cpr[0][reg])
56#define CPR0ADDRHI(reg)      MABS((UINT8 *)&mips3.core->cpr[0][reg] + 4)
57
58#define CCR0ADDR(reg)      MABS((UINT8 *)&mips3.core->ccr[0][reg])
59#define CCR0ADDRLO(reg)      MABS((UINT8 *)&mips3.core->ccr[0][reg])
60#define CCR0ADDRHI(reg)      MABS((UINT8 *)&mips3.core->ccr[0][reg] + 4)
61
62#define CPR1ADDR(reg)      MABS((UINT8 *)&mips3.core->cpr[1][reg])
63#define CPR1ADDRLO(reg)      MABS((UINT8 *)&mips3.core->cpr[1][reg])
64#define CPR1ADDRHI(reg)      MABS((UINT8 *)&mips3.core->cpr[1][reg] + 4)
65
66#define CCR1ADDR(reg)      MABS((UINT8 *)&mips3.core->ccr[1][reg])
67#define CCR1ADDRLO(reg)      MABS((UINT8 *)&mips3.core->ccr[1][reg])
68#define CCR1ADDRHI(reg)      MABS((UINT8 *)&mips3.core->ccr[1][reg] + 4)
69
70#define CPR2ADDR(reg)      MABS((UINT8 *)&mips3.core->cpr[2][reg])
71#define CPR2ADDRLO(reg)      MABS((UINT8 *)&mips3.core->cpr[2][reg])
72#define CPR2ADDRHI(reg)      MABS((UINT8 *)&mips3.core->cpr[2][reg] + 4)
73
74#define CCR2ADDR(reg)      MABS((UINT8 *)&mips3.core->ccr[2][reg])
75#define CCR2ADDRLO(reg)      MABS((UINT8 *)&mips3.core->ccr[2][reg])
76#define CCR2ADDRHI(reg)      MABS((UINT8 *)&mips3.core->ccr[2][reg] + 4)
77
78#define FPR32(reg)         (IS_FR0 ? &((float *)&mips3.core->cpr[1][0])[reg] : (float *)&mips3.core->cpr[1][reg])
79#define FPR32ADDR(reg)      MABS(FPR32(reg))
80#define FPR32ADDRLO(reg)   MABS(FPR32(reg))
81#define FPR32ADDRHI(reg)   MABS((UINT8 *)FPR32(reg) + 4)
82
83#define FPR64(reg)         (IS_FR0 ? (double *)&mips3.core->cpr[1][(reg)/2] : (double *)&mips3.core->cpr[1][reg])
84#define FPR64ADDR(reg)      MABS(FPR64(reg))
85#define FPR64ADDR(reg)      MABS(FPR64(reg))
86#define FPR64ADDRLO(reg)   MABS(FPR64(reg))
87#define FPR64ADDRHI(reg)   MABS((UINT8 *)FPR64(reg) + 4)
88
89#define CF1ADDR(which)      MABS(&mips3.core->cf[1][(mips3.core->flavor < MIPS3_TYPE_MIPS_IV) ? 0 : (which)])
90
91#define ICOUNTADDR         MABS(&mips3.core->icount)
92
93
94/***************************************************************************
95    USEFUL PRIMITIVES
96***************************************************************************/
97
98INLINE void emit_mov_r64_m64(x86code **emitptr, UINT8 reghi, UINT8 reglo, DECLARE_MEMPARAMS)
99{
100   emit_mov_r32_m32(emitptr, reglo, MEMPARAMS);
101   emit_mov_r32_m32(emitptr, reghi, base, index, scale, disp+4);
102}
103
104INLINE void emit_mov_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 reghi, UINT8 reglo)
105{
106   emit_mov_m32_r32(emitptr, MEMPARAMS, reglo);
107   emit_mov_m32_r32(emitptr, base, index, scale, disp+4, reghi);
108}
109
110INLINE void emit_mov_m64_imm32(x86code **emitptr, DECLARE_MEMPARAMS, INT32 imm)
111{
112   emit_mov_m32_imm(emitptr, MEMPARAMS, imm);
113   emit_mov_m32_imm(emitptr, base, index, scale, disp+4, (INT32)imm >> 31);
114}
115
116INLINE void emit_zero_m64(x86code **emitptr, DECLARE_MEMPARAMS)
117{
118   if (USE_SSE)
119   {
120      emit_xorpd_r128_r128(emitptr, REG_XMM0, REG_XMM0);
121      emit_movsd_m64_r128(emitptr, MEMPARAMS, REG_XMM0);
122   }
123   else
124      emit_mov_m64_imm32(emitptr, MEMPARAMS, 0);
125}
126
127INLINE void emit_mov_m64_m64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 base2, UINT8 index2, UINT8 scale2, INT32 disp2)
128{
129   if (USE_SSE)
130   {
131      emit_movsd_r128_m64(emitptr, REG_XMM0, base2, index2, scale2, disp2);
132      emit_movsd_m64_r128(emitptr, MEMPARAMS, REG_XMM0);
133   }
134   else
135   {
136      emit_mov_r64_m64(emitptr, REG_EDX, REG_EAX, base2, index2, scale2, disp2);
137      emit_mov_m64_r64(emitptr, MEMPARAMS, REG_EDX, REG_EAX);
138   }
139}
140
141#define emit_save_pc_before_call(e)                     \
142do {                                           \
143   if (mips3.drcoptions & MIPS3DRC_FLUSH_PC)            \
144      emit_mov_m32_r32(e, MABS(drc->pcptr), REG_EDI);      \
145} while (0)
146
147
148
149
150/***************************************************************************
151    TYPEDEFS
152***************************************************************************/
153
154struct _mips3drc_data
155{
156   x86code *      generate_interrupt_exception;
157   x86code *      generate_cop_exception;
158   x86code *      generate_overflow_exception;
159   x86code *      generate_invalidop_exception;
160   x86code *      generate_syscall_exception;
161   x86code *      generate_break_exception;
162   x86code *      generate_trap_exception;
163   x86code *      generate_tlbload_exception;
164   x86code *      generate_tlbstore_exception;
165   x86code *      handle_pc_tlb_mismatch;
166   x86code *      read_and_translate_byte_signed;
167   x86code *      read_and_translate_byte_unsigned;
168   x86code *      read_and_translate_half_signed;
169   x86code *      read_and_translate_half_unsigned;
170   x86code *      read_and_translate_word;
171   x86code *      read_and_translate_word_masked;
172   x86code *      read_and_translate_double;
173   x86code *      read_and_translate_double_masked;
174   x86code *      write_and_translate_byte;
175   x86code *      write_and_translate_half;
176   x86code *      write_and_translate_word;
177   x86code *      write_and_translate_word_masked;
178   x86code *      write_and_translate_double;
179   x86code *      write_and_translate_double_masked;
180};
181
182
183
184/***************************************************************************
185    FUNCTION PROTOTYPES
186***************************************************************************/
187
188static void drc_reset_callback(drc_core *drc);
189static void drc_recompile_callback(drc_core *drc);
190static void drc_entrygen_callback(drc_core *drc);
191
192static UINT32 compile_one(drc_core *drc, UINT32 pc, UINT32 physpc);
193
194static void append_generate_exception(drc_core *drc, UINT8 exception);
195static void append_readwrite_and_translate(drc_core *drc, int size, UINT8 flags);
196static void append_tlb_verify(drc_core *drc, UINT32 pc, void *target);
197static void append_update_cycle_counting(drc_core *drc);
198static void append_check_interrupts(drc_core *drc, int inline_generate);
199static void append_check_sw_interrupts(drc_core *drc, int inline_generate);
200
201static UINT32 recompile_instruction(drc_core *drc, UINT32 pc, UINT32 physpc);
202static UINT32 recompile_special(drc_core *drc, UINT32 pc, UINT32 op);
203static UINT32 recompile_regimm(drc_core *drc, UINT32 pc, UINT32 op);
204
205static UINT32 recompile_cop0(drc_core *drc, UINT32 pc, UINT32 op);
206static UINT32 recompile_cop1(drc_core *drc, UINT32 pc, UINT32 op);
207static UINT32 recompile_cop1x(drc_core *drc, UINT32 pc, UINT32 op);
208
209
210
211/***************************************************************************
212    PRIVATE GLOBAL VARIABLES
213***************************************************************************/
214
215static UINT64 dmult_temp1;
216static UINT64 dmult_temp2;
217static UINT32 jr_temp;
218
219static UINT8 in_delay_slot = 0;
220
221
222
223/***************************************************************************
224    CORE RECOMPILER SYSTEMS
225***************************************************************************/
226
227/*-------------------------------------------------
228    mips3drc_init - initialize the drc-specific
229    state
230-------------------------------------------------*/
231
232static void mips3drc_init(void)
233{
234   drc_config drconfig;
235
236   /* fill in the config */
237   memset(&drconfig, 0, sizeof(drconfig));
238   drconfig.cache_base       = mips3.cache;
239   drconfig.cache_size       = CACHE_SIZE;
240   drconfig.max_instructions = MAX_INSTRUCTIONS;
241   drconfig.address_bits     = 32;
242   drconfig.lsbs_to_ignore   = 2;
243   drconfig.uses_fp          = 1;
244   drconfig.uses_sse         = USE_SSE;
245   drconfig.pc_in_memory     = 0;
246   drconfig.icount_in_memory = 0;
247   drconfig.pcptr            = (UINT32 *)&mips3.core->pc;
248   drconfig.icountptr        = (UINT32 *)&mips3.core->icount;
249   drconfig.esiptr           = NULL;
250   drconfig.cb_reset         = drc_reset_callback;
251   drconfig.cb_recompile     = drc_recompile_callback;
252   drconfig.cb_entrygen      = drc_entrygen_callback;
253
254   /* initialize the compiler */
255   mips3.drc = drc_init(cpu_getactivecpu(), &drconfig);
256   mips3.drcoptions = MIPS3DRC_FASTEST_OPTIONS;
257
258   /* allocate our data out of the cache */
259   mips3.drcdata = drc_alloc(mips3.drc, sizeof(*mips3.drcdata));
260   memset(mips3.drcdata, 0, sizeof(*mips3.drcdata));
261}
262
263
264/*-------------------------------------------------
265    mips3drc_exit - clean up the drc-specific
266    state
267-------------------------------------------------*/
268
269static void mips3drc_exit(void)
270{
271   drc_exit(mips3.drc);
272}
273
274
275
276/***************************************************************************
277    RECOMPILER CALLBACKS
278***************************************************************************/
279
280/*------------------------------------------------------------------
281    drc_reset_callback
282------------------------------------------------------------------*/
283
284static void drc_reset_callback(drc_core *drc)
285{
286   if (LOG_CODE)
287   {
288      x86log_disasm_code_range(mips3.log, "entry_point:", (x86code *)drc->entry_point, drc->out_of_cycles);
289      x86log_disasm_code_range(mips3.log, "out_of_cycles:", drc->out_of_cycles, drc->recompile);
290      x86log_disasm_code_range(mips3.log, "recompile:", drc->recompile, drc->dispatch);
291      x86log_disasm_code_range(mips3.log, "dispatch:", drc->dispatch, drc->flush);
292      x86log_disasm_code_range(mips3.log, "flush:", drc->flush, drc->cache_top);
293   }
294
295   mips3.drcdata->generate_interrupt_exception = drc->cache_top;
296   append_generate_exception(drc, EXCEPTION_INTERRUPT);
297   if (LOG_CODE)
298      x86log_disasm_code_range(mips3.log, "generate_interrupt_exception:", mips3.drcdata->generate_interrupt_exception, drc->cache_top);
299
300   mips3.drcdata->generate_cop_exception = drc->cache_top;
301   append_generate_exception(drc, EXCEPTION_BADCOP);
302   if (LOG_CODE)
303      x86log_disasm_code_range(mips3.log, "generate_cop_exception:", mips3.drcdata->generate_cop_exception, drc->cache_top);
304
305   mips3.drcdata->generate_overflow_exception = drc->cache_top;
306   append_generate_exception(drc, EXCEPTION_OVERFLOW);
307   if (LOG_CODE)
308      x86log_disasm_code_range(mips3.log, "generate_overflow_exception:", mips3.drcdata->generate_overflow_exception, drc->cache_top);
309
310   mips3.drcdata->generate_invalidop_exception = drc->cache_top;
311   append_generate_exception(drc, EXCEPTION_INVALIDOP);
312   if (LOG_CODE)
313      x86log_disasm_code_range(mips3.log, "generate_invalidop_exception:", mips3.drcdata->generate_invalidop_exception, drc->cache_top);
314
315   mips3.drcdata->generate_syscall_exception = drc->cache_top;
316   append_generate_exception(drc, EXCEPTION_SYSCALL);
317   if (LOG_CODE)
318      x86log_disasm_code_range(mips3.log, "generate_syscall_exception:", mips3.drcdata->generate_syscall_exception, drc->cache_top);
319
320   mips3.drcdata->generate_break_exception = drc->cache_top;
321   append_generate_exception(drc, EXCEPTION_BREAK);
322   if (LOG_CODE)
323      x86log_disasm_code_range(mips3.log, "generate_break_exception:", mips3.drcdata->generate_break_exception, drc->cache_top);
324
325   mips3.drcdata->generate_trap_exception = drc->cache_top;
326   append_generate_exception(drc, EXCEPTION_TRAP);
327   if (LOG_CODE)
328      x86log_disasm_code_range(mips3.log, "generate_trap_exception:", mips3.drcdata->generate_trap_exception, drc->cache_top);
329
330   mips3.drcdata->generate_tlbload_exception = drc->cache_top;
331   append_generate_exception(drc, EXCEPTION_TLBLOAD);
332   if (LOG_CODE)
333      x86log_disasm_code_range(mips3.log, "generate_tlbload_exception:", mips3.drcdata->generate_tlbload_exception, drc->cache_top);
334
335   mips3.drcdata->generate_tlbstore_exception = drc->cache_top;
336   append_generate_exception(drc, EXCEPTION_TLBSTORE);
337   if (LOG_CODE)
338      x86log_disasm_code_range(mips3.log, "generate_tlbstore_exception:", mips3.drcdata->generate_tlbstore_exception, drc->cache_top);
339
340   mips3.drcdata->handle_pc_tlb_mismatch = drc->cache_top;
341   emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EDI);                                    // mov  eax,edi
342   emit_shr_r32_imm(DRCTOP, REG_EAX, 12);                                       // shr  eax,12
343   emit_mov_r32_m32(DRCTOP, REG_EBX, MISD(REG_EAX, 4, mips3.core->tlb_table));            // mov  ebx,tlb_table[eax*4]
344   emit_test_r32_imm(DRCTOP, REG_EBX, 2);                                       // test ebx,2
345   emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EDI);                                    // mov  eax,edi
346   emit_jcc(DRCTOP, COND_NZ, mips3.drcdata->generate_tlbload_exception);               // jnz  generate_tlbload_exception
347   emit_mov_m32_r32(DRCTOP, MABS(drc->pcptr), REG_EDI);                           // mov  [pcptr],edi
348   emit_jmp(DRCTOP, drc->recompile);                                          // jmp  recompile
349   if (LOG_CODE)
350      x86log_disasm_code_range(mips3.log, "handle_pc_tlb_mismatch:", mips3.drcdata->handle_pc_tlb_mismatch, drc->cache_top);
351
352   mips3.drcdata->read_and_translate_byte_signed = drc->cache_top;
353   append_readwrite_and_translate(drc, 1, ARW_READ | ARW_SIGNED);
354   if (LOG_CODE)
355      x86log_disasm_code_range(mips3.log, "read_and_translate_byte_signed:", mips3.drcdata->read_and_translate_byte_signed, drc->cache_top);
356
357   mips3.drcdata->read_and_translate_byte_unsigned = drc->cache_top;
358   append_readwrite_and_translate(drc, 1, ARW_READ | ARW_UNSIGNED);
359   if (LOG_CODE)
360      x86log_disasm_code_range(mips3.log, "read_and_translate_byte_unsigned:", mips3.drcdata->read_and_translate_byte_unsigned, drc->cache_top);
361
362   mips3.drcdata->read_and_translate_half_signed = drc->cache_top;
363   append_readwrite_and_translate(drc, 2, ARW_READ | ARW_SIGNED);
364   if (LOG_CODE)
365      x86log_disasm_code_range(mips3.log, "read_and_translate_half_signed:", mips3.drcdata->read_and_translate_half_signed, drc->cache_top);
366
367   mips3.drcdata->read_and_translate_half_unsigned = drc->cache_top;
368   append_readwrite_and_translate(drc, 2, ARW_READ | ARW_UNSIGNED);
369   if (LOG_CODE)
370      x86log_disasm_code_range(mips3.log, "read_and_translate_half_unsigned:", mips3.drcdata->read_and_translate_half_unsigned, drc->cache_top);
371
372   mips3.drcdata->read_and_translate_word = drc->cache_top;
373   append_readwrite_and_translate(drc, 4, ARW_READ);
374   if (LOG_CODE)
375      x86log_disasm_code_range(mips3.log, "read_and_translate_word:", mips3.drcdata->read_and_translate_word, drc->cache_top);
376
377   mips3.drcdata->read_and_translate_word_masked = drc->cache_top;
378   append_readwrite_and_translate(drc, 4, ARW_READ | ARW_MASKED);
379   if (LOG_CODE)
380      x86log_disasm_code_range(mips3.log, "read_and_translate_word_masked:", mips3.drcdata->read_and_translate_word_masked, drc->cache_top);
381
382   mips3.drcdata->read_and_translate_double = drc->cache_top;
383   append_readwrite_and_translate(drc, 8, ARW_READ);
384   if (LOG_CODE)
385      x86log_disasm_code_range(mips3.log, "read_and_translate_double:", mips3.drcdata->read_and_translate_double, drc->cache_top);
386
387   mips3.drcdata->read_and_translate_double_masked = drc->cache_top;
388   append_readwrite_and_translate(drc, 8, ARW_READ | ARW_MASKED);
389   if (LOG_CODE)
390      x86log_disasm_code_range(mips3.log, "read_and_translate_double_masked:", mips3.drcdata->read_and_translate_double_masked, drc->cache_top);
391
392   mips3.drcdata->write_and_translate_byte = drc->cache_top;
393   append_readwrite_and_translate(drc, 1, ARW_WRITE);
394   if (LOG_CODE)
395      x86log_disasm_code_range(mips3.log, "write_and_translate_byte:", mips3.drcdata->write_and_translate_byte, drc->cache_top);
396
397   mips3.drcdata->write_and_translate_half = drc->cache_top;
398   append_readwrite_and_translate(drc, 2, ARW_WRITE);
399   if (LOG_CODE)
400      x86log_disasm_code_range(mips3.log, "write_and_translate_half:", mips3.drcdata->write_and_translate_half, drc->cache_top);
401
402   mips3.drcdata->write_and_translate_word = drc->cache_top;
403   append_readwrite_and_translate(drc, 4, ARW_WRITE);
404   if (LOG_CODE)
405      x86log_disasm_code_range(mips3.log, "write_and_translate_word:", mips3.drcdata->write_and_translate_word, drc->cache_top);
406
407   mips3.drcdata->write_and_translate_word_masked = drc->cache_top;
408   append_readwrite_and_translate(drc, 4, ARW_WRITE | ARW_MASKED);
409   if (LOG_CODE)
410      x86log_disasm_code_range(mips3.log, "write_and_translate_word_masked:", mips3.drcdata->write_and_translate_word_masked, drc->cache_top);
411
412   mips3.drcdata->write_and_translate_double = drc->cache_top;
413   append_readwrite_and_translate(drc, 8, ARW_WRITE);
414   if (LOG_CODE)
415      x86log_disasm_code_range(mips3.log, "write_and_translate_double:", mips3.drcdata->write_and_translate_double, drc->cache_top);
416
417   mips3.drcdata->write_and_translate_double_masked = drc->cache_top;
418   append_readwrite_and_translate(drc, 8, ARW_WRITE | ARW_MASKED);
419   if (LOG_CODE)
420      x86log_disasm_code_range(mips3.log, "write_and_translate_double_masked:", mips3.drcdata->write_and_translate_double_masked, drc->cache_top);
421}
422
423
424/*------------------------------------------------------------------
425    drc_recompile_callback
426------------------------------------------------------------------*/
427
428static void drc_recompile_callback(drc_core *drc)
429{
430   int remaining = MAX_INSTRUCTIONS;
431   x86code *start = drc->cache_top;
432   UINT32 pc = mips3.core->pc;
433   UINT32 lastpc = pc;
434   UINT32 physpc;
435
436   (void)start;
437
438   /* begin the sequence */
439   drc_begin_sequence(drc, pc);
440
441   /* make sure our FR flag matches the last time */
442   emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_FR);                        // test [COP0_Status],SR_FR
443   emit_jcc(DRCTOP, IS_FR0 ? COND_NZ : COND_Z, drc->recompile);                     // jnz/z recompile
444
445   /* ensure that we are still mapped */
446   append_tlb_verify(drc, pc, mips3.drcdata->handle_pc_tlb_mismatch);
447   physpc = pc;
448   if (!mips3com_translate_address(mips3.core, ADDRESS_SPACE_PROGRAM, &physpc))
449   {
450      emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EDI);                                 // mov  eax,edi
451      emit_jmp(DRCTOP, mips3.drcdata->generate_tlbload_exception);                  // jmp  tlbload_exception
452      goto exit;
453   }
454   change_pc(physpc);
455
456   /* loose verification case: one verification here only */
457   if (!(mips3.drcoptions & MIPS3DRC_STRICT_VERIFY))
458      drc_append_verify_code(drc, cpu_opptr(physpc), 4);
459
460   /* loop until we hit an unconditional branch */
461   while (--remaining != 0)
462   {
463      UINT32 result;
464
465      /* if we crossed a page boundary, check the mapping */
466      if ((pc ^ lastpc) & 0xfffff000)
467      {
468         physpc = pc;
469         if (!mips3com_translate_address(mips3.core, ADDRESS_SPACE_PROGRAM, &physpc))
470            break;
471         append_tlb_verify(drc, pc, drc->dispatch);
472         change_pc(physpc);
473      }
474
475      /* compile one instruction */
476      physpc = (physpc & 0xfffff000) | (pc & 0xfff);
477      result = compile_one(drc, pc, physpc);
478      lastpc = pc;
479      pc += (INT32)result >> 20;
480      if (result & RECOMPILE_END_OF_STRING)
481         break;
482   }
483
484   /* add dispatcher just in case */
485   if (remaining == 0)
486      drc_append_dispatcher(drc);
487
488exit:
489   /* end the sequence */
490   drc_end_sequence(drc);
491
492   /* log the generated code */
493   if (LOG_CODE)
494   {
495      char label[60];
496      physpc = mips3.core->pc;
497      mips3com_translate_address(mips3.core, ADDRESS_SPACE_PROGRAM, &physpc);
498      sprintf(label, "Code @ %08X (%08X physical)", mips3.core->pc, physpc);
499      x86log_disasm_code_range(mips3.log, label, start, drc->cache_top);
500   }
501}
502
503
504/*------------------------------------------------------------------
505    drc_entrygen_callback
506------------------------------------------------------------------*/
507
508static void drc_entrygen_callback(drc_core *drc)
509{
510   emit_mov_r32_imm(DRCTOP, REG_ESI, (FPTR)&mips3.core->r[17]);
511   append_check_interrupts(drc, 1);
512}
513
514
515
516/***************************************************************************
517    RECOMPILER CORE
518***************************************************************************/
519
520/*------------------------------------------------------------------
521    compile_one
522------------------------------------------------------------------*/
523
524static UINT32 compile_one(drc_core *drc, UINT32 pc, UINT32 physpc)
525{
526   int pcdelta, cycles, hotnum;
527   UINT32 *opptr;
528   UINT32 result;
529
530   /* register this instruction */
531   drc_register_code_at_cache_top(drc, pc);
532
533   /* get a pointer to the current instruction */
534   change_pc(physpc);
535   opptr = cpu_opptr(physpc);
536
537   /* emit debugging and self-modifying code checks */
538   drc_append_call_debugger(drc);
539   if (mips3.drcoptions & MIPS3DRC_STRICT_VERIFY)
540      drc_append_verify_code(drc, opptr, 4);
541
542   /* is this a hotspot? */
543   for (hotnum = 0; hotnum < MIPS3_MAX_HOTSPOTS; hotnum++)
544      if (pc == mips3.hotspot[hotnum].pc && *(UINT32 *)opptr == mips3.hotspot[hotnum].opcode)
545         break;
546
547   /* compile the instruction */
548   result = recompile_instruction(drc, pc, physpc);
549
550   /* handle the results */
551   if (!(result & RECOMPILE_SUCCESSFUL))
552      fatalerror("Unimplemented op %08X (%02X,%02X)", *opptr, *opptr >> 26, *opptr & 0x3f);
553
554   pcdelta = (INT32)result >> 20;
555   cycles = (result >> 8) & 0xfff;
556
557   /* absorb any NOPs following */
558   if (STRIP_NOPS && !Machine->debug_mode)
559   {
560      if (!(result & (RECOMPILE_END_OF_STRING | RECOMPILE_CHECK_INTERRUPTS | RECOMPILE_CHECK_SW_INTERRUPTS)))
561         while ((((pc + pcdelta) ^ pc) & 0xfffff000) == 0 && pcdelta < 120 && opptr[pcdelta/4] == 0)
562         {
563            pcdelta += 4;
564            cycles += 1;
565         }
566   }
567
568   /* epilogue */
569   if (hotnum != MIPS3_MAX_HOTSPOTS)
570      cycles += mips3.hotspot[hotnum].cycles;
571   drc_append_standard_epilogue(drc, cycles, pcdelta, 1);
572
573   /* check interrupts */
574   if (result & RECOMPILE_CHECK_INTERRUPTS)
575      append_check_interrupts(drc, 0);
576   if (result & RECOMPILE_CHECK_SW_INTERRUPTS)
577      append_check_sw_interrupts(drc, 0);
578   if (result & RECOMPILE_ADD_DISPATCH)
579      drc_append_dispatcher(drc);
580
581   return (result & 0xff) | ((cycles & 0xfff) << 8) | ((pcdelta & 0xfff) << 20);
582}
583
584
585
586/***************************************************************************
587    COMMON ROUTINES
588***************************************************************************/
589
590/*------------------------------------------------------------------
591    append_generate_exception
592------------------------------------------------------------------*/
593
594static void append_generate_exception(drc_core *drc, UINT8 exception)
595{
596   UINT32 offset = (exception >= EXCEPTION_TLBMOD && exception <= EXCEPTION_TLBSTORE) ? 0x00 : 0x180;
597   emit_link link1, link2;
598
599   /* assumes address is in EAX */
600   if (exception == EXCEPTION_TLBLOAD || exception == EXCEPTION_TLBSTORE)
601   {
602      emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_BadVAddr), REG_EAX);                     // mov  [BadVAddr],eax
603      emit_and_m32_imm(DRCTOP, CPR0ADDR(COP0_EntryHi), 0x000000ff);                  // and  [EntryHi],0x000000ff
604      emit_and_r32_imm(DRCTOP, REG_EAX, 0xffffe000);                              // and  eax,0xffffe000
605      emit_or_m32_r32(DRCTOP, CPR0ADDR(COP0_EntryHi), REG_EAX);                     // or   [EntryHi],eax
606      emit_and_m32_imm(DRCTOP, CPR0ADDR(COP0_Context), 0xff800000);                  // and  [Context],0xff800000
607      emit_shr_r32_imm(DRCTOP, REG_EAX, 9);                                    // shr  eax,9
608      emit_or_m32_r32(DRCTOP, CPR0ADDR(COP0_Context), REG_EAX);                     // or   [Context],eax
609   }
610
611   emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_EPC), REG_EDI);                           // mov  [COP0_EPC],edi
612   emit_mov_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Cause));                        // mov  eax,[COP0_Cause]
613   emit_and_r32_imm(DRCTOP, REG_EAX, ~0x800000ff);                                 // and  eax,~0x800000ff
614   if (exception)
615      emit_or_r32_imm(DRCTOP, REG_EAX, exception << 2);                           // or   eax,exception << 2
616   emit_cmp_m32_imm(DRCTOP, MABS(&mips3.nextpc), ~0);                              // cmp  [mips3.nextpc],~0
617   emit_jcc_short_link(DRCTOP, COND_E, &link1);                                 // je   skip
618   emit_mov_m32_imm(DRCTOP, MABS(&mips3.nextpc), ~0);                              // mov  [mips3.nextpc],~0
619   emit_sub_m32_imm(DRCTOP, CPR0ADDR(COP0_EPC), 4);                              // sub  [COP0_EPC],4
620   emit_or_r32_imm(DRCTOP, REG_EAX, 0x80000000);                                 // or   eax,0x80000000
621   resolve_link(DRCTOP, &link1);                                          // skip:
622   emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Cause), REG_EAX);                        // mov  [COP0_Cause],eax
623   emit_mov_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Status));                        // mov  eax,[COP0_Status]
624   emit_or_r32_imm(DRCTOP, REG_EAX, SR_EXL);                                    // or   eax,SR_EXL
625   emit_test_r32_imm(DRCTOP, REG_EAX, SR_BEV);                                    // test eax,SR_BEV
626   emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Status), REG_EAX);                        // mov  [COP0_Status],eax
627   emit_mov_r32_imm(DRCTOP, REG_EDI, 0xbfc00200 + offset);                           // mov  edi,0xbfc00200+offset
628   emit_jcc_short_link(DRCTOP, COND_NZ, &link2);                                 // jnz  skip2
629   emit_mov_r32_imm(DRCTOP, REG_EDI, 0x80000000 + offset);                           // mov  edi,0x80000000+offset
630   resolve_link(DRCTOP, &link2);                                             // skip2:
631   drc_append_dispatcher(drc);                                                // dispatch
632}
633
634
635/*------------------------------------------------------------------
636    append_readwrite_and_translate
637------------------------------------------------------------------*/
638
639static void append_readwrite_and_translate(drc_core *drc, int size, UINT8 flags)
640{
641   emit_link link1 = { 0 }, link2 = { 0 }, link3 = { 0 };
642   int ramnum;
643
644   emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 4));                              // mov  eax,[esp+4]
645   emit_mov_r32_r32(DRCTOP, REG_EBX, REG_EAX);                                    // mov  ebx,eax
646   emit_shr_r32_imm(DRCTOP, REG_EBX, 12);                                       // shr  ebx,12
647   emit_mov_r32_m32(DRCTOP, REG_EBX, MISD(REG_EBX, 4, mips3.core->tlb_table));            // mov  ebx,tlb_table[ebx*4]
648   emit_and_r32_imm(DRCTOP, REG_EAX, 0xfff);                                    // and  eax,0xfff
649   emit_shr_r32_imm(DRCTOP, REG_EBX, ((flags & ARW_WRITE) ? 1 : 2));                  // shr  ebx,2/1 (read/write)
650   emit_lea_r32_m32(DRCTOP, REG_EBX, MBISD(REG_EAX, REG_EBX, ((flags & ARW_WRITE) ? 2 : 4), 0));
651                                                                     // lea  ebx,[eax+ebx*4/2] (read/write)
652   emit_jcc_near_link(DRCTOP, COND_C, &link1);                                    // jc   error
653   for (ramnum = 0; ramnum < MIPS3_MAX_FASTRAM; ramnum++)
654      if (!Machine->debug_mode && mips3.fastram[ramnum].base && (!(flags & ARW_WRITE) || !mips3.fastram[ramnum].readonly))
655      {
656         UINT32 fastbase = (UINT32)((UINT8 *)mips3.fastram[ramnum].base - mips3.fastram[ramnum].start);
657         if (mips3.fastram[ramnum].end != 0xffffffff)
658         {
659            emit_cmp_r32_imm(DRCTOP, REG_EBX, mips3.fastram[ramnum].end);            // cmp  ebx,fastram_end
660            emit_jcc_short_link(DRCTOP, COND_A, &link2);                        // ja   notram
661         }
662         if (mips3.fastram[ramnum].start != 0x00000000)
663         {
664            emit_cmp_r32_imm(DRCTOP, REG_EBX, mips3.fastram[ramnum].start);            // cmp  ebx,fastram_start
665            emit_jcc_short_link(DRCTOP, COND_B, &link3);                        // jb   notram
666         }
667
668         if (!(flags & ARW_WRITE))
669         {
670            if (size == 1)
671            {
672               if (mips3.core->bigendian)
673                  emit_xor_r32_imm(DRCTOP, REG_EBX, 3);                        // xor   ebx,3
674               if (flags & ARW_SIGNED)
675                  emit_movsx_r32_m8(DRCTOP, REG_EAX, MBD(REG_EBX, fastbase));         // movsx eax,byte ptr [ebx+fastbase]
676               else
677                  emit_movzx_r32_m8(DRCTOP, REG_EAX, MBD(REG_EBX, fastbase));         // movzx eax,byte ptr [ebx+fastbase]
678            }
679            else if (size == 2)
680            {
681               if (mips3.core->bigendian)
682                  emit_xor_r32_imm(DRCTOP, REG_EBX, 2);                        // xor   ebx,2
683               if (flags & ARW_SIGNED)
684                  emit_movsx_r32_m16(DRCTOP, REG_EAX, MBD(REG_EBX, fastbase));      // movsx eax,word ptr [ebx+fastbase]
685               else
686                  emit_movzx_r32_m16(DRCTOP, REG_EAX, MBD(REG_EBX, fastbase));      // movzx eax,word ptr [ebx+fastbase]
687            }
688            else if (size == 4)
689               emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_EBX, fastbase));            // mov   eax,[ebx+fastbase]
690            else if (size == 8)
691            {
692               if (mips3.core->bigendian)
693                  emit_mov_r64_m64(DRCTOP, REG_EAX, REG_EDX, MBD(REG_EBX, (FPTR)fastbase));
694                                                                     // mov   eax:edx,[ebx+fastbase]
695               else
696                  emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, MBD(REG_EBX, (FPTR)fastbase));
697                                                                     // mov   edx:eax,[ebx+fastbase]
698            }
699            emit_ret(DRCTOP);                                             // ret
700         }
701         else
702         {
703            if (size == 1)
704            {
705               emit_mov_r8_m8(DRCTOP, REG_AL, MBD(REG_ESP, 8));                  // mov   al,[esp+8]
706               if (mips3.core->bigendian)
707                  emit_xor_r32_imm(DRCTOP, REG_EBX, 3);                        // xor   ebx,3
708               emit_mov_m8_r8(DRCTOP, MBD(REG_EBX, fastbase), REG_AL);               // mov   [ebx+fastbase],al
709            }
710            else if (size == 2)
711            {
712               emit_mov_r16_m16(DRCTOP, REG_AX, MBD(REG_ESP, 8));                  // mov   ax,[esp+8]
713               if (mips3.core->bigendian)
714                  emit_xor_r32_imm(DRCTOP, REG_EBX, 2);                        // xor   ebx,2
715               emit_mov_m16_r16(DRCTOP, MBD(REG_EBX, fastbase), REG_AX);            // mov   [ebx+fastbase],ax
716            }
717            else if (size == 4)
718            {
719               if (!(flags & ARW_MASKED))
720               {
721                  emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 8));               // mov   eax,[esp+8]
722                  emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase), REG_EAX);         // mov   [ebx+fastbase],eax
723               }
724               else
725               {
726                  emit_mov_r32_m32(DRCTOP, REG_ECX, MBD(REG_ESP, 12));            // mov   ecx,[esp+12]
727                  emit_mov_r32_r32(DRCTOP, REG_EAX, REG_ECX);                     // mov   eax,ecx
728                  emit_not_r32(DRCTOP, REG_ECX);                              // not   ecx
729                  emit_and_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 8));               // and   eax,[esp+8]
730                  emit_and_r32_m32(DRCTOP, REG_ECX, MBD(REG_EBX, fastbase));         // and   ecx,[ebx+fastbase]
731                  emit_or_r32_r32(DRCTOP, REG_EAX, REG_ECX);                     // or    eax,ecx
732                  emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase), REG_EAX);         // mov   [ebx+fastbase],eax
733               }
734            }
735            else if (size == 8)
736            {
737               if (!(flags & ARW_MASKED))
738               {
739                  if (mips3.core->bigendian)
740                  {
741                     emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 8));            // mov   eax,[esp+8]
742                     emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase+4), REG_EAX);   // mov   [ebx+fastbase+4],eax
743                     emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 12));         // mov   eax,[esp+12]
744                     emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase), REG_EAX);      // mov   [ebx+fastbase],eax
745                  }
746                  else
747                  {
748                     emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 8));            // mov   eax,[esp+8]
749                     emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase), REG_EAX);      // mov   [ebx+fastbase],eax
750                     emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 12));         // mov   eax,[esp+12]
751                     emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase+4), REG_EAX);   // mov   [ebx+fastbase+4],eax
752                  }
753               }
754               else
755               {
756                  if (mips3.core->bigendian)
757                  {
758                     emit_mov_r32_m32(DRCTOP, REG_ECX, MBD(REG_ESP, 16));         // mov   ecx,[esp+16]
759                     emit_mov_r32_r32(DRCTOP, REG_EAX, REG_ECX);                  // mov   eax,ecx
760                     emit_not_r32(DRCTOP, REG_ECX);                           // not   ecx
761                     emit_and_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 8));            // and   eax,[esp+8]
762                     emit_and_r32_m32(DRCTOP, REG_ECX, MBD(REG_EBX, fastbase+4));   // and   ecx,[ebx+fastbase+4]
763                     emit_or_r32_r32(DRCTOP, REG_EAX, REG_ECX);                  // or    eax,ecx
764                     emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase+4), REG_EAX);   // mov   [ebx+fastbase+4],eax
765                     emit_mov_r32_m32(DRCTOP, REG_ECX, MBD(REG_ESP, 20));         // mov   ecx,[esp+20]
766                     emit_mov_r32_r32(DRCTOP, REG_EAX, REG_ECX);                  // mov   eax,ecx
767                     emit_not_r32(DRCTOP, REG_ECX);                           // not   ecx
768                     emit_and_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 12));         // and   eax,[esp+12]
769                     emit_and_r32_m32(DRCTOP, REG_ECX, MBD(REG_EBX, fastbase));      // and   ecx,[ebx+fastbase]
770                     emit_or_r32_r32(DRCTOP, REG_EAX, REG_ECX);                  // or    eax,ecx
771                     emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase), REG_EAX);      // mov   [ebx+fastbase],eax
772                  }
773                  else
774                  {
775                     emit_mov_r32_m32(DRCTOP, REG_ECX, MBD(REG_ESP, 16));         // mov   ecx,[esp+16]
776                     emit_mov_r32_r32(DRCTOP, REG_EAX, REG_ECX);                  // mov   eax,ecx
777                     emit_not_r32(DRCTOP, REG_ECX);                           // not   ecx
778                     emit_and_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 8));            // and   eax,[esp+8]
779                     emit_and_r32_m32(DRCTOP, REG_ECX, MBD(REG_EBX, fastbase));      // and   ecx,[ebx+fastbase]
780                     emit_or_r32_r32(DRCTOP, REG_EAX, REG_ECX);                  // or    eax,ecx
781                     emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase), REG_EAX);      // mov   [ebx+fastbase],eax
782                     emit_mov_r32_m32(DRCTOP, REG_ECX, MBD(REG_ESP, 20));         // mov   ecx,[esp+20]
783                     emit_mov_r32_r32(DRCTOP, REG_EAX, REG_ECX);                  // mov   eax,ecx
784                     emit_not_r32(DRCTOP, REG_ECX);                           // not   ecx
785                     emit_and_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 12));         // and   eax,[esp+12]
786                     emit_and_r32_m32(DRCTOP, REG_ECX, MBD(REG_EBX, fastbase+4));   // and   ecx,[ebx+fastbase+4]
787                     emit_or_r32_r32(DRCTOP, REG_EAX, REG_ECX);                  // or    eax,ecx
788                     emit_mov_m32_r32(DRCTOP, MBD(REG_EBX, fastbase+4), REG_EAX);   // mov   [ebx+fastbase+4],eax
789                  }
790               }
791            }
792            emit_ret(DRCTOP);                                             // ret
793         }
794
795         if (mips3.fastram[ramnum].end != 0xffffffff)                        // notram:
796            resolve_link(DRCTOP, &link2);
797         if (mips3.fastram[ramnum].start != 0x00000000)
798            resolve_link(DRCTOP, &link3);
799      }
800
801   if (flags & ARW_WRITE)
802   {
803      emit_mov_m32_r32(DRCTOP, MBD(REG_ESP, 4), REG_EBX);                           // mov  [esp+4],ebx
804      if (size == 1)
805         emit_jmp(DRCTOP, (x86code *)mips3.core->memory.writebyte);                  // jmp  writebyte
806      else if (size == 2)
807         emit_jmp(DRCTOP, (x86code *)mips3.core->memory.writehalf);                  // jmp  writehalf
808      else if (size == 4)
809      {
810         if (!(flags & ARW_MASKED))
811            emit_jmp(DRCTOP, (x86code *)mips3.core->memory.writeword);               // jmp  writeword
812         else
813            emit_jmp(DRCTOP, (x86code *)mips3.core->memory.writeword_masked);         // jmp  writeword_masked
814      }
815      else
816      {
817         if (!(flags & ARW_MASKED))
818            emit_jmp(DRCTOP, (x86code *)mips3.core->memory.writedouble);            // jmp  writedouble
819         else
820            emit_jmp(DRCTOP, (x86code *)mips3.core->memory.writedouble_masked);         // jmp  writedouble_masked
821      }
822   }
823   else
824   {
825      if (size == 1)
826      {
827         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
828         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
829         emit_call(DRCTOP, (x86code *)mips3.core->memory.readbyte);                  // call  readbyte
830         if (flags & ARW_SIGNED)
831            emit_movsx_r32_r8(DRCTOP, REG_EAX, REG_AL);                           // movsx eax,al
832         else
833            emit_movzx_r32_r8(DRCTOP, REG_EAX, REG_AL);                           // movzx eax,al
834         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
835         emit_ret(DRCTOP);                                                // ret
836      }
837      else if (size == 2)
838      {
839         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
840         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
841         emit_call(DRCTOP, (x86code *)mips3.core->memory.readhalf);                  // call  readhalf
842         if (flags & ARW_SIGNED)
843            emit_movsx_r32_r16(DRCTOP, REG_EAX, REG_AX);                        // movsx eax,ax
844         else
845            emit_movzx_r32_r16(DRCTOP, REG_EAX, REG_AX);                        // movzx eax,ax
846         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
847         emit_ret(DRCTOP);                                                // ret
848      }
849      else if (size == 4)
850      {
851         emit_mov_m32_r32(DRCTOP, MBD(REG_ESP, 4), REG_EBX);                        // mov  [esp+4],ebx
852         if (!(flags & ARW_MASKED))
853            emit_jmp(DRCTOP, (x86code *)mips3.core->memory.readword);               // jmp  readword
854         else
855            emit_jmp(DRCTOP, (x86code *)mips3.core->memory.readword_masked);         // jmp  readword_masked
856      }
857      else
858      {
859         emit_mov_m32_r32(DRCTOP, MBD(REG_ESP, 4), REG_EBX);                        // mov  [esp+4],ebx
860         if (!(flags & ARW_MASKED))
861            emit_jmp(DRCTOP, (x86code *)mips3.core->memory.readdouble);               // jmp  readdouble
862         else
863            emit_jmp(DRCTOP, (x86code *)mips3.core->memory.readdouble_masked);         // jmp  readdouble_masked
864      }
865   }
866   {
867      int valuebytes = (size == 8) ? 8 : 4;
868      int stackbytes = 4 + ((flags & ARW_WRITE) ? 4 + valuebytes : 4) + ((flags & ARW_MASKED) ? valuebytes : 0);
869      resolve_link(DRCTOP, &link1);                                       // error:
870      emit_mov_r32_m32(DRCTOP, REG_EAX, MBD(REG_ESP, 4));                           // mov  eax,[esp+4]
871      emit_add_r32_imm(DRCTOP, REG_ESP, stackbytes);                              // add  esp,stack_bytes
872      emit_jmp(DRCTOP, (flags & ARW_WRITE) ? (x86code *)mips3.drcdata->generate_tlbstore_exception : (x86code *)mips3.drcdata->generate_tlbload_exception);
873                                                                     // jmp    generate_exception
874   }
875}
876
877
878/*------------------------------------------------------------------
879    append_tlb_verify
880------------------------------------------------------------------*/
881
882static void append_tlb_verify(drc_core *drc, UINT32 pc, void *target)
883{
884   /* addresses 0x80000000-0xbfffffff are direct-mapped; no checking needed */
885   if (pc < 0x80000000 || pc >= 0xc0000000)
886   {
887      emit_cmp_m32_imm(DRCTOP, MABS(&mips3.core->tlb_table[pc >> 12]), mips3.core->tlb_table[pc >> 12]);
888                                                                     // cmp  tlbtable[pc >> 12],physpc & 0xfffff000
889      emit_jcc(DRCTOP, COND_NE, target);                                       // jne  handle_pc_tlb_mismatch
890   }
891}
892
893
894/*------------------------------------------------------------------
895    append_update_cycle_counting
896------------------------------------------------------------------*/
897
898static void append_update_cycle_counting(drc_core *drc)
899{
900   emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                       // sub  esp,8
901   emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                                 // mov  [icount],ebp
902   emit_push_imm(DRCTOP, (FPTR)mips3.core);                                    // push mips3.core
903   emit_call(DRCTOP, (x86code *)mips3com_update_cycle_counting);                     // call update_cycle_counting
904   emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                       // add  esp,12
905   emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                                 // mov  ebp,[icount]
906}
907
908
909/*------------------------------------------------------------------
910    append_check_interrupts
911------------------------------------------------------------------*/
912
913static void append_check_interrupts(drc_core *drc, int inline_generate)
914{
915   emit_link link1, link2, link3;
916   emit_mov_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Cause));                        // mov  eax,[COP0_Cause]
917   emit_and_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Status));                        // and  eax,[COP0_Status]
918   emit_and_r32_imm(DRCTOP, REG_EAX, 0xfc00);                                    // and  eax,0xfc00
919   if (!inline_generate)
920      emit_jcc_short_link(DRCTOP, COND_Z, &link1);                              // jz   skip
921   else
922      emit_jcc_near_link(DRCTOP, COND_Z, &link1);                                 // jz   skip
923   emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_IE);                        // test [COP0_Status,SR_IE
924   if (!inline_generate)
925      emit_jcc_short_link(DRCTOP, COND_Z, &link2);                              // jz   skip
926   else
927      emit_jcc_near_link(DRCTOP, COND_Z, &link2);                                 // jz   skip
928   emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_EXL | SR_ERL);                  // test [COP0_Status,SR_EXL | SR_ERL
929   if (!inline_generate)
930      emit_jcc(DRCTOP, COND_Z, mips3.drcdata->generate_interrupt_exception);            // jz   generate_interrupt_exception
931   else
932   {
933      emit_jcc_near_link(DRCTOP, COND_NZ, &link3);                              // jnz  skip
934      append_generate_exception(drc, EXCEPTION_INTERRUPT);                        // <generate exception>
935      resolve_link(DRCTOP, &link3);                                       // skip:
936   }
937   resolve_link(DRCTOP, &link1);                                          // skip:
938   resolve_link(DRCTOP, &link2);
939}
940
941
942/*------------------------------------------------------------------
943    append_check_sw_interrupts
944------------------------------------------------------------------*/
945
946static void append_check_sw_interrupts(drc_core *drc, int inline_generate)
947{
948   emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Cause), 0x300);                           // test [COP0_Cause],0x300
949   emit_jcc(DRCTOP, COND_NZ, mips3.drcdata->generate_interrupt_exception);               // jnz  generate_interrupt_exception
950}
951
952
953/*------------------------------------------------------------------
954    append_branch_or_dispatch
955------------------------------------------------------------------*/
956
957static void append_branch_or_dispatch(drc_core *drc, UINT32 newpc, int cycles)
958{
959   void *code = drc_get_code_at_pc(drc, newpc);
960   emit_mov_r32_imm(DRCTOP, REG_EDI, newpc);                                    // mov  edi,newpc
961   drc_append_standard_epilogue(drc, cycles, 0, 1);                              // <epilogue>
962
963   if (code)
964      emit_jmp(DRCTOP, code);                                                // jmp  code
965   else
966      drc_append_tentative_fixed_dispatcher(drc, newpc);                           // <dispatch>
967}
968
969
970
971/***************************************************************************
972    CORE RECOMPILATION
973***************************************************************************/
974
975static void ddiv(INT64 *rs, INT64 *rt)
976{
977   if (*rt)
978   {
979      mips3.core->r[REG_LO] = *rs / *rt;
980      mips3.core->r[REG_HI] = *rs % *rt;
981   }
982}
983
984static void ddivu(UINT64 *rs, UINT64 *rt)
985{
986   if (*rt)
987   {
988      mips3.core->r[REG_LO] = *rs / *rt;
989      mips3.core->r[REG_HI] = *rs % *rt;
990   }
991}
992
993
994/*------------------------------------------------------------------
995    recompile_delay_slot
996------------------------------------------------------------------*/
997
998static int recompile_delay_slot(drc_core *drc, UINT32 pc)
999{
1000   UINT8 *saved_top;
1001   UINT32 result;
1002   UINT32 physpc;
1003
1004#ifdef ENABLE_DEBUGGER
1005   if (Machine->debug_mode)
1006   {
1007      /* emit debugging */
1008      emit_mov_r32_imm(DRCTOP, REG_EDI, pc);
1009      drc_append_call_debugger(drc);
1010   }
1011#endif
1012
1013   saved_top = drc->cache_top;
1014
1015   /* recompile the instruction as-is */
1016   in_delay_slot = 1;
1017   physpc = pc;
1018   mips3com_translate_address(mips3.core, ADDRESS_SPACE_PROGRAM, &physpc);
1019   result = recompile_instruction(drc, pc, physpc);                              // <next instruction>
1020   in_delay_slot = 0;
1021
1022   /* if the instruction can cause an exception, recompile setting nextpc */
1023   if (result & RECOMPILE_MAY_CAUSE_EXCEPTION)
1024   {
1025      drc->cache_top = saved_top;
1026      emit_mov_m32_imm(DRCTOP, MABS(&mips3.nextpc), 0);                           // bogus nextpc for exceptions
1027      result = recompile_instruction(drc, pc, physpc);                           // <next instruction>
1028      emit_mov_m32_imm(DRCTOP, MABS(&mips3.nextpc), ~0);                           // reset nextpc
1029   }
1030
1031   return (result >> 8) & 0xfff;
1032}
1033
1034
1035/*------------------------------------------------------------------
1036    recompile_instruction
1037------------------------------------------------------------------*/
1038
1039static UINT32 recompile_instruction(drc_core *drc, UINT32 pc, UINT32 physpc)
1040{
1041   emit_link link1, link2 = { 0 }, link3;
1042   UINT32 op = cpu_readop32(physpc);
1043   int cycles;
1044
1045   if (LOG_CODE)
1046      log_add_disasm_comment(mips3.log, drc->cache_top, pc, op);
1047
1048   switch (op >> 26)
1049   {
1050      case 0x00:   /* SPECIAL */
1051         return recompile_special(drc, pc, op);
1052
1053      case 0x01:   /* REGIMM */
1054         return recompile_regimm(drc, pc, op);
1055
1056      case 0x02:   /* J */
1057         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1058         append_branch_or_dispatch(drc, (pc & 0xf0000000) | (LIMMVAL << 2), 1+cycles);   // <branch or dispatch>
1059         return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
1060
1061      case 0x03:   /* JAL */
1062         emit_mov_m64_imm32(DRCTOP, REGADDR(31), pc + 8);                        // mov  [31],pc + 8
1063         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1064         append_branch_or_dispatch(drc, (pc & 0xf0000000) | (LIMMVAL << 2), 1+cycles);   // <branch or dispatch>
1065         return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
1066
1067      case 0x04:   /* BEQ */
1068         if (RSREG == RTREG)
1069         {
1070            cycles = recompile_delay_slot(drc, pc + 4);                           // <next instruction>
1071            append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);         // <branch or dispatch>
1072            return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
1073         }
1074         else if (RSREG == 0)
1075         {
1076            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[rtreg].lo
1077            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // or   eax,[rtreg].hi
1078            emit_jcc_near_link(DRCTOP, COND_NZ, &link1);                        // jnz  skip
1079         }
1080         else if (RTREG == 0)
1081         {
1082            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1083            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // or   eax,[rsreg].hi
1084            emit_jcc_near_link(DRCTOP, COND_NZ, &link1);                        // jnz  skip
1085         }
1086         else
1087         {
1088            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1089            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // cmp  eax,[rtreg].lo
1090            emit_jcc_near_link(DRCTOP, COND_NE, &link1);                        // jne  skip
1091            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                  // mov  eax,[rsreg].hi
1092            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                  // cmp  eax,[rtreg].hi
1093            emit_jcc_near_link(DRCTOP, COND_NE, &link2);                        // jne  skip
1094         }
1095
1096         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1097         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
1098         resolve_link(DRCTOP, &link1);                                    // skip:
1099         if (RSREG != 0 && RTREG != 0)
1100            resolve_link(DRCTOP, &link2);                                 // skip:
1101         return RECOMPILE_SUCCESSFUL_CP(1,4);
1102
1103      case 0x05:   /* BNE */
1104         if (RSREG == 0)
1105         {
1106            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[rtreg].lo
1107            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // or   eax,[rtreg].hi
1108            emit_jcc_near_link(DRCTOP, COND_Z, &link1);                           // jz   skip
1109         }
1110         else if (RTREG == 0)
1111         {
1112            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1113            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // or   eax,[rsreg].hi
1114            emit_jcc_near_link(DRCTOP, COND_Z, &link1);                           // jz   skip
1115         }
1116         else
1117         {
1118            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1119            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // cmp  eax,[rtreg].lo
1120            emit_jcc_short_link(DRCTOP, COND_NE, &link2);                        // jne  takeit
1121            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                  // mov  eax,[rsreg].hi
1122            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                  // cmp  eax,[rtreg].hi
1123            emit_jcc_near_link(DRCTOP, COND_E, &link1);                           // je   skip
1124            resolve_link(DRCTOP, &link2);                                 // takeit:
1125         }
1126
1127         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1128         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
1129         resolve_link(DRCTOP, &link1);                                    // skip:
1130         return RECOMPILE_SUCCESSFUL_CP(1,4);
1131
1132      case 0x06:   /* BLEZ */
1133         if (RSREG == 0)
1134         {
1135            cycles = recompile_delay_slot(drc, pc + 4);                           // <next instruction>
1136            append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);         // <branch or dispatch>
1137            return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
1138         }
1139         else
1140         {
1141            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
1142            emit_jcc_near_link(DRCTOP, COND_G, &link1);                           // jg   skip
1143            emit_jcc_short_link(DRCTOP, COND_L, &link2);                        // jl   takeit
1144            emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), 0);                        // cmp  [rsreg].lo,0
1145            emit_jcc_near_link(DRCTOP, COND_NE, &link3);                        // jne  skip
1146            resolve_link(DRCTOP, &link2);                                 // takeit:
1147         }
1148
1149         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1150         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
1151         resolve_link(DRCTOP, &link1);                                    // skip:
1152         resolve_link(DRCTOP, &link3);                                    // skip:
1153         return RECOMPILE_SUCCESSFUL_CP(1,4);
1154
1155      case 0x07:   /* BGTZ */
1156         if (RSREG == 0)
1157            return RECOMPILE_SUCCESSFUL_CP(1,4);
1158         else
1159         {
1160            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
1161            emit_jcc_near_link(DRCTOP, COND_L, &link1);                           // jl   skip
1162            emit_jcc_short_link(DRCTOP, COND_G, &link2);                        // jg   takeit
1163            emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), 0);                        // cmp  [rsreg].lo,0
1164            emit_jcc_near_link(DRCTOP, COND_E, &link3);                           // je   skip
1165            resolve_link(DRCTOP, &link2);                                 // takeit:
1166         }
1167
1168         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1169         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
1170         resolve_link(DRCTOP, &link1);                                    // skip:
1171         resolve_link(DRCTOP, &link3);                                    // skip:
1172         return RECOMPILE_SUCCESSFUL_CP(1,4);
1173
1174      case 0x08:   /* ADDI */
1175         if (RSREG != 0)
1176         {
1177            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1178            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1179            emit_jcc(DRCTOP, COND_O, mips3.drcdata->generate_overflow_exception);      // jo   generate_overflow_exception
1180            if (RTREG != 0)
1181            {
1182               emit_cdq(DRCTOP);                                          // cdq
1183               emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);            // mov  [rtreg],edx:eax
1184            }
1185         }
1186         else if (RTREG != 0)
1187            emit_mov_m64_imm32(DRCTOP, REGADDR(RTREG), SIMMVAL);                  // mov  [rtreg],const
1188         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
1189
1190      case 0x09:   /* ADDIU */
1191         if (RTREG != 0)
1192         {
1193            if (RSREG != 0)
1194            {
1195               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));               // mov  eax,[rsreg].lo
1196               emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                        // add  eax,SIMMVAL
1197               emit_cdq(DRCTOP);                                          // cdq
1198               emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);            // mov  [rtreg],edx:eax
1199            }
1200            else
1201               emit_mov_m64_imm32(DRCTOP, REGADDR(RTREG), SIMMVAL);               // mov  [rtreg],const
1202         }
1203         return RECOMPILE_SUCCESSFUL_CP(1,4);
1204
1205      case 0x0a:   /* SLTI */
1206         if (RTREG != 0)
1207         {
1208            if (RSREG != 0)
1209            {
1210               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));            // mov  edx:eax,[rsreg]
1211               emit_sub_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                        // sub  eax,[rtreg].lo
1212               emit_sbb_r32_imm(DRCTOP, REG_EDX, ((INT32)SIMMVAL >> 31));            // sbb  edx,[rtreg].lo
1213               emit_shr_r32_imm(DRCTOP, REG_EDX, 31);                           // shr  edx,31
1214               emit_mov_m32_r32(DRCTOP, REGADDRLO(RTREG), REG_EDX);               // mov  [rdreg].lo,edx
1215               emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                     // mov  [rdreg].hi,0
1216            }
1217            else
1218            {
1219               emit_mov_m32_imm(DRCTOP, REGADDRLO(RTREG), (0 < SIMMVAL));            // mov  [rtreg].lo,const
1220               emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                     // mov  [rtreg].hi,sign-extend(const)
1221            }
1222         }
1223         return RECOMPILE_SUCCESSFUL_CP(1,4);
1224
1225      case 0x0b:   /* SLTIU */
1226         if (RTREG != 0)
1227         {
1228            if (RSREG != 0)
1229            {
1230               emit_xor_r32_r32(DRCTOP, REG_ECX, REG_ECX);                        // xor  ecx,ecx
1231               emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), ((INT32)SIMMVAL >> 31));      // cmp  [rsreg].hi,upper
1232               emit_jcc_short_link(DRCTOP, COND_B, &link1);                     // jb   takeit
1233               emit_jcc_short_link(DRCTOP, COND_A, &link2);                     // ja   skip
1234               emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), SIMMVAL);               // cmp  [rsreg].lo,lower
1235               emit_jcc_short_link(DRCTOP, COND_AE, &link3);                     // jae  skip
1236               resolve_link(DRCTOP, &link1);                              // takeit:
1237               emit_add_r32_imm(DRCTOP, REG_ECX, 1);                           // add  ecx,1
1238               resolve_link(DRCTOP, &link2);                              // skip:
1239               resolve_link(DRCTOP, &link3);                              // skip:
1240               emit_mov_m32_r32(DRCTOP, REGADDRLO(RTREG), REG_ECX);               // mov  [rtreg].lo,ecx
1241               emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                     // mov  [rtreg].hi,sign-extend(const)
1242            }
1243            else
1244            {
1245               emit_mov_m32_imm(DRCTOP, REGADDRLO(RTREG), (0 < SIMMVAL));            // mov  [rtreg].lo,const
1246               emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                     // mov  [rtreg].hi,sign-extend(const)
1247            }
1248         }
1249         return RECOMPILE_SUCCESSFUL_CP(1,4);
1250
1251      case 0x0c:   /* ANDI */
1252         if (RTREG != 0)
1253         {
1254            if (RSREG == RTREG)
1255            {
1256               emit_and_m32_imm(DRCTOP, REGADDRLO(RTREG), UIMMVAL);               // and  [rtreg],UIMMVAL
1257               emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                     // mov  [rtreg].hi,0
1258            }
1259            else if (RSREG != 0)
1260            {
1261               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));               // mov  eax,[rsreg].lo
1262               emit_and_r32_imm(DRCTOP, REG_EAX, UIMMVAL);                        // and  eax,UIMMVAL
1263               emit_mov_m32_r32(DRCTOP, REGADDRLO(RTREG), REG_EAX);               // mov  [rtreg].lo,eax
1264               emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                     // mov  [rtreg].hi,0
1265            }
1266            else
1267               emit_mov_m64_imm32(DRCTOP, REGADDR(RTREG), 0);                     // mov  [rtreg],0
1268         }
1269         return RECOMPILE_SUCCESSFUL_CP(1,4);
1270
1271      case 0x0d:   /* ORI */
1272         if (RTREG != 0)
1273         {
1274            if (RSREG == RTREG)
1275               emit_or_m32_imm(DRCTOP, REGADDRLO(RTREG), UIMMVAL);                  // or   [rtreg].lo,UIMMVAL
1276            else if (RSREG != 0)
1277            {
1278               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));            // mov  edx:eax,[rsreg]
1279               emit_or_r32_imm(DRCTOP, REG_EAX, UIMMVAL);                        // or   eax,UIMMVAL
1280               emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);            // mov  [rtreg],edx:eax
1281            }
1282            else
1283               emit_mov_m64_imm32(DRCTOP, REGADDR(RTREG), UIMMVAL);               // mov  [rtreg],const
1284         }
1285         return RECOMPILE_SUCCESSFUL_CP(1,4);
1286
1287      case 0x0e:   /* XORI */
1288         if (RTREG != 0)
1289         {
1290            if (RSREG == RTREG)
1291               emit_xor_m32_imm(DRCTOP, REGADDRLO(RTREG), UIMMVAL);               // xor  [rtreg].lo,UIMMVAL
1292            else if (RSREG != 0)
1293            {
1294               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));            // mov  edx:eax,[rsreg]
1295               emit_xor_r32_imm(DRCTOP, REG_EAX, UIMMVAL);                        // xor  eax,UIMMVAL
1296               emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);            // mov  [rtreg],edx:eax
1297            }
1298            else
1299               emit_mov_m64_imm32(DRCTOP, REGADDR(RTREG), UIMMVAL);               // mov  [rtreg],const
1300         }
1301         return RECOMPILE_SUCCESSFUL_CP(1,4);
1302
1303      case 0x0f:   /* LUI */
1304         if (RTREG != 0)
1305            emit_mov_m64_imm32(DRCTOP, REGADDR(RTREG), UIMMVAL << 16);               // mov  [rtreg],const << 16
1306         return RECOMPILE_SUCCESSFUL_CP(1,4);
1307
1308      case 0x10:   /* COP0 */
1309         return recompile_cop0(drc, pc, op) | RECOMPILE_MAY_CAUSE_EXCEPTION;
1310
1311      case 0x11:   /* COP1 */
1312         return recompile_cop1(drc, pc, op) | RECOMPILE_MAY_CAUSE_EXCEPTION;
1313
1314      case 0x12:   /* COP2 */
1315         emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);         // jmp  generate_invalidop_exception
1316         return RECOMPILE_SUCCESSFUL | RECOMPILE_MAY_CAUSE_EXCEPTION | RECOMPILE_END_OF_STRING;
1317
1318      case 0x13:   /* COP1X - R5000 */
1319         if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
1320         {
1321            emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);      // jmp  generate_invalidop_exception
1322            return RECOMPILE_SUCCESSFUL | RECOMPILE_MAY_CAUSE_EXCEPTION | RECOMPILE_END_OF_STRING;
1323         }
1324         return recompile_cop1x(drc, pc, op) | RECOMPILE_MAY_CAUSE_EXCEPTION;
1325
1326      case 0x14:   /* BEQL */
1327         if (RSREG == RTREG)
1328         {
1329            cycles = recompile_delay_slot(drc, pc + 4);                           // <next instruction>
1330            append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);         // <branch or dispatch>
1331            return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
1332         }
1333         else if (RSREG == 0)
1334         {
1335            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[rtreg].lo
1336            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // or   eax,[rtreg].hi
1337            emit_jcc_near_link(DRCTOP, COND_NZ, &link1);                        // jnz  skip
1338         }
1339         else if (RTREG == 0)
1340         {
1341            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1342            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // or   eax,[rsreg].hi
1343            emit_jcc_near_link(DRCTOP, COND_NZ, &link1);                        // jnz  skip
1344         }
1345         else
1346         {
1347            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1348            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // cmp  eax,[rtreg].lo
1349            emit_jcc_near_link(DRCTOP, COND_NE, &link1);                        // jne  skip
1350            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                  // mov  eax,[rsreg].hi
1351            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                  // cmp  eax,[rtreg].hi
1352            emit_jcc_near_link(DRCTOP, COND_NE, &link2);                        // jne  skip
1353         }
1354
1355         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1356         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
1357         resolve_link(DRCTOP, &link1);                                    // skip:
1358         if (RSREG != 0 && RTREG != 0)
1359            resolve_link(DRCTOP, &link2);                                 // skip:
1360         return RECOMPILE_SUCCESSFUL_CP(1,8);
1361
1362      case 0x15:   /* BNEL */
1363         if (RSREG == 0)
1364         {
1365            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[rtreg].lo
1366            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // or   eax,[rtreg].hi
1367            emit_jcc_near_link(DRCTOP, COND_Z, &link1);                           // jz   skip
1368         }
1369         else if (RTREG == 0)
1370         {
1371            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1372            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // or   eax,[rsreg].hi
1373            emit_jcc_near_link(DRCTOP, COND_Z, &link1);                           // jz   skip
1374         }
1375         else
1376         {
1377            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1378            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // cmp  eax,[rtreg].lo
1379            emit_jcc_short_link(DRCTOP, COND_NE, &link2);                        // jne  takeit
1380            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                  // mov  eax,[rsreg].hi
1381            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                  // cmp  eax,[rtreg].hi
1382            emit_jcc_near_link(DRCTOP, COND_E, &link1);                           // je   skip
1383            resolve_link(DRCTOP, &link2);                                 // takeit:
1384         }
1385
1386         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1387         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
1388         resolve_link(DRCTOP, &link1);                                    // skip:
1389         return RECOMPILE_SUCCESSFUL_CP(1,8);
1390
1391      case 0x16:   /* BLEZL */
1392         if (RSREG == 0)
1393         {
1394            cycles = recompile_delay_slot(drc, pc + 4);                           // <next instruction>
1395            append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);         // <branch or dispatch>
1396            return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
1397         }
1398         else
1399         {
1400            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
1401            emit_jcc_near_link(DRCTOP, COND_G, &link1);                           // jg   skip
1402            emit_jcc_short_link(DRCTOP, COND_L, &link2);                        // jl   takeit
1403            emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), 0);                        // cmp  [rsreg].lo,0
1404            emit_jcc_near_link(DRCTOP, COND_NE, &link3);                        // jne  skip
1405            resolve_link(DRCTOP, &link2);                                 // takeit:
1406         }
1407
1408         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1409         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
1410         resolve_link(DRCTOP, &link1);                                    // skip:
1411         resolve_link(DRCTOP, &link3);                                    // skip:
1412         return RECOMPILE_SUCCESSFUL_CP(1,8);
1413
1414      case 0x17:   /* BGTZL */
1415         if (RSREG == 0)
1416            return RECOMPILE_SUCCESSFUL_CP(1,8);
1417         else
1418         {
1419            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
1420            emit_jcc_near_link(DRCTOP, COND_L, &link1);                           // jl   skip
1421            emit_jcc_short_link(DRCTOP, COND_G, &link2);                        // jg   takeit
1422            emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), 0);                        // cmp  [rsreg].lo,0
1423            emit_jcc_near_link(DRCTOP, COND_E, &link3);                           // je   skip
1424            resolve_link(DRCTOP, &link2);                                 // takeit:
1425         }
1426
1427         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
1428         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
1429         resolve_link(DRCTOP, &link1);                                    // skip:
1430         resolve_link(DRCTOP, &link3);                                    // skip:
1431         return RECOMPILE_SUCCESSFUL_CP(1,8);
1432
1433      case 0x18:   /* DADDI */
1434         if (RSREG != 0)
1435         {
1436            emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));               // mov  edx:eax,[rsreg]
1437            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1438            emit_adc_r32_imm(DRCTOP, REG_EDX, (SIMMVAL < 0) ? -1 : 0);               // adc  edx,signext(SIMMVAL)
1439            emit_jcc(DRCTOP, COND_O, mips3.drcdata->generate_overflow_exception);      // jo   generate_overflow_exception
1440            if (RTREG != 0)
1441               emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);            // mov  [rtreg],edx:eax
1442         }
1443         else if (RTREG != 0)
1444            emit_mov_m64_imm32(DRCTOP, REGADDR(RTREG), SIMMVAL);                  // mov  [rtreg],const
1445         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
1446
1447      case 0x19:   /* DADDIU */
1448         if (RTREG != 0)
1449         {
1450            if (RSREG != 0)
1451            {
1452               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));            // mov  edx:eax,[rsreg]
1453               emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                        // add  eax,SIMMVAL
1454               emit_adc_r32_imm(DRCTOP, REG_EDX, (SIMMVAL < 0) ? -1 : 0);            // adc  edx,signext(SIMMVAL)
1455               emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);            // mov  [rtreg],edx:eax
1456            }
1457            else
1458               emit_mov_m64_imm32(DRCTOP, REGADDR(RTREG), SIMMVAL);               // mov  [rtreg],const
1459         }
1460         return RECOMPILE_SUCCESSFUL_CP(1,4);
1461
1462      case 0x1a:   /* LDL */
1463         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1464         emit_save_pc_before_call(DRCTOP);                                    // save pc
1465         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
1466         if (SIMMVAL)
1467            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1468         emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_EAX, 4, 0));                     // lea  ecx,[eax*4]
1469         emit_and_r32_imm(DRCTOP, REG_EAX, ~7);                                 // and  eax,~7
1470         emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                                 // mov  ebx,-1
1471         emit_mov_r32_imm(DRCTOP, REG_EBP, -1);                                 // mov  ebp,-1
1472         if (!mips3.core->bigendian)
1473            emit_xor_r32_imm(DRCTOP, REG_ECX, 0x1c);                           // xor  ecx,0x1c
1474         emit_shr_r32_cl(DRCTOP, REG_EBP);                                    // shr  ebp,cl
1475         emit_shrd_r32_r32_cl(DRCTOP, REG_EBX, REG_EBP);                           // shrd ebx,ebp,cl
1476         emit_shr_r32_cl(DRCTOP, REG_EBP);                                    // shr  ebp,cl
1477         emit_push_r32(DRCTOP, REG_ECX);                                       // push ecx
1478         emit_push_r32(DRCTOP, REG_EBP);                                       // push ebp
1479         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
1480         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
1481         emit_call(DRCTOP, mips3.drcdata->read_and_translate_double_masked);            // call read_and_translate_double_masked
1482         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1483         emit_pop_r32(DRCTOP, REG_ECX);                                       // pop  ecx
1484
1485         if (RTREG != 0)
1486         {
1487            emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                              // mov  ebx,-1
1488            emit_mov_r32_imm(DRCTOP, REG_EBP, -1);                              // mov  ebp,-1
1489            emit_shl_r32_cl(DRCTOP, REG_EBX);                                 // shl  ebx,cl
1490            emit_shld_r32_r32_cl(DRCTOP, REG_EBP, REG_EBX);                        // shld ebp,ebx,cl
1491            emit_shl_r32_cl(DRCTOP, REG_EBX);                                 // shl  ebx,cl
1492            emit_not_r32(DRCTOP, REG_EBX);                                    // not  ebx
1493            emit_not_r32(DRCTOP, REG_EBP);                                    // not  ebp
1494            emit_shld_r32_r32_cl(DRCTOP, REG_EDX, REG_EAX);                        // shld edx,eax,cl
1495            emit_shl_r32_cl(DRCTOP, REG_EAX);                                 // shl  eax,cl
1496            emit_shld_r32_r32_cl(DRCTOP, REG_EDX, REG_EAX);                        // shld edx,eax,cl
1497            emit_shl_r32_cl(DRCTOP, REG_EAX);                                 // shl  eax,cl
1498            emit_and_r32_m32(DRCTOP, REG_EBX, REGADDRLO(RTREG));                  // and  ebx,[rtreg].lo
1499            emit_and_r32_m32(DRCTOP, REG_EBP, REGADDRHI(RTREG));                  // and  ebp,[rtreg].hi
1500            emit_or_r32_r32(DRCTOP, REG_EAX, REG_EBX);                           // or   eax,ebx
1501            emit_or_r32_r32(DRCTOP, REG_EDX, REG_EBP);                           // or   edx,ebp
1502            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
1503         }
1504         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1505         return RECOMPILE_SUCCESSFUL_CP(1,4);
1506
1507      case 0x1b:   /* LDR */
1508         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1509         emit_save_pc_before_call(DRCTOP);                                    // save pc
1510         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
1511         if (SIMMVAL)
1512            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1513         emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_EAX, 4, 0));                     // lea  ecx,[eax*4]
1514         emit_and_r32_imm(DRCTOP, REG_EAX, ~7);                                 // and  eax,~7
1515         emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                                 // mov  ebx,-1
1516         emit_mov_r32_imm(DRCTOP, REG_EBP, -1);                                 // mov  ebp,-1
1517         if (mips3.core->bigendian)
1518            emit_xor_r32_imm(DRCTOP, REG_ECX, 0x1c);                           // xor  ecx,0x1c
1519         emit_shl_r32_cl(DRCTOP, REG_EBX);                                    // shl  ebx,cl
1520         emit_shld_r32_r32_cl(DRCTOP, REG_EBP, REG_EBX);                           // shld ebp,ebx,cl
1521         emit_shl_r32_cl(DRCTOP, REG_EBX);                                    // shl  ebx,cl
1522         emit_push_r32(DRCTOP, REG_ECX);                                       // push ecx
1523         emit_push_r32(DRCTOP, REG_EBP);                                       // push ebp
1524         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
1525         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
1526         emit_call(DRCTOP, mips3.drcdata->read_and_translate_double_masked);            // call read_and_translate_double_masked
1527         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1528         emit_pop_r32(DRCTOP, REG_ECX);                                       // pop  ecx
1529
1530         if (RTREG != 0)
1531         {
1532            emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                              // mov  ebx,-1
1533            emit_mov_r32_imm(DRCTOP, REG_EBP, -1);                              // mov  ebp,-1
1534            emit_shr_r32_cl(DRCTOP, REG_EBP);                                 // shr  ebp,cl
1535            emit_shrd_r32_r32_cl(DRCTOP, REG_EBX, REG_EBP);                        // shrd ebx,ebp,cl
1536            emit_shr_r32_cl(DRCTOP, REG_EBP);                                 // shr  ebp,cl
1537            emit_not_r32(DRCTOP, REG_EBX);                                    // not  ebx
1538            emit_not_r32(DRCTOP, REG_EBP);                                    // not  ebp
1539            emit_shrd_r32_r32_cl(DRCTOP, REG_EAX, REG_EDX);                        // shld eax,edx,cl
1540            emit_shr_r32_cl(DRCTOP, REG_EDX);                                 // shl  edx,cl
1541            emit_shrd_r32_r32_cl(DRCTOP, REG_EAX, REG_EDX);                        // shld eax,edx,cl
1542            emit_shr_r32_cl(DRCTOP, REG_EDX);                                 // shl  edx,cl
1543            emit_and_r32_m32(DRCTOP, REG_EBX, REGADDRLO(RTREG));                  // and  ebx,[rtreg].lo
1544            emit_and_r32_m32(DRCTOP, REG_EBP, REGADDRHI(RTREG));                  // and  ebp,[rtreg].hi
1545            emit_or_r32_r32(DRCTOP, REG_EAX, REG_EBX);                           // or   eax,ebx
1546            emit_or_r32_r32(DRCTOP, REG_EDX, REG_EBP);                           // or   edx,ebp
1547            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
1548         }
1549         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1550         return RECOMPILE_SUCCESSFUL_CP(1,4);
1551
1552      case 0x1c:   /* IDT-specific opcodes: mad/madu/mul on R4640/4650, msub on RC32364 */
1553         switch (op & 0x1f)
1554         {
1555            case 0: /* MAD */
1556               if (RSREG != 0 && RTREG != 0)
1557               {
1558                  emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));            // mov  eax,[rsreg]
1559                  emit_mov_r32_m32(DRCTOP, REG_EDX, REGADDRLO(RTREG));            // mov  edx,[rtreg]
1560                  emit_imul_r32(DRCTOP, REG_EDX);                              // imul edx
1561                  emit_add_r32_m32(DRCTOP, REG_EAX, LOADDRLO);                  // add  eax,[lo]
1562                  emit_adc_r32_m32(DRCTOP, REG_EDX, HIADDRLO);                  // adc  edx,[hi]
1563                  emit_mov_r32_r32(DRCTOP, REG_EBX, REG_EDX);                     // mov  ebx,edx
1564                  emit_cdq(DRCTOP);                                       // cdq
1565                  emit_mov_m64_r64(DRCTOP, LOADDR, REG_EDX, REG_EAX);               // mov  [lo],edx:eax
1566                  emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EBX);                     // mov  eax,ebx
1567                  emit_cdq(DRCTOP);                                       // cdq
1568                  emit_mov_m64_r64(DRCTOP, HIADDR, REG_EDX, REG_EAX);               // mov  [hi],edx:eax
1569               }
1570               return RECOMPILE_SUCCESSFUL_CP(3,4);
1571
1572            case 1: /* MADU */
1573               if (RSREG != 0 && RTREG != 0)
1574               {
1575                  emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));            // mov  eax,[rsreg]
1576                  emit_mov_r32_m32(DRCTOP, REG_EDX, REGADDRLO(RTREG));            // mov  edx,[rtreg]
1577                  emit_mul_r32(DRCTOP, REG_EDX);                              // mul  edx
1578                  emit_add_r32_m32(DRCTOP, REG_EAX, LOADDRLO);                  // add  eax,[lo]
1579                  emit_adc_r32_m32(DRCTOP, REG_EDX, HIADDRLO);                  // adc  edx,[hi]
1580                  emit_mov_r32_r32(DRCTOP, REG_EBX, REG_EDX);                     // mov  ebx,edx
1581                  emit_cdq(DRCTOP);                                       // cdq
1582                  emit_mov_m64_r64(DRCTOP, LOADDR, REG_EDX, REG_EAX);               // mov  [lo],edx:eax
1583                  emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EBX);                     // mov  eax,ebx
1584                  emit_cdq(DRCTOP);                                       // cdq
1585                  emit_mov_m64_r64(DRCTOP, HIADDR, REG_EDX, REG_EAX);               // mov  [hi],edx:eax
1586               }
1587               return RECOMPILE_SUCCESSFUL_CP(3,4);
1588
1589            case 2: /* MUL */
1590               if (RDREG != 0)
1591               {
1592                  if (RSREG != 0 && RTREG != 0)
1593                  {
1594                     emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));         // mov  eax,[rsreg].lo
1595                     emit_imul_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));         // imul eax,[rtreg].lo
1596                     emit_cdq(DRCTOP);                                    // cdq
1597                     emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);      // mov  [rdreg],edx:eax
1598                  }
1599                  else
1600                     emit_zero_m64(DRCTOP, REGADDR(RDREG));                     // mov  [rdreg],0
1601               }
1602               return RECOMPILE_SUCCESSFUL_CP(3,4);
1603         }
1604         break;
1605
1606      case 0x20:   /* LB */
1607         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1608         emit_save_pc_before_call(DRCTOP);                                    // save pc
1609         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
1610         if (RSREG != 0 && SIMMVAL != 0)
1611         {
1612            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1613            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1614            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1615         }
1616         else if (RSREG != 0)
1617            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1618         else
1619            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1620         emit_call(DRCTOP, mips3.drcdata->read_and_translate_byte_signed);            // call read_and_translate_byte_signed
1621         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1622         if (RTREG != 0)
1623         {
1624            emit_cdq(DRCTOP);                                             // cdq
1625            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
1626         }
1627         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1628         return RECOMPILE_SUCCESSFUL_CP(1,4);
1629
1630      case 0x21:   /* LH */
1631         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1632         emit_save_pc_before_call(DRCTOP);                                    // save pc
1633         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
1634         if (RSREG != 0 && SIMMVAL != 0)
1635         {
1636            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1637            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1638            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1639         }
1640         else if (RSREG != 0)
1641            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1642         else
1643            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1644         emit_call(DRCTOP, mips3.drcdata->read_and_translate_half_signed);            // call read_and_translate_half_signed
1645         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1646         if (RTREG != 0)
1647         {
1648            emit_cdq(DRCTOP);                                             // cdq
1649            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
1650         }
1651         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1652         return RECOMPILE_SUCCESSFUL_CP(1,4);
1653
1654      case 0x22:   /* LWL */
1655         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1656         emit_save_pc_before_call(DRCTOP);                                    // save pc
1657         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
1658         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
1659         if (SIMMVAL)
1660            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1661         emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_EAX, 8, 0));                     // lea  ecx,[eax*8]
1662         emit_and_r32_imm(DRCTOP, REG_EAX, ~3);                                 // and  eax,~3
1663         emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                                 // mov  ebx,-1
1664         if (!mips3.core->bigendian)
1665            emit_xor_r32_imm(DRCTOP, REG_ECX, 0x18);                           // xor  ecx,0x18
1666         emit_shr_r32_cl(DRCTOP, REG_EBX);                                    // shr  ebx,cl
1667         emit_push_r32(DRCTOP, REG_ECX);                                       // push ecx
1668         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
1669         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
1670         emit_call(DRCTOP, mips3.drcdata->read_and_translate_word_masked);            // call read_and_translate_word_masked
1671         emit_add_r32_imm(DRCTOP, REG_ESP, 8);                                 // add  esp,8
1672         emit_pop_r32(DRCTOP, REG_ECX);                                       // pop  ecx
1673
1674         if (RTREG != 0)
1675         {
1676            emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                              // mov  ebx,-1
1677            emit_shl_r32_cl(DRCTOP, REG_EBX);                                 // shl  ebx,cl
1678            emit_not_r32(DRCTOP, REG_EBX);                                    // not  ebx
1679            emit_shl_r32_cl(DRCTOP, REG_EAX);                                 // shl  eax,cl
1680            emit_and_r32_m32(DRCTOP, REG_EBX, REGADDRLO(RTREG));                  // and  ebx,[rtreg].lo
1681            emit_or_r32_r32(DRCTOP, REG_EAX, REG_EBX);                           // or   eax,ebx
1682            emit_cdq(DRCTOP);                                             // cdq
1683            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
1684         }
1685         emit_add_r32_imm(DRCTOP, REG_ESP, 4);                                 // add  esp,4
1686         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1687         return RECOMPILE_SUCCESSFUL_CP(1,4);
1688
1689      case 0x23:   /* LW */
1690         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1691         emit_save_pc_before_call(DRCTOP);                                    // save pc
1692         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
1693         if (RSREG != 0 && SIMMVAL != 0)
1694         {
1695            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1696            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1697            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1698         }
1699         else if (RSREG != 0)
1700            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1701         else
1702            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1703         emit_call(DRCTOP, mips3.drcdata->read_and_translate_word);                  // call read_and_translate_word
1704         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1705         if (RTREG != 0)
1706         {
1707            emit_cdq(DRCTOP);                                             // cdq
1708            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
1709         }
1710         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1711         return RECOMPILE_SUCCESSFUL_CP(1,4);
1712
1713      case 0x24:   /* LBU */
1714         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1715         emit_save_pc_before_call(DRCTOP);                                    // save pc
1716         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
1717         if (RSREG != 0 && SIMMVAL != 0)
1718         {
1719            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1720            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1721            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1722         }
1723         else if (RSREG != 0)
1724            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1725         else
1726            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1727         emit_call(DRCTOP, mips3.drcdata->read_and_translate_byte_unsigned);            // call read_and_translate_byte_unsigned
1728         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1729         if (RTREG != 0)
1730         {
1731            emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                        // mov  [rtreg].hi,0
1732            emit_mov_m32_r32(DRCTOP, REGADDRLO(RTREG), REG_EAX);                  // mov  [rtreg].lo,eax
1733         }
1734         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1735         return RECOMPILE_SUCCESSFUL_CP(1,4);
1736
1737      case 0x25:   /* LHU */
1738         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1739         emit_save_pc_before_call(DRCTOP);                                    // save pc
1740         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
1741         if (RSREG != 0 && SIMMVAL != 0)
1742         {
1743            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1744            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1745            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1746         }
1747         else if (RSREG != 0)
1748            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1749         else
1750            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1751         emit_call(DRCTOP, mips3.drcdata->read_and_translate_half_unsigned);            // call read_and_translate_half_unsigned
1752         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1753         if (RTREG != 0)
1754         {
1755            emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                        // mov  [rtreg].hi,0
1756            emit_mov_m32_r32(DRCTOP, REGADDRLO(RTREG), REG_EAX);                  // mov  [rtreg].lo,eax
1757         }
1758         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1759         return RECOMPILE_SUCCESSFUL_CP(1,4);
1760
1761      case 0x26:   /* LWR */
1762         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1763         emit_save_pc_before_call(DRCTOP);                                    // save pc
1764         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
1765         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
1766         if (SIMMVAL)
1767            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1768         emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_EAX, 8, 0));                     // lea  ecx,[eax*8]
1769         emit_and_r32_imm(DRCTOP, REG_EAX, ~3);                                 // and  eax,~3
1770         emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                                 // mov  ebx,-1
1771         if (mips3.core->bigendian)
1772            emit_xor_r32_imm(DRCTOP, REG_ECX, 0x18);                           // xor  ecx,0x18
1773         emit_shl_r32_cl(DRCTOP, REG_EBX);                                    // shl  ebx,cl
1774         emit_push_r32(DRCTOP, REG_ECX);                                       // push ecx
1775         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
1776         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
1777         emit_call(DRCTOP, mips3.drcdata->read_and_translate_word_masked);            // call read_and_translate_word_masked
1778         emit_add_r32_imm(DRCTOP, REG_ESP, 8);                                 // add  esp,8
1779         emit_pop_r32(DRCTOP, REG_ECX);                                       // pop  ecx
1780
1781         if (RTREG != 0)
1782         {
1783            emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                              // mov  ebx,-1
1784            emit_shr_r32_cl(DRCTOP, REG_EBX);                                 // shr  ebx,cl
1785            emit_not_r32(DRCTOP, REG_EBX);                                    // not  ebx
1786            emit_shr_r32_cl(DRCTOP, REG_EAX);                                 // shr  eax,cl
1787            emit_and_r32_m32(DRCTOP, REG_EBX, REGADDRLO(RTREG));                  // and  ebx,[rtreg].lo
1788            emit_or_r32_r32(DRCTOP, REG_EAX, REG_EBX);                           // or   eax,ebx
1789            emit_cdq(DRCTOP);                                             // cdq
1790            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
1791         }
1792         emit_add_r32_imm(DRCTOP, REG_ESP, 4);                                 // add  esp,4
1793         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1794         return RECOMPILE_SUCCESSFUL_CP(1,4);
1795
1796      case 0x27:   /* LWU */
1797         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1798         emit_save_pc_before_call(DRCTOP);                                    // save pc
1799         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
1800         if (RSREG != 0 && SIMMVAL != 0)
1801         {
1802            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1803            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1804            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1805         }
1806         else if (RSREG != 0)
1807            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1808         else
1809            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1810         emit_call(DRCTOP, mips3.drcdata->read_and_translate_word);                  // call read_and_translate_word
1811         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1812         if (RTREG != 0)
1813         {
1814            emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                        // mov  [rtreg].hi,0
1815            emit_mov_m32_r32(DRCTOP, REGADDRLO(RTREG), REG_EAX);                  // mov  [rtreg].lo,eax
1816         }
1817         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1818         return RECOMPILE_SUCCESSFUL_CP(1,4);
1819
1820      case 0x28:   /* SB */
1821         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1822         emit_save_pc_before_call(DRCTOP);                                    // save pc
1823         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
1824         if (RTREG != 0)
1825            emit_push_m32(DRCTOP, REGADDRLO(RTREG));                           // push dword [rtreg].lo
1826         else
1827            emit_push_imm(DRCTOP, 0);                                       // push 0
1828         if (RSREG != 0 && SIMMVAL != 0)
1829         {
1830            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1831            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1832            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1833         }
1834         else if (RSREG != 0)
1835            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1836         else
1837            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1838         emit_call(DRCTOP, mips3.drcdata->write_and_translate_byte);                  // call writebyte
1839         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1840         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1841         return RECOMPILE_SUCCESSFUL_CP(1,4);
1842
1843      case 0x29:   /* SH */
1844         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1845         emit_save_pc_before_call(DRCTOP);                                    // save pc
1846         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
1847         if (RTREG != 0)
1848            emit_push_m32(DRCTOP, REGADDRLO(RTREG));                           // push dword [rtreg].lo
1849         else
1850            emit_push_imm(DRCTOP, 0);                                       // push 0
1851         if (RSREG != 0 && SIMMVAL != 0)
1852         {
1853            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1854            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1855            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1856         }
1857         else if (RSREG != 0)
1858            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1859         else
1860            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1861         emit_call(DRCTOP, mips3.drcdata->write_and_translate_half);                  // call writehalf
1862         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1863         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1864         return RECOMPILE_SUCCESSFUL_CP(1,4);
1865
1866      case 0x2a:   /* SWL */
1867         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1868         emit_save_pc_before_call(DRCTOP);                                    // save pc
1869         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
1870         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
1871         if (SIMMVAL)
1872            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1873         emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_EAX, 8, 0));                     // lea  ecx,[eax*8]
1874         emit_and_r32_imm(DRCTOP, REG_EAX, ~3);                                 // and  eax,~3
1875         emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                                 // mov  ebx,-1
1876         if (!mips3.core->bigendian)
1877            emit_xor_r32_imm(DRCTOP, REG_ECX, 0x18);                           // xor  ecx,0x18
1878         emit_shr_r32_cl(DRCTOP, REG_EBX);                                    // shr  ebx,cl
1879         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
1880         if (RTREG != 0)
1881         {
1882            emit_mov_r32_m32(DRCTOP, REG_EDX, REGADDRLO(RTREG));                  // mov  edx,[rtreg].lo
1883            emit_shr_r32_cl(DRCTOP, REG_EDX);                                 // shr  edx,cl
1884            emit_push_r32(DRCTOP, REG_EDX);                                    // push edx
1885         }
1886         else
1887            emit_push_imm(DRCTOP, 0);                                       // push 0
1888         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
1889         emit_call(DRCTOP, mips3.drcdata->write_and_translate_word_masked);            // call write_and_translate_word_masked
1890         emit_add_r32_imm(DRCTOP, REG_ESP, 16);                                 // add  esp,16
1891         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1892         return RECOMPILE_SUCCESSFUL_CP(1,4);
1893
1894      case 0x2b:   /* SW */
1895         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1896         emit_save_pc_before_call(DRCTOP);                                    // save pc
1897         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
1898         if (RTREG != 0)
1899            emit_push_m32(DRCTOP, REGADDRLO(RTREG));                           // push dword [rtreg].lo
1900         else
1901            emit_push_imm(DRCTOP, 0);                                       // push 0
1902         if (RSREG != 0 && SIMMVAL != 0)
1903         {
1904            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
1905            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1906            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
1907         }
1908         else if (RSREG != 0)
1909            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
1910         else
1911            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
1912         emit_call(DRCTOP, mips3.drcdata->write_and_translate_word);                  // call write_and_translate_word
1913         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
1914         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1915         return RECOMPILE_SUCCESSFUL_CP(1,4);
1916
1917      case 0x2c:   /* SDL */
1918         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1919         emit_save_pc_before_call(DRCTOP);                                    // save pc
1920         emit_sub_r32_imm(DRCTOP, REG_ESP, 12);                                 // sub  esp,12
1921         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
1922         if (SIMMVAL)
1923            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1924         emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_EAX, 4, 0));                     // lea  ecx,[eax*4]
1925         emit_and_r32_imm(DRCTOP, REG_EAX, ~7);                                 // and  eax,~7
1926         emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                                 // mov  ebx,-1
1927         emit_mov_r32_imm(DRCTOP, REG_EBP, -1);                                 // mov  ebp,-1
1928         if (!mips3.core->bigendian)
1929            emit_xor_r32_imm(DRCTOP, REG_ECX, 0x1c);                           // xor  ecx,0x1c
1930         emit_shr_r32_cl(DRCTOP, REG_EBP);                                    // shr  ebp,cl
1931         emit_shrd_r32_r32_cl(DRCTOP, REG_EBX, REG_EBP);                           // shrd ebx,ebp,cl
1932         emit_shr_r32_cl(DRCTOP, REG_EBP);                                    // shr  ebp,cl
1933         emit_push_r32(DRCTOP, REG_EBP);                                       // push ebp
1934         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
1935         if (RTREG != 0)
1936         {
1937            emit_mov_r32_m32(DRCTOP, REG_EBX, REGADDRLO(RTREG));                  // mov  ebx,[rtreg].lo
1938            emit_mov_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));                  // mov  edx,[rtreg].hi
1939            emit_shrd_r32_r32_cl(DRCTOP, REG_EBX, REG_EDX);                        // shrd ebx,edx,cl
1940            emit_shr_r32_cl(DRCTOP, REG_EDX);                                 // shr  edx,cl
1941            emit_shrd_r32_r32_cl(DRCTOP, REG_EBX, REG_EDX);                        // shrd ebx,edx,cl
1942            emit_shr_r32_cl(DRCTOP, REG_EDX);                                 // shr  edx,cl
1943            emit_push_r32(DRCTOP, REG_EDX);                                    // push edx
1944            emit_push_r32(DRCTOP, REG_EBX);                                    // push ebx
1945         }
1946         else
1947         {
1948            emit_push_imm(DRCTOP, 0);                                       // push 0
1949            emit_push_imm(DRCTOP, 0);                                       // push 0
1950         }
1951         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
1952         emit_call(DRCTOP, mips3.drcdata->write_and_translate_double_masked);         // call write_and_translate_double_masked
1953         emit_add_r32_imm(DRCTOP, REG_ESP, 32);                                 // add  esp,32
1954         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1955         return RECOMPILE_SUCCESSFUL_CP(1,4);
1956
1957      case 0x2d:   /* SDR */
1958         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1959         emit_save_pc_before_call(DRCTOP);                                    // save pc
1960         emit_sub_r32_imm(DRCTOP, REG_ESP, 12);                                 // sub  esp,12
1961         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
1962         if (SIMMVAL)
1963            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
1964         emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_EAX, 4, 0));                     // lea  ecx,[eax*4]
1965         emit_and_r32_imm(DRCTOP, REG_EAX, ~7);                                 // and  eax,~7
1966         emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                                 // mov  ebx,-1
1967         emit_mov_r32_imm(DRCTOP, REG_EBP, -1);                                 // mov  ebp,-1
1968         if (mips3.core->bigendian)
1969            emit_xor_r32_imm(DRCTOP, REG_ECX, 0x1c);                           // xor  ecx,0x1c
1970         emit_shl_r32_cl(DRCTOP, REG_EBX);                                    // shl  ebx,cl
1971         emit_shld_r32_r32_cl(DRCTOP, REG_EBP, REG_EBX);                           // shld ebp,ebx,cl
1972         emit_shl_r32_cl(DRCTOP, REG_EBX);                                    // shl  ebx,cl
1973         emit_push_r32(DRCTOP, REG_EBP);                                       // push ebp
1974         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
1975         if (RTREG != 0)
1976         {
1977            emit_mov_r32_m32(DRCTOP, REG_EBX, REGADDRLO(RTREG));                  // mov  ebx,[rtreg].lo
1978            emit_mov_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));                  // mov  edx,[rtreg].hi
1979            emit_shld_r32_r32_cl(DRCTOP, REG_EDX, REG_EBX);                        // shld edx,ebx,cl
1980            emit_shl_r32_cl(DRCTOP, REG_EBX);                                 // shl  ebx,cl
1981            emit_shld_r32_r32_cl(DRCTOP, REG_EDX, REG_EBX);                        // shld edx,ebx,cl
1982            emit_shl_r32_cl(DRCTOP, REG_EBX);                                 // shl  ebx,cl
1983            emit_push_r32(DRCTOP, REG_EDX);                                    // push edx
1984            emit_push_r32(DRCTOP, REG_EBX);                                    // push ebx
1985         }
1986         else
1987         {
1988            emit_push_imm(DRCTOP, 0);                                       // push 0
1989            emit_push_imm(DRCTOP, 0);                                       // push 0
1990         }
1991         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
1992         emit_call(DRCTOP, mips3.drcdata->write_and_translate_double_masked);         // call write_and_translate_double_masked
1993         emit_add_r32_imm(DRCTOP, REG_ESP, 32);                                 // add  esp,32
1994         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
1995         return RECOMPILE_SUCCESSFUL_CP(1,4);
1996
1997      case 0x2e:   /* SWR */
1998         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
1999         emit_save_pc_before_call(DRCTOP);                                    // save pc
2000         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
2001         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
2002         if (SIMMVAL)
2003            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2004         emit_lea_r32_m32(DRCTOP, REG_ECX, MISD(REG_EAX, 8, 0));                     // lea  ecx,[eax*8]
2005         emit_and_r32_imm(DRCTOP, REG_EAX, ~3);                                 // and  eax,~3
2006         emit_mov_r32_imm(DRCTOP, REG_EBX, -1);                                 // mov  ebx,-1
2007         if (mips3.core->bigendian)
2008            emit_xor_r32_imm(DRCTOP, REG_ECX, 0x18);                           // xor  ecx,0x18
2009         emit_shl_r32_cl(DRCTOP, REG_EBX);                                    // shl  ebx,cl
2010         emit_push_r32(DRCTOP, REG_EBX);                                       // push ebx
2011         if (RTREG != 0)
2012         {
2013            emit_mov_r32_m32(DRCTOP, REG_EDX, REGADDRLO(RTREG));                  // mov  edx,[rtreg].lo
2014            emit_shl_r32_cl(DRCTOP, REG_EDX);                                 // shl  edx,cl
2015            emit_push_r32(DRCTOP, REG_EDX);                                    // push edx
2016         }
2017         else
2018            emit_push_imm(DRCTOP, 0);                                       // push 0
2019         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
2020         emit_call(DRCTOP, mips3.drcdata->write_and_translate_word_masked);            // call write_and_translate_word_masked
2021         emit_add_r32_imm(DRCTOP, REG_ESP, 16);                                 // add  esp,16
2022         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2023         return RECOMPILE_SUCCESSFUL_CP(1,4);
2024
2025      case 0x2f:   /* CACHE */
2026         return RECOMPILE_SUCCESSFUL_CP(1,4);
2027
2028//      case 0x30:  /* LL */        logerror("mips3 Unhandled op: LL\n");                                   break;
2029
2030      case 0x31:   /* LWC1 */
2031         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2032         emit_save_pc_before_call(DRCTOP);                                    // save pc
2033         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
2034         if (RSREG != 0 && SIMMVAL != 0)
2035         {
2036            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].los
2037            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2038            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2039         }
2040         else if (RSREG != 0)
2041            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2042         else
2043            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2044         emit_call(DRCTOP, mips3.drcdata->read_and_translate_word);                  // call read_and_translate_word
2045         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2046         emit_mov_m32_r32(DRCTOP, FPR32ADDR(RTREG), REG_EAX);                     // mov  [rtreg],eax
2047         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2048         return RECOMPILE_SUCCESSFUL_CP(1,4);
2049
2050      case 0x32:   /* LWC2 */
2051         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2052         emit_save_pc_before_call(DRCTOP);                                    // save pc
2053         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
2054         if (RSREG != 0 && SIMMVAL != 0)
2055         {
2056            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2057            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2058            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2059         }
2060         else if (RSREG != 0)
2061            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2062         else
2063            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2064         emit_call(DRCTOP, mips3.drcdata->read_and_translate_word);                  // call read_and_translate_word
2065         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2066         emit_mov_m32_r32(DRCTOP, CPR2ADDR(RTREG), REG_EAX);                        // mov  [rtreg],eax
2067         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2068         return RECOMPILE_SUCCESSFUL_CP(1,4);
2069
2070      case 0x33:   /* PREF */
2071         if (mips3.core->flavor >= MIPS3_TYPE_MIPS_IV)
2072            return RECOMPILE_SUCCESSFUL_CP(1,4);
2073         else
2074         {
2075            emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);      // jmp  generate_invalidop_exception
2076            return RECOMPILE_SUCCESSFUL | RECOMPILE_MAY_CAUSE_EXCEPTION | RECOMPILE_END_OF_STRING;
2077         }
2078
2079//      case 0x34:  /* LLD */       logerror("mips3 Unhandled op: LLD\n");                                  break;
2080
2081      case 0x35:   /* LDC1 */
2082         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2083         emit_save_pc_before_call(DRCTOP);                                    // save pc
2084         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
2085         if (RSREG != 0 && SIMMVAL != 0)
2086         {
2087            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2088            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2089            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2090         }
2091         else if (RSREG != 0)
2092            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2093         else
2094            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2095         emit_call(DRCTOP, mips3.drcdata->read_and_translate_double);               // call read_and_translate_double
2096         emit_mov_m64_r64(DRCTOP, FPR64ADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
2097         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2098         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2099         return RECOMPILE_SUCCESSFUL_CP(1,4);
2100
2101      case 0x36:   /* LDC2 */
2102         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2103         emit_save_pc_before_call(DRCTOP);                                    // save pc
2104         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
2105         if (RSREG != 0 && SIMMVAL != 0)
2106         {
2107            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2108            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2109            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2110         }
2111         else if (RSREG != 0)
2112            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2113         else
2114            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2115         emit_call(DRCTOP, mips3.drcdata->read_and_translate_double);               // call read_and_translate_word
2116         emit_mov_m64_r64(DRCTOP, CPR2ADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
2117         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2118         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2119         return RECOMPILE_SUCCESSFUL_CP(1,4);
2120
2121      case 0x37:   /* LD */
2122         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2123         emit_save_pc_before_call(DRCTOP);                                    // save pc
2124         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
2125         if (RSREG != 0 && SIMMVAL != 0)
2126         {
2127            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2128            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2129            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2130         }
2131         else if (RSREG != 0)
2132            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2133         else
2134            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2135         emit_call(DRCTOP, mips3.drcdata->read_and_translate_double);               // call read_and_translate_double
2136         if (RTREG != 0)
2137            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
2138         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2139         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2140         return RECOMPILE_SUCCESSFUL_CP(1,4);
2141
2142//      case 0x38:  /* SC */        logerror("mips3 Unhandled op: SC\n");                                   break;
2143
2144      case 0x39:   /* SWC1 */
2145         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2146         emit_save_pc_before_call(DRCTOP);                                    // save pc
2147         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
2148         emit_push_m32(DRCTOP, FPR32ADDR(RTREG));                              // push dword [rtreg]
2149         if (RSREG != 0 && SIMMVAL != 0)
2150         {
2151            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2152            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2153            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2154         }
2155         else if (RSREG != 0)
2156            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2157         else
2158            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2159         emit_call(DRCTOP, mips3.drcdata->write_and_translate_word);                  // call write_and_translate_word
2160         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2161         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2162         return RECOMPILE_SUCCESSFUL_CP(1,4);
2163
2164      case 0x3a:   /* SWC2 */
2165         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2166         emit_save_pc_before_call(DRCTOP);                                    // save pc
2167         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
2168         emit_push_m32(DRCTOP, CPR2ADDR(RTREG));                                 // push dword [rtreg]
2169         if (RSREG != 0 && SIMMVAL != 0)
2170         {
2171            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2172            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2173            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2174         }
2175         else if (RSREG != 0)
2176            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2177         else
2178            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2179         emit_call(DRCTOP, mips3.drcdata->write_and_translate_word);                  // call write_and_translate_word
2180         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2181         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2182         return RECOMPILE_SUCCESSFUL_CP(1,4);
2183
2184//      case 0x3b:  /* SWC3 */      invalid_instruction(op);                                                break;
2185//      case 0x3c:  /* SCD */       logerror("mips3 Unhandled op: SCD\n");                                  break;
2186
2187      case 0x3d:   /* SDC1 */
2188         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2189         emit_save_pc_before_call(DRCTOP);                                    // save pc
2190         emit_push_m32(DRCTOP, FPR64ADDRHI(RTREG));                              // push dword [rtreg].hi
2191         emit_push_m32(DRCTOP, FPR64ADDRLO(RTREG));                              // push dword [rtreg].lo
2192         if (RSREG != 0 && SIMMVAL != 0)
2193         {
2194            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2195            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2196            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2197         }
2198         else if (RSREG != 0)
2199            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2200         else
2201            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2202         emit_call(DRCTOP, mips3.drcdata->write_and_translate_double);               // call write_and_translate_double
2203         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2204         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2205         return RECOMPILE_SUCCESSFUL_CP(1,4);
2206
2207      case 0x3e:   /* SDC2 */
2208         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2209         emit_save_pc_before_call(DRCTOP);                                    // save pc
2210         emit_push_m32(DRCTOP, CPR2ADDRHI(RTREG));                              // push dword [rtreg].hi
2211         emit_push_m32(DRCTOP, CPR2ADDRLO(RTREG));                              // push dword [rtreg].lo
2212         if (RSREG != 0 && SIMMVAL != 0)
2213         {
2214            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2215            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2216            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2217         }
2218         else if (RSREG != 0)
2219            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2220         else
2221            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2222         emit_call(DRCTOP, mips3.drcdata->write_and_translate_double);               // call write_and_translate_double
2223         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2224         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2225         return RECOMPILE_SUCCESSFUL_CP(1,4);
2226
2227      case 0x3f:   /* SD */
2228         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
2229         emit_save_pc_before_call(DRCTOP);                                    // save pc
2230         if (RTREG != 0)
2231         {
2232            emit_push_m32(DRCTOP, REGADDRHI(RTREG));                           // push   dword [rtreg].hi
2233            emit_push_m32(DRCTOP, REGADDRLO(RTREG));                           // push   dword [rtreg].lo
2234         }
2235         else
2236         {
2237            emit_push_imm(DRCTOP, 0);                                       // push 0
2238            emit_push_imm(DRCTOP, 0);                                       // push 0
2239         }
2240         if (RSREG != 0 && SIMMVAL != 0)
2241         {
2242            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2243            emit_add_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // add  eax,SIMMVAL
2244            emit_push_r32(DRCTOP, REG_EAX);                                    // push eax
2245         }
2246         else if (RSREG != 0)
2247            emit_push_m32(DRCTOP, REGADDRLO(RSREG));                           // push [rsreg].lo
2248         else
2249            emit_push_imm(DRCTOP, SIMMVAL);                                    // push SIMMVAL
2250         emit_call(DRCTOP, mips3.drcdata->write_and_translate_double);               // call write_and_translate_double
2251         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2252         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
2253         return RECOMPILE_SUCCESSFUL_CP(1,4);
2254
2255//      default:    /* ??? */       invalid_instruction(op);                                                break;
2256   }
2257   return RECOMPILE_UNIMPLEMENTED;
2258}
2259
2260
2261/*------------------------------------------------------------------
2262    recompile_special
2263------------------------------------------------------------------*/
2264
2265static UINT32 recompile_special1(drc_core *drc, UINT32 pc, UINT32 op)
2266{
2267   emit_link link1, link2, link3;
2268   int cycles;
2269
2270   switch (op & 63)
2271   {
2272      case 0x00:   /* SLL */
2273         if (RDREG != 0)
2274         {
2275            if (RTREG != 0)
2276            {
2277               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2278               if (SHIFT != 0)
2279                  emit_shl_r32_imm(DRCTOP, REG_EAX, SHIFT);                     // shl  eax,SHIFT
2280               emit_cdq(DRCTOP);                                          // cdq
2281               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2282            }
2283            else
2284               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2285         }
2286         return RECOMPILE_SUCCESSFUL_CP(1,4);
2287
2288      case 0x01:   /* MOVF - R5000*/
2289         if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
2290         {
2291            emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);      // jmp  generate_invalidop_exception
2292            return RECOMPILE_SUCCESSFUL | RECOMPILE_MAY_CAUSE_EXCEPTION | RECOMPILE_END_OF_STRING;
2293         }
2294         emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);                     // cmp  [cf[x]],0
2295         emit_jcc_short_link(DRCTOP, ((op >> 16) & 1) ? COND_Z : COND_NZ, &link1);      // jz/nz skip
2296         emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));                  // mov  edx:eax,[rsreg]
2297         emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);                  // mov  [rdreg],edx:eax
2298         resolve_link(DRCTOP, &link1);                                    // skip:
2299         return RECOMPILE_SUCCESSFUL_CP(1,4);
2300
2301      case 0x02:   /* SRL */
2302         if (RDREG != 0)
2303         {
2304            if (RTREG != 0)
2305            {
2306               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2307               if (SHIFT != 0)
2308                  emit_shr_r32_imm(DRCTOP, REG_EAX, SHIFT);                     // shr  eax,SHIFT
2309               emit_cdq(DRCTOP);                                          // cdq
2310               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2311            }
2312            else
2313               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2314         }
2315         return RECOMPILE_SUCCESSFUL_CP(1,4);
2316
2317      case 0x03:   /* SRA */
2318         if (RDREG != 0)
2319         {
2320            if (RTREG != 0)
2321            {
2322               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2323               if (SHIFT != 0)
2324                  emit_sar_r32_imm(DRCTOP, REG_EAX, SHIFT);                     // sar  eax,SHIFT
2325               emit_cdq(DRCTOP);                                          // cdq
2326               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2327            }
2328            else
2329               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2330         }
2331         return RECOMPILE_SUCCESSFUL_CP(1,4);
2332
2333      case 0x04:   /* SLLV */
2334         if (RDREG != 0)
2335         {
2336            if (RTREG != 0)
2337            {
2338               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2339               if (RSREG != 0)
2340               {
2341                  emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RSREG));            // mov  ecx,[rsreg].lo
2342                  emit_shl_r32_cl(DRCTOP, REG_EAX);                           // shl  eax,cl
2343               }
2344               emit_cdq(DRCTOP);                                          // cdq
2345               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2346            }
2347            else
2348               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2349         }
2350         return RECOMPILE_SUCCESSFUL_CP(1,4);
2351
2352      case 0x06:   /* SRLV */
2353         if (RDREG != 0)
2354         {
2355            if (RTREG != 0)
2356            {
2357               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2358               if (RSREG != 0)
2359               {
2360                  emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RSREG));            // mov  ecx,[rsreg].lo
2361                  emit_shr_r32_cl(DRCTOP, REG_EAX);                           // shr  eax,cl
2362               }
2363               emit_cdq(DRCTOP);                                          // cdq
2364               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2365            }
2366            else
2367               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2368         }
2369         return RECOMPILE_SUCCESSFUL_CP(1,4);
2370
2371      case 0x07:   /* SRAV */
2372         if (RDREG != 0)
2373         {
2374            if (RTREG != 0)
2375            {
2376               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2377               if (RSREG != 0)
2378               {
2379                  emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RSREG));            // mov  ecx,[rsreg].lo
2380                  emit_sar_r32_cl(DRCTOP, REG_EAX);                           // sar  eax,cl
2381               }
2382               emit_cdq(DRCTOP);                                          // cdq
2383               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2384            }
2385            else
2386               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2387         }
2388         return RECOMPILE_SUCCESSFUL_CP(1,4);
2389
2390      case 0x08:   /* JR */
2391         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
2392         emit_mov_m32_r32(DRCTOP, MABS(&jr_temp), REG_EAX);                        // mov  jr_temp,eax
2393         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
2394         emit_mov_r32_m32(DRCTOP, REG_EDI, MABS(&jr_temp));                        // mov  edi,jr_temp
2395         return RECOMPILE_SUCCESSFUL_CP(1+cycles,0) | RECOMPILE_END_OF_STRING | RECOMPILE_ADD_DISPATCH;
2396
2397      case 0x09:   /* JALR */
2398         if (RDREG != 0)
2399            emit_mov_m64_imm32(DRCTOP, REGADDR(RDREG), pc + 8);                     // mov  [rdreg],pc + 8
2400         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
2401         emit_mov_r32_m32(DRCTOP, REG_EDI, REGADDRLO(RSREG));                     // mov  edi,[rsreg].lo
2402         return RECOMPILE_SUCCESSFUL_CP(1+cycles,0) | RECOMPILE_END_OF_STRING | RECOMPILE_ADD_DISPATCH;
2403
2404      case 0x0a:   /* MOVZ - R5000 */
2405         if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
2406         {
2407            emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);      // jmp  generate_invalidop_exception
2408            return RECOMPILE_SUCCESSFUL | RECOMPILE_MAY_CAUSE_EXCEPTION | RECOMPILE_END_OF_STRING;
2409         }
2410         if (RDREG != 0)
2411         {
2412            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[rtreg].lo
2413            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // or   eax,[rtreg].hi
2414            emit_jcc_short_link(DRCTOP, COND_NZ, &link1);                        // jnz  skip
2415            emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RSREG));
2416                                                                     // mov  [rdreg],[rsreg]
2417            resolve_link(DRCTOP, &link1);                                 // skip:
2418         }
2419         return RECOMPILE_SUCCESSFUL_CP(1,4);
2420
2421      case 0x0b:   /* MOVN - R5000 */
2422         if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
2423         {
2424            emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);      // jmp  generate_invalidop_exception
2425            return RECOMPILE_SUCCESSFUL | RECOMPILE_MAY_CAUSE_EXCEPTION | RECOMPILE_END_OF_STRING;
2426         }
2427         if (RDREG != 0)
2428         {
2429            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[rtreg].lo
2430            emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // or   eax,[rtreg].hi
2431            emit_jcc_short_link(DRCTOP, COND_Z, &link1);                        // jz   skip
2432            emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RSREG));
2433                                                                     // mov  [rdreg],[rsreg]
2434            resolve_link(DRCTOP, &link1);                                 // skip:
2435         }
2436         return RECOMPILE_SUCCESSFUL_CP(1,4);
2437
2438      case 0x0c:   /* SYSCALL */
2439         emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_syscall_exception);         // jmp  generate_syscall_exception
2440         return RECOMPILE_SUCCESSFUL | RECOMPILE_MAY_CAUSE_EXCEPTION | RECOMPILE_END_OF_STRING;
2441
2442      case 0x0d:   /* BREAK */
2443         emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_break_exception);            // jmp  generate_break_exception
2444         return RECOMPILE_SUCCESSFUL | RECOMPILE_MAY_CAUSE_EXCEPTION | RECOMPILE_END_OF_STRING;
2445
2446      case 0x0f:   /* SYNC */
2447         return RECOMPILE_SUCCESSFUL_CP(1,4);
2448
2449      case 0x10:   /* MFHI */
2450         if (RDREG != 0)
2451            emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), HIADDR);                     // mov  [rdreg],[hi]
2452         return RECOMPILE_SUCCESSFUL_CP(1,4);
2453
2454      case 0x11:   /* MTHI */
2455         emit_mov_m64_m64(DRCTOP, HIADDR, REGADDR(RSREG));                        // mov  [hi],[rsreg]
2456         return RECOMPILE_SUCCESSFUL_CP(1,4);
2457
2458      case 0x12:   /* MFLO */
2459         if (RDREG != 0)
2460            emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), LOADDR);                     // mov  [rdreg],[lo]
2461         return RECOMPILE_SUCCESSFUL_CP(1,4);
2462
2463      case 0x13:   /* MTLO */
2464         emit_mov_m64_m64(DRCTOP, LOADDR, REGADDR(RSREG));                        // mov  [lo],[rsreg]
2465         return RECOMPILE_SUCCESSFUL_CP(1,4);
2466
2467      case 0x14:   /* DSLLV */
2468         if (RDREG != 0)
2469         {
2470            if (RTREG != 0)
2471            {
2472               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RTREG));            // mov  edx:eax,[rtreg]
2473               if (RSREG != 0)
2474               {
2475                  emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RSREG));            // mov  ecx,[rsreg].lo
2476                  emit_test_r32_imm(DRCTOP, REG_ECX, 0x20);                     // test ecx,0x20
2477                  emit_jcc_short_link(DRCTOP, COND_Z, &link1);                  // jz   skip
2478                  emit_mov_r32_r32(DRCTOP, REG_EDX, REG_EAX);                     // mov  edx,eax
2479                  emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                     // xor  eax,eax
2480                  resolve_link(DRCTOP, &link1);                           // skip:
2481                  emit_shld_r32_r32_cl(DRCTOP, REG_EDX, REG_EAX);                  // shld edx,eax,cl
2482                  emit_shl_r32_cl(DRCTOP, REG_EAX);                           // shl  eax,cl
2483               }
2484               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2485            }
2486            else
2487               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2488         }
2489         return RECOMPILE_SUCCESSFUL_CP(1,4);
2490
2491      case 0x16:   /* DSRLV */
2492         if (RDREG != 0)
2493         {
2494            if (RTREG != 0)
2495            {
2496               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RTREG));            // mov  edx:eax,[rtreg]
2497               if (RSREG != 0)
2498               {
2499                  emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RSREG));            // mov  ecx,[rsreg].lo
2500                  emit_test_r32_imm(DRCTOP, REG_ECX, 0x20);                     // test ecx,0x20
2501                  emit_jcc_short_link(DRCTOP, COND_Z, &link1);                  // jz   skip
2502                  emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EDX);                     // mov  eax,edx
2503                  emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                     // xor  edx,edx
2504                  resolve_link(DRCTOP, &link1);                           // skip:
2505                  emit_shrd_r32_r32_cl(DRCTOP, REG_EAX, REG_EDX);                  // shrd eax,edx,cl
2506                  emit_shr_r32_cl(DRCTOP, REG_EDX);                           // shr  edx,cl
2507               }
2508               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2509            }
2510            else
2511               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2512         }
2513         return RECOMPILE_SUCCESSFUL_CP(1,4);
2514
2515      case 0x17:   /* DSRAV */
2516         if (RDREG != 0)
2517         {
2518            if (RTREG != 0)
2519            {
2520               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RTREG));            // mov  edx:eax,[rtreg]
2521               if (RSREG != 0)
2522               {
2523                  emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RSREG));            // mov  ecx,[rsreg].lo
2524                  emit_test_r32_imm(DRCTOP, REG_ECX, 0x20);                     // test ecx,0x20
2525                  emit_jcc_short_link(DRCTOP, COND_Z, &link1);                  // jz   skip
2526                  emit_mov_r32_r32(DRCTOP, REG_EAX, REG_EDX);                     // mov  eax,edx
2527                  emit_cdq(DRCTOP);                                       // cdq
2528                  resolve_link(DRCTOP, &link1);                           // skip:
2529                  emit_shrd_r32_r32_cl(DRCTOP, REG_EAX, REG_EDX);                  // shrd eax,edx,cl
2530                  emit_sar_r32_cl(DRCTOP, REG_EDX);                           // sar  edx,cl
2531               }
2532               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2533            }
2534            else
2535               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2536         }
2537         return RECOMPILE_SUCCESSFUL_CP(1,4);
2538
2539      case 0x18:   /* MULT */
2540         emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RTREG));                     // mov  ecx,[rtreg].lo
2541         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
2542         emit_imul_r32(DRCTOP, REG_ECX);                                       // imul ecx
2543         emit_push_r32(DRCTOP, REG_EDX);                                       // push edx
2544         emit_cdq(DRCTOP);                                                // cdq
2545         emit_mov_m64_r64(DRCTOP, LOADDR, REG_EDX, REG_EAX);                        // mov  [lo],edx:eax
2546         emit_pop_r32(DRCTOP, REG_EAX);                                       // pop  eax
2547         emit_cdq(DRCTOP);                                                // cdq
2548         emit_mov_m64_r64(DRCTOP, HIADDR, REG_EDX, REG_EAX);                        // mov  [hi],edx:eax
2549         return RECOMPILE_SUCCESSFUL_CP(4,4);
2550
2551      case 0x19:   /* MULTU */
2552         emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RTREG));                     // mov  ecx,[rtreg].lo
2553         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
2554         emit_mul_r32(DRCTOP, REG_ECX);                                       // mul  ecx
2555         emit_push_r32(DRCTOP, REG_EDX);                                       // push edx
2556         emit_cdq(DRCTOP);                                                // cdq
2557         emit_mov_m64_r64(DRCTOP, LOADDR, REG_EDX, REG_EAX);                        // mov  [lo],edx:eax
2558         emit_pop_r32(DRCTOP, REG_EAX);                                       // pop  eax
2559         emit_cdq(DRCTOP);                                                // cdq
2560         emit_mov_m64_r64(DRCTOP, HIADDR, REG_EDX, REG_EAX);                        // mov  [hi],edx:eax
2561         return RECOMPILE_SUCCESSFUL_CP(4,4);
2562
2563      case 0x1a:   /* DIV */
2564         if (RTREG != 0)
2565         {
2566            emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RTREG));                  // mov  ecx,[rtreg].lo
2567            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2568            emit_cdq(DRCTOP);                                             // cdq
2569            emit_cmp_r32_imm(DRCTOP, REG_ECX, 0);                              // cmp  ecx,0
2570            emit_jcc_short_link(DRCTOP, COND_E, &link1);                        // je   skip
2571            emit_idiv_r32(DRCTOP, REG_ECX);                                    // idiv ecx
2572            emit_push_r32(DRCTOP, REG_EDX);                                    // push edx
2573            emit_cdq(DRCTOP);                                             // cdq
2574            emit_mov_m64_r64(DRCTOP, LOADDR, REG_EDX, REG_EAX);                     // mov  [lo],edx:eax
2575            emit_pop_r32(DRCTOP, REG_EAX);                                    // pop  eax
2576            emit_cdq(DRCTOP);                                             // cdq
2577            emit_mov_m64_r64(DRCTOP, HIADDR, REG_EDX, REG_EAX);                     // mov  [hi],edx:eax
2578            resolve_link(DRCTOP, &link1);                                 // skip:
2579         }
2580         return RECOMPILE_SUCCESSFUL_CP(36,4);
2581
2582      case 0x1b:   /* DIVU */
2583         if (RTREG != 0)
2584         {
2585            emit_mov_r32_m32(DRCTOP, REG_ECX, REGADDRLO(RTREG));                  // mov  ecx,[rtreg].lo
2586            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2587            emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                           // xor  edx,edx
2588            emit_cmp_r32_imm(DRCTOP, REG_ECX, 0);                              // cmp  ecx,0
2589            emit_jcc_short_link(DRCTOP, COND_E, &link1);                        // je   skip
2590            emit_div_r32(DRCTOP, REG_ECX);                                    // div  ecx
2591            emit_push_r32(DRCTOP, REG_EDX);                                    // push edx
2592            emit_cdq(DRCTOP);                                             // cdq
2593            emit_mov_m64_r64(DRCTOP, LOADDR, REG_EDX, REG_EAX);                     // mov  [lo],edx:eax
2594            emit_pop_r32(DRCTOP, REG_EAX);                                    // pop  eax
2595            emit_cdq(DRCTOP);                                             // cdq
2596            emit_mov_m64_r64(DRCTOP, HIADDR, REG_EDX, REG_EAX);                     // mov  [hi],edx:eax
2597            resolve_link(DRCTOP, &link1);                                 // skip:
2598         }
2599         return RECOMPILE_SUCCESSFUL_CP(36,4);
2600
2601      case 0x1c:   /* DMULT */
2602         emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));                  // mov  edx:eax,[rsreg]
2603         emit_cmp_r32_imm(DRCTOP, REG_EDX, 0);                                 // cmp  edx,0
2604         emit_jcc_short_link(DRCTOP, COND_GE, &link1);                           // jge  skip1
2605         emit_mov_r32_r32(DRCTOP, REG_ECX, REG_EDX);                              // mov  ecx,edx
2606         emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                              // xor  edx,edx
2607         emit_neg_r32(DRCTOP, REG_EAX);                                       // neg  eax
2608         emit_sbb_r32_r32(DRCTOP, REG_EDX, REG_ECX);                              // sbb  edx,ecx
2609         resolve_link(DRCTOP, &link1);                                    // skip1:
2610         emit_mov_m64_r64(DRCTOP, MABS(&dmult_temp1), REG_EDX, REG_EAX);               // mov  [dmult_temp1],edx:eax
2611
2612         emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RTREG));                  // mov  edx:eax,[rtreg]
2613         emit_cmp_r32_imm(DRCTOP, REG_EDX, 0);                                 // cmp  edx,0
2614         emit_jcc_short_link(DRCTOP, COND_GE, &link2);                           // jge  skip2
2615         emit_mov_r32_r32(DRCTOP, REG_ECX, REG_EDX);                              // mov  ecx,edx
2616         emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                              // xor  edx,edx
2617         emit_neg_r32(DRCTOP, REG_EAX);                                       // neg  eax
2618         emit_sbb_r32_r32(DRCTOP, REG_EDX, REG_ECX);                              // sbb  edx,ecx
2619         resolve_link(DRCTOP, &link2);                                    // skip2:
2620         emit_mov_m64_r64(DRCTOP, MABS(&dmult_temp2), REG_EDX, REG_EAX);               // mov  [dmult_temp2],edx:eax
2621
2622         emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(LO(&dmult_temp1)));                  // mov  eax,[dmult_temp1].lo
2623         emit_mul_m32(DRCTOP, MABS(LO(&dmult_temp2)));                           // mul  [dmult_temp2].lo
2624         emit_mov_r32_r32(DRCTOP, REG_ECX, REG_EDX);                              // mov  ecx,edx
2625         emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX);                              // xor  ebx,ebx
2626         emit_mov_m32_r32(DRCTOP, LOADDRLO, REG_EAX);                           // mov  [lo].lo,eax
2627
2628         emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(HI(&dmult_temp1)));                  // mov  eax,[dmult_temp1].hi
2629         emit_mul_m32(DRCTOP, MABS(LO(&dmult_temp2)));                           // mul  [dmult_temp2].lo
2630         emit_add_r32_r32(DRCTOP, REG_ECX, REG_EAX);                              // add  ecx,eax
2631         emit_adc_r32_r32(DRCTOP, REG_EBX, REG_EDX);                              // adc  ebx,edx
2632
2633         emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(LO(&dmult_temp1)));                  // mov  eax,[dmult_temp1].lo
2634         emit_mul_m32(DRCTOP, MABS(HI(&dmult_temp2)));                           // mul  [dmult_temp2].hi
2635         emit_add_r32_r32(DRCTOP, REG_ECX, REG_EAX);                              // add  ecx,eax
2636         emit_adc_r32_r32(DRCTOP, REG_EBX, REG_EDX);                              // adc  ebx,edx
2637         emit_mov_m32_r32(DRCTOP, LOADDRHI, REG_ECX);                           // mov  [lo].hi,ecx
2638
2639         emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(HI(&dmult_temp1)));                  // mov  eax,[dmult_temp1].hi
2640         emit_mul_m32(DRCTOP, MABS(HI(&dmult_temp2)));                           // mul  [dmult_temp2].hi
2641         emit_add_r32_r32(DRCTOP, REG_EBX, REG_EAX);                              // add  ebx,eax
2642         emit_adc_r32_imm(DRCTOP, REG_EDX, 0);                                 // adc  edx,0
2643         emit_mov_m32_r32(DRCTOP, HIADDRLO, REG_EBX);                           // mov  [hi].lo,ebx
2644         emit_mov_m32_r32(DRCTOP, HIADDRHI, REG_EDX);                           // mov  [hi].hi,edx
2645
2646         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // mov  eax,[rsreg].hi
2647         emit_xor_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // xor  eax,[rtreg].hi
2648         emit_jcc_short_link(DRCTOP, COND_NS, &link3);                           // jns  noflip
2649         emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                              // xor  eax,eax
2650         emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX);                              // xor  ebx,ebx
2651         emit_xor_r32_r32(DRCTOP, REG_ECX, REG_ECX);                              // xor  ecx,ecx
2652         emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                              // xor  edx,edx
2653         emit_sub_r32_m32(DRCTOP, REG_EAX, LOADDRLO);                           // sub  eax,[lo].lo
2654         emit_sbb_r32_m32(DRCTOP, REG_EBX, LOADDRHI);                           // sbb  ebx,[lo].hi
2655         emit_sbb_r32_m32(DRCTOP, REG_ECX, HIADDRLO);                           // sbb  ecx,[hi].lo
2656         emit_sbb_r32_m32(DRCTOP, REG_EDX, HIADDRHI);                           // sbb  edx,[hi].hi
2657         emit_mov_m64_r64(DRCTOP, LOADDR, REG_EBX, REG_EAX);                        // mov  [lo],ebx:eax
2658         emit_mov_m64_r64(DRCTOP, HIADDR, REG_EDX, REG_ECX);                        // mov  [hi],edx:ecx
2659         resolve_link(DRCTOP, &link3);                                    // noflip:
2660         return RECOMPILE_SUCCESSFUL_CP(8,4);
2661
2662      case 0x1d:   /* DMULTU */
2663         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
2664         emit_mul_m32(DRCTOP, REGADDRLO(RTREG));                                 // mul  [rtreg].lo
2665         emit_mov_r32_r32(DRCTOP, REG_ECX, REG_EDX);                              // mov  ecx,edx
2666         emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX);                              // xor  ebx,ebx
2667         emit_mov_m32_r32(DRCTOP, LOADDRLO, REG_EAX);                           // mov  [lo].lo,eax
2668
2669         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // mov  eax,[rsreg].hi
2670         emit_mul_m32(DRCTOP, REGADDRLO(RTREG));                                 // mul  [rtreg].lo
2671         emit_add_r32_r32(DRCTOP, REG_ECX, REG_EAX);                              // add  ecx,eax
2672         emit_adc_r32_r32(DRCTOP, REG_EBX, REG_EDX);                              // adc  ebx,edx
2673
2674         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
2675         emit_mul_m32(DRCTOP, REGADDRHI(RTREG));                                 // mul  [rtreg].hi
2676         emit_add_r32_r32(DRCTOP, REG_ECX, REG_EAX);                              // add  ecx,eax
2677         emit_adc_r32_r32(DRCTOP, REG_EBX, REG_EDX);                              // adc  ebx,edx
2678         emit_mov_m32_r32(DRCTOP, LOADDRHI, REG_ECX);                           // mov  [lo].hi,ecx
2679
2680         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // mov  eax,[rsreg].hi
2681         emit_mul_m32(DRCTOP, REGADDRHI(RTREG));                                 // mul  [rtreg].hi
2682         emit_add_r32_r32(DRCTOP, REG_EBX, REG_EAX);                              // add  ebx,eax
2683         emit_adc_r32_imm(DRCTOP, REG_EDX, 0);                                 // adc  edx,0
2684         emit_mov_m32_r32(DRCTOP, HIADDRLO, REG_EBX);                           // mov  [hi].lo,ebx
2685         emit_mov_m32_r32(DRCTOP, HIADDRHI, REG_EDX);                           // mov  [hi].hi,edx
2686         return RECOMPILE_SUCCESSFUL_CP(8,4);
2687
2688      case 0x1e:   /* DDIV */
2689         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
2690         emit_push_imm(DRCTOP, (FPTR)&mips3.core->r[RTREG]);                        // push [rtreg]
2691         emit_push_imm(DRCTOP, (FPTR)&mips3.core->r[RSREG]);                        // push [rsreg]
2692         emit_call(DRCTOP, (x86code *)ddiv);                                    // call ddiv
2693         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2694         return RECOMPILE_SUCCESSFUL_CP(68,4);
2695
2696      case 0x1f:   /* DDIVU */
2697         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
2698         emit_push_imm(DRCTOP, (FPTR)&mips3.core->r[RTREG]);                        // push [rtreg]
2699         emit_push_imm(DRCTOP, (FPTR)&mips3.core->r[RSREG]);                        // push [rsreg]
2700         emit_call(DRCTOP, (x86code *)ddivu);                                 // call ddivu
2701         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
2702         return RECOMPILE_SUCCESSFUL_CP(68,4);
2703   }
2704
2705   emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);               // jmp  generate_invalidop_exception
2706   return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
2707}
2708
2709static UINT32 recompile_special2(drc_core *drc, UINT32 pc, UINT32 op)
2710{
2711   emit_link link1, link2, link3;
2712
2713   switch (op & 63)
2714   {
2715      case 0x20:   /* ADD */
2716         if (RSREG != 0 && RTREG != 0)
2717         {
2718            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2719            emit_add_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // add  eax,[rtreg].lo
2720            emit_jcc(DRCTOP, COND_O, mips3.drcdata->generate_overflow_exception);      // jo   generate_overflow_exception
2721            if (RDREG != 0)
2722            {
2723               emit_cdq(DRCTOP);                                          // cdq
2724               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2725            }
2726         }
2727         else if (RDREG != 0)
2728         {
2729            if (RSREG != 0)
2730            {
2731               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));               // mov  eax,[rsreg].lo
2732               emit_cdq(DRCTOP);                                          // cdq
2733               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2734            }
2735            else if (RTREG != 0)
2736            {
2737               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2738               emit_cdq(DRCTOP);                                          // cdq
2739               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2740            }
2741            else
2742               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2743         }
2744         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
2745
2746      case 0x21:   /* ADDU */
2747         if (RDREG != 0)
2748         {
2749            if (RSREG != 0 && RTREG != 0)
2750            {
2751               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));               // mov  eax,[rsreg].lo
2752               emit_add_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // add  eax,[rtreg].lo
2753               emit_cdq(DRCTOP);                                          // cdq
2754               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2755            }
2756            else if (RSREG != 0)
2757            {
2758               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));               // mov  eax,[rsreg].lo
2759               emit_cdq(DRCTOP);                                          // cdq
2760               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2761            }
2762            else if (RTREG != 0)
2763            {
2764               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2765               emit_cdq(DRCTOP);                                          // cdq
2766               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2767            }
2768            else
2769               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2770         }
2771         return RECOMPILE_SUCCESSFUL_CP(1,4);
2772
2773      case 0x22:   /* SUB */
2774         if (RSREG != 0 && RTREG != 0)
2775         {
2776            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2777            emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // sub  eax,[rtreg].lo
2778            emit_jcc(DRCTOP, COND_O, mips3.drcdata->generate_overflow_exception);      // jo   generate_overflow_exception
2779            if (RDREG != 0)
2780            {
2781               emit_cdq(DRCTOP);                                          // cdq
2782               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2783            }
2784         }
2785         else if (RDREG != 0)
2786         {
2787            if (RSREG != 0)
2788            {
2789               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));               // mov  eax,[rsreg].lo
2790               emit_cdq(DRCTOP);                                          // cdq
2791               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2792            }
2793            else if (RTREG != 0)
2794            {
2795               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2796               emit_neg_r32(DRCTOP, REG_EAX);                                 // neg  eax
2797               emit_cdq(DRCTOP);                                          // cdq
2798               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2799            }
2800            else
2801               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2802         }
2803         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
2804
2805      case 0x23:   /* SUBU */
2806         if (RDREG != 0)
2807         {
2808            if (RSREG != 0 && RTREG != 0)
2809            {
2810               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));               // mov  eax,[rsreg].lo
2811               emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // sub  eax,[rtreg].lo
2812               emit_cdq(DRCTOP);                                          // cdq
2813               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2814            }
2815            else if (RSREG != 0)
2816            {
2817               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));               // mov  eax,[rsreg].lo
2818               emit_cdq(DRCTOP);                                          // cdq
2819               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2820            }
2821            else if (RTREG != 0)
2822            {
2823               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
2824               emit_neg_r32(DRCTOP, REG_EAX);                                 // neg  eax
2825               emit_cdq(DRCTOP);                                          // cdq
2826               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2827            }
2828            else
2829               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2830         }
2831         return RECOMPILE_SUCCESSFUL_CP(1,4);
2832
2833      case 0x24:   /* AND */
2834         if (RDREG != 0)
2835         {
2836            if (RSREG != 0 && RTREG != 0)
2837            {
2838               if (USE_SSE)
2839               {
2840                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, REGADDR(RSREG));            // movsd xmm0,[rsreg]
2841                  emit_movsd_r128_m64(DRCTOP, REG_XMM1, REGADDR(RTREG));            // movsd xmm1,[rtreg]
2842                  emit_andpd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1);               // andpd xmm0,xmm1
2843                  emit_movsd_m64_r128(DRCTOP, REGADDR(RDREG), REG_XMM0);            // mov  [rdreg],xmm0
2844               }
2845               else
2846               {
2847                  emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));
2848                                                                     // mov  edx:eax,[rsreg]
2849                  emit_and_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));            // and  eax,[rtreg].lo
2850                  emit_and_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));            // and  edx,[rtreg].hi
2851                  emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);         // mov  [rdreg],edx:eax
2852               }
2853            }
2854            else
2855               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2856         }
2857         return RECOMPILE_SUCCESSFUL_CP(1,4);
2858
2859      case 0x25:   /* OR */
2860         if (RDREG != 0)
2861         {
2862            if (RSREG != 0 && RTREG != 0)
2863            {
2864               if (USE_SSE)
2865               {
2866                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, REGADDR(RSREG));            // movsd xmm0,[rsreg]
2867                  emit_movsd_r128_m64(DRCTOP, REG_XMM1, REGADDR(RTREG));            // movsd xmm1,[rtreg]
2868                  emit_orpd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1);               // orpd  xmm0,xmm1
2869                  emit_movsd_m64_r128(DRCTOP, REGADDR(RDREG), REG_XMM0);            // mov  [rdreg],xmm0
2870               }
2871               else
2872               {
2873                  emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));
2874                                                                     // mov  edx:eax,[rsreg]
2875                  emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // or   eax,[rtreg].lo
2876                  emit_or_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));               // or   edx,[rtreg].hi
2877                  emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);         // mov  [rdreg],edx:eax
2878               }
2879            }
2880            else if (RSREG != 0)
2881               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RSREG));            // mov  [rdreg],[rsreg]
2882            else if (RTREG != 0)
2883               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RTREG));            // mov  [rdreg],[rtreg]
2884            else
2885               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2886         }
2887         return RECOMPILE_SUCCESSFUL_CP(1,4);
2888
2889      case 0x26:   /* XOR */
2890         if (RDREG != 0)
2891         {
2892            if (RSREG != 0 && RTREG != 0)
2893            {
2894               if (USE_SSE)
2895               {
2896                  emit_movsd_r128_m64(DRCTOP, REG_XMM0, REGADDR(RSREG));            // movsd xmm0,[rsreg]
2897                  emit_movsd_r128_m64(DRCTOP, REG_XMM1, REGADDR(RTREG));            // movsd xmm1,[rtreg]
2898                  emit_xorpd_r128_r128(DRCTOP, REG_XMM0, REG_XMM1);               // xorpd xmm0,xmm1
2899                  emit_movsd_m64_r128(DRCTOP, REGADDR(RDREG), REG_XMM0);            // mov  [rdreg],xmm0
2900               }
2901               else
2902               {
2903                  emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));
2904                                                                     // mov  edx:eax,[rsreg]
2905                  emit_xor_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));            // xor  eax,[rtreg].lo
2906                  emit_xor_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));            // xor  edx,[rtreg].hi
2907                  emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);         // mov  [rdreg],edx:eax
2908               }
2909            }
2910            else if (RSREG != 0)
2911               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RSREG));            // mov  [rdreg],[rsreg]
2912            else if (RTREG != 0)
2913               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RTREG));            // mov  [rdreg],[rtreg]
2914            else
2915               emit_zero_m64(DRCTOP, REGADDR(RDREG));
2916         }
2917         return RECOMPILE_SUCCESSFUL_CP(1,4);
2918
2919      case 0x27:   /* NOR */
2920         if (RDREG != 0)
2921         {
2922            if (RSREG != 0 && RTREG != 0)
2923            {
2924               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));            // mov  edx:eax,[rsreg]
2925               emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // or   eax,[rtreg].lo
2926               emit_or_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));                  // or   edx,[rtreg].hi
2927               emit_not_r32(DRCTOP, REG_EDX);                                 // not  edx
2928               emit_not_r32(DRCTOP, REG_EAX);                                 // not  eax
2929               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2930            }
2931            else if (RSREG != 0)
2932            {
2933               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));            // mov  edx:eax,[rsreg]
2934               emit_not_r32(DRCTOP, REG_EDX);                                 // not  edx
2935               emit_not_r32(DRCTOP, REG_EAX);                                 // not  eax
2936               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2937            }
2938            else if (RTREG != 0)
2939            {
2940               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RTREG));            // mov  edx:eax,[rtreg]
2941               emit_not_r32(DRCTOP, REG_EDX);                                 // not  edx
2942               emit_not_r32(DRCTOP, REG_EAX);                                 // not  eax
2943               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
2944            }
2945            else
2946            {
2947               emit_mov_m32_imm(DRCTOP, REGADDRLO(RDREG), ~0);                     // mov  [rtreg].lo,~0
2948               emit_mov_m32_imm(DRCTOP, REGADDRHI(RDREG), ~0);                     // mov  [rtreg].hi,~0
2949            }
2950         }
2951         return RECOMPILE_SUCCESSFUL_CP(1,4);
2952
2953      case 0x2a:   /* SLT */
2954         if (RDREG != 0)
2955         {
2956            if (RSREG != 0)
2957               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));   // mov  edx:eax,[rsreg]
2958            else
2959            {
2960               emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                        // xor  edx,edx
2961               emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                        // xor  eax,eax
2962            }
2963            if (RTREG != 0)
2964            {
2965               emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // sub  eax,[rtreg].lo
2966               emit_sbb_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));               // sbb  edx,[rtreg].lo
2967            }
2968            emit_shr_r32_imm(DRCTOP, REG_EDX, 31);                              // shr  edx,31
2969            emit_mov_m32_r32(DRCTOP, REGADDRLO(RDREG), REG_EDX);                  // mov  [rdreg].lo,edx
2970            emit_mov_m32_imm(DRCTOP, REGADDRHI(RDREG), 0);                        // mov  [rdreg].hi,0
2971         }
2972         return RECOMPILE_SUCCESSFUL_CP(1,4);
2973
2974      case 0x2b:   /* SLTU */
2975         if (RDREG != 0)
2976         {
2977            emit_xor_r32_r32(DRCTOP, REG_ECX, REG_ECX);                           // xor  ecx,ecx
2978            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                  // mov  eax,[rsreg].hi
2979            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                  // cmp  eax,[rtreg].hi
2980            emit_jcc_short_link(DRCTOP, COND_B, &link1);                        // jb   setit
2981            emit_jcc_short_link(DRCTOP, COND_A, &link2);                        // ja   skipit
2982            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                  // mov  eax,[rsreg].lo
2983            emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // cmp  eax,[rtreg].lo
2984            emit_jcc_short_link(DRCTOP, COND_AE, &link3);                        // jae  skipit
2985            resolve_link(DRCTOP, &link1);                                 // setit:
2986            emit_add_r32_imm(DRCTOP, REG_ECX, 1);                              // add  ecx,1
2987            resolve_link(DRCTOP, &link2);                                 // skipit:
2988            resolve_link(DRCTOP, &link3);                                 // skipit:
2989            emit_mov_m32_r32(DRCTOP, REGADDRLO(RDREG), REG_ECX);                  // mov  [rdreg].lo,ecx
2990            emit_mov_m32_imm(DRCTOP, REGADDRHI(RDREG), 0);                        // mov  [rdreg].hi,0
2991         }
2992         return RECOMPILE_SUCCESSFUL_CP(1,4);
2993
2994      case 0x2c:   /* DADD */
2995         if (RSREG != 0 && RTREG != 0)
2996         {
2997            emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));               // mov  edx:eax,[rsreg]
2998            emit_add_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // add  eax,[rtreg].lo
2999            emit_adc_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));                  // adc  edx,[rtreg].hi
3000            emit_jcc(DRCTOP, COND_O, mips3.drcdata->generate_overflow_exception);      // jo   generate_overflow_exception
3001            if (RDREG != 0)
3002               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3003         }
3004         else if (RDREG != 0)
3005         {
3006            if (RSREG != 0)
3007               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RSREG));            // mov  [rdreg],[rsreg]
3008            else if (RTREG != 0)
3009               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RTREG));            // mov  [rdreg],[rtreg]
3010            else
3011               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3012         }
3013         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3014
3015      case 0x2d:   /* DADDU */
3016         if (RDREG != 0)
3017         {
3018            if (RSREG != 0 && RTREG != 0)
3019            {
3020               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));            // mov  edx:eax,[rsreg]
3021               emit_add_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // add  eax,[rtreg].lo
3022               emit_adc_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));               // adc  edx,[rtreg].hi
3023               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3024            }
3025            else if (RSREG != 0)
3026               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RSREG));
3027                                                                     // mov  [rdreg],[rsreg]
3028            else if (RTREG != 0)
3029               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RTREG));
3030                                                                     // mov  [rdreg],[rtreg]
3031            else
3032               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3033         }
3034         return RECOMPILE_SUCCESSFUL_CP(1,4);
3035
3036      case 0x2e:   /* DSUB */
3037         if (RSREG != 0 && RTREG != 0)
3038         {
3039            emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));               // mov  edx:eax,[rsreg]
3040            emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // sub  eax,[rtreg].lo
3041            emit_sbb_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));                  // sbb  edx,[rtreg].hi
3042            emit_jcc(DRCTOP, COND_O, mips3.drcdata->generate_overflow_exception);      // jo   generate_overflow_exception
3043            if (RDREG != 0)
3044               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3045         }
3046         else if (RDREG != 0)
3047         {
3048            if (RSREG != 0)
3049               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RSREG));            // mov  [rdreg],[rsreg]
3050            else if (RTREG != 0)
3051            {
3052               emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                        // xor  eax,eax
3053               emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                        // xor  edx,edx
3054               emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // sub  eax,[rtreg].lo
3055               emit_sbb_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));               // sbb  edx,[rtreg].hi
3056               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3057            }
3058            else
3059               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3060         }
3061         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3062
3063      case 0x2f:   /* DSUBU */
3064         if (RDREG != 0)
3065         {
3066            if (RSREG != 0 && RTREG != 0)
3067            {
3068               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));            // mov  edx:eax,[rsreg]
3069               emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // sub  eax,[rtreg].lo
3070               emit_sbb_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));               // sbb  edx,[rtreg].hi
3071               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3072            }
3073            else if (RSREG != 0)
3074               emit_mov_m64_m64(DRCTOP, REGADDR(RDREG), REGADDR(RSREG));            // mov  [rdreg],[rsreg]
3075            else if (RTREG != 0)
3076            {
3077               emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                        // xor  eax,eax
3078               emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                        // xor  edx,edx
3079               emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // sub  eax,[rtreg].lo
3080               emit_sbb_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));               // sbb  edx,[rtreg].hi
3081               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3082            }
3083            else
3084               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3085         }
3086         return RECOMPILE_SUCCESSFUL_CP(1,4);
3087
3088      case 0x30:   /* TGE */
3089         if (RSREG != 0)
3090            emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));               // mov  edx:eax,[rsreg]
3091         else
3092         {
3093            emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                           // xor  edx,edx
3094            emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                           // xor  eax,eax
3095         }
3096         if (RTREG != 0)
3097         {
3098            emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // sub  eax,[rtreg].lo
3099            emit_sbb_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));                  // sbb  edx,[rtreg].hi
3100         }
3101         else
3102            emit_cmp_r32_imm(DRCTOP, REG_EDX, 0);                              // cmp  edx,0
3103         emit_jcc(DRCTOP, COND_GE, mips3.drcdata->generate_trap_exception);            // jge  generate_trap_exception
3104         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3105
3106      case 0x31:   /* TGEU */
3107         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // mov  eax,[rsreg].hi
3108         emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // cmp  eax,[rtreg].hi
3109         emit_jcc(DRCTOP, COND_A, mips3.drcdata->generate_trap_exception);            // ja   generate_trap_exception
3110         emit_jcc_short_link(DRCTOP, COND_B, &link1);                           // jb   skipit
3111         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
3112         emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                     // cmp  eax,[rtreg].lo
3113         emit_jcc(DRCTOP, COND_AE, mips3.drcdata->generate_trap_exception);            // jae  generate_trap_exception
3114         resolve_link(DRCTOP, &link1);                                    // skipit:
3115         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3116
3117      case 0x32:   /* TLT */
3118         if (RSREG != 0)
3119            emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));               // mov  edx:eax,[rsreg]
3120         else
3121         {
3122            emit_xor_r32_r32(DRCTOP, REG_EDX, REG_EDX);                           // xor  edx,edx
3123            emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                           // xor  eax,eax
3124         }
3125         if (RTREG != 0)
3126         {
3127            emit_sub_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // sub  eax,[rtreg].lo
3128            emit_sbb_r32_m32(DRCTOP, REG_EDX, REGADDRHI(RTREG));                  // sbb  edx,[rtreg].hi
3129         }
3130         else
3131            emit_cmp_r32_imm(DRCTOP, REG_EDX, 0);                              // cmp  edx,0
3132         emit_jcc(DRCTOP, COND_L, mips3.drcdata->generate_trap_exception);            // jl   generate_trap_exception
3133         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3134
3135      case 0x33:   /* TLTU */
3136         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // mov  eax,[rsreg].hi
3137         emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // cmp  eax,[rtreg].hi
3138         emit_jcc(DRCTOP, COND_B, mips3.drcdata->generate_trap_exception);            // jb   generate_trap_exception
3139         emit_jcc_short_link(DRCTOP, COND_A, &link1);                           // ja   skipit
3140         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
3141         emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                     // cmp  eax,[rtreg].lo
3142         emit_jcc(DRCTOP, COND_B, mips3.drcdata->generate_trap_exception);            // jb   generate_trap_exception
3143         resolve_link(DRCTOP, &link1);                                    // skipit:
3144         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3145
3146      case 0x34:   /* TEQ */
3147         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // mov  eax,[rsreg].hi
3148         emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // cmp  eax,[rtreg].hi
3149         emit_jcc_short_link(DRCTOP, COND_NE, &link1);                           // jne  skipit
3150         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
3151         emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                     // cmp  eax,[rtreg].lo
3152         emit_jcc(DRCTOP, COND_E, mips3.drcdata->generate_trap_exception);            // je   generate_trap_exception
3153         resolve_link(DRCTOP, &link1);                                    // skipit:
3154         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3155
3156      case 0x36:   /* TNE */
3157         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RSREG));                     // mov  eax,[rsreg].hi
3158         emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                     // cmp  eax,[rtreg].hi
3159         emit_jcc_short_link(DRCTOP, COND_E, &link1);                           // je   skipit
3160         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg].lo
3161         emit_cmp_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                     // cmp  eax,[rtreg].lo
3162         emit_jcc(DRCTOP, COND_NE, mips3.drcdata->generate_trap_exception);            // jne  generate_trap_exception
3163         resolve_link(DRCTOP, &link1);                                    // skipit:
3164         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3165
3166      case 0x38:   /* DSLL */
3167         if (RDREG != 0)
3168         {
3169            if (RTREG != 0)
3170            {
3171               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RTREG));            // mov  edx:eax,[rtreg]
3172               if (SHIFT != 0)
3173               {
3174                  emit_shld_r32_r32_imm(DRCTOP, REG_EDX, REG_EAX, SHIFT);            // shld edx,eax,SHIFT
3175                  emit_shl_r32_imm(DRCTOP, REG_EAX, SHIFT);                     // shl  eax,SHIFT
3176               }
3177               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3178            }
3179            else
3180               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3181         }
3182         return RECOMPILE_SUCCESSFUL_CP(1,4);
3183
3184      case 0x3a:   /* DSRL */
3185         if (RDREG != 0)
3186         {
3187            if (RTREG != 0)
3188            {
3189               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RTREG));            // mov  edx:eax,[rtreg]
3190               if (SHIFT != 0)
3191               {
3192                  emit_shrd_r32_r32_imm(DRCTOP, REG_EAX, REG_EDX, SHIFT);            // shrd eax,edx,SHIFT
3193                  emit_shr_r32_imm(DRCTOP, REG_EDX, SHIFT);                     // shr  edx,SHIFT
3194               }
3195               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3196            }
3197            else
3198               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3199         }
3200         return RECOMPILE_SUCCESSFUL_CP(1,4);
3201
3202      case 0x3b:   /* DSRA */
3203         if (RDREG != 0)
3204         {
3205            if (RTREG != 0)
3206            {
3207               emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RTREG));            // mov  edx:eax,[rtreg]
3208               if (SHIFT != 0)
3209               {
3210                  emit_shrd_r32_r32_imm(DRCTOP, REG_EAX, REG_EDX, SHIFT);            // shrd eax,edx,SHIFT
3211                  emit_sar_r32_imm(DRCTOP, REG_EDX, SHIFT);                     // sar  edx,SHIFT
3212               }
3213               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3214            }
3215            else
3216               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3217         }
3218         return RECOMPILE_SUCCESSFUL_CP(1,4);
3219
3220      case 0x3c:   /* DSLL32 */
3221         if (RDREG != 0)
3222         {
3223            if (RTREG != 0)
3224            {
3225               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
3226               if (SHIFT != 0)
3227                  emit_shl_r32_imm(DRCTOP, REG_EAX, SHIFT);                     // shl  eax,SHIFT
3228               emit_mov_m32_imm(DRCTOP, REGADDRLO(RDREG), 0);                     // mov  [rdreg].lo,0
3229               emit_mov_m32_r32(DRCTOP, REGADDRHI(RDREG), REG_EAX);               // mov  [rdreg].hi,eax
3230            }
3231            else
3232               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3233         }
3234         return RECOMPILE_SUCCESSFUL_CP(1,4);
3235
3236      case 0x3e:   /* DSRL32 */
3237         if (RDREG != 0)
3238         {
3239            if (RTREG != 0)
3240            {
3241               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));               // mov  eax,[rtreg].hi
3242               if (SHIFT != 0)
3243                  emit_shr_r32_imm(DRCTOP, REG_EAX, SHIFT);                     // shr  eax,SHIFT
3244               emit_mov_m32_imm(DRCTOP, REGADDRHI(RDREG), 0);                     // mov  [rdreg].hi,0
3245               emit_mov_m32_r32(DRCTOP, REGADDRLO(RDREG), REG_EAX);               // mov  [rdreg].lo,eax
3246            }
3247            else
3248               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3249         }
3250         return RECOMPILE_SUCCESSFUL_CP(1,4);
3251
3252      case 0x3f:   /* DSRA32 */
3253         if (RDREG != 0)
3254         {
3255            if (RTREG != 0)
3256            {
3257               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));               // mov  eax,[rtreg].hi
3258               emit_cdq(DRCTOP);                                          // cdq
3259               if (SHIFT != 0)
3260                  emit_sar_r32_imm(DRCTOP, REG_EAX, SHIFT);                     // sar  eax,SHIFT
3261               emit_mov_m64_r64(DRCTOP, REGADDR(RDREG), REG_EDX, REG_EAX);            // mov  [rdreg],edx:eax
3262            }
3263            else
3264               emit_zero_m64(DRCTOP, REGADDR(RDREG));
3265         }
3266         return RECOMPILE_SUCCESSFUL_CP(1,4);
3267   }
3268
3269   emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);               // jmp  generate_invalidop_exception
3270   return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
3271}
3272
3273
3274static UINT32 recompile_special(drc_core *drc, UINT32 pc, UINT32 op)
3275{
3276   if (!(op & 32))
3277      return recompile_special1(drc, pc, op);
3278   else
3279      return recompile_special2(drc, pc, op);
3280}
3281
3282
3283/*------------------------------------------------------------------
3284    recompile_regimm
3285------------------------------------------------------------------*/
3286
3287static UINT32 recompile_regimm(drc_core *drc, UINT32 pc, UINT32 op)
3288{
3289   emit_link link1;
3290   int cycles;
3291
3292   switch (RTREG)
3293   {
3294      case 0x00:   /* BLTZ */
3295         if (RSREG == 0)
3296            return RECOMPILE_SUCCESSFUL_CP(1,4);
3297         else
3298         {
3299            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
3300            emit_jcc_near_link(DRCTOP, COND_GE, &link1);                        // jge  skip
3301         }
3302
3303         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
3304         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
3305         resolve_link(DRCTOP, &link1);                                    // skip:
3306         return RECOMPILE_SUCCESSFUL_CP(1,4);
3307
3308      case 0x01:   /* BGEZ */
3309         if (RSREG == 0)
3310         {
3311            cycles = recompile_delay_slot(drc, pc + 4);                           // <next instruction>
3312            append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);         // <branch or dispatch>
3313            return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
3314         }
3315         else
3316         {
3317            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
3318            emit_jcc_near_link(DRCTOP, COND_L, &link1);                           // jl   skip
3319         }
3320
3321         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
3322         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
3323         resolve_link(DRCTOP, &link1);                                    // skip:
3324         return RECOMPILE_SUCCESSFUL_CP(1,4);
3325
3326      case 0x02:   /* BLTZL */
3327         if (RSREG == 0)
3328            return RECOMPILE_SUCCESSFUL_CP(1,4);
3329         else
3330         {
3331            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
3332            emit_jcc_near_link(DRCTOP, COND_GE, &link1);                        // jge  skip
3333         }
3334
3335         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
3336         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
3337         resolve_link(DRCTOP, &link1);                                    // skip:
3338         return RECOMPILE_SUCCESSFUL_CP(1,8);
3339
3340      case 0x03:   /* BGEZL */
3341         if (RSREG == 0)
3342         {
3343            cycles = recompile_delay_slot(drc, pc + 4);                           // <next instruction>
3344            append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);         // <branch or dispatch>
3345            return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
3346         }
3347         else
3348         {
3349            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
3350            emit_jcc_near_link(DRCTOP, COND_L, &link1);                           // jl   skip
3351         }
3352
3353         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
3354         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
3355         resolve_link(DRCTOP, &link1);                                    // skip:
3356         return RECOMPILE_SUCCESSFUL_CP(1,8);
3357
3358      case 0x08:   /* TGEI */
3359         if (RSREG != 0)
3360         {
3361            emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));               // mov  edx:eax,[rsreg]
3362            emit_sub_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // sub  eax,[rtreg].lo
3363            emit_sbb_r32_imm(DRCTOP, REG_EDX, ((INT32)SIMMVAL >> 31));               // sbb  edx,[rtreg].lo
3364            emit_jcc(DRCTOP, COND_GE, mips3.drcdata->generate_trap_exception);         // jge  generate_trap_exception
3365         }
3366         else
3367         {
3368            if (0 >= SIMMVAL)
3369               emit_jmp(DRCTOP, mips3.drcdata->generate_trap_exception);            // jmp  generate_trap_exception
3370         }
3371         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3372
3373      case 0x09:   /* TGEIU */
3374         if (RSREG != 0)
3375         {
3376            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), ((INT32)SIMMVAL >> 31));
3377                                                                     // cmp  [rsreg].hi,upper
3378            emit_jcc(DRCTOP, COND_A, mips3.drcdata->generate_trap_exception);         // ja   generate_trap_exception
3379            emit_jcc_short_link(DRCTOP, COND_B, &link1);                        // jb   skip
3380            emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), SIMMVAL);                  // cmp  [rsreg].lo,lower
3381            emit_jcc(DRCTOP, COND_AE, mips3.drcdata->generate_trap_exception);         // jae  generate_trap_exception
3382            resolve_link(DRCTOP, &link1);                                 // skip:
3383         }
3384         else
3385         {
3386            if (0 >= SIMMVAL)
3387               emit_jmp(DRCTOP, mips3.drcdata->generate_trap_exception);            // jmp  generate_trap_exception
3388         }
3389         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3390
3391      case 0x0a:   /* TLTI */
3392         if (RSREG != 0)
3393         {
3394            emit_mov_r64_m64(DRCTOP, REG_EDX, REG_EAX, REGADDR(RSREG));               // mov  edx:eax,[rsreg]
3395            emit_sub_r32_imm(DRCTOP, REG_EAX, SIMMVAL);                           // sub  eax,[rtreg].lo
3396            emit_sbb_r32_imm(DRCTOP, REG_EDX, ((INT32)SIMMVAL >> 31));               // sbb  edx,[rtreg].lo
3397            emit_jcc(DRCTOP, COND_L, mips3.drcdata->generate_trap_exception);         // jl   generate_trap_exception
3398         }
3399         else
3400         {
3401            if (0 < SIMMVAL)
3402               emit_jmp(DRCTOP, mips3.drcdata->generate_trap_exception);            // jmp  generate_trap_exception
3403         }
3404         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3405
3406      case 0x0b:   /* TLTIU */
3407         if (RSREG != 0)
3408         {
3409            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), ((INT32)SIMMVAL >> 31));
3410                                                                     // cmp  [rsreg].hi,upper
3411            emit_jcc(DRCTOP, COND_B, mips3.drcdata->generate_trap_exception);         // jb   generate_trap_exception
3412            emit_jcc_short_link(DRCTOP, COND_A, &link1);                        // ja   skip
3413            emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), SIMMVAL);                  // cmp  [rsreg].lo,lower
3414            emit_jcc(DRCTOP, COND_B, mips3.drcdata->generate_trap_exception);         // jb   generate_trap_exception
3415            resolve_link(DRCTOP, &link1);                                 // skip:
3416         }
3417         else
3418         {
3419            emit_mov_m32_imm(DRCTOP, REGADDRLO(RTREG), (0 < SIMMVAL));               // mov  [rtreg].lo,const
3420            emit_mov_m32_imm(DRCTOP, REGADDRHI(RTREG), 0);                        // mov  [rtreg].hi,sign-extend(const)
3421         }
3422         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3423
3424      case 0x0c:   /* TEQI */
3425         if (RSREG != 0)
3426         {
3427            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), ((INT32)SIMMVAL >> 31));
3428                                                                     // cmp  [rsreg].hi,upper
3429            emit_jcc_short_link(DRCTOP, COND_NE, &link1);                        // jne  skip
3430            emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), SIMMVAL);                  // cmp  [rsreg].lo,lower
3431            emit_jcc(DRCTOP, COND_E, mips3.drcdata->generate_trap_exception);         // je   generate_trap_exception
3432            resolve_link(DRCTOP, &link1);                                 // skip:
3433         }
3434         else
3435         {
3436            if (0 == SIMMVAL)
3437               emit_jmp(DRCTOP, mips3.drcdata->generate_trap_exception);            // jmp  generate_trap_exception
3438         }
3439         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3440
3441      case 0x0e:   /* TNEI */
3442         if (RSREG != 0)
3443         {
3444            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), ((INT32)SIMMVAL >> 31));
3445                                                                     // cmp  [rsreg].hi,upper
3446            emit_jcc_short_link(DRCTOP, COND_E, &link1);                        // je   skip
3447            emit_cmp_m32_imm(DRCTOP, REGADDRLO(RSREG), SIMMVAL);                  // cmp  [rsreg].lo,lower
3448            emit_jcc(DRCTOP, COND_NE, mips3.drcdata->generate_trap_exception);         // jne  generate_trap_exception
3449            resolve_link(DRCTOP, &link1);                                 // skip:
3450         }
3451         else
3452         {
3453            if (0 != SIMMVAL)
3454               emit_jmp(DRCTOP, mips3.drcdata->generate_trap_exception);            // jmp  generate_trap_exception
3455         }
3456         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_MAY_CAUSE_EXCEPTION;
3457
3458      case 0x10:   /* BLTZAL */
3459         if (RSREG == 0)
3460            return RECOMPILE_SUCCESSFUL_CP(1,4);
3461         else
3462         {
3463            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
3464            emit_jcc_near_link(DRCTOP, COND_GE, &link1);                        // jge  skip
3465         }
3466         emit_mov_m64_imm32(DRCTOP, MABS(&mips3.core->r[31]), pc + 8);               // mov  [31],pc + 8
3467         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
3468         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
3469         resolve_link(DRCTOP, &link1);                                    // skip:
3470         return RECOMPILE_SUCCESSFUL_CP(1,4);
3471
3472      case 0x11:   /* BGEZAL */
3473         if (RSREG == 0)
3474         {
3475            emit_mov_m64_imm32(DRCTOP, MABS(&mips3.core->r[31]), pc + 8);            // mov  [31],pc + 8
3476            cycles = recompile_delay_slot(drc, pc + 4);                           // <next instruction>
3477            append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);         // <branch or dispatch>
3478            return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
3479         }
3480         else
3481         {
3482            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
3483            emit_jcc_near_link(DRCTOP, COND_L, &link1);                           // jl   skip
3484         }
3485
3486         emit_mov_m64_imm32(DRCTOP, MABS(&mips3.core->r[31]), pc + 8);               // mov  [31],pc + 8
3487         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
3488         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
3489         resolve_link(DRCTOP, &link1);                                    // skip:
3490         return RECOMPILE_SUCCESSFUL_CP(1,4);
3491
3492      case 0x12:   /* BLTZALL */
3493         if (RSREG == 0)
3494            return RECOMPILE_SUCCESSFUL_CP(1,4);
3495         else
3496         {
3497            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
3498            emit_jcc_near_link(DRCTOP, COND_GE, &link1);                        // jge  skip
3499         }
3500
3501         emit_mov_m64_imm32(DRCTOP, MABS(&mips3.core->r[31]), pc + 8);               // mov  [31],pc + 8
3502         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
3503         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
3504         resolve_link(DRCTOP, &link1);                                    // skip:
3505         return RECOMPILE_SUCCESSFUL_CP(1,8);
3506
3507      case 0x13:   /* BGEZALL */
3508         if (RSREG == 0)
3509         {
3510            emit_mov_m64_imm32(DRCTOP, MABS(&mips3.core->r[31]), pc + 8);            // mov  [31],pc + 8
3511            cycles = recompile_delay_slot(drc, pc + 4);                           // <next instruction>
3512            append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);         // <branch or dispatch>
3513            return RECOMPILE_SUCCESSFUL_CP(0,0) | RECOMPILE_END_OF_STRING;
3514         }
3515         else
3516         {
3517            emit_cmp_m32_imm(DRCTOP, REGADDRHI(RSREG), 0);                        // cmp  [rsreg].hi,0
3518            emit_jcc_near_link(DRCTOP, COND_L, &link1);                           // jl   skip
3519         }
3520
3521         emit_mov_m64_imm32(DRCTOP, MABS(&mips3.core->r[31]), pc + 8);               // mov  [31],pc + 8
3522         cycles = recompile_delay_slot(drc, pc + 4);                              // <next instruction>
3523         append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);            // <branch or dispatch>
3524         resolve_link(DRCTOP, &link1);                                    // skip:
3525         return RECOMPILE_SUCCESSFUL_CP(1,8);
3526   }
3527
3528   emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);               // jmp  generate_invalidop_exception
3529   return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
3530}
3531
3532
3533
3534/***************************************************************************
3535    COP0 RECOMPILATION
3536***************************************************************************/
3537
3538/*------------------------------------------------------------------
3539    recompile_set_cop0_reg
3540------------------------------------------------------------------*/
3541
3542static UINT32 recompile_set_cop0_reg(drc_core *drc, UINT8 reg)
3543{
3544   emit_link link1;
3545
3546   switch (reg)
3547   {
3548      case COP0_Cause:
3549         emit_mov_r32_m32(DRCTOP, REG_EBX, CPR0ADDR(COP0_Cause));                  // mov  ebx,[COP0_Cause]
3550         emit_and_r32_imm(DRCTOP, REG_EAX, ~0xfc00);                              // and  eax,~0xfc00
3551         emit_and_r32_imm(DRCTOP, REG_EBX, 0xfc00);                              // and  ebx,0xfc00
3552         emit_or_r32_r32(DRCTOP, REG_EAX, REG_EBX);                              // or   eax,ebx
3553         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Cause), REG_EAX);                  // mov  [COP0_Cause],eax
3554         emit_and_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(COP0_Status));                  // and  eax,[COP0_Status]
3555         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_CHECK_SW_INTERRUPTS;
3556
3557      case COP0_Status:
3558         emit_mov_r32_m32(DRCTOP, REG_EBX, CPR0ADDR(COP0_Status));                  // mov  ebx,[COP0_Status]
3559         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Status), REG_EAX);                  // mov  [COP0_Status],eax
3560         emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EAX);                              // xor  ebx,eax
3561/*
3562#ifdef ENABLE_DEBUGGER
3563            _test_r32_imm(REG_EAX, 0xe0);                                                   // test eax,0xe0
3564            _jcc_short_link(COND_Z, &link1);                                                // jz   skip
3565            _sub_r32_imm(REG_ESP, 4);                                                       // sub  esp,4
3566            _push_r32(REG_EAX);                                                             // push eax
3567            _push_imm("System set 64-bit addressing mode, SR=%08X");                        // push <string>
3568            _call(mame_printf_debug);                                                       // call mame_printf_debug
3569            _call(mame_debug_break);                                                        // call mame_debug_break
3570            _add_r32_imm(REG_ESP, 12);                                                      // add esp,12
3571            _resolve_link(&link1);                                                          // skip:
3572#endif
3573*/
3574         emit_test_r32_imm(DRCTOP, REG_EBX, 0x8000);                              // test ebx,0x8000
3575         emit_jcc_short_link(DRCTOP, COND_Z, &link1);                           // jz   skip
3576         append_update_cycle_counting(drc);                                    // update cycle counting
3577         resolve_link(DRCTOP, &link1);                                    // skip:
3578         return RECOMPILE_SUCCESSFUL_CP(1,4) | RECOMPILE_CHECK_INTERRUPTS | RECOMPILE_END_OF_STRING | RECOMPILE_ADD_DISPATCH;
3579
3580      case COP0_Count:
3581         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Count), REG_EAX);                  // mov  [COP0_Count],eax
3582         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
3583         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
3584         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
3585         emit_call(DRCTOP, (x86code *)activecpu_gettotalcycles);                     // call activecpu_gettotalcycles
3586         emit_pop_r32(DRCTOP, REG_EBX);                                       // pop  ebx
3587         emit_add_r32_imm(DRCTOP, REG_ESP, 8);                                 // add  esp,8
3588         emit_sub_r32_r32(DRCTOP, REG_EAX, REG_EBX);                              // sub  eax,ebx
3589         emit_sbb_r32_imm(DRCTOP, REG_EDX, 0);                                 // sbb  edx,0
3590         emit_sub_r32_r32(DRCTOP, REG_EAX, REG_EBX);                              // sub  eax,ebx
3591         emit_sbb_r32_imm(DRCTOP, REG_EDX, 0);                                 // sbb  edx,0
3592         emit_mov_m64_r64(DRCTOP, MABS(&mips3.core->count_zero_time), REG_EDX, REG_EAX);   // mov  [mips3.core->count_zero_time],edx:eax
3593         append_update_cycle_counting(drc);                                    // update cycle counting
3594         return RECOMPILE_SUCCESSFUL_CP(1,4);
3595
3596      case COP0_Compare:
3597         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Compare), REG_EAX);                  // mov  [COP0_Compare],eax
3598         emit_and_m32_imm(DRCTOP, CPR0ADDR(COP0_Cause), ~0x8000);                  // and  [COP0_Cause],~0x8000
3599         append_update_cycle_counting(drc);                                    // update cycle counting
3600         return RECOMPILE_SUCCESSFUL_CP(1,4);
3601
3602      case COP0_PRId:
3603         return RECOMPILE_SUCCESSFUL_CP(1,4);
3604
3605      case COP0_Config:
3606         emit_mov_r32_m32(DRCTOP, REG_EBX, CPR0ADDR(COP0_Config));                  // mov  ebx,[COP0_Cause]
3607         emit_and_r32_imm(DRCTOP, REG_EAX, 0x0007);                              // and  eax,0x0007
3608         emit_and_r32_imm(DRCTOP, REG_EBX, ~0x0007);                              // and  ebx,~0x0007
3609         emit_or_r32_r32(DRCTOP, REG_EAX, REG_EBX);                              // or   eax,ebx
3610         emit_mov_m32_r32(DRCTOP, CPR0ADDR(COP0_Config), REG_EAX);                  // mov  [COP0_Cause],eax
3611         return RECOMPILE_SUCCESSFUL_CP(1,4);
3612
3613      default:
3614         emit_mov_m32_r32(DRCTOP, CPR0ADDR(reg), REG_EAX);                        // mov  [reg],eax
3615         return RECOMPILE_SUCCESSFUL_CP(1,4);
3616   }
3617   return RECOMPILE_UNIMPLEMENTED;
3618}
3619
3620
3621/*------------------------------------------------------------------
3622    recompile_get_cop0_reg
3623------------------------------------------------------------------*/
3624
3625static UINT32 recompile_get_cop0_reg(drc_core *drc, UINT8 reg)
3626{
3627   emit_link link1;
3628
3629   switch (reg)
3630   {
3631      case COP0_Count:
3632         emit_sub_r32_imm(DRCTOP, REG_EBP, 250);                                 // sub  ebp,24
3633         emit_jcc_short_link(DRCTOP, COND_NS, &link1);                           // jns  notneg
3634         emit_xor_r32_r32(DRCTOP, REG_EBP, REG_EBP);                              // xor  ebp,ebp
3635         resolve_link(DRCTOP, &link1);                                    // notneg:
3636         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
3637         emit_sub_r32_imm(DRCTOP, REG_ESP, 12);                                 // sub  esp,12
3638         emit_call(DRCTOP, (x86code *)activecpu_gettotalcycles);                     // call activecpu_gettotalcycles
3639         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
3640         emit_sub_r32_m32(DRCTOP, REG_EAX, MABS(LO(&mips3.core->count_zero_time)));      // sub  eax,[mips3.core->count_zero_time+0]
3641         emit_sbb_r32_m32(DRCTOP, REG_EDX, MABS(HI(&mips3.core->count_zero_time)));      // sbb  edx,[mips3.core->count_zero_time+4]
3642         emit_shrd_r32_r32_imm(DRCTOP, REG_EAX, REG_EDX, 1);                        // shrd eax,edx,1
3643         return RECOMPILE_SUCCESSFUL_CP(1,4);
3644
3645      case COP0_Cause:
3646         emit_sub_r32_imm(DRCTOP, REG_EBP, 250);                                 // sub  ebp,24
3647         emit_jcc_short_link(DRCTOP, COND_NS, &link1);                           // jns  notneg
3648         emit_xor_r32_r32(DRCTOP, REG_EBP, REG_EBP);                              // xor  ebp,ebp
3649         resolve_link(DRCTOP, &link1);                                    // notneg:
3650         emit_mov_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(reg));                        // mov  eax,[reg]
3651         return RECOMPILE_SUCCESSFUL_CP(1,4);
3652
3653      default:
3654         emit_mov_r32_m32(DRCTOP, REG_EAX, CPR0ADDR(reg));                        // mov  eax,[reg]
3655         return RECOMPILE_SUCCESSFUL_CP(1,4);
3656   }
3657   return RECOMPILE_UNIMPLEMENTED;
3658}
3659
3660
3661/*------------------------------------------------------------------
3662    recompile_cop0
3663------------------------------------------------------------------*/
3664
3665static UINT32 recompile_cop0(drc_core *drc, UINT32 pc, UINT32 op)
3666{
3667   emit_link checklink;
3668   UINT32 result;
3669
3670   if (mips3.drcoptions & MIPS3DRC_STRICT_COP0)
3671   {
3672      emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_KSU_MASK);                  // test [COP0_Status],SR_KSU_MASK
3673      emit_jcc_short_link(DRCTOP, COND_Z, &checklink);                           // jz   okay
3674      emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_COP0);                     // test [COP0_Status],SR_COP0
3675      emit_jcc(DRCTOP, COND_Z, mips3.drcdata->generate_cop_exception);               // jz   generate_cop_exception
3676      resolve_link(DRCTOP, &checklink);                                    // okay:
3677   }
3678
3679   switch (RSREG)
3680   {
3681      case 0x00:   /* MFCz */
3682         result = RECOMPILE_SUCCESSFUL_CP(1,4);
3683         if (RTREG != 0)
3684         {
3685            result = recompile_get_cop0_reg(drc, RDREG);                        // read cop0 reg
3686            emit_cdq(DRCTOP);                                             // cdq
3687            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
3688         }
3689         return result;
3690
3691      case 0x01:   /* DMFCz */
3692         result = RECOMPILE_SUCCESSFUL_CP(1,4);
3693         if (RTREG != 0)
3694         {
3695            result = recompile_get_cop0_reg(drc, RDREG);                        // read cop0 reg
3696            emit_cdq(DRCTOP);                                             // cdq
3697            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
3698         }
3699         return result;
3700
3701      case 0x02:   /* CFCz */
3702         if (RTREG != 0)
3703         {
3704            emit_mov_r32_m32(DRCTOP, REG_EAX, CCR0ADDR(RDREG));                     // mov  eax,[mips3.core->ccr[0][rdreg]]
3705            emit_cdq(DRCTOP);                                             // cdq
3706            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [rtreg],edx:eax
3707         }
3708         return RECOMPILE_SUCCESSFUL_CP(1,4);
3709
3710      case 0x04:   /* MTCz */
3711         if (RTREG != 0)
3712            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[mips3.core->r[RTREG]]
3713         else
3714            emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                           // xor  eax,eax
3715         result = recompile_set_cop0_reg(drc, RDREG);                           // write cop0 reg
3716         return result;
3717
3718      case 0x05:   /* DMTCz */
3719         if (RTREG != 0)
3720            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[mips3.core->r[RTREG]]
3721         else
3722            emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                           // xor  eax,eax
3723         result = recompile_set_cop0_reg(drc, RDREG);                           // write cop0 reg
3724         return result;
3725
3726      case 0x06:   /* CTCz */
3727         if (RTREG != 0)
3728            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[mips3.core->r[RTREG]]
3729         else
3730            emit_xor_r32_r32(DRCTOP, REG_EAX, REG_EAX);                           // xor  eax,eax
3731         emit_mov_m32_r32(DRCTOP, CCR0ADDR(RDREG), REG_EAX);                        // mov  [mips3.core->ccr[0][RDREG]],eax
3732         return RECOMPILE_SUCCESSFUL_CP(1,4);
3733
3734//      case 0x08:  /* BC */
3735//          switch (RTREG)
3736//          {
3737//              case 0x00:  /* BCzF */  if (!mips3.core->cf[0][0]) ADDPC(SIMMVAL);                break;
3738//              case 0x01:  /* BCzF */  if (mips3.core->cf[0][0]) ADDPC(SIMMVAL);                 break;
3739//              case 0x02:  /* BCzFL */ invalid_instruction(op);                            break;
3740//              case 0x03:  /* BCzTL */ invalid_instruction(op);                            break;
3741//              default:    invalid_instruction(op);                                        break;
3742//          }
3743//          break;
3744
3745      case 0x10:
3746      case 0x11:
3747      case 0x12:
3748      case 0x13:
3749      case 0x14:
3750      case 0x15:
3751      case 0x16:
3752      case 0x17:
3753      case 0x18:
3754      case 0x19:
3755      case 0x1a:
3756      case 0x1b:
3757      case 0x1c:
3758      case 0x1d:
3759      case 0x1e:
3760      case 0x1f:   /* COP */
3761         switch (op & 0x01ffffff)
3762         {
3763            case 0x01:   /* TLBR */
3764               emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                           // sub  esp,8
3765               emit_push_imm(DRCTOP, (FPTR)mips3.core);                        // push mips3.core
3766               drc_append_save_call_restore(drc, (x86code *)mips3com_tlbr, 12);      // call tlbr
3767               return RECOMPILE_SUCCESSFUL_CP(1,4);
3768
3769            case 0x02:   /* TLBWI */
3770               emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                           // sub  esp,8
3771               emit_push_imm(DRCTOP, (FPTR)mips3.core);                        // push mips3.core
3772               drc_append_save_call_restore(drc, (x86code *)mips3com_tlbwi, 12);      // call tlbwi
3773               return RECOMPILE_SUCCESSFUL_CP(1,4);
3774
3775            case 0x06:   /* TLBWR */
3776               emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                           // sub  esp,8
3777               emit_push_imm(DRCTOP, (FPTR)mips3.core);                        // push mips3.core
3778               drc_append_save_call_restore(drc, (x86code *)mips3com_tlbwr, 12);      // call tlbwr
3779               return RECOMPILE_SUCCESSFUL_CP(1,4);
3780
3781            case 0x08:   /* TLBP */
3782               emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                           // sub  esp,8
3783               emit_push_imm(DRCTOP, (FPTR)mips3.core);                        // push mips3.core
3784               drc_append_save_call_restore(drc, (x86code *)mips3com_tlbp, 12);      // call tlbp
3785               return RECOMPILE_SUCCESSFUL_CP(1,4);
3786
3787            case 0x10:   /* RFE */
3788               emit_jmp(DRCTOP, mips3.drcdata->generate_invalidop_exception);         // jmp  generate_invalidop_exception
3789               return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
3790
3791            case 0x18:   /* ERET */
3792               emit_mov_r32_m32(DRCTOP, REG_EDI, CPR0ADDR(COP0_EPC));               // mov  edi,[COP0_EPC]
3793               emit_and_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), ~SR_EXL);            // and  [COP0_Status],~SR_EXL
3794               return RECOMPILE_SUCCESSFUL_CP(1,0) | RECOMPILE_CHECK_INTERRUPTS | RECOMPILE_END_OF_STRING | RECOMPILE_ADD_DISPATCH;
3795
3796            default:
3797               emit_jmp(DRCTOP, mips3.drcdata->generate_invalidop_exception);         // jmp  generate_invalidop_exception
3798               return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
3799         }
3800         break;
3801
3802//      default:
3803//          _jmp(mips3.drcdata->generate_invalidop_exception);                              // jmp  generate_invalidop_exception
3804//          return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
3805   }
3806   return RECOMPILE_UNIMPLEMENTED;
3807}
3808
3809
3810
3811/***************************************************************************
3812    COP1 RECOMPILATION
3813***************************************************************************/
3814
3815/*------------------------------------------------------------------
3816    recompile_cop1
3817------------------------------------------------------------------*/
3818
3819static UINT32 recompile_cop1(drc_core *drc, UINT32 pc, UINT32 op)
3820{
3821   emit_link link1;
3822   int cycles, i;
3823
3824   if (mips3.drcoptions & MIPS3DRC_STRICT_COP1)
3825   {
3826      emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_COP1);                     // test [COP0_Status],SR_COP1
3827      emit_jcc(DRCTOP, COND_Z, mips3.drcdata->generate_cop_exception);               // jz   generate_cop_exception
3828   }
3829
3830   switch (RSREG)
3831   {
3832      case 0x00:   /* MFCz */
3833         if (RTREG != 0)
3834         {
3835            emit_mov_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(RDREG));                  // mov  eax,[RDREG]
3836            emit_cdq(DRCTOP);                                             // cdq
3837            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [RTREG],edx:eax
3838         }
3839         return RECOMPILE_SUCCESSFUL_CP(1,4);
3840
3841      case 0x01:   /* DMFCz */
3842         if (RTREG != 0)
3843            emit_mov_m64_m64(DRCTOP, REGADDR(RTREG), FPR64ADDR(RDREG));
3844         return RECOMPILE_SUCCESSFUL_CP(1,4);
3845
3846      case 0x02:   /* CFCz */
3847         if (RTREG != 0)
3848         {
3849            emit_mov_r32_m32(DRCTOP, REG_EAX, CCR1ADDR(RDREG));                     // mov  eax,[mips3.core->ccr[1][RDREG]]
3850            if (RDREG == 31)
3851            {
3852               emit_and_r32_imm(DRCTOP, REG_EAX, ~0xfe800000);                     // and  eax,~0xfe800000
3853               emit_xor_r32_r32(DRCTOP, REG_EBX, REG_EBX);                        // xor  ebx,ebx
3854               emit_cmp_m8_imm(DRCTOP, MABS(&mips3.core->cf[1][0]), 0);            // cmp  [cf[0]],0
3855               emit_setcc_r8(DRCTOP, COND_NZ, REG_BL);                           // setnz bl
3856               emit_shl_r32_imm(DRCTOP, REG_EBX, 23);                           // shl  ebx,23
3857               emit_or_r32_r32(DRCTOP, REG_EAX, REG_EBX);                        // or   eax,ebx
3858               if (mips3.core->flavor >= MIPS3_TYPE_MIPS_IV)
3859                  for (i = 1; i <= 7; i++)
3860                  {
3861                     emit_cmp_m8_imm(DRCTOP, MABS(&mips3.core->cf[1][i]), 0);      // cmp  [cf[i]],0
3862                     emit_setcc_r8(DRCTOP, COND_NZ, REG_BL);                     // setnz bl
3863                     emit_shl_r32_imm(DRCTOP, REG_EBX, 24+i);                  // shl  ebx,24+i
3864                     emit_or_r32_r32(DRCTOP, REG_EAX, REG_EBX);                  // or   eax,ebx
3865                  }
3866            }
3867            emit_cdq(DRCTOP);                                             // cdq
3868            emit_mov_m64_r64(DRCTOP, REGADDR(RTREG), REG_EDX, REG_EAX);               // mov  [mips3.core->r[RTREG]],edx:eax
3869         }
3870         return RECOMPILE_SUCCESSFUL_CP(1,4);
3871
3872      case 0x04:   /* MTCz */
3873         if (RTREG != 0)
3874         {
3875            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[mips3.core->r[RTREG]]
3876            emit_mov_m32_r32(DRCTOP, FPR32ADDR(RDREG), REG_EAX);                  // mov  [mips3.core->cpr[1][RDREG]],eax
3877         }
3878         else
3879            emit_mov_m32_imm(DRCTOP, FPR32ADDR(RDREG), 0);                        // mov  [mips3.core->cpr[1][RDREG]],0
3880         return RECOMPILE_SUCCESSFUL_CP(1,4);
3881
3882      case 0x05:   /* DMTCz */
3883         if (RTREG != 0)
3884            emit_mov_m64_m64(DRCTOP, FPR64ADDR(RDREG), REGADDR(RTREG));
3885         else
3886            emit_zero_m64(DRCTOP, FPR64ADDR(RDREG));                           // mov  [mips3.core->cpr[1][RDREG]],0
3887         return RECOMPILE_SUCCESSFUL_CP(1,4);
3888
3889      case 0x06:   /* CTCz */
3890         if (RTREG != 0)
3891         {
3892            emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                  // mov  eax,[mips3.core->r[RTREG]]
3893            emit_mov_m32_r32(DRCTOP, CCR1ADDR(RDREG), REG_EAX);                     // mov  [mips3.core->ccr[1][RDREG]],eax
3894         }
3895         else
3896            emit_mov_m32_imm(DRCTOP, CCR1ADDR(RDREG), 0);                        // mov  [mips3.core->ccr[1][RDREG]],0
3897         if (RDREG == 31)
3898         {
3899            emit_mov_r32_m32(DRCTOP, REG_EAX, MABS(LO(&mips3.core->ccr[1][RDREG])));   // mov  eax,[mips3.core->ccr[1][RDREG]]
3900            emit_test_r32_imm(DRCTOP, REG_EAX, 1 << 23);                        // test eax,1<<23
3901            emit_setcc_m8(DRCTOP, COND_NZ, MABS(&mips3.core->cf[1][0]));            // setnz [cf[0]]
3902            if (mips3.core->flavor >= MIPS3_TYPE_MIPS_IV)
3903               for (i = 1; i <= 7; i++)
3904               {
3905                  emit_test_r32_imm(DRCTOP, REG_EAX, 1 << (24+i));               // test eax,1<<(24+i)
3906                  emit_setcc_m8(DRCTOP, COND_NZ, MABS(&mips3.core->cf[1][i]));      // setnz [cf[i]]
3907               }
3908            emit_and_r32_imm(DRCTOP, REG_EAX, 3);                              // and  eax,3
3909            emit_test_r32_imm(DRCTOP, REG_EAX, 1);                              // test eax,1
3910            emit_jcc_near_link(DRCTOP, COND_Z, &link1);                           // jz   skip
3911            emit_xor_r32_imm(DRCTOP, REG_EAX, 2);                              // xor  eax,2
3912            resolve_link(DRCTOP, &link1);                                 // skip:
3913            drc_append_set_fp_rounding(drc, REG_EAX);                           // set_rounding(EAX)
3914         }
3915         return RECOMPILE_SUCCESSFUL_CP(1,4);
3916
3917      case 0x08:   /* BC */
3918         switch ((op >> 16) & 3)
3919         {
3920            case 0x00:   /* BCzF */
3921               emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);               // cmp  [cf[x]],0
3922               emit_jcc_near_link(DRCTOP, COND_NZ, &link1);                     // jnz  link1
3923               cycles = recompile_delay_slot(drc, pc + 4);                        // <next instruction>
3924               append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);      // <branch or dispatch>
3925               resolve_link(DRCTOP, &link1);                              // skip:
3926               return RECOMPILE_SUCCESSFUL_CP(1,4);
3927
3928            case 0x01:   /* BCzT */
3929               emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);               // cmp  [cf[x]],0
3930               emit_jcc_near_link(DRCTOP, COND_Z, &link1);                        // jz   link1
3931               cycles = recompile_delay_slot(drc, pc + 4);                        // <next instruction>
3932               append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);      // <branch or dispatch>
3933               resolve_link(DRCTOP, &link1);                              // skip:
3934               return RECOMPILE_SUCCESSFUL_CP(1,4);
3935
3936            case 0x02:   /* BCzFL */
3937               emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);               // cmp  [cf[x]],0
3938               emit_jcc_near_link(DRCTOP, COND_NZ, &link1);                     // jnz  link1
3939               cycles = recompile_delay_slot(drc, pc + 4);                        // <next instruction>
3940               append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);      // <branch or dispatch>
3941               resolve_link(DRCTOP, &link1);                              // skip:
3942               return RECOMPILE_SUCCESSFUL_CP(1,8);
3943
3944            case 0x03:   /* BCzTL */
3945               emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);               // cmp  [cf[x]],0
3946               emit_jcc_near_link(DRCTOP, COND_Z, &link1);                        // jz   link1
3947               cycles = recompile_delay_slot(drc, pc + 4);                        // <next instruction>
3948               append_branch_or_dispatch(drc, pc + 4 + (SIMMVAL << 2), 1+cycles);      // <branch or dispatch>
3949               resolve_link(DRCTOP, &link1);                              // skip:
3950               return RECOMPILE_SUCCESSFUL_CP(1,8);
3951         }
3952         break;
3953
3954      default:
3955         switch (op & 0x3f)
3956         {
3957            case 0x00:
3958               if (IS_SINGLE(op))   /* ADD.S */
3959               {
3960                  if (USE_SSE)
3961                  {
3962                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
3963                     emit_addss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // addss xmm0,[ftreg]
3964                     emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);      // movss [fdreg],xmm0
3965                  }
3966                  else
3967                  {
3968                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
3969                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
3970                     emit_faddp(DRCTOP);                                    // faddp
3971                     emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                  // fstp [fdreg]
3972                  }
3973               }
3974               else            /* ADD.D */
3975               {
3976                  if (USE_SSE)
3977                  {
3978                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
3979                     emit_addsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // addsd xmm0,[ftreg]
3980                     emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);      // movsd [fdreg],xmm0
3981                  }
3982                  else
3983                  {
3984                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
3985                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
3986                     emit_faddp(DRCTOP);                                    // faddp
3987                     emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                  // fstp [fdreg]
3988                  }
3989               }
3990               return RECOMPILE_SUCCESSFUL_CP(1,4);
3991
3992            case 0x01:
3993               if (IS_SINGLE(op))   /* SUB.S */
3994               {
3995                  if (USE_SSE)
3996                  {
3997                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
3998                     emit_subss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // subss xmm0,[ftreg]
3999                     emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);      // movss [fdreg],xmm0
4000                  }
4001                  else
4002                  {
4003                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4004                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4005                     emit_fsubp(DRCTOP);                                    // fsubp
4006                     emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                  // fstp [fdreg]
4007                  }
4008               }
4009               else            /* SUB.D */
4010               {
4011                  if (USE_SSE)
4012                  {
4013                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4014                     emit_subsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // subsd xmm0,[ftreg]
4015                     emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);      // movsd [fdreg],xmm0
4016                  }
4017                  else
4018                  {
4019                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4020                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4021                     emit_fsubp(DRCTOP);                                    // fsubp
4022                     emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                  // fstp [fdreg]
4023                  }
4024               }
4025               return RECOMPILE_SUCCESSFUL_CP(1,4);
4026
4027            case 0x02:
4028               if (IS_SINGLE(op))   /* MUL.S */
4029               {
4030                  if (USE_SSE)
4031                  {
4032                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
4033                     emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // mulss xmm0,[ftreg]
4034                     emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);      // movss [fdreg],xmm0
4035                  }
4036                  else
4037                  {
4038                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4039                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4040                     emit_fmulp(DRCTOP);                                    // fmulp
4041                     emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                  // fstp [fdreg]
4042                  }
4043               }
4044               else            /* MUL.D */
4045               {
4046                  if (USE_SSE)
4047                  {
4048                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4049                     emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // mulsd xmm0,[ftreg]
4050                     emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);      // movsd [fdreg],xmm0
4051                  }
4052                  else
4053                  {
4054                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4055                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4056                     emit_fmulp(DRCTOP);                                    // fmulp
4057                     emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                  // fstp [fdreg]
4058                  }
4059               }
4060               return RECOMPILE_SUCCESSFUL_CP(1,4);
4061
4062            case 0x03:
4063               if (IS_SINGLE(op))   /* DIV.S */
4064               {
4065                  if (USE_SSE)
4066                  {
4067                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
4068                     emit_divss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // divss xmm0,[ftreg]
4069                     emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);      // movss [fdreg],xmm0
4070                  }
4071                  else
4072                  {
4073                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4074                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4075                     emit_fdivp(DRCTOP);                                    // fdivp
4076                     emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                  // fstp [fdreg]
4077                  }
4078               }
4079               else            /* DIV.D */
4080               {
4081                  if (USE_SSE)
4082                  {
4083                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4084                     emit_divsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // divsd xmm0,[ftreg]
4085                     emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);      // movsd [fdreg],xmm0
4086                  }
4087                  else
4088                  {
4089                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4090                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4091                     emit_fdivp(DRCTOP);                                    // fdivp
4092                     emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                  // fstp [fdreg]
4093                  }
4094               }
4095               return RECOMPILE_SUCCESSFUL_CP(1,4);
4096
4097            case 0x04:
4098               if (IS_SINGLE(op))   /* SQRT.S */
4099               {
4100                  if (USE_SSE)
4101                  {
4102                     emit_sqrtss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // sqrtss xmm0,[fsreg]
4103                     emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);      // movss [fdreg],xmm0
4104                  }
4105                  else
4106                  {
4107                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4108                     emit_fsqrt(DRCTOP);                                    // fsqrt
4109                     emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                  // fstp [fdreg]
4110                  }
4111               }
4112               else            /* SQRT.D */
4113               {
4114                  if (USE_SSE)
4115                  {
4116                     emit_sqrtsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // sqrtsd xmm0,[fsreg]
4117                     emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);      // movsd [fdreg],xmm0
4118                  }
4119                  else
4120                  {
4121                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4122                     emit_fsqrt(DRCTOP);                                    // fsqrt
4123                     emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                  // fstp [fdreg]
4124                  }
4125               }
4126               return RECOMPILE_SUCCESSFUL_CP(1,4);
4127
4128            case 0x05:
4129               if (IS_SINGLE(op))   /* ABS.S */
4130               {
4131                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4132                  emit_fabs(DRCTOP);                                       // fabs
4133                  emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                     // fstp [fdreg]
4134               }
4135               else            /* ABS.D */
4136               {
4137                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4138                  emit_fabs(DRCTOP);                                       // fabs
4139                  emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                     // fstp [fdreg]
4140               }
4141               return RECOMPILE_SUCCESSFUL_CP(1,4);
4142
4143            case 0x06:
4144               if (IS_SINGLE(op))   /* MOV.S */
4145               {
4146                  emit_mov_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));            // mov  eax,[fsreg]
4147                  emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);            // mov  [fdreg],eax
4148               }
4149               else            /* MOV.D */
4150                  emit_mov_m64_m64(DRCTOP, FPR64ADDR(FDREG), FPR64ADDR(FSREG));
4151               return RECOMPILE_SUCCESSFUL_CP(1,4);
4152
4153            case 0x07:
4154               if (IS_SINGLE(op))   /* NEG.S */
4155               {
4156                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4157                  emit_fchs(DRCTOP);                                       // fchs
4158                  emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                     // fstp [fdreg]
4159               }
4160               else            /* NEG.D */
4161               {
4162                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4163                  emit_fchs(DRCTOP);                                       // fchs
4164                  emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                     // fstp [fdreg]
4165               }
4166               return RECOMPILE_SUCCESSFUL_CP(1,4);
4167
4168            case 0x08:
4169               drc_append_set_temp_fp_rounding(drc, FPRND_NEAR);
4170               if (IS_SINGLE(op))   /* ROUND.L.S */
4171                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4172               else            /* ROUND.L.D */
4173                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4174               emit_fistp_m64(DRCTOP, FPR64ADDR(FDREG));                        // fistp [fdreg]
4175               drc_append_restore_fp_rounding(drc);
4176               return RECOMPILE_SUCCESSFUL_CP(1,4);
4177
4178            case 0x09:
4179               drc_append_set_temp_fp_rounding(drc, FPRND_CHOP);
4180               if (IS_SINGLE(op))   /* TRUNC.L.S */
4181                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4182               else            /* TRUNC.L.D */
4183                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4184               emit_fistp_m64(DRCTOP, FPR64ADDR(FDREG));                        // fistp [fdreg]
4185               drc_append_restore_fp_rounding(drc);
4186               return RECOMPILE_SUCCESSFUL_CP(1,4);
4187
4188            case 0x0a:
4189               drc_append_set_temp_fp_rounding(drc, FPRND_UP);
4190               if (IS_SINGLE(op))   /* CEIL.L.S */
4191                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4192               else            /* CEIL.L.D */
4193                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4194               emit_fistp_m64(DRCTOP, FPR64ADDR(FDREG));                        // fistp [fdreg]
4195               drc_append_restore_fp_rounding(drc);
4196               return RECOMPILE_SUCCESSFUL_CP(1,4);
4197
4198            case 0x0b:
4199               drc_append_set_temp_fp_rounding(drc, FPRND_DOWN);
4200               if (IS_SINGLE(op))   /* FLOOR.L.S */
4201                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4202               else            /* FLOOR.L.D */
4203                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4204               emit_fistp_m64(DRCTOP, FPR64ADDR(FDREG));                        // fistp [fdreg]
4205               drc_append_restore_fp_rounding(drc);
4206               return RECOMPILE_SUCCESSFUL_CP(1,4);
4207
4208            case 0x0c:
4209               drc_append_set_temp_fp_rounding(drc, FPRND_NEAR);
4210               if (IS_SINGLE(op))   /* ROUND.W.S */
4211                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4212               else            /* ROUND.W.D */
4213                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4214               emit_fistp_m32(DRCTOP, FPR32ADDR(FDREG));                        // fistp [fdreg]
4215               drc_append_restore_fp_rounding(drc);
4216               return RECOMPILE_SUCCESSFUL_CP(1,4);
4217
4218            case 0x0d:
4219               drc_append_set_temp_fp_rounding(drc, FPRND_CHOP);
4220               if (IS_SINGLE(op))   /* TRUNC.W.S */
4221                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4222               else            /* TRUNC.W.D */
4223                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4224               emit_fistp_m32(DRCTOP, FPR32ADDR(FDREG));                        // fistp [fdreg]
4225               drc_append_restore_fp_rounding(drc);
4226               return RECOMPILE_SUCCESSFUL_CP(1,4);
4227
4228            case 0x0e:
4229               drc_append_set_temp_fp_rounding(drc, FPRND_UP);
4230               if (IS_SINGLE(op))   /* CEIL.W.S */
4231                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4232               else            /* CEIL.W.D */
4233                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4234               emit_fistp_m32(DRCTOP, FPR32ADDR(FDREG));                        // fistp [fdreg]
4235               drc_append_restore_fp_rounding(drc);
4236               return RECOMPILE_SUCCESSFUL_CP(1,4);
4237
4238            case 0x0f:
4239               drc_append_set_temp_fp_rounding(drc, FPRND_DOWN);
4240               if (IS_SINGLE(op))   /* FLOOR.W.S */
4241                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4242               else            /* FLOOR.W.D */
4243                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4244               emit_fistp_m32(DRCTOP, FPR32ADDR(FDREG));                        // fistp [fdreg]
4245               drc_append_restore_fp_rounding(drc);
4246               return RECOMPILE_SUCCESSFUL_CP(1,4);
4247
4248            case 0x11:   /* R5000 */
4249               if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
4250               {
4251                  emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);
4252                                                                     // jmp  generate_invalidop_exception
4253                  return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
4254               }
4255               emit_cmp_m8_imm(DRCTOP, CF1ADDR((op >> 18) & 7), 0);               // cmp  [cf[x]],0
4256               emit_jcc_short_link(DRCTOP, ((op >> 16) & 1) ? COND_Z : COND_NZ, &link1);
4257                                                                     // jz/nz skip
4258               if (IS_SINGLE(op))   /* MOVT/F.S */
4259               {
4260                  emit_mov_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));            // mov  eax,[fsreg]
4261                  emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);            // mov  [fdreg],eax
4262               }
4263               else            /* MOVT/F.D */
4264                  emit_mov_m64_m64(DRCTOP, FPR64ADDR(FDREG), FPR64ADDR(FSREG));
4265               resolve_link(DRCTOP, &link1);                              // skip:
4266               return RECOMPILE_SUCCESSFUL_CP(1,4);
4267
4268            case 0x12:   /* R5000 */
4269               if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
4270               {
4271                  emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);
4272                                                                     // jmp  generate_invalidop_exception
4273                  return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
4274               }
4275               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
4276               emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                  // or   eax,[rtreg].hi
4277               emit_jcc_short_link(DRCTOP, COND_NZ, &link1);                     // jnz  skip
4278               if (IS_SINGLE(op))   /* MOVZ.S */
4279               {
4280                  emit_mov_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));            // mov  eax,[fsreg]
4281                  emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);            // mov  [fdreg],eax
4282               }
4283               else            /* MOVZ.D */
4284                  emit_mov_m64_m64(DRCTOP, FPR64ADDR(FDREG), FPR64ADDR(FSREG));
4285               resolve_link(DRCTOP, &link1);                              // skip:
4286               return RECOMPILE_SUCCESSFUL_CP(1,4);
4287
4288            case 0x13:   /* R5000 */
4289               if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
4290               {
4291                  emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);
4292                                                                     // jmp  generate_invalidop_exception
4293                  return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
4294               }
4295               emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));               // mov  eax,[rtreg].lo
4296               emit_or_r32_m32(DRCTOP, REG_EAX, REGADDRHI(RTREG));                  // or   eax,[rtreg].hi
4297               emit_jcc_short_link(DRCTOP, COND_Z, &link1);                     // jz   skip
4298               if (IS_SINGLE(op))   /* MOVN.S */
4299               {
4300                  emit_mov_r32_m32(DRCTOP, REG_EAX, FPR32ADDR(FSREG));            // mov  eax,[fsreg]
4301                  emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);            // mov  [fdreg],eax
4302               }
4303               else            /* MOVN.D */
4304                  emit_mov_m64_m64(DRCTOP, FPR64ADDR(FDREG), FPR64ADDR(FSREG));
4305               resolve_link(DRCTOP, &link1);                              // skip:
4306               return RECOMPILE_SUCCESSFUL_CP(1,4);
4307
4308            case 0x15:   /* R5000 */
4309               if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
4310               {
4311                  emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);
4312                                                                     // jmp  generate_invalidop_exception
4313                  return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
4314               }
4315               emit_fld1(DRCTOP);                                          // fld1
4316               if (IS_SINGLE(op))   /* RECIP.S */
4317               {
4318                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4319                  emit_fdivp(DRCTOP);                                       // fdivp
4320                  emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                     // fstp [fdreg]
4321               }
4322               else            /* RECIP.D */
4323               {
4324                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4325                  emit_fdivp(DRCTOP);                                       // fdivp
4326                  emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                     // fstp [fdreg]
4327               }
4328               return RECOMPILE_SUCCESSFUL_CP(1,4);
4329
4330            case 0x16:   /* R5000 */
4331               if (mips3.core->flavor < MIPS3_TYPE_MIPS_IV)
4332               {
4333                  emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);
4334                                                                     // jmp  generate_invalidop_exception
4335                  return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
4336               }
4337               emit_fld1(DRCTOP);                                          // fld1
4338               if (IS_SINGLE(op))   /* RSQRT.S */
4339               {
4340                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4341                  emit_fsqrt(DRCTOP);                                       // fsqrt
4342                  emit_fdivp(DRCTOP);                                       // fdivp
4343                  emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                     // fstp [fdreg]
4344               }
4345               else            /* RSQRT.D */
4346               {
4347                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4348                  emit_fsqrt(DRCTOP);                                       // fsqrt
4349                  emit_fdivp(DRCTOP);                                       // fdivp
4350                  emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                     // fstp [fdreg]
4351               }
4352               return RECOMPILE_SUCCESSFUL_CP(1,4);
4353
4354            case 0x20:
4355               if (IS_INTEGRAL(op))
4356               {
4357                  if (IS_SINGLE(op))   /* CVT.S.W */
4358                     emit_fild_m32(DRCTOP, FPR32ADDR(FSREG));                  // fild [fsreg]
4359                  else            /* CVT.S.L */
4360                     emit_fild_m64(DRCTOP, FPR64ADDR(FSREG));                  // fild [fsreg]
4361               }
4362               else               /* CVT.S.D */
4363                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4364               emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                        // fstp [fdreg]
4365               return RECOMPILE_SUCCESSFUL_CP(1,4);
4366
4367            case 0x21:
4368               if (IS_INTEGRAL(op))
4369               {
4370                  if (IS_SINGLE(op))   /* CVT.D.W */
4371                     emit_fild_m32(DRCTOP, FPR32ADDR(FSREG));                  // fild [fsreg]
4372                  else            /* CVT.D.L */
4373                     emit_fild_m64(DRCTOP, FPR64ADDR(FSREG));                  // fild [fsreg]
4374               }
4375               else               /* CVT.D.S */
4376                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4377               emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                        // fstp [fdreg]
4378               return RECOMPILE_SUCCESSFUL_CP(1,4);
4379
4380            case 0x24:
4381               if (IS_SINGLE(op))   /* CVT.W.S */
4382                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4383               else            /* CVT.W.D */
4384                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4385               emit_fistp_m32(DRCTOP, FPR32ADDR(FDREG));                        // fistp [fdreg]
4386               return RECOMPILE_SUCCESSFUL_CP(1,4);
4387
4388            case 0x25:
4389               if (IS_SINGLE(op))   /* CVT.L.S */
4390                  emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                        // fld  [fsreg]
4391               else            /* CVT.L.D */
4392                  emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                        // fld  [fsreg]
4393               emit_fistp_m64(DRCTOP, FPR64ADDR(FDREG));                        // fistp [fdreg]
4394               return RECOMPILE_SUCCESSFUL_CP(1,4);
4395
4396            case 0x30:
4397            case 0x38:
4398               emit_mov_m8_imm(DRCTOP, CF1ADDR((op >> 8) & 7), 0);                  /* C.F.S/D */
4399               return RECOMPILE_SUCCESSFUL_CP(1,4);
4400
4401            case 0x31:
4402            case 0x39:
4403               emit_mov_m8_imm(DRCTOP, CF1ADDR((op >> 8) & 7), 0);                  /* C.UN.S/D */
4404               return RECOMPILE_SUCCESSFUL_CP(1,4);
4405
4406            case 0x32:
4407            case 0x3a:
4408               if (USE_SSE)
4409               {
4410                  if (IS_SINGLE(op))   /* C.EQ.S */
4411                  {
4412                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
4413                     emit_comiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // comiss xmm0,[ftreg]
4414                  }
4415                  else
4416                  {
4417                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4418                     emit_comisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // comisd xmm0,[ftreg]
4419                  }
4420                  emit_setcc_m8(DRCTOP, COND_E, CF1ADDR((op >> 8) & 7));             // sete [cf[x]]
4421               }
4422               else
4423               {
4424                  if (IS_SINGLE(op))   /* C.EQ.S */
4425                  {
4426                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4427                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4428                  }
4429                  else
4430                  {
4431                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4432                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4433                  }
4434                  emit_fcompp(DRCTOP);                                    // fcompp
4435                  emit_fstsw_ax(DRCTOP);                                    // fnstsw ax
4436                  emit_sahf(DRCTOP);                                       // sahf
4437                  emit_setcc_m8(DRCTOP, COND_E, CF1ADDR((op >> 8) & 7));             // sete [cf[x]]
4438               }
4439               return RECOMPILE_SUCCESSFUL_CP(1,4);
4440
4441            case 0x33:
4442            case 0x3b:
4443               if (USE_SSE)
4444               {
4445                  if (IS_SINGLE(op))   /* C.UEQ.S */
4446                  {
4447                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
4448                     emit_ucomiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // ucomiss xmm0,[ftreg]
4449                  }
4450                  else
4451                  {
4452                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4453                     emit_ucomisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // ucomisd xmm0,[ftreg]
4454                  }
4455                  emit_setcc_m8(DRCTOP, COND_E, CF1ADDR((op >> 8) & 7));             // sete [cf[x]]
4456               }
4457               else
4458               {
4459                  if (IS_SINGLE(op))   /* C.UEQ.S */
4460                  {
4461                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4462                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4463                  }
4464                  else
4465                  {
4466                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4467                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4468                  }
4469                  emit_fucompp(DRCTOP);                                    // fucompp
4470                  emit_fstsw_ax(DRCTOP);                                    // fnstsw ax
4471                  emit_sahf(DRCTOP);                                       // sahf
4472                  emit_setcc_m8(DRCTOP, COND_E, CF1ADDR((op >> 8) & 7));             // sete [cf[x]]
4473               }
4474               return RECOMPILE_SUCCESSFUL_CP(1,4);
4475
4476            case 0x34:
4477            case 0x3c:
4478               if (USE_SSE)
4479               {
4480                  if (IS_SINGLE(op))   /* C.OLT.S */
4481                  {
4482                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
4483                     emit_comiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // comiss xmm0,[ftreg]
4484                  }
4485                  else
4486                  {
4487                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4488                     emit_comisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // comisd xmm0,[ftreg]
4489                  }
4490                  emit_setcc_m8(DRCTOP, COND_B, CF1ADDR((op >> 8) & 7));             // setb [cf[x]]
4491               }
4492               else
4493               {
4494                  if (IS_SINGLE(op))   /* C.OLT.S */
4495                  {
4496                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4497                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4498                  }
4499                  else
4500                  {
4501                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4502                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4503                  }
4504                  emit_fcompp(DRCTOP);                                    // fcompp
4505                  emit_fstsw_ax(DRCTOP);                                    // fnstsw ax
4506                  emit_sahf(DRCTOP);                                       // sahf
4507                  emit_setcc_m8(DRCTOP, COND_B, CF1ADDR((op >> 8) & 7));             // setb [cf[x]]
4508               }
4509               return RECOMPILE_SUCCESSFUL_CP(1,4);
4510
4511            case 0x35:
4512            case 0x3d:
4513               if (USE_SSE)
4514               {
4515                  if (IS_SINGLE(op))   /* C.ULT.S */
4516                  {
4517                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
4518                     emit_ucomiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // ucomiss xmm0,[ftreg]
4519                  }
4520                  else
4521                  {
4522                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4523                     emit_ucomisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // ucomisd xmm0,[ftreg]
4524                  }
4525                  emit_setcc_m8(DRCTOP, COND_B, CF1ADDR((op >> 8) & 7));             // setb [cf[x]]
4526               }
4527               else
4528               {
4529                  if (IS_SINGLE(op))   /* C.ULT.S */
4530                  {
4531                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4532                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4533                  }
4534                  else
4535                  {
4536                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4537                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4538                  }
4539                  emit_fucompp(DRCTOP);                                    // fucompp
4540                  emit_fstsw_ax(DRCTOP);                                    // fnstsw ax
4541                  emit_sahf(DRCTOP);                                       // sahf
4542                  emit_setcc_m8(DRCTOP, COND_B, CF1ADDR((op >> 8) & 7));             // setb [cf[x]]
4543               }
4544               return RECOMPILE_SUCCESSFUL_CP(1,4);
4545
4546            case 0x36:
4547            case 0x3e:
4548               if (USE_SSE)
4549               {
4550                  if (IS_SINGLE(op))   /* C.OLE.S */
4551                  {
4552                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
4553                     emit_comiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // comiss xmm0,[ftreg]
4554                  }
4555                  else
4556                  {
4557                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4558                     emit_comisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // comisd xmm0,[ftreg]
4559                  }
4560                  emit_setcc_m8(DRCTOP, COND_BE, CF1ADDR((op >> 8) & 7));          // setle [cf[x]]
4561               }
4562               else
4563               {
4564                  if (IS_SINGLE(op))   /* C.OLE.S */
4565                  {
4566                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4567                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4568                  }
4569                  else
4570                  {
4571                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4572                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4573                  }
4574                  emit_fcompp(DRCTOP);                                    // fcompp
4575                  emit_fstsw_ax(DRCTOP);                                    // fnstsw ax
4576                  emit_sahf(DRCTOP);                                       // sahf
4577                  emit_setcc_m8(DRCTOP, COND_BE, CF1ADDR((op >> 8) & 7));          // setbe [cf[x]]
4578               }
4579               return RECOMPILE_SUCCESSFUL_CP(1,4);
4580
4581            case 0x37:
4582            case 0x3f:
4583               if (USE_SSE)
4584               {
4585                  if (IS_SINGLE(op))   /* C.ULE.S */
4586                  {
4587                     emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));      // movss xmm0,[fsreg]
4588                     emit_ucomiss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));      // ucomiss xmm0,[ftreg]
4589                  }
4590                  else
4591                  {
4592                     emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));      // movsd xmm0,[fsreg]
4593                     emit_ucomisd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));      // ucomisd xmm0,[ftreg]
4594                  }
4595                  emit_setcc_m8(DRCTOP, COND_BE, CF1ADDR((op >> 8) & 7));          // setl [cf[x]]
4596               }
4597               else
4598               {
4599                  if (IS_SINGLE(op))   /* C.ULE.S */
4600                  {
4601                     emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                     // fld  [ftreg]
4602                     emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                     // fld  [fsreg]
4603                  }
4604                  else
4605                  {
4606                     emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                     // fld  [ftreg]
4607                     emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                     // fld  [fsreg]
4608                  }
4609                  emit_fucompp(DRCTOP);                                    // fucompp
4610                  emit_fstsw_ax(DRCTOP);                                    // fnstsw ax
4611                  emit_sahf(DRCTOP);                                       // sahf
4612                  emit_setcc_m8(DRCTOP, COND_BE, CF1ADDR((op >> 8) & 7));          // setbe [cf[x]]
4613               }
4614               return RECOMPILE_SUCCESSFUL_CP(1,4);
4615         }
4616         break;
4617   }
4618   emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);               // jmp  generate_invalidop_exception
4619   return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
4620}
4621
4622
4623
4624/***************************************************************************
4625    COP1X RECOMPILATION
4626***************************************************************************/
4627
4628/*------------------------------------------------------------------
4629    recompile_cop1x
4630------------------------------------------------------------------*/
4631
4632static UINT32 recompile_cop1x(drc_core *drc, UINT32 pc, UINT32 op)
4633{
4634   if (mips3.drcoptions & MIPS3DRC_STRICT_COP1)
4635   {
4636      emit_test_m32_imm(DRCTOP, CPR0ADDR(COP0_Status), SR_COP1);                     // test [COP0_Status],SR_COP1
4637      emit_jcc(DRCTOP, COND_Z, mips3.drcdata->generate_cop_exception);               // jz   generate_cop_exception
4638   }
4639
4640   switch (op & 0x3f)
4641   {
4642      case 0x00:      /* LWXC1 */
4643         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
4644         emit_save_pc_before_call(DRCTOP);                                    // save pc
4645         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
4646         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg]
4647         emit_add_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                     // add  eax,[rtreg]
4648         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
4649         emit_call(DRCTOP, mips3.drcdata->read_and_translate_word);                  // call read_and_translate_word
4650         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
4651         emit_mov_m32_r32(DRCTOP, FPR32ADDR(FDREG), REG_EAX);                     // mov  [fdreg],eax
4652         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
4653         return RECOMPILE_SUCCESSFUL_CP(1,4);
4654
4655      case 0x01:      /* LDXC1 */
4656         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
4657         emit_save_pc_before_call(DRCTOP);                                    // save pc
4658         emit_sub_r32_imm(DRCTOP, REG_ESP, 8);                                 // sub  esp,8
4659         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg]
4660         emit_add_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                     // add  eax,[rtreg]
4661         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
4662         emit_call(DRCTOP, mips3.drcdata->read_and_translate_double);               // call read_and_translate_double
4663         emit_mov_m32_r32(DRCTOP, FPR64ADDRLO(FDREG), REG_EAX);                     // mov  [fdreg].lo,eax
4664         emit_mov_m32_r32(DRCTOP, FPR64ADDRHI(FDREG), REG_EDX);                     // mov  [fdreg].hi,edx
4665         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
4666         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
4667         return RECOMPILE_SUCCESSFUL_CP(1,4);
4668
4669      case 0x08:      /* SWXC1 */
4670         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
4671         emit_save_pc_before_call(DRCTOP);                                    // save pc
4672         emit_sub_r32_imm(DRCTOP, REG_ESP, 4);                                 // sub  esp,4
4673         emit_push_m32(DRCTOP, FPR32ADDR(FSREG));                              // push [fsreg]
4674         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg]
4675         emit_add_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                     // add  eax,[rtreg]
4676         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
4677         emit_call(DRCTOP, mips3.drcdata->write_and_translate_word);                  // call write_and_translate_word
4678         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,8
4679         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
4680         return RECOMPILE_SUCCESSFUL_CP(1,4);
4681
4682      case 0x09:      /* SDXC1 */
4683         emit_mov_m32_r32(DRCTOP, ICOUNTADDR, REG_EBP);                           // mov  [icount],ebp
4684         emit_save_pc_before_call(DRCTOP);                                    // save pc
4685         emit_push_m32(DRCTOP, FPR64ADDRHI(FSREG));                              // push [fsreg].hi
4686         emit_push_m32(DRCTOP, FPR64ADDRLO(FSREG));                              // push [fsreg].lo
4687         emit_mov_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RSREG));                     // mov  eax,[rsreg]
4688         emit_add_r32_m32(DRCTOP, REG_EAX, REGADDRLO(RTREG));                     // add  eax,[rtreg]
4689         emit_push_r32(DRCTOP, REG_EAX);                                       // push eax
4690         emit_call(DRCTOP, mips3.drcdata->write_and_translate_double);               // call write_and_translate_double
4691         emit_add_r32_imm(DRCTOP, REG_ESP, 12);                                 // add  esp,12
4692         emit_mov_r32_m32(DRCTOP, REG_EBP, ICOUNTADDR);                           // mov  ebp,[icount]
4693         return RECOMPILE_SUCCESSFUL_CP(1,4);
4694
4695      case 0x0f:      /* PREFX */
4696         return RECOMPILE_SUCCESSFUL_CP(1,4);
4697
4698      case 0x20:      /* MADD.S */
4699         if (USE_SSE)
4700         {
4701            emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));               // movss xmm0,[fsreg]
4702            emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));               // mulss xmm0,[ftreg]
4703            emit_addss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FRREG));               // addss xmm0,[frreg]
4704            emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);               // movss [fdreg],xmm0
4705         }
4706         else
4707         {
4708            emit_fld_m32(DRCTOP, FPR32ADDR(FRREG));                              // fld  [frreg]
4709            emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                              // fld  [fsreg]
4710            emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                              // fld  [ftreg]
4711            emit_fmulp(DRCTOP);                                             // fmulp
4712            emit_faddp(DRCTOP);                                             // faddp
4713            emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                           // fstp [fdreg]
4714         }
4715         return RECOMPILE_SUCCESSFUL_CP(1,4);
4716
4717      case 0x21:      /* MADD.D */
4718         if (USE_SSE)
4719         {
4720            emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));               // movsd xmm0,[fsreg]
4721            emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));               // mulsd xmm0,[ftreg]
4722            emit_addsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FRREG));               // addsd xmm0,[frreg]
4723            emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);               // movsd [fdreg],xmm0
4724         }
4725         else
4726         {
4727            emit_fld_m64(DRCTOP, FPR64ADDR(FRREG));                              // fld  [frreg]
4728            emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                              // fld  [fsreg]
4729            emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                              // fld  [ftreg]
4730            emit_fmulp(DRCTOP);                                             // fmulp
4731            emit_faddp(DRCTOP);                                             // faddp
4732            emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                           // fstp [fdreg]
4733         }
4734         return RECOMPILE_SUCCESSFUL_CP(1,4);
4735
4736      case 0x28:      /* MSUB.S */
4737         if (USE_SSE)
4738         {
4739            emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));               // movss xmm0,[fsreg]
4740            emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));               // mulss xmm0,[ftreg]
4741            emit_subss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FRREG));               // subss xmm0,[frreg]
4742            emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM0);               // movss [fdreg],xmm0
4743         }
4744         else
4745         {
4746            emit_fld_m32(DRCTOP, FPR32ADDR(FRREG));                              // fld  [frreg]
4747            emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                              // fld  [fsreg]
4748            emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                              // fld  [ftreg]
4749            emit_fmulp(DRCTOP);                                             // fmulp
4750            emit_fsubrp(DRCTOP);                                          // fsubrp
4751            emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                           // fstp [fdreg]
4752         }
4753         return RECOMPILE_SUCCESSFUL_CP(1,4);
4754
4755      case 0x29:      /* MSUB.D */
4756         if (USE_SSE)
4757         {
4758            emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));               // movsd xmm0,[fsreg]
4759            emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));               // mulsd xmm0,[ftreg]
4760            emit_subsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FRREG));               // subsd xmm0,[frreg]
4761            emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM0);               // movsd [fdreg],xmm0
4762         }
4763         else
4764         {
4765            emit_fld_m64(DRCTOP, FPR64ADDR(FRREG));                              // fld  [frreg]
4766            emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                              // fld  [fsreg]
4767            emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                              // fld  [ftreg]
4768            emit_fmulp(DRCTOP);                                             // fmulp
4769            emit_fsubrp(DRCTOP);                                          // fsubrp
4770            emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                           // fstp [fdreg]
4771         }
4772         return RECOMPILE_SUCCESSFUL_CP(1,4);
4773
4774      case 0x30:      /* NMADD.S */
4775         if (USE_SSE)
4776         {
4777            emit_xorps_r128_r128(DRCTOP, REG_XMM1, REG_XMM1);                     // xorps xmm1,xmm1
4778            emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));               // movss xmm0,[fsreg]
4779            emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));               // mulss xmm0,[ftreg]
4780            emit_addss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FRREG));               // addss xmm0,[frreg]
4781            emit_subss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0);                     // subss xmm1,xmm0
4782            emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM1);               // movss [fdreg],xmm1
4783         }
4784         else
4785         {
4786            emit_fld_m32(DRCTOP, FPR32ADDR(FRREG));                              // fld  [frreg]
4787            emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                              // fld  [fsreg]
4788            emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                              // fld  [ftreg]
4789            emit_fmulp(DRCTOP);                                             // fmulp
4790            emit_faddp(DRCTOP);                                             // faddp
4791            emit_fchs(DRCTOP);                                             // fchs
4792            emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                           // fstp [fdreg]
4793         }
4794         return RECOMPILE_SUCCESSFUL_CP(1,4);
4795
4796      case 0x31:      /* NMADD.D */
4797         if (USE_SSE)
4798         {
4799            emit_xorps_r128_r128(DRCTOP, REG_XMM1, REG_XMM1);                     // xorps xmm1,xmm1
4800            emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));               // movsd xmm0,[fsreg]
4801            emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));               // mulsd xmm0,[ftreg]
4802            emit_addsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FRREG));               // addsd xmm0,[frreg]
4803            emit_subss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0);                     // subss xmm1,xmm0
4804            emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM1);               // movsd [fdreg],xmm1
4805         }
4806         else
4807         {
4808            emit_fld_m64(DRCTOP, FPR64ADDR(FRREG));                              // fld  [frreg]
4809            emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                              // fld  [fsreg]
4810            emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                              // fld  [ftreg]
4811            emit_fmulp(DRCTOP);                                             // fmulp
4812            emit_faddp(DRCTOP);                                             // faddp
4813            emit_fchs(DRCTOP);                                             // fchs
4814            emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                           // fstp [fdreg]
4815         }
4816         return RECOMPILE_SUCCESSFUL_CP(1,4);
4817
4818      case 0x38:      /* NMSUB.S */
4819         if (USE_SSE)
4820         {
4821            emit_movss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FSREG));               // movss xmm0,[fsreg]
4822            emit_mulss_r128_m32(DRCTOP, REG_XMM0, FPR32ADDR(FTREG));               // mulss xmm0,[ftreg]
4823            emit_movss_r128_m32(DRCTOP, REG_XMM1, FPR32ADDR(FRREG));               // movss xmm1,[frreg]
4824            emit_subss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0);                     // subss xmm1,xmm0
4825            emit_movss_m32_r128(DRCTOP, FPR32ADDR(FDREG), REG_XMM1);               // movss [fdreg],xmm1
4826         }
4827         else
4828         {
4829            emit_fld_m32(DRCTOP, FPR32ADDR(FRREG));                              // fld  [frreg]
4830            emit_fld_m32(DRCTOP, FPR32ADDR(FSREG));                              // fld  [fsreg]
4831            emit_fld_m32(DRCTOP, FPR32ADDR(FTREG));                              // fld  [ftreg]
4832            emit_fmulp(DRCTOP);                                             // fmulp
4833            emit_fsubp(DRCTOP);                                             // fsubp
4834            emit_fstp_m32(DRCTOP, FPR32ADDR(FDREG));                           // fstp [fdreg]
4835         }
4836         return RECOMPILE_SUCCESSFUL_CP(1,4);
4837
4838      case 0x39:      /* NMSUB.D */
4839         if (USE_SSE)
4840         {
4841            emit_movsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FSREG));               // movsd xmm0,[fsreg]
4842            emit_mulsd_r128_m64(DRCTOP, REG_XMM0, FPR64ADDR(FTREG));               // mulsd xmm0,[ftreg]
4843            emit_movsd_r128_m64(DRCTOP, REG_XMM1, FPR64ADDR(FRREG));               // movsd xmm1,[frreg]
4844            emit_subss_r128_r128(DRCTOP, REG_XMM1, REG_XMM0);                     // subss xmm1,xmm0
4845            emit_movsd_m64_r128(DRCTOP, FPR64ADDR(FDREG), REG_XMM1);               // movsd [fdreg],xmm1
4846         }
4847         else
4848         {
4849            emit_fld_m64(DRCTOP, FPR64ADDR(FRREG));                              // fld  [frreg]
4850            emit_fld_m64(DRCTOP, FPR64ADDR(FSREG));                              // fld  [fsreg]
4851            emit_fld_m64(DRCTOP, FPR64ADDR(FTREG));                              // fld  [ftreg]
4852            emit_fmulp(DRCTOP);                                             // fmulp
4853            emit_fsubp(DRCTOP);                                             // fsubrp
4854            emit_fstp_m64(DRCTOP, FPR64ADDR(FDREG));                           // fstp [fdreg]
4855         }
4856         return RECOMPILE_SUCCESSFUL_CP(1,4);
4857
4858      case 0x24:      /* MADD.W */
4859      case 0x25:      /* MADD.L */
4860      case 0x2c:      /* MSUB.W */
4861      case 0x2d:      /* MSUB.L */
4862      case 0x34:      /* NMADD.W */
4863      case 0x35:      /* NMADD.L */
4864      case 0x3c:      /* NMSUB.W */
4865      case 0x3d:      /* NMSUB.L */
4866      default:
4867         fprintf(stderr, "cop1x %X\n", op);
4868         break;
4869   }
4870   emit_jmp(DRCTOP, (void *)mips3.drcdata->generate_invalidop_exception);               // jmp  generate_invalidop_exception
4871   return RECOMPILE_SUCCESSFUL | RECOMPILE_END_OF_STRING;
4872}
src/emu/cpu/mips/mips3drc.c
r2821r2822
117117#define CPR264(reg)            MEM(&mips3->cpr[2][reg])
118118#define CCR264(reg)            MEM(&mips3->ccr[2][reg])
119119
120#define FCCMASK(which)         fcc_mask[(mips3->flavor < MIPS3_TYPE_MIPS_IV) ? 0 : ((which) & 7)]
120#define FCCMASK(which)         ((UINT32)(1 << fcc_shift[(mips3->flavor < MIPS3_TYPE_MIPS_IV) ? 0 : ((which) & 7)]))
121#define FCCSHIFT(which)         fcc_shift[(mips3->flavor < MIPS3_TYPE_MIPS_IV) ? 0 : ((which) & 7)]
121122
122123
123124
r2821r2822
177178
178179   /* tables */
179180   UINT8            fpmode[4];               /* FPU mode table */
180   UINT64            slt_table[32];            /* FLAGS table for slt */
181   UINT64            sltu_table[32];            /* FLAGS table for sltu */
182   UINT32            c_un_table[32];            /* FLAGS table for c_un */
183   UINT32            c_eq_table[32];            /* FLAGS table for c_eq */
184   UINT32            c_ueq_table[32];         /* FLAGS table for c_ueq */
185   UINT32            c_olt_table[32];         /* FLAGS table for c_olt */
186   UINT32            c_ult_table[32];         /* FLAGS table for c_ult */
187   UINT32            c_ole_table[32];         /* FLAGS table for c_ole */
188   UINT32            c_ule_table[32];         /* FLAGS table for c_ule */
189181
190182   /* register mappings */
191183   drcuml_parameter   regmap[34];               /* parameter to register mappings for all 32 integer registers */
r2821r2822
270262
271263
272264/* bit indexes for various FCCs */
273static const UINT32 fcc_mask[8] = { 1 << 23, 1 << 25, 1 << 26, 1 << 27, 1 << 28, 1 << 29, 1 << 30, 1 << 31 };
265static const UINT8 fcc_shift[8] = { 23, 25, 26, 27, 28, 29, 30, 31 };
274266
275267/* lookup table for FP modes */
276268static const UINT8 fpmode_source[4] =
r2821r2822
281273   DRCUML_FMOD_FLOOR
282274};
283275
284/* flag lookup table for SLT */
285static const UINT64 slt_table_source[32] =
286{
287   /* ..... */   0,
288   /* ....C */   0,
289   /* ...V. */   1,
290   /* ...VC */   1,
291   /* ..Z.. */   0,
292   /* ..Z.C */   0,
293   /* ..ZV. */   1,
294   /* ..ZVC */   1,
295   /* .S... */   1,
296   /* .S..C */   1,
297   /* .S.V. */   0,
298   /* .S.VC */   0,
299   /* .SZ.. */   1,
300   /* .SZ.C */   1,
301   /* .SZV. */   0,
302   /* .SZVC */   0,
303   /* U.... */   0,
304   /* U...C */   0,
305   /* U..V. */   1,
306   /* U..VC */   1,
307   /* U.Z.. */   0,
308   /* U.Z.C */   0,
309   /* U.ZV. */   1,
310   /* U.ZVC */   1,
311   /* US... */   1,
312   /* US..C */   1,
313   /* US.V. */   0,
314   /* US.VC */   0,
315   /* USZ.. */   1,
316   /* USZ.C */   1,
317   /* USZV. */   0,
318   /* USZVC */   0
319};
320276
321/* flag lookup table for SLTU */
322static const UINT64 sltu_table_source[32] =
323{
324   /* ..... */   0,
325   /* ....C */   1,
326   /* ...V. */   0,
327   /* ...VC */   1,
328   /* ..Z.. */   0,
329   /* ..Z.C */   1,
330   /* ..ZV. */   0,
331   /* ..ZVC */   1,
332   /* .S... */   0,
333   /* .S..C */   1,
334   /* .S.V. */   0,
335   /* .S.VC */   1,
336   /* .SZ.. */   0,
337   /* .SZ.C */   1,
338   /* .SZV. */   0,
339   /* .SZVC */   1,
340   /* U.... */   0,
341   /* U...C */   1,
342   /* U..V. */   0,
343   /* U..VC */   1,
344   /* U.Z.. */   0,
345   /* U.Z.C */   1,
346   /* U.ZV. */   0,
347   /* U.ZVC */   1,
348   /* US... */   0,
349   /* US..C */   1,
350   /* US.V. */   0,
351   /* US.VC */   1,
352   /* USZ.. */   0,
353   /* USZ.C */   1,
354   /* USZV. */   0,
355   /* USZVC */   1
356};
357277
358/* flag lookup table for C.UN */
359static const UINT32 c_un_table_source[32] =
360{
361   /* ..... */   0,
362   /* ....C */   0,
363   /* ...V. */   0,
364   /* ...VC */   0,
365   /* ..Z.. */   0,
366   /* ..Z.C */   0,
367   /* ..ZV. */   0,
368   /* ..ZVC */   0,
369   /* .S... */   0,
370   /* .S..C */   0,
371   /* .S.V. */   0,
372   /* .S.VC */   0,
373   /* .SZ.. */   0,
374   /* .SZ.C */   0,
375   /* .SZV. */   0,
376   /* .SZVC */   0,
377   /* U.... */   ~0,
378   /* U...C */   ~0,
379   /* U..V. */   ~0,
380   /* U..VC */   ~0,
381   /* U.Z.. */   ~0,
382   /* U.Z.C */   ~0,
383   /* U.ZV. */   ~0,
384   /* U.ZVC */   ~0,
385   /* US... */   ~0,
386   /* US..C */   ~0,
387   /* US.V. */   ~0,
388   /* US.VC */   ~0,
389   /* USZ.. */   ~0,
390   /* USZ.C */   ~0,
391   /* USZV. */   ~0,
392   /* USZVC */   ~0
393};
394
395/* flag lookup table for C.EQ */
396static const UINT32 c_eq_table_source[32] =
397{
398   /* ..... */   0,
399   /* ....C */   0,
400   /* ...V. */   0,
401   /* ...VC */   0,
402   /* ..Z.. */   ~0,
403   /* ..Z.C */   ~0,
404   /* ..ZV. */   ~0,
405   /* ..ZVC */   ~0,
406   /* .S... */   0,
407   /* .S..C */   0,
408   /* .S.V. */   0,
409   /* .S.VC */   0,
410   /* .SZ.. */   ~0,
411   /* .SZ.C */   ~0,
412   /* .SZV. */   ~0,
413   /* .SZVC */   ~0,
414   /* U.... */   0,
415   /* U...C */   0,
416   /* U..V. */   0,
417   /* U..VC */   0,
418   /* U.Z.. */   0,
419   /* U.Z.C */   0,
420   /* U.ZV. */   0,
421   /* U.ZVC */   0,
422   /* US... */   0,
423   /* US..C */   0,
424   /* US.V. */   0,
425   /* US.VC */   0,
426   /* USZ.. */   0,
427   /* USZ.C */   0,
428   /* USZV. */   0,
429   /* USZVC */   0
430};
431
432/* flag lookup table for C.UEQ */
433static const UINT32 c_ueq_table_source[32] =
434{
435   /* ..... */   0,
436   /* ....C */   0,
437   /* ...V. */   0,
438   /* ...VC */   0,
439   /* ..Z.. */   ~0,
440   /* ..Z.C */   ~0,
441   /* ..ZV. */   ~0,
442   /* ..ZVC */   ~0,
443   /* .S... */   0,
444   /* .S..C */   0,
445   /* .S.V. */   0,
446   /* .S.VC */   0,
447   /* .SZ.. */   ~0,
448   /* .SZ.C */   ~0,
449   /* .SZV. */   ~0,
450   /* .SZVC */   ~0,
451   /* U.... */   ~0,
452   /* U...C */   ~0,
453   /* U..V. */   ~0,
454   /* U..VC */   ~0,
455   /* U.Z.. */   ~0,
456   /* U.Z.C */   ~0,
457   /* U.ZV. */   ~0,
458   /* U.ZVC */   ~0,
459   /* US... */   ~0,
460   /* US..C */   ~0,
461   /* US.V. */   ~0,
462   /* US.VC */   ~0,
463   /* USZ.. */   ~0,
464   /* USZ.C */   ~0,
465   /* USZV. */   ~0,
466   /* USZVC */   ~0
467};
468
469/* flag lookup table for C.OLT */
470static const UINT32 c_olt_table_source[32] =
471{
472   /* ..... */   0,
473   /* ....C */   ~0,
474   /* ...V. */   0,
475   /* ...VC */   ~0,
476   /* ..Z.. */   0,
477   /* ..Z.C */   ~0,
478   /* ..ZV. */   0,
479   /* ..ZVC */   ~0,
480   /* .S... */   0,
481   /* .S..C */   ~0,
482   /* .S.V. */   0,
483   /* .S.VC */   ~0,
484   /* .SZ.. */   0,
485   /* .SZ.C */   ~0,
486   /* .SZV. */   0,
487   /* .SZVC */   ~0,
488   /* U.... */   0,
489   /* U...C */   0,
490   /* U..V. */   0,
491   /* U..VC */   0,
492   /* U.Z.. */   0,
493   /* U.Z.C */   0,
494   /* U.ZV. */   0,
495   /* U.ZVC */   0,
496   /* US... */   0,
497   /* US..C */   0,
498   /* US.V. */   0,
499   /* US.VC */   0,
500   /* USZ.. */   0,
501   /* USZ.C */   0,
502   /* USZV. */   0,
503   /* USZVC */   0
504};
505
506/* flag lookup table for C.ULT */
507static const UINT32 c_ult_table_source[32] =
508{
509   /* ..... */   0,
510   /* ....C */   ~0,
511   /* ...V. */   0,
512   /* ...VC */   ~0,
513   /* ..Z.. */   0,
514   /* ..Z.C */   ~0,
515   /* ..ZV. */   0,
516   /* ..ZVC */   ~0,
517   /* .S... */   0,
518   /* .S..C */   ~0,
519   /* .S.V. */   0,
520   /* .S.VC */   ~0,
521   /* .SZ.. */   0,
522   /* .SZ.C */   ~0,
523   /* .SZV. */   0,
524   /* .SZVC */   ~0,
525   /* U.... */   ~0,
526   /* U...C */   ~0,
527   /* U..V. */   ~0,
528   /* U..VC */   ~0,
529   /* U.Z.. */   ~0,
530   /* U.Z.C */   ~0,
531   /* U.ZV. */   ~0,
532   /* U.ZVC */   ~0,
533   /* US... */   ~0,
534   /* US..C */   ~0,
535   /* US.V. */   ~0,
536   /* US.VC */   ~0,
537   /* USZ.. */   ~0,
538   /* USZ.C */   ~0,
539   /* USZV. */   ~0,
540   /* USZVC */   ~0
541};
542
543/* flag lookup table for C.OLE */
544static const UINT32 c_ole_table_source[32] =
545{
546   /* ..... */   0,
547   /* ....C */   ~0,
548   /* ...V. */   0,
549   /* ...VC */   ~0,
550   /* ..Z.. */   ~0,
551   /* ..Z.C */   ~0,
552   /* ..ZV. */   ~0,
553   /* ..ZVC */   ~0,
554   /* .S... */   0,
555   /* .S..C */   ~0,
556   /* .S.V. */   0,
557   /* .S.VC */   ~0,
558   /* .SZ.. */   ~0,
559   /* .SZ.C */   ~0,
560   /* .SZV. */   ~0,
561   /* .SZVC */   ~0,
562   /* U.... */   0,
563   /* U...C */   0,
564   /* U..V. */   0,
565   /* U..VC */   0,
566   /* U.Z.. */   0,
567   /* U.Z.C */   0,
568   /* U.ZV. */   0,
569   /* U.ZVC */   0,
570   /* US... */   0,
571   /* US..C */   0,
572   /* US.V. */   0,
573   /* US.VC */   0,
574   /* USZ.. */   0,
575   /* USZ.C */   0,
576   /* USZV. */   0,
577   /* USZVC */   0
578};
579
580/* flag lookup table for C.ULE */
581static const UINT32 c_ule_table_source[32] =
582{
583   /* ..... */   0,
584   /* ....C */   ~0,
585   /* ...V. */   0,
586   /* ...VC */   ~0,
587   /* ..Z.. */   ~0,
588   /* ..Z.C */   ~0,
589   /* ..ZV. */   ~0,
590   /* ..ZVC */   ~0,
591   /* .S... */   0,
592   /* .S..C */   ~0,
593   /* .S.V. */   0,
594   /* .S.VC */   ~0,
595   /* .SZ.. */   ~0,
596   /* .SZ.C */   ~0,
597   /* .SZV. */   ~0,
598   /* .SZVC */   ~0,
599   /* U.... */   ~0,
600   /* U...C */   ~0,
601   /* U..V. */   ~0,
602   /* U..VC */   ~0,
603   /* U.Z.. */   ~0,
604   /* U.Z.C */   ~0,
605   /* U.ZV. */   ~0,
606   /* U.ZVC */   ~0,
607   /* US... */   ~0,
608   /* US..C */   ~0,
609   /* US.V. */   ~0,
610   /* US.VC */   ~0,
611   /* USZ.. */   ~0,
612   /* USZ.C */   ~0,
613   /* USZV. */   ~0,
614   /* USZVC */   ~0
615};
616
617
618
619278/***************************************************************************
620279    INLINE FUNCTIONS
621280***************************************************************************/
r2821r2822
738397
739398   /* allocate memory for cache-local state and initialize it */
740399   memcpy(mips3->impstate->fpmode, fpmode_source, sizeof(fpmode_source));
741   memcpy(mips3->impstate->slt_table, slt_table_source, sizeof(slt_table_source));
742   memcpy(mips3->impstate->sltu_table, sltu_table_source, sizeof(sltu_table_source));
743   memcpy(mips3->impstate->c_un_table, c_un_table_source, sizeof(c_un_table_source));
744   memcpy(mips3->impstate->c_eq_table, c_eq_table_source, sizeof(c_eq_table_source));
745   memcpy(mips3->impstate->c_ueq_table, c_ueq_table_source, sizeof(c_ueq_table_source));
746   memcpy(mips3->impstate->c_olt_table, c_olt_table_source, sizeof(c_olt_table_source));
747   memcpy(mips3->impstate->c_ult_table, c_ult_table_source, sizeof(c_ult_table_source));
748   memcpy(mips3->impstate->c_ole_table, c_ole_table_source, sizeof(c_ole_table_source));
749   memcpy(mips3->impstate->c_ule_table, c_ule_table_source, sizeof(c_ule_table_source));
750400
751401   /* compute the register parameters */
752402   for (regnum = 0; regnum < 34; regnum++)
r2821r2822
1259909
1260910   /* reset the FPU mode */
1261911   UML_AND(block, IREG(0), CCR132(31), IMM(3));                           // and     i0,ccr1[31],3
1262   UML_LOAD1U(block, IREG(0), &mips3->impstate->fpmode[0], IREG(0));            // load1u  i0,fpmode,i0
912   UML_LOAD(block, IREG(0), &mips3->impstate->fpmode[0], IREG(0), BYTE);         // load    i0,fpmode,i0,byte
1263913   UML_SETFMOD(block, IREG(0));                                       // setfmod i0
1264914
1265915   /* load fast integer registers */
r2821r2822
13701020   UML_RECOVER(block, IREG(0), MAPVAR_PC);                                 // recover i0,PC
13711021   UML_MOV(block, MEM(&mips3->pc), IREG(0));                              // mov     <pc>,i0
13721022   UML_SHR(block, IREG(1), IREG(0), IMM(12));                              // shr     i1,i0,12
1373   UML_LOAD4(block, IREG(1), mips3->tlb_table, IREG(1));                     // load4   i1,[tlb_table],i1
1023   UML_LOAD(block, IREG(1), mips3->tlb_table, IREG(1), DWORD);                  // load    i1,[tlb_table],i1,dword
13741024   if (PRINTF_MMU)
13751025   {
13761026      UML_MOV(block, MEM(&mips3->impstate->arg0), IREG(0));                  // mov     [arg0],i0
r2821r2822
14331083   if (exception == EXCEPTION_TLBLOAD || exception == EXCEPTION_TLBSTORE)
14341084   {
14351085      /* set the upper bits of EntryHi and the lower bits of Context to the fault page */
1436      UML_INSERT(block, CPR032(COP0_EntryHi), IREG(0), IMM(0), IMM(0xffffe000));   // insert  [EntryHi],i0,0,0xffffe000
1437      UML_INSERT(block, CPR032(COP0_Context), IREG(0), IMM(32-9), IMM(0x7fffff));   // insert  [Context],i0,32-9,0x7fffff
1086      UML_ROLINS(block, CPR032(COP0_EntryHi), IREG(0), IMM(0), IMM(0xffffe000));   // rolins  [EntryHi],i0,0,0xffffe000
1087      UML_ROLINS(block, CPR032(COP0_Context), IREG(0), IMM(32-9), IMM(0x7fffff));   // rolins  [Context],i0,32-9,0x7fffff
14381088   }
14391089
14401090   /* set the EPC and Cause registers */
r2821r2822
14541104   UML_MOVc(block, IF_Z, CPR032(COP0_EPC), IREG(0));                        // mov     [EPC],i0,Z
14551105   UML_OR(block, CPR032(COP0_Cause), IREG(2), IMM(exception << 2));            // or      [Cause],i2,exception << 2
14561106
1107   /* for BADCOP exceptions, we use the exception parameter to know which COP */
1108   if (exception == EXCEPTION_BADCOP)
1109   {
1110      UML_GETEXP(block, IREG(0));                                       // getexp  i0
1111      UML_ROLINS(block, CPR032(COP0_Cause), IREG(0), IMM(28), IMM(0x30000000));   // rolins  [Cause],i0,28,0x30000000
1112   }
1113
14571114   /* set EXL in the SR */
14581115   UML_OR(block, IREG(0), CPR032(COP0_Status), IMM(SR_EXL));                  // or      i0,[Status],SR_EXL
14591116   UML_MOV(block, CPR032(COP0_Status), IREG(0));                           // mov     [Status],i0
r2821r2822
15291186
15301187   /* general case: assume paging and perform a translation */
15311188   UML_SHR(block, IREG(3), IREG(0), IMM(12));                              // shr     i3,i0,12
1532   UML_LOAD4(block, IREG(3), mips3->tlb_table, IREG(3));                     // load4   i3,[tlb_table],i3
1189   UML_LOAD(block, IREG(3), mips3->tlb_table, IREG(3), DWORD);                  // load    i3,[tlb_table],i3,dword
15331190   UML_TEST(block, IREG(3), IMM(iswrite ? TLB_DIRTY : TLB_VALID));               // test    i3,iswrite ? TLB_DIRTY : TLB_VALID
15341191   UML_JMPc(block, IF_Z, tlbmiss = label++);                              // jmp     tlbmiss,z
1535   UML_INSERT(block, IREG(0), IREG(3), IMM(0), IMM(0xfffff000));               // insert  i0,i3,0,0xfffff000
1192   UML_ROLINS(block, IREG(0), IREG(3), IMM(0), IMM(0xfffff000));               // rolins  i0,i3,0,0xfffff000
15361193
15371194   for (ramnum = 0; ramnum < MIPS3_MAX_FASTRAM; ramnum++)
15381195      if (!Machine->debug_mode && mips3->impstate->fastram[ramnum].base != NULL && (!iswrite || !mips3->impstate->fastram[ramnum].readonly))
r2821r2822
15561213            {
15571214               UML_XOR(block, IREG(0), IREG(0), IMM(mips3->bigendian ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0)));
15581215                                                               // xor     i0,i0,bytexor
1559               UML_LOAD1U(block, IREG(0), fastbase, IREG(0));               // load1u  i0,fastbase,i0
1216               UML_LOAD(block, IREG(0), fastbase, IREG(0), BYTE);            // load    i0,fastbase,i0,byte
15601217            }
15611218            else if (size == 2)
15621219            {
15631220               UML_SHR(block, IREG(0), IREG(0), IMM(1));                  // shr     i0,i0,1
15641221               UML_XOR(block, IREG(0), IREG(0), IMM(mips3->bigendian ? BYTE_XOR_BE(0) : BYTE_XOR_LE(0)));
15651222                                                               // xor     i0,i0,bytexor
1566               UML_LOAD2U(block, IREG(0), fastbase, IREG(0));               // load2u  i0,fastbase,i0
1223               UML_LOAD(block, IREG(0), fastbase, IREG(0), WORD);            // load    i0,fastbase,i0,word
15671224            }
15681225            else if (size == 4)
15691226            {
15701227               UML_SHR(block, IREG(0), IREG(0), IMM(2));                  // shr     i0,i0,2
1571               UML_LOAD4(block, IREG(0), fastbase, IREG(0));               // load4   i0,fastbase,i0
1228               UML_LOAD(block, IREG(0), fastbase, IREG(0), DWORD);            // load    i0,fastbase,i0,dword
15721229            }
15731230            else if (size == 8)
15741231            {
15751232               UML_SHR(block, IREG(0), IREG(0), IMM(3));                  // shr     i0,i0,3
1576               UML_DLOAD8(block, IREG(0), fastbase, IREG(0));               // dload8  i0,fastbase,i0
1233               UML_DLOAD(block, IREG(0), fastbase, IREG(0), QWORD);         // dload  i0,fastbase,i0,qword
15771234               UML_DROR(block, IREG(0), IREG(0), IMM(32 * (mips3->bigendian ? BYTE_XOR_BE(0) : BYTE_XOR_LE(0))));
15781235                                                               // dror    i0,i0,32*bytexor
15791236            }
r2821r2822
15851242            {
15861243               UML_XOR(block, IREG(0), IREG(0), IMM(mips3->bigendian ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0)));
15871244                                                               // xor     i0,i0,bytexor
1588               UML_STORE1(block, fastbase, IREG(0), IREG(1));               // store1  fastbase,i0,i1
1245               UML_STORE(block, fastbase, IREG(0), IREG(1), BYTE);            // store  fastbase,i0,i1,byte
15891246            }
15901247            else if (size == 2)
15911248            {
15921249               UML_SHR(block, IREG(0), IREG(0), IMM(1));                  // shr     i0,i0,1
15931250               UML_XOR(block, IREG(0), IREG(0), IMM(mips3->bigendian ? BYTE_XOR_BE(0) : BYTE_XOR_LE(0)));
15941251                                                               // xor     i0,i0,bytexor
1595               UML_STORE2(block, fastbase, IREG(0), IREG(1));               // store2  fastbase,i0,i1
1252               UML_STORE(block, fastbase, IREG(0), IREG(1), WORD);            // store  fastbase,i0,i1,word
15961253            }
15971254            else if (size == 4)
15981255            {
15991256               UML_SHR(block, IREG(0), IREG(0), IMM(2));                  // shr     i0,i0,2
16001257               if (ismasked)
16011258               {
1602                  UML_LOAD4(block, IREG(3), fastbase, IREG(0));            // load4   i3,fastbase,i0
1603                  UML_INSERT(block, IREG(3), IREG(1), IMM(0), IREG(2));      // insert  i3,i1,0,i2
1604                  UML_STORE4(block, fastbase, IREG(0), IREG(3));            // store4  fastbase,i0,i3
1259                  UML_LOAD(block, IREG(3), fastbase, IREG(0), DWORD);         // load    i3,fastbase,i0,dword
1260                  UML_ROLINS(block, IREG(3), IREG(1), IMM(0), IREG(2));      // rolins  i3,i1,0,i2
1261                  UML_STORE(block, fastbase, IREG(0), IREG(3), DWORD);      // store   fastbase,i0,i3,dword
16051262               }
16061263               else
1607                  UML_STORE4(block, fastbase, IREG(0), IREG(1));            // store4  fastbase,i0,i1
1264                  UML_STORE(block, fastbase, IREG(0), IREG(1), DWORD);      // store  fastbase,i0,i1,dword
16081265            }
16091266            else if (size == 8)
16101267            {
r2821r2822
16151272               {
16161273                  UML_DROR(block, IREG(2), IREG(2), IMM(32 * (mips3->bigendian ? BYTE_XOR_BE(0) : BYTE_XOR_LE(0))));
16171274                                                               // dror    i2,i2,32*bytexor
1618                  UML_DLOAD8(block, IREG(3), fastbase, IREG(0));            // dload8  i3,fastbase,i0
1619                  UML_DINSERT(block, IREG(3), IREG(1), IMM(0), IREG(2));      // dinsert i3,i1,0,i2
1620                  UML_DSTORE8(block, fastbase, IREG(0), IREG(3));            // dstore8 fastbase,i0,i3
1275                  UML_DLOAD(block, IREG(3), fastbase, IREG(0), QWORD);      // dload   i3,fastbase,i0,qword
1276                  UML_DROLINS(block, IREG(3), IREG(1), IMM(0), IREG(2));      // drolins i3,i1,0,i2
1277                  UML_DSTORE(block, fastbase, IREG(0), IREG(3), QWORD);      // dstore  fastbase,i0,i3,qword
16211278               }
16221279               else
1623                  UML_DSTORE8(block, fastbase, IREG(0), IREG(1));            // dstore8 fastbase,i0,i1
1280                  UML_DSTORE(block, fastbase, IREG(0), IREG(1), QWORD);      // dstore fastbase,i0,i1,qword
16241281            }
16251282            UML_RET(block);                                          // ret
16261283         }
r2821r2822
16321289   {
16331290      case 1:
16341291         if (iswrite)
1635            UML_WRITE1(block, PROGRAM, IREG(0), IREG(1));                  // write1  i0,i1
1292            UML_WRITE(block, IREG(0), IREG(1), PROGRAM_BYTE);               // write  i0,i1,program_byte
16361293         else
1637            UML_READ1U(block, IREG(0), PROGRAM, IREG(0));                  // read1u  i0,i0
1294            UML_READ(block, IREG(0), IREG(0), PROGRAM_BYTE);               // read    i0,i0,program_byte
16381295         break;
16391296
16401297      case 2:
16411298         if (iswrite)
1642            UML_WRITE2(block, PROGRAM, IREG(0), IREG(1));                  // write2  i0,i1
1299            UML_WRITE(block, IREG(0), IREG(1), PROGRAM_WORD);               // write  i0,i1,program_word
16431300         else
1644            UML_READ2U(block, IREG(0), PROGRAM, IREG(0));                  // read2u  i0,i0
1301            UML_READ(block, IREG(0), IREG(0), PROGRAM_WORD);               // read    i0,i0,program_word
16451302         break;
16461303
16471304      case 4:
16481305         if (iswrite)
16491306         {
16501307            if (!ismasked)
1651               UML_WRITE4(block, PROGRAM, IREG(0), IREG(1));               // write4  PROGRAM,i0,i1
1308               UML_WRITE(block, IREG(0), IREG(1), PROGRAM_DWORD);            // write  i0,i1,program_dword
16521309            else
1653               UML_WRIT4M(block, PROGRAM, IREG(0), IREG(2), IREG(1));         // writ4m  PROGRAM,i0,i2,i1
1310               UML_WRITEM(block, IREG(0), IREG(2), IREG(1), PROGRAM_DWORD);   // writem  i0,i2,i1,program_dword
16541311         }
16551312         else
16561313         {
16571314            if (!ismasked)
1658               UML_READ4(block, IREG(0), PROGRAM, IREG(0));               // read4   i0,PROGRAM,i0
1315               UML_READ(block, IREG(0), IREG(0), PROGRAM_DWORD);            // read    i0,i0,program_dword
16591316            else
1660               UML_READ4M(block, IREG(0), PROGRAM, IREG(0), IREG(2));         // read4m  i0,PROGRAM,i0,i2
1317               UML_READM(block, IREG(0), IREG(0), IREG(2), PROGRAM_DWORD);      // readm  i0,i0,i2,program_dword
16611318         }
16621319         break;
16631320
r2821r2822
16651322         if (iswrite)
16661323         {
16671324            if (!ismasked)
1668               UML_DWRITE8(block, PROGRAM, IREG(0), IREG(1));               // dwrite8 PROGRAM,i0,i1
1325               UML_DWRITE(block, IREG(0), IREG(1), PROGRAM_QWORD);            // dwrite i0,i1,program_qword
16691326            else
1670               UML_DWRIT8M(block, PROGRAM, IREG(0), IREG(2), IREG(1));         // dwrit8m PROGRAM,i0,i2,i1
1327               UML_DWRITEM(block, IREG(0), IREG(2), IREG(1), PROGRAM_QWORD);   // dwritem i0,i2,i1,program_qword
16711328         }
16721329         else
16731330         {
16741331            if (!ismasked)
1675               UML_DREAD8(block, IREG(0), PROGRAM, IREG(0));               // dread8  i0,PROGRAM,i0
1332               UML_DREAD(block, IREG(0), IREG(0), PROGRAM_QWORD);            // dread  i0,i0,program_qword
16761333            else
1677               UML_DREAD8M(block, IREG(0), PROGRAM, IREG(0), IREG(2));         // dread8m i0,PROGRAM,i0,i2
1334               UML_DREADM(block, IREG(0), IREG(0), IREG(2), PROGRAM_QWORD);   // dreadm i0,i0,i2,program_qword
16781335         }
16791336         break;
16801337   }
r2821r2822
17101367
17111368static void generate_update_mode(drcuml_block *block)
17121369{
1713   UML_XTRACT(block, IREG(2), IREG(0), IMM(32-2), IMM(0x06));                  // xtract  i2,i0,32-2,0x06
1370   UML_ROLAND(block, IREG(2), IREG(0), IMM(32-2), IMM(0x06));                  // roland  i2,i0,32-2,0x06
17141371   UML_TEST(block, IREG(0), IMM(SR_EXL | SR_ERL));                           // test    i0,SR_EXL | SR_ERL
17151372   UML_MOVc(block, IF_NZ, IREG(2), IMM(0));                              // mov     i2,0,nz
1716   UML_INSERT(block, IREG(2), IREG(0), IMM(32-26), IMM(0x01));                  // insert  i2,i0,32-26,0x01
1373   UML_ROLINS(block, IREG(2), IREG(0), IMM(32-26), IMM(0x01));                  // rolins  i2,i0,32-26,0x01
17171374   UML_MOV(block, MEM(&mips3->impstate->mode), IREG(2));                     // mov     [mode],i2
17181375}
17191376
r2821r2822
17901447   {
17911448      if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
17921449      {
1793         UML_LOAD4(block, IREG(0), seqhead->opptr.l, IMM(0));               // load4   i0,*opptr
1450         UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD);            // load    i0,*opptr,0,dword
17941451         UML_CMP(block, IREG(0), IMM(*seqhead->opptr.l));                  // cmp     i0,*opptr
17951452         UML_EXHc(block, IF_NE, mips3->impstate->nocode, IMM(epc(seqhead)));      // exne    nocode,seqhead->pc
17961453      }
r2821r2822
18031460      for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
18041461         if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
18051462         {
1806            UML_LOAD4(block, IREG(0), curdesc->opptr.l, IMM(0));            // load4   i0,*opptr
1463            UML_LOAD(block, IREG(0), curdesc->opptr.l, IMM(0), DWORD);         // load    i0,*opptr,0,dword
18071464            UML_CMP(block, IREG(0), IMM(*curdesc->opptr.l));               // cmp     i0,*opptr
18081465            UML_EXHc(block, IF_NE, mips3->impstate->nocode, IMM(epc(seqhead)));   // exne    nocode,seqhead->pc
18091466         }
18101467#else
18111468      UINT32 sum = 0;
1812      UML_LOAD4(block, IREG(0), seqhead->opptr.l, IMM(0));                  // load4   i0,*opptr
1469      UML_LOAD(block, IREG(0), seqhead->opptr.l, IMM(0), DWORD);               // load    i0,*opptr,0,dword
18131470      sum += *seqhead->opptr.l;
18141471      for (curdesc = seqhead->next; curdesc != seqlast->next; curdesc = curdesc->next)
18151472         if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
18161473         {
1817            UML_LOAD4(block, IREG(1), curdesc->opptr.l, IMM(0));            // load4   i1,*opptr
1474            UML_LOAD(block, IREG(1), curdesc->opptr.l, IMM(0), DWORD);         // load    i1,*opptr,dword
18181475            UML_ADD(block, IREG(0), IREG(0), IREG(1));                     // add     i0,i0,i1
18191476            sum += *curdesc->opptr.l;
18201477         }
r2821r2822
18991556            UML_MOV(block, MEM(&mips3->impstate->arg0), IMM(desc->pc));         // mov     [arg0],desc->pc
19001557            UML_CALLC(block, cfunc_printf_debug, "Checking TLB at @ %08X\n");   // callc   printf_debug
19011558         }
1902         UML_LOAD4(block, IREG(0), &mips3->tlb_table[desc->pc >> 12], IMM(0));   // load4   i0,tlb_table[desc->pc >> 12]
1559         UML_LOAD(block, IREG(0), &mips3->tlb_table[desc->pc >> 12], IMM(0), DWORD);// load i0,tlb_table[desc->pc >> 12],0,dword
19031560         UML_CMP(block, IREG(0), IMM(mips3->tlb_table[desc->pc >> 12]));         // cmp     i0,*tlbentry
19041561         UML_EXHc(block, IF_NE, mips3->impstate->tlb_mismatch, IMM(0));         // exh     tlb_mismatch,0,NE
19051562      }
r2821r2822
19441601
19451602   /* set the link if needed */
19461603   if (linkreg != 0)
1947      UML_DSEXT4(block, R64(linkreg), IMM((INT32)(desc->pc + 8)));            // dsext4  <linkreg>,desc->pc + 8
1604      UML_DMOV(block, R64(linkreg), IMM((INT32)(desc->pc + 8)));               // dmov    <linkreg>,desc->pc + 8
19481605
19491606   /* compile the delay slot using temporary compiler state */
19501607   assert(desc->delay != NULL);
r2821r2822
20541711
20551712      case 0x0f:   /* LUI - MIPS I */
20561713         if (RTREG != 0)
2057            UML_DSEXT4(block, R64(RTREG), IMM(SIMMVAL << 16));               // dsext4  <rtreg>,SIMMVAL << 16
1714            UML_DMOV(block, R64(RTREG), IMM(SIMMVAL << 16));               // dmov    <rtreg>,SIMMVAL << 16
20581715         return TRUE;
20591716
20601717      case 0x08:   /* ADDI - MIPS I */
r2821r2822
20671724         else
20681725            UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));               // add     i0,<rsreg>,SIMMVAL
20691726         if (RTREG != 0)
2070            UML_DSEXT4(block, R64(RTREG), IREG(0));                        // dsext4  <rtreg>,i0
1727            UML_DSEXT(block, R64(RTREG), IREG(0), DWORD);                  // dsext  <rtreg>,i0,dword
20711728         return TRUE;
20721729
20731730      case 0x09:   /* ADDIU - MIPS I */
20741731         if (RTREG != 0)
20751732         {
20761733            UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));               // add     i0,<rsreg>,SIMMVAL,V
2077            UML_DSEXT4(block, R64(RTREG), IREG(0));                        // dsext4  <rtreg>,i0
1734            UML_DSEXT(block, R64(RTREG), IREG(0), DWORD);                  // dsext  <rtreg>,i0,dword
20781735         }
20791736         return TRUE;
20801737
r2821r2822
21151772         if (RTREG != 0)
21161773         {
21171774            UML_DCMP(block, R64(RSREG), IMM(SIMMVAL));                     // dcmp    <rsreg>,SIMMVAL
2118            UML_DFLAGS(block, R64(RTREG), (UINT64)~0, mips3->impstate->slt_table);
2119                                                               // dflags  <rtreg>,~0,slt_table
1775            UML_DSETc(block, IF_L, R64(RTREG));                           // dset    <rtreg>,l
21201776         }
21211777         return TRUE;
21221778
r2821r2822
21241780         if (RTREG != 0)
21251781         {
21261782            UML_DCMP(block, R64(RSREG), IMM(SIMMVAL));                     // dcmp    <rsreg>,SIMMVAL
2127            UML_DFLAGS(block, R64(RTREG), (UINT64)~0, mips3->impstate->sltu_table);
2128                                                               // dflags  <rtreg>,~0,sltu_table
1783            UML_DSETc(block, IF_B, R64(RTREG));                           // dset    <rtreg>,b
21291784         }
21301785         return TRUE;
21311786
r2821r2822
21361791         UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));                  // add     i0,<rsreg>,SIMMVAL
21371792         UML_CALLH(block, mips3->impstate->read8[mips3->impstate->mode >> 1]);   // callh   read8
21381793         if (RTREG != 0)
2139            UML_DSEXT1(block, R64(RTREG), IREG(0));                        // dsext1  <rtreg>,i0
1794            UML_DSEXT(block, R64(RTREG), IREG(0), BYTE);                  // dsext  <rtreg>,i0,byte
21401795         if (!in_delay_slot)
21411796            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
21421797         return TRUE;
r2821r2822
21451800         UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));                  // add     i0,<rsreg>,SIMMVAL
21461801         UML_CALLH(block, mips3->impstate->read16[mips3->impstate->mode >> 1]);   // callh   read16
21471802         if (RTREG != 0)
2148            UML_DSEXT2(block, R64(RTREG), IREG(0));                        // dsext2  <rtreg>,i0
1803            UML_DSEXT(block, R64(RTREG), IREG(0), WORD);                  // dsext  <rtreg>,i0,word
21491804         if (!in_delay_slot)
21501805            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
21511806         return TRUE;
r2821r2822
21541809         UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));                  // add     i0,<rsreg>,SIMMVAL
21551810         UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]);   // callh   read32
21561811         if (RTREG != 0)
2157            UML_DSEXT4(block, R64(RTREG), IREG(0));                        // dsext4  <rtreg>,i0
1812            UML_DSEXT(block, R64(RTREG), IREG(0), DWORD);                  // dsext   <rtreg>,i0
21581813         if (!in_delay_slot)
21591814            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
21601815         return TRUE;
r2821r2822
21631818         UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));                  // add     i0,<rsreg>,SIMMVAL
21641819         UML_CALLH(block, mips3->impstate->read8[mips3->impstate->mode >> 1]);   // callh   read8
21651820         if (RTREG != 0)
2166            UML_DZEXT1(block, R64(RTREG), IREG(0));                        // dzext1  <rtreg>,i0
1821            UML_DAND(block, R64(RTREG), IREG(0), IMM(0xff));               // dand    <rtreg>,i0,0xff
21671822         if (!in_delay_slot)
21681823            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
21691824         return TRUE;
r2821r2822
21721827         UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));                  // add     i0,<rsreg>,SIMMVAL
21731828         UML_CALLH(block, mips3->impstate->read16[mips3->impstate->mode >> 1]);   // callh   read16
21741829         if (RTREG != 0)
2175            UML_DZEXT2(block, R64(RTREG), IREG(0));                        // dzext2  <rtreg>,i0
1830            UML_DAND(block, R64(RTREG), IREG(0), IMM(0xffff));               // dand    <rtreg>,i0,0xffff
21761831         if (!in_delay_slot)
21771832            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
21781833         return TRUE;
r2821r2822
21811836         UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));                  // add     i0,<rsreg>,SIMMVAL
21821837         UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]);   // callh   read32
21831838         if (RTREG != 0)
2184            UML_DZEXT4(block, R64(RTREG), IREG(0));                        // dzext4  <rtreg>,i0
1839            UML_DAND(block, R64(RTREG), IREG(0), IMM(0xffffffff));            // dand    <rtreg>,i0,0xffffffff
21851840         if (!in_delay_slot)
21861841            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
21871842         return TRUE;
r2821r2822
22071862         {
22081863            UML_SHL(block, IREG(2), IMM(~0), IREG(1));                     // shl     i2,~0,i1
22091864            UML_MOV(block, IREG(3), R32(RTREG));                        // mov     i3,<rtreg>
2210            UML_INSERT(block, IREG(3), IREG(0), IREG(1), IREG(2));            // insert  i3,i0,i1,i2
2211            UML_DSEXT4(block, R64(RTREG), IREG(3));                        // dsext4  <rtreg>,i3
1865            UML_ROLINS(block, IREG(3), IREG(0), IREG(1), IREG(2));            // rolins  i3,i0,i1,i2
1866            UML_DSEXT(block, R64(RTREG), IREG(3), DWORD);                  // dsext   <rtreg>,i3,dword
22121867         }
22131868         if (!in_delay_slot)
22141869            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
r2821r2822
22271882            UML_SHR(block, IREG(2), IMM(~0), IREG(1));                     // shr     i2,~0,i1
22281883            UML_SUB(block, IREG(1), IMM(32), IREG(1));                     // sub     i1,32,i1
22291884            UML_MOV(block, IREG(3), R32(RTREG));                        // mov     i3,<rtreg>
2230            UML_INSERT(block, IREG(3), IREG(0), IREG(1), IREG(2));            // insert  i3,i0,i1,i2
2231            UML_DSEXT4(block, R64(RTREG), IREG(3));                        // dsext4  <rtreg>,i3
1885            UML_ROLINS(block, IREG(3), IREG(0), IREG(1), IREG(2));            // rolins  i3,i0,i1,i2
1886            UML_DSEXT(block, R64(RTREG), IREG(3), DWORD);                  // dsext   <rtreg>,i3,dword
22321887         }
22331888         if (!in_delay_slot)
22341889            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
r2821r2822
22451900         if (RTREG != 0)
22461901         {
22471902            UML_DSHL(block, IREG(2), IMM((UINT64)~0), IREG(1));               // dshl    i2,~0,i1
2248            UML_DINSERT(block, R64(RTREG), IREG(0), IREG(1), IREG(2));         // dinsert <rtreg>,i0,i1,i2
1903            UML_DROLINS(block, R64(RTREG), IREG(0), IREG(1), IREG(2));         // drolins <rtreg>,i0,i1,i2
22491904         }
22501905         if (!in_delay_slot)
22511906            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
r2821r2822
22631918         {
22641919            UML_DSHR(block, IREG(2), IMM((UINT64)~0), IREG(1));               // dshr    i2,~0,i1
22651920            UML_SUB(block, IREG(1), IMM(64), IREG(1));                     // sub     i1,64,i1
2266            UML_DINSERT(block, R64(RTREG), IREG(0), IREG(1), IREG(2));         // dinsert <rtreg>,i0,i1,i2
1921            UML_DROLINS(block, R64(RTREG), IREG(0), IREG(1), IREG(2));         // drolins <rtreg>,i0,i1,i2
22671922         }
22681923         if (!in_delay_slot)
22691924            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
r2821r2822
22881943      case 0x32:   /* LWC2 - MIPS I */
22891944         UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));                  // add     i0,<rsreg>,SIMMVAL
22901945         UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]);   // callh   read32
2291         UML_DZEXT4(block, CPR264(RTREG), IREG(0));                        // dzext4  <cpr2_rt>,i0
1946         UML_DAND(block, CPR264(RTREG), IREG(0), IMM(0xffffffff));            // dand    <cpr2_rt>,i0,0xffffffff
22921947         if (!in_delay_slot)
22931948            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
22941949         return TRUE;
r2821r2822
24792134         if (RDREG != 0)
24802135         {
24812136            UML_SHL(block, IREG(0), R32(RTREG), IMM(SHIFT));               // shl     i0,<rtreg>,<shift>
2482            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2137            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
24832138         }
24842139         return TRUE;
24852140
r2821r2822
24872142         if (RDREG != 0)
24882143         {
24892144            UML_SHR(block, IREG(0), R32(RTREG), IMM(SHIFT));               // shr     i0,<rtreg>,<shift>
2490            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2145            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
24912146         }
24922147         return TRUE;
24932148
r2821r2822
24952150         if (RDREG != 0)
24962151         {
24972152            UML_SAR(block, IREG(0), R32(RTREG), IMM(SHIFT));               // sar     i0,<rtreg>,<shift>
2498            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2153            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
24992154         }
25002155         return TRUE;
25012156
r2821r2822
25032158         if (RDREG != 0)
25042159         {
25052160            UML_SHL(block, IREG(0), R32(RTREG), R32(RSREG));               // shl     i0,<rtreg>,<rsreg>
2506            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2161            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
25072162         }
25082163         return TRUE;
25092164
r2821r2822
25112166         if (RDREG != 0)
25122167         {
25132168            UML_SHR(block, IREG(0), R32(RTREG), R32(RSREG));               // shr     i0,<rtreg>,<rsreg>
2514            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2169            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
25152170         }
25162171         return TRUE;
25172172
r2821r2822
25192174         if (RDREG != 0)
25202175         {
25212176            UML_SAR(block, IREG(0), R32(RTREG), R32(RSREG));               // sar     i0,<rtreg>,<rsreg>
2522            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2177            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
25232178         }
25242179         return TRUE;
25252180
r2821r2822
25782233            UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0));
25792234                                                               // exh     overflow,0,V
25802235            if (RDREG != 0)
2581               UML_DSEXT4(block, R64(RDREG), IREG(0));                     // dsext4  <rdreg>,i0
2236               UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);               // dsext  <rdreg>,i0,dword
25822237         }
25832238         else if (RDREG != 0)
25842239         {
25852240            UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG));               // add     i0,<rsreg>,<rtreg>
2586            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2241            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
25872242         }
25882243         return TRUE;
25892244
r2821r2822
25912246         if (RDREG != 0)
25922247         {
25932248            UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG));               // add     i0,<rsreg>,<rtreg>
2594            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2249            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
25952250         }
25962251         return TRUE;
25972252
r2821r2822
26202275            UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0));
26212276                                                               // exh     overflow,0,V
26222277            if (RDREG != 0)
2623               UML_DSEXT4(block, R64(RDREG), IREG(0));                     // dsext4  <rdreg>,i0
2278               UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);               // dsext  <rdreg>,i0,dword
26242279         }
26252280         else if (RDREG != 0)
26262281         {
26272282            UML_SUB(block, IREG(0), R32(RSREG), R32(RTREG));               // sub     i0,<rsreg>,<rtreg>
2628            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2283            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
26292284         }
26302285         return TRUE;
26312286
r2821r2822
26332288         if (RDREG != 0)
26342289         {
26352290            UML_SUB(block, IREG(0), R32(RSREG), R32(RTREG));               // sub     i0,<rsreg>,<rtreg>
2636            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4  <rdreg>,i0
2291            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext  <rdreg>,i0,dword
26372292         }
26382293         return TRUE;
26392294
r2821r2822
26572312
26582313      case 0x18:   /* MULT - MIPS I */
26592314         UML_MULS(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG));            // muls    i0,i1,<rsreg>,<rtreg>
2660         UML_DSEXT4(block, LO64, IREG(0));                              // dsext4  lo,i0
2661         UML_DSEXT4(block, HI64, IREG(1));                              // dsext4  hi,i1
2315         UML_DSEXT(block, LO64, IREG(0), DWORD);                           // dsext   lo,i0,dword
2316         UML_DSEXT(block, HI64, IREG(1), DWORD);                           // dsext   hi,i1,dword
26622317         return TRUE;
26632318
26642319      case 0x19:   /* MULTU - MIPS I */
26652320         UML_MULU(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG));            // mulu    i0,i1,<rsreg>,<rtreg>
2666         UML_DSEXT4(block, LO64, IREG(0));                              // dsext4  lo,i0
2667         UML_DSEXT4(block, HI64, IREG(1));                              // dsext4  hi,i1
2321         UML_DSEXT(block, LO64, IREG(0), DWORD);                           // dsext   lo,i0,dword
2322         UML_DSEXT(block, HI64, IREG(1), DWORD);                           // dsext   hi,i1,dword
26682323         return TRUE;
26692324
26702325      case 0x1c:   /* DMULT - MIPS III */
r2821r2822
26772332
26782333      case 0x1a:   /* DIV - MIPS I */
26792334         UML_DIVS(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG));            // divs    i0,i1,<rsreg>,<rtreg>
2680         UML_DSEXT4(block, LO64, IREG(0));                              // dsext4  lo,i0
2681         UML_DSEXT4(block, HI64, IREG(1));                              // dsext4  hi,i1
2335         UML_DSEXT(block, LO64, IREG(0), DWORD);                           // dsext   lo,i0,dword
2336         UML_DSEXT(block, HI64, IREG(1), DWORD);                           // dsext   hi,i1,dword
26822337         return TRUE;
26832338
26842339      case 0x1b:   /* DIVU - MIPS I */
26852340         UML_DIVU(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG));            // divu    i0,i1,<rsreg>,<rtreg>
2686         UML_DSEXT4(block, LO64, IREG(0));                              // dsext4  lo,i0
2687         UML_DSEXT4(block, HI64, IREG(1));                              // dsext4  hi,i1
2341         UML_DSEXT(block, LO64, IREG(0), DWORD);                           // dsext   lo,i0,dword
2342         UML_DSEXT(block, HI64, IREG(1), DWORD);                           // dsext   hi,i1,dword
26882343         return TRUE;
26892344
26902345      case 0x1e:   /* DDIV - MIPS III */
r2821r2822
27282383         if (RDREG != 0)
27292384         {
27302385            UML_DCMP(block, R64(RSREG), R64(RTREG));                     // dcmp    <rsreg>,<rtreg>
2731            UML_DFLAGS(block, R64(RDREG), (UINT64)~0, mips3->impstate->slt_table);// dflags  <rdreg>,~0,slt_table
2386            UML_DSETc(block, IF_L, R64(RDREG));                           // dset    <rdreg>,l
27322387         }
27332388         return TRUE;
27342389
r2821r2822
27362391         if (RDREG != 0)
27372392         {
27382393            UML_DCMP(block, R64(RSREG), R64(RTREG));                     // dcmp    <rsreg>,<rtreg>
2739            UML_DFLAGS(block, R64(RDREG), (UINT64)~0, mips3->impstate->sltu_table);// dflags  <rdreg>,~0,sltu_table
2394            UML_DSETc(block, IF_B, R64(RDREG));                           // dset    <rdreg>,b
27402395         }
27412396         return TRUE;
27422397
r2821r2822
27952450      case 0x01:   /* MOVF/MOVT - MIPS IV */
27962451         if (RDREG != 0)
27972452         {
2798            UML_TEST(block, CCR132(31), IMM(fcc_mask[(op >> 18) & 7]));         // test    ccr31,fcc_mask[x]
2453            UML_TEST(block, CCR132(31), IMM(FCCMASK(op >> 18)));            // test    ccr31,fcc_mask[x]
27992454            UML_DMOVc(block, ((op >> 16) & 1) ? IF_NZ : IF_Z, R64(RDREG), R64(RSREG));
28002455                                                               // mov     <rdreg>,<rsreg>,NZ/Z
28012456         }
r2821r2822
29542609            UML_MULS(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG));         // muls   i0,i1,rsreg,rtreg
29552610            UML_ADDf(block, FLAGS_C, IREG(0), IREG(0), LO32);               // add    i0,i0,lo
29562611            UML_ADDC(block, IREG(1), IREG(1), HI32);                     // addc   i1,i1,hi
2957            UML_DSEXT4(block, LO64, IREG(0));                           // dsext4 lo,i0
2958            UML_DSEXT4(block, HI64, IREG(1));                           // dsext4 hi,i0
2612            UML_DSEXT(block, LO64, IREG(0), DWORD);                        // dsext   lo,i0,dword
2613            UML_DSEXT(block, HI64, IREG(1), DWORD);                        // dsext   hi,i1,dword
29592614         }
29602615         return TRUE;
29612616
r2821r2822
29652620            UML_MULU(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG));         // mulu   i0,i1,rsreg,rtreg
29662621            UML_ADDf(block, FLAGS_C, IREG(0), IREG(0), LO32);               // add    i0,i0,lo
29672622            UML_ADDC(block, IREG(1), IREG(1), HI32);                     // addc   i1,i1,hi
2968            UML_DSEXT4(block, LO64, IREG(0));                           // dsext4 lo,i0
2969            UML_DSEXT4(block, HI64, IREG(1));                           // dsext4 hi,i0
2623            UML_DSEXT(block, LO64, IREG(0), DWORD);                        // dsext   lo,i0,dword
2624            UML_DSEXT(block, HI64, IREG(1), DWORD);                        // dsext   hi,i1,dword
29702625         }
29712626         return TRUE;
29722627
r2821r2822
29742629         if (RDREG != 0)
29752630         {
29762631            UML_MULS(block, IREG(0), IREG(0), R32(RSREG), R32(RTREG));         // muls   i0,i0,rsreg,rtreg
2977            UML_DSEXT4(block, R64(RDREG), IREG(0));                        // dsext4 rdreg,i0
2632            UML_DSEXT(block, R64(RDREG), IREG(0), DWORD);                  // dsext rdreg,i0,dword
29782633         }
29792634         return TRUE;
29802635   }
r2821r2822
29952650   switch (reg)
29962651   {
29972652      case COP0_Cause:
2998         UML_INSERT(block, CPR032(COP0_Cause), IREG(0), IMM(0), IMM(~0xfc00));   // insert  [Cause],i0,0,~0xfc00
2653         UML_ROLINS(block, CPR032(COP0_Cause), IREG(0), IMM(0), IMM(~0xfc00));   // rolins  [Cause],i0,0,~0xfc00
29992654         compiler->checksoftints = TRUE;
30002655         if (!in_delay_slot)
30012656            generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE);
r2821r2822
30182673         generate_update_cycles(block, compiler, IMM(desc->pc), !in_delay_slot);   // <subtract cycles>
30192674         UML_MOV(block, CPR032(COP0_Count), IREG(0));                     // mov     [Count],i0
30202675         UML_CALLC(block, cfunc_get_cycles, &mips3->impstate->numcycles);      // callc   cfunc_get_cycles,&mips3->impstate->numcycles
3021         UML_DZEXT4(block, IREG(0), IREG(0));                           // dzext4  i0,i0
2676         UML_DAND(block, IREG(0), IREG(0), IMM(0xffffffff));                  // and     i0,i0,0xffffffff
30222677         UML_DADD(block, IREG(0), IREG(0), IREG(0));                        // dadd    i0,i0,i0
30232678         UML_DSUB(block, MEM(&mips3->count_zero_time), MEM(&mips3->impstate->numcycles), IREG(0));
30242679                                                               // dsub    [count_zero_time],[mips3->impstate->numcycles],i0
r2821r2822
30362691         return TRUE;
30372692
30382693      case COP0_Config:
3039         UML_INSERT(block, CPR032(COP0_Config), IREG(0), IMM(0), IMM(0x0007));   // insert  [Config],i0,0,0x0007
2694         UML_ROLINS(block, CPR032(COP0_Config), IREG(0), IMM(0), IMM(0x0007));   // rolins  [Config],i0,0,0x0007
30402695         return TRUE;
30412696
30422697      case COP0_EntryHi:
r2821r2822
30732728         UML_DSUB(block, IREG(0), MEM(&mips3->impstate->numcycles), MEM(&mips3->count_zero_time));
30742729                                                               // dsub    i0,[numcycles],[count_zero_time]
30752730         UML_DSHR(block, IREG(0), IREG(0), IMM(1));                        // dshr    i0,i0,1
3076         UML_DSEXT4(block, IREG(0), IREG(0));                           // dsext4  i0,i0
2731         UML_DSEXT(block, IREG(0), IREG(0), DWORD);                        // dsext  i0,i0,dword
30772732         return TRUE;
30782733
30792734      case COP0_Random:
r2821r2822
30842739         UML_AND(block, IREG(1), CPR032(COP0_Wired), IMM(0x3f));               // and     i1,[Wired],0x3f
30852740         UML_SUBf(block, IREG(2), IMM(48), IREG(1), FLAGS_BE);               // sub     i2,48,i1,ALL
30862741         UML_JMPc(block, IF_BE, link1 = compiler->labelnum++);               // jmp     link1,BE
3087         UML_DZEXT4(block, IREG(2), IREG(2));                           // dzext4  i2,i2
2742         UML_DAND(block, IREG(2), IREG(2), IMM(0xffffffff));                  // dand    i2,i2,0xffffffff
30882743         UML_DDIVU(block, IREG(0), IREG(2), IREG(0), IREG(2));               // ddivu   i0,i2,i0,i2
30892744         UML_ADD(block, IREG(0), IREG(2), IREG(1));                        // add     i0,i2,i1
30902745         UML_DAND(block, IREG(0), IREG(0), IMM(0x3f));                     // dand    i0,i0,0x3f
30912746         UML_JMP(block, link2 = compiler->labelnum++);                     // jmp     link2
30922747         UML_LABEL(block, link1);                                 // link1:
3093         UML_DSEXT4(block, IREG(0), IMM(47));                           // dsext4  i0,47
2748         UML_DMOV(block, IREG(0), IMM(47));                              // dmov    i0,47
30942749         UML_LABEL(block, link2);                                 // link2:
30952750         return TRUE;
30962751
30972752      default:
3098         UML_DSEXT4(block, IREG(0), CPR032(reg));                        // dsext4  i0,cpr0[reg]
2753         UML_DSEXT(block, IREG(0), CPR032(reg), DWORD);                     // dsext  i0,cpr0[reg],dword
30992754         return TRUE;
31002755   }
31012756}
r2821r2822
31242779         if (RTREG != 0)
31252780         {
31262781            generate_get_cop0_reg(block, compiler, desc, RDREG);            // <get cop0 reg>
3127            UML_DSEXT4(block, R64(RTREG), IREG(0));                        // dsext4  <rtreg>,i0
2782            UML_DSEXT(block, R64(RTREG), IREG(0), DWORD);                  // dsext  <rtreg>,i0,dword
31282783         }
31292784         return TRUE;
31302785
r2821r2822
31382793
31392794      case 0x02:   /* CFCz */
31402795         if (RTREG != 0)
3141            UML_DSEXT4(block, R64(RTREG), CCR032(RDREG));                  // dsext4  <rtreg>,ccr0[rdreg]
2796            UML_DSEXT(block, R64(RTREG), CCR032(RDREG), DWORD);               // dsext  <rtreg>,ccr0[rdreg],dword
31422797         return TRUE;
31432798
31442799      case 0x04:   /* MTCz */
3145         UML_DSEXT4(block, IREG(0), R32(RTREG));                           // dsext4  i0,<rtreg>
2800         UML_DSEXT(block, IREG(0), R32(RTREG), DWORD);                     // dsext  i0,<rtreg>,dword
31462801         generate_set_cop0_reg(block, compiler, desc, RDREG);               // <set cop0 reg>
31472802         return TRUE;
31482803
r2821r2822
31522807         return TRUE;
31532808
31542809      case 0x06:   /* CTCz */
3155         UML_DSEXT4(block, CCR064(RDREG), R32(RTREG));                     // dsext4  ccr0[rdreg],<rtreg>
2810         UML_DSEXT(block, CCR064(RDREG), R32(RTREG), DWORD);                  // dsext  ccr0[rdreg],<rtreg>,dword
31562811         return TRUE;
31572812
31582813      case 0x10:
r2821r2822
32402895   if (mips3->impstate->drcoptions & MIPS3DRC_STRICT_COP1)
32412896   {
32422897      UML_TEST(block, CPR032(COP0_Status), IMM(SR_COP1));                     // test    [Status],SR_COP1
3243      UML_EXHc(block, IF_Z, mips3->impstate->exception[EXCEPTION_BADCOP], IMM(0));// exh     cop,0,Z
2898      UML_EXHc(block, IF_Z, mips3->impstate->exception[EXCEPTION_BADCOP], IMM(1));// exh     cop,1,Z
32442899   }
32452900
32462901   switch (RSREG)
32472902   {
32482903      case 0x00:   /* MFCz - MIPS I */
32492904         if (RTREG != 0)
3250            UML_DSEXT4(block, R64(RTREG), FPR32(RDREG));                  // dsext4  <rtreg>,fpr[rdreg]
2905            UML_DSEXT(block, R64(RTREG), FPR32(RDREG), DWORD);               // dsext  <rtreg>,fpr[rdreg],dword
32512906         return TRUE;
32522907
32532908      case 0x01:   /* DMFCz - MIPS III */
r2821r2822
32572912
32582913      case 0x02:   /* CFCz - MIPS I */
32592914         if (RTREG != 0)
3260            UML_DSEXT4(block, R64(RTREG), CCR132(RDREG));                  // dsext4  <rtreg>,ccr132[rdreg]
2915            UML_DSEXT(block, R64(RTREG), CCR132(RDREG), DWORD);               // dsext  <rtreg>,ccr132[rdreg],dword
32612916         return TRUE;
32622917
32632918      case 0x04:   /* MTCz - MIPS I */
r2821r2822
32702925
32712926      case 0x06:   /* CTCz - MIPS I */
32722927         if (RDREG != 31)
3273            UML_DSEXT4(block, CCR164(RDREG), R32(RTREG));                  // dsext4  ccr1[rdreg],<rtreg>
2928            UML_DSEXT(block, CCR164(RDREG), R32(RTREG), DWORD);               // dsext  ccr1[rdreg],<rtreg>,dword
32742929         else
32752930         {
32762931            UML_XOR(block, IREG(0), CCR132(31), R32(RTREG));               // xor     i0,ccr1[31],<rtreg>
3277            UML_DSEXT4(block, CCR164(31), R32(RTREG));                     // dsext4  ccr1[31],<rtreg>
2932            UML_DSEXT(block, CCR164(31), R32(RTREG), DWORD);               // dsext  ccr1[31],<rtreg>,dword
32782933            UML_TEST(block, IREG(0), IMM(3));                           // test    i0,3
32792934            UML_JMPc(block, IF_Z, skip = compiler->labelnum++);               // jmp     skip,Z
32802935            UML_AND(block, IREG(0), CCR132(31), IMM(3));                  // and     i0,ccr1[31],3
3281            UML_LOAD1U(block, IREG(0), &mips3->impstate->fpmode[0], IREG(0));   // load1u  i0,fpmode,i0
2936            UML_LOAD(block, IREG(0), &mips3->impstate->fpmode[0], IREG(0), BYTE);// load  i0,fpmode,i0,byte
32822937            UML_SETFMOD(block, IREG(0));                              // setfmod i0
32832938            UML_LABEL(block, skip);                                 // skip:
32842939         }
r2821r2822
33663021
33673022            case 0x08:
33683023               if (IS_SINGLE(op))   /* ROUND.L.S - MIPS III */
3369                  UML_FSTOI8R(block, FPR64(FDREG), FPR32(FSREG));            // fstoi8r <fdreg>,<fsreg>
3024                  UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, ROUND);// fstoint <fdreg>,<fsreg>,qword,round
33703025               else            /* ROUND.L.D - MIPS III */
3371                  UML_FDTOI8R(block, FPR64(FDREG), FPR64(FSREG));            // fdtoi8r <fdreg>,<fsreg>
3026                  UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, ROUND);// fdtoint <fdreg>,<fsreg>,qword,round
33723027               return TRUE;
33733028
33743029            case 0x09:
33753030               if (IS_SINGLE(op))   /* TRUNC.L.S - MIPS III */
3376                  UML_FSTOI8T(block, FPR64(FDREG), FPR32(FSREG));            // fstoi8t <fdreg>,<fsreg>
3031                  UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, TRUNC);// fstoint <fdreg>,<fsreg>,qword,trunc
33773032               else            /* TRUNC.L.D - MIPS III */
3378                  UML_FDTOI8T(block, FPR64(FDREG), FPR64(FSREG));            // fdtoi8t <fdreg>,<fsreg>
3033                  UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, TRUNC);// fdtoint <fdreg>,<fsreg>,qword,trunc
33793034               return TRUE;
33803035
33813036            case 0x0a:
33823037               if (IS_SINGLE(op))   /* CEIL.L.S - MIPS III */
3383                  UML_FSTOI8C(block, FPR64(FDREG), FPR32(FSREG));            // fstoi8c <fdreg>,<fsreg>
3038                  UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, CEIL);// fstoint <fdreg>,<fsreg>,qword,ceil
33843039               else            /* CEIL.L.D - MIPS III */
3385                  UML_FDTOI8C(block, FPR64(FDREG), FPR64(FSREG));            // fdtoi8c <fdreg>,<fsreg>
3040                  UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, CEIL);// fdtoint <fdreg>,<fsreg>,qword,ceil
33863041               return TRUE;
33873042
33883043            case 0x0b:
33893044               if (IS_SINGLE(op))   /* FLOOR.L.S - MIPS III */
3390                  UML_FSTOI8F(block, FPR64(FDREG), FPR32(FSREG));            // fstoi8f <fdreg>,<fsreg>
3045                  UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, FLOOR);// fstoint <fdreg>,<fsreg>,qword,floor
33913046               else            /* FLOOR.L.D - MIPS III */
3392                  UML_FDTOI8F(block, FPR64(FDREG), FPR64(FSREG));            // fdtoi8f <fdreg>,<fsreg>
3047                  UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, FLOOR);// fdtoint <fdreg>,<fsreg>,qword,floor
33933048               return TRUE;
33943049
33953050            case 0x0c:
33963051               if (IS_SINGLE(op))   /* ROUND.W.S - MIPS II */
3397                  UML_FSTOI4R(block, FPR32(FDREG), FPR32(FSREG));            // fstoi4r <fdreg>,<fsreg>
3052                  UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, ROUND);// fstoint <fdreg>,<fsreg>,dword,round
33983053               else            /* ROUND.W.D - MIPS II */
3399                  UML_FDTOI4R(block, FPR32(FDREG), FPR64(FSREG));            // fdtoi4r <fdreg>,<fsreg>
3054                  UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, ROUND);// fdtoint <fdreg>,<fsreg>,dword,round
34003055               return TRUE;
34013056
34023057            case 0x0d:
34033058               if (IS_SINGLE(op))   /* TRUNC.W.S - MIPS II */
3404                  UML_FSTOI4T(block, FPR32(FDREG), FPR32(FSREG));            // fstoi4t <fdreg>,<fsreg>
3059                  UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, TRUNC);// fstoint <fdreg>,<fsreg>,dword,trunc
34053060               else            /* TRUNC.W.D - MIPS II */
3406                  UML_FDTOI4T(block, FPR32(FDREG), FPR64(FSREG));            // fdtoi4t <fdreg>,<fsreg>
3061                  UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, TRUNC);// fdtoint <fdreg>,<fsreg>,dword,trunc
34073062               return TRUE;
34083063
34093064            case 0x0e:
34103065               if (IS_SINGLE(op))   /* CEIL.W.S - MIPS II */
3411                  UML_FSTOI4C(block, FPR32(FDREG), FPR32(FSREG));            // fstoi4c <fdreg>,<fsreg>
3066                  UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, CEIL);// fstoint <fdreg>,<fsreg>,dword,ceil
34123067               else            /* CEIL.W.D - MIPS II */
3413                  UML_FDTOI4C(block, FPR32(FDREG), FPR64(FSREG));            // fdtoi4c <fdreg>,<fsreg>
3068                  UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, CEIL);// fdtoint <fdreg>,<fsreg>,dword,ceil
34143069               return TRUE;
34153070
34163071            case 0x0f:
34173072               if (IS_SINGLE(op))   /* FLOOR.W.S - MIPS II */
3418                  UML_FSTOI4F(block, FPR32(FDREG), FPR32(FSREG));            // fstoi4f <fdreg>,<fsreg>
3073                  UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, FLOOR);// fstoint <fdreg>,<fsreg>,dword,floor
34193074               else            /* FLOOR.W.D - MIPS II */
3420                  UML_FDTOI4F(block, FPR32(FDREG), FPR64(FSREG));            // fdtoi4f <fdreg>,<fsreg>
3075                  UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, FLOOR);// fdtoint <fdreg>,<fsreg>,dword,floor
34213076               return TRUE;
34223077
34233078            case 0x11:
r2821r2822
34633118               if (IS_INTEGRAL(op))
34643119               {
34653120                  if (IS_SINGLE(op))   /* CVT.S.W - MIPS I */
3466                     UML_FSFRI4(block, FPR32(FDREG), FPR32(FSREG));         // fsfri4 <fdreg>,<fsreg>
3121                     UML_FSFRINT(block, FPR32(FDREG), FPR32(FSREG), DWORD);   // fsfrint <fdreg>,<fsreg>,dword
34673122                  else            /* CVT.S.L - MIPS I */
3468                     UML_FSFRI8(block, FPR32(FDREG), FPR64(FSREG));         // fsfri8 <fdreg>,<fsreg>
3123                     UML_FSFRINT(block, FPR32(FDREG), FPR64(FSREG), QWORD);   // fsfrint <fdreg>,<fsreg>,qword
34693124               }
34703125               else               /* CVT.S.D - MIPS I */
3471                  UML_FSFRFD(block, FPR32(FDREG), FPR64(FSREG));            // fsfrfd <fdreg>,<fsreg>
3126                  UML_FSFRFLT(block, FPR32(FDREG), FPR64(FSREG), QWORD);      // fsfrflt <fdreg>,<fsreg>,qword
34723127               return TRUE;
34733128
34743129            case 0x21:
34753130               if (IS_INTEGRAL(op))
34763131               {
34773132                  if (IS_SINGLE(op))   /* CVT.D.W - MIPS I */
3478                     UML_FDFRI4(block, FPR64(FDREG), FPR32(FSREG));         // fdfri4 <fdreg>,<fsreg>
3133                     UML_FDFRINT(block, FPR64(FDREG), FPR32(FSREG), DWORD);   // fdfrint <fdreg>,<fsreg>,dword
34793134                  else            /* CVT.D.L - MIPS I */
3480                     UML_FDFRI8(block, FPR64(FDREG), FPR64(FSREG));         // fdfri8 <fdreg>,<fsreg>
3135                     UML_FDFRINT(block, FPR64(FDREG), FPR64(FSREG), QWORD);   // fdfrint <fdreg>,<fsreg>,qword
34813136               }
34823137               else               /* CVT.D.S - MIPS I */
3483                  UML_FDFRFS(block, FPR64(FDREG), FPR32(FSREG));            // fdfrfs <fdreg>,<fsreg>
3138                  UML_FDFRFLT(block, FPR64(FDREG), FPR32(FSREG), DWORD);      // fdfrflt <fdreg>,<fsreg>,dword
34843139               return TRUE;
34853140
34863141            case 0x24:
34873142               if (IS_SINGLE(op))   /* CVT.W.S - MIPS I */
3488                  UML_FSTOI4(block, FPR32(FDREG), FPR32(FSREG));            // fstoi4 <fdreg>,<fsreg>
3143                  UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, DEFAULT);// fstoint <fdreg>,<fsreg>,dword,default
34893144               else            /* CVT.W.D - MIPS I */
3490                  UML_FDTOI4(block, FPR32(FDREG), FPR64(FSREG));            // fdtoi4 <fdreg>,<fsreg>
3145                  UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, DEFAULT);// fdtoint <fdreg>,<fsreg>,dword,default
34913146               return TRUE;
34923147
34933148            case 0x25:
34943149               if (IS_SINGLE(op))   /* CVT.L.S - MIPS I */
3495                  UML_FSTOI8(block, FPR64(FDREG), FPR32(FSREG));            // fstoi8 <fdreg>,<fsreg>
3150                  UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, DEFAULT);// fstoint <fdreg>,<fsreg>,qword,default
34963151               else            /* CVT.L.D - MIPS I */
3497                  UML_FDTOI8(block, FPR64(FDREG), FPR64(FSREG));            // fdtoi8 <fdreg>,<fsreg>
3152                  UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, DEFAULT);// fdtoint <fdreg>,<fsreg>,qword,default
34983153               return TRUE;
34993154
35003155            case 0x30:
r2821r2822
35083163                  UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG));            // fscmp   <fsreg>,<ftreg>
35093164               else            /* C.UN.D - MIPS I */
35103165                  UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG));            // fdcmp   <fsreg>,<ftreg>
3511               UML_FLAGS(block, CCR132(31), FCCMASK(op >> 8), mips3->impstate->c_un_table);
3512                                                               // flags   ccr31,fccmask[op],c_eq_table
3166               UML_SETc(block, IF_U, IREG(0));                           // set     i0,u
3167               UML_ROLINS(block, CCR132(31), IREG(0), IMM(FCCSHIFT(op >> 8)), IMM(FCCMASK(op >> 8)));
3168                                                               // rolins  ccr31,i0,fccshift,fcc
35133169               return TRUE;
35143170
35153171            case 0x32:
r2821r2822
35183174                  UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG));            // fscmp   <fsreg>,<ftreg>
35193175               else            /* C.EQ.D - MIPS I */
35203176                  UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG));            // fdcmp   <fsreg>,<ftreg>
3521               UML_FLAGS(block, CCR132(31), FCCMASK(op >> 8), mips3->impstate->c_eq_table);
3522                                                               // flags   ccr31,fccmask[op],c_eq_table
3177               UML_SETc(block, IF_E, IREG(0));                           // set     i0,e
3178               UML_ROLINS(block, CCR132(31), IREG(0), IMM(FCCSHIFT(op >> 8)), IMM(FCCMASK(op >> 8)));
3179                                                               // rolins  ccr31,i0,fccshift,fcc
35233180               return TRUE;
35243181
35253182            case 0x33:
r2821r2822
35283185                  UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG));            // fscmp   <fsreg>,<ftreg>
35293186               else            /* C.UEQ.D - MIPS I */
35303187                  UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG));            // fdcmp   <fsreg>,<ftreg>
3531               UML_FLAGS(block, CCR132(31), FCCMASK(op >> 8), mips3->impstate->c_ueq_table);
3532                                                               // flags   ccr31,fccmask[op],c_eq_table
3188               UML_SETc(block, IF_U, IREG(0));                           // set     i0,u
3189               UML_SETc(block, IF_E, IREG(1));                           // set     i1,e
3190               UML_OR(block, IREG(0), IREG(0), IREG(1));                  // or      i0,i0,i1
3191               UML_ROLINS(block, CCR132(31), IREG(0), IMM(FCCSHIFT(op >> 8)), IMM(FCCMASK(op >> 8)));
3192                                                               // rolins  ccr31,i0,fccshift,fcc
35333193               return TRUE;
35343194
35353195            case 0x34:
r2821r2822
35383198                  UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG));            // fscmp   <fsreg>,<ftreg>
35393199               else            /* C.OLT.D - MIPS I */
35403200                  UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG));            // fdcmp   <fsreg>,<ftreg>
3541               UML_FLAGS(block, CCR132(31), FCCMASK(op >> 8), mips3->impstate->c_olt_table);
3542                                                               // flags   ccr31,fccmask[op],c_lt_table
3201               UML_SETc(block, IF_B, IREG(0));                           // set     i0,b
3202               UML_ROLINS(block, CCR132(31), IREG(0), IMM(FCCSHIFT(op >> 8)), IMM(FCCMASK(op >> 8)));
3203                                                               // rolins  ccr31,i0,fccshift,fcc
35433204               return TRUE;
35443205
35453206            case 0x35:
r2821r2822
35483209                  UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG));            // fscmp   <fsreg>,<ftreg>
35493210               else            /* C.ULT.D - MIPS I */
35503211                  UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG));            // fdcmp   <fsreg>,<ftreg>
3551               UML_FLAGS(block, CCR132(31), FCCMASK(op >> 8), mips3->impstate->c_ult_table);
3552                                                               // flags   ccr31,fccmask[op],c_lt_table
3212               UML_SETc(block, IF_U, IREG(0));                           // set     i0,u
3213               UML_SETc(block, IF_B, IREG(1));                           // set     i1,b
3214               UML_OR(block, IREG(0), IREG(0), IREG(1));                  // or      i0,i0,i1
3215               UML_ROLINS(block, CCR132(31), IREG(0), IMM(FCCSHIFT(op >> 8)), IMM(FCCMASK(op >> 8)));
3216                                                               // rolins  ccr31,i0,fccshift,fcc
35533217               return TRUE;
35543218
35553219            case 0x36:
r2821r2822
35583222                  UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG));            // fscmp   <fsreg>,<ftreg>
35593223               else            /* C.OLE.D - MIPS I */
35603224                  UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG));            // fdcmp   <fsreg>,<ftreg>
3561               UML_FLAGS(block, CCR132(31), FCCMASK(op >> 8), mips3->impstate->c_ole_table);
3562                                                               // flags   ccr31,fccmask[op],c_le_table
3225               UML_SETc(block, IF_BE, IREG(0));                        // set     i0,be
3226               UML_ROLINS(block, CCR132(31), IREG(0), IMM(FCCSHIFT(op >> 8)), IMM(FCCMASK(op >> 8)));
3227                                                               // rolins  ccr31,i0,fccshift,fcc
35633228               return TRUE;
35643229
35653230            case 0x37:
r2821r2822
35683233                  UML_FSCMP(block, FPR32(FSREG), FPR32(FTREG));            // fscmp   <fsreg>,<ftreg>
35693234               else            /* C.ULE.D - MIPS I */
35703235                  UML_FDCMP(block, FPR64(FSREG), FPR64(FTREG));            // fdcmp   <fsreg>,<ftreg>
3571               UML_FLAGS(block, CCR132(31), FCCMASK(op >> 8), mips3->impstate->c_ule_table);
3572                                                               // flags   ccr31,fccmask[op],c_le_table
3236               UML_SETc(block, IF_U, IREG(0));                           // set     i0,u
3237               UML_SETc(block, IF_BE, IREG(1));                        // set     i1,be
3238               UML_OR(block, IREG(0), IREG(0), IREG(1));                  // or      i0,i0,i1
3239               UML_ROLINS(block, CCR132(31), IREG(0), IMM(FCCSHIFT(op >> 8)), IMM(FCCMASK(op >> 8)));
3240                                                               // rolins  ccr31,i0,fccshift,fcc
35733241               return TRUE;
35743242         }
35753243         break;
r2821r2822
35953263   if (mips3->impstate->drcoptions & MIPS3DRC_STRICT_COP1)
35963264   {
35973265      UML_TEST(block, CPR032(COP0_Status), IMM(SR_COP1));                     // test    [Status],SR_COP1
3598      UML_EXHc(block, IF_Z, mips3->impstate->exception[EXCEPTION_BADCOP], IMM(0));// exh     cop,0,Z
3266      UML_EXHc(block, IF_Z, mips3->impstate->exception[EXCEPTION_BADCOP], IMM(1));// exh     cop,1,Z
35993267   }
36003268
36013269   switch (op & 0x3f)
src/emu/cpu/drcumld.c
r2821r2822
4343static char *output_param(char *dest, int size, const drcuml_parameter *param);
4444static char *output_param_string(char *dest, int size, const drcuml_parameter *param);
4545static char *output_param_handle(char *dest, int size, const drcuml_parameter *param);
46static char *output_param_size(char *dest, int size, const drcuml_parameter *param);
4647static char *output_param_space(char *dest, int size, const drcuml_parameter *param);
48static char *output_param_space_size(char *dest, int size, const drcuml_parameter *param);
49static char *output_param_round(char *dest, int size, const drcuml_parameter *param);
4750
4851
4952
r2821r2822
8992   { DRCUML_OP_SETFMOD,   "setfmod",   { output_param } },
9093   { DRCUML_OP_GETFMOD,   "getfmod",   { output_param } },
9194   { DRCUML_OP_GETEXP,      "getexp",   { output_param } },
95   { DRCUML_OP_GETFLGS,   "getflgs",   { output_param, output_flags } },
9296   { DRCUML_OP_SAVE,      "save",      { output_param } },
9397   { DRCUML_OP_RESTORE,   "restore",   { output_param } },
9498
9599   /* Integer Operations */
96   { DRCUML_OP_LOAD1U,      "!load1u",   { output_param, output_param, output_param } },
97   { DRCUML_OP_LOAD1S,      "!load1s",   { output_param, output_param, output_param } },
98   { DRCUML_OP_LOAD2U,      "!load2u",   { output_param, output_param, output_param } },
99   { DRCUML_OP_LOAD2S,      "!load2s",   { output_param, output_param, output_param } },
100   { DRCUML_OP_LOAD4U,      "!load4u",   { output_param, output_param, output_param } },
101   { DRCUML_OP_LOAD4S,      "!load4s",   { output_param, output_param, output_param } },
102   { DRCUML_OP_LOAD8U,      "!load8u",   { output_param, output_param, output_param } },
103   { DRCUML_OP_STORE1,      "!store1",   { output_param, output_param, output_param } },
104   { DRCUML_OP_STORE2,      "!store2",   { output_param, output_param, output_param } },
105   { DRCUML_OP_STORE4,      "!store4",   { output_param, output_param, output_param } },
106   { DRCUML_OP_STORE8,      "!store8",   { output_param, output_param, output_param } },
107   { DRCUML_OP_READ1U,      "!read1u",   { output_param, output_param_space, output_param } },
108   { DRCUML_OP_READ1S,      "!read1s",   { output_param, output_param_space, output_param } },
109   { DRCUML_OP_READ2U,      "!read2u",   { output_param, output_param_space, output_param } },
110   { DRCUML_OP_READ2S,      "!read2s",   { output_param, output_param_space, output_param } },
111   { DRCUML_OP_READ2M,      "!read2m",   { output_param, output_param_space, output_param, output_param } },
112   { DRCUML_OP_READ4U,      "!read4u",   { output_param, output_param_space, output_param } },
113   { DRCUML_OP_READ4S,      "!read4s",   { output_param, output_param_space, output_param } },
114   { DRCUML_OP_READ4M,      "!read4m",   { output_param, output_param_space, output_param, output_param } },
115   { DRCUML_OP_READ8U,      "!read8u",   { output_param, output_param_space, output_param } },
116   { DRCUML_OP_READ8M,      "!read8m",   { output_param, output_param_space, output_param, output_param } },
117   { DRCUML_OP_WRITE1,      "!write1",   { output_param_space, output_param, output_param } },
118   { DRCUML_OP_WRITE2,      "!write2",   { output_param_space, output_param, output_param } },
119   { DRCUML_OP_WRIT2M,      "!writ2m",   { output_param_space, output_param, output_param, output_param } },
120   { DRCUML_OP_WRITE4,      "!write4",   { output_param_space, output_param, output_param } },
121   { DRCUML_OP_WRIT4M,      "!writ4m",   { output_param_space, output_param, output_param, output_param } },
122   { DRCUML_OP_WRITE8,      "!write8",   { output_param_space, output_param, output_param } },
123   { DRCUML_OP_WRIT8M,      "!writ8m",   { output_param_space, output_param, output_param, output_param } },
124   { DRCUML_OP_FLAGS,      "!flags",   { output_param, output_param, output_param } },
125   { DRCUML_OP_SETC,      "!setc",   { output_param, output_param } },
100   { DRCUML_OP_LOAD,      "!load",   { output_param, output_param, output_param, output_param_size } },
101   { DRCUML_OP_LOADS,      "!loads",   { output_param, output_param, output_param, output_param_size } },
102   { DRCUML_OP_STORE,      "!store",   { output_param, output_param, output_param, output_param_size } },
103   { DRCUML_OP_READ,      "!read",   { output_param, output_param, output_param_space_size } },
104   { DRCUML_OP_READM,      "!readm",   { output_param, output_param, output_param, output_param_space_size } },
105   { DRCUML_OP_WRITE,      "!write",   { output_param, output_param, output_param_space_size } },
106   { DRCUML_OP_WRITEM,      "!writem",   { output_param, output_param, output_param, output_param_space_size } },
107   { DRCUML_OP_CARRY,      "!carry",   { output_param, output_param } },
108   { DRCUML_OP_SET,      "!set",      { output_param, output_cond } },
126109   { DRCUML_OP_MOV,      "!mov",      { output_param, output_param, output_cond } },
127   { DRCUML_OP_ZEXT1,      "!zext1",   { output_param, output_param } },
128   { DRCUML_OP_ZEXT2,      "!zext2",   { output_param, output_param } },
129   { DRCUML_OP_ZEXT4,      "!zext4",   { output_param, output_param } },
130   { DRCUML_OP_SEXT1,      "!sext1",   { output_param, output_param } },
131   { DRCUML_OP_SEXT2,      "!sext2",   { output_param, output_param } },
132   { DRCUML_OP_SEXT4,      "!sext4",   { output_param, output_param } },
133   { DRCUML_OP_XTRACT,      "!xtract",   { output_param, output_param, output_param, output_param } },
134   { DRCUML_OP_INSERT,      "!insert",   { output_param, output_param, output_param, output_param } },
110   { DRCUML_OP_SEXT,      "!sext",   { output_param, output_param, output_param_size } },
111   { DRCUML_OP_ROLAND,      "!roland",   { output_param, output_param, output_param, output_param } },
112   { DRCUML_OP_ROLINS,      "!rolins",   { output_param, output_param, output_param, output_param } },
135113   { DRCUML_OP_ADD,      "!add",      { output_param, output_param, output_param, output_flags } },
136114   { DRCUML_OP_ADDC,      "!addc",   { output_param, output_param, output_param, output_flags } },
137115   { DRCUML_OP_SUB,      "!sub",      { output_param, output_param, output_param, output_flags } },
r2821r2822
158136   /* Floating-Point Operations */
159137   { DRCUML_OP_FLOAD,      "f!load",   { output_param, output_param, output_param } },
160138   { DRCUML_OP_FSTORE,      "f!store",   { output_param, output_param, output_param } },
161   { DRCUML_OP_FREAD,      "f!read",   { output_param, output_param_space, output_param } },
162   { DRCUML_OP_FWRITE,      "f!write",   { output_param_space, output_param, output_param } },
139   { DRCUML_OP_FREAD,      "f!read",   { output_param, output_param, output_param_space } },
140   { DRCUML_OP_FWRITE,      "f!write",   { output_param, output_param, output_param_space } },
163141   { DRCUML_OP_FMOV,      "f!mov",   { output_param, output_param, output_cond } },
164   { DRCUML_OP_FTOI4,      "f!toi4",   { output_param, output_param } },
165   { DRCUML_OP_FTOI4T,      "f!toi4t",   { output_param, output_param } },
166   { DRCUML_OP_FTOI4R,      "f!toi4r",   { output_param, output_param } },
167   { DRCUML_OP_FTOI4F,      "f!toi4f",   { output_param, output_param } },
168   { DRCUML_OP_FTOI4C,      "f!toi4c",   { output_param, output_param } },
169   { DRCUML_OP_FTOI8,      "f!toi8",   { output_param, output_param } },
170   { DRCUML_OP_FTOI8T,      "f!toi8t",   { output_param, output_param } },
171   { DRCUML_OP_FTOI8R,      "f!toi8r",   { output_param, output_param } },
172   { DRCUML_OP_FTOI8F,      "f!toi8f",   { output_param, output_param } },
173   { DRCUML_OP_FTOI8C,      "f!toi8c",   { output_param, output_param } },
174   { DRCUML_OP_FFRFS,      "f!frfs",   { output_param, output_param } },
175   { DRCUML_OP_FFRFD,      "f!frfd",   { output_param, output_param } },
176   { DRCUML_OP_FFRI4,      "f!fri4",   { output_param, output_param } },
177   { DRCUML_OP_FFRI8,      "f!fri8",   { output_param, output_param } },
142   { DRCUML_OP_FTOINT,      "f!toint",   { output_param, output_param, output_param_size, output_param_round } },
143   { DRCUML_OP_FFRINT,      "f!frint",   { output_param, output_param, output_param_size } },
144   { DRCUML_OP_FFRFLT,      "f!frflt",   { output_param, output_param, output_param_size } },
145   { DRCUML_OP_FRNDS,      "f!rnds",   { output_param, output_param } },
178146   { DRCUML_OP_FADD,      "f!add",   { output_param, output_param, output_param } },
179147   { DRCUML_OP_FSUB,      "f!sub",   { output_param, output_param, output_param } },
180148   { DRCUML_OP_FCMP,      "f!cmp",   { output_param, output_param, output_flags_cmptest } },
r2821r2822
448416
449417
450418/*-------------------------------------------------
419    output_param_size - output parameter 0,
420    assuming it is size
421-------------------------------------------------*/
422
423static char *output_param_size(char *dest, int size, const drcuml_parameter *param)
424{
425   if (param->type == DRCUML_PTYPE_IMMEDIATE)
426   {
427      static const char *strings[] = { "byte", "word", "dword", "qword" };
428      return dest + sprintf(dest, "%s", strings[param->value & 3]);
429   }
430   return output_param(dest, size, param);
431}
432
433
434/*-------------------------------------------------
451435    output_param_space - output parameter 0,
452436    assuming it is an address space
453437-------------------------------------------------*/
r2821r2822
458442      return dest + sprintf(dest, "%s", address_space_names[param->value]);
459443   return output_param(dest, size, param);
460444}
445
446
447/*-------------------------------------------------
448    output_param_space_size - output parameter 0,
449    assuming it is an address space/size combo
450-------------------------------------------------*/
451
452static char *output_param_space_size(char *dest, int size, const drcuml_parameter *param)
453{
454   if (param->type == DRCUML_PTYPE_IMMEDIATE && param->value / 16 >= ADDRESS_SPACE_PROGRAM && param->value / 16 <= ADDRESS_SPACE_IO)
455   {
456      dest += sprintf(dest, "%s_", address_space_names[param->value / 16]);
457      return output_param_size(dest, size, param);
458   }
459
460   return output_param(dest, size, param);
461}
462
463
464/*-------------------------------------------------
465    output_param_round - output parameter 0,
466    assuming it is a rounding mode
467-------------------------------------------------*/
468
469static char *output_param_round(char *dest, int size, const drcuml_parameter *param)
470{
471   if (param->type == DRCUML_PTYPE_IMMEDIATE && param->value >= DRCUML_FMOD_TRUNC && param->value <= DRCUML_FMOD_DEFAULT)
472   {
473      static const char *strings[] = { "trunc", "round", "ceil", "floor", "default" };
474      return dest + sprintf(dest, "%s", strings[param->value]);
475   }
476   return output_param(dest, size, param);
477}
src/emu/cpu/drcbex86.c
r2821r2822
1818
1919    * Identify common pairs and optimize output
2020
21    * Convert AND 0xff/0xffff to movzx
22
2123****************************************************************************
2224
2325    ---------------
r2821r2822
282284static x86code *op_setfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
283285static x86code *op_getfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
284286static x86code *op_getexp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
287static x86code *op_getflgs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
285288static x86code *op_save(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
286289static x86code *op_restore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
287290
288static x86code *op_load1u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
289static x86code *op_load1s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
290static x86code *op_load2u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
291static x86code *op_load2s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
292static x86code *op_load4u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
293static x86code *op_load4s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
294static x86code *op_load8u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
295static x86code *op_store1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
296static x86code *op_store2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
297static x86code *op_store4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
298static x86code *op_store8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
299static x86code *op_read1u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
300static x86code *op_read1s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
301static x86code *op_read2u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
302static x86code *op_read2s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
303static x86code *op_read2m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
304static x86code *op_read4u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
305static x86code *op_read4s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
306static x86code *op_read4m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
307static x86code *op_read8u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
308static x86code *op_read8m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
309static x86code *op_write1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
310static x86code *op_write2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
311static x86code *op_writ2m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
312static x86code *op_write4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
313static x86code *op_writ4m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
314static x86code *op_write8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
315static x86code *op_writ8m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
316static x86code *op_flags(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
317static x86code *op_setc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
291static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
292static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
293static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
294static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
295static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
296static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
297static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
298static x86code *op_carry(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
299static x86code *op_set(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
318300static x86code *op_mov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
319static x86code *op_zext1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
320static x86code *op_zext2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
321static x86code *op_zext4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
322static x86code *op_sext1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
323static x86code *op_sext2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
324static x86code *op_sext4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
325static x86code *op_xtract(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
326static x86code *op_insert(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
301static x86code *op_sext(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
302static x86code *op_roland(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
303static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
327304static x86code *op_add(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
328305static x86code *op_addc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
329306static x86code *op_sub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
r2821r2822
352329static x86code *op_fread(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
353330static x86code *op_fwrite(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
354331static x86code *op_fmov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
355static x86code *op_ftoi4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
356static x86code *op_ftoi4t(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
357static x86code *op_ftoi4r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
358static x86code *op_ftoi4f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
359static x86code *op_ftoi4c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
360static x86code *op_ftoi8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
361static x86code *op_ftoi8t(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
362static x86code *op_ftoi8r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
363static x86code *op_ftoi8f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
364static x86code *op_ftoi8c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
365static x86code *op_ffrfs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
366static x86code *op_ffrfd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
367static x86code *op_ffri4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
368static x86code *op_ffri8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
332static x86code *op_ftoint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
333static x86code *op_ffrint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
334static x86code *op_ffrflt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
335static x86code *op_frnds(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
369336static x86code *op_fadd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
370337static x86code *op_fsub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
371338static x86code *op_fcmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst);
r2821r2822
400367   /* Internal Register Operations */
401368   { DRCUML_OP_SETFMOD, op_setfmod },   /* SETFMOD src                    */
402369   { DRCUML_OP_GETFMOD, op_getfmod },   /* GETFMOD dst                    */
403   { DRCUML_OP_GETEXP,  op_getexp },   /* GETEXP  dst,index              */
404   { DRCUML_OP_SAVE,    op_save },      /* SAVE    dst,index              */
405   { DRCUML_OP_RESTORE, op_restore },   /* RESTORE dst,index              */
370   { DRCUML_OP_GETEXP,  op_getexp },   /* GETEXP  dst                    */
371   { DRCUML_OP_GETFLGS, op_getflgs },   /* GETFLGS dst[,f]                */
372   { DRCUML_OP_SAVE,    op_save },      /* SAVE    dst                    */
373   { DRCUML_OP_RESTORE, op_restore },   /* RESTORE dst                    */
406374
407375   /* Integer Operations */
408   { DRCUML_OP_LOAD1U,  op_load1u },   /* LOAD1U  dst,base,index         */
409   { DRCUML_OP_LOAD1S,  op_load1s },   /* LOAD1S  dst,base,index         */
410   { DRCUML_OP_LOAD2U,  op_load2u },   /* LOAD2U  dst,base,index         */
411   { DRCUML_OP_LOAD2S,  op_load2s },   /* LOAD2S  dst,base,index         */
412   { DRCUML_OP_LOAD4U,  op_load4u },   /* LOAD4U  dst,base,index         */
413   { DRCUML_OP_LOAD4S,  op_load4s },   /* LOAD4S  dst,base,index         */
414   { DRCUML_OP_LOAD8U,  op_load8u },   /* LOAD8U  dst,base,index         */
415   { DRCUML_OP_STORE1,  op_store1 },   /* STORE1  base,index,src         */
416   { DRCUML_OP_STORE2,  op_store2 },   /* STORE2  base,index,src         */
417   { DRCUML_OP_STORE4,  op_store4 },   /* STORE4  base,index,src         */
418   { DRCUML_OP_STORE8,  op_store8 },   /* STORE8  base,index,src         */
419   { DRCUML_OP_READ1U,  op_read1u },   /* READ1U  dst,space,src1         */
420   { DRCUML_OP_READ1S,  op_read1s },   /* READ1S  dst,space,src1         */
421   { DRCUML_OP_READ2U,  op_read2u },   /* READ2U  dst,space,src1         */
422   { DRCUML_OP_READ2S,  op_read2s },   /* READ2S  dst,space,src1         */
423   { DRCUML_OP_READ2M,  op_read2m },   /* READ2M  dst,space,src1,mask    */
424   { DRCUML_OP_READ4U,  op_read4u },   /* READ4U  dst,space,src1         */
425   { DRCUML_OP_READ4S,  op_read4s },   /* READ4S  dst,space,src1         */
426   { DRCUML_OP_READ4M,  op_read4m },   /* READ4M  dst,space,src1,mask    */
427   { DRCUML_OP_READ8U,  op_read8u },   /* READ8U  dst,space,src1         */
428   { DRCUML_OP_READ8M,  op_read8m },   /* READ8M  dst,space,src1,mask    */
429   { DRCUML_OP_WRITE1,  op_write1 },   /* WRITE1  space,dst,src1         */
430   { DRCUML_OP_WRITE2,  op_write2 },   /* WRITE2  space,dst,src1         */
431   { DRCUML_OP_WRIT2M,  op_writ2m },   /* WRIT2M  space,dst,src1         */
432   { DRCUML_OP_WRITE4,  op_write4 },   /* WRITE4  space,dst,src1         */
433   { DRCUML_OP_WRIT4M,  op_writ4m },   /* WRIT4M  space,dst,mask,src1    */
434   { DRCUML_OP_WRITE8,  op_write8 },   /* WRITE8  space,dst,src1         */
435   { DRCUML_OP_WRIT8M,  op_writ8m },   /* WRIT8M  space,dst,mask,src1    */
436   { DRCUML_OP_FLAGS,   op_flags },   /* FLAGS   dst,mask,table         */
437   { DRCUML_OP_SETC,    op_setc },      /* FLAGS   src,bitnum             */
376   { DRCUML_OP_LOAD,    op_load },      /* LOAD    dst,base,index,size    */
377   { DRCUML_OP_LOADS,   op_loads },   /* LOADS   dst,base,index,size    */
378   { DRCUML_OP_STORE,   op_store },   /* STORE   base,index,src,size    */
379   { DRCUML_OP_READ,    op_read },      /* READ    dst,src1,spacesize     */
380   { DRCUML_OP_READM,   op_readm },   /* READM   dst,src1,mask,spacesize */
381   { DRCUML_OP_WRITE,   op_write },   /* WRITE   dst,src1,spacesize     */
382   { DRCUML_OP_WRITEM,  op_writem },   /* WRITEM  dst,src1,spacesize     */
383   { DRCUML_OP_CARRY,   op_carry },   /* CARRY   src,bitnum             */
384   { DRCUML_OP_SET,     op_set },      /* SET     dst,c                  */
438385   { DRCUML_OP_MOV,     op_mov },      /* MOV     dst,src[,c]            */
439   { DRCUML_OP_ZEXT1,   op_zext1 },   /* ZEXT1   dst,src                */
440   { DRCUML_OP_ZEXT2,   op_zext2 },   /* ZEXT2   dst,src                */
441   { DRCUML_OP_ZEXT4,   op_zext4 },   /* ZEXT4   dst,src                */
442   { DRCUML_OP_SEXT1,   op_sext1 },   /* SEXT1   dst,src                */
443   { DRCUML_OP_SEXT2,   op_sext2 },   /* SEXT2   dst,src                */
444   { DRCUML_OP_SEXT4,   op_sext4 },   /* SEXT4   dst,src                */
445   { DRCUML_OP_XTRACT,  op_xtract },   /* XTRACT  dst,src1,src2,src3     */
446   { DRCUML_OP_INSERT,  op_insert },   /* INSERT  dst,src1,src2,src3     */
386   { DRCUML_OP_SEXT,    op_sext },      /* SEXT    dst,src                */
387   { DRCUML_OP_ROLAND,  op_roland },   /* ROLAND  dst,src1,src2,src3     */
388   { DRCUML_OP_ROLINS,  op_rolins },   /* ROLINS  dst,src1,src2,src3     */
447389   { DRCUML_OP_ADD,     op_add },      /* ADD     dst,src1,src2[,f]      */
448390   { DRCUML_OP_ADDC,    op_addc },      /* ADDC    dst,src1,src2[,f]      */
449391   { DRCUML_OP_SUB,     op_sub },      /* SUB     dst,src1,src2[,f]      */
r2821r2822
470412   /* Floating Point Operations */
471413   { DRCUML_OP_FLOAD,   op_fload },   /* FLOAD   dst,base,index         */
472414   { DRCUML_OP_FSTORE,  op_fstore },   /* FSTORE  base,index,src         */
473   { DRCUML_OP_FREAD,   op_fread },   /* FREAD   dst,space,src1         */
474   { DRCUML_OP_FWRITE,  op_fwrite },   /* FWRITE  space,dst,src1         */
415   { DRCUML_OP_FREAD,   op_fread },   /* FREAD   dst,src1,space         */
416   { DRCUML_OP_FWRITE,  op_fwrite },   /* FWRITE  dst,src1,space         */
475417   { DRCUML_OP_FMOV,    op_fmov },      /* FMOV    dst,src1[,c]           */
476   { DRCUML_OP_FTOI4,   op_ftoi4 },   /* FTOI4   dst,src1               */
477   { DRCUML_OP_FTOI4T,  op_ftoi4t },   /* FTOI4T  dst,src1               */
478   { DRCUML_OP_FTOI4R,  op_ftoi4r },   /* FTOI4R  dst,src1               */
479   { DRCUML_OP_FTOI4F,  op_ftoi4f },   /* FTOI4F  dst,src1               */
480   { DRCUML_OP_FTOI4C,  op_ftoi4c },   /* FTOI4C  dst,src1               */
481   { DRCUML_OP_FTOI8,   op_ftoi8 },   /* FTOI8   dst,src1               */
482   { DRCUML_OP_FTOI8T,  op_ftoi8t },   /* FTOI8T  dst,src1               */
483   { DRCUML_OP_FTOI8R,  op_ftoi8r },   /* FTOI8R  dst,src1               */
484   { DRCUML_OP_FTOI8F,  op_ftoi8f },   /* FTOI8F  dst,src1               */
485   { DRCUML_OP_FTOI8C,  op_ftoi8c },   /* FTOI8C  dst,src1               */
486   { DRCUML_OP_FFRFS,   op_ffrfs },   /* FFRFS   dst,src1               */
487   { DRCUML_OP_FFRFD,   op_ffrfd },   /* FFRFD   dst,src1               */
488   { DRCUML_OP_FFRI4,   op_ffri4 },   /* FFRI4   dst,src1               */
489   { DRCUML_OP_FFRI8,   op_ffri8 },   /* FFRI8   dst,src1               */
418   { DRCUML_OP_FTOINT,  op_ftoint },   /* FTOINT  dst,src1,size,round    */
419   { DRCUML_OP_FFRINT,  op_ffrint },   /* FFRINT  dst,src1,size          */
420   { DRCUML_OP_FFRFLT,  op_ffrflt },   /* FFRFLT  dst,src1,size          */
421   { DRCUML_OP_FRNDS,   op_frnds },   /* FRNDS   dst,src1               */
490422   { DRCUML_OP_FADD,    op_fadd },      /* FADD    dst,src1,src2          */
491423   { DRCUML_OP_FSUB,    op_fsub },      /* FSUB    dst,src1,src2          */
492424   { DRCUML_OP_FCMP,    op_fcmp },      /* FCMP    src1,src2              */
r2821r2822
36033535
36043536
36053537/*-------------------------------------------------
3538    op_getflgs - process a GETFLGS opcode
3539-------------------------------------------------*/
3540
3541static x86code *op_getflgs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3542{
3543   drcuml_parameter dstp;
3544   int dstreg;
3545
3546   /* validate instruction */
3547   assert(inst->size == 4);
3548   assert(inst->condflags != DRCUML_COND_ALWAYS);
3549
3550   /* normalize parameters */
3551   param_normalize_1(drcbe, inst, &dstp, PTYPE_MR);
3552
3553   /* pick a target register for the general case */
3554   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3555
3556   switch (inst->condflags)
3557   {
3558      /* single flags only */
3559      case DRCUML_FLAG_C:
3560         emit_setcc_r8(&dst, COND_C, REG_AL);                              // setc   al
3561         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3562         break;
3563
3564      case DRCUML_FLAG_V:
3565         emit_setcc_r8(&dst, COND_O, REG_AL);                              // seto   al
3566         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3567         emit_shl_r32_imm(&dst, dstreg, 1);                                 // shl    dstreg,1
3568         break;
3569
3570      case DRCUML_FLAG_Z:
3571         emit_setcc_r8(&dst, COND_Z, REG_AL);                              // setz   al
3572         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3573         emit_shl_r32_imm(&dst, dstreg, 2);                                 // shl    dstreg,2
3574         break;
3575
3576      case DRCUML_FLAG_S:
3577         emit_setcc_r8(&dst, COND_S, REG_AL);                              // sets   al
3578         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3579         emit_shl_r32_imm(&dst, dstreg, 3);                                 // shl    dstreg,3
3580         break;
3581
3582      case DRCUML_FLAG_U:
3583         emit_setcc_r8(&dst, COND_P, REG_AL);                              // setp   al
3584         emit_movzx_r32_r8(&dst, dstreg, REG_AL);                           // movzx  dstreg,al
3585         emit_shl_r32_imm(&dst, dstreg, 4);                                 // shl    dstreg,4
3586         break;
3587
3588      /* carry plus another flag */
3589      case DRCUML_FLAG_C | DRCUML_FLAG_V:
3590         emit_setcc_r8(&dst, COND_C, REG_AL);                              // setc   al
3591         emit_setcc_r8(&dst, COND_O, REG_CL);                              // seto   cl
3592         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3593         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3594         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0));            // lea    dstreg,[eax+ecx*2]
3595         break;
3596
3597      case DRCUML_FLAG_C | DRCUML_FLAG_Z:
3598         emit_setcc_r8(&dst, COND_C, REG_AL);                              // setc   al
3599         emit_setcc_r8(&dst, COND_Z, REG_CL);                              // setz   cl
3600         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3601         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3602         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0));            // lea    dstreg,[eax+ecx*4]
3603         break;
3604
3605      case DRCUML_FLAG_C | DRCUML_FLAG_S:
3606         emit_setcc_r8(&dst, COND_C, REG_AL);                              // setc   al
3607         emit_setcc_r8(&dst, COND_S, REG_CL);                              // sets   cl
3608         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3609         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3610         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 8, 0));            // lea    dstreg,[eax+ecx*8]
3611         break;
3612
3613      /* overflow plus another flag */
3614      case DRCUML_FLAG_V | DRCUML_FLAG_Z:
3615         emit_setcc_r8(&dst, COND_O, REG_AL);                              // seto   al
3616         emit_setcc_r8(&dst, COND_Z, REG_CL);                              // setz   cl
3617         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3618         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3619         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0));            // lea    dstreg,[eax+ecx*2]
3620         emit_shl_r32_imm(&dst, dstreg, 1);                                 // shl    dstreg,1
3621         break;
3622
3623      case DRCUML_FLAG_V | DRCUML_FLAG_S:
3624         emit_setcc_r8(&dst, COND_O, REG_AL);                              // seto   al
3625         emit_setcc_r8(&dst, COND_S, REG_CL);                              // sets   cl
3626         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3627         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3628         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0));            // lea    dstreg,[eax+ecx*4]
3629         emit_shl_r32_imm(&dst, dstreg, 1);                                 // shl    dstreg,1
3630         break;
3631
3632      /* zero plus another flag */
3633      case DRCUML_FLAG_Z | DRCUML_FLAG_S:
3634         emit_setcc_r8(&dst, COND_Z, REG_AL);                              // setz   al
3635         emit_setcc_r8(&dst, COND_S, REG_CL);                              // sets   cl
3636         emit_movzx_r32_r8(&dst, REG_EAX, REG_AL);                           // movzx  eax,al
3637         emit_movzx_r32_r8(&dst, REG_ECX, REG_CL);                           // movzx  ecx,al
3638         emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0));            // lea    dstreg,[eax+ecx*2]
3639         emit_shl_r32_imm(&dst, dstreg, 2);                                 // shl    dstreg,2
3640         break;
3641
3642      /* default cases */
3643      default:
3644         emit_pushf(&dst);                                             // pushf
3645         emit_pop_r32(&dst, REG_EAX);                                    // pop    eax
3646         emit_and_r32_imm(&dst, REG_EAX, 0x8c5);                              // and    eax,0x8c5
3647         emit_movzx_r32_m8(&dst, dstreg, MBD(REG_EAX, flags_map));               // movzx  dstreg,[flags_map]
3648         break;
3649   }
3650
3651   /* store low 32 bits */
3652   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
3653
3654   /* 64-bit form stores upper 32 bits */
3655   if (inst->size == 8)
3656   {
3657      /* general case */
3658      if (dstp.type == DRCUML_PTYPE_MEMORY)
3659         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
3660      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
3661         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
3662   }
3663   return dst;
3664}
3665
3666
3667/*-------------------------------------------------
36063668    op_save - process a SAVE opcode
36073669-------------------------------------------------*/
36083670
r2821r2822
37263788***************************************************************************/
37273789
37283790/*-------------------------------------------------
3729    op_load1u - process a LOAD1U opcode
3791    op_load - process a LOAD opcode
37303792-------------------------------------------------*/
37313793
3732static x86code *op_load1u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3794static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
37333795{
3734   drcuml_parameter dstp, basep, indp;
3796   drcuml_parameter dstp, basep, indp, sizep;
37353797   int dstreg;
37363798
37373799   /* validate instruction */
r2821r2822
37393801   assert(inst->condflags == DRCUML_COND_ALWAYS);
37403802
37413803   /* normalize parameters */
3742   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3804   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI, &sizep, PTYPE_I);
37433805
37443806   /* pick a target register for the general case */
37453807   dstreg = param_select_register(REG_EAX, &dstp, NULL);
37463808
37473809   /* immediate index */
37483810   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3749      emit_movzx_r32_m8(&dst, dstreg, MABS(basep.value + 1*indp.value));            // movzx dstreg,[basep + 1*indp]
3811   {
3812      if (sizep.value == DRCUML_SIZE_BYTE)
3813         emit_movzx_r32_m8(&dst, dstreg, MABS(basep.value + 1*indp.value));         // movzx dstreg,[basep + 1*indp]
3814      else if (sizep.value == DRCUML_SIZE_WORD)
3815         emit_movzx_r32_m16(&dst, dstreg, MABS(basep.value + 2*indp.value));         // movzx dstreg,[basep + 2*indp]
3816      else if (sizep.value == DRCUML_SIZE_DWORD)
3817         emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + 4*indp.value));         // mov   dstreg,[basep + 4*indp]
3818      else if (sizep.value == DRCUML_SIZE_QWORD)
3819      {
3820         emit_mov_r32_m32(&dst, REG_EDX, MABS(basep.value + 8*indp.value + 4));      // mov   edx,[basep + 8*indp + 4]
3821         emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + 8*indp.value));         // mov   dstreg,[basep + 8*indp]
3822      }
3823   }
37503824
37513825   /* other index */
37523826   else
37533827   {
37543828      int indreg = param_select_register(REG_ECX, &indp, NULL);
37553829      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3756      emit_movzx_r32_m8(&dst, dstreg, MISD(indreg, 1, basep.value));               // movzx dstreg,[basep + 1*indp]
3830      if (sizep.value == DRCUML_SIZE_BYTE)
3831         emit_movzx_r32_m8(&dst, dstreg, MISD(indreg, 1, basep.value));            // movzx dstreg,[basep + 1*indp]
3832      else if (sizep.value == DRCUML_SIZE_WORD)
3833         emit_movzx_r32_m16(&dst, dstreg, MISD(indreg, 2, basep.value));            // movzx dstreg,[basep + 2*indp]
3834      else if (sizep.value == DRCUML_SIZE_DWORD)
3835         emit_mov_r32_m32(&dst, dstreg, MISD(indreg, 4, basep.value));            // mov   dstreg,[basep + 4*indp]
3836      else if (sizep.value == DRCUML_SIZE_QWORD)
3837      {
3838         emit_mov_r32_m32(&dst, REG_EDX, MISD(indreg, 8, basep.value + 4));         // mov   edx,[basep + 8*indp + 4]
3839         emit_mov_r32_m32(&dst, dstreg, MISD(indreg, 8, basep.value));            // mov   dstreg,[basep + 8*indp]
3840      }
37573841   }
37583842
37593843   /* store low 32 bits */
r2821r2822
37623846   /* 64-bit form stores upper 32 bits */
37633847   if (inst->size == 8)
37643848   {
3765      /* general case */
3766      if (dstp.type == DRCUML_PTYPE_MEMORY)
3767         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
3768      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
3769         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
3770   }
3771   return dst;
3772}
3849      /* 1, 2, or 4-byte case */
3850      if (sizep.value != DRCUML_SIZE_QWORD)
3851      {
3852         if (dstp.type == DRCUML_PTYPE_MEMORY)
3853            emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                  // mov   [dstp+4],0
3854         else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
3855            emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);            // mov   [reghi],0
3856      }
37733857
3774
3775/*-------------------------------------------------
3776    op_load1s - process a LOAD1S opcode
3777-------------------------------------------------*/
3778
3779static x86code *op_load1s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3780{
3781   drcuml_parameter dstp, basep, indp;
3782   int dstreg;
3783
3784   /* validate instruction */
3785   assert(inst->size == 4 || inst->size == 8);
3786   assert(inst->condflags == DRCUML_COND_ALWAYS);
3787
3788   /* normalize parameters */
3789   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3790
3791   /* pick a target register for the general case */
3792   dstreg = (inst->size == 8) ? REG_EAX : param_select_register(REG_EAX, &dstp, NULL);
3793
3794   /* immediate index */
3795   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3796      emit_movsx_r32_m8(&dst, dstreg, MABS(basep.value + 1*indp.value));            // movsx eax,[basep + 1*indp]
3797
3798   /* other index */
3799   else
3800   {
3801      int indreg = param_select_register(REG_ECX, &indp, NULL);
3802      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3803      emit_movsx_r32_m8(&dst, dstreg, MISD(indreg, 1, basep.value));               // movsx eax,[basep + 1*indp]
3858      /* 8-byte case */
3859      else
3860      {
3861         if (dstp.type == DRCUML_PTYPE_MEMORY)
3862            emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX);               // mov   [dstp+4],edx
3863         else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
3864            emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX);      // mov   [reghi],edx
3865      }
38043866   }
3805
3806   /* 32-bit form */
3807   if (inst->size == 4)
3808   {
3809      /* general case */
3810      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3811   }
3812
3813   /* 64-bit form */
3814   else
3815   {
3816      /* general case */
3817      emit_cdq(&dst);                                                   // cdq
3818      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
3819   }
38203867   return dst;
38213868}
38223869
38233870
38243871/*-------------------------------------------------
3825    op_load2u - process a LOAD2U opcode
3872    op_loads - process a LOADS opcode
38263873-------------------------------------------------*/
38273874
3828static x86code *op_load2u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3875static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
38293876{
3830   drcuml_parameter dstp, basep, indp;
3877   drcuml_parameter dstp, basep, indp, sizep;
38313878   int dstreg;
38323879
38333880   /* validate instruction */
r2821r2822
38353882   assert(inst->condflags == DRCUML_COND_ALWAYS);
38363883
38373884   /* normalize parameters */
3838   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3885   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI, &sizep, PTYPE_I);
38393886
38403887   /* pick a target register for the general case */
38413888   dstreg = param_select_register(REG_EAX, &dstp, NULL);
38423889
38433890   /* immediate index */
38443891   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3845      emit_movzx_r32_m16(&dst, dstreg, MABS(basep.value + 2*indp.value));            // movzx dstreg,[basep + 2*indp]
3846
3847   /* other index */
3848   else
38493892   {
3850      int indreg = param_select_register(REG_ECX, &indp, NULL);
3851      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3852      emit_movzx_r32_m16(&dst, dstreg, MISD(indreg, 2, basep.value));               // movzx dstreg,[basep + 2*indp]
3893      if (sizep.value == DRCUML_SIZE_BYTE)
3894         emit_movsx_r32_m8(&dst, dstreg, MABS(basep.value + 1*indp.value));         // movsx dstreg,[basep + 1*indp]
3895      else if (sizep.value == DRCUML_SIZE_WORD)
3896         emit_movsx_r32_m16(&dst, dstreg, MABS(basep.value + 2*indp.value));         // movsx dstreg,[basep + 2*indp]
3897      else if (sizep.value == DRCUML_SIZE_DWORD)
3898         emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + 4*indp.value));         // mov   dstreg,[basep + 4*indp]
3899      else if (sizep.value == DRCUML_SIZE_QWORD)
3900      {
3901         emit_mov_r32_m32(&dst, REG_EDX, MABS(basep.value + 8*indp.value + 4));      // mov   edx,[basep + 8*indp + 4]
3902         emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + 8*indp.value));         // mov   dstreg,[basep + 8*indp]
3903      }
38533904   }
38543905
3855   /* store low 32 bits */
3856   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
3857
3858   /* 64-bit form stores upper 32 bits */
3859   if (inst->size == 8)
3860   {
3861      /* general case */
3862      if (dstp.type == DRCUML_PTYPE_MEMORY)
3863         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
3864      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
3865         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
3866   }
3867   return dst;
3868}
3869
3870
3871/*-------------------------------------------------
3872    op_load2s - process a LOAD2S opcode
3873-------------------------------------------------*/
3874
3875static x86code *op_load2s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3876{
3877   drcuml_parameter dstp, basep, indp;
3878   int dstreg;
3879
3880   /* validate instruction */
3881   assert(inst->size == 4 || inst->size == 8);
3882   assert(inst->condflags == DRCUML_COND_ALWAYS);
3883
3884   /* normalize parameters */
3885   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3886
3887   /* pick a target register for the general case */
3888   dstreg = (inst->size == 8) ? REG_EAX : param_select_register(REG_EAX, &dstp, NULL);
3889
3890   /* immediate index */
3891   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3892      emit_movsx_r32_m16(&dst, dstreg, MABS(basep.value + 2*indp.value));            // movsx eax,[basep + 2*indp]
3893
38943906   /* other index */
38953907   else
38963908   {
38973909      int indreg = param_select_register(REG_ECX, &indp, NULL);
38983910      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3899      emit_movsx_r32_m16(&dst, dstreg, MISD(indreg, 2, basep.value));               // movsx eax,[basep + 2*indp]
3911      if (sizep.value == DRCUML_SIZE_BYTE)
3912         emit_movsx_r32_m8(&dst, dstreg, MISD(indreg, 1, basep.value));            // movsx dstreg,[basep + 1*indp]
3913      else if (sizep.value == DRCUML_SIZE_WORD)
3914         emit_movsx_r32_m16(&dst, dstreg, MISD(indreg, 2, basep.value));            // movsx dstreg,[basep + 2*indp]
3915      else if (sizep.value == DRCUML_SIZE_DWORD)
3916         emit_mov_r32_m32(&dst, dstreg, MISD(indreg, 4, basep.value));            // mov   dstreg,[basep + 4*indp]
3917      else if (sizep.value == DRCUML_SIZE_QWORD)
3918      {
3919         emit_mov_r32_m32(&dst, REG_EDX, MISD(indreg, 8, basep.value + 4));         // mov   edx,[basep + 8*indp + 4]
3920         emit_mov_r32_m32(&dst, dstreg, MISD(indreg, 8, basep.value));            // mov   dstreg,[basep + 8*indp]
3921      }
39003922   }
39013923
3902   /* 32-bit form */
3903   if (inst->size == 4)
3904   {
3905      /* general case */
3906      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
3907   }
3908
3909   /* 64-bit form */
3910   else
3911   {
3912      /* general case */
3913      emit_cdq(&dst);                                                   // cdq
3914      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
3915   }
3916   return dst;
3917}
3918
3919
3920/*-------------------------------------------------
3921    op_load4u - process a LOAD4U opcode
3922-------------------------------------------------*/
3923
3924static x86code *op_load4u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3925{
3926   drcuml_parameter dstp, basep, indp;
3927   int dstreg;
3928
3929   /* validate instruction */
3930   assert(inst->size == 4 || inst->size == 8);
3931   assert(inst->condflags == DRCUML_COND_ALWAYS);
3932
3933   /* normalize parameters */
3934   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3935
3936   /* pick a target register for the general case */
3937   dstreg = param_select_register(REG_EAX, &dstp, NULL);
3938
3939   /* immediate index */
3940   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3941      emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + 4*indp.value));            // mov   dstreg,[basep + 4*indp]
3942
3943   /* other index */
3944   else
3945   {
3946      int indreg = param_select_register(REG_ECX, &indp, NULL);
3947      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3948      emit_mov_r32_m32(&dst, dstreg, MISD(indreg, 4, basep.value));               // mov   dstreg,[basep + 4*indp]
3949   }
3950
39513924   /* store low 32 bits */
39523925   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
39533926
39543927   /* 64-bit form stores upper 32 bits */
39553928   if (inst->size == 8)
39563929   {
3957      /* general case */
3930      emit_cdq(&dst);                                                   // cdq
39583931      if (dstp.type == DRCUML_PTYPE_MEMORY)
3959         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
3932         emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX);                  // mov   [dstp+4],edx
39603933      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
3961         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
3934         emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX);         // mov   [reghi],edx
39623935   }
39633936   return dst;
39643937}
39653938
39663939
39673940/*-------------------------------------------------
3968    op_load4s - process a LOAD4S opcode
3941    op_store - process a STORE opcode
39693942-------------------------------------------------*/
39703943
3971static x86code *op_load4s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
3944static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
39723945{
3973   drcuml_parameter dstp, basep, indp;
3974
3975   /* validate instruction */
3976   assert(inst->size == 8);
3977   assert(inst->condflags == DRCUML_COND_ALWAYS);
3978
3979   /* normalize parameters */
3980   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
3981
3982   /* immediate index */
3983   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
3984      emit_mov_r32_m32(&dst, REG_EAX, MABS(basep.value + 4*indp.value));            // mov   eax,[basep + 4*indp]
3985
3986   /* other index */
3987   else
3988   {
3989      int indreg = param_select_register(REG_ECX, &indp, NULL);
3990      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
3991      emit_mov_r32_m32(&dst, REG_EAX, MISD(indreg, 4, basep.value));               // movsx eax,[basep + 4*indp]
3992   }
3993
3994   /* general case */
3995   emit_cdq(&dst);                                                      // cdq
3996   emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                        // mov   dstp,edx:eax
3997
3998   return dst;
3999}
4000
4001
4002/*-------------------------------------------------
4003    op_load8u - process a LOAD8U opcode
4004-------------------------------------------------*/
4005
4006static x86code *op_load8u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4007{
4008   drcuml_parameter dstp, basep, indp;
4009   int dstreg;
4010
4011   /* validate instruction */
4012   assert(inst->size == 8);
4013   assert(inst->condflags == DRCUML_COND_ALWAYS);
4014
4015   /* normalize parameters */
4016   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI);
4017
4018   /* pick a target register for the general case */
4019   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4020
4021   /* immediate index */
4022   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
4023   {
4024      emit_mov_r32_m32(&dst, REG_EDX, MABS(basep.value + 8*indp.value + 4));         // mov   edx,[basep + 8*indp + 4]
4025      emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + 8*indp.value));            // mov   dstreg,[basep + 8*indp]
4026   }
4027
4028   /* other index */
4029   else
4030   {
4031      int indreg = param_select_register(REG_ECX, &indp, NULL);
4032      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
4033      emit_mov_r32_m32(&dst, REG_EDX, MISD(indreg, 8, basep.value + 4));            // mov   edx,[basep + 8*indp + 4]
4034      emit_mov_r32_m32(&dst, dstreg, MISD(indreg, 8, basep.value));               // mov   dstreg,[basep + 8*indp]
4035   }
4036
4037   /* general case */
4038   emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX);                        // mov   dstp,edx:dstreg
4039
4040   return dst;
4041}
4042
4043
4044/*-------------------------------------------------
4045    op_store1 - process a STORE1 opcode
4046-------------------------------------------------*/
4047
4048static x86code *op_store1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4049{
4050   drcuml_parameter srcp, basep, indp;
3946   drcuml_parameter srcp, basep, indp, sizep;
40513947   int srcreg;
40523948
40533949   /* validate instruction */
r2821r2822
40553951   assert(inst->condflags == DRCUML_COND_ALWAYS);
40563952
40573953   /* normalize parameters */
4058   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI);
3954   param_normalize_4(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI, &sizep, PTYPE_I);
40593955
40603956   /* pick a source register for the general case */
40613957   srcreg = param_select_register(REG_EAX, &srcp, NULL);
4062   if (srcreg & 4)
3958   if (sizep.value == DRCUML_SIZE_BYTE && (srcreg & 4))
40633959      srcreg = REG_EAX;
40643960
40653961   /* degenerate case: constant index */
40663962   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
40673963   {
3964      /* immediate source */
40683965      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4069         emit_mov_m8_imm(&dst, MABS(basep.value + 1*indp.value), srcp.value);      // mov   [basep + 1*indp],srcp
4070      else
40713966      {
4072         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4073         emit_mov_m8_r8(&dst, MABS(basep.value + 1*indp.value), srcreg);            // mov   [basep + 1*indp],srcreg
3967         if (sizep.value == DRCUML_SIZE_BYTE)
3968            emit_mov_m8_imm(&dst, MABS(basep.value + 1*indp.value), srcp.value);   // mov   [basep + 1*indp],srcp
3969         else if (sizep.value == DRCUML_SIZE_WORD)
3970            emit_mov_m16_imm(&dst, MABS(basep.value + 2*indp.value), srcp.value);   // mov   [basep + 2*indp],srcp
3971         else if (sizep.value == DRCUML_SIZE_DWORD)
3972            emit_mov_m32_imm(&dst, MABS(basep.value + 4*indp.value), srcp.value);   // mov   [basep + 4*indp],srcp
3973         else if (sizep.value == DRCUML_SIZE_QWORD)
3974         {
3975            emit_mov_m32_imm(&dst, MABS(basep.value + 8*indp.value), srcp.value);   // mov   [basep + 8*indp],srcp
3976            emit_mov_m32_imm(&dst, MABS(basep.value + 8*indp.value + 4), srcp.value >> 32);
3977                                                                  // mov   [basep + 8*indp + 4],srcp >> 32
3978         }
40743979      }
4075   }
40763980
4077   /* normal case: variable index */
4078   else
4079   {
4080      int indreg = param_select_register(REG_ECX, &indp, NULL);
4081      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);                           // mov   indreg,indp
4082      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4083         emit_mov_m8_imm(&dst, MISD(indreg, 1, basep.value), srcp.value);         // mov   [basep + 1*ecx],srcp
3981      /* variable source */
40843982      else
40853983      {
4086         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4087         emit_mov_m8_r8(&dst, MISD(indreg, 1, basep.value), srcreg);               // mov   [basep + 1*ecx],srcreg
3984         if (sizep.value != DRCUML_SIZE_QWORD)
3985            emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                     // mov   srcreg,srcp
3986         else
3987            emit_mov_r64_p64(drcbe, &dst, srcreg, REG_EDX, &srcp);               // mov   edx:srcreg,srcp
3988         if (sizep.value == DRCUML_SIZE_BYTE)
3989            emit_mov_m8_r8(&dst, MABS(basep.value + 1*indp.value), srcreg);         // mov   [basep + 1*indp],srcreg
3990         else if (sizep.value == DRCUML_SIZE_WORD)
3991            emit_mov_m16_r16(&dst, MABS(basep.value + 2*indp.value), srcreg);      // mov   [basep + 2*indp],srcreg
3992         else if (sizep.value == DRCUML_SIZE_DWORD)
3993            emit_mov_m32_r32(&dst, MABS(basep.value + 4*indp.value), srcreg);      // mov   [basep + 4*indp],srcreg
3994         else if (sizep.value == DRCUML_SIZE_QWORD)
3995         {
3996            emit_mov_m32_r32(&dst, MABS(basep.value + 8*indp.value), srcreg);      // mov   [basep + 8*indp],srcreg
3997            emit_mov_m32_r32(&dst, MABS(basep.value + 8*indp.value + 4), REG_EDX);   // mov   [basep + 8*indp + 4],edx
3998         }
40883999      }
40894000   }
4090   return dst;
4091}
40924001
4093
4094/*-------------------------------------------------
4095    op_store2 - process a STORE2 opcode
4096-------------------------------------------------*/
4097
4098static x86code *op_store2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4099{
4100   drcuml_parameter srcp, basep, indp;
4101   int srcreg;
4102
4103   /* validate instruction */
4104   assert(inst->size == 4 || inst->size == 8);
4105   assert(inst->condflags == DRCUML_COND_ALWAYS);
4106
4107   /* normalize parameters */
4108   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI);
4109
4110   /* pick a source register for the general case */
4111   srcreg = param_select_register(REG_EAX, &srcp, NULL);
4112
4113   /* degenerate case: constant index */
4114   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
4115   {
4116      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4117         emit_mov_m16_imm(&dst, MABS(basep.value + 2*indp.value), srcp.value);      // mov   [basep + 2*indp],srcp
4118      else
4119      {
4120         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4121         emit_mov_m16_r16(&dst, MABS(basep.value + 2*indp.value), srcreg);         // mov   [basep + 2*indp],srcreg
4122      }
4123   }
4124
41254002   /* normal case: variable index */
41264003   else
41274004   {
41284005      int indreg = param_select_register(REG_ECX, &indp, NULL);
41294006      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);                           // mov   indreg,indp
4130      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4131         emit_mov_m16_imm(&dst, MISD(indreg, 2, basep.value), srcp.value);         // mov   [basep + 2*ecx],srcp
4132      else
4133      {
4134         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4135         emit_mov_m16_r16(&dst, MISD(indreg, 2, basep.value), srcreg);            // mov   [basep + 2*ecx],srcreg
4136      }
4137   }
4138   return dst;
4139}
41404007
4141
4142/*-------------------------------------------------
4143    op_store4 - process a STORE4 opcode
4144-------------------------------------------------*/
4145
4146static x86code *op_store4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4147{
4148   drcuml_parameter srcp, basep, indp;
4149   int srcreg;
4150
4151   /* validate instruction */
4152   assert(inst->size == 4 || inst->size == 8);
4153   assert(inst->condflags == DRCUML_COND_ALWAYS);
4154
4155   /* normalize parameters */
4156   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI);
4157
4158   /* pick a source register for the general case */
4159   srcreg = param_select_register(REG_EAX, &srcp, NULL);
4160
4161   /* degenerate case: constant index */
4162   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
4163   {
4008      /* immediate source */
41644009      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4165         emit_mov_m32_imm(&dst, MABS(basep.value + 4*indp.value), srcp.value);      // mov   [basep + 4*indp],srcp
4166      else
41674010      {
4168         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4169         emit_mov_m32_r32(&dst, MABS(basep.value + indp.value), srcreg);            // mov   [basep + 4*indp],srcreg
4011         if (sizep.value == DRCUML_SIZE_BYTE)
4012            emit_mov_m8_imm(&dst, MISD(indreg, 1, basep.value), srcp.value);      // mov   [basep + 1*ecx],srcp
4013         else if (sizep.value == DRCUML_SIZE_WORD)
4014            emit_mov_m16_imm(&dst, MISD(indreg, 2, basep.value), srcp.value);      // mov   [basep + 2*ecx],srcp
4015         else if (sizep.value == DRCUML_SIZE_DWORD)
4016            emit_mov_m32_imm(&dst, MISD(indreg, 4, basep.value), srcp.value);      // mov   [basep + 4*ecx],srcp
4017         else if (sizep.value == DRCUML_SIZE_QWORD)
4018         {
4019            emit_mov_m32_imm(&dst, MISD(indreg, 8, basep.value), srcp.value);      // mov   [basep + 8*ecx],srcp
4020            emit_mov_m32_imm(&dst, MISD(indreg, 8, basep.value + 4), srcp.value >> 32);
4021                                                                  // mov   [basep + 8*ecx + 4],srcp >> 32
4022         }
41704023      }
4171   }
41724024
4173   /* normal case: variable index */
4174   else
4175   {
4176      int indreg = param_select_register(REG_ECX, &indp, NULL);
4177      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);                           // mov   indreg,indp
4178      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4179         emit_mov_m32_imm(&dst, MISD(indreg, 4, basep.value), srcp.value);         // mov   [basep + 4*ecx],srcp
4025      /* variable source */
41804026      else
41814027      {
4182         emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                        // mov   srcreg,srcp
4183         emit_mov_m32_r32(&dst, MISD(indreg, 4, basep.value), srcreg);            // mov   [basep + 4*ecx],srcreg
4028         if (sizep.value != DRCUML_SIZE_QWORD)
4029            emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp);                     // mov   srcreg,srcp
4030         else
4031            emit_mov_r64_p64(drcbe, &dst, srcreg, REG_EDX, &srcp);               // mov   edx:srcreg,srcp
4032         if (sizep.value == DRCUML_SIZE_BYTE)
4033            emit_mov_m8_r8(&dst, MISD(indreg, 1, basep.value), srcreg);            // mov   [basep + 1*ecx],srcreg
4034         else if (sizep.value == DRCUML_SIZE_WORD)
4035            emit_mov_m16_r16(&dst, MISD(indreg, 2, basep.value), srcreg);         // mov   [basep + 2*ecx],srcreg
4036         else if (sizep.value == DRCUML_SIZE_DWORD)
4037            emit_mov_m32_r32(&dst, MISD(indreg, 4, basep.value), srcreg);         // mov   [basep + 4*ecx],srcreg
4038         else if (sizep.value == DRCUML_SIZE_QWORD)
4039         {
4040            emit_mov_m32_r32(&dst, MISD(indreg, 8, basep.value), srcreg);         // mov   [basep + 8*ecx],srcreg
4041            emit_mov_m32_r32(&dst, MISD(indreg, 8, basep.value + 4), REG_EDX);      // mov   [basep + 8*ecx],edx
4042         }
41844043      }
41854044   }
41864045   return dst;
r2821r2822
41884047
41894048
41904049/*-------------------------------------------------
4191    op_store8 - process a STORE8 opcode
4050    op_read - process a READ opcode
41924051-------------------------------------------------*/
41934052
4194static x86code *op_store8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4053static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
41954054{
4196   drcuml_parameter srcp, basep, indp;
4197   int srcreg;
4198
4199   /* validate instruction */
4200   assert(inst->size == 8);
4201   assert(inst->condflags == DRCUML_COND_ALWAYS);
4202
4203   /* normalize parameters */
4204   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI);
4205
4206   /* pick a source register for the general case */
4207   srcreg = param_select_register(REG_EAX, &srcp, NULL);
4208
4209   /* degenerate case: constant index */
4210   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
4211   {
4212      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4213      {
4214         emit_mov_m32_imm(&dst, MABS(basep.value + 8*indp.value), srcp.value);      // mov   [basep + 8*indp],srcp
4215         emit_mov_m32_imm(&dst, MABS(basep.value + 4 + 8*indp.value), srcp.value >> 32);
4216                                                                  // mov   [basep + 4 + 8*indp],srcp >> 32
4217      }
4218      else
4219      {
4220         emit_mov_r64_p64(drcbe, &dst, srcreg, REG_EDX, &srcp);                  // mov   edx:srcreg,srcp
4221         emit_mov_m32_r32(&dst, MABS(basep.value + 8*indp.value), srcreg);         // mov   [basep + 8*indp],srcreg
4222         emit_mov_m32_r32(&dst, MABS(basep.value + 4 + 8*indp.value), REG_EDX);      // mov   [basep + 8*indp + 4],edx
4223      }
4224   }
4225
4226   /* normal case: variable index */
4227   else
4228   {
4229      int indreg = param_select_register(REG_ECX, &indp, NULL);
4230      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);                           // mov   indreg,indp
4231      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
4232      {
4233         emit_mov_m32_imm(&dst, MISD(indreg, 8, basep.value), srcp.value);         // mov   [basep + 8*ecx],srcp
4234         emit_mov_m32_imm(&dst, MISD(indreg, 8, basep.value + 4), srcp.value >> 32);   // mov   [basep + 8*ecx + 4],srcp >> 32
4235      }
4236      else
4237      {
4238         emit_mov_r64_p64(drcbe, &dst, srcreg, REG_EDX, &srcp);                  // mov   edx:srcreg,srcp
4239         emit_mov_m32_r32(&dst, MISD(indreg, 8, basep.value), srcreg);            // mov   [basep + 8*ecx],srcreg
4240         emit_mov_m32_r32(&dst, MISD(indreg, 8, basep.value + 4), REG_EDX);         // mov   [basep + 4 + 8*ecx],edx
4241      }
4242   }
4243   return dst;
4244}
4245
4246
4247/*-------------------------------------------------
4248    op_read1u - process a READ1U opcode
4249-------------------------------------------------*/
4250
4251static x86code *op_read1u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4252{
4253   drcuml_parameter dstp, spacep, addrp;
4055   drcuml_parameter dstp, addrp, spacesizep;
42544056   int dstreg;
42554057
42564058   /* validate instruction */
r2821r2822
42584060   assert(inst->condflags == DRCUML_COND_ALWAYS);
42594061
42604062   /* normalize parameters */
4261   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4063   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &addrp, PTYPE_MRI, &spacesizep, PTYPE_I);
42624064
42634065   /* pick a target register for the general case */
42644066   dstreg = param_select_register(REG_EAX, &dstp, NULL);
42654067
42664068   /* set up a call to the read byte handler */
42674069   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4268   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_byte);// call   read_byte
4269   emit_add_r32_imm(&dst, REG_ESP, 4);                                       // add    esp,4
4270   emit_movzx_r32_r8(&dst, dstreg, REG_AL);                                 // movzx  dstreg,al
4271
4272   /* store low 32 bits */
4273   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
4274
4275   /* 64-bit form stores upper 32 bits */
4276   if (inst->size == 8)
4070   if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE)
42774071   {
4278      /* general case */
4279      if (dstp.type == DRCUML_PTYPE_MEMORY)
4280         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
4281      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4282         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
4072      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->read_byte);
4073                                                                  // call   read_byte
4074      emit_movzx_r32_r8(&dst, dstreg, REG_AL);                              // movzx  dstreg,al
42834075   }
4284   return dst;
4285}
4286
4287
4288/*-------------------------------------------------
4289    op_read1s - process a READ1S opcode
4290-------------------------------------------------*/
4291
4292static x86code *op_read1s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4293{
4294   drcuml_parameter dstp, spacep, addrp;
4295   int dstreg;
4296
4297   /* validate instruction */
4298   assert(inst->size == 4 || inst->size == 8);
4299   assert(inst->condflags == DRCUML_COND_ALWAYS);
4300
4301   /* normalize parameters */
4302   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4303
4304   /* pick a target register for the general case */
4305   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4306
4307   /* set up a call to the read byte handler */
4308   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4309   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_byte);// call   read_byte
4310   emit_add_r32_imm(&dst, REG_ESP, 4);                                       // add    esp,4
4311   emit_movsx_r32_r8(&dst, dstreg, REG_AL);                                 // movsx  dstreg,al
4312
4313   /* 32-bit form */
4314   if (inst->size == 4)
4076   else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
43154077   {
4316      /* general case */
4317      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4078      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->read_word);
4079                                                                  // call   read_word
4080      emit_movzx_r32_r16(&dst, dstreg, REG_AX);                              // movzx  dstreg,ax
43184081   }
4319
4320   /* 64-bit form */
4321   else
4082   else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
43224083   {
4323      /* general case */
4324      emit_cdq(&dst);                                                   // cdq
4325      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
4084      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->read_dword);
4085                                                                  // call   read_dword
4086      emit_mov_r32_r32(&dst, dstreg, REG_EAX);                              // mov    dstreg,eax
43264087   }
4327   return dst;
4328}
4329
4330
4331/*-------------------------------------------------
4332    op_read2u - process a READ2U opcode
4333-------------------------------------------------*/
4334
4335static x86code *op_read2u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4336{
4337   drcuml_parameter dstp, spacep, addrp;
4338   int dstreg;
4339
4340   /* validate instruction */
4341   assert(inst->size == 4 || inst->size == 8);
4342   assert(inst->condflags == DRCUML_COND_ALWAYS);
4343
4344   /* normalize parameters */
4345   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4346
4347   /* pick a target register for the general case */
4348   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4349
4350   /* set up a call to the read word handler */
4351   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4352   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_word);// call   read_word
4088   else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
4089   {
4090      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->read_qword);
4091                                                                  // call   read_qword
4092      emit_mov_r32_r32(&dst, dstreg, REG_EAX);                              // mov    dstreg,eax
4093   }
43534094   emit_add_r32_imm(&dst, REG_ESP, 4);                                       // add    esp,4
4354   emit_movzx_r32_r16(&dst, dstreg, REG_AX);                                 // movzx  dstreg,ax
43554095
43564096   /* store low 32 bits */
4357   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
4097   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov    dstp,dstreg
43584098
43594099   /* 64-bit form stores upper 32 bits */
43604100   if (inst->size == 8)
43614101   {
4362      /* general case */
4363      if (dstp.type == DRCUML_PTYPE_MEMORY)
4364         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
4365      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4366         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
4102      /* 1, 2, or 4-byte case */
4103      if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD)
4104      {
4105         if (dstp.type == DRCUML_PTYPE_MEMORY)
4106            emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                  // mov   [dstp+4],0
4107         else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4108            emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);            // mov   [reghi],0
4109      }
4110
4111      /* 8-byte case */
4112      else
4113      {
4114         if (dstp.type == DRCUML_PTYPE_MEMORY)
4115            emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX);               // mov   [dstp+4],edx
4116         else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4117            emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX);      // mov   [reghi],edx
4118      }
43674119   }
43684120   return dst;
43694121}
43704122
43714123
43724124/*-------------------------------------------------
4373    op_read2s - process a READ2S opcode
4125    op_readm - process a READM opcode
43744126-------------------------------------------------*/
43754127
4376static x86code *op_read2s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4128static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
43774129{
4378   drcuml_parameter dstp, spacep, addrp;
4130   drcuml_parameter dstp, addrp, maskp, spacesizep;
43794131   int dstreg;
43804132
43814133   /* validate instruction */
r2821r2822
43834135   assert(inst->condflags == DRCUML_COND_ALWAYS);
43844136
43854137   /* normalize parameters */
4386   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4138   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &spacesizep, PTYPE_I);
43874139
43884140   /* pick a target register for the general case */
43894141   dstreg = param_select_register(REG_EAX, &dstp, NULL);
43904142
4391   /* set up a call to the read word handler */
4143   /* set up a call to the read byte handler */
4144   if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD)
4145      emit_push_p32(drcbe, &dst, &maskp);                                    // push   maskp
4146   else
4147      emit_push_p64(drcbe, &dst, &maskp);                                    // push   maskp
43924148   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4393   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_word);// call   read_word
4394   emit_add_r32_imm(&dst, REG_ESP, 4);                                       // add    esp,4
4395   emit_movsx_r32_r16(&dst, dstreg, REG_AX);                                 // movsx  dstreg,ax
4396
4397   /* 32-bit form */
4398   if (inst->size == 4)
4149   if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
43994150   {
4400      /* general case */
4401      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4151      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->read_word_masked);
4152                                                                  // call   read_word_masked
4153      emit_movzx_r32_r16(&dst, dstreg, REG_AX);                              // movzx  dstreg,ax
44024154   }
4403
4404   /* 64-bit form */
4405   else
4155   else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
44064156   {
4407      /* general case */
4408      emit_cdq(&dst);                                                   // cdq
4409      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
4157      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->read_dword_masked);
4158                                                                  // call   read_dword_masked
4159      emit_mov_r32_r32(&dst, dstreg, REG_EAX);                              // mov    dstreg,eax
44104160   }
4411   return dst;
4412}
4413
4414
4415/*-------------------------------------------------
4416    op_read2m - process a READ2M opcode
4417-------------------------------------------------*/
4418
4419static x86code *op_read2m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4420{
4421   drcuml_parameter dstp, spacep, addrp, maskp;
4422   int dstreg;
4423
4424   /* validate instruction */
4425   assert(inst->size == 4 || inst->size == 8);
4426   assert(inst->condflags == DRCUML_COND_ALWAYS);
4427
4428   /* normalize parameters */
4429   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI);
4430
4431   /* pick a target register for the general case */
4432   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4433
4434   /* set up a call to the read dword masked handler */
4435   emit_push_p32(drcbe, &dst, &maskp);                                       // push   maskp
4436   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4437   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_word_masked);
4438                                                                  // call   read_word_masked
4439   emit_add_r32_imm(&dst, REG_ESP, 8);                                       // add    esp,8
4440   emit_movzx_r32_r16(&dst, dstreg, REG_AX);                                 // movzx  dstreg,ax
4441
4442   /* store low 32 bits */
4443   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
4444
4445   /* 64-bit form stores upper 32 bits */
4446   if (inst->size == 8)
4161   else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
44474162   {
4448      /* general case */
4449      if (dstp.type == DRCUML_PTYPE_MEMORY)
4450         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
4451      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4452         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
4163      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->read_qword_masked);
4164                                                                  // call   read_qword_masked
4165      emit_mov_r32_r32(&dst, dstreg, REG_EAX);                              // mov    dstreg,eax
44534166   }
4454   return dst;
4455}
4456
4457
4458/*-------------------------------------------------
4459    op_read4u - process a READ4U opcode
4460-------------------------------------------------*/
4461
4462static x86code *op_read4u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4463{
4464   drcuml_parameter dstp, spacep, addrp;
4465
4466   /* validate instruction */
4467   assert(inst->size == 4 || inst->size == 8);
4468   assert(inst->condflags == DRCUML_COND_ALWAYS);
4469
4470   /* normalize parameters */
4471   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4472
4473   /* set up a call to the read dword handler */
4474   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4475   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_dword);// call   read_dword
4476   emit_add_r32_imm(&dst, REG_ESP, 4);                                       // add    esp,4
4477
4167   emit_add_r32_imm(&dst, REG_ESP, ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) ? 8 : 12);
4168                                                                  // add    esp,8/12
44784169   /* store low 32 bits */
4479   emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX);                              // mov   dstp,eax
4170   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov    dstp,dstreg
44804171
44814172   /* 64-bit form stores upper 32 bits */
44824173   if (inst->size == 8)
44834174   {
4484      /* general case */
4485      if (dstp.type == DRCUML_PTYPE_MEMORY)
4486         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
4487      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4488         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
4489   }
4490   return dst;
4491}
4175      /* 1, 2, or 4-byte case */
4176      if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD)
4177      {
4178         if (dstp.type == DRCUML_PTYPE_MEMORY)
4179            emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                  // mov   [dstp+4],0
4180         else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4181            emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);            // mov   [reghi],0
4182      }
44924183
4493
4494/*-------------------------------------------------
4495    op_read4s - process a READ4S opcode
4496-------------------------------------------------*/
4497
4498static x86code *op_read4s(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4499{
4500   drcuml_parameter dstp, spacep, addrp;
4501
4502   /* validate instruction */
4503   assert(inst->size == 8);
4504   assert(inst->condflags == DRCUML_COND_ALWAYS);
4505
4506   /* normalize parameters */
4507   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4508
4509   /* set up a call to the read dword handler */
4510   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4511   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_dword);// call   read_dword
4512   emit_add_r32_imm(&dst, REG_ESP, 4);                                       // add    esp,4
4513
4514   /* 64-bit form */
4515   emit_cdq(&dst);                                                      // cdq
4516   emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                        // mov   dst,edx:eax
4517
4518   return dst;
4519}
4520
4521
4522/*-------------------------------------------------
4523    op_read4m - process a READ4M opcode
4524-------------------------------------------------*/
4525
4526static x86code *op_read4m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4527{
4528   drcuml_parameter dstp, spacep, addrp, maskp;
4529
4530   /* validate instruction */
4531   assert(inst->size == 4 || inst->size == 8);
4532   assert(inst->condflags == DRCUML_COND_ALWAYS);
4533
4534   /* normalize parameters */
4535   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI);
4536
4537   /* set up a call to the read dword masked handler */
4538   emit_push_p32(drcbe, &dst, &maskp);                                       // push   maskp
4539   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4540   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_dword_masked);
4541                                                                  // call   read_dword_masked
4542   emit_add_r32_imm(&dst, REG_ESP, 8);                                       // add    esp,8
4543
4544   /* store low 32 bits */
4545   emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX);                              // mov   dstp,eax
4546
4547   /* 64-bit form stores upper 32 bits */
4548   if (inst->size == 8)
4549   {
4550      /* general case */
4551      if (dstp.type == DRCUML_PTYPE_MEMORY)
4552         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
4553      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4554         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
4184      /* 8-byte case */
4185      else
4186      {
4187         if (dstp.type == DRCUML_PTYPE_MEMORY)
4188            emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX);               // mov   [dstp+4],edx
4189         else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4190            emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX);      // mov   [reghi],edx
4191      }
45554192   }
45564193   return dst;
45574194}
45584195
45594196
45604197/*-------------------------------------------------
4561    op_read8u - process a READ8U opcode
4198    op_write - process a WRITE opcode
45624199-------------------------------------------------*/
45634200
4564static x86code *op_read8u(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4201static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
45654202{
4566   drcuml_parameter dstp, spacep, addrp;
4203   drcuml_parameter addrp, srcp, spacesizep;
45674204
45684205   /* validate instruction */
4569   assert(inst->size == 8);
4570   assert(inst->condflags == DRCUML_COND_ALWAYS);
4571
4572   /* normalize parameters */
4573   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
4574
4575   /* set up a call to the read qword handler */
4576   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4577   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_qword);// call   read_qword
4578   emit_add_r32_imm(&dst, REG_ESP, 4);                                       // add    esp,4
4579
4580   /* 64-bit form */
4581   emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                        // mov   dst,edx:eax
4582
4583   return dst;
4584}
4585
4586
4587/*-------------------------------------------------
4588    op_read8m - process a READ8M opcode
4589-------------------------------------------------*/
4590
4591static x86code *op_read8m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4592{
4593   drcuml_parameter dstp, spacep, addrp, maskp;
4594
4595   /* validate instruction */
4596   assert(inst->size == 8);
4597   assert(inst->condflags == DRCUML_COND_ALWAYS);
4598
4599   /* normalize parameters */
4600   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI);
4601
4602   /* set up a call to the read qword masked handler */
4603   emit_push_p64(drcbe, &dst, &maskp);                                       // push   maskp
4604   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4605   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->read_qword_masked);
4606                                                                  // call   read_qword_masked
4607   emit_add_r32_imm(&dst, REG_ESP, 12);                                    // add    esp,12
4608
4609   /* 64-bit form */
4610   emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                        // mov   dst,edx:eax
4611
4612   return dst;
4613}
4614
4615
4616/*-------------------------------------------------
4617    op_write1 - process a WRITE1 opcode
4618-------------------------------------------------*/
4619
4620static x86code *op_write1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4621{
4622   drcuml_parameter spacep, addrp, srcp;
4623
4624   /* validate instruction */
46254206   assert(inst->size == 4 || inst->size == 8);
46264207   assert(inst->condflags == DRCUML_COND_ALWAYS);
46274208
46284209   /* normalize parameters */
4629   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI);
4210   param_normalize_3(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI, &spacesizep, PTYPE_I);
46304211
46314212   /* set up a call to the write byte handler */
4632   emit_push_p32(drcbe, &dst, &srcp);                                       // push   srcp
4213   if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD)
4214      emit_push_p32(drcbe, &dst, &srcp);                                    // push   srcp
4215   else
4216      emit_push_p64(drcbe, &dst, &srcp);                                    // push   srcp
46334217   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4634   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->write_byte);// call   write_byte
4635   emit_add_r32_imm(&dst, REG_ESP, 8);                                       // add    esp,8
4636
4218   if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE)
4219      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->write_byte);
4220                                                                  // call   write_byte
4221   else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
4222      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->write_word);
4223                                                                  // call   write_word
4224   else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
4225      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->write_dword);
4226                                                                  // call   write_dword
4227   else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
4228      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->write_qword);
4229                                                                  // call   write_qword
4230   emit_add_r32_imm(&dst, REG_ESP, ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) ? 8 : 12);
4231                                                                  // add    esp,8/12
46374232   return dst;
46384233}
46394234
46404235
46414236/*-------------------------------------------------
4642    op_write2 - process a WRITE2 opcode
4237    op_writem - process a WRITEM opcode
46434238-------------------------------------------------*/
46444239
4645static x86code *op_write2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4240static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
46464241{
4647   drcuml_parameter spacep, addrp, srcp;
4242   drcuml_parameter addrp, srcp, maskp, spacesizep;
46484243
46494244   /* validate instruction */
46504245   assert(inst->size == 4 || inst->size == 8);
46514246   assert(inst->condflags == DRCUML_COND_ALWAYS);
46524247
46534248   /* normalize parameters */
4654   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI);
4249   param_normalize_4(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI, &maskp, PTYPE_MRI, &spacesizep, PTYPE_I);
46554250
4656   /* set up a call to the write word handler */
4657   emit_push_p32(drcbe, &dst, &srcp);                                       // push   srcp
4658   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4659   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->write_word);// call   write_word
4660   emit_add_r32_imm(&dst, REG_ESP, 8);                                       // add    esp,8
4661
4662   return dst;
4663}
4664
4665
4666/*-------------------------------------------------
4667    op_writ2m - process a WRIT2M opcode
4668-------------------------------------------------*/
4669
4670static x86code *op_writ2m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4671{
4672   drcuml_parameter spacep, addrp, maskp, srcp;
4673
4674   /* validate instruction */
4675   assert(inst->size == 4 || inst->size == 8);
4676   assert(inst->condflags == DRCUML_COND_ALWAYS);
4677
4678   /* normalize parameters */
4679   param_normalize_4(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &srcp, PTYPE_MRI);
4680
4681   /* set up a call to the write word handler */
4682   emit_push_p32(drcbe, &dst, &maskp);                                       // push   maskp
4683   emit_push_p32(drcbe, &dst, &srcp);                                       // push   srcp
4684   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4685   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->write_word_masked);
4686                                                                  // call   write_word_masked
4687   emit_add_r32_imm(&dst, REG_ESP, 12);                                    // add    esp,12
4688   return dst;
4689}
4690
4691
4692/*-------------------------------------------------
4693    op_write4 - process a WRITE4 opcode
4694-------------------------------------------------*/
4695
4696static x86code *op_write4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4697{
4698   drcuml_parameter spacep, addrp, srcp;
4699
4700   /* validate instruction */
4701   assert(inst->size == 4 || inst->size == 8);
4702   assert(inst->condflags == DRCUML_COND_ALWAYS);
4703
4704   /* normalize parameters */
4705   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI);
4706
4707   /* set up a call to the write dword handler */
4708   emit_push_p32(drcbe, &dst, &srcp);                                       // push   srcp
4709   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4710   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->write_dword);// call   write_dword
4711   emit_add_r32_imm(&dst, REG_ESP, 8);                                       // add    esp,8
4712
4713   return dst;
4714}
4715
4716
4717/*-------------------------------------------------
4718    op_writ4m - process a WRIT4M opcode
4719-------------------------------------------------*/
4720
4721static x86code *op_writ4m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4722{
4723   drcuml_parameter spacep, addrp, maskp, srcp;
4724
4725   /* validate instruction */
4726   assert(inst->size == 4 || inst->size == 8);
4727   assert(inst->condflags == DRCUML_COND_ALWAYS);
4728
4729   /* normalize parameters */
4730   param_normalize_4(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &srcp, PTYPE_MRI);
4731
4732   /* set up a call to the write word handler */
4733   emit_push_p32(drcbe, &dst, &maskp);                                       // push   maskp
4734   emit_push_p32(drcbe, &dst, &srcp);                                       // push   srcp
4735   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4736   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->write_dword_masked);
4737                                                                  // call   write_dword_masked
4738   emit_add_r32_imm(&dst, REG_ESP, 12);                                    // add    esp,12
4739   return dst;
4740}
4741
4742
4743/*-------------------------------------------------
4744    op_write8 - process a WRITE8 opcode
4745-------------------------------------------------*/
4746
4747static x86code *op_write8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4748{
4749   drcuml_parameter spacep, addrp, srcp;
4750
4751   /* validate instruction */
4752   assert(inst->size == 8);
4753   assert(inst->condflags == DRCUML_COND_ALWAYS);
4754
4755   /* normalize parameters */
4756   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI);
4757
4758   /* set up a call to the write qword handler */
4759   emit_push_p64(drcbe, &dst, &srcp);                                       // push   srcp
4760   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4761   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->write_qword);// call   write_qword
4762
4763   emit_add_r32_imm(&dst, REG_ESP, 12);                                    // add    esp,12
4764   return dst;
4765}
4766
4767
4768/*-------------------------------------------------
4769    op_writ8m - process a WRIT8M opcode
4770-------------------------------------------------*/
4771
4772static x86code *op_writ8m(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4773{
4774   drcuml_parameter spacep, addrp, maskp, srcp;
4775
4776   /* validate instruction */
4777   assert(inst->size == 8);
4778   assert(inst->condflags == DRCUML_COND_ALWAYS);
4779
4780   /* normalize parameters */
4781   param_normalize_4(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &srcp, PTYPE_MRI);
4782
4783   /* set up a call to the write word handler */
4784   emit_push_p64(drcbe, &dst, &maskp);                                       // push   maskp
4785   emit_push_p64(drcbe, &dst, &srcp);                                       // push   srcp
4786   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4787   emit_call(&dst, (x86code *)active_address_space[spacep.value].accessors->write_qword_masked);
4788                                                                  // call   write_qword_masked
4789   emit_add_r32_imm(&dst, REG_ESP, 20);                                    // add    esp,20
4790   return dst;
4791}
4792
4793
4794/*-------------------------------------------------
4795    op_flags - process a FLAGS opcode
4796-------------------------------------------------*/
4797
4798static x86code *op_flags(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4799{
4800   drcuml_parameter dstp, maskp, tablep;
4801   int dstreg;
4802
4803   /* validate instruction */
4804   assert(inst->size == 4 || inst->size == 8);
4805   assert(inst->condflags == DRCUML_COND_ALWAYS);
4806
4807   /* normalize parameters */
4808   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &maskp, PTYPE_I, &tablep, PTYPE_M);
4809
4810   /* pick a target register for the general case */
4811   dstreg = param_select_register(REG_ECX, &dstp, NULL);
4812
4813   /* translate live flags into UML flags */
4814   emit_pushf(&dst);                                                   // pushf
4815   emit_pop_r32(&dst, REG_EAX);                                          // pop    eax
4816   emit_and_r32_imm(&dst, REG_EAX, 0x8c5);                                    // and    eax,0x8c5
4817   emit_movzx_r32_m8(&dst, REG_EAX, MBD(REG_EAX, flags_map));                     // movzx  eax,[flags_map]
4818
4819   /* 32-bit form */
4820   if (inst->size == 4)
4251   /* set up a call to the write byte handler */
4252   if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD)
48214253   {
4822      /* no masking */
4823      if (maskp.value == 0xffffffff)
4824      {
4825         emit_mov_r32_m32(&dst, dstreg, MISD(REG_EAX, 4, tablep.value));            // mov    dstreg,[eax*4+table]
4826         emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                        // mov    dstp,dstreg
4827      }
4828
4829      /* general case */
4830      else
4831      {
4832         emit_mov_r32_p32(drcbe, &dst, dstreg, &dstp);                        // mov    dstreg,dstp
4833         emit_mov_r32_m32(&dst, REG_EDX, MISD(REG_EAX, 4, tablep.value));         // mov    edx,[eax*4+table]
4834         emit_and_r32_imm(&dst, dstreg, ~maskp.value);                        // and    dstreg,~mask
4835         emit_and_r32_imm(&dst, REG_EDX, maskp.value);                        // and    edx,mask
4836         emit_or_r32_r32(&dst, dstreg, REG_EDX);                              // or     dstreg,edx
4837         emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                        // mov    dstp,dstreg
4838      }
4254      emit_push_p32(drcbe, &dst, &maskp);                                    // push   maskp
4255      emit_push_p32(drcbe, &dst, &srcp);                                    // push   srcp
48394256   }
4840
4841   /* 64-bit form */
48424257   else
48434258   {
4844      /* no masking */
4845      if (maskp.value == U64(0xffffffffffffffff))
4846      {
4847         emit_mov_r32_m32(&dst, dstreg, MISD(REG_EAX, 8, tablep.value));            // mov    dstreg,[eax*4+table]
4848         emit_mov_r32_m32(&dst, REG_EDX, MISD(REG_EAX, 8, tablep.value + 4));      // mov    edx,[eax*4+table+4]
4849         emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX);                  // mov    dst,edx:dstreg
4850      }
4851
4852      /* general case */
4853      else
4854      {
4855         if ((UINT32)maskp.value != 0)
4856         {
4857            emit_mov_r32_p32(drcbe, &dst, dstreg, &dstp);                     // mov    dstreg,dstp
4858            emit_mov_r32_m32(&dst, REG_EDX, MISD(REG_EAX, 8, tablep.value));      // mov    edx,[eax*8+table]
4859            emit_and_r32_imm(&dst, dstreg, ~maskp.value);                     // and    dstreg,~mask
4860            emit_and_r32_imm(&dst, REG_EDX, maskp.value);                     // and    edx,mask
4861            emit_or_r32_r32(&dst, dstreg, REG_EDX);                           // or     dstreg,edx
4862            emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                     // mov    dstp,dstreg.lo
4863         }
4864         if ((UINT32)(maskp.value >> 32) != 0)
4865         {
4866            if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4867               emit_mov_r32_m32(&dst, REG_ECX, MABS(drcbe->reghi[dstp.value]));   // mov    ecx,dstp.hi
4868            else
4869               emit_mov_r32_m32(&dst, REG_ECX, MABS(dstp.value + 4));            // mov    ecx,dstp.hi
4870            emit_mov_r32_m32(&dst, REG_EDX, MISD(REG_EDX, 8, tablep.value+4));      // mov    edx,[eax*8+table+4]
4871            emit_and_r32_imm(&dst, REG_ECX, ~maskp.value);                     // and    ecx,~mask
4872            emit_and_r32_imm(&dst, REG_EDX, maskp.value);                     // and    edx,mask
4873            emit_or_r32_r32(&dst, REG_ECX, REG_EDX);                        // or     ecx,edx
4874            if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4875               emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_ECX);   // mov    dstp.hi,ecx
4876            else
4877               emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_ECX);            // mov    dstp.hi,ecx
4878         }
4879      }
4259      emit_push_p64(drcbe, &dst, &maskp);                                    // push   maskp
4260      emit_push_p64(drcbe, &dst, &srcp);                                    // push   srcp
48804261   }
4262   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
4263   if ((spacesizep.value & 3) == DRCUML_SIZE_WORD)
4264      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->write_word_masked);
4265                                                                  // call   write_word_masked
4266   else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD)
4267      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->write_dword_masked);
4268                                                                  // call   write_dword_masked
4269   else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD)
4270      emit_call(&dst, (x86code *)active_address_space[spacesizep.value / 16].accessors->write_qword_masked);
4271                                                                  // call   write_qword_masked
4272   emit_add_r32_imm(&dst, REG_ESP, ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) ? 12 : 20);
4273                                                                  // add    esp,12/20
48814274   return dst;
48824275}
48834276
48844277
48854278/*-------------------------------------------------
4886    op_setc - process a SETC opcode
4279    op_carry - process a CARRY opcode
48874280-------------------------------------------------*/
48884281
4889static x86code *op_setc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4282static x86code *op_carry(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
48904283{
48914284   drcuml_parameter srcp, bitp;
48924285
r2821r2822
49614354
49624355
49634356/*-------------------------------------------------
4357    op_set - process a SET opcode
4358-------------------------------------------------*/
4359
4360static x86code *op_set(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4361{
4362   drcuml_parameter dstp;
4363   int dstreg;
4364
4365   /* validate instruction */
4366   assert(inst->size == 4 || inst->size == 8);
4367   assert(inst->condflags >= DRCUML_COND_Z && inst->condflags < DRCUML_COND_MAX);
4368
4369   /* normalize parameters */
4370   param_normalize_1(drcbe, inst, &dstp, PTYPE_MR);
4371
4372   /* pick a target register for the general case */
4373   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4374
4375   /* set to AL */
4376   emit_setcc_r8(&dst, X86_CONDITION(inst->condflags), REG_AL);                  // setcc  al
4377   emit_movzx_r32_r8(&dst, dstreg, REG_AL);                                 // movzx  dstreg,al
4378
4379   /* store low 32 bits */
4380   emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                              // mov   dstp,dstreg
4381
4382   /* 64-bit form stores upper 32 bits */
4383   if (inst->size == 8)
4384   {
4385      /* general case */
4386      if (dstp.type == DRCUML_PTYPE_MEMORY)
4387         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
4388      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
4389         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   [reghi],0
4390   }
4391   return dst;
4392}
4393
4394
4395/*-------------------------------------------------
49644396    op_mov - process a MOV opcode
49654397-------------------------------------------------*/
49664398
r2821r2822
50674499
50684500
50694501/*-------------------------------------------------
5070    op_zext1 - process a ZEXT1 opcode
4502    op_sext - process a SEXT opcode
50714503-------------------------------------------------*/
50724504
5073static x86code *op_zext1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4505static x86code *op_sext(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
50744506{
5075   drcuml_parameter dstp, srcp;
4507   drcuml_parameter dstp, srcp, sizep;
50764508   int dstreg;
50774509
50784510   /* validate instruction */
r2821r2822
50804512   assert(inst->condflags == DRCUML_COND_ALWAYS);
50814513
50824514   /* normalize parameters */
5083   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
4515   param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI, &sizep, PTYPE_I);
50844516
50854517   /* degenerate cases -- convert to a move */
50864518   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5087      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (UINT8)srcp.value);
5088
5089   /* pick a target register for the general case */
5090   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5091
5092   /* convert 8-bit source registers */
5093   if (srcp.type == DRCUML_PTYPE_INT_REGISTER && (srcp.value & 4))
50944519   {
5095      emit_mov_r32_r32(&dst, REG_EAX, srcp.value);                           // mov   eax,srcp
5096      srcp.value = REG_EAX;
4520      if (sizep.value == DRCUML_SIZE_BYTE)
4521         return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT8)srcp.value);
4522      else if (sizep.value == DRCUML_SIZE_WORD)
4523         return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT16)srcp.value);
4524      else if (sizep.value == DRCUML_SIZE_DWORD)
4525         return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT32)srcp.value);
50974526   }
50984527
5099   /* 32-bit form */
5100   if (inst->size == 4)
5101   {
5102      /* general case */
5103      if (srcp.type == DRCUML_PTYPE_MEMORY)
5104         emit_movzx_r32_m8(&dst, dstreg, MABS(srcp.value));                     // movzx dstreg,[srcp]
5105      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5106         emit_movzx_r32_r8(&dst, dstreg, srcp.value);                        // movzx dstreg,srcp
5107      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5108   }
5109
5110   /* 64-bit form */
5111   else if (inst->size == 8)
5112   {
5113      /* general case */
5114      if (srcp.type == DRCUML_PTYPE_MEMORY)
5115         emit_movzx_r32_m8(&dst, dstreg, MABS(srcp.value));                     // movzx dstreg,[srcp]
5116      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5117         emit_movzx_r32_r8(&dst, dstreg, srcp.value);                        // movzx dstreg,srcp
5118      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5119      if (dstp.type == DRCUML_PTYPE_MEMORY)
5120         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
5121      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
5122         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   reghi[dstp],0
5123   }
5124   return dst;
5125}
5126
5127
5128/*-------------------------------------------------
5129    op_zext2 - process a ZEXT2 opcode
5130-------------------------------------------------*/
5131
5132static x86code *op_zext2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5133{
5134   drcuml_parameter dstp, srcp;
5135   int dstreg;
5136
5137   /* validate instruction */
5138   assert(inst->size == 4 || inst->size == 8);
5139   assert(inst->condflags == DRCUML_COND_ALWAYS);
5140
5141   /* normalize parameters */
5142   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5143
5144   /* degenerate cases -- convert to a move */
5145   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5146      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (UINT16)srcp.value);
5147
51484528   /* pick a target register for the general case */
5149   dstreg = param_select_register(REG_EAX, &dstp, NULL);
4529   dstreg = (inst->size == 8) ? REG_EAX : param_select_register(REG_EAX, &dstp, NULL);
51504530
5151   /* 32-bit form */
5152   if (inst->size == 4)
4531   /* convert 8-bit source registers to EAX */
4532   if (sizep.value == DRCUML_SIZE_BYTE && srcp.type == DRCUML_PTYPE_INT_REGISTER && (srcp.value & 4))
51534533   {
5154      /* general case */
5155      if (srcp.type == DRCUML_PTYPE_MEMORY)
5156         emit_movzx_r32_m16(&dst, dstreg, MABS(srcp.value));                     // movzx dstreg,[srcp]
5157      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5158         emit_movzx_r32_r16(&dst, dstreg, srcp.value);                        // movzx dstreg,srcp
5159      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5160   }
5161
5162   /* 64-bit form */
5163   else if (inst->size == 8)
5164   {
5165      /* general case */
5166      if (srcp.type == DRCUML_PTYPE_MEMORY)
5167         emit_movzx_r32_m16(&dst, dstreg, MABS(srcp.value));                     // movzx dstreg,[srcp]
5168      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5169         emit_movzx_r32_r16(&dst, dstreg, srcp.value);                        // movzx dstreg,srcp
5170      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5171      if (dstp.type == DRCUML_PTYPE_MEMORY)
5172         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
5173      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
5174         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   reghi[dstp],0
5175   }
5176   return dst;
5177}
5178
5179
5180/*-------------------------------------------------
5181    op_zext4 - process a ZEXT4 opcode
5182-------------------------------------------------*/
5183
5184static x86code *op_zext4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5185{
5186   drcuml_parameter dstp, srcp;
5187   int dstreg;
5188
5189   /* validate instruction */
5190   assert(inst->size == 8);
5191   assert(inst->condflags == DRCUML_COND_ALWAYS);
5192
5193   /* normalize parameters */
5194   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5195
5196   /* degenerate cases -- convert to a move */
5197   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5198      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (UINT32)srcp.value);
5199
5200   /* pick a target register for the general case */
5201   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5202
5203   /* 64-bit form */
5204   if (inst->size == 8)
5205   {
5206      /* general case */
5207      emit_mov_r32_p32(drcbe, &dst, dstreg, &srcp);                           // mov   dstreg,srcp
5208      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5209      if (dstp.type == DRCUML_PTYPE_MEMORY)
5210         emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0);                     // mov   [dstp+4],0
5211      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
5212         emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0);               // mov   reghi[dstp],0
5213   }
5214   return dst;
5215}
5216
5217
5218/*-------------------------------------------------
5219    op_sext1 - process a SEXT1 opcode
5220-------------------------------------------------*/
5221
5222static x86code *op_sext1(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5223{
5224   drcuml_parameter dstp, srcp;
5225   int dstreg;
5226
5227   /* validate instruction */
5228   assert(inst->size == 4 || inst->size == 8);
5229   assert(inst->condflags == DRCUML_COND_ALWAYS);
5230
5231   /* normalize parameters */
5232   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5233
5234   /* degenerate cases -- convert to a move */
5235   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5236      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT8)srcp.value);
5237
5238   /* pick a target register for the general case */
5239   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5240
5241   /* convert 8-bit source registers */
5242   if (srcp.type == DRCUML_PTYPE_INT_REGISTER && (srcp.value & 4))
5243   {
52444534      emit_mov_r32_r32(&dst, REG_EAX, srcp.value);                           // mov   eax,srcp
52454535      srcp.value = REG_EAX;
52464536   }
52474537
5248   /* 32-bit form */
5249   if (inst->size == 4)
4538   /* general case */
4539   if (srcp.type == DRCUML_PTYPE_MEMORY)
52504540   {
5251      /* general case */
5252      if (srcp.type == DRCUML_PTYPE_MEMORY)
4541      if (sizep.value == DRCUML_SIZE_BYTE)
52534542         emit_movsx_r32_m8(&dst, dstreg, MABS(srcp.value));                     // movsx dstreg,[srcp]
5254      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5255         emit_movsx_r32_r8(&dst, dstreg, srcp.value);                        // movsx dstreg,srcp
5256      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
4543      else if (sizep.value == DRCUML_SIZE_WORD)
4544         emit_movsx_r32_m16(&dst, dstreg, MABS(srcp.value));                     // movsx dstreg,[srcp]
4545      else if (sizep.value == DRCUML_SIZE_DWORD)
4546         emit_mov_r32_m32(&dst, dstreg, MABS(srcp.value));                     // mov   dstreg,[srcp]
52574547   }
5258
5259   /* 64-bit form */
5260   else if (inst->size == 8)
4548   else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
52614549   {
5262      /* general case */
5263      if (srcp.type == DRCUML_PTYPE_MEMORY)
5264         emit_movsx_r32_m8(&dst, REG_EAX, MABS(srcp.value));                     // movsx eax,[srcp]
5265      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5266         emit_movsx_r32_r8(&dst, REG_EAX, srcp.value);                        // movsx eax,srcp
5267      emit_cdq(&dst);                                                   // cdq
5268      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
4550      if (sizep.value == DRCUML_SIZE_BYTE)
4551         emit_movsx_r32_r8(&dst, dstreg, srcp.value);                        // movsx dstreg,srcp
4552      else if (sizep.value == DRCUML_SIZE_WORD)
4553         emit_movsx_r32_r16(&dst, dstreg, srcp.value);                        // movsx dstreg,srcp
4554      else if (sizep.value == DRCUML_SIZE_DWORD && dstreg != srcp.value)
4555         emit_mov_r32_r32(&dst, dstreg, srcp.value);                           // mov   dstreg,srcp
52694556   }
5270   return dst;
5271}
52724557
5273
5274/*-------------------------------------------------
5275    op_sext2 - process a SEXT2 opcode
5276-------------------------------------------------*/
5277
5278static x86code *op_sext2(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5279{
5280   drcuml_parameter dstp, srcp;
5281   int dstreg;
5282
5283   /* validate instruction */
5284   assert(inst->size == 4 || inst->size == 8);
5285   assert(inst->condflags == DRCUML_COND_ALWAYS);
5286
5287   /* normalize parameters */
5288   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5289
5290   /* degenerate cases -- convert to a move */
5291   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5292      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT16)srcp.value);
5293
5294   /* pick a target register for the general case */
5295   dstreg = param_select_register(REG_EAX, &dstp, NULL);
5296
5297   /* 32-bit form */
4558   /* 32-bit form: store the low 32 bits */
52984559   if (inst->size == 4)
5299   {
5300      /* general case */
5301      if (srcp.type == DRCUML_PTYPE_MEMORY)
5302         emit_movsx_r32_m16(&dst, dstreg, MABS(srcp.value));                     // movsx dstreg,[srcp]
5303      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5304         emit_movsx_r32_r16(&dst, dstreg, srcp.value);                        // movsx dstreg,srcp
53054560      emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg);                           // mov   dstp,dstreg
5306   }
53074561
5308   /* 64-bit form */
4562   /* 64-bit form: sign extend to 64 bits and store edx:eax */
53094563   else if (inst->size == 8)
53104564   {
5311      /* general case */
5312      if (srcp.type == DRCUML_PTYPE_MEMORY)
5313         emit_movsx_r32_m16(&dst, REG_EAX, MABS(srcp.value));                  // movsx eax,[srcp]
5314      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
5315         emit_movsx_r32_r16(&dst, REG_EAX, srcp.value);                        // movsx eax,srcp
53164565      emit_cdq(&dst);                                                   // cdq
53174566      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
53184567   }
r2821r2822
53214570
53224571
53234572/*-------------------------------------------------
5324    op_sext4 - process a SEXT4 opcode
4573    op_roland - process an ROLAND opcode
53254574-------------------------------------------------*/
53264575
5327static x86code *op_sext4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4576static x86code *op_roland(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
53284577{
5329   drcuml_parameter dstp, srcp;
5330
5331   /* validate instruction */
5332   assert(inst->size == 8);
5333   assert(inst->condflags == DRCUML_COND_ALWAYS);
5334
5335   /* normalize parameters */
5336   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI);
5337
5338   /* degenerate cases -- convert to a move */
5339   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
5340      return convert_to_mov_imm(drcbe, dst, inst, &dstp, (INT32)srcp.value);
5341
5342   /* 64-bit form */
5343   if (inst->size == 8)
5344   {
5345      /* general case */
5346      emit_mov_r32_p32(drcbe, &dst, REG_EAX, &srcp);                           // mov   eax,srcp
5347      emit_cdq(&dst);                                                   // cdq
5348      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
5349   }
5350   return dst;
5351}
5352
5353
5354/*-------------------------------------------------
5355    op_xtract - process an XTRACT opcode
5356-------------------------------------------------*/
5357
5358static x86code *op_xtract(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
5359{
53604578   drcuml_parameter dstp, srcp, shiftp, maskp;
53614579   int dstreg;
53624580
r2821r2822
54174635
54184636
54194637/*-------------------------------------------------
5420    op_insert - process an INSERT opcode
4638    op_rolins - process an ROLINS opcode
54214639-------------------------------------------------*/
54224640
5423static x86code *op_insert(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
4641static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
54244642{
54254643   drcuml_parameter dstp, srcp, shiftp, maskp;
54264644   int dstreg;
r2821r2822
58895107      emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX);                           // mov   dstp,eax
58905108      if (compute_hi)
58915109         emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX);                        // mov   edstp,edx
5110
5111      /* compute flags */
5112      if (inst->condflags != 0)
5113      {
5114         if (compute_hi)
5115         {
5116            if (inst->condflags == DRCUML_FLAG_Z)
5117               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5118            else if (inst->condflags == DRCUML_FLAG_S)
5119               emit_test_r32_r32(&dst, REG_EDX, REG_EDX);                     // test  edx,edx
5120            else
5121            {
5122               emit_movzx_r32_r16(&dst, REG_ECX, REG_AX);                     // movzx ecx,ax
5123               emit_shr_r32_imm(&dst, REG_EAX, 16);                        // shr   eax,16
5124               emit_or_r32_r32(&dst, REG_EDX, REG_ECX);                     // or    edx,ecx
5125               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5126            }
5127         }
5128         else
5129            emit_test_r32_r32(&dst, REG_EAX, REG_EAX);                        // test  eax,eax
5130      }
58925131   }
58935132
58945133   /* 64-bit form */
r2821r2822
59075146      emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reslo + 0));            // mov   eax,reslo.lo
59085147      emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reslo + 1));            // mov   edx,reslo.hi
59095148      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
5910      if (inst->condflags != 0)
5911         emit_or_r32_r32(&dst, REG_EAX, REG_EDX);                           // or    eax,edx
5149      if (inst->condflags != 0 && !compute_hi)
5150      {
5151         if (inst->condflags == DRCUML_FLAG_Z)
5152            emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                        // or    edx,eax
5153         else if (inst->condflags == DRCUML_FLAG_S)
5154            emit_test_r32_r32(&dst, REG_EDX, REG_EDX);                        // test  edx,edx
5155         else
5156         {
5157            emit_movzx_r32_r16(&dst, REG_ECX, REG_AX);                        // movzx ecx,ax
5158            emit_shr_r32_imm(&dst, REG_EAX, 16);                           // shr   eax,16
5159            emit_or_r32_r32(&dst, REG_EDX, REG_ECX);                        // or    edx,ecx
5160            emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                        // or    edx,eax
5161         }
5162      }
59125163      if (compute_hi)
59135164      {
5165         if (inst->condflags & DRCUML_FLAG_Z)
5166            emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                        // or    edx,eax
59145167         emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reshi + 0));         // mov   eax,reshi.lo
5915         emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reshi + 1));         // mov   edx,reshi.hi
5916         emit_mov_p64_r64(drcbe, &dst, &edstp, REG_EAX, REG_EDX);               // mov   edstp,edx:eax
5168         emit_mov_r32_m32(&dst, REG_ECX, MABS((UINT32 *)&drcbe->reshi + 1));         // mov   ecx,reshi.hi
5169         emit_mov_p64_r64(drcbe, &dst, &edstp, REG_EAX, REG_ECX);               // mov   edstp,ecx:eax
5170         if (inst->condflags != 0)
5171         {
5172            if (inst->condflags == DRCUML_FLAG_Z)
5173            {
5174               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5175               emit_or_r32_r32(&dst, REG_EDX, REG_ECX);                     // or    edx,ecx
5176            }
5177            else if (inst->condflags == DRCUML_FLAG_S)
5178               emit_test_r32_r32(&dst, REG_ECX, REG_ECX);                     // test  ecx,ecx
5179            else
5180            {
5181               emit_or_r32_r32(&dst, REG_EAX, REG_EDX);                     // or    eax,edx
5182               emit_movzx_r32_r16(&dst, REG_EDX, REG_AX);                     // movzx edx,ax
5183               emit_shr_r32_imm(&dst, REG_EAX, 16);                        // shr   eax,16
5184               emit_or_r32_r32(&dst, REG_ECX, REG_EDX);                     // or    edx,ecx
5185               emit_or_r32_r32(&dst, REG_ECX, REG_EAX);                     // or    edx,eax
5186            }
5187         }
59175188      }
59185189   }
59195190   return dst;
r2821r2822
60085279         emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX);                        // mov   dstp,eax
60095280         emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX);                        // mov   edstp,edx
60105281      }
5282
5283      /* compute flags */
5284      if (inst->condflags != 0)
5285      {
5286         if (compute_hi)
5287         {
5288            if (inst->condflags == DRCUML_FLAG_Z)
5289               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5290            else if (inst->condflags == DRCUML_FLAG_S)
5291               emit_test_r32_r32(&dst, REG_EDX, REG_EDX);                     // test  edx,edx
5292            else
5293            {
5294               emit_movzx_r32_r16(&dst, REG_ECX, REG_AX);                     // movzx ecx,ax
5295               emit_shr_r32_imm(&dst, REG_EAX, 16);                        // shr   eax,16
5296               emit_or_r32_r32(&dst, REG_EDX, REG_ECX);                     // or    edx,ecx
5297               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5298            }
5299         }
5300         else
5301            emit_test_r32_r32(&dst, REG_EAX, REG_EAX);                        // test  eax,eax
5302      }
60115303   }
60125304
60135305   /* 64-bit form */
r2821r2822
60265318      emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reslo + 0));            // mov   eax,reslo.lo
60275319      emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reslo + 1));            // mov   edx,reslo.hi
60285320      emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX);                     // mov   dstp,edx:eax
6029      if (inst->condflags != 0)
6030         emit_or_r32_r32(&dst, REG_EAX, REG_EDX);                           // or    eax,edx
5321      if (inst->condflags != 0 && !compute_hi)
5322      {
5323         if (inst->condflags == DRCUML_FLAG_Z)
5324            emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                        // or    edx,eax
5325         else if (inst->condflags == DRCUML_FLAG_S)
5326            emit_test_r32_r32(&dst, REG_EDX, REG_EDX);                        // test  edx,edx
5327         else
5328         {
5329            emit_movzx_r32_r16(&dst, REG_ECX, REG_AX);                        // movzx ecx,ax
5330            emit_shr_r32_imm(&dst, REG_EAX, 16);                           // shr   eax,16
5331            emit_or_r32_r32(&dst, REG_EDX, REG_ECX);                        // or    edx,ecx
5332            emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                        // or    edx,eax
5333         }
5334      }
60315335      if (compute_hi)
60325336      {
60335337         emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reshi + 0));         // mov   eax,reshi.lo
60345338         emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reshi + 1));         // mov   edx,reshi.hi
60355339         emit_mov_p64_r64(drcbe, &dst, &edstp, REG_EAX, REG_EDX);               // mov   edstp,edx:eax
5340         if (inst->condflags != 0)
5341         {
5342            if (inst->condflags == DRCUML_FLAG_Z)
5343            {
5344               emit_or_r32_r32(&dst, REG_EDX, REG_EAX);                     // or    edx,eax
5345               emit_or_r32_r32(&dst, REG_EDX, REG_ECX);                     // or    edx,ecx
5346            }
5347            else if (inst->condflags == DRCUML_FLAG_S)
5348               emit_test_r32_r32(&dst, REG_ECX, REG_ECX);                     // test  ecx,ecx
5349            else
5350            {
5351               emit_or_r32_r32(&dst, REG_EAX, REG_EDX);                     // or    eax,edx
5352               emit_movzx_r32_r16(&dst, REG_EDX, REG_AX);                     // movzx edx,ax
5353               emit_shr_r32_imm(&dst, REG_EAX, 16);                        // shr   eax,16
5354               emit_or_r32_r32(&dst, REG_ECX, REG_EDX);                     // or    edx,ecx
5355               emit_or_r32_r32(&dst, REG_ECX, REG_EAX);                     // or    edx,eax
5356            }
5357         }
60365358      }
60375359   }
60385360   return dst;
r2821r2822
69636285   /* immediate index */
69646286   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
69656287   {
6966      if (inst->size == 4)
6967         emit_fld_m32(&dst, MABS(basep.value + 4*indp.value));                  // fld   [basep + 4*indp]
6968      else if (inst->size == 8)
6969         emit_fld_m64(&dst, MABS(basep.value + 8*indp.value));                  // fld   [basep + 8*indp]
6288      emit_mov_r32_m32(&dst, REG_EAX, MABS(basep.value + 4*indp.value));            // mov   eax,[basep + 4*indp]
6289      if (inst->size == 8)
6290         emit_mov_r32_m32(&dst, REG_EDX, MABS(basep.value + 4 + 4*indp.value));      // mov   edx,[basep + 4*indp + 4]
69706291   }
69716292
69726293   /* other index */
r2821r2822
69746295   {
69756296      int indreg = param_select_register(REG_ECX, &indp, NULL);
69766297      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
6977      if (inst->size == 4)
6978         emit_fld_m32(&dst, MISD(indreg, 4, basep.value));                     // fld   [basep + 4*indp]
6979      else if (inst->size == 8)
6980         emit_fld_m64(&dst, MISD(indreg, 8, basep.value));                     // fld   [basep + 8*indp]
6298      emit_mov_r32_m32(&dst, REG_EAX, MISD(indreg, 4, basep.value));               // mov   eax,[basep + 4*indp]
6299      if (inst->size == 8)
6300         emit_mov_r32_m32(&dst, REG_EDX, MISD(indreg, 4, basep.value + 4));         // mov   edx,[basep + 4*indp + 4]
69816301   }
69826302
69836303   /* general case */
6984   emit_fstp_p(&dst, inst->size, &dstp);                                    // fstp  dstp
6985
6304   emit_mov_m32_r32(&dst, MABS(dstp.value), REG_EAX);                           // mov   [dstp],eax
6305   if (inst->size == 8)
6306      emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX);                     // mov   [dstp + 4],edx
69866307   return dst;
69876308}
69886309
r2821r2822
70036324   param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MF);
70046325
70056326   /* general case */
7006   emit_fld_p(&dst, inst->size, &srcp);
6327   emit_mov_r32_m32(&dst, REG_EAX, MABS(srcp.value));                           // mov   eax,[srcp]
6328   if (inst->size == 8)
6329      emit_mov_r32_m32(&dst, REG_EDX, MABS(srcp.value + 4));                     // mov   edx,[srcp + 4]
70076330
70086331   /* immediate index */
70096332   if (indp.type == DRCUML_PTYPE_IMMEDIATE)
70106333   {
7011      if (inst->size == 4)
7012         emit_fstp_m32(&dst, MABS(basep.value + 4*indp.value));                  // fstp  [basep + 4*indp]
7013      else if (inst->size == 8)
7014         emit_fstp_m64(&dst, MABS(basep.value + 8*indp.value));                  // fstp  [basep + 8*indp]
6334      emit_mov_m32_r32(&dst, MABS(basep.value + 4*indp.value), REG_EAX);            // mov   [basep + 4*indp],eax
6335      if (inst->size == 8)
6336         emit_mov_m32_r32(&dst, MABS(basep.value + 4 + 4*indp.value), REG_EDX);      // mov   [basep + 4*indp + 4],edx
70156337   }
70166338
70176339   /* other index */
r2821r2822
70196341   {
70206342      int indreg = param_select_register(REG_ECX, &indp, NULL);
70216343      emit_mov_r32_p32(drcbe, &dst, indreg, &indp);
7022      if (inst->size == 4)
7023         emit_fstp_m32(&dst, MISD(indreg, 4, basep.value));                     // fstp  [basep + 4*indp]
7024      else if (inst->size == 8)
7025         emit_fstp_m64(&dst, MISD(indreg, 8, basep.value));                     // fstp  [basep + 8*indp]
6344      emit_mov_m32_r32(&dst, MISD(indreg, 4, basep.value), REG_EAX);               // mov   [basep + 4*indp],eax
6345      if (inst->size == 8)
6346         emit_mov_m32_r32(&dst, MISD(indreg, 4, basep.value + 4), REG_EDX);         // mov   [basep + 4*indp + 4],edx
70266347   }
70276348   return dst;
70286349}
r2821r2822
70416362   assert(inst->condflags == DRCUML_COND_ALWAYS);
70426363
70436364   /* normalize parameters */
7044   param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &spacep, PTYPE_I, &addrp, PTYPE_MRI);
6365   param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &addrp, PTYPE_MRI, &spacep, PTYPE_I);
70456366
70466367   /* set up a call to the read dword/qword handler */
70476368   emit_push_p32(drcbe, &dst, &addrp);                                       // push   addrp
r2821r2822
70746395   assert(inst->condflags == DRCUML_COND_ALWAYS);
70756396
70766397   /* normalize parameters */
7077   param_normalize_3(drcbe, inst, &spacep, PTYPE_I, &addrp, PTYPE_MRI, &srcp, PTYPE_MF);
6398   param_normalize_3(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MF, &spacep, PTYPE_I);
70786399
70796400   /* set up a call to the write dword/qword handler */
70806401   if (inst->size == 4)
r2821r2822
71136434      emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condflags), &skip);         // jcc   skip
71146435
71156436   /* general case */
7116   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7117   emit_fstp_p(&dst, inst->size, &dstp);                                    // fstp  dstp
6437   emit_mov_r32_m32(&dst, REG_EAX, MABS(srcp.value));                           // mov   eax,[srcp]
6438   if (inst->size == 8)
6439      emit_mov_r32_m32(&dst, REG_EDX, MABS(srcp.value + 4));                     // mov   edx,[srcp + 4]
6440   emit_mov_m32_r32(&dst, MABS(dstp.value), REG_EAX);                           // mov   [dstp],eax
6441   if (inst->size == 8)
6442      emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX);                     // mov   [dstp + 4],edx
71186443
71196444   /* resolve the jump */
71206445   if (skip.target != NULL)
r2821r2822
71246449
71256450
71266451/*-------------------------------------------------
7127    op_ftoi4 - process a FTOI4 opcode
6452    op_ftoint - process a FTOINT opcode
71286453-------------------------------------------------*/
71296454
7130static x86code *op_ftoi4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
6455static x86code *op_ftoint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
71316456{
7132   drcuml_parameter dstp, srcp;
6457   drcuml_parameter dstp, srcp, sizep, roundp;
71336458
71346459   /* validate instruction */
71356460   assert(inst->size == 4 || inst->size == 8);
71366461   assert(inst->condflags == DRCUML_COND_ALWAYS);
71376462
71386463   /* normalize parameters */
7139   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
6464   param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF, &sizep, PTYPE_I, &roundp, PTYPE_I);
71406465
7141   /* general case */
7142   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7143   if (dstp.type == DRCUML_PTYPE_MEMORY)
7144      emit_fistp_m32(&dst, MABS(dstp.value));                                 // fistp [dstp]
7145   else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
6466   /* set rounding mode if necessary */
6467   if (roundp.value != DRCUML_FMOD_DEFAULT && (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC))
71466468   {
7147      emit_fistp_m32(&dst, MABS(drcbe->reglo[dstp.value]));                     // fistp reglo[dstp]
7148      emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));            // mov   dstp,reglo[dstp]
6469      emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                           // fstcw [fmodesave]
6470      emit_fldcw_m16(&dst, MABS(&fp_control[roundp.value]));                     // fldcw fpcontrol[roundp]
71496471   }
7150   return dst;
7151}
71526472
6473   /* general case */
6474   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
71536475
7154/*-------------------------------------------------
7155    op_ftoi4t - process a FTOI4T opcode
7156-------------------------------------------------*/
7157
7158static x86code *op_ftoi4t(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7159{
7160   drcuml_parameter dstp, srcp;
7161
7162   /* validate instruction */
7163   assert(inst->size == 4 || inst->size == 8);
7164   assert(inst->condflags == DRCUML_COND_ALWAYS);
7165
7166   /* normalize parameters */
7167   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7168
7169   /* non-SSE3 case */
7170   if (!drcbe->sse3)
6476   /* 4-byte integer case */
6477   if (sizep.value == DRCUML_SIZE_DWORD)
71716478   {
7172      /* save and set the control word */
7173      emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                           // fstcw [fmodesave]
7174      emit_fldcw_m16(&dst, MABS(&fp_control[DRCUML_FMOD_TRUNC]));                  // fldcw fpcontrol[DRCUML_FMOD_TRUNC]
7175
7176      /* general case */
7177      emit_fld_p(&dst, inst->size, &srcp);                                 // fld   srcp
71786479      if (dstp.type == DRCUML_PTYPE_MEMORY)
7179         emit_fistp_m32(&dst, MABS(dstp.value));                              // fistp [dstp]
6480      {
6481         if (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC)
6482            emit_fistp_m32(&dst, MABS(dstp.value));                           // fistp [dstp]
6483         else
6484            emit_fisttp_m32(&dst, MABS(dstp.value));                        // fisttp [dstp]
6485      }
71806486      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
71816487      {
7182         emit_fistp_m32(&dst, MABS(drcbe->reglo[dstp.value]));                  // fistp reglo[dstp]
6488         if (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC)
6489            emit_fistp_m32(&dst, MABS(drcbe->reglo[dstp.value]));               // fistp reglo[dstp]
6490         else
6491            emit_fisttp_m32(&dst, MABS(drcbe->reglo[dstp.value]));               // fisttp reglo[dstp]
71836492         emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));         // mov   dstp,reglo[dstp]
71846493      }
7185
7186      /* restore control word and proceed */
7187      emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                           // fldcw [fmodesave]
71886494   }
71896495
7190   /* SSE3 case */
7191   else
6496   /* 8-byte integer case */
6497   else if (sizep.value == DRCUML_SIZE_QWORD)
71926498   {
7193      /* general case */
7194      emit_fld_p(&dst, inst->size, &srcp);                                 // fld   srcp
71956499      if (dstp.type == DRCUML_PTYPE_MEMORY)
7196         emit_fisttp_m32(&dst, MABS(dstp.value));                           // fisttp [dstp]
6500      {
6501         if (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC)
6502            emit_fistp_m64(&dst, MABS(dstp.value));                           // fistp [dstp]
6503         else
6504            emit_fisttp_m64(&dst, MABS(dstp.value));                        // fisttp [dstp]
6505      }
71976506      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
71986507      {
7199         emit_fisttp_m32(&dst, MABS(drcbe->reglo[dstp.value]));                  // fisttp reglo[dstp]
6508         if (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC)
6509            emit_fistp_m64(&dst, MABS(drcbe->reglo[dstp.value]));               // fistp reglo[dstp]
6510         else
6511            emit_fisttp_m64(&dst, MABS(drcbe->reglo[dstp.value]));               // fisttp reglo[dstp]
72006512         emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));         // mov   dstp,reglo[dstp]
72016513      }
72026514   }
7203   return dst;
7204}
72056515
7206
7207/*-------------------------------------------------
7208    op_ftoi4r - process a FTOI4R opcode
7209-------------------------------------------------*/
7210
7211static x86code *op_ftoi4r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7212{
7213   drcuml_parameter dstp, srcp;
7214
7215   /* validate instruction */
7216   assert(inst->size == 4 || inst->size == 8);
7217   assert(inst->condflags == DRCUML_COND_ALWAYS);
7218
7219   /* normalize parameters */
7220   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7221
7222   /* save and set the control word */
7223   emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fstcw [fmodesave]
7224   emit_fldcw_m16(&dst, MABS(&fp_control[DRCUML_FMOD_ROUND]));                     // fldcw fpcontrol[DRCUML_FMOD_ROUND]
7225
7226   /* general case */
7227   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7228   if (dstp.type == DRCUML_PTYPE_MEMORY)
7229      emit_fistp_m32(&dst, MABS(dstp.value));                                 // fistp [dstp]
7230   else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
7231   {
7232      emit_fistp_m32(&dst, MABS(drcbe->reglo[dstp.value]));                     // fistp reglo[dstp]
7233      emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));            // mov   dstp,reglo[dstp]
7234   }
7235
72366516   /* restore control word and proceed */
7237   emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fldcw [fmodesave]
7238   return dst;
7239}
6517   if (roundp.value != DRCUML_FMOD_DEFAULT && (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC))
6518      emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                           // fldcw [fmodesave]
72406519
7241
7242/*-------------------------------------------------
7243    op_ftoi4f - process a FTOI4F opcode
7244-------------------------------------------------*/
7245
7246static x86code *op_ftoi4f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7247{
7248   drcuml_parameter dstp, srcp;
7249
7250   /* validate instruction */
7251   assert(inst->size == 4 || inst->size == 8);
7252   assert(inst->condflags == DRCUML_COND_ALWAYS);
7253
7254   /* normalize parameters */
7255   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7256
7257   /* save and set the control word */
7258   emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fstcw [fmodesave]
7259   emit_fldcw_m16(&dst, MABS(&fp_control[DRCUML_FMOD_FLOOR]));                     // fldcw fpcontrol[DRCUML_FMOD_FLOOR]
7260
7261   /* general case */
7262   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7263   if (dstp.type == DRCUML_PTYPE_MEMORY)
7264      emit_fistp_m32(&dst, MABS(dstp.value));                                 // fistp [dstp]
7265   else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
7266   {
7267      emit_fistp_m32(&dst, MABS(drcbe->reglo[dstp.value]));                     // fistp reglo[dstp]
7268      emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));            // mov   dstp,reglo[dstp]
7269   }
7270
7271   /* restore control word and proceed */
7272   emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fldcw [fmodesave]
72736520   return dst;
72746521}
72756522
72766523
72776524/*-------------------------------------------------
7278    op_ftoi4c - process a FTOI4C opcode
6525    op_ffrint - process a FFRINT opcode
72796526-------------------------------------------------*/
72806527
7281static x86code *op_ftoi4c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
6528static x86code *op_ffrint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
72826529{
7283   drcuml_parameter dstp, srcp;
6530   drcuml_parameter dstp, srcp, sizep;
72846531
72856532   /* validate instruction */
72866533   assert(inst->size == 4 || inst->size == 8);
72876534   assert(inst->condflags == DRCUML_COND_ALWAYS);
72886535
72896536   /* normalize parameters */
7290   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
6537   param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MRI, &sizep, PTYPE_I);
72916538
7292   /* save and set the control word */
7293   emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fstcw [fmodesave]
7294   emit_fldcw_m16(&dst, MABS(&fp_control[DRCUML_FMOD_CEIL]));                     // fldcw fpcontrol[DRCUML_FMOD_CEIL]
7295
7296   /* general case */
7297   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7298   if (dstp.type == DRCUML_PTYPE_MEMORY)
7299      emit_fistp_m32(&dst, MABS(dstp.value));                                 // fistp [dstp]
7300   else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
6539   /* 4-byte integer case */
6540   if (sizep.value == DRCUML_SIZE_DWORD)
73016541   {
7302      emit_fistp_m32(&dst, MABS(drcbe->reglo[dstp.value]));                     // fistp reglo[dstp]
7303      emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));            // mov   dstp,reglo[dstp]
7304   }
7305
7306   /* restore control word and proceed */
7307   emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fldcw [fmodesave]
7308   return dst;
7309}
7310
7311
7312/*-------------------------------------------------
7313    op_ftoi8 - process a FTOI8 opcode
7314-------------------------------------------------*/
7315
7316static x86code *op_ftoi8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7317{
7318   drcuml_parameter dstp, srcp;
7319
7320   /* validate instruction */
7321   assert(inst->size == 4 || inst->size == 8);
7322   assert(inst->condflags == DRCUML_COND_ALWAYS);
7323
7324   /* normalize parameters */
7325   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7326
7327   /* general case */
7328   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7329   if (dstp.type == DRCUML_PTYPE_MEMORY)
7330      emit_fistp_m64(&dst, MABS(dstp.value));                                 // fistp [dstp]
7331   else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
7332   {
7333      emit_fistp_m64(&dst, MABS(drcbe->reglo[dstp.value]));                     // fistp reglo[dstp]
7334      emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));            // mov   dstp,reglo[dstp]
7335   }
7336   return dst;
7337}
7338
7339
7340/*-------------------------------------------------
7341    op_ftoi8t - process a FTOI8T opcode
7342-------------------------------------------------*/
7343
7344static x86code *op_ftoi8t(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7345{
7346   drcuml_parameter dstp, srcp;
7347
7348   /* validate instruction */
7349   assert(inst->size == 4 || inst->size == 8);
7350   assert(inst->condflags == DRCUML_COND_ALWAYS);
7351
7352   /* normalize parameters */
7353   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7354
7355   /* non-SSE3 case */
7356   if (!drcbe->sse3)
7357   {
7358      /* save and set the control word */
7359      emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                           // fstcw [fmodesave]
7360      emit_fldcw_m16(&dst, MABS(&fp_control[DRCUML_FMOD_TRUNC]));                  // fldcw fpcontrol[DRCUML_FMOD_TRUNC]
7361
7362      /* general case */
7363      emit_fld_p(&dst, inst->size, &srcp);                                 // fld   srcp
7364      if (dstp.type == DRCUML_PTYPE_MEMORY)
7365         emit_fistp_m64(&dst, MABS(dstp.value));                              // fistp [dstp]
7366      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
6542      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
73676543      {
7368         emit_fistp_m64(&dst, MABS(drcbe->reglo[dstp.value]));                  // fistp reglo[dstp]
7369         emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));         // mov   dstp,reglo[dstp]
6544         emit_mov_m32_imm(&dst, MABS(&drcbe->fptemp), srcp.value);               // mov   [fptemp],srcp
6545         emit_fild_m32(&dst, MABS(&drcbe->fptemp));                           // fild  [fptemp]
73706546      }
7371
7372      /* restore control word and proceed */
7373      emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                           // fldcw [fmodesave]
6547      else if (srcp.type == DRCUML_PTYPE_MEMORY)
6548         emit_fild_m32(&dst, MABS(srcp.value));                              // fild  [srcp]
6549      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
6550      {
6551         emit_mov_m32_r32(&dst, MABS(drcbe->reglo[srcp.value]), srcp.value);         // mov   reglo[srcp],srcp
6552         emit_fild_m32(&dst, MABS(drcbe->reglo[srcp.value]));                  // fild  reglo[srcp]
6553      }
73746554   }
73756555
7376   /* SSE3 case */
7377   else
6556   /* 8-bit integer case */
6557   else if (sizep.value == DRCUML_SIZE_QWORD)
73786558   {
7379      /* general case */
7380      emit_fld_p(&dst, inst->size, &srcp);                                 // fld   srcp
7381      if (dstp.type == DRCUML_PTYPE_MEMORY)
7382         emit_fisttp_m64(&dst, MABS(dstp.value));                           // fisttp [dstp]
7383      else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
6559      if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
73846560      {
7385         emit_fisttp_m64(&dst, MABS(drcbe->reglo[dstp.value]));                  // fisttp reglo[dstp]
7386         emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));         // mov   dstp,reglo[dstp]
6561         emit_mov_m32_imm(&dst, MABS(&drcbe->fptemp), srcp.value);               // mov   [fptemp],srcp
6562         emit_mov_m32_imm(&dst, MABS((UINT8 *)&drcbe->fptemp + 4), srcp.value);      // mov   [fptemp+4],srcp
6563         emit_fild_m64(&dst, MABS(&drcbe->fptemp));                           // fild  [fptemp]
73876564      }
6565      else if (srcp.type == DRCUML_PTYPE_MEMORY)
6566         emit_fild_m64(&dst, MABS(srcp.value));                              // fild  [srcp]
6567      else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
6568      {
6569         emit_mov_m32_r32(&dst, MABS(drcbe->reglo[srcp.value]), srcp.value);         // mov   reglo[srcp],srcp
6570         emit_fild_m64(&dst, MABS(drcbe->reglo[srcp.value]));                  // fild  reglo[srcp]
6571      }
73886572   }
7389   return dst;
7390}
73916573
7392
7393/*-------------------------------------------------
7394    op_ftoi8r - process a FTOI8R opcode
7395-------------------------------------------------*/
7396
7397static x86code *op_ftoi8r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7398{
7399   drcuml_parameter dstp, srcp;
7400
7401   /* validate instruction */
7402   assert(inst->size == 4 || inst->size == 8);
7403   assert(inst->condflags == DRCUML_COND_ALWAYS);
7404
7405   /* normalize parameters */
7406   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7407
7408   /* save and set the control word */
7409   emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fstcw [fmodesave]
7410   emit_fldcw_m16(&dst, MABS(&fp_control[DRCUML_FMOD_ROUND]));                     // fldcw fpcontrol[DRCUML_FMOD_ROUND]
7411
7412   /* general case */
7413   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7414   if (dstp.type == DRCUML_PTYPE_MEMORY)
7415      emit_fistp_m64(&dst, MABS(dstp.value));                                 // fistp [dstp]
7416   else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
7417   {
7418      emit_fistp_m64(&dst, MABS(drcbe->reglo[dstp.value]));                     // fistp reglo[dstp]
7419      emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));            // mov   dstp,reglo[dstp]
7420   }
7421
7422   /* restore control word and proceed */
7423   emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fldcw [fmodesave]
6574   /* store the result and be done */
6575   emit_fstp_p(&dst, inst->size, &dstp);                                    // fstp  [dstp]
74246576   return dst;
74256577}
74266578
74276579
74286580/*-------------------------------------------------
7429    op_ftoi8f - process a FTOI8F opcode
6581    op_ffrflt - process a FFRFLT opcode
74306582-------------------------------------------------*/
74316583
7432static x86code *op_ftoi8f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
6584static x86code *op_ffrflt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
74336585{
7434   drcuml_parameter dstp, srcp;
6586   drcuml_parameter dstp, srcp, sizep;
74356587
74366588   /* validate instruction */
74376589   assert(inst->size == 4 || inst->size == 8);
74386590   assert(inst->condflags == DRCUML_COND_ALWAYS);
74396591
74406592   /* normalize parameters */
7441   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
6593   param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF, &sizep, PTYPE_I);
74426594
7443   /* save and set the control word */
7444   emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fstcw [fmodesave]
7445   emit_fldcw_m16(&dst, MABS(&fp_control[DRCUML_FMOD_FLOOR]));                     // fldcw fpcontrol[DRCUML_FMOD_FLOOR]
7446
74476595   /* general case */
7448   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7449   if (dstp.type == DRCUML_PTYPE_MEMORY)
7450      emit_fistp_m64(&dst, MABS(dstp.value));                                 // fistp [dstp]
7451   else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
7452   {
7453      emit_fistp_m64(&dst, MABS(drcbe->reglo[dstp.value]));                     // fistp reglo[dstp]
7454      emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));            // mov   dstp,reglo[dstp]
7455   }
6596   if (sizep.value == DRCUML_SIZE_DWORD)
6597      emit_fld_m32(&dst, MABS(srcp.value));                                 // fld   [srcp]
6598   else if (sizep.value == DRCUML_SIZE_QWORD)
6599      emit_fld_m64(&dst, MABS(srcp.value));                                 // fld   [srcp]
6600   emit_fstp_p(&dst, inst->size, &dstp);                                    // fstp  dstp
74566601
7457   /* restore control word and proceed */
7458   emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fldcw [fmodesave]
74596602   return dst;
74606603}
74616604
74626605
74636606/*-------------------------------------------------
7464    op_ftoi8c - process a FTOI8C opcode
6607    op_frnds - process a FRNDS opcode
74656608-------------------------------------------------*/
74666609
7467static x86code *op_ftoi8c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
6610static x86code *op_frnds(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
74686611{
74696612   drcuml_parameter dstp, srcp;
74706613
74716614   /* validate instruction */
7472   assert(inst->size == 4 || inst->size == 8);
7473   assert(inst->condflags == DRCUML_COND_ALWAYS);
7474
7475   /* normalize parameters */
7476   param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
7477
7478   /* save and set the control word */
7479   emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fstcw [fmodesave]
7480   emit_fldcw_m16(&dst, MABS(&fp_control[DRCUML_FMOD_CEIL]));                     // fldcw fpcontrol[DRCUML_FMOD_CEIL]
7481
7482   /* general case */
7483   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
7484   if (dstp.type == DRCUML_PTYPE_MEMORY)
7485      emit_fistp_m64(&dst, MABS(dstp.value));                                 // fistp [dstp]
7486   else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
7487   {
7488      emit_fistp_m64(&dst, MABS(drcbe->reglo[dstp.value]));                     // fistp reglo[dstp]
7489      emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value]));            // mov   dstp,reglo[dstp]
7490   }
7491
7492   /* restore control word and proceed */
7493   emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave));                              // fldcw [fmodesave]
7494   return dst;
7495}
7496
7497
7498/*-------------------------------------------------
7499    op_ffrfs - process a FFRFS opcode
7500-------------------------------------------------*/
7501
7502static x86code *op_ffrfs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7503{
7504   drcuml_parameter dstp, srcp;
7505
7506   /* validate instruction */
75076615   assert(inst->size == 8);
75086616   assert(inst->condflags == DRCUML_COND_ALWAYS);
75096617
r2821r2822
75116619   param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF);
75126620
75136621   /* general case */
7514   emit_fld_m32(&dst, MABS(srcp.value));                                    // fld   [srcp]
7515   emit_fstp_p(&dst, inst->size, &dstp);                                    // fstp  dstp
7516
7517   return dst;
7518}
7519
7520
7521/*-------------------------------------------------
7522    op_ffrfd - process a FFRFD opcode
7523-------------------------------------------------*/
7524
7525static x86code *op_ffrfd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7526{
7527   drcuml_parameter dstp, srcp;
7528
7529   /* validate instruction */
7530   assert(inst->size == 4);
7531   assert(inst->condflags == DRCUML_COND_ALWAYS);
7532
7533   /* normalize parameters */
7534   param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF);
7535
7536   /* general case */
7537   emit_fld_m64(&dst, MABS(srcp.value));                                    // fld   [srcp]
7538   emit_fstp_p(&dst, inst->size, &dstp);                                    // fstp  dstp
7539
7540   return dst;
7541}
7542
7543
7544/*-------------------------------------------------
7545    op_ffri4 - process a FFRI4 opcode
7546-------------------------------------------------*/
7547
7548static x86code *op_ffri4(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7549{
7550   drcuml_parameter dstp, srcp;
7551
7552   /* validate instruction */
7553   assert(inst->size == 4 || inst->size == 8);
7554   assert(inst->condflags == DRCUML_COND_ALWAYS);
7555
7556   /* normalize parameters */
7557   param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MRI);
7558
7559   /* general case */
7560   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
7561   {
7562      emit_mov_m32_imm(&dst, MABS(&drcbe->fptemp), srcp.value);                  // mov   [fptemp],srcp
7563      emit_fild_m32(&dst, MABS(&drcbe->fptemp));                              // fild  [fptemp]
7564   }
7565   else if (srcp.type == DRCUML_PTYPE_MEMORY)
7566      emit_fild_m32(&dst, MABS(srcp.value));                                 // fild  [srcp]
7567   else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
7568   {
7569      emit_mov_m32_r32(&dst, MABS(drcbe->reglo[srcp.value]), srcp.value);            // mov   reglo[srcp],srcp
7570      emit_fild_m32(&dst, MABS(drcbe->reglo[srcp.value]));                     // fild  reglo[srcp]
7571   }
6622   emit_fld_p(&dst, inst->size, &srcp);                                    // fld   srcp
6623   emit_fstp_m32(&dst, MABS(&drcbe->fptemp));                                 // fstp  [fptemp]
6624   emit_fld_m32(&dst, MABS(&drcbe->fptemp));                                 // fld   [fptemp]
75726625   emit_fstp_p(&dst, inst->size, &dstp);                                    // fstp  [dstp]
75736626   return dst;
75746627}
75756628
75766629
75776630/*-------------------------------------------------
7578    op_ffri8 - process a FFRI8 opcode
7579-------------------------------------------------*/
7580
7581static x86code *op_ffri8(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
7582{
7583   drcuml_parameter dstp, srcp;
7584
7585   /* validate instruction */
7586   assert(inst->size == 4 || inst->size == 8);
7587   assert(inst->condflags == DRCUML_COND_ALWAYS);
7588
7589   /* normalize parameters */
7590   param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MRI);
7591
7592   /* general case */
7593   if (srcp.type == DRCUML_PTYPE_IMMEDIATE)
7594   {
7595      emit_mov_m32_imm(&dst, MABS(&drcbe->fptemp), srcp.value);                  // mov   [fptemp],srcp
7596      emit_mov_m32_imm(&dst, MABS((UINT8 *)&drcbe->fptemp + 4), srcp.value);         // mov   [fptemp+4],srcp
7597      emit_fild_m64(&dst, MABS(&drcbe->fptemp));                              // fild  [fptemp]
7598   }
7599   else if (srcp.type == DRCUML_PTYPE_MEMORY)
7600      emit_fild_m64(&dst, MABS(srcp.value));                                 // fild  [srcp]
7601   else if (srcp.type == DRCUML_PTYPE_INT_REGISTER)
7602   {
7603      emit_mov_m32_r32(&dst, MABS(drcbe->reglo[srcp.value]), srcp.value);            // mov   reglo[srcp],srcp
7604      emit_fild_m64(&dst, MABS(drcbe->reglo[srcp.value]));                     // fild  reglo[srcp]
7605   }
7606   emit_fstp_p(&dst, inst->size, &dstp);                                    // fstp  [dstp]
7607   return dst;
7608}
7609
7610
7611/*-------------------------------------------------
76126631    op_fadd - process a FADD opcode
76136632-------------------------------------------------*/
76146633
src/emu/cpu/saturn/sat.h
r2821r2822
1enum {
2   SATURN_A=1, SATURN_B, SATURN_C, SATURN_D,
3   SATURN_R0, SATURN_R1, SATURN_R2, SATURN_R3, SATURN_R4,
4   SATURN_RSTK0, SATURN_RSTK1, SATURN_RSTK2, SATURN_RSTK3,
5   SATURN_RSTK4, SATURN_RSTK5, SATURN_RSTK6, SATURN_RSTK7,
6    SATURN_PC, SATURN_D0, SATURN_D1,
7
8   SATURN_P,
9   SATURN_IN,
10   SATURN_OUT,
11   SATURN_CARRY,
12   SATURN_ST,
13   SATURN_HST,
14
15   SATURN_EA,
16   SATURN_NMI_STATE,
17   SATURN_IRQ_STATE
18};
19
20#define PEEK_OP(pc) cpu_readop(pc)
21#define PEEK_NIBBLE(adr) cpu_readmem_20(adr)
22
src/emu/tilemap.c
r2821r2822
779779      int scrolly = effective_colscroll(tmap, 0);
780780      int currow, nextrow;
781781
782      /* iterate over rows in the tilemap */
783      for (currow = 0; currow < tmap->scrollrows; currow = nextrow)
782      /* iterate over Y to handle wraparound */
783      for (ypos = scrolly - tmap->height; ypos <= original_cliprect.max_y; ypos += tmap->height)
784784      {
785         int scrollx = effective_rowscroll(tmap, currow);
785         int const firstrow = MAX((original_cliprect.min_y - ypos) / rowheight, 0);
786         int const lastrow =  MIN((original_cliprect.max_y - ypos) / rowheight, tmap->scrollrows - 1);
786787
787         /* scan forward until we find a non-matching row */
788         for (nextrow = currow + 1; nextrow < tmap->scrollrows; nextrow++)
789            if (effective_rowscroll(tmap, nextrow) != scrollx)
790               break;
788         /* iterate over rows in the tilemap */
789         for (currow = firstrow; currow <= lastrow; currow = nextrow)
790         {
791            int scrollx = effective_rowscroll(tmap, currow);
791792
792          /* skip if disabled */
793         if (scrollx == TILE_LINE_DISABLED)
794            continue;
793            /* scan forward until we find a non-matching row */
794            for (nextrow = currow + 1; nextrow <= lastrow; nextrow++)
795               if (effective_rowscroll(tmap, nextrow) != scrollx)
796                  break;
795797
796         /* iterate over Y to handle wraparound */
797         for (ypos = scrolly - tmap->height; ypos <= original_cliprect.max_y; ypos += tmap->height)
798         {
798            /* skip if disabled */
799            if (scrollx == TILE_LINE_DISABLED)
800               continue;
801
799802            /* update the cliprect just for this set of rows */
800803            blit.cliprect.min_y = currow * rowheight + ypos;
801804            blit.cliprect.max_y = nextrow * rowheight - 1 + ypos;
src/emu/video.c
r2821r2822
574574static void decode_graphics(running_machine *machine, const gfx_decode_entry *gfxdecodeinfo)
575575{
576576   int totalgfx = 0, curgfx = 0;
577   char buffer[200];
578577   int i;
579578
580579   /* count total graphics elements */
r2821r2822
596595            /* now decode the actual graphics */
597596            for (j = 0; j < gfx->total_elements; j += 1024)
598597            {
598               char buffer[200];
599599               int num_to_decode = (j + 1024 < gfx->total_elements) ? 1024 : (gfx->total_elements - j);
600600               decodegfx(gfx, region_base + gfxdecodeinfo[i].start, j, num_to_decode);
601601               curgfx += num_to_decode;
src/emu/memory.c
r2821r2822
31643164   while (subunits-- != 0)
31653165   {
31663166      int shift = *subshift++;
3167      if ((UINT8)(mem_mask >> shift) != 0xff)
3167      if ((UINT8)(mem_mask >> shift) != 0)
31683168         (*handler->subhandler.write.mhandler8)(handler->subobject, offset, data >> shift);
31693169      offset++;
31703170   }
src/emu/inptport.c
r2821r2822
18541854      /* set each position to be 512 units */
18551855      case IPT_POSITIONAL:
18561856      case IPT_POSITIONAL_V:
1857         state->positionalscale = COMPUTE_SCALE(state->adjmax, INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN);
1857         state->positionalscale = COMPUTE_SCALE(field->max, INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN);
18581858         state->adjmin = 0;
1859         state->adjmax--;
1859         state->adjmax = field->max - 1;
18601860         state->wraps = ((field->flags & ANALOG_FLAG_WRAPS) != 0);
18611861         state->autocenter = !state->wraps;
18621862         break;
src/emu/machine/53c810.c
r2821r2822
9595   lsi810.dstat |= 0x4;   /* SIR (SCRIPTS Interrupt Instruction Received) */
9696
9797   if(intf->irq_callback != NULL) {
98      intf->irq_callback(Machine);
98      intf->irq_callback(Machine, 1);
9999   }
100100   lsi810.dma_icount = 0;
101101   lsi810.halted = 1;
r2821r2822
478478      case 0x13:      /* DSA [31-24] */
479479         return (lsi810.dsa >> 24) & 0xff;
480480      case 0x14:      /* ISTAT */
481         // clear the interrupt on service
482         if(intf->irq_callback != NULL)
483         {
484            intf->irq_callback(Machine, 0);
485         }
486
481487         return lsi810.istat;
482488      case 0x2c:      /* DSP [7-0] */
483489         return lsi810.dsp & 0xff;
r2821r2822
615621            lsi810.istat |= 0x3;   /* DMA interrupt pending */
616622            lsi810.dstat |= 0x8;   /* SSI (Single Step Interrupt) */
617623            if(intf->irq_callback != NULL) {
618               intf->irq_callback(machine);
624               intf->irq_callback(machine, 1);
619625            }
620626         }
621627         else if(lsi810.dcntl & 0x04 && !lsi810.halted)   /* manual start DMA */
src/emu/machine/53c810.h
r2821r2822
66struct LSI53C810interface
77{
88   const SCSIConfigTable *scsidevs;         /* SCSI devices */
9   void (*irq_callback)(running_machine *machine); /* IRQ callback */
9   void (*irq_callback)(running_machine *machine, int); /* IRQ callback */
1010   void (*dma_callback)(UINT32, UINT32, int, int);   /* DMA callback */
1111   UINT32 (*fetch)(UINT32 dsp);
1212};
src/emu/cpuintrf.c
r2821r2822
172172void v810_get_info(UINT32 state, cpuinfo *info);
173173void m37702_get_info(UINT32 state, cpuinfo *info);
174174void m37710_get_info(UINT32 state, cpuinfo *info);
175void ppc403_get_info(UINT32 state, cpuinfo *info);
175void ppc403ga_get_info(UINT32 state, cpuinfo *info);
176void ppc403gcx_get_info(UINT32 state, cpuinfo *info);
176177void ppc601_get_info(UINT32 state, cpuinfo *info);
177178void ppc602_get_info(UINT32 state, cpuinfo *info);
178179void ppc603_get_info(UINT32 state, cpuinfo *info);
180void ppc603e_get_info(UINT32 state, cpuinfo *info);
181void ppc603r_get_info(UINT32 state, cpuinfo *info);
179182void ppc604_get_info(UINT32 state, cpuinfo *info);
180183void mpc8240_get_info(UINT32 state, cpuinfo *info);
181184void SE3208_get_info(UINT32 state, cpuinfo *info);
r2821r2822
709712#if (HAS_M37710)
710713   { CPU_M37710, m37710_get_info },
711714#endif
712#if (HAS_PPC403)
713   { CPU_PPC403, ppc403_get_info },
715#if (HAS_PPC403GA)
716   { CPU_PPC403GA, ppc403ga_get_info },
714717#endif
718#if (HAS_PPC403GCX)
719   { CPU_PPC403GCX, ppc403gcx_get_info },
720#endif
715721#if (HAS_PPC601)
716722   { CPU_PPC601, ppc601_get_info },
717723#endif
r2821r2822
721727#if (HAS_PPC603)
722728   { CPU_PPC603, ppc603_get_info },
723729#endif
730#if (HAS_PPC603E)
731   { CPU_PPC603E, ppc603e_get_info },
732#endif
733#if (HAS_PPC603R)
734   { CPU_PPC603R, ppc603r_get_info },
735#endif
724736#if (HAS_PPC604)
725737   { CPU_PPC604, ppc604_get_info },
726738#endif
src/emu/cpuexec.h
r2821r2822
200200   CPU_V810,
201201   CPU_M37702,
202202   CPU_M37710,
203   CPU_PPC403,
203   CPU_PPC403GA,
204   CPU_PPC403GCX,
204205   CPU_PPC601,
205206   CPU_PPC602,
206207   CPU_PPC603,
208   CPU_PPC603E,
209   CPU_PPC603R,
207210   CPU_PPC604,
208211   CPU_MPC8240,
209212   CPU_SE3208,
src/emu/sound/c352.c
r2821r2822
114114   UINT16 noisecnt;
115115   INT32 frequency, delta, offset, cnt, flag;
116116   UINT32 bank;
117   UINT32 pos;
117   UINT32 pos, len;
118118
119119   frequency = info->c352_ch[ch].pitch;
120120   delta=frequency;
r2821r2822
127127   noisecnt = info->c352_ch[ch].noisecnt;
128128   noisebuf = info->c352_ch[ch].noisebuf;
129129
130   len = (UINT32)memory_region_length(info->c352_region);
130131   for(i = 0 ; (i < sample_count) && (flag & C352_FLG_BUSY) ; i++)
131132   {
132133      offset += delta;
r2821r2822
136137         offset &= 0xffff;
137138      }
138139
139      if (pos > (UINT32)memory_region_length(info->c352_region))
140      if (pos > len)
140141      {
141142         info->c352_ch[ch].flag &= ~C352_FLG_BUSY;
142143         return;
src/emu/sound/discrete.h
r2821r2822
37813781#error "DISCRETE_MAX_NODE_OUTPUTS != 8"
37823782#endif
37833783
3784#define NODE_RELATIVE(_x, _y) (NODE(NODE_INDEX(_x) + (_y)))
3785
37843786#define NODE_NC  NODE_00
37853787#define NODE_SPECIAL  NODE(DISCRETE_MAX_NODES)
37863788
src/emu/sound/scsp.c
r2821r2822
533533         SCSP->SCSPRAM = memory_region(intf->region);
534534         SCSP->SCSPRAM_LENGTH = memory_region_length(intf->region);
535535         SCSP->DSP.SCSPRAM = (UINT16 *)SCSP->SCSPRAM;
536         SCSP->DSP.SCSPRAM_LENGTH = memory_region_length(intf->region)/2;
536         SCSP->DSP.SCSPRAM_LENGTH = SCSP->SCSPRAM_LENGTH/2;
537537         SCSP->SCSPRAM += intf->roffset;
538538      }
539539   }
src/emu/sound/segapcm.c
r2821r2822
7979static void *segapcm_start(int sndindex, int clock, const void *config)
8080{
8181   const struct SEGAPCMinterface *intf = config;
82   int mask, rom_mask;
82   int mask, rom_mask, len;
8383   struct segapcm *spcm;
8484
8585   spcm = auto_malloc(sizeof(*spcm));
r2821r2822
9595   if(!mask)
9696      mask = BANK_MASK7>>16;
9797
98   for(rom_mask = 1; rom_mask < memory_region_length(intf->region); rom_mask *= 2);
98   len = memory_region_length(intf->region);
99   for(rom_mask = 1; rom_mask < len; rom_mask *= 2);
99100   rom_mask--;
100101
101102   spcm->bankmask = mask & (rom_mask >> spcm->bankshift);
src/emu/inputseq.c
r2821r2822
9696   return (length == 0) ? SEQCODE_END : seq->code[length - 1];
9797}
9898
99/*-------------------------------------------------
100    input_seq_get_last_but_one - return the
101    last_but_one code in a sequence
102-------------------------------------------------*/
99103
104INLINE input_code input_seq_get_last_but_one(const input_seq *seq)
105{
106   int length = input_seq_length(seq);
107   return (length < 2) ? SEQCODE_END : seq->code[length - 2];
108}
109
110
100111/*-------------------------------------------------
101112    input_seq_backspace - "backspace" over the
102113    last entry in a sequence
r2821r2822
302313int input_seq_poll(input_seq *finalseq)
303314{
304315   input_code lastcode = input_seq_get_last(&record_seq);
316   int has_or = FALSE;
305317   input_code newcode;
306318
307319   /* switch case: see if we have a new code to process */
r2821r2822
328340   /* absolute/relative case: see if we have an analog change of sufficient amount */
329341   else
330342   {
343      if (lastcode == SEQCODE_OR)
344      {
345         lastcode = input_seq_get_last_but_one(&record_seq);
346         has_or = TRUE;
347      }
331348      newcode = input_code_poll_axes(FALSE);
332349
333350      /* if the last code doesn't match absolute/relative of this code, ignore the new one */
r2821r2822
339356      {
340357         /* if code is duplicate and an absolute control, toggle to half axis */
341358         if (input_seq_length(&record_seq) > 0 && INPUT_CODE_ITEMCLASS(newcode) == ITEM_CLASS_ABSOLUTE)
359         {
342360            if (newcode == INPUT_CODE_SET_MODIFIER(lastcode, ITEM_MODIFIER_NONE))
343361            {
344362               /* increment the modifier, wrapping back to none */
r2821r2822
347365               newcode = INPUT_CODE_SET_MODIFIER(newcode, newmod);
348366
349367               /* back up over the previous code so we can re-append */
368               if (has_or)
369                  input_seq_backspace(&record_seq);
350370               input_seq_backspace(&record_seq);
351371            }
372         }
352373      }
353374   }
354375
r2821r2822
360381   }
361382
362383   /* if we're recorded at least one item and the RECORD_TIME has passed, we're done */
363   if (record_last != 0 && osd_ticks() > record_last + RECORD_TIME)
384   if (record_last != 0 && (osd_ticks() > record_last + RECORD_TIME))
364385   {
365386      /* if the final result is invalid, reset to nothing */
366387      if (!input_seq_is_valid(&record_seq))
src/emu/cheat.c
r2821r2822
4747
4848#define ADD_MENU_3_ITEMS(name, sub_name, enum)   do { menu_item[total] = name; menu_sub_item[total] = sub_name; menu_index[total] = enum; total++; } while(0)
4949
50#define   ADJUST_CURSOR(sel, total)            if(sel < 0) sel = 0; else if(sel > (total - 1)) sel = (total - 1);
51#define   CURSOR_TO_NEXT(sel, total)            if(++sel > (total - 1)) sel = 0;
52#define   CURSOR_TO_PREVIOUS(sel, total)         if(--sel < 0) sel = (total - 1);
53#define   CURSOR_PAGE_UP(sel)                  sel -= visible_items; if(sel < 0) sel = 0;
54#define CURSOR_PAGE_DOWN(sel, total)         sel += visible_items; if(sel >= total) sel = (total - 1);
50#define ADJUST_CURSOR(sel, total)            do { if(sel < 0) sel = 0; else if(sel > (total - 1)) sel = (total - 1); } while(0);
51#define CURSOR_TO_NEXT(sel, total)            do { if(++sel > (total - 1)) sel = 0; } while(0)
52#define CURSOR_TO_PREVIOUS(sel, total)         do { if(--sel < 0) sel = (total - 1); } while(0)
53#define CURSOR_PAGE_UP(sel)                  do { sel -= visible_items; if(sel < 0) sel = 0; } while (0)
54#define CURSOR_PAGE_DOWN(sel, total)         do { sel += visible_items; if(sel >= total) sel = (total - 1); } while (0)
55#define SET_MESSAGE(type)                  do { message_timer = DEFAULT_MESSAGE_TIME; message_type = type; } while(0)
5556
5657/***************************************************************************
5758    CONSTANTS
r2821r2822
6566#define DEFAULT_CHEAT_OPTIONS               (0xF)
6667#endif
6768#define DEFAULT_MESSAGE_TIME               (50)
68#define VARIABLE_MAX_ARRAY                  (0x0F)      // NOTE : Move code can accept max 16 variables as destination
69#define VARIABLE_MAX_ARRAY                  (0x0F)      /* NOTE : Destination in Move code can only accept variable[0]-[3] only */
6970#define CHEAT_RETURN_VALUE                  (0xFF)
70#define CUSTOM_CODE                        (0xFF)
71#define DEFAULT_ADDRESS_LENGTH               (8)
72#define SAFE_SEARCH_REGION_RANGE            (0xFFFF)
7173
7274/********** BIT FIELD **********/
7375
r2821r2822
7577{
7678   /* type field */
7779   DEFINE_BITFIELD_ENUM(OneShot,               0,   0),
78   DEFINE_BITFIELD_ENUM(DelayEnable,            1,   1),
79   DEFINE_BITFIELD_ENUM(PrefillEnable,            2,   2),
80   DEFINE_BITFIELD_ENUM(Return,               3,   3),
81   DEFINE_BITFIELD_ENUM(RestoreValue,            4,   4),
82   DEFINE_BITFIELD_ENUM(DataRead,               5,   5),      // 0 = field, 1 = variable
83   DEFINE_BITFIELD_ENUM(AddressRead,            6,   7),      // 0 = field, 1 = indirect address from variable, 2 = variable
84   DEFINE_BITFIELD_ENUM(CodeParameter,            8,   11),
85   DEFINE_BITFIELD_ENUM(CodeType,               12,   15),
86   DEFINE_BITFIELD_ENUM(Link,                  16,   17),   // 0 = master, 1 = link, 2 = sub link for label-selection, 3 = copy link for VWrite, VRWrite
87   DEFINE_BITFIELD_ENUM(LinkValueSelectBCD,      18,   18),   // used by VWrite (link)
88   DEFINE_BITFIELD_ENUM(LinkValueSelectNegative,   19,   19),   // used by VWrite (link)
89   DEFINE_BITFIELD_ENUM(PopupParameter,         18,   19),   // used by Popup
80   DEFINE_BITFIELD_ENUM(DelayEnable,            1,   3),
81   DEFINE_BITFIELD_ENUM(PrefillEnable,            4,   5),
82   DEFINE_BITFIELD_ENUM(Return,               6,   6),
83   DEFINE_BITFIELD_ENUM(RestoreValue,            7,   7),
84   DEFINE_BITFIELD_ENUM(ValueSelectEnable,         8,   8),      /* = CopyValueEnable */
85   DEFINE_BITFIELD_ENUM(ValueSelectMinimumDisplay,   9,   9),
86   DEFINE_BITFIELD_ENUM(ValueSelectMinimum,      10,   10),
87   DEFINE_BITFIELD_ENUM(ValueSelectBCD,         11,   11),   /* = CopyValueBCD */
88   DEFINE_BITFIELD_ENUM(ValueSelectNegative,      12,   12),   /* = CopyValueNegative */
89   DEFINE_BITFIELD_ENUM(PopupParameter,         13,   14),
90   DEFINE_BITFIELD_ENUM(DataRead,               15,   15),   /* 0 = field, 1 = variable */
91   DEFINE_BITFIELD_ENUM(Link,                  16,   17),   /* 0 = master, 1 = link, 2 = sub link, 3 = EOL */
92   DEFINE_BITFIELD_ENUM(Endianness,            18,   18),
9093   DEFINE_BITFIELD_ENUM(AddressSize,            20,   21),
91   DEFINE_BITFIELD_ENUM(IndexSize,               22,   23),   // used by IWrite, VWrite, Move, Popup
92   DEFINE_BITFIELD_ENUM(CPURegion,               24, 31),   // extract to CPU/Region field
94   DEFINE_BITFIELD_ENUM(AddressRead,            22,   23),   /* 0 = field, 1 = indirect address from variable, 2 = variable */
95   DEFINE_BITFIELD_ENUM(CodeParameter,            24,   27),
96   DEFINE_BITFIELD_ENUM(CodeParameterLower,      24,   25),
97   DEFINE_BITFIELD_ENUM(CodeParameterUpper,      26,   27),
98   DEFINE_BITFIELD_ENUM(CodeType,               28,   31),
9399
94100   /* extend field */
95   DEFINE_BITFIELD_ENUM(LSB16,                  0,   15),   // lower 4 bytes
96   DEFINE_BITFIELD_ENUM(MSB16,                  16,   31),   // upper 4 bytes
101   DEFINE_BITFIELD_ENUM(LSB16,                  0,   15),   /* lower 4 bytes */
102   DEFINE_BITFIELD_ENUM(MSB16,                  16,   31),   /* upper 4 bytes */
97103
98   /* value-select master code */
99   DEFINE_BITFIELD_ENUM(ValueSelectMinimumDisplay,   8,   8),
100   DEFINE_BITFIELD_ENUM(ValueSelectMinimum,      9,   9),
101   DEFINE_BITFIELD_ENUM(ValueSelectBCD,         10,   10),
102   DEFINE_BITFIELD_ENUM(ValueSelectNegative,      11,   11),
103
104104   /* watch code */
105   DEFINE_BITFIELD_ENUM(WatchDisplayFormat,      8,   9),      // from type field
106   DEFINE_BITFIELD_ENUM(WatchShowLabel,         10,   10),   //
107   DEFINE_BITFIELD_ENUM(WatchNumElements,         0,   7),      // from data field
108   DEFINE_BITFIELD_ENUM(WatchSkip,               8,   15),   //
109   DEFINE_BITFIELD_ENUM(WatchElementsPerLine,      16,   23),   //
110   DEFINE_BITFIELD_ENUM(WatchAddValue,            24,   31),   //
105   DEFINE_BITFIELD_ENUM(WatchDisplayFormat,      24,   25),   /* from type field */
106   DEFINE_BITFIELD_ENUM(WatchShowLabel,         26,   27),   /* from type field */
107   DEFINE_BITFIELD_ENUM(WatchNumElements,         0,   7),      /* from data field */
108   DEFINE_BITFIELD_ENUM(WatchSkip,               8,   15),   /* from data field */
109   DEFINE_BITFIELD_ENUM(WatchElementsPerLine,      16,   23),   /* from data field */
110   DEFINE_BITFIELD_ENUM(WatchAddValue,            24,   31),   /* from data field */
111111
112112   /* label-selection */
113113   DEFINE_BITFIELD_ENUM(LabelSelectUseSelector,   4,   4),
114114   DEFINE_BITFIELD_ENUM(LabelSelectQuickClose,      5,   5),
115115
116116   /* cpu/region field */
117   DEFINE_BITFIELD_ENUM(CPUIndex,               0,   3),      // cpu region
118   DEFINE_BITFIELD_ENUM(AddressSpace,            4,   6),      // cpu region
119   DEFINE_BITFIELD_ENUM(RegionIndex,            0,   6),      // non-cpu region
120   DEFINE_BITFIELD_ENUM(RegionFlag,            7,   7),      // 0 = cpu, 1 = non-cpu
117   DEFINE_BITFIELD_ENUM(CPUIndex,               0,   3),
118   DEFINE_BITFIELD_ENUM(AddressSpace,            4,   6),
119//  DEFINE_BITFIELD_ENUM(RegionIndex,               0,  6),     /* unused ??? */
121120
122121   /* old code */
123//  DEFINE_BITFIELD_ENUM(OneShot,                   0,  0),
122//  DEFINE_BITFIELD_ENUM(OneShot,                   0,  0),     /* = OneShot in new format */
124123   DEFINE_BITFIELD_ENUM(Type,                  1,   2),
125124   DEFINE_BITFIELD_ENUM(Operation,               3,   4),
126125   DEFINE_BITFIELD_ENUM(TypeParameter,            5,   7),
r2821r2822
136135   DEFINE_BITFIELD_ENUM(OperationParameter,      18,   18),
137136   DEFINE_BITFIELD_ENUM(OperationExtend,         19,   19),
138137   DEFINE_BITFIELD_ENUM(BytesUsed,               20,   21),
139   DEFINE_BITFIELD_ENUM(Endianness,            22,   22),
138   DEFINE_BITFIELD_ENUM(EndiannessOld,            22,   22),
140139   DEFINE_BITFIELD_ENUM(RestorePreviousValue,      23, 23),
141140   DEFINE_BITFIELD_ENUM(LocationParameter,         24,   28),
142141   DEFINE_BITFIELD_ENUM(LocationType,            29,   31),
r2821r2822
147146
148147   /* command */
149148   DEFINE_BITFIELD_ENUM(SearchBox,               0,   1),
150   DEFINE_BITFIELD_ENUM(DontPrintNewLabels,      2,   2),      // in options menu, it is reversed display
149   DEFINE_BITFIELD_ENUM(DontPrintNewLabels,      2,   2),      /* in options menu, it is reversed display */
151150   DEFINE_BITFIELD_ENUM(AutoSaveEnabled,         3,   3),
152151   DEFINE_BITFIELD_ENUM(ActivationKeyMessage,      4,   4),
153152   DEFINE_BITFIELD_ENUM(LoadOldFormat,            5,   5),
r2821r2822
172171   kCodeType_IWrite,         // EF = Index
173172   kCodeType_RWrite,         // EF = Count/Skip
174173   kCodeType_CWrite,         // EF = Condition
175   kCodeType_VWrite,         // EF = Index
176   kCodeType_VRWrite,         // EF = Count/Skip
174   kCodeType_CBit,            // EF = Condition
177175   kCodeType_PDWWrite,         // EF = 2nd Data
178   kCodeType_Move,            // EF = Index
179   kCodeType_Branch,         // EF = Jump Code
180   kCodeType_Loop,            // EF = Index
181   kCodeType_Unused1,
182   kCodeType_Unused2,
183   kCodeType_Unused3,
184   kCodeType_Unused4,
185   kCodeType_Popup,         // EF = Index
186   kCodeType_Watch };         // EF = X and Y Position
176   kCodeType_Move,            // DF = Add Value, EF = Destination
177   kCodeType_Branch,         // DF = Jump Code, EF = Condition
178   kCodeType_Loop,
179   kCodeType_Popup,         // EF = Condition
180   kCodeType_Watch,         // EF = position
181   kCodeType_Unused };
187182
188enum{      // parameter for IWrite
189   kIWrite_Write = 0,
190   kIWrite_BitSet,
191   kIWrite_BitClear,
192   kIWrite_LimitedMask };
183enum{      /* parameter for IWrite */
184   IWRITE_WRITE = 0,
185   IWRITE_BIT_SET,
186   IWRITE_BIT_CLEAR,
187   IWRITE_LIMITED_MASK };
193188
194enum{      // conditions for CWrite, Branch, Popup
189enum{      /* parameter for CBit */
190   CBIT_BIT_SET = 0,
191   CBIT_BIT_CLEAR,
192   CBIT_LIMITED_MASK };
193
194enum{      /* conditions for CWrite, Branch, Popup */
195195   kCondition_Equal = 0,
196196   kCondition_NotEqual,
197197   kCondition_Less,
r2821r2822
209209   kCondition_KeyPressedRepeat,
210210   kCondition_True };
211211
212enum{      /* conditions for CBit */
213   CONDITION_CBIT_BIT_SET = 0,
214   CONDITION_CBIT_BIT_CLEAR };
215
212216enum{      // popup parameter
213217   kPopup_Label = 0,
214218   kPopup_Value,
215219   kPopup_LabelValue,
216220   kPopup_ValueLabel };
217221
218enum{      // parameter for custom
219   kCustomCode_NoAction = 0,
220   kCustomCode_Comment,
221   kCustomCode_Separator,
222   kCustomCode_LabelSelect,
223   kCustomCode_Layer,
224   kCustomCode_Unused1,
225   kCustomCode_Unused2,
226   kCustomCode_Unused3,
227   kCustomCode_ActivationKey1,
228   kCustomCode_ActivationKey2,
229   kCustomCode_PreEnable,
230   kCustomCode_OverClock,
231   kCustomCode_RefreshRate };
222enum{      /* custom code */
223   CUSTOM_CODE = 0xF0,
224   CUSTOM_CODE_COMMENT,
225   CUSTOM_CODE_SEPARATOR,
226   CUSTOM_CODE_LABEL_SELECT,
227   CUSTOM_CODE_LAYER_TAG,
228   CUSTOM_CODE_UNUSED_1,
229   CUSTOM_CODE_UNUSED_2,
230   CUSTOM_CODE_UNUSED_3,
231   CUSTOM_CODE_ACTIVATION_KEY_1,
232   CUSTOM_CODE_ACTIVATION_KEY_2,
233   CUSTOM_CODE_PRE_ENABLE,
234   CUSTOM_CODE_OVER_CLOCK,
235   CUSTOM_CODE_REFRESH_RATE };
232236
233237enum{      // link level
234238   kLink_Master = 0,
235239   kLink_Link,
236   kLink_SubLink,
237   kLink_CopyLink };
240   kLink_SubLink };
238241
239242enum{      // address read from
240243   kReadFrom_Address = 0,         // $xxxx
r2821r2822
314317   /* set for one shot cheats after the operation is performed */
315318   kActionFlag_OperationDone =      1 << 3,
316319
317   /* set if the extendData field is being used by index adress reading (IWrite, VWrite, Move, Loop, Popup)*/
320   /* set if the extend data field is being used by index adress reading (IWrite, Move) */
318321   kActionFlag_IndexAddress =      1 << 4,
319322
320   /* set if the code needs to check the condition (CWrite, Branch, Popup) */
321   kActionFlag_CheckCondition =   1 << 5,
323   /* set if the code uses limited mask which divids data field to 16-bit data and 16-bit mask (IWrite, CBit) */
324   kActionFlag_LimitedMask =      1 << 5,
322325
323   /* set if the code needs to repeat writing (RWrite, VRWrite) */
324   kActionFlag_Repeat =         1 << 6,
326   /* set if the code needs to check the condition (CWrite, CBit, Branch, Popup) */
327   kActionFlag_CheckCondition =   1 << 6,
325328
329   /* set if the code needs to repeat writing (RWrite) */
330   kActionFlag_Repeat =         1 << 7,
331
326332   /* set if the extendData field is being used by 2nd data (PDWWrite) */
327   kActionFlag_PDWWrite =         1 << 7,
333   kActionFlag_PDWWrite =         1 << 8,
328334
329335   /* set if the lastValue field contains valid data and can be restored if needed */
330   kActionFlag_LastValueGood =      1 << 8,
336   kActionFlag_LastValueGood =      1 << 9,
331337
332338   /* set after value changes from prefill value */
333   kActionFlag_PrefillDone =      1 << 9,
339   kActionFlag_PrefillDone =      1 << 10,
334340
335341   /* set after prefill value written */
336   kActionFlag_PrefillWritten =   1 << 10,
342   kActionFlag_PrefillWritten =   1 << 11,
337343
338344   /* set if the code is a label for label-selection code */
339   kActionFlag_IsLabel =         1 << 11,
345   kActionFlag_IsLabel =         1 << 12,
340346
341347   /* set when read/write a data after 1st read/write and clear after 2nd read/write (PDWWrite) */
342   kActionFlag_IsFirst =         1 << 12,
348   kActionFlag_IsFirst =         1 << 13,
343349
344350   /* masks */
345   kActionFlag_StateMask =         kActionFlag_OperationDone |      // used in ResetAction() to clear specified flags
351   kActionFlag_StateMask =         kActionFlag_OperationDone |      /* used in ResetAction() to clear specified flags */
346352                           kActionFlag_LastValueGood |
347353                           kActionFlag_PrefillDone |
348354                           kActionFlag_PrefillWritten,
349   kActionFlag_InfoMask =         kActionFlag_IndexAddress,      // ??? unused ???
350   kActionFlag_PersistentMask =   kActionFlag_OldFormat |         // used in UpdateCheatInfo() to clear other flags
355   kActionFlag_InfoMask =         kActionFlag_IndexAddress,      /* ??? unused ??? */
356   kActionFlag_PersistentMask =   kActionFlag_OldFormat |         /* used in update_cheat_info() to clear other flags */
351357                           kActionFlag_LastValueGood
352358};
353359
r2821r2822
380386   /* true if selected code is layer index cheat */
381387   kCheatFlag_LayerSelected =         1 << 8,
382388
389   /* true if selected code requests left/right arrow for sub item */
390   kCheatFlag_RequestArrow =         1 << 9,
391
383392   /* true if the cheat has been assigned an 1st activation key */
384   kCheatFlag_HasActivationKey1 =      1 << 9,
393   kCheatFlag_HasActivationKey1 =      1 << 10,
385394
386395   /* true if the cheat has been assigned an 2nd activation key */
387   kCheatFlag_HasActivationKey2 =      1 << 10,
396   kCheatFlag_HasActivationKey2 =      1 << 11,
388397
389398   /* true if the cheat is not the newest format */
390   kCheatFlag_OldFormat =            1 << 11,
399   kCheatFlag_OldFormat =            1 << 12,
391400
392401   /* true if wrong cheat code */
393   kCheatFlag_HasWrongCode =         1 << 12,
402   kCheatFlag_HasWrongCode =         1 << 13,
394403
395404   /* true if the cheat has been edited or is a new cheat
396405       checked at auto-save then save the code if true */
397   kCheatFlag_Dirty =               1 << 13,
406   kCheatFlag_Dirty =               1 << 14,
398407
399408   /* masks */
400409   kCheatFlag_StateMask =         kCheatFlag_Active,               // used in ResetAction() and DeactivateCheat() to clear specified flag
401   kCheatFlag_InfoMask =         kCheatFlag_OneShot |            // used in UpdateCheatInfo() to detect specified flags
410   kCheatFlag_InfoMask =         kCheatFlag_OneShot |            // used in update_cheat_info() to detect specified flags
402411                           kCheatFlag_Null |
403412                           kCheatFlag_ExtendComment |
404413                           kCheatFlag_Separator |
r2821r2822
406415                           kCheatFlag_Select |
407416                           kCheatFlag_LayerIndex |
408417                           kCheatFlag_OldFormat,
409   kCheatFlag_PersistentMask =      kCheatFlag_Active |               // used in UpdateCheatInfo() to extract specified flags
418   kCheatFlag_PersistentMask =      kCheatFlag_Active |               // used in update_cheat_info() to extract specified flags
410419                           kCheatFlag_HasActivationKey1 |
411420                           kCheatFlag_HasActivationKey2 |
412421                           kCheatFlag_Dirty
r2821r2822
433442   kWatchDisplayType_MaxPlusOne
434443};
435444
436/********** REGION **********/
445/********** SEARCH REGION **********/
437446
438447enum      // flags
439448{
440449   /* true if enabled for search */
441   kRegionFlag_Enabled =      1 << 0
450   kRegionFlag_Enabled =         1 << 0,
442451
452   /* true if this region has an error */
453   kRegionFlag_HasError =         1 << 1,
454
443455   /* true if the memory region has no mapped memory and uses a memory handler (unused?) */
444//  kRegionFlag_UsesHandler =   1 << 1
456/*  kRegionFlag_UsesHandler = */
445457};
446458
447459enum      // types
r2821r2822
450462   kRegionType_Memory
451463};
452464
453enum      // default search regions
465enum      /* search speed */
454466{
455   ksearch_speed_Fast = 0,      // RAM + some banks
456   ksearch_speed_Medium,      // RAM + BANKx
457   ksearch_speed_Slow,         // all memory areas except ROM, NOP, and custom handlers
458   ksearch_speed_VerySlow,      // all memory areas except ROM and NOP
459   ksearch_speed_AllMemory,      // entire CPU address space
460   ksearch_speed_UserDefined,   // user defined region
467   SEARCH_SPEED_FAST = 0,      /* RAM + some banks */
468   SEARCH_SPEED_MEDIUM,      /* RAM + BANKx */
469   SEARCH_SPEED_SLOW,         /* all memory areas except ROM, NOP, and custom handlers */
470   SEARCH_SPEED_VERY_SLOW,      /* all memory areas except ROM and NOP */
471   SEARCH_SPEED_ALL_MEMORY,   /* entire CPU address space */
472   SEARCH_SPEED_USER_DEFINED,   /* user defined region */
461473
462   ksearch_speed_Max
474   SEARCH_SPEED_MAX
463475};
464476
465/********** SEARCH **********/
477/********** SEARCH INFO **********/
466478
467479enum      // operands
468480{
r2821r2822
515527   kSearchBox_Advanced
516528};
517529
530enum      /* format level */
531{
532   FORMAT_NEW = 1,
533   FORMAT_STANDARD,
534   FORMAT_OLD
535};
536
537enum      /* disposition for resizing a list */
538{
539   REQUEST_DISPOSE = 0,
540   NO_DISPOSE,
541};
542
518543enum      // load flags
519544{
520545   kLoadFlag_CheatOption   = 1,
r2821r2822
546571   kCheatMessage_NoOldValue,
547572   kCheatMessage_InitializeMemory,
548573   kCheatMessage_InvalidatedRegion,
549   kCheatMessage_DebugOnly,
574   kCheatMessage_FailedToAllocate,
550575   kCheatMessage_WrongCode,
551576
552577   kCheatMessage_Max
r2821r2822
563588   kErrorFlag_NoRestorePreviousValue   = 1 << 7,
564589   kErrorFlag_NoLabel               = 1 << 8,
565590   kErrorFlag_ConflictedSelects      = 1 << 9,
566   kErrorFlag_CopyLinkWithoutSelect   = 1 << 10,   // new
567   kErrorFlag_InvalidDataField         = 1 << 11,
568   kErrorFlag_InvalidExtendDataField   = 1 << 12,
569   kErrorFlag_ForbittenVariable      = 1 << 13,   // new
570   kErrorFlag_NoSelectableValue      = 1 << 14,
591   kErrorFlag_InvalidDataField         = 1 << 10,
592   kErrorFlag_InvalidExtendDataField   = 1 << 11,
593   kErrorFlag_ForbittenVariable      = 1 << 12,   // new
594   kErrorFlag_NoSelectableValue      = 1 << 13,
595   kErrorFlag_InvalidLimitedMaskSize   = 1 << 14,   // new
571596   kErrorFlag_NoRepeatCount         = 1 << 15,   // new
572597   kErrorFlag_UndefinedAddressRead      = 1 << 16,   // new
573598   kErrorFlag_AddressVariableOutRange   = 1 << 17,   // new
r2821r2822
586611
587612/********** ACTION **********/
588613
589struct CheatAction
614typedef struct _cheat_action cheat_action;
615struct _cheat_action
590616{
591   UINT32   type;               // packed several information (cpu/region, address size, operation and parameters and so on)
592   UINT8   region;               // the number of cpu or region. in case of cpu, it has a kind of an address space together
593   UINT32   address;            // address. it is changeable by RWrite in the cheat core
594   UINT32   originalAddress;      // address. it is for edit/view/save
595   UINT32   data;               // data. it is changeable by VWrite/VRWrite in the cheat core
596   UINT32   originalDataField;      // data. it is for edit/view/save
597   UINT32   extendData;            // extend parameter. it is different using by each operations
617   UINT32   type;               /* packed several information (cpu/region, address size, operation and parameters and so on) */
618   UINT8   region;               /* the number of cpu or region. in case of cpu, it has a kind of an address space together */
619   UINT32   address;            /* address. it is changeable by RWrite in the cheat core */
620   UINT32   original_address;      /* address. it is for edit/view/save */
621   UINT32   data;               /* data. it is changeable by valuse selector in the cheat core */
622   UINT32   original_data;         /* data. it is for edit/view/save */
623   UINT32   extend_data;         /* extend parameter. it is different using by each operations */
598624
599   INT32   frameTimer;            // timer for delay, keep
600   UINT32   * lastValue;         // back up value before cheating to restore value. PDWWrite uses 2 and RWrite uses about a counter
625   INT32   frame_timer;         /* timer for delay/keep */
626   UINT32   *last_value;         /* back up value before cheating to restore value. PDWWrite uses 2 and RWrite uses about a counter */
601627
602   UINT32   flags;               // internal flags
628   UINT32   flags;               /* internal flags */
603629
604   UINT8   ** cachedPointer;      // pointer for data, I/O space or non-cpu region
605   UINT32   cachedOffset;         // offset for mapped memory
630   UINT8   **cached_pointer;      /* pointer to specified address space or mapped memory */
631   UINT32   cached_offset;         /* offset for mapped memory */
606632
607   char   * optionalName;         // name to display in edit/view menu. Action doesn't have a comment
633   char   *optional_name;         /* label for label selection or popup */
608634};
609635
610typedef struct CheatAction   CheatAction;
611
612636/********** ENTRY **********/
613637
614struct CheatEntry
638typedef struct _cheat_entry cheat_entry;
639struct _cheat_entry
615640{
616   char         * name;               // name to display in list menu
617   char         * comment;            // comment
641   char         *name;               /* name to display in list menu */
642   char         *comment;            /* simple comment */
618643
619   INT32         actionListLength;      // minimum length = 1
620   CheatAction      * actionList;
644   INT32         action_list_length;      /* total codes of cheat action. NOTE : minimum length is 1 and 0 is ERROR */
645   cheat_action   *action_list;         /* pointer to cheat action */
621646
622   int            activationKey1;         // activation key index for 1st key
623   int            activationKey2;         // activation key index for 2nd key
647   int            activation_key1;      /* activation key index for 1st key */
648   int            activation_key2;      /* activation key index for 2nd key */
624649
625   int            selection;            // for label-select to set selected label number
626   int            labelIndexLength;      // minimum length = 1
627   int            * labelIndex;         // label index table
628   int            layerIndex;            // layer index for enable/disable menu
650   int            selection;            /* for label-select to set selected label number */
651   int            label_index_length;      /* total tables of index table. NOTE : minimum length is 1 and 0 is ERROR */
652   int            *label_index;         /* pointer of label index table */
629653
630   UINT32         flags;               // internal flags
654   int            layer_index;         /* layer index for enable/disable menu */
655   UINT32         flags;               /* internal flags */
631656};
632657
633typedef struct CheatEntry   CheatEntry;
634
635658/********** WATCH **********/
636659
637struct WatchInfo
660typedef struct _watch_info watch_info;
661struct _watch_info
638662{
639   UINT32         address;
640   UINT8         cpu;
641   UINT8         numElements;
642   UINT8         elementBytes;
643   UINT8         labelType;
644   UINT8         displayType;
645   UINT8         skip;
646   UINT8         elementsPerLine;
647   INT8         addValue;
648   INT8         addressShift;
649   INT8         dataShift;
650   UINT32         xor;
663   UINT32      address;         /* address */
664   UINT8      cpu;            /* target cpu or region */
665   UINT8      num_elements;      /* length of this watchpoint */
666   UINT8      element_bytes;      /* address size of this watchpoint */
667   UINT8      label_type;         /* header label */
668   UINT8      display_type;      /* type of value display */
669   UINT8      skip;            /* address skip */
670   UINT8      elements_per_line;   /* max watchpoints in the same line */
671   INT8      add_value;         /* add value */
672   INT8      address_shift;      /* address shift */
673   INT8      data_shift;         /* data shift */
674   UINT32      xor;            /* xor */
651675
652   float         x, y;
676   float      x, y;            /* position */
653677
654   CheatEntry *   linkedCheat;
678   cheat_entry   *linked_cheat;      /* relative cheat_entry */
655679
656   char         label[256];
680   char      label[256];         /* name of label */
657681};
658682
659typedef struct WatchInfo   WatchInfo;
660
661683/********** REGION **********/
662684
663685typedef struct _search_region search_region;
664686struct _search_region
665687{
666   UINT32   address;
667   UINT32   length;
688   UINT32   address;         /* address */
689   UINT32   length;            /* total length */
668690
669   UINT8   target_type;
670   UINT8   target_idx;
691   UINT8   target_type;      /* flag for cpu or region */
692   UINT8   target_idx;         /* target cpu/region */
671693
672   UINT8   flags;
694   UINT8   flags;            /* internal flags */
673695
674   UINT8   ** cached_pointer;
696   UINT8   **cached_pointer;   /* pointer to except standard cpu region */
675697   const address_map_entry
676         * write_handler;
698         *write_handler;      /* pointer to write handler from address map */
677699
678   UINT8   * first;
679   UINT8   * last;
700   UINT8   *first;            /* first value in searching */
701   UINT8   *last;            /* current value in searching */
680702
681   UINT8   * status;
703   UINT8   *status;
682704
683   UINT8   * backup_last;
684   UINT8   * backup_status;
705   UINT8   *backup_last;      /* previous value in searching */
706   UINT8   *backup_status;      /* flag of backup */
685707
686   char   name[64];
708   char   name[64];         /* name of this region. NOTE : used in advanced search only */
687709
688   UINT32   num_results;
689   UINT32   old_num_results;
710   UINT32   num_results;      /* total results */
711   UINT32   old_num_results;   /* previous total results */
690712};
691713
692714/********** SEARCH **********/
r2821r2822
773795typedef struct _cheat_menu_item_info cheat_menu_item_info;
774796struct _cheat_menu_item_info
775797{
776   UINT32   sub_cheat;      /* the number of an item */
798   UINT32   sub_cheat;      /* index of an item */
777799   UINT32   field_type;      /* field type of an item */
778800   UINT32   extra_data;      /* it stores an extra data but NOT read (so I don't know how to use)*/
779801};
r2821r2822
793815typedef const struct _cheat_format cheat_format;
794816struct _cheat_format
795817{
796   const char *   format_string;         /* string templete of a format */
818   const char      *format_string;         /* string templete of a format */
797819   UINT8         arguments_matched;      /* valid arguments of a format */
798   UINT8         length_matched;         /* valid length of a parameter */
799   UINT8         comment_matched;      /* valid argument to add comment */
820   UINT8         type_matched;         /* valid length of a type field */
821   UINT8         data_matched;         /* valid length of a data/extend data field */
822   UINT8         comment_matched;      /* valid arguments to add comment */
800823};
801824
802825static const struct _cheat_format cheat_format_table[] =
803826{
804827      /* option - :_command:TYPE */
805   {   ":_command:%[^:\n\r]",                                    1,   8,   0   },
828   {   ":_command:%[^:\n\r]",                                                1,   8,   0,   0   },
806829#ifdef MESS
807      /* code (new) - >MACHINE_NAME:CRC:TYPE:ADDRESS:DATA:EXTEND_DATA:(DESCRIPTION:COMMENT) */
808   {   ">%8[^:\n\r]:%8X:%8X:%X:%8[^:\n\r]:%8[^:\n\r]:%[^:\n\r]:%[^:\n\r]",   6,   8,   8   },
830      /* code (new) - :MACHINE_NAME::CRC::TYPE::ADDRESS::DATA::EXTEND_DATA:(DESCRIPTION:COMMENT) */
831   {   ":%8[^:\n\r]::%8X::%10[^:\n\r]::%X::%8[^:\n\r]::%8[^:\n\r]:%[^:\n\r]:%[^:\n\r]",   6,   10,   8,   8   },
809832      /* code (old) - :MACHINE_NAME:CRC:TYPE:ADDRESS:DATA:EXTEND_DATA:(DESCRIPTION:COMMENT) */
810   {   ":%8s:%8X:%8X:%X:%8[^:\n\r]:%8[^:\n\r]:%[^:\n\r]:%[^:\n\r]",      6,   8,   0   },
833   {   ":%8s:8X:%8[^:\n\r]:%X:%8[^:\n\r]:%8[^:\n\r]:%[^:\n\r]:%[^:\n\r]",               6,   8,   8,   0   },
811834      /* code (older) - :MACHINE_NAME:CRC:CPU:ADDRESS:DATA:TYPE:(DESCRIPTION:COMMENT) */
812   {   "%8[^:\n\r]:%8X:%d:%X:%X:%d:%[^:\n\r]:%[^:\n\r]",               5,   0,   8   },
835   {   "%8[^:\n\r]:%8X:%d:%X:%X:%d:%[^:\n\r]:%[^:\n\r]",                           5,   0,   0,   8   },
813836      /* user region - :MACHINE_NAME:CRC:CPU:ADDRESS_SPACE:START_ADDRESS:END_ADDRESS:STATUS:(DESCRIPTION) */
814   {   ">%8[^:\n\r]:%8X:%2X:%2X:%X:%X:%1X:%[^:\n\r]",                  7,   0,   0   },
837   {   ":%8[^:\n\r]:%8X:%2X:%2X:%X:%X:%1X:%[^:\n\r]",                              7,   0,   0,   0   },
815838#else
816      /* code (new) - >GAME_NAME:TYPE:ADDRESS:DATA:EXTEND_DATA:(DESCRIPTION:COMMENT) */
817   {   ">%8[^:\n\r]:%8X:%X:%8[^:\n\r]:%8[^:\n\r]:%[^:\n\r]:%[^:\n\r]",      5,   8,   7   },
839      /* code (new) - :GAME_NAME::TYPE::ADDRESS::DATA::EXTEND_DATA:(DESCRIPTION:COMMENT) */
840   {   ":%8[^:\n\r]::%10[^:\n\r]::%X::%8[^:\n\r]::%8[^:\n\r]:%[^:\n\r]:%[^:\n\r]",         5,   10,   8,   7   },
818841      /* code (old) - :GAME_NAME:TYPE:ADDRESS:DATA:EXTEND_DATA:(DESCRIPTION:COMMENT) */
819   {   ":%8s:%8X:%X:%8[^:\n\r]:%8[^:\n\r]:%[^:\n\r]:%[^:\n\r]",         5,   8,   0   },
842   {   ":%8s:%8[^:\n\r]:%X:%8[^:\n\r]:%8[^:\n\r]:%[^:\n\r]:%[^:\n\r]",                  5,   8,   8,   0   },
820843      /* code (older) - :GAME_NAME:CPU:ADDRESS:DATA:TYPE:(DESCRIPTION:COMMENT) */
821   {   "%8[^:\n\r]:%d:%X:%X:%d:%[^:\n\r]:%[^:\n\r]",                  4,   0,   7   },
844   {   "%8[^:\n\r]:%d:%X:%X:%d:%[^:\n\r]:%[^:\n\r]",                              4,   0,   0,   7   },
822845      /* user region - :GAME_NAME:CPU:ADDRESS_SPACE:START_ADDRESS:END_ADDRESS:STATUS:(DESCRIPTION) */
823   {   ">%8[^:\n\r]:%2X:%2X:%X:%X:%1X:%[^:\n\r]",                     6,   0,   0   },
846   {   ":%8[^:\n\r]:%2X:%2X:%X:%X:%1X:%[^:\n\r]",                                 6,   0,   0,   0   },
824847#endif   /* MESS */
825848   /* end of table */
826849   {   0   }
r2821r2822
830853    EXPORTED VARIABLES
831854***************************************************************************/
832855
833static const char         * cheatfile = NULL;
856static const char         *cheat_file = NULL;
834857
835858/***************************************************************************
836859    GLOBAL VARIABLES
837860***************************************************************************/
838861
839static emu_timer         * periodic_timer;
862static emu_timer         *periodic_timer;
840863
841static CheatEntry         * cheatList = NULL;
842static INT32            cheatListLength = 0;      // NOTE : 0 means no cheat entry and error
864static cheat_entry         *cheat_list;
865static INT32            cheat_list_length;
843866
844static WatchInfo         * watchList = NULL;
845static INT32            watchListLength = 0;
867static watch_info         *watch_list;
868static INT32            watch_list_length;
846869
847static search_info         *search_list = NULL;
848static INT32            search_list_length = 0;
849static INT32            current_search_idx = 0;
870static search_info         *search_list;
871static INT32            search_list_length;
872static INT32            current_search_idx;
850873
851874static cpu_region_info      cpu_info_list[MAX_CPU];
852875static cpu_region_info      region_info_list[REGION_LIST_LENGTH];
853876
854static int               foundCheatDatabase = 0;
877static int               found_database = 0;
855878static int               cheatsDisabled = 0;
856879static int               watchesDisabled = 0;
857880
858881static int               fullMenuPageHeight;
859882static int               visible_items;
860883
861static char               mainDatabaseName[CHEAT_FILENAME_MAX_LEN + 1];
884static char               main_database_name[CHEAT_FILENAME_MAX_LEN + 1];
862885
863886static menu_string_list      menu_strings;
864887
r2821r2822
873896
874897static int               cheatVariable[VARIABLE_MAX_ARRAY] = { 0 };
875898
876static UINT32            cheatOptions;
899static UINT32            cheat_options;
877900static UINT32            driverSpecifiedFlag;
878static UINT8            messageType;
879static UINT8            messageTimer;
901static UINT8            message_type;
902static UINT8            message_timer;
880903
881904static cpu_region_info raw_cpu_info =
882905{
r2821r2822
11651188#endif
11661189
11671190/********** ENTRY LIST **********/
1168static void      ResizeCheatList(UINT32 newLength);
1169static void      ResizeCheatListNoDispose(UINT32 newLength);
1191static void      resize_cheat_list(UINT32 new_length, UINT8 dispose);
11701192
1171static void      AddCheatBefore(UINT32 idx);
1172static void      DeleteCheatAt(UINT32 idx);
1193static void      add_cheat_before(UINT32 idx);
1194static void      delete_cheat_at(UINT32 idx);
11731195
1174static void      DisposeCheat(CheatEntry * entry);
1175static CheatEntry
1176            *GetNewCheat(void);
1196static void      dispose_cheat(cheat_entry *entry);
1197static cheat_entry
1198            *get_new_cheat(void);
11771199
11781200/********** ACTION LIST **********/
1179static void      ResizeCheatActionList(CheatEntry * entry, UINT32 newLength);
1201static void      resize_cheat_action_list(cheat_entry *entry, UINT32 new_length, UINT8 dispose);
11801202#if 0
1181static void      ResizeCheatActionListNoDispose(CheatEntry * entry, UINT32 newLength);
1182
11831203static void      AddActionBefore(CheatEntry * entry, UINT32 idx);
11841204static void      DeleteActionAt(CheatEntry * entry, UINT32 idx);
11851205#endif
1186static void      DisposeAction(CheatAction * action);
1206static void      dispose_action(cheat_action *action);
11871207
11881208/********** WATCH LIST **********/
1189static void      InitWatch(WatchInfo * info, UINT32 idx);
1190static void      ResizeWatchList(UINT32 newLength);
1191static void      ResizeWatchListNoDispose(UINT32 newLength);
1209static void      init_watch(watch_info *info, UINT32 idx);
1210static void      resize_watch_list(UINT32 new_length, UINT8 dispose);
11921211
1193static void      AddWatchBefore(UINT32 idx);
1194static void      DeleteWatchAt(UINT32 idx);
1195static void      DisposeWatch(WatchInfo * watch);
1196static WatchInfo
1197            *GetUnusedWatch(void);
1212static void      add_watch_before(UINT32 idx);
1213static void      delete_watch_at(UINT32 idx);
1214static void      dispose_watch(watch_info *watch);
11981215
1199static void      AddCheatFromWatch(WatchInfo * watch);
1200static void      SetupCheatFromWatchAsWatch(CheatEntry * entry, WatchInfo * watch);
1216static watch_info
1217            *get_unused_watch(void);
12011218
1202static void      ResetWatch(WatchInfo * watch);
1219static void      add_cheat_from_watch(watch_info *watch);
1220static void      add_cheat_from_watch_as_watch(cheat_entry *entry, watch_info *watch);
12031221
1222static void      reset_watch(watch_info *watch);
1223
12041224/********** SEARCH LIST **********/
12051225static void      resize_search_list(UINT32 newLength);
12061226#if 0
r2821r2822
12241244static void      restore_region_backup(search_region *region);
12251245static UINT8   default_enable_region(running_machine *machine, search_region *region, search_info *info);
12261246static void      set_search_region_default_name(search_region *region);
1247static UINT8   is_search_region_in_range(UINT8 cpu, UINT32 length);
12271248static void      allocate_search_regions(search_info *info);
12281249static void      build_search_regions(running_machine *machine, search_info *info);
12291250
12301251/********** LOADER **********/
12311252static int      ConvertOldCode(int code, int cpu, int * data, int * extendData);
1232static int      ConvertToNewCode(CheatAction * action);
1233static void      HandleLocalCommandCheat(running_machine *machine, int cpu, int type, int address, int data, UINT8 format);
1253static int      convert_to_new_code(cheat_action *action);
1254static void      handle_local_command_cheat(running_machine *machine, int cpu, int type, int address, int data, UINT8 format);
12341255
1235static void      LoadCheatOption(char * fileName);
1236static void      LoadCheatCode(running_machine *machine, char * fileName);
1237static void      LoadUserDefinedSearchRegion(running_machine *machine, char * fileName);
1238static void      LoadCheatDatabase(running_machine *machine, UINT8 flags);
1256static void      load_cheat_option(char *file_name);
1257static void      load_cheat_code(running_machine *machine, char *file_name);
1258static void      load_user_defined_search_region(running_machine *machine, char *file_name);
1259static void      load_cheat_database(running_machine *machine, UINT8 flags);
1260static void      reload_cheat_database(running_machine *machine);
12391261
1240static void      DisposeCheatDatabase(void);
1241static void      ReloadCheatDatabase(running_machine *machine);
1262static void      dispose_cheat_database(void);
12421263
12431264/********** SAVER **********/
1244static void      SaveCheatCode(running_machine *machine, CheatEntry * entry);
1245static void      SaveActivationKey(running_machine *machine, CheatEntry * entry, int entryIndex);
1246static void      SavePreEnable(running_machine *machine, CheatEntry * entry, int entryIndex);
1247static void      SaveCheatOptions(void);
1265static void      SaveCheatCode(running_machine *machine, cheat_entry *entry);
1266static void      SaveActivationKey(running_machine *machine, cheat_entry *entry, int entryIndex);
1267static void      SavePreEnable(running_machine *machine, cheat_entry *entry, int entryIndex);
1268static void      Savecheat_options(void);
12481269static void      SaveDescription(running_machine *machine);
12491270static void      DoAutoSaveCheats(running_machine *machine);
12501271
r2821r2822
12831304static void      DoCPUWrite(UINT32 data, UINT8 cpu, UINT32 address, UINT8 bytes, UINT8 swap);
12841305static void      DoMemoryWrite(UINT32 data, UINT8 * buf, UINT32 address, UINT8 bytes, UINT8 swap, cpu_region_info *info);
12851306
1286static UINT32   ReadData(CheatAction * action);
1287static void      WriteData(CheatAction * action, UINT32 data);
1307static UINT32   ReadData(cheat_action *action);
1308static void      WriteData(cheat_action *action, UINT32 data);
12881309
12891310/********** WATCH **********/
1290static void      WatchCheatEntry(CheatEntry * entry, UINT8 associate);
1291static void      AddActionWatch(CheatAction * action, CheatEntry * entry);
1292static void      RemoveAssociatedWatches(CheatEntry * entry);
1311static void      WatchCheatEntry(cheat_entry *entry, UINT8 associate);
1312static void      AddActionWatch(cheat_action *action, cheat_entry *entry);
1313static void      RemoveAssociatedWatches(cheat_entry *entry);
12931314
12941315/********** ACTIVE/DEACTIVE ENTRY **********/
1295static void      ResetAction(CheatAction * action);
1296static void      ActivateCheat(CheatEntry * entry);
1297static void      DeactivateCheat(CheatEntry * entry);
1298static void      TempDeactivateCheat(CheatEntry * entry);
1316static void      ResetAction(cheat_action *action);
1317static void      ActivateCheat(cheat_entry *entry);
1318static void      DeactivateCheat(cheat_entry *entry);
1319static void      TempDeactivateCheat(cheat_entry *entry);
12991320
13001321/********** OPERATION CORE **********/
1301static void      cheat_periodicOperation(CheatAction * action);
1302static UINT8   cheat_periodicCondition(CheatAction * action);
1303static int      cheat_periodicAction(running_machine *machine, CheatAction * action, int selection);
1304static void      cheat_periodicEntry(running_machine *machine, CheatEntry * entry);
1322static void      cheat_periodicOperation(cheat_action *action);
1323static UINT8   cheat_periodicCondition(cheat_action *action);
1324static int      cheat_periodicAction(running_machine *machine, cheat_action *action, int selection);
1325static void      cheat_periodicEntry(running_machine *machine, cheat_entry *entry);
13051326
13061327/********** CONFIGURE ENTRY **********/
1307static void      UpdateAllCheatInfo(void);
1308static void      UpdateCheatInfo(CheatEntry * entry, UINT8 isLoadTime);
1309static UINT32   AnalyseCodeFormat(CheatEntry * entry, CheatAction * action);
1310static void      CheckCodeFormat(CheatEntry * entry);
1311static void      BuildLabelIndexTable(CheatEntry *entry);
1328static void      update_all_cheat_info(void);
1329static void      update_cheat_info(cheat_entry *entry, UINT8 is_load_time);
1330static UINT32   AnalyseCodeFormat(cheat_entry *entry, cheat_action *action);
1331static void      check_code_format(cheat_entry *entry);
1332static void      BuildLabelIndexTable(cheat_entry *entry);
13121333static void      SetLayerIndex(void);
13131334
13141335/********** OTHER STUFF **********/
13151336static void      DisplayCheatMessage(void);
13161337static UINT8   get_address_length(UINT8 region);
1317static char *   get_region_name(UINT8 region);
1338static char      *get_region_name(UINT8 region);
13181339static void      build_cpu_region_info_list(running_machine *machine);
13191340
13201341/***************************************************************************
r2821r2822
13511372
13521373INLINE cpu_region_info *get_cpu_or_region_info(UINT8 cpu_region)
13531374{
1354   if(TEST_FIELD(cpu_region, RegionFlag))
1355      return get_region_info(cpu_region);
1356   else
1375   if(cpu_region < REGION_INVALID)
13571376      return get_cpu_info(cpu_region);
1377   else
1378      return get_region_info(cpu_region);
13581379}
13591380
13601381/*-----------------
r2821r2822
13631384
13641385INLINE UINT8 cpu_needs_swap(UINT8 cpu)
13651386{
1366   return cpu_info_list[cpu].endianness | 1;
1387   return cpu_info_list[cpu].endianness ^ 1;
13671388}
13681389
13691390/*--------------------
r2821r2822
13751396   cpu_region_info *temp = get_region_info(region);
13761397
13771398   if(temp)
1378      return temp->endianness | 1;
1399      return temp->endianness ^ 1;
13791400
13801401   return 0;
13811402}
r2821r2822
14041425   return address;
14051426}
14061427
1407/*-------------------
1408  IsAddressInRange
1409-------------------*/
1428/*---------------------------------------------------------------------------------
1429  is_address_in_range - check the range of address for eeprom and non-cpu region
1430---------------------------------------------------------------------------------*/
14101431
1411INLINE int IsAddressInRange(CheatAction * action, UINT32 length)
1432INLINE int is_address_in_range(cheat_action *action, UINT32 length)
14121433{
14131434   return ((action->address + EXTRACT_FIELD(action->type, AddressSize) + 1) <= length);
14141435}
r2821r2822
14521473  ReadKeyAsync - dirty hack until osd_readkey_unicode is supported in MAMEW re-implementation of osd_readkey_unicode
14531474---------------------------------------------------------------------------------------------------------------------*/
14541475
1455#if 1
1456
14571476#if OSD_READKEY_KLUDGE
14581477
14591478static int ReadKeyAsync(int flush)
14601479{
14611480   int   code;
14621481
1463   if(flush)      // check key input
1482   if(flush)
14641483   {
1484      /* check key input */
14651485      while(input_code_poll_keyboard_switches(TRUE) != INPUT_CODE_INVALID) ;
14661486
14671487      return 0;
14681488   }
14691489
1470   while(1)      // check pressed key
1490   while(1)
14711491   {
1492      /* check pressed key */
14721493      code = input_code_poll_keyboard_switches(FALSE);
14731494
14741495      if(code == INPUT_CODE_INVALID)
14751496      {
14761497         return 0;
14771498      }
1478      else if((code >= KEYCODE_A) && (code <= KEYCODE_Z))
1499      else if(code >= KEYCODE_A && code <= KEYCODE_Z)
14791500      {
1480         if(ShiftKeyPressed())
1481         {
1482            return 'A' + (code - KEYCODE_A);
1483         }
1484         else
1485         {
1486            return 'a' + (code - KEYCODE_A);
1487         }
1501         if(ShiftKeyPressed())      return 'A' + (code - KEYCODE_A);
1502         else                  return 'a' + (code - KEYCODE_A);
14881503      }
1489      else if((code >= KEYCODE_0) && (code <= KEYCODE_9))
1504      else if(code >= KEYCODE_0 && code <= KEYCODE_9)
14901505      {
1491         if(ShiftKeyPressed())
1492         {
1493            return ")!@#$%^&*("[code - KEYCODE_0];
1494         }
1495         else
1496         {
1497            return '0' + (code - KEYCODE_0);
1498         }
1506         if(ShiftKeyPressed())      return ")!@#$%^&*("[code - KEYCODE_0];
1507         else                  return '0' + (code - KEYCODE_0);
14991508      }
1500      else if((code >= KEYCODE_0_PAD) && (code <= KEYCODE_9_PAD))
1509      else if(code >= KEYCODE_0_PAD && code <= KEYCODE_9_PAD)
15011510      {
1502         return '0' + (code - KEYCODE_0_PAD);
1511                              return '0' + (code - KEYCODE_0_PAD);
15031512      }
15041513      else if(code == KEYCODE_TILDE)
15051514      {
1506         if(ShiftKeyPressed())
1507         {
1508            return '~';
1509         }
1510         else
1511         {
1512            return '`';
1513         }
1515         if(ShiftKeyPressed())      return '~';
1516         else                  return '`';
15141517      }
15151518      else if(code == KEYCODE_MINUS)
15161519      {
1517         if(ShiftKeyPressed())
1518         {
1519            return '_';
1520         }
1521         else
1522         {
1523            return '-';
1524         }
1520         if(ShiftKeyPressed())      return '_';
1521         else                  return '-';
15251522      }
15261523      else if(code == KEYCODE_EQUALS)
15271524      {
1528         if(ShiftKeyPressed())
1529         {
1530            return '+';
1531         }
1532         else
1533         {
1534            return '=';
1535         }
1525         if(ShiftKeyPressed())      return '+';
1526         else                  return '=';
15361527      }
15371528      else if(code == KEYCODE_BACKSPACE)
15381529      {
1539         return 0x08;
1530                              return 0x08;
15401531      }
15411532      else if(code == KEYCODE_OPENBRACE)
15421533      {
1543         if(ShiftKeyPressed())
1544         {
1545            return '{';
1546         }
1547         else
1548         {
1549            return '[';
1550         }
1534         if(ShiftKeyPressed())      return '{';
1535         else                  return '[';
15511536      }
15521537      else if(code == KEYCODE_CLOSEBRACE)
15531538      {
1554         if(ShiftKeyPressed())
1555         {
1556            return '}';
1557         }
1558         else
1559         {
1560            return ']';
1561         }
1539         if(ShiftKeyPressed())      return '}';
1540         else                  return ']';
15621541      }
15631542      else if(code == KEYCODE_COLON)
15641543      {
1565         if(ShiftKeyPressed())
1566         {
1567            return ':';
1568         }
1569         else
1570         {
1571            return ';';
1572         }
1544         if(ShiftKeyPressed())      return ':';
1545         else                  return ';';
15731546      }
15741547      else if(code == KEYCODE_QUOTE)
15751548      {
1576         if(ShiftKeyPressed())
1577         {
1578            return '\"';
1579         }
1580         else
1581         {
1582            return '\'';
1583         }
1549         if(ShiftKeyPressed())      return '\"';
1550         else                  return '\'';
15841551      }
15851552      else if(code == KEYCODE_BACKSLASH)
15861553      {
1587         if(ShiftKeyPressed())
1588         {
1589            return '|';
1590         }
1591         else
1592         {
1593            return '\\';
1594         }
1554         if(ShiftKeyPressed())      return '|';
1555         else                  return '\\';
15951556      }
15961557      else if(code == KEYCODE_COMMA)
15971558      {
1598         if(ShiftKeyPressed())
1599         {
1600            return '<';
1601         }
1602         else
1603         {
1604            return ',';
1605         }
1559         if(ShiftKeyPressed())      return '<';
1560         else                  return ',';
16061561      }
16071562      else if(code == KEYCODE_STOP)
16081563      {
1609         if(ShiftKeyPressed())
1610         {
1611            return '>';
1612         }
1613         else
1614         {
1615            return '.';
1616         }
1564         if(ShiftKeyPressed())      return '>';
1565         else                  return '.';
16171566      }
16181567      else if(code == KEYCODE_SLASH)
16191568      {
1620         if(ShiftKeyPressed())
1621         {
1622            return '?';
1623         }
1624         else
1625         {
1626            return '/';
1627         }
1569         if(ShiftKeyPressed())      return '?';
1570         else                  return '/';
16281571      }
16291572      else if(code == KEYCODE_SLASH_PAD)
16301573      {
1631         return '/';
1574                              return '/';
16321575      }
16331576      else if(code == KEYCODE_ASTERISK)
16341577      {
1635         return '*';
1578                              return '*';
16361579      }
16371580      else if(code == KEYCODE_MINUS_PAD)
16381581      {
1639         return '-';
1582                              return '-';
16401583      }
16411584      else if(code == KEYCODE_PLUS_PAD)
16421585      {
1643         return '+';
1586                              return '+';
16441587      }
16451588      else if(code == KEYCODE_SPACE)
16461589      {
1647         return ' ';
1590                              return ' ';
16481591      }
16491592   }
16501593}
16511594
16521595#define osd_readkey_unicode ReadKeyAsync
16531596
1654#endif
1597#endif /* OSD_READKEY_KLUDGE */
16551598
1656#endif
1657
16581599/*---------------------------------------------------
16591600  ui_pressed_repeat_throttle - key repeat handling
16601601---------------------------------------------------*/
r2821r2822
20511992void cheat_init(running_machine *machine)
20521993{
20531994   /* initialize lists */
2054   cheatList         = NULL;
2055   cheatListLength      = 0;
1995   cheat_list         = NULL;
1996   cheat_list_length   = 0;
20561997
2057   watchList         = NULL;
2058   watchListLength      = 0;
1998   watch_list         = NULL;
1999   watch_list_length   = 0;
20592000
20602001   search_list = NULL;
20612002   search_list_length = 0;
r2821r2822
20662007
20672008   /* initialize flags */
20682009   current_search_idx   = 0;
2069   foundCheatDatabase   = 0;
2010   found_database   = 0;
20702011   cheatsDisabled      = 0;
20712012   watchesDisabled      = 0;
20722013   editActive         = 0;
20732014   editCursor         = 0;
2074   cheatOptions      = DEFAULT_CHEAT_OPTIONS;
2015   cheat_options      = DEFAULT_CHEAT_OPTIONS;
20752016   driverSpecifiedFlag   = 0;
20762017
20772018   fullMenuPageHeight = visible_items = floor(1.0f / ui_get_line_height()) - 1;
r2821r2822
20802021   build_cpu_region_info_list(machine);
20812022
20822023   /* set cheat list from database */
2083   LoadCheatDatabase(machine, kLoadFlag_CheatOption | kLoadFlag_CheatCode);
2024   load_cheat_database(machine, kLoadFlag_CheatOption | kLoadFlag_CheatCode);
20842025
20852026   /* set default search and watch lists */
20862027   resize_search_list(1);
2087   ResizeWatchList(fullMenuPageHeight - 1);
2028   resize_watch_list(fullMenuPageHeight - 1, 0);
20882029
20892030   /* build search region */
20902031   {
20912032      search_info *info = get_current_search();
20922033
20932034      /* attemp to load user region */
2094      LoadCheatDatabase(machine, kLoadFlag_UserRegion);
2035      load_cheat_database(machine, kLoadFlag_UserRegion);
20952036
20962037      /* if no user region or fail to load the database, attempt to build default region */
20972038      if(info->region_list_length)
2098         info->search_speed = ksearch_speed_UserDefined;
2039         info->search_speed = SEARCH_SPEED_USER_DEFINED;
20992040      else
21002041      {
2101         info->search_speed = ksearch_speed_VerySlow;
2042         info->search_speed = SEARCH_SPEED_VERY_SLOW;
21022043         build_search_regions(machine, info);
21032044      }
21042045
r2821r2822
21282069   }
21292070
21302071   /* NOTE : disable all cheat messages in initializing so that message parameters should be initialized here */
2131   messageType      = 0;
2132   messageTimer   = 0;
2072   SET_MESSAGE(0);
21332073
21342074   periodic_timer = timer_alloc(cheat_periodic, NULL);
21352075   timer_adjust_periodic(periodic_timer, video_screen_get_frame_period(machine->primary_screen), 0, video_screen_get_frame_period(machine->primary_screen));
r2821r2822
21462086   int i;
21472087
21482088   /* save all cheats automatically if needed */
2149   if(TEST_FIELD(cheatOptions, AutoSaveEnabled))
2089   if(TEST_FIELD(cheat_options, AutoSaveEnabled))
21502090      DoAutoSaveCheats(machine);
21512091
2152   /* free database */
2153   DisposeCheatDatabase();
2092   /* free cheat list */
2093   dispose_cheat_database();
21542094
21552095   /* free watch lists */
2156   if(watchList)
2096   if(watch_list)
21572097   {
2158      for(i = 0; i < watchListLength; i++)
2159         DisposeWatch(&watchList[i]);
2098      for(i = 0; i < watch_list_length; i++)
2099         dispose_watch(&watch_list[i]);
21602100
2161      free(watchList);
2101      free(watch_list);
21622102
2163      watchList = NULL;
2103      watch_list = NULL;
21642104   }
21652105
21662106   /* free search lists */
r2821r2822
21882128#endif
21892129
21902130   /* free flags */
2191   cheatListLength      = 0;
2192   watchListLength      = 0;
2193   search_list_length   = 0;
2194   current_search_idx   = 0;
2195   foundCheatDatabase   = 0;
2196   cheatsDisabled      = 0;
2197   watchesDisabled      = 0;
2198   mainDatabaseName[0]   = 0;
2199   menuItemInfoLength   = 0;
2200   cheatVariable[0]   = 0;
2201   cheatOptions      = 0;
2202   driverSpecifiedFlag   = 0;
2203   messageType         = 0;
2204   messageTimer      = 0;
2131   cheat_list_length      = 0;
2132   watch_list_length      = 0;
2133   search_list_length      = 0;
2134   current_search_idx      = 0;
2135   found_database         = 0;
2136   cheatsDisabled         = 0;
2137   watchesDisabled         = 0;
2138   main_database_name[0]   = 0;
2139   menuItemInfoLength      = 0;
2140   cheatVariable[0]      = 0;
2141   cheat_options         = 0;
2142   driverSpecifiedFlag      = 0;
2143   SET_MESSAGE(0);
22052144}
22062145
22072146/*----------------------------------
r2821r2822
23592298      changed = 1;
23602299   }
23612300
2362   /* length of buffer 1*/
2301   /* length of buffer 1 */
23632302   if(menu_strings.main_string_length < main_string_length)
23642303   {
23652304      menu_strings.main_string_length = main_string_length;
r2821r2822
24102349{
24112350   char *temp = NULL;
24122351
2413   if(buf)
2352   if(buf && buf[0] != 0)
24142353   {
24152354      /* allocate memory */
24162355      size_t length = strlen(buf) + 1;
r2821r2822
25352474static int user_select_value_menu(running_machine *machine, cheat_menu_stack *menu)
25362475{
25372476   int            i;
2538   UINT8         isBCD;
2477   UINT8         is_bcd;
25392478   UINT32         min;
25402479   UINT32         max;
25412480   static int      master         = 0;
2542   static int      displayValue   = -1;
2481   static int      display_value   = -1;
25432482   char         buf[256];
2544   char *         stringsBuf      = buf;
2545   CheatEntry *   entry         = &cheatList[menu->pre_sel];
2546   CheatAction *   action         = NULL;
2483   char         *strings_buf   = buf;
2484   cheat_entry      *entry         = &cheat_list[menu->pre_sel];
2485   cheat_action   *action         = NULL;
25472486
25482487   /* first setting 1 : search master code of value-selection */
25492488   if(menu->first_time)
25502489   {
2551      for(i = 0; i < entry->actionListLength; i++)
2490      for(i = 0; i < entry->action_list_length; i++)
25522491      {
2553         /* get value selection master code */
2554         if(   EXTRACT_FIELD(entry->actionList[i].type, CodeType) == kCodeType_VWrite ||
2555            EXTRACT_FIELD(entry->actionList[i].type, CodeType) == kCodeType_VRWrite)
2556         {
2557            master = i;
2558            break;
2559         }
2492         if(entry->action_list[0].flags & kActionFlag_OldFormat) {
2493            /* NOTE : old format should be always master = 0 */
2494            master = 0; break; }
2495
2496         /* search value selection master code */
2497         if(TEST_FIELD(entry->action_list[i].type, ValueSelectEnable)) {
2498            master = i; break; }
25602499      }
25612500   }
25622501
2563   action = &entry->actionList[master];
2502   /* set value selection master code */
2503   action = &entry->action_list[master];
25642504
25652505   if(TEST_FIELD(action->type, ValueSelectMinimumDisplay) || TEST_FIELD(action->type, ValueSelectMinimum))
25662506      min = 1;
25672507   else
25682508      min = 0;
25692509
2570   max      = action->originalDataField + min;
2571   isBCD   = EXTRACT_FIELD(action->type, ValueSelectBCD);
2510   max      = action->original_data + min;
2511   is_bcd   = EXTRACT_FIELD(action->type, ValueSelectBCD);
25722512
25732513   /* first setting 2 : save the value */
25742514   if(menu->first_time)
25752515   {
2576      displayValue = isBCD ? DecimalToBCD(BCDToDecimal(ReadData(action))) : ReadData(action);
2516      display_value = is_bcd ? DecimalToBCD(BCDToDecimal(ReadData(action))) : ReadData(action);
25772517
2578      if(displayValue < min)
2579         displayValue = min;
2580      else if(displayValue > max)
2581         displayValue = max;
2518      if(display_value < min)
2519         display_value = min;
2520      else if(display_value > max)
2521         display_value = max;
25822522      else if(TEST_FIELD(action->type, ValueSelectMinimumDisplay))
2583         displayValue++;
2523         display_value++;
25842524
25852525      menu->first_time = 0;
25862526   }
25872527
25882528   /* ##### MENU CONSTRACTION ##### */
2589   stringsBuf += sprintf(stringsBuf, "\t%s\n\t", entry->name);
2529   strings_buf += sprintf(strings_buf, "\t%s\n\t", entry->name);
25902530
25912531   if(editActive)
25922532   {
25932533      for(i = kSearchByteDigitsTable[EXTRACT_FIELD(action->type, AddressSize)] - 1; i >= 0; i--)
25942534      {
25952535         if(i == editCursor)
2596            stringsBuf += sprintf(stringsBuf, "[%X]", (displayValue & kIncrementMaskTable[i]) / kIncrementValueTable[i]);
2536            strings_buf += sprintf(strings_buf, "[%X]", (display_value & kIncrementMaskTable[i]) / kIncrementValueTable[i]);
25972537         else
2598            stringsBuf += sprintf(stringsBuf, "%X", (displayValue & kIncrementMaskTable[i]) / kIncrementValueTable[i]);
2538            strings_buf += sprintf(strings_buf, "%X", (display_value & kIncrementMaskTable[i]) / kIncrementValueTable[i]);
25992539      }
26002540   }
26012541   else
2602      stringsBuf += sprintf(stringsBuf, "%.*X", kSearchByteDigitsTable[EXTRACT_FIELD(action->type, AddressSize)], displayValue);
2542      strings_buf += sprintf(strings_buf, "%.*X", kSearchByteDigitsTable[EXTRACT_FIELD(action->type, AddressSize)], display_value);
26032543
26042544   if(TEST_FIELD(action->type, ValueSelectNegative))
2605      stringsBuf += sprintf(   stringsBuf, " <%.*X>",
2545      strings_buf += sprintf(   strings_buf, " <%.*X>",
26062546                        kSearchByteDigitsTable[EXTRACT_FIELD(action->type, AddressSize)],
2607                        (~displayValue + 1) & kSearchByteMaskTable[EXTRACT_FIELD(action->type, AddressSize)]);
2547                        (~display_value + 1) & kSearchByteMaskTable[EXTRACT_FIELD(action->type, AddressSize)]);
26082548
2609   if(!isBCD)
2610      stringsBuf += sprintf(stringsBuf, " (%d)", displayValue);
2549   if(is_bcd == 0)
2550      strings_buf += sprintf(strings_buf, " (%d)", display_value);
26112551
2612   stringsBuf += sprintf(stringsBuf, "\n\t OK ");
2552   strings_buf += sprintf(strings_buf, "\n\t OK ");
26132553
26142554   /* print it */
26152555   ui_draw_message_window(buf);
r2821r2822
26192559   {
26202560      if(editActive)
26212561      {
2622         if(displayValue == max)
2623            displayValue = min;
2562         if(display_value == max)
2563            display_value = min;
26242564         else
26252565         {
2626            displayValue = isBCD ? DoIncrementDecField(displayValue, editCursor) : DoIncrementHexField(displayValue, editCursor);
2566            display_value = is_bcd ? DoIncrementDecField(display_value, editCursor) : DoIncrementHexField(display_value, editCursor);
26272567
2628            if(displayValue > max)
2629               displayValue = max;
2568            if(display_value > max)
2569               display_value = max;
26302570         }
26312571      }
26322572   }
r2821r2822
26342574   {
26352575      if(editActive)
26362576      {
2637         if(displayValue == min)
2638            displayValue = max;
2577         if(display_value == min)
2578            display_value = max;
26392579
26402580         else
26412581         {
2642            displayValue = isBCD ? DoDecrementDecField(displayValue, editCursor) : DoDecrementHexField(displayValue, editCursor);
2582            display_value = is_bcd ? DoDecrementDecField(display_value, editCursor) : DoDecrementHexField(display_value, editCursor);
26432583
2644            if(displayValue > max)
2645               displayValue = max;
2584            if(display_value > max)
2585               display_value = max;
26462586         }
26472587      }
26482588   }
r2821r2822
26552595      }
26562596      else
26572597      {
2658         if(displayValue-- == min)
2659            displayValue = max;
2598         if(display_value-- == min)
2599            display_value = max;
26602600
2661         if(isBCD)
2662            displayValue = DecimalToBCD(BCDToDecimal(displayValue));
2601         if(is_bcd)
2602            display_value = DecimalToBCD(BCDToDecimal(display_value));
26632603      }
26642604   }
26652605   else if(ui_pressed_repeat_throttle(machine, IPT_UI_RIGHT, kHorizontalFastKeyRepeatRate))
r2821r2822
26712611      }
26722612      else
26732613      {
2674         if(++displayValue > max)
2675            displayValue = min;
2614         if(++display_value > max)
2615            display_value = min;
26762616
2677         if(isBCD)
2678            displayValue = DecimalToBCD(BCDToDecimal(displayValue));
2617         if(is_bcd)
2618            display_value = DecimalToBCD(BCDToDecimal(display_value));
26792619      }
26802620   }
26812621   else if(input_ui_pressed(machine, IPT_UI_SELECT))
r2821r2822
26872627
26882628      /* adjust a value */
26892629      if(TEST_FIELD(action->type, ValueSelectMinimumDisplay))
2690         displayValue--;
2630         display_value--;
26912631
2692      if(TEST_FIELD(action->type, ValueSelectMinimum) && !displayValue)
2693         displayValue = 1;
2632      if(TEST_FIELD(action->type, ValueSelectMinimum) && display_value == 0)
2633         display_value = 1;
26942634
2695      if(TEST_FIELD(action->type, ValueSelectNegative) && displayValue)
2696         displayValue = (~displayValue + 1) & kSearchByteMaskTable[EXTRACT_FIELD(action->type, AddressSize)];
2635      if(TEST_FIELD(action->type, ValueSelectNegative) && display_value)
2636         display_value = (~display_value + 1) & kSearchByteMaskTable[EXTRACT_FIELD(action->type, AddressSize)];
26972637
2698      /* copy value */
2699      for(i = 0; i < entry->actionListLength; i++)
2638      /* set/copy value */
2639      for(i = 0; i < entry->action_list_length; i++)
27002640      {
2701         CheatAction * destination = &entry->actionList[i];
2641         cheat_action *destination = &entry->action_list[i];
27022642
2703         int copyValue = displayValue;
2643         int copy_value = display_value;
27042644
2705         if(   EXTRACT_FIELD(destination->type, CodeType) == kCodeType_VWrite ||
2706            EXTRACT_FIELD(destination->type, CodeType) == kCodeType_VRWrite)
2645         if(i == master)
27072646         {
2708            destination->data = displayValue;
2647            /* set value */
2648            destination->data = display_value;
27092649         }
2710         else if(EXTRACT_FIELD(destination->type, Link) == kLink_CopyLink)
2650         else if(TEST_FIELD(destination->type, ValueSelectEnable))
27112651         {
2712            int newData = destination->originalDataField;
2652            /* copy value */
2653            int new_data = destination->original_data;
27132654
2714            if(TEST_FIELD(destination->type, LinkValueSelectBCD))
2655            if(TEST_FIELD(destination->type, ValueSelectBCD))
27152656            {
2716               copyValue   = BCDToDecimal(DecimalToBCD(copyValue));
2717               newData      = BCDToDecimal(DecimalToBCD(newData));
2657               copy_value   = BCDToDecimal(DecimalToBCD(copy_value));
2658               new_data   = BCDToDecimal(DecimalToBCD(new_data));
27182659            }
27192660
2720            copyValue += newData;
2661            copy_value += new_data;
27212662
2722            if(TEST_FIELD(destination->type, LinkValueSelectBCD))
2723               copyValue = DecimalToBCD(BCDToDecimal(copyValue));
2663            if(TEST_FIELD(destination->type, ValueSelectBCD))
2664               copy_value = DecimalToBCD(BCDToDecimal(copy_value));
27242665
2725            if(TEST_FIELD(destination->type, LinkValueSelectNegative))
2726               copyValue = (~copyValue + 1) & kSearchByteMaskTable[EXTRACT_FIELD(destination->type, AddressSize)];
2666            if(TEST_FIELD(destination->type, ValueSelectNegative))
2667               copy_value = (~copy_value + 1) & kSearchByteMaskTable[EXTRACT_FIELD(destination->type, AddressSize)];
27272668
2728            destination->data = copyValue;
2669            destination->data = copy_value;
27292670         }
27302671      }
27312672
r2821r2822
27402681   }
27412682   else if(input_ui_pressed(machine, IPT_UI_CANCEL))
27422683   {
2743      if(editActive)
2744         editActive = 0;
2745      else
2746         menu->sel = -1;
2684      if(editActive)      editActive = 0;
2685      else            menu->sel = -1;
27472686   }
27482687
27492688   /* ##### EDIT ##### */
2750   if(!editActive)
2689   if(editActive == 0)
27512690   {
27522691      UINT32 temp;
27532692
2754      temp         = displayValue;
2755      displayValue   = do_edit_hex_field(machine, displayValue) & kCheatSizeMaskTable[EXTRACT_FIELD(action->type, AddressSize)];
2693      temp         = display_value;
2694      display_value   = do_edit_hex_field(machine, display_value) & kCheatSizeMaskTable[EXTRACT_FIELD(action->type, AddressSize)];
27562695
2757      if(displayValue != temp)
2696      if(display_value != temp)
27582697      {
2759         if(isBCD)
2760            displayValue = DecimalToBCD(BCDToDecimal(displayValue));
2698         if(is_bcd)
2699            display_value = DecimalToBCD(BCDToDecimal(display_value));
27612700
2762         if(displayValue < min)   displayValue = max;
2763         if(displayValue > max)   displayValue = min;
2701         if(display_value < min)   display_value = max;
2702         if(display_value > max)   display_value = min;
27642703      }
27652704   }
27662705
r2821r2822
27752714{
27762715   int            i;
27772716   UINT8         total   = 0;
2778   const char      ** menuItem;
2779   char         ** buf;
2780   CheatEntry      * entry   = &cheatList[menu->pre_sel];
2717   const char      **menu_item;
2718   char         **buf;
2719   cheat_entry      *entry   = &cheat_list[menu->pre_sel];
27812720
27822721   /* required items = (total items + return + terminator) & (strings buf * total items [max chars = 100]) */
2783   request_strings(entry->actionListLength + 2, entry->actionListLength, 100, 0);
2784   menuItem   = menu_strings.main_list;
2722   request_strings(entry->action_list_length + 2, entry->action_list_length, 100, 0);
2723   menu_item   = menu_strings.main_list;
27852724   buf         = menu_strings.main_strings;
27862725
27872726   /* first setting : compute cursor position from previous menu */
r2821r2822
27922731   }
27932732
27942733   /********** MENU CONSTRUCTION **********/
2795   for(i = 0; i < entry->labelIndexLength; i++)
2734   for(i = 0; i < entry->label_index_length; i++)
27962735   {
2797      if(!i)
2736      if(i == 0)
27982737      {
2799         if(!(entry->flags & kCheatFlag_OneShot))
2738         if((entry->flags & kCheatFlag_OneShot) == 0)
28002739         {
28012740            /* add "OFF" item if not one shot at the first time */
28022741            if(!entry->selection)
r2821r2822
28042743            else
28052744               sprintf(buf[total], "Off");
28062745
2807            menuItem[total] = buf[total];
2746            menu_item[total] = buf[total];
28082747            total++;
28092748         }
28102749
28112750         continue;
28122751      }
28132752      else if(i == entry->selection)
2814         sprintf(buf[total], "[ %s ]", entry->actionList[entry->labelIndex[i]].optionalName);
2753         sprintf(buf[total], "[ %s ]", entry->action_list[entry->label_index[i]].optional_name);
28152754      else
2816         sprintf(buf[total], "%s", entry->actionList[entry->labelIndex[i]].optionalName);
2755         sprintf(buf[total], "%s", entry->action_list[entry->label_index[i]].optional_name);
28172756
2818      menuItem[total] = buf[total];
2757      menu_item[total] = buf[total];
28192758      total++;
28202759   }
28212760
28222761   /* ##### RETURN ##### */
2823   menuItem[total++] = "Return to Prior Menu";
2762   menu_item[total++] = "Return to Prior Menu";
28242763
28252764   /* ##### TERMINATE ARRAY ##### */
2826   menuItem[total] = NULL;
2765   menu_item[total] = NULL;
28272766
28282767   /* adjust current cursor position */
2829   ADJUST_CURSOR(menu->sel, total)
2768   ADJUST_CURSOR(menu->sel, total);
28302769
28312770   /* draw it */
2832   old_style_menu(menuItem, NULL, NULL, menu->sel, 0);
2771   old_style_menu(menu_item, NULL, NULL, menu->sel, 0);
28332772
28342773   /********** KEY HANDLING **********/
28352774   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
28362775   {
2837      CURSOR_TO_PREVIOUS(menu->sel, total)
2776      CURSOR_TO_PREVIOUS(menu->sel, total);
28382777   }
28392778   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
28402779   {
2841      CURSOR_TO_NEXT(menu->sel, total)
2780      CURSOR_TO_NEXT(menu->sel, total);
28422781   }
28432782   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
28442783   {
r2821r2822
28462785   }
28472786   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
28482787   {
2849      CURSOR_PAGE_DOWN(menu->sel, total)
2788      CURSOR_PAGE_DOWN(menu->sel, total);
28502789   }
28512790   else if(input_ui_pressed(machine, IPT_UI_SELECT))
28522791   {
r2821r2822
28612800            DeactivateCheat(entry);
28622801
28632802         /* NOTE : the index number of master code should be stored into 1st table */
2864         if(TEST_FIELD(entry->actionList[entry->labelIndex[0]].type, LabelSelectQuickClose))
2803         if(TEST_FIELD(entry->action_list[entry->label_index[0]].type, LabelSelectQuickClose))
28652804            menu->sel = -1;
28662805      }
28672806      else
r2821r2822
28802819static int comment_menu(running_machine *machine, cheat_menu_stack *menu)
28812820{
28822821   char      buf[2048];
2883   const char   * comment;
2884   CheatEntry   * entry = &cheatList[menu->pre_sel];
2822   const char   *comment;
2823   cheat_entry   *entry = &cheat_list[menu->pre_sel];
28852824
28862825   /* first setting : NONE */
28872826   if(menu->first_time)
28882827      menu->first_time = 0;
28892828
28902829   /********** MENU CONSTRUCTION **********/
2891   if(entry->comment && entry->comment[0])
2892      comment = entry->comment;
2893   else
2894      comment = "this code doesn't have a comment";
2895
2830   comment = entry->comment;
28962831   sprintf(buf, "%s\n\t OK ", comment);
28972832
28982833   /* print it */
r2821r2822
29132848{
29142849   int         i;
29152850   UINT8      total   = 0;
2916   const char   ** menuItem;
2917   char      ** buf;
2918   CheatEntry   * entry   = &cheatList[menu->pre_sel];
2851   const char   **menu_item;
2852   char      **buf;
2853   cheat_entry   *entry   = &cheat_list[menu->pre_sel];
29192854
2920   if(!entry->actionListLength)
2921      return 0;
2922
29232855   /* first setting : NONE */
29242856   if(menu->first_time)
29252857      menu->first_time = 0;
29262858
29272859   /* required items = (display comment lines + return + terminator) & (strings buf * display comment lines [max char = 100]) */
2928   request_strings(entry->actionListLength + 1, entry->actionListLength - 1, 100, 0);
2929   menuItem    = menu_strings.main_list;
2860   request_strings(entry->action_list_length + 1, entry->action_list_length - 1, 100, 0);
2861   menu_item    = menu_strings.main_list;
29302862   buf         = menu_strings.main_strings;
29312863
29322864   /********** MENU CONSTRUCTION **********/
2933   for(i = 1; i < entry->actionListLength; i++)
2865   for(i = 1; i < entry->action_list_length; i++)
29342866   {
2935      CheatAction * action = &entry->actionList[i];
2867      cheat_action *action = &entry->action_list[i];
29362868
29372869      /* NOTE : don't display the comment in master code */
2938      if(i)
2870      if(i != 0)
29392871      {
2940         sprintf(buf[total], "%s", action->optionalName);
2941         menuItem[total] = buf[total];
2872         sprintf(buf[total], "%s", action->optional_name);
2873         menu_item[total] = buf[total];
29422874         total++;
29432875      }
29442876   }
29452877
29462878   /* ##### OK ##### */
2947   menuItem[total++] = "OK";
2879   menu_item[total++] = "OK";
29482880
29492881   /* ##### TERMINATE ARRAY ##### */
2950   menuItem[total] = NULL;
2882   menu_item[total] = NULL;
29512883
29522884   /* adjust cursor position */
2953   ADJUST_CURSOR(menu->sel, total)
2885   ADJUST_CURSOR(menu->sel, total);
29542886
29552887   /* draw it */
2956   old_style_menu(menuItem, NULL, NULL, menu->sel, 0);
2888   old_style_menu(menu_item, NULL, NULL, menu->sel, 0);
29572889
29582890   /********** KEY HANDLING **********/
29592891   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
29602892   {
2961      CURSOR_TO_PREVIOUS(menu->sel, total)
2893      CURSOR_TO_PREVIOUS(menu->sel, total);
29622894   }
29632895   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
29642896   {
2965      CURSOR_TO_NEXT(menu->sel, total)
2897      CURSOR_TO_NEXT(menu->sel, total);
29662898   }
29672899   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
29682900   {
2969      CURSOR_PAGE_UP(menu->sel)
2901      CURSOR_PAGE_UP(menu->sel);
29702902   }
29712903   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
29722904   {
2973      CURSOR_PAGE_DOWN(menu->sel, total)
2905      CURSOR_PAGE_DOWN(menu->sel, total);
29742906   }
29752907   else if(input_ui_pressed(machine, IPT_UI_SELECT) || input_ui_pressed(machine, IPT_UI_CANCEL))
29762908      menu->sel = -1;
r2821r2822
30172949   menu_item[total++].text = "Add/Edit a Cheat";
30182950
30192951   /* ##### Search a Cheat ##### */
3020   switch(EXTRACT_FIELD(cheatOptions, SearchBox))
2952   switch(EXTRACT_FIELD(cheat_options, SearchBox))
30212953   {
30222954      case kSearchBox_Minimum:
30232955         menu_item[total++].text = "Search a Cheat (Minimum Mode)";
r2821r2822
30552987   /* ##### Terminate Array ##### */
30562988   menu_item[total].text = NULL;
30572989
3058   ADJUST_CURSOR(menu->sel, total)
2990   ADJUST_CURSOR(menu->sel, total);
30592991
30602992   /* print it */
30612993   ui_menu_draw(menu_item, total, menu->sel, NULL);
r2821r2822
30632995   /********** KEY HANDLING **********/
30642996   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
30652997   {
3066      CURSOR_TO_PREVIOUS(menu->sel, total)
2998      CURSOR_TO_PREVIOUS(menu->sel, total);
30672999   }
30683000   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
30693001   {
3070      CURSOR_TO_NEXT(menu->sel, total)
3002      CURSOR_TO_NEXT(menu->sel, total);
30713003   }
30723004   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
30733005   {
3074      CURSOR_PAGE_UP(menu->sel)
3006      CURSOR_PAGE_UP(menu->sel);
30753007   }
30763008   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
30773009   {
3078      CURSOR_PAGE_DOWN(menu->sel, total)
3010      CURSOR_PAGE_DOWN(menu->sel, total);
30793011   }
30803012   else if(input_ui_pressed(machine, IPT_UI_SELECT))
30813013   {
r2821r2822
30903022            break;
30913023
30923024         case kMenu_Search:
3093            switch(EXTRACT_FIELD(cheatOptions, SearchBox))
3025            switch(EXTRACT_FIELD(cheat_options, SearchBox))
30943026            {
30953027               case kSearchBox_Minimum:
30963028                  cheat_menu_stack_push(search_minimum_menu, menu->handler, menu->sel);
r2821r2822
31283060   }
31293061   else if(input_ui_pressed(machine, IPT_UI_RELOAD_CHEAT))
31303062   {
3131      ReloadCheatDatabase(machine);
3063      reload_cheat_database(machine);
31323064   }
31333065   else if(input_ui_pressed(machine, IPT_UI_CANCEL))
31343066   {
r2821r2822
31463078{
31473079   int            i;
31483080   UINT8         total         = 0;
3149   UINT8         length         = cheatListLength ? cheatListLength : 2;
3150   UINT8         isEmpty         = 0;
3151   UINT8 *         menuIndex;
3152   static INT8      currentLayer;
3153   const char      ** menu_item;
3154   const char      ** menu_subitem;
3155   char         * flagBuf;
3156   CheatEntry      * entry;
3081   UINT8         length         = cheat_list_length ? cheat_list_length : 2;
3082   UINT8         is_empty      = 0;
3083   UINT8         request_arrow   = 0;
3084   UINT8         *menu_index;
3085   static INT8      current_layer;
3086   const char      **menu_item;
3087   const char      **menu_sub_item;
3088   char         *flag_buf;
3089   cheat_entry      *entry;
31573090
31583091   /* first setting : always starts with root layer level */
31593092   if(menu->first_time)
31603093   {
3161      currentLayer = 0;
3094      current_layer = 0;
31623095      menu->first_time = 0;
31633096   }
31643097
r2821r2822
31663099   request_strings(length + 2, 0, 0, 0);
31673100
31683101   menu_item      = menu_strings.main_list;
3169   menu_subitem   = menu_strings.sub_list;
3170   flagBuf         = menu_strings.flag_list;
3102   menu_sub_item   = menu_strings.sub_list;
3103   flag_buf      = menu_strings.flag_list;
31713104
3172   menuIndex = malloc_or_die(sizeof(INT8) * (length + 1));
3173   memset(menuIndex, 0, sizeof(INT8) * (length + 1));
3105   menu_index = malloc_or_die(sizeof(INT8) * (length + 1));
3106   memset(menu_index, 0, sizeof(INT8) * (length + 1));
31743107
31753108   /********** MENU CONSTRUCTION **********/
3176   for(i = 0; i < cheatListLength; i++)
3109   for(i = 0; i < cheat_list_length; i++)
31773110   {
3178      CheatEntry * traverse   = &cheatList[i];
3111      cheat_entry *traverse = &cheat_list[i];
31793112
31803113      if(total >= fullMenuPageHeight) break;
31813114
r2821r2822
31863119         traverse->flags &= ~kCheatFlag_LayerSelected;
31873120      }
31883121
3189      if(traverse->layerIndex == currentLayer)
3122      if(traverse->layer_index == current_layer)
31903123      {
31913124         /* ##### SEPARAOTR ##### */
31923125         if(traverse->flags & kCheatFlag_Separator)
31933126         {
31943127            menu_item[total] = MENU_SEPARATOR_ITEM;
3195            menu_subitem[total] = NULL;
3196            menuIndex[total++] = i;
3128            menu_sub_item[total] = NULL;
3129            menu_index[total++] = i;
3130            traverse->flags &= ~kCheatFlag_RequestArrow;
31973131         }
31983132         else
31993133         {
r2821r2822
32073141            if(traverse->flags & kCheatFlag_HasWrongCode)
32083142            {
32093143               /* "LOCKED" if wrong code */
3210               menu_subitem[total] = "Locked";
3144               menu_sub_item[total] = "Locked";
32113145               traverse->selection = 0;
3146               traverse->flags &= ~kCheatFlag_RequestArrow;
32123147            }
32133148            else if(traverse->flags & kCheatFlag_Select)
32143149            {
32153150               /* label or "OFF" if label-selection though one-shot should ignore "OFF" */
32163151               if(traverse->selection)
3217                  menu_subitem[total] = traverse->actionList[traverse->labelIndex[traverse->selection]].optionalName;
3152                  menu_sub_item[total] = traverse->action_list[traverse->label_index[traverse->selection]].optional_name;
32183153               else
3219                  menu_subitem[total] = "Off";
3154                  menu_sub_item[total] = "Off";
3155
3156               traverse->flags |= kCheatFlag_RequestArrow;
32203157            }
32213158            else if(traverse->flags & kCheatFlag_ExtendComment)
32223159            {
32233160               /* "READ" if extend comment code */
3224               menu_subitem[total] = "Read";
3161               menu_sub_item[total] = "Read";
3162               traverse->flags &= ~kCheatFlag_RequestArrow;
32253163            }
32263164            else if(traverse->flags & kCheatFlag_LayerIndex)
32273165            {
32283166               /* ">>>" (next layer) if layer label code */
3229               menu_subitem[total] = ">>>";
3167               menu_sub_item[total] = ">>>";
3168               traverse->flags &= ~kCheatFlag_RequestArrow;
32303169            }
3231            else if(!(traverse->flags & kCheatFlag_Null))
3170            else if((traverse->flags & kCheatFlag_Null) == 0)
32323171            {
32333172               /* otherwise, add sub-items */
32343173               if(traverse->flags & kCheatFlag_OneShot)
3235                  menu_subitem[total] = "Set";
3236               else if(traverse->flags & kCheatFlag_Active)
3237                  menu_subitem[total] = "On";
3174               {
3175                  menu_sub_item[total] = "Set";
3176                  traverse->flags &= ~kCheatFlag_RequestArrow;
3177               }
32383178               else
3239                  menu_subitem[total] = "Off";
3179               {
3180                  if(traverse->flags & kCheatFlag_Active)
3181                     menu_sub_item[total] = "On";
3182                  else
3183                     menu_sub_item[total] = "Off";
3184
3185                  traverse->flags |= kCheatFlag_RequestArrow;
3186               }
32403187            }
32413188
32423189            /* set highlight flag if comment is set */
32433190            if(traverse->comment && traverse->comment[0])
3244               flagBuf[total] = 1;
3191               flag_buf[total] = 1;
32453192            else
3246               flagBuf[total] = 0;
3247            menuIndex[total++] = i;
3193               flag_buf[total] = 0;
3194            menu_index[total++] = i;
32483195         }
32493196      }
32503197      else if(traverse->flags & kCheatFlag_LayerIndex)
32513198      {
3252         if(currentLayer == traverse->actionList[0].data)
3199         if(current_layer == traverse->action_list[0].data)
32533200         {
32543201            /* specified handling previous layer label code with "<<<" (previous layer) */
32553202            if(traverse->comment)
32563203               menu_item[total] = traverse->comment;
32573204            else
32583205               menu_item[total] = "Return to Prior Layer";
3259            menu_subitem[total] = "<<<";
3260            flagBuf[total] = 0;
3261            menuIndex[total++] = i;
3206            menu_sub_item[total] = "<<<";
3207            flag_buf[total] = 0;
3208            menu_index[total++] = i;
3209            traverse->flags &= ~kCheatFlag_RequestArrow;
32623210         }
32633211      }
32643212   }
32653213
32663214   /* if no code, set special message */
3267   if(!cheatListLength)
3215   if(cheat_list_length == 0)
32683216   {
3269      if(foundCheatDatabase)
3217      if(found_database)
32703218      {
32713219         /* the database is found but no code */
3272         menu_item[total]   = "there are no cheats for this game";
3273         menu_subitem[total]   = NULL;
3274         menuIndex[total]   = total;
3275         flagBuf[total++]   = 0;
3276         isEmpty            = 1;
3220         menu_item[total]      = "there are no cheats for this game";
3221         menu_sub_item[total]   = NULL;
3222         menu_index[total]      = total;
3223         flag_buf[total++]      = 0;
3224         is_empty            = 1;
32773225      }
32783226      else
32793227      {
32803228         /* the database itself is not found */
3281         menu_item[total]   = "cheat database not found";
3282         menu_subitem[total]   = NULL;
3283         menuIndex[total]   = total;
3284         flagBuf[total++]   = 0;
3229         menu_item[total]      = "cheat database not found";
3230         menu_sub_item[total]   = NULL;
3231         menu_index[total]      = total;
3232         flag_buf[total++]      = 0;
32853233
3286         menu_item[total]   = "unzip it and place it in the MAME directory";
3287         menu_subitem[total]   = NULL;
3288         menuIndex[total]   = total;
3289         flagBuf[total++]   = 0;
3290         isEmpty            = 2;
3234         menu_item[total]      = "unzip it and place it in the MAME directory";
3235         menu_sub_item[total]   = NULL;
3236         menu_index[total]      = total;
3237         flag_buf[total++]      = 0;
3238         is_empty            = 2;
32913239      }
32923240   }
3293   else if(currentLayer && total == 1)
3241   else if(current_layer && total == 1)
32943242   {
32953243      /* selected layer doesn't have code */
3296      menu_item[total]   = "selected layer doesn't have sub code";
3297      menu_subitem[total]   = NULL;
3298      menuIndex[total]   = menuIndex[total - 1];
3299      flagBuf[total++]   = 0;
3300      isEmpty = 3;
3244      menu_item[total]      = "selected layer doesn't have sub code";
3245      menu_sub_item[total]   = NULL;
3246      menu_index[total]      = menu_index[total - 1];
3247      flag_buf[total++]      = 0;
3248      is_empty            = 3;
33013249   }
33023250
33033251   /* ##### RETURN ##### */
3304   if(currentLayer)
3305      menu_item[total] = "Return to Root Layer";
3252   if(current_layer)
3253      menu_item[total]   = "Return to Root Layer";
33063254   else
3307      menu_item[total] = "Return to Prior Menu";
3308   menu_subitem[total] = NULL;
3309   flagBuf[total++] = 0;
3255      menu_item[total]   = "Return to Prior Menu";
3256   menu_sub_item[total]   = NULL;
3257   flag_buf[total++]      = 0;
33103258
33113259   /* ##### TERMINATE ARRAY ##### */
3312   menu_item[total] = NULL;
3313   menu_subitem[total] = NULL;
3314   flagBuf[total] = 0;
3260   menu_item[total]      = NULL;
3261   menu_sub_item[total]   = NULL;
3262   flag_buf[total]         = 0;
33153263
33163264   /* adjust cursor position */
3317   switch(isEmpty)
3265   switch(is_empty)
33183266   {
33193267      default:
3320         ADJUST_CURSOR(menu->sel, total)
3268         ADJUST_CURSOR(menu->sel, total);
33213269
33223270         /* if cursor is on comment code, skip it */
3323         while(menu->sel < total - 1 && (cheatList[menuIndex[menu->sel]].flags & kCheatFlag_Null))
3271         while(menu->sel < total - 1 && (cheat_list[menu_index[menu->sel]].flags & kCheatFlag_Null))
33243272            menu->sel++;
33253273         break;
33263274
r2821r2822
33363284            menu->sel = 0;
33373285   }
33383286
3287   /* set selected item's cheat entry */
3288   if(is_empty == 0 && menu->sel < total - 1)
3289   {
3290      entry = &cheat_list[menu_index[menu->sel]];
3291
3292      if(entry->flags & kCheatFlag_Null)
3293         entry = NULL;
3294
3295      if(entry->flags & kCheatFlag_Separator)
3296         entry = NULL;
3297
3298      if(entry->flags & kCheatFlag_RequestArrow)
3299         request_arrow = 3;
3300   }
3301   else
3302      entry = NULL;
3303
33393304   /* draw it */
3340   old_style_menu(menu_item, menu_subitem, flagBuf, menu->sel, 3);
3305   old_style_menu(menu_item, menu_sub_item, flag_buf, menu->sel, request_arrow);
33413306
33423307   /********** KEY HANDLING **********/
33433308   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
33443309   {
3345      switch(isEmpty)
3310      switch(is_empty)
33463311      {
33473312         default:
3348            CURSOR_TO_PREVIOUS(menu->sel, total)
3349            if(cheatListLength)
3313            CURSOR_TO_PREVIOUS(menu->sel, total);
3314
3315            if(cheat_list_length)
33503316            {
33513317               /* if cursor is on comment code, skip it */
3352               for(i = 0; (i < fullMenuPageHeight / 2) && menu->sel != total - 1 && (cheatList[menuIndex[menu->sel]].flags & kCheatFlag_Null); i++)
3318               for(i = 0; (i < fullMenuPageHeight / 2) && menu->sel != total - 1 && (cheat_list[menu_index[menu->sel]].flags & kCheatFlag_Null); i++)
33533319               {
33543320                  if(--menu->sel < 0)
33553321                     menu->sel = total - 1;
r2821r2822
33693335   }
33703336   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
33713337   {
3372      switch(isEmpty)
3338      switch(is_empty)
33733339      {
33743340         default:
3375            CURSOR_TO_NEXT(menu->sel, total)
3376            if(cheatListLength)
3341            CURSOR_TO_NEXT(menu->sel, total);
3342
3343            if(cheat_list_length)
33773344            {
33783345               /* if cursor is on comment code, skip it */
3379               for(i = 0; (i < fullMenuPageHeight / 2) && menu->sel < total - 1 && (cheatList[menuIndex[menu->sel]].flags & kCheatFlag_Null); i++)
3346               for(i = 0; (i < fullMenuPageHeight / 2) && menu->sel < total - 1 && (cheat_list[menu_index[menu->sel]].flags & kCheatFlag_Null); i++)
33803347                  menu->sel++;
33813348            }
33823349
r2821r2822
33923359   }
33933360   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
33943361   {
3395      CURSOR_PAGE_UP(menu->sel)
3362      CURSOR_PAGE_UP(menu->sel);
33963363   }
33973364   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
33983365   {
3399      CURSOR_PAGE_DOWN(menu->sel, total)
3366      CURSOR_PAGE_DOWN(menu->sel, total);
34003367   }
34013368
3402   if(menu->sel >= 0 && menu->sel < total - 1)
3403      entry = &cheatList[menuIndex[menu->sel]];
3404   else
3405      entry = NULL;
3406
3407   if(entry && !(entry->flags & kCheatFlag_Null) && !(entry->flags & kCheatFlag_ExtendComment) && !(entry->flags & kCheatFlag_HasWrongCode))
3369   if(entry && (entry->flags & kCheatFlag_Null) == 0 && (entry->flags & kCheatFlag_ExtendComment) == 0&& (entry->flags & kCheatFlag_HasWrongCode) == 0)
34083370   {
34093371      UINT8 toggle = 0;
34103372
r2821r2822
34123374      {
34133375         if(entry->flags & kCheatFlag_Select)
34143376         {
3415            if(TEST_FIELD(entry->actionList[entry->labelIndex[0]].type, LabelSelectUseSelector))
3377            if(TEST_FIELD(entry->action_list[entry->label_index[0]].type, LabelSelectUseSelector))
34163378            {
34173379               /* activate label selector */
34183380               cheat_menu_stack_push(user_select_label_menu, menu->handler, menu->sel);
r2821r2822
34213383            {
34223384               /* select previous label */
34233385               if(--entry->selection < 0)
3424                  entry->selection = entry->labelIndexLength - 1;
3386                  entry->selection = entry->label_index_length - 1;
34253387
34263388               /* NOTE : one shot cheat should not be activated by changing label */
3427               if(!entry->labelIndex[entry->selection])
3389               if(entry->label_index[entry->selection] == 0)
34283390                  DeactivateCheat(entry);
3429               else if(!(entry->flags & kCheatFlag_OneShot) && !(entry->flags & kCheatFlag_Active))
3391               else if((entry->flags & kCheatFlag_OneShot) == 0 && (entry->flags & kCheatFlag_Active) == 0)
34303392                  ActivateCheat(entry);
34313393            }
34323394         }
r2821r2822
34463408         if(entry->flags & kCheatFlag_Select)
34473409         {
34483410            /* label-selection special handling */
3449            if(TEST_FIELD(entry->actionList[entry->labelIndex[0]].type, LabelSelectUseSelector))
3411            if(TEST_FIELD(entry->action_list[entry->label_index[0]].type, LabelSelectUseSelector))
34503412            {
34513413               /* activate label selector */
34523414               cheat_menu_stack_push(user_select_label_menu, menu->handler, menu->sel);
r2821r2822
34543416            else
34553417            {
34563418               /* select next label index */
3457               if(++entry->selection >= entry->labelIndexLength)
3419               if(++entry->selection >= entry->label_index_length)
34583420                  entry->selection = 0;
34593421
34603422               /* NOTE : one shot cheat should not be activated by changing label */
3461               if(!entry->labelIndex[entry->selection])
3423               if(entry->label_index[entry->selection] == 0)
34623424                  DeactivateCheat(entry);
3463               else if(!(entry->flags & kCheatFlag_OneShot) && !(entry->flags & kCheatFlag_Active))
3425               else if((entry->flags & kCheatFlag_OneShot) == 0 && (entry->flags & kCheatFlag_Active) == 0)
34643426                  ActivateCheat(entry);
34653427            }
34663428         }
r2821r2822
35003462         case 2:
35013463            {
35023464               /* go to next/previous layer level */
3503               if(entry->actionList[0].data == currentLayer)
3504                  currentLayer = entry->actionList[0].address;
3465               if(entry->action_list[0].data == current_layer)
3466                  current_layer = entry->action_list[0].address;
35053467               else
3506                  currentLayer = entry->actionList[0].data;
3468                  current_layer = entry->action_list[0].data;
35073469
35083470               entry->flags |= kCheatFlag_LayerSelected;
35093471            }
r2821r2822
35163478
35173479   if(input_ui_pressed(machine, IPT_UI_SELECT))
35183480   {
3519      if(!entry)
3481      if(entry == NULL)
35203482      {
3521         if(currentLayer)
3522            currentLayer = menu->sel = 0;
3483         if(current_layer)
3484            current_layer = menu->sel = 0;
35233485         else
35243486            menu->sel = -1;
35253487      }
3526      else if(!(entry->flags & kCheatFlag_Null))
3488      else if((entry->flags & kCheatFlag_Null) == 0)
35273489      {
35283490         if(ShiftKeyPressed() && (entry->comment && entry->comment[0]))
35293491         {
r2821r2822
35323494         }
35333495         else if(entry->flags & kCheatFlag_ExtendComment)
35343496         {
3535            /* activate extend comment menu */
3497            /* display extend comment */
35363498            cheat_menu_stack_push(extend_comment_menu, menu->handler, menu->sel);
35373499         }
35383500         else if(entry->flags & kCheatFlag_UserSelect)
r2821r2822
35403502            /* activate value-selection menu */
35413503            cheat_menu_stack_push(user_select_value_menu, menu->handler, menu->sel);
35423504         }
3543         else if((entry->flags & kCheatFlag_Select) && TEST_FIELD(entry->actionList[entry->labelIndex[0]].type, LabelSelectUseSelector))
3505         else if((entry->flags & kCheatFlag_Select) && TEST_FIELD(entry->action_list[entry->label_index[0]].type, LabelSelectUseSelector))
35443506         {
35453507            /* activate label selector */
35463508            cheat_menu_stack_push(user_select_label_menu, menu->handler, menu->sel);
r2821r2822
35483510         else if(entry->flags & kCheatFlag_LayerIndex)
35493511         {
35503512            /* go to next/previous layer level */
3551            if(entry->actionList[0].data == currentLayer)
3552               currentLayer = entry->actionList[0].address;
3513            if(entry->action_list[0].data == current_layer)
3514               current_layer = entry->action_list[0].address;
35533515            else
3554               currentLayer = entry->actionList[0].data;
3516               current_layer = entry->action_list[0].data;
35553517
35563518            entry->flags |= kCheatFlag_LayerSelected;
35573519         }
r2821r2822
35723534      if(ShiftKeyPressed())
35733535      {
35743536         /* shift + save : save all codes */
3575         for(i = 0; i < cheatListLength; i++)
3576            SaveCheatCode(machine, &cheatList[i]);
3537         for(i = 0; i < cheat_list_length; i++)
3538            SaveCheatCode(machine, &cheat_list[i]);
35773539
3578         messageTimer = DEFAULT_MESSAGE_TIME;
3579         messageType = kCheatMessage_AllCheatSaved;
3540         SET_MESSAGE(kCheatMessage_AllCheatSaved);
35803541      }
35813542      else if(ControlKeyPressed())
35823543      {
35833544         /* ctrl + save : save activation key */
3584         SaveActivationKey(machine, entry, menuIndex[menu->sel]);
3545         SaveActivationKey(machine, entry, menu_index[menu->sel]);
35853546      }
35863547      else if(AltKeyPressed())
35873548      {
35883549         /* alt + save : save pre-enable */
3589         SavePreEnable(machine, entry, menuIndex[menu->sel]);
3550         SavePreEnable(machine, entry, menu_index[menu->sel]);
35903551      }
35913552   }
35923553   else if(input_ui_pressed(machine, IPT_UI_ADD_CHEAT))
35933554   {
3594      AddCheatBefore(menuIndex[menu->sel]);
3555      add_cheat_before(menu_index[menu->sel]);
35953556   }
35963557   else if(input_ui_pressed(machine, IPT_UI_DELETE_CHEAT))
35973558   {
35983559      if(entry)
3599         DeleteCheatAt(menuIndex[menu->sel]);
3560         delete_cheat_at(menu_index[menu->sel]);
36003561      else
3601      {
3602         messageType      = kCheatMessage_FailedToDelete;
3603         messageTimer   = DEFAULT_MESSAGE_TIME;
3604      }
3562         SET_MESSAGE(kCheatMessage_FailedToDelete);
36053563   }
36063564   else if(input_ui_pressed(machine, IPT_UI_EDIT_CHEAT))
36073565   {
r2821r2822
36163574   }
36173575   else if(input_ui_pressed(machine, IPT_UI_RELOAD_CHEAT))
36183576   {
3619      ReloadCheatDatabase(machine);
3577      reload_cheat_database(machine);
36203578   }
36213579   else if(input_ui_pressed(machine, IPT_UI_CANCEL))
36223580   {
r2821r2822
36243582      menu->sel = -1;
36253583   }
36263584
3627   free(menuIndex);
3585   free(menu_index);
36283586
36293587   return menu->sel + 1;
36303588}
r2821r2822
36363594static int add_edit_cheat_menu(running_machine *machine, cheat_menu_stack *menu)
36373595{
36383596   int            i;
3639   UINT8         total         = 0;
3640   const char      ** menu_item;
3641   CheatEntry      * entry;
3597   UINT8         total = 0;
3598   const char      **menu_item;
3599   cheat_entry      *entry;
36423600
36433601   /* first setting : NONE */
36443602   if(menu->first_time)
36453603      menu->first_time = 0;
36463604
36473605   /* required items = total codes + return + terminator */
3648   request_strings(cheatListLength + 2, 0, 0, 0);
3606   request_strings(cheat_list_length + 2, 0, 0, 0);
36493607   menu_item = menu_strings.main_list;
36503608
36513609   /********** MENU CONSTRUCTION **********/
3652   for(i = 0; i < cheatListLength; i++)
3610   for(i = 0; i < cheat_list_length; i++)
36533611   {
3654      CheatEntry * traverse = &cheatList[i];
3612      cheat_entry *traverse = &cheat_list[i];
36553613
36563614      /* ##### NAME ##### */
36573615      if(traverse->name)
r2821r2822
36673625   menu_item[total] = NULL;
36683626
36693627   /* adjust cursor position */
3670   ADJUST_CURSOR(menu->sel, total)
3628   ADJUST_CURSOR(menu->sel, total);
36713629
36723630   /* draw it */
36733631   old_style_menu(menu_item, NULL, NULL, menu->sel, 0);
36743632
3633   /* set entry for selected item if valid, otherwise null (return item) */
36753634   if(menu->sel < total - 1)
3676      entry = &cheatList[menu->sel];
3635      entry = &cheat_list[menu->sel];
36773636   else
36783637      entry = NULL;
36793638
36803639   /********** KEY HANDLING **********/
36813640   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
36823641   {
3683      CURSOR_TO_PREVIOUS(menu->sel, total)
3642      CURSOR_TO_PREVIOUS(menu->sel, total);
36843643   }
36853644   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
36863645   {
3687      CURSOR_TO_NEXT(menu->sel, total)
3646      CURSOR_TO_NEXT(menu->sel, total);
36883647   }
36893648   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
36903649   {
3691      CURSOR_PAGE_UP(menu->sel)
3650      CURSOR_PAGE_UP(menu->sel);
36923651   }
36933652   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
36943653   {
3695      CURSOR_PAGE_DOWN(menu->sel, total)
3654      CURSOR_PAGE_DOWN(menu->sel, total);
36963655   }
36973656   else if(input_ui_pressed(machine, IPT_UI_SELECT))
36983657   {
r2821r2822
37103669   }
37113670   else if(input_ui_pressed(machine, IPT_UI_RELOAD_CHEAT))
37123671   {
3713      ReloadCheatDatabase(machine);
3672      reload_cheat_database(machine);
37143673   }
37153674   else if(input_ui_pressed(machine, IPT_UI_EDIT_CHEAT))
37163675   {
r2821r2822
37263685   }
37273686   else if(input_ui_pressed(machine, IPT_UI_ADD_CHEAT))
37283687   {
3729      AddCheatBefore(menu->sel);
3688      add_cheat_before(menu->sel);
37303689   }
37313690   else if(input_ui_pressed(machine, IPT_UI_DELETE_CHEAT))
37323691   {
3733      DeleteCheatAt(menu->sel);
3692      delete_cheat_at(menu->sel);
37343693   }
37353694   else if(input_ui_pressed(machine, IPT_UI_SAVE_CHEAT))
37363695   {
37373696      if(ShiftKeyPressed())
37383697      {
37393698         /* shift + save = save all codes */
3740         for(i = 0; i < cheatListLength; i++)
3741            SaveCheatCode(machine, &cheatList[i]);
3699         for(i = 0; i < cheat_list_length; i++)
3700            SaveCheatCode(machine, &cheat_list[i]);
37423701
3743         messageTimer   = DEFAULT_MESSAGE_TIME;
3744         messageType      = kCheatMessage_AllCheatSaved;
3702         SET_MESSAGE(kCheatMessage_AllCheatSaved);
37453703      }
37463704      else if(ControlKeyPressed())
37473705      {
r2821r2822
37973755   int            i;
37983756   UINT8         total = 0;
37993757   ui_menu_item   menu_item[kMenu_Max + 1];
3800   CheatEntry      *entry = &cheatList[menu->pre_sel];
3758   cheat_entry      *entry = &cheat_list[menu->pre_sel];
38013759
38023760   memset(menu_item, 0, sizeof(menu_item));
38033761
r2821r2822
38293787   menu_item[total].text = NULL;
38303788
38313789   /* adjust cursor position */
3832   ADJUST_CURSOR(menu->sel, total)
3790   ADJUST_CURSOR(menu->sel, total);
38333791
38343792   /* print it */
38353793   ui_menu_draw(menu_item, total, menu->sel, NULL);
r2821r2822
38373795   /********** KEY HANDLING **********/
38383796   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
38393797   {
3840      CURSOR_TO_PREVIOUS(menu->sel, total)
3798      CURSOR_TO_PREVIOUS(menu->sel, total);
38413799   }
38423800   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
38433801   {
3844      CURSOR_TO_NEXT(menu->sel, total)
3802      CURSOR_TO_NEXT(menu->sel, total);
38453803   }
38463804   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
38473805   {
3848      CURSOR_PAGE_UP(menu->sel)
3806      CURSOR_PAGE_UP(menu->sel);
38493807   }
38503808   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
38513809   {
3852      CURSOR_PAGE_DOWN(menu->sel, total)
3810      CURSOR_PAGE_DOWN(menu->sel, total);
38533811   }
38543812   else if(input_ui_pressed(machine, IPT_UI_SELECT))
38553813   {
r2821r2822
38633821            break;
38643822
38653823         case kMenu_ReloadDatabase:
3866            ReloadCheatDatabase(machine);
3824            reload_cheat_database(machine);
38673825            cheat_menu_stack_pop();
38683826            break;
38693827
r2821r2822
38853843
38863844         case kMenu_SaveAllCodes:
38873845            {
3888               for(i = 0; i < cheatListLength; i++)
3889                  SaveCheatCode(machine, &cheatList[i]);
3846               for(i = 0; i < cheat_list_length; i++)
3847                  SaveCheatCode(machine, &cheat_list[i]);
38903848
3891               messageTimer   = DEFAULT_MESSAGE_TIME;
3892               messageType      = kCheatMessage_AllCheatSaved;
3849               SET_MESSAGE(kCheatMessage_AllCheatSaved);
38933850            }
38943851            break;
38953852
38963853         case kMenu_AddCode:
3897            AddCheatBefore(menu->pre_sel);
3854            add_cheat_before(menu->pre_sel);
38983855            menu->sel = -1;
38993856            break;
39003857
39013858         case kMenu_DeleteCode:
3902            DeleteCheatAt(menu->pre_sel);
3859            delete_cheat_at(menu->pre_sel);
39033860            menu->sel = -1;
39043861            break;
39053862
39063863#ifdef MAME_DEBUG
39073864         case kMenu_ConvertFormat:
3908            if(!(entry->flags & kCheatFlag_OldFormat))
3865            if((entry->flags & kCheatFlag_OldFormat) == 0)
39093866            {
3910               for(i = 0; i < entry->actionListLength; i++)
3867               /* new -> old (UNDERCONSTRUCTION) */
3868               for(i = 0; i < entry->action_list_length; i++)
39113869               {
3912                  entry->actionList[i].flags |= kActionFlag_OldFormat;
3913                  UpdateCheatInfo(entry, 0);
3870                  entry->action_list[i].flags |= kActionFlag_OldFormat;
3871                  update_cheat_info(entry, 0);
39143872               }
39153873            }
39163874            else
39173875            {
3918               for(i = 0; i < entry->actionListLength; i++)
3876               /* old -> new (UNDERCONSTRUCTION) */
3877               for(i = 0; i < entry->action_list_length; i++)
39193878               {
3920                  entry->actionList[i].flags &= ~kActionFlag_OldFormat;
3921                  UpdateCheatInfo(entry, 0);
3879                  entry->action_list[i].flags &= ~kActionFlag_OldFormat;
3880                  update_cheat_info(entry, 0);
39223881               }
39233882            }
39243883            break;
r2821r2822
39343893   }
39353894   else if(input_ui_pressed(machine, IPT_UI_RELOAD_CHEAT))
39363895   {
3937      ReloadCheatDatabase(machine);
3896      reload_cheat_database(machine);
39383897   }
39393898   else if(input_ui_pressed(machine, IPT_UI_CANCEL) || input_ui_pressed(machine, IPT_UI_LEFT) || input_ui_pressed(machine, IPT_UI_RIGHT))
39403899   {
r2821r2822
48334792         break;
48344793
48354794         case kType_WatchSize:
4836            action->originalDataField = (action->originalDataField & 0xFFFFFF00) | ((action->originalDataField - 0x00000001) & 0x000000FF);
4837            action->data = action->originalDataField;
4795            action->originalData = (action->originalData & 0xFFFFFF00) | ((action->originalData - 0x00000001) & 0x000000FF);
4796            action->data = action->originalData;
48384797            break;
48394798
48404799         case kType_WatchSkip:
4841            action->originalDataField = (action->originalDataField & 0xFFFF00FF) | ((action->originalDataField - 0x00000100) & 0x0000FF00);
4842            action->data = action->originalDataField;
4800            action->original_data = (action->originalData & 0xFFFF00FF) | ((action->originalData - 0x00000100) & 0x0000FF00);
4801            action->data = action->originalData;
48434802            break;
48444803
48454804         case kType_WatchPerLine:
4846            action->originalDataField = (action->originalDataField & 0xFF00FFFF) | ((action->originalDataField - 0x00010000) & 0x00FF0000);
4847            action->data = action->originalDataField;
4805            action->originalData = (action->originalData & 0xFF00FFFF) | ((action->originalData - 0x00010000) & 0x00FF0000);
4806            action->data = action->originalData;
48484807            break;
48494808
48504809         case kType_WatchAddValue:
4851            action->originalDataField = (action->originalDataField & 0x00FFFFFF) | ((action->originalDataField - 0x01000000) & 0xFF000000);
4852            action->data = action->originalDataField;
4810            action->original_data = (action->originalData & 0x00FFFFFF) | ((action->originalData - 0x01000000) & 0xFF000000);
4811            action->data = action->originalData;
48534812            break;
48544813
48554814         case kType_WatchFormat:
r2821r2822
49124871            break;
49134872
49144873         case kType_Data:
4915            action->originalDataField -= 1;
4916            action->originalDataField &= info->extraData;
4917            action->data = action->originalDataField;
4874            action->originalData -= 1;
4875            action->originalData &= info->extraData;
4876            action->data = action->originalData;
49184877            break;
49194878
49204879         case kType_UserSelect:
r2821r2822
51335092         break;
51345093
51355094         case kType_WatchSize:
5136            action->originalDataField = (action->originalDataField & 0xFFFFFF00) | ((action->originalDataField + 0x00000001) & 0x000000FF);
5137            action->data = action->originalDataField;
5095            action->originalData = (action->originalData & 0xFFFFFF00) | ((action->originalData + 0x00000001) & 0x000000FF);
5096            action->data = action->originalData;
51385097            break;
51395098
51405099         case kType_WatchSkip:
5141            action->originalDataField = (action->originalDataField & 0xFFFF00FF) | ((action->originalDataField + 0x00000100) & 0x0000FF00);
5142            action->data = action->originalDataField;
5100            action->originalData = (action->originalData & 0xFFFF00FF) | ((action->originalData + 0x00000100) & 0x0000FF00);
5101            action->data = action->originalData;
51435102            break;
51445103
51455104         case kType_WatchPerLine:
5146            action->originalDataField = (action->originalDataField & 0xFF00FFFF) | ((action->originalDataField + 0x00010000) & 0x00FF0000);
5147            action->data = action->originalDataField;
5105            action->originalData = (action->originalData & 0xFF00FFFF) | ((action->originalData + 0x00010000) & 0x00FF0000);
5106            action->data = action->originalData;
51485107            break;
51495108
51505109         case kType_WatchAddValue:
5151            action->originalDataField = (action->originalDataField & 0x00FFFFFF) | ((action->originalDataField + 0x01000000) & 0xFF000000);
5152            action->data = action->originalDataField;
5110            action->originalData = (action->originalData & 0x00FFFFFF) | ((action->originalData + 0x01000000) & 0xFF000000);
5111            action->data = action->originalData;
51535112            break;
51545113
51555114         case kType_WatchFormat:
r2821r2822
52185177            break;
52195178
52205179         case kType_Data:
5221            action->originalDataField += 1;
5222            action->originalDataField &= info->extraData;
5223            action->data = action->originalDataField;
5180            action->originalData += 1;
5181            action->originalData &= info->extraData;
5182            action->data = action->originalData;
52245183            break;
52255184
52265185         case kType_UserSelect:
r2821r2822
54915450
54925451         case kType_WatchSize:
54935452         {
5494            UINT32 temp = (action->originalDataField >> 0) & 0xFF;
5453            UINT32 temp = (action->originalData >> 0) & 0xFF;
54955454
54965455            temp++;
54975456            temp = do_edit_hex_field(machine, temp) & 0xFF;
54985457            temp--;
54995458
5500            action->originalDataField = (action->originalDataField & 0xFFFFFF00) | ((temp << 0) & 0x000000FF);
5501            action->data = action->originalDataField;
5459            action->originalData = (action->originalData & 0xFFFFFF00) | ((temp << 0) & 0x000000FF);
5460            action->data = action->originalData;
55025461         }
55035462         break;
55045463
55055464         case kType_WatchSkip:
55065465         {
5507            UINT32 temp = (action->originalDataField >> 8) & 0xFF;
5466            UINT32 temp = (action->originalData >> 8) & 0xFF;
55085467
55095468            temp = do_edit_hex_field(machine, temp) & 0xFF;
55105469
5511            action->originalDataField = (action->originalDataField & 0xFFFF00FF) | ((temp << 8) & 0x0000FF00);
5512            action->data = action->originalDataField;
5470            action->originalData = (action->originalData & 0xFFFF00FF) | ((temp << 8) & 0x0000FF00);
5471            action->data = action->originalData;
55135472         }
55145473         break;
55155474
55165475         case kType_WatchPerLine:
55175476         {
5518            UINT32 temp = (action->originalDataField >> 16) & 0xFF;
5477            UINT32 temp = (action->originalData >> 16) & 0xFF;
55195478
55205479            temp = do_edit_hex_field(machine, temp) & 0xFF;
55215480
5522            action->originalDataField = (action->originalDataField & 0xFF00FFFF) | ((temp << 16) & 0x00FF0000);
5523            action->data = action->originalDataField;
5481            action->originalData = (action->originalData & 0xFF00FFFF) | ((temp << 16) & 0x00FF0000);
5482            action->data = action->originalData;
55245483         }
55255484         break;
55265485
55275486         case kType_WatchAddValue:
55285487         {
5529            UINT32 temp = (action->originalDataField >> 24) & 0xFF;
5488            UINT32 temp = (action->originalData >> 24) & 0xFF;
55305489
55315490            temp = DoEditHexFieldSigned(temp, 0xFFFFFF80) & 0xFF;
55325491
5533            action->originalDataField = (action->originalDataField & 0x00FFFFFF) | ((temp << 24) & 0xFF000000);
5534            action->data = action->originalDataField;
5492            action->originalData = (action->originalData & 0x00FFFFFF) | ((temp << 24) & 0xFF000000);
5493            action->data = action->originalData;
55355494         }
55365495         break;
55375496
r2821r2822
55885547         break;
55895548
55905549         case kType_Data:
5591            action->originalDataField = do_edit_hex_field(machine, action->originalDataField);
5592            action->originalDataField &= info->extraData;
5593            action->data = action->originalDataField;
5550            action->originalData = do_edit_hex_field(machine, action->originalData);
5551            action->originalData &= info->extraData;
5552            action->data = action->originalData;
55945553            break;
55955554
55965555         case kType_Address:
r2821r2822
56155574
56165575         entry->actionList[info->sub_cheat].extendData = ~0;
56175576
5618         for(i = 0; i < entry->actionListLength; i++)
5577         for(i = 0; i < entry->action_list_length; i++)
56195578         {
5620            CheatAction * action = &entry->actionList[i];
5579            cheat_action *action = &entry->action_list[i];
56215580
56225581            if(i)
56235582               SET_MASK_FIELD(action->type, LinkEnable);
r2821r2822
56305589         if(!info->sub_cheat)
56315590         {
56325591            /* don't delete MASTER Action due to crash */
5633            messageTimer = DEFAULT_MESSAGE_TIME;
5634            messageType = kCheatMessage_FailedToDelete;
5592            SET_MESSAGE(kCheatMessage_FailedToDelete);
56355593         }
56365594         else
56375595            DeleteActionAt(entry, info->sub_cheat);
r2821r2822
56515609      if(entry->flags & kCheatFlag_Select)
56525610         BuildLabelIndexTable(entry);
56535611
5654      CheckCodeFormat(entry);
5612      check_code_format(entry);
56555613
56565614      editActive = 0;
56575615      dirty = 1;
r2821r2822
56745632      "Program", "Data Space", "I/O Space", "Opcode RAM", "Mapped Memory", "Direct Memory", "EEPROM" };
56755633
56765634   static const char *const kCodeTypeNames[] = {
5677      "Write", "PDWWrite", "RWrite", "IWrite", "CWrite", "VWrite", "VRWrite", "Move", "Branch", "Loop",
5678      "Unused 1", "Unused 2", "Unused 3", "Unused 4",
5679      "Popup", "Watch" };
5635      "Write", "IWrite", "RWrite", "CWrite", "CBit", "PDWWrite", "Move", "Branch", "Loop", "Popup", "Watch" };
56805636
56815637   static const char *const kCustomCodeTypeNames[] = {
5682      "No Action", "Comment", "Separator", "Label Select", "Layer",
5638      "NOP", "Comment", "Separator", "Label Select", "Layer Tag",
56835639      "Unused 1", "Unused2", "Unused 3",
56845640      /* NOTE : the following command codes should be removed when database is loaded */
56855641      "Activation Key 1", "Activation Key 2", "Pre-enable", "Overclock", "Refresh Rate" };
56865642
5643   static const char *const kIWriteParameterNames[] = {
5644      "Write", "Bit Set", "Bit Clear", "Limited Mask" };
5645
5646   static const char *const kCBitParameterNames[] = {
5647      "Bit Set", "Bit Clear", "Limited Mask" };
5648
56875649   static const char *const kConditionNames[] = {
5688      "EQ", "NE", "LS", "LSEQ", "GR", "GREQ", "BSET", "BCLR",
5650      "Equal", "Not Equal", "Less", "Less or Equal", "Greater", "Greater or Equal", "Bit Set", "Bit Clear",
56895651      "Unused 1", "Unused 2", "Unused 3", "Unused 4",
5690      "PVAL", "KEY", "KEYR", "TRUE" };
5652      "Previous Value", "Key Pressed", "Key Hold", "TRUE" };
56915653
5654   static const char *const kCBitConditionNames[] = {
5655      "Bis Set", "Bit Clear" };
5656
56925657   static const char *const kDataNames[] = {
5693      "Data", "1st Data", "Data", "Data", "Data", "Max Data", "Max Data", "Add Value", "Comparison", "Count",
5694      "-----", "-----", "-----", "-----",
5695      "Comparison", "-----" };
5658      "Data", "Data", "Data", "Data", "Bit", "1st Data", "Add Value", "Jump Index", "-----", "-----", "-----" };
56965659
56975660   static const char *const kPopupOptionNames[] = {
56985661      "Label", "Value", "Label + Value", "Value + Label" };
56995662
57005663   enum{
5701      kViewMenu_Header = 1,                  // format : total index / current index
5702      kViewMenu_CodeLayer,                  // internal value of code and layer index
5703      kViewMenu_Name,                        // master code = entry->name, linked code = action->optionalName
5664      kViewMenu_Header = 1,                  /* format : [total index / current index] */
5665      kViewMenu_Layer,                     /* internal value of code and layer index */
5666      kViewMenu_Name,                        /* master code = entry->name, linked code = action->optionalName */
57045667         kViewMenu_Comment,
57055668         kViewMenu_ActivationKey1,
57065669         kViewMenu_ActivationKey2,
5707      // if(!CustomCode)
5708         kViewMenu_CodeType,                     // CodeType - CodeParameter / Return
5709         kViewMenu_CPURegion,                  // add Address Space if CPU region
5670      /* if(CustomCode == 0) */
5671         kViewMenu_CPURegion,               /* add address space if CPU region */
5672         kViewMenu_CodeType,
5673         /* if(CodeType == IWrite) */
5674            kViewMenu_IWriteParameter,
5675         /* if(CodeType == CWrite, CBit, Branch, Popup) */
5676            kViewMenu_Condition,
5677         /* if(CodeType == CBit) */
5678            kViewMenu_CBitParameter,
5679            kViewMenu_CBitCondition,
5680         /* if(CodeType == Watch) */
5681            kViewMenu_WatchParameter,
5682         /* if(CodeType == Popup) */
5683            kViewMenu_PopupParameter,
5684         /* if(CodeType == RWrite, CWrite, CBit, Branch, Popup */
5685            kViewMenu_Extend,
57105686         kViewMenu_Address,
5711         kViewMenu_Size,                        // address size / index size
5687         kViewMenu_AddressSize,
5688         /* if(CodeType == IWrite, Move) */
5689            kViewMenu_IndexOffset,
5690            kViewMenu_IndexAddressSize,
5691         /* if(CodeType == Move) */
5692            kViewMenu_MoveParameter,         /* variable 0-3 */
57125693         kViewMenu_Data,
5713         kViewMenu_Extend,
5714         // if(ValueSelect)
5694         /* if(LimitedMask) */
5695            kViewMenu_LimitedMask,            /* for IWrite, CBit */
5696         /* if(CodeType == PDWWRite) */
5697            kViewMenu_SubData,
5698            kViewMenu_SubDataSize,
5699         /* if(ValueSelect) */
57155700            kViewMenu_ValueSelectOptions,
5716         // if(Popup)
5717            kViewMenu_PopupOptions,
5718         // if(CopyLink)
5719            kViewMenu_CopyLinkOptions,
5720         kViewMenu_Options,                     // One-shot, Delay, Prefill, RestoreValue
5721      // if(CustomCode)
5722         //if(LayerIndex)
5701         kViewMenu_Options,                  /* One-shot, Delay, Return, Prefill, RestoreValue */
5702      /* if(CustomCode) */
5703         /* if(LayerIndex) */
57235704            kViewMenu_LayerDisplayLevel,
57245705            kViewMenu_LayerSetLevel,
57255706            kViewMenu_LayerSetLength,
r2821r2822
57295710   int            total = 0;
57305711   int            menu_index[kViewMenu_Max] = { 0 };
57315712   static int      page_index = 0;
5732   UINT8         address_length = 0;
5733   UINT8         address_size = 0;
5734   const char      ** menu_item;
5735   const char      ** menu_sub_item;
5736   char         * flag_buf;
5737   char         * header;
5738   char         * buf_code;
5739   char         * buf_type;
5740   char         * buf_cpu;
5741   char         * buf_address;
5742   char         * buf_size;
5743   char         * buf_data;
5744   char         * buf_extend;
5745   char         * buf_options;
5746   char         * buf_code_type_options;
5747   CheatEntry      * entry = &cheatList[menu->pre_sel];
5748   CheatAction      * action = NULL;
5749   astring         * activation_key_string1 = NULL;
5750   astring         * activation_key_string2 = NULL;
5713   INT8         code_type = 0;
5714   INT8         address_length = 0;
5715   INT8         address_size = 0;
5716   INT8         request_arrow = 0;
5717   const char      **menu_item;
5718   const char      **menu_sub_item;
5719   char         *flag_buf;
5720   char         *header;
5721   char         *buf_code;
5722   char         *buf_type;
5723   char         *buf_cpu;
5724   char         *buf_address;
5725   char         *buf_size;
5726   char         *buf_sub_size;
5727   char         *buf_data;
5728   char         *buf_extend;
5729   char         *buf_limited_mask;
5730   char         *buf_options;
5731   char         *buf_code_type_options;
5732   cheat_entry      *entry = &cheat_list[menu->pre_sel];
5733   cheat_action   *action = NULL;
5734   astring         *activation_key_string1 = NULL;
5735   astring         *activation_key_string2 = NULL;
57515736
57525737   /* first setting : forced set page as 0 when first open */
57535738   if(menu->first_time)
r2821r2822
57565741      menu->first_time = 0;
57575742   }
57585743
5759   action         = &entry->actionList[page_index];
5744   action         = &entry->action_list[page_index];
5745   code_type      = EXTRACT_FIELD(action->type, CodeType);
57605746   address_length   = get_address_length(action->region);
57615747   address_size   = EXTRACT_FIELD(action->type, AddressSize);
57625748
5763   /* required items = (total items + return + terminator) & (strings buf * 10) */
5764   request_strings(kViewMenu_Max + 2, 0x0A, 32, 0);
5749   /* required items = (total items + return + terminator) + (strings buf * 12) */
5750   request_strings(kViewMenu_Max + 2, 12, 32, 0);
57655751   menu_item            = menu_strings.main_list;
57665752   menu_sub_item         = menu_strings.sub_list;
57675753   flag_buf            = menu_strings.flag_list;
57685754   header               = menu_strings.main_strings[0];
57695755   buf_code            = menu_strings.main_strings[1];
5770   buf_type            = menu_strings.main_strings[2];
5756   buf_type            = menu_strings.main_strings[1];
57715757   buf_cpu               = menu_strings.main_strings[3];
57725758   buf_address            = menu_strings.main_strings[4];
57735759   buf_size            = menu_strings.main_strings[5];
5774   buf_data            = menu_strings.main_strings[6];
5775   buf_extend            = menu_strings.main_strings[7];
5776   buf_options            = menu_strings.main_strings[8];
5777   buf_code_type_options   = menu_strings.main_strings[9];
5760   buf_sub_size         = menu_strings.main_strings[6];
5761   buf_data            = menu_strings.main_strings[7];
5762   buf_extend            = menu_strings.main_strings[8];
5763   buf_limited_mask      = menu_strings.main_strings[9];
5764   buf_options            = menu_strings.main_strings[10];
5765   buf_code_type_options   = menu_strings.main_strings[11];
57785766
57795767   memset(flag_buf, 0, kViewMenu_Max + 2);
57805768
57815769   /********** MENU CONSTRUCTION **********/
57825770   /* ##### HEADER ##### */
5783   sprintf(header, "[%2.2d/%2.2d]", page_index + 1, entry->actionListLength);
5771   sprintf(header, "%2.2d/%2.2d", page_index + 1, entry->action_list_length);
57845772   ADD_MENU_3_ITEMS("Page", header, kViewMenu_Header);
57855773
5786   /* ##### CODE / LAYER INDEX ##### */
5787   sprintf(buf_code, "%8.8X / %2.2X", action->type, entry->layerIndex);
5788   ADD_MENU_3_ITEMS("Code / Layer", buf_code, kViewMenu_CodeLayer);
5774   /* ##### LAYER INDEX ##### */
5775   sprintf(buf_code, "%2.2X", entry->layer_index);
5776   ADD_MENU_3_ITEMS("Layer Index", buf_code, kViewMenu_Layer);
57895777
57905778   /* ##### NAME ##### */
57915779   if(entry->name)
57925780   {
5793      if(page_index)
5794         ADD_MENU_3_ITEMS("Name", action->optionalName, kViewMenu_Name);
5795      else
5796         ADD_MENU_3_ITEMS("Name", entry->name, kViewMenu_Name);
5781      /* NOTE : master code is from cheat entry and others are from cheat action */
5782      ADD_MENU_3_ITEMS("Name", page_index ? action->optional_name : entry->name, kViewMenu_Name);
57975783   }
57985784   else
57995785      ADD_MENU_3_ITEMS("Name", "< none >", kViewMenu_Name);
r2821r2822
58085794      if(entry->flags & kCheatFlag_HasActivationKey1)
58095795      {
58105796         activation_key_string1 = astring_alloc();
5811         ADD_MENU_3_ITEMS("Activation Key", astring_c(input_code_name(activation_key_string1, entry->activationKey1)), kViewMenu_ActivationKey1);
5797         ADD_MENU_3_ITEMS("Activation Key - Prev", astring_c(input_code_name(activation_key_string1, entry->activation_key1)), kViewMenu_ActivationKey1);
58125798      }
5799
5800      if(entry->flags & kCheatFlag_HasActivationKey2)
5801      {
5802         activation_key_string2 = astring_alloc();
5803         ADD_MENU_3_ITEMS("Activation Key - Next", astring_c(input_code_name(activation_key_string2, entry->activation_key2)), kViewMenu_ActivationKey2);
5804      }
58135805   }
58145806   else
58155807   {
58165808      if(entry->flags & kCheatFlag_HasActivationKey1)
58175809      {
58185810         activation_key_string1 = astring_alloc();
5819         ADD_MENU_3_ITEMS("Activation Key - Prev", astring_c(input_code_name(activation_key_string1, entry->activationKey1)), kViewMenu_ActivationKey1);
5811         ADD_MENU_3_ITEMS("Activation Key", astring_c(input_code_name(activation_key_string1, entry->activation_key1)), kViewMenu_ActivationKey1);
58205812      }
5813   }
58215814
5822      if(entry->flags & kCheatFlag_HasActivationKey2)
5815   /* ##### CPU/REGION ##### */
5816   if((action->flags & kActionFlag_Custom) == 0)
5817   {
5818      if(action->region < REGION_INVALID)
58235819      {
5824         activation_key_string2 = astring_alloc();
5825         ADD_MENU_3_ITEMS("Activation Key - Next", astring_c(input_code_name(activation_key_string2, entry->activationKey2)), kViewMenu_ActivationKey2);
5820         /* cpu region */
5821         sprintf(buf_cpu, "%s (%s)", kRegionNames[EXTRACT_FIELD(action->region, CPUIndex) + 1], kAddressSpaceNames[EXTRACT_FIELD(action->region, AddressSpace)]);
5822         ADD_MENU_3_ITEMS("CPU", buf_cpu, kViewMenu_CPURegion);
58265823      }
5824      else
5825         /* non-cpu region */
5826         ADD_MENU_3_ITEMS("Region", kRegionNames[action->region - REGION_INVALID], kViewMenu_CPURegion);
58275827   }
58285828
58295829   /* ##### CODE TYPE ##### */
r2821r2822
58335833   }
58345834   else
58355835   {
5836      char * type_strings = buf_type;
5836      ADD_MENU_3_ITEMS("Code Type", kCodeTypeNames[code_type], kViewMenu_CodeType);
5837   }
58375838
5838      type_strings += sprintf(type_strings, "%s", kCodeTypeNames[EXTRACT_FIELD(action->type, CodeType)]);
5839   if((action->flags & kActionFlag_Custom) == 0)
5840   {
5841      /* ##### CODE PARAMETER ##### */
5842      if(code_type == kCodeType_IWrite)
5843      {
5844         /* writing parameter */
5845         ADD_MENU_3_ITEMS("Parameter", kIWriteParameterNames[EXTRACT_FIELD(action->type, CodeParameterUpper)], kViewMenu_IWriteParameter);
5846      }
58395847
5848      if(code_type == kCodeType_RWrite)
5849      {
5850         /* repeat parameter */
5851         sprintf(buf_extend, "%4.4X / %4.4X",
5852                  EXTRACT_FIELD(action->extend_data, LSB16),
5853                  EXTRACT_FIELD(action->extend_data, MSB16));
5854         ADD_MENU_3_ITEMS("Count / Skip", buf_extend, kViewMenu_Extend);
5855      }
5856
58405857      if(action->flags & kActionFlag_CheckCondition)
5841         type_strings += sprintf(type_strings, "-%s", kConditionNames[EXTRACT_FIELD(action->type, CodeParameter)]);
5858      {
5859         if(code_type == kCodeType_CBit)
5860         {
5861            /* bit parameter for CBit */
5862            ADD_MENU_3_ITEMS("Parameter", kCBitParameterNames[EXTRACT_FIELD(action->type, CodeParameterUpper)], kViewMenu_CBitParameter);
58425863
5843      if(TEST_FIELD(action->type, Return))
5844         type_strings += sprintf(type_strings, "/Ret");
5864            /* bit condition for CBit */
5865            ADD_MENU_3_ITEMS("Condition", kCBitConditionNames[EXTRACT_FIELD(action->type, CodeParameterLower)], kViewMenu_CBitCondition);
58455866
5846      ADD_MENU_3_ITEMS("Type", buf_type, kViewMenu_CodeType);
5847   }
5867         }
5868         else
5869         {
5870            /* condition for CWrite, Branch, Popup */
5871            ADD_MENU_3_ITEMS("Condition", kConditionNames[EXTRACT_FIELD(action->type, CodeParameter)], kViewMenu_Condition);
5872         }
58485873
5849   if((action->flags & kActionFlag_Custom) == 0)
5850   {
5851      /* ##### CPU/REGION ##### */
5852      if(TEST_FIELD(action->region, RegionFlag))
5853      {
5854         ADD_MENU_3_ITEMS("Region", kRegionNames[EXTRACT_FIELD(action->region, RegionIndex)], kViewMenu_CPURegion);
5874         sprintf(buf_extend, "%*.*X", kCheatSizeDigitsTable[address_size], kCheatSizeDigitsTable[address_size], action->extend_data);
5875
5876         ADD_MENU_3_ITEMS("Comparison", buf_extend, kViewMenu_Extend);
58555877      }
5856      else
5878
5879      if(code_type == kCodeType_Popup)
58575880      {
5858         sprintf(buf_cpu, "%s (%s)", kRegionNames[EXTRACT_FIELD(action->region, CPUIndex) + 1], kAddressSpaceNames[EXTRACT_FIELD(action->region, AddressSpace)]);
5859         ADD_MENU_3_ITEMS("CPU", buf_cpu, kViewMenu_CPURegion);
5881         /* popup parameter */
5882         ADD_MENU_3_ITEMS("Parameter", kPopupOptionNames[EXTRACT_FIELD(action->type, PopupParameter)], kViewMenu_PopupParameter);
58605883      }
58615884
58625885      /* ##### ADDRESS ##### */
58635886      switch(EXTRACT_FIELD(action->type, AddressRead))
58645887      {
58655888         case kReadFrom_Address:
5866            sprintf(buf_address, "%*.*X", address_length, address_length, action->originalAddress);
5889            sprintf(buf_address, "%*.*X", address_length, address_length, action->original_address);
58675890            break;
58685891
58695892         case kReadFrom_Index:
5870            sprintf(buf_address, "(V%s)", kNumbersTable[action->originalAddress]);
5893            sprintf(buf_address, "(V%s)", kNumbersTable[action->original_address]);
58715894            break;
58725895
58735896         case kReadFrom_Variable:
5874            sprintf(buf_address, "V%s", kNumbersTable[action->originalAddress]);
5897            sprintf(buf_address, "V%s", kNumbersTable[action->original_address]);
58755898      }
58765899
58775900      ADD_MENU_3_ITEMS("Address", buf_address, kViewMenu_Address);
58785901
58795902      /* ##### SIZE ##### */
5880      if(action->flags & kActionFlag_PDWWrite)
5903      sprintf(buf_size, "%s", kByteSizeStringList[address_size]);
5904      ADD_MENU_3_ITEMS("Size", buf_size, kViewMenu_AddressSize);
5905
5906      /* ##### INDEX ##### */
5907      if(action->flags & kActionFlag_IndexAddress)
58815908      {
5882         sprintf(buf_size, "%s / %s", kByteSizeStringList[address_size], kByteSizeStringList[EXTRACT_FIELD(action->type, IndexSize)]);
5883         ADD_MENU_3_ITEMS("Size 1st / 2nd", buf_size, kViewMenu_Size);
5884      }
5885      else if(action->flags & kActionFlag_IndexAddress)
5886      {
5887         if(action->extendData != ~0)
5888         {
5889            sprintf(buf_size, "%s / %s", kByteSizeStringList[address_size], kByteSizeStringList[EXTRACT_FIELD(action->type, IndexSize)]);
5890         }
5891         else
5892            sprintf(buf_size, "%s / < None >", kByteSizeStringList[address_size]);
5909         /* index offset for IWrite, Move */
5910         sprintf(buf_extend, "%*.*X", address_length, address_length, action->extend_data);
5911         ADD_MENU_3_ITEMS("Index Offset", buf_extend, kViewMenu_IndexOffset);
58935912
5894         ADD_MENU_3_ITEMS("Size Adr / Idx", buf_size, kViewMenu_Size);
5913         /* index size for IWrite, Move */
5914         sprintf(buf_sub_size, "%s", kByteSizeStringList[EXTRACT_FIELD(action->type, CodeParameterLower)]);
5915         ADD_MENU_3_ITEMS("Index Size", buf_sub_size, kViewMenu_IndexAddressSize);
58955916      }
5896      else
5917
5918      /* ##### DESTINATION ##### */
5919      if(code_type == kCodeType_Move)
58975920      {
5898         sprintf(buf_size, "%s", kByteSizeStringList[address_size]);
5899         ADD_MENU_3_ITEMS("Size", buf_size, kViewMenu_Size);
5921         sprintf(buf_type, "%s", kNumbersTable[EXTRACT_FIELD(action->type, CodeParameterUpper)]);
5922         ADD_MENU_3_ITEMS("Destination", buf_type, kViewMenu_MoveParameter);
59005923      }
59015924
59025925      /* ##### DATA ##### */
5903      if(EXTRACT_FIELD(action->type, CodeType) != kCodeType_Watch)
5926      if(code_type != kCodeType_Watch)
59045927      {
5905         if(TEST_FIELD(action->type, DataRead))
5928         if(action->flags & kActionFlag_LimitedMask)
59065929         {
5907            sprintf(buf_data, "V%s", kNumbersTable[action->originalDataField]);
5930            /* NOTE : data is upper 2 bytes from data field in case of limite mask */
5931            if(TEST_FIELD(action->type, DataRead))
5932               sprintf(buf_data, "V%s", kNumbersTable[EXTRACT_FIELD(action->original_data, MSB16)]);
5933            else
5934               sprintf(buf_data, "%*.*X", kCheatSizeDigitsTable[address_size], kCheatSizeDigitsTable[address_size], EXTRACT_FIELD(action->original_data, MSB16));
59085935         }
59095936         else
59105937         {
5911            sprintf(buf_data, "%*.*X", kCheatSizeDigitsTable[address_size], kCheatSizeDigitsTable[address_size], action->originalDataField);
5938            if(TEST_FIELD(action->type, DataRead))
5939               sprintf(buf_data, "V%s", kNumbersTable[action->original_data]);
5940            else
5941               sprintf(buf_data, "%*.*X", kCheatSizeDigitsTable[address_size], kCheatSizeDigitsTable[address_size], action->original_data);
59125942         }
59135943
5914         if(EXTRACT_FIELD(action->type, Link) != kLink_CopyLink)
5915            ADD_MENU_3_ITEMS(kDataNames[EXTRACT_FIELD(action->type, CodeType)], buf_data, kViewMenu_Data);
5916         else
5917            ADD_MENU_3_ITEMS("Add Value", buf_data, kViewMenu_Data);
5944         ADD_MENU_3_ITEMS(kDataNames[EXTRACT_FIELD(action->type, CodeType)], buf_data, kViewMenu_Data);
59185945      }
59195946
5920      /* ##### EXTEND DATA ##### */
5921      if(action->flags & kActionFlag_IndexAddress)
5947      /* ##### MASK ##### */
5948      if(code_type == kCodeType_Write)
59225949      {
5923         if(action->extendData != ~0)
5924            sprintf(buf_extend, "%*.8X", address_length, action->extendData);
5925         else
5926            sprintf(buf_extend, "< none >");
5927
5928         ADD_MENU_3_ITEMS("Index", buf_extend, kViewMenu_Extend);
5950         sprintf(buf_extend, "%*.*X", address_size, address_size, action->extend_data);
5951         ADD_MENU_3_ITEMS("Mask", buf_extend, kViewMenu_Extend);
59295952      }
5930      else if(action->flags & kActionFlag_PDWWrite)
5953      else if(action->flags & kActionFlag_LimitedMask)
59315954      {
5955         /* NOTE : mask is lower 2 bytes from data field in case of limited mask */
5956         sprintf(buf_limited_mask, "%*.*X", address_size, address_size, EXTRACT_FIELD(action->original_data, LSB16));
5957         ADD_MENU_3_ITEMS("Mask", buf_limited_mask, kViewMenu_LimitedMask);
5958      }
5959
5960      /* ##### SUB DATA ##### */
5961      if(code_type == kCodeType_PDWWrite)
5962      {
5963         /* 2nd data */
59325964         sprintf(buf_extend, "%*.*X",
5933            kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, IndexSize)],
5934            kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, IndexSize)],
5935            action->extendData);
5965            kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, CodeParameterLower)],
5966            kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, CodeParameterLower)],
5967            action->extend_data);
59365968         ADD_MENU_3_ITEMS("2nd Data", buf_extend, kViewMenu_Extend);
5969
5970         /* 2nd data size */
5971         sprintf(buf_sub_size, "%s", kByteSizeStringList[EXTRACT_FIELD(action->type, CodeParameterLower)]);
5972         ADD_MENU_3_ITEMS("2nd Data Size", buf_sub_size, kViewMenu_SubDataSize);
59375973      }
5938      else if(action->flags & kActionFlag_Repeat)
5974
5975      /* ##### JUMP INDEX ##### */
5976      if(code_type == kCodeType_Branch)
59395977      {
5940         sprintf(buf_extend, "%4.4X / %4.4X",
5941                  EXTRACT_FIELD(action->extendData, LSB16),
5942                  EXTRACT_FIELD(action->extendData, MSB16));
5943         ADD_MENU_3_ITEMS("Count / Skip", buf_extend, kViewMenu_Extend);
5978         /* jump index for branch */
5979         sprintf(buf_extend, "%2.2d", action->extend_data + 1);
5980         ADD_MENU_3_ITEMS("Jump Index", buf_extend, kViewMenu_Extend);
59445981      }
5945      else
5946      {
5947         switch(EXTRACT_FIELD(action->type, CodeType))
5948         {
5949            case kCodeType_Write:
5950            case kCodeType_IWrite:
5951            case kCodeType_VWrite:
5952               sprintf(buf_extend, "%*.*X", address_size, address_size, action->extendData);
5953               ADD_MENU_3_ITEMS("Mask", buf_extend, kViewMenu_Extend);
5954               break;
59555982
5956            case kCodeType_CWrite:
5957               sprintf(buf_extend, "%*.*X", address_size, address_size, action->extendData);
5958               ADD_MENU_3_ITEMS("Comparison", buf_extend, kViewMenu_Extend);
5959               break;
5960
5961            case kCodeType_Branch:
5962               sprintf(buf_extend, "%2.2d", action->extendData + 1);
5963               ADD_MENU_3_ITEMS("Jump Index", buf_extend, kViewMenu_Extend);
5964               break;
5965
5966            default:
5967               ADD_MENU_3_ITEMS("UNKNOWN", "?????", kViewMenu_Extend);
5968         }
5969      }
5970
59715983      /* ##### OPTIONS ##### */
5972      sprintf(buf_options, "%s %s %s %s",
5973               TEST_FIELD(action->type, OneShot) ? "O" : "-",
5974               TEST_FIELD(action->type, DelayEnable) ? "D" : "-",
5975               TEST_FIELD(action->type, PrefillEnable) ? "P" : "-",
5976               TEST_FIELD(action->type, RestoreValue) ? "R" : "-");
5984      sprintf(buf_options, "%s %s %s %s %s",
5985               TEST_FIELD(action->type, OneShot) ? "One" : "-",
5986               TEST_FIELD(action->type, DelayEnable) ? "Del" : "-",
5987               TEST_FIELD(action->type, PrefillEnable) ? "Pre" : "-",
5988               TEST_FIELD(action->type, Return) ? "Ret" : "-",
5989               TEST_FIELD(action->type, RestoreValue) ? "Rst" : "-");
59775990      ADD_MENU_3_ITEMS("Options", buf_options, kViewMenu_Options);
59785991
59795992      /* ##### CODE TYPE OPTIONS ##### */
5980      if(   EXTRACT_FIELD(action->type, CodeType) == kCodeType_VWrite ||
5981         EXTRACT_FIELD(action->type, CodeType) == kCodeType_VRWrite)
5993      if(TEST_FIELD(action->type, ValueSelectEnable))
59825994      {
59835995         sprintf(buf_code_type_options, "%s %s %s %s",
5984                  TEST_FIELD(action->type, ValueSelectMinimumDisplay) ? "D" : "-",
5985                  TEST_FIELD(action->type, ValueSelectMinimum) ? "M" : "-",
5986                  TEST_FIELD(action->type, ValueSelectBCD) ? "B" : "-",
5987                  TEST_FIELD(action->type, ValueSelectNegative) ? "N" : "-");
5996                  TEST_FIELD(action->type, ValueSelectMinimumDisplay) ? "MinD" : "-",
5997                  TEST_FIELD(action->type, ValueSelectMinimum) ? "Min" : "-",
5998                  TEST_FIELD(action->type, ValueSelectBCD) ? "BCD" : "-",
5999                  TEST_FIELD(action->type, ValueSelectNegative) ? "Neg" : "-");
59886000         ADD_MENU_3_ITEMS("Value Select Options", buf_code_type_options, kViewMenu_ValueSelectOptions);
59896001      }
5990      else if(EXTRACT_FIELD(action->type, CodeType) == kCodeType_Popup)
5991      {
5992         ADD_MENU_3_ITEMS("Popup Options", kPopupOptionNames[EXTRACT_FIELD(action->type, PopupParameter)], kViewMenu_PopupOptions);
5993      }
5994      else if(EXTRACT_FIELD(action->type, Link) == kLink_CopyLink)
5995      {
5996         sprintf(buf_code_type_options, "%s %s",
5997                  TEST_FIELD(action->type, LinkValueSelectBCD) ? "B" : "-",
5998                  TEST_FIELD(action->type, LinkValueSelectNegative) ? "N" : "-");
5999         ADD_MENU_3_ITEMS("Copy Link Options", buf_code_type_options, kViewMenu_CopyLinkOptions);
6000      }
60016002   }
60026003   else
60036004   {
6004      if(EXTRACT_FIELD(action->type, CodeType) == kCustomCode_Layer)
6005      /* ##### CUSTOM CODE PARAMETER ##### */
6006      if(EXTRACT_FIELD(action->type, CodeType) == CUSTOM_CODE_LAYER_TAG)
60056007      {
6006         /* ##### LAYER ##### */
6007         sprintf(buf_address, "%2.2X", action->originalAddress);
6008         /* ##### LAYER TAG ##### */
6009         sprintf(buf_address, "%2.2X", action->original_address);
60086010         ADD_MENU_3_ITEMS("Display Level", buf_address, kViewMenu_LayerDisplayLevel);
60096011
6010         sprintf(buf_data, "%2.2X", action->originalDataField);
6012         sprintf(buf_data, "%2.2X", action->original_data);
60116013         ADD_MENU_3_ITEMS("Set Level", buf_data, kViewMenu_LayerSetLevel);
60126014
6013         sprintf(buf_extend, "%2.2X", action->extendData);
6015         sprintf(buf_extend, "%2.2X", action->extend_data);
60146016         ADD_MENU_3_ITEMS("Set Length", buf_extend, kViewMenu_LayerSetLength);
60156017      }
60166018   }
r2821r2822
60226024   TERMINATE_MENU_2_ITEMS;
60236025
60246026   /* adjust current cursor position */
6025   ADJUST_CURSOR(menu->sel, total)
6027   ADJUST_CURSOR(menu->sel, total);
60266028
6029   if(menu_index[menu->sel] == kViewMenu_Header)
6030   {
6031      if(entry->action_list_length > 1)
6032         request_arrow = 3;
6033   }
6034
60276035   /* draw it */
6028   old_style_menu(menu_item, menu_sub_item, flag_buf, menu->sel, 0);
6036   old_style_menu(menu_item, menu_sub_item, flag_buf, menu->sel, request_arrow);
60296037
60306038   /********** KEY HANDLING **********/
60316039   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
60326040   {
6033      CURSOR_TO_PREVIOUS(menu->sel, total)
6041      CURSOR_TO_PREVIOUS(menu->sel, total);
60346042   }
60356043   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
60366044   {
6037      CURSOR_TO_NEXT(menu->sel, total)
6045      CURSOR_TO_NEXT(menu->sel, total);
60386046   }
60396047   else if(ui_pressed_repeat_throttle(machine, IPT_UI_LEFT, kHorizontalSlowKeyRepeatRate))
60406048   {
60416049      if(--page_index < 0)
6042         page_index = entry->actionListLength - 1;
6050         page_index = entry->action_list_length - 1;
60436051   }
60446052   else if(ui_pressed_repeat_throttle(machine, IPT_UI_RIGHT, kHorizontalSlowKeyRepeatRate))
60456053   {
6046      if(++page_index > entry->actionListLength - 1)
6054      if(++page_index > entry->action_list_length - 1)
60476055         page_index = 0;
60486056   }
60496057   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
60506058   {
6051      CURSOR_PAGE_UP(menu->sel)
6059      CURSOR_PAGE_UP(menu->sel);
60526060   }
60536061   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
60546062   {
6055      CURSOR_PAGE_DOWN(menu->sel, total)
6063      CURSOR_PAGE_DOWN(menu->sel, total);
60566064   }
60576065   else if(input_ui_pressed(machine, IPT_UI_SELECT) || input_ui_pressed(machine, IPT_UI_CANCEL))
60586066   {
r2821r2822
60886096      "Missing Restore Previous Value flag",
60896097      "Missing label link code",
60906098      "Both Value and Label Select are defined",
6091      "Copy Link is defined though no value-select code",
60926099      "Invalid Data Field",
60936100      "Invalid Extend Data Field",
60946101      "Don't set Variable in this type",
60956102      "Value Select can't select any value",
6103      "Limited Mask is over length",
60966104      "RWrite doesn't have counter",
60976105      "Invalid Address Read",
60986106      "Invalid Variable in address field",
r2821r2822
61056113
61066114   int            i, j;
61076115   int            total         = 0;
6108   UINT8         isEdit         = 0;
6109   const char      ** menuItem;
6110   CheatEntry      * entry         = &cheatList[menu->pre_sel];
6116   UINT8         is_edit         = 0;
6117   const char      **menu_item;
6118   cheat_entry      *entry         = &cheat_list[menu->pre_sel];
61116119
61126120   /* first setting : NONE */
61136121   if(menu->first_time)
61146122      menu->first_time = 0;
61156123
61166124   /* required items = ((items + header + 2 separators) * total_actions) + edit + return + terminator) */
6117   request_strings(((kErrorFlag_Max + 3) * entry->actionListLength) + 3, 0, 0, 0);
6118   menuItem = menu_strings.main_list;
6125   request_strings(((kErrorFlag_Max + 3) * entry->action_list_length) + 3, 0, 0, 0);
6126   menu_item = menu_strings.main_list;
61196127
61206128   /********** MENU CONSTRUCTION **********/
6121   for(i = 0; i < entry->actionListLength; i++)
6129   for(i = 0; i < entry->action_list_length; i++)
61226130   {
6123      CheatAction * action = &entry->actionList[i];
6131      cheat_action *action = &entry->action_list[i];
61246132
61256133      UINT32 flags = AnalyseCodeFormat(entry, action);
61266134
6127      menuItem[total++] = action->optionalName ? action->optionalName : "(Null)";
6128      menuItem[total++] = MENU_SEPARATOR_ITEM;
6135      menu_item[total++] = action->optional_name ? action->optional_name : "(Null)";
6136      menu_item[total++] = MENU_SEPARATOR_ITEM;
61296137
61306138      if(flags)
61316139      {
61326140         for(j = 0; j < kErrorFlag_Max; j++)
61336141         {
61346142            if((flags >> j) & 1)
6135               menuItem[total++] = kAnalyseItemName[j];
6143               menu_item[total++] = kAnalyseItemName[j];
61366144         }
61376145      }
61386146      else
6139         menuItem[total++] = "No Problem";
6147         menu_item[total++] = "No Problem";
61406148
6141      menuItem[total++] = MENU_SEPARATOR_ITEM;
6149      menu_item[total++] = MENU_SEPARATOR_ITEM;
61426150   }
61436151
6144   menuItem[total++] = "Edit This Entry";
6145   menuItem[total++] = "Return to Prior Menu";
6146   menuItem[total] = NULL;
6152   menu_item[total++] = "Edit This Entry";
6153   menu_item[total++] = "Return to Prior Menu";
6154   menu_item[total] = NULL;
61476155
61486156   /* adjust cursor position */
6149   ADJUST_CURSOR(menu->sel, total)
6157   ADJUST_CURSOR(menu->sel, total);
61506158
6151   old_style_menu(menuItem, NULL, NULL, menu->sel, 0);
6159   old_style_menu(menu_item, NULL, NULL, menu->sel, 0);
61526160
61536161   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
61546162   {
6155      CURSOR_TO_PREVIOUS(menu->sel, total)
6163      CURSOR_TO_PREVIOUS(menu->sel, total);
61566164   }
61576165   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
61586166   {
6159      CURSOR_TO_NEXT(menu->sel, total)
6167      CURSOR_TO_NEXT(menu->sel, total);
61606168   }
61616169   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
61626170   {
6163      CURSOR_PAGE_UP(menu->sel)
6171      CURSOR_PAGE_UP(menu->sel);
61646172   }
61656173   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
61666174   {
6167      CURSOR_PAGE_DOWN(menu->sel, total)
6175      CURSOR_PAGE_DOWN(menu->sel, total);
61686176   }
61696177   else if(input_ui_pressed(machine, IPT_UI_EDIT_CHEAT))
61706178   {
6171      isEdit = 1;
6179      is_edit = 1;
61726180   }
61736181   else if(input_ui_pressed(machine, IPT_UI_SELECT))
61746182   {
61756183      if(menu->sel == total - 2)
6176         isEdit = 1;
6184         is_edit = 1;
61776185      else
61786186         menu->sel = -1;
61796187   }
r2821r2822
61826190      menu->sel = -1;
61836191   }
61846192
6185   if(isEdit)
6193   if(is_edit)
61866194   {
61876195      if(entry->flags & kCheatFlag_OldFormat)
61886196         cheat_menu_stack_push(edit_cheat_menu, menu->return_handler, menu->pre_sel);
r2821r2822
64466454      }
64476455      else
64486456      {
6449         CURSOR_TO_PREVIOUS(menu->sel, total)
6457         CURSOR_TO_PREVIOUS(menu->sel, total);
64506458
64516459         if(menu->sel == kMenu_Divider1 || menu->sel == kMenu_Divider2)
64526460         {
r2821r2822
64846492      }
64856493      else
64866494      {
6487         CURSOR_TO_NEXT(menu->sel, total)
6495         CURSOR_TO_NEXT(menu->sel, total);
64886496
64896497         if(menu->sel == kMenu_Divider1 || menu->sel == kMenu_Divider2)
64906498            menu->sel++;
r2821r2822
65846592   }
65856593   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
65866594   {
6587      CURSOR_PAGE_UP(menu->sel)
6595      CURSOR_PAGE_UP(menu->sel);
65886596   }
65896597   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
65906598   {
6591      CURSOR_PAGE_DOWN(menu->sel, total)
6599      CURSOR_PAGE_DOWN(menu->sel, total);
65926600   }
65936601   else if(input_ui_pressed(machine, IPT_UI_SELECT))
65946602   {
r2821r2822
66856693               else
66866694               {
66876695                  /* if no search region (eg, sms.c in HazeMD), don't open result viewer to avoid the crash */
6688                  messageTimer =   DEFAULT_MESSAGE_TIME;
6689                  messageType =   kCheatMessage_NoSearchRegion;
6696                  SET_MESSAGE(kCheatMessage_NoSearchRegion);
66906697               }
66916698               break;
66926699
r2821r2822
67406747      update_search(search);
67416748
67426749      if(doneSaveMemory || menu->sel == kMenu_Value)
6743         messageType = kCheatMessage_CheatFound;
6750         SET_MESSAGE(kCheatMessage_CheatFound);
67446751      else
6745         messageType = kCheatMessage_InitializeMemory;
6752         SET_MESSAGE(kCheatMessage_InitializeMemory);
67466753
6747      messageTimer = DEFAULT_MESSAGE_TIME;
6748
67496754      doneSaveMemory = 1;
67506755
67516756      if(search->num_results == 1)
67526757      {
67536758         AddCheatFromFirstResult(search);
67546759
6755         messageType = kCheatMessage_1CheatFound;
6760         SET_MESSAGE(kCheatMessage_1CheatFound);
67566761      }
67576762   }
67586763
r2821r2822
69916996   menuSubItem[total] = NULL;
69926997
69936998   /* adjust current cursor position */
6994   ADJUST_CURSOR(menu->sel, total)
6999   ADJUST_CURSOR(menu->sel, total);
69957000
69967001   /* draw it */
69977002   old_style_menu(menuItem, menuSubItem, 0, menu->sel, 0);
r2821r2822
70187023      }
70197024      else
70207025      {
7021         CURSOR_TO_PREVIOUS(menu->sel, total)
7026         CURSOR_TO_PREVIOUS(menu->sel, total);
70227027
70237028         if(menu->sel == kMenu_Separator) menu->sel--;
70247029      }
r2821r2822
70447049      }
70457050      else
70467051      {
7047         CURSOR_TO_NEXT(menu->sel, total)
7052         CURSOR_TO_NEXT(menu->sel, total);
70487053
70497054         if(menu->sel == kMenu_Separator) menu->sel++;
70507055      }
r2821r2822
70527057   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
70537058   {
70547059      if(!editActive)
7055         CURSOR_PAGE_UP(menu->sel)
7060         CURSOR_PAGE_UP(menu->sel);
70567061   }
70577062   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
70587063   {
70597064      if(!editActive)
7060         CURSOR_PAGE_DOWN(menu->sel, total)
7065         CURSOR_PAGE_DOWN(menu->sel, total);
70617066   }
70627067   else if(ui_pressed_repeat_throttle(machine, IPT_UI_LEFT, kHorizontalFastKeyRepeatRate))
70637068   {
r2821r2822
74057410   else
74067411      sprintf(valueBuffer, "%.*X", kSearchByteDigitsTable[search->bytes], search->value & kSearchByteMaskTable[search->bytes]);
74077412
7408   if(TEST_FIELD(cheatOptions, DontPrintNewLabels))
7413   if(TEST_FIELD(cheat_options, DontPrintNewLabels))
74097414   {
74107415      menu_item[total] = kOperandNameTable[search->lhs];
74117416      menu_subitem[total++] = NULL;
r2821r2822
77887793      "User Defined"
77897794   };
77907795
7791   int            total      = 0;
7792   UINT8         doRebuild   = 0;
7793   const char      ** menuItem;
7794   const char      ** menuSubItem;
7796   int            total         = 0;
7797   UINT8         do_rebuild      = 0;
7798   UINT8         do_reallocate   = 0;
7799   const char      **menu_item;
7800   const char      **menu_sub_item;
77957801   search_info      *search = get_current_search();
77967802   search_region   *region;
77977803
r2821r2822
78007806      menu->first_time = 0;
78017807
78027808   /* required items = speed + total regions + return + terminator */
7803   request_strings(search->region_list_length + 3, 0, 0, 0);
7804   menuItem   = menu_strings.main_list;
7805   menuSubItem   = menu_strings.sub_list;
7809   request_strings(search->region_list_length + 4, 0, 0, 0);
7810   menu_item      = menu_strings.main_list;
7811   menu_sub_item   = menu_strings.sub_list;
78067812
78077813   /********** MENU CONSTRUCTION **********/
78087814   /* ##### SEARCH SPEED ##### */
7809   menuItem[total] = "Search Speed";
7810   menuSubItem[total++] = ksearch_speedList[search->search_speed];
7815   menu_item[total] = "Search Speed";
7816   menu_sub_item[total++] = ksearch_speedList[search->search_speed];
78117817
78127818   /* ##### REGIONS ##### */
78137819   if(search->region_list_length)
r2821r2822
78187824      {
78197825         search_region *region = &search->region_list[i];
78207826
7821         menuItem[total] = region->name;
7822         menuSubItem[total++] = region->flags & kRegionFlag_Enabled ? "On" : "Off";
7827         menu_item[total] = region->name;
7828
7829         if(region->flags & kRegionFlag_HasError)
7830            menu_sub_item[total++] = "Locked";
7831         else
7832            menu_sub_item[total++] = region->flags & kRegionFlag_Enabled ? "On" : "Off";
78237833      }
78247834   }
78257835   else
78267836   {
7827      /* in case of no SearchRegion */
7828      menuItem[total] = "No Search Region";
7829      menuSubItem[total++] = NULL;
7837
7838      /* in case of no search region */
7839      menu_item[total] = "No Search Region";
7840      menu_sub_item[total++] = NULL;
78307841   }
78317842
78327843   /* ##### RETURN ##### */
7833   menuItem[total] = "Return to Prior Menu";
7834   menuSubItem[total++] = NULL;
7844   menu_item[total] = "Return to Prior Menu";
7845   menu_sub_item[total++] = NULL;
78357846
78367847   /* ##### TERMINATE ARRAY ##### */
7837   menuItem[total] = NULL;
7838   menuSubItem[total] = NULL;
7848   menu_item[total] = NULL;
7849   menu_sub_item[total] = NULL;
78397850
78407851   /* adjust current cursor position */
7841   ADJUST_CURSOR(menu->sel, total)
7852   ADJUST_CURSOR(menu->sel, total);
78427853
78437854   /* draw it */
7844   old_style_menu(menuItem, menuSubItem, NULL, menu->sel, 0);
7855   old_style_menu(menu_item, menu_sub_item, NULL, menu->sel, 0);
78457856
7846   if(search->region_list_length && menu->sel && menu->sel < total -1)
7857   if(search->region_list_length && menu->sel && menu->sel < total - 1)
7858   {
78477859      region = &search->region_list[menu->sel - 1];
7860
7861      if(region->flags & kRegionFlag_HasError)
7862         region = NULL;
7863   }
78487864   else
78497865      region = NULL;
78507866
78517867   /********** KEY HANDLING **********/
78527868   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
78537869   {
7854      CURSOR_TO_PREVIOUS(menu->sel, total)
7870      CURSOR_TO_PREVIOUS(menu->sel, total);
78557871   }
78567872   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
78577873   {
7858      CURSOR_TO_NEXT(menu->sel, total)
7874      CURSOR_TO_NEXT(menu->sel, total);
78597875   }
78607876   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
78617877   {
7862      CURSOR_PAGE_UP(menu->sel)
7878      CURSOR_PAGE_UP(menu->sel);
78637879   }
78647880   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
78657881   {
7866      CURSOR_PAGE_DOWN(menu->sel, total)
7882      CURSOR_PAGE_DOWN(menu->sel, total);
78677883   }
78687884   else if(ui_pressed_repeat_throttle(machine, IPT_UI_LEFT, kHorizontalSlowKeyRepeatRate))
78697885   {
r2821r2822
78717887      {
78727888         /* toggle ON/OFF */
78737889         region->flags ^= kRegionFlag_Enabled;
7890
7891         do_reallocate = 1;
78747892      }
7875      else if(!menu->sel)
7893      else if(menu->sel == 0)
78767894      {
78777895         if(--search->search_speed < 0)
78787896            /* "Fast" -> "User Defined" */
7879            search->search_speed = ksearch_speed_Max - 1;
7897            search->search_speed = SEARCH_SPEED_MAX - 1;
78807898
7881         doRebuild = 1;
7899         do_rebuild = 1;
7900         do_reallocate = 1;
78827901      }
78837902   }
78847903   else if(ui_pressed_repeat_throttle(machine, IPT_UI_RIGHT, kHorizontalSlowKeyRepeatRate))
r2821r2822
78877906      {
78887907         /* toggle ON/OFF */
78897908         region->flags ^= kRegionFlag_Enabled;
7909
7910         do_reallocate = 1;
78907911      }
7891      else if(!menu->sel)
7912      else if(menu->sel == 0)
78927913      {
7893         if(++search->search_speed >= ksearch_speed_Max)
7914         if(++search->search_speed >= SEARCH_SPEED_MAX)
78947915            /* "User Defined" -> "Fast" */
7895            search->search_speed = ksearch_speed_Fast;
7916            search->search_speed = SEARCH_SPEED_FAST;
78967917
7897         doRebuild = 1;
7918         do_rebuild = 1;
7919         do_reallocate = 1;
78987920      }
78997921   }
79007922   else if(input_ui_pressed(machine, IPT_UI_DELETE_CHEAT))
r2821r2822
79037925      {
79047926         /* SHIFT + CHEAT DELETE = invalidate selected region */
79057927         invalidate_entire_region(search, region);
7906//          ui_popup_time(1, "region invalidated - %d results remain", search->num_results);
79077928      }
79087929   }
79097930   else if(input_ui_pressed(machine, IPT_UI_RELOAD_CHEAT))
79107931   {
7911      if(search->search_speed == ksearch_speed_UserDefined)
7932      if(search->search_speed == SEARCH_SPEED_USER_DEFINED)
79127933      /* reload user region */
7913         doRebuild = 1;
7934         do_rebuild = 1;
7935         do_reallocate = 1;
79147936   }
79157937   else if(input_ui_pressed(machine, IPT_UI_SELECT))
79167938   {
79177939      if(region)
7940      {
79187941         region->flags ^= kRegionFlag_Enabled;
7919      else if(!menu->sel)
7920         doRebuild = 1;
7921      else
7942         do_reallocate = 1;
7943      }
7944      else if(menu->sel == 0)
7945      {
7946         do_rebuild = 1;
7947         do_reallocate = 1;
7948      }
7949      else if(menu->sel == total - 1)
79227950         menu->sel = -1;
79237951   }
79247952   else if(input_ui_pressed(machine, IPT_UI_CANCEL))
79257953      menu->sel = -1;
79267954
79277955   /********** REBUILD SEARCH REGION **********/
7928   if(doRebuild)
7956   if(do_rebuild)
79297957   {
7930      if(search->search_speed != ksearch_speed_UserDefined)
7931         /* rebuild SearchRegion from memory map */
7958      if(search->search_speed != SEARCH_SPEED_USER_DEFINED)
7959         /* rebuild search region from memory map */
79327960         build_search_regions(machine, search);
79337961      else
7934         /* rebuild SearchRegion from user-defined map */
7935         LoadCheatDatabase(machine, kLoadFlag_UserRegion);
7962         /* rebuild search region from user-defined map */
7963         load_cheat_database(machine, kLoadFlag_UserRegion);
7964   }
79367965
7937      /* reallocate SearchRegions */
7966   if(do_reallocate)
7967      /* reallocate search region */
79387968      allocate_search_regions(search);
7939   }
79407969
79417970   return menu->sel + 1;
79427971}
r2821r2822
82348263         search->num_results--;
82358264         region->num_results--;
82368265
8237         messageType = kCheatMessage_SucceededToDelete;
8238         messageTimer = DEFAULT_MESSAGE_TIME;
8266         SET_MESSAGE(kCheatMessage_SucceededToDelete);
82398267      }
82408268   }
82418269   else if(input_ui_pressed(machine, IPT_UI_WATCH_VALUE))
r2821r2822
83298357   const char      ** menuItem;
83308358   char         ** buf;
83318359   char         * stringsBuf;   // "USER20 FFFFFFFF (99:32 Bit)"    27 chars
8332   WatchInfo      * watch;
8360   watch_info      *watch;
83338361
83348362   /* first setting : NONE */
83358363   if(menu->first_time)
83368364      menu->first_time = 0;
83378365
83388366   /* required items = (total watchpoints + return + terminator) & (strings buf * total watchpoints [max chars = 32]) */
8339   request_strings(watchListLength + 2, watchListLength, 32, 0);
8367   request_strings(watch_list_length + 2, watch_list_length, 32, 0);
83408368   menuItem   = menu_strings.main_list;
83418369   buf         = menu_strings.main_strings;
83428370
83438371   /********** MENU CONSTRUCTION **********/
8344   for(i = 0; i < watchListLength; i++)
8372   for(i = 0; i < watch_list_length; i++)
83458373   {
8346      WatchInfo   * traverse   = &watchList[i];
8347      cpu_region_info *info = get_cpu_or_region_info(traverse->cpu);
8374      watch_info      *traverse   = &watch_list[i];
8375      cpu_region_info   *info      = get_cpu_or_region_info(traverse->cpu);
83488376
83498377      /* FORMAT : "CPU/Region : Address (Length : Bytes)" */
83508378      if(!editActive || menu->sel != i)
r2821r2822
83538381            get_region_name(traverse->cpu),
83548382            info->address_chars_needed,
83558383            traverse->address,
8356            traverse->numElements,
8357            kByteSizeStringList[traverse->elementBytes]);
8384            traverse->num_elements,
8385            kByteSizeStringList[traverse->element_bytes]);
83588386      }
83598387      else
83608388      {
r2821r2822
83798407                     stringsBuf += sprintf(stringsBuf, "%X", (traverse->address & kIncrementMaskTable[digits]) / kIncrementValueTable[digits]);
83808408               }
83818409
8382               stringsBuf += sprintf(stringsBuf, " (%d:%s)", traverse->numElements, kByteSizeStringList[traverse->elementBytes]);
8410               stringsBuf += sprintf(stringsBuf, " (%d:%s)", traverse->num_elements, kByteSizeStringList[traverse->element_bytes]);
83838411            }
83848412            break;
83858413
r2821r2822
83888416                  get_region_name(traverse->cpu),
83898417                  info->address_chars_needed,
83908418                  traverse->address,
8391                  traverse->numElements,
8392                  kByteSizeStringList[traverse->elementBytes]);
8419                  traverse->num_elements,
8420                  kByteSizeStringList[traverse->element_bytes]);
83938421               break;
83948422
83958423            case 0:
r2821r2822
83978425                  get_region_name(traverse->cpu),
83988426                  info->address_chars_needed,
83998427                  traverse->address,
8400                  traverse->numElements,
8401                  kByteSizeStringList[traverse->elementBytes]);
8428                  traverse->num_elements,
8429                  kByteSizeStringList[traverse->element_bytes]);
84028430               break;
84038431         }
84048432      }
r2821r2822
84148442   menuItem[total] = NULL;
84158443
84168444   /* adjust current cursor position */
8417   ADJUST_CURSOR(menu->sel, total)
8445   ADJUST_CURSOR(menu->sel, total);
84188446
84198447   /* draw it */
84208448   old_style_menu(menuItem, NULL, NULL, menu->sel, 0);
84218449
8422   if(menu->sel < watchListLength)
8423      watch = &watchList[menu->sel];
8450   if(menu->sel < watch_list_length)
8451      watch = &watch_list[menu->sel];
84248452   else
84258453      watch = NULL;
84268454
r2821r2822
84298457   {
84308458      if(!editActive)
84318459      {
8432         CURSOR_TO_PREVIOUS(menu->sel, total)
8460         CURSOR_TO_PREVIOUS(menu->sel, total);
84338461      }
84348462      else
84358463      {
r2821r2822
84408468               break;
84418469
84428470            case 1:
8443               if(watch->numElements < 99)
8444                  watch->numElements++;
8471               if(watch->num_elements < 99)
8472                  watch->num_elements++;
84458473               break;
84468474
84478475            case 0:
8448               watch->elementBytes = (watch->elementBytes + 1) & 0x03;
8476               watch->element_bytes = (watch->element_bytes + 1) & 0x03;
84498477               break;
84508478         }
84518479      }
r2821r2822
84548482   {
84558483      if(!editActive)
84568484      {
8457         CURSOR_TO_NEXT(menu->sel, total)
8485         CURSOR_TO_NEXT(menu->sel, total);
84588486      }
84598487      else
84608488      {
r2821r2822
84658493               break;
84668494
84678495            case 1:
8468               if(watch->numElements > 0)
8469                  watch->numElements--;
8496               if(watch->num_elements > 0)
8497                  watch->num_elements--;
84708498               break;
84718499
84728500            case 0:
8473               watch->elementBytes = (watch->elementBytes - 1) & 0x03;
8501               watch->element_bytes = (watch->element_bytes - 1) & 0x03;
84748502               break;
84758503         }
84768504      }
r2821r2822
84788506   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
84798507   {
84808508      if(!editActive)
8481         CURSOR_PAGE_UP(menu->sel)
8509         CURSOR_PAGE_UP(menu->sel);
84828510   }
84838511   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
84848512   {
84858513      if(!editActive)
8486         CURSOR_PAGE_DOWN(menu->sel, total)
8514         CURSOR_PAGE_DOWN(menu->sel, total);
84878515   }
84888516   else if(ui_pressed_repeat_throttle(machine, IPT_UI_LEFT, kVerticalKeyRepeatRate))
84898517   {
r2821r2822
85228550      if(!editActive && watch)
85238551      {
85248552         if(ShiftKeyPressed())
8525            AddCheatFromWatch(watch);
8553            add_cheat_from_watch(watch);
85268554         else if(ControlKeyPressed())
85278555         {
8528            CheatEntry * entry = GetNewCheat();
8556            cheat_entry *entry = get_new_cheat();
85298557
8530            DisposeCheat(entry);
8531            SetupCheatFromWatchAsWatch(entry, watch);
8558            add_cheat_from_watch_as_watch(entry, watch);
85328559
85338560            /* when fails to add, delete this entry because it causes the crash */
8534            if(messageType == kCheatMessage_FailedToAdd)
8561            if(message_type == kCheatMessage_FailedToAdd)
85358562            {
8536               DeleteCheatAt(cheatListLength - 1);
8537               messageType      = kCheatMessage_FailedToAdd;
8538               messageTimer   = DEFAULT_MESSAGE_TIME;
8563               delete_cheat_at(cheat_list_length - 1);
8564               SET_MESSAGE(kCheatMessage_FailedToAdd);
85398565            }
85408566         }
85418567         else
8542            AddWatchBefore(menu->sel);
8568            add_watch_before(menu->sel);
85438569      }
85448570   }
85458571   else if(input_ui_pressed(machine, IPT_UI_DELETE_CHEAT))
r2821r2822
85488574      {
85498575         if(ShiftKeyPressed())
85508576         {
8551            DeleteWatchAt(menu->sel);
8577            delete_watch_at(menu->sel);
85528578         }
85538579         else if(ControlKeyPressed())
85548580         {
8555            for(i = 0; i < watchListLength; i++)
8556               watchList[i].numElements = 0;
8581            for(i = 0; i < watch_list_length; i++)
8582               watch_list[i].num_elements = 0;
85578583         }
85588584         else
85598585         {
85608586            if(watch)
8561               watch->numElements = 0;
8587               watch->num_elements = 0;
85628588         }
85638589      }
85648590      else if(editActive)
r2821r2822
85708596               break;
85718597
85728598            case 1:
8573               watch->numElements = 0;
8599               watch->num_elements = 0;
85748600               break;
85758601
85768602            case 0:
8577               watch->elementBytes = 0;
8603               watch->element_bytes = 0;
85788604         }
85798605      }
85808606   }
r2821r2822
85828608   {
85838609      if(!editActive && watch)
85848610      {
8585         CheatEntry entry;
8611         cheat_entry entry;
85868612
8587         memset(&entry, 0, sizeof(CheatEntry));
8613         memset(&entry, 0, sizeof(cheat_entry));
85888614
8589         SetupCheatFromWatchAsWatch(&entry, watch);
8615         add_cheat_from_watch_as_watch(&entry, watch);
85908616         SaveCheatCode(machine, &entry);
8591         DisposeCheat(&entry);
8617         dispose_cheat(&entry);
85928618      }
85938619   }
85948620   else if(input_ui_pressed(machine, IPT_UI_EDIT_CHEAT))
r2821r2822
86058631      {
86068632         if(ShiftKeyPressed())
86078633         {
8608            if(watch)
8609               ResetWatch(watch);
8634            reset_watch(watch);
86108635         }
86118636         else
86128637         {
8613            for(i = 0; i < watchListLength; i++)
8614               ResetWatch(&watchList[i]);
8638            for(i = 0; i < watch_list_length; i++)
8639               reset_watch(&watch_list[i]);
86158640         }
86168641      }
86178642      else
86188643      {
86198644         watch->address = 0;
8620         watch->numElements = 0;
8621         watch->elementBytes = 0;
8645         watch->num_elements = 0;
8646         watch->element_bytes = 0;
86228647      }
86238648   }
86248649   else if(input_ui_pressed(machine, IPT_UI_CANCEL))
r2821r2822
86568681   int            i;
86578682   UINT8         total   = 0;
86588683   ui_menu_item   menuItem[kMenu_Max + 1];
8659   WatchInfo      * entry   = &watchList[menu->pre_sel];
8684   watch_info      *entry   = &watch_list[menu->pre_sel];
86608685
86618686   /* first setting : NONE */
86628687   if(menu->first_time)
r2821r2822
86808705   menuItem[total].text = NULL;
86818706
86828707   /* adjust current cursor position */
8683   ADJUST_CURSOR(menu->sel, total)
8708   ADJUST_CURSOR(menu->sel, total);
86848709
86858710   /* print it */
86868711   ui_menu_draw(menuItem, total, menu->sel, NULL);
r2821r2822
86888713   /********** KEY HANDLING **********/
86898714   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
86908715   {
8691      CURSOR_TO_PREVIOUS(menu->sel, total)
8716      CURSOR_TO_PREVIOUS(menu->sel, total);
86928717   }
86938718   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
86948719   {
8695      CURSOR_TO_NEXT(menu->sel, total)
8720      CURSOR_TO_NEXT(menu->sel, total);
86968721   }
86978722   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
86988723   {
8699      CURSOR_PAGE_UP(menu->sel)
8724      CURSOR_PAGE_UP(menu->sel);
87008725   }
87018726   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
87028727   {
8703      CURSOR_PAGE_DOWN(menu->sel, total)
8728      CURSOR_PAGE_DOWN(menu->sel, total);
87048729   }
87058730   else if(input_ui_pressed(machine, IPT_UI_SELECT))
87068731   {
r2821r2822
87118736            break;
87128737
87138738         case kMenu_DisableWatch:
8714            entry->numElements = 0;
8739            entry->num_elements = 0;
87158740            break;
87168741
87178742         case kMenu_DisableAllWatch:
8718            for(i = 0; i < watchListLength; i++)
8719               watchList[i].numElements = 0;
8743            for(i = 0; i < watch_list_length; i++)
8744               watch_list[i].num_elements = 0;
87208745            break;
87218746
87228747         case kMenu_ResetWatch:
8723            ResetWatch(entry);
8748            reset_watch(entry);
87248749            break;
87258750
87268751         case kMenu_ResetAllWatch:
8727            for(i = 0; i < watchListLength; i++)
8728               ResetWatch(&watchList[i]);
8752            for(i = 0; i < watch_list_length; i++)
8753               reset_watch(&watch_list[i]);
87298754            break;
87308755
87318756         case kMenu_AddAsCheatCode:
8732            AddCheatFromWatch(entry);
8757            add_cheat_from_watch(entry);
87338758            break;
87348759
87358760         case kMenu_AddAsWatchCode:
87368761         {
8737            CheatEntry * newEntry = GetNewCheat();
8762            cheat_entry *new_entry = get_new_cheat();
87388763
8739            DisposeCheat(newEntry);
8740            SetupCheatFromWatchAsWatch(newEntry, entry);
8764            add_cheat_from_watch_as_watch(new_entry, entry);
87418765
87428766            /* when fails to add, delete this entry because it causes the crash */
8743            if(messageType == kCheatMessage_FailedToAdd)
8767            if(message_type == kCheatMessage_FailedToAdd)
87448768            {
8745               DeleteCheatAt(cheatListLength - 1);
8746               messageType      = kCheatMessage_FailedToAdd;
8747               messageTimer   = DEFAULT_MESSAGE_TIME;
8769               delete_cheat_at(cheat_list_length - 1);
8770               SET_MESSAGE(kCheatMessage_FailedToAdd);
87488771            }
87498772         }
87508773         break;
r2821r2822
87558778
87568779         case kMenu_SaveAsWatchCode:
87578780         {
8758            CheatEntry tempEntry;
8781            cheat_entry temp_entry;
87598782
8760            memset(&tempEntry, 0, sizeof(CheatEntry));
8783            memset(&temp_entry, 0, sizeof(cheat_entry));
87618784
8762            SetupCheatFromWatchAsWatch(&tempEntry, entry);
8763            SaveCheatCode(machine, &tempEntry);
8764            DisposeCheat(&tempEntry);
8785            add_cheat_from_watch_as_watch(&temp_entry, entry);
8786            SaveCheatCode(machine, &temp_entry);
8787            dispose_cheat(&temp_entry);
87658788         }
87668789         break;
87678790
r2821r2822
87718794   }
87728795   else if(input_ui_pressed(machine, IPT_UI_RELOAD_CHEAT))
87738796   {
8774      ReloadCheatDatabase(machine);
8797      reload_cheat_database(machine);
87758798   }
87768799   else if(input_ui_pressed(machine, IPT_UI_CANCEL) || input_ui_pressed(machine, IPT_UI_LEFT) || input_ui_pressed(machine, IPT_UI_RIGHT))
87778800   {
r2821r2822
88138836   const char      ** menuSubItem;
88148837   char         ** buf;
88158838   char         * flagBuf;
8816   WatchInfo      * entry      = &watchList[menu->pre_sel];
8817   cpu_region_info *info = get_cpu_or_region_info(entry->cpu);
8839   watch_info      *entry      = &watch_list[menu->pre_sel];
8840   cpu_region_info *info      = get_cpu_or_region_info(entry->cpu);
88188841
88198842   /* first setting : NONE */
88208843   if(menu->first_time)
r2821r2822
88308853
88318854   /********** MENU CONSTRUCTION **********/
88328855   /* ##### ADDRESS ##### */
8833   sprintf(buf[total], "%.*X", info->address_chars_needed, entry->address >> entry->addressShift);
8856   sprintf(buf[total], "%.*X", info->address_chars_needed, entry->address >> entry->address_shift);
88348857   menuItem[total] = "Address";
88358858   menuSubItem[total] = buf[total];
88368859   total++;
88378860
88388861   /* ##### CPU/REGION ##### */
88398862   sprintf(buf[total], "%s", get_region_name(entry->cpu));
8840   menuItem[total] = TEST_FIELD(entry->cpu, RegionFlag) ? "Region" : "CPU";
8863   menuItem[total] = entry->cpu < REGION_INVALID ? "CPU" : "Region";
88418864   menuSubItem[total] = buf[total];
88428865   total++;
88438866
88448867   /* ##### LENGTH ##### */
8845   sprintf(buf[total], "%d", entry->numElements);
8868   sprintf(buf[total], "%d", entry->num_elements);
88468869   menuItem[total] = "Length";
88478870   menuSubItem[total] = buf[total];
88488871   total++;
88498872
88508873   /* ##### ELEMENT SIZE ##### */
88518874   menuItem[total] = "Element Size";
8852   menuSubItem[total++] = kByteSizeStringList[entry->elementBytes];
8875   menuSubItem[total++] = kByteSizeStringList[entry->element_bytes];
88538876
88548877   /* ##### LABEL TYPE ##### */
88558878   menuItem[total] = "Label Type";
8856   menuSubItem[total++] = kWatchLabelStringList[entry->labelType];
8879   menuSubItem[total++] = kWatchLabelStringList[entry->label_type];
88578880
88588881   /* ##### TEXT LABEL ##### */
88598882   menuItem[total] = "Text Label";
r2821r2822
88648887
88658888   /* ##### DISPLAY TYPE ##### */
88668889   menuItem[total] = "Display Type";
8867   menuSubItem[total++] = kWatchDisplayTypeStringList[entry->displayType];
8890   menuSubItem[total++] = kWatchDisplayTypeStringList[entry->display_type];
88688891
88698892   /* ##### X POSITION ##### */
88708893   sprintf(buf[total], "%f", entry->x);
r2821r2822
88858908   total++;
88868909
88878910   /* ##### ELEMENTS PER LINE ##### */
8888   sprintf(buf[total], "%d", entry->elementsPerLine);
8911   sprintf(buf[total], "%d", entry->elements_per_line);
88898912   menuItem[total] = "Elements Per Line";
88908913   menuSubItem[total] = buf[total];
88918914   total++;
88928915
88938916   /* ##### ADD VALUE ##### */
88948917   menuItem[total] = "Add Value";
8895   if(entry->addValue < 0)
8896      sprintf(buf[total], "-%.2X", -entry->addValue);
8918   if(entry->add_value < 0)
8919      sprintf(buf[total], "-%.2X", -entry->add_value);
88978920   else
8898      sprintf(buf[total], "%.2X", entry->addValue);
8921      sprintf(buf[total], "%.2X", entry->add_value);
88998922   menuSubItem[total] = buf[total];
89008923   total++;
89018924
89028925   /* ##### ADDRESS SHIFT ##### */
8903   sprintf(buf[total], "%d", entry->addressShift);
8926   sprintf(buf[total], "%d", entry->address_shift);
89048927   menuItem[total] = "Address Shift";
89058928   menuSubItem[total] = buf[total];
89068929   total++;
89078930
89088931   /* ##### DATA SHIFT ##### */
8909   sprintf(buf[total], "%d", entry->dataShift);
8932   sprintf(buf[total], "%d", entry->data_shift);
89108933   menuItem[total] = "Data Shift";
89118934   menuSubItem[total] = buf[total];
89128935   total++;
89138936
89148937   /* ##### XOR ##### */
8915   sprintf(buf[total], "%.*X", kSearchByteDigitsTable[kWatchSizeConversionTable[entry->elementBytes]], entry->xor);
8938   sprintf(buf[total], "%.*X", kSearchByteDigitsTable[kWatchSizeConversionTable[entry->element_bytes]], entry->xor);
89168939   menuItem[total] = "XOR";
89178940   menuSubItem[total] = buf[total];
89188941   total++;
r2821r2822
89268949   menuSubItem[total] = NULL;
89278950
89288951   /* adjust current cursor position */
8929   ADJUST_CURSOR(menu->sel, total)
8952   ADJUST_CURSOR(menu->sel, total);
89308953
89318954   /* higlighted sub-item if edit mode */
89328955   if(editActive)
r2821r2822
89388961   /********** KEY HANDLING **********/
89398962   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
89408963   {
8941      CURSOR_TO_PREVIOUS(menu->sel, total)
8964      CURSOR_TO_PREVIOUS(menu->sel, total);
89428965   }
89438966   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
89448967   {
8945      CURSOR_TO_NEXT(menu->sel, total)
8968      CURSOR_TO_NEXT(menu->sel, total);
89468969   }
89478970   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
89488971   {
8949      CURSOR_PAGE_UP(menu->sel)
8972      CURSOR_PAGE_UP(menu->sel);
89508973   }
89518974   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
89528975   {
8953      CURSOR_PAGE_DOWN(menu->sel, total)
8976      CURSOR_PAGE_DOWN(menu->sel, total);
89548977   }
89558978   else if(ui_pressed_repeat_throttle(machine, IPT_UI_LEFT, kHorizontalSlowKeyRepeatRate))
89568979   {
r2821r2822
89638986         switch(menu->sel)
89648987         {
89658988            case kMenu_Address:
8966               entry->address = DoShift(entry->address, entry->addressShift);
8989               entry->address = DoShift(entry->address, entry->address_shift);
89678990               entry->address -= increment;
8968               entry->address = DoShift(entry->address, -entry->addressShift);
8991               entry->address = DoShift(entry->address, -entry->address_shift);
89698992
8970               if(!TEST_FIELD(entry->cpu, RegionFlag))
8993               if(entry->cpu < REGION_INVALID)
89718994                  entry->address &= info->address_mask;
89728995               break;
89738996
r2821r2822
89819004               break;
89829005
89839006            case kMenu_NumElements:
8984               if(entry->numElements > 0)
8985                  entry->numElements--;
9007               if(entry->num_elements > 0)
9008                  entry->num_elements--;
89869009               else
8987                  entry->numElements = 0;
9010                  entry->num_elements = 0;
89889011               break;
89899012
89909013            case kMenu_ElementSize:
8991               if(entry->elementBytes > 0)
8992                  entry->elementBytes--;
9014               if(entry->element_bytes > 0)
9015                  entry->element_bytes--;
89939016               else
8994                  entry->elementBytes = 0;
9017                  entry->element_bytes = 0;
89959018
8996               entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->elementBytes]];
9019               entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->element_bytes]];
89979020               break;
89989021
89999022            case kMenu_LabelType:
9000               if(entry->labelType > 0)
9001                  entry->labelType--;
9023               if(entry->label_type > 0)
9024                  entry->label_type--;
90029025               else
9003                  entry->labelType = 0;
9026                  entry->label_type = 0;
90049027               break;
90059028
90069029            case kMenu_TextLabel:
90079030               break;
90089031
90099032            case kMenu_DisplayType:
9010               if(entry->displayType > 0)
9011                  entry->displayType--;
9033               if(entry->display_type > 0)
9034                  entry->display_type--;
90129035               else
9013                  entry->displayType = 0;
9036                  entry->display_type = 0;
90149037               break;
90159038
90169039            case kMenu_XPosition:
r2821r2822
90279050               break;
90289051
90299052            case kMenu_ElementsPerLine:
9030               if(entry->elementsPerLine > 0)
9031                  entry->elementsPerLine--;
9053               if(entry->elements_per_line > 0)
9054                  entry->elements_per_line--;
90329055               break;
90339056
90349057            case kMenu_AddValue:
9035               entry->addValue = (entry->addValue - 1) & 0xFF;
9058               entry->add_value = (entry->add_value - 1) & 0xFF;
90369059               break;
90379060
90389061            case kMenu_AddressShift:
9039               if(entry->addressShift > -31)
9040                  entry->addressShift--;
9062               if(entry->address_shift > -31)
9063                  entry->address_shift--;
90419064               else
9042                  entry->addressShift = 31;
9065                  entry->address_shift = 31;
90439066               break;
90449067
90459068            case kMenu_DataShift:
9046               if(entry->dataShift > -31)
9047                  entry->dataShift--;
9069               if(entry->data_shift > -31)
9070                  entry->data_shift--;
90489071               else
9049                  entry->dataShift = 31;
9072                  entry->data_shift = 31;
90509073               break;
90519074
90529075            case kMenu_XOR:
90539076               entry->xor -= increment;
9054               entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->elementBytes]];
9077               entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->element_bytes]];
90559078         }
90569079      }
90579080   }
r2821r2822
90669089         switch(menu->sel)
90679090         {
90689091            case kMenu_Address:
9069               entry->address = DoShift(entry->address, entry->addressShift);
9092               entry->address = DoShift(entry->address, entry->address_shift);
90709093               entry->address += increment;
9071               entry->address = DoShift(entry->address, -entry->addressShift);
9094               entry->address = DoShift(entry->address, -entry->address_shift);
90729095
9073               if(!TEST_FIELD(entry->cpu, RegionFlag))
9096               if(entry->cpu < REGION_INVALID)
90749097                  entry->address &= info->address_mask;
90759098               break;
90769099
r2821r2822
90849107               break;
90859108
90869109            case kMenu_NumElements:
9087               entry->numElements++;
9110               entry->num_elements++;
90889111               break;
90899112
90909113            case kMenu_ElementSize:
9091               if(entry->elementBytes < kSearchSize_32Bit)
9092                  entry->elementBytes++;
9114               if(entry->element_bytes < kSearchSize_32Bit)
9115                  entry->element_bytes++;
90939116               else
9094                  entry->elementBytes = kSearchSize_32Bit;
9117                  entry->element_bytes = kSearchSize_32Bit;
90959118
9096               entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->elementBytes]];
9119               entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->element_bytes]];
90979120               break;
90989121
90999122            case kMenu_LabelType:
9100               if(entry->labelType < kWatchLabel_MaxPlusOne - 1)
9101                  entry->labelType++;
9123               if(entry->label_type < kWatchLabel_MaxPlusOne - 1)
9124                  entry->label_type++;
91029125               else
9103                  entry->labelType = kWatchLabel_MaxPlusOne - 1;
9126                  entry->label_type = kWatchLabel_MaxPlusOne - 1;
91049127               break;
91059128
91069129            case kMenu_TextLabel:
91079130               break;
91089131
91099132            case kMenu_DisplayType:
9110               if(entry->displayType < kWatchDisplayType_MaxPlusOne - 1)
9111                  entry->displayType++;
9133               if(entry->display_type < kWatchDisplayType_MaxPlusOne - 1)
9134                  entry->display_type++;
91129135               else
9113                  entry->displayType = kWatchDisplayType_MaxPlusOne - 1;
9136                  entry->display_type = kWatchDisplayType_MaxPlusOne - 1;
91149137               break;
91159138
91169139            case kMenu_XPosition:
r2821r2822
91269149               break;
91279150
91289151            case kMenu_ElementsPerLine:
9129               entry->elementsPerLine++;
9152               entry->elements_per_line++;
91309153               break;
91319154
91329155            case kMenu_AddValue:
9133               entry->addValue = (entry->addValue + 1) & 0xFF;
9156               entry->add_value = (entry->add_value + 1) & 0xFF;
91349157               break;
91359158
91369159            case kMenu_AddressShift:
9137               if(entry->addressShift < 31)
9138                  entry->addressShift++;
9160               if(entry->address_shift < 31)
9161                  entry->address_shift++;
91399162               else
9140                  entry->addressShift = -31;
9163                  entry->address_shift = -31;
91419164               break;
91429165
91439166            case kMenu_DataShift:
9144               if(entry->dataShift < 31)
9145                  entry->dataShift++;
9167               if(entry->data_shift < 31)
9168                  entry->data_shift++;
91469169               else
9147                  entry->dataShift = -31;
9170                  entry->data_shift = -31;
91489171               break;
91499172
91509173            case kMenu_XOR:
91519174               entry->xor += increment;
9152               entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->elementBytes]];
9175               entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->element_bytes]];
91539176         }
91549177      }
91559178   }
r2821r2822
91829205   }
91839206   else if(input_ui_pressed(machine, IPT_UI_CLEAR))
91849207   {
9185      ResetWatch(entry);
9208      reset_watch(entry);
91869209   }
91879210   else if(input_ui_pressed(machine, IPT_UI_CANCEL))
91889211   {
r2821r2822
91979220      switch(menu->sel)
91989221      {
91999222         case kMenu_Address:
9200            entry->address = DoShift(entry->address, entry->addressShift);
9223            entry->address = DoShift(entry->address, entry->address_shift);
92019224            entry->address = do_edit_hex_field(machine, entry->address);
9202            entry->address = DoShift(entry->address, -entry->addressShift);
9225            entry->address = DoShift(entry->address, -entry->address_shift);
92039226            entry->address &= info->address_mask;
92049227            break;
92059228
r2821r2822
92099232            break;
92109233
92119234         case kMenu_NumElements:
9212            entry->numElements = DoEditDecField(entry->numElements, 0, 99);
9235            entry->num_elements = DoEditDecField(entry->num_elements, 0, 99);
92139236            break;
92149237
92159238         case kMenu_TextLabel:
r2821r2822
92259248            break;
92269249
92279250         case kMenu_AddValue:
9228            entry->addValue = DoEditHexFieldSigned(entry->addValue, 0xFFFFFF80) & 0xFF;
9251            entry->add_value = DoEditHexFieldSigned(entry->add_value, 0xFFFFFF80) & 0xFF;
92299252            break;
92309253
92319254         case kMenu_AddressShift:
9232            entry->addressShift = DoEditDecField(entry->addressShift, -31, 31);
9255            entry->address_shift = DoEditDecField(entry->address_shift, -31, 31);
92339256            break;
92349257
92359258         case kMenu_DataShift:
9236            entry->dataShift = DoEditDecField(entry->dataShift, -31, 31);
9259            entry->data_shift = DoEditDecField(entry->data_shift, -31, 31);
92379260            break;
92389261
92399262         case kMenu_XOR:
92409263            entry->xor = do_edit_hex_field(machine, entry->xor);
9241            entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->elementBytes]];
9264            entry->xor &= kSearchByteMaskTable[kWatchSizeConversionTable[entry->element_bytes]];
92429265            break;
92439266      }
92449267   }
92459268   else
92469269   {
92479270      if(input_ui_pressed(machine, IPT_UI_ADD_CHEAT))
9248         AddCheatFromWatch(entry);
9271         add_cheat_from_watch(entry);
92499272
92509273      if(input_ui_pressed(machine, IPT_UI_DELETE_CHEAT))
9251         entry->numElements = 0;
9274         entry->num_elements = 0;
92529275
92539276      if(input_ui_pressed(machine, IPT_UI_SAVE_CHEAT))
92549277      {
9255         CheatEntry tempEntry;
9278         cheat_entry temp_entry;
92569279
9257         memset(&tempEntry, 0, sizeof(CheatEntry));
9280         memset(&temp_entry, 0, sizeof(cheat_entry));
92589281
9259         SetupCheatFromWatchAsWatch(&tempEntry, entry);
9260         SaveCheatCode(machine, &tempEntry);
9261         DisposeCheat(&tempEntry);
9282         add_cheat_from_watch_as_watch(&temp_entry, entry);
9283         SaveCheatCode(machine, &temp_entry);
9284         dispose_cheat(&temp_entry);
92629285      }
92639286   }
92649287
r2821r2822
92739296{
92749297   enum{
92759298      kMenu_SelectSearch = 0,
9276      kMenu_LoadCheatOptions,
9277      kMenu_SaveCheatOptions,
9278      kMenu_ResetCheatOptions,
9299      kMenu_Loadcheat_options,
9300      kMenu_Savecheat_options,
9301      kMenu_Resetcheat_options,
92799302      kMenu_Separator,
92809303      kMenu_SearchDialogStyle,
92819304      kMenu_ShowSearchLabels,
r2821r2822
93159338
93169339   /* ##### SEARCH MENU ##### */
93179340   menu_item[total] = "Search Dialog Style";
9318   switch(EXTRACT_FIELD(cheatOptions, SearchBox))
9341   switch(EXTRACT_FIELD(cheat_options, SearchBox))
93199342   {
93209343      case kSearchBox_Minimum:
93219344         menu_sub_item[total++] = "Minimum";
r2821r2822
93359358   }
93369359
93379360   /* ##### SEARCH LABEL ##### */
9338   ADD_MENU_2_ITEMS("Show Search Labels", TEST_FIELD(cheatOptions, DontPrintNewLabels) ? "Off" : "On");
9361   ADD_MENU_2_ITEMS("Show Search Labels", TEST_FIELD(cheat_options, DontPrintNewLabels) ? "Off" : "On");
93399362
93409363   /* ##### AUTO SAVE ##### */
9341   ADD_MENU_2_ITEMS("Auto Save Cheats", TEST_FIELD(cheatOptions, AutoSaveEnabled) ? "On" : "Off");
9364   ADD_MENU_2_ITEMS("Auto Save Cheats", TEST_FIELD(cheat_options, AutoSaveEnabled) ? "On" : "Off");
93429365
93439366   /* ##### ACTIVATION KEY MESSAGE ##### */
9344   ADD_MENU_2_ITEMS("Show Activation Key Message", TEST_FIELD(cheatOptions, ActivationKeyMessage) ? "On" : "Off");
9367   ADD_MENU_2_ITEMS("Show Activation Key Message", TEST_FIELD(cheat_options, ActivationKeyMessage) ? "On" : "Off");
93459368
93469369   /* ##### OLD FORMAT LOADING ##### */
9347   ADD_MENU_2_ITEMS("Load Old Format Code", TEST_FIELD(cheatOptions, LoadOldFormat) ? "On" : "Off");
9370   ADD_MENU_2_ITEMS("Load Old Format Code", TEST_FIELD(cheat_options, LoadOldFormat) ? "On" : "Off");
93489371
93499372#ifdef MESS
93509373   /* ##### SHARED CODE ##### */
9351   ADD_MENU_2_ITEMS("Shared Code", TEST_FIELD(cheatOptions, SharedCode) ? "On" : "Off");
9374   ADD_MENU_2_ITEMS("Shared Code", TEST_FIELD(cheat_options, SharedCode) ? "On" : "Off");
93529375#endif
93539376
93549377   /* ##### RETURN ##### */
r2821r2822
93639386   /********** KEY HANDLING **********/
93649387   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
93659388   {
9366      CURSOR_TO_PREVIOUS(menu->sel, total)
9389      CURSOR_TO_PREVIOUS(menu->sel, total);
93679390
93689391      if(menu->sel == kMenu_Separator)
93699392         menu->sel--;
93709393   }
93719394   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
93729395   {
9373      CURSOR_TO_NEXT(menu->sel, total)
9396      CURSOR_TO_NEXT(menu->sel, total);
93749397
93759398      if(menu->sel == kMenu_Separator)
93769399         menu->sel++;
93779400   }
93789401   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
93799402   {
9380      CURSOR_PAGE_UP(menu->sel)
9403      CURSOR_PAGE_UP(menu->sel);
93819404   }
93829405   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
93839406   {
9384      CURSOR_PAGE_DOWN(menu->sel, total)
9407      CURSOR_PAGE_DOWN(menu->sel, total);
93859408   }
93869409   else if(ui_pressed_repeat_throttle(machine, IPT_UI_LEFT, kHorizontalSlowKeyRepeatRate))
93879410   {
r2821r2822
93899412      {
93909413         case kMenu_SearchDialogStyle:
93919414         {
9392            UINT8 length = (EXTRACT_FIELD(cheatOptions, SearchBox) - 1) & 3;
9415            UINT8 length = (EXTRACT_FIELD(cheat_options, SearchBox) - 1) & 3;
93939416
93949417            if(length > kSearchBox_Advanced)
93959418               length = kSearchBox_Advanced;
93969419
9397            SET_FIELD(cheatOptions, SearchBox, length);
9420            SET_FIELD(cheat_options, SearchBox, length);
93989421         }
93999422         break;
94009423
94019424         case kMenu_ShowSearchLabels:
9402            TOGGLE_MASK_FIELD(cheatOptions, DontPrintNewLabels);
9425            TOGGLE_MASK_FIELD(cheat_options, DontPrintNewLabels);
94039426            break;
94049427
94059428         case kMenu_AutoSaveCheats:
9406            TOGGLE_MASK_FIELD(cheatOptions, AutoSaveEnabled);
9429            TOGGLE_MASK_FIELD(cheat_options, AutoSaveEnabled);
94079430            break;
94089431
94099432         case kMenu_ShowActivationKeyMessage:
9410            TOGGLE_MASK_FIELD(cheatOptions, ActivationKeyMessage);
9433            TOGGLE_MASK_FIELD(cheat_options, ActivationKeyMessage);
94119434            break;
94129435
94139436         case kMenu_LoadOldFormat:
9414            TOGGLE_MASK_FIELD(cheatOptions, LoadOldFormat);
9437            TOGGLE_MASK_FIELD(cheat_options, LoadOldFormat);
94159438            break;
94169439#ifdef MESS
94179440         case kMenu_SharedCode:
9418            TOGGLE_MASK_FIELD(cheatOptions, SharedCode);
9441            TOGGLE_MASK_FIELD(cheat_options, SharedCode);
94199442#endif
94209443      }
94219444   }
r2821r2822
94259448      {
94269449         case kMenu_SearchDialogStyle:
94279450         {
9428            UINT8 length = (EXTRACT_FIELD(cheatOptions, SearchBox) + 1) & 3;
9451            UINT8 length = (EXTRACT_FIELD(cheat_options, SearchBox) + 1) & 3;
94299452
94309453            if(length > kSearchBox_Advanced)
94319454               length = kSearchBox_Minimum;
94329455
9433            SET_FIELD(cheatOptions, SearchBox, length);
9456            SET_FIELD(cheat_options, SearchBox, length);
94349457         }
94359458         break;
94369459
94379460         case kMenu_ShowSearchLabels:
9438            TOGGLE_MASK_FIELD(cheatOptions, DontPrintNewLabels);
9461            TOGGLE_MASK_FIELD(cheat_options, DontPrintNewLabels);
94399462            break;
94409463
94419464         case kMenu_AutoSaveCheats:
9442            TOGGLE_MASK_FIELD(cheatOptions, AutoSaveEnabled);
9465            TOGGLE_MASK_FIELD(cheat_options, AutoSaveEnabled);
94439466            break;
94449467
94459468         case kMenu_ShowActivationKeyMessage:
9446            TOGGLE_MASK_FIELD(cheatOptions, ActivationKeyMessage);
9469            TOGGLE_MASK_FIELD(cheat_options, ActivationKeyMessage);
94479470            break;
94489471
94499472         case kMenu_LoadOldFormat:
9450            TOGGLE_MASK_FIELD(cheatOptions, LoadOldFormat);
9473            TOGGLE_MASK_FIELD(cheat_options, LoadOldFormat);
94519474
94529475#ifdef MESS
94539476         case kMenu_SharedCode:
9454            TOGGLE_MASK_FIELD(cheatOptions, SharedCode);
9477            TOGGLE_MASK_FIELD(cheat_options, SharedCode);
94559478#endif
94569479      }
94579480   }
r2821r2822
94639486            cheat_menu_stack_push(select_search_menu, menu->handler, menu->sel);
94649487            break;
94659488
9466         case kMenu_LoadCheatOptions:
9467            LoadCheatDatabase(machine, kLoadFlag_CheatOption);
9489         case kMenu_Loadcheat_options:
9490            load_cheat_database(machine, kLoadFlag_CheatOption);
94689491            break;
94699492
9470         case kMenu_SaveCheatOptions:
9471            SaveCheatOptions();
9493         case kMenu_Savecheat_options:
9494            Savecheat_options();
94729495            break;
94739496
9474         case kMenu_ResetCheatOptions:
9475            cheatOptions = DEFAULT_CHEAT_OPTIONS;
9497         case kMenu_Resetcheat_options:
9498            cheat_options = DEFAULT_CHEAT_OPTIONS;
94769499            break;
94779500
94789501         case kMenu_Return:
r2821r2822
94819504   }
94829505   else if(input_ui_pressed(machine, IPT_UI_SAVE_CHEAT))
94839506   {
9484      SaveCheatOptions();
9507      Savecheat_options();
94859508   }
94869509   else if(input_ui_pressed(machine, IPT_UI_RELOAD_CHEAT))
94879510   {
9488      LoadCheatDatabase(machine, kLoadFlag_CheatOption);
9511      load_cheat_database(machine, kLoadFlag_CheatOption);
94899512   }
94909513   else if(input_ui_pressed(machine, IPT_UI_CANCEL))
94919514   {
r2821r2822
97699792   old_style_menu(menuItem, menuSubItem, NULL, menu->sel, 0);
97709793
97719794   /* adjust current cursor position */
9772   ADJUST_CURSOR(menu->sel, total)
9795   ADJUST_CURSOR(menu->sel, total);
97739796
97749797   /********** KEY HANDLING **********/
97759798   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
97769799   {
9777      CURSOR_TO_PREVIOUS(menu->sel, total)
9800      CURSOR_TO_PREVIOUS(menu->sel, total);
97789801   }
97799802   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
97809803   {
9781      CURSOR_TO_NEXT(menu->sel, total)
9804      CURSOR_TO_NEXT(menu->sel, total);
97829805   }
97839806   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
97849807   {
9785      CURSOR_PAGE_UP(menu->sel)
9808      CURSOR_PAGE_UP(menu->sel);
97869809   }
97879810   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
97889811   {
9789      CURSOR_PAGE_DOWN(menu->sel, total)
9812      CURSOR_PAGE_DOWN(menu->sel, total);
97909813   }
97919814   else if(ui_pressed_repeat_throttle(machine, IPT_UI_RIGHT, kHorizontalSlowKeyRepeatRate))
97929815   {
r2821r2822
98589881      kMenu_CRC,
98599882#endif
98609883      kMenu_FullMenuPageHeight,
9861      kMenu_CheatListLength,
9884      kMenu_cheat_list_length,
98629885      kMenu_Separator,
98639886      kMenu_CPURegionInfo,
98649887      kMenu_KeyCodeChecker,
r2821r2822
99239946
99249947   /* ##### CHEAT LIST LENGTH ##### */
99259948   menuItem[total] = "Total Code Entries";
9926   sprintf(numCodeBuf, "%d", cheatListLength);
9949   sprintf(numCodeBuf, "%d", cheat_list_length);
99279950   menuSubItem[total++] = numCodeBuf;
99289951
99299952   /* ##### SEPARATOR ##### */
r2821r2822
99479970   menuSubItem[total] = NULL;
99489971
99499972   /* adjust cursor position */
9950   ADJUST_CURSOR(menu->sel, total)
9973   ADJUST_CURSOR(menu->sel, total);
99519974
99529975   /* draw it */
99539976   old_style_menu(menuItem, menuSubItem, NULL, menu->sel, 0);
r2821r2822
99559978   /********** KEY HANDLING **********/
99569979   if(ui_pressed_repeat_throttle(machine, IPT_UI_UP, kVerticalKeyRepeatRate))
99579980   {
9958      CURSOR_TO_PREVIOUS(menu->sel, total)
9981      CURSOR_TO_PREVIOUS(menu->sel, total);
99599982
99609983      if(menu->sel == kMenu_Separator)
99619984         menu->sel--;
99629985   }
99639986   else if(ui_pressed_repeat_throttle(machine, IPT_UI_DOWN, kVerticalKeyRepeatRate))
99649987   {
9965      CURSOR_TO_NEXT(menu->sel, total)
9988      CURSOR_TO_NEXT(menu->sel, total);
99669989
99679990      if(menu->sel == kMenu_Separator)
99689991         menu->sel++;
99699992   }
99709993   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_UP, kVerticalKeyRepeatRate))
99719994   {
9972      CURSOR_PAGE_UP(menu->sel)
9995      CURSOR_PAGE_UP(menu->sel);
99739996   }
99749997   else if(ui_pressed_repeat_throttle(machine, IPT_UI_PAGE_DOWN, kVerticalKeyRepeatRate))
99759998   {
9976      CURSOR_PAGE_DOWN(menu->sel, total)
9999      CURSOR_PAGE_DOWN(menu->sel, total);
997710000   }
997810001   else if(input_ui_pressed(machine, IPT_UI_SELECT))
997910002   {
r2821r2822
1002410047
1002510048         if(cheatsDisabled)
1002610049         {
10027            for(i = 0; i < cheatListLength; i++)
10028               TempDeactivateCheat(&cheatList[i]);
10050            for(i = 0; i < cheat_list_length; i++)
10051               TempDeactivateCheat(&cheat_list[i]);
1002910052         }
1003010053      }
1003110054   }
r2821r2822
1003310056   if(cheatsDisabled)
1003410057      return;
1003510058
10036   for(i = 0; i < cheatListLength; i++)
10037      cheat_periodicEntry(machine, &cheatList[i]);
10059   for(i = 0; i < cheat_list_length; i++)
10060      cheat_periodicEntry(machine, &cheat_list[i]);
1003810061
10039   if(EXTRACT_FIELD(cheatOptions, SearchBox) == kSearchBox_Minimum)
10040      SET_FIELD(cheatOptions, SearchBox, kSearchBox_Standard);
10062   if(EXTRACT_FIELD(cheat_options, SearchBox) == kSearchBox_Minimum)
10063      SET_FIELD(cheat_options, SearchBox, kSearchBox_Standard);
1004110064}
1004210065
1004310066/*--------------
r2821r2822
1011810141   if(watchesDisabled)
1011910142      return;
1012010143
10121   for(i = 0; i < watchListLength; i++)
10144   for(i = 0; i < watch_list_length; i++)
1012210145   {
10123      WatchInfo * info = &watchList[i];
10146      watch_info *info = &watch_list[i];
1012410147
1012510148      int         j;
1012610149      int         numChars;
r2821r2822
1013110154
1013210155      char      buf[1024];
1013310156
10134      if(info->numElements)
10157      if(info->num_elements)
1013510158      {
1013610159         /* ##### LABEL ##### */
10137         switch(info->labelType)
10160         switch(info->label_type)
1013810161         {
1013910162            case kWatchLabel_Address:
1014010163               numChars = sprintf(buf, "%.8X: ", info->address);
r2821r2822
1015210175         }
1015310176
1015410177         /* ##### VALUE ##### */
10155         for(j = 0; j < info->numElements; j++)
10178         for(j = 0; j < info->num_elements; j++)
1015610179         {
1015710180            UINT32 data = 0;
1015810181
10159            if(!TEST_FIELD(info->cpu, RegionFlag))
10182            if(info->cpu < REGION_INVALID)
1016010183            {
1016110184               UINT8 cpu = EXTRACT_FIELD(info->cpu, CPUIndex);
1016210185
1016310186               switch(EXTRACT_FIELD(info->cpu, AddressSpace))
1016410187               {
1016510188                  case kAddressSpace_Program:
10166                     data = (DoCPURead(cpu, address, kSearchByteIncrementTable[info->elementBytes], cpu_needs_swap(cpu)) + info->addValue) & kSearchByteMaskTable[info->elementBytes];
10189                     data = (DoCPURead(cpu, address, kSearchByteIncrementTable[info->element_bytes], cpu_needs_swap(cpu)) + info->add_value) & kSearchByteMaskTable[info->element_bytes];
1016710190                     break;
1016810191
1016910192                  case kAddressSpace_DataSpace:
r2821r2822
1017310196                     UINT8 * buf = (UINT8 *) GetMemoryRegionBasePointer(cpu, EXTRACT_FIELD(info->cpu, AddressSpace), address);
1017410197
1017510198                     if(buf)
10176                        data =   DoMemoryRead(buf, address, kSearchByteIncrementTable[info->elementBytes], cpu_needs_swap(cpu) + info->addValue, get_cpu_info(cpu)) &
10177                              kSearchByteMaskTable[info->elementBytes];
10199                        data =   DoMemoryRead(buf, address, kSearchByteIncrementTable[info->element_bytes], cpu_needs_swap(cpu) + info->add_value, get_cpu_info(cpu)) &
10200                              kSearchByteMaskTable[info->element_bytes];
1017810201                  }
1017910202                  break;
1018010203
r2821r2822
1018710210               UINT8 * buf = memory_region(info->cpu);
1018810211
1018910212               if(buf)
10190                  data =   DoMemoryRead(buf, address, kSearchByteIncrementTable[info->elementBytes],
10191                        region_needs_swap(info->cpu) + info->addValue,
10192                        get_region_info(info->cpu)) & kSearchByteMaskTable[info->elementBytes];
10213                  data =   DoMemoryRead(buf, address, kSearchByteIncrementTable[info->element_bytes],
10214                        region_needs_swap(info->cpu) + info->add_value,
10215                        get_region_info(info->cpu)) & kSearchByteMaskTable[info->element_bytes];
1019310216            }
1019410217
10195            data = DoShift(data, info->dataShift);
10218            data = DoShift(data, info->data_shift);
1019610219            data ^= info->xor;
1019710220
10198            if(   (lineElements >= info->elementsPerLine) && info->elementsPerLine)
10221            if(   (lineElements >= info->elements_per_line) && info->elements_per_line)
1019910222            {
1020010223               lineElements = 0;
1020110224               xOffset = 0;
1020210225               yOffset++;
1020310226            }
1020410227
10205            switch(info->displayType)
10228            switch(info->display_type)
1020610229            {
1020710230               case kWatchDisplayType_Hex:
10208                  numChars = sprintf(buf, "%.*X", kSearchByteDigitsTable[info->elementBytes], data);
10231                  numChars = sprintf(buf, "%.*X", kSearchByteDigitsTable[info->element_bytes], data);
1020910232
1021010233                  ui_draw_text(buf, xOffset * ui_get_char_width('0') + info->x, yOffset * ui_get_line_height() + info->y);
1021110234                  xOffset += numChars;
r2821r2822
1021310236                  break;
1021410237
1021510238               case kWatchDisplayType_Decimal:
10216                  numChars = sprintf(buf, "%.*d", kSearchByteDecDigitsTable[info->elementBytes], data);
10239                  numChars = sprintf(buf, "%.*d", kSearchByteDecDigitsTable[info->element_bytes], data);
1021710240
1021810241                  ui_draw_text(buf, xOffset * ui_get_char_width('0') + info->x, yOffset * ui_get_line_height() + info->y);
1021910242                  xOffset += numChars;
r2821r2822
1022110244                  break;
1022210245
1022310246               case kWatchDisplayType_Binary:
10224                  numChars = PrintBinary(buf, data, kSearchByteMaskTable[info->elementBytes]);
10247                  numChars = PrintBinary(buf, data, kSearchByteMaskTable[info->element_bytes]);
1022510248
1022610249                  ui_draw_text(buf, xOffset * ui_get_char_width('0') + info->x, yOffset * ui_get_line_height() + info->y);
1022710250                  xOffset += numChars;
r2821r2822
1022910252                  break;
1023010253
1023110254               case kWatchDisplayType_ASCII:
10232                  numChars = PrintASCII(buf, data, info->elementBytes);
10255                  numChars = PrintASCII(buf, data, info->element_bytes);
1023310256
1023410257                  ui_draw_text(buf, xOffset * ui_get_char_width('0') + info->x, yOffset * ui_get_line_height() + info->y);
1023510258                  xOffset += numChars;
1023610259                  break;
1023710260            }
1023810261
10239            address += kSearchByteIncrementTable[info->elementBytes] + info->skip;
10262            address += kSearchByteIncrementTable[info->element_bytes] + info->skip;
1024010263            lineElements++;
1024110264         }
1024210265      }
1024310266   }
1024410267}
1024510268
10246/*------------------
10247  ResizeCheatList
10248------------------*/
10269/*--------------------------------------------------------
10270  resize_cheat_list - memory allocation for cheat entry
10271--------------------------------------------------------*/
1024910272
10250static void ResizeCheatList(UINT32 newLength)
10273static void resize_cheat_list(UINT32 new_length, UINT8 dispose)
1025110274{
10252   if(newLength != cheatListLength)
10275   if(new_length != cheat_list_length)
1025310276   {
10254      if(newLength < cheatListLength)
10277      /* ??? REQUEST_DISPOSE is only when INSERT right now so that it's meaningless ??? */
10278      if(dispose == REQUEST_DISPOSE)
1025510279      {
10256         int   i;
10280         /* free cheat entry if delete */
10281         if(new_length < cheat_list_length)
10282         {
10283            int i;
1025710284
10258         for(i = newLength; i < cheatListLength; i++)
10259            DisposeCheat(&cheatList[i]);
10285            for(i = new_length; i < cheat_list_length; i++)
10286               dispose_cheat(&cheat_list[i]);
10287         }
1026010288      }
1026110289
10262      cheatList = realloc(cheatList, newLength * sizeof(CheatEntry));
10290      /* reallocate cheat entry */
10291      cheat_list = realloc(cheat_list, new_length * sizeof(cheat_entry));
1026310292
10264      if(!cheatList && (newLength != 0))
10293      if(cheat_list == NULL && new_length != 0)
1026510294      {
10266         logerror("ResizeCheatList: out of memory resizing cheat list\n");
10267         ui_popup_time(2, "out of memory while loading cheat database");
10268
10269         cheatListLength = 0;
10270
10271         return;
10295         fatalerror("cheat: [cheat entry] memory allocation error\n"
10296                  "   length =      %.8X\n"
10297                  "   new_length =   %.8X\n"
10298                  "   cheat_list =   %p\n",
10299                  cheat_list_length, new_length, cheat_list);
1027210300      }
1027310301
10274      if(newLength > cheatListLength)
10302      /* add new entry if insert */
10303      if(new_length > cheat_list_length)
1027510304      {
10276         int   i;
10305         int i;
1027710306
10278         memset(&cheatList[cheatListLength], 0, (newLength - cheatListLength) * sizeof(CheatEntry));
10307         memset(&cheat_list[cheat_list_length], 0, (new_length - cheat_list_length) * sizeof(cheat_entry));
1027910308
10280         for(i = cheatListLength; i < newLength; i++)
10281            cheatList[i].flags |= kCheatFlag_Dirty;
10309         /* set dirty flag to inserted entry */
10310         for(i = cheat_list_length; i < new_length; i++)
10311            cheat_list[i].flags |= kCheatFlag_Dirty;
1028210312      }
1028310313
10284      cheatListLength = newLength;
10314      cheat_list_length = new_length;
1028510315   }
1028610316}
1028710317
10288/*---------------------------
10289  ResizeCheatListNoDispose
10290---------------------------*/
10318/*-----------------------------------------------------------------
10319  add_cheat_before - insert new cheat entry before selected code
10320-----------------------------------------------------------------*/
1029110321
10292static void ResizeCheatListNoDispose(UINT32 newLength)
10322static void add_cheat_before(UINT32 idx)
1029310323{
10294   if(newLength != cheatListLength)
10295   {
10296      cheatList = realloc(cheatList, newLength * sizeof(CheatEntry));
10324   /* insert new cheat entry */
10325   resize_cheat_list(cheat_list_length + 1, REQUEST_DISPOSE);
1029710326
10298      if(!cheatList && (newLength != 0))
10299      {
10300         logerror("ResizeCheatListNoDispose: out of memory resizing cheat list\n");
10301         ui_popup_time(2, "out of memory while loading cheat database");
10327   /* pack later entry if inserting point is not last */
10328   if(idx < cheat_list_length - 1)
10329      memmove(&cheat_list[idx + 1], &cheat_list[idx], sizeof(cheat_entry) * (cheat_list_length - 1 - idx));
1030210330
10303         cheatListLength = 0;
10331   if(idx >= cheat_list_length)
10332      idx = cheat_list_length - 1;
1030410333
10305         return;
10306      }
10334   /* initialize inserted entry */
10335   memset(&cheat_list[idx], 0, sizeof(cheat_entry));
1030710336
10308      if(newLength > cheatListLength)
10309      {
10310         int   i;
10337   /* set dirty flag (meaningelss?) */
10338   cheat_list[idx].flags |= kCheatFlag_Dirty;
1031110339
10312         memset(&cheatList[cheatListLength], 0, (newLength - cheatListLength) * sizeof(CheatEntry));
10340   /* insert new cheat action together */
10341   resize_cheat_action_list(&cheat_list[idx], 1, REQUEST_DISPOSE);
1031310342
10314         for(i = cheatListLength; i < newLength; i++)
10315            cheatList[i].flags |= kCheatFlag_Dirty;
10316      }
10343   cheat_list[idx].action_list[0].extend_data = ~0;
10344   cheat_list[idx].action_list[0].last_value = NULL;
1031710345
10318      cheatListLength = newLength;
10319   }
10346   SET_MESSAGE(kCheatMessage_SucceededToAdd);
1032010347}
1032110348
10322/*---------------------------------------------------------------
10323  AddCheatBefore - insert new cheat entry before selected code
10324---------------------------------------------------------------*/
10349/*------------------------------------------------
10350  delete_cheat_at - delete selected cheat entry
10351------------------------------------------------*/
1032510352
10326static void AddCheatBefore(UINT32 idx)
10353static void delete_cheat_at(UINT32 idx)
1032710354{
10328   ResizeCheatList(cheatListLength + 1);
10329
10330   if(idx < (cheatListLength - 1))
10331      memmove(&cheatList[idx + 1], &cheatList[idx], sizeof(CheatEntry) * (cheatListLength - 1 - idx));
10332
10333   if(idx >= cheatListLength)
10334      idx = cheatListLength - 1;
10335
10336   memset(&cheatList[idx], 0, sizeof(CheatEntry));
10337
10338   cheatList[idx].flags |= kCheatFlag_Dirty;
10339
10340   ResizeCheatActionList(&cheatList[idx], 1);
10341
10342   cheatList[idx].actionList[0].extendData = ~0;
10343   cheatList[idx].actionList[0].lastValue = NULL;
10344
10345   messageType = kCheatMessage_SucceededToAdd;
10346   messageTimer = DEFAULT_MESSAGE_TIME;
10347}
10348
10349/*----------------
10350  DeleteCheatAt
10351----------------*/
10352
10353static void DeleteCheatAt(UINT32 idx)
10354{
10355   if(idx >= cheatListLength)
10355   /* if selected point is not cheat entry, no action */
10356   if(idx >= cheat_list_length)
1035610357   {
10357      messageType = kCheatMessage_FailedToDelete;
10358      messageTimer = DEFAULT_MESSAGE_TIME;
10358      SET_MESSAGE(kCheatMessage_FailedToDelete);
1035910359      return;
1036010360   }
1036110361
10362   DisposeCheat(&cheatList[idx]);
10362   /* free selected cheat entry */
10363   dispose_cheat(&cheat_list[idx]);
1036310364
10364   if(idx < (cheatListLength - 1))
10365   /* pack later cheat entry if selected point is not last */
10366   if(idx < cheat_list_length - 1)
1036510367   {
10366      memmove(&cheatList[idx], &cheatList[idx + 1], sizeof(CheatEntry) * (cheatListLength - 1 - idx));
10368      memmove(&cheat_list[idx], &cheat_list[idx + 1], sizeof(cheat_entry) * (cheat_list_length - 1 - idx));
1036710369   }
1036810370
10369   ResizeCheatListNoDispose(cheatListLength - 1);
10371   /* realloc cheat entry */
10372   resize_cheat_list(cheat_list_length - 1, NO_DISPOSE);
1037010373
10371   messageType = kCheatMessage_SucceededToDelete;
10372   messageTimer = DEFAULT_MESSAGE_TIME;
10374   SET_MESSAGE(kCheatMessage_SucceededToDelete);
1037310375}
1037410376
10375/*------------------------------------------------
10376  DisposeCheat - free memory for selected entry
10377------------------------------------------------*/
10377/*--------------------------------------------------------------------------------
10378  dispose_cheat - free selected cheat entry and all cheat actions in this entry
10379--------------------------------------------------------------------------------*/
1037810380
10379static void DisposeCheat(CheatEntry * entry)
10381static void dispose_cheat(cheat_entry *entry)
1038010382{
1038110383   if(entry)
1038210384   {
10383      int   i;
10385      int i;
1038410386
1038510387      free(entry->name);
1038610388      free(entry->comment);
10387      free(entry->labelIndex);
10389      free(entry->label_index);
1038810390
10389      for(i = 0; i < entry->actionListLength; i++)
10390      {
10391         CheatAction   * action = &entry->actionList[i];
10391      /* free all cheat actions in selected entry */
10392      for(i = 0; i < entry->action_list_length; i++)
10393         dispose_action(&entry->action_list[i]);
1039210394
10393         DisposeAction(action);
10394      }
10395      free(entry->action_list);
1039510396
10396      free(entry->actionList);
10397
10398      memset(entry, 0, sizeof(CheatEntry));
10397      memset(entry, 0, sizeof(cheat_entry));
1039910398   }
1040010399}
1040110400
10402/*-----------------------------------------------------
10403  GetNewCheat - insert new cheat entry and return it
10404-----------------------------------------------------*/
10401/*-------------------------------------------------------------------------------
10402  get_new_cheat - return pointer to new cheat entry inserted at last position
10403-------------------------------------------------------------------------------*/
1040510404
10406static CheatEntry *   GetNewCheat(void)
10405static cheat_entry *get_new_cheat(void)
1040710406{
10408   AddCheatBefore(cheatListLength);
10407   /* insert new cheat entry at last position */
10408   add_cheat_before(cheat_list_length);
1040910409
10410   return &cheatList[cheatListLength - 1];
10410   return &cheat_list[cheat_list_length - 1];
1041110411}
1041210412
10413/*------------------------
10414  ResizeCheatActionList
10415------------------------*/
10413/*-----------------------------------------------------------------------
10414  resize_cheat_action_list - reallocate cheat action in selected entry
10415-----------------------------------------------------------------------*/
1041610416
10417static void ResizeCheatActionList(CheatEntry * entry, UINT32 newLength)
10417static void resize_cheat_action_list(cheat_entry *entry, UINT32 new_length, UINT8 dispose)
1041810418{
10419   if(newLength != entry->actionListLength)
10419   if(new_length != entry->action_list_length)
1042010420   {
10421      if(newLength < entry->actionListLength)
10421      if(dispose == REQUEST_DISPOSE)
1042210422      {
10423         int   i;
10423         /* free cheat action if delete */
10424         if(new_length < entry->action_list_length)
10425         {
10426            int i;
1042410427
10425         for(i = newLength; i < entry->actionListLength; i++)
10426            DisposeAction(&entry->actionList[i]);
10428            for(i = new_length; i < entry->action_list_length; i++)
10429               dispose_action(&entry->action_list[i]);
10430         }
1042710431      }
1042810432
10429      entry->actionList = realloc(entry->actionList, newLength * sizeof(CheatAction));
10430      if(!entry->actionList && (newLength != 0))
10431      {
10432         logerror("ResizeCheatActionList: out of memory resizing cheat action list\n");
10433         ui_popup_time(2, "out of memory while loading cheat database");
10433      /* reallocate cheat action */
10434      entry->action_list = realloc(entry->action_list, new_length * sizeof(cheat_action));
1043410435
10435         entry->actionListLength = 0;
10436
10437         return;
10438      }
10439
10440      if(newLength > entry->actionListLength)
10436      if(entry->action_list == NULL && new_length != 0)
1044110437      {
10442         memset(&entry->actionList[entry->actionListLength], 0, (newLength - entry->actionListLength) * sizeof(CheatAction));
10438         fatalerror("cheat: [cheat action] memory allocation error\n"
10439                  "   length =      %.8X\n"
10440                  "   new_length =   %.8X\n"
10441                  "   action_list =   %p\n",
10442                  entry->action_list_length, new_length, entry->action_list);
1044310443      }
1044410444
10445      entry->actionListLength = newLength;
10446   }
10447}
10448
10449/*---------------------------------
10450  ResizeCheatActionListNoDispose
10451---------------------------------*/
10452#if 0
10453static void ResizeCheatActionListNoDispose(CheatEntry * entry, UINT32 newLength)
10454{
10455   if(newLength != entry->actionListLength)
10456   {
10457      entry->actionList = realloc(entry->actionList, newLength * sizeof(CheatAction));
10458      if(!entry->actionList && (newLength != 0))
10445      /* add new action if insert */
10446      if(new_length > entry->action_list_length)
1045910447      {
10460         logerror("ResizeCheatActionList: out of memory resizing cheat action list\n");
10461         ui_popup_time(2, "out of memory while loading cheat database");
10462
10463         entry->actionListLength = 0;
10464
10465         return;
10448         memset(&entry->action_list[entry->action_list_length], 0, (new_length - entry->action_list_length) * sizeof(cheat_action));
1046610449      }
1046710450
10468      if(newLength > entry->actionListLength)
10469      {
10470         memset(&entry->actionList[entry->actionListLength], 0, (newLength - entry->actionListLength) * sizeof(CheatAction));
10471      }
10472
10473      entry->actionListLength = newLength;
10451      entry->action_list_length = new_length;
1047410452   }
1047510453}
1047610454
10455#if 0
1047710456/*----------------------------------------------------------------
1047810457  AddActionBefore - Insert empty Action
1047910458                    This function is only called in EditCheat()
r2821r2822
1049110470
1049210471   memset(&entry->actionList[idx], 0, sizeof(CheatAction));
1049310472
10494   cheatList[idx].actionList[0].extendData = ~0;
10495   cheatList[idx].actionList[0].lastValue = NULL;
10473   cheat_list[idx].actionList[0].extendData = ~0;
10474   cheat_list[idx].actionList[0].lastValue = NULL;
1049610475}
1049710476
1049810477/*-----------------
r2821r2822
1050310482{
1050410483   if(idx >= entry->actionListLength)
1050510484   {
10506      messageType = kCheatMessage_FailedToDelete;
10507      messageTimer = DEFAULT_MESSAGE_TIME;
10485      SET_MESSAGE(kCheatMessage_FailedToDelete);
1050810486      return;
1050910487   }
1051010488
r2821r2822
1051510493
1051610494   ResizeCheatActionListNoDispose(entry, entry->actionListLength - 1);
1051710495
10518   messageTimer = DEFAULT_MESSAGE_TIME;
10519   messageType = kCheatMessage_SucceededToDelete;
10496   SET_MESSAGE(kCheatMessage_SucceededToDelete);
1052010497}
1052110498#endif
10522/*----------------
10523  DisposeAction
10524----------------*/
10499/*----------------------------------------------
10500  dispose_action - free selected cheat action
10501----------------------------------------------*/
1052510502
10526static void DisposeAction(CheatAction * action)
10503static void dispose_action(cheat_action *action)
1052710504{
10528   if(action)
10505   if(action != NULL)
1052910506   {
10530      free(action->optionalName);
10507      free(action->optional_name);
1053110508
10532      if(action->lastValue)
10533         free(action->lastValue);
10509      if(action->last_value)
10510         free(action->last_value);
1053410511
10535      memset(action, 0, sizeof(CheatAction));
10512      memset(action, 0, sizeof(cheat_action));
1053610513   }
1053710514}
1053810515
10539/*------------------------------------------------
10540  InitWatch - initialize a value for watchpoint
10541------------------------------------------------*/
10516/*-------------------------------------------------
10517  init_watch - initialize a value for watchpoint
10518-------------------------------------------------*/
1054210519
10543static void InitWatch(WatchInfo * info, UINT32 idx)
10520static void init_watch(watch_info *info, UINT32 idx)
1054410521{
1054510522   /* NOTE : 1st watchpoint should be always Y = 0 */
1054610523   if(idx > 0)
10547      info->y = watchList[idx - 1].y + ui_get_line_height();
10524      info->y = watch_list[idx - 1].y + ui_get_line_height();
1054810525   else
1054910526      info->y = 0;
1055010527}
1055110528
10552/*------------------
10553  ResizeWatchList
10554------------------*/
10529/*--------------------------------------------------------------
10530  resize_watch_list - reallocate watch list if different size
10531--------------------------------------------------------------*/
1055510532
10556static void ResizeWatchList(UINT32 newLength)
10533static void resize_watch_list(UINT32 new_length, UINT8 dispose)
1055710534{
10558   if(newLength != watchListLength)
10535   if(new_length != watch_list_length)
1055910536   {
10560      if(newLength < watchListLength)
10537      /* NOTE : dispose flag is only set when called from delete_watch_at() */
10538      if(dispose)
1056110539      {
10562         int   i;
10540         /* if delete, free deleted or later watch list */
10541         if(new_length < watch_list_length)
10542         {
10543            int i;
1056310544
10564         for(i = newLength; i < watchListLength; i++)
10565            DisposeWatch(&watchList[i]);
10545            for(i = new_length; i < watch_list_length; i++)
10546               dispose_watch(&watch_list[i]);
10547         }
1056610548      }
1056710549
10568      watchList = realloc(watchList, newLength * sizeof(WatchInfo));
10569      if(!watchList && (newLength != 0))
10570      {
10571         logerror("ResizeWatchList: out of memory resizing watch list\n");
10572         ui_popup_time(2, "out of memory while adding watch");
10550      /* reallocate watch list */
10551      watch_list = realloc(watch_list, new_length * sizeof(watch_info));
1057310552
10574         watchListLength = 0;
10575
10576         return;
10577      }
10578
10579      if(newLength > watchListLength)
10553      if(watch_list == NULL && new_length != 0)
1058010554      {
10581         int   i;
10582
10583         memset(&watchList[watchListLength], 0, (newLength - watchListLength) * sizeof(WatchInfo));
10584
10585         for(i = watchListLength; i < newLength; i++)
10586            InitWatch(&watchList[i], i);
10555         /* memory allocation error */
10556         fatalerror(   "cheat : [watch list] memory allocation error\n"
10557                  "   length =      %.8X\n"
10558                  "   new_length =   %.8X\n"
10559                  "   watch_list =   %p\n",
10560                  watch_list_length, new_length, watch_list);
1058710561      }
1058810562
10589      watchListLength = newLength;
10590   }
10591}
10592
10593/*---------------------------
10594  ResizeWatchListNoDispose
10595---------------------------*/
10596
10597static void ResizeWatchListNoDispose(UINT32 newLength)
10598{
10599   if(newLength != watchListLength)
10600   {
10601      watchList = realloc(watchList, newLength * sizeof(WatchInfo));
10602      if(!watchList && (newLength != 0))
10563      /* if insert, move later watch list */
10564      if(new_length > watch_list_length)
1060310565      {
10604         logerror("ResizeWatchList: out of memory resizing watch list\n");
10605         ui_popup_time(2, "out of memory while adding watch");
10566         int i;
1060610567
10607         watchListLength = 0;
10568         memset(&watch_list[watch_list_length], 0, (new_length - watch_list_length) * sizeof(watch_info));
1060810569
10609         return;
10570         for(i = watch_list_length; i < new_length; i++)
10571            init_watch(&watch_list[i], i);
1061010572      }
1061110573
10612      if(newLength > watchListLength)
10613      {
10614         int   i;
10615
10616         memset(&watchList[watchListLength], 0, (newLength - watchListLength) * sizeof(WatchInfo));
10617
10618         for(i = watchListLength; i < newLength; i++)
10619            InitWatch(&watchList[i], i);
10620      }
10621
10622      watchListLength = newLength;
10574      watch_list_length = new_length;
1062310575   }
1062410576}
1062510577
10626/*-----------------
10627  AddWatchBefore
10628-----------------*/
10578/*-------------------------------------------
10579  add_watch_before - insert new watch list
10580-------------------------------------------*/
1062910581
10630static void AddWatchBefore(UINT32 idx)
10582static void add_watch_before(UINT32 idx)
1063110583{
10632   ResizeWatchList(watchListLength + 1);
10584   /* reallocate watch list */
10585   resize_watch_list(watch_list_length + 1, 0);
1063310586
10634   if(idx < (watchListLength - 1))
10635      memmove(&watchList[idx + 1], &watchList[idx], sizeof(WatchInfo) * (watchListLength - 1 - idx));
10587   /* if insert position is not last, move later watch list */
10588   if(idx < watch_list_length - 1)
10589      memmove(&watch_list[idx + 1], &watch_list[idx], sizeof(watch_info) * (watch_list_length - 1 - idx));
10590   else
10591      idx = watch_list_length - 1;
1063610592
10637   if(idx >= watchListLength)
10638      idx = watchListLength - 1;
10593   /* memory initialize */
10594   memset(&watch_list[idx], 0, sizeof(watch_info));
1063910595
10640   memset(&watchList[idx], 0, sizeof(WatchInfo));
10641
10642   InitWatch(&watchList[idx], idx);
10596   init_watch(&watch_list[idx], idx);
1064310597}
1064410598
10645/*----------------
10646  DeleteWatchAt
10647----------------*/
10599/*------------------------------------------------
10600  delete_watch_at - delete selected watch point
10601------------------------------------------------*/
1064810602
10649static void DeleteWatchAt(UINT32 idx)
10603static void delete_watch_at(UINT32 idx)
1065010604{
10651   if(idx >= watchListLength)
10605   /* if selected item is not watchpoint, no delete */
10606   if(idx >= watch_list_length)
10607   {
10608      SET_MESSAGE(kCheatMessage_FailedToDelete);
1065210609      return;
10610   }
1065310611
10654   DisposeWatch(&watchList[idx]);
10612   /* free selected watch list */
10613   dispose_watch(&watch_list[idx]);
1065510614
10656   if(idx < (watchListLength - 1))
10657      memmove(&watchList[idx], &watchList[idx + 1], sizeof(WatchInfo) * (watchListLength - 1 - idx));
10615   /* move later watch list */
10616   memmove(&watch_list[idx], &watch_list[idx + 1], sizeof(watch_info) * (watch_list_length - 1 - idx));
1065810617
10659   ResizeWatchListNoDispose(watchListLength - 1);
10618   /* reallocate watch list */
10619   resize_watch_list(watch_list_length - 1, 1);
1066010620}
1066110621
10662/*---------------
10663  DisposeWatch
10664---------------*/
10622/*-------------------------------------------------
10623  dispose_watch - initialize selected watch list
10624-------------------------------------------------*/
1066510625
10666static void DisposeWatch(WatchInfo * watch)
10626static void dispose_watch(watch_info *watch)
1066710627{
10668   if(watch)
10669      memset(watch, 0, sizeof(WatchInfo));
10628   memset(watch, 0, sizeof(watch_info));
1067010629}
1067110630
10672/*----------------------------------------------------------
10673  GetUnusedWatch - search unused watchpoint and return it
10674----------------------------------------------------------*/
10631/*--------------------------------------------
10632  get_unused_watch - find unused watchpoint
10633--------------------------------------------*/
1067510634
10676static WatchInfo * GetUnusedWatch(void)
10635static watch_info *get_unused_watch(void)
1067710636{
1067810637   int         i;
10679   WatchInfo   * info;
10680   WatchInfo   * theWatch = NULL;
10638   watch_info   *info;
10639   watch_info   *the_watch = NULL;
1068110640
1068210641   /* search unused watchpoint */
10683   for(i = 0; i < watchListLength; i++)
10642   for(i = 0; i < watch_list_length; i++)
1068410643   {
10685      info = &watchList[i];
10644      info = &watch_list[i];
1068610645
10687      if(info->numElements == 0)
10646      /* NOTE : "unused" means "undisplayed" */
10647      if(info->num_elements == 0)
1068810648      {
10689         theWatch = info;
10649         the_watch = info;
1069010650         break;
1069110651      }
1069210652   }
1069310653
10694   /* if unused watchpoint is not found, insert new watchpoint */
10695   if(!theWatch)
10654   /* if all watchpoints are used, insert new watchpoint */
10655   if(the_watch == NULL)
1069610656   {
10697      AddWatchBefore(watchListLength);
10657      add_watch_before(watch_list_length);
1069810658
10699      theWatch = &watchList[watchListLength - 1];
10659      the_watch = &watch_list[watch_list_length - 1];
1070010660   }
1070110661
10702   return theWatch;
10662   return the_watch;
1070310663}
1070410664
10705/*----------------------------------------------------------------------------
10706  AddCheatFromWatch - add new cheat code from watchpoint list to cheat list
10707----------------------------------------------------------------------------*/
10665/*------------------------------------------------------------
10666  add_cheat_from_watch - add new cheat code from watchpoint
10667------------------------------------------------------------*/
1070810668
10709static void AddCheatFromWatch(WatchInfo * watch)
10669static void add_cheat_from_watch(watch_info *watch)
1071010670{
1071110671   if(watch)
1071210672   {
10713      int         tempStringLength;
10714      char      tempString[1024];
10715      CheatEntry   * entry            = GetNewCheat();
10716      CheatAction   * action         = &entry->actionList[0];
10673      int            temp_string_length;
10674      char         temp_string[1024];
10675      cheat_entry      *entry      = get_new_cheat();
10676      cheat_action   *action      = &entry->action_list[0];
1071710677
1071810678      /* set parameters */
10719      action->region      = watch->cpu;
10720      SET_FIELD(action->type, CPURegion, action->region);
10721      SET_FIELD(action->type, AddressSize, watch->elementBytes);
10722      action->address      = action->originalAddress   = watch->address;
10723      action->extendData   = ~0;
10724      action->lastValue   = NULL;
10679      action->region            = watch->cpu;
10680      action->address            = watch->address;
10681      action->original_address   = watch->address;
10682      action->extend_data         = ~0;
10683      action->last_value         = NULL;
10684      action->data             = ReadData(action);
10685      SET_FIELD(action->type, AddressSize, watch->element_bytes);
1072510686
10726      action->data       = ReadData(action);
10727
1072810687      /* set name */
10729      tempStringLength = sprintf(tempString, "%.8X (%d) = %.*X", watch->address, watch->cpu, kSearchByteDigitsTable[watch->elementBytes], action->data);
10730      entry->name = create_string_copy(tempString);
10688      temp_string_length = sprintf(temp_string, "%.8X (%d) = %.*X", watch->address, watch->cpu, kSearchByteDigitsTable[watch->element_bytes], action->data);
10689      entry->name = create_string_copy(temp_string);
1073110690
10732      UpdateCheatInfo(entry, 0);
10691      update_cheat_info(entry, 0);
1073310692
10734      messageType      = kCheatMessage_SucceededToAdd;
10735      messageTimer   = DEFAULT_MESSAGE_TIME;
10693      SET_MESSAGE(kCheatMessage_SucceededToAdd);
1073610694   }
1073710695   else
10738   {
10739      messageType      = kCheatMessage_FailedToAdd;
10740      messageTimer   = DEFAULT_MESSAGE_TIME;
10741   }
10696      SET_MESSAGE(kCheatMessage_FailedToAdd);
1074210697}
1074310698
10744/*--------------------------------------------------------------------------------------
10745  SetupCheatFromWatchAsWatch - add new watch code from watchpoint list to cheat list
10746                               If watchpoint is not displayed (length = 0), don't add
10747--------------------------------------------------------------------------------------*/
10699/*---------------------------------------------------------------------------
10700  add_cheat_from_watch_as_watch - add new watchpoint cheat from watchpoint
10701---------------------------------------------------------------------------*/
1074810702
10749static void SetupCheatFromWatchAsWatch(CheatEntry * entry, WatchInfo * watch)
10703static void add_cheat_from_watch_as_watch(cheat_entry *entry, watch_info *watch)
1075010704{
10751   if(watch && entry && watch->numElements)
10705   /* NOTE : don't add in case of undisplayed watchpoint */
10706   if(watch && entry && watch->num_elements)
1075210707   {
10753      char         tempString[256];
10754      CheatAction      * action;
10708      char         temp_string[256];
10709      cheat_action   *action;
1075510710
10756      DisposeCheat(entry);
10757      ResizeCheatActionList(entry, 1);
10711      /* free then add new cheat entry */
10712      dispose_cheat(entry);
10713      resize_cheat_action_list(entry, 1, REQUEST_DISPOSE);
10714      action = &entry->action_list[0];
1075810715
10759      action = &entry->actionList[0];
10716      /* set name and comments */
10717      sprintf(temp_string, "Watch %.8X (%d)", watch->address, watch->cpu);
1076010718
10761      sprintf(tempString, "Watch %.8X (%d)", watch->address, watch->cpu);
10762
10763      /* set name */
10764      entry->name      = create_string_copy(tempString);
10719      entry->name      = create_string_copy(temp_string);
1076510720      entry->comment   = create_string_copy(watch->label);
1076610721
1076710722      /* set parameters */
10768      SET_FIELD(action->type, CodeType, kCodeType_Watch);
10769      SET_FIELD(action->type, AddressSize, kSearchByteIncrementTable[watch->elementBytes] - 1);
10723      action->region            = watch->cpu;
10724      action->address            = watch->address;
10725      action->original_address   = watch->address;
10726      action->original_data      = action->data;
10727      action->extend_data         = ~0;
1077010728
10771      action->region            =   watch->cpu;
10772      action->address            =   watch->address;
10773      action->originalAddress      =   action->address;
10774      action->originalDataField   =   action->data;
10775      action->extendData         =   0xFFFFFFFF;
10776
10777      SET_FIELD(action->data, WatchNumElements, watch->numElements - 1);
10729      SET_FIELD(action->type, CodeType, kCodeType_Watch);
10730      SET_FIELD(action->type, AddressSize, kSearchByteIncrementTable[watch->element_bytes] - 1);
10731      SET_FIELD(action->data, WatchNumElements, watch->num_elements - 1);
1077810732      SET_FIELD(action->data, WatchSkip, watch->skip);
10779      SET_FIELD(action->data, WatchElementsPerLine, watch->elementsPerLine);
10780      SET_FIELD(action->data, WatchAddValue, watch->addValue);
10733      SET_FIELD(action->data, WatchElementsPerLine, watch->elements_per_line);
10734      SET_FIELD(action->data, WatchAddValue, watch->add_value);
1078110735
10782      /* set comment */
10736      update_cheat_info(entry, 0);
1078310737
10784      UpdateCheatInfo(entry, 0);
10785
10786      messageType      = kCheatMessage_SucceededToAdd;
10787      messageTimer   = DEFAULT_MESSAGE_TIME;
10738      SET_MESSAGE(kCheatMessage_SucceededToAdd);
1078810739   }
1078910740   else
10790   {
10791      messageType      = kCheatMessage_FailedToAdd;
10792      messageTimer   = DEFAULT_MESSAGE_TIME;
10793   }
10741      SET_MESSAGE(kCheatMessage_FailedToAdd);
1079410742}
1079510743
10796/*-----------------------------------------------------------
10797  ResetWatch - clear data in WatchInfo except x/y position
10798-----------------------------------------------------------*/
10744/*----------------------------------------------------------------------
10745  reset_watch - clear data in selected watch list except the position
10746----------------------------------------------------------------------*/
1079910747
10800static void ResetWatch(WatchInfo * watch)
10748static void reset_watch(watch_info *watch)
1080110749{
1080210750   if(watch)
1080310751   {
10804      watch->address         = 0;
10805      watch->cpu            = 0;
10806      watch->numElements      = 0;
10807      watch->elementBytes      = kWatchSizeConversionTable[0];
10808      watch->labelType      = kWatchLabel_None;
10809      watch->displayType      = kWatchDisplayType_Hex;
10810      watch->skip            = 0;
10811      watch->elementsPerLine   = 0;
10812      watch->addValue         = 0;
10813      watch->addressShift      = 0;
10814      watch->dataShift      = 0;
10815      watch->xor            = 0;
10816      watch->linkedCheat      = NULL;
10817      watch->label[0]         = 0;
10752      watch->address            = 0;
10753      watch->cpu               = 0;
10754      watch->num_elements         = 0;
10755      watch->element_bytes      = kWatchSizeConversionTable[0];
10756      watch->label_type         = kWatchLabel_None;
10757      watch->display_type         = kWatchDisplayType_Hex;
10758      watch->skip               = 0;
10759      watch->elements_per_line   = 0;
10760      watch->add_value         = 0;
10761      watch->address_shift      = 0;
10762      watch->data_shift         = 0;
10763      watch->xor               = 0;
10764      watch->linked_cheat         = NULL;
10765      watch->label[0]            = 0;
1081810766   }
10767   else
10768      SET_MESSAGE(kCheatMessage_FailedToDelete);
1081910769}
1082010770
1082110771/*------------------------------------------------------------------
r2821r2822
1082610776{
1082710777   if(new_length != search_list_length)
1082810778   {
10829      /* if delete, dispose deleted or later search lists */
10779      /* free search list if delete */
1083010780      if(new_length < search_list_length)
1083110781      {
1083210782         int i;
r2821r2822
1084010790
1084110791      if(search_list == NULL && new_length != 0)
1084210792      {
10843         /* memory allocation error */
10844         logerror("ResizeSearchList: out of memory resizing search list\n");
10845         ui_popup_time(2, "out of memory while adding search");
10846
10847         search_list_length = 0;
10848
10849         return;
10793         fatalerror("cheat: [search info] memory allocation error\n"
10794                  "   length =      %.8X\n"
10795                  "   new_length =   %.8X\n"
10796                  "   search_list =   %p\n",
10797                  search_list_length, new_length, search_list);
1085010798      }
1085110799
10852      /* if insert, initialize new search list */
10800      /* add new search list if insert */
1085310801      if(new_length > search_list_length)
1085410802      {
1085510803         int i;
r2821r2822
1093410882static void init_search(search_info *info)
1093510883{
1093610884   if(info)
10937      info->search_speed = ksearch_speed_Medium;
10885      info->search_speed = SEARCH_SPEED_MEDIUM;
1093810886}
1093910887
1094010888/*---------------------------------------------------------------------------
r2821r2822
1099810946  fill_buffer_from_region - fill selected search region with a value read from search address
1099910947----------------------------------------------------------------------------------------------*/
1100010948
11001static void fill_buffer_from_region(search_region *region, UINT8 * buf)
10949static void fill_buffer_from_region(search_region *region, UINT8 *buf)
1100210950{
1100310951   UINT32 offset;
1100410952
r2821r2822
1106611014      info->backup_valid   = 0;
1106711015
1106811016#if 1
11069      messageTimer = DEFAULT_MESSAGE_TIME;
11070      messageType = kCheatMessage_RestoreValue;
11017      SET_MESSAGE(kCheatMessage_RestoreValue);
1107111018#else
1107211019      ui_popup_time(1, "values restored");   /* not displayed when ui is opend */
1107311020#endif
r2821r2822
1107511022   else
1107611023   {
1107711024#if 1
11078      messageTimer = DEFAULT_MESSAGE_TIME;
11079      messageType = kCheatMessage_NoOldValue;
11025      SET_MESSAGE(kCheatMessage_NoOldValue);
1108011026#else
1108111027      ui_popup_time(1, "there are no old values");   /* not displayed when ui is opend */
1108211028#endif
r2821r2822
1112011066static UINT8 default_enable_region(running_machine *machine, search_region *region, search_info *info)
1112111067{
1112211068   write8_machine_func   handler         = region->write_handler->write.mhandler8;
11123   FPTR            handlerAddress   = (FPTR)handler;
11069   FPTR            handler_address   = (FPTR)handler;
1112411070
1112511071   switch(info->search_speed)
1112611072   {
11127      case ksearch_speed_Fast:
11128#if HAS_SH2
11129         if(   machine->config->cpu[0].type == CPU_SH2 &&
11130            (info->target_type == kRegionType_CPU && info->target_idx == 0 && region->address == 0x06000000))
11131               return 1;
11132         else
11133            return 0;
11134#endif
11073      case SEARCH_SPEED_FAST:
1113511074         if(handler == SMH_RAM && region->write_handler->baseptr != NULL)
1113611075            return 1;
1113711076
11138      case ksearch_speed_Medium:
11139         if(handlerAddress >= (FPTR)SMH_BANK1 && handlerAddress <= (FPTR)SMH_BANK24)
11077      case SEARCH_SPEED_MEDIUM:
11078         if(handler_address >= (FPTR)SMH_BANK1 && handler_address <= (FPTR)SMH_BANK32)
1114011079            return 1;
1114111080
1114211081         if(handler == SMH_RAM)
r2821r2822
1114411083
1114511084         return 0;
1114611085
11147      case ksearch_speed_Slow:
11086      case SEARCH_SPEED_SLOW:
1114811087         if(handler == SMH_NOP || handler == SMH_ROM)
1114911088            return 0;
1115011089
11151         if(handlerAddress > STATIC_COUNT && region->write_handler->baseptr == NULL)
11090         if(handler_address > STATIC_COUNT && region->write_handler->baseptr == NULL)
1115211091            return 0;
1115311092
1115411093         return 1;
1115511094
11156      case ksearch_speed_VerySlow:
11095      case SEARCH_SPEED_VERY_SLOW:
1115711096         if(handler == SMH_NOP || handler == SMH_ROM)
1115811097            return 0;
1115911098
r2821r2822
1118011119            genf   *handler      = region->write_handler->write.generic;
1118111120            FPTR   handler_address   = (FPTR)handler;
1118211121
11183            if(handler_address >= (FPTR)SMH_BANK1 && handler_address <= (FPTR)SMH_BANK24)
11122            if(handler_address >= (FPTR)SMH_BANK1 && handler_address <= (FPTR)SMH_BANK32)
1118411123            {
1118511124               sprintf(desc, "BANK%.2d", (int)(handler_address - (FPTR)SMH_BANK1) + 1);
1118611125            }
r2821r2822
1121411153   }
1121511154}
1121611155
11217/*-------------------------------------------------------------------------------------
11218  allocate_search_regions - free memory for search region then realloc if searchable
11219-------------------------------------------------------------------------------------*/
11156/*------------------------------------------------------------------
11157  is_search_region_in_range - check valid range for search region
11158------------------------------------------------------------------*/
1122011159
11160static UINT8 is_search_region_in_range(UINT8 cpu, UINT32 length)
11161{
11162   if(length > cpu_info_list[cpu].address_mask)
11163      return 0;
11164
11165   /* all memory in 32-bit cpu causes zero length in several cases */
11166   if(length == 0)
11167      return 0;
11168
11169   if(length > SAFE_SEARCH_REGION_RANGE)
11170      return 0;
11171
11172   return 1;
11173}
11174
11175/*----------------------------------------------------------------
11176  allocate_search_regions - memory allocation for search region
11177----------------------------------------------------------------*/
11178
1122111179static void allocate_search_regions(search_info *info)
1122211180{
1122311181   int i;
r2821r2822
1122711185
1122811186   for(i = 0; i < info->region_list_length; i++)
1122911187   {
11230      search_region *region;
11188      search_region *region = &info->region_list[i];
1123111189
11232      region            = &info->region_list[i];
11233      region->num_results   = 0;
11190      region->num_results = 0;
1123411191
1123511192      free(region->first);
1123611193      free(region->last);
r2821r2822
1124711204         region->backup_status   = malloc(region->length);
1124811205
1124911206         if(region->first == NULL || region->last == NULL || region->status == NULL || region->backup_last == NULL || region->backup_status == NULL)
11250            fatalerror(   "cheat: [search region] memory allocation error\n"
11251                     "   ----- %s -----\n"
11252                     "   first         = %p\n"
11253                     "   last         = %p\n"
11254                     "   status         = %p\n"
11255                     "   backup_last      = %p\n"
11256                     "   backup_status   = %p\n",
11257                     region->name,
11258                     region->first, region->last, region->status, region->backup_last, region->backup_status);
11207         {
11208            /* NOTE : ignored memory allocation error but locked this region */
11209            free(region->first);
11210            free(region->last);
11211            free(region->status);
11212            free(region->backup_last);
11213            free(region->backup_status);
11214
11215            region->first =         NULL;
11216            region->last =         NULL;
11217            region->status =      NULL;
11218            region->backup_last =   NULL;
11219            region->backup_status =   NULL;
11220            region->flags &=       ~kRegionFlag_Enabled;
11221            region->flags |=      kRegionFlag_HasError;
11222
11223            SET_MESSAGE(kCheatMessage_FailedToAllocate);
11224         }
1125911225      }
1126011226      else
1126111227      {
r2821r2822
1128411250   {
1128511251      case kRegionType_CPU:
1128611252      {
11287         if(info->search_speed == ksearch_speed_AllMemory)
11253         if(info->search_speed == SEARCH_SPEED_ALL_MEMORY)
1128811254         {
1128911255            UINT32         length = cpu_info_list[info->target_idx].address_mask + 1;
1129011256            search_region   *region;
r2821r2822
1130311269            region->status         = NULL;
1130411270            region->backup_last      = NULL;
1130511271            region->backup_status   = NULL;
11306            region->flags         = kRegionFlag_Enabled;
1130711272
1130811273            set_search_region_default_name(region);
11274
11275            if(is_search_region_in_range(info->target_idx, length) == 0)
11276            {
11277               region->flags &= ~kRegionFlag_Enabled;
11278               region->flags |= kRegionFlag_HasError;
11279            }
11280            else
11281               region->flags = kRegionFlag_Enabled;
1130911282         }
1131011283         else
1131111284         {
r2821r2822
1134211315                     traverse->status      = NULL;
1134311316                     traverse->backup_last   = NULL;
1134411317                     traverse->backup_status   = NULL;
11345                     traverse->flags         = default_enable_region(machine, traverse, info) ? kRegionFlag_Enabled : 0;
1134611318
11319                     if(is_search_region_in_range(info->target_idx, length) == 0)
11320                     {
11321                        traverse->flags &= ~kRegionFlag_Enabled;
11322                        traverse->flags |= kRegionFlag_HasError;
11323                     }
11324                     else
11325                        traverse->flags = default_enable_region(machine, traverse, info) ? kRegionFlag_Enabled : 0;
11326
1134711327                     set_search_region_default_name(traverse);
1134811328
1134911329                     traverse++;
r2821r2822
1150611486   return newCode;
1150711487}
1150811488
11509/*-------------------
11510  ConvertToNewCode
11511-------------------*/
11489/*----------------------
11490  convert_to_new_code
11491----------------------*/
1151211492
11513static int ConvertToNewCode(CheatAction * action)
11493static int convert_to_new_code(cheat_action *action)
1151411494{
11515   int newType = 0;
11495   int new_type = 0;
1151611496
11517   if(EXTRACT_FIELD(action->type, LocationType) == kLocation_IndirectIndexed)
11518      SET_FIELD(newType, CPURegion, EXTRACT_FIELD(action->type, LocationParameterCPU));
11519   else if(EXTRACT_FIELD(action->type, LocationType) != kLocation_Custom)
11520      SET_FIELD(newType, CPURegion, EXTRACT_FIELD(action->type, LocationParameter));
11521
11522   if(TEST_FIELD(action->type, UserSelectEnable))
11523      SET_FIELD(newType, CodeType, kCodeType_VWrite);
11524   else if(EXTRACT_FIELD(action->type, LocationType) == kLocation_IndirectIndexed)
11525   {   SET_FIELD(newType, CodeType, kCodeType_IWrite);
11526      SET_FIELD(newType, IndexSize, EXTRACT_FIELD(action->type, LocationParameterOption)); }
11527   else
11528   {   SET_FIELD(newType, CodeType, kCodeType_PDWWrite);
11529      SET_FIELD(newType, IndexSize, kSearchSize_32Bit); }
11530
11531   SET_FIELD(newType, AddressSize, EXTRACT_FIELD(action->type, BytesUsed));
11532
11533   if(TEST_FIELD(action->type, LinkEnable))
11534      SET_FIELD(newType, Link, kLink_Link);
11535
11497   if(EXTRACT_FIELD(action->type, LocationType) == kLocation_IndirectIndexed) {
11498      SET_FIELD(new_type, CodeType, kCodeType_IWrite);
11499      SET_FIELD(new_type, CodeParameter, EXTRACT_FIELD(action->type, LocationParameterOption)); }
11500   SET_FIELD(new_type, AddressSize, kSearchSize_32Bit);
11501   SET_MASK_FIELD(new_type, Endianness);
1153611502   if(TEST_FIELD(action->type, RestorePreviousValue))
11537      SET_MASK_FIELD(newType, RestoreValue);
11538
11503      SET_MASK_FIELD(new_type, RestoreValue);
1153911504   if(EXTRACT_FIELD(action->type, Prefill))
11540      SET_MASK_FIELD(newType, PrefillEnable);
11505      SET_FIELD(new_type, PrefillEnable, 0);
11506   if(EXTRACT_FIELD(action->type, Type) == kLocation_Standard && EXTRACT_FIELD(action->type, TypeParameter))
11507      SET_MASK_FIELD(new_type, DelayEnable);
1154111508
11542   if(!EXTRACT_FIELD(action->type, Type) && EXTRACT_FIELD(action->type, TypeParameter))
11543      SET_MASK_FIELD(newType, DelayEnable);
11544
11545   if(TEST_FIELD(action->type, OneShot))
11546      SET_MASK_FIELD(newType, OneShot);
11547
11548   return newType;
11509   return new_type;
1154911510}
1155011511
11551/*--------------------------
11552  HandleLocalCommandCheat
11553--------------------------*/
11512/*-------------------------------------------------------------------
11513  handle_local_command_cheat - handle specified cheat command code
11514-------------------------------------------------------------------*/
1155411515
11555static void HandleLocalCommandCheat(running_machine *machine, int cpu, int type, int address, int data, UINT8 format)
11516static void handle_local_command_cheat(running_machine *machine, int cpu, int type, int address, int data, UINT8 format)
1155611517{
1155711518   int command = 0;
1155811519
11559   if(format != 1)
11520   if(format != FORMAT_NEW)
1156011521   {
1156111522      switch(EXTRACT_FIELD(type, LocationParameter))
1156211523      {
1156311524         case kCustomLocation_AssignActivationKey:
11564            command = kCustomCode_ActivationKey1;
11525            command = CUSTOM_CODE_ACTIVATION_KEY_1;
1156511526
1156611527            if(TEST_FIELD(type, OneShot))
11567               command = kCustomCode_ActivationKey2;
11528               command = CUSTOM_CODE_ACTIVATION_KEY_2;
1156811529            break;
1156911530
1157011531         case kCustomLocation_Enable:
11571            command = kCustomCode_PreEnable;
11532            command = CUSTOM_CODE_PRE_ENABLE;
1157211533            break;
1157311534
1157411535         case kCustomLocation_Overclock:
11575            command = kCustomCode_OverClock;
11536            command = CUSTOM_CODE_OVER_CLOCK;
1157611537            break;
1157711538
1157811539         case kCustomLocation_RefreshRate:
11579            command = kCustomCode_RefreshRate;
11540            command = CUSTOM_CODE_REFRESH_RATE;
1158011541            break;
1158111542
1158211543         default:
r2821r2822
1158411545      }
1158511546   }
1158611547   else
11587      command = EXTRACT_FIELD(type, CodeType);
11548      command = cpu;
1158811549
1158911550   switch(command)
1159011551   {
11591      case kCustomCode_ActivationKey1:
11592      case kCustomCode_ActivationKey2:
11593         if(address < cheatListLength)
11552      case CUSTOM_CODE_ACTIVATION_KEY_1:
11553      case CUSTOM_CODE_ACTIVATION_KEY_2:
11554         if(address < cheat_list_length)
1159411555         {
11595            CheatEntry * entry = &cheatList[address];
11556            cheat_entry *entry = &cheat_list[address];
1159611557
11597            if(command == kCustomCode_ActivationKey1)
11558            if(command == CUSTOM_CODE_ACTIVATION_KEY_1)
1159811559            {
11599               entry->activationKey2 = data;
11560               entry->activation_key2 = data;
1160011561               entry->flags |= kCheatFlag_HasActivationKey2;
1160111562            }
1160211563            else
1160311564            {
11604               entry->activationKey1 = data;
11565               entry->activation_key1 = data;
1160511566               entry->flags |= kCheatFlag_HasActivationKey1;
1160611567            }
1160711568         }
1160811569         break;
1160911570
11610      case kCustomCode_PreEnable:
11611         if(address < cheatListLength)
11571      case CUSTOM_CODE_PRE_ENABLE:
11572         if(address < cheat_list_length)
1161211573         {
11613            CheatEntry * entry = &cheatList[address];
11574            cheat_entry *entry = &cheat_list[address];
1161411575
1161511576            ActivateCheat(entry);
1161611577
11617            if(data && (data < entry->actionListLength))
11578            if(data && data < entry->action_list_length)
1161811579               entry->selection = data;
1161911580         }
1162011581         break;
1162111582
11622      case kCustomCode_OverClock:
11623         if(VALID_CPU(cpu))
11583      case CUSTOM_CODE_OVER_CLOCK:
11584         if(VALID_CPU(address))
1162411585         {
11625            double   overclock = data / 65536.0;
11586            double   over_clock = data / 65536.0;
1162611587
11627            cpunum_set_clockscale(machine, address, overclock);
11588            cpunum_set_clockscale(machine, address, over_clock);
1162811589         }
1162911590         break;
1163011591
11631      case kCustomCode_RefreshRate:
11592      case CUSTOM_CODE_REFRESH_RATE:
1163211593         {
1163311594            int width      = video_screen_get_width(machine->primary_screen);
1163411595            int height      = video_screen_get_height(machine->primary_screen);
r2821r2822
1164211603   }
1164311604}
1164411605
11645/*----------------------------------------------------
11646  LoadCheatOption - load cheat option from database
11647----------------------------------------------------*/
11606/*------------------------------------------------------
11607  load_cheat_option - load cheat option from database
11608------------------------------------------------------*/
1164811609
11649static void LoadCheatOption(char * fileName)
11610static void load_cheat_option(char *file_name)
1165011611{
1165111612   static char      buf[2048];
11652   mame_file *      theFile;
11613   mame_file      *the_file;
1165311614   file_error      filerr;
11654   cheat_format *   format = &cheat_format_table[0];
11615   cheat_format   *format = &cheat_format_table[0];
1165511616
1165611617   /* open the database */
11657   filerr = mame_fopen(SEARCHPATH_CHEAT, fileName, OPEN_FLAG_READ, &theFile);
11618   filerr = mame_fopen(SEARCHPATH_CHEAT, file_name, OPEN_FLAG_READ, &the_file);
1165811619
1165911620   if(filerr != FILERR_NONE)
1166011621   {
11661      messageType      = kCheatMessage_FailedToLoadDatabase;
11662      messageTimer   = DEFAULT_MESSAGE_TIME;
11622      SET_MESSAGE(kCheatMessage_FailedToLoadDatabase);
1166311623      return;
1166411624   }
1166511625
11666   while(mame_fgets(buf, 2048, theFile))
11626   while(mame_fgets(buf, 2048, the_file))
1166711627   {
11668      char preCommand[9];
11628      char pre_command[9];
1166911629
11670      if(sscanf(buf, format->format_string, preCommand) == format->arguments_matched)
11630      if(sscanf(buf, format->format_string, pre_command) == format->arguments_matched)
1167111631      {
11672         if(strlen(preCommand) == format->length_matched)
11632         if(strlen(pre_command) == format->type_matched)
1167311633         {
11674            sscanf(preCommand, "%X", &cheatOptions);
11675            messageType      = kCheatMessage_ReloadCheatOption;
11676            messageTimer   = DEFAULT_MESSAGE_TIME;
11634            sscanf(pre_command, "%X", &cheat_options);
11635            SET_MESSAGE(kCheatMessage_ReloadCheatOption);
1167711636         }
1167811637      }
1167911638   }
1168011639
11681   mame_fclose(theFile);
11640   mame_fclose(the_file);
1168211641}
1168311642
11684/*------------------------------------------------
11685  LoadCheatCode - load cheat code from database
11686------------------------------------------------*/
11643/*--------------------------------------------------
11644  load_cheat_code - load cheat code from database
11645--------------------------------------------------*/
1168711646
11688static void LoadCheatCode(running_machine *machine, char * fileName)
11647static void load_cheat_code(running_machine *machine, char *file_name)
1168911648{
11690   enum{
11691      kFormatLevel_New = 1,
11692      kFormatLevel_Standard,
11693      kFormatLevel_Old };
11694
1169511649   char      buf[2048];
11696   mame_file   * theFile;
11650   mame_file   *the_file;
1169711651   file_error   filerr;
1169811652
1169911653   /* open the database */
11700   filerr = mame_fopen(SEARCHPATH_CHEAT, fileName, OPEN_FLAG_READ, &theFile);
11654   filerr = mame_fopen(SEARCHPATH_CHEAT, file_name, OPEN_FLAG_READ, &the_file);
1170111655
1170211656   if(filerr != FILERR_NONE)
1170311657      return;
1170411658
11705   foundCheatDatabase = 1;
11659   found_database = 1;
1170611660
1170711661   /* get a line from database */
11708   while(mame_fgets(buf, 2048, theFile))
11662   while(mame_fgets(buf, 2048, the_file))
1170911663   {
11710      int         i;
11664      int      i;
1171111665#ifdef MESS
11712      int         crc;
11666      int      crc;
1171311667#endif
11714      int         type = 0;
11715      int         address = 0;
11716      int         data = 0;
11717      int         extendData = 0;
11718      int         argumentsMatched = 0;
11719      int         formatLevel = 0;
11720      int         oldCPU = 0;
11721      int         oldCode = 0;
11722      char      name[16] = { 0 };
11723      char      preData[16] = { 0 };
11724      char      preExtendData[16] = { 0 };
11725      char      description[256] = { 0 };
11726      char      comment[256] = { 0 };
11727      CheatEntry   * entry;
11728      CheatAction   * action;
11668      int      type = 0;
11669      int      address = 0;
11670      int      data = 0;
11671      int      extend_data = 0;
11672      int      arguments_matched = 0;
11673      int      format_level = 0;
11674      int      cpu = 0;
11675      int      code = 0;
11676      char   name[16] = { 0 };
11677      char   pre_type[16] = { 0 };
11678      char   pre_data[16] = { 0 };
11679      char   pre_extend_data[16] = { 0 };
11680      char   description[256] = { 0 };
11681      char   comment[256] = { 0 };
1172911682
11683      cheat_entry      *entry;
11684      cheat_action   *action;
11685
1173011686      /* scan and check format */
1173111687      for(i = 1; i < 4; i++)
1173211688      {
11733         cheat_format * format = &cheat_format_table[i];
11689         cheat_format *format = &cheat_format_table[i];
1173411690
11691         if(TEST_FIELD(cheat_options, LoadOldFormat) == 0)
11692         {
11693            if(i != 1)
11694               break;
11695         }
11696
1173511697         /* scan a parameter */
1173611698         switch(i)
1173711699         {
11738            case kFormatLevel_New:
11739            case kFormatLevel_Standard:
11700            case FORMAT_NEW:
11701            case FORMAT_STANDARD:
1174011702#ifdef MESS
11741               argumentsMatched = sscanf(buf, format->format_string, name, &crc, &type, &address, preData, preExtendData, description, comment);
11703               arguments_matched = sscanf(buf, format->format_string, name, &crc, pre_type, &address, pre_data, pre_extend_data, description, comment);
1174211704#else
11743               argumentsMatched = sscanf(buf, format->format_string, name, &type, &address, preData, preExtendData, description, comment);
11705               arguments_matched = sscanf(buf, format->format_string, name, pre_type, &address, pre_data, pre_extend_data, description, comment);
1174411706#endif
1174511707               break;
1174611708
11747            case kFormatLevel_Old:
11709            case FORMAT_OLD:
1174811710#ifdef MESS
11749               argumentsMatched = sscanf(buf, format->format_string, &crc, name, &oldCPU, &address, &data, &oldCode, description, comment);
11711               arguments_matched = sscanf(buf, format->format_string, &crc, name, &cpu, &address, &data, &code, description, comment);
1175011712#else
11751               argumentsMatched = sscanf(buf, format->format_string, name, &oldCPU, &address, &data, &oldCode, description, comment);
11713               arguments_matched = sscanf(buf, format->format_string, name, &cpu, &address, &data, &code, description, comment);
1175211714#endif
1175311715         }
1175411716
1175511717         /* NOTE : description and comment are not always needed */
11756         if(argumentsMatched < format->arguments_matched)
11718         if(arguments_matched < format->arguments_matched)
1175711719            continue;
1175811720
1175911721#ifdef MESS
1176011722         /* check name */
11761         if(TEST_FIELD(cheatOptions, SharedCode) && strcmp(machine->gamedrv->parent, "0"))
11723         if(TEST_FIELD(cheat_options, SharedCode) && strcmp(machine->gamedrv->parent, "0"))
1176211724         {
1176311725            if(strcmp(name, machine->gamedrv->parent))
1176411726               break;
r2821r2822
1177211734         if(MatchesCRCTable(crc) == 0)
1177311735            break;
1177411736#endif
11775         if(i != kFormatLevel_Old)
11737         if(i != FORMAT_OLD)
1177611738         {
11777            UINT8 hasError = 0;
11739            UINT8 is_error = 0;
1177811740
11779            /* check the length of data and extendData */
11780            if(strlen(preData) != format->length_matched)
11741            /* check length */
11742            if(strlen(pre_type) != format->type_matched)
1178111743            {
11782               logerror("cheat - LoadCheatFile : %s has invalid extend data field length\n", description);
11783               messageType = kCheatMessage_WrongCode;
11784               hasError++;
11744               logerror("cheat: [load code] %s has invalid type field length (%X)\n", description, (int)strlen(pre_type));
11745               is_error++;
1178511746            }
1178611747
11787            if(strlen(preExtendData) != format->length_matched)
11748            if(strlen(pre_data) != format->data_matched)
1178811749            {
11789               logerror("cheat - LoadCheatFile : %s has invalid data field length\n", description);
11790               messageType = kCheatMessage_WrongCode;
11791               hasError++;
11750               logerror("cheat: [load code] %s has invalid data field length (%X)\n", description, (int)strlen(pre_type));
11751               is_error++;
1179211752            }
1179311753
11794            if(hasError)
11754            if(strlen(pre_extend_data) != format->data_matched)
11755            {
11756               logerror("cheat: [load code] %s has invalid extend data field length (%X)\n", description, (int)strlen(pre_extend_data));
11757               is_error++;
11758            }
11759
11760            if(is_error)
11761            {
11762               SET_MESSAGE(kCheatMessage_WrongCode);
1179511763               continue;
11764            }
1179611765            else
1179711766            {
11798               sscanf(preData, "%X", &data);
11799               sscanf(preExtendData, "%X", &extendData);
11767               if(i == FORMAT_NEW)
11768                  sscanf(pre_type, "%2X%8X", &cpu, &type);
11769               else
11770               {
11771                  sscanf(pre_type, "%X", &type);
11772                  cpu = EXTRACT_FIELD(type, LocationParameter) & 0x0F;
11773               }
11774
11775               sscanf(pre_data, "%X", &data);
11776               sscanf(pre_extend_data, "%X", &extend_data);
1180011777            }
1180111778         }
1180211779         else
11803            type = ConvertOldCode(oldCode, oldCPU, &data, &extendData);
11780            type = ConvertOldCode(code, cpu, &data, &extend_data);
1180411781
1180511782         /* matched! */
11806         formatLevel = i;
11783         format_level = i;
1180711784         break;
1180811785      }
1180911786
1181011787      /* attemp to get next line if unmatched */
11811      if(formatLevel == 0)
11788      if(format_level == 0 || format_level >= 4)
1181211789         continue;
1181311790
11814      //logerror("cheat: processing %s\n", buf);
11791      /* logerror("cheat: processing %s\n", buf); */
1181511792
1181611793      /* handle command code */
11817      if(formatLevel == kFormatLevel_New)
11794      if(cpu >= CUSTOM_CODE_ACTIVATION_KEY_1)
1181811795      {
11819         if(EXTRACT_FIELD(type, CPURegion) == CUSTOM_CODE && EXTRACT_FIELD(type, CodeType) >= kCustomCode_ActivationKey1)
11820         {
11821            // logerror("cheat: cheat line removed\n", buf);
11822            HandleLocalCommandCheat(machine, EXTRACT_FIELD(type, CPUIndex), type, address, data, formatLevel);
11823            continue;
11824         }
11796         /* logerror("cheat: cheat line removed\n", buf); */
11797         handle_local_command_cheat(machine, cpu, type, address, data, format_level);
11798         continue;
1182511799      }
11826      else
11827      {
11828         if(   EXTRACT_FIELD(type, LocationType) == kLocation_Custom &&
11829            EXTRACT_FIELD(type, LocationParameter) <= kCustomLocation_AssignActivationKey)
11830            {
11831               HandleLocalCommandCheat(machine, EXTRACT_FIELD(type, LocationParameter), type, address, data, formatLevel);
11832               continue;
11833            }
11834      }
1183511800
1183611801      /***** ENTRY *****/
1183711802      if(EXTRACT_FIELD(type, Link) == kLink_Master)
1183811803      {
1183911804         /* 1st (master) code in an entry */
11840         ResizeCheatList(cheatListLength + 1);
11805         resize_cheat_list(cheat_list_length + 1, REQUEST_DISPOSE);
1184111806
11842         if(cheatListLength == 0)
11807         if(cheat_list_length == 0)
1184311808         {
11844            logerror("cheat - LoadCheatFile: cheat list resize failed; bailing\n");
11809            logerror("cheat: [load code] cheat list resize failed. bailing\n");
1184511810            goto bail;
1184611811         }
1184711812
11848         entry = &cheatList[cheatListLength - 1];
11813         entry = &cheat_list[cheat_list_length - 1];
1184911814
1185011815         entry->name = create_string_copy(description);
1185111816
11852         if(argumentsMatched == cheat_format_table[formatLevel].comment_matched)
11817         if(arguments_matched == cheat_format_table[format_level].comment_matched)
1185311818            entry->comment = create_string_copy(comment);
1185411819      }
1185511820      else
1185611821      {
1185711822         /* 2nd or later (link) code in an entry */
11858         if(cheatListLength == 0)
11823         if(cheat_list_length == 0)
1185911824         {
11860            logerror("cheat - LoadCheatFile: first cheat found was link cheat; bailing\n");
11825            logerror("cheat: [load code] first cheat found was link cheat. bailing\n");
1186111826            goto bail;
1186211827         }
1186311828
11864         entry = &cheatList[cheatListLength - 1];
11829         entry = &cheat_list[cheat_list_length - 1];
1186511830      }
1186611831
1186711832      /***** ACTION *****/
11868      ResizeCheatActionList(&cheatList[cheatListLength - 1], entry->actionListLength + 1);
11833      resize_cheat_action_list(&cheat_list[cheat_list_length - 1], entry->action_list_length + 1, REQUEST_DISPOSE);
1186911834
11870      if(entry->actionListLength == 0)
11835      if(entry->action_list_length == 0)
1187111836      {
11872         logerror("cheat - LoadCheatFile: action list resize failed; bailing\n");
11837         logerror("cheat: [load code] action list resize failed. bailing\n");
1187311838         goto bail;
1187411839      }
1187511840
11876      action = &entry->actionList[entry->actionListLength - 1];
11841      action                  = &entry->action_list[entry->action_list_length - 1];
11842      action->flags            = 0;
11843      action->type            = type;
11844      action->region            = cpu;
11845      action->address            = address;
11846      action->original_address   = address;
11847      action->data            = data;
11848      action->original_data      = data;
11849      action->extend_data         = extend_data;
11850      action->optional_name      = create_string_copy(description);
11851      action->last_value         = NULL;
1187711852
11878      action->flags = 0;
11879      action->type = type;
11880      action->address = action->originalAddress = address;
11881      action->data = action->originalDataField = data;
11882      action->extendData = extendData;
11883      action->optionalName = create_string_copy(description);
11884      action->lastValue = NULL;
11885
11886      if(formatLevel != kFormatLevel_New)
11853      if(format_level != FORMAT_NEW)
1188711854         action->flags |= kActionFlag_OldFormat;
1188811855   }
1188911856
1189011857   bail:
1189111858
11892   /* close the database */
11893   mame_fclose(theFile);
11859   mame_fclose(the_file);
1189411860}
1189511861
11896/*--------------------------------------------------------------------------------
11897  LoadUserDefinedSearchRegion - load user region code and rebuild search region
11898--------------------------------------------------------------------------------*/
11862/*------------------------------------------------------------------------------------
11863  load_user_defined_search_region - load user region code and rebuild search region
11864------------------------------------------------------------------------------------*/
1189911865
11900static void LoadUserDefinedSearchRegion(running_machine *machine, char * fileName)
11866static void load_user_defined_search_region(running_machine *machine, char *file_name)
1190111867{
1190211868   int      count = 0;
1190311869   char   buf[2048];
1190411870
11905   search_info    *info = get_current_search();
11906   mame_file *      theFile;
11871   search_info    *info   = get_current_search();
11872   mame_file       *the_file;
1190711873   file_error      filerr;
11908   cheat_format *   format = &cheat_format_table[4];
11874   cheat_format    *format   = &cheat_format_table[4];
1190911875
1191011876   /* 1st, free all search regions in current search_info */
1191111877   dispose_search_reigons(info);
1191211878
1191311879   /* 2nd, attempt to open the memorymap file */
11914   filerr = mame_fopen(SEARCHPATH_CHEAT, fileName, OPEN_FLAG_READ, &theFile);
11880   filerr = mame_fopen(SEARCHPATH_CHEAT, file_name, OPEN_FLAG_READ, &the_file);
1191511881
1191611882   if(filerr != FILERR_NONE)
1191711883   {
11918      info->region_list_length   = 0;
11919      messageType            = kCheatMessage_FailedToLoadDatabase;
11920      messageTimer         = DEFAULT_MESSAGE_TIME;
11884      info->region_list_length = 0;
11885      SET_MESSAGE(kCheatMessage_FailedToLoadDatabase);
1192111886      return;
1192211887   }
1192311888
1192411889   /* 3rd, scan parameters from the file */
11925   while(mame_fgets(buf, 2048, theFile))
11890   while(mame_fgets(buf, 2048, the_file))
1192611891   {
1192711892#ifdef MESS
1192811893      int      crc;
r2821r2822
1193211897      int      start;
1193311898      int      end;
1193411899      int      status;
11935      char   name[9];
11936      char   description[64];
11900      char   name[16] = { 0 };
11901      char   description[64] = { 0 };
1193711902
1193811903      cpu_region_info *cpu_info;
1193911904      search_region   *region;
1194011905
11941      description[0] = 0;
11942
1194311906#ifdef MESS
1194411907      if(sscanf(buf, format->format_string, name, &crc, &cpu, &space, &start, &end, &status, description) < format->arguments_matched)
1194511908#else
r2821r2822
1194911912      else
1195011913      {
1195111914#ifdef MESS
11952         if(!MatchesCRCTable(crc))
11915         if(MatchesCRCTable(crc) == 0)
1195311916            continue;
1195411917#endif
1195511918         if(cpu != info->target_idx)
r2821r2822
1195911922      cpu_info = get_cpu_info(cpu);
1196011923
1196111924      /* check parameters */
11925      switch(space)
1196211926      {
11963         switch(space)
11964         {
11965            case kAddressSpace_Program:         // standard program space
11966            case kAddressSpace_DirectMemory:   // direct memory access for standard program space
11967               /* check length */
11968               if(start >= end)
11969               {
11970                  logerror("cheat - LoadUserDefinedSearchRegion : invalid length (start : %X >= end : %X) \n", start, end);
11971                  continue;
11972               }
11927         case kAddressSpace_Program:
11928         case kAddressSpace_DirectMemory:
11929            /* check length */
11930            if(start >= end)
11931            {
11932               logerror("cheat: [user region] invalid length (start : %.8X >= end : %.8X)\n", start, end);
11933               continue;
11934            }
1197311935
11974               /* check bound */
11975               if(end > cpu_info->address_mask)
11976               {
11977                  logerror("cheat - LoadUserDefinedSearchRegion : end address (%X) is out of range\n", end);
11978                  continue;
11979               }
11980               break;
11981
11982            case kAddressSpace_DataSpace:   // data space
11983            case kAddressSpace_IOSpace:      // I/O space
11984               // underconstruction...
11985               break;
11986
11987            default:
11988               logerror("cheat - LoadUserDefinedSearchRegion : %X is invalid space\n", space);
11936            /* check bound */
11937            if(is_search_region_in_range(info->target_idx, start + end + 1) == 0)
11938            {
11939               logerror("cheat: [user region] invalid length (%.8X)\n", start - end);
1198911940               continue;
11990         }
11941            }
11942            break;
1199111943
11992         /* check status */
11993         if(status > 1)
11994         {
11995            logerror("cheat - LoadUserDefinedSearchRegion : %X is invalid status\n", status);
11944         case kAddressSpace_DataSpace:
11945         case kAddressSpace_IOSpace:
11946            /* underconstruction... */
11947            break;
11948
11949         default:
11950            logerror("cheat: [user region] %X is invalid space\n", space);
1199611951            continue;
11997         }
1199811952      }
1199911953
11954      /* check status */
11955      if(status > kRegionFlag_Enabled)
11956      {
11957         logerror("cheat: [user region] %X is invalid status\n", status);
11958         continue;
11959      }
11960
1200011961      /* allocate memory for new search region */
1200111962      info->region_list = realloc(info->region_list, (count + 1) * sizeof(search_region));
1200211963
12003      if(!info->region_list)
11964      if(info->region_list == NULL)
1200411965      {
12005         /* memory allocation error */
12006         logerror("cheat - LoadUserDefinedSearchRegion: out of memory resizing search region\n");
12007         ui_popup_time(2, "out of memory while buiding user search region");
12008         info->region_list_length = 0;
12009         mame_fclose(theFile);
12010         return;
11966         mame_fclose(the_file);
11967         fatalerror(   "cheat: [user region] memory allocation error\n"
11968                  "   length =      %.8X\n"
11969                  "   region_list =   %p\n",
11970                  count + 1, info->region_list);
1201111971      }
1201211972
1201311973      region = &info->region_list[count];
r2821r2822
1204312003                        cpu_info->address_chars_needed, region->address + region->length - 1,
1204412004                        description);
1204512005
12006      if(is_search_region_in_range(cpu, region->length) == 0)
12007      {
12008         region->flags &= ~kRegionFlag_Enabled;
12009         region->flags |= kRegionFlag_HasError;
12010      }
12011      else
12012         region->flags = status;
12013
1204612014      count++;
1204712015   }
1204812016
1204912017   info->region_list_length = count;
1205012018
1205112019   if(info->region_list_length)
12052   {
12053      messageType      = kCheatMessage_ReloadUserRegion;
12054      messageTimer   = DEFAULT_MESSAGE_TIME;
12055   }
12020      SET_MESSAGE(kCheatMessage_ReloadUserRegion);
1205612021
12057   mame_fclose(theFile);
12022   mame_fclose(the_file);
1205812023}
1205912024
12060/*---------------------------------------------------------
12061  LoadCheatDatabase - get the database name then load it
12062---------------------------------------------------------*/
12025/*-----------------------------------------------------------
12026  load_cheat_database - get the database name then load it
12027-----------------------------------------------------------*/
1206312028
12064static void LoadCheatDatabase(running_machine *machine, UINT8 flags)
12029static void load_cheat_database(running_machine *machine, UINT8 flags)
1206512030{
1206612031   UINT8      first = 1;
12067
12068   char      buf[256];
12032   char      buf[256] = { 0 };
1206912033   char      data;
12070   const char   * inTraverse;
12071   char      * outTraverse;
12072   char      * mainTraverse;
12034   const char   *in_traverse;
12035   char      *out_traverse;
12036   char      *main_traverse;
1207312037
12074   cheatfile = options_get_string(mame_options(), OPTION_CHEAT_FILE);
12038   cheat_file = options_get_string(mame_options(), OPTION_CHEAT_FILE);
1207512039
12076   if (!cheatfile[0])
12077      cheatfile = "cheat.dat";
12040   if(cheat_file[0] == 0)
12041      cheat_file = "cheat.dat";
1207812042
12079   inTraverse      = cheatfile;
12080   outTraverse      = buf;
12081   mainTraverse   = mainDatabaseName;
12043   in_traverse      = cheat_file;
12044   out_traverse   = buf;
12045   main_traverse   = main_database_name;
1208212046
12083   buf[0] = 0;
12084
1208512047   do
1208612048   {
12087      data = *inTraverse;
12049      data = *in_traverse;
1208812050
1208912051      /* check separator or end */
12090      if(data == ';' || !data)
12052      if(data == ';' || data == 0)
1209112053      {
12092         *outTraverse++ = 0;
12054         *out_traverse++ = 0;
1209312055
1209412056         if(first)
12095            *mainTraverse++ = 0;
12057            *main_traverse++ = 0;
1209612058
1209712059         if(buf[0])
1209812060         {
1209912061            /* load database based on the name we gotten */
1210012062            if(flags & kLoadFlag_CheatOption)
12101               LoadCheatOption(buf);
12063               load_cheat_option(buf);
1210212064            if(flags & kLoadFlag_CheatCode)
12103               LoadCheatCode(machine, buf);
12065               load_cheat_code(machine, buf);
1210412066            if(flags & kLoadFlag_UserRegion)
12105               LoadUserDefinedSearchRegion(machine, buf);
12067               load_user_defined_search_region(machine, buf);
1210612068
12107            outTraverse   = buf;
12108            buf[0]      = 0;
12109            first      = 0;
12069            out_traverse   = buf;
12070            buf[0]         = 0;
12071            first         = 0;
1211012072            break;
1211112073         }
1211212074      }
1211312075      else
1211412076      {
12115         *outTraverse++ = data;
12077         *out_traverse++ = data;
1211612078
1211712079         if(first)
12118            *mainTraverse++ = data;
12080            *main_traverse++ = data;
1211912081      }
1212012082
12121      inTraverse++;
12083      in_traverse++;
1212212084   }
1212312085   while(data);
1212412086
12125   UpdateAllCheatInfo();
12087   update_all_cheat_info();
1212612088}
1212712089
12128/*---------------------------------------------------------------------------------------
12129  DisposeCheatDatabase - deactivate all cheats when reload a code or exit cheat system
12130---------------------------------------------------------------------------------------*/
12090/*---------------------------------------------------------------------------
12091  reload_cheat_database - reload cheat database directly on the cheat menu
12092---------------------------------------------------------------------------*/
1213112093
12132static void DisposeCheatDatabase(void)
12094static void reload_cheat_database(running_machine *machine)
1213312095{
12096   dispose_cheat_database();
12097   load_cheat_database(machine, kLoadFlag_CheatCode);
12098
12099   SET_MESSAGE(found_database ? kCheatMessage_ReloadCheatCode : kCheatMessage_FailedToLoadDatabase);
12100}
12101
12102/*-------------------------------------------------
12103  dispose_cheat_database - free all cheat entries
12104-------------------------------------------------*/
12105
12106static void dispose_cheat_database(void)
12107{
1213412108   int i;
1213512109
1213612110   /* first, turn all cheats "OFF" */
12137   for(i = 0; i < cheatListLength; i++)
12138      TempDeactivateCheat(&cheatList[i]);
12111   for(i = 0; i < cheat_list_length; i++)
12112      TempDeactivateCheat(&cheat_list[i]);
1213912113
1214012114   /* next, free memory for all cheat entries */
12141   if(cheatList)
12115   if(cheat_list)
1214212116   {
12143      for(i = 0; i < cheatListLength; i++)
12144         DisposeCheat(&cheatList[i]);
12117      for(i = 0; i < cheat_list_length; i++)
12118         dispose_cheat(&cheat_list[i]);
1214512119
12146      free(cheatList);
12120      free(cheat_list);
1214712121
12148      cheatList = NULL;
12149      cheatListLength = 0;
12122      cheat_list = NULL;
12123      cheat_list_length = 0;
1215012124   }
1215112125}
1215212126
12153/*-------------------------------------------------------------------------
12154  ReloadCheatDatabase - reload cheat database directly on the cheat menu
12155-------------------------------------------------------------------------*/
12156
12157static void ReloadCheatDatabase(running_machine *machine)
12158{
12159   DisposeCheatDatabase();
12160   LoadCheatDatabase(machine, kLoadFlag_CheatCode);
12161
12162   if(foundCheatDatabase)
12163      messageType   = kCheatMessage_ReloadCheatCode;
12164   else
12165      messageType   = kCheatMessage_FailedToLoadDatabase;
12166
12167   messageTimer   = DEFAULT_MESSAGE_TIME;
12168}
12169
1217012127/*------------------------------------------------------
1217112128  SaveCheatCode - save a cheat code into the database
1217212129------------------------------------------------------*/
1217312130
12174static void SaveCheatCode(running_machine *machine, CheatEntry * entry)
12131static void SaveCheatCode(running_machine *machine, cheat_entry *entry)
1217512132{
12176#ifdef MESS
12133#if 0
1217712134   INT8   i;
1217812135   INT8   error = 0;
1217912136   char   buf[4096];
r2821r2822
1218112138   mame_file *   theFile;
1218212139   file_error   filerr;
1218312140
12184   if(!entry || !entry->actionList || ((entry->flags & kCheatFlag_Select) && entry->actionListLength == 1))
12141   if(entry == NULL || entry->action_list == NULL || ((entry->flags & kCheatFlag_Select) && entry->action_list_length == 1))
1218512142      error = 1;
1218612143
1218712144   /* open the database */
1218812145   if(!error)
1218912146   {
12190      filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE, &theFile);
12147      filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE, &theFile);
1219112148
1219212149      if(!theFile)
1219312150         error = 1;
1219412151      else if(filerr != FILERR_NONE)
1219512152      {
12196         filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
12153         filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
1219712154
1219812155         if(filerr != FILERR_NONE)
1219912156            error = 1;
r2821r2822
1220212159
1220312160   if(error)
1220412161   {
12205      messageType = kCheatMessage_FailedToSave;
12206      messageTimer = DEFAULT_MESSAGE_TIME;
12162      SET_MESSAGE(kCheatMessage_FailedToSave);
1220712163      return;
1220812164   }
1220912165
1221012166   mame_fseek(theFile, 0, SEEK_END);
1221112167
1221212168   /* write the code to the database */
12213   for(i = 0; i < entry->actionListLength; i++)
12169   for(i = 0; i < entry->action_list_length; i++)
1221412170   {
1221512171      UINT8      addressLength   = 8;
1221612172      char      * name;
1221712173      char      * bufTraverse   = buf;
1221812174
12219      CheatAction   * action      = &entry->actionList[i];
12175      cheat_action *action = &entry->action_list[i];
1222012176
1222112177      /* get name */
1222212178      if(!i)
1222312179         name = entry->name;
1222412180      else
12225         name = action->optionalName;
12181         name = action->optional_name;
1222612182
1222712183      /* get address length of CPU/Region */
1222812184      addressLength = get_address_length(EXTRACT_FIELD(action->type, CPURegion));
r2821r2822
1223412190                  thisGameCRC,
1223512191                  action->type,
1223612192                  addressLength,
12237                  action->originalAddress,
12238                  action->originalDataField,
12239                  action->extendData);
12193                  action->original_address,
12194                  action->original_data,
12195                  action->extend_data);
1224012196#else
1224112197      bufTraverse +=   sprintf(bufTraverse, ">%s:%.8X:%.*X:%.8X:%.8X",
1224212198                  machine->gamedrv->name,
1224312199                  action->type,
1224412200                  addressLength,
12245                  action->originalAddress,
12246                  action->originalDataField,
12247                  action->extendData);
12201                  action->original_address,
12202                  action->original_data,
12203                  action->extend_data);
1224812204#endif
1224912205      /* set name */
1225012206      if(name)
r2821r2822
1227712233   /* clear dirty flag as "this entry is already saved" */
1227812234   entry->flags &= ~kCheatFlag_Dirty;
1227912235
12280   messageType = kCheatMessage_SucceededToSave;
12281   messageTimer = DEFAULT_MESSAGE_TIME;
12282#endif
12236   SET_MESSAGE(kCheatMessage_SucceededToSave);
12237#else
1228312238   SaveDescription(machine);
12239#endif
1228412240}
1228512241
1228612242/*-----------------------------------------------------------------
1228712243  SaveActivationKey - save activation key code into the database
1228812244-----------------------------------------------------------------*/
1228912245
12290static void SaveActivationKey(running_machine *machine, CheatEntry * entry, int entryIndex)
12246static void SaveActivationKey(running_machine *machine, cheat_entry *entry, int entryIndex)
1229112247{
12248#if 0
1229212249   INT8   i;
1229312250   INT8   error = 0;
1229412251   char   buf[4096];
1229512252
12296   mame_file *   theFile = NULL;
12253   mame_file *   theFile;
1229712254   file_error   filerr;
1229812255
1229912256   if(!(entry->flags & kCheatFlag_HasActivationKey1) && !(entry->flags & kCheatFlag_HasActivationKey2))
1230012257      error = 1;
1230112258
12302   if(!error && (!entry || !entry->actionList || ((entry->flags & kCheatFlag_Select) && entry->actionListLength == 1)))
12259   if(error == 0 && (entry == NULL || entry->action_list == NULL || ((entry->flags & kCheatFlag_Select) && entry->action_list_length == 1)))
1230312260      error = 2;
1230412261
1230512262   /* open the database */
1230612263   if(!error)
1230712264   {
12308      filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE, &theFile);
12265      filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE, &theFile);
1230912266
1231012267      if(!theFile)
1231112268         error = 2;
1231212269      else if(filerr != FILERR_NONE)
1231312270      {
12314         filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
12271         filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
1231512272
1231612273         if(filerr != FILERR_NONE)
1231712274            error = 2;
r2821r2822
1232112278   switch(error)
1232212279   {
1232312280      case 1:
12324         messageType = kCheatMessage_NoActivationKey;
12325         messageTimer = DEFAULT_MESSAGE_TIME;
12281         SET_MESSAGE(kCheatMessage_NoActivationKey);
1232612282         return;
1232712283
1232812284      case 2:
12329         messageType = kCheatMessage_FailedToSave;
12330         messageTimer = DEFAULT_MESSAGE_TIME;
12285         SET_MESSAGE(kCheatMessage_FailedToSave);
1233112286         return;
1233212287   }
1233312288
r2821r2822
1233712292   for(i = 0; i < 2; i++)
1233812293   {
1233912294      int      addressLength   = 8;
12340      int      activationKey   = !i ? entry->activationKey1 : entry->activationKey2;
12295      int      activationKey   = !i ? entry->activation_key1 : entry->activation_key2;
1234112296      int      type         = 0;
1234212297      char   * bufTraverse   = buf;
1234312298
12344      CheatAction   * action = &entry->actionList[0];
12345      astring      * name = input_code_name(astring_alloc(), activationKey);
12299      cheat_action   *action = &entry->action_list[0];
12300      astring         *name = input_code_name(astring_alloc(), activationKey);
1234612301
12347      /* set the flag in type field */
12348      SET_FIELD(type, CPURegion, CUSTOM_CODE);
12349
1235012302      if(activationKey)
12351         SET_FIELD(type, CodeType, kCustomCode_ActivationKey1);
12303         SET_FIELD(type, CodeType, CUSTOM_CODE_ACTIVATION_KEY_1);
1235212304      else
12353         SET_FIELD(type, CodeType, kCustomCode_ActivationKey2);
12305         SET_FIELD(type, CodeType, CUSTOM_CODE_ACTIVATION_KEY_2);
1235412306
1235512307      /* get address length of CPU/Region */
12356      addressLength = get_address_length(EXTRACT_FIELD(action->type, CPURegion));
12308      addressLength = get_address_length(action->region);
1235712309
1235812310      /* if not find 1st activation key at saving 1st key, try to save 2nd key */
1235912311      if(!i && !(entry->flags & kCheatFlag_HasActivationKey1))
r2821r2822
1241712369   /* close the database */
1241812370   mame_fclose(theFile);
1241912371
12420   messageType = kCheatMessage_ActivationKeySaved;
12421   messageTimer = DEFAULT_MESSAGE_TIME;
12372   SET_MESSAGE(kCheatMessage_ActivationKeySaved);
12373#endif
1242212374}
1242312375
1242412376/*-----------------------------------------------------------
1242512377  SavePreEnable - save a pre-enable code into the database
1242612378-----------------------------------------------------------*/
1242712379
12428static void SavePreEnable(running_machine *machine, CheatEntry * entry, int entryIndex)
12380static void SavePreEnable(running_machine *machine, cheat_entry *entry, int entryIndex)
1242912381{
12382#if 0
1243012383   int      type         = 0;
1243112384   INT8   error         = 0;
1243212385   INT8   addressLength   = 8;
1243312386   char   buf[4096];
1243412387   char   * bufTraverse   = buf;
1243512388
12436   CheatAction      * action = &entry->actionList[0];
12437   mame_file *      theFile = NULL;
12389   cheat_action   *action = &entry->action_list[0];
12390   mame_file      *theFile;
1243812391   file_error      filerr;
1243912392
12440   if(!entry || !entry->actionList || ((entry->flags & kCheatFlag_Select) && entry->actionListLength == 1))
12393   if(entry == NULL || entry->action_list == NULL || ((entry->flags & kCheatFlag_Select) && entry->action_list_length == 1))
1244112394      error = 1;
1244212395
1244312396   /* open the database */
1244412397   if(!error)
1244512398   {
12446      filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE, &theFile);
12399      filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE, &theFile);
1244712400
1244812401      if(!theFile)
1244912402         error = 1;
1245012403      else if(filerr != FILERR_NONE)
1245112404      {
12452         filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
12405         filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
1245312406
1245412407         if(filerr != FILERR_NONE)
1245512408            error = 1;
r2821r2822
1245812411
1245912412   if(error)
1246012413   {
12461      messageType = kCheatMessage_FailedToSave;
12462      messageTimer = DEFAULT_MESSAGE_TIME;
12414      SET_MESSAGE(kCheatMessage_FailedToSave);
1246312415      return;
1246412416   }
1246512417   else
1246612418   {
12467      SET_FIELD(type, CPURegion, CUSTOM_CODE);
12468      SET_FIELD(type, CodeType, kCustomCode_PreEnable);
12419      SET_FIELD(type, CodeType, CUSTOM_CODE_PRE_ENABLE);
1246912420   }
1247012421
1247112422   mame_fseek(theFile, 0, SEEK_END);
r2821r2822
1249812449
1249912450   /* set label name */
1250012451   if(entry->selection)
12501      bufTraverse += sprintf(bufTraverse, " Label - %s", entry->actionList[entry->labelIndex[entry->selection]].optionalName);
12452      bufTraverse += sprintf(bufTraverse, " Label - %s", entry->action_list[entry->label_index[entry->selection]].optional_name);
1250212453
1250312454   bufTraverse += sprintf(bufTraverse, "\n");
1250412455
r2821r2822
1250812459   /* close the database */
1250912460   mame_fclose(theFile);
1251012461
12511   messageType = kCheatMessage_PreEnableSaved;
12512   messageTimer = DEFAULT_MESSAGE_TIME;
12462   SET_MESSAGE(kCheatMessage_PreEnableSaved);
12463#endif
1251312464}
1251412465
1251512466/*--------------------------------------------------------------
12516  SaveCheatOptions - save cheat option code into the database
12467  Savecheat_options - save cheat option code into the database
1251712468--------------------------------------------------------------*/
1251812469
12519static void SaveCheatOptions(void)
12470static void Savecheat_options(void)
1252012471{
1252112472   UINT8      error = 0;
1252212473   char      buf[32];
r2821r2822
1252512476   file_error      filerr;
1252612477
1252712478   /* open the database */
12528   filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE, &theFile);
12479   filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE, &theFile);
1252912480
1253012481   if(!theFile)
1253112482      error = 1;
1253212483   else if(filerr != FILERR_NONE)
1253312484   {
12534      filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
12485      filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
1253512486
1253612487      if(filerr != FILERR_NONE)
1253712488         error = 1;
r2821r2822
1253912490
1254012491   if(error)
1254112492   {
12542      messageType = kCheatMessage_FailedToSave;
12543      messageTimer = DEFAULT_MESSAGE_TIME;
12493      SET_MESSAGE(kCheatMessage_FailedToSave);
1254412494      return;
1254512495   }
1254612496
1254712497   mame_fseek(theFile, 0, SEEK_END);
1254812498
12549   sprintf(buf, ":_command:%.8X\n", cheatOptions);
12499   sprintf(buf, ":_command:%.8X\n", cheat_options);
1255012500
1255112501   /* write the command code */
1255212502   mame_fwrite(theFile, buf, (UINT32)strlen(buf));
r2821r2822
1255412504   /* close the database */
1255512505   mame_fclose(theFile);
1255612506
12557   messageType = kCheatMessage_SucceededToSave;
12558   messageTimer = DEFAULT_MESSAGE_TIME;
12507   SET_MESSAGE(kCheatMessage_SucceededToSave);
1255912508}
1256012509
1256112510/*------------------
r2821r2822
1257012519   mame_file *      theFile;
1257112520   file_error      filerr;
1257212521
12573   filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE, &theFile);
12522   filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE, &theFile);
1257412523
1257512524   if(!theFile)
1257612525      error = 1;
1257712526   else if(filerr != FILERR_NONE)
1257812527   {
12579      filerr = mame_fopen(SEARCHPATH_CHEAT, mainDatabaseName, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
12528      filerr = mame_fopen(SEARCHPATH_CHEAT, main_database_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &theFile);
1258012529
1258112530      if(filerr != FILERR_NONE)
1258212531         error = 1;
r2821r2822
1258412533
1258512534   if(error)
1258612535   {
12587      messageType = kCheatMessage_FailedToSave;
12588      messageTimer = DEFAULT_MESSAGE_TIME;
12536      SET_MESSAGE(kCheatMessage_FailedToSave);
1258912537      return;
1259012538   }
1259112539
1259212540   mame_fseek(theFile, 0, SEEK_END);
12593   sprintf(buf, "> [ %s ]\n", machine->gamedrv->description);
12541   sprintf(buf, "; [ %s ]\n", machine->gamedrv->description);
1259412542
1259512543   /* write the command code */
1259612544   mame_fwrite(theFile, buf, (UINT32)strlen(buf));
r2821r2822
1259812546   /* close the database */
1259912547   mame_fclose(theFile);
1260012548
12601   messageType = kCheatMessage_SucceededToSave;
12602   messageTimer = DEFAULT_MESSAGE_TIME;
12549   SET_MESSAGE(kCheatMessage_SucceededToSave);
1260312550}
1260412551
1260512552/*--------------------------------------------------------------------------
r2821r2822
1261012557{
1261112558   int i;
1261212559
12613   for(i = 0; i < cheatListLength; i++)
12560   for(i = 0; i < cheat_list_length; i++)
1261412561   {
12615      CheatEntry * entry = &cheatList[i];
12562      cheat_entry *entry = &cheat_list[i];
1261612563
1261712564      /* if the entry is not edited/added newly or has not been already saved, save it */
1261812565      if(entry->flags & kCheatFlag_Dirty)
r2821r2822
1262812575{
1262912576   if((region->target_type == kRegionType_CPU) || (region->target_type == kRegionType_Memory))
1263012577   {
12631      CheatEntry   * entry = GetNewCheat();
12632      CheatAction   * action = &entry->actionList[0];
12633      char      tempString[1024];
12634      int         tempStringLength;
12635      UINT32      data = read_search_operand(kSearchOperand_First, search, region, address);
12578      cheat_entry      *entry      = get_new_cheat();
12579      cheat_action   *action      = &entry->action_list[0];
12580      char         tempString[1024];
12581      int            tempStringLength;
12582      UINT32         data = read_search_operand(kSearchOperand_First, search, region, address);
1263612583
1263712584      tempStringLength = sprintf(tempString, "%.8X (%d) = %.*X", address, region->target_idx, kSearchByteDigitsTable[search->bytes], data);
1263812585
1263912586      entry->name = realloc(entry->name, tempStringLength + 1);
1264012587      memcpy(entry->name, tempString, tempStringLength + 1);
1264112588
12642      SET_FIELD(action->type, CPURegion, region->target_idx);
12589      action->region         = region->target_idx;
12590      action->address         = address;
12591      action->data         = data;
12592      action->original_data   = data;
12593      action->extend_data      = 0xFFFFFFFF;
12594      action->last_value      = NULL;
12595
1264312596      SET_FIELD(action->type, AddressSize, kSearchByteIncrementTable[search->bytes] - 1);
12644      action->address = address;
12645      action->data = action->originalDataField = data;
12646      action->extendData = 0xFFFFFFFF;
12647      action->lastValue = NULL;
1264812597
12649      UpdateCheatInfo(entry, 0);
12598      update_cheat_info(entry, 0);
1265012599   }
1265112600}
1265212601
r2821r2822
1268812637{
1268912638   if(region->target_type == kRegionType_CPU || region->target_type == kRegionType_Memory)
1269012639   {
12691      WatchInfo * info = GetUnusedWatch();
12640      watch_info *info = get_unused_watch();
1269212641
1269312642      info->address         = address;
1269412643      info->cpu            = region->target_idx;
12695      info->numElements      = 1;
12696      info->elementBytes      = kWatchSizeConversionTable[search->bytes];
12697      info->labelType         = kWatchLabel_None;
12698      info->displayType      = kWatchDisplayType_Hex;
12644      info->num_elements      = 1;
12645      info->element_bytes      = kWatchSizeConversionTable[search->bytes];
12646      info->label_type      = kWatchLabel_None;
12647      info->display_type      = kWatchDisplayType_Hex;
1269912648      info->skip            = 0;
12700      info->elementsPerLine   = 0;
12701      info->addValue         = 0;
12702      info->linkedCheat      = NULL;
12649      info->elements_per_line   = 0;
12650      info->add_value         = 0;
12651      info->linked_cheat      = NULL;
1270312652      info->label[0]         = 0;
1270412653
12705      messageType      = kCheatMessage_SucceededToAdd;
12706      messageTimer   = DEFAULT_MESSAGE_TIME;
12654      SET_MESSAGE(kCheatMessage_SucceededToAdd);
1270712655   }
1270812656   else
12709   {
12710      messageType      = kCheatMessage_FailedToAdd;
12711      messageTimer   = DEFAULT_MESSAGE_TIME;
12712   }
12657      SET_MESSAGE(kCheatMessage_FailedToAdd);
1271312658}
1271412659
1271512660/*---------------------
r2821r2822
1343713382  ReadData
1343813383-----------*/
1343913384
13440static UINT32 ReadData(CheatAction * action)
13385static UINT32 ReadData(cheat_action *action)
1344113386{
1344213387   UINT8   addressRead      = EXTRACT_FIELD(action->type, AddressRead);
1344313388   UINT8   bytes         = EXTRACT_FIELD(action->type, AddressSize) + 1;
r2821r2822
1345013395      if(addressRead == kReadFrom_Address)      address = action->address;
1345113396      else if(addressRead == kReadFrom_Index)      address = cheatVariable[action->address];
1345213397
13453      if(!TEST_FIELD(action->region, RegionFlag))
13398      if(action->region < REGION_INVALID)
1345413399      {
1345513400         /* read a data from CPU */
1345613401         UINT8 cpu = EXTRACT_FIELD(action->region, CPUIndex);
r2821r2822
1346413409
1346513410                  cpu_region_info *info = get_cpu_info(cpu);
1346613411
13467                  indexAddress = DoCPURead(cpu, address, EXTRACT_FIELD(action->type, IndexSize) + 1, cpu_needs_swap(cpu));
13412                  indexAddress = DoCPURead(cpu, address, EXTRACT_FIELD(action->type, CodeParameterLower) + 1, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness));
1346813413
1346913414                  if(info && info->address_shift)
1347013415                     indexAddress = DoShift(indexAddress, info->address_shift);
1347113416
1347213417                  if(indexAddress)
1347313418                  {
13474                     indexAddress += action->extendData;
13475                     return DoCPURead(cpu, indexAddress, bytes, cpu_needs_swap(cpu));
13419                     indexAddress += action->extend_data;
13420                     return DoCPURead(cpu, indexAddress, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness));
1347613421                  }
1347713422               }
1347813423               else if(action->flags & kActionFlag_PDWWrite)
r2821r2822
1348013425                  if(action->flags & kActionFlag_IsFirst)
1348113426                  {
1348213427                     address += bytes;
13483                     bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13428                     bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1348413429                     action->flags &= ~kActionFlag_IsFirst;
1348513430                  }
1348613431                  else
1348713432                     action->flags |= kActionFlag_IsFirst;
1348813433
13489                  return DoCPURead(cpu, address, bytes, cpu_needs_swap(cpu));
13434                  return DoCPURead(cpu, address, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness));
1349013435               }
1349113436               else
1349213437               {
13493                  return DoCPURead(cpu, address, bytes, cpu_needs_swap(cpu));
13438                  return DoCPURead(cpu, address, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness));
1349413439               }
1349513440               break;
1349613441
r2821r2822
1350113446               {
1350213447                  UINT8 * buf;
1350313448
13504                  action->cachedPointer = GetMemoryRegionBasePointer(cpu, EXTRACT_FIELD(action->type, AddressSpace), address);
13505                  buf = (UINT8 *) action->cachedPointer;
13449                  action->cached_pointer = GetMemoryRegionBasePointer(cpu, EXTRACT_FIELD(action->type, AddressSpace), address);
13450                  buf = (UINT8 *) action->cached_pointer;
1350613451
1350713452                  if(buf)
1350813453                  {
r2821r2822
1351113456                        if(action->flags & kActionFlag_IsFirst)
1351213457                        {
1351313458                           address += bytes;
13514                           bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13459                           bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1351513460                           action->flags &= ~kActionFlag_IsFirst;
1351613461                        }
1351713462                        else
1351813463                           action->flags |= kActionFlag_IsFirst;
1351913464                     }
1352013465
13521                     return DoMemoryRead(buf, address, bytes, cpu_needs_swap(cpu), get_cpu_info(cpu));
13466                     return DoMemoryRead(buf, address, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness), get_cpu_info(cpu));
1352213467                  }
1352313468               }
1352413469               break;
1352513470
1352613471            case kAddressSpace_MappedMemory:
1352713472               {
13528                  int         relativeAddress;
13529                  UINT8 **   buf;
13473                  int      relativeAddress;
13474                  UINT8   **buf;
1353013475
13531                  action->cachedPointer = LookupHandlerMemory(cpu, address, &action->cachedOffset);
13532                  buf = action->cachedPointer;
13533                  relativeAddress = action->cachedOffset;
13476                  action->cached_pointer = LookupHandlerMemory(cpu, address, &action->cached_offset);
13477                  buf = action->cached_pointer;
13478                  relativeAddress = action->cached_offset;
1353413479
1353513480                  if(buf && *buf)
1353613481                  {
r2821r2822
1353913484                        if(action->flags & kActionFlag_IsFirst)
1354013485                        {
1354113486                           relativeAddress += bytes;
13542                           bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13487                           bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1354313488                           action->flags &= ~kActionFlag_IsFirst;
1354413489                        }
1354513490                        else
1354613491                           action->flags |= kActionFlag_IsFirst;
1354713492                     }
1354813493
13549                     return DoMemoryRead(*buf, relativeAddress, bytes, cpu_needs_swap(cpu), get_cpu_info(cpu));
13494                     return DoMemoryRead(*buf, relativeAddress, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness), get_cpu_info(cpu));
1355013495                  }
1355113496               }
1355213497               break;
r2821r2822
1355413499            case kAddressSpace_EEPROM:
1355513500               {
1355613501                  int      length;
13557                  UINT8 *   buf;
13502                  UINT8   *buf;
1355813503
1355913504                  buf = eeprom_get_data_pointer(&length);
1356013505
13561                  if(IsAddressInRange(action, length))
13506                  if(is_address_in_range(action, length))
1356213507                  {
1356313508                     if(action->flags & kActionFlag_PDWWrite)
1356413509                     {
1356513510                        if(action->flags & kActionFlag_IsFirst)
1356613511                        {
1356713512                           address += bytes;
13568                           bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13513                           bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1356913514                           action->flags &= ~kActionFlag_IsFirst;
1357013515                        }
1357113516                        else
r2821r2822
1358313528         /* read a data from region */
1358413529         UINT8 * buf = memory_region(action->region);
1358513530
13586         if(buf && IsAddressInRange(action, memory_region_length(action->region)))
13531         if(buf && is_address_in_range(action, memory_region_length(action->region)))
1358713532         {
1358813533            if(action->flags & kActionFlag_PDWWrite)
1358913534            {
1359013535               if(action->flags & kActionFlag_IsFirst)
1359113536               {
1359213537                  address += bytes;
13593                  bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13538                  bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1359413539                  action->flags &= ~kActionFlag_IsFirst;
1359513540               }
1359613541               else
1359713542                  action->flags |= kActionFlag_IsFirst;
1359813543
13599               return DoMemoryRead(buf, address, bytes, region_needs_swap(action->region), get_region_info(action->region));
13544               return DoMemoryRead(buf, address, bytes, region_needs_swap(action->region) ^ EXTRACT_FIELD(action->type, Endianness), get_region_info(action->region));
1360013545            }
1360113546            else
13602               return DoMemoryRead(buf, address, bytes, region_needs_swap(action->region), get_region_info(action->region));
13547               return DoMemoryRead(buf, address, bytes, region_needs_swap(action->region) ^ EXTRACT_FIELD(action->type, Endianness), get_region_info(action->region));
1360313548         }
1360413549      }
1360513550   }
r2821r2822
1361413559  WriteData - write a data to memory
1361513560-------------------------------------*/
1361613561
13617static void WriteData(CheatAction * action, UINT32 data)
13562static void WriteData(cheat_action *action, UINT32 data)
1361813563{
1361913564   UINT8   addressRead =   EXTRACT_FIELD(action->type, AddressRead);
1362013565   UINT8   bytes =         EXTRACT_FIELD(action->type, AddressSize) + 1;
r2821r2822
1362713572      if(addressRead == kReadFrom_Address)      address = action->address;
1362813573      else if(addressRead == kReadFrom_Index)      address = cheatVariable[action->address];
1362913574
13630      if(!TEST_FIELD(action->region, RegionFlag))
13575      if(action->region < REGION_INVALID)
1363113576      {
1363213577         UINT8 cpu = EXTRACT_FIELD(action->region, CPUIndex);
1363313578
r2821r2822
1364013585
1364113586                  cpu_region_info *info = get_cpu_info(cpu);
1364213587
13643                  indexAddress = DoCPURead(cpu, address, EXTRACT_FIELD(action->type, IndexSize) + 1, cpu_needs_swap(cpu));
13588                  indexAddress = DoCPURead(cpu, address, EXTRACT_FIELD(action->type, CodeParameterLower) + 1, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness));
1364413589
1364513590                  if(info && info->address_shift)
1364613591                     indexAddress = DoShift(indexAddress, info->address_shift);
1364713592
1364813593                  if(indexAddress)
1364913594                  {
13650                     indexAddress += action->extendData;
13651                     DoCPUWrite(data, cpu, indexAddress, bytes, cpu_needs_swap(cpu));
13595                     indexAddress += action->extend_data;
13596                     DoCPUWrite(data, cpu, indexAddress, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness));
1365213597                  }
1365313598               }
1365413599               else if(action->flags & kActionFlag_PDWWrite)
r2821r2822
1365613601                  if(action->flags & kActionFlag_IsFirst)
1365713602                  {
1365813603                     address += bytes;
13659                     bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13604                     bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1366013605                     action->flags &= ~kActionFlag_IsFirst;
1366113606                  }
1366213607                  else
1366313608                     action->flags |= kActionFlag_IsFirst;
1366413609
13665                  DoCPUWrite(data, cpu, address, bytes, cpu_needs_swap(cpu));
13610                  DoCPUWrite(data, cpu, address, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness));
1366613611               }
1366713612               else
1366813613               {
13669                  DoCPUWrite(data, cpu, address, bytes, cpu_needs_swap(cpu));
13614                  DoCPUWrite(data, cpu, address, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness));
1367013615               }
1367113616               break;
1367213617
r2821r2822
1367713622               {
1367813623                  UINT8 * buf;
1367913624
13680                  action->cachedPointer = GetMemoryRegionBasePointer(cpu, EXTRACT_FIELD(action->type, AddressSpace), address);
13681                  buf = (UINT8 *) action->cachedPointer;
13625                  action->cached_pointer = GetMemoryRegionBasePointer(cpu, EXTRACT_FIELD(action->type, AddressSpace), address);
13626                  buf = (UINT8 *) action->cached_pointer;
1368213627
1368313628                  if(buf)
1368413629                  {
r2821r2822
1368713632                        if(action->flags & kActionFlag_IsFirst)
1368813633                        {
1368913634                           address += bytes;
13690                           bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13635                           bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1369113636                           action->flags &= ~kActionFlag_IsFirst;
1369213637                        }
1369313638                        else
1369413639                           action->flags |= kActionFlag_IsFirst;
1369513640                     }
1369613641
13697                     DoMemoryWrite(data, buf, address, bytes, cpu_needs_swap(cpu), get_cpu_info(cpu));
13642                     DoMemoryWrite(data, buf, address, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness), get_cpu_info(cpu));
1369813643                  }
1369913644               }
1370013645               break;
r2821r2822
1370413649                  int         relativeAddress;
1370513650                  UINT8 **   buf;
1370613651
13707                  action->cachedPointer = LookupHandlerMemory(cpu, address, &action->cachedOffset);
13708                  buf = action->cachedPointer;
13709                  relativeAddress = action->cachedOffset;
13652                  action->cached_pointer = LookupHandlerMemory(cpu, address, &action->cached_offset);
13653                  buf = action->cached_pointer;
13654                  relativeAddress = action->cached_offset;
1371013655
1371113656                  if(buf && *buf)
1371213657                  {
r2821r2822
1371513660                        if(action->flags & kActionFlag_IsFirst)
1371613661                        {
1371713662                           relativeAddress += bytes;
13718                           bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13663                           bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1371913664                           action->flags &= ~kActionFlag_IsFirst;
1372013665                        }
1372113666                        else
1372213667                           action->flags |= kActionFlag_IsFirst;
1372313668                     }
1372413669
13725                     DoMemoryWrite(data, *buf, relativeAddress, bytes, cpu_needs_swap(cpu), get_cpu_info(cpu));
13726                     return;
13670                     DoMemoryWrite(data, *buf, relativeAddress, bytes, cpu_needs_swap(cpu) ^ EXTRACT_FIELD(action->type, Endianness), get_cpu_info(cpu));
1372713671                  }
1372813672               }
1372913673               break;
r2821r2822
1373513679
1373613680                  buf = eeprom_get_data_pointer(&length);
1373713681
13738                  if(IsAddressInRange(action, length))
13682                  if(is_address_in_range(action, length))
1373913683                  {
1374013684                     if(action->flags & kActionFlag_PDWWrite)
1374113685                     {
1374213686                        if(action->flags & kActionFlag_IsFirst)
1374313687                        {
1374413688                           address += bytes;
13745                           bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13689                           bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1374613690                           action->flags &= ~kActionFlag_IsFirst;
1374713691                        }
1374813692                        else
r2821r2822
1375013694                     }
1375113695
1375213696                     DoMemoryWrite(data, buf, address, bytes, 0, &raw_cpu_info);
13753                     return;
1375413697                  }
1375513698               }
1375613699               break;
r2821r2822
1376113704         /* write a data into region */
1376213705         UINT8 * buf = memory_region(action->region);
1376313706
13764         if(buf && IsAddressInRange(action, memory_region_length(action->region)))
13707         if(buf && is_address_in_range(action, memory_region_length(action->region)))
1376513708         {
1376613709            if(action->flags & kActionFlag_PDWWrite)
1376713710            {
1376813711               if(action->flags & kActionFlag_IsFirst)
1376913712               {
1377013713                  address += bytes;
13771                  bytes = EXTRACT_FIELD(action->type, IndexSize) + 1;
13714                  bytes = EXTRACT_FIELD(action->type, CodeParameterLower) + 1;
1377213715                  action->flags &= ~kActionFlag_IsFirst;
1377313716               }
1377413717               else
1377513718                  action->flags |= kActionFlag_IsFirst;
1377613719            }
1377713720
13778            DoMemoryWrite(data, buf, address, bytes, region_needs_swap(action->region), get_region_info(action->region));
13779            return;
13721            DoMemoryWrite(data, buf, address, bytes, region_needs_swap(action->region) ^ EXTRACT_FIELD(action->type, Endianness), get_region_info(action->region));
1378013722         }
1378113723      }
1378213724   }
r2821r2822
1378813730  WatchCheatEntry - set watchpoint when watch value key is pressed in several menus
1378913731------------------------------------------------------------------------------------*/
1379013732
13791static void WatchCheatEntry(CheatEntry * entry, UINT8 associate)
13733static void WatchCheatEntry(cheat_entry *entry, UINT8 associate)
1379213734{
1379313735   int         i, j;
13794   CheatEntry   * associateEntry = NULL;
13736   cheat_entry   *associateEntry = NULL;
1379513737
1379613738   /* NOTE : calling with associate = 1 doesn't exist right now */
1379713739   if(associate)
r2821r2822
1379913741
1380013742   if(!entry)
1380113743   {
13802      messageType = kCheatMessage_FailedToAdd;
13803      messageTimer = DEFAULT_MESSAGE_TIME;
13744      SET_MESSAGE(kCheatMessage_FailedToAdd);
1380413745      return;
1380513746   }
1380613747
13807   for(i = 0; i < entry->actionListLength; i++)
13748   for(i = 0; i < entry->action_list_length; i++)
1380813749   {
13809      CheatAction * action = &entry->actionList[i];
13750      cheat_action *action = &entry->action_list[i];
1381013751
1381113752      if(!(action->flags & kActionFlag_NoAction) && !EXTRACT_FIELD(action->type, AddressRead))
1381213753      {
1381313754         /* NOTE : unsupported the watchpoint for indirect index right now */
13814         if((action->flags & kActionFlag_IndexAddress) && action->extendData != ~0)
13755         if((action->flags & kActionFlag_IndexAddress) && action->extend_data != ~0)
1381513756            continue;
1381613757
1381713758         if(!i)
1381813759         {
13819            /* first CheatAction */
13820            AddActionWatch(&entry->actionList[i], associateEntry);
13760            /* first cheat action */
13761            AddActionWatch(&entry->action_list[i], associateEntry);
1382113762         }
1382213763         else
1382313764         {
13824            /* 2nd or later CheatAction */
13765            /* 2nd or later cheat action */
1382513766            UINT8 differentAddress = 1;
1382613767
1382713768            for(j = 0; j < i; j++)
1382813769            {
13829               /* if we find the same address CheatAction, skip it */
13830               if(entry->actionList[j].address == entry->actionList[i].address)
13770               /* if we find the same address cheat action, skip it */
13771               if(entry->action_list[j].address == entry->action_list[i].address)
1383113772                  differentAddress = 0;
1383213773            }
1383313774
1383413775            if(differentAddress)
13835               AddActionWatch(&entry->actionList[i], associateEntry);
13776               AddActionWatch(&entry->action_list[i], associateEntry);
1383613777         }
1383713778      }
1383813779   }
1383913780
13840   messageType = kCheatMessage_SucceededToAdd;
13841   messageTimer = DEFAULT_MESSAGE_TIME;
13781   SET_MESSAGE(kCheatMessage_SucceededToAdd);
1384213782}
1384313783
1384413784/*-----------------------------------------------------------------------
r2821r2822
1384713787                   or ActivateCheat() via watchpoint code.
1384813788-----------------------------------------------------------------------*/
1384913789
13850static void AddActionWatch(CheatAction * action, CheatEntry * entry)
13790static void AddActionWatch(cheat_action *action, cheat_entry *entry)
1385113791{
1385213792   switch(EXTRACT_FIELD(action->type, CodeType))
1385313793   {
1385413794      case kCodeType_Write:
13855      case kCodeType_PDWWrite:
13856      case kCodeType_RWrite:
1385713795      case kCodeType_IWrite:
13796      case kCodeType_RWrite:
1385813797      case kCodeType_CWrite:
13859      case kCodeType_VWrite:
13860      case kCodeType_VRWrite:
13861      case kCodeType_Branch:
13798      case kCodeType_CBit:
13799      case kCodeType_PDWWrite:
1386213800      case kCodeType_Move:
13801      case kCodeType_Branch:
1386313802      case kCodeType_Loop:
1386413803      case kCodeType_Popup:
1386513804         {
13866            WatchInfo   * info = GetUnusedWatch();
13805            watch_info *info = get_unused_watch();
1386713806
1386813807            info->address      = action->address;
1386913808            info->cpu         = action->region;
13870            info->displayType   = kWatchDisplayType_Hex;
13871            info->elementBytes   = kSearchSize_8Bit;
13809            info->display_type   = kWatchDisplayType_Hex;
13810            info->element_bytes   = kSearchSize_8Bit;
1387213811            info->label[0]      = 0;
13873            info->labelType      = kWatchLabel_None;
13874            info->numElements   = EXTRACT_FIELD(action->type, AddressSize) + 1;
13875            info->linkedCheat   = entry;
13812            info->label_type   = kWatchLabel_None;
13813            info->num_elements   = EXTRACT_FIELD(action->type, AddressSize) + 1;
13814            info->linked_cheat   = entry;
1387613815            info->skip         = 0;
1387713816
1387813817            if(action->flags & kActionFlag_PDWWrite)
1387913818            {
13880               info->numElements += (EXTRACT_FIELD(action->type, IndexSize) + 1);
13819               info->num_elements += (EXTRACT_FIELD(action->type, CodeParameterLower) + 1);
1388113820            }
1388213821            else if(action->flags & kActionFlag_Repeat)
1388313822            {
13884               info->numElements   = EXTRACT_FIELD(action->extendData, LSB16);
13885               info->skip         = EXTRACT_FIELD(action->extendData, MSB16) - 1;
13823               info->num_elements   = EXTRACT_FIELD(action->extend_data, LSB16);
13824               info->skip         = EXTRACT_FIELD(action->extend_data, MSB16) - 1;
1388613825            }
1388713826         }
1388813827         break;
1388913828
1389013829      case kCodeType_Watch:
1389113830         {
13892            WatchInfo * info = GetUnusedWatch();
13831            watch_info *info = get_unused_watch();
1389313832
1389413833            info->address         = action->address;
13895            info->cpu            = EXTRACT_FIELD(action->type, CPURegion);
13896            info->displayType      = EXTRACT_FIELD(action->type, WatchDisplayFormat);
13897            info->elementBytes      = kByteConversionTable[EXTRACT_FIELD(action->type, AddressSize)];
13834            info->cpu            = action->region;
13835            info->display_type      = EXTRACT_FIELD(action->type, WatchDisplayFormat);
13836            info->element_bytes      = kByteConversionTable[EXTRACT_FIELD(action->type, AddressSize)];
1389813837            info->label[0]         = 0;
13899            info->linkedCheat      = entry;
13900            info->numElements      = EXTRACT_FIELD(action->data, WatchNumElements) + 1;
13838            info->linked_cheat      = entry;
13839            info->num_elements      = EXTRACT_FIELD(action->data, WatchNumElements) + 1;
1390113840            info->skip            = EXTRACT_FIELD(action->data, WatchSkip);
13902            info->elementsPerLine   = EXTRACT_FIELD(action->data, WatchElementsPerLine);
13903            info->addValue         = EXTRACT_FIELD(action->data, WatchAddValue);
13841            info->elements_per_line   = EXTRACT_FIELD(action->data, WatchElementsPerLine);
13842            info->add_value         = EXTRACT_FIELD(action->data, WatchAddValue);
1390413843
13905            if(info->addValue & 0x80)
13906               info->addValue |= ~0xFF;
13844            if(info->add_value & 0x80)
13845               info->add_value |= ~0xFF;
1390713846
13908            if(action->extendData != ~0)
13847            if(action->extend_data != ~0)
1390913848            {
1391013849               /* ### fix me... ### */
13911               info->x = (float)(EXTRACT_FIELD(action->extendData, LSB16)) / 100;
13912               info->y = (float)(EXTRACT_FIELD(action->extendData, MSB16)) / 100;
13850               info->x = (float)(EXTRACT_FIELD(action->extend_data, LSB16)) / 100;
13851               info->y = (float)(EXTRACT_FIELD(action->extend_data, MSB16)) / 100;
1391313852            }
1391413853
1391513854            if(TEST_FIELD(action->type, WatchShowLabel) && entry->comment && strlen(entry->comment) < 256)
1391613855            {
13917               info->labelType = kWatchLabel_String;
13856               info->label_type = kWatchLabel_String;
1391813857               strcpy(info->label, entry->comment);
1391913858            }
1392013859            else
13921               info->labelType = kWatchLabel_None;
13860               info->label_type = kWatchLabel_None;
1392213861         }
1392313862         break;
1392413863   }
r2821r2822
1392913868                            called from DeactivateCheat().
1393013869------------------------------------------------------------------------------*/
1393113870
13932static void RemoveAssociatedWatches(CheatEntry * entry)
13871static void RemoveAssociatedWatches(cheat_entry *entry)
1393313872{
1393413873   int i;
1393513874
13936   for(i = watchListLength - 1; i >= 0; i--)
13875   for(i = watch_list_length - 1; i >= 0; i--)
1393713876   {
13938      WatchInfo * info = &watchList[i];
13877      watch_info *info = &watch_list[i];
1393913878
13940      if(info->linkedCheat == entry)
13941         DeleteWatchAt(i);
13879      if(info->linked_cheat == entry)
13880         delete_watch_at(i);
1394213881   }
1394313882}
1394413883
r2821r2822
1394613885  ResetAction - back up data and set action flags
1394713886--------------------------------------------------*/
1394813887
13949static void ResetAction(CheatAction * action)
13888static void ResetAction(cheat_action *action)
1395013889{
1395113890   if(action->flags & kActionFlag_NoAction)
1395213891      return;
1395313892
1395413893   /* back up a value */
13955   if(!(action->flags & kActionFlag_LastValueGood))
13894   if(action->flags & kActionFlag_OldFormat)
1395613895   {
13957      switch(EXTRACT_FIELD(action->type, CodeType))
13896      UINT32 type = action->type;
13897
13898      action->last_value = malloc_or_die(sizeof(action->last_value));
13899      action->type = convert_to_new_code(action);
13900      action->last_value[0] = ReadData(action);
13901      action->type = type;
13902   }
13903   else
13904   {
13905      if(!(action->flags & kActionFlag_LastValueGood))
1395813906      {
13959         default:
13960            action->lastValue = malloc_or_die(sizeof(action->lastValue));
13961            action->lastValue[0] = ReadData(action);
13962            break;
13907         switch(EXTRACT_FIELD(action->type, CodeType))
13908         {
13909            default:
13910               action->last_value = malloc_or_die(sizeof(action->last_value));
13911               action->last_value[0] = ReadData(action);
13912               break;
1396313913
13964         case kCodeType_PDWWrite:
13965            action->lastValue = malloc_or_die(sizeof(action->lastValue) * 2);
13966            action->lastValue[0] = ReadData(action);
13967            action->lastValue[1] = ReadData(action);
13968            break;
13914            case kCodeType_PDWWrite:
13915               action->last_value = malloc_or_die(sizeof(action->last_value) * 2);
13916               action->last_value[0] = ReadData(action);
13917               action->last_value[1] = ReadData(action);
13918               break;
1396913919
13970         case kCodeType_RWrite:
13971         case kCodeType_VRWrite:
13972            {
13973               int i;
13974
13975               for(i = 0; i < EXTRACT_FIELD(action->extendData, LSB16); i++)
13920            case kCodeType_RWrite:
1397613921               {
13977                  action->lastValue = realloc(action->lastValue, sizeof(action->lastValue) * EXTRACT_FIELD(action->extendData, LSB16));
13978                  action->lastValue[i] = ReadData(action);
13979                  action->address +=   EXTRACT_FIELD(action->extendData, MSB16) ?
13980                                 EXTRACT_FIELD(action->extendData, MSB16) :
13981                                 kSearchByteIncrementTable[EXTRACT_FIELD(action->type, AddressSize)];
13922                  int i;
13923
13924                  for(i = 0; i < EXTRACT_FIELD(action->extend_data, LSB16); i++)
13925                  {
13926                     action->last_value = realloc(action->last_value, sizeof(action->last_value) * EXTRACT_FIELD(action->extend_data, LSB16));
13927                     action->last_value[i] = ReadData(action);
13928                     action->address +=   EXTRACT_FIELD(action->extend_data, MSB16) ?
13929                                    EXTRACT_FIELD(action->extend_data, MSB16) :
13930                                    kSearchByteIncrementTable[EXTRACT_FIELD(action->type, AddressSize)];
13931                  }
13932                  action->address = action->original_address;
1398213933               }
13983               action->address = action->originalAddress;
13984            }
13985            break;
13934               break;
13935         }
1398613936      }
1398713937   }
1398813938
13989   action->frameTimer = 0;
13939   action->frame_timer = 0;
1399013940   action->flags &= ~kActionFlag_StateMask;
1399113941   action->flags |= kActionFlag_LastValueGood;
1399213942
r2821r2822
1399513945      if(EXTRACT_FIELD(action->type, CodeParameter) == kCondition_PreviousValue)
1399613946      {
1399713947         if(EXTRACT_FIELD(action->type, CodeType) == kCodeType_CWrite)
13998            action->extendData = ReadData(action);
13948            action->extend_data = ReadData(action);
1399913949         else
1400013950            action->data = ReadData(action);
1400113951      }
r2821r2822
1400613956  ActivateCheat - reset action entry and set activate entry flag when turn CODE "ON"
1400713957-------------------------------------------------------------------------------------*/
1400813958
14009static void ActivateCheat(CheatEntry * entry)
13959static void ActivateCheat(cheat_entry *entry)
1401013960{
1401113961   int   i;
1401213962
14013   for(i = 0; i < entry->actionListLength; i++)
13963   for(i = 0; i < entry->action_list_length; i++)
1401413964   {
14015      CheatAction * action = &entry->actionList[i];
13965      cheat_action *action = &entry->action_list[i];
1401613966
1401713967      ResetAction(action);
1401813968
r2821r2822
1402913979  DeactivateCheat - restore previous value and remove watchpoint when turn CODE "OFF"
1403013980--------------------------------------------------------------------------------------*/
1403113981
14032static void DeactivateCheat(CheatEntry * entry)
13982static void DeactivateCheat(cheat_entry *entry)
1403313983{
1403413984   int i;
1403513985
14036   for(i = 0; i < entry->actionListLength; i++)
13986   for(i = 0; i < entry->action_list_length; i++)
1403713987   {
14038      CheatAction * action = &entry->actionList[i];
13988      cheat_action *action = &entry->action_list[i];
1403913989
1404013990      /* restore previous value and clear backup flag if needed */
1404113991      if(TEST_FIELD(action->type, RestoreValue) && (action->flags & kActionFlag_LastValueGood))
r2821r2822
1404313993         switch(EXTRACT_FIELD(action->type, CodeType))
1404413994         {
1404513995            default:
14046               WriteData(action, (UINT32)action->lastValue[0]);
13996               WriteData(action, (UINT32)action->last_value[0]);
1404713997               break;
1404813998
1404913999            case kCodeType_PDWWrite:
14050               WriteData(action, (UINT32)action->lastValue[0]);
14051               WriteData(action, (UINT32)action->lastValue[1]);
14000               WriteData(action, (UINT32)action->last_value[0]);
14001               WriteData(action, (UINT32)action->last_value[1]);
1405214002               break;
1405314003
1405414004            case kCodeType_RWrite:
14055            case kCodeType_VRWrite:
1405614005               {
1405714006                  int j;
1405814007
14059                  for(j = 0; j < EXTRACT_FIELD(action->extendData, LSB16); j++)
14008                  for(j = 0; j < EXTRACT_FIELD(action->extend_data, LSB16); j++)
1406014009                  {
14061                     WriteData(action, (UINT32)action->lastValue[j]);
14062                     action->address +=   EXTRACT_FIELD(action->extendData, MSB16) ?
14063                                    EXTRACT_FIELD(action->extendData, MSB16) :
14010                     WriteData(action, (UINT32)action->last_value[j]);
14011                     action->address +=   EXTRACT_FIELD(action->extend_data, MSB16) ?
14012                                    EXTRACT_FIELD(action->extend_data, MSB16) :
1406414013                                    kSearchByteIncrementTable[EXTRACT_FIELD(action->type, AddressSize)];
1406514014                  }
14066                  action->address = action->originalAddress;
14015                  action->address = action->original_address;
1406714016               }
1406814017               break;
1406914018         }
1407014019         action->flags &= ~kActionFlag_LastValueGood;
1407114020      }
14072      free(action->lastValue);
14073      action->lastValue = NULL;
14021      free(action->last_value);
14022      action->last_value = NULL;
1407414023   }
1407514024
1407614025   /* remove watchpoint */
r2821r2822
1408414033  TempDeactivateCheat - restore previous value when turn CHEAT "OFF"
1408514034--------------------------------------------------------------------*/
1408614035
14087static void TempDeactivateCheat(CheatEntry * entry)
14036static void TempDeactivateCheat(cheat_entry *entry)
1408814037{
1408914038   if(entry->flags & kCheatFlag_Active)
1409014039   {
1409114040      int i;
1409214041
14093      for(i = 0; i < entry->actionListLength; i++)
14042      for(i = 0; i < entry->action_list_length; i++)
1409414043      {
14095         CheatAction * action = &entry->actionList[i];
14044         cheat_action *action = &entry->action_list[i];
1409614045
14097         action->frameTimer = 0;
14046         action->frame_timer = 0;
1409814047         action->flags &= ~kActionFlag_OperationDone;
1409914048
1410014049         /* restore previous value if needed */
1410114050         switch(EXTRACT_FIELD(action->type, CodeType))
1410214051         {
1410314052            default:
14104               WriteData(action, (UINT32)action->lastValue[0]);
14053               WriteData(action, (UINT32)action->last_value[0]);
1410514054               break;
1410614055
1410714056            case kCodeType_PDWWrite:
14108               WriteData(action, (UINT32)action->lastValue[0]);
14109               WriteData(action, (UINT32)action->lastValue[1]);
14057               WriteData(action, (UINT32)action->last_value[0]);
14058               WriteData(action, (UINT32)action->last_value[1]);
1411014059               break;
1411114060
1411214061            case kCodeType_RWrite:
14113            case kCodeType_VRWrite:
1411414062               {
1411514063                  int j;
1411614064
14117                  for(j = 0; j < EXTRACT_FIELD(action->extendData, LSB16); j++)
14065                  for(j = 0; j < EXTRACT_FIELD(action->extend_data, LSB16); j++)
1411814066                  {
14119                     WriteData(action, (UINT32)action->lastValue[j]);
14120                     action->address +=   EXTRACT_FIELD(action->extendData, MSB16) ?
14121                                    EXTRACT_FIELD(action->extendData, MSB16) :
14067                     WriteData(action, (UINT32)action->last_value[j]);
14068                     action->address +=   EXTRACT_FIELD(action->extend_data, MSB16) ?
14069                                    EXTRACT_FIELD(action->extend_data, MSB16) :
1412214070                                    kSearchByteIncrementTable[EXTRACT_FIELD(action->type, AddressSize)];
1412314071                  }
14124                  action->address = action->originalAddress;
14072                  action->address = action->original_address;
1412514073               }
1412614074               break;
1412714075         }
r2821r2822
1413414082  cheat_periodicOperation - management for cheat operations
1413514083------------------------------------------------------------*/
1413614084
14137static void cheat_periodicOperation(CheatAction * action)
14085static void cheat_periodicOperation(cheat_action *action)
1413814086{
1413914087   int data = TEST_FIELD(action->type, DataRead) ? cheatVariable[action->data] : action->data;
1414014088
r2821r2822
1414214090   {
1414314091      action->flags &= ~kActionFlag_IsFirst;
1414414092      WriteData(action, data);
14145      WriteData(action, action->extendData);
14093      WriteData(action, action->extend_data);
1414614094   }
1414714095   else if(action->flags & kActionFlag_Repeat)
1414814096   {
1414914097      int i;
1415014098
14151      for(i = 0; i < EXTRACT_FIELD(action->extendData, LSB16); i++)
14099      for(i = 0; i < EXTRACT_FIELD(action->extend_data, LSB16); i++)
1415214100      {
1415314101         WriteData(action, data);
14154         action->address +=   EXTRACT_FIELD(action->extendData, MSB16) ?
14155                        EXTRACT_FIELD(action->extendData, MSB16) :
14102         action->address +=   EXTRACT_FIELD(action->extend_data, MSB16) ?
14103                        EXTRACT_FIELD(action->extend_data, MSB16) :
1415614104                        kSearchByteIncrementTable[EXTRACT_FIELD(action->type, AddressSize)];
1415714105      }
14158      action->address = action->originalAddress;
14106      action->address = action->original_address;
1415914107   }
1416014108   else
1416114109   {
1416214110      switch(EXTRACT_FIELD(action->type, CodeType))
1416314111      {
1416414112         case kCodeType_Write:
14165            WriteData(action, (data & action->extendData) | (ReadData(action) & ~action->extendData));
14113            WriteData(action, (data & action->extend_data) | (ReadData(action) & ~action->extend_data));
1416614114            break;
1416714115
1416814116         case kCodeType_IWrite:
1416914117            switch(EXTRACT_FIELD(action->type, CodeParameter))
1417014118            {
14171               case kIWrite_Write:
14119               case IWRITE_WRITE:
1417214120                  WriteData(action, data);
1417314121                  break;
1417414122
14175               case kIWrite_BitSet:
14123               case IWRITE_BIT_SET:
1417614124                  WriteData(action, ReadData(action) | data);
1417714125                  break;
1417814126
14179               case kIWrite_BitClear:
14127               case IWRITE_BIT_CLEAR:
1418014128                  WriteData(action, ReadData(action) & ~data);
1418114129                  break;
1418214130
14183               case kIWrite_LimitedMask:
14131               case IWRITE_LIMITED_MASK:
1418414132                  WriteData(action, (EXTRACT_FIELD(data, MSB16) & EXTRACT_FIELD(data, LSB16)) | (ReadData(action) & ~EXTRACT_FIELD(data, LSB16)));
1418514133                  break;
1418614134            }
1418714135            break;
1418814136
1418914137         case kCodeType_CWrite:
14190         case kCodeType_VWrite:
1419114138            WriteData(action, data);
1419214139            break;
1419314140
14141         case kCodeType_CBit:
14142            switch(EXTRACT_FIELD(action->type, CodeParameterUpper))
14143            {
14144               case CBIT_BIT_SET:
14145                  WriteData(action, ReadData(action) | data);
14146                  break;
14147
14148               case CBIT_BIT_CLEAR:
14149                  WriteData(action, ReadData(action) & ~data);
14150                  break;
14151
14152               case CBIT_LIMITED_MASK:
14153                  WriteData(action, (EXTRACT_FIELD(data, MSB16) & EXTRACT_FIELD(data, LSB16)) | (ReadData(action) & ~EXTRACT_FIELD(data, LSB16)));
14154                  break;
14155            }
14156            break;
14157
1419414158         case kCodeType_Move:
1419514159            cheatVariable[EXTRACT_FIELD(action->type, CodeParameter)] = ReadData(action) + data;
1419614160            break;
r2821r2822
1419914163            switch(EXTRACT_FIELD(action->type, PopupParameter))
1420014164            {
1420114165               case kPopup_Label:
14202                  ui_popup_time(1, "%s", action->optionalName);
14166                  ui_popup_time(1, "%s", action->optional_name);
1420314167                  break;
1420414168
1420514169               case kPopup_Value:
1420614170                  ui_popup_time(1, "%*.*X",
14207                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressRead)],
14208                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressRead)],
14171                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressSize)],
14172                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressSize)],
1420914173                              ReadData(action));
1421014174                  break;
1421114175
1421214176               case kPopup_LabelValue:
1421314177                  ui_popup_time(1, "%s %*.*X",
14214                              action->optionalName,
14215                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressRead)],
14216                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressRead)],
14178                              action->optional_name,
14179                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressSize)],
14180                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressSize)],
1421714181                              ReadData(action));
1421814182                  break;
1421914183
1422014184               case kPopup_ValueLabel:
1422114185                  ui_popup_time(1, "%*.*X %s",
14222                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressRead)],
14223                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressRead)],
14186                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressSize)],
14187                              kCheatSizeDigitsTable[EXTRACT_FIELD(action->type, AddressSize)],
1422414188                              ReadData(action),
14225                              action->optionalName);
14189                              action->optional_name);
1422614190                  break;
1422714191            }
1422814192            break;
r2821r2822
1423614200
1423714201/*------------------------------------------------------------
1423814202  cheat_periodicCondition - management for cheat conditions
14239                            used by CWrite, Branch, Popup
1424014203------------------------------------------------------------*/
1424114204
14242static UINT8 cheat_periodicCondition(CheatAction * action)
14205static UINT8 cheat_periodicCondition(cheat_action *action)
1424314206{
1424414207   int   data   = ReadData(action);
14245   int   value   = EXTRACT_FIELD(action->type, CodeType) == kCodeType_CWrite ? action->extendData : action->data;
14208   int   value   = action->extend_data;
1424614209
14247   switch(EXTRACT_FIELD(action->type, CodeParameter))
14210   if(EXTRACT_FIELD(action->type, CodeType) != kCodeType_CBit)
1424814211   {
14249      case kCondition_Equal:
14250         return (data == value);
14212      /* CWrite, Branch, Popup */
14213      switch(EXTRACT_FIELD(action->type, CodeParameter))
14214      {
14215         case kCondition_Equal:
14216            return (data == value);
1425114217
14252      case kCondition_NotEqual:
14253         return (data != value);
14218         case kCondition_NotEqual:
14219            return (data != value);
1425414220
14255      case kCondition_Less:
14256         return (data < value);
14221         case kCondition_Less:
14222            return (data < value);
1425714223
14258      case kCondition_LessOrEqual:
14259         return (data <= value);
14224         case kCondition_LessOrEqual:
14225            return (data <= value);
1426014226
14261      case kCondition_Greater:
14262         return (data > value);
14227         case kCondition_Greater:
14228            return (data > value);
1426314229
14264      case kCondition_GreaterOrEqual:
14265         return (data >= value);
14230         case kCondition_GreaterOrEqual:
14231            return (data >= value);
1426614232
14267      case kCondition_BitSet:
14268         return (data & value);
14233         case kCondition_BitSet:
14234            return (data & value);
1426914235
14270      case kCondition_BitClear:
14271         return (!(data & value));
14236         case kCondition_BitClear:
14237            return (!(data & value));
1427214238
14273      case kCondition_PreviousValue:
14274         if(data != value)
14275         {
14276            if(EXTRACT_FIELD(action->type, CodeType) == kCodeType_CWrite)
14277               action->extendData = data;
14278            else
14279               action->data = data;
14239         case kCondition_PreviousValue:
14240            if(data != value)
14241            {
14242               if(EXTRACT_FIELD(action->type, CodeType) == kCodeType_CWrite)
14243                  action->extend_data = data;
14244               else
14245                  action->data = data;
1428014246
14281            return 1;
14282         }
14283         break;
14247               return 1;
14248            }
14249            break;
1428414250
14285      case kCondition_KeyPressedOnce:
14286         return (input_code_pressed_once(value));
14251         case kCondition_KeyPressedOnce:
14252            return (input_code_pressed_once(value));
1428714253
14288      case kCondition_KeyPressedRepeat:
14289         return (input_code_pressed(value));
14254         case kCondition_KeyPressedRepeat:
14255            return (input_code_pressed(value));
1429014256
14291      case kCondition_True:
14292         return 1;
14257         case kCondition_True:
14258            return 1;
14259      }
1429314260   }
14261   else
14262   {
14263      /* CBit */
14264      switch(EXTRACT_FIELD(action->type, CodeParameterLower))
14265      {
14266         case CONDITION_CBIT_BIT_SET:
14267            return (data & value);
1429414268
14269         case CONDITION_CBIT_BIT_CLEAR:
14270            return (!(data & value));
14271      }
14272   }
14273
1429514274   return 0;
1429614275}
1429714276
r2821r2822
1429914278  cheat_periodicAction - management for cheat actions
1430014279------------------------------------------------------*/
1430114280
14302static int cheat_periodicAction(running_machine *machine, CheatAction * action, int selection)
14281static int cheat_periodicAction(running_machine *machine, cheat_action *action, int selection)
1430314282{
1430414283   UINT8 executeOperation = 0;
1430514284
14306   if(driverSpecifiedFlag)
14307      return (TEST_FIELD(action->type, Return) ? CHEAT_RETURN_VALUE : selection + 1);
14308
14309   if(TEST_FIELD(action->type, PrefillEnable) && !(action->flags & kActionFlag_PrefillDone))
14285   if(TEST_FIELD(action->type, PrefillEnable))
1431014286   {
14311      UINT8 prefillValue = kPrefillValueTable[EXTRACT_FIELD(action->type, PrefillEnable)];
14312
14313      if(!(action->flags & kActionFlag_PrefillWritten))
14287      if((action->flags & kActionFlag_PrefillDone) == 0)
1431414288      {
14315         /* set prefill */
14316         WriteData(action, prefillValue);
14317         action->flags |= kActionFlag_PrefillWritten;
14318         return (TEST_FIELD(action->type, Return) ? CHEAT_RETURN_VALUE : selection + 1);
14289         UINT8 prefillValue = kPrefillValueTable[EXTRACT_FIELD(action->type, PrefillEnable)];
1431914290
14320      }
14321      else
14322      {
14323         /* do re-write */
14324         if(ReadData(action) == prefillValue)
14291         if((action->flags & kActionFlag_PrefillWritten) == 0)
14292         {
14293            /* set prefill */
14294            WriteData(action, prefillValue);
14295            action->flags |= kActionFlag_PrefillWritten;
1432514296            return (TEST_FIELD(action->type, Return) ? CHEAT_RETURN_VALUE : selection + 1);
14297         }
14298         else
14299         {
14300            /* do re-write */
14301            if(ReadData(action) == prefillValue)
14302               return (TEST_FIELD(action->type, Return) ? CHEAT_RETURN_VALUE : selection + 1);
1432614303
14327         action->flags |= kActionFlag_PrefillDone;
14304            action->flags |= kActionFlag_PrefillDone;
14305         }
1432814306      }
1432914307   }
1433014308
r2821r2822
1433514313         /* Keep */
1433614314         executeOperation = 1;
1433714315
14338         if(action->frameTimer++ >= EXTRACT_FIELD(action->type, DelayEnable) * ATTOSECONDS_TO_HZ(video_screen_get_frame_period(machine->primary_screen).attoseconds))
14316         if(action->frame_timer++ >= EXTRACT_FIELD(action->type, DelayEnable) * ATTOSECONDS_TO_HZ(video_screen_get_frame_period(machine->primary_screen).attoseconds))
1433914317            action->flags |= kActionFlag_OperationDone;
1434014318      }
1434114319      else
1434214320      {
14343         if(action->frameTimer++ >= EXTRACT_FIELD(action->type, DelayEnable) * ATTOSECONDS_TO_HZ(video_screen_get_frame_period(machine->primary_screen).attoseconds))
14321         if(action->frame_timer++ >= EXTRACT_FIELD(action->type, DelayEnable) * ATTOSECONDS_TO_HZ(video_screen_get_frame_period(machine->primary_screen).attoseconds))
1434414322         {
1434514323            /* Delay */
1434614324            executeOperation = 1;
14347            action->frameTimer = 0;
14325            action->frame_timer = 0;
1434814326
1434914327            if(TEST_FIELD(action->type, OneShot))
1435014328               action->flags |= kActionFlag_OperationDone;
r2821r2822
1435314331   }
1435414332   else
1435514333   {
14356      if(action->frameTimer++)
14334      if(action->frame_timer++)
1435714335      {
14358         if(action->frameTimer >= EXTRACT_FIELD(action->type, DelayEnable) * ATTOSECONDS_TO_HZ(video_screen_get_frame_period(machine->primary_screen).attoseconds))
14359            action->frameTimer = 0;
14336         if(action->frame_timer >= EXTRACT_FIELD(action->type, DelayEnable) * ATTOSECONDS_TO_HZ(video_screen_get_frame_period(machine->primary_screen).attoseconds))
14337            action->frame_timer = 0;
1436014338
1436114339         return (TEST_FIELD(action->type, Return) ? CHEAT_RETURN_VALUE : selection + 1);
1436214340      }
1436314341      else
1436414342      {
14365         executeOperation = 1;
14343            executeOperation = 1;
1436614344
14367         action->flags |= kActionFlag_OperationDone;
14345            action->flags |= kActionFlag_OperationDone;
1436814346      }
1436914347   }
1437014348
14349   if(action->flags & kActionFlag_CheckCondition)
14350   {
14351      if(cheat_periodicCondition(action))
14352         executeOperation = 1;
14353      else
14354         executeOperation = 0;
14355   }
14356
1437114357   if(executeOperation)
1437214358   {
1437314359      /* do cheat operation */
1437414360      switch(EXTRACT_FIELD(action->type, CodeType))
1437514361      {
1437614362         case kCodeType_Write:
14377         case kCodeType_PDWWrite:
14378         case kCodeType_RWrite:
1437914363         case kCodeType_IWrite:
14380         case kCodeType_VWrite:
14381         case kCodeType_VRWrite:
14364         case kCodeType_RWrite:
14365         case kCodeType_CWrite:
14366         case kCodeType_CBit:
14367         case kCodeType_PDWWrite:
1438214368         case kCodeType_Move:
14369         case kCodeType_Popup:
1438314370            cheat_periodicOperation(action);
1438414371            break;
1438514372
14386         case kCodeType_CWrite:
14387         case kCodeType_Popup:
14388            if(cheat_periodicCondition(action))
14389               cheat_periodicOperation(action);
14390            break;
14391
1439214373         case kCodeType_Branch:
14393            if(cheat_periodicCondition(action))
14394               return action->extendData;
14395            break;
14374            return action->data;
1439614375
1439714376         case kCodeType_Loop:
1439814377            {
1439914378               int counter = ReadData(action);
1440014379
14401               if(counter)
14380               if(counter != 0)
1440214381               {
1440314382                  WriteData(action, counter - 1);
1440414383
1440514384                  return (TEST_FIELD(action->type, DataRead) ? cheatVariable[action->data] : action->data);
1440614385               }
1440714386            }
14408            break;
1440914387      }
1441014388   }
1441114389
r2821r2822
1441614394  cheat_periodicEntry - management for cheat entries
1441714395-----------------------------------------------------*/
1441814396
14419static void cheat_periodicEntry(running_machine *machine, CheatEntry * entry)
14397static void cheat_periodicEntry(running_machine *machine, cheat_entry *entry)
1442014398{
1442114399   int      i         = 0;
1442214400   UINT8   pressedKey   = 0;
r2821r2822
1442714405   if(!ui_is_menu_active())
1442814406   {
1442914407      /* NOTE : activation key should be not checked in activating UI menu because it conflicts activation key checker */
14430      if((entry->flags & kCheatFlag_HasActivationKey1) && input_code_pressed_once(entry->activationKey1))
14408      if((entry->flags & kCheatFlag_HasActivationKey1) && input_code_pressed_once(entry->activation_key1))
1443114409         pressedKey = 1;
14432      else if((entry->flags & kCheatFlag_HasActivationKey2) && input_code_pressed_once(entry->activationKey2))
14410      else if((entry->flags & kCheatFlag_HasActivationKey2) && input_code_pressed_once(entry->activation_key2))
1443314411         pressedKey = 2;
1443414412   }
1443514413
r2821r2822
1444014418         if(pressedKey == 1)
1444114419         {
1444214420            if(--entry->selection < 0)
14443               entry->selection = entry->labelIndexLength - 1;
14421               entry->selection = entry->label_index_length - 1;
1444414422         }
1444514423         else
1444614424         {
14447            if(++entry->selection >= entry->labelIndexLength)
14425            if(++entry->selection >= entry->label_index_length)
1444814426               entry->selection = 0;
1444914427         }
1445014428
1445114429         /* NOTE : in handling activatio key, forced to activate a cheat even if one shot */
14452         if(!(entry->flags & kCheatFlag_OneShot) && !(entry->labelIndex[entry->selection]))
14430         if(!(entry->flags & kCheatFlag_OneShot) && !(entry->label_index[entry->selection]))
1445314431            DeactivateCheat(entry);
1445414432         else
1445514433            ActivateCheat(entry);
1445614434
14457         if(TEST_FIELD(cheatOptions, ActivationKeyMessage))
14435         if(TEST_FIELD(cheat_options, ActivationKeyMessage))
1445814436         {
1445914437            if(!entry->selection)
1446014438               ui_popup_time(1,"%s disabled", entry->name);
1446114439            else
14462               ui_popup_time(1,"%s : %s selected", entry->name, entry->actionList[entry->labelIndex[entry->selection]].optionalName);
14440               ui_popup_time(1,"%s : %s selected", entry->name, entry->action_list[entry->label_index[entry->selection]].optional_name);
1446314441         }
1446414442      }
1446514443   }
r2821r2822
1447214450         {
1447314451            ActivateCheat(entry);
1447414452
14475            if(TEST_FIELD(cheatOptions, ActivationKeyMessage))
14453            if(TEST_FIELD(cheat_options, ActivationKeyMessage))
1447614454               ui_popup_time(1,"set %s", entry->name);
1447714455         }
1447814456         else if(entry->flags & kCheatFlag_Active)
1447914457         {
1448014458            DeactivateCheat(entry);
1448114459
14482            if(TEST_FIELD(cheatOptions, ActivationKeyMessage))
14460            if(TEST_FIELD(cheat_options, ActivationKeyMessage))
1448314461               ui_popup_time(1,"%s disabled", entry->name);
1448414462         }
1448514463         else
1448614464         {
1448714465            ActivateCheat(entry);
1448814466
14489            if(TEST_FIELD(cheatOptions, ActivationKeyMessage))
14467            if(TEST_FIELD(cheat_options, ActivationKeyMessage))
1449014468               ui_popup_time(1,"%s enabled", entry->name);
1449114469         }
1449214470      }
r2821r2822
1449514473   /* ***** 2nd, do cheat actions ***** */
1449614474
1449714475   /* if "OFF", no action */
14498   if(!(entry->flags & kCheatFlag_Active))
14476   if(driverSpecifiedFlag != 0 || (entry->flags & kCheatFlag_Active) == 0)
1449914477      return;
1450014478
1450114479   while(1)
1450214480   {
14503      if(entry->actionList[i].flags & kActionFlag_Custom)
14481      if(entry->action_list[i].flags & kActionFlag_Custom)
1450414482      {
14505         if(EXTRACT_FIELD(entry->actionList[i].type, CodeType) == kCustomCode_LabelSelect)
14483         if(EXTRACT_FIELD(entry->action_list[i].type, CodeType) == CUSTOM_CODE_LABEL_SELECT)
1450614484         {
14507            i = entry->labelIndex[entry->selection];
14485            i = entry->label_index[entry->selection];
1450814486            isSelect = 1;
1450914487            continue;
1451014488         }
1451114489         else
1451214490            i++;
1451314491      }
14514      else if((entry->actionList[i].flags & kActionFlag_OperationDone) || (entry->actionList[i].flags & kActionFlag_NoAction))
14492      else if((entry->action_list[i].flags & kActionFlag_OperationDone) || (entry->action_list[i].flags & kActionFlag_NoAction))
1451514493      {
1451614494         i++;
1451714495      }
14518      else if(entry->actionList[i].flags & kActionFlag_OldFormat)
14496      else if(entry->action_list[i].flags & kActionFlag_OldFormat)
1451914497      {
14520         int   tempType   = entry->actionList[i].type;
14498         int   tempType   = entry->action_list[i].type;
1452114499         int   j         = i;
1452214500
14523         entry->actionList[i].type = ConvertToNewCode(&entry->actionList[i]);
14524         i = cheat_periodicAction(machine, &entry->actionList[i], i);
14525         entry->actionList[j].type = tempType;
14501         entry->action_list[i].type = convert_to_new_code(&entry->action_list[i]);
14502         i = cheat_periodicAction(machine, &entry->action_list[i], i);
14503         entry->action_list[j].type = tempType;
1452614504      }
1452714505      else
14528         i = cheat_periodicAction(machine, &entry->actionList[i], i);
14506         i = cheat_periodicAction(machine, &entry->action_list[i], i);
1452914507
14530      if(i >= entry->actionListLength)
14508      if(i >= entry->action_list_length)
1453114509         break;
1453214510
14533      if(isSelect && EXTRACT_FIELD(entry->actionList[i].type, Link) != kLink_SubLink)
14511      if(isSelect && EXTRACT_FIELD(entry->action_list[i].type, Link) != kLink_SubLink)
1453414512         break;
1453514513   }
1453614514
r2821r2822
1454514523
1454614524      while(1)
1454714525      {
14548         if(entry->actionList[i].flags & kActionFlag_Custom)
14526         if(entry->action_list[i].flags & kActionFlag_Custom)
1454914527         {
14550            if(EXTRACT_FIELD(entry->actionList[i].type, CodeType) == kCustomCode_LabelSelect)
14528            if(EXTRACT_FIELD(entry->action_list[i].type, CodeType) == CUSTOM_CODE_LABEL_SELECT)
1455114529            {
14552               i = entry->labelIndex[entry->selection];
14530               i = entry->label_index[entry->selection];
1455314531               isSelect = 1;
1455414532               continue;
1455514533            }
1455614534         }
14557         else if(entry->actionList[i].flags & kActionFlag_NoAction)
14535         else if(entry->action_list[i].flags & kActionFlag_NoAction)
1455814536         {
1455914537            i++;
1456014538         }
14561         else if(!(entry->actionList[i].flags & kActionFlag_OperationDone))
14539         else if(!(entry->action_list[i].flags & kActionFlag_OperationDone))
1456214540         {
1456314541            done = 0;
1456414542            i++;
r2821r2822
1456614544         else
1456714545            i++;
1456814546
14569         if(i >= entry->actionListLength)
14547         if(i >= entry->action_list_length)
1457014548            break;
1457114549
14572         if(isSelect && EXTRACT_FIELD(entry->actionList[i].type, Link) != kLink_SubLink)
14550         if(isSelect && EXTRACT_FIELD(entry->action_list[i].type, Link) != kLink_SubLink)
1457314551            break;
1457414552      }
1457514553
r2821r2822
1457814556   }
1457914557}
1458014558
14581/*------------------------------------------------------------------
14582  UpdateAllCheatInfo - update all cheat info when database loaded
14583------------------------------------------------------------------*/
14559/*---------------------------------------------------------------------
14560  update_all_cheat_info - update all cheat info when database loaded
14561---------------------------------------------------------------------*/
1458414562
14585static void UpdateAllCheatInfo(void)
14563static void update_all_cheat_info(void)
1458614564{
1458714565   int i;
1458814566
14589   /* update flags for all CheatEntry */
14590   for(i = 0; i < cheatListLength; i++)
14567   /* update flags for all cheat entry */
14568   for(i = 0; i < cheat_list_length; i++)
1459114569   {
14592      UpdateCheatInfo(&cheatList[i], 1);
14570      update_cheat_info(&cheat_list[i], 1);
1459314571
14594      if(cheatList[i].flags & kCheatFlag_Select)
14595         BuildLabelIndexTable(&cheatList[i]);
14572      if(cheat_list[i].flags & kCheatFlag_Select)
14573         BuildLabelIndexTable(&cheat_list[i]);
1459614574   }
1459714575
1459814576   SetLayerIndex();
1459914577}
1460014578
14601/*---------------------------------------------------------------------------------------------
14602  UpdateCheatInfo - check several fields on CheatEntry and CheatAction then set flags
14603                    "isLoadTime" parameter is set when called UpdateAllCheatInfo() right now
14604---------------------------------------------------------------------------------------------*/
14579/*--------------------------------------------------------------------------------------------------
14580  update_cheat_info - check several fields on cheat entry and cheat action then set flags
14581                      "isLoadTime" parameter is set when called update_all_cheat_info() right now
14582--------------------------------------------------------------------------------------------------*/
1460514583
14606static void UpdateCheatInfo(CheatEntry * entry, UINT8 isLoadTime)
14584static void update_cheat_info(cheat_entry *entry, UINT8 is_load_time)
1460714585{
1460814586   int      i;
1460914587   int      flags = 0;
14610   UINT8   isOneShot = 1;
14611   UINT8   isNull = 1;
14612   UINT8   isSeparator = 1;
14613   UINT8   isNewFormat = 1;
14588   UINT8   is_one_shot = 1;
14589   UINT8   is_null = 1;
14590   UINT8   is_separator = 1;
14591   UINT8   is_new_format = 1;
1461414592
1461514593   flags = entry->flags & kCheatFlag_PersistentMask;
1461614594
14617   for(i = 0; i < entry->actionListLength; i++)
14595   for(i = 0; i < entry->action_list_length; i++)
1461814596   {
14619      CheatAction * action = &entry->actionList[i];
14597      cheat_action *action = &entry->action_list[i];
1462014598
14621      int actionFlags = action->flags & kActionFlag_PersistentMask;
14599      int action_flags = action->flags & kActionFlag_PersistentMask;
1462214600
14623      action->region = EXTRACT_FIELD(action->type, CPURegion);
14601      if(TEST_FIELD(action->type, OneShot) == 0)
14602         is_one_shot = 0;
1462414603
14625      if(actionFlags & kActionFlag_OldFormat)
14604      if(action_flags & kActionFlag_OldFormat)
1462614605      {
1462714606         if(   (EXTRACT_FIELD(action->type, LocationType) == kLocation_Custom) &&
1462814607            (EXTRACT_FIELD(action->type, LocationParameter) == kCustomLocation_Select))
1462914608               flags |= kCheatFlag_Select;
1463014609
1463114610         if(EXTRACT_FIELD(action->type, LocationType) != kLocation_Custom)
14632            isNull = 0;
14611            is_null = 0;
1463314612
14634         if(!TEST_FIELD(action->type, OneShot))
14635            isOneShot = 0;
14636
1463714613         if(TEST_FIELD(action->type, UserSelectEnable))
1463814614            flags |= kCheatFlag_UserSelect;
1463914615
1464014616         if(   (EXTRACT_FIELD(action->type, LocationType) == kLocation_Custom) &&
1464114617            (EXTRACT_FIELD(action->type, LocationParameter) == kCustomLocation_Select))
14642               actionFlags |= kActionFlag_NoAction;
14618               action_flags |= kActionFlag_NoAction;
1464314619
1464414620         if(   (EXTRACT_FIELD(action->type, LocationType) == kLocation_IndirectIndexed) ||
1464514621            ((EXTRACT_FIELD(action->type, LocationType) != kLocation_Custom) &&
1464614622            ((EXTRACT_FIELD(action->type, Operation) | EXTRACT_FIELD(action->type, OperationExtend) << 2) == 1)))
14647               actionFlags |= kActionFlag_IndexAddress;
14623               action_flags |= kActionFlag_IndexAddress;
1464814624
14649         if(i && entry->actionList[i-1].type == entry->actionList[i].type)
14625         if(i && entry->action_list[i-1].type == entry->action_list[i].type)
1465014626         {
14651            if(   entry->actionList[i].address >= entry->actionList[i-1].address &&
14652               entry->actionList[i].address <= entry->actionList[i-1].address + 3)
14653                  actionFlags |= kActionFlag_NoAction;
14627            if(   entry->action_list[i].address >= entry->action_list[i-1].address &&
14628               entry->action_list[i].address <= entry->action_list[i-1].address + 3)
14629                  action_flags |= kActionFlag_NoAction;
1465414630         }
1465514631
14656         isNewFormat = 0;
14632         is_new_format = 0;
14633         is_one_shot = 0;
1465714634      }
1465814635      else
1465914636      {
14660         if(action->region != CUSTOM_CODE)
14637         if(action->region < CUSTOM_CODE)
1466114638         {
1466214639            switch(EXTRACT_FIELD(action->type, CodeType))
1466314640            {
1466414641               case kCodeType_PDWWrite:
14665                  actionFlags |= kActionFlag_PDWWrite;
14642                  action_flags |= kActionFlag_PDWWrite;
1466614643                  break;
1466714644
14645               case kCodeType_IWrite:
14646                  if(action->extend_data != ~0)
14647                     action_flags |= kActionFlag_IndexAddress;
14648                  if(EXTRACT_FIELD(action->type, CodeParameterUpper) == IWRITE_LIMITED_MASK)
14649                     action_flags |= kActionFlag_LimitedMask;
14650                  break;
14651
14652               case kCodeType_CBit:
14653                  action->flags |= kActionFlag_CheckCondition;
14654                  if(EXTRACT_FIELD(action->type, CodeParameterUpper) == CBIT_LIMITED_MASK)
14655                     action_flags |= kActionFlag_LimitedMask;
14656                  break;
14657
1466814658               case kCodeType_RWrite:
14669                  actionFlags |= kActionFlag_Repeat;
14659                  action_flags |= kActionFlag_Repeat;
1467014660                  break;
1467114661
14672               case kCodeType_IWrite:
1467314662               case kCodeType_Move:
14674               case kCodeType_Loop:
14675                  if(action->extendData != ~0)
14676                     actionFlags |= kActionFlag_IndexAddress;
14663                  if(action->extend_data != ~0)
14664                     action_flags |= kActionFlag_IndexAddress;
1467714665                  break;
1467814666
1467914667               case kCodeType_CWrite:
1468014668               case kCodeType_Branch:
14681                  actionFlags |= kActionFlag_CheckCondition;
14669                  action_flags |= kActionFlag_CheckCondition;
1468214670                  break;
1468314671
14684               case kCodeType_VWrite:
14685                  flags |= kCheatFlag_UserSelect;
14686
14687                  if(action->extendData != ~0)
14688                     actionFlags |= kActionFlag_IndexAddress;
14672               case kCodeType_Popup:
14673                  action_flags |= kActionFlag_CheckCondition;
1468914674                  break;
1469014675
14691               case kCodeType_VRWrite:
14692                  flags |= kCheatFlag_UserSelect;
14693                  actionFlags |= kActionFlag_Repeat;
14676                  if(action->extend_data != ~0)
14677                     action_flags |= kActionFlag_IndexAddress;
1469414678                  break;
1469514679
14696               case kCodeType_Popup:
14697                  actionFlags |= kActionFlag_CheckCondition;
14698
14699                  if(action->extendData != ~0)
14700                     actionFlags |= kActionFlag_IndexAddress;
14701                  break;
14702
1470314680               case kCodeType_Watch:
14704                  actionFlags |= kActionFlag_NoAction;
14681                  action_flags |= kActionFlag_NoAction;
1470514682                  break;
1470614683            }
1470714684
14708            isNull = 0;
14709            isSeparator = 0;
14685            if(TEST_FIELD(action->type, ValueSelectEnable))
14686               flags |= kCheatFlag_UserSelect;
14687
14688            is_null = 0;
14689            is_separator = 0;
1471014690         }
1471114691         else
1471214692         {
1471314693            /* is label-select? */
14714            if(EXTRACT_FIELD(action->type, CodeType) == kCustomCode_LabelSelect)
14694            if(action->region == CUSTOM_CODE_LABEL_SELECT)
1471514695               flags |= kCheatFlag_Select;
1471614696
1471714697            /* is comment? */
14718            if(EXTRACT_FIELD(action->type, CodeType) != kCustomCode_Comment)
14719               isNull = 0;
14698            if(action->region != CUSTOM_CODE_COMMENT)
14699               is_null = 0;
1472014700
1472114701            /* is separator? */
14722            if(EXTRACT_FIELD(action->type, CodeType) != kCustomCode_Separator)
14723               isSeparator = 0;
14702            if(action->region != CUSTOM_CODE_SEPARATOR)
14703               is_separator = 0;
1472414704
1472514705            /* is layer index? */
14726            if(EXTRACT_FIELD(action->type, CodeType) == kCustomCode_Layer)
14706            if(action->region == CUSTOM_CODE_LAYER_TAG)
1472714707               flags |= kCheatFlag_LayerIndex;
1472814708
14729            actionFlags |= kActionFlag_NoAction;
14730            actionFlags |= kActionFlag_Custom;
14709            action_flags |= kActionFlag_NoAction;
14710            action_flags |= kActionFlag_Custom;
1473114711         }
14732
14733         /* is one shot? */
14734         if(!TEST_FIELD(action->type, OneShot))
14735            isOneShot = 0;
1473614712      }
1473714713
14738      action->flags = actionFlags;
14714      action->flags = action_flags;
1473914715   }
1474014716
14741   /* one shot is set if "ALL" actions are not an one shot */
14742   if(isOneShot)
14717   if(is_new_format == 0)
14718      flags |= kCheatFlag_OldFormat;
14719
14720   if(is_one_shot)
1474314721      flags |= kCheatFlag_OneShot;
1474414722
14745   if(isNull)
14723   if(is_null)
1474614724   {
14747      if(entry->actionListLength > 1)
14725      if(entry->action_list_length > 1)
1474814726         flags |= kCheatFlag_ExtendComment;
1474914727      else
1475014728         flags |= kCheatFlag_Null;
1475114729   }
1475214730
14753   if(isSeparator)
14731   if(is_new_format)
1475414732   {
14755      flags |= kCheatFlag_Null;
14756      flags |= kCheatFlag_Separator;
14733      if(is_separator)
14734      {
14735         flags |= kCheatFlag_Null;
14736         flags |= kCheatFlag_Separator;
14737      }
1475714738   }
1475814739
14759   if(isNewFormat == 0)
14760      flags |= kCheatFlag_OldFormat;
14761
1476214740   entry->flags = (flags & kCheatFlag_InfoMask) | (entry->flags & ~kCheatFlag_InfoMask);
1476314741
14764   /* clear dirty flag as "this entry has already exist in the database" when loaded from a database */
14765   if(isLoadTime)
14742   /* clear dirty flag */
14743   if(is_load_time)
1476614744      entry->flags &= ~kCheatFlag_Dirty;
1476714745
14768   CheckCodeFormat(entry);
14746   check_code_format(entry);
1476914747}
1477014748
1477114749/*--------------------
1477214750  AnalyseCodeFormat
1477314751--------------------*/
1477414752
14775static UINT32 AnalyseCodeFormat(CheatEntry * entry, CheatAction * action)
14753static UINT32 AnalyseCodeFormat(cheat_entry *entry, cheat_action *action)
1477614754{
1477714755   UINT32 errorFlag = 0;
1477814756
r2821r2822
1481214790
1481314791      if(TEST_FIELD(action->type, UserSelectEnable))
1481414792      {
14815         if(!action->originalDataField)
14793         if(!action->original_data)
1481614794            errorFlag |= kErrorFlag_NoSelectableValue;
1481714795      }
1481814796
1481914797      if(type == kLocation_Custom && parameter == kCustomLocation_Select)
1482014798      {
14821         if(entry->actionListLength == 1)
14799         if(entry->action_list_length == 1)
1482214800            errorFlag |= kErrorFlag_NoLabel;
1482314801
14824         if(action->originalDataField)
14802         if(action->original_data)
1482514803            errorFlag |= kErrorFlag_InvalidDataField;
1482614804
14827         if(action->extendData)
14805         if(action->extend_data)
1482814806            errorFlag |= kErrorFlag_InvalidExtendDataField;
1482914807      }
1483014808
r2821r2822
1483214810      {
1483314811         if(type == kLocation_Standard)
1483414812         {
14835            if(!action->extendData || action->extendData == 0xFF || action->extendData == 0xFFFF || action->extendData == 0xFFFFFF)
14813            if(!action->extend_data || action->extend_data == 0xFF || action->extend_data == 0xFFFF || action->extend_data == 0xFFFFFF)
1483614814               errorFlag |= kErrorFlag_InvalidExtendDataField;
1483714815         }
1483814816         else if(type == kLocation_MemoryRegion)
1483914817         {
14840            if(action->extendData != ~0)
14818            if(action->extend_data != ~0)
1484114819               errorFlag |= kErrorFlag_InvalidExtendDataField;
1484214820         }
1484314821      }
r2821r2822
1484914827         UINT8   codeType      = EXTRACT_FIELD(action->type, CodeType);
1485014828         UINT8   codeParameter   = EXTRACT_FIELD(action->type, CodeParameter);
1485114829
14852         if(codeType >= kCodeType_Unused1 && codeType <= kCodeType_Unused4)
14830         if(codeType >= kCodeType_Unused)
1485314831            errorFlag |= kErrorFlag_InvalidCodeType;
1485414832
1485514833         if(action->flags & kActionFlag_CheckCondition)
r2821r2822
1486414842               errorFlag |= kErrorFlag_ForbittenVariable;
1486514843         }
1486614844
14867         if(EXTRACT_FIELD(action->type, Link) == kLink_CopyLink)
14845         if(action->region >= REGION_CPU1 || EXTRACT_FIELD(action->type, AddressSpace) == kAddressSpace_OpcodeRAM)
1486814846         {
14869            if(!entry->flags & kCheatFlag_UserSelect)
14870               errorFlag |= kErrorFlag_CopyLinkWithoutSelect;
14871         }
14872
14873         if(   TEST_FIELD(action->region, RegionFlag) ||
14874            EXTRACT_FIELD(action->type, AddressSpace) == kAddressSpace_OpcodeRAM)
14875         {
1487614847            if(!TEST_FIELD(action->type, RestoreValue))
1487714848               errorFlag |= kErrorFlag_NoRestorePreviousValue;
1487814849         }
1487914850
14880         if(   EXTRACT_FIELD(action->type, CodeType) == kCodeType_VWrite ||
14881            EXTRACT_FIELD(action->type, CodeType) == kCodeType_VRWrite)
14851         if(action->flags & kActionFlag_LimitedMask)
1488214852         {
14883            if(!action->originalDataField)
14884               errorFlag |= kErrorFlag_NoSelectableValue;
14853            if(EXTRACT_FIELD(action->type, AddressSize) > kSearchSize_16Bit)
14854               errorFlag |= kErrorFlag_InvalidLimitedMaskSize;
1488514855         }
1488614856
1488714857         if(action->flags & kActionFlag_Repeat)
1488814858         {
14889            if(!EXTRACT_FIELD(action->extendData, LSB16))
14859            if(!EXTRACT_FIELD(action->extend_data, LSB16))
1489014860               errorFlag |= kErrorFlag_NoRepeatCount;
1489114861         }
1489214862
r2821r2822
1490714877
1490814878         if(codeType == kCodeType_Write)
1490914879         {
14910            if(!action->extendData || action->extendData == 0xFF || action->extendData == 0xFFFF || action->extendData == 0xFFFFFF)
14880            if(!action->extend_data || action->extend_data == 0xFF || action->extend_data == 0xFFFF || action->extend_data == 0xFFFFFF)
1491114881               errorFlag |= kErrorFlag_InvalidExtendDataField;
1491214882         }
1491314883
14914         if(!(action->flags & kActionFlag_Custom))
14884         if((action->flags & kActionFlag_Custom) == 0)
1491514885         {
14916            if(TEST_FIELD(action->region, RegionFlag))
14886            if(action->region < REGION_INVALID)
1491714887            {
14918               UINT8 region = EXTRACT_FIELD(action->region, RegionIndex);
14919
14920               if(region >= REGION_MAX)            errorFlag |= kErrorFlag_OutOfCPURegion;
14921               else if(!region_info_list[region].type)   errorFlag |= kErrorFlag_InvalidCPURegion;
14922               else if(!IsAddressInRange(action, memory_region_length(action->region)))
14923                                             errorFlag |= kErrorFlag_RegionOutOfRange;
14924            }
14925            else
14926            {
1492714888               UINT8 cpu = EXTRACT_FIELD(action->region, CPUIndex);
1492814889
14929               if(!VALID_CPU(cpu))
14890               if(VALID_CPU(cpu) == 0)
1493014891                  errorFlag |= kErrorFlag_OutOfCPURegion;
1493114892               else if(cpu_info_list[cpu].type == 0)
1493214893                  errorFlag |= kErrorFlag_InvalidCPURegion;
r2821r2822
1493414895               if(EXTRACT_FIELD(action->type, AddressSpace) > kAddressSpace_EEPROM)
1493514896                  errorFlag |= kErrorFlag_InvalidAddressSpace;
1493614897            }
14898            else
14899            {
14900               UINT8 region = action->region - REGION_INVALID;
14901
14902               if(region >= REGION_MAX)            errorFlag |= kErrorFlag_OutOfCPURegion;
14903               else if(!region_info_list[region].type)   errorFlag |= kErrorFlag_InvalidCPURegion;
14904               else if(!is_address_in_range(action, memory_region_length(action->region)))
14905                                             errorFlag |= kErrorFlag_RegionOutOfRange;
14906            }
1493714907         }
1493814908      }
1493914909      else
1494014910      {
14941         if(EXTRACT_FIELD(action->type, CodeParameter) >= kCustomCode_Unused1)
14911         if(EXTRACT_FIELD(action->type, CodeParameter) >= CUSTOM_CODE_UNUSED_1)
1494214912            errorFlag |= kErrorFlag_InvalidCustomCode;
1494314913      }
1494414914   }
r2821r2822
1494614916   return errorFlag;
1494714917}
1494814918
14949/*----------------------------------------
14950  CheckCodeFormat - code format checker
14951----------------------------------------*/
14919/*------------------------------------------
14920  check_code_format - code format checker
14921------------------------------------------*/
1495214922
14953static void CheckCodeFormat(CheatEntry * entry)
14923static void check_code_format(cheat_entry *entry)
1495414924{
1495514925   int      i;
14956   UINT8   isError = 0;
14926   UINT8   is_error = 0;
1495714927
14958   for(i = 0; i < entry->actionListLength; i++)
14928   for(i = 0; i < entry->action_list_length; i++)
1495914929   {
14960      CheatAction * action = &entry->actionList[i];
14930      cheat_action *action = &entry->action_list[i];
1496114931
1496214932      if(AnalyseCodeFormat(entry, action))
14963         isError = 1;
14933         is_error = 1;
1496414934   }
1496514935
14966   if(isError)
14936   if(is_error)
1496714937   {
1496814938      entry->flags |= kCheatFlag_HasWrongCode;
14969      messageType = kCheatMessage_WrongCode;
14970      messageTimer = DEFAULT_MESSAGE_TIME;
14939      SET_MESSAGE(kCheatMessage_WrongCode);
1497114940   }
1497214941}
1497314942
r2821r2822
1497514944  BuildLabelIndexTable - create index table for label-selection and calculate index table length
1497614945-------------------------------------------------------------------------------------------------*/
1497714946
14978static void BuildLabelIndexTable(CheatEntry *entry)
14947static void BuildLabelIndexTable(cheat_entry *entry)
1497914948{
1498014949   int i, j, length = 0;
1498114950
14982   entry->labelIndexLength = 0;
14951   entry->label_index_length = 0;
1498314952
14984   for(i = 0, j = 0; i < entry->actionListLength; i++)
14953   for(i = 0, j = 0; i < entry->action_list_length; i++)
1498514954   {
14986      CheatAction * action = &entry->actionList[i];
14955      cheat_action *action = &entry->action_list[i];
1498714956
14988      if((action->flags && kActionFlag_Custom) && EXTRACT_FIELD(action->type, CodeType) == kCustomCode_LabelSelect)
14957      if((action->flags && kActionFlag_Custom) && EXTRACT_FIELD(action->type, CodeType) == CUSTOM_CODE_LABEL_SELECT)
1498914958      {
14990         entry->labelIndex = malloc_or_die(sizeof(entry->labelIndex) * (++entry->labelIndexLength + 1));
14991         entry->labelIndex[j++] = i;
14959         entry->label_index = malloc_or_die(sizeof(entry->label_index) * (++entry->label_index_length + 1));
14960         entry->label_index[j++] = i;
1499214961
14993         length = action->data ? action->data + i : entry->actionListLength;
14962         length = action->data ? action->data + i : entry->action_list_length;
1499414963      }
1499514964      else if(EXTRACT_FIELD(action->type, Link) == kLink_Link)
1499614965      {
1499714966         if(length)
1499814967         {
14999            entry->labelIndex = realloc(entry->labelIndex, sizeof(entry->labelIndex) * (++entry->labelIndexLength + 1));
15000            entry->labelIndex[j++] = i;
14968            entry->label_index = realloc(entry->label_index, sizeof(entry->label_index) * (++entry->label_index_length + 1));
14969            entry->label_index[j++] = i;
1500114970         }
1500214971      }
1500314972   }
1500414973
15005   if(entry->labelIndexLength <= 1)
14974   if(entry->label_index_length <= 1)
1500614975   {
1500714976      logerror("cheat - BuildLabelIndexTable : %s fails to build due to invalid or no link\n", entry->name);
1500814977      return;
r2821r2822
1501114980   if(entry->flags & kCheatFlag_OneShot)
1501214981      entry->selection = 1;
1501314982
15014   //logerror("Cheat - Finish building index table for %s (length = %x)\n", entry->name, entry->labelIndexLength);
15015   //for(i = 0; i < entry->labelIndexLength; i++)
15016   //  logerror("IndexTable[%x] = %x\n",i,entry->labelIndex[i]);
14983   //logerror("Cheat - Finish building index table for %s (length = %x)\n", entry->name, entry->label_index_length);
14984   //for(i = 0; i < entry->label_index_length; i++)
14985   //  logerror("IndexTable[%x] = %x\n",i,entry->label_index[i]);
1501714986
1501814987}
1501914988
r2821r2822
1502514994{
1502614995   int i, j;
1502714996
15028   for(i = 0; i < cheatListLength; i++)
14997   for(i = 0; i < cheat_list_length; i++)
1502914998   {
15030      CheatEntry * entry = &cheatList[i];
14999      cheat_entry *entry = &cheat_list[i];
1503115000
1503215001      if(entry->flags & kCheatFlag_LayerIndex)
1503315002      {
15034         int length = entry->actionList[0].extendData;
15003         int length = entry->action_list[0].extend_data;
1503515004
15036         if(length < cheatListLength && (i + length) <= cheatListLength)
15005         if(length < cheat_list_length && (i + length) <= cheat_list_length)
1503715006         {
15038            entry->layerIndex = entry->actionList[0].address;
15007            entry->layer_index = entry->action_list[0].address;
1503915008
1504015009            for(j = i + 1; j <= i + length; j++)
1504115010            {
15042               CheatEntry * traverse = &cheatList[j];
15011               cheat_entry *traverse = &cheat_list[j];
1504315012
1504415013               if(!(traverse->flags & kCheatFlag_LayerIndex))
15045                  traverse->layerIndex = entry->actionList[0].data;
15014                  traverse->layer_index = entry->action_list[0].data;
1504615015            }
1504715016         }
1504815017      }
r2821r2822
1507915048      "there are no old values!",
1508015049      "saved all memory regions",
1508115050      "region invalidated remains results are",
15082      "debug mode only!",
15051      "failed to allocate memory!",
1508315052      "found wrong code!" };
1508415053
1508515054   char buf[64];
1508615055
15087   if(!messageType)
15056   if(message_type == 0)
1508815057      return;
1508915058
15090   switch(messageType)
15059   switch(message_type)
1509115060   {
1509215061      /* simple message */
1509315062      default:
15094         sprintf(buf, "%s", kCheatMessageTable[messageType]);
15063         sprintf(buf, "%s", kCheatMessageTable[message_type]);
1509515064         break;
1509615065
1509715066      /* message with data */
r2821r2822
1510015069      {
1510115070         search_info *search = get_current_search();
1510215071
15103         sprintf(buf, "%d %s", search->num_results, kCheatMessageTable[messageType]);
15072         sprintf(buf, "%d %s", search->num_results, kCheatMessageTable[message_type]);
1510415073      }
1510515074      break;
1510615075
1510715076      case kCheatMessage_AllCheatSaved:
15108         sprintf(buf, "%d %s", cheatListLength, kCheatMessageTable[messageType]);
15077         sprintf(buf, "%d %s", cheat_list_length, kCheatMessageTable[message_type]);
1510915078         break;
1511015079   }
1511115080
1511215081   /* draw it */
15113   switch(messageType)
15082   switch(message_type)
1511415083   {
1511515084      default:
1511615085         ui_draw_text_box(buf, JUSTIFY_CENTER, 0.5f, 0.9f, UI_FILLCOLOR);
r2821r2822
1512515094      case kCheatMessage_NoSearchRegion:
1512615095      case kCheatMessage_NoOldValue:
1512715096      case kCheatMessage_Max:
15128      case kCheatMessage_DebugOnly:
15097      case kCheatMessage_FailedToAllocate:
1512915098      case kCheatMessage_WrongCode:
1513015099         /* warning message has red background color */
1513115100         ui_draw_text_box(buf, JUSTIFY_CENTER, 0.5f, 0.9f, UI_REDCOLOR);
r2821r2822
1513315102   }
1513415103
1513515104   /* decrement message timer */
15136   if(--messageTimer == 0)
15137      messageType = 0;
15105   if(--message_timer == 0)
15106      message_type = 0;
1513815107}
1513915108
1514015109/*---------------------
r2821r2822
1515115120         return info->address_chars_needed;
1515215121   }
1515315122
15154   return 8;
15123   return DEFAULT_ADDRESS_LENGTH;
1515515124}
1515615125
1515715126/*------------------
r2821r2822
1516015129
1516115130static char *get_region_name(UINT8 region)
1516215131{
15163   if(TEST_FIELD(region, RegionIndex))
15132   if(region < REGION_INVALID)
1516415133   {
15165      if(region >= REGION_INVALID && region < REGION_MAX)
15166         return (char *)kRegionNames[EXTRACT_FIELD(region, RegionIndex)];
15134      if(VALID_CPU(region))
15135         return (char *)kRegionNames[EXTRACT_FIELD(region, CPUIndex) + 1];
1516715136   }
1516815137   else
1516915138   {
15170      if(VALID_CPU(region))
15171         return (char *)kRegionNames[EXTRACT_FIELD(region, CPUIndex) + 1];
15139      if(region < REGION_MAX)
15140         return (char *)kRegionNames[region - REGION_INVALID];
1517215141   }
1517315142
1517415143   return (char *)kRegionNames[0];
src/emu/validity.c
r2821r2822
2828
2929
3030/***************************************************************************
31    COMPILE-TIME VALIDATION
32***************************************************************************/
33
34/* if the following lines error during compile, your PTR64 switch is set incorrectly in the makefile */
35#ifdef PTR64
36UINT8 your_ptr64_flag_is_wrong[(int)(sizeof(void *) - 7)];
37#else
38UINT8 your_ptr64_flag_is_wrong[(int)(5 - sizeof(void *))];
39#endif
40
41
42
43/***************************************************************************
3144    CONSTANTS
3245***************************************************************************/
3346
r2821r2822
12111224   /* allocate the input ports */
12121225   portlist = input_port_config_alloc(driver->ipt, errorbuf, sizeof(errorbuf));
12131226   if (errorbuf[0] != 0)
1227   {
12141228      mame_printf_error("%s: %s has input port errors:\n%s\n", driver->source_file, driver->name, errorbuf);
1229      error = TRUE;
1230   }
12151231
12161232   /* check for duplicate tags */
12171233   for (port = portlist; port != NULL; port = port->next)
src/emu/romload.c
r2821r2822
198198      {
199199         const char *biosname = ROM_GETHASHDATA(rom);
200200         int bios_flags = ROM_GETBIOSFLAGS(rom);
201         char bios_number[3];
201         char bios_number[20];
202202
203203         /* Allow '-bios n' to still be used */
204204         sprintf(bios_number, "%d", bios_flags - 1);
src/mess/machine/bebox.c
r2821r2822
211211      int inputline;
212212   } crossproc_map[] =
213213   {
214      { 0x40000000, 0, 1, PPC_INPUT_LINE_SMI },
215      { 0x20000000, 1, 1, PPC_INPUT_LINE_SMI },
216      { 0x08000000, 0, 0, PPC_INPUT_LINE_TLBISYNC },
217      { 0x04000000, 1, 0, PPC_INPUT_LINE_TLBISYNC }
214      { 0x40000000, 0, 1, 0/*PPC_INPUT_LINE_SMI*/ },
215      { 0x20000000, 1, 1, 0/*PPC_INPUT_LINE_SMI*/ },
216      { 0x08000000, 0, 0, 0/*PPC_INPUT_LINE_TLBISYNC*/ },
217      { 0x04000000, 1, 0, 0/*PPC_INPUT_LINE_TLBISYNC*/ }
218218   };
219219   int i, line;
220220   UINT32 old_crossproc_interrupts = bebox_crossproc_interrupts;
r2821r2822
232232
233233         if (LOG_INTERRUPTS)
234234         {
235/*
235236            logerror("bebox_crossproc_interrupts_w(): CPU #%d %s %s\n",
236237               crossproc_map[i].cpunum, line ? "Asserting" : "Clearing",
237238               (crossproc_map[i].inputline == PPC_INPUT_LINE_SMI) ? "SMI" : "TLBISYNC");
239               */
238240         }
239241
240242         cpunum_set_input_line(machine, crossproc_map[i].cpunum, crossproc_map[i].inputline, line);
r2821r2822
947949}
948950
949951
950static void scsi53c810_irq_callback(running_machine *machine)
952static void scsi53c810_irq_callback(running_machine *machine, int value)
951953{
952   bebox_set_irq_bit(machine, 21, 1);
953   bebox_set_irq_bit(machine, 21, 0);
954   bebox_set_irq_bit(machine, 21, value);
954955}
955956
956957
src/mess/mess.mak
r2821r2822
175175#CPUS += V810
176176#CPUS += M37702
177177#CPUS += M37710
178#CPUS += PPC403
178#CPUS += PPC403GA
179#CPUS += PPC403GCX
179180#CPUS += PPC601
180181CPUS += PPC602
181182CPUS += PPC603
183CPUS += PPC603E
184#CPUS += PPC603R
182185#CPUS += MPC8240
183186#CPUS += SE3208
184187#CPUS += MC68HC11
r2821r2822
212215CPUS += SM8500
213216CPUS += V30MZ
214217#CPUS += CXD8661R
218#CPUS += PPC403
215219#CPUS += SSP1610
216220CPUS += UPD7801
217221CPUS += M68008
src/mess/drivers/bebox.c
r2821r2822
8080ADDRESS_MAP_END
8181
8282
83static const ppc_config bebox_ppc_config =
84{
85   PPC_MODEL_603,   /* 603 "Wart"                   */
86   0x10,      /* Multiplier 1.0, Bus = 66MHz, Core = 66MHz    */
87   BUS_FREQUENCY_66MHZ
88};
89
90static const ppc_config bebox2_ppc_config =
91{
92   PPC_MODEL_603E,   /* 603E "Stretch", version 1.3          */
93   0x19,      /* Multiplier 2.0, Bus = 66MHz, Core = 133MHz   */
94   BUS_FREQUENCY_66MHZ
95};
96
97
9883static MACHINE_DRIVER_START( bebox )
9984   /* basic machine hardware */
10085   MDRV_CPU_ADD_TAG("ppc1", PPC603, 66000000)   /* 66 MHz */
101   MDRV_CPU_CONFIG(bebox_ppc_config)
10286   MDRV_CPU_PROGRAM_MAP(bebox_mem, 0)
10387
10488   MDRV_CPU_ADD_TAG("ppc2", PPC603, 66000000)   /* 66 MHz */
105   MDRV_CPU_CONFIG(bebox_ppc_config)
10689   MDRV_CPU_PROGRAM_MAP(bebox_mem, 0)
10790
10891   MDRV_INTERLEAVE(1)
r2821r2822
154137
155138static MACHINE_DRIVER_START( bebox2 )
156139   MDRV_IMPORT_FROM( bebox )
157   MDRV_CPU_REPLACE("ppc1", PPC603, 133000000)   /* 133 MHz */
158   MDRV_CPU_CONFIG(bebox2_ppc_config)
159
160   MDRV_CPU_REPLACE("ppc2", PPC603, 133000000)   /* 133 MHz */
161   MDRV_CPU_CONFIG(bebox2_ppc_config)
140   MDRV_CPU_REPLACE("ppc1", PPC603E, 133000000)   /* 133 MHz */
141   MDRV_CPU_REPLACE("ppc2", PPC603E, 133000000)   /* 133 MHz */
162142MACHINE_DRIVER_END
163143
164144static INPUT_PORTS_START( bebox )
docs/messnew.txt
r2821r2822
127127
128128Source Changes:
129129----------------
130- The core is based on MAME 0.125u3.  This incorporates all features of the
130- The core is based on MAME 0.125u4.  This incorporates all features of the
131131  update to this core.  [MAME team]
132132
133133- Fixed performance problems with -triplebuffer.  (bug #1539) [Justin Kerk]
makefile
r2821r2822
111111# a native backend
112112# FORCE_DRC_C_BACKEND = 1
113113
114# uncomment next line to use DRC PowerPC engine
115X86_PPC_DRC = 1
116114
117115
118
119116#-------------------------------------------------
120117# specify build options; see each option below
121118# for details
r2821r2822
159156# sanity check the configuration
160157#-------------------------------------------------
161158
162# disable DRC cores for 64-bit builds
163ifdef PTR64
164X86_PPC_DRC =
165endif
166
167159# specify a default optimization level if none explicitly stated
168160ifndef OPTIMIZE
169161ifndef SYMBOLS

Previous 15994 Revisions Next


© 1998-2018 The MESS Team