; Funktionen für AS
hi	function x,(x>>8)&255 	; oberes Byte eines 16-Bit-Wortes

;-----------------------------------------------------------------------------
; Macros
;-----------------------------------------------------------------------------

		if shadow16k=1

; Shadow RAM an/aus

; ohne EI
shadow_on	macro
		di
		out	(rambank2), a	; Schattenbios aktiv
		push	af
		xor	a
		ld	(bmode), a	; Bios-Mode: 'U'-Arbeit	im Upper Bios, 00-Arbeit im Schatten-Bios
		pop	af
		endm

shadow_off	macro
		di
		out	(rambank1), a	; Schattenbios wegschalten
		push	af
		ld	a, 'U'
		ld	(bmode), a	; Bios-Mode: 'U'-Arbeit	im Upper Bios, 00-Arbeit im Schatten-Bios
		pop	af
		endm

; mit Interrupt enable
shadow_oni	macro
		shadow_on
		ei
		endm

shadow_offi	macro
		shadow_off
		ei
		endm

		else
shadow_on	macro
		endm

shadow_off	macro
		endm

shadow_oni	macro
		endm

shadow_offi	macro
		endm
		endif		

;-----------------------------------------------------------------------------
; weitere Konstanten
;-----------------------------------------------------------------------------

BDOS       	equ	CCP+0806h	; base of bdos
UBIOS		equ	CCP+1600h	; base of upper bios
SBIOS		equ	SHADOWRAM+1600h	; base of shadow bios in Shadow-Memory 5600H

;-----------------------------------------------------------------------------
; Initialisierung Loader (CPMLDR/CPABAS)
; vom aktuellen Boot-Loader wird dieser Code nicht ausgeführt, es wird nur
; die Ladeadresse entnommen.
;-----------------------------------------------------------------------------
;
		org 	SBIOS - 1600H - 128

		include	cpmldr.inc

;-----------------------------------------------------------------------------
; CCP+BDOS
; frühere CPA-Version 24.08.86

; Anpassungen an Z9001:
;CCP
;CLKBCD:		equ	001Dh		; BCD-Buffer für CLK, Z9001
;DISKA		EQU	0003H		; disk address for current disk, üblich 0004!
;dircol		1			; 2spaltiges Dir
;clk:		...ld	b, 3		; Z9001 nur 3 BCD-Werte (nur Uhr)
;
;BDOS
;IOLOC		EQU	0004H		;Z9001 i/o byte location
;DISKA		EQU	0003H		;Z9001 disk address for current disk
;-----------------------------------------------------------------------------

		org	SBIOS - 1600H

  		; CCP
		phase	CCP
		LISTING	OFF
		section CCP
		public	dircol,COMLEN,RETCOM
	if ccpcod=0
		include	ccp_cpa1.asm
	else
		include	ccp_cpa1r.asm
	endif
		endsection
		dephase
		LISTING	NOSKIPPED
		
		; BDOS
		phase	BDOS-0006
		LISTING	OFF
		section BDOS
		include	bdos_cpa1.asm
		endsection
		dephase
		LISTING	NOSKIPPED


;------------------------------------------------------------
;	BEGINN BIOS-CODE
;------------------------------------------------------------

;-----------------------------------------------------------------------------
; BIOS 
;-----------------------------------------------------------------------------

		org 	SBIOS

		jp	start+LOADADRESS-SHADOWRAM	; boot im Loadbereich 8000h ff.
					; adresse wird später gepatcht
		jp	wboot
		jp	_const		; const im upper bios
		jp	0F009h		; conin im z9001-os
		jp	_conout		; conout im upper bios
		jp	0F00Fh		; list im z9001-os
		jp	0F012h		; punch im z9001-os
		jp	0F015h		; reader im z9001-os
		jp	home
		jp	seldsk
		jp	settrk
		jp	setsec
		jp	setdma
uread:		jp	read
uwrite:		jp	write
		jp	0F02Dh		; listst im z9001-os
		jp	sectran


		IF scpcod <> ''
		db	scpcod		; CP/A-Kennung
		ENDIF

	;include BIOSKBD

	;include BIOSCRT

; zeichenorientierte Geraete
		include	bioschd.inc

; Logischer Diskettentreiber
		include	biosdsk.inc

; physischer Disketten-Transfer
		include biosfdc.inc


;------------------------------------------------


	IF fdcspace=1
; ????? alte Reste ?????
		ds	42
	ENDIF

; BIOSRAF
; BIOSTIM

; BIOSNUC
; Zentrale BIOS-Kompenenten

 ;	Allgemeine BIOS-Hilfsprogramme
;-----------------------------------------------------------------------------
; Ausgabe Zeichenkette, zu uprnst
;-----------------------------------------------------------------------------

prnst:		ex	de, hl
		ld	hl, (0F057h)	; Adr. PRNST-Funktion im OS
		jp	(hl)
biosms:		di
		call	prnst
		ei
		ret

;-----------------------------------------------------------------------------
; Kurze Warteschleife, ungenutzt???
;-----------------------------------------------------------------------------

 ;	Wait 0.01 sec * (B)
wait:		push	bc
		ld	c, 10 		;10* 1ms warten
wait1:		ld	b, 189		;(189*13)/(256*9600)=0.001
wait2:		djnz	wait2		;1ms warten
		dec	c
		jr	nz, wait1
		pop	bc
		djnz	wait
		ret

;	zentral verwendete Rueckkonvertierungsroutinen

;-----------------------------------------------------------------------------
; (HL) nach hex	konvertieren, Eintragen	nach (DE), 2x inc DE
; zu Fehlerbehandlung dioert und upunch
;-----------------------------------------------------------------------------

mbreco:		ld	a, (hl)
;
; A nach hex konvertieren, Eintragen nach (DE),	2x inc DE
hexa:		call	hexa1		
hexa1:		rrca
		rrca
		rrca
		rrca
		push	af
		and	0Fh
		sub	0Ah
		jr	c, hexa2
		add	a, 7
hexa2:		add	a, 3Ah
		ld	(de), a
		inc	de
		pop	af
		ret

;-----------------------------------------------------------------------------
; wboot
; Warmstart
;-----------------------------------------------------------------------------
	; warmst
	
wboot:		ld	sp, 80h
		ld	hl, SHADOWRAM	; CCP restaurieren
		ld	de, CCP
		ld	bc, 800h	; Länge CCP
		ldir

		IF inicod=0
		ld	hl, CCP+0003h
wboot3:		ld	(wboot3u1+1), hl
		ENDIF

	; warmin
		di
		ld	a, hi(intvectab)	;E7H
		ld	i, a		; Interruptvektor und
		im	2		; Interruptmodus 2 setzen
;Systemeinsprünge init.
		ld	a, 0C3h		; Befehlscode JP
		ld	(0), a		; 0000h: jp wboot
		ld	(38h), a	; 0038h: RST 38H, jp wboot
		ld	hl, ubios+3	; wboot	im upper Bios
		ld	(1), hl
		ld	(39h), hl
		ld	(5), a		; 0005h: jp bdos
wboot0:		ld	hl, BDOS	; Adresse wird ggf. bepatcht (BINIT9, Fehler bei RAM-Test)
		ld	(6), hl

	; timwarm
;Systemuhr init.
		ld	a, 0C7h		;ZAEHLERINTERRUPT (Steuerwort CTC3: EI, Reset, Zeitkonstante folgt)
		out	(CTC3), a	; Systemuhr
		ld	a, 40h		;Zeitkonstante 64, zusammen mit CTC2 ergibt das einen Takt von 1 sek = 1 Hz
		out	(CTC3), a	; Systemuhr

	; dskwarm
;kein Laufwerk gepuffert
		ld	a, 0FFh
		ld	(dbdev), a	; zum Disk-Treiber gehoeriges Geraet auf ungültig setzen

	; setcld
