X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=ROM2%2Fcoinmech.c;h=d3b099205741042e7a6e9a914bc6ad7dc0f2ce87;hb=27fb8a023fa0572ef4171624781460bc59537d49;hp=a5a38e0f1775da208f2eb17d81d61d13a6088031;hpb=65f351eccb34b310c15e3cd38dcae5b152187092;p=uccvend-snackrom.git diff --git a/ROM2/coinmech.c b/ROM2/coinmech.c index a5a38e0..d3b0992 100644 --- a/ROM2/coinmech.c +++ b/ROM2/coinmech.c @@ -1,9 +1,17 @@ +#include "coinmech.h" #include "vend.h" #define COINMECH_ID 0x20 -u8 last_byte; +volatile u8 last_byte; +volatile u8 packet_pos; +volatile u16 value_1; +volatile u8 value_2; +volatile u8 dec_point; +volatile u16 coin_value; +u8 item_cost; +volatile bool have_change; u8 parity_test(u8 c) { u8 parity = 0; @@ -13,6 +21,8 @@ u8 parity_test(u8 c) { return parity; } +bool parity_good(u8 c) { + /* * parity_good truth table: * @@ -21,9 +31,10 @@ u8 parity_test(u8 c) { * -----+--------- * R8 0 | 1 0 * 1 | 0 1 + * + * equates to even parity? */ -bool parity_good(u8 c) { u8 R8 = (_io_ports[M6811_SCCR1] & M6811_R8)?1:0; u8 p = parity_test(c)?1:0; return R8 == p; @@ -33,20 +44,12 @@ void send_byte(u8 c) { last_byte = c; while (!(_io_ports[M6811_SCSR] & M6811_TDRE)); /* wait for TD register empty */ - if (parity_of(c)) - bset(&_io_ports[M6811_SCCR1], M6811_T8); + if (parity_test(c)) + bset((void*)&_io_ports[M6811_SCCR1], M6811_T8); else - bclr(&_io_ports[M6811_SCCR1], M6811_T8); + bclr((void*)&_io_ports[M6811_SCCR1], M6811_T8); } -void ask_for_retrans() { - /* sends an 0xff down the line */ - send_byte(0xff); -} - - -u8 packet_pos = 0; - #define IS_CTRL(x) (x & 0x10) /* true if this packet is a control packet */ void sci_interrupt() { u8 in; @@ -55,12 +58,12 @@ void sci_interrupt() { /* test for framing errors & parity bit */ if (_io_ports[M6811_SCSR] & M6811_FE || !parity_good(in)) { _io_ports[M6811_SCDR]; /* read of register req'd to clear FE */ - ask_for_retrans(); + send_byte(0xff); /* request a retransmit */ return; } /* all bytes must have the correct ID in the 3 MSBs */ - if (in & 0xe0 != COINMECH_ID) return; + if ((in & 0xe0) != COINMECH_ID) return; /* we have a good packet */ if (in == 0x3f) { @@ -69,10 +72,74 @@ void sci_interrupt() { return; } - if (packet_pos != 0 && !IS_CTRL(x&0x10)) { - switch (in & 0x0f) { + if (packet_pos != 0 || IS_CTRL(in)) { + in &= 0x0f; + switch (in) { + case 0x01: + /* just reply with ack */ + /* original firmware does something with link master price holding */ + send_byte(0x00); + case 0x02: + /* write back how much change to give, or 0xfe to hold it. */ + if (item_cost) { + send_byte(item_cost / value_2); + } else + send_byte(0xfe); + break; + case 0x03: + /* hmmm, maybe we're sposed to do something here. firmware doesnt */ + /* and just sets a random bit - something like "changer in use"? */ + break; + case 0x08: + /* start of packet */ + packet_pos = 1; + send_byte(0x00); + break; + default: + /* just ack it and move on */ + send_byte(0x00); } } else { - + in &= 0x0f; + switch (packet_pos) { + case 1: value_1 = in; break; + case 2: value_1 |= in << 4; break; + case 3: value_1 |= in << 8; break; + case 4: value_1 |= in << 12; break; + case 5: value_2 = in; break; + case 6: value_2 |= in << 4; break; + case 7: dec_point = in; break; + case 8: have_change = (in&0x01); break; + default: + if (packet_pos == 9) { + packet_pos = 0; + coin_value = value_1*value_2; + } + /* hmmm, else? */ + } + packet_pos++; + send_byte(0x00); /* ack */ } } + +void coin_eat() { + coin_cost(coin_value); /* eat everything */ +} + +void coin_cost(u16 cost) { + item_cost = cost; + while(coin_value); /* wait until coin mech cleared */ +} + +void coinmech_init() { + packet_pos = 0; + value_1 = value_2 = 0; + dec_point = 0; + coin_value = 0; + item_cost = 0; + have_change = 0; + _io_ports[M6811_SCCR1] = 0x10; + _io_ports[M6811_SCCR2] = 0x2e; + _io_ports[M6811_BAUD] = 0x03; + send_byte(0xff); +}