Write optimized/semi-unrolled Fill, add comments
x1phosura x1phosura@x1phosura.zone
Sun, 26 Dec 2021 19:52:08 -0800
2 files changed,
121 insertions(+),
6 deletions(-)
A
projects/04/fill/Fill-unrolled.asm
@@ -0,0 +1,115 @@
+// This file is part of www.nand2tetris.org +// and the book "The Elements of Computing Systems" +// by Nisan and Schocken, MIT Press. +// File name: projects/04/Fill.asm + +// Runs an infinite loop that listens to the keyboard input. +// When a key is pressed (any key), the program blackens the screen, +// i.e. writes "black" in every pixel; +// the screen should remain fully black as long as the key is pressed. +// When no key is pressed, the program clears the screen, i.e. writes +// "white" in every pixel; +// the screen should remain fully clear as long as no key is pressed. + +// Put your code here. + +// Fill: for length of screen, checks keypress. If keypress is nonzero, set +// R2 to -1 (black), otherwise set R2 to 0 (white). Do 8 times: set two 16-bit +// words in screen to R2 ("coloring white or black"). + +// Point to next 16 +// pixels and repeat to enf of screen, then restart at start of screen. +// +// R0 - current screen pointer (to-be incremented until end of screen is hit) +// R1 - DRAW_SCREEN_LOOP local loop counter (for optimized drawing of 2 rows) +// R2 - 0 or -1 (white or black), stored 16-pixel pattern to draw + +// zero initialize local variables +@R1 +M=0 +@R2 +M=0 + +(SET_SCREEN_PTR) + // R0 = SCREEN pointer + @SCREEN + D=A + @R0 + M=D + +(IS_KEYPRESSED) + // end of screen: 0x5fff (dec 24575) + // if R0 >= (24575 - 8); goto SET_SCREEN_PTR + @R0 + D=M + @24567 + D=D-A + @SET_SCREEN_PTR + D;JGE + + // D=KBD, goto WHITE_SCREEN if D == 0 + @KBD + D=M + @WHITE_SCREEN + D;JEQ + +(BLACK_SCREEN) + @R2 + M=-1 + @DRAW_SCREEN_LOOP + 0;JMP + +(WHITE_SCREEN) + @R2 + M=0 + +(DRAW_SCREEN_LOOP) + // D = <16-bit pixel pattern to draw> + @R2 + D=M + // *R0++ = -1; *R0++ = -1 (unrolled and optimized) + @R0 + A=M + M=D + A=A+1 + M=D + D=A+1 + @R0 + M=D + + // *R0++ = -1 (unrolled and unoptimized, old) + //@R0 + //A=M + //M=D + //@R0 + //M=M+1 + // *R0++ = -1 + //@R0 + //A=M + //M=D + //@R0 + //M=M+1 + + // increment local loop counter + @R1 + M=M+1 + + // if (R1 - 8) > 0, then exit local loop, otherwise loop back + @R1 + D=M + @7 + D=D-A + @DRAW_SCREEN_LOOP + D;JLE + + // set local loop count to zero, return to test if key is pressed + @R1 + M=0 + @IS_KEYPRESSED + 0;JMP + +// should never reach here, but just in case... +(END) + @END + 0;JMP +
M
projects/04/fill/Fill.asm
→
projects/04/fill/Fill.asm
@@ -13,9 +13,11 @@ // the screen should remain fully clear as long as no key is pressed.
// Put your code here. -// TODO: optimize better in the future - -// have separate branch _only_ for drawing black/white pixels +// Fill: for length of screen, checks keypress. If keypress is nonzero, set +// current 16 pixels to black, otherwise set them to white. Point to next 16 +// pixels and repeat to enf of screen, then restart at start of screen. +// +// R0 - current screen pointer (to-be incremented until end of screen is hit) (SET_SCREEN_PTR) // R0 = SCREEN pointer@@ -24,10 +26,8 @@ D=A
@R0 M=D -// TODO: fix infinitely incrementing screen pointer bug -// end of screen: 0x5fff (dec 24575) - (IS_KEYPRESSED) + // end of screen: 0x5fff (dec 24575) // if R0 == 24575; goto SET_SCREEN_PTR @R0 D=M