• entries
104
102
• views
258752

A c64 game - Step 2

9095 views

And onwards we stumble!

In the first part we prepared everything for the VIC, now we set up our modified charset. Note that I used a selfmade tool (similar to CharPad), which is included (Windows binary). The file J.CHR contains the charset and is included into the source as binary. The memory layout of the game expects the modified charset at $f000. Since the C64 can't load files to locations after$C000 we have to copy the charset to the target memory at $f000. To be able to properly write at those addresses we need to switch off the ROM overlay. The current step should display "HELLO". The rest of the screen depends on the current memory setup of your emulator/C64 First code piece we add is the copy routine. Interrupts are blocked because we turn off the kernal ROM. If we didn't the IRQ code would jump in the middle of uninitialised RAM, likely resulting in a crash. The RAM/ROM layout is influenced by memory address$1.

          ;----------------------
;copy charset to target
;----------------------

;block interrupts
;since we turn ROMs off this would result in crashes if we did not
sei

;save old configuration
lda $1 sta PARAM1 ;only RAM ;to copy under the IO rom lda #%00110000 sta$1

;take source address from CHARSET
LDA #<CHARSET
STA ZEROPAGE_POINTER_1
LDA #>CHARSET
STA ZEROPAGE_POINTER_1 + 1

;now copy
jsr CopyCharSet

;restore ROMs
lda PARAM1
sta $1 cli The actual copy routine. Note that we only copy 254 characters. The last two characters are omitted to not overwrite the default IRQ vectors residing at$fffb. Since we deal with a 8 bit machine there is an extra loop taking care of the high bytes of our addresses. At the end of the copy routine we include the binary charset data.

!zone CopyCharSet
CopyCharSet
;set target address ($F000) lda #$00
sta ZEROPAGE_POINTER_2
lda #$F0 sta ZEROPAGE_POINTER_2 + 1 ldx #$00
ldy #$00 lda #0 sta PARAM2 .NextLine lda (ZEROPAGE_POINTER_1),Y sta (ZEROPAGE_POINTER_2),Y inx iny cpx #$8
bne .NextLine

cpy #$00 bne .PageBoundaryNotReached ;we reached the next 256 bytes, inc high byte inc ZEROPAGE_POINTER_1 + 1 inc ZEROPAGE_POINTER_2 + 1 .PageBoundaryNotReached ;only copy 254 chars to keep irq vectors intact inc PARAM2 lda PARAM2 cmp #254 beq .CopyCharsetDone ldx #$00
jmp .NextLine

.CopyCharsetDone
rts

CHARSET
!binary "j.chr"

To display HELLO on the screen we simple poke the character codes on the screen and also set the characters colors to white.

;test charset
lda #'H'
sta SCREEN_CHAR
lda #'E'
sta SCREEN_CHAR + 1
lda #'L'
sta SCREEN_CHAR + 2
sta SCREEN_CHAR + 3
lda #'O'
sta SCREEN_CHAR + 4

lda #1
sta SCREEN_COLOR
sta SCREEN_COLOR + 1
sta SCREEN_COLOR + 2
sta SCREEN_COLOR + 3
sta SCREEN_COLOR + 4

Clarifications:

The charset of the C64 is using 8 bytes per character. This totals at 256 characters a 8 bytes = 2048 bytes. A custom character set can be positioned almost everywhere in RAM (at 2048 interval steps).

In hires text mode every bit corresponds to a pixel. In multicolor text mode pixels are doubling width, so two bits make up one pixel. In multicolor mode two colors are shared by all multi-color characters, one is the background color and one is the current char color.

The memory layout looks like this (nicked from www.c64-wiki.de):

$FFFF = 65535 ????????????????????????????????? ?---------------?|||||||||||||||? ||| = read by PEEK ?---------------?|||||||||||||||? --- = written to by POKE ?---------------?|||||||||||||||? +++ = read and write ?---------------?||| KERNAL- |||? other = not reachable from BASIC ?---------------?||| ROM |||? ?---------------?|||||||||||||||? ?---------------?|||||||||||||||?$E000 = 57344 ?????????????????????????????????????????????????
?               ?               ?+++++++++++++++?
?               ?    CHAR ROM   ?+++++ I/O +++++?
?               ?               ?+++++++++++++++?
$D000 = 53248 ????????????????????????????????????????????????? ?+++++++++++++++? ?+++++++++++++++? ?+++++++++++++++?$C000 = 49152 ?????????????????????????????????
?---------------?|||||||||||||||?
?---------------?|||||||||||||||?
?---------------?||| BASIC- ||||?
?---------------?|||  ROM   ||||?
?---------------?|||||||||||||||?
?---------------?|||||||||||||||?
?---------------?|||||||||||||||?
$A000 = 40960 ????????????????????????????????? ?+++++++++++++++? ?+++ BASIC- ++++? ?+++ RAM ++++? . . ?+++ BASIC- ++++? ?+++ RAM ++++?$800 = 2048   ?+++++++++++++++?-?
$400 = 1024 ?+++++++++++++++?-?Default Screen Address$0000         ?????????????????-?Zeropage and Enhanced Zeropage

I like these articles Totally hackish.

Nice work, looking forward to seeing more.

Does the C64CharTiler not support multicolor yet?

Glad you like it

It does support multicolor, but with the restrictions of the real machine. You need to a) check multicolor for every char and b) have a char color >= 8.

The C64 allowed both multicolor and hires color chars at the same time, albeit only a char color in the first 8 colors.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account