* * 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 "hrg/hrgsystem.i" INCLUDE "devices/inputevent.i" XREF _SysBase ;Main.asm XREF _GfxBase XREF _IntuitionBase XREF _EGSBase XREF _VilIntuiBase XREF _CyberGfxBase XREF _HRGSystemBase XREF TurboCyber 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 STYP_MERLIN = 5 ; 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 ; HRG hrLockBitMap = -78 hrUnlockBitMap = -84 hrOpenScreenTagList = -90 hrCloseScreen = -96 hrGetRGBA = -108 hrSetRGB8 = -114 hrSwitchCursor = -216 * * 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 ** d0=9 Kein HRG ** ; 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/Merlin: 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/Merlin) cmp.w #STYP_EGS,ScreenType beq OpenEGS cmp.w #STYP_CYBER,ScreenType beq OpenCyber cmp.w #STYP_MERLIN,ScreenType beq OpenMerlin 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$ ; Ohne Turbo alles nach LineStore schreiben, sonst das meiste direkt ; in den Bildschirmspeicher tst.l TurboCyber bne 3$ move.l #LineStore,Registers+CURRENTA5 bra 4$ 3$ move.l _CyberGfxBase,a6 move.l TheRastPort,a0 move.l rp_BitMap(a0),a0 move.l #CYBRMATTR_DISPADR,d0 jsr GetCyberMapAttr(a6) move.l d0,InvisibleMap move.l d0,Registers+CURRENTA5 ; VBlank-Routine setzen 4$ move.l #CyberVBlank,VBlankProc moveq #0,d0 rts * * Merlin-Screen öffnen * ; hrgsystem.library öffnen OpenMerlin move.l _SysBase,a6 moveq #38,d0 lea HRGSystemName,a1 JSRLIB OpenLibrary move.l d0,_HRGSystemBase beq NoHRGSystem ; Screen öffnen move.w ScreenX,d0 move.w ScreenY,d1 move.w d0,WindowWidth+2 move.w d1,WindowHeight+2 move.w d0,HRGScrWidth+2 move.w d1,HRGScrHeight+2 move.l _HRGSystemBase,a6 lea HRGScreenTags,a0 jsr hrOpenScreenTagList(a6) move.l d0,MerlScreen beq NoScreen move.l d0,a0 move.l hrh_IScr(a0),a0 move.l a0,WindowScreen move.l a0,TheScreen ; 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 _HRGSystemBase,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 MerlScreen,a0 jsr hrSetRGB8(a6) addq.b #1,d7 bne 1$ ; Adresse des Bildschirmspeichers setzen move.l MerlScreen,a0 lea hrh_BitMap(a0),a2 move.l a2,a0 jsr hrLockBitMap(a6) move.l d0,InvisibleMap move.l d0,Registers+CURRENTA5 move.l a2,a0 jsr hrUnlockBitMap(a6) ; VBlank-Routine setzen move.l #MerlinVBlank,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 NoHRGSystem moveq #9,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 cmp.w #STYP_MERLIN,ScreenType beq CloseMerlin ; 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 ; Merlin CloseMerlin move.l _IntuitionBase,a6 move.l TheWindow,d0 beq 1$ move.l d0,a0 JSRLIB CloseWindow 1$ move.l _HRGSystemBase,a6 move.l MerlScreen,d0 beq 2$ move.l d0,a0 jsr hrCloseScreen(a6) 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/Merlin 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/Merlin 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/Merlin 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: Bei TurboCyber a5 neu laden CyberVBlank tst.l TurboCyber beq Periodic6569 move.l InvisibleMap,CURRENTA5(a4) bra Periodic6569 ; Merlin: a5 neu laden MerlinVBlank move.l InvisibleMap,CURRENTA5(a4) 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 dc.l GetA5Merlin GetA5AmigaMono move.l CURRENTA5(a4),a5 ;Amiga-Mono: In die Bitplane schreiben bra AmigaMono6569 ; und in spezielle VIC-Routine springen GetA5EGS GetA5Picasso GetA5Cyber GetA5Merlin lea LineStore,a5 ;EGS/Picasso/Cyber/Merlin: 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 bne VICIncA5 ;Sonst nix tst.l TurboCyber bne VICIncA5 bra VICNextCyber 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 VICNextCopyLine move.l CURRENTA5(a4),a1 lea LineStore,a0 moveq #DisplayX/4-1,d0 1$ move.l (a0)+,(a1)+ dbra d0,1$ bra VICIncA5 VICNextCyber tst.l TurboCyber bne VICNextCopyLine 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 20(a1),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 HRGSystemName dc.b "hrgsystem.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 den Screen (Merlin) HRGScreenTags dc.l HTOS_BitMapType,HRCOL_PACKED8 dc.l HTOS_Width HRGScrWidth dc.l 0 dc.l HTOS_Height HRGScrHeight dc.l 0 dc.l HTOS_Active,-1 dc.l HTOS_MatchModeInfo,-1 dc.l HTOS_EazyScreen,HRES_SIMPLE 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 MerlScreen dc.l 0 ;Merlin-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) ;Zeiger auf Bildschirmspeicher (TurboCyber) ;Zeiger auf Bildschirmspeicher (Merlin) 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