Примечание: этот ответ является продолжением моей предыдущей, которая не поместилась бы по соображениям космоса в первый ответ.
После экспериментов единственным жизнеспособным отображением отображения является «куча», отображение с геометрией, показанной ниже. Это ограничение марса.
Вот обновленная / улучшенная версия, которая делает цвет:
# mipscirc/fix2.asm -- breshenham circle algorithm
# this _must_ be first
.data
.eqv dpy_max 4194304 # maximum display area
dpy_width: .word 512
dpy_height: .word 256
dpy_base: .word 0x10040000 # heap
dpy_now: .word 0 # current base [for debug]
dpy_blit: .word 0 # 1=do offscreen blit (currently broken)
.eqv dpy_stride 9 # left shift
.eqv dpy_size 524288 # display size (bytes)
.eqv dpy_margin 8 # radius margin
.data
sdata:
radius: .word 10
center_x: .word 0
center_y: .word 0
# midpoint circle algorithm variables
color_octant: .space 32
dpy_radius: .word 10
dpy_color: .word 0x00FFFFFF
ask_diamond: .word 0 # 1=do diamond pattern
ask_radmin: .word 0 # minimum radius (0=single circle)
ask_radinc: .word 16 # radius decrement amount
ask_colorinc: .word 0 # color increment (0=single color)
bitmap: .space dpy_size
.text
.globl main
main:
# this _must_ be first
li $a0,dpy_size # maximum size
li $v0,9 # sbrk
syscall
lw $v1,dpy_base # get what we expect
beq $v0,$v1,dpyinit_done
la $a0,_S_000
li $v0,4 # puts
syscall
dpyinit_done:
.eqv mrzhow $fp
li $v1,0 # clear mask
.eqv MRZDBGPRT 0x00000001 # output numbers
.eqv _MRZDBGPRT 0 # output numbers
.eqv MRZDPYSHOW 0x00000002 # show display coordinates
.eqv _MRZDPYSHOW 1 # show display coordinates
.eqv MRZDPYCHK 0x00000004 # check display area bounds
.eqv _MRZDPYCHK 2 # check display area bounds
move mrzhow,$v1 # set final register value
# prompt user for ask_diamond value
la $a0,_S_001 # prompt user
li $a1,0 # set default
jal qask
sw $v0,ask_diamond # place to store
# prompt user for ask_radmin value
la $a0,_S_002 # prompt user
li $a1,4 # set default
jal qask
sw $v0,ask_radmin # place to store
lw $t0,ask_radmin
beqz $t0,main_skipinc
# prompt user for ask_radinc value
la $a0,_S_003 # prompt user
li $a1,6 # set default
jal qask
sw $v0,ask_radinc # place to store
main_skipinc:
# prompt user for ask_colorinc value
la $a0,_S_004 # prompt user
li $a1,-2 # set default
jal qask
sw $v0,ask_colorinc # place to store
lw $t0,ask_radmin
# compute circle center from display geometry
lw $s6,dpy_width
srl $s6,$s6,1
sw $s6,center_x
lw $s5,dpy_height
srl $s5,$s5,1
sw $s5,center_y
# set radius to min((width / 2) - 16,(height / 2) - 16)
move $s0,$s6
blt $s6,$s5,main_gotradius
move $s0,$s5
main_gotradius:
subi $s0,$s0,dpy_margin # give us some margin
sw $s0,dpy_radius
main_loop:
jal colorgo
jal colorinc
bnez $v0,main_loop
main_done:
li $v0,10
syscall
# colorgo -- draw all items with single color
colorgo:
subi $sp,$sp,4
sw $ra,0($sp)
jal dpybase
# reset the radius
colorgo_noblit:
lw $t0,dpy_radius
sw $t0,radius
colorgo_loop:
# output circle
jal kdraw
jal radbump
# output diamond/hexagon
lw $t0,ask_diamond # is it enabled?
beqz $t0,colorgo_next # if no, skip
jal wdraw
jal radbump
colorgo_next:
bnez $v0,colorgo_loop # done with concentric circles? if no, loop
jal dpyblit # blit to screen (if mode applicable)
colorgo_done:
lw $ra,0($sp)
addi $sp,$sp,4
jr $ra
# colorinc -- increment to next color
#
# RETURNS:
# v0 -- 1=more to do, 0=done
#
# registers:
# t0 -- color value
colorinc:
subi $sp,$sp,4
sw $ra,0($sp)
lw $v0,ask_colorinc # get option that controls increment
beqz $v0,colorinc_done # do increment? if no, fly
bltz $v0,colorinc_rand # random increment? if yes, fly
lw $t0,dpy_color # get current color
addi $t0,$t0,1 # increment it
andi $t0,$t0,0x00FFFFFF # keep it clean
sw $t0,dpy_color # save it back
li $v0,1
j colorinc_done
colorinc_rand:
jal colorany # get random colors
lw $t0,color_octant # the first one
sw $t0,dpy_color # save to the single color
# without a delay, the colors blast by too fast to be enjoyed
###li $t0,1000000
li $t0,500000
colorinc_loop:
subi $t0,$t0,1
bgtz $t0,colorinc_loop
li $v0,1
colorinc_done:
lw $ra,0($sp)
addi $sp,$sp,4
jr $ra
# colorany -- get random colors
colorany:
lw $t0,ask_colorinc # get option
li $t1,-3 # get value for the "spin" option
bne $t0,$t1,colorany_noslide # slide mode? if no, fly
li $t0,7
la $t1,color_octant
subi $t1,$t1,4
# slide all colors to make room for single new one
colorany_slide:
addi $t1,$t1,4 # advance
lw $a0,4($t1) # get ptr[1]
sw $a0,0($t1) # set ptr[0]
subi $t0,$t0,1 # more to do?
bnez $t0,colorany_slide # if yes, loop
# set new random first element
li $v0,41 # randint
syscall
andi $a0,$a0,0x00FFFFFF # clean the value
sw $a0,4($t1)
j colorany_done
colorany_noslide:
li $t0,8
la $t1,color_octant
colorany_loop:
li $v0,41 # randint
syscall
andi $a0,$a0,0x00FFFFFF # clean the value
sw $a0,0($t1) # store it
subi $t0,$t0,1 # decrement remaining count
addi $t1,$t1,4 # advance pointer
bnez $t0,colorany_loop # done? if no, loop
colorany_done:
jr $ra
# radbump -- bump down radius
#
# RETURNS:
# v0 -- 1=more to do, 0=done
#
# registers:
# t0 -- radius value
radbump:
lw $t0,radius
lw $t1,ask_radinc
sub $t0,$t0,$t1
lw $v0,ask_radmin # do multiple rings?
beqz $v0,radbump_store # if no, fly
slt $v0,$v0,$t0 # radius < ask_radmin?
radbump_store:
beqz $t0,radbump_safe
sw $t0,radius
radbump_safe:
jr $ra
# wdraw -- draw circle (wikipedia)
#
# NOTES:
# (1) this is wikipedia's algorithm for a circle, but it is more like a
# diamond or polygon
# (2) https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
# (2) either it's "broken" or _I_ broke it
#
# registers:
# s0 -- x
# s1 -- y
# s2 -- decision/error term (err)
#
# * void
# * DrawCircle(int x0,int y0,int radius)
# * {
# * int x = radius;
# * int y = 0;
# *
# * // Decision criterion divided by 2 evaluated at x=r, y=0
# * int decisionOver2 = 1 - x;
# *
# * while (y <= x) {
# * DrawPixel(x + x0,y + y0); // Octant 1
# * DrawPixel(y + x0,x + y0); // Octant 2
# * DrawPixel(-x + x0,y + y0); // Octant 4
# * DrawPixel(-y + x0,x + y0); // Octant 3
# * DrawPixel(-x + x0,-y + y0); // Octant 5
# * DrawPixel(-y + x0,-x + y0); // Octant 6
# * DrawPixel(x + x0,-y + y0); // Octant 7
# * DrawPixel(y + x0,-x + y0); // Octant 8
# *
# * y++;
# *
# * // Change in decision criterion for y -> y+1
# * if (decisionOver2 <= 0) {
# * decisionOver2 += 2 * y + 1;
# * }
# *
# * // Change for y -> y+1, x -> x-1
# * else {
# * x--;
# * decisionOver2 += 2 * (y - x) + 1;
# * }
# * }
# * }
wdraw:
subi $sp,$sp,4
sw $ra,0($sp)
lw $s0,radius # x = radius
li $s1,0 # y = 0
# get initial decision (err = 1 - x)
li $s2,1 # err = 1
sub $s2,$s2,$s0 # err = 1 - x
wdraw_loop:
bgt $s1,$s0,wdraw_done # y <= x? if no, fly (we're done)
# draw pixels in all 8 octants
jal draw8
addi $s1,$s1,1 # y += 1
bgtz $s2,wdraw_case2 # err <= 0? if no, fly
# change in decision criterion for y -> y+1
# err += (2 * y) + 1
wdraw_case1:
sll $t0,$s2,1 # get 2 * y
addu $s2,$s2,$t0 # err += 2 * y (NOTE: this can overflow)
add $s2,$s2,1 # err += 1
j wdraw_loop
# change for y -> y+1, x -> x-1
# x -= 1
# err += (2 * (y - x)) + 1
wdraw_case2:
subi $s0,$s0,1 # x -= 1
sub $t0,$s1,$s0 # get y - x
sll $t0,$t0,1 # get 2 * (y - x)
addi $t0,$t0,1 # get 2 * (y - x) + 1
add $s2,$s2,$t0 # add it to err
j wdraw_loop
wdraw_done:
lw $ra,0($sp)
addi $sp,$sp,4
jr $ra
# kdraw -- draw circle (john kennedy)
#
# NOTES:
# (1) this is John Kennedy's algorithm from:
# http://web.engr.oregonstate.edu/~sllu/bcircle.pdf
#
# registers:
# s0 -- x
# s1 -- y
# s2 -- raderr
# s3 -- xchg
# s4 -- ychg
#
# * void
# * PlotCircle(int CX, int CY, int r)
# * {
# * int x;
# * int y;
# * int xchg;
# * int ychg;
# * int raderr;
# *
# * x = r;
# * y = 0;
# *
# * xchg = 1 - (2 * r);
# * ychg = 1;
# *
# * raderr = 0;
# *
# * while (x >= y) {
# * draw8(x,y);
# * y += 1;
# *
# * raderr += ychg;
# * ychg += 2;
# *
# * if (((2 * raderr) + xchg) > 0) {
# * x -= 1;
# * raderr += xchg;
# * xchg += 2;
# * }
# * }
# * }
kdraw:
subi $sp,$sp,4
sw $ra,0($sp)
lw $s0,radius # x = radius
li $s1,0 # y = 0
# initialize: xchg = 1 - (2 * r)
li $s3,1 # xchg = 1
sll $t0,$s0,1 # get 2 * r
sub $s3,$s3,$t0 # xchg -= (2 * r)
li $s4,1 # ychg = 1
li $s2,0 # raderr = 0
kdraw_loop:
blt $s0,$s1,kdraw_done # x >= y? if no, fly (we're done)
# draw pixels in all 8 octants
jal draw8
addi $s1,$s1,1 # y += 1
add $s2,$s2,$s4 # raderr += ychg
addi $s4,$s4,2 # ychg += 2
sll $t0,$s2,1 # get 2 * raderr
add $t0,$t0,$s3 # get (2 * raderr) + xchg
blez $s2,kdraw_loop # >0? if no, loop
subi $s0,$s0,1 # x -= 1
add $s2,$s2,$s3 # raderr += xchg
addi $s3,$s3,2 # xchg += 2
j kdraw_loop
kdraw_done:
lw $ra,0($sp)
addi $sp,$sp,4
jr $ra
# draw8 -- draw single point in all 8 octants
#
# arguments:
# s0 -- X coord
# s1 -- Y coord
#
# registers:
# t8 -- center_x
# t9 -- center_y
draw8:
subi $sp,$sp,4
sw $ra,0($sp)
lw $t8,center_x
lw $t9,center_y
lw $a2,dpy_color
lw $t0,ask_colorinc
li $t1,-2
ble $t0,$t1,draw8_octant
# draw [+x,+y]
add $a0,$t8,$s0
add $a1,$t9,$s1
jal dpypixel
# draw [+y,+x]
add $a0,$t8,$s1
add $a1,$t9,$s0
jal dpypixel
# draw [-y,+x]
add $a0,$t8,$s1
sub $a1,$t9,$s0
jal dpypixel
# draw [-x,+y]
sub $a0,$t8,$s0
add $a1,$t9,$s1
jal dpypixel
# draw [-x,-y]
sub $a0,$t8,$s0
sub $a1,$t9,$s1
jal dpypixel
# draw [-y,-x]
sub $a0,$t8,$s1
sub $a1,$t9,$s0
jal dpypixel
# draw [+x,-y]
add $a0,$t8,$s0
sub $a1,$t9,$s1
jal dpypixel
# draw [+y,-x]
sub $a0,$t8,$s1
add $a1,$t9,$s0
jal dpypixel
j draw8_done
draw8_octant:
la $t7,color_octant
# draw [+x,+y]
add $a0,$t8,$s0
add $a1,$t9,$s1
lw $a2,0($t7)
addi $t7,$t7,4
jal dpypixel
# draw [+y,+x]
add $a0,$t8,$s1
add $a1,$t9,$s0
lw $a2,0($t7)
addi $t7,$t7,4
jal dpypixel
# draw [-y,+x]
add $a0,$t8,$s1
sub $a1,$t9,$s0
lw $a2,0($t7)
addi $t7,$t7,4
jal dpypixel
# draw [-x,+y]
sub $a0,$t8,$s0
add $a1,$t9,$s1
lw $a2,0($t7)
addi $t7,$t7,4
jal dpypixel
# draw [-x,-y]
sub $a0,$t8,$s0
sub $a1,$t9,$s1
lw $a2,0($t7)
addi $t7,$t7,4
jal dpypixel
# draw [-y,-x]
sub $a0,$t8,$s1
sub $a1,$t9,$s0
lw $a2,0($t7)
addi $t7,$t7,4
jal dpypixel
# draw [+x,-y]
add $a0,$t8,$s0
sub $a1,$t9,$s1
lw $a2,0($t7)
addi $t7,$t7,4
jal dpypixel
# draw [+y,-x]
sub $a0,$t8,$s1
add $a1,$t9,$s0
lw $a2,0($t7)
addi $t7,$t7,4
jal dpypixel
draw8_done:
lw $ra,0($sp)
addi $sp,$sp,4
jr $ra
# marzmca/marzdpy.inc -- mars display functions
# dpypixel -- draw pixel on display
#
# arguments:
# a0 -- X coord
# a1 -- Y coord
# a2 -- color
# a3 -- display base address
#
# clobbers:
# v1 -- bitmap offset/index
# trace:
# v0,a0
dpypixel:
dpypixel_go:
lw $v1,dpy_width # off = display width
mul $v1,$a1,$v1 # off = y * width
add $v1,$v1,$a0 # off += x
sll $v1,$v1,2 # convert to offset
add $v1,$a3,$v1 # ptr = base + off
sw $a2,($v1) # store pixel
jr $ra
# dpybase -- get display base address
#
# RETURNS:
# a3 -- display base address
dpybase:
lw $a3,dpy_base # direct draw to display
lw $t0,dpy_blit
beqz $t0,dpybase_done
la $a3,bitmap # draw to bitmap
dpybase_done:
sw $a3,dpy_now # remember it [for debug]
jr $ra
# dpyblit -- blit bitmap to display
dpyblit:
lw $a0,dpy_blit # blit mode?
beqz $a0,dpyblit_done # if no, fly
li $t0,2 # zap the background first?
blt $a0,$t2,dpyblit_init # if no, fly
# zero out the display
lw $a0,dpy_base # get the base address
addi $a1,$a0,dpy_size # get the end address
dpyblit_zap:
sw $zero,0($a0) # set black
addi $a0,$a0,4 # advance current pointer
blt $a0,$a1,dpyblit_zap # more to do? if yes, loop
# setup for blit
dpyblit_init:
lw $a0,dpy_base # get the base address
addi $a1,$a0,dpy_size # get the end address
la $a2,bitmap # get offscreen address
dpyblit_loop:
lw $t0,0($a2) # fetch from offscreen image
addi $a2,$a2,4 # advance offscreen pointer
sw $t0,0($a0) # store to live area
addi $a0,$a0,4 # advance current pointer
blt $a0,$a1,dpyblit_loop # more to do? if yes, loop
dpyblit_done:
jr $ra
# marzmca/marzqask.inc -- extra prompting functions
.eqv qask_siz 100
# qask -- prompt user for number (possibly hex)
#
# RETURNS:
# v0 -- value
#
# arguments:
# a0 -- prompt string
# a1 -- default value
#
# registers:
# a2 -- save for a0
# a3 -- save for a1
# t0 -- current buffer char
# t1 -- offset into qask_hex
# t2 -- current hex string char
# t3 -- current hex string pointer
# t6 -- 1=negative
# t7 -- number base
qask:
move $a2,$a0 # remember for reprompt
move $a3,$a1 # remember for reprompt
qask_retry:
# output the prompt
move $a0,$a2
li $v0,4
syscall
la $a0,qask_dft1
li $v0,4
syscall
# output the default value
move $a0,$a3
li $v0,1
syscall
la $a0,qask_dft2
li $v0,4
syscall
# read in string
li $v0,8
la $a0,qask_buf
la $a1,qask_siz
syscall
lb $t0,0($a0) # get first buffer char
li $t1,0x0A # get newline
beq $t0,$t1,qask_dft # empty line? if yes, use default
li $v0,0 # zap accumulator
# decide if we have a negative number
li $t6,0
lb $t0,0($a0) # get first buffer char
li $t1,'-'
bne $t0,$t1,qask_tryhex
li $t6,1 # set negative number
addi $a0,$a0,1 # skip over '-'
# decide if want hex
qask_tryhex:
li $t7,10 # assume base 10
li $t1,'x'
bne $t0,$t1,qask_loop
addi $a0,$a0,1 # skip over 'x'
li $t7,16 # set base 16
qask_loop:
lb $t0,0($a0) # get character
addi $a0,$a0,1 # advance buffer pointer
# bug out if newline -- we are done
li $t1,0x0A
beq $t0,$t1,qask_done
la $t3,qask_hex
li $t1,0
qask_trymatch:
lb $t2,0($t3) # get next hex char
addi $t3,$t3,1 # advance hex string pointer
beq $t2,$t0,qask_match # got a match
addi $t1,$t1,1 # advance hex offset
blt $t1,$t7,qask_trymatch # too large? if no, loop
j qask_retry # if yes, the input char is unknown
qask_match:
mul $v0,$v0,$t7 # acc *= base
add $v0,$v0,$t1 # acc += digit
j qask_loop
qask_dft:
move $v0,$a3
j qask_exit
qask_done:
beqz $t6,qask_exit
neg $v0,$v0 # set negative number
qask_exit:
jr $ra
.data
qask_dft1: .asciiz " ["
qask_dft2: .asciiz "] > "
qask_buf: .space qask_siz
qask_hex: .asciiz "0123456789ABCDEF"
.text
.data
_S_000: .asciiz "dpyinit: mismatch\n"
_S_001: .asciiz "output diamond pattern?"
_S_002: .asciiz "minimum radius (0=single)"
_S_003: .asciiz "radius decrement"
_S_004: .asciiz "color increment (-1=rand, -2=rand/octant, -3=spin)"
_S_005: .asciiz "dpy_width"
_S_006: .asciiz "dpy_height"
_S_007: .asciiz "dpy_radius"
.data #+
#+
edata:
Я отвечаю на свой вопрос, потому что оказывается, что самый простой способ сделать это - манипулировать вашим системным временем. Это было обременительно для меня, потому что оно заблокировано на моей машине разработчика, поэтому мне пришлось делать это на машине с виртуальной коробкой с отключенной синхронизацией времени. После изменения системного времени на дату в течение срока действия сертификата я смог подписать файлы. Позже я даже смог добавить метку времени, используя внешний сервис. Конечно, Windows сразу же будет жаловаться на этот факт, если вы решите проверить вкладку «Цифровые подписи» в свойствах файла, но это то, чего я хотел добиться для выполнения своих тестов.