wboot1:		ld	hl, 0003h	; DRIVE-Byte !! Im Std.-CP/M ist das 0004h !!
		ld	c, (hl)		; aktuelles Laufwerk
		push	bc		; merken
		ld	a, c
		and	0Fh
		ld	c, a		; oberes Nibble (USER-Bereich) 0
		xor	(hl)		; oberes Nibble (USER-Bereich) aus (HL) übernehmen
wboot2:		or	0		; Kaltstart-Laufwerk, wird in binit gepatcht
		ld	(hl), a
;
		ld	e, 1		; E: Bit 0 ist LOGIN-Bit von BDOS
		call	seldsk		; Standardlaufwerk merken, DPH selektieren
		pop	bc		; aktuelles Laufwerk
		ld	a, h
		or	l		; DPH=0?
		jr	z, wboot1	; Fehler -> nochmal probieren
;
		jp	wboot3u		; wboot ende und Start CCP


		IF cpprot=1

; Copyrightschutztest, s. a. copyprot
schutzbyte1:	db	 28h 		; Lo(Adr. zweite Bildschirmzeile)
schutzbyte2:	db	   0 		; Prüfwert
schutzbyte3:	dw 	bootmsg		; Adr. Bootmessage
schutzbyte4:	db	0ECh 		; Hi(Adr. zweite Bildschirmzeile)

		ENDIF

;-----------------------------------------------------------------------------
; Aufruf bei call sbios: (jp start), wenn BIOS bereits initialisiert
; die Reset-Routine wird nach 0080h kopiert und gestartet
;-----------------------------------------------------------------------------

ustart:		ld	hl, reset0
		ld	de, 80h
		ld	bc, start-reset0
		ldir
		jp	80h

;-----------------------------------------------------------------------------
; wird nach 0080h kopiert
;-----------------------------------------------------------------------------

reset0:		equ	$

		phase 	0080h

		shadow_off
		out	(rambank_wo), a	; RAM wegschalten
		ld	(0F800h), a	; ROM-Modul zuschalten

		jp	0F000h		; Sprung in Z9001-OS (Kaltstart)

		dephase

; --------

fdcbuffer:	equ	$		; Buffer für FDC-IO-Operation (1K)
fdcbufsiz:	equ	400h		; 1K Byte
; Adr. biosstack (100 Byte)
biosstack:	equ	fdcbuffer + fdcbufsiz + 100	; Stackbereich	für Upper-BIOS E200


;-----------------------------------------------------------------------------
; boot, vgl. Code mit Initialisierung am Anfang
; Einsprung durch Init nach Bootloader
; Code ist relokatibel und kann von bel. Adresse im RAM aus gestartet werden.
; der zweite Teil start1 muss natürlich an der korrekten Position liegen!
;-----------------------------------------------------------------------------

start:		di
		ld	hl, LOADADRESS	; anfängliche Ladeadr.
		ld	bc, romend-SHADOWRAM	; Programmlänge
		ld	de, SHADOWRAM
		shadow_on
		ldir			; BIOS in Shadowram kopieren
		jp	start1		; weiter nach Kopieren des BIOS

;-----------------------------------------------------------------------------
; weiter gehts im Shadow-RAM
; Initialisierung von binit und ubios
;-----------------------------------------------------------------------------

start1:		di
		ld	sp, 80h
		; CCP und BDOS kopieren
		ld	de, CCP
		ld	hl, SHADOWRAM
		ld	bc, 1600h		;Länge CCP+BDOS
		ldir
		; Kopieren oberen Teil BIOS nach E200
		ld	hl, memubios
		ld	bc, ubiosend-ubios
		ldir
		; Kopieren bios-Init nach 0180
		ld	hl, membinit
		ld	de, binit
		ld	bc, binitend-binit
		ldir

		jp	binit			; start Bios-Init

;-----------------------------------------------------------------------------
membinit:	equ	$

