-
Notifications
You must be signed in to change notification settings - Fork 1
/
crtc.c
165 lines (150 loc) · 5.53 KB
/
crtc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "plateform.h"
#include "z80.h"
#include "crtc.h"
#include "vga.h"
void ResetCRTC( core_crocods_t *core )
{
memset( core->RegsCRTC, -1, sizeof( core->RegsCRTC ) );
core->TailleVBL = 16;
core->CptCharVert = 0;
core->NumLigneChar = 0;
core->LigneCRTC = 0;
core->MaCRTC = 0;
core->SyncCount = 0;
core->RegsCRTC[0]=0;
}
/********************************************************* !NAME! **************
* Nom : WriteCRTC
********************************************************** !PATHS! *************
* !./V1!\!./V2!\!./V3!\!./V4!\Fonctions
********************************************************** !1! *****************
*
* Fichier : !./FPTH\/FLE!, ligne : !./LN!
*
* Description : Ecriture d'un registre du CRTC
*
* Résultat : /
*
* Variables globales modifiées : RegsCRTC, RegCRTCSel, XStart, XEnd
*
********************************************************** !0! ****************/
void WriteCRTC( core_crocods_t *core, u16 adr, u8 val )
{
adr &= 0xBF00;
if (adr == 0xBC00) {
core->RegCRTCSel = val & 0x1F;
} else {
if (adr == 0xBD00) {
switch(core->RegCRTCSel) { // only registers 0 - 15 can be written to
case 1: // horizontal displayed
core->RegsCRTC[core->RegCRTCSel] = val;
break;
case 2: // horizontal sync position
core->RegsCRTC[core->RegCRTCSel] = val;
break;
case 8: // interlace and skew
val &= 0xF3; // sur PreAsic, Asic, HD6845S
// val &= 0x03; // 03 sur HD6845R, UM6845R, MC6845
core->RegsCRTC[core->RegCRTCSel] = val;
break;
case 0: // horizontal total
core->RegsCRTC[0] = val;
break;
case 3: // sync width
case 13: // start address low byte
case 15: // cursor address low byte
core->RegsCRTC[core->RegCRTCSel] = val;
break;
case 4: // vertical total
val &= 0x7F; // sur PreAsic, Asic, HD6845S
// val &= 0x0F; // sur HD6845R, UM6845R, MC6845
core->RegsCRTC[core->RegCRTCSel] = val;
break;
case 6: // vertical displayed
case 7: // vertical sync position
case 10: // cursor start raster
val &= 0x7F;
core->RegsCRTC[core->RegCRTCSel] = val;
break;
case 5: // vertical total adjust
case 9: // maximum raster count
case 11: // cursor end raster
val &= 0x1F;
core->RegsCRTC[core->RegCRTCSel] = val;
break;
case 12: // start address high byte
case 14: // cursor address high byte
val &= 0x3F;
core->RegsCRTC[core->RegCRTCSel] = val;
break;
}
}
}
core->XStart = max( ( 50 - core->RegsCRTC[ 2 ] ) << 1, 0 );
core->XEnd = min( core->XStart + ( core->RegsCRTC[ 1 ] << 1 ), 96 );
}
/********************************************************* !NAME! **************
* Nom : CalcCRTCLine
********************************************************** !PATHS! *************
* !./V1!\!./V2!\!./V3!\!./V4!\Fonctions
********************************************************** !1! *****************
*
* Fichier : !./FPTH\/FLE!, ligne : !./LN!
*
* Description : Calcul et affiche une ligne CRTC
*
* Résultat : La ligne suivante du CRTC à afficher
*
* Variables globales modifiées : /
*
********************************************************** !0! ****************/
int CalcCRTCLine( core_crocods_t *core )
{
if ( !--core->TailleVBL ) {
core->VSync = 0;
}
// if ( ++LigneCRTC >= RegsCRTC[ 5 ] )
if ( ++core->LigneCRTC ) {
if ( core->NumLigneChar == core->RegsCRTC[ 9 ] ) {
core->NumLigneChar = 0;
core->CptCharVert = ( core->CptCharVert + 1 ) & 0x7F;
core->MaCRTC += core->RegsCRTC[ 1 ];
}
else {
core->NumLigneChar = ( core->NumLigneChar + 1 ) & 0x1F;
}
if ( core->CptCharVert == core->RegsCRTC[ 4 ] + 1 ) {
core->NumLigneChar = 0; // ### Pas sur...
core->CptCharVert = 0;
core->MaCRTC = core->RegsCRTC[ 13 ] | ( core->RegsCRTC[ 12 ] << 8 );
}
if ( core->CptCharVert == core->RegsCRTC[ 7 ] && !core->NumLigneChar ) {
core->LigneCRTC = 0;
core->TailleVBL = 16;
core->SyncCount = 2;
core->VSync = 1;
core->DoResync = 1;
} else {
int y = core->LigneCRTC - 32;
if ( y >= 0 && y < TAILLE_Y_LOW ) {
core->DrawFct( core, y
, core->CptCharVert < core->RegsCRTC[ 6 ] ? core->MaCRTC << 1 : -1
, ( ( core->NumLigneChar ) << 11 ) | ( ( core->MaCRTC & 0x3000 ) << 2 )
);
}
else
if ( core->LigneCRTC > 312 ) {
core->LigneCRTC = 0;
core->DoResync = 0;
}
}
}
// ASIC HSync
if (core->hw==CPC_HW_CPCPLUS) {
/* yes. See if ASIC interrupts are required */
// ASIC_HSync(CRTC_InternalState.LineCounter, CRTC_InternalState.RasterCounter);
}
// VGA Update
VGA_Update(core);
return( core->LigneCRTC );
}