;; ;; Author: Bill Slough ;; ;; Subroutines with stack frames: improved parameter passing ;; ;; Lights one pixel and one 2x2 square block ;; .ORIG x3000 ;; Main program............................................................... START LD R6,TOP ; initialize stack pointer AND R5,R5,#0 ; frame pointer = null LD R0,ROW ; ADD R6,R6,#-1 ; STR R0,R6,#0 ; push ROW LD R0,COLUMN ; ADD R6,R6,#-1 ; STR R0,R6,#0 ; push COLUMN LD R0,RED ; ADD R6,R6,#-1 ; STR R0,R6,#0 ; push RED JSR DRAW_PIXEL ; DRAW_PIXEL(ROW, COLUMN, RED) ADD R6,R6,#3 ; remove parameters from stack frame LD R0,BROW ; ADD R6,R6,#-1 ; STR R0,R6,#0 ; push BROW LD R0,BCOLUMN ; ADD R6,R6,#-1 ; STR R0,R6,#0 ; push BCOLUMN JSR DRAW_BLK ; DRAW_BLOCK(BROW, BCOLUMN) ADD R6,R6,#2 ; remove parameters from stack frame STOP HALT TOP .FILL x6000 ; where does the stack begin? ROW .FILL 2 ; which pixel row? COLUMN .FILL 8 ; which pixel column? RED .FILL x7C00 ; desired color for pixel BROW .FILL 3 ; which block row? BCOLUMN .FILL 8 ; which block column? ;; Subroutine ................................................................ DRAW_BLK ;; Draw a 2x2 green block at a specified location ;; ;; Parameters: ;; b_row -- which row of blocks ;; b_column -- which column of blocks ;; ;; Frame offsets: ;; -2 saved R2 ;; -1 saved R1 ;; 0 saved R0 ;; +1 previous frame pointer ;; +2 return address ;; +3 column ;; +4 row ;; PROLOG ADD R6,R6,#-1 ; STR R7,R6,#0 ; push return address ADD R6,R6,#-1 ; STR R5,R6,#0 ; push previous frame pointer ADD R5,R6,#-1 ; establish frame pointer for this frame STR R0,R6,#-1 ; save registers being used in this routine STR R1,R6,#-2 ; STR R2,R6,#-3 ; ADD R6,R6,#-3 ; adjust stack pointer to the top of the frame ;; BODY LDR R0,R5,#4 ; R0 = b_row LDR R1,R5,#3 ; R1 = b_column LD R2,GREEN ; R2 = green ADD R0,R0,R0 ; R0 = 2 * b_row ADD R1,R1,R1 ; R1 = 2 * b_column ADD R6,R6,#-1 ; upper left pixel in block STR R0,R6,#0 ; push R0 ADD R6,R6,#-1 ; STR R1,R6,#0 ; push R1 ADD R6,R6,#-1 ; STR R2,R6,#0 ; push R2 JSR DRAW_PIXEL ; draw_pixel(2 * b_row, 2 * b_column, GREEN) ADD R6,R6,#3 ; remove parameters ADD R1,R1,#1 ; upper right pixel in block ADD R6,R6,#-1 ; STR R0,R6,#0 ; push R0 ADD R6,R6,#-1 ; STR R1,R6,#0 ; push R1 ADD R6,R6,#-1 ; STR R2,R6,#0 ; push R2 JSR DRAW_PIXEL ; draw_pixel(2 * b_row, 2 * b_column + 1, GREEN) ADD R6,R6,#3 ; remove parameters ADD R0,R0,#1 ; lower right pixel in block ADD R6,R6,#-1 ; STR R0,R6,#0 ; push R0 ADD R6,R6,#-1 ; STR R1,R6,#0 ; push R1 ADD R6,R6,#-1 ; STR R2,R6,#0 ; push R2 JSR DRAW_PIXEL ; draw_pixel(2 * b_row + 1, 2 * b_column + 1, GREEN) ADD R6,R6,#3 ; remove parameters ADD R1,R1,#-1 ; lower left pixel in block ADD R6,R6,#-1 ; STR R0,R6,#0 ; push R0 ADD R6,R6,#-1 ; STR R1,R6,#0 ; push R1 ADD R6,R6,#-1 ; STR R2,R6,#0 ; push R2 JSR DRAW_PIXEL ; draw_pixel(2 * b_row + 1, 2 * b_column, GREEN) ADD R6,R6,#3 ; remove parameters ;; EPILOG LDR R2,R5,#-2 ; restore R2 LDR R1,R5,#-1 ; restore R1 LDR R0,R5,#0 ; restore R0 LDR R7,R5,#2 ; get the return address LDR R5,R5,#1 ; restore the previous frame pointer ADD R6,R6,#5 ; adjust the stack pointer, deallocate frame RET ;; Constants used by DRAW_BLK GREEN .FILL x03E0 ;; Subroutine ................................................................ DRAW_PIXEL ;; Draw a pixel on the graphics display unit at a specified location ;; ;; Parameters: ;; row -- a value between 0 and 123 ;; column -- a value between 0 and 127 ;; color -- a 15-bit RGB value ;; ;; Frame offsets: ;; -4 saved R4 ;; -3 saved R3 ;; -2 saved R2 ;; -1 saved R1 ;; 0 saved R0 ;; +1 previous frame pointer ;; +2 return address ;; +3 color ;; +4 column ;; +5 row ;; PROLOG ADD R6,R6,#-1 ; STR R7,R6,#0 ; push return address ADD R6,R6,#-1 ; STR R5,R6,#0 ; push previous frame pointer ADD R5,R6,#-1 ; establish frame pointer for this frame STR R0,R6,#-1 ; save registers being used in this routine STR R1,R6,#-2 ; STR R2,R6,#-3 ; STR R3,R6,#-4 ; STR R4,R6,#-5 ; ADD R6,R6,#-5 ; adjust stack pointer to the top of the frame ;; BODY LDR R0,R5,#5 ; R0 = row LDR R1,R5,#4 ; R1 = column LDR R2,R5,#3 ; R2 = color ADD R3,R0,#0 ; LD R4,PIX_PER_ROW ; MUL R3,R3,R4 ; ADD R3,R3,R1 ; R3 = PIX_PER_ROW * row + column LD R4,VIDEO_ADDR ADD R4,R4,R3 ; R4 = address of desired pixel STR R2,R4,#0 ; Video[row,column] = color ;; EPILOG LDR R4,R5,#-4 ; restore R4 LDR R3,R5,#-3 ; restore R3 LDR R2,R5,#-2 ; restore R2 LDR R1,R5,#-1 ; restore R1 LDR R0,R5,#0 ; restore R0 LDR R7,R5,#2 ; get the return address LDR R5,R5,#1 ; restore the previous frame pointer ADD R6,R6,#7 ; adjust the stack pointer, deallocate frame RET ;; Constants used by DRAW_PIXEL VIDEO_ADDR .FILL xC000 ; base address of the video display PIX_PER_ROW .FILL 128 ; number of pixels per row .END