CP/M RMAC ASSEM 1.1	#001	RAMDISK - DRIVER FOR PROF 80

                	title 'RAMDISK - Driver for PROF 80'
                
                        page 56
                
                ;	COMMON CODE SEGMENT :
                ;	=====================
                
                	maclib	cdef		; system definitions
                
U               	if 	RAMDISK		; logical, isn't it ?
                
                	public	rdsd0		; link into drive table
                
                	extrn	@dma,@trk,@sect	; r/w parameter
                	extrn	@dbnk,@cbnk	; disk bank, current bank
                	extrn	cdma		; common DMA buffer
                	extrn	@date		; actual date in SCB
                
                	extrn	?bank		; bank switch code
                	extrn	?time		; get actual time
                	extrn	?move,?xmove	; interbank move code
                
                	maclib	cpm3		; use DR macros
                
                	maclib	z80		; use Z80 opcodes
                
                
                ;	eXtended Disk Parameter Header (XPDH) :
                ;	=======================================
                
                	dseg
                
                	dw	write
                	dw	read
                	dw	login
                	dw	init
                	db	12,0		; relative drive M:
                rdsd0:	dph	SVT,dpb0,0	; rest by GENCPM
                
                
                ; 	Disk Parameter Block ( DPB ) :
                ;	==============================
                
                	cseg
                
                dpb0:	dpb	PSS,PST,TN,BSI,ENT,STO,CSS
                
                
                ;	Automatic Init of Ramdisk :
                ;	===========================
                
                	dseg
                
                init:	lda	dpb0+13		; possibly system tracks
                	sta	@trk		; set directory track
                	xra	a		; set sector 0, disk bank 0
CP/M RMAC ASSEM 1.1	#002	RAMDISK - DRIVER FOR PROF 80

                	sta	@sect
                	sta	@dbnk
                	lxi	h,cdma		; set common dma address
                	shld	@dma
                	call	read		; read this sector into buffer
                
                	lxi	d,rtest		; first entry is label RAMDISK
                	lxi	h,cdma
                	mvi	b,12
                
                initt:	ldax	d		; testbyte
                	cmp	m		; label byte
                	jrnz	doinit		; if not equal then init ramdisk
                	inx	d		; else next byte
                	inx	h
                	djnz	initt		; until ready
                	ret
                
                rtest:	db	' RAMDISK '	; label entry for ramdisk
                	db	'   ',61h	; label=on, access=on, update=on
                
                doinit:	mvi	b,128		; clear dma buffer
                	lxi	h,cdma
                doinic:	mvi	m,0		; all zeros
                	inx	h
                	djnz	doinic
                
                	mvi	a,0E5h		; set up 3 dir entrys
                	sta	cdma
                	sta	cdma+32
                	sta	cdma+64
                
                	mvi	a,021h		; set up 1 time entry
                	sta	cdma+96
                
                	mvi	a,1		; start with sector 1
                	sta	@sect
                	lhld	dpb0+7		; calc number of dir records
                	srlr	h		; 32 bytes / dir entry
                	rarr	l
                	srlr	h
                	rarr	l
                	
                doinil:	push	h		; save it
                	call	write		; write sector back to ramdisk
                	lda	@sect		; next one
                	inr	a
                	sta	@sect
                	pop	h
                	dcr	l
                	jrnz	doinil		; until all directory records written
                
                	xra	a		; now write sector 0
                	sta	@sect
                
                	lxi	h,rtest		; set ramdisk label
