' Apple II Low Res Tetris ' Bobbi 2018 word addrs[24]={$400,$480,$500,$580,$600,$680,$700,$780,$428,$4a8,$528,$5a8,$628,$6a8,$728,$7a8,$450,$4d0,$550,$5d0,$650,$6d0,$750,$7d0} ' Size of playfield const lhs=14 const rhs=lhs+11 const top=10 const bttm=top+22 const strow=8 const stcol=18 ' Apple II specific addresses const spkr=$c030 const kbdata=$c000 const kbstrb=$c010 const hpos=36 const rnd=$4e ' ASCII const beep=7 const clrscr=12 ' Position of piece byte col=stcol byte row=strow byte rot=0 ' Previous col, row, rotation byte ocol=stcol byte orow=strow byte orot=0 byte key=0 byte piece=0 byte done=0 word score=0 ' Seed the PRNG word rr=$4e ' Left, right, rotate permitted? byte lok=1 byte rok=1 byte rotok=1 ' First run byte first=1 call prng() piece=rr%5 call loresmix() while 1 score=0 pr.ch clrscr call clrlomix() call frame() call printnewlines() if first call printintro() kbd.ch &key call clearintro() first=0 endif call printtext() call printscore() call playgame() kbd.ch &key endwhile end sub playgame() while 1 key=getkey() orow=row;ocol=col;orot=rot if key=='s'&&rotok if rot==3 rot=0 else rot=rot+1 endif else if (key=='a')&&lok col=col-1 else if (key=='d')&&rok col=col+1 else if key=='p' while getkey()==0 endwhile endif endif endif endif key=^spkr row=row+1 lok=1 rok=1 rotok=1 call drawPiece(ocol,orow,orot,1); 'Erase if drawPiece(col,row,rot,0) if row==strow+1 call loser() return 0 else call checkframe(row) col=stcol;row=strow;rot=0 call prng() piece=rr%5 endif endif endwhile endsub sub getkey() if ^kbdata<128 return 0 endif ^kbstrb=0 return ^kbdata endsub sub lores() ^$c050=0 ^$c052=0 ^$c054=0 ^$c056=0 endsub sub loresmix() ^$c050=0 ^$c053=0 ^$c054=0 ^$c056=0 endsub sub text() ^$c051=0 ^$c054=0 endsub sub clrlo() byte r=0 byte c=0 for r=0:23 for c=0:39 ^(addrs[r]+c)=0 endfor endfor endsub sub clrlomix() byte r=0 byte c=0 for r=0:19 for c=0:39 ^(addrs[r]+c)=0 endfor endfor for r=20:23 for c=0:39 ^(addrs[r]+c)=' '+128 endfor endfor endsub sub plot(byte c,byte r,byte color) word a=addrs[r/2]+c if r%2 ^a=(^a&$0f)|(color<<4) else ^a=(^a&$f0)|color endif endsub sub readpix(byte c,byte r) word a=addrs[r/2]+c if r%2 return (^a&$f0)>>4 else return ^a&$0f endif endsub sub hlin(byte c1,byte c2,byte r,byte color) byte i=0 for i=c1:c2 call plot(i,r,color) endfor endsub sub vlin(byte c,byte r1,byte r2,byte color) byte i=0 for i=r1:r2 call plot(c,i,color) endfor endsub sub frame() call hlin(lhs,rhs,bttm,4) call vlin(lhs,top,bttm,4) call vlin(rhs,top,bttm,4) endsub sub drawPiece(byte c,byte r,byte rot,byte erase) if piece==0 return drawT(c,r,rot,erase) else; if piece==1 return drawL(c,r,rot,erase) else; if piece==2 return drawZ(c,r,rot,erase) else; if piece==3 return drawSq(c,r,rot,erase) else return drawI(c,r,rot,erase) endif;endif;endif;endif endsub sub drawT(byte c,byte r,byte rot,byte erase) byte color=1 if erase color=0 endif if rot==0 call plot(c,r+1,color) call plot(c+1,r+1,color) call plot(c+2,r+1,color) call plot(c+1,r+2,color) if erase return 0 endif lok=!(readpix(c-1,r+2)||readpix(c,r+2)||readpix(c,r+3)) rok=!(readpix(c+2,r+2)||readpix(c+3,r+2)||readpix(c+2,r+3)) rotok=!(readpix(c,r+2)||readpix(c+1,r+3)) return readpix(c,r+2)||readpix(c+1,r+3)||readpix(c+2,r+2) else if rot==1 call plot(c+1,r,color) call plot(c,r+1,color) call plot(c+1,r+1,color) call plot(c+1,r+2,color) if erase return 0 endif lok=!(readpix(c-1,r+2)||readpix(c,r+2)||readpix(c,r+3)) rok=!(readpix(c+2,r+1)||readpix(c+2,r+2)||readpix(c+2,r+3)) rotok=!(readpix(c,r+2)||readpix(c+2,r+2)) return readpix(c,r+2)||readpix(c+1,r+3) else if rot==2 call plot(c+1,r,color) call plot(c,r+1,color) call plot(c+1,r+1,color) call plot(c+2,r+1,color) if erase return 0 endif lok=!(readpix(c-1,r+2)||readpix(c,r+2)||readpix(c+1,r+2)) rok=!(readpix(c+1,r+2)||readpix(c+2,r+2)||readpix(c+3,r+2)) rotok=!(readpix(c+1,r+2)||readpix(c+2,r+2)||readpix(c+1,r+3)) return readpix(c,r+2)||readpix(c+1,r+2)||readpix(c+2,r+2) else if rot==3 call plot(c+1,r,color) call plot(c+1,r+1,color) call plot(c+2,r+1,color) call plot(c+1,r+2,color) if erase return 0 endif lok=!(readpix(c,r+1)||readpix(c,r+2)||readpix(c,r+3)) rok=!(readpix(c+2,r+2)||readpix(c+3,r+2)||readpix(c+2,r+3)) rotok=!(readpix(c,r+2)||readpix(c+2,r+2)||readpix(c+1,r+3)) return readpix(c+1,r+3)||readpix(c+2,r+2) endif endif endif endif endsub sub drawL(byte c,byte r,byte rot,byte erase) byte color=8 if erase color=0 endif if rot==0 call plot(c+1,r,color) call plot(c+1,r+1,color) call plot(c+1,r+2,color) call plot(c+2,r+2,color) if erase return 0 endif lok=!(readpix(c,r+1)||readpix(c,r+2)||readpix(c,r+3)||readpix(c+1,r+3)) rok=!(readpix(c+2,r+1)||readpix(c+2,r+3)||readpix(c+3,r+3)) rotok=!(readpix(c,r+2)||readpix(c+2,r+1)) return readpix(c+1,r+3)||readpix(c+2,r+3) else if rot==1 call plot(c+2,r,color) call plot(c,r+1,color) call plot(c+1,r+1,color) call plot(c+2,r+1,color) if erase return 0 endif lok=!(readpix(c-1,r+2)||readpix(c,r+2)||readpix(c+1,r+2)) rok=!(readpix(c+1,r+2)||readpix(c+2,r+2)||readpix(c+3,r+2)||readpix(c+3,r+1)) rotok=!(readpix(c+2,r+2)||readpix(c+2,r+3)) return readpix(c,r+2)||readpix(c+1,r+2)||readpix(c+2,r+2) else if rot==2 call plot(c+1,r,color) call plot(c+2,r,color) call plot(c+2,r+1,color) call plot(c+2,r+2,color) if erase return 0 endif lok=!(readpix(c,r+1)||readpix(c+1,r+1)||readpix(c+1,r+2)||readpix(c+1,r+3)) rok=!(readpix(c+3,r+1)||readpix(c+3,r+2)||readpix(c+3,r+3)) rotok=!(readpix(c+1,r+1)||readpix(c+1,r+2)||readpix(c+3,r+1)) return readpix(c+1,r+1)||readpix(c+2,r+3) else if rot==3 call plot(c+1,r,color) call plot(c+2,r,color) call plot(c+3,r,color) call plot(c+1,r+1,color) if erase return 0 endif lok=!(readpix(c,r+1)||readpix(c,r+2)) rok=!(readpix(c+2,r+1)||readpix(c+3,r+1)||readpix(c+4,r+1)||readpix(c+2,r+2)) rotok=!(readpix(c+2,r+1)||readpix(c+2,r+2)||readpix(c+2,r+3)||readpix(c+3,r+3)) return readpix(c+1,r+2)||readpix(c+2,r+1)||readpix(c+3,r+1) endif endif endif endif endsub sub drawZ(byte c,byte r,byte rot,byte erase) byte color=2 if erase color=0 endif if (rot==0)||(rot==2) call plot(c+1,r,color) call plot(c+1,r+1,color) call plot(c+2,r+1,color) call plot(c+2,r+2,color) if erase return 0 endif lok=!(readpix(c,r+1)||readpix(c,r+2)||readpix(c+1,r+2)||readpix(c+1,r+3)) rok=!(readpix(c+3,r+2)||readpix(c+3,r+3)) rotok=!(readpix(c,r+3)||readpix(c+1,r+3)||readpix(c+1,r+2)) return readpix(c+1,r+2)||readpix(c+2,r+3) else if (rot==1)||(rot==3) call plot(c+1,r+1,color) call plot(c+2,r+1,color) call plot(c,r+2,color) call plot(c+1,r+2,color) if erase return 0 endif lok=!(readpix(c-1,r+3)||readpix(c,r+3)||readpix(c+2,r+2)) rok=!(readpix(c+1,r+3)||readpix(c+2,r+3)||readpix(c+2,r+2)||readpix(c+3,r+2)) rotok=!(readpix(c+2,r+2)||readpix(c+2,r+3)) return readpix(c,r+3)||readpix(c+1,r+3) endif endif endsub sub drawI(byte c,byte r,byte rot,byte erase) byte color=14 if erase color=0 endif if (rot==0)||(rot==2) call plot(c,r+2,color) call plot(c+1,r+2,color) call plot(c+2,r+2,color) call plot(c+3,r+2,color) if erase return 0 endif lok=!readpix(c-1,r+3) rok=!readpix(c+4,r+3) rotok=!(readpix(c+2,r+3)||readpix(c+2,r+4)) return readpix(c,r+3)||readpix(c+1,r+3)||readpix(c+2,r+3)||readpix(c+3,r+3) else if (rot==1)||(rot==3) call plot(c+2,r,color) call plot(c+2,r+1,color) call plot(c+2,r+2,color) call plot(c+2,r+3,color) if erase return 0 endif lok=!(readpix(c+1,r+1)||readpix(c+1,r+2)||readpix(c+1,r+3)||readpix(c+1,r+4)) rok=!(readpix(c+3,r+1)||readpix(c+3,r+2)||readpix(c+3,r+3)||readpix(c+3,r+4)) rotok=!(readpix(c,r+3)||readpix(c+1,r+3)||readpix(c+3,r+3)) return readpix(c+2,r+4) endif endif endsub sub drawSq(byte c,byte r,byte rot,byte erase) byte color=13 if erase color=0 endif call plot(c+1,r+1,color) call plot(c+2,r+1,color) call plot(c+1,r+2,color) call plot(c+2,r+2,color) if erase return 0 endif lok=!(readpix(c,r+2)||readpix(c,r+3)) rok=!(readpix(c+3,r+2)||readpix(c+3,r+3)) rotok=1 return readpix(c+1,r+3)||readpix(c+2,r+3) endsub sub checkframe(byte r) byte rr=r+3 if rr>bttm-1 rr=bttm-1 endif while rr>=r if checkline(rr) pr.ch beep else rr=rr-1 endif endwhile endsub sub checkline(byte r) byte c=0 for c=lhs+1:rhs-1 if !readpix(c,r) return 0 endif endfor call deleterow(r) score=score+1 call printscore() return 1 endsub sub deleterow(byte r) byte i=r byte c=0 byte v=0 byte empty=0 while (i>top+1)&&(!empty) empty=1 for c=lhs+1:rhs-1 v=readpix(c,i-1) if v empty=0 endif call plot(c,i,v) endfor i=i-1 endwhile endsub sub printnewlines() byte i=0 for i=0:19 pr.nl endfor endsub sub printintro() ^hpos=10 pr.msg "TETRIS - PRESS ANY KEY" endsub sub clearintro() ^hpos=10 pr.msg " " endsub sub printtext() ^hpos=10 pr.msg "SCORE: " endsub sub printscore() ^hpos=17 pr.dec score pr.msg " " endsub sub loser() ^hpos=10 pr.msg "GAME OVER - SCORE WAS " pr.dec score endsub sub prng() rr=rr*8191+7; ' Mersenne prime endsub