Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove interrupt_occurred/reset_interrupt_flag from Input/Output #182

Open
8 tasks
rrbutani opened this issue Jul 28, 2022 · 0 comments
Open
8 tasks

Remove interrupt_occurred/reset_interrupt_flag from Input/Output #182

rrbutani opened this issue Jul 28, 2022 · 0 comments
Assignees
Labels
🐛 bug Something isn't working.. ➕ improvement Chores and fixes: the small things. P-low Low priority T-peripheral traits Topic: Peripheral Traits

Comments

@rrbutani
Copy link
Member

what

As per the book, interrupts for the keyboard and display peripherals occur when the ready bit (i.e. current_data_unread) is high and when interrupts are enabled (interrupt_enabled).

We don't have an additional state for "interrupts are not enabled but an interrupt has occurred and is pending", i.e.: disabling interrupts clears any pending interrupts.

Similarly, reset_interrupt_flag is redundant: read_data clears the ready bit and that's all we need.

What we want instead is to have read_data be separate from clear_data on the Input trait (and to have some accesses – like tui and control memory accesses to the data - not call clear_data).

misc

As a separate thing, as per the book, the keyboard simply does not accept new input when the ready bit is already high (§9.2.2.2):

When the LC-3 reads KBDR, the electronic circuits associated with the keyboard automatically clear KBSR[15], allowing another key to be struck. If KBSR[15] = 1, the ASCII code corresponding to the last key struck has not yet been read, and so the keyboard is disabled; that is, no key can be struck until the last key is read.

This results in new key presses being discarded and the first unread key press being retained. This is in contrast to how our InputShim works today (it retains the last entered key press).

We should:

  • document this behavior on the Input trait
  • update our InputShim impl to match
  • add a test for this on the InputShim
  • I believe the output analogue to this is that data that is written when the display is not ready is discarded (or does it overwrite the current char on the screen?); we should double check

steps

  • remove interrupt_occurred and reset_interrupt_flag from the I/O traits
  • update the docs on the I/O traits
  • update the interpreter to match
  • this program tests that interrupts fire repeatedly when KBDR is not actually read, we should turn it into a test:
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; init code
    .orig x800
    ; Put our ISR in the interrupt vector table:
        ; compute the address corresponding to the keyboard
        ; interrupt's vector table entry, store into r0:
        LD  r0, INT_VEC_TABLE_BASE
        LD  r1, KBD_INTERRUPT_VEC_NUM
        ADD r0, r0, r1
        ; get the address of our keyboard isr:
        LD  r1, KBD_ISR_ADDR
        ; store:
        STR r1, r0, #0
    ; Enable interrupts (bit 14 of KBSR):
        LD  r0, KBSR
        LDR r1, r0, #0
        ; mask out bit 14:
        LD  r2, BIT_14_MASK
        AND r1, r1, r2
        ; set bit 14
        NOT r2, r2
        ADD r1, r1, r2
        ; store:
        STR r1, r0, #0
    ; Jump to user code:
        LD  r0, STARTING_PSR
        ADD r6, r6, #-1
        STR r0, r6, #0
        LD  r0, STARTING_PC
        ADD r6, r6, #-1
        STR r0, r6, #0
        RTI
    INT_VEC_TABLE_BASE
        .FILL x0180
    KBD_INTERRUPT_VEC_NUM
        .FILL x0
    KBSR
        .FILL xFE00
    KBDR
        .FILL xFE02
    BIT_14_MASK
        .FILL xBFFF
    STARTING_PC
        .FILL USER_PROG
    KBD_ISR_ADDR
        .FILL KBD_ISR
    STARTING_PSR
        .FILL x8002
    .end
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; user program
    .orig x3000
    USER_PROG
        LEA r0, MSG_START
        PUTS
    ; Spin, endlessly:
    LOOP
        BRnzp LOOP
    MSG_START
        .STRINGZ "hello!\n"
    .end
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; ISR
    .orig x4000
    KBD_ISR
        LEA r0, MSG
        PUTS
        RTI
    MSG
        .STRINGZ "in the keyboard ISR!\n"
    .end

where

branch: imp/io-trait-reform

fn interrupt_occurred(&self) -> bool;

fn interrupt_occurred(&self) -> bool;

open questions

@rrbutani rrbutani added 🐛 bug Something isn't working.. ➕ improvement Chores and fixes: the small things. P-low Low priority T-peripheral traits Topic: Peripheral Traits labels Jul 28, 2022
@rrbutani rrbutani self-assigned this Jul 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Something isn't working.. ➕ improvement Chores and fixes: the small things. P-low Low priority T-peripheral traits Topic: Peripheral Traits
Projects
None yet
Development

No branches or pull requests

1 participant