1 // FBAlpha BSMT2000 emulation, based on code written by Aaron Giles
2 #include "burnint.h"
3 #include "tms32010.h"
4 #include "dac.h"
5
6 static UINT32 bsmt2k_clock = 0;
7
8 static INT32 write_pending = 0;
9 static UINT16 write_data = 0;
10 static UINT16 register_select = 0;
11 static UINT16 rom_address = 0;
12 static UINT8 rom_bank = 0;
13 static UINT8 *datarom = NULL;
14 static INT32 datarom_len = 0;
15 static void (*ready_callback)() = NULL;
16 static UINT16 data_left = 0;
17 static UINT16 data_right = 0;
18
bsmt2k_write_reg(UINT16 data)19 void bsmt2k_write_reg(UINT16 data)
20 {
21 register_select = data;
22 }
23
bsmt2k_write_data(UINT16 data)24 void bsmt2k_write_data(UINT16 data)
25 {
26 write_data = data;
27 write_pending = 1;
28 }
29
bsmt2k_read_status()30 INT32 bsmt2k_read_status()
31 {
32 return write_pending ? 0 : 1;
33 }
34
BSMTSyncDAC()35 static INT32 BSMTSyncDAC()
36 {
37 return (INT32)(float)(nBurnSoundLen * (tms32010TotalCycles() / (bsmt2k_clock / (nBurnFPS / 100.0000))));
38 }
39
bsmt2k_update()40 void bsmt2k_update()
41 {
42 DACUpdate(pBurnSoundOut, nBurnSoundLen);
43 }
44
update_stream()45 static void update_stream()
46 {
47 DACWrite16Stereo(0, data_left, data_right);
48 }
49
bsmt2k_write_port(INT32 port,UINT16 data)50 static void bsmt2k_write_port(INT32 port, UINT16 data)
51 {
52 switch (port)
53 {
54 case 0:
55 rom_address = data;
56 return;
57
58 case 1:
59 rom_bank = data;
60 return;
61
62 case 3:
63 data_left = data;
64 update_stream();
65 return;
66
67 case 7:
68 data_right = data;
69 update_stream();
70 return;
71 }
72 }
73
bsmt2k_read_port(INT32 port)74 static UINT16 bsmt2k_read_port(INT32 port)
75 {
76 switch (port)
77 {
78 case 0:
79 return register_select;
80
81 case 1:
82 write_pending = 0;
83 if (ready_callback)
84 ready_callback();
85 return write_data;
86
87 case 2: {
88 INT32 addr = (rom_bank << 16) + rom_address;
89 if (addr >= datarom_len) return 0;
90 return (INT16)(datarom[addr] << 8);
91 }
92
93 case TMS32010_BIO:
94 return (write_pending) ? 1 : 0;
95 }
96
97 return 0;
98 }
99
bsmt2kReset()100 void bsmt2kReset()
101 {
102 tms32010_reset();
103
104 DACReset();
105
106 write_pending = 0;
107 write_data = 0;
108 register_select = 0;
109 rom_address = 0;
110 rom_bank = 0;
111 data_left = 0;
112 data_right = 0;
113 }
114
bsmt2kResetCpu()115 void bsmt2kResetCpu()
116 {
117 tms32010_reset();
118 }
119
bsmt2kExit()120 void bsmt2kExit()
121 {
122 tms32010_exit();
123
124 DACExit();
125 }
126
bsmt2kScan(INT32 nAction,INT32 * pnMin)127 void bsmt2kScan(INT32 nAction, INT32 *pnMin)
128 {
129 tms32010_scan(nAction);
130
131 DACScan(nAction, pnMin);
132
133 SCAN_VAR(write_pending);
134 SCAN_VAR(write_data);
135 SCAN_VAR(register_select);
136 SCAN_VAR(rom_address);
137 SCAN_VAR(rom_bank);
138 SCAN_VAR(data_left);
139 SCAN_VAR(data_right);
140 }
141
bsmt2kInit(INT32 clock,UINT8 * tmsrom,UINT8 * tmsram,UINT8 * data,INT32 size,void (* cb)())142 void bsmt2kInit(INT32 clock, UINT8 *tmsrom, UINT8 *tmsram, UINT8 *data, INT32 size, void (*cb)())
143 {
144 bsmt2k_clock = clock;
145
146 tms32010_rom = (UINT16*)tmsrom; // 0x1000 words (0x2000 bytes)
147 tms32010_ram = (UINT16*)tmsram; // 0x100 bytes
148
149 datarom = data;
150 datarom_len = size;
151
152 ready_callback = cb;
153
154 tms32010_init();
155 tms32010_set_write_port_handler(bsmt2k_write_port);
156 tms32010_set_read_port_handler(bsmt2k_read_port);
157
158 DACInit(0, 0, 0, BSMTSyncDAC);
159 DACSetRoute(0, 0.60, BURN_SND_ROUTE_BOTH);
160 DACStereoMode(0);
161 }
162
bsmt2kNewFrame()163 void bsmt2kNewFrame()
164 {
165 tms32010NewFrame();
166 }
167