Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .-----------------------------------.
- ( P A R T 3 . T H E V I C C H I P )
- `-----------------------------------´
- general contents: pastebin.com/hmpJmurr
- 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.
- o==========o
- | Contents |
- o==========o
- A. Memory banks (reprise)
- B. RAM, ROM, CPU and VIC
- 1. RAM vs. CPU/VIC access
- 2. CPU: switch between I/O and char ROM
- 3. I/O memory map
- 4. The 47 VIC registers
- C. Memory types
- 1a. Character (generator) ROM
- 1b. Character memory/RAM (replacement for ROM)
- 2. Bitmap
- 3. Screen RAM/scr mem/video matrix/video RAM (char position)
- 4. Color RAM (char color)
- 5. Bank config examples
- D. Discussion
- E. Bug
- X. References
- -<>-<>-<>-<>-<>-<>-<>-
- o===========================o
- | A. Memory banks (reprise) |
- o===========================o
- Summary: set with DD00_hex (set write access to this register with DD02_hex).
- 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:
- Bank 0: 0000_hex (default)
- Bank 1: 4000_hex
- Bank 2: 8000_hex
- Bank 3: C000_hex
- 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.
- o==========================o
- | B. RAM, ROM, CPU and VIC |
- o==========================o
- 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".
- 1. RAM vs. CPU/VIC access
- ~~~~~~~~~~~~~~~~~~~~~~~~~
- 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.
- 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).
- 2. CPU: switch between I/O and char ROM
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 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!
- 3. I/O memory map
- ~~~~~~~~~~~~~~~~~
- 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).
- I/O mem for the CPU
- (in any VIC bank mode)
- E000 ___________ 4 kB
- | I/O 2 |
- DF00 |___________| 3¾ kB
- | I/O 1 |
- DE00 |___________| 3½ kB
- | CIA 2 |
- DD00 |___________| 3¼ kB
- | CIA 1 |
- DC00 |___________| 3 kB
- | Color | CPU write
- | RAM |<---------- & VIC read via
- D800 |___________| 2 kB separate bus
- | SID |
- | registers |
- D400 |___________| 1 kB
- | VIC |
- | registers |<---------- CPU access
- D000 |___________| 0 kB to VIC regs.
- 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').
- 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]).
- 4. The 47 VIC registers
- ~~~~~~~~~~~~~~~~~~~~~~~
- 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.
- 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.
- These 47 registers are repeated every 64 bytes from D000 to D400_hex [4].
- ____________________________________________
- Address Function
- ____________________________________________
- D000 - D00F X- & Y-coordinates of sprites
- D010 MSBs of X coordinates
- D011 Control register 1
- D012 Raster counter
- D013 & D014 Light pen X & Y
- D015 Sprites enabled
- D016 Control register 2
- D017 Sprite Y expansion
- D018 Memory pointers
- D019 Interrupt register
- D01A Interrupts enabled
- D01B Sprite data priority
- D01C Sprite multicolor
- D01D Sprite X expansion
- D01E Sprite-sprite collision
- D01F Sprite-data collision
- D020 Border color
- D021 - D024 Background color 0 to 3
- D025 & D026 Sprite multicolor 0 & 1
- D027 - D02E Colors of the 8 sprites
- ___________________________________________
- 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.
- o=================o
- | C. Memory types |
- o=================o
- 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.
- 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:
- 1a. Character (generator) ROM
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 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.
- 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).
- 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.
- 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.
- 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.
- See also Appendix "PETSCII".
- 1b. Character memory/RAM (replacement for ROM)
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- There is a subtle difference between char ROM and char RAM!
- 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".
- 2. Screen RAM/scr mem/video matrix/video RAM (char position)
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 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.
- 3. Color RAM (char color)
- ~~~~~~~~~~~~~~~~~~~~~~~~~
- 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.
- Try POKE 55296,1. It makes the first char on screen white. One can also set the chars to reverse (00C7_hex).
- 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.
- 4. Bitmap
- ~~~~~~~~~
- 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.
- 5. Bank config examples
- ~~~~~~~~~~~~~~~~~~~~~~~
- Below are some examples of configurations for the 16 kB of a VIC memory bank (BMM = bitmap mode, see doc "Display modes").
- 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.
- Address Rel. pos.
- Bank 2: (hex): (kB):
- _________________ C000 16 <-- End of BASIC ROM for CPU
- | |
- | |
- | 8 kB (Bitmap?) |<--------------- May be used by VIC for bitmap?
- | |
- |_________________| A000 8 <--- End of free RAM, start of BASIC
- | 4 kB Character | ROM image for CPU
- | ROM (shadowed) |<--------------- Rerouted, RAM may be used for PRG
- |_________________| 9000 4
- | 2 kB (Chr. RAM?)|
- |_________________| 8800 2
- | 1 kB Screen RAM |<--------------- What if a PRG is in here?
- |_________________| 8400 1
- | 1 kB (Sprites?) |
- |_________________| 8000 0 <--- Still in free BASIC RAM
- Bank 0 (= default):
- _________________ 4000 16
- | |
- | |
- | 8 kB Bitmap |<--------------- If used for bitmap in BMM or
- | (in BMM) | sprites then no PRG here
- |_________________| 2000 8
- | 4 kB Character |
- | ROM (shadowed) |<--------------- Rerouted, RAM may be used for PRG
- |_________________| 1000 4
- | 2 kB Sprites or |<--------------- If sprite data (512 kB) or char
- | Chr. RAM | RAM then no PRG here
- |_________________| 0800 2 <--- Start of free BASIC RAM
- | 1 kB Screen RAM |
- |_________________| 0400 1
- | 1 kB |
- |_________________| 0000 0
- Remarks:
- - About screen RAM in bank 2: won't it be overwritten by a PRG? That's your own responsibility when in bank 2 mode.
- - 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).
- o===============o
- | D. Discussion |
- o===============o
- 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:
- 1. Screen RAM (char pos)
- 2. Bitmap
- 3a. Character RAM
- The other types do not have to be in a VIC bank. They are always managed by the Commodore itself:
- 3b. Character ROM
- 4. Color RAM (char color, dedicated chip, dedicated bus)
- 5. VIC registers
- 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.
- 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).
- 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.
- o========o
- | E. Bug |
- o========o
- 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.
- o===============o
- | X. References |
- o===============o
- [1] "C64 programmer's reference guide", Commodore Business Machines and Howard W. Sams and Co. publ., First ed. (1983).
- [2] "Mapping the C64", Sheldon Leemon, 'Compute! Publications Inc.', ISBN 0-942386-23-X (1984).
- [3] "C64/C128 Assembly language programming" by Mark Andrews, Howard W. Sams & Co. publ., ISBN 0-672-22244-5, First ed. (1986).
- [4] "The MOS 6567/6569 video controller (VIC-II) and its application in the Commodore 64" by Christian Bauer (1996):
- http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt
- [5] Ghost byte:
- Discussion:
- https://csdb.dk/forums/?roomid=11&topicid=62074&showallposts=1
- Usage to disable border:
- https://www.youtube.com/watch?v=zUJ80eLciUU
- Best and shortest explanation:
- http://www.dbfinteractive.com/forum/index.php?topic=4477.0
- [6] "The master memory map for the C64" by P. Pavelko and T. Kelly, Prentice Hall, ISBN 0-13-574351-6 (1983).
- [7] Screen modes cheaper by the dozen:
- https://dustlayer.com/vic-ii/2013/4/26/vic-ii-for-beginners-screen-modes-cheaper-by-the-dozen
- By the same author:
- https://dustlayer.com/vic-ii/2013/4/22/when-visibility-matters
- [8] HTML C64 memory map by Joe Forster:
- https://sta.c64.org/cbm64mem.html
- [9] C64 Wiki, multi color character:
- https://www.c64-wiki.com/wiki/Character_set#Defining_a_multi-color_character
- [10] Bug, Kernal writes in shadow RAM:
- https://www.lemon64.com/forum/viewtopic.php?t=74763
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement