Memory-mapped Modules

Corvassembly allows the programmer to access peripherals through memory-mapped interfaces. Reading and writing to these modules is done in the same way as reading and writing to ram:

ldr a, UART
add a, 32
str a, UART

Each module has built-in variables so the programmer doesn’t need to memorize addresses.



A UART module with built-in 512 byte RX and TX FIFO buffering.

  • UART‎ (read) – read the current FIFO value and increment FIFO pointer

  • UART (write) – write to FIFO; data is sent as soon as the UART is not busy

  • UART_STATUS (read) – read the UART status


---- EFGH

(E) RX empty, (F) RX full, (G) TX empty, (H) TX full



Emulation of the 2A03’s audio processing unit. Variable names reflect the addresses for the original chip.

  • R4000 – Pulse 1 duty, control bits, and volume

  • R4001 – Pulse 1 sweep unit

  • R4002 – Pulse 1 timer LSB

  • R4003 – Pulse 1 length counter and timer MSbs

  • R4004 – Pulse 2 duty, control bits, and volume

  • R4005 – Pulse 2 sweep unit

  • R4006 – Pulse 2 timer LSB

  • R4007 – Pulse 2 length counter and timer MSbs

  • R4008 – Triangle control bits and linear counter

  • R400A – Triangle timer LSB

  • R400B – Triangle length counter and timer MSbs

  • R400C – Noise control bits and volume

  • R400E – Noise loop flag and period

  • R400F – Noise length counter

  • R4010 – DMC control bits and frequency

  • R4011 – DMC load counter

  • R4012 – DMC sample address

  • R4013 – DMC sample length

  • R4015 – APU status register

  • R9000 – VRC6 Pulse 1 control bit, duty, and volume

  • R9001 – VRC6 Pulse 1 timer LSB

  • R9002 – VRC6 Pulse 1 enable and timer MSbs

  • RA000 – VRC6 Pulse 2 control bit, duty, and volume

  • RA001 – VRC6 Pulse 2 timer LSB

  • RA002 – VRC6 Pulse 2 enable and timer MSbs

  • RB000 – VRC6 Saw accumulator rate

  • RB001 – VRC6 Saw timer LSB

  • RB002 – VRC6 Saw enable and timer MSbs

Detailed information about 2A03 and VRC6 register function can be found at the NesDev wiki.



A timer module that can produce interrupts at a fixed frequency.

  • TIMER_STATUS – one enables the module, zero disables it

  • TIMER_COMP – Timer compare register. When the timer accumulator reaches the value in TIMER_COMP, the timer accumulator is reset to zero and the TIMER interrupt is set.

  • TIMER_PRES – 8-bit timer prescalar register. Each clock, the prescalar register is decremented. When it reaches zero, the timer accumulator is incremented and the prescalar register is reset to the value of TIMER_PRES. A zero in TIMER_PRES means the accumulator will increment every clock.



A module that writes analog values to a 128-byte buffer at a specified frequency.

  • SCOPE_DATA‎ (write) – 16-bit register that determines sampling frequency. When the sample accumulator is decremented to zero, a new sample is loaded into the buffer and the accumulator is reset to the value of SCOPE_RATE.

  • SCOPE_DATA (read) – reads from the sample buffer. When read, the read address is incremented by one. When the address reaches the end of the buffer, it simply wraps.

  • SCOPE_TRIGGER (write) – writing a 1 to this register triggers sample collection. When the buffer is filled, sample collection stops. This prevents tearing.



A module that allows easy access and control of typical 8-pin flash memory chips used for FPGA configuration.

  • FLASH_DATA‎ (read) – Read from the FIFO buffer. This should be done after a read request is sent and the module is no longer busy.

  • FLASH_DATA (write) – Write to the FIFO buffer. This should be done before sending a write request.

  • FLASH_PAGE – Address of the page to be operated on (most significant 16 bits of 24).

  • FLASH_STATUS‎ (write) – Status register for the module. Read, write, and erase requests are handles through this register.

  • FLASH_STATUS (read) – Reading the status register returns only the busy and error bits



(S) Program security bit, (s) Configuration security bit,
(P) 256 or 512 (packed) transfer, (E) Erase request,
(W) Write request, (R) Read request, (e) error bit, (B) Busy bit

Read requests are safe anywhere within the Flash memory address space. Write and erase requests, however, are not necessarily safe in the areas where FPGA configuration and program data are stored. For these addresses, (page 0x05FF and below) the appropriate security bit must be set before a write or erase operation will occur. The configuration space ends at address 0x02FF, corresponding to the configuration security bit. The program space begins at 0x0300 and ends at 0x05FF, coresponding to the program security bit.

If an illegal operation is requested, the module exits the process and sets the error bit.

After any operation, security bits are reset. For every write and read to relevant addresses, they must be set before every transfer.

A read operation will read the entire page at address FLASH_PAGE. Therefore, it is recommended to read and write in 256-byte chunks.

The erase operation erases 4096 byte sectors, meaning that an erase only need be requested every 16 pages. Erase requests must occur on address multiples of 4096. If erase requests are not made on multiples of 4096, the module exits the operation and sets the error bit.


The page register controls the most significant 16 bits of the 24 bit flash address, meaning that 4096 byte intervals correspond to page intervals of 16.