#include "z180-serv.h"
#include "common.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
#include <util/atomic.h>
#include "config.h"
/* ---------------------------------------------------------------------------*/
+/* measure f_cpu */
+void do_msg_m_fcpu(uint8_t subf, int len UNUSED, uint8_t * msg)
+{
+ uint32_t freq;
+ uint8_t eimsk_save;
+
+ /* 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 */
+ z80_bus_cmd(Request);
+ z80_write(0x3f, 0xff);
+ z80_bus_cmd(Release);
+
+ freq = z80_measure_phi(*msg);
+
+ z80_bus_cmd(Request);
+ z80_write(0x3f, 0xff);
+ z80_bus_cmd(Release);
+
+ /* 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);
+ }
+
+ msg_xmit(4, subf, sizeof(freq), (uint8_t *) &freq);
+}
+
+/* ---------------------------------------------------------------------------*/
+
#define CPM_DAY_OFFSET ((1978-1900) * 365 + 19) /* 19 leap years */
/*
for (uint8_t i = 0; i < CONFIG_CPM_MAX_DRIVE; i++) {
struct cpm_drive_s * p = &drv_table[i];
if (p->img_name) {
- printf_P(PSTR(" dsk%d: %2s %3s attached to %s\n"), i,
- p->opt&DRV_OPT_RO ? "RO":"RW", p->opt&DRV_OPT_DEBUG ? "DBG":"",
+ printf_P(PSTR(" dsk%d: %2S %3S attached to %s\n"), i,
+ p->opt&DRV_OPT_RO ? PSTR("RO") : PSTR("RW"),
+ p->opt&DRV_OPT_DEBUG ? PSTR("DBG") : PSTR(""),
p->img_name);
}
}
p->flags &= ~DRV_FLG_DIRTY;
p->img_name = NULL;
- uint32_t scb = getenv_ulong(ENV_CPM3_SCB, 16, 0);
+ uint32_t scb = getenv_ulong(PSTR(ENV_CPM3_SCB), 16, 0);
if (scb && (z80_bus_cmd(Request) & ZST_ACQUIRED)) {
z80_write(scb + 0xf0, 0xff);
z80_write(p->dph + 11, 0xff);
drv = unit;
if (drv >= CONFIG_CPM_MAX_DRIVE)
- return AT_RANGE;
+ return EATRANGE;
struct cpm_drive_s *p = &drv_table[drv];
if (options & DRV_OPT_REATTATCH) {
if (filename) {
- return AT_ERROR;
+ return EUNEXPARG;
}
if (!p->img_name) {
- return AT_NOT;
+ return EATNOT;
}
/* change options */
} else {
if (p->img_name)
- return AT_ALREADY;
+ return EATALRDY;
if (drv_find_file_attached(filename) >= 0)
- return AT_OTHER;
+ return EATOTHER;
p->opt = options;
/* new attachment */
if ((p->img_name = strdup(filename)) == NULL)
- return AT_NOMEM;
+ return ENOMEM;
res = f_open(&p->fd, p->img_name,
FA_READ | (options&DRV_OPT_RO ? 0 : FA_WRITE));
}
if (res) {
drv_detach(drv);
- return AT_OPEN;
+ return EATOPEN;
}
}
- return AT_OK;
+ return ESUCCESS;
}
FSTR("Access byond disk size"), /* 04 */
FSTR("Write protect"), /* 05 */
FSTR("No media"), /* 06 */
+ FSTR("R/W address == 0 !!!!"), /* 07 */
};
void msg_cpm_result(uint8_t subf, uint8_t rc, int res)
msg_xmit(2, subf, sizeof(result_msg), result_msg);
- if (rc)
+ if (rc) {
+#if defined(GCC_BUG_61443)
+ char msg[40];
+ strncpy_P(msg, rc_messages[rc & 0x7f], sizeof msg -1);
+ drv_debug(END, PSTR(" rc: %.02x/%d, '%s'"),
+ rc, res, msg);
+#else
drv_debug(END, PSTR(" rc: %.02x/%d, '%S'"),
rc, res, rc_messages[rc & 0x7f]);
- else
+#endif
+ } else
drv_debug(END, PSTR(""));
}
drv_debug(MIDDLE, PSTR(" T:%4d, S:%2d, cnt:%2d, lba: %.8lx, addr: %.5lx"),
track, sec, secs, pos, addr);
+ if (addr == 0) {
+ return msg_cpm_result(subf, 0x07, res);
+ }
+
if (dowrite && dp->opt & DRV_OPT_RO) {
return msg_cpm_result(subf, 0x05, res);
}
{ 3,
2, 3, /* 2: get, 3: set time and date */
do_msg_get_set_time},
+ { 4,
+ 1, 1,
+ do_msg_m_fcpu},
{ 0xff, /* end mark */
0, 0,
0},
};
-
-
void do_message(int len, uint8_t *msg)
{
uint8_t fct, sub_fct;