Waiting for a change on $D012 (C64 assembler)

4k views Asked by At

I've run into a few issues while playing around with asm on an emulated C64 machine.

What I want to do is to check if the key "N" on the keyboard is being pressed, then the program should wait for a change to appear on address $D012. Now what I don't understand is how I can "wait" for a change to appear? Can anybody tell me what it's all about?

Checking if N button on the keyboard is pressed down is simple - just use the subroutines FFE4 (input) and FFD2 (output).

I don't really ask for anything to be done for me, but if I can get some quick info on how the D012 works and how I can "wait" for a change, I would be really thankful.

Thanks in advance!

2

There are 2 answers

2
Jens Björnhager On BEST ANSWER

$d012 contains the current raster line.

If you only need to wait until the the register changes, that is wait until the next raster line, you can do simple busy-waiting:

lda $d012 ;load the current raster line into the accumulator
cmp $d012 ;check if it has changed
beq *-3   ;if not, jump back and check again

edit:

If you want to wait for several rasterlines, for example 3:

lda $d012
clc       ;make sure carry is clear
adc #$03  ;add lines to wait
cmp $d012
bne *-3   ;check *until* we're at the target raster line
0
Erik Post On

You can respond to changes in $d012 by using a raster IRQ handler. I'll throw in a couple of specifics from my game code because it can be hairy to get this to work if you use the wrong combination of incantations. This should also give you enough stuff to google.

In particular, you might want to look at installing your int handler in $0314 like the code mentions, in which case your IRQ handler will be chained with the commie's own default handlers, and you need to skip the pha ... pha bit at the start of your handler. This can be useful if you need to use some of its I/O code.

;;; -----------------------------------------------------------------------------
;;; install raster interrupt handler
;;; -----------------------------------------------------------------------------

        sei                     ; turn off interrupts

        ldx #1                  ; enable raster interrupts
        stx $d01a

        lda #<int_handler       ; set raster interrupt vector
        ldx #>int_handler
        sta $fffe
        stx $ffff

        ldy #$f0                ; set scanline on which to trigger interrupt
        sty $d012
        lda $d011                ; scanline hi bit
        and #%01111111
        sta $d011

        lda #$35                ; disable kernal and BASIC memory ($e000 - $ffff)
        sta $01

        asl $d019               ; acknowledge VIC interrupts
        cli

loop_pro_semper
        jmp loop_pro_semper

Then you handle these interrupts like this:

;;; -----------------------------------------------------------------------------
;;; raster IRQ handler
;;; -----------------------------------------------------------------------------

int_handler

        pha                     ; needed if our raster int handler is set in fffe instead of 0314
        txa
        pha
        tya
        pha

                    ; ... do your stuff here ...