AON板上的自制计算机

最近,有关由各种非标准组件制造的家用计算机的几篇文章出现在Habré上。我还决定谈论我的计算机,该计算机创建于1993年。出于对Sinclair的普遍热情,我想拥有一台基于z80的完全原始的8位计算机,并且另外为它创建软件,从操作系统开始,以玩具为结尾。它的结果是,在切口下阅读。

创建计算机时出现的第一个问题是体系结构问题。我决定基于z80处理器,它将足够紧凑,而不会在电视上显示图像,而是具有LCD文本屏幕,相当大的键盘,以单音高音扬声器的形式输出声音(当时大多数计算机当时是标准配置)和用于连接的RS232端口到其他计算机进行编程和调试。

但是,由于在1993年中国人还没有为全世界生产电路板,在工厂订购开发和生产的成本非常高,因此出现了为完全原始的电路板获得印刷电路板的问题。然后,我将注意力转向制作呼叫者ID的板卡-自动呼叫者ID。它们在Mitinsky市场上有售,有机会安装我需要但仍需改进的组件。在出售中,有几种这样的印刷电路板,如果我能为我服务,我会选择一块名为“ Rus”的电路板。

让我提醒年轻的读者AON是什么。这是一部带有按钮拨号功能的电话(顺便说一句,那时候它很酷,因为大多数电话都带有旋转磁盘),它由12个按钮和一个9位7段指示灯闪烁组成,该指示灯在其上显示电话号码,如果有可能确定和其他一些信息。 AON板包含一个z80处理器,一个并行端口58055,一个解码器电路,一个计时器58053,一个32千字节的ROM(具有紫外线擦除功能),一个8千字节的静态RAM,与电话线相连的模拟部分,以及可能的其他东西,过去几年我忘记了什么。

12键键盘和呼叫者ID上可用的指示符绝对不适合我,因为它们通常无法输入或显示信息(特别是字母)。因此,决定使用40键的自制键盘和文本24字符2行LCD屏幕,然后开始销售。要连接键盘和LCD屏幕,必须修改AON方案。我做的第一件事是丢弃与电话线相关的整个模拟部分,或者,我只是没有密封它。同时,释放了选择指示器排放量的解码器上的输出支路和并行端口58055上的支路。 LCD屏幕需要4条线来传输信息,但是对于键盘,必须使用解码器。由于键盘上的40个按钮排列成5行8排的矩阵,因此决定将这8个按钮连接到解码器,以便通过向解码器输入提供三行的不同组合并使用KR580VB55从按钮行中读取5个值来进行扫描。因此,键盘上被按下的按钮的扫描代码大小为一个字节,其中前三位确定按钮被按下的列,其余的五位指示该按钮(或一次按下多个按钮)在哪一行中被按下。 。另外,我认为8 KB的RAM是不够的,因此将其替换为32 KB。同时,我不得不在印刷电路板上重新焊接几条走线,幸运的是,8和32 KB RAM盒的引脚排列几乎相同。通过这种方式,我得到了32 KB的ROM和32 KB的RAM(我记得z80最多可以寻址64 KB,因此我使用了最大的地址空间)。此外,另外两行58055连接到RS232串行端口,这是连接到另一台计算机所必需的。我把所有的经济情况都放在了测试人员的案例中。结果就是这样的设计:

图片

硬件完成后,就该创建软件了。在这里应该注意的是,它的创建过程并没有像今天这样看起来。首先,大部分代码都是用汇编器z80编写的(尽管那时,几乎所有用于此类系统的程序都是用汇编器编写的,除了BASIC以外)。为了在第一阶段从汇编器进行编译,我的朋友帮助了我,他有一台Profi计算机-辛克莱克隆机,但装有TR-DOS。然后我开始使用我的IBM PC,它是OS / 2,它在一个单独的窗口中运行MS-DOS,然后在其中启动TR-DOS仿真器,并在其中进行编译。我必须说,当软件显着增长时,编译和组装过程花费了十分钟。第二个问题是没有调试工具,因此,有必要每次都在我的自制计算机上下载所有内容并检查其工作方式(要做的第一件事是以每秒9600位的速度运行RS232的程序进行下载)。最后,应该说的是,调试ROM映像后,有必要先将其擦除,然后再将其写入该ROM中。使用紫外线晒黑灯通过微电路外壳中的特殊窗口进行擦除,然后用特殊的黑色粘性纸覆盖该窗口,该粘性纸用于密封5英寸软盘侧面的孔以防止其写入。另外,由于我没有程序员,所以每次不得不去朋友那里去莫斯科另一端时,都需要用ROM编写新版本的ROM,谁有这个程序员。在这里有必要澄清这个问题,如何在不将ROM映像加载到该ROM中的情况下对其进行调试?为此,我的所有软件都使用了一个基址,将地址移了32 KB。也就是说,将一个新的ROM映像加载到RAM中并在其中进行调试,然后在调试之后,将基地址设置为零,再次编译所有内容,然后我去找一个朋友在ROM中编写新版本。一切都重新编译了,我去找一个朋友用ROM编写新版本。一切都重新编译了,我去找一个朋友用ROM编写新版本。

当调试“编码”-“调试”-“固件”的过程时,出现了编写操作系统的问题。操作系统必须支持键盘输入,在LCD屏幕上显示信息,支持输出不同的声音,并在可能的情况下并行执行所有这些操作,即多任务处理。为此,选择了以下体系结构-在OS中,存在三种类型的任务:几项具有最高优先级的实时任务,一项与人本身交互的用户任务以及在处理器空闲时工作的后台任务。我将中断的优先级最高挂起,该中断由KR580VI53计时器每秒生成10次。应该说,在“呼叫者ID”中,每秒产生400次中断,因为有必要非常频繁地更新指示器,以便这样一个人就不会注意到闪烁。除了在中断中更新指示器外,还对键盘进行了轮询以寻找所按的键。 AON如此频繁的中断导致这样一个事实,即处理器的大部分时间实际上都花在了中断上,我希望我的计算机做一些其他有用的事情。由于我安装了LCD屏幕作为信息显示设备,它具有自己的内存并且不需要动态更新,因此不再需要这种中断频率。实验确定,每秒10次中断足以轮询键盘。大部分的处理器时间实际上都花在了中断上,我希望我的电脑做一些其他有用的事情。由于我安装了LCD屏幕作为信息显示设备,它具有自己的内存并且不需要动态更新,因此不再需要这种中断频率。实验确定,每秒10次中断足以轮询键盘。大部分的处理器时间实际上都花在了中断上,我希望我的电脑做一些其他有用的事情。由于我安装了LCD屏幕作为信息显示设备,它具有自己的内存并且不需要动态更新,因此不再需要这种中断频率。实验确定,每秒10次中断足以轮询键盘。

因此,实时任务在每个中断处启动,并将新信息放入特殊事件队列中。事件有几种类型,并且包含与事件类型相对应的信息,例如,“按下按钮”事件包含扫描代码。实际上,在每个中断处开始的优先任务之一是轮询键盘并以编程方式消除触点反弹的任务。除此任务外,还有优先级任务-用户任务可以设置的计时器,并且在指定时间后将相应的事件排队,有在特定时间,时钟和日历工作的警报,还有一个任务是使用对KR580VI53进行编程,并以注释形式输入数据。通过这种方式,用户的任务可以简单地开始播放音乐并执行其他操作。

我的计算机上的有用工作是由事件驱动的用户任务完成的。这种任务的典型视图如下:

while(true) {
  Event e;

  GetEvent(e);

  /* process event */
}


在这里,GetEvent(e)函数等待事件出现在队列中,并在事件出现时填充Event结构。显然,根据某个事件,程序可能会退出无限循环,并将控制权转移回系统监视器,从而启动用户任务。由于通常快速处理用户任务中的事件,因此程序等待新事件出现在GetEvent(e)过程中。为了以某种方式利用这种期望,引入了可以运行用户程序并且独立运行的后台任务。也就是说,当发生计时器中断时,首先通过将事件放置在队列中来完成实时任务,然后在中断完成后,用户任务处理了队列中的所有事件,以及将下一次中断分配给后台任务的剩余时间。今天,这样的计划看起来很自然,但是在1993年却非常进步。

另一个问题与LCD屏幕无法显示俄语字母这一事实有关。这是由于这样的事实,即这些指标刚刚出现在我们的市场上,并且还没有人专门对其进行过粗化处理。自然,没有使用它们的库,但是只有命令的规范和描述。因此,所有初始化和使用它的工作都必须从头开始。我通过以下方式解决了Russification的问题:编写了一个特殊过程,该过程的输入是需要显示的带有俄语文本的字符串。此过程用相应的拉丁字母替换了所有与拉丁字母相似的俄语字母,并使用可下载到LCD屏幕的自定义图像即时创建了无法替换的字母。应该注意里面有八个这样的用户图像,因此,在俄语文本中,最多只能有八个字母,而类似物不在拉丁字母中。但是通常就足够了。我使用的另一个有趣的机会是,如果您更改一个角色的用户图像,则会得到一个有趣的动画。我在这个工兵游戏中利用了这个机会,我将在下面讨论该工兵游戏,地雷上方的旗帜随风飘扬,炸弹爆炸。我在这个工兵游戏中利用了这个机会,我将在下面讨论该工兵游戏,地雷上方的旗帜随风飘扬,炸弹爆炸。我在这个工兵游戏中利用了这个机会,我将在下面讨论该工兵游戏,地雷上方的旗帜随风飘扬,炸弹爆炸。

