You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Physical memory consists of three sections. Two are directly accessible by code: ROM (rx) and RAM (rwx). The third section is an instruction cache which is 4x less dense than main memory.
10
10
11
-
The instruction cache should be initialized at boot using the MLOGSYS instruction. It is also updated whenever an instruction writes to RAM that is covered by the icache. If executing from memory not covered by the icache, the processor manually fetches and decodes the instruction from main memory.
12
-
13
-
Code begins executing at address `0x00000000` (ie. the start of ROM).
11
+
For maximum performance, the instruction cache for ROM can be initialized at boot using the MLOGSYS instruction. It is also updated whenever an instruction writes to RAM that is covered by the icache. If executing from memory not covered by the icache, the processor manually fetches and decodes the instruction from main memory.
14
12
15
13
The main CPU code is generated from `src/main.mlog.jinja` using a custom Jinja-based preprocessor (`python/src/mlogv32/preprocessor`).
Code begins executing at address `0x00000000` (ie. the start of ROM).
32
+
33
+
Addresses `0xf0000000` - `0xffffffff` are reserved for system purposes such as MMIO.
34
+
35
+
### UART
36
+
37
+
Addresses `0xf0000010` and `0xf0000030` contain emulated UART 16550 peripherals based on [this datasheet](https://caro.su/msx/ocm_de1/16550.pdf). The UARTs support the following features:
38
+
39
+
- Configurable FIFO capacity (up to 254 bytes) for TX and RX, stored as a variable in the CONFIG processor.
40
+
- Theoretical maximum transfer rate of 121920 bits/sec (254 bytes/tick).
41
+
- Line Status Register flags: Transmitter Empty, THR Empty, Overrun Error, Data Ready.
42
+
43
+
The UART registers have a stride of 4 bytes to simplify some internal logic.
Each UART is implemented as two circular buffers in a memory bank with the following layout. Note that RX refers to data sent to / read by the processor, and TX refers to data sent from / written by the processor.
59
+
60
+
| Index | Name |
61
+
| ----- | ----------------------- |
62
+
| 0 | RX buffer start |
63
+
| 254 | RX buffer read pointer |
64
+
| 255 | RX buffer write pointer |
65
+
| 256 | TX buffer start |
66
+
| 510 | TX buffer read pointer |
67
+
| 511 | TX buffer write pointer |
68
+
69
+
Read/write pointers are stored modulo `2 * capacity` ([ref 1](https://github.com/hathach/tinyusb/blob/b203d9eaf7d76fd9fec71b4ee327805a80594574/src/common/tusb_fifo.h), [ref 2](https://gist.github.com/mcejp/719d3485b04cfcf82e8a8734957da06a)) to allow using the entire buffer capacity without introducing race conditions.
70
+
71
+
If the RX buffer is full and more data arrives, producers should discard the new data rather than overwriting old data in the buffer. An overflow may optionally be indicated by advancing the RX write pointer (without writing a value to the buffer) such that the size of the buffer is `capacity + 1`; this must be done atomically (ie. `wait` first) to avoid race conditions.
72
+
73
+
Note that the processor itself does not prevent code from overflowing the TX buffer. Users are expected to check the Line Status Register and avoid writing too much data at once.
74
+
75
+
### Syscon
24
76
25
-
Addresses `0xf0000000` - `0xffffffff` are reserved for MMIO and other system purposes.
77
+
Address `0xfffffff0` contains a simple write-only peripheral which can be used to control the system by writing values from the following table. Unsupported values will have no effect if written.
26
78
27
-
| Address | Value |
28
-
| ------------ | --------------------- |
29
-
|`0xf0000000`|`mtime`|
30
-
|`0xf0000004`|`mtimeh`|
31
-
|`0xf0000008`|`mtimecmp`|
32
-
|`0xf000000c`|`mtimecmph`|
33
-
|`0xfffffffc`|`mtvec` default value |
79
+
| Value | Effect |
80
+
| ------------ | --------- |
81
+
|`0x00000000`| Power off |
82
+
|`0x00000001`| Reboot |
34
83
35
-
The machine trap vector CSR `mtvec` is initialized to `0xfffffffc` at reset. To help catch issues with uninitialized `mtvec`, the processor will halt if code jumps to this address.
84
+
Additionally, the machine trap vector CSR `mtvec` is initialized to `0xfffffff0` at reset. To help catch issues with uninitialized `mtvec`, the processor will halt and output an error message if code jumps to this address.
36
85
37
86
## ISA
38
87
@@ -61,41 +110,41 @@ This non-standard extension adds instructions to control the mlogv32 processor's
The MLOG instructions are encoded with an I-type instruction format using the _custom-0_ opcode. The zero-extended immediate is used as a minor opcode (funct12) for implementation reasons.
67
116
68
-
The MLOGSYS instruction is used for simple system controls, including halt, `printchar`, `printflush`, `drawflush`, sortKB/kbconv integration, and icache initialization.
|4|char (0 if no new data) |`00000`| Read next char from sortKB|
77
-
|5|`00000`|\_\_etext | Decode ROM .text section|
78
-
79
-
The MLOGDRAW instruction is used for drawing graphics using the Mlog `draw` instruction. Arguments are passed to this instruction using registers a0 to a5 as necessary, and any return value is placed in _rd_. If _rd_ is specified as `00000` in the below table, no value will be written to `rd` in any case.
| 10 |lookup success (1 or 0) |x | y | type| id | size | rotation |`draw image`|
94
-
| 11 |`00000`| x| y| alignment||||`draw print`|
95
-
| 12 |`00000`|x | y |||||`draw translate`|
96
-
| 13 |`00000`|x | y |||||`draw scale`|
97
-
| 14 |`00000`|degrees ||||||`draw rotate`|
98
-
| 15 |`00000`|||||||`draw reset`|
117
+
The MLOGSYS instruction is used for simple system controls, including `printchar`, `printflush`, `drawflush`, and icache initialization.
118
+
119
+
The `mlogsys.icache` instruction uses register _rs1_ as the number of bytes to decode. This can be generated by using a linker script to find the end address of the `.text` section and load it using `li`. The actual number of bytes decoded will be the smallest of _rs1_, the size of the icache, and the size of ROM.
120
+
121
+
|funct12 | rs1| name|
122
+
|------- | ------- | ---------------------|
123
+
|0|length | Initialize ROM icache|
124
+
|1|char|`printchar`|
125
+
|2|`00000`|`printflush`|
126
+
|3|`00000`|`drawflush`|
127
+
128
+
The MLOGDRAW instruction is used for drawing graphics using the Mlog `draw` instruction. Arguments are passed to this instruction using registers _rs1_, a1, a2, a3, a4, and a5 as necessary.
0 commit comments