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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
|
/*************************************************************************
Driver for Midway Zeus games
**************************************************************************/
#include "driver.h"
#include "eminline.h"
#include "includes/midzeus.h"
#include "video/poly.h"
/*************************************
*
* Constants
*
*************************************/
#define WAVERAM_WIDTH 512
#define WAVERAM_HEIGHT 4096
/*************************************
*
* Type definitions
*
*************************************/
typedef struct _poly_extra_data poly_extra_data;
struct _poly_extra_data
{
const UINT32 * palbase;
const UINT32 * texbase;
UINT16 transcolor;
UINT16 texwidth;
UINT16 color;
UINT32 alpha;
};
/*************************************
*
* Global variables
*
*************************************/
UINT32 *zeusbase;
static poly_manager *poly;
static UINT32 zeuscmd_buffer[8];
static UINT8 zeuscmd_buffer_words;
static UINT8 zeuscmd_buffer_expected_words;
static INT16 zeus_matrix[3][3];
static INT32 zeus_point[3];
static UINT32 *zeus_palbase;
static int zeus_enable_logging;
static UINT32 zeus_blend;
static UINT32 zeus_texdata;
static UINT32 zeus_objdata;
static UINT32 last_tex[1000][2];
static int last_tex_index;
static UINT32 *waveram;
/*************************************
*
* Function prototypes
*
*************************************/
static void exit_handler(running_machine *machine);
/*************************************
*
* Inlines
*
*************************************/
INLINE UINT32 *waveram_ptr_from_addr(UINT32 addr)
{
return &waveram[((addr & 0x1ff) | ((addr & 0xfff000) >> 3)) * 2];
}
INLINE UINT32 *waveram_pixel_ptr(int bank, int y, int x)
{
return &waveram[bank * (WAVERAM_HEIGHT * WAVERAM_WIDTH) + y * WAVERAM_WIDTH + (x & ~1)];
}
INLINE void waveram_plot(int y, int x, UINT16 color)
{
if (x >= 0 && x < 400 && y >= 0 && y < 256)
{
UINT32 *ptr = waveram_pixel_ptr(1, y, x);
if (x & 1)
*ptr = (*ptr & 0x0000ffff) | (color << 16);
else
*ptr = (*ptr & 0xffff0000) | color;
}
}
INLINE void waveram_plot_depth(int y, int x, UINT16 color, UINT16 depth)
{
if (x >= 0 && x < 400 && y >= 0 && y < 256)
{
UINT32 *ptr = waveram_pixel_ptr(1, y, x);
if (x & 1)
{
ptr[0] = (ptr[0] & 0x0000ffff) | (color << 16);
ptr[1] = (ptr[1] & 0x0000ffff) | (depth << 16);
}
else
{
ptr[0] = (ptr[0] & 0xffff0000) | color;
ptr[1] = (ptr[1] & 0xffff0000) | depth;
}
}
}
INLINE void waveram_plot_check_depth(int y, int x, UINT16 color, UINT16 depth)
{
if (x >= 0 && x < 400 && y >= 0 && y < 256)
{
UINT32 *ptr = waveram_pixel_ptr(1, y, x);
if (x & 1)
{
if (depth <= (ptr[1] >> 16))
{
ptr[0] = (ptr[0] & 0x0000ffff) | (color << 16);
ptr[1] = (ptr[1] & 0x0000ffff) | (depth << 16);
}
}
else
{
if (depth <= (ptr[1] & 0xffff))
{
ptr[0] = (ptr[0] & 0xffff0000) | color;
ptr[1] = (ptr[1] & 0xffff0000) | depth;
}
}
}
}
INLINE UINT32 *zeus_pixaddr(void)
{
int bank = (zeusbase[0xb6] >> 31) & 1;
int x = (zeusbase[0xb4] & 0xff) << 1;
int y = ((zeusbase[0xb4] >> 15) & 0xffe) | ((zeusbase[0xb4] >> 8) & 0x01);
return waveram_pixel_ptr(bank, y, x);
}
INLINE UINT8 get_texel_8bit(const UINT32 *base, int y, int x, int width)
{
if (x >= width)
return 0;
base += (y / 2) * (width / 2) + (x / 4) * 2 + (y & 1);
return *base >> (8 * (x & 3));
}
INLINE UINT8 get_texel_4bit(const UINT32 *base, int y, int x, int width)
{
if (x >= width * 2)
return 0;
base += (y / 2) * (width / 2) + (x / 8) * 2 + (y & 1);
return (*base >> (4 * (x & 7))) & 0x0f;
}
/*************************************
*
* Video startup
*
*************************************/
VIDEO_START( midzeus )
{
int i;
/* allocate memory for "wave" RAM */
waveram = auto_malloc(2 * WAVERAM_WIDTH * WAVERAM_HEIGHT * sizeof(*waveram));
state_save_register_global_pointer(waveram, 2 * WAVERAM_WIDTH * WAVERAM_HEIGHT);
/* initialize a 5-5-5 palette */
for (i = 0; i < 32768; i++)
palette_set_color_rgb(machine, i, pal5bit(i >> 10), pal5bit(i >> 5), pal5bit(i >> 0));
/* initialize polygon engine */
poly = poly_alloc(1000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
/* we need to cleanup on exit */
add_exit_callback(machine, exit_handler);
}
static void exit_handler(running_machine *machine)
{
FILE *f = fopen("waveram.dmp", "w");
int i;
for (i = 0; i < 2 * WAVERAM_WIDTH * WAVERAM_HEIGHT; i += 2)
{
if (i % 8 == 0) fprintf(f, "%03X%03X: ", (i / 1024), (i / 2) & 0x1ff);
fprintf(f, " %08X %08X ", waveram[i+0], waveram[i+1]);
if (i % 8 == 6) fprintf(f, "\n");
}
fclose(f);
}
/*************************************
*
* Video update
*
*************************************/
VIDEO_UPDATE( midzeus )
{
int x, y;
/* normal update case */
if (!input_code_pressed(KEYCODE_W))
{
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
{
UINT32 *src = waveram_pixel_ptr(1, y, 0);
UINT16 *dest = (UINT16 *)bitmap->base + y * bitmap->rowpixels;
for (x = cliprect->min_x; x <= cliprect->max_x; x += 2)
{
UINT32 pixels = *src;
dest[x+0] = pixels & 0x7fff;
dest[x+1] = (pixels >> 16) & 0x7fff;
src += 2;
}
}
}
/* waveram drawing case */
else
{
static int yoffs = 0;
static int width = 256;
UINT32 *base;
if (input_code_pressed(KEYCODE_DOWN)) yoffs += input_code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1;
if (input_code_pressed(KEYCODE_UP)) yoffs -= input_code_pressed(KEYCODE_LSHIFT) ? 0x40 : 1;
if (input_code_pressed(KEYCODE_LEFT) && width > 4) { width >>= 1; while (input_code_pressed(KEYCODE_LEFT)) ; }
if (input_code_pressed(KEYCODE_RIGHT) && width < 512) { width <<= 1; while (input_code_pressed(KEYCODE_RIGHT)) ; }
if (yoffs < 0) yoffs = 0;
base = waveram_ptr_from_addr(yoffs << 12);
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
{
UINT16 *dest = (UINT16 *)bitmap->base + y * bitmap->rowpixels;
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
{
UINT8 tex = get_texel_8bit(base, y, x, width);
dest[x] = (tex << 8) | tex;
}
}
popmessage("offs = %06X", yoffs << 12);
}
if (input_code_pressed(KEYCODE_T) && last_tex_index != 0)
{
int i;
printf("----\n");
for (i = 0; i < last_tex_index; i++)
printf("%06X %03X (w=%d)\n", last_tex[i][0], last_tex[i][1], 512 >> ((last_tex[i][1] >> 6) & 7));
last_tex_index = 0;
}
return 0;
}
/*
New analysis:
Offset
------
$58 W Usually written after $5A; after writing, waits for $F6 bit 4 to be cleared
$5A W Usually written first, followed by $58
$68 W Written at startup:
$00030000 = toggled on then off at startup
$76 W
$7C W
$80 W Master control
$40000000 = set along with $02000000 when enabling FIFO empty interrupt
$02000000 = enable internal data FIFO empty interrupt
$01000000 = cleared along with $02000000 when disabling FIFO empty interrupt
$00020000 = 16-bit (0) or 32-bit (1) mode
$00000008 = cleared just before writing to offsets $200-$3FF
$82 W
$84 W
$86 W
$88 W
$8A W
$8C W
$8E W
$B0 R/W Data port for direct RAM access
$B2 R/W Data port for direct RAM access
$B4 W Address for direct RAM access
$07FF0100 = mask for Y coordinate
$000000FF = mask for X coordinate
$B6 W Direct RAM access control
$80000000 = enable writes to wave RAM 0
$40000000 = enable writes to wave RAM 1
$02000000 = perform access on write to B0(0) or B2(1) ?????
$00800000 = enable writes from [$B2] to depth buffer
$00400000 = enable writes from [$B0] to depth buffer
$00200000 = enable writes from [$B2] to RAM buffer
$00100000 = enable writes from [$B0] to RAM buffer
$00020000 = auto increment the address
$00010000 = perform a read when the address is written
$00000001 = enable direct RAM access
Examples:
$80A00000 when writing a single pixel (address written each time)
$80A20001 when writing the right pixel of a pair (autoinc assumed)
$80F60001 when writing the middle pairs of pixels (autoinc assumed)
$80520001 when writing the left pixel of a pair (autoinc assumed)
$82F00001 when testing wave RAM page 1 (address written each pair)
$42F00001 when testing wave RAM page 0 (address written each pair)
$82F60001 when uploading to wave RAM page 1 (autoinc assumed)
$42F60001 when uploading to wave RAM page 0 (autoinc assumed)
$C0 W Written at startup = $801F2500
$C2 W Written at startup = $0015E591
$C4 W Written at startup = $000C0042 (HSYNC start/HSYNC end?)
$C6 W Written at startup = $0211007F (HTOTAL/HBLANK end?)
$C8 W Written at startup = $010300FF (VSYNC start/VBLANK start?)
$CA W Written at startup = $01160107 (VTOTAL/VSYNC end?)
$CC W Written at startup = $00000000
$CE W Written at startup = $00C87620
$E0 W Internal data FIFO
$F2 R Looped on until it returns a stable value; must change frequently; PRNG?
$F4 R Status register
$00000800 = VBLANK? code waits for it to clear to 0 and then reset to 1
$00000140 = tested together in tight loop until both are 0
$00000008 = internal data FIFO full
$00000004 = tested in tight loop along with $00000002 until at least one is set
$00000002 = tested in tight loop after handling FIFO interrupt until set
$F6 R Status register 2
$00000010 = tested in tight loop after writing 5A/59/58 until set to 0
$200- W Unknown, but written in a loop with master control bit $00000008 cleared
$3FF Possible fast buffer clear? One set of writes stores $7F7F to all entries.
A second set writes $E00,$25,$E01,$25,...,$E7F,$25. A third set writes
$52,$A0000000,...
Notes:
In 16-bit mode, writes to $E0 are done via $E1 first then $E0
-------------------------------------------------------
Old info:
offset B7 = control....
8000 = page 1 enable
4000 = page 0 enable
0080 = 2nd pixel enable (maybe Z buff?)
0040 = 1st pixel enable (maybe Z buff?)
0020 = 2nd pixel enable
0010 = 1st pixel enable
writes 80a2 to write an odd pixel at startup
writes 80f6 to write the middle pixels
writes 8052 to write an odd pixel at the end
writes 8050 before writing an odd pixel
writes 80a0 before writing an even pixel
writes 44f1 before reading from page 0 of wave ram
writes 84f1 before reading from page 1 of wave ram
writes 42f0 before writing to page 0 of wave ram
writes 82f0 before writing to page 1 of wave ram
*/
/*
zeus data notes:
Data from $1000-1A20
Palettes at $2000,$2200,$2400
Data from $2600-27C7
Palettes at $27C8,$29C8,$2BC8,$2DC8
Palettes up through $5A000
Interesting data at $5A000-5BFFF
Common sequence:
$8000 xxxx $0C01 $3805
x = matches address of next data * 8
*/
/*
Control = $80F6 when doing initial screen clear.
Writes 256 consecutive values to $B0, must mean autoincrement
Uses latched value in $B2 (maybe also in $B0)
Control = $82F0 when doing video RAM test write phase.
Writes 512 values across, but updates address before each one.
Control = $84F1 when doing video RAM test read phase.
Reads 512 values across, but updates address before each one.
Control = $80F2 when doing screen clear.
Writes 256 consecutive values to $B0, must mean autoincrement.
Uses latched value in $B2 (maybe also in $B0)
Control = $80A0/$8050 when plotting pixels.
Control = $42F0 when doing wave RAM test write phase.
Writes 512 values across, but updates address before each one.
Control = $44F1 when doing wave RAM test read phase.
Reads 512 values across, but updates address before each one.
*/
/*
Known commands:
$00rrxxxx = another type of register set?
yyyyyyyy
$0000C040 = set palette to 'yyyyyyyy'
$17rrxxxx = 16-bit write 'xxxx' to register 'rr'
$1752xxxx = write 'xxxx' to something that reflects back through $B2
$1770xxxx = write 'xxxx' to upper 16 bits of X coordinate
$1772xxxx = write 'xxxx' to upper 16 bits of Y coordinate
$1774xxxx = write 'xxxx' to upper 16 bits of Z coordinate
$18rr0000 = 32-bit write 'xxxxxxxx' to register 'rr'
xxxxxxxx
$1A000000 = pipeline synchronize (guess)
$1C00cccc = load matrix (abc)(def)(ghi) and point (xyz)
ffffiiii
bbbbaaaa
eeeedddd
hhhhgggg
xxxxxxxx
yyyyyyyy
zzzzzzzz
$6700xxxx = render object described at 'bbbbbb' in waveram
aabbbbbb
ccddcccc
*/
/*
Zeus cmd 18 : 18D60000 500A00FF
Zeus cmd 00 : 0005C0A5 21001125
Zeus cmd 25 : 25000000 007F0018 01000400 B0F60008
Zeus cmd 18 : 18D60000 500A00FF
Zeus cmd 18 : 18CE0000 00FFFFFF
Zeus cmd 1A : 1A000000
Zeus cmd 18 : 187E0000 0000FFFF
Zeus cmd 1A : 1A000000
Zeus cmd 18 : 18CE0000 00FFFFFF
Zeus cmd 1A : 1A000000
Zeus cmd 18 : 187E0000 FF980000
Zeus cmd 00 : 0080C0A5 3F00102F
Zeus cmd 17 : 17681370
Zeus cmd 17 : 176940C4
Zeus cmd 1C : ( 4000 0000 0000 ) ( 0000 4000 0000 ) ( 0000 0000 4000 ) -152.00 -50.00 1.25000
Zeus cmd 00 : 0000C040 0318E132 -> palette @ (18E,132)
Zeus cmd 67 : 67008000 0919F1C4 151 01FA4C -> render @ (19F,1C4)
Zeus cmd 1C : ( 4000 0000 0000 ) ( 0000 4000 0000 ) ( 0000 0000 4000 ) -135.00 -50.00 1.25000
Zeus cmd 67 : 67008000 0919F1C4 151 01FA4C
Zeus cmd 1C : ( 4000 0000 0000 ) ( 0000 4000 0000 ) ( 0000 0000 4000 ) -118.00 -50.00 1.25000
Zeus cmd 67 : 67008000 0919F1C4 151 01F988
Zeus cmd 1C : ( 4000 0000 0000 ) ( 0000 4000 0000 ) ( 0000 0000 4000 ) -101.00 -50.00 1.25000
19F1BA: 19DC0000 00000000 19840000 00F01605 25810000 21010000 FFD00000 00000000 FFD00038 000E0000 00080038 0E0E0000 00080000 0E000000 30000000 30000000 30000000 30000000 08000000 00000000
19F1C4: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFD0FFFC 00000000 FFD0003C 00100000 0008003C 0E100000 0008FFFC 0E000000 30000000 30000000 30000000 30000000 08000000 00000000
19F1CE: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFD0FFFC 00000000 FFD00028 000B0000 00080028 0E0B0000 0008FFFC 0E000000 30000000 30000000 30000000 30000000 08000000 00000000
19F1D8: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFD00000 00000000 FFD00034 000D0000 00080034 0E0D0000 00080000 0E000000 30000000 30000000 30000000 30000000 08000000 00000000
19F1E2: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFD00000 00000000 FFD00028 000A0000 000C0028 0F0A0000 000C0000 0F000000 30000000 30000000 30000000 30000000 08000000 00000000
19F1EC: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFD00000 00000000 FFD00014 00050000 00080014 0E050000 00080000 0E000000 30000000 30000000 30000000 30000000 08000000 00000000
19F1F6: 19DC0000 00000000 19840000 00F01605 25810000 21010000 FFD0FFFC 00000000 FFD00034 000E0000 00080034 0E0E0000 0008FFFC 0E000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0000: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFCC0000 00000000 FFCC0038 000E0000 000C0038 100E0000 000C0000 10000000 30000000 30000000 30000000 30000000 08000000 00000000
1A000A: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFCC0000 00000000 FFCC0034 000D0000 000C0034 100D0000 000C0000 10000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0014: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFCC0000 00000000 FFCC002C 000B0000 0008002C 0F0B0000 00080000 0F000000 30000000 30000000 30000000 30000000 08000000 00000000
1A001E: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFCC0000 00000000 FFCC002C 000B0000 000C002C 100B0000 000C0000 10000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0028: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFD00000 00000000 FFD0002C 000B0000 000C002C 0F0B0000 000C0000 0F000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0032: 19DC0000 00000000 19840000 00F01605 25800000 21010000 FFD00000 00000000 FFD00018 00060000 00080018 0E060000 00080000 0E000000 30000000 30000000 30000000 30000000 08000000 00000000
1A003C: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF9CFF64 00000000 FF9C0084 00480000 005C0084 30480000 005CFF64 30000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0046: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF80FF48 00000000 FF80009C 00550000 0070009C 3C550000 0070FF48 3C000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0050: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF68FF30 00000000 FF6800B0 00600000 008800B0 48600000 0088FF30 48000000 30000000 30000000 30000000 30000000 08000000 00000000
1A005A: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF54FF20 00000000 FF5400C4 00690000 00A000C4 53690000 00A0FF20 53000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0064: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF44FF10 00000000 FF4400D4 00710000 00B000D4 5B710000 00B0FF10 5B000000 30000000 30000000 30000000 30000000 08000000 00000000
1A006E: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF3CFF08 00000000 FF3C00E4 00770000 00B400E4 5E770000 00B4FF08 5E000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0078: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF38FEFC 00000000 FF3800E4 007A0000 00C000E4 627A0000 00C0FEFC 62000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0082: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF28FEFC 00000000 FF2800EC 007C0000 00C000EC 667C0000 00C0FEFC 66000000 30000000 30000000 30000000 30000000 08000000 00000000
1A008C: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF60FF28 00000000 FF6000C0 00660000 009C00C0 4F660000 009CFF28 4F000000 30000000 30000000 30000000 30000000 08000000 00000000
1A0096: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF80FF48 00000000 FF80009C 00550000 0078009C 3E550000 0078FF48 3E000000 30000000 30000000 30000000 30000000 08000000 00000000
1A00A0: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FF94FF5C 00000000 FF940088 004B0000 00640088 344B0000 0064FF5C 34000000 30000000 30000000 30000000 30000000 08000000 00000000
1A00AA: 19DC0000 40B68800 19840000 00001604 25810000 21010000 FFA4FF6C 00000000 FFA4007C 00440000 0054007C 2C440000 0054FF6C 2C000000 30000000 30000000 30000000 30000000 08000000 00000000
1A00B4: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FFACFF78 00000000 FFAC0070 003E0000 00480070 273E0000 0048FF78 27000000 30000000 30000000 30000000 30000000 08000000 00000000
1A00BE: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FFB4FF7C 00000000 FFB4006C 003C0000 0044006C 243C0000 0044FF7C 24000000 30000000 30000000 30000000 30000000 08000000 00000000
1A00C8: 19DC0000 00000000 19840000 00001605 25800000 21000000 FF42FF02 00000000 FF4200FE 007F0000 00BE00FE 5F7F0000 00BEFF02 5F000000 30000000 30000000 30000000 30000000 08000000 00000000
1A00D2: 19DC0000 00000000 19840000 00001605 25800000 21010000 FFB0FF70 00000000 FFB0007C 00430000 0054007C 29430000 0054FF70 29000000 30000000 30000000 30000000 30000000 08000000 00000000
1A00DC: 19DC0000 40B68800 19840000 00001604 25800000 21010000 FA10F810 00000000 FA1007F0 007F0000 05F007F0 5F7F0000 05F0F810 5F000000 30000000 30000000 30000000 30000000 08000000 00000000
1A00E6: 0C02C0F0 0F18E1BE
19DC0000 4B23CB00 19840000 00001605 252978EF 200C0000 04480000 00000000 043D0000 0000001E 043DFFEB 00000015 043DFFEB 00000015 00040000 0A331400 0743178C 0743178C
1A00F0: 251178D7 200C0000 04480000 00000000 043DFFEB 00000015 043DFFE2 00000000 043DFFE2 00000000 00040000 0743178C 0003175D 0003175D
25EF78D7 200C0000 04480000 00000000 043DFFE2 00000000 043DFFEB 0000FFEB 043DFFEB 0000FFEB 00040000 0003175D 38C3178C 38C3178C
25D778EF 200C0000 04480000 00000000 043DFFEB 0000FFEB 043D0000 0000FFE2 043D0000 0000FFE2 00040000 38C3178C 35D31400 35D31400
25D77811 200C0000 04480000 00000000 043D0000 0000FFE2 043D0015 0000FFEB 043D0015 0000FFEB 00040000 35D31400 38C31474 38C31474
1A010C: 25EF7829 200C0000 04480000 00000000 043D0015 0000FFEB 043D001E 00000000 043D001E 00000000 00040000 38C31474 000314A3 000314A3
25117829 200C0000 04480000 00000000 043D001E 00000000 043D0015 00000015 043D0015 00000015 00040000 000314A3 07431474 07431474
25297811 200C0000 04480000 00000000 043D0015 00000015 043D0000 0000001E 043D0000 0000001E 00040000 07431474 0A331400 0A331400
0C018000 381A0122
252186F3 200C0000 F64A0000 00000000 F652FFEB 00000015 F6520000 0000001E F6520000 0000001E 000C0000 06ECD393 09ACD3FF 09ACD3FF
250D86DF 200C0000 F64A0000 00000000 F652FFE2 00000000 F652FFEB 00000015 F652FFEB 00000015 000C0000 001CD366 06DCD392 06DCD392
1A0130: 25F386DF 200C0000 F64A0000 00000000 F652FFEB 0000FFEB F652FFE2 00000000 F652FFE2 00000000 000C0000 393CD392 3FFCD366 3FFCD366
25DF86F3 200C0000 F64A0000 00000000 F6520000 0000FFE2 F652FFEB 0000FFEB F652FFEB 0000FFEB 000C0000 366CD3FF 392CD393 392CD393
25DF860D 200C0000 F64A0000 00000000 F6520015 0000FFEB F6520000 0000FFE2 F6520000 0000FFE2 000C0000 392CD06D 366CD001 366CD001
25F38621 200C0000 F64A0000 00000000 F652001E 00000000 F6520015 0000FFEB F6520015 0000FFEB 000C0000 3FFCD09A 393CD06E 393CD06E
1A014C: 250D8621 200C0000 F64A0000 00000000 F6520015 00000015 F652001E 00000000 F652001E 00000000 000C0000 06DCD06E 001CD09A 001CD09A
2521860D 200C0000 F6520000 0000001E F6520015 00000015 F64A0000 00000000 F64A0000 00000000 09ACD001 06ECD06D 000C0000 000C0000
0C018000 381A015B
25D53969 200C0000 0429001D 0000FFE3 04290029 00000000 043D001E 00000000 043D0015 0000FFEB 356110B3 3FA110F7 3EB2D8B3 3902D88D
252B3969 200C0000 04290029 00000000 0429001D 0000001D 043D0015 00000015 043D001E 00000000 006110F7 0AA110B3 0702D88D 0152D8B3
2569392B 200C0000 0429001D 0000001D 04290000 00000029 043D0000 0000001E 043D0015 00000015 0B3110AA 0F711006 0B32D815 08D2D870
1A0170: 256939D5 200C0000 04290000 00000029 0429FFE3 0000001D 043DFFEB 00000015 043D0000 0000001E 0F7113FA 0B311356 08D2DB90 0B32DBEB
252B3997 200C0000 0429FFE3 0000001D 0429FFD7 00000000 043DFFE2 00000000 043DFFEB 00000015 0AA1134D 00611309 0152DB4D 0702DB73
25D53997 200C0000 0429FFD7 00000000 0429FFE3 0000FFE3 043DFFEB 0000FFEB 043DFFE2 00000000 3FA11309 3561134D 3902DB73 3EB2DB4D
259739D5 200C0000 0429FFE3 0000FFE3 04290000 0000FFD7 043D0000 0000FFE2 043DFFEB 0000FFEB 34D11356 309113FA 34D2DBEB 3732DB90
1A018C: 2597392B 200C0000 04290000 0000FFD7 0429001D 0000FFE3 043D0015 0000FFEB 043D0000 0000FFE2 30911006 34D110AA 3732D870 34D2D815
0C018000 381A0194
1A0194: 252BC769 200C0000 F666001D 0000001D F6660029 00000000 F652001E 00000000 F6520015 00000015 0AAEF0B3 006EF0F7 018D20B0 06CD208D
25D5C769 200C0000 F6660029 00000000 F666001D 0000FFE3 F6520015 0000FFEB F652001E 00000000 3FAEF0F7 356EF0B3 394D208D 3E8D20B0
2597C72B 200C0000 F666001D 0000FFE3 F6660000 0000FFD7 F6520000 0000FFE2 F6520015 0000FFEB 34DEF0AA 309EF006 350D2018 373D206C
2597C7D5 200C0000 F6660000 0000FFD7 F666FFE3 0000FFE3 F652FFEB 0000FFEB F6520000 0000FFE2 309EF3FA 34DEF356 373D2394 350D23E8
1A01B0: 25D5C797 200C0000 F666FFE3 0000FFE3 F666FFD7 00000000 F652FFE2 00000000 F652FFEB 0000FFEB 356EF34D 3FAEF309 3E8D2350 394D2373
252BC797 200C0000 F666FFD7 00000000 F666FFE3 0000001D F652FFEB 00000015 F652FFE2 00000000 006EF309 0AAEF34D 06CD2373 018D2350
2569C7D5 200C0000 F666FFE3 0000001D F6660000 00000029 F6520000 0000001E F652FFEB 00000015 0B3EF356 0F7EF3FA 0B0D23E8 08DD2394
2569C72B 200C0000 F6660000 00000029 F666001D 0000001D F6520015 00000015 F6520000 0000001E 0F7EF006 0B3EF0AA 08DD206C 0B0D2018
1A01CC: 0C018000 311A01CD
25300076 200C0000 F6660029 00000000 F666001D 0000001D 0429001D 0000001D 04290029 00000000 00FF24FA 0A6F24BB 0A60DCBB 00F0DCFA
1A01D4: 25760030 200C0000 F666001D 0000001D F6660000 00000029 04290000 00000029 0429001D 0000001D 0BBF24A6 0FAF240F 0FA0DC0F 0BB0DCA6
257600D0 200C0000 F6660000 00000029 F666FFE3 0000001D 0429FFE3 0000001D 04290000 00000029 0FAF27F1 0BBF275A 0BB0DF5A 0FA0DFF1
2530008A 200C0000 F666FFE3 0000001D F666FFD7 00000000 0429FFD7 00000000 0429FFE3 0000001D 0A6F2745 00FF2706 00F0DF06 0A60DF45
25D0008A 200C0000 F666FFD7 00000000 F666FFE3 0000FFE3 0429FFE3 0000FFE3 0429FFD7 00000000 3F1F2706 35AF2745 35A0DF45 3F10DF06
1A01F0: 258A00D0 200C0000 F666FFE3 0000FFE3 F6660000 0000FFD7 04290000 0000FFD7 0429FFE3 0000FFE3 345F275A 306F27F1 3060DFF1 3450DF5A
258A0030 200C0000 F6660000 0000FFD7 F666001D 0000FFE3 0429001D 0000FFE3 04290000 0000FFD7 306F240F 345F24A6 3450DCA6 3060DC0F
0C018000 071A1000 00000000 00000000
1A1000: 25D00076 200C0000 F666001D 0000FFE3 F6660029 00000000 04290029 00000000 0429001D 0000FFE3 35AF24BB 3F1F24FA 3F10DCFA 35A0DCBB
08000000 00000000
*/
static void render_poly_4bit(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
{
const poly_extra_data *extra = extradata;
float ooz = extent->param[0].start;
float uoz = extent->param[1].start;
float voz = extent->param[2].start;
float doozdx = extent->param[0].dpdx;
float duozdx = extent->param[1].dpdx;
float dvozdx = extent->param[2].dpdx;
const UINT32 *texbase = extra->texbase;
const UINT32 *palbase = extra->palbase;
UINT16 transcolor = extra->transcolor;
int texwidth = extra->texwidth;
int x;
for (x = extent->startx; x < extent->stopx; x++)
{
float z = recip_approx(ooz);
int u = (int)(uoz * z) & ((texwidth * 2) - 1);
int v = (int)(voz * z) & 255;
UINT8 texel = get_texel_4bit(texbase, v, u, texwidth);
if (texel != transcolor)
{
UINT16 color = palbase[texel >> 1] >> (16 * (texel & 1));
INT32 depth = z * 256.0f;
if (depth > 0x7fff) depth = 0x7fff;
if (depth >= 0)
waveram_plot_check_depth(scanline, x, color, depth);
}
ooz += doozdx;
uoz += duozdx;
voz += dvozdx;
}
}
static void render_poly_8bit(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
{
const poly_extra_data *extra = extradata;
float ooz = extent->param[0].start;
float uoz = extent->param[1].start;
float voz = extent->param[2].start;
float doozdx = extent->param[0].dpdx;
float duozdx = extent->param[1].dpdx;
float dvozdx = extent->param[2].dpdx;
const UINT32 *texbase = extra->texbase;
const UINT32 *palbase = extra->palbase;
UINT16 transcolor = extra->transcolor;
int texwidth = extra->texwidth;
int x;
for (x = extent->startx; x < extent->stopx; x++)
{
float z = recip_approx(ooz);
int u = (int)(uoz * z) & (texwidth - 1);
int v = (int)(voz * z) & 255;
UINT8 texel = get_texel_8bit(texbase, v, u, texwidth);
if (texel != transcolor)
{
UINT16 color = palbase[texel >> 1] >> (16 * (texel & 1));
INT32 depth = z * 256.0f;
if (depth > 0x7fff) depth = 0x7fff;
if (depth >= 0)
waveram_plot_check_depth(scanline, x, color, depth);
}
ooz += doozdx;
uoz += duozdx;
voz += dvozdx;
}
}
static void zeus_draw_polys(UINT32 addr_and_count, UINT32 texdata, int logcmd)
{
static UINT32 *loglist[1000];
static int loglist_last = 0;
UINT32 *data = waveram_ptr_from_addr(addr_and_count);
UINT32 val1, val2;
int i, logit = FALSE;
int texwshift;
int testbit = 0;
val1 = ((texdata >> 10) & 0x3f0000) | (texdata & 0xffff);
val2 = (texdata >> 16) & 0x3ff;
texwshift = (val2 >> 6) & 7;
if (logcmd)
{
int texwshift = (val2 >> 6) & 7;
logerror("Zeus cmd 67 : %08X %08X %03X %06X (w=%d adj=%03X%03X)\n",
zeuscmd_buffer[0], addr_and_count, val2, val1,
512 >> texwshift,
((val1 << (7 - texwshift)) >> 10) & 0xfff,
((val1 << (7 - texwshift)) >> 1) & 0x1ff
);
}
for (i = 0; i < last_tex_index; i++)
if (last_tex[i][0] == val1 && last_tex[i][1] == val2)
break;
if (i == last_tex_index)
{
last_tex[i][0] = val1;
last_tex[i][1] = val2;
last_tex_index++;
}
if (logcmd)
{
for (i = 0; i < loglist_last; i++)
if (loglist[i] == data)
break;
logit = (i == loglist_last);
if (i == loglist_last)
loglist[loglist_last++] = data;
}
if (input_code_pressed(KEYCODE_Z)) testbit = 1;
if (input_code_pressed(KEYCODE_X)) testbit = 2;
if (input_code_pressed(KEYCODE_C)) testbit = 3;
if (input_code_pressed(KEYCODE_V)) testbit = 4;
if (input_code_pressed(KEYCODE_B)) testbit = 5;
if (input_code_pressed(KEYCODE_N)) testbit = 6;
if (input_code_pressed(KEYCODE_M)) testbit = 7;
if (testbit != 0)
texwshift = testbit;
while (1)
{
const UINT32 *data = waveram_ptr_from_addr(addr_and_count);
int count = ((addr_and_count >> 24) + 1) * 2;
UINT32 next_addr_and_count = 0;
int datanum;
int length;
for (datanum = 0; datanum < count; datanum += length * 2)
{
int offs;
length = ((data[datanum] >> 24) == 0x25 || (data[datanum] >> 24) == 0x30) ? 7 : 1;
if (logit)
{
logerror("\t%08X", data[datanum]);
for (offs = 1; offs < length * 2; offs++)
logerror(" %08X", data[datanum + offs]);
logerror("\n");
}
if ((data[datanum] >> 24) == 0x25 || (data[datanum] >> 24) == 0x30 /* invasn */)
{
poly_draw_scanline callback;
poly_extra_data *extra;
poly_vertex vert[4];
int i;
callback = (val2 & 0x20) ? render_poly_8bit : render_poly_4bit;
for (i = 0; i < 4; i++)
{
UINT32 ixy = data[datanum + 2 + 2*i];
UINT32 iuvz = data[datanum + 3 + 2*i];
INT32 xo = (INT16)ixy;
INT32 yo = (INT16)(ixy >> 16);
INT32 zo = (INT16)iuvz;
UINT8 u = iuvz >> 16;
UINT8 v = iuvz >> 24;
float z, ooz;
vert[i].x = (xo * zeus_matrix[0][0] + yo * zeus_matrix[0][1] + zo * zeus_matrix[0][2] + zeus_point[0]) * (1.0f / 65536.0f);
vert[i].y = (xo * zeus_matrix[1][0] + yo * zeus_matrix[1][1] + zo * zeus_matrix[1][2] + zeus_point[1]) * (1.0f / 65536.0f);
z = (xo * zeus_matrix[2][0] + yo * zeus_matrix[2][1] + zo * zeus_matrix[2][2] + zeus_point[2]) * (1.0f / (512.0f * 65536.0f));
ooz = 1.0f / z;
vert[i].x *= ooz;
vert[i].y *= ooz;
vert[i].p[0] = ooz;
vert[i].p[1] = u * ooz;
vert[i].p[2] = v * ooz;
vert[i].x += 200.0f;
vert[i].y += 128.0f;
}
val1 <<= 7 - texwshift;
extra = poly_get_extra_data(poly);
extra->transcolor = 0x100;
extra->texbase = &waveram[val1 & 0x3fffff];
extra->texwidth = 512 >> texwshift;
extra->palbase = zeus_palbase;
extra->alpha = zeus_blend;
poly_render_quad(poly, NULL, &Machine->screen[0].visarea, callback, 3, &vert[0], &vert[1], &vert[2], &vert[3]);
poly_wait(poly, "Normal");
}
else if (data[datanum] == 0x0c018000)
next_addr_and_count = data[datanum + 1];
}
if (datanum != count)
logerror("Overran data\n");
if (next_addr_and_count == 0)
break;
else
addr_and_count = next_addr_and_count;
}
}
static void zeuscmd_execute(void)
{
static int colorcount;
int logcmd = input_code_pressed(KEYCODE_L);
int wordnum;
switch (zeuscmd_buffer[0] >> 24)
{
case 0x1c:
if (logcmd)
logerror("Zeus cmd 1C : ( %04X %04X %04X ) ( %04X %04X %04X ) ( %04X %04X %04X ) %8.2f %8.2f %8.5f\n",
zeuscmd_buffer[2] & 0xffff,
zeuscmd_buffer[2] >> 16,
zeuscmd_buffer[0] & 0xffff,
zeuscmd_buffer[3] & 0xffff,
zeuscmd_buffer[3] >> 16,
zeuscmd_buffer[1] >> 16,
zeuscmd_buffer[4] & 0xffff,
zeuscmd_buffer[4] >> 16,
zeuscmd_buffer[1] & 0xffff,
(float)(INT32)zeuscmd_buffer[5] * (1.0f / 65536.0f),
(float)(INT32)zeuscmd_buffer[6] * (1.0f / 65536.0f),
(float)(INT32)zeuscmd_buffer[7] * (1.0f / (65536.0f * 512.0f)));
zeus_matrix[0][0] = zeuscmd_buffer[2];
zeus_matrix[0][1] = zeuscmd_buffer[2] >> 16;
zeus_matrix[0][2] = zeuscmd_buffer[0];
zeus_matrix[1][0] = zeuscmd_buffer[3];
zeus_matrix[1][1] = zeuscmd_buffer[3] >> 16;
zeus_matrix[1][2] = zeuscmd_buffer[1] >> 16;
zeus_matrix[2][0] = zeuscmd_buffer[4];
zeus_matrix[2][1] = zeuscmd_buffer[4] >> 16;
zeus_matrix[2][2] = zeuscmd_buffer[1];
zeus_point[0] = zeuscmd_buffer[5];
zeus_point[1] = zeuscmd_buffer[6];
zeus_point[2] = zeuscmd_buffer[7];
break;
case 0x13: /* invasn */
zeus_draw_polys(zeus_objdata, zeus_texdata, logcmd);
break;
case 0x67:
zeus_draw_polys(zeuscmd_buffer[1], zeuscmd_buffer[2], logcmd);
break;
case 0x01: /* invasn */
if (logcmd)
logerror("Zeus cmd %02X : %08X %08X\n", zeuscmd_buffer[0] >> 24, zeuscmd_buffer[0], zeuscmd_buffer[1]);
if (zeuscmd_buffer[0] == 0x01008000)
zeus_objdata = zeuscmd_buffer[1];
else if (zeuscmd_buffer[0] == 0x0100c0b0)
zeus_texdata = zeuscmd_buffer[1];
else if (zeuscmd_buffer[0] == 0x0100C040)
zeus_palbase = waveram_ptr_from_addr(zeuscmd_buffer[1]);
break;
default:
if ((zeuscmd_buffer[0] >> 16) == 0x1752)
{
zeusbase[0xb2] = zeuscmd_buffer[0];
// zeus_enable_logging = 1;
}
if ((zeuscmd_buffer[0] >> 16) == 0x1770)
zeus_point[0] = zeuscmd_buffer[0] << 16;
if ((zeuscmd_buffer[0] >> 16) == 0x1772)
zeus_point[1] = zeuscmd_buffer[0] << 16;
if ((zeuscmd_buffer[0] >> 16) == 0x1774)
zeus_point[2] = zeuscmd_buffer[0] << 16;
if ((zeuscmd_buffer[0] >> 16) == 0x18ce)
zeus_blend = zeuscmd_buffer[1];
if (zeuscmd_buffer[0] == 0x0000c040)
zeus_palbase = waveram_ptr_from_addr(zeuscmd_buffer[1]);
if (zeuscmd_buffer[0] == 0x0080C0A5)
{
/* not right -- just a hack */
int x, y;
for (y = 0; y <= 255; y++)
for (x = 0; x <= 399; x++)
waveram_plot_depth(y, x, 0, 0x7fff);
colorcount = 0;
last_tex_index = 0;
}
if (logcmd)
{
logerror("Zeus cmd %02X : %08X", zeuscmd_buffer[0] >> 24, zeuscmd_buffer[0]);
for (wordnum = 1; wordnum < zeuscmd_buffer_expected_words; wordnum++)
logerror(" %08X", zeuscmd_buffer[wordnum]);
logerror("\n");
}
break;
}
}
static UINT8 zeuscmd_length(UINT32 word)
{
switch (word >> 24)
{
case 0x00:
case 0x01:
return (word == 0) ? 1 : 2;
case 0x13:
case 0x17:
case 0x1a:
case 0x2d: /* invasn */
case 0x70:
return 1;
case 0x18:
case 0x23:
case 0x2e: /* invasn */
return 2;
case 0x67:
return 3;
case 0x25:
case 0x30: /* invasn */
return 4; /* ??? */
case 0x1c:
return 8;
default:
printf("Unknown command %02X\n", zeusbase[0xe0] >> 24);
break;
}
return 1;
}
READ32_HANDLER( zeus_r )
{
int logit = (offset < 0xb0 || offset > 0xb7);
UINT32 result = zeusbase[offset & ~1];
switch (offset & ~1)
{
case 0x00:
// crusnexo wants bit 0x20 to be non-zero
result = 0x20;
break;
case 0x51:
// crusnexo expects a reflection of the data at 0x08 here (b425)
result = zeusbase[0x08];
break;
case 0xf2:
// polled frequently during gametime; expected to change often
// as it is polled multiple times and a consistent value is looked for
result = video_screen_get_vpos(0);
logit = 0;
break;
case 0xf4:
result = 6;
if (video_screen_get_vblank(0))
result |= 0x800;
logit = 0;
break;
case 0xf6: // status -- they wait for this & 9 == 0
if (zeusbase[0xb6] == 0x80040000)
result = 1;
else
result = 0;
logit = 0;
break;
}
/* 32-bit mode */
if (zeusbase[0x80] & 0x00020000)
{
if (offset & 1)
result >>= 16;
if (logit)
{
if (offset & 1)
logerror("%06X:zeus32_r(%02X) = %08X -- unexpected in 32-bit mode\n", activecpu_get_pc(), offset, result);
else if (offset != 0xe0)
logerror("%06X:zeus32_r(%02X) = %08X\n", activecpu_get_pc(), offset, result);
else
logerror("%06X:zeus32_r(%02X) = %08X\n", activecpu_get_pc(), offset, result);
}
}
/* 16-bit mode */
else
{
if (offset & 1)
result >>= 16;
else
result &= 0xffff;
if (logit)
logerror("%06X:zeus16_r(%02X) = %04X\n", activecpu_get_pc(), offset, result);
}
return result;
}
WRITE32_HANDLER( zeus_w )
{
int logit = zeus_enable_logging || ((offset < 0xb0 || offset > 0xb7) && (offset < 0xe0 || offset > 0xe1));
/* 32-bit mode */
if (zeusbase[0x80] & 0x00020000)
{
zeusbase[offset & ~1] = data;
if (logit)
{
if (offset & 1)
logerror("%06X:zeus32_w(%02X) = %08X -- unexpected in 32-bit mode\n", activecpu_get_pc(), offset, data);
else if (offset != 0xe0)
logerror("%06X:zeus32_w(%02X) = %08X\n", activecpu_get_pc(), offset, data);
else
logerror("%06X:zeus32_w(%02X) = %08X\n", activecpu_get_pc(), offset, data);
}
}
/* 16-bit mode */
else
{
if (offset & 1)
zeusbase[offset & ~1] = (zeusbase[offset & ~1] & 0x0000ffff) | (data << 16);
else
zeusbase[offset & ~1] = (zeusbase[offset & ~1] & 0xffff0000) | (data & 0xffff);
if (logit)
logerror("%06X:zeus16_w(%02X) = %04X [%08X]\n", activecpu_get_pc(), offset, data & 0xffff, zeusbase[offset & ~1]);
}
/* handle the writes; only trigger on low accesses */
switch (offset)
{
case 0x60:
/* invasn writes here to execute a command (?) */
if (zeusbase[0x60] & 1)
{
if (zeusbase[0x80] == 0x0022FCFF)
{
int startx, stopx, starty, stopy;
int x, y;
// zeusbase[0x00] = color
// zeusbase[0x02] = ??? = 0x000C0000
// zeusbase[0x04] = ??? = 0x00000E01
// zeusbase[0x06] = ??? = 0xFFFF0030
// zeusbase[0x08] = vert[0] = (y0 << 16) | x0
// zeusbase[0x0a] = vert[1] = (y1 << 16) | x1
// zeusbase[0x0c] = vert[2] = (y2 << 16) | x2
// zeusbase[0x0e] = vert[3] = (y3 << 16) | x3
// zeusbase[0x18] = ??? = 0xFFFFFFFF
// zeusbase[0x1a] = ??? = 0xFFFFFFFF
// zeusbase[0x1c] = ??? = 0xFFFFFFFF
// zeusbase[0x1e] = ??? = 0xFFFFFFFF
// zeusbase[0x20] = ??? = 0x00000000
// zeusbase[0x22] = ??? = 0x00000000
// zeusbase[0x24] = ??? = 0x00000000
// zeusbase[0x26] = ??? = 0x00000000
// zeusbase[0x40] = ??? = 0x00000000
// zeusbase[0x42] = ??? = 0x00000000
// zeusbase[0x44] = ??? = 0x00000000
// zeusbase[0x46] = ??? = 0x00000000
// zeusbase[0x4c] = ??? = 0x00808080 (brightness?)
// zeusbase[0x4e] = ??? = 0x00808080 (brightness?)
startx = (zeusbase[0x08] & 0xffff);
starty = zeusbase[0x08] >> 16;
stopx = (zeusbase[0x0c] & 0xffff);
stopy = zeusbase[0x0c] >> 16;
for (y = starty; y <= stopy; y++)
for (x = startx; x <= stopx; x++)
waveram[(1 * WAVERAM_HEIGHT + (y % WAVERAM_HEIGHT)) * WAVERAM_WIDTH + x] = zeusbase[0x00];
}
else
logerror("Execute unknown command\n");
}
break;
case 0xb0:
case 0xb2:
if ((zeusbase[0xb6] >> 16) != 0)
{
UINT32 *dest = zeus_pixaddr();
if ((offset == 0xb0 && (zeusbase[0xb6] & 0x02000000) == 0) ||
(offset == 0xb2 && (zeusbase[0xb6] & 0x02000000) != 0))
{
if (zeusbase[0xb6] & 0x00100000)
dest[0] = (dest[0] & 0xffff0000) | (zeusbase[0xb0] & 0x0000ffff);
if (zeusbase[0xb6] & 0x00200000)
dest[0] = (dest[0] & 0x0000ffff) | (zeusbase[0xb0] & 0xffff0000);
if (zeusbase[0xb6] & 0x00400000)
dest[1] = (dest[1] & 0xffff0000) | (zeusbase[0xb2] & 0x0000ffff);
if (zeusbase[0xb6] & 0x00800000)
dest[1] = (dest[1] & 0x0000ffff) | (zeusbase[0xb2] & 0xffff0000);
if (zeusbase[0xb6] & 0x00020000)
zeusbase[0xb4]++;
}
}
break;
case 0xb4:
if (zeusbase[0xb6] & 0x00010000)
{
UINT32 *src = zeus_pixaddr();
zeusbase[0xb0] = src[0];
zeusbase[0xb2] = src[1];
}
break;
case 0xe0:
zeuscmd_buffer[zeuscmd_buffer_words++] = zeusbase[0xe0];
if (zeuscmd_buffer_words == 1)
zeuscmd_buffer_expected_words = zeuscmd_length(zeusbase[0xe0]);
if (zeuscmd_buffer_words == zeuscmd_buffer_expected_words)
{
zeuscmd_execute();
zeuscmd_buffer_words = 0;
}
break;
}
}
READ32_HANDLER( zeus2_r )
{
return zeus_r(offset * 2, 0);
}
WRITE32_HANDLER( zeus2_w )
{
zeus_w(offset * 2, data, mem_mask);
}
|