	PAGE 60
	.Z80
	.XLIST

	.COMMENT#

BANKLIB.MAC enthaelt alle Routinen fuer das Banking.

ACHTUNG !!!
Jede Routine soll einen Modul in der Library BANKLIB.REL bilden.
Deshalb muss jede Routine einzeln assembliert und benannt werden.
Dazu dienen die Assemble-Flags (s.u.).

Wenn das zugehoerige Assemble-Flag gesetzt (=1) ist, wird die Routine
assembliert, sonst uebersprungen.
Fuer M80 ist der jeweilige Modul-Name als Output-Filename anzugeben.
#

; Gemeinsame Konstanten

XCHL	EQU 0DF6EH	; urspr. Adresse der Bank Read Routine
XHLC	EQU 0DF83H	; dto. der Bank Write Routine
LNG	EQU 26H		; Laenge beider Routinen
YCHL	EQU 0FE80H	; neue Adresse der Bank Read Routine
YHLC	EQU 0FE95H	; dto. der Bank Write Routine

; Assemble-Flags  (1 = assemblieren / 0 = nicht assemblieren)

IB	EQU 1		; INIBNK
SE	EQU 0		; SELBNK
LB	EQU 0		; LOADB
LW	EQU 0		; LOADW
LR	EQU 0		; LOADR
SB	EQU 0		; STOREB
SW	EQU 0		; STOREW
SR	EQU 0		; STORER
AD	EQU 0		; ADRHL
VP	EQU 0		; VARPTR


	IF IB
	TITLE INIBNK
	.PRINTX *INIBNK*
	.LIST
	ENTRY INIBNK
	.COMMENT#

INIBNK
initialisiert das Banking, indem die Lese- und Schreib-Routinen XCHL und XHLC 
aus dem CBIOS in die oberen 4K von Bank No.0 transferiert werden. Sie heissen
von da an YCHL und YHLC.

INIBNK kann als erste Routine vor allen Bank-Zugriffen gerufen werden, muss
aber nicht, da BDOS die Routinen selbst an diese Stelle reloziert.

A.Herrmann	18.06.84
#
INIBNK:	LD HL,XCHL	; transferiert die Zugriffsroutinen
	LD DE,YCHL
	LD BC,LNG
	LDIR
	RET

	.XLIST
	ENDIF

	IF SE
	TITLE SELBNK
	.PRINTX *SELBNK*
	.LIST
	ENTRY SELBNK
	EXT BANKNR
	.COMMENT#

SELBNK(NR)
selektiert die Bank, auf die zugegriffen werden soll. Die Bank-Nr. NR wird in
der Variable BANKNR im Modul ADRHL abgelegt. Da ADRHL von allen Load- und 
Store-Routinen gerufen wird, ist die Variable immer geladen.

Das Argument wird nach den Regeln von Microsoft FORTRAN uebergeben.
Demnach enthaelt
- HL die Adresse von NR.

A.Herrmann	18.06.84
#
SELBNK:	LD A,(HL)
	LD (BANKNR),A
	RET

	.XLIST
	ENDIF

	IF LB
	TITLE LOADB
	.PRINTX *LOADB*
	.LIST
	ENTRY LOADB
	EXT ADRHL,BANKNR
	.COMMENT#

LOADB(BYTE,IADDR)
liest ein Byte aus der RAM-Bank.

Die Argumente werden nach den Regeln von Microsoft FORTRAN uebergeben.
Demnach enthaelt
- HL die Adresse von BYTE 
- DE die Adresse der Integer-Variablen IADDR. Darin steht die Speicheradresse,
  woher das Byte gelesen werden soll.

Der Inhalt von IADDR wird von Routine ADRHL nach HL geladen.

A.Herrmann	18.06.84
#
LOADB:	PUSH HL
	CALL ADRHL	; Lies Adresse nach HL
	LD A,(BANKNR)	; Bank Nr.
	CALL YCHL	; Lies Byte nach C
	POP HL
	LD (HL),C
	RET

	.XLIST
	ENDIF

	IF LW
	TITLE LOADW
	.PRINTX *LOADW*
	.LIST
	ENTRY LOADW
	EXT ADRHL,BANKNR
	.COMMENT#

