Close

Memory and Disassembly

A project log for The PCW Project

Doing things with an Amstrad PCW

james-otsJames Ots 10/16/2017 at 08:231 Comment

I tried to add an extra 512Kb of RAM to my PCW at the weekend. I used an as6c4008 static RAM chip to make things easy — no need to mess around with refresh signals or RAS and CAS and address decoding — and borrowed some VHDL code from my homebuilt Z80 project so that it would be switched in when a bank select command was sent requesting banks 32-63. I was hoping that this would be enough to make it work, but it doesn't seem to be. 

The documentation I'd seen said that the PCW will use the existing RAM if external RAM doesn't exist, but there's no mention of how to detect the external RAM. I wrote a small machine code programme which switches banks and copies data around, and the data I copy gets corrupted, which seems to indicate that the computer is writing and reading from my external RAM and the internal RAM at the same time.

I started disassembling CP/M (the J14CPM3.EMS file) to see if it could throw any light on the matter, and I think I've found the RAM detection code. Memory location 007F contains the number of 16Kb pages of memory in the system, so I just had to find where this location was written. I found one location, and it is preceded by a loop of bank switches and memory reads and writes, so it looks like it's the right bit of code. I haven't properly worked out the algorithm yet. However, I'd be surprised if there's any code which can tell the gate array not to access internal memory.

(There's also still quite a large chance that my VHDL code isn't quite right.)

As an interesting aside, I was intrigued by how J14CPM3.EMS copies itself into memory. The file is loaded into memory at 0000 and execution starts there too. It then switches banks and copies parts of itself into other locations in memory using LDIR. It also zeroes out some parts of memory using LDIR too. All pretty straightforward so far.

But then it comes to the weird part. There's a routine which copies 128 byte blocks of memory in reverse. It copies 128 bytes from SOURCE to DESTINATION, then it copies 128 bytes from SOURCE-128 to DESTINATION+128, then from SOURCE-256 to DESTINATION+256. At the moment I'm at a loss as to why it would do this. Actually, I'm still not quite sure I haven't misunderstood the code, because it seems such an odd thing to do.

Discussions

John Elliott wrote 12/10/2017 at 18:16 point

The parts that unpack backwards in 128-byte blocks are those parts that on a normal CP/M system would be in CPM3.SYS -- the BDOS and the BIOS. CPM3.SYS holds them in reverse so that CPMLDR can load the first record at the top of memory, the next just below it and so on.

  Are you sure? yes | no