-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathl2scroller.lst
1149 lines (1149 loc) · 65.4 KB
/
l2scroller.lst
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
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# file opened: ./src/main.asm
1 0000 SLDOPT COMMENT WPMEM, LOGPOINT, ASSERTION
2 0000 DEVICE ZXSPECTRUMNEXT
3 0000 CSPECTMAP "l2scroller.map"
4 0000
5 0000 ;------------------------------------------------------------------------------
6 0000 ; Layer2 SCROLLER v2 - Scroller on Layer2 via COPPER & DMA copy
7 0000 ; em00k 17.03.24
8 0000
9 0000 org $8000
10 8000
11 8000 ;------------------------------------------------------------------------------
12 8000 ; Includes
13 8000
14 8000 include "hardware.inc" ; hardare equates and ports
# file opened: ./src/hardware.inc
1+ 8000 BIT_UP equ 4 ; 16
2+ 8000 BIT_DOWN equ 5 ; 32
3+ 8000 BIT_LEFT equ 6 ; 64
4+ 8000 BIT_RIGHT equ 7 ; 128
5+ 8000
6+ 8000 DIR_NONE equ %00000000
7+ 8000 DIR_UP equ %00010000
8+ 8000 DIR_DOWN equ %00100000
9+ 8000 DIR_LEFT equ %01000000
10+ 8000 DIR_RIGHT equ %10000000
11+ 8000
12+ 8000 DIR_UP_I equ %11101111
13+ 8000 DIR_DOWN_I equ %11011111
14+ 8000 DIR_LEFT_I equ %10111111
15+ 8000 DIR_RIGHT_I equ %01111111
16+ 8000
17+ 8000 ;-----------------------------------------------------------------------------
18+ 8000 ;-- I/O ports - ZX Spectrum classic (48, 128, Timex, Pentagon, ...) ports
19+ 8000
20+ 8000 ULA_P_FE equ $FE ; BORDER + MIC + BEEP + read Keyboard
21+ 8000 TIMEX_P_FF equ $FF ; Timex video control port
22+ 8000
23+ 8000 ZX128_MEMORY_P_7FFD equ $7FFD ; ZX Spectrum 128 ports
24+ 8000 ZX128_MEMORY_P_DFFD equ $DFFD
25+ 8000 ZX128P3_MEMORY_P_1FFD equ $1FFD
26+ 8000
27+ 8000 AY_REG_P_FFFD equ $FFFD
28+ 8000 AY_DATA_P_BFFD equ $BFFD
29+ 8000
30+ 8000 Z80_DMA_PORT_DATAGEAR equ $6B ; on ZXN the zxnDMA handles this in zxnDMA mode
31+ 8000 Z80_DMA_PORT_MB02 equ $0B ; on ZXN the zxnDMA handles this in Zilog mode
32+ 8000
33+ 8000 DIVMMC_CONTROL_P_E3 equ $E3
34+ 8000 SPI_CS_P_E7 equ $E7
35+ 8000 SPI_DATA_P_EB equ $EB
36+ 8000
37+ 8000 KEMPSTON_MOUSE_X_P_FBDF equ $FBDF
38+ 8000 KEMPSTON_MOUSE_Y_P_FFDF equ $FFDF
39+ 8000 KEMPSTON_MOUSE_B_P_FADF equ $FADF ; kempston mouse wheel+buttons
40+ 8000
41+ 8000 KEMPSTON_JOY1_P_1F equ $1F
42+ 8000 KEMPSTON_JOY2_P_37 equ $37
43+ 8000
44+ 8000 ;-----------------------------------------------------------------------------
45+ 8000 ;-- I/O ports - ZX Spectrum NEXT specific ports
46+ 8000
47+ 8000 TBBLUE_REGISTER_SELECT_P_243B equ $243B
48+ 8000 ; -- port $243B = 9275 Read+Write (detection bitmask: %0010_0100_0011_1011)
49+ 8000 ; -- selects NextREG mapped at port TBBLUE_REGISTER_ACCESS_P_253B
50+ 8000
51+ 8000 TBBLUE_REGISTER_ACCESS_P_253B equ $253B
52+ 8000 ; -- port $253B = 9531 Read?+Write? (detection bitmask: %0010_0101_0011_1011)
53+ 8000 ; -- data for selected NextREG (read/write depends on the register selected)
54+ 8000
55+ 8000 ; indexes into DAC_CHANNEL_* def-arrays, depending on the type of DAC you want to use
56+ 8000 DAC_GS_COVOX_INDEX equ 1
57+ 8000 DAC_PENTAGON_ATM_INDEX equ 2
58+ 8000 DAC_SPECDRUM_INDEX equ 3
59+ 8000 DAC_SOUNDRIVE1_INDEX equ 4
60+ 8000 DAC_SOUNDRIVE2_INDEX equ 5
61+ 8000 DAC_COVOX_INDEX equ 6
62+ 8000 DAC_PROFI_COVOX_INDEX equ 7
63+ 8000 ; -- enable 8bit DACs with PERIPHERAL_3_NR_08, use DAC_*_INDEX to access particular set of ports
64+ 8000 ;DEFARRAY DAC_CHANNEL_A @@, @@, $FB, $DF, $1F, $F1, @@, $3F
65+ 8000 ;DEFARRAY DAC_CHANNEL_B @@, $B3, @@, @@, $0F, $F3, $0F, @@
66+ 8000 ;DEFARRAY DAC_CHANNEL_C @@, $B3, @@, @@, $4F, $F9, $4F, @@
67+ 8000 ;DEFARRAY DAC_CHANNEL_D @@, @@, $FB, $DF, $5F, $FB, @@, $5F
68+ 8000 ; -- like for example: ld bc,DAC_CHANNEL_B[DAC_PROFI_COVOX_INDEX]
69+ 8000
70+ 8000 I2C_SCL_P_103B equ $103B ; i2c bus port (clock) (write only?)
71+ 8000 I2C_SDA_P_113B equ $113B ; i2c bus port (data) (read+write)
72+ 8000 UART_TX_P_133B equ $133B ; UART tx port (read+write)
73+ 8000 UART_RX_P_143B equ $143B ; UART rx port (read+write)
74+ 8000 UART_CTRL_P_153B equ $153B ; UART control port (read+write)
75+ 8000
76+ 8000 ZILOG_DMA_P_0B equ $0B
77+ 8000 ZXN_DMA_P_6B equ $6B
78+ 8000 ; -- port $6B = 107 Read+Write (detection bitmask: %xxxx_xxxx_0110_1011)
79+ 8000 ; - The zxnDMA is mostly compatible with Zilog DMA chip (Z8410) (at least
80+ 8000 ; as far as old ZX apps are concerned), but has many modifications.
81+ 8000 ; - core3.1.1 update - Zilog/zxnDMA mode is now selected by port number, not PERIPHERAL_2_NR_06!
82+ 8000 ; - core3.0 update - (REMOVED) specific behaviour details can be selected (PERIPHERAL_2_NR_06)
83+ 8000
84+ 8000 LAYER2_ACCESS_P_123B equ $123B
85+ 8000 ; -- port $123B = 4667 Read+Write (detection bitmask: %0001_0010_0011_1011)
86+ 8000 ; - see ports.txt or wiki for details (has become a bit more complex over time)
87+ 8000
88+ 8000 LAYER2_ACCESS_WRITE_OVER_ROM equ $01 ; map Layer2 bank into ROM area (0000..3FFF) for WRITE-only (reads as ROM)
89+ 8000 LAYER2_ACCESS_L2_ENABLED equ $02 ; enable Layer2 (make banks form nextreg $12 visible)
90+ 8000 LAYER2_ACCESS_READ_OVER_ROM equ $04 ; map Layer2 bank into ROM area (0000..3FFF) for READ-only
91+ 8000 LAYER2_ACCESS_SHADOW_OVER_ROM equ $08 ; bank selected by bits 6-7 is from "shadow Layer 2" banks range (nextreg $13)
92+ 8000 LAYER2_ACCESS_BANK_OFFSET equ $10 ; bit 2-0 is bank offset for current active mapping +0..+7 (other bits are reserved, use 0)
93+ 8000 LAYER2_ACCESS_OVER_ROM_BANK_M equ $C0 ; (mask of) value 0..3 selecting bank mapped for R/W (Nextreg $12 or $13)
94+ 8000 LAYER2_ACCESS_OVER_ROM_BANK_0 equ $00 ; screen lines 0..63 (256x192) or columns 0..63 (320x256) or columns 0..127 (640x256)
95+ 8000 LAYER2_ACCESS_OVER_ROM_BANK_1 equ $40 ; screen lines 64..127 (256x192) or columns 64..127 (320x256) or columns 128..255 (640x256)
96+ 8000 LAYER2_ACCESS_OVER_ROM_BANK_2 equ $80 ; screen lines 128..191 (256x192) or columns 128..191 (320x256) or columns 256..383 (640x256)
97+ 8000 LAYER2_ACCESS_OVER_ROM_48K equ $C0 ; maps all 0..191 lines into $0000..$BFFF region (256x192) or 2/3 of columns in 320x256/640x256
98+ 8000
99+ 8000 SPRITE_STATUS_SLOT_SELECT_P_303B equ $303B
100+ 8000 ; -- port $303B = 12347 Read+Write (detection bitmask: %0011_0000_0011_1011)
101+ 8000 ; -- write:
102+ 8000 ; - sets both "sprite slot" (0..63) and "pattern slot" (0..63 +128)
103+ 8000 ; - once the sprite/pattern slots are set, they act independently and
104+ 8000 ; each port ($xx57 and $xx5B) will auto-increment its own slot index
105+ 8000 ; (to resync one can write to this port again).
106+ 8000 ; - the +128 flag will make the pattern upload start at byte 128 of pattern
107+ 8000 ; slot (second half of slot)
108+ 8000 ; - The sprite-slot (sprite-attributes) may be optionally interlinked with
109+ 8000 ; NextReg $34 (feature controlled by NextReg $34)
110+ 8000 ; - auto-increments of slot position from value 63 are officially
111+ 8000 ; "undefined behaviour", wrap to 0 is not guaranteed. (only setting slots
112+ 8000 ; explicitly back to valid 0..63 will make your code future-proof)
113+ 8000 ; -- read (will also reset both collision and max-sprites flags):
114+ 8000 ; - bit 1 = maximum sprites per line hit (set when sprite renderer ran
115+ 8000 ; out of time when preparing next scanline)
116+ 8000 ; - bit 0 = collision flag (set when any sprites draw non-transparent
117+ 8000 ; pixel at the same location)
118+ 8000 ; Both flags contain values for current scanline already at the beginning
119+ 8000 ; of scanline (sprite engine renders one line ahead into buffer and updates
120+ 8000 ; flags progressively as it renders the sprites)
121+ 8000 SPRITE_STATUS_MAXIMUM_SPRITES equ $02
122+ 8000 SPRITE_STATUS_COLLISION equ $01
123+ 8000 SPRITE_SLOT_SELECT_PATTERN_HALF equ 128 ; add it to 0..63 index to make pattern upload start at second half of pattern
124+ 8000
125+ 8000 SPRITE_ATTRIBUTE_P_57 equ $57
126+ 8000 ; -- port $xx57 = 87 write-only (detection bitmask: %xxxx_xxxx_0101_0111)
127+ 8000 ; - writing 4 or 5 bytes long structures to control particular sprite
128+ 8000 ; - after 4/5 bytes block the sprite slot index is auto-incremented
129+ 8000 ; - for detailed documentation check official docs or wiki (too long)
130+ 8000
131+ 8000 SPRITE_PATTERN_P_5B equ $5B
132+ 8000 ; -- port $xx5B = 91 write-only (detection bitmask: %xxxx_xxxx_0101_1011)
133+ 8000 ; - each pattern slot is 256 bytes long = one 16x16 pattern of 8-bit pixels
134+ 8000 ; or two 16x16 patterns of 4-bit pixels.
135+ 8000 ; - Patterns are uploaded in "English" order (left to right, top to bottom),
136+ 8000 ; one byte encodes single pixel in 8 bit mode and two pixels in 4 bit
137+ 8000 ; mode (bits 7-4 are "left" pixel, 3-0 are "right" pixel)
138+ 8000 ; - pixels are offset (index) into active sprite palette
139+ 8000
140+ 8000 TURBO_SOUND_CONTROL_P_FFFD equ $FFFD ; write with bit 7 = 1 (port shared with AY)
141+ 8000
142+ 8000 ;-----------------------------------------------------------------------------
143+ 8000 ;-- NEXT HW Registers (NextReg)
144+ 8000 MACHINE_ID_NR_00 equ $00
145+ 8000 NEXT_VERSION_NR_01 equ $01
146+ 8000 NEXT_RESET_NR_02 equ $02
147+ 8000 MACHINE_TYPE_NR_03 equ $03
148+ 8000 ROM_MAPPING_NR_04 equ $04 ;In config mode, allows RAM to be mapped to ROM area.
149+ 8000 PERIPHERAL_1_NR_05 equ $05 ;Sets joystick mode, video frequency and Scandoubler.
150+ 8000 PERIPHERAL_2_NR_06 equ $06 ;Enables turbo/50Hz/60Hz keys, DivMMC, Multiface and audio (beep/AY)
151+ 8000 TURBO_CONTROL_NR_07 equ $07
152+ 8000 PERIPHERAL_3_NR_08 equ $08 ;ABC/ACB Stereo, Internal Speaker, SpecDrum, Timex Video Modes, Turbo Sound Next, RAM contention and [un]lock 128k paging.
153+ 8000 PERIPHERAL_4_NR_09 equ $09 ;Sets scanlines, AY mono output, Sprite-id lockstep, disables Kempston and divMMC ports.
154+ 8000 PERIPHERAL_5_NR_0A equ $0A ;Mouse buttons and DPI settings (core 3.1.5)
155+ 8000 NEXT_VERSION_MINOR_NR_0E equ $0E
156+ 8000 ANTI_BRICK_NR_10 equ $10
157+ 8000 VIDEO_TIMING_NR_11 equ $11
158+ 8000 LAYER2_RAM_BANK_NR_12 equ $12 ;bank number where visible Layer 2 video memory begins.
159+ 8000 LAYER2_RAM_SHADOW_BANK_NR_13 equ $13 ;bank number for "shadow" write-over-rom mapping
160+ 8000 GLOBAL_TRANSPARENCY_NR_14 equ $14 ;Sets the color treated as transparent for ULA/Layer2/LoRes
161+ 8000 SPRITE_CONTROL_NR_15 equ $15 ;LoRes mode, Sprites configuration, layers priority
162+ 8000 ; bit 7: enable LoRes mode
163+ 8000 ; bit 6: sprite rendering (1=sprite 0 on top of other, 0=sprite 0 at bottom)
164+ 8000 ; bit 5: If 1, the clipping works even in "over border" mode
165+ 8000 ; 4-2: layers priority: 000=SLU, 001=LSU, 010=SUL, 011=LUS, 100=USL, 101=ULS, 110=S,mix(U+L), 111=S,mix(U+L-5)
166+ 8000 ; bit 1: enable sprites over border, bit 0: show sprites
167+ 8000 LAYER2_XOFFSET_NR_16 equ $16
168+ 8000 LAYER2_YOFFSET_NR_17 equ $17
169+ 8000 CLIP_LAYER2_NR_18 equ $18
170+ 8000 CLIP_SPRITE_NR_19 equ $19
171+ 8000 CLIP_ULA_LORES_NR_1A equ $1A
172+ 8000 CLIP_TILEMAP_NR_1B equ $1B
173+ 8000 CLIP_WINDOW_CONTROL_NR_1C equ $1C ;set to 15 to reset all clip-window indices to 0
174+ 8000 VIDEO_LINE_MSB_NR_1E equ $1E
175+ 8000 VIDEO_LINE_LSB_NR_1F equ $1F
176+ 8000 VIDEO_INTERUPT_CONTROL_NR_22 equ $22 ;Controls the timing of raster interrupts and the ULA frame interrupt.
177+ 8000 VIDEO_INTERUPT_VALUE_NR_23 equ $23
178+ 8000 ULA_XOFFSET_NR_26 equ $26 ;since core 3.0
179+ 8000 ULA_YOFFSET_NR_27 equ $27 ;since core 3.0
180+ 8000 HIGH_ADRESS_KEYMAP_NR_28 equ $28 ;reads first 8b part of value written to $44 (even unfinished 16b write)
181+ 8000 LOW_ADRESS_KEYMAP_NR_29 equ $29
182+ 8000 HIGH_DATA_TO_KEYMAP_NR_2A equ $2A
183+ 8000 LOW_DATA_TO_KEYMAP_NR_2B equ $2B
184+ 8000 DAC_B_MIRROR_NR_2C equ $2C ;reads as MSB of Pi I2S left side sample, LSB waits at $2D
185+ 8000 DAC_AD_MIRROR_NR_2D equ $2D ;another alias for $2D, reads LSB of value initiated by $2C or $2E read
186+ 8000 SOUNDDRIVE_DF_MIRROR_NR_2D equ $2D ;Nextreg port-mirror of port 0xDF
187+ 8000 DAC_C_MIRROR_NR_2E equ $2E ;reads as MSB of Pi I2S right side sample, LSB waits at $2D
188+ 8000 TILEMAP_XOFFSET_MSB_NR_2F equ $2F
189+ 8000 TILEMAP_XOFFSET_LSB_NR_30 equ $30
190+ 8000 TILEMAP_YOFFSET_NR_31 equ $31
191+ 8000 LORES_XOFFSET_NR_32 equ $32
192+ 8000 LORES_YOFFSET_NR_33 equ $33
193+ 8000 SPRITE_ATTR_SLOT_SEL_NR_34 equ $34 ;Sprite-attribute slot index for $35-$39/$75-$79 port $57 mirrors
194+ 8000 SPRITE_ATTR0_NR_35 equ $35 ;port $57 mirror in nextreg space (accessible to copper)
195+ 8000 SPRITE_ATTR1_NR_36 equ $36
196+ 8000 SPRITE_ATTR2_NR_37 equ $37
197+ 8000 SPRITE_ATTR3_NR_38 equ $38
198+ 8000 SPRITE_ATTR4_NR_39 equ $39
199+ 8000 PALETTE_INDEX_NR_40 equ $40 ;Chooses a ULANext palette number to configure.
200+ 8000 PALETTE_VALUE_NR_41 equ $41 ;Used to upload 8-bit colors to the ULANext palette.
201+ 8000 PALETTE_FORMAT_NR_42 equ $42 ;ink-mask for ULANext modes
202+ 8000 PALETTE_CONTROL_NR_43 equ $43 ;Enables or disables ULANext interpretation of attribute values and toggles active palette.
203+ 8000 PALETTE_VALUE_9BIT_NR_44 equ $44 ;Holds the additional blue color bit for RGB333 color selection.
204+ 8000 TRANSPARENCY_FALLBACK_COL_NR_4A equ $4A ;8-bit colour to be drawn when all layers are transparent
205+ 8000 SPRITE_TRANSPARENCY_I_NR_4B equ $4B ;index of transparent colour in sprite palette (only bottom 4 bits for 4-bit patterns)
206+ 8000 TILEMAP_TRANSPARENCY_I_NR_4C equ $4C ;index of transparent colour in tilemap graphics (only bottom 4 bits)
207+ 8000 MMU0_0000_NR_50 equ $50 ;Set a Spectrum RAM page at position 0x0000 to 0x1FFF
208+ 8000 MMU1_2000_NR_51 equ $51 ;Set a Spectrum RAM page at position 0x2000 to 0x3FFF
209+ 8000 MMU2_4000_NR_52 equ $52 ;Set a Spectrum RAM page at position 0x4000 to 0x5FFF
210+ 8000 MMU3_6000_NR_53 equ $53 ;Set a Spectrum RAM page at position 0x6000 to 0x7FFF
211+ 8000 MMU4_8000_NR_54 equ $54 ;Set a Spectrum RAM page at position 0x8000 to 0x9FFF
212+ 8000 MMU5_A000_NR_55 equ $55 ;Set a Spectrum RAM page at position 0xA000 to 0xBFFF
213+ 8000 MMU6_C000_NR_56 equ $56 ;Set a Spectrum RAM page at position 0xC000 to 0xDFFF
214+ 8000 MMU7_E000_NR_57 equ $57 ;Set a Spectrum RAM page at position 0xE000 to 0xFFFF
215+ 8000 COPPER_DATA_NR_60 equ $60
216+ 8000 COPPER_CONTROL_LO_NR_61 equ $61
217+ 8000 COPPER_CONTROL_HI_NR_62 equ $62
218+ 8000 COPPER_DATA_16B_NR_63 equ $63 ; same as $60, but waits for full 16b before write
219+ 8000 VIDEO_LINE_OFFSET_NR_64 equ $64 ; (core 3.1.5)
220+ 8000 ULA_CONTROL_NR_68 equ $68
221+ 8000 DISPLAY_CONTROL_NR_69 equ $69
222+ 8000 LORES_CONTROL_NR_6A equ $6A
223+ 8000 TILEMAP_CONTROL_NR_6B equ $6B
224+ 8000 TILEMAP_DEFAULT_ATTR_NR_6C equ $6C
225+ 8000 TILEMAP_BASE_ADR_NR_6E equ $6E ;Tilemap base address of map
226+ 8000 TILEMAP_GFX_ADR_NR_6F equ $6F ;Tilemap definitions (graphics of tiles)
227+ 8000 LAYER2_CONTROL_NR_70 equ $70
228+ 8000 LAYER2_XOFFSET_MSB_NR_71 equ $71 ; for 320x256 and 640x256 L2 modes (core 3.0.6+)
229+ 8000 SPRITE_ATTR0_INC_NR_75 equ $75 ;port $57 mirror in nextreg space (accessible to copper) (slot index++)
230+ 8000 SPRITE_ATTR1_INC_NR_76 equ $76
231+ 8000 SPRITE_ATTR2_INC_NR_77 equ $77
232+ 8000 SPRITE_ATTR3_INC_NR_78 equ $78
233+ 8000 SPRITE_ATTR4_INC_NR_79 equ $79
234+ 8000 USER_STORAGE_0_NR_7F equ $7F
235+ 8000 EXPANSION_BUS_ENABLE_NR_80 equ $80
236+ 8000 EXPANSION_BUS_CONTROL_NR_81 equ $81
237+ 8000 INTERNAL_PORT_DECODING_0_NR_82 equ $82 ;bits 0-7
238+ 8000 INTERNAL_PORT_DECODING_1_NR_83 equ $83 ;bits 8-15
239+ 8000 INTERNAL_PORT_DECODING_2_NR_84 equ $84 ;bits 16-23
240+ 8000 INTERNAL_PORT_DECODING_3_NR_85 equ $85 ;bits 24-31
241+ 8000 EXPANSION_BUS_DECODING_0_NR_86 equ $86 ;bits 0-7 mask
242+ 8000 EXPANSION_BUS_DECODING_1_NR_87 equ $87 ;bits 8-15 mask
243+ 8000 EXPANSION_BUS_DECODING_2_NR_88 equ $88 ;bits 16-23 mask
244+ 8000 EXPANSION_BUS_DECODING_3_NR_89 equ $89 ;bits 24-31 mask
245+ 8000 EXPANSION_BUS_PROPAGATE_NR_8A equ $8A ;Monitoring internal I/O or adding external keyboard
246+ 8000 ALTERNATE_ROM_NR_8C equ $8C ;Enable alternate ROM or lock 48k ROM
247+ 8000 ZX_MEM_MAPPING_NR_8E equ $8E ;shortcut to set classic zx128+3 memory model at one place
248+ 8000 PI_GPIO_OUT_ENABLE_0_NR_90 equ $90 ;pins 0-7
249+ 8000 PI_GPIO_OUT_ENABLE_1_NR_91 equ $91 ;pins 8-15
250+ 8000 PI_GPIO_OUT_ENABLE_2_NR_92 equ $92 ;pins 16-23
251+ 8000 PI_GPIO_OUT_ENABLE_3_NR_93 equ $93 ;pins 24-27
252+ 8000 PI_GPIO_0_NR_98 equ $98 ;pins 0-7
253+ 8000 PI_GPIO_1_NR_99 equ $99 ;pins 8-15
254+ 8000 PI_GPIO_2_NR_9A equ $9A ;pins 16-23
255+ 8000 PI_GPIO_3_NR_9B equ $9B ;pins 24-27
256+ 8000 PI_PERIPHERALS_ENABLE_NR_A0 equ $A0
257+ 8000 PI_I2S_AUDIO_CONTROL_NR_A2 equ $A2
258+ 8000 ;PI_I2S_CLOCK_DIVIDE_NR_A3 equ $A3 ; REMOVED in core 3.1.5 (no more master-mode)
259+ 8000 ESP_WIFI_GPIO_OUTPUT_NR_A8 equ $A8
260+ 8000 ESP_WIFI_GPIO_NR_A9 equ $A9
261+ 8000 EXTENDED_KEYS_0_NR_B0 equ $B0 ;read Next compound keys as standalone keys (outside of zx48 matrix)
262+ 8000 EXTENDED_KEYS_1_NR_B1 equ $B1 ;read Next compound keys as standalone keys (outside of zx48 matrix)
263+ 8000 ;DIVMMC_TRAP_ENABLE_1_NR_B2 equ $B2 ; NOT IMPLEMENTED in core yet (as of 3.1.4), may happen in future
264+ 8000 ;DIVMMC_TRAP_ENABLE_2_NR_B4 equ $B4 ; NOT IMPLEMENTED in core yet (as of 3.1.4), may happen in future
265+ 8000 DEBUG_LED_CONTROL_NR_FF equ $FF ;Turns debug LEDs on and off on TBBlue implementations that have them.
266+ 8000
267+ 8000 ;-----------------------------------------------------------------------------
268+ 8000 ;-- common memory addresses
269+ 8000 MEM_ROM_CHARS_3C00 equ $3C00 ; actual chars start at $3D00 with space
270+ 8000 MEM_ZX_SCREEN_4000 equ $4000
271+ 8000 MEM_ZX_ATTRIB_5800 equ $5800
272+ 8000 MEM_LORES0_4000 equ $4000
273+ 8000 MEM_LORES1_6000 equ $6000
274+ 8000 MEM_TIMEX_SCR0_4000 equ $4000
275+ 8000 MEM_TIMEX_SCR1_6000 equ $6000
276+ 8000
277+ 8000 ;-----------------------------------------------------------------------------
278+ 8000 ;-- Copper commands
279+ 8000 COPPER_NOOP equ %00000000
280+ 8000 COPPER_WAIT_H equ %10000000
281+ 8000 COPPER_HALT_B equ $FF ; 2x $FF = wait for (511,63) = infinite wait
282+ 8000
283+ 8000 ;===========================================================================
284+ 8000 ; Ports
285+ 8000 ;===========================================================================
286+ 8000 NEXTREG_REGISTER_SELECT_PORT equ $243B
287+ 8000 NEXTREG_REGISTER_ACCESS_PORT equ $253B
288+ 8000 SPRITE_SLOT_SELECT_PORT equ $303B
289+ 8000 MEMORY_PAGING_CONTROL_PORT equ $7FFD
290+ 8000 AY_REGISTER_WRITE_PORT equ $BFFD
291+ 8000 MEMORY_BANK_SELECT_PORT equ $DFFD
292+ 8000 AY_SOUND_CONTROL_PORT equ $FFFD
293+ 8000 UART_WRITE_TX equ $133B ; Write is byte to send, when read is status 0x01 = RX_AVAIL or 0x02 - TX_READY
294+ 8000 UART_READ_RX equ $143B ; Read is byte received, when written sets the BAUD rate. (now two bytes of prescaler TBU >.28)
295+ 8000 UART_SELECT equ $153B
296+ 8000 Z80_DMA_DATAGEAR_PORT equ $6b
297+ 8000 SPRITE_INFO_PORT equ $57
298+ 8000 SPRITE_IMAGE_PORT equ $5b
299+ 8000
300+ 8000 ;-----------------------------------------------------------------------------
301+ 8000 ; DMA (Register 6)
302+ 8000 DMA_RESET equ $C3
303+ 8000 DMA_RESET_PORT_A_TIMING equ $C7
304+ 8000 DMA_RESET_PORT_B_TIMING equ $CB
305+ 8000 DMA_LOAD equ $CF
306+ 8000 DMA_CONTINUE equ $D3
307+ 8000 DMA_DISABLE_INTERUPTS equ $AF
308+ 8000 DMA_ENABLE_INTERUPTS equ $AB
309+ 8000 DMA_RESET_DISABLE_INTERUPTS equ $A3
310+ 8000 DMA_ENABLE_AFTER_RETI equ $B7
311+ 8000 DMA_READ_STATUS_BYTE equ $BF
312+ 8000 DMA_REINIT_STATUS_BYTE equ $8B
313+ 8000 DMA_START_READ_SEQUENCE equ $A7
314+ 8000 DMA_FORCE_READY equ $B3
315+ 8000 DMA_DISABLE equ $83
316+ 8000 DMA_ENABLE equ $87
317+ 8000 DMA_READ_MASK_FOLLOWS equ $BB
318+ 8000 DMA_WRITE_REGISTER_COMMAND equ $bb
319+ 8000 DMA_BURST equ %11001101
320+ 8000 DMA_CONTINUOUS equ %10101101
321+ 8000 KEYB equ $7F10
322+ 8000 KEYN equ $7F08
323+ 8000 KEYM equ $7F04
324+ 8000 KEYSYMBOL equ $7F02
325+ 8000 KEYSPACE equ $7F01
326+ 8000 KEYH equ $BF10
327+ 8000 KEYJ equ $BF08
328+ 8000 KEYK equ $BF04
329+ 8000 KEYL equ $BF02
330+ 8000 KEYENTER equ $BF01
331+ 8000 KEYY equ $DF10
332+ 8000 KEYU equ $DF08
333+ 8000 KEYI equ $DF04
334+ 8000 KEYO equ $DF02
335+ 8000 KEYP equ $DF01
336+ 8000 KEY6 equ $EF10
337+ 8000 KEY7 equ $EF08
338+ 8000 KEY8 equ $EF04
339+ 8000 KEY9 equ $EF02
340+ 8000 KEY0 equ $EF01
341+ 8000 KEY5 equ $F710
342+ 8000 KEY4 equ $F708
343+ 8000 KEY3 equ $F704
344+ 8000 KEY2 equ $F702
345+ 8000 KEY1 equ $F701
346+ 8000 KEYT equ $FB10
347+ 8000 KEYR equ $FB08
348+ 8000 KEYE equ $FB04
349+ 8000 KEYW equ $FB02
350+ 8000 KEYQ equ $FB01
351+ 8000 KEYG equ $FD10
352+ 8000 KEYF equ $FD08
353+ 8000 KEYD equ $FD04
354+ 8000 KEYS equ $FD02
355+ 8000 KEYA equ $FD01
356+ 8000 KEYV equ $FE10
357+ 8000 KEYC equ $FE08
358+ 8000 KEYX equ $FE04
359+ 8000 KEYZ equ $FE02
360+ 8000 KEYCAPS equ $FE01
# file closed: ./src/hardware.inc
15 8000
16 8000 ;------------------------------------------------------------------------------
17 8000 ; Main Program
18 8000
19 8000 main:
20 8000
21 8000 CD 58 80 call setup_hardware ; set up hardware registers
22 8003 3E 00 ld a, 0
23 8005 CD 64 80 call clsL2 ; clear layer2 with 0/black
24 8008
25 8008 ; blit some test patterns
26 8008 ;
27 8008 11 00 00 ld de, $0000 ; de = yx position on screen
28 800B DD 21 DC 83 ld ix, test_logo_128 ; ix points to source table
29 800F CD 64 81 call straight_plot ; draw using straight plot
30 8012
31 8012 11 C0 00 ld de, $00c0 ; something different
32 8015 DD 21 E6 83 ld ix, parrot_64
33 8019 CD 64 81 call straight_plot
34 801C
35 801C 11 80 00 ld de, $0080 ; and so on
36 801F DD 21 D7 83 ld ix, test_logo_64
37 8023 CD 64 81 call straight_plot
38 8026
39 8026 11 00 80 ld de, $8000 ; some more
40 8029 DD 21 D7 83 ld ix, test_logo_64
41 802D CD 64 81 call straight_plot
42 8030
43 8030 11 C0 80 ld de, $80c0 ; last one
44 8033 DD 21 D7 83 ld ix, test_logo_64
45 8037 CD 64 81 call straight_plot
46 803A
47 803A CD EB 84 call init_copper ; initialise the copper
48 803D CD B7 81 call init_scroller ; initialise the scroller
49 8040
50 8040 scroll_loop:
51 8040
52 8040
53 8040 3E 02 ld a,2
53 8042 D3 FE out ($fe), a ; colour bar to monitor performance
54 8044 CD C3 81 call update_scroller ; update the scroller
55 8047 3E 07 ld a,7
55 8049 D3 FE out ($fe), a
56 804B CD A5 83 call update_copper ; update the copper code
57 804E 3E 00 ld a,0
57 8050 D3 FE out ($fe), a
58 8052 CD 6D 83 call wait_vblank
59 8055 ; wait for vblank
60 8055
61 8055 C3 40 80 jp scroll_loop ; repeatsville
62 8058
63 8058
64 8058 ;------------------------------------------------------------------------------
65 8058 ; Routines
66 8058
67 8058 setup_hardware:
68 8058 ED 91 07 03 nextreg TURBO_CONTROL_NR_07,3 ; 28 mhz because
69 805C ED 91 4A 00 nextreg TRANSPARENCY_FALLBACK_COL_NR_4A,0 ; transparency black
70 8060 AF xor a
70 8061 D3 FE out ($fe), a ; black border
71 8063
72 8063 C9 ret
73 8064
74 8064 ;------------------------------------------------------------------------------
75 8064 ; Includes
76 8064
77 8064 include "layer2.asm"
# file opened: ./src/layer2.asm
1+ 8064 ;------------------------------------------------------------------------------
2+ 8064 ; layer2 routines
3+ 8064
4+ 8064 clsL2:
5+ 8064 ; Clears L2 320x256 with A as colour
6+ 8064 ; IN A > colour
7+ 8064 ; USES : hl, de, bc, a
8+ 8064
9+ 8064 32 7F 80 ld (.colour+1), a
10+ 8067 3E 12 ld a, $12 ; $12 is L2 RAM start bank register
11+ 8069 CD 62 83 call getRegister ; get L2 ram bank in a
12+ 806C 87 add a, a ; A = start of L2 ram, we need to *2
13+ 806D 06 05 ld b, 5 ; 3 blocks to do
14+ 806F
15+ 806F .L2loop:
16+ 806F C5 push bc ; save loop counter
17+ 8070
18+ 8070 ED 92 50 nextreg MMU0_0000_NR_50, a ; set 0 - $1fff
19+ 8073 3C inc a
20+ 8074 ED 92 51 nextreg MMU1_2000_NR_51, a ; set 0 - $1fff
21+ 8077 3C inc a
22+ 8078
23+ 8078 21 00 00 ld hl, 0 ; start at address 0
24+ 807B 11 01 00 ld de, 1
25+ 807E .colour:
26+ 807E 36 14 ld (hl), 20 ; smc colour from above
27+ 8080 01 FF 3F ld bc, $3fff ; bytes to clear
28+ 8083 ED B0 ldir
29+ 8085 C1 pop bc ; bring back loop counter
30+ 8086 10 E7 djnz .L2loop ; repeat until b = 0
31+ 8088
32+ 8088 ; restore ROMS
33+ 8088
34+ 8088 ED 91 50 FF nextreg MMU0_0000_NR_50, $ff
35+ 808C ED 91 51 FF nextreg MMU1_2000_NR_51, $ff
36+ 8090
37+ 8090 ; clear ULA
38+ 8090 21 00 40 ld hl, 16384
39+ 8093 11 01 40 ld de, 16385
40+ 8096 01 00 1B ld bc, 6912
41+ 8099 36 00 ld (hl), 0
42+ 809B ED B0 ldir
43+ 809D
44+ 809D C9 ret
45+ 809E
46+ 809E
47+ 809E LAYER2_ACCESS_PORT EQU $123B
48+ 809E
49+ 809E plot_l2: ; (byVal X as ubyte, byval Y as ubyte, byval T as ubyte)
50+ 809E ; hl = XY , a colour
51+ 809E
52+ 809E 01 3B 12 ld bc,LAYER2_ACCESS_PORT
53+ 80A1 F5 push af ; save colour
54+ 80A2 7C ld a,h ; put y into A
55+ 80A3 E6 C0 and $c0 ; yy00 0
56+ 80A5 F6 03 or 3 ; yy00 0011
57+ 80A7 ED 79 out (c),a ; select 8k-bank
58+ 80A9 7C ld a,h ; yyyy yyyy
59+ 80AA E6 3F and 63 ; 00yy yyyy
60+ 80AC 67 ld h,a
61+ 80AD F1 pop af ; pop back colour
62+ 80AE 77 ld (hl),a ; set pixel value
63+ 80AF
64+ 80AF 3E 02 ld a,2 ; 0000 0010
65+ 80B1 ED 79 out (c),a ; Layer2 writes off
66+ 80B3 C9 ret
67+ 80B4
68+ 80B4
69+ 80B4 set_coords:
70+ 80B4 ; sets co-ords
71+ 80B4 ; call set_coords: db x,y
72+ 80B4
73+ 80B4 E1 pop hl
73+ 80B5 CD B9 80 call set_xy
73+ 80B8 E9 jp (hl)
74+ 80B9 7E set_xy: ld a,(hl) ; X
75+ 80BA 32 F8 80 ld (L2_coords), a
76+ 80BD 23 inc hl
77+ 80BE 7E ld a,(hl) ; Y
78+ 80BF 32 F9 80 ld (L2_coords+1), a
79+ 80C2 23 inc hl
80+ 80C3 7E ld a,(hl) ; C
81+ 80C4 32 FA 80 ld (L2_coords+2), a
82+ 80C7 C9 ret
83+ 80C8
84+ 80C8
85+ 80C8 L2Line: ; (byVal Y as ubyte, byval W as ubyte, byval A as ubyte)
86+ 80C8 ; XY from coords, a = width
87+ 80C8
88+ 80C8 F5 push af
89+ 80C9 01 3B 12 ld bc,LAYER2_ACCESS_PORT
90+ 80CC 2A F8 80 ld hl, (L2_coords)
91+ 80CF 7C ld a,h
92+ 80D0 E6 C0 and $c0
93+ 80D2
94+ 80D2 F6 03 or 3
95+ 80D4 ED 79 out (c),a
96+ 80D6 7C ld a,h
97+ 80D7 E6 3F and 63
98+ 80D9 67 ld h,a
99+ 80DA C1 pop bc
100+ 80DB 0E 20 ld c, 32
101+ 80DD .lineloop2
102+ 80DD 06 20 ld b, 32
103+ 80DF 2E 00 ld l, 0
104+ 80E1 .lineloop:
105+ 80E1 ;push bc
106+ 80E1 3A FA 80 ld a, (L2_coords+2) ; get colour/map value off stack
107+ 80E4 77 ld (hl),a ; set pixel value
108+ 80E5 2C inc l
109+ 80E6 78 ld a, b
110+ 80E7 B7 or a
111+ 80E8 20 F7 jr nz,.lineloop
112+ 80EA 24 inc h
113+ 80EB 0D dec c
114+ 80EC 79 ld a, c
115+ 80ED B7 or a
116+ 80EE 20 ED jr nz,.lineloop2
117+ 80F0
118+ 80F0 3E 02 ld a,2 ; 0000 0010
119+ 80F2 01 3B 12 ld bc,LAYER2_ACCESS_PORT
120+ 80F5 ED 79 out (c),a ; Layer2 writes off
121+ 80F7
122+ 80F7 C9 ret
123+ 80F8
124+ 80F8 L2_coords: ; X Y C
125+ 80F8 00 00 00 DB 0 , 0 , 0
126+ 80FB
127+ 80FB
128+ 80FB get_xy_pos_l2:
129+ 80FB ; input d = y, e = x
130+ 80FB ; uses de a bc
131+ 80FB C5 push bc
132+ 80FC 01 3B 12 ld bc,LAYER2_ACCESS_PORT
133+ 80FF 7A ld a,d ; put y into A
134+ 8100 E6 C0 and $c0 ; yy00 0000
135+ 8102
136+ 8102 F6 03 or 3 ; yy00 0011
137+ 8104 ED 79 out (c),a ; select 8k-bank
138+ 8106 7A ld a,d ; yyyy yyyy
139+ 8107 E6 3F and 63 ; 00yy yyyy
140+ 8109 57 ld d,a
141+ 810A C1 pop bc
142+ 810B C9 ret
143+ 810C
144+ 810C get_xy_pos_l2_hl:
145+ 810C ; input h = y, l = x
146+ 810C ; uses hl a bc
147+ 810C 01 3B 12 ld bc,LAYER2_ACCESS_PORT
148+ 810F 7C ld a,h ; put y into A
149+ 8110 E6 C0 and $c0 ; yy00 0000
150+ 8112
151+ 8112 F6 03 or 3 ; yy00 0011
152+ 8114 ED 79 out (c),a ; select 8k-bank
153+ 8116 7C ld a,h ; yyyy yyyy
154+ 8117 E6 3F and 63 ; 00yy yyyy
155+ 8119 67 ld h,a
156+ 811A C9 ret
157+ 811B
158+ 811B ; snake draw L2
159+ 811B
160+ 811B snake_plot:
161+ 811B ; draws a tile with snake formatted data
162+ 811B ; de = xy, ix = snake_data
163+ 811B
164+ 811B DD 7E 00 ld a,(ix+0)
165+ 811E ED 92 50 nextreg $50, a
166+ 8121
167+ 8121 CD FB 80 call get_xy_pos_l2
168+ 8124 ; hl now position an mapped in
169+ 8124 DD 6E 03 ld l, (ix+3)
170+ 8127 DD 66 04 ld h, (ix+4)
171+ 812A 23 inc hl
172+ 812B 23 inc hl
173+ 812C ;ex de, hl ; hl now snake_data, de = destination on l2
174+ 812C DD 7E 02 ld a, (ix+2) ; height
175+ 812F DD 4E 01 .line1: ld c, (ix+1) ; width
176+ 8132 06 00 ld b, 0
177+ 8134 ED B0 ldir
178+ 8136 14 inc d ; next line down
179+ 8137 4F ld c, a
180+ 8138 CD 54 81 call .check_line
181+ 813B DD 46 01 ld b, (ix+1) ; width
182+ 813E 1D .line2: dec e
183+ 813F 23 inc hl
184+ 8140 7E ld a, (hl)
185+ 8141 12 ld (de), a
186+ 8142 10 FA djnz .line2
187+ 8144 14 inc d
188+ 8145 CD 54 81 call .check_line
189+ 8148 79 ld a, c
190+ 8149 3D dec a
191+ 814A 20 E3 jr nz, .line1
192+ 814C 01 3B 12 ld bc, LAYER2_ACCESS_PORT
193+ 814F 3E 02 ld a, 2
194+ 8151 ED 79 out (c), a
195+ 8153 C9 ret
196+ 8154
197+ 8154 .check_line:
198+ 8154
199+ 8154 7A ld a, d
200+ 8155 FE 40 cp $40
201+ 8157 CC FB 80 call z, get_xy_pos_l2
202+ 815A FE 80 cp $80
203+ 815C CC 60 81 call z, 1F
204+ 815F C9 ret
205+ 8160 CD FB 80 1: call get_xy_pos_l2
206+ 8163 C9 ret
207+ 8164
208+ 8164 straight_plot:
209+ 8164 ; typwriter plots large tile
210+ 8164 ; de = yx, ix = source_data
211+ 8164 ; break
212+ 8164 DD 7E 00 ld a, (ix+0) ; get the bank the source date is in from table
213+ 8167 ED 92 50 nextreg $50, a ; set slot 0
214+ 816A 3C inc a ; next bank
215+ 816B ED 92 51 nextreg $51, a ; set slot 1
216+ 816E DD 6E 03 ld l, (ix+3) ; source
217+ 8171 DD 66 04 ld h, (ix+4)
218+ 8174 23 inc hl ; add 2 because the first 2 bytes are WxH
219+ 8175 23 inc hl
220+ 8176 DD 46 02 ld b, (ix+2) ; height
221+ 8179 ED 53 7E 81 ld (.add1+1), de ; save yx address
222+ 817D .add1:
223+ 817D 11 00 00 ld de, 0000 ; will hold yx with self mod code
224+ 8180 .line1:
225+ 8180 CD FB 80 call get_xy_pos_l2 ; get position and l2 bank in place
226+ 8183 C5 push bc ; save bc / height
227+ 8184 06 00 ld b, 0 ; clear b
228+ 8186 DD 4E 01 ld c,(ix+1) ; width
229+ 8189 ED B0 ldir ; copy line
230+ 818B 7C ld a, h ; did we pass 16kb?
231+ 818C F6 C0 or $80 | $40
232+ 818E CC A6 81 call z,.nextbanks ; yes go to next bank
233+ 8191 C1 pop bc ; get back height
234+ 8192 ED 5B 7E 81 ld de, (.add1+1) ; get back yx
235+ 8196 14 inc d ; inc y
236+ 8197 ED 53 7E 81 ld (.add1+1), de ; save yx again
237+ 819B 05 dec b ; decrease height
238+ 819C 20 E2 jr nz, .line1 ; was height 0? no then loop to line1
239+ 819E 01 3B 12 ld bc, LAYER2_ACCESS_PORT ; turn off layer 2 writes
240+ 81A1 3E 02 ld a, 2
241+ 81A3 ED 79 out (c), a
242+ 81A5 C9 ret
243+ 81A6 .nextbanks
244+ 81A6 DD 7E 00 ld a, (ix+0) ; fetch bank
245+ 81A9 87 add a, a ; x2
246+ 81AA 87 add a, a
247+ 81AB ED 92 50 nextreg $50, a ; set new banks
248+ 81AE 3C inc a
249+ 81AF ED 92 51 nextreg $51,a
250+ 81B2 7C ld a, h ; wrap h
251+ 81B3 E6 7F and 127
252+ 81B5 7C ld a, h
253+ 81B6 C9 ret
# file closed: ./src/layer2.asm
78 81B7 include "scroller.asm"
# file opened: ./src/scroller.asm
1+ 81B7 ;------------------------------------------------------------------------------
2+ 81B7 ; scroller routines
3+ 81B7
4+ 81B7 init_scroller:
5+ 81B7
6+ 81B7 ; initialises the scroller
7+ 81B7
8+ 81B7 21 5C 82 ld hl,scroller_text-1 ; set to refresh char on first call
9+ 81BA 22 16 82 ld (txt_position),hl
10+ 81BD 21 18 82 ld hl,glyph_slice ; slice counter
11+ 81C0 36 01 ld (hl),1
12+ 81C2 C9 ret
13+ 81C3
14+ 81C3 update_scroller:
15+ 81C3
16+ 81C3 ; updates the scroller
17+ 81C3
18+ 81C3 ED 91 50 1E nextreg $50, 30 ; page in font
19+ 81C7 21 18 82 ld hl,glyph_slice ; update slice count
20+ 81CA 35 dec (hl)
21+ 81CB 20 28 jr nz,scroll_text
22+ 81CD
23+ 81CD new_char:
24+ 81CD 36 08 ld (hl),8 ; reset slice count
25+ 81CF 2A 16 82 ld hl,(txt_position) ; update current character
26+ 81D2 23 inc hl
27+ 81D3 22 16 82 ld (txt_position),hl
28+ 81D6 7E ld a,(hl) ; check for loop token
29+ 81D7 B7 or a
30+ 81D8 20 06 jr nz,get_new_glyp
31+ 81DA
32+ 81DA 21 5D 82 ld hl,scroller_text ; loop if necessary
33+ 81DD 22 16 82 ld (txt_position),hl
34+ 81E0
35+ 81E0 get_new_glyp:
36+ 81E0 7E ld a,(hl) ; collect char as ASCII
37+ 81E1 D6 20 sub 32
38+ 81E3 5F ld e, a ; char * 64bytes per tile
39+ 81E4 16 40 ld d, 64
40+ 81E6 ED 30 mul d, e
41+ 81E8 ED 53 19 82 ld (current_glyph),de ; points to correct letter in font
42+ 81EC
43+ 81EC EB ex de, hl ; put letter into hl for source
44+ 81ED 11 1D 82 ld de, tempchar ; point de to a temp buffer
45+ 81F0 01 40 00 ld bc, 64 ; size to copy
46+ 81F3 ED B0 ldir
47+ 81F5
48+ 81F5
49+ 81F5 scroll_text:
50+ 81F5
51+ 81F5 21 1D 82 ld hl, tempchar ; point to buffer
52+ 81F8 3A 18 82 ld a, (glyph_slice) ; which slice of the letter are we printing
53+ 81FB ED 44 neg ; glyph_slice counts down 8>0, we need 0-8
54+ 81FD C6 08 add a, 8 ;
55+ 81FF 85 add a, l ; add a as an offset into the buffer
56+ 8200 6F ld l, a ; put back into L
57+ 8201
58+ 8201 16 B8 ld d,192-8
59+ 8203 3A FB 84 ld a, (init_copper.layer2_xoffset-1) ; we need to move x+1 with each line draw
60+ 8206 5F ld e, a
61+ 8207 CD FB 80 call get_xy_pos_l2 ; DE = yx, get position and L2 page in
62+ 820A 06 08 ld b, 8 ; loop 8 times
63+ 820C
64+ 820C vertical_copy:
65+ 820C 7E ld a, (hl) ; 7 copy one bye
66+ 820D 12 ld (de), a ; 7
67+ 820E 3E 08 ld a, 8 ; 7
68+ 8210 ED 31 add hl, a ; 8
69+ 8212 14 inc d ; 4 this is for 256x192 +h +256
70+ 8213 10 F7 djnz vertical_copy
71+ 8215
72+ 8215 C9 ret
73+ 8216
74+ 8216
75+ 8216 00 00 txt_position: dw 0
76+ 8218 00 glyph_slice: db 0
77+ 8219 00 00 current_glyph: dw 0
78+ 821B 00 00 xpos: dw 0
79+ 821D tempchar:
80+ 821D 00 00 00... ds 64,0
81+ 825D
82+ 825D scroller_text:
83+ 825D
84+ 825D 48 45 4C 4C db "HELLO ZX SPECTRUM NEXT FANS "
84+ 8261 4F 20 5A 58
84+ 8265 20 53 50 45
84+ 8269 43 54 52 55
84+ 826D 4D 20 4E 45
84+ 8271 58 54 20 46
84+ 8275 41 4E 53 20
85+ 8279 48 65 72 65 db "Here we have your classic text scroller in its simplest form. "
85+ 827D 20 77 65 20
85+ 8281 68 61 76 65
85+ 8285 20 79 6F 75
85+ 8289 72 20 63 6C
85+ 828D 61 73 73 69
85+ 8291 63 20 74 65
85+ 8295 78 74 20 73
85+ 8299 63 72 6F 6C
85+ 829D 6C 65 72 20
85+ 82A1 69 6E 20 69
85+ 82A5 74 73 20 73
85+ 82A9 69 6D 70 6C
85+ 82AD 65 73 74 20
85+ 82B1 66 6F 72 6D
85+ 82B5 2E 20
86+ 82B7 20 20 57 65 db " We are using the copper to slide a horizontal slice of screen"
86+ 82BB 20 61 72 65
86+ 82BF 20 75 73 69
86+ 82C3 6E 67 20 74
86+ 82C7 68 65 20 63
86+ 82CB 6F 70 70 65
86+ 82CF 72 20 74 6F
86+ 82D3 20 73 6C 69
86+ 82D7 64 65 20 61
86+ 82DB 20 68 6F 72
86+ 82DF 69 7A 6F 6E
86+ 82E3 74 61 6C 20
86+ 82E7 73 6C 69 63
86+ 82EB 65 20 6F 66
86+ 82EF 20 73 63 72
86+ 82F3 65 65 6E
87+ 82F6 20 20 77 68 db " while at the same time printing text in slices along the way."
87+ 82FA 69 6C 65 20
87+ 82FE 61 74 20 74
87+ 8302 68 65 20 73
87+ 8306 61 6D 65 20
87+ 830A 74 69 6D 65
87+ 830E 20 70 72 69
87+ 8312 6E 74 69 6E
87+ 8316 67 20 74 65
87+ 831A 78 74 20 69
87+ 831E 6E 20 73 6C
87+ 8322 69 63 65 73
87+ 8326 20 61 6C 6F
87+ 832A 6E 67 20 74
87+ 832E 68 65 20 77
87+ 8332 61 79 2E
88+ 8335 20 20 41 6E db " Anyway that's enough of that! >>>>> ",00
88+ 8339 79 77 61 79
88+ 833D 20 74 68 61
88+ 8341 74 27 73 20
88+ 8345 65 6E 6F 75
88+ 8349 67 68 20 6F
88+ 834D 66 20 74 68
88+ 8351 61 74 21 20
88+ 8355 20 20 20 20
88+ 8359 20 3E 3E 3E
88+ 835D 3E 3E 20 20
88+ 8361 00
89+ 8362
90+ 8362
# file closed: ./src/scroller.asm
79 8362 include "utils.asm"
# file opened: ./src/utils.asm
1+ 8362
2+ 8362 ;------------------------------------------------------------------------------
3+ 8362 ; Utils
4+ 8362
5+ 8362 getRegister:
6+ 8362
7+ 8362 ; IN A > Register to read
8+ 8362 ; OUT A < Value of Register
9+ 8362
10+ 8362 C5 push bc
11+ 8363 01 3B 24 ld bc, TBBLUE_REGISTER_SELECT_P_243B
12+ 8366 ED 79 out (c), a
13+ 8368 04 inc b
14+ 8369 ED 78 in a, (c)
15+ 836B C1 pop bc
16+ 836C C9 ret
17+ 836D
18+ 836D ; Vsync wait
19+ 836D
20+ 836D wait_vblank:
21+ 836D 21 01 00 ld hl, 1
22+ 8370 .readline:
23+ 8370 3E 1F ld a,VIDEO_LINE_LSB_NR_1F
24+ 8372 01 3B 24 ld bc,TBBLUE_REGISTER_SELECT_P_243B
25+ 8375 ED 79 out (c),a
26+ 8377 04 inc b
27+ 8378 ED 78 in a,(c)
28+ 837A FE FA cp 250 ; line to wait for 192
29+ 837C 20 F2 jr nz,.readline
30+ 837E ;dec hl
31+ 837E ;ld a,h
32+ 837E ;or l
33+ 837E ;jr nz,.readline
34+ 837E C9 ret
# file closed: ./src/utils.asm
80 837F include "copper.asm"
# file opened: ./src/copper.asm
1+ 837F ;------------------------------------------------------------------------------
2+ 837F ; copper routines
3+ 837F
4+ 837F start_copper:
5+ 837F ; hl = copper list
6+ 837F ; bc = length
7+ 837F
8+ 837F ED 91 62 00 nextreg COPPER_CONTROL_HI_NR_62, 0 ; stop
9+ 8383 ED 91 61 00 nextreg COPPER_CONTROL_LO_NR_61, 0
10+ 8387
11+ 8387 C5 push bc
12+ 8388 01 3B 24 ld bc, TBBLUE_REGISTER_SELECT_P_243B
13+ 838B 3E 60 ld a, COPPER_DATA_NR_60
14+ 838D ED 79 out (c),a
15+ 838F C1 pop bc ; select copper data port
16+ 8390 CD B1 83 call TransferDMAPort
17+ 8393
18+ 8393 ED 91 62 C0 nextreg COPPER_CONTROL_HI_NR_62, %11000000 ; start
19+ 8397 ED 91 61 00 nextreg COPPER_CONTROL_LO_NR_61, %00000000
20+ 839B C9 ret
21+ 839C
22+ 839C stop_copper:
23+ 839C ED 91 62 00 nextreg COPPER_CONTROL_HI_NR_62, 0 ; stop
24+ 83A0 ED 91 61 00 nextreg COPPER_CONTROL_LO_NR_61, 0
25+ 83A4 C9 ret
26+ 83A5
27+ 83A5 update_copper:
28+ 83A5
29+ 83A5
30+ 83A5 3A FB 84 ld a, (init_copper.layer2_xoffset-1)
31+ 83A8 3C inc a
32+ 83A9
33+ 83A9 32 FB 84 ld (init_copper.layer2_xoffset-1),a
34+ 83AC
35+ 83AC CD EB 84 call init_copper
36+ 83AF C9 ret
37+ 83B0 .xpos:
38+ 83B0 00 db 0
39+ 83B1
# file closed: ./src/copper.asm
81 83B1 include "dma.asm"
# file opened: ./src/dma.asm
1+ 83B1
2+ 83B1 ;------------------------------------------------------------------------------
3+ 83B1 ; DMA routines
4+ 83B1
5+ 83B1 ;===========================================================================
6+ 83B1 ; hl = source
7+ 83B1 ; bc = length
8+ 83B1 ; set port to write to with NEXTREG_REGISTER_SELECT_PORT
9+ 83B1 ; prior to call
10+ 83B1 ;===========================================================================
11+ 83B1 TransferDMAPort
12+ 83B1 22 C4 83 ld (.dmaSource),hl
13+ 83B4 ED 43 C6 83 ld (.dmaLength),bc
14+ 83B8 21 C2 83 ld hl,.dmaCode
15+ 83BB 06 10 ld b,.dmaCodeLen
16+ 83BD 0E 6B ld c,Z80_DMA_PORT_DATAGEAR
17+ 83BF ED B3 otir
18+ 83C1 C9 ret
19+ 83C2 ;===========================================================================
20+ 83C2 ;
21+ 83C2 ;===========================================================================
22+ 83C2 .dmaCode
23+ 83C2 83 db DMA_DISABLE
24+ 83C3 7D db %01111101 ;R0-Transfer mode, A -> B, write adress + block length
25+ 83C4 .dmaSource
26+ 83C4 00 00 dw 0 ;R0-Port A, Start address (source address)
27+ 83C6 .dmaLength
28+ 83C6 00 00 dw 0 ;R0-Block length (length in bytes)
29+ 83C8 54 db %01010100 ;R1-read A time byte, increment, to memory, bitmask
30+ 83C9 02 db %00000010 ;R1-Cycle length port A
31+ 83CA 68 db %01101000 ;R2-write B time byte, increment, to memory, bitmask
32+ 83CB 02 db %00000010 ;R2-Cycle length port B
33+ 83CC AD db %10101101 ;R4-Continuous mode (use this for block tansfer), write dest adress
34+ 83CD 3B 25 dw $253b ;R4-Dest address (destination address)
35+ 83CF 82 db %10000010 ;R5-Restart on end of block, RDY active LOW
36+ 83D0 CF db DMA_LOAD ;R6-Load
37+ 83D1 87 db DMA_ENABLE ;R6-Enable DMA
38+ 83D2 .dmaCodeLen equ $-.dmaCode
39+ 83D2
# file closed: ./src/dma.asm
82 83D2 include "tables.asm"
# file opened: ./src/tables.asm
1+ 83D2 ;------------------------------------------------------------------------------
2+ 83D2 ; logo data
3+ 83D2
4+ 83D2 snake_emk_logo:
5+ 83D2 ; bank wdith height
6+ 83D2 ; offset
7+ 83D2 21 60 20 db 33, 96, 32
8+ 83D5 02 00 dw 2
9+ 83D7 test_logo_64:
10+ 83D7 ; bank wdith height
11+ 83D7 ; offset
12+ 83D7 21 40 40 db 33, 64, 64
13+ 83DA 00 0C dw 3072
14+ 83DC test_logo_128:
15+ 83DC ; bank wdith height
16+ 83DC ; offset
17+ 83DC 22 80 80 db 34, 128, 128
18+ 83DF 00 00 dw 0
19+ 83E1
20+ 83E1 test_logo_256:
21+ 83E1 ; bank wdith height