Jump to content
IGNORED

CPM/Z-80 card for the 1090XL -- Calling anyone with Z-80 experience!


Recommended Posts

Can't edit the previous post anymore. But I just tested the freshly assembled ATSYSGEN.COM under emulation and it works correctly with whatever number of bootracks and sectors per track I hardcode in the assembly source. It's a bit of a weird "conversation" you have with the program though:

 

A>atsysgen
SYSGEN VER 2.0
SOURCE DRIVE NAME (OR RETURN TO SKIP)a
SOURCE ON A, THEN TYPE RETURN
FUNCTION COMPLETE
DESTINATION DRIVE NAME (OR RETURN TO REBOOT)b
DESTINATION ON B, THEN TYPE RETURN
FUNCTION COMPLETE
DESTINATION DRIVE NAME (OR RETURN TO REBOOT)

So you type 'a', then Enter. Then 'b', then Enter, and after that you can run it again on a different destination. If you don't press another drive name but Enter instead, it does a JMP $0000 and exits.

Edited by ivop
  • Like 1
  • Thanks 1
9 hours ago, ivop said:

I started disassembling atformat, and it does indeed send a special BIOS command to the Atari. For fun, I tried Ghidra in Z80 mode, but it does not have a proper export to assembly. I am expected to write code for that, which I'm not going to do. Reko constantly crashes, so I guess it's back to the z80dasm command line utility :( Perhaps it's easier to write format and sysgen from scratch. We can even do that in C and compile with the Amsterdam Compiler Kit. Format just needs to read the drive name from the command line (from cpm_fcb), ask for Y/N, and send the format command to the Atari. Sysgen is basically a sector copier that copies the bootblock from drive x to drive y, which is also trivial in C.

 

I'll come up with some sort of command system, in the CP/M BIOS, to format a disk and, maybe, do some other things.

 

Using C would make development a little faster...

 

 

9 hours ago, ivop said:

Ah, IIRC that's a Z80 port of wozmon, isn't it? Is it small enough to fit in the BIOS?

Nope.  It's the Atari port of Wozmon that I added to the 6.2 version of the Atari OS that I put together.  I just haven't released it yet.  It does work quite well, though.    🙂

 

9 hours ago, ivop said:

Edit3: attached atsysgen.zip. Contains official DRI source, modified for 3 boot tracks and sectran to a no-op, and the resulting binary.

 

Looks like 8080 code?  Either way, that code could be used to help figure out how to write the atcopy and atformat programs....

 

 

 

 

 

 

 

1 hour ago, reifsnyderb said:

Nope.  It's the Atari port of Wozmon that I added to the 6.2 version of the Atari OS that I put together.  I just haven't released it yet.  It does work quite well, though.    🙂

Yes, that sounds helpful during debugging the Atari side of things. BTW WozMon Z80 actually is a thing. I googled it and found: http://www.welzel-online.ch/downloads.html . Source is included. Looks easy enough to replace the single board computer I/O with BIOS calls and include it in your BIOS. Then, triggering an IRQ could jump to there.

 

1 hour ago, reifsnyderb said:

Looks like 8080 code?  Either way, that code could be used to help figure out how to write the atcopy and atformat programs....

Yes, it's the original DRI 8080 SYSGEN.ASM source code from '79. It has nothing to do with Atari. I just also named it ATSYSGEN because that is what it replaces after my modifications for your Atari ED format (3 tracks bootblock, 26 sectors per track).

 

16 hours ago, ivop said:

. The dumps are not correct though. They include a zeroed page zero.

 

 

That would be me that has done that. My z80 dissembler assumes zero is start of program. (may be possible to set but haven't looked into it).

here is ATCOPY that i have dissembled.

ATCOPY.DIS

  • Like 2

I did a bit more in depth disassembly, and it turns out it is not the utility you are looking for. It just copies some sectors from drive x to drive y and is probably part of preparing a new bootable disk. We don't need that. The SYSGEN I supplied earlier will take care of that, and in case you decide to incorporate the .SYS loader, there's PIP to copy over bios.sys, bdos.sys and ccp.sys. But for now, SYSGEN is enough.

 

So, a simple format utility is easy (send format command, fill bootblock with 0E5h).

SYSGEN we have.

Copying files from DOS 2.5 to CP/M is not what ATCOPY does, but it's fairly trivial to write. I'll write it this evening in portable C so we can use the same utility under CP/M-65. That was on my todo-list anyway, so that's two birds with one stone ;) The author of the ACK CP/M backend is the same as the author of the llvm-mos CP/M-65 backend (David Given), so the API is nearly identical.

 

 

atcopy.asm

Edited by ivop
  • Thanks 1

Here's dos2tools for CP/M. Even though I prefer to use cpmtools myself, I acknowledge that the command line is not for everyone, so now you can download CP/M files, put them in a DOS 2.x formatted ATR with your favorite GUI tool and copy them to your CP/M disks from within CP/M. I implemented CP/M style wildcards which means you do not have to copy each file one at the time. Period ALL CAPS interface ;)

 

Spoiler

64k CP/M vers 2.2

 

A>dos2dir
ATARI DOS 2.x DIR
SELECT DRIVE: b
  WINSTALLCOM  0233
 <WS      INS> 0465
0309 FREE SECTORS

 

A>dos2copy
ATARI DOS 2.x COPY
SELECT SOURCE DRIVE: b
SPECIFY FILE(S): w*.*
SELECT DESTINATION DRIVE: a
COPYING "W??????????" FROM DRIVE B TO DRIVE A
ARE YOU SURE? (Y/N) y
COPYING "WINSTALLCOM"
COPYING "WS      INS"

 

A>       (swapped disks here, and pressed ctrl-C)

 

A>dos2dir
ATARI DOS 2.x DIR
SELECT DRIVE: b
  WSMSGS  OVR  0240
  WSOVLY1 OVR  0268
* WSU     COM  0141
0357 FREE SECTORS

 

A>dos2copy
ATARI DOS 2.x COPY
SELECT SOURCE DRIVE: b
SPECIFY FILE(S): wsu.com
SELECT DESTINATION DRIVE: a
COPYING "WSU     COM" FROM DRIVE B TO DRIVE A
ARE YOU SURE? (Y/N) y
COPYING "WSU     COM"

 

A>dos2copy
ATARI DOS 2.x COPY
SELECT SOURCE DRIVE: b
SPECIFY FILE(S): *.ovr
SELECT DESTINATION DRIVE: a
COPYING "????????OVR" FROM DRIVE B TO DRIVE A
ARE YOU SURE? (Y/N) y
COPYING "WSMSGS  OVR"
COPYING "WSOVLY1 OVR"

 

A>
 

 

Compiled versions for the atari1090ed disk format, plus source and Makefile included.

 

dos2tools.zip

Edited by ivop
  • Like 3
  • Thanks 1
Posted (edited)
On 4/21/2024 at 3:55 PM, ivop said:

Here's a disk image that might help you debugging this problem

 

Source:

  Hide contents

#include <stdio.h>
#include <string.h>
#include <cpm.h>

unsigned char buffer[128];

int main(int argc, char **argv) {
    int i;

    cpm_fcb.ex = cpm_fcb.s1 = cpm_fcb.s2 = cpm_fcb.rc = 0;
    memcpy(&cpm_fcb.f, "FOO     BAR", 11);

    printf("Opening file\n");
    if (cpm_make_file(&cpm_fcb)) {
        printf("Error opening file, file exists?\n");
        return 1;
    }

    printf("Setting DMA\n");
    cpm_set_dma(&buffer);

    printf("Filling buffer\n");
    for (i=0; i<128; i++)
        buffer[i] = i;

    printf("Writing buffer\n");
    if (cpm_write_sequential(&cpm_fcb)) {
        printf("Error writing to disk\n");
        return 1;
    }

    printf("Closing file\n");
    if (cpm_close_file(&cpm_fcb)) {
        printf("Error closing file\n");
        return 1;
    }

    printf("Done.\n");
    return 0;
 

 

Expected output:

  Reveal hidden contents

64k CP/M vers 2.2

A>dir foo.bar
NO FILE
A>write
Opening file
Setting DMA
Filling buffer
Writing buffer
Closing file
Done.

A>dir foo.bar
A: FOO      BAR
A>dump foo.bar

0000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0010 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
0020 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
0030 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
0040 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
0050 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
0060 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
0070 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F

 

Edit: BTW are you sure the disk is writable? I don't know what RespeQt's defaults are. Might be R/O.

 

writetest.atr 130.02 kB · 5 downloads

Ok.  I am finally back to trying to get this sucker to work.

 

Reading and writing now works as tested out on a DOS 2.5 ATR file.

 

Running the write.com file fails on line 10.

 

 

    printf("Opening file\n");
    if (cpm_make_file(&cpm_fcb)) {
        printf("Error opening file, file exists?\n");
        return 1;
    }

 

Where line 10 is

 

     if (cpm_make_file(&cpm_fcb)) {
 

 

The directory shows the "FOO.BAR" file.  Upon examination of the directory, with a hex editor, there are no blocks listed.

 

I was thinking that maybe the write status is screwed up for some reason.  It's not.  The status being returned is 0 where 0 is success and non-zero is an error.

 

Here's the CP/M BIOS write sector code:

 

WRITE:
	; Copies the sector from DMA address to SBUFF then writes it to disk.
	; Uses selected drive, track, and sector.
	; Returns 0 in a if no error and > 0 if error occurred.

	; Copy sector buffer to DMA address
	ld	hl,(IODMA)
	ld	de,SBUFF
	ld	bc,$80
	ldir

	; Set IOCommand
	ld	a,WriteSector
	ld	(IOCommand),a

	call AtariIO

	ld	a,(IOStatus)

	; Add error handling.....
	
	ret

 

 

AtariIO code:

 

AtariIO:
	;	Set IOComplete flag to $ff
	ld	a, $FF
	ld	(IOComplete),a

	; Lower service request flag
	ld	a,$00		; Only bit 7 will be set low on I/O
	out	($00),a

	; Wait for IO to be completed.  (IOComplete will be $00)
AtariIO1:
	ld	a,(IOComplete)
	cp	$00
	jr		nz,AtariIO1
	
	; Reset (raise) service request flag
	ld	a,$FF		; Only bit 7 will be set high on I/O
	out	($00),a

	ret

 

 

Any thoughts on this?

 

Thanks!

 

Brian

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Edited by reifsnyderb
35 minutes ago, reifsnyderb said:

Ok.  I am finally back to trying to get this sucker to work.

 

Reading and writing now works as tested out on a DOS 2.5 ATR file.

 

Running the write.com file fails on line 10.

 

 

    printf("Opening file\n");
    if (cpm_make_file(&cpm_fcb)) {
        printf("Error opening file, file exists?\n");
        return 1;
    }

 

Where line 10 is

 

     if (cpm_make_file(&cpm_fcb)) {
 

 

The directory shows the "FOO.BAR" file.  Upon examination of the directory, with a hex editor, there are no blocks listed.

 

I was thinking that maybe the write status is screwed up for some reason.  It's not.  The status being returned is 0 where 0 is success and non-zero is an error.

 

Here's the CP/M BIOS write sector code:

 

WRITE:
	; Copies the sector from DMA address to SBUFF then writes it to disk.
	; Uses selected drive, track, and sector.
	; Returns 0 in a if no error and > 0 if error occurred.

	; Copy sector buffer to DMA address
	ld	hl,(IODMA)
	ld	de,SBUFF
	ld	bc,$80
	ldir

	; Set IOCommand
	ld	a,WriteSector
	ld	(IOCommand),a

	call AtariIO

	ld	a,(IOStatus)

	; Add error handling.....
	
	ret

 

 

AtariIO code:

 

AtariIO:
	;	Set IOComplete flag to $ff
	ld	a, $FF
	ld	(IOComplete),a

	; Lower service request flag
	ld	a,$00		; Only bit 7 will be set low on I/O
	out	($00),a

	; Wait for IO to be completed.  (IOComplete will be $00)
AtariIO1:
	ld	a,(IOComplete)
	cp	$00
	jr		nz,AtariIO1
	
	; Reset (raise) service request flag
	ld	a,$FF		; Only bit 7 will be set high on I/O
	out	($00),a

	ret

 

 

Any thoughts on this?

 

Thanks!

 

Brian

Try ERA FOO.BAR first. make_file() fails if the file exists. That's why dos2copy does a delete_file() first. Does that help?

21 minutes ago, ivop said:

Try ERA FOO.BAR first. make_file() fails if the file exists. That's why dos2copy does a delete_file() first. Does that help?

ERA FOO.BAR successfully erases the file.

 

Running WRITE.COM, afterwards, results in the same error.

 

Posted (edited)
9 hours ago, ivop said:

Try ERA FOO.BAR first. make_file() fails if the file exists. That's why dos2copy does a delete_file() first. Does that help?

Is it possible the

 

if (cpm_make_file(&cpm_fcb)) {

 

line needs changed to something like

 

if (cpm_make_file(&cpm_fcb) != 0) {

 

or maybe cpm_make_file(&cpm_fcb) returns a 1 upon success?

 

I am trying to find some reference to the library function.

 

 

Edit:  I found a reference here:    https://github.com/davidgiven/cpmish/blob/master/cpmtools/qe.c

 

if (cpm_make_file(fcb) == 0xff)
        return false;

 

 

 

Edited by reifsnyderb
1 hour ago, reifsnyderb said:

Is it possible the

 

if (cpm_make_file(&cpm_fcb)) {

 

line needs changed to something like

 

if (cpm_make_file(&cpm_fcb) != 0) {

 

or maybe cpm_make_file(&cpm_fcb) returns a 1 upon success?

 

I am trying to find some reference to the library function.

 

 

Edit:  I found a reference here:    https://github.com/davidgiven/cpmish/blob/master/cpmtools/qe.c

 

if (cpm_make_file(fcb) == 0xff)
        return false;

Oh, looks like I might have posted the wrong version :( If you look at dos2copy I do the same as David, i.e. compare with 0xff. Somehow I ealier posted a version from before I fixed this, but with the console output of the correct version. Here's the right version.

 

64k CP/M vers 2.2

A>write
Opening file
Setting DMA
Filling buffer
Writing buffer
Closing file
Done.

A>
 

write.zip

  • Like 2
  • Thanks 2
Posted (edited)

I still need to test the write program.  Interrupt testing appears to work from a hardware level.  So, I am comfortable that the hardware works and the software just needs some bugs worked out.

 

10 boards are now ordered.   🙂

 

Z-80boardfinalwcomponents.thumb.png.c2807a58d285ed885d91485dc65a4ba7.png

Edited by reifsnyderb
  • Like 4
On 5/1/2024 at 11:25 AM, ivop said:

Oh, looks like I might have posted the wrong version :( If you look at dos2copy I do the same as David, i.e. compare with 0xff. Somehow I ealier posted a version from before I fixed this, but with the console output of the correct version. Here's the right version.

 

64k CP/M vers 2.2

A>write
Opening file
Setting DMA
Filling buffer
Writing buffer
Closing file
Done.

A>
 

write.zip 5.2 kB · 7 downloads

I just confirmed the new write.com works.  Disk I/O looks good.   🙂

 

  • Like 4
39 minutes ago, reifsnyderb said:

What is more surprising is that the Z80 after 48 years of service is finally being discontinued, at least they could of made it to 50 :D 

 

  • Like 1
  • Haha 1

FYI there are other versions of the Z80 that will continue to be manufactured, including the eZ80 used on the Agon Light/Agon Light2/Agon Console 8 computers and the TI-84 Plus CE calculator. I believe all the eZ80 are in surface mount packages.

 

 

  • Like 1
Posted (edited)
1 minute ago, Forrest said:

FYI there are other versions of the Z80 that will continue to be manufactured, including the eZ80 used on the Agon Light/Agon Light2/Agon Console 8 computers and the TI-84 Plus CE calculator. I believe all the eZ80 are in surface mount packages.

 

 

The ez80 is, basically, a micro controller.  It's a 100 pin package.  Making an adapter, to plug it into a 40 pin DIP socket, would be difficult.  (The Agon uses the ez80.)

Edited by reifsnyderb

@ivop  What did you use to compile the write.c file?  I installed the z88dk and it's failing with an error of "unknown symbol:  cpm_fcb".  I am using the command of "zcc +cpm write.c".  I am guessing that cpm_fcb isn't in the cpm.h library.

I was unable to find any documentation explaining the cpm library for z88sdk.  So, I just posted a message in the z88dk forums to try to get some help with compiling write.c.  <sigh>

 

Posted (edited)
10 hours ago, reifsnyderb said:

@ivop  What did you use to compile the write.c file?  I installed the z88dk and it's failing with an error of "unknown symbol:  cpm_fcb".  I am using the command of "zcc +cpm write.c".  I am guessing that cpm_fcb isn't in the cpm.h library.

I used the Amsterdam Compiler Kit, which can be downloaded here: https://github.com/davidgiven/ack

 

dos2dir and dos2copy can also be compiled with that. There's a Makefile in the zipfile I posted earlier. The basic compile command is ack -mcpm -o foo.com foo.c

Edited by ivop
  • Thanks 1

I decided to try to get z88sdk working so as to write a couple utilities needed to import files stored on Atari disks into the CP/M ecosystem.  Since a first, reasonable step, appeared to be to get the write.com source code ported, here's what I came up with.  It works.   🙂

 

 

#include <stdio.h>
#include <string.h>
#include <cpm.h>

unsigned char buffer[128];

int main(int argc, char **argv) {
    int i;

	unsigned char buffer[128];

	FILE *dest;

    printf("Opening file\n");

	dest = fopen("FOO.BAR","wb");
	if(dest == NULL)
	{
		printf("Error opening file, file exists?\n");
        return 1;
    }

    printf("Setting DMA\n");

    printf("Filling buffer\n");
    for (i=0; i<128; i++)
        buffer[i] = i;

    printf("Writing buffer\n");
	if(NULL==fwrite(buffer,128,1,dest))
	{
        printf("Error writing to disk\n");
        return 1;
	}

    printf("Closing file\n");
	
	fclose(dest);

    printf("Done.\n");
    return 0;
}

 

  • Like 3
  • Thanks 1
Posted (edited)
3 hours ago, reifsnyderb said:

I decided to try to get z88sdk working so as to write a couple utilities needed to import files stored on Atari disks into the CP/M ecosystem.  Since a first, reasonable step, appeared to be to get the write.com source code ported, here's what I came up with.  It works.   🙂

Did you miss my post with dos2dir and dos2copy? I already wrote the utilities to import files stored on Atari disks.

 

Re using stdio.h, in write.com I used printf for convenience because size didn't really matter for a test utility. dos2dir and dos2copy use CP/M directly which saves an enormous amount of RAM, disk space and load time. A single printf in dos2dir increases the file size from 3494 bytes to 9704 bytes. That's 277% bigger, and not even pulling in fopen/fclose/fread/fwrite/etc... Another reason I called CP/M directly in write.com is that you know exactly what it does. You wouldn't have known which BIOS call went wrong if I used libc functions that do whatever behind your back.

 

A note on dos2copy, BDOS doesn't really like it when you bypass it and change the drive underneath it with BIOS calls. But we need that, because we need to read the Atari directory and file sectors. Hence it uses BIOS seldsk to restore it back to what BDOS expects for its file access. BDOS's seldsk won't work, because it is not aware of a drive change.

 

You can port it to the z88dk environment if you want to, but I don't really see the point. ACK is a compiler that has been tested for over 40 years, and used to be the main Minix compiler.

 

 

Edit:

 

sysgen: https://forums.atariage.com/topic/362513-cpmz-80-card-for-the-1090xl-calling-anyone-with-z-80-experience/?do=findComment&comment=5457101

dos2tools: https://forums.atariage.com/topic/362513-cpmz-80-card-for-the-1090xl-calling-anyone-with-z-80-experience/?do=findComment&comment=5458386

 

I recommend renaming atsysgen.com to plain sysgen.com as it has always been a device specific utility back in the past and its name was sysgen.

 

All three programs were specifically written for your CP/M 1090 port.

Edited by ivop
Posted (edited)
15 minutes ago, ivop said:

Did you miss my post with dos2dir and dos2copy? I already wrote the utilities to import files stored on Atari disks.

I guess I forgot or missed it.  I'll take another look as I was thinking I had to write them.

 

 

15 minutes ago, ivop said:

Re using stdio.h, in write.com I used printf for convenience because size didn't really matter for a test utility. dos2dir and dos2copy use CP/M directly which saves an enormous amount of RAM, disk space and load time. A single printf in dos2dir increases the file size from 3494 bytes to 9704 bytes. That's 277% bigger, and not even pulling in fopen/fclose/fread/fwrite/etc... Another reason I called CP/M directly in write.com is that you know exactly what it does. You wouldn't have known which BIOS call went wrong if I used libc functions that do whatever behind your back.

 

I noticed the C version is humongous and experience tells me it's a library being a hog.  Given that an import utility wouldn't be used too often, I figured being able to develop it at a higher speed, by using C, was a reasonable tradeoff.

 

15 minutes ago, ivop said:

A note on dos2copy, BDOS doesn't really like it when you bypass it and change the drive underneath it with BIOS calls. But we need that, because we need to read the Atari directory and file sectors. Hence it uses BIOS seldsk to restore it back to what BDOS expects for its file access. BDOS's seldsk won't work, because it is not aware of a drive change.

 

Makes sense.  I've noticed the write.com file I compiled changes the selected disk from B back to A, when done.

 

15 minutes ago, ivop said:

You can port it to the z88dk environment if you want to, but I don't really see the point. ACK is a compiler that has been tested for over 40 years, and used to be the main Minix compiler.

 

I mainly set up the z88dk environment as I didn't realize ack was used.

 

 

I'll check out the dos2dir and dos2copy next.

 

Thanks!

 

 

Edited by reifsnyderb
  • Like 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...