home *** CD-ROM | disk | FTP | other *** search
- *
- * 6569.asm - VIC-Emulation
- *
- * Copyright (C) 1994-1995 by Christian Bauer
- *
-
- *
- * Anmerkungen:
- * ------------
- *
- * Funktionsweise/Periodic:
- * - Die VIC-Emulation arbeitet zeilenweise. Pro (simulierter)
- * C64-Rasterzeile wird vom 6510-Task die Routine Periodic6569
- * aufgerufen, die eine Pixelzeile der Grafik anhand der aktuellen
- * Einstellungen in den VIC-Registern aufbaut. Dadurch können
- * Rastereffekte sehr gut emuliert werden.
- * - Die Emulation setzt eine 8-Bit-Chunky-Bitmap voraus und schreibt
- * ihre Grafikdaten direkt dort hinein
- * - Bei der Darstellung über die Amiga-Chips wird direkt in eine
- * Chunky-Bitmap geschrieben, die beim VIC-VBlank in das planare Format
- * konvertiert wird (mit c2p4), bei EGS/Picasso werden die Grafikdaten
- * für eine Zeile in einen Puffer geschrieben, der am Ende der Zeile
- * in den Grafikspeicher der Karte übertragen wird
- * - Für eine sauberere Darstellung verwendet die Emulation Double
- * Buffering. Es wird jeweils in eine unsichtbare Bitmap gezeichnet
- * und bei einem VIC-VBlank werden die Puffer gewechselt.
- * - Die Farbpalette besteht aus den 16 C64-Farben, 16mal wiederholt.
- * Dadurch spart man sich das Ausmaskieren der unteren 4 Bit bei den
- * VIC-Farbcodes. Allerdings muß dieses bei der Chunky->Planar-
- * Konvertierung für die Amiga-Chips erfolgen (der Algorithmus
- * setzt voraus, daß die oberen Nibbles Null sind).
- * - Die Auswahl der 5 verschiedenen Darstellungsmodi (plus 3 ungültige,
- * die einen schwarzen Bildschirm erzeugen) geschieht über den
- * Zeiger DisplayProc, der auf die entsprechende Routine (z.B. TextStd,
- * BitMapMulti etc.) zeigt und der bei einem Schreibzugriff auf eines
- * der beiden Kontrollregister CTRL1/CTRL2 neu gesetzt wird
- *
- * 6510-Zyklenzähler
- * - In jeder Rasterzeile wird der Zyklenzähler für die CPU neu gesetzt,
- * und zwar unterschiedlich je nachdem, ob eine Bad Line stattfand
- * oder nicht
- * - Für jedes dargestellte Sprite werden nochmal je 2 Zyklen abgezogen
- *
- * Bad Lines:
- * - Eine Bad Line ist dann, wenn $30 <= RASTER <= $f7 und
- * die unteren drei Bits von RASTER mit den unteren drei Bits von
- * Reg. $11 (Y-Scroll) übereinstimmen
- * - In einer Bad Line werden 40 Bytes aus Videomatrix und Farb-RAM geholt
- *
- * Rasterzähler RC/Grafikdarstellung:
- * - Der RC wird in jeder Bad Line auf Null gesetzt, gleichzeitig wird
- * die Darstellung der Grafik angeschaltet (DISPLAYOFF wird gelöscht)
- * - Am Ende einer Rasterzeile wird der RC um 1 erhöht, es sei denn,
- * er steht auf 7. In diesem Fall wird die Darstellung ausgeschaltet.
- * - Ist DISPLAYOFF gesetzt, wird in der Textspalte $3fff dargestellt,
- * ansonsten Text oder Bitmapgrafik
- * - Deshalb wird im oberen/unteren Rahmen immer $3fff dargestellt, weil
- * es dort keine Bad Lines gibt und der RC nie zurückgesetzt wird
- *
- * Videomatrixzähler VC:
- * - Es gibt zwei Register, VCBASE und VCCOUNT. Zum Zugriff auf die
- * Grafikdaten wird VCCOUNT benutzt.
- * - Beim VBlank wird VCBASE auf Null gesetzt
- * - Zu Beginn jeder Zeile wird VCCOUNT mit dem Wert aus VCBASE geladen
- * - Wenn DISPLAYOFF gelöscht ist und Grafik dargestellt wird, wird
- * VCCOUNT um 40 erhöht (symbolisch für die 40 Zugriffe des VIC)
- * - Wenn die Darstellung abgeschaltet wird, weil RC=7 ist (am Ende
- * einer Zeile) wird VCBASE mit dem Wert aus VCCOUNT geladen
- *
- * Spritedatenzähler MCx/Spritedarstellung:
- * - Da die Spritedaten beim VIC am Ende einer Rasterzeile geholt werden
- * und daher die Y-Positionen der Sprites eins niedriger als die
- * Rasterzeilennummern sind, werden die Spritedatenzähler in der
- * Emulation am Ende einer Rasterzeile gehandhabt (nachdem die Sprites
- * gezeichnet wurden)
- * - Wenn ein Sprite eingeschaltet ist und die Y-Koordinate gleich den
- * unteren 8 Bit von RASTER ist, wird der Datenzähler auf Null gesetzt
- * und die Darstellung des Sprite eingeschaltet (Bit in SPRITEON).
- * Jede folgende Rasterzeile wird der Zähler um 3 erhöht, solange er
- * kleiner als 60 ist. Erreicht er 60, wird die Darstellung des Sprite
- * ausgeschaltet. Wenn das Sprite Y-expandiert ist, wird der Zähler nur
- * in den Zeilen erhöht, in denen die unteren Bits von Y-Koordinate und
- * Zeilennummer gleich sind.
- * - Der Puffer GfxCollBuf wird beim Malen der Grafikdaten mit Flags
- * gefüllt, ob das zugehörige Pixel ein Vorder- oder Hintergrundpixel
- * ist. Dieser Puffer wird für die Sprite-Grafik-Kollisionserkennung
- * und für das Zeichnen von Hintergrundsprites benutzt.
- *
- * X-Scroll>0 und 40 Spalten:
- * - Wenn der X-Scroll>0 und die 40-Spalten-Darstellung eingeschaltet
- * ist, hängt das, was am linken Bildrand dargestellt wird, vom
- * aktuellen Grafikmodus ab
- * - Im Standard-Text-, Multicolor-Text- und Multicolor-Bitmap-Modus wird
- * dort die Hintergrundfarbe aus Reg.$21 dargestellt
- * - Im Standard-Bitmap- und ECM-Text-Modus wird die Hintergrundfarbe
- * der letzten 8 Pixel der vorherigen Zeile dargestellt
- *
- * Inkompatibilitäten:
- * - Effekte, die durch die Änderung von VIC-Registern innerhalb einer
- * Rasterzeile erreicht werden, können nicht emuliert werden
- * - Sprite-Kollisionen werden nur innerhalb des sichtbaren Bereiches
- * erkannt, Kollisionen mit $3fff werden gar nicht erkannt
- * - X-expandierte Sprites mit X-Koordinaten >=$140 werden nicht angezeigt.
- * Genaugenommen sollte ein Sprite nur dann unsichtbar sein, wenn die
- * X-Koordinate zwischen $1f8 und $1ff liegt.
- * - In den Bitmap-Darstellungen ab den Adressen $0000 und $8000 sollte
- * eigentlich ab $1000/$9000 das Char-ROM sichtbar sein. Aus
- * Geschwindigkeitsgründen wird in der Emulation das RAM darunter
- * dargestellt. Dies sollte keine Rolle spielen, da diese Bitmap-Seiten
- * aus dem genannten Grund von keinem Programm komplett verwendet werden.
- * - Der IRQ wird bei jedem Schreibzugriff in das Flag-Register gelöscht.
- * Das ist ein Hack für die RMW-Befehle des 6510, die zuerst den
- * Originalwert schreiben.
- *
-
- MACHINE 68020
-
- INCLUDE "exec/types.i"
- INCLUDE "exec/macros.i"
- INCLUDE "exec/memory.i"
- INCLUDE "exec/libraries.i"
- INCLUDE "exec/ports.i"
- INCLUDE "intuition/intuition.i"
- INCLUDE "graphics/displayinfo.i"
- INCLUDE "egs/egs.i"
- INCLUDE "cybergraphics/cybergraphics.i"
- INCLUDE "devices/inputevent.i"
-
- XREF _SysBase ;Main.asm
- XREF _GfxBase
- XREF _IntuitionBase
- XREF _EGSBase
- XREF _VilIntuiBase
- XREF _CyberGfxBase
-
- XREF TheRAM ;6510.asm
- XREF TheChar
- XREF TheColor
- XREF IntIsVICIRQ
- XREF CyclesLeft
- XREF CPUTask
-
- XREF CountTODs ;6526.asm
- XREF Periodic6526
- XREF KeyPressed
-
- XREF _c2p4 ;c2p4.asm
- XREF Initc2p4
- XREF Exitc2p4
-
- XDEF OpenGraphics
- XDEF CloseGraphics
- XDEF AmigaToFront
- XDEF EmulToFront
- XDEF WaitForClick
- XDEF ChangedVA
- XDEF Init6569
- XDEF Exit6569
- XDEF ReadFrom6569
- XDEF WriteTo6569
- XDEF Periodic6569
-
- XDEF DisplayID ;Prefs
- XDEF ScreenType
- XDEF NormalCycles
- XDEF BadLineCycles
- XDEF Collisions
- XDEF Overscan
- XDEF SkipLatch
-
- SECTION "CODE",CODE
-
-
- **
- ** Definitionen
- **
-
- ; VIC-Register
- M0Y = $01 ;Y-Position von Sprite 0
- M1Y = $03 ;Y-Position von Sprite 1
- M2Y = $05 ;Y-Position von Sprite 2
- M3Y = $07 ;Y-Position von Sprite 3
- M4Y = $09 ;Y-Position von Sprite 4
- M5Y = $0b ;Y-Position von Sprite 5
- M6Y = $0d ;Y-Position von Sprite 6
- M7Y = $0f ;Y-Position von Sprite 7
- MX8 = $10 ;Höchste Bits der Sprite X-Positionen
- CTRL1 = $11 ;Steuerreg. 1
- RASTER = $12 ;Rasterzähler
- SPREN = $15 ;Sprite eingeschaltet
- CTRL2 = $16 ;Steuerreg. 2
- MYE = $17 ;Sprite Y-Expansion
- VBASE = $18 ;Basisadressen
- IRQFLAG = $19 ;Interruptreg.
- IRQMASK = $1a
- MDP = $1b ;Sprite Priorität
- MMC = $1c ;Sprite Multicolor
- MXE = $1d ;Sprite X-Expansion
- CLXSPR = $1e ;Kollisionsreg.
- CLXBGR = $1f
- EC = $20 ;Rahmenfarbe
- B0C = $21 ;Hintergrundfarbe
-
- ; Zusätzliche Register
- DISPLAYOFF = $2f ;Flag: $3fff wird dargestellt
- IRQRASTER = $30 ;Rasterzeile, bei der ein IRQ ausgelöst wird (Wort)
- XSCROLL = $32 ;X-Scroll-Wert (Wort)
- YSCROLL = $34 ;Y-Scroll-Wert (Wort)
- DXSTART = $36 ;Aktuelle Werte des Randbereichs
- DXSTOP = $38
- DYSTART = $3a
- DYSTOP = $3c
- RC = $3e ;Rasterzähler RC
- MATRIXBASE = $40 ;Videomatrix-Basis (Amiga-Adresse)
- CHARBASE = $44 ;Zeichengenerator-Basis (Amiga-Adresse)
- BITMAPBASE = $48 ;Bitmap-Basis (Amiga-Adresse)
- CURRENTA5 = $4c ;Augenblicklicher Zeiger im Bildschirmspeicher
- ;Speicher für a5 zwischen Aufrufen von Periodic6569
- CURRENTRASTER = $50 ;Augenblickliche Rasterzeile
- ;Speicher für d7 zwischen Aufrufen von Periodic6569
- LASTBKGD = $52 ;Letzte dargestellte Hintergrundfarbe
- SPRITEON = $53 ;Sprite wird dargestellt, pro Sprite ein Bit
- BORDERON = $54 ;Flag: Oberer/unterer Rahmen wird dargestellt
- IS38COL = $55 ;Flag: 38 Spalten
- SCREENOFF = $56 ;Flag: Bildschirm ist abgeschaltet, nur Rahmen darstellen
- ;Bei jedem VBlank wird Bit 4 in $D011 getestet und
- ; dieses Flag entsprechend gesetzt
- SKIPFRAME = $57 ;Flag: Dieses Frame überspringen, nichts zeichnen
- MC0 = $58 ;Spritedatenzähler 0
- MC1 = $5a
- MC2 = $5c
- MC3 = $5e
- MC4 = $60
- MC5 = $62
- MC6 = $64
- MC7 = $66 ;Spritedatenzähler 7
- VCBASE = $68 ;VC-Zwischenspeicher
- VCCOUNT = $6a ;VC-Zähler
- BORDERLONG = $6c ;Vorberechnete Farbwerte
- BACK0LONG = $70
- SPRX0 = $74 ;16-Bit Sprite-X-Koordinaten
- SPRX1 = $76
- SPRX2 = $78
- SPRX3 = $7a
- SPRX4 = $7c
- SPRX5 = $7e
- SPRX6 = $80
- SPRX7 = $82
- VICRegLength = $84
-
- ; Anzahl Rasterzeilen
- TotalRasters = $138
-
- ; Textfenster-Koordinaten (Stop-Werte sind immer eins mehr)
- Row25YStart = $33
- Row25YStop = $fb
- Row24YStart = $37
- Row24YStop = $f7
-
- Col40XStart = $18
- Col40XStop = $158
- Col38XStart = $1f
- Col38XStop = $14f
-
- ; Erste und letzte mögliche Zeile für Bad Lines
- FirstDMALine = $30
- LastDMALine = $f7
-
- ; Erste und letzte dargestellte Zeile
- FirstDispLine = $10
- LastDispLine = $11f ;eigentlich $12b
-
- ; Größe der Anzeige
- DisplayX = $170
- DisplayY = LastDispLine-FirstDispLine+1
-
- ; ScreenTypes
- STYP_EGS = 0
- STYP_PICASSO = 1
- STYP_AMIGA = 2
- STYP_AMIGAMONO = 3
- STYP_CYBER = 4
-
- ; EGS
- E_OpenScreen = -30
- E_CloseScreen = -36
- E_ScreenToFront = -60
- E_ScreenToBack = -66
- E_ActivateEGSScreen = -72
- E_ActivateAmigaScreen = -78
- E_SetRGB8 = -84
- E_DisposeBitMap = -132
- E_FlipMap = -168
- E_AllocBitMap = -198
-
- ; Village
- OpenVillageScreen = -30
- CloseVillageScreen = -36
- LockVillageScreen = -42
- UnLockVillageScreen = -48
- OpenVillageScreenTagList = -114
- VillageGetBufAddr = -126
- VillageSetDisplayBuf = -132
-
- TAVIS_FIRSTITEM = TAG_USER+4711
- TAVIS_DOUBLE_BUFFER = TAVIS_FIRSTITEM+40
- TAVIS_DM_STRUCT = TAVIS_FIRSTITEM+41
-
- ; CyberGfx
- IsCyberModeID = -54
- GetCyberMapAttr = -96
- DoCDrawMethod = -156
-
- *
- * Makros
- *
-
- ; Aus einer VIC-16-Bit-Adresse die entsprechende Amiga-Adresse berechnen
- ; -> d0.w: 16-Bit-Adresse
- ; <- a0.l: 32-Bit-Adresse
- GetPhysical MACRO
- or.w CiaVABase(pc),d0 ;VA14/15 dazunehmen
- move.w d0,d1
- and.w #$7000,d1
- cmp.w #$1000,d1
- beq \@1$
- move.l TheRAM(pc),a0
- moveq #0,d1
- move.w d0,d1
- add.l d1,a0
- bra \@2$
- \@1$ and.w #$0fff,d0 ;$1000-$1fff, $9000-$9fff: Char-ROM
- move.l TheChar(pc),a0
- add.w d0,a0
- \@2$
- ENDM
-
- ; Sprite darstellen
- DoSprite MACRO ;Nummer
- btst #\1,SPRITEON(a4) ;Wird das Sprite dargestellt?
- beq \@1$
-
- move.l MATRIXBASE(a4),a0
- moveq #0,d0
- move.b $03f8+\1(a0),d0 ;Datenzeiger
- lsl.w #6,d0 ;*64
- add.w MC\1(a4),d0 ;MC dazunehmen
- GetPhysical
- move.l (a0),d0 ;d0: Spritedaten
-
- move.w SPRX\1(a4),d1 ;d1: X-Koordinate
- move.l a5,a1
- add.w d1,a1 ;a1: Ziel im Bildschirmspeicher
- lea SprCollBuf,a2
- add.w d1,a2 ;a2: Ziel im Kollisionspuffer
- lea GfxCollBuf,a3
- add.w d1,a3 ;a3: Zeiger auf Grafik-Kollisionspuffer
-
- move.b $27+\1(a4),d2 ;d2: Spritefarbe
-
- move.b #1<<\1,d7 ;d7: Sprite-Bit
- jsr ([Sprite\1Proc])
- \@1$
- ENDM
-
-
- **
- ** Bildschirm öffnen
- ** Rückgabe: d0=0 Alles OK
- ** d0=1 Fehler beim Screen-Öffnen
- ** d0=2 Kein Speicher
- ** d0=3 Kein EGS
- ** d0=4 Kein VilIntuiSup
- ** d0=5 Probleme mit DisplayID
- ** d0=6 Screen zu klein (min. 384×272)
- ** d0=7 Kein CyberGfx
- ** d0=8 Kein CyberGfx-Modus ausgewählt
- **
-
- ; Name des ScreenMode holen
- OpenGraphics move.l _GfxBase,a6
- sub.l a0,a0
- lea ModeNameBuf,a1
- moveq #nif_SIZEOF,d0
- move.l #DTAG_NAME,d1
- move.l DisplayID,d2
- JSRLIB GetDisplayInfoData
- tst.l d0
- beq NoDisplayID
-
- ; Register vorbereiten
- lea Registers,a0
- move.w #7,RC(a0)
- move.w #-1,CURRENTRASTER(a0)
- move.l TheRAM,MATRIXBASE(a0)
- move.l TheRAM,CHARBASE(a0)
- move.l TheRAM,BITMAPBASE(a0)
- clr.w CiaVABase
- move.w #63,MC0(a0)
- move.w #63,MC1(a0)
- move.w #63,MC2(a0)
- move.w #63,MC3(a0)
- move.w #63,MC4(a0)
- move.w #63,MC5(a0)
- move.w #63,MC6(a0)
- move.w #63,MC7(a0)
-
- bsr SetDispProc
- bsr SetSpriteProcs
-
- ; Screen-Typ auswerten (Amiga)
- cmp.w #STYP_AMIGA,ScreenType
- beq OpenAmiga
- cmp.w #STYP_AMIGAMONO,ScreenType
- beq OpenAmigaMono
-
- ; EGS/Picasso/Cyber: Dimensionen holen und prüfen, ob ausreichend
- move.l _IntuitionBase,a6
- move.l DisplayID,a0
- lea TheRect,a1
- moveq #OSCAN_TEXT,d0
- JSRLIB QueryOverscan
- tst.l d0
- beq NoDisplayID
-
- lea TheRect,a0
- move.w ra_MaxX(a0),d0
- sub.w ra_MinX(a0),d0
- addq.w #1,d0
- move.w d0,ScreenX
- move.w ra_MaxY(a0),d0
- sub.w ra_MinY(a0),d0
- addq.w #1,d0
- move.w d0,ScreenY
-
- cmp.w #384,ScreenX
- blo TooSmall
- cmp.w #272,ScreenY
- blo TooSmall
-
- ; Screen-Typ auswerten (EGS/Picasso/Cyber)
- cmp.w #STYP_EGS,ScreenType
- beq OpenEGS
- cmp.w #STYP_CYBER,ScreenType
- beq OpenCyber
- bra OpenPicasso
-
- *
- * Amiga-Screen öffnen
- *
-
- ; Screen öffnen
- OpenAmiga move.w #$180,d0 ;Vielfaches von 32 (wegen c2p)
- move.w d0,ScreenX
- move.w d0,WindowWidth+2
- move.w #DisplayY,d0
- move.w d0,ScreenY
- move.w d0,WindowHeight+2
- move.l DisplayID,ScreenDID
- move.w Overscan,ScreenOScan+2
-
- bsr Initc2p4
- tst.l d0
- beq NoMem
-
- move.l _IntuitionBase,a6
- sub.l a0,a0
- lea ScreenTags,a1
- JSRLIB OpenScreenTagList
- move.l d0,TheScreen
- beq NoScreen
- move.l d0,WindowScreen
-
- move.l TheScreen,a0
- lea sc_RastPort(a0),a1
- move.l a1,TheRastPort
- lea sc_ViewPort(a0),a1
- move.l a1,TheViewPort
-
- ; Speicher für Chunky-BitMap und Comparison Buffer holen
- move.l _SysBase,a6
- move.w ScreenX,d0
- mulu.w #DisplayY,d0
- add.l d0,d0
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- JSRLIB AllocVec
- move.l d0,InvisibleMap
- beq NoMem
- move.w ScreenX,d1
- mulu.w #DisplayY,d1
- add.l d1,d0
- move.l d0,ComparisonBuf
-
- ; Fenster öffnen
- move.l _IntuitionBase,a6
- sub.l a0,a0
- lea WindowTags,a1
- JSRLIB OpenWindowTagList
- move.l d0,TheWindow
- beq NoMem
-
- move.l TheWindow,a0
- move.l wd_UserPort(a0),WindowPort
-
- ; Farbpalette laden
- move.l _GfxBase,a6
- moveq #0,d7 ;Registerzähler
- lea Palette,a2
- 1$ move.b d7,d0
- and.w #$0f,d0
- lea (a2,d0.w*4),a0
- moveq #0,d1
- move.b (a0)+,d1
- lsr.b #4,d1
- moveq #0,d2
- move.b (a0)+,d2
- lsr.b #4,d2
- moveq #0,d3
- move.b (a0)+,d3
- lsr.b #4,d3
- move.l d7,d0
- move.l TheViewPort,a0
- JSRLIB SetRGB4
- addq.b #1,d7
- cmp.b #16,d7 ;Hier nur 16 Register
- bne 1$
-
- ; VBlank-Routine setzen
- move.l #AmigaVBlank,VBlankProc
-
- ; Double Buffering-Kram einrichten
- ; Bildschirmadresse neu setzen!
- bsr OpenDoubleBuf
- clr.w MustWaitForC2P
-
- moveq #0,d0
- rts
-
- *
- * Amiga-Mono-Screen öffnen
- *
-
- ; Screen öffnen
- OpenAmigaMono move.w #$180,d0
- move.w d0,ScreenX
- move.w d0,WindowWidth+2
- move.w #DisplayY,d0
- move.w d0,ScreenY
- move.w d0,WindowHeight+2
- move.l DisplayID,MonoScreenDID
- move.w Overscan,MonoScreenOScan+2
-
- move.l _IntuitionBase,a6
- sub.l a0,a0
- lea MonoScreenTags,a1
- JSRLIB OpenScreenTagList
- move.l d0,TheScreen
- beq NoScreen
- move.l d0,WindowScreen
-
- move.l TheScreen,a0
- lea sc_RastPort(a0),a1
- move.l a1,TheRastPort
- lea sc_ViewPort(a0),a1
- move.l a1,TheViewPort
-
- ; Fenster öffnen
- move.l _IntuitionBase,a6
- sub.l a0,a0
- lea WindowTags,a1
- JSRLIB OpenWindowTagList
- move.l d0,TheWindow
- beq NoMem
-
- move.l TheWindow,a0
- move.l wd_UserPort(a0),WindowPort
-
- ; Farbpalette laden (schwarz/weiß)
- move.l _GfxBase,a6
- move.l TheViewPort,a0
- moveq #0,d0
- moveq #0,d1
- moveq #0,d2
- moveq #0,d3
- JSRLIB SetRGB4
- move.l TheViewPort,a0
- moveq #1,d0
- moveq #15,d1
- moveq #15,d2
- moveq #15,d3
- JSRLIB SetRGB4
-
- ; Adresse der Bitplane setzen
- move.l TheRastPort,a0
- move.l rp_BitMap(a0),a0
- move.l bm_Planes(a0),a0
- move.l a0,InvisibleMap
- move.l a0,Registers+CURRENTA5
-
- ; VBlank-Routine setzen
- move.l #AmigaMonoVBlank,VBlankProc
-
- ; Double Buffering-Kram einrichten
- bsr OpenDoubleBuf
-
- moveq #0,d0
- rts
-
- *
- * Picasso-Screen öffnen
- *
-
- ; vilintuisup.library öffnen
- OpenPicasso move.l _SysBase,a6
- moveq #2,d0
- lea VilIntuiName,a1
- JSRLIB OpenLibrary
- move.l d0,_VilIntuiBase
- beq NoVilIntuiSup
-
- ; Screen öffnen (interleaved)
- move.w ScreenX,WindowWidth+2
- move.w ScreenY,WindowHeight+2
-
- move.l _VilIntuiBase,a6
- lea Dimensions,a0
- move.w ScreenX,4(a0)
- move.w ScreenY,6(a0)
- lea VilTags,a0
- jsr OpenVillageScreenTagList(a6)
- move.l d0,TheScreen
- beq NoScreen
- move.l d0,WindowScreen
-
- move.l TheScreen,a0
- lea sc_ViewPort(a0),a1
- move.l a1,TheViewPort
-
- ; Fenster öffnen
- move.l _IntuitionBase,a6
- sub.l a0,a0
- lea WindowTags,a1
- JSRLIB OpenWindowTagList
- move.l d0,TheWindow
- beq NoMem
-
- move.l TheWindow,a0
- move.l wd_UserPort(a0),WindowPort
-
- ; Farbpalette laden
- move.l _GfxBase,a6
- moveq #0,d7 ;Registerzähler
- lea Palette,a2
- 1$ move.b d7,d0
- and.w #$0f,d0
- lea (a2,d0.w*4),a0
- moveq #0,d1
- move.b (a0)+,d1
- moveq #0,d2
- move.b (a0)+,d2
- moveq #0,d3
- move.b (a0)+,d3
- move.l d7,d0
- move.l TheViewPort,a0
- JSRLIB SetRGB4
- addq.b #1,d7
- bne 1$
-
- ; Adresse des Bildschirmspeichers setzen
- move.l #1,InvBufNum ;Adresse des zweiten Puffers holen
- move.l _VilIntuiBase,a6
- move.l TheScreen,a0
- jsr LockVillageScreen(a6)
- move.l TheScreen,a0
- move.l InvBufNum,d0
- jsr VillageGetBufAddr(a6)
- move.l d0,Registers+CURRENTA5
-
- ; VBlank-Routine setzen
- move.l #PicassoVBlank,VBlankProc
-
- moveq #0,d0
- rts
-
- *
- * EGS-Screen öffnen
- *
-
- ; egs.library öffnen
- OpenEGS move.l _SysBase,a6
- moveq #6,d0
- lea EGSName,a1
- JSRLIB OpenLibrary
- move.l d0,_EGSBase
- beq NoEGS
-
- ; Screen öffnen
- move.l _EGSBase,a6
- lea NewEScreen,a0
- jsr E_OpenScreen(a6)
- move.l d0,TheScreen
- beq NoScreen
-
- move.l TheScreen,a0
- move.l esc_Port(a0),EGSPort
-
- ; Zweite Bitmap für Double Buffering holen
- moveq #0,d0
- move.w ScreenX,d0
- moveq #0,d1
- move.w ScreenY,d1
- moveq #8,d2
- moveq #0,d3
- move.l #E_EB_DISPLAYABLE|E_EB_CLEARMAP,d4
- move.l TheScreen,a0
- move.l esc_Map(a0),a0
- jsr E_AllocBitMap(a6)
- move.l d0,InvisibleMap
- beq NoMem
-
- ; Farbpalette laden
- moveq #0,d7 ;Registerzähler
- lea Palette,a2
- 1$ move.b d7,d0
- and.w #$0f,d0
- lea (a2,d0.w*4),a0
- moveq #0,d1
- move.b (a0)+,d1
- moveq #0,d2
- move.b (a0)+,d2
- moveq #0,d3
- move.b (a0)+,d3
- move.l d7,d0
- move.l TheScreen,a0
- jsr E_SetRGB8(a6)
- addq.b #1,d7
- bne 1$
-
- ; Adresse des Bildschirmspeichers setzen
- move.l InvisibleMap,a1
- addq.b #1,ebm_Lock(a1)
- move.l ebm_Dest(a1),Registers+CURRENTA5
-
- ; VBlank-Routine setzen
- move.l #EGSVBlank,VBlankProc
-
- moveq #0,d0
- rts
-
- *
- * Cybergraphics-Screen öffnen
- *
-
- ; cybergraphics.library öffnen
- OpenCyber tst.l _CyberGfxBase
- bne 2$
- move.l _SysBase,a6
- moveq #40,d0
- lea CyberGfxName,a1
- JSRLIB OpenLibrary
- move.l d0,_CyberGfxBase
- beq NoCyberGfx
- 2$
-
- ; CyberGfx-Modus?
- move.l _CyberGfxBase,a6
- move.l DisplayID,d0
- jsr IsCyberModeID(a6)
- tst.l d0
- beq NoCyberMode
-
- ; Screen öffnen
- move.w ScreenX,WindowWidth+2
- move.w ScreenX,CyberScreenX+2
- move.w ScreenY,WindowHeight+2
- move.w ScreenY,CyberScreenY+2
- move.l DisplayID,CyberScreenDID
-
- move.l _IntuitionBase,a6
- sub.l a0,a0
- lea CyberScreenTags,a1
- JSRLIB OpenScreenTagList
- move.l d0,TheScreen
- beq NoScreen
- move.l d0,WindowScreen
-
- move.l TheScreen,a0
- lea sc_RastPort(a0),a1
- move.l a1,TheRastPort
- lea sc_ViewPort(a0),a1
- move.l a1,TheViewPort
-
- ; Fenster öffnen
- move.l _IntuitionBase,a6
- sub.l a0,a0
- lea WindowTags,a1
- JSRLIB OpenWindowTagList
- move.l d0,TheWindow
- beq NoMem
-
- move.l TheWindow,a0
- move.l wd_UserPort(a0),WindowPort
-
- ; Farbpalette laden
- move.l _GfxBase,a6
- moveq #0,d7 ;Registerzähler
- lea Palette,a2
- 1$ move.b d7,d0
- and.w #$0f,d0
- lea (a2,d0.w*4),a0
- move.w (a0),d1
- move.b (a0),d1
- swap d1
- move.w (a0),d1
- move.b (a0)+,d1
- move.w (a0),d2
- move.b (a0),d2
- swap d2
- move.w (a0),d2
- move.b (a0)+,d2
- move.w (a0),d3
- move.b (a0),d3
- swap d3
- move.w (a0),d3
- move.b (a0)+,d3
- move.l d7,d0
- move.l TheViewPort,a0
- JSRLIB SetRGB32
- addq.b #1,d7
- bne 1$
-
- ; Es wird alles nach LineStore geschrieben
- move.l #LineStore,Registers+CURRENTA5
-
- ; VBlank-Routine setzen
- move.l #CyberVBlank,VBlankProc
-
- moveq #0,d0
- rts
-
- ; Fehler aufgetreten
- NoScreen moveq #1,d0
- rts
- NoMem moveq #2,d0
- rts
- NoEGS moveq #3,d0
- rts
- NoVilIntuiSup moveq #4,d0
- rts
- NoDisplayID moveq #5,d0
- rts
- TooSmall moveq #6,d0
- rts
- NoCyberGfx moveq #7,d0
- rts
- NoCyberMode moveq #8,d0
- rts
-
-
- *
- * Double Buffering einrichten
- *
-
- ; Intuition V39 vorhanden? Sonst hat's keinen Zweck.
- OpenDoubleBuf move.l _IntuitionBase,a0
- cmp.w #39,LIB_VERSION(a0)
- blo 1$
-
- ; Screen Buffer holen
- move.l _IntuitionBase,a6
- move.l TheScreen,a0
- sub.l a1,a1
- moveq #SB_SCREEN_BITMAP,d0
- JSRLIB AllocScreenBuffer
- move.l d0,ScrBuf0
- beq CloseDoubleBuf
-
- move.l TheScreen,a0
- sub.l a1,a1
- moveq #SB_COPY_BITMAP,d0
- JSRLIB AllocScreenBuffer
- move.l d0,ScrBuf1
- beq CloseDoubleBuf
-
- ; Etwas warten
- move.l _GfxBase,a6
- JSRLIB WaitTOF
- JSRLIB WaitTOF
-
- ; Adresse des Bildschirmspeichers holen
- move.l #1,InvBufNum
-
- cmp.w #STYP_AMIGA,ScreenType
- beq 2$
- move.l ScrBuf1,a0
- move.l sb_BitMap(a0),a0
- move.l bm_Planes(a0),Registers+CURRENTA5
- move.w #-1,UsingDB
- 1$ rts
-
- ; Amiga: Zweiten Comparison Buffer holen
- 2$ move.l InvisibleMap,Registers+CURRENTA5
-
- move.l _SysBase,a6
- move.w ScreenX,d0
- mulu.w #DisplayY,d0
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- JSRLIB AllocVec
- move.l d0,ComparisonBuf1
- beq CloseDoubleBuf
-
- move.w #-1,UsingDB
- rts
-
-
- **
- ** Bildschirm schließen
- **
-
- CloseGraphics cmp.w #STYP_EGS,ScreenType
- beq CloseEGS
- cmp.w #STYP_PICASSO,ScreenType
- beq ClosePicasso
- cmp.w #STYP_AMIGAMONO,ScreenType
- beq CloseAmigaMono
- cmp.w #STYP_CYBER,ScreenType
- beq CloseCyber
-
- ; Amiga
- CloseAmiga move.l _IntuitionBase,a6
- move.l TheWindow,d0
- beq 1$
- move.l d0,a0
- JSRLIB CloseWindow
-
- 1$ bsr CloseDoubleBuf
-
- move.l _IntuitionBase,a6
- move.l TheScreen,d0
- beq 2$
- move.l d0,a0
- JSRLIB CloseScreen
-
- 2$ move.l InvisibleMap,d0
- beq 3$
- move.l _SysBase,a6
- move.l d0,a1
- JSRLIB FreeVec
-
- 3$ bra Exitc2p4
-
- ; Amiga-Mono
- CloseAmigaMono move.l _IntuitionBase,a6
- move.l TheWindow,d0
- beq 1$
- move.l d0,a0
- JSRLIB CloseWindow
-
- 1$ bsr CloseDoubleBuf
-
- move.l _IntuitionBase,a6
- move.l TheScreen,d0
- beq 2$
- move.l d0,a0
- JSRLIB CloseScreen
- 2$ rts
-
- ; Picasso
- ClosePicasso move.l _IntuitionBase,a6
- move.l TheWindow,d0
- beq 1$
- move.l d0,a0
- JSRLIB CloseWindow
-
- 1$ move.l _VilIntuiBase,a6
- move.l TheScreen,d0
- beq 2$
- move.l d0,a0
- jsr UnLockVillageScreen(a6)
- move.l TheScreen,a0
- jsr CloseVillageScreen(a6)
- 2$ rts
-
- ; EGS
- CloseEGS move.l _EGSBase,a6
- move.l TheScreen,d0
- beq 1$
- move.l d0,a0
- jsr E_CloseScreen(a6)
-
- 1$ move.l InvisibleMap,d0
- beq 2$
- move.l d0,a0
- subq.b #1,ebm_Lock(a0)
- jsr E_DisposeBitMap(a6)
- 2$ rts
-
- ; Cybergraphics
- CloseCyber move.l _IntuitionBase,a6
- move.l TheWindow,d0
- beq 1$
- move.l d0,a0
- JSRLIB CloseWindow
-
- 1$ move.l TheScreen,d0
- beq 2$
- move.l d0,a0
- JSRLIB CloseScreen
- 2$ rts
-
- *
- * Double Buffering schließen
- *
-
- ; Zweiten Comparison Buffer freigeben
- CloseDoubleBuf tst.w UsingDB
- beq 2$
-
- move.l _SysBase,a6
- move.l ComparisonBuf1,d0
- beq 1$
- move.l d0,a1
- JSRLIB FreeVec
-
- ; Screen Buffer freigeben
- 1$ move.l _IntuitionBase,a6
- move.l TheScreen,a0
- move.l ScrBuf0,a1 ;NULL ist OK
- JSRLIB FreeScreenBuffer
-
- move.l TheScreen,a0
- move.l ScrBuf1,a1
- JSRLIB FreeScreenBuffer
- 2$ rts
-
-
- **
- ** Amiga-Anzeige nach vorne
- **
-
- AmigaToFront move.l a6,-(sp)
- cmp.w #STYP_EGS,ScreenType
- beq ATFEGS
-
- ; Bei Picasso Screen unlocken
- cmp.w #STYP_PICASSO,ScreenType
- bne 1$
- move.l _VilIntuiBase,a6
- move.l TheScreen,a0
- jsr UnLockVillageScreen(a6)
- 1$
-
- ; Amiga/Picasso/Cyber
- move.l _IntuitionBase,a6
- move.l TheScreen,a0
- JSRLIB ScreenToBack
- move.l (sp)+,a6
- rts
-
- ; EGS
- ATFEGS move.l _EGSBase,a6
- jsr E_ActivateAmigaScreen(a6)
- move.l TheScreen,a0
- jsr E_ScreenToBack(a6)
- move.l (sp)+,a6
- rts
-
-
- **
- ** Emulator-Anzeige nach vorne
- **
-
- EmulToFront move.l a6,-(sp)
- cmp.w #STYP_EGS,ScreenType
- beq ETFEGS
-
- ; Amiga/Picasso/Cyber
- move.l _IntuitionBase,a6
- move.l TheScreen,a0
- JSRLIB ScreenToFront
-
- ; Bei Picasso Screen locken
- cmp.w #STYP_PICASSO,ScreenType
- bne 1$
- move.l _VilIntuiBase,a6
- move.l TheScreen,a0
- jsr LockVillageScreen(a6)
- 1$ move.l (sp)+,a6
- rts
-
- ; EGS
- ETFEGS move.l _EGSBase,a6
- jsr E_ActivateEGSScreen(a6)
- move.l TheScreen,a0
- jsr E_ScreenToFront(a6)
- move.l (sp)+,a6
- rts
-
-
- **
- ** Auf rechten Mausklick warten, Tastatur handhaben
- **
-
- WaitForClick cmp.w #STYP_EGS,ScreenType
- beq WFCEGS
-
- ; Amiga/Picasso/Cyber
- WFCAmiga move.l _SysBase,a6
- move.l WindowPort,a0
- JSRLIB WaitPort
-
- move.l WindowPort,a0
- JSRLIB GetMsg
- tst.l d0
- beq WFCAmiga
- move.l d0,a1
- move.l 20(a1),d2 ;d2: Class
- move.w 24(a1),d3 ;d3: Code
- move.l 32(a1),d4 ;d4: MouseXY
- move.w 26(a1),d5 ;d5: Qualifier
- JSRLIB ReplyMsg
-
- ; Klasse auswerten
- cmp.l #IDCMP_MOUSEBUTTONS,d2
- bne 1$
- cmp.w #IECODE_RBUTTON,d3 ;Rechte Maustaste: Beenden
- beq WFCDone
- bra WFCAmiga
-
- 1$ cmp.l #IDCMP_RAWKEY,d2
- bne WFCAmiga
- move.b d3,d0
- bsr KeyPressed ;Tastaturabfrage
- bra WFCAmiga
-
- ; EGS
- WFCEGS move.l _SysBase,a6
- move.l EGSPort,a0
- JSRLIB WaitPort
-
- move.l EGSPort,a0
- JSRLIB GetMsg
- tst.l d0
- beq WFCEGS
- move.l d0,a1
- move.l 20(a1),d2 ;d2: Class
- move.w 24(a1),d3 ;d3: Code
- move.l 32(a1),d4 ;d4: MouseXY
- move.w 26(a1),d5 ;d5: Qualifier
- JSRLIB ReplyMsg
-
- ; Klasse auswerten
- cmp.w #E_eMOUSEBUTTONS,d2
- bne 1$
- cmp.w #IECODE_RBUTTON,d3 ;Rechte Maustaste: Beenden
- beq WFCDone
- bra WFCEGS
-
- 1$ cmp.w #E_eRAWKEY,d2
- bne WFCEGS
- move.b d3,d0
- bsr KeyPressed ;Tastaturabfrage
- bra WFCEGS
-
- ; Beenden
- WFCDone rts
-
-
- **
- ** CIA-VA14/15 hat sich geändert, Video-Bank wechseln
- ** d0.b: Neue VA ($00-$03)
- **
-
- ChangedVA lea Registers,a0 ;Wichtig für WrVBASE
- clr.w d1 ;VABase speichern
- move.b d0,d1
- ror.w #2,d1
- move.w d1,CiaVABase
-
- move.b VBASE(a0),d1 ;Zeiger neu berechnen
- bra WrVBASE
-
-
- **
- ** Initialisierung vom 6510-Task aus
- **
-
- ; Signal für c2p4 holen
- Init6569 move.l _SysBase,a6
- moveq #-1,d0
- JSRLIB AllocSignal
- move.b d0,GfxSig
- moveq #0,d1
- bset d0,d1
- move.l d1,GfxSet
- rts
-
-
- **
- ** Aufräumen vom 6510-Task aus
- **
-
- ; Ggf. auf Signal von c2p4 warten und freigeben
- Exit6569 move.l _SysBase,a6
- tst.w MustWaitForC2P
- beq 1$
- move.l GfxSet,d0
- JSRLIB Wait
-
- 1$ moveq #0,d0
- move.b GfxSig,d0
- JMPLIB FreeSignal
-
-
- **
- ** Aus einem VIC-Register lesen
- ** d0.w: Registernummer ($00-$3f)
- ** Rückgabe: d0.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- ** Darf a1 nicht verändern!
- **
-
- ReadFrom6569 move.l ReadTab(pc,d0.w*4),a0
- jmp (a0)
-
- CNOP 0,4
- ReadTab dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
- dc.l RdSprX
- dc.l RdNormal
-
- dc.l RdNormal
- dc.l RdCTRL1
- dc.l RdRASTER
- dc.l RdNormal
- dc.l RdNormal
- dc.l RdNormal
- dc.l RdCTRL2
- dc.l RdNormal
- dc.l RdVBASE
- dc.l RdIRQFLAG
- dc.l RdIRQMASK
- dc.l RdNormal
- dc.l RdNormal
- dc.l RdNormal
- dc.l RdCLXSPR
- dc.l RdCLXBGR
-
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdColor
- dc.l RdUndef
-
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
- dc.l RdUndef
-
- RdNormal lea Registers,a0
- move.b (a0,d0.w),d0
- rts
-
- RdSprX lea Registers,a0
- move.b SPRX0+1(a0,d0.w),d0 ;LSB lesen
- rts
-
- RdCTRL1 lea Registers,a0
- move.b CTRL1(a0),d0
- and.b #$7f,d0
- move.b CURRENTRASTER(a0),d1 ;MSB des Rasterzählers lesen
- and.b #$01,d1
- ror.b #1,d1
- or.b d1,d0 ;und dazunehmen
- rts
-
- RdRASTER move.b Registers+CURRENTRASTER+1,d0 ;Rasterzähler lesen
- rts
-
- RdCTRL2 move.b Registers+CTRL2,d0
- or.b #$c0,d0 ;Unbenutzte Bits auf 1
- rts
-
- RdVBASE move.b Registers+VBASE,d0
- or.b #$01,d0 ;Unbenutzte Bits auf 1
- rts
-
- RdIRQFLAG move.b Registers+IRQFLAG,d0
- or.b #$70,d0 ;Unbenutzte Bits auf 1
- rts
-
- RdIRQMASK move.b Registers+IRQMASK,d0
- or.b #$f0,d0 ;Unbenutzte Bits auf 1
- rts
-
- RdCLXSPR lea Registers+CLXSPR,a0
- move.b (a0),d0 ;Lesen und löschen
- clr.b (a0)
- rts
-
- RdCLXBGR lea Registers+CLXBGR,a0
- move.b (a0),d0 ;Lesen und löschen
- clr.b (a0)
- rts
-
- RdColor lea Registers,a0
- move.b (a0,d0.w),d0 ;Bei den Farbregistern
- or.b #$f0,d0 ;das obere Nibble setzen
- rts
-
- RdUndef move.b #$ff,d0 ;Nicht existierendes Register
- rts
-
-
- **
- ** In ein VIC-Register schreiben
- ** d0.w: Registernummer ($00-$3f)
- ** d1.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- WriteTo6569 lea Registers,a0
- move.l WriteTab(pc,d0.w*4),a1
- jmp (a1)
-
- CNOP 0,4
- WriteTab dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
- dc.l WrSprX
- dc.l WrNormal
-
- dc.l WrSprXMSB
- dc.l WrCTRL1
- dc.l WrRASTER
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrCTRL2
- dc.l WrNormal
- dc.l WrVBASE
- dc.l WrIRQFLAG
- dc.l WrIRQMASK
- dc.l WrMDP
- dc.l WrMMC
- dc.l WrMXE
- dc.l WrUndef
- dc.l WrUndef
-
- dc.l WrBorder
- dc.l WrBack0
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrUndef
-
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
- dc.l WrUndef
-
- WrNormal move.b d1,(a0,d0.w)
- WrUndef rts
-
- WrSprX move.b d1,SPRX0+1(a0,d0.w)
- rts
-
- WrSprXMSB move.b d1,MX8(a0)
- lea SPRX7(a0),a0 ;MSBs in 16-Bit-Werte umrechnen
- moveq #7,d0
- 1$ add.b d1,d1
- bcs 2$
- clr.b (a0)
- bra 3$
- 2$ move.b #1,(a0)
- 3$ subq.w #2,a0
- dbra d0,1$
- rts
-
- WrCTRL1 move.b d1,CTRL1(a0)
- move.b d1,d0
- and.w #7,d0
- move.w d0,YSCROLL(a0)
- move.b d1,d0 ;MSB Raster
- and.b #$80,d0
- rol.b #1,d0
- move.b d0,IRQRASTER(a0)
- btst #3,d1 ;24/25 Zeilen
- beq 1$
- move.w #Row25YStart,DYSTART(a0)
- move.w #Row25YStop,DYSTOP(a0)
- bra SetDispProc
- 1$ move.w #Row24YStart,DYSTART(a0)
- move.w #Row24YStop,DYSTOP(a0)
- bra SetDispProc
-
- SetDispProc moveq #0,d0 ;ECM, BMM und MCM holen
- move.b CTRL1(a0),d0
- and.b #$60,d0
- move.b CTRL2(a0),d1
- and.b #$10,d1
- or.b d1,d0
- lsr.b #2,d0 ;Als Index in DispProcTab benutzen
- cmp.w #STYP_AMIGAMONO,ScreenType
- beq 1$
- move.l (DispProcTab,pc,d0.w),DisplayProc
- rts
- 1$ move.l (MonoDispProcTab,pc,d0.w),DisplayProc
- rts
-
- WrRASTER move.b d1,IRQRASTER+1(a0)
- rts
-
- WrCTRL2 move.b d1,CTRL2(a0)
- move.b d1,d0
- and.w #7,d0
- move.w d0,XSCROLL(a0)
- btst #3,d1 ;38/40 Zeilen
- beq 1$
- clr.b IS38COL(a0)
- move.w #Col40XStart,DXSTART(a0)
- move.w #Col40XStop,DXSTOP(a0)
- bra SetDispProc
- 1$ st.b IS38COL(a0)
- move.w #Col38XStart,DXSTART(a0)
- move.w #Col38XStop,DXSTOP(a0)
- bra SetDispProc
-
- WrVBASE move.l a0,a1 ;a1: Zeiger auf Register
- move.b d1,VBASE(a1)
-
- move.w d1,-(sp)
- move.b d1,d0 ;Videomatrixbasis berechnen
- and.w #$f0,d0
- lsl.w #6,d0
- GetPhysical
- move.l a0,MATRIXBASE(a1)
- move.w (sp),d1 ;Nur lesen, nicht entfernen
-
- move.b d1,d0 ;Zeichengeneratorbasis berechnen
- and.w #$0e,d0
- ror.w #6,d0
- GetPhysical
- move.l a0,CHARBASE(a1)
- move.w (sp)+,d1
-
- move.b d1,d0
- and.w #$08,d0
- ror.w #6,d0
- GetPhysical
- move.l a0,BITMAPBASE(a1)
- rts
-
- WrIRQFLAG not.b d1 ;Gesetztes Bit: Flag löschen
- and.b #$0f,d1
- move.b IRQFLAG(a0),d0
- and.b d1,d0
-
- clr.b IntIsVICIRQ ;IRQ zurücknehmen
-
- move.b d0,d1 ;Erlaubter IRQ noch gesetzt?
- and.b IRQMASK(a0),d1
- beq 1$
- or.b #$80,d0 ;Ja, Master-Bit setzen
- 1$ move.b d0,IRQFLAG(a0)
- rts
-
- WrIRQMASK and.b #$0f,d1
- move.b d1,IRQMASK(a0)
- rts
-
- WrMDP move.b d1,MDP(a0)
- bra SetSpriteProcs
-
- WrMMC move.b d1,MMC(a0)
- bra SetSpriteProcs
-
- WrMXE move.b d1,MXE(a0) ;Fällt durch!
-
- SetSpriteProcs moveq #7,d1
- lea Sprite7Proc,a1
- 1$ moveq #0,d0
- btst d1,MXE(a0)
- beq 2$
- or.b #1,d0
- 2$ btst d1,MMC(a0)
- beq 3$
- or.b #2,d0
- 3$ btst d1,MDP(a0)
- beq 4$
- or.b #4,d0
- 4$ move.l (SpriteProcTab,pc,d0.w*4),(a1)
- subq.w #4,a1
- dbra d1,1$
- rts
-
- WrBorder move.b d1,EC(a0)
- move.b d1,d0 ;In ein Langwort konvertieren
- lsl.w #8,d0
- move.b d1,d0
- move.w d0,d1
- swap d0
- move.w d1,d0
- move.l d0,BORDERLONG(a0)
- moveq #0,d0
- rts
-
- WrBack0 move.b d1,B0C(a0)
- move.b d1,d0 ;In ein Langwort konvertieren
- lsl.w #8,d0
- move.b d1,d0
- move.w d0,d1
- swap d0
- move.w d1,d0
- move.l d0,BACK0LONG(a0)
- moveq #0,d0
- rts
-
-
- **
- ** Eine Rasterzeile des VIC ausführen
- **
- ** d7: Rasterzeilenzähler
- ** a4: Zeiger auf VIC-Register
- ** a5: Zeiger auf das Ziel im Bildschirmspeicher
- **
-
- ; VBlank: Zähler zurücksetzen und Bitmap wechseln
- VICVBlank move.w #-1,CURRENTRASTER(a4)
- clr.w VCBASE(a4)
-
- btst #4,CTRL1(a4) ;Bildschirm abschalten, wenn DEN gelöscht
- bne 1$
- st.b SCREENOFF(a4)
- bra 2$
- 1$ clr.b SCREENOFF(a4)
- 2$
- bsr CountTODs ;TODs zählen
-
- st.b SKIPFRAME(a4)
- subq.w #1,SkipCounter
- bne 3$
- move.w SkipLatch,SkipCounter
- clr.b SKIPFRAME(a4)
-
- 3$ tst.b SKIPFRAME(a4)
- bne Periodic6569
- move.l VBlankProc,a0
- jmp (a0)
-
- ; EGS: BitMap wechseln (Double Buffering)
- EGSVBlank move.l _EGSBase(pc),a6 ;Vorher unsichtbare Bitmap
-
- move.l TheScreen,a0 ;darstellen
- move.l InvisibleMap,a1
- subq.b #1,ebm_Lock(a1)
- jsr E_FlipMap(a6)
- move.l d0,InvisibleMap ;In alte Bitmap ab jetzt zeichnen
-
- move.l d0,a0 ;Adresse ermitteln
- addq.b #1,ebm_Lock(a0)
- move.l ebm_Dest(a0),CURRENTA5(a4)
-
- bra Periodic6569
-
- ; Cybergraphics: Nichts
- CyberVBlank bra Periodic6569
-
- ; Amiga: Chunky-BitMap in Planar konvertieren
- AmigaVBlank tst.w MustWaitForC2P(pc) ;Ggf. erst auf c2p4 warten
- beq 1$
- move.l _SysBase,a6
- move.l GfxSet,d0
- JSRLIB Wait
-
- 1$ tst.w UsingDB ;Double Buffering?
- beq 4$
-
- 3$ move.l _IntuitionBase,a6 ;Ja, Puffer tauschen
- lea ScrBuf0,a1
- move.w InvBufNum+2,d0
- move.l (a1,d0.w*4),a1
- move.l TheScreen,a0
- JSRLIB ChangeScreenBuffer
- tst.l d0
- bne 2$
- move.l _GfxBase,a6 ;Nicht gelungen, warten
- JSRLIB WaitTOF ; und nochmal versuchen
- bra 3$
-
- 2$ eor.w #1,InvBufNum+2 ;Adresse des neuen Grafikspeichers holen
- move.l InvisibleMap,a2 ;Neue Konvertierung starten
- lea ComparisonBuf,a0
- move.w InvBufNum+2,d0
- move.l (a0,d0.w*4),a3
- lea ScrBuf0,a0
- move.l (a0,d0.w*4),a0
- move.l sb_BitMap(a0),a0
- lea bm_Planes(a0),a4
- move.l CPUTask,a5
- move.l GfxSet,d0
- jsr _c2p4
-
- move.l InvisibleMap,Registers+CURRENTA5
- move.w #-1,MustWaitForC2P
- bra Periodic6569
-
- 4$ move.l InvisibleMap,a2 ;Kein DB: Neue Konvertierung starten
- move.l ComparisonBuf,a3
- move.l TheRastPort,a4
- move.l rp_BitMap(a4),a4
- lea bm_Planes(a4),a4
- move.l CPUTask,a5
- move.l GfxSet,d0
- jsr _c2p4
-
- move.l InvisibleMap,Registers+CURRENTA5
- move.w #-1,MustWaitForC2P
- bra Periodic6569
-
- ; Amiga-Mono: Double Buffering
- AmigaMonoVBlank tst.w UsingDB(pc) ;Double Buffering?
- beq 1$
-
- 3$ move.l _IntuitionBase,a6
- lea ScrBuf0,a1
- move.w InvBufNum+2,d0
- move.l (a1,d0.w*4),a1
- move.l TheScreen,a0
- JSRLIB ChangeScreenBuffer
- tst.l d0
- bne 2$
- move.l _GfxBase,a6 ;Nicht gelungen, warten
- JSRLIB WaitTOF ; und nochmal versuchen
- bra 3$
-
- 2$ eor.w #1,InvBufNum+2 ;Adresse des neuen Grafikspeichers holen
- lea ScrBuf0,a0
- move.w InvBufNum+2,d0
- move.l (a0,d0.w*4),a0
- move.l sb_BitMap(a0),a0
- move.l bm_Planes(a0),CURRENTA5(a4)
- bra Periodic6569
-
- 1$ move.l InvisibleMap,CURRENTA5(a4) ;Kein DB
- bra Periodic6569
-
- ; Picasso: Double Buffering
- PicassoVBlank move.l _VilIntuiBase,a6
-
- move.l TheScreen,a0
- jsr UnLockVillageScreen(a6)
-
- move.l TheScreen,a0 ;Vorher unsichtbare Bitmap
- move.l InvBufNum,d0 ;darstellen
- jsr VillageSetDisplayBuf(a6)
-
- eor.l #1,InvBufNum ;Puffer wechseln
- move.l TheScreen,a0
- jsr LockVillageScreen(a6)
- move.l TheScreen,a0 ;Adresse ermitteln
- move.l InvBufNum,d0
- jsr VillageGetBufAddr(a6)
- move.l d0,CURRENTA5(a4)
-
- ;Fällt durch!
- *
- * Aktuelle Rasterzeile holen
- *
-
- Periodic6569 lea Registers,a4
- move.w CURRENTRASTER(a4),d7
-
- *
- * Rasterzähler erhöhen (muß hier geschehen, damit bei einem Raster-IRQ
- * der Wert des Rasterzählers mit der IRQ-Zeile übereinstimmt)
- *
-
- addq.w #1,d7
- move.w d7,CURRENTRASTER(a4)
- cmp.w #TotalRasters,d7 ;Bildende erreicht?
- beq VICVBlank
-
- *
- * Raster-IRQ auslösen, wenn Vergeichswert erreicht
- *
-
- cmp.w IRQRASTER(a4),d7 ;IRQ-Zeile erreicht?
- bne NoRasterIRQ
- or.b #$01,IRQFLAG(a4) ;Ja, IRST-Bit setzen
- btst #0,IRQMASK(a4) ;Raster-IRQ erlaubt?
- beq NoRasterIRQ
- or.b #$80,IRQFLAG(a4) ;Ja, IRQ-Bit setzen
- st.b IntIsVICIRQ ;Und Interrupt auslösen
- NoRasterIRQ
-
- *
- * Neue Anzahl CPU-Zyklen setzen
- *
-
- move.w NormalCycles,CyclesLeft
-
- tst.b SKIPFRAME(a4)
- bne VICSkip
-
- *
- * Innerhalb des sichtbaren Bereichs?
- *
-
- cmp.w #FirstDispLine,d7
- blo VICNop
- cmp.w #LastDispLine,d7
- bhi VICNop
-
- *
- * Zeiger in Bildschirmspeicher nach a5 holen
- *
-
- move.w ScreenType,d0
- jmp ([GetA5JmpTab,pc,d0.w*4])
- GetA5JmpTab dc.l GetA5EGS
- dc.l GetA5Picasso
- dc.l GetA5Amiga
- dc.l GetA5AmigaMono
- dc.l GetA5Cyber
-
- GetA5AmigaMono move.l CURRENTA5(a4),a5 ;Amiga-Mono: In die Bitplane schreiben
- bra AmigaMono6569 ; und in spezielle VIC-Routine springen
- GetA5EGS
- GetA5Picasso
- GetA5Cyber
- lea LineStore,a5 ;EGS/Picasso/Cyber: In LineStore schreiben
- bra GetA5Done
- GetA5Amiga move.l CURRENTA5(a4),a5 ;Amiga: In die Chunky-Map schreiben
- GetA5Done
-
- *
- * Bei abgeschaltetem Bildschirm nur Rahmen zeichnen
- *
-
- tst.b SCREENOFF(a4)
- bne TBBorderDraw
-
- *
- * VC-Zähler setzen
- *
-
- move.w VCBASE(a4),VCCOUNT(a4)
-
- *
- * "Bad Lines"-Videomatrixzugriff:
- * 40 Bytes aus Videomatrix und Farb-RAM lesen und zwischenspeichern
- *
-
- cmp.w #FirstDMALine,d7 ;Innerhalb des DMA-Bereiches?
- blo NoBadLine
- cmp.w #LastDMALine,d7
- bhi NoBadLine
-
- move.b d7,d0 ;Ja, stimmen die unteren Bits
- and.b #7,d0 ;der Rasterzeile mit dem Y-Scroll
- cmp.b YSCROLL+1(a4),d0 ;überein?
- bne NoBadLine
-
- IsBadLine move.w VCCOUNT(a4),d2 ;d2: VC Videomatrix-Zähler
-
- move.l MATRIXBASE(a4),a0 ;Videomatrixbasis holen
- add.w d2,a0 ;Videomatrixzähler dazunehmen
-
- move.l TheColor(pc),a2 ;Zeiger auf Farb-RAM holen
- add.w d2,a2 ;Videomatrixzähler dazunehmen
-
- lea MatrixLine,a1 ;Videomatrix- und Farb-RAM-Zeile lesen
- lea ColorLine,a3
- movem.l (a0)+,d0-d6 ;Je 40 Bytes kopieren
- movem.l d0-d6,(a1)
- movem.l (a2)+,d0-d6
- movem.l d0-d6,(a3)
- movem.l (a0)+,d0-d2
- movem.l d0-d2,28(a1)
- movem.l (a2)+,d0-d2
- movem.l d0-d2,28(a3)
-
- clr.w RC(a4) ;RC zurücksetzen
- clr.b DISPLAYOFF(a4) ;Darstellung anschalten
-
- move.w BadLineCycles,CyclesLeft ;Andere Anzahl Zyklen
- NoBadLine
-
- *
- * Oberen und unteren Rahmen handhaben
- *
-
- cmp.w DYSTOP(a4),d7 ;Unteres Ende des Fensters erreicht
- bne 1$ ; -> Rahmen einschalten
- st.b BORDERON(a4)
- bra TBBorderDraw
-
- 1$ cmp.w DYSTART(a4),d7 ;Oberes Ende des Fensters erreicht
- bne TBBorderDone ; -> Rahmen abschalten
- clr.b BORDERON(a4)
- bra TBNoBorder
-
- TBBorderDone tst.b BORDERON(a4) ;Rahmen an?
- beq TBNoBorder
-
- TBBorderDraw move.l CURRENTA5(a4),a0 ;Ja, Rahmen malen. Und zwar in jedem
- ; Fall direkt in die Bitmap schreiben
- ; (kein Umweg über LineStore)
- move.l BORDERLONG(a4),d0 ;d0.l: Rahmenfarbe
- move.w #DisplayX/4-1,d1
- 1$ move.l d0,(a0)+
- dbra d1,1$
- cmp.w #STYP_CYBER,ScreenType
- beq VICNextCyber
- bra VICIncA5 ;Sonst nix
- TBNoBorder
-
- *
- * Inhalt des Fensters: Darstellung eingeschaltet?
- *
-
- lea Col40XStart(a5),a1
- add.w XSCROLL(a4),a1 ;a1: Ziel in Bildschirmspeicher
- lea MatrixLine,a2 ;a2: Zeichencodes
- lea ColorLine,a3 ;a3: Farbcodes
- lea GfxCollBuf+Col40XStart,a6
- add.w XSCROLL(a4),a6 ;a6: Grafik-Kollisionspuffer
-
- tst.b DISPLAYOFF(a4) ;$3FFF darstellen?
- bne Show3FFF
-
- jmp ([DisplayProc]) ;Nein, Routine für entsp. Modus anspringen
-
- *
- * Standard-Text: Zeichendaten holen und darstellen
- *
-
- TextStd add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
-
- move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
- add.w RC(a4),a0 ;RC dazunehmen
-
- move.l BACK0LONG(a4),d3 ;d3.l: Hintergrundfarbe
-
- move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
- move.l d3,Col40XStart+4(a5)
-
- ; Schleife für 40 Zeichen
- moveq #39,d1 ;d1: Zeichenzähler
- moveq #0,d0
- CharLoop move.b (a2)+,d0 ;Zeichencode lesen
- move.b (a0,d0.w*8),d0 ;Zeichendaten lesen
- beq OnlyBack
- move.b (a3)+,d2 ;d2: Zeichenfarbe
-
- ; 8 Pixel konvertieren
- moveq #7,d6
- 10$ add.b d0,d0
- bcc 11$
- move.b d2,(a1)+
- st.b (a6)+
- bra 12$
- 11$ move.b d3,(a1)+
- clr.b (a6)+
- 12$ dbra d6,10$
-
- dbra d1,CharLoop
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- OnlyBack move.l d3,(a1)+
- move.l d3,(a1)+
- clr.l (a6)+
- clr.l (a6)+
- addq.w #1,a3 ;Farb-RAM-Byte überspringen
- dbra d1,CharLoop
- bra DoSprites
-
- *
- * Multicolor-Text: Zeichendaten holen und darstellen
- *
-
- TextMulti add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
-
- move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
- add.w RC(a4),a0 ;RC dazunehmen
-
- move.l BACK0LONG(a4),d3 ;d3.l: Farbe 0
-
- move.w $22(a4),d4 ;d4.w: Farbe 1
- move.b $22(a4),d4
-
- move.w $23(a4),d5 ;d5.w: Farbe 2
- move.b $23(a4),d5
-
- move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
- move.l d3,Col40XStart+4(a5)
-
- ; Schleife für 40 Zeichen
- moveq #39,d1 ;d1: Zeichenzähler
- moveq #0,d0
- CharMLoop move.b (a2)+,d0 ;Zeichencode lesen
- move.b (a0,d0.w*8),d0 ;Zeichendaten lesen
- beq MOnlyBack
- move.b (a3)+,d2 ;d2: Farbnibble
- bclr #3,d2 ;Standard oder Multi?
- beq StdInMulti
-
- ; Multicolor: 4 Pixel konvertieren
- moveq #3,d6
- 10$ add.b d0,d0
- bcc 11$
- add.b d0,d0
- bcc 12$
- move.b d2,(a1)+ ;11
- move.b d2,(a1)+
- st.b (a6)+
- st.b (a6)+
- bra 14$
- 12$ move.w d5,(a1)+ ;10
- st.b (a6)+
- st.b (a6)+
- bra 14$
- 11$ clr.w (a6)+
- add.b d0,d0
- bcc 13$
- move.w d4,(a1)+ ;01
- bra 14$
- 13$ move.w d3,(a1)+ ;00
- 14$ dbra d6,10$
-
- dbra d1,CharMLoop
- bra DoSprites
-
- ; Standard: 8 Pixel konvertieren
- CNOP 0,4
- StdInMulti moveq #7,d6
- 10$ add.b d0,d0
- bcc 11$
- move.b d2,(a1)+
- st.b (a6)+
- bra 12$
- 11$ move.b d3,(a1)+
- clr.b (a6)+
- 12$ dbra d6,10$
-
- dbra d1,CharMLoop
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- MOnlyBack move.l d3,(a1)+
- move.l d3,(a1)+
- clr.l (a6)+
- clr.l (a6)+
- addq.w #1,a3 ;Farb-RAM-Byte überspringen
- dbra d1,CharMLoop
- bra DoSprites
-
- *
- * Extended Color Mode: Grafikdaten holen und darstellen
- *
-
- TextECM add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
-
- move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
- add.w RC(a4),a0 ;RC dazunehmen
-
- move.b $21(a4),d3 ;d3: Hintergrund 0
- move.b $22(a4),d4 ;d4: Hintergrund 1
- move.b $23(a4),d5 ;d5: Hintergrund 2
-
- move.w LASTBKGD(a4),d0 ;Letzter Hintergrund, wenn X-Scroll>0
- move.b LASTBKGD(a4),d0
-
- move.w d0,Col40XStart(a5)
- move.w d0,Col40XStart+2(a5)
- move.w d0,Col40XStart+4(a5)
- move.w d0,Col40XStart+6(a5)
-
- ; Schleife für 40 Zeichen
- ; d7: Aktuelle Hintergrundfarbe
- moveq #39,d1 ;d1: Zeichenzähler
- moveq #0,d0
- CharELoop move.b (a2)+,d0 ;Zeichencode lesen
- move.b (a3)+,d2 ;d2: Farbnibble
- bclr #7,d0
- bne 1$
- bclr #6,d0
- bne 2$
- move.b d3,d7 ;00: Hintergrund 0
- bra 4$
- 2$ move.b d4,d7 ;01: Hintergrund 1
- bra 4$
- 1$ bclr #6,d0
- bne 3$
- move.b d5,d7 ;10: Hintergrund 2
- bra 4$
- 3$ move.b $24(a4),d7 ;11: Hintergrund 3
- 4$ move.b (a0,d0.w*8),d0 ;Zeichendaten lesen
- beq EOnlyBack
-
- ; 8 Pixel konvertieren
- moveq #7,d6
- 10$ add.b d0,d0
- bcc 11$
- move.b d2,(a1)+
- st.b (a6)+
- bra 12$
- 11$ move.b d7,(a1)+
- clr.b (a6)+
- 12$ dbra d6,10$
-
- dbra d1,CharELoop
-
- move.b d7,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
- move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- EOnlyBack move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- move.b d7,(a1)+
- clr.l (a6)+
- clr.l (a6)+
- dbra d1,CharELoop
- move.b d7,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
- move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
- bra DoSprites
-
- *
- * Standard-BitMap: Grafikdaten holen und darstellen
- *
-
- BitMapStd move.l BITMAPBASE(a4),a0 ;a0: Bitmap-Basis
- move.w VCCOUNT(a4),d0 ;VC holen
- lsl.w #3,d0 ;*8
- add.w RC(a4),d0 ;RC dazunehmen
- add.w d0,a0 ;und zur Bitmap-Basis dazunehmen
-
- add.w #40,VCCOUNT(a4) ;VC erhöhen
-
- move.w LASTBKGD(a4),d0 ;Letzter Hintergrund, wenn X-Scroll>0
- move.b LASTBKGD(a4),d0
-
- move.w d0,Col40XStart(a5)
- move.w d0,Col40XStart+2(a5)
- move.w d0,Col40XStart+4(a5)
- move.w d0,Col40XStart+6(a5)
-
- ; Schleife für 40 Bytes
- moveq #39,d1 ;d1: Zeichenzähler
- BitMapLoop move.b (a2)+,d2 ;Farbe holen
- move.b d2,d3 ;d3: Hintergrundfarbe
- move.b (a0),d0 ;Byte holen
- beq BOnlyBack
- lsr.b #4,d2 ;d2: Vordergrundfarbe
-
- ; 8 Pixel konvertieren
- moveq #7,d6
- 10$ add.b d0,d0
- bcc 11$
- move.b d2,(a1)+
- st.b (a6)+
- bra 12$
- 11$ move.b d3,(a1)+
- clr.b (a6)+
- 12$ dbra d6,10$
-
- addq.l #8,a0 ;Quellzeiger erhöhen
- dbra d1,BitMapLoop
-
- move.b d3,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- BOnlyBack move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- move.b d3,(a1)+
- clr.l (a6)+
- clr.l (a6)+
- addq.l #8,a0 ;Quellzeiger erhöhen
- dbra d1,BitMapLoop
- move.b d3,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
- bra DoSprites
-
- *
- * Multicolor-Bitmap: Grafikdaten holen und darstellen
- *
-
- BitMapMulti move.l BITMAPBASE(a4),a0 ;a0: Bitmap-Basis
- move.w VCCOUNT(a4),d0 ;VC holen
- lsl.w #3,d0 ;*8
- add.w RC(a4),d0 ;RC dazunehmen
- add.w d0,a0 ;und zur Bitmap-Basis dazunehmen
-
- add.w #40,VCCOUNT(a4) ;VC erhöhen
-
- move.l BACK0LONG(a4),d5 ;d5.w: Farbe 0
-
- move.l d5,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
- move.l d5,Col40XStart+4(a5)
-
- ; Schleife für 40 Bytes
- moveq #39,d1
- BitMapMLoop move.b (a2)+,d2 ;Farbe 1/2 holen
- move.b (a0),d0 ;Byte holen
- beq BMOnlyBack
- move.b d2,d3 ;d3.b: Farbe 2
- lsr.b #4,d2 ;d2.b: Farbe 1
- move.b (a3)+,d4 ;d4.b: Farbe 3
-
- ; 4 Pixel konvertieren
- moveq #3,d6
- 10$ add.b d0,d0
- bcc 11$
- add.b d0,d0
- bcc 12$
- move.b d4,(a1)+ ;11
- move.b d4,(a1)+
- st.b (a6)+
- st.b (a6)+
- bra 14$
- 12$ move.b d3,(a1)+ ;10
- move.b d3,(a1)+
- st.b (a6)+
- st.b (a6)+
- bra 14$
- 11$ clr.w (a6)+
- add.b d0,d0
- bcc 13$
- move.b d2,(a1)+ ;01
- move.b d2,(a1)+
- bra 14$
- 13$ move.w d5,(a1)+ ;00
- 14$ dbra d6,10$
-
- addq.l #8,a0 ;Quellzeiger erhöhen
- dbra d1,BitMapMLoop
- bra DoSprites
-
- ; Nur Hintergrund
- CNOP 0,4
- BMOnlyBack move.l d5,(a1)+
- move.l d5,(a1)+
- clr.l (a6)+
- clr.l (a6)+
- addq.w #1,a3 ;Farb-RAM-Byte überspringen
- addq.l #8,a0 ;Quellzeiger erhöhen
- dbra d1,BitMapMLoop
- bra DoSprites
-
- *
- * Ungültiger Darstellungsmodus: Schwarzen Bildschirm anzeigen
- *
-
- BlackScreen add.w #40,VCCOUNT(a4) ;VC erhöhen
-
- moveq #39,d0 ;40 Zeichen schwarz
- 1$ clr.l (a1)+
- clr.l (a1)+
- clr.l (a6)+
- clr.l (a6)+
- dbra d0,1$
- bra DoSprites
-
- *
- * $3FFF darstellen
- *
-
- Show3FFF move.l BACK0LONG(a4),d3 ;d3.w: Hintergrundfarbe
-
- move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
- move.l d3,Col40XStart+4(a5)
-
- btst #6,CTRL1(a4)
- bne 11$
- move.w #$3fff,d0 ;Byte bei $3FFF lesen
- bra 12$
- 11$ move.w #$39ff,d0 ;ECM: Byte bei $39FF lesen
- 12$ GetPhysical
- move.b (a0),d0 ;Byte lesen
-
- ; 4 Pixel nach d1 konvertieren, 0: Hintergrund, 1: schwarz
- moveq #0,d1
- add.b d0,d0
- bcs 1$
- move.b d3,d1
- 1$ lsl.w #8,d1
- add.b d0,d0
- bcs 2$
- move.b d3,d1
- 2$ lsl.l #8,d1
- add.b d0,d0
- bcs 3$
- move.b d3,d1
- 3$ lsl.l #8,d1
- add.b d0,d0
- bcs 4$
- move.b d3,d1
- 4$
-
- ; 4 Pixel nach d2 konvertieren
- moveq #0,d2
- add.b d0,d0
- bcs 5$
- move.b d3,d2
- 5$ lsl.w #8,d2
- add.b d0,d0
- bcs 6$
- move.b d3,d2
- 6$ lsl.l #8,d2
- add.b d0,d0
- bcs 7$
- move.b d3,d2
- 7$ lsl.l #8,d2
- add.b d0,d0
- bcs 8$
- move.b d3,d2
- 8$
-
- ; Zeile schreiben
- moveq #39,d0 ;d0: Bytezähler
- Loop3FFF move.l d1,(a1)+
- move.l d2,(a1)+
- clr.l (a6)+ ;Falsch!!
- clr.l (a6)+
- dbra d0,Loop3FFF
-
- *
- * Sprites malen?
- *
-
- DoSprites tst.b SPRITEON(a4) ;Ist überhaupt ein Sprite z.Z. sichtbar?
- beq DrawLRBorder ;Nein, dann Rahmen
-
- *
- * Mindestens ein Sprite ist sichtbar, Sprites malen
- *
-
- ; Kollisions-Puffer löschen
- lea SprCollBuf,a0
- moveq #DisplayX/4-1,d0
- 1$ clr.l (a0)+
- dbra d0,1$
-
- ; Sprites malen
- moveq #0,d4 ;Sprite-Grafik Kollisionsflag
- moveq #0,d5 ;Sprite-Sprite Kollisionsflag
- DoSprite 0
- DoSprite 1
- DoSprite 2
- DoSprite 3
- DoSprite 4
- DoSprite 5
- DoSprite 6
- DoSprite 7
- move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
-
- ; Kollisions-Flags auswerten
- tst.w Collisions
- beq DrawLRBorder
-
- move.b CLXSPR(a4),d0
- or.b d5,CLXSPR(a4) ;Bits im Kollisionsregister setzen
- tst.b d0 ;Haben bereits Kollisionen stattgefunden?
- bne 2$
- or.b #$04,IRQFLAG(a4) ;Nein, IMMC-Bit setzen
- btst #2,IRQMASK(a4) ;IRQ erlaubt?
- beq 2$
- or.b #$80,IRQFLAG(a4) ;Ja, IRQ-Bit setzen
- st.b IntIsVICIRQ ;Und Interrupt auslösen
-
- 2$ move.b CLXBGR(a4),d0
- or.b d4,CLXBGR(a4)
- tst.b d0
- bne DrawLRBorder
- or.b #$02,IRQFLAG(a4)
- btst #1,IRQMASK(a4)
- beq DrawLRBorder
- or.b #$80,IRQFLAG(a4)
- st.b IntIsVICIRQ
-
- *
- * Linken und rechten Rahmen zeichnen
- *
-
- ; 40-Spalten-Rahmen
- DrawLRBorder move.l a5,a0
- move.l BORDERLONG(a4),d0 ;d0.l: Rahmenfarbe
-
- move.l d0,(a0)+ ;Links: $00..$17
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
-
- lea Col40XStop-Col40XStart(a0),a0
- move.l d0,(a0)+ ;Rechts: $158..$16f
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)+
- move.l d0,(a0)
-
- ; 38-Spalten-Rahmen nach (a5) (Puffer oder Bitmap)
- tst.b IS38COL(a4)
- beq 1$
-
- lea Col40XStart(a5),a0
- move.l d0,(a0)+ ;Links: $18..$1e
- move.w d0,(a0)+
- move.b d0,(a0)
-
- lea Col38XStop(a5),a0
- move.b d0,(a0)+ ;Rechts: $14f..$157
- move.l d0,(a0)+
- move.l d0,(a0)+
- 1$
-
- *
- * Ende einer sichtbaren Zeile: Bei EGS/Picasso Zeile in die Karte schreiben.
- * Es wird nur der Bereich zwischen Col40XStart und Col40XStop geschrieben,
- * der Rest ist immer Rahmen und der wird in DrawLRBorder direkt in die
- * Bitmap geschrieben.
- *
-
- VICNext cmp.w #STYP_AMIGA,ScreenType
- beq VICIncA5
- cmp.w #STYP_CYBER,ScreenType
- beq VICNextCyber
- move.l CURRENTA5(a4),a1
- lea LineStore,a0
- moveq #DisplayX/4-1,d0
- 1$ move.l (a0)+,(a1)+
- dbra d0,1$
- bra VICIncA5
-
- VICNextCyber move.l _CyberGfxBase,a6
- lea CyberHook,a0
- move.l TheRastPort,a1
- sub.l a2,a2
- jsr DoCDrawMethod(a6)
- bra VICIncRC ;a5 nicht erhöhen (zeigt auf LineStore)!
-
- CyberHookProc move.l (a1),a0 ;a0: Adresse des Bildschirmspeichers
- moveq #0,d0
- move.w ScreenX,d0
- move.w Registers+CURRENTRASTER,d1
- sub.w #FirstDispLine,d1
- mulu.w d1,d0
- add.l d0,a0
- lea LineStore,a1
- moveq #DisplayX/4-1,d0
- 1$ move.l (a1)+,(a0)+
- dbra d0,1$
- rts
-
- *
- * Bild wird übersprungen, nur Bad-Line-Zyklen berechnen
- *
-
- VICSkip cmp.w #FirstDMALine,d7 ;Innerhalb des DMA-Bereiches?
- blo VICNop
- cmp.w #LastDMALine,d7
- bhi VICNop
-
- move.b d7,d0 ;Ja, stimmen die unteren Bits
- and.b #7,d0 ;der Rasterzeile mit dem Y-Scroll
- cmp.b YSCROLL+1(a4),d0 ;überein?
- bne VICNop
-
- move.w BadLineCycles,CyclesLeft
- bra VICNop
-
- *
- * Zeiger in Bitmap erhöhen
- *
-
- VICIncA5 moveq #0,d0
- move.w ScreenX,d0
- add.l d0,CURRENTA5(a4)
-
- *
- * RC erhöhen, Darstellung abschalten, wenn gleich 7
- * (braucht nur im sichtbaren Bereich zu geschehen)
- *
-
- VICIncRC cmp.w #7,RC(a4)
- beq 1$
- addq.w #1,RC(a4)
- bra 2$
- 1$ st.b DISPLAYOFF(a4)
- move.w VCCOUNT(a4),VCBASE(a4)
- 2$
-
- *
- * MCs erhöhen (muß in jeder Rasterzeile geschehen, damit die Sprites
- * auch im Overscan-Bereich korrekt dargestellt werden)
- *
-
- ; Wenn alle Sprites aus sind, direkt zu CIA-Periodic springen
- VICNop lea SPRITEON(a4),a3
- move.b (a3),d0
- or.b SPREN(a4),d0
- beq Periodic6526
-
- ; MC für jedes Sprite zählen (7..0)
- moveq #7,d6 ;d6: Spritenummer
- lea M7Y(a4),a1 ;a1: Zeiger auf erste Y-Koordinate
- lea MC7(a4),a2 ;a2: Zeiger auf MC
-
- MCLoop move.b (a1),d0 ;Y-Koordinate
- btst d6,SPREN(a4) ;Sprite angeschaltet?
- bne 1$
- 3$ cmp.w #60,(a2) ;Nein, MC kleiner als 60?
- blo 2$
- bclr d6,(a3) ;Nein, Sprite nicht mehr darstellen
- bra 5$
-
- 1$ cmp.b d0,d7 ;Sprite angeschaltet, Y-Koord. mit
- bne 3$
- clr.w (a2) ;Gleich, MC zurücksetzen
- bset d6,(a3) ;Und Sprite ab jetzt darstellen
- bra 5$
-
- 2$ btst d6,MYE(a4) ;MC kleiner als 60, Sprite Y-expandiert?
- beq 4$
- eor.b d7,d0 ;Ja, nur erhöhen, wenn Bit 0
- and.b #$01,d0 ; der Y-Koordinate gleich Bit 0
- bne 5$ ; des Rasterzählers ist
- 4$ addq.w #3,(a2) ;MC erhöhen
- subq.w #2,CyclesLeft ;2 Zyklen vom 6510 abziehen
-
- 5$ subq.w #2,a1 ;Zeiger auf Y-Koordinate erhöhen
- subq.w #2,a2 ;Zeiger auf MC erhöhen
- dbra d6,MCLoop
-
- ; Zu CIA-Periodic springen
- bra Periodic6526
-
-
- **
- ** Ein Sprite zeichnen
- ** d0.l: Spritedaten
- ** d1.w: X-Koordinate
- ** d2.b: Spritefarbe
- ** d3 : (Temp.)
- ** d4.b: Kollisionsergebnis Sprite-Hintergrund
- ** d5.b: Kollisionsergebnis Sprite-Sprite
- ** d6 : (Pixelzähler)
- ** d7.b: Sprite-Bit (1,2,4, ...)
- ** a1 : Ziel im Bildschirmspeicher
- ** a2 : Ziel im Kollisionspuffer
- ** a3 : Zeiger auf Grafik-Kollisionspuffer
- **
-
- CNOP 0,4
- ; Standard-Sprite: 3 Byte mit je 8 Pixeln konvertieren
- DrawSprStd cmp.w #DisplayX-24,d1 ;Sprite horizontal sichtbar?
- bhs DSSRts
-
- moveq #0,d6 ;Pixelzähler
- DSSLoop add.l d0,d0 ;Pixel gesetzt?
- bcc DSSNext
-
- tst.b (a3,d6.w) ;Ist hier schon Grafik?
- beq 1$
- or.b d7,d4 ;Ja, Kollision erkannt
-
- 1$ move.b (a2,d6.w),d1 ;Ist schon ein Sprite da?
- bne DSSDont
-
- move.b d2,(a1,d6.w) ;Nein, Punkt setzen
- move.b d7,(a2,d6.w)
- bra DSSNext
-
- DSSDont or.b d1,d5 ;Ja, Kollision erkannt zwischen bestehendem
- or.b d7,d5 ; und aktuellem Sprite
-
- DSSNext addq.w #1,d6
- cmp.w #24,d6
- bne DSSLoop
- DSSRts rts
-
- CNOP 0,4
- ; X-expandiertes Standard-Sprite: 3 Byte mit je 8 Pixeln konvertieren
- DrawSprStdExp cmp.w #DisplayX-48,d1
- bhs DSSERts
-
- moveq #0,d6
- DSSELoop add.l d0,d0
- bcc DSSENext
-
- tst.b (a3,d6.w)
- beq 1$
- or.b d7,d4
-
- 1$ move.b (a2,d6.w),d1
- bne DSSEDont1st
-
- move.b d2,(a1,d6.w)
- move.b d7,(a2,d6.w)
- bra DSSETest2nd
-
- DSSEDont1st or.b d1,d5
- or.b d7,d5
-
- DSSETest2nd tst.b 1(a3,d6.w)
- beq 1$
- or.b d7,d4
-
- 1$ move.b 1(a2,d6.w),d1
- bne DSSEDont2nd
-
- move.b d2,1(a1,d6.w)
- move.b d7,1(a2,d6.w)
- bra DSSENext
-
- DSSEDont2nd or.b d1,d5
- or.b d7,d5
-
- DSSENext addq.w #2,d6
- cmp.w #48,d6
- bne DSSELoop
- DSSERts rts
-
- CNOP 0,4
- ; Multicolor-Sprite: 3 Byte mit je 4 Pixeln konvertieren
- DrawSprMulti cmp.w #DisplayX-24,d1
- bhs DSMRts
-
- moveq #0,d6
- DSMLoop add.l d0,d0 ;Farbe des Pixels bestimmen
- bcc DSMFirstIs0
- add.l d0,d0
- bcc DSMDraw10
- move.b $26(a4),d3 ;11
- bra DSMDraw
- DSMDraw10 move.b d2,d3 ;10
- bra DSMDraw
- DSMFirstIs0 add.l d0,d0
- bcc DSMNext
- move.b $25(a4),d3 ;01
-
- DSMDraw tst.b (a3,d6.w)
- beq 1$
- or.b d7,d4
-
- 1$ move.b (a2,d6.w),d1
- bne DSMDont1st
-
- move.b d3,(a1,d6.w)
- move.b d7,(a2,d6.w)
- bra DSMTest2nd
-
- DSMDont1st or.b d1,d5
- or.b d7,d5
-
- DSMTest2nd tst.b 1(a3,d6.w)
- beq 1$
- or.b d7,d4
-
- 1$ move.b 1(a2,d6.w),d1
- bne DSMDont2nd
-
- move.b d3,1(a1,d6.w)
- move.b d7,1(a2,d6.w)
- bra DSMNext
-
- DSMDont2nd or.b d1,d5
- or.b d7,d5
-
- DSMNext addq.w #2,d6
- cmp.w #24,d6
- bne DSMLoop
- DSMRts rts
-
- CNOP 0,4
- ; X-expandiertes Multicolor-Sprite: 3 Byte mit je 4 Pixeln konvertieren
- DrawSprMultiExp cmp.w #DisplayX-48,d1
- bhs DSMERts
-
- moveq #0,d6
- DSMELoop add.l d0,d0
- bcc DSMEFirstIs0
- add.l d0,d0
- bcc DSMEDraw10
- move.b $26(a4),d3 ;11
- bra DSMEDraw
- DSMEDraw10 move.b d2,d3 ;10
- bra DSMEDraw
- DSMEFirstIs0 add.l d0,d0
- bcc DSMENext
- move.b $25(a4),d3 ;01
-
- DSMEDraw tst.b (a3,d6.w)
- beq 1$
- or.b d7,d4
-
- 1$ move.b (a2,d6.w),d1
- bne DSMEDont1st
-
- move.b d3,(a1,d6.w)
- move.b d7,(a2,d6.w)
- bra DSMETest2nd
-
- DSMEDont1st or.b d1,d5
- or.b d7,d5
-
- DSMETest2nd tst.b 1(a3,d6.w)
- beq 1$
- or.b d7,d4
-
- 1$ move.b 1(a2,d6.w),d1
- bne DSMEDont2nd
-
- move.b d3,1(a1,d6.w)
- move.b d7,1(a2,d6.w)
- bra DSMETest3rd
-
- DSMEDont2nd or.b d1,d5
- or.b d7,d5
-
- DSMETest3rd tst.b 2(a3,d6.w)
- beq 1$
- or.b d7,d4
-
- 1$ move.b 2(a2,d6.w),d1
- bne DSMEDont3rd
-
- move.b d3,2(a1,d6.w)
- move.b d7,2(a2,d6.w)
- bra DSMETest4th
-
- DSMEDont3rd or.b d1,d5
- or.b d7,d5
-
- DSMETest4th tst.b 3(a3,d6.w)
- beq 1$
- or.b d7,d4
-
- 1$ move.b 3(a2,d6.w),d1
- bne DSMEDont4th
-
- move.b d3,3(a1,d6.w)
- move.b d7,3(a2,d6.w)
- bra DSMENext
-
- DSMEDont4th or.b d1,d5
- or.b d7,d5
-
- DSMENext addq.w #4,d6
- cmp.w #48,d6
- bne DSMELoop
- DSMERts rts
-
- CNOP 0,4
- ; Standard-Sprite im Hintergrund: 3 Byte mit je 8 Pixeln konvertieren
- DrawBackStd cmp.w #DisplayX-24,d1 ;Sprite horizontal sichtbar?
- bhs DBSRts
-
- moveq #0,d6 ;Pixelzähler
- DBSLoop add.l d0,d0 ;Pixel gesetzt?
- bcc DBSNext
-
- tst.b (a3,d6.w) ;Ist hier schon Grafik?
- beq 1$
- or.b d7,d4 ;Ja, Kollision erkannt
- move.b (a2,d6.w),d1 ;Ist schon ein Sprite da?
- beq DBSNext
- or.b d1,d5 ;Ja, Kollision erkannt
- or.b d7,d5
- bra DBSNext ;Sprite nicht zeichnen
-
- 1$ move.b (a2,d6.w),d1 ;Ja, ist schon ein Sprite da?
- bne DBSDont
-
- move.b d2,(a1,d6.w) ;Nein, Punkt setzen
- move.b d7,(a2,d6.w)
- bra DBSNext
-
- DBSDont or.b d1,d5 ;Ja, Kollision erkannt zwischen bestehendem
- or.b d7,d5 ; und aktuellem Sprite
-
- DBSNext addq.w #1,d6
- cmp.w #24,d6
- bne DBSLoop
- DBSRts rts
-
- CNOP 0,4
- ; X-expandiertes Standard-Sprite im Hintergrund: 3 Byte mit je 8 Pixeln konvertieren
- DrawBackStdExp cmp.w #DisplayX-48,d1
- bhs DBSERts
-
- moveq #0,d6
- DBSELoop add.l d0,d0
- bcc DBSENext
-
- tst.b (a3,d6.w)
- beq 1$
- or.b d7,d4
- move.b (a2,d6.w),d1
- beq DBSETest2nd
- or.b d1,d5
- or.b d7,d5
- bra DBSETest2nd
-
- 1$ move.b (a2,d6.w),d1
- bne DBSEDont1st
-
- move.b d2,(a1,d6.w)
- move.b d7,(a2,d6.w)
- bra DBSETest2nd
-
- DBSEDont1st or.b d1,d5
- or.b d7,d5
-
- DBSETest2nd tst.b 1(a3,d6.w)
- beq 1$
- or.b d7,d4
- move.b 1(a2,d6.w),d1
- beq DBSENext
- or.b d1,d5
- or.b d7,d5
- bra DBSENext
-
- 1$ move.b 1(a2,d6.w),d1
- bne DBSEDont2nd
-
- move.b d2,1(a1,d6.w)
- move.b d7,1(a2,d6.w)
- bra DBSENext
-
- DBSEDont2nd or.b d1,d5
- or.b d7,d5
-
- DBSENext addq.w #2,d6
- cmp.w #48,d6
- bne DBSELoop
- DBSERts rts
-
- CNOP 0,4
- ; Multicolor-Sprite im Hintergrund: 3 Byte mit je 4 Pixeln konvertieren
- DrawBackMulti cmp.w #DisplayX-24,d1
- bhs DBMRts
-
- moveq #0,d6
- DBMLoop add.l d0,d0 ;Farbe des Pixels bestimmen
- bcc DBMFirstIs0
- add.l d0,d0
- bcc DBMDraw10
- move.b $26(a4),d3 ;11
- bra DBMDraw
- DBMDraw10 move.b d2,d3 ;10
- bra DBMDraw
- DBMFirstIs0 add.l d0,d0
- bcc DBMNext
- move.b $25(a4),d3 ;01
-
- DBMDraw tst.b (a3,d6.w)
- beq 1$
- or.b d7,d4
- move.b (a2,d6.w),d1
- beq DBMTest2nd
- or.b d1,d5
- or.b d7,d5
- bra DBMTest2nd
-
- 1$ move.b (a2,d6.w),d1
- bne DBMDont1st
-
- move.b d3,(a1,d6.w)
- move.b d7,(a2,d6.w)
- bra DBMTest2nd
-
- DBMDont1st or.b d1,d5
- or.b d7,d5
-
- DBMTest2nd tst.b 1(a3,d6.w)
- beq 1$
- or.b d7,d4
- move.b 1(a2,d6.w),d1
- beq DBMNext
- or.b d1,d5
- or.b d7,d5
- bra DBMNext
-
- 1$ move.b 1(a2,d6.w),d1
- bne DBMDont2nd
-
- move.b d3,1(a1,d6.w)
- move.b d7,1(a2,d6.w)
- bra DBMNext
-
- DBMDont2nd or.b d1,d5
- or.b d7,d5
-
- DBMNext addq.w #2,d6
- cmp.w #24,d6
- bne DBMLoop
- DBMRts rts
-
- CNOP 0,4
- ; X-expandiertes Multicolor-Sprite im Hintergrund: 3 Byte mit je 4 Pixeln konvertieren
- DrawBackMultiExp cmp.w #DisplayX-48,d1
- bhs DBMERts
-
- moveq #0,d6
- DBMELoop add.l d0,d0
- bcc DBMEFirstIs0
- add.l d0,d0
- bcc DBMEDraw10
- move.b $26(a4),d3 ;11
- bra DBMEDraw
- DBMEDraw10 move.b d2,d3 ;10
- bra DBMEDraw
- DBMEFirstIs0 add.l d0,d0
- bcc DBMENext
- move.b $25(a4),d3 ;01
-
- DBMEDraw tst.b (a3,d6.w)
- beq 1$
- or.b d7,d4
- move.b (a2,d6.w),d1
- beq DBMETest2nd
- or.b d1,d5
- or.b d7,d5
- bra DBMETest2nd
-
- 1$ move.b (a2,d6.w),d1
- bne DBMEDont1st
-
- move.b d3,(a1,d6.w)
- move.b d7,(a2,d6.w)
- bra DBMETest2nd
-
- DBMEDont1st or.b d1,d5
- or.b d7,d5
-
- DBMETest2nd tst.b 1(a3,d6.w)
- beq 1$
- or.b d7,d4
- move.b 1(a2,d6.w),d1
- beq DBMETest3rd
- or.b d1,d5
- or.b d7,d5
- bra DBMETest3rd
-
- 1$ move.b 1(a2,d6.w),d1
- bne DBMEDont2nd
-
- move.b d3,1(a1,d6.w)
- move.b d7,1(a2,d6.w)
- bra DBMETest3rd
-
- DBMEDont2nd or.b d1,d5
- or.b d7,d5
-
- DBMETest3rd tst.b 2(a3,d6.w)
- beq 1$
- or.b d7,d4
- move.b 2(a2,d6.w),d1
- beq DBMETest4th
- or.b d1,d5
- or.b d7,d5
- bra DBMETest4th
-
- 1$ move.b 2(a2,d6.w),d1
- bne DBMEDont3rd
-
- move.b d3,2(a1,d6.w)
- move.b d7,2(a2,d6.w)
- bra DBMETest4th
-
- DBMEDont3rd or.b d1,d5
- or.b d7,d5
-
- DBMETest4th tst.b 3(a3,d6.w)
- beq 1$
- or.b d7,d4
- move.b 3(a2,d6.w),d1
- beq DBMENext
- or.b d1,d5
- or.b d7,d5
- bra DBMENext
-
- 1$ move.b 3(a2,d6.w),d1
- bne DBMEDont4th
-
- move.b d3,3(a1,d6.w)
- move.b d7,3(a2,d6.w)
- bra DBMENext
-
- DBMEDont4th or.b d1,d5
- or.b d7,d5
-
- DBMENext addq.w #4,d6
- cmp.w #48,d6
- bne DBMELoop
- DBMERts rts
-
-
- **
- ** Amiga-Mono-Routinen einbinden
- **
-
- INCLUDE "6569mono.i"
-
-
- **
- ** Konstanten
- **
-
- ; Strings
- EGSName dc.b "egs.library",0
- VilIntuiName dc.b "vilintuisup.library",0
- CyberGfxName dc.b "cybergraphics.library",0
-
- ; Farbpalette
- CNOP 0,4
- Palette dc.b 0,0,0,0 ;Schwarz
- dc.b 255,255,255,0 ;Weiß
- dc.b 204,0,0,0 ;Rot
- dc.b 0,255,204,0 ;Cyan
- dc.b 255,0,255,0 ;Magenta
- dc.b 0,204,0,0 ;Grün
- dc.b 0,0,204,0 ;Blau
- dc.b 255,255,0,0 ;Gelb
- dc.b 255,128,0,0 ;Orange
- dc.b 128,64,0,0 ;Braun
- dc.b 255,128,128,0 ;Hellrot
- dc.b 64,64,64,0 ;Dunkelgrau
- dc.b 128,128,128,0 ;Mittelgrau
- dc.b 128,255,128,0 ;Hellgrün
- dc.b 128,128,255,0 ;Hellblau
- dc.b 192,192,192,0 ;Hellgrau
-
- ; Tabelle der Display-Routinen (jeweils für Farbe und Monochrom)
- DispProcTab dc.l TextStd
- dc.l TextMulti
- dc.l BitMapStd
- dc.l BitMapMulti
- dc.l TextECM
- dc.l BlackScreen
- dc.l BlackScreen
- dc.l BlackScreen
-
- MonoDispProcTab dc.l FTextStd
- dc.l FTextStd
- dc.l FBitMapStd
- dc.l FBitMapStd
- dc.l FTextStd
- dc.l FBlackScreen
- dc.l FBlackScreen
- dc.l FBlackScreen
-
- ; Tabelle der Sprite-Display-Routinen
- SpriteProcTab dc.l DrawSprStd
- dc.l DrawSprStdExp
- dc.l DrawSprMulti
- dc.l DrawSprMultiExp
- dc.l DrawBackStd
- dc.l DrawBackStdExp
- dc.l DrawBackMulti
- dc.l DrawBackMultiExp
-
-
- **
- ** Datenbereich
- **
-
- ; Taglist für den Screen (Amiga)
- ScreenTags dc.l SA_DisplayID
- ScreenDID dc.l 0
- dc.l SA_Width,$180 ;Vielfaches von 32
- dc.l SA_Height,DisplayY
- dc.l SA_Depth,4
- dc.l SA_Quiet,-1
- dc.l SA_AutoScroll,-1
- dc.l SA_Overscan
- ScreenOScan dc.l 0
- dc.l 0,0
-
- ; Taglist für den Screen (Amiga-Mono)
- MonoScreenTags dc.l SA_DisplayID
- MonoScreenDID dc.l 0
- dc.l SA_Width,$180
- dc.l SA_Height,DisplayY
- dc.l SA_Depth,1
- dc.l SA_Quiet,-1
- dc.l SA_AutoScroll,-1
- dc.l SA_Overscan
- MonoScreenOScan dc.l 0
- dc.l 0,0
-
- ; Taglist für den Screen (Cyber)
- CyberScreenTags dc.l SA_DisplayID
- CyberScreenDID dc.l 0
- dc.l SA_Width
- CyberScreenX dc.l 0
- dc.l SA_Height
- CyberScreenY dc.l 0
- dc.l SA_Depth,8
- dc.l SA_Quiet,-1
- dc.l 0,0
-
- ; Taglist für das Fenster (Picasso/Amiga/Cyber)
- WindowTags dc.l WA_Left,0
- dc.l WA_Top,0
- dc.l WA_Width
- WindowWidth dc.l 0
- dc.l WA_Height
- WindowHeight dc.l 0
- dc.l WA_NoCareRefresh,-1
- dc.l WA_Borderless,-1
- dc.l WA_Activate,-1
- dc.l WA_RMBTrap,-1
- dc.l WA_CustomScreen
- WindowScreen dc.l 0
- dc.l WA_IDCMP,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY
- dc.l 0,0
-
- ; Struktur für E_OpenScreen (EGS)
- NewEScreen dc.l ModeNameBuf+16
- dc.w 8,0 ;Tiefe 8
- dc.l 0
- dc.l 0
- dc.l 0
- dc.l 0
- dc.l E_eMOUSEBUTTONS|E_eRAWKEY
- dc.l 0
-
- ; Taglist für den Screen (Picasso)
- VilTags dc.l TAVIS_DM_STRUCT,Dimensions
- dc.l TAVIS_DOUBLE_BUFFER,-1
- dc.l 0,0
-
- ; VilIntuiSup-Dimensions (Picasso)
- Dimensions dc.w 0,0,0,0,8,0 ;8: Tiefe
-
- ; Hook für Cybergraphics
- CyberHook dc.l 0,0
- dc.l CyberHookProc
- dc.l 0
- dc.l 0
-
- ; Variablen
- CNOP 0,4
- DisplayID dc.l 0 ;Prefs: DisplayID des Screens
- TheScreen dc.l 0 ;Screen
- TheWindow dc.l 0 ;Window (Picasso/Amiga/Cyber)
- EGSPort dc.l 0 ;EDCMP-Port (EGS)
- WindowPort dc.l 0 ;IDCMP-Port (Amiga/Picasso/Cyber)
- TheRastPort dc.l 0 ;RastPort (Amiga/Cyber)
- TheViewPort dc.l 0 ;ViewPort (Amiga/Picasso/Cyber)
- VBlankProc dc.l 0 ;Zeiger auf VBlank-Routine
- DisplayProc dc.l 0 ;Zeiger auf die Display-Routine (Text/Bitmap etc.)
-
- Sprite0Proc dc.l 0 ;Zeiger auf Display-Routinen für die einzelnen Sprites
- Sprite1Proc dc.l 0
- Sprite2Proc dc.l 0
- Sprite3Proc dc.l 0
- Sprite4Proc dc.l 0
- Sprite5Proc dc.l 0
- Sprite6Proc dc.l 0
- Sprite7Proc dc.l 0
-
- InvisibleMap dc.l 0 ;Zeiger auf unsichtbare BitMap (EGS)
- ;Zeiger auf Chunky-Map (Amiga)
- ;Zeiger auf Bitplane (AmigaMono ohne DB)
- InvBufNum dc.l 0 ;Nummer des unsichtbaren Puffers (Amiga/Picasso)
- ScrBuf0 dc.l 0 ;Screen Buffer 0 (Amiga) - Muß zusammen bleiben!
- ScrBuf1 dc.l 0 ;Screen Buffer 1 (Amiga) /
-
- ComparisonBuf dc.l 0 ;Puffer für c2p4 - Muß zusammen bleiben!
- ComparisonBuf1 dc.l 0 ;Zweiter Puffer /
- GfxSet dc.l 0 ;Signal für c2p4
- GfxSig dc.w 0
-
- ScreenType dc.w 0 ;Prefs: Typ der Screen-Ansteuerung
- NormalCycles dc.w 0 ;Prefs: Anzahl 6510-Zyklen pro Rasterzeile
- BadLineCycles dc.w 0 ;Prefs: Anzahl 6510-Zyklen in einer Bad Line
- Collisions dc.w 0 ;Prefs: Sprite-Kollisionen angeschaltet
- Overscan dc.w 0 ;Prefs: Overscan-Typ für Amiga-Modi
-
- CiaVABase dc.w 0 ;16-Bit Basisadresse durch Cia-VA14/15
- ScreenX dc.w 0 ;Ausmaße des Screens
- ScreenY dc.w 0
- MustWaitForC2P dc.w 0 ;Es muß auf das Signal von c2p gewartet werden
- UsingDB dc.w 0 ;Flag: Double Buffering wird benutzt
-
- SkipCounter dc.w 1
- SkipLatch dc.w 0 ;Prefs: Nur jedes nte Bild darstellen
-
- CNOP 0,4
- Registers ds.b VICRegLength ;VIC-Register
- MatrixLine ds.b 40 ;Eine Bildschirmzeile
- ColorLine ds.b 40 ;Eine Farb-RAM-Zeile
-
- **
- ** Nicht initialisierte Daten
- **
-
- SECTION "BSS",BSS
- LineStore ds.b DisplayX ;Puffer für eine Zeile
- SprCollBuf ds.b DisplayX ;Puffer für Sprite-Sprite-Kollisionen
- GfxCollBuf ds.b DisplayX ;Puffer für Sprite-Grafik-Kollisionen und Priorität
-
- ModeNameBuf ds.b nif_SIZEOF ;Puffer für GetDisplayInfoData
- TheRect ds.b ra_SIZEOF ;Puffer für QueryOverscan
- END
-