;-----------------------------------------------------------------------------
; BIOS-Initialisierung
; Startmeldung,
; Initialisieren Gerätetreibertabelle,
; RAM-Test,
; Starten des CCP-Systems
;
; Register A: untere 2 Bit Laufwerk; Bit 7 = 1 Warmstart
; Bei Bit7=0 Kaltstart mit kompletter Initialisierung, es
; kann ein Kommando beim start des CCP ausgeführt werden
;
;-----------------------------------------------------------------------------

		phase 	0180h

binit:
		IF inicod=1
		push	af
		and	80h
		ld	(binit7+1), a	; 0 Kaltstart, 80 = Warmstart
		pop	af
		ENDIF

		and	3		; Laufwerk begrenzen
		ld	(3), a		; Standard-Laufwerk
		ld	(wboot2+1), a

		ld	hl, start	; mit FF füllen
		ld	de, start+1	; d.h. die originale Lokation dieses Codes überschreiben
		ld	bc, biosstack-start-1
		ld	(hl), 0FFh
		ldir

		ld	hl, 0FCB0h	; Z9001-OS: Tabelle der Interruptadressen
		ld	bc, 0Ch
		ld	de, intvectab	; nach E700 kopieren
		ldir

		ld	bc, 0FFh-0Ch	; bis E7FF mit 0 füllen
		ld	h, d		; DE=E70D
		ld	l, e
		inc	de
		ld	(hl), 0
		ldir

		ld	c, 10010100b	; I/O-Byte: LIST=UL:,PUNCH=UP1:,READER=UR1:,CONST=TTY:
		call	0F03Ch		; Z9001-OS: Setzen I/O-Byte

		ld	hl, intvectab	; Interrupttabelle
		ld	a, h
		ld	i, a		; Interruptregister setzen
		im	2

; Initialisierung FDC

	IF FDCPORTS = 'ROBOTRON'

		ld	a, 20h		; 0010 0000 FDC	Reset
		out	(FDCZ),	a
		ld	a, 13h		; 0001 0011 Terminal Count aktivieren, Motor LW	1+2 an
		out	(FDCZ),	a
	ENDIF
;
binit1:		ld	b, 0		;INITIALISIERUNG P8272
binit2:		djnz	binit2
		in	a, (CFDC)
		cp	80h
		jr	z, binit4
		in	a, (DFDC)
binit3:		jr	binit1
;
stab:		db  	stab1		;XXXX=Schrittratenzeit SRT,XXXX= Kopfladezeit HUT
		db  	stab2		;XXXXXXX=Kopfladezeit HLT,X=no dma ND

binit4:		ld	hl, stab-1	;PARAMETER LADEN
		ld	bc, 303h	;SPECIFY-COMM 3BYTES
		call	wcom1		;SCHREIBEN COMM
		xor	a
		ld	(UNIT), a
		ld	(dFDCZ1), a
		call	recal2
		call	sds
		bit	4, a
		ld	a, 1
		jr	z, binit5
		ld	(dFDCZ1), a
binit5:		ld	(UNIT), a
		call	recal2
		call	sds
		bit	4, a
		ld	a, (dFDCZ1)
		jr	z, binit6

		IF FDCPORTS = 'ROBOTRON'
		or	2
		ELSE
		inc	a
		ENDIF
		ld	(dFDCZ1), a
binit6:

		IF FDCPORTS = 'ROBOTRON'
		out	(FDCZ), a	; ZusatzRegister FDC schreiben
		ENDIF

