Musim panas lalu saya diundang ke sebuah pesta di Sunnyvale. Ternyata pemilik di garasi memiliki mesin arcade NBA JAM Tournament Edition untuk empat pemain. Terlepas dari kenyataan bahwa permainan sudah lebih dari 25 tahun (dirilis pada tahun 1993), masih sangat menarik untuk dimainkan, terutama untuk penggemar yang antusias.
Saya terkejut dengan daftar pemain Chicago Bulls yang tidak termasuk Michael Jordan. Menurut sumber
[1] , MJ menerima lisensi sendiri dan bukan bagian dari kesepakatan yang dibuat Midway dengan NBA.
Setelah bertanya kepada pemilik mesin, saya mengetahui bahwa peretas merilis mod untuk SNES "NBA Jam 2K17", yang memungkinkan pemain baru dan MJ untuk bermain, tetapi tidak ada yang menganalisis bagaimana versi arcade bekerja. Karena itu, saya pasti harus mencari ke dalam.
Latar belakang
Kisah NBA Jam dimulai bukan dengan bola basket, tetapi dengan Jean-Claude Van Damme. Sekitar waktu yang sama ketika Universal Soldier dirilis, Midway Games mengembangkan teknologi untuk memanipulasi sprite fotorealistik yang besar dan dijital yang memiliki kemiripan dengan aktor nyata. Itu adalah terobosan teknologi besar: animasi dengan 60 frame per detik, sprite yang sebelumnya tak terlihat berukuran 100x100 piksel, masing-masing memiliki palet 256-warna sendiri.
Perusahaan menggunakan teknologi ini dengan sukses besar dalam penembak populer "Terminator 2: Judgment Day"
[2] , tetapi tidak dapat memperoleh lisensi untuk "Universal Soldier" (kondisi keuangan JCVD tidak dapat diterima untuk Midway
[3] ). Ketika negosiasi berakhir dengan kegagalan, Midway mengubah arah dan mulai mengembangkan game pertempuran mega-hit Capcom 1991 yang disebut Street Fighter II: The World Warrior.
Sebuah tim beranggotakan empat orang berkumpul (Ed Boone menulis kode, John Tobias melakukan seni dan skrip, John Vogel menggambar grafik, dan Dan Forden adalah seorang insinyur suara). Setelah satu tahun kerja keras
[4] Midway meluncurkan Mortal Kombat pada tahun 1992.
Gaya visualnya sangat berbeda dari pixel art biasa, dan desain gimnya, paling tidak, "kontroversial." Permainan dengan liter darah di layar dan sangat kejam mendorong- "kematian" langsung menjadi hit dunia dan menghasilkan hampir 1 miliar dolar dalam setahun
[5] .
SF2: 384 × 224 dengan 4.096 warna.MK: 400 × 254 dengan 32.768 warna.Fakta menarik: seperti dalam Mode VGA 0x13 pada PC, dalam game ini pikselnya tidak persegi. Meskipun penyangga bingkai Mortal Kombat memiliki ukuran 400 × 254, itu diperbesar hingga rasio 4: 3 dari layar CRT, memberikan resolusi 400 × 300
[6]Peralatan T-Unit Midway
Perangkat keras yang dikembangkan oleh Midway untuk Mortal Kombat ternyata sangat bagus. Begitu baik sehingga ia diberi nama sendiri T-Unit dan digunakan kembali di game lain.
- Mortal Kombat.
- Mortal Kombat II.
- NBA Jam.
- Edisi Turnamen NBA Jam.
- Hakim Dredd (belum dirilis).
T-Unit terdiri dari dua papan. Kebanyakan dari mereka berurusan dengan logika dan grafis gim.
Papan prosesor NBA JAM TE Edition (sekitar 40x40 cm, atau 15 inci).Papan lainnya tidak terlalu rumit, tetapi juga mampu melakukan banyak hal. Ini dirancang untuk audio, tetapi dapat memainkan tidak hanya musik menggunakan sintesis FM, tetapi juga suara digital.
Kartu suara terhubung ke sumber daya dan kartu grafis dipasang di bagian belakang. Perhatikan radiator besar yang terletak di sudut kiri atas.
Bersama-sama, dua papan ini berisi lebih dari dua ratus chip, resistor, dan EPROM. Untuk memahami semua ini hanya berdasarkan nomor seri akan sangat memakan waktu. Tapi, yang mengejutkan, kadang-kadang di perangkat dari dokumentasi tahun 90an tidak sengaja ditemukan. Dan dalam kasus NBA Jam, dia luar biasa.
Arsitektur Unit-T Midway
Mencari data, saya menemukan Kit Jam NBA. Tingkat detail dokumen ini luar biasa
[7] . Di antara hal-hal lain, saya berhasil menemukan deskripsi terperinci tentang koneksi kabel, termasuk EPROM dan chip.
Informasi dari dokumen memungkinkan kami untuk menggambar diagram papan dan menentukan fungsi setiap bagian. Untuk membantu dalam pencarian komponen, papan memiliki koordinat dengan awal di sudut kanan bawah (UA0), meningkat ke sudut kiri atas (UJ26).
Jantung dari papan utama adalah Texas Instrument TMS34010 (UB21) dengan frekuensi 50 MHz dan dengan kode 1 mebibyte dalam EPROMs dan DRAM 512 kibibytes
[8] . 34010 adalah chip 32-bit dengan bus 16-bit, yang memiliki instruksi grafis luar biasa seperti PIXT dan PIXBLT
[9] . Pada awal 90-an, chip ini digunakan dalam beberapa kartu akselerasi perangkat keras
[10] , dan saya pikir ia menangani sejumlah besar efek grafis. Anehnya, dia hanya berurusan dengan logika game dan tidak menarik apa pun.
Bahkan, chip UE13 yang disebut "DMA2" ternyata menjadi monster grafis. Menurut diagram dari dokumentasi, ia memiliki bus data 32-bit dan bus alamat 32-bit yang mengesankan (oleh karena itu menjadi chip terbesar di papan tulis). Sirkuit terintegrasi khusus (ASIC) ini mampu melakukan banyak operasi grafis, yang akan saya bahas di bawah ini.
Semua chip (RAM Sistem, GFX EPROM, Palette SDRAM, Code, Video Banks) dipetakan ke satu ruang alamat 32-bit dan terhubung ke bus yang sama. Saya tidak dapat menemukan informasi tentang protokol bus, jadi jika Anda tahu sesuatu tentang itu, tulis email.
Perhatikan triknya: satu komponen EPROM (ditandai dengan warna biru) digunakan untuk membuat sistem penyimpanan lain (dan menghemat uang). EPROMs 512 kb ini memiliki pin alamat 32-bit dan pin data 8-bit. Untuk 34010, yang membutuhkan bus data 16-bit, dua EPROM (J12 dan G12) terhubung dengan dua alternatif alamat, sehingga menghasilkan memori 1 mebibyte. Demikian pula, sumber daya grafis dihubungkan dengan bergantian empat kali lipat alamat untuk membentuk alamat 32-bit dengan sistem penyimpanan 32-bit yang berisi 8 mebibytes.
Meskipun dalam artikel ini saya terutama akan mempertimbangkan pipa grafis, saya tidak bisa menahan godaan, dan karena itu saya akan berbicara singkat tentang sistem audio.
Diagram kartu suara menunjukkan Motorola 6809 (U4 dengan frekuensi 2 MHz), yang menerima instruksi dari satu EPROM (U3) untuk mengontrol musik dan efek suara.
Chip sintesis FM Yamaha 2151 (3,5 MHz) menghasilkan musik langsung dari instruksi yang diterima dari 6809 (musik menggunakan bandwidth yang cukup kecil).
OKI6295 (1 MHz) bertanggung jawab untuk memutar audio digital dalam format ADPCM (misalnya, “Boomshakalaka” yang legendaris
[11] Tim Kittsrow).
Perhatikan bahwa pada papan utama, EPROM 32a / 8d biru 512-kbyte yang sama digunakan dalam sistem 16-bit dengan penyisipan ganda alamat untuk menyimpan suara digital, tetapi untuk instruksi 8-bit data / alamat Motorola 6809 tidak disisipkan.
Kehidupan bingkai
Seluruh layar Jam NBA diindeks dalam palet 16-bit. Warna disimpan dalam format xRGB 1555 dalam palet 64-kbyte. Palet dibagi menjadi 128 blok (256 * 16 bit) dari 512 byte. Sprite yang disimpan di EPROM ditandai sebagai "GFX". Setiap sprite memiliki palet sendiri hingga warna 256x16-bit. Sprite sering menggunakan seluruh blok palet, tetapi tidak pernah lebih dari satu. Sinyal CRT ditransmisikan ke monitor menggunakan RAMDAC, yang untuk setiap piksel membaca indeks dari bank DRAM Video dan melakukan pencarian warna dalam palet.
Kehidupan setiap frame video NBA Jam berjalan sebagai berikut:
- Logika permainan terdiri dari aliran instruksi 16-bit yang dikirimkan dari J12 / G12 ke 34010.
- 34010 membaca input pemain, menghitung status game, dan kemudian menggambar layar.
- Untuk menggambar di layar, 34010 pertama-tama menemukan blok yang tidak digunakan dalam palet dan menulis palet sprite di sana (palet sprite disimpan bersama dengan instruksi 34010 di J12 / G12).
- 34010 membuat permintaan ke DMA2, yang meliputi alamat dan ukuran sprite, blok palet 8-bit yang digunakan, pemotongan, penskalaan, metode pemrosesan piksel transparan, dan sebagainya.
- DMA2 membaca indeks sprite 8-bit dari chip ROM J14-G23 GFX, menggabungkan nilai ini dengan indeks blok palet 8-bit dan menulis indeks 16-bit ke bank video. DRAM2 dapat dianggap sebagai blitter yang membaca nilai 8-bit dari GFX EPROM dan menulis nilai 16-bit ke bank video
- Langkah 3-5 diulang sampai semua permintaan untuk menggambar sprite selesai.
- Ketika datang ke refresh layar, RAMDAC mengubah data di bank video menjadi sinyal bahwa monitor CRT dapat mengerti. Agar bandwidth cukup untuk mengubah indeks 16-bit menjadi 16-bit RGB, palet disimpan dalam SRAM yang sangat mahal dan sangat cepat.

