home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Brotikasten
/
BROTCD01.iso
/
amiga
/
frodov13.lha
/
src
/
6569.asm
< prev
next >
Wrap
Assembly Source File
|
1995-02-22
|
65KB
|
3,223 lines
*
* 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.
*
* 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
* - Keine Sprite-Grafik-PrioritΣt
* - Keine Sprite-Hintergrund-Kollisionen
* - Sprite-Sprite-Kollisionen werden nur innerhalb des sichtbaren
* Bereiches 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 "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 DontPause
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
M0X = $00 ;Position von Sprite 0
M0Y = $01
M1X = $02 ;Position von Sprite 1
M1Y = $03
M2X = $04 ;Position von Sprite 2
M2Y = $05
M3X = $06 ;Position von Sprite 3
M3Y = $07
M4X = $08 ;Position von Sprite 4
M4Y = $09
M5X = $0a ;Position von Sprite 5
M5Y = $0b
M6X = $0c ;Position von Sprite 6
M6Y = $0d
M7X = $0e ;Position von Sprite 7
M7Y = $0f
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
MMC = $1c ;Sprite Multicolor
MXE = $1d ;Sprite X-Expansion
CLXSPR = $1e ;Kollisionsreg.
CLXBGR = $1f
; 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
BACK0LONG = $70
BACK1LONG = $74
; 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
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
moveq #\1,d6 ;d6: Spritenummer
btst d6,SPRITEON(a4) ;Wird das Sprite dargestellt?
beq \@1$
move.w $27+\1(a4),d2
move.b $27+\1(a4),d2 ;d2.w: Spritefarbe
move.w MC\1(a4),d5 ;d5: DatenzΣhler
move.l MATRIXBASE(a4),a0
move.b $03f8+\1(a0),d7 ;d7: Datenzeiger
lea M\1X(a4),a2 ;a2: Zeiger auf X-Koordinate
bsr DrawSprite
\@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
**
; Kollisionsflag-Tabelle berechnen
OpenGraphics lea SprCollTab,a0 ;Vorgabe: Kollision
moveq #256/4-1,d0
1$ move.l #-1,(a0)+
dbra d0,1$
lea SprCollTab,a0 ;Keine Kollision bei nur einem Sprite
clr.w (a0)
clr.b 2(a0)
clr.b 4(a0)
clr.b 8(a0)
clr.b 16(a0)
clr.b 32(a0)
clr.b 64(a0)
clr.b 128(a0)
; Name des ScreenMode holen
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.l #TextStd,DisplayProc
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)
; 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 und erste Display-Proc setzen
move.l #AmigaMonoVBlank,VBlankProc
move.l #FTextStd,DisplayProc
; 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 cmp.w #STYP_EGS,ScreenType
beq ATFEGS
; Amiga/Picasso/Cyber
move.l a6,-(sp)
move.l _IntuitionBase,a6
move.l TheScreen,a0
JSRLIB ScreenToBack
move.l (sp)+,a6
rts
; EGS
ATFEGS move.l a6,-(sp)
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 cmp.w #STYP_EGS,ScreenType
beq ETFEGS
; Amiga/Picasso/Cyber
move.l a6,-(sp)
move.l _IntuitionBase,a6
move.l TheScreen,a0
JSRLIB ScreenToFront
move.l (sp)+,a6
rts
; EGS
ETFEGS move.l a6,-(sp)
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
JSRLIB FreeSignal
rts
**
** 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 RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
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
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
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
**
** 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 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 WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
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 WrNormal
dc.l WrNormal
dc.l WrNormal
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
WrBorder move.b d1,(a0,d0.w)
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,(a0,d0.w)
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
WrNormal move.b d1,(a0,d0.w)
WrUndef 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
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
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
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
**
** 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.w #-1,DontPause ;Nicht hier anhalten
move.l a6,-(sp)
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)
move.l (sp)+,a6
clr.w DontPause ;Darf wieder angehalten werden
bra Periodic6569
; Cybergraphics: Nichts
CyberVBlank bra Periodic6569
; Amiga: Chunky-BitMap in Planar konvertieren
AmigaVBlank move.w #-1,DontPause ;Nicht hier anhalten
movem.l a4-a6,-(sp)
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 ;Kein DB: 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
movem.l (sp)+,a4-a6
move.l InvisibleMap,CURRENTA5(a4)
move.w #-1,MustWaitForC2P
clr.w DontPause ;Darf wieder angehalten werden
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
movem.l (sp)+,a4-a6
move.l InvisibleMap,CURRENTA5(a4)
move.w #-1,MustWaitForC2P
clr.w DontPause ;Darf wieder angehalten werden
bra Periodic6569
; Amiga-Mono: Double Buffering
AmigaMonoVBlank tst.w UsingDB(pc) ;Double Buffering?
beq 1$
move.w #-1,DontPause ;Ja, Puffer tauschen
move.l a6,-(sp)
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)
move.l (sp)+,a6
clr.w DontPause
bra Periodic6569
1$ move.l InvisibleMap,CURRENTA5(a4) ;Kein DB
bra Periodic6569
; Picasso: Double Buffering
PicassoVBlank move.w #-1,DontPause ;Nicht hier anhalten
move.l a6,-(sp)
move.l _VilIntuiBase(pc),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)
move.l (sp)+,a6
clr.w DontPause ;Darf wieder angehalten werden
;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
tst.b DISPLAYOFF(a4) ;$3FFF darstellen?
bne Show3FFF
move.l DisplayProc,a0 ;Nein, Routine entsprechend
jmp (a0) ;dem Darstellungsmodus 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
add.b d0,d0
bcc 11$
move.b d2,(a1)+
bra 12$
11$ move.b d3,(a1)+
12$ add.b d0,d0
bcc 21$
move.b d2,(a1)+
bra 22$
21$ move.b d3,(a1)+
22$ add.b d0,d0
bcc 31$
move.b d2,(a1)+
bra 32$
31$ move.b d3,(a1)+
32$ add.b d0,d0
bcc 41$
move.b d2,(a1)+
bra 42$
41$ move.b d3,(a1)+
42$ add.b d0,d0
bcc 51$
move.b d2,(a1)+
bra 52$
51$ move.b d3,(a1)+
52$ add.b d0,d0
bcc 61$
move.b d2,(a1)+
bra 62$
61$ move.b d3,(a1)+
62$ add.b d0,d0
bcc 71$
move.b d2,(a1)+
bra 72$
71$ move.b d3,(a1)+
72$ add.b d0,d0
bcc 81$
move.b d2,(a1)+
bra 82$
81$ move.b d3,(a1)+
82$ dbra d1,CharLoop
bra DoSprites
; Nur Hintergrund
CNOP 0,4
OnlyBack move.l d3,(a1)+
move.l d3,(a1)+
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
add.b d0,d0
bcc 11$
add.b d0,d0
bcc 12$
move.b d2,(a1)+ ;11
move.b d2,(a1)+
bra 20$
12$ move.w d5,(a1)+ ;10
bra 20$
11$ add.b d0,d0
bcc 13$
move.w d4,(a1)+ ;01
bra 20$
13$ move.w d3,(a1)+ ;00
20$ add.b d0,d0
bcc 21$
add.b d0,d0
bcc 22$
move.b d2,(a1)+
move.b d2,(a1)+
bra 30$
22$ move.w d5,(a1)+
bra 30$
21$ add.b d0,d0
bcc 23$
move.w d4,(a1)+
bra 30$
23$ move.w d3,(a1)+
30$ add.b d0,d0
bcc 31$
add.b d0,d0
bcc 32$
move.b d2,(a1)+
move.b d2,(a1)+
bra 40$
32$ move.w d5,(a1)+
bra 40$
31$ add.b d0,d0
bcc 33$
move.w d4,(a1)+
bra 40$
33$ move.w d3,(a1)+
40$ add.b d0,d0
bcc 41$
add.b d0,d0
bcc 42$
move.b d2,(a1)+
move.b d2,(a1)+
bra 50$
42$ move.w d5,(a1)+
bra 50$
41$ add.b d0,d0
bcc 43$
move.w d4,(a1)+
bra 50$
43$ move.w d3,(a1)+
50$ dbra d1,CharMLoop
bra DoSprites
; Standard: 8 Pixel konvertieren
CNOP 0,4
StdInMulti add.b d0,d0
bcc 11$
move.b d2,(a1)+
bra 12$
11$ move.b d3,(a1)+
12$ add.b d0,d0
bcc 21$
move.b d2,(a1)+
bra 22$
21$ move.b d3,(a1)+
22$ add.b d0,d0
bcc 31$
move.b d2,(a1)+
bra 32$
31$ move.b d3,(a1)+
32$ add.b d0,d0
bcc 41$
move.b d2,(a1)+
bra 42$
41$ move.b d3,(a1)+
42$ add.b d0,d0
bcc 51$
move.b d2,(a1)+
bra 52$
51$ move.b d3,(a1)+
52$ add.b d0,d0
bcc 61$
move.b d2,(a1)+
bra 62$
61$ move.b d3,(a1)+
62$ add.b d0,d0
bcc 71$
move.b d2,(a1)+
bra 72$
71$ move.b d3,(a1)+
72$ add.b d0,d0
bcc 81$
move.b d2,(a1)+
bra 82$
81$ move.b d3,(a1)+
82$ dbra d1,CharMLoop
bra DoSprites
; Nur Hintergrund
CNOP 0,4
MOnlyBack move.l d3,(a1)+
move.l d3,(a1)+
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.b $24(a4),d6 ;d6: Hintergrund 3
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
move.w d7,-(sp) ;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 d6,d7 ;11: Hintergrund 3
4$ move.b (a0,d0.w*8),d0 ;Zeichendaten lesen
beq EOnlyBack
; 8 Pixel konvertieren
add.b d0,d0
bcc 11$
move.b d2,(a1)+
bra 12$
11$ move.b d7,(a1)+
12$ add.b d0,d0
bcc 21$
move.b d2,(a1)+
bra 22$
21$ move.b d7,(a1)+
22$ add.b d0,d0
bcc 31$
move.b d2,(a1)+
bra 32$
31$ move.b d7,(a1)+
32$ add.b d0,d0
bcc 41$
move.b d2,(a1)+
bra 42$
41$ move.b d7,(a1)+
42$ add.b d0,d0
bcc 51$
move.b d2,(a1)+
bra 52$
51$ move.b d7,(a1)+
52$ add.b d0,d0
bcc 61$
move.b d2,(a1)+
bra 62$
61$ move.b d7,(a1)+
62$ add.b d0,d0
bcc 71$
move.b d2,(a1)+
bra 72$
71$ move.b d7,(a1)+
72$ add.b d0,d0
bcc 81$
move.b d2,(a1)+
bra 82$
81$ move.b d7,(a1)+
82$ dbra d1,CharELoop
move.b d7,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
move.w (sp)+,d7
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)+
dbra d1,CharELoop
move.b d7,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
move.w (sp)+,d7
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
add.b d0,d0
bcc 11$
move.b d2,(a1)+
bra 12$
11$ move.b d3,(a1)+
12$ add.b d0,d0
bcc 21$
move.b d2,(a1)+
bra 22$
21$ move.b d3,(a1)+
22$ add.b d0,d0
bcc 31$
move.b d2,(a1)+
bra 32$
31$ move.b d3,(a1)+
32$ add.b d0,d0
bcc 41$
move.b d2,(a1)+
bra 42$
41$ move.b d3,(a1)+
42$ add.b d0,d0
bcc 51$
move.b d2,(a1)+
bra 52$
51$ move.b d3,(a1)+
52$ add.b d0,d0
bcc 61$
move.b d2,(a1)+
bra 62$
61$ move.b d3,(a1)+
62$ add.b d0,d0
bcc 71$
move.b d2,(a1)+
bra 72$
71$ move.b d3,(a1)+
72$ add.b d0,d0
bcc 81$
move.b d2,(a1)+
bra 82$
81$ move.b d3,(a1)+
82$ 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)+
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
add.b d0,d0
bcc 11$
add.b d0,d0
bcc 12$
move.b d4,(a1)+ ;11
move.b d4,(a1)+
bra 20$
12$ move.b d3,(a1)+ ;10
move.b d3,(a1)+
bra 20$
11$ add.b d0,d0
bcc 13$
move.b d2,(a1)+ ;01
move.b d2,(a1)+
bra 20$
13$ move.w d5,(a1)+ ;00
20$ add.b d0,d0
bcc 21$
add.b d0,d0
bcc 22$
move.b d4,(a1)+
move.b d4,(a1)+
bra 30$
22$ move.b d3,(a1)+
move.b d3,(a1)+
bra 30$
21$ add.b d0,d0
bcc 23$
move.b d2,(a1)+
move.b d2,(a1)+
bra 30$
23$ move.w d5,(a1)+
30$ add.b d0,d0
bcc 31$
add.b d0,d0
bcc 32$
move.b d4,(a1)+
move.b d4,(a1)+
bra 40$
32$ move.b d3,(a1)+
move.b d3,(a1)+
bra 40$
31$ add.b d0,d0
bcc 33$
move.b d2,(a1)+
move.b d2,(a1)+
bra 40$
33$ move.w d5,(a1)+
40$ add.b d0,d0
bcc 41$
add.b d0,d0
bcc 42$
move.b d4,(a1)+
move.b d4,(a1)+
bra 50$
42$ move.b d3,(a1)+
move.b d3,(a1)+
bra 50$
41$ add.b d0,d0
bcc 43$
move.b d2,(a1)+
move.b d2,(a1)+
bra 50$
43$ move.w d5,(a1)+
50$ 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)+
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)+
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)+
dbra d0,Loop3FFF
*
* Sprites malen?
*
DoSprites tst.b SPRITEON(a4) ;Ist ⁿberhaupt ein Sprite z.Z. sichtbar?
bne DrawTheSprites ;Ja, dann Sprites malen
*
* 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 a6,-(sp)
move.l _CyberGfxBase,a6
lea CyberHook,a0
move.l TheRastPort,a1
sub.l a2,a2
jsr DoCDrawMethod(a6)
move.l (sp)+,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
*
* Mindestens ein Sprite ist sichtbar, Sprites malen
*
; Kollisions-Puffer l÷schen
DrawTheSprites tst.w Collisions
beq 7$
lea SprCollBuf,a0
moveq #DisplayX/4-1,d0
6$ clr.l (a0)+
dbra d0,6$
7$
; Multicolor-Farben laden
move.w $25(a4),d3 ;d3.l: Multicolor #0
move.b $25(a4),d3
move.w d3,d0
swap d3
move.w d0,d3
move.w $26(a4),d4 ;d4.l: Multicolor #1
move.b $26(a4),d4
move.w d4,d0
swap d4
move.w d0,d4
; Sprites malen
move.l d7,-(sp)
DoSprite 7
DoSprite 6
DoSprite 5
DoSprite 4
DoSprite 3
DoSprite 2
DoSprite 1
DoSprite 0
move.l (sp)+,d7
; Kollisions-Puffer auswerten
tst.w Collisions
beq DrawLRBorder
lea SprCollBuf,a0
lea SprCollTab,a1
moveq #0,d0
move.w #DisplayX-1,d2
1$ move.b (a0)+,d0 ;Byte aus Puffer holen
beq 5$
tst.b (a1,d0.w) ;Entspricht die Bitkombination einer
bne 2$ ; Kollision?
5$ dbra d2,1$ ;Nein, weitertesten
bra DrawLRBorder
2$ move.b CLXSPR(a4),d1 ;Ja, Kollision erkannt
or.b d0,CLXSPR(a4) ;Bits im Kollisionsregister setzen
tst.b d1 ;Wenn bereits Kollisionen stattgefunden
bne 3$ ; haben, keinen IRQ mehr ausl÷sen
or.b #$04,IRQFLAG(a4) ;IMMC-Bit setzen
btst #2,IRQMASK(a4) ;IRQ erlaubt?
beq 3$
or.b #$80,IRQFLAG(a4) ;Ja, IRQ-Bit setzen
st.b IntIsVICIRQ ;Und Interrupt ausl÷sen
3$ dbra d2,1$
bra DrawLRBorder
**
** Ein Sprite zeichnen
** d2.w: Spritefarbe
** d3.l: Multicolor #0
** d4.l: Multicolor #1
** d5.w: MC
** d6.l: Spritenummer (0..7)
** d7.b: Spritedatenzeiger
** a2 : Zeiger auf X-Koordinate
**
CNOP 0,4
DrawSprite moveq #0,d0 ;Ja, Basisadresse berechnen
move.b d7,d0 ;Spritedatenzeiger
lsl.w #6,d0
add.w d5,d0 ;MC dazunehmen
GetPhysical ;a0: Spritedaten
moveq #0,d5 ;X-Position zusammenbauen
move.b (a2),d5
btst d6,MX8(a4)
beq 1$
or.w #$0100,d5 ;d5: Sprite-X-Position
1$
move.l a5,a1 ;(lea ist langsamer)
add.w d5,a1 ;a1: Ziel in Bildschirmspeicher
lea SprCollBuf,a2
add.w d5,a2 ;a2: Ziel im Kollisionspuffer
btst d6,MMC(a4) ;Multicolor?
bne SprMulti
btst d6,MXE(a4) ;Nein, X-expandiert?
bne SprStdExp
; Standard-Sprite: 3 Byte mit je 8 Pixeln konvertieren
cmp.w #DisplayX-24,d5 ;Sprite horizontal sichtbar?
bhs SpriteDone
moveq #0,d5
bset d6,d5 ;d5: Bitmaske fⁿr Kollisionspuffer
moveq #2,d1 ;BytezΣhler
SprLoop move.b (a0)+,d0 ;Byte lesen
beq 18$ ;Null: Nichts darstellen
add.b d0,d0
bcc 11$
move.b d2,(a1)
or.b d5,(a2)
11$ add.b d0,d0
bcc 12$
move.b d2,1(a1)
or.b d5,1(a2)
12$ add.b d0,d0
bcc 13$
move.b d2,2(a1)
or.b d5,2(a2)
13$ add.b d0,d0
bcc 14$
move.b d2,3(a1)
or.b d5,3(a2)
14$ add.b d0,d0
bcc 15$
move.b d2,4(a1)
or.b d5,4(a2)
15$ add.b d0,d0
bcc 16$
move.b d2,5(a1)
or.b d5,5(a2)
16$ add.b d0,d0
bcc 17$
move.b d2,6(a1)
or.b d5,6(a2)
17$ add.b d0,d0
bcc 18$
move.b d2,7(a1)
or.b d5,7(a2)
18$ addq.w #8,a1
addq.w #8,a2
dbra d1,SprLoop
SpriteDone rts
; X-expandiertes Standard-Sprite: 3 Byte mit je 8 Pixeln konvertieren
SprStdExp cmp.w #DisplayX-48,d5 ;Sprite sichtbar?
bhs SpriteDone
moveq #0,d5
bset d6,d5
lsl.w #8,d5
bset d6,d5 ;d5: Bitmaske fⁿr Kollisionspuffer
moveq #2,d1 ;BytezΣhler
SprELoop move.b (a0)+,d0 ;Byte lesen
beq 18$ ;Null: Nichts darstellen
add.b d0,d0
bcc 11$
move.w d2,(a1)
or.w d5,(a2)
11$ add.b d0,d0
bcc 12$
move.w d2,2(a1)
or.w d5,2(a2)
12$ add.b d0,d0
bcc 13$
move.w d2,4(a1)
or.w d5,4(a2)
13$ add.b d0,d0
bcc 14$
move.w d2,6(a1)
or.w d5,6(a2)
14$ add.b d0,d0
bcc 15$
move.w d2,8(a1)
or.w d5,8(a2)
15$ add.b d0,d0
bcc 16$
move.w d2,10(a1)
or.w d5,10(a2)
16$ add.b d0,d0
bcc 17$
move.w d2,12(a1)
or.w d5,12(a2)
17$ add.b d0,d0
bcc 18$
move.w d2,14(a1)
or.w d5,14(a2)
18$ lea 16(a1),a1
lea 16(a2),a2
dbra d1,SprELoop
rts
; Multicolor-Sprite: 3 Byte mit je 4 Pixeln konvertieren
SprMulti btst d6,MXE(a4) ;X-expandiert?
bne SprMultiExp
moveq #0,d5
bset d6,d5
lsl.w #8,d5
bset d6,d5 ;d5: Bitmaske fⁿr Kollisionspuffer
moveq #2,d1 ;BytezΣhler
SprMLoop move.b (a0)+,d0 ;Byte lesen
beq 50$ ;Null: Nichts darstellen
add.b d0,d0
bcc 11$
or.w d5,(a2)
add.b d0,d0
bcc 12$
move.w d4,(a1) ;11
bra 20$
12$ move.w d2,(a1) ;10
bra 20$
11$ add.b d0,d0
bcc 20$
move.w d3,(a1) ;01
or.w d5,(a2)
20$ add.b d0,d0
bcc 21$
or.w d5,2(a2)
add.b d0,d0
bcc 22$
move.w d4,2(a1)
bra 30$
22$ move.w d2,2(a1)
bra 30$
21$ add.b d0,d0
bcc 30$
move.w d3,2(a1)
or.w d5,2(a2)
30$ add.b d0,d0
bcc 31$
or.w d5,4(a2)
add.b d0,d0
bcc 32$
move.w d4,4(a1)
bra 40$
32$ move.w d2,4(a1)
bra 40$
31$ add.b d0,d0
bcc 40$
move.w d3,4(a1)
or.w d5,4(a2)
40$ add.b d0,d0
bcc 41$
or.w d5,6(a2)
add.b d0,d0
bcc 42$
move.w d4,6(a1)
bra 50$
42$ move.w d2,6(a1)
bra 50$
41$ add.b d0,d0
bcc 50$
move.w d3,6(a1)
or.w d5,6(a2)
50$ addq.l #8,a1
addq.l #8,a2
dbra d1,SprMLoop
SpriteDone1 rts
; X-expandiertes Multicolor-Sprite: 3 Byte mit je 4 Pixeln konvertieren
SprMultiExp cmp.w #DisplayX-48,d5 ;Sprite sichtbar?
bhs SpriteDone1
moveq #0,d5
bset d6,d5
lsl.w #8,d5
bset d6,d5
move.w d5,d0
swap d5
move.w d0,d5 ;d5: Bitmaske fⁿr Kollisionspuffer
move.w d2,d0 ;d2 auf Langwort erweitern
swap d2
move.w d0,d2
moveq #2,d1
SprMELoop move.b (a0)+,d0 ;Byte lesen
beq 50$ ;Null: Nichts darstellen
add.b d0,d0
bcc 11$
or.l d5,(a2)
add.b d0,d0
bcc 12$
move.l d4,(a1) ;11
bra 20$
12$ move.l d2,(a1) ;10
bra 20$
11$ add.b d0,d0
bcc 20$
move.l d3,(a1) ;01
or.l d5,(a2)
20$ add.b d0,d0
bcc 21$
or.l d5,4(a2)
add.b d0,d0
bcc 22$
move.l d4,4(a1)
bra 30$
22$ move.l d2,4(a1)
bra 30$
21$ add.b d0,d0
bcc 30$
move.l d3,4(a1)
or.l d5,4(a2)
30$ add.b d0,d0
bcc 31$
or.l d5,8(a2)
add.b d0,d0
bcc 32$
move.l d4,8(a1)
bra 40$
32$ move.l d2,8(a1)
bra 40$
31$ add.b d0,d0
bcc 40$
move.l d3,8(a1)
or.l d5,8(a2)
40$ add.b d0,d0
bcc 41$
or.l d5,12(a2)
add.b d0,d0
bcc 42$
move.l d4,12(a1)
bra 50$
42$ move.l d2,12(a1)
bra 50$
41$ add.b d0,d0
bcc 50$
move.l d3,12(a1)
or.l d5,12(a2)
50$ lea 16(a1),a1
lea 16(a2),a2
dbra d1,SprMELoop
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
**
** 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.)
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: AmigaMono benutzt Double Buffering
SkipCounter dc.w 1
SkipLatch dc.w 0 ;Prefs: Nur jedes nte Bild darstellen
CNOP 0,4
Registers ds.b 128 ;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-Kollisionen
SprCollTab ds.b 256 ;Welche Bitkombinationen l÷sen eine Kollision aus?
ModeNameBuf ds.b nif_SIZEOF ;Puffer fⁿr GetDisplayInfoData
TheRect ds.b ra_SIZEOF ;Puffer fⁿr QueryOverscan
END