Previous 199869 Revisions Next

r18881 Wednesday 7th November, 2012 at 01:00:44 UTC by Ryan Holtz
01234567890123456789012345678901234567890123456789012345678901234567890123456789
- avr8.c: Renamed io map to data map, routed ports through io map [MooglyGuy]

- avr8.c: Implemented ST Z+ and SBIW opcodes [MooglyGuy]

- craft.c: Converted to use new AVR8 core [MooglyGuy]
[src/emu/cpu/avr8]avr8.c avr8.h
[src/mess/drivers]craft.c uzebox.c

trunk/src/emu/cpu/avr8/avr8.c
r18880r18881
99      the existing opcodes has been shown to wildly corrupt the video output in Craft, so one can assume that the
1010      existing timing is 100% correct.
1111
12     Unimplemented opcodes: CPSR, LD Z+, ST Z+, ST -Z/-Y/-X, ELPM, SPM, SPM Z+, EIJMP, SLEEP, BREAK, WDR, ICALL,
13                            EICALL, JMP, CALL, SBIW
12     Unimplemented opcodes: CPSR, LD Z+, ST -Z/-Y/-X, ELPM, SPM, SPM Z+, EIJMP, SLEEP, BREAK, WDR, ICALL, EICALL,
13                            JMP, CALL
1414
1515   - Changelist -
1616     30 Oct. 2012
r18880r18881
9595
9696enum
9797{
98   WGM2_NORMAL = 0,
99   WGM2_PWM_PC,
100   WGM2_CTC_CMP,
101   WGM2_FAST_PWM,
102   WGM2_RESERVED0,
103   WGM2_PWM_PC_CMP,
104   WGM2_RESERVED1,
105   WGM2_FAST_PWM_CMP
98   WGM02_NORMAL = 0,
99   WGM02_PWM_PC,
100   WGM02_CTC_CMP,
101   WGM02_FAST_PWM,
102   WGM02_RESERVED0,
103   WGM02_PWM_PC_CMP,
104   WGM02_RESERVED1,
105   WGM02_FAST_PWM_CMP
106106};
107107
108108static const char avr8_reg_name[4] = { 'A', 'B', 'C', 'D' };
109109
110#define SREG_R(b) ((m_status & (1 << (b))) >> (b))
111#define SREG_W(b,v) m_status = (m_status & ~(1 << (b))) | ((v) << (b))
110#define SREG_R(b) ((m_r[AVR8_REGIDX_SREG] & (1 << (b))) >> (b))
111#define SREG_W(b,v) m_r[AVR8_REGIDX_SREG] = (m_r[AVR8_REGIDX_SREG] & ~(1 << (b))) | ((v) << (b))
112112#define NOT(x) (1 - (x))
113113
114114// Opcode-Parsing Defines
r18880r18881
145145#define AVR8_TCNT1H            (m_r[AVR8_REGIDX_TCNT1H])
146146#define AVR8_TCNT1L            (m_r[AVR8_REGIDX_TCNT1L])
147147
148#define AVR8_TCCR0B               (m_r[AVR8_REGIDX_TCCR0B])
149#define AVR8_TCCR0B_FOC0A_MASK      0x80
150#define AVR8_TCCR0B_FOC0A_SHIFT      7
151#define AVR8_TCCR0B_FOC0B_MASK      0x40
152#define AVR8_TCCR0B_FOC0B_SHIFT      6
153#define AVR8_TCCR0B_WGM0_2_MASK      0x08
154#define AVR8_TCCR0B_WGM0_2_SHIFT   3
155#define AVR8_TCCR0B_CS_MASK         0x07
156#define AVR8_TCCR0B_CS_SHIFT      0
157#define AVR8_TIMER0_CLOCK_SELECT   (AVR8_TCCR0B & AVR8_TCCR0B_CS_MASK)
158
159#define AVR8_TCCR0A               (m_r[AVR8_REGIDX_TCCR0A])
160#define AVR8_TCCR0A_COM0A_MASK      0xc0
161#define AVR8_TCCR0A_COM0A_SHIFT      6
162#define AVR8_TCCR0A_COM0B_MASK      0x30
163#define AVR8_TCCR0A_COM0B_SHIFT      4
164#define AVR8_TCCR0A_WGM0_10_MASK   0x03
165#define AVR8_TCCR0A_WGM0_10_SHIFT   0
166#define AVR8_TCCR0A_COM0A         ((AVR8_TCCR0A & AVR8_TCCR0A_COM0A_MASK) >> AVR8_TCCR0A_COM0A_SHIFT)
167#define AVR8_TCCR0A_COM0B         ((AVR8_TCCR0A & AVR8_TCCR0A_COM0B_MASK) >> AVR8_TCCR0A_COM0B_SHIFT)
168#define AVR8_TCCR0A_WGM0_10         (AVR8_TCCR0A & AVR8_TCCR0A_WGM0_10_MASK)
169
170#define AVR8_TIMSK0            (m_r[AVR8_REGIDX_TIMSK0])
171#define AVR8_TIMSK0_OCIE0B_MASK   0x04
172#define AVR8_TIMSK0_OCIE0A_MASK   0x02
173#define AVR8_TIMSK0_TOIE0_MASK   0x01
174#define AVR8_TIMSK0_OCIE0B      ((AVR8_TIMSK0 & AVR8_TIMSK0_OCIE0B_MASK) >> 2)
175#define AVR8_TIMSK0_OCIE0A      ((AVR8_TIMSK0 & AVR8_TIMSK0_OCIE0A_MASK) >> 1)
176#define AVR8_TIMSK0_TOIE0      (AVR8_TIMSK0 & AVR8_TIMSK0_TOIE0_MASK)
177
178#define AVR8_TIFR0            (m_r[AVR8_REGIDX_TIFR0])
179#define AVR8_TIFR0_OCF0B_MASK   0x04
180#define AVR8_TIFR0_OCF0B_SHIFT   2
181#define AVR8_TIFR0_OCF0A_MASK   0x02
182#define AVR8_TIFR0_OCF0A_SHIFT   1
183#define AVR8_TIFR0_TOV0_MASK   0x01
184#define AVR8_TIFR0_TOV0_SHIFT   0
185#define AVR8_TIFR0_MASK         (AVR8_TIFR0_TOV0_MASK | AVR8_TIFR0_OCF0B_MASK | AVR8_TIFR0_OCF0A_MASK)
186
148187#define AVR8_TCCR1B               (m_r[AVR8_REGIDX_TCCR1B])
149188#define AVR8_TCCR1B_ICNC1_MASK      0x80
150189#define AVR8_TCCR1B_ICNC1_SHIFT      7
r18880r18881
189228#define AVR8_TIFR1_MASK         (AVR8_TIFR1_ICF1_MASK | AVR8_TIFR1_TOV1_MASK | \
190229                         AVR8_TIFR1_OCF1B_MASK | AVR8_TIFR1_OCF1A_MASK)
191230
192#define AVR8_TCCR2B               (m_r[AVR8_REGIDX_TCCR1B])
231#define AVR8_TCCR2B               (m_r[AVR8_REGIDX_TCCR2B])
193232#define AVR8_TCCR2B_FOC2A_MASK      0x80
194233#define AVR8_TCCR2B_FOC2A_SHIFT      7
195234#define AVR8_TCCR2B_FOC2B_MASK      0x40
r18880r18881
200239#define AVR8_TCCR2B_CS_SHIFT      0
201240#define AVR8_TIMER2_CLOCK_SELECT   (AVR8_TCCR2B & AVR8_TCCR2B_CS_MASK)
202241
203#define AVR8_TCCR2A               (m_r[AVR8_REGIDX_TCCR1A])
242#define AVR8_TCCR2A               (m_r[AVR8_REGIDX_TCCR2A])
204243#define AVR8_TCCR2A_COM2A_MASK      0xc0
205244#define AVR8_TCCR2A_COM2A_SHIFT      6
206245#define AVR8_TCCR2A_COM2B_MASK      0x30
r18880r18881
209248#define AVR8_TCCR2A_WGM2_10_SHIFT   0
210249#define AVR8_TCCR2A_COM2A         ((AVR8_TCCR2A & AVR8_TCCR2A_COM2A_MASK) >> AVR8_TCCR2A_COM2A_SHIFT)
211250#define AVR8_TCCR2A_COM2B         ((AVR8_TCCR2A & AVR8_TCCR2A_COM2B_MASK) >> AVR8_TCCR2A_COM2B_SHIFT)
212#define AVR8_TCCR2A_WGM2_10         (AVR8_TCCR2A & AVR8_TCCR1A_WGM2_10_MASK)
251#define AVR8_TCCR2A_WGM2_10         (AVR8_TCCR2A & AVR8_TCCR2A_WGM2_10_MASK)
213252
214253#define AVR8_TIMSK2            (m_r[AVR8_REGIDX_TIMSK2])
215254#define AVR8_TIMSK2_OCIE2B_MASK   0x04
216255#define AVR8_TIMSK2_OCIE2A_MASK   0x02
217256#define AVR8_TIMSK2_TOIE2_MASK   0x01
218#define AVR8_TIMSK2_OCIE2B      ((AVR8_TIMSK2 & AVR8_TIMSK1_OCIE2B_MASK) >> 2)
219#define AVR8_TIMSK2_OCIE2A      ((AVR8_TIMSK2 & AVR8_TIMSK1_OCIE2A_MASK) >> 1)
220#define AVR8_TIMSK2_TOIE2      (AVR8_TIMSK2 & AVR8_TIMSK1_TOIE2_MASK)
257#define AVR8_TIMSK2_OCIE2B      ((AVR8_TIMSK2 & AVR8_TIMSK2_OCIE2B_MASK) >> 2)
258#define AVR8_TIMSK2_OCIE2A      ((AVR8_TIMSK2 & AVR8_TIMSK2_OCIE2A_MASK) >> 1)
259#define AVR8_TIMSK2_TOIE2      (AVR8_TIMSK2 & AVR8_TIMSK2_TOIE2_MASK)
221260
222261#define AVR8_TIFR2            (m_r[AVR8_REGIDX_TIFR2])
223262#define AVR8_TIFR2_OCF2B_MASK   0x04
r18880r18881
228267#define AVR8_TIFR2_TOV2_SHIFT   0
229268#define AVR8_TIFR2_MASK         (AVR8_TIFR2_TOV2_MASK | AVR8_TIFR2_OCF2B_MASK | AVR8_TIFR2_OCF2A_MASK)
230269
270#define AVR8_OCR0A            m_r[AVR8_REGIDX_OCR0A]
271#define AVR8_OCR0B            m_r[AVR8_REGIDX_OCR0B]
272#define AVR8_TCNT0            m_r[AVR8_REGIDX_TCNT0]
273#define AVR8_WGM0            (((AVR8_TCCR0B & 0x08) >> 1) | (AVR8_TCCR0A & 0x03))
274
231275#define AVR8_OCR1A            ((AVR8_OCR1AH << 8) | AVR8_OCR1AL)
232276#define AVR8_OCR1B            ((AVR8_OCR1BH << 8) | AVR8_OCR1BL)
233277#define AVR8_ICR1            ((AVR8_ICR1H  << 8) | AVR8_ICR1L)
r18880r18881
235279#define AVR8_WGM1            (((AVR8_TCCR1B & 0x18) >> 1) | (AVR8_TCCR1A & 0x03))
236280#define AVR8_TCNT1_DIR         (state->m_tcnt1_direction)
237281
282#define AVR8_OCR2A            m_r[AVR8_REGIDX_OCR2A]
238283#define AVR8_OCR2B            m_r[AVR8_REGIDX_OCR2B]
239#define AVR8_OCR2A            m_r[AVR8_REGIDX_OCR2A]
240284#define AVR8_TCNT2            m_r[AVR8_REGIDX_TCNT2]
241285#define AVR8_WGM2            (((AVR8_TCCR2B & 0x08) >> 1) | (AVR8_TCCR2A & 0x03))
242286
243287#define AVR8_GTCCR_PSRASY_MASK   0x02
244288#define AVR8_GTCCR_PSRASY_SHIFT   1
245289
290#define AVR8_SPSR            (m_r[AVR8_REGIDX_SPSR])
291#define AVR8_SPSR_SPR2X         (AVR8_SPSR & AVR8_SPSR_SPR2X_MASK)
292
293#define AVR8_SPCR            (m_r[AVR8_REGIDX_SPCR])
294#define AVR8_SPCR_SPIE         ((AVR8_SPCR & AVR8_SPCR_SPIE_MASK) >> 7)
295#define AVR8_SPCR_SPE         ((AVR8_SPCR & AVR8_SPCR_SPE_MASK) >> 6)
296#define AVR8_SPCR_DORD         ((AVR8_SPCR & AVR8_SPCR_DORD_MASK) >> 5)
297#define AVR8_SPCR_MSTR         ((AVR8_SPCR & AVR8_SPCR_MSTR_MASK) >> 4)
298#define AVR8_SPCR_CPOL         ((AVR8_SPCR & AVR8_SPCR_CPOL_MASK) >> 3)
299#define AVR8_SPCR_CPHA         ((AVR8_SPCR & AVR8_SPCR_CPHA_MASK) >> 2)
300#define AVR8_SPCR_SPR         (AVR8_SPCR & AVR8_SPCR_SPR_MASK)
301
302#define AVR8_SPI_RATE         ((AVR8_SPSR_SPR2X << 2) | AVR8_SPCR_SPR)
303
304#define AVR8_PORTB_MOSI         0x08
305
246306//**************************************************************************
247307//  DEVICE INTERFACE
248308//**************************************************************************
r18880r18881
250310const device_type ATMEGA88 = &device_creator<atmega88_device>;
251311const device_type ATMEGA644 = &device_creator<atmega644_device>;
252312
313//**************************************************************************
314//  INTERNAL ADDRESS MAP
315//**************************************************************************
316
317static ADDRESS_MAP_START( avr8_internal_map, AS_DATA, 8, avr8_device )
318   AM_RANGE(0x0000, 0x00ff) AM_READWRITE( regs_r, regs_w )
319ADDRESS_MAP_END
320
253321//-------------------------------------------------
254//  atmega8_device - constructor
322//  atmega88_device - constructor
255323//-------------------------------------------------
256324
257avr8_device::avr8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, const device_type type, UINT32 addr_mask)
325atmega88_device::atmega88_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
326   : avr8_device(mconfig, tag, owner, clock, ATMEGA88, 0x0fff, ADDRESS_MAP_NAME(avr8_internal_map))
327{
328}
329
330//-------------------------------------------------
331//  atmega644_device - constructor
332//-------------------------------------------------
333
334atmega644_device::atmega644_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
335   : avr8_device(mconfig, tag, owner, clock, ATMEGA644, 0xffff, ADDRESS_MAP_NAME(avr8_internal_map))
336{
337}
338
339//-------------------------------------------------
340//  avr8_device - constructor
341//-------------------------------------------------
342
343avr8_device::avr8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, const device_type type, UINT32 addr_mask, address_map_constructor internal_map)
258344   : cpu_device(mconfig, type, "AVR8", tag, owner, clock),
259345     m_program_config("program", ENDIANNESS_LITTLE, 8, 22),
260     m_io_config("io", ENDIANNESS_LITTLE, 8, 16),
346     m_data_config("data", ENDIANNESS_LITTLE, 8, 16, 0, internal_map),
347     m_io_config("io", ENDIANNESS_LITTLE, 8, 2),
348     m_eeprom(NULL),
261349      m_pc(0),
262      m_debugger_pc(0),
263      m_status(0),
350      m_shifted_pc(0),
264351      m_timer0_top(0),
265352      m_timer0_increment(1),
266353      m_timer0_prescale(0),
r18880r18881
273360      m_timer2_increment(1),
274361      m_timer2_prescale(0),
275362      m_timer2_prescale_count(0),
363      m_spi_active(false),
364      m_spi_prescale(0),
365      m_spi_prescale_count(0),
276366      m_addr_mask(addr_mask),
277367      m_interrupt_pending(false),
278368      m_icount(0),
r18880r18881
341431    m_pc = 0;
342432
343433    m_program = &space(AS_PROGRAM);
434    m_data = &space(AS_DATA);
344435    m_io = &space(AS_IO);
345436
346437   // register our state for the debugger
347438   astring tempstr;
348   state_add(STATE_GENPC,     "GENPC",     m_pc).noshow();
349   state_add(STATE_GENFLAGS,  "GENFLAGS",  m_status).callimport().callexport().formatstr("%8s").noshow();
439   state_add(STATE_GENPC,     "GENPC",     m_shifted_pc).noshow();
440   state_add(STATE_GENFLAGS,  "GENFLAGS",  m_r[AVR8_REGIDX_SREG]).callimport().callexport().formatstr("%8s").noshow();
350441   state_add(AVR8_SREG,       "STATUS",    m_r[AVR8_REGIDX_SREG]).mask(0xff);
351   state_add(AVR8_PC,         "PC",        m_debugger_pc).mask(0xffff);
442   state_add(AVR8_PC,         "PC",        m_shifted_pc).mask(0xffff);
352443   state_add(AVR8_R0,         "R0",        m_r[ 0]).mask(0xff);
353444   state_add(AVR8_R1,         "R1",        m_r[ 1]).mask(0xff);
354445   state_add(AVR8_R2,         "R2",        m_r[ 2]).mask(0xff);
r18880r18881
384475
385476   // register our state for saving
386477   save_item(NAME(m_pc));
387   save_item(NAME(m_status));
388478   save_item(NAME(m_r));
389479   save_item(NAME(m_timer0_top));
390480   save_item(NAME(m_timer0_increment));
r18880r18881
405495
406496   // set our instruction counter
407497   m_icountptr = &m_icount;
498
499   m_eeprom = machine().root_device().memregion(eeprom_region)->base();
408500}
409501
410502//-------------------------------------------------
r18880r18881
413505
414506void avr8_device::device_reset()
415507{
416   m_status = 0;
417    io_write8(AVR8_REGIDX_SPL, 0);
418    io_write8(AVR8_REGIDX_SPH, 0);
508   m_r[AVR8_REGIDX_SPL] = 0;
509   m_r[AVR8_REGIDX_SPH] = 0;
419510
420   for (int i = 0; i < 32; i++)
511   for (int i = 0; i < 256; i++)
421512   {
422513      m_r[i] = 0;
423514   }
424515
516   m_spi_active = false;
517   m_spi_prescale = 0;
518   m_spi_prescale_count = 0;
519
425520    m_timer0_top = 0;
426521   m_timer0_increment = 1;
427522   m_timer0_prescale = 0;
r18880r18881
465560   {
466561      return &m_program_config;
467562   }
563   else if (spacenum == AS_DATA)
564   {
565      return &m_data_config;
566   }
468567   else if (spacenum == AS_IO)
469568   {
470569      return &m_io_config;
r18880r18881
484583   {
485584      case STATE_GENFLAGS:
486585         string.printf("%c%c%c%c%c%c%c%c",
487             (m_status & 0x80) ? 'I' : '-',
488             (m_status & 0x40) ? 'T' : '-',
489             (m_status & 0x20) ? 'H' : '-',
490             (m_status & 0x10) ? 'S' : '-',
491             (m_status & 0x08) ? 'V' : '-',
492             (m_status & 0x04) ? 'N' : '-',
493             (m_status & 0x02) ? 'Z' : '-',
494             (m_status & 0x01) ? 'C' : '-');
586             (m_r[AVR8_REGIDX_SREG] & 0x80) ? 'I' : '-',
587             (m_r[AVR8_REGIDX_SREG] & 0x40) ? 'T' : '-',
588             (m_r[AVR8_REGIDX_SREG] & 0x20) ? 'H' : '-',
589             (m_r[AVR8_REGIDX_SREG] & 0x10) ? 'S' : '-',
590             (m_r[AVR8_REGIDX_SREG] & 0x08) ? 'V' : '-',
591             (m_r[AVR8_REGIDX_SREG] & 0x04) ? 'N' : '-',
592             (m_r[AVR8_REGIDX_SREG] & 0x02) ? 'Z' : '-',
593             (m_r[AVR8_REGIDX_SREG] & 0x01) ? 'C' : '-');
495594         break;
496595   }
497596}
r18880r18881
535634//  MEMORY ACCESSORS
536635//**************************************************************************
537636
538inline UINT8 avr8_device::program_read8(UINT32 address)
539{
540    return m_program->read_byte(address);
541}
542
543inline UINT16 avr8_device::program_read16(UINT32 address)
544{
545    return m_program->read_word(address << 1);
546}
547
548inline void avr8_device::program_write8(UINT32 address, UINT8 data)
549{
550    m_program->write_byte(address, data);
551}
552
553inline void avr8_device::program_write16(UINT32 address, UINT16 data)
554{
555    m_program->write_word(address, data);
556}
557
558inline UINT8 avr8_device::io_read8(UINT16 address)
559{
560   if (address < 0x100)
561   {
562      // Allow unhandled internal registers to be handled by external driver
563      UINT8 data;
564      if (io_reg_read(address, &data))
565      {
566         return data;
567      }
568   }
569    return m_io->read_byte(address);
570}
571
572inline void avr8_device::io_write8(UINT16 address, UINT8 data)
573{
574   if (address < 0x100)
575   {
576      // Allow unhandled internal registers to be handled by external driver
577      if (io_reg_write(address, data))
578      {
579         return;
580      }
581   }
582    m_io->write_byte(address, data);
583}
584
585637inline void avr8_device::push(UINT8 val)
586638{
587639   UINT16 sp = SPREG;
588    io_write8(sp, val);
640    m_data->write_byte(sp, val);
589641    sp--;
590    io_write8(AVR8_REGIDX_SPL, sp & 0x00ff);
591    io_write8(AVR8_REGIDX_SPH, (sp >> 8) & 0x00ff);
642    m_r[AVR8_REGIDX_SPL] = sp & 0x00ff;
643    m_r[AVR8_REGIDX_SPH] = (sp >> 8) & 0x00ff;
592644}
593645
594646inline UINT8 avr8_device::pop()
595647{
596648   UINT16 sp = SPREG;
597649    sp++;
598   io_write8(AVR8_REGIDX_SPL, sp & 0x00ff);
599   io_write8(AVR8_REGIDX_SPH, (sp >> 8) & 0x00ff);
600    return io_read8(sp);
650   m_r[AVR8_REGIDX_SPL] = sp & 0x00ff;
651   m_r[AVR8_REGIDX_SPH] = (sp >> 8) & 0x00ff;
652    return m_data->read_byte(sp);
601653}
602654
603655//**************************************************************************
r18880r18881
615667         push((m_pc >> 8) & 0x00ff);
616668         push(m_pc & 0x00ff);
617669         m_pc = vector;
670         m_shifted_pc = vector << 1;
618671      }
619672      else
620673      {
r18880r18881
636689static const CInterruptCondition s_int_conditions[AVR8_INTIDX_COUNT] =
637690{
638691   { AVR8_INT_SPI_STC, AVR8_REGIDX_SPCR,   AVR8_SPCR_SPIE_MASK,     AVR8_REGIDX_SPSR,    AVR8_SPSR_SPIF_MASK },
692   { AVR8_INT_T0COMPB, AVR8_REGIDX_TIMSK0, AVR8_TIMSK0_OCIE0B_MASK, AVR8_REGIDX_TIFR0,   AVR8_TIFR0_OCF0B_MASK },
693   { AVR8_INT_T0COMPA, AVR8_REGIDX_TIMSK0, AVR8_TIMSK0_OCIE0A_MASK, AVR8_REGIDX_TIFR0,   AVR8_TIFR0_OCF0A_MASK },
694   { AVR8_INT_T0OVF,   AVR8_REGIDX_TIMSK0, AVR8_TIMSK0_TOIE0_MASK,  AVR8_REGIDX_TIFR0,   AVR8_TIFR0_TOV0_MASK },
639695   { AVR8_INT_T1CAPT,  AVR8_REGIDX_TIMSK1, AVR8_TIMSK1_ICIE1_MASK,  AVR8_REGIDX_TIFR1,   AVR8_TIFR1_ICF1_MASK },
640696   { AVR8_INT_T1COMPB, AVR8_REGIDX_TIMSK1, AVR8_TIMSK1_OCIE1B_MASK, AVR8_REGIDX_TIFR1,   AVR8_TIFR1_OCF1B_MASK },
641697   { AVR8_INT_T1COMPA, AVR8_REGIDX_TIMSK1, AVR8_TIMSK1_OCIE1A_MASK, AVR8_REGIDX_TIFR1,   AVR8_TIFR1_OCF1A_MASK },
r18880r18881
666722//**************************************************************************
667723void avr8_device::timer_tick(int cycles)
668724{
669   if (m_timer0_prescale != 0)
725   for(int count = 0; count < cycles; count++)
670726   {
671      m_timer0_prescale_count += cycles;
672      while(m_timer0_prescale_count >= m_timer0_prescale)
727      m_elapsed_cycles++;
728
729      if (m_spi_active && m_spi_prescale > 0 && m_spi_prescale_countdown >= 0)
673730      {
674         timer0_tick();
675         m_timer0_prescale_count -= m_timer0_prescale;
731         m_spi_prescale_count++;
732         if (m_spi_prescale_count >= m_spi_prescale)
733         {
734            UINT8 out_bit = (m_r[AVR8_REGIDX_SPDR] & (1 << m_spi_prescale_countdown)) >> m_spi_prescale_countdown;
735            m_spi_prescale_countdown--;
736            m_io->write_byte(0x01, (m_r[AVR8_REGIDX_PORTB] &~ AVR8_PORTB_MOSI) | (out_bit ? AVR8_PORTB_MOSI : 0));
737            m_r[AVR8_REGIDX_PORTB] = (m_r[AVR8_REGIDX_PORTB] &~ AVR8_PORTB_MOSI) | (out_bit ? AVR8_PORTB_MOSI : 0);
738            m_spi_prescale_count -= m_spi_prescale;
739         }
676740      }
677   }
678741
679   if (m_timer1_prescale != 0)
680   {
681      m_timer1_prescale_count += cycles;
682      while(m_timer1_prescale_count >= m_timer1_prescale)
742      if (m_timer0_prescale != 0)
683743      {
684         timer1_tick();
685         m_timer1_prescale_count -= m_timer1_prescale;
744         m_timer0_prescale_count++;
745         if (m_timer0_prescale_count >= m_timer0_prescale)
746         {
747            timer0_tick();
748            m_timer0_prescale_count -= m_timer0_prescale;
749         }
686750      }
687   }
688751
689   if (m_timer2_prescale != 0)
690   {
691      m_timer2_prescale_count += cycles;
692      while(m_timer2_prescale_count >= (m_timer2_prescale))
752      if (m_timer1_prescale != 0)
693753      {
694         timer2_tick();
695         m_timer2_prescale_count -= (m_timer2_prescale);
754         m_timer1_prescale_count++;
755         if (m_timer1_prescale_count >= m_timer1_prescale)
756         {
757            timer1_tick();
758            m_timer1_prescale_count -= m_timer1_prescale;
759         }
696760      }
761
762      if (m_timer2_prescale != 0)
763      {
764         m_timer2_prescale_count++;
765         if (m_timer2_prescale_count == m_timer2_prescale)
766         {
767            timer2_tick();
768            m_timer2_prescale_count -= m_timer2_prescale;
769         }
770      }
697771   }
698772}
699773
700774// Timer 0 Handling
701775void avr8_device::timer0_tick()
702776{
777   /*
778    UINT16 count = m_r[AVR8_REGIDX_TCNT0];
779    INT32 wgm0 = ((m_r[AVR8_REGIDX_TCCR0B] & AVR8_TCCR0B_WGM0_2_MASK) >> 1) |
780                 (m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_WGM0_10_MASK);
781
782    // Cache things in array form to avoid a compare+branch inside a potentially high-frequency timer
783    //UINT8 compare_mode[2] = { (m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_COM0A_MASK) >> AVR8_TCCR0A_COM0A_SHIFT,
784                              //(m_r[AVR8_REGIDX_TCCR0A] & AVR8_TCCR0A_COM0B_MASK) >> AVR8_TCCR0A_COM0B_SHIFT };
785    UINT8 ocr0[2] = { m_r[AVR8_REGIDX_OCR0A], m_r[AVR8_REGIDX_OCR0B] };
786   UINT8 ocf0[2] = { (1 << AVR8_TIFR0_OCF0A_SHIFT), (1 << AVR8_TIFR0_OCF0B_SHIFT) };
787    INT32 increment = m_timer0_increment;
788
789    for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
790    {
791        switch(wgm0)
792        {
793            case WGM02_FAST_PWM:
794                if(count == ocr0[reg])
795                {
796                    if (reg == 0)
797                    {
798                        m_r[AVR8_REGIDX_TIFR0] |= AVR8_TIFR0_TOV0_MASK;
799                        count = 0;
800                        increment = 0;
801                    }
802
803                    m_r[AVR8_REGIDX_TIFR0] |= ocf0[reg];
804                }
805                else if(count == 0)
806                {
807                    if (reg == 0)
808                    {
809                        m_r[AVR8_REGIDX_TIFR0] &= ~AVR8_TIFR0_TOV0_MASK;
810                    }
811                }
812                break;
813
814            case WGM02_FAST_PWM_CMP:
815                if(count == ocr0[reg])
816                {
817                    if (reg == 0)
818                    {
819                        m_r[AVR8_REGIDX_TIFR0] |= AVR8_TIFR0_TOV0_MASK;
820                        count = 0;
821                        increment = 0;
822                    }
823
824                    m_r[AVR8_REGIDX_TIFR0] |= ocf0[reg];
825                }
826                else if(count == 0)
827                {
828                    if (reg == 0)
829                    {
830                        m_r[AVR8_REGIDX_TIFR0] &= ~AVR8_TIFR0_TOV0_MASK;
831                    }
832                }
833                break;
834
835            default:
836                // TODO
837                break;
838        }
839        switch(compare_mode[reg])
840        {
841            case 0:
842                //verboselog(m_pc, 0, "update_timer0_compare_mode: Normal port operation (OC0 disconnected)\n");
843                break;
844
845            case 1:
846            case 2:
847                // TODO
848                break;
849
850            case 3:
851                break;
852        }
853    }
854
855    m_r[AVR8_REGIDX_TCNT0] = count + increment;
856
857   update_interrupt(AVR8_INTIDX_OCF0A);
858   update_interrupt(AVR8_INTIDX_OCF0B);
859   update_interrupt(AVR8_INTIDX_TOV0);
860        */
861}
862
863void avr8_device::update_timer0_waveform_gen_mode()
864{
865    m_timer0_top = 0;
866   switch(AVR8_WGM0)
867   {
868      case WGM02_NORMAL:
869      case WGM02_PWM_PC:
870      case WGM02_FAST_PWM:
871         m_timer0_top = 0x00ff;
872         break;
873
874      case WGM02_CTC_CMP:
875      case WGM02_PWM_PC_CMP:
876      case WGM02_FAST_PWM_CMP:
877         m_timer0_top = AVR8_OCR0A;
878         break;
879
880      default:
881         verboselog(m_pc, 0, "update_timer0_waveform_gen_mode: Unsupported waveform generation type: %d\n", AVR8_WGM0);
882         break;
883   }
884}
885
886void avr8_device::changed_tccr0a(UINT8 data)
887{
888   UINT8 oldtccr = AVR8_TCCR0A;
889   UINT8 newtccr = data;
890   UINT8 changed = newtccr ^ oldtccr;
891
892   AVR8_TCCR0A = data;
893
894   if(changed & AVR8_TCCR0A_WGM0_10_MASK)
895   {
896      // TODO
897      update_timer0_waveform_gen_mode();
898   }
899}
900
901void avr8_device::timer0_force_output_compare(int reg)
902{
703903   // TODO
904   verboselog(m_pc, 0, "timer0_force_output_compare: TODO; should be forcing OC0%c\n", avr8_reg_name[reg]);
704905}
705906
907void avr8_device::changed_tccr0b(UINT8 data)
908{
909   UINT8 oldtccr = AVR8_TCCR0B;
910   UINT8 newtccr = data;
911   UINT8 changed = newtccr ^ oldtccr;
912
913   AVR8_TCCR0B = data;
914
915   if(changed & AVR8_TCCR0B_FOC0A_MASK)
916   {
917      // TODO
918      timer0_force_output_compare(AVR8_REG_A);
919   }
920
921   if(changed & AVR8_TCCR0B_FOC0B_MASK)
922   {
923      // TODO
924      timer0_force_output_compare(AVR8_REG_B);
925   }
926
927   if(changed & AVR8_TCCR0B_WGM0_2_MASK)
928   {
929      // TODO
930      update_timer0_waveform_gen_mode();
931   }
932
933   if(changed & AVR8_TCCR0B_CS_MASK)
934   {
935      update_timer0_clock_source();
936   }
937}
938
939void avr8_device::update_timer0_clock_source()
940{
941   switch(AVR8_TIMER0_CLOCK_SELECT)
942   {
943      case 0: // Counter stopped
944         m_timer0_prescale = 0;
945         break;
946      case 1: // Clk/1; no prescaling
947         m_timer0_prescale = 1;
948         break;
949      case 2: // Clk/8
950         m_timer0_prescale = 8;
951         break;
952      case 3: // Clk/64
953         m_timer0_prescale = 64;
954         break;
955      case 4: // Clk/256
956         m_timer0_prescale = 256;
957         break;
958      case 5: // Clk/1024
959         m_timer0_prescale = 1024;
960         break;
961      case 6: // T0 trigger, falling edge
962      case 7: // T0 trigger, rising edge
963         m_timer0_prescale = 0;
964         verboselog(m_pc, 0, "update_timer0_clock_source: T0 Trigger mode not implemented yet\n");
965         break;
966   }
967
968   if (m_timer0_prescale_count > m_timer0_prescale)
969   {
970      m_timer0_prescale_count = m_timer0_prescale - 1;
971   }
972}
973
974void avr8_device::update_ocr0(UINT8 newval, UINT8 reg)
975{
976    m_r[(reg == AVR8_REG_A) ? AVR8_REGIDX_OCR0A : AVR8_REGIDX_OCR0B] = newval;
977}
978
706979// Timer 1 Handling
707980
708981void avr8_device::timer1_tick()
r18880r18881
726999    {
7271000        switch(wgm1)
7281001        {
1002         case WGM1_CTC_OCR:
1003            if (count == 0xffff)
1004            {
1005               m_r[AVR8_REGIDX_TIFR1] |= AVR8_TIFR1_TOV1_MASK;
1006               update_interrupt(AVR8_INTIDX_TOV1);
1007               count = 0;
1008               increment = 0;
1009            }
1010
1011                if (count == ocr1[reg])
1012                {
1013                    m_r[AVR8_REGIDX_TIFR1] |= ocf1[reg];
1014               update_interrupt(int1[reg]);
1015                }
1016                else if (count == 0)
1017                {
1018                    if (reg == 0)
1019                    {
1020                        m_r[AVR8_REGIDX_TIFR1] &= ~AVR8_TIFR1_TOV1_MASK;
1021                  update_interrupt(AVR8_INTIDX_TOV1);
1022                    }
1023
1024                    m_r[AVR8_REGIDX_TIFR1] &= ~ocf1[reg];
1025               update_interrupt(int1[reg]);
1026                }
1027                break;
1028
7291029            case WGM1_FAST_PWM_OCR:
7301030                if(count == ocr1[reg])
7311031                {
r18880r18881
7541054                break;
7551055
7561056            default:
757                // TODO
1057                  verboselog(m_pc, 0, "update_timer1_compare_mode: Unknown waveform generation mode: %02x\n", wgm1);
7581058                break;
7591059        }
7601060        /*
r18880r18881
7801080    m_r[AVR8_REGIDX_TCNT1L] = count & 0xff;
7811081}
7821082
783void avr8_device::change_timsk1(UINT8 data)
784{
785   UINT8 oldtimsk = AVR8_TIMSK1;
786   UINT8 newtimsk = data;
787   UINT8 changed = newtimsk ^ oldtimsk;
788
789    AVR8_TIMSK1 = newtimsk;
790
791   if(changed & AVR8_TIMSK1_ICIE1_MASK)
792   {
793      // Check for Input Capture Interrupt interrupt condition
794      update_interrupt(AVR8_INTIDX_ICF1);
795   }
796
797   if(changed & AVR8_TIMSK1_OCIE1B_MASK)
798   {
799      // Check for Output Compare B Interrupt interrupt condition
800      update_interrupt(AVR8_INTIDX_OCF1B);
801   }
802
803   if(changed & AVR8_TIMSK1_OCIE1A_MASK)
804   {
805      // Check for Output Compare A Interrupt interrupt condition
806      update_interrupt(AVR8_INTIDX_OCF1A);
807   }
808
809   if(changed & AVR8_TIMSK1_TOIE1_MASK)
810   {
811      // Check for Output Compare A Interrupt interrupt condition
812      update_interrupt(AVR8_INTIDX_TOV1);
813   }
814}
815
8161083void avr8_device::update_timer1_waveform_gen_mode()
8171084{
8181085   // TODO
8191086   m_timer1_top = 0;
820   verboselog(m_pc, 0, "update_timer1_waveform_gen_mode: TODO; WGM1 is %d\n", AVR8_WGM1 );
8211087   switch(AVR8_WGM1)
8221088   {
8231089      case WGM1_NORMAL:
r18880r18881
9421208
9431209   if(changed & AVR8_TCCR1B_WGM1_32_MASK)
9441210   {
945      // TODO
9461211      update_timer1_waveform_gen_mode();
9471212   }
9481213
r18880r18881
9811246    {
9821247        switch(wgm2)
9831248        {
984            case WGM2_FAST_PWM_CMP:
1249            case WGM02_FAST_PWM:
9851250                if(count == ocr2[reg])
9861251                {
9871252                    if (reg == 0)
r18880r18881
10021267                }
10031268                break;
10041269
1270            case WGM02_FAST_PWM_CMP:
1271                if(count == ocr2[reg])
1272                {
1273                    if (reg == 0)
1274                    {
1275                        m_r[AVR8_REGIDX_TIFR2] |= AVR8_TIFR2_TOV2_MASK;
1276                        count = 0;
1277                        increment = 0;
1278                    }
1279
1280                    m_r[AVR8_REGIDX_TIFR2] |= ocf2[reg];
1281                }
1282                else if(count == 0)
1283                {
1284                    if (reg == 0)
1285                    {
1286                        m_r[AVR8_REGIDX_TIFR2] &= ~AVR8_TIFR2_TOV2_MASK;
1287                    }
1288                }
1289                break;
1290
10051291            default:
10061292                // TODO
10071293                break;
r18880r18881
10361322    m_timer2_top = 0;
10371323   switch(AVR8_WGM2)
10381324   {
1039      case WGM2_NORMAL:
1040      case WGM2_PWM_PC:
1041      case WGM2_FAST_PWM:
1325      case WGM02_NORMAL:
1326      case WGM02_PWM_PC:
1327      case WGM02_FAST_PWM:
10421328         m_timer2_top = 0x00ff;
10431329         break;
10441330
1045      case WGM2_CTC_CMP:
1046      case WGM2_PWM_PC_CMP:
1047      case WGM2_FAST_PWM_CMP:
1331      case WGM02_CTC_CMP:
1332      case WGM02_PWM_PC_CMP:
1333      case WGM02_FAST_PWM_CMP:
10481334         m_timer2_top = AVR8_OCR2A;
10491335         break;
10501336
r18880r18881
10601346   UINT8 newtccr = data;
10611347   UINT8 changed = newtccr ^ oldtccr;
10621348
1349   AVR8_TCCR2A = data;
1350
10631351   if(changed & AVR8_TCCR2A_WGM2_10_MASK)
10641352   {
10651353      // TODO
r18880r18881
11151403   UINT8 newtccr = data;
11161404   UINT8 changed = newtccr ^ oldtccr;
11171405
1406   AVR8_TCCR2B = data;
1407
11181408   if(changed & AVR8_TCCR2B_FOC2A_MASK)
11191409   {
11201410      // TODO
r18880r18881
11461436    // Nothing needs to be done? All handled in timer callback
11471437}
11481438
1439/****************/
1440/* SPI Handling */
1441/****************/
1442
1443void avr8_device::enable_spi()
1444{
1445   // TODO
1446}
1447
1448void avr8_device::disable_spi()
1449{
1450   // TODO
1451}
1452
1453void avr8_device::spi_update_masterslave_select()
1454{
1455   // TODO
1456}
1457
1458void avr8_device::spi_update_clock_polarity()
1459{
1460   // TODO
1461}
1462
1463void avr8_device::spi_update_clock_phase()
1464{
1465   // TODO
1466}
1467
1468const UINT8 avr8_device::spi_clock_divisor[8] = { 4, 16, 64, 128, 2, 8, 32, 64 };
1469
1470void avr8_device::spi_update_clock_rate()
1471{
1472   m_spi_prescale = spi_clock_divisor[AVR8_SPI_RATE];
1473   m_spi_prescale_count &= m_spi_prescale - 1;
1474}
1475
1476void avr8_device::change_spcr(UINT8 data)
1477{
1478   UINT8 oldspcr = AVR8_SPCR;
1479   UINT8 newspcr = data;
1480   UINT8 changed = newspcr ^ oldspcr;
1481   UINT8 high_to_low = ~newspcr & oldspcr;
1482   UINT8 low_to_high = newspcr & ~oldspcr;
1483
1484   AVR8_SPCR = data;
1485
1486   if(changed & AVR8_SPCR_SPIE_MASK)
1487   {
1488      // Check for SPI interrupt condition
1489      update_interrupt(AVR8_INTIDX_SPI);
1490   }
1491
1492   if(low_to_high & AVR8_SPCR_SPE_MASK)
1493   {
1494      enable_spi();
1495   }
1496   else if(high_to_low & AVR8_SPCR_SPE_MASK)
1497   {
1498      disable_spi();
1499   }
1500
1501   if(changed & AVR8_SPCR_MSTR_MASK)
1502   {
1503      spi_update_masterslave_select();
1504   }
1505
1506   if(changed & AVR8_SPCR_CPOL_MASK)
1507   {
1508      spi_update_clock_polarity();
1509   }
1510
1511   if(changed & AVR8_SPCR_CPHA_MASK)
1512   {
1513      spi_update_clock_phase();
1514   }
1515
1516   if(changed & AVR8_SPCR_SPR_MASK)
1517   {
1518      spi_update_clock_rate();
1519   }
1520}
1521
1522void avr8_device::change_spsr(UINT8 data)
1523{
1524   UINT8 oldspsr = AVR8_SPSR;
1525   UINT8 newspsr = data;
1526   UINT8 changed = newspsr ^ oldspsr;
1527
1528   AVR8_SPSR &= ~1;
1529   AVR8_SPSR |= data & 1;
1530
1531   if(changed & AVR8_SPSR_SPR2X_MASK)
1532   {
1533      spi_update_clock_rate();
1534   }
1535}
1536
11491537/*****************************************************************************/
11501538
1151bool avr8_device::io_reg_write(UINT16 offset, UINT8 data)
1539WRITE8_MEMBER( avr8_device::regs_w )
11521540{
11531541    switch( offset )
11541542    {
1543      case AVR8_REGIDX_TCCR0B:
1544         verboselog(m_pc, 0, "AVR8: TCCR0B = %02x\n", data );
1545         changed_tccr0b(data);
1546         break;
1547
1548      case AVR8_REGIDX_TCCR0A:
1549         verboselog(m_pc, 0, "AVR8: TCCR0A = %02x\n", data );
1550         changed_tccr0a(data);
1551         break;
1552
1553      case AVR8_REGIDX_OCR0A:
1554         verboselog(m_pc, 0, "AVR8: OCR0A = %02x\n", data);
1555         update_ocr0(AVR8_OCR0A, AVR8_REG_A);
1556         break;
1557
1558      case AVR8_REGIDX_OCR0B:
1559         verboselog(m_pc, 0, "AVR8: OCR0B = %02x\n", data );
1560         update_ocr0(AVR8_OCR0B, AVR8_REG_B);
1561         break;
1562
1563      case AVR8_REGIDX_TIMSK0:
1564         verboselog(m_pc, 0, "AVR8: TIMSK0 = %02x\n", data );
1565         m_r[AVR8_REGIDX_TIMSK0] = data;
1566         update_interrupt(AVR8_INTIDX_OCF0A);
1567         update_interrupt(AVR8_INTIDX_OCF0B);
1568         update_interrupt(AVR8_INTIDX_TOV0);
1569         break;
1570
1571      case AVR8_REGIDX_TIFR0:
1572         verboselog(m_pc, 0, "AVR8: TIFR0 = %02x\n", data );
1573         m_r[AVR8_REGIDX_TIFR0] &= ~(data & AVR8_TIFR0_MASK);
1574         update_interrupt(AVR8_INTIDX_OCF0A);
1575         update_interrupt(AVR8_INTIDX_OCF0B);
1576         update_interrupt(AVR8_INTIDX_TOV0);
1577         break;
1578
1579        case AVR8_REGIDX_TCNT0:
1580            AVR8_TCNT0 = data;
1581         break;
1582
1583      case AVR8_REGIDX_TCCR1B:
1584         verboselog(m_pc, 0, "AVR8: TCCR1B = %02x\n", data );
1585         changed_tccr1b(data);
1586         break;
1587
1588      case AVR8_REGIDX_TCCR1A:
1589         verboselog(m_pc, 0, "AVR8: TCCR1A = %02x\n", data );
1590         changed_tccr1a(data);
1591         break;
1592
11551593      case AVR8_REGIDX_OCR1BH:
11561594         verboselog(m_pc, 0, "AVR8: OCR1BH = %02x\n", data );
11571595         update_ocr1((AVR8_OCR1B & 0x00ff) | (data << 8), AVR8_REG_B);
1158         return true;
1596         break;
11591597
11601598      case AVR8_REGIDX_OCR1BL:
11611599         verboselog(m_pc, 0, "AVR8: OCR1BL = %02x\n", data );
11621600         update_ocr1((AVR8_OCR1B & 0xff00) | data, AVR8_REG_B);
1163         return true;
1601         break;
11641602
11651603      case AVR8_REGIDX_OCR1AH:
11661604         verboselog(m_pc, 0, "AVR8: OCR1AH = %02x\n", data );
11671605         update_ocr1((AVR8_OCR1A & 0x00ff) | (data << 8), AVR8_REG_A);
1168         return true;
1606         break;
11691607
11701608      case AVR8_REGIDX_OCR1AL:
11711609         verboselog(m_pc, 0, "AVR8: OCR1AL = %02x\n", data );
11721610         update_ocr1((AVR8_OCR1A & 0xff00) | data, AVR8_REG_A);
1173         return true;
1611         break;
11741612
1175      case AVR8_REGIDX_TCCR1B:
1176         verboselog(m_pc, 0, "AVR8: TCCR1B = %02x\n", data );
1177         changed_tccr1b(data);
1178         return true;
1179
1180      case AVR8_REGIDX_TCCR1A:
1181         verboselog(m_pc, 0, "AVR8: TCCR1A = %02x\n", data );
1182         changed_tccr1a(data);
1183         return true;
1184
11851613      case AVR8_REGIDX_TIMSK1:
11861614         verboselog(m_pc, 0, "AVR8: TIMSK1 = %02x\n", data );
1187         change_timsk1(data);
1188         return true;
1615         m_r[AVR8_REGIDX_TIMSK1] = data;
1616         update_interrupt(AVR8_INTIDX_ICF1);
1617         update_interrupt(AVR8_INTIDX_OCF1A);
1618         update_interrupt(AVR8_INTIDX_OCF1B);
1619         update_interrupt(AVR8_INTIDX_TOV1);
1620         break;
11891621
11901622      case AVR8_REGIDX_TIFR1:
11911623         verboselog(m_pc, 0, "AVR8: TIFR1 = %02x\n", data );
r18880r18881
11941626         update_interrupt(AVR8_INTIDX_OCF1A);
11951627         update_interrupt(AVR8_INTIDX_OCF1B);
11961628         update_interrupt(AVR8_INTIDX_TOV1);
1197         return true;
1629         break;
11981630
1631        case AVR8_REGIDX_TCNT1H:
1632            AVR8_TCNT1H = data;
1633         break;
1634
1635        case AVR8_REGIDX_TCNT1L:
1636            AVR8_TCNT1L = data;
1637         break;
1638
11991639      case AVR8_REGIDX_TCCR2B:
12001640         verboselog(m_pc, 0, "AVR8: TCCR2B = %02x\n", data );
1201         changed_tccr2b(data);
1202         return true;
1641         break;
12031642
12041643      case AVR8_REGIDX_TCCR2A:
12051644         verboselog(m_pc, 0, "AVR8: TCCR2A = %02x\n", data );
12061645         changed_tccr2a(data);
1207         return true;
1646         break;
12081647
12091648      case AVR8_REGIDX_OCR2A:
12101649         update_ocr2(data, AVR8_REG_A);
1211         return true;
1650         break;
12121651
12131652      case AVR8_REGIDX_OCR2B:
12141653         update_ocr2(data, AVR8_REG_B);
1215         return true;
1654         break;
12161655
1656      case AVR8_REGIDX_TIMSK2:
1657         verboselog(m_pc, 0, "AVR8: TIMSK2 = %02x\n", data );
1658         m_r[AVR8_REGIDX_TIMSK2] = data;
1659         update_interrupt(AVR8_INTIDX_OCF2A);
1660         update_interrupt(AVR8_INTIDX_OCF2B);
1661         update_interrupt(AVR8_INTIDX_TOV2);
1662         break;
1663
1664      case AVR8_REGIDX_TIFR2:
1665         verboselog(m_pc, 0, "AVR8: TIFR2 = %02x\n", data );
1666         m_r[AVR8_REGIDX_TIFR2] &= ~(data & AVR8_TIFR2_MASK);
1667         update_interrupt(AVR8_INTIDX_OCF2A);
1668         update_interrupt(AVR8_INTIDX_OCF2B);
1669         update_interrupt(AVR8_INTIDX_TOV2);
1670         break;
1671
12171672        case AVR8_REGIDX_TCNT2:
12181673            AVR8_TCNT2 = data;
1219            return true;
1674         break;
12201675
12211676        case AVR8_REGIDX_GTCCR:
12221677           if (data & AVR8_GTCCR_PSRASY_MASK)
r18880r18881
12241679            data &= ~AVR8_GTCCR_PSRASY_MASK;
12251680            m_timer2_prescale_count = 0;
12261681         }
1227            //verboselog(m_pc, 0, "AVR8: GTCCR = %02x\n", data );
1228            // TODO
1229            return true;
1682         break;
12301683
12311684      case AVR8_REGIDX_SPL:
12321685      case AVR8_REGIDX_SPH:
1686      case AVR8_REGIDX_DDRA:
1687      case AVR8_REGIDX_DDRB:
1688      case AVR8_REGIDX_DDRC:
1689      case AVR8_REGIDX_DDRD:
1690      case AVR8_REGIDX_EEARL:
1691      case AVR8_REGIDX_EEARH:
1692      case AVR8_REGIDX_SREG:
12331693         m_r[offset] = data;
1234         return true;
1694         break;
12351695
1696      case AVR8_REGIDX_EECR:
1697         if (data & AVR8_EECR_EERE)
1698         {
1699            UINT16 addr = (m_r[AVR8_REGIDX_EEARH] & AVR8_EEARH_MASK) << 8;
1700            addr |= m_r[AVR8_REGIDX_EEARL];
1701            m_r[AVR8_REGIDX_EEDR] = m_eeprom[addr];
1702         }
1703         break;
1704
12361705      case AVR8_REGIDX_GPIOR0:
1237         verboselog(m_pc, 0, "AVR8: GPIOR0 Write: %02x\n", data);
1706         verboselog(m_pc, 1, "AVR8: GPIOR0 Write: %02x\n", data);
12381707         m_r[offset] = data;
1239         return true;
1708         break;
12401709
1241      case AVR8_REGIDX_SREG:
1242         m_status = data;
1243         return true;
1710      case AVR8_REGIDX_PORTA:
1711         m_io->write_byte(0x00, data);
1712         m_r[AVR8_REGIDX_PORTA] = data;
1713         break;
12441714
12451715      case AVR8_REGIDX_PORTB:
1246         if (m_portb_changed)
1247         {
1248            UINT8 changed = m_r[AVR8_REGIDX_PORTB] ^ data;
1249            (*m_portb_changed)(*this, data, changed);
1250            m_r[AVR8_REGIDX_PORTB] = data;
1251         }
1716         m_io->write_byte(0x01, data);
1717         m_r[AVR8_REGIDX_PORTB] = data;
12521718         break;
12531719
12541720      case AVR8_REGIDX_PORTC:
1255         if (m_portc_changed)
1256         {
1257            UINT8 changed = m_r[AVR8_REGIDX_PORTC] ^ data;
1258            (*m_portc_changed)(*this, data, changed);
1259            m_r[AVR8_REGIDX_PORTC] = data;
1260         }
1721         m_io->write_byte(0x02, data);
1722         m_r[AVR8_REGIDX_PORTC] = data;
12611723         break;
12621724
12631725        case AVR8_REGIDX_PORTD:
1264         if (m_portd_changed)
1265         {
1266            UINT8 changed = m_r[AVR8_REGIDX_PORTD] ^ data;
1267            (*m_portd_changed)(*this, data, changed);
1268            m_r[AVR8_REGIDX_PORTD] = data;
1269         }
1270            break;
1726         m_io->write_byte(0x03, data);
1727         m_r[AVR8_REGIDX_PORTD] = data;
1728         break;
12711729
1730      case AVR8_REGIDX_SPSR:
1731         change_spsr(data);
1732         break;
1733
1734      case AVR8_REGIDX_SPCR:
1735         change_spcr(data);
1736         break;
1737
1738      case AVR8_REGIDX_SPDR:
1739      {
1740         m_r[AVR8_REGIDX_SPDR] = data;
1741         m_spi_active = true;
1742         m_spi_prescale_countdown = 7;
1743         m_spi_prescale_count = 0;
1744         break;
1745      }
1746
12721747        default:
1273            return false;
1748         verboselog(m_pc, 0, "AVR8: Unknown Register Write: %02x = %02x\n", (UINT8)offset, data);
1749         break;
12741750    }
1275    return false;
12761751}
12771752
1278bool avr8_device::io_reg_read(UINT16 offset, UINT8 *data)
1753READ8_MEMBER( avr8_device::regs_r )
12791754{
1755   //printf("offset %04x\n", offset);
12801756    switch( offset )
12811757    {
12821758      case AVR8_REGIDX_SPL:
r18880r18881
12841760      case AVR8_REGIDX_TCNT1L:
12851761      case AVR8_REGIDX_TCNT1H:
12861762      case AVR8_REGIDX_TCNT2:
1763      case AVR8_REGIDX_PORTA:
12871764      case AVR8_REGIDX_PORTB:
12881765      case AVR8_REGIDX_PORTC:
12891766      case AVR8_REGIDX_PORTD:
1290         *data = m_r[offset];
1291         return true;
1292
1767      case AVR8_REGIDX_DDRA:
1768      case AVR8_REGIDX_DDRB:
1769      case AVR8_REGIDX_DDRC:
1770      case AVR8_REGIDX_DDRD:
12931771      case AVR8_REGIDX_GPIOR0:
1294         *data = m_r[offset];
1295         verboselog(m_pc, 0, "AVR8: GPIOR0 Read: %02x\n", *data);
1296         return true;
1297
1772      case AVR8_REGIDX_EEDR:
12981773      case AVR8_REGIDX_SREG:
1299         *data = m_status;
1300         return true;
1774         return m_r[offset];
13011775
13021776        default:
1303            return false;
1777         verboselog(m_pc, 0, "AVR8: Unknown Register Read: %02x\n", (UINT8)offset);
1778            return 0;
13041779    }
1305
1306    return false;
13071780}
13081781
13091782
r18880r18881
13701843      opcycles = 1;
13711844
13721845        m_pc &= m_addr_mask;
1846        m_shifted_pc &= (m_addr_mask << 1) | 1;
13731847
1374        debugger_instruction_hook(this, m_debugger_pc);
1848        debugger_instruction_hook(this, m_shifted_pc);
13751849
1376        op = (UINT32)program_read16(m_pc);
1850        op = (UINT32)m_program->read_word(m_shifted_pc);
13771851
13781852        switch(op & 0xf000)
13791853        {
r18880r18881
16222096                switch(op & 0x0208)
16232097                {
16242098                    case 0x0000:    // LDD Rd,Z+q
1625                        m_r[RD5(op)] = io_read8(ZREG + QCONST6(op));
2099                        m_r[RD5(op)] = m_data->read_byte(ZREG + QCONST6(op));
16262100                        opcycles = 2;
16272101                        break;
16282102                    case 0x0008:    // LDD Rd,Y+q
1629                        m_r[RD5(op)] = io_read8(YREG + QCONST6(op));
2103                        m_r[RD5(op)] = m_data->read_byte(YREG + QCONST6(op));
16302104                        opcycles = 2;
16312105                        break;
16322106                    case 0x0200:    // STD Z+q,Rr
1633                        io_write8(ZREG + QCONST6(op), m_r[RD5(op)]);
2107                        m_data->write_byte(ZREG + QCONST6(op), m_r[RD5(op)]);
16342108                        opcycles = 2;
16352109                        break;
16362110                    case 0x0208:    // STD Y+q,Rr
1637                        io_write8(YREG + QCONST6(op), m_r[RD5(op)]);
2111                        m_data->write_byte(YREG + QCONST6(op), m_r[RD5(op)]);
16382112                        opcycles = 2;
16392113                        break;
16402114                }
r18880r18881
16492123                            case 0x0000:    // LDS Rd,k
16502124                                op <<= 16;
16512125                                m_pc++;
1652                                op |= program_read16(m_pc);
1653                                m_r[RD5(op >> 16)] = io_read8(op & 0x0000ffff);
2126                                m_shifted_pc += 2;
2127                                op |= m_program->read_word(m_shifted_pc);
2128                                m_r[RD5(op >> 16)] = m_data->read_byte(op & 0x0000ffff);
16542129                                opcycles = 2;
16552130                                break;
16562131                            case 0x0001:    // LD Rd,Z+
r18880r18881
16592134                            case 0x0002:    // LD Rd,-Z
16602135                                pd = ZREG;
16612136                                pd--;
1662                                m_r[RD5(op)] = io_read8(pd);
2137                                m_r[RD5(op)] = m_data->read_byte(pd);
16632138                                m_r[31] = (pd >> 8) & 0x00ff;
16642139                                m_r[30] = pd & 0x00ff;
16652140                                opcycles = 2;
16662141                                break;
16672142                            case 0x0004:    // LPM Rd,Z
1668                                m_r[RD5(op)] = program_read8(ZREG);
2143                                m_r[RD5(op)] = m_program->read_byte(ZREG);
16692144                                opcycles = 3;
16702145                                break;
16712146                            case 0x0005:    // LPM Rd,Z+
16722147                                pd = ZREG;
1673                                m_r[RD5(op)] = program_read8(pd);
2148                                m_r[RD5(op)] = m_program->read_byte(pd);
16742149                                pd++;
16752150                                m_r[31] = (pd >> 8) & 0x00ff;
16762151                                m_r[30] = pd & 0x00ff;
r18880r18881
16862161                                break;
16872162                            case 0x0009:    // LD Rd,Y+
16882163                                pd = YREG;
1689                                m_r[RD5(op)] = io_read8(pd);
2164                                m_r[RD5(op)] = m_data->read_byte(pd);
16902165                                pd++;
16912166                                m_r[29] = (pd >> 8) & 0x00ff;
16922167                                m_r[28] = pd & 0x00ff;
r18880r18881
16952170                            case 0x000a:    // LD Rd,-Y
16962171                                pd = YREG;
16972172                                pd--;
1698                                m_r[RD5(op)] = io_read8(pd);
2173                                m_r[RD5(op)] = m_data->read_byte(pd);
16992174                                m_r[29] = (pd >> 8) & 0x00ff;
17002175                                m_r[28] = pd & 0x00ff;
17012176                                opcycles = 2;
17022177                                break;
17032178                            case 0x000c:    // LD Rd,X
1704                               m_r[RD5(op)] = io_read8(XREG);
2179                               m_r[RD5(op)] = m_data->read_byte(XREG);
17052180                               opcycles = 2;
17062181                                break;
17072182                            case 0x000d:    // LD Rd,X+
17082183                                pd = XREG;
1709                                m_r[RD5(op)] = io_read8(pd);
2184                                m_r[RD5(op)] = m_data->read_byte(pd);
17102185                                pd++;
17112186                                m_r[27] = (pd >> 8) & 0x00ff;
17122187                                m_r[26] = pd & 0x00ff;
r18880r18881
17152190                            case 0x000e:    // LD Rd,-X
17162191                                pd = XREG;
17172192                                pd--;
1718                                m_r[RD5(op)] = io_read8(pd);
2193                                m_r[RD5(op)] = m_data->read_byte(pd);
17192194                                m_r[27] = (pd >> 8) & 0x00ff;
17202195                                m_r[26] = pd & 0x00ff;
17212196                                opcycles = 2;
r18880r18881
17372212                            case 0x0000:    // STS k,Rr
17382213                                op <<= 16;
17392214                                m_pc++;
1740                                op |= program_read16(m_pc);
1741                                io_write8(op & 0x0000ffff, m_r[RD5(op >> 16)]);
2215                                m_shifted_pc += 2;
2216                                op |= m_program->read_word(m_shifted_pc);
2217                                m_data->write_byte(op & 0x0000ffff, m_r[RD5(op >> 16)]);
17422218                                opcycles = 2;
17432219                                break;
17442220                            case 0x0001:    // ST Z+,Rd
1745                                //output += sprintf( output, "ST       Z+, R%d", RD5(op) );
1746                                unimplemented_opcode(op);
2221                                pd = ZREG;
2222                                m_data->write_byte(pd, m_r[RD5(op)]);
2223                                pd++;
2224                                m_r[31] = (pd >> 8) & 0x00ff;
2225                                m_r[30] = pd & 0x00ff;
2226                                opcycles = 2;
17472227                                break;
17482228                            case 0x0002:    // ST -Z,Rd
17492229                                //output += sprintf( output, "ST      -Z , R%d", RD5(op) );
r18880r18881
17512231                                break;
17522232                            case 0x0009:    // ST Y+,Rd
17532233                                pd = YREG;
1754                                io_write8(pd, m_r[RD5(op)]);
2234                                m_data->write_byte(pd, m_r[RD5(op)]);
17552235                                pd++;
17562236                                m_r[29] = (pd >> 8) & 0x00ff;
17572237                                m_r[28] = pd & 0x00ff;
r18880r18881
17622242                                unimplemented_opcode(op);
17632243                                break;
17642244                            case 0x000c:    // ST X,Rd
1765                                io_write8(XREG, m_r[RD5(op)]);
2245                                m_data->write_byte(XREG, m_r[RD5(op)]);
17662246                                break;
17672247                            case 0x000d:    // ST X+,Rd
17682248                                pd = XREG;
1769                                io_write8(pd, m_r[RD5(op)]);
2249                                m_data->write_byte(pd, m_r[RD5(op)]);
17702250                                pd++;
17712251                                m_r[27] = (pd >> 8) & 0x00ff;
17722252                                m_r[26] = pd & 0x00ff;
r18880r18881
19092389                            case 0x000d:    // JMP k
19102390                        offs = KCONST22(op) << 16;
19112391                                m_pc++;
1912                                offs |= program_read16(m_pc);
2392                                m_shifted_pc += 2;
2393                                offs |= m_program->read_word(m_shifted_pc);
19132394                                m_pc = offs;
19142395                        m_pc--;
19152396                        opcycles = 3;
r18880r18881
19202401                        push((m_pc + 1) & 0x00ff);
19212402                        offs = KCONST22(op) << 16;
19222403                                m_pc++;
1923                                offs |= program_read16(m_pc);
2404                                m_shifted_pc += 2;
2405                                offs |= m_program->read_word(m_shifted_pc);
19242406                                m_pc = offs;
19252407                        m_pc--;
19262408                        opcycles = 4;
r18880r18881
20282510                                        unimplemented_opcode(op);
20292511                                        break;
20302512                                    case 0x00c0:    // LPM
2031                                        m_r[0] = program_read8(ZREG);
2513                                        m_r[0] = m_program->read_byte(ZREG);
20322514                                        opcycles = 3;
20332515                                        break;
20342516                                    case 0x00d0:    // ELPM
r18880r18881
21112593                        opcycles = 2;
21122594                        break;
21132595                    case 0x0700:    // SBIW Rd+1:Rd,K
2114                        //output += sprintf( output, "SBIW    R%d:R%d, 0x%02x", 24+(RD2(op) << 1)+1, 24+(RD2(op) << 1), KCONST6(op) );
2115                        unimplemented_opcode(op);
2596                        rd = m_r[24 + (DCONST(op) << 1)];
2597                        rr = m_r[25 + (DCONST(op) << 1)];
2598                        pd = rd;
2599                        pd |= rr << 8;
2600                        pd -= KCONST6(op);
2601                        SREG_W(AVR8_SREG_V, BIT(pd,15) & NOT(BIT(rr,7)));
2602                        SREG_W(AVR8_SREG_N, BIT(pd,15));
2603                        SREG_W(AVR8_SREG_S, SREG_R(AVR8_SREG_N) ^ SREG_R(AVR8_SREG_V));
2604                        SREG_W(AVR8_SREG_Z, (pd == 0) ? 1 : 0);
2605                        SREG_W(AVR8_SREG_C, NOT(BIT(pd,15)) & BIT(rr,7));
2606                        m_r[24 + (DCONST(op) << 1)] = pd & 0x00ff;
2607                        m_r[25 + (DCONST(op) << 1)] = (pd >> 8) & 0x00ff;
2608                        opcycles = 2;
21162609                        break;
21172610                    case 0x0800:    // CBI A,b
21182611                        //output += sprintf( output, "CBI     0x%02x, %d", ACONST5(op), RR3(op) );
2119                        io_write8(32 + ACONST5(op), io_read8(32 + ACONST5(op)) &~ (1 << RR3(op)));
2612                        m_data->write_byte(32 + ACONST5(op), m_data->read_byte(32 + ACONST5(op)) &~ (1 << RR3(op)));
21202613                        opcycles = 2;
21212614                        break;
21222615                    case 0x0900:    // SBIC A,b
2123                      if(NOT(BIT(io_read8(32 + ACONST5(op)), RR3(op))))
2616                      if(NOT(BIT(m_data->read_byte(32 + ACONST5(op)), RR3(op))))
21242617                      {
2125                            op = (UINT32)program_read16(m_pc + 1);
2618                            op = (UINT32)m_program->read_word(m_shifted_pc + 2);
21262619                     opcycles = is_long_opcode(op) ? 3 : 2;
21272620                            m_pc += is_long_opcode(op) ? 2 : 1;
21282621                  }
21292622                        break;
21302623                    case 0x0a00:    // SBI A,b
2131                        io_write8(32 + ACONST5(op), io_read8(32 + ACONST5(op)) | (1 << RR3(op)));
2624                        m_data->write_byte(32 + ACONST5(op), m_data->read_byte(32 + ACONST5(op)) | (1 << RR3(op)));
21322625                        opcycles = 2;
21332626                        break;
21342627                    case 0x0b00:    // SBIS A,b
2135                      if(BIT(io_read8(32 + ACONST5(op)), RR3(op)))
2628                      if(BIT(m_data->read_byte(32 + ACONST5(op)), RR3(op)))
21362629                      {
2137                            op = (UINT32)program_read16(m_pc + 1);
2630                            op = (UINT32)m_program->read_word(m_shifted_pc + 2);
21382631                     opcycles = is_long_opcode(op) ? 3 : 2;
21392632                            m_pc += is_long_opcode(op) ? 2 : 1;
21402633                  }
r18880r18881
21552648            case 0xb000:
21562649                if(op & 0x0800) // OUT A,Rr
21572650                {
2158                    io_write8(32 + ACONST6(op), m_r[RD5(op)]);
2651                    m_data->write_byte(32 + ACONST6(op), m_r[RD5(op)]);
21592652                }
21602653                else            // IN Rd,A
21612654                {
2162                    m_r[RD5(op)] = io_read8(0x20 + ACONST6(op));
2655                    m_r[RD5(op)] = m_data->read_byte(0x20 + ACONST6(op));
21632656                }
21642657                break;
21652658            case 0xc000:    // RJMP k
r18880r18881
22262719                        {
22272720                            if(BIT(m_r[RD5(op)], RR3(op)))
22282721                            {
2229                                op = (UINT32)program_read16(m_pc++);
2230                                m_pc += is_long_opcode(op) ? 1 : 0;
2722                                op = (UINT32)m_program->read_word(m_shifted_pc + 2);
2723                                m_pc += is_long_opcode(op) ? 2 : 1;
22312724                                opcycles = is_long_opcode(op) ? 3 : 2;
22322725                            }
22332726                        }
r18880r18881
22352728                        {
22362729                            if(NOT(BIT(m_r[RD5(op)], RR3(op))))
22372730                            {
2238                                op = (UINT32)program_read16(m_pc++);
2239                                m_pc += is_long_opcode(op) ? 1 : 0;
2731                                op = (UINT32)m_program->read_word(m_shifted_pc + 2);
2732                                m_pc += is_long_opcode(op) ? 2 : 1;
22402733                                opcycles = is_long_opcode(op) ? 3 : 2;
22412734                            }
22422735                        }
r18880r18881
22472740
22482741        m_pc++;
22492742
2250        m_debugger_pc = m_pc << 1;
2743        m_shifted_pc = m_pc << 1;
22512744
22522745        m_icount -= opcycles;
22532746
2254      m_elapsed_cycles += opcycles;
2255
22562747      timer_tick(opcycles);
22572748    }
22582749}
trunk/src/emu/cpu/avr8/avr8.h
r18880r18881
5353
5454struct avr8_config
5555{
56   void (*m_portb_changed)(avr8_device &device, UINT8 pins, UINT8 changed);
57   void (*m_portc_changed)(avr8_device &device, UINT8 pins, UINT8 changed);
58   void (*m_portd_changed)(avr8_device &device, UINT8 pins, UINT8 changed);
56   const char *eeprom_region;
5957};
6058
6159
r18880r18881
7977      return m_elapsed_cycles;
8078   }
8179
80   // register handling
81   DECLARE_WRITE8_MEMBER( regs_w );
82   DECLARE_READ8_MEMBER( regs_r );
83
8284protected:
85   avr8_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock, const device_type type, UINT32 address_mask, address_map_constructor internal_map);
86
8387   // device-level overrides
8488   virtual void device_start();
8589   virtual void device_reset();
r18880r18881
104108
105109   // address spaces
106110   const address_space_config m_program_config;
111   const address_space_config m_data_config;
107112   const address_space_config m_io_config;
113    UINT8 *m_eeprom;
108114
109115   // CPU registers
110116    UINT32 m_pc;
111    UINT32 m_debugger_pc;
112   UINT8 m_status;
117    UINT32 m_shifted_pc;
113118   UINT8 m_r[256];
114119
115   // On-chip Device Registers
120   // internal timers
116121    UINT8 m_timer0_top;
117122   INT32 m_timer0_increment;
118123   UINT16 m_timer0_prescale;
r18880r18881
128133   UINT16 m_timer2_prescale;
129134   UINT16 m_timer2_prescale_count;
130135
131    // internal stuff
136   // SPI
137   bool m_spi_active;
138   UINT8 m_spi_prescale;
139   UINT8 m_spi_prescale_count;
140   INT8 m_spi_prescale_countdown;
141    static const UINT8 spi_clock_divisor[8];
142   void enable_spi();
143   void disable_spi();
144   void spi_update_masterslave_select();
145   void spi_update_clock_polarity();
146   void spi_update_clock_phase();
147   void spi_update_clock_rate();
148   void change_spcr(UINT8 data);
149   void change_spsr(UINT8 data);
150
151    // internal CPU state
132152   UINT32 m_addr_mask;
133153   bool m_interrupt_pending;
134154
r18880r18881
160180
161181   // timer 0
162182   void timer0_tick();
183   void changed_tccr0a(UINT8 data);
184   void changed_tccr0b(UINT8 data);
185   void update_timer0_waveform_gen_mode();
186   void update_timer0_clock_source();
187   void update_ocr0(UINT8 newval, UINT8 reg);
188   void timer0_force_output_compare(int reg);
163189
164190   // timer 1
165191   void timer1_tick();
166   void change_timsk1(UINT8 data);
192   void changed_tccr1a(UINT8 data);
193   void changed_tccr1b(UINT8 data);
167194   void update_timer1_waveform_gen_mode();
168   void changed_tccr1a(UINT8 data);
195   void update_timer1_clock_source();
169196   void update_timer1_input_noise_canceler();
170197   void update_timer1_input_edge_select();
171   void update_timer1_clock_source();
172   void changed_tccr1b(UINT8 data);
173198   void update_ocr1(UINT16 newval, UINT8 reg);
174199
175200   // timer 2
176201   void timer2_tick();
202   void changed_tccr2a(UINT8 data);
203   void changed_tccr2b(UINT8 data);
177204   void update_timer2_waveform_gen_mode();
178   void changed_tccr2a(UINT8 data);
179205   void update_timer2_clock_source();
206   void update_ocr2(UINT8 newval, UINT8 reg);
180207   void timer2_force_output_compare(int reg);
181   void changed_tccr2b(UINT8 data);
182   void update_ocr2(UINT8 newval, UINT8 reg);
183208
184   // register Handling
185   bool io_reg_write(UINT16 offset, UINT8 data);
186   bool io_reg_read(UINT16 offset, UINT8 *data);
187
188209   // address spaces
189210    address_space *m_program;
211    address_space *m_data;
190212    address_space *m_io;
191213};
192214
r18880r18881
200222{
201223public:
202224   // construction/destruction
203   atmega88_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
204    : avr8_device(mconfig, tag, owner, clock, ATMEGA88, 0x0fff) { }
225   atmega88_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
205226};
206227
207228// ======================> atmega644_device
r18880r18881
210231{
211232public:
212233   // construction/destruction
213   atmega644_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
214    : avr8_device(mconfig, tag, owner, clock, ATMEGA644, 0xffff) { }
234   atmega644_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
215235};
216236
217237/***************************************************************************
r18880r18881
326346   AVR8_REGIDX_R30,
327347   AVR8_REGIDX_R31,
328348
329   AVR8_REGIDX_PINB = 0x23,
349   AVR8_REGIDX_PINA = 0x20,
350   AVR8_REGIDX_DDRA,
351   AVR8_REGIDX_PORTA,
352   AVR8_REGIDX_PINB,
330353   AVR8_REGIDX_DDRB,
331354   AVR8_REGIDX_PORTB,
332355   AVR8_REGIDX_PINC,
r18880r18881
445468enum
446469{
447470   AVR8_INTIDX_SPI,
471   AVR8_INTIDX_OCF0B,
472   AVR8_INTIDX_OCF0A,
473   AVR8_INTIDX_TOV0,
448474   AVR8_INTIDX_ICF1,
449475   AVR8_INTIDX_OCF1B,
450476   AVR8_INTIDX_OCF1A,
r18880r18881
457483};
458484
459485#define AVR8_EECR_EERE         0x01
486
460487#define AVR8_EEARH_MASK         0x01
461488
462489#define AVR8_SPSR_SPIF_MASK      0x80
trunk/src/mess/drivers/uzebox.c
r18880r18881
66
77// overclocked to 8 * NTSC burst frequency
88
9#define VERBOSE_LEVEL   (0)
10
11#define ENABLE_VERBOSE_LOG (0)
12
13#if ENABLE_VERBOSE_LOG
14INLINE void verboselog(running_machine &machine, int n_level, const char *s_fmt, ...)
15{
16   if( VERBOSE_LEVEL >= n_level )
17   {
18      va_list v;
19      char buf[ 32768 ];
20      va_start( v, s_fmt );
21      vsprintf( buf, s_fmt, v );
22      va_end( v );
23      logerror( "%08x: %s", machine.device("maincpu")->safe_pc(), buf );
24   }
25}
26#else
27#define verboselog(x,y,z,...)
28#endif
29
930#define MASTER_CLOCK 28618180
1031
1132class uzebox_state : public driver_device
1233{
1334public:
1435   uzebox_state(const machine_config &mconfig, device_type type, const char *tag)
15      : driver_device(mconfig, type, tag)
36      : driver_device(mconfig, type, tag),
37        m_maincpu(*this, "maincpu")
1638   {
1739   }
40
41   virtual void machine_start();
42
43    required_device<avr8_device> m_maincpu;
44
45   DECLARE_READ8_MEMBER(port_r);
46   DECLARE_WRITE8_MEMBER(port_w);
1847   DECLARE_DRIVER_INIT(uzebox);
1948   virtual void machine_reset();
2049   UINT32 screen_update_uzebox(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
2150};
51
52void uzebox_state::machine_start()
53{
54}
55
56READ8_MEMBER(uzebox_state::port_r)
57{
58    return 0;
59}
60
61WRITE8_MEMBER(uzebox_state::port_w)
62{
63}
64
2265/****************************************************\
2366* Address maps                                       *
2467\****************************************************/
r18880r18881
2770   AM_RANGE(0x0000, 0xffff) AM_ROM // 64 KB internal eprom  ATmega644
2871ADDRESS_MAP_END
2972
73static ADDRESS_MAP_START( uzebox_data_map, AS_DATA, 8, uzebox_state )
74   AM_RANGE(0x0100, 0x10ff) AM_RAM //  4KB RAM
75ADDRESS_MAP_END
76
3077static ADDRESS_MAP_START( uzebox_io_map, AS_IO, 8, uzebox_state )
31   AM_RANGE(0x0000, 0x00ff) AM_RAM
32   AM_RANGE(0x0100, 0x0fff) AM_RAM //  4KB RAM
78   AM_RANGE(0x00, 0x03) AM_READWRITE( port_r, port_w )
3379ADDRESS_MAP_END
3480
3581/****************************************************\
r18880r18881
62108
63109const avr8_config atmega644_config =
64110{
65   NULL,
66   NULL,
67   NULL
111   "eeprom"
68112};
69113
70114static MACHINE_CONFIG_START( uzebox, uzebox_state )
r18880r18881
73117   MCFG_CPU_ADD("maincpu", ATMEGA644, MASTER_CLOCK)
74118    MCFG_CPU_AVR8_CONFIG(atmega644_config)
75119   MCFG_CPU_PROGRAM_MAP(uzebox_prg_map)
120   MCFG_CPU_DATA_MAP(uzebox_data_map)
76121   MCFG_CPU_IO_MAP(uzebox_io_map)
77122
78123   /* video hardware */
r18880r18881
99144ROM_START( uzebox )
100145   ROM_REGION( 0x10000, "maincpu", 0 )  /* Main program store */
101146   ROM_CART_LOAD("cart1", 0x0000, 0x10000, ROM_OPTIONAL)
147
148   ROM_REGION( 0x200, "eeprom", 0 )  /* on-die eeprom */
102149ROM_END
103150
104151/*   YEAR  NAME      PARENT    COMPAT    MACHINE   INPUT     INIT      COMPANY   FULLNAME */
trunk/src/mess/drivers/craft.c
r18880r18881
4141#define PIXELS_PER_FRAME   (CYCLES_PER_FRAME)
4242
4343/****************************************************\
44* I/O defines                                        *
45\****************************************************/
46
47#define AVR8_PORTD            (state->m_regs[AVR8_REGIDX_PORTD])
48#define AVR8_DDRD            (state->m_regs[AVR8_REGIDX_DDRD])
49#define AVR8_PORTC            (state->m_regs[AVR8_REGIDX_PORTC])
50#define AVR8_DDRC            (state->m_regs[AVR8_REGIDX_DDRC])
51#define AVR8_PORTB            (state->m_regs[AVR8_REGIDX_PORTB])
52#define AVR8_DDRB            (state->m_regs[AVR8_REGIDX_DDRB])
53
54#define AVR8_SPSR            (state->m_regs[AVR8_REGIDX_SPSR])
55#define AVR8_SPSR_SPR2X         (AVR8_SPSR & AVR8_SPSR_SPR2X_MASK)
56
57#define AVR8_SPCR            (state->m_regs[AVR8_REGIDX_SPCR])
58#define AVR8_SPCR_SPIE         ((AVR8_SPCR & AVR8_SPCR_SPIE_MASK) >> 7)
59#define AVR8_SPCR_SPE         ((AVR8_SPCR & AVR8_SPCR_SPE_MASK) >> 6)
60#define AVR8_SPCR_DORD         ((AVR8_SPCR & AVR8_SPCR_DORD_MASK) >> 5)
61#define AVR8_SPCR_MSTR         ((AVR8_SPCR & AVR8_SPCR_MSTR_MASK) >> 4)
62#define AVR8_SPCR_CPOL         ((AVR8_SPCR & AVR8_SPCR_CPOL_MASK) >> 3)
63#define AVR8_SPCR_CPHA         ((AVR8_SPCR & AVR8_SPCR_CPHA_MASK) >> 2)
64#define AVR8_SPCR_SPR         (AVR8_SPCR & AVR8_SPCR_SPR_MASK)
65
66
67/****************************************************\
6844* I/O devices                                        *
6945\****************************************************/
7046
r18880r18881
7753   {
7854   }
7955
56   void video_update();
57
8058   virtual void machine_start();
8159
82    dac_device* dac;
60    dac_device* m_dac;
8361
84   UINT8 m_regs[0x100];
85    UINT8* m_eeprom;
8662    UINT32 m_last_cycles;
87
88    bool m_spi_pending;
89    UINT64 m_spi_start_cycle;
90
9163    UINT64 m_frame_start_cycle;
9264
65   UINT8 m_port_b;
66   UINT8 m_port_c;
67   UINT8 m_port_d;
68
69   UINT8 m_latched_color;
9370    UINT8 m_pixels[PIXELS_PER_FRAME];
9471
9572    required_device<avr8_device> m_maincpu;
9673
97   DECLARE_READ8_MEMBER(avr8_read);
98   DECLARE_WRITE8_MEMBER(avr8_write);
74   DECLARE_READ8_MEMBER(port_r);
75   DECLARE_WRITE8_MEMBER(port_w);
9976   DECLARE_DRIVER_INIT(craft);
10077   virtual void machine_reset();
10178   UINT32 screen_update_craft(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
102   TIMER_CALLBACK_MEMBER(avr8_timer0_tick);
103   TIMER_CALLBACK_MEMBER(avr8_timer1_tick);
104   TIMER_CALLBACK_MEMBER(avr8_timer2_tick);
10579};
10680
10781void craft_state::machine_start()
10882{
10983}
11084
111READ8_MEMBER(craft_state::avr8_read)
85READ8_MEMBER(craft_state::port_r)
11286{
11387    switch( offset )
11488    {
115      case AVR8_REGIDX_EEDR:
116         return m_regs[offset];
117
118        default:
119            verboselog(machine(), 0, "AVR8: Unrecognized register read: %02x\n", offset );
89      case 0x00: // Port A
90      case 0x01: // Port B
91      case 0x02: // Port C
92      case 0x03: // Port D
93         // Unhandled
94         return 0x00;
12095    }
12196
12297    return 0;
12398}
12499
125static UINT8 avr8_get_ddr(running_machine &machine, int reg)
100WRITE8_MEMBER(craft_state::port_w)
126101{
127    craft_state *state = machine.driver_data<craft_state>();
128
129   switch(reg)
130   {
131      case AVR8_REG_B:
132         return AVR8_DDRB;
133
134      case AVR8_REG_C:
135         return AVR8_DDRC;
136
137      case AVR8_REG_D:
138         return AVR8_DDRD;
139
140      default:
141         verboselog(machine, 0, "avr8_get_ddr: Unsupported register retrieval: %c\n", avr8_reg_name[reg]);
102    switch( offset )
103    {
104      case 0x00: // Port A
105         // Unhandled
142106         break;
143   }
144107
145   return 0;
146}
147
148static void avr8_change_ddr(running_machine &machine, int reg, UINT8 data)
149{
150    //craft_state *state = machine.driver_data<craft_state>();
151
152   UINT8 oldddr = avr8_get_ddr(machine, reg);
153   UINT8 newddr = data;
154   UINT8 changed = newddr ^ oldddr;
155   // TODO: When AVR8 is converted to emu/machine, this should be factored out to 8 single-bit callbacks per port
156   if(changed)
157   {
158      // TODO
159      verboselog(machine, 0, "avr8_change_ddr: DDR%c lines %02x changed\n", avr8_reg_name[reg], changed);
160   }
161}
162
163static void avr8_video_update(running_machine &machine)
164{
165    craft_state *state = machine.driver_data<craft_state>();
166
167   UINT64 cycles = state->m_maincpu->get_elapsed_cycles();
168   UINT32 frame_cycles = (UINT32)(cycles - state->m_frame_start_cycle);
169
170   if (state->m_last_cycles < frame_cycles)
171   {
172      for (UINT32 pixidx = state->m_last_cycles; pixidx < frame_cycles; pixidx++)
108      case 0x01: // Port B
173109      {
174         UINT8 value = AVR8_PORTC & 0x3f;
175         if (state->m_spi_pending)
110         UINT8 old_port_b = m_port_b;
111         UINT8 pins = data;
112         UINT8 changed = pins ^ old_port_b;
113         if(pins & changed & 0x02)
176114         {
177            if (pixidx >= state->m_spi_start_cycle && pixidx < (state->m_spi_start_cycle + 16))
178            {
179               UINT8 bitidx = 7 - ((pixidx - state->m_spi_start_cycle) >> 1);
180               value = ((state->m_regs[AVR8_REGIDX_SPDR] & (1 << bitidx)) ? value : 0x3f);
181               if (pixidx == (state->m_spi_start_cycle + 15))
182               {
183                  state->m_spi_pending = false;
184                  state->m_regs[AVR8_REGIDX_SPDR] = 0;
185               }
186            }
115            m_frame_start_cycle = m_maincpu->get_elapsed_cycles();
116            video_update();
187117         }
188         state->m_pixels[pixidx] = value;
118         if(changed & 0x08)
119         {
120            video_update();
121            m_latched_color = (pins & 0x08) ? (m_port_c & 0x3f) : 0x3f;
122         }
123         m_port_b = data;
124         break;
189125      }
190   }
191   else
192   {
193      memset(state->m_pixels + state->m_last_cycles, 0, sizeof(state->m_pixels) - state->m_last_cycles);
194      memset(state->m_pixels, 0, frame_cycles);
195   }
196126
197   state->m_last_cycles = frame_cycles;
198}
127      case 0x02: // Port C
128         video_update();
129         m_port_c = data;
130         m_latched_color = m_port_c;
131         break;
199132
200static void portb_write(avr8_device &device, UINT8 pins, UINT8 changed)
201{
202    craft_state *state = device.machine().driver_data<craft_state>();
203   if(pins & changed & 0x02)
204   {
205      state->m_frame_start_cycle = device.get_elapsed_cycles();
206   }
133      case 0x03: // Port D
134      {
135         m_port_d = data;
136         UINT8 audio_sample = (data & 0x02) | ((data & 0xf4) >> 2);
137         m_dac->write_unsigned8(audio_sample << 1);
138         break;
139      }
140    }
207141}
208142
209static void portc_write(avr8_device &device, UINT8 pins, UINT8 changed)
143void craft_state::video_update()
210144{
211    craft_state *state = device.machine().driver_data<craft_state>();
212   avr8_video_update(device.machine());
213   AVR8_PORTC = pins;
214}
145   UINT64 cycles = m_maincpu->get_elapsed_cycles();
146   UINT32 frame_cycles = (UINT32)(cycles - m_frame_start_cycle);
215147
216static void portd_write(avr8_device &device, UINT8 pins, UINT8 changed)
217{
218    craft_state *state = device.machine().driver_data<craft_state>();
219   UINT8 audio_sample = (pins & 0x02) | ((pins & 0xf4) >> 2);
220   state->dac->write_unsigned8(audio_sample << 1);
221}
222
223/****************/
224/* SPI Handling */
225/****************/
226
227static void avr8_enable_spi(running_machine &machine)
228{
229   // TODO
230   verboselog(machine, 0, "avr8_enable_spi: TODO\n");
231}
232
233static void avr8_disable_spi(running_machine &machine)
234{
235   // TODO
236   verboselog(machine, 0, "avr8_disable_spi: TODO\n");
237}
238
239static void avr8_spi_update_masterslave_select(running_machine &machine)
240{
241   // TODO
242    //craft_state *state = machine.driver_data<craft_state>();
243   //verboselog(machine, 0, "avr8_spi_update_masterslave_select: TODO; AVR is %s\n", AVR8_SPCR_MSTR ? "Master" : "Slave");
244}
245
246static void avr8_spi_update_clock_polarity(running_machine &machine)
247{
248   // TODO
249    //craft_state *state = machine.driver_data<craft_state>();
250   //verboselog(machine, 0, "avr8_spi_update_clock_polarity: TODO; SCK is Active-%s\n", AVR8_SPCR_CPOL ? "Low" : "High");
251}
252
253static void avr8_spi_update_clock_phase(running_machine &machine)
254{
255   // TODO
256    //craft_state *state = machine.driver_data<craft_state>();
257   //verboselog(machine, 0, "avr8_spi_update_clock_phase: TODO; Sampling edge is %s\n", AVR8_SPCR_CPHA ? "Trailing" : "Leading");
258}
259
260static const UINT8 avr8_spi_clock_divisor[8] = { 4, 16, 64, 128, 2, 8, 32, 64 };
261
262static void avr8_spi_update_clock_rate(running_machine &machine)
263{
264   // TODO
265    //craft_state *state = machine.driver_data<craft_state>();
266   //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));
267}
268
269static void avr8_change_spcr(running_machine &machine, UINT8 data)
270{
271    craft_state *state = machine.driver_data<craft_state>();
272
273   UINT8 oldspcr = AVR8_SPCR;
274   UINT8 newspcr = data;
275   UINT8 changed = newspcr ^ oldspcr;
276   UINT8 high_to_low = ~newspcr & oldspcr;
277   UINT8 low_to_high = newspcr & ~oldspcr;
278
279   AVR8_SPCR = data;
280
281   if(changed & AVR8_SPCR_SPIE_MASK)
148   if (m_last_cycles < frame_cycles)
282149   {
283      // Check for SPI interrupt condition
284      state->m_maincpu->update_interrupt(AVR8_INTIDX_SPI);
150      for (UINT32 pixidx = m_last_cycles; pixidx < frame_cycles && pixidx < PIXELS_PER_FRAME; pixidx++)
151      {
152         m_pixels[pixidx] = m_latched_color;
153      }
285154   }
286
287   if(low_to_high & AVR8_SPCR_SPE_MASK)
155   else
288156   {
289      avr8_enable_spi(machine);
290   }
291   else if(high_to_low & AVR8_SPCR_SPE_MASK)
292   {
293      avr8_disable_spi(machine);
294   }
295
296   if(changed & AVR8_SPCR_MSTR_MASK)
297   {
298      avr8_spi_update_masterslave_select(machine);
299   }
300
301   if(changed & AVR8_SPCR_CPOL_MASK)
302   {
303      avr8_spi_update_clock_polarity(machine);
304   }
305
306   if(changed & AVR8_SPCR_CPHA_MASK)
307   {
308      avr8_spi_update_clock_phase(machine);
309   }
310
311   if(changed & AVR8_SPCR_SPR_MASK)
312   {
313      avr8_spi_update_clock_rate(machine);
314   }
315}
316
317static void avr8_change_spsr(running_machine &machine, UINT8 data)
318{
319    craft_state *state = machine.driver_data<craft_state>();
320
321   UINT8 oldspsr = AVR8_SPSR;
322   UINT8 newspsr = data;
323   UINT8 changed = newspsr ^ oldspsr;
324   //UINT8 high_to_low = ~newspsr & oldspsr;
325   //UINT8 low_to_high = newspsr & ~oldspsr;
326
327   AVR8_SPSR &= ~1;
328   AVR8_SPSR |= data & 1;
329
330   if(changed & AVR8_SPSR_SPR2X_MASK)
331   {
332      avr8_spi_update_clock_rate(machine);
333   }
334}
335
336WRITE8_MEMBER(craft_state::avr8_write)
337{
338    switch( offset )
339    {
340      case AVR8_REGIDX_SPSR:
341         avr8_change_spsr(machine(), data);
342         break;
343
344      case AVR8_REGIDX_SPCR:
345         avr8_change_spcr(machine(), data);
346         break;
347
348      case AVR8_REGIDX_SPDR:
157      UINT32 end_clear = sizeof(m_pixels) - m_last_cycles;
158      UINT32 start_clear = frame_cycles;
159      end_clear = (end_clear > PIXELS_PER_FRAME) ? (PIXELS_PER_FRAME - m_last_cycles) : end_clear;
160      start_clear = (start_clear > PIXELS_PER_FRAME) ? PIXELS_PER_FRAME : start_clear;
161      if (m_last_cycles < PIXELS_PER_FRAME)
349162      {
350         avr8_video_update(machine());
351         m_regs[offset] = data;
352         m_spi_pending = true;
353         m_spi_start_cycle = m_maincpu->get_elapsed_cycles() - m_frame_start_cycle;
354         break;
163         memset(m_pixels + m_last_cycles, 0, end_clear);
355164      }
165      if (start_clear < PIXELS_PER_FRAME)
166      {
167         memset(m_pixels, 0, start_clear);
168      }
169   }
356170
357      case AVR8_REGIDX_EECR:
358         if (data & AVR8_EECR_EERE)
359         {
360            UINT16 addr = (m_regs[AVR8_REGIDX_EEARH] & AVR8_EEARH_MASK) << 8;
361            addr |= m_regs[AVR8_REGIDX_EEARL];
362            m_regs[AVR8_REGIDX_EEDR] = m_eeprom[addr];
363         }
364         break;
365
366        case AVR8_REGIDX_EEARL:
367        case AVR8_REGIDX_EEARH:
368         m_regs[offset] = data;
369         break;
370
371      case AVR8_REGIDX_DDRD:
372         avr8_change_ddr(machine(), AVR8_REG_D, data);
373         break;
374
375      case AVR8_REGIDX_DDRC:
376         avr8_change_ddr(machine(), AVR8_REG_C, data);
377         break;
378
379      case AVR8_REGIDX_DDRB:
380         avr8_change_ddr(machine(), AVR8_REG_B, data);
381         break;
382
383        default:
384            verboselog(machine(), 0, "AVR8: Unrecognized register write: %02x = %02x\n", offset, data );
385    }
171   m_last_cycles = frame_cycles;
386172}
387173
388174/****************************************************\
r18880r18881
393179    AM_RANGE(0x0000, 0x1fff) AM_ROM
394180ADDRESS_MAP_END
395181
396static ADDRESS_MAP_START( craft_io_map, AS_IO, 8, craft_state )
397    AM_RANGE(0x0000, 0x00ff) AM_READWRITE(avr8_read, avr8_write)
182static ADDRESS_MAP_START( craft_data_map, AS_DATA, 8, craft_state )
398183    AM_RANGE(0x0100, 0x04ff) AM_RAM
399184ADDRESS_MAP_END
400185
186static ADDRESS_MAP_START( craft_io_map, AS_IO, 8, craft_state )
187    AM_RANGE(0x00, 0x03) AM_READWRITE( port_r, port_w )
188ADDRESS_MAP_END
189
401190/****************************************************\
402191* Input ports                                        *
403192\****************************************************/
r18880r18881
438227
439228void craft_state::machine_reset()
440229{
441    craft_state *state = machine().driver_data<craft_state>();
230    m_dac = machine().device<dac_device>("dac");
442231
443    state->dac = machine().device<dac_device>("dac");
232    m_dac->write_unsigned8(0x00);
444233
445    state->dac->write_unsigned8(0x00);
446
447    state->m_eeprom = memregion("eeprom")->base();
448
449    state->m_frame_start_cycle = 0;
450    state->m_last_cycles = 0;
451
452    state->m_spi_pending = false;
453
454    state->m_spi_start_cycle = 0;
234    m_frame_start_cycle = 0;
235    m_last_cycles = 0;
455236}
456237
457238const avr8_config atmega88_config =
458239{
459   &portb_write,   // Video timing signals
460   &portc_write,   // Video color signals
461   &portd_write   // Audio DAC
240   "eeprom"
462241};
463242
464243static MACHINE_CONFIG_START( craft, craft_state )
r18880r18881
467246    MCFG_CPU_ADD("maincpu", ATMEGA88, MASTER_CLOCK)
468247    MCFG_CPU_AVR8_CONFIG(atmega88_config)
469248    MCFG_CPU_PROGRAM_MAP(craft_prg_map)
249    MCFG_CPU_DATA_MAP(craft_data_map)
470250    MCFG_CPU_IO_MAP(craft_io_map)
471251
472252    /* video hardware */
r18880r18881
492272ROM_END
493273
494274/*   YEAR  NAME      PARENT    COMPAT    MACHINE   INPUT     INIT      COMPANY          FULLNAME */
495CONS(2008, craft,    0,        0,        craft,    craft, craft_state,    craft,    "Linus Akesson", "Craft", GAME_IMPERFECT_GRAPHICS)
275CONS(2008, craft,    0,        0,        craft,    craft, craft_state,    craft,    "Linus Akesson", "Craft", GAME_NOT_WORKING)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team