Fakta yang menarik: EPROM flash firmware bukanlah proses yang sederhana. Sebelum menulis ke chip, Anda harus menghapus semua isinya.
Untuk melakukan ini, chip harus disinari dengan sinar UV. Pertama, Anda harus membatalkan pemasangan stiker dari bagian atas EPROM untuk membuka diagramnya. Kemudian EPROM ditempatkan di perangkat penghapus khusus di mana ada lampu UV.
Setelah 20 menit, EPROM akan diisi dengan nol dan siap untuk direkam.
Dokumentasi MAME
Setelah mengetahui peralatannya, saya menyadari set EPROM apa yang dapat Anda tulis ke Michael Jordan (palet disimpan dalam Kode EPROMs, dan indeks dalam GFX EPROMs). Namun, saya masih tidak tahu lokasi atau format yang digunakan.
Dokumentasi yang hilang ditemukan di MAME.
Jika Anda tidak tahu cara kerja emulator yang luar biasa ini, saya akan jelaskan secara singkat. MAME didasarkan pada konsep "driver", yang merupakan tiruan dari papan. Setiap driver terdiri dari komponen yang meniru (biasanya) setiap chip. Dalam hal Midway T-Unit, kami tertarik pada file-file berikut:
mame / include / midtunit.h
mame / src / mame / video / midtunit.cpp
mame / src / mame / drivers / midtunit.cpp
mame / src / mame / machine / midtunit.cpp
cpu / tms34010 / tms34010.h
Jika Anda melihat driver / midtunit.cpp, kita akan melihat bahwa setiap chip memori adalah bagian dari ruang alamat 32-bit tunggal. Dapat dilihat dari kode sumber driver bahwa palet dimulai pada 0x01800000, gfxrom dimulai pada 0x02000000, dan chip DMA2 dimulai pada 0x01a80000. Untuk mengikuti jalur data, kita harus mengikuti fungsi C ++ yang dijalankan ketika objek operasi baca atau tulis adalah alamat memori.
void midtunit_state::main_map(address_map &map) { map.unmap_value_high(); map(0x00000000, 0x003fffff).rw(m_video, FUNC(midtunit_vram_r), FUNC(midtunit_vram_w)); map(0x01000000, 0x013fffff).ram(); map(0x01400000, 0x0141ffff).rw(FUNC(midtunit_cmos_r), FUNC(midtunit_cmos_w)).share("nvram"); map(0x01480000, 0x014fffff).w(FUNC(midtunit_cmos_enable_w)); map(0x01600000, 0x0160000f).portr("IN0"); map(0x01600010, 0x0160001f).portr("IN1"); map(0x01600020, 0x0160002f).portr("IN2"); map(0x01600030, 0x0160003f).portr("DSW"); map(0x01800000, 0x0187ffff).ram().w(m_palette, FUNC(write16)).share("palette"); map(0x01a80000, 0x01a800ff).rw(m_video, FUNC(midtunit_dma_r), FUNC(midtunit_dma_w)); map(0x01b00000, 0x01b0001f).w(m_video, FUNC(midtunit_control_w)); map(0x01d00000, 0x01d0001f).r(FUNC(midtunit_sound_state_r)); map(0x01d01020, 0x01d0103f).rw(FUNC(midtunit_sound_r), FUNC(midtunit_sound_w)); map(0x01d81060, 0x01d8107f).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); map(0x01f00000, 0x01f0001f).w(m_video, FUNC(midtunit_control_w)); map(0x02000000, 0x07ffffff).r(m_video, FUNC(midtunit_gfxrom_r)).share("gfxrom"); map(0x1f800000, 0x1fffffff).rom().region("maincpu", 0); map(0xff800000, 0xffffffff).rom().region("maincpu", 0); }
Pada akhir file yang sama "drivers / midtunit.cpp" kita melihat bagaimana isi EPROM dimuat ke dalam RAM. Dalam kasus sumber daya grafis "gfxrom" (terkait dengan alamat 0x02000000), kita dapat melihat bahwa mereka membentang 8 mebibytes ruang alamat dalam blok chip dengan empat kali lipat alamat bergantian. Perhatikan bahwa nama file sesuai dengan lokasi chip (misalnya, UJ12 / UG12). Set file EPROM ini di dunia emulator lebih dikenal sebagai "ROM."
ROM_START( nbajamte ) ROM_REGION( 0x50000, "adpcm:cpu", 0 ) ROM_LOAD( "l1_nba_jam_tournament_u3_sound_rom.u3", 0x010000, 0x20000, NO_DUMP) ROM_RELOAD( 0x030000, 0x20000 ) ROM_REGION( 0x100000, "adpcm:oki", 0 ) ROM_LOAD( "l1_nba_jam_tournament_u12_sound_rom.u12", 0x000000, 0x80000, NO_DUMP) ROM_LOAD( "l1_nba_jam_tournament_u13_sound_rom.u13", 0x080000, 0x80000, NO_DUMP) ROM_REGION16_LE( 0x100000, "maincpu", 0 ) ROM_LOAD16_BYTE( "l4_nba_jam_tournament_game_rom_uj12.uj12", 0x00000, 0x80000, NO_DUMP) ROM_LOAD16_BYTE( "l4_nba_jam_tournament_game_rom_ug12.ug12", 0x00001, 0x80000, NO_DUMP) ROM_REGION( 0xc00000, "gfxrom", 0 ) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_ug14.ug14", 0x000000, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_uj14.uj14", 0x000001, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_ug19.ug19", 0x000002, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_uj19.uj19", 0x000003, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_ug16.ug16", 0x200000, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_uj16.uj16", 0x200001, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_ug20.ug20", 0x200002, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_uj20.uj20", 0x200003, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_ug17.ug17", 0x400000, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_uj17.uj17", 0x400001, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_ug22.ug22", 0x400002, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_uj22.uj22", 0x400003, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_ug18.ug18", 0x600000, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_uj18.uj18", 0x600001, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_ug23.ug23", 0x600002, 0x80000, NO_DUMP) ROM_LOAD32_BYTE( "l1_nba_jam_tournament_game_rom_uj23.uj23", 0x600003, 0x80000, NO_DUMP) ROM_END
Fakta yang menarik: pada contoh kode di atas, parameter fungsi yang terakhir diganti dengan “NO_DUMP” sehingga EPROMs yang dimodifikasi dapat dimuat. Bidang-bidang ini biasanya
[12] hash CRC / SHA1 dari isi EPROM. Beginilah cara MAME menentukan game mana yang termasuk ROM dan membuat Anda tahu bahwa salah satu ROM di set hilang atau rusak.
Mesin video jantung: DMA2
Kunci untuk memahami format grafik adalah fungsi yang memproses tulis / baca DMA di 256 register DMA2 yang terletak di alamat dari 0x01a80000 hingga 0x01a800ff. Semua kerja keras rekayasa balik telah dilakukan oleh pengembang MAME. Mereka bahkan meluangkan waktu untuk mendokumentasikan format perintah dengan sangat baik.
Register DMA
------------------
Daftar | Bit | Aplikasi
---------- + - FEDCBA9876543210 - + ------------
0 | xxxxxxxx -------- | piksel dibuang di awal setiap baris
| -------- xxxxxxxx | piksel dibuang di akhir setiap baris
1 | x --------------- | aktifkan perekaman (atau hapus jika nol)
| -421 ------------ | gambar bpp (0 = 8)
| ---- 84 ---------- | ukuran lulus setelah = (1 << x)
| ------ 21 -------- | lulus ukuran hingga = (1 << x)
| -------- 8 ------- | aktifkan lewati sebelum / sesudah
| --------- 4 ------ | aktifkan pemotongan
| ---------- 2 ----- | y mirroring
| ----------- 1 ---- | x mirroring
| ------------ 8 --- | mentransfer piksel bukan nol sebagai warna
| ------------- 4-- | mentransmisikan nol piksel sebagai warna
| -------------- 2- | transmisi piksel bukan nol
| --------------- 1 | transmisi nol piksel
2 | xxxxxxxxxxxxxxxx | alamat sumber kata rendah
3 | xxxxxxxxxxxxxxxx | alamat sumber kata tinggi
4 | ------- xxxxxxxxx | x penerima
5 | ------- xxxxxxxxx | y penerima
6 | ------ xxxxxxxxxx | kolom gambar
7 | ------ xxxxxxxxxx | garis gambar
8 | xxxxxxxxxxxxxxxx | palet
9 | xxxxxxxxxxxxxxxx | warna
10 | --- xxxxxxxxxxxxx | skala x
11 | --- xxxxxxxxxxxxx | skala y
12 | ------- xxxxxxxxx | pemangkasan atas / kiri
13 | ------- xxxxxxxxx | pemangkasan bawah / kanan
14 | ---------------- | tes
15 | xxxxxxxx -------- | byte deteksi nol
| -------- 8 ------- | halaman tambahan
| --------- 4 ------ | ukuran penerima
| ---------- 2 ----- | pemilihan tepi atas / bawah atau kiri / kanan untuk register 12/13
Bahkan ada fungsi debugging yang memungkinkan Anda untuk menyimpan sprite asli dalam proses mentransfernya ke DMA2 (fungsi ini ditulis oleh peserta lama dalam proyek MAME, Ryan Holtz
[13] ). Sudah cukup bagi saya untuk hanya memainkan game sehingga semua file dengan metadata disimpan ke disk.
Ternyata sprite terdiri dari elemen sederhana dari palet 16-bit tanpa kompresi. Namun, tidak semua sprite memiliki jumlah warna yang sama. Beberapa sprite hanya menggunakan 16 warna dengan indeks warna 4-bit, sementara yang lain menggunakan 256 warna dan memerlukan indeks warna 8-bit.
Tambalan
Sekarang saya tahu lokasi dan format sprite, jadi tetap melakukan jumlah minimum reverse engineering. Saya menulis sebuah program kecil di Golang untuk menghilangkan pergantian "kode" EPROM dan "gfx". Dengan menghilangkan striping, mudah untuk mencari ASCII atau nilai yang diketahui, karena saya bekerja persis dengan apa yang tampak seperti RAM selama eksekusi program.
Setelah itu, Anda dapat dengan mudah menemukan karakteristik pemain. Ternyata mereka semua disimpan satu demi satu dalam format big-endian 16-bit unsigned (yang sangat logis, karena 34010 bekerja dengan big-endian). Saya menambahkan patcher untuk memodifikasi atribut pemain. Tidak terlalu tertarik pada bola basket, saya memasukkan SPEED = 9, 3 PTS = 9, DUNKS = 9, PASS = 9, POWER = 9, STEAL = 9, BLOCK = 9 dan CLTCH = 9.
Saya juga menulis kode untuk menambal game dengan sprite baru dengan satu-satunya batasan - sprite baru harus memiliki ukuran yang sama dengan yang tergantikan. Untuk foto MJ, saya membuat indeks PNG 256-warna (Anda bisa melihatnya di
sini ).
Akhirnya, saya menambahkan kode untuk mengkonversi format menengah ke format yang disisipkan untuk menulis ke masing-masing file EPROM.
Mulai game
Setelah menambal isi EPROM, alat diagnostik NBAJam menunjukkan bahwa isi beberapa chip ditandai sebagai "BAD". Saya mengharapkan ini karena saya hanya menambal isi EPROM, tetapi tidak repot mencari format CRC dan bahkan lokasi penyimpanannya.
EPROM GFX ditandai dengan warna merah (UG16 / UJ16, UG17 / UJ17, UG18 / UJ18, UG20 / UJ20, UG22 / UJ22 dan UG23 / UJ23), karena berisi gambar yang saya ubah. Dua EPROMs di mana instruksi (UG12 dan UJ12) disimpan juga berwarna merah, karena ada palet.
Untungnya, di sini CRC tidak digunakan untuk melindungi konten yang dimodifikasi dan hanya diperlukan untuk memverifikasi integritas chip. Game sudah dimulai. Dan hasilkan!
Hasta La Vista, Baby!
Setelah selesai dengan kesulitan teknis, saya dengan cepat kehilangan minat pada alat dan berhenti mengembangkannya. Gagasan untuk mereka yang ingin bermain-main dengan kode:
- Tambahkan ke Eastern Conference Toronto Raptors.
- Tambahkan kemampuan untuk mengubah nama pemain. Sayangnya, mereka tidak terdiri dari ASCII, tetapi gambar yang dibuat sebelumnya.
Buku tentang NBA Jam
Jika Anda penggemar NBA Jam, maka Reyan Ali menulis seluruh buku tentangnya
[14] . Anda bisa membelinya di
sini .
Kode sumber
Jika Anda ingin berkontribusi atau hanya melihat cara kerja semuanya, maka sumber lengkap diunggah ke github di
sini .
Referensi
[1] Sumber:
'NJA Jam' oleh Reyan Ali[2] Sumber:
'NJA Jam' oleh Reyan Ali[3] Sumber:
'NJA Jam' oleh Reyan Ali[4] Sumber:
Mortal Kombat 1 Behind The Scene[5] Sumber:
'NJA Jam' oleh Reyan Ali[6] Sumber:
4: 3 versus Piksel Persegi[7] Komentar: Sayangnya, era dokumentasi yang luar biasa seperti ini telah lama berlalu
[8] Sumber:
Layar pembuka Mame NBA Jam[9] Sumber:
Set Instruksi TMS34010[10] Sumber:
T34010 Panduan Pengguna[11] Sumber:
NBA Jam - Video BoomShakaLaka[12] Sumber:
MAME T-Unit driver.cpp[13] Sumber:
Commit 'midtunit.cpp: Menambahkan penampil DMA-blitter opsional'[14] Sumber:
'NBA JAM Book' oleh Reyan Ali