;PoPack2 - Pointer-Pack (v1.2)
;31.8.1992 (1.,2.4., 9.,13.,18.,19.6.1992)
;
nolist
;
;WRITE"POPACK2.BIN"
;
org &9E00;bis &A4c6 (interne Variablen ab &a483)
PRGSTART JP RSXINST;Rsx-Install
POJUMPTAB
DEFW PORSXTAB;Adr Namenstabelle
JP WINITBAS;|WINIT
JP PMOVEBAS;|PMOVE
JP WINBAS;|WIN
JP WRESBAS;|WRES
;
DEFM "Pointy v1.2"
;
MAUS DEFB 0;Flag, ob Maus=#FF, 00=Joystick
MMOVE DEFW #0205;x,y-PointerMovewert bei Maus
ZMINIT DEFB 25;y-Zmove-Init
DEFB 25;x-Zmove-Init
ZMRELO DEFB 7;y-Zmove-Reload
DEFB 12;x-Zmove-Reload
SHOWFLG DEFB 0;Rahmen nicht zeigen, wenn nicht genug Speicher
;
;
PORSXTAB
DEFM "WINI"
DEFB "T"+#80
DEFM "PMOV"
DEFB "E"+#80
DEFM "WI"
DEFB "N"+#80
DEFM "WRE"
DEFB "S"+#80
DEFB 0;Ende
;
RSXINST
LD HL,PORSXTAB;Adr WINIT-Kommando
CALL #BCD4;KL FIND COMMAND
RET C;schon vorhanden,nicht einhaengen
LD HL,KERBYTES;4 Bytes fuer Verkettung
LD BC,POJUMPTAB;Adr Kommandotabelle
CALL #BCD1;KL LOG EXT (Rsx einhaengen)
JP INITALL;schon mal Standardinit
;
;
AVONIX LD A,(IX+0)
AVONIX1 INC IX
INC IX
RET
;
HLVONIX LD H,(IX+1)
LD L,(IX+0)
JR AVONIX1
;
;WInit-Befehl
;|WINIT,art,para1,para2  oder |WINIT (=Totalinit)
;art=0 - PDBUFSET - para1=Anfadr, para2=Endadr
;art=1 - Windowbyte - para1=Windowrahmen, para2=Windowinnen
WINITBAS OR A
JR Z,INITALL;kein Param.
CP 3;3 Param?
JR NZ,INITALL;nein,Err
CALL HLVONIX;3.Param.
EX DE,HL;nach DE
CALL HLVONIX;2.Param.
CALL AVONIX;1.Param=Art
OR A;cp 0
JR Z,WINITBAS2;PD-Buffer set
CP 1
JR Z,WINITBAS3;Windowrahmen,-Innen set
RET
WINITBAS2
LD (PDANF),HL;PD-Bufferanf
LD (PDZEIG),HL;als akt.PDPos
LD (PDEND),DE;PD-Bufferend
RET
WINITBAS3
LD H,E;Windowinnen nach H
LD (WINDOWB),HL;Windowrahmen,innen set
RET

INITALL CALL &BC11;Scr Get Mode
CALL MODESET;setzen
LD HL,HIBUF
LD (PHIBU),HL;Hintergrbufferadr
LD HL,#0000
LD (POWIN),HL;Pointerwindow oben,links
LD (POWIN+4),HL;Menuewindow oben,links
LD HL,#4EBA
LD (POWIN+2),HL;Pointerwindow unten,rechts
INC H;re=79
LD (POWIN+6),HL;Menuewindow un,re
LD HL,#0000
LD (PMPOS),HL
LD HL,&9000;Bufferanf
LD DE,PRGSTART;Bufferende (&9F00)
CALL WINITBAS2;set
JP BALKAUS1;Balken init

;
;PMove-Befehl
;|PMOVE,@x,@y
;Pointer move und select - liefert absolute Selectposition x,y (0,0=ESC)
;
PMOVEBAS CP 2
RET NZ
CALL HLVONIX
PUSH HL;Varadr Selectpos-y
CALL HLVONIX
PUSH HL;Varadr Selectpos-x
CALL PMOVE
LD BC,&0000;kein Select
JR NC,PMBASNEE;nichts Select
LD BC,(BALPOS)
CALL CHPOS;BC wird Charpos
INC B
INC C;fuer Basic+1
PMBASNEE POP HL;Adr-x
LD (HL),B
INC HL
LD (HL),0
POP HL;Adr-y
LD (HL),C
INC HL
LD (HL),0
RET

;
;Win-Befehl
;|WIN,art,links,rechts,oben,unten
;(art - 0=normales Window, 1=PD-Window, 2=Menuewindow, 3=Pointerwindow)
WINBAS SUB 5
RET C;C=zu wenig Param.
CALL AVONIX
LD E,A;unterste Zeile
CALL AVONIX
LD C,A;oberste Zeile
CALL AVONIX
LD D,A;rechte Spalte
CALL AVONIX
LD B,A;linke Spalte
CALL AVONIX;Windowart
DEC B
DEC C
DEC D
DEC E;Koordinaten-1
CP 4;>=4?
RET NC;Ja,Err.
LD HL,WINDOW;Fortsetzungsadr. normal Window
OR A;cp 0
JP Z,TWINDOW
LD HL,PDSET;PD-Windowroutine
CP 1
JP Z,TWINDOW
CP 2
JR Z,WINBASMEN;art=2 - Menuewindow set
;3 = Pointer-Window set
LD (POWIN),BC;oben,links
LD (POWIN+2),DE;unten,rechts
JP PMINIT;Pointerpos evtl.set