; Gerätetreibertabellen füllen
	if S6010=0

		call	fiotab		; Gerätetreibertabelle READER setzen
		dw	8
		dw	0F8F1h		; TTY:=	CRT-Treiber Z9001
		dw	_dummyin	; RDR:
		dw	_dummyin	; UR1:
		dw	_dummyin	; UR2:

		call	fiotab		; Gerätetreibertabelle PUNCH setzen
		dw	10h
		dw	0F8F1h		; TTY:=	CRT-Treiber Z9001
		dw	_pun		; PUN:
		dw	_pun		; UP1:
		dw	_up2		; UP2:

		call	fiotab		; Gerätetreibertabelle LIST setzen
		dw	18h
		dw	0F8F1h		; TTY:=	CRT-Treiber Z9001
		dw	_CRTL		; CRT:
		dw	_up2		; LST:
		dw	_UL		; UL:

	elseif S6010=1
	
		call	fiotab		; Gerätetreibertabelle READER setzen
		dw	8
		dw	0F8F1h		; TTY:=	CRT-Treiber Z9001
                dw 	_UR6010		; RDR = S6010
		dw	_dummyin	; UR1:
		dw	_dummyin	; UR2:

;-----------------------------------------------------------------------------
; S6010-Treiber UBIOS Initialisierung
;-----------------------------------------------------------------------------

IS61010:        ld      hl, 0
                ld      (UR6010_b1), hl	; init.
        	jr      IS6010_1

IS6010_tab:     
		; CTC 
		db    7			; Steuerwort: DI, Zeitgeber, Zeitkonstante folgt, Reset
                db    8			; Zeitkonstante: 8 => 1200 Baud (ZKCTC=9600/BDRAT)
		
		; SIO
                db    4			; next Register WR4
                db  4Ch			; x1 Taktrate, 8 Bit-Sync-Zeichen, 2 Stop-Bit, keine Parität
                db    1			; next Register WR1
                db    0
                db    3			; next Register WR3
                db 0E1h			; Rx 8 Bits/Zeichen, Auto Enables, Empfänger-Freigabe
                db    5			; next Register WR5
                db 0E8h			; DTR, Tx 8 Bits/Zeichen, Senderfreigabe


IS6010_1:       ld      hl, IS6010_tab
                ld      a, 18h		; SIO Reset
                out     (SIOKD), a
                ld      bc, 2*100h+CTC	; B=2 C=CTC
                otir
                ld      bc, 8*100h+SIOKD	; B=7 C=SIOKD
                otir

; ---------------------------------------------------------------------------


		call	fiotab		; Gerätetreibertabelle PUNCH setzen
		dw	10h
		dw	0F8F1h		; TTY:=	CRT-Treiber Z9001
                dw 	_UP6010		; PUN = S6010
		dw	_pun		; UP1:
		dw	_up2		; UP2:

		call	fiotab		; Gerätetreibertabelle LIST setzen
		dw	18h
		dw	0F8F1h		; TTY:=	CRT-Treiber Z9001
                dw 	_up2
                dw 	_UP6010		; LST = S6010
		dw	_UL		; UL:
	
	endif

		xor	a
		ld	(_0_572Fh), a	; Unklar, ungenutzt, CP/A-Reste????

		call	fiotab		; Gerätetreiber	CONST setzen
		dw	0
		dw	_TTYC		; TTY:
		dw	_CRTC		; CRT:
		dw	_BATC		; BAT:
		dw	0F8F1h		; RDR:=	CRT-Treiber Z9001

		xor	a
		ld	(lstflag), a

		IF inicod=1
binit7:		ld	a, 0		; 0 = Kaltstart; wird in binit gepatcht
		ENDIF

		; Warmstart-Initialisierung CRT
		ld	hl, _con_escp1	; ESCAPE-Modus Ringpuffer
		ld	(_con_escp), hl	; init.
		ld	hl, 0		; mit 0 füllen
		ld	(_con_escp1), hl
		ld	a, 0FFh
		ld	(_con_esc), a	; evtl. ESCAPE-Modus beenden

		ld	hl, ustart	; BIOS boot Funktion auf ustart patchen
		ld	(sbios+1), hl

		IF cpprot=0
		ld	hl, bootmsg	; Anzeige Boot-Meldung
		ELSE
		ld	hl, (schutzbyte3)
		ENDIF

		call	uprnst		; Stringausgabe
		ld	hl, aRamTest	; "\r\n- RAM-Test ... "
		call	uprnst		; Anzeige RAM-Test...

		; RAM-Test
		ld	hl, BDOS	; Beginn BDOS
		ld	de, binitend+3	; Ende INIT
		or	a
		sbc	hl, de
		ld	b, h
		ld	c, l
		ex	de, hl
		shadow_off
