.Z80
ASEG

;=====================================================================
;
;	CP/M 2.2 TREIBER FUER CMOS-FLOPPY ALS LAUFWERK D:
;
;			DOBBERTIN-PATCH
;
;=====================================================================

DIRBUF	EQU	0FF80H			; DIRECTORY BUFFER DOBBERTIN
DVCMOS	EQU	'D'			; LAUFWERK D: FUER CMOS
PORTCM	EQU	0FBE0H			; ECB-PORTNUMMER
T_PORT	EQU	0FBEBH			; PORT 8255 (UHR) KONTROLLREGISTER
DHOME	EQU	02518H			; DOBBERTIN : TRACK 0
DDSK	EQU	00B58H			; DOBBERTIN : SELECT DRIVE
DTRK	EQU	00B4AH			; DOBBERTIN : SELECT TRACK
DSEC	EQU	00B51H			; DOBBERTIN : SELECT SECTOR
DDMA	EQU	00BB6H			; DOBBERTIN : INSTALL BUFFER
DMAPUF	EQU	03F80H			; DOBBERTIN : DMA BUFFER
DREAD	EQU	00BCEH			; DOBBERTIN : READ SECTOR
DRD_IN	EQU	00BE5H			; EINSPRUNG ZU READ SECTOR
DWRITE	EQU	00C44H			; DOBBERTIN : WRITE SECTOR
DWR_OUT EQU	00C7AH			; AUSSPRUNG AUS WRITE SECTOR
DWR_IN	EQU	00C7DH			; EINSPRUNG ZU WRITE SECTOR
DLIST	EQU	0252DH			; DOBBERTIN : LIST STATUS
DSECTR	EQU	02530H			; DOBBERTIN : SECTOR TRANSLATION
DCHAR	EQU	04899H			; DOBBERTIN : CHARACTER SET
DPBD	EQU	0FE70H			; DOBBERTIN : DRIVE D DPB
DPHD	EQU	0FE30H			; DOBBERTIN : DRIVE D DPH
DPHCM	EQU	DPHD
PATCH	EQU	02580H			; FREIES RAM IN SYSTEMBANK
BIOSTAB EQU	0FD67H			; TEIL DER SPRUNGTABELLE
SYSCALL	EQU	0FDCAH			; CALL IN SYSTEMBANK
DBDOS	EQU	01700H			; BDOS IN SYSTEMBANK
BIOSJMP	EQU	099H			; LOWBYTE FUER SPRUNGVEKTORPATCH
COMBIOS	EQU	0FF60H			; FREIER PLATZ IM COMMON RAM,
					; eingeblendet bei 04000H
DAT_PB	EQU	COMBIOS - 08000H	; DATEN FUER DATUM UND ZEIT
TTTT	EQU	DAT_PB			; TAGE
HOUR	EQU	TTTT+2
MINUTE	EQU	HOUR+1
SECOND	EQU	MINUTE+1

	org	0100h

	ld	hl,switch
	ld	de,0c000h
	ld	bc,ptc_end-patch+ptc_anf-switch_anf
	ldir
	jp	0c000h

switch:

	.phase 0c000h

switch_anf:

	JP	LADER

TAB_ANF:CALL	SYSCALL
	DW	HOME
	CALL	SYSCALL
	DW	SELDSK
	CALL	SYSCALL
	DW	SETTRK
	CALL	SYSCALL
	DW	SETSEC
	CALL	SYSCALL
	DW	DDMA
	CALL	SYSCALL
	DW	READ
	CALL	SYSCALL
	DW	DWRITE
	CALL	SYSCALL
	DW	DLIST
	CALL	SYSCALL
	DW	DSECTR
	CALL	SYSCALL
	DW	DCHAR
	CALL	SYSCALL
	DW	TIMEGO
		
TAB_END:

DPBCM:		;DISK PARAMETER BLOCK CMOS-FLOPPY (256 K)

SPT_CM:	DW	32			; 32 SEKTOREN/TRACK
BSH_CM: DB	3			; 1-K-BLOECKE
BLH_CM:	DB	7			; 1-K-BLOECKE
EXM_CM:	DB	0			; 1 EXTENT/EINTRAG
DSM_CM:	DW	256-1			; MAX. BLOCKNUMMER
DRM_CM:	DW	64-1			; 64 DIR-EINTRAEGE
ALO_CM:	DB	0C0H,00H		; 2 BLOECKE BESETZT
CKS_CM:	DW	0			; KEIN DISK-WECHSEL
OFF_CM:	DW	0			; KEINE SYSTEM-SPUREN

DPBEND:


