12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- /*
- * abcio.c
- *
- * Handle ABC-bus I/O operations
- */
- #include "fw.h"
- #include "io.h"
- #include "irq.h"
- #include "abcio.h"
- struct abc_dev *abc_device[64];
- static struct abc_dev *selected_dev;
- static inline void abc_select(struct abc_dev *dev)
- {
- selected_dev = dev;
- if (!dev) {
- ABC_BUSY_MASK = 0x0082; /* Only RST# and CS# */
- ABC_INP_ENABLE = 0;
- } else {
- ABC_BUSY_MASK = dev->callback_mask | 0x0082;
- ABC_INP_ENABLE = 3;
- }
- }
- IRQHANDLER(abc)
- {
- uint16_t what = ABC_BUSY_STATUS;
- bool callback = selected_dev && (what & selected_dev->callback_mask);
- if (what & 0xff) {
- uint8_t addr = ABC_OUT_ADDR;
- uint8_t data = ABC_OUT_DATA;
- switch (addr) {
- case 0:
- if (selected_dev->out_cnt) {
- *selected_dev->out_buf++ = data;
- selected_dev->inp_data[1] &= selected_dev->status_first_out_mask;
- ABC_INP1_DATA = selected_dev->inp_data[1];
- if (--selected_dev->out_cnt)
- callback = false;
- }
- /* fall through */
- case 2 ... 5:
- selected_dev->out_data[addr] = data;
- if (callback)
- selected_dev->callback_out(selected_dev, data, addr);
- break;
- case 1:
- {
- struct abc_dev *dev = abc_device[data & 0x3f];
- abc_select(dev);
- if (dev)
- dev->out_data[addr] = data;
- break;
- }
- case 7:
- /* XXX: broadcast reset to devices? */
- abc_select(NULL);
- break;
- default:
- break;
- }
- }
- if (what & 0x100) {
- if (selected_dev->inp_cnt) {
- ABC_INP0_DATA = *selected_dev->inp_buf++;
- selected_dev->inp_data[1] &= selected_dev->status_first_inp_mask;
- ABC_INP1_DATA = selected_dev->inp_data[1];
- if (--selected_dev->inp_cnt)
- callback = false;
- } else {
- ABC_INP0_DATA = selected_dev->inp_data[0];
- }
- if (callback)
- selected_dev->callback_inp(selected_dev, 0);
- }
- if (what & 0x200) {
- ABC_INP1_DATA = selected_dev->inp_data[1];
- if (callback)
- selected_dev->callback_inp(selected_dev, 1);
- }
- ABC_BUSY_STATUS = what;
- }
|