📄 lcd.asm
字号:
// GOTO ?_Lcd_Line_End
//?_Lcd_Line44: //说明写入页数>1
// R1 = maskcode //写入第一页
// R1 += [k]
// R1 = [R1]
// [mask] = R1
// R1 = [y]
// R1 = R1 LSR 3
// R2 = [x]
// R3 = mask
// R4 = 1
// CALL __LcdPageWriteWord //调用页写入程序
// R1 = [ysize]
// R1 -= 8
// R1 += [k]
// [ysize] = R1
// R1 = [y]
// R1 += 8
// [y] = R1
//?_Lcd_Line43: //从页起始开始
// R1 = [ysize]
// CMP R1,0x08
// JNB ?_Lcd_Line46
// GOTO ?_Lcd_Line47
//?_Lcd_Line46:
// R1 = 0xFF
// [mask] = R1
// R1 = [y]
// R1 = R1 LSR 3 //得到页码
// R2 = [x]
// R3 = mask
// R4 = 1
// CALL __LcdPageWriteWord //调用页写入程序
// R1 = [ysize]
// R1 -= 8
// [ysize] = R1
// R1 = [y]
// R1 += 8
// [y] = R1
// JMP ?_Lcd_Line43
//?_Lcd_Line47:
// R1 = [ysize]
// CMP R1,C_Null
// JNE ?_Lcd_Line48
// GOTO ?_Lcd_Line_End //行列值都不等,返回失败
//?_Lcd_Line48: //写入最后一页
// R1 = maskcode
// R1 += [ysize]
// R1 = [R1]
// R1 = R1 XOR 0xFFFF
// R1 &= 0xFF //mask为低ysize位为1
// [mask] = R1
// R1 = [y]
// R1 = R1 LSR 3
// R2 =[x]
// R3 = mask
// R4 = 1
// CALL __LcdPageWriteWord //调用页写入程序
// GOTO ?_Lcd_Line_End
//?_Lcd_Line5: //判断是否是画横线
// R1 = [y]
// CMP R1,[y1]
// JE ?_Lcd_Line51
// GOTO ?_Lcd_Line_End //行列值都不等,返回失败
//?_Lcd_Line51:
// R1 &= 0x07 //画水平线
// [k] = R1
// CMP R1,C_Null
// JNE ?_Lcd_Line53
// R3 = 0x01
// [mask] = R3
// JMP ?_Lcd_Line54
//?_Lcd_Line53:
// R3 = 0x01
// R5 = [k]
// CALL _LCDShiftL //0x01左移K位
// [mask] = R3 //得到屏蔽码
//?_Lcd_Line54:
// R1 = [x]
// CMP R1,[x1]
// JNA ?_Lcd_Line52
// R2 = [x1] //令[x] <[x1]
// [x1] = R1
// [x] = R2
//?_Lcd_Line52:
// R1 = [y]
// R1 = R1 LSR 3 //得到页值
// R2 = [x] //得到列值
// R3 = mask
// R4 = 1
// CALL __LcdPageWriteWord //调用页写入程序
// R2 =[x]
// R2 += 1
// [x] = R2
// CMP R2,[x1]
// JNE ?_Lcd_Line52
//?_Lcd_Line_End:
// POP R1,R5 FROM [SP]
// RETF
//----------------------------------------------------------//
//名称:F_Lcd_Track
//功能:画任意角度的线,包括横线或竖线
//入口:模式R_LcdStatus,起始坐标R_LcdStartDot(x,y),终止坐标R_LcdEndDot(x,y)
//出口:无
//影响寄存器:无
//存在问题:没有xy同时加1的情况,所以45度时会出现双线
//----------------------------------------------------------//
.public F_Lcd_Track
F_Lcd_Track:
PUSH R1,R5 TO [SP]
R1 = [R_LcdStartDot]
CMP R1,[R_LcdEndDot]
JNE ?_Lcd_track_0
GOTO ?_Lcd_track_End
?_Lcd_track_0:
R1 = C_False
[chanxy] = R1 //xy坐标没有与换
?_Lcd_track:
CALL _Cal_Dot_Correct //用到R1 R2寄存器
R2 = [chanxy]
CMP R2,C_True
JE ?_Lcd_track1
CMP R1,C_False
JNE ?_Lcd_track1
GOTO ?_Lcd_track_End //坐标不符合要求则退出
?_Lcd_track1:
R1 = 1
[stepx] = R1
[stepy] = R1
R1 = [x1]
R1 -= [x] //dx
[dx] = R1
CMP R1,0x8000
JNA ?_Lcd_track2
R1 = [x] //x1 < x
R1 -= [x1] //得到dx的绝对值
[dx] = R1
R2 = -1
[stepx] = R2 //
?_Lcd_track2:
R2 = [y1]
R2 -= [y] //dy
[dy] = R2
CMP R2,0x8000
JNA ?_Lcd_track3
R2 = [y]
R2 -= [y1]
[dy] = R2
R3 = -1
[stepy] = R3 //得到stepy
?_Lcd_track3:
CMP R1,R2 //R1==dx; R2 ==dy
JNB ?_Lcd_track4
R1 = [R_LcdStartDot] //xy互换
R2 = R1 LSR 4
R2 = R2 LSR 4
R1 = R1 LSL 4
R1 = R1 LSL 4
R1 |= R2 //高低字节互换
[R_LcdStartDot] = R1
R1 = [R_LcdEndDot] //xy互换
R2 = R1 LSR 4
R2 = R2 LSR 4
R1 = R1 LSL 4
R1 = R1 LSL 4
R1 |= R2 //高低字节互换
[R_LcdEndDot] = R1
R1 = C_True
[chanxy] = R1 //xy坐标与换过
GOTO ?_Lcd_track
?_Lcd_track4: //dx>dy
R1 = [stepx]
CMP R1,0x8000
JNA ?_Lcd_track5
R4 = [R_LcdStartDot]
R4 += 1 //起点包括终点不包括
R5 = [R_LcdEndDot]
R5 += 1 //
[R_LcdStartDot] = R5 //起点与终点与换
[R_LcdEndDot] = R4
GOTO ?_Lcd_track
?_Lcd_track5: //画线
R1 = -[dx]
[e] = R1 //得到判断标志
R1 = [dy]
R1 = R1 LSL 1 //得到2dy
[dy] = R1
R1 = [dx]
R1 = R1 LSL 1 //得到2dx
[dx] = R1
?_Lcd_track7: //画线开始
R1 = [x]
R2 = [y] //保护xy值
R3 = [chanxy]
CMP R3,C_True
JNE ?_Lcd_track6
[y] = R1
[x] = R2 //xy坐标互换
?_Lcd_track6:
CALL _Lcd_PutPixul
R1 += 1
[x] = R1 //得到原x坐标,并加1
[y] = R2 //重新得到原xy值
R1 = [e]
R1 += [dy]
[e] = R1 //e = e+ 2 * dy
CMP R1,0x8000
JA ?_Lcd_track8
R1 = [y] //e>=0 ,y同时变化
R1 += [stepy]
[y] = R1
R1 = [e]
R1 -= [dx]
[e] = R1
?_Lcd_track8:
R1 = [x]
CMP R1,[x1]
JE ?_Lcd_track_End
GOTO ?_Lcd_track7
?_Lcd_track_End:
POP R1,R5 FROM [SP] //结束
RETF
//----------------------------------------------------------//
//名称:F_Lcd_Rectangle
//功能:画矩形
//入口:模式R_LcdStatus,起始坐标R_LcdStartDot(x,y),终止坐标R_LcdEndDot(x,y)
//出口:无
//影响寄存器:无
//--------------------------------------------------------//
.public F_Lcd_Rectangle
F_Lcd_Rectangle:
PUSH R1,R5 TO [SP]
R1 = [R_LcdStartDot]
R2 = R1 LSR 4
R2 = R2 LSR 4
R2 &= 0xFF
[y0] = R2
R1 &= 0xFF
[x0] = R1
R1 = [R_LcdEndDot]
R2 = R1 LSR 4
R2 = R2 LSR 4
R2 &= 0xFF
[y2] = R2
R1 &= 0xFF
[x2] = R1 //得到x0 y0 x2 y2
R2 = [y0]
R2 = R2 LSL 4
R2 = R2 LSL 4
R2 |= R1 //R2= [y0 x2]
[R_LcdEndDot] = R2
CALL F_Lcd_Track //画(y0 x0)--(y0 x2 )的水平线
R1 = [x0]
R2 = [y2]
R2 = R2 LSL 4
R2 = R2 LSL 4
R2 |= R1
[R_LcdEndDot] = R2
CALL F_Lcd_Track //画(y0 x0)--(y2 x0 )的竖线
R2 = [R_LcdEndDot]
R2 -= 0x100
[R_LcdEndDot] = R2 //不包括Y2和X2两边的直线
R1 = [x2]
R2 = [y2]
R2 -= 1
R2 = R2 LSL 4
R2 = R2 Lsl 4
R2 |= R1
[R_LcdStartDot] = R2
CALL F_Lcd_Track //画(y2 x0)--(y2 x2 )的竖线
R1 = [R_LcdStartDot]
R1 -= 1
[R_LcdStartDot] = R1
R1 = [x2]
R1 -= 1
R2 = [y0]
R2 = R2 LSL 4
R2 = R2 Lsl 4
R2 |= R1
[R_LcdEndDot] = R2
CALL F_Lcd_Track //画(y2 x2)--(y0 x2 )的竖线
POP R1,R5 FROM [SP]
RETF
//----------------------------------------------------------//
//名称:F_Lcd_Block
//功能:块操作,对某一区块进行清除、覆盖、或、异或操作
//入口:模式R_LcdStatus,起始坐标R_LcdStartDot(x,y),终止坐标R_LcdEndDot(x,y)
// 灰度R_LcdGray(只对模式1有效)
//出口:无
//影响寄存器:无
//--------------------------------------------------------//
.public F_Lcd_Block
F_Lcd_Block:
PUSH R1,R5 TO [SP]
CALL _Cal_Dot_Correct //判断起终坐标是否符合要求
CMP R1,C_True
JE ?_Lcd_Block_0
GOTO ?_Lcd_Block_End
?_Lcd_Block_0:
R1 = [R_LcdStartDot] //判断起始点与终止点
R2 = [R_LcdEndDot] //起点必须小于终点
CMP R1,R2
JB ?_Lcd_Block_1
GOTO ?_Lcd_Block_End
?_Lcd_Block_1:
R1 =[y] //判断行值是否相同
CMP R1,[y1]
JNE ?_Lcd_Block_2
CALL F_Lcd_Track //画线
GOTO ?_Lcd_Block_End
?_Lcd_Block_2:
R1 = [x] //判断列值是否相同
CMP R1,[x1]
JNE ?_Lcd_Block_3
CALL F_Lcd_Track //画线
GOTO ?_Lcd_Block_End
?_Lcd_Block_3:
CMP R1,[x1] //比较起点与终点X坐标
JB ?_Lcd_Block_4
GOTO ?_Lcd_Block_End
?_Lcd_Block_4:
R4 = [y1]
R3 = [y]
CMP R4,R3 //比较起点与终点X坐标
JA ?_Lcd_Block_5
GOTO ?_Lcd_Block_End
?_Lcd_Block_5:
R4 -= R3
[ysize] = R4
CALL _CAL_maskcode //初始化maskcode值 8word
R3 = [y]
R3 &= 0x03 //取低三位
[k] = R3 //得到页内偏移量
CMP R3,C_Null
JNE ?_Lcd_Block_Page
GOTO ?_Lcd_Block_WholePage
?_Lcd_Block_Page:
R4 = R4 + R3 //R4 = k = ysize
CMP R4,4 //看是否满一页
JA ?_Lcd_Block_FirstPage
GOTO ?_Lcd_Block_JustOnePage
?_Lcd_Block_FirstPage: //firstpage 高[8-k]位有效
R4 = maskcode //说明只需两页显示
R4 += [k] //显示第一页
R4 =[R4] //读取maskcode码
r1 = r4
call F_LCDData_Change
r4 = r1
[mask] = R4 //保存屏蔽码
?_Lcd_Block_FirstPage1:
R3 = 0xFF //取要显示的字
[LcdBuffer] = R3
R1 = [y]
R1 = R1 LSR 2 //得到写入页值
R2 = [x] //得到写入列值
R3 = LcdBuffer
R4 = 1 //写入长度为1个字节
CALL __LcdPageWrite //调用页写入程序
R3 = [x]
R3 += 1
[x] = R3
CMP R3,[x1]
JNE ?_Lcd_Block_FirstPage1
R3 = [y]
R3 &= 0xfc
R3 += 4 //[y]换到下一页起始位置
[y] = R3
R3 = [ysize]
R3 = R3 -4
R3 += [k]
[ysize] = R3 //计算还要写的行值
R3 = [R_LcdStartDot]
R3 &= 0xFF //得到x0指针
[x] = R3
?_Lcd_Block_MiddlePage:
R1 = 0xff
CALL F_LCDData_Change
R3 = R1
[mask] = R3 //
R3 = [ysize]
CMP R3 ,4 //看是否还要写一满页?
JB ?_Lcd_Block_LastPage
?_Lcd_Block_MiddlePage1:
R3 = 0xFF
[LcdBuffer] = R3
R1 = [y]
R1 = R1 LSR 2 //得到写入页值
R2 = [x] //得到写入列值
R3 = LcdBuffer
R4 = 1 //写入长度为1个字节
CALL __LcdPageWrite //调用页写入程序
R3 = [x] //向下移一个字
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -