I decided to do a minor upgrade to My CP/M (Version 1).
Swap RST6.5 for RST7.5 and increase the FRAM disk capacity from 32k to 256k.
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
ATMEGA1284_UserGuide.pdfAdobe Portable Document Format - 1.15 MB - 07/19/2020 at 04:20 |
|
|
MS_CPM_Prog_Ref2.jpgJPEG Image - 374.91 kB - 07/19/2020 at 04:20 |
|
|
MS_CPM_Prog_Ref1.jpgJPEG Image - 390.55 kB - 07/19/2020 at 04:20 |
|
|
MS_CPM_Prog_Ref4.jpgJPEG Image - 246.80 kB - 07/19/2020 at 04:20 |
|
|
MS_CPM_Prog_Ref3.jpgJPEG Image - 376.63 kB - 07/19/2020 at 04:20 |
|
|
Finally
I worked my way through Grant Searle's CBIOS and compared it to my CBIOS. I found a two disk set up errors but the main problem was not copying CP/M properly upon a Warm Boot. All fixed and CP/M now works properly.
I also redesigned my Flash ROM Programmer so I can upload a single (large) HEX8-16 file to the Flash ROM (i.e. W29C020). This save a huge amount of time over the old Flash ROM Programmer which uploaded just 16kb blocks in firmware.
Here is the happy MyCP/M V2 and the Flash ROM Programmer:
AlanX
Unlocking the Boot Block
Finally found out how to unlock the Boot Block on the Flash Chip. It's undocumented but:
instead of:
[0x0000]=0x00
as used in the Boot Block lock sequence (documented), its:
[0x2AAA]=0xAA
This unlocks both the lower and upper boot blocks.
I16HEX
I8HEX can be upgraded to I16HEX by added the segment prefix record code (0x02).
Done.
CP/M EMU
Need to update my CP/M emulator of I16HEX as the Flash Disk is more than 64k.
Still working on this, getting close. Found a precedence error:
ROM[PAGE*0x8000+addr&0x7fff][DISK];
Must be:
ROM[PAGE*0x8000+(addr&0x7fff)][DISK];
Working better but TYPE only lists 128b of a 254b file?
Loading Some Files Crashes CP/M
I need it to work out why CP/M crashed when I exit some (larger) but not all (generally smaller) programs.
Solved (I think). The faulty logic is that directory record size is 128b (as per Internet directory format documentation). For a 2048b block, it should be 256b per record. My directory calculations are based on 128b per record. This made CP/M load twice the required disk data, over-writing CCP. Or at least I think so, I will fine out tomorrow.
My TEST.COM program works but upon return HALTS the emulator:
$ ./myCPM_EMU
my CP/M EMU Console - Written by Alan Cooper (AlanCooper@StartMail.com)
my CP/M 2.2 V1A
A>B:
B>DIR
B: CC COM : CC COM : CC MSG : AS COM
B: LN COM : C LIB : C LIB : M LIB
B: STDIO H : MATH H : COMPILE TXT : TEST C
B: TEST COM
B>TYPE TEST.C
#include "stdio.h"
#include "math.h"
main()
{
char buf[80];
float r;
printf("please enter your name: ");
gets(buf);
r=sqrt(1.1);
printf("hello, %s, %f welcome to the growing community of Aztec C users\n", buf,r);
}
B>TEST
please enter your name: AlanX
hello, AlanX, 1.048798 welcome to the growing community of Aztec C users
my CP/M 2.2 V1A
8085 halted
$
So an improvement but CCP is still being trashed(?).
Reloaded all the Flash Disks and ran the machine.
Still the same "my CPM 2.2 V1A" loop. I can run 8k program and return safely but not my 14k TEST program. I must be double loading (28k) and wiping out CCP. Must be something I have to change somewhere.
I can't work it out! Spent a whole day on this. Thinking I should go back to 1kb blocks.
My CP/M V2
The board is ready and I have the components. For version 2 I am still using software serial but RAM is increased to 56kb (enough for the C compiler) and the Flash disk capacity is increased to 512kb (e.i. W29C040-90B).
New Flash ROM Programmer
Need to design a new flash ROM programmer using a MEGA 2560.
AlanX
Going the Next Level Up
I was brought up on Turbo Pascal V3 and it is available for CP/M-80. But no, it is for the Z80 (or at least the one I tried did not work).
Okay, a C compiler would be pretty cool. First compilers of the CP/M era are generally K&R (not ansi) which means the syntax (of the function definition) is not the same as modern compilers. So every modern C program will need to be modified.
Next, many of the compilers are short integer and offer floating point as an add-on (i.e. the professional version).
Finally, you do need the documentation!
BDSC
Okay, first of the line is the free and professional version of bdsc. Looks good but it does not run under the Linux CP/M emulator I am using.
Aztec C
Looks good, works with Linux CP/M emulator and I have the documentation.
Better still the minimum package (with floating point) is:
Now you will need to add other libraries as you require them but the above is only 160kb.
Here is an example (under my Linux CP/M emulator):
Here is my test.c:
#include "stdio.h"
#include "math.h"
main()
{
char buf[80];
float r;
printf("please enter your name: ");
gets(buf);
r=sqrt(1.1);
printf("hello, %s, %f welcome to the growing community of Aztec C users\n",
buf,r);
}
And the Output:
./cpm test
please enter your name: AlanX
hello, AlanX, 1.048798 welcome to the growing community of Aztec C users
The only downside is that the COM file is rather large (12.4k) for such a small program, but then COM file needs to include all the libraries (i.e. static) and the 8080 is a rather primitive CPU (8 bit and no FPU).
Without floating point maths, the executable is still 8.5kb.
Yes and No
Modified makeDisk256 to read native CP/M files rather than hex files (saves a lot of work renaming files once they are on the machine.
Took a day trying to workout why the compiler did not work on the machine. I only have 32kb of RAM (less CP/M) for a 39kb executable.
Any, uploaded a precompiled test file (TEST.COM) and it works.
Only problem is when the program exits it kills my machine. Likely a problem in my CBIOS.
Here is the run:
my CP/M 2.2 V1A
A>DIR
A: STAT COM : ED COM : ASM COM : DDT COM
A: LOAD COM : SUBMIT COM : XSUB COM : PIP COM
A: BASIC COM : BASIC DOC : UNZIP COM : TEST BAS
A>STAT *.*
Recs Bytes Ext Acc
64 8k 1 R/W A:ASM.COM
59 8k 1 R/W A:BASIC.COM
51 8k 1 R/W A:BASIC.DOC
38 6k 1 R/W A:DDT.COM
52 8k 1 R/W A:ED.COM
14 2k 1 R/W A:LOAD.COM
58 8k 1 R/W A:PIP.COM
41 6k 1 R/W A:STAT.COM
10 2k 1 R/W A:SUBMIT.COM
1 2k 1 R/W A:TEST.BAS
28 4k 1 R/W A:UNZIP.COM
6 2k 1 R/W A:XSUB.COM
Bytes Remaining On A: 180k
A>STAT DSK:
A: Drive Characteristics...
Read more »Post Mortem
Well, this is the end of this project. The machine works as expected.
One other problem was that I lost my boot sector twice. So I have implemented Boot Sector (for the first 8kb) Software Protection. What caused it? I don't know (other than an attempted write to the first sector between 0x8000 and 0x807F). Was it CCP/BDOS or was it (my) CBIOS.
Otherwise it works fine:
my CP/M 2.2 V1A
A>dir
A: STAT COM : ED COM : ASM COM : DDT COM
A: LOAD COM : SUBMIT COM : XSUB COM : PIP COM
A: BASIC COM : BASIC DOC : UNZIP COM
A>STAT *.*
A>STAT DSK:
A>BASIC
BASIC/5 INTERACTIVE INTERPRETER V Z1.0 10/16/77
NEW OR OLD? N
NEW PROGRAM NAME: TEST.BAS
READY
10 FOR I=1 TO 10
20 PRINT I
30 NEXT I
40 END
LIST
10 FOR I=1 TO 10
20 PRINT I
30 NEXT I
40 END
RUN
1 2 3 4 5 6 7 8 9 10
READY
SAVE
READY
SYSTEM
A>DIR
Some Thoughts
Although I have a new CP/M (Version 2) PCB that has 512kb Flash Disk and 56kb RAM, I really need to get rid of software serial. The only way to get software serial to work properly is to use an interrupt timer. It's just that using a proper UART would be easier.
The UART also needs hardware handshake.
8085 vs Z80
A lot of CP/M 2.2 software is Z80 rather than 8080/85.
Flash Programmer Upgrade
Due to the 32kb program capacity of the Nano, it is rather error prone setting up four Arduino Nano scripts per 64kb of Flash Disk capacity. An ATMEGA2560 has 256kb of program capacity so using one of these would usually be a one pass Flash program.
An ATMEGA1284 is a through hole IC and would allow a 120kb programming pass. So I need to design a Flash programmer around one of these.
CH275B USB Module
I want to make provision for one of these on the next design.
Serial Port Jumper
I was supposed to use a 90 angle jumper socket with the myCM/P V1A, so I don't have to replace the 90 degree jumper pins on the USB2Serial converter. I just forgot.
Software
I have written a lot of code for this project:
Created System Flash Disk
Created a 256kb system disk with 128 directories with a 2048b block size.
Well actually I just flashed the lower 16kb of the system disk as that is all that is needed to boot up.
First Power Up
Well I got:
My CP/M 2.2 V1A
A:
But Serial In did not work (i.e. no response to the terminal input). That is not too bad. A lot has to work to get here. I am guessing I have interrupts disabled and not re-enabled somewhere.
A Day Later
Managed to find (most of) the bugs, seems to be working:
my CP/M 2.2 V1A
A>DIRA: R/W, Space: 238k
A>STAT DSK:
A: Drive Characteristics
1984: 128 Byte Record Capacity
248: Kilobyte Drive Capacity
128: 32 Byte Directory Entries
0: Checked Directory Entries
256: Records/ Extent
16: Records/ Block
16: Sectors/ Track
4: Reserved Tracks
dding More Files to the Flash Disk
I am have some problems here. I cannot download hex via the serial port as the software serial code is not up to the task (I can't download while writing to disk).
Using my makeDisk code and programming the flash disk via an Ardunio Nano is pretty clumsy. This can be improved by using an ATMEGA1284 for the programmer.
I think however, it is time to use an UART.
The alternative is to have a clocked interrupt to manage software serial and disk writes. But do I really want to go there? Only to show off I suppose!
makeDisk Debug
I managed to find a benign bug (not benign for flash disks with more than 32kb) in my makeDisk code. I knew it was there but I could not see it! So time to load up some more programs to flash disk.
Found another bug in the directory structure code. Fixed. Now all the files are visible.
i8HEX
I have to edit my i8hex code to add segment information as the address rolls over after 64k. Checking the Internet, there are a couple of ways to do this. The Intel 8086 segment type command is an easy option.
AlanX
Software Serial
When I wrote the software serial code I realised that it could not handle back to back bytes (at 9600 baud) as there is only 30us spare. I am using a 5MHz clock (i.e. 10MHz crystal). That is, there is no time to echo or do anything else. It was not considered a problem for a human typist however. Still, receiving while sending is still a problem.
But at the time, it was good enough.
I do have a problem however as the flash disk write is timing sensitive (should not be interrupted for more than 200us). It takes 948uS to write the sector (128b) and 1047us (less 30us) to read a serial byte. An impossible position.
Yes, I have looked at using and UART and it is coming, but after sorting out the Flash disks. I do not want to make too many changes at one time.
An option is to use software serial handshake (i.e. XON/XOFF). That is stop serial input during a flash critical disk write (and/or serial output).
Rather than trying to fix these problems, I am just living with it until I move to an UART.
It properly fix these issues in software, an interrupt timer is required.
The lesser of two (or more) evils is to disable interrupts during serial write or flash disk write.
AlanX
My CP/M V2
Should not really be working on this now, but anyway I updated cbios.asm for the W29C040-90B 256 byte page size. It was not that hard really, you just read to a buffer the"other" segment (that is within the 256b page boundary) and then write back the buffer before (immediately) writing the target segment.
I also had the rework the disk/track/segment address from:
DDTTTTTT 1TTTTSSS SAAAAAAA
to:
DDTTTTTT 111TTSSS SAAAAAAA
where:
D = Disk
T = Track
S = Segment
A = Address of a byte withing a segment.
The first address format (V1) could access 32kb RAM, 4 disks of 2 Mb capacity while the second (V2) can address 56kb RAM, 4 disks of 512kb capacity.
In theory, CP/M can access 16 disks of 8 Mb capacity.
Alan
PCB
Today the PCB has arrived. So tomorrow I will round up he chips and start the assembly. Flash the chips and with some luck it will fire up.
The most important thing to check here is if rst7.5 is trouble free from other programs hijacking the interrupt.
Next Version
Yes, I am thinking of that. But I have to check that the current design works first. The idea is baby steps, make debugging much easier.
The current version has 32kb RAM and 32kb of exposed ROM (i.e. Flash). It uses A15 to control the boot-up logic.
I can increase the RAM by reducing the exposed ROM, by using (say) A15, A14 and A13. This will give me 56kb RAM and 8kb exposed ROM (i.e. the full boot, ccp, bdos and cdos code). Now, I could increase the RAM further but this configuration work well with the 29AT040-90B Flash chip. The configuration give me 4x Flash disks of 512kb and 56k RAM. Here is the new schematic:
Instead of using a fourth Flash disk, the slot could be used for an UART and other hardware.
Assembled CP/M V1A this morning:
Next is to format the Flash Chips and load the system files.
Z80 Interrupts
I looked at the Z80 interrupts and found the "Mode 1" must be what most other CP/M systems must be using. It functionally equivalent to RST7.5 on the 8085 but the address is 0038h rather than 003Ch.
AlanX
Editing the CBIOS
The cbios is used to tell the CP/M operating system about your hardware. It contains routines (i.e. drivers) for your hardware. In my case I have software serial I/O and FRAM (i.e. flash) disks.
The only thing I have to change for the serial I/O is the interrupt vector (from RST6.5 to RST7.5).
The flash disk configurations and the read/write drivers.
The Disk Parameters
Using the CPM_2_0_System_Alteration_Guide,pdf as a guide I have recalculated the "standard floppy" for CP/M machines:
CP/M Disk Parameter Calcs | |||||||||
|
Standard |
|
|||||||
Bytes/Sector | 128 | Record size | |||||||
Sectors/Track | 26 |
|
|||||||
Tracks | 77 | Tracks | |||||||
|
|
|
|||||||
Disk Capacity | 250.25 | Disk Capacity kb | |||||||
SYS | 2 | System Tracks | |||||||
TRK | 75 | User Tracks | |||||||
CAP | 243.75 | Storage Capacity kb | |||||||
n | 10 | n = 10 to 14 | |||||||
BLS | 1,024 | BLS = 2**n | |||||||
|
|
|
|||||||
SPT | 26 | Sectors | |||||||
BSH | 3 | BSH = n-7 | |||||||
BLM | 7 | BLM = 2**BSH - 1 | |||||||
EXM | 0 | EXM = 2**(BSH-3) - 1 if DSM<256 | |||||||
|
|
EXM = 2**(BSH-4) - 1 if DSM>=256 | |||||||
DSM | 242 | DSM = maximum data block number | |||||||
DRM | 63 | Directory Mask: DRM=BLS/16 | |||||||
BLOCKS | 32 |
|
|||||||
AL0 | 192 |
|
|||||||
AL1 | 0 |
|
|||||||
|
|
|
|||||||
|
Standard Floppy |
DISK PARAMETER BLOCK: | |||||||
SPT | 26 | SECTORS PER TRACK | |||||||
BSH | 3 | BLOCK SHIFT FACTOR | |||||||
BLM | 7 | BLOCK MASK | |||||||
EXM | 0 | EXTENDED BLOCK MASK | |||||||
DSM | 242 | DISK SIZE-1 | |||||||
DRM | 63 | DIRECTORY SIZE-1 | |||||||
AL0 | 192 | ALLOC 0 | |||||||
AL1 | 0 | ALLOC 1 | |||||||
CKS | 16 | CHECK SIZE | |||||||
OFS | 2 | SYSTEM TRACK OFFSET |
For the 8*256kb Flash I want 128 directory entries. Therefore I need a BLOCK size of 2048 bytes. Here are the parameters for the system disk A:
CP/M Disk Parameter Calcs | |||||||||
|
256k System |
|
|||||||
Bytes/Sector | 128 | Record size | |||||||
Sectors/Track | 16 |
|
|||||||
Tracks | 128 | Tracks | |||||||
|
|
|
|||||||
Disk Capacity | 256 | Capacity kb | |||||||
SYS | 4 | System Tracks | |||||||
TRK | 124 | User Tracks | |||||||
CAP | 248.00 | Capacity kb | |||||||
n | 11 | n = 10 to 14 | |||||||
BLS | 2,048 | BLS = 2**n | |||||||
|
|
|
|||||||
SPT | 16 | Sectors | |||||||
BSH | 4 | BSH = n-7 | |||||||
BLM | 15 | BLM = 2**BSH - 1 | |||||||
EXM | 1 | EXM = 2**(BSH-3) - 1 if DSM<256 | |||||||
|
|
EXM = 2**(BSH-4) - 1 if DSM>=256 | |||||||
DSM | 247 | DSM = maximum data block number | |||||||
DRM | 127 | Directory Mask: DRM=BLS/16 | |||||||
BLOCKS | 32 |
|
|||||||
AL0 | 240 |
|
|||||||
AL1 | 0 |
|
|||||||
|
|
|
|||||||
|
256k System | DISK PARAMETER BLOCK: | |||||||
SPT | 16 | SECTORS PER TRACK | |||||||
BSH | 4 | BLOCK SHIFT FACTOR | |||||||
BLM | 15 | BLOCK MASK | |||||||
EXM | 1 | EXTENDED BLOCK MASK | |||||||
DSM | 247 | DISK SIZE-1 | |||||||
DRM | 127 | DIRECTORY SIZE-1 | |||||||
AL0 | 240 | ALLOC 0 | |||||||
AL1 | 0 | ALLOC 1 | |||||||
CKS | 0 | NOT REMOVEABLE | |||||||
OFS | 4 | SYSTEM TRACK OFFSET |
And the same for the data disk (B):
|
256k Data | DISK PARAMETER BLOCK: |
SPT | 16 | SECTORS PER TRACK |
BSH | 4 | BLOCK SHIFT FACTOR |
BLM | 15 | BLOCK MASK |
EXM | 1 | EXTENDED BLOCK MASK |
DSM | 255 | DISK SIZE-1 |
DRM | 127 | DIRECTORY SIZE-1 |
AL0 | 240 | ALLOC 0 |
AL1 | 0 | ALLOC 1 |
CKS | 0 | NOT REMOVEABLE |
OFS | 0 | SYSTEM TRACK OFFSET |
Note: CP/M does not need to check the disks are the media (Flash) cannot be removed while the power is on.
Edits done, files compile, so next is make a disk image and to load the image onto the Flash chips.
AlanX
Updated the Schematic and PCB
Well I did update the schematic and PCB but found I had done that some time ago.
So I sent the PCB off for manufacture.
Here is the schematic:
CP/M Firmware
I will have to collect the work I did on the first version and update the "cbios.asm" for the new FRAM size etc.
I will also have to collect the programs I want to put on the "Flash Disks". Previously I wrote a C program to do this. However, writing the hex code to flash has to be in 16kb passes as the Nano can only hold about this much. Not really problem as hex code can be added incrementally.
The Flash Programmer
Here is the Flash Programmer:
It is set up for either an AT29C256 or a W29C020.
Note: When flashing these chips I use software protections to avoid the chips losing their contents due to accidental writes (during debugging).
Here is the assembled Flash Programmer (with the old My CP/M computer):
AlanX
Create an account to leave a comment. Already have an account? Log In.
Become a member to follow this project and never miss any updates
By using our website and services, you expressly agree to the placement of our performance, functionality, and advertising cookies. Learn More