Appendix C
Equates for Mode Byte Bit Fields

; equates for mode byte bit fields
mb$input	equ OO00$OOOlb  ; device may do input
mb$output	equ O0OO$OOlOb  ; device may do output
mb$in$out	equ mb$input+mb$output
mb$soft$baud	equ 000O$OlOOb	; software selectable baud rates
mb$serial	equ 0O0O$lOOOb	; device may use protocol
mb$xon$xoff	equ OOOl$OOOOb	; XON/XOFF protocol enabled
baud$none	equ	0	; no baud rate associated with device
baud$5O	equ	1	; SO baud
baud$75	equ	2	; 75 baud
baud$ll0	equ	3	; 110] baud
baud$134	equ	4	; 134.5 baud
baud$150	equ	5	; 150] baud
baud$300	equ	6	; 300 baud
baud$600	equ	7	; 600 baud
baud$1200	equ	8	; 1200 baud
baud$1800	equ	9	; 1900 baud
baud$2400	equ	10	; 2400 baud
baud$3600	equ	11	; 3600 baud
baud$4800	equ	12	; 4800 baud
baud$7200	equ	13	; 7200 baud
baud$9600	equ	14	; 9600 baud
baud$19200	equ	15	; 19.2k baud







Listing G-1. Equates for Node Byte Fields:  NODEBAUD.LIB


End of Appendix G
Appendix H
Macro Definitions for CP/M 3 BIOS Data Structures

Macro Definitions for CP/M3 BIOS Data Structures.
	; dtbl  <dphO,dphl,...>	- drive table
	; dph	translate$table,	- disk parameter header
	;	disk$Parameter$block,	(optional)
	;	checksum$size,
	;	alloc$size	(optional)
	; skew	sectors,	- skew table
	;	skew$factor,
	;	first$sector$number
	; dpb	physical$sector$size,	- disk parameter block
	;	physical$sectors$per$track;
	.	number$tracks,
	;	block$size,
	.	number$dir$entries,
	;	track$offset,
	;	checksum$vec$size	(optional)
;	Drive Table.  Contains 16 one word entries.

dtbl macro ?list
local ?n
?n	set 0
	irp ?drv,<?list>
?n	set ?n+l
	    dw	?drv
	endm

if ?n > 16
.' Too many drives.  Max 16 allowed'
exitm
	endif

if ?n < 16
rept (16-?n)
	dw	0
endm
endif
endm

dph	macro ?trans,?dpb,?csize,?ssize
local ?csv,?alv
	dW ?trana	; translate table address
	db 0,0,0,0,0,0,0,0,0	; RBOS Scratch area
	db 0	; media flag


		dw ?dpb	; disk parameter block
if not nul 7csize
		dw ?csv	; checksum vector
else
		dw OFFFEh	; checksum vector allocated by GENCPM
endif
if not nul ?aslze
	dw ?alv	; allocation vector
else
		dw OFFFEh	; alloc vector allocated by GENCPM
endif
	dw Offfeh,Offfeh,Offfeh	; dirbeb, dtabcb, hash alloc'd by GE!;CPM
	db 0	; hash bank






Listing H-i. Macro Definitions for CP/M 3 BIOS Data Structures
CP/M 3 System Guide	H  Macro Definitions



if not nul ?c=ize
	?csv    ds	?csize	; checksum vector
	endif
	    if not nul	?asize
	?alv    ds	?asize	; allocation vector
	endif

ends

dpb macro ?psize,?papt,?trka,?bls,?ndirs,?off,?nck=
local ?spt,?bsh,?blm,?exu,?dsm,?drm,?alO,?all,?cks,?psh,?psm
local ?n
; physical sector mask and physical sector shift
	?psh	set 0
	?n	set ?psize/l28
	?psm	Set ?n-l
rept 8
	?n	set ?n/2
if ?n - 0
exitm
endif
?psh    set ?psh + 1
ends
	?spt	set ?pspt*(?psize/128)
	?bah	set 3
	?n	set ?bls/1024
rept 8
	?n	set ?n/2
if ?n - 0
exits
endif
?bsh    set ?bsh + 1
endm
	?blm	set ?bls/128-l
	?size	set (?trks-?Off)*?spt
	?dsm	set ?size/(?bls/128)-1
	?exm	set ?bls/1024
if ?dsm > 255
if ?bls - 1024


'Error, can''t have this size disk with Lk block size'
exitm
endif
	    ?exm	met ?exm/2
	    endif
	?exm	set ?exm-l
	?sll	set 0
	?n	set	(?ndirs*32+?b1s-l)/?bls
	    rept ?n
	    ?all	set (?all shr	1) or 8000h
	    endm
	?al0	set high ?all
	?all	set low ?&11
	?drm	set ?ndirs-l
	if not nul ?ncks
	    ?cks	set 7ncks
	else
	    ?cks	set ?ndirs/4
	endif
	    dw	?spt		; 128 byte records per track
	    db	?bsh,?blm		; block shift and mask
	    db	?exm		; extent mask
	    dw	?dsm		; maximum block number
	    dw	?drm		; maximum directory entry number
	    db	?al0,?al1		; alloc vector for directory
	    dw	?cks		; checksum size
	    dw	?0ff		; offset for system tracks
	    db	?psh,?psm		; physical sector size shift and mask
ends









Listing H-i.  (continued)
CP/M 3 System Guide	H Macro Definitions



gcd macro ?u,?n
p;  greatest common divisor of .,n
		p;	produces value gcdn as result
		p;	(used in sector translate table generation)
	?gcdm	set ?m	;;variable for U
	?gcdn	set ?n	;;vsrisble for n
	?gcdr	set 0 	;;variable for r
	   rept	65535
?qcdx   set ?gcdm/?gcdn
?gcdr   set ?gcdm - ?gcdx*?gcdn
1f ?gcdr = 0
exitm
endif
?gcdm   set ?gcdn
?gcdn   set ?gcdr
endm
end.

skev macro ?secs,?skf,?fsc
;;	generate the translate table
?nxtsec    set 0   ;;next sector to fill
?nxtbas     set 0   ;;Uoves by one on overflow
ged %?secs,?skf
;;  ?gcdn - gcd(?secs,skew)
?neltst    set ?secs/?gcdn
;;  neltat is nu=ber of elements to generate
;  before we overlap previous elements
	?nelts	set ?neltst	;;counter
	rapt ?secs		;;once for each sector
	db	?nxtsec+?fac
?nxtsec set ?nxtsec+?skf
if ?nxtsec >= ?secs
		?nxtsec	set ?nxtsec-?secs
endif
?nelta  set ?nelts-l
if ?nelts - 0
		?nxtbas	set ?nxtbas+l
		?nxtsec	set ?nxtbas
		?nelts	set ?neltst
endif
endm
endm


Listing H-1.  (continued)


End of Appendix H
Appendix I
ACS 8000-15 BIOS Modules

1.1	Boot Loader Nodule for CP/M 3

The BOOT.ASM module performs system initialization other than
character and disk I/O.  BOOT loads the CCP for cold starts and
reloads it for warm starts.  Note that the device drivers in the
Digital Research sample BIOS initialize devices for a polled, and
not an interrupt-driven, environment.
	1			        title   'Boot loadar module for Cp/M 3.0'
	2
	3	FFFF	-	true equ -1
	4	0000	=	false equ not true
	5
	6	FFFF	=	banked  equ true
	7
	8			        public  ?init,?ldccp,?rlccp,?time
	9		extrn   ?pmsg,?conin
	10		extrn   @civec,@covec,@aivec,@aovec,@lovec
	11		Cxtrn   @cbnk,?bnksl
	12
	13		maclib ports
	14		maclib z80
	15
	16	0005 =         bdos	equ 5
	17
	18		if banked
	19	0001 =         tpa$bank        equ 1
	20		else
	21	               tpa$bank        equ 0
	22		endif
	23
	24		daeg    ; init done from banked memory
	25
	26	               ?init:
	27	0000 2100802200	lxi h,08000h ! shld @civec ! shld @covec        
; assign console to CRT:
	28	0009 2100402200	lxi h,04000h ! shld @lovec                      
; assign printer to LPT:
	29	QOOF 2100202200	lxi h,02000h ! shld @aivec ! shld @aovec        
; assign AUX to CRT'l:
	30	0018 21EFOOCD2S	lxi h,init$table ! call out$blocks      ; set up 
misc hardware
	31	OOIE 218700CD00	lxi h,signon$msg ! call ?pmsg           ; print 