LADER:	DI
	CALL	BANK0			; SYSTEMBANK EINBLENDEN

	LD	HL,PTC_ANF
	LD	DE,PATCH
	LD	BC,PTC_END-PATCH
	LDIR

	LD	HL,DWR_OUT
	LD	DE,WRITE
	LD	A,0C3H
	LD	(HL),A
	INC	HL
	LD	(HL),E
	INC	HL
	LD	(HL),D

	LD	HL,DBDOS+011H
	LD	A,BIOSJMP
	LD	(HL),A			; TIMEBIOS INSTALLIEREN

	CALL	BANK1			; SYSTEMBANK AUSBLENDEN

	LD	HL,DPBCM
	LD	BC,DPBEND-DPBCM
	LD	DE,DPBD
	LDIR				; DPB EINTRAGEN

	LD	HL,TAB_ANF
	LD	BC,TAB_END-TAB_ANF
	LD	DE,BIOSTAB
	LDIR				; NEUE SPRUNGTABELLE

	LD	HL,(0001)		; BEGINN BIOS
	LD	DE,0F20EH		; 
	ADD	HL,DE			; BEGINN BDOS+011H
	LD	(HL),099H		; BIOSTIME
	
	EI

	LD	DE,MESSAGE
	LD	C,9
	CALL	5
	RET


BANK0:	LD	BC,07FC1H
	OUT	(C),C
	RET

BANK1:	LD	BC,07FC2H
	OUT	(C),C
	RET

MESSAGE:DB	0DH,0AH,'CPM2INIT V3.6 vom 24.02.89',0DH,0AH,0AH
	DB	09H,'CMOS-Floppy als D: installiert.',0DH,0AH
	DB	09H,'Z80-Realtime-BIOS  installiert.',0DH,0AH,'$'


PTC_ANF:
	.DEPHASE

	.PHASE	PATCH


HOME:	XOR	A
	LD	(TRACK),A
	LD	A,(DRIVE)
	CP	DVCMOS-'A'
HOM_EX:	JP	NZ,DHOME
	RET

SELDSK:	LD	A,C
	LD	(DRIVE),A
	CP	DVCMOS-'A'
SEL_EX:	JP	NZ,DDSK
	LD	HL,DPHCM
	RET

SETTRK:	LD	(TRACK),BC
	JP	DTRK

SETSEC:	LD	(SEKT),BC
	JP	DSEC

READ:	LD	A,(DRIVE)
	CP	DVCMOS-'A'
RD_EX:	JP	NZ,DREAD

RAR: 	CALL	STDRV

RDLOOP: INI
	INC	B
	DEC	D
	JR	NZ,RDLOOP

	XOR	A
	JP	DRD_IN			; WEITER MIT BANKSWITCH USW.

STDRV:	DI
	LD	BC,PORTCM
	LD	A,(TRACK)
	LD	D,A
	LD	A,(SEKT)
	LD	E,A
CMFL:	SLA	E
	SLA	E
	SLA	E
	SRL	D
	RR	E
	SRL	D
	RR	E
	SRL	D
	RR	E
STOUT:	OUT	(C),E
	INC	C
	OUT	(C),D
	DEC	C
	LD	HL,DMAPUF
	LD	D,080H
	
	RET

WRITE: 	LD	A,(DRIVE)
	CP	DVCMOS-'A'
JMP7:	JR	Z,RAW

	LD	A,(0D29H)			; ORIGINAL CODE DOBBERTIN
	JP	DWR_IN				; WEITER IM ORIGINAL

RAW: 	CALL	STDRV

WRCMOS:	INC	C
	INC	C

WRLOOP:	OUTI
	INC	B
	DEC	D
	JR	NZ,WRLOOP

	LD	BC,07FC0H
	OUT	(C),C
	XOR	A
	POP	BC			; ORIGINAL DOBBERTIN
	RET


DRIVE:	DW	0			; AKTUELLES LAUFWERK
TRACK:	DW	0			; AKTUELLER TRACK
SEKT:	DW	0			; AKTUELLER SEKTOR
DMA:	DW	0			; AKTUELLE DMA-ADRESSE

;******************************************************************************
;******************************************************************************

.RADIX 16

OUTA	MACRO	X
	LD	A,X
	OUT	(C),A
	ENDM

C_READ  MACRO	REG,BUF			; UHR-REGISTER LESEN
	CALL	UPDATE			; UPDATE-ZYKLUS ABWARTEN
	LD	L,REG			; UHR-REGISTER
	CALL	C_RD
	LD	A,H			; GELESENER WERT
	LD	HL,BUF
	LD	(HL),A			; WERT SCHREIBEN
	ENDM

C_WRITE MACRO	REG,BUF			; UHR-REGISTER SCHREIBEN
	LD	HL,BUF
	LD	A,(HL)			; WERT HOLEN
	LD	L,REG			; REGISTER
	LD	H,A			; WERT
	CALL	C_WR			; REIN DAMIT
	ENDM

BCD2BIN	MACRO	BUF
	LD	A,(BUF)
	CALL	BCDBIN
	LD	(BUF),A
	ENDM

TIMEGO:	push	bc
	ld	bc,07fc7h		; bank 3' bei 04000h
	out	(c),c
	pop	bc
	XOR	A
	OR	C			; C=0, DANN LESEN
	JP	NZ,SETTIME

