works
[des2015.git] / mart / ex11 / ex11.c
1 #include <stdio.h>
2 #include <signal.h>
3 #include <unistd.h>
4 #include <sys/mman.h>
5 #include <sys/io.h>
6
7 #include <native/task.h>
8 #include <native/timer.h>
9 #include <native/intr.h>
10
11 #include <rtdk.h>
12
13 #define LPT1IRQ 7
14 #define TICKS 5
15 #define BANNERWIDTH 10000
16 #define MAXX 20
17
18 RT_TASK intrtask, drawtask;
19 RTIME ticks[TICKS+1];
20 RTIME tocks[TICKS+1];
21
22 unsigned char data[BANNERWIDTH];
23 char* message;
24 unsigned int pointer = 0;
25 unsigned int msglen;
26
27 void add_tick(RTIME *t, RTIME tnew)
28 {
29 unsigned int i = 0;
30 t[TICKS] = 0;
31 for(i=TICKS-1; i>0; i--){
32 t[i] = t[i-1];
33 t[TICKS] += t[i];
34 }
35 t[0] = tnew;
36 t[TICKS] = (t[TICKS]+t[0])/TICKS;
37 }
38
39 void taskd(void *arg)
40 {
41 RTIME time = *(RTIME *)arg;
42 RTIME step = time/(2*MAXX+2);
43 unsigned int i;
44
45 //To the right
46 outb(0x00, 0x378);
47 rt_task_sleep(step*2);
48 for(i=0; i<MAXX; i++){
49 outb(data[i+pointer], 0x378);
50 rt_task_sleep(step);
51 outb(0x00, 0x378);
52 }
53 rt_task_sleep(step);
54 outb(0x00, 0x378);
55
56 pointer = pointer > msglen ? 0 : pointer+1;
57 }
58
59 void taski(void *arg)
60 {
61 //Register as interrupt handler
62 RT_INTR intr;
63 rt_intr_create(&intr, NULL, LPT1IRQ, 0);
64 rt_printf("Interrupt created\n");
65
66 //Initialize and declare the timer variables
67 RTIME tick = rt_timer_read();
68 RTIME tock;
69 RTIME period;
70 while(1){
71 tock = rt_timer_read();
72 add_tick(ticks, tock-tick);
73
74 // Tocks waiting period
75 if(tocks[TICKS] < ticks[TICKS]){
76 // sleep until the arm is most left
77 rt_task_sleep(tocks[TICKS]/2);
78 rt_task_create(&drawtask, NULL, 0, 50, 0);
79 period = ticks[TICKS]+tocks[TICKS];
80 rt_task_start(&drawtask, &taskd, &period);
81 rt_printf("tocks is the short stretch\n");
82 }
83 rt_intr_wait(&intr, TM_INFINITE);
84
85 //Tick waiting period
86 tick = rt_timer_read();
87 add_tick(tocks, tick-tock);
88
89 if(ticks[TICKS] < tocks[TICKS]){
90 // sleep until the arm is most left
91 rt_task_sleep(ticks[TICKS]/2);
92 rt_task_create(&drawtask, NULL, 0, 50, 0);
93 period = ticks[TICKS]+tocks[TICKS];
94 rt_task_start(&drawtask, &taskd, &period);
95 rt_printf("ticks is the short stretch\n");
96 }
97 rt_intr_wait(&intr, TM_INFINITE);
98 //Print average
99 //rt_printf("avgtick: %lluns, avgtock: %lluns, avgticktock: %lluns\n",
100 // ticks[TICKS], tocks[TICKS], (ticks[TICKS]+tocks[TICKS])/2);
101 }
102 }
103
104 int main(int argc, char* argv[])
105 {
106 if(argc != 2){
107 printf("Usage: %s \"Message\"\n", argv[0]);
108 return 1;
109 }
110 message = argv[1];
111 rt_print_auto_init(1);
112 mlockall(MCL_CURRENT | MCL_FUTURE);
113
114 unsigned int i;
115 for(i=0; i<BANNERWIDTH; i++){
116 data[i] = 0;
117 }
118
119 i=20;
120 unsigned char s = 0;
121 while(i<BANNERWIDTH && s < strlen(message)){
122 char c = message[s];
123 printf("processing: '%c'\n", c);
124 switch(c){
125 case 'A':
126 case 'a':
127 data[i++] = 0x1e; data[i++] = 0x5; data[i++] = 0x1e; break;
128 case 'B':
129 case 'b':
130 data[i++] = 0x1f; data[i++] = 0x15; data[i++] = 0xe; break;
131 case 'C':
132 case 'c':
133 data[i++] = 0xe; data[i++] = 0x11; break;
134 case 'D':
135 case 'd':
136 data[i++] = 0x1f; data[i++] = 0x11; data[i++] = 0xe; break;
137 case 'E':
138 case 'e':
139 data[i++] = 0x1f; data[i++] = 0x15; break;
140 case 'F':
141 case 'f':
142 data[i++] = 0x1f; data[i++] = 0x05; break;
143 case 'G':
144 case 'g':
145 data[i++] = 0xe; data[i++] = 0x11, data[i++] = 0x1d; break;
146 case 'H':
147 case 'h':
148 data[i++] = 0x1f; data[i++] = 0x4, data[i++] = 0x1f; break;
149 case 'I':
150 case 'i':
151 data[i++] = 0x1f; break;
152 case 'J':
153 case 'j':
154 data[i++] = 0x10; data[i++] = 0x1f; break;
155 case 'K':
156 case 'k':
157 data[i++] = 0x1f; data[i++] = 0x04; data[i++] = 0x1b; break;
158 case 'L':
159 case 'l':
160 data[i++] = 0x1f; data[i++] = 0x10; break;
161 case 'M':
162 case 'm':
163 data[i++] = 0x1f; data[i++] = 0x2; data[i++] = 0x7; data[i++] = 0x2; data[i++] = 0x1f; break;
164 case 'N':
165 case 'n':
166 data[i++] = 0x1f; data[i++] = 0x2; data[i++] = 0x4; data[i++] = 0x1f; break;
167 case 'O':
168 case 'o':
169 data[i++] = 0xe; data[i++] = 0x11; data[i++] = 0xe; break;
170 case 'P':
171 case 'p':
172 data[i++] = 0x1f; data[i++] = 0x5; data[i++] = 0x2; break;
173 case 'Q':
174 case 'q':
175 data[i++] = 0xe; data[i++] = 0x11; data[i++] = 0x19; data[i++] = 0x1e; break;
176 case 'R':
177 case 'r':
178 data[i++] = 0x1f; data[i++] = 0x5; data[i++] = 0x1a; break;
179 case 'S':
180 case 's':
181 data[i++] = 0x12; data[i++] = 0x15; data[i++] = 0xd; break;
182 case 'T':
183 case 't':
184 data[i++] = 0x1; data[i++] = 0x1f; data[i++] = 0x1; break;
185 case 'U':
186 case 'u':
187 data[i++] = 0x1f; data[i++] = 0x10; data[i++] = 0x1f; break;
188 case 'V':
189 case 'v':
190 data[i++] = 0xf; data[i++] = 0x10; data[i++] = 0xf; break;
191 case 'W':
192 case 'w':
193 data[i++] = 0xf; data[i++] = 0x10; data[i++] = 0xc; data[i++] = 0x10; data[i++] = 0xf; break;
194 case 'X':
195 case 'x':
196 data[i++] = 0x11; data[i++] = 0xe; data[i++] = 0x11; break;
197 case 'Y':
198 case 'y':
199 data[i++] = 0x17; data[i++] = 0x14; data[i++] = 0xf; break;
200 case 'Z':
201 case 'z':
202 data[i++] = 0x19; data[i++] = 0x15; data[i++] = 0x13; break;
203 case '.':
204 data[i++] = 0x10; break;
205 case ',':
206 data[i++] = 0x10; data[i++] = 0x8; break;
207 case '\'':
208 case '"':
209 data[i++] = 0x1; break;
210 case ' ':
211 i++;
212 break;
213 case '!':
214 data[i++] = 0x17; break;
215 default:
216 break;
217 }
218 i++;
219 s++;
220 }
221 msglen = i;
222
223 // Get permission to write to parallel port
224 ioperm(0x37A, 1, 1);
225 ioperm(0x378, 1, 1);
226 outb(inb(0x37A) | 0x10, 0x37A);
227
228 rt_task_create(&intrtask, NULL, 0, 50, 0);
229 rt_task_start(&intrtask, &taski, 0);
230
231 pause();
232 }