0

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"

1 Answers1

2

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...

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
  • 1
    Thank you for this, some great detective work. I am certainly onto something here. But as a bit of a novice, I'm not sure what flipping the bit 2 in 53272 means, I am guessing it would be something like #$02 into $D018 ? The whole D018 stuff is confusing to me, as it doesn't get too into in the Programmers Reference Guide. -- As I am playing around with it I can get the text to display in uppercase and lowercase on both lines, but the first character is chopped, why would that be? – James Bradley Dec 21 '21 at 11:15
  • Flipping is `lda $D018; eor #2; sta $d018` – Aki Suihkonen Dec 21 '21 at 11:36
  • So, I have it kinda working but the two sides are being sliced off meaning that the first column of Characters isn't displaying, nor are the last. – James Bradley Dec 21 '21 at 11:42
  • The first character is chopped probably due to what's happening in the split screen interrupt service, whose details I don't know. Often it was preferred to shrink the visible screen to 38 characters or so, to allow scrolling without artifacts. The easy fix is to start the message with space. – Aki Suihkonen Dec 21 '21 at 11:42
  • and the flipping hasn't worked. With some playing around in the dark I have managed to get the text displaying correctly with "lda #22 sta $d018 LDA #%00000000 sta $d016" – James Bradley Dec 21 '21 at 11:46
  • Ah okay, so the clipping is just something I will need to adjust for? Perhaps introduce a scroll or something like that? – James Bradley Dec 21 '21 at 11:48
  • Actually, in closing, this has all been solved by the following... $D016 Screen control register #2. Bits: Bits #0-#2: Horizontal raster scroll. Bit #3: Screen width; 0 = 38 columns; 1 = 40 columns. Bit #4: 1 = Multicolor mode on. Default: $C8, %11001000. – James Bradley Dec 21 '21 at 13:55