Skip to content

Commit

Permalink
Fix #245 - MMU warn/error mode applies more reliably, checks ORG address
Browse files Browse the repository at this point in the history
new line, the ParseLine checking page for label definition did reset the
check and later emit of machine code did not warn/error about crossing
the boundary.

And now the third "ORG" address argument will warn where it is outside
of the range affected by paging (if you intentionally want that, just do
stand-alone ORG, don't mix it with MMU changing pages)
  • Loading branch information
ped7g committed Nov 28, 2024
1 parent 6e16cf4 commit 1f63f65
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/documentation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@
- ZX Next CSpect emulator v2.19.9.1: `break` opcode changed to `FD 00`
- fix: windows cmd.exe console state after running sjasmplus.exe
- Lua: minor version upgrade to 5.4.7 (from 5.4.6)
- minor bugfixes/improvements in specific edge cases
</synopsis>
</listitem>
</varlistentry>
Expand Down
14 changes: 10 additions & 4 deletions sjasm/devices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,10 @@ void CDevice::CheckPage(const ECheckPageLevel level) {
ErrorInt("No more memory pages to map next one into slot", previousSlotI, SUPPRESS);
// disable the option on the overflowing slot
prevS->Option = CDeviceSlot::O_NONE;
// reset error reporting even when level is CHECK_NO_EMIT, one error is enough
limitExceeded = false;
previousSlotI = i;
previousSlotOpt = S->Option;
break; // continue into next slot, don't wrap any more
}
if (realAddr != (prevS->Address + prevS->Size)) { // should be equal
Expand All @@ -443,10 +447,12 @@ void CDevice::CheckPage(const ECheckPageLevel level) {
}
break;
}
// refresh check slot settings
limitExceeded &= (previousSlotI == i); // reset limit flag if slot changed (in non check_reset mode)
previousSlotI = i;
previousSlotOpt = S->Option;
// refresh check slot settings (only in CHECK_EMIT case, otherwise ParseLine will reset it with CHECK_NO_EMIT at BoL!)
if (CHECK_EMIT == level) {
limitExceeded &= (previousSlotI == i); // reset limit flag if slot changed (in non check_reset mode)
previousSlotI = i;
previousSlotOpt = S->Option;
}
return;
}
Error("CheckPage(..): please, contact the author of this program.", nullptr, FATAL);
Expand Down
9 changes: 9 additions & 0 deletions sjasm/directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,15 @@ static void dirMMU() {
if (DISP_NONE != PseudoORG) {
WarningById(W_DISPLACED_ORG);
}
// check if explicit ORG address is outside of the slots affected by MMU, warn about it
const CDeviceSlot & check_s1 = *Device->GetSlot(slot1);
const CDeviceSlot & check_s2 = *Device->GetSlot(slot2);
if ((address < check_s1.Address) || (check_s2.Address + check_s2.Size <= address)) {
char buf[LINEMAX];
SPRINTF3(buf, LINEMAX, "[MMU] Requested ORG address 0x%04X is out of range 0x%04X..0x%04X",
address, check_s1.Address, check_s2.Address + check_s2.Size - 1);
Warning(buf);
}
}
Device->CheckPage(CDevice::CHECK_RESET);
}
Expand Down
24 changes: 24 additions & 0 deletions tests/devices/mmu.asm
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,27 @@ label3_p5: ld sp,"66" ; '166' ; last byte of page 5, first two bytes of pa
ASSERT 0x3456 == $ && 6 == $$
ENT
ASSERT 0x2345 == $ && 6 == $$

;-----------------------------------------------------------
; new part to verify bugfix for #245

; error option (guarding machine code write outside of current slot)
MMU 1 e, 5 : ASSERT {0x4000} == "55"
ORG 0x7FFF : ccf : ccf ; should be error, second `ccf` left the slot memory
ASSERT {0x8000} == "7?" ; but damage is done in the virtual memory, that's how it is