binit8:		ld	a, (hl)		; RAM-Test
		cpl
		ld	(hl), a
		cp	(hl)
		jr	nz, binit9	; Bei RAM-Fehler
		cpl
		ld	(hl), a
		inc	hl
		dec	bc
		ld	a, b
		or	c
		jr	nz, binit8
		shadow_on

		ld	hl, aTpaIstOk	; "TPA ist OK!\r"
		call	uprnst		; Stringausgabe

		IF cpprot=1
		call	copyprot	; Copyrightschutztest
		ENDIF
;
		jp	binit10

; -------------------------
; HL als Hexwert nach (DE) schreiben, DE 4x inkrementieren
convhl:		ld	a, h
		call	conva		; A als	Hexwert	nach (DE) schreiben, DE	2x inkrementieren
		ld	a, l
; A als	Hexwert	nach (DE) schreiben, DE	2x inkrementieren
conva:		call	conva1
conva1:		rrca
		rrca
		rrca
		rrca
		push	af
		and	0Fh
		sub	0Ah
		jr	c, conva2
		add	a, 7
conva2:		add	a, 3Ah
		ld	(de), a
		inc	de
		pop	af
		ret

;-----------------------------------------------------------------------------
; Copyrightschutztest
;-----------------------------------------------------------------------------

		IF cpprot=1

; Aufruf am Ende von binit
copyprot:	ld	b, 21h 			; Länge von "implementiert von F.Schwarzenberg"
		ld	a, (schutzbyte1)
		ld	l, a
		ld	e, a
		ld	a, (schutzbyte4)
		ld	d, a			; de = ec28h = Adr. zweite Bildschirmzeile
		sub	4
		ld	h, a			; hl = e828h = Adr. zweite Farbzeile
		ld	a, (de)			; Prüfwert: startwert 1. Buchstabe
copyprot1:	rrca				; Prüfwert rotieren
		ld	(hl), 2			; Hintergrundfarbe ändern auf ...
		inc	hl
		inc	de
		ex	de, hl
		xor	(hl)			; Prüfwert mit nächstem Buchstaben verknüpfen
		ex	de, hl
		djnz	copyprot1
		ld	(schutzbyte2), a	; muß 0ACh ergeben, s. a. binit10
		ret

		ENDIF

;-----------------------------------------------------------------------------
; weiter mit Initialisierung
;-----------------------------------------------------------------------------
; Wenn Fehler beim Ramtest
binit9:		shadow_on
		ld	de, aRamFehler+1Bh
		call	convhl		; HL als Hexwert nach (DE) schreiben, DE 4x inkrementieren
		ld	de, BDOS	; Adresse BDOS
		dec	hl
		ld	(hl), d
		dec	hl
		ld	(hl), e
		dec	hl
		ld	(hl), 0C3h	; 'JP'
		ld	(wboot0+1), hl	; Adresse BDOS; wird zu CALL 5 kopiert
		dec	hl
		ld	de, aRamFehler+30h
		call	convhl		; HL als Hexwert nach (DE) schreiben, DE 4x inkrementieren

		ld	hl, aRamFehler	; "\r\n!!RAM-Fehler auf Adresse XXXXH!!  TPA"...
		call	uprnst		; Stringausgabe

