forked from MrKWatkins/ZXSpectrumNextTests
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nextreg.txt
883 lines (774 loc) · 32.6 KB
/
nextreg.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
ped's version tag: core3.1.5 20200427
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
The ZX Next stores configuration state in a field of registers.
These registers are accessible via two io ports or via the special nextreg instructions.
Port 0x243B (9275) is used to select the register by number, listed below.
Port 0x253B (9531) is used to read or write the register value.
Some registers are accessible only during the initialization process.
Registers 0x80 and above are inaccessible to the copper.
Initial values are set during a hard or soft reset but may be modified by the operating system.
A hard reset is generated at power on, by the F1 key or via a write to nextreg 0x02 with bit 1 set.
A soft reset is generated by a hard reset, the F4 key or via a write to nextreg 0x02 with bit 0 set.
NEXTREG REGISTER SPACE (Core 3.01.05)
Generally a set bit indicates the property is asserted
0x00 (00) => Machine ID
(R)
00000001 = DE1A
00000010 = DE2A
00000101 = FBLABS
00000110 = VTRUCCO
00000111 = WXEDA
00001000 = EMULATORS *
00001010 = ZX Spectrum Next *
11101010 = ZX Spectrum Next on ZX-DOS fpga platform *
00001011 = Multicore
11111010 = ZX Spectrum Next Anti-brick *
* = Relevant for ZX Next machines & software
0x01 (01) => Core Version
(R)
bits 7:4 = Major version number
bits 3:0 = Minor version number
(see register 0x0E for sub minor version number)
0x02 (02) => Reset
(R)
bit 7 = Indicates the reset signal to the expansion bus and esp is asserted
bits 6:2 = Reserved
bit 1 = Indicates the last reset was a hard reset
bit 0 = Indicates the last reset was a soft reset
* Only one of bits 1:0 will be set
(W)
bit 7 = Assert and hold reset to the expansion bus and the esp wifi (hard reset = 0)
bits 6:2 = Reserved, must be 0
bit 1 = Generate a hard reset (reboot)
bit 0 = Generate a soft reset
* Hard reset has precedence
0x03 (03) => Machine Type
(R)
bit 7 = nextreg 0x44 second byte indicator
bits 6:4 = Display timing
bit 3 = User lock on display timing applied
bits 2-0 = Machine type
(W)
A write to this register disables the bootrom in config mode
bit 7 = 1 to allow changes to bits 6:4
bits 6:4 = Selects display timing (VGA/RGB only)
affects port decoding
000 = Internal Use
001 = ZX 48K display timing
010 = ZX 128K/+2 display timing
011 = ZX +2A/+2B/+3 display timing
100 = Pentagon display timing 50 Hz only
bit 3 = 1 to toggle user lock on display timing (hard reset = 0)
bits 2:0 = Selects machine type (config mode only)
determines roms loaded and multiface type
000 = Configuration mode
001 = ZX 48K
010 = ZX 128K/+2
011 = ZX +2A/+2B/+3
100 = Pentagon
0x04 (04) => Config Mapping (config mode only, bootrom disabled)
(W)
bits 7:5 = Reserved, must be 0
bits 4:0 = 16K SRAM bank mapped to 0x0000-0x3FFF (first 1MB of sram) (hard reset = 0)
0x05 (05) => Peripheral 1 Setting
(R/W)
bits 7:6 = Joystick 1 mode (LSB)
bits 5:4 = Joystick 2 mode (LSB)
bit 3 = Joystick 1 mode (MSB)
bit 2 = 50/60 Hz mode (0 = 50Hz, 1 = 60Hz, Pentagon is always 50Hz)
bit 1 = Joystick 2 mode (MSB)
bit 0 = Enable scandoubler (1 = enabled)
Joystick modes:
000 = Sinclair 2 (12345)
001 = Kempston 1 (port 0x1F)
010 = Cursor (56780)
011 = Sinclair 1 (67890)
100 = Kempston 2 (port 0x37)
101 = MD 1 (3 or 6 button joystick port 0x1F)
110 = MD 2 (3 or 6 button joystick port 0x37)
111 = I/O Mode
Both joysticks are placed in I/O Mode if either is set to I/O Mode. The underlying
joystick type is not changed and reads of this register will continue to return
the last joystick type. Whether the joystick is in io mode or not is invisible
but this state can be cleared either through reset or by re-writing the register
with joystick type not equal to 111. Recovery time for a normal joystick read after
leaving I/O Mode is at most 64 scan lines.
0x06 (06) => Peripheral 2 Setting
(R/W)
bit 7 = Enable F8 cpu speed hotkey (soft reset = 1)
bit 6 = Divert BEEP only to internal speaker (hard reset = 0)
bit 5 = Enable F3 50/60 Hz hotkey (soft reset = 1)
bit 4 = Enable divmmc automap and divmmc nmi by DRIVE button (hard reset = 0)
bit 3 = Enable multiface nmi by M1 button (hard reset = 0)
bit 2 = PS/2 mode (0 = keyboard primary, 1 = mouse primary; config mode only)
bits 1-0 = Audio chip mode (00 = YM, 01 = AY, 11 = Hold all AY in reset)
0x07 (07) => CPU Speed
(R)
bits 7:6 = Reserved
bits 5:4 = Current actual cpu speed
bits 3:2 = Reserved
bits 1:0 = Programmed cpu speed
(W)
bits 7:2 = Reserved, must be 0
bits 1:0 = Set cpu speed (soft reset = 00)
00 = 3.5 MHz
01 = 7 MHz
10 = 14 MHz
11 = 28 MHz
0x08 (08) => Peripheral 3 Setting
(R/W)
bit 7 = Unlock port 0x7ffd (read 1 indicates port 0x7ffd is not locked)
bit 6 = Disable ram and port contention (soft reset = 0)
bit 5 = AY stereo mode (0 = ABC, 1 = ACB) (hard reset = 0)
bit 4 = Enable internal speaker (hard reset = 1)
bit 3 = Enable 8-bit DACs (A,B,C,D) (hard reset = 0)
bit 2 = Enable port 0xff Timex video mode read (hides floating bus on 0xff) (hard reset = 0)
bit 1 = Enable turbosound (currently selected AY is frozen when disabled) (hard reset = 0)
bit 0 = Implement issue 2 keyboard (hard reset = 0)
0x09 (09) => Peripheral 4 Setting
(R/W)
bit 7 = Place AY 2 in mono mode (hard reset = 0)
bit 6 = Place AY 1 in mono mode (hard reset = 0)
bit 5 = Place AY 0 in mono mode (hard reset = 0)
bit 4 = Sprite id lockstep (nextreg 0x34 and port 0x303B are in lockstep) (soft reset = 0)
bit 3 = Reset divmmc mapram bit (port 0xe3 bit 6) (read returns 0)
bit 2 = 1 to silence hdmi audio (hard reset = 0)
bits 1:0 = Scanline weight
00 = scanlines off
01 = scanlines 50%
10 = scanlines 25%
11 = scanlines 12.5%
0x0A (10) => Peripheral 5 Setting
bits 7:3 = Reserved, must be zero
bit 2 = 1 to reverse left and right mouse buttons (hard reset = 0)
bits 1:0 = mouse dpi (hard reset = 01)
00 = low dpi
01 = default
10 = medium dpi
11 = high dpi
0x0E (14) => Core Version (sub minor number)
(R) (see register 0x01 for the major and minor version number)
0x10 (16) => Core Boot
(R)
bits 7:2 = Reserved
bit 1 = Button DRIVE (divmmc) is pressed
bit 0 = Button M1 (multiface) is pressed
(W)
bit 7 = Start selected core
bits 6:5 = Reserved, must be 0
bits 4:0 = Core ID 0-31 (config mode only)
0x11 (17) => Video Timing (writable in config mode only)
(R/W)
bits 7:3 = Reserved, must be 0
bits 2:0 = Mode (VGA = 0..6, HDMI = 7)
000 = Base VGA timing, clk28 = 28000000
001 = VGA setting 1, clk28 = 28571429
010 = VGA setting 2, clk28 = 29464286
011 = VGA setting 3, clk28 = 30000000
100 = VGA setting 4, clk28 = 31000000
101 = VGA setting 5, clk28 = 32000000
110 = VGA setting 6, clk28 = 33000000
111 = HDMI, clk28 = 27000000
* 50/60Hz selection depends on bit 2 of nextreg 0x05
0x12 (18) => Layer 2 Active RAM bank
(R/W)
bit 7 = Reserved, must be 0
bits 6:0 = Starting 16K RAM bank (soft reset = 8)
0x13 (19) => Layer 2 Shadow RAM bank
(R/W)
bit 7 = Reserved, must be 0
bits 6:0 = Starting 16K RAM bank (soft reset = 11)
0x14 (20) => Global Transparency Colour
(R/W)
bits 7:0 = Transparency colour value (soft reset = 0xe3)
* Note: This value is 8-bit, so the transparency colour is compared against
the MSB bits of the final 9-bit colour only.
* Note: This colour only applies to Layer 2, ULA and LoRes.
Sprites use nextreg 0x4B and the tilemap uses nextreg 0x4C for transparency.
0x15 (21) => Sprite and Layers System
(R/W)
bit 7 = Enable lores mode (soft reset = 0)
bit 6 = Sprite priority (1 = sprite 0 on top, 0 = sprite 127 on top) (soft reset = 0)
bit 5 = Enable sprite clipping in over border mode (soft reset = 0)
bits 4:2 = Set layer priority (eg SLU = sprites over layer 2 over ula) (soft reset = 000)
000 - S L U
001 - L S U
010 - S U L
011 - L U S
100 - U S L
101 - U L S
110 - (U|T)S(T|U)(B+L) Blending layer and Layer 2 combined, colours clamped to [0,7]
111 - (U|T)S(T|U)(B+L-5) Blending layer and Layer 2 combined, colours clamped to [0,7]
bit 1 = Enable sprites over border (soft reset = 0)
bit 0 = Enable sprites (soft reset = 0)
0x16 (22) => Layer2 X Scroll LSB
(R/W)
bits 7:0 = X Offset (0-255) (soft reset = 0)
0x17 (23) => Layer2 Y Scroll
(R/W)
bits 7:0 = Y Offset (limited to 0-191 when vertical resolution is 192 pixels) (soft reset = 0)
0x18 (24) => Clip Window Layer 2
(R/W)
bits 7:0 = Clip window coordinate (inclusive)
1st write - X1 position (soft reset = 0)
2nd write - X2 position (soft reset = 255)
3rd write - Y1 position (soft reset = 0)
4rd write - Y2 position (soft reset = 191)
Reads do not advance the clip position
0x19 (25) => Clip Window Sprites
(R/W)
bits 7:0 = Clip window coordinate (inclusive)
1st write - X1 position (soft reset = 0)
2nd write - X2 position (soft reset = 255)
3rd write - Y1 position (soft reset = 0)
4rd write - Y2 position (soft reset = 191)
Reads do not advance the clip position
When the clip window is enabled for sprites in "over border" mode,
the X coords are internally doubled and the clip window origin is
moved to the sprite origin inside the border.
0x1A (26) => Clip Window ULA (and LoRes, see note)
(R/W)
bits 7:0 = Clip window coordinate (inclusive)
1st write = X1 position (soft reset = 0)
2nd write = X2 position (soft reset = 255)
3rd write = Y1 position (soft reset = 0)
4rd write = Y2 position (soft reset = 191)
Reads do not advance the clip position
LoRes may get a separate clip window in the future
0x1B (27) => Clip Window Tilemap
(R/W)
bits 7:0 = Clip window coordinate (inclusive)
1st write = X1 position (soft reset = 0)
2nd write = X2 position (soft reset = 159)
3rd write = Y1 position (soft reset = 0)
4rd write = Y2 position (soft reset = 255)
Reads do not advance the clip position
The X coordinates are internally doubled.
0x1C (28) => Clip Window control
(R) (may change)
bits 7:6 = Tilemap clip index
bits 5:4 = ULA/Lores clip index
bits 3:2 = Sprite clip index
bits 1:0 = Layer 2 clip index
(W) (may change)
bits 7:4 = Reserved, must be 0
bit 3 = Reset the tilemap clip index
bit 2 = Reset the ULA/LoRes clip index
bit 1 = Reset the sprite clip index
bit 0 = Reset the Layer 2 clip index
0x1E (30) => Active video line (MSB)
(R)
bits 7:1 = Reserved
bit 0 = Active line MSB
0x1F (31) => Active video line (LSB)
(R)
bits 7:0 = Active line LSB
0x22 (34) => Line Interrupt control
(R/W)
bit 7 = (R) Indicates if the ula is asserting an interrupt (even if disabled)
bits 7:3 = Reserved, must be 0
bit 2 = Disables ula interrupt (soft reset = 0)
bit 1 = Enables line Interrupt (soft reset = 0)
bit 0 = MSB of line interrupt value (soft reset = 0)
0x23 (35) => Line Interrupt Value LSB
(R/W)
bits 7:0 = Line Interrupt value LSB (soft reset = 0)
0x26 (38) => ULA X Scroll
(R/W)
bits 7:0 = X Offset (0-255) (soft reset = 0)
0x27 (39) => ULA Y Scroll
(R/W)
bits 7:0 = Y Offset (0-191) (soft reset = 0)
0x28 (40) => PS/2 Keymap Address MSB
(R)
bits 7:0 = Stored palette value from nextreg 0x44
(W)
bits 7:1 = Reserved, must be 0
bit 0 = MSB address
0x29 (41) => PS/2 Keymap Address LSB
(W)
bits 7:0 = LSB adress
0x2A (42) => PS/2 Keymap Data MSB
(W)
bits 7:1 = Reserved, must be 0
bit 0 = MSB data
0x2B (43) => PS/2 Keymap Data LSB
(W) (write causes the data to be written and auto-increments the keymap address)
bits 7:0 = LSB data
0x2C (44) => DAC B Mirror (left)
(R)
bits 7:0 = MSB of current I2S (pi) left side sample
the LSB is latched and can be read from nextreg 0x2D later
(W)
bits 7:0 = 8-bit sample written to left side DAC B (soft reset = 0x80)
0x2D (45) => DAC A+D Mirror (mono)
(R)
bits 7:0 = LSB of last I2S (pi) sample read from nextreg 0x2C or nextreg 0x2E
(W)
bits 7:0 = 8-bit sample written to DACs A and D (soft reset = 0x80)
0x2E (46) => DAC C Mirror (right)
(R)
bits 7:0 = MSB of current I2S (pi) right side sample
the LSB is latched and can be read from nextreg 0x2D later
(W)
bits 7:0 = 8-bit sample written to right side DAC C (soft reset = 0x80)
0x2F (47) => Tilemap X Scroll MSB
(R/W)
bits 7:2 = Reserved, must be 0
bits 1:0 = MSB X Offset (soft reset = 0)
Meaningful Range is 0-319 in 40 char mode, 0-639 in 80 char mode
0x30 (48) => Tilemap X Scroll LSB
(R/W)
bits 7:0 = LSB X Offset (soft reset = 0)
Meaningful range is 0-319 in 40 char mode, 0-639 in 80 char mode
0x31 (49) => Tilemap Offset Y
(R/W)
bits 7:0 = Y Offset (0-255) (soft reset = 0)
0x32 (50) => LoRes X Scroll
(R/W)
bits 7:0 = X Offset (0-255) (soft reset = 0)
LoRes scrolls in "half-pixels" at the same resolution and smoothness as Layer 2.
0x33 (51) => LoRes Y Scroll
(R/W)
bits 7:0 = Y Offset (0-191) (soft reset = 0)
LoRes scrolls in "half-pixels" at the same resolution and smoothness as Layer 2.
0x34 (52) => Sprite Number
(R/W)
If the sprite number is in lockstep with port 0x303B (nextreg 0x09 bit 4 is set)
bit 7 = Pattern address offset (add 128 to pattern address)
bits 6:0 = Sprite number 0-127, Pattern number 0-63
Selects which sprite has its attributes connected to the following registers.
Effectively performs an out to port 0x303B with the same value
Otherwise
bit 7 = Ignored
bits 6:0 = Sprite number 0-127
Selects which sprite has its attributes connected to the following registers.
Bit 7 always reads back as zero.
0x35 (53) => Sprite Attribute 0
0x75 (117) => Sprite Attribute 0 with automatic post increment of Sprite Number
(W) See documentation at https://www.specnext.com/sprites/
0x36 (54) => Sprite Attribute 1
0x76 (118) => Sprite Attribute 1 with automatic post increment of Sprite Number
(W) See documentation at https://www.specnext.com/sprites/
0x37 (55) => Sprite Attribute 2
0x77 (119) => Sprite Attribute 2 with automatic post increment of Sprite Number
(W) See documentation at https://www.specnext.com/sprites/
0x38 (56) => Sprite Attribute 3
0x78 (120) => Sprite Attribute 3 with automatic post increment of Sprite Number
(W) See documentation at https://www.specnext.com/sprites/
0x39 (57) => Sprite Attribute 4
0x79 (121) => Sprite Attribute 4 with automatic post increment of Sprite Number
(W) See documentation at https://www.specnext.com/sprites/
0x40 (64) => Palette Index
(R/W)
bits 7:0 = Select the palette index to change the associated colour. (soft reset = 0)
For the ULA only, INKs are mapped to indices 0-7, Bright INKS to indices 8-15,
PAPERs to indices 16-23 and Bright PAPERs to indices 24-31.
In ULANext mode, INKs come from a subset of indices 0-127 and PAPERs come from
a subset of indices 128-255. The number of active indices depends on the number
of attribute bits assigned to INK and PAPER out of the attribute byte.
In ULA+ mode, the top 64 entries hold the ula+ palette.
The ULA always takes border colour from paper for standard ULA and ULAnext.
0x41 (65) => Palette Value (8 bit colour)
(R/W)
bits 7:0 = Colour for the palette index selected by nextreg 0x40.
The format is RRRGGGBB - the lower blue bit of the 9-bit colour will be the logical
OR of blue bits 1 and 0 of this 8-bit value.
After the write, the palette index is auto-incremented to the next index if the
auto-increment is enabled in nextreg 0x43. Reads do not auto-increment.
Any other bits associated with the index will be zeroed.
0x42 (66) => ULANext Attribute Byte Format
(R/W)
bits 7:0 = Mask indicating which bits of an attribute byte are used to represent INK.
Other bits represent PAPER. (soft reset = 0x07)
The mask can only indicate a solid sequence of bits on the right side of an attribute
byte (1, 3, 7, 15, 31, 63, 127 or 255).
INKs are mapped to base index 0 in the palette and PAPERs and border are
mapped to base index 128 in the palette.
The 255 value enables the full ink colour mode making all the palette entries INK.
In this case PAPER and border are both taken from the fallback colour in nextreg 0x4A.
If the mask is not one of those listed above, the INK is taken as the logical AND of
the mask with the attribute byte and the PAPER and border colour are again both taken
from the fallback colour in nextreg 0x4A.
0x43 (67) => Palette Control
(R/W)
bit 7 = Disable palette write auto-increment (soft reset = 0)
bits 6-4 = Select palette for reading or writing (soft reset = 000)
000 = ULA first palette
100 = ULA second palette
001 = Layer 2 first palette
101 = Layer 2 second palette
010 = Sprites first palette
110 = Sprites second palette
011 = Tilemap first palette
111 = Tilemap second palette
bit 3 = Select Sprites palette (0 = first palette, 1 = second palette) (soft reset = 0)
bit 2 = Select Layer 2 palette (0 = first palette, 1 = second palette) (soft reset = 0)
bit 1 = Select ULA palette (0 = first palette, 1 = second palette) (soft reset = 0)
bit 0 = Enabe ULANext mode (soft reset = 0)
0x44 (68) => Palette Value (9 bit colour)
(R/W)
Two consecutive writes are needed to write the 9 bit colour
1st write:
bits 7:0 = RRRGGGBB
2nd write:
bits 7:1 = Reserved, must be 0
bit 0 = lsb B
If writing to an L2 palette
bit 7 = 1 for L2 priority colour, 0 for normal.
An L2 priority colour moves L2 above all layers. If you need the same
colour in both priority and normal modes, you will need to have two
different entries with the same colour one with and one without priority.
After two consecutive writes the palette index is auto-incremented if
auto-increment is enabled in nextreg 0x43.
Reads only return the 2nd byte and do not auto-increment.
0x4A (74) => Fallback Colour
(R/W)
bits 7:0 = 8-bit colour used if all layers are transparent (soft reset = 0xe3)
0x4B (75) => Sprite Transparency Index
(R/W)
bits 7:0 = Sprite colour index treated as transparent (soft reset = 0xe3)
For 4-bit sprites only the bottom 4-bits are used
0x4C (76) => Tilemap Transparency Index
(R/W)
bits 7-4 = Reserved, must be 0
bits 3-0 = Tilemap colour index treated as transparent (soft reset = 0xf)
0x50 (80) => MMU slot 0
(R/W)
bits 7:0 = 8K RAM page occupying address 0x0000 - 0x1FFF (soft reset = 255)
Pages range from 0 to 223 on a fully expanded Next.
A 255 value causes the ROM to become visible.
0x51 (81) => MMU slot 1
(R/W)
bits 7:0 = 8K RAM page occupying address 0x2000 - 0x3FFF (soft reset = 255)
Pages range from 0 to 223 on a fully expanded Next.
A 255 value causes the ROM to become visible.
0x52 (82) => MMU slot 2
(R/W)
bits 7:0 = 8K RAM page occupying address 0x4000 - 0x5FFF (soft reset = 10)
Pages range from 0 to 223 on a fully expanded Next.
0x53 (83) => MMU slot 3
(R/W)
bits 7:0 = 8K RAM page occupying address 0x6000 - 0x7FFF (soft reset = 11)
Pages range from 0 to 223 on a fully expanded Next.
0x54 (84) => MMU slot 4
(R/W)
bits 7:0 = 8K RAM page occupying address 0x8000 - 0x9FFF (soft reset = 4)
Pages range from 0 to 223 on a fully expanded Next.
0x55 (85) => MMU slot 5
(R/W)
bits 7:0 = 8K RAM page occupying address 0xA000 - 0xBFFF (soft reset = 5)
Pages range from 0 to 223 on a fully expanded Next.
0x56 (86) => MMU slot 6
(R/W)
bits 7:0 = 8K RAM page occupying address 0xC000 - 0xDFFF (soft reset = 0)
Pages range from 0 to 223 on a fully expanded Next.
0x57 (87) => MMU slot 7
(R/W)
bits 7:0 = 8K RAM page occupying address 0xE000 - 0xFFFF (soft reset = 1)
Pages range from 0 to 223 on a fully expanded Next.
0x60 (96) => Copper Data 8-bit Write
(W)
bits 7:0 = Byte to write to copper instruction memory
Note that each copper instruction is two bytes long
After a write, the copper address is auto-incremented to the next memory position
0x61 (97) => Copper Address LSB
(R/W)
bits 7:0 = Copper instruction memory address LSB (soft reset = 0)
(Copper addresses range over 0 - 0x7FF = 2K)
0x62 (98) => Copper Control
(R/W)
bits 7:6 = Start control (soft reset = 00)
00 = Copper fully stopped
01 = Copper start, execute the list from index 0, and loop to the start
10 = Copper start, execute the list from last point, and loop to the start
11 = Copper start, execute the list from index 0, and restart the list
when the raster reaches position (0,0)
bits 2:0 = Copper instruction memory address MSB (soft reset = 0)
(Copper addresses range over 0 - 0x7FF = 2K)
Writing the same start control value does not reset the copper
0x63 (99) => Copper Data 16-bit Write
(W)
The 16-bit value is written in pairs. The first 8-bits are the MSB and
are destined for an even copper instruction address. The second 8-bits are
the LSB and are destined for an odd copper instruction address.
After each write, the copper address is auto-incremented to the next memory position
After a write to an odd address, the entire 16-bits is written to copper memory at once
0x64 (100) => Vertical Line Count Offset
(R/W)
bits 7:0 = Offset added to the vertical line counter affects copper, line interrupt and active line count.
Normally the ula's pixel row 0 aligns with vertical line count 0. With a non-zero
offset, the ula's pixel row 0 will align with the vertical line offset. Eg, if the offset is 32
then vertical line 32 will correspond to the first pixel row in the ula and vertical line 0
will align with the first pixel row of the tilemap and sprites.
* Since a change in offset takes effect when the ula reaches row 0, the change can take up to
one frame to occur.
0x68 (104) => ULA Control
(R/W)
bit 7 = Disable ULA output (soft reset = 0)
bits 6:5 = Blending in SLU modes 6 & 7 (soft reset = 0)
= 00 for ula as blend colour
= 10 for ula/tilemap mix result as blend colour
= 11 for tilemap as blend colour
= 01 for no blending
bit 4 = Cancel entries in 8x5 matrix for extended keys
bit 3 = ULA+ enable (soft reset = 0)
bit 2 = ULA half pixel scroll (may change) (soft reset = 0)
bit 1 = Reserved, must be 0
bit 0 = Enable stencil mode when both the ULA and tilemap are enabled (soft reset = 0)
(if either are transparent the result is transparent otherwise the result is a logical AND of both colours)
0x69 (105) => Display Control 1
(R/W)
bit 7 = Enable layer 2 (alias port 0x123B bit 1)
bit 6 = Enable ULA shadow display (alias port 0x7FFD bit 3)
bits 5:0 = Port 0xFF bits 5:0 alias (Timex display modes)
0x6A (106) => LoRes Control
(R/W)
bits 7-6 = Reserved, must be 0
bit 5 = LoRes is Radastan mode (128x96x4, 6144 bytes) (soft reset = 0)
bit 4 = LoRes Radastan timex display file xor (soft reset = 0)
bits 3:0 = LoRes palette offset (bits 1:0 apply in ula+ mode) (soft reset = 0)
0x6B (107) => Tilemap Control
(R/W)
bit 7 = 1 Enable the tilemap (soft reset = 0)
bit 6 = 0 for 40x32, 1 for 80x32 (soft reset = 0)
bit 5 = Eliminate the attribute entry in the tilemap (soft reset = 0)
bit 4 = Palette select (soft reset = 0)
bit 3 = Select textmode (soft reset = 0)
bit 2 = Reserved, must be 0
bit 1 = Activate 512 tile mode (soft reset = 0)
bit 0 = Force tilemap on top of ULA (soft reset = 0)
0x6C (108) => Default Tilemap Attribute
(R/W)
Active if nextreg 0x6B bit 5 is set
bits 7:4 = Palette offset (soft reset = 0)
bit 3 = X mirror (soft reset = 0)
bit 2 = Y mirror (soft reset = 0)
bit 1 = Rotate (soft reset = 0)
bit 0 = ULA over tilemap (soft reset = 0)
(or bit 8 of the tile number if 512 tile mode is enabled)
0x6E (110) => Tilemap Base Address
(R/W) (soft reset = 0x6c00)
bits 7:6 = Read back as zero, write values ignored
bits 5:0 = MSB of address of the tilemap in Bank 5
The value written is an offset into Bank 5 allowing the tilemap to be placed
at any multiple of 256 bytes.
Writing a physical MSB address in 0x40-0x7f or 0xc0-0xff range is permitted.
The value read back should be treated as having a fully significant 8-bit value.
0x6F (111) => Tile Definitions Base Address
(R/W) (soft reset = 0x4c00)
bits 7:6 = Read back as zero, write values ignored
bits 5:0 = MSB of address of tile definitions in Bank 5
The value written is an offset into Bank 5 allowing tile definitions to be placed
at any multiple of 256 bytes.
Writing a physical MSB address in 0x40-0x7f or 0xc0-0xff range is permitted.
The value read back should be treated as having a fully significant 8-bit value.
0x70 (112) => Layer 2 Control
(R/W)
bits 7:6 = Reserved, must be 0
bits 5:4 = Layer 2 resolution (soft reset = 0)
00 = 256x192x8
01 = 320x256x8
10 = 640x256x4
bits 3:0 = Palette offset (soft reset = 0)
0x71 (113) => Layer 2 X Scroll MSB
(R/W)
bits 7:1 = Reserved, must be 0
bit 0 = MSB of scroll amount
0x75 (117) => Sprite Attribute 0 with automatic post increment of Sprite Number
(W) see nextreg 0x35
0x76 (118) => Sprite Attribute 1 with automatic post increment of Sprite Number
(W) see nextreg 0x36
0x77 (119) => Sprite Attribute 2 with automatic post increment of Sprite Number
(W) see nextreg 0x37
0x78 (120) => Sprite Attribute 3 with automatic post increment of Sprite Number
(W) see nextreg 0x38
0x79 (121) => Sprite Attribute 4 with automatic post increment of Sprite Number
(W) see nextreg 0x39
0x7F (127) => User Register 0
(R/W)
bits 7:0 = Unused storage available to the user (soft reset = 0xff)
NEXTREG 0x80 AND HIGHER ARE INACCESSIBLE TO THE COPPER
0x80 (128) => Expansion Bus Enable
(R/W) (hard reset = 0)
IMMEDIATE
bit 7 = 1 to enable the expansion bus
bit 6 = 1 to enable romcs rom replacement from divmmc banks 14/15
bit 5 = 1 to disable i/o cycles & ignore iorqula
bit 4 = 1 to disable memory cycles & ignore romcs
AFTER SOFT RESET (copied into bits 7-4)
bit 3 = 1 to enable the expansion bus
bit 2 = 1 to enable romcs rom replacement from divmmc banks 14/15
bit 1 = 1 to disable i/o cycles & ignore iorqula
bit 0 = 1 to disable memory cycles & ignore romcs
0x81 (129) => Expansion Bus Control
(R/W) (hard reset = 0)
bit 7 = 1 if ROMCS is asserted on the expansion bus (read only)
bit 4 = 1 to propagate the max cpu clock at all times including when the expansion bus is off
bits 1-0 = max cpu speed when the expansion bus is on (currently fixed at 00 = 3.5MHz)
0x85,0x84,0x83,0x82 (133-130) => Internal Port Decoding Enables (0x85 is MSB) (soft reset if bit 31 = 1, hard reset if bit 31 = 0 : all 1)
0x89,0x88,0x87,0x86 (137-134) => Expansion Bus Decoding Enables (0x89 is MSB) (soft reset if bit 31 = 0, hard reset if bit 31 = 1 : all 1)
(R/W)
bit 0 = port ff
bit 1 = port 7ffd
bit 2 = port dffd
bit 3 = port 1ffd
bit 4 = +3 floating bus
bit 5 = port 6b zxn dma
bit 6 = port 1f kempston / md1
bit 7 = port 37 kempston 2 / md2 / joystick control
-----
bit 8 = port e3 divmmc control
bit 9 = multiface (two variable ports)
bit 10 = port 103b,113b i2c
bit 11 = port e7,eb spi
bit 12 = port 133b,143b,153b uart
bit 13 = port fadf,fbdf,ffdf mouse
bit 14 = port 57,5b,303b sprites
bit 15 = port 123b layer2
-----
bit 16 = port fffd,bffd ay
bit 17 = port 0f,1f,4f,5f dac soundrive mode 1
bit 18 = port f1,f3,f9,fb dac soundrive mode 2
bit 19 = port 3f,5f dac stereo profi covox
bit 20 = port 0f,4f dac stereo covox
bit 21 = port fb dac mono pentagon/atm (sd mode 2 off)
bit 22 = port b3 dac mono gs covox
bit 23 = port df dac mono specdrum
-----
bit 24 = port bf3b, ff3b ula+
bit 25 = port 0b z80 dma
...
bit 31 = register reset mode (soft or hard reset selection)
-----
The internal port decoding enables always apply.
When the expansion bus is on, the expansion port decoding enables are logically ANDed with the internal enables.
A zero bit indicates the internal device is disabled. If the expansion bus is on, this allows io cycles for
disabled ports to propagate to the expansion bus, otherwise corresponding io cycles to the expansion bus are filtered.
0x8A (138) => Expansion Bus IO Propagate
(R/W)
bits 7:5 = Reserved, must be 0
bit 4 = Propagate port 0xff io cycles (hard reset = 0)
bit 3 = Propagate port 0x1ffd io cycles (hard reset = 0)
bit 2 = Propagate port 0xdffd io cycles (hard reset = 0)
bit 1 = Propagate port 0x7ffd io cycles (hard reset = 0)
bit 0 = Propagare port 0xfe io cycles (hard reset = 0)
If any of the bits are set, io cycles for the corresponding ports are propagated to the expansion bus when
the expansion bus is on. If the internal port decode is still active, any response sent by devices on the
expansion bus will be ignored. The purpose here is to allow external peripherals to monitor changes in state
inside the zx next.
Port 0xfe is treated specially so that external keyboards can be attached. When its propagate bit is set,
the value read from the bus will be mixed into keyboard reads on port 0xfe.
0x8C (140) => Alternate ROM
(R/W) (hard reset = 0)
IMMEDIATE
bit 7 = 1 to enable alt rom
bit 6 = 1 to make alt rom visible only during writes, otherwise replaces rom during reads
bit 5 = 1 to lock ROM1 (48K rom)
bit 4 = 1 to lock ROM0 (128K rom)
AFTER SOFT RESET (copied into bits 7-4)
bit 3 = 1 to enable alt rom
bit 2 = 1 to make alt rom visible only during writes, otherwise replaces rom during reads
bit 1 = 1 to lock ROM1 (48K rom)
bit 0 = 1 to lock ROM0 (128K rom)
The locking mechanism also applies if the alt rom is not enabled. For the +3 and zx next, if the two lock bits are not
zero, then the corresponding rom page is locked in place. Other models use the bits to preferentially lock the corresponding
48K rom or the 128K rom.
0x8E (142) => Spectrum Memory Mapping
(R/W)
bit 7 = port 0xdffd bit 0 \ RAM
bits 6:4 = port 0x7ffd bits 2:0 / bank 0-15
R bit 3 = 1
W bit 3 = 1 to change RAM bank, 0 = no change to mmu6 / mmu7 / RAM bank in ports 0x7ffd, 0xdffd
bit 2 = port 0x1ffd bit 0 paging mode
If bit 2 = paging mode = 0 (normal)
bit 1 = port 0x1ffd bit 2 \ ROM
bit 0 = port 0x7ffd bit 4 / select
If bit 2 = paging mode = 1 (special allRAM)
bit 1 = port 0x1ffd bit 2 \ all
bit 0 = port 0x1ffd bit 1 / RAM
Writes can affect all ports 0x7ffd, 0xdffd, 0x1ffd
Writes always change the ROM / allRAM mapping
Writes immediately change the current mmu mapping as if by port write
0x93,0x92,0x91,0x90 (147-144) => PI GPIO Output Enable (0x93 is MSB)
(R/W)
bits 27:0 Set bits enable GPIO output on the corresponding GPIO pin (soft reset = all 0)
(GPIO pins 1:0 cannot be enabled)
0x9B,0x9A,0x99,0x98 (155-152) => PI GPIO (0x9B is MSB)
(R/W)
bits 27:0 Read / Write the GPIO pin state (soft reset = 0x00001ff)
(writes only propagate when the corresponding pin has its output enabled)
0xA0 (160) => PI Peripheral Enable
(R/W)
bits 7:6 = Reserved, must be 0
bit 5 = Enable UART on GPIO 14,15 (overrides gpio) (soft reset = 0)
bit 4 = 0 to connect Rx to GPIO 15, Tx to GPIO 14 (for comm with pi hats) (soft reset = 0)
= 1 to connect Rx to GPIO 14, Tx to GPIO 15 (for comm with pi)
bit 3 = Enable I2C on GPIO 2,3 (override gpio) (soft reset = 0)
bits 2:1 = Reserved, must be 0
bit 0 = Enable SPI on GPIO 7,8,9,10,11 (overrides gpio) (soft reset = 0)
0xA2 (162) => PI I2S Audio Control
(R/W)
bits 7:6 = I2S enable (soft reset = 00)
00 = i2s off
01 = i2s is mono source right
10 = i2s is mono source left
11 = i2s is stereo
bit 5 = Reserved, must be 0
bit 4 = 0 PCM_DOUT to pi, PCM_DIN from pi (hats) (soft reset = 0)
= 1 PCM_DOUT from pi, PCM_DIN to pi (pi)
bit 3 = Mute left side (soft reset = 0)
bit 2 = Mute right side (soft reset = 0)
//bit 1 = Slave mode (PCM_CLK, PCM_FS supplied externally) (soft reset = 0)
bit 1 = Reserved must be 1
bit 0 = Direct i2s audio to EAR on port 0xFE (soft reset = 0)
// 0xA3 (163) => PI I2S Clock Divide (Master Mode)
// (R/W)
// bits 7:0 = Clock divide sets sample rate when in master mode (soft reset = 11)
// clock divider = 538461 / SampleRateHz - 1
0xA8 (168) => ESP Wifi GPIO Output Enable
(R/W) (soft reset = 0)
bit 2 = GPIO2 output enable (fixed at 0, GPIO2 is read-only)
bit 0 = GPIO0 output enable
0xA9 (169) => ESP Wifi GPIO
(R/W)
bit 2 = Read / Write ESP GPIO2 (soft reset = 1)
bit 0 = Read / Write ESP GPIO0 (soft reset = 1)
0xB0 (176) => EXTENDED KEYS 0
bit 7 = 1 if ; pressed
bit 6 = 1 if " pressed
bit 5 = 1 if , pressed
bit 4 = 1 if . pressed
bit 3 = 1 if UP pressed
bit 2 = 1 if DOWN pressed
bit 1 = 1 if LEFT pressed
bit 0 = 1 if RIGHT pressed
0xB1 (177) => EXTENDED KEYS 1
bit 7 = 1 if DELETE pressed
bit 6 = 1 if EDIT pressed
bit 5 = 1 if BREAK pressed
bit 4 = 1 if INV VIDEO pressed
bit 3 = 1 if TRUE VIDEO pressed
bit 2 = 1 if GRAPH pressed
bit 1 = 1 if CAPS LOCK pressed
bit 0 = 1 if EXTEND pressed
0xFF (255) => Reserved for internal use
-----------------------------------------
-- memory decode order
--
-- 0-16k:
-- 1. bootrom
-- 2. machine config mapping
-- 3. multiface
-- 4. divmmc
-- 5. layer 2 mapping
-- 6. mmu
-- 7. romcs expansion bus
-- 8. rom
--
-- 16k-48k:
-- 1. layer 2 mapping
-- 2. mmu
--
-- 48k-64k:
-- 1. mmu