PC Engine Hardware : CPU
The HuC6280 is a 8-bit microprocessor similar to the popular 6502 and 65C02 CPU's. It contains a 65C02 core to which have been added several new instructions, and a few internal peripheral functions such as an interrupt controller, a MMU, a TIMER, a 8-bit parallel I/O port, and a PSG.
Memory Mapping :
The HuC6280 has a 64 KB logical address space and a 2 MB physical address space. To access this entire memory space, the HuC6280 uses a MMU (Memory Managment Unit) that splits the memory space in segment of 8 KB. The logical address space is splitted as follow :
| page 0 | $0000-$1FFF |
| page 1 | $2000-$3FFF |
| page 2 | $4000-$5FFF |
| page 3 | $6000-$7FFF |
| page 4 | $8000-$9FFF |
| page 5 | $A000-$BFFF |
| page 6 | $C000-$DFFF |
| page 7 | $E000-$FFFF |
Each logical 8 KB segment (or page) is associated to a 8-bit register (MPR0-7) that contains the index of the 8 KB segment (or bank) in physical memory to map in this page. Two special instructions are used to access these registers :
| TAMi, | transfer the content of the accumulator (A) into a
MPR register (0 - 7). |
| TMAi, | transfer a MPR register into the accumulator. |
Bank Map :
| ROM | |
| $F7 | battery backed RAM |
| $F8 | work RAM |
| $FF | hardware I/O page |
You are free to map banks anywhere into the 8 pages, but a sort of standard has been defined, all the games seem to use it, so it was used in all the MagicKit's tools too. Here's how banks are mapped by default :
| page 0 | bank $FF (I/O) |
| page 1 | bank $F8 (RAM) |
| page 2 | user definable |
| page 3 | |
| page 4 | |
| page 5 | |
| page 6 | |
| page 7 | bank $00 |
| Note : |
After a RESET bank $00 is automaticaly mapped into |
TIMER
The TIMER base frequency is 6.992 KHz.
| TIMER counter register | |||
$0C00 |
R/W |
(unused) | |
| 7-bit down counter | |||
| TIMER control register | |||
$0C01 |
/W |
(unused) | |
| start/stop bit (0 = off, 1 = on) | |||
An interrupt is raised when the counter generates a carry, in other words, when the counter is to be decremented and its value is zero.
Gamepad
| Gamepad I/O port | |||
$1000 |
/W |
(unused) | |
| gamepad CLR line | |||
| gamepad SEL line | $1000 |
R/ |
(unused) |
| country bit (1 = JPN, 0 = USA) | |||
| (unused) | |||
| gamepad 4-bit data | |||
Interrupts :
| Interrupt disable register | |||
$1402 |
R/W |
(unused) | |
| TIMER | |||
| IRQ1 (VDC) | |||
| IRQ2 (external int.) | |||
| 1 to disable an interrupt, 0 to enable it. | |||
| Interrupt status register | |||
$1403 |
R/ |
(unused) | |
| TIMER | |||
| IRQ1 (VDC) | |||
| IRQ2 (external int.) | |||
| Set to 1 when an interrupt is waiting. | |||
$1403 |
/W |
(unused) | |
| A write to this register will acknowledge the internal TIMER interrupt. | |||
| Don't forget to write to the status register at the end of the TIMER interrupt handler, otherwise you will get infinite interrupts. |
Interrupt vectors :
$FFF6 | IRQ2 (BRK and external int.) |
$FFF8 | IRQ1 (VDC) |
$FFFA | TIMER |
$FFFC | NMI |
$FFFE | RESET |