[07] Almost done with BasicTest implementation
This commit is contained in:
parent
3fa5a5c07a
commit
9782ba7e4d
|
@ -0,0 +1,224 @@
|
||||||
|
@10 // push constant 10
|
||||||
|
D=A
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push constant 10
|
||||||
|
@SP // pop
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
@LCL
|
||||||
|
A=M // Read @LCL to A
|
||||||
|
M=D // Write D to *A
|
||||||
|
@21 // push constant 21
|
||||||
|
D=A
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push constant 21
|
||||||
|
@22 // push constant 22
|
||||||
|
D=A
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push constant 22
|
||||||
|
@ARG // argument 2
|
||||||
|
D=M
|
||||||
|
@2 // write 2 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @ARG+2 to R13
|
||||||
|
@SP // pop
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
@R13
|
||||||
|
A=M // Read @R13 to A
|
||||||
|
M=D // Write D to *A
|
||||||
|
@ARG // argument 1
|
||||||
|
D=M
|
||||||
|
@1 // write 1 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @ARG+1 to R13
|
||||||
|
@SP // pop
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
@R13
|
||||||
|
A=M // Read @R13 to A
|
||||||
|
M=D // Write D to *A
|
||||||
|
@36 // push constant 36
|
||||||
|
D=A
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push constant 36
|
||||||
|
@THIS // this 6
|
||||||
|
D=M
|
||||||
|
@6 // write 6 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @THIS+6 to R13
|
||||||
|
@SP // pop
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
@R13
|
||||||
|
A=M // Read @R13 to A
|
||||||
|
M=D // Write D to *A
|
||||||
|
@42 // push constant 42
|
||||||
|
D=A
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push constant 42
|
||||||
|
@45 // push constant 45
|
||||||
|
D=A
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push constant 45
|
||||||
|
@THAT // that 5
|
||||||
|
D=M
|
||||||
|
@5 // write 5 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @THAT+5 to R13
|
||||||
|
@SP // pop
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
@R13
|
||||||
|
A=M // Read @R13 to A
|
||||||
|
M=D // Write D to *A
|
||||||
|
@THAT // that 2
|
||||||
|
D=M
|
||||||
|
@2 // write 2 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @THAT+2 to R13
|
||||||
|
@SP // pop
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
@R13
|
||||||
|
A=M // Read @R13 to A
|
||||||
|
M=D // Write D to *A
|
||||||
|
@510 // push constant 510
|
||||||
|
D=A
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push constant 510
|
||||||
|
@LCL // local 0
|
||||||
|
D=M
|
||||||
|
@0 // write 0 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @LCL+0 to R13
|
||||||
|
@R13
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push local 0
|
||||||
|
@THAT // that 5
|
||||||
|
D=M
|
||||||
|
@5 // write 5 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @THAT+5 to R13
|
||||||
|
@R13
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push that 5
|
||||||
|
@SP // ==== add ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
A=A-1
|
||||||
|
M=D+M
|
||||||
|
@SP
|
||||||
|
M=M-1
|
||||||
|
@ARG // argument 1
|
||||||
|
D=M
|
||||||
|
@1 // write 1 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @ARG+1 to R13
|
||||||
|
@R13
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push argument 1
|
||||||
|
@SP // ==== sub ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
A=A-1
|
||||||
|
M=M-D
|
||||||
|
@SP
|
||||||
|
M=M-1
|
||||||
|
@THIS // this 6
|
||||||
|
D=M
|
||||||
|
@6 // write 6 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @THIS+6 to R13
|
||||||
|
@R13
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push this 6
|
||||||
|
@THIS // this 6
|
||||||
|
D=M
|
||||||
|
@6 // write 6 to A
|
||||||
|
D=D+A // D = segment+index
|
||||||
|
@R13 // save it to R13
|
||||||
|
M=D // write @THIS+6 to R13
|
||||||
|
@R13
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push this 6
|
||||||
|
@SP // ==== add ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
A=A-1
|
||||||
|
M=D+M
|
||||||
|
@SP
|
||||||
|
M=M-1
|
||||||
|
@SP // ==== sub ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
A=A-1
|
||||||
|
M=M-D
|
||||||
|
@SP
|
||||||
|
M=M-1
|
||||||
|
@R11 // temp 6
|
||||||
|
D=M
|
||||||
|
@SP
|
||||||
|
A=M
|
||||||
|
M=D
|
||||||
|
@SP
|
||||||
|
M=M+1 // end push temp 6
|
||||||
|
@SP // ==== add ====
|
||||||
|
A=M-1
|
||||||
|
D=M
|
||||||
|
A=A-1
|
||||||
|
M=D+M
|
||||||
|
@SP
|
||||||
|
M=M-1
|
||||||
|
@223
|
||||||
|
0;JMP
|
|
@ -0,0 +1,2 @@
|
||||||
|
|RAM[256]|RAM[300]|RAM[401]|RAM[402]|RAM[3006|RAM[3012|RAM[3015|RAM[11] |
|
||||||
|
| 10 | 10 | 22 | 22 | 36 | 45 | 45 | 0 |
|
|
@ -216,19 +216,94 @@ class CodeWriter {
|
||||||
"@$index // push $segment $index",
|
"@$index // push $segment $index",
|
||||||
// Write it to D
|
// Write it to D
|
||||||
"D=A",
|
"D=A",
|
||||||
// A=SP
|
]);
|
||||||
"@SP",
|
break;
|
||||||
"A=M",
|
case 'argument':
|
||||||
// Write D to SP
|
case 'local':
|
||||||
"M=D",
|
case 'this':
|
||||||
// Bump Stack Pointer
|
case 'that':
|
||||||
"@SP",
|
$this->resolveSegmentToR13($segment, $index);
|
||||||
"M=M+1 // end push $segment $index",
|
$this->write([
|
||||||
|
"@R13",
|
||||||
|
"D=M",
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'temp':
|
||||||
|
// Temp section starts from R5;
|
||||||
|
$tempBase = 5;
|
||||||
|
$ramAddress = $tempBase + $index;
|
||||||
|
$register = "@R$ramAddress";
|
||||||
|
$this->write([
|
||||||
|
"$register // temp $index",
|
||||||
|
"D=M"
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("Not Implemented $segment", 1);
|
throw new \Exception("Not Implemented $segment", 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->write([
|
||||||
|
// A=SP
|
||||||
|
"@SP",
|
||||||
|
"A=M",
|
||||||
|
// Write D to SP
|
||||||
|
"M=D",
|
||||||
|
// Bump Stack Pointer
|
||||||
|
"@SP",
|
||||||
|
"M=M+1 // end push $segment $index",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function segmentToRegister(String $segment) {
|
||||||
|
return [
|
||||||
|
'local' => '@LCL',
|
||||||
|
'argument' => '@ARG',
|
||||||
|
'this' => '@THIS',
|
||||||
|
'that' => '@THAT',
|
||||||
|
][$segment];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resolveSegmentToR13(string $segment, Int $index) {
|
||||||
|
$register = $this->segmentToRegister($segment);
|
||||||
|
$this->write([
|
||||||
|
"$register // $segment $index" ,
|
||||||
|
"D=M",
|
||||||
|
"@$index // write $index to A",
|
||||||
|
"D=D+A // D = segment+index",
|
||||||
|
"@R13 // save it to R13",
|
||||||
|
"M=D // write $register+$index to R13",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function writePop(String $segment, Int $index) {
|
||||||
|
switch ($segment) {
|
||||||
|
// The address is given by LCL+INDEX
|
||||||
|
case 'local':
|
||||||
|
case 'argument':
|
||||||
|
case 'this':
|
||||||
|
case 'that':
|
||||||
|
if($index !== 0) {
|
||||||
|
$this->resolveSegmentToR13($segment, $index);
|
||||||
|
$lookupRegister = '@R13';
|
||||||
|
} else {
|
||||||
|
$lookupRegister = $this->segmentToRegister($segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->write([
|
||||||
|
"@SP // pop",
|
||||||
|
"A=M-1",
|
||||||
|
"D=M",
|
||||||
|
$lookupRegister,
|
||||||
|
"A=M // Read $lookupRegister to A",
|
||||||
|
"M=D // Write D to *A",
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
# code...
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +315,7 @@ class CodeWriter {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CommandType::POP:
|
case CommandType::POP:
|
||||||
|
$this->writePop($segment, $index);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception("Invalid Command Type", 1);
|
throw new Exception("Invalid Command Type", 1);
|
||||||
|
|
Loading…
Reference in New Issue