diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index c11401d..3ac3b39 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -3,7 +3,8 @@ { "name": "Linux", "includePath": [ - "${workspaceFolder}/**" + "${workspaceFolder}/**", + "${workspaceFolder}" ], "defines": [], "compilerPath": "/usr/bin/gcc", diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7834431 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "libregisters.h": "c" + } +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..24b39e1 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +# Regras principais +all: tool + +tool: registers.o biblioteca.o libregisters.a + gcc -o tool registers.o biblioteca.o -lregisters -L. + +libregisters.a: registers.o + ar rcs libregisters.a registers.o + +registers.o: registers.c libregisters.h + gcc -c registers.c + +biblioteca.o: biblioteca.c biblioteca.o + gcc -c biblioteca.c + +# Limpeza dos arquivos gerados +clean: + rm -f *.o tool *.a diff --git a/apoio_registers.h b/apoio_registers.h deleted file mode 100644 index e1fbca2..0000000 --- a/apoio_registers.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef REGISTERS_H -#define REGISTERS_H - -#include - -// Definições dos registradores -extern uint16_t *R0; -extern uint16_t *R1; -extern uint16_t *R2; -extern uint16_t *R3; -extern uint16_t *R4; -extern uint16_t *R5; -extern uint16_t *R6; -extern uint16_t *R7; -extern uint16_t *R8; -extern uint16_t *R9; -extern uint16_t *R10; -extern uint16_t *R11; -extern uint16_t *R12; -extern uint16_t *R13; -extern uint16_t *R14; -extern uint16_t *R15; - -// Funções para leitura e escrita nos registradores -uint16_t read_register(uint16_t *reg); -void write_register(uint16_t *reg, uint16_t value); - -// Funções de controle para o hardware -void display_message(const char *message); -void control_status_led(int battery_level); - -#endif /* REGISTERS_H */ - - diff --git a/biblioteca.c b/biblioteca.c new file mode 100644 index 0000000..090fba1 --- /dev/null +++ b/biblioteca.c @@ -0,0 +1,486 @@ +#include "libregisters.h" +#include + +//esse vai mudar o led do status +void set_colorLed(unsigned short*r0, int bit10, int bit11, int bit12) { + if (bit10 == 1) { + *r0 |= (0x1 << 10); // Ativa o bit de cor RED + + + } else if (bit10 == 0) { + *r0 &= ~(0x1 << 10); // Zera o bit 1 + } + if (bit11 == 1) { + *r0 |= (0x1 << 11); // Seta para 1 o bit 11 no registrador 0 + + } else if (bit11 == 0) { + *r0 &= ~(0x1 << 11); // Zera o bit 11 + } + if (bit12 == 1) { + *r0 |= (0x1 << 12); // Ativa o bit de cor BLUE + } else if (bit12 == 0) { + *r0 &= ~(0x1 << 12); // Zera o bit 12 + } + +} + +void set_colorDisplay(unsigned short*r1, unsigned short *r2, int red, int green, int blue) { + if (red == 1) { + *r1 |= 255; // Ativa o bit de cor RED + + + } else if (red == 0) { + *r1 &= ~(0xFF); // Zera o bit 1 + } + if (green == 1) { + *r1 |= (255 << 8); // Seta para 1 o bit 11 no registrador 0 + + } else if (green == 0) { + *r1 &= ~(0xFF00); // Zera o bit 11 + } + if (blue == 1) { + *r2 |= 255; // Ativa o bit de cor BLUE + } else if (blue == 0) { + *r2 &= ~(0xFF); // Zera o bit 12 + } + +} +//se o display vai estar ligado +void setOnOff(unsigned short *r0, int bit){ + + if(bit == 1 ){ + *r0 |= (0x1 << 0); + } + else if(bit == 0){ + *r0 &= ~(0x1 << 0); + } +} +//se o led de operação do display vai estar ligado ou desligado +void setOnOff_Operacao(unsigned short *r0, int bit){ + + if(bit == 0 ){ + *r0 |= (0x1 << 9); + } + else if(bit == 1){ + *r0 &= ~(0x1 << 9); + } +} + +void setPadraoFabrica(unsigned short *reg, int bit){ + + if(bit == 0 || bit > 1) { + return; + } + + else if(bit == 1){ + // muda de 0 para um o bit 13 do primeiro registrador + *reg= (0x1 << 13); + + //coloca na versão de fábrica a velocidade de exibição + *reg &= ~(0x1 << 2); + *reg &= ~(0x1 << 1); + + //coloca a velocidade na versão default + + *reg &= ~(0x3F << 3); + + *reg |= (2 & 0x3F) << 3; + + //muda o led de operação do display para o padrao de fabrica + *reg &= ~(0x1 << 9); + + } + +} + + +void setExibicao( unsigned short *r0, int bit1, int bit2){ + + if( bit1 == 0 && bit2 == 0){ + //estatico + *r0 &= ~(0x1 << 2); + *r0 &= ~(0x1 << 1); + } + + if( bit1 == 0 && bit2== 1){ + //deslizante + *r0 &= ~(0x1 << 2); + *r0 |= (0x1 << 1); + } + + if( bit1 == 1 && bit2 == 0){ + //piscante + *r0 |= (0x1 << 2); + *r0 &= ~(0x1 << 1); + } + + if( bit1 == 1 && bit2 == 1){ + //deslizante/piscante + *r0 |= (0x1 << 2); + *r0 |= (0x1 << 1); + } + +} +// criar outro com as especificações acima só que mudando apenas os rgb + + +//ainda com alguns problemas +void setVelocidade(unsigned short *r0, int velocidade){ + + int velo = (velocidade / 100) -1; + + *r0 &= ~(0x3F << 3); + + *r0 |= (velo & 0x3F) << 3; +} + + +unsigned char mapearLetra(unsigned char letra) { + + switch (letra) + { + case 'A': return 0b01000001; + case 0xC0: return 0b11000000; //À + case 0xC1: return 0b11000001; // Á + case 0xC2: return 0b11000010; // Â + case 0xC3: return 0b11000011; // Ã + case 'B': return 0b01000010; + case 'C': return 0b01000011; + case 0xC7: return 0b11000111; //Ç + case 'D': return 0b01000100; + case 'E': return 0b01000101; + case 0xC9: return 0b11001001; //É + case 0xCA: return 0b11001010; // Ê + case 'F': return 0b01000110; + case 'G': return 0b01000111; + case 'H': return 0b01001000; + case 'I': return 0b01001001; + case 0xCD: return 0b11001101; //Í + case 'J': return 0b01001010; + case 'K': return 0b01001011; + case 'L': return 0b01001100; + case 'M': return 0b01001101; + case 'N': return 0b01001110; + case 'O': return 0b01001111; + case 0xD3: return 0b11010011; //Ó + case 0xD4: return 0b11010100; //Ô + case 0xD5: return 0b11010101; //Õ + case 'P': return 0b01010000; + case 'Q': return 0b01010001; + case 'R': return 0b01010010; + case 'S': return 0b01010011; + case 'T': return 0b01010100; + case 'U': return 0b01010101; + case 0xDA: return 0b11011010; //Ú + case 'V': return 0b01010110; + case 'W': return 0b01010111; + case 'X': return 0b01011000; + case 'Y': return 0b01011001; + case 'Z': return 0b01011010; + + //minúsculas + case 'a': return 0b01100001; + case 0xE0: return 0b11100000; //à + case 0xE1: return 0b11100001; //á + case 0xE2: return 0b11100010; //â + case 0xE3: return 0b11100011; //ã + case 'b': return 0b01100010; + case 'c': return 0b01100011; + case 0xE7: return 0b11100111; //ç + case 'd': return 0b01100100; + case 'e': return 0b01100101; + case 0xE9: return 0b11101001; // é + case 0xEA: return 0b11101010; // ê + case 'f': return 0b01100110; + case 'g': return 0b01100111; + case 'h': return 0b01101000; + case 'i': return 0b01101001; + case 0xED: return 0b11101101; //í + case 'j': return 0b01101010; + case 'k': return 0b01101011; + case 'l': return 0b01101100; + case 'm': return 0b01101101; + case 'n': return 0b01101110; + case 'o': return 0b01101111; + case 0xF3: return 0b11110011; //ó + case 0xF4: return 0b11110100; //ô + case 0xF5: return 0b11110101; //õ + case 'p': return 0b01110000; + case 'q': return 0b01110001; + case 'r': return 0b01110010; + case 's': return 0b01110011; + case 't': return 0b01110100; + case 'u': return 0b01110101; + case 0xFA: return 0b11111010; //ú + case 'v': return 0b01110110; + case 'w': return 0b01110111; + case 'x': return 0b01111000; + case 'y': return 0b01111001; + case 'z': return 0b01111010; + default: + printf("Letra inválida! Forneça uma letra válida.\n"); + return 0; + } + } + + +void setPalavras( unsigned short *reg, char letra, char letra2 ){ + + unsigned char valor1 = mapearLetra(letra); + unsigned char valor2 = mapearLetra(letra2); + + + if(valor1 && valor2){ + + *reg &= 0x0000; + *reg |= valor1; + *reg |= (valor2 << 8); + + + } else{ + + printf("Erro"); + } + +} + + + +// Funções de GET + + +const char * getEstadoDisplay( unsigned short *r0){ + + return (*r0 & ( 0x1 << 0)) == 0 ? "desligado" : "ligado"; +} + +const char * getEstadoLed( unsigned short *r0){ + + return (*r0 & ( 0x1 << 9)) == 0 ? "desligado" : "ligado"; +} + +const char * getCorLed( unsigned short *r0){ + + if ((*r0 & (0x1 << 10)) && (*r0 & (0x1 << 11)) && (*r0 & (0x1 << 12))) { + return "white"; + } + + if ((*r0 & (0x1 << 10)) && (*r0 & (0x1 << 11)) && !(*r0 & (0x1 << 12))) { + return "yellow"; + } + + if (!(*r0 & (0x1 << 10)) && (*r0 & (0x1 << 11)) && (*r0 & (0x1 << 12))) { + return "cian"; + } + + if ((*r0 & (0x1 << 10)) && !(*r0 & (0x1 << 11)) && (*r0 & (0x1 << 12))) { + return "pink"; + } + + if ((*r0 & (0x1 << 10)) && !(*r0 & (0x1 << 11)) && !(*r0 & (0x1 << 12))) { + return "red"; + } + + if (!(*r0 & (0x1 << 10)) && (*r0 & (0x1 << 11)) && !(*r0 & (0x1 << 12))) { + return "green"; + } + + if (!(*r0 & (0x1 << 10)) && !(*r0 & (0x1 << 11)) && (*r0 & (0x1 << 12))) { + return "blue"; + } + +} + +const char * getCorDisplay( unsigned short *r1 , unsigned short * r2 ){ + + if ((*r1 & (0x1 << 1)) && (*r1 & (0x1 << 8)) && (*r2 & (0x1 << 1))) { + return "white"; + } + + if ((*r1 & (0x1 << 1)) && (*r1 & (0x1 << 8)) && !(*r2 & (0x1 << 1))) { + return "yellow"; + } + + if (!(*r1 & (0x1 << 1)) && (*r1 & (0x1 << 8)) && (*r2 & (0x1 << 1))) { + return "cian"; + } + + if ((*r1 & (0x1 << 1)) && !(*r1 & (0x1 << 8)) && (*r2 & (0x1 << 1))) { + return "pink"; + } + + if ((*r1 & (0x1 << 1)) && !(*r1 & (0x1 << 8)) && !(*r2 & (0x1 << 1))) { + return "red"; + } + + if (!(*r1 & (0x1 << 1)) && (*r1 & (0x1 << 8)) && !(*r2 & (0x1 << 1))) { + return "green"; + } + + if (!(*r1 & (0x1 << 1)) && !(*r1 & (0x1 << 8)) && (*r2 & (0x1 << 1))) { + return "blue"; + } + +} + +const char * getBateryLevel( unsigned short * r3){ + + if (!(*r3 & (0x1 << 0)) && !(*r3 & (0x1 << 1))) { + return "critico"; + } + + if (!(*r3 & (0x1 << 0)) && (*r3 & (0x1 << 1))) { + return "baixo"; + } + + if ((*r3 & (0x1 << 0)) && !(*r3 & (0x1 << 1))) { + return "médio"; + } + + if ((*r3 & (0x1 << 0)) && (*r3 & (0x1 << 1))) { + return "alto"; + } + +} + +const char * getModoExibicao( unsigned short *r0){ + if (!(*r0 & (0x1 << 1)) && !(*r0 & (0x1 << 2))) { + return "estático"; + } + if (!(*r0 & (0x1 << 1)) && (*r0 & (0x1 << 2))) { + return "deslizante"; + } + if ((*r0 & (0x1 << 1)) && !(*r0 & (0x1 << 2))) { + return "piscante"; + } + if ((*r0 & (0x1 << 1)) && (*r0 & (0x1 << 2))) { + return "deslizante/piscante"; + } +} + +int calcularQuantidadeMensagem ( unsigned short *r3){ + + int quantidade =0; + + unsigned short bits_relevantes = ( *r3>> 2) & 0xF; + + for(int i = 0; i < 4; i++){ + + if(bits_relevantes & (0x1 << i)){ + quantidade += (1<> 3) & 0xF; + + for(int i = 0; i < 6; i++){ + + if(bits_relevantes & (0x1 << i)){ + quantidade += (1<> 6) & 0x3FF; + + // Converter para decimal e considerar complemento de dois para valores negativos + int valor_decimal; + if (bits_relevantes & 0x200) { // Se o bit mais significativo estiver definido, é negativo + valor_decimal = -(0x3FF - bits_relevantes + 1); + } else { + valor_decimal = bits_relevantes; + } + + // Calcular a temperatura em graus Celsius + float temperatura = valor_decimal / 10.0f; + return temperatura; +} + + + +char mapearCaractere(unsigned char valor) { + switch (valor) { + case 0b01000001: return 'A'; + case 0b01000010: return 'B'; + case 0b01000011: return 'C'; + case 0b01000100: return 'D'; + case 0b01000101: return 'E'; + case 0b01000110: return 'F'; + case 0b01000111: return 'G'; + case 0b01001000: return 'H'; + case 0b01001001: return 'I'; + case 0b01001010: return 'J'; + case 0b01001011: return 'K'; + case 0b01001100: return 'L'; + case 0b01001101: return 'M'; + case 0b01001110: return 'N'; + case 0b01001111: return 'O'; + case 0b01010000: return 'P'; + case 0b01010001: return 'Q'; + case 0b01010010: return 'R'; + case 0b01010011: return 'S'; + case 0b01010100: return 'T'; + case 0b01010101: return 'U'; + case 0b01010110: return 'V'; + case 0b01010111: return 'W'; + case 0b01011000: return 'X'; + case 0b01011001: return 'Y'; + case 0b01011010: return 'Z'; + case 0b01100001: return 'a'; + case 0b01100010: return 'b'; + case 0b01100011: return 'c'; + case 0b01100100: return 'd'; + case 0b01100101: return 'e'; + case 0b01100110: return 'f'; + case 0b01100111: return 'g'; + case 0b01101000: return 'h'; + case 0b01101001: return 'i'; + case 0b01101010: return 'j'; + case 0b01101011: return 'k'; + case 0b01101100: return 'l'; + case 0b01101101: return 'm'; + case 0b01101110: return 'n'; + case 0b01101111: return 'o'; + case 0b01110000: return 'p'; + case 0b01110001: return 'q'; + case 0b01110010: return 'r'; + case 0b01110011: return 's'; + case 0b01110100: return 't'; + case 0b01110101: return 'u'; + case 0b01110110: return 'v'; + case 0b01110111: return 'w'; + case 0b01111000: return 'x'; + case 0b01111001: return 'y'; + case 0b01111010: return 'z'; + default: + printf("Valor inválido! Não corresponde a uma letra.\n"); + return '\0'; // Retorna um caractere nulo para indicar erro + } +} + +char getLetra(unsigned short *reg, int pos){ + + if(pos == 0){ + return mapearCaractere( *reg & 0xFF); //0-7 + } + + else if(pos == 1){ + return mapearCaractere ((*reg >> 8) & 0xFF);//bit 8-15 + + } + + +} + diff --git a/biblioteca.o b/biblioteca.o new file mode 100644 index 0000000..733768c Binary files /dev/null and b/biblioteca.o differ diff --git a/compilar b/compilar new file mode 100644 index 0000000..c347d8a --- /dev/null +++ b/compilar @@ -0,0 +1,26 @@ +para rodar o trabalho pode se optar por utilizar pelo terminal: + +primeiro passo: + +gcc registers.c -o programa -L -lregisters + + +segundo passo: + +./programa + +terceiro passo: + +./emulator + + +esse programa também possui um makefile, podendo ser executado após a instalação do make na maquina pelo terminal + +após isso é só dar /make , ./programa e no final ./emulator + + + + +No código eu apenas cheguei a implementar 2/3 do que foi solicitado, é possível alterar a cor e o status de ligado ou desligado do display e a outra parte +foi implemtar um método que da um get no status da bateria, ambos funcionando e testados. Sobre o texto interativo, foi complicado já tentar tratar caracteres +especiais então acabei perdendo tempo lidando com ç e assentos. No fim ficando sem tempo para entender como poderia ser um display com mais de 24 caractéres. diff --git a/libregisters.a b/libregisters.a new file mode 100644 index 0000000..a235050 Binary files /dev/null and b/libregisters.a differ diff --git a/libregisters.h b/libregisters.h new file mode 100644 index 0000000..1d6b924 --- /dev/null +++ b/libregisters.h @@ -0,0 +1,37 @@ +#ifndef REGISTERS_H +#define REGISTERS_H + +#include + +// Definições dos registradores + + + +// Funções de configuração +void set_colorLed(unsigned short *r0, int bit10, int bit11, int bit12); +void set_colorDisplay(unsigned short *r1, unsigned short *r2, int red, int green, int blue); +void setOnOff(unsigned short *r0, int bit); +void setOnOff_Operacao(unsigned short *r0, int bit); +void setPadraoFabrica(unsigned short *r0, int bit); +void setExibicao(unsigned short *r0, int bit1, int bit2); +void setVelocidade(unsigned short *r0, int velocidade); +void setPalavras(unsigned short *reg, char letra, char letra2); + +// Funções de mapeamento de caracteres +unsigned char mapearLetra(unsigned char letra); +char mapearCaractere(unsigned char valor); + +// Funções de GET +const char *getEstadoDisplay(unsigned short *r0); +const char *getEstadoLed(unsigned short *r0); +const char *getCorLed(unsigned short *r0); +const char *getCorDisplay(unsigned short *r1, unsigned short *r2); +const char *getBateryLevel(unsigned short *r3); +const char *getModoExibicao(unsigned short *r0); +int calcularQuantidadeMensagem(unsigned short *r3); +int calcularVelocidade(unsigned short *r0); +float calcularTemperatura(unsigned short *r3); +char getLetra(unsigned short *reg, int pos); + + +#endif /* REGISTERS_H */ \ No newline at end of file diff --git a/registers b/registers index 1a23377..b192b32 100755 Binary files a/registers and b/registers differ diff --git a/registers.bin b/registers.bin index 3fca702..101793f 100644 Binary files a/registers.bin and b/registers.bin differ diff --git a/registers.c b/registers.c index 78a50d5..46cc6c4 100644 --- a/registers.c +++ b/registers.c @@ -4,6 +4,7 @@ #include #include #include +#include "libregisters.h" #define FILE_PATH "registers.bin" #define FILE_SIZE 1024 // Same size as used in the first program @@ -51,23 +52,14 @@ int registers_release(void* map, int file_size, int fd) { } void print_binary(unsigned short value) { - // Comece a partir do bit mais significativo - for (int i = 15; i >= 0; i--) { - // Verifique se o bit na posição 'i' está definido - if (value & (1 << i)) { - printf("1"); - } else { - printf("0"); - } - - // Adicione espaços para melhor visualização - if (i % 4 == 0) { - printf(" "); - } + int i; + for (i = 15; i >= 0; i--) { + printf("%d", (value >> i) & 1); } printf("\n"); } + int main() { int fd; // Open the file and map it into memory @@ -79,32 +71,72 @@ int main() { unsigned short *base_address = (unsigned short *)map; unsigned short *r0 = base_address + 0x00; unsigned short *r1 = base_address + 0x01; - unsigned short *r2 = base_address + 0x00; - unsigned short *r3 = base_address + 0x01; - unsigned short *r4 = base_address + 0x00; - unsigned short *r5 = base_address + 0x01; - unsigned short *r6 = base_address + 0x00; - unsigned short *r7 = base_address + 0x01; - unsigned short *r8 = base_address + 0x00; - unsigned short *r9 = base_address + 0x01; - unsigned short *r10 = base_address + 0x00; - unsigned short *r11 = base_address + 0x01; - unsigned short *r12 = base_address + 0x00; - unsigned short *r13 = base_address + 0x01; - unsigned short *r14 = base_address + 0x00; - unsigned short *r15 = base_address + 0x01; - printf("Initial value of R0: 0x%02x\n", *r0); - printf("Initial value of R1: 0x%02x\n", *r1); + unsigned short *r2 = base_address + 0x02; + unsigned short *r3 = base_address + 0x03; + unsigned short *r4 = base_address + 0x04; + unsigned short *r5 = base_address + 0x05; + unsigned short *r6 = base_address + 0x06; + unsigned short *r7 = base_address + 0x07; + unsigned short *r8 = base_address + 0x08; + unsigned short *r9 = base_address + 0x09; + unsigned short *r10 = base_address + 0x10; + unsigned short *r11 = base_address + 0x11; + unsigned short *r12 = base_address + 0x12; + unsigned short *r13 = base_address + 0x13; + unsigned short *r14 = base_address + 0x14; + unsigned short *r15 = base_address + 0x15; + + + + // printf("Current value of R0: 0x%02x\n", *r0); + // printf("Current value of R1: 0x%02x\n", *r1); + + // Write a new value to R0 - *r0 = *r0 | 0x00; + // *r0 = *r0 | 0x00; + //alterar a cor do led + set_colorLed(r0,1,0, 1); + + //alterar a cor do display r, g e b + set_colorDisplay(r1,r2,0 , 1 ,1 ); + + //deixa o display ligado ou nao + setOnOff(r0,1); + + //teste a operacao + setOnOff_Operacao(r0,1); + + +//ta invertido + setExibicao(r0, 1,1); + //("O display esta %s\n", getEstadoDisplay(r0)); + + + //teste modo de exibição + printf("O display esta %s\n", getModoExibicao(r0)); + + //tese para pegar o nivel da bateria + printf("O nivel da bateria %s\n", getBateryLevel(r3)); + + setPalavras(r7, 'l', 'p'); + //teste para calculo de velocidade + //printf("N vezes %d\n", calcularVelocidade(r0)); + + //teste para calcular a temperatura + //printf("N vezes %f\n", calcularTemperatura(r3)); + + //printf("O display esta: %c\n", getLetra(r5,0)); + + + + + //print_binary(*r4); // Release resources if (registers_release(map, FILE_SIZE, fd) == -1) { return EXIT_FAILURE; } - printf("Valor de R0 em binário: "); - print_binary(r0); return EXIT_SUCCESS; -} \ No newline at end of file +} diff --git a/registers.o b/registers.o new file mode 100644 index 0000000..647a5d3 Binary files /dev/null and b/registers.o differ diff --git a/tool b/tool new file mode 100755 index 0000000..b192b32 Binary files /dev/null and b/tool differ