LOADW(WORD,IADDR)
liest ein Wort, d.h. 2 Bytes aus der RAM-Bank.

Die Argumente werden nach den Regeln von Microsoft FORTRAN uebergeben.
Demnach enthaelt
- HL die Adresse von WORD 
- DE die Adresse der Integer-Variablen IADDR. Darin steht die Speicheradresse,
  woher das Wort gelesen werden soll.

Der Inhalt von IADDR wird von Routine ADRHL nach HL geladen.

A.Herrmann	18.06.84
#
LOADW:	PUSH HL
	CALL ADRHL	; Lies Adresse nach HL
	LD A,(BANKNR)	; Bank Nr.
	CALL YCHL	; Lies Low Byte nach C
	LD B,C
	LD A,(BANKNR)
	INC HL
	CALL YCHL	; Lies High Byte nach C
	POP HL
	LD (HL),B	; Schreibe Wort
	INC HL
	LD (HL),C
	RET

	.XLIST
	ENDIF

	IF LR
	TITLE LOADR
	.PRINTX *LOADR*
	.LIST
	ENTRY LOADR
	EXT ADRHL,BANKNR
	.COMMENT#

LOADR(REAL,IADDR)
liest ein Doppelwort aus der RAM-Bank.

Die Argumente werden nach den Regeln von Microsoft FORTRAN uebergeben.
Demnach enthaelt
- HL die Adresse von REAL
- DE die Adresse der Integer-Variablen IADDR. Darin steht die Speicheradresse,
  woher das Doppelwort gelesen werden soll.

Der Inhalt von IADDR wird von Routine ADRHL nach HL geladen.

A.Herrmann	18.06.84
#
LOADR:	PUSH HL
	CALL ADRHL	; Lies Adresse nach HL
	LD A,(BANKNR)	; Bank Nr.
	CALL YCHL	; Lies 1. Byte nach D
	LD B,C
	LD A,(BANKNR)
	INC HL
	CALL YCHL	; Lies 2. Byte nach E
	PUSH BC
	LD A,(BANKNR)
	INC HL
	CALL YCHL	; Lies 3. Byte nach B
	LD B,C
	LD A,(BANKNR)
	INC HL
	CALL YCHL	; Lies 4. Byte nach C
	POP DE
	POP HL
	LD (HL),D	; Schreibe DEBC in Variable
	INC HL
	LD (HL),E
	INC HL
	LD (HL),B
	INC HL
	LD (HL),C
	RET

	.XLIST
	ENDIF

	IF SB
	TITLE STOREB
	.PRINTX *STOREB*
	.LIST
	ENTRY STOREB
	EXT ADRHL,BANKNR
	.COMMENT#

STOREB(BYTE,IADDR)
speichert ein Byte in die RAM-Bank.

Die Argumente werden nach den Regeln von Microsoft FORTRAN uebergeben.
Demnach enthaelt
- HL die Adresse von BYTE 
- DE die Adresse der Integer-Variablen IADDR. Darin steht die Speicheradresse,
  wohin das Byte geschrieben werden soll.

Der Inhalt von IADDR wird von Routine ADRHL nach HL geladen.

A.Herrmann	18.06.84
#
STOREB:	LD C,(HL)	; Lies Byte nach BC
	CALL ADRHL	; Lies Adresse nach HL
	LD A,(BANKNR)	; Bank Nr.
	CALL YHLC	; Schreibe Byte aus C
	RET

	.XLIST
	ENDIF

	IF SW
	TITLE STOREW
	.PRINTX *STOREW*
	.LIST
	ENTRY STOREW
	EXT ADRHL,BANKNR
	.COMMENT#

STOREW(WORD,IADDR)
speichert ein Wort, d.h. 2 Bytes in die RAM-Bank.

