+
+int z80_clock_set(unsigned long freq)
+{
+ unsigned long ocrval = F_CPU / freq / 2;
+ uint8_t prescale = 0;
+
+ while (ocrval > (1L<<16)) {
+ prescale++;
+ if (prescale < 3)
+ ocrval = ocrval / 8;
+ else
+ ocrval = ocrval / 4;
+ }
+
+ if ((ocrval == 0) || (prescale > 4))
+ return -1;
+
+ ocrval -= 1;
+
+ PINB |= _BV(6); /* Debug */
+
+ /* Stop Timer */
+ TCCR1B = (0b01 << WGM12) | (0b000 << CS10);
+ TCNT1 = 0;
+
+ OCR1A = ocrval;
+ OCR1CL = ocrval;
+ TCCR1A = (0b01 << COM1C0) | (0b00 << WGM10);
+ TCCR1B = (0b01 << WGM12) | ((prescale+1) << CS10);
+
+ if (ocrval == 0) {
+// TCCR1C |= _BV(FOC1C);
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ TCNT1 = 0xFFFF;
+ }
+ }
+
+ PINB |= _BV(6); /* Debug */
+
+ return 0;
+}
+
+uint32_t z80_clock_get(void)
+{
+ uint32_t count = (OCR1A + 1L) * 2;
+ uint8_t pre = (TCCR1B & 7) - 1;
+
+ while (pre) {
+ if (pre > 2)
+ count *= 4;
+ else
+ count *= 8;
+ pre--;
+
+ }
+
+ return F_CPU/count;
+}
+
+
+
+static void z80_addrbus_set_tristate(void)