CP/M RMAC ASSEM 1.1	#001	BOOT LOADER MODULE FOR PROF-80 CP/M 3.0

                	title	'Boot loader module for PROF-80 CP/M 3.0'
                
                	; Letzte Aenderung am:
                	; 24.11.1984 (Joachim)
                
 FFFF =         true equ -1
 0000 =         false equ not true
                
 FFFF =         banked	equ true
                
                	public	?init,?ldccp,?rlccp,?time,binit
                	extrn	?pmsg,?conin,?cono,?const,?wboot
                	extrn	@civec,@covec,@aivec,@aovec,@lovec
                	extrn 	@cbnk,?bnksl,?pmsg,?bank,@ctbl
                	extrn	@date,@hour,@min,@sec
                	extrn	monon,monoff,intser
                
                	maclib	cdef
                ;
                	maclib	monvec
                ;
                	maclib	z80
                ;
                	maclib	syspage
                ;
                	maclib	modebaud
                
 0005 =         bdos	equ 5
                
                	if banked
 0001 =         tpa$bank	equ 1
                	else
                tpa$bank	equ 0
                	endif
                
                	dseg	; init done from banked memory
                
                ?init:
 0000 AF3276FF  	xra	a ! sta epromz				;
 0004 3EF0326EFF	mvi	a,com$page ! sta common$page		;
 0009 3EC3323800	mvi	a,0c3h ! sta 38h			; interuppt in
 000E 2100002239	lxi	h,intser ! shld 39h			; bank 0
                
 0014 210000222E	lxi h,xwboot ! shld umleit$getcm + 1		; setze umleit
 001A 210B00223D	lxi h,xconst ! shld umleit$const + 1		; vektoren
 0020 211500224B	lxi h,xconin ! shld umleit$conin + 1		;
 0026 211F00224E	lxi h,xcono ! shld umleit$conout + 1		;
                
 002C 3A13FF    	lda	io$jumperbyte		; waehle richtige Voreinstellung
 002F FE04      	cpi	4 ! jrz io4		; der Geraetetreiber
 0031+2838      	DB	28H,IO4-$-1
 0033 FE03      	cpi	3 ! jrz io3		; in Abhaengigkeit des IO Jumpers
 0035+2829      	DB	28H,IO3-$-1
 0037 FE02      	cpi	2 ! jrz io2
 0039+281A      	DB	28H,IO2-$-1
 003B FE01      	cpi	1 ! jrz io1
CP/M RMAC ASSEM 1.1	#002	BOOT LOADER MODULE FOR PROF-80 CP/M 3.0

 003D+280B      	DB	28H,IO1-$-1
                
 003F 2100081100io0:	lxi h,00800h ! lxi d,00400h ! lxi b,08000h ! jr ioset	; j4 kein jumper 
 0048+182A      	DB	18H,IOSET-$-1
 004A 2100801100io1:	lxi h,08000h ! lxi d,04000h ! lxi b,08000h ! jr ioset	; j4/1-3
 0053+181F      	DB	18H,IOSET-$-1
 0055 2100201100io2:	lxi h,02000h ! lxi d,04000h ! lxi b,08000h ! jr ioset	; j4/2-4
 005E+1814      	DB	18H,IOSET-$-1
 0060 2100101100io3:	lxi h,01000h ! lxi d,04000h ! lxi b,08000h ! jr ioset	; j4/3-5
 0069+1809      	DB	18H,IOSET-$-1
 006B 2100081100io4:	lxi h,00800h ! lxi d,00400h ! lxi b,08000h		; j4/4-6
                
 0074 2200002200ioset:	shld @civec ! shld @covec
                	sded @lovec
 007A+ED53      	DB	0EDH,53H
 007C+0000      	DW	@LOVEC
                	sbcd @aivec
 007E+ED43      	DB	0EDH,43H
 0080+0000      	DW	@AIVEC
                	sbcd @aovec
 0082+ED43      	DB	0EDH,43H
 0084+0000      	DW	@AOVEC
                
                
 0086 3A29FF    	lda bank$err$byte	;sind beide RAM banks ok?
 0089 B7        	ora a ! jrz twobank	;sprung wenn ja
 008A+2834      	DB	28H,TWOBANK-$-1
                
 008C 219400CD00	lxi h,ramtext ! call ?pmsg	;sonst fehlermeldung
                ramfail	jr ramfail
 0092+18FE      	DB	18H,RAMFAIL-$-1
                
                
 0094 0D0A657272ramtext	db 13,10,'error, CP/M 3 needs 128k RAM on PROF-80',13,10,0
                
 00C0 21C700CD00twobank	lxi h,signon$msg ! call ?pmsg			; print signon message
 00C6 C9        	ret
                
 00C7 0D0A0D0A  signon$msg:	db	13,10,13,10
 00CB 50524F462D		db	'PROF-80 CP/M Version 3, sample BIOS  '
 00F0 2843292032		db	'(C) 24.11.1984  Digital Research & Conitec'
 011A 0D0A00    		db	13,10,0
                
                
                binit:
 011D 3A04FF    	lda	baud$jumperbyte		; setze duplex baudrate
 0120 6F2600    	mov	l,a ! mvi h,0		; entsprechend j4
 0123 112C0119  	lxi	d,j4baudlist ! dad d	;
 0127 7E320700  	mov	a,m ! sta @ctbl+7	;
 012B C9        	ret				;
                
                j4baudlist:
 012C 0E        	db	baud$9600
 012D 0C        	db	baud$4800
 012E 0A        	db	baud$2400
 012F 08        	db	baud$1200
CP/M RMAC ASSEM 1.1	#003	BOOT LOADER MODULE FOR PROF-80 CP/M 3.0

 0130 06        	db	baud$300
                
                
                	cseg
                	
                	; diese Routinen werden vom EPROM benutzt
                
                xwboot:
 0000 3E013276FF	mvi a,1 ! sta epromz
 0005 CD0000C300	call monoff ! jmp ?wboot
                
                xconst:
 000B C5D5E5    	push b ! push d ! push h
 000E CD0000    	call ?const
 0011 E1D1C1C9  	pop h ! pop d ! pop b ! ret
                
                xconin:
 0015 C5D5E5    	push b ! push d ! push h
 0018 CD0000    	call ?conin
 001B E1D1C1C9  	pop h ! pop d ! pop b ! ret
                
                xcono:
 001F C5D5E5    	push b ! push d ! push h
 0022 CD0000    	call ?cono
 0025 E1D1C1C9  	pop h ! pop d ! pop b ! ret
                
                	
                	; Laden des CCP.COM von Drive A:
                
                ?ldccp:
 0029 3EC3323800	mvi	a,0c3h ! sta 38h	;setze interuppt vektor
 002E 2100002239	lxi	h,intser ! shld 39h	;in bank 1
                
                	; First time, load the A:CCP.COM file into TPA
 0034 AF32E900  	xra a ! sta ccp$fcb+15		; zero extent
 0038 21000022FA	lxi h,0 ! shld fcb$nr		; start at beginning of file
 003E 11DA00CDA5	lxi d,ccp$fcb ! call open	; open file containing CCP
 0044 3CCA7400  	inr a ! jz no$CCP		; error if no file...
 0048 110001CDAA	lxi d,0100h ! call setdma	; start of TPA
 004E 118000CDAF	lxi d,128 ! call setmulti	; allow up to 16k bytes
 0054 11DA00CDB4	lxi d,ccp$fcb ! call read	; load the thing
                					;
 005A 01DE70    	lxi b,070h*256+p$ram$table	; schalte bank1 f000h
 005D 3E0B      	mvi a,0bh ! outp a		; nach 7000h
 005F+ED79      	DB	0EDH,A*8+41H
 0061 2100011100	lxi h,0100h ! lxi d,07000h	; und kopiere
 0067 01800C    	lxi b,0c80h ! ldir		;
 006A+EDB0      	DB	0EDH,0B0H
 006C 01DE70    	lxi b,070h*256+p$ram$table	;
 006F 3E02      	mvi a,2 ! outp a		;
 0071+ED79      	DB	0EDH,A*8+41H
                					;
 0073 C9        	ret
                
                no$CCP:			; here if we couldn't find the file
 0074 21B900CD00	lxi h,ccp$msg ! call ?pmsg	; report this...
