You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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_NUMADD 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_MASKAND r1, r1, r2 ; set bit 14NOT r2, r2ADD r1, r1, r2 ; store:STR r1, r0, #0; Jump to user code: LD r0, STARTING_PSRADD r6, r6, #-1STR r0, r6, #0 LD r0, STARTING_PCADD r6, r6, #-1STR r0, r6, #0 RTIINT_VEC_TABLE_BASE .FILL x0180KBD_INTERRUPT_VEC_NUM .FILL x0KBSR .FILL xFE00KBDR .FILL xFE02BIT_14_MASK .FILL xBFFFSTARTING_PC .FILL USER_PROGKBD_ISR_ADDR .FILL KBD_ISRSTARTING_PSR .FILL x8002.end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; user program.orig x3000USER_PROGLEA r0, MSG_START PUTS; Spin, endlessly:LOOP BRnzp LOOPMSG_START .STRINGZ "hello!\n".end;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ISR.orig x4000KBD_ISRLEA r0, MSG PUTS RTIMSG .STRINGZ "in the keyboard ISR!\n".end
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_flagis redundant:read_dataclears the ready bit and that's all we need.What we want instead is to have
read_databe separate fromclear_dataon theInputtrait (and to have some accesses – like tui and control memory accesses to the data - not callclear_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):
This results in new key presses being discarded and the first unread key press being retained. This is in contrast to how our
InputShimworks today (it retains the last entered key press).We should:
InputtraitInputShimimpl to matchInputShimsteps
interrupt_occurredandreset_interrupt_flagfrom the I/O traitswhere
branch:
imp/io-trait-reformcore/traits/src/peripherals/input.rs
Line 24 in 5e0f0eb
core/traits/src/peripherals/output.rs
Line 19 in 5e0f0eb
open questions