I am hesitant to call it a big because it isn't a bug unless it does something the developer didn't intend... but the behaviour seems different to real physical CPCs... of course being an emulator, it is uncommon to be 100% in every way.
TThe Behaviour and RAM test program in basic is here
https://www.cpcwiki.eu/forum/amstrad-cpc-hardware/problems-with-4-mb-ram-expansion-may-happen-to-you-too-please-read!/
WinAPE consistently gives back different available banks than a real CPC.
Is WinAPE incorrectly shadowing certain banks of RAM?
Does it work if you only check the 7Fxx range?
I ask because the last 2MB can be problematic under certain hardware configurations, so blindly OUTing to 7Bxx, 7A, 79xx or 78xx may be triggering unintended behaviour (especially on a emulator where it is more likely emulating esoteric hardware expansions)
See https://www.cpcwiki.eu/index.php/Standard_Memory_Expansions for a description of the issue.
I can configure just 6128 plus without more than 128k ram and run the test and it behaves differently than a real 6128 plus without extra ram. Likewose if i configure as a 664 with extra ram. It shouldn't matter what I out to if is to be as close to real hardware as possible then it should give the same results as real hardware. Just my view...
I get consistent results on the real cpc no matter 664 or 6128 plus with real dkrronics 256k rams or 256k silicon discs on the 664 or with Gemini on 6128 plus/664.
I didn't try my old dktronics on the 6128plus because a bit of a pain to connect without the right cabling.
As I wrote last un the other thread "no matter what i try, in winape, i cannot detect in 6128 configuration blocks at c4, c5, c6, and c7 - for some reason they are at fc, fd, fe, ff. Yet 128k software runs. hmm, seems something in my memory test logic that breaks WinAPE but not a real CPC. "
What I mean is, the test maybe triggering hardware emulated by WinAPE that you don't have on your physical CPC and it *might* influence the result.
The IO address space used by > 2MB RAM expansion can clash with non-RAM hardware (another reason I've never really been a fan of them) so by testing the whole 4MB you may be getting other weirdness. What does the test do if you only check the standard 512K expansion range? Does it still differ between WinAPE and a real machine?
Quote from: andycadley on 16:17, 03 November 23What I mean is, the test maybe triggering hardware emulated by WinAPE that you don't have on your physical CPC and it *might* influence the result.
The IO address space used by > 2MB RAM expansion can clash with non-RAM hardware (another reason I've never really been a fan of them) so by testing the whole 4MB you may be getting other weirdness. What does the test do if you only check the standard 512K expansion range? Does it still differ between WinAPE and a real machine?
I will test that, but you'd think if a hardware is not enabled in an emulator it should be effectively not there.
Quote from: zhulien on 17:03, 03 November 23Quote from: andycadley on 16:17, 03 November 23What I mean is, the test maybe triggering hardware emulated by WinAPE that you don't have on your physical CPC and it *might* influence the result.
The IO address space used by > 2MB RAM expansion can clash with non-RAM hardware (another reason I've never really been a fan of them) so by testing the whole 4MB you may be getting other weirdness. What does the test do if you only check the standard 512K expansion range? Does it still differ between WinAPE and a real machine?
I will test that, but you'd think if a hardware is not enabled in an emulator it should be effectively not there.
The RAM expansion won't be there, but other devices that aren't RAM expansions but can conflict with them might be. For example the FDC will still be present on a disk machine.
verified that CPCEmu works 100% in all configurations up to 512k that i can test, note you cannot turn individually on/off the silicon disc and ram - it assumes if you want a silicon disc the ram is there
verified that even only checking the 7fxx ranges, WinApe gives the wrong port bank/block numbers as described above.
Change lines 130 and 270 from:
FOR high%=&78 TO &7F
to:
FOR high%=&7F TO &7F
If you forcefully want to only check the 7F banks. Not sure if these are really official because only a 3rd parties created a RAM expansion but at least consistent with Amstrad produced 128K machines for 64k of it.
10 blocks%=0:m$="":GOSUB 60
20 '
30 PRINT:PRINT blocks%;"x 16KB blocks of extra RAM totalling ";:PRINT ram%;"KB"
31 PRINT m$
40 END
50 '
60 REM RAM Test
70 '
80 OUT &7F00,&C0:POKE &4000,&EE:POKE &4001,&EE:POKE &4002,&EE
90 '
100 t=TIME:ram%=0
110 PRINT"pass 1";:PRINT"..."
120 counter%=0
130 FOR high%=&78 TO &7F
140 port = high%*256
150 RESTORE
160 FOR i%=1 TO 32 STEP 4
170 READ low%,low2%,low3%,low4%
180 OUT port,low%:POKE &4000,low%:POKE &4001,high%:POKE &4002,counter%
190 counter%=counter%+1
200 NEXT
210 NEXT
220 '
230 OUT &7F00,&C0:POKE &4000,&EE:POKE &4001,&EE:POKE &4002,&EE
240 '
250 PRINT"pass 2";:PRINT"..."
260 counter%=0
270 FOR high%=&78 TO &7F
280 port = high%*256
290 RESTORE
300 FOR i%=1 TO 32 STEP 4
310 READ low%, low2%, low3%, low4%
320 OUT &7F00,&C0:main%=PEEK(&4000)
330 OUT port,low%:lowtest%=PEEK(&4000):hightest%=PEEK(&4001):countertest%=PEEK(&4002)
340 IF hightest%=high% AND lowtest%=low% AND countertest%=counter% AND main%=&EE THEN ELSE 430
350 ram%=ram%+64:blocks%=blocks%+4
360 m$=m$+"Y"
380 PRINT HEX$(high%)+HEX$(low%)+" ";
390 PRINT HEX$(high%)+HEX$(low2%)+" ";
400 PRINT HEX$(high%)+HEX$(low3%)+" ";
410 PRINT HEX$(high%)+HEX$(low4%)+" ";
420 GOTO 450
430 REM else
440 m$=m$+"N"
450 REM endif
460 counter%=counter%+1
470 NEXT
480 NEXT
490 RETURN
500 DATA &C4,&C5,&C6,&C7
510 DATA &CC,&CD,&CE,&CF
520 DATA &D4,&D5,&D6,&D7
530 DATA &DC,&DD,&DE,&DF
540 DATA &E4,&E5,&E6,&E7
550 DATA &EC,&ED,&EE,&EF
560 DATA &F4,&F5,&F6,&F7
570 DATA &FC,&FD,&FE,&FF
I am positive it is correct because every platform works so far (that I have tested) except for WinApe.
Just tested X-Mem and Y-Mem and XY-Mem work too.
So... verified working 100%
- real CPC 664+any combinations of no extra RAM, X-Mem, Y-Mem, XY-Mem, Zaxon 4mb, 256k DkTronics RAM, 256k DkTronics Silicon Disc, Gemini 2Mb (in both modes) Symbiface 2
- real CPC 6128+any combinations of no extra RAM, X-Mem, Y-Mem, XY-Mem, Zaxon 4mb, 256k DkTronics RAM, 256k DkTronics Silicon Disc, Gemini 2Mb (in both modes) Symbiface 2
- real 6128 Plus+any combinations of no extra RAM, X-Mem, Y-Mem, XY-Mem, Zaxon 4mb, 256k DkTronics RAM, 256k DkTronics Silicon Disc, Gemini 2Mb (in both modes)
- CPCEmu with 64k, 128k, 320k (RAM only), 576k (RAM+Silicon Disc)
verified not working as expected:
- WInApe v2.0 Beta
- CPCBox (same result as WinApe) https://www.retroshowcase.gr/cpcbox-master/index.html
Not tested because a bit of a pain to setup, I would be surprised if any of them failed:
- real CPC464
- Zaxon Just128k (CPC clone)
- Zaxon JustCPC4ATX (CPC clone)
- Terasic T-Rex (FPGA CPC)
- BB-CPC (emulator)
Quote from: zhulien on 13:00, 03 November 23Is WinAPE incorrectly shadowing certain banks of RAM?
That's not always incorrect and may happen with other memory expansions as well.
IIRC I had shadow ram banks with my old 256K Dobbertin RAM expansion, too. From my experience you should just expect such a behaviour.
You have to start writing the test values to the highest ram bank first and then walk down to the lowest. In this case shadow banks won't confuse your detection routine.
I'm not sure it should be walking up or down. In reality I should be able to test randomly any block at any time and I would expect a block to not interfere with another block that is not paged in.
In any case seems all thr real hardware j have tested works 100%, but those 2 emulators don't. They are supposed to be emulating the hardware, you don't write software usually to satisfy inacurate emulation.
Quote from: zhulien on 12:46, 05 November 23I'm not sure it should be walking up or down. In reality I should be able to test randomly any block at any time and I would expect a block to not interfere with another block that is not paged in.
In any case seems all thr real hardware j have tested works 100%, but those 2 emulators don't. They are supposed to be emulating the hardware, you don't write software usually to satisfy inacurate emulation.
My real 6128 behaves exactly like WinApe.
if I type...
10 OUT &7F00,&C4
20 POKE &4000,&C4
30 OUT &7F00,&F4
40 POKE &4000,&F4
50 OUT &7F00,&C4
60 PRINT HEX$(PEEK(&4000))
70 OUT &7F00,&F4
80 PRINT HEX$(PEEK(&4000))
I get...
F4
F4
So BANK 1 (#C4-#C7) is mirrored to BANK 7 (#F4-#F7) as well on an original 6128 without memory expansion. WinApe does the emulation 100% correctly in this case.
It may happen, that some memory expansions show random bytes, when you map in a non existing bank, no idea.
But at least the SYMBiFACE 3 (2MB ram expansion) is mirroring BANK 1-32 to BANK 33-64 as well (tested right now), which is the same behaviour like in WinApe.
On real hardware it is a fact, that existing banks may be mirrored to non-existing banks, and a good detection routine should consider this.
If you run the code I posted above on your real 6128 what do you get?
I am specifically writing each port into each bank, then writing to #c0 then reading each bank as well as #c0 and checking the bank had their port in it as well as #c0 having not changed also. I need to do this so u can detect all available ram using the said schemes with any holes that may exist in the map. It is perfectly valid for someone to make a 512k ram expansion sequential blocks if you are ignoring the complete 64k banking option.
On my real 128k machines they are consistent as I described and different to winape.
I guess if it is shadowed on some machines and not others then you ultimately can pick and choose which you use, however if it is not shadowed on other machines you will have no ram there.
Have you ever experienced, what "not shadowed/mirrored" means?
If you map non-existing banks on your real hardware, what is happening then?
Will you get corrupt ram without any stable read/write values...
- or will you see a mirrored bank?
Usually you will get the last one.
I didn't have time to transfer your basic prog to my real machine yet, will try to do it soon. Anyway I am using cpc memory detection routines since 1989 in great way, it was always working, so it will be interesting what is the difference in yours once beside the fact, that memory is mirrored usually.
On a unmodified 6128 bits 4-6 of port &7F00 are "unused" and the PAL simply doesn't decode them (D4-D6 are not connected to the PAL). So out &7f00,&c4 and out &7f00,&f4 have exactly the same meaning for a PAL.
That's also the behaviour I see in WinApe. When you activate a bank and you poke to &4000 a value, you will see that value at &4000 whatever bank you select (&c4, &cc,&d4,...,&fc).
Quick test in Winape:
10 DEFINT a-z
20 s=&C4:e=&FC
30 FOR i=e TO s STEP -8
40 OUT &7F00,i:POKE &4000,i
50 NEXT
60 FOR i=s TO e STEP 8
70 OUT &7F00,i
80 PRINT HEX$(i);" ";HEX$(PEEK(&4000))
90 NEXT
100 OUT &7F00,&C0
With 128K setup, it outputs the expected &c4 (which was poked last to &4000) in all banks, with a 576K setup, it outputs &c4-&fc in the respective banks (also expected).
Interesting in further investigation, I believe it is now the 6128 profile that WinAPE correctly emulates, but the 464 with extra RAM that is incorrect.
I didn't know about the 6128 shadowing and I can see where my code makes me think that, based on the last RAM i wrote to will come up on a 6128, but... it is still correct on my 464 and 664 with additional RAM - but incorrect in WinApe for a 464 with extra RAM.
WinAPE is assuming a 464 should behave as a 6128. I cannot confirm a 464Plus with Extra RAM as I don't have one - whether it behaves like a CPC464 with extra RAM or a 6128Plus.
Given the explanation, I'd imagine it's highly dependent on the exact make and model of RAM expansion you had plugged in. Any device that just copied the decoding scheme from the 128 will have shadowing, any that expect specific port values won't.
Although personally I'd just be tempted to check the 4MB, 2MB and 1MB limits and assume that if there is RAM there it covers the full address space up to that point. As I can't imagine there are many hardware options that don't and it's hard enough dealing with RAM in that range let alone worrying about holes.
I'd only worry about checking specific pages for memory if the total RAM is under 576K (i.e. it's an expansion compatible with the original DKtronics spec) since there it's plausible you might not have a contiguous 512K.
Quote from: andycadley on 11:28, 07 November 23Given the explanation, I'd imagine it's highly dependent on the exact make and model of RAM expansion you had plugged in. Any device that just copied the decoding scheme from the 128 will have shadowing, any that expect specific port values won't.
Although personally I'd just be tempted to check the 4MB, 2MB and 1MB limits and assume that if there is RAM there it covers the full address space up to that point. As I can't imagine there are many hardware options that don't and it's hard enough dealing with RAM in that range let alone worrying about holes.
I'd only worry about checking specific pages for memory if the total RAM is under 576K (i.e. it's an expansion compatible with the original DKtronics spec) since there it's plausible you might not have a contiguous 512K.
I totally agree, unfortunately I don't have access to a real DkTronics 64k RAM expansion (we could argue my 256K one is, because it was upgraded from 64k to 256k but I am not getting the behaviour of a 6128 with my 664 or 464 with the real DkTronics 256).
I guess I could argue that if someone's detection does give a shortage of 64k when adding sh*tloads then they still have sh*tloads :D
Is there any past documentation of fc, fd, fe, ff being remapped to dc, dd, de, df under any circumstances? I can see the 6128 shadowning behaviour but don't have the means to show this odd remapping with real hardware - only emulators.
Well Soft968 has bit 5 as *reserved* (and suggests you should send 0) and then bits 3 and 4 as being required to be 0 [I assume
@eto meant bits 3-5 since bit 6 is part of the GA function select]
Which doesn't entirely prove what was intended but does suggest memory management code really ought to have avoided other values (either because the hardware ignored them or because future machines may have applied different logic). If a physical 6128 ignores those bits, then an emulator should to. Would be interesting to see what a Plus machine does.
Its interesting the different detection logics we all have. Please continue posting them.
Quote from: andycadley on 15:29, 07 November 23[I assume eto (https://www.cpcwiki.eu/forum/profile/?u=3625) meant bits 3-5 since bit 6
:doh: sorry, sure!
Here are some SyMon (this app is included in SymbOS 4.0) screenshots, which show, which memory is available with different types of memory expansions. Just check the N/A areas.
This is in fact the same like we had with exactly these expansions in the 80ies/early 90ies.
CPC6128 with 128K:
symon-128k.png
CPC 464/664 with additional 256K:
symon-64+256k.png
CPC6128 with additional 256K:
symon-128+256k.png
(now you can see some unavailable banks/gaps, which are not existing resulting in gaps, but mirrored and still detected as not existing)
Any CPC (464/664/6128) with additional 512K:
symon-128 or 64+512k.png
Any CPC with 1MB (or more):
symon-1mb.png
The images didn't show, does symbos work on e.g. 664 with silicon disc?
no idea, why the images are gone, next try...
CPC6128 with 128K:
symon-128k.png
CPC 464/664 with additional 256K:
symon-64+256k.png
CPC6128 with additional 256K:
symon-128+256k.png
(now you can see some unavailable banks/gaps, which are not existing resulting in gaps, but mirrored and still detected as not existing)
Any CPC (464/664/6128) with additional 512K:
symon-128 or 64+512k.png
Any CPC with 1MB (or more):
symon-1mb.png
Quote from: zhulien on 01:28, 08 November 23The images didn't show, does symbos work on e.g. 664 with silicon disc?
The second screen shows this configuration, but I don't know, if the original silicon disc supports #C1 and #C2 on a 464/664?
I made another test with real hardware, and indeed it may happen, that non-existing banks are not mirrored but return random bytes. I guess this depends on the ram expansion hardware.
As an original unexpanded 6128 will mirror its second 64K to all non-existing banks, it is always the best way to consider, that banks may be either mirrored or return broken bytes.
WinApe is always mirroring banks. You may be right, when saying, that for special memory expansions this is not the correct behaviour. But a detection routine should always consider both behaviours, as both may happen on real hardware as well.
Quote from: zhulien on 20:12, 07 November 23Its interesting the different detection logics we all have. Please continue posting them.
Eto already posted a good one, here is another variant:
10 memory &3fff
20 for x=&fc to &c4 step -8
30 out &7f00,x:poke &4000,x
40 next
50 for x=0 to 7
60 out &7f00,&c4+x*8
70 print"Bank";x+1;"- ";
80 if peek(&4000)=&c4+x*8 then print"Available" else print"Not existing"
90 next
100 out &7f00,&c0
You may extend it for more 512K areas using &7exx, &7dxx etc.
The principle is always the same, start writing the test values to the most upper bank and walk down to the lowest, if you don't want to be confused by mirrored banks.
Eto's one uses a similar method to the Gemini one and the one I posted which was based on the Gemini one. It can detect exactly which blocks are available and not. I guess if its shadowed it doesn't matter which we use as long as it isn't assumed to be fixed always. I had seen some very simple 128 checks that do not much more than check for c4 and if present assume a 6128, I guess it is ok in reality as there isn't any real less than 64k expansions or expansions that aren't contiguous.
Now to think of how to check using this method but not permanently corrupt the ram... 256 byes maybe pushed to the stack...or in smaller groups that would never be shadowed to reduce stack usage... perhaps temporarily use video ram.