1 #include <../base.hpp>
2 
3 #define ST018_CPP
4 namespace SNES {
5 
6 ST018 st018;
7 
mmio_read(unsigned addr)8 uint8 ST018::mmio_read(unsigned addr) {
9   addr &= 0xffff;
10   if(addr == 0x3800) return regs.r3800;
11   if(addr == 0x3804) return regs.r3804;
12   return cpu.regs.mdr;
13 }
14 
mmio_write(unsigned addr,uint8 data)15 void ST018::mmio_write(unsigned addr, uint8 data) {
16   addr &= 0xffff;
17 
18   if(addr == 0x3802) {
19     switch(regs.mode) {
20       case Waiting: {
21         switch(data) {
22           case 0x01: regs.r3800 = regs.r3800_01; break;
23           case 0xaa: op_board_upload(); break;
24           case 0xb2: op_b2(); break;
25           case 0xb3: op_b3(); break;
26           case 0xb4: op_b4(); break;
27           case 0xb5: op_b5(); break;
28           case 0xf1: op_query_chip(); break;
29           case 0xf2: op_query_chip(); break;
30           default: fprintf(stdout, "* ST018 w3802::%.2x\n", data); break;
31         }
32       } return;
33 
34       case BoardUpload: {
35         op_board_upload(data);
36       } return;
37     }
38   }
39 
40   if(addr == 0x3804) {
41     regs.w3804 <<= 8;
42     regs.w3804  |= data;
43     regs.w3804  &= 0xffffff;
44     return;
45   }
46 }
47 
init()48 void ST018::init() {
49 }
50 
enable()51 void ST018::enable() {
52   for(unsigned i = 0x3800; i <= 0x38ff; i++) memory::mmio.map(i, *this);
53 }
54 
power()55 void ST018::power() {
56   reset();
57 }
58 
reset()59 void ST018::reset() {
60   regs.mode = Waiting;
61   regs.r3800 = 0x00;
62   regs.r3804 = 0x85;
63   regs.w3804 = 0;
64   for(unsigned i = 0; i < 97; i++) board[i] = 0;
65 }
66 
67 //=============
68 //ST018 opcodes
69 //=============
70 
op_board_upload()71 void ST018::op_board_upload() {
72   regs.mode = BoardUpload;
73   regs.counter = 0;
74   regs.r3800 = 0xe0;
75 }
76 
op_board_upload(uint8 data)77 void ST018::op_board_upload(uint8 data) {
78   board[regs.counter] = data;
79   regs.r3800 = 96 - regs.counter;
80   regs.counter++;
81   if(regs.counter >= 97) {
82     regs.mode = Waiting;
83     #if 0
84     for(unsigned y = 0; y < 9; y++) {
85       for(unsigned x = 0; x < 9; x++) {
86         fprintf(stdout, "%.2x ", board[y * 9 + x]);
87       }
88       fprintf(stdout, "\n");
89     }
90     for(unsigned n = 0; n < 16; n++) fprintf(stdout, "%.2x ", board[81 + n]);
91     fprintf(stdout, "\n\n");
92     #endif
93   }
94 }
95 
op_b2()96 void ST018::op_b2() {
97   fprintf(stdout, "* ST018 w3802::b2\n");
98   regs.r3800 = 0xe0;
99   regs.r3800_01 = 0;  //unknown
100 }
101 
op_b3()102 void ST018::op_b3() {
103   fprintf(stdout, "* ST018 w3802::b3\n");
104   regs.r3800 = 0xe0;
105   regs.r3800_01 = 1;  //0 = player lost?
106 }
107 
op_b4()108 void ST018::op_b4() {
109   fprintf(stdout, "* ST018 w3802::b4\n");
110   regs.r3800 = 0xe0;
111   regs.r3800_01 = 1;  //0 = player won?
112 }
113 
op_b5()114 void ST018::op_b5() {
115   fprintf(stdout, "* ST018 w3802::b5\n");
116   regs.r3800 = 0xe0;
117   regs.r3800_01 = 0;  //1 = move will result in checkmate?
118 }
119 
op_query_chip()120 void ST018::op_query_chip() {
121   regs.r3800 = 0x00;
122 }
123 
124 };
125