projects/04/fill/Fill-unrolled.asm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 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
|