WINBASMEN
CALL CHECKCO;Koordinaten ueberpruefen
CALL KOTRANS;transformieren
CALL RAHMKO;mit Rahmen
JP MINIT;set
;

;
;WRes-Befehl
;|WRES,art
; art=0 - Balkaus(evtl. Menuebalken ausschalten)
; art=1 - PDRes(evtl. letztes PD-Window loeschen)
; art=2 - PDFlush(evtl. alle PD-Windows loeschen)
WRESBAS DEC A;1 Param?
RET NZ
CALL AVONIX;Art holen
CP 1
JP Z,PDRES;=1
JP C,BALKAUS;<1 = 0
JP PDFLUSH
;
;
;***
;
MODESET LD (SCRMODE),A;Scrmode merken
LD B,0;Windowinnen
CP 1
JR C,MODESET0
JR Z,MODESET1
;ModeSet2
LD HL,POMASK2
LD A,#FF;Mode 2-Komplementbyte
LD C,&AA;Rahmenbyte
MODESET3
LD (PMASK),HL
LD (CPLBYTE),A
LD (WINDOWB),BC
RET
MODESET0 LD HL,POMASK0
LD A,#C0
LD C,&80
JR MODESET3
MODESET1 LD HL,POMASK1
LD A,#F0
LD C,&A0
JR MODESET3
;
;
;
;Allgemeine Erlaeuterungen zu den Begriffen --
; xpos    = x-Position auf Bildschirm (0..79), meistens in B
; ypos    = y-Position auf Bildschirm (0..199), meistens in C
; Bildadr = Bildschirmadresse (&C000-&FFFF), meistens in HL
; Charadr = wie Bildadr (&C000-&FFFF), nur oberste Rasterzeile der Zeile, HL
;
;
;I. Keyboard-Pack
;
;TestKeys - Testet Tasten (+Joystick) fuer Waitmove,Nokey
; EIN  -
; AUS  NZ-A=Movecode(1=hoch..., 32=ESC, 64=TAB ), Z-A=0(keine Taste)
;
TESTKEYS PUSH BC
PUSH HL
CALL #BB24;KM Get JOY
LD A,H;Joy 0
OR A
JR NZ,TESTKEYS2;ja
LD A,L;Joy 1
OR A
JR NZ,TESTKEYS2;ja
LD HL,KEYTAB;Tastentabelle
LD B,7;max.Anz
TESTKEYS1 LD A,(HL);Tastennummer
INC HL
PUSH HL
CALL #BB1E;KM Test KEY, C veraendert !
POP HL
LD A,(HL);Richtungscode
INC HL
JR NZ,TESTKEYS2;gedrueckt
DJNZ TESTKEYS1;weiter
XOR A;nichts gedrueckt
TESTKEYS2 POP HL
POP BC
RET
;
;WaitMv - Waitmove (auf Move-Tasten warten)
; EIN  -
; AUS  A=MoveCode (1=hoch,2=runter,4=links,8=rechts,16=Feuer,32=Esc,64=Tab)
;
WAITMV PUSH HL
LD HL,ALTJOY;Adr.alter Code
LD A,(HL);alter Code
WAITMV1 LD (HL),A;Altjoy set
CALL TESTKEYS
JR Z,WAITMV1;keine Taste,A=0
CP (HL);akt.Code=alter Code?
LD (HL),A;neuen Code merken
CALL NZ,DMOVEINIT;nein,moveinit
POP HL
RET
;
;NoChar - Warten,bis keine Taste gedrueckt
; EIN  -
; AUS  - (alles erhalten)
;
NOCHAR
PUSH AF
NOCHAR1 CALL #BB1B;KM Read Key
JR C,NOCHAR1;Zeichen da - warten
NOCHAR2 CALL TESTKEYS;Tasten testen
JR NZ,NOCHAR2;eine gedrueckt
POP AF
RET
;
;
;II. Screen-Pack
;
;NLine - NextLine fuer Bildadresse HL
; EIN  HL=Bildadr
; AUS  HL=Bildadr+NL / AF veraendert
;
NLINE LD A,H
ADD A,#08
LD H,A
RET NC
AND #38
RET NZ
LD A,H
SUB #40
LD H,A
LD A,L
ADD A,#50
LD L,A
RET NC
INC H
;Uebertrag auf RA unberuecksichtigt
RET
;
;LCopy - LineCopy vervielfacht eine Rasterzeile
; EIN  HL=Bildadr, B=x-Ausd.(Breite), C=Y-Ausd.(Laenge)
; AUS  HL=neue Bildadr, AF,DE,BC veraendert
;(HL=Bildadr Ecke links oben, Lcopy macht ein Window daraus)
;(fuer Clear,Rahmen)
;
LCOPY DEC C;Laenge-1
RET Z;0 -- Ende
LD D,H;alte Badr
LD E,L;auch in DE
CALL NLINE;neue Badr (Zeile)
EX DE,HL;neue Line in DE,alte in HL
PUSH DE;neue Line sich
PUSH BC;Ausd.merken
LD C,B;Breite nach C
LD B,0
LDIR
POP BC
POP HL;wird alte Line (aus DE)
JR LCOPY
;
;Clear loescht ein Window
; EIN  HL=Bildadr, B=x-Ausd.(Breite), C=Y-Ausd.(Laenge), A=Farbzahl fuer Clear
; AUS  HL=neue Bildadr, AF,DE,BC veraendert
;(fuer Rahmen)
;
CLEAR LD D,H
LD E,L;Bildadr auch in DE sich
PUSH BC;B sich
CLEAR1
LD (HL),A;Farbzahl
INC HL
DJNZ CLEAR1
POP BC;B zurueck
EX DE,HL;Bildadr zurueck nach HL
JR LCOPY;Line vervielfachen
;
;GFast - GetFast vom Bildschirm
; EIN  HL=Bildadr, DE=Datenadr, B=x-Ausd.(Breite), C=Y-Ausd.(Laenge)
; AUS  HL=neue Bildadr,DE=neue Datenadr, AF,BC veraendert
;(fuer PDSet)
;
GFAST
PUSH HL;Bildadr sich
PUSH BC;Ausd.merken
LD C,B;Breite nach C
LD B,0
LDIR
POP BC
POP HL;alte Bildadr
CALL NLINE
DEC C
JR NZ,GFAST
RET
;
;PFast - PutFast auf den Bildschirm
; EIN  HL=Bildadr, DE=Datenadr, B=x-Ausd.(Breite), C=Y-Ausd.(Laenge)
; AUS  HL=neue Bildadr,DE=neue Datenadr, AF,BC veraendert
;(fuer PDRes)
;
PFAST
PUSH HL;Bildadr sich
PUSH BC;Ausd.merken
LD C,B;Breite nach C
LD B,0
EX DE,HL;DE=Bildadr
LDIR
EX DE,HL
POP BC
POP HL;alte Bildadr
CALL NLINE
DEC C
JR NZ,PFAST
RET
;
;
;CAdr - Charadr aus Bildpos berechnen (d.h. nur oberste Rasterzeile)
;
CADR LD A,C
AND %11111000
LD C,A
JR BADR;weiter mit Badr...
;
;BAdr - Bildadresse HL aus BC berechnen
; EIN  B=xpos, C=ypos
; AUS  HL=Bildadr / AF veraendert
;
BADR
PUSH DE;SICH
LD A,C;ypos
AND #F8
LD L,A
LD H,0
LD D,H
LD E,L
ADD HL,HL
ADD HL,HL
ADD HL,DE
ADD HL,HL;*10 /8*80
LD A,C;ypos
AND 7;MOD 8
ADD A,A
ADD A,A
ADD A,A;*8
ADD A,#C0;SCR-START
LD D,A
LD E,B;xpos
ADD HL,DE;HL=Bildadr
POP DE
RET
;
;ChPos - wandelt Bildpos in Charpos um (TextSpalte,Zeile)
; EIN  BC=Bildpos
; AUS  B=Spalte (0..18,38,79) je Mode , C=Zeile(0..25), AF veraendert
;
CHPOS SRL C
SRL C
SRL C;C div 8
LD A,(SCRMODE);Modus
CP 1
JR Z,CHPOS1;Mode1
RET NC;Mode2-fertig
SRL B;Md.0 div 4 insges.
CHPOS1 SRL B;Md.0,1
RET
;
;Inver - Invertiert A Zeichen ab Charadr HL
; EIN  HL=Charadr, A=Anzahl Zeichen (auch 0)
; AUS  AF,HL veraendert
;
INVER
OR A;Laenge=0?
RET Z
PUSH BC;SICH
PUSH DE
LD C,A;Laenge nach C
INVER1
LD D,H
LD E,L;SICH 
LD B,C
INVER2
LD A,(HL);BYTE VOM BILDSCHIRM GET
CPLBYTE EQU $+1
XOR #FF;Komplement (je nach Mode)
LD (HL),A;ZURUECK AUF BILDSCHIRM
INC HL
DJNZ INVER2
LD H,D
LD L,E
LD A,H
ADD A,8
LD H,A
JR NC,INVER1;BIS UEBERLAUF
POP DE
POP BC
RET
;
;TestChar - testet Charadr HL auf Zeichen mit 8*Bytewert A
; EIN  HL=Charadr, A=Bytewert (Soll)
; AUS  Z=1=Zeichenpos enthaelt Bytewert, AF veraendert
;
TESTCHAR CP (HL);1.Byte testen
RET NZ;nein - schon fertig
PUSH DE
LD E,A;Bytewert nach E
LD D,H;Hi-Byte sich
JR TESTCHARH
TESTCHAR1 LD A,(HL);Byte holen
CP E;=Bytewert?
JR NZ,TESTCHAR2;<>ENDE
TESTCHARH LD A,H
ADD A,8;NL
LD H,A
JR NC,TESTCHAR1;BIS ALLE LINES
XOR A;Z=1=gefunden
TESTCHAR2
LD H,D;ALTES HI-BYTE
POP DE
RET
;
;
;III. Pointer-Pack
;
;PoHiPut - Pointer-Hintergrund-Put schreibt Pointerhintergrund zurueck
; EIN  -
; AUS  AF veraendert
;
POHIPUT PUSH BC
PUSH DE
PUSH HL
LD BC,(PMPOS)
CALL BADR;aus BC Bildadr HL berechnen
EX DE,HL;und nach DE
LD HL,(PHIBU);gesicherter Hintergrund
LD BC,#0EFF;B=Anz Zeilen
POHIPUT2 LDI
LDI
DEC DE
DEC DE
EX DE,HL
CALL NLINE
EX DE,HL
DJNZ POHIPUT2
POP HL
POP DE
POP BC
RET
;
;PoMake - Pointer-Make (Hintergrund merken+Pointershape zeigen)
; EIN  -
; AUS  AF veraendert
;
POMAKE PUSH BC
PUSH DE
PUSH HL
PUSH IX
LD BC,(PMPOS)
CALL BADR;aus BC Bildadr HL berechnen
EX DE,HL;und nach DE
LD HL,(PMASK);Pointermaskenadr
LD IX,(PHIBU);PointerMove-Hintergrundbuffer
LD B,#0E;Anz Zeilen
POMAKE2 LD A,(DE)
LD (IX+0),A;Hintergr. sich
INC IX
AND (HL);And-Maske dazu
INC HL
OR (HL);Or-Maske
INC HL
LD (DE),A
INC DE
LD A,(DE);und fuer's 2.Byte
LD (IX+0),A
INC IX
AND (HL)
INC HL
OR (HL)
INC HL
LD (DE),A
DEC DE;alte Adr
EX DE,HL
CALL NLINE
EX DE,HL
DJNZ POMAKE2
POP IX
POP HL
POP DE
POP BC
RET
;
;DMoveInit - Pointer-Movewert init
; EIN  -
; AUS  - (alles erhalten)
;
DMOVEINIT PUSH AF
PUSH HL
LD HL,(MMOVE);Movewerte bei Maus
LD A,(MAUS)
OR A
JR NZ,DMOVEINIT2;Maus
LD HL,#0101;x,y-PointerMovewert bei Joystick,Cursor
DMOVEINIT2 LD (AMOVE),HL;als akt.Move
LD HL,(ZMINIT);Init-Werte
LD (ZMOVE),HL;Zaehler init
POP HL
POP AF
RET
;
;DMoveInc - Pointer-Movewert erhoehen,falls Zaehler zmove=0
; EIN  -
; AUS  AF veraendert
;
DMOVEINC LD A,(MAUS);Maus?
OR A
RET NZ;Ja,lineare Bewegung
PUSH HL
LD HL,(ZMOVE);Zaehler
DEC H;x-Zaehler-1
CALL Z,DMOVEX;xmove erhoehen
DEC L;y-Zaehler-1
CALL Z,DMOVEY;ymove erhoehen
LD (ZMOVE),HL
POP HL
RET

