From 698f4f9387ae7ac2f15a2076035c0af0b33cbeae Mon Sep 17 00:00:00 2001 From: Ryan Holtz Date: Fri, 19 Oct 2012 03:38:51 +0000 Subject: [PATCH] - Added opcodes to Atmel AVR core: OR, SBCI, ORI, ST Y+, ADIW [Mooglyguy] - Fixed functional issues in Atmel AVR opcodes: COM, NEG, LSR [Mooglyguy] - Added basic Timer 1 support to Craft driver and hooked up the DAC, currently plays only a buzzing noise due to lacking EEPROM support [MooglyGuy] --- src/emu/cpu/avr8/avr8.c | 77 +++++++++++---- src/mess/drivers/craft.c | 205 +++++++++++++++++++-------------------- src/mess/machine/avr8.h | 6 +- 3 files changed, 164 insertions(+), 124 deletions(-) diff --git a/src/emu/cpu/avr8/avr8.c b/src/emu/cpu/avr8/avr8.c index 2760706d257..00f87955d90 100644 --- a/src/emu/cpu/avr8/avr8.c +++ b/src/emu/cpu/avr8/avr8.c @@ -62,6 +62,7 @@ enum #define RR3(op) ((op) & 0x0007) #define RR4(op) ((op) & 0x000f) #define RR5(op) ((((op) >> 5) & 0x0010) | ((op) & 0x000f)) +#define DCONST(op) (((op) >> 4) & 0x0003) #define KCONST6(op) ((((op) >> 2) & 0x0030) | ((op) & 0x000f)) #define KCONST7(op) (((op) >> 3) & 0x007f) #define KCONST8(op) ((((op) >> 4) & 0x00f0) | ((op) & 0x000f)) @@ -165,7 +166,6 @@ INLINE UINT8 POP(avr8_state *cpustate) static void avr8_set_irq_line(avr8_state *cpustate, UINT16 vector, int state) { - //printf( "OMFG SETTING IRQ LINE\n" ); // Horrible hack, not accurate if(state) { @@ -367,8 +367,14 @@ static CPU_EXECUTE( avr8 ) WRITE_IO_8(cpustate, RD5(op), rd); break; case 0x0800: // OR Rd,Rr - //output += sprintf( output, "OR R%d, R%d", RD5(op), RR5(op) ); - unimplemented_opcode(cpustate, op); + rd = READ_IO_8(cpustate, RD5(op)); + rr = READ_IO_8(cpustate, RR5(op)); + rd |= rr; + SREG_W(AVR8_SREG_V, 0); + SREG_W(AVR8_SREG_N, rd & 0x80); + SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); + SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0); + WRITE_IO_8(cpustate, RD5(op), rd); break; case 0x0c00: // MOV Rd,Rr WRITE_IO_8(cpustate, RD5(op), READ_IO_8(cpustate, RR5(op))); @@ -387,8 +393,16 @@ static CPU_EXECUTE( avr8 ) SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7)))); break; case 0x4000: // SBCI Rd,K - //output += sprintf( output, "SBCI R%d, 0x%02x", 16+RD4(op), KCONST8(op) ); - unimplemented_opcode(cpustate, op); + rd = READ_IO_8(cpustate, 16+RD4(op)); + rr = KCONST8(op); + res = rd - (rr + SREG_R(AVR8_SREG_C)); + WRITE_IO_8(cpustate, 16+RD4(op), res); + SREG_W(AVR8_SREG_H, (NOT(BIT(rd,3)) & BIT(rr,3)) | (BIT(rr,3) & BIT(res,3)) | (BIT(res,3) & NOT(BIT(rd,3)))); + SREG_W(AVR8_SREG_V, (BIT(rd,7) & NOT(BIT(rr,7)) & NOT(BIT(res,7))) | (NOT(BIT(rd,7)) & BIT(rr,7) & BIT(res,7))); + SREG_W(AVR8_SREG_N, BIT(res,7)); + SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); + SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0); + SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7)))); break; case 0x5000: // SUBI Rd,K rd = READ_IO_8(cpustate, 16+RD4(op)); @@ -403,8 +417,14 @@ static CPU_EXECUTE( avr8 ) SREG_W(AVR8_SREG_C, (NOT(BIT(rd,7)) & BIT(rr,7)) | (BIT(rr,7) & BIT(res,7)) | (BIT(res,7) & NOT(BIT(rd,7)))); break; case 0x6000: // ORI Rd,K - //output += sprintf( output, "ORI R%d, 0x%02x", 16+RD4(op), KCONST8(op) ); - unimplemented_opcode(cpustate, op); + rd = READ_IO_8(cpustate, 16+RD4(op)); + rr = KCONST8(op); + rd |= rr; + SREG_W(AVR8_SREG_V, 0); + SREG_W(AVR8_SREG_N, rd & 0x80); + SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); + SREG_W(AVR8_SREG_Z, (rd == 0) ? 1 : 0); + WRITE_IO_8(cpustate, 16+RD4(op), rd); break; case 0x7000: // ANDI Rd,K //output += sprintf( output, "ANDI R%d, 0x%02x", 16+RD4(op), KCONST8(op) ); @@ -527,8 +547,12 @@ static CPU_EXECUTE( avr8 ) unimplemented_opcode(cpustate, op); break; case 0x0009: // ST Y+,Rd - //output += sprintf( output, "ST Y+, R%d", RD5(op) ); - unimplemented_opcode(cpustate, op); + pd = YREG; + WRITE_IO_8(cpustate, pd, READ_IO_8(cpustate, RD5(op))); + pd++; + WRITE_IO_8(cpustate, 29, (pd >> 8) & 0x00ff); + WRITE_IO_8(cpustate, 28, pd & 0x00ff); + opcycles = 2; break; case 0x000a: // ST -Z,Rd //output += sprintf( output, "ST -Y , R%d", RD5(op) ); @@ -566,12 +590,13 @@ static CPU_EXECUTE( avr8 ) { case 0x0000: // COM Rd rd = READ_IO_8(cpustate, RD5(op)); - rd = ~rd; + res = ~rd; SREG_W(AVR8_SREG_C, 1); SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0); SREG_W(AVR8_SREG_N, BIT(res,7)); SREG_W(AVR8_SREG_V, 0); - SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) | SREG_R(AVR8_SREG_V)); + SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); + WRITE_IO_8(cpustate, RD5(op), res); break; case 0x0001: // NEG Rd rd = READ_IO_8(cpustate, RD5(op)); @@ -580,8 +605,9 @@ static CPU_EXECUTE( avr8 ) SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0); SREG_W(AVR8_SREG_N, BIT(res,7)); SREG_W(AVR8_SREG_V, (res == 0x80) ? 1 : 0); - SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) | SREG_R(AVR8_SREG_V)); + SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); SREG_W(AVR8_SREG_H, BIT(res,3) | BIT(rd,3)); + WRITE_IO_8(cpustate, RD5(op), res); break; case 0x0002: // SWAP Rd //output += sprintf( output, "SWAP R%d", RD5(op) ); @@ -608,6 +634,7 @@ static CPU_EXECUTE( avr8 ) SREG_W(AVR8_SREG_N, 0); SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C)); SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); + WRITE_IO_8(cpustate, RD5(op), res); break; case 0x0007: // ROR Rd //output += sprintf( output, "ROR R%d", RD5(op) ); @@ -694,23 +721,24 @@ static CPU_EXECUTE( avr8 ) { case 0x0000: // COM Rd rd = READ_IO_8(cpustate, RD5(op)); - rd = ~rd; + res = ~rd; SREG_W(AVR8_SREG_C, 1); SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0); SREG_W(AVR8_SREG_N, BIT(res,7)); SREG_W(AVR8_SREG_V, 0); - SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) | SREG_R(AVR8_SREG_V)); + SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); + WRITE_IO_8(cpustate, RD5(op), res); break; case 0x0001: // NEG Rd rd = READ_IO_8(cpustate, RD5(op)); res = 0 - rd; - WRITE_IO_8(cpustate, RD5(op), res); SREG_W(AVR8_SREG_C, (res == 0) ? 0 : 1); SREG_W(AVR8_SREG_Z, (res == 0) ? 1 : 0); SREG_W(AVR8_SREG_N, BIT(res,7)); SREG_W(AVR8_SREG_V, (res == 0x80) ? 1 : 0); - SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) | SREG_R(AVR8_SREG_V)); + SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); SREG_W(AVR8_SREG_H, BIT(res,3) | BIT(rd,3)); + WRITE_IO_8(cpustate, RD5(op), res); break; case 0x0002: // SWAP Rd //output += sprintf( output, "SWAP R%d", RD5(op) ); @@ -737,6 +765,7 @@ static CPU_EXECUTE( avr8 ) SREG_W(AVR8_SREG_N, 0); SREG_W(AVR8_SREG_V, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_C)); SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); + WRITE_IO_8(cpustate, RD5(op), res); break; case 0x0007: // ROR Rd //output += sprintf( output, "ROR R%d", RD5(op) ); @@ -839,8 +868,19 @@ static CPU_EXECUTE( avr8 ) } break; case 0x0600: // ADIW Rd+1:Rd,K - //output += sprintf( output, "ADIW R%d:R%d, 0x%02x", 24+(RD2(op) << 1)+1, 24+(RD2(op) << 1), KCONST6(op) ); - unimplemented_opcode(cpustate, op); + rd = READ_IO_8(cpustate, 24 + (DCONST(op) << 1)); + rr = READ_IO_8(cpustate, 25 + (DCONST(op) << 1)); + pd = rd; + pd |= rr << 8; + pd += KCONST6(op); + SREG_W(AVR8_SREG_V, BIT(pd,15) & NOT(BIT(rr,7))); + SREG_W(AVR8_SREG_N, BIT(pd,15)); + SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V)); + SREG_W(AVR8_SREG_Z, (pd == 0) ? 1 : 0); + SREG_W(AVR8_SREG_C, NOT(BIT(pd,15)) & BIT(rr,7)); + WRITE_IO_8(cpustate, 24 + (DCONST(op) << 1), pd & 0xff); + WRITE_IO_8(cpustate, 25 + (DCONST(op) << 1), (pd >> 8) & 0xff); + opcycles = 2; break; case 0x0700: // SBIW Rd+1:Rd,K //output += sprintf( output, "SBIW R%d:R%d, 0x%02x", 24+(RD2(op) << 1)+1, 24+(RD2(op) << 1), KCONST6(op) ); @@ -999,7 +1039,6 @@ static CPU_SET_INFO( avr8 ) switch (state) { - /* interrupt lines/exceptions */ case CPUINFO_INT_INPUT_STATE + AVR8_INT_RESET: avr8_set_irq_line(cpustate, AVR8_INT_RESET, info->i); break; case CPUINFO_INT_INPUT_STATE + AVR8_INT_INT0: avr8_set_irq_line(cpustate, AVR8_INT_INT0, info->i); break; diff --git a/src/mess/drivers/craft.c b/src/mess/drivers/craft.c index f3d0b184839..9a4161c780b 100644 --- a/src/mess/drivers/craft.c +++ b/src/mess/drivers/craft.c @@ -1,8 +1,7 @@ /*\ * * Linus Akesson's "Craft" * * -* * Skeleton driver by MooglyGuy -* * Partial rewrite by Harmony +* * Driver by MooglyGuy \*/ #include "emu.h" @@ -10,9 +9,9 @@ #include "machine/avr8.h" #include "sound/dac.h" -#define VERBOSE_LEVEL (0) +#define VERBOSE_LEVEL (99) -#define ENABLE_VERBOSE_LOG (1) +#define ENABLE_VERBOSE_LOG (0) #if ENABLE_VERBOSE_LOG INLINE void verboselog(running_machine &machine, int n_level, const char *s_fmt, ...) @@ -45,7 +44,8 @@ class craft_state : public driver_device { public: craft_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu") { m_timer0_increment = 1; @@ -56,18 +56,22 @@ public: virtual void machine_start(); + dac_device* dac; + UINT8 m_regs[0x100]; + required_device m_maincpu; + emu_timer* m_timer0_timer; - UINT8 m_timer0_top; + UINT8 m_timer0_top; INT32 m_timer0_increment; emu_timer* m_timer1_timer; - UINT16 m_timer1_top; + UINT16 m_timer1_top; INT32 m_timer1_increment; emu_timer* m_timer2_timer; - UINT8 m_timer2_top; + UINT8 m_timer2_top; INT32 m_timer2_increment; DECLARE_READ8_MEMBER(avr8_read); DECLARE_WRITE8_MEMBER(avr8_write); @@ -102,109 +106,77 @@ TIMER_CALLBACK_MEMBER(craft_state::avr8_timer0_tick) TIMER_CALLBACK_MEMBER(craft_state::avr8_timer1_tick) { - /* TODO: Handle comparison, setting OC1x pins, detection of BOTTOM and TOP + /* TODO: Handle comparison, setting OC1x pins, detection of BOTTOM and TOP */ - UINT16 count = AVR8_TCNT1; - count += m_timer1_increment; + UINT16 count = (m_regs[Avr8::REGIDX_TCNT1H] << 8) | m_regs[Avr8::REGIDX_TCNT1L]; + INT32 wgm1 = ((m_regs[Avr8::REGIDX_TCCR1B] & AVR8_TCCR1B_WGM1_32_MASK) >> 1) | + (m_regs[Avr8::REGIDX_TCCR1A] & AVR8_TCCR1A_WGM1_10_MASK); + + // Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer + //UINT8 compare_mode[2] = { (m_regs[Avr8::REGIDX_TCCR1A] & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT, + //(m_regs[Avr8::REGIDX_TCCR1A] & AVR8_TCCR1A_COM1B_MASK) >> AVR8_TCCR1A_COM1B_SHIFT }; + UINT16 ocr1[2] = { (m_regs[Avr8::REGIDX_OCR1AH] << 8) | m_regs[Avr8::REGIDX_OCR1AL], + (m_regs[Avr8::REGIDX_OCR1BH] << 8) | m_regs[Avr8::REGIDX_OCR1BL] }; + INT32 int_lines[2] = { AVR8_INT_T1COMPA, AVR8_INT_T1COMPB }; + INT32 int_masks[2] = { AVR8_TIMSK1_OCIE1A_MASK, AVR8_TIMSK1_OCIE1B_MASK }; + INT32 increment = m_timer1_increment; for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++) { - UINT8 mode = (reg == AVR8_REG_A) ? AVR8_TCCR1A_COM1A : AVR8_TCCR1A_COM1B; - switch(mode) + switch(wgm1) + { + case Avr8::WGM1_FAST_PWM_OCR: + if(count == ocr1[reg]) + { + if (reg == 0) + { + m_regs[Avr8::REGIDX_TIFR1] |= (1 << AVR8_TIFR1_TOV1_SHIFT); + count = 0; + increment = 0; + } + if (m_regs[Avr8::REGIDX_TIMSK1] & int_masks[reg]) + { + m_maincpu->set_input_line(int_lines[reg], 1); + } + } + else if(count == 0) + { + if (reg == 0) + { + m_regs[Avr8::REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK; + } + if (m_regs[Avr8::REGIDX_TIMSK1] & int_masks[reg]) + { + m_maincpu->set_input_line(int_lines[reg], 0); + } + } + break; + + default: + // TODO + break; + } + /* + switch(compare_mode[reg]) { case 0: //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Normal port operation (OC1 disconnected)\n"); break; case 1: - switch(AVR8_WGM1) - { - case Avr8::WGM1_NORMAL: - case Avr8::WGM1_CTC_OCR: - case Avr8::WGM1_CTC_ICR: - case Avr8::WGM1_FAST_PWM_8: - case Avr8::WGM1_FAST_PWM_9: - case Avr8::WGM1_FAST_PWM_10: - case Avr8::WGM1_PWM_8_PC: - case Avr8::WGM1_PWM_9_PC: - case Avr8::WGM1_PWM_10_PC: - case Avr8::WGM1_PWM_PFC_ICR: - case Avr8::WGM1_PWM_PC_ICR: - //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Normal port operation (OC1 disconnected)\n"); - break; - - case Avr8::WGM1_FAST_PWM_ICR: - case Avr8::WGM1_FAST_PWM_OCR: - case Avr8::WGM1_PWM_PFC_OCR: - case Avr8::WGM1_PWM_PC_OCR: - //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Toggle OC1A on compare match, OC1B disconnected\n"); - break; - } - break; - case 2: - switch(AVR8_WGM1) - { - case Avr8::WGM1_NORMAL: - case Avr8::WGM1_CTC_OCR: - case Avr8::WGM1_CTC_ICR: - //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Clear OC1%c on compare match\n", avr8_reg_name[reg]); - break; - - case Avr8::WGM1_PWM_8_PC: - case Avr8::WGM1_PWM_9_PC: - case Avr8::WGM1_PWM_10_PC: - case Avr8::WGM1_PWM_PFC_ICR: - case Avr8::WGM1_PWM_PC_ICR: - case Avr8::WGM1_PWM_PFC_OCR: - case Avr8::WGM1_PWM_PC_OCR: - //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Clear OC1%c on match when up-counting, set when down-counting\n", avr8_reg_name[reg]); - break; - - case Avr8::WGM1_FAST_PWM_8: - case Avr8::WGM1_FAST_PWM_9: - case Avr8::WGM1_FAST_PWM_10: - case Avr8::WGM1_FAST_PWM_ICR: - case Avr8::WGM1_FAST_PWM_OCR: - //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Clear OC1%c on compare match, set at BOTTOM\n", avr8_reg_name[reg]); - break; - } + // TODO break; case 3: - switch(AVR8_WGM1) - { - case Avr8::WGM1_NORMAL: - case Avr8::WGM1_CTC_OCR: - case Avr8::WGM1_CTC_ICR: - //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Set OC1%c on compare match\n", avr8_reg_name[reg]); - break; - - case Avr8::WGM1_PWM_8_PC: - case Avr8::WGM1_PWM_9_PC: - case Avr8::WGM1_PWM_10_PC: - case Avr8::WGM1_PWM_PFC_ICR: - case Avr8::WGM1_PWM_PC_ICR: - case Avr8::WGM1_PWM_PFC_OCR: - case Avr8::WGM1_PWM_PC_OCR: - //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Set OC1%c on match when up-counting, clear on match when down-counting\n", avr8_reg_name[reg]); - break; - - case Avr8::WGM1_FAST_PWM_8: - case Avr8::WGM1_FAST_PWM_9: - case Avr8::WGM1_FAST_PWM_10: - case Avr8::WGM1_FAST_PWM_ICR: - case Avr8::WGM1_FAST_PWM_OCR: - //verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Set OC1%c on compare match, clear at BOTTOM\n", avr8_reg_name[reg]); - break; - } - break; - default: - verboselog(machine(), 0, "avr8_update_timer1_compare_mode: Unknown COM1%c mode setting (%d)\n", avr8_reg_name[reg], mode); break; } + */ } - */ + + count += increment; + m_regs[Avr8::REGIDX_TCNT1H] = (count >> 8) & 0xff; + m_regs[Avr8::REGIDX_TCNT1L] = count & 0xff; } READ8_MEMBER(craft_state::avr8_read) @@ -263,22 +235,26 @@ static void avr8_change_ddr(running_machine &machine, int reg, UINT8 data) if(changed) { // TODO - verboselog(machine, 0, "avr8_change_port: DDR%c lines %02x changed\n", avr8_reg_name[reg], changed); + verboselog(machine, 0, "avr8_change_ddr: DDR%c lines %02x changed\n", avr8_reg_name[reg], changed); } } static void avr8_change_port(running_machine &machine, int reg, UINT8 data) { - //craft_state *state = machine.driver_data(); + craft_state *state = machine.driver_data(); UINT8 oldport = avr8_get_ddr(machine, reg); UINT8 newport = data; UINT8 changed = newport ^ oldport; + // TODO: When AVR8 is converted to emu/machine, this should be factored out to 8 single-bit callbacks per port if(changed) { // TODO - verboselog(machine, 0, "avr8_change_port: PORT%c lines %02x changed\n", avr8_reg_name[reg], changed); + //verboselog(machine, 0, "avr8_change_port: PORT%c lines %02x changed\n", avr8_reg_name[reg], changed); + if (reg == AVR8_REG_D) { + state->dac->write_unsigned8(data & 0x7f); + } } } @@ -342,21 +318,21 @@ static void avr8_disable_spi(running_machine &machine) static void avr8_spi_update_masterslave_select(running_machine &machine) { // TODO - craft_state *state = machine.driver_data(); + //craft_state *state = machine.driver_data(); verboselog(machine, 0, "avr8_spi_update_masterslave_select: TODO; AVR is %s\n", AVR8_SPCR_MSTR ? "Master" : "Slave"); } static void avr8_spi_update_clock_polarity(running_machine &machine) { // TODO - craft_state *state = machine.driver_data(); + //craft_state *state = machine.driver_data(); verboselog(machine, 0, "avr8_spi_update_clock_polarity: TODO; SCK is Active-%s\n", AVR8_SPCR_CPOL ? "Low" : "High"); } static void avr8_spi_update_clock_phase(running_machine &machine) { // TODO - craft_state *state = machine.driver_data(); + //craft_state *state = machine.driver_data(); verboselog(machine, 0, "avr8_spi_update_clock_phase: TODO; Sampling edge is %s\n", AVR8_SPCR_CPHA ? "Trailing" : "Leading"); } @@ -365,7 +341,7 @@ static const UINT8 avr8_spi_clock_divisor[8] = { 4, 16, 64, 128, 2, 8, 32, 64 }; static void avr8_spi_update_clock_rate(running_machine &machine) { // TODO - craft_state *state = machine.driver_data(); + //craft_state *state = machine.driver_data(); verboselog(machine, 0, "avr8_spi_update_clock_rate: TODO; New clock rate should be f/%d\n", avr8_spi_clock_divisor[AVR8_SPCR_SPR] / (AVR8_SPSR_SPR2X ? 2 : 1)); } @@ -448,6 +424,8 @@ static void avr8_change_timsk1(running_machine &machine, UINT8 data) UINT8 newtimsk = data; UINT8 changed = newtimsk ^ oldtimsk; + AVR8_TIMSK1 = newtimsk; + if(changed & AVR8_TIMSK1_ICIE1_MASK) { // Check for Input Capture Interrupt interrupt condition @@ -528,7 +506,9 @@ static void avr8_changed_tccr1a(running_machine &machine, UINT8 data) UINT8 newtccr = data; UINT8 changed = newtccr ^ oldtccr; - if(changed & AVR8_TCCR1A_WGM1_10) + state->m_regs[Avr8::REGIDX_TCCR1A] = newtccr; + + if(changed & AVR8_TCCR1A_WGM1_10_MASK) { // TODO avr8_update_timer1_waveform_gen_mode(machine); @@ -690,6 +670,8 @@ static void avr8_changed_tccr1b(running_machine &machine, UINT8 data) UINT8 newtccr = data; UINT8 changed = newtccr ^ oldtccr; + state->m_regs[Avr8::REGIDX_TCCR1B] = newtccr; + if(changed & AVR8_TCCR1B_ICNC1_MASK) { // TODO @@ -832,6 +814,7 @@ static void avr8_update_ocr1(running_machine &machine, UINT16 newval, UINT8 reg) UINT8 *p_reg_l = (reg == AVR8_REG_A) ? &AVR8_OCR1AL : &AVR8_OCR1BL; *p_reg_h = (UINT8)(newval >> 8); *p_reg_l = (UINT8)newval; + // TODO verboselog(machine, 0, "avr8_update_ocr1: TODO: new OCR1%c = %04x\n", avr8_reg_name[reg], newval); } @@ -892,6 +875,16 @@ WRITE8_MEMBER(craft_state::avr8_write) avr8_changed_tccr2a(machine(), data); break; + case Avr8::REGIDX_TCNT2: + //verboselog(machine(), 0, "AVR8: TCNT2 = %02x\n", data ); + AVR8_TCNT2 = data; + break; + + case Avr8::REGIDX_GTCCR: + //verboselog(machine(), 0, "AVR8: GTCCR = %02x\n", data ); + // TODO + break; + case Avr8::REGIDX_SPL: case Avr8::REGIDX_SPH: case Avr8::REGIDX_SREG: @@ -906,6 +899,10 @@ WRITE8_MEMBER(craft_state::avr8_write) avr8_change_spcr(machine(), data); break; + case Avr8::REGIDX_PORTD: + avr8_change_port(machine(), AVR8_REG_D, data); + break; + case Avr8::REGIDX_DDRD: avr8_change_ddr(machine(), AVR8_REG_D, data); break; @@ -980,7 +977,9 @@ void craft_state::machine_reset() AVR8_TCNT1H = 0; AVR8_TCNT1L = 0; - machine().device("dac")->write_unsigned8(0x00); + state->dac = machine().device("dac"); + + state->dac->write_unsigned8(0x00); } static MACHINE_CONFIG_START( craft, craft_state ) diff --git a/src/mess/machine/avr8.h b/src/mess/machine/avr8.h index daf7f94b04d..f67d9b74512 100644 --- a/src/mess/machine/avr8.h +++ b/src/mess/machine/avr8.h @@ -192,6 +192,8 @@ enum #define AVR8_TCNT1H (state->m_regs[Avr8::REGIDX_TCNT1H]) #define AVR8_TCNT1L (state->m_regs[Avr8::REGIDX_TCNT1L]) +#define AVR8_SREG_I 0x80 + #define AVR8_TCCR1B (state->m_regs[Avr8::REGIDX_TCCR1B]) #define AVR8_TCCR1B_ICNC1_MASK 0x80 #define AVR8_TCCR1B_ICNC1_SHIFT 7 @@ -210,7 +212,7 @@ enum #define AVR8_TCCR1A_WGM1_10_MASK 0x03 #define AVR8_TCCR1A_WGM1_10_SHIFT 0 #define AVR8_TCCR1A_COM1A ((AVR8_TCCR1A & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT) -#define AVR8_TCCR1A_COM1B ((AVR8_TCCR1A & AVR8_TCCR1A_COM1A_MASK) >> AVR8_TCCR1A_COM1A_SHIFT) +#define AVR8_TCCR1A_COM1B ((AVR8_TCCR1A & AVR8_TCCR1A_COM1B_MASK) >> AVR8_TCCR1A_COM1B_SHIFT) #define AVR8_TCCR1A_WGM1_10 (AVR8_TCCR1A & AVR8_TCCR1A_WGM1_10_MASK) #define AVR8_TIMSK1 (state->m_regs[Avr8::REGIDX_TIMSK1]) @@ -242,7 +244,7 @@ enum #define AVR8_TCCR2A_WGM2_10_MASK 0x03 #define AVR8_TCCR2A_WGM2_10_SHIFT 0 #define AVR8_TCCR2A_COM2A ((AVR8_TCCR2A & AVR8_TCCR2A_COM2A_MASK) >> AVR8_TCCR2A_COM2A_SHIFT) -#define AVR8_TCCR2A_COM2B ((AVR8_TCCR2A & AVR8_TCCR2A_COM2A_MASK) >> AVR8_TCCR2A_COM2A_SHIFT) +#define AVR8_TCCR2A_COM2B ((AVR8_TCCR2A & AVR8_TCCR2A_COM2B_MASK) >> AVR8_TCCR2A_COM2B_SHIFT) #define AVR8_TCCR2A_WGM2_10 (AVR8_TCCR2A & AVR8_TCCR1A_WGM2_10_MASK) #define AVR8_SPSR (state->m_regs[Avr8::REGIDX_SPSR])