英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

 找回密码
 立即注册
搜索
电子烟方案单片机单片机开发深圳单片机开发
单片机方案国产单片机8位单片机电子烟方案开发
查看: 4423|回复: 0
打印 上一主题 下一主题

使用16F84产生视频信号

[复制链接]
跳转到指定楼层
1#
发表于 2009-3-8 11:50:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
电路图
1BE.gif (6.6 KB)
2007-7-17 18:30


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
;number  0
                retlw 0x1C
                retlw 0x36
                retlw 0x63
                retlw 0x6B
                retlw 0x63
                retlw 0x36
                retlw 0x1C
                retlw 0x0
;number  1
                retlw 0x18
                retlw 0x1C
                retlw 0x18
                retlw 0x18
                retlw 0x18
                retlw 0x18
                retlw 0x7E
                retlw 0x0
;number  2
                retlw 0x3E
                retlw 0x63
                retlw 0x60
                retlw 0x38
                retlw 0xC
                retlw 0x66
                retlw 0x7F
                retlw 0x0
;number  3
                retlw 0x3E
                retlw 0x63
                retlw 0x60
                retlw 0x3C
                retlw 0x60
                retlw 0x63
                retlw 0x3E
                retlw 0x0
;number  4
                retlw 0x38
                retlw 0x3C
                retlw 0x36
                retlw 0x33
                retlw 0x7F
                retlw 0x30
                retlw 0x78
                retlw 0x0
;number  5
                retlw 0x7F
                retlw 0x3
                retlw 0x3
                retlw 0x3F
                retlw 0x60
                retlw 0x63
                retlw 0x3E
                retlw 0x0
;number  6
                retlw 0x1C
                retlw 0x6
                retlw 0x3
                retlw 0x3F
                retlw 0x63
                retlw 0x63
                retlw 0x3E
                retlw 0x0
;number  7
                retlw 0x7F
                retlw 0x63
                retlw 0x30
                retlw 0x18
                retlw 0xC
                retlw 0xC
                retlw 0xC
                retlw 0x0
;number  8
                retlw 0x3E
                retlw 0x63
                retlw 0x63
                retlw 0x3E
                retlw 0x63
                retlw 0x63
                retlw 0x3E
                retlw 0x0
;number  9
                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                        ;131  cycles
                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 下一条

小黑屋|公司首页|Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 ( 粤ICP备09008620号 )

GMT+8, 2024-11-24 02:03 , Processed in 0.056447 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表