DMOVEX LD A,(AMOVE+1);xmove
INC A
LD (AMOVE+1),A
LD A,(ZMRELO+1);x-Reload
LD H,A;x-Zaehler neu
RET

DMOVEY LD A,(AMOVE);ymove
INC A
LD (AMOVE),A
LD A,(ZMRELO);y-Reload
LD L,A;y-Zaehler neu
RET
;
;BalkAn, BalkAus - Menuebalken (evtl.) ein-/ausschalten
; EIN  -
; AUS  AF veraendert
;(Balkaus1=Balken init)
;
BALKAN
LD A,(BALLG);Balkenlaenge<>0 (Balken an)?
OR A
RET Z;nein - fertig
PUSH HL;SICH
PUSH BC
LD BC,(BALPOS);Balkenpos
PUSH AF;Ballg sich
CALL BADR
POP AF;Ballg zur.
CALL INVER
POP BC
POP HL
RET
BALKAUS CALL BALKAN;Balken evtl. aus
BALKAUS1 XOR A
LD (BALLG),A;Balkenlg=0
RET
;
;PMove - PointerMove (Pointerhauptprg.)
; EIN  -
; AUS  CY=1=Balken select (Pos in BalPos), AF veraendert
;
PMOVE
PUSH IX
PUSH HL
PUSH DE;sich
CALL NOCHAR;BIS KEINE TASTE GEDR
LD IX,POWIN;ADR POINTERWINDOWAUSD.
CALL DMOVEINIT;MoveAbst init
CALL BALKAUS1;Balken init
PMOVE2
CALL BALKTEST;Menuebalken evtl.zeigen
CALL POMAKE;Hintergr. sich+Pointer zeigen
PMOVE3
CALL WAITMV;Movecode von Tastatur holen
LD BC,(PMPOS)
LD DE,(AMOVE);D=XMOVE/E=YMOVE
LD L,A;Movecode
RR L;0.BIT
CALL C,PMUP
RR L
CALL C,PMDN
RR L
CALL C,PMLT
RR L
CALL C,PMRT
RR L
JR C,PMFEUER
RR L
JR C,PMESC
RR L
JR C,PMTAB
;BC=evtl. neue Pos
LD HL,(PMPOS);alte Pos
OR A
SBC HL,BC
CALL Z,DMOVEINIT;keine Bwg. - Move init
JR Z,PMOVE3;keine Bewegung
PUSH BC;neue Pos merken
CALL DMOVEINC;amove evtl.erhoehen,nur af veraendert
CALL #BD19
CALL POHIPUT;Hintergrund zurueck
POP HL;aus BC
LD (PMPOS),HL;neue Pos set
JP PMOVE2

