Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
memory_map [2021/08/25 18:34] – [Misc. peripherals] pulkomandy | memory_map [2021/09/05 16:02] – [External bus configuration] simer | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | {{: | ||
+ | |||
^ Start | ^ Start | ||
| 0x000000 | | 0x000000 | ||
Line 4: | Line 6: | ||
| 0x003000 | | 0x003000 | ||
| 0x003D00 | | 0x003D00 | ||
- | | 0x003e00 | + | | 0x003e00 |
External memory starts at 0x4000. It can be mapped to the internal ROM and the two possible chips in the cartridges. | External memory starts at 0x4000. It can be mapped to the internal ROM and the two possible chips in the cartridges. | ||
Line 11: | Line 13: | ||
====== IO registers ====== | ====== IO registers ====== | ||
+ | |||
+ | {{: | ||
^ Address | ^ Address | ||
Line 23: | Line 27: | ||
| 5/A/F | IOx mask | | | 5/A/F | IOx mask | | ||
- | IO special functions and usage: | + | Each IO port is configured by 4 registers. |
+ | |||
+ | The direction register is 0 for input pins, 1 for output pins. | ||
+ | |||
+ | ===== Input pins configuration ===== | ||
+ | |||
+ | If the attribute bit for a pin is 0, the data bit can be used to set a pull up or pull down resistor on the pin. | ||
+ | |||
+ | If the attribute bit is 1, the pin is floating without pull up or pull down. | ||
+ | |||
+ | It is possible to read both the internal buffer and the actual state of the pin. | ||
+ | |||
+ | ===== Output pins configuration ===== | ||
+ | |||
+ | If the attribute bit for a pin is 0, the output is inverted. Writing 1 to the data bit results in a logic 0 output. If the data bit is set to 0, the result is a logic 1 output. | ||
+ | |||
+ | If the attribute bit is 1, there is no inversion, and the data bit is output as is. | ||
+ | |||
+ | ===== IO special functions and usage ===== | ||
+ | |||
+ | FIXME this does not match the info from the V.Smile motion schematics (see [[IO]] page). Where does this info come from (except from bmx spreadsheet) and which is correct? | ||
* IOA15: act | * IOA15: act | ||
Line 48: | Line 72: | ||
* IOC0: TBPWM / external clock 2 input | * IOC0: TBPWM / external clock 2 input | ||
- | ===== Cartridge banks selection ===== | ||
- | These IO pins allow to map either the internal ROM or the two different cartridge banks into memory. | + | ====== Timers ====== |
- | * IOB2: CSB3 | + | {{:sunplus:sunplus_timer.png? |
- | * IOB1: CSB2 | + | |
- | * IOB0: CSB0 | + | |
- | + | ||
- | ====== Timers ====== | + | |
^ Address ^ Contents | ^ Address ^ Contents | ||
Line 78: | Line 97: | ||
- 11: TMB2 = 1024Hz, TMB1 = 64Hz | - 11: TMB2 = 1024Hz, TMB1 = 64Hz | ||
+ | ===== Timer A ===== | ||
+ | |||
+ | Timer A ticks on the rising edge of the AND of sources A and B (so one source can be used to mask the other). | ||
+ | |||
+ | The counter is incremented at each tick until it reaches FFFF and overflows. | ||
+ | |||
+ | Reading the data register allows to know the current timer value. | ||
+ | |||
+ | When the timer overflows, several things happen: | ||
+ | |||
+ | * An interrupt is triggered (if activated) | ||
+ | * The FTAOUT pin is toggled | ||
+ | * The counter is reloaded to the last value written to the data register | ||
+ | * The 4 bit counter for PWM generation is incremented | ||
+ | |||
+ | ==== Control register bits 2-0: Source A ==== | ||
+ | |||
+ | * 00x: Timer disabled | ||
+ | * 010: 32768Hz | ||
+ | * 011: 8192Hz | ||
+ | * 100: 4096Hz | ||
+ | * 101: 1 (use source B only) | ||
+ | * 110: Timer disabled | ||
+ | * 111: EXT1 | ||
+ | |||
+ | ==== Control register bits 5-3: Source B ==== | ||
+ | |||
+ | * 000: 2048Hz | ||
+ | * 001: 1024Hz | ||
+ | * 010: 256Hz | ||
+ | * 011: TMB1 | ||
+ | * 100: 4Hz | ||
+ | * 101: 2Hz | ||
+ | * 110: 1 (use source A only) | ||
+ | * 111: EXT2 | ||
+ | |||
+ | ==== Control register bits 9-6: output pulse control ==== | ||
+ | |||
+ | {{: | ||
+ | |||
+ | This configure the pulse width from 0 to 15 timer ticks. A new pulse starts every 16 ticks. | ||
====== Misc. peripherals ====== | ====== Misc. peripherals ====== | ||
Line 111: | Line 171: | ||
===== Interrupts ===== | ===== Interrupts ===== | ||
- | The three interrupt registers have the same layout | + | The three interrupt registers have the same layout: |
* Bit 13: ADC (interrupt vector is at FFFB) | * Bit 13: ADC (interrupt vector is at FFFB) | ||
Line 127: | Line 187: | ||
* Bit 0: TMB2 (FFFF) | * Bit 0: TMB2 (FFFF) | ||
+ | There are interrupts coming from devices, which have separate enable bits in each of the devices. | ||
+ | |||
+ | The complete list of interrupt vectors is: | ||
+ | |||
+ | ^ Vector address ^ Name ^Triggered by ^ | ||
+ | | FFF5 | BREAK |'' | ||
+ | | FFF6 | FIQ | ||
+ | | FFF7 | RESET |Console startup/ | ||
+ | | FFF8 | IRQ0 |PPU | | ||
+ | | FFF9 | IRQ1 |SPU | | ||
+ | | FFFA | IRQ2 |Timers A and B | | ||
+ | | FFFB | IRQ3 |UART, SPI, SIO, I2C | | ||
+ | | FFFC | IRQ4 |SPU beat and envelope | ||
+ | | FFFD | IRQ5 |External interrupts | ||
+ | | FFFE | IRQ6 |1024, 2048 or 4096Hz ticker | | ||
+ | | FFFF | IRQ7 |4Hz ticker, Timebase 1, Timebase 2, Low voltage detect, Key change | | ||
+ | |||
+ | As the vector addresses are only 16-bit, they can only point to the first segment (0x0000 - 0xFFFF). | ||
===== External bus configuration ===== | ===== External bus configuration ===== | ||
- | * Bits 11-8: Ram decode control | + | * Bits 11-8: External RAM decode control |
- | * Bits 7-6: Address | + | * 0xxx - No mapping |
- | * Bits 5-3: Bus arbitration control | + | * 1000 - Map '' |
+ | * 1001 - Map '' | ||
+ | * 1010 - Map '' | ||
+ | * 1011 - Map '' | ||
+ | * 1100 - Map '' | ||
+ | * 1101 - Map '' | ||
+ | * 1110 - Map '' | ||
+ | * 1111 - Map '' | ||
+ | * Bits 7-6: ROM address | ||
+ | * 00 - Map entire range to ROMCSB | ||
+ | * 01 - Map '' | ||
+ | * 1x - Map '' | ||
+ | * Bits 5-3: Bus arbitration | ||
+ | * 101 - 1. Audio, 2. PPU, 3. CPU | ||
+ | * 111 - 1. PPU, 2. Audio, 3. CPU | ||
* Bits 2-1: Number of wait states | * Bits 2-1: Number of wait states | ||
* Bit 0: CKOEN | * Bit 0: CKOEN | ||
+ | |||
+ | External RAM mapping overrides any ROM mapping. | ||
==== ADC ==== | ==== ADC ==== | ||
Line 184: | Line 278: | ||
====== UART ====== | ====== UART ====== | ||
- | 3D30 UART Control TxEn RxEn Mode MulPro 9th bit TxIntEn RxIntEn | + | {{: |
- | 3D31 UART Status rxbf txbusy bit9 overrun frame parity txrdy rxrdy | + | |
- | 3D32 UART Reset reset | + | All UART registers are 8bit only. |
- | 3D33 UART | + | |
- | 3D34 UART Baud Scalar Hi 57600: | + | ^ Address ^ Contents ^ |
- | 3D35 UART TxBUF uart_txbuf | + | | 3D30 | UART Control |
- | 3D36 UART RxBUF uart_rxbuf | + | | 3D31 | UART Status |
+ | | 3D32 | UART Reset (bit 0) | | ||
+ | | 3D33 | UART Baudrate setting (low byte) | | ||
+ | | 3D34 | UART Baudrate setting (high byte) | | ||
+ | | 3D35 | UART Tx buffer | ||
+ | | 3D36 | UART Rx buffer | ||
+ | |||
+ | Baudrate settings: | ||
+ | |||
+ | * 1200: FA 92 | ||
+ | * 2400: FD 41 | ||
+ | * 4800: FE A0 | ||
+ | * 9600: FF 50 | ||
+ | * 19200: | ||
+ | | ||
+ | * 115200: | ||
====== SPI ====== | ====== SPI ====== | ||
- | 3D40 SPI Control busy txempty rxfull SPH SPO SPIEN LPM TxIntEn RxIntEn | + | ^ Address ^ Contents ^ |
- | 3D41 SPI | + | | 3D40 | SPI Control |
- | 3D42 SPI | + | | 3D41 |
+ | | 3D42 | ||
====== General DMA ====== | ====== General DMA ====== | ||
- | 3E00 DMA | + | ^ Address ^ Contents ^ |
- | 3E01 DMA | + | | 3E00 |
- | 3E02 DMA | + | | 3E01 |
- | 3E03 DMA Target Address target address | + | | 3E02 | DMA word count | |
+ | | 3E03 | ||
+ | |||
+ | This is a DMA for generic purposes. Note that there is another DMA channel in the [[PPU]] registers. | ||
+ | |||
+ | Both DMA units operate in the same way. First, set the source and destination addresses. The source can be anywhere in memory, but the destination register is only 14 bits wide, which allows to target only the internal RAM and IO registers (you wouldn' | ||
+ | The transfer is started when you write the word count register, and you can read that register to know when the transfer is done (the register is 0 when there are no more words to transfer). |