El joc vol imitar, amb les limitacions que imposa la pantalla, el jos d'enfonsar vaixells. L'ús dels polsadors és el següent:
| Polsador | Finalitat |
| 0 | Canvi de taulell |
| 1 | Desplaçament a l'esquerra |
| 2 | Desplaçament a la dreta Pinta de verd (vaixells propis) |
| 3 | Desplaçament avall Pinta de blau (aigua) |
| 4 | Desplaçament amunt Pinta de vermell (tocat) |
| 5 | Canvi de mode |
El programa és el següent:
#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF #pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF #include <xc.h> #define _XTAL_FREQ 4000000
char Port; char Compta; char Sortida[6]; char Sorti[6]; char Actiu; char Polsad; char figura[8]; char figura_vermell[8]; char figura_verd[8]; // --- NUEVAS MATRICES PARA LA SEGUNDA PANTALLA --- char figura2[8]; char figura2_vermell[8]; char figura2_verd[8]; char pantalla_actual = 1; // 1 = primera pantalla, 2 = segunda char x = 0; char y = 0; char mirar = 1;
// --- DECLARACIÓN DE FUNCIONES --- void Envia3max(char Valor[]); void Envia_max(void); void Ini3max(void); void Apaga(void); char Polsador(void);
// --- PROGRAMA PRINCIPAL ---
void main (void) {
OPTION_REG = 0b10000101;
TRISC = 0;
TRISB = 0;
TRISA = 0xFF;
ANSEL = 0b00000101;
ANSELH = 0;
PORTC = 0;
PORTB = 0;
ADCON1 = 0b00010000;
ADCON0 = 0b00001001;
Ini3max();
Actiu = 1;
TMR0 = 100;
INTCON = 0b10100000;
Apaga();
// Inicialización de las dos pantallas
for (signed char k = 0; k < 8; k++) {
figura[k] = 0;
figura_vermell[k] = 0;
figura_verd[k] = 0;
figura2[k] = 0;
figura2_vermell[k] = 0;
figura2_verd[k] = 0;
}
TRISAbits.TRISA3 = 1; // RA3 com a entrada
ANSELbits.ANS3 = 0;
// Desactiva el mode analògic per RA3
while (1) {
Polsad = Polsador();
// --- Selecciona los arrays activos según la pantalla actual ---
char *figura_activa_vermell;
char *figura_activa_verd;
char *figura_activa_blau;
if (pantalla_actual == 1) {
figura_activa_vermell = figura_vermell;
figura_activa_verd = figura_verd;
figura_activa_blau = figura;
} else {
figura_activa_vermell = figura2_vermell;
figura_activa_verd = figura2_verd;
figura_activa_blau = figura2;
}
// --- Control de pulsadores ---
if (mirar == 1){
if (Polsad == 1) {
x = (x + 1) % 8;
mirar = 0;
}
if (Polsad == 2) {
x = (x - 1 + 8) % 8;
mirar = 0;
}
if (Polsad == 3) {
y = (y + 1) % 8;
mirar = 0;
}
if (Polsad == 4) {
y = (y - 1 + 8) % 8;
mirar = 0;
}
if (Polsad == 5) {
mirar = 2; // Modo de edición de color
}
if (Polsad == 6) { // --- NUEVO: cambia de pantalla ---
if (pantalla_actual == 1) pantalla_actual = 2;
else pantalla_actual = 1;
mirar = 0;
}
} else if (mirar == 2){
if (Polsad == 1) {
mirar = 0;
}
if (Polsad == 3) {
figura_activa_vermell[y] &= ~(1 << x);
figura_activa_verd[y] &= ~(1 << x);
figura_activa_blau[y] = figura_activa_blau[y] ^ (1 << x);
mirar = 0;
}
if (Polsad == 4) {
figura_activa_blau[y] &= ~(1 << x);
figura_activa_verd[y] &= ~(1 << x);
figura_activa_vermell[y] = figura_activa_vermell[y] ^ (1 << x);
mirar = 0;
}
if (Polsad == 2) {
figura_activa_blau[y] &= ~(1 << x);
figura_activa_vermell[y] &= ~(1 << x);
figura_activa_verd[y] = figura_activa_verd[y] ^ (1 << x);
mirar = 0;
}
} else {
if (Polsad == 0) {
mirar = 1;
}
}
// --- Muestra la matriz activa ---
for (unsigned char k = 0; k < 8; k++){
char mascara;
Sortida[0] = figura_activa_vermell[k];
Sortida[2] = figura_activa_verd[k];
Sortida[4] = figura_activa_blau[k];
if (y == k){
mascara = (1 << x);
Sortida[0] |= mascara; // Cursor en rojo
Sortida[2] |= mascara; // y verde
Sortida[4] &= ~mascara; // sin azul
}
Sortida[1] = k+1;
Sortida[3] = k+1;
Sortida[5] = k+1;
Envia3max(Sortida);
__delay_ms(1);
}
}
}
// --- INTERRUPCIÓN DE TIMER ---
void __interrupt() temporit(void){
if (INTCONbits.T0IF) {
TMR0 = 100;
INTCONbits.T0IF = 0;
if (Actiu != 0) {
Actiu--;
if (Actiu == 0) {
Actiu = 3;
}
}
Sorti[0] = 0x00;
Sorti[2] = 0x00;
Sorti[4] = 0x00;
if (Actiu == 1) Sorti[0] = 0x01;
if (Actiu == 2) Sorti[2] = 0x01;
if (Actiu == 3) Sorti[4] = 0x01;
Sorti[1] = 0x0C;
Sorti[3] = 0x0C;
Sorti[5] = 0x0C;
Envia_max();
}
}
void Envia3max(char Valor[]) {
INTCONbits.T0IE = 0;
char Port = 0;
char Temp;
for (signed char j = 5; j >= 0; j--){
for (signed char k = 1; k < 9; k++){
Temp = Valor[j] & 0b10000000;
if (Temp == 0)
Port = Port & 0b11101111;
else
Port = Port | 0b00010000;
Valor[j] = Valor[j] << 1;
PORTB = Port;
Port = Port | 0b00100000;
PORTB = Port;
Port = Port & 0b11011111;
PORTB = Port;
}
}
Port = Port | 0b01000000;
PORTB = Port;
INTCONbits.T0IE = 1;
}
void Envia_max(void) {
asm("banksel _Port");
asm("bcf (_Port&7fh),5");
asm("bcf (_Port&7fh),6");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
asm("banksel _Compta");
asm("movlw 48");
asm("movwf (_Compta&7fh)");
asm("Bucle:");
asm("banksel _Port");
asm("bcf (_Port&7fh),4");
asm("banksel _Sorti");
asm("rlf (_Sorti&7fh),f");
asm("rlf ((_Sorti+1)&7fh),f");
asm("rlf ((_Sorti+2)&7fh),f");
asm("rlf ((_Sorti+3)&7fh),f");
asm("rlf ((_Sorti+4)&7fh),f");
asm("rlf ((_Sorti+5)&7fh),f");
asm("banksel _Port");
asm("btfsc STATUS,0");
asm("bsf (_Port&7fh),4");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
asm("banksel _Port");
asm("bsf (_Port&7fh),5");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
asm("banksel _Port");
asm("bcf (_Port&7fh),5");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
asm("banksel _Compta");
asm("decfsz (_Compta&7fh),f");
asm("goto (Bucle&7ffh)");
asm("banksel _Port");
asm("bsf (_Port&7fh),6");
asm("movf (_Port&7fh),w");
asm("banksel PORTB");
asm("movwf PORTB");
}
void Ini3max(void) {
char Bytes[6];
Bytes[0] = 0x00;
Bytes[1] = 0x0C;
Bytes[2] = 0x00;
Bytes[3] = 0x0C;
Bytes[4] = 0x00;
Bytes[5] = 0x0C;
Envia3max(Bytes);
Bytes[0] = 0x00;
Bytes[1] = 0x09;
Bytes[2] = 0x00;
Bytes[3] = 0x09;
Bytes[4] = 0x00;
Bytes[5] = 0x09;
Envia3max(Bytes);
Bytes[0] = 0x07;
Bytes[1] = 0x0B;
Bytes[2] = 0x07;
Bytes[3] = 0x0B;
Bytes[4] = 0x07;
Bytes[5] = 0x0B;
Envia3max(Bytes);
}
void Apaga(void) {
char Bytes[6];
for (unsigned char j = 1; j <= 8; j++){
Bytes[1] = j;
Bytes[3] = j;
Bytes[5] = j;
Bytes[0] = 0x00;
Bytes[2] = 0x00;
Bytes[4] = 0x00;
Envia3max(Bytes);
}
}
char Polsador(void) {
char Pols = 0;
ADCON0bits.GO = 1;
while (ADCON0bits.GO == 1);
if (ADRESH < 220 && ADRESH > 200) Pols = 1;
if (ADRESH < 194 && ADRESH > 174) Pols = 2;
if (ADRESH < 163 && ADRESH > 143) Pols = 3;
if (ADRESH < 90 && ADRESH > 70) Pols = 4;
if (ADRESH < 55 && ADRESH > 35) Pols = 5;
if (PORTAbits.RA3 == 0) { // Si el botó està connectat a GND
__delay_ms(30); // Desrebot
if (PORTAbits.RA3 == 0)
Pols = 6;
}
return Pols;
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.