Advertisement
Zeda

bigint_shift

Nov 28th, 2022 (edited)
2,127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Z80 Assembler 4.11 KB | Source Code | 0 0
  1. ; bigint_lshift(void* arr, size_t len, uint8_t nbits)
  2. bigint_lshift:
  3.     call ti._frameset0
  4.     ld a,(ix + 3)
  5.     ld hl,(ix + 9)
  6.     ld bc,(ix + 6)
  7.     rra
  8.     call nc,bigint_lshift1
  9.     rra
  10.     call nc,bigint_lshift2
  11.     rra
  12.     call nc,bigint_lshift4
  13.     rra
  14.     or a
  15.     call nz,bigint_lshift_A_bytes
  16.     ld sp, ix
  17.     pop ix
  18.     ret
  19.  
  20. ; bigint_rshift(void* arr, size_t len, uint8_t nbits)
  21. bigint_rshift:
  22.     call ti._frameset0
  23.     ld a,(ix + 3)
  24.     ld hl,(ix + 9)
  25.     ld bc,(ix + 6)
  26.     rra
  27.     call nc,bigint_rshift1
  28.     rra
  29.     call nc,bigint_rshift2
  30.     rra
  31.     call nc,bigint_rshift4
  32.     rra
  33.     or a
  34.     call nz,bigint_rshift_A_bytes
  35.     ld sp, ix
  36.     pop ix
  37.     ret
  38.  
  39.  
  40. bigint_lshift_A_bytes:
  41. ; shifts the bigint left by A bytes:
  42. ; Inputs:
  43. ;   HL points to the int
  44. ;   BC is the size (in bytes), ** BC<65536 **
  45. ;   A is the number of bytes to shift
  46. ; Destroys:
  47. ;   DE
  48. ;
  49.     ; or a
  50.     ; ret z
  51.     push hl
  52.     push bc
  53.     push af
  54.  
  55.     add hl,bc
  56.     dec hl
  57.     ex de,hl  ; DE points to the MSB, which is where we'll write
  58.  
  59.     or a,a
  60.     sbc hl,hl
  61.     ld l,a    ; HL is the number of bytes to shift by
  62.  
  63.     ; BC - A, guaranteed to not be 0
  64.     ld a,c
  65.     sub l
  66.     ld c,a
  67.     sbc a,a ; A = -carry
  68.     add a,b
  69.     ld b,a
  70.     ; If BC is negative, just zero out the whole int
  71.     ld a,l  ; restore A
  72.     jp m,.zero_bytes
  73.     ; If BC is 0, zero-out the whole int
  74.     jr nz,.shift_bytes
  75.     dec c
  76.     inc c
  77.     jr z,.zero_bytes
  78.  
  79. .shift_bytes:
  80.     ; want HL = DE - HL
  81.     ex de,hl
  82.     or a,a
  83.     sbc hl,de
  84.     ex de,hl  ; HL is where to read from
  85.  
  86.     ; HL is where to read from
  87.     ; DE is where to write to
  88.     ; BC is size of the bigint, minus the number of bytes to shift
  89.     ; A is the number of bytes to shift by
  90.  
  91.     lddr  ; copy bytes up
  92.  
  93. .zero_bytes:
  94.     ; zero-out the remaining bytes, A is non-zero
  95.     ld b,a
  96.     xor a
  97. .loop:
  98.     ld (de),a
  99.     dec de
  100.     djnz .loop
  101.  
  102.     pop af
  103.     pop bc
  104.     pop hl
  105.     ret
  106.  
  107.  
  108. bigint_lshift4:
  109. ; shifts the bigint left by 4 bits
  110. ; Inputs:
  111. ;   HL points to the int
  112. ;   BC is the size (in bytes)
  113. ; Destroys:
  114. ;   None
  115.     push hl
  116.     push bc
  117.     push af
  118.     xor a
  119. .loop
  120.     rld
  121.     cpi
  122.     jp pe,.loop
  123.     pop af
  124.     pop bc
  125.     pop hl
  126.     ret
  127.  
  128. bigint_lshift2:
  129.     call bigint_lshift1
  130. bigint_lshift1:
  131.     push hl
  132.     push bc
  133.     or a,a
  134. .loop:
  135.     rl (hl)
  136.     cpi
  137.     jp pe,.loop
  138.     pop bc
  139.     pop hl
  140.     ret
  141.  
  142.  
  143. bigint_rshift_A_bytes:
  144. ; shifts the bigint right by A bytes
  145. ; Inputs:
  146. ;   HL points to the int
  147. ;   BC is the size (in bytes), ** BC<65536 **
  148. ;   A is the number of bytes to shift
  149. ; Destroys:
  150. ;   DE
  151.     ; or a
  152.     ; ret z
  153.  
  154.     push hl
  155.     push bc
  156.     push af
  157.     ex de,hl  ; DE points to the start of the string
  158.  
  159.     sbc hl,hl
  160.     ld l,a    ; HL is the number of bytes to shift by
  161.  
  162.     ; BC - A, guaranteed to not be 0
  163.     ld a,c
  164.     sub l
  165.     ld c,a
  166.     sbc a,a ; A = -carry
  167.     add a,b
  168.     ld b,a
  169.     ; If BC is negative, just zero out the whole int
  170.     ld a,l  ; restore A
  171.     jp m,.zero_bytes
  172.     ; If BC is 0, zero-out the whole int
  173.     jr nz,.shift_bytes
  174.     dec c
  175.     inc c
  176.     jr z,.zero_bytes
  177.  
  178. .shift_bytes:
  179.     add hl,de ; HL points to where to start reading
  180.  
  181.     ; HL is where to read from
  182.     ; DE is where to write to
  183.     ; BC is size of the bigint, minus the number of bytes to shift
  184.     ; A is the number of bytes to shift by
  185.  
  186.     ldir  ; copy bytes down
  187.  
  188. .zero_bytes:
  189.     ; zero-out the remaining bytes, A is non-zero
  190.     ld b,a
  191.     xor a
  192. .loop:
  193.     ld (de),a
  194.     inc de
  195.     djnz .loop
  196.  
  197.     pop af
  198.     pop bc
  199.     pop hl
  200.     ret
  201.  
  202. bigint_rshift4:
  203. ; shifts the bigint right by 4 bits
  204. ; Inputs:
  205. ;   HL points to the int
  206. ;   BC is the size (in bytes)
  207. ; Destroys:
  208. ;   None
  209.     push hl
  210.     push bc
  211.     push af
  212.     add hl,bc
  213.     dec hl
  214.     xor a
  215. .loop
  216.     rrd
  217.     cpd
  218.     jp pe,.loop
  219.     pop af
  220.     pop bc
  221.     pop hl
  222.     ret
  223.  
  224.  
  225. bigint_rshift2:
  226.     call bigint_lshift1
  227. bigint_rshift1:
  228.     push hl
  229.     push bc
  230.     add hl,bc
  231.     dec hl
  232.     or a,a
  233. .loop:
  234.     rr (hl)
  235.     cpd
  236.     jp pe,.loop
  237.     pop bc
  238.     pop hl
  239.     ret
  240.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement