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.

83 lines
1.4KB

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