home *** CD-ROM | disk | FTP | other *** search
- ;-----------------------------------------------------------------------------
- ; Tetris © Copyright 1990 Software Alchemy All Rights Reserved, V0.1 28-Dec-89
- ; Code generated by Transform © 1990 Software Alchemy All Rights Reserved
- ;-----------------------------------------------------------------------------
- include 'tetris.i'
-
- ; Tetris renders to 5 bitplanes with one blit, the screen format is
- ; "interleaved" to support this. Andreas Hommel was the first person
- ; to think of this idea (CMON, GAUNTLET). S0ren Gronbech told me of
- ; of rumors to that effect (he did SWORD OF SODAN, DATASTORM ect).
- ; Interleaved bitplanes are a very common concept however, the hacker
- ; intro to BackLash uses them for example, and thats 1987 technology.
-
- ;
- ; Generate Mulu Table for rest of blits to rely upon
- ;
- MakeMulu110
- lea Mulu110(pc),a0
- moveq #0,d0
- 1$ move.w d0,(a0)+
- add.w #110*8,d0
- cmp.w #110*8*30,d0
- bne.s 1$
-
- lea Mulu44(pc),a0
- moveq #0,d0
- 2$ move.w d0,(a0)+
- add.w #44,d0
- cmp.w #44*30,d0
- bne.s 2$
- rts
-
- Mulu110 dcb.w 30,0
- Mulu44 dcb.w 30,0
-
- ;
- ; Draw a tetris tile to screen, with damage repair and teats.
- ;
- DrawBlock
-
- moveq #0,d1
- move.w d1,d0
- move.b BlockPos(a4),d1 ; D1 = Byte X
- move.b BlockPos+2(a4),d0 ; D0 = Byte Y (0-30)
-
- DrawBlockAt
-
- add.w d0,d0 ; Y * 2
-
- lea TetrisByteMap(pc),a2
- add.w Mulu44(pc,d0.w),a2
- add.w d1,a2 ; a2 = Current ByteMap Pos
-
- move.l GameVideo2(pc),a0 ; A0 = Half-Screen
- lea Mulu110(pc),a1
- add.w (a1,d0.w),a0 ; + Y * 110*8 (add 1/2)
-
- add.l a0,a0 ; A0 = Raw Screen sans X
- add.w d1,a0 ; Add X Pos
- ror.w #1,d1 ; D1 = Pixel Shift
-
- ;
- ; Repair damaged backdrop if any prior to next render (if any)
- ;
- lea BlitWorkSpace(a4),a1 ; A1 = Source/Dest of Damage
- move.l BlitRepairAddress(a4),d0 ; D0 = Blit Repair Info
- beq.s BlitSave ; (No Damage)
- BlitRepair
- btst #14-8,$02(a6) ; 680x0 stuff, force read ACK
- 1$ btst #14-8,$02(a6) ; Wait for Blitter
- bne.s 1$
- move.l d0,$54(a6) ; D0 = Old Place to repair
- move.l a1,$48(a6) ; A1 = Source, Damage Buffer
- move.w #44-6,$66(a6) ; Dest Mod
- move.w #0,$60(a6) ; Source Mod
- move.l #$03aa0000,$40(a6) ; D = C
- move.w #64*5*34+3,$58(a6) ; Do 3 words by 34 lines
-
- ;
- ; Copy a hunk of object size for damage repair, d0 = source or dest
- ;
- BlitSave
- move.l a0,BlitRepairAddress(a4) ; Will Undo to here next pass
- btst #14-8,$02(a6) ; 680x0 stuff, force read ACK
- 1$ btst #14-8,$02(a6) ; Wait for Blitter
- bne.s 1$
- move.l a0,$48(a6) ; A0 = Source (C) Damage Save
- move.l a1,$54(a6) ; DEST
- move.w #44-6,$60(a6) ; SRC Modulo (DMA C)
- move.w #0,$66(a6) ; Dest Modulo
- move.l #$03aa0000,$40(a6) ; Minterm is D = C
- move.w #64*5*34+3,$58(a6) ; Do 3 words by 34 lines
-
- ;
- ; Get a Tetris Piece detailed TileMap in (a2)
- ;
- GetPiece
- move.w BlockID(a4),d2 ; D2 = Pointer to Tile # * 2
- lsl.w #3,d2 ; (2>>3) = 16
- lea TetrisDetails(pc),a1
- lea (a1,d2.w),a1 ; A1 = Detailed TileMap
-
- add.w #2*220,a0 ; Room for Teat
-
- DrawLoop
- ;
- ; Loop thru all pieces of TileMap and render them...
- ;
- moveq #4-1,d7 ; D7 = Vertical
- 1$ moveq #4-1,d6 ; D6 = Horizontal
- 2$
- moveq #0,d0 ; (clean)
- move.b (a1)+,d0 ; D0 = Data
- beq.s 3$ ; Don't draw where nothing
- mulu #2*5*8,d0
- add.l PiecesMem(pc),d0
- bsr ContinueDraw ; Draw next piece...
- ;
- ; Render a teat here only if non-incident with tile or backdrop
- ;
-
- tst.b -44(a2) ; Allowable on bytemap?
- bne.s 3$
- tst.b -4-1(a1) ; Allowable on tile?
- bne.s 3$
- moveq #0,d0
- move.b -1(a1),d0
- or.b #7,d0 ; Get to teat data
- mulu #2*5*8,d0
- add.l PiecesMem(pc),d0
- sub.w #8*220,a0 ; (backup for teat)
- bsr ContinueDraw ; Add the teat
- add.w #8*220,a0
- 3$
-
- ;
- ; Get to Next Horizontal raw-write and bytemap position
- ;
- add.w #$8000,d1 ; Pixel Shift >>
- add.w #1,a0 ; Next Byte Also >>
- lea 1(a2),a2 ; Next HLine of ByteMap
- dbf d6,2$ ; End horizontal loop
- ;
- ; Get to next Vertical raw-write and bytemap position
- ;
- add.w #8*220-4,a0 ; Next VLine of RAW
- lea 44-4(a2),a2 ; Next VLine of ByteMap
- dbf d7,1$ ; End vertical loop
- rts
-
-
-
- ;
- ; Draw one line of tetris bytemap to screen with teats
- ; Supply Y Line #
- ;
- DrawLine
- ; D0.w = Y on ByteMap
- move.w PlayerArea2+2(a4),d1 ; D1.w = X on ByteMap
- lea TetrisByteMap(pc),a2
- add.w PlayerArea(a4),a2 ; + Active Zone
- lea Mulu44(pc),a1
- add.w d0,d0 ; Y * 2 (index)
- add.w (a1,d0.w),a2 ; + Y
- ; a2 = Current ByteMap Pos
-
- add.w #1,a2 ; Don't draw left wall
- add.w #1,d1 ; Don't draw left wall
- add.w PlayerArea2(a4),d0 ; Add Raw Vertical Offset
- add.w PlayerArea2(a4),d0
-
- move.l GameVideo2(pc),a0 ; A0 = Half-Screen
- lea Mulu110(pc),a1
- add.w (a1,d0.w),a0 ; + Y * 110*8 (add 1/2)
- add.l a0,a0 ; A0 = Raw Screen sans X
- add.w d1,a0 ; Add X Pos
- ror.w #1,d1 ; D1 = Pixel Shift
-
- add.w #2*220,a0 ; Room for Teat
-
- moveq #RECT_X-1,d2 ; D2 = Horizontal
- 2$ moveq #0,d0 ; (clean)
- move.b (a2)+,d0 ; D0 = Data
- ; (Do Draw where nothing)
- mulu #2*5*8,d0
- add.l PiecesMem(pc),d0
- bsr ContinueDraw ; Draw next piece...
-
- tst.b -1(a2) ; Anything here?
- beq.s 3$
- tst.b -44-1(a2) ; Allowable on bytemap?
- bne.s 3$
- moveq #0,d0
- move.b -1(a2),d0
- or.b #7,d0 ; Get to teat data
- mulu #2*5*8,d0
- add.l PiecesMem(pc),d0
- sub.w #8*220,a0 ; (backup for teat)
- bsr ContinueDraw ; Add the teat
- add.w #8*220,a0
- 3$ add.w #$8000,d1 ; In pixel blitter shift
- add.w #1,a0
- dbf d2,2$ ; End horizontal loop
- rts
-
-
-
-
-
-
- ;
- ; Draw one element, part of a tile, to screen
- ; Supply X,Y Byte Positions in D1,D0
- ; Object to draw is in D2.w
- ;
- DrawOne
- ; D0.w = Y on ByteMap
- ; D1.w = X on ByteMap
- lea TetrisByteMap(pc),a2
- add.w d1,a2 ; + X
- lea Mulu44(pc),a1
- add.w d0,d0 ; Y * 2 (index)
- add.w (a1,d0.w),a2 ; + Y
-
- ; a2 = Current ByteMap Pos
- and.w #$00ff,d2
- move.b d2,(a2) ; Store Element
-
- move.l GameVideo2(pc),a0 ; A0 = Half-Screen
- lea Mulu110(pc),a1
- add.w (a1,d0.w),a0 ; + Y * 110*8 (add 1/2)
- add.l a0,a0 ; A0 = Raw Screen sans X
- add.w d1,a0 ; Add X Pos
- ror.w #1,d1 ; D1 = Pixel Shift
-
- add.w #2*220,a0 ; Room for Teat
-
- move.w d2,d0
- ext.l d0 ; (clean)
- mulu #2*5*8,d0
- add.l PiecesMem(pc),d0
- bsr ContinueDraw ; Draw next piece...
-
- tst.b -44(a2) ; Put Teat above?
- bne.s 2$
- move.w d2,d0
- beq.s 2$
- sub.w #8*220,a0 ; (backup for teat if !0)
- or.b #7,d0 ; Get to teat data
- ext.l d0 ; (clean)
- mulu #2*5*8,d0
- add.l PiecesMem(pc),d0
- bra ContinueDraw ; Add the teat
- 2$ rts
-
- ; Note that the Blitter always uses Post-Increment and Post-Decrement
- ; irregardless of if you are using it backwards or forwards. Luckily
- ; however it does shift in reverse, and that is why I am using a backwards
- ; blit in this example:
-
- DrawScroller
- move.l GameVideo(pc),a0
- add.l #232*44*5-2,a0
- btst #14-8,$02(a6)
- 1$ btst #14-8,$02(a6)
- bne.s 1$
- move.l #$ffffffff,$44(a6)
- move.l a0,$50(a6)
- move.l a0,$54(a6)
- move.l #0,$64(a6)
- move.l #$89f00002,$40(a6) ; Backwards mode on
- move.w #64*5*80+22,$58(a6)
- rts
-
- DrawScrollBit
- move.l GameVideo2(pc),a0 ; A0 = Half-Screen
- lea Mulu110(pc),a1
- add.w d0,d0
- add.w (a1,d0.w),a0 ; + Y * 110*8 (add 1/2)
- add.l a0,a0 ; A0 = Raw Screen sans X
- add.w d1,a0 ; Add X Pos
- ror.w #1,d1 ; D1 = Pixel Shift
- add.w #2*220,a0 ; Room for Teat
- move.w d2,d0
- ext.l d0 ; (clean)
- mulu #2*5*8,d0
- add.l PiecesMem(pc),d0
- bra ContinueDraw
-
- DrawScrollClear
- move.l GameVideo(pc),a0
- add.l #232*44*5-2,a0
- btst #14-8,$02(a6) ; Erase Right Hand Side
- 2$ btst #14-8,$02(a6)
- bne.s 2$
- move.l a0,$54(a6)
- move.w #44-2,$66(a6)
- move.l #$01000002,$40(a6) ; (backwards also)
- move.w #64*5*80+1,$58(a6)
- rts
-
-
- ;
- ; Draw a block anywhere (Renders to all 5 planes with one blit)
- ;
- ContinueDraw
- ; A0 = Raw Dest
- ; D0 = Raw Source
- ; D1 = 16 bit Pixel Shift
-
- btst #14-8,$02(a6) ; 680x0 stuff, force read ACK
- 1$ btst #14-8,$02(a6) ; Wait for Blitter
- bne.s 1$
- move.l a0,$54(a6) ; DEST
- move.l a0,$48(a6) ; DEST READ (DMA CHANNEL C)
- move.l d0,$4c(a6) ; source grafix
- and.w #$f000,d1 ; (clean)
- move.w d1,$42(a6) ; SOURCE Shift (DMA B)
- or.w #$07ca,d1 ; Minterm = Cookie, A is OFF
- move.w d1,$40(a6) ; MASK Shifts also (DMA A)
-
- ; (these can be moved for optimization)
- move.l #$ffff0000,$44(a6) ; A MASK (Occurs before A*B)
- move.w #$ff00,$74(a6) ; Source A (acts as mask on B)
- move.w #-2,$64(a6) ; Src Modulo undoes over-blit
- move.w #-2,$62(a6)
- move.w #44-2-2,$60(a6) ; Dest Mod gets next bitplane
- move.w #44-2-2,$66(a6)
-
- move.w #64*5*8+2,$58(a6) ; Trigger 5 PLANE BLIT.
- rts
-
-
-
-
- Erase
- move.l GameVideo2(pc),a0 ; A0 = Half-Screen
- lea Mulu110(pc),a1
- add.w d0,d0 ; Y * 2
- add.w (a1,d0.w),a0 ; + Y * 110*8 (add 1/2)
-
- add.l a0,a0 ; A0 = Raw Screen sans X
- add.w d1,a0 ; Add X Pos
-
- btst #14-8,$02(a6)
- 1$ btst #14-8,$02(a6)
- bne.s 1$
- move.l a0,$54(a6)
- move.w #44-6,$66(a6)
- move.l #$01000000,$40(a6)
- move.w #64*5*34+3,$58(a6)
- rts
-
-
- ;
- ; Raisers needs a faster redraw, and one that doesn't collide with tile
- ; being moved by player.
- ;
- RaisersDraw
- sub.l #8*220,BlitRepairAddress(a4) ; hack, move up repair also
-
- move.w PlayerArea2(a4),d0
- move.w PlayerArea2+2(a4),d1
- addq.w #1,d0 ; Y++
- move.l GameVideo2(pc),a0 ; A0 = Half-Screen
- lea Mulu110(pc),a1
- add.w d0,d0
- add.w (a1,d0.w),a0 ; + Y * 110*8 (add 1/2)
- add.l a0,a0 ; A0 = Raw Screen sans X
- add.w d1,a0 ; Add X Pos
- move.l a0,a1
- add.w #16*220,a0
- add.w #8*220,a1
-
- btst #14-8,$02(a6) ; 680x0 stuff, force read ACK
- 1$ btst #14-8,$02(a6) ; Wait for Blitter
- bne.s 1$
- move.l a0,$50(a6)
- move.l a1,$54(a6)
- move.l #$ffffffff,$44(a6) ; A MASK (Occurs before A*B)
- move.w #44-RECT_X-2,$64(a6)
- move.w #44-RECT_X-2,$66(a6)
- move.l #$09f00000,$40(a6)
- move.w #(RECT_Y*8+2-8-8-8)*5*64+RECT_X/2+1,$58(a6)
- rts
-
- ;
- ; Each tetris object is made up of small pieces. Tetris
- ; has all the pieces in one color internally. The pieces
- ; must be "unpacked" into 8 colors
- ;
- ; There are 8 slots for pieces and
- ; there are 4 rotations per piece and 8 colors per rotation
- ; 8*8*4 makes exactly 256 possible pieces (index 1).
- ;
- ; Pieces are stored in a non-interleaved bitplane format 3 planes deep
- ; and there are 8*4 pieces total
- ;
- ; Pieces end up in interleaved bitplane format 5 planes deep
- ;
- ; Pieces are one byte at source
- ; Pieces are 8 tall
- ;
-
- DataSize equ 5*2*8 ; Depth*Width*Heigth
- BankEls equ 8*4 ; (pieces * rotations)
-
- UnpackPieces
- moveq #7-1,d2 ; D2 = Merge Generated Colors
- 1$ bsr UnpackBank ; Do next color...
- dbf d2,1$
- rts
-
-
- UnpackBank
- move.l PiecesMem(pc),a2 ; A2 = Base of Dest
- move.l d2,d3 ; Color #?
- mulu #BankEls*DataSize,d3 ; Get Appropriate Color Bank
- add.w d3,a2 ; A2 = Color Bank of pieces
-
- moveq #0,d5 ; D5 = Counter (and Index)
- 0$
- lea PiecesSource(pc),a0
- move.l d5,d0
- lsl.w #3,d0 ; Graphic #
- add.w d0,a0
- moveq #8-1,d4 ; D4 = Do One Object
- 1$ move.b (a0)+,(a2)+ ; Copy Black and White Info
- move.b #0,(a2)+
- move.b 256-1(a0),(a2)+ ; (next plane)
- move.b #0,(a2)+
- moveq #0,d0
- move.b 512-1(a0),d0 ; D0 = Color Info
- lsl.w #8,d0 ; (force up)
- bsr UnpackPiece
- lea 6(a2),a2 ; Skip to next set of planes
- dbf d4,1$
- add.w #1,d5
- cmp.w #BankEls,d5
- bne.s 0$
- rts
-
-
- UnpackPiece
- clr.w (a2) ; pre clean
- clr.w 2(a2)
- clr.w 4(a2)
- cmp.b #0,d2 ; moronic stupidity
- beq.s zero
- cmp.b #1,d2
- beq.s one2
- cmp.b #2,d2
- beq.s two
- cmp.b #3,d2
- beq.s three
- cmp.b #4,d2
- beq.s four
- cmp.b #5,d2
- beq.s five
- six move.w d0,(a2)
- five move.w d0,2(a2)
- three move.w d0,4(a2)
- rts
- zero move.w d0,(a2)
- rts
- two move.w d0,(a2)
- one2 move.w d0,2(a2)
- rts
- four move.w d0,(a2)
- move.w d0,4(a2)
- rts
-
- ; end of tetrisblit.s
-