Commander X16 ROM Flash Utility 1.0
This program flashes the ROM of the Commander X16 with a new ROM.BIN file.
cx16-rom-flash.c File Reference
#include <cx16.h>
#include <cx16-file.h>
#include <conio.h>
#include <printf.h>
#include <6502.h>
#include <kernal.h>
Include dependency graph for cx16-rom-flash.c:

Macros

#define __FLASH
 
#define ROM_BASE   ((unsigned int)0xC000)
 
#define ROM_SIZE   ((unsigned int)0x4000)
 
#define ROM_PTR_MASK   ((unsigned long)0x03FFF)
 
#define ROM_BANK_MASK   ((unsigned long)0x7C000)
 
#define SST39SF010A   ((unsigned char)0xB5)
 
#define SST39SF020A   ((unsigned char)0xB6)
 
#define SST39SF040   ((unsigned char)0xB7)
 

Functions

unsigned char rom_bank (unsigned long address)
 Calculates the 5 bit ROM bank from the ROM 19 bit address. The ROM bank number is calcuated by taking the upper 5 bits (bit 18-14) and shifing those 14 bits to the right. More...
 
brom_ptr_t rom_ptr (unsigned long address)
 Calcuates the 16 bit ROM pointer from the ROM using the 19 bit address. The 16 bit ROM pointer is calculated by masking the lower 14 bits (bit 13-0), and then adding $C000 to it. The 16 bit ROM pointer is returned as a char* (brom_ptr_t). More...
 
unsigned char rom_read_byte (unsigned long address)
 Read a byte from the ROM using the 19 bit address. The lower 14 bits of the 19 bit ROM address are transformed into the ptr_rom 16 bit ROM address. The higher 5 bits of the 19 bit ROM address are transformed into the bank_rom 5 bit bank number. bank_ptr* is used to set the bank using ZP $01. **ptr_rom is used to read the byte. More...
 
void rom_write_byte (unsigned long address, unsigned char value)
 Write a byte to the ROM using the 19 bit address. The lower 14 bits of the 19 bit ROM address are transformed into the ptr_rom 16 bit ROM address. The higher 5 bits of the 19 bit ROM address are transformed into the bank_rom 5 bit bank number. bank_ptr* is used to set the bank using ZP $01. **ptr_rom is used to write the byte into the ROM. More...
 
void rom_wait (brom_ptr_t ptr_rom)
 Wait for the required time to allow the chip to flash the byte into the ROM. This is a core wait routine which is the most important routine in this whole program. Once a byte is flashed into the ROM, it takes time for the chip to actually flash the byte. The chip has implemented a loop mechanism to guarantee correct flashing of the written byte. It does this by requiring the execution of two sequential reads from the previously written ROM address. And loop those sequential reads until bit 6 of the 2 read bytes are equal. Once those two bits are equal, the chip has successfully flashed the byte into the ROM. More...
 
void rom_unlock (unsigned long address, unsigned char unlock_code)
 Unlock a byte location for flashing using the 19 bit address. This is a various purpose routine to unlock the ROM for flashing a byte. The 3rd byte can be variable, depending on the write sequence used, so this byte is a parameter into the routine. More...
 
void rom_byte_program (unsigned long address, unsigned char value)
 Write a byte and wait until the byte has been successfully flashed into the ROM. More...
 
void rom_sector_erase (unsigned long address)
 Erases a 1KB sector of the ROM using the 19 bit address. This is required before any new bytes can be flashed into the ROM. Erasing a sector of the ROM requires an erase sector sequence to be initiated, which has the following steps: More...
 
void main ()
 

Macro Definition Documentation

◆ __FLASH

#define __FLASH

◆ ROM_BANK_MASK

#define ROM_BANK_MASK   ((unsigned long)0x7C000)

◆ ROM_BASE

#define ROM_BASE   ((unsigned int)0xC000)

◆ ROM_PTR_MASK

#define ROM_PTR_MASK   ((unsigned long)0x03FFF)

◆ ROM_SIZE

#define ROM_SIZE   ((unsigned int)0x4000)

◆ SST39SF010A

#define SST39SF010A   ((unsigned char)0xB5)

◆ SST39SF020A

#define SST39SF020A   ((unsigned char)0xB6)

◆ SST39SF040

#define SST39SF040   ((unsigned char)0xB7)

Function Documentation

◆ main()

void main ( )
Here is the call graph for this function:

◆ rom_bank()

unsigned char rom_bank ( unsigned long  address)