signon message
	32	0024 C9	ret
	33
	34	               out$blocks:
	35	0025 7EB7C847	mov a,m ! ora a ! rz ! mov b,a
	36	0029 234E23	inx h ! mov c,m ! inx h
	37		outir
	38	002C+EDB3	DB      OEDH,0B3H
	39	002E C32500	jmp out$blocks
	40
	41
	42		caeg    ; boot loading most be done from resident memory
	43
	44	                   ;	This version of the boot loader loads the 
CCP from a file
	45	                   .	called CCP.COM on the system drive (A:).
	46
	47
	48	               ?ldccp:
	49		; First time, load the A:CCP,CO!! file into TPA
	50	0000 AF32DBOO	xra a ! Sta ccp$fcb+15          ; zero extent
	51	0004 21000022EC	lxi h,0 ! shld fcb$nr           ; start at 
beginning of file
	52	OOOA llCCOOCD73	lxi d,ccp$fcb ! call open       ; open file 
containing CCP
	53	0010 3CCA4AOO	inr a ! jz no$CCP               ; error if no 
file. . '
	54	0014 110001CD78	lxi d,OlOOh ! call setdma       ; Start of TPA
	55	00lA l18OOOCD7D	lxi d,128 ! call setmulti       ; allow up to 
16k bytes
	56	0020 IlCCOOCD82	lxi d,ccp$fcb ! call read       ; load the thing
	57		                                ; now,



Listing I-i.   Boot Loader Module for CP/M 3
CP/M 3 System Guide	I.1  Boot Loader Module for CP/M 3
	58	;   copy CCP to bank 0 for reloading
	59	0026 2100010180	lxi	h;OlOOh ! lxi b,OC8Oh	; clone 3.125K, just in 
case
	60	002C 3AOOOOFS	lda	@cbnk ! push psw	; save current bank
	61	               ld$1:
	62	0030 3EO1CDOOOO	mvi	a,tpa$bank ! call ?bnksl	; select TPA
	63	0035 7EFS	mov	a,m ! push psw	; get a byte
	64	0037 3E02CD0000	mvi	a,2 ! call ?bnksl	; select extra bank
	65	OO3C Fl77	pop	psw ! mov m,s	; save the byte
	66	003E 230B	inx	h ! dcx b	; bump pointer, drop count
	67	0040 78B1	mov	a,b ! ora c	; test for done
	68	0042 C23000	jnz	ld$1
	69	0045 FlCDOOOO	pop	psw ! call ?bnksl	; restore original bank
	70	0049 C9	ret
	71
	72	               no$CCP:		            ; here 1f we couldn't find 
the file
	73	004A 2lABOOCDOO	lxi	h,ccp$msg ! call ?pmsg	; report this. . .
	74	0050 CDOOOO            call ?conin			; get a response
	75	0053 C30000	jmp	?ldccp	; and try again
	76
	77
	78	               ?rlccp:
	79	0056 2100010180	lxi	h,OlOOh ! lxi b,OC8Oh	; clone 3.125K
	80	               rl$l:
	81	OOSC 3BO2CDOOOO	mvi	a,2 ! call ?bnksl	; select extra bank
	82	0061 7EFS	mov	a,m ! push psw	; get a byte
	83	0063 3EO1CDOOOO	mvi	a,tpa$bank ! call ?bnksl	; select TPA
	84	0068 Fl77	pop	psw ! mov m,a	; save the byte
	85	006A 230B	inx	h ! dcx b	; bump pointer, drop count
	86	006C 78B1	mov	a,b ! ora c	; test for done
	87	006E C2SCOO	jnz	rl$1
	88	0071 C9	ret
	59
	90	                   ; No external clock.
	91	               ?time:
	92	0072 C9	ret
	93
	   94                          ; CP/M BDOS Function Interfaces
	95
	96	               open:
	97	0073 OEOFC3OSOO	mvi	c,l5 ! jmp bdos	; open file control block
	98
	99	               setdma:
	100	0078 OEIAC3O5OO	mvi	c,26 ! jmp bdos	; set data transfer address
	101
	102	               setmulti:
	103	0070 0E2CC30500	mvi	c,44 ! jmp bdos	; set record count
	104
	105	               read:
	106	0082 0E14C30500	mvi	c,20 ! jmp bdos	; read records
	107
	108
	109	0087	ODOAODOA43signon$msg 	    db      13,lO,13,1O,'CP/M Version 
3.0, sample BIOS',13,lO,0
	110
	111	OOAB	ODOA42494Fccp$msg    	    db      13,l0,'BIOS Err    	on A: 
No CCP.COM file',O
	112
	113
	114	OOCC	0143435020ccp$fcb    	    db      1,'CCP     
','COM',0,O,O,O
	115	OODC		    ds      16
	116	OOEC 000000    fcb$nr		    db      0,0,0
	117
	118	OOBF	O326CFFFO7init$table 	    db      3,p$zpio$3a,OCFh,OFFh,07h 
      ; set up config port
	119	00F4 0327CF0007		    db      3,p$zpio$3b,OCFh,OOOh,O7h       ; 
set up bank port
	120	00F9 012500		    db      1,p$bank$select,O       ; select bank 0
	121	OOFC 00		    db      0	        ; end of init$table
	122
	123	OOFD	end
	BANKED	        FFFF     6#	18
	BC	        0000
	BDoS	        0005    16#	97 	100   103   106
	CCPFCB	        OOCC    50	52 	 56   114#
	CCPMSG	        0OAn    73	lll#
	BE	        0002
	FALSE	        0000     4#
	FCBNR	        OOBC    51	ll6#
	EL	        0004
	INITTABLE        OORF    30		119#
	IX	        0004
	IY	        0004
	1,01	        0030    61#	68
	NOCCP	        004A    53	72#


Listing I-i.  (continued)
CP/M 3 System Guide	I.1  Boot Loader Module for CP/M 3
 OPEN	0073	52	96#
OUTBLOCKS	0025	30	34#	39
 PBANKSELECT	0025	120
 PBAUDCON1	OOOC
 PBAUDCON2	0030
PBAUDCON34	0031
 PBAUDLPT1	OOOE
PBAUDLPT2	0032
PBOOT	0014
PCENTDATA	0011
PCENTSTAT	0010
PCON2DATA	002C
PCON2STAT	002D
PCON3DATA	002E
PCON3STAT	0021
PCON4DATA	002A
PCON4ST'AT	002B
PCONFIGURATION	0024
PCRTDAT'A	OOIC
PCRTSTAT	001D
PFDCMND	0004
PFDDATA	0007
PFDINT	0008
PFDMISC	0009
PFDSBCTOR	OOOE
PFDSTAT	0004
PFDTRACK	0005
PINDEX	0001
PLPT2DATA	0028
PLPT2ST'AT'	0029
PLP'TDATA	OO1E
PLPTSTAT	0011
PRTC	0033
PSELECT	0008
PWD1797	0004
PZCTCl	OOOC
PZCTC2	0030
PZDART	OOIC
PZDNA	0000
PZPIO1	0008
PZPIOIA	OOOA
PZPIO1B	000B
PZPIO2	0010
PZPIO2A	0012
PZPIO2B	0013
PZPIO3	0024
PZPIO3A	002E	118
PZPIO3B	0027	119
PZSIO1	0028
PZSIO2	002C
RIAD	0082	56	105#
RL1	OOSC	80#	87
SETDMA	0078	54	99#
SETMULTI	007D	55	102#
SIGNONMSG	0087	31	109#
TPABANK	0001	19#	21#	62	83
TRUE	FFFF	3#	4	6
?BNKSL	0000	11	62	64	69	81	83
?CONIN	0000	9	74
?INIT	0000	8	26#
?LDCCP	0000	8	484	75
?PMSG	0000	9	31	73
?RLCCP	0056	8	78#
?TINE	0072	8	914
@AIVEC	0000	10	29
@AOVEC	0000	10	29
@CBNK	0000	11	60
@CIVEC	0000	10	27
@COVEC	0000	10	27
@LOVEC	0000	10	28



Listing I-i.  (continued)
CP/M 3 System Guide	1.2  Character I/O Handler


69
	70		           null$lnput:
	71	0063	3E1A	mvi a,lAh	; return a ctl-Z for no device
	72	0065	C9	ret
	73
	74		          ?ciat:	        ; character input Status
	75
	76	0066	78FE06D27D	mov a,b ! cpi 6 ! jnc null$status ; can't read 
from centronlca
	77	006C	682600	mov l,b ! mvi h,O	; make device number 16 bits
	78	006F	llDCOOl9	lxi d,data$ports ! dad d	; make pointer to port 
address
	79	0073	4E0C	mov c,m ! inr c	; get SIO status port
	80			inp a	; read from status port
	 81   0075+ED78			DB      OEDH,A*8+4OH
	82	0077	E601	anl 1                   ; isolate RxRdy
	83	0079	C8	rz	; return with zero
	84	007A	F6FF	ori 0FFh
	85	007C	C9	ret
	86
	87		          null$status:
	88	0070	AFC9	xra a ! ret
	89
	go		          ?co:	        ; character output
	91	007F	78FEO6CA9E	mov a,b ! cpi 6 ! jz centronics$out
	92	0085	029000	jnc null$Output
	93	0088	79F5	mov a,c ! push psw	; save character from <C>
	94	008A	C5	push b	; save device number
	95		          co$spin:
	96	008B	CDB3OOCA8B	call ?cost ! jz co$spin	; wait for TxEmpty
	97	0091	E16C2600	pop h ! mov l,h ! mvi h,O	; get device number in 
<HL)
	98	0095	11DC0019	lxI d,data$ports ! dad d	; make address of port 
address
	99	0099	4E	mov c,m	; get port address
	100	009A	Fl	pop psw ! outp a	; send data
	101   009B+ED79			DB      OEDH,A*8+41H
	102		          null$output:
	103	0090	C9	ret
	104
	105		          centronics$out:
	106	009E	DBlOE62OC2	in p$centstat ! ani 20h ! jnz csntronics$out
	107	00A5	79D311	mov a,c ! out p$centdata	; give printer data
	108	00A8	DBIOF6OlD3	in p$centstat ! ori 1 ! out p$centstat  ; set 
strobe
	109	OOAE	E67ED310	ani 7Eh ! out p$centstat	        ; clear strobe
	110	00B2	C9	ret
	111
	112		          ?cost:	        ; character output status
	113	00B3	78FEO6CACD	mov a,b ! cpi 6 ! jz cent$stat
	114	00B9	027000	jnc null$status
	115	OOBC	682600	mov 1,b ! mvi h,0
	116	OOBF	11DC0019	lxi d,data$ports ! dad d
	117	00C3	4E0C	mov c,m ! inr c
	118			inp a	; get input status
	119   OOCS+ED78			DB      OEDH,A*8+4OH
	120	00C7	E604C8	ani 4 ! rz	; test transmitter empty
	121	OOCA	F6FFC9	ori 0FFh ! ret	; return true if ready
	122
	123
	124		          cent$stat:
	125	OOCD	DBlO2F	in p$centstat ! cas
	126	0000	E620C8	ani 20h ! rz
	127	0003	F6FFC9	ori 0FFh ! ret
	128
	129		          baud$ports:             ; CTC ports by physical 
device number
	130	0006	0C0E3031	db      p$baud$conl , p$baud$lptl , p$baud$con2, 
p$baud$con 34
	131	OOOA	3132	db      p$baud$con34,p$baud$lpt2
	132
	133		          data$ports:             ; serial base ports by 
physical device number
	134	OODC	lClE2C2E	db      
p$crt$data,p$lpt$data,p$con2data,p$con3data
	135	OOEO	2A28	db      p$con4data,p$lpt2data
	136
	137
	138	00E2	4352542020@ctbl	db 'CRT   '     ; device 0, CRT'	port 0
	139	00E8	OF	db mb$in$out+mb$aerial+mb$aoftbaud
	140	00E9	OE	db baud$9600
	141	OOEA	4C50542020	db 'LPT   '     ; device 1, LPT	port 0
	142	OOFO	1F	db mb$in$out+mb$serial+mb$softbaud+mb$xonxoff
	143	OOFI	QE	db baud$9600
	144	00F2	4352543120	db 'CRTl  '      ; device 2, CRT	port 1
	145	00F8	OF	db mb$ln$out+mb$serlal+mb$softbaud
	146	00F9	OE	db baud$9600
	147	OOFA	4352543220	db 'CRT2  '      ; device 3, CRT	port 2
	148	0100	OF	db mb$'in$out+mb$serial+sb$softbaud
	149	0101	CE	db baud$9600

Listing 1-2.  (continued)
cP/M 3 System Guide	1.2  Character I/O Handler
	150	0102	4352543320	db 'CRT3  '      ; device 4, CRT' pnrt 3
	151	0108	0F	db 'mb$in$out+mb$serial+mb$softbaud
	152	0L09	OE	db baud$9600
	153	0l0A	5641582020	db 'VAX   '     ; device 5, LPT' port 1 used for 
VAX interface
	154	0110	OF	db mb$in$out+mb$serial+mb$softbaud
	155	0111	OE	db baud$9600
	156	0112	43454E2020	db 'CEN   '	; device 6, Centronics rerallel 
printer
	157	0118	02	db mb$output
	158	0119	00	db baud$none
	159	0llA 00	db 0	; table terminator
160
161
	162	011B 
OOFFFFFFE9Speed$table	db	0.255,255,255.233,208,104,208,104,69,52,35,
26,17,13,7
163
	164			serial$init$tbl
	165	012B	02		db	2	; two bytes to CTC
	166	012C		ctc$port	ds	I	; port addresS of CTC
	167	012D	47		db	47h	; CTC mode byte
	168	012E		Speed	ds	1	; baud multiplier
	169	012F	07		db	7	; 7 bytes to SIO
	170	0130		Sio$port	ds	1	; port address of SIO
	171	0131	180311104		db	18h,3,OElh,4
	172	0135		sio$reg$4	dS	1
	173	0136 O5EA	db 5,OEAh
	174	0138 00	db 0	; terminator
	175
	176	0139 O2130F07  pio$init$tbl	db	2,p$zpio$2b,OFh,07h
	177	0130 0312CFF807	db	3,p$zpio$2a,OCFh,OF8h,07h
   178   0142	00				db 0
   179
   180   0143			end
BAUDIIO	0003
BAUD12OO	0008
BAUD134	0004
BAUD15O	0005
BAUD18OO	0009
BAUO192OO	000F
BAUD24OO	OOOA
BAUD3OO	0006
BAUD36OO	000B
BAUD48OO	OOOC
BAUD5O	0001
BAUD6OO	0007	34
BAUD72OO	0000
BAUD75	0002
BAUD96OO	OOOE	140	143	146	149	152	155
BAUDNONE	0000	158
BAUDPORTS	0006	44	129#
BC	0000
CENTINIT	0042	28	49#
CE!;TRONICSOUT'	00911	91	105#	106
CENTSTAT	OOCO	113	124#
CII	0057	63#	64
COSPIN	008B	95#	96
CTCPORT	012C	45	166#
DATAPORTS	OODC	42	44	78	98	116	133#
DE	0002
HISPEED	001D	35	37#
HL	0004
IX	0004
IY	0004
MAXDEVICES	0006	23#	28
MBINOUT	0003	139	142	145	148	151	154
MBINPUT	0001
MBOUTPUT	0002	157
MBSERIAL	000B	139	142	145	148	151	154
MBSOFTBAUD	0004	139	142	145	148	151	154
MBXONXOFF	0010	142
NULLINPUT	0063	62	70#
NULLOUTPUT	0090	92	102#
NULLSTATUS	0070	76	87#	114
PBANKSELECT	0025
PBAUDCON1	OOOC	130
PBAUDCON2	0030	130
PBAUDCON34	0031	130	131
PBAUDLPT1	OOOE	130
PBAUDLPT2	0032	131
PBOOT	0014
PCENTDATA	0011	107
PCENTSTAT	0010	106	108	108	109	125
PCON2DATA	002C	134


Listing 1-2.  (continued)
CP/M 3 System Guide	1.2  Character I/O Handler
pCON2STAT	002D
PCON3DATA	002E	134
pCON3STAT	002F
PCON4DATA	002A	135
PCON4ST'AT'	002B
PCONFIGURAT'ION	0024
PCRT'DATA	OOiC	134
PCRTSTAT	001D
PFDCMBD	0004
pFDDATA	0007
PFDINT	0008
PFDMISC	0009
PFDSECTOR	0006
PFDSTAT	0004
PFDTRACK	0005
PINDEX	000F
PIOINITTBL	0139	50	176#
PLPT2DATA	0028	135
PLPT2ST'AT	0029
PLPTDATA	OO1E	134
PLPTSTAT'	OO1F
PRTC	0033
PSELECT	0008
PWD1797	0004
PZCTCl	OOOC
PZCTC2	0030
PZDART	OO1C
PZDMA	0000
PZPIO1	0008
PZPIOlA	OOOA
PZPIO1B	000B
PZPIO2	0010
PZPIO2A	0012	177
PZPIO2B	0013	176
PZPIO3	0024
PZPIO3A	0026
PZPIO3B	0027
PZSIO1	0028
PZSIO2	002C
SERIALINITTBL	012B	46	164#
SIOPORT	0130	43	170#
SIOREG4	0135	38	172#
SPEED	012E	40	168#
SPEEDTABLE	011B	39	162#
STREAMOUT	0045	47	52#	57
?CI	0051	16	60#
?CINIT	0000	16	27#
?CIST	0066	16	64	74#
?CO	007F	16	90#
?COST	0083	16	96	112#
@CTBL	00E2	17	33	138#


