;Archi3 (v1.3) - (Adventure-Routinen)
;15.5.1990 (1.,14.5.1990)
;[Line1 - Zeichnen beliebiger Linien ( Bildschirmstart beliebig )]
;30.12.1989
;
NOLIST
;WRITE"ARCHI3.BIN"
;
FLYBACK EQU &BD19
;
;
;dynamische Variablen
;
ERRFLG EQU &A400;DB 0 (0=kein Fehler;1=Buffer voll;2=Buffanfang;
 ;3=Buffende;4=Esc)
ART EQU ERRFLG+1;DB 0 Zeichenart(0=move;1=plot;2=draw;3=Rechteck)
BUFFANF EQU ART+1;DW 0 (Bufferanfang)
BUFFEND EQU BUFFANF+2;DW 0 (Bufferende)
BUFFMAX EQU BUFFEND+2;DW 0 (akt.Bufferende,bis wo benutzt)
BUFFPTR EQU BUFFMAX+2;DW 0 (akt.Bufferpointer)

VARSTART EQU BUFFPTR+2
XANF EQU VARSTART;DW 0 x-Anfang
YANF EQU XANF+2;DB 0 y-Anfang
XEND EQU YANF+1;DW 0 x-Ende
YEND EQU XEND+2;DB 0 y-Ende
LCALL EQU YEND+1;DW 0 Line-Call (HTLINE oder VTLINE)
KDIFF EQU LCALL+2;DW 0 kleinere Differenz
VAREND EQU KDIFF+2;
;
NMOVE EQU VAREND;DB 0,0 (Normalmove y,x)
PMPOS EQU NMOVE+2;DS 3 (PointerMovePOS xx,y)
POWIN EQU PMPOS+3;DS 6 (Pointerwindow +0=ob(y),+1=un(y),+2=li(xx),+4=re(xx))
 POWINOB EQU POWIN;DB 0
 POWINUN EQU POWIN+1;DB 0
 POWINLI EQU POWIN+2;DW 0
 POWINRE EQU POWIN+4;DW 0
 AMOVE EQU POWIN+6;DB 0,0 (akt.Move y,x)
PMPOS2 EQU POWIN+8;DS 3 (Backup-Pos)
ZMOVE EQU PMPOS2+3;DB 0 (Zaehler-Move)
ALTJOY EQU ZMOVE+1;DB 0 (alter Joystickwert)
XSICH EQU ALTJOY+1;DW 0 (gesicherte xpos)
YSICH EQU XSICH+2;DB 0 (gesicherte ypos)
;
;
;
ORG &9800
JP SCRINIT
JP LINESTART
;
JP MOVEINIT
JP MOVE
;
JP BUFFINITSTART
JP BUFFDECSTART
JP BUFFINCSTART
JP BUFFERSHOW
;
JP DEEK
JP DOKE
;
;
DEEK CP 2
RET NZ
CALL HLVONIX;Deek-Zielvariable
EX DE,HL;nach de
CALL HLVONIX;Adresse
LD C,(HL)
INC HL
LD B,(HL)
EX DE,HL
LD (HL),C
INC HL
LD (HL),B
RET

DOKE CP 2
RET NZ
CALL HLVONIX;Doke-Wert
EX DE,HL;nach de
CALL HLVONIX;Adr
LD (HL),E
INC HL
LD (HL),D
RET
;
;
ERROR
LD (ERRFLG),A;Error set
RET
;
BUFFINITSTART
CP 2
RET NZ
CALL HLVONIX;Bufferende
LD (BUFFEND),HL
CALL HLVONIX;Bufferanfang
LD (BUFFANF),HL
JP BUFFINIT;Bufferzeiger init
;
BUFFDECSTART
CALL BUFFERDEC
LD A,2;Anfang erreicht
JP Z,ERROR
CALL &BB6C;Txt Clear Window
JP BUFFERSHOW
;
BUFFINCSTART
CALL BUFFERGET0;evtl.Koord.+Art holen
LD L,A;ypos schon mal nach l
LD A,3;Ende erreicht
JP Z,ERROR
JP ARTMAKE1;ausfuehren

;Routinen zur Bufferverwaltung
BUFFINIT ; Bufferzeiger,Buffermaxzeiger auf Anfang setzen
LD HL,(BUFFANF)
LD (BUFFPTR),HL
LD (BUFFMAX),HL
RET

BUFFANANF ;Bufferzeiger auf Anfang setzen
LD HL,(BUFFANF)
LD (BUFFPTR),HL
RET

BUFFTESTANF ;hl=buffptr; testen,ob Zeiger auf Anfang (Z=Ja)
PUSH DE
EX DE,HL;buffptr nach de
LD HL,(BUFFANF)
OR A
SBC HL,DE
EX DE,HL;buffptr zurueck
POP DE
RET

BUFFTESTMAX ;hl=buffptr; testen,ob Zeiger auf Max (Z=Ja) (C= HL>buffmax)
PUSH DE
EX DE,HL;buffptr nach de
LD HL,(BUFFMAX)
OR A
SBC HL,DE
EX DE,HL;buffptr zurueck
POP DE
RET


BUFFERINC ;Bufferzeiger ein Element weiterruecken (NZ=Ok)
LD HL,(BUFFPTR);
CALL BUFFTESTMAX;Zeiger auf Max?
RET Z;Ja
INC HL;ypos ueberlesen
INC HL
INC HL;xpos hi ueberlesen
LD (BUFFPTR),HL
RET;mit NZ=Ok

BUFFERDEC ;Bufferzeiger erniedrigen (NZ=Ok)
LD HL,(BUFFPTR)
CALL BUFFTESTANF;Zeiger am Anfang?
RET Z;Ja
DEC HL
DEC HL
DEC HL
LD (BUFFPTR),HL
RET;mit NZ=Ok

BUFFERPUT0 CALL ARTGET; Art nach D
BUFFERPUT ;de=xpos,A=ypos in Buffer schreiben + Pointer erhoehen (NZ=Ok)
LD HL,(BUFFPTR)
PUSH DE
EX DE,HL;buffptr nach de
LD HL,(BUFFEND);maximales Bufferende
OR A
SBC HL,DE
EX DE,HL;buffptr zurueck
POP DE
RET Z;Ende
JR C,BUFFERPUTERR;pointer>ende
LD (HL),E
INC HL
LD (HL),D
INC HL
LD (HL),A
INC HL
LD (BUFFPTR),HL
CALL BUFFTESTMAX;C= hl>buffmax
JR NC,BUFFEROK;hl<=buffmax,buffmax nicht setzen
LD (BUFFMAX),HL;sonst Buffmax setzen
BUFFEROK LD L,1
BIT 0,L
RET;mit NZ=Ok
BUFFERPUTERR
LD L,A
CP L
RET;mit Z=Err


BUFFERGET0 CALL BUFFERGET
CALL NZ,ARTSET;evtl Art aus DE setzen (AF erhalten)
RET
BUFFERGET ;de,A aus Buffer holen + Pointer erhoehen (NZ=Ok)
LD HL,(BUFFPTR);akt.Pos
CALL BUFFTESTMAX
RET Z;Ende
LD E,(HL)
INC HL
LD D,(HL)
INC HL
LD A,(HL)
INC HL
LD (BUFFPTR),HL
RET;mit NZ=Ok

ARTSET ;Art entsprechend de setzen (x-Koord.,Bit 2..7)
PUSH AF
LD A,D
AND %11111100;Bit 2..7
RRCA
RRCA;Bit 2 wird Bit 0
LD (ART),A;set
LD A,D
AND %11;nur bit 0,1 lassen
LD D,A
POP AF
RET

ARTGET ;Art in x-Koordinate de holen (Bit 2..7)
PUSH AF
LD A,(ART)
AND %00111111;Bit 6,7 unbenutzt
RLCA
RLCA;Bit 0 wird Bit 2
OR D;mit Hi-x-Koord.verkn.
LD D,A;nach D
POP AF
RET
;
BUFFERSHOW; Buffer zeigen
CALL GRACURHOME;Grafik-Cursor home
LD HL,(BUFFMAX);akt.Ende
PUSH HL;sich
LD HL,(BUFFPTR);akt.Pos
LD (BUFFMAX),HL;als akt.Ende
CALL BUFFANANF;akt.Zeiger an Anfang
CALL BUFFERSHOW1
LD HL,(BUFFMAX)
LD (BUFFPTR),HL;akt.Pos zurueck
POP HL
LD (BUFFMAX),HL;akt.Ende zurueck
RET

BUFFERSHOW1
CALL BUFFERGET0;Koord.+Art aus Buffer holen
RET Z;keine mehr,fertig
LD L,A;ypos nach L
CALL ARTMAKE1;Art ausfuehren
JR BUFFERSHOW1;weiter
;
;
;
DEADDA
ADD A,E
LD E,A
RET NC
INC D
RET
;
DESUBA
NEG;Zweierkomplement
ADD A,E
LD E,A
RET C;Ueberlauf,dann ok
DEC D
RET
;
MOVEINIT
LD A,0;oben
LD (POWINOB),A;set
ADD A,4
LD (PMPOS+2),A;ypos set

LD A,&BF;unten(191, moeglich bis 199)
LD (POWINUN),A;set
LD HL,&0000;links
LD (POWINLI),HL;set
EX DE,HL;nach DE
LD A,8
CALL DEADDA
EX DE,HL
LD (PMPOS),HL;xpos set

LD HL,639;rechts
LD (POWINRE),HL;set
LD HL,&0101
LD (NMOVE),HL;L=y-Move(1),H=x-Move(1)
RET
;
;
PMPOGET ;PmPos get, de=xpos, A und L=ypos
LD DE,(PMPOS)
LD A,(PMPOS+2)
LD L,A
RET

KREUZAUS0
CALL PMPOGET
;DE=X-Pos;L=Y-Pos
KREUZAN
KREUZAUS
LD A,(WRITESCR);akt.Mode
PUSH AF;sich
LD A,&AE;xor(HL)
LD (WRITESCR),A;set
CALL ARTMAKE0;Art ausfuehren(hl,de,iy,pos erhalten)
PUSH HL;ypos sich
PUSH DE;xpos sich
LD A,8
CALL DEADDA;DE=DE+A
CALL XINWIN;DE in Window
LD B,D
LD C,E;nach BC als xend
POP DE;xpos
PUSH DE;wieder sich
LD A,8
CALL DESUBA;DE=DE-A
CALL XINWIN;in Window
CALL HLINE;horiz.Line
POP DE;xpos
POP BC;C=ypos aus L
LD A,C
SUB A,4;-ypos
JR NC,KREUZ2;kein Unterlauf
LD A,(POWINOB);auf min
KREUZ2
LD L,A
CALL YINWIN;L in Wind.
LD H,L;als xanf
LD A,C
ADD A,4;ypos
LD L,A;nach L
CALL YINWIN;in Wind
CALL VLINE;vertik.Line
POP AF
LD (WRITESCR),A;alten Screen-Mode set
RET
;
CURSICH ;akt.Curpos sich
PUSH AF
PUSH HL
LD HL,(XANF)
LD A,(YANF)
LD (XSICH),HL
LD (YSICH),A
POP HL
POP AF
RET
;
CURRET ;gesicherte Curpos zurueck
PUSH AF
PUSH HL
LD HL,(XSICH)
LD A,(YSICH)
LD (XANF),HL
LD (YANF),A
POP HL
POP AF
RET

;
ARTMAKE0 ;mit Register + alte Pos sichern
CALL CURSICH;akt.Curpos sich
PUSH IY
PUSH DE
PUSH HL
CALL ARTMAKE2
POP HL
POP DE
POP IY
JR CURRET;alte Curpos zurueck

ARTMAKE1 ;mit Registerretten 
PUSH IY
PUSH DE;xpos sich
PUSH HL;ypos sich
CALL ARTMAKE2
POP HL
POP DE
POP IY
RET

ARTMAKE2
LD A,(ART);Zeichenart
OR A;0=move
JR Z,ARTMOVE
DEC A;1?
JR Z,ARTPUNKT
DEC A;2?
JR Z,ARTLINE
DEC A;3?
JR Z,ARTRECHTECK
RET;nichts

ARTMOVE
LD (XANF),DE
LD A,L
LD (YANF),A
RET

ARTPUNKT
CALL ARTMOVE;Posit sich,A=y-Koord.
DEFB #DD
LD L,A;nach XL
CALL BPOSM2;fuer Md.2
JP WRITESCR;Punkt setzen

ARTLINE ;de=xpos,l=ypos
PUSH DE;xpos
PUSH HL;ypos
LD A,L;ypos nach A
CALL LINE;Linie ziehen(iy varaendert)
POP HL
POP DE
JR ARTMOVE;neue Curpos set
;
ARTRECHTECK
CALL CURSICH;Curpos sich,falls nicht erfolgt
PUSH DE;neue xpos
PUSH HL;neue ypos
PUSH HL;nochmal
LD A,(YSICH);alte ypos
LD L,A;nach L
CALL ARTLINE;waag.Linie
POP HL;L=neue ypos
CALL ARTLINE;senkr.L.
LD DE,(XSICH);alte xpos
CALL ARTLINE;waag.L.
LD A,(YSICH);wieder alte ypos
LD L,A
CALL ARTLINE;senkr.L.
POP HL;neue ypos
POP DE;neue xpos
JR ARTMOVE;set

;
DAUS100 ;fuer 0..999
LD DE,100
CALL DAUS1
LD E,10
CALL DAUS1
LD A,L;REST
INC A;KORREKTUR MIND.1
JR DAUS3
DAUS1
XOR A;ZAEHLER=0+NC
DAUS2
SBC HL,DE
INC A
JR NC,DAUS2
ADD HL,DE;EIN SBC RUECKGAENGIG REST
DAUS3
ADD A,"0"-1 ;AUF ASCII
JP &BB5A;Txt Output

POSPRINT
LD H,21;Spalte
LD L,25;Zeile
CALL &BB75;Txt Set Cursor
CALL PMPOGET
PUSH HL;L=ypos sich
EX DE,HL;xpos nach HL
CALL DAUS100;Zahl ausg.
LD A,29;Spalte
CALL &BB6F;Txt Set Column
POP HL;L=ypos
LD H,0;Hi auf 0
CALL DAUS100;ausg.
RET

;
;
MOVE
CP 1;1 Param?
RET NZ
CALL AVONIX
LD (ART),A;Zeichenart set
PUSH IX
PUSH IY
PUSH HL
PUSH DE;SICH
LD IY,POWIN;ADR POINTERWINDOWAUSD.
CALL DMOVEINIT;MoveAbst init
CALL POSPRINT;Akt.Pos ausg.
PMOVE2
CALL PMPOGET;x(de),y(a,l)-pos get
LD (PMPOS2),DE;als alte xpos
LD (PMPOS2+2),A;als alte ypos
CALL KREUZAN
PMOVE3
CALL WAITJOY
LD B,A;Taste sich
CALL PMPOGET;x(de),y(a,l)-pos get
RR B;0.BIT
CALL C,HOCH
RR B
CALL C,RUNTER
RR B
CALL C,LINKS
RR B
CALL C,RECHTS
RR B
JR C,PMFEUER
RR B
JR C,PMESC
CALL XINWIN;DE in Window
CALL YINWIN;L in Window
LD A,L;neue ypos
LD (PMPOS+2),A;sich
EX DE,HL;neue xpos in HL
LD (PMPOS),HL;sich
LD A,(PMPOS2+2);alte ypos
CP E;=neue ypos?
LD DE,(PMPOS2);alte xpos
JR NZ,PMOVE4;nein,Posit veraendert
OR A
SBC HL,DE;=neue xpos?
JR NZ,PMOVE4;nein,veraendert
;nicht veraendert
CALL DMOVEINIT
JR PMOVE3

PMOVE4
CALL FLYBACK
;de ist schon (PMPOS2),A schon (PMPOS2+2)
LD L,A
CALL KREUZAUS;DE=xpos,L=ypos
CALL DMOVEINC;amove evtl.erhoehen
JR PMOVE2
;

PMFEUER
CALL KREUZAUS0
CALL PMPOGET;x,ypos get
PUSH DE;DE sich (D bekommt art)
CALL BUFFERPUT0;in Buffer
POP DE
JR Z,PMFEUER1;Buffer voll
LD L,A;ypos nach L,da l veraendert
CALL ARTMAKE1;Art ausfuehren
JR PMFEUER2
PMFEUER1 LD A,1;Buffer voll
CALL ERROR
PMFEUER2 SCF
PMENDE
POP DE
POP HL
POP IY
POP IX
RET

PMESC
CALL KREUZAUS0
LD A,4;Esc
CALL ERROR
XOR A;Z/NC
JR PMENDE

HOCH
LD A,L;ypos
SUB (IY+6);-ymove
RET C;Unterlauf
LD L,A
RET

RUNTER
LD A,L;ypos
ADD A,(IY+6);+ymove
RET C;Ueberlauf
LD L,A
RET

LINKS
LD A,(IY+7);xmove
JP DESUBA;DE=DE-A

RECHTS
LD A,(IY+7);xmove
JP DEADDA;DE=DE+A
;
;
WAITJOY
PUSH HL
WAITJOY1
CALL &BB24;KM get Joy
OR A;Joy0<>0
JR NZ,WAITJOY3;Ja
LD A,L;Joy1?
OR A
JR NZ,WAITJOY3;Ja
CALL DMOVEINIT;keine Bewegung=> Move init
PUSH DE
PUSH BC;sich
CALL POSPRINT;akt.Pos auf Bildschirm
POP BC
POP DE
LD A,66
CALL &BB09;KM Read Char
CP 252;Esc?
JR NZ,WAITJOY1;nein,weiterwarten
LD A,32;Esc set
WAITJOY3
LD C,A;Code sich
LD A,(ALTJOY);alter Code
CP C;=neuer?
CALL NZ,DMOVEINIT;<>
LD A,C
LD (ALTJOY),A
POP HL
RET
;
;
DMOVEINIT
LD HL,(NMOVE);normalMove
LD (AMOVE),HL;als akt.Move
LD A,12
LD (ZMOVE),A;Zaehler init
RET
;Moveabstand erhoehen,falls Zaehler zmove=0
DMOVEINC
LD A,(ZMOVE);Zaehler
OR A;0?
JR Z,DMOVEINC2;Ja
DEC A;-1
LD (ZMOVE),A
RET
DMOVEINC2
LD HL,AMOVE+1;Adr x-Move
INC (HL);+1
LD A,(HL);get
RRA;Bit 0
JR NC,DMOVEINC3;Bit 0 nicht gesetzt
DEC HL;Adr y-Move
INC (HL);+1
DMOVEINC3 LD A,2
LD (ZMOVE),A
RET
;
;
;x-Koordinate DE in Window bringen
XINWIN
PUSH HL;sich
LD HL,(POWINLI);linke Grenze
SCF;-1
SBC HL,DE
JP P,XINWIN2;zu klein
LD HL,(POWINRE);rechte Grenze
OR A
SBC HL,DE
JP P,XINWIN3;ok
;Koord.zu gross
LD DE,(POWINRE);rechte Grenze nehmen
POP HL
RET
;Koord.zu klein
XINWIN2
LD DE,(POWINLI);linke Grenze nehmen
XINWIN3
POP HL
RET
;
;y-Koordinate L in Window bringen
YINWIN
PUSH DE
PUSH HL
EX DE,HL;Koord.in E
LD D,0
LD A,(POWINUN);untere Windowgrenze(z.B.199)
LD L,A
LD H,0
OR A
SBC HL,DE
JP M,YINWIN2;zu gross
LD A,(POWINOB);obere Grenze(z.B.0)
LD L,A
LD H,0
SCF
SBC HL,DE;y-Koord.
JP P,YINWIN3;zu klein
POP HL
POP DE
RET;ok
;zu gross
YINWIN2
POP HL
LD A,(POWINUN)
LD L,A
POP DE
RET
;zu klein
YINWIN3
POP HL
LD A,(POWINOB)
LD L,A
POP DE
RET
;
;
;
;Line
;
SCRHI DEFB 0;Screen-Hi-Byte &40 oder &C0
HLINE JP 0;Adresse der Horizontalroutine HLineM1 oder HLineM2
VLINE JP 0;Adresse der Vertikalroutine VLineM1 oder VLineM2
;
WRITESCR OR (HL);verknuepfen,auch xor (HL)
LD (HL),A;auf Screen
RET
;
GRACURHOME
LD HL,0
LD (XANF),HL
LD A,0
LD (YANF),A
RET
;
SCRINIT CP 2;2 Param?
RET NZ
CALL AVONIX;Screen-Hi-Byte holen
LD (SCRHI),A;set
CALL AVONIX;Mode holen
LD HL,HLINEM1;Adr fuer Mode1
LD DE,VLINEM1;Adr fuer Mode1
CP 1;Mode1?
JR Z,SCRINIT2;Ja
LD HL,HLINEM2;sonst Adressen
LD DE,VLINEM2;fuer Mode2
SCRINIT2 LD (HLINE+1),HL
LD (VLINE+1),DE
JP GRACURHOME;Grafik-Cursor home
;
LINESTART CP 4
RET NZ
CALL AVONIX;y-Ende
LD C,A;in C sich
CALL HLVONIX;x-Ende
EX DE,HL;nach DE
CALL AVONIX;y-Anfang
LD (YANF),A;set
CALL HLVONIX;x-Anfang
LD (XANF),HL;set
LD A,C;y-Ende
JP LINE
;
AVONIX LD A,(IX+0)
INC IX
INC IX
RET
HLVONIX LD L,(IX+0)
INC IX
LD H,(IX+0)
INC IX
RET
;
;
;
;Line - zeichnen einer Linie
;EIN  DE=x-Ende / A=y-Ende / (xanf),(yanf)
;
LINE
LD (XEND),DE;x-Ende set
LD (YEND),A;y-Ende set
LD IY,0;beide Vorzeichen positiv=0
LD C,A;und in C sich
LD HL,(XANF);x-Anfang
XOR A;A=0;CY AUS
SBC HL,DE;xanf-xend
JP P,LOK;positiv,ok
CALL NEGHL;Zweierkomplement
DEFB #FD
DEC H;YH=Vorzeichen x-Diff,&ff=negativ
LOK PUSH HL;x-Diff sich
LD A,(YANF);y-Anfang
SUB C;-y-Ende
JR NC,LOK2;positiv,ok
NEG;Zweierkomplement
DEFB #FD
DEC L;YL=Vorzeichen y-Diff,&ff=negativ
LOK2 LD L,A
LD H,0;y-Diff nach HL
POP DE;x-Diff
OR A
SBC HL,DE;y-Diff - x-Diff (cy set)
ADD HL,DE;y-Diff wiederherstellen (cy unbeeinflusst)
SBC A,A;A=&ff,wenn x-Diff groesser
LD (LFLG),A;sich
DEFB #FD
LD A,L;y-Diff nach A
LD BC,VTLINE
JR Z,LOK3;y-Diff groesser oder gleich
EX DE,HL;Differenzen vertauschen
DEFB #FD
LD A,H;Vorz.x-Diff
LD BC,HTLINE;x-Diff groesser
;
;EIN HL=groessere Differenz,A=Vorzeichen dazu / DE=kleinere Differenz/
;    BC=Routinenadr fuer Teillinie (VTLine bei yDiff>=xDiff, sonst HTLine)
;
LOK3 LD (LCALL),BC;Teillinienadr set
PUSH AF;Vorz.gr.Diff
LD (KDIFF),DE;kleinere Diff sich
LD B,H
LD C,L
INC BC;gr.Diff+1=Breite
LD (BREIT),BC;set
CALL NEGHL;Zweierkomplement der Breite
POP AF;Vorz.gr.Diff
PUSH HL;neg.gr.Diff
ADD HL,DE;kleinere-groessere Diff
LD (DDIFF),HL;Differenz der Differenzen
OR A;Vorzeichen gr.Diff negativ?
JR NZ,LOK4;Ja
LD A,(YEND);y-Ende
LD (YANF),A;nach y-Anf
LD HL,(XEND);x-Ende
LD (XANF),HL;nach x-Anf
DEFB #FD
LD A,L;Vorz.y-Diff
CPL;komplementieren
DEFB #FD
LD L,A;und wieder set
DEFB #FD
LD A,H;Vorz.x-Diff
CPL;kompl.
DEFB #FD
LD H,A
;
LOK4 EQU $
LFLG EQU $+1
LD A,0;FLAG 0/FF
OR A;FF=X-DIFF MANIP.
JR NZ,LOK5;JA
;Y GROESSER 
LD HL,VHLP;ADR VERT.INC/DEC
LD (HL),#1B;CODE DEC DE
DEFB #FD
INC H;X-DIFF POSITIV?
JR NZ,LOK6;JA
LD (HL),#13;CODE INC DE
JR LOK6
;X GROESSER 
LOK5
LD HL,HHLP;ADR HORIZ.INC/DEC
LD (HL),#3D;CODE DEC A
DEFB #FD
INC L;POSITIV?
JR NZ,LOK6;JA
DEC (HL);#3C=INC A
LOK6
POP HL;NEG GR DIFF
SRA H
RR L;/2 KORRIGIEREN
LD A,D
OR E;KLEINERE DIFF=0?
JP Z,TLINE;NUR TEILLINIE
LD BC,#0000
PUSH BC;GROE SCHRITTWEITE
POP IY
L1840
PUSH IY
POP DE
OR A
ADC HL,DE
LD DE,(KDIFF);kleinere Differenz
JP P,L1853
L184D
INC BC
ADD IY,DE
ADD HL,DE
JR NC,L184D
L1853
XOR A
SUB E
LD E,A
SBC A,A
SUB D
LD D,A
L1859
ADD HL,DE
JR NC,L1861
ADD IY,DE
DEC BC
JR L1859
DDIFF EQU $+1
L1861
LD DE,0;KL-GR.DIFF
ADD HL,DE
PUSH BC
PUSH HL
BREIT EQU $+1
LD HL,0;BREITE
OR A
SBC HL,BC
JR NC,L1876
ADD HL,BC
LD B,H
LD C,L
LD HL,#0000
L1876
LD (BREIT),HL
CALL TLINE;Teillinie zeichnen
POP HL
POP BC
LD DE,(BREIT)
LD A,D
OR E
JR NZ,L1840
RET
;
;Teillinie ziehen
TLINE LD HL,(LCALL);entweder VTLine oder HTLine
JP (HL);anspringen
;
;vertikale Teillinie ziehen
;EIN  C=Laenge
;
VTLINE LD DE,(XANF);x-Anfang
LD A,C;Laenge=0?
OR A
JR Z,VHLP;ja,nicht zeichnen
LD A,(YANF);y-Anfang
LD H,A;in H sich
ADD A,C;+Laenge
LD (YANF),A;neues y-Anf set
DEC A;Korrektur
LD L,A;y-Ende
CALL VLINE;vertikale Linie ziehen / DE erhalten
VHLP
NOP;DEC/INC DE=x-Koordinate erhoehen,erniedrigen
LD (XANF),DE;und setzen
RET
;
;horizontale Teillinie ziehen
;EIN  BC=Laenge
;
HTLINE LD A,B
OR C;Laenge=0?
LD A,(YANF);y-Koord
JR Z,HHLP;Laenge=0
LD HL,(XANF);x-Anfang
LD D,H
LD E,L;auch in DE
ADD HL,BC;Laenge dazu
LD (XANF),HL;neues y-Anfang set
DEC HL;Korrektur
LD B,H
LD C,L;x-Ende in BC
LD L,A;y-Anf nach L
CALL HLINE;horizontale Linie ziehen
DEFB #DD
LD A,L;y-Koord aus XL
HHLP
NOP;INC/DEC A=y-Koord erhoehen,erniedrigen
LD (YANF),A;und setzen
RET
;
;
;Zweierkomplement von HL
;EIN  HL=Zahl in Komplementdarstellung
;AUS  HL=umgewandelte Zahl / A=H
;
NEGHL XOR A
SUB L
LD L,A
SBC A,A
SUB H
LD H,A
RET
;
;
;
;horizontale/vertikale Linien
;30.12.1989
;Screen ab &4000 oder &C000 !
;
;HLINEM1 (Mode 1) , HLINEM2 (Mode 2)
;EIN   DE=x-Koord.Anfang / BC=x-Koord.Ende / L=y-Koord.
;AUS   HL=letzte Bildadr / XL=yPos / AF,BC,DE veraendert
;BENOETIGT HLINET (ohne Adresse mit Ueberlauf!)
;
;VLINEM1 (Mode 1) , VLINEM2 (Mode 2)
;EIN   DE=x-Koordinate / H=y-Koord.Anfang / L=y-Koord.Ende
;AUS   HL=letzte Bildadr/C=Bitmaske / IXL=y-Anfang / DE erhalten
;
;BENOETIGEN BPOSM1 , BPOSM2
;
;
;Mode 1
HLINEM1 LD A,L;y-Koord
DEFB #DD
LD L,A;nach XL
LD H,B
LD L,C;x-Ende
OR A
SBC HL,DE;-x-Anfang
RET C;Ende<Anfang
PUSH HL;x-Differenz sich
CALL BPOSM1;Positionsberechnung fuer Md1
CALL WRITESCR
POP DE;x-Differenz aus HL
SRL D
RR E;x-Diff/2,da 2 Punkte pro Koordinate
HLINEM11 LD A,D
OR E;Differenz schon 0?
RET Z;fertig
RRC C;Maske nach rechts
LD A,C;Maske nach A
CP &10;schon<&10?
JR C,HLINEM12;ja,Maske Unterlauf
DEC DE;jetzt erst Breite-1
CALL WRITESCR
JR HLINEM11;und weiter
HLINEM12 LD A,E;Breite Lo
SRL D
RRA
SRL D
RRA;A=DE/4(Pixel pro Byte)
INC A;Byteanz+1,da gleich zuerst Djnz
LD B,A;Byteanzahl nach B
;ld a,240
JR HLINEM14
HLINEM13 INC HL;Adr+1
LD A,240;Byte voll (4 Pixel gesetzt)
CALL WRITESCR
HLINEM14 DJNZ HLINEM13;weiter
LD A,E
AND &3;Breite Mod 4
RET Z;fertig
;innerhalb Byte Restpixel setzen (A=Anz Bits)
LD DE,HLINET;Tabellenstart
ADD A,E;Tabelle ohne Ueberlaufadresse !
LD E,A
LD A,(DE);Bitmaske aus Tabelle holen
INC HL;next Byte
CALL WRITESCR
RET
;
VLINEM1 LD A,L;y-Koord.Ende
SUB H;-y-Koord.Anfang
RET C;Eende<Anfang!
PUSH AF;y-Diff sich
LD A,H;y-Anfang
DEFB #DD
LD L,A;nach XL
CALL BPOSM1;Positionsberechnung fuer Md1
CALL WRITESCR
POP AF;Laenge
RET Z;Laenge=0 - fertig
LD B,A;Laenge nach B
PUSH DE;x-Koord.sich
LD DE,#C050;Ueberlaufwert bei Next Line
VLINEM11
LD A,H
ADD A,8
LD H,A;next Line
AND #38;Ueberlauf?
JR NZ,VLINEM12;nein
ADD HL,DE;+Ueberlaufwert (entspricht -#3FB0)
VLINEM12 LD A,C;Maske
CALL WRITESCR
DJNZ VLINEM11;bis Laenge=0
POP DE;x-Koord.zurueck
RET
;
;
;Mode 2
HLINEM2 LD A,L;y-Koord
DEFB #DD
LD L,A;nach XL
LD H,B
LD L,C;x-Ende
OR A
SBC HL,DE;-x-Anfang
RET C;Ende<Anfang
PUSH HL;x-Differenz sich
CALL BPOSM2;Positionsberechnung fuer Md2
CALL WRITESCR;Maske mit Scr verknuepfen
POP DE;x-Differenz aus HL
HLINEM21 LD A,D
OR E;Differenz schon 0?
RET Z;fertig
RRC C;Maske nach rechts
DEC DE;Breite-1
JR C,HLINEM22;Maske Unterlauf
LD A,C;Maske nach A
CALL WRITESCR;Pset mit Maske
JR HLINEM21;und weiter
HLINEM22 LD A,E;Breite Lo
SRL D
RRA
SRL D
RRA
SRL D
RRA;A=DE/8(Pixel pro Byte)
INC A;Byteanz+1,da gleich zuerst Djnz
LD B,A;Byteanzahl nach B
;ld a,255
JR HLINEM24
HLINEM23 INC HL;Adr+1
LD A,255;Byte voll (4 Pixel gesetzt)
CALL WRITESCR
HLINEM24 DJNZ HLINEM23;weiter
LD A,E
AND &7;Breite Mod 8
RET Z;fertig
;innerhalb Byte Restpixel setzen (A=Anz Bits)
LD DE,HLINET;Tabellenstart
ADD A,E;Tabelle ohne Ueberlaufadresse !
LD E,A
LD A,(DE);Bitmaske aus Tabelle holen
INC HL;next Byte
CALL WRITESCR
RET
;
VLINEM2 LD A,L;y-Koord.Ende
SUB H;-y-Koord.Anfang
RET C;Eende<Anfang!
PUSH AF;y-Diff sich
LD A,H;y-Anfang
DEFB #DD
LD L,A;nach XL
CALL BPOSM2;Positionsberechnung fuer Md2
CALL WRITESCR
POP AF;Laenge
RET Z;Laenge=0 - fertig
LD B,A;Laenge nach B
PUSH DE;x-Koord.sich
LD DE,#C050;Ueberlaufwert bei Next Line
VLINEM21
LD A,H
ADD A,8
LD H,A;next Line
AND #38;Ueberlauf?
JR NZ,VLINEM22;nein
ADD HL,DE;+Ueberlaufwert (entspricht -#3FB0)
VLINEM22 LD A,C;Maske
CALL WRITESCR
DJNZ VLINEM21;bis Laenge=0
POP DE;x-Koord.zurueck
RET
;
;
;
;
;Bildschirmpositionsberechnung (beliebiger Bildschirmstart)
;30.12.1989
;
;BPOSM1 (Mode 1) , BPOSM2 (Mode 2)
;EIN  DE=x-Koordinate (0-639) / IXL=y-Koordinate (0-199)
;AUS  HL=Bildadresse/A,C=BitMaske /B veraendert
;
;BENOETIGT BPOST (ohne Adresse mit Ueberlauf!) , SCRHI=Hi-Byte des Screens
;
;
;Mode 1
BPOSM1 PUSH DE;SICH
DEFB #DD
LD A,L;LD A,IXL
AND #F8;8*INT(Y/8)...
LD L,A
LD C,A
LD H,0
LD B,H;NACH HL UND BC
ADD HL,HL
ADD HL,HL;*4
ADD HL,BC;*5
ADD HL,HL;*10
DEFB #DD
LD A,L;Y-KOORD.
AND 7;REST VON Y/8
ADD A,A
ADD A,A
ADD A,A;*8
ADD A,H;Hi-Byte dazu
LD H,A;schon mal sichern
LD A,(SCRHI);Hi-Byte Scr
ADD A,H;dazu
LD H,A;und setzen
SRL D
RR E;x-Koord/2
LD A,E;xLo nach A
SRL D
RRA;/4
SRL D
RRA;/8
LD B,0
LD C,A;NACH BC
ADD HL,BC;UND ZUR ADR
LD A,E;xLo/2
AND 3;REST VON X/4
LD DE,BPOST;TABELLENADR
ADD A,E;LOW-BYTE DAZU
LD E,A
LD A,(DE);MASKE HOLEN
LD C,A;AUCH NACH C
POP DE;X-KOORD.ZURUECK
RET
;
;
;Mode 2
BPOSM2 PUSH DE;SICH
DEFB #DD
LD A,L;LD A,IXL
AND #F8;8*INT(Y/8)...
LD L,A
LD C,A
LD H,0
LD B,H;NACH HL UND BC
ADD HL,HL
ADD HL,HL;*4
ADD HL,BC;*5
ADD HL,HL;*10
DEFB #DD
LD A,L;Y-KOORD.
AND 7;REST VON Y/8
ADD A,A
ADD A,A
ADD A,A;*8
ADD A,H;Hi-Byte dazu
LD H,A;schon mal sichern
LD A,(SCRHI);Hi-Byte Scr
ADD A,H;dazu
LD H,A;und setzen
LD A,E;X-LOW NACH A
SRL D
RRA;DE/8,A=ERG
SRL D
RRA
SRL D
RRA
LD B,0
LD C,A;NACH BC
ADD HL,BC;UND ZUR ADR
LD A,E;X-LOW
AND 7;REST VON X/8
LD DE,BPOST;TABELLENADR
ADD A,E;LOW-BYTE DAZU
LD E,A
LD A,(DE);MASKE HOLEN
LD C,A;AUCH NACH C
POP DE;X-KOORD.ZURUECK
RET
;
;
;
list
;folgende Tabellen duerfen keine Adresse mit Hi-Byte-Ueberlauf belegen !!
BPOST DEFB #80,#40,#20,#10,#08,#04,#02,#01
HLINET DEFB #00,#80,#C0,#E0,#F0,#F8,#FC,#FE,#FF
nolist
;
LIST
END
;
