;*********************************************
;*      Relozierprogramm: Datenblock         *
;* Version 2 vom 18.01.1986 - Stefan M. Aust *
;*********************************************
;
;--> Startadresse des Datenblocks
;
ORG #A000
;
;--> Format der Daten:  Die Lénge der einzelnen Z80-Befehle ist jeweils
; fèr normale Befehle, ED-Befehle, DD & FD-Befehle
; bitweise in Byte gepackt.
; Fèr den Befehl 'LD HL,(nn)' := 2A steht z.B. an
; #2A. Stelle in der Tabelle % 0011 0111.
; DD & DF-Befehl 3 Byte - - - - ^^^
; ED-Befehl (undefiniert) 1 Byte - -^^
; normaler Befehl 3 Byte - - - - - - -^^
;
byttab: DEFB #15,#17,#15,#15,#15,#15,#16,#15
DEFB #15,#15,#15,#15,#15,#15,#16,#15
DEFB #16,#17,#15,#15,#15,#15,#16,#15
DEFB #16,#15,#15,#15,#15,#15,#16,#15
DEFB #16,#37,#37,#15,#15,#15,#16,#15
DEFB #16,#15,#37,#15,#15,#15,#16,#15
DEFB #16,#17,#17,#15,#25,#25,#46,#15
DEFB #16,#15,#17,#15,#15,#15,#16,#15
DEFB #15,#15,#15,#1D,#15,#15,#25,#15
DEFB #15,#15,#15,#1D,#15,#15,#25,#15
DEFB #15,#15,#15,#1D,#15,#15,#25,#15
DEFB #15,#15,#15,#1D,#15,#15,#25,#15
DEFB #15,#15,#15,#1D,#15,#15,#25,#15
DEFB #15,#15,#15,#1D,#15,#15,#25,#15
DEFB #25,#25,#25,#2D,#25,#25,#15,#25
DEFB #15,#15,#15,#1D,#15,#15,#25,#15
DEFB #15,#15,#15,#15,#15,#15,#25,#15
DEFB #15,#15,#15,#15,#15,#15,#25,#15
DEFB #15,#15,#15,#15,#15,#15,#25,#15
DEFB #15,#15,#15,#15,#15,#15,#25,#15
DEFB #15,#15,#15,#15,#15,#15,#25,#15
DEFB #15,#15,#15,#15,#15,#15,#25,#15
DEFB #15,#15,#15,#15,#15,#15,#25,#15
DEFB #15,#15,#15,#15,#15,#15,#25,#15
DEFB #15,#15,#17,#17,#17,#15,#16,#15
DEFB #15,#15,#17,#46,#17,#17,#16,#15
DEFB #15,#15,#17,#16,#17,#15,#16,#15
DEFB #15,#15,#17,#16,#17,#14,#16,#15
DEFB #15,#15,#17,#15,#17,#15,#16,#15
DEFB #15,#15,#17,#15,#17,#14,#16,#15
DEFB #15,#15,#17,#15,#17,#15,#16,#15
DEFB #15,#15,#17,#15,#17,#14,#16,#15
;
;
;***********************************************
;*  Relozierprogramm: Source-Code              *
;*  Version 4 vom 18.01.1986 - Stefan M. Aust  *
;***********************************************
;
;Aufruf des Programms: CALL Adresse,Start,Ende,Anfang,Schu~,Offset
; Adresse := Startadresse des Relozierprogramms
; Start  := Beginn des zu untersuchenden Bereichs
; Ende := Ende dieses Bereichs
; Anfang := Beginn des Adressbereichs, in dem die
;    Adresse liegen mu~, damit sie geéndert wird
; Schlu~ := Ende dieses Bereichs
; Offset := Die Basisadresse fèr den neuen Adressbereich
;
;--> Hier steht das Programm: Startadresse
;
Here: EQU $ ;Here mu~ #A100 sein, sonst Fehler in Datenblock
;
;--> Und hier féngt das Programm an
;
CP 5 ;wurden 5 Argumente èbergeben?
RET NZ ;nein, zurèck
LD HL,offset+1 ;Adresse-Speicherbereich
LD B,A ;B=Anzahl Argumente (5)
loop1: LD A,(IX+1) ;(HL)=(IX+1)
LD (HL),A
DEC HL
LD A,(IX+0) ;(HL-1)=(IX)
LD (HL),A
DEC HL
INC IX
INC IX
DJNZ loop1 ;weiter bis alle Argumente kopier
LD HL,(anfang) ;Startadresse
;--> Hauptschleife:
loop2: PUSH HL ;retten
LD A,(HL) ;A=zu untersuchendes Byte
INC HL ;HL=Adresse néchstes Byte
CP #ED ;ED-Befehl?
JR NZ,no_ED ;nein,->weiter
LD B,1 ;sonst B=ED-Befehl
CALL adr1 ;Lénge bestimmen
AND 3
LD B,1
JR test ;weiter->
no_ED: CP #DD ;DD-Befehl?
JR Z,DD_Bef ;ja,->
CP #FD ;oder FD-Befehl?
JR NZ,normal ;nein,->normal
DD_Bef: LD B,2 ;sonst B=DD,FD-Befehl
CALL adr1 ;Lénge bestimmen
AND 7
LD B,1
JR test ;weiter->
normal: LD B,0 ;B=normaler Befehl
CALL adr2 ;Lénge bestimmen
AND 3
test: CP 3 ;3-Byte-Befehl?
JR NZ,unglei ;nein, nicht veréndern
PUSH BC ;Register retten
LD E,(HL) ;DE=Argument des 3-Byte-Befehls
INC HL
LD D,(HL)
EX DE,HL ;HL=Argument
LD BC,(ende) ;BC=Endadresse
OR A ;carry lùschen
SBC HL,BC ;Argument < Ende ?
JR NC,nein ;nein, nicht veréndern
ADD HL,BC ;Argument wiederherstellen
LD BC,(start) ;BC=Startadresse
OR A ;Carry lùschen
SBC HL,BC ;Argument > Start ?
JR C,nein ;nein, nicht veréndern
LD BC,(offset) ;BC=Offset auf neuen Adressbereich
ADD HL,BC ;HL=veréndertes Argument
EX DE,HL ;DE=Argument, HL=Adress
LD (HL),D ;Argument abspeichern
DEC HL
LD (HL),E
nein: POP BC ;Register zurèck
unglei: CP 4 ;A = 4 ? ( Spezialbefehl LD (IX+d),n )
JR NZ,weiter ;nein, ->
DEC A ;sonst A - 1
weiter: ADD A,B ;Offset B zu A addieren
LD D,0 ;DE = A (Lénge des Befehls)
LD E,A
POP HL ;HL=aktuelle Adresse
ADD HL,DE ;HL=neue Adresse
LD BC,(schlus) ;BC=Schlu~
OR A ;carry lùschen
SBC HL,BC ;schon Schlu~ erreicht?
RET NC ;ja, zurèck
ADD HL,BC ;sonst HL wiederherstellen
JR loop2 ;und weiter
;
;--> Unterprogramm: Lénge des Z80-Befehl feststellen
;    In:  HL=Adresse des Befehls, B=Befehlstyp (normal,ED,DD & FD)
;    Out: A and 3=Lénge, ev. HL=HL+1
;
adr1: LD A,(HL) ;A = Befehlsbyte
INC HL ;Adresse + 1
adr2: PUSH HL ;und retten
LD HL,byttab ;HL Anfangsadresse Tabelle
LD D,0 ;DE=Befehlsbyte (d.h. Offset auf Tabelle)
LD E,A
ADD HL,DE ;HL=gesuchter Tabelleneintrag
LD A,B ;B=0?
OR A ;dann Zero=1
LD A,(HL) ;A=Tabelleneintrag
JR Z,ok ;B war 0,->
loop3: RRCA ;Eintrag rotieren, solange bis gewènschte
RRCA ;Bitposition ins Bit 0 und 1 steht
DJNZ loop3
ok: POP HL ;Adresse zurèck nach HL
RET
;
;--> Speicherbereich fèr Daten
;
anfang: DEFW 0
schlus: DEFW 0
start: DEFW 0
ende: DEFW 0
offset: DEFW 0
END