winnie 发表于 2009-3-8 11:50:46

使用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]
查看完整版本: 使用16F84产生视频信号