mirror of
https://github.com/LIV2/CIDER-Software.git
synced 2025-12-06 00:23:50 +00:00
Compare commits
24 Commits
dev-180423
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e23e0adfe9 | |||
| 3183606d23 | |||
| be25d2dae1 | |||
| 96c13103fa | |||
| 1baa384a18 | |||
| 1d174e6024 | |||
| ee663c106c | |||
| c7f43f60c6 | |||
| d495ba8962 | |||
| 0d5ee7f460 | |||
| 1dbb93e487 | |||
| b14297ef66 | |||
| 06314f04a6 | |||
| 1b9d4789b0 | |||
| 118857bdf6 | |||
| 7398c66189 | |||
| f17d232d7c | |||
| 2b389d1f91 | |||
| 83e0231039 | |||
| 3c8e5aeabf | |||
| dc1538b8c2 | |||
| 6db2b712b3 | |||
| 618089c795 | |||
| b1fb7b8aaa |
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@ -5,7 +5,7 @@ permissions:
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "Release_**"
|
||||
- "Release-**"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@ -22,7 +22,7 @@ jobs:
|
||||
- name: Build
|
||||
run: make software package
|
||||
|
||||
- uses: actions/upload-artifact@master
|
||||
- uses: actions/upload-artifact@v4.4
|
||||
with:
|
||||
name: software
|
||||
path: artifacts/*
|
||||
@ -35,7 +35,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4.1.8
|
||||
with:
|
||||
path: artifacts
|
||||
- name: release
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "iderom/ide_device"]
|
||||
path = iderom/ide_device
|
||||
url = git@github.com:LIV2/liv2ride.device.git
|
||||
5
Makefile
5
Makefile
@ -9,21 +9,18 @@ software:
|
||||
$(MAKE) -C bootrom all
|
||||
$(MAKE) -C addram all
|
||||
$(MAKE) -C cflash all
|
||||
$(MAKE) -C iderom all
|
||||
|
||||
clean:
|
||||
$(MAKE) -C bootrom clean
|
||||
$(MAKE) -C addram clean
|
||||
$(MAKE) -C cflash clean
|
||||
$(MAKE) -C iderom clean
|
||||
rm -rf $(ARTIFACTDIR)
|
||||
rm -rf $(TMPDIR)
|
||||
|
||||
package: addram/addram bootrom/bootrom cflash/cflash iderom/cider-ide.rom
|
||||
package: addram/addram bootrom/bootrom cflash/cflash ideupdate/lide.device/lide.rom
|
||||
rm -rf $(TMPDIR)
|
||||
mkdir -p $(TMPDIR)
|
||||
mkdir -p $(ARTIFACTDIR)
|
||||
cp $^ $(TMPDIR)
|
||||
cp iderom/disk/*.adf $(ARTIFACTDIR)
|
||||
cd $(TMPDIR) && xdftool $(ARTIFACTDIR)/CIDER-Software.adf format CIDER $(addprefix + write ,$(notdir $^))
|
||||
cd $(TMPDIR) && lha -c $(ARTIFACTDIR)/CIDER-Software.lha $(notdir $^)
|
||||
|
||||
44
README.md
Normal file
44
README.md
Normal file
@ -0,0 +1,44 @@
|
||||
# CIDER Software
|
||||
This repository contains software utilities for the [CIDER](https://github.com/LIV2/CIDER) expansion board for Amiga computers.
|
||||
|
||||
## What is CIDER?
|
||||
|
||||
CIDER is an expansion board for the Commodore CDTV that significantly enhances its capabilities:
|
||||
- **11.37 MB Fast RAM**: Including 1.5 MB Ranger RAM, 8 MB standard Fast RAM, and 1.87 MB Bonus RAM at $A00000
|
||||
- **IDE Interface**: Built-in IDE controller with autoboot driver for hard drives and other storage
|
||||
- **Dual Kickstart Flash ROM**: Programmable flash memory for multiple Kickstart and Extended ROMs
|
||||
- **In-system programming**: All flash components can be updated without removing the board
|
||||
- **CDTV integration**: Plugs into the CDTV's diagnostic port for seamless integration
|
||||
|
||||
## Tools Overview
|
||||
|
||||
- **[cflash](https://github.com/LIV2/CIDER-Software/tree/main/cflash#cflash)** - Flash ROM programming tool for Kickstart and Extended ROMs
|
||||
- **[addram](https://github.com/LIV2/CIDER-Software/tree/main/addram#addram)** - Manual tool to add BonusRAM to your system with configurable options
|
||||
- **[bootrom](https://github.com/LIV2/CIDER-Software/tree/main/bootrom#cider-bootrom)** - Automatic resident module that adds BonusRAM at boot time
|
||||
|
||||
## Quick Start
|
||||
|
||||
**New to CIDER?** Choose the right tool for your needs:
|
||||
|
||||
- **Want automatic memory activation?** → Use **bootrom** (integrate into Extended ROM for set-and-forget operation)
|
||||
- **Need control over memory settings?** → Use **addram** (command-line tool with options for testing and configuration)
|
||||
- **Want to update ROMs?** → Use **cflash** (program new Kickstart/Extended ROMs to flash memory)
|
||||
|
||||
Each tool has comprehensive documentation with step-by-step instructions for both beginners and advanced users.
|
||||
|
||||
## Downloads
|
||||
Binaries are provided under [Releases](https://github.com/LIV2/CIDER-Software/releases)
|
||||
* CIDER-Software.adf and CIDER-Software.lha contain binaries for the tools in this repository
|
||||
* IDE firmware can be programmed using the lastest [lide-update adf](https://github.com/LIV2/LIDE.device/releases/latest)
|
||||
|
||||
## Third-Party notice
|
||||
lide.device - reloc.S: reloc.S is adapted from the [A4091](https://github.com/A4091/a4091-software) open-source driver and is Copyright Stefan Reinauer
|
||||
lide.device: mounter.c is adapted from the [A4091](https://github.com/A4091/a4091-software) open-source driver and is Copyright 2021-2022 Toni Wilen
|
||||
lide.device: The fast read/write routines for ATA devices are adapted from [Frédéric REQUIN](https://github.com/fredrequin)'s [at_apollo_device](https://github.com/fredrequin/at_apollo_device)
|
||||
|
||||
## License
|
||||
All software contained that is not provided by a third-party is covered by a GPL 2.0 Only license
|
||||
[](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
||||
|
||||
|
||||
CIDER and it's software are licensed under the GPL-2.0 only license
|
||||
251
addram/README.md
251
addram/README.md
@ -1,12 +1,249 @@
|
||||
# Addram
|
||||
# ADDRAM
|
||||
|
||||
A tool to add the BonusRAM ($A0000) to the system
|
||||
A tool to add the BonusRAM to your CIDER-equipped system's memory pool.
|
||||
|
||||
## What is ADDRAM?
|
||||
|
||||
ADDRAM is a tool that activates and adds the BonusRAM provided by your CIDER expansion board to your Amiga's memory system. BonusRAM uses the address space from $A00000 to $BEFFFF.
|
||||
|
||||
When you run ADDRAM, it:
|
||||
1. Tests and detects available BonusRAM
|
||||
2. Enables the BonusRAM hardware
|
||||
3. Adds the memory to your system's Fast RAM pool
|
||||
4. Optionally merges it with existing Fast RAM for better efficiency
|
||||
|
||||
## Before You Start
|
||||
|
||||
### Getting Started
|
||||
- ADDRAM only adds memory that's physically present on your CIDER board
|
||||
- The tool safely tests memory before adding it to avoid system conflicts
|
||||
- **Safe operation**: If BonusRAM is already active, ADDRAM will detect this and exit safely
|
||||
|
||||
### What You'll Need
|
||||
- Your CIDER-equipped Amiga
|
||||
- The addram program (available in [CIDER-Software.adf](https://github.com/LIV2/CIDER-Software/releases/latest))
|
||||
- A CLI/terminal or Workbench to run commands
|
||||
|
||||
### Prerequisites
|
||||
- CIDER expansion board must be properly installed
|
||||
- System should be stable with adequate power
|
||||
- No conflicting memory expansions in the BonusRAM address space
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Simple Memory Addition
|
||||
|
||||
To add BonusRAM to your system with default settings:
|
||||
|
||||
## Usage
|
||||
```
|
||||
-d - Perform a dry-run
|
||||
-v - Verbose
|
||||
-m - Attempt to merge Bonus RAM with Fast RAM Memory block
|
||||
-p <priority> - Set Fast / BonusRAM Priority
|
||||
addram
|
||||
```
|
||||
|
||||
This will:
|
||||
- Test and detect available BonusRAM
|
||||
- Add it to your system as Fast RAM
|
||||
- Use default priority settings
|
||||
|
||||
### Check What Would Happen (Dry Run)
|
||||
|
||||
To see what ADDRAM would do without actually changing anything:
|
||||
|
||||
```
|
||||
addram -d
|
||||
```
|
||||
|
||||
This is useful for:
|
||||
- Checking how much BonusRAM is available
|
||||
- Verifying the tool detects your CIDER board
|
||||
- Testing before making actual changes
|
||||
|
||||
### Verbose Output
|
||||
|
||||
To see detailed information about what's happening:
|
||||
|
||||
```
|
||||
addram -v
|
||||
```
|
||||
|
||||
This shows:
|
||||
- Memory testing progress
|
||||
- Detected memory size
|
||||
- Board information
|
||||
- Priority changes
|
||||
|
||||
### Combined Options
|
||||
|
||||
```
|
||||
addram -d -v
|
||||
```
|
||||
|
||||
Shows detailed information while doing a dry run.
|
||||
|
||||
## Advanced Options
|
||||
|
||||
### Setting Memory Priority
|
||||
|
||||
You can control the priority of Fast RAM and BonusRAM:
|
||||
|
||||
```
|
||||
addram -p 10
|
||||
```
|
||||
|
||||
This sets the Fast/BonusRAM priority to 10. Higher numbers mean higher priority for memory allocation.
|
||||
|
||||
**Priority explained:**
|
||||
- Higher priority memory gets used first by the system
|
||||
- Useful for controlling which memory gets allocated for different purposes
|
||||
- Default system behavior works well for most users
|
||||
|
||||
### Merging with Fast RAM
|
||||
|
||||
For optimal memory layout, you can merge BonusRAM with existing Fast RAM:
|
||||
|
||||
```
|
||||
addram -m
|
||||
```
|
||||
|
||||
**Benefits of merging:**
|
||||
- Creates one large contiguous Fast RAM block
|
||||
- More efficient memory management
|
||||
- Better for applications that need large memory allocations
|
||||
|
||||
**Note:** This is an advanced feature that modifies memory structures more extensively.
|
||||
|
||||
### Combined Advanced Usage
|
||||
|
||||
```
|
||||
addram -v -m -p 15
|
||||
```
|
||||
|
||||
This will:
|
||||
- Show verbose output
|
||||
- Merge BonusRAM with Fast RAM
|
||||
- Set priority to 15
|
||||
|
||||
## Understanding BonusRAM
|
||||
|
||||
### Memory Layout
|
||||
- **Address Range**: $A00000 to $BEFFFF (up to ~2MB)
|
||||
- **Type**: Fast RAM (32-bit, no wait states)
|
||||
- **Compatibility**: Works with all Amiga software that supports Fast RAM
|
||||
|
||||
### How It Works
|
||||
1. CIDER provides RAM in the $A00000-$BEFFFF address space
|
||||
2. For RAM-equipped addresses, it provides fast memory access
|
||||
3. This provides additional memory in previously unused address space
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Memory block already added"
|
||||
- BonusRAM is already active in your system
|
||||
- This is normal if you've already run ADDRAM
|
||||
- **Solution**: BonusRAM is working - no action needed
|
||||
|
||||
### "Board not found"
|
||||
- CIDER expansion board isn't detected
|
||||
- **Check**: Board is properly seated and connected
|
||||
- **Check**: Board firmware is up to date
|
||||
|
||||
### "No memory found"
|
||||
- CIDER board detected but no BonusRAM available
|
||||
- **Possible causes**:
|
||||
- Hardware fault with RAM
|
||||
|
||||
### "Detected more ram than should be in Bonus region"
|
||||
- Unusual memory configuration detected
|
||||
- **Solution**: Check your memory configuration and board installation
|
||||
|
||||
## Example Workflows
|
||||
|
||||
### First Time Setup
|
||||
```
|
||||
# 1. Check what's available (safe)
|
||||
addram -d -v
|
||||
|
||||
# 2. Add the memory
|
||||
addram -v
|
||||
|
||||
# 3. Verify in system (check with avail command)
|
||||
avail
|
||||
```
|
||||
|
||||
### Optimal Configuration
|
||||
```
|
||||
# Add BonusRAM merged with Fast RAM for best performance
|
||||
addram -v -m
|
||||
```
|
||||
|
||||
### Custom Priority Setup
|
||||
```
|
||||
# Set specific priority for memory management
|
||||
addram -v -p 20
|
||||
```
|
||||
|
||||
### Startup-Sequence Integration
|
||||
|
||||
To automatically add BonusRAM every time you boot, add this to your startup-sequence:
|
||||
|
||||
```
|
||||
; Add BonusRAM if available
|
||||
C:addram >NIL:
|
||||
```
|
||||
|
||||
Or for verbose output during boot:
|
||||
```
|
||||
; Add BonusRAM with status messages
|
||||
C:addram -v
|
||||
```
|
||||
|
||||
For optimal performance with automatic merging:
|
||||
```
|
||||
; Add BonusRAM merged with Fast RAM
|
||||
C:addram -m >NIL:
|
||||
```
|
||||
|
||||
**Startup-sequence tips:**
|
||||
- Place the addram command early in your startup-sequence
|
||||
- Use `>NIL:` to suppress output during normal boot
|
||||
- Remove `>NIL:` if you want to see status messages during boot
|
||||
|
||||
## Getting Help
|
||||
|
||||
If addram won't run or you get errors, try running it with help option:
|
||||
|
||||
```
|
||||
addram -h
|
||||
```
|
||||
|
||||
This shows all available options and their syntax.
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Memory Integration
|
||||
- BonusRAM is added as MEMF_FAST type memory
|
||||
- Can be merged with existing Fast RAM blocks for efficiency
|
||||
- Priority system ensures proper memory allocation order
|
||||
|
||||
## Command-line Options
|
||||
```
|
||||
Usage: addram [-d] [-v] [-p <Priority>] [-m] [-h]
|
||||
-d - Dry run (test without making changes)
|
||||
-v - Verbose output
|
||||
-p - Set Fast/BonusRAM priority
|
||||
-m - Merge BonusRAM with Fast RAM blocks
|
||||
-h - Show help
|
||||
```
|
||||
|
||||
## Final Tips
|
||||
|
||||
1. **Start with dry run**: Use `-d -v` first to see what will happen
|
||||
2. **Merge for performance**: Use `-m` for optimal memory layout
|
||||
3. **Default works well**: Basic `addram` is fine for most users
|
||||
4. **Check with avail**: Use the `avail` command to verify memory was added
|
||||
5. **Run once**: You typically only need to run ADDRAM once per boot
|
||||
|
||||
## License
|
||||
[](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
||||
|
||||
|
||||
addram is licensed under the GPL-2.0 only license
|
||||
@ -220,7 +220,7 @@ ULONG sizeBonusRam(struct Config *config) {
|
||||
* Poke the control register to enable Bonus RAM
|
||||
*/
|
||||
void enableBonusRam() {
|
||||
*ConfigRegister |= BONUSRAM_EN | SET_FLAG;
|
||||
*ConfigRegister = BONUSRAM_EN | SET_FLAG;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,7 +229,7 @@ void enableBonusRam() {
|
||||
* Poke the control register to disable Bonus RAM
|
||||
*/
|
||||
void disableBonusRam() {
|
||||
*ConfigRegister |= BONUSRAM_EN;
|
||||
*ConfigRegister = BONUSRAM_EN;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -32,8 +32,8 @@ struct ConfigDev* FindConfigDev(struct ConfigDev*, LONG, LONG);
|
||||
|
||||
// End fixes
|
||||
#define BOARDSTRING "GottaGoFast!!!\0"
|
||||
#define BOARD_MANUF 2011
|
||||
#define BOARD_PROD 74
|
||||
#define BOARD_MANUF 5194
|
||||
#define BOARD_PROD 6
|
||||
#define BONUSRAM_EN 1<<13
|
||||
#define SET_FLAG 1<<12
|
||||
|
||||
@ -47,4 +47,4 @@ void fixPriorities(char *, Config *);
|
||||
bool getArgs(int, char*[]);
|
||||
bool addBonusRam(ULONG, char*, struct Config*);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -1,10 +1,212 @@
|
||||
# BootROM
|
||||
# CIDER BootROM
|
||||
|
||||
A resident module that adds the BonusRAM ($A0000) to the system
|
||||
A resident module that automatically adds BonusRAM to your CIDER-equipped system at boot time.
|
||||
|
||||
This will automatically add the $A0000 RAM to your system's memory pool if Fast RAM is enabled
|
||||
## What is BootROM?
|
||||
|
||||
If the Left mouse-button is held at boot it will not run
|
||||
BootROM is a resident module (library) that automatically detects and adds your CIDER board's BonusRAM to the system memory pool during the boot process. Unlike the standalone `addram` tool, BootROM runs automatically every time you boot your system without requiring any user intervention.
|
||||
|
||||
## Usage
|
||||
Add to your extended rom using Remus or Romtool
|
||||
### Key Features
|
||||
- **Automatic operation**: Runs during system startup without user intervention
|
||||
- **Smart detection**: Only activates if CIDER board and BonusRAM are present
|
||||
- **Memory merging**: Attempts to merge BonusRAM with existing Fast RAM for optimal layout
|
||||
- **Safe fallback**: Creates separate memory block if merging isn't possible
|
||||
- **Boot bypass**: Hold left mouse button during boot to skip activation
|
||||
- **Legacy support**: Fixes memory priorities on Kickstart 1.x systems
|
||||
|
||||
## How It Works
|
||||
|
||||
BootROM integrates into the Amiga's boot process as a resident module:
|
||||
|
||||
1. **Detection**: Scans for CIDER board during system startup
|
||||
2. **Testing**: Safely tests available BonusRAM using non-destructive methods
|
||||
3. **Integration**: Adds memory to system pool, preferring to merge with existing Fast RAM
|
||||
4. **Optimization**: On older Kickstart versions, adjusts memory priorities for better performance
|
||||
|
||||
### Memory Layout
|
||||
- **Address Range**: $A00000 to $BEFFFF (up to ~2MB)
|
||||
- **Type**: Fast RAM (32-bit, no wait states)
|
||||
- **Integration**: Merged with existing Fast RAM when possible
|
||||
- **Compatibility**: Works with all Amiga software that supports Fast RAM
|
||||
|
||||
## Installation Methods
|
||||
|
||||
### Method 1: Extended ROM Integration (Recommended)
|
||||
|
||||
For permanent installation, integrate BootROM into your Extended ROM using tools like Remus or Romtool. The custom Extended ROM can then be easily programmed into your CIDER's flash memory using the cflash tool.
|
||||
|
||||
**Benefits:**
|
||||
- Automatic activation on every boot
|
||||
- No startup-sequence modification needed
|
||||
- Works even with minimal system configurations
|
||||
- Fastest activation (runs early in boot process)
|
||||
- Easy installation to flash memory with cflash
|
||||
|
||||
### Method 2: LoadModule Command
|
||||
|
||||
For temporary or testing purposes, you can load BootROM manually:
|
||||
|
||||
```
|
||||
loadmodule bootrom
|
||||
```
|
||||
|
||||
**Use cases:**
|
||||
- Testing before permanent installation
|
||||
- Temporary setups
|
||||
- Systems where you don't want to modify Extended ROM
|
||||
|
||||
### Method 3: Startup-Sequence Integration
|
||||
|
||||
Add to your startup-sequence for automatic loading:
|
||||
|
||||
```
|
||||
; Load CIDER BootROM support
|
||||
C:loadmodule DEVS:bootrom
|
||||
```
|
||||
|
||||
## User Control
|
||||
|
||||
### Bypassing BootROM
|
||||
|
||||
To prevent BootROM from activating (useful for troubleshooting):
|
||||
|
||||
1. **During boot**: Hold the **left mouse button** while the system starts
|
||||
2. **Keep holding** until the boot process completes
|
||||
3. **Result**: BootROM will detect the button press and skip activation
|
||||
|
||||
This is useful when:
|
||||
- Troubleshooting memory issues
|
||||
- Testing system without BonusRAM
|
||||
- Comparing performance with/without additional memory
|
||||
|
||||
### Verifying Operation
|
||||
|
||||
Check if BootROM successfully added memory:
|
||||
|
||||
```
|
||||
avail
|
||||
```
|
||||
|
||||
Look for:
|
||||
- Increased Fast RAM amount
|
||||
- Memory blocks labeled "GottaGoFast!"
|
||||
- Total available memory increase
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Resident Module Integration
|
||||
- **Priority**: Runs during cold start initialization
|
||||
- **Type**: NT_LIBRARY resident module
|
||||
- **Activation**: Automatic during system boot
|
||||
- **Dependencies**: Requires expansion.library
|
||||
|
||||
### Memory Testing Method
|
||||
BootROM uses safe, non-destructive memory testing:
|
||||
- Tests at offset +$B00 from each 64KB boundary
|
||||
- Avoids potential conflicts with system hardware
|
||||
- Uses address-based test patterns
|
||||
- Restores original values after testing
|
||||
|
||||
### Memory Integration Strategy
|
||||
1. **Preferred**: Merge with existing Fast RAM block for contiguous memory
|
||||
2. **Fallback**: Create separate BonusRAM memory block
|
||||
3. **Optimization**: Adjusts memory priorities on Kickstart 1.x systems
|
||||
|
||||
### Kickstart 1.x Enhancements
|
||||
On older Kickstart versions, BootROM provides additional optimizations:
|
||||
- Sets Ranger RAM priority to -5 for better allocation order
|
||||
- Ensures proper memory type flags are set
|
||||
- Improves overall memory management behavior
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### BootROM Not Running
|
||||
- **Check installation**: Verify BootROM is properly integrated into Extended ROM
|
||||
- **Check board**: Ensure CIDER board is properly installed and detected
|
||||
- **Mouse button**: Make sure you're not accidentally holding left mouse button during boot
|
||||
|
||||
### Memory Not Added
|
||||
- **No BonusRAM**: Board may not have RAM installed or RAM may be faulty
|
||||
- **Already active**: Memory may already be added by other means (addram tool, etc.)
|
||||
- **Board detection**: CIDER board may not be detected properly
|
||||
|
||||
### Verification
|
||||
Use these commands to check system status:
|
||||
```
|
||||
; Check available memory
|
||||
avail
|
||||
|
||||
; Check for CIDER board (if you have appropriate tools)
|
||||
showconfig
|
||||
|
||||
; Check memory layout
|
||||
showmem
|
||||
```
|
||||
|
||||
## Comparison with ADDRAM Tool
|
||||
|
||||
| Feature | BootROM | ADDRAM Tool |
|
||||
|---------|---------|-------------|
|
||||
| **Activation** | Automatic | Manual |
|
||||
| **Boot timing** | Early (resident) | Later (startup-sequence) |
|
||||
| **User control** | Mouse button bypass | Command line options |
|
||||
| **Installation** | Extended ROM | Startup-sequence |
|
||||
| **Flexibility** | Fixed behavior | Configurable options |
|
||||
| **Best for** | Set-and-forget | Testing and customization |
|
||||
|
||||
### When to Use Each
|
||||
|
||||
**Use BootROM when:**
|
||||
- You want automatic, hands-off operation
|
||||
- You have a stable system configuration
|
||||
- You want the earliest possible memory activation
|
||||
- You prefer ROM-based solutions
|
||||
|
||||
**Use ADDRAM tool when:**
|
||||
- You want control over memory configuration
|
||||
- You need verbose output for troubleshooting
|
||||
- You want to test different settings
|
||||
- You prefer startup-sequence based solutions
|
||||
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### Extended ROM Integration Workflow
|
||||
```
|
||||
# 1. Obtain bootrom module from CIDER-Software.lha
|
||||
# Download from: https://github.com/LIV2/CIDER-Software/releases/latest
|
||||
|
||||
# 2. Backup your current Extended ROM
|
||||
cp extended.rom extended.rom.backup
|
||||
|
||||
# 3. Add bootrom to Extended ROM using Remus/Romtool
|
||||
<use your preferred ROM tool to add bootrom to extended.rom>
|
||||
|
||||
# 4. Flash updated Extended ROM to your CIDER
|
||||
cflash -x extended.rom
|
||||
```
|
||||
|
||||
### Testing Before Permanent Installation
|
||||
```
|
||||
# 1. Test with loadmodule first
|
||||
loadmodule bootrom
|
||||
|
||||
# 2. Verify memory was added
|
||||
avail
|
||||
|
||||
# 3. If satisfied, integrate into Extended ROM using your preferred ROM tool
|
||||
```
|
||||
|
||||
## Final Tips
|
||||
|
||||
1. **Backup first**: Always backup your Extended ROM before modification
|
||||
2. **Test thoroughly**: Use loadmodule to test before permanent integration
|
||||
3. **Mouse bypass**: Remember the left mouse button bypass for troubleshooting
|
||||
4. **Check compatibility**: Verify with your specific system configuration
|
||||
5. **Monitor memory**: Use `avail` to confirm proper operation
|
||||
|
||||
## License
|
||||
[](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
||||
|
||||
|
||||
BootROM is licensed under the GPL-2.0 only license
|
||||
@ -26,9 +26,9 @@
|
||||
include libraries/configvars.i
|
||||
include hardware/cia.i
|
||||
|
||||
ManufId = 2011
|
||||
MemDevId = 72
|
||||
CtrlDevId = 74
|
||||
ManufId = 5194
|
||||
MemDevId = 4
|
||||
CtrlDevId = 6
|
||||
|
||||
BonusEna = $3000
|
||||
BonusBase = $A00000
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
PROJECT=cflash
|
||||
CC=m68k-amigaos-gcc
|
||||
CFLAGS=-lamiga -mcrt=nix13 -mcpu=68000 -Wall -Wno-pointer-sign -Os -fomit-frame-pointer
|
||||
CFLAGS=-lamiga -mcrt=nix13 -mcpu=68000 -Wall -Wno-pointer-sign -O3 -fomit-frame-pointer
|
||||
.PHONY: clean all
|
||||
all: $(PROJECT)
|
||||
|
||||
|
||||
238
cflash/README.md
238
cflash/README.md
@ -1,19 +1,247 @@
|
||||
# CFLASH
|
||||
|
||||
A tool to program the Kickstart and IDE Flash of the CIDER board.
|
||||
A tool to program the Kickstart and Extended ROM flash of the CIDER board for the Commodore CDTV.
|
||||
This tool allows you to program the flash in-system even while it is currently in use.
|
||||
|
||||
## What is CFLASH?
|
||||
|
||||
CFLASH is a tool that lets you update the firmware (ROM files) on your CIDER expansion board for the Commodore CDTV. It can update two types of firmware:
|
||||
|
||||
- **Kickstart ROM**: The main system firmware that boots your Amiga
|
||||
- **Extended ROM**: Additional firmware for CDTV functionality
|
||||
|
||||
## Before You Start
|
||||
|
||||
### Getting Started
|
||||
- CFLASH only programs the flash memory - it never touches your original system ROMs
|
||||
- Make sure your CDTV has stable power during flashing
|
||||
- **If you want to go back**: Simply switch off the kickflash DIP switch and reboot
|
||||
|
||||
### What You'll Need
|
||||
- Your CIDER-equipped CDTV
|
||||
- ROM files you want to flash (`.rom` files)
|
||||
- The cflash program (available in [CIDER-Software.adf](https://github.com/LIV2/CIDER-Software/releases/latest))
|
||||
- A CLI/terminal or Workbench to run commands
|
||||
|
||||
### Prerequisites
|
||||
- CIDER expansion board must be properly installed
|
||||
- ROM overlay should be switched off
|
||||
- Bonus RAM must be disabled during flashing
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### 1. Copy Your Current ROMs to Flash
|
||||
|
||||
To preserve what you currently have running:
|
||||
|
||||
## Usage
|
||||
```
|
||||
Usage: cflash [-iEvV] [-e k|x] [-c|-k <kickstart rom>] [-C|-x <extended rom>] [-I <ide rom>] -s [0|1]
|
||||
cflash -c -C
|
||||
```
|
||||
|
||||
This copies your current Kickstart and Extended ROMs from the system to flash.
|
||||
|
||||
### 2. Flash a New Kickstart ROM
|
||||
|
||||
To install a new Kickstart ROM file:
|
||||
|
||||
```
|
||||
cflash -k kick31.rom
|
||||
```
|
||||
|
||||
Replace `kick31.rom` with the actual filename of your Kickstart ROM.
|
||||
|
||||
**For dual Kickstart setups:**
|
||||
- Flash to slot 0 (default): `cflash -s 0 -k kick31.rom`
|
||||
- Flash to slot 1: `cflash -s 1 -k kick13.rom`
|
||||
|
||||
### 3. Flash an Extended ROM
|
||||
|
||||
To install a new Extended ROM file:
|
||||
|
||||
```
|
||||
cflash -x cdtv-ext.rom
|
||||
```
|
||||
|
||||
Replace `cdtv-ext.rom` with your Extended ROM filename.
|
||||
|
||||
### 4. Copy Current System ROMs to Flash
|
||||
|
||||
If you want to preserve your currently running ROMs to flash:
|
||||
|
||||
**Copy current Kickstart:**
|
||||
```
|
||||
cflash -c
|
||||
```
|
||||
|
||||
**Copy current Extended ROM:**
|
||||
```
|
||||
cflash -C
|
||||
```
|
||||
|
||||
**Copy both:**
|
||||
```
|
||||
cflash -c -C
|
||||
```
|
||||
|
||||
### 5. Verify Flash Contents
|
||||
|
||||
To check if your flash matches a ROM file:
|
||||
|
||||
```
|
||||
cflash -v -k kick31.rom
|
||||
```
|
||||
|
||||
To verify against currently running ROMs:
|
||||
```
|
||||
cflash -v -c -C
|
||||
```
|
||||
|
||||
### 6. Check Flash Device Information
|
||||
|
||||
To see what flash chip you have:
|
||||
|
||||
```
|
||||
cflash -i
|
||||
```
|
||||
|
||||
This displays the manufacturer and device ID of your flash chip.
|
||||
|
||||
## Advanced Operations
|
||||
|
||||
### Erasing Flash
|
||||
|
||||
**Erase Kickstart bank:**
|
||||
```
|
||||
cflash -e k
|
||||
```
|
||||
|
||||
**Erase Extended ROM bank:**
|
||||
```
|
||||
cflash -e x
|
||||
```
|
||||
|
||||
**Erase entire chip:**
|
||||
```
|
||||
cflash -E
|
||||
```
|
||||
|
||||
### Skip Verification
|
||||
|
||||
```
|
||||
cflash -V -k kick31.rom
|
||||
```
|
||||
|
||||
The `-V` flag skips verification after programming (not recommended).
|
||||
|
||||
## Understanding Slots
|
||||
|
||||
The CIDER has dual Kickstart slots, allowing you to have two different Kickstart ROMs:
|
||||
|
||||
- **Slot 0**: Default slot
|
||||
- **Slot 1**: Alternative slot
|
||||
|
||||
You can switch between them using CIDER's controls. Use `-s 0` or `-s 1` to specify which slot to program.
|
||||
|
||||
## ROM File Sizes
|
||||
|
||||
CFLASH supports these ROM sizes:
|
||||
|
||||
- **Kickstart**: 256KB, 512KB, or 1MB
|
||||
- **Extended ROM**: 256KB or 512KB
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Flash is enabled" Message
|
||||
If you see this message, cflash will automatically:
|
||||
1. Copy ROMs to RAM
|
||||
2. Switch to RAM mode
|
||||
3. Proceed with flashing
|
||||
|
||||
This is normal - just wait for it to complete.
|
||||
|
||||
### "Bonus RAM must be disabled"
|
||||
- Restart your system
|
||||
- Make sure Bonus RAM is not activated before running cflash
|
||||
|
||||
### "Unknown Flash device"
|
||||
- Check that your CIDER board is properly installed
|
||||
- Verify you're using compatible flash chips
|
||||
|
||||
### Verification Failed
|
||||
- Try flashing again
|
||||
- Check that your ROM file isn't corrupted
|
||||
- Ensure stable power during flashing
|
||||
|
||||
### Want to Use Original ROMs Again
|
||||
- Switch off the kickflash DIP switch on your CIDER board
|
||||
- Reboot your system (it will use the original ROMs)
|
||||
- Your original ROMs are always safe and untouched
|
||||
|
||||
## Example Workflows
|
||||
|
||||
### Upgrading to Kickstart 3.1
|
||||
```
|
||||
# 1. Copy current setup to flash (optional)
|
||||
cflash -c -C
|
||||
|
||||
# 2. Flash new Kickstart
|
||||
cflash -k kick31.rom
|
||||
|
||||
# 3. Verify it worked
|
||||
cflash -v -k kick31.rom
|
||||
```
|
||||
|
||||
### Setting up Dual Kickstart
|
||||
```
|
||||
# Flash Kickstart 3.1 to slot 0
|
||||
cflash -s 0 -k kick31.rom
|
||||
|
||||
# Flash Kickstart 1.3 to slot 1
|
||||
cflash -s 1 -k kick13.rom
|
||||
|
||||
# Now you can switch between them using CIDER controls
|
||||
```
|
||||
|
||||
### Complete ROM Update
|
||||
```
|
||||
# Update both ROM components
|
||||
cflash -k kick31.rom
|
||||
cflash -x cdtv-ext.rom
|
||||
```
|
||||
|
||||
## Getting Help
|
||||
|
||||
If cflash won't run or you get errors, try running it without parameters to see the usage information:
|
||||
|
||||
```
|
||||
cflash
|
||||
```
|
||||
|
||||
This will show you all available options and their syntax.
|
||||
|
||||
## Command-line options
|
||||
```
|
||||
Usage: cflash [-iEvV] [-e k|x] [-c|-k <kickstart rom>] [-C|-x <extended rom>] -s [0|1]
|
||||
-c - Copy ROM to Flash.
|
||||
-C - Copy Extended ROM to Flash.
|
||||
-k <kickstart file> - Kickstart to Flash or verify.
|
||||
-x <ext rom file> - Extended ROM to Flash or verify.
|
||||
-i - Print Flash device id.
|
||||
-I <ide rom> - Flash IDE ROM.
|
||||
-e [k|x] - Erase [k]ickstart or e[x]t rom bank.
|
||||
-E - Erase chip.
|
||||
-v - Verify bank against file or ROM
|
||||
-V - Skip verification after programming.
|
||||
-s [0|1] - Select kickstart slot to work on.
|
||||
```
|
||||
```
|
||||
|
||||
## Final Tips
|
||||
|
||||
1. **Start simple**: Begin with copying your current ROMs to flash
|
||||
2. **Keep ROM files**: Save copies of useful ROM files for future use
|
||||
3. **Easy recovery**: If something doesn't work, just switch off the kickflash DIP switch and reboot
|
||||
|
||||
## License
|
||||
[](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
||||
|
||||
|
||||
cflash is licensed under the GPL-2.0 only license
|
||||
BIN
cflash/cflash
BIN
cflash/cflash
Binary file not shown.
@ -27,4 +27,6 @@
|
||||
#define FLASH_BANK_0 0x000000
|
||||
#define FLASH_BANK_1 0x080000
|
||||
|
||||
#define KICK_BASE 0xF80000
|
||||
#define EXT_BASE 0xF00000
|
||||
#endif
|
||||
@ -26,6 +26,9 @@
|
||||
|
||||
ULONG ide_flashBase;
|
||||
|
||||
static inline void ide_flash_command(UBYTE);
|
||||
static inline void ide_flash_poll(UWORD);
|
||||
|
||||
/** ide_flash_writeByte
|
||||
*
|
||||
* @brief Write a byte to the Flash
|
||||
@ -37,7 +40,7 @@ void ide_flash_writeByte(UWORD address, UBYTE data) {
|
||||
address <<= 1;
|
||||
ide_flash_unlock_sdp();
|
||||
ide_flash_command(CMD_BYTE_PROGRAM);
|
||||
*(UBYTE *)(ide_flashBase + address) = data;
|
||||
*(volatile UBYTE *)(ide_flashBase + address) = data;
|
||||
ide_flash_poll(address);
|
||||
|
||||
return;
|
||||
@ -48,8 +51,8 @@ void ide_flash_writeByte(UWORD address, UBYTE data) {
|
||||
* @brief send a command to the Flash
|
||||
* @param command
|
||||
*/
|
||||
void ide_flash_command(UBYTE command) {
|
||||
*(UBYTE *)(ide_flashBase + ADDR_CMD_STEP_1) = command;
|
||||
static inline void ide_flash_command(UBYTE command) {
|
||||
*(volatile UBYTE *)(ide_flashBase + ADDR_CMD_STEP_1) = command;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -59,8 +62,8 @@ void ide_flash_command(UBYTE command) {
|
||||
* @brief Send the SDP command sequence
|
||||
*/
|
||||
void ide_flash_unlock_sdp() {
|
||||
*(UBYTE *)(ide_flashBase + ADDR_CMD_STEP_1) = CMD_SDP_STEP_1;
|
||||
*(UBYTE *)(ide_flashBase + ADDR_CMD_STEP_2) = CMD_SDP_STEP_2;
|
||||
*(volatile UBYTE *)(ide_flashBase + ADDR_CMD_STEP_1) = CMD_SDP_STEP_1;
|
||||
*(volatile UBYTE *)(ide_flashBase + ADDR_CMD_STEP_2) = CMD_SDP_STEP_2;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -83,7 +86,7 @@ void ide_flash_erase_chip() {
|
||||
* @brief Poll the status bits at address, until they indicate that the operation has completed.
|
||||
* @param address Address to poll
|
||||
*/
|
||||
void ide_flash_poll(UWORD address) {
|
||||
static inline void ide_flash_poll(UWORD address) {
|
||||
address &= (FLASH_SIZE-1);
|
||||
address <<= 1;
|
||||
volatile UBYTE *read1 = ((void *)ide_flashBase + address);
|
||||
@ -109,8 +112,8 @@ bool ide_flash_init(UBYTE *manuf, UBYTE *devid, ULONG *flashBase) {
|
||||
ide_flash_unlock_sdp();
|
||||
ide_flash_command(CMD_ID_ENTRY);
|
||||
|
||||
manufId = *(UBYTE *)ide_flashBase;
|
||||
deviceId = *(UBYTE *)(ide_flashBase + 2);
|
||||
manufId = *(volatile UBYTE *)ide_flashBase;
|
||||
deviceId = *(volatile UBYTE *)(ide_flashBase + 2);
|
||||
|
||||
ide_flash_command(CMD_CFI_ID_EXIT);
|
||||
|
||||
|
||||
@ -24,10 +24,8 @@
|
||||
|
||||
void ide_flash_unlock_sdp();
|
||||
void ide_flash_erase_chip();
|
||||
void ide_flash_command(UBYTE);
|
||||
void ide_flash_writeByte(UWORD, UBYTE);
|
||||
bool ide_flash_init(UBYTE *, UBYTE *, ULONG *);
|
||||
void ide_flash_poll(UWORD);
|
||||
void ide_flash_erase_block(UWORD);
|
||||
|
||||
#endif
|
||||
@ -32,6 +32,10 @@ enum {
|
||||
BOTTOM
|
||||
} flash_bootbank;
|
||||
|
||||
|
||||
static inline void kick_flash_poll(ULONG address);
|
||||
static inline void kick_flash_command(UWORD command);
|
||||
|
||||
/** kick_flash_writeWord
|
||||
*
|
||||
* @brief Write a word to the Flash
|
||||
@ -42,7 +46,7 @@ void kick_flash_writeWord(ULONG address, UWORD data) {
|
||||
address &= (FLASH_SIZE-1);
|
||||
kick_flash_unlock_sdp();
|
||||
kick_flash_command(CMD_WORD_PROGRAM);
|
||||
*(UWORD *)(flashbase + address) = data;
|
||||
*(volatile UWORD *)(flashbase + address) = data;
|
||||
kick_flash_poll(address);
|
||||
|
||||
return;
|
||||
@ -53,8 +57,8 @@ void kick_flash_writeWord(ULONG address, UWORD data) {
|
||||
* @brief send a command to the Flash
|
||||
* @param command
|
||||
*/
|
||||
void kick_flash_command(UWORD command) {
|
||||
*(UWORD *)(flashbase + ADDR_CMD_STEP_1) = command;
|
||||
static inline void kick_flash_command(UWORD command) {
|
||||
*(volatile UWORD *)(flashbase + ADDR_CMD_STEP_1) = command;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -64,8 +68,8 @@ void kick_flash_command(UWORD command) {
|
||||
* @brief Send the SDP command sequence
|
||||
*/
|
||||
void kick_flash_unlock_sdp() {
|
||||
*(UWORD *)(flashbase + ADDR_CMD_STEP_1) = CMD_SDP_STEP_1;
|
||||
*(UWORD *)(flashbase + ADDR_CMD_STEP_2) = CMD_SDP_STEP_2;
|
||||
*(volatile UWORD *)(flashbase + ADDR_CMD_STEP_1) = CMD_SDP_STEP_1;
|
||||
*(volatile UWORD *)(flashbase + ADDR_CMD_STEP_2) = CMD_SDP_STEP_2;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -88,7 +92,7 @@ void kick_flash_erase_chip() {
|
||||
* @brief Poll the status bits at address, until they indicate that the operation has completed.
|
||||
* @param address Address to poll
|
||||
*/
|
||||
void kick_flash_poll(ULONG address) {
|
||||
static inline void kick_flash_poll(ULONG address) {
|
||||
address &= (FLASH_SIZE-1);
|
||||
volatile UWORD *read1 = ((void *)flashbase + address);
|
||||
volatile UWORD *read2 = ((void *)flashbase + address);
|
||||
@ -110,8 +114,8 @@ bool kick_flash_init(UWORD *manuf, UWORD *devid) {
|
||||
kick_flash_unlock_sdp();
|
||||
kick_flash_command(CMD_ID_ENTRY);
|
||||
|
||||
manufId = *(UWORD *)flashbase;
|
||||
deviceId = *(UWORD *)(flashbase + 2);
|
||||
manufId = *(volatile UWORD *)flashbase;
|
||||
deviceId = *(volatile UWORD *)(flashbase + 2);
|
||||
|
||||
kick_flash_command(CMD_CFI_ID_EXIT);
|
||||
|
||||
@ -149,7 +153,7 @@ void kick_flash_erase_block(ULONG address) {
|
||||
kick_flash_unlock_sdp();
|
||||
kick_flash_command(CMD_ERASE);
|
||||
kick_flash_unlock_sdp();
|
||||
*(UWORD *)(flashbase + address) = CMD_ERASE_BLOCK;
|
||||
*(volatile UWORD *)(flashbase + address) = CMD_ERASE_BLOCK;
|
||||
|
||||
kick_flash_poll(address);
|
||||
}
|
||||
@ -171,7 +175,7 @@ void kick_flash_erase_bank(int bank) {
|
||||
}
|
||||
|
||||
// Erase the smaller blocks
|
||||
block += 32767;
|
||||
block += 32768;
|
||||
kick_flash_erase_block(block);
|
||||
block += 8192;
|
||||
kick_flash_erase_block(block);
|
||||
@ -198,4 +202,38 @@ void kick_flash_erase_bank(int bank) {
|
||||
kick_flash_erase_block(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** kick_flash_unlock_bypass
|
||||
*
|
||||
* @brief Sends UNLOCK BYPASS command to flash
|
||||
*/
|
||||
void kick_flash_unlock_bypass() {
|
||||
kick_flash_unlock_sdp();
|
||||
kick_flash_command(CMD_UNLOCK_BYPASS);
|
||||
}
|
||||
|
||||
/** kick_flash_unlock_bypass_reset
|
||||
*
|
||||
* @brief Sends UNLOCK BYPASS RESET command to flash returning it to read mode
|
||||
*/
|
||||
void kick_flash_unlock_bypass_reset() {
|
||||
kick_flash_unlock_sdp();
|
||||
kick_flash_command(CMD_UNLOCK_BYPASS_RESET);
|
||||
*(volatile UWORD *)(flashbase) = 0;
|
||||
}
|
||||
|
||||
/** kick_flash_bypass_program
|
||||
*
|
||||
* @brief Write a word to the Flash when in bypass mode
|
||||
* @param address Address to write to
|
||||
* @param data The word to write
|
||||
*/
|
||||
void kick_flash_bypass_program(ULONG address, UWORD data) {
|
||||
address &= (FLASH_SIZE-1);
|
||||
kick_flash_command(CMD_UNLOCK_BYPASS_PROGRAM);
|
||||
*(volatile UWORD *)(flashbase + address) = data;
|
||||
kick_flash_poll(address);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -24,12 +24,13 @@
|
||||
|
||||
void kick_flash_unlock_sdp();
|
||||
void kick_flash_erase_chip();
|
||||
void kick_flash_command(UWORD);
|
||||
void kick_flash_writeWord(ULONG, UWORD);
|
||||
bool kick_flash_init(UWORD *, UWORD *);
|
||||
void kick_flash_poll(ULONG);
|
||||
void kick_flash_reset();
|
||||
void kick_flash_erase_bank(int);
|
||||
void kick_flash_erase_block(ULONG);
|
||||
void kick_flash_unlock_bypass();
|
||||
void kick_flash_unlock_bypass_reset();
|
||||
void kick_flash_bypass_program(ULONG address, UWORD data);
|
||||
|
||||
#endif
|
||||
@ -34,15 +34,18 @@
|
||||
#define ADDR_CMD_STEP_1 (0x555 << 1)
|
||||
#define ADDR_CMD_STEP_2 (0x2AA << 1)
|
||||
|
||||
#define CMD_SDP_STEP_1 0xAA
|
||||
#define CMD_SDP_STEP_2 0x55
|
||||
#define CMD_WORD_PROGRAM 0xA0
|
||||
#define CMD_ERASE 0x80
|
||||
#define CMD_ERASE_BLOCK 0x30
|
||||
#define CMD_ERASE_CHIP 0x10
|
||||
#define CMD_ID_ENTRY 0x90
|
||||
#define CMD_CFI_ENTRY 0x98
|
||||
#define CMD_CFI_ID_EXIT 0xF0
|
||||
#define CMD_READ_RESET 0xF0
|
||||
#define CMD_SDP_STEP_1 0xAA
|
||||
#define CMD_SDP_STEP_2 0x55
|
||||
#define CMD_WORD_PROGRAM 0xA0
|
||||
#define CMD_ERASE 0x80
|
||||
#define CMD_ERASE_BLOCK 0x30
|
||||
#define CMD_ERASE_CHIP 0x10
|
||||
#define CMD_ID_ENTRY 0x90
|
||||
#define CMD_CFI_ENTRY 0x98
|
||||
#define CMD_CFI_ID_EXIT 0xF0
|
||||
#define CMD_READ_RESET 0xF0
|
||||
#define CMD_UNLOCK_BYPASS 0x20
|
||||
#define CMD_UNLOCK_BYPASS_PROGRAM 0xA0
|
||||
#define CMD_UNLOCK_BYPASS_RESET 0x90
|
||||
|
||||
#endif
|
||||
@ -32,10 +32,10 @@
|
||||
#include "cider.h"
|
||||
#include "constants.h"
|
||||
|
||||
#define MANUF_ID 2011
|
||||
#define PROD_ID 74
|
||||
#define IDE_MANUF_ID 0x082C
|
||||
#define IDE_PROD_ID 6
|
||||
#define MANUF_ID 5194
|
||||
#define PROD_ID 6
|
||||
#define IDE_MANUF_ID 5194
|
||||
#define IDE_PROD_ID 5
|
||||
#define IDE_ROM_OFFSET 0x0
|
||||
|
||||
#define CFLASH_VER 1
|
||||
@ -44,7 +44,7 @@ struct Library *DosBase;
|
||||
struct ExecBase *SysBase;
|
||||
struct ExpansionBase *ExpansionBase = NULL;
|
||||
|
||||
UWORD *controlRegister;
|
||||
volatile UWORD *controlRegister;
|
||||
|
||||
extern void *flashbase;
|
||||
|
||||
@ -63,6 +63,8 @@ int main(int argc, char *argv[])
|
||||
printf("CIDER FlashROM tool\n");
|
||||
|
||||
struct Config *config;
|
||||
struct Task *task = FindTask(0);
|
||||
SetTaskPri(task,20);
|
||||
if ((config = configure(argc,argv)) != NULL) {
|
||||
if ((ExpansionBase = (struct ExpansionBase *)OpenLibrary("expansion.library",0)) != NULL) {
|
||||
|
||||
@ -74,7 +76,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (hw_ver > CFLASH_VER) {
|
||||
printf("A newer version of cflash is needed for this CIDER firmware version.\n");
|
||||
rc = 0;
|
||||
rc = 5;
|
||||
goto exit;
|
||||
} else if (hw_ver < CFLASH_VER) {
|
||||
printf("The CIDER firmware must be upgraded to be compatible with this version of cflash\n");
|
||||
@ -90,7 +92,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (*controlRegister & FLASHEN_BIT) {
|
||||
printf("Flash is enabled, copying ROM to RAM and disabling Flash\n");
|
||||
CopyMemQuick((ULONG *)0xF00000,(ULONG *)0xF00000,1024*1024); // Copy Extended and Kick rom to RAM
|
||||
CopyMem((ULONG *)0xF00000,(ULONG *)0xF00000,1024*1024); // Copy Extended and Kick rom to RAM
|
||||
printf("Switching to RAM now, good luck!\n");
|
||||
*controlRegister = (CTRL_SET | MAPRAMEN_BIT);
|
||||
}
|
||||
@ -107,6 +109,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
printf("Error: Unknown Flash device Manufacturer: %04X Device: %04X\n", manufacturerId, deviceId);
|
||||
printf("Check that ROM overlay is switched off and try again.\n");
|
||||
rc = 5;
|
||||
|
||||
} else {
|
||||
|
||||
@ -119,14 +122,14 @@ int main(int argc, char *argv[])
|
||||
case OP_VERIFY:
|
||||
// Verify Kickstart
|
||||
if (config->kick_source == SOURCE_ROM) {
|
||||
rc = (verifyBank((ULONG *)0xF80000,FLASH_BANK_1,ROM_512K)) ? 0 : 5;
|
||||
rc = (verifyBank((ULONG *)KICK_BASE,FLASH_BANK_1,ROM_512K)) ? 0 : 5;
|
||||
} else if (config->kick_source == SOURCE_FILE) {
|
||||
rc = (verifyFile(config->ks_filename,FLASH_BANK_1)) ? 0 : 5;
|
||||
}
|
||||
|
||||
// Verify Extended ROM
|
||||
if (config->ext_source == SOURCE_ROM) {
|
||||
rc = (verifyBank((ULONG *)0xF00000,FLASH_BANK_0,ROM_256K)) ? 0 : 5;
|
||||
rc = (verifyBank((ULONG *)EXT_BASE,FLASH_BANK_0,ROM_256K)) ? 0 : 5;
|
||||
} else if (config->ext_source == SOURCE_FILE) {
|
||||
rc = (verifyFile(config->ext_filename,FLASH_BANK_0)) ? 0 : 5;
|
||||
}
|
||||
@ -145,18 +148,27 @@ int main(int argc, char *argv[])
|
||||
if (config->kick_source == SOURCE_ROM) {
|
||||
erase_bank(FLASH_BANK_1,config->programSlot);
|
||||
printf("Copying Kickstart ROM\n");
|
||||
copyBufToFlash((void *)0xF80000,FLASH_BANK_1,ROM_512K,config->skipVerify);
|
||||
if (copyBufToFlash((void *)KICK_BASE,FLASH_BANK_1,ROM_512K,config->skipVerify) == false) {
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
} else if (config->kick_source == SOURCE_FILE) {
|
||||
ULONG romSize = 0;
|
||||
printf("Flashing kick file %s\n",config->ks_filename);
|
||||
if ((romSize = getFileSize(config->ks_filename)) != 0) {
|
||||
if (romSize == ROM_256K || romSize == ROM_512K ) {
|
||||
erase_bank(FLASH_BANK_1,config->programSlot);
|
||||
copyFileToFlash(config->ks_filename,FLASH_BANK_1,romSize,config->skipVerify);
|
||||
if (copyFileToFlash(config->ks_filename,FLASH_BANK_1,romSize,config->skipVerify) == false) {
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
} else if (romSize == ROM_1M) {
|
||||
erase_bank(FLASH_BANK_0,config->programSlot);
|
||||
erase_bank(FLASH_BANK_1,config->programSlot);
|
||||
copyFileToFlash(config->ks_filename,FLASH_BANK_0,romSize,config->skipVerify);
|
||||
if (copyFileToFlash(config->ks_filename,FLASH_BANK_0,romSize,config->skipVerify) == false) {
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
printf("Bad file size, 256K/512K/1M ROM required.\n");
|
||||
rc = 5;
|
||||
@ -165,16 +177,27 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
// Ext ROM flash
|
||||
if (config->ext_source == SOURCE_ROM) {
|
||||
if (*((UWORD *)EXT_BASE + 1) != 0x4EF9) {
|
||||
printf("Extended ROM not found - Check that JP15 is connected and that both A500 mode and Kick Flash are disabled.\n");
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
erase_bank(FLASH_BANK_0,config->programSlot);
|
||||
printf("Copying Extended ROM\n");
|
||||
copyBufToFlash((void *)0xF00000,FLASH_BANK_0,ROM_256K,config->skipVerify);
|
||||
if (copyBufToFlash((ULONG *)EXT_BASE,FLASH_BANK_0,ROM_256K,config->skipVerify) == false) {
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
} else if (config->ext_source == SOURCE_FILE) {
|
||||
ULONG romSize = 0;
|
||||
printf("Flashing ext file %s\n",config->ext_filename);
|
||||
if ((romSize = getFileSize(config->ext_filename)) != 0) {
|
||||
if (romSize == ROM_256K || romSize == ROM_512K ) {
|
||||
erase_bank(FLASH_BANK_0,config->programSlot);
|
||||
copyFileToFlash(config->ext_filename,FLASH_BANK_0,romSize,config->skipVerify);
|
||||
if (copyFileToFlash(config->ext_filename,FLASH_BANK_0,romSize,config->skipVerify) == false) {
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
printf("Bad file size, 256K/512K EXT ROM required.\n");
|
||||
rc = 5;
|
||||
@ -202,12 +225,20 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (config->flash_ide_rom == true) {
|
||||
|
||||
void *ide_flashbase = NULL;
|
||||
struct ConfigDev *ide_configDev;
|
||||
if ((ide_configDev = FindConfigDev(NULL,IDE_MANUF_ID,IDE_PROD_ID))) {
|
||||
|
||||
ide_flashbase = ide_configDev->cd_BoardAddr;
|
||||
|
||||
if (ide_configDev->cd_BoardSize > 65536) {
|
||||
// Newer version of the CIDER firmware give the IDE device a 128K block, with the top 64K dedicated to the Flash
|
||||
// This means we can flash the IDE ROM without having to disable IDE
|
||||
ide_flashbase += 65536;
|
||||
}
|
||||
|
||||
UBYTE manufId,devId;
|
||||
if (ide_flash_init(&manufId,&devId,ide_configDev->cd_BoardAddr)) {
|
||||
if (ide_flash_init(&manufId,&devId,(ULONG *)ide_flashbase)) {
|
||||
|
||||
ULONG romSize = getFileSize(config->ide_rom_filename);
|
||||
if (romSize <= (0x10000 - IDE_ROM_OFFSET)/2) {
|
||||
@ -244,7 +275,7 @@ int main(int argc, char *argv[])
|
||||
fprintf(stdout,"\n");
|
||||
fflush(stdout);
|
||||
|
||||
fprintf(stdout,"Vefifying IDE ROM: ");
|
||||
fprintf(stdout,"Verifying IDE ROM: ");
|
||||
for (int i=0; i<romSize; i++) {
|
||||
|
||||
progress = (i*100)/(romSize-1);
|
||||
@ -255,10 +286,11 @@ int main(int argc, char *argv[])
|
||||
lastProgress = progress;
|
||||
}
|
||||
sourcePtr = ((void *)buffer + i);
|
||||
destPtr = ((void *)ide_configDev->cd_BoardAddr + (i << 1));
|
||||
destPtr = ((void *)ide_flashbase + (i << 1));
|
||||
if (*sourcePtr != *destPtr) {
|
||||
printf("\nVerification failed at %06x - Expected %02X but read %02X\n",(int)destPtr,*sourcePtr,*destPtr);
|
||||
return false;
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
}
|
||||
@ -271,14 +303,19 @@ int main(int argc, char *argv[])
|
||||
|
||||
} else {
|
||||
printf("File too large to fit IDE ROM\n");
|
||||
rc = 5;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("Error: IDE - Unknown Flash device Manufacturer: %02X Device: %02X\n", manufId, devId);
|
||||
printf("Check that IDE is switched off and try again.\n");
|
||||
if (ide_configDev->cd_BoardSize == 65535) {
|
||||
printf("Turn IDE off and try again.\n");
|
||||
}
|
||||
rc = 5;
|
||||
}
|
||||
} else {
|
||||
printf("Could not find IDE board.\n");
|
||||
rc = 5;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -399,15 +436,16 @@ APTR readFileToBuf(char *filename) {
|
||||
* @param romSize Size in bytes of the source
|
||||
* @param skipVerify Skip verification
|
||||
*/
|
||||
void copyFileToFlash(char *filename, ULONG destination, ULONG romSize, bool skipVerify) {
|
||||
bool copyFileToFlash(char *filename, ULONG destination, ULONG romSize, bool skipVerify) {
|
||||
APTR buffer;
|
||||
bool success = true;
|
||||
|
||||
if ((buffer = readFileToBuf(filename)) != NULL) {
|
||||
copyBufToFlash(buffer,destination,romSize,skipVerify);
|
||||
success = copyBufToFlash(buffer,destination,romSize,skipVerify);
|
||||
FreeMem(buffer,romSize);
|
||||
}
|
||||
|
||||
return;
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -419,7 +457,8 @@ void copyFileToFlash(char *filename, ULONG destination, ULONG romSize, bool skip
|
||||
* @param romSize Size in bytes of the source
|
||||
* @param skipVerify Skip verification
|
||||
*/
|
||||
void copyBufToFlash(ULONG *source, ULONG destination, ULONG romSize, bool skipVerify) {
|
||||
bool copyBufToFlash(ULONG *source, ULONG destination, ULONG romSize, bool skipVerify) {
|
||||
bool success = true;
|
||||
int progress = 0;
|
||||
int lastProgress = 1;
|
||||
|
||||
@ -429,6 +468,8 @@ void copyBufToFlash(ULONG *source, ULONG destination, ULONG romSize, bool skipVe
|
||||
|
||||
fprintf(stdout,"Writing: ");
|
||||
fflush(stdout);
|
||||
kick_flash_unlock_bypass(); // Enter unlock bypass mode
|
||||
|
||||
for (ULONG i=0; i<byteCount; i+=2) {
|
||||
sourcePtr = ((void *)source + (i % romSize)); // Loop the source address around when programming 256K
|
||||
progress = i*100/(byteCount-2);
|
||||
@ -439,13 +480,17 @@ void copyBufToFlash(ULONG *source, ULONG destination, ULONG romSize, bool skipVe
|
||||
lastProgress = progress;
|
||||
}
|
||||
|
||||
kick_flash_writeWord(destination+i,*sourcePtr);
|
||||
kick_flash_bypass_program(destination+i,*sourcePtr);
|
||||
|
||||
}
|
||||
|
||||
kick_flash_unlock_bypass_reset(); // Return to read mode
|
||||
printf("\n");
|
||||
if (skipVerify == false) {
|
||||
verifyBank(source,destination,romSize);
|
||||
success = verifyBank(source,destination,romSize);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/** verifyBank
|
||||
@ -535,4 +580,4 @@ void selectSlot(UBYTE slot) {
|
||||
} else {
|
||||
*controlRegister = CLR_BANKBIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,12 +24,12 @@
|
||||
struct ConfigDev* FindConfigDev(struct ConfigDev*, LONG, LONG);
|
||||
|
||||
ULONG getFileSize(char *);
|
||||
void copyFileToFlash(char *, ULONG, ULONG, bool);
|
||||
void copyBufToFlash(ULONG *, ULONG, ULONG, bool);
|
||||
bool copyFileToFlash(char *, ULONG, ULONG, bool);
|
||||
bool copyBufToFlash(ULONG *, ULONG, ULONG, bool);
|
||||
void erase_bank(ULONG,UBYTE);
|
||||
void erase_chip();
|
||||
bool verifyBank(ULONG *, ULONG, ULONG);
|
||||
bool verifyFile(char *, ULONG);
|
||||
APTR readFileToBuf(char *);
|
||||
void selectSlot(UBYTE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
8
iderom/.gitignore
vendored
8
iderom/.gitignore
vendored
@ -1,8 +0,0 @@
|
||||
obj/*
|
||||
at
|
||||
*.rom
|
||||
**/*.o
|
||||
**/*.out
|
||||
**/*.device
|
||||
**/*.hunk
|
||||
**/*.adf
|
||||
@ -1,48 +0,0 @@
|
||||
PROGRAM=cider-ide.rom
|
||||
INCLUDE=/opt/amiga/m68k-amigaos/ndk-include
|
||||
AS=vasmm68k_mot
|
||||
ASFLAGS=-Fhunk -I$(INCLUDE) -quiet -align
|
||||
LINKER=vlink
|
||||
LINKFLAGS=-brawbin1 -s -sc -sd -mrel -lamiga -lauto -L/opt/amiga/m68k-amigaos/vbcc/lib
|
||||
OBJDIR=obj
|
||||
|
||||
.PHONY: all clean rom ide_device/liv2ride.device disk
|
||||
|
||||
SRCS = bootldr.S \
|
||||
endrom.S
|
||||
OBJS = $(SRCS:%.S=$(OBJDIR)/%.o)
|
||||
|
||||
all: $(PROGRAM) disk
|
||||
|
||||
$(OBJDIR)/mungerom: mungerom.c
|
||||
@mkdir -p $(OBJDIR)
|
||||
$(CC) $< -Wall -o $@
|
||||
|
||||
$(OBJDIR)/%.o: %.S
|
||||
@mkdir -p $(OBJDIR)
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
$(OBJDIR)/bootldr: $(OBJDIR)/bootldr.o
|
||||
$(LINKER) $(LINKFLAGS) -o $@ $^
|
||||
|
||||
$(OBJDIR)/bootnibbles: $(OBJDIR)/bootldr $(OBJDIR)/mungerom
|
||||
@mkdir -p $(OBJDIR)
|
||||
./obj/mungerom
|
||||
|
||||
ide_device/liv2ride.device:
|
||||
$(MAKE) -C ide_device all
|
||||
|
||||
$(OBJDIR)/assets.o: assets.S $(OBJDIR)/bootnibbles ide_device/liv2ride.device
|
||||
|
||||
$(PROGRAM): $(OBJDIR)/bootnibbles $(OBJDIR)/assets.o
|
||||
$(LINKER) $(LINKFLAGS) -Trom.ld -o $@ $(OBJDIR)/assets.o
|
||||
|
||||
disk:
|
||||
$(MAKE) -C disk all
|
||||
|
||||
clean:
|
||||
$(MAKE) -C disk clean
|
||||
$(MAKE) -C ide_device clean
|
||||
rm -f $(OBJDIR)/*
|
||||
rm -f $(PROGRAM)
|
||||
rm -f mungerom
|
||||
@ -1,3 +0,0 @@
|
||||
## ide boot rom
|
||||
|
||||
WIP for the IDE driver
|
||||
@ -1,5 +0,0 @@
|
||||
section BOOTLDR
|
||||
incbin "obj/bootnibbles"
|
||||
|
||||
section DEVICE
|
||||
incbin "ide_device/liv2ride.device"
|
||||
173
iderom/bootldr.S
173
iderom/bootldr.S
@ -1,173 +0,0 @@
|
||||
; Based on rom.S from Open Source A4091.device by Stefan Reinauer & Chris Hooper
|
||||
include libraries/configvars.i
|
||||
include exec/resident.i
|
||||
include lvo/exec_lib.i
|
||||
|
||||
|
||||
VERSION = 1
|
||||
REVISION = 1
|
||||
DRIVEROFFSET = $2000
|
||||
dc.w $00
|
||||
******* DiagStart **************************************************
|
||||
DiagStart
|
||||
; This is the DiagArea structure whose relative offset from
|
||||
; your board base appears as the Init Diag vector in your
|
||||
; autoconfig ID information. This structure is designed
|
||||
; to use all relative pointers (no patching needed).
|
||||
dc.b DAC_NIBBLEWIDE+DAC_CONFIGTIME ; da_Config
|
||||
dc.b 0 ; da_Flags
|
||||
dc.w EndCopy-DiagStart ; da_Size
|
||||
dc.w DiagEntry-DiagStart ; da_DiagPoint
|
||||
dc.w BootEntry-DiagStart ; da_BootPoint
|
||||
dc.w DevName-DiagStart ; da_Name
|
||||
dc.w 0 ; da_Reserved01
|
||||
dc.w 0 ; da_Reserved02
|
||||
|
||||
|
||||
******* DiagEntry **************************************************
|
||||
**********************************************************************
|
||||
*
|
||||
* success = DiagEntry(BoardBase,DiagCopy, configDev)
|
||||
* d0 a0 a2 a3
|
||||
*
|
||||
* Called by expansion architecture to relocate any pointers
|
||||
* in the copied diagnostic area. We will patch the romtag.
|
||||
* If you have pre-coded your MakeDosNode packet, BootNode,
|
||||
* or device initialization structures, they would also need
|
||||
* to be within this copy area, and patched by this routine.
|
||||
*
|
||||
**********************************************************************
|
||||
* These are the calling conventions for the Diag routine
|
||||
*
|
||||
* A7 -- points to at least 2K of stack
|
||||
* A6 -- ExecBase
|
||||
* A5 -- ExpansionBase
|
||||
* A3 -- your board's ConfigDev structure
|
||||
* A2 -- Base of diag/init area that was copied
|
||||
* A0 -- Base of your board
|
||||
*
|
||||
* The Diag routine shall return a non-zero value in D0 for success.
|
||||
* If this value is NULL, then the diag/init area that was copied
|
||||
* will be returned to the free memory pool.
|
||||
*
|
||||
DiagEntry
|
||||
movem.l d2-d7/a2-a6,-(sp)
|
||||
|
||||
; Patch up Romtag Resident Structure in memory
|
||||
lea.l Romtag(pc),a4 ; find Romtag in memory
|
||||
move.l a4,RT_MATCHTAG(a4) ; pointer to itself
|
||||
lea.l EndCopy(pc),a1
|
||||
move.l a1,RT_ENDSKIP(a4)
|
||||
lea.l DevName(pc),a1
|
||||
move.l a1,RT_NAME(a4)
|
||||
move.l a1,RT_IDSTRING(a4)
|
||||
lea.l Init(pc),a1
|
||||
move.l a1,RT_INIT(a4)
|
||||
move.l a0,BoardBase-Romtag(a4) ; Save board base for later
|
||||
move.l a3,MyConfigDev-Romtag(a4) ; Save ConfigDev for later
|
||||
|
||||
movem.l (sp)+,d2-d7/a2-a6
|
||||
moveq.l #1,d0
|
||||
rts
|
||||
|
||||
******* BootEntry **************************************************
|
||||
**********************************************************************
|
||||
|
||||
BootEntry
|
||||
lea DosName(PC),a1 ; 'dos.library',0
|
||||
jsr _LVOFindResident(a6) ; find the DOS resident tag
|
||||
tst.l d0
|
||||
beq.s .BadBoot
|
||||
move.l d0,a0 ; in order to bootstrap
|
||||
move.l RT_INIT(A0),a0 ; set vector to DOS INIT
|
||||
jsr (a0) ; and initialize DOS
|
||||
.BadBoot
|
||||
rts
|
||||
|
||||
**********************************************************************
|
||||
* Chainloader
|
||||
* This module will:
|
||||
* - Load a driver from ROM.
|
||||
* - Initialize it
|
||||
* - Mount the drive(s)
|
||||
**********************************************************************
|
||||
Romtag
|
||||
dc.w RTC_MATCHWORD ; UWORD RT_MATCHWORD
|
||||
dc.l 0 ; APTR RT_MATCHTAG
|
||||
dc.l 0 ; APTR RT_ENDSKIP
|
||||
dc.b RTF_COLDSTART ; UBYTE RT_FLAGS
|
||||
dc.b VERSION ; UBYTE RT_VERSION
|
||||
dc.b 0 ; UBYTE RT_TYPE
|
||||
dc.b 0 ; BYTE RT_PRI
|
||||
dc.l 0 ; APTR RT_NAME
|
||||
dc.l 0 ; APTR RT_IDSTRING
|
||||
dc.l 0 ; APTR RT_INIT
|
||||
|
||||
BoardBase: dc.l 0
|
||||
MyConfigDev: dc.l 0
|
||||
|
||||
Init: movem.l d2-d7/a2-a6,-(sp)
|
||||
|
||||
move.l MyConfigDev(PC),a1
|
||||
move.w cd_Rom+er_InitDiagVec(a1),d1 ; Get rom offset
|
||||
ror.l #8,d1 ; Divide by 8 for Z2 Nibble-wide
|
||||
andi.l #1,d1
|
||||
move.l #DRIVEROFFSET,d0 ; Add to Driver offset
|
||||
add.l d1,d0
|
||||
|
||||
move.l BoardBase(PC),a0
|
||||
bsr _relocate
|
||||
tst.l d0
|
||||
bne.s .ok
|
||||
.err
|
||||
******* Show checkered purple failure screen **************************
|
||||
movem.l d2-d3,-(sp)
|
||||
move.w #$0020,d2
|
||||
.fc1
|
||||
move.w #$ffff,d3
|
||||
.fc2
|
||||
move.w #$0000,$dff180 ; black
|
||||
move.w #$0f0c,$dff180 ; purple
|
||||
dbra d3,.fc2
|
||||
dbra d2,.fc1
|
||||
movem.l (sp)+,d2-d3
|
||||
******* End checkered purple failure screen **************************
|
||||
|
||||
moveq.l #0,d0
|
||||
movem.l (sp)+,d2-d7/a2-a6
|
||||
rts
|
||||
|
||||
* Search for the driver Romtag
|
||||
*
|
||||
* Some drivers (Like OktaPus.device) have extra code in front of the Romtag structure so we will search a bit until we find it
|
||||
.ok
|
||||
move.l #$1000,d3 ; Search the first 4096 words for a Romtag
|
||||
move.l d0,a1
|
||||
.findrt cmpi.w #$4AFC,(a1)
|
||||
bne.s .not_rt
|
||||
cmp.l RT_MATCHTAG(a1),a1 ; Check that the RT_MATCHTAG is correct
|
||||
beq.s .found
|
||||
.not_rt addq.l #2,a1
|
||||
dbra d3,.findrt
|
||||
bra.s .err
|
||||
|
||||
* Found the driver, initialize it
|
||||
.found
|
||||
moveq.l #0,d1
|
||||
jsr _LVOInitResident(A6)
|
||||
.done
|
||||
moveq.l #0,d0 ; Report "failure" as the chainloader romtag is no longer needed
|
||||
movem.l (sp)+,d2-d7/a2-a6
|
||||
rts
|
||||
|
||||
******* Strings referenced in Diag Copy area **************************
|
||||
*************************************************************************
|
||||
DevName
|
||||
dc.b 'Chainloader',0 ; Name string
|
||||
align 1
|
||||
DosName
|
||||
dc.b 'dos.library',0 ; DOS library name
|
||||
align 1 ; word align
|
||||
|
||||
include reloc.S
|
||||
EndCopy:
|
||||
@ -1,7 +0,0 @@
|
||||
all: CIDER-IDE-Update.adf
|
||||
|
||||
CIDER-IDE-Update.adf: startup-sequence ../../cflash/cflash ../cider-ide.rom
|
||||
xdftool $@ format CIDER-IDE + boot install boot1x + makedir s + write startup-sequence s/startup-sequence + write ../../cflash/cflash cflash + write ../cider-ide.rom cider-ide.rom
|
||||
|
||||
clean:
|
||||
rm -rf *.adf
|
||||
@ -1 +0,0 @@
|
||||
cflash -I cider-ide.rom
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit 7f20d88417e478befc76eb0f459508bcdda836b0
|
||||
@ -1,33 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Chop up the bootrom section into nibbles for Z2 nibblewise bootrom - Kick 1.3 and below don't support DAC_BYTEWIDE :(
|
||||
// The device driver will be loaded bytewise by reloc
|
||||
int main () {
|
||||
FILE *fh = fopen("obj/bootldr","r");
|
||||
|
||||
char *src,*dst = NULL;
|
||||
|
||||
src = malloc(2048);
|
||||
dst = malloc(4096);
|
||||
|
||||
int len = fread(src,1,2048,fh);
|
||||
fclose(fh);
|
||||
for (int i=0; i<len;i++) {
|
||||
char hi = *(src+i) & 0xF0;
|
||||
char lo = *(src+i) & 0x0F;
|
||||
lo <<= 4;
|
||||
dst[i<<1] = hi;
|
||||
dst[(i<<1)+1] = lo;
|
||||
}
|
||||
|
||||
fh = fopen("obj/bootnibbles","w");
|
||||
|
||||
fwrite(dst,1,len*2,fh);
|
||||
|
||||
fclose(fh);
|
||||
|
||||
free(src);
|
||||
free(dst);
|
||||
}
|
||||
328
iderom/reloc.S
328
iderom/reloc.S
@ -1,328 +0,0 @@
|
||||
; reloc
|
||||
; Modified from Open Source A4091.device reloc.S by Stefan Reinauer & Chris Hooper
|
||||
INCLUDE "exec/memory.i"
|
||||
INCLUDE "lvo/exec_lib.i"
|
||||
|
||||
NUM_ENTRIES EQU 5
|
||||
|
||||
; API:
|
||||
; Z2 ROM access:
|
||||
; a0: rombase
|
||||
; d0: offset
|
||||
; Memory (RAM) access:
|
||||
; a0: pointer to binary
|
||||
; d0: 0
|
||||
public _relocate
|
||||
_relocate
|
||||
movem.l d1-d7/a0-a6,-(sp)
|
||||
|
||||
bsr InitHandle
|
||||
|
||||
; fetch file header
|
||||
bsr RomFetch32
|
||||
cmp.l #$3f3,d0 ; We only know hunk_hdr
|
||||
bne .RelocateFail
|
||||
|
||||
; consume the header and remember number of hunks
|
||||
bsr RomFetch32
|
||||
bsr RomFetch32
|
||||
move.l d0,d7 ; table size
|
||||
subq.l #1,d7
|
||||
move.l d7,d6 ; for HUNK_END
|
||||
bsr RomFetch32
|
||||
bsr RomFetch32
|
||||
|
||||
; Go through hunk header and allocate all segments
|
||||
move.l 4,a6 ; execbase
|
||||
|
||||
move.l pHunks(pc),a2 ; segment pointers
|
||||
lea.l 4*NUM_ENTRIES(a2),a3 ; segment lengths
|
||||
.AllocateLoop
|
||||
moveq.l #MEMF_PUBLIC,d1
|
||||
bsr RomFetch32
|
||||
lsl.l #2,d0
|
||||
move.l d0,(a3)+ ; segment length
|
||||
addq.l #8,d0 ; Add 8 for seglist overhead
|
||||
jsr _LVOAllocMem(a6)
|
||||
tst.l d0
|
||||
beq.s .RelocateFail
|
||||
addq.l #8,d0 ; Skip seglist overhead
|
||||
move.l d0,(a2)+ ; segment pointer
|
||||
dbra d7,.AllocateLoop
|
||||
|
||||
move.l pHunks(pc),a5
|
||||
.HunkLoop
|
||||
move.l (a5),a0 ; current hunk
|
||||
bsr RomFetch32
|
||||
|
||||
cmp.l #$3e9,d0
|
||||
beq .HunkCode
|
||||
cmp.l #$3ea,d0
|
||||
beq .HunkData
|
||||
cmp.l #$3eb,d0
|
||||
beq .HunkBSS
|
||||
cmp.l #$3ec,d0
|
||||
beq .HunkReloc32
|
||||
cmp.l #$3fc,d0
|
||||
beq .HunkReloc32Short
|
||||
cmp.l #$3f7,d0
|
||||
beq .HunkDRel32
|
||||
cmp.l #$3f0,d0
|
||||
beq .HunkSymbol
|
||||
cmp.l #$3f2,d0
|
||||
beq .HunkEnd
|
||||
|
||||
; We don't know this hunk
|
||||
.RelocateFail
|
||||
IFD HAVE_ERRNO
|
||||
; Save hunk number in rErrno as error code
|
||||
lea _rErrno(pc),a0
|
||||
move.l d0,(a0)
|
||||
ENDIF
|
||||
bsr .RelocateCleanup
|
||||
moveq.l #0,d0 ; NULL = Failure
|
||||
movem.l (sp)+,d1-d7/a0-a6
|
||||
rts
|
||||
|
||||
; ---------------------
|
||||
|
||||
.HunkData
|
||||
.HunkCode
|
||||
bsr RomFetch32
|
||||
move.l d0,d7
|
||||
subq.l #1,d7
|
||||
.CopyHunk
|
||||
bsr RomFetch32
|
||||
move.l d0,(a0)+
|
||||
dbra d7,.CopyHunk
|
||||
bra .HunkLoop
|
||||
|
||||
; ---------------------
|
||||
|
||||
.HunkBSS
|
||||
bsr RomFetch32
|
||||
move.l d0,d7
|
||||
subq.l #1,d7
|
||||
; hunk address in a0
|
||||
.ClearBSS
|
||||
move.l #$0,(a0)+
|
||||
dbra d7,.ClearBSS
|
||||
|
||||
bra .HunkLoop
|
||||
|
||||
; ---------------------
|
||||
|
||||
.HunkReloc32
|
||||
bsr RomFetch32
|
||||
|
||||
tst.l d0 ; if len is zero the reloc32 block is done
|
||||
beq .HunkLoop
|
||||
|
||||
move.l d0,d1 ; len ; number of offsets for a given hunk
|
||||
subq.l #1,d1 ; for dbra
|
||||
|
||||
bsr RomFetch32
|
||||
move.l d0,d2 ; num ; number of the hunk the offsets are to point into
|
||||
|
||||
lsl.l #2,d2 ; *4 ; offset from Hunks
|
||||
move.l pHunks(pc),a2
|
||||
add.l d2,a2 ; hunk number num
|
||||
move.l (a2),d3 ; base address of hunk
|
||||
|
||||
.Reloc32Tight
|
||||
bsr RomFetch32
|
||||
; get baseaddr + d0, add d3 to the data there.
|
||||
move.l a0,a4
|
||||
add.l d0,a4
|
||||
add.l d3,(a4)
|
||||
dbra d1,.Reloc32Tight
|
||||
|
||||
bra .HunkReloc32
|
||||
; ---------------------
|
||||
|
||||
.HunkDRel32
|
||||
.HunkReloc32Short
|
||||
bsr RomFetch16
|
||||
|
||||
tst.l d0 ; if len is zero the reloc32 block is done
|
||||
beq .HunkLoopPrep
|
||||
|
||||
move.l d0,d1 ; len ; number of offsets for a given hunk
|
||||
subq.l #1,d1 ; for dbra
|
||||
|
||||
bsr RomFetch16
|
||||
move.l d0,d2 ; num ; number of the hunk the offsets are to point into
|
||||
|
||||
lsl.l #2,d2 ; *4 ; offset from Hunks
|
||||
move.l pHunks(pc),a2
|
||||
add.l d2,a2 ; hunk number num
|
||||
move.l (a2),d3 ; base address of hunk
|
||||
|
||||
.Reloc32ShortTight
|
||||
bsr RomFetch16
|
||||
; get baseaddr + d0, add d3 to the data there.
|
||||
move.l a0,a4
|
||||
add.l d0,a4
|
||||
add.l d3,(a4)
|
||||
dbra d1,.Reloc32ShortTight
|
||||
|
||||
bra .HunkReloc32Short
|
||||
.HunkLoopPrep
|
||||
lea ReadHandle(pc),a2
|
||||
move.l (a2),d0 ; align pointer to longword
|
||||
addq.l #2,d0 ; in case we had an odd number
|
||||
and.l #$fffffffc,d0 ; of relocations
|
||||
move.l d0,(a2)
|
||||
bra .HunkLoop
|
||||
; ---------------------
|
||||
|
||||
.HunkSymbol
|
||||
bsr RomFetch32
|
||||
tst.l d0
|
||||
beq .HunkLoop
|
||||
move.l d0,d7
|
||||
.SkipSymbol
|
||||
bsr RomFetch32
|
||||
dbra d7,.SkipSymbol
|
||||
bra .HunkSymbol
|
||||
|
||||
; ---------------------
|
||||
|
||||
.HunkEnd
|
||||
addq.l #4,a5
|
||||
dbra d6,.HunkLoop
|
||||
IFD HAVE_ERRNO
|
||||
lea _rErrno(pc),a0
|
||||
move.l #0,(a0)
|
||||
ENDIF
|
||||
|
||||
bsr.s CreateSegList
|
||||
|
||||
move.l pHunks(pc),a0
|
||||
move.l (a0),d2
|
||||
subq.l #4,d2
|
||||
|
||||
bsr.s .RelocateCleanup
|
||||
move.l d2,d0
|
||||
movem.l (sp)+,d1-d7/a0-a6
|
||||
rts
|
||||
|
||||
.RelocateCleanup
|
||||
move.l pHunks(pc),a1
|
||||
moveq.l #(8*NUM_ENTRIES),d0
|
||||
jsr _LVOFreeMem(a6)
|
||||
rts
|
||||
|
||||
; ---------------------
|
||||
|
||||
; +--------------------+
|
||||
; | seg length (longs) | <-- = pHunks[x+NUM_ENTRIES]
|
||||
; +--------------------+ <-- seglist returned
|
||||
; | bptr to next seg | <-- = pHunks[x+1]
|
||||
; +--------------------+ <-- pHunks[x] points here
|
||||
; | segment data (also |
|
||||
; | first entry point) |
|
||||
; |/\/\/\/\/\/\/\/\/\/\|
|
||||
|
||||
; pHunks -+ Hunk Pointers Hunk Lengths
|
||||
; | +--+--+--+--+ +--+--+--+--+
|
||||
; +->| | | | 0| | | | | 0|
|
||||
; +--+--+--+--+ +--+--+--+--+
|
||||
CreateSegList:
|
||||
move.l pHunks(pc),a0
|
||||
|
||||
.NextSeg
|
||||
move.l (a0),a1 ; Hunks[x]
|
||||
|
||||
move.l 4*NUM_ENTRIES(a0),d0 ; length of current hunk
|
||||
addq.l #8,d0 ; add header size
|
||||
lsr.l #2,d0 ; MKBADDR
|
||||
move.l d0,-8(a1) ; write seg size
|
||||
|
||||
addq.l #4,a0
|
||||
move.l (a0),d0 ; next hunk
|
||||
tst.l d0 ; hunk addr zero?
|
||||
beq .SegListDone ; we're done
|
||||
subq.l #4,d0 ; else: point to linked list
|
||||
lsr.l #2,d0 ; MKBADDR
|
||||
move.l d0,-4(a1) ; write BPTR to next hunk
|
||||
|
||||
bra.s .NextSeg
|
||||
|
||||
.SegListDone
|
||||
move.l d0,-4(a1) ; terminate seglist
|
||||
rts
|
||||
|
||||
; ---------------------
|
||||
|
||||
; data = RomFetch32(void)
|
||||
; d0
|
||||
RomFetch16
|
||||
moveq #1,d0
|
||||
bra.s RomFetch
|
||||
RomFetch32
|
||||
moveq #3,d0
|
||||
|
||||
RomFetch
|
||||
movem.l a0-a1/d1-d3,-(sp)
|
||||
lea ReadHandle(pc),a1
|
||||
move.l (a1),a0
|
||||
|
||||
tst.l 4(a1) ; access type ZorroII?
|
||||
bne.s .RomFetchZ2
|
||||
|
||||
cmp.b #3,d0
|
||||
bne.b .RomFetchWord
|
||||
move.l (a0)+,d0 ; access type is memory
|
||||
bra.s .RomFetchDone
|
||||
.RomFetchWord
|
||||
move.w (a0)+,d0
|
||||
bra.s .RomFetchDone
|
||||
|
||||
.RomFetchZ2 ; access type is ZorroII
|
||||
move.l d0,d3
|
||||
.nextbyte
|
||||
lsl.l #8,d0
|
||||
move.b (a0),d0
|
||||
addq #2,a0
|
||||
dbra d3,.nextbyte
|
||||
|
||||
.RomFetchDone
|
||||
move.l a0,(a1)
|
||||
movem.l (sp)+,a0-a1/d1-d3
|
||||
rts
|
||||
|
||||
InitHandle
|
||||
; initialize readhandle to beginning of device driver
|
||||
; ROM_OFFSET needs to be multiplied by 4 because of the
|
||||
; nibble mapped nature of the AutoConfig ROM.
|
||||
; ROM_ADDRESS is passed in a0
|
||||
; ROM_OFFSET is passed in d0
|
||||
|
||||
;lsl.l #2,d0
|
||||
|
||||
add.l d0,a0
|
||||
lea ReadHandle(pc),a1
|
||||
move.l a0,(a1) ; memory location passed in a0
|
||||
move.l d0,4(a1) ; Set access type: 0 = memory, Z2 otherwise
|
||||
|
||||
moveq.l #(8*NUM_ENTRIES),d0
|
||||
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
|
||||
jsr _LVOAllocMem(a6)
|
||||
lea pHunks(pc),a1
|
||||
move.l d0,(a1)
|
||||
rts
|
||||
|
||||
ReadHandle
|
||||
dc.l 0 ; Current address
|
||||
dc.l 0 ; 0=memory, otherwise Z2
|
||||
|
||||
pHunks
|
||||
dc.l 0
|
||||
|
||||
IFD HAVE_ERRNO
|
||||
public _rErrno
|
||||
_rErrno
|
||||
dc.l 0
|
||||
ENDIF
|
||||
CODE
|
||||
@ -1,13 +0,0 @@
|
||||
SECTIONS {
|
||||
rom = .;
|
||||
.bootldr : {
|
||||
*(BOOTLDR)
|
||||
}
|
||||
.device 0x1000 : {
|
||||
*(DEVICE)
|
||||
}
|
||||
.fill : {
|
||||
FILL8(0xFF);
|
||||
RESERVE(0x8000-.);
|
||||
} =0xffff
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user