CP/M RMAC ASSEM 1.1	#004	BOOT LOADER MODULE FOR PROF-80 CP/M 3.0

 007A CD0000    	call ?conin			; get a response
 007D C32900    	jmp ?ldccp			; and try again
                
                
 0080 3EC3323800?rlccp:	mvi	a,0c3h ! sta 38h	;setze interrupt sprung
 0085 2100002239	lxi	h,intser ! shld 39h	;in bank 1 neu
                
 008B 01DE70    	lxi b,070h*256+p$ram$table	; 
 008E 3E0B      	mvi a,0bh ! outp a		;
 0090+ED79      	DB	0EDH,A*8+41H
 0092 1100012100	lxi d,0100h ! lxi h,07000h	; kopiere
 0098 01800C    	lxi b,0c80h ! ldir		; ccp
 009B+EDB0      	DB	0EDH,0B0H
 009D 01DE70    	lxi b,070h*256+p$ram$table	;
 00A0 3E02      	mvi a,2 ! outp a		;
 00A2+ED79      	DB	0EDH,A*8+41H
 00A4 C9        	ret
                
                	dseg
                ?time:
 0131 E5        	push	h
 0132 D5        	push	d
 0133 79        	mov	a,c	;lesen oder setzen
 0134 B7        	ora	a	;seze flags
 0135 CACB01    	jz	set$scb	;setze scb neu
                			;setze zeit neu
                	;berechne aus der absolutem zahl das datum
 0138 2A0000    	lhld	@date	;lese datumszahl aus scb
 013B 11DA02    	lxi	d,730	;setze auf 1 jan. 1980
 013E DAC801    	jc	time$ret;zeit vor 1980, keine aenderung
 0141 373F      	stc ! cmc	;loesche carry bit
                	dsbc	d	;subtrahiere
 0143+ED52      	DB	0EDH,D*8+42H
 0145 0E00      	mvi	c,0	;zaehler fuer jahreszahl nach 1980
                year$loop:
 0147 116E01    	lxi	d,366	;ziehe schaltjahr ab
 014A CD5B01    	call	sub$end	;
 014D 116D01    	lxi	d,365	;ziehe drei normale jahre ab
 0150 CD5B01    	call	sub$end	;
 0153 CD5B01    	call	sub$end	;
 0156 CD5B01    	call	sub$end	;
                	jr	year$loop	;beginne wieder von vorn
 0159+18EC      	DB	18H,YEAR$LOOP-$-1
                
                sub$end:
 015B 373F      	stc ! cmc	;loesche  carry bit
                	dsbc	d	;ziehe de von hl ab
 015D+ED52      	DB	0EDH,D*8+42H
                	jrc	sub$end1
 015F+3802      	DB	38H,SUB$END1-$-1
 0161 0C        	inr	c	;jahr  zaehler um eins weiter
 0162 C9        	ret
                
                sub$end1:		;ok jahreszahl ist berrechnet
 0163 33        	inx	sp	;setze stack richtig
 0164 33        	inx	sp	;
CP/M RMAC ASSEM 1.1	#005	BOOT LOADER MODULE FOR PROF-80 CP/M 3.0

 0165 19        	dad	d	;in hl jetzt die tage des verbleibenden jahres
 0166 79        	mov	a,c	;speichere jahr ab
 0167 326C02    	sta	jahr	;
 016A CD3602    	call	set$feb	;setze februar bei schaltjahr auf 29 sonst 28
                			;berechne monat
 016D 114202    	lxi	d,monat$list
 0170 0600      	mvi	b,0	;
                monat$loop:
 0172 1A        	ldax	d	;lade monats anzahl
 0173 4F        	mov	c,a	;setze de
 0174 373F      	stc ! cmc	;loesche carry
                	dsbc	b	;ziehe monat ab
 0176+ED42      	DB	0EDH,B*8+42H
                	jrc	monat$loop$end	;wenn carry, monat erreicht
 0178+3803      	DB	38H,MONAT$LOOP$END-$-1
 017A 13        	inx	d	;zeige auf naechsten monat
                	jr	monat$loop
 017B+18F5      	DB	18H,MONAT$LOOP-$-1
                monat$loop$end:
 017D 09        	dad	b	;monat wieder dazu
 017E 7D        	mov	a,l	;speichere tag ab
 017F 326E02    	sta	tag	;
 0182 EB        	xchg		;berrechne monatszahl aus d
 0183 114202    	lxi	d,monat$list
 0186 373F      	stc ! cmc
                	dsbc	d	;in l steht jetzt monat ab 0
 0188+ED52      	DB	0EDH,D*8+42H
 018A 7D        	mov	a,l
 018B 3C        	inr	a	;speichere monat ab. jan=1,.. dez=0ch
 018C 326D02    	sta	monat	;
                			;ok, datum ist berrechnet
 018F 07        	rlc		;bringe monat in die oberen 4 bit
 0190 07        	rlc
 0191 07        	rlc
 0192 07        	rlc
 0193 E6F0      	ani	0f0h
 0195 3218FF    	sta	phys$time+4	;lege monat ab
 0198 3A6E02    	lda	tag		;lege tag ab
 019B CD2B02    	call	bindez		;wandle in bcd zahl
 019E 3217FF    	sta	phys$time+3
 01A1 3A0000    	lda	@hour		;lege sunde ab
 01A4 3216FF    	sta	phys$time+2
 01A7 3A0000    	lda	@min		;lege minute ab
 01AA 3215FF    	sta	phys$time+1
 01AD 3A0000    	lda	@sec		;lege sekunde ab
 01B0 3214FF    	sta	phys$time
                	
 01B3 CD4E02    	call	set$phys$time	;setze zeit, und lese shiftreg aus
                
 01B6 3A6C02    	lda	jahr		;speichere jahr im shiftregister
 01B9 E61F      	ani	01fh		;nur fuenf bits vom jahr
 01BB 47        	mov	b,a
 01BC 3A1DFF    	lda	shift$cont+4	;rette ober 3 bits dieser zelle
 01BF E6E0      	ani	0e0h
 01C1 B0        	ora	b		;packe jahr dazu
 01C2 321DFF    	sta	shift$cont+4
