轮询I / O(MIPS) [英] Polling I/O (MIPS)

查看:322
本文介绍了轮询I / O(MIPS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在MIPS中编写一个程序,该程序使用轮询从键盘读取字符,然后使用内置的键盘和显示MMIO模拟器显示它。不幸的是,我无法理解所使用的寄存器和控制位背后的概念,但一直试图从在线示例中找出它。

I am attempting to write a program in MIPS that uses polling to read a character from the keyboard and then displays it using the builtin Keyboard and Display MMIO Simulator. Unfortunately, I am having trouble grasping the concept behind the registers used and the control bits, but have been trying to figure it out from examples online.

这就是我所拥有的到目前为止写的:

Here is what I have written so far:

            .data

            .text
            .globl main

main:
            .eqv    RCR 0xffff0000      # Receiver Control Register     (Ready Bit)
            .eqv    RDR 0xffff0004      # Receiver Data Register        (Key Pressed - ASCII)
            .eqv    TCR 0xffff0008      # Transmitter Control Register  (Ready Bit)
            .eqv    TDR 0xffff000c      # Transmitter Data Register     (Key Displayed- ASCII)

keyWait:    lw      $t0, RCR
            andi    $t0, $t0, 1
            beq     $t0, $zero, keyWait

            lb      $a0, RDR

我认为这里发生的是 keyWait 继续循环,直到就绪位设置为1(*),然后该键的ASCII值存储在 $ a0 中。这是正确的吗?

What I believe is happening here is that keyWait continues to loop until the ready bit is set to 1 (*), and then the ASCII value of the key is stored in $a0. Is this correct?

如果这是正确的,那么如何使用与TCR和TDR相同的轮询技术在显示器上打印字符?

If this is correct, how can I then print the character on the display using the same polling technique with the TCR and TDR?

*我不明白为什么需要使用 andi 操作来检查 - 如果 $ t0 是1(或0),它是 ed with 1,等于1(或0),然后存储在 $ T0 ?那么 $ t0 的价值是否保持与此操作之前相同?

*I don't understand why this is needed to be checked with the andi operation - if $t0 is 1 (or 0), it is anded with 1, which equals 1 (or 0), which is then stored in $t0? So the value of $t0 stays as it was prior to this operation regardless?

EDIT

这是我尝试将按键数据传递给显示器。

Here is my attempt at passing the key pressed data to the display.

                .data

                .text
                .globl main

main:
                .eqv    RCR 0xffff0000      # Receiver Control Register     (Ready Bit)
                .eqv    RDR 0xffff0004      # Receiver Data Register    (Key Pressed - ASCII)
                .eqv    TCR 0xffff0008      # Transmitter Control Register  (Ready Bit)
                .eqv    TDR 0xffff000c      # Transmitter Data Register (Key Displayed- ASCII)

keyWait:        lw      $t0, RCR
                andi    $t0, $t0, 1
                beq     $t0, $zero, keyWait

                lbu     $a0, RDR

displayWait:    lw      $t1, TCR
                andi    $t1, $t1, 1
                beq     $t1, $zero, displayWait

                sb      $a1, TDR

                li      $v0, 11
                syscall 

                j       keyWait

这只是一个测试程序,它应该在MMIO显示模拟器上打印字符,也可以在控制台中打印MIPS。它正在做后者,但不在显示模拟器上。在显示模拟器中, Cursor:每次按下一个键时都会递增,但没有打印任何内容。我缺少什么?

This is just a test program which should print the character on the MMIO Display Simulator, and also in the console within MIPS. It is doing the latter, but not on the display simulator. In the display simulator, Cursor: is incrementing each time a key is pressed, but nothing is being printed. What am I missing?

推荐答案

您可能没有点击连接到MIPS。

You probably didn't click "Connect to MIPS".

请参阅此答案:如何打印从MIPS程序集到屏幕

当我测试时,我发现如果你停止模拟,重新加载程序,你可能需要点击断开MIPS然后再连接到MIPS(即稍微切换一下)

When I was testing I've found that if you stop simulation, reload your program, you probably have to click on "Disconnect from MIPS" and then "Connect to MIPS" again (i.e. toggle it a bit)

此外, bug :来自<的数据code> RDR 在 $ a0 中,但您存入 TDR 来自 $ a1

Also, a bug: The data from RDR is in $a0, but you are storing into TDR from $a1

从链接中注意样式略有不同你的。在链接中,它们使用基址寄存器的偏移量而不是硬连线地址。对于[在现实世界中的设备驱动程序]中的设备来说,这更常见,特别是如果可以配置/更改设备的基地址。

From the link, notice that the style is slightly different than yours. In the link, they use offsets from a base register rather than hardwiring the addresses. This is much more usual for devices [in device drivers in the real world], particularly if the base address of the device could be configured/changed.

此外,在 mars ,如果你看看硬连线与基本寄存器版本中伪操作产生的实际低电平指令,基址寄存器版本更紧凑(即注入的数量更少 lui insts)

Also, in mars, if you look at the actual low level instructions generated from the pseudo-ops in the hardwired vs. base register versions, the base register version is more compact (i.e. fewer injected lui insts)

所以,我重新设计了你的代码以使用基址寄存器:

So, I've restyled your code to use a base register:

    .data

    .eqv    MMIOBASE    0xffff0000

    # Receiver Control Register (Ready Bit)
    .eqv    RCR_        0x0000
    .eqv    RCR         RCR_($s0)

    # Receiver Data Register (Key Pressed - ASCII)
    .eqv    RDR_        0x0004
    .eqv    RDR         RDR_($s0)

    # Transmitter Control Register (Ready Bit)
    .eqv    TCR_        0x0008
    .eqv    TCR         TCR_($s0)

    # Transmitter Data Register (Key Displayed- ASCII)
    .eqv    TDR_        0x000c
    .eqv    TDR         TDR_($s0)

    .text
    .globl  main
main:
    li      $s0,MMIOBASE            # get base address of MMIO area

keyWait:
    lw      $t0,RCR                 # get control reg
    andi    $t0,$t0,1               # isolate ready bit
    beq     $t0,$zero,keyWait       # is key available? if no, loop

    lbu     $a0,RDR                 # get key value

displayWait:
    lw      $t1,TCR                 # get control reg
    andi    $t1,$t1,1               # isolate ready bit
    beq     $t1,$zero,displayWait   # is display ready? if no, loop

    sb      $a0,TDR                 # send key to display

    li      $v0,11
    syscall

    j       keyWait

我用 .eqv 以上。在一般情况下,即使它更冗长,也可能更清楚:

I did a little "fancy footwork" with the .eqv above. In the general case, even though it's a bit more verbose, it may be clearer to do:

    .eqv    RCR         0x0000

    lw      $t0,RCR($s0)            # get control reg

这篇关于轮询I / O(MIPS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