;Linetes
;
;
NOLIST
;WRITE"LINETES.BIN"
;
;dynamische Variablen ab &a400
;
VARSTART EQU &A400
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;

FARBE EQU VAREND
;
;
ORG &9800
JP SCRINIT
JP LINESTART
JP FARBSET
;
FARBSET CP 1
RET NZ
CALL AVONIX
LD (FARBE),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
RET
;
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
;
;
;
;auf Screen schreiben
; EIN  HL=Screenadr ; A=Bitmaske
; AUS  -
WRITESCR OR (HL);verknuepfen,auch xor (HL)
LD (HL),A;auf Screen
RET
;
;BPOS JP 0;Adresse der Positionsberechnung BposM1 oder BposM2
;
;
;
;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
;
;
;
;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 C,240;4 Pixel gesetzt
JR HLINEM14
HLINEM13 INC HL;Adr+1
LD A,C;Byte voll
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 C,255;Byte voll(8 Pixel gesetzt)
JR HLINEM24
HLINEM23 INC HL;Adr+1
LD A,C;
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
JP WRITESCR
;
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
;