I recently added a few more features to JMON. The main one is a new iNfo command which displays information about the system it is running on. Here is sample output:
CPU TYPE: 65C02
CPU SPEED: 2.0 MHZ
RAM DETECTED FROM: $0000 TO $7FFF
NMI VECTOR: $0F00
RESET VECTOR: $FF00
IRQ/BRK VECTOR: $0100
ACI CARD: NOT PRESENT
CFFA1 CARD: NOT PRESENT
MULTI I/O CARD: PRESENT
BASIC ROM: PRESENT
KRUSADER ROM: PRESENT
WOZMON ROM: PRESENT
The way some of this information was generated is somewhat interesting. I'll explain a bit about how the code was implemented.
To determine the CPU type I used some code from the Western Design Center manual for the 65xx series processors. The code first distinguishes between 6502 and 65C02 processors by the behavior of the negative flag in decimal mode. The 65C02 fixed the behavior to make the flag valid (also V and C) while the 6502 did not. It then tries a 65816 instruction which will change the carry flag but is an unimplemented instruction and hence a NOP on the 65C02. From this it determines if it is running on a 6502, 65C02, or 65816 processor.
There are different manufacturers of 65C02. I don't know of any easy way to distinguish between a Rockwell and WDC 65C02. Thw only added instructions on the WDC are STP and WAI which both stop the CPU from running. They require either a reset or an interrupt to restart the CPU.
To find the range of RAM the code does the following. Starting from address zero, it in turn writes all ones, all zeroes, and alternating ones and zeroes to each memory location. If the same data is read back, it is considered RAM. The original data at the location is then written back to avoid corrupting what is in memory (namely, JMON). This is done until memory is found that cannot be written to and read back with the same data. I then stop, so the test only checks for contiguous RAM starting at zero.
A wrinkle is to avoid writing to the area of memory where the code itself is running since it would get corrupted in the middle of execution. I do this by avoiding testing the 256 byte page where the memory test code resides.
Next is the CPU speed. We want to determine the approximate clock speed of the CPU. But how, since we have no reference to actual time? The trick I used is to make use of a serial port, which is available when a Multi I/O board is present. If we send some characters out the serial port and see how many CPU cycles it takes, we can determine how fast the CPU is running since the serial port works at baud rates that are independent of the CPU clock speed. The code is calculated to give a value that is approximately the clock speed in megahertz to two significant figures.
For testing if certain ROMS are present, like the Krusader assembler, we can check the first few bytes for known data.
For expansion cards, like the CFFA1, they may have ID bytes in hardware (the CFFA1 does) or we can look at the hardware registers like the 6551 on the Multi I/O board and check for behavior of the registers, such as specific bits that can or can't be changed. I wrote tests for the cards that I have, the CFFA1 flash card, Multi I/O card, and ACI Apple Cassette Interface (the latter I don't yet have).
I tested the new info command with 6502, 65C02, and 65816 processors and 1 MHz and 2 MHz crystal oscillators. I also tested it on the POM1 emulator. A screenshot under POM1 is shown below.
Info Command Running on the POM1 Emulator |
With these changes I am running out of features to add to JMON so I am considering it to be feature complete and calling it version 1.0.
I noticed it recently exceeded 8K in size, so it no longer fits in a single 8K EPROM. I could reduce it to under 8K by disabling some features. The disassembler has some reasonably large tables (which the assembler also uses).
No comments:
Post a Comment