Lab3 바운싱 그래픽/공(파트 III)

Lab3 개요



이 실습은 6502 어셈블리 언어로 산술/수학 코드를 작성하여 보다 복잡한 x86_64 및 AArch64 어셈블리 언어 학습을 준비합니다.

내가 선택한 옵션은 바운싱 그래픽입니다. 화면에 그래픽을 배치하고, 화면 주위에서 물체를 튕기며, 물체가 화면 가장자리 또는 다른 물체와 충돌했을 때 감지하는 등 여러 가지 기술이 필요합니다.

이 단계에서 가장 중요한 부분은 draw 기능을 개선하는 것입니다. 공이 움직일 때 이 기능이 잘 작동하도록 만들고 제거한 다음 다시 뽑습니다. 특히 테이크keystroke input 기능은 쓰는 데 시간이 많이 걸리고 결국 위, 아래, 왼쪽, 오른쪽 화살표 키 이외의 키 입력으로 볼이 움직이지 못하게 할 수 있습니다. 따라서 이 기능은 설계된 대로 완전히 작동하지 않습니다.

포인터 위치를 계산하고, 그래픽을 그리고, 키 입력을 확인하고 확인하고, 공이 화면 가장자리에 닿는지 확인하고, 공을 다시 그리기 위해 화면을 지우는 기능을 포함하여 코드가 아래에 나와 있습니다.

define WIDTH   5 
define HEIGHT  5

define  POINTER         $12      
define  POINTER_H       $13
define  ROW_COUNT       $14 
define  ROW             $15 
define  COLUMN          $16
define  CHECK_LINE      $17  ; this is to check the edge
define  ROW_FLAG    $18  ; edge on row or col flag
define  COL_FLAG   $19  
define  PTR_CAL   $20
define  DATA_INDEX      $21
define  SCREENCOL_INDEX $22
define  KEY             $23

 lda #$00
 sta ROW_FLAG
 sta COL_FLAG

 lda  #$05          
 sta  ROW
 lda  #$05 
 sta  COLUMN

; prepare to move by row and col
cal_init:
  lda  #$00    
  sta  POINTER
  lda  #$02
  sta  POINTER_H

  lda #$00  
  sta ROW_COUNT

  lda #$00   
  sta PTR_CAL 

  cmp ROW
  beq column_count
  bne row_count

row_count:
 lda PTR_CAL
 clc
 adc #$20
 sta PTR_CAL

 lda POINTER_H
 adc #$00
 sta  POINTER_H

 inc ROW_COUNT 

 lda ROW
 cmp ROW_COUNT
 bne row_count    ; run utill get the row set 
 beq column_count

column_count:
 lda PTR_CAL
 clc
 adc  COLUMN
 sta PTR_CAL
 sta  POINTER     ; once row and col done, set pointer

; draw graphic initializing 
 lda #$00
 sta ROW_COUNT

 ldx #$00  
 ldy #$00  

; draw graph, while checking the keystroke
draw: lda ball,x

 sta (POINTER),y 

 inx
 iny
 cpy #WIDTH
 bne draw

 inc ROW_COUNT

 lda #HEIGHT 
 cmp ROW_COUNT
 beq readkey_init

 lda POINTER
 clc
 adc #$20 
 sta POINTER 
 lda POINTER_H 
 adc #$00
 sta POINTER_H  

 ldy #$00 
 beq draw

; 
readkey_init:
 txa     
 sta DATA_INDEX
 tya 
 sta SCREENCOL_INDEX   

readkey: lda  $ff  ; get a keystroke 

 ldx #$00 ; clear out the key buffer
 stx $ff  ; store index x in memory


  cmp  #$80 ; if not a cursor key, ignore
  bmi  readkey_check   ; branch on minus
  cmp  #$84
  bpl  readkey_check   ; branch on plus

  cmp  #$80  ; check key, up key
  bne  rightKey_check

  dec  ROW  ; if yes, decrement row
  jmp  readkey_check

 rightKey_check: 
 cmp  #$81  ; check key, right key
  bne  downKey_check

  inc  COLUMN   ; if yes, increment col
  jmp  readkey_check

 downKey_check: 
 cmp  #$82  ; check if key, down key
  bne  leftKey_check

  inc  ROW  ;  if yes, increment row
  jmp  readkey_check

 leftKey_check: 
 cmp  #$83  ; check if key, left key
  bne  readkey_check

  dec  COLUMN   ; if yes, decrement col
  clc
  bcc  readkey_check 