Listing 1-2.  (continued)
cP/M 3 System Guide	1.3  Drive Table


1.3	Drive Table

	The DRVTBL.ASM module points to the data structures for each
configured disk drive.  The drive table determines which physical
disk unit is associated with which logical drive.   The data
structure for each disk drive is called an Extended Disk Parameter
Header (XDPH) .
	1			public @dtbl
	2			extin fdsd0,fdsdl
	3
	4			cseg
	5
	6	0000	00000000  @dtbl	dw fdsd0,fdsdl
	7	0004	0000000000	dw 0.0,0,o,0,0,0,0,0,0,0,0,0,0	; drives C-P 
non-existent
	8
	9	0020		end
	FDSDO		0000     2	6
	FDSDl		0000     2	6
	@DTBL		0000     1	6#



Listing I-3.  Drive Table



1.4	Z80 DMA single-density Disk Handler

	The FDl797SD module initializes the disk controllers for the
disks described in the Disk Parameter Headers and Disk Parameter
Blocks contained in this module.  FDl797SD is written for hardware
that supports Direct Memory Access (DMA) .
	1		    title 'wd1797 w/ z80 DMA Single density diskette handler'
	2
	3	'	CP/M-80 Version 3     --  Modular BIOS
	4
	5	;	    Disk I/O Module for wd1797 based diskette systems
	6
	7		    ;        Initial version 0.01,
	8		                    Single density floppy only.     - jrp, 4 Aug 
82
	9
	10		    dseg
	11
	12		; Disk drive dispatc))ing tables for linked BIOS
	13
	14		   public  fdsd0,fdsdl
	15
	16		; Variables containing parameters passed by BDOS
	17
	18		   extrn   @adrv,@rdrv
	19		   extrn   @dma,@trk,@sect
	20		   extrn   @dbnk
	21
	22		; System Control Block variables
	23
	24		   extrn   @ermde          ; BDOS error mode
	25
	26		; Utility routines in standard BIOS


Listing 1-4*  z80 DMA single-density Disk Handler
CP/M 3 System Guide	1.4  z80 DMA Single-density Disk Handler



27
	28			extrn	 ?wboot  ; warm	hoot vector
	29			extrn	 ?pmsg   ; print	message @<HL> up to 00, saves <BC> & <DE>
	30			extrn	?pdec   ; print	binary number in <A> from 0 to 99,
	31			extrn	 ?pderr  ; print	BIOS disk error header
	32			extrn	?conin,?cono	; con in and out
	33			extrn	?const	; get console status
	34
	35
	 36                      ; Port Address Equates
	37
	38			saclib	ports
	39
	 40                      ; Cp/M 3 Disk derinition macros
	41
	42			maclib	cpm3
	43
	 44                     ; Z80 macro library instruction 
definitions
	45
	46			maclib	z80
	47
	 48                       ; common control characters
	49
	50	000b =	cr    	equ 13
	51	OOOA =	lf    	equ 10
	52	0007 =	bell  	equ 7
	53
	94
	 55                       ; Extended				Disk Parameter Headers 
(XPDNS)
	56
	57	0000 E600		dw	 fd$write
	58	0002 DCOO		dw	 fd$read
	59	0004 DB00		dw	 fd$login
	60	0006 BE00		dw	 fd$init0
	61	0008 0000		db	 0,0	; relative drive zero
	62		fdsdO	dph	 trans,dpbsd,16,31
	63	OOOA+A400		DW TRANS		; TRANSLATE TABLE ADDRESS
	64	OOOC+OO000000O0		DB 0,0,0,0,0,0,0,0,0		; BDOS SCRATCH AREA
	65	0015+00		DB 0		; MEDIA FLAG
	66	0016+0000		DW DPBSD		        ; DISK PARAMETER BLOCK
	67	0018+2300		DW ??0001		        ; CHECKSUM VECTOR
	68	OOlA+3300		DW ??0002		        ; ALLOCATION VECTOR
	69	OOlC+FEFFFEFFFE		DW OFFFEH,OFFFEH,OFFFEH		; DIRBCB, DTABCB, HASH 
ALLOC'D BY GENCPM
	70	0022+00		DB 0		; HASH BANK
	71	0023+	??000l	DS	 16	; CHECKSUM VECTOR
	72	0033+	??0002	DS	 31	; ALLOCATION VECTOR
	73
	74	0052 E600		dw	fd$write
	79	0054 DCOO		dw	fd$read
	76	0056 DB00		dw	 fd$login
	77	0058 CDOO		dw	 fd$initl
	78	OOSA 0100		db	 1,0	; relative drive one
	79		fdsdl	dph	trans,dpbsd,16,31
	80	OOSC+A400		DW TRANS		; TRANSLATE TABLE ADDRESS
	81	OOSE+O000000O0O		DB 0,0,0,0,0,0,0,0,0		; BDOS SCRATCH AREA
	82	0067+00		DB 0		; MEDIA FLAG
	83	0068+0000		DW DPBSD		        ; DISK PARAMETER BLOCK
	84	006A+7500		DW ??0003		        ; CHECKSUM VECTOR
	85	006C+8500		DW ??0004		        ; ALLOCATION VECTOR
	86	006E+FEFFFEFFFE		DW OFFFEH,OFFFEH,OFFFEH		; DIRBCB, DTABCB, HASH 
ALLOC'D BY GENCPM
	87	0074+00		DB 0		; HASH BANK
	88	0075+	770003	DS	16	; CHECKSUM VECTOR
	89	0085+	770004	DS	 31	; ALLOCATION VECTOR
	90
	91			cseg	 ; DPB must ba resident
	92
	93		dpbsd	dpb 128,26,77,1024,64,2
	94	O0O0+lAOO		DW	770005	; 128 BYTE RECORDS PER TRACK
	95	0002+0307		DB	??0006,??0007	; BLOCK SHIFT' AND MASK
	96	0004+00		DB	770008	; EXTENT MASK
	97	OO0S+F200		DW	770009	; MAXIMUM BLOCK NUMBER
	98	0007+3F00		DW	770010	; MAXIMUM DIRECTORY ENTRY NUMBER
	99	0009+COOO		DB	770011,770012	; ALLOC VECTOR FOR DIRECTORY
	100	0008+1000		DW	770013	; CHECKSUM SIzE
	101	OOOD+0200		DW	 2	; OFFSET FOR SYSTEM TRACKS
	102	OOOF+OOOO		DB	??0014,??0015	; PHYSICAL SECTOR SIZE SHIFT AND MASK
	103
	104			dseg	; rest is banked


Listing 1-4.  (continued)
cP/M 3 system Guide	1.4  z80 DMA single-density Disk Handler


105
	106		trans	skew 26,6,1
	107	OOA4+Ol		DB      ?NXTSEC+1
	108	OOA5+07		DB      ?NXTSEC+1
	109	00A6+OD		DB      ?NXTSEC+1
	110	00A7+13		DB      ?NXTSEC+1
	111	00A8+19		DB      ?NXTSEC+1
	112	00A9+O5		DB      ?NXTSEC+1
	113	OOAA+OB		DB      ?NXTSEC+1
	114	OOAB+1l		DB      ?NXTSEC+1
	115	OOAC+17		DB      ?NXTSEC+1
	116	OOAD+03		DB      ?NXTSEC+1
	117	OOAE+09		DB      ?NXTSEC+1
	118	OOAF+OF		DB      ?NXTSEC+1
	119	OOBO+15		DB      ?NXTSEC+1
	120	OOBI+02		DB      ?NXTSEC+1
	121	00B2+O9		DB      ?NXTSEC+1
	122	OOB)+OE		DB      ?NXTSEC+1
	123	00B4+14		DB      ?NXTSEC+1
	124	OOBS+IA		DB      ?NXTSEC+1
	125	00B6+06		DB      ?NXTSEC+1
	126	00B7+OC		DB      ?NXTSEC+1
	127	00B8+12		DB      ?NXTSEC+1
	128	00B9+18		DB      ?NXTSEC+1
	129	OOBA+04		DB      ?NXTSEC+1
	130	OOBB+OA		DB      ?NXTSEC+1
	131	OOBC+10		DB      ?NXTSEC+1
	132	OOBD+16		DB      ?NXTSEC+1
	133
	134
	135
	136		    ; Disk I/O routines for standardized BIOS interface
	137
	138		; Initialization entry point.
	139
	140			        called for first time initialization.
	141
	142
	143		fd$init0
	144	OOBE 2ICEOO		lxi h,init$table
	145		fd$init$next:
	146	OOCI 7EB7CB		mov a,m ! ora a ! rz
	147	00C4 47234E23		mov b,a ! inx h ! mov c,m ! inx h
	148			outir
	149	00C8+EDB3		DB      OEDH,0B3H
	150	OOCA C3C1OO		jmp fd$init$next
	151
	152		fd$initl:       ; all initialization done by drive 0
	153	OOCD C9		ret
	154
	155	OOCE 040A	init$table      db 4,p$zpio$1A
	156	OODO CFC217FF		        db      llOOllllb, 11000010b, 
