Mirror of CollapseOS
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

88 строки
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_hasrx(ACIA *acia)
  31. {
  32. return acia->status & 0x01; // RDRF
  33. }
  34. bool acia_hastx(ACIA *acia)
  35. {
  36. return !(acia->status & 0x02); // TRDE
  37. }
  38. uint8_t acia_read(ACIA *acia)
  39. {
  40. acia->status |= 0x02; // TRDE high
  41. _check_irq(acia);
  42. return acia->tx;
  43. }
  44. void acia_write(ACIA *acia, uint8_t val)
  45. {
  46. if (acia->control & 0x40) { // RTS high
  47. fprintf(stderr, "ACIA RTS high: can't send byte\n");
  48. return;
  49. }
  50. acia->status |= 0x01; // RDRF high
  51. acia->rx = val;
  52. _check_irq(acia);
  53. }
  54. uint8_t acia_ctl_rd(ACIA *acia)
  55. {
  56. return acia->status;
  57. }
  58. void acia_ctl_wr(ACIA *acia, uint8_t val)
  59. {
  60. acia->control = val;
  61. _check_irq(acia);
  62. }
  63. uint8_t acia_data_rd(ACIA *acia)
  64. {
  65. acia->status &= ~0x81; // RDRF and IRQ low
  66. acia->in_int = false;
  67. return acia->rx;
  68. }
  69. void acia_data_wr(ACIA *acia, uint8_t val)
  70. {
  71. acia->tx = val;
  72. acia->status &= ~0x82; // TRDE and IRQ low
  73. acia->in_int = false;
  74. _check_irq(acia);
  75. }