Calculates the 5 bit ROM bank from the ROM 19 bit address. The ROM bank number is calcuated by taking the upper 5 bits (bit 18-14) and shifing those 14 bits to the right.

Parameters
addressThe 19 bit ROM address.
Returns
unsigned char The ROM bank number for usage in ZP $01.
Here is the caller graph for this function:

◆ rom_byte_program()

void rom_byte_program ( unsigned long  address,
unsigned char  value 
)

Write a byte and wait until the byte has been successfully flashed into the ROM.

Parameters
addressThe 19 bit ROM address.
valueThe byte value to be written.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rom_ptr()

brom_ptr_t rom_ptr ( unsigned long  address)

Calcuates the 16 bit ROM pointer from the ROM using the 19 bit address. The 16 bit ROM pointer is calculated by masking the lower 14 bits (bit 13-0), and then adding $C000 to it. The 16 bit ROM pointer is returned as a char* (brom_ptr_t).

Parameters
addressThe 19 bit ROM address.
Returns
brom_ptr_t The 16 bit ROM pointer for the main CPU addressing.
Here is the caller graph for this function:

◆ rom_read_byte()

unsigned char rom_read_byte ( unsigned long  address)

Read a byte from the ROM using the 19 bit address. The lower 14 bits of the 19 bit ROM address are transformed into the ptr_rom 16 bit ROM address. The higher 5 bits of the 19 bit ROM address are transformed into the bank_rom 5 bit bank number. bank_ptr* is used to set the bank using ZP $01. **ptr_rom is used to read the byte.

Parameters
addressThe 19 bit ROM address.
Returns
unsigned char The byte read from the ROM.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rom_sector_erase()

void rom_sector_erase ( unsigned long  address)

Erases a 1KB sector of the ROM using the 19 bit address. This is required before any new bytes can be flashed into the ROM. Erasing a sector of the ROM requires an erase sector sequence to be initiated, which has the following steps:

  1. Write byte $AA into ROM address $005555.
  2. Write byte $55 into ROM address $002AAA.
  3. Write byte $80 into ROM address $005555.
  4. Write byte $AA into ROM address $005555.
  5. Write byte $55 into ROM address $002AAA.

Once this write sequence is finished, the ROM sector is erased by writing byte $30 into the 19 bit ROM sector address. Then it waits until the chip has correctly flashed the ROM erasure.

Note that a ROM sector is 1KB (not 4KB), so the most 7 significant bits (18-12) are used. The remainder 12 low bits are ignored.

                              +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  
                              | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
                              | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
                              +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  
 SECTOR              0x7F000  | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
                              +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  
 IGNORED             0x00FFF  | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
                              +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  
Parameters
addressThe 19 bit ROM address.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rom_unlock()

void rom_unlock ( unsigned long  address,
unsigned char  unlock_code 
)

Unlock a byte location for flashing using the 19 bit address. This is a various purpose routine to unlock the ROM for flashing a byte. The 3rd byte can be variable, depending on the write sequence used, so this byte is a parameter into the routine.

Parameters
addressThe 3rd write to model the specific unlock sequence.
unlock_codeThe 3rd write to model the specific unlock sequence.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rom_wait()

void rom_wait ( brom_ptr_t  ptr_rom)

Wait for the required time to allow the chip to flash the byte into the ROM. This is a core wait routine which is the most important routine in this whole program. Once a byte is flashed into the ROM, it takes time for the chip to actually flash the byte. The chip has implemented a loop mechanism to guarantee correct flashing of the written byte. It does this by requiring the execution of two sequential reads from the previously written ROM address. And loop those sequential reads until bit 6 of the 2 read bytes are equal. Once those two bits are equal, the chip has successfully flashed the byte into the ROM.

Parameters
ptr_romThe 16 bit pointer where the byte was written. This pointer is used for the sequence reads to verify bit 6.
Here is the caller graph for this function:

◆ rom_write_byte()

void rom_write_byte ( unsigned long  address,
unsigned char  value 
)

Write a byte to the ROM using the 19 bit address. The lower 14 bits of the 19 bit ROM address are transformed into the ptr_rom 16 bit ROM address. The higher 5 bits of the 19 bit ROM address are transformed into the bank_rom 5 bit bank number. bank_ptr* is used to set the bank using ZP $01. **ptr_rom is used to write the byte into the ROM.

Parameters
addressThe 19 bit ROM address.
valueThe byte value to be written.
Here is the call graph for this function:
Here is the caller graph for this function: