Note: main 'documentation' and description (including I/O memory layout, additional information, details, etc) page can be found here.
Click here to return to the disassembly list.
8000 | At offset 4: this bytes tells the number of Kbytes to be checked by the ROM checksum routine. I don't know the purpose of the other bytes though. |
8008 | Every ROM images begins with this "identification" string. This one is also used to compare with the searched ones by the ROM scanning routine. |
8015 | Every ROMs contain a "directory" with the "applications" can be found (I guess). Besides the names, I know only maybe three bytes of the six (prefixed every name): the size of that entry, zero for no more entries. Two other bytes (last two bytes - a word - before the name itself) may encode the entry point of the given software. I don't know the purpose of other bytes. |
8038 | It seems to be the entry point of "MONITOR.MON". |
804C | It seems to be the entry point of "COMMAND.CMD". |
8277 | Interesting, though I don't know the purpose of the given ZP locations. It seems, $FD00, $FD80, $FE00, $FE80 are used some kind of MMU purpose, based on value CMP'd with constants which suggests memory is devided into parts (high byte only): $00-$3F, $40-$7F, $80-$BF, $C0-$F7, $F8-$FF. |
82CB | The 'ScanROMs' routine uses this table to write values to $FF00 to check for ROMs. |
82D3 | This routine seems to scan ROMs, searching for the "Commodore LCD" string. This is done by using register at $FF00 which seems to tell the memory mapping at CPU address $4000. So I think $FF00 tells what is mapped to $4000. |
82F3 | $4004 is the paged-in ROM, where the id string would be ($FF00 controls what can you see from $4000), it's compared with the kernal's image's id string ("Commodore LCD"). |
8307 | Hmm, it seems to be a bug for me, it should be 'pla', otherwise X is messed up to be used to address byte on the stack. |
832F | Push Y onto the stack. Write "ROMSUM ...." text, then take the value from the stack, "covert" into an ASCII number (ORA), and print it, followed by the " INSTALLED" text. |
8367 | Creates checksum on ROMs. Input: A = value of $FF00 reg to start at X = number of Kbytes to check Output: X/A = 16 bit checksum (simple addition, X is the high byte) |
84FA | This seems to be the "shutdown" function or part of it: "state" should be saved (which is checked on next reset to see it was a clean shutdown) and then it used /POWEROFF line to actually switch the power off (the RAM is still powered at least on CLCD!) |
852A | Release /POWERON signal, machine will switch off. Run the endless BRA if it needs some cycle to happen or some kind of odd problem makes it impossible to power off actually. |
8534 | ************************************* Start of the real RESET routine after MMU set up. ************************************* |
8535 | As soon as possible set /POWERON signal to low (low-active signal) configure DDR bit as well. |
8653 | Funny :) |
86A0 | Set MEMBOT vector to $0FFF |
86A9 | D9/DA shows here the tested amount of RAM to be found OK, starts from zero |
86AE | This seems to test the zero page memory. |
86C2 | Test rest of the RAM, using the kernal window to page in the testable area. |
8763 | Inits VIAs, ACIA and possible other stuffs with JSRing routines. |
942B | Jumps (by a jump table) to the right routine to dump the "virtual 1541" directory listing tail/head or the content itself, IMHO. |
9437 | This (and other part later) fragment seems to be the usual directory listing produced by an 1541 and compatible drives. The text says "virtual 1541" thus it seems CLCD handles something (possible programs in ROM and/or RAM disk) as it would be a "real" 1541 drive for the user. |
9457 | This dumps the directory listing head, with the "virtual 1541" text. |
9488 | This dumps the directory listing tail, with the "block used" text. |
94A8 | Afaik this dumps a row of the directory listing, about a file, you can even see the "PRG", "SEQ" stuffs appended. |
AF25 | This op puts the chr into the video RAM. |
AFCB | This fragments prints spaces (ie; clear) on screen. |
B0D5 | Just guessing: this table is a byte then a jump address. Maybe it's some kind of terminal escape sequence table or such, at least pointed routines are often touch cursor position zp locs, etc. |
B228 | This routine is called by RESET routine, with carry set. It seems it's the only part where locations $FF80 - $FF83 are written. $FF80-$FF83 is the write-only registers of the LCD controller. It's called first with carry set from $87B5, then called second with carry clear from $B204 |
B39A | My guess: these tables help to decode the keyboard matrix read into actual characters. More tables, because of shifted, etc state. |
B5E4 | It seems, CLCD's kbd is read through VIA's SR ... Interesting. AFAIK, port B of VIA is mainly used by IEC bus, but bit 0 for example seems to trigger (0->1) the keyboard "controller" to provide bits through serial transfer in SR-in. |
BB7F | Maybe typo? :) Or it's only my English ... "SAVEING" ... |
BC96 | This routine seems to be used to send out a byte on the IEC bus. |
BE1A | Reset VIA1 port-B bit#4. |
BE23 | Set VIA1 port-B bit#4. |
BE2C | Reset VIA1 port-B bit#5. |
BE35 | Set VIA1 port-B bit#5. |
BE3E | Waiting for change on port B of VIA1. The high two bits are inverted, and bit 7 moved to carry. Maybe used for CLK/DAT sense on IEC bus? |
BF4F | Updates time-of-day (TOD) clock. Should be called at 60Hz frequency. |
BF7E | this TOD stuff was easy, but I have no idea what the rest is ... |
BFE4 | Waits for multiple of 1/60 seconds. Interrupt must be enabled, since it used TOD's 1/60 val. Input: X = number of 1/60 seconds. |
C352 | This quite odd routine reads (4 bit) data from the RTC chip. Odd, because port A of VIA#2 is configured as _output_ otherwise ... $40 is for AW (address write) signal for the RTC. Input: Y = RTC register number Output: A = read value |
C669 | It seems the following routines will be copied from $0338 to the RAM and used from there. Guessed purpose: the ROM itself is not always paged in, so we need them to be in RAM. Note about the "dummy writes", those (maybe ...) used to set/reset flip-flops to switch on/off mapping of various parts of the memories, but dunno what exactly :( ---------------------------------------------------- My best guess so far: dummy writes to ... * $FA00: enables lower parts of KERNAL to be "seen" * $FA80: disables the above but enable ROM mapped from $4000 to be seen * $FB00: disables all mapped, but the "high area" "High area" is the end of the KERNAL & some I/O registers from at $FA00 (or probably from $F800?) and needs to be always (?) seen. ---------------------------------------------------- This will be $0338 in RAM. It's even used by BASIC for example, the guessed purpose: allow to use RAM for BASIC even at an area where there is BASIC ROM paged in (from $4000) during its execution. $033C will be the RAM zp loc of LDA (zp),Y op. |
C672 | This will be $0341 in RAM. $0345 will be the RAM zp loc of STA (zp),Y op. This routine is also used by BASIC. It seems ZP loc of STA is modified in RAM. |
C67B | This will be $034A in RAM. $034E will be the RAM zp loc of LDA (zp),Y op. |
C684 | This will be $0353 in RAM. $0357 will be the RAM zp loc of LDA (zp),Y op. |
C68D | This will be $035C in RAM. $0360 will be the RAM zp loc of STA (zp),Y op. |
C6A1 | This copies the routines from $C669 into the RAM from $338. |
CAC3 | Prints a hex word given at ZP locs and then a space. Input: $CC = high byte, $CB = low byte |
CAC7 | Prints a hex word and then a space. Input: X = high byte, A = low byte |
CAD8 | Byte as hex print function, prints byte in A as hex number. X is saved to $39D and loaded back then. |
CAE8 | Byte to hex converter Input: A = byte Output: A = high nibble hex ASCII digit, X = low nibble hex ASCII digit |
CAF2 | Nibble to hex converter Input: A = byte (low nibble is used only) Output: A = hex ASCII digit |
CC1D | Prints PC as hex word, and registers? |
CE12 | Addressing mode characters for the monitor/(dis)assembler? |
F700 | This is the character set. It contains 6 bytes for each characters, and the bitmap is "rotated", ie the on screen the resolution is 6*8, not 8*6. Character set area is from $F700 to $F9FF, for 128 characters (codes > 128 would mean inverse text probably?). The area from the point of view of the CPU also contains the VIA registers, it seems. |
FA07 | The actual RESET routine, pointed by the RESET hardware vector. Notice the usage $FA00, seems to be a dummy write (no actual LDA before it, etc). Maybe it's just for enabling the lower part of the KERNAL to be mapped, so we can jump there, or something like that. |
FA0E | The IRQ routine, pointed by the IRQ hardware vector. Note about the usage of $FC00 and $FA80 locations, seems to be dummy write, as with the RESET routine, but different addresses ... |
FA31 | Default IRQ handler, where IRQ RAM vector ($314) points to by default. |
FA7E | An interesting example for addresses like $FA80 are write only registers, but on read, normal ROM content is read as opcodes, as $FA80 here is inside and opcode itself. |
FA8D | Contains $FA87 by default. |
FA90 | Default values of "RAM vectors" copied to $314 into the RAM. The "missing" vector in the gap seems to be "monitor" entry (according to C128's ROM) but points to RTS in CLCD. The the last two vectors are unknown, not exists on C128. |
FB51 | This stuff prints (zero terminated) string after the JSR to the screen (by using the return address from the stack). The multiple entry points seems to be about the fact that "kernal messages control byte" should be checked or not, and such ... |
FB92 | Code from here clearly shows many examples for the need to "dummy write" some "MMU registers" - $FA00 - (maybe only a flip-flop) before jumping to lower address in the KERNAL ROM. Usually there is even an operation like that after the call - $FA80. My guess: the top of the kernal is always (?) mapped into the CPU address space, but lower addresses are not; so you need to "page in" first. However I don't know _exactly_ what happens with $FA00/$FA80 (set/reset a flip-flop, but what memory region is affected then exactly). |
FDFC | SCREEN. Fetch number of screen rows and columns. On CLCD the screen's resolution is 80*16 chars. |
FE01 | PLOT. Save or restore cursor position. Input: Carry: 0 = Restore from input, 1 = Save to output; X = Cursor column (if Carry = 0); Y = Cursor row (if Carry = 0). Output: X = Cursor column (if Carry = 1); Y = Cursor row (if Carry = 1). Used registers: X, Y. |
FE0C | ?? Might be IOBASE. Fetch CIA #1 base address. Input: - Output: X/Y = CIA #1 base address . Used registers: X, Y. Though CLCD contains VIA, not CIA, but fair enough :) $F800 seems to be OK, as this is addr of VIA-1, indeed. It also helped me to be sure that F800 is really start of the VIA regs. |
FE11 | Seems to be an unused area. |
FF81 | ------------------------------------------------------------------------------ Begin of the table of the kernal vectors (well, compared with "standard KERNAL entries" on Commodore 64, I can just guess if there is not so much difference on the CLCD) ------------------------------------------------------------------------------ |
FFA2 | The following entry (three bytes) would be "SETTMO. Unknown. (Set serial bus timeout.)" according to the C64 KERNAL, however on CLCD it seems to be unused. |
FFB4 | ??TALK. Send TALK command to serial bus. Input: A = Device number. |
FFB7 | ??READST. Fetch status of current input/output device, value of ST variable. (For RS232, status is cleared.) Output: A = Device status. |
FFBA | ??SETLFS. Set file parameters. Input: A = Logical number; X = Device number; Y = Secondary address. |
FFBD | SETNAM. Set file name parameters. Input: A = File name length; X/Y = Pointer to file name. |
FFC0 | "OPEN". Must call SETLFS and SETNAM beforehands. RAMVEC_OPEN points to $FCE7 in RAM by default. |
FFD5 | ??LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.) Input: A: 0 = Load, 1-255 = Verify; X/Y = Load address (if secondary address = 0). Output: Carry: 0 = No errors, 1 = Error; A = KERNAL error code (if Carry = 1); X/Y = Address of last byte loaded/verified (if Carry = 0). Used registers: A, X, Y. Real address: $F49E. |
FFD8 | ??SAVE. Save file. (Must call SETLFS and SETNAM beforehands.) Input: A = Address of zero page register holding start address of memory area to save; X/Y = End address of memory area plus 1. Output: Carry: 0 = No errors, 1 = Error; A = KERNAL error code (if Carry = 1). Used registers: A, X, Y. Real address: $F5DD. |
FFDB | ??SETTIM. Set Time of Day, at memory address $0390-$0392. Input: A/X/Y = New TOD value. Output: – Used registers: – Real address: $F6E4. |
FFDE | ??RDTIM. read Time of Day, at memory address $0390-$0392. Input: – Output: A/X/Y = Current TOD value. Used registers: A, X, Y. |
FFE1 | ??STOP. Query Stop key indicator, at memory address $0091; if pressed, call CLRCHN and clear keyboard buffer. Input: – Output: Zero: 0 = Not pressed, 1 = Pressed; Carry: 1 = Pressed. Used registers: A, X. Vector in RAM ($328) seems to point to $FDC2 |
FFE4 | GETIN. Read byte from default input. (If not keyboard, must call OPEN and CHKIN beforehands.) Input: – Output: A = Byte read. Used registers: A, X, Y. |
FFEA | ??Might be UDTIM. Update Time of Day, at memory address $0390-$0392, and Stop key indicator |
FFED | SCREEN. Fetch number of screen rows and columns. |
FFF0 | PLOT. Save or restore cursor position. Input: Carry: 0 = Restore from input, 1 = Save to output; X = Cursor column (if Carry = 0); Y = Cursor row (if Carry = 0). Output: X = Cursor column (if Carry = 1); Y = Cursor row (if Carry = 1). Used registers: X, Y. |
FFF3 | ?? Might be IOBASE. Fetch CIA #1 base address. Input: - Output: X/Y = CIA #1 base address . Used registers: X, Y. |
FFF6 | Four unused bytes, this is the same as with C64. |
FFFA | The 65xx hardware vectors (NMI, RESET, IRQ). |
FFFC | This is the RESET vector. |