Trying to support the Xerox 820 with appmake

Post Reply
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Trying to support the Xerox 820 with appmake

Post by stefano »

Some time ago I submitted a patch to the MAME project fixing the disk controllers on the basic Xerox820 model (SA400->SA400l drive models).
The RAW format is not accepted yet, but IMD works fine.
Now it is possible to work on the disk images with CPMTOOLS and, with a bit of work, run CP/M programs on MAME.
The TRM has detailed technical specs, so I thought it was easy to include the disk format in appmake, but something is wrong.

Got from the TRM (SSSD, 5"1/4, 40 Tracks, 18 Sectors, 128 byte sector size):


Sectors Per Track (SPT) 18
Block Shift Factor (BSH) 3
Max. Rec. # in blk (BLM) 7
Extent Mask (EXM) 0
Total Storage capacity (DSM) 82
Total # of directory entries (DRM) 31
Allocation mask (ALO) 80H
Allocation mask (AL 1) 0
Size of dir check vector (CKS) 8
Reserved tracks (OFF) 3


Skew table: 1 ,6, 11, 16, 3, 8, 13, 18, 5, 1 0, 15, 2, 7, 12, 17, 4, 9, 14


Cpmtools (works):

# XER2 Xerox 820 - SSSD 48 tpi 5.25" - 128 x 18
diskdef xer2
seclen 128
tracks 40
sectrk 18
blocksize 1024
maxdir 32
skew 5
boottrk 3
os 2.2
end




My conclusions (close, but does not work):


static disc_spec x820_spec = {
.name = "Xerox820",
.sectors_per_track = 18,
.tracks = 40,
.sides = 1,
.sector_size = 128,
.gap3_length = 0x17,
.filler_byte = 0xe5,
.boottracks = 3,
.directory_entries = 32,
.extent_size = 1024,
.byte_size_extents = 0,
.first_sector_offset = 0,
.has_skew = 1,
.skew_track_start = 0,
.skew_tab = { 0,5,10,15,2,7,12,17,4,9,14,1,6,11,16,3,8,13 }
};


I can see a correct directory on CPMTOOLS but MAME fails. The image is accepted by MAME but CP/M says "disk error".
Suggestions ?
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Re: Trying to support the Xerox 820 with appmake

Post by dom »

Did you try it without the skew table? And it might need byte-sized extents as well.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

Yes. I'm comparing it with a working image containing only magic.com.
It looks almost identical, that's why I'm puzzled.

In the meantime I discovered a small difference in the allocation tables, now I changed from words to bytes, which you noticed as well.
Still no luck, though.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

I decided to create an inspection program starting from dpb.com, it will be useful.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

I noticed that both my cpmtools version and MAME are not always dealing with the disk image formats as expected, e.g. a specific model could work fine with RAW and D88 formats and fail with IMD, or vice versa.

BTW, here's my current progress, tested on the emulated Bondwell 14:
BW14.png
You do not have the required permissions to view the files attached to this post.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

Tool is ready ;)


https://github.com/z88dk/z88dk/blob/mas ... /cpm/dpb.c


A bit of inspiration came from an ancient tool by Sydex, which is capable of listing the skew table, thus sometimes it could still be useful.
I adapted it to z80asm, so it's now easy to build with zcc or z88dk-z80asm:

Code: Select all


;  To build:   zcc +cpm -create-app /c/z88dk/examples/cpm/dpbz80.asm
;              where already available, -create-app probably helps

; ..otherwise, just add "org 100h" and build it directly with z80asm  ;)


DEFC bdos  =  0005h ; BDOS call vector
DEFC wboot  =  0000h ; Warm boot vector
DEFC cdisk  =  0004h ; current disk
DEFC cr  =  13 ; return
DEFC lf  =  10 ; line feed
DEFC bel  =  7 ; bell


GLOBAL _main

_main:
	call	Strout
	DEFM	cr,lf,"       Parameters for Drive ",0

	LD	A,(cdisk)
	AND	15
	ADD	A,'A'
	call	chout		; give a drive letter

	call	Strout
	DEFM	":",cr,lf,lf,0  ; skip a line

	LD	A,(cdisk)
	LD 	c,a
	LD	HL,(wboot+1)
	LD 	l,27		; point to seldisk
	call	Indcall		; go call (seldisk)

	LD 	a,h
	OR	l
	JP	NZ,GetDPB2		; if okay
	call	Strout
	DEFM	cr,lf,bel,"Select error",cr,lf,0
	JP	wboot		; exit...

