.
[mu.git] / 112read-byte.subx
blob5ffd49039a2ed3284fc861a887292cd1dbfba32a
1 # Read a single byte from a stream.
3 # We need to do this in machine code because streams need to be opaque types,
4 # and we don't yet support opaque types in Mu.
6 == code
7 #   instruction                     effective address                                                   register    displacement    immediate
8 # . op          subop               mod             rm32          base        index         scale       r32
9 # . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
11 # Return next byte value in eax, with top 3 bytes cleared.
12 # Abort on reaching end of stream.
13 read-byte:  # s: (addr stream byte) -> result/eax: byte
14     # . prologue
15     55/push-ebp
16     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
17     # . save registers
18     51/push-ecx
19     56/push-esi
20     # esi = s
21     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
22     # ecx = s->read
23     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
24     # if (f->read >= f->write) abort
25     3b/compare                      0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # compare ecx with *esi
26     0f 8d/jump-if->=  $read-byte:abort/disp32
27     # result = f->data[f->read]
28     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
29     8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/AL    0xc/disp8       .                 # copy byte at *(esi+ecx+12) to AL
30     # ++f->read
31     ff          0/subop/increment   1/mod/*+disp8   6/rm32/esi    .           .             .           .           4/disp8         .                 # increment *(esi+4)
32 $read-byte:end:
33     # . restore registers
34     5e/pop-to-esi
35     59/pop-to-ecx
36     # . epilogue
37     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
38     5d/pop-to-ebp
39     c3/return
41 $read-byte:abort:
42     (abort "read-byte: empty stream")
43     # never gets here
45 # Return next byte value in eax, with top 3 bytes cleared.
46 # Abort on reaching end of stream.
47 peek-byte:  # s: (addr stream byte) -> result/eax: byte
48     # . prologue
49     55/push-ebp
50     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
51     # . save registers
52     51/push-ecx
53     56/push-esi
54     # esi = s
55     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
56     # ecx = s->read
57     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
58     # if (f->read >= f->write) abort
59     3b/compare                      0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # compare ecx with *esi
60     0f 8d/jump-if->=  $peek-byte:abort/disp32
61     # result = f->data[f->read]
62     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
63     8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/AL    0xc/disp8       .                 # copy byte at *(esi+ecx+12) to AL
64 $peek-byte:end:
65     # . restore registers
66     5e/pop-to-esi
67     59/pop-to-ecx
68     # . epilogue
69     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
70     5d/pop-to-ebp
71     c3/return
73 $peek-byte:abort:
74     (abort "peek-byte: empty stream")
75     # never gets here
77 == data
79 _test-input-stream:  # (stream byte)
80     # current write index
81     0/imm32
82 $_test-input-stream->read:
83     # current read index
84     0/imm32
85     # size
86     0x400/imm32  # 1024 bytes
87     # data (64 lines x 16 bytes/line)
88     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
89     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
91     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
92     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
93     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
94     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
95     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
96     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
97     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
98     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
99     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
100     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
101     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
102     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
103     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
104     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
105     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
106     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
107     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
108     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
109     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
110     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
111     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
112     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
113     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
114     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
115     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
116     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
117     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
118     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
119     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
120     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
121     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
122     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
123     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
124     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
125     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
126     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
127     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
128     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
129     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
130     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
131     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
132     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
133     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
134     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
135     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
136     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
137     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
138     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
139     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
140     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
141     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
142     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
143     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
144     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
145     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
146     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
147     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
148     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
149     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
150     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
151     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
153 # . . vim:nowrap:textwidth=0