mirror of
https://github.com/Pecusx/libretro-atari800.git
synced 2026-05-21 14:49:36 +02:00
initial commit
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
#ifndef DOS_INTS_H_
|
||||
#define DOS_INTS_H_
|
||||
|
||||
/* Thanks, Allegro! */
|
||||
#define BPS_TO_TIMER(x) (1193182L / (long)(x))
|
||||
#define END_OF_FUNCTION(x) void x##_end(void) {}
|
||||
#define END_OF_STATIC_FUNCTION(x) static void x##_end(void) {}
|
||||
#define LOCK_VARIABLE(x) _go32_dpmi_lock_data((void*)&x, sizeof(x))
|
||||
#define LOCK_FUNCTION(x) _go32_dpmi_lock_code((void *)x, (long)x##_end - (long)x)
|
||||
|
||||
#define DISABLE_INTS() __asm__ __volatile__ ("cli")
|
||||
#define ENABLE_INTS() __asm__ __volatile__ ("sti")
|
||||
|
||||
#endif /* DOS_INTS_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
#ifndef DOS_SB_H_
|
||||
#define DOS_SB_H_
|
||||
|
||||
typedef void (*sbmix_t)(void *buffer, unsigned int size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern int sb_init(int *sample_rate, int *bps, int *buf_samples, int *stereo);
|
||||
extern void sb_shutdown(void);
|
||||
extern int sb_startoutput(sbmix_t fillbuf);
|
||||
extern void sb_stopoutput(void);
|
||||
extern void sb_setrate(int rate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* DOS_SB_H_ */
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* sound_dos.c - high level sound routines for DOS port
|
||||
*
|
||||
* Copyright (c) 1998-2000 Matthew Conte
|
||||
* Copyright (c) 2000-2014 Atari800 development team (see DOC/CREDITS)
|
||||
*
|
||||
* This file is part of the Atari800 emulator project which emulates
|
||||
* the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
|
||||
*
|
||||
* Atari800 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Atari800 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Atari800; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "dos_sb.h"
|
||||
|
||||
#include "atari.h"
|
||||
#include "log.h"
|
||||
#include "platform.h"
|
||||
#include "sound.h"
|
||||
#include "util.h" /* TODO */
|
||||
|
||||
int PLATFORM_SoundSetup(Sound_setup_t *setup)
|
||||
{
|
||||
int playback_freq = setup->freq;
|
||||
int bps = setup->sample_size * 8;
|
||||
int buffer_samples;
|
||||
int stereo = setup->channels == 2;
|
||||
|
||||
if (setup->buffer_frames == 0)
|
||||
/* Set buffer_frames automatically. */
|
||||
setup->buffer_frames = Sound_NextPow2(setup->freq / 50);
|
||||
|
||||
buffer_samples = setup->buffer_frames * setup->channels;
|
||||
|
||||
if (sb_init(&playback_freq, &bps, &buffer_samples, &stereo) < 0) {
|
||||
Log_print("Cannot init sound card");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
setup->channels = stereo ? 2 : 1;
|
||||
setup->sample_size = bps / 8;
|
||||
setup->buffer_frames = buffer_samples / setup->channels;
|
||||
setup->freq = playback_freq;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void PLATFORM_SoundExit(void)
|
||||
{
|
||||
sb_shutdown();
|
||||
}
|
||||
|
||||
void PLATFORM_SoundPause(void)
|
||||
{
|
||||
sb_stopoutput();
|
||||
}
|
||||
|
||||
void PLATFORM_SoundContinue(void)
|
||||
{
|
||||
sb_startoutput((sbmix_t) Sound_Callback);
|
||||
}
|
||||
|
||||
void PLATFORM_SoundLock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void PLATFORM_SoundUnlock(void)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
* vga_asm.s - x86-assembler routines for DOS/VGA port
|
||||
*
|
||||
* Copyright (c) 1996 Ivo van Poorten
|
||||
* Copyright (c) 1996-2003 Atari800 development team (see DOC/CREDITS)
|
||||
*
|
||||
* This file is part of the Atari800 emulator project which emulates
|
||||
* the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
|
||||
*
|
||||
* Atari800 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Atari800 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Atari800; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* read analog joystick 0 from atari_vga.c */
|
||||
/* int joystick0(int *x, int *y) */
|
||||
/* stack frame:
|
||||
esp: old_ebx
|
||||
esp+4: ret_addr
|
||||
esp+8: x
|
||||
esp+12: y
|
||||
*/
|
||||
|
||||
.globl _joystick0
|
||||
_joystick0:
|
||||
pushl %ebx
|
||||
cli
|
||||
movw $0x201, %dx
|
||||
xorl %ebx, %ebx
|
||||
xorl %ecx, %ecx
|
||||
outb %al, %dx
|
||||
__jloop:
|
||||
inb %dx, %al
|
||||
testb $1, %al
|
||||
jz x_ok
|
||||
incl %ecx
|
||||
x_ok:
|
||||
testb $2, %al
|
||||
jz y_ok
|
||||
incl %ebx
|
||||
jmp __jloop
|
||||
y_ok:
|
||||
testb $1, %al
|
||||
jnz __jloop
|
||||
sti
|
||||
shrb $4, %al
|
||||
movl 8(%esp), %edx
|
||||
movl %ecx, (%edx)
|
||||
movl 12(%esp), %edx
|
||||
movl %ebx, (%edx)
|
||||
andl $3, %eax
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
/* from vga_gfx.c ---------------------------------------------------------- */
|
||||
|
||||
/* void x_open_asm(int mode) */
|
||||
/* stack frame:
|
||||
esp: old_es
|
||||
esp+2: old_ebx
|
||||
esp+6: old_esi
|
||||
esp+10: old_edi
|
||||
esp+14: ret_addr
|
||||
esp+18: mode
|
||||
*/
|
||||
.globl _x_open_asm
|
||||
_x_open_asm:
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushw %es
|
||||
|
||||
movl 18(%esp), %ebx
|
||||
movw __go32_info_block+26, %es /* __dos_ds */
|
||||
movw $0x03c4, %dx
|
||||
movb _x_clocktab(%ebx), %cl
|
||||
orb %cl, %cl
|
||||
je x_Skip_Reset
|
||||
|
||||
movw $0x100, %ax
|
||||
outw %ax, %dx
|
||||
|
||||
movw $0x3c2, %dx
|
||||
movb %cl, %al
|
||||
outb %al, %dx
|
||||
|
||||
movw $0x3c4, %dx
|
||||
movw $0x300, %ax
|
||||
outw %ax, %dx
|
||||
x_Skip_Reset:
|
||||
movw $0x604, %ax
|
||||
outw %ax, %dx
|
||||
|
||||
cld
|
||||
movl $0xa0000, %edi
|
||||
xorl %eax, %eax
|
||||
movl $0x8000, %ecx
|
||||
rep
|
||||
stosw
|
||||
|
||||
movw $0x3d4, %dx
|
||||
xorl %esi, %esi
|
||||
movw $3, %cx
|
||||
cmpb $5, %bl
|
||||
jbe x_CRT1
|
||||
movw $10, %cx
|
||||
x_CRT1:
|
||||
movw _x_regtab(,%esi,2), %ax
|
||||
outw %ax, %dx
|
||||
incl %esi
|
||||
decw %cx
|
||||
jne x_CRT1
|
||||
|
||||
movl _x_verttab(,%ebx,4),%esi
|
||||
cmpl $0, %esi
|
||||
je x_noerr
|
||||
cmpl $1, %esi
|
||||
je x_Set400
|
||||
|
||||
movw $8, %cx
|
||||
x_CRT2:
|
||||
movw (%esi), %ax
|
||||
outw %ax, %dx
|
||||
incl %esi
|
||||
incl %esi
|
||||
decl %ecx
|
||||
jne x_CRT2
|
||||
jmp x_noerr
|
||||
|
||||
x_Set400:
|
||||
movw $0x4009, %ax
|
||||
outw %ax, %dx
|
||||
x_noerr:
|
||||
|
||||
popw %es
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
ret
|
||||
|
||||
/* bitmap blitting function */
|
||||
/* void VESA_blit(void *mem,ULONG width,ULONG height,ULONG bitmapline,ULONG videoline,UWORD selector) */
|
||||
/* stack frame:
|
||||
esp: old_es
|
||||
esp+2: old_esi
|
||||
esp+6: old_edi
|
||||
esp+10: ret_addr
|
||||
esp+14: mem
|
||||
esp+18: width
|
||||
esp+22: height
|
||||
esp+26: bitmapline
|
||||
esp+30: videoline
|
||||
esp+34: selector
|
||||
*/
|
||||
.globl _VESA_blit
|
||||
_VESA_blit:
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushw %es
|
||||
movw 34(%esp), %es
|
||||
movl 14(%esp), %esi
|
||||
xorl %edi, %edi
|
||||
movl 18(%esp), %edx
|
||||
subl %edx, 26(%esp)
|
||||
subl %edx, 30(%esp)
|
||||
shrl $4, %edx
|
||||
movl 22(%esp), %ecx
|
||||
0:
|
||||
movl %edx, %eax
|
||||
1:
|
||||
movsl
|
||||
movsl
|
||||
movsl
|
||||
movsl
|
||||
decl %eax
|
||||
jnz 1b
|
||||
addl 30(%esp), %edi
|
||||
addl 26(%esp), %esi
|
||||
decl %ecx
|
||||
jnz 0b
|
||||
popw %es
|
||||
popl %esi
|
||||
popl %edi
|
||||
ret
|
||||
|
||||
/* interlaced bitmap blitting function */
|
||||
/* void VESA_i_blit(void *mem,ULONG width,ULONG height,ULONG bitmapline,ULONG videoline,UWORD selector) */
|
||||
/* stack frame:
|
||||
esp: old_es
|
||||
esp+2: old_ebx
|
||||
esp+6: old_esi
|
||||
esp+10: old_edi
|
||||
esp+14: ret_addr
|
||||
esp+18: mem
|
||||
esp+22: width
|
||||
esp+26: height
|
||||
esp+30: bitmapline
|
||||
esp+34: videoline
|
||||
esp+38: selector
|
||||
*/
|
||||
.globl _VESA_i_blit
|
||||
_VESA_i_blit:
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushw %es
|
||||
movw 38(%esp), %es
|
||||
movl 18(%esp), %esi
|
||||
xorl %edi, %edi
|
||||
movl 22(%esp), %ebx
|
||||
movl 34(%esp), %edx
|
||||
subl $4, %edx
|
||||
shll $1, 34(%esp)
|
||||
subl %ebx, 30(%esp)
|
||||
subl %ebx, 34(%esp)
|
||||
shrl $3, %ebx
|
||||
movl 26(%esp), %ecx
|
||||
shll $16, %ecx
|
||||
orl %ebx, %ecx
|
||||
0:
|
||||
movb %cl, %ch
|
||||
1:
|
||||
lodsl
|
||||
stosl
|
||||
movl %eax, %ebx
|
||||
andl $0xf0f0f0f0, %eax
|
||||
shrl $1, %ebx
|
||||
andl $0x07070707, %ebx
|
||||
orl %ebx, %eax
|
||||
movl %eax, %es:(%edi,%edx)
|
||||
lodsl
|
||||
stosl
|
||||
movl %eax, %ebx
|
||||
andl $0xf0f0f0f0, %eax
|
||||
shrl $1, %ebx
|
||||
andl $0x07070707, %ebx
|
||||
orl %ebx, %eax
|
||||
movl %eax, %es:(%edi,%edx)
|
||||
decb %ch
|
||||
jnz 1b
|
||||
addl 34(%esp), %edi
|
||||
addl 30(%esp), %esi
|
||||
subl $0x10000, %ecx
|
||||
testl $0xffff0000, %ecx
|
||||
jnz 0b
|
||||
popw %es
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
ret
|
||||
|
||||
/* Procedure for copying atari screen to x-mode videomemory */
|
||||
/* void x_blit(void *mem,UBYTE lines,ULONG change,ULONG videoline) */
|
||||
/* stack frame:
|
||||
esp: old_es
|
||||
esp+2: old_ebx
|
||||
esp+6: old_esi
|
||||
esp+10: old_edi
|
||||
esp+14: ret_addr
|
||||
esp+18: mem
|
||||
esp+22: lines
|
||||
esp+26: change
|
||||
esp+30: videoline
|
||||
*/
|
||||
.globl _x_blit
|
||||
_x_blit:
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushw %es
|
||||
movl 18(%esp), %esi
|
||||
movw __go32_info_block+26, %es /* __dos_ds */
|
||||
subl $4, 26(%esp)
|
||||
|
||||
movb $2, %bl
|
||||
movw $0x3c4, %dx
|
||||
cld
|
||||
|
||||
movl $0xa0000, %edi
|
||||
.ALIGN 4
|
||||
1:
|
||||
movb $0x11, %bh
|
||||
2:
|
||||
movw %bx, %ax
|
||||
outw %ax, %dx
|
||||
movl $20, %ecx
|
||||
.ALIGN 4
|
||||
3:
|
||||
movb (%esi), %al
|
||||
movb 4(%esi), %ah
|
||||
shrd $16, %eax, %eax
|
||||
movb 8(%esi), %al
|
||||
movb 12(%esi), %ah
|
||||
shrd $16, %eax, %eax
|
||||
addl $16, %esi
|
||||
stosl
|
||||
|
||||
decl %ecx
|
||||
jne 3b
|
||||
|
||||
subl $319, %esi
|
||||
subl $80, %edi
|
||||
addb %bh, %bh
|
||||
jnc 2b
|
||||
|
||||
addl 26(%esp), %esi
|
||||
addl 30(%esp), %edi
|
||||
decl 22(%esp)
|
||||
jne 1b
|
||||
|
||||
popw %es
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
ret
|
||||
|
||||
/* Procedure for copying atari screen to x-mode videomemory interlaced with darker-lines (-video 3)*/
|
||||
/* void x_blit(void *mem,UBYTE lines,ULONG change,ULONG videoline) */
|
||||
/* stack frame:
|
||||
esp: old_es
|
||||
esp+2: old_ebx
|
||||
esp+6: old_esi
|
||||
esp+10: old_edi
|
||||
esp+14: ret_addr
|
||||
esp+18: mem
|
||||
esp+22: lines
|
||||
esp+26: change
|
||||
esp+30: videoline
|
||||
*/
|
||||
.globl _x_blit_i2
|
||||
_x_blit_i2:
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushw %es
|
||||
movl 18(%esp), %esi
|
||||
movw __go32_info_block+26, %es /* __dos_ds */
|
||||
subl $4, 26(%esp)
|
||||
|
||||
movb $2, %bl
|
||||
cld
|
||||
|
||||
movl $0xa0000, %edi
|
||||
.ALIGN 4
|
||||
1:
|
||||
movb $0x11, %bh
|
||||
2:
|
||||
movw $0x3c4, %dx
|
||||
movw %bx, %ax
|
||||
outw %ax, %dx
|
||||
movl $20, %ecx
|
||||
.ALIGN 4
|
||||
3:
|
||||
movb (%esi), %al
|
||||
movb 4(%esi), %ah
|
||||
shrd $16, %eax, %eax
|
||||
movb 8(%esi), %al
|
||||
movb 12(%esi), %ah
|
||||
shrd $16, %eax, %eax
|
||||
addl $16, %esi
|
||||
movl %eax, %edx
|
||||
stosl
|
||||
shrl $1, %edx
|
||||
andl $0xf0f0f0f0, %eax
|
||||
andl $0x07070707, %edx
|
||||
orl %edx, %eax
|
||||
/* .BYTE 0x26 */
|
||||
movl %eax, %es:76(%edi)
|
||||
|
||||
decl %ecx
|
||||
jne 3b
|
||||
|
||||
subl $319, %esi
|
||||
subl $80, %edi
|
||||
addb %bh, %bh
|
||||
jnc 2b
|
||||
|
||||
addl 26(%esp), %esi
|
||||
addl 30(%esp), %edi
|
||||
decl 22(%esp)
|
||||
jne 1b
|
||||
|
||||
popw %es
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
ret
|
||||
|
||||
/* this routine makes darker copy of buffer 'source' in buffer 'target' */
|
||||
/* void make_darker(void *target,void *source,int bytes) */
|
||||
/* stack frame:
|
||||
esp: old_esi
|
||||
esp+4: old_edi
|
||||
esp+8: ret_addr
|
||||
esp+12: target
|
||||
esp+16: source
|
||||
esp+20: bytes
|
||||
*/
|
||||
/* ALLEGRO support has been removed
|
||||
.globl _make_darker
|
||||
_make_darker:
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
movl 12(%esp), %edi
|
||||
movl 16(%esp), %esi
|
||||
movl 20(%esp), %ecx
|
||||
subl $4, %edi
|
||||
shr $2, %ecx
|
||||
0:
|
||||
movl (%esi), %eax
|
||||
movl %eax, %edx
|
||||
andl $0xf0f0f0f0, %eax
|
||||
shrl $1, %edx
|
||||
addl $4, %esi
|
||||
addl $4, %edi
|
||||
andl $0x07070707, %edx
|
||||
orl %edx, %eax
|
||||
decl %ecx
|
||||
movl %eax, (%edi)
|
||||
jnz 0b
|
||||
popl %esi
|
||||
popl %edi
|
||||
ret
|
||||
*/
|
||||
|
||||
/* Vertical retrace control */
|
||||
/* void v_ret(void) */
|
||||
.globl _v_ret
|
||||
_v_ret:
|
||||
movw $0x03da, %dx
|
||||
1:
|
||||
inb %dx, %al
|
||||
testb $8, %al
|
||||
jnz 1b
|
||||
2:
|
||||
inb %dx, %al
|
||||
testb $8, %al
|
||||
jz 2b
|
||||
ret
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* vga_gfx.c - DOS VGA graphics routines
|
||||
*
|
||||
* Copyright (c) 2001 Robert Golias
|
||||
* Copyright (c) 2001-2003 Atari800 development team (see DOC/CREDITS)
|
||||
*
|
||||
* This file is part of the Atari800 emulator project which emulates
|
||||
* the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
|
||||
*
|
||||
* Atari800 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Atari800 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Atari800; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <go32.h>
|
||||
#include <dpmi.h>
|
||||
#include <sys/farptr.h>
|
||||
#include <string.h>
|
||||
#include "atari.h"
|
||||
#include "config.h"
|
||||
#include "vga_gfx.h"
|
||||
|
||||
#ifdef AT_USE_ALLEGRO
|
||||
#include <allegro.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#ifndef AT_USE_ALLEGRO
|
||||
|
||||
/***************************************************************************
|
||||
* VESA2 support *
|
||||
***************************************************************************/
|
||||
|
||||
/*structure that is returned by VESA function 4f00 (get vesa info) */
|
||||
struct VESAinfo
|
||||
{
|
||||
char sig[4];
|
||||
UWORD version;
|
||||
ULONG OEM; /*dos pointer*/
|
||||
ULONG capabilities;
|
||||
ULONG videomodes; /*dos pointer*/
|
||||
UWORD memory;
|
||||
UWORD oemRevision;
|
||||
ULONG oemVendorName; /*dos pointer*/
|
||||
ULONG oemProductName; /*dos pointer*/
|
||||
ULONG oemProductRev; /*dos pointer*/
|
||||
UBYTE reserved[222+256];
|
||||
}__attribute__((packed));
|
||||
/*structure that is returned by VESA function 4f01 (get videomode info) */
|
||||
struct modeInfo
|
||||
{
|
||||
UWORD attributes;
|
||||
UBYTE winAAttributes;
|
||||
UBYTE winBAttributes;
|
||||
UWORD winGranularity;
|
||||
UWORD winSize;
|
||||
UWORD winASegment;
|
||||
UWORD winBSegment;
|
||||
ULONG winfunc; /*dos pointer*/
|
||||
UWORD bytesPerScanline;
|
||||
|
||||
UWORD XResolution;
|
||||
UWORD YResolution;
|
||||
UBYTE XCharSize;
|
||||
UBYTE YCharSize;
|
||||
UBYTE numOfPlanes;
|
||||
UBYTE bitsPerPixel;
|
||||
UBYTE numOfBanks;
|
||||
UBYTE memoryModel;
|
||||
UBYTE bankSize;
|
||||
UBYTE numOfImagePages;
|
||||
UBYTE reserved;
|
||||
|
||||
UBYTE redMaskSize;
|
||||
UBYTE redFieldPosition;
|
||||
UBYTE greenMaskSize;
|
||||
UBYTE greenFieldPosition;
|
||||
UBYTE blueMaskSize;
|
||||
UBYTE blueFieldPosition;
|
||||
UBYTE reservedMaskSize;
|
||||
UBYTE reservedPosition;
|
||||
UBYTE directAttributes;
|
||||
|
||||
ULONG basePtr;
|
||||
ULONG offScreenMemoryOffset;
|
||||
ULONG offScreenMemorySize;
|
||||
UBYTE reserved2[216];
|
||||
}__attribute__((packed));
|
||||
|
||||
|
||||
/*functions for mapping physical memory and allocating the corresponding selector */
|
||||
static UBYTE mapPhysicalMemory(ULONG addr,ULONG length,ULONG *linear)
|
||||
{
|
||||
__dpmi_meminfo meminfo;
|
||||
|
||||
if (addr>=0x100000)
|
||||
{
|
||||
meminfo.size=length;
|
||||
meminfo.address=addr;
|
||||
*linear=0;
|
||||
if (__dpmi_physical_address_mapping(&meminfo)!=0)
|
||||
return FALSE;
|
||||
*linear=meminfo.address;
|
||||
__dpmi_lock_linear_region(&meminfo);
|
||||
}
|
||||
else
|
||||
*linear=addr; /* there is no way for mapping memory under 1MB with dpmi0.9
|
||||
so we suppose that the address remains the same*/
|
||||
return TRUE;
|
||||
}
|
||||
static UBYTE unmapPhysicalMemory(ULONG *linear)
|
||||
{
|
||||
__dpmi_meminfo meminfo;
|
||||
|
||||
if (*linear>=0x100000)
|
||||
{
|
||||
meminfo.address=*linear;
|
||||
__dpmi_free_physical_address_mapping(&meminfo);
|
||||
} /* when <1MB, suppose that it lies in regular DOS memory and does not
|
||||
requires freeing... */
|
||||
*linear=0;
|
||||
return TRUE;
|
||||
}
|
||||
static UBYTE createSelector(ULONG addr,ULONG length,int *selector)
|
||||
{
|
||||
*selector=__dpmi_allocate_ldt_descriptors(1);
|
||||
if (*selector<0)
|
||||
{
|
||||
*selector=0;
|
||||
return FALSE;
|
||||
}
|
||||
if (__dpmi_set_segment_base_address(*selector,addr)<0)
|
||||
{
|
||||
__dpmi_free_ldt_descriptor(*selector);
|
||||
return FALSE;
|
||||
}
|
||||
if (__dpmi_set_segment_limit(*selector,length-1)<0)
|
||||
{
|
||||
__dpmi_free_ldt_descriptor(*selector);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#if 0
|
||||
/* unused by our code, warning suppressed */
|
||||
static UBYTE freeSelector(int *selector)
|
||||
{
|
||||
if (*selector>0)
|
||||
{
|
||||
__dpmi_free_ldt_descriptor(*selector);
|
||||
*selector=0;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static UBYTE getPhysicalMemory(ULONG addr,ULONG length,ULONG *linear,int *selector)
|
||||
{
|
||||
if (!mapPhysicalMemory(addr,length,linear))
|
||||
{
|
||||
selector=0;
|
||||
return FALSE;
|
||||
}
|
||||
if (!createSelector(*linear,length,selector))
|
||||
{
|
||||
unmapPhysicalMemory(linear);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
static UBYTE freePhysicalMemory(ULONG *linear,int *selector)
|
||||
{
|
||||
unmapPhysicalMemory(linear);
|
||||
linear=0;
|
||||
selector=0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* VESA getmode - finds the desired videomode*/
|
||||
UBYTE VESA_getmode(int width,int height,UWORD *videomode,ULONG *memaddress,ULONG *line,ULONG *memsize)
|
||||
{
|
||||
__dpmi_regs rg;
|
||||
struct VESAinfo vInfo;
|
||||
struct modeInfo mInfo;
|
||||
UWORD modesAddr;
|
||||
UWORD mode;
|
||||
UWORD modes[0x1000]; /* modes list needs to be saved (K.N.) */
|
||||
int i;
|
||||
|
||||
*videomode=0;
|
||||
|
||||
if (_go32_info_block.size_of_transfer_buffer < 512)
|
||||
return FALSE; /*transfer buffer too small*/
|
||||
|
||||
memset(&vInfo,0,sizeof(vInfo));
|
||||
strncpy(vInfo.sig,"VBE2",4);
|
||||
dosmemput(&vInfo,sizeof(vInfo),__tb&0xfffff);
|
||||
rg.x.ax=0x4f00;
|
||||
rg.x.di=__tb & 0xf;
|
||||
rg.x.es=(__tb >>4 )&0xffff;
|
||||
__dpmi_int(0x10,&rg);
|
||||
dosmemget(__tb&0xfffff,sizeof(vInfo),&vInfo);
|
||||
if (rg.x.ax!=0x004f || strncmp(vInfo.sig,"VESA",4) || (vInfo.version<0x200) )
|
||||
return FALSE; /*vesa 2.0 not found*/
|
||||
|
||||
/*now we must search the videomode list for desired screen resolutin*/
|
||||
modesAddr=( (vInfo.videomodes>>12)&0xffff0)+(vInfo.videomodes&0xffff);
|
||||
dosmemget(__tb&0xfffff, sizeof(modes), modes); /* save modes list (K.N.) */
|
||||
for (i = 0; (mode = modes[i]) != 0xffff; i++)
|
||||
{
|
||||
modesAddr+=2;
|
||||
|
||||
rg.x.ax=0x4f01;
|
||||
rg.x.cx=mode;
|
||||
rg.x.es=(__tb>>4) & 0xffff;
|
||||
rg.x.di=__tb & 0xf;
|
||||
__dpmi_int(0x10,&rg); /*get vesa-mode info*/
|
||||
if (rg.h.al!=0x4f) return FALSE; /*function not supported, but we need it*/
|
||||
|
||||
|
||||
if (rg.h.ah!=0) continue; /*mode not supported*/
|
||||
dosmemget(__tb&0xfffff,sizeof(mInfo)-216,&mInfo); /*note: we don't need the reserved bytes*/
|
||||
if ((mInfo.attributes&0x99) != 0x99) continue;
|
||||
/*0x99 = available, color, graphics mode, LFB available*/
|
||||
if (mInfo.XResolution!=width || mInfo.YResolution!=height) continue;
|
||||
if (mInfo.numOfPlanes!=1 || mInfo.bitsPerPixel!=8 || mInfo.memoryModel!=4) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode==0xffff) return FALSE;
|
||||
|
||||
*line=mInfo.bytesPerScanline;
|
||||
*memsize=*line * height;
|
||||
*videomode=(mode&0x03ff)|0x4000; /*LFB version of video mode*/
|
||||
*memaddress=mInfo.basePtr;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* VESA_open - opens videomode and allocates the corresponding selector */
|
||||
UBYTE VESA_open(UWORD mode,ULONG memaddress,ULONG memsize,ULONG *linear,int *selector)
|
||||
{
|
||||
__dpmi_regs rg;
|
||||
|
||||
rg.x.ax=0x4f02;
|
||||
rg.x.bx=mode;
|
||||
__dpmi_int(0x10,&rg);
|
||||
if (rg.x.ax!=0x004f) return FALSE;
|
||||
|
||||
if (!getPhysicalMemory(memaddress,memsize,linear,selector))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
UBYTE VESA_close(ULONG *linear,int *selector)
|
||||
{
|
||||
__dpmi_regs rg;
|
||||
|
||||
freePhysicalMemory(linear,selector);
|
||||
rg.x.ax=0x0003;
|
||||
__dpmi_int(0x10,&rg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* XMODE support *
|
||||
***************************************************************************/
|
||||
|
||||
/* Procedure for initializing X-mode. Possible modes:
|
||||
* 0 320x175 6 360x175
|
||||
* 1 320x200 7 360x200
|
||||
* 2 320x240 8 360x240
|
||||
* 3 320x350 9 360x350
|
||||
* 4 320x400 a 360x400
|
||||
* 5 320x480 b 360x480
|
||||
*
|
||||
* This procedure is based on Guru mode by Per Ole Klemetsrud
|
||||
*/
|
||||
UWORD x_regtab[]={0x0e11,0x0014,0xe317,0x6b00,0x5901,
|
||||
0x5a02,0x8e03,0x5e04,0x8a05,0x2d13};
|
||||
UWORD x_vert480[]={0x4009,0x3e07,0x0b06,0xea10,0x8c11,
|
||||
0xe715,0x0416,0xdf12,0xdf12};
|
||||
UWORD x_vert350[]={0x4009,0x1f07,0xbf06,0x8310,0x8511,
|
||||
0x6315,0xba16,0x5d12,0x5d12};
|
||||
UBYTE x_clocktab[]={0xa3,0x0,0xe3,0xa3,0x0,0xe3,0xa7,0x67,
|
||||
0xe7,0xa7,0x67,0xe7};
|
||||
UWORD *x_verttab[]={x_vert350+1,(void*)0,x_vert480+1,x_vert350,(void*)1,x_vert480,
|
||||
x_vert350+1,(void*)0,x_vert480+1,x_vert350,(void*)1,x_vert480};
|
||||
|
||||
void x_open_asm(int mode); /* in vga_asm.s */
|
||||
|
||||
UBYTE x_open(UWORD mode)
|
||||
{
|
||||
__dpmi_regs rg;
|
||||
|
||||
if (mode>0xb) return 0;
|
||||
rg.x.ax = 0x1a00;
|
||||
__dpmi_int(0x10,&rg);
|
||||
if (rg.h.al != 0x1a) return 0;
|
||||
|
||||
rg.x.ax=0x0013;
|
||||
__dpmi_int(0x10,&rg);
|
||||
|
||||
x_open_asm(mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* ALLEGRO support *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/*this routine maps allegro's bitmap to given memory */
|
||||
void Map_bitmap(BITMAP *bitmap,void *memory,int width,int height)
|
||||
{
|
||||
int i;
|
||||
|
||||
bitmap->dat=memory;
|
||||
bitmap->line[0]=memory;
|
||||
for (i=1;i<height;i++)
|
||||
bitmap->line[i]=bitmap->line[i-1]+width;
|
||||
}
|
||||
/*this routine maps allegro's bitmap to given memory interlaced with memory2*/
|
||||
void Map_i_bitmap(BITMAP *bitmap,void *memory,void *memory2,int width,int height)
|
||||
{
|
||||
int i;
|
||||
|
||||
bitmap->dat=memory;
|
||||
bitmap->line[0]=memory;
|
||||
bitmap->line[1]=memory2;
|
||||
for (i=2;i<height;i+=2)
|
||||
{
|
||||
bitmap->line[i]=bitmap->line[i-2]+width;
|
||||
bitmap->line[i+1]=bitmap->line[i-1]+width;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef VGA_GFX_H_
|
||||
#define VGA_GFX_H_
|
||||
|
||||
#include "atari.h"
|
||||
|
||||
#ifndef AT_USE_ALLEGRO
|
||||
|
||||
/****************************** VESA2 **********************************/
|
||||
|
||||
/*find given VESA mode and get informations about it*/
|
||||
extern UBYTE VESA_getmode(int width,int height,UWORD *videomode,ULONG *memaddress,ULONG *line,ULONG *memsize);
|
||||
/*open given vesa mode*/
|
||||
extern UBYTE VESA_open(UWORD mode,ULONG memaddress,ULONG memsize,ULONG *linear,int *selector);
|
||||
/*close VESA mode*/
|
||||
extern UBYTE VESA_close(ULONG *linear,int *selector);
|
||||
/*draw atari screen in VESA mode*/
|
||||
extern void VESA_blit(void *mem,ULONG width,ULONG height,ULONG bitmapline,ULONG videoline,UWORD selector);
|
||||
/*draw atari screen interlaced with darker lines*/
|
||||
extern void VESA_i_blit(void *mem,ULONG width,ULONG height,ULONG bitmapline,ULONG videoline,UWORD selector);
|
||||
|
||||
/****************************** XMODE **********************************/
|
||||
|
||||
/*open given x-mode*/
|
||||
extern UBYTE x_open(UWORD mode);
|
||||
/*draw normal or interlaced atari screen*/
|
||||
extern void x_blit(void *mem,UBYTE lines,ULONG change,ULONG videoline);
|
||||
/*draw atari screen interlaced with darker lines*/
|
||||
extern void x_blit_i2(void *mem,UBYTE lines,ULONG change,ULONG videoline);
|
||||
|
||||
#else
|
||||
|
||||
/****************************** ALLEGRO ********************************/
|
||||
|
||||
/*map allegro's bitmap into given memory*/
|
||||
extern void Map_bitmap(BITMAP *bitmap,void *memory,int width,int height);
|
||||
/*map allegro's bitmap into given memory interlaced with memory2*/
|
||||
extern void Map_i_bitmap(BITMAP *bitmap,void *memory,void *memory2,int width,int height);
|
||||
/*make darker copy of buffer 'source'*/
|
||||
extern void make_darker(void *target,void *source,int bytes);
|
||||
|
||||
#endif /* AT_USE_ALLEGRO */
|
||||
|
||||
/*vertical retrace control*/
|
||||
extern void v_ret(void);
|
||||
|
||||
#endif /* VGA_GFX_H_ */
|
||||
Reference in New Issue
Block a user