The VICE monitor - part I: Starting and showing memory contents
By Spiro Trikaliotis on Sunday, March 25 2007, 09:41 - VICE - Permalink
From time to time, I read questions about the monitor of VICE. It seems its usage is not self-explanatory. Thus, I will try to start a series of articles where I explain the usage of the monitor of VICE. This is part I of this series, which handles starting the monitor and using it to statically examine the state of the computer.
What is a monitor?
What is a monitor all about? Why do I need one?
Most probably, if you ask this question, you will never need to use the machine language monitor, often referred to as monitor. Nevertheless, I will try to explain it to you. A computer like the C64, but also any modern PC, consists of some parts. Among them are the processor (nowadays, it is most often referred to as Central processing unit, "CPU"), memory, and I/O interfaces. In case of the Commodore 64, the processor is a MOS Technology 6510, a variant of the very popular MOS Technology 6502. This processor contains some registers. These are just some very small data area where the processor essentially can do simple calculations.
The number of registers is very limited. In the case of the 6502/6510, the processor has the following "visible" registers:
- one 8 bit accumulator A
- two 8 bit index registers X and Y
- one 8 bit status register P
- one 8 bit stack pointer register S, most often referred to as SP, and
- one 16 bit program counter PC.
I assume you are familiar with all this. If not, I recommend you look out for a tutorial on 6502 programming.
The memory of the computer is the place where a program is stored, as well as all of the data is written while the program is running. In case of the Commodore 64, the memory consists of:
- 64 KiB of RAM,
- 8 KiB of BASIC ROM
- 8 KiB of KERNAL ROM
- 4 KiB of character ROM which tells the graphics controller how each character on the screen should look like,
- 1 KiB of color RAM (to be more precise, this memory only consists of 1024 nibbles),
- and some more data areas which I don't want to count here.
Additionally to this, the computer also has some I/O areas which tell parts of the system, like the graphics controller VIC-II, the sound controller SID, or the CIA what they should do. In effect, the I/O devices are the parts of the system that let the user communicate with the system.
Now, to come back to the question: What is a monitor? A machine language monitor program allows the user to look "into" the computer. The user can examine the memory, the processor and the I/O of the computer in order to find out what is happening inside of the machine.
Starting the VICE monitor
Obviously, a monitor is a very helpful piece of software. Now, how do you start it?
I assume you already have VICE running on your system. I tested all of my steps with the Windows version of VICE, WinVICE version 1.21. Nevertheless, the steps can be used with the other ports and other versions of VICE, too. To be more precise, I will always use x64, the Commodore 64 emulator part of VICE.
After starting VICE, you can enter the VICE monitor via File/Monitor, or by pressing Alt+M. Note that the key combination and the menu names can vary on the different versions of VICE. After starting it, a window will open with an output like follows:
** Monitor 000 000 (C:$e5d4)
Note, however, that the exact numbers shown can vary on your machine.
The first line ("** Monitor 000 000") just shows that you just entered the monitor. Additionally, two values are given, which I will not comment now. This will be done in some later part of this series.
The next line (C:$e5d4) is the prompt. That is, the monitor asks you to tell it what you want. In this prompt, there is some information: The "C:" part tells you that you just entered the monitor for the bc/bomputer. Other options would be 8: and 9: for drive 8: and drive 9:, the floppy drives. The value $e5d4 tells you that the emulator would execute the command at address $e5d4 in the computer (C:) as the next command.
In this part of this series on the VICE monitor, we do not want to have a look into the execution. Instead, we just want to examine the contents of the computer. Thus, the above information is not interesting for us (yet).
Getting help on commands
Now, the monitor wants you to tell it what you want to do. It wants to get some command from you. Although you will remember many commands you use frequently, no one is able to remember all of these commands. Thus, you can ask the computer for some help to memory the commands. The command to ask for the list of all commands is called "help". Just enter it (and enter), and you will get the following output:
(C:$e5d4) help Available commands are: ~ > @ a add_label (al) bank bload (bl) block_read (br) break bsave (bs) block_write (bw) cd command compare (c) condition (cond) cpu disass (d) delete (del) delete_label (dl) device (dev) disable dump enable exit (x) fill (f) goto (g) help (?) hunt (h) i ignore io keybuf load (l) load_labels (ll) mem (m) memchar (mc) move (t) memsprite (ms) next (n) playback (pb) print (p) quit radix (rad) record (rec) registers (r) return (ret) save (s) save_labels (sl) screen (sc) show_labels (shl) sidefx (sfx) step (z) stop trace (tr) until (un) undump watch (w) (C:$e5d4)
This is the list of all available commands. As you can see, some commands just consist of some characters (~, >, @), while others consist of a full name (i.e., save_labels). With many commands, you also have a short form in paranthesis after the full name. This is just for convenience, as you won't want to always write such long names into the window.
If you want to get more precise help, you can use "help" plus the name of the command. For example, to get help on the command "stop", enter "help stop" + enter.
Leaving the VICE monitor
An important command for every command-line based utility like the VICE monitor is the command to exit. As you might have seen in the help output, there is a command exit with abbreviation x:
(C:$e5d4) help exit Syntax: exit Abbreviation: x Leave the monitor and return to execution. (C:$e5d4)
Thus, if you want to quit the VICE monitor, just enter exit (or just a x) and press enter.
Display memory regions
We want to have a look at the memory. For this, the command "mem" (abbreviation: m) can be used. First of all, let's have a more specific look at the help output on mem:
(C:$e5d4) help mem Syntax: mem [<data_type>] [<address_opt_range>] Abbreviation: m Display the contents of memory. If no datatype is given, the default is used. If only one address is specified, the length of data displayed is based on the datatype. If no addresses are given, the 'dot' address is used. (C:$e5d4)
Note that the same output would be given if you had asked for "help m".
The most important part here seems to be the syntax. It tells you that you have to enter "mem" in order to tell the machine that you want to output memory (of course, you can also use the abbreviation "m"). After this, there are two parts which are optional, that is, you can also ommit them. You see that these are optional because they are surrounded by brackets ([ and ]).
The first optional argument is the data_type. The second optional argument is address_opt_range.
Let's start with the second optional argument, address_opt_range. In fact, this argument consists of two arguments: One address, and another, optional address.
Let's show it with the help of some examples:
mem a000 a0ff: This command outputs the memory from address $A000 up to $A0FF. Note: Many monitor program show the memory starting with the first address and ending at the second address, excluding the second address itself. The VICE monitor behaves differently here: It outputs from the first address to the second address, including the second address:
(C:$e5d4) m a000 a100
>C:a000 94 e3 7b e3 43 42 4d 42 41 53 49 43 30 a8 41 a7 ..{.CBMBASIC0.A.
>C:a010 1d ad f7 a8 a4 ab be ab 80 b0 05 ac a4 a9 9f a8 ................
>C:a020 70 a8 27 a9 1c a8 82 a8 d1 a8 3a a9 2e a8 4a a9 p.'.......:...J.
>C:a030 2c b8 67 e1 55 e1 64 e1 b2 b3 23 b8 7f aa 9f aa ,.g.U.d...#.....
>C:a040 56 a8 9b a6 5d a6 85 aa 29 e1 bd e1 c6 e1 7a ab V...]...).....z.
>C:a050 41 a6 39 bc cc bc 58 bc 10 03 7d b3 9e b3 71 bf A.9...X...}...q.
>C:a060 97 e0 ea b9 ed bf 64 e2 6b e2 b4 e2 0e e3 0d b8 ......d.k.......
>C:a070 7c b7 65 b4 ad b7 8b b7 ec b6 00 b7 2c b7 37 b7 |.e.........,.7.
>C:a080 79 69 b8 79 52 b8 7b 2a ba 7b 11 bb 7f 7a bf 50 yi.yR.{*.{...z.P
>C:a090 e8 af 46 e5 af 7d b3 bf 5a d3 ae 64 15 b0 45 4e ..F..}..Z..d..EN
>C:a0a0 c4 46 4f d2 4e 45 58 d4 44 41 54 c1 49 4e 50 55 .FO.NEX.DAT.INPU
>C:a0b0 54 a3 49 4e 50 55 d4 44 49 cd 52 45 41 c4 4c 45 T.INPU.DI.REA.LE
>C:a0c0 d4 47 4f 54 cf 52 55 ce 49 c6 52 45 53 54 4f 52 .GOT.RU.I.RESTOR
>C:a0d0 c5 47 4f 53 55 c2 52 45 54 55 52 ce 52 45 cd 53 .GOSU.RETUR.RE.S
>C:a0e0 54 4f d0 4f ce 57 41 49 d4 4c 4f 41 c4 53 41 56 TO.O.WAI.LOA.SAV
>C:a0f0 c5 56 45 52 49 46 d9 44 45 c6 50 4f 4b c5 50 52 .VERIF.DE.POK.PR
How can this output be interpreted? Let's look specifically at the first output line:
>C:a000 94 e3 7b e3 43 42 4d 42 41 53 49 43 30 a8 41 a7 ..{.CBMBASIC0.A.
The first part of the output C:a000 tells you the address where the contents displayed in this output line is located in memory. After this, the bytes follow one by one. Thus, at $A000, there is the byte $94, at $A001, there is the byte $E3, at $A002, there is the byte $7B, and so on. After every 4 byte, the space between two bytes is is a little bit wider, so you can easily count the bytes yourself.
After (in this case) 16 byte, the "new" data ends. What is the last part ..{.CBMBASIC0.A. about? This part repeats the data (thus, the $94, $E3, $7B, $E3, ...). Now, instead of printing each byte with its value, the monitor assumes this to be some text, and outputs the corresponding ASCII (or, more precisely, PETSCII representation of that data. Of course, as ASCII/PETSCII also contains some control characters (for example, there are characters to clear the whole screen), the monitor only prints characters which it consideres as "printable". If not, the monitor just outputs a dot (".").
So, interpreting the line at $A000, you can clearly see the $A004 to $A00C contains the text "CBMBASIC0".
mem a000: If you ommit the second parameter, the output will start at $A000. Anyway, the monitor will print up to some point where it thinks it makes sense.
(C:$a101) m a000
>C:a000 94 e3 7b e3 43 42 4d 42 41 53 49 43 30 a8 41 a7 ..{.CBMBASIC0.A.
>C:a010 1d ad f7 a8 a4 ab be ab 80 b0 05 ac a4 a9 9f a8 ................
>C:a020 70 a8 27 a9 1c a8 82 a8 d1 a8 3a a9 2e a8 4a a9 p.'.......:...J.
>C:a030 2c b8 67 e1 55 e1 64 e1 b2 b3 23 b8 7f aa 9f aa ,.g.U.d...#.....
>C:a040 56 a8 9b a6 5d a6 85 aa 29 e1 bd e1 c6 e1 7a ab V...]...).....z.
>C:a050 41 a6 39 bc cc bc 58 bc 10 03 7d b3 9e b3 71 bf A.9...X...}...q.
>C:a060 97 e0 ea b9 ed bf 64 e2 6b e2 b4 e2 0e e3 0d b8 ......d.k.......
>C:a070 7c b7 65 b4 ad b7 8b b7 ec b6 00 b7 2c b7 37 b7 |.e.........,.7.
>C:a080 79 69 b8 79 52 b8 7b 2a ba 7b 11 bb 7f 7a bf 50 yi.yR.{*.{...z.P
>C:a090 e8 af 46 e5 af 7d b3 bf 5a d3 ae 64 15 b0 45 4e ..F..}..Z..d..EN
>C:a0a0 c4 46 4f d2 4e 45 58 d4 44 41 54 c1 49 4e 50 55 .FO.NEX.DAT.INPU
>C:a0b0 54 a3 49 4e 50 55 d4 44 49 cd 52 45 41 c4 4c 45 T.INPU.DI.REA.LE
>C:a0c0 d4 47 4f 54 cf 52 55 ce 49 c6 52 45 53 54 4f 52 .GOT.RU.I.RESTOR
>C:a0d0 c5 47 4f 53 55 c2 52 45 54 55 52 ce 52 45 cd 53 .GOSU.RETUR.RE.S
>C:a0e0 54 4f d0 4f ce 57 41 49 d4 4c 4f 41 c4 53 41 56 TO.O.WAI.LOA.SAV
>C:a0f0 c5 56 45 52 49 46 d9 44 45 c6 50 4f 4b c5 50 52 .VERIF.DE.POK.PR
>C:a100 49 4e 54 a3 50 52 49 4e d4 43 4f 4e d4 4c 49 53 INT.PRIN.CON.LIS
>C:a110 d4 43 4c d2 43 4d c4 53 59 d3 4f 50 45 ce 43 4c .CL.CM.SY.OPE.CL
>C:a120 4f 53 c5 47 45 d4 4e 45 d7 54 41 42 a8 54 cf 46 OS.GE.NE.TAB.T.F
>C:a130 ce 53 50 43 a8 54 48 45 ce 4e 4f d4 53 54 45 d0 .SPC.THE.NO.STE.
>C:a140 ab ad aa af de 41 4e c4 4f d2 be bd bc 53 47 ce .....AN.O....SG.
>C:a150 49 4e d4 41 42 d3 55 53 d2 46 52 c5 50 4f d3 53 IN.AB.US.FR.PO.S
>C:a160 51 d2 52 4e c4 4c 4f c7 45 58 d0 43 4f d3 53 49 Q.RN.LO.EX.CO.SI
>C:a170 ce 54 41 ce 41 54 ce 50 45 45 cb 4c 45 ce 53 54 .TA.AT.PEE.LE.ST
>C:a180 52 a4 56 41 cc 41 53 c3 43 48 52 a4 4c 45 46 54 R.VA.AS.CHR.LEFT
>C:a190 a4 52 49 47 48 54 a4 4d 49 44 a4 47 cf 00 54 4f .RIGHT.MID.G..TO
>C:a1a0 4f 20 4d 41 4e 59 20 46 49 4c 45 d3 46 49 4c 45 O MANY FILE.FILE
>C:a1b0 20 4f 50 45 ce 46 49 4c 45 20 4e 4f 54 20 4f 50 OPE.FILE NOT OP
>C:a1c0 45 ce 46 49 4c 45 20 4e 4f 54 20 46 4f 55 4e c4 E.FILE NOT FOUN.
>C:a1d0 44 45 56 49 43 45 20 4e 4f 54 20 50 52 45 53 45 DEVICE NOT PRESE
>C:a1e0 4e d4 4e 4f 54 20 49 4e 50 55 54 20 46 49 4c c5 N.NOT INPUT FIL.
You see in this case, that the monitor showed the memory up to $A1EF on my machine. This is because my monitor window is rather large. On a smaller window, it would have choosen a much smaller area.
mem: You can also ommit the address entirely. In this case, the monitor will display the contents starting from where it ended in the last command:
(C:$a1f0) m >C:a1f0 4e 4f 54 20 4f 55 54 50 55 54 20 46 49 4c c5 4d NOT OUTPUT FIL.M >C:a200 49 53 53 49 4e 47 20 46 49 4c 45 20 4e 41 4d c5 ISSING FILE NAM. >C:a210 49 4c 4c 45 47 41 4c 20 44 45 56 49 43 45 20 4e ILLEGAL DEVICE N >C:a220 55 4d 42 45 d2 4e 45 58 54 20 57 49 54 48 4f 55 UMBE.NEXT WITHOU >C:a230 54 20 46 4f d2 53 59 4e 54 41 d8 52 45 54 55 52 T FO.SYNTA.RETUR >C:a240 4e 20 57 49 54 48 4f 55 54 20 47 4f 53 55 c2 4f N WITHOUT GOSU.O >C:a250 55 54 20 4f 46 20 44 41 54 c1 49 4c 4c 45 47 41 UT OF DAT.ILLEGA >C:a260 4c 20 51 55 41 4e 54 49 54 d9 4f 56 45 52 46 4c L QUANTIT.OVERFL >C:a270 4f d7 4f 55 54 20 4f 46 20 4d 45 4d 4f 52 d9 55 O.OUT OF MEMOR.U >C:a280 4e 44 45 46 27 44 20 53 54 41 54 45 4d 45 4e d4 NDEF'D STATEMEN. >C:a290 42 41 44 20 53 55 42 53 43 52 49 50 d4 52 45 44 BAD SUBSCRIP.RED >C:a2a0 49 4d 27 44 20 41 52 52 41 d9 44 49 56 49 53 49 IM'D ARRA.DIVISI >C:a2b0 4f 4e 20 42 59 20 5a 45 52 cf 49 4c 4c 45 47 41 ON BY ZER.ILLEGA >C:a2c0 4c 20 44 49 52 45 43 d4 54 59 50 45 20 4d 49 53 L DIREC.TYPE MIS >C:a2d0 4d 41 54 43 c8 53 54 52 49 4e 47 20 54 4f 4f 20 MATC.STRING TOO >C:a2e0 4c 4f 4e c7 46 49 4c 45 20 44 41 54 c1 46 4f 52 LON.FILE DAT.FOR >C:a2f0 4d 55 4c 41 20 54 4f 4f 20 43 4f 4d 50 4c 45 d8 MULA TOO COMPLE. >C:a300 43 41 4e 27 54 20 43 4f 4e 54 49 4e 55 c5 55 4e CAN'T CONTINU.UN >C:a310 44 45 46 27 44 20 46 55 4e 43 54 49 4f ce 56 45 DEF'D FUNCTIO.VE >C:a320 52 49 46 d9 4c 4f 41 c4 9e a1 ac a1 b5 a1 c2 a1 RIF.LOA......... >C:a330 d0 a1 e2 a1 f0 a1 ff a1 10 a2 25 a2 35 a2 3b a2 ..........%.5.;. >C:a340 4f a2 5a a2 6a a2 72 a2 7f a2 90 a2 9d a2 aa a2 O.Z.j.r......... >C:a350 ba a2 c8 a2 d5 a2 e4 a2 ed a2 00 a3 0e a3 1e a3 ................ >C:a360 24 a3 83 a3 0d 4f 4b 0d 00 20 20 45 52 52 4f 52 $....OK.. ERROR >C:a370 00 20 49 4e 20 00 0d 0a 52 45 41 44 59 2e 0d 0a . IN ...READY... >C:a380 00 0d 0a 42 52 45 41 4b 00 a0 ba e8 e8 e8 e8 bd ...BREAK........ >C:a390 01 01 c9 81 d0 21 a5 4a d0 0a bd 02 01 85 49 bd .....!.J......I. >C:a3a0 03 01 85 4a dd 03 01 d0 07 a5 49 dd 02 01 f0 07 ...J......I..... >C:a3b0 8a 18 69 12 aa d0 d8 60 20 08 a4 85 31 84 32 38 ..i....` ...1.28 >C:a3c0 a5 5a e5 5f 85 22 a8 a5 5b e5 60 aa e8 98 f0 23 .Z._."..[.`....# >C:a3d0 a5 5a 38 e5 22 85 5a b0 03 c6 5b 38 a5 58 e5 22 .Z8.".Z...[8.X."
Now, what is the first parameter about? The help talked about "data_type". In fact, it can be one of D (for decimal), H (for hexadecimal), B (for binary), or O (for octal). Note that this character must be written in upper-case!
Now, lets have a look at some examples again:
- Decimal (D):
(C:$a3e0) m D a000 a01f
>C:a000 148 227 123 227 67 66 77 66 65 83 73 67 ..{.CBMBASIC
>C:a00c 48 168 65 167 29 173 247 168 164 171 190 171 0.A.........
>C:a018 128 176 5 172 164 169 159 168 ........
- Hexadecimal (H):
(C:$a020) m H a000 a01f
>C:a000 94 e3 7b e3 43 42 4d 42 41 53 49 43 30 a8 41 a7 ..{.CBMBASIC0.A.
>C:a010 1d ad f7 a8 a4 ab be ab 80 b0 05 ac a4 a9 9f a8 ................
- Octal (O):
(C:$a020) m O a000 a01f
>C:a000 224 343 173 343 103 102 115 102 101 123 111 103 ..{.CBMBASIC
>C:a00c 060 250 101 247 035 255 367 250 244 253 276 253 0.A.........
>C:a018 200 260 005 254 244 251 237 250 ........
(C:$a020)
- Binary (B):
(C:$a020) m B a000 a01f
>C:a000 10010100 11100011 01111011 11100011 ..{.
>C:a004 01000011 01000010 01001101 01000010 CBMB
>C:a008 01000001 01010011 01001001 01000011 ASIC
>C:a00c 00110000 10101000 01000001 10100111 0.A.
>C:a010 00011101 10101101 11110111 10101000 ....
>C:a014 10100100 10101011 10111110 10101011 ....
>C:a018 10000000 10110000 00000101 10101100 ....
>C:a01c 10100100 10101001 10011111 10101000 ....
This closes the first part of the series on the VICE monitor. In the next part, we will discuss how you can disassemble parts of the memory.