'************************************************* ***************
'* Name : JuegoBloques.BAS *
'* Author : Leonardo Castillo *
'* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 31/03/2011 *
'* Version : 1.0 *
'* Notes :Programa final, funciona correctamente *
'* :lcd Nokia 1100 con driver PCF 8814 65x96 pixeles. *
'************************************************* ***************
'Cuadros de figuras
; FigParada1 FigParada2 FigDer1 FigDer2
; 0 0 0 0 0
; 0 0 0 0 0 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0
;$18,$2F,$78,$2F,$18-$30,$2F,$78,$2F,$10-$09,$12,$7C,$28,$6E-$10,$29,$7E,$2A,$14
; FigIz1 FigIz2 FigAr_Ab1 FigAr_Ab2
; 0 0 0 0 0
; 0 0 0 0 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0 0 0
; 0 0 0 0 0 0 0 0
; 0 0 0 0
;$6E,$28,$7C,$12,$09-$14,$2A,$7E,$29,$10-$18,$2E,$78,$2F,$10-$10,$2F,$78,$2E,$18
; Choque1 Choque2 Bloque EspacioBlanco
; 0 0 0 0 O O O O O |¬¬¬¬¬¬¬¬¬¬|
; 0 0 0 O O O O O O | |
; 0 0 O O O | |
; 0 0 0 0 0 0 O O O O O | |
; 0 0 0 0 O O O | |
; 0 0 0 0 O O O | |
; 0 0 0 0 O O O O O |__________|
;$13,$24,$68,$2B,$4C-$4C,$2B,$68,$24,$13-$7F,$49,$7F,$49,$7F-$00,$00,$00,$00,$00

' _CAMPO DE JUEGO__
'c[0]=%1100011000001101=$C60D |00 00 | 00 0|
'c[1]=%1100000110001100=$C18C |00 0|0 00 |
'c[2]=%0000110011000000=$0CC0 | 00 |00 |
'c[3]=%0001110010001100=$1C8C |___000__|0___00__|
'c[4]=%1000110001100100=$8C64 |0 00 | 00 0 |
'c[5]=%0001110011100110=$1CE6 | 000 |000 00 |
'c[6]=%1001111001100011=$9E63 |0 0000 | 00 00|
'c[7]=%0000110000000111=$0C07 |____00__|_____000|

INCLUDE "modedefs.bas"
asm
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB3 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_ON & _INTRC_IO
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
endasm
define OSC 8
C var word[8]
a var byte[2]
b var byte[2]
n var byte
v var word
x var byte
y var byte
xc var byte
yc var byte
xf var byte[2]
yf var byte[2]
PosX var byte
PosY var byte
LcdReg var byte
m1 var byte[2]
m2 var byte
i var byte
mascara var byte
Lcd_sda var Portb.1 'DATO AL LCD
Lcd_Clk var Portb.2 'CLOCK DEL LCD
Lcd_rst var Portb.0 'RESET DEL LCD
Abajo var Mascara.4
Arriba var mascara.5
Izquierda var mascara.6
Derecha var mascara.7

'almacena figs en eeprom
FigBloque data $7F,$49,$7F,$49,$7F
FigParada1 data $18,$2F,$78,$2F,$18
FigParada2 data $30,$2F,$78,$2F,$10
FigDer1 data $09,$12,$7C,$28,$6E
FigDer2 data $10,$29,$7E,$2A,$14
FigIz1 data $6E,$28,$7C,$12,$09
FigIz2 data $14,$2A,$7E,$29,$10
FigAr_Ab1 data $18,$2E,$78,$2F,$10
FigAr_Ab2 data $10,$2F,$78,$2E,$18
FigChoque1 data $13,$24,$68,$2B,$4C
FigChoque2 data $4C,$2B,$68,$24,$13
FigEspacioBlanco data $00,$00,$00,$00,$00

CampoJuego data word $C60D,word $C18C,word $0CC0,word $1C8C,_
word $8C64,word $1CE6,word $9E63,word $0C07

goto Inicio
'dibuja campo de juego
DibujaCampo:
y=0
for yc=b[0]*4 to b[0]*4+3
x=0
for xc=a[0]*8 to a[0]*8+7
gosub ObtieneImagen
if v=1 then
m2=FigBloque
else
m2=FigEspacioBlanco
endif
gosub EnviaImagen
x=x+5
next xc
y=y+1
next yc
return
EnviaImagen:
Posx=x
posy=y
EnviaFig:
gosub Lcd_GotoXY
for i=0 to 4
read m2+i,LcdReg
gosub Lcd_SentDato
next i
return
ObtieneImagen:
v=c[yc]>>(15-xc) & $01
return
Campo:
for i=0 to 7
read CampoJuego+2*i,word C[i]
next i
return
;LCD RUTINAS
Lcd_Init:
Low Lcd_RST
pause 10 ' Reset minimo de 5mS recomendado
High Lcd_RST

