Advertisement
Meneer_Jansen

Part 3. The VIC chip

Jul 3rd, 2020 (edited)
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.46 KB | None | 0 0
  1. .-----------------------------------.
  2. ( P A R T 3 . T H E V I C C H I P )
  3. `-----------------------------------´
  4. general contents: pastebin.com/hmpJmurr
  5.  
  6.  
  7.  
  8. The VIC-II chip (NTSC: MOS 6567, PAL: MOS 6569) manages graphics in the C64. It is the follow up of the VIC chip in the Commodore VIC-20. It can handle 8 sprites and 4 bit color graphics. This is a very difficult topic to grasp: I may be wrong in certain parts.
  9.  
  10.  
  11.  
  12. o==========o
  13. | Contents |
  14. o==========o
  15.  
  16. A. Memory banks (reprise)
  17.  
  18. B. RAM, ROM, CPU and VIC
  19. 1. RAM vs. CPU/VIC access
  20. 2. CPU: switch between I/O and char ROM
  21. 3. I/O memory map
  22. 4. The 47 VIC registers
  23.  
  24. C. Memory types
  25. 1a. Character (generator) ROM
  26. 1b. Character memory/RAM (replacement for ROM)
  27. 2. Bitmap
  28. 3. Screen RAM/scr mem/video matrix/video RAM (char position)
  29. 4. Color RAM (char color)
  30. 5. Bank config examples
  31.  
  32. D. Discussion
  33.  
  34. E. Bug
  35.  
  36. X. References
  37.  
  38. -<>-<>-<>-<>-<>-<>-<>-
  39.  
  40.  
  41.  
  42.  
  43. o===========================o
  44. | A. Memory banks (reprise) |
  45. o===========================o
  46.  
  47. Summary: set with DD00_hex (set write access to this register with DD02_hex).
  48.  
  49. In the doc "Memory map" it was explained that the VIC can only access 16 kB of memory. Therefore the 64 kB of RAM is divided into four banks that start at:
  50.  
  51. Bank 0: 0000_hex (default)
  52. Bank 1: 4000_hex
  53. Bank 2: 8000_hex
  54. Bank 3: C000_hex
  55.  
  56. Which bank the VIC uses is set via bits 0 to 1 of register DD00_hex (see "I/O memory map"). In bank 0 and 2 the 4 kB of Character ROM is shadowed at 1000_hex and 9000_hex respectively. After startup the VIC uses Bank 0.
  57.  
  58.  
  59.  
  60. o==========================o
  61. | B. RAM, ROM, CPU and VIC |
  62. o==========================o
  63.  
  64. As said, RAM is shared by CPU and VIC. Certain locations in RAM "are meant" for the VIC (like bitmaps), others for the CPU (like free BASIC RAM), and some for both (like color RAM). Some RAM locations are shortcut to ROM, the VIC has a separate bus for accessing color RAM and the CPU can set registers in the VIC by means of "a shortcut via RAM".
  65.  
  66. 1. RAM vs. CPU/VIC access
  67. ~~~~~~~~~~~~~~~~~~~~~~~~~
  68. This is explained quite well in [4] Ch. 2.4.3. "The division of accesses between CPU and VIC is basically static: each clock cycle consists of two phases. The VIC accesses in the first phase, the processor in the second. That way the CPU and VIC can both use the memory alternatively without disturbing each other.
  69.  
  70. The VIC has primary control over the bus and may "stun" the processor sometime or another when it needs additional cycles for memory accesses. So called "bad lines" result from this (see Appendix).
  71.  
  72. 2. CPU: switch between I/O and char ROM
  73. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  74. This is explained quite well in "Mapping the C64" [2] chapter 1, page 6. One has to make a choice for the CPU. The CPU can use RAM from D000 to E000_hex to address in- and output (see mem map below) or it can use that part of RAM to read the character ROM chip that is inside the C64. Switch this on/off with bit 2 of 0001_hex. Now, why should one ditch the ability to use in- and output (temporarily!) just to read the char ROM? Well, that way one can copy it to another location in RAM. One can then change (some of) it's characters (into graphics) that a game uses. Don't forget to switch back to I/O afterwards!
  75.  
  76. 3. I/O memory map
  77. ~~~~~~~~~~~~~~~~~
  78. If the 4 kB of RAM from D000 to E000 for the CPU is set to point to I/O registers (default) then its mem map is like below [4]. Also see 'The C64 Memory Map' (separate doc).
  79.  
  80. I/O mem for the CPU
  81. (in any VIC bank mode)
  82.  
  83. E000 ___________ 4 kB
  84. | I/O 2 |
  85. DF00 |___________| 3¾ kB
  86. | I/O 1 |
  87. DE00 |___________| 3½ kB
  88. | CIA 2 |
  89. DD00 |___________| 3¼ kB
  90. | CIA 1 |
  91. DC00 |___________| 3 kB
  92. | Color | CPU write
  93. | RAM |<---------- & VIC read via
  94. D800 |___________| 2 kB separate bus
  95. | SID |
  96. | registers |
  97. D400 |___________| 1 kB
  98. | VIC |
  99. | registers |<---------- CPU access
  100. D000 |___________| 0 kB to VIC regs.
  101.  
  102.  
  103. On Color RAM access. The VIC has a separate bus for accessing color RAM (color RAM is really a dedicated chip on the C64 main board [7]). It can not - and does not have to - be re-allocated by D018_hex (see chapter 'Memory types').
  104.  
  105. The registers in the VIC chip are directly written to by the CPU "via" the detour of D000 to D02E_hex. So this RAM is free to use for, say, sprite data to be read by the VIC (see 'The 47 VIC registers'). For this one must set the interrupt temporarily off (assembly: SEI) and configure register $0001 to make RAM visible from D000 to DFFF_hex (see HTML mem map [8]).
  106.  
  107. 4. The 47 VIC registers
  108. ~~~~~~~~~~~~~~~~~~~~~~~
  109. The 47 VIC registers are like "on/off" switches inside the VIC chip which are "virtually" set by the CPU via RAM locations D000 to D02E_hex (redirected by the PLA). Probably by the so-called "built-in 6 bit I/O port" mentioned in [4] (6 bit = 64 addressable registers). Therefore the registers are not mapped in a VIC RAM bank: the VIC does not read them from RAM, they are simply set by the CPU or VIC internally.
  110.  
  111. Note that this part of RAM may be used to store data to be read by the VIC (e.g. sprite data) because the CPU is re-directed away from it by the PLA.
  112.  
  113. These 47 registers are repeated every 64 bytes from D000 to D400_hex [4].
  114. ____________________________________________
  115. Address Function
  116. ____________________________________________
  117. D000 - D00F X- & Y-coordinates of sprites
  118. D010 MSBs of X coordinates
  119. D011 Control register 1
  120. D012 Raster counter
  121. D013 & D014 Light pen X & Y
  122. D015 Sprites enabled
  123. D016 Control register 2
  124. D017 Sprite Y expansion
  125. D018 Memory pointers
  126. D019 Interrupt register
  127. D01A Interrupts enabled
  128. D01B Sprite data priority
  129. D01C Sprite multicolor
  130. D01D Sprite X expansion
  131. D01E Sprite-sprite collision
  132. D01F Sprite-data collision
  133. D020 Border color
  134. D021 - D024 Background color 0 to 3
  135. D025 & D026 Sprite multicolor 0 & 1
  136. D027 - D02E Colors of the 8 sprites
  137. ___________________________________________
  138.  
  139. In registers D011 and D012 the currently drawn raster line (Y position) can be read (bit 7 of D011 is the MSB for D012). The detection of raster line 0 is used to to time (or rather: slow down) certain Assembly routines. Line 0 on a PAL machine is the top one, on NTSC its on of the lowest.
  140.  
  141.  
  142.  
  143. o=================o
  144. | C. Memory types |
  145. o=================o
  146.  
  147. Summary. A VIC mem bank is setup with D018_hex: chr. mem is set with bit 1 to 3, bitmap mem (when in BMM) is set with bit 3, scr. mem is set with bit 4 to 7. Default: chr. ROM 1000_hex, scr. RAM 400_hex. Clr. RAM always at D800_hex.
  148.  
  149. The VIC uses a several types of memory to print characters and/or bits on screen. They can be "relocated" in RAM and/or set on/off. These are the definitions of terms that are used in the various memory maps:
  150.  
  151. 1a. Character (generator) ROM
  152. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  153. A 4 kB chip that holds the default character's bitmaps. Notice the subtle difference between char ROM and char RAM (see further on)! Also see 'Memory banks' for its position.
  154.  
  155. The default character ROM contains 2 sets of 2 kB of 256 characters. Per default set 1 is accessed at 1000 to 1800_hex in shadowed RAM, the second from 1800 to 2000_hex. One usually chooses a set with Shift + C=, but it can also be done via register D018_hex (or with Petscii control character 0E_hex).
  156.  
  157. The first set contains only upper case letters (default) and the second lower- as well as upper case letters. The latter thus contains less "graphical" characters for making tables etc.
  158.  
  159. The characters from 128 to 254 are the "inverted" characters (each of the two sets contain only 128 unique characters). One switched to those with Ctrl + 9 (or by setting register 00C7_hex in RAM or by Petscii control character 12_hex). The latter probably sets an offset in the character set.
  160.  
  161. Notice that a combination of 1 set of inverted and 1 set of regular chars contains 256 characters which are fully addressable by 1 byte (8 bits make 2^8 = 256 combinations). Each position on screen is defined by 1 byte (see 'Screen RAM'), having less than 256 chars would be a waste of screen RAM.
  162.  
  163. See also Appendix "PETSCII".
  164.  
  165. 1b. Character memory/RAM (replacement for ROM)
  166. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  167. There is a subtle difference between char ROM and char RAM!
  168.  
  169. If the standard 4 kB char ROM chip is not used - because one wants to use one's own custom 2 kB character set instead - then the relative position of so called "character RAM" in the 16 kB VIC bank must be set. Usually a character set is 2 kB. Use bits 1 to 3 from D018_hex for this. You are in fact then setting bit 11 to 13 of the VIC address bus. Note: when VIC bank 0 or 2 is used then the values 010_bin and 011_bin select character ROM again. Also see chapter "Bank config examples" and the appendix "Use custom font".
  170.  
  171. 2. Screen RAM/scr mem/video matrix/video RAM (char position)
  172. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  173. A 1,000 bytes of memory in RAM in a VIC bank. When in text display mode and using bank 0 (default) then 1,000 bytes from 400_hex (1024_dec, default) onwards are used for storing the 8 bit codes of the characters on screen. Try POKE 1024,1. It should print an A in the upper left corner. One may "relocate" this memory in the VIC RAM bank with bits 4 to 7 of register D018_hex. You are in fact then setting bit 10 to 13 of the VIC address bus.
  174.  
  175. 3. Color RAM (char color)
  176. ~~~~~~~~~~~~~~~~~~~~~~~~~
  177. A 1,000 bytes (only the low nybbles = 4 bits = 16 colors) are written by the CPU to a separate RAM chip (Color RAM) via RAM locations from D800_hex (= 55296_dec) onwards to set the colors of the characters on screen. Since the the high nybbles are not relevant, and therefore do not have to be stored, Color RAM is only 512 kB.
  178.  
  179. Try POKE 55296,1. It makes the first char on screen white. One can also set the chars to reverse (00C7_hex).
  180.  
  181. The VIC has a separate bus for accessing Color RAM so there's *NO* need (re)locate it in a bank. You may even place, for instance, sprite data in D800 - DC00_hex because that sort of "regular" VIC data (like sprites, bitmaps etc.) is read via another bus than Color RAM.
  182.  
  183. 4. Bitmap
  184. ~~~~~~~~~
  185. In bitmap display mode (BMM, see separate chapter/document) the place of the 8 kB bitmap in the 16 kB VIC bank can be set with bit 3 of D018. Realize that text mode is set off then.
  186.  
  187. 5. Bank config examples
  188. ~~~~~~~~~~~~~~~~~~~~~~~
  189. Below are some examples of configurations for the 16 kB of a VIC memory bank (BMM = bitmap mode, see doc "Display modes").
  190.  
  191. When the 64 is turned on it uses bank 0 in text mode (see 'Display modes'), color RAM is not (ever) in the bank, screen RAM (char positions) is at a location not used by BASIC progs and the "shadowed" char ROM is at 1000 to 2000_hex and may thus be written to by BASIC.
  192.  
  193. Address Rel. pos.
  194. Bank 2: (hex): (kB):
  195. _________________ C000 16 <-- End of BASIC ROM for CPU
  196. | |
  197. | |
  198. | 8 kB (Bitmap?) |<--------------- May be used by VIC for bitmap?
  199. | |
  200. |_________________| A000 8 <--- End of free RAM, start of BASIC
  201. | 4 kB Character | ROM image for CPU
  202. | ROM (shadowed) |<--------------- Rerouted, RAM may be used for PRG
  203. |_________________| 9000 4
  204. | 2 kB (Chr. RAM?)|
  205. |_________________| 8800 2
  206. | 1 kB Screen RAM |<--------------- What if a PRG is in here?
  207. |_________________| 8400 1
  208. | 1 kB (Sprites?) |
  209. |_________________| 8000 0 <--- Still in free BASIC RAM
  210.  
  211. Bank 0 (= default):
  212. _________________ 4000 16
  213. | |
  214. | |
  215. | 8 kB Bitmap |<--------------- If used for bitmap in BMM or
  216. | (in BMM) | sprites then no PRG here
  217. |_________________| 2000 8
  218. | 4 kB Character |
  219. | ROM (shadowed) |<--------------- Rerouted, RAM may be used for PRG
  220. |_________________| 1000 4
  221. | 2 kB Sprites or |<--------------- If sprite data (512 kB) or char
  222. | Chr. RAM | RAM then no PRG here
  223. |_________________| 0800 2 <--- Start of free BASIC RAM
  224. | 1 kB Screen RAM |
  225. |_________________| 0400 1
  226. | 1 kB |
  227. |_________________| 0000 0
  228.  
  229. Remarks:
  230. - About screen RAM in bank 2: won't it be overwritten by a PRG? That's your own responsibility when in bank 2 mode.
  231.  
  232. - The CPU can load a bitmap into the last 8 kB of bank 2 for the VIC to read. The CPU is rerouted away from that part of RAM to the BASIC ROM if it tries to *read* RAM there. But loading things into RAM there is no problem (note: bank out BASIC ROM temporarily during the write).
  233.  
  234.  
  235.  
  236. o===============o
  237. | D. Discussion |
  238. o===============o
  239.  
  240. There are a lot of configurations of a VIC's mem bank. There are roughly three mem types that must be in a VIC RAM bank. One must do the memory management for those oneself because the machine doesn't in every configuration:
  241.  
  242. 1. Screen RAM (char pos)
  243. 2. Bitmap
  244. 3a. Character RAM
  245.  
  246. The other types do not have to be in a VIC bank. They are always managed by the Commodore itself:
  247.  
  248. 3b. Character ROM
  249. 4. Color RAM (char color, dedicated chip, dedicated bus)
  250. 5. VIC registers
  251.  
  252. When the C64 is turned on then VIC bank 0 is used and the machine is in standard text mode (see separate Part). That places screen RAM below the free RAM that programs use. Concerning character memory the VIC is rerouted by the PLA to a ROM chip. So, like one may expect, after turning the C64 on there is no problem with overlapping memory locations.
  253.  
  254. When one wants to use a custom character map things get a bit more complicated. See the appendix on using a custom character set/font. For now just realize that one way to achieve this is by simply using standard VIC bank 0. The only thing one has to do is to alter the place in which the VIC looks for character memory and to load one's own font there. On the internet binary files of fonts can be found that LOAD to (e.g.) 3800_hex in memory. Now the register D018_hex (53272_dec) must be altered to 0001_1111_bin (31_dec). This way the VIC still uses the default address space for screen RAM (char pos), but looks for the characters' description at 3800_hex and onward (use POKE 53272,31 or write Assembly program).
  255.  
  256. When one wants to load a bitmap things can get even more complicated. A bitmap must be loaded into a VIC bank. This may not to clash with the other data in the bank (screen RAM, sprites, etc.) and the computer must be set to bitmap mode (BMM, see separate Part). Returning from BMM to operate the computer might be difficult because screen RAM does not contain the characters' positions anymore. See separate document/appendix to be written about loading bitmaps.
  257.  
  258.  
  259.  
  260. o========o
  261. | E. Bug |
  262. o========o
  263.  
  264. A probably non-documented bug has been found that can corrupt data for the VIC if it uses bank 3. A Kernal stop/restore routine has been identified that writes data to FD30 - FD4F_hex inclusive (= 7,3 kB = approx. 90% into kernal ROM) [10]. The CPU is re-routed to Kernel ROM there and is not supposed to write data in RAM at that location. It does, however, overwrite data meant for the VIC. The bug occurs in the top most kilobyte of the 8 kB shadowed by the kernal ROM. So this area cannot be used to place a bitmap (which is 8 kB), but the lower part can be used for, e.g., a custom character set etc.
  265.  
  266.  
  267.  
  268. o===============o
  269. | X. References |
  270. o===============o
  271.  
  272. [1] "C64 programmer's reference guide", Commodore Business Machines and Howard W. Sams and Co. publ., First ed. (1983).
  273.  
  274. [2] "Mapping the C64", Sheldon Leemon, 'Compute! Publications Inc.', ISBN 0-942386-23-X (1984).
  275.  
  276. [3] "C64/C128 Assembly language programming" by Mark Andrews, Howard W. Sams & Co. publ., ISBN 0-672-22244-5, First ed. (1986).
  277.  
  278. [4] "The MOS 6567/6569 video controller (VIC-II) and its application in the Commodore 64" by Christian Bauer (1996):
  279. http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt
  280.  
  281. [5] Ghost byte:
  282. Discussion:
  283. https://csdb.dk/forums/?roomid=11&topicid=62074&showallposts=1
  284. Usage to disable border:
  285. https://www.youtube.com/watch?v=zUJ80eLciUU
  286. Best and shortest explanation:
  287. http://www.dbfinteractive.com/forum/index.php?topic=4477.0
  288.  
  289. [6] "The master memory map for the C64" by P. Pavelko and T. Kelly, Prentice Hall, ISBN 0-13-574351-6 (1983).
  290.  
  291. [7] Screen modes cheaper by the dozen:
  292. https://dustlayer.com/vic-ii/2013/4/26/vic-ii-for-beginners-screen-modes-cheaper-by-the-dozen
  293. By the same author:
  294. https://dustlayer.com/vic-ii/2013/4/22/when-visibility-matters
  295.  
  296. [8] HTML C64 memory map by Joe Forster:
  297. https://sta.c64.org/cbm64mem.html
  298.  
  299. [9] C64 Wiki, multi color character:
  300. https://www.c64-wiki.com/wiki/Character_set#Defining_a_multi-color_character
  301.  
  302. [10] Bug, Kernal writes in shadow RAM:
  303. https://www.lemon64.com/forum/viewtopic.php?t=74763
  304.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement