Last active
May 18, 2017 12:43
-
-
Save gusaa960/0f4ce890318ba89fe1f1b474cc8a684c to your computer and use it in GitHub Desktop.
labb 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; | |
; | |
; Labb4.asm | |
; | |
; Created: 2017-05-15 10:55:17 | |
; Author : Gustav Aaro | |
; | |
; Replace with your application code | |
; --- lab4_skal.asm | |
.def zeroReg = r18 | |
.def row = r19 | |
.def speakerHigh = r20 | |
.equ VMEM_SZ = 5 ; #rows on display | |
.equ AD_CHAN_X = 0 ; ADC0=PA0, PORTA bit 0 X-led | |
.equ AD_CHAN_Y = 1 ; ADC1=PA1, PORTA bit 1 Y-led | |
.equ GAME_SPEED = 124 ; inter-run delay (millisecs) | |
.equ PRESCALE = 4 ; AD-prescaler value | |
.equ BEEP_PITCH = 20 ; Victory beep pitch | |
.equ BEEP_LENGTH = 100 ; Victory beep length | |
; --------------------------------------- | |
; --- Memory layout in SRAM | |
.dseg | |
.org SRAM_START | |
POSX: .byte 1 ; Own position | |
POSY: .byte 1 | |
TPOSX: .byte 1 ; Target position | |
TPOSY: .byte 1 | |
LINE: .byte 1 ; Current line | |
VMEM: .byte VMEM_SZ ; Video MEMory | |
SEED: .byte 1 ; Seed for Random | |
; --------------------------------------- | |
; --- Macros for inc/dec-rementing | |
; --- a byte in SRAM | |
.macro INCSRAM ; inc byte in SRAM | |
push r16 | |
lds r16,@0 | |
inc r16 | |
sts @0,r16 | |
pop r16 | |
.endmacro | |
.macro DECSRAM ; dec byte in SRAM | |
push r16 | |
lds r16,@0 | |
dec r16 | |
sts @0,r16 | |
pop r16 | |
.endmacro | |
; --------------------------------------- | |
; --- Code | |
.cseg | |
.org $0 | |
jmp START | |
.org INT0addr | |
jmp MUX | |
START: | |
clr row | |
clr zeroReg | |
ldi speakerHigh, 0b10000000 | |
ldi r16, HIGH(RAMEND) | |
out SPH, r16 | |
ldi r16, LOW(RAMEND) | |
out SPL, r16 | |
call HW_INIT | |
call WARM | |
RUN: | |
call JOYSTICK | |
call ERASE | |
call UPDATE | |
call DELAY | |
lds r16, POSX | |
lds r17, TPOSX | |
cp r16,r17 | |
brne NO_HIT | |
lds r16, POSY | |
lds r17, TPOSY | |
cp r16,r17 | |
brne NO_HIT | |
ldi r16,BEEP_LENGTH | |
call BEEP | |
call WARM | |
NO_HIT: | |
jmp RUN | |
; --------------------------------------- | |
; --- Multiplex display | |
; --- Uses: r16 | |
MUX: | |
push ZL | |
push ZH | |
push r17 | |
in r17, SREG | |
push r17 | |
INCSRAM SEED | |
ldi ZL, LOW(VMEM) | |
ldi ZH, HIGH(VMEM) | |
add ZL, row | |
adc ZH, zeroReg | |
ld r17, Z | |
out PORTB, zeroReg | |
out PORTA, row | |
out PORTB, r17 | |
inc row | |
cpi row, VMEM_SZ | |
brne DONE | |
clr row | |
DONE: | |
pop r17 | |
out SREG, r17 | |
pop r17 | |
pop ZH | |
pop ZL | |
reti | |
; --------------------------------------- | |
; --- JOYSTICK Sense stick and update POSX, POSY | |
JOYSTICK: | |
; X | |
ldi r16, (1<<ADEN)|(PRESCALE) | |
out ADCSRA, r16 | |
ldi r16, (1<<ADLAR)|3 | |
out ADMUX, r16 | |
sbi ADCSRA, ADSC | |
call WAIT | |
andi r16, $C0 | |
cpi r16, $C0 | |
breq INC_POSX | |
; Annars höger | |
cpi r16, $00 | |
breq DEC_POSX | |
Y_POS: | |
; Y | |
ldi r16, (1<<ADLAR)|4 | |
out ADMUX, r16 | |
sbi ADCSRA, ADSC | |
call WAIT | |
andi r16, $C0 | |
cpi r16, $C0 | |
breq INC_POSY | |
; Annars upp (?) | |
cpi r16, $00 | |
breq DEC_POSY | |
POS_DONE: | |
jmp JOY_LIM | |
WAIT: | |
; check ADSC bit, conversion complete if bit is zero | |
sbic ADCSRA, ADSC ; conversion ready? | |
jmp WAIT ; not yet | |
; read MSB of the AD conversion result, here Y-axis | |
in r16, ADCH | |
ret | |
DEC_POSX: | |
DECSRAM POSX | |
jmp Y_POS | |
INC_POSX: | |
INCSRAM POSX | |
jmp Y_POS | |
DEC_POSY: | |
DECSRAM POSY | |
jmp POS_DONE | |
INC_POSY: | |
INCSRAM POSY | |
jmp POS_DONE | |
JOY_LIM: | |
call LIMITS ; don't fall off world! | |
ret | |
; --------------------------------------- | |
; --- LIMITS Limit POSX,POSY coordinates | |
; --- Uses: r16,r17 | |
LIMITS: | |
lds r16, POSX ; variable | |
ldi r17, 7 ; upper limit+1 | |
call POS_LIM ; actual work | |
sts POSX, r16 | |
lds r16, POSY ; variable | |
ldi r17, 5 ; upper limit+1 | |
call POS_LIM ; actual work | |
sts POSY, r16 | |
ret | |
POS_LIM: | |
ori r16, 0 ; negative? | |
brmi POS_LESS ; POSX neg => add 1 | |
cp r16, r17 ; past edge | |
brne POS_OK | |
subi r16, 2 | |
POS_LESS: | |
inc r16 | |
POS_OK: | |
ret | |
; --------------------------------------- | |
; --- UPDATE VMEM | |
; --- with POSX/Y, TPOSX/Y | |
; --- Uses: r16, r17, Z | |
UPDATE: | |
clr ZH | |
ldi ZL, LOW(POSX) | |
call SETPOS | |
clr ZH | |
ldi ZL, LOW(TPOSX) | |
call SETPOS | |
ret | |
; --- SETPOS Set bit pattern of r16 into *Z | |
; --- Uses: r16, r17, Z | |
; --- 1st call Z points to POSX at entry and POSY at exit | |
; --- 2nd call Z points to TPOSX at entry and TPOSY at exit | |
SETPOS: | |
ld r17, Z+ ; r17=POSX | |
call SETBIT ; r16=bitpattern for VMEM+POSY | |
ld r17, Z ; r17=POSY Z to POSY | |
ldi ZL, LOW(VMEM) | |
add ZL, r17 ; Z=VMEM+POSY, ZL=VMEM+0..4 | |
ld r17, Z ; current line in VMEM | |
or r17, r16 ; OR on place | |
st Z, r17 ; put back into VMEM | |
ret | |
; --- SETBIT Set bit r17 on r16 | |
; --- Uses: r16, r17 | |
SETBIT: | |
ldi r16, $01 ; bit to shift | |
SETBIT_LOOP: | |
dec r17 | |
brmi SETBIT_END ; til done | |
lsl r16 ; shift | |
jmp SETBIT_LOOP | |
SETBIT_END: | |
ret | |
; --------------------------------------- | |
; --- Hardware init | |
; --- Uses: | |
HW_INIT: | |
;Konfifguration av ADC | |
ldi r16, (1<<ISC01) | |
out MCUCR, r16 | |
; Activate. Here INT1 and INT0 | |
ldi r16, (1<<INT0) | |
out GICR, r16 | |
; Enable Interrupts Globally | |
ldi r16, $FF | |
out DDRB, r16 | |
ldi r16, $7 | |
out DDRA, r16 | |
sei ; display on | |
ret | |
; --------------------------------------- | |
; --- WARM start. Set up a new game | |
; --- Uses: | |
WARM: | |
sts POSX, zeroReg | |
ldi r16, 2 | |
sts POSY, r16 | |
push r0 | |
push r0 | |
call RANDOM ; RANDOM returns TPOSX, TPOSY on stack | |
pop r21 | |
sts TPOSY, r21 | |
pop r21 | |
sts TPOSX, r21 | |
lds r21, SEED | |
call ERASE | |
ret | |
; --------------------------------------- | |
; --- RANDOM generate TPOSX, TPOSY | |
; --- in variables passed on stack. | |
; --- Usage as: | |
; --- push r0 | |
; --- push r0 | |
; --- call RANDOM | |
; --- pop TPOSX | |
; --- pop TPOSY | |
; --- Uses: r16 | |
RANDOM: | |
in r21, SPH | |
mov ZH, r21 | |
in r21, SPL | |
mov ZL, r21 | |
lds r21, SEED | |
andi r21, 0b00000111 | |
; random y-coord | |
cpi r21, 5 | |
brpl REDUCE_Y | |
PUSH_Y: | |
;sts TPOSY, r21 | |
std Z+3, r21 | |
; random x-coord | |
lds r21, SEED | |
subi r21, -7 ; Different than Y | |
andi r21, 0b00000111 | |
cpi r21, 5 | |
brpl REDUCE_X | |
PUSH_X: | |
subi r21, -2 | |
;sts TPOSX, r21 | |
std Z+4, r21 | |
ret | |
REDUCE_Y: | |
subi r21, 5 | |
jmp PUSH_Y | |
REDUCE_X: | |
subi r21, 5 | |
jmp PUSH_X | |
; --------------------------------------- | |
; --- ERASE videomemory | |
; --- Clears VMEM..VMEM+4 | |
; --- Uses: | |
ERASE: | |
ldi ZL, LOW(VMEM) | |
ldi ZH, HIGH(VMEM) | |
clr r16 | |
ERASE_ROW: | |
st Z+, zeroReg | |
inc r16 | |
cpi r16, VMEM_SZ | |
brne ERASE_ROW | |
ret | |
; --------------------------------------- | |
; --- BEEP(r16) r16 half cycles of BEEP-PITCH | |
; --- Uses: | |
BEEP: | |
ldi r16, BEEP_LENGTH | |
OUTER_BEEP: | |
ldi r17, 0 | |
INNER_BEEP: | |
sbi PORTB, 7 | |
dec r17 | |
brne INNER_BEEP | |
dec r16 | |
brne OUTER_BEEP | |
ret | |
DELAY: | |
push r16 | |
push r17 | |
ldi r16, GAME_SPEED | |
OUTER_DELAY: | |
ldi r17, 0 | |
INNER_DELAY: | |
dec r17 | |
brne INNER_DELAY | |
dec r16 | |
brne OUTER_DELAY | |
pop r17 | |
pop r16 | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment