Hack Assembly Language, another sample program.

Again, get the value at R0...

..fill that many rows of Hack Computers screen..
So here is the code I have:
// The Hack Computer has a screen with 512 x 256 = 131072 pixels.
// It is a memory - mapped screen.
// Screen starts at M[16384]. (@SCREEN will load the value 16384 to Register A.)
// Each register at a given memory address has 16 bits. 
// Since there are total of 131072 pixels.. 
// 131072 / 16 = 8192 rows starting from 16384 is mapped to the screen.
// 16384 + 8192 - 1 = M[24575] is the address of the last register for the screen. 
 
// Lets write an application that fills the number of rows in the screen
// Input will be taken from R0
// If R0 = 128, we should fill the top half of the screen.
 
@R0
D = M
@rowCounter          // This is how many rows of screen we need to fill.
M = D                // Remember each row has 512 pixels.. 
 
// Load the base address value(16384) to Register A
// Hold this value in the M[currentScreenRow]
@SCREEN           
D = A              
@currentScreenRow   
M = D              
 
(FILLROW)
// If (rowCounter == 0) {jump to end, we should not fill any rows}
@rowCounter
D = M
@ENDFILLSCREEN
D;JEQ
 
// else 
// First decrement rowCounter by 1, since we will be filling this row.
@rowCounter
D = M
D = D - 1
@rowCounter
M = D
 
// Each screen row has 512 pixels. Each Register has 16 bits. 
// 512 / 16 = 32. We will need to fill 32 registers, 
// starting from currentScreenRow, in order to fill a complete row in the Screen.
 
// For each single row, initialize a new variable, innerLoopCounter
// The innerLoopCounter is initialized with 31 instead of 32 because we will be
// filling register with offset +31, +30, +29 .. until 0 (including 0)
@31
D = A
@innerLoopCounter
M = D
 
// Start the innerLoop
(INNERLOOP)
@currentScreenRow
D = M
@innerLoopCounter
A = M
A = D + A
M = -1
 
// Decrement innerLoopCounter and store. 
@innerLoopCounter
D = M
D = D - 1
@innerLoopCounter
M = D
 
// If (innerLoopCounter < 0) {jump to (ENDFILLROW)}
// If we break when innerLoopCounter == 0, we will not fill the first 16 bits
// for the given row. (Pixels 0 to 15..)
@innerLoopCounter
D = M
@ENDFILLROW
D;JLT       // Jump if D is less than 0. innerLoopCounter has been loaded to D. 
 
// else jump to (INNERLOOP)
@INNERLOOP
0;JMP
 
// After we are done with the current row, increment the currentScreenRow by
// 32, since next row starts at the address that is at + 32..
(ENDFILLROW)
@currentScreenRow
D = M
@32
D = D + A
@currentScreenRow
M = D
 
// Now jump back to fill row
@FILLROW
0;JMP
 
// Clean up the temporary storages we used in the RAM.. 
(ENDFILLSCREEN)
@0
D = A
@rowCounter
M = D
@currentScreenRow
M = D
@innerLoopCounter
M = D
 
// Infinite loop.. Application has ended. 
(END)
@END
0;JMP

And in action: