.include "system.h65" .include "lcd.h65" .include "math.h65" .include "keypad.h65" .import home:absolute .segment "SPI" .export CODE_START CODE_START: .assert * = $5000, error, "SPI Code not at $5000" lda '$' jsr lcd::print_char lda #TEST_FMT sta ARG1 lda #TEST_OUT sta ARG3 lda #$a9 sta ARG4 lda #$3c sta ARG5 lda #$10 sta ARG6 jsr strf Print TEST_OUT stz kp::_DEBUG_VAL @loop: lda kp::_DEBUG_VAL jeq home bra @loop fmt_idx = $30 out_idx = $31 fmt_digit = $32 .proc strf stz out_idx stz fmt_idx stz fmt_digit ldx #0 ; index of format args @loop: ldy fmt_idx lda (ARG0),y beq @null cmp #'%' beq @percent @normal_char: ; store A in output string ldy out_idx sta (ARG2),y inc fmt_idx inc out_idx beq @out_overflow bra @loop @percent: ; check for format in next position iny sty fmt_idx lda (ARG0),y ; next char beq @null ; formats cmp #'9' ble @percent_number ; numbers < letters cmp #'x' beq @format_hex1 bra @normal_char @percent_number: cmp #'1' blt @normal_char ; NaN or zero ; todo covert from char jsr hex_char_to_int ; only 0-9 supported ; A is now number of digits to convert sta fmt_digit iny sty fmt_idx lda (ARG0),y ; next char beq @null cmp #'x' beq @format_hexN bra @normal_char @format_hexN: lda fmt_digit jsr int_to_hex_str bra @format_return @format_hex1: ; 1 byte hex -> 2 chars lda ARG4,x phx jsr int8_to_hex_str ldy out_idx sta (ARG2),y ; most sig digit iny beq @out_overflow txa sta (ARG2),y ; least sig digit iny beq @out_overflow sty out_idx plx inx ; 1 byte of args handeled ; bra @format_return @format_return: ; increment fmt_idx to swallow the formating char inc fmt_idx bra @loop @out_overflow: ; store 0 in last position ldy #$ff sty out_idx @store_null: lda #0 @null: ; store and return ldy out_idx sta (ARG2),y @rts: rts .endproc ;******************************************************************************** ; @function Convert a 1 byte number into two hex characters ; @param A: Number to convert ; @returns A: Most significant digit ; @returns X: Least significant digit ; @modifies A,X,Y ;******************************************************************************** .proc int8_to_hex_str pha and #%00001111 tay ldx HEX_CHARS_UPPER,y pla div A,16 and #%00001111 tay lda HEX_CHARS_UPPER,y rts .endproc ; todo error handling .proc hex_char_to_int cmp #'A' bge @char sbc #'0' rts @char: sbc #('A' - $A) rts .endproc ;******************************************************************************** ; @function Convert any int into hex ; @param ARG2-3: Address of output string ; @param Y: Offset onto output string ; @param A: Number of digits to convert ; @param X: Offset onto ARG4 = start of int (big endian) ; @returns Y: New offset onto output string ; @returns A: 0 ; @returns X: Offset onto ARG4 = past the end of number ; @modifies X,Y,A ;******************************************************************************** .proc int_to_hex_str cmp #0 @loop: beq @rts ; check done ; load next byte pha lda ARG4,x inx phx pha ; copy byte div A,16 ; get first 4 bits = first digit and #%00001111 phy tay lda HEX_CHARS_LOWER,y ply sta (ARG2),y iny pla ; get copy and #%00001111 ; lower 4 bits = second digit phy tay lda HEX_CHARS_LOWER,y ply sta (ARG2),y iny plx pla dec @rts: rts .endproc TEST_FMT: .asciiz "%x -> %x -> %x:)" TEST_OUT: .asciiz "TESTOUT" HEX_CHARS_UPPER: .byte "0123456789ABCDEF" HEX_CHARS_LOWER: .byte "0123456789abcdef"