Mirror of CollapseOS
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

222 linhas
4.6KB

  1. ; tape blkdev read-only
  2. ; to be included as a kernel module.
  3. ; In the glue.asm devices list the PutB pointer has to be unsetZ
  4. ; defines:
  5. ; tap_buffer = 256-byte tape loading buffer in RAM
  6. ; buf_pos = read position in the buffer
  7. ; crossing the buffer boundaries require loading or rewinding+loading
  8. ; tap_pos = previous read position of the block device,
  9. ; then the difference btw current and previous positions, both in EDLH format as throughout the kernel code
  10. tapeblk_init:
  11. ; initialized CFS and a placeholder 1-block, 1-byte file in the buffer
  12. ; the tape fs is not default, has to be mounted
  13. ld hl, .plh
  14. ld de, tap_buffer
  15. ld bc, 6
  16. ldir
  17. ret
  18. .plh:
  19. .db "CFS",1,1,0,'@'
  20. tapeGetB:
  21. ; it gets the new position in DE/HL, has to return value in A
  22. push bc
  23. push ix
  24. ; First of all, is the difference between positions negative or positive?
  25. push hl ; store the position
  26. push de
  27. ld ix, tap_pos ; previous
  28. push de ; working copy, higher bytes
  29. ld e, (ix+2) ; lower bytes of previous position
  30. ld d, (ix+3)
  31. scf
  32. ccf
  33. sbc hl,de
  34. ld (ix+6), l
  35. ld (ix+7), h
  36. pop hl
  37. ld e, (ix+0) ; higher bytes
  38. ld d, (ix+1)
  39. sbc hl,de
  40. ld (ix+4), l
  41. ld (ix+5), h
  42. jp nc, .tblk_posdif
  43. .tblk_negdif:
  44. ; at this point we have the negative difference
  45. pop de ; restore the current position
  46. pop hl
  47. ; store it as 'the previous'
  48. ld (ix+0), e
  49. ld (ix+1), d
  50. ld (ix+2), l
  51. ld (ix+3), h
  52. ; let's set the buffer position while we're here
  53. ld a, (buf_pos)
  54. add a, (ix+6) ; l
  55. ; the difference bytes are negative, so e.g. add 255 = sub 1
  56. ld (buf_pos), a
  57. ; no carry would mean underflow in this case
  58. jp nc, .tblk_rewind
  59. ; we now have a chance that the higher bytes are FF (due to lower CY)
  60. xor a
  61. dec a
  62. and (ix+7)
  63. and (ix+4)
  64. and (ix+5)
  65. cp 255
  66. jp z, .tblk_readbyte ; a negative difference within the buffer
  67. ; we have to rewind the tape and load back to the current position,
  68. ; so it's safe to discard the difference and treat the current position as the positive difference
  69. .tblk_rewind:
  70. ; as we will rewind to zero, at least one additional block is to be loaded
  71. xor a
  72. inc h
  73. cp h
  74. jr nz, .tblk_store
  75. inc de
  76. .tblk_store:
  77. ld (ix+4), e ; diff
  78. ld (ix+5), d
  79. ld (ix+6), l ; diff
  80. ld (ix+7), h
  81. ; purple border means 'rewind the tape and press enter'
  82. di
  83. ld a, 3
  84. out (254), a
  85. .tblk_key:
  86. ld a, 191 ; waiting for enter
  87. in a,(254)
  88. rra
  89. jr c, .tblk_key
  90. ei
  91. jr .tblk_skip
  92. ; we don't have to set the buffer position, done it already
  93. .tblk_posdif:
  94. ; at this point we have the difference and know it is positive
  95. pop de ; restore the current position
  96. pop hl
  97. ; store it as 'the previous'
  98. ld (ix+0), e
  99. ld (ix+1), d
  100. ld (ix+2), l
  101. ld (ix+3), h
  102. .tblk_buffer:
  103. ; setting the buffer position for the positive difference
  104. ld a, (buf_pos)
  105. add a, (ix+6) ; l
  106. ld (buf_pos), a
  107. jr nc, .tblk_skip
  108. ; now we increase the higher difference bytes due to overflow
  109. xor a
  110. inc (ix+7) ; h
  111. cp (ix+7)
  112. jr nz, .tblk_skip
  113. inc (ix+4) ; e
  114. cp (ix+4)
  115. jr nz, .tblk_skip
  116. inc (ix+5) ; d
  117. .tblk_skip:
  118. ; Now, how many tape blocks do we have to load before the target block appears in the buffer?
  119. ; it is shown by the 3 higher bytes of the difference
  120. ; We've just set them up for the positive difference case.
  121. ; For the negative difference case, the L-byte has to be equal to the buf_pos we set earlier
  122. ; (ix+7) H, (ix+4) E, (ix+5) D is now the counter for blocks to be loaded
  123. ; if it's 0, the block is already at the buffer and we don't have to load anything
  124. xor a
  125. or (ix+7)
  126. or (ix+4)
  127. or (ix+5)
  128. jp z, .tblk_readbyte
  129. ; well, let's play the tape
  130. ld a, (ix+5)
  131. ld b,a ; this is the outer cycle
  132. inc b ; as we will djnz
  133. ld a, (ix+7)
  134. ld l, a ; lower byte of the inner counter
  135. ld a, (ix+4)
  136. ld h, a ; higher byte
  137. dec hl ; as we know at this point that at least one block is to be loaded
  138. ld c, 0 ; it's a 16-bit cycle flag used below
  139. xor a
  140. or h
  141. or l
  142. jp z, .tblk_load
  143. ld c, 1 ; hl=nonzero
  144. .tblk_load:
  145. push bc ; counters
  146. push hl
  147. ld ix, tap_buffer ; we don't need the ix value anymore
  148. ld de, 256
  149. ld a, 255
  150. call t_load
  151. pop hl
  152. pop bc
  153. ; counter
  154. xor a
  155. dec hl
  156. or h
  157. or l
  158. jr nz, .tblk_ccheck
  159. ld c, 0 ; on the next cycle, b has to be decremented
  160. jr .tblk_load
  161. .tblk_ccheck:
  162. xor a
  163. or c
  164. jp nz, .tblk_load
  165. inc c ; next 16-bit cycle
  166. djnz .tblk_load
  167. .tblk_readbyte:
  168. ld hl, tap_buffer
  169. ld b, 0
  170. ld a, (buf_pos)
  171. ld c, a
  172. add hl,bc
  173. ld a, (hl) ; here it is!
  174. pop ix
  175. pop bc
  176. cp a
  177. ret
  178. t_load:
  179. push iy
  180. ld iy, IYBAS
  181. scf
  182. ; one can not call directly, as RST8 is then called upon break
  183. inc d
  184. ex af,af'
  185. dec d
  186. di
  187. ld a, 15
  188. out (254), a
  189. call 1378 ; jump into LD-BYTES
  190. t_ldret:
  191. ld a, (23624) ; restore border
  192. and 0x38
  193. rrca
  194. rrca
  195. rrca
  196. out (254),a
  197. pop iy
  198. ei
  199. ret
  200. ;end