Compare commits

...

24 Commits

Author SHA1 Message Date
e23e0adfe9 Update documentation 2025-09-21 14:47:49 +12:00
3183606d23 Remove ideupdate & point users to lide repo for IDE fw 2024-09-04 14:06:17 +12:00
be25d2dae1 GH Actions: Fixup workflow trigger 2023-08-14 10:39:14 +00:00
96c13103fa Update lide.device 2023-08-14 10:37:50 +00:00
1baa384a18 Update lide.device 2023-08-04 14:31:16 +00:00
1d174e6024 Move bootrom code to lide repo 2023-07-11 11:27:53 +00:00
ee663c106c CFLASH: Check that ext rom is there when copying 2023-07-10 09:02:53 +00:00
c7f43f60c6 CFLASH: Add more failure checks 2023-06-13 21:07:43 +00:00
d495ba8962 Switch to OAHR allocated Autoconfig IDs 2023-06-12 18:22:47 +00:00
0d5ee7f460 IDE ROM: liv2ride submodule renamed to lide and updated to current release 2023-06-09 20:57:05 +00:00
1dbb93e487 iderom: bump lide.device version 2023-05-16 02:13:49 +00:00
b14297ef66 cflash: fix control register
Pointer was not marked volatile, causing the bonus ram check to be optimized away
2023-05-16 02:13:16 +00:00
06314f04a6 addram: Fix enable/disablebonusram
Incorrectly used a read-modify-write op on the control register
2023-05-16 02:10:40 +00:00
1b9d4789b0 cflash: fixup erase block address for M29F160FT 2023-05-13 22:32:59 +00:00
118857bdf6 iderom: Rename liv2ride.device to lide.device and update submodule 2023-05-13 22:32:15 +00:00
7398c66189 iderom: fixup bootldr. needed to define ROM and BYTEWIDE in makefile 2023-05-06 17:47:32 +00:00
f17d232d7c Update reloc.S from upstream and integrate my changes with IF statements 2023-04-24 14:28:41 +00:00
2b389d1f91 Add notice for at_apollo_device transfer routines 2023-04-24 14:27:28 +00:00
83e0231039 Update READMEs 2023-04-23 19:11:23 +00:00
3c8e5aeabf cflash: implement ability to flash IDE even when enabled 2023-04-22 17:42:29 +00:00
dc1538b8c2 iderom: fixup AT-Bus offset stuff 2023-04-22 17:06:09 +00:00
6db2b712b3 iderom: tweaks
* Tweak driver offset stuff
* Add ability to build a rom for AT-Bus 2008 cards
2023-04-21 14:09:58 +00:00
618089c795 cflash speedup
Using the "UNLOCK BYPASS" commands for the flash it takes half as many cycles to program each word

Also bump the task priority and enable compiler optimization
2023-04-18 20:47:21 +00:00
b1fb7b8aaa cflash: replace CopyMemQuick call with CopyMem as it caused a guru 2023-04-18 16:05:29 +00:00
31 changed files with 894 additions and 719 deletions

View File

@ -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
View File

@ -1,3 +0,0 @@
[submodule "iderom/ide_device"]
path = iderom/ide_device
url = git@github.com:LIV2/liv2ride.device.git

View File

@ -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
View 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
[![License: GPL v2](https://img.shields.io/badge/License-GPL_v2-blue.svg)](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

View File

@ -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
[![License: GPL v2](https://img.shields.io/badge/License-GPL_v2-blue.svg)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
addram is licensed under the GPL-2.0 only license

View File

@ -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;
}
/**

View File

@ -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

View File

@ -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
[![License: GPL v2](https://img.shields.io/badge/License-GPL_v2-blue.svg)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
BootROM is licensed under the GPL-2.0 only license

View File

@ -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

View File

@ -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)

View File

@ -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
[![License: GPL v2](https://img.shields.io/badge/License-GPL_v2-blue.svg)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
cflash is licensed under the GPL-2.0 only license

Binary file not shown.

View File

@ -27,4 +27,6 @@
#define FLASH_BANK_0 0x000000
#define FLASH_BANK_1 0x080000
#define KICK_BASE 0xF80000
#define EXT_BASE 0xF00000
#endif

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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
View File

@ -1,8 +0,0 @@
obj/*
at
*.rom
**/*.o
**/*.out
**/*.device
**/*.hunk
**/*.adf

View File

@ -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

View File

@ -1,3 +0,0 @@
## ide boot rom
WIP for the IDE driver

View File

@ -1,5 +0,0 @@
section BOOTLDR
incbin "obj/bootnibbles"
section DEVICE
incbin "ide_device/liv2ride.device"

View File

@ -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:

View File

@ -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

View File

@ -1 +0,0 @@
cflash -I cider-ide.rom

@ -1 +0,0 @@
Subproject commit 7f20d88417e478befc76eb0f459508bcdda836b0

View File

@ -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);
}

View File

@ -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

View File

@ -1,13 +0,0 @@
SECTIONS {
rom = .;
.bootldr : {
*(BOOTLDR)
}
.device 0x1000 : {
*(DEVICE)
}
.fill : {
FILL8(0xFF);
RESERVE(0x8000-.);
} =0xffff
}