Pada tahun 80-an, sebuah perusahaan tak dikenal bernama Binary Systems menerbitkan game Starflight. Permainan ini menempatkan pemain dalam peran kapten kapal luar angkasa yang dikirim untuk menjelajahi galaksi. Tidak ada jalur yang ditentukan, memungkinkan pemain untuk beralih secara bebas antara penambangan, pertempuran antar kapal, dan diplomasi alien. Plot permainan yang lebih luas muncul perlahan-lahan, ketika pemain menemukan bahwa ras makhluk purba menyebabkan bintang-bintang berkobar dan menghancurkan semua makhluk hidup. Permainan ini telah dipuji secara luas oleh para kritikus kontemporer dan modern, dan merupakan salah satu contoh paling awal dari permainan sandbox. Game ini memengaruhi desain banyak game lain selama beberapa dekade setelah dirilis.
Untuk mengetahui lebih lanjut tentang game ini, periksa tautan berikut:
Anda dapat membeli gamenya di GoG
Pertama kali saya mendengar tentang game ini saya ingin memainkannya. Namun, saya masih terlalu muda dan tidak bisa berbahasa Inggris. 20 kemudian saya mencoba lagi dan itu adalah pengalaman yang sangat menyenangkan. Eksplorasinya menyenangkan, jalan ceritanya epik dan diakhiri dengan kejutan, itulah salah satu pengalaman terbaik yang pernah saya alami. Tentu saja, game ini belum berkembang dengan baik, tetapi Anda bisa merasakan pengabdian para pengembang terhadap game tersebut. Ada aspek seni dalam game ini serta perhatian pengrajin terhadap detail.
Meskipun memainkan game yang benar-benar luar biasa ini menyenangkan, begitu pula rekayasa balik game ini. Anda mengikuti jejak para pengembang dan mengalami proses berpikir mereka seolah-olah ini adalah tahun 1985 lagi. Untuk game ini mengharapkan hal yang tidak terduga. Biasanya ketika Anda merekayasa balik permainan lama seperti itu, Anda harus menerima sepuluh ribu baris kode assembler murni, yang dapat Anda analisis dengan alat biasa seperti IDA Pro. Tapi tidak kali ini. Sebenarnya untuk game ini kamu bisa membuang alat-alat yang biasa. Mereka tidak berguna. Anda sendirian. Alasannya adalah Starflight ditulis dalam bahasa Forth, bahasa yang hampir tidak saya ketahui.
Keempat adalah bahasa dengan minimalisme tertinggi dalam hal sintaksis. Tidak ada sintaksis yang lebih dari spasi antar "kata". Anda pada dasarnya dapat menulis pembaca dan juru bahasa Forth dalam beberapa baris kode.
Dalam bahasa modern Anda menulis sesuatu seperti
print ( 2 + 3 )
untuk mencetak hasil 2+3. Namun di Forth terlihat seperti ini.
2 3 + .
Forth adalah mesin tumpukan, dengan notasi Polandia terbalik. Penafsirannya adalah sebagai berikut
Sintaksnya sederhana dan penerjemahnya sederhana. "2", "3", "+" dan "." hanya disebut "kata-kata". Tidak ada perbedaan sintaksis antara data dan kode. Tentu saja bahasa yang memenuhi keterbatasan komputer rumahan awal.
Saat Anda membedah STARFLT.COM yang dapat dieksekusi, ia mengungkapkan beberapa internal yang fantastis
Seperti yang dijelaskan di atas, Forth adalah mesin tumpukan. Sebagai mekanik pengkodean, ia menggunakan threading tidak langsung, metode yang sangat hemat ruang untuk menyimpan kode kompilasi Anda. Kode berulir memiliki bentuk yang pada dasarnya seluruhnya terdiri dari panggilan ke subrutin. Threading tidak langsung menggunakan penunjuk ke lokasi yang pada gilirannya menunjuk ke kode mesin.
Katakanlah penunjuk instruksi Anda menunjuk ke alamat 0x1000 dan berisi nilai 16-Bit Read16(0x1000)=0x0f72.
0x1000 : dw 0x0f72
Nilai 0x0f72 adalah kode yang setara dengan kata keempat '+'. Ingat uraian di atas. Kata '+' memunculkan dua entri tumpukan terakhir, menambahkannya bersama-sama dan mendorong hasilnya kembali ke atas tumpukan. Menurut threading tidak langsung, nilai 16-Bit 0x0f72 ini adalah penunjuk ke lokasi yang pada gilirannya menunjuk ke kode mesin. Saat Anda membaca konten memori Read16(0x0f72) Anda mendapatkan penunjuk ke 0x0f74. Dan memang, ketika Anda melihat lokasi memori ini dan membongkarnya, Anda mendapatkan yang berikut ini
0x0f72 : dw 0x0f74
0x0f74 : pop ax
0x0f75 : pop bx
0x0f76 : add ax , bx
0x0f78 : push ax
0x0f79 : lodsw
0x0f7a : mov bx , ax
0x0f7c : jmp word ptr [ bx ]
Empat instruksi pertama melakukan operasi persis seperti yang seharusnya dilakukan oleh kata "+". Tiga instruksi assembler terakhir yang dimulai dari "lodsw" meningkatkan penunjuk instruksi dan melompat ke kode berikutnya.
Mari kita lanjutkan. Sekarang penunjuk instruksi menunjuk ke 0x1002
0x1002 : dw 0x53a3
Membaca alamat 0x53a3 mengungkapkan
0x53a3 : dw 0x1d29
0x53a5 : dw 0x0001
dan kode yang sesuai
0x1d29 : inc bx
0x1d2a : inc bx
0x1d2b : push bx
0x1d2c : lodsw
0x1d2d : mov bx , ax
0x1d2f : jmp word ptr [ bx ]
Saat ini register bx berisi alamat kata 0x53a3. Jadi kode ini hanya mendorong alamat 0x53a5 di atas tumpukan. Apa yang telah kita lakukan adalah memberikan program sebuah pointer ke suatu variabel. Variabel tersebut memiliki konten 0x0001. Kata keempat '@' akan mengeluarkan alamat dari tumpukan, membaca isinya dan mendorongnya kembali ke tumpukan.
Sejauh ini saya dapat mengidentifikasi 6256 kata yang mengandung kode atau data.
Dan hanya itu saja yang perlu Anda ketahui tentang struktur kode. Seperti yang Anda lihat, ini bisa menjadi pengkodean yang hemat ruang, tetapi dari segi kecepatan, ini adalah bencana. Setiap beberapa instruksi kode mesin Anda harus melompat ke blok kode yang berbeda.
Persamaan dari threading tidak langsung di C akan terlihat seperti ini.
uint16_t instruction_pointer = start_of_program_pointer ;
void Call ( uint16_t word_adress )
{
// the first two byte of the word's address contain
// the address of the corresponding code, which must be executed for this word
uint16_t code_address = Read16 ( word_address );
switch ( code_address )
{
.
.
.
case 0x0f74 : // word '+'
Push16 ( Pop16 () + Pop16 ());
break ;
.
.
.
}
}
void Run ()
{
while ( 1 )
{
uint16_t word_address = Read16 ( instruction_pointer );
instruction_pointer += 2 ;
Call ( word_address );
}
}
Kode yang dieksekusi untuk kata tertentu memiliki akses ke 5 variabel utama (16-Bit)
Pembongkaran mengubah kode FORTH menjadi kode gaya C.. Sebagian besar kode transpilasi dikompilasi. Untuk memahami apa yang dilakukan program lihat tabel berikut. Dibutuhkan "bytecode" (yang sebagian besar merupakan pointer 16-Bit) sebagai input dan mengubahnya menjadi C.
Kode keempat:
: .C ( -- )
Display context stack contents.
CR CDEPTH IF CXSP @ 3 + END-CX
DO I 1.5@ .DRJ -3 +LOOP
ELSE ." MT STK"
THEN CR ;
EXIT
Transformasi:
Pointer 16-Bit | KE DEPAN | C |
---|---|---|
: .C ( -- ) | void DrawC() { | |
unsigned short int i, imax; | ||
0x0642 | Kr | Exec("CR"); |
0x75d5 | CDEPTH | CDEPTH(); |
0x15fa 0x0020 | JIKA | if (Pop() != 0) { |
0x54ae | CXSP | Push(Read16(pp_CXSP) + 3); |
0xbae | @ | |
0x3b73 | 3 | |
0x0f72 | + | |
0x4ffd | AKHIR-CX | Push(Read16(cc_END_dash_CX)); |
0x15b8 | MELAKUKAN | i = Pop(); |
imax = Pop(); | ||
do { | ||
0x50e0 | SAYA | Push(i); |
0x4995 | 1,5@ | _1_dot_5_at_(); |
0x81d5 | .DRJ | DrawDRJ(); |
0x175d 0xfffd | -3 | Push(-3); |
0x155c 0xffff | +LOOP | int step = Pop(); |
i += step; | ||
if (((step>=0) && (i>=imax)) || ((step<0) && (i<=imax))) break; | ||
} while(1); | ||
0x1660 0x000b | KALAU TIDAK | } else { |
0x1bdc | “MTSTK” | PRINT("MT STK", 6); |
0x06 | ||
0x4d | 'M' | |
0x54 | 'T' | |
0x20 | ' ' | |
0x53 | 'S' | |
0x54 | 'T' | |
0x4b | 'K' | |
KEMUDIAN | } | |
0x0642 | Kr | Exec("CR"); |
0x1690 | KELUAR | } |
Permainan ini hadir dalam 3 File
Konten STARA.com
pintu masuk | ukuran | keterangan |
---|---|---|
DIREKTORI | 4096 | berisi direktori STARA dan STARB |
ELO-CPIC | 4816 | |
GAZ-CPIC | 3120 | |
MEC-CPIC | 2848 | |
MYS-CPIC | 6064 | |
NOM-CPIC | 1136 | |
SPE-CPIC | 1888 | |
THR-CPIC | 2480 | |
VEL-CPIC | 4672 | |
VPR-CPIC | 1248 | |
MIN-CPIC | 2096 | |
MEMERCIKKAN | 16384 | Gambar |
MED-PIC | 2048 | Gambar |
FASE | 6144 | |
HUM-PIC | 480 | Gambar |
VEL-PIC | 432 | Gambar |
THR-PIC | 272 | Gambar |
ELO-PIC | 608 | Gambar |
DAN-PIC | 640 | Gambar |
MENYIMPAN | 124000 | |
MUSIK | 4960 | Hamparan Kode |
BUMI | 1152 | Peta planet bumi |
GALAKSI | 6304 | |
KREDIT | 16384 | gambar |
COP-CPIC | 2928 | |
FONT | 768 | |
CGA | 3600 | Rutinitas Kode Mesin untuk kartu grafis CGA |
EG | 3600 | Rutinitas Kode Mesin untuk kartu grafis EGA |
Konten STARB.COM
pintu masuk | ukuran | keterangan |
---|---|---|
DIREKTORI | 4096 | berisi direktori STARA dan STARB |
CONTOH | 150528 | Struktur pohon dengan sebagian besar konten permainan |
KOTAK | 1024 | Meja |
BANK-TRANS | 144 | Meja |
CREWMEMBER | 128 | Meja |
KAPAL | 1936 | Meja |
ELEMEN | 544 | Meja |
ARTIFAK | 1584 | Meja |
PLANET | 1360 | Meja |
CONTOH | 448 | Meja |
BIO-DATA | 448 | Meja |
TPORT-PIC | 2416 | Gambar |
BPORT-PIC | 3984 | Gambar |
ANALISIS-TEKS | 3200 | Meja |
TOMBOL | 944 | Meja |
IKON1:1 | 912 | |
IKON1:2 | 912 | |
IKON1:4 | 912 | |
NAMA IKON | 736 | |
DPART-OV | 1552 | Hamparan Kode |
DAERAH | 176 | Meja |
MAKHLUK | 17024 | Meja |
CHKFLIGHT-OV | 960 | Hamparan Kode |
FRAK-OV | 4640 | Hamparan Kode |
IKONP-OV | 832 | Hamparan Kode |
SITUS-OV | 1888 | Hamparan Kode |
HIPERMSG-OV | 4112 | Hamparan Kode |
GPOLY | 368 | |
SEGI | 288 | |
PUNCAK | 416 | |
BLT-OV | 864 | Hamparan Kode |
LAIN-LAIN-OV | 1440 | Hamparan Kode |
BANK-OV | 1520 | Hamparan Kode |
ASSCREW-OV | 2800 | Hamparan Kode |
PERSONIL-OV | 4192 | Hamparan Kode |
KAPAL GRPH-OV | 2112 | Hamparan Kode |
KONFIG-OV | 3072 | Hamparan Kode |
TDEPOT-OV | 4800 | Hamparan Kode |
PORTMENU-OV | 3120 | Hamparan Kode |
VITA-OV | 3552 | Hamparan Kode |
HP-OV | 4832 | Hamparan Kode |
LP-OV | 5280 | Hamparan Kode |
DIKIRIM-OV | 4784 | Hamparan Kode |
TV-OV | 3472 | Hamparan Kode |
KOM-OV | 7232 | Hamparan Kode |
COMMSPEC-OV | 2864 | Hamparan Kode |
BENIH-OV | 2400 | Hamparan Kode |
DAFTAR | 720 | Hamparan Kode |
PINDAHKAN-OV | 3808 | Hamparan Kode |
INSINYUR | 2320 | Hamparan Kode |
DOKTER | 1280 | Hamparan Kode |
ORBIT-OV | 6640 | Hamparan Kode |
KAPTEN | 5952 | Hamparan Kode |
SAINS | 3952 | Hamparan Kode |
NAVIGATR | 880 | Hamparan Kode |
TOMBOL PENGIRIMAN | 1984 | |
PETA-OV | 4160 | Hamparan Kode |
HIPER-OV | 7168 | Hamparan Kode |
ANALISIS-OV | 2560 | Hamparan Kode |
PELUNCURAN-OV | 1360 | Hamparan Kode |
EFEK FLUX | 464 | |
OP-OV | 4400 | Hamparan Kode |
ITEM-OV | 6016 | Hamparan Kode |
LSYSICON | 752 | |
MSYSICON | 448 | |
SSYSICON | 176 | |
PERILAKU-OV | 5360 | |
CMAP | 1008 | |
MEMASANG | 800 | |
SEMBUH-OV | 1232 | Hamparan Kode |
PERBAIKAN-OV | 1696 | Hamparan Kode |
PERMAINAN-OV | 5920 | Hamparan Kode |
PLSET-OV | 2400 | Hamparan Kode |
PETA-OV | 2240 | Hamparan Kode |
VES-BLT | 4528 | |
BADAI-OV | 1232 | Hamparan Kode |
SENYAWA | 176 | Meja |
ITU-OV | 1936 | Hamparan Kode |
COMBAT-OV | 6192 | Hamparan Kode |
KERUSAKAN-OV | 2752 | Hamparan Kode |
TANAH-OV | 1088 | Hamparan Kode |
PSTAT | 64 | Meja |
STP-OV | 1440 | Hamparan Kode |
Masukkan file game Starflight asli ke dalam folder starflt1-in
dan starflt2-in
dan jalankan make
. Anda harus mendapatkan dua executable ( disasOV1
dan disasOV2
), yang menghasilkan konten di folder starflt1-out
dan starflt2-out
. Output yang dihasilkan adalah bagian dari repositori ini.