📄 asm_prsm.s
字号:
movel a6@(8),d2 | x1 movel a6@(12),d3 | y1 movel a6@(20),d1 | y2 movel a6@(16),a2 | x2 subl d3,d1 | (y2 - y1) -> d1 clrl d4 | d4 = (2 * dx) = NA clrl d5 | d5 = (2 * dx) = NB subl d1,d4 | (2 * dx) - dy -> d4 subql #1,d4 | d4 - SY -> d4 movel d1,d6 | dy -> d6 movel d5,d7 | dx -> d7 subl d6,d7 | dx - dy -> d7 lsll #1,d7 | shift left, d7 = ND| by this point, d4 = ND, d5 = NB subql #1,d6 | d6 = NC moveq #6,d0 | SX, SY, XMAJ| we are drawing a series of vertical lines, all the same length| so no need to re-calculate all the magic numbers each timeldraw5x_1: cmpl d2,a2 | x1 <= x2 jge ldraw5x_2 jra ldraw5x_12ldraw5x_2: movel #0x0e,a0@(GCW_CMD) | write, 4x5, 1 of 20 tstl d1 | dy bne ldraw5x_10 movel d3,a0@(GCW_PY) | pixel Y addr movel d2,a0@(GCW_PX_SM) | pixel X addr, start single mem bra ldraw5x_11ldraw5x_10: movel d4,a0@(GCW_LG2) | NA movel d5,a0@(GCW_LG1) | NB movel d7,a0@(GCW_LG2) | ND movel d6,a0@(GCW_LG3) | NC movel d0,a0@(GCW_LG4) | SX, SY, XMAJ movel d3,a0@(GCW_PY) | pixel Y movel d2,a0@(GCW_PX_SL) | pixel X, start lineldraw5x_11: addql #1,d2 | x++ jra ldraw5x_1ldraw5x_12: moveml sp@+,d0-d7/a0-a2 unlk a6 rts| read 1 pixel from the screen, handle the bizarre layout .even.globl r1pix3r1pix3: link a6,#0 moveml d1-d5/a0,sp@- movew #1023,d5 subw a6@(14),d5 | d5 is y as 16-bit value movew d5,d4 andib #0xfc,d4 | d4 is y0 movew #3,d0 andw d5,d0 | y & 3 movel #3,d3 | ensure top word is clear subw d0,d3 | 3 - (y & 3) aslw #3,d3 | << 3 movel a6@(8),d0 | x divuw #20,d0 | x % 20 clrw d0 | clear quotient swap d0 | put remainder in lower 16 bits divuw #5,d0 | (x % 20) / 5 aslw #3,d0 | << 3 addw d0,d3 | ys in d3 movew #24,d0 cmpw d3,d0 jge r1pix3_1 movew #-32,d0 addw d0,d3r1pix3_1: lea GC_BASE,a0 | base of video control registers movel a6@(16),a0@(GCW_PSEL) | plane select mask movel #0x07,a0@(GCW_LG4) movel #0x66,a0@(GCW_CMD) movel a6@(8),a0@(GCW_PX) | x movel d4,a0@(GCW_PY) | y movel a0@(GCR_IN_SM),d0 | read intensity, start single mem cycle movel a0@(GCR_IN_SM),d0 movel d0,d1 moveq #0,d0 notb d0 | d0 = 0xff asll d3,d0 | << fs andl d1,d0 | (ic & (0xff << fs) asrl d3,d0 | >> ys andl #0xff,d0 moveml sp@+,d1-d5/a0 unlk a6 rts| read a rectangular array of pixels from the screen| void rd_rect(int x1, int y1, int x2, int y2, char *buf) .even.globl rd_rect2rd_rect2: link a6,#0 moveml d1-d7/a0-a1,sp@- movel #1023,d7 subl a6@(20),d7 | d7 is y2 as 16-bit value movel d7,a6@(20) movel #1023,d6 subl a6@(12),d6 | d6 is y1 as 16-bit value movel d6,a6@(12) movel a6@(8),d5 | d5 is x lea GC_BASE,a0 | base of video control registers movel a6@(24),a1 | bufrd_rect2_1: cmpw a6@(18),d5 | x < x2 jlt rd_rect2_2 jra rd_rect2_8rd_rect2_2: movel d5,d4 | d4 is xs divuw #20,d4 | x % 20 clrw d4 | clear quotient swap d4 | remainder in lower word divuw #5,d4 | (x % 20) / 5 aslw #3,d4 | ((x % 20) / 5) << 3rd_rect2_3: cmpw d7,d6 | y > y2 jgt rd_rect2_4 jra rd_rect2_7rd_rect2_4: movel d6,d3 | d3 is y0 andib #0xfc,d3 | y & 0xfffc moveq #3,d0 andw d6,d0 | y & 3 moveq #3,d2 | ensure top word is clear subw d0,d2 | 3 - (y & 3) aslw #3,d2 | << 3 addw d4,d2 | ys in d2 moveq #24,d0 cmpw d2,d0 jge rd_rect2_5 movew #-32,d0 addw d0,d2rd_rect2_5: movel #0xff,a0@(GCW_PSEL) | plane select mask movel #0x07,a0@(GCW_LG4) movel #0x66,a0@(GCW_CMD) movel d5,a0@(GCW_PX) | x movel d3,a0@(GCW_PY) | y0 movel a0@(GCR_IN_SM),d1 | read intensity, start single mem cycle movel a0@(GCR_IN_SM),d1 moveq #0,d0 notb d0 | d0 = 0xff asll d2,d0 | << fs andl d1,d0 | (ic & (0xff << fs) asrl d2,d0 | >> ys andl #0xff,d0 moveb d0,a1@+ | *buf++rd_rect2_6: subqw #1,d6 | y-- jra rd_rect2_3rd_rect2_7: addqw #1,d5 | x++ movel a6@(12),d6 | y = y1 jra rd_rect2_1rd_rect2_8: moveml sp@+,d1-d7/a0-a1 unlk a6 rts| write a rectangular array of pixels to the screen| void wr_rect(int x1, int y1, int x2, int y2, char *buf) .even.globl wr_rect2wr_rect2: link a6,#0 moveml d1-d7/a0-a1,sp@- movel #1023,d7 subl a6@(20),d7 | d7 is y2 as 16-bit value movel d7,a6@(20) movel #1023,d6 subl a6@(12),d6 | d6 is y1 as 16-bit value movel d6,a6@(12) movel a6@(8),d5 | d5 is x lea GC_BASE,a0 | base of video control registers movel a6@(24),a1 | bufwr_rect2_1: cmpw a6@(18),d5 | x < x2 jlt wr_rect2_2 jra wr_rect2_8wr_rect2_2: movel d5,d4 | d4 is xs divuw #20,d4 | x % 20 clrw d4 | clear quotient swap d4 | remainder in lower word divuw #5,d4 | (x % 20) / 5 aslw #3,d4 | ((x % 20) / 5) << 3wr_rect2_3: cmpw d7,d6 | y > y2 jgt wr_rect2_4 jra wr_rect2_7wr_rect2_4: movel d6,d3 | d3 is y0 andib #0xfc,d3 | y & 0xfffc movel #0xff,a0@(GCW_PSEL) | plane select mask movel #0x07,a0@(GCW_LG4) movel #0x66,a0@(GCW_CMD) movel d5,a0@(GCW_PX) | x movel d3,a0@(GCW_PY) | y0 movel a0@(GCR_IN_SM),d1 | read intensity, start single mem cycle movel a0@(GCR_IN_SM),d1 | d1 is ic moveq #3,d0 andw d6,d0 | y & 3 moveq #3,d2 | ensure top word is clear subw d0,d2 | 3 - (y & 3) aslw #3,d2 | << 3 addw d4,d2 | ys in d2 moveq #24,d0 cmpw d2,d0 jge wr_rect2_5 movew #-32,d0 addw d0,d2wr_rect2_5: moveq #0,d0 notb d0 | d0 = 0xff asll d2,d0 | <<fs notl d0 | invert andl d1,d0 | (ic & (0cff << ys)) clrl d1 moveb a1@+,d1 | *buf++ asll d2,d1 | << ys orl d1,d0 movel #0xff,a0@(GCW_PSEL) | plane select mask movel #0x07,a0@(GCW_LG4) movel #0x6e,a0@(GCW_CMD) movel d5,a0@(GCW_PX) | x movel d3,a0@(GCW_PY) | y0 movel d0,a0@(GCW_IN_SM) | write inten, start single mem cyclewr_rect2_6: subqw #1,d6 | y-- jra wr_rect2_3wr_rect2_7: addqw #1,d5 | x++ movel a6@(12),d6 | y = y1 jra wr_rect2_1wr_rect2_8: moveml sp@+,d1-d7/a0-a1 unlk a6 rts| write a rectangular array of pixels to the screen| void wr_rect4(int x1, int y1, int x2, int y2, char *buf)|| This version writes the block with the x axis as the inner loop,| this is slower than wr_rect2() but is necessary for the VNC| CopyDataToScreen() function. .even.globl wr_rect4wr_rect4: link a6,#0 moveml d1-d7/a0-a1,sp@- movel #1023,d7 subl a6@(20),d7 | d7 is y2 as 16-bit value movel d7,a6@(20) movel #1023,d6 subl a6@(12),d6 | d6 is y1 as 16-bit value movel d6,a6@(12) movel a6@(8),d5 | d5 is x lea GC_BASE,a0 | base of video control registers movel a6@(24),a1 | bufwr_rect4_1: cmpw d7,d6 | y > y2 jgt wr_rect4_2 jra wr_rect4_8wr_rect4_2: movel d6,d3 | d3 is y0 andib #0xfc,d3 | y & 0xfffc moveq #3,d0 andw d6,d0 | y & 3 moveq #3,d2 | ensure top word is clear subw d0,d2 | 3 - (y & 3) aslw #3,d2 | << 3wr_rect4_3: cmpw a6@(18),d5 | x < x2 jlt wr_rect4_4 jra wr_rect4_7wr_rect4_4: movel #0xff,a0@(GCW_PSEL) | plane select mask movel #0x07,a0@(GCW_LG4) movel #0x66,a0@(GCW_CMD) movel d5,a0@(GCW_PX) | x movel d3,a0@(GCW_PY) | y0 movel a0@(GCR_IN_SM),d1 | read intensity, start single mem cycle movel a0@(GCR_IN_SM),d1 | d1 is ic movel d5,d4 | d4 is xs divuw #20,d4 | x % 20 clrw d4 | clear quotient swap d4 | remainder in lower word divuw #5,d4 | (x % 20) / 5 aslw #3,d4 | ((x % 20) / 5) << 3 addw d2,d4 | ys in d2, xs in d4 moveq #24,d0 cmpw d4,d0 jge wr_rect4_5 movew #-32,d0 addw d0,d4wr_rect4_5: moveq #0,d0 notb d0 | d0 = 0xff asll d4,d0 | <<fs notl d0 | invert andl d1,d0 | (ic & (0cff << ys)) clrl d1 moveb a1@+,d1 | *buf++ asll d4,d1 | << ys orl d1,d0 movel #0xff,a0@(GCW_PSEL) | plane select mask movel #0x07,a0@(GCW_LG4) movel #0x6e,a0@(GCW_CMD) movel d5,a0@(GCW_PX) | x movel d3,a0@(GCW_PY) | y0 movel d0,a0@(GCW_IN_SM) | write inten, start single mem cyclewr_rect4_6: addqw #1,d5 | x++ jra wr_rect4_3wr_rect4_7: subqw #1,d6 | y-- movel a6@(8),d5 | x = x1 jra wr_rect4_1wr_rect4_8: moveml sp@+,d1-d7/a0-a1 unlk a6 rts| write a rectangular array of pixels to the screen| void wr_rect5(int x1, int y1, int x2, int y2, char *buf)|| This version writes the block with the x axis as the inner loop,| this is slower than wr_rect2() but is necessary for the VNC| CopyDataToScreen() function.|| This version uses a lookup table for the pixel mask and shift count.| This removes one of the divide instructions (divides are slow). .even.globl wr_rect5wr_rect5: link a6,#0 moveml d1-d7/a0-a2,sp@- movel #1023,d7 subl a6@(20),d7 | d7 is y2 movel #1023,d6 subl a6@(12),d6 | d6 is y1 movel a6@(8),d5 | d5 is x lea GC_BASE,a0 | base of video control registers movel a6@(24),a1 | buf lea pm_tab,a2 | base of lookup table movel #0xff,a0@(GCW_PSEL) | plane select maskwr_rect5_1: cmpl d7,d6 | y > y2 jle wr_rect5_8 movel d6,d3 | d3 is y0 andib #0xfc,d3 | y & 0xfffc moveq #3,d2 andl d6,d2 | y & 3 asll #3,d2 | (y & 3) * 8wr_rect5_3: cmpl a6@(16),d5 | x < x2 jge wr_rect5_7 movel #0x07,a0@(GCW_LG4) movel #0x66,a0@(GCW_CMD) movel d5,a0@(GCW_PX) | x movel d3,a0@(GCW_PY) | y0 movel a0@(GCR_IN_SM),d1 | read intensity, start single mem cycle movel a0@(GCR_IN_SM),d1 | d1 is ic movel d5,d4 | d4 is xs divuw #20,d4 | x % 20 clrw d4 | clear quotient swap d4 | remainder in lower word asll #5,d4 | *32 addl d2,d4 | ((x % 20) * 32) + ((y % 4) * 8) movel a2@(d4:w:1),d0 | fetch mask andl d1,d0 | (ic & mask)| andl a2@(d4:w:1),d0 | (ic & mask) clrl d1 moveb a1@+,d1 | *buf++ addql #4,d4 movel a2@(d4:w:1),d4 | fetch shift count asll d4,d1 | << ys orl d1,d0 movel #0x07,a0@(GCW_LG4) movel #0x6e,a0@(GCW_CMD) movel d5,a0@(GCW_PX) | x movel d3,a0@(GCW_PY) | y0 movel d0,a0@(GCW_IN_SM) | write inten, start single mem cyclewr_rect5_6: addql #1,d5 | x++ jra wr_rect5_3wr_rect5_7: subql #1,d6 | y-- movel a6@(8),d5 | x = x1 jra wr_rect5_1wr_rect5_8: moveml sp@+,d1-d7/a0-a2 unlk a6 rts| write 1 pixel to the screen, handle the bizarre layout .even.globl w1pix3w1pix3: link a6,#0 moveml d1-d5/a0,sp@- movew #1023,d5 subw a6@(14),d5 | d5 is y as 16-bit value movew d5,d4 andib #0xfc,d4 | d4 is y0 lea GC_BASE,a0 | base of video control registers movel a6@(16),a0@(GCW_PSEL) | plane select mask movel #0x07,a0@(GCW_LG4) movel #0x66,a0@(GCW_CMD) movel a6@(8),a0@(GCW_PX) | x movel d4,a0@(GCW_PY) | y0 movel a0@(GCR_IN_SM),d0 | read intensity, start single mem cycle movel a0@(GCR_IN_SM),d0 | 4 pixels in d0 movel d0,d3 | ic in d3 movew #3,d0 andw d5,d0 | y & 3 movel #3,d2 | ensure top word is clear subw d0,d2 | 3 - (y & 3) aslw #3,d2 | << 3 movel a6@(8),d0 | x divuw #20,d0 | x % 20 clrw d0 | clear quotient swap d0 | put remainder in lower 16 bits divuw #5,d0 | (x % 20) / 5 aslw #3,d0 | << 3 addw d0,d2 | ys in d2 movew #24,d0 cmpw d2,d0 jge w1pix3_1 movew #-32,d0 addw d0,d2w1pix3_1: moveq #0,d0 notb d0 | d0 = 0xff asll d2,d0 | << ys notl d0 | invert andl d3,d0 | (ic & (0xff << ys) movel a6@(20),d1 | i asll d2,d1 | i << ys orl d1,d0 movel a6@(16),a0@(GCW_PSEL) | plane select mask movel #0x07,a0@(GCW_LG4) movel #0x6e,a0@(GCW_CMD) movel a6@(8),a0@(GCW_PX) | x movel d4,a0@(GCW_PY) | y0 movel d0,a0@(GCW_IN_SM) | write inten, start single mem cycle moveml sp@+,d1-d5/a0 unlk a6 rts| data .data| lookup table for wr_rect5()| this gives the pixel mask and shift count to locate each pixel in | the 4 x 20 array pattern used by the Prisma video boardpm_tab: .long 0x00ffffff, 24 | 0,0 .long 0xff00ffff, 16 | 0,1 .long 0xffff00ff, 8 | 0,2 .long 0xffffff00, 0 | 0,3 .long 0x00ffffff, 24 | 1,0 .long 0xff00ffff, 16 | 1,1 .long 0xffff00ff, 8 | 1,2 .long 0xffffff00, 0 | 1,3 .long 0x00ffffff, 24 | 2,0 .long 0xff00ffff, 16 | 2,1 .long 0xffff00ff, 8 | 2,2 .long 0xffffff00, 0 | 2,3 .long 0x00ffffff, 24 | 3,0 .long 0xff00ffff, 16 | 3,1 .long 0xffff00ff, 8 | 3,2 .long 0xffffff00, 0 | 3,3 .long 0x00ffffff, 24 | 4,0 .long 0xff00ffff, 16 | 4,1 .long 0xffff00ff, 8 | 4,2 .long 0xffffff00, 0 | 4,3 .long 0xffffff00, 0 | 5,0 .long 0x00ffffff, 24 | 5,1 .long 0xff00ffff, 16 | 5,2 .long 0xffff00ff, 8 | 5,3 .long 0xffffff00, 0 | 6,0 .long 0x00ffffff, 24 | 6,1 .long 0xff00ffff, 16 | 6,2 .long 0xffff00ff, 8 | 6,3 .long 0xffffff00, 0 | 7,0 .long 0x00ffffff, 24 | 7,1 .long 0xff00ffff, 16 | 7,2 .long 0xffff00ff, 8 | 7,3 .long 0xffffff00, 0 | 8,0 .long 0x00ffffff, 24 | 8,1 .long 0xff00ffff, 16 | 8,2 .long 0xffff00ff, 8 | 8,3 .long 0xffffff00, 0 | 9,0 .long 0x00ffffff, 24 | 9,1 .long 0xff00ffff, 16 | 9,2 .long 0xffff00ff, 8 | 9,3 .long 0xffff00ff, 8 | 10,0 .long 0xffffff00, 0 | 10,1 .long 0x00ffffff, 24 | 10,2 .long 0xff00ffff, 16 | 10,3 .long 0xffff00ff, 8 | 11,0 .long 0xffffff00, 0 | 11,1 .long 0x00ffffff, 24 | 11,2 .long 0xff00ffff, 16 | 11,3 .long 0xffff00ff, 8 | 12,0 .long 0xffffff00, 0 | 12,1 .long 0x00ffffff, 24 | 12,2 .long 0xff00ffff, 16 | 12,3 .long 0xffff00ff, 8 | 13,0 .long 0xffffff00, 0 | 13,1 .long 0x00ffffff, 24 | 13,2 .long 0xff00ffff, 16 | 13,3 .long 0xffff00ff, 8 | 14,0 .long 0xffffff00, 0 | 14,1 .long 0x00ffffff, 24 | 14,2 .long 0xff00ffff, 16 | 14,3 .long 0xff00ffff, 16 | 15,0 .long 0xffff00ff, 8 | 15,1 .long 0xffffff00, 0 | 15,2 .long 0x00ffffff, 24 | 15,3 .long 0xff00ffff, 16 | 16,0 .long 0xffff00ff, 8 | 16,1 .long 0xffffff00, 0 | 16,2 .long 0x00ffffff, 24 | 16,3 .long 0xff00ffff, 16 | 17,0 .long 0xffff00ff, 8 | 17,1 .long 0xffffff00, 0 | 17,2 .long 0x00ffffff, 24 | 17,3 .long 0xff00ffff, 16 | 18,0 .long 0xffff00ff, 8 | 18,1 .long 0xffffff00, 0 | 18,2 .long 0x00ffffff, 24 | 18,3 .long 0xff00ffff, 16 | 19,0 .long 0xffff00ff, 8 | 19,1 .long 0xffffff00, 0 | 19,2 .long 0x00ffffff, 24 | 19,3| temporary storage for line drawing routinegr_data:line_x1: .long 0 | 0 (668)line_y1: .long 0 | 4 (66c)line_x2: .long 0 | 8 (670)line_y2: .long 0 | 12 (674) .long 0 | 16 (678) .long 0 | 20 (67c) .long 0 | 24 (680) .long 0 | 28 (684) .long 0 | 32 (688) .long 0 | 36 (68c)line_xdir: .long 0 | 40 (690)line_ydir: .long 0 | 44 (694) .long 0 | 48 (698)line_selmask: .long 0 | 52 (69c)line_inten: .long 0 | 56 (6A0)line_flag: .word 0 | 60 (6a4)init_flag1: .word 0 | 62 (6a6) .long 0 | 64 (6a8) .long 0 | 64 (6ac)init_flag4: .long 0 | 64 (6b0) .long 0 | 64 (6b4) .long 0 | 64 (6b8) .long 0 | 64 (6bc) .long 0 | 64 (6c0) .long 0 | 64 (6c4) .long 0 | 64 (6c8) .long 0 | 64 (6cc) .long 0 | 64 (6d0) .long 0 | 64 (6d4) .long 0 | 64 (6d8) .long 0 | 64 (6dc) .long 0 | 64 (6e0) .long 0 | 64 (6e4) .long 0 | 64 (6e8) .long 0 | 64 (6ec)init_flag6: .long 0 | 64 (6f0)init_flag5: .word 0 | 64 (6f4)init_flag2: .word 0 | 64 (6f6)init_flag3: .word 0 | 64 (6f8)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -