]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc64/l.s
vmx: clean up mksegment, memset only if segment existed (devsegment clears new ones)
[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         MOVL    cx+8(FP), CX            /* sub-level in CX */
253         CPUID
254
255         MOVQ    info+16(FP), BP
256         MOVL    AX, 0(BP)
257         MOVL    BX, 4(BP)
258         MOVL    CX, 8(BP)
259         MOVL    DX, 12(BP)
260         RET
261
262 /*
263  * Port I/O.
264  */
265 TEXT inb(SB), 1, $-4
266         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
267         XORL    AX, AX
268         INB
269         RET
270
271 TEXT insb(SB), 1, $-4
272         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
273         MOVQ    address+8(FP), DI
274         MOVL    count+16(FP), CX
275         CLD
276         REP;    INSB
277         RET
278
279 TEXT ins(SB), 1, $-4
280         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
281         XORL    AX, AX
282         INW
283         RET
284
285 TEXT inss(SB), 1, $-4
286         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
287         MOVQ    address+8(FP), DI
288         MOVL    count+16(FP), CX
289         CLD
290         REP;    INSW
291         RET
292
293 TEXT inl(SB), 1, $-4
294         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
295         INL
296         RET
297
298 TEXT insl(SB), 1, $-4
299         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
300         MOVQ    address+8(FP), DI
301         MOVL    count+16(FP), CX
302         CLD
303         REP; INSL
304         RET
305
306 TEXT outb(SB), 1, $-1
307         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
308         MOVL    byte+8(FP), AX
309         OUTB
310         RET
311
312 TEXT outsb(SB), 1, $-4
313         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
314         MOVQ    address+8(FP), SI
315         MOVL    count+16(FP), CX
316         CLD
317         REP; OUTSB
318         RET
319
320 TEXT outs(SB), 1, $-4
321         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
322         MOVL    short+8(FP), AX
323         OUTW
324         RET
325
326 TEXT outss(SB), 1, $-4
327         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
328         MOVQ    address+8(FP), SI
329         MOVL    count+16(FP), CX
330         CLD
331         REP; OUTSW
332         RET
333
334 TEXT outl(SB), 1, $-4
335         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
336         MOVL    long+8(FP), AX
337         OUTL
338         RET
339
340 TEXT outsl(SB), 1, $-4
341         MOVL    RARG, DX                        /* MOVL port+0(FP), DX */
342         MOVQ    address+8(FP), SI
343         MOVL    count+16(FP), CX
344         CLD
345         REP; OUTSL
346         RET
347
348 TEXT getgdt(SB), 1, $-4
349         MOVQ    RARG, AX
350         MOVL    GDTR, (AX)                      /* Note: 10 bytes returned */
351         RET
352
353 TEXT lgdt(SB), $0                               /* GDTR - global descriptor table */
354         MOVQ    RARG, AX
355         MOVL    (AX), GDTR
356         RET
357
358 TEXT lidt(SB), $0                               /* IDTR - interrupt descriptor table */
359         MOVQ    RARG, AX
360         MOVL    (AX), IDTR
361         RET
362
363 TEXT ltr(SB), 1, $-4
364         MOVW    RARG, AX
365         MOVW    AX, TASK
366         RET
367
368 /*
369  * Read/write various system registers.
370  */
371 TEXT getcr0(SB), 1, $-4                         /* Processor Control */
372         MOVQ    CR0, AX
373         RET
374
375 TEXT putcr0(SB), 1, $-4
376         MOVQ    RARG, CR0
377         RET
378
379 TEXT getcr2(SB), 1, $-4                         /* #PF Linear Address */
380         MOVQ    CR2, AX
381         RET
382
383 TEXT putcr2(SB), 1, $-4
384         MOVQ    BP, CR2
385         RET
386
387 TEXT getcr3(SB), 1, $-4                         /* PML4 Base */
388         MOVQ    CR3, AX
389         RET
390
391 TEXT putcr3(SB), 1, $-4
392         MOVQ    RARG, CR3
393         RET
394
395 TEXT getcr4(SB), 1, $-4                         /* Extensions */
396         MOVQ    CR4, AX
397         RET
398
399 TEXT putcr4(SB), 1, $-4
400         MOVQ    RARG, CR4
401         RET
402
403 TEXT getxcr0(SB), 1, $-4                        /* XCR0 - extended control */
404         XORQ CX, CX
405         WORD $0x010f; BYTE $0xd0        // XGETBV
406         SHLQ $32, DX
407         ORQ DX, AX
408         RET
409
410 TEXT putxcr0(SB), 1, $-4
411         XORQ CX, CX
412         MOVL RARG, DX
413         SHRQ $32, DX
414         MOVL RARG, AX
415         WORD $0x010f; BYTE $0xd1        // XSETBV
416         RET
417
418 TEXT mb386(SB), 1, $-4                          /* hack */
419 TEXT mb586(SB), 1, $-4
420         XORL    AX, AX
421         CPUID
422         RET
423
424 /*
425  * BIOS32.
426  */
427 TEXT bios32call(SB), 1, $-4
428         XORL    AX, AX
429         INCL    AX
430         RET
431
432 /*
433  * Basic timing loop to determine CPU frequency.
434  */
435 TEXT aamloop(SB), 1, $-4
436         MOVL    RARG, CX
437 _aamloop:
438         LOOP    _aamloop
439         RET
440
441 TEXT _cycles(SB), 1, $-4                        /* time stamp counter */
442         RDTSC
443         MOVL    AX, 0(RARG)                     /* lo */
444         MOVL    DX, 4(RARG)                     /* hi */
445         RET
446
447 TEXT rdmsr(SB), 1, $-4                          /* Model-Specific Register */
448         MOVL    RARG, CX
449         MOVQ    $0, BP
450 TEXT _rdmsrinst(SB), $0
451         RDMSR
452         MOVQ    vlong+8(FP), CX                 /* &vlong */
453         MOVL    AX, 0(CX)                       /* lo */
454         MOVL    DX, 4(CX)                       /* hi */
455         MOVQ    BP, AX                          /* BP set to -1 if traped */
456         RET
457         
458 TEXT wrmsr(SB), 1, $-4
459         MOVL    RARG, CX
460         MOVL    lo+8(FP), AX
461         MOVL    hi+12(FP), DX
462         MOVQ    $0, BP
463 TEXT _wrmsrinst(SB), $0
464         WRMSR
465         MOVQ    BP, AX                          /* BP set to -1 if traped */
466         RET
467
468 /* fault-proof memcpy */
469 TEXT peek(SB), 1, $-4
470         MOVQ    RARG, SI
471         MOVQ    dst+8(FP), DI
472         MOVL    cnt+16(FP), CX
473         CLD
474 TEXT _peekinst(SB), $0
475         REP; MOVSB
476         MOVL    CX, AX
477         RET
478         
479
480 TEXT invlpg(SB), 1, $-4
481         INVLPG  (RARG)
482         RET
483
484 TEXT wbinvd(SB), 1, $-4
485         WBINVD
486         RET
487
488 /*
489  * Serialisation.
490  */
491 TEXT lfence(SB), 1, $-4
492         LFENCE
493         RET
494
495 TEXT mfence(SB), 1, $-4
496         MFENCE
497         RET
498
499 TEXT sfence(SB), 1, $-4
500         SFENCE
501         RET
502
503 /*
504  * Note: CLI and STI are not serialising instructions.
505  * Is that assumed anywhere?
506  */
507 TEXT splhi(SB), 1, $-4
508 _splhi:
509         PUSHFQ
510         POPQ    AX
511         TESTQ   $0x200, AX                      /* 0x200 - Interrupt Flag */
512         JZ      _alreadyhi                      /* use CMOVLEQ etc. here? */
513
514         MOVQ    (SP), BX
515         MOVQ    BX, 8(RMACH)                    /* save PC in m->splpc */
516
517 _alreadyhi:
518         CLI
519         RET
520
521 TEXT spllo(SB), 1, $-4
522 _spllo:
523         PUSHFQ
524         POPQ    AX
525         TESTQ   $0x200, AX                      /* 0x200 - Interrupt Flag */
526         JNZ     _alreadylo                      /* use CMOVLEQ etc. here? */
527
528         MOVQ    $0, 8(RMACH)                    /* clear m->splpc */
529
530 _alreadylo:
531         STI
532         RET
533
534 TEXT splx(SB), 1, $-4
535         TESTQ   $0x200, RARG                    /* 0x200 - Interrupt Flag */
536         JNZ     _spllo
537         JMP     _splhi
538
539 TEXT spldone(SB), 1, $-4
540         RET
541
542 TEXT islo(SB), 1, $-4
543         PUSHFQ
544         POPQ    AX
545         ANDQ    $0x200, AX                      /* 0x200 - Interrupt Flag */
546         RET
547
548 /*
549  * Synchronisation
550  */
551 TEXT tas(SB), 1, $-4
552 TEXT _tas(SB), 1, $-4
553         MOVL    $0xdeaddead, AX
554         XCHGL   AX, (RARG)                      /*  */
555         RET
556
557 TEXT cmpswap486(SB), 1, $-4
558 TEXT cas(SB), 1, $-4
559         MOVL    exp+8(FP), AX
560         MOVL    new+16(FP), BX
561         LOCK; CMPXCHGL BX, (RARG)
562         MOVL    $1, AX                          /* use CMOVLEQ etc. here? */
563         JNZ     _cas32r0
564 _cas32r1:
565         RET
566 _cas32r0:
567         DECL    AX
568         RET
569
570 /*
571  * Label consists of a stack pointer and a programme counter
572  */
573 TEXT gotolabel(SB), 1, $-4
574         MOVQ    0(RARG), SP                     /* restore SP */
575         MOVQ    8(RARG), AX                     /* put return PC on the stack */
576         MOVQ    AX, 0(SP)
577         MOVL    $1, AX                          /* return 1 */
578         RET
579
580 TEXT setlabel(SB), 1, $-4
581         MOVQ    SP, 0(RARG)                     /* store SP */
582         MOVQ    0(SP), BX                       /* store return PC */
583         MOVQ    BX, 8(RARG)
584         MOVL    $0, AX                          /* return 0 */
585         RET
586
587 TEXT halt(SB), 1, $-4
588         CLI
589         CMPL    nrdy(SB), $0
590         JEQ     _nothingready
591         STI
592         RET
593 _nothingready:
594         STI
595         HLT
596         RET
597
598 TEXT mwait(SB), 1, $-4
599         MOVQ    RARG, AX
600         MOVL    (AX), CX
601         ORL     CX, CX
602         JNZ     _mwaitdone
603         XORL    DX, DX
604         BYTE $0x0f; BYTE $0x01; BYTE $0xc8      /* MONITOR */
605         MOVL    (AX), CX
606         ORL     CX, CX
607         JNZ     _mwaitdone
608         XORL    AX, AX
609         BYTE $0x0f; BYTE $0x01; BYTE $0xc9      /* MWAIT */
610 _mwaitdone:
611         RET
612
613 /*
614  * SIMD Floating Point.
615  * Note: for x87 instructions which have both a 'wait' and 'nowait' version,
616  * 8a only knows the 'wait' mnemonic but does NOT insertthe WAIT prefix byte
617  * (i.e. they act like their FNxxx variations) so WAIT instructions must be
618  * explicitly placed in the code if necessary.
619  */
620 TEXT _clts(SB), 1, $-4
621         CLTS
622         RET
623
624 TEXT _fldcw(SB), 1, $-4                         /* Load x87 FPU Control Word */
625         MOVQ    RARG, cw+0(FP)
626         FLDCW   cw+0(FP)
627         RET
628
629 TEXT _fnclex(SB), 1, $-4
630         FCLEX
631         RET
632
633 TEXT _fninit(SB), 1, $-4
634         FINIT                                   /* no WAIT */
635         RET
636
637 TEXT _fxrstor(SB), 1, $-4
638         FXRSTOR64 (RARG)
639         RET
640
641 TEXT _fxsave(SB), 1, $-4
642         FXSAVE64 (RARG)
643         RET
644
645 TEXT _xrstor(SB), 1, $-4
646         MOVL $7, AX
647         XORL DX, DX
648         BYTE $0x48; BYTE $0x0f; BYTE $0xae; BYTE $0x6d; BYTE $0x00 // XRSTOR (RARG)
649         RET
650
651 TEXT _xrstors(SB), 1, $-4
652         MOVL $7, AX
653         XORL DX, DX
654         BYTE $0x48; BYTE $0x0f; BYTE $0xc7; BYTE $0x5d; BYTE $0x00 // XRSTORS (RARG)
655         RET
656
657 TEXT _xsave(SB), 1, $-4
658         MOVL $7, AX
659         XORL DX, DX
660         BYTE $0x48; BYTE $0x0f; BYTE $0xae; BYTE $0x65; BYTE $0x00 // XSAVE (RARG)
661         RET
662
663 TEXT _xsaveopt(SB), 1, $-4
664         MOVL $7, AX
665         XORL DX, DX
666         BYTE $0x48; BYTE $0x0f; BYTE $0xae; BYTE $0x75; BYTE $0x00 // XSAVEOPT (RARG)
667         RET
668
669 TEXT _xsaves(SB), 1, $-4
670         MOVL $7, AX
671         XORL DX, DX
672         BYTE $0x48; BYTE $0x0f; BYTE $0xc7; BYTE $0x6d; BYTE $0x00 // XSAVES (RARG)
673         RET
674
675 TEXT _fwait(SB), 1, $-4
676         WAIT
677         RET
678
679 TEXT _ldmxcsr(SB), 1, $-4                       /* Load MXCSR */
680         MOVQ    RARG, mxcsr+0(FP)
681         LDMXCSR mxcsr+0(FP)
682         RET
683
684 TEXT _stts(SB), 1, $-4
685         MOVQ    CR0, AX
686         ORQ     $8, AX                          /* Ts */
687         MOVQ    AX, CR0
688         RET
689
690 TEXT mul64fract(SB), 1, $-4
691         MOVQ    a+8(FP), AX
692         MULQ    b+16(FP)                        /* a*b */
693         SHRQ    $32, AX:DX
694         MOVQ    AX, (RARG)
695         RET
696
697 #define RDRANDAX        BYTE $0x0f; BYTE $0xc7; BYTE $0xf0
698 #define RDRAND64AX      BYTE $0x48; BYTE $0x0f; BYTE $0xc7;  BYTE $0xf0
699
700 TEXT rdrand32(SB), $-4
701 loop32:
702         RDRANDAX
703         JCC             loop32
704         RET
705
706 TEXT rdrand64(SB), $-4
707 loop64:
708         RDRAND64AX
709         JCC             loop64
710         RET
711
712 TEXT rdrandbuf(SB), $0
713         MOVQ    RARG, DX
714
715         MOVLQZX cnt+8(FP), CX
716         SHRQ    $3, CX
717 eights:
718         CMPL    CX, $0
719         JLE     f1
720         CALL    rdrand64(SB)
721         MOVQ    AX, 0(DX)
722         ADDQ    $8, DX
723         SUBL    $1, CX
724         JMP     eights
725
726 f1:
727         MOVLQZX cnt+8(FP), CX
728         ANDL    $7, CX
729         SHRQ    $2, CX
730 fours:
731         CMPL    CX, $0
732         JLE     f2
733         CALL    rdrand32(SB)
734         MOVL    AX, 0(DX)
735         ADDQ    $4, DX
736         SUBL    $1, CX
737         JMP     fours
738
739 f2:
740         MOVLQZX cnt+8(FP), CX
741         ANDL    $3, CX
742 ones:
743         CMPL    CX, $0
744         JLE     f3
745         CALL    rdrand32(SB)
746         MOVB    AX, 0(DX)
747         ADDQ    $1, DX
748         SUBL    $1, CX
749         JMP     ones
750
751 f3:
752         RET
753
754 /* debug register access */
755
756 TEXT putdr(SB), 1, $-4
757         MOVQ    56(BP), AX
758         MOVQ    AX, DR7
759         /* wet floor */
760 TEXT putdr01236(SB), 1, $-4
761         MOVQ    0(BP), AX
762         MOVQ    AX, DR0
763         MOVQ    8(BP), AX
764         MOVQ    AX, DR1
765         MOVQ    16(BP), AX
766         MOVQ    AX, DR2
767         MOVQ    24(BP), AX
768         MOVQ    AX, DR3
769         MOVQ    48(BP), AX
770         MOVQ    AX, DR6
771         RET
772
773 TEXT getdr6(SB), 1, $-4
774         MOVQ    DR6, AX
775         RET
776
777 TEXT putdr6(SB), 1, $-4
778         MOVQ    BP, DR6
779         RET
780
781 TEXT putdr7(SB), 1, $-4
782         MOVQ    BP, DR7
783         RET
784
785 /* VMX instructions */
786 TEXT vmxon(SB), 1, $-4
787         MOVQ    BP, 8(SP)
788         /* VMXON 8(SP) */
789         BYTE    $0xf3; BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x08
790         JMP     _vmout
791
792 TEXT vmxoff(SB), 1, $-4
793         BYTE    $0x0f; BYTE $0x01; BYTE $0xc4
794         JMP     _vmout
795
796 TEXT vmclear(SB), 1, $-4
797         MOVQ    BP, 8(SP)
798         /* VMCLEAR 8(SP) */
799         BYTE    $0x66;  BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x08
800         JMP     _vmout
801
802 TEXT vmlaunch(SB), 1, $-4
803         MOVL    $0x6C14, DI
804         MOVQ    SP, DX
805         BYTE    $0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
806         JBE     _vmout
807         MOVL    $0x6C16, DI
808         MOVQ    $vmrestore(SB), DX
809         BYTE    $0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
810         JBE     _vmout
811         
812         MOVQ    BP, ureg+0(FP)
813         MOVL    resume+8(FP), AX
814         TESTL   AX, AX
815         MOVQ    0x00(BP), AX
816         MOVQ    0x08(BP), BX
817         MOVQ    0x10(BP), CX
818         MOVQ    0x18(BP), DX
819         MOVQ    0x20(BP), SI
820         MOVQ    0x28(BP), DI
821         MOVQ    0x38(BP), R8
822         MOVQ    0x40(BP), R9
823         MOVQ    0x48(BP), R10
824         MOVQ    0x50(BP), R11
825         MOVQ    0x58(BP), R12
826         MOVQ    0x60(BP), R13
827         MOVQ    0x68(BP), R14
828         MOVQ    0x70(BP), R15
829         MOVQ    0x30(BP), BP
830         JNE     _vmresume
831         BYTE    $0x0f; BYTE $0x01; BYTE $0xc2 /* VMLAUNCH */
832         JMP     _vmout
833 _vmresume:
834         BYTE    $0x0f; BYTE $0x01; BYTE $0xc3 /* VMRESUME */
835         JMP _vmout
836         
837 TEXT vmrestore(SB), 1, $-4
838         PUSHQ   BP
839         MOVQ    ureg+0(FP), BP
840         MOVQ    AX, 0x00(BP)
841         MOVQ    BX, 0x08(BP)
842         MOVQ    CX, 0x10(BP)
843         MOVQ    DX, 0x18(BP)
844         MOVQ    SI, 0x20(BP)
845         MOVQ    DI, 0x28(BP)
846         POPQ    0x30(BP)
847         MOVQ    R8, 0x38(BP)
848         MOVQ    R9, 0x40(BP)
849         MOVQ    R10, 0x48(BP)
850         MOVQ    R11, 0x50(BP)
851         MOVQ    R12, 0x58(BP)
852         MOVQ    R13, 0x60(BP)
853         MOVQ    R14, 0x68(BP)
854         MOVQ    R15, 0x70(BP)
855         
856         BYTE    $0x65; MOVQ 0, RMACH /* MOVQ GS:(0), RMACH */
857         MOVQ    16(RMACH), RUSER
858         XORL    AX, AX
859         RET
860
861 TEXT vmptrld(SB), 1, $-4
862         MOVQ    BP, 8(SP)
863         /* VMMPTRLD 8(SP) */
864         BYTE    $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x08
865         JMP _vmout
866
867 TEXT vmwrite(SB), 1, $-4
868         MOVQ    val+8(FP), DX
869         /* VMWRITE DX, BP */
870         BYTE    $0x0f; BYTE $0x79; BYTE $0xea
871         JMP _vmout
872
873 TEXT vmread(SB), 1, $-4
874         MOVQ    valp+8(FP), DI
875         /* VMREAD BP, (DI) */
876         BYTE    $0x0f; BYTE $0x78; BYTE $0x2f
877         JMP _vmout
878
879 TEXT invept(SB), 1, $-4
880         /* INVEPT BP, 16(SP) */
881         BYTE    $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x80; BYTE $0x6c; BYTE $0x24; BYTE $0x10
882         JMP _vmout
883
884 TEXT invvpid(SB), 1, $-4
885         /* INVVPID BP, 16(SP) */
886         BYTE    $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x81; BYTE $0x6c; BYTE $0x24; BYTE $0x10
887         JMP _vmout
888
889 _vmout:
890         JC      _vmout1
891         JZ      _vmout2
892         XORL    AX, AX
893         RET
894 _vmout1:
895         MOVQ    $-1, AX
896         RET
897 _vmout2:
898         MOVQ    $-2, AX
899         RET
900
901 /*
902  */
903 TEXT touser(SB), 1, $-4
904         CLI
905         SWAPGS
906
907         MOVL    $0, RMACH
908         MOVL    $0, RUSER
909
910         MOVQ    $(UTZERO+0x28), CX              /* ip */
911         MOVL    $0x200, R11                     /* flags */
912         MOVQ    RARG, SP                        /* sp */
913
914         BYTE $0x48; SYSRET                      /* SYSRETQ */
915
916 /*
917  */
918 TEXT syscallentry(SB), 1, $-4
919         SWAPGS
920         BYTE $0x65; MOVQ 0, AX                  /* m-> (MOVQ GS:0x0, AX) */
921         MOVQ    16(AX), BX                      /* m->proc */
922         MOVQ    SP, R13
923         MOVQ    16(BX), SP                      /* m->proc->kstack */
924         ADDQ    $KSTACK, SP
925
926         PUSHQ   $UDSEL                          /* old stack segment */
927         PUSHQ   R13                             /* old sp */
928         PUSHQ   R11                             /* old flags */
929         PUSHQ   $UESEL                          /* old code segment */
930         PUSHQ   CX                              /* old ip */
931         PUSHQ   $0                              /* error code */
932         PUSHQ   $64                             /* trap number (VectorSYSCALL) */
933
934         SUBQ    $(8 + 23*8-7*8), SP             /* arg + sizeof(Ureg)-pushed */
935
936         MOVQ    RMACH, (15*8)(SP)               /* old r15 */
937         MOVQ    RUSER, (14*8)(SP)               /* old r14 */
938
939         MOVQ    RARG, (7*8)(SP)                 /* system call number */
940
941         MOVQ    AX, RMACH                       /* m */
942         MOVQ    BX, RUSER                       /* up */
943
944         LEAQ    8(SP), RARG                     /* Ureg* arg */
945
946         CALL    syscall(SB)
947
948 TEXT forkret(SB), 1, $-4
949         CLI
950         SWAPGS
951
952         MOVQ    8(SP), AX                       /* return value */
953
954         MOVQ    (15*8)(SP), RMACH               /* r15 */
955         MOVQ    (14*8)(SP), RUSER               /* r14 */
956
957         MOVQ    (19*8)(SP), CX                  /* ip */
958         MOVQ    (21*8)(SP), R11                 /* flags */
959         MOVQ    (22*8)(SP), SP                  /* sp */
960
961         BYTE $0x48; SYSRET                      /* SYSRETQ */
962
963 /*
964  * Interrupt/exception handling.
965  */
966
967 TEXT _strayintr(SB), 1, $-4                     /* no error code pushed */
968         PUSHQ   AX                              /* save AX */
969         MOVQ    8(SP), AX                       /* vectortable(SB) PC */
970         JMP     _intrcommon
971
972 TEXT _strayintrx(SB), 1, $-4                    /* error code pushed */
973         XCHGQ   AX, (SP)
974 _intrcommon:
975         MOVBQZX (AX), AX
976         XCHGQ   AX, (SP)
977
978         SUBQ    $24, SP                         /* R1[45], [DEFG]S */
979         CMPW    48(SP), $KESEL                  /* old CS */
980         JEQ     _intrnested
981
982         MOVQ    RUSER, 0(SP)
983         MOVQ    RMACH, 8(SP)
984
985         SWAPGS
986         BYTE $0x65; MOVQ 0, RMACH               /* m-> (MOVQ GS:0x0, R15) */
987         MOVQ    16(RMACH), RUSER                /* up */
988
989 _intrnested:
990         PUSHQ   R13
991         PUSHQ   R12
992         PUSHQ   R11
993         PUSHQ   R10
994         PUSHQ   R9
995         PUSHQ   R8
996         PUSHQ   BP
997         PUSHQ   DI
998         PUSHQ   SI
999         PUSHQ   DX
1000         PUSHQ   CX
1001         PUSHQ   BX
1002         PUSHQ   AX
1003
1004         MOVQ    SP, RARG
1005         PUSHQ   SP
1006         CALL    trap(SB)
1007
1008 TEXT _intrr(SB), 1, $-4
1009 _intrestore:
1010         POPQ    AX
1011
1012         POPQ    AX
1013         POPQ    BX
1014         POPQ    CX
1015         POPQ    DX
1016         POPQ    SI
1017         POPQ    DI
1018         POPQ    BP
1019         POPQ    R8
1020         POPQ    R9
1021         POPQ    R10
1022         POPQ    R11
1023         POPQ    R12
1024         POPQ    R13
1025
1026         CMPQ    48(SP), $KESEL
1027         JEQ     _iretnested
1028
1029         SWAPGS
1030
1031         MOVQ    8(SP), RMACH
1032         MOVQ    0(SP), RUSER
1033
1034 _iretnested:
1035         ADDQ    $40, SP
1036         IRETQ
1037
1038 TEXT noteret(SB), 1, $-4
1039         CLI
1040         JMP     _intrestore
1041
1042 TEXT vectortable(SB), $0
1043         CALL _strayintr(SB); BYTE $0x00         /* divide error */
1044         CALL _strayintr(SB); BYTE $0x01         /* debug exception */
1045         CALL _strayintr(SB); BYTE $0x02         /* NMI interrupt */
1046         CALL _strayintr(SB); BYTE $0x03         /* breakpoint */
1047         CALL _strayintr(SB); BYTE $0x04         /* overflow */
1048         CALL _strayintr(SB); BYTE $0x05         /* bound */
1049         CALL _strayintr(SB); BYTE $0x06         /* invalid opcode */
1050         CALL _strayintr(SB); BYTE $0x07         /* no coprocessor available */
1051         CALL _strayintrx(SB); BYTE $0x08        /* double fault */
1052         CALL _strayintr(SB); BYTE $0x09         /* coprocessor segment overflow */
1053         CALL _strayintrx(SB); BYTE $0x0A        /* invalid TSS */
1054         CALL _strayintrx(SB); BYTE $0x0B        /* segment not available */
1055         CALL _strayintrx(SB); BYTE $0x0C        /* stack exception */
1056         CALL _strayintrx(SB); BYTE $0x0D        /* general protection error */
1057         CALL _strayintrx(SB); BYTE $0x0E        /* page fault */
1058         CALL _strayintr(SB); BYTE $0x0F         /*  */
1059         CALL _strayintr(SB); BYTE $0x10         /* coprocessor error */
1060         CALL _strayintrx(SB); BYTE $0x11        /* alignment check */
1061         CALL _strayintr(SB); BYTE $0x12         /* machine check */
1062         CALL _strayintr(SB); BYTE $0x13         /* simd error */
1063         CALL _strayintr(SB); BYTE $0x14
1064         CALL _strayintr(SB); BYTE $0x15
1065         CALL _strayintr(SB); BYTE $0x16
1066         CALL _strayintr(SB); BYTE $0x17
1067         CALL _strayintr(SB); BYTE $0x18
1068         CALL _strayintr(SB); BYTE $0x19
1069         CALL _strayintr(SB); BYTE $0x1A
1070         CALL _strayintr(SB); BYTE $0x1B
1071         CALL _strayintr(SB); BYTE $0x1C
1072         CALL _strayintr(SB); BYTE $0x1D
1073         CALL _strayintr(SB); BYTE $0x1E
1074         CALL _strayintr(SB); BYTE $0x1F
1075         CALL _strayintr(SB); BYTE $0x20         /* VectorLAPIC */
1076         CALL _strayintr(SB); BYTE $0x21
1077         CALL _strayintr(SB); BYTE $0x22
1078         CALL _strayintr(SB); BYTE $0x23
1079         CALL _strayintr(SB); BYTE $0x24
1080         CALL _strayintr(SB); BYTE $0x25
1081         CALL _strayintr(SB); BYTE $0x26
1082         CALL _strayintr(SB); BYTE $0x27
1083         CALL _strayintr(SB); BYTE $0x28
1084         CALL _strayintr(SB); BYTE $0x29
1085         CALL _strayintr(SB); BYTE $0x2A
1086         CALL _strayintr(SB); BYTE $0x2B
1087         CALL _strayintr(SB); BYTE $0x2C
1088         CALL _strayintr(SB); BYTE $0x2D
1089         CALL _strayintr(SB); BYTE $0x2E
1090         CALL _strayintr(SB); BYTE $0x2F
1091         CALL _strayintr(SB); BYTE $0x30
1092         CALL _strayintr(SB); BYTE $0x31
1093         CALL _strayintr(SB); BYTE $0x32
1094         CALL _strayintr(SB); BYTE $0x33
1095         CALL _strayintr(SB); BYTE $0x34
1096         CALL _strayintr(SB); BYTE $0x35
1097         CALL _strayintr(SB); BYTE $0x36
1098         CALL _strayintr(SB); BYTE $0x37
1099         CALL _strayintr(SB); BYTE $0x38
1100         CALL _strayintr(SB); BYTE $0x39
1101         CALL _strayintr(SB); BYTE $0x3A
1102         CALL _strayintr(SB); BYTE $0x3B
1103         CALL _strayintr(SB); BYTE $0x3C
1104         CALL _strayintr(SB); BYTE $0x3D
1105         CALL _strayintr(SB); BYTE $0x3E
1106         CALL _strayintr(SB); BYTE $0x3F
1107         CALL _strayintr(SB); BYTE $0x40         /* was VectorSYSCALL */
1108         CALL _strayintr(SB); BYTE $0x41
1109         CALL _strayintr(SB); BYTE $0x42
1110         CALL _strayintr(SB); BYTE $0x43
1111         CALL _strayintr(SB); BYTE $0x44
1112         CALL _strayintr(SB); BYTE $0x45
1113         CALL _strayintr(SB); BYTE $0x46
1114         CALL _strayintr(SB); BYTE $0x47
1115         CALL _strayintr(SB); BYTE $0x48
1116         CALL _strayintr(SB); BYTE $0x49
1117         CALL _strayintr(SB); BYTE $0x4A
1118         CALL _strayintr(SB); BYTE $0x4B
1119         CALL _strayintr(SB); BYTE $0x4C
1120         CALL _strayintr(SB); BYTE $0x4D
1121         CALL _strayintr(SB); BYTE $0x4E
1122         CALL _strayintr(SB); BYTE $0x4F
1123         CALL _strayintr(SB); BYTE $0x50
1124         CALL _strayintr(SB); BYTE $0x51
1125         CALL _strayintr(SB); BYTE $0x52
1126         CALL _strayintr(SB); BYTE $0x53
1127         CALL _strayintr(SB); BYTE $0x54
1128         CALL _strayintr(SB); BYTE $0x55
1129         CALL _strayintr(SB); BYTE $0x56
1130         CALL _strayintr(SB); BYTE $0x57
1131         CALL _strayintr(SB); BYTE $0x58
1132         CALL _strayintr(SB); BYTE $0x59
1133         CALL _strayintr(SB); BYTE $0x5A
1134         CALL _strayintr(SB); BYTE $0x5B
1135         CALL _strayintr(SB); BYTE $0x5C
1136         CALL _strayintr(SB); BYTE $0x5D
1137         CALL _strayintr(SB); BYTE $0x5E
1138         CALL _strayintr(SB); BYTE $0x5F
1139         CALL _strayintr(SB); BYTE $0x60
1140         CALL _strayintr(SB); BYTE $0x61
1141         CALL _strayintr(SB); BYTE $0x62
1142         CALL _strayintr(SB); BYTE $0x63
1143         CALL _strayintr(SB); BYTE $0x64
1144         CALL _strayintr(SB); BYTE $0x65
1145         CALL _strayintr(SB); BYTE $0x66
1146         CALL _strayintr(SB); BYTE $0x67
1147         CALL _strayintr(SB); BYTE $0x68
1148         CALL _strayintr(SB); BYTE $0x69
1149         CALL _strayintr(SB); BYTE $0x6A
1150         CALL _strayintr(SB); BYTE $0x6B
1151         CALL _strayintr(SB); BYTE $0x6C
1152         CALL _strayintr(SB); BYTE $0x6D
1153         CALL _strayintr(SB); BYTE $0x6E
1154         CALL _strayintr(SB); BYTE $0x6F
1155         CALL _strayintr(SB); BYTE $0x70
1156         CALL _strayintr(SB); BYTE $0x71
1157         CALL _strayintr(SB); BYTE $0x72
1158         CALL _strayintr(SB); BYTE $0x73
1159         CALL _strayintr(SB); BYTE $0x74
1160         CALL _strayintr(SB); BYTE $0x75
1161         CALL _strayintr(SB); BYTE $0x76
1162         CALL _strayintr(SB); BYTE $0x77
1163         CALL _strayintr(SB); BYTE $0x78
1164         CALL _strayintr(SB); BYTE $0x79
1165         CALL _strayintr(SB); BYTE $0x7A
1166         CALL _strayintr(SB); BYTE $0x7B
1167         CALL _strayintr(SB); BYTE $0x7C
1168         CALL _strayintr(SB); BYTE $0x7D
1169         CALL _strayintr(SB); BYTE $0x7E
1170         CALL _strayintr(SB); BYTE $0x7F
1171         CALL _strayintr(SB); BYTE $0x80         /* Vector[A]PIC */
1172         CALL _strayintr(SB); BYTE $0x81
1173         CALL _strayintr(SB); BYTE $0x82
1174         CALL _strayintr(SB); BYTE $0x83
1175         CALL _strayintr(SB); BYTE $0x84
1176         CALL _strayintr(SB); BYTE $0x85
1177         CALL _strayintr(SB); BYTE $0x86
1178         CALL _strayintr(SB); BYTE $0x87
1179         CALL _strayintr(SB); BYTE $0x88
1180         CALL _strayintr(SB); BYTE $0x89
1181         CALL _strayintr(SB); BYTE $0x8A
1182         CALL _strayintr(SB); BYTE $0x8B
1183         CALL _strayintr(SB); BYTE $0x8C
1184         CALL _strayintr(SB); BYTE $0x8D
1185         CALL _strayintr(SB); BYTE $0x8E
1186         CALL _strayintr(SB); BYTE $0x8F
1187         CALL _strayintr(SB); BYTE $0x90
1188         CALL _strayintr(SB); BYTE $0x91
1189         CALL _strayintr(SB); BYTE $0x92
1190         CALL _strayintr(SB); BYTE $0x93
1191         CALL _strayintr(SB); BYTE $0x94
1192         CALL _strayintr(SB); BYTE $0x95
1193         CALL _strayintr(SB); BYTE $0x96
1194         CALL _strayintr(SB); BYTE $0x97
1195         CALL _strayintr(SB); BYTE $0x98
1196         CALL _strayintr(SB); BYTE $0x99
1197         CALL _strayintr(SB); BYTE $0x9A
1198         CALL _strayintr(SB); BYTE $0x9B
1199         CALL _strayintr(SB); BYTE $0x9C
1200         CALL _strayintr(SB); BYTE $0x9D
1201         CALL _strayintr(SB); BYTE $0x9E
1202         CALL _strayintr(SB); BYTE $0x9F
1203         CALL _strayintr(SB); BYTE $0xA0
1204         CALL _strayintr(SB); BYTE $0xA1
1205         CALL _strayintr(SB); BYTE $0xA2
1206         CALL _strayintr(SB); BYTE $0xA3
1207         CALL _strayintr(SB); BYTE $0xA4
1208         CALL _strayintr(SB); BYTE $0xA5
1209         CALL _strayintr(SB); BYTE $0xA6
1210         CALL _strayintr(SB); BYTE $0xA7
1211         CALL _strayintr(SB); BYTE $0xA8
1212         CALL _strayintr(SB); BYTE $0xA9
1213         CALL _strayintr(SB); BYTE $0xAA
1214         CALL _strayintr(SB); BYTE $0xAB
1215         CALL _strayintr(SB); BYTE $0xAC
1216         CALL _strayintr(SB); BYTE $0xAD
1217         CALL _strayintr(SB); BYTE $0xAE
1218         CALL _strayintr(SB); BYTE $0xAF
1219         CALL _strayintr(SB); BYTE $0xB0
1220         CALL _strayintr(SB); BYTE $0xB1
1221         CALL _strayintr(SB); BYTE $0xB2
1222         CALL _strayintr(SB); BYTE $0xB3
1223         CALL _strayintr(SB); BYTE $0xB4
1224         CALL _strayintr(SB); BYTE $0xB5
1225         CALL _strayintr(SB); BYTE $0xB6
1226         CALL _strayintr(SB); BYTE $0xB7
1227         CALL _strayintr(SB); BYTE $0xB8
1228         CALL _strayintr(SB); BYTE $0xB9
1229         CALL _strayintr(SB); BYTE $0xBA
1230         CALL _strayintr(SB); BYTE $0xBB
1231         CALL _strayintr(SB); BYTE $0xBC
1232         CALL _strayintr(SB); BYTE $0xBD
1233         CALL _strayintr(SB); BYTE $0xBE
1234         CALL _strayintr(SB); BYTE $0xBF
1235         CALL _strayintr(SB); BYTE $0xC0
1236         CALL _strayintr(SB); BYTE $0xC1
1237         CALL _strayintr(SB); BYTE $0xC2
1238         CALL _strayintr(SB); BYTE $0xC3
1239         CALL _strayintr(SB); BYTE $0xC4
1240         CALL _strayintr(SB); BYTE $0xC5
1241         CALL _strayintr(SB); BYTE $0xC6
1242         CALL _strayintr(SB); BYTE $0xC7
1243         CALL _strayintr(SB); BYTE $0xC8
1244         CALL _strayintr(SB); BYTE $0xC9
1245         CALL _strayintr(SB); BYTE $0xCA
1246         CALL _strayintr(SB); BYTE $0xCB
1247         CALL _strayintr(SB); BYTE $0xCC
1248         CALL _strayintr(SB); BYTE $0xCD
1249         CALL _strayintr(SB); BYTE $0xCE
1250         CALL _strayintr(SB); BYTE $0xCF
1251         CALL _strayintr(SB); BYTE $0xD0
1252         CALL _strayintr(SB); BYTE $0xD1
1253         CALL _strayintr(SB); BYTE $0xD2
1254         CALL _strayintr(SB); BYTE $0xD3
1255         CALL _strayintr(SB); BYTE $0xD4
1256         CALL _strayintr(SB); BYTE $0xD5
1257         CALL _strayintr(SB); BYTE $0xD6
1258         CALL _strayintr(SB); BYTE $0xD7
1259         CALL _strayintr(SB); BYTE $0xD8
1260         CALL _strayintr(SB); BYTE $0xD9
1261         CALL _strayintr(SB); BYTE $0xDA
1262         CALL _strayintr(SB); BYTE $0xDB
1263         CALL _strayintr(SB); BYTE $0xDC
1264         CALL _strayintr(SB); BYTE $0xDD
1265         CALL _strayintr(SB); BYTE $0xDE
1266         CALL _strayintr(SB); BYTE $0xDF
1267         CALL _strayintr(SB); BYTE $0xE0
1268         CALL _strayintr(SB); BYTE $0xE1
1269         CALL _strayintr(SB); BYTE $0xE2
1270         CALL _strayintr(SB); BYTE $0xE3
1271         CALL _strayintr(SB); BYTE $0xE4
1272         CALL _strayintr(SB); BYTE $0xE5
1273         CALL _strayintr(SB); BYTE $0xE6
1274         CALL _strayintr(SB); BYTE $0xE7
1275         CALL _strayintr(SB); BYTE $0xE8
1276         CALL _strayintr(SB); BYTE $0xE9
1277         CALL _strayintr(SB); BYTE $0xEA
1278         CALL _strayintr(SB); BYTE $0xEB
1279         CALL _strayintr(SB); BYTE $0xEC
1280         CALL _strayintr(SB); BYTE $0xED
1281         CALL _strayintr(SB); BYTE $0xEE
1282         CALL _strayintr(SB); BYTE $0xEF
1283         CALL _strayintr(SB); BYTE $0xF0
1284         CALL _strayintr(SB); BYTE $0xF1
1285         CALL _strayintr(SB); BYTE $0xF2
1286         CALL _strayintr(SB); BYTE $0xF3
1287         CALL _strayintr(SB); BYTE $0xF4
1288         CALL _strayintr(SB); BYTE $0xF5
1289         CALL _strayintr(SB); BYTE $0xF6
1290         CALL _strayintr(SB); BYTE $0xF7
1291         CALL _strayintr(SB); BYTE $0xF8
1292         CALL _strayintr(SB); BYTE $0xF9
1293         CALL _strayintr(SB); BYTE $0xFA
1294         CALL _strayintr(SB); BYTE $0xFB
1295         CALL _strayintr(SB); BYTE $0xFC
1296         CALL _strayintr(SB); BYTE $0xFD
1297         CALL _strayintr(SB); BYTE $0xFE
1298         CALL _strayintr(SB); BYTE $0xFF