Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASCII to C64 Screen Codes In DASM Assembler

I'm learning assembly for the 6502 micro via a C64 emulator. Currently trying to output strings to the screen. Here is my code:

    processor 6502
    org $1000

    ldx #$00    ;using x register as column counter
print:
    lda message,x;load a with x bit from message
    sta $0400,x ;store this bit in row 0 col 0 address
    inx         ;x++
    cpx #$05    ;is x >= 5?
    bne print   ;if not x >= 5, loop again
    rts         ;return from program


message dc "HELLO"
hexmsg dc $08,$05,$0c,$0c,$0f

Because my editor (notepad++ on win 10) uses ascii-like char-codes, the "HELLO" in message is bits 48 45 4C 4C 4F. This gives the following output in the top left corner of the screen: enter image description here

This is correct I guess, by looking at the commodore screen codes table here.

If I change line 6 to lda hexmsg,x then I get exactly what I'm after, the word HELLO.

I'm not yet very familiar with DASM assembler and having trouble finding complete documentation of it (if it exists). Most tutorials I've found just have you declare message .byte "HELLO" or something similar and it just works because the assembler they are using auto-converts the ascii-like text string to a commodore string automatically, but DASM doesn't seem to do that.

Does anyone know a way I can either get DASM to do this, or recommend another way to simply type strings into the assembler rather than manually typing my strings as a bunch of hex data?

like image 614
nexus_2006 Avatar asked Dec 05 '22 14:12

nexus_2006


2 Answers

Aha, ASCII encoding vs. Commodore screen codes. We've all been there. You have a few options:

  1. Don't write directly to screen memory, but use the Kernal CHROUT routine instead (probably via the higher-level string-output routine). Then all you have to worry about is the differences between ASCII and PETSCII, but that's a story for another bed-time. Also, this is good for text but sucks for games as the Kernal is s-l-o-w compared to direct writes.

  2. Write a little conversion routine that runs when your program starts, eats your string table, and spits out converted screen code equivalents. Fast and efficient, provided your strings are all together and you're not writing a ROM-based application (which would not be able to do an in-place conversion).

  3. Write a DASM pre-processor which runs before DASM in your build script and basically does the same conversion as #2 above, but to the sourcecode before the assembler sees it. This can be a bit gnarly, and you have to be sure to back-up the original source before munging it.

  4. Get the DASM sourcecode and patch it to invoke a user-exit for a new data-type (for screen codes) that does the same as #2 but on-the-fly during assembly. Very gnarly.

  5. Use lower-case letters in your strings, which will translate to upper-case screen code equivalents during assembly. You may have overlooked the fact that what you're seeing is the shifted representation of the characters in the string, which in the default display mode is graphics symbols.

Speaking from experience of all 5 options, I've settled on #2.

Also: switch to KickAssembler, which

  • is newer, and actively maintained
  • offers more powerful features
  • integrates very well with VICE for debugging
like image 106
Eight-Bit Guru Avatar answered Dec 08 '22 02:12

Eight-Bit Guru


Been a while since I programmed 6510. (If you are not pressed for conserving every single byte of C64 memory..) Also consider zero terminating your string(s) with say a 0 byte rather than terminating on length reached in the X register. Makes it a little more convenient rather than working out string lengths :D

processor 6502
org $1000

printstring:
    ldx #$00
printstrlp:
    lda message,x
    cmp #0
    beq quitstr
    cmp #32         ;' ' character
    beq noconv
    cmp #33         ;! character
    beq noconv
    cmp #42         ;* character
    beq noconv
    cmp #48         ;numbers 0-9
    bcs numconv
conv:
    sec
    sbc #$40
noconv: 
    sta $0400,x
    inx         
    bne printstrlp
quitstr:
    rts
numconv:
    cmp #58
    bcc noconv
    jmp conv

message dc "** HELLO C64 WORLD! **",0
like image 27
foxcode64 Avatar answered Dec 08 '22 02:12

foxcode64