| 703 | } |
| 704 | |
| 705 | void mem_write_cpu(uint32_t addr, uint8_t value) { |
| 706 | uint32_t ramAddr, select; |
| 707 | addr &= 0xFFFFFF; |
| 708 | |
| 709 | #ifdef DEBUG_SUPPORT |
| 710 | if ((debug.addr[addr] &= ~(DBG_INST_START_MARKER | DBG_INST_MARKER)) & DBG_MASK_WRITE) { |
| 711 | debug_open(DBG_WATCHPOINT_WRITE, addr); |
| 712 | } |
| 713 | #endif |
| 714 | |
| 715 | if (addr == control.stackLimit) { |
| 716 | control.protectionStatus |= 1; |
| 717 | gui_console_err_printf("[CEmu] NMI reset caused by writing to the stack limit at address %#06x. Hint: Probably a stack overflow (aka too much recursion).\n", addr); |
| 718 | cpu_nmi(); |
| 719 | } /* writes to stack limit succeed */ |
| 720 | |
| 721 | if (addr >= control.protectedStart && addr <= control.protectedEnd && unprivileged_code()) { |
| 722 | control.protectionStatus |= 2; |
| 723 | gui_console_err_printf("[CEmu] NMI reset caused by writing to protected memory (%#06x through %#06x) at address %#06x from unprivileged code.\n", control.protectedStart, control.protectedEnd, addr); |
| 724 | cpu_nmi(); |
| 725 | } else { /* writes to protected memory are ignored */ |
| 726 | switch((addr >> 20) & 0xF) { |
| 727 | /* FLASH */ |
| 728 | case 0x0: case 0x1: case 0x2: case 0x3: |
| 729 | case 0x4: case 0x5: case 0x6: case 0x7: |
| 730 | if (unprivileged_code()) { |
| 731 | control.protectionStatus |= 2; |
| 732 | gui_console_err_printf("[CEmu] NMI reset caused by writing to flash at address %#06x from unprivileged code. Hint: Possibly a null pointer dereference.\n", addr); |
| 733 | cpu_nmi(); |
| 734 | } else { |
| 735 | mem_write_flash(addr, value); |
| 736 | } |
| 737 | break; |
| 738 | |
| 739 | /* UNMAPPED/FLASH */ |
| 740 | case 0x8: case 0x9: case 0xA: case 0xB: |
| 741 | cpu.cycles += asic.serFlash ? flash_touch_cache(addr) : 258; |
| 742 | break; |
| 743 | |
| 744 | /* UNMAPPED */ |
| 745 | case 0xC: |
| 746 | cpu.cycles += asic.serFlash ? 2 : 258; |
| 747 | break; |
| 748 | |
| 749 | /* RAM */ |
| 750 | case 0xD: |
| 751 | sched_process_pending_dma(2); |
| 752 | ramAddr = addr & 0x7FFFF; |
| 753 | if (ramAddr < 0x65800) { |
| 754 | mem.ram.block[ramAddr] = value; |
| 755 | } |
| 756 | break; |
| 757 | |
| 758 | /* MMIO <-> Advanced Perphrial Bus */ |
| 759 | case 0xE: case 0xF: |
| 760 | #ifdef DEBUG_SUPPORT |
| 761 | if (debug_get_flags() & DBG_SOFT_COMMANDS) { |
| 762 | if (addr >= DBG_PORT_RANGE) { |
no test coverage detected