readkey_check:
 ldx DATA_INDEX
 ldy SCREENCOL_INDEX
 jmp check_location

check_location: 
 jsr check_top
 jsr check_bottom
 jsr check_right 
 jsr check_left
 jsr move_pointer

check_initialize: 
 lda #$00
 sta CHECK_LINE
 rts                 ; return

check_top: 
 jsr check_initialize 
 lda ROW  
 cmp #$01            ; 01
 lda CHECK_LINE
 adc #$00
 cmp #$00  
 beq flip_rowFlag
 rts

check_bottom: 
 jsr check_initialize
 lda ROW
 cmp #$1b           ; 1b
 lda CHECK_LINE
 adc #$00
 cmp #$01
 beq flip_rowFlag 
 rts

check_left:
 jsr check_initialize
 lda COLUMN
 cmp #$01          ; 01
 lda CHECK_LINE
 adc #$00
 cmp #$00
 beq flip_colFlag
 rts

check_right:
 jsr check_initialize
 lda COLUMN
 cmp #$1b
 lda CHECK_LINE
 adc #$00
 cmp #$01
 beq flip_colFlag
 rts

;Set Row Flag 
flip_rowFlag:
 lda ROW_FLAG
 cmp #$00 
 beq inc_rowFlag
 bne dec_rowFlag
 rts

inc_rowFlag:
 inc ROW_FLAG
 rts

dec_rowFlag:
 dec ROW_FLAG
 rts


; Set Col Flag 
flip_colFlag:
 lda COLFLIP_FLAG
 cmp #$00
 beq inc_colFlag
 bne dec_colFlag
 rts

inc_colFlag:
 inc COLFLIP_FLAG
 rts

dec_colFlag:
 dec COLFLIP_FLAG
 rts

; move the graph 
; first move the pointer
move_pointer:
 jsr row_check
 jsr col_check
 jmp clear      ; jump to clear

row_check:
 lda ROW_FLAG
 cmp #$01
 beq dec_row
 bne inc_row

col_check:
 lda COLFLIP_FLAG
 cmp #$01
 beq dec_col
 bne inc_col

inc_row:
 inc ROW
 rts

dec_row:
 dec ROW
 rts

inc_col:
 inc COLUMN
 rts

dec_col:
 dec COLUMN 
 rts

; move the graph 
;move: inc ROW
; inc COLUMN

; clear the screen before redraw the graph
clear: lda ball
 sta POINTER 
 lda #$02
 sta POINTER_H

 ldy #$00
 tya

clear_loop:
 sta (POINTER),y
 iny
 bne clear_loop

 inc POINTER_H
 ldx POINTER_H 
 cpx #$06
 bne clear_loop

 jsr  cal_init

; data constant byte (dcb)
ball:
 dcb 00,07,07,07,00
 dcb 07,07,07,07,07
 dcb 07,07,07,07,07
 dcb 07,07,07,07,07
 dcb 00,07,07,07,00




내가 배운 것



주요 테이크 아웃은 분기, 함수 및 서브루틴을 사용하여 모든 기능이 제대로 작동하도록 하는 것입니다. 두 번째로 중요한 것은 6502 어셈블리 언어의 수학(덧셈)입니다. 특히 캐리를 사용합니다.
이 실습의 모든 작업은 , , 및 이 부분에서 찾을 수 있습니다. 어셈블리 언어를 사용하여 프로그래밍하는 방법을 제대로 생각하는 데 많은 시간이 걸렸습니다. 어셈블리 언어에서 분기 및 서브루틴에 더 능숙해지려면 아직 시간이 더 필요한 것 같습니다.

좋은 웹페이지 즐겨찾기