; ; Csabo's 1K Tetris ; Written by Csaba Pankaczy ; aka Csabo/LOD ; ; Finished 2002.09.14 ; ORG $1001 - 2 DW $1001 ; DW $100D,0 DB $9E,"4109" DB 0,0,0 ; ; --- Variables ; z = $62 paddr = $64 ppos = $C2 ppos2 = $C4 ppos3 = $C6 lastrandom = $CA speed = $CB speedw = $CC width = $CD keyrep = $D0 pieces = $3900 char_space = $00 char_current = $41 char_block = $81 char_wall = $02 ScorePos = $0F85 GameOverPos = $0FCF ; One piece 4x4 = 16 bytes ; 4 rotationsx4 = 64 bytes Start ; LDX #$04 ; put this to "paddr" LDA #pieces >> 8 JSR $9534 ; 64=X 63=Y 65=A 62,Y=0 RTS ; SEI STA $FF3F ; TYA STY $FF15 ; screen color black STY $FF19 ; LDX #$38 STX z+1 LDX #$07 JSR fill ; clear char bitmap mem ; LDX #$07 tet20 LDA t_chars,x STA $3808,x EOR #$FF STA $3810,x DEX BPL tet20 ; ;=============== ; LDX #$06 tet1 LDA PieceData,x LDY #7 tet4 LSR A BCC tet3 PHA LDA #$01 STA (paddr),y PLA tet3 DEY BPL tet4 ; INC paddr+1 DEX BPL tet1 ; ;--------------- ; ;LDX #$00 ; no need to init X - it will count from $FF ; tet33 TXA PHA ; LDX #$02 LDA #$00 STA tet31 + 1 ; tet34 LDA tet31 + 1 STA tet30 + 1 CLC ADC #$40 STA tet31 + 1 TXA PHA ; LDX #$00 tet32 STX z ; LDY #$03 tet30 LDA $3900,y tet31 STA $3940,x TXA CLC ADC #$04 TAX DEY BPL tet30 ; LDA tet30 + 1 CLC ADC #$04 STA tet30 + 1 ; LDX z INX CPX #$04 BNE tet32 ; PLA TAX DEX BPL tet34 ; INC tet30 + 2 INC tet31 + 2 PLA TAX INX CPX #$06 ; 6 = 7 shapes (counts from $FF to $05) BNE tet33 ; ;================== ; LDA #10 STA width ; LDA #$12 LDX #irq & 255 ;LDY #irq >> 8 ; IRQ is $12xx STA $FF0B STX $FFFE STA $FFFF ; LDA #$5B STA $FF06 ; CLI ; Restart JSR redraw ; ; --------------------------------------------------------------- ; Game Loop ; l2 JSR randompiece ; l1 JSR draw_current ; JSR twait ; JSR check_down BNE l0 JSR erase_piece ; ;--------- LDA ppos ; move this piece down... CLC ADC #40 STA ppos BCC tet_noi2 INC ppos+1 tet_noi2 ;--------- ; JMP l1 ; l0 JSR draw_block ; this piece has landed... ; ; ================= ; LDA ppos CMP #4 * 40 BCS tet47 LDA ppos+1 CMP #$0C BNE tet47 ; ; *************** Game over ***************** ; LDX #9 go1 LDA GameOver,x STA GameOverPos,x LDA #$52 STA GameOverPos-$400,x DEX BPL go1 ; waitspc LDA #$7F JSR KeyCheck CMP #$EF BNE waitspc JMP Restart ; ; ***************** ; tet47 LDY #$00 ; go left until we find wall ; tet47a LDA (ppos),y CMP #char_wall BEQ tet40 ; LDA ppos SEC SBC #$01 STA ppos BCS tet47a DEC ppos + 1 BNE tet47a ; tet40 LDX #$03 tet43 TXA PHA ; LDY #$00 tet41 INY LDA (ppos),y AND #$03 CMP #$01 BEQ tet41 ; DEY CPY width BNE tet42 ;-----------! JSR remove_line ;-----------! tet42 LDA ppos CLC ADC #40 STA ppos BCC tet_noi7 INC ppos+1 tet_noi7 PLA TAX DEX BPL tet43 ; ; ***************** ; JMP l2 ; ;========================================================================== redraw ; LDX #$08 STX ppos2 + 1 ; STX z+1 DEX LDA #$00 STA z JSR fill ; clear color & video mem ; ; --- ; LDX #$11 ; rd1 LDA Tetris,x STA $0C0B,x ; LDA #$55 STA $080B,x ; CPX #$0A BCS rd2 ; LDA Lines,x STA ScorePos - 6,x ; LDA #$66 STA ScorePos - $400 - 6,x ; rd2 DEX BPL rd1 ; LDA #40 SEC SBC width LSR a CLC ADC #40 * 4 - 1 STA ppos STA ppos2 ;LDA #$08 ;STA ppos2 + 1 LDA #$0C STA ppos + 1 ; LDA #$77 STA z ; LDX #15 ; tet6 LDY #00 LDA #char_wall STA (ppos),y LDA z STA (ppos2),y LDY width INY STA (ppos2),y LDA #char_wall STA (ppos),y ; LDA ppos CLC ADC #40 STA ppos STA ppos2 BCC tet_noi1 INC ppos+1 INC ppos2+1 tet_noi1 TXA AND #$01 BNE tet2 LDA z SEC SBC #$10 STA z tet2 DEX BPL tet6 ; LDY width INY tet7 LDA #char_wall STA (ppos),y LDA #$07 STA (ppos2),y DEY BPL tet7 RTS ; ;========================================================================== remove_line LDX #$03 sc1 INC ScorePos,x LDA ScorePos,x CMP #$3A BNE t1 LDA #$30 STA ScorePos,x DEX BNE sc1 ; ; --- ; t1 LDA ppos STA ppos3 LDA ppos + 1 STA ppos3 + 1 ; tet62 LDA ppos3 + 1 STA ppos2 + 1 LDA ppos3 STA ppos2 SEC SBC #40 STA ppos3 BCS tet_noi8 DEC ppos3 + 1 tet_noi8 ; LDY width tet61 LDA (ppos3),y STA (ppos2),y LDA #char_space STA (ppos3),y DEY BNE tet61 ; JSR wait_sync ; LDA (ppos2),y CMP #char_wall BEQ tet62 ; RTS ; ;========================================================================== ; ; high byte is not stored, ; all must be within $12xx kjump DB cursor_right & 255,cursor_left & 255 DB cursor_up & 255,cursor_down & 255 DB inc_width & 255,dec_width & 255 ; get_keys LDX #key2 - key1 - 1 gk1 LDA key1,x JSR KeyCheck rk AND key2,x ; BNE not_pressed ; DEC keyrep,x BNE gk4 ; TXA PHA ; LDA kjump,x STA gk2 + 1 ; only low byte ; ; gk2 JSR cursor_right ; self-mod ; PLA TAX LDA #$08 ; key-delay. lower number means ; keys are more responsive DB $2C ; skip next 2 bytes ; not_pressed LDA #$01 STA keyrep,x ; gk4 DEX BPL gk1 RTS ; ; ------------------------------ ; cursor_right ;---------------- Cursor Right JSR check_right BNE tg1 ; JSR erase_piece INC ppos BNE tet_noi5a INC ppos+1 BNE tet_noi5a ; cursor_left ;--------------- Cursor Left tleft JSR check_left BNE tg1 ; JSR erase_piece LDA ppos BNE tet_noi5 DEC ppos+1 tet_noi5 DEC ppos tet_noi5a JSR draw_current ; tg1 RTS ; cursor_up ;----------------- Cursor up (rotate) JSR erase_piece ; LDA paddr CLC ADC #$40 STA paddr ; JSR check BEQ good_rotation ; LDA paddr SEC SBC #$40 STA paddr good_rotation JSR draw_current ; RTS ; inc_width ;----------------- 1 LDX width CPX #38 BEQ tet48 INX INX tet49 STX width JSR redraw JSR randompiece tet48 RTS ; dec_width ;----------------- 2 LDX width DEX DEX CPX #2 BNE tet49 RTS ; ;================================================================ ; *** IRQ *** ; irq PHA TXA PHA TYA PHA ; ASL $FF09 ; LDA #$00 STA $FF12 LDA #$38 STA $FF13 ; LDA #$13 ; number of rows STA $f0 ; LDA #$B0 ; tet72 LDY #$07 ; 8 lines tet71 LDX tetris_colors,y tet70 CMP $FF1E BCS tet70 STX $FF17 ; raster DEY BPL tet71 ; DEC $F0 BPL tet72 ; LDA #$C4 STA $FF12 LDA #$D1 STA $FF13 ; PLA TAY PLA TAX PLA RTI ;========================================================================= randompiece LDA $FF00 AND #$03 CLC ADC lastrandom AND #$07 BEQ randompiece STA lastrandom CLC ADC #(pieces >> 8) - 1 ; ;LDA #$3E ; cheat!! ; STA paddr + 1 ; LDA #$00 STA paddr ; LDA #20 - 2 + 3 * 40 STA ppos LDA #$0C STA ppos+1 ; LDA #$0F ; adjust speed DB $2C cursor_down ;----------------- Cursor Down (drop) LDA #$01 STA speed ; RTS KeyCheck STA $FD30 STA $FF08 LDA $FF08 RTS twait LDA speed STA speedw ; s1 LDA #$BC JSR comp1 ; JSR wait_sync ; JSR get_keys ; DEC speedw BNE s1 RTS t_chars DB $80,$80,$80,$80,$80,$80,$80,$FF Lines DB $C,$9,$E,$5,$13,$20,$30,$30,$30,$30 GameOver DB $7,$1,$D,$5,$20,$20,$F,$16,$5,$12 Tetris DB $3,$13,$1,$2,$F,"'",$13,$20,$20 DB $31,$B,$20,$14,$5,$14,$12,$9,$13 PieceData DB $F0 ; long DB $66 ; square DB $2E ; L DB $47 ; J DB $72 ; T DB $C6 ; z DB $6C ; s tetris_colors DB $16,$26,$36,$46,$56,$66,$76,$00 key1 DB $BF,$BF,$DF,$DF,$7F,$7F key2 DB $08,$01,$08,$01,$01,$08 ;========================================================================= check LDA ppos STA ppos2 ; SEC BCS tet25 check_left LDA ppos SEC SBC #1 STA ppos2 tet25 LDA ppos+1 SBC #0 STA ppos2+1 BNE tet22 check_down LDA ppos CLC ADC #40 JMP tet23 check_right LDA ppos CLC ADC #1 tet23 STA ppos2 ; LDA ppos+1 ADC #0 tet24 STA ppos2+1 ; tet22 LDA paddr+1 STA tet14+2 LDA paddr STA tet14+1 ; LDX #$00 LDY #$00 tet14 LDA $FFFF,x ; self-mod BEQ tet15 ; LDA (ppos2),y ; cmp #char_space BEQ tet15 CMP #char_current BEQ tet15 ; not empty! ; ; lda #$01 RTS ; a <> 0 ; tet15 JSR inc_y INX CPX #$10 BNE tet14 ; LDA #$00 ; return zero = place is empty tet16 RTS ;========================================================================= draw_block LDA #$81 ; color ;LDA $FF00 ;AND #$40 ; used to be random ;ORA #$81 DB $AE ; skip two bytes with LDX $0000 draw_current LDA #char_current DB $AE ; skip two bytes with LDX $0000 erase_piece LDA #char_space tet17 STA tet_ch + 1 ; LDA paddr STA tet8+1 LDA paddr+1 STA tet8+2 ; LDX #$00 LDY #$00 tet8 LDA $FFFF,x ; self-mod BEQ tet12 ; tet_ch LDA #$00 ; character to put on screen STA (ppos),y ; tet12 JSR inc_y ; INX CPX #$10 BNE tet8 RTS ; inc_y INY ; adjust Y for the loop CPY #4 ; values go like this: 0-3 BNE tet9 LDY #40 ; 40-43 tet9 CPY #44 BNE tet10 LDY #80 ; 80-83 tet10 CPY #84 BNE tet11 LDY #120 tet11 RTS ; wait_sync LDA #$cc ; wait for sync comp1 CMP $ff1d BNE comp1 RTS ; ;--------------- ; expects A=value X=size $Z=addr ; fill LDY #$00 loop_f STA (z),y INY BNE loop_f INC z+1 DEX BPL loop_f ; after loop: A=unchanged ; X=$FF ; Y=0 RTS