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.

112 lines
2.3KB

  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. ; *** VARIABLES ***
  16. ; A memory pointer to a device table. A device table is a list of addresses
  17. ; pointing to GetC, PutC and Seek routines.
  18. BLOCKDEV_TBL .equ BLOCKDEV_RAMSTART
  19. ; Pointer to the selected block device. A block device is a 6 bytes block of
  20. ; memory with pointers to GetC, PutC and Seek routines, in that order. 0 means
  21. ; unsupported.
  22. BLOCKDEV_SEL .equ BLOCKDEV_TBL+(BLOCKDEV_COUNT*2)
  23. BLOCKDEV_RAMEND .equ BLOCKDEV_SEL+2
  24. ; *** CODE ***
  25. ; set DE to point to the table entry at index A.
  26. blkFind:
  27. ld de, BLOCKDEV_TBL
  28. cp 0
  29. ret z ; index is zero? don't loop
  30. push bc
  31. ld b, a
  32. .loop:
  33. inc de
  34. inc de
  35. djnz .loop
  36. pop bc
  37. ret
  38. ; Set the pointer of device id A to the value in HL
  39. blkSet:
  40. call blkFind
  41. call writeHLinDE
  42. ret
  43. ; Select block index specified in A
  44. blkSel:
  45. push de
  46. push hl
  47. call blkFind
  48. ld hl, BLOCKDEV_SEL
  49. ex hl, de
  50. ldi
  51. pop hl
  52. pop de
  53. ret
  54. blkBselCmd:
  55. .db "bsel", 0b001, 0, 0
  56. blkBsel:
  57. ld a, (hl) ; argument supplied
  58. cp BLOCKDEV_COUNT
  59. jr nc, .error ; if selection >= device count, error
  60. call blkSel
  61. xor a
  62. ret
  63. .error:
  64. ld a, BLOCKDEV_ERR_OUT_OF_BOUNDS
  65. ret
  66. ; In those routines below, IY is destroyed (we don't push it to the stack). We
  67. ; seldom use it anyways...
  68. ; call routine in BLOCKDEV_SEL with offset IYL.
  69. _blkCall:
  70. push ix
  71. push de
  72. ld de, (BLOCKDEV_SEL)
  73. ; DE now points to the *address table*, not the routine addresses
  74. ; themselves. One layer of indirection left.
  75. ; slide by offset
  76. push af
  77. ld a, iyl
  78. call addDE ; slide by offset
  79. pop af
  80. call intoDE
  81. ; Alright, now de points to what we want to call
  82. ld ixh, d
  83. ld ixl, e
  84. pop de
  85. call callIX
  86. pop ix
  87. ret
  88. ; Reads one character from blockdev ID specified at A and returns its value
  89. ; in A. Always returns a character and waits until read if it has to.
  90. blkGetC:
  91. ld iyl, 0
  92. jr _blkCall
  93. blkPutC:
  94. ld iyl, 2
  95. jr _blkCall
  96. blkSeek:
  97. ld iyl, 4
  98. jr _blkCall