c65gm/lib/decoutlib.c65

188 lines
4 KiB
Text

//------------------------------------------------------------------------
// Decimal Output Library
//
// Purpose: Display BYTE and WORD values as decimal numbers
//
// Functions:
// lib_decout_decoutb({BYTE value}) - Print BYTE (0-255) as decimal
// lib_decout_decoutw({WORD value}) - Print WORD (0-65535) as decimal
//
// Dependencies: cbmiolib.c65 (for lib_cbmio_print)
// No ZP usage required
//
// Algorithm: Repeated subtraction per decimal place
// - decoutb: max 7 iterations (2+5+0 for 255)
// - decoutw: max 19 iterations (6+5+5+3+0 for 65535)
// No division needed, self-contained, ~5-6x faster than general div
//------------------------------------------------------------------------
#IFNDEF __LIB_DECOUT
#DEFINE __LIB_DECOUT = 1
GOTO lib_decout_skip
//-----------------------------------------------------------
// Output string buffer (5 digits + null terminator = 6 bytes)
//-----------------------------------------------------------
ASM
lib_decout_buf
!8 0,0,0,0,0,0
ENDASM
//-----------------------------------------------------------
// Pointer for building the output string
// Non-ZP: compiler uses self-modifying code for POKE
//-----------------------------------------------------------
WORD lib_decout_ptr
//-----------------------------------------------------------
// decoutb - Display BYTE (0-255) as decimal with leading zero
// suppression
//-----------------------------------------------------------
FUNC lib_decout_decoutb ( {BYTE value} )
BYTE digit
BYTE leading
BYTE ch
POINTER lib_decout_ptr TO lib_decout_buf
leading = 0
// Hundreds place
digit = 0
WHILE value >= 100
value = value - 100
digit++
WEND
IF digit != 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
leading = 1
ENDIF
// Tens place
digit = 0
WHILE value >= 10
value = value - 10
digit++
WEND
IF digit != 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
leading = 1
ENDIF
IF leading != 0
IF digit == 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
ENDIF
ENDIF
// Ones place
ch = value + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
POKE lib_decout_ptr , 0
CALL lib_cbmio_print ( @lib_decout_buf )
FEND
//-----------------------------------------------------------
// decoutw - Display WORD (0-65535) as decimal with leading
// zero suppression
//-----------------------------------------------------------
FUNC lib_decout_decoutw ( {WORD value} )
BYTE digit
BYTE leading
BYTE ch
POINTER lib_decout_ptr TO lib_decout_buf
leading = 0
// Ten-thousands place
digit = 0
WHILE value >= 10000
value = value - 10000
digit++
WEND
IF digit != 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
leading = 1
ENDIF
// Thousands place
digit = 0
WHILE value >= 1000
value = value - 1000
digit++
WEND
IF digit != 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
leading = 1
ENDIF
IF leading != 0
IF digit == 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
ENDIF
ENDIF
// Hundreds place
digit = 0
WHILE value >= 100
value = value - 100
digit++
WEND
IF digit != 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
leading = 1
ENDIF
IF leading != 0
IF digit == 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
ENDIF
ENDIF
// Tens place
digit = 0
WHILE value >= 10
value = value - 10
digit++
WEND
IF digit != 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
leading = 1
ENDIF
IF leading != 0
IF digit == 0
ch = digit + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
ENDIF
ENDIF
// Ones place
ch = value + $30
POKE lib_decout_ptr , ch
INC lib_decout_ptr
POKE lib_decout_ptr , 0
CALL lib_cbmio_print ( @lib_decout_buf )
FEND
LABEL lib_decout_skip
#IFEND