Mirror of CollapseOS
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

98 řádky
2.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 echo
  16. ; immediately.
  17. ACIA_BUFSIZE .equ 0x20
  18. ; *** VARIABLES ***
  19. ; Our input buffer starts there
  20. ACIA_BUF .equ ACIA_RAMSTART
  21. ; index, in the buffer, where our next character will go. 0 when the buffer is
  22. ; empty, BUFSIZE-1 when it's almost full.
  23. ACIA_BUFIDX .equ ACIA_BUF+ACIA_BUFSIZE
  24. ACIA_RAMEND .equ ACIA_BUFIDX+1
  25. aciaInit:
  26. ; initialize variables
  27. xor a
  28. ld (ACIA_BUFIDX), a ; starts at 0
  29. ; setup ACIA
  30. ; CR7 (1) - Receive Interrupt enabled
  31. ; CR6:5 (00) - RTS low, transmit interrupt disabled.
  32. ; CR4:2 (101) - 8 bits + 1 stop bit
  33. ; CR1:0 (10) - Counter divide: 64
  34. ld a, 0b10010110
  35. out (ACIA_CTL), a
  36. ret
  37. ; read char in the ACIA and put it in the read buffer
  38. aciaInt:
  39. push af
  40. push hl
  41. ; Read our character from ACIA into our BUFIDX
  42. in a, (ACIA_CTL)
  43. bit 0, a ; is our ACIA rcv buffer full?
  44. jr z, .end ; no? a interrupt was triggered for nothing.
  45. call aciaBufPtr ; HL set, A set
  46. ; is our input buffer full? If yes, we don't read anything. Something
  47. ; is wrong: we don't process data fast enough.
  48. cp ACIA_BUFSIZE
  49. jr z, .end ; if BUFIDX == BUFSIZE, our buffer is full.
  50. ; increase our buf ptr while we still have it in A
  51. inc a
  52. ld (ACIA_BUFIDX), a
  53. in a, (ACIA_IO)
  54. ld (hl), a
  55. .end:
  56. pop hl
  57. pop af
  58. ei
  59. reti
  60. ; Set current buffer pointer in HL. The buffer pointer is where our *next* char
  61. ; will be written. A is set to the value of (BUFIDX)
  62. aciaBufPtr:
  63. push bc
  64. ld a, (ACIA_BUFIDX)
  65. ld hl, ACIA_BUF
  66. xor b
  67. ld c, a
  68. add hl, bc ; hl now points to INPTBUF + BUFIDX
  69. pop bc
  70. ret
  71. ; spits character in A in port SER_OUT
  72. aciaPutC:
  73. push af
  74. .stwait:
  75. in a, (ACIA_CTL) ; get status byte from SER
  76. bit 1, a ; are we still transmitting?
  77. jr z, .stwait ; if yes, wait until we aren't
  78. pop af
  79. out (ACIA_IO), a ; push current char
  80. ret