HD200: Change move.w -> move.b in lcd-as-hd200.S when doing transfers to lcd to expli...
[kugel-rb.git] / firmware / target / coldfire / mpio / hd200 / lcd-as-hd200.S
blob17b3dabfbeb74cb9bf45b51bbe9a51cf2354d532
1 /***************************************************************************
2  *             __________               __   ___.
3  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7  *                     \/            \/     \/    \/            \/
8  * $Id:$
9  *
10  * Copyright (C) 2010 Marcin Bukat
11  * based on lcd-as-m3.S by Jens Arnold
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ****************************************************************************/
23 #include "config.h" 
24 #include "cpu.h"
27 #define LCD_BASE_ADDRESS 0xf0000000
29     .section    .icode,"ax",@progbits
31     .align      2
32     .global     lcd_write_command
33     .type       lcd_write_command,@function
35 lcd_write_command:
36     move.l  (4, %sp), %d0
37     move.b  %d0, LCD_BASE_ADDRESS       /* transfers 1 byte to LCD */
39     rts
40 .wc_end:
41     .size   lcd_write_command,.wc_end-lcd_write_command
44     .align      2
45     .global     lcd_write_command_e
46     .type       lcd_write_command_e,@function
48 lcd_write_command_e:
49     lea.l   LCD_BASE_ADDRESS, %a0
50     move.l  (4, %sp), %d0       /* Command */
51     move.b  %d0, (%a0)         
52     move.l  (8, %sp), %d0       /* Data */
53     move.b  %d0, (%a0)          /* Write to LCD */
55     rts
56 .wce_end:
57     .size   lcd_write_command_e,.wce_end-lcd_write_command_e
60     .align      2
61     .global     lcd_write_data
62     .type       lcd_write_data,@function
64 /* PIXELFORMAT = VERTICAL_INTERLEAVED
65  * this means that data is packed verticaly in 8 pixels columns
66  * first byte is lsb of 2bit color in column
67  * second byte is msb of 2bit color in column
68  * so one word of data equals 8 pixels i 2bits color depth packed
69  * verticaly
70  */
71 lcd_write_data:
72     movem.l (4, %sp), %a0            /* Data pointer */
73     move.l  (8, %sp), %d0            /* Length i in words */
74     lea.l   LCD_BASE_ADDRESS+2, %a1  /* LCD data port address */
76     btst    #0, %d0    /* longwords multiply? */
77     jeq    .l_write
79 .w_write:
80     move.w  (%a0)+, %d1  /* load data         3 cycles*/
81     move.b  %d1, (%a1)   /* first byte        1 cycle*/
82     lsr.l   #8, %d1      /* load second byte  1 cycle*/
83     move.b  %d1, (%a1)   /* transfer          1 cycle*/
84     subq.l  #1, %d0      /* decrement counter 1 cycle*/
85     jeq     .write_end   
86     
87 .l_write:
88     move.l  (%a0)+, %d1  /* load data         2 cycles*/
89     swap    %d1          /*                   1 cycle */
90     move.b  %d1, (%a1)   /* first byte        1 cycle*/
91     lsr.l   #8, %d1      /*                   1 cycle */
92     move.b  %d1, (%a1)   /* second byte       1 cycle*/
93     lsr.l   #8, %d1      /*                   1 cycle */
94     move.b  %d1, (%a1)   /* third byte        1 cycle*/
95     lsr.l   #8, %d1      /*                   1 cycle */
96     move.b  %d1, (%a1)   /* forth byte        1 cycle*/
97     subq.l  #2, %d0      /* decrement counter 1 cycle*/
98     bne.s   .l_write
100 .write_end:
101     rts
102 .wd_end:
103     .size   lcd_write_data,.wd_end-lcd_write_data
105     .global lcd_mono_data
106     .type   lcd_mono_data, @function
108 lcd_mono_data:
109     move.l  (4, %sp), %a0       /* p_bytes */
110     move.l  (8, %sp), %d0       /* count */
111     lea.l   LCD_BASE_ADDRESS+2, %a1  /* LCD data port address */
113 .md_loop:
114     move.b  (%a0)+, %d1
115     move.b  %d1, (%a1)    /* byte transfers */
116     move.b  %d1, (%a1)
117     subq.l  #1, %d0
118     bne.s   .md_loop
120     rts
121 .md_end:
122     .size   lcd_mono_data,.md_end-lcd_mono_data
124     .global     lcd_grey_data
125     .type       lcd_grey_data,@function
127 lcd_grey_data:
128     lea.l   (-11*4, %sp), %sp
129     movem.l  %d2-%d7/%a2-%a6, (%sp) /* save some registers */
130     movem.l (11*4+4, %sp), %a0-%a2  /* values, phases, length */
131     add.l   %a2, %a2
132     lea.l   (%a1, %a2.l*4), %a2    /* end address */
133     lea.l   LCD_BASE_ADDRESS+2, %a3 /* LCD data port address */
134     moveq.l #24, %d4            /* shift count */
135     move.l  #0x204081, %d5      /* bit shuffle factor */
137     moveq.l #8, %d2
138     add.l   %a1, %d2
139     and.l   #0xfffffff0, %d2    /* first line bound */
140     cmp.l   %d2, %a2            /* end address lower than first line bound? */
141     bhs.s   1f
142     move.l  %a2, %d2            /* -> adjust end address of head loop */
144     cmp.l   %a1, %d2
145     bls.s   .g_hend
147     /* process head pixels */
148     movem.l (%a1), %d0-%d1      /* fetch 8 pixel phases */
150     move.l  %d0, %d2
151     and.l   #0x80808080, %d2    /* %d2 = 0.......1.......2.......3....... */
152     eor.l   %d2, %d0
153     add.l   (%a0)+, %d0         /* add values to first 4 phases */
155     move.l  %d1, %d3
156     and.l   #0x80808080, %d3    /* %d3 = 4.......5.......6.......7....... */
157     eor.l   %d3, %d1
158     add.l   (%a0)+, %d1         /* add values to second 4 phases */
160     lsr.l   #4, %d3             /* %d3 = ....4.......5.......6.......7... */
161     or.l    %d3, %d2            /* %d2 = 0...4...1...5...2...6...3...7... */
162     mulu.l  %d5, %d2            /* %d2 = 01234567123.567.23..67..3...7... */
163     not.l   %d2                 /*       negate bits */
164     lsr.l   %d4, %d2            /* %d2 = ........................01234567 */
166     move.b  %d2, (%a3)          /* transfer first LCD byte */
168     movem.l %d0-%d1, (%a1)      /* store 8 new pixel phases */
169     addq.l  #8, %a1
171     move.b  %d2, (%a3)          /* transfer second LCD byte */
173 .g_hend:
174     cmp.l   %a1, %a2
175     bls.w   .g_tend
176     subq.l  #8, %a2
177     cmp.l   %a1, %a2
178     bls.s   .g_lend
180 .g_line_loop:
181     /* loop that utilizes line transfers */
182     movem.l (%a1), %d0-%d3      /* fetch 2 * 8 pixels phases */
184     move.l  %d0, %d6
185     and.l   #0x80808080, %d6    /* %d6 = 0.......1.......2.......3....... */
186     eor.l   %d6, %d0
188     move.l  %d1, %d7
189     and.l   #0x80808080, %d7    /* %d7 = 4.......5.......6.......7....... */
190     eor.l   %d7, %d1
192     lsr.l   #4, %d7             /* %d7 = ....4.......5.......6.......7... */
193     or.l    %d7, %d6            /* %d6 = 0...4...1...5...2...6...3...7... */
194     mulu.l  %d5, %d6            /* %d6 = 01234567123.567.23..67..3...7... */
195     not.l   %d6                 /*       negate bits */
196     lsr.l   %d4, %d6            /* %d6 = ........................01234567 */
198     move.b  %d6, (%a3)          /* transfer first LCD byte */
200     movem.l (%a0), %d7/%a4-%a6  /* fetch 2 * 8 pixel values */
201     lea.l   (16, %a0), %a0
203     move.b  %d6, (%a3)          /* transfer second LCD byte */
205     add.l   %d7, %d0
206     add.l   %a4, %d1
208     move.l  %d2, %d6
209     and.l   #0x80808080, %d6    /* %d6 = 0.......1.......2.......3....... */
210     eor.l   %d6, %d2
212     move.l  %d3, %d7
213     and.l   #0x80808080, %d7    /* %d7 = 4.......5.......6.......7....... */
214     eor.l   %d7, %d3
216     lsr.l   #4, %d7             /* %d7 = ....4.......5.......6.......7... */
217     or.l    %d7, %d6            /* %d6 = 0...4...1...5...2...6...3...7... */
218     mulu.l  %d5, %d6            /* %d6 = 01234567123.567.23..67..3...7... */
219     not.l   %d6                 /*       negate bits */
220     lsr.l   %d4, %d6            /* %d6 = ........................01234567 */
222     add.l   %a5, %d2
223     add.l   %a6, %d3
225     move.b  %d6, (%a3)          /* transfer first LCD byte */
227     movem.l %d0-%d3, (%a1)      /* store 2 * 8 new pixel phases */
228     lea.l   (16, %a1), %a1      /* advance pointer */
230     move.b  %d6, (%a3)          /* transfer second LCD byte */
232     cmp.l   %a2, %a1
233     bls.s   .g_line_loop
235 .g_lend:
236     addq.l  #8, %a2
237     cmp.l   %a1, %a2
238     bls.s   .g_tend
240     /* process tail pixels */
241     movem.l (%a1), %d0-%d1      /* fetch 8 pixel phases */
243     move.l  %d0, %d2
244     and.l   #0x80808080, %d2    /* %d2 = 0.......1.......2.......3....... */
245     eor.l   %d2, %d0
246     add.l   (%a0)+, %d0         /* add values to first 4 phases */
248     move.l  %d1, %d3
249     and.l   #0x80808080, %d3    /* %d3 = 4.......5.......6.......7....... */
250     eor.l   %d3, %d1
251     add.l   (%a0)+, %d1         /* add values to second 4 phases */
253     lsr.l   #4, %d3             /* %d3 = ....4.......5.......6.......7... */
254     or.l    %d3, %d2            /* %d2 = 0...4...1...5...2...6...3...7... */
255     mulu.l  %d5, %d2            /* %d2 = 01234567123.567.23..67..3...7... */
256     not.l   %d2                 /*       negate bits */
257     lsr.l   %d4, %d2            /* %d2 = ........................01234567 */
259     move.b  %d2, (%a3)          /* transfer first LCD byte */
261     movem.l %d0-%d1, (%a1)      /* store 8 new pixel phases */
262     /* addq.l  #8, %a1             not needed anymore */
264     move.b  %d2, (%a3)          /* transfer second LCD byte */
266 .g_tend:
267     movem.l (%sp), %d2-%d7/%a2-%a6
268     lea.l   (11*4, %sp), %sp
269     rts
270 .grey_end:
271     .size    lcd_grey_data,.grey_end-lcd_grey_data