summaryrefslogtreecommitdiffstats
path: root/arch/arm/lib/ll_char_wr.S
blob: 966d2846e0d083a40e45eab561875db648028ca1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * linux/arch/arm/lib/ll_char_wr.S
 *
 * Copyright (C) 1995, 1996 Russell King.
 *
 * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
 *
 * 10-04-96	RMK	Various cleanups & reduced register usage.
 * 08-04-98	RMK	Shifts re-ordered
 */

@ Regs: [] = corruptible
@       {} = used
@       () = do not use

#include <linux/linkage.h>
#include <asm/assembler.h>
		.text

#define BOLD            0x01
#define ITALIC          0x02
#define UNDERLINE       0x04
#define FLASH           0x08
#define INVERSE         0x10

LC0:		.word	SYMBOL_NAME(bytes_per_char_h)
		.word	SYMBOL_NAME(video_size_row)
		.word	SYMBOL_NAME(cmap_80)
		.word	SYMBOL_NAME(con_charconvtable)

ENTRY(ll_write_char)
		stmfd	sp!, {r4 - r7, lr}
@
@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
@
		eor	ip, r1, #UNDERLINE << 9
/*
 * calculate colours
 */
		tst	r1, #INVERSE << 9
		moveq	r2, r1, lsr #16
		moveq	r3, r1, lsr #24
		movne	r2, r1, lsr #24
		movne	r3, r1, lsr #16
		and	r3, r3, #255
		and	r2, r2, #255
/*
 * calculate offset into character table
 */
		mov	r1, r1, lsl #23
		mov	r1, r1, lsr #20
/*
 * calculate offset required for each row [maybe I should make this an argument to this fn.
 * Have to see what the register usage is like in the calling routines.
 */
		adr	r4, LC0
		ldmia	r4, {r4, r5, r6, lr}
		ldr	r4, [r4]
		ldr	r5, [r5]
/*
 * Go to resolution-dependent routine...
 */
		cmp	r4, #4
		blt	Lrow1bpp
		eor	r2, r3, r2			@ Create eor mask to change colour from bg
		orr	r3, r3, r3, lsl #8		@ to fg.
		orr	r3, r3, r3, lsl #16
		add	r0, r0, r5, lsl #3		@ Move to bottom of character
		add	r1, r1, #7
		ldrb	r7, [r6, r1]
		tst	ip, #UNDERLINE << 9
		eoreq	r7, r7, #255
		teq	r4, #8
		beq	Lrow8bpplp
@
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
@
		orr	r3, r3, r3, lsl #4
Lrow4bpplp:	ldr	r7, [lr, r7, lsl #2]
		mul	r7, r2, r7
		tst	r1, #7				@ avoid using r7 directly after
		eor	ip, r3, r7
		str	ip, [r0, -r5]!
		LOADREGS(eqfd, sp!, {r4 - r7, pc})
		sub	r1, r1, #1
		ldrb	r7, [r6, r1]
		ldr	r7, [lr, r7, lsl #2]
		mul	r7, r2, r7
		tst	r1, #7				@ avoid using r7 directly after
		eor	ip, r3, r7
		str	ip, [r0, -r5]!
		subne	r1, r1, #1
		ldrneb	r7, [r6, r1]
		bne	Lrow4bpplp
		LOADREGS(fd, sp!, {r4 - r7, pc})

@
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
@
Lrow8bpplp:	mov	ip, r7, lsr #4
		ldr	ip, [lr, ip, lsl #2]
		mul	r4, r2, ip
		and	ip, r7, #15			@ avoid r4
		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
		mul	ip, r2, ip			@ avoid r4
		eor	r4, r3, r4			@ avoid ip
		tst	r1, #7				@ avoid ip
		sub	r0, r0, r5			@ avoid ip
		eor	ip, r3, ip
		stmia	r0, {r4, ip}
		LOADREGS(eqfd, sp!, {r4 - r7, pc})
		sub	r1, r1, #1
		ldrb	r7, [r6, r1]
		mov	ip, r7, lsr #4
		ldr	ip, [lr, ip, lsl #2]
		mul	r4, r2, ip
		and	ip, r7, #15			@ avoid r4
		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
		mul	ip, r2, ip			@ avoid r4
		eor	r4, r3, r4			@ avoid ip
		tst	r1, #7				@ avoid ip
		sub	r0, r0, r5			@ avoid ip
		eor	ip, r3, ip
		stmia	r0, {r4, ip}
		subne	r1, r1, #1
		ldrneb	r7, [r6, r1]
		bne	Lrow8bpplp
		LOADREGS(fd, sp!, {r4 - r7, pc})

@
@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
@
Lrow1bpp:	add	r6, r6, r1
		ldmia	r6, {r4, r7}
		tst	ip, #INVERSE << 9
		mvnne	r4, r4
		mvnne	r7, r7
		strb	r4, [r0], r5
		mov	r4, r4, lsr #8
		strb	r4, [r0], r5
		mov	r4, r4, lsr #8
		strb	r4, [r0], r5
		mov	r4, r4, lsr #8
		strb	r4, [r0], r5
		strb	r7, [r0], r5
		mov	r7, r7, lsr #8
		strb	r7, [r0], r5
		mov	r7, r7, lsr #8
		strb	r7, [r0], r5
		mov	r7, r7, lsr #8
		tst	ip, #UNDERLINE << 9
		mvneq	r7, r7
		strb	r7, [r0], r5
		LOADREGS(fd, sp!, {r4 - r7, pc})

		.bss
ENTRY(con_charconvtable)
		.space	1024