|
| 1 | + .def _random |
| 2 | + .def __state |
| 3 | + .assume adl=1 |
| 4 | + |
| 5 | +; uint32_t random(void); |
| 6 | + |
| 7 | +; https://github.com/MersenneTwister-Lab/XSadd/blob/master/xsadd.h#L75 |
| 8 | +; using shift parameters (19, 21, 8) instead of (15, 18, 11) |
| 9 | + |
| 10 | +; uint32_t xsadd(uint32_t state[static 4]) |
| 11 | +; { |
| 12 | +; uint32_t s0, s1, s2, t0, t1, t2, t3, z, result; |
| 13 | +; t0 = state[0]; |
| 14 | +; state[0] = state[1]; state[1] = state[2]; state[2] = state[3]; |
| 15 | +; s0 = t0 << 19; |
| 16 | +; t1 = t0 ^ s0; |
| 17 | +; s1 = t1 >> 21; |
| 18 | +; t2 = t1 ^ s1; |
| 19 | +; z = state[3]; |
| 20 | +; s2 = z << 8; |
| 21 | +; t3 = t2 ^ s2; |
| 22 | +; state[3] = t3; |
| 23 | +; result = t3 + state[2]; |
| 24 | +; return result; |
| 25 | +; } |
| 26 | + |
| 27 | + SEGMENT DATA |
| 28 | +__state: |
| 29 | + dl 0d0e0f10h,090a0b0ch,05060708h,01020304h |
| 30 | + |
| 31 | + SEGMENT CODE |
| 32 | +_random: |
| 33 | +; Read state[0] and perform state shifting. |
| 34 | + ld iy,__state ; iy = &state[0] |
| 35 | + ld hl,(iy+0*4+0) ; hl = hl(state[0]) |
| 36 | + push hl |
| 37 | + ld hl,(iy+0*4+2) ; hl = eu(state[0]) |
| 38 | + push hl |
| 39 | + lea hl,iy+1*4 ; hl = &state[1] |
| 40 | + lea de,iy+0*4 ; de = &state[0] |
| 41 | + ld bc,3*4 |
| 42 | + ldir ; state[0] = state[1] |
| 43 | + ; state[1] = state[2] |
| 44 | + ; state[2] = state[3] |
| 45 | + pop bc |
| 46 | + pop de ; bcde = state[0] == t0 |
| 47 | +; |
| 48 | +; s0 = t0 << 19 ==> s0h == 0 ==> t1h = t0h |
| 49 | +; s0l == 0 ==> t1l = t0l |
| 50 | +; |
| 51 | +; s1 = t1 >> 21 ==> s1e == 0 ==> t2e = t1e |
| 52 | +; s1u == 0 ==> t2u = t1u |
| 53 | +; |
| 54 | +; s2 = z << 8 ==> s2e == zu ==> t3e == t2e ^ s2e == t1e ^ s2e == t0e ^ s0e ^ s2e |
| 55 | +; s2u == zh ==> t3u == t2u ^ s2u == t1u ^ s2u == t0u ^ s0u ^ s2u |
| 56 | +; s2h == zl ==> t3h == t2h ^ s2h == t1h ^ s1h ^ s2h == t0h ^ s1h ^ s2h |
| 57 | +; s2l == 0 ==> t3l == t2l == t1l ^ s1l == t0l ^ s1l |
| 58 | +; |
| 59 | +; Calculate s0. |
| 60 | + ld h,d |
| 61 | + ld l,e ; hl = t0hl == t0 << 16 |
| 62 | + add hl,hl |
| 63 | + add hl,hl |
| 64 | + add hl,hl ; hl = t0 << 19 = s0eu |
| 65 | + ; h = s0e |
| 66 | + ; l = s0u |
| 67 | +; Calculate t1e and t3e. |
| 68 | + ld a,b ; a = t0e |
| 69 | + xor a,h ; a = t0e ^ s0e == t1e |
| 70 | + ld h,a ; h = t1e |
| 71 | + xor a,(iy+3*4+2) ; a = t1e ^ zu == t2e ^ s2e == t3e |
| 72 | + ld (iy+3*4+3),a ; e(state[3]) = t3e |
| 73 | + ld b,a ; b = t3e |
| 74 | +; Calculate t1u and t3u. |
| 75 | + ld a,c ; a = t0u |
| 76 | + xor a,l ; a = t0u ^ s0u == t1u |
| 77 | + ld l,a ; l = t1u |
| 78 | + ; hl = t1eu == t1 >> 16 |
| 79 | + xor a,(iy+3*4+1) ; a = t1u ^ zh == t2u ^ s2u == t3u |
| 80 | + ld (iy+3*4+2),a ; u(state[3]) = t3u |
| 81 | +; Calculate s1. |
| 82 | + xor a,a ; a = 0 |
| 83 | + add.s hl,hl |
| 84 | + adc a,a |
| 85 | + add.s hl,hl |
| 86 | + adc a,a |
| 87 | + add.s hl,hl |
| 88 | + adc a,a ; ahl = (t1 >> 16) << 3 |
| 89 | + ; ah = ((t1 >> 16) << 3) >> 8 == t1 >> 21 == s1hl |
| 90 | + ; a = s1h |
| 91 | + ; h = s1l |
| 92 | +; Calculate t3h. |
| 93 | + xor a,d ; a = s1h ^ t0h === s1h ^ t1h == t2h |
| 94 | + xor a,(iy+3*4+0) ; a = t2h ^ zl == t2h ^ s2h == t3h |
| 95 | + ld (iy+3*4+1),a ; h(state[3]) = t3h |
| 96 | +; Calculate t3l. |
| 97 | + ld a,e ; a = t0l == t1l |
| 98 | + xor a,h ; a = t1l ^ s1l == t2l == t3l |
| 99 | + ld (iy+3*4+0),a ; l(state[3]) = t3l |
| 100 | +; Calculate result. |
| 101 | + ld hl,(iy+3*4) |
| 102 | + ld a,b ; auhl = t3 |
| 103 | + ld de,(iy+2*4) |
| 104 | + ld c,(iy+2*4+3) ; cude = state[2] |
| 105 | + add hl,de |
| 106 | + adc a,c ; auhl = t3 + state[2] = result |
| 107 | + ld e,a ; euhl = result |
| 108 | + ret |
0 commit comments