]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc64/l.s
devip: cleanup rudp.c
[plan9front.git] / sys / src / 9 / pc64 / l.s
1 #include "mem.h"
2
3 MODE $32
4
5 #define DELAY           BYTE $0xEB; BYTE $0x00  /* JMP .+2 */
6
7 #define pFARJMP32(s, o) BYTE $0xea;             /* far jump to ptr32:16 */\
8                         LONG $o; WORD $s
9
10 /*
11  * Enter here in 32-bit protected mode. Welcome to 1982.
12  * Make sure the GDT is set as it should be:
13  *      disable interrupts;
14  *      load the GDT with the table in _gdt32p;
15  *      load all the data segments
16  *      load the code segment via a far jump.
17  */
18 TEXT _protected<>(SB), 1, $-4
19         CLI
20
21         MOVL    $_gdtptr32p<>-KZERO(SB), AX
22         MOVL    (AX), GDTR
23
24         MOVL    $SELECTOR(2, SELGDT, 0), AX
25         MOVW    AX, DS
26         MOVW    AX, ES
27         MOVW    AX, FS
28         MOVW    AX, GS
29         MOVW    AX, SS
30
31         pFARJMP32(SELECTOR(3, SELGDT, 0), _warp64<>-KZERO(SB))
32
33         BYTE    $0x90   /* align */
34
35 /*
36  * Must be 4-byte aligned.
37  */
38 TEXT _multibootheader<>(SB), 1, $-4
39         LONG    $0x1BADB002                     /* magic */
40         LONG    $0x00010007                     /* flags */
41         LONG    $-(0x1BADB002 + 0x00010007)     /* checksum */
42         LONG    $_multibootheader<>-KZERO(SB)   /* header_addr */
43         LONG    $_protected<>-KZERO(SB)         /* load_addr */
44         LONG    $edata-KZERO(SB)                /* load_end_addr */
45         LONG    $end-KZERO(SB)                  /* bss_end_addr */
46         LONG    $_multibootentry<>-KZERO(SB)    /* entry_addr */
47         LONG    $0                              /* mode_type */
48         LONG    $0                              /* width */
49         LONG    $0                              /* height */
50         LONG    $32                             /* depth */
51
52 /* 
53  * the kernel expects the data segment to be page-aligned
54  * multiboot bootloaders put the data segment right behind text
55  */
56 TEXT _multibootentry<>(SB), 1, $-4
57         MOVL    $etext-KZERO(SB), SI
58         MOVL    SI, DI
59         ADDL    $(BY2PG-1), DI
60         ANDL    $~(BY2PG-1), DI
61         MOVL    $edata-KZERO(SB), CX
62         SUBL    DI, CX
63         ADDL    CX, SI
64         ADDL    CX, DI
65         INCL    CX      /* one more for post decrement */
66         STD
67         REP; MOVSB
68         MOVL    BX, multibootptr-KZERO(SB)
69         MOVL    $_protected<>-KZERO(SB), AX
70         JMP*    AX
71
72 /* multiboot structure pointer (physical address) */
73 TEXT multibootptr(SB), 1, $-4
74         LONG    $0
75
76 TEXT _gdt<>(SB), 1, $-4
77         /* null descriptor */
78         LONG    $0
79         LONG    $0
80
81         /* (KESEG) 64 bit long mode exec segment */
82         LONG    $(0xFFFF)
83         LONG    $(SEGL|SEGG|SEGP|(0xF<<16)|SEGPL(0)|SEGEXEC|SEGR)
84
85         /* 32 bit data segment descriptor for 4 gigabytes (PL 0) */
86         LONG    $(0xFFFF)
87         LONG    $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
88
89         /* 32 bit exec segment descriptor for 4 gigabytes (PL 0) */
90         LONG    $(0xFFFF)
91         LONG    $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
92
93
94 TEXT _gdtptr32p<>(SB), 1, $-4
95         WORD    $(4*8-1)
96         LONG    $_gdt<>-KZERO(SB)
97
98 TEXT _gdtptr64p<>(SB), 1, $-4
99         WORD    $(4*8-1)
100         QUAD    $_gdt<>-KZERO(SB)
101
102 TEXT _gdtptr64v<>(SB), 1, $-4
103         WORD    $(4*8-1)
104         QUAD    $_gdt<>(SB)
105
106 /*
107  * Macros for accessing page table entries; change the
108  * C-style array-index macros into a page table byte offset
109  */
110 #define PML4O(v)        ((PTLX((v), 3))<<3)
111 #define PDPO(v)         ((PTLX((v), 2))<<3)
112 #define PDO(v)          ((PTLX((v), 1))<<3)
113 #define PTO(v)          ((PTLX((v), 0))<<3)
114
115 TEXT _warp64<>(SB), 1, $-4
116
117         /* clear mach and page tables */
118         MOVL    $((CPU0END-CPU0PML4)>>2), CX
119         MOVL    $(CPU0PML4-KZERO), SI
120         MOVL    SI, DI
121         XORL    AX, AX
122         CLD
123         REP;    STOSL
124
125         MOVL    SI, AX                          /* PML4 */
126         MOVL    AX, DX
127         ADDL    $(PTSZ|PTEWRITE|PTEVALID), DX   /* PDP at PML4 + PTSZ */
128         MOVL    DX, PML4O(0)(AX)                /* PML4E for double-map */
129         MOVL    DX, PML4O(KZERO)(AX)            /* PML4E for KZERO */
130
131         ADDL    $PTSZ, AX                       /* PDP at PML4 + PTSZ */
132         ADDL    $PTSZ, DX                       /* PD0 at PML4 + 2*PTSZ */
133         MOVL    DX, PDPO(0)(AX)                 /* PDPE for double-map */
134         MOVL    DX, PDPO(KZERO)(AX)             /* PDPE for KZERO */
135
136         /*
137          * add PDPE for KZERO+1GB early as Vmware
138          * hangs when modifying kernel PDP
139          */
140         ADDL    $PTSZ, DX                       /* PD1 */
141         MOVL    DX, PDPO(KZERO+GiB)(AX)
142
143         ADDL    $PTSZ, AX                       /* PD0 at PML4 + 2*PTSZ */
144         MOVL    $(PTESIZE|PTEGLOBAL|PTEWRITE|PTEVALID), DX
145         MOVL    DX, PDO(0)(AX)                  /* PDE for double-map */
146
147         /*
148          * map from KZERO to end using 2MB pages
149          */
150         ADDL    $PDO(KZERO), AX
151         MOVL    $end-KZERO(SB), CX
152
153         ADDL    $(16*1024), CX                  /* qemu puts multiboot data after the kernel */
154
155         ADDL    $(PGLSZ(1)-1), CX
156         ANDL    $~(PGLSZ(1)-1), CX
157         MOVL    CX, MemMin-KZERO(SB)            /* see memory.c */
158         SHRL    $(1*PTSHIFT+PGSHIFT), CX
159 memloop:
160         MOVL    DX, (AX)
161         ADDL    $PGLSZ(1), DX
162         ADDL    $8, AX
163         LOOP    memloop
164
165 /*
166  * Enable and activate Long Mode. From the manual:
167  *      make sure Page Size Extentions are off, and Page Global
168  *      Extensions and Physical Address Extensions are on in CR4;
169  *      set Long Mode Enable in the Extended Feature Enable MSR;
170  *      set Paging Enable in CR0;
171  *      make an inter-segment jump to the Long Mode code.
172  * It's all in 32-bit mode until the jump is made.
173  */
174 TEXT _lme<>(SB), 1, $-4
175         MOVL    SI, CR3                         /* load the mmu */
176         DELAY
177
178         MOVL    CR4, AX
179         ANDL    $~0x00000010, AX                        /* Page Size */
180         ORL     $0x000000A0, AX                 /* Page Global, Phys. Address */
181         MOVL    AX, CR4
182
183         MOVL    $0xc0000080, CX                 /* Extended Feature Enable */
184         RDMSR
185         ORL     $0x00000100, AX                 /* Long Mode Enable */
186         WRMSR
187
188         MOVL    CR0, DX
189         ANDL    $~0x6000000a, DX
190         ORL     $0x80010000, DX                 /* Paging Enable, Write Protect */
191         MOVL    DX, CR0
192
193         pFARJMP32(SELECTOR(KESEG, SELGDT, 0), _identity<>-KZERO(SB))
194
195 /*
196  * Long mode. Welcome to 2003.
197  * Jump out of the identity map space;
198  * load a proper long mode GDT.
199  */
200 MODE $64
201
202 TEXT _identity<>(SB), 1, $-4
203         MOVQ    $_start64v<>(SB), AX
204         JMP*    AX
205
206 TEXT _start64v<>(SB), 1, $-4
207         MOVQ    $_gdtptr64v<>(SB), AX
208         MOVL    (AX), GDTR
209
210         XORQ    AX, AX
211         MOVW    AX, DS                          /* not used in long mode */
212         MOVW    AX, ES                          /* not used in long mode */
213         MOVW    AX, FS
214         MOVW    AX, GS
215         MOVW    AX, SS                          /* not used in long mode */
216
217         MOVW    AX, LDTR
218
219         MOVQ    $(CPU0MACH+MACHSIZE), SP
220         MOVQ    $(CPU0MACH), RMACH
221         MOVQ    AX, RUSER                       /* up = 0; */
222
223 _clearbss:
224         MOVQ    $edata(SB), DI
225         MOVQ    $end(SB), CX
226         SUBQ    DI, CX                          /* end-edata bytes */
227         SHRQ    $2, CX                          /* end-edata doublewords */
228
229         CLD
230         REP;    STOSL                           /* clear BSS */
231
232         PUSHQ   AX                              /* clear flags */
233         POPFQ
234
235         CALL    main(SB)
236
237 /*
238  * Park a processor. Should never fall through a return from main to here,
239  * should only be called by application processors when shutting down.
240  */
241 TEXT idle(SB), 1, $-4
242 _idle:
243         STI
244         HLT
245         JMP     _idle
246
247 /*
248  * The CPUID instruction is always supported on the amd64.
249  */
250 TEXT cpuid(SB), $-4
251         MOVL    RARG, AX                        /* function in AX */
252         CPUID
253
254         MOVQ    info+8(FP), BP
255         MOVL    AX, 0(BP)
256         MOVL    BX, 4(BP)
257         MOVL    CX, 8(BP)
258         MOVL    DX, 12(BP)
259         RET
260
261 /*
262  * Port I/O.
263  */
264 TEXT inb(SB), 1, $-4
265         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
266         XORL    AX, AX
267         INB
268         RET
269
270 TEXT insb(SB), 1, $-4
271         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
272         MOVQ    address+8(FP), DI
273         MOVL    count+16(FP), CX
274         CLD
275         REP;    INSB
276         RET
277
278 TEXT ins(SB), 1, $-4
279         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
280         XORL    AX, AX
281         INW
282         RET
283
284 TEXT inss(SB), 1, $-4
285         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
286         MOVQ    address+8(FP), DI
287         MOVL    count+16(FP), CX
288         CLD
289         REP;    INSW
290         RET
291
292 TEXT inl(SB), 1, $-4
293         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
294         INL
295         RET
296
297 TEXT insl(SB), 1, $-4
298         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
299         MOVQ    address+8(FP), DI
300         MOVL    count+16(FP), CX
301         CLD
302         REP; INSL
303         RET
304
305 TEXT outb(SB), 1, $-1
306         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
307         MOVL    byte+8(FP), AX
308         OUTB
309         RET
310
311 TEXT outsb(SB), 1, $-4
312         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
313         MOVQ    address+8(FP), SI
314         MOVL    count+16(FP), CX
315         CLD
316         REP; OUTSB
317         RET
318
319 TEXT outs(SB), 1, $-4
320         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
321         MOVL    short+8(FP), AX
322         OUTW
323         RET
324
325 TEXT outss(SB), 1, $-4
326         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
327         MOVQ    address+8(FP), SI
328         MOVL    count+16(FP), CX
329         CLD
330         REP; OUTSW
331         RET
332
333 TEXT outl(SB), 1, $-4
334         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
335         MOVL    long+8(FP), AX
336         OUTL
337         RET
338
339 TEXT outsl(SB), 1, $-4
340         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
341         MOVQ    address+8(FP), SI
342         MOVL    count+16(FP), CX
343         CLD
344         REP; OUTSL
345         RET
346
347 TEXT getgdt(SB), 1, $-4
348         MOVQ    RARG, AX
349         MOVL    GDTR, (AX)                      /* Note: 10 bytes returned */
350         RET
351
352 TEXT lgdt(SB), $0                               /* GDTR - global descriptor table */
353         MOVQ    RARG, AX
354         MOVL    (AX), GDTR
355         RET
356
357 TEXT lidt(SB), $0                               /* IDTR - interrupt descriptor table */
358         MOVQ    RARG, AX
359         MOVL    (AX), IDTR
360         RET
361
362 TEXT ltr(SB), 1, $-4
363         MOVW    RARG, AX
364         MOVW    AX, TASK
365         RET
366
367 /*
368  * Read/write various system registers.
369  */
370 TEXT getcr0(SB), 1, $-4                         /* Processor Control */
371         MOVQ    CR0, AX
372         RET
373
374 TEXT putcr0(SB), 1, $-4
375         MOVQ    RARG, CR0
376         RET
377
378 TEXT getcr2(SB), 1, $-4                         /* #PF Linear Address */
379         MOVQ    CR2, AX
380         RET
381
382 TEXT putcr2(SB), 1, $-4
383         MOVQ    BP, CR2
384         RET
385
386 TEXT getcr3(SB), 1, $-4                         /* PML4 Base */
387         MOVQ    CR3, AX
388         RET
389
390 TEXT putcr3(SB), 1, $-4
391         MOVQ    RARG, CR3
392         RET
393
394 TEXT getcr4(SB), 1, $-4                         /* Extensions */
395         MOVQ    CR4, AX
396         RET
397
398 TEXT putcr4(SB), 1, $-4
399         MOVQ    RARG, CR4
400         RET
401
402 TEXT mb386(SB), 1, $-4                          /* hack */
403 TEXT mb586(SB), 1, $-4
404         XORL    AX, AX
405         CPUID
406         RET
407
408 /*
409  * BIOS32.
410  */
411 TEXT bios32call(SB), 1, $-4
412         XORL    AX, AX
413         INCL    AX
414         RET
415
416 /*
417  * Basic timing loop to determine CPU frequency.
418  */
419 TEXT aamloop(SB), 1, $-4
420         MOVL    RARG, CX
421 _aamloop:
422         LOOP    _aamloop
423         RET
424
425 TEXT _cycles(SB), 1, $-4                        /* time stamp counter */
426         RDTSC
427         MOVL    AX, 0(RARG)                     /* lo */
428         MOVL    DX, 4(RARG)                     /* hi */
429         RET
430
431 TEXT rdmsr(SB), 1, $-4                          /* Model-Specific Register */
432         MOVL    RARG, CX
433         MOVQ    $0, BP
434 TEXT _rdmsrinst(SB), $0
435         RDMSR
436         MOVQ    vlong+8(FP), CX                 /* &vlong */
437         MOVL    AX, 0(CX)                       /* lo */
438         MOVL    DX, 4(CX)                       /* hi */
439         MOVQ    BP, AX                          /* BP set to -1 if traped */
440         RET
441         
442 TEXT wrmsr(SB), 1, $-4
443         MOVL    RARG, CX
444         MOVL    lo+8(FP), AX
445         MOVL    hi+12(FP), DX
446         MOVQ    $0, BP
447 TEXT _wrmsrinst(SB), $0
448         WRMSR
449         MOVQ    BP, AX                          /* BP set to -1 if traped */
450         RET
451
452 TEXT invlpg(SB), 1, $-4
453         INVLPG  (RARG)
454         RET
455
456 TEXT wbinvd(SB), 1, $-4
457         WBINVD
458         RET
459
460 /*
461  * Serialisation.
462  */
463 TEXT lfence(SB), 1, $-4
464         LFENCE
465         RET
466
467 TEXT mfence(SB), 1, $-4
468         MFENCE
469         RET
470
471 TEXT sfence(SB), 1, $-4
472         SFENCE
473         RET
474
475 /*
476  * Note: CLI and STI are not serialising instructions.
477  * Is that assumed anywhere?
478  */
479 TEXT splhi(SB), 1, $-4
480 _splhi:
481         PUSHFQ
482         POPQ    AX
483         TESTQ   $0x200, AX                      /* 0x200 - Interrupt Flag */
484         JZ      _alreadyhi                      /* use CMOVLEQ etc. here? */
485
486         MOVQ    (SP), BX
487         MOVQ    BX, 8(RMACH)                    /* save PC in m->splpc */
488
489 _alreadyhi:
490         CLI
491         RET
492
493 TEXT spllo(SB), 1, $-4
494 _spllo:
495         PUSHFQ
496         POPQ    AX
497         TESTQ   $0x200, AX                      /* 0x200 - Interrupt Flag */
498         JNZ     _alreadylo                      /* use CMOVLEQ etc. here? */
499
500         MOVQ    $0, 8(RMACH)                    /* clear m->splpc */
501
502 _alreadylo:
503         STI
504         RET
505
506 TEXT splx(SB), 1, $-4
507         TESTQ   $0x200, RARG                    /* 0x200 - Interrupt Flag */
508         JNZ     _spllo
509         JMP     _splhi
510
511 TEXT spldone(SB), 1, $-4
512         RET
513
514 TEXT islo(SB), 1, $-4
515         PUSHFQ
516         POPQ    AX
517         ANDQ    $0x200, AX                      /* 0x200 - Interrupt Flag */
518         RET
519
520 /*
521  * Synchronisation
522  */
523 TEXT tas(SB), 1, $-4
524 TEXT _tas(SB), 1, $-4
525         MOVL    $0xdeaddead, AX
526         XCHGL   AX, (RARG)                      /*  */
527         RET
528
529 TEXT cmpswap486(SB), 1, $-4
530 TEXT cas(SB), 1, $-4
531         MOVL    exp+8(FP), AX
532         MOVL    new+16(FP), BX
533         LOCK; CMPXCHGL BX, (RARG)
534         MOVL    $1, AX                          /* use CMOVLEQ etc. here? */
535         JNZ     _cas32r0
536 _cas32r1:
537         RET
538 _cas32r0:
539         DECL    AX
540         RET
541
542 /*
543  * Label consists of a stack pointer and a programme counter
544  */
545 TEXT gotolabel(SB), 1, $-4
546         MOVQ    0(RARG), SP                     /* restore SP */
547         MOVQ    8(RARG), AX                     /* put return PC on the stack */
548         MOVQ    AX, 0(SP)
549         MOVL    $1, AX                          /* return 1 */
550         RET
551
552 TEXT setlabel(SB), 1, $-4
553         MOVQ    SP, 0(RARG)                     /* store SP */
554         MOVQ    0(SP), BX                       /* store return PC */
555         MOVQ    BX, 8(RARG)
556         MOVL    $0, AX                          /* return 0 */
557         RET
558
559 TEXT halt(SB), 1, $-4
560         CLI
561         CMPL    nrdy(SB), $0
562         JEQ     _nothingready
563         STI
564         RET
565 _nothingready:
566         STI
567         HLT
568         RET
569
570 TEXT mwait(SB), 1, $-4
571         MOVQ    RARG, AX
572         MOVL    (AX), CX
573         ORL     CX, CX
574         JNZ     _mwaitdone
575         XORL    DX, DX
576         BYTE $0x0f; BYTE $0x01; BYTE $0xc8      /* MONITOR */
577         MOVL    (AX), CX
578         ORL     CX, CX
579         JNZ     _mwaitdone
580         XORL    AX, AX
581         BYTE $0x0f; BYTE $0x01; BYTE $0xc9      /* MWAIT */
582 _mwaitdone:
583         RET
584
585 /*
586  * SIMD Floating Point.
587  * Note: for x87 instructions which have both a 'wait' and 'nowait' version,
588  * 8a only knows the 'wait' mnemonic but does NOT insertthe WAIT prefix byte
589  * (i.e. they act like their FNxxx variations) so WAIT instructions must be
590  * explicitly placed in the code if necessary.
591  */
592 TEXT _clts(SB), 1, $-4
593         CLTS
594         RET
595
596 TEXT _fldcw(SB), 1, $-4                         /* Load x87 FPU Control Word */
597         MOVQ    RARG, cw+0(FP)
598         FLDCW   cw+0(FP)
599         RET
600
601 TEXT _fnclex(SB), 1, $-4
602         FCLEX
603         RET
604
605 TEXT _fninit(SB), 1, $-4
606         FINIT                                   /* no WAIT */
607         RET
608
609 TEXT _fxrstor(SB), 1, $-4
610         FXRSTOR64 (RARG)
611         RET
612
613 TEXT _fxsave(SB), 1, $-4
614         FXSAVE64 (RARG)
615         RET
616
617 TEXT _fwait(SB), 1, $-4
618         WAIT
619         RET
620
621 TEXT _ldmxcsr(SB), 1, $-4                       /* Load MXCSR */
622         MOVQ    RARG, mxcsr+0(FP)
623         LDMXCSR mxcsr+0(FP)
624         RET
625
626 TEXT _stts(SB), 1, $-4
627         MOVQ    CR0, AX
628         ORQ     $8, AX                          /* Ts */
629         MOVQ    AX, CR0
630         RET
631
632 TEXT mul64fract(SB), 1, $-4
633         MOVQ    a+8(FP), AX
634         MULQ    b+16(FP)                        /* a*b */
635         SHRQ    $32, AX:DX
636         MOVQ    AX, (RARG)
637         RET
638
639 #define RDRANDAX        BYTE $0x0f; BYTE $0xc7; BYTE $0xf0
640 #define RDRAND64AX      BYTE $0x48; BYTE $0x0f; BYTE $0xc7;  BYTE $0xf0
641
642 TEXT rdrand32(SB), $-4
643 loop32:
644         RDRANDAX
645         JCC             loop32
646         RET
647
648 TEXT rdrand64(SB), $-4
649 loop64:
650         RDRAND64AX
651         JCC             loop64
652         RET
653
654 TEXT rdrandbuf(SB), $0
655         MOVQ    RARG, DX
656
657         MOVLQZX cnt+8(FP), CX
658         SHRQ    $3, CX
659 eights:
660         CMPL    CX, $0
661         JLE     f1
662         CALL    rdrand64(SB)
663         MOVQ    AX, 0(DX)
664         ADDQ    $8, DX
665         SUBL    $1, CX
666         JMP     eights
667
668 f1:
669         MOVLQZX cnt+8(FP), CX
670         ANDL    $7, CX
671         SHRQ    $2, CX
672 fours:
673         CMPL    CX, $0
674         JLE     f2
675         CALL    rdrand32(SB)
676         MOVL    AX, 0(DX)
677         ADDQ    $4, DX
678         SUBL    $1, CX
679         JMP     fours
680
681 f2:
682         MOVLQZX cnt+8(FP), CX
683         ANDL    $3, CX
684 ones:
685         CMPL    CX, $0
686         JLE     f3
687         CALL    rdrand32(SB)
688         MOVB    AX, 0(DX)
689         ADDQ    $1, DX
690         SUBL    $1, CX
691         JMP     ones
692
693 f3:
694         RET
695
696 /* debug register access */
697
698 TEXT putdr(SB), 1, $-4
699         MOVQ    56(BP), AX
700         MOVQ    AX, DR7
701         /* wet floor */
702 TEXT putdr01236(SB), 1, $-4
703         MOVQ    0(BP), AX
704         MOVQ    AX, DR0
705         MOVQ    8(BP), AX
706         MOVQ    AX, DR1
707         MOVQ    16(BP), AX
708         MOVQ    AX, DR2
709         MOVQ    24(BP), AX
710         MOVQ    AX, DR3
711         MOVQ    48(BP), AX
712         MOVQ    AX, DR6
713         RET
714
715 TEXT getdr6(SB), 1, $-4
716         MOVQ    DR6, AX
717         RET
718
719 TEXT putdr6(SB), 1, $-4
720         MOVQ    BP, DR6
721         RET
722
723 TEXT putdr7(SB), 1, $-4
724         MOVQ    BP, DR7
725         RET
726
727 /* VMX instructions */
728 TEXT vmxon(SB), 1, $-4
729         MOVQ    BP, 8(SP)
730         /* VMXON 8(SP) */
731         BYTE    $0xf3; BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x08
732         JMP     _vmout
733
734 TEXT vmxoff(SB), 1, $-4
735         BYTE    $0x0f; BYTE $0x01; BYTE $0xc4
736         JMP     _vmout
737
738 TEXT vmclear(SB), 1, $-4
739         MOVQ    BP, 8(SP)
740         /* VMCLEAR 8(SP) */
741         BYTE    $0x66;  BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x08
742         JMP     _vmout
743
744 TEXT vmlaunch(SB), 1, $-4
745         MOVL    $0x6C14, DI
746         MOVQ    SP, DX
747         BYTE    $0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
748         JBE     _vmout
749         MOVL    $0x6C16, DI
750         MOVQ    $vmrestore(SB), DX
751         BYTE    $0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
752         JBE     _vmout
753         
754         MOVQ    BP, ureg+0(FP)
755         MOVL    resume+8(FP), AX
756         TESTL   AX, AX
757         MOVQ    0x00(BP), AX
758         MOVQ    0x08(BP), BX
759         MOVQ    0x10(BP), CX
760         MOVQ    0x18(BP), DX
761         MOVQ    0x20(BP), SI
762         MOVQ    0x28(BP), DI
763         MOVQ    0x38(BP), R8
764         MOVQ    0x40(BP), R9
765         MOVQ    0x48(BP), R10
766         MOVQ    0x50(BP), R11
767         MOVQ    0x58(BP), R12
768         MOVQ    0x60(BP), R13
769         MOVQ    0x68(BP), R14
770         MOVQ    0x70(BP), R15
771         MOVQ    0x30(BP), BP
772         JNE     _vmresume
773         BYTE    $0x0f; BYTE $0x01; BYTE $0xc2 /* VMLAUNCH */
774         JMP     _vmout
775 _vmresume:
776         BYTE    $0x0f; BYTE $0x01; BYTE $0xc3 /* VMRESUME */
777         JMP _vmout
778         
779 TEXT vmrestore(SB), 1, $-4
780         PUSHQ   BP
781         MOVQ    ureg+0(FP), BP
782         MOVQ    AX, 0x00(BP)
783         MOVQ    BX, 0x08(BP)
784         MOVQ    CX, 0x10(BP)
785         MOVQ    DX, 0x18(BP)
786         MOVQ    SI, 0x20(BP)
787         MOVQ    DI, 0x28(BP)
788         POPQ    0x30(BP)
789         MOVQ    R8, 0x38(BP)
790         MOVQ    R9, 0x40(BP)
791         MOVQ    R10, 0x48(BP)
792         MOVQ    R11, 0x50(BP)
793         MOVQ    R12, 0x58(BP)
794         MOVQ    R13, 0x60(BP)
795         MOVQ    R14, 0x68(BP)
796         MOVQ    R15, 0x70(BP)
797         
798         BYTE    $0x65; MOVQ 0, RMACH /* MOVQ GS:(0), RMACH */
799         MOVQ    16(RMACH), RUSER
800         XORL    AX, AX
801         RET
802
803 TEXT vmptrld(SB), 1, $-4
804         MOVQ    BP, 8(SP)
805         /* VMMPTRLD 8(SP) */
806         BYTE    $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x08
807         JMP _vmout
808
809 TEXT vmwrite(SB), 1, $-4
810         MOVQ    val+8(FP), DX
811         /* VMWRITE DX, BP */
812         BYTE    $0x0f; BYTE $0x79; BYTE $0xea
813         JMP _vmout
814
815 TEXT vmread(SB), 1, $-4
816         MOVQ    valp+8(FP), DI
817         /* VMREAD BP, (DI) */
818         BYTE    $0x0f; BYTE $0x78; BYTE $0x2f
819         JMP _vmout
820
821 TEXT invept(SB), 1, $-4
822         /* INVEPT BP, 16(SP) */
823         BYTE    $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x80; BYTE $0x6c; BYTE $0x24; BYTE $0x10
824         JMP _vmout
825
826 TEXT invvpid(SB), 1, $-4
827         /* INVVPID BP, 16(SP) */
828         BYTE    $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x81; BYTE $0x6c; BYTE $0x24; BYTE $0x10
829         JMP _vmout
830
831 _vmout:
832         JC      _vmout1
833         JZ      _vmout2
834         XORL    AX, AX
835         RET
836 _vmout1:
837         MOVQ    $-1, AX
838         RET
839 _vmout2:
840         MOVQ    $-2, AX
841         RET
842
843 /*
844  */
845 TEXT touser(SB), 1, $-4
846         CLI
847         SWAPGS
848
849         MOVL    $0, RMACH
850         MOVL    $0, RUSER
851
852         MOVQ    $(UTZERO+0x28), CX              /* ip */
853         MOVL    $0x200, R11                     /* flags */
854         MOVQ    RARG, SP                        /* sp */
855
856         BYTE $0x48; SYSRET                      /* SYSRETQ */
857
858 /*
859  */
860 TEXT syscallentry(SB), 1, $-4
861         SWAPGS
862         BYTE $0x65; MOVQ 0, AX                  /* m-> (MOVQ GS:0x0, AX) */
863         MOVQ    16(AX), BX                      /* m->proc */
864         MOVQ    SP, R13
865         MOVQ    16(BX), SP                      /* m->proc->kstack */
866         ADDQ    $KSTACK, SP
867
868         PUSHQ   $UDSEL                          /* old stack segment */
869         PUSHQ   R13                             /* old sp */
870         PUSHQ   R11                             /* old flags */
871         PUSHQ   $UESEL                          /* old code segment */
872         PUSHQ   CX                              /* old ip */
873         PUSHQ   $0                              /* error code */
874         PUSHQ   $64                             /* trap number (VectorSYSCALL) */
875
876         SUBQ    $(8 + 23*8-7*8), SP             /* arg + sizeof(Ureg)-pushed */
877
878         MOVQ    RMACH, (15*8)(SP)               /* old r15 */
879         MOVQ    RUSER, (14*8)(SP)               /* old r14 */
880
881         MOVQ    RARG, (7*8)(SP)                 /* system call number */
882
883         MOVQ    AX, RMACH                       /* m */
884         MOVQ    BX, RUSER                       /* up */
885
886         LEAQ    8(SP), RARG                     /* Ureg* arg */
887
888         CALL    syscall(SB)
889
890 TEXT forkret(SB), 1, $-4
891         CLI
892         SWAPGS
893
894         MOVQ    8(SP), AX                       /* return value */
895
896         MOVQ    (15*8)(SP), RMACH               /* r15 */
897         MOVQ    (14*8)(SP), RUSER               /* r14 */
898
899         MOVQ    (19*8)(SP), CX                  /* ip */
900         MOVQ    (21*8)(SP), R11                 /* flags */
901         MOVQ    (22*8)(SP), SP                  /* sp */
902
903         BYTE $0x48; SYSRET                      /* SYSRETQ */
904
905 /*
906  * Interrupt/exception handling.
907  */
908
909 TEXT _strayintr(SB), 1, $-4                     /* no error code pushed */
910         PUSHQ   AX                              /* save AX */
911         MOVQ    8(SP), AX                       /* vectortable(SB) PC */
912         JMP     _intrcommon
913
914 TEXT _strayintrx(SB), 1, $-4                    /* error code pushed */
915         XCHGQ   AX, (SP)
916 _intrcommon:
917         MOVBQZX (AX), AX
918         XCHGQ   AX, (SP)
919
920         SUBQ    $24, SP                         /* R1[45], [DEFG]S */
921         CMPW    48(SP), $KESEL                  /* old CS */
922         JEQ     _intrnested
923
924         MOVQ    RUSER, 0(SP)
925         MOVQ    RMACH, 8(SP)
926
927         SWAPGS
928         BYTE $0x65; MOVQ 0, RMACH               /* m-> (MOVQ GS:0x0, R15) */
929         MOVQ    16(RMACH), RUSER                /* up */
930
931 _intrnested:
932         PUSHQ   R13
933         PUSHQ   R12
934         PUSHQ   R11
935         PUSHQ   R10
936         PUSHQ   R9
937         PUSHQ   R8
938         PUSHQ   BP
939         PUSHQ   DI
940         PUSHQ   SI
941         PUSHQ   DX
942         PUSHQ   CX
943         PUSHQ   BX
944         PUSHQ   AX
945
946         MOVQ    SP, RARG
947         PUSHQ   SP
948         CALL    trap(SB)
949
950 TEXT _intrr(SB), 1, $-4
951 _intrestore:
952         POPQ    AX
953
954         POPQ    AX
955         POPQ    BX
956         POPQ    CX
957         POPQ    DX
958         POPQ    SI
959         POPQ    DI
960         POPQ    BP
961         POPQ    R8
962         POPQ    R9
963         POPQ    R10
964         POPQ    R11
965         POPQ    R12
966         POPQ    R13
967
968         CMPQ    48(SP), $KESEL
969         JEQ     _iretnested
970
971         SWAPGS
972
973         MOVQ    8(SP), RMACH
974         MOVQ    0(SP), RUSER
975
976 _iretnested:
977         ADDQ    $40, SP
978         IRETQ
979
980 TEXT noteret(SB), 1, $-4
981         CLI
982         JMP     _intrestore
983
984 TEXT vectortable(SB), $0
985         CALL _strayintr(SB); BYTE $0x00         /* divide error */
986         CALL _strayintr(SB); BYTE $0x01         /* debug exception */
987         CALL _strayintr(SB); BYTE $0x02         /* NMI interrupt */
988         CALL _strayintr(SB); BYTE $0x03         /* breakpoint */
989         CALL _strayintr(SB); BYTE $0x04         /* overflow */
990         CALL _strayintr(SB); BYTE $0x05         /* bound */
991         CALL _strayintr(SB); BYTE $0x06         /* invalid opcode */
992         CALL _strayintr(SB); BYTE $0x07         /* no coprocessor available */
993         CALL _strayintrx(SB); BYTE $0x08        /* double fault */
994         CALL _strayintr(SB); BYTE $0x09         /* coprocessor segment overflow */
995         CALL _strayintrx(SB); BYTE $0x0A        /* invalid TSS */
996         CALL _strayintrx(SB); BYTE $0x0B        /* segment not available */
997         CALL _strayintrx(SB); BYTE $0x0C        /* stack exception */
998         CALL _strayintrx(SB); BYTE $0x0D        /* general protection error */
999         CALL _strayintrx(SB); BYTE $0x0E        /* page fault */
1000         CALL _strayintr(SB); BYTE $0x0F         /*  */
1001         CALL _strayintr(SB); BYTE $0x10         /* coprocessor error */
1002         CALL _strayintrx(SB); BYTE $0x11        /* alignment check */
1003         CALL _strayintr(SB); BYTE $0x12         /* machine check */
1004         CALL _strayintr(SB); BYTE $0x13         /* simd error */
1005         CALL _strayintr(SB); BYTE $0x14
1006         CALL _strayintr(SB); BYTE $0x15
1007         CALL _strayintr(SB); BYTE $0x16
1008         CALL _strayintr(SB); BYTE $0x17
1009         CALL _strayintr(SB); BYTE $0x18
1010         CALL _strayintr(SB); BYTE $0x19
1011         CALL _strayintr(SB); BYTE $0x1A
1012         CALL _strayintr(SB); BYTE $0x1B
1013         CALL _strayintr(SB); BYTE $0x1C
1014         CALL _strayintr(SB); BYTE $0x1D
1015         CALL _strayintr(SB); BYTE $0x1E
1016         CALL _strayintr(SB); BYTE $0x1F
1017         CALL _strayintr(SB); BYTE $0x20         /* VectorLAPIC */
1018         CALL _strayintr(SB); BYTE $0x21
1019         CALL _strayintr(SB); BYTE $0x22
1020         CALL _strayintr(SB); BYTE $0x23
1021         CALL _strayintr(SB); BYTE $0x24
1022         CALL _strayintr(SB); BYTE $0x25
1023         CALL _strayintr(SB); BYTE $0x26
1024         CALL _strayintr(SB); BYTE $0x27
1025         CALL _strayintr(SB); BYTE $0x28
1026         CALL _strayintr(SB); BYTE $0x29
1027         CALL _strayintr(SB); BYTE $0x2A
1028         CALL _strayintr(SB); BYTE $0x2B
1029         CALL _strayintr(SB); BYTE $0x2C
1030         CALL _strayintr(SB); BYTE $0x2D
1031         CALL _strayintr(SB); BYTE $0x2E
1032         CALL _strayintr(SB); BYTE $0x2F
1033         CALL _strayintr(SB); BYTE $0x30
1034         CALL _strayintr(SB); BYTE $0x31
1035         CALL _strayintr(SB); BYTE $0x32
1036         CALL _strayintr(SB); BYTE $0x33
1037         CALL _strayintr(SB); BYTE $0x34
1038         CALL _strayintr(SB); BYTE $0x35
1039         CALL _strayintr(SB); BYTE $0x36
1040         CALL _strayintr(SB); BYTE $0x37
1041         CALL _strayintr(SB); BYTE $0x38
1042         CALL _strayintr(SB); BYTE $0x39
1043         CALL _strayintr(SB); BYTE $0x3A
1044         CALL _strayintr(SB); BYTE $0x3B
1045         CALL _strayintr(SB); BYTE $0x3C
1046         CALL _strayintr(SB); BYTE $0x3D
1047         CALL _strayintr(SB); BYTE $0x3E
1048         CALL _strayintr(SB); BYTE $0x3F
1049         CALL _strayintr(SB); BYTE $0x40         /* was VectorSYSCALL */
1050         CALL _strayintr(SB); BYTE $0x41
1051         CALL _strayintr(SB); BYTE $0x42
1052         CALL _strayintr(SB); BYTE $0x43
1053         CALL _strayintr(SB); BYTE $0x44
1054         CALL _strayintr(SB); BYTE $0x45
1055         CALL _strayintr(SB); BYTE $0x46
1056         CALL _strayintr(SB); BYTE $0x47
1057         CALL _strayintr(SB); BYTE $0x48
1058         CALL _strayintr(SB); BYTE $0x49
1059         CALL _strayintr(SB); BYTE $0x4A
1060         CALL _strayintr(SB); BYTE $0x4B
1061         CALL _strayintr(SB); BYTE $0x4C
1062         CALL _strayintr(SB); BYTE $0x4D
1063         CALL _strayintr(SB); BYTE $0x4E
1064         CALL _strayintr(SB); BYTE $0x4F
1065         CALL _strayintr(SB); BYTE $0x50
1066         CALL _strayintr(SB); BYTE $0x51
1067         CALL _strayintr(SB); BYTE $0x52
1068         CALL _strayintr(SB); BYTE $0x53
1069         CALL _strayintr(SB); BYTE $0x54
1070         CALL _strayintr(SB); BYTE $0x55
1071         CALL _strayintr(SB); BYTE $0x56
1072         CALL _strayintr(SB); BYTE $0x57
1073         CALL _strayintr(SB); BYTE $0x58
1074         CALL _strayintr(SB); BYTE $0x59
1075         CALL _strayintr(SB); BYTE $0x5A
1076         CALL _strayintr(SB); BYTE $0x5B
1077         CALL _strayintr(SB); BYTE $0x5C
1078         CALL _strayintr(SB); BYTE $0x5D
1079         CALL _strayintr(SB); BYTE $0x5E
1080         CALL _strayintr(SB); BYTE $0x5F
1081         CALL _strayintr(SB); BYTE $0x60
1082         CALL _strayintr(SB); BYTE $0x61
1083         CALL _strayintr(SB); BYTE $0x62
1084         CALL _strayintr(SB); BYTE $0x63
1085         CALL _strayintr(SB); BYTE $0x64
1086         CALL _strayintr(SB); BYTE $0x65
1087         CALL _strayintr(SB); BYTE $0x66
1088         CALL _strayintr(SB); BYTE $0x67
1089         CALL _strayintr(SB); BYTE $0x68
1090         CALL _strayintr(SB); BYTE $0x69
1091         CALL _strayintr(SB); BYTE $0x6A
1092         CALL _strayintr(SB); BYTE $0x6B
1093         CALL _strayintr(SB); BYTE $0x6C
1094         CALL _strayintr(SB); BYTE $0x6D
1095         CALL _strayintr(SB); BYTE $0x6E
1096         CALL _strayintr(SB); BYTE $0x6F
1097         CALL _strayintr(SB); BYTE $0x70
1098         CALL _strayintr(SB); BYTE $0x71
1099         CALL _strayintr(SB); BYTE $0x72
1100         CALL _strayintr(SB); BYTE $0x73
1101         CALL _strayintr(SB); BYTE $0x74
1102         CALL _strayintr(SB); BYTE $0x75
1103         CALL _strayintr(SB); BYTE $0x76
1104         CALL _strayintr(SB); BYTE $0x77
1105         CALL _strayintr(SB); BYTE $0x78
1106         CALL _strayintr(SB); BYTE $0x79
1107         CALL _strayintr(SB); BYTE $0x7A
1108         CALL _strayintr(SB); BYTE $0x7B
1109         CALL _strayintr(SB); BYTE $0x7C
1110         CALL _strayintr(SB); BYTE $0x7D
1111         CALL _strayintr(SB); BYTE $0x7E
1112         CALL _strayintr(SB); BYTE $0x7F
1113         CALL _strayintr(SB); BYTE $0x80         /* Vector[A]PIC */
1114         CALL _strayintr(SB); BYTE $0x81
1115         CALL _strayintr(SB); BYTE $0x82
1116         CALL _strayintr(SB); BYTE $0x83
1117         CALL _strayintr(SB); BYTE $0x84
1118         CALL _strayintr(SB); BYTE $0x85
1119         CALL _strayintr(SB); BYTE $0x86
1120         CALL _strayintr(SB); BYTE $0x87
1121         CALL _strayintr(SB); BYTE $0x88
1122         CALL _strayintr(SB); BYTE $0x89
1123         CALL _strayintr(SB); BYTE $0x8A
1124         CALL _strayintr(SB); BYTE $0x8B
1125         CALL _strayintr(SB); BYTE $0x8C
1126         CALL _strayintr(SB); BYTE $0x8D
1127         CALL _strayintr(SB); BYTE $0x8E
1128         CALL _strayintr(SB); BYTE $0x8F
1129         CALL _strayintr(SB); BYTE $0x90
1130         CALL _strayintr(SB); BYTE $0x91
1131         CALL _strayintr(SB); BYTE $0x92
1132         CALL _strayintr(SB); BYTE $0x93
1133         CALL _strayintr(SB); BYTE $0x94
1134         CALL _strayintr(SB); BYTE $0x95
1135         CALL _strayintr(SB); BYTE $0x96
1136         CALL _strayintr(SB); BYTE $0x97
1137         CALL _strayintr(SB); BYTE $0x98
1138         CALL _strayintr(SB); BYTE $0x99
1139         CALL _strayintr(SB); BYTE $0x9A
1140         CALL _strayintr(SB); BYTE $0x9B
1141         CALL _strayintr(SB); BYTE $0x9C
1142         CALL _strayintr(SB); BYTE $0x9D
1143         CALL _strayintr(SB); BYTE $0x9E
1144         CALL _strayintr(SB); BYTE $0x9F
1145         CALL _strayintr(SB); BYTE $0xA0
1146         CALL _strayintr(SB); BYTE $0xA1
1147         CALL _strayintr(SB); BYTE $0xA2
1148         CALL _strayintr(SB); BYTE $0xA3
1149         CALL _strayintr(SB); BYTE $0xA4
1150         CALL _strayintr(SB); BYTE $0xA5
1151         CALL _strayintr(SB); BYTE $0xA6
1152         CALL _strayintr(SB); BYTE $0xA7
1153         CALL _strayintr(SB); BYTE $0xA8
1154         CALL _strayintr(SB); BYTE $0xA9
1155         CALL _strayintr(SB); BYTE $0xAA
1156         CALL _strayintr(SB); BYTE $0xAB
1157         CALL _strayintr(SB); BYTE $0xAC
1158         CALL _strayintr(SB); BYTE $0xAD
1159         CALL _strayintr(SB); BYTE $0xAE
1160         CALL _strayintr(SB); BYTE $0xAF
1161         CALL _strayintr(SB); BYTE $0xB0
1162         CALL _strayintr(SB); BYTE $0xB1
1163         CALL _strayintr(SB); BYTE $0xB2
1164         CALL _strayintr(SB); BYTE $0xB3
1165         CALL _strayintr(SB); BYTE $0xB4
1166         CALL _strayintr(SB); BYTE $0xB5
1167         CALL _strayintr(SB); BYTE $0xB6
1168         CALL _strayintr(SB); BYTE $0xB7
1169         CALL _strayintr(SB); BYTE $0xB8
1170         CALL _strayintr(SB); BYTE $0xB9
1171         CALL _strayintr(SB); BYTE $0xBA
1172         CALL _strayintr(SB); BYTE $0xBB
1173         CALL _strayintr(SB); BYTE $0xBC
1174         CALL _strayintr(SB); BYTE $0xBD
1175         CALL _strayintr(SB); BYTE $0xBE
1176         CALL _strayintr(SB); BYTE $0xBF
1177         CALL _strayintr(SB); BYTE $0xC0
1178         CALL _strayintr(SB); BYTE $0xC1
1179         CALL _strayintr(SB); BYTE $0xC2
1180         CALL _strayintr(SB); BYTE $0xC3
1181         CALL _strayintr(SB); BYTE $0xC4
1182         CALL _strayintr(SB); BYTE $0xC5
1183         CALL _strayintr(SB); BYTE $0xC6
1184         CALL _strayintr(SB); BYTE $0xC7
1185         CALL _strayintr(SB); BYTE $0xC8
1186         CALL _strayintr(SB); BYTE $0xC9
1187         CALL _strayintr(SB); BYTE $0xCA
1188         CALL _strayintr(SB); BYTE $0xCB
1189         CALL _strayintr(SB); BYTE $0xCC
1190         CALL _strayintr(SB); BYTE $0xCD
1191         CALL _strayintr(SB); BYTE $0xCE
1192         CALL _strayintr(SB); BYTE $0xCF
1193         CALL _strayintr(SB); BYTE $0xD0
1194         CALL _strayintr(SB); BYTE $0xD1
1195         CALL _strayintr(SB); BYTE $0xD2
1196         CALL _strayintr(SB); BYTE $0xD3
1197         CALL _strayintr(SB); BYTE $0xD4
1198         CALL _strayintr(SB); BYTE $0xD5
1199         CALL _strayintr(SB); BYTE $0xD6
1200         CALL _strayintr(SB); BYTE $0xD7
1201         CALL _strayintr(SB); BYTE $0xD8
1202         CALL _strayintr(SB); BYTE $0xD9
1203         CALL _strayintr(SB); BYTE $0xDA
1204         CALL _strayintr(SB); BYTE $0xDB
1205         CALL _strayintr(SB); BYTE $0xDC
1206         CALL _strayintr(SB); BYTE $0xDD
1207         CALL _strayintr(SB); BYTE $0xDE
1208         CALL _strayintr(SB); BYTE $0xDF
1209         CALL _strayintr(SB); BYTE $0xE0
1210         CALL _strayintr(SB); BYTE $0xE1
1211         CALL _strayintr(SB); BYTE $0xE2
1212         CALL _strayintr(SB); BYTE $0xE3
1213         CALL _strayintr(SB); BYTE $0xE4
1214         CALL _strayintr(SB); BYTE $0xE5
1215         CALL _strayintr(SB); BYTE $0xE6
1216         CALL _strayintr(SB); BYTE $0xE7
1217         CALL _strayintr(SB); BYTE $0xE8
1218         CALL _strayintr(SB); BYTE $0xE9
1219         CALL _strayintr(SB); BYTE $0xEA
1220         CALL _strayintr(SB); BYTE $0xEB
1221         CALL _strayintr(SB); BYTE $0xEC
1222         CALL _strayintr(SB); BYTE $0xED
1223         CALL _strayintr(SB); BYTE $0xEE
1224         CALL _strayintr(SB); BYTE $0xEF
1225         CALL _strayintr(SB); BYTE $0xF0
1226         CALL _strayintr(SB); BYTE $0xF1
1227         CALL _strayintr(SB); BYTE $0xF2
1228         CALL _strayintr(SB); BYTE $0xF3
1229         CALL _strayintr(SB); BYTE $0xF4
1230         CALL _strayintr(SB); BYTE $0xF5
1231         CALL _strayintr(SB); BYTE $0xF6
1232         CALL _strayintr(SB); BYTE $0xF7
1233         CALL _strayintr(SB); BYTE $0xF8
1234         CALL _strayintr(SB); BYTE $0xF9
1235         CALL _strayintr(SB); BYTE $0xFA
1236         CALL _strayintr(SB); BYTE $0xFB
1237         CALL _strayintr(SB); BYTE $0xFC
1238         CALL _strayintr(SB); BYTE $0xFD
1239         CALL _strayintr(SB); BYTE $0xFE
1240         CALL _strayintr(SB); BYTE $0xFF