cscg22-gearboy

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

__ltoa.s (4365B)


      1;--------------------------------------------------------------------------
      2;  __ltoa.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 _ltoa
     32	.globl _ultoa
     33;
     34;void __itoa(long value, char *string, unsigned char radix);
     35;
     36_ltoa::
     37	push	ix
     38	ld	ix, #0
     39	add	ix, sp
     40;
     41;	4(ix) - value
     42;	8(ix) - string
     43;	10(ix) - radix
     44;
     45	ld	e, 4 (ix)
     46	ld	d, 5 (ix)
     47	bit	7, 7 (ix)
     48	jr	Z, ___ultoa_de
     49;positive/negative numbers are supported only for radix=10
     50	ld	a, 10 (ix)
     51	cp	a, #10
     52	jr	NZ, ___ultoa_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	hl, #0
     59	ld	c, 6 (ix)
     60	ld	b, 7 (ix)
     61	sbc	hl, bc
     62	ld	6 (ix), l
     63	ld	7 (ix), h
     64	ld	l, 8 (ix)
     65	ld	h, 9 (ix)
     66	ld	(hl), #0x2D	;minus symbol
     67	inc	hl
     68	ld	8 (ix), l
     69	ld	9 (ix), h
     70	jr	___ultoa_dehl
     71;
     72;void __uitoa(unsigned int value, char *string, unsigned char radix);
     73;
     74_ultoa::
     75	push	ix
     76	ld	ix, #0
     77	add	ix, sp
     78;
     79;	4(ix) - value
     80;	8(ix) - string
     81;	10(ix) - radix
     82;
     83	ld	e, 4 (ix)
     84	ld	d, 5 (ix)
     85;
     86___ultoa_de:
     87	ld	l, 8 (ix)
     88	ld	h, 9 (ix)
     89;
     90___ultoa_dehl:
     91	ld	a, e
     92	or	a, d
     93	or	a, 6 (ix)
     94	or	a, 7 (ix)
     95	jr	NZ, 100$
     96;
     97	ld	(hl), #0x30
     98	inc	hl
     99	jp	190$
    100100$:
    101	ld	a, 10 (ix)
    102	cp	a, #10		;most popular radix
    103	jr	NZ, 110$
    104;
    105;-------- decimal convertion
    106;this algorithm is 20% faster than generic one
    107;
    108	ld	c, l
    109	ld	b, h
    110	ld	hl, #-5
    111	add	hl, sp
    112	ld	sp, hl
    113	push	bc
    114	push	hl
    115	ld	c, 6 (ix)
    116	ld	b, 7 (ix)
    117	push	bc
    118	push	de
    119	call	___ultobcd
    120	ld	hl, #6
    121	add	hl, sp
    122	ld	sp, hl
    123	pop	de		;DE - pointer to string
    124	inc	hl
    125	inc	hl		;HL - pointer to BCD value
    126	ld	b, #5		;number of bytes in BCD value
    127	ld	a, #0x30	;ASCII code of '0'
    128103$:
    129	rrd
    130	ld	(de), a
    131	inc	de
    132	rrd
    133	ld	(de), a
    134	inc	de
    135	inc	hl
    136	djnz	103$
    137;
    138;	ld	sp, hl
    139;skip trailing zeroes
    140	ld	b, #10		;real decimal number is at most 10 digits
    141105$:
    142	dec	de
    143	ld	a, (de)
    144	cp	a, #0x30
    145	jr	NZ, 107$	;break loop if non-zero found
    146	djnz	105$
    147107$:
    148	inc	de		;always point to symbol next to last significant
    149	ex	de, hl
    150	jr	190$
    151;
    152;---------------------------
    153;
    154110$:
    155	cp	a, #2
    156	jr	C, 190$		;radix is less than 2
    157;
    158	ld	c, a
    159	dec	c
    160	and	a, c
    161	jr	NZ, 150$
    162;
    163;-------- radix is power of 2
    164;
    165; DE - lower 16 bits of value, HL - pointer to string, C - mask
    166120$:
    167	ld	a, e
    168	ld	b, c
    169125$:
    170	srl	7 (ix)
    171	rr	6 (ix)
    172	rr	d
    173	rr	e
    174	srl	b
    175	jr	NZ, 125$
    176;
    177	and	a, c
    178	add	a, #0x30
    179	cp	a, #0x3A ;convert to 0...9A...Z
    180	jr	C, 130$
    181	add	a, #7
    182130$:
    183	ld	(hl), a
    184	inc	hl
    185	ld	a, e
    186	or	a, d
    187	or	a, 6 (ix)
    188	or	a, 7 (ix)
    189	jr	NZ, 120$
    190	jr	190$
    191;
    192;---------------------------
    193;
    194;-------- custom radix (generic algorithm)
    195;
    196150$:
    197	ex	de, hl
    198	ld	c, e
    199	ld	b, d
    200	ld	e, 6 (ix)
    201	ld	d, 7 (ix)
    202160$:
    203	push	bc
    204	ld	c, 10 (ix)
    205	call	___divu32_8
    206	pop	bc
    207	add	a, #0x30
    208	cp	a, #0x3A
    209	jr	C, 165$
    210	add	a, #7
    211165$:
    212	ld	(bc), a
    213	inc	bc
    214	ld	a, l
    215	or	a, h
    216	or	a, e
    217	or	a, d
    218	jr	NZ, 160$
    219	ld	l, c
    220	ld	h, b
    221;	jr	190$
    222;
    223;---------------------------
    224;
    225;-------- finish string and reverse order
    226190$:
    227	ld	(hl), #0
    228	ld	e, 8 (ix)
    229	ld	d, 9 (ix)
    230	call	___strreverse_reg
    231	ld	sp, ix
    232	pop	ix
    233	ret
    234;
    235;in: DEHL - divident, C - divisor
    236;out: DEHL - quotient, A - remainder
    237___divu32_8:
    238	xor	a, a
    239	ld	b, #32
    240100$:
    241	add	hl, hl
    242	rl	e
    243	rl	d
    244	rla
    245	jr	c, 110$
    246	cp	a, c
    247	jr	c, 120$
    248110$:
    249	sub	a, c
    250	inc	l
    251120$:
    252	djnz	100$
    253	ret
    254