GETTIME:DI
	C_READ  04,HOUR
	C_READ  02,MINUTE
	C_READ	00,SECOND
	C_READ  07,DAY
	C_READ  08,MONTH
	C_READ	09,YEAR

	BCD2BIN	DAY
	BCD2BIN	MONTH
	BCD2BIN	YEAR

	SUB	04E			; DEC 78 = ANFANGSJAHR
	LD	B,A
	LD	HL,0
	LD	DE,016D			; DEC 365

JAHRE:	ADD	HL,DE
	DJNZ	JAHRE

	LD	A,(YEAR)
	LD	B,A
	LD	A,04E			; DEC 78
S_TAGE:	INC	A
	CP	B			; AKTUELLES JAHR ?
	JR	Z,NEUJAHR		; DANN UNTEN WEITER
	CALL	SCHALT			; SCHALTJAHR ?
	JR	S_TAGE

NEUJAHR:LD	(TTTT),HL		; TAGE MERKEN
	AND	3			; AKTUELLES JAHR = SCHALTJAHR ?
	JR	Z,NEU_2			; DANN ANDERE TABELLE
NEU_1:	LD	HL,MONTAB1-2
	JR	MONATE
NEU_2:	LD	HL,MONTAB2-2

MONATE:	LD	A,(MONTH)
	LD	B,A
M_TAGE:	INC	HL
	INC	HL
	DJNZ	M_TAGE			; RICHTIGEN TABELLENEINTRAG SUCHEN
	LD	A,(HL)			; LOWBYTE
	INC	HL
	LD	H,(HL)			; HIGHBYTE
	LD	L,A
	EX	DE,HL
	LD	HL,(TTTT)		; BISHERIGER WERT
	ADD	HL,DE			; PLUS VOLLE MONATE
	LD	D,0
	LD	A,(DAY)
	LD	E,A
	ADD	HL,DE			; PLUS TAGE IM MONAT
	
	LD	(TTTT),HL		; IN PARAMETERBLOCK

	LD	HL,COMBIOS		; ADRESSE UEBERGEBEN
	LD	A,(SECOND)		; SEKUNDEN IN A
	EI

	RET				; ZURUECK ZUM PROGRAMM

;------------------------------------------------------------------------------

SETTIME:DI
	C_WRITE 04,HOUR
	C_WRITE 02,MINUTE
	C_WRITE 00,SECOND
	LD	HL,(DAT_PB)		; TAGE IN HL
	CALL	DATEHL
	LD	(DAY),A
	LD	A,L
	LD	(MONTH),A
	LD	A,H
	LD	(YEAR),A
	C_WRITE 07,DAY
	C_WRITE 08,MONTH
	C_WRITE 09,YEAR
	EI
	RET

;------------------------------------------------------------------------------

C_RD:	CALL	C_INIT			; 8255 ANPASSEN
	INC	BC
	INC	BC			; KONTROLLREGISTER 8255
	OUTA	089			; MODE 0, KONTROLL-WORT 5
	DEC	BC
	DEC	BC			; 8255 PORT B
	OUTA	01D			; CE- = 1, AS = 0, R/W- = 1, DS = 1
	OUTA	01C			; CE- = 0, AS = 0, R/W- = 1, DS = 1
	OUTA	014			; CE- = 0, AS = 0, R/W- = 1, DS = 0
	INC	BC			; 8255 PORT C
	IN	H,(C)			; REGISTER LESEN
	DEC	BC
C_EXIT:	OUTA	01C			; CE- = 0, AS = 0, R/W- = 1, DS = 1
	OUTA	01D			; CE- = 1, AS = 0, R/W- = 1, DS = 1
	RET

;------------------------------------------------------------------------------

C_WR:	CALL	C_INIT
	OUTA	01D
	OUTA	01C
	INC	BC
	OUT	(C),H
	DEC	BC
	OUTA	18
	JR	C_EXIT

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

C_INIT:	LD	BC,T_PORT		; 8255 KONTROLLREGISTER	
	OUTA	080			; MODE 0, KONTROLL-WORT 0
	DEC	BC
	DEC	BC			; 8255 PORT B
	OUTA	01F			; CE- = 1, AS = 1, R/W- = 1, DS = 1
	OUTA	01E			; CE- = 0, AS = 1, R/W- = 1, DS = 1
	INC	BC			; 8255 PORT C
	OUT	(C),L			; REGISTERNUMMER
	DEC	BC			; 8255 PORT B
	OUTA	01A			; CE- = 0, AS = 1, R/W- = 0, DS = 1
	OUTA	01E			; CE- = 0, AS = 1, R/W- = 1, DS = 1
	OUTA	01F			; CE- = 1, AS = 1, R/W- = 1, DS = 1
	RET

;------------------------------------------------------------------------------

UPDATE:	LD	L,0A			; KONTROLLREGISTER UHR
UPD_2:	CALL	C_RD			; LESEN
	BIT	7,H			; UPDATE-BIT
	JR	NZ,UPD_2		; GESETZT, DANN WARTEN
	RET

;------------------------------------------------------------------------------

SCHALT:	PUSH	AF
	AND	3
	JR	NZ,S_EXIT
	INC	HL
S_EXIT: POP	AF
	RET

;------------------------------------------------------------------------------

BCDBIN: PUSH	AF
	AND	0F0			; HIGHNIBBLE
	RRCA
	RRCA
	RRCA
	RRCA
	LD	H,0
	LD	L,A			; IN HL
	LD	DE,0A			; MAL 10
	CALL	MULT			; HL = HL * DE
	LD	B,L			; MERKEN
	POP	AF
	AND	0F			; LOWNIBBLE
	ADD	A,B
	RET

;------------------------------------------------------------------------------

MULT:	OR	L			; ACHTUNG: HIGHBYTE=0 MUSS STIMMEN !
	RET	Z			; LOW = 0, DANN FERTIG
	LD	A,D
	OR	E
	LD	A,L
	LD	L,E
	LD	H,D
	RET	Z			; DE=0 --> HL = 0
	CP	3			; < 3
	JR	C,LT_3			; DANN EINFACHER
	SCF
MULT_1:	ADC	A,A
	JR	NC,MULT_1
MULT_2:	ADD	HL,HL
	RET	C
	ADD	A,A
	JR	NC,MULT_3
	ADD	HL,DE
	RET	C
MULT_3:	CP	080
	JR	NZ,MULT_2
	RET

LT_3:	CP	1
	RET	Z
	ADD	HL,HL
	RET

;------------------------------------------------------------------------------

.RADIX 10

MONTAB1:DW	0			; JANUAR
	DW	31			; FEBRUAR
	DW	59			; MAERZ
	DW	90			; APRIL
	DW	120			; MAI
	DW	151			; JUNI
	DW	181			; JULI
	DW	212			; AUGUST
	DW	243			; SEPTEMBER
	DW	273			; OKTOBER
	DW	304			; NOVEMBER
	DW	334			; DEZEMBER

MONTAB2:DW	0			; JANUAR
	DW	31			; FEBRUAR
	DW	60			; MAERZ
	DW	91			; APRIL
	DW	121			; MAI
	DW	152			; JUNI
	DW	182			; JULI
	DW	213			; AUGUST
	DW	244			; SEPTEMBER
	DW	274			; OKTOBER
	DW	305			; NOVEMBER
	DW	335			; DEZEMBER

YEAR:	DB	0
MONTH:	DB	0
DAY:	DB	0

;------------------------------------------------------------------------------

; Module Name:	DATEHL
; Author:	Carson Wilson
; Version:	1.0
; Date: 	25 Sept 87

;
; DATEHL converts the value in HL to BCD year, month, day
;	 for use with Z80DOS time stamps.
;
; Inputs:	HL contains hex days since December 31, 1977
;
; Outputs:	H contains BCD 20th century year
;		L contains BCD month
;		A contains BCD day
;
;		Zero flag set (Z) and A=0 if invalid date (zero) detected,
;		Zero flag reset (NZ) and A=0ffh otherwise.

; Adapted from B5C-CPM3.INS

DateHL:
	ld	a,h
	or	l		; Test blank date (zero)
	ret	z		; Return Z and A=0 if so

	ld	(days),hl	; Save initial value
	ld	b,78		; Set years counter
loop:
	call	ckleap
	ld	de,-365		; Set up for subtract
	jp	nz,nolpy	; Skip if no leap year
	dec	de		; Set for leap year
nolpy:
	add	hl,de		; Subtract
	jp	nc,ydone	; Continue if years done
	ld	a,h
	or	l
	jp	z,ydone
	ld	(days),hl	; Else save days count
	inc	b		; Increment years count
	jp	loop		; And do again
;
; The years are now finished, the years count is in 'B' (HL is invalid)
;
ydone:
	ld	a,b
	call	binbcd
	ld	(dyear),a	; save BCD year
;
	call	ckleap		; Check if leap year
	ld	a,-28
	jp	nz,febno	; February not 29 days
	ld	a,-29		; Leap year
febno:
	ld	(feb),a		; Set february
	ld	hl,(days)	; Get days count
	ld	de,mtable	; Point to months table
	ld	b,0ffh		; Set up 'B' for subtract
	ld	a,0		; Set a for # of months
mloop:
	push	af
	ld	a,(de)		; Get month
	ld	c,a		; Put in 'C' for subtract
	pop	af
	ld	(days),hl	; save days count
	add	hl,bc		; Subtract
	inc	de		; Increment months counter
	inc	a
	jp	c,mloop		; Loop for next month
