icodenosleep
icodenosleep

Reputation: 49

How to create a delay in asm for the MOS 6502

I'm new to ASM and I trying to workout how to create a delay for the following code:

org $1000

loop: inc $d021
    jmp loop

Upvotes: 3

Views: 6224

Answers (4)

supercat
supercat

Reputation: 81143

If you can ensure that the code doesn't cross a page boundary, a useful approach is to have a pair of bytes somewhere in RAM which will hold a computed jump address, and use an indirect jump into something like the following:

TableStart:
    cmp #$C9
    cmp #$C9
    cmp #$C9
    cmp #$C9
    cmp #$C9
    ...
TableEnd:
    nop

If the jump vector points to tableEnd, code will reach the instruction after the NOP after seven cycles. If it points one byte earlier, eight cycles. Two bytes earlier, nine cycles, etc. Setting up the jump vector may take a little while, but the delay itself will be smoothly adjustable from seven cycles to any higher value in single-cycle increments. Flags will be trashed, but no registers will be affected.

Upvotes: 0

cbmeeks
cbmeeks

Reputation: 11410

How about this? This should change the background, wait 4 seconds, then change it again. Repeat forever.

Note, you can change the number of seconds to anything from 0 to 255.

This is for NTSC machines but you can change the 60 to 50 for PAL.

main:
    inc $D021

    ldx #4          //  Wait 4 seconds
loop1:
    ldy #60
loop2:

waitvb:
    bit $D011
    bpl waitvb
waitvb2:
    bit $D011
    bmi waitvb2

    dey
    bne loop2
    dex
    bne loop1

    jmp main

Upvotes: 0

Emir Akaydın
Emir Akaydın

Reputation: 5823

Comments are clear enough i guess.

Code sample for changing color each frame (1/50 of a second)

        sei       ; enable interrupts

loop1:  lda #$fb  ; wait for vertical retrace
loop2:  cmp $d012 ; until it reaches 251th raster line ($fb)
        bne loop2 ; which is out of the inner screen area

        inc $d021 ; increase background color

        lda $d012 ; make sure we reached
loop3:  cmp $d012 ; the next raster line so next time we
        beq loop3 ; should catch the same line next frame

        jmp loop1 ; jump to main loop

Code sample for changing color each second

counter = $fa ; a zeropage address to be used as a counter

        lda #$00    ; reset
        sta counter ; counter

        sei       ; enable interrupts

loop1:  lda #$fb  ; wait for vertical retrace
loop2:  cmp $d012 ; until it reaches 251th raster line ($fb)
        bne loop2 ; which is out of the inner screen area

        inc counter ; increase frame counter
        lda counter ; check if counter
        cmp #$32    ; reached 50
        bne out     ; if not, pass the color changing routine

        lda #$00    ; reset
        sta counter ; counter

        inc $d021 ; increase background color
out:
        lda $d012 ; make sure we reached
loop3:  cmp $d012 ; the next raster line so next time we
        beq loop3 ; should catch the same line next frame

        jmp loop1 ; jump to main loop

Upvotes: 7

user2699113
user2699113

Reputation: 4509

for example:

loop: ldx $d021
      inx
      stx $d021
      cpx #100
      bne loop

Upvotes: 0

Related Questions