;PMTab - Toggle between Joystick/Mouse
PMTAB
LD A,(MAUS)
CPL
LD (MAUS),A
CALL DMOVEINIT
CALL NOCHAR
JR PMOVE3

;PMFeuer - Pointer-Move-Feuer
PMFEUER
LD A,(BALLG);BalkenLg=0?
OR A
JR Z,PMOVE3;Ja,weiter
CALL POHIPUT;Hintergr zurueck
SCF;OK
PMENDE
CALL NOCHAR
POP DE
POP HL
POP IX
RET

;PMEsc - Pointer-Move-Escape
PMESC
CALL POHIPUT;Hintergr zurueck
XOR A;Z/NC
JR PMENDE

;PMUp - Pointer-Move-Up
PMUP
LD A,C;YPOS
SUB E;-YMOV
RET C;UEBERL.
CP (IX+0);Pointer-Fenster oben
RET C;A<YMIN
LD C,A;SICH
RET
;PMDn - Pointer-Move-down
PMDN
LD A,C;YPOS
ADD A,E;+YMOVE
RET C;UL.
CP (IX+2);unten
JR Z,DNOK
RET NC;A>YMA
DNOK
LD C,A
RET
;PMLT - Pointer-Move-left
PMLT
LD A,B;XPOS
SUB D;-XMOV
RET C;UL.
CP (IX+1);links
RET C;A<MI
LD B,A
RET
;PMRT - Pointer-Move-right
PMRT
LD A,B;XPOS
ADD A,D;+XMOV
RET C;UL.
CP (IX+3);rechts
JR Z,RTOK
RET NC;A>XMA
RTOK
LD B,A
RET
;
;MenTest - Testet, ob Pointer im Menuewindow
; EIN  BC=Pointerpos, (IX+4,5,6,7)=Menuewindow
; AUS  CY=1=nicht im Menuewindow, AF veraendert
;(fuer BalkTest)
;
MENTEST LD A,C;ypos
SUB (IX+4);-MenueWindow oben
RET C
LD A,B;xpos
SUB (IX+5);links
RET C
LD A,(IX+6);unten
SUB C;-ypos
RET C
LD A,(IX+7);rechts
SUB B
RET
;
;Anfang eines Windows finden (links)
; EIN  B=akt.xpos, HL=Charadr, E=Windowbyte
; AUS  Z=1=Anfang gefunden (B,HL angepasst), AF veraendert
;(fuer BalkTest)
;
AFIND LD A,B;xpos
SUB (IX+5);Menuewin. links
;RET C;XPO<XLI NZ (gibt's nicht)
INC A
PUSH DE;merken
LD D,A;max.Anz Schritte
AFIN1 LD A,E;TestByte
CALL TESTCHAR;POSITION=A?
JR Z,AFIND2;ja,Suchzeichen links gefunden
DEC HL;LINKS WEITERSUCHEN
DEC B;xpos-1
DEC D;Schritte-1
JR NZ,AFIN1
INC D;NZ
AFIND2 POP DE
RET
;
;Ende im Menuewindow finden (rechts)
; EIN  BC=Menpos, HL=Charadr dazu, E=Windowbyte
; AUS  A=Balkenlaenge
;(fuer BalkTest)
;
EFIND LD A,(IX+7);Menuewindow rechts
SUB B
INC A
PUSH BC;xpos,ypos sich
PUSH HL;Charadr sich
LD C,A;max.Anz
EFIND1 LD A,E;TestByte
CALL TESTCHAR;Rahmenbyte gefunden?
JR Z,EFIND2;ja,fertig
INC HL;Charadr+1
INC B;Charpos+1
DEC C;Schritte-1
JR NZ,EFIND1;noch weiter
EFIND2 LD A,B;end-xpos
POP HL;AnfangsCharadr
POP BC;xpos,ypos zurueck
SUB B;end-xpos minus anf-xpos
DEC A;Korrektur
RET
;
;
;BalkTest - auf MenueBalken testen+evtl. zeigen
; EIN  -
; AUS  veraendert ...
;
BALKTEST
LD BC,(PMPOS);Pointerpos
CALL MENTEST;Pointer im Menuewindow?
JR C,BALKTEST2;nein,Abbruch
CALL CADR;aus BC Charadr HL berechnen
;(entspricht nach BADR  LD A,H AND 7 OR #C0 LD H,A)
LD DE,(WINDOWB);Rahmen+Innen
CALL AFIND;Anfang vom Window finden (linken Rand)
JR NZ,BALKTEST2;kein Anfang - Abbruch
INC HL
INC B;xpos+1
LD A,D;Windowinnen
CALL TESTCHAR;AN POSIT VORHANDEN?
JR NZ,BALKTEST2;NEIN ENDE
INC HL
INC B
LD A,D;Windowinnen
CALL TESTCHAR;HIER NOCHMAL?
JR Z,BALKTEST2;JA AUCH ENDE
CALL EFIND;Ende vom Window finden, A=Lg
LD E,A;merk
LD A,(BALLG);alte Balkenlaenge
OR A;0?
LD A,E;neue Laenge
JR Z,BALKTEST1;ALTE Lg=0--NUR BalkAn
LD HL,(BALPOS);alte Pos
OR A
SBC HL,BC;-neue Pos
RET Z;gleich-Balken schon da
PUSH AF;Lg
CALL BALKAUS;alten Balken loeschen
POP AF
BALKTEST1
LD (BALLG),A;Balkenlaenge setzen
LD (BALPOS),BC;Balkenposition setzen
JP BALKAN
BALKTEST2
JP BALKAUS
;
;
; IV. WindowPack
;
;Rahmen - Zeichnet einen Windowrahmen
; EIN  B=xpos,C=ypos (links oben),  D=x-Ausd.,E=Y-Ausdehnung
; AUS  AF,BC,DE,HL veraendert
;(Angabe der Groesse einschliesslich Rahmen !)
;
RAHMEN
CALL BADR;aus BC Bildadr HL berechnen
LD A,E
SUB 8;-Rahmenbreite oben+unten
LD E,A
LD B,D
LD C,E;Ausdehnung nach BC
LD DE,(WINDOWB);WINDOWBYTE+INNEN
CALL RAHMOBUN;Rahmen oben
CALL NLINE;NL
LD A,B;B=Breite sich
PUSH HL;Badr sich
LD (HL),E;Rahmen links
INC HL
DEC B
DEC B;Breite ohne Rahmen
RAHM1
LD (HL),D;Innenraum
INC HL
DJNZ RAHM1
LD (HL),E;Rahmen rechts
POP HL;Badr zurueck
LD B,A;Breite zurueck
PUSH BC
PUSH DE
CALL LCOPY;Linie vervielfachen
POP DE
POP BC
CALL NLINE;NL
;und Rahmen unten ...
RAHMOBUN PUSH BC;Ausd.merken
PUSH DE;Windowbytes merken
LD A,E;Windowrahmen
LD C,4;4 Zeilen
CALL CLEAR;mit A loeschen
POP DE
POP BC;Ausd.zurueck
RET
;
;RahmKo - wandeln Windowkoordinanten in Koordinaten mit Rahmen um
; EIN  B=linke Spalte(2..77), D=rechte Spalte(2..77)
;      C=oberste Zeile (8..191), E=unterste Zeile(8..191)
; AUS  B,D,C,E umgewandelt (BC pos, DE ausd.), AF veraendert
;
RAHMKO DEC B
DEC B;linke Spalte-2 wg. Rahmen links(+Freizone)
INC D
INC D;rechte Spalte+2 wg. Rahmen rechts(+Freizone)
LD A,D;rechte Spalte
SUB B;-linke Spalte
LD D,A;ergibt x-Ausdehnung
LD A,C
SUB 8;oberste Zeile-8 wg. Rahmen oben(+Freizone)
LD C,A
LD A,E
ADD 8;unterste Zeile+8 wg. Rahmen unten(+Freizone)
SUB C;-oberste Zeile
LD E,A;ergibt y-Ausdehnung
RET
;
;Window - zeichet ein Window (Rahmen)
; EIN  B=linke Spalte(2..77), D=rechte Spalte(2..77)
;      C=oberste Zeile (8..191), E=unterste Zeile(8..191)
; AUS  AF,BC,DE,HL veraendert
;(Angabe der Groesse ohne Rahmen!!)
;
WINDOW CALL RAHMKO;in Rahmenkordinaten umwandeln
JP RAHMEN;Rahmen(+Window) zeichen
;
;KoTrans - Koordinatentransformation
; EIN  B=linke Spalte(2..18,38,77), D=rechte Spalte(2..18,38,77) je Mode
;      C=oberste Zeile (1..24), E=unterste Zeile(1..24)
; AUS  B=linke Spalte(2..77), D=rechte Spalte(2..77)
;      C=oberste Zeile (8..191), E=unterste Zeile(8..191)
;      AF veraendert
;
KOTRANS INC E;untere Zeile+1(wg.Ausd.) (damit unterer Rahmen im Window)
LD A,C
ADD A,A
ADD A,A
ADD A,A;*8
LD C,A
LD A,E
ADD A,A
ADD A,A
ADD A,A;*8
LD E,A
INC D;rechte Spalte+1(wg.Ausd.) (damit linke+rechte Spalte im Window)
LD A,(SCRMODE);Bildschirmmodus
CP 1
JR Z,KOTRANS1;Md.1
RET NC;Md.2 - fertig
SLA B;Md.0 - insges. *4
SLA D
KOTRANS1 SLA B;Md.0,1
SLA D
RET
;

;CheckCo - ueberprueft Koordinaten und korrigiert gegebenfalls
; EIN  B=linke Spalte(0.., , 79), D=rechte Spalte(0.., , 79) je Mode
;      C=oberste Zeile (0..24), E=unterste Zeile(0..24)
; AUS  B=linke Spalte(2..18,38,77), D=rechte Spalte(2..18,38,77) je Mode
;      C=oberste Zeile (1..24), E=unterste Zeile(1..24)
;      AF veranedert
;
CHECKCO PUSH HL;sich
LD H,D
LD L,B
CALL CHECKMI
LD D,H
LD B,L
LD H,E
LD L,C
CALL CHECKMI
LD E,H
LD C,L
LD HL,#1701;Zeile von 1..23
LD A,C
CALL CHECK1
LD C,A
LD A,E
CALL CHECK1
LD E,A
LD HL,#4d02;Spalte von 2..77 (mode 2)
LD A,(SCRMODE)
CP 1
JR Z,CHECKMD1
JR C,CHECKMD0
;Md2.
CHECKMD LD A,B
CALL CHECK1
LD B,A
LD A,D
CALL CHECK1
LD D,A
POP HL
RET

CHECKMD1 LD H,38;max.Spalte Mode 1
DEC L;auch 1
JR CHECKMD

CHECKMD0 LD H,18;max.Spalte Mode 0
DEC L;auch 1
JR CHECKMD

CHECKMI LD A,H;soll-max
CP L
RET NC;ok,H>=L
LD H,L;max
LD L,A;min
RET

CHECK1 CP L;min-Wert
JR NC,CHECK1OK
LD A,L;sonst min-Wert nehmen
CHECK1OK CP H
RET C;< - ok
RET Z;= - ok
LD A,H;sonst max-Wert nehmen
RET
;

;
;TWindow - Text-Window (normal oder PD, je nach HL)
; EIN  B=linke Spalte(0.., , 79), D=rechte Spalte(0.., , 79) je Mode
;      C=oberste Zeile (0..24), E=unterste Zeile(0..24)
;      HL=Windowroutinenadr(WINDOW oder PDSET)
; AUS  AF,BC,DE,HL veraendert
;
TWINDOW
CALL CHECKCO;Koordinaten check
PUSH BC
PUSH DE
CALL KOTRANS
CALL #001E;jp (hl)
POP DE
POP HL;aus BC
;H,D=Spaltengrenzen, L,E=Zeilengrenzen
JP #BB66;Txt Win Enable
;
;Mult8 - 8-Bit-Multiplikation HL=A*E
; EIN  A=Multiplikant, E=Multiplikator
; AUS  HL=Produkt, AF veraendert
;
MULT8
LD HL,0
PUSH BC;SICH
LD C,D;D SICH
LD D,H;0
LD B,8;8 BITS
MULT81
ADD HL,HL;SHIFT LEFT 1 BIT
RLA;MULTIPLIKANT 1 BIT
JR NC,MULT82
ADD HL,DE
MULT82
DJNZ MULT81
LD D,C
POP BC
RET
;
;
;MInit - Menuewindow init
; EIN  B=xpos,C=ypos (links oben),  D=x-Ausd.,E=Y-Ausdehnung
; AUS  AF veraendert
;
MINIT
LD (POWIN+4),BC;Menuewin.oben.links
PUSH HL
LD A,C;ypos
ADD A,E;+yaus
LD L,A;unten
LD A,B;xpos
ADD A,D;+xaus
LD H,A;rechts
DEC H
DEC H;ohne rechten Windowrahmen
LD (POWIN+6),HL;Menuewin.unten,rechts
POP HL
RET
;
;PMInit - PointerPosInit
; EIN  B=xpos,C=ypos
; AUS  AF veraendert
;
PMINIT LD A,(MAUS)
OR A
RET NZ;Maus,fertig
LD A,B;xpos
LD (PMPOS+1),A;ALS XPOS
LD A,C;ypos
ADD A,8;auf 1.Menuepunkt
LD (PMPOS),A
RET
;
SICHLG EQU 17;Laenge Windowdaten fuer PDSet,PDRes
;
;PDSet - PullDownWindow set
; EIN  B=linke Spalte(2..77), D=rechte Spalte(2..77)
;      C=oberste Zeile (8..191), E=unterste Zeile(8..191)
; AUS  AF,BC,DE,HL veraendert
;(Angabe der Groesse ohne Rahmen!!)
;
PDSET CALL RAHMKO;in Koordinaten mit Rahmen umwandeln
LD (PDPOS),BC
LD (PDAUS),DE;merken
PUSH DE;Ausdehnung merken
LD A,D;x-Ausd.
CALL MULT8;HL=A*E
LD DE,(PDZEIG);akt.PDWindowZeiger
ADD HL,DE;Windowlaenge dazu
LD DE,SICHLG;Laenge Windowdaten(auch PDPos,PDAus,PDZeig)
ADD HL,DE;ergibt Gesamtlaenge
EX DE,HL;nach DE
LD HL,(PDEND);max.Ende PD-Windowbuffer
OR A
SBC HL,DE;PDEND< ?
POP DE;Ausd.
JR C,PDSET2;Error - kein Platz
PUSH BC;Position merken
CALL BADR;Bildadr berechnen
LD B,D
LD C,E;Ausd.nach BC
PUSH BC;merken
LD DE,(PDZEIG);akt.PDWindowZeiger
CALL GFAST;Windowhintergrund get (merken)
;Endadr in DE
LD HL,POWIN;Sicherungsstart
LD BC,SICHLG;Laenge
LDIR;sichern
LD (PDZEIG),DE;akt.PDSichadr(=Ende+1)
POP DE;Ausdehnung
POP BC;Posit
CALL MINIT;Menuefenster definieren
CALL PMINIT;evtl.Pointerpos set
JP RAHMEN;Windowrahmen
;nicht genug Speicher
PDSET2
LD A,(SHOWFLG);Rahmen-zeigen ?
OR A
RET Z;nein
JP RAHMEN;(normales Window)
;
;
;PDRes - PDRestore - (letztes) PD-Window restore
; EIN  -
; AUS  NZ=Window gefunden, AF,BC,DE,HL vaeaendert
;
PDRES
LD HL,(PDANF);PD-BufferAnfang
LD DE,(PDZEIG);akt.PDZeiger
OR A
SBC HL,DE;gleich?
JR Z,PDRES2;ja,kein PD-Window da
EX DE,HL;HL=PDZeig
LD DE,POWIN+SICHLG-1;Ende gesicherte Daten
LD BC,SICHLG;Laenge
DEC HL;auf letztes Byte
LDDR;zurueckkopieren(auch PDPos,PDAus,PDZeig)
LD BC,(PDPOS)
CALL BADR
LD BC,(PDAUS)
LD DE,(PDZEIG);alter WindowAnf(jetztiges Ende)
CALL PFAST;Hintergrund zurueckkopieren
CALL BALKAUS;evtl.Balken aus
XOR A
INC A;A=1 NZ Window gefunden
PDRES2
RET
;

;
PDFLUSH
CALL PDRES;WINDOW WEG
JR NZ,PDFLUSH;ALLE WEG
RET
;

;
;IX. Tabellen

;Tastenueberprueftabelle  Tastencode,Richtungscode(falls gedrueckt)
KEYTAB DEFB 0,1, 2,2, 8,4, 1,8, 9,16, 66,32, 68,64

;Pointer-Masken  Mode 0,1,2
;And-Maske,Or-Maske,And-...
POMASK0
DEFB #BF,#80,#FF,#00,#FF,#C0,#7F,#00,#FF,#C0,#7F,#00,#FF,#80
DEFB #BF,#80,#FF,#80,#BF,#80,#BF,#80,#FF,#C0,#BF,#80,#7F,#40
DEFB #BF,#80,#7F,#40,#FF,#C0,#BF,#80,#7F,#40,#BF,#80,#BF,#00
DEFB #BF,#80,#BF,#00,#FF,#C0,#FF,#00,#7F,#40,#FF,#00,#7F,#40

POMASK1
DEFB #FF,#E0,#FF,#00,#9F,#90,#FF,#00,#AF,#A0,#FF,#80,#BF,#B0
DEFB #7F,#40,#BF,#B0,#BF,#A0,#BF,#B0,#DF,#D0,#BF,#B0,#DF,#D0
DEFB #BF,#B0,#EF,#E0,#BF,#B0,#EF,#E0,#BF,#B0,#BF,#A0,#EF,#00
DEFB #BF,#B0,#EF,#00,#DF,#D0,#FF,#00,#5F,#50,#FF,#00,#7F,#70

POMASK2
DEFB #AF,#A8,#FF,#00,#BB,#BA,#FF,#00,#BE,#BE,#FF,#80,#BF,#BF
DEFB #BF,#A0,#BF,#BF,#EF,#E8,#BF,#BF,#FB,#FA,#BF,#BF,#FE,#FE
DEFB #BF,#BF,#F7,#F4,#BF,#BF,#EF,#E8,#B5,#B5,#77,#74,#D7,#00
DEFB #BB,#BA,#FF,#00,#DD,#5D,#FF,#00,#EE,#2E,#FF,#00,#F7,#17
;
;Ende
;
;dynamische Variablen
;
KERBYTES EQU $;DS 4; 4 Bytes fuer RSX-Verkettung
SCRMODE EQU KERBYTES+4;DB 0 (Screen-Mode 0,1,2)
WINDOWB EQU SCRMODE+1;DB 0,0 (Farbzahl Rahmen/Innenraum d.Windows)
AMOVE EQU WINDOWB+2;DB 0,0 (akt.Move y,x)
ZMOVE EQU AMOVE+2;DB 0,0 (Movezaehler y,x)
ALTJOY EQU ZMOVE+2;DB 0 (alter Joystickwert)
PMASK EQU ALTJOY+1;DW 0;Adr Pointermaske (je nach Mode)
PHIBU EQU PMASK+2;DW 0;Adr Pointer-Hintergrundbuffer (auf 28 Bytes)
PMPOS EQU PHIBU+2;DW 0 (PointerMovePOS y,x)
;folgende 17 Bytes werden beim PD-Window gesichert ...
POWIN EQU PMPOS+2
;DS 4 (Pointerwindow oben,links,unten(<=186),rechts(<=78))
;DS 4 (Menuewindow oben,links,unten,rechts(<=79))
BALPOS EQU POWIN+8;DB 0,0 (Balkenposition y,x)
BALLG EQU BALPOS+2;DB 0 (Balkenlaenge)
PDPOS EQU BALLG+1;DB 0,0 (PD-Winpos) fuer PDSet,PDRes
PDAUS EQU PDPOS+2;DB 0,0 (PD-Win.Ausdehnung) fuer PDset,PDRes
PDZEIG EQU PDAUS+2;DW 0 (akt.PD-Bufferpos)
;
PDANF EQU PDZEIG+2;DW 0 (PD-Windowbufferstart)
PDEND EQU PDANF+2;DW 0 (PD-Windowbufferende)
HIBUF EQU PDEND+2;DS 28 (28-Bytes Hintergrundbuffer)
list
VAREND EQU HIBUF+28
end
;