;
; The months are finished, days count is on stack.  First, calculate
; month.
;
mdone:
	ld	b,a		; Save months
	ld	hl,(days)
	ld	a,h
	or	l
	jp	nz,nzd
	dec	de
	dec	de
	ld	a,(de)
	cpl
	inc	a
	ld	l,a
	dec	b
nzd:
	ld	a,l		; Retrieve binary day of month
	call	binbcd		; Convert to BCD
	push	af		; Save day in A
;
	ld	a,b		; Retrieve the binary month
	call	binbcd		; Convert binary month to BCD
	ld	l,a		; Return month in L
;
	ld	a,(dyear)
	ld	h,a		; Return year in H
;
	or	0ffh		; Return no error
	pop	af		; Restore day
	ret

;
; Support Routines:
;

;
; Check for leap years.
;
ckleap:	ld	a,b
	and	0fch
	cp	b
	ret
;
; Convert A to BCD & store back in A
;
BinBCD:
	or	a
	ret	z
	push	bc
	ld	b,a
	xor	a
BinBCD1:
	add	a,1
	daa
	djnz	BinBCD1
	pop	bc
	ret
;
; Buffers:
;

;
; Months table
;
mtable:
	db	-31		;January
feb:
	db	-28		;February
	db	-31,-30,-31,-30	;Mar-Jun
	db	-31,-31,-30	;Jul-Sep
	db	-31,-30,-31	;Oct-Dec
days:
	ds	2		; temporary buffers
dyear:
	ds	1

	

; END DATEHD.Z80


PTC_END:
	.DEPHASE

	END
			s.
;
ckleap:	ld	a,b
	and	0fch
	cp	b
	ret
;
; Convert A to BCD & store back in A
;
BinBCD:
	or	a
	ret	z
	push	bc
	ld.Z80
ASEG

;=====================================================================
;
;	CP/M 2.2 TREIBER FUER CMOS-FLOPPY ALS LAUFWERK D:
;
;			DOBBERTIN-PATCH
;
;=====================================================================

DIRBUF	EQU	0FF80H			; DIRECTORY BUFFER DOBBERTIN
DVCMOS	EQU	'D'			; LAUFWERK D: FUER CMOS
PORTCM	EQU	0FBE0H			; ECB-PORTNUMMER
T_PORT	EQU	0FBEBH			; PORT 8255 (UHR) KONTROLLREGISTER
DHOME	EQU	02518H			; DOBBERTIN : TRACK 0
DDSK	EQU	00B58H			; DOBBERTIN : SELECT DRIVE
DTRK	EQU	00B4AH			; DOBBERTIN : SELECT TRACK
DSEC	EQU	00B51H			; DOBBERTIN : SELECT SECTOR
DDMA	EQU	00BB6H			; DOBBERTIN : INSTALL BUFFER
DMAPUF	EQU	03F80H			; DOBBERTIN : DMA BUFFER
DREAD	EQU	00BCEH			; DOBBERTIN : READ SECTOR
DRD_IN	EQU	00BE5H			; EINSPRUNG ZU READ SECTOR
DWRITE	EQU	00C44H			; DOBBERTIN : WRITE SECTOR
DWR_OUT EQU	00C7AH			; AUSSPRUNG AUS WRITE SECTOR
DWR_IN	EQU	00C7DH			; EINSPRUNG ZU WRITE SECTOR
DLIST	EQU	0252DH			; DOBBERTIN : LIST STATUS
DSECTR	EQU	02530H			; DOBBERTIN : SECTOR TRANSLATION
DCHAR	EQU	04899H			; DOBBERTIN : CHARACTER SET
DPBD	EQU	0FE70H			; DOBBERTIN : DRIVE D DPB
DPHD	EQU	0FE30H			; DOBBERTIN : DRIVE D DPH
DPHCM	EQU	DPHD
PATCH	EQU	02580H			; FREIES RAM IN SYSTEMBANK
BIOSTAB EQU	0FD67H			; TEIL DER SPRUNGTABELLE
SYSCALL	EQU	0FDCAH			; CALL IN SYSTEMBANK
DBDOS	EQU	01700H			; BDOS IN SYSTEMBANK
BIOSJMP	EQU	099H			; LOWBYTE FUER SPRUNGVEKTORPATCH
COMBIOS	EQU	0FF60H			; FREIER PLATZ IM COMMON RAM,
					; eingeblendet bei 04000H
DAT_PB	EQU	COMBIOS - 08000H	; DATEN FUER DATUM UND ZEIT
TTTT	EQU	DAT_PB			; TAGE
HOUR	EQU	TTTT+2
MINUTE	EQU	HOUR+1
SECOND	EQU	MINUTE+1

	org	0100h

	ld	hl,switch
	ld	de,0c000h
	ld	bc,ptc_end-patch+ptc_anf-switch_anf
	ldir
	jp	0c000h

switch:

	.phase 0c000h

switch_anf:

	JP	LADER