OOOlOlllb,llllllllb
	157	00D4 040B		        db 4,p$zpio$lB
	158	00D6 CFDDl7FF		        db      ll00llllb, llOlllOlb, 
OOOlOlllb,llllllllb
	159	OODA 00		        db 0
	160
	161
	162		fd$login
	163			     ; This entry is called when a logical drive is about to
	164			    ; be logged into for the purpose of density determination.
	165
	166			    ; It may adjust the parameters contained in the disk
	167			        ; parameter header pointed at by <DE)
	168
	169	00DB C9		ret     ; we have nothing to do in
	170			        ;       simple single density only environment.
	171
	172
	173		; disk READ and WRITE entry points.
	174
	175			    ; these entries are called with the following arguments:
	176
	177			                . relative drive number in @rdrv (8 bits)
	178			                ; absolute drive number in @adrv (8 bits)
	179			         , disk transfer address in @dma (16 bitS)
	180			         , disk transfer bank    in @dbnk (8 bits)
	181			                ; disk track address    in @trk (16 bits)
	182			                ; disk sector address   in @sect (16 bits)
	183			                ; pointer to XDPH in <DE>
184


Listing 1-4.  (continued)
CP/M 3 System Guide	I.4  Z80 DMA Single-density Disk Handler
	185		                 ; they tranafer the appropriate data, perform 
retries
	186		                 ; if necessary, then return an error code in 
<A>
	187
	188		fd$read:
	189	OODC 211802	        lxi h,read$msg           ; point at " Read 
"
	190	OODF 3E880601	        mvi a,88h ! mvi b,Olh   ; 1797	read + 
Z8ODMA direction
	191	00E3 C3EDOO	        jmp rw$common
	192
	193		fd$write
	194	00E6 211F02	        lxi h,write$msg         ; point at " Write 
"
	195	00E9 3EA80605	        mvi a,OA8h ! mvi b,OSh  ; 1797	write + 
Z8ODMA direction
	196		    '   jmp wr$common
	197
	198		rw$common:                      ; seek	to correct track (if 
necessary),
	199		                                '	 initialize DMA controller,
	200		                                ,	and issue 1797 command.
	201
	202	OQED 222702	        shld operation$name	 ; save message for 
errors
	203	OOFO 321102	        sta disk$command	 ; save 1797 command
	204	00F3 7832A802	        mov a,b ! sta zdma$direction	 ; save 
Z8ODMA direction code
	205	00F7 2A0000229F        lhld @dma ( shld  zdma$dma		 ; get and 
save DMA address
	206	OOFD 3A00006F26        lda @rdrv ! mov 1,a ! mvi h,0		 ; get 
controller-relative disk drive
	207	0103 11160219	        lxi d,select$table ! dad d	 ; point to 
select mask for drive
	208	0107 7E321202	        mov a,m ! sta select$mask	 ; get select 
mask and save it
	209	0108 D308	        Out p$Select	 ; select drive
	210		more$retries:
	2)1	0l0D OEOA	        mvi c,lO	 ; allow 10 retries
	212		retry$operation:
	213	OlOF C5	        push b	 ; save retry counter
	2)4
	215	0110 3A12022113        lda select$mask ! lxi h,old$=elect ! 
csp m
	216	(0117 77	        mov m,a
	2)7	0118 C22D01	        jnz new$track	 ; if not same drive as last, 
seek
	218
	2)9	011B 3A00002114        lda @trk ! lxi h,old$track ! csp m
	220	0122 77	        mov m,a
	221	0123 C22001	        jnz new$track	 ; if not same track, then 
seek
	222
	223	0126 DB09E602C2        in p$fdmisc ! ani 2 ! jnz same$track    
; head still loaded, we are OK
	224
	225		new$track:      ; or drive or unloaded	head means we should . . 
'
	226	012D CDA9Ol	        call check$seek          ; ' . read address 
and seek if wrong track
	227
	228	0130 011B41	        lxi b,16667              ; 100 ms I (24 t 
states*250 ns)
	229		spin$loop:                        ; wait	for head/seek settling
	230	0133 OB	        dcx b
	231	0134 78B1	        mov a,b ! ora c
	232	0136 C23301	        jnz spin$loop
	233
	234		same$track
	235	0139 3A00000305        lda @trk ! out p$fdtrack		; give 1797 
track
	236	013E 3A0000D306        lda @sect ! Out p$fdsector		;        and 
sector
	237
	238	0143 219A02	        lxi h,dma$block	; point to dma command block
	239	0146 010011	        lxi b,dmab$length*256 + p$zdma	; command 
block length and port address
	240		       outir	; send commands to Z80 DMA
	241	0149+EDB3	        DB      OEDH,0B3H
	242
	243	0148 DB2S	        in p$bankse)ect	; get old value of bank select 
port
	244	014D E63F47	       ani 3Fh ! mov b,a	; mask off DMA bank and 
save
	245	0150 3AOOOOOFOF        lda @dbnk ! rrc ! rrc		; get DMA bank to 
2 hi-order bits
	246	0155 E6COBO	        ani OCOh ! ora b	; merge with other bank 
stuff
	247	0158 D325	       out p$bankselect	; and select the correct DMA 
bank
	248
	249	Ol5A 3A1102	        lda disk$command        ; get 1797 command
	250	015D CDDSOl	       call exec$co'""'and       ; start it then 
wait for IREQ and read status
	251	0160 321502	       sta disk$status         ; save	status for 
error messages
	252
	253	0163 C1	       pop b                   ; recover retry counter
	254	0164 B7C8	       ora a ! rz              ; check status and 
return to BDOS if no error
	255
	256	0166 E610	       ani 0OOl$OOOOb          ; see if record not 
found error
	257	0168 C4A901	       cnz check$seek          ; if a	record not 
found, we might need to seek
	258
	259	0168 ODC2OFO1	       dcr c ! jnz retry$operation
	260
	261		    ; suppress error message if BDOS is returning errors to 
application. . .
	262
	263	016F 3AOOOOFEFF        lda @ermde ! cpi 0FFh ! jz hard$error


Listing 1-4.  (continued)
cP/M 3 system Guide	I.4  z80 DMA Single-density Disk Handler



264
	265	, Had permanent error, print message like:
266
	267	                               ; BIOS Err on d: T-nn,	S-mm, 
<operation> <type>, Retry 7
	268
	269	0177 CDOOOO            call ?pderr             ; print	message 
header
	270
	271	017A 2A2702CD00        lhld operation$name ! call ?pmsg        
         ; last function
	272
	273	                                 ; then, messages for all 
indicated error bits
	274
	275	0180 3A1502             lda disk$status          ; get Status 
byte from last error
	276	0183 212902             lxi h,error$table       ; point	at 
table of message addresses
	277	                errml:
	278	0186 5E235623          mov e,m ! Inx h ! mov d,m ! inx	h ; get 
next message address
	279	018A 87F5               add a ! push psw        ; shift	left 
and push residual bits with status
	280	018C EBDCO0OOEB        xchg ! cc ?pmsg ! xchg  ; print	message, 
saving table pointer
	281	0191 F1C28601           pop psw ! jnz errml     ; if any more 
bits left, continue
	282
	283	0195 218A02CD00        lxi h,error$msg ! call ?pmsg	; print  
<BEL>, Retry (Y/N) ? "
	284	019B CDF5OI             call u$conin$echo       ; get operator 
response
	285	019E FE59CAODOl        cpi 'Y' ! jz more$retries ; Yes, then 
retry 10 more times
	286	                hard$error:                       ; otherwise,
	287	01A3 3E01C9             mvi a,1 ! ret            ;	return hard 
error to BDOS
	288
	289	                cancel:                           ; here	to 
