• Please review our updated Terms and Rules here

How can this be relocated?

alank2

Veteran Member
Joined
Aug 3, 2016
Messages
2,256
Location
USA
I've got a program that is a demo for the NEC PC-6001A. It is called substrike and has two components. The first is written in BASIC and it has a loader to load the second part. The first part is fine and easily dealt with, but the second part is the problem. It loads on a Z80 compatible CPU between 0xC400 and 0xDFFF. The problem is that I want to make it work from a floppy disk instead of loading from cassette. The computer has more memory and a floppy interface which double the memory to 32K, but unfortunately the way they designed it, the floppy uses the memory area 0xDA00-0xDFFF. With the RAM expansion I have 0x8400 through 0xD9FF available, but yet the program wants to load 0xC400-0xDFFF. To make it easy, I would just think of moving it from starting at 0xC400 to 0xB400. Could I just find all the CALL/JMP opcodes and change it possibly? I'm attaching it.
 

Attachments

  • substrike.zip
    7.1 KB · Views: 2
Maybe it doesn't need to be relocated. I wonder if I could load it into memory and then copy it into place and then execute it. I don't think that memory area would be used maybe.
 
Would changing the address in the BLOAD command in the BASIC program work? The BASIC quick reference shows that the load address can be appended to the command.
BLOAD PROG 1, &H100 is the example given though the scan shows the value as IOO which I think is mistake.
 
My current plan is to BLOAD it in at 0xA400 and then write a small assembly stub at 0xA300 that copies 0xA400 directly to 0xC400 for 7168 bytes and then executes it. Hopefully the extended basic won't touch that memory if it never gets control returned to it.
 
Here is my loading code - I"m sure you guys can improve it! It has an Z80 compatible, but I'm only familiar with 8080
Code:
A300                          .ORG   $a300   
A300   21 00 A4               LXI   h,$a400   
A303                LOOP:     
A303   46                     MOV   b,m   
A304   3E 20                  MVI   a,$20   
A306   84                     ADD   h   
A307   67                     MOV   h,a   
A308   70                     MOV   m,b   
A309   3E E0                  MVI   a,$e0   
A30B   84                     ADD   h   
A30C   67                     MOV   h,a   
A30D   23                     INX   h   
A30E   3E C0                  MVI   a,$c0   
A310   BC                     CMP   h   
A311   C2 03 A3               JNZ   loop   
A314   C3 00 C4               JMP   $c400
 
Oddly, it is working if I enter 0 files at startup up, but if I specify 2 files, then one of the boats you are trying to hit is corrupted in its graphics. My loader copies the full 7168 bytes in and directly executes it. I wouldn't think the extended basic would ever have control again at that point, so I find this odd. It may be possible for the game to call areas in the non-extended basic rom, but again, that wouldn't use the area in the upper 0xDxxx range.

Could there be an interrupt/vector taking control? This thing has ROM at 0x0000-0x3fff.
 
If it's a Z80 Compatable system, I'm just wondering if it's got something like LDIR or LDDR?

That's what I'd do on my system, so you can load the file somewhere else from Disk and use something like this:

LD HL,&<address of the code>
LD DE,&<where it needs to go>
LD BC,&<the length of it>
LDIR
RET
 
That is quite a bit easier than what I came up with!

Here it is, probably very few people in the world will be interested in it, but the cassette demo for the NEC PC-6001 modified for disk use on a system with 32K and extended BASIC. (Mode 4, Files 0, Pages 2). Files must be set to 0 for sub strike to work for some reason - I can only guess that some of the functions that the game uses still interact with that upper area of memory where the number of files you specify at reset matter.
 

Attachments

  • NEC PC-6001 Demo on Disk [m4 f0 p2].zip
    331 KB · Views: 1
I made a tool that can import/export files into a disk image now, so I've done some more testing on this. CP/M user your optimized Z80 memory copier works fine with the LDIR instruction.

I am still finding a mystery with the game though. On this system when it boots with the extended basic cartridge, it asks how many files you want. When I select 0, the game boots and runs fine. When I pick 2, some of the ships you are shooting at are corrupted. I believe this is because of the memory area shared by extended basic for floppy file access and the game. The game does not need or have knowledge of the extended basic cartridge which loads between 0x4000-0x7fff. Regular basic is at 0x0000-0x3fff. Normally basic uses another area of ram 0xfa00-0xffff, and I suspected that the number of files selected is stored here somewhere. I then attempted to load the 16K version of this fa00-ffff range using the same copy method I was using for the game. My thinking was that if the game calls out to the 0x0000-0x3fff rom basic for anything, it will see the fa00-ffff range as normal data for it and be content. This also did not work and I still have corrupt ships if I specify 2 for the number of files. What is baffling is that practically all of the memory that would be in the machine if it were 16K is essentially being copied to what a 16K machine would be. 0xc000-0xc3ff is text screen. 0xc400-0xdfff is the game copied in. 0xe000-0xf5ff is the extended graphics screen. 0xfa00-0xffff is the basic area also being copied in. Could there be another way it knows the number of files? I'd love to find out how to make the game work when one selects 2 for the number of files by overriding it somehow, but I am out of ideas.
 
