Struct rz80::Memory
[−]
[src]
pub struct Memory { pub heap: [u8; 131072], // some fields omitted }
memory access
The Memory object wraps access to the Z80's 64 KByte address space. All memory access goes through a page table with a page-size of 1 KByte. The page table mapping allows a very simple implementation of bank-switching, which was a popular way in 8-bit computers to manage more than 64 KBytes of memory.
Memory Layers
Mapped memory is assigned to 1 out of (currently) 4 layers. If 2 memory chunks are mapped to the same CPU address range on different layers, only the memory assigned to the higher-priority layer is visible to the CPU (layer number 0 has the highest priority and layer number 3 the lowest).
The layer concept is easier to visualize than to describe:
+---------------------------------------+
LAYER 3 |333333333333333333333333333333333333333|
+-------+---------------+---------------+
LAYER 2 |222222222222222|
+---------------+ +-------+
LAYER 1 |1111111|
+---------+ +-------+
LAYER 0 |000000000|
+---------+
+-------+-----+---------+-------+-------+
CPU VISIBLE: |3333333|22222|000000000|3333333|1111111|
+-------+-----+---------+-------+-------+
The Heap
The Memory class will never keep references to external memory, instead it comes with it's own few hundred KBytes of embedded memory which is used as 'heap'. A single memory page maps 1 KByte of memory from the Z80 address range to 1 KByte of memory somewhere on the embedded heap.
Mapping Memory
This 'maps' a chunk of memory in Z80 address range to a chunk of memory of the same size in the embedded heap on one of the four memory layers.
The simple form performs the memory mapping but does not copy any data into the mapped memory region:
use rz80::Memory; let mut mem = Memory::new(); // map 32 KByte at heap address 0x08000 to CPU addr 0x0000 // on layer 0 as writable: mem.map(0, 0x08000, 0x0000, true, 32*1024); // map another 32 KByte at heap address 0x10000 to CPU addr 0x8000 // on layer 1 as read-only: mem.map(1, 0x10000, 0x8000, false, 32*1024);
The method map_bytes() performs a memory mapping as above, but also copies a range of bytes into the mapped memory. This is useful to initialize the memory with a ROM dump.
use rz80::Memory; let mut mem = Memory::new(); let rom = [0xFFu8; 4096]; // assume that 'rom' is a system ROM dump, and map it as read-only to CPU address 0xF000 mem.map_bytes(0, 0x00000, 0xF000, false, &rom);
Reading and Writing Memory
(TODO!)
Fields
heap: [u8; 131072]
'host' memory
Methods
impl Memory
[src]
fn new() -> Memory
return new, unmapped memory object
fn new_64k() -> Memory
return new memory object with 64 kByte mapped, writable memory (for testing)
fn map(
&mut self,
layer: usize,
heap_offset: usize,
addr: usize,
writable: bool,
size: usize
)
&mut self,
layer: usize,
heap_offset: usize,
addr: usize,
writable: bool,
size: usize
)
map a chunk of uninitialized heap memory to CPU-mapped memory
fn map_bytes(
&mut self,
layer: usize,
heap_offset: usize,
addr: usize,
writable: bool,
content: &[u8]
)
&mut self,
layer: usize,
heap_offset: usize,
addr: usize,
writable: bool,
content: &[u8]
)
map a chunk of heap memory, and initialize it
fn unmap(&mut self, layer: usize, size: usize, addr: usize)
unmap a chunk heap memory
fn unmap_layer(&mut self, layer: usize)
unmap all pages in a layer
fn unmap_all(&mut self)
unmap all pages in all layers
fn r8(&self, addr: RegT) -> RegT
read unsigned byte from 16-bit address
fn rs8(&self, addr: RegT) -> RegT
read signed byte from 16-bit address
fn w8(&mut self, addr: RegT, val: RegT)
write unsigned byte to 16-bit address
fn w8f(&mut self, addr: RegT, val: RegT)
write unsigned byte, ignore write-protection flag
fn r16(&self, addr: RegT) -> RegT
read unsigned word from 16-bit address
fn w16(&mut self, addr: RegT, val: RegT)
write unsigned word to 16-bit address
fn write(&mut self, addr: RegT, data: &[u8])
write a whole chunk of memory, ignore write-protection