NES Elite - Mã nguồn được tài liệu hóa của Elite cho NES
(github.com/markmoxon)- Mã nguồn Elite cho NES của Ian Bell và David Braben, với tài liệu cho mọi dòng và giải thích cho phần lớn nội dung, được tái dựng thủ công từ disassembly của binary game gốc
- Có thể build từ source trên máy tính hiện đại để tạo ra iNES ROM image của game hoạt động hoàn chỉnh, rồi nạp lên NES thật hoặc trình giả lập
- Các biến thể được hỗ trợ là PAL variant của Imagineer và biến thể NTSC trên website cá nhân của Ian Bell, trong đó bản build mặc định là PAL variant
- Cách khám phá source là xem ở dạng dễ đọc cho con người tại elite.bbcelite.com hoặc mở source có chú thích trong IDE; nội dung trên website và trong các file source là giống hệt nhau
- Yêu cầu để build là BeebAsm, Python, và
maketrên Mac/Linux; bản build bằng Python mới chỉ được kiểm thử trên 3.x, còn Windows có kèmmake.exe- Trên Windows build bằng
make.bat, còn Mac/Linux dùngmake; đầu ra mặc định làelite-pal.NEStrong thư mục5-compiled-rom-images - Có thể tạo
elite-ntsc.NESvớivariant=ntsc
- Trên Windows build bằng
- Các tùy chọn build kiểm soát việc chọn biến thể, dùng commander thử nghiệm gần mức tối đa, bỏ qua việc khớp với binary gốc, vô hiệu hóa kiểm tra crc32, v.v.
- Ví dụ tiêu biểu là
make variant=ntsc commander=max match=no verify=no crc32.pyso sánh song song checksum và kích thước file của file được tạo ra với file chuẩn được trích từ source gốc
- Ví dụ tiêu biểu là
- Biến thể PAL và NTSC khác nhau ở số chu kỳ của NMI handler, phần tiêu đề Imagineer/Nintendo trên Start screen, thời gian chờ auto-play của combat demo, thuật toán checksum của save slot, số phiên bản nội bộ, hidden copyright message, scroll text, hằng số y-coordinate, v.v.
- NTSC variant không chạy trên thiết bị NTSC thực; đây là bản mô phỏng NTSC với NMI timing đã được thay đổi để phù hợp với NTSC mode của một số trình giả lập
- Không có file license, nên mặc định áp dụng luật bản quyền: chỉ cho phép đọc và fork, không cho phép tái tạo, phân phối hoặc tạo tác phẩm phái sinh
1 bình luận
Ý kiến trên Hacker News
Hồi xưa khi làm ở Frontier, tôi từng nghe David Braben kể một giai thoại thú vị về NES Elite. Tôi nhớ ban đầu họ dùng bộ hẹn giờ phần cứng của NES để theo dõi thời gian thực, nhằm bảo đảm vật lý diễn ra ổn định dù tốc độ khung hình khác nhau
Trong khâu kiểm tra trước khi phát hành của Nintendo, họ phán rằng một số máy NES đời đầu có bộ hẹn giờ đó không hoạt động đúng nên không được dùng. Tôi nghe nói Bell/Braben sau đó đã tự duy trì ước lượng xem mỗi hàm đã dùng bao nhiêu chu kỳ xung nhịp trong khung hình tương ứng, rồi cộng lại ở cuối khung để ước tính thời gian đã trôi qua
Nhưng nhìn mã nguồn trên GitHub thì có vẻ hoặc là tôi nhớ nhầm, hoặc là đã không hiểu đúng lời Braben. Trong
elite-source-bank-7.asmcó chú thích “cập nhật bộ hẹn giờ NMI có thể dùng thay cho bộ hẹn giờ phần cứng mà NES không hỗ trợ”, và có vẻ họ đã triển khai một đồng hồ gần thời gian thực bằng cách đếm ngắt không che đượcTrên die CPU NES đời đầu có một lỗi và phần còn sót lại của bộ hẹn giờ khoảng lập trình được đã bị vô hiệu hóa: https://www.nesdev.org/wiki/RP2A03_Programmable_Interval_Tim...
Ở các revision sau thì nó bị loại bỏ hoàn toàn, và có khả năng chỉ được bật trên những thứ như bộ kit phát triển. Nếu dựa vào một tính năng không hoạt động trên thiết bị tiêu dùng thì việc bị Nintendo test từ chối là điều hiển nhiên
Ngay cả nếu console phát hành có bộ hẹn giờ khoảng lập trình được, nó có lẽ cũng chỉ hữu ích cho các phép đo dưới mức một khung hình, như hiệu ứng raster chính xác. Để đo thời gian thực thì đếm NMI hợp lý hơn nhiều. NMI xảy ra ở đầu mỗi khung hình video, rất ổn định ở 60.0988Hz, và dù engine game chậm đi khiến tốc độ khung hình thay đổi, phần xử lý phía CPU cũng không thể ảnh hưởng đến timing của tín hiệu video
Nhân tiện, phần cứng âm thanh cũng có thể tạo ngắt hẹn giờ, và nhiều chip mở rộng có bộ đếm scanline để đồng bộ render. Trên NES không thiếu cách để đo thời gian
Khi cố xin Nintendo phê duyệt một trò chơi nào đó, tôi nghe nói nó hoặc không chạy trên một phiên bản cụ thể của NES bản Mỹ, hoặc gây quá nhiệt hệ thống. Lịch phát hành rất gấp nên họ phải bay tới tận trụ sở Nintendo để giải quyết, và tôi nhớ phiên bản cụ thể đó có lượng lưu hành dưới 100 máy
Về sau tôi tìm lại được ghi chú cho một cuốn sách chưa xuất bản, và thực tế hơi khác một chút. Việc kiểm thử game không chỉ giới hạn ở gameplay, mà phải kiểm thử trên mọi biến thể console NES có thể chạy được. Andrew Davie của Beam Software nhớ lại rằng “The Three Stooges” gây vấn đề trên chiếc NES dùng để test tại văn phòng Nintendo ở Washington, nên ông ấy đã trực tiếp đến đó
Ông ấy nói để trò chơi được thông qua thì có “khoảng 23 biến thể máy”, gồm các tổ hợp nhà sản xuất chip khác nhau, và do thiếu tài liệu chính thức, ông đã khiến dữ liệu sprite được ghi trực tiếp mỗi 2 giây thay vì ghi vào RAM như khuyến nghị chính thức, làm NES quá nóng và gây nhấp nháy sprite xuyên suốt trò chơi. Sau khi sửa thì được phê duyệt phát hành, và ông nghe nói tổ hợp NES gây vấn đề chỉ có khoảng 5 máy trên toàn nước Mỹ, nên đã bị loại khỏi dàn máy test của Nintendo
Gần đây tôi bắt đầu chơi phần tiếp theo là Elite: Dangerous; tuy không phải không có vấn đề, nhưng đó là một trải nghiệm khá đáng kinh ngạc
Việc thấy những yếu tố game nối tiếp từ bản năm 1984 đem lại cảm giác xúc động lạ kỳ. Khi những con tàu, và đặc biệt là trạm Coriolis, vốn trước đây được nhìn dưới dạng đồ họa vector trên màn hình memory-mapped 16K tối tân thời đó, nay chuyển thành render 3D hoàn chỉnh ở 4K/60fps, cảm xúc đến mạnh hơn tôi tưởng
Thành thật mà nói, việc cuối cùng được nhìn thấy bên trong Coriolis chi tiết, có cả bảng quảng cáo, cây cối và thiết bị cập bến, khiến tôi hơi rưng rưng. Dù hiện tại có khó khăn, trò chơi này là một di sản quý giá, và tôi mong nó tiếp tục tồn tại dưới hình thức nào đó
Tự tay cập bến tàu vũ trụ trong khi nghe Blue Danube luôn là một trải nghiệm thư thái
Tôi tự hỏi vì sao các simulator không gian và game không gian lúc nào cũng rơi vào nhiều vấn đề như vậy. Elite Dangerous có vẻ chẳng đi đến đâu, Star Citizen thì như beta vĩnh viễn, còn KSP2 cũng gây thất vọng
Những suy nghĩ tôi viết 9 năm trước: https://hypertexthero.com/elite-dangerous-education/
Bản mở rộng Odyssey cũng thú vị, và tôi hy vọng một ngày nào đó họ sẽ thêm hoạt động ngoài tàu trong không gian và các nhiệm vụ không trọng lực
Cũng có Elite - The New Kind, một phiên bản C gần như trung thành với nguyên tác: https://github.com/fesh0r/newkind
Do Christian Pinder tạo ra: https://www.christianpinder.com/games/
Trang chủ Elite của Ian Bell cũng đáng xem, có nhiều phiên bản gốc: http://www.ianbellelite.com/
Phần cốt lõi của bản NES năm 1991, tức khoảng 30% ROM 128K, về bản chất là phiên bản BBC Master năm 1986, bản thân nó là sự phát triển từ phiên bản BBC Micro ban đầu năm 1984. Các phiên bản Commodore 64 và Apple II cũng cùng dòng dõi đó, và việc phát triển cũng được thực hiện trên BBC Micro
Phần lớn mã ở bank 0, 1, 2 được lấy trực tiếp từ phiên bản BBC gốc, và trong bank 7 cũng còn thêm một phần. Phía trước được gắn thêm các routine đồ họa, âm thanh và tay cầm mới, nhưng trái tim đang đập vẫn là phiên bản Beeb
Ian Bell, tác giả của Elite, từng nói bản NES là phiên bản Elite 8-bit mà ông yêu thích nhất
Nói chung ông cho biết mình thích nhất bản port 32-bit Archimedes
Toàn bộ cuộc phỏng vấn có tại http://www.elitehomepage.org/archive/b5081501.htm
Tôi hiểu câu này là phiên bản ông thích nhất là bản cassette BBC Micro, còn bản chuyển thể ông thích nhất là bản NES. Tuy nhiên cũng có thể tôi đang diễn giải theo hướng mong muốn vì là fanboy của BBC
Tôi thích việc ở đầu mỗi bank có một shim chuyển bank như thế này
SEI/INC $C006/JMP BEGINPhần giải thích nói khá kỹ rằng làm vậy để tiết kiệm không gian, nhưng trong mắt tôi, lý do duy nhất cần
JMPlà vì pipeline lệnh, và có vẻ chỉNOPthôi cũng có thể flush đượcVì vậy tối ưu 2 byte của tôi là:
SEI/INC $FFFD ; dùng thay byte C0 trong vector lệnh/NOPJMPlà vì pipeline lệnh” cũng đúng, nhưng nó cũng có ý nghĩa với con người. Việc thực thi bắt đầu từ bank 7, nên đó là nhảy sang bank 7Nhân tiện, trên Game Boy, entry point nằm trong ROM0 là bank cố định, nên ít nhất với các MBC phổ biến thì ngay từ đầu đã không có vấn đề này
Để so sánh, có mã nguồn của Oolite, một clone Elite mã nguồn mở viết bằng Objective-C: https://github.com/OoliteProject/oolite
https://oolite.space
https://news.ycombinator.com/item?id=7894145
Tôi đã chơi trò này trên C64 lúc 8 tuổi. Giờ đã 30 năm trôi qua mà tôi vẫn không hiểu nổi đoạn mã này
Chỉ riêng bank 0 đã có 18.305 dòng assembly, thật không hình dung nổi họ đã giữ được tất cả trong đầu như thế nào
Ngay cả với những công cụ hàng đầu, để lần theo code hẳn cũng cần năng lực tổ chức và kỷ luật cực lớn. Tôi đã tìm hiểu các assembler dành cho Hitachi 6303[0]/Motorola 6800[1] hồi đầu thập niên 80, và thật đáng kinh ngạc khi thấy người ta đã làm được gì trong các giới hạn công cụ như vậy
Ví dụ, hai assembler dưới đây chỉ cho phép label tối đa 6 ký tự, và cũng không có local label dùng riêng bên trong subroutine. Trong công việc của tôi, dù giới hạn label ở 40 ký tự để dễ mô tả hơn mà vẫn còn thấy vậy
Tuy nhiên, sự đơn giản tương đối của các kiến trúc này thật sự đem lại cảm giác mới mẻ so với công việc embedded trên các hệ thống hiện đại. Việc có thể nắm đại khái toàn bộ trạng thái hệ thống trong đầu rõ ràng là một lợi thế
0: http://www.bitsavers.org/components/hitachi/_dataBooks/U24_H...
1: http://www.bitsavers.org/components/motorola/6800/exorciser/...
Nhìn chung, lập trình assembly cũng không khác ngôn ngữ bậc cao quá nhiều. Ta tổ chức code thành hàm, block, v.v. Việc viết một bức tường code siêu dài với các lệnh jump chằng chịt là tự rước lấy vấn đề nghiêm trọng
Thật tiếc vì nó không phải phần mềm tự do. Nếu tôi là người tạo ra Elite, tôi đã phát hành mọi bản port của game dưới giấy phép tự do
Dù sao thì ngày nay ta có thể chơi Oolite trên một chiếc netbook rẻ tiền, và nhờ danh sách add-on khổng lồ mà có thể có trải nghiệm vui ngang bằng hoặc còn hơn
Phía Braben có vẻ không muốn làm suy yếu bản quyền vì khi đó đang làm Elite 4/Elite: Dangerous
Tất cả mã nguồn nên được tài liệu hóa ở mức này