Sorry I'm a bit confused because I'm not familiar with the OS the NEC uses. :(

Earlier when you said that you have 0x8400 to 0xD9FF available, I thought if it were possible to load the second file somewhere in that area, the LDIR could be used to MOVE it to 0xC400-0xDFFF area, though if other files need to be loaded, this could be a problem if the file occupies the area the OS resides. Though it sounds to me the OS has to know what files needs loading, it sounds similiar to a MSX, though MSXs have additional file handling commands. The routine I supplied is only 11 bytes in size, it should be ample space if it's possible to load the 2nd file to that free space area before moving it to 0xC400, the routine also needs to be executed, so whatever command BASIC has to execute Machine Code routine, once RET (&C9) is found, it returns back to where BASIC executed the command from.

The alternative would be a painstacking process of moving the location of that M/C, though depending on what tools are available a really good disassembler can generate dummy labels and then reassembled to the new locality (0x8400 ?).
 
Let me start at the beginning and try to fill in the context! :)

The NEC PC-6001 has BASIC as its OS with a built-in ROM at 0x0000-0x3fff. This BASIC (non-extended) doesn't know anything about floppy disks as it is intended for cassette use. The system uses an interesting, but odd set of graphics modes where you can specify the number of pages you want at startup. Standard 16K RAM is at 0xc000-0xffff. Page 1 is only a screen that only supports text mode typically at 0xc000-0xc3ff. Page 2 is a much more capable screen that supports text and graphics so its range is larger between 0xe000-0xf9ff. The area at 0xfa00-0xffff is used for internal storage of BASIC's state. It just happens that the graphics do not use the full range of 0xe000-0xffff so in this case there is 0x600 bytes available for basic at the end of it. The system does support more modes with more ram that carve out an entire 8K range for pages 3 and 4 with 0x600 bytes wasted at the top of each one.

Adding 16K more RAM goes into the 0x8000-0xbfff range and moves page 1 from 0xc000-0xc3ff to 0x8000-0x83ff. Page 2 stays where it is, and now pages 3 and 4 which are full graphics pages can be used as well. I am thinking they expected programs to draw a screen in the background while the user is viewing another in the foreground.

The extra memory doesn't really move that much, so the game from the demo, Sub strike, will still load and work from cassette. It is unusual in that is has two tape sections. The first is a basic program that shows instructions, plays a song, and then has a machine language loader it pokes into memory and executes. The machine language loader is short and likely calls a basic function to load data from tape as the tape drive is enabled and it then loads the second tape section into the memory area c400-dfff and executes it. This memory is available in the 16K version (its intended configuration) and it is also available in the 32K version where the game will load and run fine there as well. I have to assume that the game makes calls to the basic rom area (0x0000-0x3fff) because some of the things it does such as displaying text look exactly the same when you do them in basic, so while it is a machine language program, it makes calls to basic functions or parts of basic rom to do things it needs.

I want to load the game from disk. So I've replaced the game's loader with a BLOAD command and at the front of what is BLOADED is the loader which copies it into the correct regions after we no longer need basic to BLOAD anything.

Here is where the complication comes in. Adding the extended BASIC cartridge at 0x4000-0x7fff extends BASIC with many more commands. 95% of them are disk related, so I think of it more as disk basic than extended basic. One of the things it does however now at start up is ask how many files in addition to the how many pages question. Depending on what you answer, it allocates more room for open files. You can answer 0 to this and still load files from disk, so I am thinking this means open files in basic, but not the files you might want to load with basic commands. The issue here is that they decided to use RAM at the end of the user section, which if you select page=2 will be the area below 0xe000. It uses around 400-600 bytes even with 0 files selected and adds another 291 bytes for each file you specify. This is the real issue that extended basic now uses this area which the game also wants to use. My thinking was that the game itself only knows about non-extended basic and should only make calls to it, but likely something else causes regular basic to now also think it needs to use this area. Maybe they set a pointer up in the 0xfa00-0xffff range that even if one calls non-extended basic, it somehow ends up in extended basic code. This is the mystery.

If I specify 0 files, it works. if I specify 2 files, some of the ships graphics are corrupted, which makes sense as I think that area is the ships graphics. If I specify more files like 10, it seems to also work, but I suspect something is still being overwritten and it might fail if played long enough.

The goal was, even if the user specifies 2 files, can I undo or override that? What I've tried to do is copy a section into 0xfa00-0xffff from a "0 files extended configuration" or even a non extended 16K configuration. The way I did that was, copy the game into 0xc400-0xdfff, copy the basic memory into 0xfa00-0xffff, execute the game at 0xc400. The loader does not return to basic at all, just copy the two sections and execute. The game may make basic calls, but they should be non-extended ones and the basic config at 0xfa00 shouldn't know anything about files at 0xdfxx. The result is that when I copy the basic section in, it just restarts asking the how many files question, so basic doesn't like having its memory area copied in!

I am baffled as to why that question "how many files" seems to make a change outside of memory where I can't undo it.
 
In TRS-80 Disk BASIC, "how many files" creates that many file buffers. I suspect NEC is doing something similar. I don't have a memory map for the NEC so I can't be sure that Substrike is writing over a disk buffer which causes the crash.
 
krebizfan - it is definitely creating file buffers and it is absoutely sharing the same space as the game. I totally agree that that is the issue. Once the game is loaded though, it shouldn't need to use those file buffers any longer and the game shouldn't call any basic function that would need them. That is why I'm trying to solve - making it not use that area or corrupt that area once the game is copied in. My loader copies the game into that area and then directly executes it. I think where the issue is happening is that the game calls some BASIC functions (non extended, in the 0x0000-0x3fff) range which should be unaware of the disk buffers. Yet something still corrupts that area. Could there be a dma type of thing going on? I don't think so as the system uses an 8255 to talk to the floppy drive (which has its own cpu presumably). That is what I'm trying to figure out - how does the game get corrupted after I copy it in and start its execution. Is it when the game makes a call back to regular BASIC? Does regular BASIC use some sort of pointer in the 0xfa00-0xffff area to do something in the upper 0xdxxx area? That is what I find perplexing about this. I even replaced the entire upper basic area memory with a memory I saved from a non-extended 16K version and that did not help.
 
I'm not sure I can answer your questions correctly, I did a Google Search relating to the 'Number of Files?' on a NEC PC based system and found this page:

https://archive.org/details/Neo_Kobe_NEC_PC-6001_2016-02-25

In some plain text below the Manual Image. According to that when a Disk Drive is attached "Number of Files?" pops up, which will accept an input of 0,1 or 2.

It sounds like the more files you add, the more Memory is reserved, so perhaps the correct answer for the Space Game is 0?

There was also another question within the Plain Text from that Linked site asking 'How Many Pages', which is used to reserve the number of Screen Pages, though I have noticed this page relates to the PC-6001 and you're referring to the PC-6001A, how different those systems are I'm not prepared to guess after totally misunderstand an Atari 800 from an Atari 800XL on another forum!
 
It works with 0. What I'd like to do is find out how to make it work no matter what someone enters by adjusting the environment. That is what I've been unsuccessful with.

The A is the American version, they are almost identical.

The Neo Kobe page is a good one, essentially I'm trying to make a game work in Mode 4 that was written in Mode 1.

What I don't understand is that even if I replace essentially all the memory in a Mode 1 configuration with what it should have been in Mode 1, it still corrupts the ships.
 
It works with 0. What I'd like to do is find out how to make it work no matter what someone enters by adjusting the environment. That is what I've been unsuccessful with.

It sounds as if the question automatically appears when a disk system is automatically detected, I wonder if its possible to still use the disk operating system though disable the detection thing in order to disable the question. There maybe information about it in an disk operating system manual which would be in the form of an address that could be poked perhaps?
I'm not sure if your system would accept something in the form of: files=0 to let the system know there's no additional files to use. That was just something I remember seeing in a batch file.

The A is the American version, they are almost identical.

The Neo Kobe page is a good one, essentially I'm trying to make a game work in Mode 4 that was written in Mode 1.

What I don't understand is that even if I replace essentially all the memory in a Mode 1 configuration with what it should have been in Mode 1, it still corrupts the ships.
Are there any other unusual things which happen? What happens if you try playing the game out or does it become unplayable? Can the game return back to BASIC and if so, does the operating system function normally or does the machine freeze up (crash) or needs resetting to return back to normal?
 
Back
Top