-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathelite-z.asm
8945 lines (6961 loc) · 363 KB
/
elite-z.asm
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
\ ******************************************************************************
\
\ 6502 SECOND PROCESSOR ELITE MAIN GAME SOURCE (I/O PROCESSOR)
\
\ 6502 Second Processor Elite was written by Ian Bell and David Braben and is
\ copyright Acornsoft 1985
\
\ The code in this file is identical to the source discs released on Ian Bell's
\ personal website at http://www.elitehomepage.org/ (it's just been reformatted
\ to be more readable)
\
\ The commentary is copyright Mark Moxon, and any misunderstandings or mistakes
\ in the documentation are entirely my fault
\
\ The terminology and notations used in this commentary are explained at
\ https://elite.bbcelite.com/terminology
\
\ The deep dive articles referred to in this commentary can be found at
\ https://elite.bbcelite.com/deep_dives
\
\ ------------------------------------------------------------------------------
\
\ This source file contains the I/O processor code for 6502 Second Processor
\ Elite. This is the code that runs in the I/O processor (i.e. the BBC Micro).
\
\ ------------------------------------------------------------------------------
\
\ This source file produces the following binary file:
\
\ * I.CODE.bin
\
\ ******************************************************************************
INCLUDE "1-source-files/main-sources/elite-build-options.asm"
_SOURCE_DISC = (_VARIANT = 1)
_SNG45 = (_VARIANT = 2)
_EXECUTIVE = (_VARIANT = 3)
GUARD &4000 \ Guard against assembling over screen memory
\ ******************************************************************************
\
\ Configuration variables
\
\ ******************************************************************************
CODE% = &2400 \ The assembly address of the main I/O processor code
LOAD% = &2400 \ The load address of the main I/O processor code
VSCAN = 57 \ Defines the split position in the split-screen mode
Y = 96 \ The centre y-coordinate of the 256 x 192 space view
YELLOW = %00001111 \ Four mode 1 pixels of colour 1 (yellow)
RED = %11110000 \ Four mode 1 pixels of colour 2 (red, magenta or white)
CYAN = %11111111 \ Four mode 1 pixels of colour 3 (cyan or white)
GREEN = %10101111 \ Four mode 1 pixels of colour 3, 1, 3, 1 (cyan/yellow)
WHITE = %11111010 \ Four mode 1 pixels of colour 3, 2, 3, 2 (cyan/red)
MAGENTA = RED \ Four mode 1 pixels of colour 2 (red, magenta or white)
DUST = WHITE \ Four mode 1 pixels of colour 3, 2, 3, 2 (cyan/red)
RED2 = %00000011 \ Two mode 2 pixels of colour 1 (red)
GREEN2 = %00001100 \ Two mode 2 pixels of colour 2 (green)
YELLOW2 = %00001111 \ Two mode 2 pixels of colour 3 (yellow)
BLUE2 = %00110000 \ Two mode 2 pixels of colour 4 (blue)
MAG2 = %00110011 \ Two mode 2 pixels of colour 5 (magenta)
CYAN2 = %00111100 \ Two mode 2 pixels of colour 6 (cyan)
WHITE2 = %00111111 \ Two mode 2 pixels of colour 7 (white)
STRIPE = %00100011 \ Two mode 2 pixels of colour 5, 1 (magenta/red)
PARMAX = 15 \ The number of dashboard parameters transmitted with
\ the #RDPARAMS and OSWRCH 137 <param> commands
IRQ1V = &0204 \ The IRQ1V vector that we intercept to implement the
\ split-screen mode
WRCHV = &020E \ The WRCHV vector that we intercept to implement our
\ own custom OSWRCH commands for communicating over the
\ Tube
WORDV = &020C \ The WORDV vector that we intercept to implement our
\ own custom OSWORD commands for communicating over the
\ Tube
RDCHV = &0210 \ The RDCHV vector that we intercept to add validation
\ when reading characters using OSRDCH
VIA = &FE00 \ Memory-mapped space for accessing internal hardware,
\ such as the video ULA, 6845 CRTC and 6522 VIAs (also
\ known as SHEILA)
NVOSWRCH = &FFCB \ The address for the non-vectored OSWRCH routine
OSWRCH = &FFEE \ The address for the OSWRCH routine
OSBYTE = &FFF4 \ The address for the OSBYTE routine
OSWORD = &FFF1 \ The address for the OSWORD routine
\ ******************************************************************************
\
\ Name: ZP
\ Type: Workspace
\ Address: &0080 to &0097
\ Category: Workspaces
\ Summary: Important variables used by the I/O processor
\
\ ******************************************************************************
ORG &0080
.ZP
SKIP 0 \ The start of the zero page workspace
.P
SKIP 1 \ Temporary storage, used in a number of places
.Q
SKIP 1 \ Temporary storage, used in a number of places
.R
SKIP 1 \ Temporary storage, used in a number of places
.S
SKIP 1 \ Temporary storage, used in a number of places
.T
SKIP 1 \ Temporary storage, used in a number of places
.SWAP
SKIP 1 \ Temporary storage, used to store a flag that records
\ whether or not we had to swap a line's start and end
\ coordinates around when clipping the line in routine
\ LL145 (the flag is used in places like BLINE to swap
\ them back)
.T1
SKIP 1 \ Temporary storage, used in a number of places
.COL
SKIP 1 \ Temporary storage, used to store colour information
\ when drawing pixels in the dashboard
.OSSC
SKIP 2 \ When the parasite sends an OSWORD command to the I/O
\ processor (i.e. an OSWORD with A = 240 to 255), then
\ the relevant handler routine in the I/O processor is
\ called with OSSC(1 0) pointing to the OSWORD parameter
\ block (i.e. OSSC(1 0) = (Y X) from the original call
\ in the I/O processor)
ORG &0090
.XX15
SKIP 0 \ Temporary storage, typically used for storing screen
\ coordinates in line-drawing routines
\
\ There are six bytes of storage, from XX15 TO XX15+5.
\ The first four bytes have the following aliases:
\
\ X1 = XX15
\ Y1 = XX15+1
\ X2 = XX15+2
\ Y2 = XX15+3
\
\ These are typically used for describing lines in terms
\ of screen coordinates, i.e. (X1, Y1) to (X2, Y2)
\
\ The last two bytes of XX15 do not have aliases
.X1
SKIP 1 \ Temporary storage, typically used for x-coordinates in
\ the line-drawing routines
.Y1
SKIP 1 \ Temporary storage, typically used for y-coordinates in
\ line-drawing routines
.X2
SKIP 1 \ Temporary storage, typically used for x-coordinates in
\ the line-drawing routines
.Y2
SKIP 1 \ Temporary storage, typically used for y-coordinates in
\ line-drawing routines
SKIP 2 \ The last 2 bytes of the XX15 block
.SC
SKIP 1 \ Screen address (low byte)
\
\ Elite draws on-screen by poking bytes directly into
\ screen memory, and SC(1 0) is typically set to the
\ address of the character block containing the pixel
\ we want to draw
.SCH
SKIP 1 \ Screen address (high byte)
PRINT "ZP workspace (I/O processor) from ", ~ZP, "to ", ~P%-1, "inclusive"
\ ******************************************************************************
\
\ Name: TINA
\ Type: Workspace
\ Address: &0B00 to &0BFF
\ Category: Workspaces
\ Summary: The code block for the TINA hook
\ Deep dive: The TINA hook
\
\ ------------------------------------------------------------------------------
\
\ To use the TINA hook, this workspace should start with "TINA" and then be
\ followed by code that executes on the I/O processor before the main game code
\ terminates.
\
\ ------------------------------------------------------------------------------
\
\ Other entry points:
\
\ TINA+4 The code to run if the TINA hook is enabled
\
\ ******************************************************************************
ORG &0B00
.TINA
SKIP 256
PRINT "TINA workspace (I/O processor) from ", ~ZP, "to ", ~P%-1, "inclusive"
\ ******************************************************************************
\
\ Name: TABLE
\ Type: Variable
\ Category: Drawing lines
\ Summary: The line buffer for line data transmitted from the parasite
\
\ ------------------------------------------------------------------------------
\
\ Lines are drawn by sending the line coordinates one byte at a time from the
\ parasite, using the OSWRCH 129 and 130 commands. As they are sent, they are
\ stored in the TABLE buffer, until all the points have been received, at which
\ point the line is drawn.
\
\ LINTAB points to the offset of the first free byte within TABLE, so the table
\ can be reset by setting LINTAB to 0.
\
\ ******************************************************************************
ORG &2300
.TABLE
SKIP 256
\ ******************************************************************************
\
\ Name: FONT%
\ Type: Variable
\ Category: Text
\ Summary: A copy of the character definition bitmap table from the MOS ROM
\
\ ------------------------------------------------------------------------------
\
\ This is used by the TT26 routine to save time looking up the character bitmaps
\ from the ROM. Note that FONT% contains just the high byte (i.e. the page
\ number) of the address of this table, rather than the full address.
\
\ The contents of the P.FONT.bin file included here are taken straight from the
\ following three pages in the BBC Micro OS 1.20 ROM:
\
\ ASCII 32-63 are defined in &C000-&C0FF (page 0)
\ ASCII 64-95 are defined in &C100-&C1FF (page 1)
\ ASCII 96-126 are defined in &C200-&C2F0 (page 2)
\
\ The code could look these values up each time (as the cassette version does),
\ but it's quicker to use a lookup table, at the expense of three pages of
\ memory.
\
\ The Executive version uses a different font to the standard OS, which is
\ included in the P.FONTEX.bin file. This means all in-game text uses this new
\ font, which is based on the 1960s Westminster font. The font style is similar
\ to the machine-readable font on cheques, and is in a style that we would now
\ call "retro-futuristic" (though presumably it was just "futuristic" back in
\ 1984).
\
\ ******************************************************************************
ORG CODE%
FONT% = HI(P%)
IF _SNG45 OR _SOURCE_DISC
INCBIN "1-source-files/fonts/P.FONT.bin"
ELIF _EXECUTIVE
INCBIN "1-source-files/fonts/P.FONTEX.bin"
ENDIF
\ ******************************************************************************
\
\ Name: log
\ Type: Variable
\ Category: Maths (Arithmetic)
\ Summary: Binary logarithm table (high byte)
\
\ ------------------------------------------------------------------------------
\
\ At byte n, the table contains the high byte of:
\
\ &2000 * log10(n) / log10(2) = 32 * 256 * log10(n) / log10(2)
\
\ where log10 is the logarithm to base 10. The change-of-base formula says that:
\
\ log2(n) = log10(n) / log10(2)
\
\ so byte n contains the high byte of:
\
\ 32 * log2(n) * 256
\
\ ******************************************************************************
.log
IF _MATCH_ORIGINAL_BINARIES
IF _SNG45
EQUB &18 \ This byte appears to be unused and just contains
\ random workspace noise left over from the BBC Micro
\ assembly process
ELIF _EXECUTIVE
EQUB &FF \ This byte appears to be unused and just contains
\ random workspace noise left over from the BBC Micro
\ assembly process
ELIF _SOURCE_DISC
EQUB &8E \ This byte appears to be unused and just contains
\ random workspace noise left over from the BBC Micro
\ assembly process
ENDIF
EQUB &00, &20, &32, &40, &4A, &52, &59
EQUB &5F, &65, &6A, &6E, &72, &76, &79, &7D
EQUB &80, &82, &85, &87, &8A, &8C, &8E, &90
EQUB &92, &94, &96, &98, &99, &9B, &9D, &9E
EQUB &A0, &A1, &A2, &A4, &A5, &A6, &A7, &A9
EQUB &AA, &AB, &AC, &AD, &AE, &AF, &B0, &B1
EQUB &B2, &B3, &B4, &B5, &B6, &B7, &B8, &B9
EQUB &B9, &BA, &BB, &BC, &BD, &BD, &BE, &BF
EQUB &BF, &C0, &C1, &C2, &C2, &C3, &C4, &C4
EQUB &C5, &C6, &C6, &C7, &C7, &C8, &C9, &C9
EQUB &CA, &CA, &CB, &CC, &CC, &CD, &CD, &CE
EQUB &CE, &CF, &CF, &D0, &D0, &D1, &D1, &D2
EQUB &D2, &D3, &D3, &D4, &D4, &D5, &D5, &D5
EQUB &D6, &D6, &D7, &D7, &D8, &D8, &D9, &D9
EQUB &D9, &DA, &DA, &DB, &DB, &DB, &DC, &DC
EQUB &DD, &DD, &DD, &DE, &DE, &DE, &DF, &DF
EQUB &E0, &E0, &E0, &E1, &E1, &E1, &E2, &E2
EQUB &E2, &E3, &E3, &E3, &E4, &E4, &E4, &E5
EQUB &E5, &E5, &E6, &E6, &E6, &E7, &E7, &E7
EQUB &E7, &E8, &E8, &E8, &E9, &E9, &E9, &EA
EQUB &EA, &EA, &EA, &EB, &EB, &EB, &EC, &EC
EQUB &EC, &EC, &ED, &ED, &ED, &ED, &EE, &EE
EQUB &EE, &EE, &EF, &EF, &EF, &EF, &F0, &F0
EQUB &F0, &F1, &F1, &F1, &F1, &F1, &F2, &F2
EQUB &F2, &F2, &F3, &F3, &F3, &F3, &F4, &F4
EQUB &F4, &F4, &F5, &F5, &F5, &F5, &F5, &F6
EQUB &F6, &F6, &F6, &F7, &F7, &F7, &F7, &F7
EQUB &F8, &F8, &F8, &F8, &F9, &F9, &F9, &F9
EQUB &F9, &FA, &FA, &FA, &FA, &FA, &FB, &FB
EQUB &FB, &FB, &FB, &FC, &FC, &FC, &FC, &FC
EQUB &FD, &FD, &FD, &FD, &FD, &FD, &FE, &FE
EQUB &FE, &FE, &FE, &FF, &FF, &FF, &FF, &FF
ELSE
SKIP 1
FOR I%, 1, 255
EQUB HI(INT(&2000 * LOG(I%) / LOG(2) + 0.5))
NEXT
ENDIF
\ ******************************************************************************
\
\ Name: logL
\ Type: Variable
\ Category: Maths (Arithmetic)
\ Summary: Binary logarithm table (low byte)
\
\ ------------------------------------------------------------------------------
\
\ At byte n, the table contains the high byte of:
\
\ &2000 * log10(n) / log10(2) = 32 * 256 * log10(n) / log10(2)
\
\ where log10 is the logarithm to base 10. The change-of-base formula says that:
\
\ log2(n) = log10(n) / log10(2)
\
\ so byte n contains the low byte of:
\
\ 32 * log2(n) * 256
\
\ ******************************************************************************
.logL
IF _MATCH_ORIGINAL_BINARIES
IF _SNG45
EQUB &86 \ This byte appears to be unused and just contains
\ random workspace noise left over from the BBC Micro
\ assembly process
ELIF _EXECUTIVE
EQUB &FF \ This byte appears to be unused and just contains
\ random workspace noise left over from the BBC Micro
\ assembly process
ELIF _SOURCE_DISC
EQUB &00 \ This byte appears to be unused and just contains
\ random workspace noise left over from the BBC Micro
\ assembly process
ENDIF
EQUB &00, &00, &B8, &00, &4D, &B8, &D5
EQUB &FF, &70, &4D, &B3, &B8, &6A, &D5, &05
EQUB &00, &CC, &70, &EF, &4D, &8D, &B3, &C1
EQUB &B8, &9A, &6A, &28, &D5, &74, &05, &88
EQUB &00, &6B, &CC, &23, &70, &B3, &EF, &22
EQUB &4D, &71, &8D, &A3, &B3, &BD, &C1, &BF
EQUB &B8, &AB, &9A, &84, &6A, &4B, &28, &00
EQUB &D5, &A7, &74, &3E, &05, &C8, &88, &45
EQUB &FF, &B7, &6B, &1D, &CC, &79, &23, &CA
EQUB &70, &13, &B3, &52, &EF, &89, &22, &B8
EQUB &4D, &E0, &71, &00, &8D, &19, &A3, &2C
EQUB &B3, &39, &BD, &3F, &C1, &40, &BF, &3C
EQUB &B8, &32, &AB, &23, &9A, &10, &84, &F7
EQUB &6A, &DB, &4B, &BA, &28, &94, &00, &6B
EQUB &D5, &3E, &A7, &0E, &74, &DA, &3E, &A2
EQUB &05, &67, &C8, &29, &88, &E7, &45, &A3
EQUB &00, &5B, &B7, &11, &6B, &C4, &1D, &75
EQUB &CC, &23, &79, &CE, &23, &77, &CA, &1D
EQUB &70, &C1, &13, &63, &B3, &03, &52, &A1
EQUB &EF, &3C, &89, &D6, &22, &6D, &B8, &03
EQUB &4D, &96, &E0, &28, &71, &B8, &00, &47
EQUB &8D, &D4, &19, &5F, &A3, &E8, &2C, &70
EQUB &B3, &F6, &39, &7B, &BD, &FE, &3F, &80
EQUB &C1, &01, &40, &80, &BF, &FD, &3C, &7A
EQUB &B8, &F5, &32, &6F, &AB, &E7, &23, &5F
EQUB &9A, &D5, &10, &4A, &84, &BE, &F7, &31
EQUB &6A, &A2, &DB, &13, &4B, &82, &BA, &F1
EQUB &28, &5E, &94, &CB, &00, &36, &6B, &A0
EQUB &D5, &0A, &3E, &73, &A7, &DA, &0E, &41
EQUB &74, &A7, &DA, &0C, &3E, &70, &A2, &D3
EQUB &05, &36, &67, &98, &C8, &F8, &29, &59
EQUB &88, &B8, &E7, &16, &45, &74, &A3, &D1
ELSE
SKIP 1
FOR I%, 1, 255
EQUB LO(INT(&2000 * LOG(I%) / LOG(2) + 0.5))
NEXT
ENDIF
\ ******************************************************************************
\
\ Name: antilog
\ Type: Variable
\ Category: Maths (Arithmetic)
\ Summary: Binary antilogarithm table
\
\ ------------------------------------------------------------------------------
\
\ At byte n, the table contains:
\
\ 2^((n / 2 + 128) / 16) / 256
\
\ which equals:
\
\ 2^(n / 32 + 8) / 256
\
\ ******************************************************************************
.antilog
FOR I%, 0, 255
EQUB HI(INT(2^((I% / 2 + 128) / 16) + 0.5))
NEXT
\ ******************************************************************************
\
\ Name: antilogODD
\ Type: Variable
\ Category: Maths (Arithmetic)
\ Summary: Binary antilogarithm table
\
\ ------------------------------------------------------------------------------
\
\ At byte n, the table contains:
\
\ 2^((n / 2 + 128.25) / 16) / 256
\
\ which equals:
\
\ 2^(n / 32 + 8.015625) / 256 = 2^(n / 32 + 8) * 2^(.015625) / 256
\ = (2^(n / 32 + 8) + 1) / 256
\
\ ******************************************************************************
.antilogODD
FOR I%, 0, 255
EQUB HI(INT(2^((I% / 2 + 128.25) / 16) + 0.5))
NEXT
\ ******************************************************************************
\
\ Name: ylookup
\ Type: Variable
\ Category: Drawing pixels
\ Summary: Lookup table for converting pixel y-coordinate to page number of
\ screen address
\
\ ------------------------------------------------------------------------------
\
\ Elite's screen mode is based on mode 1, so it allocates two pages of screen
\ memory to each character row (where a character row is 8 pixels high). This
\ table enables us to convert a pixel y-coordinate in the range 0-247 into the
\ page number for the start of the character row containing that coordinate.
\
\ Screen memory is from &4000 to &7DFF, so the lookup works like this:
\
\ Y = 0 to 7, lookup value = &40 (so row 1 is from &4000 to &41FF)
\ Y = 8 to 15, lookup value = &42 (so row 2 is from &4200 to &43FF)
\ Y = 16 to 23, lookup value = &44 (so row 3 is from &4400 to &45FF)
\ Y = 24 to 31, lookup value = &46 (so row 4 is from &4600 to &47FF)
\
\ ...
\
\ Y = 232 to 239, lookup value = &7A (so row 31 is from &7A00 to &7BFF)
\ Y = 240 to 247, lookup value = &7C (so row 32 is from &7C00 to &7DFF)
\
\ There is also a lookup value for y-coordinates from 248 to 255, but that's off
\ the end of the screen, as the special Elite screen mode only has 31 character
\ rows.
\
\ ******************************************************************************
.ylookup
FOR I%, 0, 255
EQUB &40 + ((I% DIV 8) * 2)
NEXT
\ ******************************************************************************
\
\ Name: TVT3
\ Type: Variable
\ Category: Drawing the screen
\ Summary: Palette data for the mode 1 part of the screen (the top part)
\
\ ------------------------------------------------------------------------------
\
\ The following table contains four different mode 1 palettes, each of which
\ sets a four-colour palette for the top part of the screen. Mode 1 supports
\ four colours on-screen and in Elite colour 0 is always set to black, so each
\ of the palettes in this table defines the three other colours (1 to 3).
\
\ There is some consistency between the palettes:
\
\ * Colour 0 is always black
\ * Colour 1 (#YELLOW) is always yellow
\ * Colour 2 (#RED) is normally red-like (i.e. red or magenta)
\ ... except in the title screen palette, when it is white
\ * Colour 3 (#CYAN) is always cyan-like (i.e. white or cyan)
\
\ The configuration variables of #YELLOW, #RED and #CYAN are a bit misleading,
\ but if you think of them in terms of hue rather than specific colours, they
\ work reasonably well (outside of the title screen palette, anyway).
\
\ The palettes are set in the IRQ1 handler that implements the split screen
\ mode, and can be changed by the parasite sending a #SETVDU19 <offset> command
\ to point to the offset of the new palette in this table.
\
\ This table must start on a page boundary (i.e. an address that ends in two
\ zeroes in hexadecimal). In the release version of the game TVT3 is at &2C00.
\ This is so the #SETVDU19 command can switch palettes properly, as it does this
\ by overwriting the low byte of the palette data address with a new offset, so
\ the low byte for first palette's address must be 0.
\
\ Palette data is given as a set of bytes, with each byte mapping a logical
\ colour to a physical one. In each byte, the logical colour is given in bits
\ 4-7 and the physical colour in bits 0-3. See page 379 of the "Advanced User
\ Guide for the BBC Micro" by Bray, Dickens and Holmes for details of how
\ palette mapping works, as in modes 1 and 2 we have to do multiple palette
\ commands to change the colours correctly, and the physical colour value is
\ EOR'd with 7, just to make things even more confusing.
\
\ ******************************************************************************
.TVT3
EQUB &00, &34 \ 1 = yellow, 2 = red, 3 = cyan (space view)
EQUB &24, &17 \
EQUB &74, &64 \ Set with a #SETVDU19 0 command, after which:
EQUB &57, &47 \
EQUB &B1, &A1 \ #YELLOW = yellow
EQUB &96, &86 \ #RED = red
EQUB &F1, &E1 \ #CYAN = cyan
EQUB &D6, &C6 \ #GREEN = cyan/yellow stripe
\ #WHITE = cyan/red stripe
EQUB &00, &34 \ 1 = yellow, 2 = red, 3 = white (chart view)
EQUB &24, &17 \
EQUB &74, &64 \ Set with a #SETVDU19 16 command, after which:
EQUB &57, &47 \
EQUB &B0, &A0 \ #YELLOW = yellow
EQUB &96, &86 \ #RED = red
EQUB &F0, &E0 \ #CYAN = white
EQUB &D6, &C6 \ #GREEN = white/yellow stripe
\ #WHITE = white/red stripe
EQUB &00, &34 \ 1 = yellow, 2 = white, 3 = cyan (title screen)
EQUB &24, &17 \
EQUB &74, &64 \ Set with a #SETVDU19 32 command, after which:
EQUB &57, &47 \
EQUB &B1, &A1 \ #YELLOW = yellow
EQUB &90, &80 \ #RED = white
EQUB &F1, &E1 \ #CYAN = cyan
EQUB &D0, &C0 \ #GREEN = cyan/yellow stripe
\ #WHITE = cyan/white stripe
EQUB &00, &34 \ 1 = yellow, 2 = magenta, 3 = white (trade view)
EQUB &24, &17 \
EQUB &74, &64 \ Set with a #SETVDU19 48 command, after which:
EQUB &57, &47 \
EQUB &B0, &A0 \ #YELLOW = yellow
EQUB &92, &82 \ #RED = magenta
EQUB &F0, &E0 \ #CYAN = white
EQUB &D2, &C2 \ #GREEN = white/yellow stripe
\ #WHITE = white/magenta stripe
\ ******************************************************************************
\
\ Name: I/O variables
\ Type: Workspace
\ Address: &2C40 to &2C60
\ Category: Workspaces
\ Summary: Various variables used by the I/O processor
\
\ ******************************************************************************
.XC
EQUB 1 \ The x-coordinate of the text cursor (i.e. the text
\ column), set to an initial value of 1
.YC
EQUB 1 \ The y-coordinate of the text cursor (i.e. the text
\ row), set to an initial value of 1
.K3
SKIP 1 \ Temporary storage, used in a number of places
.U
SKIP 1 \ Temporary storage, used in a number of places
.LINTAB
SKIP 1 \ The offset of the first free byte in the TABLE buffer,
\ which stores bytes in the current line as they are
\ transmitted from the parasite using the OSWRCH 129 and
\ 130 commands
.LINMAX
SKIP 1 \ The number of points in the line currently being
\ transmitted from the parasite using the OSWRCH 129
\ and 130 commands
.YSAV
SKIP 1 \ Temporary storage for saving the value of the Y
\ register, used in a number of places
.svn
SKIP 1 \ "Saving in progress" flag
\
\ * Non-zero while the disc is being accessed (so this
\ is also the case for cataloguing, loading etc.)
\
\ * 0 otherwise
.PARANO
SKIP 1 \ PARANO points to the last free byte in PARAMS, which
\ is used as a buffer for bytes sent from the parasite
\ by the #RDPARAMS and OSWRCH 137 <param> commands when
\ updating the dashboard
.DL
SKIP 1 \ Vertical sync flag
\
\ DL gets set to 30 every time we reach vertical sync on
\ the video system, which happens 50 times a second
\ (50Hz). The WSCAN routine uses this to pause until the
\ vertical sync, by setting DL to 0 and then monitoring
\ its value until it changes to 30
.VEC
SKIP 2 \ VEC = &7FFE
\
\ This gets set to the value of the original IRQ1 vector
\ by the loading process
.HFX
SKIP 1 \ A flag that toggles the hyperspace colour effect
\
\ * 0 = no colour effect
\
\ * Non-zero = hyperspace colour effect enabled
\
\ When HFX is set to 1, the mode 1 screen that makes
\ up the top part of the display is temporarily switched
\ to mode 2 (the same screen mode as the dashboard),
\ which has the effect of blurring and colouring the
\ hyperspace rings in the top part of the screen. The
\ code to do this is in the LINSCN routine, which is
\ called as part of the screen mode routine at IRQ1.
\ It's in LINSCN that HFX is checked, and if it is
\ non-zero, the top part of the screen is not switched
\ to mode 1, thus leaving the top part of the screen in
\ the more colourful mode 2
.CATF
SKIP 1 \ The disc catalogue flag
\
\ Determines whether a disc catalogue is currently in
\ progress, so the TT26 print routine can format the
\ output correctly:
\
\ * 0 = disc is not currently being catalogued
\
\ * 1 = disc is currently being catalogued
\
\ Specifically, when CATF is non-zero, TT26 will omit
\ column 17 from the catalogue so that it will fit
\ on-screen (column 17 is blank column in the middle
\ of the catalogue, between the two lists of filenames,
\ so it can be dropped without affecting the layout)
.K
SKIP 4 \ Temporary storage, used in a number of places
.PARAMS
SKIP 0 \ PARAMS points to the start of the dashboard parameter
\ block that is populated by the parasite when it sends
\ the #RDPARAMS and OSWRCH 137 <param> commands
\
\ These commands update the dashboard, but because the
\ parameter block uses the same locations as the flight
\ variables, these commands also have the effect of
\ updating the following variables, from ENERGY to ESCP
.ENERGY
SKIP 1 \ Energy bank status
\
\ * 0 = empty
\
\ * &FF = full
.ALP1
SKIP 1 \ Magnitude of the roll angle alpha, i.e. |alpha|,
\ which is a positive value between 0 and 31
.ALP2
SKIP 1 \ Bit 7 of ALP2 = sign of the roll angle in ALPHA
.BETA
SKIP 1 \ The current pitch angle beta, which is reduced from
\ JSTY to a sign-magnitude value between -8 and +8
\
\ This describes how fast we are pitching our ship, and
\ determines how fast the universe pitches around us
\
\ The sign bit is also stored in BET2, while the
\ opposite sign is stored in BET2+1
.BET1
SKIP 1 \ The magnitude of the pitch angle beta, i.e. |beta|,
\ which is a positive value between 0 and 8
.DELTA
SKIP 1 \ Our current speed, in the range 1-40
.ALTIT
SKIP 1 \ Our altitude above the surface of the planet or sun
\
\ * 255 = we are a long way above the surface
\
\ * 1-254 = our altitude as the square root of:
\
\ x_hi^2 + y_hi^2 + z_hi^2 - 6^2
\
\ where our ship is at the origin, the centre of the
\ planet/sun is at (x_hi, y_hi, z_hi), and the
\ radius of the planet/sun is 6
\
\ * 0 = we have crashed into the surface
.MCNT
SKIP 1 \ The main loop counter
\
\ This counter determines how often certain actions are
\ performed within the main loop
.FSH
SKIP 1 \ Forward shield status
\
\ * 0 = empty
\
\ * &FF = full
.ASH
SKIP 1 \ Aft shield status
\
\ * 0 = empty
\
\ * &FF = full
.QQ14
SKIP 1 \ Our current fuel level (0-70)
\
\ The fuel level is stored as the number of light years
\ multiplied by 10, so QQ14 = 1 represents 0.1 light
\ years, and the maximum possible value is 70, for 7.0
\ light years
.GNTMP
SKIP 1 \ Laser temperature (or "gun temperature")
\
\ If the laser temperature exceeds 242 then the laser
\ overheats and cannot be fired again until it has
\ cooled down
.CABTMP
SKIP 1 \ Cabin temperature
\
\ The ambient cabin temperature in deep space is 30,
\ which is displayed as one notch on the dashboard bar
\
\ We get higher temperatures closer to the sun
\
\ CABTMP shares a location with MANY, but that's OK as
\ MANY+0 would contain the number of ships of type 0,
\ and as there is no ship type 0 (they start at 1), the
\ byte at MANY+0 is not used for storing a ship type
\ and can be used for the cabin temperature instead
.FLH
SKIP 1 \ Flashing console bars configuration setting
\
\ * 0 = static bars (default)
\
\ * &FF = flashing bars
\
\ Toggled by pressing "F" when paused, see the DKS3
\ routine for details
.ESCP
SKIP 1 \ Escape pod
\
\ * 0 = not fitted
\
\ * &FF = fitted
PRINT "I/O variables workspace (I/O processor) from ", ~XC, "to ", ~P%-1, "inclusive"
\ ******************************************************************************
\
\ Name: JMPTAB
\ Type: Variable
\ Category: Tube
\ Summary: The lookup table for OSWRCH jump commands (128-147)
\ Deep dive: 6502 Second Processor Tube communication
\
\ ------------------------------------------------------------------------------
\
\ Once they have finished, routines in this table should reset WRCHV to point
\ back to USOSWRCH again by calling the PUTBACK routine with a JMP as their last
\ instruction.
\
\ ******************************************************************************
.JMPTAB
EQUW USOSWRCH \ 128 (&80) 0 = Put back to USOSWRCH
EQUW BEGINLIN \ 129 (&81) 1 = Begin drawing a line
EQUW ADDBYT \ 130 (&82) 2 = Add line byte/draw line
EQUW DOFE21 \ #DOFE21 = 131 (&83) 3 = Show energy bomb effect
EQUW DOHFX \ #DOhfx = 132 (&84) 4 = Show hyperspace colours
EQUW SETXC \ #SETXC = 133 (&85) 5 = Set text cursor column
EQUW SETYC \ #SETYC = 134 (&86) 6 = Set text cursor row
EQUW CLYNS \ #clyns = 135 (&87) 7 = Clear bottom of screen
EQUW RDPARAMS \ #RDPARAMS = 136 (&88) 8 = Update dashboard
EQUW ADPARAMS \ 137 (&89) 9 = Add dashboard parameter
EQUW DODIALS \ #DODIALS = 138 (&8A) 10 = Show or hide dashboard
EQUW DOVIAE \ #VIAE = 139 (&8B) 11 = Set 6522 System VIA IER
EQUW DOBULB \ #DOBULB = 140 (&8C) 12 = Toggle dashboard bulb
EQUW DOCATF \ #DOCATF = 141 (&8D) 13 = Set disc catalogue flag
EQUW DOCOL \ #SETCOL = 142 (&8E) 14 = Set the current colour
EQUW SETVDU19 \ #SETVDU19 = 143 (&8F) 15 = Change mode 1 palette
EQUW DOSVN \ #DOsvn = 144 (&90) 16 = Set file saving flag
EQUW DOBRK \ 145 (&91) 17 = Execute BRK instruction
EQUW printer \ #printcode = 146 (&92) 18 = Write to printer/screen
EQUW prilf \ #prilf = 147 (&93) 19 = Blank line on printer