CP/M RMAC ASSEM 1.1	#006	BOOT LOADER MODULE FOR PROF-80 CP/M 3.0

                	
 01C5 CD6202    	call	set$shift	;lade shiftregister zurueck
                
                time$ret:
 01C8 D1        	pop	d
 01C9 E1        	pop	h
 01CA C9        	ret
                
                set$scb:
                		; setze das datum und die uhrzeit im
                		; system control block
                		;
 01CB CD5802    	call	read$phys$time	;lese die uhr aus
 01CE 3A1DFF    	lda	shift$cont+4	;lese jahres offset
 01D1 CD3602    	call	set$feb		;setze februar entspr.
                		; berechne absolute tageszahl
 01D4 210000    	lxi	h,0
 01D7 3A17FF    	lda	phys$time+3	;lese tag ein
                set$scb1:			;und wandle in binaerzahl
 01DA 23        	inx	h		;erhoehe h um eins
 01DB 3D        	dcr	a		;akku eins dezimal weniger
 01DC 27        	daa
                	jrnz	set$scb1
 01DD+20FB      	DB	20H,SET$SCB1-$-1
                				;in hl steht jetzt der tag
 01DF 3A18FF    	lda	phys$time+4	;lade monat
 01E2 0F        	rrc			;schieb 4 bit nach rechts
 01E3 0F        	rrc
 01E4 0F        	rrc
 01E5 0F        	rrc
 01E6 E60F      	ani	0fh		;monat steht in den untern 4 bit
 01E8 114202    	lxi	d,monat$list	;zeiger auf die liste mit den monatstagen
 01EB 0600      	mvi	b,0
                set$scb2:
 01ED 3D        	dcr	a		;ende der monats addition?
                	jrz	set$scb3
 01EE+2808      	DB	28H,SET$SCB3-$-1
 01F0 F5        	push	psw		;rette akku
 01F1 1A        	ldax	d
 01F2 4F        	mov	c,a
 01F3 F1        	pop	psw
 01F4 09        	dad	b		;monat zu hl
 01F5 13        	inx	d		;zeiger auf naechsten monat
                	jr	set$scb2
 01F6+18F5      	DB	18H,SET$SCB2-$-1
                set$scb3:			;die tage des laufenden jahres sind in hl
 01F8 3A1DFF    	lda	shift$cont+4	;lade jahres offset zu 1980
 01FB E61F      	ani	1fh		;nur die untern 5 bits fuer jahres offset
 01FD 116D01    	lxi	d,365		;fuer jedes jahr 365 tage
 0200 47        	mov	b,a		;b dient als zaehler
 0201 B7        	ora	a
                	jrz	set$scb6	;wenn jahreszahl=0
 0202+280B      	DB	28H,SET$SCB6-$-1
                set$scb4:
 0204 78        	mov	a,b		;wenn schaltjahr, ein tag mehr
 0205 E603      	ani	3		;schaltjahr wenn untere 2 bits 01
