- To reduce confuse rename the parts of linuxbios bios that run from
[coreboot.git] / src / arch / i386 / llshell / llshell.inc
1 jmp llshell_out
2
3 // (c) 2004 Bryan Chafy,  This program is released under the GPL
4
5 // LLShell, A low level interactive debug shell
6 // Designed to be an interactive shell that operates with zero
7 // system resources.  For example at initial boot.
8
9 // to use, jump to label "low_level_shell" 
10 // set %esp to the return address for exiting
11
12
13 #define UART_BASEADDR $0x3f8  
14 #define resultreg %esi
15 #define subroutinereg %edi
16 #define freqtime $2193  // 1.93 * freq
17 #define timertime $6000
18 .equ    sys_IOPL, 110           
19
20 // .data
21 // .text
22
23 welcome:
24         .string "\r\n! Low Level Shell (LLShell)  (c)2004 Bryan Chafy \r\n\r\n"
25 prompt:
26         .string "\r\n!> "
27 badcmd:
28         .string "bad command\r\n"
29 sorry:
30         .string "sorry, not yet implemented\r\n"
31 cmds:
32         .string "\r\nList of commands:\r\n \
33 \r\nbeep                    -- pc speaker beep \
34 \r\nrst (or RST)            -- reset \
35 \r\nout(b,w,l) <val> <port> -- raw out val at port \
36 \r\nin(b,w,l)  <port>       -- show raw port value \
37 \r\njmp  <address>          -- jmp to address (llshell addr is in eax) \
38 \r\ncall <address>          -- funcion call (assumes a working stack) \
39 \r\ncli                     -- clear interrupts \
40 \r\nsti                     -- enable interrupts \
41 \r\npush <value>            -- push value onto stack \
42 \r\npop                     -- pop from stack and display \
43 \r\nwm(b,w,l) <addr> <val>  -- write mem \
44 \r\ndm   <addr> <lines>     -- dump mem  \
45 \r\nmcp  <src> <dst> <size> -- mem copy  \
46 \r\nmpat <pat> <dst> <size> -- mem pattern \
47 \r\nmemt <begin> <end>      -- memory test \
48 \r\npcir(b,w,l) <loc>       -- pci read config \
49 \r\npciw(b,w,l) <loc> <val> -- pci write config  \
50 \r\ndl   <addr> <size>      -- memory download (display xor cheksum at completion) \
51 \r\ncram <addr> <size>      -- enable cache to be ram (experimental) \
52 \r\nbaud <val>              -- change baudrate (not yet implemented)  \
53 \r\nexit                    -- exit shell \
54 \r\nAll values in hex (0x prefixing ok)  \
55 \r\n"
56
57 cr:     
58         .string "\r\n"
59 spaces:     
60         .string "   "
61
62 // .globl _start
63 //ASSUME CS:@CODE, DS:@DATA
64
65 // _start:
66
67 // call ioperms
68
69 low_level_shell:
70
71 mov $preamble,subroutinereg
72 jmp beep
73 preamble:
74 mov $welcome,resultreg
75 mov $readcommand,subroutinereg
76 jmp displaystring
77
78 readcommand:
79 mov $prompt,resultreg
80 mov $rcmd,subroutinereg
81 jmp displaystring
82
83 rcmd:
84 mov $readcommand,subroutinereg
85 movl $0x0, resultreg
86
87 readchar:
88 mov  UART_BASEADDR+5,%dx
89 in   %dx, %al
90 and  $0x9f,%al
91 test $0x01,%al
92 jz   readchar
93 mov  UART_BASEADDR,%dx
94 in   %dx,%al             //char in al
95 xchg %al,%ah
96
97 send_char:
98 mov  UART_BASEADDR+5,%dx
99 us_wait:
100 in   %dx,%al
101 test $0x20,%al
102 jz us_wait
103 mov  UART_BASEADDR,%dx
104 xchg %al,%ah
105 out  %al,%dx            // output char
106
107 cmp  $0x0D,%al      //CR
108 jnz  eval_char
109 mov  $0x0A,%ah
110 jmp  send_char
111
112 eval_char:
113 cmp  $0x20,%al      //space
114 jz   cmdtable
115 cmp  $0x0A,%al      //CR
116 jz   cmdtable
117 cmp  $0x08,%al      //BS
118 jnz  additup
119 //subit:
120 shr  $0x8,resultreg
121 jmp  readchar
122 additup:
123 shl  $0x8,resultreg
124 and  $0xff,%eax
125 add  %eax,resultreg
126 jmp  readchar
127
128 cmdtable:
129 mov resultreg,%eax
130 cmp $0,%eax
131 jz  readcommand
132 cmp $0x74657374,%eax
133 jz  dotest
134 cmp $0x68656c70,%eax
135 jz  dohelp
136 cmp $0x0000003f,%eax
137 jz  dohelp
138 cmp $0x6f757462,%eax
139 jz  dooutb
140 cmp $0x6f757477,%eax
141 jz  dooutw
142 cmp $0x6f75746c,%eax
143 jz  dooutd
144 cmp $0x00696e62,%eax
145 jz doinb
146 cmp $0x00696e77,%eax
147 jz doinw
148 cmp $0x00696e6c,%eax
149 jz doind
150 cmp $0x63697262,%eax
151 jz pcirb
152 cmp $0x63697277,%eax
153 jz pcirw
154 cmp $0x6369726c,%eax
155 jz pcirl
156 cmp $0x63697762,%eax
157 jz pciwb
158 cmp $0x63697777,%eax
159 jz pciww
160 cmp $0x6369776c,%eax
161 jz pciwl
162 cmp $0x00776d62,%eax
163 jz  wmemb
164 cmp $0x00776d77,%eax
165 jz  wmemw
166 cmp $0x00776d6c,%eax
167 jz  wmeml
168 cmp $0x0000646d,%eax
169 jz  dodmem  
170 cmp $0x6d656d74,%eax
171 jz  memt                    // mem test
172 cmp $0x00727374,%eax
173 jz  rst                     // reset
174 cmp $0x00525354,%eax
175 jz  RST
176 cmp $0x62656570,%eax
177 jz  beep   
178 cmp $0x0000646c,%eax
179 jz  dodl                    // download to mem <loc> <size>
180 cmp $0x006a6d70,%eax
181 jz  jmpto                   // jump to location (eax holds return addr)
182 cmp $0x62617564,%eax
183 jz  baud                    // change baudrate
184 cmp $0x00696e74,%eax
185 jz  doint                   // trigger an interrupt 
186 cmp $0x63616c6c,%eax
187 jz  callto                  // call assumes memory
188 cmp $0x70757368,%eax
189 jz  dopush                  // assumes mem
190 cmp $0x00706f70,%eax
191 jz  dopop                   // assumes mem
192 cmp $0x6372616d,%eax
193 jz  cram                    // cache ram trick <location> <size>
194 cmp $0x006d6370,%eax
195 jz  mcp                     // mem copy <src> <dst> <size>
196 cmp $0x6d706174,%eax
197 jz  dopattern
198 cmp $0x00636c69,%eax
199 jz docli
200 cmp $0x00737469,%eax
201 jz dosti
202 cmp $0x65786974,%eax
203 jz  doexit
204 mov $badcmd,resultreg
205 mov $readcommand,subroutinereg
206 jmp displaystring
207
208
209 readnibbles:
210 movl $0x0, resultreg
211 readit:
212 mov  UART_BASEADDR+5,%dx
213 in   %dx, %al
214 and  $0x9f,%al
215 test $0x1,%al
216 jz   readit
217 mov  UART_BASEADDR,%dx
218 in   %dx,%al
219 xchg %al,%ah
220
221 sendchar:
222 mov  UART_BASEADDR+5,%dx
223 us_waitit:
224 in   %dx,%al
225 test $0x20,%al
226 jz   us_waitit
227 mov  UART_BASEADDR,%dx
228 xchg %al,%ah
229 out  %al,%dx            // output char
230
231 cmp  $0x78,%al
232 jz   readit
233 cmp  $0x0D,%al      //CR
234 jnz  evalchar
235 mov  $0x0A,%ah
236 jmp  sendchar
237
238 evalchar:
239 cmp  $0x20,%al        //space
240 jz   gosub
241 cmp  $0x0A,%al      //CR
242 jz   gosub
243 cmp  $0x08,%al      //BS
244 jnz  processchar
245 //subit:
246 shr  $0x04,resultreg
247 jmp  readit
248 processchar:
249 cmp  $0x3A,%al
250 jl   subnum
251 cmp  $0x47,%al
252 jl   subcaps 
253 //sublc:
254 sub  $0x57,%al
255 jmp  additupn
256 subcaps:
257 sub  $0x37,%al
258 jmp  additupn
259 subnum:
260 sub  $0x30,%al
261 additupn:
262 shl  $0x04,resultreg
263 and  $0xf,%eax
264 add  %eax,resultreg
265 jmp  readit
266
267 gosub:
268 jmp  *subroutinereg
269
270 //intersubcall
271 // eax,edx,esi,edi
272
273 // ebx,ecx,ebp,esp(?)
274 // ds,es,fs,gs
275
276 dotest:
277 mov $ramtest,resultreg
278 mov $test1a,subroutinereg
279 jmp displayhex
280 test1a:
281 mov $welcome,resultreg
282 mov $readcommand,subroutinereg
283 jmp displayhex
284
285 dodmem:
286
287 movl $dmem1a, subroutinereg
288 jmp  readnibbles
289 dmem1a:
290 mov  resultreg,%ebx    // address
291 movl $dmem1b, subroutinereg
292 jmp  readnibbles
293 dmem1b:
294 mov  resultreg,%ecx    // length
295
296 dmemloop:
297 mov %ebx,resultreg
298 mov $daddr1,subroutinereg
299 jmp displayhex
300 daddr1:
301 mov $spaces,resultreg
302 mov $startshowm,subroutinereg
303 jmp displaystring
304
305 startshowm:
306 mov (%ebx),resultreg
307 mov $showm1,subroutinereg
308 jmp displayhexlinear
309 showm1:
310 add $0x04,%ebx
311 mov (%ebx),resultreg
312 mov $showm2,subroutinereg
313 jmp displayhexlinear
314 showm2:
315 add $0x04,%ebx
316 mov (%ebx),resultreg
317 mov $showm3,subroutinereg
318 jmp displayhexlinear
319 showm3:
320 add $0x04,%ebx
321 mov (%ebx),resultreg
322 mov $showa0,subroutinereg
323 jmp displayhexlinear
324
325 showa0:
326 sub $0xC,%ebx
327 mov (%ebx),resultreg
328 mov $showa1,subroutinereg
329 jmp displayasciilinear
330 showa1:
331 add $0x04,%ebx
332 mov (%ebx),resultreg
333 mov $showa2,subroutinereg
334 jmp displayasciilinear
335 showa2:
336 add $0x04,%ebx
337 mov (%ebx),resultreg
338 mov $showa3,subroutinereg
339 jmp displayasciilinear
340 showa3:
341 add $0x04,%ebx
342 mov (%ebx),resultreg
343 mov $doneshow,subroutinereg
344 jmp displayasciilinear
345 doneshow:
346 mov $cr,resultreg
347 mov $doneshow1,subroutinereg
348 jmp displaystring
349 doneshow1:
350 dec %cx
351 cmp $0x0,%cx
352 jz  exitdmem 
353 add $0x04,%ebx
354 jmp dmemloop
355 exitdmem:
356 jmp readcommand
357
358 dooutb:
359 // out val,port
360 movl $outb1a, subroutinereg
361 jmp  readnibbles
362 outb1a:
363 mov  resultreg,%ebx
364 movl $outb1b, subroutinereg
365 jmp  readnibbles
366 outb1b:
367 mov  resultreg,%edx
368 mov  %ebx,%eax
369 out  %al,%dx
370 jmp  readcommand
371
372 dooutw:
373 // out val,port
374 movl $outw1a, subroutinereg
375 jmp  readnibbles
376 outw1a:
377 mov  resultreg,%ebx
378 movl $outw1b, subroutinereg
379 jmp  readnibbles
380 outw1b:
381 mov  resultreg,%edx
382 mov  %ebx,%eax
383 out  %ax,%dx
384 jmp  readcommand
385
386 dooutd:
387 // out val,port
388 movl $outd1a, subroutinereg
389 jmp  readnibbles
390 outd1a:
391 mov  resultreg,%ebx
392 movl $outd1b, subroutinereg
393 jmp  readnibbles
394 outd1b:
395 mov  resultreg,%edx
396 mov  %ebx,%eax
397 out  %eax,%dx
398 jmp  readcommand
399
400 wmemb:
401 movl $wmemba, subroutinereg
402 jmp  readnibbles
403 wmemba:
404 mov  resultreg,%ebx
405 movl $wmembb, subroutinereg
406 jmp  readnibbles
407 wmembb:
408 mov  resultreg,%eax
409 mov  %al,(%ebx)
410 jmp  readcommand
411
412 wmemw:
413 movl $wmemwa, subroutinereg
414 jmp  readnibbles
415 wmemwa:
416 mov  resultreg,%ebx
417 movl $wmemwb, subroutinereg
418 jmp  readnibbles
419 wmemwb:
420 mov  resultreg,%eax
421 mov  %ax,(%ebx)
422 jmp  readcommand
423
424 wmeml:
425 movl $wmemla, subroutinereg
426 jmp  readnibbles
427 wmemla:
428 mov  resultreg,%ebx
429 movl $wmemlb, subroutinereg
430 jmp  readnibbles
431 wmemlb:
432 mov  resultreg,%eax
433 mov  %eax,(%ebx)
434 jmp  readcommand
435
436 doinb:
437 // in port
438 movl $inb1a, subroutinereg
439 jmp  readnibbles
440 inb1a:
441 mov  resultreg,%edx
442 mov  $0x0,%eax
443 in   %dx,%al
444 mov  %eax,resultreg
445 mov  $readcommand,subroutinereg
446 jmp  displayhex
447
448 doinw:
449 // in port
450 movl $inw1a, subroutinereg
451 jmp  readnibbles
452 inw1a:
453 mov  resultreg,%edx
454 mov  $0x0,%eax
455 in   %dx,%ax
456 mov  %eax,resultreg
457 mov  $readcommand,subroutinereg
458 jmp  displayhex
459
460 doind:
461 // in port
462 movl $ind1a, subroutinereg
463 jmp  readnibbles
464 ind1a:
465 mov  resultreg,%edx
466 in   %dx,%eax
467 mov  %eax,resultreg
468 mov  $readcommand,subroutinereg
469 jmp  displayhex
470
471 jmpto:
472 movl $jmp1a, subroutinereg
473 jmp  readnibbles
474 jmp1a:
475 mov  $readcommand,%eax
476 jmp  *resultreg
477
478 callto:
479 movl $call1a, subroutinereg
480 jmp  readnibbles
481 call1a:
482 mov  $readcommand,%eax
483 call *resultreg
484 jmp  readcommand
485
486 dopush:
487 movl $push1a, subroutinereg
488 jmp  readnibbles
489 push1a:
490 mov  resultreg,%eax
491 push %eax
492 jmp  readcommand
493
494 doint:
495 movl $int1a, subroutinereg
496 jmp  readnibbles
497 int1a:
498 mov  resultreg,%eax
499 // need to lookup int table? 
500 // int  %eax
501 jmp  readcommand
502
503 doenter:
504 //setup stack frame
505
506
507 dopop:
508 movl $readcommand, subroutinereg
509 pop  resultreg
510 jmp  displayhex
511
512 docli:
513 cli
514 jmp  readcommand
515
516 dosti:
517 sti
518 jmp  readcommand
519
520
521 displaystring:
522 // resultreg= pointer to string terminated by \0
523 dsloop:
524 movb  (resultreg),%ah
525 cmp  $0x0, %ah
526 jz   displaystringexit
527 mov  UART_BASEADDR+5,%dx
528 us_waits:
529 in   %dx,%al
530 test $0x20,%al
531 jz us_waits
532 mov  UART_BASEADDR,%dx
533 xchg %al,%ah
534 out  %al,%dx            // output char
535 inc  resultreg
536 jmp  dsloop
537 displaystringexit:
538 jmp  *subroutinereg
539
540 displayhexlinear:
541 mov  resultreg,%eax
542 xchg %al,%ah     
543 rol  $0x10,%eax
544 xchg %al,%ah
545 mov  %eax,resultreg
546 displayhex:
547 rol  $0x10,%ecx
548 mov  $0x8,%cx
549 dhloop:
550 cmp  $0xf,%cl
551 je   exitdisplayhex
552 rol  $0x04,resultreg
553 movl resultreg,%eax
554 and  $0xf,%al
555 cmp  $0xa,%al
556 jl   addnum
557 //addcaps
558 add $0x37,%al
559 jmp  outcharhex
560 addnum:
561 add  $0x30,%al
562 outcharhex:
563 xchg %al,%ah
564 mov  UART_BASEADDR+5,%dx
565 us_waith:
566 in   %dx,%al
567 test $0x20,%al
568 jz us_waith
569 mov  UART_BASEADDR,%dx
570 xchg %al,%ah
571 out  %al,%dx            // output char
572 dec  %cx
573 cmp  $0x0,%cx
574 jne  dhloop
575 mov  $0x20,%al
576 mov  $0x10,%cl
577 jmp  outcharhex
578 exitdisplayhex:
579 rol  $0x10,%ecx
580 jmp  *subroutinereg
581
582 displayasciilinear:
583 mov  resultreg,%eax
584 xchg %al,%ah     
585 rol  $0x10,%eax
586 xchg %al,%ah
587 mov  %eax,resultreg
588 displayascii:
589 rol  $0x10,%ecx
590 mov  $0x4,%cx
591 daloop:
592 rol  $0x08,resultreg
593 movl resultreg,%eax
594 cmp  $0x7e,%al
595 jg   unprintable
596 cmp  $0x20,%al
597 jl   unprintable
598 jmp  outcharascii
599 unprintable:
600 mov  $0x2e,%al          // dot
601 outcharascii:
602 xchg %al,%ah
603 mov  UART_BASEADDR+5,%dx
604 us_waita:
605 in   %dx,%al
606 test $0x20,%al
607 jz us_waita
608 mov  UART_BASEADDR,%dx
609 xchg %al,%ah
610 out  %al,%dx            // output char
611 dec  %cx
612 cmp  $0x0,%cx
613 jne  daloop
614 rol  $0x10,%ecx
615 jmp  *subroutinereg
616
617 rst:
618 cli
619 movb $0x0fe,%al
620 out  %al,$0x64
621 hlt
622
623 RST:
624 cli
625 lidt %cs:0x03fff
626 int  $0x3
627 hlt
628
629
630 beep:
631 mov  timertime,%eax
632 rol  $0x10,%eax
633 mov  $0xb6,%al
634 out  %al,$0x43
635 mov  freqtime,%ax
636 out  %al,$0x42
637 xchg %al,%ah
638 out  %al,$0x42
639
640 in   $0x61,%al
641 or   $0x03,%al
642 out  %al,$0x61
643
644 //timer here
645 timer:
646 in   $0x42,%al
647 // xchg %al,%ah
648 in   $0x42,%al
649 // xchg %al,%ah
650 cmp  $0x0,%al
651 jnz  timer
652 rol  $0x10,%eax
653 dec  %ax
654 cmp  $0x0,%ax;
655 rol  $0x10,%eax
656 jnz  timer
657 // timer
658
659 in   $0x61,%al
660 and  $0xfc,%al
661 out  %al,$0x61
662 jmp  *subroutinereg
663
664 dohelp:
665 mov $cmds,resultreg
666 mov $readcommand,subroutinereg
667 jmp displaystring
668
669 memt:
670 movl $memt1, subroutinereg
671 jmp  readnibbles
672 memt1:
673 mov  resultreg,%ecx
674 movl $memt2, subroutinereg
675 jmp  readnibbles
676 memt2:
677 mov  resultreg,%ebx
678 xchg %ecx,%eax
679 mov  $readcommand,%esp   // internal to linux bios
680 jmp ramtest
681
682 pcirb:
683 movl $pcirb1, subroutinereg
684 jmp  readnibbles
685 pcirb1:
686 mov  resultreg,%eax
687 PCI_READ_CONFIG_BYTE
688 and  $0xff,%eax
689 mov  %eax,resultreg
690 mov  $readcommand,subroutinereg
691 jmp  displayhex
692
693 pcirw:
694 movl $pcirw1, subroutinereg
695 jmp  readnibbles
696 pcirw1:
697 mov  resultreg,%eax
698 PCI_READ_CONFIG_WORD
699 and  $0xffff,%eax
700 mov  %eax,resultreg
701 mov  $readcommand,subroutinereg
702 jmp  displayhex
703
704 pcirl:
705 movl $pcirl1, subroutinereg
706 jmp  readnibbles
707 pcirl1:
708 mov  resultreg,%eax
709 PCI_READ_CONFIG_DWORD
710 mov  %eax,resultreg
711 mov  $readcommand,subroutinereg
712 jmp  displayhex
713
714
715
716
717 pciwb:
718 movl $pciwb1, subroutinereg
719 jmp  readnibbles
720 pciwb1:
721 mov  resultreg,%ebx
722 movl $pciwb2, subroutinereg
723 jmp  readnibbles
724 pciwb2:
725 mov  resultreg,%edx
726 mov  %ebx,%eax
727 PCI_WRITE_CONFIG_BYTE
728 jmp  readcommand
729
730 pciww:
731 movl $pciww1, subroutinereg
732 jmp  readnibbles
733 pciww1:
734 mov  resultreg,%ebx
735 movl $pciww2, subroutinereg
736 jmp  readnibbles
737 pciww2:
738 mov  resultreg,%ecx
739 mov  %ebx,%eax
740 PCI_WRITE_CONFIG_WORD
741 jmp  readcommand
742
743 pciwl:
744 movl $pciwl1, subroutinereg
745 jmp  readnibbles
746 pciwl1:
747 mov  resultreg,%ebx
748 movl $pciwl2, subroutinereg
749 jmp  readnibbles
750 pciwl2:
751 mov  resultreg,%ecx
752 mov  %ebx,%eax
753 PCI_WRITE_CONFIG_DWORD
754 jmp  readcommand
755
756 cram:
757 //likely not working.  Just testing for now
758 movl $cram1, subroutinereg
759 jmp  readnibbles
760 cram1:
761 mov resultreg,%ebx
762 movl $cram1, subroutinereg
763 jmp  readnibbles
764 cram2:
765 mov resultreg,%ecx
766 // enable it
767 mov %cr0,%eax
768 and $0x9fffffff,%eax  // also try 0x0fff, 0x2ff(write back)...
769 mov %eax,%cr0
770 //wbinvd ??
771 cacheloop:
772 mov (%ebx),%eax
773 inc %ebx
774 loop cacheloop
775 // disable it
776 mov %cr0,%eax
777 or  $0x60000000,%eax
778 mov %eax,%cr0
779 //wbinvd ??
780
781 dodl:
782 movl $dl1, subroutinereg
783 jmp  readnibbles
784 dl1:
785 mov  resultreg,%ebx
786 movl $dl2, subroutinereg
787 jmp  readnibbles
788 dl2:
789 mov  resultreg,%ecx
790 mov  resultreg,subroutinereg
791 mov  %ebx,resultreg
792 dlloop:
793 mov  UART_BASEADDR+5,%dx
794 in   %dx, %al
795 and  $0x9f,%al
796 test $0x01,%al
797 jz   dlloop
798 mov  UART_BASEADDR,%dx
799 in   %dx,%al
800 mov  %al,(%ebx)
801 inc  %ebx
802 loop dlloop
803 csum:
804 mov subroutinereg,%ecx
805 shr $0x02,%ecx
806 mov resultreg,%ebx
807 mov $0x0,%eax
808 csumloop:
809 rol $0x03,%eax
810 mov (%ebx),%dl
811 xor  %dl,%al
812 inc  %ebx
813 loop csumloop
814 mov $readcommand,subroutinereg
815 mov %eax,resultreg
816 jmp displayhex
817
818 baud:
819 mov $sorry,resultreg
820 mov $readcommand,subroutinereg
821 jmp displaystring
822
823 mcp:
824 movl $mcp1, subroutinereg
825 jmp  readnibbles
826 mcp1:
827 mov  resultreg,%ebx
828 movl $mcp2, subroutinereg
829 jmp  readnibbles
830 mcp2:
831 mov  resultreg,%ecx
832 movl $mcp3, subroutinereg
833 jmp  readnibbles
834 mcp3:
835 mov  resultreg,%eax
836 xchg %ecx,%eax
837 mcploop:
838 mov  (%ebx),%dl
839 mov  %dl,(%eax)
840 inc  %ebx
841 inc  %eax
842 loop mcploop
843 jmp  readcommand
844
845 dopattern:
846 movl $pat1, subroutinereg
847 jmp  readnibbles
848 pat1:
849 mov  resultreg,%ebx
850 movl $pat2, subroutinereg
851 jmp  readnibbles
852 pat2:
853 mov  resultreg,%ecx
854 movl $pat3, subroutinereg
855 jmp  readnibbles
856 pat3:
857 mov  resultreg,%eax
858 xchg %ecx,%eax
859 patloop:
860 rol $0x08,%ebx
861 mov %bl,(%eax)
862 inc %eax
863 loop patloop
864 jmp readcommand
865
866
867 doexit:
868          // LB specific:
869 RETSP    // if there's no stack yet, caller must set %esp manually
870 // RET_LABEL(low_level_shell)
871
872
873 //Linux OS Specific
874 ioperms:
875 movl    $sys_IOPL, %eax         # system-call ID-number
876 movl    $3, %ebx                # new value for IO0PL
877 int     $0x80                   # enter the kernel
878 ret
879
880 llshell_out: