First of all, I must apologize for not writing for so long. I was short on time, thus, I was not able to do this before. I am trying to write more articles as time permits. This is the first one of more to come.

Starting execution at a memory address

The go (g) command is the easiest of the ones I will describe in this part of the sequel. It is used when you want to execute your own program. its help text looks like follows:

(C:$e5d4) ? g

Syntax: goto <address>
Abbreviation: g

Change the PC to ADDRESS and continue execution

(C:$e5d4)

It's easy, isn't it? You might remember the good old "SYS 64738" command which seems to reset your C64. You can use this command from the BASIC command line, or you can enter it in the monitor.

Assume you have some program loading which does not return to the BASIC command-line. To reset it, you can do the following: Enter the monitor (Alt+M in the Windows version of VICE), and enter:

(C:$e5d4) ? g +64738

The monitor will immediately exit, and you will see the left and rights borders of the C64 screen getting smaller for some seconds. Afterwards, your emulated C64 will look as if it was just started.

Of course, you could also have used the (virtual) RESET button of VICE to reset the machine (Alt+R on the Windows version of VICE), but this was not the point of this blog entry.

You might have noticed the "+" in the command-line above. This tells the VICE monitor that the number afterwards is written in decimal, not in hexadecimal. Normally, all numbers are given in hexadecimal, unless specified otherwise. The "+" specifies otherwise, in this case, decimal.

Thus, you could have achieved the same effect with the command

(C:$e5d4) ? g fce2

as $FCE2 is the same 64738. You are not convinced? You can let the monitor do the conversion for you:

(C:$e5cf) ~ +64738
+64738
$fce2
0176342
11111100 11100010
(C:$e5cf)

Here, the monitor outputs the number you have given (64738 in decimal) into all number systems it knows about: Decimal (+), hexadecimal ($), octal, and binary. The key to this conversion is the command ").

Of course, if I convert the hexadecimal value FCE2, I get the same output:

(C:$e5cf) ~ fce2
+64738
$fce2
0176342
11111100 11100010
(C:$e5cf)

Note that the command, the monitor tells you how to specify decimal numbers: With the plus (+) sign.

Modifying registers

Now, we know how to start a program at a given location. Sometimes, you also want to be able to change some register values before this. This can be done with the registers command. Its online help is as follows:

(C:$fd83) ? r

Syntax: registers <reg_name> = <number> [, <reg_name> = <number>*]
Abbreviation: r

Assign respective registers.  With no parameters, display register
values.

(C:$fd83)

So, we have two ways to use it: "registers" without any parameter just outputs the current register values:

(C:$fd83) registers
  ADDR AC XR YR SP 00 01 NV-BDIZC LIN CYC
.;fd83 ff ff fe fd 2f 37 10100101 000 000
(C:$fd83)

So, we see that currently, the Accu is $FF, X is $FF, Y is $FE, the stack pointer (SP) is $FD, and the flags. The VICE monitor also outputs additional information. I will skip these additional values "00", "01", "LIN" and "CYC", which are not present with most other monitors, here.

Now, assume we want to change the value of a register. For this, we can use the registers command and assign a value to the register we want. For example, we can change the value of the accu (AC) to $46 by issuing

(C:$fd83) r A=46

That's all! You can verify that the change took effect by having a look at the registers again:

(C:$fd83) r
  ADDR AC XR YR SP 00 01 NV-BDIZC LIN CYC
.;fd83 46 ff fe fd 2f 37 10100101 000 000
(C:$fd83)

You see that AC has changed its value.

Oh... Now, you are surprised? You used the name "A" in the command, but the output is "AC"? Yes, this is an inconsistency, and I do not like it, either. But that's the way it is currently.

Even worse, it is not always obvious which name to use to assign a register a value. You must use other names that are output. As I am searching for the names myself quite a lot (by having a look into the VICE sources!), I made a list for you:

  • the accu (AC) is "A"
  • the X register (XR) is "X"
  • the Y register (YR) is "Y"
  • the program counter (ADDR) is "PC"
  • the stack pointer (SP) is "SP"

You see, only the stack pointer has the abbreviation that is output by the registers command itself! Furthermore, notice that you can not change the status registers (at least, not that I know of - and I have looked at the sources)

Of course, with this info, it is easy to mimic the effect of "g fce2":

(C:$fd83) r PC=fce2
(C:$fd83) r
  ADDR AC XR YR SP 00 01 NV-BDIZC LIN CYC
.;fce2 46 ff fe fd 2f 37 10100101 000 000
(C:$fd83) x

As with "g fce2", the C64 is reset with this sequence of commands.

Ok, can we do something more interesting than resetting the machine with these commands? Yes, we can. You might know the following BASIC command sequence to output something to a given position on the screen:

POKE 214,Y:POKE 211,X:SYS 58732

We can mimic this behaviour without problems. First, let's have a look into the routine at +58732:

(C:$e595) d +58732
.C:e56c   A6 D6      LDX $D6
.C:e56e   A5 D3      LDA $D3
.C:e570   B4 D9      LDY $D9,X
.C:e572   30 08      BMI $E57C
.C:e574   18         CLC
.C:e575   69 28      ADC #$28
.C:e577   85 D3      STA $D3
.C:e579   CA         DEX

Wow... It directly performs some calculations. While the routine is not very hard to understand, it is out of the scope of this blog entry here. Of course, we could write the Y position into +214 ($D6) and the X position into +211 ($D3), but this way, I would not be able to tell you how to use the registers command. Instead, let's have a look into the KERNAL routine (PLOT, $FFF0) which calls our routine at $E56C (58732) at some time:

(C:$0019) d fff0
.C:fff0   4C 0A E5   JMP $E50A

... Ok, it jumps directly to $E50A, so let's have a look there:

(C:$fff3) d e50a
.C:e50a   B0 07      BCS $E513
.C:e50c   86 D6      STX $D6
.C:e50e   84 D3      STY $D3
.C:e510   20 6C E5   JSR $E56C
.C:e513   A6 D6      LDX $D6
.C:e515   A4 D3      LDY $D3
.C:e517   60         RTS

What is the BCS for? The PLOT kernal routine can be used for two purposes: If the Carry flag is set, it reads out the current position (and the X position is given in Y, and the Y position in X (sic!)). If the carry flag is not set, the current position is changed to the position given by the X register and the Y register. The BCS in $E50A distinguished between both uses. It is a scheme found rather commonly in the Commodore KERNAL.

As I already told, I do not know how to clear the carry flag. Thus, to be sure, we will just jump to $E50C with the X and the Y register properly set:

(C:$e534) r X=5
(C:$e534) r Y=7
(C:$e534) g e50c

But what is this? When you execute these lines, your C64 will NOT position the cursor to line 5, column 7. Instead, it output a screen that looks like you have pressed Run/STOP+Restore:

Why does this happen? Don't the commands work as I told you?

I can assure you, they work as advertised. The problem is another one, we will try to find it out and the next part of this sequel...