CP/M RMAC ASSEM 1.1	#003	RAMDISK - DRIVER FOR PROF 80

                	lxi	d,cdma
                	lxi	b,13
                	ldir
                
                	mvi	c,0		; set actual time in SCB
                	call	?time
                
                	lxi	h,@date		; set time entries
                	lxi	d,cdma+24
                	lxi	b,4
                	ldir
                	lxi	h,@date
                	lxi	b,4
                	ldir
                	lxi	h,@date
                	lxi	d,cdma+97
                	lxi	b,4
                	ldir
                	lxi	h,@date
                	lxi	b,4
                	ldir
                
                	jr	write		; write sector back
                
                
                ;	log in the drive :
                ;	==================
                
                login:	ret			; nothing to do
                
                
                ;	CODE ONLY FOR KAYSER RAMDISK :
                ;	==============================
                
                	if	KAYSER
                
                inop	equ	0B2h		; difference between OTIR and INIR
                outop	equ	0B3h
                
                
                ;	write a sector :
                ;	================
                
                write:	mvi	c,RD$BASIS-9	; ramdisk state register address of card 4
                	lda	@trk		; which card ?
                	rar			; card-number in bit 5,6 of @trk
                	rar
                	rar
                	cma
                	ani	00001100b	; now <A> holds Offset to <C>
                	add	c
                	mov	c,a		; <C> points to state register of ramcard
                	inp	a		; ramdisk protected ?
                	bit	1,a
                	mvi	a,2		; yes : disk is read-only
                	rnz
CP/M RMAC ASSEM 1.1	#004	RAMDISK - DRIVER FOR PROF 80

                	mvi	a,outop		; OTIR - opcode 2nd byte
                	jr	rwcom
                
                ;	read a sector :
                ;	===============
                
                
                read:	mvi	a,inop		; INIR - opcode 2nd byte
                
                
                ;	common r/w - code :
                ;	===================
                
                rwcom:	sta	irloc+1		; set transfer direction
                	mvi	c,RD$BASIS-11	; ramdisk track register address of card 4
                	lda	@trk		; which card ?
                	rar			; card-number in bit 5,6 of @trk
                	rar
                	rar
                	cma
                	ani	00001100b	; now <A> holds Offset to <C>
                	add	c
                	mov	c,a		; <C> points to track register of ramcard
                	lda	@trk		; set track & sector register
                	outp	a
                	lda	@sect
                	inr	c		; point to sector register
                	outp	a
                	lhld	@dma		; set DMA address
                
                	lda	@dbnk		; E := disk-bank
                	mov	e,a
                	lda	@cbnk		; A := cpu-bank
                	cmp	e		; equal ?
                	push	psw		; save Z-flag and cpu-bank
                	mov	a,e		; A := disk-bank
                	jmp	rwbank
                
                	cseg			; bank switch code included
                
                rwbank:	cnz	?bank		; set disk-bank
                	dcr	c		; point to data register
                	dcr	c
                	mvi	b,128		; transfer data
                irloc:	outir			; also used as INIR
                	pop	psw		; need to switch to old bank ?
                	cnz	?bank
                	xra	a		; no error
                	ret
                
                
                	endif			; end of if KAYSER
                
                
                ;	CODE ONLY FOR TURBO RAMDISK :
                ;	=============================
CP/M RMAC ASSEM 1.1	#005	RAMDISK - DRIVER FOR PROF 80

                
                	if	TURBO
                
                	dseg			; we only use move routines
                
                write:	lda	@dbnk		; C := source bank
                	mov	c,a
                	lda	@trk		; B := dest. bank
                	adi	2		; = @trk + 2
                	mov	b,a
                	call	?xmove		; set xmove banks
                	call	getadr		; HL := dest.  address
                	lded	@dma		; DE := source address
                	lxi	b,128		; physical sector size
                	call	?move		; transfer data
                	xra	a		; no error
                	ret
                
                read:	lda	@dbnk		; B := dest. bank
                	mov	b,a
                	lda	@trk		; C := source bank
                	adi	2		; = @trk + 2
                	mov	c,a
                	call	?xmove		; set xmove banks
                	call	getadr		; HL := source address
                	xchg			; DE := source address
                	lhld	@dma		; HL := dest.  address
                	lxi	b,128		; physical sector size
                	call	?move		; transfer data
                	xra	a		; no error
                	ret
                	
                getadr:	lxi	h,4000h		; offset for turbo ram
                	lda	@sect		; + @sect * 128
                	srlr	a		; lsb into carry
                	rarr	l		; into L as msb
                	add	h		; + turbo ram offset
                	mov	h,a		; back into h
                	ret
                	
                
                	endif			; end of if TURBO
                
                	endif			; end of if RAMDISK
                
 0000           	end
