assembly6502c646510

I think I have solved raster interrupts text/bitmap mode but I have this weird text error


Assembler: CBM prg Studio.

Hi guys, Merry Christmas and happy holidays :) What is going on with the text output in my interupt? I must be missing something obvious here but please take a look at the attached picture...

It is supposed to say:

"Moving into range of the first candidate..."

*Bitmap displays

"COMMENCE MINE Y/N?"

Take a look at the attached image and see for yourself.

Below is the code. Thanks for taking the time out to take a look, this has been baffling me all night!

:) JamesClick here to see the pic

    ; 10 SYS (2064)

*=$0801

        BYTE    $0E, $08, $0A, $00, $9E, $20, $28, $32, $30, $36, $34, $29, $00, $00, $00
;Sexy Subroutines...
CHROUT = $FFD2   ;  Output a character to the screen
SCNKEY = $FF9F   ;  Place ASCII character into keyboard queue
GETIN = $FFE4    ;  Places the ASCII value into the Accumulator

PLOT = $FFF0     ;  PLOTs the cursor to the next line down, X = the row number
                 ;  Y = the colum. Always Clear the Carry (CLC) vital for
                 ;  plotting!

DECDIS = $BDCD

;The stack location for temporary strings...
tempst1 = $0020
tempst2 = $0021

;Screen details...
Screen = $0400
Border = $D020
Background = $D021

; I/O Stuff.........
LSTX = $00c5     ; Current key pressed.
; 01=ENTER. 3C=SPACE. 1=38. 2=3b. 3=08. 4=0b. 5=10. 6=13. 7=18. 8=1b. 9=20
; Y=19. N=27. S=0d. P=29.


*=$0810

        lda #147          ; This is a BASIC routine that presses the keyboard
        jsr CHROUT        ; button that clears the screen.

        lda #00
        sta Border
        sta Background
        
        jsr Init          ; Split the screen!

        ldx #$00

        lda #$0e
        jsr CHROUT

        ldx #20
        ldy #00
        clc
        jsr PLOT
        lda #>Siliconi
        sta tempst2
        lda #<Siliconi
        sta tempst1

        jsr print

        ldx #01
        ldy #00
        clc
        jsr PLOT
        lda #>message
        sta tempst2
        lda #<message
        sta tempst1

        jsr print


loaddccimage
        ;lda $3f40,x
        ;sta $0400,x
        lda $4040,x
        sta $0500,x
        lda $4140,x
        sta $0600,x
        ;lda $4240,x
        ;sta $0700,x

        ;lda $4328,x
        ;sta $d800,x
        lda $4428,x
        sta $d900,x
        lda $4528,x
        sta $da00,x
        ;lda $4628,x
        ;sta $db00,x
        inx
        bne loaddccimage

        lda #$3b
        sta $d011
        lda #$18
        sta $d016


jump    jmp *
;===================

Init    SEI                  ; set interrupt bit, make the CPU ignore interrupt requests
        LDA #%01111111       ; switch off interrupt signals from CIA-1
        STA $DC0D

        AND $D011            ; clear most significant bit of VIC's raster register
        STA $D011

        LDA $DC0D            ; acknowledge pending interrupts from CIA-1
        LDA $DD0D            ; acknowledge pending interrupts from CIA-2

        LDA #0               ; set rasterline where interrupt shall occur
        STA $D012

        LDA #<Irq            ; set interrupt vectors, pointing to interrupt service routine below
        STA $0314
        LDA #>Irq
        STA $0315

        LDA #%00000001       ; enable raster interrupt signals from VIC
        STA $D01A

        CLI                  ; clear interrupt flag, allowing the CPU to respond to interrupt requests

        RTS                  ; ?? Leave here ??

Irq     LDA $D011             ; select text screen mode
        AND #%11011111
        STA $D011

        lda #$14
        sta $d018

        LDA #%00000000
        sta $d016

        LDA #<Irq2            ; set interrupt vectors to the second interrupt service routine at Irq2
        STA $0314
        LDA #>Irq2
        STA $0315

        LDA #100
        STA $D012            ; next interrupt will occur at line no. 0

        ASL $D019            ; acknowledge the interrupt by clearing the VIC's interrupt flag

        JMP $EA31            ; jump into KERNAL's standard interrupt service routine to handle keyboard scan, cursor display etc.

Irq2    LDA $D011             ; select bitmap screen mode
        ORA #%00100000
        STA $D011

        lda #$18
        sta $d018

        LDA #%00010000
        sta $d016

        LDA #<Irq             ; set interrupt vectors back to the first interrupt service routine at Irq
        STA $0314
        LDA #>Irq
        STA $0315

        LDA #200
        STA $D012            ; next interrupt will occur at line no. 210

        ASL $D019            ; acknowledge the interrupt by clearing the VIC's interrupt flag

        JMP $EA81            ; jump into shorter ROM routine to only restore registers from the stack etc

Print
        ldy #0 ;Clear the Y register
Print1
        lda (tempst1),y
        cmp #255
        beq PrintDone
        jsr PrintChar
        iny
        jmp Print1
PrintDone
        RTS
PrintChar
        cmp #48
        bcc PrintChar1
PrintChar1
        jsr CHROUT
        rts

Siliconi
        Text "COMMENCE MINE Y/N?"
        byte 255

message
        Text "Moving into range of the first candidate..."
        byte 255

*=$1FFE
        incbin  "ASTRO1.prg"

Solution

  • The issue seems to relate to the feature of the PETSCII specification called shifting.

    Assuming the graphics mode is unshifted, PETSCII has only uppercase letters in its powerup state.

    In the shifted mode, the lowercase characters a-z occupy the same character space (0x41..0x5a) as the upper case characters A-Z in the unshifted mode. In this mode the upper case characters are located at (0x61..0x7a), which holds some graphical glyphs in the unshifted mode.

    The evidence supports this, since the lower case letters are visualised as uppercase and the uppercase letters are shown as block graphics characters.

    To solve this:

    On C64 the sets are alternated by flipping bit 2 of the byte 53272

    Alternatively I think it's possible to output the right character directly to the screen memory without using the KERNAL function. I'm not sure about this, since it's been quite a long time when I programmed C64. It might have been that instead the toggling of the character set needed to be disabled so that random key presses didn't alter the screen...