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.

133 lines
2.9KB

  1. ; blockdev
  2. ;
  3. ; A block device is an abstraction over something we can read from, write to.
  4. ;
  5. ; A device that fits this abstraction puts the properly hook into itself, and
  6. ; then the glue code assigns a blockdev ID to that device. It then becomes easy
  7. ; to access arbitrary devices in a convenient manner.
  8. ;
  9. ; This part exposes a new "bsel" command to select the currently active block
  10. ; device.
  11. ; *** DEFINES ***
  12. ; BLOCKDEV_COUNT: The number of devices we manage.
  13. ; *** CONSTS ***
  14. BLOCKDEV_ERR_OUT_OF_BOUNDS .equ 0x03
  15. BLOCKDEV_ERR_UNSUPPORTED .equ 0x04
  16. ; *** VARIABLES ***
  17. ; Pointer to the selected block device. A block device is a 6 bytes block of
  18. ; memory with pointers to GetC, PutC and Seek routines, in that order. 0 means
  19. ; unsupported.
  20. BLOCKDEV_SEL .equ BLOCKDEV_RAMSTART
  21. BLOCKDEV_RAMEND .equ BLOCKDEV_SEL+2
  22. ; *** CODE ***
  23. ; Select block index specified in A
  24. blkSel:
  25. push af
  26. push hl
  27. ld hl, blkDevTbl
  28. cp 0
  29. jr z, .afterloop ; index is zero? don't loop
  30. push bc
  31. ld b, a
  32. .loop:
  33. ld a, 6
  34. call addHL
  35. djnz .loop
  36. pop bc
  37. .afterloop:
  38. ld (BLOCKDEV_SEL), hl
  39. pop Hl
  40. pop af
  41. ret
  42. blkBselCmd:
  43. .db "bsel", 0b001, 0, 0
  44. ld a, (hl) ; argument supplied
  45. cp BLOCKDEV_COUNT
  46. jr nc, .error ; if selection >= device count, error
  47. call blkSel
  48. xor a
  49. ret
  50. .error:
  51. ld a, BLOCKDEV_ERR_OUT_OF_BOUNDS
  52. ret
  53. ; In those routines below, IY is destroyed (we don't push it to the stack). We
  54. ; seldom use it anyways...
  55. ; call routine in BLOCKDEV_SEL with offset IYL.
  56. _blkCall:
  57. push ix
  58. push de
  59. ld de, (BLOCKDEV_SEL)
  60. ; DE now points to the *address table*, not the routine addresses
  61. ; themselves. One layer of indirection left.
  62. ; slide by offset
  63. push af
  64. ld a, iyl
  65. call addDE ; slide by offset
  66. pop af
  67. call intoDE
  68. ; Alright, now de points to what we want to call
  69. ld ixh, d
  70. ld ixl, e
  71. pop de
  72. ; Before we call... is it zero? We don't want to call a zero.
  73. push af
  74. ld a, ixh
  75. add a, ixl
  76. jr c, .ok ; if there's a carry, it isn't zero
  77. cp 0
  78. jr z, .error ; if no carry and zero, then both numbers are
  79. ; zero
  80. .ok:
  81. pop af
  82. call callIX
  83. jr .end
  84. .error:
  85. pop af
  86. ld a, BLOCKDEV_ERR_UNSUPPORTED
  87. .end:
  88. pop ix
  89. ret
  90. ; Reads one character from selected device and returns its value in A. Always
  91. ; returns a character and waits until read if it has to.
  92. blkGetC:
  93. ld iyl, 0
  94. jr _blkCall
  95. ; Writes character in A in current position in the selected device
  96. blkPutC:
  97. ld iyl, 2
  98. jr _blkCall
  99. blkSeekCmd:
  100. .db "seek", 0b011, 0b001, 0
  101. ; HL points to two bytes that contain out address. Seek expects HL
  102. ; to directly contain that address.
  103. ld a, (hl)
  104. ex af, af'
  105. inc hl
  106. ld a, (hl)
  107. ld l, a
  108. ex af, af'
  109. ld h, a
  110. xor a
  111. ; Set position of selected device to the value specified in HL
  112. blkSeek:
  113. ld iyl, 4
  114. jr _blkCall
  115. ; This label is at the end of the file on purpose: the glue file should include
  116. ; a list of device routine table entries just after the include. Each line
  117. ; has 3 word addresses: GetC, PutC and Seek. An entry could look like:
  118. ; .dw mmapGetC, mmapPutC, mmapSeek
  119. blkDevTbl: