aboutsummaryrefslogtreecommitdiff
path: root/board/MAI/bios_emulator/scitech/src/pm/dos/vflat.c
blob: 2e78e25a8b57684322040ac7eae55f1a2bb7f455 (plain)
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/****************************************************************************
*
*                   SciTech OS Portability Manager Library
*
*  ========================================================================
*
*    The contents of this file are subject to the SciTech MGL Public
*    License Version 1.0 (the "License"); you may not use this file
*    except in compliance with the License. You may obtain a copy of
*    the License at http://www.scitechsoft.com/mgl-license.txt
*
*    Software distributed under the License is distributed on an
*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
*    implied. See the License for the specific language governing
*    rights and limitations under the License.
*
*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
*
*    The Initial Developer of the Original Code is SciTech Software, Inc.
*    All Rights Reserved.
*
*  ========================================================================
*
* Language:     ANSI C
* Environment:  32-bit DOS
*
* Description:  Main C module for the VFlat framebuffer routines. The page
*               fault handler is always installed to handle up to a 4Mb
*               framebuffer with a window size of 4Kb or 64Kb in size.
*
****************************************************************************/

#include "pmapi.h"
#include <stdlib.h>
#include <dos.h>

/*-------------------------------------------------------------------------*/
/* DOS4G/W, PMODE/W and CauseWay support.                                  */
/*-------------------------------------------------------------------------*/

#if defined(DOS4GW)

#define VFLAT_START_ADDR    0xF0000000U
#define VFLAT_END_ADDR      0xF03FFFFFU
#define VFLAT_LIMIT         (VFLAT_END_ADDR - VFLAT_START_ADDR)
#define PAGE_PRESENT        1
#define PAGE_NOTPRESENT     0
#define PAGE_READ           0
#define PAGE_WRITE          2

PRIVATE ibool   installed = false;
PRIVATE ibool   haveDPMI = false;
PUBLIC  ibool   _ASMAPI VF_haveCauseWay = false;
PUBLIC  uchar * _ASMAPI VF_zeroPtr = NULL;

/* Low level assembler code */

int     _ASMAPI InitPaging(void);
void    _ASMAPI ClosePaging(void);
void    _ASMAPI MapPhysical2Linear(ulong pAddr, ulong lAddr, int pages, int flags);
void    _ASMAPI InstallFaultHandler(ulong baseAddr,int bankSize);
void    _ASMAPI RemoveFaultHandler(void);
void    _ASMAPI InstallBankFunc(int codeLen,void *bankFunc);

void * _ASMAPI VF_malloc(uint size)
{ return PM_malloc(size); }

void _ASMAPI VF_free(void *p)
{ PM_free(p); }

PRIVATE ibool CheckDPMI(void)
/****************************************************************************
*
* Function:     CheckDPMI
* Returns:      True if we are running under DPMI
*
****************************************************************************/
{
    PMREGS  regs;

    if (haveDPMI)
        return true;

    /* Check if we are running under DPMI in which case we will not be
     * able to install our page fault handlers. We can however use the
     * DVA.386 or VFLATD.386 virtual device drivers if they are present.
     */
    regs.x.ax = 0xFF00;
    PM_int386(0x31,&regs,&regs);
    if (!regs.x.cflag && (regs.e.edi & 8))
        return (haveDPMI = true);
    return false;
}

ibool PMAPI VF_available(void)
/****************************************************************************
*
* Function:     VF_available
* Returns:      True if virtual buffer is available, false if not.
*
****************************************************************************/
{
    if (!VF_zeroPtr)
        VF_zeroPtr = PM_mapPhysicalAddr(0,0xFFFFFFFF,true);
    if (CheckDPMI())
        return false;

    /* Standard DOS4GW, PMODE/W and Causeway */
    if (InitPaging() == -1)
        return false;
    ClosePaging();
    return true;
}

void * PMAPI InitDPMI(ulong baseAddr,int bankSize,int codeLen,void *bankFunc)
/****************************************************************************
*
* Function:     InitDOS4GW
* Parameters:   baseAddr    - Base address of framebuffer bank window
*               bankSize    - Physical size of banks in Kb (4 or 64)
*               codeLen     - Length of 32 bit bank switch function
*               bankFunc    - Pointer to protected mode bank function
* Returns:      Near pointer to virtual framebuffer, or NULL on failure.
*
* Description:  Installs the virtual linear framebuffer handling for
*               DPMI environments. This requires the DVA.386 or VFLATD.386
*               virtual device drivers to be installed and functioning.
*
****************************************************************************/
{
    (void)baseAddr;
    (void)bankSize;
    (void)codeLen;
    (void)bankFunc;
    return NULL;
}

void * PMAPI InitDOS4GW(ulong baseAddr,int bankSize,int codeLen,void *bankFunc)
/****************************************************************************
*
* Function:     InitDOS4GW
* Parameters:   baseAddr    - Base address of framebuffer bank window
*               bankSize    - Physical size of banks in Kb (4 or 64)
*               codeLen     - Length of 32 bit bank switch function
*               bankFunc    - Pointer to protected mode bank function
* Returns:      Near pointer to virtual framebuffer, or NULL on failure.
*
* Description:  Installs the virtual linear framebuffer handling for
*               the DOS4GW extender.
*
****************************************************************************/
{
    int     i;

    if (InitPaging() == -1)
        return NULL;            /* Cannot do hardware paging!       */

    /* Map 4MB of video memory into linear address space (read/write) */
    if (bankSize == 64) {
        for (i = 0; i < 64; i++) {
            MapPhysical2Linear(baseAddr,VFLAT_START_ADDR+(i<<16),16,
                PAGE_WRITE | PAGE_NOTPRESENT);
            }
        }
    else {
        for (i = 0; i < 1024; i++) {
            MapPhysical2Linear(baseAddr,VFLAT_START_ADDR+(i<<12),1,
                PAGE_WRITE | PAGE_NOTPRESENT);
            }
        }

    /* Install our page fault handler and banks switch function */
    InstallFaultHandler(baseAddr,bankSize);
    InstallBankFunc(codeLen,bankFunc);
    installed = true;
    return (void*)VFLAT_START_ADDR;
}

void * PMAPI VF_init(ulong baseAddr,int bankSize,int codeLen,void *bankFunc)
/****************************************************************************
*
* Function:     VF_init
* Parameters:   baseAddr    - Base address of framebuffer bank window
*               bankSize    - Physical size of banks in Kb (4 or 64)
*               codeLen     - Length of 32 bit bank switch function
*               bankFunc    - Pointer to protected mode bank function
* Returns:      Near pointer to virtual framebuffer, or NULL on failure.
*
* Description:  Installs the virtual linear framebuffer handling.
*
****************************************************************************/
{
    if (installed)
        return (void*)VFLAT_START_ADDR;
    if (codeLen > 100)
        return NULL;                /* Bank function is too large!      */
    if (!VF_zeroPtr)
        VF_zeroPtr = PM_mapPhysicalAddr(0,0xFFFFFFFF,true);
    if (CheckDPMI())
        return InitDPMI(baseAddr,bankSize,codeLen,bankFunc);
    return InitDOS4GW(baseAddr,bankSize,codeLen,bankFunc);
}

void PMAPI VF_exit(void)
/****************************************************************************
*
* Function:     VF_exit
*
* Description:  Closes down the virtual framebuffer services and
*               restores the previous page fault handler.
*
****************************************************************************/
{
    if (installed) {
        if (haveDPMI) {
            /* DPMI support */
            }
        else {
            /* Standard DOS4GW and PMODE/W support */
            RemoveFaultHandler();
            ClosePaging();
            }
        installed = false;
        }
}

/*-------------------------------------------------------------------------*/
/* Support mapped out for other compilers.                                 */
/*-------------------------------------------------------------------------*/

#else

ibool PMAPI VF_available(void)
{
    return false;
}

void * PMAPI VF_init(ulong baseAddr,int bankSize,int codeLen,void *bankFunc)
{
    (void)baseAddr;
    (void)bankSize;
    (void)codeLen;
    (void)bankFunc;
    return NULL;
}

void PMAPI VF_exit(void)
{
}

#endif