Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
1.6KB

  1. #include <stdio.h>
  2. #include "acia.h"
  3. static void _check_irq(ACIA *acia)
  4. {
  5. // do we have RDRF?
  6. if ((acia->status & 0x01) && (acia->control & 0x80)) {
  7. acia->status |= 0x80;
  8. }
  9. // do we have TDRE?
  10. if ((acia->status & 0x02) && ((acia->control & 0xe0) == 0xe0)) {
  11. acia->status |= 0x80;
  12. }
  13. }
  14. void acia_init(ACIA *acia)
  15. {
  16. acia->status = 0x02; // TDRE
  17. acia->control = 0x00;
  18. acia->rx = 0;
  19. acia->tx = 0;
  20. acia->in_int = false;
  21. }
  22. bool acia_has_irq(ACIA *acia)
  23. {
  24. if (acia->in_int) {
  25. return false;
  26. }
  27. acia->in_int = acia->status & 0x80;
  28. return acia->in_int;
  29. }
  30. bool acia_cantransmit(ACIA *acia)
  31. {
  32. return !(acia->status & 0x01 // RDRF
  33. || acia->control & 0x40); // RTS
  34. }
  35. bool acia_hastx(ACIA *acia)
  36. {
  37. return !(acia->status & 0x02); // TRDE
  38. }
  39. uint8_t acia_read(ACIA *acia)
  40. {
  41. acia->status |= 0x02; // TRDE high
  42. _check_irq(acia);
  43. return acia->tx;
  44. }
  45. void acia_write(ACIA *acia, uint8_t val)
  46. {
  47. if (acia->control & 0x40) { // RTS high
  48. fprintf(stderr, "ACIA RTS high: can't send byte\n");
  49. return;
  50. }
  51. acia->status |= 0x01; // RDRF high
  52. acia->rx = val;
  53. _check_irq(acia);
  54. }
  55. uint8_t acia_ctl_rd(ACIA *acia)
  56. {
  57. return acia->status;
  58. }
  59. void acia_ctl_wr(ACIA *acia, uint8_t val)
  60. {
  61. acia->control = val;
  62. _check_irq(acia);
  63. }
  64. uint8_t acia_data_rd(ACIA *acia)
  65. {
  66. acia->status &= ~0x81; // RDRF and IRQ low
  67. acia->in_int = false;
  68. return acia->rx;
  69. }
  70. void acia_data_wr(ACIA *acia, uint8_t val)
  71. {
  72. acia->tx = val;
  73. acia->status &= ~0x82; // TRDE and IRQ low
  74. acia->in_int = false;
  75. _check_irq(acia);
  76. }