abort job
	290	01A6 C30000            jmp ?wboot              ; leap	directly 
to warmstart vector
	291
	292
	293	                   ; subroutine to seek if	on wrong track
	294	                               ; called both to set up	new 
track or drive
	295
	296	               check$seek:
	297	01A9 C5                push b	; save error counter
	298	OlAA CDElO1            call read$id	; try to read ID, put track 
in <B>
	299	OlAD CABE01            jz id$ok	; if OK, we're DE
	300	OlBO CDCEOl             call step$out	; else step towards Trk 0
	301	01B3 CDElOl             call read$id	; and try again
	302	01B6 CABE01             jz id$ok	; if OK, we're OK
	303	01B9 CDD3O1            call restore	; else, restore the drive
	304	O1BC 0600              mvi b,O	; and make like we are at track 
0
	305	               id$ok:
	306	OlBE 78D305            mov a,b ! Out p$fdtrack	; send current 
track to track port
	307	OlCl 3AOOOOB8Cl        lda @trk ! cmp b ! pop b ! rz	; lf its 
desired track, we are done
	308	01C7 D307              Out p$fddata	; else, desired track to 
data port
	309	01C9 3E1A              mvi a,OOOllOlOb	; seek wi 10 ms. steps
	310	OlCB C3D501             jmp exec$command
	311
	312
	313
	314	                step$out:
	315	OlCE 3E6A               mvi a,OllOlOlOb	; step out once at 10 
ms.
	316	0100 C3DSOl            jmp exec$command
	317
	318	               restore:
	319	01D3 3EOB              mvi a,OOOOlOllb	; restore at 15 ms
	320	                     ; jmp exec$command
	321
	322
	323	               exec$command:           ; issue 1797 command, 
and wait for IREQ
	324	                                         ;        return 
Status
	325	0105 0304               Out p$fdcmnd	; send 1797 command
	326	                wait$IREQ:	; spin til IREQ
	327	0107 DBO8E64OCA        in p$fdint ! ani 40h ! jz wait$IREQ
	328	OlDE 0804               in p$fdstat	; get 1797 Status and clear 
IREQ
	329	OIEO C9                 ret
	330
	331	                read$id:
	332	OIEl 21AB02             lxi h,read$id$block     ; set up DMA 
controller
	333	OlE4 O1OOF             lxi b,length$id$dmab*256 + p$zdma ; for 
READ ADDRESS operation
	334	                        outir
	335	01E7+EDB3               DB      OEDH,OB3H
	336	01E9 3EC4               mvi a,llOOOlOOb         ; issue	1797 
read address command
	337	OlEB CDD5Ol             call exec$command       ; wait for 
IRED and read status
	338	OIEE E69D               ani 10011101b            ; mask status
	339	OlFO 21110046           lxi h;id$buffer ! mov b,m	; get actual 
track number in <B>
	340	01F4 C9                 ret                      ; and return 
with z flag true for OK
	341
	342
		            Listing 1-4.  (continued)
CP/M 3 System Guide     I.4  Z80 DMA Single-density Disk Handler
	343	u$conin$echo:	; get console input, echo it, and shift to upper 
case
	344	OlF5 CDOOOO87CA	call ?const ! ora a ! jz u$cl	; see if any char 
already struck
	345	O1FC CDOOOOC3FS	call ?conin ! jmp u$conin$echo  ; yes, eat it 
and try again
	346	u$cl:
	347	0202 CDOOOOFS	call ?conin ! push psw
	348   0206 4FCDOOOO          mov c,a ! call				?cono
	349	020A	FlFE6lD8          pop psw ! cpi 'a' ! rc
	350   020E D620              sui 'a'-'A'					; make upper case
	351	0210	C9                ret
	352
	353
	354	0211	          disk$command	ds	1	; current wd1797 command
	355	0212	          select$mask	ds	1	; current drive select code
	356	0213	          old$select	ds	1	; laat drive selected
	357	0214	          old$track	ds	1	; last track seeked to
	358
	359	0215	          diik$status	ds	1	; last error status code for 
messages
	360
	361	0216	1020      select$table	db	000l$OOOOb,0Ol0$OOOOb ; for now 
use drives C and D
	362
	363
	364		                  ; error	message	components
	365
	366	0218	2C2Os26s6lread$msg	db	', Read',O
	367	021F	2C2O577269write$msg	db	', Write',O
	36!!
	369	0227	1802      operation$name	dw	read$msg
	370
	371		                  ; table	of pointers to		error message strings
	372		                  ;	first entry is		for bit 7 of 1797 status byte
	373
	374	0229	3902      error$table	dw	b7$msg
	375	022B	4502	dw	b6$msg
	376	0220	4F02	dw	b5$msg
	377	022F	5702	dw	b4$msg
	378	0231	6A02	dw	b3$msg
	379	0233	7002	dw	b2$msq
	380	0235	7C02	dw	bl$msg
	381	0237	8302	dw	b0$msg
	382
	383	0239	2O4E6F7420b7$msg	db	' Not ready,',O
	384	0245	2O5O726F74b6$msq	db	' protect,',0
	385	024F	2O466l756Cb5$msg	db	' Fault,',O
	386	0257	205265636Fb4$msg	db	' Record not found,',0
	387	026A	204352432Cb3$msg	db	' CRC,',0
	388	0270	204C6F7374b2$msg	db	' Lost	dsta,',O
	389	027C	2044524551b1$msg	db	' DREQ,',0
	390	0283	2042757379b0$msg	db	' Busy,',O
	391
	392	028A	2052657472error$msg	db	' Retry	(Y/N) ? ',O
	393
	394
	395
	396		                  ; command string for Z8ODMA device for 
normal operation
	397
	398	029A	C3        dma$block	db	OC3h	; reset DMA channel
	399	0298	14	db	14h	; channel A is incrementing memory
	400	029C	28	db	28h	; channel B is fixed port address
	401	029D	8A	db	8Ah	; RDY is high, CE/ only, stop on EOB
	402	029E	79	db	79h	; program all of ch. A, xfer B->A (temp)
	403	029F	          zdma$dma	ds	2	; starting DMA address
	404	02A1	7F00	dw	128-1	; 128 byte sectors in SD
	405	02A3	85	db	85h	; xfer byte at a time, ch B is 8 bit address
	406	02A4	07	db	p$fddata ; ch B port address (1797 data port)
	407	02A5	CF	db	OCFh	; load B as source register
	408	02A6	05	db	O5h	; ;'fer A->B
	409	02A7	CF	db	OCFh	; load A as source register
	410	02A8	          zdma$direction	ds	1	; either A->B or B->A
	411	02A9	CF	db	OCFh	; load final source register
	412	02AA	87	db	87h	; enable DMA channel
	413	0011	=         dmab$length	equ	$-dma$block
	414
	415
	416
	417	02AB	C3        read$id$block	db	OC3h	; reset DMA channel
	418	O2AC	14	db	14h	; channel A is incrementing memory
	419	O2AD	28	db	28h	; channel B is fixed port address
	420	O2AE	8A	db	8Ah	; RDY is high, CE/ only, stop on EOB
	421   O2AF		70	db	7Dh	; program all of ch. A, xfer A->B (temp)
	422	02B0	1100	dw	id$buffer ; starting DMA address
	423	0282	0500	dw	6-1	; Read ID always xfers 6 bytes


Listing 1-4.  (continued)
cP/M 3 System Guide	I.4  z80 DMA Single-density Disk Handler
	424	02B4	85		db	85h	; byte xfer, ch B is 8 bit address
	425	02B5	07		db	p$fddata ; ch B port address (1797 data port)
	426	02B6	CF		db	OCFh	; load dest (currently source) register
	427	02B7	01		db	Olh	; xfer B->A
	428	02B8	CF		db	OCFh	; load source register
	429	0259	87		db	87h	; enable DMA channel
	430	000F	=	length$id$dmab	equ	$-read$id$block
	431
	432			       cseg	; easier to put		ID buffer in common
	433
	434	0011		id$buffer	ds	6	; buffer to hold ID field
	435	; track
	436	; Side
	437	; Sector
	438	; length
	439	; CRC 1
	440	; CRC 2
441
   442	0017			end