现在,我将告诉您有关我为计算机创建的那些用户任务的信息。当我开始创建它们时,我很快就意识到,就像当时每个人对sinclair这样的系统所做的那样,用汇编器编写它们是非常可悲的。由于我是在IBM PC上编写C语言的,所以我考虑了是否可以在C语言和计算机上进行编程。经过一番搜索之后,我找到了C-TR-DOS的经典K&R版本的编译器。该编译器相当原始,例如,它不检查传递给该过程的参数数量是否与它们的实际数量相对应,更不用说检查其类型了。但是,如果我可以在计算机上使用此编译器,那将是一个巨大的进步。问题是如何使该编译器收到的代码适合我的计算机。在这里,我走了我们已经忘记的经典方式,到了1993年,他们仍然记得。这种方式不是将源代码直接编译到目标文件中,而是编译成汇编程序源代码。因此,仅需编写宏,该宏将允许通过正确的参数传输来调用从代码编译的汇编程序,反之亦然。使用此编译器,除了使用代码的便利性之外,还提供了另一个巨大的优势-可以使用整数乘法/除法(我记得z80没有整数乘法和除法命令),以及(lo和betain!)使用数字的能力。浮点。但是,为此,我不得不处理编译器附带的库,因为编译后的所有数学运算都作为对该库的调用而执行。问题在于该库使用的临时变量是编译器放置在特定于TR-DOS的内存模型中的,当然,这些变量完全不与我的计算机的内存模型相对应。我必须查找所有此类临时变量,然后将它们重做以找到适合我的RAM的地址。但是,作为奖励,我得到了很多标准函数,如正弦和余弦,这些函数已在我的任务中使用,下面将对其进行讨论。我必须查找所有此类临时变量,然后将它们重做以找到适合我的RAM的地址。但是,作为奖励,我得到了很多标准函数,如正弦和余弦,这些函数已在我的任务中使用,下面将对其进行讨论。我必须查找所有此类临时变量,然后将它们重做以找到适合我的RAM的地址。但是,作为奖励,我得到了很多标准函数,如正弦和余弦,这些函数已在我的任务中使用,下面将对其进行讨论。

使用C编译器创建的第一个程序是用于检查RAM是否正确运行的程序。该程序遍历整个RAM,进行写入,然后读取各种模式并比较结果。此外,整个过程都显示在LCD屏幕上,这也证实了与其相关的程序的正确操作。显然,这只是在编写更有趣的程序之前对笔的测试。我要做的下一件事是创建一个十六进制编辑器来修改RAM的内容。该编辑器已经具有相当广泛的可能性,不仅包括查看和编辑存储单元,还包括在RAM中搜索有趣的字节。特别是,可以用机器代码直接在RAM中编写小型程序。要测试计算机的声音功能,我创建了一个程序,例如“音乐盒”,它播放各种旋律(我记得旋律被记录为音符)。此外,编写了一个“牛与牛”游戏的程序,其中要求一个人猜测由计算机构想的随机四位数数字(是的,我还制作了一个随机数生成器)。在此程序中,我不得不创建一个滚动列表,其中包含已输入数字的历史记录,因为不可能在两行上显示特别长的列表。下一个创建的程序是16x16领域的经典“ sapper”。由于我只有两条线可以使用,因此我进行了滚动,添加了音乐伴奏和一面旗帜随风飘扬,炸弹爆炸的动画。此外,为了冥想,我编写了一个程序,显示蠕虫在随机方向上爬行,使用将自定义图像上传到屏幕的功能。好吧,在没有经典井字游戏的地方呢?在他们中,我测试了minimax算法,也就是说,计算机(相当快地)计算了所有选项,并且永不丢失。由于我的操作系统支持警报,时间和日历,因此我制作了一个用户程序来设置时间,日期和一些警报,这些警报在达到设置的时间后会弹奏不同的旋律。最后,在我的计算机中,创造的最高点是一个程序,用于计算两个引力体问题中的运动轨迹。也就是说,对于给定的身体初始位置和速度以及吸引中心的质量,解决了具有给定积分步骤的两个二阶非线性常微分方程组的数值积分问题。为此,我添加了一个对这些方程进行数值积分的过程。所有变量均为双浮点格式。在这里,我再次强调,在z80处理器中,不仅支持处理浮点的硬件,而且还支持通常的整数乘法/除法,所有操作均以编程方式完成。该集成工作非常缓慢,大约每秒执行一个步骤,但是它起作用了!而且还有通常的整数乘法/除法,所有事情都是以编程方式完成的。该集成工作非常缓慢,大约每秒执行一个步骤,但是它起作用了!而且还有通常的整数乘法/除法,所有事情都是以编程方式完成的。该集成工作非常缓慢,大约每秒执行一个步骤,但是它起作用了!

我仍然想实现,但是没有成功-首先,动态分配/释放内存,以便我可以灵活地管理每个任务的资源。此外,没有像Sinclair一样在磁带上进行记录/读取。但是总的来说,我对自己的工作感到满意。我强调以上所有内容都在一个32 KB的ROM中-当前的大小不是那么大。

您可以在这里查看我使用的计算机:




在这里下载他的软件

All Articles