TAB_ANF:CALL	SYSCALL
	DW	HOME
	CALL	SYSCALL
	DW	SELDSK
	CALL	SYSCALL
	DW	SETTRK
	CALL	SYSCALL
	DW	SETSEC
	CALL	SYSCALL
	DW	DDMA
	CALL	SYSCALL
	DW	READ
	CALL	SYSCALL
	DW	DWRITE
	CALL	SYSCALL
	DW	DLIST
	CALL	SYSCALL
	DW	DSECTR
	CALL	SYSCALL
	DW	DCHAR
	CALL	SYSCALL
	DW	TIMEGO
		
TAB_END:

DPBCM:		;DISK PARAMETER BLOCK CMOS-FLOPPY (256 K)

SPT_CM:	DW	32			; 32 SEKTOREN/TRACK
BSH_CM: DB	3			; 1-K-BLOECKE
BLH_CM:	DB	7			; 1-K-BLOECKE
EXM_CM:	DB	0			; 1 EXTENT/EINTRAG
DSM_CM:	DW	256-1			; MAX. BLOCKNUMMER
DRM_CM:	DW	64-1			; 64 DIR-EINTRAEGE
ALO_CM:	DB	0C0H,00H		; 2 BLOECKE BESETZT
CKS_CM:	DW	0			; KEIN DISK-WECHSEL
OFF_CM:	DW	0			; KEINE SYSTEM-SPUREN

DPBEND:


LADER:	DI
	CALL	BANK0			; SYSTEMBANK EINBLENDEN

	LD	HL,PTC_ANF
	LD	DE,PATCH
	LD	BC,PTC_END-PATCH
	LDIR

	LD	HL,DWR_OUT
	LD	DE,WRITE
	LD	A,0C3H
	LD	(HL),A
	INC	HL
	LD	(HL),E
	INC	HL
	LD	(HL),D

	LD	HL,DBDOS+011H
	LD	A,BIOSJMP
	LD	(HL),A			; TIMEBIOS INSTALLIEREN

	CALL	BANK1			; SYSTEMBANK AUSBLENDEN

	LD	HL,DPBCM
	LD	BC,DPBEND-DPBCM
	LD	DE,DPBD
	LDIR				; DPB EINTRAGEN

	LD	HL,TAB_ANF
	LD	BC,TAB_END-TAB_ANF
	LD	DE,BIOSTAB
	LDIR				; NEUE SPRUNGTABELLE

	LD	HL,(0001)		; BEGINN BIOS
	LD	DE,0F20EH		; 
	ADD	HL,COPYRIGHT (C) DIGITAL RESEARCH, 1980     1 ]  ʑ?ʑ!   __0