B0MSG		0283	381	390#
BlMSG		027C	380	389#
B2MSG		0270	379	388#
B3MSG		026A	378	3871
B4MSG		0257	377	386#
B5MSG		024F	376	3851
B6MSG		0245	375	384#
B7MSG		0239	374	383#
BC		0000
BELL	0007	52#
CANCEL	01A6	289#
CHECKSEEK	01A9	226	257	296#
CR	OOOD	50#
DE	0002
DISKC0MMAMD	0211	203	249	354#
DISKSTATUS	0215	251	275	359#
DMABLENGTH	0011	239	4131
DMABLOCK	029A	238	398#	413
DPBSD	0000	62	66	79	83	93#
ERRMl	0186	277#	281
ERRORMSG	028A	283	392#
ERRORTABLE	0229	276	374#
EXECCOMMAND	OlD5	250	310	316	323#	337
FDINITD	OOBE	60	143#
FDINIT1	OOCD	77	152#
FDIMITNEXT	OOC1	145#	150
FDLOGIN	00DB	59	76	1621
FDREAD	OODC	58	75	188#
FDSDO	OOOA	14	621
FDSDl	OO5C	14	791
FDWRITE	00E6	57	74	193#
HARDERROR	01A3	263	286#
HL	0004
IDBUFFER	0011	339	422	4341
IDOK	OlBE	299	302	3051
INITTABLE	OOCE	144	1551
IX	0004
IY	0004
LEMGTMIDDMAB	000F	333	430#
LF	OOOA	511
MORERETRIES	0l0D	2101	285
NEWTRACK	012D	217	221	225#
OLDSELECT	0213	215	356#
OLDTRACK	0214	219	3571
OPERATIOMMAME	0227	202	271	3691
PBANkSELECT	0025	243	247
PBAUDCON1	OOOC















Listing 1-4.  (continued)
CP/M 3 System Guide	I.4  Z80 DMA Single-density Disk Handler
PBAUDCON2	0030
PBAUDCON34	0031
PBAUDLPT1	OOOE
PBAUDLPT2	0032
PBOOT	0014
PCENTDATA	0011
PCENTSTAT	0010
PCON2DATA	002C
PCON2STAT	002D
PCON3DATA	002E
PCON3STAT	002F
PCON4DATA	002A
PCON4STAT	002B
PCONFIGURATION	0024
PCRTDATA	OO1C
PCRTSTAT	001D
PFDCMND	0004	325
PFDDATA	0007	308	406	425
PFDINT	0008	327
PFDMISC	0009	223
PFDSECTOR	0006	236
PFDSTAT	0004	329
PFDTRACK	0005	235	306
PINDEX	000?
PLPT2DATA	0028
PLPT2STAT	0029
PLPTDATA	OO1E
PLPTSTAT'	OO1F
PRTC	0033
PSELECT	0008	209
PWD1797	0004
PZCTCl	OOOC
PZCTC2	0030
PZDART	OO1C
PZDMA	0000	239	333
PZPIO1	0008
PzPIOlA	OOOA	155
PZPIO1B	000B	157
PZPIO2	0010
PzPIO2A	0012
PZPIO2B	0013
PZPIO3	0024
PZPI03A	0026
PzPIO3B	0027
PZSIO1	0028
PZSIO2	002C
READID	01E1	298	301	331#
READIDBLOCK	02AB	332	417#	430
READMSG	0218	189	366#	369
RESTORE	01D3	303	318#
RETRYOPERATION	OlOF	212#	259
RWCOMMON	COED	191	198#
SAMETRACK	0139	223	234#
SELECTMASK	0212	208	215	355#
SELECTTABLE	0216	207	361#
SPINLOOP	0133	229#	232
STEPOUT	OlCE	300	314#
TRANS	00A4	62	63	79	80	106#
UCI	0202	344	346#
UCONINECHO	OlF5	284	343#	345
WAITIREQ	0107	326*	327
WRITEMSG	021F	194	367*
ZDMADIRECTION	02A8	204	410#
ZDMADMA	029?	205	403*
?CONIN	0000	32	345	347
?CONO	0000	32	348
?CONST	0000	33	344
?PDEC	0000	30
?PDERR	0000	31	269
?PMSG	0000	29	271	280	283
?WBOOT	0000	28	290
@ADRV	0000	18









Listing 1-4.  (continued)
cP/M 3 System Guide	I.4  Z80 DMA Single-density Disk Handler
	@DBNK	0000	20	245
	@DMA	0000	19	205
	@ERMDE	0000	24	263
	@RDRV	0000	18	206
	@SECT	0000	19	236
	@TRK	0000	19	219	235	307


Listing I-4.  (continued)



I.5	Bank and Move Module for CP/M 3 Linked BIOS

	The MOVE.ASM module performs memory-to-memory moves and bank
selects .
	1		 title 'bank & move module for CP/M3 linked BIOS'
	2
	3		 cseg
	4
	5		 public ?move,?xmove,?bank
	6		extrn @cbnk
	7
	8		 maclib z80
	9		 maclib ports
	10
        11                  ?xmove:         ; ALTOS can't perform 
interbank moves
	12	0000 C9	 ret
	13
	14	?move:
	15	0001 EB	xchg            . we are passed	source in DE and dest in 
HL
	16		 ldir            , use Z80 block	move instruction
	17	0002+EDBO	DB      OEDH,OBOH
	18	0004 EB	 xchq            ' need next addresses in same regs
	19	0005 C9	 ret
	20
	21			; by exiting through bank select
	22	?bank:
	23	0006 C5	push b	; save register b for temp
	24	0007 171717E618	ral ! ral ! ral ! ani lBh	; isolate bank in 
