DEV Community

Tecca Yu
Tecca Yu

Posted on

LAB3 - continued

In the previous post, a drawing program was successfully run on 6502 Emulator, now I want to create a kaleidoscope drawing program.

My plan is to allow the user to only draw on the second quadrant which is the top left quadrant in the 6502 display and reflecting whatever the user draw on it to the other three quadrant to create an kaleidoscope effect.

A couple more things needs to be done in order to achieve this.

First it needs to restrict the cursor's movement to only allow user draw on the second quadrant, in drawing cursor by setting the range of row and column to [$00 : $0F] will make this happen.

drawing_cursor:
    lda ROW     ; ensure ROW is in range 0:0F
    and #$0f
    sta ROW

    lda COL     ; ensure COL is in range 0:0F
    and #$0f
    sta COL

    ldy ROW     ; load POINTER with start-of-row
    lda table_low,y
    sta POINTER
    lda table_high,y
    sta POINTER_H

    ldy COL     ; store CURSOR at POINTER plus COL
    lda #CURSOR
    sta (POINTER),y

    rts
Enter fullscreen mode Exit fullscreen mode

Then whatever pixels that are in the second quadrant should be reflected to other three quadrant. This is done by storing a copy of the current position and adding the x or y offset to the cursor every time user moves the cursor.

drawing_other_quads:     
    LDA POINTER ;; save the pointer to the
    PHA     ;; original location in top_left_quad
    LDA POINTER_H
    PHA

; top right quadrant
    LDA #$10
    CLC
    SBC COL
    CLC
    ADC #$10
    TAY
    LDA DOT
    STA (POINTER),y

    TYA
    PHA     ; save the y offset

; bottom left quadrant  
    lda #$10    ; load POINTER with start-of-row
    CLC
    SBC ROW
    CLC
    ADC #$10
    TAY

    lda table_low,y
    sta POINTER
    lda table_high,y
    sta POINTER_H

    ldy COL     ; store CURSOR at POINTER plus COL
    lda DOT
    sta (POINTER),y

    PLA
    TAY

; bottom right quadrant 
    lda DOT
    sta (POINTER),y

    PLA
    STA POINTER_H
    PLA
    STA POINTER

    RTS
Enter fullscreen mode Exit fullscreen mode

Complete source code:

; zero-page variable locations
 define ROW     $20 ; current row
 define COL     $21 ; current column
 define POINTER     $10 ; ptr: start of row
 define POINTER_H   $11

 ; constants
 define DOT     $01 ; dot colour location
 define CURSOR      $04 ; purple colour


setup:  lda #$0f    ; set initial ROW,COL
    sta ROW
    sta COL
    LDA #$01
    STA DOT

draw:   jsr drawing_cursor

getkey:
    ldx #$00    ; clear out the key buffer
    lda $ff     ; get a keystroke
    stx $ff

    cmp #$30
    bmi getkey
    cmp #$40
    bpl continue

    SEC
    sbc #$30
    tay
    lda color_pallete, y
    sta DOT
    jmp done

continue:   
    cmp #$43    ; handle C or c
    beq clear
    cmp #$63
    beq clear

    cmp #$80    ; if not a cursor key, ignore
    bmi getkey
    cmp #$84
    bpl getkey

    pha     ; save A

    lda DOT ; set current position to DOT
    sta (POINTER),y
    jsr drawing_other_quads

    pla     ; restore A

    cmp #$80    ; check key == up
    bne check1

    dec ROW     ; ... if yes, decrement ROW
    jmp done

 check1:    
    cmp #$81    ; check key == right
    bne check2

    inc COL     ; ... if yes, increment COL
    jmp done

 check2:    
    cmp #$82    ; check if key == down
    bne check3

    inc ROW     ; ... if yes, increment ROW
    jmp done

 check3:    
    cmp #$83    ; check if key == left
    bne done

    dec COL     ; ... if yes, decrement COL
    clc
    bcc done

 clear: 
    lda table_low   ; clear the screen
    sta POINTER
    lda table_high
    sta POINTER_H

    ldy #$00
    tya

 c_loop:    
    sta (POINTER),y
    iny
    bne c_loop

    inc POINTER_H
    ldx POINTER_H
    cpx #$06
    bne c_loop

 done:  
    clc     ; repeat
    bcc draw


 drawing_cursor:
    lda ROW     ; ensure ROW is in range 0:0F
    and #$0f
    sta ROW

    lda COL     ; ensure COL is in range 0:0F
    and #$0f
    sta COL

    ldy ROW     ; load POINTER with start-of-row
    lda table_low,y
    sta POINTER
    lda table_high,y
    sta POINTER_H

    ldy COL     ; store CURSOR at POINTER plus COL
    lda #CURSOR
    sta (POINTER),y

    rts

 drawing_other_quads:     
    LDA POINTER ;; save the pointer to the
    PHA     ;; original location in top_left_quad
    LDA POINTER_H
    PHA

; top right quadrant
    LDA #$10
    CLC
    SBC COL
    CLC
    ADC #$10
    TAY
    LDA DOT
    STA (POINTER),y

    TYA
    PHA     ; save the y offset

; bottom left quadrant  
    lda #$10    ; load POINTER with start-of-row
    CLC
    SBC ROW
    CLC
    ADC #$10
    TAY

    lda table_low,y
    sta POINTER
    lda table_high,y
    sta POINTER_H

    ldy COL     ; store CURSOR at POINTER plus COL
    lda DOT
    sta (POINTER),y

    PLA
    TAY

; bottom right quadrant 
    lda DOT
    sta (POINTER),y

    PLA
    STA POINTER_H
    PLA
    STA POINTER

    RTS

 ; these two tables contain the high and low bytes
 ; of the addresses of the start of each row

 table_high:
 dcb $02,$02,$02,$02,$02,$02,$02,$02
 dcb $03,$03,$03,$03,$03,$03,$03,$03
 dcb $04,$04,$04,$04,$04,$04,$04,$04
 dcb $05,$05,$05,$05,$05,$05,$05,$05,

 table_low:
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0
 dcb $00,$20,$40,$60,$80,$a0,$c0,$e0

color_pallete:
dcb $01,$02,$03,$04,$05,$06,$07,$08,$09,$0a
Enter fullscreen mode Exit fullscreen mode

Results:

Image description

Image description

Top comments (0)