DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦4c0af9d8e⟧ TextFile

    Length: 8704 (0x2200)
    Types: TextFile
    Names: »DUP2.HEX«

Derivation

└─⟦0d02879d3⟧ Bits:30004605 COMPAS Pascal version 3.03
    └─ ⟦this⟧ »DUP2.HEX« 

TextFile

;	MDS-800 I/O Drivers for CP/M 2.2
;	(four drive single density version)
;
;	Version 2.2 February, 1980
;
vers	equ	22	;version 2.2
;
;	Copyright (c) 1980
;	Digital Research
;	Box 579, Pacific Grove
;	California, 93950
;
;
true	equ	0ffffh	;value of "true"
false	equ	not true	;"false"
test	equ	false	;true if test bios
;
	if	test
bias	equ	03400h	;base of CCP in test system
	endif
	if	not test
bias	equ	0000h	;generate relocatable cp/m system
	endif
;
patch	equ	1600h
;
	org	patch
cpmb	equ	$-patch	;base of cpm console processor
bdos	equ	806h+cpmb	;basic dos (resident portion)
cpml	equ	$-cpmb	;length (in bytes) of cpm system
nsects	equ	cpml/128	;number of sectors to load
offset	equ	2	;number of disk tracks used by cp/m
cdisk	equ	0004h	;address of last logged disk on warm start
buff	equ	0080h	;default buffer address
retry	equ	10	;max retries on disk i/o before error
;
;	perform following functions
;	boot	cold start
;	wboot	warm start (save i/o byte)
;	(boot and wboot are the same for mds)
;	const	console status
;		reg-a = 00 if no character ready
;		reg-a = ff if character ready
;	conin	console character in (result in reg-a)
;	conout	console character out (char in reg-c)
;	list	list out (char in reg-c)
;	punch	punch out (char in reg-c)
;	reader	paper tape reader in (result to reg-a)
;	home	move to track 00
;
;	(the following calls set-up the io parameter block for the
;	mds, which is used to perform subsequent reads and writes)
;	seldsk	select disk given by reg-c (0,1,2...)
;	settrk	set track address (0,...76) for subsequent read/write
;	setsec	set sector address (1,...,26) for subsequent read/write
;	setdma	set subsequent dma address (initially 80h)
;
;	(read and write assume previous calls to set up the io parameters)
;	read	read track/sector to preset dma address
;	write	write track/sector from preset dma address
;
;	jump vector for indiviual routines
	jmp	boot
wboote:	jmp	wboot
	jmp	const
	jmp	conin
	jmp	conout
	jmp	list
	jmp	punch
	jmp	reader
	jmp	home
	jmp	seldsk
	jmp	settrk
	jmp	setsec
	jmp	setdma
	jmp	read
	jmp	write
	jmp	listst	;list status
	jmp	sectran
;
	maclib	diskdef	;load the disk definition library
	disks	4	;four disks
	diskdef	0,1,26,6,1024,243,64,64,offset
	diskdef	1,0
	diskdef	2,0
	diskdef	3,0
;	endef occurs at end of assembly
;
;	end of controller - independent code, the remaining subroutines
;	are tailored to the particular operating environment, and must
;	be altered for any system which differs from the intel mds.
;
;	the following code assumes the mds monitor exists at 0f800h
;	and uses the i/o subroutines within the monitor
;
;	we also assume the mds system has four disk drives
revrt	equ	0fdh	;interrupt revert port
intc	equ	0fch	;interrupt mask port
icon	equ	0f3h	;interrupt control port
inte	equ	0111$1110b	;enable rst 0(warm boot), rst 7 (monitor)
;
;	mds monitor equates
mon80	equ	0f800h	;mds monitor
rmon80	equ	0ff0fh	;restart mon80 (boot error)
ci	equ	0f803h	;console character to reg-a
ri	equ	0f806h	;reader in to reg-a
co	equ	0f809h	;console char from c to console out
po	equ	0f80ch	;punch char from c to punch device
lo	equ	0f80fh	;list from c to list device
csts	equ	0f812h	;console status 00/ff to register a
;
;	disk ports and commands
base	equ	78h	;base of disk command io ports
dstat	equ	base	;disk status (input)
rtype	equ	base+1	;result type (input)
rbyte	equ	base+3	;result byte (input)
;
ilow	equ	base+1	;iopb low address (output)
ihigh	equ	base+2	;iopb high address (output)
;
readf	equ	4h	;read function
writf	equ	6h	;write function
recal	equ	3h	;recalibrate drive
iordy	equ	4h	;i/o finished mask
cr	equ	0dh	;carriage return
lf	equ	0ah	;line feed
;
signon:	;signon message: xxk cp/m vers y.y
	db	cr,lf,lf
	if	test
	db	'32'	;32k example bios
	endif
	if	not test
	db	'00'	;memory size filled by relocator
	endif
	db	'k CP/M vers '
	db	vers/10+'0','.',vers mod 10+'0'
	db	cr,lf,0
;
boot:	;print signon message and go to ccp
;	(note: mds boot initialized iobyte at 0003h)
	lxi	sp,buff+80h
	lxi	h,signon
	call	prmsg	;print message
	xra	a	;clear accumulator
	sta	cdisk	;set initially to disk a
	jmp	gocpm	;go to cp/m
;
;
wboot:;	loader on track 0, sector 1, which will be skipped for warm 
;	read cp/m from disk - assuming there is a 128 byte cold start
;	start.
;
	lxi	sp,buff	;using dma - thus 80 thru ff available for stack
