kyuseo의 게임 프로그래밍

마메 (MAME) 소스코드 공개 본문

개발자 팁

마메 (MAME) 소스코드 공개

kyuseo 2008. 7. 17. 15:03

개요..

 

인터넷 서핑 도중 마메 (MAME) 소스코드가 공개된 사이트가 있어서 링크 해드립니다.

 

MAME Source Code

 

링크 : http://mamedev.org/source/src/index.html

 

아래 코드를 보면 알겠지만 원본 소스코드 그대로 이네요.

 

모두 다 저작권이 있을 텐데 어떻게 공개가 되었는지 궁금하네요.

 

지저분해질 수 밖에 없는 C코드인데 정말 깔끔하게 잘 짰네요.

 

 

1943 및 텐가이등 각종 Psikyo 소스 코드 중 일부

 

아래코드를 보면 알겠지만 코드를 하나 작성하여 1943, 사무라이 에이스, 1945 스트라이커스, 텐가이 등 여러 코드에서 재활용하여 사용하였네요.

 

http://mamedev.org/source/src/mame/drivers/psikyo.c.html

1  /***************************************************************************

    2  

    3                              -= Psikyo Games =-

    4  

    5                  driver by   Luca Elia (l.elia@tin.it)

    6  

    7  

    8  CPU:    68EC020 + PIC16C57 [Optional MCU]

    9  

   10  Sound:  Z80A                +   YM2610

   11     Or:  LZ8420M (Z80 core)  +   YMF286-K (YM2610 compatible)

   12  

   13  Chips:  PS2001B

   14          PS3103

   15          PS3204

   16          PS3305

   17  

   18  ---------------------------------------------------------------------------

   19  Name                    Year    Board          Notes

   20  ---------------------------------------------------------------------------

   21  Sengoku Ace         (J) 1993    SH201B

   22  Gun Bird            (J) 1994    KA302C

   23  Battle K-Road       (J) 1994    ""

   24  Strikers 1945       (J) 1995    SH403/SH404    SH403 is similiar to KA302C

   25  Tengai              (J) 1996    SH404          SH404 has MCU, ymf278-b for sound and gfx banking

   26  ---------------------------------------------------------------------------

   27  

   28  To Do:

   29  

   30  - Flip Screen support

   31  

   32  ***************************************************************************/
										

   33  

   34  /***** Gun Bird Japan Crash Notes

   35  

   36  The Following Section of Code in Gunbird causes reads from the

   37  0x080000 - 0x0fffff region

   38  

   39  002894: E2817000           asr.l   #1, D1

   40  002896: 70001030           moveq   #$0, D0

   41  002898: 10301804           move.b  ($4,A0,D1.l), D0   <-- *

   42  00289C: 60183202           bra     28b6

   43  00289E: 3202C2C7           move.w  D2, D1

   44  0028A0: C2C77000           mulu.w  D7, D1

   45  0028A2: 70003005           moveq   #$0, D0

   46  0028A4: 3005D280           move.w  D5, D0

   47  0028A6: D280E281           add.l   D0, D1

   48  0028A8: E2812071           asr.l   #1, D1

   49  0028AA: 20713515           movea.l ([A1],D3.w*4), A0

   50  0028AE: 70001030           moveq   #$0, D0

   51  0028B0: 10301804           move.b  ($4,A0,D1.l), D0   <-- *

   52  0028B4: E880720F           asr.l   #4, D0

   53  0028B6: 720FC041           moveq   #$f, D1

   54  

   55  This causes Gunbird to crash if the ROM Region Size

   56  allocated during loading is smaller than the SMH_ROM

   57  region as it trys to read beyond the allocated rom region

   58  

   59  This was pointed out by Bart Puype

   60  

   61  *****/
										

   62  

   63  #include
										"driver.h"
										

   64  #include
										"sound/2610intf.h"
										

   65  #include
										"sound/ymf278b.h"
										

   66  

   67  

   68  /* Variables defined in video */
										

   69  

   70  extern UINT32 *psikyo_vram_0, *psikyo_vram_1, *psikyo_vregs;

   71  extern
										int psikyo_ka302c_banking;

   72  

   73  /* Functions defined in video */
										

   74  

   75  WRITE32_HANDLER( psikyo_vram_0_w );

   76  WRITE32_HANDLER( psikyo_vram_1_w );

   77  

   78  VIDEO_START( psikyo );

   79  VIDEO_EOF( psikyo );

   80  VIDEO_UPDATE( psikyo );

   81  

   82  extern
										void psikyo_switch_banks( int tmap, int bank );

   83  

   84  /* Variables only used here */
										

   85  

   86  static UINT8 psikyo_soundlatch;

   87  static
										int z80_nmi, mcu_status;

   88  

   89  static MACHINE_RESET( psikyo )

   90  {

   91      z80_nmi = mcu_status = 0;

   92  }

   93  

   94  

   95  /***************************************************************************

   96  

   97  

   98                                  Main CPU

   99  

  100  

  101  ***************************************************************************/
										

  102  

  103  static
										int psikyo_readcoinport(running_machine *machine, int has_mcu)

  104  {

  105      int ret = input_port_read(machine, "COIN") & ~0x84;

  106  

  107      if (has_mcu)

  108      {

  109          /* Don't know exactly what this bit is, but s1945 and tengai

  110             both spin waiting for it to go low during POST.  Also,

  111             the following code in tengai (don't know where or if it is

  112             reached) waits for it to pulse:

  113  

  114             01A546:  move.b  (A2), D0    ; A2 = $c00003

  115             01A548:  andi.b  #$4, D0

  116             01A54C:  beq     $1a546

  117             01A54E:  move.b  (A2), D0

  118             01A550:  andi.b  #$4, D0

  119             01A554:  bne     $1a54e

  120  

  121             Interestingly, s1945jn has the code that spins on this bit,

  122             but said code is never reached.  Prototype? */
										

  123          if (mcu_status) ret |= 0x04;

  124          mcu_status = !mcu_status;   /* hack */
										

  125      }

  126  

  127      if (z80_nmi)

  128      {

  129          ret |= 0x80;

  130  

  131          /* main CPU might be waiting for sound CPU to finish NMI,

  132             so set a timer to give sound CPU a chance to run */
										

  133          timer_call_after_resynch(NULL, 0, NULL);

  134  //      logerror("PC %06X - Read coin port during Z80 NMI\n", activecpu_get_pc());
										

  135      }

  136  

  137      return ret;

  138  }

  139  

  140  static READ32_HANDLER( sngkace_input_r )

  141  {

  142      switch(offset)

  143      {

  144          case 0x0:   return (input_port_read(machine, "IN0") << 16) | 0xffff;

  145          case 0x1:   return (input_port_read(machine, "DSW1") << 16) | input_port_read(machine, "DSW3");

  146          case 0x2:   return (psikyo_readcoinport(machine, 0) << 16) | input_port_read(machine, "DSW2");

  147          default:    logerror("PC %06X - Read input %02X !\n", activecpu_get_pc(), offset * 2);

  148                      return 0;

  149      }

  150  }

  151  

  152  static READ32_HANDLER( gunbird_input_r )

  153  {

  154      switch(offset)

  155      {

  156          case 0x0:   return (input_port_read(machine, "IN0") << 16) | psikyo_readcoinport(machine, 0);

  157          case 0x1:   return (input_port_read(machine, "DSW1") << 16) | input_port_read(machine, "DSW2");

  158          default:    logerror("PC %06X - Read input %02X !\n", activecpu_get_pc(), offset*2);

  159                      return 0;

  160      }

  161  }

  162  

  163  

  164  static TIMER_CALLBACK( psikyo_soundlatch_callback )

  165  {

  166      psikyo_soundlatch = param;

  167      cpunum_set_input_line(machine, 1, INPUT_LINE_NMI, ASSERT_LINE);

  168      z80_nmi = 1;

  169  }

  170  

  171  static WRITE32_HANDLER( psikyo_soundlatch_w )

  172  {

  173      if (ACCESSING_BITS_0_7)

  174          timer_call_after_resynch(NULL, data & 0xff, psikyo_soundlatch_callback);

  175  }

  176  

  177  /***************************************************************************

  178                          Strikers 1945 / Tengai

  179  ***************************************************************************/
										

  180  

  181  static WRITE32_HANDLER( s1945_soundlatch_w )

  182  {

  183      if (ACCESSING_BITS_16_23)

  184          timer_call_after_resynch(NULL, (data >> 16) & 0xff, psikyo_soundlatch_callback);

  185  }

  186  

  187  static
										const UINT8 s1945_table[256] = {

  188      0x00, 0x00, 0x64, 0xae, 0x00, 0x00, 0x26, 0x2c, 0x00, 0x00, 0x2c, 0xda, 0x00, 0x00, 0x2c, 0xbc,

  189      0x00, 0x00, 0x2c, 0x9e, 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x31, 0x10, 0x00, 0x00, 0xc5, 0x1e,

  190      0x00, 0x00, 0x32, 0x90, 0x00, 0x00, 0xac, 0x5c, 0x00, 0x00, 0x2b, 0xc0

  191  };

  192  

  193  static
										const UINT8 s1945a_table[256] = {

  194      0x00, 0x00, 0x64, 0xbe, 0x00, 0x00, 0x26, 0x2c, 0x00, 0x00, 0x2c, 0xda, 0x00, 0x00, 0x2c, 0xbc,

  195      0x00, 0x00, 0x2c, 0x9e, 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x31, 0x10, 0x00, 0x00, 0xc7, 0x2a,

  196      0x00, 0x00, 0x32, 0x90, 0x00, 0x00, 0xad, 0x4c, 0x00, 0x00, 0x2b, 0xc0

  197  };

  198  

  199  static
										const UINT8 s1945j_table[256] = {

  200      0x00, 0x00, 0x64, 0xb6, 0x00, 0x00, 0x26, 0x2c, 0x00, 0x00, 0x2c, 0xda, 0x00, 0x00, 0x2c, 0xbc,

  201      0x00, 0x00, 0x2c, 0x9e, 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x31, 0x10, 0x00, 0x00, 0xc5, 0x92,

  202      0x00, 0x00, 0x32, 0x90, 0x00, 0x00, 0xac, 0x64, 0x00, 0x00, 0x2b, 0xc0

  203  };

  204  

  205  static UINT8 s1945_mcu_direction, s1945_mcu_latch1, s1945_mcu_latch2, s1945_mcu_inlatch, s1945_mcu_index;

  206  static UINT8 s1945_mcu_latching, s1945_mcu_mode, s1945_mcu_direction, s1945_mcu_control, s1945_mcu_bctrl;

  207  static
										const UINT8 *s1945_mcu_table;

  208  

  209  static
										void s1945_mcu_init(const UINT8 *mcu_table)

  210  {

  211      s1945_mcu_direction = 0x00;

  212      s1945_mcu_inlatch = 0xff;

  213      s1945_mcu_latch1 = 0xff;

  214      s1945_mcu_latch2 = 0xff;

  215      s1945_mcu_latching = 0x5;

  216      s1945_mcu_control = 0xff;

  217      s1945_mcu_index = 0;

  218      s1945_mcu_mode = 0;

  219      s1945_mcu_table = mcu_table;

  220      s1945_mcu_bctrl = 0x00;

  221  }

  222  

  223  static WRITE32_HANDLER( s1945_mcu_w )

  224  {

  225      // Accesses are always bytes, so resolve it
										

  226      int suboff;

  227      for(suboff=0; suboff < 3; suboff++)

  228          if((0xff << (8*suboff)) & mem_mask)

  229              break;

  230      data >>= 8*suboff;

  231      offset = offset*4+4+(3-suboff);

  232  

  233      switch(offset) {

  234      case 0x06:

  235          s1945_mcu_inlatch = data;

  236          break;

  237      case 0x08:

  238          s1945_mcu_control = data;

  239          break;

  240      case 0x09:

  241          s1945_mcu_direction = data;

  242          break;

  243      case 0x07:

  244          psikyo_switch_banks(1, (data >> 6) & 3);

  245          psikyo_switch_banks(0, (data >> 4) & 3);

  246          s1945_mcu_bctrl = data;

  247          break;

  248      case 0x0b:

  249          switch(data | (s1945_mcu_direction ? 0x100 : 0)) {

  250          case 0x11c:

  251              s1945_mcu_latching = 5;

  252              s1945_mcu_index = s1945_mcu_inlatch;

  253              break;

  254          case 0x013:

  255  //          logerror("MCU: Table read index %02x\n", s1945_mcu_index);
										

  256              s1945_mcu_latching = 1;

  257              s1945_mcu_latch1 = s1945_mcu_table[s1945_mcu_index];

  258              break;

  259          case 0x113:

  260              s1945_mcu_mode = s1945_mcu_inlatch;

  261              if(s1945_mcu_mode == 1) {

  262                  s1945_mcu_latching &= ~1;

  263                  s1945_mcu_latch2 = 0x55;

  264              } else {

  265                  // Go figure.
										

  266                  s1945_mcu_latching &= ~1;

  267                  s1945_mcu_latching |= 2;

  268              }

  269              s1945_mcu_latching &= ~4;

  270              s1945_mcu_latch1 = s1945_mcu_inlatch;

  271              break;

  272          case 0x010:

  273          case 0x110:

  274              s1945_mcu_latching |= 4;

  275              break;

  276          default:

  277  //          logerror("MCU: function %02x, direction %02x, latch1 %02x, latch2 %02x (%x)\n", data, s1945_mcu_direction, s1945_mcu_latch1, s1945_mcu_latch2, activecpu_get_pc());
										

  278              break;

  279          }

  280          break;

  281      default:

  282  //      logerror("MCU.w %x, %02x (%x)\n", offset, data, activecpu_get_pc());
										

  283          ;

  284      }

  285  }

  286  

  287  static READ32_HANDLER( s1945_mcu_r )

  288  {

  289      switch(offset) {

  290      case 0: {

  291          UINT32 res;

  292          if(s1945_mcu_control & 16) {

  293              res = s1945_mcu_latching & 4 ? 0x0000ff00 : s1945_mcu_latch1 << 8;

  294              s1945_mcu_latching |= 4;

  295          } else {

  296              res = s1945_mcu_latching & 1 ? 0x0000ff00 : s1945_mcu_latch2 << 8;

  297              s1945_mcu_latching |= 1;

  298          }

  299          res |= s1945_mcu_bctrl & 0xf0;

  300          return res;

  301      }

  302      case 1:

  303          return (s1945_mcu_latching << 24) | 0x08000000;

  304      }

  305      return 0;

  306  }

  307  

  308  static READ32_HANDLER( s1945_input_r )

  309  {

  310      switch(offset)

  311      {

  312          case 0x0:   return (input_port_read(machine, "IN0") << 16) | psikyo_readcoinport(machine, 1);

  313          case 0x1:   return (((input_port_read(machine, "DSW1") << 16) | input_port_read(machine, "DSW2")) & 0xffff000f) | s1945_mcu_r(machine, offset-1, mem_mask);

  314          case 0x2:   return s1945_mcu_r(machine, offset-1, mem_mask);

  315          default:    logerror("PC %06X - Read input %02X !\n", activecpu_get_pc(), offset*2);

  316                      return 0;

  317      }

  318  }

  319