中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 请问如何编写TC下的内存映射程序?
作者:
标题: 请问如何编写TC下的内存映射程序? 上一主题 | 下一主题
yunlong
初级用户




积分 105
发帖 1
注册 2002-12-26
状态 离线
『楼 主』:  请问如何编写TC下的内存映射程序? [已使用 LLM 解释]

我做了一块CAN通信板(PC/104模块的,在硬件设计上采用了一片CPLD作为CAN和PC/104总线之间的桥梁),以前做的就是那种I/O方式的,比如说我用的地址是0x220和0x221,整个测试程序就是inportb(0x220)、outportb(0x221,dat)起CAN和PC/104之间数据交换作用,现在要求改设计,改成内存映射方式,把SMEMR和SMEMW以及ALE都连接到了CPLD上了。现在我的问题是:一方面在CPLD上具体如何编写VHDL语言以便实现内存映射,另一方面是在如何编写TC下的内存映射程序,即怎么样编写才是内存映射方式而不是I/O方式?对内存映射我只知道是在内存区开辟一块内存用作存取数据用,其他的具体操作我就不知道了(注:PC/104总线完全兼容ISA总线)谢谢!
LLM 解释

一、TC下内存映射程序的编写方法

内存映射I/O的核心是将硬件寄存器映射到CPU的物理内存地址空间,通过直接读写内存地址而非in/out指令访问硬件。在TC中实现需以下步骤:

1. 关键前提:硬件物理地址分配

需先为CAN板分配一个未被系统占用的物理内存地址段(通常为ISA总线的内存映射区,如1MB以下的保留区或扩展内存,但需注意:ISA总线的内存映射地址需满足AEN=0SMEMR#/SMEMW#有效,地址范围通常为0xC0000~0xFFFFF中的未使用区域,需避免与显存、BIOS、扩展卡ROM冲突)。假设分配的基地址为0xD0000(需与CPLD设计一致)。

2. TC中的实现方式

TC运行于实模式,默认只能直接访问640KB以下的常规内存,而ISA内存映射区多在640KB~1MB之间(0xA0000~0xFFFFF),属于保留内存区,需通过段地址+偏移地址的方式访问(实模式下物理地址=段地址×16+偏移地址)。

示例代码框架(假设基地址0xD0000,寄存器偏移为0x00和0x01):

#include <dos.h>
#include <mem.h>

// 硬件物理基地址(需与CPLD一致)
#define BASE_ADDR 0xD0000  
// 转换为段地址:BASE_ADDR / 16 = 0xD000
#define HW_SEG    0xD000  

// 内存映射寄存器指针(通过段地址+偏移访问)
unsigned char far *pReg0 = (unsigned char far *)MK_FP(HW_SEG, 0x00); // 对应物理地址0xD0000
unsigned char far *pReg1 = (unsigned char far *)MK_FP(HW_SEG, 0x01); // 对应物理地址0xD0001

void main() {
    unsigned char data;

    // 读寄存器0(替代inportb(0x220))
    data = *pReg0;  

    // 写寄存器1(替代outportb(0x221, dat))
    *pReg1 = 0x5A;  

    // 注意:若地址段被系统标记为"不可写",需先修改内存控制寄存器(如EMS芯片或系统BIOS设置),但实模式下通常无需额外配置,硬件会直接响应
}

3. 与I/O方式的核心区别

  • I/O方式:用inportb/outportb函数,对应CPU的IN/OUT指令,访问I/O地址空间(地址范围0x0000~0xFFFF)。
  • 内存映射方式:用far指针直接读写内存地址,对应CPU的MOV指令,访问物理内存地址空间,无需额外指令。

二、当年常见误解的澄清

当年很多开发者混淆“内存映射”与“常规内存”,错误认为需要在常规内存(640KB以下)中“开辟空间”,实际内存映射I/O的地址是硬件直接响应的物理地址,并非从系统内存中划分,CPU只是通过内存读写指令触发硬件操作。

三、CPLD设计的VHDL逻辑提示(非代码,仅原理)

CPLD需实现地址译码+读写控制,核心逻辑如下:

  1. 地址译码:根据ISA总线的地址线(A0~A19)、AEN(需为0,标识非DMA周期)、SMEMR#/SMEMW#(内存读写使能),判断是否访问CAN板的映射地址。
  2. 读写控制:当地址匹配且SMEMR#有效时,将硬件数据输出到ISA总线的数据线(D0~D7);当SMEMW#有效时,锁存总线数据到硬件寄存器。
  3. ALE信号:用于锁存地址线与控制线,确保读写周期中地址稳定。

(注:具体VHDL代码需根据地址分配、寄存器数量调整,当年常见的错误是忽略AEN信号导致DMA周期误触发,或地址译码不完整导致与其他设备冲突。)

四、补充说明

PC/104总线兼容ISA总线,内存映射的硬件与软件逻辑完全遵循ISA规范,需注意:

  • 内存映射地址需通过跳线或DIP开关设置,确保与系统中其他设备无冲突;
  • 实模式下TC无法直接访问1MB以上的扩展内存,若硬件映射到扩展内存,需进入保护模式(但当年很少这么做,通常使用1MB以下的ISA保留区)。

当年的跟帖可能会提到“内存地址冲突检测工具”(如MEM命令或第三方硬件检测软件),这是验证地址是否可用的关键步骤,需优先确认硬件地址的唯一性。



2002-12-26 00:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: