|
Dark-Destroy
元老会员
积分 8312
发帖 3551
注册 2003-3-22
状态 离线
|
『楼 主』:
[转帖]認識MAME DRIVER VOL.1
作者: zchou (Nelson Chou) 看板: Emulator
標題: 認識MAME DRIVER VOL.1(翻譯版-1)
時間: Tue Sep 8 18:25:46 1998
┌───────────────────────────────┐
│ │
│ 這是一系列介紹MAME DRIVER的第一份文件,不過原作者只寫到第一 │
│ 份文件,等到他繼續寫下去,跟著再繼續翻譯下去. │
│ │
│ 我承認有些地方的確是翻的不好,如果發現有任何疑問的地方,請參 │
│ 照原文!對於內文翻譯上有任何意見,也請不吝指教! │
│ │
│ NELSON CHOU │
│ │
└───────────────────────────────┘
認識 MAME DRIVER
Volume 1: Data Structures v1.0
by Daniel Boris
目錄表
1.0 導論
2.0 /drivers/rockola.c
2.1 GameDriver Structure
2.2 MachineDriver Structure
2.3 ROM Definition
2.4 MemoryReadAddress Structure
2.5 MemoryWriteAddress Structure
2.6 Input Ports
2.7 GfxDecodeInfo Structure
2.8 GfxLayout Structure
3.0 Linking in the Driver
1.0 導論
這個文件的目的在於幫助人們了解一個MAME DRIVER如何運作,並且幫助想
要寫自己的MAME DRIVER的人們.一個DRIVER是一群定義一個特定ARCADE遊
戲運作的MAME原始檔中一部份的檔案組合.
這個文件之中,我將描述遊戲ZARZON的DRIVER.在閱讀這個文件之前,你應
該先讀過我的Decoding Schematics文件,這文件描述了ZARZON的硬體.(
譯注:這個名稱換了!變成"轉換概圖(Schematics)成為模擬器"
我所要描述的DRIVER是基於MAME 0.33 DOS版原始碼.這裡描述的某些東東
可能在其他版的MAME原始檔中沒有加入.
ZARZON DRIVER 可以在兩個檔案中找到,/driver/rockola.c 及
/vidhrdw/rockola.c.會在這裡找到是因為硬體十分類似於某些其他的
ROCKOLA遊戲.製作MAME的資料結構以幾個層級的方式連結在一起,所以你
可能不太了解某些在較高層級的事物,直到閱讀過較低層級之後.
2.0 /drivers/rockola.c
這個DRIVER的第一部份包含在 /drivers/ 目錄中.在這裡的檔案是MAME
DRIVER的主要部份.它們包含了定義被模擬機器如何運作的所有資料結構.
2.1 GameDriver Structure
MAME中每個遊戲的最高層結構是GameDriver結構.ZARZON的GameDriver
Structure 看起來像這樣(每行開頭都編上編號,所以在內文中可以容易的
參考到行數.)
1 struct GameDriver zarzon_driver =
2 {
3 __FILE__,
4 &satansat_driver,
5 "zarzon",
6 "Zarzon",
7 "1981",
8 "[SNK] (Taito America license)",
9 "Dan Boris\nTheo Philips",
10 0,
11 &satansat_machine_driver,
12
13 zarzon_rom,
14 0, 0,
15 0,
16 0, /* sound_prom */
17
18 satansat_input_ports,
19
20 satansat_color_prom,0,0,
21 ORIENTATION_ROTATE_90,
22
23 0, 0
24 };
第一行開始於DRIVER的宣告.結構的名稱,在這個例子 zarzon_driver,通
常是用來開始遊戲的名稱後面加上"_driver".
第三行DRIVER所包含的原始檔.應該總是設成:__FILE__
如果這個遊戲是另一個遊戲的複製品,則第四行應該是指到母遊戲的
GameDriver結構的指標.舉例來說,ZARZON就是SATAN OF SATURN的複製品.
第五行是用來開始遊戲的名稱,同時也是放置這個遊戲ROM的目錄/壓縮檔目
錄.每個遊戲應該最多以8個字母命名.
第6行是遊戲的全名.
第7行是這個遊戲出現的年代,第8行是生產這個遊戲的公司名稱.第9行是
DRIVER作者,當DRIVER開始時所顯示的作者.
第10行設計成保持不同的旗標值.現在只有一個旗標,定義為GAME_NOT_WORKING
,表示遊戲現在不能執行.
第11行是指到MachineDriver結構的指標,這個結構定義了這個機器的硬體
如何運作.可能有超過一個遊戲能在同樣機器硬體上執行.例如有一堆不同
版本的小精靈(PAC-MAN)都可在相同的硬體上執行,所以他們都能共用相同
的MachineDriver結構.
第13行是指到一個結構的指標,定義了這個遊戲使用哪些ROM及哪裡載入它
們.
第14行中的兩個0可以是一個指標指到解譯ROM的常式及一個指標指到解譯
ROM 中的運作碼(OPCODE).這是選擇性的並且在這個遊戲中是沒有使用的.
第15行是一個指標指到SAMPLES檔名陣列,這是遊戲用來產生聲音的檔名.這
個遊戲現在不使用SAMPLES,所以打"0".
第16行是一個指標到聲音ROM資料.這個遊戲不使用.
第18行是一個指標指到這個遊戲的InputPort結構.注意那裡,這是定義遊
戲的一部份而不是硬體的一部份,因為這是負責那些像改變功能的指撥開
關(DIPSWITCH).
第20行中的3個數值是一些指標指到調色盤及顏色表,儲放於DRIVER之中.
這些表格現在被從程式碼中移走並且放在ROM IMAGES中,就像他們在原來遊
戲中的位置,所以這是從磁碟載入這些表格的最好方式.第1個數值是一個
指到這個遊戲的調色盤ROM的指標,第2個是指到目前顏色值的表格,用來產
生這個遊戲的調色盤,第3個是指到色彩鎖定表格(color lookup table)的
指標.
第21行定義了遊戲顯示器的方向.看看driver.h,有這一行的合法數值.
第23行是一些指標到用來儲放及載入高分記錄的常式.ZARZON現在沒有儲
存高分記錄,所以這裡是"0".
2.2 MachineDriver Structure
下一層資料結構是MachineDriver.這個結構定義了遊戲執行的硬體.本例
中,ZARZON是SATAN OF SATURN的一個複製品,所以MachineDriver結構被呼
叫為satansat_machine_driver.
1 static struct MachineDriver satansat_machine_driver =
2 {
3 /* 基本硬體結構*/
4 {
5 {
6 CPU_M6502,
7 11289000/16, /* 700 kHz */
8 0,
9 satansat_readmem,satansat_writemem,0,0,
10 satansat_interrupt,2
11 },
12 },
13 60, DEFAULT_60HZ_VBLANK_DURATION, /* 每秒頁框數, vblank 持續時間 */
14 1, /* 單CPU,不須間隔(interleaving) */
15 0,
16
17 /* 影像硬體 */
18 32*8, 32*8, { 0*8, 32*8-1, 0*8, 28*8-1 },
19 satansat_gfxdecodeinfo,
20 32,4*4 + 4*4,
21 satansat_vh_convert_color_prom,
22
23 VIDEO_TYPE_RASTER | VIDEO_SUPPORTS_DIRTY,
24 0,
25 generic_vh_start,
26 generic_vh_stop,
27 satansat_vh_screenrefresh,
28
29 /* 聲音硬體 */
30 0,0,0,0
31 };
第1行開始這個遊戲的MachineDriver的定義.
第4-12行定義這個遊戲使用的CPU.可能一個遊戲有多個CPU.每個CPU都必
須有自己的MachineCPU結構,並且每一個都要一個接一個的列出來在
MachineDriver結構中.ZARZON只使用一個CPU.
第6行定義CPU的種類,本例中是一個6502.
第7行是CPU執行時的時序速度.保持遊戲在正確的速度執行是很重要的.以
ZARZON來說,它是11289000/16.會這樣寫是因為在ZARZON基版上的主時序
是11289000並且被16除由基版上的硬體.(譯注:這表示另一篇寫錯了!)
第8行是個處理器所使用記憶體區域(memory region).當你載入ROM時,為
了從ROM處保存資料,你要定義一個或更多個記憶體區域.每個處理器要有
自己的記憶體區域並且可能有其他的記憶體區域配置給像圖形ROM等.本例
中,這個CPU所使用的記憶體區域是"0".
第9行包含了4個指標指到定義如何處理記憶體及IO存取的結構.這些指標
是Memory Read, Memory Write, IO Read, IO Write.6502沒有IO存取,所
以這裡沒有定義.
第10行決定了向量"BLANK中斷"如何處理.第一個數值是一個指標指到處理
中斷的常式.第二個數值是每個頁框(FRAME)有多少中斷,這裡通常是"1".
第13行標明了這個遊戲每秒產生多少影像頁框,這行的第二個數值標明了
VBLANK最少需要多長(看看driver.h可以得到更多資訊).
第14行是CPU間隔值(interleave value).這個數值決定了對在機器中每個
CPU,MAME要多頻繁的切換.較高的數值,MAME將更為頻繁的切換於處理器之
間.更頻繁的切換,模擬的速度會越慢,但是有時是必需的為了保持每個CPU
同步於其他的CPU.因為ZARZON只有一個CPU,所以這個數值設定為"1".
第15行是一個指標指到用於處理機器硬體所需執行的任何特殊初始動作的
常式.
第18行定義了以點來說,遊戲畫面的長寬,及畫面的可視範圍多大.因為
ZARZON是一個瓷磚為主的繪圖方式(tile based graphics),(譯注:這種方
式的說法很多,例如作者的另一篇是用"character based display",日式
的說法是"動畫拼合"32*8標示用來標明畫面是32個瓷磚交錯及每個瓷磚
是8個像點寬,畫面也是32*8個像點寬.接下來4個數值定義了畫面可視範圍
的角落.以ZARZON來說,左上角是0,0,右下角是255,223.
19行是一個指標指到定義圖型在圖形ROM中以怎樣格式儲放的資料結構.
20行中,第一個數值是這個遊戲色彩調色盤中的顏色數.第二個數值是在遊
戲中顏色鎖定表格(color lookup table)中的項目數.
21行是一個指標指向被呼叫用以轉換原始ROM資料成為實際調色盤RGB數值
的常式.這個常式通常可以在 /vidhrdw/ 目錄找到.
23行是顏色屬性.這個屬性標明了這是一個光域遊戲(raster game ,與向
量相反之意)並且支援dirty rectangle處理.完整的屬性列表可以參考
driver.h.
Line 24 ???
25,26,27行是一些指標分別的指到初始顯示器硬體,停止顯示器硬體,及更
新螢幕的常式.ZARZON使用了MAME通用的初始及停止常式,因為對影像來說
,不須任何特定的設定.大部分的遊戲有自己的螢幕更新常式,負責專門為
這個遊戲實際上繪製影像顯示的常式.
這個結構其餘的部份描述聲音的硬體.因為ZARZON現在不支援聲音,這裡我
不討論DRIVER的這一個部份.
2.3 ROM Definition
DRIVER下一個段落定義了遊戲需要載入的ROM IMAGE及哪裡可以載入它們.
這一個段落看起來不像正常的C程式碼,因為使用巨集會使得它可讀性更高.
1 ROM_START( zarzon_rom )
2 ROM_REGION(0x10000) /* 程式碼用的64k */
3 ROM_LOAD( "ZARZ122.07", 0x4000, 0x0800, 0xa260b9f8 )
4 ROM_LOAD( "ZARZ123.08", 0x4800, 0x0800, 0xf2b8072c )
5 ROM_LOAD( "ZARZ124.09", 0x5000, 0x0800, 0xdea47b9a )
6 ROM_LOAD( "ZARZ125.10", 0x5800, 0x0800, 0xa30532d5 )
7 ROM_LOAD( "ZARZ126.13", 0x6000, 0x0800, 0x043c84ba )
8 ROM_LOAD( "ZARZ127.14", 0x6800, 0x0800, 0xa3f1286b )
9 ROM_LOAD( "ZARZ128.15", 0x7000, 0x0800, 0xfbc89252 )
10 ROM_LOAD( "ZARZ129.16", 0x7800, 0x0800, 0xc7440c84 )
11 ROM_RELOAD( 0xf800, 0x0800 ) /* 保留給RESET/中斷向量 */
12 ROM_LOAD( "ZARZ130.22", 0x8000, 0x0800, 0x78362c82 )
13 ROM_LOAD( "ZARZ131.23", 0x8800, 0x0800, 0x566914b5 )
14 ROM_LOAD( "ZARZ132.24", 0x9000, 0x0800, 0x7c4f3143 )
15
16 ROM_REGION(0x1000) /* 圖形用的暫存空間 (在轉換之後的排列) */
17 ROM_LOAD( "ZARZ135.73", 0x0000, 0x0800, 0xbc67fa61 )
18 ROM_LOAD( "ZARZ136.75", 0x0800, 0x0800, 0x2364fe46 )
19
20 ROM_REGION(0x1000) /* Vanguard-style 聲音區域聲音資料 */
21 ROM_LOAD( "ZARZ133.53", 0x0000, 0x0800, 0x4b404b14 )
22 ROM_LOAD( "ZARZ134.54", 0x0800, 0x0800, 0x01380400 )
23 ROM_END
第1行定義了這個遊戲的ROM資訊的開頭,括號中的名稱(zarzon_rom)是指
到GameDriver結構的名稱.
第2行定義了ROM區域的開頭.括號中的數值是這個區域的大小.這行定義了
ROM區域0為64K大小.
第3到14行是載入到這個ROM區域的那些ROM.每行的第一個參數是要載入的
ROM檔名.第二個參術是說明這個ROM應該被載入到記憶體區域的哪裡.第三
個參數說明這個ROM有多少BYTE長.最後一個參數是這個ROM的CHECHSUM,用
來確認ROM是否正確.舉例來說,第3行會載入0x800 BYTE長從檔案ZARZ122.07
開始於位址0x4000在記憶體區域0中.
11行有些不同於其他行.這行是ROM_RELOAD,代替ROM_LOAD.ROM_RELOAD用
來再載入這個ROM,載入到記憶體中到不同區域.所以第10行載入ZARZ129.16
到記憶體在0x7800,第11行再載入一次在記憶體位址0xf800.這樣做的主要
理由是如果ROM不在或是有錯誤的CHECKSUM,只要重複使用ROM_RELOAD,就
不會重複回報同樣的錯誤.
第16行是結束ROM區域0並且開始ROM區域1.在ZARZON中,這個記憶體區域用
來存放圖形ROM.20行結束ROM區域1並且開始用來存放產生聲音用的PROM的
ROM區域2.ZARZON還不支援聲音,所以這些ROM不使用.
23行結束這些ROM的定義.
2.4 MemoryReadAddress Structure
MemoryReadAddress結構定義了這個機器的MEMORY MAP.它告訴MAME,當處
理器想要讀取資料從一個特殊的記憶體位置,應該做些什麼.這裡是ZARZON
的MemoryReadAddress結構(記住!ZARZON是Satan of Saturn的複製品,所
以名稱是satansat_readmem):
1 static struct MemoryReadAddress satansat_readmem[] =
2 {
3 { 0x0000, 0x1fff, MRA_RAM },
4 { 0x4000, 0x97ff, MRA_ROM },
5 { 0xb004, 0xb004, input_port_0_r }, /* IN0 */
6 { 0xb005, 0xb005, input_port_1_r }, /* IN1 */
7 { 0xb006, 0xb006, input_port_2_r }, /* DSW */
8 { 0xb007, 0xb007, input_port_3_r }, /* IN2 */
9 { 0xf800, 0xffff, MRA_ROM },
10 { -1 } /* 表格結尾 */
11 };
第一行是這個結構定義的開頭.名稱,本例是satansat_readmem,指到
MachineDriver結構.
結構內的每一行開頭跟著兩個數字,記憶體區段開始及結束的位址.接下來
是一個或更多物件,定義記憶體節區是什麼及它應該如何處理.
第3行定義了一個記憶體區域,開始於0x0000及結束於0x1FFF.它被定義為
MRA_RAM,意指這個區域是RAM的位置.當一次執行在這個區段中的位址的讀
寫時,對處理器而言相當於在記憶體區域(當你載入ROM時定義的)中相對應
的位置做一次讀寫.
第4行定義了MRA_ROM,意指這個區域是ROM的區域.本質上,與MRA_RAM的行
為相同.
第5行顯示了一個稍微不同類型的記憶體區段.因為起始及終止的位址相同
,表示這個區段只有一個BYTE長,這是十分合理的.這個區域的功能代替一
個預先定義(pre-defined)的一個常式名稱的功能.當處理器讀取這個記憶
體位置時,MAME會呼叫常式"input_port_0_r",並且這個常式會傳回一個適
當的數值.本例中,"input_port_0_r"是一個功能雖然由MAME定義,不過它
也很簡單的能由你自己寫你專用的常式."input_port_0_r"會在IO 結構的
段落中更進一步的討論.
6,7,8行所有功能都和第5行一樣.
第9行定義了位址0xf800到0xffff的ROM的最後一塊.
第10行設定為"-1"表示是這個表格的結尾.
[此贴子已经被作者于2003-8-24 16:20:26编辑过]
|
MSN:tiqit2@hotmail.com
|
|
2003-8-24 00:00 |
|
|
Dark-Destroy
元老会员
积分 8312
发帖 3551
注册 2003-3-22
状态 离线
|
『第
2 楼』:
作者: zchou (Nelson Chou) 看板: Emulator
標題: 認識MAME DRIVER VOL.1(翻譯版-2)
時間: Tue Sep 8 18:27:56 1998
2.5 MemoryWriteAddress Structure
MemoryWriteAddress結構很簡單的像MemoryReadAddress結構一樣的設定,
但是就像代替從記憶體讀取的處理一樣,這個結構處理記憶體的寫入.
1 static struct MemoryWriteAddress satansat_writemem[] =
2 {
3 { 0x0000, 0x03ff, MWA_RAM },
4 { 0x0400, 0x07ff, MWA_RAM, &rockola_videoram2 },
5 { 0x0800, 0x0bff, videoram_w, &videoram, &videoram_size },
6 { 0x0c00, 0x0fff, colorram_w, &colorram },
7 { 0x1000, 0x1fff, rockola_characterram_w, &rockola_characterram },
8 { 0x4000, 0x97ff, MWA_ROM },
9 // { 0xb000, 0xb000, satansat_sound0_w },
10 // { 0xb001, 0xb001, satansat_sound1_w },
11 { 0xb002, 0xb002, satansat_b002_w }, /* flip screen & irq enable */
12 { 0xb003, 0xb003, satansat_backcolor_w },
13 { -1 } /* 表格結尾 */
14 };
第3行定義了從0x0000到0x03FF的記憶體區段.並且如同RAM一般的定義.
第4行像第3行一樣同樣定義一個像RAM一樣的區段,但是比第3行多了一個
參數.這個"&rockola_videoram2"是一個指標變數,就像這樣的宣告:
unsigned char *rockola_videoram2;
當MAME為這個機器設置記憶體時,會把記憶體區段0x400-0x7ff的位址交給
指標rockola_videoram2.這會允許這個記憶體區段更容易為DRIVER的其他
部份所存取.記住這點很重要,這一個段落仍在整個ROM載入的記憶體區段
內,rockola_videoram2只是一個指標指到這個區域的一部份而已.
第5行有點小小的複雜.像平常一樣,我們定義記憶體區段,這裡是0x800到
0xbff.接下來我們有videoram_w,當一個寫入動作到在這個段落時呼叫的
常式.videoram_w是MAME中一個預先定義的常式.接下來我們有&videoram
,像第4行一樣的指標變數.當記憶體被設置時,&videoram會指到這個記憶
體區段.最後我們有&videoram_size.當記憶體被設置時,MAME會把這個記
憶體區域的大小放到變數videoram_size內.
第6行就像第5行一樣,但是這裡我們不需要這個區段在記憶體中的大小,所
以沒有包含尺寸變數.colorram_w and &colorram也同時定義於MAME核心
中.
第7行也與第6行一樣,不同的是,特定變數用來代替標準內建的變數.
第8行定義像ROM一樣的記憶體區段.
9-12行與在MemoryReadAddress結構中的5-8行類似.當這些位址被寫入時,
這個相對應的常式會被呼叫去處理寫入動作.
第13行是我們以"-1"結束這個結構.
2.6 Input Ports
DRIVER的下一個我們要觀察的段落定義了這個機器輸入埠的運作.這個結
構用來定義這些,像搖桿輸入,錢幣投入,指撥開關(dipswitch),和其他等
.我已經拆開這個段落成為兩個較小的段落:
1 INPUT_PORTS_START( satansat_input_ports )
2 PORT_START /* IN0 */
3 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT | IPF_2WAY )
4 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT | IPF_2WAY )
5 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
6 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT | IPF_2WAY | IPF_COCKTAIL )
7 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT | IPF_2WAY | IPF_COCKTAIL )
8 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 | IPF_COCKTAIL )
9 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON2 )
10 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 | IPF_COCKTAIL )
第1行開始這個遊戲的輸入埠的定義.名稱,satansat_input_port指到
GameDriver結構.
第2行開始第一個埠的定義(輸出埠0).
3到10行定義這個埠中每個bit做些什麼.每一行的第一個參數是遮罩(mask
).每一個BIT,也就是遮罩中的那個"1",將會使這一行的功能有作用.所以
在第3行中,遮罩是0x01,這表示使這行有作用的是BIT 0.下一個參數設定
這個功能是在高電位(HIGH)時作用還是低電位時作用(LOW).最後一個參數
設定這個BIT的功能並且它還有任何特殊的屬性.第3行中,功能是
IPT_JOYSTICK_LEFT ,表示這個BIT被搖桿推向左所控制.這行中的
IP_ACTIVE_HIGH參數表示當搖桿推向左時,這個BIT將會是一個"1",所有其
餘時間都應該是一個"0".IPF_2WAY屬性表示這是一個兩方向搖桿,它只能
被推向左或向右.
第4行與第3行相同,只是這行是JOYSTICK_RIGHT.
第5行定義一個按鍵(button).BUTTON1在這個遊戲中通常是"發射(FIRE)"
鍵.
6,7,8行定義了第二組兩方向搖桿及按鍵,但是這一組有個屬性IPF_COCKTAIL
.這表示這個搖桿使用在機器的雞尾酒桌版.
9,10行定義了一個第二組的按鍵為了正常機器及雞尾酒版兩種.
這裡是輸入埠第二個段落,定義在PORT 1的BIT:
1 PORT_START /* IN1 */
2 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 )
3 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 )
4 PORT_BIT( 0x7C, IP_ACTIVE_HIGH, IPT_UNKNOWN )
5 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
第2行開始第二組埠(PORT1).
2,3行類似於第一輸入埠的幾行.第2行定義了START1,通常是1P開始按鍵,
第3行定義了START2,通常是1P開始按鍵.
如果你觀察第4行,你會注意到,有超過1bit設定在這個遮罩中.你可以使遮
罩中有許多你想要的BIT設定為1在每個空位.每一個設定為1的BIT會使該
行的功能有作用.第4行的功能是IPT_UNKNOWN,意指這些BITS的功能現在還
不知道.因為這行以IP_ACTIVE_HIGH來定義,並且任何未知的輸入永遠不能
變成ACTIVE,所以這些BITS將總是為0.
第5行類似於第4行,因為這是IP_ACTIVE_LOW,所以這個BIT將總是為高電位
(HIGH).
下一個段落有點不同,因為它定義了指撥開關(dipswitch)代替輸入端.不
過即使它是一個指撥開關,它仍然如一個輸入埠一樣的被參考,本例中是輸
入埠2:
1 PORT_START /* DSW */
2 PORT_DIPNAME( 0x01, 0x01, "Cabinet", IP_KEY_NONE )
3 PORT_DIPSETTING( 0x01, "Upright"
4 PORT_DIPSETTING( 0x00, "Cocktail" )
5 PORT_DIPNAME (0x0a, 0x00, "Coinage", IP_KEY_NONE )
6 PORT_DIPSETTING ( 0x08, "2 Coins/1 Credit" )
7 PORT_DIPSETTING ( 0x00, "1 Coin/1 Credit" )
8 PORT_DIPSETTING ( 0x02, "1 Coin/2 Credits" )
9 /* 0x0a gives 2/1 again */
10 PORT_DIPNAME (0x04, 0x00, "Bonus Life", IP_KEY_NONE )
11 PORT_DIPSETTING ( 0x00, "5000" )
12 PORT_DIPSETTING ( 0x04, "10000" )
13 PORT_DIPNAME (0x30, 0x00, "Lives", IP_KEY_NONE )
14 PORT_DIPSETTING ( 0x00, "3" )
15 PORT_DIPSETTING ( 0x10, "4" )
16 PORT_DIPSETTING ( 0x20, "5" )
17 /* 0x30 gives 3 again */
18 PORT_DIPNAME (0x40, 0x00, "Unknown", IP_KEY_NONE )
19 PORT_DIPSETTING ( 0x00, "Off" )
20 PORT_DIPSETTING ( 0x40, "On" )
21 PORT_DIPNAME (0x80, 0x00, "Unknown", IP_KEY_NONE )
22 PORT_DIPSETTING ( 0x00, "Off" )
23 PORT_DIPSETTING ( 0x80, "On" )
第1行像,平常一樣,定義這個輸入埠的開頭.
第2行定義指撥開關的第一段的開頭.第一個參數是像在正常的輸入埠一樣
的遮罩.每一個是"1"的BIT會使這個指撥開關有作用.下一個參數是指撥開
關的內定值,本例中是0x01.下一個參數是這個指撥開關的名稱,會顯示在
MAME中的指撥開關目錄中.最後一個參數允許你設定一個按鍵去控制這個
指撥開關.因為這是IP_KEY_NONE意指沒有任何按鍵能控制它,並且它必須
被設置在指撥開關目錄上.
3,4行是PORT_DIPSETTING.這些定義了不同的設定為了我們定義的指撥開
關區段.第一個參數在PORT_DIPSETTING中是對應到設定的數值,第二個參
數是設定的名稱.例如,如果指撥開關"Cabinet"設定給"Upright",然後這
個埠的BIT 0將會設成0x01.如果是設定給"Cocktail",這個埠的BIT 0將會
設成0x00.
第5行開始指撥開關下一個區段的定義,這次叫"Coinage".注意這裡,有兩
個BIT設定在遮罩裡,意指這個指撥開關有兩種以上組合.
第6-8行定義了"Coinage"指撥開關的設定.有四種可能的組合在這個DIP區
段,但是只定義了其中三種.像第9行所表示的,第四種設定,0x0A,與0x08的
設定相同.
13-23行定義了指撥開關區段及設定的剩餘部份.
這裡是輸入埠最後區段:
1 PORT_START /* IN2 */
2 PORT_BITX(0x01, IP_ACTIVE_HIGH, IPT_COIN1 | IPF_IMPULSE,
3 IP_NAME_DEFAULT, IP_KEY_DEFAULT, IP_JOY_DEFAULT, 1 )
4 PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED )
5 PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* 連接到一個計數器 - 亂數產生器? */
6 INPUT_PORTS_END
第1行是開始最後的輸入埠,PORT 3,的定義.
第2行是POST BIT定義的另外一種類型.PORT_BITX允許我們去指定這個
PORT的某些額外參數.這個BIT的功能是IPT_COIN1,第一個錢幣投入口.屬
性IPF_IMPULSE表示這是一個脈衝輸入,意指這個BIT會引發(active)多玩
一次遊戲,然後又回到自己之前的(inactive)狀態.這一行唯一額外的參數
是在最後的1,這是脈衝時間的長度.所有其他的額外參數都設定DEFUALT,
因為我們不需要他們.
第4行顯示更多不同的功能,IPT_UNUSED.這表示這些BITS在這個遊戲是不
被使用的,通常意指在硬體中它們是沒有連接的.就像UNKNOWN,這些是永不
變成ACTIVE的.因為這BITS被定義為IP_ACTIVE_LOW,這些BITS總是處於高
電位.
第6行是這個機器的輸入埠的結尾.
2.7 GfxDecodeInfo Structure
GfxDecodeInfo是用來決定這個遊戲的繪圖資料如何被解碼的兩個結構的
第一個結構.繪圖資料通常儲存在遊戲基版上的ROM中,並且這些ROM被組織
以使電路繪製顯示影像時能更簡單的方式.不幸的,資料被儲存在ROM中的
方式通常不容易使用在模擬器中.GfxDecode結構告訴MAME如何轉換原始繪
圖ROM到更有用的格式.
1 static struct GfxDecodeInfo satansat_gfxdecodeinfo[] =
2 {
3 { 0, 0x1000, &charlayout256, 0, 4 }, /* 遊戲會動態的改變這裡 */
4 { 1, 0x0000, &charlayout256, 4*4, 4 },
5 { -1 }
6 };
第1行開始了GfxDecodeInfo結構的定義.它的名稱,本例是
satansat_gfxdecodeinfo,指到MachineDriver結構.
這個機器有兩種不同的對圖形解碼的方案,第3,4行各定義這些方案之一.
這幾行的第一個參數告訴MAME,在哪個記憶體區域可以找到圖形資料.第4
行最明顯.它顯示了圖形資料可以在區域1找到,如果觀察ROM載入結構,可
以看到圖形ROM被載入在這個區域.第3行顯示資料來自區域0,處理機記憶
體區域.這樣做的理由是,ZARZON儲存一些圖形資料在RAM中.下一個參數說
明這些資料來自哪裡.第三個參數是一個指標指到GfxLayout結構,定義了
這些圖形資料是怎樣的格式.
每行中的最後兩個參數是用來決定畫這些圖形的顏色.這組的第一個數字
是到顏色的位移,查看表格到這些圖形顏色的起點.這組中的第二個參數是
這個圖形所使用的顏色總數.
2.8 GfxLayout structure
GfxLayout結構是定義圖形ROM是怎樣格式的第二部份.這個結構定義了資
料的實際格式.
1 static struct GfxLayout charlayout256 =
2 {
3 8,8, /* 8*8 圖樣 */
4 256, /* 256 圖樣 */
5 2, /* 每個像點2 bits */
6 { 0, 256*8*8 }, /* 兩個位元平面(bitplane)是分開的 */
7 { 0, 1, 2, 3, 4, 5, 6, 7 },
8 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
9 8*8 /* 每個圖樣要8個連續的BYTE */
10 };
這可能有點困擾,所以看的時候要小心一點.
第1開始這個結構.它的名稱,本例是charlayout256,指到GfxDecodeInfo結構.
第3行定義了每個圖樣的長寬是幾個像點.所以圖樣在ZARZON中是8點長8點
寬.
第4行定義圖形ROM中有幾個圖樣,本例中有256個圖樣.
第5行定義了圖樣中每個像點用了幾個BITS表示.ZARZON是每個像點2BITS.
因為2BITS有4種不同的組合(00,01,10,11),所以每個圖樣最多有4種顏色.
第6行包含每個位元平面中資料起點的位移以BIT表示.因為ZARZON是每個
像點使用2BITS(定義在第五行),所以它也有兩個位元平面.在ZARZON硬體
中,造成每個像點的2BITS中的每一個位元都被儲存在分別的ROM CHIP中.
我們所載入的第一個圖形ROM包含第一位元平面,所以第一位元平面位移為
0.我們所載入的第二個圖形ROM包含第二位元平面,所以為了得到它,我們
必須保留在第一位元平面的所有資料.到第二位元平面的位移是256*8*8,
這個數字從何得來?256是每個ROM中有256個圖樣,第一個"*8"是因為每個
圖樣有8條線高,所以每個圖樣有8BYTE.256*8=2048是圖形ROM的長度以
BYTE表示,位元平面的位移是以BIT作單位,因為每個圖樣的每條線是8BITS
,所以我們要乘以8,2048 X 8得到總位移是256*8*8 = 16384.
7,8行說明了圖樣中在每個座標的每個像點的資料在哪裡得到.ZARZON中的
圖樣是8X8像點.第7行給的是直切過圖樣的像點的位移.第8行給的是圖樣
由上而下每行的位移.聽起來有點混亂,不過當看到例子時就會很清楚.
第9行給的是兩個連續圖樣之間的距離以位元表示.在ZARZON中,每個圖樣
需要8BYTE,並且每個BYTE有8個BIT,所有總數是8*8=64.
OK!現在我們來看這些加在一起如何運作.當MAME對這些圖形ROM解碼時,它
是一個圖樣接著一個的步驟.所以譬如它想對編號10的圖樣解碼.ZARZON使
用兩個位元平面(第五行),所以MAME首先必須找到每個位元平面資料的起
點.從GfxDecodeInfo結構中,我們知道這些圖型ROM在記憶體區域1開始在
位移0的位置.從第六行得知,位元平面1開始在位移0及位元平面2開始在位
移16384.從第9行得知,每個圖樣需要64BITS,所以我們可以計算每個圖樣
的每個位元平面的資料開始在哪裡:
位元平面1,第10個圖樣 * 每個圖樣64BITS + 平面位移0 = 640
位元平面2,第10個圖樣 * 每個圖樣64BITS + 平面位移16384 = 17024
現在我們知道資料中每個位元平面的開始在哪裡,我們能開始對這個圖樣
解碼.我們從圖樣的左上角的像點開始.這就是第一行的第一個像點.為了
從資料中找出這個位元的位移,觀察第8行的第一個數值,0*8,這是圖樣上
第一行資料的位移.接下來觀察第七行的第一個數值,0,這是每一行中第
一個像點資料的位移.所以這個像點資料的位移將是 (0*8) + 0.第一行的
第二個像點,我們還是用0*8,因為還是在第一行,但是如果現在我們使用第
7行中的第二個像點,第七行是1.這行第二個像點的位移就會是(0*8)+1.我
們以這種方式繼續處理第一行八個像點中的每一個.為了得到圖樣的第二
行中的第一個像點,我們從第八行中的第二個數值開始,1*8.第二行的第一
個像點將是(1*8)+0 = 8,第二點將是(1*8)+1 = 9, etc.
3.0 Linking In The Driver.
我在本篇寫的最後一件事是如何連結你的DRIVER到MAME原始碼中.第一件
事是你必須把所有你的原始碼檔案的檔名放到MAKEFILE檔案中.因為ZARZON
是在rockola driver原始檔中,在MAKEFILE中它將看起來長成這樣:
obj/vidhrdw/rockola.o obj/sndhrdw/rockola.o obj/drivers/rockola.o \
這將編譯rockola driver並連結它到MAME中,但是MAME仍然不知道有這個
遊戲存在,這需要更多步驟.在檔案driver.c中,有個指標陣列指到MAME中
每個GameDriver結構.ZARZON那行看起來像這樣:
&zarzon_driver, /* (c) 1981 Taito, gameplay says SNK */
你也需要在driver.c中宣告這個,以使編譯器可以找到它:
extern struct GameDriver zarzon_driver;
這就是連結DRIVER到程式碼中的全部步驟.
|
MSN:tiqit2@hotmail.com
|
|
2003-8-24 00:00 |
|
|