Assembly Z80组件(1MHz)CP/M:如何使用按钮获得正确的物理输入
我是学计算机科学的大一新生。在计算机工程中,我们正在研究Zilog Z80 8位微处理器(1MHz)和一组需要使用试验板和电缆手动连接的组件 连接部分并不让我担心,但我确实有一些关于组装程序的问题,我需要编写这些程序来让我的程序工作(LED指示灯亮起,手动输入行为和频率) 我已经阅读了手册,知道可以使用的一套说明(仅限于基本必需品)。首先,我并不是想得到尽可能干净、好看的代码;但不用担心,我以后会美化它,因为我喜欢干净高效的代码 目前,该程序似乎在模拟器中运行良好,因此语法似乎没有问题。不过,我不知道如何处理某些逻辑问题 该练习具有以下规格:Assembly Z80组件(1MHz)CP/M:如何使用按钮获得正确的物理输入,assembly,z80,cpm,Assembly,Z80,Cpm,我是学计算机科学的大一新生。在计算机工程中,我们正在研究Zilog Z80 8位微处理器(1MHz)和一组需要使用试验板和电缆手动连接的组件 连接部分并不让我担心,但我确实有一些关于组装程序的问题,我需要编写这些程序来让我的程序工作(LED指示灯亮起,手动输入行为和频率) 我已经阅读了手册,知道可以使用的一套说明(仅限于基本必需品)。首先,我并不是想得到尽可能干净、好看的代码;但不用担心,我以后会美化它,因为我喜欢干净高效的代码 目前,该程序似乎在模拟器中运行良好,因此语法似乎没有问题。不过,我
ORG E000h
设置了起始地址,并使用MOV SP,FFFFh
初始化了堆栈指针。对于输入(三种不同类型的闪烁/运行,以及两种不同的频率,总共等于五个按钮),我创建了不同的标签
目前我的问题是,我不太确定如何正确地获取物理输入-IIRC,我需要使用XOR指定一个位模式,除了所需的输入之外,所有内容都是1,这样我就可以使用程序中的信息
但是,即使我知道它的工作方式(至少我认为我知道),我也不能完全围绕软件实现来思考。此外,我的条件也有问题:按下一个开关会将闪烁频率更改为1/4 Hz,而按下另一个开关会将其更改为4 Hz。在更高级的语言中,我只会在这里使用IF/ELSE,但我不知道在这种情况下如何操作——遗憾的是,手册中只包含基本操作,所以我不知所措
因此,我想我应该试试运气,向社区寻求帮助
对于那些感兴趣的人,我将发布我的代码。这是非常基本的,正如我已经提到的,但我只是需要它来完成目前的工作。因为我不喜欢大量格式笨拙的代码,所以我发布了这个文件。该文件是通过GoogleDrive托管的*.txt文件
谢谢你抽出时间,祝你度过愉快的一天
[编辑]根据用户Ruud Helderman的输入,在帖子中添加了特定代码
[编辑]更新了*.txt文件中的代码-现在更简单、更高效
[EDIT]使用HTML格式在post中突出显示指令
特定代码段:
blink: ;function: all LED blinking, activated via input[2]
MOV A,FFh
OUT 05h,A ;all LED out
CALL pause1 ;frequency 1/4Hz, activated via input[5]
MOV A,00h
OUT 05h,A ;all LED on
CALL pause1
JP blink ;jump back to begin of function
上述功能改变LED行为(在这种情况下:闪烁)和频率,在输入开关板上使用不同的特定物理开关,共有八个开关(1到8,停用状态=1;使用开关2到6)。我知道获取输入应该是小菜一碟——只需使用位模式为0且正好为1的XOR即可
在试图找到问题的解决方案时,我在网上找到了不同的方法,比如使用TEST
检查特定位置上的位。尽管如此,我的指导手册没有提到任何这样的指令,作业本身也没有提到
我很清楚,这可能是一个微不足道的问题,也许我只是陷入了一个思维过度造成的思维循环中,但目前我不知道如何达到我所需要的状态(即使我能看到地平线上的城堡——感谢卡夫卡!)
非常感谢您的帮助。第一件事:如果您使用的是
MOV
,那么您可能使用的是8080语法而不是Z80语法。出于历史法律原因,Z80不仅扩展了8080的汇编语言,它还重命名了所有现有的助记符(MOV
到LD
)。如果你正在搜索Z80代码,却发现了你无法识别的指令,这很可能是其中的一部分
实现if/else类型条件的常用方法是:
ANI
(z80:和
)。它计算累加器和操作数的逻辑and,将其存储在累加器中,但除其他外,它还设置零标志。因此,您可以使用JNZ
(/JP-NZ
)和JZ
(/JP-Z
)根据是否设置了位来执行某些操作。例如
; upon entry, A has an unknown value, loaded from somewhere.
ANI 08h ; Set a = a & 8; so either bit 2 was originally set and a now
; has the value 8, or bit 2 wasn't set and a now has the value 0.
; Also: the zero flag is now set if a is zero, reset otherwise.
; So you've loaded NOT (a.bit2) into the zero flag.
; You've also lost the rest of the accumulator, but such is life.
; Keep a copy somewhere, or grab it again via IN as required.
JZ bitnotset
; code here will be performed only if bit 2 was originally unset.
bitnotset:
; this code will happen regardless of whether bit 2 was set.
我不知道8080或Z80风格的语法中有测试
您还可能会看到一种破坏性较小、效率稍高的解决方案,通过将字节中的多个位转换为进位,来按顺序测试多个字节。这是另一种选择,但不一定值得担心,除非你的课程笔记强烈暗示这是你应该关注的方向。首先:如果你使用的是MOV
,那么你可能使用的是8080语法而不是Z80语法。出于历史法律原因,Z80不仅扩展了8080的汇编语言,它还重命名了所有现有的助记符(MOV
到LD
)。如果你正在搜索Z80代码,却发现了你无法识别的指令,这很可能是其中的一部分
实现if/else类型条件的常用方法是:
性能
programloop:
MOV A,40h ;state of button 2, inverted (XOR FFh)
MOV B,A ;save state to register B
IN A,03h ;input at port-address 03h
AND B ;find out if button is pressed
JPNZ blink ;if yes, jump to blink
MOV A,20h ;state of button 3, inverted (XOR FFh)
MOV B,A ;save state to register B
IN A,03h ;input at port-address 03h
AND B ;find out if button is pressed
JPNZ goright ;if yes, jump to goright
MOV A,10h ;state of button 4, inverted (XOR FFh)
MOV B,A ;save state to register B
IN A,03h ;input at port-address 03h
AND B ;find out if button is pressed
JPNZ goleft ;if yes, jump to goleft
JP programloop ;go back to beginning (input has to be checked constantly)
MOV A,03h ;state of button five being pressed (inverted)
MOV B,A ;saved state into register B for later use
IN A,03h ;physical input over button
AND B ;find out if button is pressed
JPNZ freq025Hz ;if yes, jump to freq025Hz
JPZ freq4Hz ;if no, jump to freq4Hz