abcpun80.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * abcpun80.c
  3. *
  4. * Emulate a PUN80 network card
  5. */
  6. #include "compiler.h"
  7. #include "fw.h"
  8. #include "io.h"
  9. #include "abcio.h"
  10. #define PUN_IOSEL 60
  11. #define PUN_TTY_CHAN 1
  12. #if PUN_TTY_CHAN >= TTY_CHANNELS
  13. # error "PUN_TTY_CHAN out of range"
  14. #endif
  15. #define PUN_DATA TTY_DATA(PUN_TTY_CHAN)
  16. #define PUN_WATERCTL TTY_WATERCTL(PUN_TTY_CHAN)
  17. #define PUN_STATUS TTY_STATUS(PUN_TTY_CHAN)
  18. #define PUN_IRQEN TTY_IRQEN(PUN_TTY_CHAN)
  19. #define PUN_IRQPOL TTY_IRQPOL(PUN_TTY_CHAN)
  20. #define PUN_IRQ TTY_NIRQ(PUN_TTY_CHAN)
  21. #define PUN_IRQ_MASK (TTY_STATUS_TX_FULL|TTY_STATUS_RX_EMPTY|\
  22. TTY_STATUS_USB_CONFIG)
  23. static struct abc_dev pun80_iodev;
  24. static __hot void pun80_refresh_input(bool advance);
  25. IRQHANDLER(tty,PUN_TTY_CHAN)
  26. {
  27. pun80_refresh_input(false);
  28. }
  29. /*
  30. * Convert to FT232H-compatible status codes, and advance
  31. * the receive FIFO if applicable.
  32. */
  33. static __hot void pun80_refresh_input(bool advance)
  34. {
  35. static bool data_loaded;
  36. unsigned int status;
  37. unsigned int pun80_status;
  38. status = PUN_STATUS;
  39. if (!data_loaded || advance) {
  40. data_loaded = !(status & TTY_STATUS_RX_EMPTY);
  41. if (data_loaded) {
  42. abc_set_inp_default(&pun80_iodev, PUN_DATA);
  43. status = PUN_STATUS;
  44. }
  45. }
  46. pun80_status = ~15;
  47. if (status & TTY_STATUS_USB_CONFIG)
  48. pun80_status |= 8;
  49. if (!(status & TTY_STATUS_TX_FULL))
  50. pun80_status |= 2;
  51. if (data_loaded)
  52. pun80_status |= 1;
  53. abc_set_inp_status(&pun80_iodev, pun80_status);
  54. PUN_IRQPOL = status;
  55. }
  56. ABC_CALLBACK(pun80_callback_out)
  57. {
  58. PUN_DATA = data;
  59. pun80_refresh_input(false);
  60. }
  61. ABC_CALLBACK(pun80_callback_inp)
  62. {
  63. pun80_refresh_input(true);
  64. }
  65. /* The "flush" command in FT232H (C1#) is not needed with our USB stack */
  66. static struct abc_dev pun80_iodev = {
  67. .callback_mask = (1 << 0)|(1 << 8),
  68. .inp_en = 3,
  69. .status_first_out_mask = ~0,
  70. .status_first_inp_mask = ~0,
  71. .callback_out[0] = pun80_callback_out,
  72. .callback_inp[0] = pun80_callback_inp
  73. };
  74. void pun80_init(void)
  75. {
  76. mask_irq(PUN_IRQ);
  77. PUN_IRQEN = PUN_IRQ_MASK;
  78. pun80_refresh_input(false);
  79. abc_register(&pun80_iodev, PUN_IOSEL);
  80. unmask_irq(PUN_IRQ);
  81. }