;normales Init.
binit10:
		IF inicod=1

		ld	hl, CCP+0003h	; CLEAR: CCP-Aufruf mit	Löschen	des Befehlsbuffers
		ld	a, (binit7+1)	; 0 = Kaltstart, 80 = Warmstart
		or	a
		jr	nz, binit11

		endif

		if	cpprot=1

		ld	a, (schutzbyte2)
		cp	0ACh
		jr	z, binit12	; alles OK, Impl. Zeile wurde nicht verändert

		; Copyright-Änderung ahnden: Speicher löschen !
		ld	hl, 0B0EDh	; Auf Adr. 80 Code bringen:
		ld	(80h), hl	; 0080: ED B0	ldir
		ld	hl, 0FC18h	; 0082: 18 FC	jr zu Adr. 0080H
		ld	(82h), hl	; 0084: 23	Zeichen '#'
		ld	hl, 0084h
		ld	d, h
		ld	e, l
		inc	de
		ld	(hl), 23h

		ld	bc, 0E800h-0084h	; hl=0084h, de = 0085h, bc=0E77Ch
		jp	80h		; Speicher von 84h-E7FFh mit '#' füllen

		ENDIF

binit12:	ld	hl, startkdo	; start-Kommando
		ld	de, CCP+0007h	; CCP-Befehlsbuffer
		ld	bc, 81h		; 80 Byte + 1 Längenbyte
		ldir
		ld	hl, CCP		; COLD:	CCP-start

		IF inicod=1
binit11:	jp	wboot		; WBOOT	im ShadowBios
		ELSEIF inicod=0
binit11:	jp	wboot3		; WBOOT	im ShadowBios, mit Ausführung des startkdo :-))
		ENDIF


;-----------------------------------------------------------------------------
; Stringausgabe
;-----------------------------------------------------------------------------

		IF inicod=1

uprnst:		ld	a, (binit7+1)	; 0 = Kaltstart, 80 = Warmstart
		or	a
		ret	nz		; keine Anzeige bei Warmstart
		jp	prnst		; shadow prnst

		ELSEIF	inicod=0

uprnst:		equ	prnst

		ENDIF

;-----------------------------------------------------------------------------
; Gerätetreibertabelle füllen
; Nach Call 1 Word Offset, dann	4 Word Adressen	der Gerätetreiber
;-----------------------------------------------------------------------------

fiotab:		pop	hl		; Adresse nach Call holen (Ret-Adr. vom	Stack)
		ld	e, (hl)
		inc	hl
		ld	d, (hl)
		inc	hl
		ex	de, hl		; HL=Offset
		ld	bc, 0EFC9h	; Tabelle der Gerätetreiberadressen
		add	hl, bc		; Offset addieren
		ex	de, hl
		ld	bc, 8
		ldir			; 4 Word kopieren
		jp	(hl)		; und zurück zum Aufrufer

bootmsg:	db  	0Ch
		db	 " CP/A Z9001, Version ",reldate, 0Ah, 0Dh
		db  	16h, "implementiert von F.Schwarzenberg", 16h, 0Ah, 0Dh
		db	"TPA 100H - 0\{BDOS-1}H", 0Dh, 0Ah
		db	"- Disks: 5", '"'
		if	lw1='S4'
		db	"(40,SS)"
		elseif	lw1='D4'
		db	"(40,DS)"
		elseif	lw1='S8'
		db	"(80,SS)"
		elseif	lw1='D8'
		db	"(80,DS)"
		endif
		db	"/5", '"'
		if	lw2='S4'
		db	"(40,SS)"
		elseif	lw2='D4'
		db	"(40,DS)"
		elseif	lw2='S8'
		db	"(80,SS)"
		elseif	lw2='D8'
		db	"(80,DS)"
		endif
		db 0Dh, 0Ah

		db 	"IO-Byte:", 0Dh, 0Ah
		db	"Bit 7,6 (LST:-Kanal):", 0Dh, 0Ah
		db	"     00 (TTY:): ", 0Dh, 0Ah
	if S6010=0
		db	"     01 (CRT:): V24-User-Port 1200 Bd", 0Dh, 0Ah
		db	"     10 (LPT:): V24-User-Port 9600 Bd", 0Dh, 0Ah
		db	"     11 (UL1:): Centronics User-Port", 0Dh, 0Ah
		db	"Bit 5,4 (PUN:-Kanal):", 0Dh, 0Ah
		db	"Bit 3,2 (RDR:-Kanal):", 0Dh, 0Ah
	elseif S6010=1
                db 	"     01 (CRT:): V24-User-Port 9600 Bd",0Dh,0Ah
                db 	"     10 (LPT:): S 6010 (SIO)  1200 Bd",0Dh,0Ah
                db 	"     11 (UL1:): Centronics User-Port",0Dh,0Ah
                db 	"Bit 5,4 (PUN:-Kanal):",0Dh,0Ah
                db 	"     01 (PTP:): S 6010 (SIO)  1200 Bd",0Dh,0Ah
                db 	"Bit 3,2 (RDR:-Kanal):",0Dh,0Ah
                db 	"     01 (PTR:): S 6010 (SIO)  1200 Bd",0Dh,0Ah
	endif
		db	"Bit 1,0 (CON:-Kanal):", 0Dh, 0Ah
		db	"     00 (TTY:): Beep + Gross<=>Klein", 0Dh, 0Ah
		db	"     01 (CRT:): nur  Tastatur-Beep", 0Dh, 0Ah
		db	"     11 (UC1:): ohne Beep"
		db 	0

