ioport: Restore PIN to PORT values when DDR is set to output
[simavr] / simavr / sim / avr_eeprom.c
index 7cbd5a6..376cec8 100644 (file)
@@ -40,7 +40,7 @@ static avr_cycle_count_t avr_eei_raise(struct avr_t * avr, avr_cycle_count_t whe
        return 0;
 }
 
-static void avr_eeprom_write(avr_t * avr, uint8_t addr, uint8_t v, void * param)
+static void avr_eeprom_write(avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
 {
        avr_eeprom_t * p = (avr_eeprom_t *)param;
        uint8_t eempe = avr_regbit_get(avr, p->eempe);
@@ -50,9 +50,13 @@ static void avr_eeprom_write(avr_t * avr, uint8_t addr, uint8_t v, void * param)
        if (!eempe && avr_regbit_get(avr, p->eempe)) {
                avr_cycle_timer_register(avr, 4, avr_eempe_clear, p);
        }
-       
+
        if (eempe && avr_regbit_get(avr, p->eepe)) {    // write operation
-               uint16_t addr = avr->data[p->r_eearl] | (avr->data[p->r_eearh] << 8);
+               uint16_t addr;
+               if (p->r_eearh)
+                       addr = avr->data[p->r_eearl] | (avr->data[p->r_eearh] << 8);
+               else
+                       addr = avr->data[p->r_eearl];
        //      printf("eeprom write %04x <- %02x\n", addr, avr->data[p->r_eedr]);
                p->eeprom[addr] = avr->data[p->r_eedr]; 
                // Automatically clears that bit (?)
@@ -61,7 +65,11 @@ static void avr_eeprom_write(avr_t * avr, uint8_t addr, uint8_t v, void * param)
                avr_cycle_timer_register_usec(avr, 3400, avr_eei_raise, p); // 3.4ms here
        }
        if (avr_regbit_get(avr, p->eere)) {     // read operation
-               uint16_t addr = avr->data[p->r_eearl] | (avr->data[p->r_eearh] << 8);
+               uint16_t addr;
+               if (p->r_eearh)
+                       addr = avr->data[p->r_eearl] | (avr->data[p->r_eearh] << 8);
+               else
+                       addr = avr->data[p->r_eearl];
                avr->data[p->r_eedr] = p->eeprom[addr];
        //      printf("eeprom read %04x : %02x\n", addr, p->eeprom[addr]);
        }
@@ -79,19 +87,19 @@ static int avr_eeprom_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_para
        switch(ctl) {
                case AVR_IOCTL_EEPROM_SET: {
                        avr_eeprom_desc_t * desc = (avr_eeprom_desc_t*)io_param;
-                       if (!desc || !desc->size || !desc->ee || (desc->offset + desc->size) >= p->size) {
-                               printf("%s: AVR_IOCTL_EEPROM_SET Invalid argument\n",
+                       if (!desc || !desc->size || !desc->ee || (desc->offset + desc->size) > p->size) {
+                               AVR_LOG(port->avr, LOG_WARNING, "EEPROM: %s: AVR_IOCTL_EEPROM_SET Invalid argument\n",
                                                __FUNCTION__);
                                return -2;
                        }
                        memcpy(p->eeprom + desc->offset, desc->ee, desc->size);
-                       printf("%s: AVR_IOCTL_EEPROM_SET Loaded %d at offset %d\n",
+                       AVR_LOG(port->avr, LOG_TRACE, "EEPROM: %s: AVR_IOCTL_EEPROM_SET Loaded %d at offset %d\n",
                                        __FUNCTION__, desc->size, desc->offset);
                }       break;
                case AVR_IOCTL_EEPROM_GET: {
                        avr_eeprom_desc_t * desc = (avr_eeprom_desc_t*)io_param;
-                       if (!desc || (desc->offset + desc->size) >= p->size) {
-                               printf("%s: AVR_IOCTL_EEPROM_GET Invalid argument\n",
+                       if (!desc || (desc->offset + desc->size) > p->size) {
+                               AVR_LOG(port->avr, LOG_WARNING, "EEPROM: %s: AVR_IOCTL_EEPROM_GET Invalid argument\n",
                                                __FUNCTION__);
                                return -2;
                        }
@@ -105,9 +113,18 @@ static int avr_eeprom_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_para
        return res;
 }
 
+static void avr_eeprom_dealloc(struct avr_io_t * port)
+{
+       avr_eeprom_t * p = (avr_eeprom_t *)port;
+       if (p->eeprom)
+               free(p->eeprom);
+       p->eeprom = NULL;
+}
+
 static avr_io_t        _io = {
        .kind = "eeprom",
        .ioctl = avr_eeprom_ioctl,
+       .dealloc = avr_eeprom_dealloc,
 };
 
 void avr_eeprom_init(avr_t * avr, avr_eeprom_t * p)