r)))	O 	@|r}@r. g  å{u  
INVALID MEMORY SIZE$!  $ʡ~/w/wʔ|g* "z|?¸>@G!>0w#w!4~:60+4~u!N#F! 	x,# = !v"z!w6! u#+w+wz
> ZxG}o|g"|! 	:m  c	p!"xp~#c*|! :m  ʅ 	xä
SYNCRONIZATION ERROR${°~#o}oҼüÅ *zZ#:m  m! 	~	#*	DM! 	x	w#!N#F! 		D!_>0w#w1!`4~:60+4*"e@u  
READY FOR "SYSGEN" OR
"SAVE 34 CPM44.COM"$ *|	   
CONSTRUCTING 44k CP/M vers 2.2$                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     f"ff >ͦ      !q:_  
!p+q.*	       !q*&  !p+q* 2!p+q* 2!p+q* 2   2!p+q* !p+q* !p+q* !p+q* 2!p+q*,A			; WERT
	CALL	C_WR			; REIN DAMIT
	ENDM

BCD2BIN	MACRO	BUF
	LD	A,(BUF)
	CALL	BCDBIN
	LD	(BUF),A
	ENDM

TIMEGO:	push	bc
	ld	bc,07fc7h		; bank 3' bei 04000h
	out	(c),c
	pop	bc
	XOR	A
	OR	C			; C=0, DANN LESEN
	JP	NZ,SETTIME

GETTIME:DI
	C_READ  04,HOUR
	C_READ  02,MINUTE
	C_READ	00,SECOND
	C_READ  07,DAY
	C_READ  08,MONTH
	C_READ	09,YEAR

	BCD2BIN	DAY
	BCD2BIN	MONTH
	BCD2BIN	YEAR

	SUB	04E			; DEC 78 = ANFANGSJAHR
	LD	B,A
	LD	HL,0
	LD	DE,016D			; DEC 365

JAHRE:	ADD	HL,DE
	DJNZ	JAHRE

	LD	A,(YEAR)
	LD	B,A
	LD	A,04E			; DEC 78
S_TAGE:	INC	A
	CP	B			; AKTUELLES JAHR ?
	JR	Z,NEUJAHR		; DANN UNTEN WEITER
	CALL	SCHALT			; SCHALTJAHR ?
	JR	S_TAGE

NEUJAHR:LD	(TTTT),HL		; TAGE MERKEN
	AND	3			; AKTUELLES JAHR = SCHALTJAHR ?
	JR	Z,NEU_2			; DANN ANDERE TABELLE
NEU_1:	LD	HL,MONTAB1-2
	JR	MONATE
NEU_2:	LD	HL,MONTAB2-2

MONATE:	LD	A,(MONTH)
	LD	B,A
M_TAGE:	INC	HL
	INC	HL
	DJNZ	M_TAGE			; RICHTIGEN TABELLENEINTRAG SUCHEN
	LD	A,(HL)			; LOWBYTE
	INC	HL
	LD	H,(HL)			; HIGHBYTE
	LD	L,A
	EX	DE,HL
	LD	HL,(TTTT)		; BISHERIGER WERT
	ADD	HL,DE			; PLUS VOLLE MONATE
	LD	D,0
	LD	A,(DAY)
	LD	E,A
	ADD	HL,DE			; PLUS TAGE IM MONAT
	
	LD	(TTTT),HL		; IN PARAMETERBLOCK

	LD	HL,COMBIOS		; ADRESSE UEBERGEBEN
	LD	A,(SECOND)		; SEKUNDEN IN A
	EI

	RET				; ZURUECK ZUM PROGRAMM

;------------------------------------------------------------------------------

SETTIME:DI
	C_WRITE 04,HOUR
	C_WRITE 02,MINUTE
	C_WRITE 00,SECOND
	LD	HL,(DAT_PB)		; TAGE IN HL
	CALL	DATEHL
	LD	(DAY),A
	LD	A,L
	LD	(MONTH),A
	LD	A,H
	LD	(YEAR),A
	C_WRITE 07,DAY
	C_WRITE 08,MONTH
	C_WRITE 09,YEAR
	EI
	RET

;------------------------------------------------------------------------------

C_RD:	CALL	C_INIT			; 8255 ANPASSEN
	INC	BC
	INC	BC			; KONTROLLREGISTER 8255
	OUTA	089			; MODE 0, KONTROLL-WORT 5
	DEC	BC
	DEC	BC			; 8255 PORT B
	OUTA	01D			; CE- = 1, AS = 0, R/W- = 1, DS = 1
	OUTA	01C			; CE- = 0, AS = 0, R/W- = 1, DS = 1
	OUTA	014			; CE- = 0, AS = 0, R/W- = 1, DS = 0
	INC	BC			; 8255 PORT C
	IN	H,(C)			; REGISTER LESEN
	DEC	BC
C_EXIT:	OUTA	01C			; CE- = 0, AS = 0, R/W- = 1, DS = 1
	OUTA	01D			; CE- = 1, AS = 0, R/W- = 1, DS = 1
	RET

;------------------------------------------------------------------------------

C_WR:	CALL	C_INIT
	OUTA	01D
	OUTA	01C
	INC	BC
	OUT	(C),H
	DEC	BC
	OUTA	18
	JR	C_EXIT

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

C_INIT:	LD	BC,T_PORT		; 8255 KONTROLLREGISTER	
	OUTA	080			; MODE 0, KONTROLL-WORT 0
	DEC	BC
	DEC	BC			; 8255 PORT B
	OUTA	01F			; CE- = 1, AS = 1, R/W- = 1, DS = 1
	OUTA	01E			; CE- = 0, AS = 1, R/W- = 1, DS = 1
	INC	BC			; 8255 PORT C
	OUT	(C),L			; REGISTERNUMMER
	DEC	BC			; 8255 PORT B
	OUTA	01A			; CE- = 0, AS = 1, R/W- = 0, DS = 1
	OUTA	01E			; CE- = 0, AS = 1, R/W- = 1, DS = 1
	OUTA	01F			; CE- = 1, AS = 1, R/W- = 1, DS = 1
	RET

;------------------------------------------------------------------------------

UPDATE:	LD	L,0A			; KONTROLLREGISTER UHR
UPD_2:	CALL	C_RD			; LESEN
	BIT	7,H			; UPDATE-BIT
	JR	NZ,UPD_2		; GESETZT, DANN WARTEN
	RET

;------------------------------------------------------------------------------

SCHALT:	PUSH	AF
	AND	3
	JR	NZ,S_EXIT
	INC	HL
S_EXIT: POP	AF
	RET

;------------------------------------------------------------------------------

BCDBIN: PUSH	AF
	AND	0F0			; HIGHNIBBLE
	RRCA
	RRCA
	RRCA
	RRCA
	LD	H,0
	LD	L,A			; IN HL
	LD	DE,0A			; MAL 10
	CALL	MULT			; HL = HL * DE
	LD	B,L			; MERKEN
	POP	AF
	AND	0F			; LOWNIBBLE
	ADD	A,B
	RET

;------------------------------------------------------------------------------

MULT:	OR	L			; ACHTUNG: HIGHBYTE=0 MUSS STIMMEN !
	RET	Z			; LOW = 0, DANN FERTIG
	LD	A,D
	OR	E
	LD	A,L
	LD	L,E
	LD	H,D
	RET	Z			; DE=0 --> HL = 0
	CP	3			; < 3
	JR	C,LT_3			; DANN EINFACHER
	SCF
MULT_1:	ADC	A,A
	JR	NC,MULT_1
MULT_2:	ADD	HL,HL
	RET	C
	ADD	A,A
	JR	NC,MULT_3
	ADD	HL,DE
	RET	C
MULT_3:	CP	080
	JR	NZ,MULT_2
	RET

LT_3:	CP	1
	RET	Z
	ADD	HL,HL
	RET

;------------------------------------------------------------------------------

.RADIX 10

MONTAB1:DW	0			; JANUAR
	DW	31			; FEBRUAR
	DW	59			; MAERZ
	DW	90			; APRIL
	DW	120			; MAI
	DW	151			; JUNI
	DW	181			; JULI
	DW	212			; AUGUST
	DW	243			; SEPTEMBER
	DW	273			; OKTOBER
	DW	304			; NOVEMBER
	DW	334			; DEZEMBER

MONTAB2:DW	0			; JANUAR
	DW	31			; FEBRUAR
	DW	60			; MAERZ
	DW	91			; APRIL
	DW	121			; MAI
	DW	152			; JUNI
	DW	182			; JULI
	DW	213			; AUGUST
	DW	244			; SEPTEMBER
	DW	274			; OKTOBER
	DW	305			; NOVEMBER
	DW	335			; DEZEMBER

YEAR:	DB	0
MONTH:	DB	0
DAY:	DB	0

;------------------------------------------------------------------------------

; Module Name:	DATEHL
; Author:	Carson Wilson
; Version:	1.0
; Date: 	25 Sept 87

;
; DATEHL converts the value in HL to BCD year, month, day
;	 for use with Z80DOS time stamps.
;
; Inputs:	HL contains hex days since December 31, 1977
;
; Outputs:	H contains BCD 20th century year
;		L contains BC                                                                                                                                \X                 COPYRIGHT (C) 1979, DIGITAL RESEARCH                                                                              _ ͌>͒>
Ò> Ò͘~#͌ì _  2<×2͞˗×××͞ߗ  ͞×   !2 :2 a{_:ʖ:> Ľ˗ʖ:=2̞! B!6 #5ڗʖ:Ľ!ͬʧݘÂݘ
 )!F#xʺ~0wëw!"     !~6 ͽ:ý(! Ϛ#͘*~ ""͌#>?͌͘ݘÂ 	=_.:;<> Oo$> !͞Y2*O"ʉ@G:ʐ:wÖx2p0ʹ#*©6?ëw0ï#6 ¹.0#*ٙ6?ۙwș0ߙ#6 #6 " #~?	xDIR ERA TYPESAVEREN USER   ! yΞO#< Ty#O321y_͸2y2ͽ:	; Set up 'B' for subtract
	ld	a,0		; Set a for # of months
