05/Memory
This commit is contained in:
parent
262e336fcd
commit
69a32190dc
51
NOTES.md
51
NOTES.md
|
@ -14,30 +14,33 @@ PC
|
||||||
|
|
||||||
Fill.asm
|
Fill.asm
|
||||||
: Figured out that my RAM16K implementation was wrong while working on this. The rough pseudocode would be:
|
: Figured out that my RAM16K implementation was wrong while working on this. The rough pseudocode would be:
|
||||||
```c
|
```c
|
||||||
int r0=*screen;
|
int r0=*screen;
|
||||||
while(true) {
|
while(true) {
|
||||||
int color = 0;
|
int color = 0;
|
||||||
if (*kbd > 0) {
|
if (*kbd > 0) {
|
||||||
color = -1;
|
color = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This sets an entire row of pixels to color
|
// This sets an entire row of pixels to color
|
||||||
// each row has 32 registers (512/16) that we set to color
|
// each row has 32 registers (512/16) that we set to color
|
||||||
*r0 = color;
|
*r0 = color;
|
||||||
*r0+1 = color;
|
*r0+1 = color;
|
||||||
*r0+2 = color;
|
*r0+2 = color;
|
||||||
*r0+3 = color;
|
*r0+3 = color;
|
||||||
*r0+4 = color;
|
*r0+4 = color;
|
||||||
// and so on
|
// and so on
|
||||||
*r0+31 = color;
|
*r0+31 = color;
|
||||||
|
|
||||||
// if we are on the last row
|
// if we are on the last row
|
||||||
if (r0-24575 <=0) {
|
if (r0-24575 <=0) {
|
||||||
r0 = *screen;
|
r0 = *screen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
So every "cycle" of the loop, we are coloring an entire row. The row is decided by R0, which is set to @SCREEN at the start. So if you press a key while we are on the middle of the loop (say 120th row), everything from that row onwards would get painted in black, and then the loop resets r0=*screen once we cross the limits. The next iteration of the loop then starts filling the white pixels we'd left in the previous iteration. I kept the smallest paint unit as the row, but it doesn't really matter that much. The only difference is that I'm reading kbd a total of 256 times to paint the screen. Reading once per register also would work, and reading once per "screenfill" would also work. But that changes the 'delay' b/w your keyboard press and the screen fill start. I thought per row was a good compromise.
|
|
||||||
**assembly**: Since our assembly doesn't have any functions, writing Assembly is much tougher than I thought it would be. All state is global, there are no functions, and you can only jump using goto.
|
So every "cycle" of the loop, we are coloring an entire row. The row is decided by R0, which is set to @SCREEN at the start. So if you press a key while we are on the middle of the loop (say 120th row), everything from that row onwards would get painted in black, and then the loop resets r0=\*screen once we cross the limits. The next iteration of the loop then starts filling the white pixels we'd left in the previous iteration. I kept the smallest paint unit as the row, but it doesn't really matter that much. The only difference is that I'm reading kbd a total of 256 times to paint the screen. Reading once per register also would work, and reading once per "screenfill" would also work. But that changes the 'delay' b/w your keyboard press and the screen fill start. I thought per row was a good compromise.
|
||||||
|
|
||||||
|
Memory
|
||||||
|
: Started by using a Mux4Way16, but then decided against making the same mistake I did in PC. Switched to 2 Mux16s instead.
|
||||||
|
|
|
@ -61,7 +61,7 @@ Counting number of instructions by `wc -l $file.hack`
|
||||||
|
|
||||||
## [Project 5: Computer Architecture](https://www.nand2tetris.org/project05)
|
## [Project 5: Computer Architecture](https://www.nand2tetris.org/project05)
|
||||||
|
|
||||||
- [ ] `Memory.hdl`
|
- [x] `Memory.hdl` (2xMux16, 2xNot, 3xAnd)
|
||||||
- [ ] `CPU.hdl`
|
- [ ] `CPU.hdl`
|
||||||
- [ ] `Computer.hdl`
|
- [ ] `Computer.hdl`
|
||||||
|
|
||||||
|
|
|
@ -5,20 +5,20 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The complete address space of the Hack computer's memory,
|
* The complete address space of the Hack computer's memory,
|
||||||
* including RAM and memory-mapped I/O.
|
* including RAM and memory-mapped I/O.
|
||||||
* The chip facilitates read and write operations, as follows:
|
* The chip facilitates read and write operations, as follows:
|
||||||
* Read: out(t) = Memory[address(t)](t)
|
* Read: out(t) = Memory[address(t)](t)
|
||||||
* Write: if load(t-1) then Memory[address(t-1)](t) = in(t-1)
|
* Write: if load(t-1) then Memory[address(t-1)](t) = in(t-1)
|
||||||
* In words: the chip always outputs the value stored at the memory
|
* In words: the chip always outputs the value stored at the memory
|
||||||
* location specified by address. If load==1, the in value is loaded
|
* location specified by address. If load==1, the in value is loaded
|
||||||
* into the memory location specified by address. This value becomes
|
* into the memory location specified by address. This value becomes
|
||||||
* available through the out output from the next time step onward.
|
* available through the out output from the next time step onward.
|
||||||
* Address space rules:
|
* Address space rules:
|
||||||
* Only the upper 16K+8K+1 words of the Memory chip are used.
|
* Only the upper 16K+8K+1 words of the Memory chip are used.
|
||||||
* Access to address>0x6000 is invalid. Access to any address in
|
* Access to address>0x6000 is invalid. Access to any address in
|
||||||
* the range 0x4000-0x5FFF results in accessing the screen memory
|
* the range 0x4000-0x5FFF results in accessing the screen memory
|
||||||
* map. Access to address 0x6000 results in accessing the keyboard
|
* map. Access to address 0x6000 results in accessing the keyboard
|
||||||
* memory map. The behavior in these addresses is described in the
|
* memory map. The behavior in these addresses is described in the
|
||||||
* Screen and Keyboard chip specifications given in the book.
|
* Screen and Keyboard chip specifications given in the book.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -27,5 +27,22 @@ CHIP Memory {
|
||||||
OUT out[16];
|
OUT out[16];
|
||||||
|
|
||||||
PARTS:
|
PARTS:
|
||||||
// Put your code here:
|
// loadscreen = address[14] && (!address[13]) && load
|
||||||
}
|
Not(in=address[13], out=notkbd);
|
||||||
|
And(a=address[14], b=notkbd, out=pickscreen);
|
||||||
|
And(a=pickscreen,b=load, out=loadscreen);
|
||||||
|
|
||||||
|
// loadram = !address[14] && load
|
||||||
|
Not(in=address[14], out=pickram);
|
||||||
|
And(a=pickram,b=load, out=loadram);
|
||||||
|
RAM16K(in=in,load=loadram,address=address[0..13], out=ramout);
|
||||||
|
|
||||||
|
// This is only called if MSB(address) == 1
|
||||||
|
Screen(in=in, load=loadscreen, address=address[0..12], out=screenout);
|
||||||
|
Keyboard(out=kbdout);
|
||||||
|
|
||||||
|
// MSB(0|1) = RAM|(screen|keyboard)
|
||||||
|
Mux16(a=ramout, b=kbdorscreenout, sel=address[14], out=out);
|
||||||
|
// address[13] = screen|keyboard
|
||||||
|
Mux16(a=screenout, b=kbdout, sel=address[13], out=kbdorscreenout);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
| in |load | address | out |
|
||||||
|
| -1 | 1 | 000000000000000 | 0 |
|
||||||
|
| -1 | 1 | 000000000000000 | -1 |
|
||||||
|
| 9999 | 0 | 000000000000000 | -1 |
|
||||||
|
| 9999 | 0 | 000000000000000 | -1 |
|
||||||
|
| 9999 | 0 | 010000000000000 | 0 |
|
||||||
|
| 9999 | 0 | 100000000000000 | 0 |
|
||||||
|
| 2222 | 1 | 010000000000000 | 0 |
|
||||||
|
| 2222 | 1 | 010000000000000 | 2222 |
|
||||||
|
| 9999 | 0 | 010000000000000 | 2222 |
|
||||||
|
| 9999 | 0 | 010000000000000 | 2222 |
|
||||||
|
| 9999 | 0 | 000000000000000 | -1 |
|
||||||
|
| 9999 | 0 | 100000000000000 | 0 |
|
||||||
|
| 9999 | 0 | 000000000000001 | 0 |
|
||||||
|
| 9999 | 0 | 000000000000010 | 0 |
|
||||||
|
| 9999 | 0 | 000000000000100 | 0 |
|
||||||
|
| 9999 | 0 | 000000000001000 | 0 |
|
||||||
|
| 9999 | 0 | 000000000010000 | 0 |
|
||||||
|
| 9999 | 0 | 000000000100000 | 0 |
|
||||||
|
| 9999 | 0 | 000000001000000 | 0 |
|
||||||
|
| 9999 | 0 | 000000010000000 | 0 |
|
||||||
|
| 9999 | 0 | 000000100000000 | 0 |
|
||||||
|
| 9999 | 0 | 000001000000000 | 0 |
|
||||||
|
| 9999 | 0 | 000010000000000 | 0 |
|
||||||
|
| 9999 | 0 | 000100000000000 | 0 |
|
||||||
|
| 9999 | 0 | 001000000000000 | 0 |
|
||||||
|
| 9999 | 0 | 010000000000000 | 2222 |
|
||||||
|
| 1234 | 1 | 001001000110100 | 0 |
|
||||||
|
| 1234 | 1 | 001001000110100 | 1234 |
|
||||||
|
| 1234 | 0 | 010001000110100 | 0 |
|
||||||
|
| 1234 | 0 | 110001000110100 | 0 |
|
||||||
|
| 2345 | 1 | 010001101000101 | 0 |
|
||||||
|
| 2345 | 1 | 010001101000101 | 2345 |
|
||||||
|
| 2345 | 0 | 000001101000101 | 0 |
|
||||||
|
| 2345 | 0 | 100001101000101 | 0 |
|
||||||
|
| 2345 | 0 | 110000000000000 | 75 |
|
||||||
|
| -1 | 1 | 100111111001111 | -1 |
|
||||||
|
| -1 | 1 | 101000001001111 | -1 |
|
||||||
|
| -1 | 1 | 000111111001111 | 0 |
|
||||||
|
| -1 | 1 | 010111111001111 | 0 |
|
||||||
|
| -1 | 0 | 100111111001110 | 0 |
|
||||||
|
| -1 | 0 | 100111111001101 | 0 |
|
||||||
|
| -1 | 0 | 100111111001011 | 0 |
|
||||||
|
| -1 | 0 | 100111111000111 | 0 |
|
||||||
|
| -1 | 0 | 100111111011111 | 0 |
|
||||||
|
| -1 | 0 | 100111111101111 | 0 |
|
||||||
|
| -1 | 0 | 100111110001111 | 0 |
|
||||||
|
| -1 | 0 | 100111101001111 | 0 |
|
||||||
|
| -1 | 0 | 100111011001111 | 0 |
|
||||||
|
| -1 | 0 | 100110111001111 | 0 |
|
||||||
|
| -1 | 0 | 100101111001111 | 0 |
|
||||||
|
| -1 | 0 | 100011111001111 | 0 |
|
||||||
|
| -1 | 0 | 101111111001111 | 0 |
|
||||||
|
| -1 | 0 | 110000000000000 | 89 |
|
Loading…
Reference in New Issue