vram-addressing.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. VRAM Addressing
  2. ===============
  3. This document describes a model for the way the V9938 VDP calculates
  4. addresses in VRAM using base registers and indices.
  5. General Formula
  6. ---------------
  7. General formula for VRAM addressing:
  8. vram_address = index1 & mask
  9. where:
  10. vram_address is the index in VRAM
  11. index1 is the index in the particular table, such as the name table or
  12. color table. The unused bits of index are all ones.
  13. mask is the value in the table's base register. The unused bits of mask
  14. are all ones.
  15. Examples:
  16. The name table base register is VDP R#2.
  17. It contains A16-A10 of the mask, the other bits are 1.
  18. If R#2 would contain 24h, the mask would be:
  19. (24h << 10) | ~(-1 << 10) = 093FFh
  20. In SCREEN1 (Graphic 1) there are usually 24 lines of 32 characters each.
  21. However, the actual screen height is 32 lines, as can be seen when the
  22. vertical adjust register R#23 is used. So the number of characters per
  23. screen is 32*32 = 1024 = 2^10. With one byte per character, the index is
  24. 10 bits wide.
  25. If the index would be 157h, this is extended with leading ones for A10 and
  26. higher (1FC00h) to become 1FD57h. Then the final address is:
  27. vram_address = 1FD57h & 093FFh = 09157h
  28. Note that in this case, the final address is equal to:
  29. R#2 * 2^10 + index = 09000h + 157h = 09157h
  30. This is true for all display modes in which the used bits in the base
  31. register (A16..A10 in this case) do not overlap the bits in the index
  32. (A9..A0 in this case). This is also the way application programmers
  33. typically use the table base address registers.
  34. In SCREEN5 (Graphic 4) there are 256 lines of 128 bytes each. Only 212 lines
  35. are visible at a time, but using the vertical adjust register R#23 all 256
  36. lines can be seen. A line is 256 pixels wide, with 4 bits per pixel that
  37. makes 128 bytes per line. So the total number of bytes per screen is
  38. 256 * 128 = 32768 = 2^15. Therefore the index is 15 bits wide.
  39. If the index would be 4521h, this is extended with leading ones for A16 and
  40. A15 (18000h) to become 1C521h. Using the same mask as before (093FFh), the
  41. final address is:
  42. vram_address = 1C521h & 093FFh = 08121h
  43. Note that in this case, the final address is NOT equal to:
  44. R#2 * 2^10 + index = 09000h + 4521h = 0D521h
  45. The VDP data book states that in SCREEN5 bit4 to bit0 should be 1, in those
  46. cases the general formula is equivalent to addition. But when some of those
  47. bits are zeroes, the general formula gives the same result the real VDP
  48. does, while addition does not. The many-scrollers part of Anma's "Source of
  49. Power" demo uses this feature to display the same scrolling text many times
  50. on the same screen.
  51. Range Checking
  52. --------------
  53. Different VDP subsystems are interested in different tables. For example,
  54. the sprite subsystem is only interested in the sprite name and pattern
  55. tables. On reads and writes to tables, interested subsystems must be
  56. informed so they can update their internal state. Therefore an algorithm is
  57. needed which calculates in which tables (if any) a given address is located.
  58. Here is the address calculation formula again:
  59. vram_address = index1 & mask
  60. The lowest address within the range is when the index is 0, index1 then
  61. contains only ones in unused bits. The highest address (inclusive) is when
  62. the index is all ones, then index1 is also all ones and the address is equal
  63. to the mask. However, not all addresses between the lowest and the highest
  64. address actually occur if the mask has one or more zeroes in the bits that
  65. overlap with the index.
  66. Let "inside : Int -> Bool" be the function that tells whether an address is
  67. inside a table:
  68. inside.addr = (Exist i : i in Indices : i & mask = addr)
  69. In English: there is an index i, for which the VRAM address is addr.
  70. A convenient formula for the inside function is this one:
  71. inside.addr =
  72. addr & (~mask | (-1 << index_width)) = mask & (-1 << index_width)
  73. Note that "addr" only occurs once and all other values are constant for each
  74. display mode, so the check takes two operations (one compare and one AND).
  75. This is probably the cheapest you can get.
  76. Index Width
  77. -----------
  78. Which address bits are stored in the table base address registers is
  79. documented in the VDP data book, but which address bits are produced by the
  80. index is not documented there. This section fills that gap.
  81. - Name Table -
  82. Name table base address is [A16..A10] (R#2).
  83. Display mode: Index width in bits:
  84. Text 1 12 (*1)
  85. Text 2 12
  86. Multicolor 10 (*2)
  87. Graphic 1 10 (*2)
  88. Graphic 2 10 (*2)
  89. Graphic 3 10 (*2)
  90. Graphic 4 15
  91. Graphic 5 15
  92. Graphic 6 15 + plane (*3)
  93. Graphic 7 15 + plane (*3)
  94. (*1) Text 1 index is calculated as 00C00h + position.
  95. On MSX1 it was 10 bits wide. For some reason, unifying address
  96. calculation with Text 2 must have been simpler than keeping it 10 bits
  97. wide, even though unification requires an add operation.
  98. (*2) Maybe this is 12 bits and index = 00C00h + position just like Text 1.
  99. That's equivalent to 10 bits though, because there are 1024 characters
  100. per screen.
  101. (*3) See "Planar Addressing" section for details.
  102. - Pattern Table -
  103. Pattern table base address is [A16..A11] (R#4).
  104. Display mode: Index width in bits:
  105. Text 1 11
  106. Text 2 11
  107. Multicolor 11
  108. Graphic 1 11
  109. Graphic 2 13
  110. Graphic 3 13
  111. Graphic 4 -
  112. Graphic 5 -
  113. Graphic 6 -
  114. Graphic 7 -
  115. - Color Table -
  116. Color table base address is [A16..A6] (R#3 and R#10).
  117. Display mode: Index width in bits:
  118. Text 1 -
  119. Text 2 9
  120. Multicolor -
  121. Graphic 1 6 (*1)
  122. Graphic 2 13
  123. Graphic 3 13
  124. Graphic 4 -
  125. Graphic 5 -
  126. Graphic 6 -
  127. Graphic 7 -
  128. (*1) Bit5 is fixed to zero.
  129. - Sprite Attribute Table -
  130. Sprite mode: Index width in bits:
  131. mode 1 7
  132. mode 2 10 (*1)
  133. (*1) Bit9 selects sprite color table (0) or sprite attribute table (1).
  134. Bit8 and Bit7 are fixed to zero for the attribute table.
  135. - Sprite Pattern Table -
  136. Sprite mode: Index width in bits:
  137. mode 1 11
  138. mode 2 11
  139. Index Calculation
  140. -----------------
  141. The following variables occur in every display mode:
  142. org_line: display line,
  143. 0 <= org_line < 256
  144. line: org_line after scroll adjustment (R#23 is applied),
  145. 0 <= line < 256
  146. name: value in VRAM at address (name_index & name_mask),
  147. 0 <= name < 256
  148. The "/" operation is integer division ("div").
  149. The "%" operation is modulo/remainder ("mod").
  150. - Text 1 -
  151. Aka SCREEN0, WIDTH40.
  152. 0 <= x < 40
  153. y = org_line / 8
  154. name_index = 00C00h + y * 40 + x
  155. pattern_index = name * 8 + line % 8
  156. Adding 00C00h was probably done to make the index 12 bits wide, just like
  157. in Text 2 mode. You can see this addition in action if you enable 212 lines
  158. display and then play with different values of R#2. Pay attention to the
  159. characters displayed in the lower few lines of the screen.
  160. - Text 2 -
  161. Aka SCREEN0, WIDTH80.
  162. 0 <= x < 80
  163. y = org_line / 8
  164. name_index = y * 80 + x
  165. pattern_index = name * 8 + line % 8
  166. - Multicolor -
  167. Aka SCREEN3.
  168. 0 <= x < 32
  169. y = line / 8
  170. name_index = y * 32 + x
  171. pattern_index = name * 8 + line % 4
  172. - Graphic 1 -
  173. Aka SCREEN1.
  174. 0 <= x < 32
  175. y = line / 8
  176. name_index = y * 32 + x
  177. pattern_index = name * 8 + line % 8
  178. color_index = name / 8
  179. - Graphic 2 and 3 -
  180. These modes are equivalent, except for the sprite mode.
  181. Aka SCREEN2 and SCREEN4.
  182. 0 <= x < 32
  183. y = line / 8
  184. name_index = y * 32 + x
  185. pattern_index = ((line / 64) * 256 + name) * 8 + line % 8
  186. color_index = ((line / 64) * 256 + name) * 8 + line % 8
  187. - Graphic 4 -
  188. 0 <= x < 256
  189. name_index = line * 128 + x / 2
  190. - Graphic 5 -
  191. 0 <= x < 512
  192. name_index = line * 128 + x / 4
  193. - Graphic 6 -
  194. 0 <= x < 512
  195. name_index = line * 128 + x / 4
  196. plane = (x / 2) % 2
  197. - Graphic 7 -
  198. 0 <= x < 256
  199. name_index = line * 128 + x / 2
  200. plane = x % 2
  201. - Sprite Mode 1 -
  202. 0 <= sprite_nr < 32
  203. attrib_index = sprite_nr * 4
  204. 0 <= pattern_nr < 256
  205. pattern_index = pattern_nr * 8
  206. When sprite size is 16x16, Bit1 and Bit0 of the index are ignored.
  207. Four patterns define the look of a single sprite, like this:
  208. 0 2
  209. 1 3
  210. - Sprite Mode 2 -
  211. 0 <= sprite_nr < 32
  212. attrib_index = 512 + sprite_nr * 4
  213. color_index = sprite_nr * 16
  214. 0 <= pattern_nr < 256
  215. pattern_index = pattern_nr * 8
  216. When sprite size is 16x16, Bit1 and Bit0 of the index are ignored.
  217. Four patterns define the look of a single sprite, like this:
  218. 0 2
  219. 1 3
  220. Planar Addressing
  221. -----------------
  222. The V9938 has 3 pins that select a group of VRAM ICs each: CAS0, CAS1 and CASX.
  223. CASX is used to select the expansion RAM, which can be accessed through the CPU
  224. interface and through commands, but cannot be displayed directly.
  225. Each VRAM group can be 0K, 16K or 64K. A group can consist of 8 chips of 1-bit
  226. wide RAM or 2 chips of 4-bit wide RAM, but for the purpose of addressing we can
  227. just pretend it is 1 chip with 8-bit wide RAM.
  228. In real MSX machines, the following group combinations are used:
  229. CAS0: CAS1: CASX: Description:
  230. 16K 0K 0K MSX1 with V9938 and 16K VRAM (*1)
  231. 64K 0K 0K MSX2 with 64K VRAM (*2)
  232. 64K 64K 0K MSX2 with 128K VRAM
  233. 64K 64K 64K MSX2 with 128K VRAM and 64K expansion (*3)
  234. *1: Examples are the Spectravideo SVI-738 X'PRESS and the Yamaha CX5MII/128.
  235. The only V9938-specific display mode that they can fully display is
  236. 80-columns text mode (TEXT2).
  237. *2: Known 64K VRAM machines: Canon V-25, Hitachi MB-H3, Talent TPP-311 and 312,
  238. Toshiba HX-23.
  239. *3: No known machines shipped with expansion VRAM. It was a popular amateur
  240. upgrade for users of FastCopy, to reduce the number of required disk swaps.
  241. In most display modes addressing is linear, meaning the lower 64K of address
  242. space uses the VRAM connected to CAS0 and the upper 64K of address space uses
  243. the VRAM connected to CAS1.
  244. In SCREEN7/8 (Graphic 6/7) the addressing is planar, meaning that even VRAM
  245. addresses are mapped to CAS0 and odd addresses are mapped to CAS1. This means
  246. that SCREEN 7/8 are only available on 128K VRAM machines. The most likely
  247. reason for using planar addressing is getting a higher bandwidth: even though
  248. the data lines are shared between all VRAM groups, the row select has to be
  249. done only once.
  250. VR=0 / VR=1 mode
  251. ----------------
  252. The VDP chip has 10 pins that are connected to the VRAM subsystem to control
  253. the read/write address. There are 8 address pins, these select the CAS/RAS
  254. address. And there is a CAS0 and CAS1 pin, these select one of two ram chip
  255. (groups). In total this allows for a 17-bit address space (=128kB). (I'm
  256. ignoring the extended VRAM here).
  257. When the VDP does a memory access, it's puts the 17-bit logical address on
  258. these pins. The way how this is done depends on the VR bit (bit 3 of register
  259. 8), see table below.
  260. In VR=1 mode, it first puts the bits A15-A8 on the address bus, followed by the
  261. bits A7-A0. The whole time either pin CAS0 or CAS1 is selected, depending on
  262. address bit A16. In VR=0 mode, .. well see table ;)
  263. VDP | VR=0 | VR=1 |
  264. address|----------------------|----------------------|
  265. pin | RAS(high) | CAS(low) | RAS(high) | CAS(low) |
  266. -------+-----------+----------|-----------+----------|
  267. AD0 | A6 #2| 1 #1| A8 | A0 |
  268. AD1 | A7 | A0 | A9 | A1 |
  269. AD2 | A8 | A1 | A10 | A2 |
  270. AD3 | A9 | A2 | A11 | A3 |
  271. AD4 | A10 | A3 | A12 | A4 |
  272. AD5 | A11 | A4 | A13 | A5 |
  273. AD6 | A12 | A5 | A14 | A6 |
  274. AD7 | A13 | A6 #2| A15 | A7 |
  275. -------+-----------+----------|-----------+----------|
  276. CAS0/1 | A14 | A16 |
  277. #1 this pin is always '1' in the CAS phase
  278. #2 A6 is output both in CAS and RAS phase, this allows to use both 8/6 and 7/7
  279. RAS/CAS configurations (see VDP data sheet for details)
  280. One important side-effect is that in VR=0 mode, the VDP can only address 32kB
  281. memory. This is what makes the demo 'syntax infinity' work even though R14 is
  282. programmed 'wrongly' (it writes to address 0x1????, but expects the data to end
  283. up at address 0x0????).
  284. Another side effect is that when switching between VR=0 and VR=1 modes, the
  285. address space gets shuffled around, much like bit 7 in VDP register 1 for
  286. TMS99x8 chips.