cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

__itoa.s (4077B)


      1;--------------------------------------------------------------------------
      2;  __itoa.s
      3;
      4;  Copyright (C) 2020, Sergey Belyashov
      5;
      6;  This library is free software; you can redistribute it and/or modify it
      7;  under the terms of the GNU General Public License as published by the
      8;  Free Software Foundation; either version 2, or (at your option) any
      9;  later version.
     10;
     11;  This library is distributed in the hope that it will be useful,
     12;  but WITHOUT ANY WARRANTY; without even the implied warranty of
     13;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     14;  GNU General Public License for more details.
     15;
     16;  You should have received a copy of the GNU General Public License 
     17;  along with this library; see the file COPYING. If not, write to the
     18;  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
     19;   MA 02110-1301, USA.
     20;
     21;  As a special exception, if you link this library with other files,
     22;  some of which are compiled with SDCC, to produce an executable,
     23;  this library does not by itself cause the resulting executable to
     24;  be covered by the GNU General Public License. This exception does
     25;  not however invalidate any other reasons why the executable file
     26;   might be covered by the GNU General Public License.
     27;--------------------------------------------------------------------------
     28
     29	.area   _CODE
     30
     31	.globl _itoa
     32	.globl _uitoa
     33;
     34;void __itoa(int value, char *string, unsigned char radix);
     35;
     36_itoa::
     37	push	ix
     38	ld	ix, #0
     39	add	ix, sp
     40;
     41;	4(ix) - value
     42;	6(ix) - string
     43;	8(ix) - radix
     44;
     45	ld	e, 4 (ix)
     46	ld	d, 5 (ix)
     47	bit	7, d
     48	jr	Z, ___uitoa_de
     49;positive/negative numbers are supported only for radix=10
     50	ld	a, 8 (ix)
     51	cp	a, #10
     52	jr	NZ, ___uitoa_de
     53;add minus sign to result and inverse value
     54	ld	hl, #0
     55	or	a, a
     56	sbc	hl, de
     57	ex	de, hl
     58	ld	l, 6 (ix)
     59	ld	h, 7 (ix)
     60	ld	(hl), #0x2D	;minus symbol
     61	inc	hl
     62	ld	6 (ix), l
     63	ld	7 (ix), h
     64	jr	___uitoa_dehl
     65;
     66;void __uitoa(unsigned int value, char *string, unsigned char radix);
     67;
     68_uitoa::
     69	push	ix
     70	ld	ix, #0
     71	add	ix, sp
     72;
     73;	4(ix) - value
     74;	6(ix) - string
     75;	8(ix) - radix
     76;
     77	ld	e, 4 (ix)
     78	ld	d, 5 (ix)
     79;
     80___uitoa_de:
     81	ld	l, 6 (ix)
     82	ld	h, 7 (ix)
     83;
     84___uitoa_dehl:
     85	ld	a, e
     86	or	a, d
     87	jr	NZ, 100$
     88;
     89	ld	(hl), #0x30
     90	inc	hl
     91	jp	190$
     92100$:
     93	ld	a, 8 (ix)
     94	cp	a, #10		;most popular radix
     95	jr	NZ, 110$
     96;
     97;-------- decimal convertion
     98; this algorithm up to 2 times faster than generic
     99;
    100	ld	c, l
    101	ld	b, h
    102	ld	hl, #-4
    103	add	hl, sp
    104	ld	sp, hl
    105	push	bc
    106	push	hl
    107	push	de
    108	call	___uitobcd
    109	ld	hl, #4
    110	add	hl, sp
    111	ld	sp, hl
    112	pop	de		;DE - pointer to string
    113	inc	hl
    114	inc	hl		;HL - pointer to BCD value
    115	ld	b, #3		;number of bytes in BCD value
    116	ld	a, #0x30	;ASCII code of '0'
    117103$:
    118	rrd
    119	ld	(de), a
    120	inc	de
    121	rrd
    122	ld	(de), a
    123	inc	de
    124	inc	hl
    125	djnz	103$
    126;
    127;	pop	af
    128;	pop	af
    129;skip trailing zeroes
    130	ld	b, #5		;real BCD number is at most 5 digits
    131	dec	de		;so always skip last zero
    132105$:
    133	dec	de
    134	ld	a, (de)
    135	cp	a, #0x30
    136	jr	NZ, 107$	;break loop if non-zero found
    137	djnz	105$
    138107$:
    139	inc	de		;always point to symbol next to last significant
    140	ex	de, hl
    141	jr	190$
    142;
    143;---------------------------
    144;
    145110$:
    146	cp	a, #2
    147	jr	C, 190$		;radix is less than 2
    148;
    149	ld	c, a
    150	dec	c
    151	and	a, c
    152	jr	NZ, 150$
    153;
    154;-------- radix is power of 2
    155;
    156; DE - value, HL - pointer to string, C - mask
    157120$:
    158	ld	a, e
    159	ld	b, c
    160125$:
    161	srl	d
    162	rr	e
    163	srl	b
    164	jr	NZ, 125$
    165;
    166	and	a, c
    167	add	a, #0x30
    168	cp	a, #0x3A ;convert to 0...9A...Z
    169	jr	C, 130$
    170	add	a, #7
    171130$:
    172	ld	(hl), a
    173	inc	hl
    174	ld	a, e
    175	or	a, d
    176	jr	NZ, 120$
    177	jr	190$
    178;
    179;---------------------------
    180;
    181;-------- custom radix (generic algorithm)
    182;
    183150$:
    184	ex	de, hl
    185160$:
    186	ld	c, 8 (ix)
    187	call	___divu16_8
    188	add	a, #0x30
    189	cp	a, #0x3A
    190	jr	C, 165$
    191	add	a, #7
    192165$:
    193	ld	(de), a
    194	inc	de
    195	ld	a, l
    196	or	h
    197	jr	NZ, 160$
    198	ex	de, hl
    199;	jr	190$
    200;
    201;---------------------------
    202;
    203;-------- finish string and reverse order
    204190$:
    205	ld	(hl), #0
    206	ld	e, 6 (ix)
    207	ld	d, 7 (ix)
    208	call	___strreverse_reg
    209	ld	sp, ix
    210	pop	ix
    211	ret
    212;
    213;
    214;in: HL - divident, C - divisor
    215;out: HL - quotient, A - remainder
    216___divu16_8:
    217	xor	a, a
    218	ld	b, #16
    219100$:
    220	add	hl, hl
    221	rla
    222	jr	c, 110$
    223	cp	a, c
    224	jr	c, 120$
    225110$:
    226	sub	a, c
    227	inc	l
    228120$:
    229	djnz	100$
    230	ret
    231