1/*
2 *  linux/arch/arm/lib/ll_char_wr.S
3 *
4 *  Copyright (C) 1995, 1996 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 *  Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
11 *
12 *  10-04-96	RMK	Various cleanups & reduced register usage.
13 *  08-04-98	RMK	Shifts re-ordered
14 */
15
16@ Regs: [] = corruptible
17@       {} = used
18@       () = do not use
19
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22		.text
23
24#define BOLD            0x01
25#define ITALIC          0x02
26#define UNDERLINE       0x04
27#define FLASH           0x08
28#define INVERSE         0x10
29
30LC0:		.word	SYMBOL_NAME(bytes_per_char_h)
31		.word	SYMBOL_NAME(video_size_row)
32		.word	SYMBOL_NAME(acorndata_8x8)
33		.word	SYMBOL_NAME(con_charconvtable)
34
35ENTRY(ll_write_char)
36		stmfd	sp!, {r4 - r7, lr}
37@
38@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
39@
40		eor	ip, r1, #UNDERLINE << 9
41/*
42 * calculate colours
43 */
44		tst	r1, #INVERSE << 9
45		moveq	r2, r1, lsr #16
46		moveq	r3, r1, lsr #24
47		movne	r2, r1, lsr #24
48		movne	r3, r1, lsr #16
49		and	r3, r3, #255
50		and	r2, r2, #255
51/*
52 * calculate offset into character table
53 */
54		mov	r1, r1, lsl #23
55		mov	r1, r1, lsr #20
56/*
57 * calculate offset required for each row [maybe I should make this an argument to this fn.
58 * Have to see what the register usage is like in the calling routines.
59 */
60		adr	r4, LC0
61		ldmia	r4, {r4, r5, r6, lr}
62		ldr	r4, [r4]
63		ldr	r5, [r5]
64/*
65 * Go to resolution-dependent routine...
66 */
67		cmp	r4, #4
68		blt	Lrow1bpp
69		eor	r2, r3, r2			@ Create eor mask to change colour from bg
70		orr	r3, r3, r3, lsl #8		@ to fg.
71		orr	r3, r3, r3, lsl #16
72		add	r0, r0, r5, lsl #3		@ Move to bottom of character
73		add	r1, r1, #7
74		ldrb	r7, [r6, r1]
75		tst	ip, #UNDERLINE << 9
76		eoreq	r7, r7, #255
77		teq	r4, #8
78		beq	Lrow8bpplp
79@
80@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
81@
82		orr	r3, r3, r3, lsl #4
83Lrow4bpplp:	ldr	r7, [lr, r7, lsl #2]
84		mul	r7, r2, r7
85		tst	r1, #7				@ avoid using r7 directly after
86		eor	ip, r3, r7
87		str	ip, [r0, -r5]!
88		LOADREGS(eqfd, sp!, {r4 - r7, pc})
89		sub	r1, r1, #1
90		ldrb	r7, [r6, r1]
91		ldr	r7, [lr, r7, lsl #2]
92		mul	r7, r2, r7
93		tst	r1, #7				@ avoid using r7 directly after
94		eor	ip, r3, r7
95		str	ip, [r0, -r5]!
96		subne	r1, r1, #1
97		ldrneb	r7, [r6, r1]
98		bne	Lrow4bpplp
99		LOADREGS(fd, sp!, {r4 - r7, pc})
100
101@
102@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
103@
104Lrow8bpplp:	mov	ip, r7, lsr #4
105		ldr	ip, [lr, ip, lsl #2]
106		mul	r4, r2, ip
107		and	ip, r7, #15			@ avoid r4
108		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
109		mul	ip, r2, ip			@ avoid r4
110		eor	r4, r3, r4			@ avoid ip
111		tst	r1, #7				@ avoid ip
112		sub	r0, r0, r5			@ avoid ip
113		eor	ip, r3, ip
114		stmia	r0, {r4, ip}
115		LOADREGS(eqfd, sp!, {r4 - r7, pc})
116		sub	r1, r1, #1
117		ldrb	r7, [r6, r1]
118		mov	ip, r7, lsr #4
119		ldr	ip, [lr, ip, lsl #2]
120		mul	r4, r2, ip
121		and	ip, r7, #15			@ avoid r4
122		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
123		mul	ip, r2, ip			@ avoid r4
124		eor	r4, r3, r4			@ avoid ip
125		tst	r1, #7				@ avoid ip
126		sub	r0, r0, r5			@ avoid ip
127		eor	ip, r3, ip
128		stmia	r0, {r4, ip}
129		subne	r1, r1, #1
130		ldrneb	r7, [r6, r1]
131		bne	Lrow8bpplp
132		LOADREGS(fd, sp!, {r4 - r7, pc})
133
134@
135@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
136@
137Lrow1bpp:	add	r6, r6, r1
138		ldmia	r6, {r4, r7}
139		tst	ip, #INVERSE << 9
140		mvnne	r4, r4
141		mvnne	r7, r7
142		strb	r4, [r0], r5
143		mov	r4, r4, lsr #8
144		strb	r4, [r0], r5
145		mov	r4, r4, lsr #8
146		strb	r4, [r0], r5
147		mov	r4, r4, lsr #8
148		strb	r4, [r0], r5
149		strb	r7, [r0], r5
150		mov	r7, r7, lsr #8
151		strb	r7, [r0], r5
152		mov	r7, r7, lsr #8
153		strb	r7, [r0], r5
154		mov	r7, r7, lsr #8
155		tst	ip, #UNDERLINE << 9
156		mvneq	r7, r7
157		strb	r7, [r0], r5
158		LOADREGS(fd, sp!, {r4 - r7, pc})
159
160		.bss
161ENTRY(con_charconvtable)
162		.space	1024
163