Die Argumente werden nach den Regeln von Microsoft FORTRAN uebergeben.
Demnach enthaelt
- HL die Adresse von WORD
- DE die Adresse der Integer-Variablen IADDR. Darin steht die Speicheradresse,
  wohin das Wort geschrieben werden soll.

Der Inhalt von IADDR wird von Routine ADRHL nach HL geladen.

A.Herrmann	18.06.84
#
STOREW:	LD C,(HL)	; Lies Wort nach BC
	INC HL
	LD B,(HL)
	CALL ADRHL	; Lies Adresse nach HL
	LD A,(BANKNR)	; Bank Nr.
	CALL YHLC	; Schreibe Low Byte aus C
	INC HL
	LD C,B
	LD A,(BANKNR)
	CALL YHLC	; Schreibe High Byte aus C
	RET

	.XLIST
	ENDIF

	IF SR
	TITLE STORER
	.PRINTX *STORER*
	.LIST
	ENTRY STORER
	EXT ADRHL,BANKNR
	.COMMENT#

STORER(REAL,IADDR)
speichert ein Doppelwort, d.h. 4 Bytes in die RAM-Bank.

Die Argumente werden nach den Regeln von Microsoft FORTRAN uebergeben.
Demnach enthaelt
- HL die Adresse von REAL
- DE die Adresse der Integer-Variablen IADDR. Darin steht die Speicheradresse,
  wohin das Doppelwort geschrieben werden soll.

Der Inhalt von IADDR wird von Routine ADRHL nach HL geladen.

A.Herrmann	18.06.84
#
STORER:	PUSH DE
	LD C,(HL)	; Var. nach CBED kopieren
	INC HL
	LD B,(HL)
	INC HL
	LD E,(HL)
	INC HL
	LD D,(HL)
	POP HL
	PUSH DE
	EX DE,HL
	CALL ADRHL	; Lies Adresse nach HL
	LD A,(BANKNR)	; Bank Nr.
	CALL YHLC	; Schreibe 1. Byte aus C
	INC HL
	LD C,B
	LD A,(BANKNR)
	CALL YHLC	; Schreibe 2. Byte aus B
	POP BC
	INC HL
	LD A,(BANKNR)
	CALL YHLC	; Schreibe 3. Byte aus E
	INC HL
	LD C,B
	LD A,(BANKNR)
	CALL YHLC	; Schreibe 4. Byte aus D
	RET

	.XLIST
	ENDIF

	IF AD
	TITLE ADRHL
	.PRINTX *ADRHL*
	.LIST
	ENTRY ADRHL
	PUBLIC BANKNR
	.COMMENT#

ADRHL
laedt HL mit der Adresse in der RAM-Bank, auf die beim Lesen oder Schreiben 
zugegriffen werden soll. DE zeigt auf die Variable, die diese Adresse enthaelt.

In der Variablen BANKNR steht die Nummer der RAM-Bank, auf die zugegriffen
werden soll.

Diese Routine wird von allen LOAD- und STORE-Routinen benutzt.

A.Herrmann	18.06.84
#
BANKNR:	DB 1		; Initialisiert auf Bank-Nr. 1

ADRHL:	EX DE,HL	; Lies Adresse nach HL
	LD E,(HL)
	INC HL
	LD D,(HL)
	EX DE,HL
	RET

	.XLIST
	ENDIF

	IF VP
	TITLE VARPTR
	.PRINTX *VARPTR*
	.LIST
	ENTRY VARPTR
	.COMMENT#

VARPTR(ARG)
fungiert als Dummy-Routine, um die Adresse einer Variablen oder Routine
ARG zu finden.

Wenn VARPTR als Integer-Function in FORTRAN aufgerufen wird, enthaelt 
HL die Adresse von ARG. Da eine Integer-Function ihr Ergebnis in HL
zurueckgeben muss, genuegt der Return-Befehl.

A.Herrmann	12.01.84
#
VARPTR:	RET

	.XLIST
	ENDIF

	.LIST
	END
