[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,6 +216,36 @@ class CodeWriter {
|
|||
"@$index // push $segment $index",
|
||||
// Write it to D
|
||||
"D=A",
|
||||
]);
|
||||
break;
|
||||
case 'argument':
|
||||
case 'local':
|
||||
case 'this':
|
||||
case 'that':
|
||||
$this->resolveSegmentToR13($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;
|
||||
|
||||
default:
|
||||
throw new \Exception("Not Implemented $segment", 1);
|
||||
break;
|
||||
}
|
||||
|
||||
$this->write([
|
||||
// A=SP
|
||||
"@SP",
|
||||
"A=M",
|
||||
|
@ -225,10 +255,55 @@ class CodeWriter {
|
|||
"@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:
|
||||
throw new Exception("Not Implemented $segment", 1);
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +315,7 @@ class CodeWriter {
|
|||
break;
|
||||
|
||||
case CommandType::POP:
|
||||
|
||||
$this->writePop($segment, $index);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid Command Type", 1);
|
||||
|
|
Loading…
Reference in New Issue