Mirror of CollapseOS
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

135 wiersze
3.4KB

  1. ; acia
  2. ;
  3. ; Manage I/O from an asynchronous communication interface adapter (ACIA).
  4. ; provides "aciaPutC" to put c char on the ACIA as well as an input buffer.
  5. ; You have to call "aciaInt" on interrupt for this module to work well.
  6. ;
  7. ; "aciaInit" also has to be called on boot, but it doesn't call "ei" and "im 1",
  8. ; which is the responsibility of the main asm file, but is needed.
  9. ; *** DEFINES ***
  10. ; ACIA_CTL: IO port for the ACIA's control registers
  11. ; ACIA_IO: IO port for the ACIA's data registers
  12. ; ACIA_RAMSTART: Address at which ACIA-related variables should be stored in
  13. ; RAM.
  14. ; *** CONSTS ***
  15. ; size of the input buffer. If our input goes over this size, we start losing
  16. ; data.
  17. ACIA_BUFSIZE .equ 0x20
  18. ; *** VARIABLES ***
  19. ; Our input buffer starts there. This is a circular buffer.
  20. ACIA_BUF .equ ACIA_RAMSTART
  21. ; The "read" index of the circular buffer. It points to where the next char
  22. ; should be read. If rd == wr, the buffer is empty. Not touched by the
  23. ; interrupt.
  24. ACIA_BUFRDIDX .equ ACIA_BUF+ACIA_BUFSIZE
  25. ; The "write" index of the circular buffer. Points to where the next char
  26. ; should be written. Should only be touched by the interrupt. if wr == rd-1,
  27. ; the interrupt will *not* write in the buffer until some space has been freed.
  28. ACIA_BUFWRIDX .equ ACIA_BUFRDIDX+1
  29. ACIA_RAMEND .equ ACIA_BUFWRIDX+1
  30. aciaInit:
  31. ; initialize variables
  32. xor a
  33. ld (ACIA_BUFRDIDX), a ; starts at 0
  34. ld (ACIA_BUFWRIDX), a
  35. ; setup ACIA
  36. ; CR7 (1) - Receive Interrupt enabled
  37. ; CR6:5 (00) - RTS low, transmit interrupt disabled.
  38. ; CR4:2 (101) - 8 bits + 1 stop bit
  39. ; CR1:0 (10) - Counter divide: 64
  40. ld a, 0b10010110
  41. out (ACIA_CTL), a
  42. ret
  43. ; Increase the circular buffer index in A, properly considering overflow.
  44. ; returns value in A.
  45. aciaIncIndex:
  46. inc a
  47. cp ACIA_BUFSIZE
  48. ret nz ; not equal? nothing to do
  49. ; equal? reset
  50. xor a
  51. ret
  52. ; read char in the ACIA and put it in the read buffer
  53. aciaInt:
  54. push af
  55. push hl
  56. ; Read our character from ACIA into our BUFIDX
  57. in a, (ACIA_CTL)
  58. bit 0, a ; is our ACIA rcv buffer full?
  59. jr z, .end ; no? a interrupt was triggered for nothing.
  60. ; Load both read and write indexes so we can compare them. To do so, we
  61. ; perform a "fake" read increase and see if it brings it to the same
  62. ; value as the write index.
  63. ld a, (ACIA_BUFRDIDX)
  64. call aciaIncIndex
  65. ld l, a
  66. ld a, (ACIA_BUFWRIDX)
  67. cp l
  68. jr z, .end ; Equal? buffer is full
  69. ; Alrighty, buffer not full. let's write.
  70. ld de, ACIA_BUF
  71. ; A already contains our write index, add it to DE
  72. call addDE
  73. ; increase our buf ptr while we still have it in A
  74. call aciaIncIndex
  75. ld (ACIA_BUFWRIDX), a
  76. ; And finally, fetch the value and write it.
  77. in a, (ACIA_IO)
  78. ld (de), a
  79. .end:
  80. pop hl
  81. pop af
  82. ei
  83. reti
  84. ; Read a character from the input buffer. If the buffer is empty, loop until
  85. ; there something to fetch. Returns value in A.
  86. aciaGetC:
  87. push de
  88. .loop:
  89. ld a, (ACIA_BUFWRIDX)
  90. ld e, a
  91. ld a, (ACIA_BUFRDIDX)
  92. cp e
  93. jr z, .loop ; equal? buffer empty, wait.
  94. ; Alrighty, buffer not empty. let's read.
  95. ld de, ACIA_BUF
  96. ; A already contains our read index, add it to DE
  97. call addDE
  98. ; increase our buf ptr while we still have it in A
  99. call aciaIncIndex
  100. ld (ACIA_BUFRDIDX), a
  101. ; And finally, fetch the value.
  102. ld a, (de)
  103. pop de
  104. ret
  105. ; spits character in A in port SER_OUT
  106. aciaPutC:
  107. push af
  108. .stwait:
  109. in a, (ACIA_CTL) ; get status byte from SER
  110. bit 1, a ; are we still transmitting?
  111. jr z, .stwait ; if yes, wait until we aren't
  112. pop af
  113. out (ACIA_IO), a ; push current char
  114. ret