- Timestamp:
- 07/31/2017 05:01:38 PM (7 years ago)
- Branches:
- master
- Children:
- 1489228
- Parents:
- 1efc42c
- git-author:
- Thomas Lopatic <thomas@…> (07/31/2017 05:01:32 PM)
- git-committer:
- Thomas Lopatic <thomas@…> (07/31/2017 05:01:38 PM)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
emu/fdd.c
r1efc42c rc5b6c90 26 26 #define N_CYL 80 27 27 #define N_SID 2 28 #define N_SEC 1828 #define N_SEC 9 29 29 #define SZ_SEC 512 30 30 31 31 #define SZ_DISK (N_CYL * N_SID * N_SEC * SZ_SEC) 32 32 33 #define REG_COM_STAT 0 34 #define REG_TRA 1 35 #define REG_SEC 2 36 #define REG_DAT 3 37 38 #define COM_REST 0x00 39 #define COM_SEEK 0x10 40 #define COM_SEEK_VER 0x14 41 #define COM_RD_SEC 0x80 42 #define COM_RD_SEC_MUL 0x90 43 #define COM_WR_SEC_WP 0xa0 44 #define COM_WR_SEC 0xa2 45 #define COM_INT 0xd0 46 #define COM_WR_TRA 0xf0 47 48 #define COM_LAT_CYC 10 49 #define COM_EXE_CYC 10 50 51 typedef enum { 52 STEP_IDLE, 53 STEP_PREP, 54 STEP_EXEC 55 } step_t; 56 57 typedef struct { 58 int32_t reg_tra; 59 int32_t reg_sec; 60 int32_t reg_dat; 61 int32_t sid; 62 step_t step; 63 int32_t com; 64 int32_t cyc; 65 uint8_t *dat; 66 bool tra_0; 67 } state_t; 68 69 static state_t state = { 70 .reg_tra = 0, .reg_sec = 0, .reg_dat = 0, .sid = 0, 71 .step = STEP_IDLE, .com = -1, .cyc = 0, .dat = NULL, .tra_0 = false 72 }; 73 33 74 static uint8_t image[SZ_DISK]; 75 76 static const char *com_string(int32_t com) 77 { 78 switch (com) { 79 case COM_REST: 80 return "COM_REST"; 81 82 case COM_SEEK: 83 return "COM_SEEK"; 84 85 case COM_SEEK_VER: 86 return "COM_SEEK_VER"; 87 88 case COM_RD_SEC: 89 return "COM_RD_SEC"; 90 91 case COM_RD_SEC_MUL: 92 return "COM_RD_SEC_MUL"; 93 94 case COM_WR_SEC_WP: 95 return "COM_WR_SEC_WP"; 96 97 case COM_WR_SEC: 98 return "COM_WR_SEC"; 99 100 case COM_WR_TRA: 101 return "COM_WR_TRA"; 102 103 default: 104 fail("unknown command 0x%02x", com); 105 } 106 } 107 108 static void stat_string(int32_t stat, char *buff) { 109 buff[0] = 0; 110 111 if ((stat & 0x80) != 0) { 112 strcat(buff, " mot_on"); 113 } 114 115 if ((stat & 0x04) != 0) { 116 strcat(buff, " zero"); 117 } 118 119 if ((stat & 0x02) != 0) { 120 strcat(buff, " dat_req"); 121 } 122 123 if ((stat & 0x01) != 0) { 124 strcat(buff, " busy"); 125 } 126 } 127 128 void fdd_set_side(int32_t sid) 129 { 130 ver2("sid <- %d", sid); 131 state.sid = sid; 132 } 133 134 void fdd_set_sel(int32_t sel) 135 { 136 ver2("sel <- %d", sel); 137 } 34 138 35 139 void fdd_init(void) … … 67 171 { 68 172 ver3("fdd exec"); 173 174 switch (state.step) { 175 case STEP_IDLE: 176 break; 177 178 case STEP_PREP: 179 ver3("prep %d", state.cyc); 180 --state.cyc; 181 182 if (state.cyc == 0) { 183 ver2("exec %s", com_string(state.com)); 184 state.step = STEP_EXEC; 185 state.cyc = COM_EXE_CYC; 186 } 187 188 break; 189 190 case STEP_EXEC: 191 ver3("exec %d", state.cyc); 192 --state.cyc; 193 194 if (state.cyc == 0) { 195 ver2("idle %s", com_string(state.com)); 196 state.step = STEP_IDLE; 197 } 198 199 break; 200 } 201 69 202 return false; 70 203 } … … 72 205 uint32_t fdd_read(uint32_t off, int32_t sz) 73 206 { 74 ver2("fdd rd %u:%d", off, sz * 8); 75 return 0; 207 ver3("fdd rd %u:%d", off, sz * 8); 208 209 if (sz != 1 || off > 3) { 210 fail("invalid fdd rd %u:%d", off, sz * 8); 211 } 212 213 uint32_t rv; 214 215 switch (off) { 216 case REG_COM_STAT: 217 rv = 0x80; // motor on 218 219 if (state.step == STEP_EXEC) { 220 rv |= 0x01; // busy 221 222 switch (state.com) { 223 case COM_RD_SEC: 224 case COM_RD_SEC_MUL: 225 case COM_WR_SEC: 226 case COM_WR_SEC_WP: 227 rv |= 0x02; // data request 228 break; 229 } 230 } 231 232 if (state.tra_0) { 233 rv |= 0x04; // track zero 234 } 235 236 char stat[100]; 237 stat_string((int32_t)rv, stat); 238 ver3("stat -> 0x%02x%s", rv, stat); 239 break; 240 241 case REG_TRA: 242 rv = (uint32_t)state.reg_tra; 243 ver2("tra -> %u", rv); 244 break; 245 246 case REG_SEC: 247 rv = (uint32_t)state.reg_sec; 248 ver2("sec -> %u", rv); 249 break; 250 251 case REG_DAT: 252 if (state.step != STEP_EXEC || 253 (state.com != COM_RD_SEC && state.com != COM_RD_SEC_MUL)) { 254 fail("unexpected data register read"); 255 } 256 257 rv = *state.dat; 258 size_t addr = (size_t)(state.dat - image); 259 260 if ((addr & (SZ_SEC - 1)) == 0) { 261 ver2("addr 0x%06zx -> 0x%02x", addr, rv); 262 } 263 else { 264 ver3("addr 0x%06zx -> 0x%02x", addr, rv); 265 } 266 267 ++state.dat; 268 state.cyc = COM_EXE_CYC; 269 break; 270 271 default: 272 rv = 0; 273 break; 274 } 275 276 return rv; 76 277 } 77 278 78 279 void fdd_write(uint32_t off, int32_t sz, uint32_t val) 79 280 { 80 ver2("fdd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val); 81 } 281 ver3("fdd wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val); 282 283 if (sz != 1 || off > 3) { 284 fail("invalid fdd wr %u:%d", off, sz * 8); 285 } 286 287 switch (off) { 288 case REG_COM_STAT: 289 ver2("com <- 0x%02x, tra %d, sid %d, sec %d", 290 val, state.reg_tra, state.sid, state.reg_sec); 291 292 state.com = (int32_t)val; 293 294 ver2("prep %s", com_string(state.com)); 295 state.step = STEP_PREP; 296 state.cyc = COM_LAT_CYC; 297 298 switch (val) { 299 case COM_REST: 300 state.reg_tra = 0; 301 state.tra_0 = true; 302 break; 303 304 case COM_SEEK: 305 case COM_SEEK_VER: 306 state.reg_tra = state.reg_dat; 307 state.tra_0 = state.reg_tra == 0; 308 break; 309 310 case COM_RD_SEC: 311 case COM_RD_SEC_MUL: 312 case COM_WR_SEC: 313 case COM_WR_SEC_WP: { 314 size_t sec_off = (size_t)(((state.reg_tra * N_SID + state.sid) * N_SEC + 315 state.reg_sec - 1) * SZ_SEC); 316 state.dat = image + sec_off; 317 state.tra_0 = false; 318 break; 319 } 320 321 case COM_INT: 322 state.step = STEP_IDLE; 323 state.com = -1; 324 state.cyc = 0; 325 state.dat = NULL; 326 state.tra_0 = false; 327 break; 328 329 case COM_WR_TRA: 330 state.tra_0 = false; 331 fail("format not yet supported"); 332 break; 333 } 334 335 break; 336 337 case REG_TRA: 338 state.reg_tra = (int32_t)val; 339 ver2("tra <- %u", val); 340 break; 341 342 case REG_SEC: 343 state.reg_sec = (int32_t)val; 344 ver2("sec <- %u", val); 345 break; 346 347 case REG_DAT: 348 if (state.step == STEP_EXEC && 349 (state.com == COM_WR_SEC || state.com == COM_WR_SEC_WP)) { 350 *state.dat = (uint8_t)val; 351 size_t addr = (size_t)(state.dat - image); 352 353 if ((addr & (SZ_SEC - 1)) == 0) { 354 ver2("addr 0x%06zx <- 0x%02x", addr, val); 355 } 356 else { 357 ver3("addr 0x%06zx <- 0x%02x", addr, val); 358 } 359 360 ++state.dat; 361 state.cyc = COM_EXE_CYC; 362 } 363 else { 364 state.reg_dat = (int32_t)val; 365 ver2("dat <- 0x%02x", val); 366 } 367 368 break; 369 370 default: 371 break; 372 } 373 }
Note:
See TracChangeset
for help on using the changeset viewer.