aRamTest:	db 	0Dh, 0Ah, "- RAM-Test ... " , 0

aTpaIstOk:	db	"TPA ist OK!", 0Dh, 0

aRamFehler:	db 	0Dh, 0Ah, "!!RAM-Fehler auf Adresse XXXXH!!  TPA nur bis YYYYH.", 7, 0Dh, 0Ah, 0

; hier kann ein	Befehl eingetragen werden, der beim start des CCP ausgeführt werden soll
startkdo:	db  	7Fh	; Länge	des Befehls(buffers)
	if cldkdo <> ""
		db 	cldkdo
	endif	
		db	128-($-startkdo-1) dup (0)	; mit 00 auffüllen

binitend:	equ	$

		dephase

;-----------------------------------------------------------------------------
memubios:	equ	$












;-----------------------------------------------------------------------------
;
; Upper BIOS	E200h - E519h
;
;-----------------------------------------------------------------------------


		phase 	UBIOS

		include	ubios.inc
		
		include	dph.inc

lastram:	equ	$

intvectab:	equ	0E700h		; Interruptvektortabelle, 12 Byte
; bis E7FF wird mit FFH aufgefüllt

		dephase
;-----------------------------------------------------------------------------

biosend:	equ	$

;-----------------------------------------------------------------------------
; Systeminfos
;-----------------------------------------------------------------------------

	;if MOMPASS > 1
	outradix 16
	message	"=============================================="
	message	"CP/A-System Z9001 "+FDCPORTS
	message "2 Laufwerke "+lw1+", "+lw2
	message "automatische Formaterkennung"
	if S6010=1
		message	"I/O-Treiber fuer S6010"
	endif
	if cpprot=1
		message	"Coypright-Schutz aktiv"
	endif
	if cldkdo<>""
		message	"Autostartkommando "+cldkdo
	endif
	message	"=============================================="
	message	"CCP:		\{ccp}H		\{SHADOWRAM}H - \{sbios-1}H"
	message	"BDOS:		\{bdos}H		Kopie CCP-BDOS"
	message	"SBIOS:		\{sbios}H - \{membinit-1}H"
	message	"fdcbuffer:	\{fdcbuffer}H - \{fdcbuffer+1024}H"
	message	"biosstack:	\{biosstack}H"
	message	"init:		\{binit}H - \{binitend}H	\{membinit}H - \{memubios-1}H"
	message	"UBIOS:		\{ubios}H - \{lastram}H	\{memubios}H - \{biosend}H"
	message	"=============================================="
	;endif 	

	if lastram > intvectab
		error "UBIOS überschneidet sich mit Interruptvektortabelle!"
	endif
