Skip to content

Commit b861a3d

Browse files
committed
[assembler] Add test for default-assigned index registers.
Thre's a little ambiguity over previsely what section 6-2.2 of the User Handbook intends for the case where index register values are hard-coded elsewhere in the source, but the test (like our pre-existing code) takes what I believe to be the most likely interpretation. The ambiguity is also called out in OPEN-QUESTIONS.md. This fixes #109.
1 parent a44d83a commit b861a3d

File tree

2 files changed

+78
-12
lines changed

2 files changed

+78
-12
lines changed

OPEN-QUESTIONS.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,14 @@
7171
2. Is there a difference between the configuration values 34 and -3?
7272
Both seem to occur in symbolic code (e.g. the examples memo by
7373
H. Philip Peterson, 6M-5780, July 23, 1958).
74-
3. The user handbook (ch. 6) appears to state that it is possible to
75-
assemble an instruction into both the left and right halves of a
76-
word. Is the operand address portion of both instructions
77-
discarded? If not, how is it handled?
78-
4. In the pipe construct "Z ₚ|ₜ Q" described in the User Handbook
74+
3. In the pipe construct "Z ₚ|ₜ Q" described in the User Handbook
7975
section 2-2.8 "SPECIAL SYMBOLS", are spaces allowed in the "ₚ" or
8076
"ₜ"?
77+
4. Symexes used only for index register values (User Handbook section
78+
6-2.2) are assigned as "The lowest numerical index register value
79+
not already used". What does "used" mean? We currently assume it
80+
means "not already default-assigned", meaning that the assembler
81+
does not need to track which index registers are used via explicit
82+
equalities or numeric literals. (Otherwise, use of index register
83+
0o52 would mean that the first value to be default-assigned would
84+
be 0o53, which isn't very helpful).

assembler/src/asmlib/driver/tests.rs

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use super::{assemble_pass1, Binary, BinaryChunk};
1818
use base::{
1919
charset::Script,
2020
prelude::{
21-
u18, u36, Address, Instruction, Opcode, OperandAddress, SymbolicInstruction, Unsigned18Bit,
22-
Unsigned36Bit, Unsigned5Bit, Unsigned6Bit,
21+
u18, u36, u6, Address, Instruction, Opcode, OperandAddress, SymbolicInstruction,
22+
Unsigned18Bit, Unsigned36Bit, Unsigned5Bit, Unsigned6Bit,
2323
},
2424
};
2525

@@ -652,11 +652,8 @@ fn default_assigned_rc_word() {
652652
// The numerical memory location of the next place in the RC words
653653
// block. The contents of this RC word are set to zero. This
654654
// provision is useful in assigning temporary storage.
655-
let program = assemble_source(
656-
concat!("100| STA TEMP1\n", " STB TEMP2\n"),
657-
Default::default(),
658-
)
659-
.expect("program is valid");
655+
let program = assemble_source("100| STA TEMP1\n STB TEMP2\n", Default::default())
656+
.expect("program is valid");
660657
assert_eq!(
661658
program,
662659
Binary {
@@ -694,3 +691,68 @@ fn default_assigned_rc_word() {
694691
}
695692
);
696693
}
694+
695+
#[test]
696+
fn default_assigned_index_register_easy_case() {
697+
// See section 6-2.2 of the User Handbook for a description of how
698+
// this is supposed to work.
699+
//
700+
// It states that for symexes used only in an index register
701+
// context, the default assignment is, "The lowest numerical index
702+
// register value not already used. Except zero and no higher
703+
// than 77."
704+
//
705+
// It's not clear what "not already used" really means. For
706+
// example, in this program:
707+
//
708+
// STAⱼ 0
709+
// STAₖ 0
710+
//
711+
// It seems clear that j and k would be default-addiend to 1 and 2
712+
// respectively. But suppose instead that the program looked like
713+
// this:
714+
//
715+
// STA₁ 0 ** USES INDEX REGISTER 1
716+
// STAⱼ 0 ** SHOULD j BE DEFAULT ASSIGNED as 1 or 2?
717+
//
718+
// Here, index register 1 is used by the first instruction. Does
719+
// index register 1 count as used?
720+
//
721+
// This test uses the first program above. IOW it doesn't assume
722+
// any particular answer to the second question.
723+
//
724+
// But, if the intent was that we would avoid assigning j=1 in the
725+
// case above, a somewhat legalistic interpretation would be that
726+
// any use of hardware-specific sequence 65 (LW input) would cause
727+
// the assembler to default-assign 66 (which is also a hardware
728+
// device, LW output). That doesn't seem very useful.
729+
let program =
730+
assemble_source("100|STAⱼ 0\nSTAₖ 0\n", Default::default()).expect("program is valid");
731+
assert_eq!(
732+
program,
733+
Binary {
734+
entry_point: None,
735+
chunks: vec![BinaryChunk {
736+
address: Address::from(u18!(0o100)),
737+
words: vec![
738+
Instruction::from(&SymbolicInstruction {
739+
held: false,
740+
configuration: Unsigned5Bit::ZERO,
741+
opcode: Opcode::Sta,
742+
index: u6!(1), // j
743+
operand_address: OperandAddress::Direct(Address::from(Unsigned18Bit::ZERO)),
744+
})
745+
.bits(),
746+
Instruction::from(&SymbolicInstruction {
747+
held: false,
748+
configuration: Unsigned5Bit::ZERO,
749+
opcode: Opcode::Sta,
750+
index: u6!(2), // k
751+
operand_address: OperandAddress::Direct(Address::from(Unsigned18Bit::ZERO)),
752+
})
753+
.bits()
754+
]
755+
}]
756+
}
757+
);
758+
}

0 commit comments

Comments
 (0)