mloop:
	push	af
	ld	a,(de)		; Get month
	ld	c,a		; Put in 'C' for subtract
	pop	af
	ld	(days),hl	; save days count
	add	hl,bc		; Subtract
	inc	de		; Increment months counter
	inc	a
	jp	c,mloop		; Loop for next month
;
; The months are finished, days count is on stack.  First, calculate
; month.
;
mdone:
	ld	b,a		; Save months
	ld	hl,(days)
	ld	a,h
	or	l
	jp	nz,nzd
	dec	de
	dec	de
	ld	a,(de)
	cpl
	inc	a
	ld	l,a
	dec	b
nzd:
	ld	a,l		; Retrieve binary day of month
	call	binbcd		; Convert to BCD
	push	af		; Save day in A
;
	ld	a,b		; Retrieve the binary month
	call	binbcd		; Convert binary month to BCD
	ld	l,a		; Return month in L
;
	ld	a,(dyear)
	ld	h,a		; Return year in H
;
	or	0ffh		; Return no error
	pop	af		; Restore day
	ret

;
; Support Routines:
;

;
; Check for leap years.
;
ckleap:	ld	a,b
	and	0fch
	cp	b
	ret
;
; Convert A to BCD & store back in A
;
BinBCD:
	or	a
	ret	z
	push	bc
	ld	b,a
	xor	a
BinBCD1:
	add	a,1
	daa
	djnz	BinBCD1
	pop	bc
	ret
;
; Buffers:
;

;
; Months table
;
mtable:
	db	-31		;January
feb:
	db	-28		;February
	db	-31,-30,-31,-30	;Mar-Jun
	db	-31,-31,-30	;Jul-Sep
	db	-31,-30,-31	;Oct-Dec
days:
	ds	2		; temporary buffers
dyear:
	ds	1

	

; END DATEHD.Z80


PTC_END:
	.DEPHASE

	END
			