/* * AVR emulator * * Copyright (C) 2007 Michael Buesch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include "hardware.h" #include "memory.h" #include "pinout.h" #include "devices/timers.h" #include "devices/ports.h" #include #include #include struct avr_setup active_setup; static void init_iomap(struct avr_memory *mem) { int i; for (i = 0; i < NR_VIRT_IO_PORTS; i++) mem->physical_io_map[i] = IO_PORT_UNAVAILABLE; } #undef IO #define IO(virt, phys) mem->physical_io_map[IO_##virt] = (phys); static void mega8_io_setup(struct avr_memory *mem) { init_iomap(mem); IO(TWBR, 0x20); IO(TWSR, 0x21); IO(TWAR, 0x22); IO(TWDR, 0x23); IO(ADCL, 0x24); IO(ADCH, 0x25); IO(ADCSRA, 0x26); IO(ADMUX, 0x27); IO(ACSR, 0x28); IO(UBRRL, 0x29); IO(UCSRB, 0x2A); IO(UCSRA, 0x2B); IO(UDR, 0x2C); IO(SPCR, 0x2D); IO(SPSR, 0x2E); IO(SPDR, 0x2F); IO(PIND, 0x30); IO(DDRD, 0x31); IO(PORTD, 0x32); IO(PINC, 0x33); IO(DDRC, 0x34); IO(PORTC, 0x35); IO(PINB, 0x36); IO(DDRB, 0x37); IO(PORTB, 0x38); IO(EECR, 0x3C); IO(EEDR, 0x3D); IO(EEARL, 0x3E); IO(EEARH, 0x3F); IO(UCSRC, 0x40); IO(UBRRH, 0x40); IO(WDTCR, 0x41); IO(ASSR, 0x42); IO(OCR2, 0x43); IO(TCNT2, 0x44); IO(TCCR2, 0x45); IO(ICR1L, 0x46); IO(ICR1H, 0x47); IO(OCR1BL, 0x48); IO(OCR1BH, 0x49); IO(OCR1AL, 0x4A); IO(OCR1AH, 0x4B); IO(TCNT1L, 0x4C); IO(TCNT1H, 0x4D); IO(TCCR1B, 0x4E); IO(TCCR1A, 0x4F); IO(SFIOR, 0x50); IO(OSCAL, 0x51); IO(TCNT0, 0x52); IO(TCCR0, 0x53); IO(MCUCSR, 0x54); IO(MCUCR, 0x55); IO(TWCR, 0x56); IO(SPMCR, 0x57); IO(TIFR, 0x58); IO(TIMSK, 0x59); IO(GIFR, 0x5A); IO(GICR, 0x5B); IO(SPL, 0x5D); IO(SPH, 0x5E); IO(SREG, 0x5F); //TODO init the peripheral hardware. } static void mega48_88_168_io_setup(struct avr_memory *mem) { init_iomap(mem); IO(PINB, 0x23); IO(DDRB, 0x24); IO(PORTB, 0x25); IO(PINC, 0x26); IO(DDRC, 0x27); IO(PORTC, 0x28); IO(PIND, 0x29); IO(DDRD, 0x2A); IO(PORTD, 0x2B); IO(TIFR0, 0x35); IO(TIFR1, 0x36); IO(TIFR2, 0x37); IO(PCIFR, 0x3B); IO(EIFR, 0x3C); IO(EIMSK, 0x3D); IO(GPIOR0, 0x3E); IO(EECR, 0x3F); IO(EEDR, 0x40); IO(EEARL, 0x41); IO(EEARH, 0x42); IO(GTCCR, 0x43); IO(TCCR0A, 0x44); IO(TCCR0B, 0x45); IO(TCNT0, 0x46); IO(OCR0A, 0x47); IO(OCR0B, 0x48); IO(GPIOR1, 0x4A); IO(GPIOR2, 0x4B); IO(SPCR, 0x4C); IO(SPSR, 0x4D); IO(SPDR, 0x4E); IO(ACSR, 0x50); IO(SMCR, 0x53); IO(MCUSR, 0x54); IO(MCUCR, 0x55); IO(SPMCSR, 0x57); IO(SPL, 0x5D); IO(SPH, 0x5E); IO(SREG, 0x5F); IO(WDRCSR, 0x60); IO(CLKPR, 0x61); IO(PRR, 0x64); IO(OSCAL, 0x66); IO(PCICR, 0x68); IO(EICRA, 0x69); IO(PCMSK0, 0x6B); IO(PCMSK1, 0x6C); IO(PCMSK2, 0x6D); IO(TIMSK0, 0x6E); IO(TIMSK1, 0x6F); IO(TIMSK2, 0x70); IO(ADCL, 0x78); IO(ADCH, 0x79); IO(ADCSRA, 0x7A); IO(ADCSRB, 0x7B); IO(ADMUX, 0x7C); IO(DIDR0, 0x7E); IO(DIDR1, 0x7F); IO(TCCR1A, 0x80); IO(TCCR1B, 0x81); IO(TCCR1C, 0x82); IO(TCNT1L, 0x84); IO(TCNT1H, 0x85); IO(ICR1L, 0x86); IO(ICR1H, 0x87); IO(OCR1AL, 0x88); IO(OCR1AH, 0x89); IO(OCR1BL, 0x8A); IO(OCR1BH, 0x8B); IO(TCCR2A, 0xB0); IO(TCCR2B, 0xB1); IO(TCNT2, 0xB2); IO(OCR2A, 0xB3); IO(OCR2B, 0xB4); IO(ASSR, 0xB6); IO(TWBR, 0xB8); IO(TWSR, 0xB9); IO(TWAR, 0xBA); IO(TWDR, 0xBB); IO(TWCR, 0xBC); IO(TWAMR, 0xBD); IO(UCSR0A, 0xC0); IO(UCSR0B, 0xC1); IO(UCSR0C, 0xC2); IO(UBRR0L, 0xC4); IO(UBRR0H, 0xC5); IO(UDR0, 0xC6); //TODO init the peripheral hardware. avrdev_timers_init(); avrdev_ports_init(); } #undef IO #define kiB * 1024 #define Mhz * 1000000 static const struct avr_setup setup_list[] = { [AVR_ATMEGA8] = { .type = AVR_ATMEGA8, .pinout = &atmega8_pinout, .memory_size = 0x460, .sram_offset = 0x60, .sp_offset = 0x3D, .pc_22bit = 0, .flash_size = 8 kiB, .eeprom_size = 512, .max_hz = 16 Mhz, .io_setup = mega8_io_setup, }, [AVR_ATMEGA168] = { .type = AVR_ATMEGA168, .pinout = &atmega48_88_168_pinout, .memory_size = 0x500, .sram_offset = 0x100, .sp_offset = 0x3D, .pc_22bit = 0, .flash_size = 16 kiB, .eeprom_size = 512, .max_hz = 20 Mhz, .io_setup = mega48_88_168_io_setup, }, }; void avr_do_cleanup(void) { memory_cleanup(); free(active_setup.memory_data); } int avr_do_setup(enum avr_setup_type type) { int err; break_linkage_on(ARRAY_SIZE(setup_list) != AVR_NR_TYPES, setup_not_defined_for_all_architectures); if (type >= ARRAY_SIZE(setup_list)) { fprintf(stderr, "Unsupported architecture\n"); return -ENODEV; } memcpy(&active_setup, &(setup_list[type]), sizeof(active_setup)); active_setup.memory_data = malloc(active_setup.memory_size); if (!active_setup.memory_data) { fprintf(stderr, "Out of memory\n"); return -ENOMEM; } err = memory_initialize(); if (err) goto err_free_mem; memset(&active_pinout_handlers, 0, sizeof(active_pinout_handlers)); return 0; err_free_mem: free(active_setup.memory_data); return err; }