Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
memory_map [2021/08/25 21:49] – simer | memory_map [2024/07/01 11:27] (current) – ↷ Links adapted because of a move operation admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | {{: | ||
+ | |||
^ Start | ^ Start | ||
| 0x000000 | | 0x000000 | ||
| 0x002800 | | 0x002800 | ||
- | | 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. |
- | * IOA15: act | + | The direction register is 0 for input pins, 1 for output pins. |
- | * IOA14-0: 15 bit RGB | + | |
- | * IOA15: SCK | + | |
- | * IOA14: SDA | + | |
- | * IOA13: SWS | + | |
- | * IOA12: CKV | + | |
- | * IOA11: FM | + | |
- | * IOA10: FP | + | |
- | * IOA9: LP | + | |
- | * IOA8: CP | + | |
- | * IOA7-0: D7-0 | + | |
- | * IOC15: SPI clock | + | |
- | * IOC14: RX | + | |
- | * IOC13: TX | + | |
- | * IOC12: SPI SSB | + | |
- | * IOC11: TFT Clock | + | |
- | * IOC10: timebase | + | |
- | * IOC9: TAPWM | + | |
- | * IOC8: VSYNC | + | |
- | * IOC7: HSYNC | + | |
- | * IOC1: timebase 2 / external clock 1 input | + | |
- | * IOC0: TBPWM / external clock 2 input | + | |
- | ===== Cartridge banks selection | + | ===== Global configuration register |
- | These IO pins allow to map either | + | * Bit 0: IOA special functions select |
+ | * Bit 1: IOB special functions select | ||
+ | |||
+ | These two bits allow to select one of two special functions for the IOA and IOB registers. Then each pin in that IO register can be switched between normal GPIO and special function using the MASK register. | ||
+ | |||
+ | For IOA, special = 0 selects the TFT display interface, special = 1 selects the STN LCD interface and I2S audio output. | ||
+ | |||
+ | For IOB, only special = 0 is documented and it selects the CSB0, CSB1, CSB2 chip select | ||
+ | |||
+ | * Bit 2: IOA Wakeup enable | ||
+ | * Bit 3: IOB Wakeup enable | ||
+ | * Bit 4: IOC Wakeup enable | ||
+ | |||
+ | These bits enable system wakeup from sleep mode from activity on the corresponding IO ports. A typical setup on the V.Smile is to enable wakeup on port B to detect when the ON button is pressed. | ||
+ | ===== 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. | ||
- | * IOB2: CSB3 | ||
- | * IOB1: CSB2 | ||
- | * IOB0: CSB0 | ||
====== Timers ====== | ====== Timers ====== | ||
+ | |||
+ | {{: | ||
^ Address ^ Contents | ^ Address ^ Contents | ||
Line 71: | Line 79: | ||
| 3D1C | Scanline counter | | 3D1C | Scanline counter | ||
- | Timebase values: | + | Timebase |
+ | * Bits 3-2: TMB2 frequency | ||
+ | * 00 - 128 Hz | ||
+ | * 01 - 256 Hz | ||
+ | * 10 - 512 Hz | ||
+ | * 11 - 1024 Hz | ||
+ | * Bits 1-0: TMB1 frequency | ||
+ | * 00 - 8 Hz | ||
+ | * 01 - 16 Hz | ||
+ | * 10 - 32 Hz | ||
+ | * 11 - 64 Hz | ||
- | - 00: TMB2 = 128Hz, TMB1 = 8Hz | + | ===== Timer A ===== |
- | - 01: TMB2 = 256Hz, TMB1 = 16Hz | + | |
- | - 10: TMB2 = 512Hz, TMB1 = 32Hz | + | |
- | - 11: TMB2 = 1024Hz, TMB1 = 64Hz | + | |
+ | 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 95: | Line 149: | ||
| 3D2D | Pseudo Random2 | | 3D2D | Pseudo Random2 | ||
| 3D2E | FIQ Sel | | 3D2E | FIQ Sel | ||
- | | 3D2F | DS register | + | | 3D2F | DS register |
===== System control ===== | ===== System control ===== | ||
Line 111: | Line 165: | ||
===== 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 181: | ||
* 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. | ||
+ | |||
+ | On the V.Smile, both ROMCSB and CSB1 allow to access the cartridge ROM. This means bit 6 is not very useful. | ||
+ | |||
+ | CSB2 is the cartridge RAM, and CSB3 is the system ROM. They are both enabled at the same time by using bit 7. | ||
==== ADC ==== | ==== ADC ==== | ||
Line 183: | Line 275: | ||
This allows direct read and write access to the DS (Data Segment) register. Normally in the uN'SP architecture, | This allows direct read and write access to the DS (Data Segment) register. Normally in the uN'SP architecture, | ||
====== UART ====== | ====== UART ====== | ||
+ | |||
+ | {{: | ||
All UART registers are 8bit only. | All UART registers are 8bit only. | ||
Line 205: | Line 299: | ||
* 115200: FF F1 | * 115200: FF F1 | ||
+ | Before using the UART, the corresponding PINs need to be configured properly. IOC13 and IOC14 must be set to " | ||
+ | The example below also forces CTS A (IOC8) low, allowing the first controller port to transmit data. Normally this would only be done after receiving an RTS from said controller. | ||
+ | |||
+ | // Enable controller CTS | ||
+ | *PORTC_DIR = 0x89c0; | ||
+ | *PORTC_ATTR = 0x89c0; | ||
+ | *PORTC_DATA = 0xf77f; | ||
+ | |||
+ | // Enable Uart RX (controller input) | ||
+ | *UART_BAUDRATE_LOW = 0xA0; | ||
+ | *UART_BAUDRATE_HIGH = 0xFE; | ||
+ | *UART_CONTROL = 0xc3; | ||
+ | *UART_STATUS = 3; | ||
+ | |||
+ | *PORTC_SPECIAL |= 0x6000; // UART Tx and Rx in " | ||
+ | *PORTC_ATTR |= 0x6000; | ||
+ | *PORTC_DIR |= 0x4000; | ||
+ | |||
+ | Reading from the UART then is quite simple: | ||
+ | |||
+ | * Wait until the status register indicates Rx ready (bit 0) | ||
+ | * When Rx is ready, read the Rx data register to get the byte | ||
+ | |||
+ | For transmitting, | ||
====== SPI ====== | ====== SPI ====== | ||