aboutsummaryrefslogtreecommitdiff
path: root/vds.h
blob: c006e1d55965feccc35b1b9dc7417dfd37fe78b3 (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
/*
 * VBMouse - Interface to the Virtual DMA Service (VDS)
 * Copyright (C) 2022 Javier S. Pedro
 *
 * This program 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.

 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef VDS_H
#define VDS_H

#include <stdbool.h>
#include <stdint.h>

typedef unsigned char vdserr;
enum {
	VDS_SUCCESSFUL = 0,
	VDS_REGION_NOT_CONTIGUOUS = 1,
	VDS_REGION_NOT_ALIGNED    = 2,
	VDS_UNABLE_TO_LOCK        = 3,
	VDS_NO_BUFFER_AVAIL       = 4,
	VDS_REGION_TOO_LARGE      = 5,
	VDS_BUFFER_IN_USE         = 6,
	VDS_INVALID_REGION        = 7,
	VDS_REGION_NOT_LOCKED     = 8,
	VDS_TOO_MANY_PAGES        = 9,
	VDS_INVALID_BUFFER_ID     = 0xA,
	VDS_BUFFER_BOUNDARY       = 0xB,
	VDS_INVALID_DMA_CHANNEL   = 0xC,
	VDS_DISABLE_COUNT_OVRFLOW = 0xD,
	VDS_DISABLE_COUNT_UNDFLOW = 0xE,
	VDS_NOT_SUPPORTED         = 0xF,
	VDS_FLAGS_NOT_SUPPORTED   = 0x10,
};

enum {
/*
   Bit 1 = Automatically copy to/from buffer
   Bit 2 = Disable automatic buffer allocation
   Bit 3 = Disable automatic remap feature
   Bit 4 = Region must not cross 64K physical alignment boundary
   Bit 5 = Region must not cross 128K physical alignment boundary
   Bit 6 = Copy page-table for scatter/gather remap
   Bit 7 = Allow non-present pages for scatter/gather remap
*/
	VDS_AUTO_COPY_DATA = 1 << 1,
	VDS_NO_AUTO_ALLOC  = 1 << 2,
	VDS_NO_AUTO_REMAP  = 1 << 3,
	VDS_ALIGN_64K      = 1 << 4,
	VDS_ALIGN_128K     = 1 << 5
};

/** DMA Descriptor structure. Describes a potentially DMA-lockable buffer. */
typedef _Packed struct VDS_DDS
{
	/** Size of this buffer. */
	uint32_t regionSize;
	/** Logical/segmented address of this buffer, offset part */
	uint32_t offset;
	/** Segment of this buffer. */
	uint16_t segOrSelector;
	/** Internal VDS buffer ID. */
	uint16_t bufferId;
	/** Physical address of this buffer. */
	uint32_t physicalAddress;
} VDS_DDS;

static bool vds_available(void);
#pragma aux vds_available = \
	"mov ax, 0x40" \
	"mov es, ax" \
	"mov al, es:[0x7B]" \
	"and al, 0x20" \
	"setnz al" \
	__value [al] \
	__modify [ax es]

/** Locks an already allocated buffer into a physical memory location.
  * regionSize, offset and segment must be valid in the DDS,
  * while the physical address is returned. */
static vdserr vds_lock_dma_buffer_region(VDS_DDS __far * dds, unsigned char flags);
#pragma aux vds_lock_dma_buffer_region = \
	"stc"              /* If nothing happens, assume failure. */ \
	"mov ax, 0x8103" \
	"int 0x4B" \
	"jc fail" \
	"mov al, 0" \
	"jmp end" \
	"fail: test al, al" \
	"jnz end" \
	"mov al, 0xFF"       /* Force a error code if there was none. */ \
	"end:" \
	__parm [es di] [dx] \
	__value [al] \
	__modify [ax]

/** Unlocks a locked buffer. */
static vdserr vds_unlock_dma_buffer_region(VDS_DDS __far * dds, unsigned char flags);
#pragma aux vds_unlock_dma_buffer_region = \
	"stc" \
	"mov ax, 0x8104" \
	"int 0x4B" \
	"jc fail" \
	"mov al, 0" \
	"jmp end" \
	"fail: test al, al" \
	"jnz end" \
	"mov al, 0xFF" \
	"end:" \
	__parm [es di] [dx] \
	__value [al] \
	__modify [ax]

#endif