📄 writeout.asm
字号:
/******************************************************************
** 文件名:writeout.asm
** Copyright (c) 1998-1999 *********公司技术开发部
** 创建人:
** 日 期:2003.01.29
** 修改人:
** 日 期:2003.05.26
** 描 述: 输出的汇编子程序,分别用于将水平线、点、旋转后的点
画到屏幕上。
** 版 本:
**--------------------------------------------------------------------------*/
#include "hddamacros.h"
#include "def21160.h"
#include <asm_sprt.h>
//用到的全局变量
.extern _g_nNumOfRotatedResult;
.extern _g_nNumOfResult;
.extern _g_nNumOfHorizontalLine;
.extern _g_nRotatedResult;
.extern _g_nResult;
.extern _g_nHorizontalLine;
.extern _g_pCurrentBufferOutput;
/*****************************************************************
** 函数名:_asm_showresult
** 输 入: 无
** 输 出: 无
** 功能描述:把未经旋转的点输出到外部帧缓冲区
** 调用模块:无
** 全局变量:_g_nNumOfResult
** 作 者:
** 日 期:2003.01.29
** 修改人:
** 日 期:2003.08.10
** 版 本:
****************************************************************/
.SECTION/PM seg_pmco;
.GLOBAL _asm_showresult;
_asm_showresult:
entry;
save_reg;
//取得要输出的点数,并判断是否大于零,若否,则返回。
r15=pm(_g_nNumOfResult);
r15=pass r15;
if le jump _showresult_end;
//取得结果缓冲区的地址减1放入i4,减1是因为需要先读入缓冲区中第二个数
i4=_g_nResult-1;
m4=-2;
//将帧缓冲区的地址放入i0
i0=dm(_g_pCurrentBufferOutput);m0=0;
r10=0xffff0000;r11=0x0000ffff;
r2=0;
r13=r13-r13;r14=WIDTHIN;
//读入y坐标
r1=dm(i4,m6);
lcntr=r15,do _showresult_loop0 until lce;
//计算行首地址,读入x坐标
r1=r1*r14(ssi),r0=dm(i4,m4);
//行首地址加x坐标得到该点在帧存中的位置,并将结果送到目标单元中
r3=r0+r1,dm(m0,i0)=r2;
//将目标单元地址向偶地址对齐,并读入颜色值
r3=bclr r3 by r13,r4=dm(i4,m4);
m0=r3;
//读入目标单元中原有的值
btst r0 by r13,r2=dm(m0,i0);
//如果x坐标是偶数将颜色值复制到目标单元的低16位
if sz jump (pc,_showresult_loop0),r3=r2 and r10;
//R3是目标单元需保留下来的部分
R3=r2 and r11;
//如果x坐标是奇数将颜色值复制到目标单元的高16位
r4=lshift r4 by 16;
_showresult_loop0:
//读入下一点的y坐标
r2=r3 or r4,r1=dm(i4,m6);
//将结果送到目标单元中
dm(m0,i0)=r2;
_showresult_end:
restore_reg;
exit;
_asm_showresult.end:
/*****************************************************************
** 函数名:_asm_showrotatedresult
** 输 入: 无
** 输 出: 无
** 功能描述:把偶场的旋转过的点输出到外部帧缓冲区
** 调用模块:无
** 全局变量:_g_nNumOfRotatedResult
** 作 者:
** 日 期:2003.01.29
** 修改人:
** 日 期:2003.05.26
** 版 本:
****************************************************************/
.SECTION/PM seg_pmco;
.GLOBAL _asm_showrotatedresult;
_asm_showrotatedresult:
entry;
save_reg;
//判断要输出的点的个数是否有效
r0=dm(_g_nNumOfRotatedResult);
r0=pass r0;
if le jump _showrotatedresult_end;
// i4=dm(_g_pCurrentBufferOutput);i0=dm(_g_pCurrentBufferOutput)+WIDTHIN;
// i3=dm(_g_pCurrentBufferOutput)+2;i1=dm(_g_pCurrentBufferOutput)+2+WIDTHIN;
//i4指向帧缓存中第0行第0个32位值
//i3指向帧缓存中第0行第1个32位值
//i0指向帧缓存中第1行第0个32位值
//i1指向帧缓存中第1行第1个32位值
i4=dm(_g_pCurrentBufferOutput);
i3=i4;
m4=2;
modify(i3,m4);
i0=i4;
i1=i3;
m4=WIDTHIN;
modify(i0,m4);
modify(i1,m4);
i12=_g_nRotatedResult+1;
m12=3;
r15=0;
r14=WIDTHIN;
r7=0x1f;
r8=0xffff0000;s8=r8;
//读入y坐标
r1=pm(i12,m15);
lcntr=r0,do _showrotatedresult_loop0 until lce;
//计算行首地址,读入x坐标
r5=r1*r14(ssi),r0=pm(i12,2);
//读入颜色值
r4=pm(i12,1);
//行首地址加x坐标得到目标点在帧存中的位置
r5=r5+r0;
r5=bclr r5 by r15;
//测试是否偶列,根据x坐标的奇偶性进入不同的分支
btst r0 by r15,m4=r5;
if not sz jump (pc,_showrotatedresult_oddrow0)(db);
//读入目标单元中原有的值
r5=dm(m4,i4);
s4=r4;
s5=dm(m4,i0);
bit set mode1 PEYEN;nop;
//对左边的点进行处理
//B
r10=fext r4 by 0:5;
r0=fext r5 by 0:5;
r1=r10-r0,r2=pm(i12,1);
r1=r1*r2(ssi),r3=pm(i12,4);
r1=ashift r1 by -8;
r13=r1+r0;
//R
r0=fext r5 by 5:6;
r11=fext r4 by 5:6;
r1=r11-r0;
r1=r1*r2(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r13=r13 or fdep r1 by 5:6;
//G
r0=fext r5 by 11:5;
r12=fext r4 by 11:5;
r1=r12-r0;
r1=r1*r2(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r13=r13 or fdep r1 by 11:5;
//对右边的点进行处理
//B
r0=fext r5 by 16:5;
r1=r10-r0;
r1=r1*r3(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r13=r13 or fdep r1 by 16:5;
//R
r0=fext r5 by 21:6;
r1=r11-r0;
r1=r1*r3(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r13=r13 or fdep r1 by 21:6;
//G
r0=fext r5 by 27:5;
r1=r12-r0;
r1=r1*r3(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r13=r13 or fdep r1 by 27:5;
/////////////////////////////////////////////////
bit clr mode1 PEYEN;nop;
jump (pc,_showrotatedresult_loop0)(db);
dm(m4,i4)=r13;
dm(m4,i0)=s13;
_showrotatedresult_oddrow0:
//读入目标单元中原有的值
// r6=dm(m4,i3);
// s6=dm(m4,i1);
s5=dm(m4,i0);
r10=r4 and r7,r6=dm(m4,i3);
s10=r10;s6=dm(m4,i1);
bit set mode1 PEYEN;nop;
//对右边的点进行处理
r9=r6 and r8,r2=pm(i12,1);//r8=0xffff0000
//B
r0=fext r6 by 0:5;
// r10=fext r4 by 0:5;被放到上面去了
r1=r10-r0,r3=pm(i12,4);
r1=r1*r3(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r9=r9 or r1;
//R
r0=fext r6 by 5:6;
r11=fext r4 by 5:6;
r1=r11-r0;
r1=r1*r3(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r9=r9 or fdep r1 by 5:6;
//G
r0=fext r6 by 11:5;
r12=fext r4 by 11:5;
r1=r12-r0;
r1=r1*r3(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r9=r9 or fdep r1 by 11:5;
//对左边的点进行处理
r13=fext r5 by 0:16;
//B
r0=fext r5 by 16:5;
r1=r10-r0;
r1=r1*r2(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r13=r13 or fdep r1 by 16:5;
//R
r0=fext r5 by 21:6;
r1=r11-r0;
r1=r1*r2(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r13=r13 or fdep r1 by 21:6;
//G
r0=fext r5 by 27:5;
r1=r12-r0;
r1=r1*r2(ssi);
r1=ashift r1 by -8;
r1=r1+r0;
r13=r13 or fdep r1 by 27:5;
bit clr mode1 PEYEN;nop;
dm(m4,i4)=r13;
dm(m4,i0)=s13;
//下面两条可能可与上面合并
dm(m4,i3)=r9;
dm(m4,i1)=s9;
_showrotatedresult_loop0:
//读入下一点y坐标
r1=pm(i12,m15);
_showrotatedresult_end:
restore_reg;
exit;
_asm_showrotatedresult.end:
/*****************************************************************
** 函数名:_asm_showhorizontalline
** 输 入: 无
** 输 出: 无
** 功能描述:把水平直线快速地输出到外部帧缓冲区
** 调用模块:无
** 全局变量:_g_nNumOfHorizontalLine
** 作 者:
** 日 期:2003.01.29
** 修改人:
** 日 期:2003.08.10
** 版 本:
****************************************************************/
.GLOBAL _asm_showhorizontalline;
_asm_showhorizontalline:
entry;
save_reg;
//判断要输出的点的个数是否大于零
r0=dm(_g_nNumOfHorizontalLine);
r0=pass r0;
if le jump _show_horizontalline_end;
//获取当前帧的首地址
r12=dm(_g_pCurrentBufferOutput);i2=dm(_g_pCurrentBufferOutput);
//输出数据缓冲区的地址
i4=_g_nHorizontalLine;i12=_g_nHorizontalLine+1;
r5=WIDTHIN;
r10=16;r11=1;r13=0xffff0000;r14=0x0000ffff;r15=0;
m4=2;m12=2;
//读入直线两端的x坐标
r8=dm(i4,m4),r2=pm(i12,m12);
lcntr=r0,do _show_horizontalline_loop0 until lce;
//读入直线的y坐标和颜色值
//确保直线的右端横坐标大于左端横坐标
r0=r2-r8,r3=dm(i4,m4),r4=pm(i12,m12);
if le jump(pc,_show_horizontalline_loop0),else r3=r3*r5(ssi);
//计算直线左端地址并放入i0中
r9=r8+r12;
r9=r3+r9;
r6=lshift r4 by r10;
//判断直线左端是否落在奇地址
btst r8 by r15,i0=r9;
if sz jump (pc,_show_horizontalline_jump0),btst r2 by r15;
//如果直线左端落在奇地址
//i0=i0-1对齐到偶地址
r8=r8+1,r0=dm(m7,i0);
//将r0高位中无用的一个象素点的数据清零
r0=r0 and r14,modify(i0,m7);
//将颜色值写到r0高位
r0=r0 or r6;
//输出r0
btst r2 by r15,dm(i0,m4)=r0;
_show_horizontalline_jump0:
//判断直线右端是否落在偶地址
if not sz jump (pc,_show_horizontalline_jump1),r0=r2-r8;
//如果直线右端落在偶地址
r9=r3+r2;
r2=r2-1,m0=r9;
r0=dm(m0,i2);
r0=r0 and r13;
r0=r0 or r4;
r0=r2-r8,dm(m0,i2)=r0;
_show_horizontalline_jump1:
//判断左右两点分别向奇偶地址对齐后直线长度是否大于0
if le jump(pc,_show_horizontalline_loop0),else r6=r4 or r6;
//循环次数是直线长度加一的一半
r0=(r0+r11)/2;
lcntr=r0,do _show_horizontalline_loop1 until lce;
_show_horizontalline_loop1:
dm(i0,m4)=r6;
_show_horizontalline_loop0:
//读入直线两端的x坐标
r8=dm(i4,m4),r2=pm(i12,m12);
_show_horizontalline_end:
restore_reg;
exit;
_asm_showhorizontalline.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -