-
-
Notifications
You must be signed in to change notification settings - Fork 7
Technical reference
- Boot sequence
- Keyword tokens
- Microsoft Binary Format
- Character codes
- Keycodes
- Palette
- Memory model
- System variables
- Programmable sound generator
- DMA
- I/O ports
- Accessing extended RAM
During startup, UnoDOS 3 prints a logo in the standard screen (in page 5). After it finishes initialization, ROM 1 is paged in with the PC set to zero. This is the BASIC ROM. Because BASIC is not ready yet it pages in the BOOT ROM (ROM 0). The BOOT ROM wipes all the memory banks except for page 0 and page 5. It sets the middle 32K to be shadow RAM paged from the DOCK bank (this breaks the prototype Spectrum SE due to page contention -- this won't run on Fuse). It copies the font and palette to the framebuffer are sets the palette. At this point it activates the framebuffer and the palette, and clears page 5 (which will not be cleared by the BASIC startup code when running on the Chloe 280SE). Then it copies the last 7K of BASIC to $4000 (which will be DOCK or page 5 depending on the machine), sets the page in the top 16K to page 0, and passees control to the BASIC ROM. The BASIC ROM's NEW routine then sets hi-res mode and clears from $5C00 to $FFFF, displays the copyright notice, and passes control to the user.
The final code points of the tokens have not yet been determined. BASIC is stored in plain text format, so changes to the token arrangement will not break existing programs. These are the current assignments:
Code | Token |
---|---|
$80 |
EOF # |
$81 |
FN |
$82 |
INKEY$ |
$83 |
LOC # |
$84 |
LOF # |
$85 |
PI |
$86 |
RND |
$87 |
INSTR |
$88 |
LEFT$ |
$89 |
MID$ |
$8A |
RIGHT$ |
$8B |
STR$ |
$8C |
STRING$ |
$8D |
SPC |
$8E |
TAB |
$8F |
USING |
$90 |
ABS |
$91 |
ACOS |
$92 |
ASC |
$93 |
ASIN |
$94 |
ATAN |
$95 |
CHR$ |
$96 |
COS |
$97 |
DEEK |
$98 |
EXP |
$99 |
FIX |
$9A |
INP |
$9B |
INT |
$9C |
LEN |
$9D |
LOG |
$9E |
NOT |
$9F |
PEEK |
$A0 |
SIN |
$A1 |
SGN |
$A2 |
SQR |
$A3 |
TAN |
$A4 |
USR |
$A5 |
VAL |
$A6 |
VAL$ |
$A7 |
MOD |
$A8 |
<> |
$A9 |
<= |
$AA |
>= |
$AB |
AND |
$AC |
OR |
$AD |
XOR |
$AE |
LINE |
$AF |
OFF |
$B0 |
STEP |
$B1 |
THEN |
$B2 |
TO |
$B3 |
_B3 |
$B4 |
_B4 |
$B5 |
_B5 |
$B6 |
_B6 |
$B7 |
_B7 |
$B8 |
_B8 |
$B9 |
_B3 |
$BA |
_BA |
$BB |
_BB |
$BC |
_BC |
$BD |
_BD |
$BE |
_BE |
$BF |
_BF |
$C0 |
_C0 |
$C1 |
_C1 |
$C2 |
_C2 |
$C3 |
_C3 |
$C4 |
BLOAD |
$C5 |
BSAVE |
$C6 |
CALL |
$C7 |
CHDIR |
$C8 |
CLEAR |
$C9 |
CLOSE # |
$CA |
CLS |
$CB |
COLOR |
$CC |
CONT |
$CD |
COPY |
$CE |
DATA |
$CF |
DEF FN |
$D0 |
DELETE |
$D1 |
DIM |
$D2 |
DOKE |
$D3 |
EDIT |
$D4 |
ELSE |
$D5 |
END |
$D6 |
ERROR |
$D7 |
FILES |
$D8 |
FOR |
$D9 |
GOSUB |
$DA |
GOTO |
$DB |
IF |
$DC |
INPUT |
$DD |
KEY |
$DE |
KILL |
$DF |
LET |
$E0 |
LIST |
$E1 |
LOAD |
$E2 |
LOCATE |
$E3 |
MERGE |
$E4 |
MKDIR |
$E5 |
NAME |
$E6 |
NEXT |
$E7 |
NEW |
$E8 |
OLD |
$E9 |
ON |
$EA |
OPEN # |
$EB |
OUT |
$EC |
PALETTE |
$ED |
POKE |
$EE |
PRINT |
$EF |
RANDOMIZE |
$F0 |
READ |
$F1 |
REM |
$F2 |
RENUM |
$F3 |
RESTORE |
$F4 |
RETURN |
$F5 |
RMDIR |
$F6 |
RUN |
$F7 |
SAVE |
$F8 |
SCREEN |
$F9 |
SEEK # |
$FA |
SOUND |
$FB |
STOP |
$FC |
TRACE |
$FD |
WAIT |
$FE |
WEND |
$FF |
WHILE |
MBF extended precision numbers consist of an 8-bit base-2 exponent with a bias of 128, so that exponents −127…−1 are represented by x = 1…127 ($01…$7F), exponents 0…127 are represented by x = 128…255 ($80…$FF), with a special case for x = 0 ($00) representing the whole number being zero, a sign bit (positive mantissa: s = 0; negative mantissa: s = 1) and a 31-bit mantissa of the significand. There is always a 1-bit implied to the left of the explicit mantissa, and the radix point is located before this assumed bit. Unlike IEEE floating point, MBF doesn't support denormal numbers, infinities or NaNs.
Exponent | Sign | Significand |
---|---|---|
8 bits, bit 39–32 | 1 bit, bit 31 | 31 bits, bit 30–0 |
xxxxxxxx | s | mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm |
- 10: $84, $20, $00, $00, $00
- 1: $81, $00, $00, $00, $00
- 0: $00, $00, $00, $00, $00
- 0.5: $80, $00, $00, $00, $00
- 0.25: $7F, $00, $00, $00, $00
- -0.5: $80, $80, $00, $00, $00
- sqrt(0.5): $80, $35, $04, $F3, $34
- sqrt(2): $81, $35, $04, $F3, $34
- ln(2): $80, $31, $72, $17, $F8
- log2(e): $81, $38, $AA, $3B, $29
- pi/2": $81, $49, $0F, $DA, $A2
- 2*pi: $83, $49, $0F, $DA, $A2
Depending on context, SE Basic IV will treat a code point in the control characters range as a control character or as a glyph defined by the active code page which by default is code page 437. Depending on context, code points of $80 or higher are interpreted as a token or a code page glyph.
This is a list of the American Standard Code for Information Interchange (ASCII). ASCII only covers 128 characters and defines the code point ranges $00–$1F and $7F as control characters which do not have a printable glyph assigned to them. This includes such values as the Carriage Return (CR) character that ends a program line.
. | _0` | _1` | _2` | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0_ | NUL | SOH | STX | ETX | EOT | ENQ | ACK | BEL | BS | HT | LF | VT | FF | CR | SO | SI |
1_ | DLE | DC1 | DC2 | DC3 | DC4 | NAK | SYN | ETB | CAN | EM | SUB | ESC | FS | GS | RS | US |
2_ | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | |
3_ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
4_ | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
5_ | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
6_ | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
7_ | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | DEL |
This table shows the characters that are produced by the 256 single-byte code points when the DOS Latin USA code page 437 is loaded, which is the default. Other code pages can be loaded to assign other characters to these code points.
- SE Basiv IV adds the Euro currency symbol (€) at code point 255.
- Redefining characters in the printable ASCII code point range $20–$7E will result in a different glyph being shown on the screen, but the character will continue to be treated as the corresponding ASCII character.
- All characters can be redefined by loading another code page.
. | _0 | _1 | _2 | _3 | _4 | _5 | _6 | _7 | _8 | _9 | _A | _B | _C | _D | _E | _F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0_ | ☺ | ☻ | ♥ | ♦ | ♣ | ♠ | • | ◘ | ○ | ◙ | ♂ | ♀ | ♪ | ♫ | ☼ | |
1_ | ► | ◄ | ↕ | ‼ | ¶ | § | ▬ | ↨ | ↑ | ↓ | → | ← | ∟ | ↔ | ▲ | ▼ |
2_ | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | |
3_ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
4_ | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
5_ | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
6_ | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
7_ | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | ⌂ |
8_ | Ç | ü | é | â | ä | à | å | ç | ê | ë | è | ï | î | ì | Ä | Å |
9_ | É | æ | Æ | ô | ö | ò | û | ù | ÿ | Ö | Ü | ¢ | £ | ¥ | ₧ | ƒ |
A_ | á | í | ó | ú | ñ | Ñ | ª | º | ¿ | ⌐ | ¬ | ½ | ¼ | ¡ | « | » |
B_ | ░ | ▒ | ▓ | │ | ┤ | ╡ | ╢ | ╖ | ╕ | ╣ | ║ | ╗ | ╝ | ╜ | ╛ | ┐ |
C_ | └ | ┴ | ┬ | ├ | ─ | ┼ | ╞ | ╟ | ╚ | ╔ | ╩ | ╦ | ╠ | ═ | ╬ | ╧ |
D_ | ╨ | ╤ | ╥ | ╙ | ╘ | ╒ | ╓ | ╫ | ╪ | ┘ | ┌ | █ | ▄ | ▌ | ▐ | ▀ |
E_ | α | ß | Γ | π | Σ | σ | µ | τ | Φ | Θ | Ω | δ | ∞ | φ | ε | ∩ |
F_ | ≡ | ± | ≥ | ≤ | ⌠ | ⌡ | ÷ | ≈ | ° | ∙ | · | √ | ⁿ | ² | ■ |
SE Basic IV primarily reads the keyboard using a 40-key matrix. However, the top row can only be read using the PS/2 scan codes. It stores key presses in the keyboard buffer with the following codes:
Key | Code | Notes |
---|---|---|
Esc | $20 |
+ SHIFT
|
Backspace | $0C |
|
Tab | $06 |
|
Return | $0D |
|
F0 | Not stored in keyboard buffer. Must be read using a user NMI routine. | |
F1 | $11 |
|
F2 | $12 |
|
F3 | $13 |
|
F4 | $14 |
|
F5 | $15 |
|
F6 | $16 |
|
F7 | $17 |
|
F8 | $18 |
|
F9 | $19 |
|
F10 | $1A |
|
F11 | $1B |
|
F12 | $1C |
|
F13 | $1D |
|
F14 | $1E |
|
F14 | $1E |
|
F15 | $1F |
|
Home | $02 |
|
End | $03 |
|
Page Up | $04 |
|
Page Down | $05 |
|
↑ | $0B |
|
← | $08 |
|
→ | $09 |
|
↓ | $0A |
|
Insert | $00 |
|
Delete | $7F |
|
Help | $10 |
|
Clr | $01 |
Key | Code | Notes |
---|---|---|
F1 | $05 |
|
F2 | $06 |
|
F3 | $04 |
|
F4 | $0C |
|
F5 | $03 |
|
F6 | $0B |
|
F7 | $83 |
|
F8 | $0A |
|
F9 | $01 |
|
F10 | $09 |
|
F11 | $78 |
|
F12 | $07 |
|
F13 | $2F |
|
F14 | $37 |
|
F15 | $3F |
┌───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
│76 │ │05 │06 │04 │0C │ │03 │0B │83 │0A │ │01 │09 │78 │07 │ │2F │37 │3F │
└───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐ ┌───┬───┬───┐
│0E │16 │1E │26 │25 │2E │36 │3D │3E │46 │45 │4E │55 │ 66│ │70x│6Cx│7Dx│
├───┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬────┤ ├───┼───┼───┤
│0D │15 │1D │24 │2D │2C │35 │3C │43 │44 │4D │54 │5B │ 5A│ │71x│69x│7Ax│
├────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ └───┴───┴───┘
│58 │1C │1B │23 │2B │34 │33 │3B │42 │4B │4C │52 │5D │ │
├────┬┴──┬┴──┬┴──┬┴──┬┴──┬┴──┬┴──┬┴──┬┴──┬┴──┬┴──┬┴──┬┴───┤ ┌───┐
│12 │61 │1A │22 │21 │2A │32 │31 │3A │41 │49 │4A │51 │ 59│ │75x│
├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴┬──┴─┬─┴──┬┴───┼────┤ ┌───┼───┼───┐
│14 │1Fx │11 │ 29 │ 11x│ 27x│ 2Fx│ 14x│ │6Bx│72x│74x│
└────┴────┴────┴──────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘
Note: Code $61
is present only 88 key and 89 key layouts. Code $51
is present only on 89 key layouts.
To convert a 24-bit color to an 8-bit ULAplus color, take the most significant bits of the 8-bit values of the RGB color and arrange them in GRB order. Then drop the least significant bit. For example:
dark orange = #ff8c00
R = %111[11111], G = %100[01100], B = %000[00000]
9-bit GRB = %10011100[0]
8-bit GRB = %10011100
To convert an 8-bit ULAplus color to a 24-bit color, convert the 2-bit blue value to a 3-bit value by ORing the first two bits to get the least significant bit. Then repeat the values to get the 9-bit value and drop the least significant bit. For example:
dark orange - %10011100
R = %111 G = %100 B = %00[0]
9-bit R = %111 111 11[1]
9-bit G = %100 100 10[0]
9-bit B = %000 000 00[0]
24-bit RGB = %11111111 10010010 00000000
= #FF9200
The canonical 8-bit values for the ULAplus 3-bit values are:
B R/G hex
%00[0] %000 #00
%001 #24
%010 #49
%01[1] %011 #6d
%100 #92
%10[1] %101 #b6
%110 #db
%11[1] %111 #ff
In normal operation, the 64K address space is used as follows:
┌─────┬───────┬───────────┬─────────────┬───┬─────────┬───────────┬───┬────────────────────┬───┬∙∙∙
│ ROM │ BASIC │ System │ Channel │ 8 │ BASIC │ Variables │ 8 │ Command or program │ N │
│ │ (RAM) │ Variables │ Information │ 0 │ Program │ │ 0 │ line being entered │ L │
├─────┼───────┼───────────┼─────────────┴───┼─────────┼───────────┴───┼────────────────────┴───┴∙∙∙
↑ ↑ ↑ ↑ ↑ ↑ ↑
│ │ │ │ │ │ │
0 $4000 $5BB9 CHANS PROG VARS ELINE
∙∙∙┬───┬───────┬───┬────────────┬────────────┬───────┬─────────┬───────┬───┬───┐
│ 8 │ INPUT │ N │ Temporary │ Calculator │ Spare │ Machine │ GOSUB │ ? │ 3 │
│ 0 │ Data │ L │ Work Space │ Stack │ │ Stack │ Stack │ │ E │
∙∙∙┴───┼───────┴───┴────────────┼────────────┼───────┼─────────┴───────┴───┼───┤
↑ ↑ ↑ ↑ ↑ ↑
│ │ │ │ │ │
WORKSP STKBOT STKEND SP RAMTOP PRAMT
The framebuffer is stored outside main RAM (bank 7). In 80 column mode it is used as follows:
$FFFF ┬───────────────┬ 65535
│ font │
$F800 ┼───────────────┼ 63488
│ odd columns │
$E000 ┼───────────────┼ 57344
│ palette │
$DFC0 ┼───────────────┼ 57280
│ temp stack │
$DF80 ┼───────────────┼ 57216
│ character map │
$D800 ┼───────────────┼ 55296
│ even columns │
$C000 ┴───────────────┴ 49152
In 40 column mode it is used as followes:
$FFFF +---------------+ 65535
| font |
$F800 +---------------+ 63488
| attribute map |
$E000 +---------------+ 57344
| palette |
$DFC0 +---------------+ 57280
| temp stack |
$DF80 +---------------+ 57216
| character map |
$D800 +---------------+ 55296
| bitmap |
$C000 +---------------+ 49152
Having the temporary stack grow down towards the character map means that in a worst case scenario some incorrect characters would be read back from the screen in 80 column mode. In 40 column mode where the character map is half the size but there is more processing to do it will never get near the character map.
In 80 column mode the palette is updated so that the foreground and background colors match the permanent attributes. When switching to 40 column mode the original palette entries are restored.
In 40 column mode the bitmap is stored in the even columns
area and the attribute map is stored in the odd columns
area.
MSTATE 23548 Mouse state.
JSTATE 23549 Joystick state.
K-HEAD 23550 Points to head of keyboard buffer.
K-TAIL 23551 Points to tail of keyboard buffer.
KSTATE 23552 (8) Keyboard state.
REPDEL 23560 Delay before keys auto-repeat (in 50ths. of a second); normally 25.
REPPER 23561 Delay between key repeats (in 50ths. of a second); normally 2.
DEFADD 23562 (2) DEF FN address (offset).
ONERR 23564 (2) Status of ON ERROR and line to jump to.
MASKADD 23566 (2) Address of user IM1 routine.
STREAMS 23568 (38) For streams -3 to 15, a word gives the displacement from the start of the channels area to the assigned channel. If the word is zero, the stream is closed.
SEG 23606 (2) Reserved.
RASP 23608 Length of error sound in 60ths of a second; normally 60.
PIP 23609 Length of keyboard click (normally zero).
ERR-NR 23610 Error number.
FLAGS 23611 Main flags byte.
VDU-FLAG 23612 Display flags.
ERR-SP 23613 (2) SP value to use when an error occurs.
LIST-SP 23615 (2) SP value to use when an automatic list fills the screen.
MODE 23617 Cursor mode; L, C, E or G.
NEWPPC 23618 (2) New line to jump to.
NSPPC 23620 New statement to jump to, or FFH.
PPC 23621 (2) Current line number during program execution.
SUBPPC 23623 Current statement number.
BORDCR 23624 Attributes for lower screen except in SCREEN 0.
E-PPC 23625 (2) Number of line with > cursor.
VARS 23627 (2) Address of variables.
DEST 23629 (2) Used in variable assignments.
CHANS 23631 (2) Start of channels area.
CURCHL 23633 (2) Start of current channel.
PROG 23635 (2) Program start (address of line number of first line).
NXTLINE 23637 (2) Address of next line in BASIC program.
DATADD 23639 (2) Data address used by READ command.
E-LINE 23641 (2) Edit line start.
K-CUR 23643 (2) Address of cursor in the edit line.
CH-ADD 23645 (2) Current character address.
X-PTR 23647 (2) Address in the edit line of a syntax error.
WORKSP 23649 (2) workspace start.
STKBOT 23651 (2) Address of bottom of calculator stack.
STKEND 23653 (2) End of floating point calculator stack.
BREG 23655 Calculator’s B register.
MEM 23656 (2) Start of calculator’s memory area.
FLAGS2 23658 8 if caps lock is on, else zero.
DF-SZ 23659 The number of lines (including one blank line) in the lower part of the screen.
S-TOP 23660 (2) Line number of top line in an automatic listing.
OLDPPC 23662 (2) Line number that CONTINUE goes to.
OSPCC 23664 Statement number that CONTINUE goes to.
FLAGX 23665 Flags used by INPUT command and the editor.
STRLEN 23666 (2) Used when variables are assigned to.
T-ADDR 23668 (2) Address of next item in syntax table.
SEED 23670 (2) Random number seed. Set by RANDOMIZE.
FRAME 23672 Current frame (0-59).
TIME-T 23673 (4) POSIX time (unsigned).
COORD-Y 23677 Y pixel co-ordinate (0-255).
COORD-X 23678 X pixel co-ordinate (0-65535).
NMIADD 23680 Address to jump to on non-maskable interrupt.
ECHO-E 23682 (2) 33 column number and 24 line number (in lower half) of end of input buffer.
DF-CC 23684 (2) Address in display file of upper window PRINT position.
DF-CCL 23686 (2) Address in display file of lower window PRINT position.
S-POSN 23688 (2) Upper window position as column/row.
SPOSNL 23690 (2) Lower window position as column/row.
SCR-CT 23692 (2) Counter used to give “Scroll?” prompt.
ATTR-P 23693 Attributes used by mode 0.
MASK-P 23694 Mask used by mode 0. Bits which are 1 make the corresponding attribute bit be taken from the screen, not ATTRP.
ATTR-T 23695 Temporary version of ATTR-P.
MASK-T 23696 Temporary version of MASK-P.
P-FLAG 23697 Bit 4 and 5 are set for paper 9, bit 6 and 7 for pen 9.
MEMBOT 23698 (30) Calculator’s memory area.
DOSVAR 23728 (2) Used by the operating system.
RAMTOP 23730 (2) Address of last byte of BASIC system area.
P-RAMT 23732 (2) Address of last byte of physical RAM.
The individual bits of certain system variables are flags as follows:
0
: Set to suppress a leading space.
5
: Set if function key macros are enabled.
6
: Set if scanning result is numeric.
7
: Reset if checking syntax.
0
: Set if lower screen in use.
3
: Set if editing a line.
4
: Set if an automatic listing required.
5
: Set if lower screen to be cleared.
0
: Set if main screen to be cleared.
1
: Set if software defined screen in use.
2
: Set if a :
is within quotes.
3
: Set if caps lock on.
4
: Set if K channel in use.
5
: Set if next character should be treated as a printable character.
6
: Set if next character should be over-printed at the previous location.
7
: Set if trace enabled.
0
: Set if handling a simple string.
1
: Set if handling a new variable.
5
: Set if in input mode.
7
: Set if handling INPUT LINE.
0-7
: Set to STOP.
1-6
: Set to CONTINUE.
6-7
: Reset to GOTO.
The Chloe 280SE's PSG (programmable sound generator) is clocked at 1.75MHz. However, SE Basic IV can also run on hardware with PSGs clocked at other speeds. Note tables are provided for the most common variants.
Ideal Tune Registers Actual
Note Octave Frequency Period Coarse Fine Frequency
C 1 32.703 3344 13 16 32.708
C# 1 34.648 3157 12 85 34.645
D 1 36.708 2980 11 164 36.703
D# 1 38.891 2812 10 252 38.896
E 1 41.203 2655 10 95 41.196
F 1 43.654 2506 9 202 43.645
F# 1 46.249 2365 9 61 46.247
G 1 48.999 2232 8 184 49.003
G# 1 51.913 2107 8 59 51.910
A 1 55.000 1989 7 197 54.990
A# 1 58.270 1877 7 85 58.271
B 1 61.735 1772 6 236 61.724
C 2 65.406 1672 6 136 65.416
C# 2 69.296 1578 6 42 69.312
D 2 73.416 1490 5 210 73.406
D# 2 77.782 1406 5 126 77.792
E 2 82.407 1327 5 47 82.423
F 2 87.307 1253 4 229 87.291
F# 2 92.499 1182 4 158 92.534
G 2 97.999 1116 4 92 98.006
G# 2 103.826 1053 4 29 103.870
A 2 110.000 994 3 226 110.035
A# 2 116.541 939 3 171 116.480
B 2 123.471 886 3 118 123.448
C 3 130.813 836 3 68 130.831
C# 3 138.591 789 3 21 138.625
D 3 146.832 745 2 233 146.812
D# 3 155.563 703 2 191 155.583
E 3 164.814 664 2 152 164.721
F 3 174.614 626 2 114 174.720
F# 3 184.997 591 2 79 185.068
G 3 195.998 558 2 46 196.013
G# 3 207.652 527 2 15 207.543
A 3 220.000 497 1 241 220.070
A# 3 233.082 469 1 213 233.209
B 3 246.942 443 1 187 246.896
C 4 261.626 418 1 162 261.663
C# 4 277.183 395 1 139 276.899
D 4 293.665 372 1 116 294.019
D# 4 311.127 352 1 96 310.724
E 4 329.628 332 1 76 329.443
F 4 349.228 313 1 57 349.441
F# 4 369.994 296 1 40 369.510
G 4 391.995 279 1 23 392.025
G# 4 415.305 263 1 7 415.875
A 4 440.000 249 0 249 439.257
A# 4 466.164 235 0 235 465.426
B 4 493.883 221 0 221 494.910
C 5 523.251 209 0 209 523.325
C# 5 554.365 197 0 197 555.203
D 5 587.330 186 0 186 588.038
D# 5 622.254 176 0 176 621.449
E 5 659.255 166 0 166 658.886
F 5 698.456 157 0 157 696.656
F# 5 739.989 148 0 148 739.020
G 5 783.991 140 0 140 781.250
G# 5 830.609 132 0 132 828.598
A 5 880.000 124 0 124 882.056
A# 5 932.328 117 0 117 934.829
B 5 987.767 111 0 111 985.360
C 6 1046.502 105 0 105 1041.667
C# 6 1108.731 99 0 99 1104.798
D 6 1174.659 93 0 93 1176.075
D# 6 1244.508 88 0 88 1242.898
E 6 1318.510 83 0 83 1317.771
F 6 1396.913 78 0 78 1402.244
F# 6 1479.978 74 0 74 1478.041
G 6 1567.982 70 0 70 1562.500
G# 6 1661.219 66 0 66 1657.197
A 6 1760.000 62 0 62 1764.113
A# 6 1864.655 59 0 59 1853.814
B 6 1975.533 55 0 55 1988.636
C 7 2093.005 52 0 52 2103.365
C# 7 2217.461 49 0 49 2232.143
D 7 2349.318 47 0 47 2327.128
D# 7 2489.016 44 0 44 2485.795
E 7 2637.020 41 0 41 2667.683
F 7 2793.826 39 0 39 2804.487
F# 7 2959.955 37 0 37 2956.081
G 7 3135.963 35 0 35 3125.000
G# 7 3322.438 33 0 33 3314.394
A 7 3520.000 31 0 31 3528.226
A# 7 3729.310 29 0 29 3771.552
B 7 3951.066 28 0 28 3906.250
C 8 4186.009 26 0 26 4206.731
C# 8 4434.922 25 0 25 4375.000
D 8 4698.636 23 0 23 4755.435
D# 8 4978.032 22 0 22 4971.591
E 8 5274.041 21 0 21 5208.333
F 8 5587.652 20 0 20 5468.750
F# 8 5919.911 18 0 18 6076.389
G 8 6271.927 17 0 17 6433.824
G# 8 6644.875 16 0 16 6835.938
A 8 7040.000 16 0 16 6835.938
A# 8 7458.620 15 0 15 7291.667
B 8 7902.133 14 0 14 7812.500
Ideal Tune Registers Actual
Note Octave Frequency Period Coarse Fine Frequency
C 1 32.703 3371 13 43 32.705
C# 1 34.648 3182 12 110 34.648
D 1 36.708 3003 11 187 36.713
D# 1 38.891 2835 11 19 38.889
E 1 41.203 2676 10 116 41.200
F 1 43.654 2526 9 222 43.646
F# 1 46.249 2384 9 80 46.246
G 1 48.999 2250 8 202 49.000
G# 1 51.913 2124 8 76 51.907
A 1 55.000 2005 7 213 54.988
A# 1 58.270 1892 7 100 58.272
B 1 61.735 1786 6 250 61.730
C 2 65.406 1686 6 150 65.391
C# 2 69.296 1591 6 55 69.296
D 2 73.416 1502 5 222 73.402
D# 2 77.782 1417 5 137 77.805
E 2 82.407 1338 5 58 82.399
F 2 87.307 1263 4 239 87.292
F# 2 92.499 1192 4 168 92.492
G 2 97.999 1125 4 101 98.000
G# 2 103.826 1062 4 38 103.814
A 2 110.000 1002 3 234 110.030
A# 2 116.541 946 3 178 116.543
B 2 123.471 893 3 125 123.460
C 3 130.813 843 3 75 130.783
C# 3 138.591 796 3 28 138.505
D 3 146.832 751 2 239 146.804
D# 3 155.563 709 2 197 155.501
E 3 164.814 669 2 157 164.798
F 3 174.614 631 2 119 174.723
F# 3 184.997 596 2 84 184.983
G 3 195.998 563 2 51 195.826
G# 3 207.652 531 2 19 207.627
A 3 220.000 501 1 245 220.060
A# 3 233.082 473 1 217 233.087
B 3 246.942 446 1 190 247.197
C 4 261.626 421 1 165 261.876
C# 4 277.183 398 1 142 277.010
D 4 293.665 375 1 119 294.000
D# 4 311.127 354 1 98 311.441
E 4 329.628 334 1 78 330.090
F 4 349.228 316 1 60 348.892
F# 4 369.994 298 1 42 369.966
G 4 391.995 281 1 25 392.349
G# 4 415.305 265 1 9 416.038
A 4 440.000 251 0 251 439.243
A# 4 466.164 237 0 237 465.190
B 4 493.883 223 0 223 494.395
C 5 523.251 211 0 211 522.512
C# 5 554.365 199 0 199 554.020
D 5 587.330 188 0 188 586.436
D# 5 622.254 177 0 177 622.881
E 5 659.255 167 0 167 660.180
F 5 698.456 158 0 158 697.785
F# 5 739.989 149 0 149 739.933
G 5 783.991 141 0 141 781.915
G# 5 830.609 133 0 133 828.947
A 5 880.000 125 0 125 882.000
A# 5 932.328 118 0 118 934.322
B 5 987.767 112 0 112 984.375
C 6 1046.502 105 0 105 1050.000
C# 6 1108.731 99 0 99 1113.636
D 6 1174.659 94 0 94 1172.872
D# 6 1244.508 89 0 89 1238.764
E 6 1318.510 84 0 84 1312.500
F 6 1396.913 79 0 79 1395.570
F# 6 1479.978 74 0 74 1489.865
G 6 1567.982 70 0 70 1575.000
G# 6 1661.219 66 0 66 1670.455
A 6 1760.000 63 0 63 1750.000
A# 6 1864.655 59 0 59 1868.644
B 6 1975.533 56 0 56 1968.750
C 7 2093.005 53 0 53 2080.189
C# 7 2217.461 50 0 50 2205.000
D 7 2349.318 47 0 47 2345.745
D# 7 2489.016 44 0 44 2505.682
E 7 2637.020 42 0 42 2625.000
F 7 2793.826 39 0 39 2826.923
F# 7 2959.955 37 0 37 2979.730
G 7 3135.963 35 0 35 3150.000
G# 7 3322.438 33 0 33 3340.909
A 7 3520.000 31 0 31 3556.452
A# 7 3729.310 30 0 30 3675.000
B 7 3951.066 28 0 28 3937.500
C 8 4186.009 26 0 26 4240.385
C# 8 4434.922 25 0 25 4410.000
D 8 4698.636 23 0 23 4793.478
D# 8 4978.032 22 0 22 5011.364
E 8 5274.041 21 0 21 5250.000
F 8 5587.652 20 0 20 5512.500
F# 8 5919.911 19 0 19 5802.632
G 8 6271.927 18 0 18 6125.000
G# 8 6644.875 17 0 17 6485.294
A 8 7040.000 16 0 16 6890.625
A# 8 7458.620 15 0 15 7350.000
B 8 7902.133 14 0 14 7875.000
Ideal Tune Registers Actual
Note Octave Frequency Period Coarse Fine Frequency
C 1 32.703 3389 13 61 32.706
C# 1 34.648 3199 12 127 34.649
D 1 36.708 3020 11 204 36.702
D# 1 38.891 2850 11 34 38.891
E 1 41.203 2690 10 130 41.205
F 1 43.654 2539 9 235 43.655
F# 1 46.249 2397 9 93 46.241
G 1 48.999 2262 8 214 49.001
G# 1 51.913 2135 8 87 51.916
A 1 55.000 2015 7 223 55.008
A# 1 58.270 1902 7 110 58.276
B 1 61.735 1795 7 3 61.750
C 2 65.406 1695 6 159 65.393
C# 2 69.296 1600 6 64 69.275
D 2 73.416 1510 5 230 73.404
D# 2 77.782 1425 5 145 77.783
E 2 82.407 1345 5 65 82.409
F 2 87.307 1270 4 246 87.276
F# 2 92.499 1198 4 174 92.521
G 2 97.999 1131 4 107 98.002
G# 2 103.826 1068 4 44 103.783
A 2 110.000 1008 3 240 109.961
A# 2 116.541 951 3 183 116.552
B 2 123.471 898 3 130 123.431
C 3 130.813 847 3 79 130.863
C# 3 138.591 800 3 32 138.551
D 3 146.832 755 2 243 146.809
D# 3 155.563 713 2 201 155.457
E 3 164.814 673 2 161 164.696
F 3 174.614 635 2 123 174.552
F# 3 184.997 599 2 87 185.043
G 3 195.998 566 2 54 195.831
G# 3 207.652 534 2 22 207.567
A 3 220.000 504 1 248 219.922
A# 3 233.082 476 1 220 232.858
B 3 246.942 449 1 193 246.861
C 4 261.626 424 1 168 261.417
C# 4 277.183 400 1 144 277.102
D 4 293.665 377 1 121 294.007
D# 4 311.127 356 1 100 311.350
E 4 329.628 336 1 80 329.883
F 4 349.228 317 1 61 349.655
F# 4 369.994 300 1 44 369.469
G 4 391.995 283 1 27 391.663
G# 4 415.305 267 1 11 415.133
A 4 440.000 252 0 252 439.844
A# 4 466.164 238 0 238 465.717
B 4 493.883 224 0 224 494.824
C 5 523.251 212 0 212 522.833
C# 5 554.365 200 0 200 554.203
D 5 587.330 189 0 189 586.458
D# 5 622.254 178 0 178 622.700
E 5 659.255 168 0 168 659.766
F 5 698.456 159 0 159 697.111
F# 5 739.989 150 0 150 738.938
G 5 783.991 141 0 141 786.104
G# 5 830.609 133 0 133 833.388
A 5 880.000 126 0 126 879.688
A# 5 932.328 119 0 119 931.434
B 5 987.767 112 0 112 989.648
C 6 1046.502 106 0 106 1045.666
C# 6 1108.731 100 0 100 1108.406
D 6 1174.659 94 0 94 1179.156
D# 6 1244.508 89 0 89 1245.400
E 6 1318.510 84 0 84 1319.531
F 6 1396.913 79 0 79 1403.046
F# 6 1479.978 75 0 75 1477.875
G 6 1567.982 71 0 71 1561.136
G# 6 1661.219 67 0 67 1654.338
A 6 1760.000 63 0 63 1759.375
A# 6 1864.655 59 0 59 1878.655
B 6 1975.533 56 0 56 1979.297
C 7 2093.005 53 0 53 2091.333
C# 7 2217.461 50 0 50 2216.813
D 7 2349.318 47 0 47 2358.311
D# 7 2489.016 45 0 45 2463.125
E 7 2637.020 42 0 42 2639.063
F 7 2793.826 40 0 40 2771.016
F# 7 2959.955 37 0 37 2995.693
G 7 3135.963 35 0 35 3166.875
G# 7 3322.438 33 0 33 3358.807
A 7 3520.000 31 0 31 3575.504
A# 7 3729.310 30 0 30 3694.688
B 7 3951.066 28 0 28 3958.594
C 8 4186.009 26 0 26 4263.101
C# 8 4434.922 25 0 25 4433.625
D 8 4698.636 24 0 24 4618.359
D# 8 4978.032 22 0 22 5038.210
E 8 5274.041 21 0 21 5278.125
F 8 5587.652 20 0 20 5542.031
F# 8 5919.911 19 0 19 5833.717
G 8 6271.927 18 0 18 6157.813
G# 8 6644.875 17 0 17 6520.037
A 8 7040.000 16 0 16 6927.539
A# 8 7458.620 15 0 15 7389.375
B 8 7902.133 14 0 14 7917.188
The DMA engine can do these types of transfer:
- Memory to memory (both using incrementing addresses)
- Memory to I/O (memory address incrementing)
- I/O to memory (memory address incrementing)
- I/O to I/O
Like the CPU, the DMA can only access a 64K address space. Any memory paging that affects the CPU also affects the DMA.
It can operate in foreground, halting the main CPU during the transfer, or in the background, allowing the CPU to continue working (although slightly slower than usual).
Two types of transfers are possible. Burst transfers move data as fast as possible, typically halting the CPU during transfer. Timed transfers move data at a specified rate, controlled by an onchip timer. Timed transfers are best suited for audio streaming directly from memory to DAC.
Transfers can be retriggerable, or one time. When a retriggerable transfer ends, it automatically restarts from the beginning. One time transfers do not restart. Burst transfers cannot be retriggerable.
For a non-CPU halting transfer, the DMA can be queried to return if a given source or destination address has been reached.
The DMA does not trigger CPU interrupts.
The DMA registers are part of the Uno
group of registers. Port #FC3B
selects the register to write to:
-
$A0
: DMActrl Control register. Reading it returns the last written value. A DMA transfer is initiated from thestop
condition, by writing any value other than0
into theMODE
bits. Stopping and re-starting a DMA transfer does not resume it; it starts from the beginning.-
D0-1
:MODE
:-
00
DMA is stopped. You can stop a timed DMA at any time by writing%00
toMODE
. -
01
Burst DMA transfer. CPU is halted during the transfer. -
10
Timed DMA transfer. -
11
Retrigerrable timed DMA transfer.
-
-
D2
:DST
:0
if destination address is memory.1
if destination address is I/O. -
D3
:SRC
:0
if source address is memory.1
if source address is I/O. -
D4
:PROB
:0
if address inDMAprob
is related to source (read) memory address.1
ifaddress inDMAprob
is related to destination (write) memory address. -
D5-7
: Reserved. Written and read as 0.
-
-
$A1
: DMAsrc Holds the source address for a memory-to-memory transfer, or memory-to-I/O transfer. Holds the I/O source address for a I/O-to-memory transfer, or I/O-to-I/O transfer. It requires two reads or two writes to transfer a little-endian 16-bit value to or from the register. The value of the register is not changed during or after a transfer. -
$A2
: DMAdst Holds the I/O destination address for an I/O-to-memory transfer, or an I/O-to-I/O transfer. It requires two reads or two writes to transfer a little-endian 16-bit value to or from the register. The value of the register is not changed during or after a transfer. -
$A3
: DMApre Holds the 16-bit preescaler value used to determine the frequency rate for a timed transfer. It requires two reads or two writes to transfer a little-endian 16-bit value to or from the register. The value of the register is not changed during or after a transfer. The actual rate is determined by these formula:- Transfers per second = 28000000 / preescaler_value (for memory to memory transfers)
- Transfers per second = 3500000 / preescaler_value (for transfers involving some sort of I / O address)
-
$A4
: DMAlen Holds the transfer byte length.0
means65536
bytes to transfer. It requires two reads or two writes to transfer a little-endian 16-bit value to or from the register. The value of the register is not changed during or after a transfer. -
$A5
: DMAprob Holds the 16-bit value that identifies the memory address involved in a DMA transfer (it can be a source or destination address). When the DMA reads from (if configured as a source address) or writes to (if configured as a destination address) this memory address, bit 7 ofDMAstat
is set. It requires two reads or two writes to transfer a little-endian 16-bit value to or from the register. The value of the register is not changed during or after a transfer. -
$A6
: DMAstat (read-only) The status register currently uses only bit 7. It is set to1
whenDMAprob
address is reached. Reading this register resets its value to0
.
The 8-bit digital to analog converter (DAC) is available on two different ports:
-
#DF
(SpecDrum) -
#B3
(Covox)
To avoid hitting other hardware, set the high byte of BC
to $FF
before issuing an OUT (C), A
instruction.
The mouse can be read directly using the MouseData
and MouseStatus
registers on the Uno ports. But typically it is easier to read the K-mouse
ports.
-
#FADF
: Button status.-
D0
:0
if right button pressed -
D1
:0
if leftbutton pressed -
D2
:0
if middle button pressed -
D3
:0
if fourth button pressed -
D4-7
: mouse wheel position (defaults to1111
)
-
-
#FBDF
: Horizontal position (x-axis) -
#FFDF
: Vertical position (y-axis)
The joystick I/O behavior is configurable. By default it is read using port #1F
. A 1
incidates active.
-
D0
: Right -
D1
: Left -
D2
: Down -
D3
: Up -
D4
: Fire button 1 -
D5
: -
D6
: -
D7
:
Port #FE
is used to read the 40-key keyboard matrix:
INP: Reads keys (bit 0 to bit 4 inclusive)
#FEFE SHIFT, Z, X, C, V #EFFE 0, 9, 8, 7, 6
#FDFE A, S, D, F, G #DFFE P, O, I, U, Y
#FBFE Q, W, E, R, T #BFFE ENTER, L, K, J, H
#F7FE 1, 2, 3, 4, 5 #7FFE SPACE, SYM SHFT, M, N, B
Reading bit 6 of port #FE
returns the input of the mono line-in.
Writing to port #FE
has the following effect:
-
D0-2
: Set border color (0 to 7
) -
D3
: Enable Mic (activate 1-bit speaker) -
D4
: Enable Ear (activate 1-bit speaker) -
D4-7
: Reserved
The bit pattern of the byte sent to port #F4
sets which 8K pages of the shadow RAM are mapped over main RAM. For example, %10000000
would page in chunk 7
at $E000-$FFFF
. The Ex
bank or Dock
bank are selected with bit 7
of the SCLD
register. By default this is 0
(Dock
).
By default, when shadow RAM is available, SE Basic IV sets the middle 32K of address space to be shadow RAM, effectively: OUT ($F4), %00111100
. In normal operation you should not change this value. If you set the middle 32K of address space to be main RAM, then Bank 5
(the shadow frame buffer) is paged from $4000 to $7FFF
and Bank 2
is paged from $8000 to $BFFF
. Both those banks can be paged in at $C000
using the Paging register, and leaving the middle 32K as shadow RAM provides a contiguous 24K for code with 128K of pageable RAM in the top 16K of the address space.
Bank 0-6
can be selected using the Paging register. Bank 7
is reserved for the frame buffer, so to get all 128K you must set the top 16K to be shadow RAM, effectively: OUT ($F4), %11111100
. Note, you should not attempt to write to the screen when the top 16K of shadow RAM is paged in, because it masks main RAM, rendering the frame buffer inaccessible.
In run mode, a total of 256K RAM is directly available to the user. This comprises 128K of Home RAM pageable in 16K chunks, and two 64K banks of shadow RAM (Dock and Ex banks) pageable in 8K chunks. The shadow RAM banks are mutually exclusive, so in practice it ie easier to use only one bank of shadow RAM. At boot, SE Basic IV sets the middle 32K of the address space to shadow RAM and sets the page at $C000
to Bank 0
. The frame buffer uses Bank 7
, but the top 16K of shadow RAM can be paged in at $C000
to provide a total of eight 16K RAM pages (128) in addition to the 24K of shadow RAM available from $6000 to $BFFF
. Note, because shadow RAM masks main RAM, you must not attempt to write to the screen (Bank 7
) if Dock 6-7
is paged in at $C000
. Also, writes to the screen will page in Bank 7
to do the screen write and then set Bank 0
, so you may need to reset the bank after writing to the screen.
The memory map of SE Basic IV on boot is:
$ffff +--------+--------+--------+--------+--------+--------+--------+--------+
| Bank 0 | Bank 1 | Bank 2 | Bank 3 | Bank 4 | Bank 5 | Bank 6 | Dock |
| | | | | | | | 6-7 |
| | | | | | | | |
| | | | | | | | |
$c000 +--------+--------+--------+--------+--------+--------+--------+--------+
| Dock | Any one of these pages may be switched in.
| 4-5 |
| |
| |
$8000 +--------+
| Dock |
| 2-3 |
| |
| |
$4000 +--------+
| ROM 1 |
| |
| |
| |
$0000 +--------+
To select Bank 0 to 6
write to port #7FFD
:
-
D0-2
: Bank (0 to 6
) to map into memory at$C000
. -
D3
: Framebuffer select. You should leave this as1
unless you are doing back buffering:-
0
: UseBank 5
as framebuffer -
1
: UseBank 7
as framebuffer
-
-
D4
: ROM select. You should always leave this as1
.-
0
: Boot ROM -
1
: BASIC ROM
-
-
D5
: When set to1
, further writes to port#7FFD
are ignored until a reset takes place. -
D6-7
: Reserved.
-
#BF3B
: register select -
#FF3B
: data
To switch off palette mode, OUT ($BF3B), 64: OUT ($FF3B), 0
.
Registers 0 to 63
are the palette entries.
Palette entries are stored in G3R3B2 format.
-
#BFFD
: data -
#FFFD
: register select
To select channels A to C
, OUT ($FFFD), 255
. To select channels D to F
, `OUT ($FFFD), 255).
Audio panning is set using port #F7
with bit pairs read left to right (big-endian) for channels ABC and the speaker/DAC:
-
10
: pan left -
11
: pan middle -
01
: pan right -
00
: mute channel
By default this is set to %10011111
(ACB stereo with the speaker/DAC going to left and right speakers).
-
D0-2
: Mode:-
000
: 256x192 pixles, 8x8 attributes, offset$0000
. -
001
: 256x192, 8x8 attributes, offset$2000
. -
010
: 256x192, 8x1 attributes. -
110
: 512x192, mono
-
-
D3-5
: Color settings for mono mode-
000
: Foreground0
, background7
. -
001
: Foreground1
, background6
. -
010
: Foreground2
, background5
. -
011
: Foreground3
, background4
. -
100
: Foreground4
, background3
. -
101
: Foreground5
, background2
. -
110
: Foreground6
, background1
. -
111
: Foreground7
, background0
.
-
-
D6
: When set to1
, timer interrupt is switched off. -
D7
: Select shadow RAM bank used by MMU.-
0
: Dock -
1
: Ex
-
Ports $FC3B
and $FD3B
are used to configure the Uno's ZX core. These ports provide access to up to 256 registers.
-
$FC3B
(64571
): Register. Write to select a regiser. Read to find last register selected. Note, when interrupts are enabled, SE Basic IV continually updates this register to read the keyboard. -
$FD3B
(64827
): Data. The behavior of this port when reading and writing depends on the register selected.
Binary format (fields in bold, the can be altered only when LOCK
= 0
):
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
LOCK | MODE1 | DISCONT | MODE0 | I2KB | DISNMI | DIVEN | BOOTM |
-
BOOTM
:-
0
: Run mode. -
1
: Boot mode (configuration mode). Used by the firmware, where you can configure some aspects of the hardware before entering run mode. Also required to access the full 512K of RAM.
-
-
DIVEN
:-
0
(default): divMMC not enabled. SPI interface access ports of the SD / MMC slot are still available. Memory used by divMMC available for other uses. -
1
: divMMC enabled. Before entering run mode, an OS image must be loaded into the corresponding RAM bank.
-
-
DISNMI
:-
0
(default): OS handles NMI events. -
1
: BASIC handles NMI events.
-
-
I2KB
:-
0
(default): Port#FE
behaves as issue 3. -
1
: Port#FE
behaves as issue 2.
-
-
MODE1
,MODE0
:-
00
: PAL, 312 lines -
01
: PAL, 311 lines -
10
: PAL, 320 lines -
11
: NTSC, 262 lines
-
-
DISCONT
:-
0
: Video contention enabled. CPU halted during VDP framebuffer access. -
1
: No video contention.
-
-
LOCK
:-
0
: Set by cold start or hard reset. -
1
: Prevents further changes to certain bits of theUnoConf
register and prevents access to the flash SPI.
-
UnoConf
can always be read, both in boot mode and run mode.
It is set to %00000001
on cold start or hard reset. It is unaffected by a soft reset.
In boot mode, sets the 16K RAM bank (0 to 31
) paged at $C000 to $FFFF
. Permits a maximum of 4MB of RAM. Ignored in run mode.
It is set to %00000000
on cold start or hard reset. It is unaffected by a soft reset.
Values written to the port are sent to the SPI flash. Reading the port returns the last value written and changes the next value read. Therefore, in block read operations you must discard the first byte read.
It is set to %00000000
on cold start. It is unaffected by a hard or soft reset.
Bit 0
only is used to set the status of the CS line of the Flash SPI:
-
0
: Flash selected. -
1
: Flash not selected.
It is set to %00000001
on cold start. It is unaffected by a hard or soft reset.
Read to obtain the last PS/2 scan code from the keyboard. Written to send commands to the keyboard.
Key status:
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
BSY | 0 | 0 | 0 | ERR | RLS | EXT | PEN |
-
BSY
:1
when a data transmission to the PS/2 port is still in progress. You must wait for0
to start a new transmission. -
ERR
:1
when the last transmission to or from the PS/2 port had errors. -
RLS
:1
when the last event belongs to a key that has been released. -
EXT
:1
when the last event belongs to a key with an extended code (E0 + scancode). -
PEN
:1
when there is new data ready to be read in the SCANCODE register. After readingKeyStat
, this bit is reset to0
.
-
D0-3
: keyboard-mapped joystick -
D4-7
: DB9 joystick port If bita
is1
, auto-fire is enabled.-
a000
: no joystick -
a001
: Kempston (K-stick) -
a010
: Sinclair 1 -
a011
: Sincalir 2 -
a100
: Protek / Curosr / AGF -
a101
: Fuller
-
It is set to %00010000
on cold start. It is unaffected by a hard or soft reset.
When read, returns the next byte of the key map (4KB in the current core, 16KB in earlier cores). When written replaces the next byte of the key map. The pointer is reset to 0
after a reset, a write to the #FC3B
register or when the key map is terminated. A key map can be loaded at boot time by specifying it in the CONFIG.SYS
file.
Deprecated.
Read to obtain the last PS/2 data from the mouse. Written to send commands to the mouse. For example, to initialize the mouse, the value $F4
must be sent to this register.
Mouse status:
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
BSY | 0 | 0 | 0 | ERR | 0 | 0 | PEN |
-
BSY
:1
when a data transmission to the PS/2 port is in progress. You must wait for0
to start a new transmission. -
ERR
:1
if the last transmission to or from the PS/2 port had errors. -
PEN
:1
when there is new data ready to be read in theMouseData
register. After readingMouseStatus
, this bit is reset to0
.
Scandoubler is mainly used to set timings.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
TURBO1 | TURBO0 | COPT | FREQ2 | FREQ1 | FREQ0 | ENSCAN | VGA |
-
TURBO
: CPU speed:-
00
: 3.5 MHz -
01
: 7.0 MHz -
10
: 14.0 MHz -
11
: 28.0 MHz
-
-
COPT
: composite sync for RGB and composite-
0
: ULA -
1
: PAL
-
-
FREQ
: Vertical refresh rate. Note, this scales all timings to preserve raster effects. You should leave this at%000
unless your monitor has problems at that frequency.-
000
: 50 Hz 48 / Pentagon -
001
: 50 Hz 128 -
010
: 52 Hz -
011
: 53 Hz -
100
: 55 Hz -
101
: 57 Hz -
110
: 59 Hz -
111
: 60 Hz
-
-
ENSCAN
: Set to1
to enable fake scanlines in VGA mode only. -
VGA
: Typically, even with a VGA display the scandoubler should be switched off. It can be configured in theCONFIG.SYS
file.-
0
: Switch off scandoubler for 5kHz RGB / composite video output. -
1
: The scandoubler output is the same as the normal RGB output, but doubling the horizontal delay frequency.
-
It is set to %11100000
on cold start. It is unaffected by a hard or soft reset.
Combined with the value of LINE8
in RasterCtrl
to set the scan line (0 to 511
) on which the raster interrup is triggered.
In practice, the largest value is limited by the number of lines generated by the VDP as set in the MODE
value of UnoConf
(311
, 310
, 319
or 261
). If a line number greater than the limit is set, the raster interrupt will not occur.
A screen line is made up of right edge
+ horizontal blanking interval
+ left edge
+ paper area
. Therefore, a value of 0
triggers the interrupt just as the right edge of the line before the first screen line begins. A value of 192
triggers the raster interrupt at the beginning of the bottom edge.
The line numbers for the end of the bottom edge and the beginning of the top edge depend on the video timings set in the UnoConf
register. In practice, the largest possible value (511
) triggers a raster interrupt on the last line of the top border. It is set to 511
on cold start and hard or soft reset.
Control register and raster interrupt status. The following bits are defined:
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
INT | 0 | 0 | 0 | 0 | DISVINT | ENARINT | LINE8 |
-
INT
(read only): It is worth 1 for 32 clock cycles from the moment the raster interrupt is triggered. Available even if interrupts are not enabled. It is not available ifENARINT
is0
. -
DISVINT
: When set to1
, switches off vertical delay masking interrupts (the original ones from the ULA). Set to0
after a reset. -
ENARINT
: Set to1
to enable masking interrupts per raster line. Set to0
after a reset. -
LINE8
: Bit8
ofRasterLine
.
Control various device properties.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
DISD | ENMMU | DIROMSEL1F | DIROMSEL7F | DI1FFD | DI7FFD | DITAY | DIAY |
-
DISD
: Set to1
to switch off the SPI hardware interface for SD (divMMC). Uses ports#1F
,#3F
,#E7
and#EB
. -
ENMMU
: Set to1
to enable the shadow RAM (horizontal MMU). Uses bit7
of port#FF
, port#F4
is useda read from port#FF
returns the last value written in it. -
DIROM1F
: The value of this bit is masked with the value of bit2
of port#1FFD
. When set to1
, the value of bit2
to of port#1FFD
is always0
. -
DIROM7F
: The value of this bit is masked with the value of bit4
of port $ 7FFD. When set to1
, the value of bit4
of port#7FFD
is always0
. -
DI1FFD
: When set to1
switches off +3 compatible paging. Uses port#1FFD
. Always1
whenDI7FFD
is1
. -
DI7FFD
: Set to1
to switch off 128 compatilbe paging system. -
DITAY
: Set to1
to switch off PSG channelsD
toF
. Always1
whenDIAY
is1
. -
DIAY
: Set to1
to switch off PSG channelsA
toC
.
Set to %01101000
on cold boot.
Control various device properties.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
- | - | - | - | - | DIRADAS | DITIMEX | DIULAPLUS |
-
D7-D3
: Reserved. Must contain%00000
or no change is made to the hardawre. -
DIRADES
: Set to1
to switch off Radastanian dispaly mode. When set to0
,DIULAPLUS
must also be set to0
. -
DITIMEX
: Set to1
to switch off Timex display modes. Writing to port#FF
is then ignored and if the Timex MMU is enabled, a read from port#FF
returns0
. -
DIULAPLUS
: Set to1
to switch off palette support. If contention is enabled, it continues to function.
Set to %00000100
on cold boot.
The registers in this range control a very low resolution 16-color video mode that is not directly supported by SE Basic IV. For more details see the ZX uno wiki.
Screen horizontal centering adjustment value for 48 ULA.
Screen vertical centering adjustment value for 48 ULA.
Screen horizontal centering adjustment value for 128 ULA.
Screen vertical centering adjustment value for 128 ULA.
Screen horizontal centering adjustment value for Pentagon ULA.
Screen vertical centering adjustment value for Pentagon ULA.
See DMA
Range of Uno registers reserved for experiments or private use
Control of the AD724 encoder chip operating mode. Bits 7-1
are reserved. Bit 0
sets the operating mode:
-
0
: PAL -
1
: NTSC
It is set to %00000001
on cold start. It is unaffected by a hard or soft reset.
Stores the 24-bit address in the SPI memory of a core to be started. Three bytes in big-endian format are written or read in succession.
Sending 1
to this port instructs the FPGA to start another core from address COREADDR
. Bits 7-1
are reserved and must be set to 0
. If no change is made to COREADDR
, this effectively performs a cold restart.
Deprecated
Reading this port returns the next ASCII character in the string containing the current revision of the Uno core. When the string ends, subsequent reads return 0
until the pointer goes back to the start of the string. This happens automatically after a reset or write to port #FC3B
. The string can contain only ASCII codes 32 to 127
The full 512K of RAM can only be accessed in Boot mode. This is extremely hazardous because RAM used by the system may be overwritten. However, in the worst case scenario it should be possible to restore the system using a cold restart.
The full memory layout is as follows:
In Boot mode the default memory map is as follows:
0xffff +--------+
| SRAM | Selected by UnoMapper
| |
| |
| |
0xc000 +--------+
| Bank 2 |
| |
| |
| |
0x8000 +--------+
| Bank 5 |
| |
| |
| |
0x4000 +--------+
| FPGA |
| Boot |
| ROM |
| |
0x0000 +--------+
The value written to UnoMapper
is as follows:
Byte | Value |
---|---|
$00 |
Home 0 |
$01 |
Home 1 |
$02 |
Home 2 |
$03 |
Home 3 |
$04 |
Home 4 |
$05 |
Home 5 (shadow frame buffer) |
$06 |
Home 6 |
$07 |
Home 7 (frame buffer) |
$08 |
Boot ROM |
$09 |
BASIC ROM |
$0A |
- |
$0B |
- |
$0C |
OS ROM |
$0D |
- |
$0E |
- |
$0F |
- |
$10 |
OS RAM 0-1
|
$11 |
OS RAM 2-3
|
$12 |
OS RAM 4-5
|
$13 |
OS RAM 6-7
|
$14 |
OS RAM 8-9
|
$15 |
OS RAM 10-11
|
$16 |
OS RAM 12-13
|
$17 |
OS RAM 14-15
|
$18 |
Ex 0-1
|
$19 |
Ex 2-3
|
$1A |
Ex 4-5
|
$1B |
Ex 6-7
|
$1C |
Dock 0-1
|
$1D |
Dock 2-3
|
$1E |
Dock 4-5
|
$1F |
Dock 6-7
|
Typically, you should not modify the contents of pages $09
, $0C
, $10
and $11
. If you are short of memory, you can safely use the Boot ROM area, because it is only called on a hard reset which will restore the contents. Pages 4-15
of OS RAM are not used by UnoDOS 3 and are safe to use. If you have already loaded all the data you require from disk and will make no futhere use of the OS, you can switch off the divMMC hardware and then use pages $0C
, $10
and $11
. If your program makes no use of the service routines, you can use page $09
.
This documentation is copyright © 2012-2022 Source Solutions, Inc. Portions copyright © 2014-2019 Rob Hagemans.
Licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.