GetDPB2:
	LD	(DPHaddr),HL		; save DPH address
	LD	DE,10
	ADD	HL,DE
	LD 	e,(HL)
	INC	HL
	LD 	d,(HL)		; get DPB address
	EX	DE,HL
	LD	(DPBaddr),HL		; save DPB address

;	Show sectors/track.

	call	Strout
	DEFM	"Sectors per Track............",0
	LD 	a,0
	call	GetField	; get a field from the DPB
	LD	(SectTrk),HL		; save it
	call	ShowDec		; show it

;	If there's a translate table, show it.

	LD	HL,(DPHaddr)
	LD 	e,(HL)
	INC	HL
	LD 	d,(HL)
	LD 	a,d
	OR	e
	JP	Z,GetDPB6		; if none..
	call	Strout
	DEFM	cr,lf,"Sectors interleaved as follows:",0

	LD	HL,(SectTrk)		; get Sectors/track
	LD 	b,h
	LD 	c,l
GetDPB4:
	call	Strout
	DEFM	cr,lf,"    ",0  ; indent
	LD	A,(DE)		; get a sector
	PUSH	HL
	LD 	l,a
	LD 	h,0
	call	ShowDec		; show it
	POP	HL
	DEC	BC
	LD 	a,b
	OR	c
	JP	NZ,GetDPB4		; loop...
	JP	GetDPB8		; do the rest...

GetDPB6:
	call	Strout
	DEFM	cr,lf,"Sectors are not interleaved",0

;	Show the rest of the fields.

GetDPB8:
	call	Strout
	DEFM	cr,lf,"Block Shift (BSH)............",0
	LD 	a,2
	call	GetField
	LD 	h,0
	call	ShowDec
	call	Strout
	DEFM	cr,lf,"Block Mask (BLM).............",0
	LD 	a,3
	call	GetField
	LD 	h,0
	call	ShowDec
	call	Strout
	DEFM	cr,lf,"Extent Mask (EXM)............",0
	LD 	a,4
	call	GetField
	LD 	h,0
	call	ShowDec
	call	Strout
	DEFM	cr,lf,"Total Blocks (DSM)...........",0
	LD 	a,5
	call	GetField
	call	ShowDec
	call	Strout
	DEFM	cr,lf,"Directory Entries (DRM)......",0
	LD 	a,7
	call	GetField
	call	ShowDec
	call	Strout
	DEFM	cr,lf,"Allocation 0 (AL0)...........",0
	LD 	a,9
	call	GetField
	LD 	h,0
	call	ShowHex
	call	Strout
	DEFM	cr,lf,"Allocation 1 (AL1)...........",0
	LD 	a,10
	call	GetField
	LD 	h,0
	call	ShowHex
	call	Strout
	DEFM	cr,lf,"Cylinder Offset (OFS)........",0
	LD 	a,13
	call	GetField
	call	ShowDec
	call	Strout
	DEFM	cr,lf,lf,0		; done...
	JP	wboot			; exit...

;*	Indirect call to (hl).
;
;	Simple, yet effective.
;

Indcall:
	JP	(HL)			; jmp to (hl)

;*	GetField - Get a DPB field into (hl)
;
;	(a) = offset on entry.
;

GetField:
	PUSH	DE
	LD	HL,(DPBaddr)
	LD 	e,a
	LD 	d,0
	ADD	HL,DE
	LD 	e,(HL)
	INC	HL
	LD 	d,(HL)
	EX	DE,HL
	POP	DE
	ret


;*	Chout - Character in (a) to console output.
;
;	Preserves all but (a)
;

chout:
	PUSH	HL
	PUSH	BC
	PUSH	DE
	LD 	e,a
	LD 	c,2
	call	bdos			; issue a console-out
	POP	DE
	POP	BC
	POP	HL
	ret

;*	Strout - Output a string following the call to this routine.
;
;	preserves all.
;
;	String is null-terminated.
;

Strout:
	EX	(SP),HL				; get return in (hl)
	PUSH	AF			; save (a)
Strout2:
	LD 	a,(HL)
	INC	HL
	OR	a
	JP	Z,Strout4			; if done...
	PUSH	DE
	PUSH	BC
	PUSH	HL
	LD 	e,a
	LD 	c,2			; console out
	call	bdos
	POP	HL
	POP	BC
	POP	DE
	JP	Strout2

Strout4:
	POP	AF
	EX	(SP),HL
	ret				; exit...all regs preserved

;*	ShowDec - Show (HL) as a decimal number.
;
;	Output to the console; blank leading zeroes.
;

ShowDec:
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF
	LD	DE,DecTable	; get powers table
	EX	DE,HL
	LD 	c,0		; say blanking
