summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo C.2024-06-24 11:59:56 +0200
committerLeo C.2024-06-24 11:59:56 +0200
commit7535ca1b43f9320f0de3c49fc7a12560a5022a7c (patch)
tree09edd4a41f56b6cc8db9552fdc4dd8ac56a8874c
parent49475345ffc5fd27ca937006ef6aa18858bf7c90 (diff)
downloadz180-stamp-7535ca1b43f9320f0de3c49fc7a12560a5022a7c.zip
merge/unify chkcpu and freq. wip
-rw-r--r--avr/cmd_cpu.c264
-rw-r--r--z180/cpuinfo.18054
2 files changed, 193 insertions, 125 deletions
diff --git a/avr/cmd_cpu.c b/avr/cmd_cpu.c
index 64dd721..e77b901 100644
--- a/avr/cmd_cpu.c
+++ b/avr/cmd_cpu.c
@@ -27,6 +27,20 @@
debug_cond(DEBUG_CPU, fmt, ##args)
+char * ulltoa (uint64_t val, char *s)
+{
+ char *p = s;
+
+ while (val >= 10) {
+ *p++ = (val % 10) + '0';
+ val = val / 10;
+ }
+ *p++ = val + '0';
+ *p = '\0';
+
+ return strrev(s);
+}
+
/*
* delay for <count> ms...
*/
@@ -59,24 +73,21 @@ static uint32_t z80_measure_phi(uint_fast8_t cycles)
/* Wait for falling edge */
while ((EIFR & _BV(INTF6)) == 0)
;
- TCCR3B = 0b110<<CS30; /* Count falling edges on T3 (==INT6) */
OCR4B = TCNT4;
+ TCCR3B = 0b110<<CS30; /* Count falling edges on T3 (==INT6) */
TIFR4 = _BV(OCF4B); /* clear compare match flag */
- }
- while (ref_ovfl < 60) {
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
+
+ while (ref_ovfl < 60) {
if ((TIFR4 & _BV(OCF4B)) != 0) {
TIFR4 = _BV(OCF4B);
- ref_ovfl++;
+ ++ref_ovfl;
}
if ((TIFR3 & _BV(TOV3)) != 0) {
TIFR3 = _BV(TOV3);
- x_ovfl++;
+ ++x_ovfl;
}
}
- }
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
EIFR = _BV(INTF6);
for (;;) {
if (EIFR & _BV(INTF6)) {
@@ -86,7 +97,7 @@ static uint32_t z80_measure_phi(uint_fast8_t cycles)
}
if ((TIFR4 & _BV(OCF4B)) != 0) {
TIFR4 = _BV(OCF4B);
- ref_ovfl++;
+ ++ref_ovfl;
}
}
}
@@ -100,12 +111,16 @@ static uint32_t z80_measure_phi(uint_fast8_t cycles)
uint32_t x_cnt = TCNT3 + ((uint32_t) x_ovfl << 16);
uint64_t x_tmp = (uint64_t) 100000 * (x_cnt * cycles);
- debug_cpu("TCNT3: %6u, ref_cnt: %9lu\n", TCNT3, ref_cnt);
- debug_cpu("x_tmp: %lu %lu\n", (uint32_t) (x_tmp >> 32), (uint32_t) (x_tmp & 0xffffffff));
+// char x_tmp_str[21];
+//
+// debug_cpu("TCNT3: %6u, ref_cnt: %9lu\n", TCNT3, ref_cnt);
+// ulltoa(x_tmp, x_tmp_str);
+// debug_cpu("x_tmp: %s\n", x_tmp_str);
x_tmp = (x_tmp * getenv_ulong(PSTR(ENV_FMON), 10, F_CPU) + (ref_cnt / 2)) / ref_cnt;
- debug_cpu("x_tmp: %lu %lu\n", (uint32_t) (x_tmp >> 32), (uint32_t) (x_tmp & 0xffffffff));
+// ulltoa(x_tmp, x_tmp_str);
+// debug_cpu("x_tmp: %s\n", x_tmp_str);
/* round to 5 decimal digits */
int_fast8_t sc = 5;
@@ -126,36 +141,19 @@ static uint32_t z80_measure_phi(uint_fast8_t cycles)
return x_freq;
}
-static const FLASH uint8_t loop_code[] = {
-/* 0000 */ 0x00, /* nop */
-/* 0001 */ 0xAF, /* xor a */
-/* 0005 */ 0xD3,0x32, /* out (032h),a ;DCNTL */
-/* 0002 */ 0xD3,0x36, /* out (036h),a ;RCR */
-/* */ /* */
-/* 0006 */ 0xD3,0x40, /* out (040H),a ;Ready */
-/* */ /* */
-/* */ /* ;Z80 Z180(0W) Z180(MaxW) */
-/* 0008 */ /* loop: ;-------------------------- */
-/* 0008 */ 0xDB,0x50, /* in a,(050h) ;11 10 +3*3 19 */
-/* 000A */ 0xC3,0x08,0x00 /* jp loop ;10 9 +3*3 18 */
- /* ;-------------------------- */
- /* ;21 19 37 */
-};
-
-command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
-{
#define O_SILENT (1<<0)
#define O_WENV (1<<1)
#define O_LOAD_LOOP (1<<2)
#define O_UNLOAD_LOOP (1<<3)
+command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
+{
uint_fast8_t options = O_LOAD_LOOP | O_UNLOAD_LOOP;
- uint_fast8_t lcycles = 19;
+ uint_fast8_t lcycles = 0;
uint16_t timeout = 1000;
uint8_t eimsk_save;
-
- uint8_t mem_save[ARRAY_SIZE(loop_code)];
+ ERRNUM err = ESUCCESS;
int opt;
while ((opt = getopt(argc, argv, PSTR("swnuc:t:"))) != -1) {
@@ -185,31 +183,32 @@ command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int
if (argc - optind != 0)
return CMD_RET_USAGE;
- if (z80_bus_state() & ZST_RUNNING) {
- if (!(options & O_SILENT))
- printf_P(PSTR("Frequency measuring failed. CPU allready running!\n"));
- return CMD_RET_FAILURE;
+ if (z80_bus_state() & ZST_RUNNING)
+ cmd_error(CMD_RET_FAILURE, ERUNNING, NULL);
+
+ uint8_t *mem_save = NULL;
+ if (options & O_LOAD_LOOP) {
+ mem_save = (uint8_t *) malloc(cpuinfo_length);
+ if (mem_save == NULL)
+ cmd_error(CMD_RET_FAILURE, ENOMEM, NULL);
+ z80_bus_cmd(Request);
+ z80_read_block(mem_save, 0, cpuinfo_length);
+ z80_load_mem(0, cpuinfo, &cpuinfo_sections, cpuinfo_address,
+ cpuinfo_length_of_sections);
+ z80_bus_cmd(Release);
}
+ /* Save state and disable INT5/INT6 */
ATOMIC_BLOCK(ATOMIC_FORCEON) {
- /* Save state and disable INT5/INT6 */
eimsk_save = EIMSK;
EIMSK &= ~_BV(INT6);
EIMSK &= ~_BV(INT5);
}
-
- z80_bus_cmd(Request);
- if (options & O_LOAD_LOOP) {
- z80_read_block(mem_save, 0, ARRAY_SIZE(loop_code));
- z80_write_block_P(loop_code, 0, ARRAY_SIZE(loop_code));
- }
EIFR = _BV(INTF5); /* Reset pending int */
- z80_bus_cmd(Release);
+
z80_bus_cmd(Run);
clear_ctrlc(); /* forget any previous Control C */
- ERRNUM err = 0;
-
/* Wait for falling edge */
do {
/* check for ctrl-c to abort... */
@@ -219,18 +218,20 @@ command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int
}
} while ((EIFR & _BV(INTF5)) == 0);
+ if (lcycles == 0) {
+ z80_bus_cmd(Request);
+ if (z80_read(3) == 0xFF)
+ lcycles = z80_read(5);
+ z80_bus_cmd(Release);
+ }
uint32_t cpu_freq = 0;
if (!err)
cpu_freq = z80_measure_phi(lcycles);
z80_bus_cmd(Reset);
- if (options & O_UNLOAD_LOOP) {
- z80_bus_cmd(Request);
- z80_write_block(mem_save, 0, ARRAY_SIZE(loop_code));
- z80_bus_cmd(Release);
- }
+
+ /* Restore INT5/INT6 */
ATOMIC_BLOCK(ATOMIC_FORCEON) {
- /* Restore INT5/INT6 */
if ((eimsk_save & _BV(INT5)) != 0)
EIMSK |= _BV(INT5);
if ((eimsk_save & _BV(INT6)) != 0)
@@ -239,17 +240,28 @@ command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int
EIFR = _BV(INTF5);
EIFR = _BV(INTF6);
}
-
Stat &= ~S_MSG_PENDING;
Stat &= ~S_CON_PENDING;
+
+
+
+
+
+
+ if ((mem_save != NULL) && options & O_UNLOAD_LOOP) {
+ z80_bus_cmd(Request);
+ z80_write_block(mem_save, 0, cpuinfo_length);
+ z80_bus_cmd(Release);
+ }
+ free(mem_save);
+
if (err)
cmd_error(CMD_RET_FAILURE, err, NULL);
- if (!(options & O_SILENT)) {
- uint8_t sc = cpu_freq >> 28;
- printf_P(PSTR("%lu %3u\n"), cpu_freq & 0x0fffffff, sc);
- }
+ if (!(options & O_SILENT))
+ printf_P(PSTR("%lu\n"), cpu_freq);
+
#if 0
if (options & O_WENV) {
if (setenv_ulong(PSTR(ENV_CPU_FREQ), cpu_freq)) {
@@ -275,64 +287,104 @@ static const FLASH char * const FLASH cpu_strings[] = {
command_ret_t do_cpuchk(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
{
+ uint_fast8_t options = O_LOAD_LOOP | O_UNLOAD_LOOP;
uint_fast8_t cputype = 0;
ERRNUM err = ESUCCESS;
uint8_t eimsk_save;
- uint8_t ram_save[cpuinfo_length];
-
- if (z80_bus_state() & ZST_RUNNING) {
- err = ERUNNING;
- } else {
- z80_bus_request_or_exit();
- z80_read_block(ram_save, 0, cpuinfo_length);
- z80_load_mem(0, cpuinfo,
- &cpuinfo_sections,
- cpuinfo_address,
- cpuinfo_length_of_sections);
+
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("swnu"))) != -1) {
+ switch (opt) {
+ case 's':
+ options |= O_SILENT;
+ break;
+ case 'w':
+ options |= O_WENV;
+ break;
+ case 'n':
+ options &= ~O_LOAD_LOOP;
+ break;
+ case 'u':
+ options &= ~O_UNLOAD_LOOP;
+ break;
+ default: /* '?' */
+ return CMD_RET_USAGE;
+ }
+ }
+ if (argc - optind != 0)
+ return CMD_RET_USAGE;
+
+ if (z80_bus_state() & ZST_RUNNING)
+ cmd_error(CMD_RET_FAILURE, ERUNNING, NULL);
+
+ uint8_t *mem_save = NULL;
+ if (options & O_LOAD_LOOP) {
+ mem_save = (uint8_t *) malloc(cpuinfo_length);
+ if (mem_save == NULL)
+ cmd_error(CMD_RET_FAILURE, ENOMEM, NULL);
+ z80_bus_cmd(Request);
+ z80_read_block(mem_save, 0, cpuinfo_length);
+ z80_load_mem(0, cpuinfo, &cpuinfo_sections, cpuinfo_address,
+ cpuinfo_length_of_sections);
z80_bus_cmd(Release);
+ }
+
+ /* Save state and disable INT5/INT6 */
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ eimsk_save = EIMSK;
+ EIMSK &= ~_BV(INT6);
+ EIMSK &= ~_BV(INT5);
+ }
+ EIFR = _BV(INTF5); /* Reset pending int */
- if (argv[1] && (argv[1][0] == 'n'))
- goto donot;
+ z80_bus_cmd(Run);
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
- /* Save state and disable INT5/INT6 */
- eimsk_save = EIMSK;
- EIMSK &= ~_BV(INT6);
- EIMSK &= ~_BV(INT5);
- }
- EIFR = _BV(INTF5); /* Reset pending int */
- z80_bus_cmd(Run);
-
- clear_ctrlc(); /* forget any previous Control C */
- do {
- /* check for ctrl-c to abort... */
- if (had_ctrlc() || ctrlc()) {
- err = EINTR;
- break;
- }
- } while ((EIFR & _BV(INTF5)) == 0);
- z80_bus_cmd(Reset);
- ATOMIC_BLOCK(ATOMIC_FORCEON) {
- /* Restore INT5/INT6 */
- if ((eimsk_save & _BV(INT5)) != 0)
- EIMSK |= _BV(INT5);
- if ((eimsk_save & _BV(INT6)) != 0)
- EIMSK |= _BV(INT6);
- /* Reset pending int */
- EIFR = _BV(INTF5);
- EIFR = _BV(INTF6);
+ clear_ctrlc(); /* forget any previous Control C */
+ do {
+ /* check for ctrl-c to abort... */
+ if (had_ctrlc() || ctrlc()) {
+ err = EINTR;
+ break;
}
- Stat &= ~S_MSG_PENDING;
- Stat &= ~S_CON_PENDING;
+ } while ((EIFR & _BV(INTF5)) == 0);
+
+
+
+
+
+
+
+
+
+
+
+ z80_bus_cmd(Reset);
+
+ /* Restore INT5/INT6 */
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ if ((eimsk_save & _BV(INT5)) != 0)
+ EIMSK |= _BV(INT5);
+ if ((eimsk_save & _BV(INT6)) != 0)
+ EIMSK |= _BV(INT6);
+ /* Reset pending int */
+ EIFR = _BV(INTF5);
+ EIFR = _BV(INTF6);
+ }
+ Stat &= ~S_MSG_PENDING;
+ Stat &= ~S_CON_PENDING;
+
+ z80_bus_cmd(Request);
+ if (z80_read(3) == 0xFF) {
+ cputype = z80_read(4);
+ }
+ z80_bus_cmd(Release);
+
+ if ((mem_save != NULL) && options & O_UNLOAD_LOOP) {
z80_bus_cmd(Request);
- if (z80_read(3) == 0xFF) {
- cputype = z80_read(4);
- }
- z80_write_block(ram_save, 0, cpuinfo_length);
+ z80_write_block(mem_save, 0, cpuinfo_length);
z80_bus_cmd(Release);
}
-
-donot:
+ free(mem_save);
if (err)
cmd_error(CMD_RET_FAILURE, err, NULL);
diff --git a/z180/cpuinfo.180 b/z180/cpuinfo.180
index 0ea3e8e..372f003 100644
--- a/z180/cpuinfo.180
+++ b/z180/cpuinfo.180
@@ -29,6 +29,19 @@ base equ 0
done: db 0
result: db 0
+cycls: db 0
+wstates:db 0
+
+;-------------------------------------------------------------------------------
+cyctab:
+ db 0 ;Unknown CPU
+ db 20 ;8080
+ db 20 ;8085
+ db 21 ;Z80
+ db 19 ;HD64180 or higher
+ db 19 ;HD64180
+ db 19 ;Z80180
+ db 19 ;Z8S180, Z8L180
;-------------------------------------------------------------------------------
; Check if register C exists. D holds mask of bit to test.
@@ -111,9 +124,10 @@ chk_z80:
; Test differences in certain internal registers
; to determine the 180 variant.
- ld b,0
- ld c,icr
- in a,(c)
+ ld a,(wstates)
+ out0 (DCNTL),a
+ out0 (RCR),b ;
+ in0 a,(icr)
cp 01FH
jr z,icr_ok
@@ -125,7 +139,6 @@ chk_z80:
icr_ok:
inc e ; HD64180
- out0 (RCR),b ;
ld c,omcr ; Check, if CPU has OMCR register
ld d,M_IOC ;
call chk_reg ;
@@ -145,29 +158,32 @@ icr_ok:
start:
ld sp,stack
ld hl,done
- ld (hl),0
+ ld b,h
+ ld (hl),b
inc hl
- ld (hl),0
- push hl
+ ld (hl),b
call check
- pop hl
+ ld hl,cyctab
+ ld d,h
+ add hl,de
+ ld a,(hl)
+ ld hl,cycls
+ ld (hl),a
+ dec hl
ld (hl),e
dec hl
ld (hl),0ffH
out (040H),a
+ ;808x Z80 Z180(0W) Z180(MaxW)
+loop: ;---------------------------------
+ in a,(050h) ;10 11 10 +3*3 19
+ jp loop ;10 10 9 +3*3 18
+ ;---------------------------------
+ ;20 21 19 37
-; ld a,(wstates)
-; out0 (DCNTL),a
- ;Z80 Z180(0W) Z180(MaxW)
-loop: ;--------------------------
- in a,(050h) ;11 10 +3*3 19
- jp loop ;10 9 +3*3 18
- ;--------------------------
- ;21 19 37
-
-; jr loop ;12 8 +2*3 14
+; jr loop ;-- 12 8 +2*3 14
- rept 8
+ rept 4
dw 0
endm
stack: