Oldschool Gaming - reviewing new games on classic computers
The Hex Files :: Part 3 :: written by Jason Kelk :: added 23 Jan 2004

Welcome again, here's the third installment of Hex Files for your delight, delectation and several other words beginning with the letter D that sound quite good. And, before we start proper, I'll just give you the solution to the little teaser I posed at the end of the previous article. Now, one of the joys of machine code is that there are several ways to reach the same solution and, whilst some are better than others, they're all valid at this stage in the game. So, whilst there are other methods that could be used (and if you found and used one, it's not the wrong answer!) the easiest way to modify the routine we were playing with in the previous installment would be something along these lines:

		* = $0900
		ldx #$00
		lda #$03	; to change the character
loop		sta $0400,x
		inx
		cpx #$0b	; to change the number of repeats
		bne loop
		rts

Okay, lets have some fun with a loop shall we? One of the most common things in demos (and in fact most games too) is the scrolling message and what we are going to do is a simple one with some limits. As we have seen from the example last issue it's possible to put characters on the screen very fast, so fast in fact that we can't actually see it happen. It's also possible to move the characters around the screen using loops. Start up your text editor, tab a couple of times to get the cursor to its start position and enter this program:

		* = $0900
main		ldx #$00
move_loop	lda $0401,x
		sta $0400,x
		inx
		cpx #$27
		bne move_loop
		inc $0427
		jmp main

Before we run it lets look at what you have typed. The * command is as we used before, telling C64Asm we want our code at $0900 (again, 2304 in decimal). We then have a label called main which is the start of our main code (hence the name!) and that clears the X register again as we have done before. The main loop of the program (named with the appropriate label again) is new though.

It reads from screen position $0401 and then puts whatever it has read into $0400. Then the X register goes up one and it repeats that until X reaches $27 (which is 39 in decimal). Why stop at 39? Well, by the time X gets to 40 (by the time we're checking X it's been INCremented, remember) the routine is reading from $0428 (the start of the second line of the screen) and writing to $0427 (the right hand end of the first line) so if we wait we would be reading the first character of the next line of the screen! Finally we just play with the character at the top right of the screen to make something to look at (by constantly INCrementing it to make it show every character the C64 has).

Okay, lets crank it up and watch it go! Assembling is as before, save the file from the text editor as scroll.asm (the extension meaning "assembly code", not even vaguely essential to the process but it makes remembering what the files are a lot easier), type c64asm scroll.asm scroll.prg from DOS whilst in the correct directory and finally drag and drop the PRG into WinVICE and SYS2304 to start it. Oh! Now something is happening but because machine code is so fast we can't see what, so we need to slow things down a bit and to do that I'll introduce a new friend in the form of one of the locations in the VIC-II chip.

Location $D012 (or 53,266 in decimal) is known as the raster register. The raster is a line that moves down the C64's screen redrawing it fifty times a second and there are over three hundred "raster lines" on a standard PAL C64 (there are less lines and a faster refresh speed for NTSC machines) and it's possible to wait for a specific line and do something when you get there. Lets alter our example to take advantage of this, go back to the source and enter the following just after the ldx #$00 on the second line:

		lda #$fe
raster		cmp $d012
		bne raster

Save it back out this time as scroll2.asm and assemble it as before. These three new lines set the A register up with a value of $fe (254 in decimal), then compare that to whatever $D012 contains in the same way as we compared numbers in the previous installment and if it's not the same (in other words if the raster isn't at position $fe) then the Branch if Not Equal (BNE) back to raster keeps it waiting in that loop until it is.

You should now see loads of characters scrolling across the top of the screen very fast but not so fast that you can't see what's going on. Don't worry about the odd jump, we are only experimenting at this point and every now and then the C64 will miss a beat because it's busy doing it's housekeeping at rasterline $fe. Believe it or not this is moving fifty times a second! Okay, so one final trick for our new listing I think, flip back over to the text editor and alter the routine to read like this:

		* = $0900
		ldy #$00		; this is new
main		ldx #$00
		lda #$fe
raster		cmp $d012
		bne raster
move_loop	lda $0401,x
		sta $0400,x
		inx
		cpx #$27
		bne move_loop
		lda $a1ff,y		; this line is new too
		sta $0427		; the INC command used to be here
		iny			; and this line is new as well
		jmp main

Save the source out as scroll3.asm, assemble and execute again, and if you press the shift and Commodore keys you'll see words flying across your screen! What we are actually doing in these new bits is using the Y register as a counter and reading from the C64's memory at $A1FF onwards for 256 bytes. So where do the words come from? Well, $A1FF is actually where the C64 keeps some of its error messages and this is what you're seeing.

Well, I think that's almost enough for another installment but before I go another couple of little challenges for you all to see if you've got the gist; at the moment the routine reads it's data from location $A1FF but can you change it to read from $E460? And can you make it work on the second line of the screen rather than the first (remember to change all of the references to the screen). I'll give the answers in the next thrilling installment but If you have any questions about this article, machine code or Flamenco dancing, contact me and I'll see what I can do. Oh, except about the dancing.

The source code for the routines above can be downloaded here for easier reference.

Content copyright © 2004-2014 Oldschool Gaming     Designed and hosted by Enisoc Design