;
	mvi	c,retry	;max retries
	push	b
wboot0:	;enter here on error retries
	lxi	b,cpmb	;set dma address to start of disk system
	call	setdma
	mvi	c,0	;boot from drive 0
	call	seldsk
	mvi	c,0
	call	settrk	;start with track 0
	mvi	c,2	;start reading sector 2
	call	setsec
;
;	read sectors, count nsects to zero
	pop	b	;10-error count
	mvi	b,nsects
rdsec:	;read next sector
	push	b	;save sector count
	call	read
	jnz	booterr	;retry if errors occur
	lhld	iod	;increment dma address
	lxi	d,128	;sector size
	dad	d	;incremented dma address in hl
	mov	b,h
	mov	c,l	;ready for call to set dma
	call	setdma
	lda	ios	;sector number just read
	cpi	26	;read last sector?
	jc	rd1
;	must be sector 26, zero and go to next track
	lda	iot	;get track to register a
	inr	a
	mov	c,a	;ready for call
	call	settrk
	xra	a	;clear sector number
rd1:	inr	a	;to next sector
	mov	c,a	;ready for call
	call	setsec
	pop	b	;recall sector count
	dcr	b	;done?
	jnz	rdsec
;
;	done with the load, reset default buffer address
gocpm:	;(enter here from cold start boot)
;	enable rst0 and rst7
	di
	mvi	a,12h	;initialize command
	out	revrt
	xra	a
	out	intc	;cleared
	mvi	a,inte	;rst0 and rst7 bits on
	out	intc
	xra	a
	out	icon	;interrupt control
;
;	set default buffer address to 80h
	lxi	b,buff
	call	setdma
;
;	reset monitor entry points
	mvi	a,jmp
	sta	0
	lxi	h,wboote
	shld	1	;jmp wboot at location 00
	sta	5
	lxi	h,bdos
	shld	6	;jmp bdos at location 5
	if	not test
	sta	7*8	;jmp to mon80 (may have been changed by ddt)
	lxi	h,mon80
	shld	7*8+1
	endif
;	leave iobyte set
;	previously selected disk was b, send parameter to cpm
	lda	cdisk	;last logged disk number
	mov	c,a	;send to ccp to log it in
	ei
	jmp	cpmb
;
;	error condition occurred, print message and retry
booterr:
	pop	b	;recall counts
	dcr	c
	jz	booter0
;	try again
	push	b
	jmp	wboot0
;
booter0:
;	otherwise too many retries
	lxi	h,bootmsg
	call	prmsg
	jmp	rmon80	;mds hardware monitor
;
bootmsg:
	db	'?boot',0
;
;
const:	;console status to reg-a
;	(exactly the same as mds call)
	jmp	csts
;
conin:	;console character to reg-a
	call	ci
	ani	7fh	;remove parity bit
	ret
;
conout:	;console character from c to console out
	jmp	co
;
list:	;list device out
;	(exactly the same as mds call)
	jmp	lo
;
listst:
	;return list status
	xra	a
	ret		;always not ready
;
punch:	;punch device out
;	(exactly the same as mds call)
	jmp	po
;
reader:	;reader character in to reg-a
;	(exactly the same as mds call)
	jmp	ri
;
home:	;move to home position
;	treat as track 00 seek
	mvi	c,0
	jmp	settrk
;
seldsk:	;select disk given by register c
	lxi	h,0000h	;return 0000 if error
	mov	a,c
	cpi	ndisks	;too large?
	rnc		;leave HL = 0000
;
	ani	10b	;00 00 for drive 0,1 and 10 10 for drive 2,3
	sta	dbank	;to select drive bank
	mov	a,c	;00, 01, 10, 11
	ani	1b	;mds has 0,1 at 78, 2,3 at 88
	ora	a	;result 00?
	jz	setdrive
	mvi	a,00110000b	;selects drive 1 in bank
setdrive:
	mov	b,a	;save the function
	lxi	h,iof	;io function
	mov	a,m
	ani	11001111b	;mask out disk number
	ora	b	;mask in new disk number
	mov	m,a	;save it in iopb
	mov	l,c
	mvi	h,0	;HL=disk number
	dad	h	;*2
	dad	h	;*4
	dad	h	;*8
	dad	h	;*16
	lxi	d,dpbase
	dad	d	;HL=disk header table address
	ret
;
;
settrk:	;set track address given by c
	lxi	h,iot
	mov	m,c
	ret
;
setsec:	;set sector number given by c
	lxi	h,ios
	mov	m,c
	ret
sectran:
		;translate sector bc using table at de
	mvi	b,0	;double precision sector number in BC
	xchg		;translate table address to HL
	dad	b	;translate(sector) address
	mov	a,m	;translated sector number to A
	sta	ios
	mov	l,a	;return sector number in L
	ret
;
setdma:	;set dma address given by regs b,c
	mov	l,c
	mov	h,b
	shld	iod
	ret
;
read:	;read next disk record (assuming disk/trk/sec/dma set)
	mvi	c,readf	;set to read function
	call	setfunc
	call	waitio	;perform read function
	ret		;may have error set in reg-a
;
;
write:	;disk write function
	mvi	c,writf
	call	setfunc	;set to write function
	call	waitio
	ret		;may have error set
;
;
;	utility subroutines
prmsg:	;print message at h,l to 0
	mov	a,m
	ora	a	;zero?
	rz
;	more t