From 9a10a193c326e5207f661c64523370ff5a9cd534 Mon Sep 17 00:00:00 2001 From: Daniele Verducci su MatissePenguin <daniele.verducci@gmail.com> Date: Tue, 27 Oct 2020 22:27:39 +0100 Subject: [PATCH] Experimenting with lcd cursor location instructions --- README.md | 33 +++- .../eeprom_programmer/eeprom_programmer.ino | 175 ++++++++++++++++++ assembly/bios/driver_hd44780.asm | 8 +- assembly/bios/main.asm | 27 ++- 4 files changed, 235 insertions(+), 8 deletions(-) create mode 100644 arduino/eeprom_programmer/eeprom_programmer/eeprom_programmer.ino diff --git a/README.md b/README.md index 6ea9ad5..9c39114 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,38 @@ Compilatore c: sdcc (da repo debian) Eeprom flash: minipro (da https://gitlab.com/DavidGriffith/minipro/) # Assembly -## Compilare assembly: +## Deploy +### Compilare assembly: `z80asm -i hd44780_lcd_test_procedure.asm -o rom.bin` -## Portare binario alla dimensione dell eeprom: +### Portare binario alla dimensione dell eeprom: `dd if=/dev/zero of=rom.bin bs=1 count=0 seek=8192` -## Scrivere su EEPROM: +### Scrivere su EEPROM: `minipro -w rom.bin -p "AT28C64B"` -## Leggere EEPROM: +### Leggere EEPROM: `minipro -r rom_read.bin -p "AT28C64B"` +## Istruzioni +### Dichiarare una variabile: +Usare EQU per assegnare una posizione di memoria nota (nella RAM) al nome variabile. +``` +myVar: EQU 0x800F ; init variable +ld hl, "A" ; load value into register +ld (myVar), hl ; copy value into variable +``` +NB: Se il programma si blocca, verificare che la variabile non sia stata dichiarata in una parte non scrivibile della memoria (ROM) +### Accedere ad una variabile +Modificarne il valore (nell'esempio: incrementarla di 1) +``` +ld a, (myVar) +inc a +ld (myVar), a +``` +Passarne il puntatore ad una funzione: +``` +ld bc, myVar +call lcd_print +``` # C -## Compilare c: +## Deploy +### Compilare c: `sdcc -mz80 test.c` diff --git a/arduino/eeprom_programmer/eeprom_programmer/eeprom_programmer.ino b/arduino/eeprom_programmer/eeprom_programmer/eeprom_programmer.ino new file mode 100644 index 0000000..b33cd6e --- /dev/null +++ b/arduino/eeprom_programmer/eeprom_programmer/eeprom_programmer.ino @@ -0,0 +1,175 @@ +/* ************** EEPROM PROGRAMMER ****************** + +HARDWARE: + + CORRISPONDENZA PIN EEPROM Atmel AT28C64B -> ARDUINO MEGA 2560 + (Compatibile con eeprom fino a 16 bit di address bus. In caso di altre eeprom collegare secondo datasheet) + NB: Nel caso della eeprom da 8k, ci sono solo 12 address bus, quindi gli altri 4 pin provenienti dall'Arduino + vengono lasciati disconnessi + + Arduino VCC 11 38 40 44 10 42 12 9 8 7 6 5 + Eeprom 28 27 26 25 24 23 22 21 20 19 18 17 16 15 + ____________________________________________________________________ + | | + | | + |_ | + |_) Atmel AT28C64B | + | | + | | + |____________________________________________________________________| + + Eeprom 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + Arduino 46 36 34 32 30 28 26 24 22 2 3 4 GND + + + + + CORRISPONDENZA FUNZIONALE: + + Address bus (A0...A15): 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52 + + Data bus (D0...D7): 2, 3, 4, 5, 6, 7, 8, 9 + + Control bus: + /OE 10 + /WE 11 + /CE 12 + +*/ + +const byte ROM_DATA[] = {0x76, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00}; + + +const byte ADDR_BUS[] = {52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22}; +const byte DATA_BUS[] = {9, 8, 7, 6, 5, 4, 3, 2}; +const byte CTRL_BUS_OE = 10; +const byte CTRL_BUS_WE = 11; +const byte CTRL_BUS_CE = 12; + +void setup() { + Serial.begin(57600); + for(int pin=0; pin < 16; pin++) { + pinMode(ADDR_BUS[pin], OUTPUT); + } + setDataBusAs(INPUT); + pinMode(CTRL_BUS_OE, OUTPUT); + pinMode(CTRL_BUS_WE, OUTPUT); + pinMode(CTRL_BUS_CE, OUTPUT); + digitalWrite(CTRL_BUS_OE, HIGH); //Active low + digitalWrite(CTRL_BUS_WE, HIGH); //Active low + digitalWrite(CTRL_BUS_CE, HIGH); //Active low + + delay(1000); + + //readRom(8192); + writeRom(); + verifyRom(); +} + +void writeRom() { + digitalWrite(CTRL_BUS_OE, HIGH); + setDataBusAs(OUTPUT); + Serial.print("Starting to write ROM... "); + for (int i=0; i<sizeof(ROM_DATA); i++) { + writeIntToAddressBus(i); + delayMicroseconds(5); // Address hold time (tAH) + digitalWrite(CTRL_BUS_CE, LOW); + digitalWrite(CTRL_BUS_WE, LOW); + writeByteToDataBus(ROM_DATA[i]); + delayMicroseconds(5); // Data setup time (tDS) + digitalWrite(CTRL_BUS_WE, HIGH); + digitalWrite(CTRL_BUS_CE, HIGH); //Active low + delayMicroseconds(5); // Data hold time (tDH) + } + setDataBusAs(INPUT); + Serial.println("Done."); +} + +void verifyRom() { + Serial.print("Starting to verify ROM... "); + digitalWrite(CTRL_BUS_WE, HIGH); //Active low + char output[50] = {}; + for (int i=0; i<sizeof(ROM_DATA); i++) { + writeIntToAddressBus(i); + delayMicroseconds(5); + digitalWrite(CTRL_BUS_OE, LOW); //Active low + digitalWrite(CTRL_BUS_CE, LOW); //Active low + delayMicroseconds(5); + byte readData = getData(); + if(readData != ROM_DATA[i]) { + sprintf(output, "Error at addr %04x: expected %02x, found %02x", i, ROM_DATA[i], readData); + Serial.println(output); + } + + while(true){} + digitalWrite(CTRL_BUS_OE, HIGH); //Active low + digitalWrite(CTRL_BUS_CE, HIGH); //Active low + delayMicroseconds(5); + } + Serial.println("Done."); +} + +void readRom(int bytes) { + digitalWrite(CTRL_BUS_WE, HIGH); //Active low + char output[50] = {}; + for (int i=0; i<bytes; i++) { + writeIntToAddressBus(i); + delayMicroseconds(5); + digitalWrite(CTRL_BUS_OE, LOW); //Active low + digitalWrite(CTRL_BUS_CE, LOW); //Active low + delayMicroseconds(5); + byte readData = getData(); + sprintf(output, "0x%02x ", readData); + Serial.print(output); + digitalWrite(CTRL_BUS_OE, HIGH); //Active low + digitalWrite(CTRL_BUS_CE, HIGH); //Active low + delayMicroseconds(5); + } + Serial.println("Done."); +} + +unsigned int getData() { + setDataBusAs(INPUT); + unsigned int data = 0; + for(int pin=0; pin < 8; pin++) { + byte b = digitalRead(DATA_BUS[pin]) ? 1 : 0; + data = (data << 1) + b; // Shifta di 1 e aggiunge il bit corrente. Serve per ricostruire il numero da binario + } + return data; +} + +void setDataBusAs(byte mode){ + for(int pin=0; pin < 8; pin++) { + pinMode(DATA_BUS[pin], mode); + } +} + +void writeByteToDataBus(byte j) { + setDataBusAs(OUTPUT); + for (int n=0; n<8; n++) + { + if((0x01&j) < 0x01) + { + digitalWrite(DATA_BUS[n],LOW); + } else { + digitalWrite(DATA_BUS[n],HIGH); + } + j>>=1; + } +} + + +void writeIntToAddressBus(int j) { + for (int n=0; n<16; n++) + { + if((0x01&j) < 0x01) + { + digitalWrite(ADDR_BUS[n],LOW); + } else { + digitalWrite(ADDR_BUS[n],HIGH); + } + j>>=1; + } +} + +void loop() {} diff --git a/assembly/bios/driver_hd44780.asm b/assembly/bios/driver_hd44780.asm index e60d083..11ad50c 100644 --- a/assembly/bios/driver_hd44780.asm +++ b/assembly/bios/driver_hd44780.asm @@ -1,6 +1,9 @@ ; HD44780 20x4 characters LCD display driver ; @author Daniele Verducci +; variables +;lcd_cur_x: EQU DRV_VAR_SPACE +;lcd_cur_y: lcd_cur_x + 1 ; functions @@ -36,7 +39,10 @@ lcd_print: ; @param B X-axis position (0 to 19) ; @param C Y-axis position (0 to 3) lcd_locate: - ; TODO + ld a,0xFE + out (LCD_INSTR_REG),a ; warns the lcd microcontroller that a command is coming + ld a,0xA8 + out (LCD_INSTR_REG),a ; place cursor to first char of second line ret ; Clears the screen diff --git a/assembly/bios/main.asm b/assembly/bios/main.asm index d51b6a6..dbf8a2f 100644 --- a/assembly/bios/main.asm +++ b/assembly/bios/main.asm @@ -1,8 +1,11 @@ ; Pat80 BIOS v0.01 ; @author: Daniele Verducci ; -; ROM is at 0x00 -; RAM is at 0x80 +; ROM is at 0x0000 +; RAM is at 0x8000 +; SYSTEM VAR SPACE: 0x8000 - 0x8FFF (4kb) +; DRIVERS VAR SPACE: 0x9000 - 0x9FFF (4kb) +; APPLICATION VAR SPACE: 0xA000 - 0xFFFF (24kb) ; LCD is at I/O 0x00 and 0x01 @@ -13,6 +16,9 @@ jp sysinit ; Startup vector: DO NOT MOVE! Must be the first instruction ; SYSTEM CONFIGURATION LCD_INSTR_REG: EQU %00000000 LCD_DATA_REG: EQU %00000001 +SYS_VAR_SPACE: EQU 0x8000 +DRV_VAR_SPACE: EQU 0x9000 +APP_VAR_SPACE: EQU 0xA000 ; CONSTANTS @@ -35,12 +41,29 @@ sysinit: ld bc, SYSINIT_GREETING call lcd_print ; write string to screen + call lcd_locate + ld bc, LIPSUM call lcd_print ;call lcd_cls ; clear screen + ;call count + halt +; count: +; myVar: EQU APP_VAR_SPACE ; init variable +; ld hl, "A" ; load value into register +; ld (myVar), hl ; copy value into variable +; call count_loop +; count_loop: +; ld bc, myVar +; call lcd_print +; ; increm var +; ld a, (myVar) +; inc a +; ld (myVar), a +; call count_loop