|
|
|
@ -7,110 +7,123 @@ |
|
|
|
|
|
|
|
|
|
; sized string: w_size=n b_c1 b_c2 ... b_cn |
|
|
|
|
|
|
|
|
|
; pointer where the "emit" routine address is stored |
|
|
|
|
ramallot write_emit_routine_p, 2 |
|
|
|
|
|
|
|
|
|
; initialise with the default "emit" |
|
|
|
|
write_init: |
|
|
|
|
mov #uart_emit, &write_emit_routine_p |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
; print a single hexadecimal digit |
|
|
|
|
; expects: |
|
|
|
|
; - a0: value to print (0-15) |
|
|
|
|
; - a1: "emit" routine to use |
|
|
|
|
write_custom_hexdigit: |
|
|
|
|
_write_hexdigit: |
|
|
|
|
add.b #'0', a0 |
|
|
|
|
cmp #':', a0 ; ':' = '9'+1 |
|
|
|
|
jl + |
|
|
|
|
add.b #39, a0 ; get to lowercase alpha |
|
|
|
|
+ mov a1, pc ; jump to "emit" (call/ret shortcut) |
|
|
|
|
+ mov &write_emit_routine_p, pc ; jump to "emit" (call/ret shortcut) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; print a byte, hexadecimal, unsigned |
|
|
|
|
; print a value, hexadecimal, unsigned |
|
|
|
|
; expects: |
|
|
|
|
; - a0: value to print |
|
|
|
|
; - a1: "emit" routine to call |
|
|
|
|
; - a2: if non zero, always print two digits |
|
|
|
|
uart_write_byte_hex: |
|
|
|
|
mov #uart_emit, a1 |
|
|
|
|
write_custom_byte_hex: |
|
|
|
|
push s3 |
|
|
|
|
mov.b a0, s3 |
|
|
|
|
rrc.b a0 |
|
|
|
|
rrc.b a0 |
|
|
|
|
rrc.b a0 |
|
|
|
|
rrc.b a0 |
|
|
|
|
and #0Fh, a0 |
|
|
|
|
; - a1: how many bits to print (multiple of 4) |
|
|
|
|
; - a2: if non zero, pad with zeroes |
|
|
|
|
; clobbers: t0 |
|
|
|
|
write_value_hex: |
|
|
|
|
push s0 ; let's not clobber anything |
|
|
|
|
|
|
|
|
|
mov a0, s0 |
|
|
|
|
add a2, s0 ; =0 iff printing 0 with no padding |
|
|
|
|
jnz + |
|
|
|
|
cmp #0, a2 |
|
|
|
|
jz ++ |
|
|
|
|
+ call #write_custom_hexdigit |
|
|
|
|
+ mov.b s3, a0 |
|
|
|
|
pop s3 |
|
|
|
|
and #0Fh, a0 |
|
|
|
|
jmp write_custom_hexdigit ; (call/ret shortcut) |
|
|
|
|
mov #4, a1 ; in that case, only print the last digit |
|
|
|
|
+ cmp #4, a1 ; check if we're only printing the last digit |
|
|
|
|
jnz + |
|
|
|
|
mov #1, a2 ; if yes, we're printing it |
|
|
|
|
+ mov a1, t0 ; t0: counter for |
|
|
|
|
- cmp #16, t0 ; .. rotating the first nibble to print into |
|
|
|
|
jeq + ; ... the highest nibble of a0 |
|
|
|
|
rla a0 |
|
|
|
|
inc t0 ; counting up to 16 |
|
|
|
|
jmp - |
|
|
|
|
+ mov a0, s0 ; save the value we are printing |
|
|
|
|
.loop ; main digit printing loop |
|
|
|
|
mov #4, t0 ; rotate next nibble into a0 |
|
|
|
|
- rla s0 ; mini loop |
|
|
|
|
rlc a0 |
|
|
|
|
dec t0 |
|
|
|
|
jnz - |
|
|
|
|
and #0Fh, a0 ; got the next digit in a0 now |
|
|
|
|
jnz .emit ; it's not zero => we're printing it |
|
|
|
|
cmp #0, a2 ; check if we're requesting not to print zeroes |
|
|
|
|
jz + ; yes, do not print |
|
|
|
|
.emit |
|
|
|
|
mov #1, a2 ; printing a digit, so printing the rest as well |
|
|
|
|
call #_write_hexdigit |
|
|
|
|
+ sub #4, a1 ; move to the next nibble |
|
|
|
|
jnz .loop ; finish if =0 |
|
|
|
|
|
|
|
|
|
pop s0 |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
; print a word, hexadecimal, unsigned, always four digits |
|
|
|
|
; expects: |
|
|
|
|
; - a0: value to print |
|
|
|
|
; - a1: "emit" routine to call |
|
|
|
|
; clobbers: a2 |
|
|
|
|
uart_write_word_hex_p: |
|
|
|
|
mov.w #uart_emit, a1 |
|
|
|
|
write_custom_word_hex_p: |
|
|
|
|
push.b a0 ; save the lower byte |
|
|
|
|
swpb a0 |
|
|
|
|
mov #1, a2 ; want leading zeroes |
|
|
|
|
call #write_custom_byte_hex ; only prints LSB of a0 |
|
|
|
|
pop a0 |
|
|
|
|
jmp write_custom_byte_hex |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; print a word, hexadecimal, unsigned, not padded |
|
|
|
|
; print a byte, hexadecimal, unsigned |
|
|
|
|
; expects: |
|
|
|
|
; - a0: value to print |
|
|
|
|
; - a1: "emit" routine to call |
|
|
|
|
; clobbers: a2 |
|
|
|
|
uart_write_word_hex: |
|
|
|
|
mov.w #uart_emit, a1 |
|
|
|
|
write_custom_word_hex: |
|
|
|
|
push.b a0 ; save the lower byte |
|
|
|
|
swpb a0 |
|
|
|
|
mov #0, a2 ; assume we won't want leading zeroes |
|
|
|
|
and #0FFh, a0 ; restrict and test |
|
|
|
|
jz + ; do not print zeroes |
|
|
|
|
call #write_custom_byte_hex |
|
|
|
|
mov #1, a2 ; want leading zeroes (as we printed the upper byte) |
|
|
|
|
+ pop a0 |
|
|
|
|
jmp write_custom_byte_hex |
|
|
|
|
; - a2: if non zero, always print two digits |
|
|
|
|
; clobbers: a1, t0 |
|
|
|
|
write_byte_hex: |
|
|
|
|
mov #8, a1 |
|
|
|
|
jmp write_value_hex |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; print a word, decimal, unsigned |
|
|
|
|
; expects: |
|
|
|
|
; - a0: value to print |
|
|
|
|
; - a1: "emit" routine to call |
|
|
|
|
; clobbers: t0 |
|
|
|
|
uart_write_word_dec: |
|
|
|
|
mov #uart_emit, a1 |
|
|
|
|
write_custom_word_dec: |
|
|
|
|
push a1 ; save "emit" |
|
|
|
|
call #to_bcd ; a1|a0 is now BCD |
|
|
|
|
mov a1, t0 |
|
|
|
|
pop a1 ; restore "emit" |
|
|
|
|
and #0Fh, t0 |
|
|
|
|
jz + ; skip leading 0 |
|
|
|
|
push a0 |
|
|
|
|
mov t0, a0 |
|
|
|
|
call #write_custom_hexdigit ; print fifth digit |
|
|
|
|
pop a0 |
|
|
|
|
jmp write_custom_word_hex_p |
|
|
|
|
+ jmp write_custom_word_hex |
|
|
|
|
; clobbers: a1, a2, t0 |
|
|
|
|
write_word_dec: |
|
|
|
|
call #to_bcd ; a2|a0 is now BCD |
|
|
|
|
and #0Fh, a2 |
|
|
|
|
jz write_word_hex ; skipping leading zeroes |
|
|
|
|
push a0 ; need to deal with fifth digit |
|
|
|
|
mov a2, a0 |
|
|
|
|
call #_write_hexdigit ; print fifth digit |
|
|
|
|
pop a0 ; here a2!=0 |
|
|
|
|
; ! continues onto write_word_hex below ! |
|
|
|
|
|
|
|
|
|
; print a word, hexadecimal, unsigned |
|
|
|
|
; expects: |
|
|
|
|
; - a0: value to print |
|
|
|
|
; - a2: if non-zero, pad with zeroes |
|
|
|
|
; clobbers: a1, t0 |
|
|
|
|
write_word_hex: |
|
|
|
|
mov #16, a1 |
|
|
|
|
jmp write_value_hex |
|
|
|
|
|
|
|
|
|
; expected usage: puts "text\n" |
|
|
|
|
; will type "text\n" out |
|
|
|
|
puts macro Text |
|
|
|
|
call #_write_puts_pc |
|
|
|
|
static_string Text |
|
|
|
|
endm |
|
|
|
|
|
|
|
|
|
; internal |
|
|
|
|
_write_puts_pc: ; sized string on stack (as a return address) |
|
|
|
|
mov @sp, a0 |
|
|
|
|
add @a0, @sp ; fix the return address |
|
|
|
|
incd @sp |
|
|
|
|
bit #1, @sp ; add 1 if odd |
|
|
|
|
jz write_str |
|
|
|
|
inc @sp |
|
|
|
|
; ! continues onto write_str below ! |
|
|
|
|
|
|
|
|
|
; print a sized string |
|
|
|
|
; expects: |
|
|
|
|
; - a0: sized string address |
|
|
|
|
; - data stack: data for variables printing (%..) |
|
|
|
|
; - if called as write_custom: a1: address for "emit" routine |
|
|
|
|
; clobbers: a0, potentially (flags): a2, t0, t1 |
|
|
|
|
uart_write_str: |
|
|
|
|
mov #uart_emit, a1 |
|
|
|
|
write_custom_str: |
|
|
|
|
; clobbers: potentially (flags): a1, a2, t0, t1 |
|
|
|
|
write_str: |
|
|
|
|
push s0 |
|
|
|
|
push s1 |
|
|
|
|
mov @a0+, s1 ; set up loop: s0:current, s1:end |
|
|
|
@ -123,30 +136,32 @@ write_custom_str: |
|
|
|
|
|
|
|
|
|
; logic to deal with % flags |
|
|
|
|
mov.b @s0+, a0 |
|
|
|
|
mov #1, a2 ; padding with 0s by default |
|
|
|
|
|
|
|
|
|
cmp #'B', a0 ; byte in hex |
|
|
|
|
jne + |
|
|
|
|
popda a0 ; get the value to be printed |
|
|
|
|
mov #1, a2 ; want leading zeroes |
|
|
|
|
call #write_custom_byte_hex |
|
|
|
|
mov #8, a1 ; want leading zeroes |
|
|
|
|
call #write_value_hex |
|
|
|
|
jmp - |
|
|
|
|
|
|
|
|
|
+ cmp #'W', a0 ; word (16bit) in hex, padded 4 digits |
|
|
|
|
jne + |
|
|
|
|
popda a0 ; get the value to be printed |
|
|
|
|
call #write_custom_word_hex_p |
|
|
|
|
mov #16, a1 |
|
|
|
|
call #write_value_hex |
|
|
|
|
jmp - |
|
|
|
|
|
|
|
|
|
+ cmp #'d', a0 ; unsigned decimal (16bit) |
|
|
|
|
jne + |
|
|
|
|
popda a0 ; get the value to be printed |
|
|
|
|
call #write_custom_word_dec |
|
|
|
|
call #write_word_dec |
|
|
|
|
jmp - |
|
|
|
|
|
|
|
|
|
+ ; another flag comes here ... |
|
|
|
|
|
|
|
|
|
.emit |
|
|
|
|
call a1 ; "emit" |
|
|
|
|
call &write_emit_routine_p ; "emit" |
|
|
|
|
cmp s1, s0 ; repeat until s0 reaches s1 |
|
|
|
|
jlo - |
|
|
|
|
|
|
|
|
@ -160,40 +175,18 @@ write_custom_str: |
|
|
|
|
; expects: |
|
|
|
|
; - a0: number to convert |
|
|
|
|
; returns: |
|
|
|
|
; - a1|a0 BCD |
|
|
|
|
; - a2|a0 BCD |
|
|
|
|
; clobbers: |
|
|
|
|
; - t0, t1 |
|
|
|
|
; - t0,t1 |
|
|
|
|
to_bcd: |
|
|
|
|
mov #16, t0 ; loop counter |
|
|
|
|
clr a1 ; 0, result MSD |
|
|
|
|
clr a2 ; 0, result MSD |
|
|
|
|
clr t1 ; 0, result LSD |
|
|
|
|
- rla a0 ; MSbit to carry |
|
|
|
|
dadd t1, t1 ; 2*result+carry to LSD |
|
|
|
|
dadd a1, a1 ; to MSD |
|
|
|
|
dadd a2, a2 ; to MSD |
|
|
|
|
dec t0 ; loop |
|
|
|
|
jnz - |
|
|
|
|
mov t1, a0 ; fix return value register |
|
|
|
|
ret |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; expected usage: uart_puts "text\n" |
|
|
|
|
; will send "text\n" to uart |
|
|
|
|
uart_puts macro Text |
|
|
|
|
call #_write_puts_pc |
|
|
|
|
static_string Text |
|
|
|
|
endm |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------------ |
|
|
|
|
; internals |
|
|
|
|
;------------------------------------------------------------------------------ |
|
|
|
|
|
|
|
|
|
_write_puts_pc: ; sized string on stack (as a return address) |
|
|
|
|
mov @sp, a0 |
|
|
|
|
add @a0, @sp ; fix the return address |
|
|
|
|
incd @sp |
|
|
|
|
bit #1, @sp ; add 1 if odd |
|
|
|
|
jz + |
|
|
|
|
inc @sp |
|
|
|
|
+ jmp uart_write_str |
|
|
|
|