SPO600 Lab3 - 6502 조립 언어 수학 실습실

4074 단어
lab3에서는 6502 어셈블리 언어를 사용하여 만화경 프로그램을 만들고 있습니다. 비트맵 화면은 4개의 사분면으로 나뉘며 사용자는 키보드의 화살표 키를 사용하여 두 번째 사분면(왼쪽 상단)에 픽셀을 그릴 수 있습니다. 그려진 픽셀은 다른 3개 사분면에 반영됩니다.

결과



소스 코드

 ; 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 draw_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 draw_on_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


 draw_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

 draw_on_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


서브루틴:
  • "draw_cursor"는 행과 열의 범위를 [$00 : $0F]로 설정하여 커서가 이동할 수 있는 영역인 2사분면만 제한합니다
  • .
  • "draw_on_quads"는 현재 위치의 복사본을 저장하고 커서에 x 또는 y 오프셋을 추가하여 2사분면의 픽셀을 다른 3사분면에 반영합니다.
  • 좋은 웹페이지 즐겨찾기