Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly Z80组件(1MHz)CP/M:如何使用按钮获得正确的物理输入_Assembly_Z80_Cpm - Fatal编程技术网

Assembly Z80组件(1MHz)CP/M:如何使用按钮获得正确的物理输入

Assembly Z80组件(1MHz)CP/M:如何使用按钮获得正确的物理输入,assembly,z80,cpm,Assembly,Z80,Cpm,我是学计算机科学的大一新生。在计算机工程中,我们正在研究Zilog Z80 8位微处理器(1MHz)和一组需要使用试验板和电缆手动连接的组件 连接部分并不让我担心,但我确实有一些关于组装程序的问题,我需要编写这些程序来让我的程序工作(LED指示灯亮起,手动输入行为和频率) 我已经阅读了手册,知道可以使用的一套说明(仅限于基本必需品)。首先,我并不是想得到尽可能干净、好看的代码;但不用担心,我以后会美化它,因为我喜欢干净高效的代码 目前,该程序似乎在模拟器中运行良好,因此语法似乎没有问题。不过,我

我是学计算机科学的大一新生。在计算机工程中,我们正在研究Zilog Z80 8位微处理器(1MHz)和一组需要使用试验板和电缆手动连接的组件

连接部分并不让我担心,但我确实有一些关于组装程序的问题,我需要编写这些程序来让我的程序工作(LED指示灯亮起,手动输入行为和频率)

我已经阅读了手册,知道可以使用的一套说明(仅限于基本必需品)。首先,我并不是想得到尽可能干净、好看的代码;但不用担心,我以后会美化它,因为我喜欢干净高效的代码

目前,该程序似乎在模拟器中运行良好,因此语法似乎没有问题。不过,我不知道如何处理某些逻辑问题

该练习具有以下规格:

  • 起始地址RAM:E000h
  • 输入端口1:03h
  • 输出端口1:05h
  • 端口的I/O映射
  • 电路自动断开(1),因此LED处于低激活状态(0)
  • 输入2,3,4改变LED运动行为
  • 输入5,6改变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