;-----------------------------------------------------------
; new part: third ORG argument will now warn when it's outside of slot range

MMU 0, 0, 0x3FFF
MMU 0, 0, 0x4000 ; warn
MMU 1, 5, 0x3FFF ; warn
MMU 1, 5, 0x4000
MMU 1, 5, 0x7FFF
MMU 1, 5, 0x8000 ; warn
MMU 1 2, 5, 0x3FFF ; warn
MMU 1 2, 5, 0x4000
MMU 1 2, 5, 0xBFFF
MMU 1 2, 5, 0xC000 ; warn
MMU 3, 7, 0xBFFF ; warn
MMU 3, 7, 0xC000
35 changes: 35 additions & 0 deletions tests/devices/mmu.lst
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ mmu.asm(109): error: Unexpected: ,
110 0000
111 0000 ; valid syntax with address -exercise different code-paths
112 0000 ORG 0x1234
mmu.asm(113): warning: [MMU] Requested ORG address 0x4000 is out of range 0x0000..0x3FFF
113 1234 MMU 0, 0, 0x4000
114 4000 ASSERT 0x4000 == $ && 6 == $$ && {0x0000} == "00" && {$} == "66"
mmu.asm(115): warning: value 0x12345 is truncated to 16bit value: 0x2345
Expand All @@ -198,6 +199,40 @@ mmu.asm(118): warning[displacedorg]: ORG-address set inside displaced block, the
122 3456 ENT
123 2345 ASSERT 0x2345 == $ && 6 == $$
124 2345
125 2345 ;-----------------------------------------------------------
126 2345 ; new part to verify bugfix for #245
127 2345
128 2345 ; error option (guarding machine code write outside of current slot)
129 2345 MMU 1 e, 5
129 2345 ASSERT {0x4000} == "55"
130 2345 ORG 0x7FFF
130 7FFF 3F ccf
mmu.asm(130): error: Write outside of memory slot: 32768
130 8000 3F ccf ; should be error, second `ccf` left the slot memory
131 8001 ASSERT {0x8000} == "7?" ; but damage is done in the virtual memory, that's how it is
132 8001
133 8001 ;-----------------------------------------------------------
134 8001 ; new part: third ORG argument will now warn when it's outside of slot range
135 8001
136 8001 MMU 0, 0, 0x3FFF
mmu.asm(137): warning: [MMU] Requested ORG address 0x4000 is out of range 0x0000..0x3FFF
137 3FFF MMU 0, 0, 0x4000 ; warn
mmu.asm(138): warning: [MMU] Requested ORG address 0x3FFF is out of range 0x4000..0x7FFF
138 4000 MMU 1, 5, 0x3FFF ; warn
139 3FFF MMU 1, 5, 0x4000
140 4000 MMU 1, 5, 0x7FFF
mmu.asm(141): warning: [MMU] Requested ORG address 0x8000 is out of range 0x4000..0x7FFF
141 7FFF MMU 1, 5, 0x8000 ; warn
mmu.asm(142): warning: [MMU] Requested ORG address 0x3FFF is out of range 0x4000..0xBFFF
142 8000 MMU 1 2, 5, 0x3FFF ; warn
143 3FFF MMU 1 2, 5, 0x4000
144 4000 MMU 1 2, 5, 0xBFFF
mmu.asm(145): warning: [MMU] Requested ORG address 0xC000 is out of range 0x4000..0xBFFF
145 BFFF MMU 1 2, 5, 0xC000 ; warn
mmu.asm(146): warning: [MMU] Requested ORG address 0xBFFF is out of range 0xC000..0xFFFF
146 C000 MMU 3, 7, 0xBFFF ; warn
147 BFFF MMU 3, 7, 0xC000
148 C000
# file closed: mmu.asm

Value Label
Expand Down

0 comments on commit 1f63f65

Please sign in to comment.