]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_loadcpm3.c
2 * (C) Copyright 2015,2016,2018 Leo C. <erbl259-lmu@yahoo.de>
4 * SPDX-License-Identifier: GPL-2.0
8 * See CP/M 3 System Manual, Appendix D: CPM3.SYS File Format
11 #include "cmd_loadcpm3.h"
17 #include "con-utils.h"
23 #define RS 128 /* CP/M record size */
27 static FRESULT
read_record(FIL
*fp
, uint8_t *buffer
)
29 unsigned int br
; /* bytes read */
31 FRESULT res
= f_read(fp
, buffer
, RS
, &br
);
40 * Input: addr = Page Address of load top
41 * len = Length in pages of module to read
44 ERRNUM
load(FIL
*File
, uint32_t addr
, uint8_t len
)
48 len
*= 2; /* length in records of module */
49 //debug("## load: addr: 0x%.4X, records: 0x%.4X, (%u)\n", addr, len, len);
53 FRESULT res
= read_record(File
, buffer
);
57 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
))
59 z80_write_block(buffer
, addr
, RS
);
61 //debug("## written: 0x%.4X\n", addr);
67 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
69 command_ret_t
do_loadcpm3(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
75 uint16_t osentry_addr
= 0;
76 uint32_t common_base
= 0;
80 char default_fname
[strlen_P(PSTR(CONFIG_CPM3_SYSFILE
)) + 1];
85 //common_base = getenv_ulong(PSTR(ENV_CPM3_COMMON_BASE), 16,
86 // CONFIG_CPM3_COMMON_BASE);
87 banked_base
= getenv_ulong(PSTR(ENV_CPM3_BANKED_BASE
), 16,
88 CONFIG_CPM3_BANKED_BASE
);
91 banked_base
= eval_arg(argv
[3], NULL
);
93 common_base
= eval_arg(argv
[2], NULL
);
95 fname
= getenv_str(PSTR(ENV_CPM3_SYSFILE
));
96 if (fname
== NULL
|| *fname
== '\0') {
97 strcpy_P(default_fname
, PSTR(CONFIG_CPM3_SYSFILE
));
98 fname
= default_fname
;
104 res
= f_open(&File
, fname
, FA_READ
);
108 printf_P(PSTR("Loading: '%s'...\n"), fname
);
110 /* read the load record */
111 res
= read_record(&File
, buffer
);
115 mem_top
= buffer
[0] << 8;
117 bank_top
= buffer
[2] << 8;
118 bank_len
= buffer
[3];
119 osentry_addr
= buffer
[4] + (buffer
[5] << 8);
121 /* read display info */
122 res
= read_record(&File
, buffer
);
128 uint8_t *p
= memchr(buffer
, '$', RS
);
130 my_puts((char *)buffer
);
132 if (common_base
== 0) {
134 * http://www.seasip.info/Cpm/scb.html
136 FSIZE_t common_base_ofs
= ((res_len
- 6) << 8) + 2*RS
+ RS
-7;
137 FSIZE_t cur_pos
= f_tell(&File
);
138 unsigned int br
; /* bytes read */
139 if ((res
= f_lseek(&File
, common_base_ofs
)) ||
140 (res
= f_read(&File
, buffer
, 2, &br
)) ||
141 (res
= f_lseek(&File
, cur_pos
)))
147 common_base
= (uint16_t) buffer
[0] + (buffer
[1] << 8);
148 setenv_hex(PSTR(ENV_CPM3_COMMON_BASE
), common_base
);
151 setenv_hex(PSTR(ENV_CPM3_SCB
), mem_top
- ((res_len
- (6 - 1)) << 8) + common_base
);
153 /* Main System Load */
155 /* Load Common Portion of System */
156 if ((res
= load(&File
, common_base
+ mem_top
, res_len
)) != 0)
159 /* Load Banked Portion of System */
160 res
= load(&File
, banked_base
+ bank_top
, bank_len
);
166 cmd_error(CMD_RET_FAILURE
, res
, PSTR("%s"), fname
);
169 if (osentry_addr
+ common_base
> 0xffff) {
170 z80_bus_cmd(Request
);
171 if (z80_read(osentry_addr
+ common_base
) == 0xc3) {
172 osentry_addr
= z80_read(osentry_addr
+common_base
+1) +
173 (z80_read(osentry_addr
+ common_base
+2) << 8);
175 z80_bus_cmd(Release
);
176 if (banked_base
+ osentry_addr
> 0xffff)
179 setenv_hex(PSTR(ENV_STARTADDRESS
), osentry_addr
);
181 printf_P(PSTR("Loaded: Resident: "));
183 printf_P(PSTR("%.5lX-%.5lX, "),
184 (common_base
+ mem_top
) - res_len
*256,
185 (common_base
+ mem_top
) - 1);
187 printf_P(PSTR(" - "));
188 printf_P(PSTR("Banked: "));
190 printf_P(PSTR("%.5lX-%.5lX\n"),
191 (banked_base
+ bank_top
) - bank_len
*256,
192 (banked_base
+ bank_top
) - 1);
194 printf_P(PSTR(" - \n"));
196 return CMD_RET_SUCCESS
;