home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Games 1995 January
/
amigagames-1995-01.iso
/
archive
/
spiele
/
publicdomain
/
sk003.dms
/
sk003.adf
/
src
/
tetrisblit.s
< prev
next >
Wrap
Text File
|
2001-01-01
|
12KB
|
474 lines
;-----------------------------------------------------------------------------
; 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