4 #define COINMECH_ID 0x20
7 volatile u8 packet_pos = 0;
8 volatile u16 value_1 = 0;
9 volatile u8 value_2 = 0;
10 volatile u8 dec_point = 0;
12 volatile u16 coin_value = 0;
14 volatile bool have_change = 0;
16 u8 parity_test(u8 c) {
18 for (parity = 0; c; c = c>>1) {
19 if (c&1) parity = !parity;
24 bool parity_good(u8 c) {
27 * parity_good truth table:
35 * equates to even parity?
38 u8 R8 = (_io_ports[M6811_SCCR1] & M6811_R8)?1:0;
39 u8 p = parity_test(c)?1:0;
43 void send_byte(u8 c) {
45 while (!(_io_ports[M6811_SCSR] & M6811_TDRE)); /* wait for TD register empty */
48 bset((void*)&_io_ports[M6811_SCCR1], M6811_T8);
50 bclr((void*)&_io_ports[M6811_SCCR1], M6811_T8);
53 #define IS_CTRL(x) (x & 0x10) /* true if this packet is a control packet */
54 void sci_interrupt() {
56 in = _io_ports[M6811_SCDR];
58 /* test for framing errors & parity bit */
59 if (_io_ports[M6811_SCSR] & M6811_FE || !parity_good(in)) {
60 _io_ports[M6811_SCDR]; /* read of register req'd to clear FE */
61 send_byte(0xff); /* request a retransmit */
65 /* all bytes must have the correct ID in the 3 MSBs */
66 if ((in & 0xe0) != COINMECH_ID) return;
68 /* we have a good packet */
70 /* retransmit was requested */
75 if (packet_pos != 0 || IS_CTRL(in)) {
79 /* just reply with ack */
80 /* original firmware does something with link master price holding */
83 /* write back how much change to give, or 0xfe to hold it. */
85 send_byte(item_cost / value_2);
90 /* hmmm, maybe we're sposed to do something here. firmware doesnt */
91 /* and just sets a random bit - something like "changer in use"? */
99 /* just ack it and move on */
104 switch (packet_pos) {
105 case 1: value_1 = in; break;
106 case 2: value_1 |= in << 4; break;
107 case 3: value_1 |= in << 8; break;
108 case 4: value_1 |= in << 12; break;
109 case 5: value_2 = in; break;
110 case 6: value_2 |= in << 4; break;
111 case 7: dec_point = in; break;
112 case 8: have_change = (in&0x01); break;
114 if (packet_pos == 9) {
116 coin_value = value_1*value_2;
121 send_byte(0x00); /* ack */
126 coin_cost(coin_value); /* eat everything */
129 void coin_cost(u16 cost) {
131 while(coin_value); /* wait until coin mech cleared */