使用16F84产生视频信号
电路图http://topsee.com.cn/bbs/images/default/attachimg.gif http://topsee.com.cn/bbs/attachment.php?aid=157&k=5796634ecb9c05d52e1e24a67d6a895f&t=1236484270&noupdate=yes http://topsee.com.cn/bbs/images/attachicons/image.gif 1BE.gif (6.6 KB)
2007-7-17 18:30
http://topsee.com.cn/bbs/images/default/attachimg.gif http://topsee.com.cn/bbs/attachment.php?aid=158&k=0f0f1f9ce67be0cff5b74402b2b5c55d&t=1236484270&noupdate=yes http://topsee.com.cn/bbs/images/attachicons/image.gif tetris.jpg (5.6 KB)
2007-7-17 18:30
F84的程序如下:
list p=16F84,r=hex
w equ 0
f equ 1
pcl equ 0x02
status equ 0x03
porta equ 0x05
portb equ 0x06
indf equ 0x00
fsr equ 0x04
eedata equ 0x08
eeadr equ 0x09
eecon1 equ 0x08
rd equ 0
rp0 equ 5
startspeed equ 0x18
movespeed equ 0x06
up1b equ 3
down1b equ 2
left1b equ 5
right1b equ 4
fire1b equ 1
up2b equ 7
down2b equ 6
left2b equ 2
right2b equ 3
fire2b equ 1
up1p equ portb
down1p equ portb
left1p equ portb
right1p equ portb
fire1p equ portb
up2p equ portb
down2p equ portb
left2p equ porta
right2p equ porta
fire2p equ porta
counter0 equ 0x0C
counter1 equ 0x0D
counter2 equ 0x0E
counter3 equ 0x0F
nextblocktyp equ 0x10
blockx equ 0x11
blocky equ 0x12
blocktyp equ 0x13
line equ 0x14
x equ 0x15
y equ 0x16
delaycnt equ 0x17
angle equ 0x18
blockstuff equ 0x19
fallcnt equ 0x1A
points equ 0x1B
random equ 0x1E
stuff equ 0x1F
m_freq equ 0x20
m_cnt equ 0x21
m_songcnt equ 0x22
buffer equ 0x24
currbl equ 0x44
x0 equ 0x4C
y0 equ 0x4D
movecnt equ 0x4E
remline equ 0x4F
hsfall equ 0
rotate equ 1
goleft equ 2
goright equ 3
drop equ 4
rotat equ 5
gameover equ 5
delay MACRO
LOCAL label
movwf delaycnt
label decfsz delaycnt
goto label
ENDM
dnop MACRO
LOCAL label
label goto label+1
ENDM
org 0x000
goto inittetris
;------------ This table contains the 3 note lengthes for the 5 speeds --------
getlength addwf pcl
retlw 0x0B
retlw 0x16
retlw 0x1D
retlw 0x09
retlw 0x12
retlw 0x19
retlw 0x07
retlw 0x0D
retlw 0x11
retlw 0x04
retlw 0x08
retlw 0x0C
retlw 0x02
retlw 0x04
retlw 0x06
;------------------------ set bit in the gamefield ----------------------------
setbit call getbit ;get bitbyte and bitmask 20 cycles
iorwf indf ;set bit
return
;----------------------- clear bit in the gamefield ---------------------------
clrbit call getbit ;get bitbyte and bitmask 21 cycles
xorlw 0xff ;invert bitmask
andwf indf ;clear bit
return
;-------------------- point at byte, and return bitmask -----------------------
getbit movlw buffer ;15 cycles
btfsc x,3
movlw buffer+1
clrc
rlf y
addwf y,w
movwf fsr ;fsr = 2*y + x<<3 + buffer
movfw x
andlw 7 ;w = x&7
bitmask addwf pcl
retlw 0x01
retlw 0x02
retlw 0x04
retlw 0x08
retlw 0x10
retlw 0x20
retlw 0x40
retlw 0x80
;------------------------ blocks in compressed format -------------------------
blocks andlw 0xF
addwf pcl
retlw 0x50
retlw 0x44
retlw 0xD0
retlw 0x0C
retlw 0xD0
retlw 0x0C
retlw 0xD0
retlw 0x3C
retlw 0xD0
retlw 0xCC
retlw 0xF4
retlw 0xC0
retlw 0x5C
retlw 0xC0
retlw 0x00
retlw 0x6C
;---------------- convert from compressed format to uncompressed --------------
convert andlw 3
addwf pcl
retlw 0
retlw 1
retlw 2
retlw -1
;------------------------- generate numbers for points ------------------------
chars movwf delaycnt ;13 cycles
clrc
rlf delaycnt
rlf delaycnt
rlf delaycnt
movfw delaycnt
addwf line,w
addwf pcl
;number0
retlw 0x1C
retlw 0x36
retlw 0x63
retlw 0x6B
retlw 0x63
retlw 0x36
retlw 0x1C
retlw 0x0
;number1
retlw 0x18
retlw 0x1C
retlw 0x18
retlw 0x18
retlw 0x18
retlw 0x18
retlw 0x7E
retlw 0x0
;number2
retlw 0x3E
retlw 0x63
retlw 0x60
retlw 0x38
retlw 0xC
retlw 0x66
retlw 0x7F
retlw 0x0
;number3
retlw 0x3E
retlw 0x63
retlw 0x60
retlw 0x3C
retlw 0x60
retlw 0x63
retlw 0x3E
retlw 0x0
;number4
retlw 0x38
retlw 0x3C
retlw 0x36
retlw 0x33
retlw 0x7F
retlw 0x30
retlw 0x78
retlw 0x0
;number5
retlw 0x7F
retlw 0x3
retlw 0x3
retlw 0x3F
retlw 0x60
retlw 0x63
retlw 0x3E
retlw 0x0
;number6
retlw 0x1C
retlw 0x6
retlw 0x3
retlw 0x3F
retlw 0x63
retlw 0x63
retlw 0x3E
retlw 0x0
;number7
retlw 0x7F
retlw 0x63
retlw 0x30
retlw 0x18
retlw 0xC
retlw 0xC
retlw 0xC
retlw 0x0
;number8
retlw 0x3E
retlw 0x63
retlw 0x63
retlw 0x3E
retlw 0x63
retlw 0x63
retlw 0x3E
retlw 0x0
;number9
retlw 0x3E
retlw 0x63
retlw 0x63
retlw 0x7E
retlw 0x60
retlw 0x30
retlw 0x1E
retlw 0x0
;-------------------------- vertical syncing stuff ----------------------------
shortsync movwf counter1
shortsync_l0 bcf porta,0 ;2us sync
bcf portb,0
dnop
movlw 0x1D - 5 ;30us black
movwf counter2
nop
bsf porta,0
shortsync_l1 decfsz counter2
goto shortsync_l1
call sound
decfsz counter1
goto shortsync_l0
retlw 5
vertsync movlw 5
btfss stuff,7
movlw 6
call shortsync
btfss stuff,7
goto opage
bcf stuff,7
opager
longsync movwf counter1
longsync_l0 movlw 0x1D - 5
movwf counter2
bcf porta,0 ;30 us sync
bcf portb,0
longsync_l1 decfsz counter2
goto longsync_l1
nop ;2us black
call sound
bsf portb,0
nop
decfsz counter1
goto longsync_l0
movlw 5
btfss stuff,7
movlw 4
call shortsync
return
opage bsf stuff,7
goto opager
;----------------- routines for displaying whole empty lines ------------------
emptylines movwf counter1
dnop
nop
ell bcf porta,0
dnop
ell2 nop
movlw 2
delay
movlw 10
bsf porta,0
delay
call sound
movlw 0x20
delay
call sound
nop
decfsz counter1
goto ell
movlw 3
bcf porta,0
delay
nop
movlw 0x10
bsf porta,0
delay
call sound
movlw 0x1D
delay
dnop
call sound
return
;-- routine for testing if it is possible to place the block on position x,y --
test movlw 4 ;131cycles
movwf counter2 ;hitcounter = 4
movwf counter0 ;test 4 bits
movlw currbl ;point at current block
movwf fsr ;with fsr
testl movfw blockx
addwf indf,w
incf fsr
movwf x ;x = x0 + blockdiffx
movfw blocky
addwf indf,w
incf fsr
movwf y ;y = y0 + blockdiffy
movfw fsr
movwf counter1 ;save fsr
call getbit ;get bit
andwf indf,w ;test bit
skpnz
decf counter0
movfw counter1 ;restore fsr
movwf fsr
decfsz counter2
goto testl
movf counter0 ;set Z if ok
return
;################### HERE STARTS THE MAIN THREAD OF TETRIS ####################
tetrismain call vertsync ;do vertical retrace
btfsc stuff,gameover
goto nogame
call createnext ;create the preview image (line 0)
call remblock ;hide the preview image (line 1)
call createcurrent ;create the current image (line 2)
call remblock ;hide the current image (line 3)
;----------------------------- make block fall -------------------------------
call hsync ;horizontal sync (line 4)
btfsc blockstuff,hsfall ;check for high speed fall (drop)
goto fall
decfsz fallcnt ;decrease fallcounter
goto nofall ;if not zero, then dont fall
fall
movfw points ;calculate speed from the most
sublw 0xa ;significant digit of the score
movwf fallcnt
rlf fallcnt
rlf fallcnt
incf blocky ;move block down
call test ;check if it was ok
skpnz
goto fallok ;if ok, skip the newblock below
movlw 0x0B
delay
decf blocky
call showblock ;make the old block visible (line 5)
call hsync ;horizontal sync (line 6)
newblock clrf blockstuff
movlw 0x9
movwf blockx ;blockx = 9
movlw 0x1
movwf blocky ;blocky = 1
movfw nextblocktyp
movwf blocktyp ;blocktyp = nexttyp
movfw random
movwf nextblocktyp ;nexttyp = random
clrf angle ;angle = 0
call incpoints ;add one point
bcf blockstuff,hsfall
movfw y0
sublw 1
skpnz ;if y = 1 then
bsf stuff,gameover ;game over
nofallret
;----------------------------- joystick motion --------------------------------
btfss left1p,left1b ;check left
bsf blockstuff,goleft
btfss right1p,right1b ;check right
bsf blockstuff,goright
btfss fire1p,fire1b ;check fire (rotate)
bsf blockstuff,rotate
btfss down1p,down1b ;check down (drop)
bsf blockstuff,drop
btfss stuff,1 ;rotate last time ?
goto norotate ;yes, wait for release
btfsc blockstuff,rotate ;check rotate
bsf blockstuff,rotat ;if rotate start rotate
btfsc blockstuff,rotate ;check rotate
bcf stuff,1 ;if rotation then remember it
nop
norotater bcf blockstuff,rotate ;clear rotation indicator
btfss stuff,2 ;down last time ?
goto nofallu ;yes, wait for release
btfsc blockstuff,drop ;check down
bsf blockstuff,hsfall ;if down start fall
btfsc blockstuff,drop ;check down
bcf stuff,2 ;if down then remember it
nop
nofallur bcf blockstuff,drop ;and clear down indicator
movlw 0x23 ;wait 33us for line to end
delay
nop
;--------------------------- handle rotation ----------------------------------
btfss blockstuff,rotat ;rotate ?
goto norot ;no, skip all rotation stuff
incf angle ;try to increase angle
call createcurrent ;make block image for this angle (line 7)
call hsync
call test ;ok ?
skpz
decf angle ;no undo angle change
movlw 0xC
delay
incf random
movlw 7
andwf random
dnop
call createcurrent ;create block (line 8)
norotr call hsync ; (line 9)
bcf blockstuff,rotat ;rotate one step only
bcf blockstuff,rotate
;---------------------- move block, left and right ----------------------------
btfsc blockstuff,goleft
decf blockx
btfsc blockstuff,goright
incf blockx
movlw 0x38
delay
call createcurrent ;create current block image (line 10)
call hsync ;horizontal sync (line 11)
call test
skpnz
goto moveok ;if ok skip restore
dnop
dnop
dnop
nomove btfsc blockstuff,goleft
incf blockx
btfsc blockstuff,goright
decf blockx
movlw 0x2e
dnop
dnop
moveokret movlw 0x8
delay
bcf blockstuff,goleft ;clear move left indicator
bcf blockstuff,goright ;clear move right indicator
;---------------- search for filled line in the 8 first lines ---------------
bcf porta,0 ;start sync (line 12)
dnop
dnop
movlw 8 ;check the first 8 lines this scanline
movwf counter0
movlw buffer ;set up pointer to screen buffer
movwf fsr
clrf line
dnop
bsf porta,0 ;end sync
movlw 6 ;wait for 6 uS
delay
clrf remline
remfilledl11 movfw indf ;get first byte of line
incf fsr ;move pointer to next byte
sublw 0xF0 ;is it "filled" ?
skpz
goto nofilled11 ;nope, we're outa here
movfw indf ;get second byte of line
incf fsr ;move pointer to next byte (next line)
sublw 0xFF ;is it "filled" ?
skpz
goto nofilled21 ;nope, we're outa here
movfw line
movwf remline ;save line nr
nop
nofilledr1 incf line ;count up line nr
decfsz counter0
goto remfilledl11
;------------ search for filled line in the following 7 lines -------------
bcf porta,0 ;start sync (line 13)
movlw 3
delay
movlw 7 ;check next 7 lines this scanline
bsf porta,0 ;end sync
movwf counter0
remfilledl12 movfw indf ;get first byte of line
incf fsr ;move pointer to next byte
sublw 0xF0 ;is it "filled" ?
skpz
goto nofilled12 ;nope, we're outa here
movfw indf ;get second byte of line
incf fsr ;move pointer to next byte (next line)
sublw 0xFF ;is it "filled" ?
skpz
goto nofilled22 ;nope, we're outa here
movfw line
movwf remline ;save line nr
nop
nofilledr2 incf line ;count up line nr
decfsz counter0
goto remfilledl12
movlw 0x0B ;wait for 12 uS
delay
; ---------- if one line is going to be removed, add lots of points -----------
call hsync ; (line 14)
movf remline
skpnz
goto noaddpoints
call incpoints
call incpoints
call incpoints
call incpoints
call incpoints
call incpoints
call incpoints
noaddpointsr
; --------------- remove line part 1: if neccessary, remove 15 blocks ---------
bcf porta,0 ;start sync (line 15)
movlw 0x10 ;remove all crap at top of screen
movwf buffer
movlw 0x80
movwf buffer + 1
dnop
movfw remline
addwf remline,w
movwf counter0 ;half lines to be removed = 2*remline
addlw buffer + 1 ;start pointer = 2*remline + buffer base + 1
movwf fsr
bsf porta,0 ;end sync
movlw 0xF
subwf counter0,w
movwf counter2
movwf counter3
btfsc counter2,7 ;do we only have to move less than 15 blocks ?
goto remshort ;yes, skip this part
movlw 0xF ;else remove 15 lines first
movwf counter0
remfilledl21 decf fsr ;move blocks two steps in buffer
decf fsr
movfw indf ;get data at fsr - 2
incf fsr ;move back again
incf fsr
movwf indf ;put it at fsr
decf fsr ;point to next block to move
decfsz counter0
goto remfilledl21
movlw 0x7 ;wait 7us for line to end
delay
; --------------- remove line part 2: remove the other blocks -------------
remshortr: bcf porta,0 ;start sync (line 16)
movlw 3
delay
nop
bsf porta,0 ;end sync
btfsc counter3,7 ;if lines to draw is less than zero
goto noremfilled ;then don't draw any lines
remfilledl31 decf fsr ;move blocks two steps in buffer (uses counter1 * 10)
decf fsr
movfw indf ;get data at fsr - 2
incf fsr
incf fsr
movwf indf ;put it at fsr
decf fsr ;fsr++
decfsz counter2
goto remfilledl31
movfw counter3 ;calc wait time
sublw 0xF + 2
movwf counter1
remfilledl32 movlw 2 ;wait for ((15+2)-counter3)*10 cycles
delay
decfsz counter1
goto remfilledl32
dnop
dnop
dnop
noremfilledr
;-------------------------- some block image management -----------------------
call createcurrent ;(line 17)
call showblock ;(line 18)
call createnext ;(line 19)
call showblock ;(line 20)
;---------------------- start drawing the graphics on screen ------------------
nogamer movlw 0x12 ;18 empty lines at top of screen
movwf counter1
bcf porta,0
call ell2
movlw 0x0
tris portb
clrf portb
movlw buffer ;set up pointer to buffer
movwf fsr
movlw 0x10 ;16 blocklines (each 11+2 lines)
movwf counter2
tml0 movlw 0xb ;11 lines for each block
movwf counter3
tml1 bcf porta,0 ;start sync
movlw 3 ;keep low for 4us
delay
nop
bsf porta,0
nop ;colorburst + black(15.67 us)
movlw 0x0F - 5
delay
call sound
movfw indf ;get left byte of gfx
movwf portb ;start showing first bit
movlw 7 ;set up counter for next 7 bits
movwf counter0
incf fsr ;point at right gfx byte
db0 bcf portb,0 ;one black vertical line between the blocks
rrf portb ;show next bit
decfsz counter0 ;keep on looping, showing all bits
goto db0
movfw indf ;get right byte of gfx
bcf portb,0 ;one black vertical line between the blocks
movwf portb ;start showing first bit
movlw 7 ;set up counter for next 7 bits
movwf counter0
decf fsr ;point at left gfxbyte again
db1 bcf portb,0 ;one black vertical line between the blocks
rrf portb ;show next bit
decfsz counter0 ;keep on looping, showing all bits
goto db1
movlw 0xF - 5
bcf portb,0 ;set level to black
delay ;for 16us
call sound
nop
movlw 2 ;prepare for 2 emptylines
movwf counter1
decfsz counter3
goto tml1 ;do all 12 lines
bcf porta,0
call ell2 ;do 2 emptylines
dnop
incf fsr ;point at next line (each line is 2 bytes)
incf fsr
decfsz counter2 ;do all 16 blocklines
goto tml0
;------------------------------- display score --------------------------------
clrf line
call hsync
movlw 0x39
delay
nop
movlw 8
movwf counter2
shpl call hsync
movlw 0x18
delay
call showp
movlw 4
delay
call hsync
movlw 0x18
delay
call showp
movlw 2
delay
dnop
incf line
decfsz counter2
goto shpl
;--------------- some empty lines, and also some random stuff -----------------
movlw 0x2A ;empty lines at bottom of screen
movwf counter1
call ell
call music
movlw 1
btfsc stuff,gameover
movwf m_freq
movlw 0xFE
tris portb
incf random
movlw 7
andwf random
movf movecnt
skpz
decf movecnt
goto tetrismain ;next frame
;################ THIS IS THE END OF THE MAIN THREAD OF TETRIS ################
;--------------------------- create next block stuff --------------------------
createnext bcf porta,0 ;start sync
movfw blocktyp
movwf counter3 ;save current block kind
movfw nextblocktyp
movwf blocktyp ;set the next block kind
movfw angle
movwf delaycnt
clrf angle
movlw 1 ;set x and ypos, they
movwf x0 ;are not used here,
movlw 2 ;but we will need them later
movwf y0
bsf porta,0 ;end sync
call makeblock ;create block
movfw counter3
movwf blocktyp
movfw delaycnt
movwf angle
return
;------------------ create current block stuff scan line ---------------------
createcurrent bcf porta,0 ;start sync
movlw 0x2
delay
movfw blockx ;x0 anf y0 are not
movwf x0 ;used here, but we will use
movfw blocky ;them later
movwf y0
bsf porta,0 ;end sync
call makeblock
return
;------------------------ remove big block scan line -------------------------
remblock bcf porta,0 ;start sync
movlw 3
delay
nop
bsf porta,0 ;end sync
movlw 4
movwf counter0
movlw currbl
movwf fsr
hbl movfw x0
addwf indf,w
incf fsr
movwf x ;x = x0 + relx
movfw y0
addwf indf,w
incf fsr
movwf y ;y = y0 + rely
movfw fsr
movwf counter1
call clrbit
movfw counter1
movwf fsr
decfsz counter0
goto hbl
movlw 9
delay
return
;--------------------------- show block scan line ----------------------------
showblock bcf porta,0 ;start sync
movlw 3
delay
movlw 4
bsf porta,0 ;end sync
movwf counter0
movlw currbl
movwf fsr
sbl movfw x0
addwf indf,w
incf fsr
movwf x ;x = x0 + relx
movfw y0
addwf indf,w
incf fsr
movwf y ;y = y0 + rely
movfw fsr
movwf counter1
call setbit
movfw counter1
movwf fsr
decfsz counter0
goto sbl
movlw 0xA
delay
return
;------------------------- output one sync pulse ------------------------------
;17 cycles
hsync bcf porta,0
movlw 3
delay
nop
bsf porta,0 ;end sync
return
;-------------------------- add one point to score ----------------------------
incpoints incf points + 2 ;25 cycles
movfw points + 2
sublw 0xA
skpz
goto firstok
clrf points + 2
incf points + 1
movfw points + 1
sublw 0xA
skpz
goto secondok
clrf points + 1
incf points
movlw 2
delay
return
firstok nop
dnop
dnop
secondok dnop
movlw 3
delay
return
;------------------------- part of line of score ------------------------------
showp movfw points + 2 ;89 cycles
call chars
movwf counter1
movfw points + 1
call chars
movwf counter0
movfw points
call chars
call shiftout
movfw counter0
call shiftout
movfw counter1
call shiftout
return
;----------- routine used by showp to shift out one byte to display -----------
shiftout movwf portb ;13 cycles
rrf portb
rrf portb
rrf portb
rrf portb
rrf portb
rrf portb
rrf portb
bcf portb,0
return
;-------- makeblock creates a block of blocktype into the image buffer -------
;167 cycles
makeblock
movlw 3 ;keep angle 0-3
andwf angle
movf blocktyp ;if blocktype = 0
skpnz
clrf angle ;then dont allow rotation
bcf stuff,3 ;clear x-mirror flag
bcf stuff,4 ;clear y-mirror flag
btfsc angle,1 ;if angle = 2 or 3
bsf stuff,4 ;then set y-mirror flag
movfw angle
xorlw 1 ;if angle = 1
skpnz
bsf stuff,3 ;then set x-mirror flag
xorlw 1+2 ;if angle = 2
skpnz
bsf stuff,3 ;then set x-mirror flag
clrc
rlf blocktyp,w ;pointer = blocktyp * 2
call blocks ;get x-blockinfo from pointer
movwf counter0 ;save x-blockinfo
clrc
rlf blocktyp,w
addlw 1 ;pointer = blocktyp * 2 + 1
call blocks ;get y-blockinfo from pointer
movwf counter1 ;save y-blockinfo
btfss angle,0 ;if angle = 1, or angle = 3
goto mbnoswap
xorwf counter0,w ;then swap x and y blockinfo
xorwf counter1
xorwf counter0
mbnoswapr movlw 4
movwf counter2 ;we have 4 coordinat pairs per block
movlw currbl
movwf fsr ;setup pointer to image buffer
mbl0 movfw counter0 ;get x-blockinfo
call convert ;convert the two first bits into a coordinat value
btfsc stuff,3 ;if x-mirror flag = 1
sublw 0 ;then make the x-coordinate negative
movwf indf ;save x-coordinate in image buffer
incf fsr ;move pointer to next position in image buffer
movfw counter1 ;get y-block info
call convert ;convert the two first bits into a coordinate value
btfsc stuff,4 ;if y-mirror flag = 1
sublw 0 ;then make the y-coordinate negative
movwf indf ;save y-coordinate in image buffer
incf fsr ;move pointer to next position in image buffer
rrf counter0 ;rotate x-blockinfo to the next two bits
rrf counter0
rrf counter1 ;rotate y-blockinfo to the next two bits
rrf counter1
decfsz counter2 ;do all 4 coordinate pairs
goto mbl0
return
;--------------------- initialize tetris, clear stuff -------------------------
inittetris movlw 0x0D
movwf fsr
movlw 0x43
movwf counter0
cllp clrf indf
incf fsr
decfsz counter0
goto cllp
movlw buffer ;point to buffer
movwf fsr
movlw 0xf ;15 blocklines
movwf counter0
itl0 movlw 0x10 ;left block: ....*...
movwf indf
incf fsr ;point to next block
movlw 0x80 ;right block: .......*
movwf indf
incf fsr ;point to next block
decfsz counter0 ;do all 15 lines
goto itl0
movlw 0xf0 ;bottom left ....****
movwf buffer + 0x1E
movlw 0xff ;bottom right ********
movwf buffer + 0x1F
movlw 0xE
tris porta
movlw 0xFE
tris portb
movlw 1
movwf fallcnt ;fallcount = 1
movwf movecnt ;move count = 1
movwf m_songcnt ;song count = 1
clrf eeadr
call createcurrent
goto newblock
;------------------------------ delay stuff -----------------------------------
noaddpoints movlw 0x39
delay
goto noaddpointsr
nofall movlw 0x2D
delay
dnop
fallok movlw 0xB
delay
call hsync
movlw 0x3A
delay
call hsync
movlw 0xC
delay
nop
goto nofallret
moveok nop
movf movecnt
skpz
goto nomove
movlw movespeed
movwf movecnt
incf random
movlw 7
andwf random
dnop
goto moveokret
nofilled11 incf fsr
nop
dnop
nofilled21 goto nofilledr1
nofilled12 incf fsr
nop
dnop
nofilled22 goto nofilledr2
remshort movlw 0x36 ;wait 56us for sync to end
delay
dnop
movfw counter0
movwf counter2
movwf counter3
skpnz
bsf counter3,7
goto remshortr ;then continue removing lines
noremfilled movlw 0x39 ;wait 59us for sync to end
delay
dnop
goto noremfilledr ;no lines removed, continue and stuff..
norot call createcurrent
call createcurrent
call hsync
movlw 0x39
delay
nop
goto norotr
nofallu btfss blockstuff,drop
bsf stuff,2
goto nofallur
norotate btfss blockstuff,rotate
bsf stuff,1
goto norotater
mbnoswap goto mbnoswapr
nogame call hsync
btfss fire1p,fire1b
goto inittetris
movlw 0x14
call emptylines
goto nogamer
;---------------------------- Sound output routine---------------------------
;15 cycles
sound bsf porta,4 ;set sound output to 1
btfss stuff,6 ;check sound state
bcf porta,4 ;if soundstate is 0 then sound output should be 0
movfw m_freq ;get current frequency
decfsz m_cnt ;decrease sound counter, check if it becomes zero
goto soundsk
movwf m_cnt ;if zero, set music counter to current frequency
btfsc stuff,6
goto skstuff
nop
bsf stuff,6
return
skstuff bcf stuff,6
return
soundsk dnop
dnop
return
;------------------------ Set frequency (music routine) -----------------------
music call hsync
movlw 0x36 ;prepare for some long delay or something
decfsz m_songcnt ;update music counter
goto nochnote ;if not zero, dont update
bsf status,rp0 ;setup some eeprom read stuff
bsf eecon1,rd
bcf status,rp0
movf m_freq ;check current frequency
skpz
goto pause ;if freq is not zero, make a pause
movfw eedata ;get one note
andlw 0x3F ;mask out frequenvy
movwf m_freq ;store it
swapf eedata,w ;get note + length, swap upper and lower part into w
andlw 0xC ;mask out length
movwf counter3
clrc
rrf counter3 ;rotate down the length
rrf counter3
clrc
rrf points,w
movwf delaycnt
clrc
rlf delaycnt
addwf delaycnt,w ;points/2*3
addwf counter3,w ;points/2*3 + shortlength
call getlength ;get real length
movwf m_songcnt
incf eeadr ;next song position
movfw eeadr
sublw 0x34 ;end of song ?
skpnz
clrf eeadr ;if so, restart song
movlw 0x2B ;this delay is not very critical
nochnote delay
return
pause clrf m_freq
movlw 2
movwf m_songcnt
movlw 0x2B + 5
goto nochnote
;------------------------- the song: karaboschka ------------------------------
m_d3 equ 0x35 ; note definitions
m_e3 equ 0x2F
m_f3 equ 0x2D
m_g3 equ 0x28
m_a3 equ 0x24
m_b3x equ 0x21
m_c4 equ 0x1E
m_d4 equ 0x1B
m_l4 equ 0x00 ; length definition
m_l2 equ 0x40
m_l2x equ 0x80
org 0x2100
dw m_a3+m_l2
dw m_e3+m_l4
dw m_f3+m_l4
dw m_g3+m_l2
dw m_f3+m_l4
dw m_e3+m_l4
dw m_d3+m_l2x
dw m_f3+m_l4
dw m_a3+m_l2
dw m_g3+m_l4
dw m_f3+m_l4
dw m_e3+m_l2x
dw m_f3+m_l4
dw m_g3+m_l2
dw m_a3+m_l2
dw m_f3+m_l2
dw m_d3+m_l2
dw m_d3+m_l2
dw m_b3x +m_l2x
dw m_c4+m_l4
dw m_d4+m_l2
dw m_c4+m_l4
dw m_b3x +m_l4
dw m_a3+m_l2x
dw m_f3+m_l4
dw m_a3+m_l2
dw m_g3+m_l4
dw m_f3+m_l4
dw m_e3+m_l2x
dw m_f3+m_l4
dw m_g3+m_l2
dw m_a3+m_l2
dw m_f3+m_l2
dw m_d3+m_l2
dw m_d3+m_l2
dw m_b3x +m_l2x
dw m_c4+m_l4
dw m_d4+m_l2
dw m_c4+m_l4
dw m_b3x +m_l4
dw m_a3+m_l2x
dw m_f3+m_l4
dw m_a3+m_l2
dw m_g3+m_l4
dw m_f3+m_l4
dw m_e3+m_l2x
dw m_f3+m_l4
dw m_g3+m_l2
dw m_a3+m_l2
dw m_f3+m_l2
dw m_d3+m_l2
dw m_d3+m_l2
;--------------------------- configuration word --------------------------------
org 0x2007
dw 0xFA ;osc_HS + WDT_off + pwrtmr_off + cp_off
dw 0xFF
end
页:
[1]