C64 talk at 25C3
By Spiro Trikaliotis on Tuesday, December 16 2008, 19:14 - Commodore64 - Permalink
There is an article by Michael Steil which will be printed in the Congress Proceedings of the 25th Chaos Communication Congress 2008 (25C3). It accompanies his talk "The Ultimate Commodore 64 Talk - Everything about the C64 in 64 Minutes". I take this opportunity to comment on some of the statements there, reviving this blog.
Note that you will have to read the article in order to understand most of my comments.
Look and Feel
The handling of the "extended" 80 character lines has a bug in kernel revisions -02 and before. If you do this on the very last row on the screen, go to the 80th position, enter a character and go back ("DEL"), the C64 will behave erratically.
This will not happen on the -03 KERNAL.
Board
It is arguable if the ROMs can be considered custom chip designs. They are standard chips, but they have programmed contents. This was the common way to have ROMs in the days back then.
And: Not all non-RAM chips are custom chips, only all non-RAM chips mentioned in that section. There are many additional standard TTL chips available on the board of a C64.
Address Space
$8000-$9FFF is special, too, as it can be used specifically for external cartridges. $A000-$BFFF can be used for external cartridges, too.
6502 CPU
Unlike other CPUs, the 6502 does not have a set of general purpose registers.
Nor does the 6800, nor does the 8080 or the Z80. At that time, it was common to have specialised registers. Even the 8086 followed that rule - to a lesser extent, admittedly.
The B flag (break) does not actually exist in the processor status register. It is only available in the status register that is written on the stack on a hardware- or software-interrupt.
The 8×8 opcode matrix is somewhat logical ..., but there is no easy rule to construct the opcode table.
What is not easy in your point of view? It is not very hard to find a system for the encoding. Admittedly, there are exceptions, but most - even modern - encodings show exceptions. If you look at Lance A. Leventhal, "6502 Assembly Language Programming", you can see a start of this system, as the tables show the opcodes with the appropriate decoding of the addressing modes. This is a good starting point for doing more "opcode consolidation". In the end, you find out that the encoding is more regular than many people believe. Interestingly, you can even derive the meaning of some illegal opcodes when looking at this table.
Instruction Set
and SEC/SBC is a regular subtraction, because of the one’s complement logic
No, it is not because of the one's complement logic, it is because you want to work with two's complement logic.
Addressing Modes
Here, you are mixing notation (# for immediate, ...) with the actual implementation.
Zero-Page-X-indexed, Zero-Page-X-indexed-indirect: All of the three addressing modes wrap around ($FE, $FF, $00). However, it is unclear if this is to be regarded as an error or not. Many - but not all - people believe that the wrap-around is not ok with index-indirect. The 65C02 handles this differently.
Personally, I think that with or without wrap-around is ok, but it should be consistent. That is, the actual implementation of the 6502 is right (one of the two possible solutions), while the implementation of the 65C02 is wrong (no wrap-around with indexed-indirect, but wrap-around with zero-page-x-indexed).
Control Transfer
BRK causes a software interrupt and behaves the same as a hardware interrupt, except that it sets the B flag on the stack to 1 (a hardware interrupt sets it to 0).
Well, there is no B flag on the stack. What you mean is the "B-flag of the status register as it is stored on the stack."
NMIs do not behave the same as IRQs. IRQs are level sensitive, NMIs are edge triggered.
Flags and Branches
while the V flag can only be cleared (CLV)
Here is a difference between the 6502 and the 6510. On the 6502, the V flag can also be set via hardware (pin S.O.). This feature is used in the IEC 5,25" floppy drives.
Branches encode an 8 bit relative offset and can therefore reach code in the area of +127 and -128.
Yes, but the range is measured from the 2nd byte of the instruction.
Common tricks
An elegant way to store a flag is to have it in bit #7 of a zero page address. While a load/store combination has to be used to set the flag, ...
No, are not forced to use LD?/ST?. You can also use SEC; ROR or similar.
Bugs and Quirks
When in decimal mode, the negative flag reflects the original binary result, not the effective decimal result.
Why is this a bug? Is it anywhere documented that the N flag should be set according to the corrected value? The N flag does not make much sense to indicate "negative" in BCD mode, does it?
LDX #$07 LDA $D019,X will first read from $D019, discard the result, and then read from $D020. On the C64, this read form $D019 would ACK all pending VIC interrupts, while it is only supposed to read the border color ($D020).
Is this a quirk of the CPU or of the VIC? From today's perspective, it would be more of a quirk of the VIC, that resets its state just by reading it. But you are right, when C64 came out, this was state of the art for peripheral chips. (Others like the CIA behave the same)
On a C64, this can be seen when incrementing the screen border color at a defined area of the screen, as every write to the register will cause a tiny gray dot on the screen.
Does this dot occur with all variants of the VIC? AFAIR, mine (C=64 from 1983) does not show this behaviour.
BASIC
The Commodore 64 got the exact same version, except that it runs at a different memory address ($A000-$BFFF).
Mostly. The USR vector ($00-$02) was relocated, as well as some small patches applied. For example $E447 contains a vector to only print an error if bit 7 of the error code is set. On the VIC-20, this pointer points to the error out routine. Furthermore, there are different versions of the VIC-20 BASIC available. For example, $E1B8 differs between C64, VIC-20 -2 and -6 (-7) ROM (the ROM versions are 901486-02, 901486-06 and 901486-07. Of course, they denote the KERNAL, as the upper half of BASIC is in the $E000-$FFFF area.)
KERNAL
Devices 4 to 15 will be directed to the IEC bus.
To be more precise, all devices >= 4 will be directed to the IEC bus. AS the IEC bus uses the upper 2 bits for the "mode" (TALK, LISTEN, OPEN, CLOSE), and the device 31 is special (*UN*LISTEN, *UN*TALK), all devices 4-30 can be used for IEC devices. If one uses the "special" IEC routines, even IEC devices 0-3 can be accessed.
6526 CIA
Since the keyboard consists of 64 keys (plus SHIFT LOCK, which is parallel to the left SHIFT key, and RESTORE, which is directly connected to the CPU’s NMI line), ...
The RESTORE key is not directly connected to the NMI line; rather, pressing NMI activates a mono-flop that directly affects the NMI line.
KERNAL uses CIA 1 for the 50 Hz system timer, ...
The C64 uses a 60 Hz system timer, regardless of NTSC or PAL.
6567/6569 VIC
Character Mode
The foreground color of the characters can be changed by writing the color numbers into the Color RAM, which is located at $D800-$DBFF. There is one byte per character, but only the lower 4 bits are actually preserved by Color RAM.
To be more precise: Only the lower nibble (4 bits) actually *exists* as Color RAM.
Memory Layout
If the VIC is set to banks $0000 or $8000, then the two built-in character sets shadow RAM in the area of $1000-$1FFF.
No, there is no shadow RAM. The ROM is just mapped into the address space of the VIC.
Memory Configuration
The C64 supports another ROM bank at $8000-$9FFF, which can only be serviced by an external cartridge connected to the expansion port.
There are more configurations than that. The C64 also support only a ROM at $A000-$BFFF, or a 16 KB ROM from $8000-$BFFF.
IEC Bus
If the computer raises ATN, every device on the bus listens for the 4 bit device number and compares it with its own.
More precisely, the computer sends out 8 bytes, the primary address, and (optionally) the secondary address. In the primary address, there is the device address encoded (lower 5 bits, not 4), and the command to use. LISTEN ($20), TALK ($40). Additionally, $60 is used to send the secondary address to a LISTEN or TALK, while $F0 is used to send the secondary address on a OPEN. $E0 is used to send the secondary address on a CLOSE. In the case of OPEN and CLOSE, the primary address is send as a LISTEN ($20).