CP/M RMAC ASSEM 1.1	#007	BOOT LOADER MODULE FOR PROF-80 CP/M 3.0

 0207 FE01      	cpi	1		;
                	jrnz	set$scb5	;sprung wenn kein schaltjahr
 0209+2001      	DB	20H,SET$SCB5-$-1
 020B 23        	inx	h		;ein tag mehr
                set$scb5:
 020C 19        	dad	d		;365 tage dazu
                	djnz	set$scb4	;addiere fuer alle jahre
 020D+10F5      	DB	10H,SET$SCB4-$-1
                set$scb6:			;in hl jetzt offset ab 1 jan 1980
 020F 11DA02    	lxi	d,730		;berechene offset ab 1 jan 1978
 0212 19        	dad	d		;ok
 0213 220000    	shld	@date		;ab, in scb
                				;
                				;uebertrage noch uhrzeit
 0216 3A14FF    	lda	phys$time	;sekunden
 0219 320000    	sta	@sec		;
 021C 3A15FF    	lda	phys$time+1	;minuten
 021F 320000    	sta	@min		;
 0222 3A16FF    	lda	phys$time+2	;stunden
 0225 320000    	sta	@hour		;
 0228 C3C801    	jmp	time$ret	;alles ok
                
                
                
                bindez:	;binaer dezimalwandlung im akku
 022B B7        	ora	a	;akku=0
 022C C8        	rz		;alles ok
 022D C5        	push	b	;rette bc
 022E 47        	mov	b,a	;b=zaehler
 022F AF        	xra	a	;akku=0
 0230 3C        bindez1	inr	a	;akku=akku+1
 0231 27        	daa		;dez. korr.
                	djnz	bindez1
 0232+10FC      	DB	10H,BINDEZ1-$-1
 0234 C1        	pop	b
 0235 C9        	ret
                
                set$feb:
                	;pruefe ob in akku schaltjahr
                	;dann setze tage im februar auf 29
                	;sonst auf 28
 0236 E603      	ani	3	;untere 2 bits null
 0238 3E1D      	mvi	a,29
                	jrz	set$feb1
 023A+2802      	DB	28H,SET$FEB1-$-1
 023C 3E1C      	mvi	a,28	;kein schaltjahr, 28 tage
                set$feb1:
 023E 324302    	sta	monat$list+1	;speichere im februar ab
 0241 C9        	ret
                
                monat$list:
                	; liste der tage im monat
                	; erster eintrag fuer jan. dann feb usw.
 0242 1F1C1F1E1F	db	31,28,31,30,31,30
 0248 1F1F1E1F1E	db	31,31,30,31,30,31
                
CP/M RMAC ASSEM 1.1	#008	BOOT LOADER MODULE FOR PROF-80 CP/M 3.0

                
                ; routinen zum ein und auslesen der uhrzeit
                ; fuer den upd 1990
                
                
                set$phys$time:
 024E CD0000    	call	monon
 0251 CD9C00    	call	mset$phys$time
 0254 CD0000    	call	monoff
 0257 C9        	ret
                
                read$phys$time:
 0258 CD0000    	call	monon
 025B CD9F00    	call	mread$phys$time
 025E CD0000    	call	monoff
 0261 C9        	ret
                
                set$shift:
 0262 CD0000    	call	monon
 0265 CDA200    	call	mset$shift
 0268 CD0000    	call	monoff
 026B C9        	ret
                
 026C           jahr	ds	1
 026D           monat	ds	1
 026E           tag	ds	1
                
                
                	cseg
                
                	; CP/M BDOS Function Interfaces
                
                open:
 00A5 0E0FC30500	mvi c,15 ! jmp bdos		; open file control block
                
                setdma:
 00AA 0E1AC30500	mvi c,26 ! jmp bdos		; set data transfer address
                
                setmulti:
 00AF 0E2CC30500	mvi c,44 ! jmp bdos		; set record count
                
                read:
 00B4 0E14C30500	mvi c,20 ! jmp bdos		; read records
                
                
 00B9 0D0A42494Fccp$msg		db	13,10,'BIOS Err on A: No CCP.COM file',0
                
                
 00DA 0143435020ccp$fcb		db	1,'CCP     ','COM',0,0,0,0
 00EA           		ds	16
 00FA 000000    fcb$nr		db	0,0,0
                
                
 00FD           	end
