Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
Fmsx
Commits
18180788
Commit
18180788
authored
Nov 10, 2021
by
Cayce
Browse files
apply missing parts of migration from fMSX 3.9 to 4.9, to complement
8d5f4a12
parent
01731fc6
Changes
12
Hide whitespace changes
Inline
Side-by-side
EMULib/AY8910.c
View file @
18180788
...
...
@@ -72,6 +72,9 @@ void Reset8910(AY8910 *D,int ClockHz,int First)
SetSound
(
4
+
First
,
SND_NOISE
);
SetSound
(
5
+
First
,
SND_NOISE
);
/* Configure noise generator */
SetNoise
(
0x10000
,
16
,
14
);
/* Silence all channels */
for
(
J
=
0
;
J
<
AY8910_CHANNELS
;
J
++
)
{
...
...
@@ -293,7 +296,7 @@ void Sync8910(AY8910 *D,byte Sync)
J
=
(
D
->
Freq
[
3
]
?
D
->
Volume
[
3
]
:
0
)
+
(
D
->
Freq
[
4
]
?
D
->
Volume
[
4
]
:
0
)
+
(
D
->
Freq
[
5
]
?
D
->
Volume
[
5
]
:
0
);
if
(
J
)
Drum
(
DRM_MIDI
|
28
,
(
J
+
2
)
/
3
);
if
(
J
)
Drum
(
DRM_MIDI
|
28
,
J
>
255
?
255
:
J
);
}
if
(
Sync
!=
AY8910_FLUSH
)
D
->
Sync
=
Sync
;
...
...
EMULib/AY8910.h
View file @
18180788
...
...
@@ -37,7 +37,7 @@ typedef struct
byte
R
[
16
];
/* PSG registers contents */
int
Freq
[
AY8910_CHANNELS
];
/* Frequencies (0 for off) */
int
Volume
[
AY8910_CHANNELS
];
/* Volumes (0..255) */
int
Clock
;
/* Base clock
used by PSG
*/
int
Clock
;
/* Base clock
rate (Fin/16)
*/
int
First
;
/* First used Sound() channel */
byte
Changed
;
/* Bitmap of changed channels */
byte
Sync
;
/* AY8910_SYNC/AY8910_ASYNC */
...
...
EMULib/EMULib.c
View file @
18180788
...
...
@@ -112,9 +112,6 @@ void SetVideo(Image *Img,int X,int Y,int W,int H)
VideoY
=
Y
<
0
?
0
:
Y
>=
Img
->
H
?
Img
->
H
-
1
:
Y
;
VideoW
=
VideoX
+
W
>
Img
->
W
?
Img
->
W
-
VideoX
:
W
;
VideoH
=
VideoY
+
H
>
Img
->
H
?
Img
->
H
-
VideoY
:
H
;
#ifdef WINDOWS
FreeImage
(
&
BigScreen
);
#endif
}
/** WaitJoystick() *******************************************/
...
...
EMULib/EMULib.h
View file @
18180788
...
...
@@ -35,11 +35,18 @@
#define EFF_SHOWFPS 0x0200
/* Show frames-per-sec count */
#define EFF_LCDLINES 0x0400
/* Apply LCD scanlines effect */
#define EFF_VKBD 0x0800
/* Draw virtual keyboard */
#define EFF_SOFTEN2 0x1000
/* Softening algorithm select */
#define EFF_FULLJOY 0x2000
/* Use full screen controls */
#define EFF_TILTJOY 0x4000
/* Use accelerometer controls */
#define EFF_PENJOY 0x8000
/* Use touchpad controls */
#define EFF_VSYNC 0x10000
/* Wait for VBlanks */
#define EFF_DIRECT 0x20000
/* Copy whole VideoImg */
#define EFF_CMYMASK 0x40000
/* Apply vertical CMY mask */
#define EFF_RGBMASK 0x80000
/* Apply vertical RGB mask */
#define EFF_SOFTEN3 0x1000000
/* Softening algorithm select */
#define EFF_MONO 0x2000000
/* Apply monochrome color */
#define EFF_VIGNETTE 0x4000000
/* Apply CRT-like vignetting */
#define EFF_4X3 0x8000000
/* Stretch video to 4x3 ratio */
#if defined(ANDROID)
#define EFF_FIXFFWD 0x100000
/* Persistent FFWD button */
#define EFF_GLES 0x200000
/* OpenGLES video rendering */
...
...
@@ -59,6 +66,22 @@
#define EFF_VARBPP 0x200000
/* X11 determines Image depth */
#endif
#define EFF_SOFTEN_ALL (EFF_SOFTEN|EFF_SOFTEN2|EFF_SOFTEN3)
#define EFF_2XSAI (EFF_SOFTEN)
#define EFF_EPX (EFF_SOFTEN2)
#define EFF_EAGLE (EFF_SOFTEN|EFF_SOFTEN2)
#define EFF_SCALE2X (EFF_SOFTEN3)
#define EFF_HQ4X (EFF_SOFTEN|EFF_SOFTEN3)
#define EFF_NEAREST (EFF_SOFTEN2|EFF_SOFTEN3)
#define EFF_RASTER_ALL (EFF_TVLINES|EFF_LCDLINES)
#define EFF_RASTER (EFF_TVLINES|EFF_LCDLINES)
#define EFF_MASK_ALL (EFF_CMYMASK|EFF_RGBMASK|EFF_MONO)
#define EFF_GREEN (EFF_MONO|EFF_CMYMASK)
#define EFF_AMBER (EFF_MONO|EFF_RGBMASK)
#define EFF_SEPIA (EFF_MONO|EFF_CMYMASK|EFF_RGBMASK)
/** Button Bits **********************************************/
/** Bits returned by GetJoystick() and WaitJoystick(). **/
/*************************************************************/
...
...
@@ -244,12 +267,60 @@ void LcdizeImage(Image *Img,int X,int Y,int W,int H);
/*************************************************************/
void
RasterizeImage
(
Image
*
Img
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** CMYizeImage() ********************************************/
/** Apply vertical CMY stripes to the image. **/
/*************************************************************/
void
CMYizeImage
(
Image
*
Img
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** RGBizeImage() ********************************************/
/** Apply vertical RGB stripes to the image. **/
/*************************************************************/
void
RGBizeImage
(
Image
*
Img
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** MonoImage() **********************************************/
/** Turn image into monochrome. **/
/*************************************************************/
void
MonoImage
(
Image
*
Img
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** SepiaImage() *********************************************/
/** Turn image into sepia tones. **/
/*************************************************************/
void
SepiaImage
(
Image
*
Img
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** GreenImage() *********************************************/
/** Simulate green CRT phosphor. **/
/*************************************************************/
void
GreenImage
(
Image
*
Img
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** AmberImage() *********************************************/
/** Simulate amber CRT phosphor. **/
/*************************************************************/
void
AmberImage
(
Image
*
Img
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** SoftenImage() ********************************************/
/** Uses softening algorithm to interpolate image Src into **/
/** a bigger image Dst. **/
/*************************************************************/
void
SoftenImage
(
Image
*
Dst
,
const
Image
*
Src
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** SoftenSCALE2X() ******************************************/
/** Uses SCALE2X softening algorithm to interpolate image **/
/** Src into a bigger image Dst. **/
/*************************************************************/
void
SoftenSCALE2X
(
Image
*
Dst
,
const
Image
*
Src
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** SoftenEPX() **********************************************/
/** Uses EPX softening algorithm to interpolate image Src **/
/** into a bigger image Dst. **/
/*************************************************************/
void
SoftenEPX
(
Image
*
Dst
,
const
Image
*
Src
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** SoftenEAGLE() ********************************************/
/** Uses EAGLE softening algorithm to interpolate image Src **/
/** into a bigger image Dst. **/
/*************************************************************/
void
SoftenEAGLE
(
Image
*
Dst
,
const
Image
*
Src
,
int
X
,
int
Y
,
int
W
,
int
H
);
/** ClearImage() *********************************************/
/** Clear image with a given color. **/
/*************************************************************/
...
...
@@ -304,6 +375,11 @@ void SetPalette(pixel N,unsigned char R,unsigned char G,unsigned char B);
/*************************************************************/
unsigned
int
GetFreeAudio
(
void
);
/** GetTotalAudio() ******************************************/
/** Get total amount of samples in the audio buffer. **/
/*************************************************************/
unsigned
int
GetTotalAudio
(
void
);
/** WriteAudio() *********************************************/
/** Write up to a given number of samples to audio buffer. **/
/** Returns the number of samples written. **/
...
...
@@ -391,6 +467,12 @@ int ProcessEvents(int Wait);
/*************************************************************/
void
SetEffects
(
unsigned
int
NewEffects
);
/** ParseEffects() *******************************************/
/** Parse command line visual effect options, removing them **/
/** from Args[] and applying to the initial Effects value. **/
/*************************************************************/
unsigned
int
ParseEffects
(
char
*
Args
[],
unsigned
int
Effects
);
/** GetFilePath() ********************************************/
/** Extracts pathname from filename and returns a pointer **/
/** to the internal buffer containing just the path name **/
...
...
EMULib/Floppy.c
View file @
18180788
...
...
@@ -185,13 +185,13 @@ int DSKFile(byte *Dsk,const char *FileName)
/*************************************************************/
const
char
*
DSKFileName
(
const
byte
*
Dsk
,
int
ID
)
{
const
unsigned
char
*
Name
;
const
char
*
Name
;
/* Can't have ID that is out of bounds */
if
((
ID
<
1
)
||
(
ID
>
DSK_DIR_SIZE
))
return
(
0
);
/* Return file name */
Name
=
DIRENTRY
(
Dsk
,
ID
-
1
);
return
(
!
Name
[
0
]
||
(
Name
[
0
]
==
0xE5
)
?
0
:
Name
);
Name
=
(
const
char
*
)
DIRENTRY
(
Dsk
,
ID
-
1
);
return
(
!
Name
[
0
]
||
(
Name
[
0
]
==
(
char
)
0xE5
)
?
0
:
Name
);
}
/** DSKFileSize() ********************************************/
...
...
@@ -371,7 +371,8 @@ int DSKDelete(byte *Dsk,int ID)
/*************************************************************/
byte
*
DSKLoad
(
const
char
*
Name
,
byte
*
Dsk
)
{
byte
*
Dsk1
,
*
Buf
,
FN
[
32
],
*
Path
;
byte
*
Dsk1
,
*
Buf
;
char
*
Path
,
FN
[
32
];
struct
stat
FS
;
RFILE
*
F
;
struct
RDIR
*
D
;
...
...
@@ -457,7 +458,7 @@ byte *DSKLoad(const char *Name,byte *Dsk)
const
byte
*
DSKSave
(
const
char
*
Name
,
const
byte
*
Dsk
)
{
const
char
*
T
;
byte
*
Path
,
*
P
;
char
*
Path
,
*
P
;
struct
stat
FS
;
RFILE
*
F
;
int
J
,
I
,
K
;
...
...
EMULib/Sound.c
View file @
18180788
...
...
@@ -43,13 +43,13 @@ static const struct { byte Note;word Wheel; } Freqs[4096] =
#include "MIDIFreq.h"
};
static
const
int
Programs
[
5
]
=
static
const
int
Programs
[]
=
{
80
,
/* SND_MELODIC/SND_RECTANGLE */
80
,
/* SND_TRIANGLE */
122
,
/* SND_NOISE */
122
,
/* SND_PERIODIC */
80
/* SND_WAVE */
80
,
/* SND_WAVE */
};
static
struct
...
...
@@ -58,24 +58,25 @@ static struct
int
Note
;
int
Pitch
;
int
Level
;
int
Power
;
}
MidiCH
[
MIDI_CHANNELS
]
=
{
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
},
{
-
1
,
-
1
,
-
1
,
-
1
}
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
},
{
-
1
,
-
1
,
-
1
,
-
1
,
256
}
};
static
struct
...
...
@@ -112,7 +113,9 @@ static struct
/** RenderAudio() Variables *******************************************/
static
int
SndRate
=
0
;
/* Sound rate (0=Off) */
static
int
NoiseGen
=
1
;
/* Noise generator seed */
static
int
NoiseGen
=
0x10000
;
/* Noise generator seed */
static
int
NoiseOut
=
16
;
/* NoiseGen bit used for output */
static
int
NoiseXor
=
14
;
/* NoiseGen bit used for XORing */
int
MasterSwitch
=
0xFFFF
;
/* Switches to turn channels on/off */
int
MasterVolume
=
192
;
/* Master volume */
...
...
@@ -153,13 +156,20 @@ void Sound(int Channel,int Freq,int Volume)
{
/* All parameters have to be valid */
if
((
Channel
<
0
)
||
(
Channel
>=
SND_CHANNELS
))
return
;
Freq
=
Freq
<
0
?
0
:
Freq
>
20000
?
0
:
Freq
;
Freq
=
Freq
<
0
?
0
:
Freq
;
Volume
=
Volume
<
0
?
0
:
Volume
>
255
?
255
:
Volume
;
/* Modify
wave
channel */
/* Modify channel
parameters
*/
WaveCH
[
Channel
].
Volume
=
Volume
;
WaveCH
[
Channel
].
Freq
=
Freq
;
/* When disabling sound, reset waveform */
if
(
!
Freq
||!
Volume
)
{
WaveCH
[
Channel
].
Pos
=
0
;
WaveCH
[
Channel
].
Count
=
0
;
}
/* Log sound to MIDI file */
MIDISound
(
Channel
,
Freq
,
Volume
);
}
...
...
@@ -209,6 +219,18 @@ void SetChannels(int Volume,int Switch)
MasterSwitch
=
Switch
&
((
1
<<
SND_CHANNELS
)
-
1
);
}
/** SetNoise() ***********************************************/
/** Initialize random noise generator to the given Seed and **/
/** then take random output from OUTBit and XOR it with **/
/** XORBit. **/
/*************************************************************/
void
SetNoise
(
int
Seed
,
int
OUTBit
,
int
XORBit
)
{
NoiseGen
=
Seed
;
NoiseOut
=
OUTBit
;
NoiseXor
=
XORBit
;
}
/** SetWave() ************************************************/
/** Set waveform for a given channel. The channel will be **/
/** marked with sound type SND_WAVE. Set Rate=0 if you want **/
...
...
@@ -217,6 +239,8 @@ void SetChannels(int Volume,int Switch)
/*************************************************************/
void
SetWave
(
int
Channel
,
const
signed
char
*
Data
,
int
Length
,
int
Rate
)
{
unsigned
int
I
,
J
;
/* Channel and waveform length have to be valid */
if
((
Channel
<
0
)
||
(
Channel
>=
SND_CHANNELS
)
||
(
Length
<=
0
))
return
;
...
...
@@ -229,7 +253,19 @@ void SetWave(int Channel,const signed char *Data,int Length,int Rate)
WaveCH
[
Channel
].
Data
=
Data
;
/* Log instrument change to MIDI file */
MIDISetSound
(
Channel
,
Rate
?
-
1
:
SND_MELODIC
);
MIDISetSound
(
Channel
,
Rate
?
-
1
:
SND_WAVE
);
/* Compute overall waveform power for MIDI */
if
(
Rate
)
I
=
0
;
else
{
for
(
J
=
I
=
0
;
J
<
Length
;
++
J
)
I
+=
Data
[
J
]
>
0
?
Data
[
J
]
:-
Data
[
J
];
I
=
(
I
<<
1
)
/
Length
;
I
=
I
>
256
?
256
:
I
;
}
/* Will use power value when computing MIDI volume */
MidiCH
[
Channel
].
Power
=
I
;
}
/** GetWave() ************************************************/
...
...
@@ -414,10 +450,14 @@ void MIDISound(int Channel,int Freq,int Volume)
if
(
!
Volume
||!
Freq
)
NoteOff
(
Channel
);
else
{
/* SND_TRIANGLE is twice quieter than SND_MELODIC */
if
(
MidiCH
[
Channel
].
Type
==
SND_TRIANGLE
)
Volume
=
(
Volume
+
1
)
/
2
;
/* SND_TRIANGLE has 1/2 volume of SND_MELODIC */
/* SND_WAVE may have different effective volume */
Volume
=
MidiCH
[
Channel
].
Type
==
SND_TRIANGLE
?
(
Volume
>>
1
)
:
MidiCH
[
Channel
].
Type
==
SND_WAVE
?
((
Volume
*
MidiCH
[
Channel
].
Power
)
>>
8
)
:
Volume
;
/* Compute MIDI note parameters */
MIDIVolume
=
(
127
*
Volume
+
128
)
/
255
;
MIDIVolume
=
Volume
>>
1
;
MIDINote
=
Freqs
[
Freq
/
3
].
Note
;
MIDIWheel
=
Freqs
[
Freq
/
3
].
Wheel
;
...
...
@@ -471,7 +511,7 @@ void MIDIDrum(int Type,int Force)
/* Release previous drum */
if
(
DrumOn
)
MIDIMessage
(
0x89
,
DrumOn
,
127
);
/* Hit next drum */
if
(
Type
)
MIDIMessage
(
0x99
,
Type
,(
Force
&
0xFF
)
/
2
);
if
(
Type
)
MIDIMessage
(
0x99
,
Type
,(
Force
&
0xFF
)
>>
1
);
DrumOn
=
Type
;
}
...
...
@@ -577,7 +617,6 @@ unsigned int InitSound(unsigned int Rate,unsigned int Latency)
/* Initialize internal variables (keeping MasterVolume/MasterSwitch!) */
SndRate
=
0
;
NoiseGen
=
1
;
/* Reset sound parameters */
for
(
I
=
0
;
I
<
SND_CHANNELS
;
I
++
)
...
...
@@ -618,7 +657,6 @@ void RenderAudio(int *Wave,unsigned int Samples)
/* Keep GCC happy about variable initialization */
N
=
L
=
A2
=
0
;
/* Waveform generator */
for
(
J
=
0
;
J
<
SND_CHANNELS
;
J
++
)
if
(
WaveCH
[
J
].
Freq
&&
(
V
=
WaveCH
[
J
].
Volume
)
&&
(
MasterSwitch
&
(
1
<<
J
)))
...
...
@@ -693,18 +731,27 @@ void RenderAudio(int *Wave,unsigned int Samples)
case
SND_NOISE
:
/* White Noise */
/* For high frequencies, recompute volume */
if
(
WaveCH
[
J
].
Freq
<=
SndRate
)
K
=
0x10000
*
WaveCH
[
J
].
Freq
/
SndRate
;
else
{
V
=
V
*
SndRate
/
WaveCH
[
J
].
Freq
;
K
=
0x10000
;
}
if
(
WaveCH
[
J
].
Freq
<
SndRate
)
K
=
((
unsigned
int
)
WaveCH
[
J
].
Freq
<<
16
)
/
SndRate
;
else
{
V
=
V
*
SndRate
/
WaveCH
[
J
].
Freq
;
K
=
0x10000
;
}
L1
=
WaveCH
[
J
].
Count
;
for
(
I
=
0
;
I
<
Samples
;
I
++
)
{
/* Use NoiseOut bit for output */
Wave
[
I
]
+=
((
NoiseGen
>>
NoiseOut
)
&
1
?
127
:-
128
)
*
V
;
L1
+=
K
;
if
(
L1
&
0xFFFF0000
)
{
if
((
NoiseGen
<<=
1
)
&
0x80000000
)
NoiseGen
^=
0x08000001
;
/* XOR NoiseOut and NoiseXOR bits and feed them back */
NoiseGen
=
(((
NoiseGen
>>
NoiseOut
)
^
(
NoiseGen
>>
NoiseXor
))
&
1
)
|
((
NoiseGen
<<
1
)
&
((
2
<<
NoiseOut
)
-
1
));
L1
&=
0xFFFF
;
}
Wave
[
I
]
+=
(
NoiseGen
&
1
?
127
:-
128
)
*
V
;
}
WaveCH
[
J
].
Count
=
L1
;
break
;
...
...
@@ -756,12 +803,12 @@ unsigned int PlayAudio(int *Wave,unsigned int Samples)
{
/* Compute number of samples to convert */
J
=
sizeof
(
Buf
)
/
sizeof
(
sample
);
J
=
Samples
<=
J
?
Samples
:
J
;
J
=
Samples
-
K
>
J
?
J
:
Samples
-
K
;
/* Convert samples */
for
(
I
=
0
;
I
<
J
;
++
I
)
{
D
=
((
*
Wave
++
)
*
MasterVolume
)
/
255
;
D
=
((
*
Wave
++
)
*
MasterVolume
)
>>
8
;
D
=
D
>
32767
?
32767
:
D
<-
32768
?
-
32768
:
D
;
#if defined(BPU16)
Buf
[
I
]
=
D
+
32768
;
...
...
EMULib/Sound.h
View file @
18180788
...
...
@@ -100,6 +100,13 @@ void SetSound(int Channel,int NewType);
/*************************************************************/
void
SetChannels
(
int
Volume
,
int
Switch
);
/** SetNoise() ***********************************************/
/** Initialize random noise generator to the given Seed and **/
/** then take random output from OUTBit and XOR it with **/
/** XORBit. **/
/*************************************************************/
void
SetNoise
(
int
Seed
,
int
OUTBit
,
int
XORBit
);
/** SetWave() ************************************************/
/** Set waveform for a given channel. The channel will be **/
/** marked with sound type SND_WAVE. Set Rate=0 if you want **/
...
...
EMULib/WD1793.c
View file @
18180788
...
...
@@ -34,6 +34,7 @@ void Reset1793(WD1793 *D,FDIDisk *Disks,byte Eject)
D
->
WRLength
=
0
;
D
->
RDLength
=
0
;
D
->
Wait
=
0
;
D
->
Cmd
=
0xD0
;
/* For all drives... */
for
(
J
=
0
;
J
<
4
;
++
J
)
...
...
@@ -60,8 +61,16 @@ byte Read1793(WD1793 *D,byte A)
A
=
D
->
R
[
0
];
/* If no disk present, set F_NOTREADY */
if
(
!
D
->
Disk
[
D
->
Drive
]
||!
D
->
Disk
[
D
->
Drive
]
->
Data
)
A
|=
F_NOTREADY
;
if
(
D
->
Cmd
<
0x80
)
{
/* Keep flipping F_INDEX bit as the disk rotates (Sam Coupe) */
D
->
R
[
0
]
=
(
D
->
R
[
0
]
^
F_INDEX
)
&
(
F_INDEX
|
F_BUSY
|
F_NOTREADY
|
F_READONLY
|
F_TRACK0
);
}
else
{
/* When reading status, clear all bits but F_BUSY and F_NOTREADY */
D
->
R
[
0
]
&=
F_BUSY
|
F_NOTREADY
;
D
->
R
[
0
]
&=
F_BUSY
|
F_NOTREADY
|
F_READONLY
|
F_DRQ
;
}
return
(
A
);
case
WD1793_TRACK
:
case
WD1793_SECTOR
:
...
...
@@ -125,6 +134,7 @@ byte Write1793(WD1793 *D,byte A,byte V)
{
/* Reset any executing command */
D
->
RDLength
=
D
->
WRLength
=
0
;
D
->
Cmd
=
0xD0
;
/* Either reset BUSY flag or reset all flags if BUSY=0 */
if
(
D
->
R
[
0
]
&
F_BUSY
)
D
->
R
[
0
]
&=~
F_BUSY
;
else
D
->
R
[
0
]
=
D
->
Track
[
D
->
Drive
]
?
0
:
F_TRACK0
;
...
...
@@ -137,6 +147,7 @@ byte Write1793(WD1793 *D,byte A,byte V)
if
(
D
->
R
[
0
]
&
F_BUSY
)
break
;
/* Reset status register */
D
->
R
[
0
]
=
0x00
;
D
->
Cmd
=
V
;
/* Depending on the command... */
switch
(
V
&
0xF0
)
{
...
...
EMULib/WD1793.h
View file @
18180788
...
...
@@ -90,6 +90,7 @@ typedef struct
byte
LastS
;
/* Last STEP direction */
byte
IRQ
;
/* 0x80: IRQ pending, 0x40: DRQ pending */
byte
Wait
;
/* Expiration counter */
byte
Cmd
;
/* Last command */
int
WRLength
;
/* Data left to write */
int
RDLength
;
/* Data left to read */
...
...
fMSX/Common.h
View file @
18180788
...
...
@@ -103,8 +103,9 @@ pixel *RefreshBorder(byte Y,pixel C)
/*************************************************************/
void
Sprites
(
byte
Y
,
pixel
*
Line
)
{
static
const
byte
SprHeights
[
4
]
=
{
8
,
16
,
16
,
32
};
pixel
*
P
,
C
;
byte
H
,
*
PT
,
*
AT
;
byte
OH
,
I
H
,
*
PT
,
*
AT
;
unsigned
int
M
;
int
L
,
K
;
...
...
@@ -112,10 +113,11 @@ void Sprites(byte Y,pixel *Line)
VDPStatus
[
0
]
&=~
0x5F
;
/* Assign initial values before counting */
H
=
Sprites16x16
?
16
:
8
;
OH
=
SprHeights
[
VDP
[
1
]
&
0x03
];
IH
=
SprHeights
[
VDP
[
1
]
&
0x02
];
AT
=
SprTab
-
4
;
Y
+=
VScroll
;
C
=
0
;
C
=
MAXSPRITE1
+
1
;
M
=
0
;
/* Count displayed sprites */
...
...
@@ -124,17 +126,16 @@ void Sprites(byte Y,pixel *Line)
M
<<=
1
;
AT
+=
4
;
/* Iterating through SprTab */
K
=
AT
[
0
];
/* K = sprite Y coordinate */
if
(
K
==
208
)
break
;
/* Iteration terminates if Y=208 */
if
(
K
>
256
-
H
)
K
-=
256
;
/* Y coordinate may be negative */
if
(
K
>
256
-
I
H
)
K
-=
256
;
/* Y coordinate may be negative */
/* Mark all valid sprites with 1s, break at MAXSPRITE1 sprites */
if
((
Y
>
K
)
&&
(
Y
<=
K
+
H
))
if
((
Y
>
K
)
&&
(
Y
<=
K
+
O
H
))
{
/* If we exceed the maximum number of sprites per line... */
if
(
++
C
==
MAXSPRITE1
+
1
)
if
(
!--
C
)
{
/* Record extra sprite number in the VDP status register */
VDPStatus
[
0
]
|=
0x40
|
(
L
&
0x1F
);
/* Set 5thSprite flag in the VDP status register */
VDPStatus
[
0
]
|=
0x40
;
/* Stop drawing sprites, unless all-sprites option enabled */
if
(
!
OPTION
(
MSX_ALLSPRITE
))
break
;
}
...
...
@@ -144,6 +145,9 @@ void Sprites(byte Y,pixel *Line)
}
}
/* Mark last checked sprite (5th in line, Y=208, or sprite #31) */
VDPStatus
[
0
]
|=
L
<
32
?
L
:
31
;
/* Draw all marked sprites */
for
(;
M
;
M
>>=
1
,
AT
-=
4
)
if
(
M
&
1
)
...
...
@@ -152,38 +156,82 @@ void Sprites(byte Y,pixel *Line)
L
=
C
&
0x80
?
AT
[
1
]
-
32
:
AT
[
1
];
/* Sprite may be shifted left by 32 */
C
&=
0x0F
;
/* C = sprite color */
if
((
L
<
256
)
&&
(
L
>-
H
)
&&
C
)
if
((
L
<
256
)
&&
(
L
>-
O
H
)
&&
C
)
{
K
=
AT
[
0
];
/* K = sprite Y coordinate */
if
(
K
>
256
-
H
)
K
-=
256
;
/* Y coordinate may be negative */
if
(
K
>
256
-
I
H
)
K
-=
256
;
/* Y coordinate may be negative */
P
=
Line
+
L
;
PT
=
SprGen
+
((
int
)(
H
>
8
?
AT
[
2
]
&
0xFC
:
AT
[
2
])
<<
3
)
+
Y
-
K
-
1
;
K
=
Y
-
K
-
1
;
PT
=
SprGen
+
((
int
)(
IH
>
8
?
AT
[
2
]
&
0xFC
:
AT
[
2
])
<<
3
)
+
(
OH
>
IH
?
(
K
>>
1
)
:
K
);
C
=
XPal
[
C
];
/* Mask 1: clip left sprite boundary */
K
=
L
>=
0
?
0x0FFFF
:
(
0x10000
>>-
L
)
-
1
;
K
=
L
>=
0
?
0xFFFF
:
(
0x10000
>>
(
OH
>
IH
?
(
-
L
>>
1
)
:-
L
))
-
1
;
/* Mask 2: clip right sprite boundary */
if
(
L
>
256
-
H
)
K
^=
((
0x00200
>>
(
H
-
8
))
<<
(
L
-
257
+
H
))
-
1
;
L
+=
(
int
)
OH
-
257
;
if
(
L
>=
0
)
{
L
=
(
IH
>
8
?
0x0002
:
0x0200
)
<<
(
OH
>
IH
?
(
L
>>
1
)
:
L
);
K
&=~
(
L
-
1
);
}
/* Get and clip the sprite data */
K
&=
((
int
)
PT
[
0
]
<<
8
)
|
(
H
>
8
?
PT
[
16
]
:
0x00
);
K
&=
((
int
)
PT
[
0
]
<<
8
)
|
(
I
H
>
8
?
PT
[
16
]
:
0x00
);
/*
Draw left 8 pixels of the sprite
*/
if
(
K
&
0xFF00
)
/*
If output size is bigger than the input size...
*/
if
(
OH
>
IH
)
{
if
(
K
&
0x8000
)
P
[
0
]
=
C
;
if
(
K
&
0x4000
)
P
[
1
]
=
C
;
if
(
K
&
0x2000
)
P
[
2
]
=
C
;
if
(
K
&
0x1000
)
P
[
3
]
=
C
;
if
(
K
&
0x0800
)
P
[
4
]
=
C
;
if
(
K
&
0x0400
)
P
[
5
]
=
C
;
if
(
K
&
0x0200
)
P
[
6
]
=
C
;
if
(
K
&
0x0100
)
P
[
7
]
=
C
;
}
/* Big (zoomed) sprite */
/* Draw right 8 pixels of the sprite */
if
(
K
&
0x00FF
)
/* Draw left 16 pixels of the sprite */
if
(
K
&
0xFF00
)
{
if
(
K
&
0x8000
)
P
[
1
]
=
P
[
0
]
=
C
;
if
(
K
&
0x4000
)
P
[
3
]
=
P
[
2
]
=
C
;
if
(
K
&
0x2000
)
P
[
5
]
=
P
[
4
]
=
C
;
if
(
K
&
0x1000
)
P
[
7
]
=
P
[
6
]
=
C
;
if
(
K
&
0x0800
)
P
[
9
]
=
P
[
8
]
=
C
;
if
(
K
&
0x0400
)
P
[
11
]
=
P
[
10
]
=
C
;
if
(
K
&
0x0200
)
P
[
13
]
=
P
[
12
]
=
C
;
if
(
K
&
0x0100
)
P
[
15
]
=
P
[
14
]
=
C
;
}
/* Draw right 16 pixels of the sprite */
if
(
K
&
0x00FF
)
{
if
(
K
&
0x0080
)
P
[
17
]
=
P
[
16
]
=
C
;
if
(
K
&
0x0040
)
P
[
19
]
=
P
[
18
]
=
C
;
if
(
K
&
0x0020
)
P
[
21
]
=
P
[
20
]
=
C
;