Mail Archives: djgpp/2005/11/29/11:46:50
<blk5743 AT yahoo DOT com DOT tw> wrote in message
news:1133234864 DOT 835782 DOT 126770 AT g49g2000cwa DOT googlegroups DOT com...
> hello, this is my code of BC++ 31
> i need to convert these code to DJGPP
> i must know physical address of structrues and buffer which i must
> assign to BIOS/INT call.
> i do not know how can i get really address for these call that i can
> use FP_SEG,FP_OFF in BC++ 31
(snip)
I tried to port that code. The code below is untested. It may have
errors...
Rod Pemberton
#include <dpmi.h>
__dpmi_regs r;
#define TOTAL_REGIONS 12
#define ULONG unsigned long
#define WORD unsigned short
#define BYTE unsigned char
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
#pragma pack(push,1)
// VDS DMA Descriptor Data Structure
typedef struct
{
ULONG RegionSize; // DDS region size
ULONG Offset; // DDS region offset
WORD Segment; // DDS region segement
WORD BufferID; // to be filled by VDS
ULONG PhysicalAddr; // to be filled by VDS
} DDS;
// VDS EDDS Region Data Structure
typedef struct
{
ULONG PhysicalAddr;
ULONG Size;
} REGION;
// VDS Extended DMA Descriptor Data Structure
typedef struct
{
ULONG RegionSize; // Size of the region
ULONG Offset; // Offset
ULONG Segment; // Segment, the upper 16 bits must be 0.
WORD NumberAvail; // number of region available
WORD NumberUsed; // number of region used, to be filled by VDS
REGION Region[TOTAL_REGIONS]; // physical regions, to be filled by VDS
} EDDS;
// PRD Table Structure
typedef struct // Physical Region Descriptor
{
ULONG BaseAddr; // Region base address
WORD ByteCount; // Region size
WORD EOT; // End of Table
} PRD_T;
//
typedef union
{
ULONG addr;
WORD addr_word[2];
} PRD_T_A;
#pragma pack(pop)
BYTE *r_buffer;
? *VDS_Exist;
? PRD_Pool;
DDS PRD_DDS;
EDDS PRD_EDDS;
PRD_T PRD_Table;
PRT_T_A PRD_Addr;
int LockDMARegion(ULONG size)
{
// Construct the EDDS table.
PRD_EDDS.RegionSize = size;
#if 0
// only if r_buffer points to data within this program...
PRD_EDDS.Offset = (ULONG)r_buffer+__djgpp_conventional_base;
PRD_EDDS.Segment = 0;
#else
// only if r_buffer points to RM data outside this program, like XMS...
PRD_EDDS.Offset = r.x.dx; // RM offset e.g., Lock XMS r.x.dx segment
PRD_EDDS.Segment = r.x.bx; // RM segment e.g., Lock XMS r.x.bx offset
#endif
PRD_EDDS.NumberAvail = TOTAL_REGIONS;
dosmemput(PRD_EDDS,sizeof(PRD_EDDS),__tb); // copy PRD_EDDS to __tb
r.x.ax=0x8105;
r.x.dx=0; // DX = 0 as we does not use page-table EDDS
r.x.es=__tb_segment // ES:DI points to __tb, where PRD_EDDS was copied
r.x.di=__tb_offset
__dpmi_int(0x4b, &r); // Scatter/Gather Lock Region request
dosmemget(__tb,sizeof(PRD_EDDS),PRD_EDDS); // copy returned data to
PRD_EDDS
if (r.x.flags & 1)
return 1; // Scatter/Gather Lock Region request failed.
else
return 0; // Scatter/Gather Lock Region request OK.
}
int Lock_PRD()
{
if((*VDS_Exist) & 0x20)
{
if(PRD_DDS.BufferID == 0)
{
PRD_DDS.RegionSize = sizeof(PRD_Pool);
PRD_DDS.Offset = (ULONG)&PRD_Table+__djgpp_conventional_base;
PRD_DDS.Segment = 0;
dosmemput(PRD_DDS,sizeof(PRD_DDS),__tb); // copy PRD_DDS to __tb
r.x.ax=0x8103;
r.x.dx=0x3c;
r.x.es=__tb_segment // ES:DI points to __tb, where PRD_DDS was
copied
r.x.di=__tb_offset
__dpmi_int(0x4b, &r); // VDS: Lock DMA Buffer Region
dosmemget(__tb,sizeof(PRD_DDS),PRD_DDS); // copy returned data to
PRD_DDS
if (r.x.flags & 1)
return 1;
else
PRD_Addr.addr = PRD_DDS.PhysicalAddr;
}
}
else // VDS not exist
PRD_Addr.addr = (ULONG)&PRD_Table+__djgpp_conventional_base;
return 0;
}
- Raw text -