ShowDec2:
	LD 	a,(HL)
	OR	a		; see if last digit
	JP	Z,ShowDec8	; if so
	LD 	b,0
ShowDec4:
	INC	b
	LD 	a,e
	sub	(HL)
	LD 	e,a
	INC	HL
	LD 	a,d
	SBC	(HL)
	LD 	d,a
	DEC	HL
	JP	NC,ShowDec4	; if oversubtract

;	correct oversubtract.

	LD 	a,e
	ADD	A,(HL)
	LD 	e,a
	INC	HL
	LD 	a,d
	ADC	A,(HL)
	INC	HL
	LD 	d,a
	DEC	b
	JP	Z,ShowDec6	; if a zero
	LD 	c,1
ShowDec6:
	INC	c
	DEC	c		; check (c)
	JP	Z,ShowDec2	; loop to next digit
	LD 	a,b
	ADD	A,'0'
	call	chout		; character out
	JP	ShowDec2	; to next digit

;	Do the last digit - do not blank.

ShowDec8:
	LD 	a,e
	ADD	A,'0'
	call	chout
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	ret

DecTable:
	DEFW	10000,1000,100,10,0	; powers of 10


;*	ShowHex - Show a string of hex digits.
;
;	On entry (HL) = value.
;
;	Output is to console, leading zeroes blanked.
;

ShowHex:
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF
	LD	BC,0400h			; 4 digits + blank indicator
ShowHex2:
	XOR	a
	ADD	HL,HL
	RLA
	ADD	HL,HL
	RLA
	ADD	HL,HL
	RLA
	ADD	HL,HL
	RLA				; isolate a digit in (a)
	OR	a
	JP	Z,ShowHex4		; if zero
	LD 	c,1			; say nonzero
ShowHex4:
	ADD	A,'0'                     ; bias for ASCII
	CP	'9'+1
	JP	C,ShowHex6		; if 0-9
	ADD	A,'A'-'9'-1               ; make digits
ShowHex6:
	DEC	b
	JP	Z,ShowHex8		; if last digit
	INC	c
	DEC	c
	JP	Z,ShowHex10		; skip the leading zero
ShowHex8:
	call	chout
ShowHex10:
	INC	b
	DEC	b
	JP	NZ,ShowHex2		; if not done yet
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	ret				; exit...

DPBaddr: DEFW	0		; address of DPB
DPHaddr: DEFW	0		; address of DPH
SectTrk: DEFW	0		; sectors/track


The C version should be able to identify the right block size.
When in trouble, it will warn about it and will suggest a second guess.
kaypro_a.png
kaypro_b.png
bondwell.png
You do not have the required permissions to view the files attached to this post.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

MAME often allows a shortcut, after having loaded the CP/M system, to QUICKLOAD a .COM program in memory and run it directly.
So, even if you can't write in a disk image :
xerox820.png
You do not have the required permissions to view the files attached to this post.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

When the QUICKLOAD is not available, run mame with the "-debug" option, boot the CP/M disk (mout the disk image and press F5), then type in the bottom row in the debugger window: "load c:\files\dpb.com,100".
alph_debugger.png
You can then move in the emulator windows and save the loaded file in the current disk image, then just run it !
alph_dpb.png
You do not have the required permissions to view the files attached to this post.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

... I think the disk size is still wrong, the other results look strangely good :D
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

Fixed and improved.
Now it checks the CP/M version (and warns when the version is not supported) and shows the interleave table (in appmake format) when used.
I'm not yet able to create valid disk images for the Xerox820, but we now have a nice general purpose tool :D

xerox820.png
You do not have the required permissions to view the files attached to this post.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: Trying to support the Xerox 820 with appmake

Post by stefano »

I found a side element which was increasing the confusion: when I tried to convert from IMD to RAW a disk image, MAME, ONLY ON SOME OF THE CP/M TARGETS stopped working. The odd thing was that there wasn't target specific code which could have explained such behavior.
I finally discovered that the reason is probably on the FM versus MFM disk format emulation (plus on some obscure exception for few targets) !

Code: Select all

Container FM/MFM:
  hfe                      r- - SDCard HxC Floppy Emulator HFE File format [hfe]
  mfm                      rw - HxCFloppyEmulator floppy disk image [mfm]
  td0                      r- - Teledisk disk image [td0]
  imd                      r- - IMD disk image [imd]
Container MFM:
  d88                      r- - D88 disk image [d77,d88,1dd]
  cqm                      r- - CopyQM disk image [cqm,cqi,dsk]
  dsk                      r- - CPC DSK Format [dsk]
  dmk                      r- - DMK disk image [dmk]
Post Reply