'inicia escritura en modo comando LCD Nokia 1100 con Driver PCF8814
LcdReg=$20:Gosub Lcd_SentControl' escribe Vop
LcdReg=$90:Gosub Lcd_SentControl
LcdReg=$aa:gosub Lcd_SentControl' modo de direcccionamiento de escritura horizontal (aa=0)-vertical(ab=1)
LcdReg=$a4:GOSUB Lcd_SentControl' DAL=0
LcdReg=$a6:GOSUB Lcd_SentControl' E=0 // normal display (non inverted)
LcdReg=$af:GOSUB Lcd_SentControl' DON=1
lcdreg=$a9:gosub Lcd_Sentcontrol' DOR (ordenamiento de datos MSB-LSB/DOR=1($a9);LSB-MSB/DOR=0 ($a8))
LcdReg=$d2:gosub Lcd_SentControl' parcial display 1:48
LcdReg=$2F:Gosub Lcd_SentControl' Power control set(charge pump on/off)
LcdReg=$40:Gosub Lcd_SentControl' set start row address = 5
LcdReg=$b0:Gosub Lcd_SentControl' set Y-address = 0
LcdReg=$10:Gosub Lcd_SentControl' set X-address, upper 3 bits
LcdReg=$00:Gosub Lcd_SentControl' set X-address, lower 4 bits
LcdReg=$C0:Gosub Lcd_SentControl' mirror Y axis (about X axis)
LcdReg=$ac:Gosub Lcd_SentControl' set initial row (R0) of the display
LcdReg=$01:Gosub Lcd_SentControl' inicia en la linea 8 (se incrementa de 8 en 8 por cada bit del registro)
GOSUB Lcd_clear
Return
Lcd_Home:
PosX=0:PosY=0:Gosub Lcd_GotoXY
Return
Lcd_Clear:
Gosub Lcd_Home
For i=1 to 195
Lcdreg=0:Gosub Lcd_SentDato
Lcdreg=0:Gosub Lcd_SentDato
Lcdreg=0:Gosub Lcd_SentDato
Lcdreg=0:Gosub Lcd_SentDato
Next i
Return
Lcd_GotoXY:
LcdReg=%10110000 | PosY :Gosub Lcd_SentControl ' Y
LcdReg=%00001111 & PosX :Gosub Lcd_SentControl ' X parte baja
LcdReg=%00010000 | ($07&(posx>>4)) :gosub Lcd_SentControl ' X parte alta
Return
Lcd_SentControl:
lcd_sda=0 ' envia control poniendo D/C a 0
Lcd_SentDato: ' envia dato con D/C a 1
lcd_clk=1
lcd_clk=0
n=0
repeat
lcd_sda = lcdreg.7
LcdReg = LcdReg << 1
lcd_ClK = 1
lcd_ClK = 0
n=n+1
until n>7
lcd_sda=1 ' pone D/C a 1
return

'****************************
Inicio:
OSCCON= %11111110
CMCON = 7
ANSEL = 0
TRISA = %00000000
TRISB = %11110000
OPTION_REG.7=0 'habilita pull-up
gosub Campo
gosub Lcd_Init
gosub Lcd_Clear
a[0]=0
b[0]=0
gosub DibujaCampo 'dibuja el primer cuadrante del campo
xf[0]=15
yf[0]=1
xf[1]=15
yf[1]=1
IniciaJuego:
'posiciona figura
Mascara=PortB
if arriba=0 then
yf[1]=yf[0]-1
m1[0]=FigAr_Ab1
m1[1]=FigAr_Ab2
elseif abajo=0 then
yf[1]=yf[0]+1
m1[0]=FigAr_Ab1
m1[1]=FigAr_Ab2
elseif izquierda=0 then
xf[1]=xf[0]-5
m1[0]=FigIz1
m1[1]=FigIz2
elseif derecha=0 then
xf[1]=xf[0]+5
m1[0]=FigDer1
m1[1]=FigDer2
else
m1[0]=FigParada1
m1[1]=FigParada2
endif
'compara choque
xc = xf[1]/5 'se divide entre 5 para obtener multiplos de 5 y poder
yc = yf[1] 'obtener la posicion relativa con respecto al campo.
gosub ObtieneImagen
if (v=1|xf[1]>75|yf[1]>7) then 'hay choque y no modifica coordenadas
m1[0]=FigChoque1 'xf[1]max 0 min 75|yf[1]max 0 min 7, limita un cuadro
m1[1]=FigChoque2
xf[1]=xf[0]
yf[1]=yf[0]
endif
'actualiza campo dependiendo de la posicion del jugador
if xf[1]<=35&yf[1]<=3 then a[0]=0:b[0]=0
if xf[1]>35&yf[1]<=3 then a[0]=1:b[0]=0
if xf[1]<=35&yf[1]>3 then a[0]=0:b[0]=1
if xf[1]>35&yf[1]>3 then a[0]=1:b[0]=1
if a[0]<>a[1]|b[0]<>b[1] then
gosub Lcd_Clear
gosub DibujaCampo
endif
a[1]=a[0]
b[1]=b[0]
'actualiza figura en el campo
x=xf[0]-40*a[0]
y=yf[0]-4*b[0]
m2=m1[0]
gosub EnviaImagen
pause 400
m2=FigEspacioBlanco
gosub EnviaImagen
x=xf[1]-40*a[0]
y=yf[1]-4*b[0]
m2=m1[1]
gosub EnviaImagen
pause 400
xf[0]=xf[1] 'no hay choque y actualiza las coordenadas
yf[0]=yf[1]
goto iniciajuego
end