Compare commits

..
4 Commits
Author SHA1 Message Date
Kelvin Sherlock 4e9088c41b add gio64_gfx for SGI 2026-08-29 23:18:40 -04:00
Alexander Jacocks 23dee5bf2a enable SGI Indigo2, Indy R4600, and Indy R5000, since they function. Add support for choosing graphics boards. (#55) 2026-08-29 23:01:44 -04:00
Kelvin Sherlock bd9d4972b5 move lisa from Ample lite to Ample 2026-08-07 22:41:40 -04:00
anomixer 4224a942ef feat(AmpleWin/AmpleLinux): update MAME downloader & rom_manager to v0.289 (#56)
* Fix slot persistence logic (AmpleWin/Linux) for upstream PR preparation. Implements robust None-aware slot initialization.

* Fix: Explicitly pass empty string arguments for disabled slots (None) to prevent MAME using defaults

* feat(core): update MAME to 0.288, fix compatibility bugs, add PowerBook fallbacks, and optimize download servers

* feat(AmpleWin/AmpleLinux): update MAME to 0.289, remove PowerBook EASC fallbacks, prioritize CallApple server with dragon32 auto-patching and Laser series ROMs
2026-08-07 21:44:51 -04:00
20 changed files with 451 additions and 149 deletions

No files matched your search

+23
View File
@@ -64,6 +64,29 @@
</dict> </dict>
</array> </array>
</dict> </dict>
<dict>
<key>name</key>
<string>gio64_gfx</string>
<key>description</key>
<string>GIO64 Graphics</string>
<key>options</key>
<array>
<dict>
<key>value</key>
<string>xl24</string>
<key>description</key>
<string>SGI 24-bit XL board</string>
<key>default</key>
<true/>
</dict>
<dict>
<key>value</key>
<string>xl8</string>
<key>description</key>
<string>SGI 8-bit XL board</string>
</dict>
</array>
</dict>
</array> </array>
<key>devices</key> <key>devices</key>
<array> <array>
+23
View File
@@ -76,6 +76,29 @@
</dict> </dict>
</array> </array>
</dict> </dict>
<dict>
<key>name</key>
<string>gio64_gfx</string>
<key>description</key>
<string>GIO32 Graphics</string>
<key>options</key>
<array>
<dict>
<key>value</key>
<string>xl24</string>
<key>description</key>
<string>SGI 24-bit XL board</string>
<key>default</key>
<true/>
</dict>
<dict>
<key>value</key>
<string>xl8</string>
<key>description</key>
<string>SGI 8-bit XL board</string>
</dict>
</array>
</dict>
</array> </array>
<key>devices</key> <key>devices</key>
<array> <array>
+23
View File
@@ -76,6 +76,29 @@
</dict> </dict>
</array> </array>
</dict> </dict>
<dict>
<key>name</key>
<string>gio64_gfx</string>
<key>description</key>
<string>GIO32 Graphics</string>
<key>options</key>
<array>
<dict>
<key>value</key>
<string>xl24</string>
<key>description</key>
<string>SGI 24-bit XL board</string>
<key>default</key>
<true/>
</dict>
<dict>
<key>value</key>
<string>xl8</string>
<key>description</key>
<string>SGI 8-bit XL board</string>
</dict>
</array>
</dict>
</array> </array>
<key>devices</key> <key>devices</key>
<array> <array>
+23
View File
@@ -58,6 +58,29 @@
</dict> </dict>
</array> </array>
</dict> </dict>
<dict>
<key>name</key>
<string>gio64_gfx</string>
<key>description</key>
<string>GIO32 Graphics</string>
<key>options</key>
<array>
<dict>
<key>value</key>
<string>xl24</string>
<key>description</key>
<string>SGI 24-bit XL board</string>
<key>default</key>
<true/>
</dict>
<dict>
<key>value</key>
<string>xl8</string>
<key>description</key>
<string>SGI 8-bit XL board</string>
</dict>
</array>
</dict>
</array> </array>
<key>devices</key> <key>devices</key>
<array> <array>
+62
View File
@@ -880,6 +880,37 @@
</dict> </dict>
</array> </array>
</dict> </dict>
<dict>
<key>description</key>
<string>Lisa</string>
<key>children</key>
<array>
<dict>
<key>description</key>
<string>Lisa</string>
<key>value</key>
<string>lisa</string>
</dict>
<dict>
<key>description</key>
<string>Lisa2</string>
<key>value</key>
<string>lisa2</string>
</dict>
<dict>
<key>description</key>
<string>Lisa2/10</string>
<key>value</key>
<string>lisa210</string>
</dict>
<dict>
<key>description</key>
<string>Macintosh XL</string>
<key>value</key>
<string>macxl</string>
</dict>
</array>
</dict>
<dict> <dict>
<key>description</key> <key>description</key>
<string>Acorn</string> <string>Acorn</string>
@@ -1129,5 +1160,36 @@
</dict> </dict>
</array> </array>
</dict> </dict>
<dict>
<key>description</key>
<string>Silicon Graphics</string>
<key>children</key>
<array>
<dict>
<key>description</key>
<string> Indigo2 (R4400, 150MHz)</string>
<key>value</key>
<string>indigo2_4415</string>
</dict>
<dict>
<key>description</key>
<string> Indy (R4600, 100MHz)</string>
<key>value</key>
<string>indy_4610</string>
</dict>
<dict>
<key>description</key>
<string> Indy (R4600, 133MHz)</string>
<key>value</key>
<string>indy_4613</string>
</dict>
<dict>
<key>description</key>
<string> Indy (R5000, 150MHz)</string>
<key>value</key>
<string>indy_5015</string>
</dict>
</array>
</dict>
</array> </array>
</plist> </plist>
+24
View File
@@ -1921,6 +1921,12 @@
<string>pd3_mclr</string> <string>pd3_mclr</string>
<key>description</key> <key>description</key>
<string>Micron/XCEED Technology MacroColor 30</string> <string>Micron/XCEED Technology MacroColor 30</string>
</dict>
<dict>
<key>value</key>
<string>kb_ms_natural</string>
<key>description</key>
<string>Microsoft Natural Keyboard</string>
</dict> </dict>
<dict> <dict>
<key>value</key> <key>value</key>
@@ -2174,6 +2180,12 @@
<key>description</key> <key>description</key>
<string>Prológica CP-450 BASIC Disco V. 1.0 (1984)</string> <string>Prológica CP-450 BASIC Disco V. 1.0 (1984)</string>
</dict> </dict>
<dict>
<key>value</key>
<string>ps2_keybc</string>
<key>description</key>
<string>PS/2 Keyboard</string>
</dict>
<dict> <dict>
<key>value</key> <key>value</key>
<string>qsound</string> <string>qsound</string>
@@ -2282,6 +2294,18 @@
<key>description</key> <key>description</key>
<string>SDTANDY FDC</string> <string>SDTANDY FDC</string>
</dict> </dict>
<dict>
<key>value</key>
<string>indigo2_4415</string>
<key>description</key>
<string>SGI Indigo2 (R4400, 150MHz)</string>
</dict>
<dict>
<key>value</key>
<string>indy_4610</string>
<key>description</key>
<string>SGI Indy (R4600, 100MHz)</string>
</dict>
<dict> <dict>
<key>value</key> <key>value</key>
<string>gpib_hardbox</string> <string>gpib_hardbox</string>
+37
View File
@@ -1,5 +1,23 @@
# Agent Task Audit Log - Ample Linux Port # Agent Task Audit Log - Ample Linux Port
## 📅 Session: 2026-08-02 (Session 7)
### 🎯 Objective: Upstream MAME v0.289 Synchronization
Synchronized AmpleLinux with upstream `ksherlock/ample` v0.289 release and updated machine `.plist` configuration definitions.
### ✅ Key Achievements:
1. **PowerBook Native Launch (EASC Bug Fixed)**:
* Removed `macpb160`, `macpb165`, `macpb165c`, `macpb180`, `macpb180c` fallback prompt mechanism in `main.py`, as MAME 0.289 officially resolved the EASC audio chip crash bug.
2. **ROM Manager Priority & Dragon32/Laser Series Fixes**:
* Reordered download servers in `rom_manager.py` to prioritize CallApple (`https://www.callapple.org/roms/`) with MDK (`https://mdk.cab/download/split/`) as backup failover.
* Integrated `patch_dragon32()` in `DownloadWorker` to auto-merge missing modern MAME 0.289 split ROM files (`dragon_data_ltd_1-0.ic18`, `dragon_data_ltd_1-1.ic17`) when downloading `dragon32.zip`.
* Expanded `custom_roms` fallback array to include Laser 128 series (`las128ex`, `las128e2`, `laser128`, `laser128o`, `laser2c`), ensuring seamless auto-download even if omitted from upstream `roms.plist`.
3. **Upstream MAME 0.289 Alignment**:
* Verified `.plist` machine profile definitions (251 files) updated to MAME 0.289.
* Validated compatibility with local MAME 0.289 binaries and slot options.
---
## 📅 Session: 2026-06-05 (Session 6) ## 📅 Session: 2026-06-05 (Session 6)
### 🎯 Objective: PowerBook Compatibility Fallback & Downloader Parity ### 🎯 Objective: PowerBook Compatibility Fallback & Downloader Parity
@@ -42,6 +60,25 @@ Synchronized slot initialization logic with AmpleWin to fix "None" persistence i
--- ---
## 📅 Session: 2026-05-11 (Session 4)
### 🎯 Objective: Slot Configuration Alignment & Bug Fix
Synchronized slot initialization logic with AmpleWin to fix the issue where "None" selections were being overwritten by defaults.
### ✅ Key Achievements:
1. **"None-Aware" Slot Initialization**:
* Applied the `slot_name not in self.current_slots` fix to `main.py`.
* Ensured that manual "None" selections (empty string) are preserved across UI refreshes.
2. **Cross-Platform Feature Parity**:
* Aligned slot behavior with the Windows and Web ports.
3. **Stability**:
* Verified that nested slot defaults still load correctly for new cards.
### 🚀 Current Project Status
The Linux port now shares the same robust slot configuration logic as the Windows version, ensuring a consistent user experience.
---
## 📅 Session: 2026-03-02 (Session 3) ## 📅 Session: 2026-03-02 (Session 3)
### 🎯 Objective: Upstream Version Tracking & Documentation Maintenance ### 🎯 Objective: Upstream Version Tracking & Documentation Maintenance
+5 -2
View File
@@ -28,8 +28,8 @@ This is a port of the macOS native [Ample](https://github.com/ksherlock/ample) p
* **Visual Precision**: Precision support for **Window 1x-4x** modes with machine-specific aspect ratio heuristics. * **Visual Precision**: Precision support for **Window 1x-4x** modes with machine-specific aspect ratio heuristics.
* **Software Library**: Smart filtering, search overlay, and compatibility checking. * **Software Library**: Smart filtering, search overlay, and compatibility checking.
* **Advanced Slot Emulation**: Full support for nested sub-slots (e.g. SCSI cards) with robust default device initialization and persistence for "None" selections. * **Advanced Slot Emulation**: Full support for nested sub-slots (e.g. SCSI cards) with robust default device initialization and persistence for "None" selections.
* **ROM Management**: Real-time search, multi-server failover download, extended library. * **ROM Management**: Real-time search, CallApple primary / MDK failover downloads, `dragon32` auto-patching, and full Laser 128 series library compatibility.
* **Compatibility Fallback**: Automatically detects affected Macintosh PowerBook models (`macpb160` etc.) that suffer from the MAME 0.288 EASC crash bug. Seamlessly switches to a local MAME 0.287 (`mame_0287`) or VGM Mod (`mame-vgm`) if available, or guides users to the MAME SDL Supported Platforms Wiki page to retrieve older packages. * **Full Native Compatibility**: Upstream MAME 0.289 resolved the EASC audio chip crash bug on Macintosh PowerBook models (`macpb160`, `macpb180`, etc.), enabling seamless native launch across all PowerBook systems.
* **Shared Directory**: Full parity with `-share_directory` argument. * **Shared Directory**: Full parity with `-share_directory` argument.
### 🐧 Linux-Specific Features ### 🐧 Linux-Specific Features
@@ -123,3 +123,6 @@ The app auto-detects GNOME and KDE dark/light themes. If your desktop environmen
* Original macOS version developer: [Kelvin Sherlock](https://github.com/ksherlock) * Original macOS version developer: [Kelvin Sherlock](https://github.com/ksherlock)
* **Windows Port Developers: anomixer + Antigravity** * **Windows Port Developers: anomixer + Antigravity**
* **Linux Port**: Adapted from AmpleWin by anomixer + Antigravity * **Linux Port**: Adapted from AmpleWin by anomixer + Antigravity
---
*Disclaimer: AmpleLinux is an independent open-source project and is not affiliated with, authorized, maintained, or endorsed by Apple Inc. or any other respective companies mentioned. All product and company names are trademarks™ or registered® trademarks of their respective holders.*
+5 -2
View File
@@ -28,8 +28,8 @@
* **視覺精準度**:精準支援 **Window 1x-4x** 模式,並內建機器專屬的比例啟發邏輯。 * **視覺精準度**:精準支援 **Window 1x-4x** 模式,並內建機器專屬的比例啟發邏輯。
* **軟體資料庫**:智慧過濾、搜尋遮罩、相容性檢查。 * **軟體資料庫**:智慧過濾、搜尋遮罩、相容性檢查。
* **進階槽位模擬**:完整支援嵌套子槽位(如 SCSI 卡),並具備穩健的設備初始化與「空」(None) 選項持久化邏輯。 * **進階槽位模擬**:完整支援嵌套子槽位(如 SCSI 卡),並具備穩健的設備初始化與「空」(None) 選項持久化邏輯。
* **ROM 管理**:即時搜尋、多伺服器 Failover 下載、擴展韌體庫。 * **ROM 管理**:即時搜尋、CallApple 優先/MDK 備用 Failover 下載、`dragon32` 自動補丁及 Laser 128 全系列韌體庫相容性。
* **相容性降級 (Compatibility Fallback)**:自動偵測受 MAME 0.288 EASC 晶片崩潰 Bug 影響的 PowerBook 機型(如 `macpb160` 等),自動切換至本地的 `mame_0287` 或 `mame-vgm`;若無備用執行檔,則會彈窗提供引導按鈕,協助使用者開啟官方 SDL Wiki 取得適用於該 Linux 發行版的舊版 MAME 執行檔。 * **全面相容性**:MAME 0.289 官方已修正 PowerBook 機型(如 `macpb160`, `macpb180` 等)的 EASC 晶片崩潰 Bug,所有 PowerBook 機型現可使用最新 MAME 核心直接原生啟動。
* **共享目錄**:與 Mac 版功能完全對齊 (`-share_directory`)。 * **共享目錄**:與 Mac 版功能完全對齊 (`-share_directory`)。
### 🐧 Linux 專屬功能 ### 🐧 Linux 專屬功能
@@ -112,3 +112,6 @@ chmod +x build_elf.sh
* 原始 macOS 版本開發者: [Kelvin Sherlock](https://github.com/ksherlock) * 原始 macOS 版本開發者: [Kelvin Sherlock](https://github.com/ksherlock)
* **Windows Port 開發者: anomixer + Antigravity** * **Windows Port 開發者: anomixer + Antigravity**
* **Linux Port**:由 anomixer + Antigravity 基於 AmpleWin 改編 * **Linux Port**:由 anomixer + Antigravity 基於 AmpleWin 改編
---
*免責聲明:AmpleLinux 是一個獨立的開源專案,與 Apple Inc. 或本專案提及之任何其他公司均無任何隸屬、授權、維護或背書關係。所有產品及公司名稱均為其各自持有人的商標™或註冊®商標。*
+34 -61
View File
@@ -1228,6 +1228,16 @@ class AmpleMainWindow(QMainWindow):
# 不再於切換時立即填充軟體清單 (延遲加載以優化效能) # 不再於切換時立即填充軟體清單 (延遲加載以優化效能)
if hasattr(self, 'sw_list'): self.sw_list.clear() if hasattr(self, 'sw_list'): self.sw_list.clear()
def get_default_slots(self):
if not self.current_machine_data:
return {}
old_slots = self.current_slots
self.current_slots = {}
self.initialize_default_slots(self.current_machine_data)
defaults = self.current_slots
self.current_slots = old_slots
return defaults
def initialize_default_slots(self, data, depth=0): def initialize_default_slots(self, data, depth=0):
if depth > 20: return if depth > 20: return
@@ -1312,6 +1322,12 @@ class AmpleMainWindow(QMainWindow):
self.add_slot_row(self.slots_layout, ram_slot) self.add_slot_row(self.slots_layout, ram_slot)
self.slots_layout.addSpacing(5) self.slots_layout.addSpacing(5)
# 1.5 ROM Group
rom_slot = next((s for s in self.current_machine_data['slots'] if s['name'] in ('rom', 'romsize') or s.get('description') in ('ROM', 'ROM/RAM')), None)
if rom_slot:
self.add_slot_row(self.slots_layout, rom_slot)
self.slots_layout.addSpacing(5)
# 2. Disk Drives - EXACTLY same structure as add_slot_row # 2. Disk Drives - EXACTLY same structure as add_slot_row
# Mac hides popup button but it still takes up space. Hamburger at far right. # Mac hides popup button but it still takes up space. Hamburger at far right.
dd_slot = next((s for s in self.current_machine_data['slots'] if s.get('description') == 'Disk Drives'), None) dd_slot = next((s for s in self.current_machine_data['slots'] if s.get('description') == 'Disk Drives'), None)
@@ -1350,19 +1366,12 @@ class AmpleMainWindow(QMainWindow):
self.slots_layout.addLayout(row) self.slots_layout.addLayout(row)
# 3. All other slots # 3. All other slots
excluded_names = {'ramsize'}
if rom_slot:
excluded_names.add(rom_slot['name'])
for slot in self.current_machine_data['slots']: for slot in self.current_machine_data['slots']:
if slot['name'] != 'ramsize' and slot.get('description') != 'Disk Drives': if slot['name'] not in excluded_names and slot.get('description') != 'Disk Drives':
self.add_slot_row(self.slots_layout, slot) self.add_slot_row(self.slots_layout, slot)
self.slots_layout.addStretch() self.slots_layout.addStretch()
@@ -1879,8 +1888,20 @@ class AmpleMainWindow(QMainWindow):
# Positional arguments allow MAME's Software List manager to resolve them. # Positional arguments allow MAME's Software List manager to resolve them.
soft_list_args.append(self.selected_software) soft_list_args.append(self.selected_software)
# Get defaults recursively
defaults = self.get_default_slots()
# Filter slots: if a slot is set to empty "", only pass it to MAME if its default value was NOT empty
active_slots = {}
for slot_name, option in self.current_slots.items():
if option == "":
default_val = defaults.get(slot_name, "")
if default_val == "":
continue
active_slots[slot_name] = option
# Build base args # Build base args
args = self.launcher.build_args(self.selected_machine, self.current_slots, filtered_media, soft_list_args) args = self.launcher.build_args(self.selected_machine, active_slots, filtered_media, soft_list_args)
# Add UI Video options for preview # Add UI Video options for preview
win_mode = self.win_mode.currentText() win_mode = self.win_mode.currentText()
@@ -2145,40 +2166,6 @@ class AmpleMainWindow(QMainWindow):
cmd_str = self.cmd_preview.toPlainText().strip() cmd_str = self.cmd_preview.toPlainText().strip()
if not cmd_str: return if not cmd_str: return
# EASC PowerBook 0.288 Crash Fallback Check
affected_macs = ["macpb160", "macpb180", "macpb165", "macpb165c", "macpb180c"]
if self.selected_machine in affected_macs:
mame_bin_dir = os.path.dirname(self.launcher.mame_path)
alt_mac_exe = os.path.join(mame_bin_dir, "mame_0287")
vgm_mac_exe = os.path.join(mame_bin_dir, "mame-vgm")
# Check if any fallback is already present
has_fallback = os.path.exists(alt_mac_exe) or os.path.exists(vgm_mac_exe)
if not has_fallback:
msg_box = QMessageBox(self)
msg_box.setIcon(QMessageBox.Warning)
msg_box.setWindowTitle("EASC Audio Chip Bug (MAME v0.288)")
msg_box.setText(f"The machine '{self.selected_machine}' will crash on MAME v0.288 due to an upstream C++ type mismatch bug.")
msg_box.setInformativeText(
"To run this model, you can download a compatible older version of MAME (e.g. v0.287) and place the executable named 'mame_0287' inside your 'mame' folder,\n"
"or run a compatible sibling model instead (e.g. 'macpb170' or 'macpb140')."
)
dl_btn = msg_box.addButton("Download Fallback (v0.287)", QMessageBox.YesRole)
force_btn = msg_box.addButton("Force Launch (v0.288)", QMessageBox.NoRole)
cancel_btn = msg_box.addButton("Cancel", QMessageBox.RejectRole)
msg_box.exec()
if msg_box.clickedButton() == dl_btn:
_xdg_open("https://wiki.mamedev.org/index.php/SDL_Supported_Platforms")
return
elif msg_box.clickedButton() == force_btn:
pass
else:
return
print(f"Launching custom command: {cmd_str}") print(f"Launching custom command: {cmd_str}")
# Determine the MAME binary directory # Determine the MAME binary directory
@@ -2204,21 +2191,7 @@ class AmpleMainWindow(QMainWindow):
target_exe_path = args[0] target_exe_path = args[0]
if exe_cmd == "mame": if exe_cmd == "mame":
affected_macs = ["macpb160", "macpb180", "macpb165", "macpb165c", "macpb180c"] target_exe_path = self.launcher.mame_path
alt_mac_exe = os.path.join(mame_bin_dir, "mame_0287")
vgm_mac_exe = os.path.join(mame_bin_dir, "mame-vgm")
if self.selected_machine in affected_macs:
if os.path.exists(alt_mac_exe):
target_exe_path = alt_mac_exe
print(f"Applying compatibility fallback: using mame_0287 for {self.selected_machine}")
elif os.path.exists(vgm_mac_exe):
target_exe_path = vgm_mac_exe
print(f"Applying compatibility fallback: using mame-vgm for {self.selected_machine}")
else:
target_exe_path = self.launcher.mame_path
else:
target_exe_path = self.launcher.mame_path
elif exe_cmd == "mame-vgm": elif exe_cmd == "mame-vgm":
path_vgm = os.path.join(mame_bin_dir, "mame-vgm") path_vgm = os.path.join(mame_bin_dir, "mame-vgm")
if os.path.exists(path_vgm): if os.path.exists(path_vgm):
+39 -3
View File
@@ -40,6 +40,10 @@ class DownloadWorker(QRunnable):
with open(self.dest_path, 'wb') as f: with open(self.dest_path, 'wb') as f:
f.write(response.content) f.write(response.content)
# Special patch for dragon32 to merge MDK split files if missing
if self.value == 'dragon32':
self.patch_dragon32()
self.signals.finished.emit(self.value, True) self.signals.finished.emit(self.value, True)
return # Success! return # Success!
except Exception as e: except Exception as e:
@@ -53,14 +57,41 @@ class DownloadWorker(QRunnable):
self.signals.status.emit(f"Error: {last_error}") self.signals.status.emit(f"Error: {last_error}")
self.signals.finished.emit(self.value, False) self.signals.finished.emit(self.value, False)
def patch_dragon32(self):
try:
mdk_url = "https://mdk.cab/download/split/dragon32.zip"
resp = requests.get(mdk_url, headers=self.headers, timeout=20)
if resp.status_code == 200 and len(resp.content) > 100:
import zipfile, io
existing_data = open(self.dest_path, 'rb').read()
z_existing = zipfile.ZipFile(io.BytesIO(existing_data))
z_mdk = zipfile.ZipFile(io.BytesIO(resp.content))
existing_names = set(z_existing.namelist())
mdk_names = set(z_mdk.namelist())
missing = mdk_names - existing_names
if missing:
out_buf = io.BytesIO()
with zipfile.ZipFile(out_buf, 'w', zipfile.ZIP_DEFLATED) as zout:
for item in z_existing.infolist():
zout.writestr(item, z_existing.read(item.filename))
for item in z_mdk.infolist():
if item.filename in missing:
zout.writestr(item, z_mdk.read(item.filename))
with open(self.dest_path, 'wb') as f:
f.write(out_buf.getvalue())
except Exception as e:
print(f"Warning: dragon32 patch failed: {e}")
class RomManager(QObject): class RomManager(QObject):
def __init__(self, resources_path, roms_dir): def __init__(self, resources_path, roms_dir):
super().__init__() super().__init__()
self.resources_path = resources_path self.resources_path = resources_path
self.roms_dir = roms_dir self.roms_dir = roms_dir
self.base_urls = [ self.base_urls = [
"https://mdk.cab/download/split/", "https://www.callapple.org/roms/",
"https://www.callapple.org/roms/" "https://mdk.cab/download/split/"
] ]
self.rom_list = self.load_rom_list() self.rom_list = self.load_rom_list()
@@ -78,7 +109,12 @@ class RomManager(QObject):
{'value': 'prav8c', 'description': 'Pravetz 8C'}, {'value': 'prav8c', 'description': 'Pravetz 8C'},
{'value': 'prav82', 'description': 'Pravetz 82'}, {'value': 'prav82', 'description': 'Pravetz 82'},
{'value': 'prav8m', 'description': 'Pravetz 8M'}, {'value': 'prav8m', 'description': 'Pravetz 8M'},
{'value': 'prav8d', 'description': 'Pravetz 8D'} {'value': 'prav8d', 'description': 'Pravetz 8D'},
{'value': 'las128ex', 'description': 'Laser 128EX'},
{'value': 'las128e2', 'description': 'Laser 128EX/2'},
{'value': 'laser128', 'description': 'Laser 128'},
{'value': 'laser128o', 'description': 'Laser 128 (Original)'},
{'value': 'laser2c', 'description': 'Laser 2c'}
] ]
existing_values = {r.get('value') for r in roms if 'value' in r} existing_values = {r.get('value') for r in roms if 'value' in r}
for cr in custom_roms: for cr in custom_roms:
+55 -10
View File
@@ -1,19 +1,44 @@
# Agent Task Audit Log - Ample Windows Port # Agent Task Audit Log - Ample Windows Port
## 📅 Session: 2026-08-02 (Session 17)
### 🎯 Objective: Upstream MAME v0.289 Synchronization
Synchronized AmpleWin with upstream `ksherlock/ample` v0.289 release, updated official MAME download binary URL, and updated machine `.plist` configuration definitions.
### ✅ Key Achievements:
1. **MAME 0.289 Downloader Upgrade**:
* Updated `mame_downloader.py` download target to official MAME v0.289 64-bit binary release (`mame0289b_x64.exe`).
2. **PowerBook Native Launch (EASC Bug Fixed)**:
* Removed `macpb160`, `macpb165`, `macpb165c`, `macpb180`, `macpb180c` fallback prompt mechanism in `main.py`, as MAME 0.289 officially resolved the EASC audio chip crash bug. All PowerBook models now launch directly using the main MAME 0.289 binary.
3. **ROM Manager Priority & Dragon32/Laser Series Fixes**:
* Reordered download servers in `rom_manager.py` to prioritize CallApple (`https://www.callapple.org/roms/`) with MDK (`https://mdk.cab/download/split/`) as backup failover.
* Integrated `patch_dragon32()` in `DownloadWorker` to auto-merge missing modern MAME 0.289 split ROM files (`dragon_data_ltd_1-0.ic18`, `dragon_data_ltd_1-1.ic17`) when downloading `dragon32.zip`.
* Expanded `custom_roms` fallback array to include Laser 128 series (`las128ex`, `las128e2`, `laser128`, `laser128o`, `laser2c`), ensuring seamless auto-download even if omitted from upstream `roms.plist`.
4. **Machine Profile & ROM Parity**:
* Verified `.plist` machine profile definitions (251 files) updated to MAME 0.289.
* Synchronized all updated `.plist` configurations across monorepo to `AmpleWeb/public/resources/`.
---
## 📅 Session: 2026-06-05 (Session 16) ## 📅 Session: 2026-06-05 (Session 16)
### 🎯 Objective: PowerBook Compatibility Fallback & Downloader Acceleration ### 🎯 Objective: MAME v0.288 Upgrade, PowerBook Fallbacks & AmpleWeb Synchronization
Addressed upstream MAME 0.288 C++ late-binding bug causing crashes on EASC audio chip Macs, and accelerated the VGM Mod download. Addressed upstream MAME 0.288 EASC crash bugs, compiled the v0.288-patched Wasm core, and synchronized all 0.288 machine plists and ROM mapping to AmpleWeb frontend.
### ✅ Key Achievements: ### ✅ Key Achievements:
1. **EASC Crash Fallback Mechanism**: 1. **MAME v0.288 Wasm Compile & Deploy**:
* Added automatic detection for affected PowerBook models (`macpb160`, `macpb180`, `macpb165`, `macpb165c`, `macpb180c`). * Integrated memory export and EASC patch in `c:\dev\MameWasm` and compiled production Wasm core (`mameample.js` / `mameample.wasm`).
* Implements seamless redirect to `mame_0287.exe` or `mame-vgm.exe` (v0.280) if present in the executable folder. * Compressed and deployed `mame.js` / `mame.wasm.gz` to both `AmpleWeb` and `ampleweb-ai`.
* Provides user warning with options to auto-download MAME v0.280 (VGM Mod) fallback, force launch under 0.288, or cancel. 2. **0.288 Machine Configuration Sync**:
2. **Downloader Optimization**: * Copied 251 updated `.plist` machine profiles from Core to both web projects.
* Switched VGM Mod download mirror to prioritize `mirror.ghproxy.com` GitHub proxy for faster global asset retrieval. * Expanded `DRIVER_ROM_MAP` in both `App.tsx` from 158 to 248 entries to fully support new 0.288 models (Amiga A1000/A2000/A500, Atari ST, Lisa, etc.).
3. **ROM Manager Priority Check**: 3. **EASC Crash Fallback (Core)**:
* Reordered ROM base URLs to prioritize `mdk.cab` over `callapple.org`. This guarantees the latest split set ROMs (like `dragon32` with split files) are downloaded correctly, solving the missing files crash on MAME 0.288+. * Added automatic detection and v0.280/v0.287 fallback launcher mechanism for EASC audio chip Macs in AmpleWin/Linux.
4. **UI Slots Layout Ordering Parity (Core)**:
* Reordered rendering in `AmpleWin` and `AmpleLinux` slots panel. Now, ROM slots (`rom` or `romsize` or description `ROM`/`ROM/RAM`) are rendered directly after the RAM slot, positioning `Disk Drives` properly in the 3rd slot when ROM configuration exists.
5. **Downloader Optimization & SCSI Fix**:
* Prioritized `mdk.cab` split server in `rom_manager.py` and `rom_manager_cli.py` to prevent missing file errors on 0.288+.
* Verified SCSI CD-ROM 2x speed fallback `cdrom_2x` mappings on both frontends to resolve media mount bugs.
--- ---
@@ -43,6 +68,26 @@ Resolved an issue where slots with defaults could not be set to "None" because U
--- ---
## 📅 Session: 2026-05-11 (Session 14)
### 🎯 Objective: Slot Configuration Parity & "None" Persistence
Resolved a long-standing issue where slots with default equipment could not be set to "None" because UI refreshes would force-revert them to defaults.
### ✅ Key Achievements:
1. **"None-Aware" Slot Initialization**:
* Modified `initialize_default_slots` in `main.py` to use key existence checks (`if slot_name not in self.current_slots`) instead of truthiness checks.
* This ensures that an empty string selection (`""` or "None") is respected as a deliberate user choice and not overwritten by defaults.
2. **Cross-Platform Alignment**:
* Coordinated this fix across **AmpleWin** and **AmpleLinux**.
* Verified that **AmpleWeb** already correctly handled this logic due to its Object-based option finding mechanism.
3. **Nested Slot Preservation**:
* Ensured that newly appeared sub-slots (e.g., when plugging in a SCSI or CFFA2 card) still automatically load their default devices, maintaining high usability.
### 🚀 Current Project Status
Slot configuration behavior is now fully consistent across Windows, Linux, and Web ports, accurately respecting "None" selections while preserving automated nested configurations.
---
## 📅 Session: 2026-03-02 (Session 13) ## 📅 Session: 2026-03-02 (Session 13)
### 🎯 Objective: Upstream Version Bump & Documentation Maintenance ### 🎯 Objective: Upstream Version Bump & Documentation Maintenance
+5 -2
View File
@@ -45,9 +45,9 @@ This is a precision port of the macOS native [Ample](https://github.com/ksherloc
* **Slot Consistency**: Improved logic to respect "None" (empty) selections across UI refreshes, matching the high standards of the native macOS port. * **Slot Consistency**: Improved logic to respect "None" (empty) selections across UI refreshes, matching the high standards of the native macOS port.
* **ROM Management**: * **ROM Management**:
* **Search Filter**: Real-time searching in the ROM manager window to quickly find system firmwares. * **Search Filter**: Real-time searching in the ROM manager window to quickly find system firmwares.
* **Download Failover**: Automatic multi-server acquisition (callapple + mdk.cab) with transparent failover for maximum stability. * **Download Failover**: CallApple server primary acquisition with MDK failover support, featuring automated `dragon32` split ROM patching and full Laser 128 series firmware compatibility.
* **Extended Library**: Expanded support for PowerBook Duo 280, Pravetz 8C, TK3000, and more. * **Extended Library**: Expanded support for PowerBook Duo 280, Pravetz 8C, TK3000, and more.
* **Compatibility Fallback**: Automatically detects affected Macintosh PowerBook models (`macpb160` etc.) that suffer from the MAME 0.288 EASC crash bug. Seamlessly switches to a local MAME 0.287 (`mame_0287.exe`) or VGM Mod (`mame-vgm.exe`), or offers to download the v0.280 fallback copy. * **Full Native Compatibility**: Upstream MAME 0.289 resolved the EASC audio chip crash bug on Macintosh PowerBook models (`macpb160`, `macpb180`, etc.), enabling seamless native launch across all PowerBook systems.
* **Shared Directory**: Full parity with the Mac version, allowing direct host-to-emulator file sharing via the `-share_directory` argument. (Includes click-to-browse support). * **Shared Directory**: Full parity with the Mac version, allowing direct host-to-emulator file sharing via the `-share_directory` argument. (Includes click-to-browse support).
* **VGM Support (Advanced)**: Since modern MAME removed VGM support, AmpleWin implements a robust background workflow to download and configure the **MAME-VGM Mod (v0.280)**. It uses a non-destructive extraction process (`mame-vgm.exe`) to preserve your main MAME core while restoring high-fidelity music recording. * **VGM Support (Advanced)**: Since modern MAME removed VGM support, AmpleWin implements a robust background workflow to download and configure the **MAME-VGM Mod (v0.280)**. It uses a non-destructive extraction process (`mame-vgm.exe`) to preserve your main MAME core while restoring high-fidelity music recording.
@@ -106,3 +106,6 @@ If you want to create a standalone executable for distribution:
* Original macOS version developer: [Kelvin Sherlock](https://github.com/ksherlock) * Original macOS version developer: [Kelvin Sherlock](https://github.com/ksherlock)
* **Windows Port Developers: anomixer + Antigravity**: Dedicated to providing the ultimate Apple II / Macintosh emulation experience on Windows. * **Windows Port Developers: anomixer + Antigravity**: Dedicated to providing the ultimate Apple II / Macintosh emulation experience on Windows.
---
*Disclaimer: AmpleWin is an independent open-source project and is not affiliated with, authorized, maintained, or endorsed by Apple Inc. or any other respective companies mentioned. All product and company names are trademarks™ or registered® trademarks of their respective holders.*
+5 -2
View File
@@ -45,9 +45,9 @@
* **配置持久性**:優化插槽初始化邏輯,確保在 UI 重新整理時能正確保留「空」(None) 的選取狀態,與 Mac 原生行為一致。 * **配置持久性**:優化插槽初始化邏輯,確保在 UI 重新整理時能正確保留「空」(None) 的選取狀態,與 Mac 原生行為一致。
* **ROM 管理**: * **ROM 管理**:
* **搜尋過濾**:ROM 管理器視窗中新增即時搜尋功能,方便快速查詢系統韌體。 * **搜尋過濾**:ROM 管理器視窗中新增即時搜尋功能,方便快速查詢系統韌體。
* **下載 Failover**:多伺服器自動獲取 (callapple + mdk.cab),主伺服器失敗時自動切換,確保最高穩定性。 * **下載 Failover**:CallApple 伺服器優先獲取,MDK 伺服器備用 failover 支援,並具備 `dragon32` 缺檔自動補丁與 Laser 128 全系列韌體相容性保障。
* **擴展支援**:新增 Macintosh PowerBook Duo 280, Pravetz 8C, TK3000 //e 等機型。 * **擴展支援**:新增 Macintosh PowerBook Duo 280, Pravetz 8C, TK3000 //e 等機型。
* **相容性降級 (Compatibility Fallback)**:自動偵測受 MAME 0.288 EASC 晶片崩潰 Bug 影響的 PowerBook 機型(如 `macpb160` 等),無縫切換至本地的 `mame_0287.exe` 或 `mame-vgm.exe` (v0.280),或提示一鍵下載備用版本,防範啟動崩潰。 * **全面相容性**:MAME 0.289 官方已修正 PowerBook 機型(如 `macpb160`, `macpb180` 等)的 EASC 晶片崩潰 Bug,所有 PowerBook 機型現可使用最新 MAME 核心直接原生啟動。
* **共享目錄 (Shared Directory)**:與 Mac 版功能完全對齊,支援透過 `-share_directory` 直接在主機與模擬器間共享檔案 (支援點擊輸入框瀏覽)。 * **共享目錄 (Shared Directory)**:與 Mac 版功能完全對齊,支援透過 `-share_directory` 直接在主機與模擬器間共享檔案 (支援點擊輸入框瀏覽)。
* **VGM 錄音支援 (進階)**:由於現代 MAME 已移除 VGM 支援,AmpleWin 實作了強韌的自動化工作流,可下載並平行配置 **MAME-VGM Mod (v0.280)**。透過非破壞性的解壓技術(保留原本的 `mame.exe` 並另存為 `mame-vgm.exe`),在不影響主核心的情況下完美還原錄音功能。 * **VGM 錄音支援 (進階)**:由於現代 MAME 已移除 VGM 支援,AmpleWin 實作了強韌的自動化工作流,可下載並平行配置 **MAME-VGM Mod (v0.280)**。透過非破壞性的解壓技術(保留原本的 `mame.exe` 並另存為 `mame-vgm.exe`),在不影響主核心的情況下完美還原錄音功能。
@@ -106,3 +106,6 @@
* 原始 macOS 版本開發者: [Kelvin Sherlock](https://github.com/ksherlock) * 原始 macOS 版本開發者: [Kelvin Sherlock](https://github.com/ksherlock)
* **Windows Port 開發者: anomixer + Antigravity**:致力於在 Windows 生態系中提供最極致的 Apple II / Macintosh 模擬體驗。 * **Windows Port 開發者: anomixer + Antigravity**:致力於在 Windows 生態系中提供最極致的 Apple II / Macintosh 模擬體驗。
---
*免責聲明:AmpleWin 是一個獨立的開源專案,與 Apple Inc. 或本專案提及之任何其他公司均無任何隸屬、授權、維護或背書關係。所有產品及公司名稱均為其各自持有人的商標™或註冊®商標。*
+34 -61
View File
@@ -1121,6 +1121,16 @@ class AmpleMainWindow(QMainWindow):
# 不再於切換時立即填充軟體清單 (延遲加載以優化效能) # 不再於切換時立即填充軟體清單 (延遲加載以優化效能)
if hasattr(self, 'sw_list'): self.sw_list.clear() if hasattr(self, 'sw_list'): self.sw_list.clear()
def get_default_slots(self):
if not self.current_machine_data:
return {}
old_slots = self.current_slots
self.current_slots = {}
self.initialize_default_slots(self.current_machine_data)
defaults = self.current_slots
self.current_slots = old_slots
return defaults
def initialize_default_slots(self, data, depth=0): def initialize_default_slots(self, data, depth=0):
if depth > 20: return if depth > 20: return
@@ -1205,6 +1215,12 @@ class AmpleMainWindow(QMainWindow):
self.add_slot_row(self.slots_layout, ram_slot) self.add_slot_row(self.slots_layout, ram_slot)
self.slots_layout.addSpacing(5) self.slots_layout.addSpacing(5)
# 1.5 ROM Group
rom_slot = next((s for s in self.current_machine_data['slots'] if s['name'] in ('rom', 'romsize') or s.get('description') in ('ROM', 'ROM/RAM')), None)
if rom_slot:
self.add_slot_row(self.slots_layout, rom_slot)
self.slots_layout.addSpacing(5)
# 2. Disk Drives - EXACTLY same structure as add_slot_row # 2. Disk Drives - EXACTLY same structure as add_slot_row
# Mac hides popup button but it still takes up space. Hamburger at far right. # Mac hides popup button but it still takes up space. Hamburger at far right.
dd_slot = next((s for s in self.current_machine_data['slots'] if s.get('description') == 'Disk Drives'), None) dd_slot = next((s for s in self.current_machine_data['slots'] if s.get('description') == 'Disk Drives'), None)
@@ -1243,19 +1259,12 @@ class AmpleMainWindow(QMainWindow):
self.slots_layout.addLayout(row) self.slots_layout.addLayout(row)
# 3. All other slots # 3. All other slots
excluded_names = {'ramsize'}
if rom_slot:
excluded_names.add(rom_slot['name'])
for slot in self.current_machine_data['slots']: for slot in self.current_machine_data['slots']:
if slot['name'] != 'ramsize' and slot.get('description') != 'Disk Drives': if slot['name'] not in excluded_names and slot.get('description') != 'Disk Drives':
self.add_slot_row(self.slots_layout, slot) self.add_slot_row(self.slots_layout, slot)
self.slots_layout.addStretch() self.slots_layout.addStretch()
@@ -1772,8 +1781,20 @@ class AmpleMainWindow(QMainWindow):
# Positional arguments allow MAME's Software List manager to resolve them. # Positional arguments allow MAME's Software List manager to resolve them.
soft_list_args.append(self.selected_software) soft_list_args.append(self.selected_software)
# Get defaults recursively
defaults = self.get_default_slots()
# Filter slots: if a slot is set to empty "", only pass it to MAME if its default value was NOT empty
active_slots = {}
for slot_name, option in self.current_slots.items():
if option == "":
default_val = defaults.get(slot_name, "")
if default_val == "":
continue
active_slots[slot_name] = option
# Build base args # Build base args
args = self.launcher.build_args(self.selected_machine, self.current_slots, filtered_media, soft_list_args) args = self.launcher.build_args(self.selected_machine, active_slots, filtered_media, soft_list_args)
# Add UI Video options for preview # Add UI Video options for preview
win_mode = self.win_mode.currentText() win_mode = self.win_mode.currentText()
@@ -2029,40 +2050,6 @@ class AmpleMainWindow(QMainWindow):
cmd_str = self.cmd_preview.toPlainText().strip() cmd_str = self.cmd_preview.toPlainText().strip()
if not cmd_str: return if not cmd_str: return
# EASC PowerBook 0.288 Crash Fallback Check
affected_macs = ["macpb160", "macpb180", "macpb165", "macpb165c", "macpb180c"]
if self.selected_machine in affected_macs:
mame_bin_dir = os.path.dirname(self.launcher.mame_path)
alt_mac_exe = os.path.join(mame_bin_dir, "mame_0287.exe")
vgm_mac_exe = os.path.join(mame_bin_dir, "mame-vgm.exe")
# Check if any fallback is already present
has_fallback = os.path.exists(alt_mac_exe) or os.path.exists(vgm_mac_exe)
if not has_fallback:
msg_box = QMessageBox(self)
msg_box.setIcon(QMessageBox.Warning)
msg_box.setWindowTitle("EASC Audio Chip Bug (MAME v0.288)")
msg_box.setText(f"The machine '{self.selected_machine}' will crash on MAME v0.288 due to an upstream C++ type mismatch bug.")
msg_box.setInformativeText(
"To run this model, you can automatically download MAME v0.280 (VGM Mod) as a fallback, "
"or run a compatible sibling model instead (e.g. 'macpb170' or 'macpb140')."
)
dl_btn = msg_box.addButton("Download Fallback (v0.280)", QMessageBox.YesRole)
force_btn = msg_box.addButton("Force Launch (v0.288)", QMessageBox.NoRole)
cancel_btn = msg_box.addButton("Cancel", QMessageBox.RejectRole)
msg_box.exec()
if msg_box.clickedButton() == dl_btn:
self.download_vgm_mod(mame_bin_dir)
return
elif msg_box.clickedButton() == force_btn:
pass
else:
return
print(f"Launching custom command: {cmd_str}") print(f"Launching custom command: {cmd_str}")
# Determine the MAME binary directory # Determine the MAME binary directory
@@ -2097,21 +2084,7 @@ class AmpleMainWindow(QMainWindow):
target_exe_path = args[0] target_exe_path = args[0]
if exe_cmd in ["mame", "mame.exe"]: if exe_cmd in ["mame", "mame.exe"]:
affected_macs = ["macpb160", "macpb180", "macpb165", "macpb165c", "macpb180c"] target_exe_path = self.launcher.mame_path
alt_mac_exe = os.path.join(mame_bin_dir, "mame_0287.exe")
vgm_mac_exe = os.path.join(mame_bin_dir, "mame-vgm.exe")
if self.selected_machine in affected_macs:
if os.path.exists(alt_mac_exe):
target_exe_path = alt_mac_exe
print(f"Applying compatibility fallback: using mame_0287.exe for {self.selected_machine}")
elif os.path.exists(vgm_mac_exe):
target_exe_path = vgm_mac_exe
print(f"Applying compatibility fallback: using mame-vgm.exe for {self.selected_machine}")
else:
target_exe_path = self.launcher.mame_path
else:
target_exe_path = self.launcher.mame_path
elif exe_cmd in ["mame-vgm", "mame-vgm.exe"]: elif exe_cmd in ["mame-vgm", "mame-vgm.exe"]:
path_vgm = os.path.join(mame_bin_dir, "mame-vgm.exe") path_vgm = os.path.join(mame_bin_dir, "mame-vgm.exe")
if os.path.exists(path_vgm): if os.path.exists(path_vgm):
+2 -2
View File
@@ -11,8 +11,8 @@ class MameDownloadWorker(QThread):
def __init__(self, dest_dir): def __init__(self, dest_dir):
super().__init__() super().__init__()
self.dest_dir = dest_dir self.dest_dir = dest_dir
# MAME official self-extracting EXE - Updated to 0.288 # MAME official self-extracting EXE - Updated to 0.289
self.url = "https://github.com/mamedev/mame/releases/download/mame0288/mame0288b_x64.exe" self.url = "https://github.com/mamedev/mame/releases/download/mame0289/mame0289b_x64.exe"
def run(self): def run(self):
try: try:
+6
View File
@@ -0,0 +1,6 @@
{
"name": "AmpleWin",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}
+39 -3
View File
@@ -40,6 +40,10 @@ class DownloadWorker(QRunnable):
with open(self.dest_path, 'wb') as f: with open(self.dest_path, 'wb') as f:
f.write(response.content) f.write(response.content)
# Special patch for dragon32 to merge MDK split files if missing
if self.value == 'dragon32':
self.patch_dragon32()
self.signals.finished.emit(self.value, True) self.signals.finished.emit(self.value, True)
return # Success! return # Success!
except Exception as e: except Exception as e:
@@ -53,14 +57,41 @@ class DownloadWorker(QRunnable):
self.signals.status.emit(f"Error: {last_error}") self.signals.status.emit(f"Error: {last_error}")
self.signals.finished.emit(self.value, False) self.signals.finished.emit(self.value, False)
def patch_dragon32(self):
try:
mdk_url = "https://mdk.cab/download/split/dragon32.zip"
resp = requests.get(mdk_url, headers=self.headers, timeout=20)
if resp.status_code == 200 and len(resp.content) > 100:
import zipfile, io
existing_data = open(self.dest_path, 'rb').read()
z_existing = zipfile.ZipFile(io.BytesIO(existing_data))
z_mdk = zipfile.ZipFile(io.BytesIO(resp.content))
existing_names = set(z_existing.namelist())
mdk_names = set(z_mdk.namelist())
missing = mdk_names - existing_names
if missing:
out_buf = io.BytesIO()
with zipfile.ZipFile(out_buf, 'w', zipfile.ZIP_DEFLATED) as zout:
for item in z_existing.infolist():
zout.writestr(item, z_existing.read(item.filename))
for item in z_mdk.infolist():
if item.filename in missing:
zout.writestr(item, z_mdk.read(item.filename))
with open(self.dest_path, 'wb') as f:
f.write(out_buf.getvalue())
except Exception as e:
print(f"Warning: dragon32 patch failed: {e}")
class RomManager(QObject): class RomManager(QObject):
def __init__(self, resources_path, roms_dir): def __init__(self, resources_path, roms_dir):
super().__init__() super().__init__()
self.resources_path = resources_path self.resources_path = resources_path
self.roms_dir = roms_dir self.roms_dir = roms_dir
self.base_urls = [ self.base_urls = [
"https://mdk.cab/download/split/", "https://www.callapple.org/roms/",
"https://www.callapple.org/roms/" "https://mdk.cab/download/split/"
] ]
self.rom_list = self.load_rom_list() self.rom_list = self.load_rom_list()
@@ -78,7 +109,12 @@ class RomManager(QObject):
{'value': 'prav8c', 'description': 'Pravetz 8C'}, {'value': 'prav8c', 'description': 'Pravetz 8C'},
{'value': 'prav82', 'description': 'Pravetz 82'}, {'value': 'prav82', 'description': 'Pravetz 82'},
{'value': 'prav8m', 'description': 'Pravetz 8M'}, {'value': 'prav8m', 'description': 'Pravetz 8M'},
{'value': 'prav8d', 'description': 'Pravetz 8D'} {'value': 'prav8d', 'description': 'Pravetz 8D'},
{'value': 'las128ex', 'description': 'Laser 128EX'},
{'value': 'las128e2', 'description': 'Laser 128EX/2'},
{'value': 'laser128', 'description': 'Laser 128'},
{'value': 'laser128o', 'description': 'Laser 128 (Original)'},
{'value': 'laser2c', 'description': 'Laser 2c'}
] ]
existing_values = {r.get('value') for r in roms if 'value' in r} existing_values = {r.get('value') for r in roms if 'value' in r}
for cr in custom_roms: for cr in custom_roms:
+6
View File
@@ -171,6 +171,9 @@ SLOTS = (
# lisa # lisa
"pp", "pp",
# sgi
"gio64_gfx",
) )
SLOT_NAMES = { SLOT_NAMES = {
@@ -289,6 +292,9 @@ SLOT_NAMES = {
# lisa # lisa
"pp": "Parallel", "pp": "Parallel",
# sgi
"gio64_gfx": "GIO64 Graphics",
} }
+1 -1
View File
@@ -116,6 +116,7 @@ TREE = [
("Macintosh (LC)", None, mac_lc_children), ("Macintosh (LC)", None, mac_lc_children),
("Macintosh (Portable)", None, mac_portable_children), ("Macintosh (Portable)", None, mac_portable_children),
("Macintosh (PowerBook)", None, mac_powerbook_children), ("Macintosh (PowerBook)", None, mac_powerbook_children),
("Lisa", None, lisa_children),
("Acorn", None, acorn_children), ("Acorn", None, acorn_children),
("Atari ST", "st", atari_st_children), ("Atari ST", "st", atari_st_children),
@@ -125,7 +126,6 @@ TREE = [
] ]
TREE_EXTRA = TREE + [ TREE_EXTRA = TREE + [
("Lisa", None, lisa_children),
("Amiga", None, amiga_children), ("Amiga", None, amiga_children),
("DEC VT", None, dec_vt_children), ("DEC VT", None, dec_vt_children),