/
funworld.cpp
9028 lines (7199 loc) · 420 KB
/
funworld.cpp
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
// license:BSD-3-Clause
// copyright-holders:Roberto Fresca, Grull Osgo, Andreas Naive, Peter Ferrie
/*********************************************************************************************
Fun World / Amatic / TAB / Impera
Series 7000 hardware.
65C02/65SC02 + 2x 6821 PIAs + 6845 CRTC + AY-3-8910.
From raw, to different ways of encryption. Even through custom CPUs.
Also from CMC, Dino4 (encrypted), and Leopard 4.
Driver by Roberto Fresca.
Based on a preliminary work of Curt Coder & Peter Trauner.
**********************************************************************************************
Games running on this hardware:
* Jolly Card (German, set 1), TAB Austria, 1985.
* Jolly Card (German, set 2), TAB Austria, 1985.
* Jolly Card (3x3 deal), TAB Austria, 1985.
* Jolly Card Professional 2.0 (MZS Tech), MZS Tech, 1993.
* Jolly Card Professional 2.0 (Spale Soft), Spale Soft, 2000.
* Jolly Card (Evona Electronic), Evona Electronic 1998.
* Jolly Card (Croatian, set 1), TAB Austria, 1985.
* Jolly Card (Croatian, set 2), Soft Design, 1993.
* Super Joly 2000 - 3x, M.P. 1985.
* Jolly Card (German, Fun World, bootleg), Inter Games, 1986.
* Jolly Card (Spanish, blue TAB board, encrypted), TAB Austria, 1992.
* Jolly Card (Italian, different colors, set 1), bootleg, 1990.
* Jolly Card (Italian, different colors, set 2), bootleg, 1990.
* Jolly Card (Italian, bootleg, set 1), bootleg, 1990.
* Jolly Card (Italian, bootleg, set 2), bootleg, 1993.
* Jolly Card (Italian, bootleg, set 3), bootleg, 1990.
* Jolly Game (V1, Otti Karl logo), bootleg, 1993.
* Bonus Card (German), Fun World, 1986.
* Bonus Card (German, ATG Electronic hack), Fun World, 1986.
* Big Deal (Hungarian, set 1), Fun World, 1986.
* Big Deal (Hungarian, set 2), Fun World, 1986.
* Cuore 1 (Italian, set 1), C.M.C., 1996.
* Cuore 1 (Italian, set 2), C.M.C., 1996.
* Cuore 1 (Italian, set 3), C.M.C., 1996.
* Cuore 1 (Italian, set 4), C.M.C., 1996.
* Cuore 1 (Italian, set 5), C.M.C., 1996.
* Cuore 1 (Italian, set 6), C.M.C., 1996.
* Cuore 1 (Italian, set 7), bootleg, 1996.
* Elephant Family (Italian, new), C.M.C., 1997.
* Elephant Family (Italian, old), C.M.C., 1996.
* Pool 10 (Italian, set 1), C.M.C., 1996.
* Pool 10 (Italian, set 2), C.M.C., 1996.
* Pool 10 (Italian, set 3), C.M.C., 1996.
* Pool 10 (Italian, set 4), C.M.C., 1997.
* Pool 10 (Italian, set 5), C.M.C., 1996.
* Pool 10 (Italian, set 6), C.M.C., 1996.
* Pool 10 (Italian, set 7), C.M.C., 1997.
* Pool 10 (Italian, set 8), C.M.C., 1997.
* Pool 10 (Italian, set 9), bootleg (R.B.), 1996.
* Pool 10 (Italian, set 10), C.M.C., 1997.
* Magic 10 Nevada (bootleg of Pool 10), bootleg (Magic), 1997.
* New Biliard 98 (Pool 10 hack), bootleg, 1998.
* Royal (Pool 10 hack), unknown, 2001.
* Tortuga Family (Italian), C.M.C., 1997.
* Pot Game (Italian), C.M.C., 1996.
* Bottle 10 (Italian, set 1), C.M.C., 1996.
* Bottle 10 (Italian, set 2), C.M.C., 1996.
* Luna Park (set 1, dual program), unknown, 1998.
* Luna Park (set 2, dual program), unknown, 1998.
* Luna Park (set 3), unknown, 1998.
* Crystal Colours (CMC hardware), J.C.D. srl, 1998.
* Royal Card (German, set 1), TAB Austria, 1991.
* Royal Card (German, set 2), TAB Austria, 1991.
* Royal Card (German/Polish, set 3), TAB Austria, 1991.
* Royal Card (German, set 4), TAB Austria, 1991.
* Royal Card (German, set 5), TAB Austria, 1991.
* Royal Card (German, set 6), TAB Austria, 1991.
* Royal Card (TAB original), TAB Austria, 1991.
* Royal Card (German, set 7, CMC C1030 HW), bootleg, 1991.
* Royal Card (German, set 8), TAB Austria, 1991.
* Royal Card (French), TAB Austria, 1991.
* Royal Card v2.0 Professional, Digital Dreams, 1993.
* Royal Card / Royal Jackpot (with a third draw)(encrypted), TAB / Video Klein, 1991
* Witch Royal (Export version 2.1), Video Klein, 199?.
* Lucky Lady (3x3 deal), TAB Austria, 1991.
* Lucky Lady (4x1 aces), TAB Austria, 1991.
* Magic Card II (Bulgarian), Impera, 1996.
* Magic Card II (Nov, Yugoslavian), Impera, 1996.
* Magic Card II (green TAB or Impera board), Impera, 1996.
* Magic Card II (blue TAB board, encrypted), Impera, 1996.
* Royal Vegas Joker Card (Slow deal), Fun World, 1993.
* Royal Vegas Joker Card (Fast deal), Soft Design, 1993.
* Royal Vegas Joker Card (Fast deal, english gfx), Soft Design, 1993.
* Royal Vegas Joker Card (Fast deal, Mile), Mile, 1993.
* Jolly Joker (98bet, set 1). Impera, 199?.
* Jolly Joker (98bet, set 2). Impera, 199?.
* Jolly Joker (40bet, higher paytable), Impera, 1985.
* Jolly Joker (40bet, lower paytable), Impera, 1985.
* Jolly Joker (Apple Time), Apple Time, 199?.
* Jolly Joker (original program, interleaved GFX, Impera logo), Impera, 199?.
* Jolly Joker (original program, interleaved GFX, no logo), Impera, 199?.
* Jolly Joker (original program, interleaved GFX, Otti Karl logo, set 1), Impera, 199?.
* Jolly Joker (original program, interleaved GFX, Otti Karl logo, set 2), Impera, 199?.
* Jolly Joker (Solid State module in suicide board). Impera, 199?.
* Multi Win (Ver.0167, encrypted), Fun World, 1992.
* Multi Win (Ver.0091, encrypted), Fun World, 1991.
* Multi Win (EPM7032, encrypted), Amatic, 2001.
* Power Card (Ver 0263, encrypted), Fun World, 1993.
* Mega Card (Ver.0210, encrypted), Fun World, 1993.
* Mega Card (Ver.0053, encrypted), Fun World, 1992.
* Joker Card 300 (Ver.A267BC, encrypted), Amatic Trading, 1993.
* Royal Card (Evona, Polish, encrypted), Evona Electronic, 1991.
* Saloon (French, encrypted), unknown, 199?.
* Nevada (French, encrypted), unknown, 199?.
* Jolly Card (Italian, blue TAB board, encrypted), bootleg, 199?.
* Jolly Card (Italian, encrypted bootleg, set 1), bootleg, 1990.
* Jolly Card (Italian, encrypted bootleg, set 2), bootleg, 1993.
* Jolly Card (Italian, encrypted bootleg, set 3), bootleg (Cleco), 1993.
* Zabavni Karti (Bulgarian, cyrillic, encrypted), bootleg (Cleco), 1993.
* Pool 10 (Italian, Dino 4 hardware, encrypted), C.M.C., 1997.
* Royal Card (Italian, Dino 4 hardware, encrypted), unknown, 1998.
* China Town (Ver 1B, Dino4 HW), unknown, 1998.
* Mongolfier New (Italian), unknown, 199?.
* Soccer New (Italian), unknown, 199?.
* Fun World Quiz (German), Fun World, 198?.
* Fun World Quiz (German, 12-11-1990), Fun World, 1990.
* Fun World Quiz (German, 27-04-1990), Fun World, 1990.
* Novo Play Multi Card / Club Card, Admiral/Novomatic, 1986.
* Novo Play Club Card (V6.2H), Novo Play International, 1992.
* Novo Play Club Card (V3.3H), Novo Play International, 1991.
* Joker Card (Inter Games), Inter Games, 1991.
* Unknown Fun World A7-11 game 1, Fun World, 1985.
* Unknown Fun World A7-11 game 2, Fun World, 1985.
* Unknown Fun World A0-1 game, Fun World, 1991.
* Joker Card / Multi Card (Epoxy brick CPU), Fun World, 1991.
* Gratis Poker (V.204, set 1), Mega Soft, 1995.
* Gratis Poker (V.204, set 2), Mega Soft, 1995.
* Gkoulit (encrypted GFX), JK Amusement, 1995.
* Reflex Cards (English, serial protected), TAB Austria, 1999.
* Club Card (ver. 1.1 English), Impera / Mega Tech, 199?.
* Royal Card (stealth with NES multigame, set 1), bootleg, 1991.
* Royal Card (stealth with NES multigame, set 2), bootleg, 1991.
* Royal Card (stealth with MSX multigame), bootleg, 1991.
Supported games: 123
**********************************************************************************************
The hardware is generally composed by:
CPU: 1x 65SC02 or 65C02 at 2MHz.
Sound: 1x AY-3-8910 or YM2149F (AY8910 compatible) at 2MHz.
I/O: 2x 6821 (PIA)
Video: 1x 6845 (CRTC)
RAM: 1x 6116
NVRAM: 1x 6264
ROMs: 3x 27256 (or 27512 in some cases)
PROMs: 1x 82S147 (or similar. 512 bytes)
PLDs: 1 to 4 PALs, GALs or PEELs
Clock: 1x Crystal: 16MHz.
All current games are running from a slightly modified to heavily hacked hardware.
Color palettes are normally stored in format GGBBBRRR inside a bipolar color PROM.
- bits -
7654 3210
---- -xxx Red component.
--xx x--- Blue component.
xx-- ---- Green component.
The hardware was designed to manage 4096 tiles with a size of 8x4 pixels each.
Also support 4bpp graphics and the palette limitation is 8 bits for color codes (256 x 16 colors).
It means the hardware was designed for more elaborated graphics than Jolly Card games...
Color PROMs from current games are 512 bytes lenght, but they only can use the first or the last 256 bytes.
Normal hardware capabilities:
- bits -
7654 3210
xxxx xx-- tiles color (game tiles) ;codes 0x00-0xdc
xxx- x-xx tiles color (title). :codes 0xe9-0xeb
xxxx -xxx tiles color (background). ;codes 0xf1-0xf7
About protection, there are several degrees of protection found in the sets:
- There are writes to unknown offsets (out of the normal memory range), and some
checks later to see if the data is still there.
- There are checks for code in unused RAM and therefore jumps to offsets where there
are not pieces of code in RAM or just RAM is inexistent.
I think this is to avoid a "ROM swap" that allow the software to run in other game boards.
- There are "masked" unused inputs.
The software is polling the unused input status and expect a special value to boot the game.
- There are parts of code that are very complex and twisted with fake jumps to inexistent code,
or pretending to initialize fake devices.
- Encryption.
A) Encrypted CPU. At least five Fun World boards have custom encrypted CPUs:
- Joker Card from Vesely Svet, Mega Card, Power Card and Multi Win,
use custom unknown CPUs and also encrypted/scrambled prg roms.
- Royal Card (slovak, encrypted) from Evona Electronic seems to use a block
with CPU + extras (ICs, TTL, etc) to manage the encryption.
B) General encryption. Managed through hardware:
- All games using the blue TAB PCB with 2x HY18CV85 (electrically-erasable PLDs), use
complex operations for each byte nibble. See DRIVER_INIT for the final algorithm.
- Saloon (french) use bitswaps to address & data in program, graphics and color PROM.
- Dino4 hardware games have address/data bitswap in program, and data bitswap (sometimes
with extra boolean XOR operations) in graphics.
- Microcontroller. Some games (like Soccer New and Mongolfier New are using an extra MCU mainly
for protection.
- Mirrored video and color RAM. A derivative of CMC hardware uses this trick to avoid ROM swaps.
If you run Luna Park in a regular CMC board, you'll get an unplayable mess of graphics.
GENERAL NOTES:
- It takes 46 seconds for the bigdeal/jolycdat games to boot up
after the initial screen is displayed!!!
- The default DIP switch settings must be used when first booting up
the games to allow them to complete the NVRAM initialization.
- Almost all games: Start game, press and hold Service1 & Service2, press
reset (F3), release Service1/2 and press reset (F3) again.
Now the NVRAM has been initialized.
- Royalcdb needs a hard reset after NVRAM initialization.
- For games that allow remote credits, after NVRAM init change the payout
DIP switch from "Hopper" to "Manual Payout".
NOTES BY GAME/SET:
* Pool 10
* Cuore 1
* Elephant Family
* Tortuga Family
* Pot Game
* Bottle 10
* Luna Park
In Italy many people became addicted to videopokers. They put so much money on them,
and they had to sell the house. Also some engineers modified videopokers to do less
wins and so on... Because of this the government did some laws in order to regulate
videopokers wins. Starting from around 1996/1997 there were subsequent laws because
engineers always found a way to elude them.
Today all the videopokers need to be connected via AAMS net (a government society de-
dicated to games) which check if the videopoker is regular. Nowadays it's difficult
to trick and the videopoker has to give 75% of wins. This has made videopoker market
to collapse and infact there aren't many videopokers left.
Also because the laws changed very often and old videopokers became illegal was a
very bad thing for bar owners because they couldn't earn enough money.
Pool 10 (now found!), apparently was the "father" of other italian gambling games.
As soon as it became illegal, was converted to Cuore 1, Elephant Family, Tortuga Family
and maybe other games. So you can see that engineers always found a simple way to elude
the law.
There is another set of Cuore 1. I didn't include it because the only difference with
the supported set is the program rom that is double sized, having identical halves.
Luna Park, is running in a modified hardware with video RAM mirrored from 4000-4FFF to
6000-6FFF and color RAM mirrored from 5000-5FFF to 7000-7FFF. The program writes criti-
cal graphics (cans, strings and partial screen cleans) to the mirrored range, so if you
run this program in a regular CMC hardware, you'll get an unplayable mess of graphics.
Also PRG rom higher address line is connected to DIP switch #1 so it should have 2 games
in the same PCB (2 revisions?).
There is at least one missing game in the family... 'Hyppo Family', also from C.M.C.
This game should be located and dumped.
--- Super Game ---
If you have some points accumulated and need to grab the tokens/tickets, you must to play
a bonus game called SUPER GAME to get the points out. To enter the bonus game, you must
press STOP5 in the attract mode. The payout system is through this game.
5 themed items will be shown (cuores, balls, elephants, etc... depending of the game).
The joker will start to move from item to item quickly, but decreasing the speed gradually.
To beat the game, you need to push the start button in the exact moment when the joker is
located exactly in the center of the screen (item 3).
Depending of the DIP switches settings, you can grab the prize manually pressing the SCARICA
(payout) button, and then TICKET or HOPPER buttons. Press TICKET button to print a 100 points
ticket. Press HOPPER button to get tokens x10 points.
You have 1 attempt for each 100 earned points. If you lose the game, you lose the points.
* Bonus Card (German)
* Big Deal (Hungarian)
These ones seems to have normal RAM instead of NVRAM.
Going through the code, there's not any NVRAM initialization routine through service 1 & 2.
* Jolly Card Professional 2.0 (MZS Tech & Spale Soft)
Each 1st boot, this game show a generated code. You must enter this code in a DOS program to
get the input codes necessary to allow boot the game.
This set is one of the most wanted for customers because is a real SCAM.
The program has 2 hidden menues that allow change parameters without knowledge of the players.
See more at ROM_LOAD section...
* Jolly Card (Evona Electronic)
This set has some hidden features.
In the service 2 screen, press service 1 to enter to a message edit mode.
* Jolly Card (croatian sets) and Jolly Card Professional 2.0
These games don't operate with regular coins/tokens. Only remote credits are allowed.
* Royal Card Professional 2.0 (Digital Dreams)
Same generated code as Jolly Card Professional.
* Magic Card II (Impera)
Impera made 2 graphics sets for this game. One of them is encrypted, and meant for the TAB blue board.
This board has two HY18CV85 (electrically-erasable PLD) that handle the encryption.
In another hand, the sound has some weird things, but is confirmed that happen in the real thing.
The game resolution seems to change 'on the fly' when entering the input test mode.
There aren't any writes to the m6845 registers to manage these changes.
Regarding the CPU, it's a Mexican Rockwell R65C02 with some mods respect the regular/stock 65C02.
Some CPU instructions seems to be changed. The following piece of code at $C1A8 is very clear:
C1A8: A0 00 ldy #$00 ; clear Y register to use as counter.
C1AA: B9 9D C1 lda $C19D,y ; load PIA port address
C1AD: 85 06 sta $06 ; into $06-$07 ZP vector.
C1AF: B9 92 C1 lda $C192,y ;
C1B2: 85 07 sta $07 ;
C1B4: C0 0B cpy #$0B
C1B6: B0 0C bcs $C1C4
... load values to store into Accumulator...
...
C1C6: 91 06 sta ($06),y ; store value in PIA port, indexed (Y).
C1C8: C8 iny ; increment Y
C1C9: C0 0C cpy #$0C ; finish?
C1CB: D0 DD bne $C1AA ; if not, branch to load a new PIA address.
In this example, as soon as Y register increments, the indexed writes go out of range.
To get this piece of code working and initialize the PIAs properly, the instruction 0x91 should be
"sta ($ZP)" instead of Y indexed. (like instruction 0x92 in stock 65c02's).
* Jolly Joker (Impera)
To boot this game for 1st time, DSW should be in the following position:
1=ON 2=OFF 3=ON 4=OFF 5=OFF 6=ON 7=ON 8=OFF
Press RESET (key F3) and then SERVICE1 & SERVICE2 (keys 9 & 0), then RESET (key F3).
When numbers start to fill the screen, press RESET (key F3) again to start the game.
* Joker Card 300 (Ver.A267BC, encrypted).
* Multi Win (Fun World)
* Power Card (Fun World)
* Mega Card (Fun World)
These sets seems to run in the same modified hardware. They are highly encrypted.
Joker Card has a title nag at boot. You can wait to finish nearly one minute,
or simply press SERVICE 2 (key 0), then START (key 1) to enter the game.
Joker Card has a weird way of play. The more you bet, the more cards burns to
get better chances. You're not betting really. Just buying removed cards.
* Mongolfier New
* Soccer New
These games are based in Royal Card. They are running in a heavely modified Royal Card
hardware with a microcontroller as an extra (protection?) component and a TDA2003 as
audio amplifier.
The extra microcontroller is a 8 bit (PLCC-44) TSC87C52-16CB from Intel (now dumped!)
Each set has double sized ROMs. One half contains the proper set and the other half store
a complete Royal Card set, so... Is possible the existence of a shortcut,'easter egg',
simple hack or DIP switches combination to enable the Royal Card game.
These games should be moved to a new driver in a near future, as soon as we know a bit more
about them and start to implement the missing pieces for an accurate emulation.
* Saloon
This game is totally encrypted. No PIAs to drive I/O. The PCB has printed "LEOPARDO 5", so we
can expect a game called the same way to appear.
This game should be moved to a new driver in a near future, as soon as we know a bit more about it.
* Fun World Quiz
Beschreibung / Description
--------------------------
Fur OES 5,-- Einwurf werden 3 Kredite gegeben. Fur einen Kredit bekommt der Spieler
500 Spielpunkte. Bei jeder Frage kann der Spieler 100, 500 oder alle Punkte einsetzen.
Wird die Frage richtig beantwortet, wird der Einsatz aufaddiert. Erreicht der Spieler
nach 5 Fragen mehr als 2500 Punkte, bekommt er Bonusfragen. Das Spiel endet bei einer
falschen Beantwortung der Frage.
Insertion of ATS 5,- (Austrian Schilling coin) yields 5 credits. For 1 credit a player
receives 500 points. At each question a player can bet 100, 500 or all points. If a
question is answered correctly, the bet is added to the points. If a player reaches
more than 2500 points after 5 questions, he gets bonus questions. The game is over
after an incorrect answer.
Besides notes....
This machine is meant to work as "amusement", with high scores like another regular arcade.
You can set it as "bet mode", allowing to choose the amount of points to play, but can't be
turned to gambling mode (no payout, keyout, etc) for pubs, etc...
In bookkeeping mode (DIP switch #1):
Keep joystick left to clear bookkeeping.
Keep joystick up to clear high scores.
Keep joystick down to clear credits.
Keep joystick right to exit bookkeeping.
If the game has credits loaded, the bookkeeping mode will start
as soon as the current game ends.
* Novo Play Multi Card / Club Card
This game needs a default NVRAM to work. There is a special ROM that need to be
placed into the program socket, then turn ON the board till the OK message appear.
After this operation, just switch the special ROM with the regular program.
The board now is ready to operate.
To program the game, enter the service mode (Key 9), and then keep pressed both
HOLD2 & HOLD4 at least for 5 seconds....
You can see:
C1 C2 REMOTE IN-MAX/IN-MIN CONT
(Coin A) (Coin B) (Remote credits) (Bet Max & Minimum) (Difficult)
C2: Coin B, from 1-20... Selectable through HOLD1.
REMOTE: Remote Credits, from 10-100... Selectable through HOLD3.
IN-MAX: Maximum Bet allowed. From 1-40. selectable through HOLD4.
IN_MIN: Minimum Bet allowed. From 1-5. selectable through HOLD4, keeping COLLECT pressed.
CONT: Earnings control... From 1-4, selectable through HOLD5. 4 is the highest payment.
Press DEAL/DRAW to exit the mode.
* Unknown Royal Card on Dino4 hardware....
This one is really strange. The game is running in a Dino4 hardware, plus a daughterboard
with a mexican Rockwell R65C02 + an unknown PLCC. The program/gfx are totally decrypted.
The game vectors are $C122 (RESET) and $C20F (IRQ)
The code starts...
C122: A2 FF LDX #$FF ; load 0xFF to reg X
C124: 9A TXS ; transfer to the stack
C125: 78 SEI ; set interrupts
C126: D8 CLD ; clear decimal
C127: 18 CLC ; clear carry
C128: A9 4C LDA #$4C ;\
C12A: 8D 00 00 STA $0000 ; \
C12D: A9 10 LDA #$10 ; \ set 4C 10 C2 (JMP $C210) into $0000
C12F: 8D 01 00 STA $0001 ; /
C132: A9 C2 LDA #$C2 ; /
C134: 8D 02 00 STA $0002 ;/
C137: 4C DC 48 JMP $48DC ; jump to $48DC...
And the IRQ vector pointed code... does nothing!
C20F: 40 RTI ; return from interrupt
And the code pointed from $0000...
C210: 48 PHA ; transfer accumulator to stack
C211: AD 01 0A LDA $0A01 ; read the PIA #2 input
C214: 29 F7 AND #$F7 ; \ compare with 0xF7
C216: CD 01 0A CMP $0A01 ; /
C219: D0 02 BNE $C21D ; if not... jump to $C21D
C21B: 09 08 ORA #$08 ; \ clean the value
C21D: 8D 01 0A STA $0A01 ; /
C220: 68 PLA ; take out from the stack the previous accumulator value
C221: 40 RTI ; return from interrupt
The board was later connected to a fluke, and the pieces of code dumped from the real hardware,
match 100% the ones I decrypted here. Even with the game working properly in the real hardware.
The only visible changes are in the NVRAM, where the $0000 offset hasn't the JMP $C210 instruction
injected at the start...
* Joker Card / Multi Card (Epoxy brick CPU)
These series are running in a derivative hardware with epoxy CPU brick.
CPU is RP65C02A, with 2x Toshiba TC5565APL-10 RAMs. 1x Intel D27128A ROM.
and 1x PAL16L8B.
The main program is inside the battery backed RAM, and need to be dumped.
See more notes below in the ROM loading.
* Royal Card (Italian, Dino 4 hardware, encrypted)
This game is highly encrypted and is running in Dino 4 hardware.
To initialize the NVRAM, you should press both service buttons together (keys 0-9) and then reset (key F3).
Due to the way the routine is programmed, the procedure is time sensitive and often doesn't work.
This game has a programming menu through the service mode (key 0), then pressing STOP 2 & STOP 4 together
and waiting for some seconds.
You can see two options...
STOP 1 ---- OPZIONI 1
STOP 3 ---- OPZIONI 2
OPZIONI 1:
You can change game parameters for Gioco AB, Play Max, Play Min, Difficolt, Bonus, and Rilancio.
OPZIONI 2:
You can change game parameters for Tabella Vincite, Velocita Simboli, Control Double, Valore Ticket,
Limit Credit, and Limit Scarico.
In both cases, you can exit pressing the START button (key 1).
* Jolly Card (Italian, bootleg, set 2)
This game PCB has a TI EP910DC-30 CPLD, like others Italian bootlegs
that have an Altera EP910PC CPLD on board.
To init NVRAM, DIP switches must be in the following positions:
OFF ON ON ON ON ON ON ON
Then press SERVICE 1 + SERVICE 2 and reset, then release both buttons.
Once NVRAM is initialized, the hardware still complains about it due
to a hardware check (see more at the rom load), but is now working.
The game seems to work for a currency that needs decimal values.
Maybe Italian Lires...
* Jolly Card (German, Fun World, bootleg)
This game is a bootleg made from a Fun World original program.
The game has hidden features, as a program mode.
In the Service menu (key 0), press HOLD 1 & HOLD 2 together for
some seconds and the programming menu will appear.
* Royal Card (Evona, Polish, encrypted)
This is another highly encrypted game.
To initialize the NVRAM all DIP switches must be in ON. Keep pressed both service buttons
(keys 9 & 0) and then RESET (key F3), then release first the service 1 (key 9) and then
service 2 (key 0).
The game does some odd things, due to a possible bug in the
decryption scheme. (see the TO DO list).
* Zabavni Karti (ЗАБАВНИ КАРТИ)
(cyrillic, Bulgarian, encrypted)
This is a Bulgarian Jolly Card pseudo-clone, with cyrillic charset.
ЗАБАВНИ КАРТИ means "Fun cards" / "Cards for fun".
The game has encrypted GFX. Same style as blue TAB board.
This is a timed game. You coin for an amount of playing time.
Once the time counter ends, all earned credits/bonus dissapear.
It looks like an amusement version.
---------------------------------------------------------------------
To initialize the NVRAM you must...
1) Press SETUP (НАСТРОЙКА) (key 0)
2) Keep pressed CANCEL (ИЗЧИСТВАНЕ) button (key N)
3) Press the following STOP (СТОП) buttons (keys Z-X-C-V-B) sequence:
1 - 5 - 4 - 3 - 4 - 2
(you will see the initialization message)
4) Release the CANCEL (ИЗЧИСТВАНЕ) button (key N)
---------------------------------------------------------------------
To configure the game...
1) Press SETUP (НАСТРОЙКА) (key 0)
You'll see the following counters and menu:
КАРЕ С ЖОКЕР 0 (five of a kind)
КЕНТ ФЛЕШ РОЯЛ 0 (royal flush)
КЕНТ ФЛЕШ 0 (straight flush)
КАРЕ 0 (poker)
ФУЛ 0 (full house)
ФЛЕШ 0 (flush)
КЕНТА 0 (straight)
ТРОЙКА 0 (three of a kind)
2 ДВОЙКИ 0 (two pairs)
ГОЛЯМА ДВОЙКИ 0 (high pair)
ВРЕМЕ: Натиснете бутон Стоп3
TIME: Press the Stop3 button
Изиграно време, мин. : 00
Played time, min. : 00
Платено време, мин. : 00
Paid time, min. : 00
НАСТРОЙКА: Натиснете бутони Стоп2 и Стоп4
SETUP: Press the Stop2 and Stop4 buttons
Бутон Стоп1 -- Време за една игра, мин. (1-99, 5 by default)
Stop1 Button -- Time for one game, min. (1-99, 5 by default)
Бутон Стоп2 -- Залог (1-99, 10 by default)
Stop2 button - Bet (1-99, 10 by default)
Бутон Стоп3 -- Ниво на трудност (0-3, 2 by default)
Stop3 button -- Level of difficulty (0-3, 2 by default)
ИЗХОД: Натиснете бутон Старт
EXIT: Press the Start button
НУЛИРАНЕ: Стоп1 нулира часовника
RESET: Stop1 resets the clock
ИЗЧИСТВАНЕ: Натиснете 2 с. бутон Изчистване
CLEAR: Press the Cancel button for 2 seconds
ИЗХОД: Натиснете бутон Старт
EXIT: Press the Start button
---------------------------------------------------------------------
You can enter the test mode activating the 'TEST MODE' DIP switch.
(only will work if you have some adquired time)
For AUTOHOLD (АВТОСТОП) function, set the 'AUTO HOLD' DIP switch ON,
then toggle ON/OFF the function pressing CANCEL (ИЗЧИСТВАНЕ) button (key N).
**********************************************************************************************
Memory Map (generic)
--------------------
$0000 - $07FF NVRAM // All registers and settings.
$0800 - $0803 PIA1 // Input Ports 0 & 1.
$0A00 - $0A03 PIA2 // Input Ports 2 & 3.
$0C00 - $0C00 AY-8910 (R/C) // Read/Control.
$0C01 - $0C01 AY-8910 (W) // Write. Lamps through output ports.
$0E00 - $0E00 CRTC6845 (A) // MC6845 addressing.
$0E01 - $0E01 CRTC6845 (R/W) // MC6845 Read/Write.
$2000 - $2FFF VideoRAM (bonuscrd/bigdeal)
$3000 - $3FFF ColorRAM (bonuscrd/bigdeal)
$4000 - $4FFF VideoRAM (magicrd2/royalcrd)
$5000 - $5FFF ColorRAM (magicrd2/royalcrd)
$6000 - $6FFF VideoRAM (CMC italian games)
$7000 - $7FFF ColorRAM (CMC italian games)
$8000 - $FFFF ROM (almost all games)
*** MC6845 Initialization ***
----------------------------------------------------------------------------------------------------------------------
register: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17
----------------------------------------------------------------------------------------------------------------------
jollycrd: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
jolycdae: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
jolycdcr: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
jolycdit: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
jolycdab: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
bigdeal: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
cuoreuno: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
elephfam: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
pool10: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
tortufam: 0x7C 0x60 0x65 0x08 0x1E 0x08 0x1D 0x1D 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
royalcrd: 0x7C 0x60 0x65 0xA8 0x1E 0x08 0x1D 0x1C 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
magicrd2: 0x7B 0x70 0x66 0xA8 0x24 0x08 0x22 0x22 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
monglfir: 0x7C 0x60 0x65 0xA8 0x1E 0x08 0x1D 0x1C 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
soccernw: 0x7C 0x60 0x65 0xA8 0x1E 0x08 0x1D 0x1C 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
rcdino4: 0x7C 0x60 0x65 0x08 0x21 0x08 0x1F 0x1F 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
chinatow: 0x7C 0x60 0x65 0x08 0x21 0x08 0x1F 0x1F 0x00 0x07 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00.
**********************************************************************************************
*** TO DO ***
- Figure out the remaining PIA connections for almost all games.
- Reverse-engineering the boot code of Jolly Card Professional 2.0,
and Royal Card Professional 2.0 to get the proper codes to boot.
- Analyze the unknown writes to $2000/$4000 in some games.
- Check for the reads to the ay8910 output ports in some games.
- Implement the MCU in monglfir and soccernw.
*********************************************************************************************/
#include "emu.h"
#include "funworld.h"
#include "cpu/m6502/m65sc02.h"
#include "cpu/m6502/r65c02.h"
#include "machine/6821pia.h"
#include "machine/nvram.h"
#include "screen.h"
#include "speaker.h"
#include "bonuscrd.lh"
#include "jollycrd.lh"
#include "novoplay.lh"
#include "royalcrd.lh"
#define MASTER_CLOCK XTAL(16'000'000)
#define CPU_CLOCK (MASTER_CLOCK/8)
#define SND_CLOCK (MASTER_CLOCK/8)
#define CRTC_CLOCK (MASTER_CLOCK/8)
/**********************
* Read/Write Handlers *
**********************/
void funworld_state::funworld_lamp_a_w(uint8_t data)
{
/* - bits -
7654 3210
---- ---x Credit In counter.
---- --x- HOLD1 & HOLD3 lamps (inverted).
---- -x-- Credit Out counter.
---- x--- HOLD2 lamp (inverted).
---x ---- Unknown (inverted).
--x- ---- CANCEL / COLLECT (inverted).
-x-- ---- Hopper Motor (inverted).
x--- ---- HOLD4 lamp.
*/
m_lamps[0] = BIT(~data, 1); // Hold1 (inverted)
m_lamps[2] = BIT(~data, 1); // Hold3 (inverted, see pinouts)
m_lamps[1] = BIT(~data, 3); // Hold2 / Low (inverted)
m_lamps[3] = BIT(data, 7); // Hold4 / High
m_lamps[5] = BIT(~data, 5); // Cancel / Collect (inverted)
machine().bookkeeping().coin_counter_w(0, data & 0x01); // Credit In counter
machine().bookkeeping().coin_counter_w(7, data & 0x04); // Credit Out counter, mapped as coin 8
m_lamps[7] = BIT(~data, 6); // Hopper Motor (inverted)
// popmessage("Lamps A: %02X", (data ^ 0xff));
}
void funworld_state::funworld_lamp_b_w(uint8_t data)
{
/* - bits -
7654 3210
---- ---x HOLD5 lamp.
---- --x- DEAL/DRAW lamp.
---- -x-- Unknown (inverted).
xxxx x--- Unknown.
*/
m_lamps[4] = BIT(data, 0); // Hold5 / Bet
m_lamps[6] = BIT(data, 1); // Start / Deal / Draw
// popmessage("Lamps B: %02X", data);
}
void funworld_state::pia1_ca2_w(int state)
{
// TAB and Impera games are writing 0x01 constantly, and 0x00 with each screen change.
// This line is tied to some sort of reset circuitery.
// popmessage("PIA1 CA2: %02X", state);
}
/*************************
* Memory map information *
*************************/
void funworld_state::funworld_map(address_map &map)
{
map(0x0000, 0x07ff).ram().share("nvram");
map(0x0800, 0x0803).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0a00, 0x0a03).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0c00, 0x0c00).r("ay8910", FUNC(ay8910_device::data_r));
map(0x0c00, 0x0c01).w("ay8910", FUNC(ay8910_device::address_data_w));
map(0x0e00, 0x0e00).w("crtc", FUNC(mc6845_device::address_w));
map(0x0e01, 0x0e01).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x2000, 0x2fff).ram().w(FUNC(funworld_state::funworld_videoram_w)).share("videoram");
map(0x3000, 0x3fff).ram().w(FUNC(funworld_state::funworld_colorram_w)).share("colorram");
map(0x4000, 0x7fff).rom();
map(0x8000, 0xbfff).rom();
map(0xc000, 0xffff).rom();
}
static uint8_t funquiz_question_bank = 0x80;
uint8_t funworld_state::questions_r(offs_t offset)
{
uint8_t* quiz = memregion("questions")->base();
int extraoffset = ((funquiz_question_bank & 0x1f) * 0x8000);
// if 0x80 is set, read the 2nd half of the question rom (contains header info)
if (funquiz_question_bank & 0x80) extraoffset += 0x4000;
return quiz[offset + extraoffset];
}
void funworld_state::question_bank_w(uint8_t data)
{
// printf("question bank write %02x\n", data);
funquiz_question_bank = data;
}
void funworld_state::funquiz_map(address_map &map)
{
map(0x0000, 0x07ff).ram().share("nvram");
map(0x0800, 0x0803).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0a00, 0x0a03).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0c00, 0x0c00).r("ay8910", FUNC(ay8910_device::data_r));
map(0x0c00, 0x0c01).w("ay8910", FUNC(ay8910_device::address_data_w));
map(0x0e00, 0x0e00).w("crtc", FUNC(mc6845_device::address_w));
map(0x0e01, 0x0e01).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x1800, 0x1800).w(FUNC(funworld_state::question_bank_w));
map(0x2000, 0x2fff).ram().w(FUNC(funworld_state::funworld_videoram_w)).share("videoram");
map(0x3000, 0x3fff).ram().w(FUNC(funworld_state::funworld_colorram_w)).share("colorram");
map(0x4000, 0x7fff).r(FUNC(funworld_state::questions_r));
map(0xc000, 0xffff).rom();
}
void funworld_state::magicrd2_map(address_map &map)
{
map(0x0000, 0x07ff).ram().share("nvram");
map(0x0800, 0x0803).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0a00, 0x0a03).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0c00, 0x0c00).r("ay8910", FUNC(ay8910_device::data_r));
map(0x0c00, 0x0c01).w("ay8910", FUNC(ay8910_device::address_data_w));
map(0x0e00, 0x0e00).w("crtc", FUNC(mc6845_device::address_w));
map(0x0e01, 0x0e01).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x2c00, 0x2cff).ram(); // range for protection
map(0x3600, 0x36ff).ram(); // some games use $3603-05 range for protection
map(0x3c00, 0x3cff).ram(); // range for protection
map(0x4000, 0x4fff).ram().w(FUNC(funworld_state::funworld_videoram_w)).share("videoram");
map(0x5000, 0x5fff).ram().w(FUNC(funworld_state::funworld_colorram_w)).share("colorram");
map(0x6000, 0xffff).rom();
}
void funworld_state::clubcard_map(address_map &map)
{
map(0x0000, 0x07ff).ram().share("nvram");
map(0x0800, 0x0803).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0a00, 0x0a03).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0c00, 0x0c00).r("ay8910", FUNC(ay8910_device::data_r));
map(0x0c00, 0x0c01).w("ay8910", FUNC(ay8910_device::address_data_w));
map(0x0e00, 0x0e00).w("crtc", FUNC(mc6845_device::address_w));
map(0x0e01, 0x0e01).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x4000, 0x4fff).ram().w(FUNC(funworld_state::funworld_videoram_w)).share("videoram");
map(0x5000, 0x5fff).ram().w(FUNC(funworld_state::funworld_colorram_w)).share("colorram");
map(0x8000, 0xbfff).rom();
map(0xc000, 0xffff).rom();
}
void funworld_state::cuoreuno_map(address_map &map)
{
map(0x0000, 0x07ff).ram().share("nvram");
map(0x0800, 0x0803).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0a00, 0x0a03).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0c00, 0x0c00).r("ay8910", FUNC(ay8910_device::data_r));
map(0x0c00, 0x0c01).w("ay8910", FUNC(ay8910_device::address_data_w));
map(0x0e00, 0x0e00).w("crtc", FUNC(mc6845_device::address_w));
map(0x0e01, 0x0e01).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x2000, 0x2000).nopr(); // some unknown reads
map(0x3e00, 0x3fff).ram(); // some games use $3e03-05 range for protection
map(0x4000, 0x5fff).rom(); // used by rcdino4 (dino4 hw )
map(0x6000, 0x6fff).ram().w(FUNC(funworld_state::funworld_videoram_w)).share("videoram");
map(0x7000, 0x7fff).ram().w(FUNC(funworld_state::funworld_colorram_w)).share("colorram");
map(0x8000, 0xffff).rom();
}
uint8_t chinatow_state::chinatow_r_32f0(offs_t offset)
{
logerror("read from 0x32f0 at offset %02X\n", offset);
switch (offset)
{
case 0: return 0xfe;
}
return 0xff;
}
void chinatow_state::chinatow_map(address_map &map)
{
map(0x0000, 0x07ff).ram().share("nvram");
map(0x0800, 0x0803).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0a00, 0x0a03).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0c00, 0x0c00).r("ay8910", FUNC(ay8910_device::data_r));
map(0x0c00, 0x0c01).w("ay8910", FUNC(ay8910_device::address_data_w));
map(0x0e00, 0x0e00).w("crtc", FUNC(mc6845_device::address_w));
map(0x0e01, 0x0e01).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x2000, 0x2000).nopr(); // some unknown reads
map(0x32f0, 0x32ff).r(FUNC(chinatow_state::chinatow_r_32f0));
map(0x4000, 0x5fff).rom(); // used by rcdino4 (dino4 hw)
map(0x6000, 0x6fff).ram().w(FUNC(chinatow_state::funworld_videoram_w)).share("videoram");
map(0x7000, 0x7fff).ram().w(FUNC(chinatow_state::funworld_colorram_w)).share("colorram");
map(0x8000, 0xffff).rom();
}
void lunapark_state::lunapark_map(address_map &map)
{ // mirrored video RAM 4000/5000 to 6000/7000
map(0x0000, 0x07ff).ram().share("nvram");
map(0x0800, 0x0803).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0a00, 0x0a03).rw("pia1", FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x0c00, 0x0c00).r("ay8910", FUNC(ay8910_device::data_r));
map(0x0c00, 0x0c01).w("ay8910", FUNC(ay8910_device::address_data_w));
map(0x0e00, 0x0e00).w("crtc", FUNC(mc6845_device::address_w));
map(0x0e01, 0x0e01).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x4000, 0x4fff).ram().w(FUNC(lunapark_state::funworld_videoram_w)).share("videoram").mirror(0x2000);
map(0x5000, 0x5fff).ram().w(FUNC(lunapark_state::funworld_colorram_w)).share("colorram").mirror(0x2000);
map(0x8000, 0xffff).bankr("bank1");
}
void funworld_state::saloon_map(address_map &map)
{
map(0x0000, 0x07ff).ram().share("nvram");
map(0x0800, 0x0800).portr("IN0");
map(0x0801, 0x0801).portr("IN1");
map(0x0802, 0x0802).portr("IN2"); // maybe
map(0x0808, 0x0808).portr("IN3"); // maybe
map(0x0810, 0x0810).nopw();
map(0x0a00, 0x0a00).portr("IN4");
map(0x0a01, 0x0a01).portr("IN5");
map(0x081b, 0x081b).portw("I2C_CK");
map(0x081c, 0x081c).w("crtc", FUNC(mc6845_device::address_w));
map(0x081d, 0x081d).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x1000, 0x1000).portr("I2C_DI").portw("I2C_DO");
map(0x1800, 0x1800).r("ay8910", FUNC(ay8910_device::data_r));
map(0x1800, 0x1801).w("ay8910", FUNC(ay8910_device::address_data_w));
map(0x2000, 0x2003).nopr(); // check for extra ROM in $2000. if exist just jump to $2100