proper bit position
	25	OOOC 47	mov b,a	; save in reg B
	26	0000 DB25	 in p$bankselect	; get old memory control byte
	27	000F E6E7BO	ani OE7h ( ora b	; mask out old and merge in new
	28	0012 0325	out p$bankselect	; put new memory control byte
	29	0014 C1	pop b	; restore register b
	30	0015 C9	ret
	31
	32		                         ;	128 bytes at a time
	33
	34	0016	end
BC		0000
DE		0002
HL		0004
IX		0004
IY		0004
PBANKSELECT      0025    26			28
PBAUDCON1		OOOC
PBAUDCON2		0030
PBAUDCON34       0031
PBAUDLPT1		OOOE
PBAUDLPT2		0032
PBOOT		0014
PCENTDATA		0011
PCENTSTAT		0010
PCON2DATA		002C
PCON2STAT		002D
PCON3DATA		002E
PCON3STAT		002F
PCON4DATA		002A
pCON4STAT		002B
PCONFIGURATION   0024
PCRT'DATA		OO1C


Listing I-S.  Bank and Move Module for CP/M 3 Linked BIOS
CP/M 3 System Guide	I.5  Bank & Move Module for Linked BIOS
	pCRTSTAT	001D
	PFDCMND	0004
	pFDDATA	0007
	pFDINT	000B
	PFDMISC	0009
	PFDSECTOR	0006
	PFDSTAT	0004
	PFDTRACK	0005
	PINDEX	000F
	PLPT2DATA	0028
	PLPT2STAT	0029
	PLPTDATA	OO1E
	PLPTSTAT	OO1F
	PRTC	0033
	PSELECT	000B
	PWD1797	0004
	PZCTCl	OOOC
	PZCTC2	0030
	PZDART	OO1C
	PZDMA	0000
	PZPIO1	0008
	PzpIOlA	OOOA
	PzPIO1B	000B
	PZPIO2	0010
	PzPIO2A	0012
	PZPIO2B	0013
	PZPIO3	0024
	PZPI03A	0026
	PZPIO3B	0027
	PZSIO1	002B
	PzSIO2	002C
	?BANK	0006	5	22#
	?MOVE	0001	5	14#
	?XMOVE	0000	5	11#
	@CBNK	0000	6


Listing 1-5.  (continued)



1.6	I/o Port Addresses for z80 Chip-based System:  PORTS.LIB

	This listing is the PORTS.LIB file on your distribution
diskette.  It contains the port addresses for the Z80 chip-based
system with a Western Digital 1797 Floppy Disk Controller.


I/O Port addresses for z80 chip set based system with wd1797 FDC
; chip bases
	p$zdma	equ	0
	p$wd1797	equ	4
	p$zpio1	equ	8
	p$zctcl	equ	12
	P$ zpio2	equ	16
	p$boot	equ	20	; OUT disables boot EPROM
	p$zdart	equ	28	; console 1 and printer 1
	p$zpio3	equ	36
	p$zsio1	equ	40
	p$zsio2	equ	44
	p$zctc2	equ	48


; diskette controller chip ports
	p$fdcmnd	equ	p$wdl797+0
	p$fdstat	equ	p$wdl797+0
	p$fdtrack	equ	p$wd1797+l
	p$fdsector	equ	p$wd1797+2
	p$fddata	equ	p$wd1797+3

; parallel i/O 1


Listing 1-6.  I/O Port Addresses for z80 Chip-based System
CP/M 3 System Guide	I.5  Bank & Move Module for Linked BIOS
	PCRTSTAT	001D
	PFDCMND	0004
	pFDDATA	0007
	PFDINT	0008
	PFDMISC	0009
	PFDSECTOR	0006
	PFDSTAT	0004
	PFDTRACK	0005
	PINDEX	000F
	PLPT2DATA	0028
	PLPT2STAT	0029
	PLPTDATA	OO1E
	PLPTSTAT	OO1F
	PRTC	0033
	PSELECT	0008
	PWD1797	0004
	PZCTCl	OOOC
	PZCTC2	0030
	PZDART	OO1C
	PZDMA	0000
	PZPIO1	0008
	PZPIO1A	OOOA
	PZPIO1B	000B
	PZPIO2	0010
	PZPIO2A	0012
	PZPIO2B	0013
	PZPI03	0024
	PZPI03A	0026
	PZPIO3B	0027
	PZSIO1	002B
	PZSIO2	002C
	?BANK	0006	5	22#
	?MOVE	0001	5	14#
	?XMOVE	0000	5	11#
	@CBNK	0000	6


Listing 1-5.  (continued)



1.6	I/o Port Addresses for z80 Chip-based System:  PORTS.LIB

	This listing is the PORTS.LIB file on your distribution
diskette.  It contains the port addresses for the Z80 chip-based
system with a Western Digital 1797 Floppy Disk Controller.


I/O Port addre!;=e; for Z80 chip set based system with wd1797 FDC
; chip bases
	p$zdma	equ	0
	p$wd1797	equ	4
	p$zpio1	equ	8
	p$zctcl	equ	12
	p$ zpio2	equ	16
	p$boot	equ	20	; OUT disables boot EPROM
	p$zdart	equ	26	; console 1 and printer 1
	p$zpio3	equ	36
	p$zsiol	equ	40
	p$zsio2	equ	44
	p$zctc2	equ	48


; diskette controller chip ports
	p$fdcmnd	equ	p$wdl797+0
	p$fdstat	equ	p$wdl797+0
	p$fdtrack	equ	p$wd1797+l
	p$fdsector	equ	p$wd1797+2
	p$fddata	equ	p$wd1797+3

; parallel I/O 1


Listing 1-6.  I/O Port Addresses for Z80 Chip-based System
CP/M 3 System Guide	I.5  Bank & Move Module for Linked BIOS
	pCRTSTAT	001D
	PFDCMND	0004
	pFDDATA	0007
	PFDINT	0008
	PFDMISC	0009
	pFDSECTOR	0006
	PFDSTAT	0004
	PFDTRACK	0005
	PINDEX	000F
	PLPT2DATA	0028
	PLPT2STAT	0029
	PLPTDATA	OO1E
	PLPTSTAT	OO1F
	PRTC	0033
	PSELECT	0008
	PWD1797	0004
	PZCTCl	OOOC
	PZCTC2	0030
	PZDART	OO1C
	PZDMA	0000
	PZPIO1	0008
	pZPIOlA	OOOA
	PZPIO1B	000B
	PZPIO2	0010
	PZPIO2A	0012
	PZPIO2B	0013
	PZPIO3	0024
	PZPI03A	0026
	PZPIO3B	0027
	PZSIO1	0028
	PZSIO2	002C
	?BANK	0006	5	22#
	?MOVE	0001	5	14#
	?XMOVE	0000	5	11#
	@CBNK	0000	6


Listing 1-5.  (continued)



1.6	I/o Port Addresses for z80 Chip-based System:  PORTS.LIB

	This listing is the PORTS.LIB file on your distribution
diskette.  It contains the port addresses for the Z80 chip-based
system with a Western Digital 1797 Floppy Disk Controller.


I/o Port addresses for Z80 chip set based system with wd1797 FDC
; chip bases
	pSzdma	equ	0
	p$wd1797	equ	4
	p$zpio1	equ	8
	p$zctcl	equ	12
	p$zpio2	equ	16
	p~boot	equ	20	; OUT disables boot EPROM
	p$zdart	equ	28	; console ! and printer !
	p$zpio3	equ	36
	p~zsiol	equ	40
	p$zsio2	equ	44
	p$zctc2	equ	48


; diskette controller chip ports
	p$fdcmnd	equ	p$wdl797+0
	p$~dstx't	equ	p$wdl797+0
	p$fdtrack	equ	p$wd1797+l
	p$fdr@ctor	equ	p$wd1797+2
	p):Lddata	equ	p$wd1797+3
	psra~1e1 LID 1


Listing 1-6.  I/O Port Addresses for Z80 Chip-based System
CP/M 3 System Guide	1.6  I/o Port Addresses
	p$sel~ct	equ p$zpiol+O
	p$fdint	equ p$zpiol+0
	p$fdmisc	equ p$zpiol+l
	p$zpiola	equ pSzpiol+2
	p$zpiolb	equ p$zpiol+3
		; counter timer chip 1
	p$baudconl	equ p$zctcl+0
	p$baudlptl	equ p$zctcl+2
	p$index	equ p$zctcl+3


; parallel I/O 2, Centronics printer interface
	p$cent$atat	equ p$zpio2+0
	p$cent$data	equ p$zpio2+1
	p$zpio2a	equ p$zpio2+2
	p$zpio2b	equ p$zpio2+3
	        ; dual	asynch rcvr/xmtr, console and serial printer ports
	p$crt$data	equ p!:zdart+O
	p$crt$stat	equ p$zddmrt+l
	p$lpt$data	equ p$zdart+2
	p$lpt$Stat	equ p$zdart+3


; Third Parallel I/O device
p$configuration	equ p$zpio3+O
p$bankselect	equ p$zpio3+l
p$zpio3a	equ p$zplo3+2
p$zpio3b	equ p$zpio3+3


; Serial I/O device l, printer 2 and console 4
	p$lpt2data	equ p$zsiol+O
	p$lpt2stat	equ p$zsiol+l
	p$con4data	equ p$zaiol+2
	p$con4stat	equ p$zsiol+3


; Serial I/O device 2, console 2 and 3
	p$con2data	equ p$zSio2+O
	p$con2=tat	equ p$z'sio2+1
	p$con3data	equ p$zsio2+2
	p$con3stat	equ p$zsio2+3


; second Counter Timer Circuit
	p$baudcon2	equ p$zctc2+O
	p$baudcon34	equ p$zctc2+l
	p$baudlpt2	equ p$zctc2+2
	p;rtc	equ p$zctc2+3


Listing 1-6.  (continued)
CP/M 3 System Guide	1.7  Sample Submit FilE


1.7	Sauple Submit File for ASC 8000-15 System

	Digital Research used this SUBMIT file to build the samplE
BIOS.


;Su!:5it file to build sample BIOS for ACS 8000-15 single-density system

rmac bioskrnl
rmac buot
rmac move
rmac chano
rmac drvtbl
r;=ac fdl797sd
rmac scb
link bnkbios3[b,q].bioskrnl,boot,move,chario,drvtbl,fd17975d,scb
gencpm



Listing 1-7.  Sample Submit File for ASC 8000-15 System


End of Appendix I
Appendix
Public Entry Points for CP/M 3 Sample BIOS Modules
	Public
Module  Entry	Input	Return
Name	Point	Function	Parameter	Value

~IOSERNL
	?PMSG	Print Message	HL points to may	none
	?PDEC	Print Decimal	NL=number	none
	?PDERR  Print BIOS Disk	none	none
		Err May Header


HARID
	?CINIT  Char Dev Init	C=Phys Dev #	none
			Dev Parms	in ~CTBL
	?CIST	Char Inp Dev St	B=Phys 0ev	#	A=OO if no input
					A=OFFH if input
					  char available
	?COST	Char Out 0ev St	B=Phys Dev	i	A=OO if output
					  busy
					A=OFFH if output
					  ready
	?CI	Char De" Input	B=Phya Dev	#	A=next available
					  input char
	?CO	Char Dev Output	B"Phys Dev	#
			C=Input Char


~VE
	?MOVE	Memory to Memory	BC=byte count	DE,HL point to
	Move	DE=start source adr	next bytes
		HL=start dest adr	after move
	?xMOVE  Set Banks for	B=OeSt Bank	BC,DE,HL are
	Extended Move	C=Source Bank	unchanged
	?BANK	Select Bank	A=Bank Number	All unchanged


BOOT
	?INIT'	System Init	none	none
	?LDCCP  Load CCP	none	none
	?RLCCP  Reload CCP	none	none
	?TIME	Get/Set Time	C=OOOH if get	none
		C=OFFH if set


Listing J-l.  Public Entry Points for cP/M 3 Sample BIOS Modules


End of Appendix J
