branches/alto2/src/emu/cpu/alto2/alto2.c
| r26263 | r26264 | |
| 2346 | 2346 | * </PRE> |
| 2347 | 2347 | */ |
| 2348 | 2348 | |
| 2349 | enum { |
| 2350 | A10_UNUSED = (1 << 0), |
| 2351 | A10_TSELECT = (1 << 1), |
| 2352 | A10_ALUCI = (1 << 2), |
| 2353 | A10_ALUM = (1 << 3), |
| 2354 | A10_ALUS0 = (1 << 4), |
| 2355 | A10_ALUS1 = (1 << 5), |
| 2356 | A10_ALUS2 = (1 << 6), |
| 2357 | A10_ALUS3 = (1 << 7), |
| 2358 | A10_ALUIN = (A10_ALUM|A10_ALUCI|A10_ALUS0|A10_ALUS1|A10_ALUS2|A10_ALUS3) |
| 2359 | }; |
| 2360 | |
| 2349 | 2361 | //! S function, M flag and C carry in |
| 2350 | | #define SMC(s3,s2,s1,s0,m,c) (((s3)<<7)|((s2)<<6)|((s1)<<5)|((s0)<<4)|((m)<<3)|((c)<<2)) |
| 2362 | #define SMC(s3,s2,s1,s0,m,ci) (s3*A10_ALUS3 + s2*A10_ALUS2 + s1*A10_ALUS1 + s0*A10_ALUS0 + m*A10_ALUM + ci*A10_ALUCI) |
| 2351 | 2363 | |
| 2352 | 2364 | /** |
| 2353 | | * @brief Compute the 74181 ALU operation smc |
| 2365 | * @brief Compute the 74181 ALU operation smc for inputs a and b |
| 2366 | * |
| 2367 | * The function, arithmetic / logic flag and carry in define the |
| 2368 | * ALU operation. The carry in is irrelevant for the logic operations. |
| 2369 | * The result is 17 bit, where bit #16 is the carry out. |
| 2370 | * |
| 2354 | 2371 | * @param smc S function [0-15], M arithmetic/logic flag, C carry |
| 2355 | 2372 | * @return resulting ALU output |
| 2356 | 2373 | */ |
| 2357 | | UINT32 alto2_cpu_device::alu_74181(UINT32 smc) |
| 2374 | UINT32 alto2_cpu_device::alu_74181(UINT32 a, UINT32 b, UINT8 smc) |
| 2358 | 2375 | { |
| 2359 | | register UINT32 a = m_bus; |
| 2360 | | register UINT32 b = m_t; |
| 2361 | | register UINT32 s = 0; |
| 2362 | | register UINT32 f = 0; |
| 2376 | register UINT32 f; |
| 2377 | register const UINT32 cout = 1 << 16; |
| 2363 | 2378 | |
| 2364 | | switch (smc & SMC(1,1,1,1, 1, 1)) { |
| 2379 | switch (smc & A10_ALUIN) { |
| 2365 | 2380 | case SMC(0,0,0,0, 0, 0): // 0000: A + 1 |
| 2366 | 2381 | f = a + 1; |
| 2367 | 2382 | break; |
| r26263 | r26264 | |
| 2370 | 2385 | f = a; |
| 2371 | 2386 | break; |
| 2372 | 2387 | |
| 2388 | case SMC(0,0,0,0, 1, 0): // 0000: A' |
| 2389 | case SMC(0,0,0,0, 1, 1): |
| 2390 | f = (~a) | cout; |
| 2391 | break; |
| 2392 | |
| 2373 | 2393 | case SMC(0,0,0,1, 0, 0): // 0001: (A | B) + 1 |
| 2374 | 2394 | f = (a | b) + 1; |
| 2375 | 2395 | break; |
| r26263 | r26264 | |
| 2378 | 2398 | f = a | b; |
| 2379 | 2399 | break; |
| 2380 | 2400 | |
| 2401 | case SMC(0,0,0,1, 1, 0): // 0001: A' | B' |
| 2402 | case SMC(0,0,0,1, 1, 1): |
| 2403 | f = (~a | ~b) | cout; |
| 2404 | break; |
| 2405 | |
| 2381 | 2406 | case SMC(0,0,1,0, 0, 0): // 0010: (A | B') + 1 |
| 2382 | 2407 | f = (a | ~b) + 1; |
| 2383 | 2408 | break; |
| r26263 | r26264 | |
| 2386 | 2411 | f = a | ~b; |
| 2387 | 2412 | break; |
| 2388 | 2413 | |
| 2414 | case SMC(0,0,1,0, 1, 0): // 0010: A' & B |
| 2415 | case SMC(0,0,1,0, 1, 1): |
| 2416 | f = (~a & b) | cout; |
| 2417 | break; |
| 2418 | |
| 2389 | 2419 | case SMC(0,0,1,1, 0, 0): // 0011: -1 + 1 |
| 2390 | | s = 1; |
| 2391 | | f = -1 + 1; |
| 2420 | f = (-1 + 1) | cout; |
| 2392 | 2421 | break; |
| 2393 | 2422 | |
| 2394 | 2423 | case SMC(0,0,1,1, 0, 1): // 0011: -1 |
| 2395 | | s = 1; |
| 2396 | | f = -1; |
| 2424 | f = (-1) | cout; |
| 2397 | 2425 | break; |
| 2398 | 2426 | |
| 2427 | case SMC(0,0,1,1, 1, 0): // 0011: logic 0 |
| 2428 | case SMC(0,0,1,1, 1, 1): |
| 2429 | f = cout; |
| 2430 | break; |
| 2431 | |
| 2399 | 2432 | case SMC(0,1,0,0, 0, 0): // 0100: A + (A & B') + 1 |
| 2400 | 2433 | f = a + (a & ~b) + 1; |
| 2401 | 2434 | break; |
| r26263 | r26264 | |
| 2404 | 2437 | f = a + (a & ~b); |
| 2405 | 2438 | break; |
| 2406 | 2439 | |
| 2440 | case SMC(0,1,0,0, 1, 0): // 0100: (A & B)' |
| 2441 | case SMC(0,1,0,0, 1, 1): |
| 2442 | f = ~(a & b) | cout; |
| 2443 | break; |
| 2444 | |
| 2407 | 2445 | case SMC(0,1,0,1, 0, 0): // 0101: (A | B) + (A & B') + 1 |
| 2408 | 2446 | f = (a | b) + (a & ~b) + 1; |
| 2409 | 2447 | break; |
| r26263 | r26264 | |
| 2412 | 2450 | f = (a | b) + (a & ~b); |
| 2413 | 2451 | break; |
| 2414 | 2452 | |
| 2453 | case SMC(0,1,0,1, 1, 0): // 0101: B' |
| 2454 | case SMC(0,1,0,1, 1, 1): |
| 2455 | f = (~b) | cout; |
| 2456 | break; |
| 2457 | |
| 2415 | 2458 | case SMC(0,1,1,0, 0, 0): // 0110: A - B - 1 + 1 |
| 2416 | | s = 1; |
| 2417 | | f = a - b - 1 + 1; |
| 2459 | f = (a - b - 1 + 1) ^ cout; |
| 2418 | 2460 | break; |
| 2419 | 2461 | |
| 2420 | 2462 | case SMC(0,1,1,0, 0, 1): // 0110: A - B - 1 |
| 2421 | | s = 1; |
| 2422 | | f = a - b - 1; |
| 2463 | f = (a - b - 1) ^ cout; |
| 2423 | 2464 | break; |
| 2424 | 2465 | |
| 2466 | case SMC(0,1,1,0, 1, 0): // 0110: A ^ B |
| 2467 | case SMC(0,1,1,0, 1, 1): |
| 2468 | f = (a ^ b) | cout; |
| 2469 | break; |
| 2470 | |
| 2425 | 2471 | case SMC(0,1,1,1, 0, 0): // 0111: (A & B) - 1 + 1 |
| 2426 | | s = 1; |
| 2427 | | f = (a & b) - 1 + 1; |
| 2472 | f = ((a & b) - 1 + 1) ^ cout; |
| 2428 | 2473 | break; |
| 2429 | 2474 | |
| 2430 | 2475 | case SMC(0,1,1,1, 0, 1): // 0111: (A & B) - 1 |
| 2431 | | s = 1; |
| 2432 | | f = (a & b) - 1; |
| 2476 | f = ((a & b) - 1) ^ cout; |
| 2433 | 2477 | break; |
| 2434 | 2478 | |
| 2479 | case SMC(0,1,1,1, 1, 0): // 0111: A & B' |
| 2480 | case SMC(0,1,1,1, 1, 1): |
| 2481 | f = (a & ~b) | cout; |
| 2482 | break; |
| 2483 | |
| 2435 | 2484 | case SMC(1,0,0,0, 0, 0): // 1000: A + (A & B) + 1 |
| 2436 | 2485 | f = a + (a & b) + 1; |
| 2437 | 2486 | break; |
| r26263 | r26264 | |
| 2440 | 2489 | f = a + (a & b); |
| 2441 | 2490 | break; |
| 2442 | 2491 | |
| 2492 | case SMC(1,0,0,0, 1, 0): // 1000: A' | B |
| 2493 | case SMC(1,0,0,0, 1, 1): |
| 2494 | f = (~a | b) | cout; |
| 2495 | break; |
| 2496 | |
| 2443 | 2497 | case SMC(1,0,0,1, 0, 0): // 1001: A + B + 1 |
| 2444 | 2498 | f = a + b + 1; |
| 2445 | 2499 | break; |
| r26263 | r26264 | |
| 2448 | 2502 | f = a + b; |
| 2449 | 2503 | break; |
| 2450 | 2504 | |
| 2505 | case SMC(1,0,0,1, 1, 0): // 1001: A' ^ B' |
| 2506 | case SMC(1,0,0,1, 1, 1): |
| 2507 | f = (~a ^ ~b) | cout; |
| 2508 | break; |
| 2509 | |
| 2451 | 2510 | case SMC(1,0,1,0, 0, 0): // 1010: (A | B') + (A & B) + 1 |
| 2452 | 2511 | f = (a | ~b) + (a & b) + 1; |
| 2453 | 2512 | break; |
| r26263 | r26264 | |
| 2456 | 2515 | f = (a | ~b) + (a & b); |
| 2457 | 2516 | break; |
| 2458 | 2517 | |
| 2518 | case SMC(1,0,1,0, 1, 0): // 1010: B |
| 2519 | case SMC(1,0,1,0, 1, 1): |
| 2520 | f = (b) | cout; |
| 2521 | break; |
| 2522 | |
| 2459 | 2523 | case SMC(1,0,1,1, 0, 0): // 1011: (A & B) - 1 + 1 |
| 2460 | | s = 1; |
| 2461 | | f = (a & b) - 1 + 1; |
| 2524 | f = ((a & b) - 1 + 1) ^ cout; |
| 2462 | 2525 | break; |
| 2463 | 2526 | |
| 2464 | 2527 | case SMC(1,0,1,1, 0, 1): // 1011: (A & B) - 1 |
| 2465 | | s = 1; |
| 2466 | | f = (a & b) - 1; |
| 2528 | f = ((a & b) - 1) ^ cout; |
| 2467 | 2529 | break; |
| 2468 | 2530 | |
| 2531 | case SMC(1,0,1,1, 1, 0): // 1011: A & B |
| 2532 | case SMC(1,0,1,1, 1, 1): |
| 2533 | f = (a & b) | cout; |
| 2534 | break; |
| 2535 | |
| 2469 | 2536 | case SMC(1,1,0,0, 0, 0): // 1100: A + A + 1 |
| 2470 | 2537 | f = a + a + 1; |
| 2471 | 2538 | break; |
| r26263 | r26264 | |
| 2474 | 2541 | f = a + a; |
| 2475 | 2542 | break; |
| 2476 | 2543 | |
| 2544 | case SMC(1,1,0,0, 1, 0): // 1100: logic 1 |
| 2545 | case SMC(1,1,0,0, 1, 1): |
| 2546 | f = (~0) | cout; |
| 2547 | break; |
| 2548 | |
| 2477 | 2549 | case SMC(1,1,0,1, 0, 0): // 1101: (A | B) + A + 1 |
| 2478 | 2550 | f = (a | b) + a + 1; |
| 2479 | 2551 | break; |
| r26263 | r26264 | |
| 2482 | 2554 | f = (a | b) + a; |
| 2483 | 2555 | break; |
| 2484 | 2556 | |
| 2557 | case SMC(1,1,0,1, 1, 0): // 1101: A | B' |
| 2558 | case SMC(1,1,0,1, 1, 1): |
| 2559 | f = (a | ~b) | cout; |
| 2560 | break; |
| 2561 | |
| 2485 | 2562 | case SMC(1,1,1,0, 0, 0): // 1110: (A | B') + A + 1 |
| 2486 | 2563 | f = (a | ~b) + a + 1; |
| 2487 | 2564 | break; |
| r26263 | r26264 | |
| 2490 | 2567 | f = (a | ~b) + a; |
| 2491 | 2568 | break; |
| 2492 | 2569 | |
| 2570 | case SMC(1,1,1,0, 1, 0): // 1110: A | B |
| 2571 | case SMC(1,1,1,0, 1, 1): |
| 2572 | f = (a | b) | cout; |
| 2573 | break; |
| 2574 | |
| 2493 | 2575 | case SMC(1,1,1,1, 0, 0): // 1111: A - 1 + 1 |
| 2494 | | s = 1; |
| 2495 | | f = a - 1 + 1; |
| 2576 | f = (a - 1 + 1) ^ cout; |
| 2496 | 2577 | break; |
| 2497 | 2578 | |
| 2498 | 2579 | case SMC(1,1,1,1, 0, 1): // 1111: A - 1 |
| 2499 | | s = 1; |
| 2500 | | f = a - 1; |
| 2580 | f = (a - 1) ^ cout; |
| 2501 | 2581 | break; |
| 2502 | 2582 | |
| 2503 | | case SMC(0,0,0,0, 1, 0): // 0000: A' |
| 2504 | | case SMC(0,0,0,0, 1, 1): |
| 2505 | | f = ~a; |
| 2506 | | break; |
| 2507 | | |
| 2508 | | case SMC(0,0,0,1, 1, 0): // 0001: A' | B' |
| 2509 | | case SMC(0,0,0,1, 1, 1): |
| 2510 | | f = ~a | ~b; |
| 2511 | | break; |
| 2512 | | |
| 2513 | | case SMC(0,0,1,0, 1, 0): // 0010: A' & B |
| 2514 | | case SMC(0,0,1,0, 1, 1): |
| 2515 | | f = ~a & b; |
| 2516 | | break; |
| 2517 | | |
| 2518 | | case SMC(0,0,1,1, 1, 0): // 0011: logic 0 |
| 2519 | | case SMC(0,0,1,1, 1, 1): |
| 2520 | | f = 0; |
| 2521 | | break; |
| 2522 | | |
| 2523 | | case SMC(0,1,0,0, 1, 0): // 0100: (A & B)' |
| 2524 | | case SMC(0,1,0,0, 1, 1): |
| 2525 | | f = ~(a & b); |
| 2526 | | break; |
| 2527 | | |
| 2528 | | case SMC(0,1,0,1, 1, 0): // 0101: B' |
| 2529 | | case SMC(0,1,0,1, 1, 1): |
| 2530 | | f = ~b; |
| 2531 | | break; |
| 2532 | | |
| 2533 | | case SMC(0,1,1,0, 1, 0): // 0110: A ^ B |
| 2534 | | case SMC(0,1,1,0, 1, 1): |
| 2535 | | f = a ^ b; |
| 2536 | | break; |
| 2537 | | |
| 2538 | | case SMC(0,1,1,1, 1, 0): // 0111: A & B' |
| 2539 | | case SMC(0,1,1,1, 1, 1): |
| 2540 | | f = a & ~b; |
| 2541 | | break; |
| 2542 | | |
| 2543 | | case SMC(1,0,0,0, 1, 0): // 1000: A' | B |
| 2544 | | case SMC(1,0,0,0, 1, 1): |
| 2545 | | f = ~a | b; |
| 2546 | | break; |
| 2547 | | |
| 2548 | | case SMC(1,0,0,1, 1, 0): // 1001: A' ^ B' |
| 2549 | | case SMC(1,0,0,1, 1, 1): |
| 2550 | | f = ~a ^ ~b; |
| 2551 | | break; |
| 2552 | | |
| 2553 | | case SMC(1,0,1,0, 1, 0): // 1010: B |
| 2554 | | case SMC(1,0,1,0, 1, 1): |
| 2555 | | f = b; |
| 2556 | | break; |
| 2557 | | |
| 2558 | | case SMC(1,0,1,1, 1, 0): // 1011: A & B |
| 2559 | | case SMC(1,0,1,1, 1, 1): |
| 2560 | | f = a & b; |
| 2561 | | break; |
| 2562 | | |
| 2563 | | case SMC(1,1,0,0, 1, 0): // 1100: logic 1 |
| 2564 | | case SMC(1,1,0,0, 1, 1): |
| 2565 | | f = ~0; |
| 2566 | | break; |
| 2567 | | |
| 2568 | | case SMC(1,1,0,1, 1, 0): // 1101: A | B' |
| 2569 | | case SMC(1,1,0,1, 1, 1): |
| 2570 | | f = a | ~b; |
| 2571 | | break; |
| 2572 | | |
| 2573 | | case SMC(1,1,1,0, 1, 0): // 1110: A | B |
| 2574 | | case SMC(1,1,1,0, 1, 1): |
| 2575 | | f = a | b; |
| 2576 | | break; |
| 2577 | | |
| 2578 | 2583 | case SMC(1,1,1,1, 1, 0): // 1111: A |
| 2579 | 2584 | case SMC(1,1,1,1, 1, 1): |
| 2580 | | f = a; |
| 2585 | f = (a) | cout; |
| 2581 | 2586 | break; |
| 2582 | 2587 | } |
| 2583 | | if (smc & 2) { |
| 2584 | | m_aluc0 = ((f >> 16) ^ s) & 1; |
| 2585 | | } else { |
| 2586 | | m_aluc0 = 1; |
| 2587 | | } |
| 2588 | 2588 | return f; |
| 2589 | 2589 | } |
| 2590 | 2590 | #endif |
| 2591 | 2591 | |
| 2592 | 2592 | /** @brief flag that tells whether to load the T register from BUS or ALU */ |
| 2593 | | #define TSELECT (1 << 1) |
| 2593 | #define TSELECT A10_TSELECT |
| 2594 | 2594 | |
| 2595 | 2595 | /** @brief flag that tells wheter operation was 0: logic (M=1) or 1: arithmetic (M=0) */ |
| 2596 | | #define ALUM2 (1 << 3) |
| 2596 | #define ALUM2 A10_ALUM |
| 2597 | 2597 | |
| 2598 | 2598 | /** @brief execute the CPU for at most nsecs nano seconds */ |
| 2599 | 2599 | void alto2_cpu_device::execute_run() |
| r26263 | r26264 | |
| 2603 | 2603 | |
| 2604 | 2604 | do { |
| 2605 | 2605 | int do_bs, flags; |
| 2606 | | UINT32 alu; |
| 2607 | 2606 | |
| 2608 | 2607 | /* |
| 2609 | 2608 | * Subtract the microcycle time from the display time accu. |
| r26263 | r26264 | |
| 2734 | 2733 | // B4: ALUS0' B5: ALUS1' B6: ALUS2' B7: ALUS3' |
| 2735 | 2734 | // B3-B7 are inverted on loading the PROM |
| 2736 | 2735 | UINT8 a10 = m_alu_a10[(m_emu.skip << 4) | aluf]; |
| 2737 | | alu = alu_74181(a10); |
| 2736 | UINT32 alu = alu_74181(m_bus, m_t, a10); |
| 2737 | m_aluc0 = (alu >> 16) & 1; |
| 2738 | 2738 | flags = (a10 ^ ALUM2) & (TSELECT | ALUM2); |
| 2739 | m_alu = static_cast<UINT16>(alu); |
| 2739 | 2740 | #else |
| 2741 | UINT32 alu; |
| 2740 | 2742 | /* compute the ALU function */ |
| 2741 | 2743 | switch (aluf) { |
| 2742 | 2744 | /** |
| r26263 | r26264 | |
| 2924 | 2926 | /** |
| 2925 | 2927 | * 16: ALU ← BUS |
| 2926 | 2928 | * PROM data for S3-0:1111 M:1 C:0 T:1 |
| 2927 | | * 74181 perhaps F=0 (0011/0/0) |
| 2928 | | * T source is BUS |
| 2929 | * 74181 function F=A |
| 2930 | * T source is ALU |
| 2929 | 2931 | */ |
| 2930 | 2932 | case aluf_undef_16: |
| 2931 | 2933 | alu = m_bus; |
| r26263 | r26264 | |
| 2937 | 2939 | /** |
| 2938 | 2940 | * 17: ALU ← BUS |
| 2939 | 2941 | * PROM data for S3-0:1111 M:1 C:0 T:1 |
| 2940 | | * 74181 perhaps F=~0 (0011/0/1) |
| 2941 | | * T source is BUS |
| 2942 | * 74181 function F=A |
| 2943 | * T source is ALU |
| 2942 | 2944 | */ |
| 2943 | 2945 | case aluf_undef_17: |
| 2944 | 2946 | default: |
| r26263 | r26264 | |
| 2947 | 2949 | flags = TSELECT; |
| 2948 | 2950 | LOG((LOG_CPU,0," ALU← 0 (illegal aluf in task %s, mpc:%05o aluf:%02o)\n", task_name(m_task), m_mpc, aluf)); |
| 2949 | 2951 | } |
| 2952 | m_alu = static_cast<UINT16>(alu); |
| 2950 | 2953 | #endif |
| 2951 | | m_alu = static_cast<UINT16>(alu); |
| 2952 | 2954 | |
| 2953 | 2955 | /* WRTRAM now, before L is changed */ |
| 2954 | 2956 | if (m_wrtram_flag) |