Image Map Image Map
Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 24

Thread: Exidy Sorcerer - Vista - Hard sector floppy disk image format question

  1. #11
    Join Date
    May 2018
    Location
    Melbourne, Australia
    Posts
    154

    Default

    Quote Originally Posted by ldkraemer View Post
    Simon,
    First of all, THANKS for SAMdisk! I haven't used it in a while, and likely need to check the latest version
    compared to what I'm using.

    It doesn't really matter to me that the directory is located at some OFFSET to where I'm thinking it really
    should be. I was just trying to figure out how the Hard Sectored Floppy Controller was laying down the
    boot track(s) on the floppy with 512 x 10 Sectors Per Track.
    Kryoflux team have offered this definition:

    Code:
    diskdef exidy
      seclen 512
      tracks 50
      sectrk 8
      blocksize 1024
      maxdir 64
      skew 0
      boottrk 2
      os 2.2
    end

  2. #12

    Default

    If Kryoflux is right, it is not likely a 10 hard sectored. It is more likely a 16 hard sectored.
    Of course, we are assuming that the controller is hard sectored. There is no reason that you can't format a 10 hard sectored disk as a soft sectored disk, with most controllers. My guess is that it is soft sectored double density with 512 byte sectors. Then these numbers make sense.
    Dwight

  3. #13
    Join Date
    Mar 2013
    Location
    Chaffee, MO
    Posts
    1,204

    Default

    Yes, that seems to make more sense. I've conjured up the libdsk definition according to their cpmtools definition:
    Code:
    diskdef exidy
      seclen 512
      tracks 50
      sectrk 8
      blocksize 1024
      maxdir 64
      skew 0
      boottrk 2
      os 2.2
    end
    
    # libdsk data below
    [exidy]
    description = Sorcerer Vista - SSDD 48 tpi 5.25" - 512 x 8
    cylinders = 50
    heads = 1
    secsize = 512
    sectors = 8
    secbase = 0
    datarate = DD
    But my cpmtools version 2.21 doesn't like that definition:
    $ cpmls -f vista -D 033_head0.raw
    *** Error in `cpmls': free(): invalid next size (normal): 0x093cce80 ***
    Aborted
    mmcpm3u1 does locate a valid directory for 033, 037, 049, 051, 055:
    Code:
    $ ./mmcpm3U1 033_head0.raw
    00      0 -backup3.033 
    00   9344   encod2.com 04 05 06 07 08 09 0a 0b 0c 0d 
    00   9344   decod2.com 0e 0f 10 11 12 13 14 15 16 17 
    00  12288    exasm.com 1c 1d 1e 1f 20 21 22 23 24 25 26 27 
    00   2304   mess28.cad 28 29 2a 
    00   8960  diskcat.doc 02 03 31 5f 64 b5 b6 b7 b8 
    00   1536    devcn.com 32 33 
    00   1792 tapedisk.com 34 35 
    00    640 disktape.com 36 
    00   2048 diskcopy.com 37 38 
    00  16384    cbas2.com 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 
    00  20224    cbas2.com 49 4a 4b 4c 
    00  16384    crun2.com 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 
    00  18176    crun2.com 5d 5e 
    00   6784    pass2.com 18 19 1a 1b b9 ba bb 
    00    512 diskdriv.com 60 
    00   2560    bascn.com 61 62 63 
    00   1792  rom2dsk.com bc bd 
    00   6912     xref.com 65 66 67 68 69 6a 6b 
    00   8704    vedit.com 2b 2c 2d 2e 2f 30 6c 6d 6e 
    00  11008 gapbios5.asm 78 79 7a 7b 7c 7d 7e 7f 80 81 82 
    00  10496   myword.com 83 84 85 86 87 88 89 8a 8b 8c 8d 
    00  16384  cadas29.asm 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 
    00  29056  cadas29.asm 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa 
    00   8704  veditzm.set 6f 70 71 72 73 74 75 76 77 
    00   4352   vedset.com ab ac ad ae af 
    00   1024      cat.com b0 
    00   1024     fmap.com b1 
    00   2304     ucat.com b2 b3 b4 
    
    
    $ ./mmcpm3U1 037_head0.raw
    00      0   -music.037 
    00   8448     juke.com 02 03 04 05 06 07 08 09 0a 
    00   7168      pip.com 0b 0c 0d 0e 0f 10 11 
    00   1792        d.com 12 13 
    00   4864    boure.mus 14 15 16 17 18 
    00   2560 mockbird.mus 19 1a 1b 
    00   1536     xmas.mus 1c 1d 
    00   8192    rondo.mus 1e 1f 20 21 22 23 24 25 
    00   4608    waltz.mus 26 27 28 29 2a 
    00   2816    finld.mus 2b 2c 2d 
    00   3328    boogy.mus 2e 2f 30 31 
    00   2816     jesu.mus 32 33 34 
    00   1024    sprng.mus 35 
    00   5376    naila.mus 36 37 38 39 3a 3b 
    00   2816    elean.mus 3c 3d 3e 
    00   1792     fanf.mus 3f 40 
    00   2816    fanta.mus 41 42 43 
    00   5376    maple.mus 44 45 46 47 48 49 
    00   1536      ode.mus 4a 4b 
    00   5376    sting.mus 4c 4d 4e 4f 50 51 
    00   2560    wtell.mus 52 53 54 
    00   1280     yest.mus 55 56 
    00   4864 serenade.mus 57 58 59 5a 5b 
    00  12544   chomp3.com 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 
    00  12544   chomp4.com 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 
    00    256   favor1.med 76 
    00    256   favor2.med 77 
    00  13824   telnet.com 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 
    00   7936      pre.bas 86 87 88 89 8a 8b 8c 8d 
    00   8448     zetu.com 8e 8f 90 91 92 93 94 95 96 
    
    $ ./mmcpm3U1 049_head0.raw
    00   9984  cpm2-56.�om 02 03 04 05 06 07 08 09 0a 0b 
    00   1280 diskcopy.�om 0f 10 
    00   5248    stat2.�om 11 12 13 14 15 16 
    00   9984  cpm2-46.�om 0c 17 18 19 1a 1b 1c 1d 1e 26 
    00   1792     load.�om 1f 20 
    00   4864      ddt.�om 21 22 23 24 25 
    00   1280  read-me.�oc 0d 0e 
    00   1280   submit.�om 2d 2e 
    00    768     xsub.�om 2f 
    00    512     dump.�om 30 
    00   8192      asm.�om 31 32 33 34 35 36 37 38 
    00   4864     ddt1.�om 39 3a 3b 3c 3d 
    00   1280   sysgen.�om 29 2a 
    00    768   format.�om 3f 
    00   4224     dump.�sm 40 41 42 43 44 
    00  12288     bios.�sm 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 
    00   8832    cbios.�sm 51 52 53 54 55 56 57 58 59 
    00  10240  deblock.�sm 5a 5b 5c 5d 5e 5f 60 61 62 63 
    00   6272  diskdef.�ib 64 65 66 67 68 69 6a 
    00  16384    mbios.�ac 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 
    00  24576    mbios.�ac 7b 7c 7d 7e 7f 80 81 82 
    00   1280  submitx.�om 83 84 
    00  11008 vmovcpm2.�om 27 28 2b 2c 3e 85 86 87 88 89 94 
    00   9984  cpm2-44.�om 8a 8b 8c 8d 8e 8f 90 91 92 93 
    00  10240 cp2bios5.�sm 96 97 98 99 9a 9b 9c 9d 9e 9f 
    00   2048      dd3.�om 95 a0 
    00   1024  vsysgen.�om a2 
    00      0 -systemn.049 
    00   7552     pip2.�om a3 a4 a5 a6 a7 a8 a9 aa 
    00  10368 cp2bios4.�sm ab ac ad ae af b0 b1 b2 b3 b4 b5 
    e5      0    mbios.$$$ 
    
    $ ./mmcpm3U1 051_head0.raw
    00      0   -trans.051 
    00   2048      dd3.com 29 2a 
    00  10368 diskdisk.asm 0e 0f 10 11 1b 1c 1d 1e 31 32 44 
    00   2304 diskdisk.doc 33 34 35 
    00   2176  disknew.com 3e 3f 40 
    00   8960  diskold.asm 12 13 14 15 16 17 18 19 1a 
    00   1792  diskold.com 38 39 
    00   7680    dtran.asm 02 03 04 05 06 09 0a 0b 
    00   7552      pdt.asm 1f 20 2b 2c 2d 2e 2f 30 
    00   9344  ramtran.asm 4e 4f 50 51 52 53 54 55 56 57 
    00   1920  ramtran.com 5d 5e 
    00   1408 transcab.doc 0c 0d 
    00   1536 transfer.com 3a 3b 
    00  10240    cpm48.com 07 08 21 22 23 24 25 26 27 28 
    00   2176  dskdsk2.com 36 37 3c 
    e5  16384  dskdsk2.bak 3d 41 42 43 45 46 47 48 49 4a 4b 4c 4d 58 59 5a 
    e5  17280  dskdsk2.bak 5b 
    00  10112  dskdsk2.mac 5c 5f 60 61 62 63 64 65 66 67 
    
    $ ./mmcpm3U1 055_head0.raw
    00      0       -c.055 
    00   4608    clink.com 0d 0e 0f 10 11 
    00   1152        c.ccc 12 13 
    00  12672      cc1.com 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 
    00   3840      chcnt.c 5b 5c 5d 5e 
    00   4736    chcnt.com 3a 3b 3c 3d 6e 
    00   4864     clib.com 40 41 42 43 44 
    00   7936     deff.crl 21 22 23 24 25 26 27 28 
    00   2048      dd3.com 02 03 
    00   6272    float.doc 29 2a 2b 2c 2d 2e 2f 
    00  15744      cc2.com 30 45 46 47 48 49 4a 57 58 59 5f 60 61 62 63 64 
    00    384   rectangl.c 3e 
    00   7680     pip3.com 31 32 33 34 35 36 37 39 
    00    128    plotter.c 38 
    00   5888    deff2.crl 65 66 67 68 69 6b 
    00    768  plotter.crl 6f 
    00   6400    stone.crl 6c 6d 70 71 72 78 79 
    00   8704    stone.com 7a 7b 7c 7d 7e 7f 80 81 82 
    00  11520      stone.c 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 
    00    896 rectangl.crl 3f 
    00    256       test.c 5a 
    00   8960      edv.com 04 05 06 07 08 09 0a 0b 0c 
    00   6784      float.c 83 84 85 86 87 88 89 
    00    768   floatsum.c 8a 
    00   4224  convcad.com 73 74 75 76 77 
    00   5248     bdscio.h 8b 8c 8d 8e 8f 90 
    00    640       conv.c 92 
    00    896    convcad.c 6a 
    00   1408        e2s.c 94 95 
    e5      0   bdscio.$$$ 
    00   5760      e2s.com 96 97 98 99 9a 9b 
    e5   1408      e2s.bak 91 93
    Image 049_head0.raw still needs the edits for the directory entries to correct the modified characters.

    All files in the images appear to extract properly. The random ones I looked at are SANE.


    It would be interesting if that group would add the libdsk definition and try using libdsk to write the floppy, to see how that works in a real exidy computer..
    Code:
    dsktrans -otype floppy 033_head0.raw /dev/fd0
    Thanks.

    Larry
    Last edited by ldkraemer; August 27th, 2019 at 04:27 AM. Reason: added libdsk info

  4. #14
    Join Date
    May 2018
    Location
    Melbourne, Australia
    Posts
    154

    Default

    Quote Originally Posted by ldkraemer View Post
    Y
    It would be interesting if they would try libdsk to write the floppy and see how it works in a real exidy.
    Kryoflux team are never going to do that.
    Do you mean write the image back to a soft-sectored disk with the same geometry as the hard-sector disk and try and boot it on a Sorcerer with some arbitrary soft-sector controller or try and get access to a Sorcerer with a Vista hard sector controller and some blank hard sector media and see if it works?
    All the generic CP/M files extracted so far with either cpmtools definition work on CP/M systems and the Sorcerer specific files work under emulation.

  5. #15
    Join Date
    Mar 2013
    Location
    Chaffee, MO
    Posts
    1,204

    Default

    exidyboy,
    OH that's right it is hard sectored. I keep thinking it's a soft sectored floppy. It's good that all the files are working properly.

    I did notice that the MBIOS.MAC file is missing some characters at the start:
    Code:
    ER
    ;
    ; ** 1 Millisecond Timer DE = delay time in milliseconds
    TIMER:	PUSH	BC
    	PUSH	HL
    	LD	HL,(DCBASE)
    	LD	A,(HL)		;retrigger 4 sec timer Disk
    	LD	B,96
    TI010:	LD	A,B
    TI020:	SUB	001H
    	OR	A
    	JR	NZ,TI020
    	DEC	DE
    	LD	A,E
    	OR	D
    	JR	NZ,TI010
    	POP	HL
    	POP	BC
    	RET
    ;
    ; ** write one sector
    WSECT:	CALL	SLCT
    Do you have a copy that is complete?

    Thanks.

    Larry

  6. #16

    Default

    Ok, I did some more digging.
    Here was a post by exidyboy in another forum:

    "
    Here is an interesting snippet from a 1985 Sorcerer newsletter.

    Different disk controller electronics produce (at least) the following mutually icompatible kinds of track format:

    1) Soft sectored on the lines laid down by IBM in about 1970 and generally embodied in the Western Digital family of chips;
    2) Soft sectoring in any of various ways devised for CBM, Sirius, or Apple;
    3) Hard sector 10 sectors per track (North Star and Vista are similar enough for software to get round their mutual incompatibilities); and
    4) Micropolis 16 sectors per track and either 48 or 100 tpi. The only soft sectored 100 tpi formats I am aware of are used by the Exidy Sorcerer, which started in Micropolis hard sector format and then moved on to soft sector using the same drives, but a different controller card.
    "

    So, it seems that Exidy originally used 16 sector hard sectored disk and then moved to 16 sector soft sectored disk. Now if I get this right, we are trying to squeeze 16 sectored data onto a Exidy using a Vista 10 hard sectored controller. ( cough cough )
    It can't be done without significant driver software changes. The driver code needs to know how many sectors are a disk track. It can't have an arbitrary number of sectors.
    It is possible to modify a Vista controller to handle 16 sectored hard disk with skipping every other hard sectored mark to get 8 hard sectored per track. ( I have a 8 inch machine that uses 32 hard sectored disk but only uses two actual sectors, each being 16 holes long ).
    The next question is data of 8 sectors with each sector being 512 bytes looks like double density. Is the Vista controller single density or double density? You can't squeeze the data down to any sector size you'd like. Again spreading the data over a larger number of tracks requires modification of drivers.

    Now that this is a little clearer, does the Exidy in question have an operating disk running on the Vista controller and using 10 hard sectored disk?
    If so, the data could be extracted from the images and transmitted into the Exidy over something like a serial link and loaded onto a disk using the drivers currently on the Exidy.
    Is that what is being attempted?
    Dwight

  7. #17

    Default

    Reading through things, I'm still confused? It is obvious that the disk imaged by Kryoflux are either soft or hard sectored and 8 sectors long of 512 bytes. That would be double density. If you are seeing this on a floppy with 10 holes, it is not likely recorded in a hard sectored format and squeezed 512 bytes into 8 of those 10 sectors ( at least not likely ). Now were the Vista controller comes into this is the next question that isn't clear.
    I didn't know of any double density hard sectored controllers other than Polymorhic or Victor. I'm not that familiar with the Vista controller.
    Dwight

  8. #18

    Default

    From an advert in ETI Dec 81 p78 - just confirming disk size

    vista_advert.jpg
    Last edited by ChickenMan; August 27th, 2019 at 06:14 PM.

  9. #19

    Default

    Quote Originally Posted by ldkraemer View Post
    exidyboy,
    OH that's right it is hard sectored. I keep thinking it's a soft sectored floppy. It's good that all the files are working properly.

    I did notice that the MBIOS.MAC file is missing some characters at the start:
    Code:
    ER
    ;
    ; ** 1 Millisecond Timer DE = delay time in milliseconds
    TIMER:	PUSH	BC
    	PUSH	HL
    	LD	HL,(DCBASE)
    	LD	A,(HL)		;retrigger 4 sec timer Disk
    	LD	B,96
    TI010:	LD	A,B
    TI020:	SUB	001H
    	OR	A
    	JR	NZ,TI020
    	DEC	DE
    	LD	A,E
    	OR	D
    	JR	NZ,TI010
    	POP	HL
    	POP	BC
    	RET
    ;
    ; ** write one sector
    WSECT:	CALL	SLCT
    Do you have a copy that is complete?

    Thanks.

    Larry
    Yes we do
    Code:
    TITLE CP/M 2.2 CBIOS vers 2.7
    SUBTTL for Lifeboat and Exidy formats
    
    ;CBIOS FOR CP/M 2.2 ON SORCERER UNDER MICROPOLIS
    ;(C) 1980 JOHN WOOLNER AND GREG LISTER
    ;vers 1.5 differs from v1.3 only in the addition of
    ;	BOOTLOC at WARMBOOT + 43H
    ;      (this is the actual cold boot address)
    ;		(THERE IS NO V1.4!!!)
    ;All utilities requiring coldboot termination should use 1.5+
    ;
    ;version 1.6 supports 4 drives.
    ;version 1.7 supports E: drive as Exidy format on B:
    ;version 2.0 supports drive F: G: H: = Exidy CP/M on B: C: D:
    ;version 2.1 returns sector in A as well as L
    ;version 2.2 is adjusted for 128 directories on Exidy
    ;version 2.3 has bug in constat ironed out
    ;version 2.4 has Exidy & Lifeboat names removed
    ;version 2.5 Exidy DPB's fixed, long SLCT time for motor off.
    ;version 2.6 for use with altered CP/M with RUB changed
    ;version 2.7 faster up-to-speed check & drive not up error
    
    ;	5/7/81
    
    ;      Exidy Equates:
    
    lodtim EQU     16		;retries for speed up of disk
    SEND   EQU     0E00CH
    SERIN  EQU     0E00FH
    SEROUT EQU     0E012H
    KEYBRD EQU     0E018H
    VIDEO  EQU     0E01BH
    GETIY  EQU     0E1A2H
    CRLF   EQU     0E205H
    CENDRV EQU     0E997H
    
    BOOTAD	EQU	00A2H		;Micropolis leaves boot
    				;address here
    
    ccp	equ	$-1600h		;Console command processor
    bdos	equ	$-0E00h		;BDOS address
    cdisk	equ	4		;Address of last logged disk
    buff	equ	80h		;Default buffer address
    tpa	equ	100h		;Transient memory
    intioby equ	81H		;Initial IOBYTE
    iobyte	equ	3		;IOBYTE location
    wbot	equ	0		;Warm boot jump address
    entry	equ	5		;BDOS entry jump address
    
    retries equ	10		;Max retries on disk i/o
    				;before error
    step	equ	60h		;steps for disk track
    
    bios	equ	$		;CBIOS starting address
    
    ;*****************************************************
    
    ;here starts CBIOS
    
    	JP	CBOOT
    WBOOTE: JP	WBOOT
    	JP	CONST
    	JP	CONIN
    	JP	CONOUT
    	JP	LIST
    	JP	PUNCH
    	JP	READER
    	JP	HOME
    	JP	SETDRV
    	JP	SETTRK
    	JP	SETSEC
    	JP	SETDMA
    	JP	READ
    	JP	WRITE
    	JP	LISTST		;LIST STATUS
    	JP	SECTRAN
    SINGLE: JP	SLCT1		;HOOK for SINGLE.COM
    
    CONCOLD:  LD	  A,INTIOBY
    	  LD	  (IOBYTE),A
    CWARM:	  RET
    
    TRACK:	DEFB	0FFH		;current track pos
    	DEFB	0FFH		;of each of four
    	DEFB	0FFH		;drives
    	DEFB	0FFH
    TB3FA:	DEFB	76		;max track length of 4 drives
    	DEFB	76
    	DEFB	76
    	DEFB	76
    	DEFB	0
    ;
    	AUTOFLG:  DEFB	11110000b	;(warmboot +42h)
    ;set bit:
    	   ;0=autostart on cold
    	   ;1=auto on warm & cold
    	   ;2=strip linefeeds
    	   ;3=disable directory update
    	   ;4=enable interrupts on return from disk
    	   ;5=no error message on write prot
    	   ;6=verify after write
    	   ;7=verify before write
    
    BOOTLOC:DEFS 2			;(warmboot + 43h)
    
    SINON:	DEFM	'for Micropolis on Sorcerer',0dh,0ah
    	DEFM	'Bios Vers 2.7 (c) 1980 Software Source'
    	DEFM	0DH,0AH,'$'
    
    CBOOT:	LD	HL,(BOOTAD)
    	LD	(DCBASE),HL
    	LD	HL,(BOOTAD-2)	;actual addr of boot
    	LD	(BOOTLOC),HL
    	CALL	CONCOLD
    	XOR	A
    	LD	(CDISK),A	;current disk=A
    	JP	GOCPM
    
    WBOOT:	LD	SP,TPA
    	LD	BC,CCP
    	CALL	SETDMA		;start writing here
    	XOR	A
    	LD	(BIODRV),A	;last accessed drive
    	LD	C,A		;set drive A
    	CALL	SETDRV
    	LD	C,0		;from track
    	LD	L,7		;logical start sector
    	LD	H,30		;no of cpm sectors to read
    	CALL	WRMLOD
    	LD	C,1		;from track
    	LD	L,1		;logical start sector
    	LD	H,14		;no. of cpm sectors to read
    	CALL	WRMLOD
    	CALL	CWARM		;console warm init.
    GOCPM:	LD	A,0C3H		;jump instr
    	LD	(WBOT),A	;write jumps at bottom
    	LD	HL,WBOOTE
    	LD	(WBOT+1),HL
    	LD	(ENTRY),A
    	LD	HL,bdos+6
    	LD	(ENTRY+1),HL
    	LD	BC,BUFF		;default dma
    	CALL	SETDMA
    	LD	A,(CDISK)
    	LD	C,A		;current drive in C
    	XOR	A
    	LD	(DIODRV),A	;set primary drive
    	LD	(BIODRV),A
    	LD	A,(TRACK)	;cold entry? (=FF)
    	INC	A
    	LD	A,(AUTOFLG)
    	JR	NZ,notcld
    	AND	001H
    	JP	NZ,CCP		;auto only on cold
    notcld: AND	002H
    	JP	NZ,CCP		;autostart on warm
    	JP	CCP+3		;no autostart
    
    WRMLOD: LD	(wrmcnt),HL
    	CALL	SETTRK
    WRML1:	LD	HL,wrmcnt
    	LD	C,(HL)		;get sector count
    	CALL	SETSEC
    	CALL	READ
    	JP	NZ,WBOOT	;error:retry
    	LD	HL,(CPMDMA)
    	LD	DE,BUFF
    	ADD	HL,DE
    	LD	(CPMDMA),HL	;move on
    	LD	HL,wrmcnt
    	LD	A,(HL)
    	AND	001H		;returns 1=odd,0=even sector
    	JR	NZ,ODDS
    	LD	A,5		;match skew of cold boot loader
    ODDS:	ADD	A,(HL)
    	DEC	A
    	AND	01FH
    	INC	A
    	LD	(HL),A
    	INC	HL
    	DEC	(HL)
    	JR	NZ,WRML1
    	RET
    ;
    
    SECTRAN: LD	B,0		;C has CP/M sector
    	EX	DE,HL		;DE has table addr
    	ADD	HL,BC		;move to translation
    	LD	A,(HL)		;get new value
    	LD	H,0
    	LD	L,A		;for CP/M
    	DEC	A
    	LD	(CPMSEC),A	;for us
    	INC	A
    	RET
    
    SETDRV: LD	HL,0		;for error
    	LD	A,C		;drive
    	CP	8		;max=4+4 / 6+=EXIDY CP/M
    	RET	NC		;show error
    	LD	DE,DPH0		;disk parameter header
    	CP	4		;E: drive not valid
    	RET	Z		;return with error
    	JR	C,SET1
    	SUB	4
    	LD	C,A
    	LD	DE,DPH3
    SET1:	LD	B,0		;initial count
    	ADD	HL,BC		;in HL
    	ADD	HL,HL		;*16
    	ADD	HL,HL
    	ADD	HL,HL
    	ADD	HL,HL
    	ADD	HL,DE		;select right one
    	INC	A
    	LD	(CPMDRV),A	;tell driver
    	RET
    ;
    HOME:	LD	C,0
    	CALL	SETTRK
    	CALL	SEEK0
    	RET
    ;
    SETTRK: LD	A,C
    	LD	(CPMTRK),A
    	RET
    ;
    SETSEC: LD	A,C
    	DEC	A
    	LD	(CPMSEC),A
    	RET
    ;
    SETDMA: LD	H,B
    	LD	L,C
    	LD	(CPMDMA),HL
    	RET
    ;
    READ:	LD	HL,(CPMSEC)	;sec in H;trk in L
    	LD	A,(DIODRV)	;last write drive
    	OR	A		;buffer empty?
    	JR	Z,AAF5A		;yes--read to it
    	LD	B,A		;save it
    	LD	A,(CPMDRV)	;disk to read
    	CP	B		;did we write to it?
    	JR	NZ,AAF5A	;no- read
    	LD	A,(DIOTRK)	;last written track
    	CP	H		;are we reading?(not on disk)
    	JR	NZ,AAF5A	;no- get from disk
    	LD	A,(DIOSEC)	;last written sector
    	CP	L		;reading it?
    	JR	NZ,AAF5A	;no read disk
    
    ;** here if reading as-yet-unwritten disk sector--
    ;     we just need to transfer the buffer
    	LD	HL,(CPMDMA)	;dma address
    	EX	DE,HL		;in DE
    	LD	HL,HLDBUF	 ;first half of write buffer
    	CALL	AB080		;transfer it
    	XOR	A		;good read flag
    	RET
    
    ;** here if not reading last-written sector
    
    AAF5A:	LD	A,(BIODRV)	;last read drive
    	OR	A		;last write an error?
    	JR	Z,AAF97		;yes: do it again
    	LD	B,A
    	LD	A,(CPMDRV)	;drive to read
    	CP	B		;same as last?
    	JR	NZ,AAF97	;no--do read
    	LD	A,(BIOTRK)	;last read track
    	CP	H		;same?
    	JR	NZ,AAF97	;no: read new
    	LD	A,L		;sector to read
    	AND	0FEH		;make even
    	LD	L,A		;save it
    	LD	A,(BIOSEC)	;sector last read
    	AND	0FEH		;make even
    	CP	L		;do we have it?
    	JR	NZ,AAF97	;no: go get it
    AAF7D:	LD	A,(CPMSEC)	;sector to read (we have it)
    	AND	001H		;Z if even
    	LD	HL,EVNBUF	 ;even buffer (top)
    	JR	Z,AAF8B		;keep even buffer
    	LD	HL,ODDBUF	 ;odd buffer if sector was odd
    AAF8B:	EX	DE,HL		;in DE
    	LD	HL,(CPMDMA)	;where to put it
    	EX	DE,HL		;swap them
    	CALL	AB080		;transfer
    	XOR	A		;ok read flag
    	RET
    
    AAF97:	LD	A,(DIODRV)	;anything in hold buf?
    	OR	A		;test
    	CALL	NZ,FLUSH1	;there was! flush it
    	LD	HL,CPMDRV	;get current read data
    	LD	DE,BIODRV	;make it last read data
    	CALL	LDIR3
    	CALL	AB094		;seek track and read
    	JR	Z,AAF7D		;if ok do buffer xfer
    	XOR	A
    	LD	(BIODRV),A	;bad read last flag
    AB059:	LD	A,1		;error flag to CP/M
    	OR	A
    	RET
    
    WRITE:	LD	HL,(CPMSEC)	;sect & track to write
    	LD	A,(DIODRV)	;last writ
    	OR	A		;test buff empty
    	JR	Z,AB00C		;empty:xfer in & write
    	LD	B,A		;last writ drive
    	LD	A,(CPMDRV)	;drive to write
    	CP	B		;did we last?
    	JR	NZ,FLUSH	;no: need to flush
    	LD	A,(DIOTRK)	;track last writ
    	CP	H		;different?
    	JR	NZ,FLUSH	;yes: flush first
    	LD	A,(DIOSEC)	;sector last writ
    	SUB	L		;different?
    	JR	Z,AB00C		;no:write it out
    	LD	B,A		;save sector offset
    	LD	A,L		;new sector in A
    	RRCA			;carry if odd sector
    	LD	A,B		;offset(=FF if we're writing
    				;next sector)
    				;(=1 if we're writing previous)
    	JR	NC,AAFDE	;sect to write is even
    	CPL			;=0 if we're writing
    				;next odd setor
    	ADD	A,001H		;increment for testing
    AAFDE:	DEC	A		;this will return Z if we're
    				;writing: next odd sector, or
    				;previous even sector
    	JR	NZ,FLUSH	;else we need to flush
    	LD	A,(CPMSEC)	;sector to write
    	AND	001H		;Z if even
    	LD	DE,EVNBUF	 ;even buffer
    	JR	Z,AAFF0		;leave even if Z
    	LD	DE,ODDBUF	 ;odd buffer
    AAFF0:	LD	HL,(CPMDMA)	;where to get
    	CALL	AB080		;xfer it in
    	LD	HL,DIODRV	;make last read=last writ
    	LD	DE,BIODRV	;because we need other
    	CALL	LDIR3		;half of sector
    	CALL	AB05D		;xfers approp buf to write buf
    	CALL	AB09A		;write to disk
    	JP	NZ,AB059	;bad write:return with error
    	XOR	A		;ok write:return with ok flag
    	RET
    
    ;** here to write out to disk
    AB00C:	LD	HL,CPMDRV	;set up
    	LD	DE,DIODRV	;to write
    	CALL	LDIR3		;to right place
    	LD	HL,(CPMDMA)	;get info
    	LD	DE,HLDBUF	 ;and put it
    	CALL	AB080		;in write buffer
    	LD	A,(CPMTRK)	;get track
    	CP	002H		;directory?
    	JR	NZ,AB053	;no:that's all
    	LD	A,(AUTOFLG)
    	AND	008H		;directory update disabled?
    	JR	NZ,AB053	;yes: do no more
    FLUSH1: LD	H,0FFH		;flag for directory write
    FLUSH:	LD	A,H		;get track
    	LD	(SAVIT),A	;store it
    	LD	HL,DIODRV	;last disk io is
    	LD	DE,BIODRV	;last buf io
    	CALL	LDIR3
    	CALL	AB094		;seek & read sector
    	JP	NZ,AB059	;bad read: error
    	CALL	AB05D		;xfers aprop buf to write buf
    	CALL	AB09A		;seek & write sector
    	JP	NZ,AB059	;bad read: error
    	LD	A,(SAVIT)	;restore track
    	INC	A		;directory write?
    	JR	NZ,AB00C	;no : go write it
    AB053:	XOR	A		;else return successfully
    	RET
    
    ;** xfers aprop buffer to write buffer
    AB05D:	LD	A,(DIOSEC)	;last disk io
    	LD	DE,EVNBUF	 ;even buffer
    	AND	001H		;odd?
    	JR	Z,AB06B		;no: leave even
    	LD	DE,ODDBUF	 ;odd buffer
    AB06B:	LD	HL,HLDBUF	 ;write buffer
    	CALL	AB080		;xfer it in
    	XOR	A		;flag for
    	LD	(DIODRV),A	;buffer empty
    	RET
    
    LDIR3:	LD	B,003H
    	JR	AB082
    
    AB080:	LD	B,080H
    AB082:	LD	A,(HL)
    	LD	(DE),A
    	INC	HL
    	INC	DE
    	DJNZ	AB082
    	RET
    
    ;** seeks track zero
    SEEK0:	XOR	A
    	LD	HL,CPMDRV
    	JR	AB09F
    
    ;** seek & read sector
    AB094:	LD	A,001H
    	JR	AB09C
    
    ;** seek & write sector
    AB09A:	LD	A,002H
    
    ;** entry for seek and read/write
    AB09C:	LD	HL,BIODRV
    
    ;** entry for seek0
    AB09F:	LD	DE,DCBFN
    	LD	(DE),A
    	INC	DE
    	CALL	LDIR3
    	LD	HL,DCBUN
    	DEC	(HL)
    	INC	HL
    	LD	A,(HL)
    	RRA
    	AND	07FH
    	LD	(HL),A
    	LD	HL,DCBUF
    	LD	(DCBAD),HL
    	CALL	DSKIO
    	RET
    ;
    DSKIO:	DI			;beginning of microp disk IO
    	LD	(STACK),SP
    	LD	SP,DCBASE
    ;** VALIDATE DISK CONTROL BLOCK
    	LD	HL,DCBFN
    	LD	A,(HL)
    	CP	004H		;function 3 or less
    	JP	NC,PARMER
    	INC	HL
    	LD	A,(HL)
    	CP	004H		;unit address must be less 4
    	JP	NC,PARMER
    	INC	HL
    	LD	A,(HL)
    	CP	010H		;sector must be 15 or less
    	JP	NC,PARMER
    	INC	HL
    	PUSH	HL
    	LD	HL,DCBUN
    	LD	E,(HL)
    	LD	D,000H
    	LD	HL,TB3FA	;base of trakmax table
    	ADD	HL,DE
    	LD	A,(HL)
    	POP	HL
    	SUB	(HL)		;check valid track no.
    	JP	M,PARMER
    	SCF
    ;** ensure drive is operational
    	CALL	SLCT
    ; ** seek desired track
    	CALL	SEEK
    ; ** get func parameter from dcb 
    	LD	A,(DCBFN)
    	OR	A
    	JP	Z,DS100		;done if function is seek only
    ; ** perform read write function
    ; ** retry control for read write
    	LD	A,003H		;retries
    	LD	(L3RTRY),A
    DS030:	LD	A,004H		;retries
    	LD	(L2RTRY),A
    DS040:	LD	A,005H		;retries
    	LD	(L1RTRY),A
    ; ** select desired function and perform
    DS050:	LD	HL,(DCBAD)	;preset buffer address
    	LD	(BUFADR),HL
    	LD	A,(DCBFN)
    	DEC	A
    	JR	NZ,DS060
    ; ** read sector
    	CALL	AB35D		;read sector
    	JR	ERCHK		;check for error
    ;
    DS060:	DEC	A
    	JR	NZ,DS080
    ; ** write sector
    	LD	A,(AUTOFLG)
    	AND	080H		;prewrite read
    	JR	Z,DS070		;write only
    	LD	A,(DCBSC)	;backspace sector
    	DEC	A		;count mod 16
    	AND	00FH
    	LD	B,A
    	CALL	AB38D		;do prewrite hdr
    	JR	NZ,ERCHK	;check abort error
    DS070:	CALL	WSECT		;go write
    	LD	A,(DCBSC)	;do raw checksum
    	LD	B,A		;read check
    	LD	A,(AUTOFLG)
    	AND	040H		;read after write
    	CALL	NZ,AB38D
    	JR	ERCHK		;go check for error
    ;
    DS080:	DEC	A
    	JP	NZ,PARMER	 ;trap just incase
    ; ** verify sector
    	LD	A,(DCBSC)
    	LD	B,A
    	CALL	AB38D		;do checksum read
    ; ** check for error
    ERCHK:	JR	Z,DS100		;no error exit
    	LD	A,(L1RTRY)	;level 1 retry up to 5 times
    	DEC	A
    	LD	(L1RTRY),A
    	JR	NZ,DS050
    	CALL	RESTEP		 ;set off and repeat
    	LD	A,(L2RTRY)	;level 2 upto 4 times
    	DEC	A
    	LD	(L2RTRY),A
    	JR	NZ,DS040
    	CALL	RESLCT		 ;deselect & reselect
    	LD	A,(L3RTRY)	;level 3 upto 3 times
    	DEC	A
    	LD	(L3RTRY),A
    	JP	NZ,DS030
    ; ** unsuccessful abort with perm IO error
    	JP	PERMER
    ; ** end of operation
    ;
    DS100:	XOR	A
    AB18D:	OR	A		;exit disk access
    	PUSH	AF
    	CALL	AB19C
    	POP	AF
    	LD	HL,(STACK)
    	LD	SP,HL
    DB19A:	NOP
    	RET
    ;
    AB19C:	LD	A,(AUTOFLG)
    	AND	010H		;enable interupts after access
    	JR	Z,AB1A6
    	LD	A,0FBH
    AB1A6:	LD	(DB19A),A
    	RET
    ;
    SEEK:  CALL    SLCT	      ;ensure drive selected & ready
    	PUSH	HL
    	CALL	LDTRK		;point HL to track
    	LD	A,0FFH		;see if drive initialised
    	CP	(HL)
    	JR	NZ,SEEK1	;yes continue
    	CALL	RESTOR		 ;calibrate position
    SEEK1:	LD	A,(DCBTK)	;get track from dcb
    	LD	C,A
    	SUB	(HL)		;save in C are we there ?
    	JP	Z,SEEKR		;yes return
    ; ** not at track issue appropriate steps
    	JP	M,SEKOUT
    SEKIN:	CALL	STPIN
    	DEC	A
    	JR	NZ,SEKIN
    	JR	SEEKR1
    ;
    SEKOUT: CALL	STPOUT
    	INC	A
    	JR	NZ,SEKOUT
    SEEKR1: CALL	SETTLE		 ;wait for head to settle
    SEEKR:	LD	(HL),C		;store track
    	POP	HL
    	RET
    ;
    ; ** step in one track
    STPIN:	PUSH	AF
    	PUSH	DE
    	PUSH	HL
    	XOR	A		;set direction flag
    	LD	(DIRCTN),A
    	LD	HL,(DCBASE)
    	LD	(HL),step+1
    STP1:	LD	DE,30		;wait step time
    	CALL	TIMER
    	POP	HL
    	POP	DE
    	POP	AF
    	RET
    ;
    ; ** step out one track
    STPOUT: PUSH	AF
    	PUSH	DE
    	PUSH	HL
    	LD	A,0FFH		;set direction flag
    	LD	(DIRCTN),A
    	LD	HL,(DCBASE)
    	LD	(HL),step	;step out one track
    	JR	STP1
    ; ** wait head settle time
    ;
    SETTLE:	 PUSH	 DE
    	LD	DE,10		;10 milliseconds
    	CALL	TIMER
    	POP	DE
    	RET
    ;
    ; ** step off track one and back
    RESTEP:	 CALL	 LDTRK
    	LD	A,(HL)
    	OR	A
    	JR	NZ,RSTPA
    	CALL	RESTOR		 ;use restore if track zero
    	RET
    ;
    RSTPA:	LD	A,(DIRCTN)
    	OR	A
    	JR	NZ,RSTPB
    	CALL	STPIN
    	CALL	SETTLE
    	CALL	STPOUT
    	CALL	SETTLE
    	RET
    ;
    RSTPB:	CALL	STPOUT
    	CALL	SETTLE
    	CALL	STPIN
    	CALL	SETTLE
    	RET
    ;
    ; ** reselect routine
    RESLCT:	 PUSH	 HL
    	LD	HL,(DCBASE)
    	LD	(HL),0A0H	;reset controller
    	LD	DE,200
    	CALL	TIMER
    	CALL	SLCT	       ;reselect
    	POP	HL
    	CALL	RESTOR
    	JP	SEEK	       ;go reseek
    ;
    ; ** restor track zero
    RESTOR:	 PUSH	 HL
    	PUSH	BC
    	CALL	LDTRK
    	LD	(HL),0FFH
    	CALL	RESTR1		 ;restore to track zero
    	LD	(HL),000H
    	POP	BC
    	POP	HL
    	RET
    ;
    ; ** restore to track zero
    RESTR1:	 PUSH	 HL
    	CALL	SLCT	       ;ensure unit selected
    	PUSH	DE
    	PUSH	BC
    	LD	HL,(DCBASE)	;point to status byte
    	INC	HL
    	LD	A,(HL)
    	AND	008H		;already at track zero ??
    	JR	Z,REST3		;no press on
    ; ** already at track zero step in 8
    	LD	A,008H
    REST2:	CALL	STPIN
    	DEC	A
    	JR	NZ,REST2
    	CALL	SETTLE
    ; ** step out to track zero or 85 steps
    REST3:	LD	C,85		;load max step count
    REST3A: LD	A,(HL)		;track zero ??
    	AND	008H
    	JR	NZ,REST4	;yes press on
    	CALL	STPOUT
    	DEC	C
    	JR	NZ,REST3A
    ; ** max no. of steps ABORT
    	JP	PERMER
    ;
    REST4:	CALL	SETTLE		 ;found track zero settle
    	POP	BC		;and exit
    	POP	DE
    	POP	HL
    	RET
    ;
    ; ** load address of current track on current unit into HL
    LDTRK:	PUSH	DE
    	LD	A,(DCBUN)
    	LD	E,A
    	LD	D,000H
    	LD	HL,TRACK
    	ADD	HL,DE
    	POP	DE
    	RET
    ;
    ; ** error exits
    PERMER:	 LD	 A,001H
    	JP	DS100+1
    ;
    PARMER:	 LD	 A,002H
    	JP	DS100+1
    ;
    DRIVER:	 LD	 A,003H
    	JP	DS100+1
    ;
    PROTER: PUSH	HL
    	LD	HL,WPD
    	CALL	0E1BAH
    	POP	HL
    	LD	A,004H
    	JP	DS100+1
    
    WPD:	DB 13,'Write protected disk',13,10,0
    DNU:	DB 13,'Drive not up - hit a key to continue',0
    ;
    ; ** SELECT DRIVE SPECIFIED BY UNIT ADDRESS IN DCB
    SLCT:  PUSH    DE
    	PUSH	BC
    	PUSH	HL
    SLCTX:	LD	HL,(DCBASE)	;get controller address
    	LD	A,(DCBUN)	;get unit address
    	LD	C,A		;for SINGLE.COM
    	JP	SINGLE		;will normally return to SLCT1
    SLCT1:	LD	B,C
    	INC	HL		;point to status
    	LD	A,(HL)
    	LD	C,A
    	AND	007H		;mask usld & addr
    	XOR	B		;desired unit prev
    				;** THIS TEST WILL FAIL IF
    				;** CONTROLLER NOT PLUGGED IN
    	LD	A,C		;selected ??
    	JR	Z,SL010		;yes check ready
    	LD	A,B		;get unit addr
    	OR	020H		;build command
    	LD	(HL),A		;out command
    	LD	A,LODTIM
    SLCT3:	EX	AF,AF'          ;save counter
    	LD	DE,250		;WAIT- head load, speed, sector
    	CALL	TIMER
    	LD	A,(HL)
    	AND	007H		;selected now
    	XOR	B
    	LD	A,(HL)		;get status
    	JR	NZ,SL020	;error if not select
    SL010:	AND	020H		;ensure unit ready
    	XOR	020H
    	JR	Z,SL020
    SLCT2:	EX	AF,AF'          ;get counter
    	DEC	A		;any more?
    	JR	NZ,SLCT3	;no flip out
    	LD	HL,DNU
    	CALL	0E1BAH		;print 'drive not up'
    	CALL	CONIN		;wait for keypress
    	CALL	0E205H		;start with c/r
    	JR	SLCTX		;try again this time
    SL020:	POP	HL
    	POP	BC
    	POP	DE
    	RET	Z		;return if O.K.
    ; ** DRIVE NOT UP ERROR
    	JP	DRIVER
    ;
    ; ** 1 Millisecond Timer DE = delay time in milliseconds
    TIMER:	PUSH	BC
    	PUSH	HL
    	LD	HL,(DCBASE)
    	LD	A,(HL)		;retrigger 4 sec timer Disk
    	LD	B,96
    TI010:	LD	A,B
    TI020:	SUB	001H
    	OR	A
    	JR	NZ,TI020
    	DEC	DE
    	LD	A,E
    	OR	D
    	JR	NZ,TI010
    	POP	HL
    	POP	BC
    	RET
    ;
    ; ** write one sector
    WSECT:	CALL	SLCT
    	LD	A,(DCBSC)
    	LD	B,A
    	PUSH	BC
    	LD	C,134		;sector length/2
    	LD	HL,(DCBASE)
    	PUSH	HL
    	INC	HL		;read status
    	LD	A,(HL)		;abort if write protect
    	AND	010H
    	JR	Z,AB320
    	LD	A,(AUTOFLG)
    	AND	020H		;write protect detect
    	JP	NZ,PROTER
    AB320:	LD	HL,(BUFADR)
    	PUSH	HL
    	POP	DE
    	LD	A,(DCBTK)	;move track & sector ID to
    	LD	(HL),A		;write buffer
    	INC	HL
    	LD	(HL),B
    	LD	HL,(DCBASE)
    	CALL	GETSEC		 ;wait for sector
    ; ** found desired sector enable write
    	LD	(HL),080H
    	INC	HL
    WS010:	OR	(HL)
    	JP	P,WS010		;wait for transfer flag
    	INC	HL
    	LD	(HL),0FFH	;insert synch byte
    	XOR	A
    	EX	DE,HL
    	LD	B,A		;clear carry & chksum
    ; ** write header and data fields
    WS020:	LD	A,(HL)
    	LD	(DE),A		;see below
    	ADC	A,B
    	LD	B,A
    	INC	HL
    	LD	A,(HL)		;get byte from memory
    	LD	(DE),A		;onto disk
    	ADC	A,B
    	LD	B,A		;add to chksum
    	INC	HL
    	DEC	C
    	JR	NZ,WS020
    	LD	A,B
    	LD	(DE),A		;write chksum
    ; ** wait for end of sector
    	POP	HL
    	XOR	A
    WS030:	OR	(HL)		;wait for sector flag
    	JP	P,WS030
    	LD	DE,1
    	CALL	TIMER		;wait 1 millisec for erase
    				;delay
    	POP	BC
    	RET
    ;
    ; ** read one sector verify chksum
    ;(return Z=ok NZ=error)
    ;
    AB35D:	CALL	SLCT
    	LD	A,(DCBSC)
    	LD	B,A
    	PUSH	BC
    	LD	C,134
    	CALL	WTSYNC		 ;wait desired sector & sync
    				 ;byte
    ; ** found desired sector  read
    	EX	DE,HL
    	LD	B,000H		;clear chksum
    RDA10:	LD	A,(DE)		;read from disk
    	LD	(HL),A		;into buffer
    	INC	HL
    	ADC	A,B		;add chksum
    	LD	B,A
    	LD	A,(DE)
    	LD	(HL),A		;and again
    	INC	HL
    	ADC	A,B
    	LD	B,A
    	DEC	C		;end of data ??
    	JR	NZ,RDA10	;no loop
    	LD	A,(DE)		;read chksum
    RDA020: CP	B		;compare chksum
    	POP	BC
    	RET	NZ		;return if error
    	LD	HL,(BUFADR)	 ;chksum ok
    	EX	DE,HL
    	CALL	LDTRK
    	LD	A,(DE)
    	CP	(HL)		;compare track id
    	RET	NZ
    	INC	DE
    	LD	A,(DE)
    	CP	B		;compare sector
    	RET
    ;
    ; ** VERIFY SECTOR ( in B ) NO READ INTO MEMORY
    AB38D:	PUSH	BC
    	CALL	SLCT
    	LD	C,133		;sect length -1
    	CALL	WTSYNC
    	LD	B,000H		;clear chksum
    	LD	A,(HL)
    	LD	(DE),A
    	ADC	A,B		;read & add track
    	LD	B,A
    	INC	DE
    	LD	A,(HL)
    	LD	(DE),A		;read & add sector ID's
    	ADC	A,B
    	LD	B,A
    	NOP
    RDCK10: LD	A,(HL)
    	ADC	A,B
    	LD	B,A
    	NOP			;read remainder of sector
    	NOP
    	LD	A,(HL)
    	ADC	A,B
    	LD	B,A
    	DEC	C
    	JR	NZ,RDCK10
    ; ** end of data read chksum
    	LD	A,(HL)
    	JR	RDA020
    ;
    ; ** wait for sector & sync byte
    WTSYNC:	 LD	 HL,(BUFADR)
    	EX	DE,HL
    	LD	HL,(DCBASE)
    	CALL	GETSEC		 ;wait for sector
    	INC	HL
    WTS010: OR	(HL)
    	JP	P,WTS010	;wait for transfer ready flag
    	INC	HL
    	LD	A,(HL)
    	XOR	A		;read in sync byte throw it
    				;away
    	RET			;clear carry & read
    ;
    ; ** wait for desired sector
    GETSEC:	 LD	 A,(HL)		 ;wait for sector flag
    	OR	A
    	JP	P,GETSEC
    	AND	00FH
    	XOR	B		;is it the one ??
    	JR	NZ,GETSEC	 ; no go wait
    	RET			;yes then return
    ;************************************************
    ;************************************************
    ;		 CONSOLE I/O ROUTINES
    
    CONST:	LD	HL,LSTCHR	;point HL to LSTCHR for future
    	LD	A,(HL)		;do we alraedy have a key held
    	OR	A
    	JR	NZ,READY	;yes, no more to do
    	LD	B,00FH
    AB421:	LD	A,B
    	OUT	(0FEH),A
    	IN	A,(0FEH)
    	CPL
    	AND	01FH
    	JR	NZ,AB43C
    	DJNZ	AB421
    HANG:	XOR	A
    	OUT	(0FEH),A
    	IN	A,(0FEH)
    	BIT	0,A		;run/stop?
    	JR	NZ,NORUN
    	BIT	2,A		;r/s + ctrl?
    	JR	NZ,HANG		;no: hang it
    	AND	00010111b	;All three?
    	JP	Z,0000		;yes: warm boot
    	BIT	4,A		;+ SHF?
    	JP	Z,0E003H	;yep:EXIDY MONITOR
    	BIT	1,A		;+ graphic?
    	JR	NZ,HANG		;no- just wait
    	LD	HL,(BOOTLOC)	;controller address
    	JP	(HL)		;jump cold boot
    NORUN:	XOR	A
    	RET
    ;
    AB43C:	CALL	KEYBRD		;if key pressed then get it
    	JP	M,SPEED0
    	LD	(HL),A
    	OR	A
    	RET	Z
    READY:	LD	A,0FFH		;exit with 0ffh used by other
    				;routines as well
    	RET
    ;
    CONIN:	CALL	CONST
    	JR	Z,CONIN		;see if key is waiting for us
    	LD	A,(HL)		;get the char
    	LD	(HL),0
    	CP	07FH
    	JR	NZ,SWP1
    	LD	A,08H
    	RET
    SWP1: 
    	CP	8
    	RET	NZ
    	LD	A,07FH
    	RET
    
    ;
    SPEED0: AND	07FH		;if Gpaphics + pressed then
    	PUSH	IY		;change the console speed
    	CALL	GETIY
    	LD	(IY+03EH),A
    	POP	IY
    	XOR	A		;return a no key pressed
    	RET
    ;
    CONOUT: LD	A,C
    	OR	A
    	RET	Z
    	CP	8
    	JR	Z,AB488		;trap a DESTRUCTIVE backsapace,
    				;it really IS
    	CP	1
    	JR	Z,LFTONE	;detect a left shift to inc
    				;count
    	LD	A,(COLCNT)
    	DEC	A
    	JR	NZ,AB473
    	CALL	CRLF
    	LD	A,041H		;one less because next char is
    				;not a LF
    AB473:	LD	(COLCNT),A
    	LD	A,C
    	CALL	SEND
    	CP	00DH
    	JR	Z,AB482
    	CP	00CH
    	RET	NZ
    AB482:	LD	A,042H		;must disregard the count of
    				;the linefeed
    	LD	(COLCNT),A
    	RET
    ;
    AB488:
    	LD	A,001H
    	CALL	VIDEO
    	LD	A,020H
    	CALL	VIDEO
    	LD	A,001H
    LFTONE: CALL	VIDEO
    	LD	A,(COLCNT)
    	INC	A
    	LD	(COLCNT),A
    	RET
    ;
    LISTST: IN	A,(0FFH)
    	AND	080H
    	RET	Z
    	OR	0FFH
    	RET
    ;
    LIST:	CALL	GETIY
    	CALL	GETIY
    	LD	A,(AUTOFLG)
    	BIT	2,A
    	LD	A,C
    	PUSH	AF
    	JP	Z,CENDRV
    	JP	CENDRV+4
    ;
    PUNCH:	LD	A,C
    	CALL	SEROUT
    	RET
    ;
    READER: CALL	SERIN
    	RET
    ;
    LSTCHR:	 DEFB	0		;character for input
    COLCNT:	 DEFB	 0		;screen column count
    
    DPBM5:	DEFW	32		;SPT (sects/track)
    	DEFB	4		;BSH (For BLS=2048)
    	DEFB	15		;BLM (for BLS=2048)
    	DEFB	0		;EXM (no more than 16K per
    				;directory entry)
    	DEFW	149		;blocks on disk
    	DEFW	63		;max no of directory entries-1
    	DEFB	80H,0		;AL0,AL1 Reserve directory
    				;blocks
    	DEFW	16		;CKS Directory Checkspace
    	DEFW	2		;System trax
    	DEFB	1		;16*CPM SECTS/PHYS SEC
    
    DPBMX:	DEFW	32		;SPT (sects/track)
    	DEFB	4		;BSH (For BLS=2048)
    	DEFB	15		;BLM (for BLS=2048)
    	DEFB	0		;EXM (no more than 16K per
    				;directory entry)
    	DEFW	149		;blocks on disk
    	DEFW	127		;max no of directory entries-1
    	DEFB	0C0H,0		;AL0,AL1 Reserve directory
    				;blocks
    	DEFW	16		;CKS Directory Checkspace
    	DEFW	2		;System trax
    	DEFB	1		;16*CPM SECTS/PHYS SEC
    
    DPH0:	DEFW	XLTM5
    	DEFW	0
    	DEFW	0
    	DEFW	0
    	DEFW	SCRATCH
    	DEFW	DPBM5
    	DEFW	CSV0
    	DEFW	ALV0
    	
    DPH1:	DEFW	XLTM5
    	DEFW	0
    	DEFW	0
    	DEFW	0
    	DEFW	SCRATCH
    	DEFW	DPBM5
    	DEFW	CSV1
    	DEFW	ALV1
    	
    DPH2:	DEFW	XLTM5
    	DEFW	0
    	DEFW	0
    	DEFW	0
    	DEFW	SCRATCH
    	DEFW	DPBM5
    	DEFW	CSV2
    	DEFW	ALV2
    	
    DPH3:	DEFW	XLTM5
    	DEFW	0
    	DEFW	0
    	DEFW	0
    	DEFW	SCRATCH
    	DEFW	DPBM5
    	DEFW	CSV3
    	DEFW	ALV3
    	
    DPH4:	DEFW	XLTMX
    	DEFW	0
    	DEFW	0
    	DEFW	0
    	DEFW	SCRATCH
    	DEFW	DPBMX
    	DEFW	CSV4
    	DEFW	ALV4
    	
    DPH5:	DEFW	XLTMX
    	DEFW	0
    	DEFW	0
    	DEFW	0
    	DEFW	SCRATCH
    	DEFW	DPBMX
    	DEFW	CSV5
    	DEFW	ALV5
    	
    DPH6:	DEFW	XLTMX
    	DEFW	0
    	DEFW	0
    	DEFW	0
    	DEFW	SCRATCH
    	DEFW	DPBMX
    	DEFW	CSV6
    	DEFW	ALV6
    	
    XLTM5:	DEFB	1,2,11,12,21,22,31,32,9,10,19,20,29,30
    	DEFB	7,8,17,18,27,28,5,6,15,16,25,26,3,4,13,14,23,24
    XLTMX:: DEFB	11,12,21,22,31,32,9,10,19,20,29,30,7,8,17
    	DEFB	18,27,28,5,6,15,16,25,26,3,4,13,14,23,24,1,2
    
    CSV0:	DEFS	16
    ALV0:	DEFS	20
    CSV1:	DEFS	16
    ALV1:	DEFS	20
    CSV2:	DEFS	16
    ALV2:	DEFS	20
    CSV3:	DEFS	16
    ALV3:	DEFS	20
    CSV4:	DEFS	32
    ALV4:	DEFS	20
    CSV5:	DEFS	32
    ALV5:	DEFS	20
    CSV6:	DEFS	32
    ALV6:	DEFS	20
    SCRATCH: DEFS	 128
    
    	DEFS	40		;for Micropolis Stack
    
    DCBASE: DEFS	2
    DCBFN:	DEFS	1		;function parameter
    DCBUN:	DEFS	1		;drive addressed
    DCBSC:	DEFS	1		;sector address
    DCBTK:	DEFS	1		;track address
    DCBAD:	DEFS	2		;address of dcbuf
    BUFADR: DEFS	2
    L1RTRY: DEFS	1		;level 1 retry count
    L2RTRY: DEFS	1		;level 2 retry count
    L3RTRY: DEFS	1		;level 3 retry count
    DIRCTN: DEFS	1		;direction flag:0=in, FF=out
    CPMDMA: DEFS	2
    CPMDRV: DEFS	1
    CPMSEC: DEFS	1
    CPMTRK: DEFS	1
    BIODRV: DEFS	1		;last buffer io addresses
    BIOSEC: DEFS	1
    BIOTRK: DEFS	1
    DIODRV: DEFS	1		;last disk io addresses
    DIOSEC: DEFS	1
    DIOTRK: DEFS	1
    wrmcnt: DEFS	2		;scratch for warmlod
    SAVIT:	DEFS	1		;scratchpad
    STACK:	DEFS	2		;CP/M stack saved here
    HLDBUF: DEFS	128		;holding buffer
    DCBUF:	DEFS	12		;micropolis buffer start
    EVNBUF: DEFS	128		;CP/M SECTOR #1
    ODDBUF: DEFS	128		;CP/M SECTOR #2
    
    ENDFLAG::
    IF2
    IF ENDFLAG-WBOOTE GT 3149
    .PRINTX * ASSEMBLY TOO LONG *
    ENDIF
    ENDIF
    	END

  10. #20
    Join Date
    May 2018
    Location
    Melbourne, Australia
    Posts
    154

    Default

    The presence of the source code for a 16 sector Micropolis BIOS on one of the disks imaged does not mean that is what has been assembled and is actually running on the system tracks of these Vista disks. It merely serves as an example of the validity of the cpmtools definition as evidenced by successful file extraction.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •