Skip to main content

First assembly program on the C64... in BASIC

There are many books, tutorials etc dedicated to teaching C64 programming, many of them start by teaching BASIC. I had an MSX as a kid so I'm pretty familiar with this flavor of BASIC (Microsoft BASIC). On the other hand, most assembly programming tutorials begin with number systems, binary numbers and other pretty basic stuff for someone who's already familiar with assembly programming in other platforms. 

What I wanted was to create the smallest programs in assembly that could run on the machine and show some effect. After looking around for a bit I've found this one:

    lda #$00
    sta $d020
    sta $d021
    rts 

This sets the contents of the accumulator to 0 and then store this zero at memory locations 0xD020 and 0xD021. These two memory locations control the color of the screen background (0xD021) and the border (0xD020). As expected, setting them to zero will make the whole screen black (except for the text).

Now the next step is how to run this program. The ideal way would be to assemble the program and then run on the machine or emulator, and for that we could generate a program in the very simple PRG format and transfer it to the machine. However, I wanted something more immediate and then thought about doing it the way magazines and books did in the old days when users had access to BASIC but not an assembler. This is by using the POKE instruction from BASIC to set memory locations to arbitrary values. After looking at some examples, it seems address 0xC000 (49152) is a popular spot for placing machine language subroutines to be called from BASIC. Using a web-based assembler, the above program is translated to the following bytes in 6502 machine language:

A9 00 8D 20 D0 8D 21 D0 60

So the only thing left is to convert all bytes to decimal and create the POKEs that will put the program at the right location, then transfer to it:

10 POKE 49152, 169
20 POKE 49153, 00
30 POKE 49154, 141
40 POKE 49155, 32
50 POKE 49156, 208
60 POKE 49157, 141
70 POKE 49158, 33
80 POKE 49159, 208
90 POKE 49160, 96
100 SYS 49152

The SYS command at the last line calls a "system" subroutine at the specified address. Note that the assembly code ends with a RTS (return from subroutine) instruction that will return control to the BASIC interpreter. 

Type and run this code at the C64 BASIC and voila, the screen turns black:

The next step could be to create a PRG file by hand with this program, load it from (virtual) disk and run it. Maybe next time. 

Comments

Popular posts from this blog

C64: Create a PRG file with a simple machine-language program

Getting back to machine-language, we will take the program from a previous post , assemble it by hand, and create a PRG file that can be run on a C64 emulator.  The program is a very simple one that changes the background and border color to black: LDA #00 STA $D020 STA $D021 RTS If we look up the opcodes by hand or use an assembler, we can see that the machine language code for this program is the following byte sequence: A9 00 8D 20 D0 8D 21 D0 60 One way to run this program, at least on a Commodore 64 emulator, is to create a PRG file with it. Another way would be to create a disk image (D64). But the PRG format is much simpler, so we go with it, for now. A PRG file consists of a 2-byte header followed by the binary contents of the program to load into memory. The header specifies the memory address for the binary code to be loaded in the C64 memory space. So we could start with the bytes 00 C0 (the 6502 is a little-endian CPU) and load the code to address $C000; then we sho...

C64: Playing with video memory in text mode

 As it happens with older computers, with the C64 the programmer had complete control over the machine and could write directly to any part of memory, perform I/O and so on. Video memory was mapped to the CPU address space and so could be read and written directly as well.  For the C64, the relevant memory addresses are 0x0400 for characters and 0xD800 for colors. The byte at 0x0400 determines the character that appears at the top left corner at the screen, while the byte at 0xD800 determines the color of this character. The following bytes store the next characters in order going from left to right, and top to bottom. So, to find the address of screen position (x, y) for column x and row y, you have to calculate 40*y+x. Multiplication can be slow in these old CPUs, but we can fill the memory sequentially and, en passant, see the complete character set of the computer (it does not follow ASCII).  So here's a small BASIC program to manipulate video memory using POKEs. We c...