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