/* dump-asm.S */
/*
This file is part of the AVR-Huffman.
Copyright (C) 2009 Daniel Otte (daniel.otte@rub.de)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "avr-asm-macros.S"
#include
#include
#define DUMP_WIDTH 16
#define ADDR_BASE 16
/******************************************************************************/
/* uint8_t charisinstr_P(char c, PGM_P str)
* param c: r24
* param str: r22:r23
*/
charisinstr_P:
movw r30, r22
1:
lpm r22, Z+
tst r22
brne 2f
clr r24
ret
2:
cp r22, r24
brne 1b
ldi r24, 1
ret
/******************************************************************************/
/* void dump_chars(uint8_t* buffer, uint8_t len)
* param buffer: r24:r25
* param len: r22
*/
dump_chars:
push r16
push r17
push r28
push r29
movw r28, r24
mov r16, r22
ldi r24, '|'
clr r25
call cli_putc
mov r17, r16
1:
ld r24, Y
clr r25
call isprint
tst r24
brne 2f
ldi r24, '.'
adiw r28, 1
rjmp 3f
2: ld r24, Y+
3:
clr r25
call cli_putc
dec r17
brne 1b
subi r16, DUMP_WIDTH
tst r16
breq 5f
neg r16
4:
ldi r24, ' '
clr r25
call cli_putc
dec r16
brne 4b
5:
ldi r24, '|'
clr r25
call cli_putc
pop r29
pop r28
pop r17
pop r16
ret
/*****************************************************************************/
/* void print_aligned(unsigned long value, uint8_t align)
* param value: r22:r25
* param align: r20
*/
print_aligned:
push r16
push r28
push r29
stack_alloc 12, r28, r29
adiw r28, 1
mov r16, r20
movw r20, r28
ldi r18, ADDR_BASE
clr r19
call ultoa
movw r24, r28
call strlen
sub r16, r24
brmi 3f
breq 3f
1:
ldi r24, ' '
clr r25
call cli_putc
dec r16
brne 1b
3:
movw r24, r28
call cli_putstr
stack_free 12
pop r29
pop r28
pop r16
ret
/*****************************************************************************/
/* void dump(char* s)
* param s: r24:r25
*/
STR_0 = 4
STR_1 = 5
ADDR_0 = 6
ADDR_1 = 7
ADDR_2 = 8
ADDR_3 = 9
SIZE_0 = 10
SIZE_1 = 11
SIZE_2 = 12
SIZE_3 = 13
MEM_0 = 14
MEM_1 = 15
xREADLEN = 16
TMP = 17
.global dump
dump:
call strstrip
push_range 4, 17
push_range 28, 29
movw r26, r24
ld TMP, X
movw STR_0, r26
ldi r30, lo8(memtype_desc)
ldi r31, hi8(memtype_desc)
1:
lpm r22, Z+
lpm r23, Z+
tst r22
brne 2f
tst r23
breq 5f
2:
movw r28, r30
mov r24, TMP
clr r25
rcall charisinstr_P
movw r30, r28
tst r24
brne 6f
adiw r30, 4
rjmp 1b
5:
ldi r30, lo8(memtype_desc+2)
ldi r31, hi8(memtype_desc+2)
6:
movw MEM_0, r30
movw r26, STR_0
61:
ld r20, X+
ori r20, 'A'^'a'
cpi r20, 'a'
brmi 7f
cpi r20, 'z'+1
brge 7f
rjmp 61b
7:
sbiw r26, 1
stack_alloc 2+DUMP_WIDTH, r28, r29
adiw r28, 1
movw r24, r26
movw r22, r28
clr r20
clr r21
call strtoul
movw ADDR_0, r22
movw ADDR_2, r24
ld r24, Y+
ld r25, Y+
clr r23
clr r22
clr r21
clr r20
call strtoul
movw SIZE_0, r22
movw SIZE_2, r24
tst SIZE_0
brne 72f
tst SIZE_1
brne 72f
tst SIZE_2
brne 72f
tst SIZE_3
brne 72f
ldi TMP, 128
mov SIZE_0, TMP
72:
ldi r24, lo8(dumping)
ldi r25, hi8(dumping)
call cli_putstr_P
movw r24, SIZE_2
movw r22, SIZE_0
movw r20, r28
clr r19
ldi r18, 10
call ultoa
movw r24, r28
call cli_putstr
ldi r24, lo8(bytesof)
ldi r25, hi8(bytesof)
call cli_putstr_P
movw r30, MEM_0
lpm r24, Z+
lpm r25, Z+
call cli_putstr_P
ldi r24, lo8(beginning)
ldi r25, hi8(beginning)
call cli_putstr_P
movw r24, ADDR_2
movw r22, ADDR_0
movw r20, r28
clr r19
ldi r18, 16
call ultoa
movw r24, r28
call cli_putstr
ldi r24, lo8(suffix)
ldi r25, hi8(suffix)
call cli_putstr_P
movw r30, MEM_0
adiw r30, 2
lpm MEM_0, Z+
lpm MEM_1, Z
1:
ldi xREADLEN, DUMP_WIDTH
tst SIZE_3
brne 3f
tst SIZE_2
brne 3f
tst SIZE_1
brne 3f
tst SIZE_0
brne 2f
rjmp 90f
2:
cp DUMP_WIDTH, SIZE_0
brmi 3f
mov xREADLEN, SIZE_0
3:
movw r24, r28
movw r22, ADDR_2
movw r20, ADDR_0
clr r19
mov r18, xREADLEN
movw r30, MEM_0
icall
movw r24, ADDR_2
movw r22, ADDR_0
clr r21
ldi r20, 6
rcall print_aligned
clr r25
ldi r24, ':'
call cli_putc
clr r25
ldi r24, ' '
call cli_putc
movw r24, r28
clr r23
mov r22, xREADLEN
call cli_hexdump2
ldi TMP, DUMP_WIDTH
sub TMP, xREADLEN
tst TMP
breq 5f
4:
clr r25
ldi r24, ' '
call cli_putc
clr r25
ldi r24, ' '
call cli_putc
clr r25
ldi r24, ' '
call cli_putc
dec TMP
brne 4b
5:
clr r25
ldi r24, '\t'
call cli_putc
movw r24, r28
clr r23
mov r22, xREADLEN
rcall dump_chars
add ADDR_0, xREADLEN
adc ADDR_1, r1
adc ADDR_2, r1
adc ADDR_3, r1
sub SIZE_0, xREADLEN
sbc SIZE_1, r1
sbc SIZE_2, r1
sbc SIZE_3, r1
clr r25
ldi r24, '\r'
call cli_putc
clr r25
ldi r24, '\n'
call cli_putc
rjmp 1b
90:
stack_free 2+DUMP_WIDTH
pop_range 28,29
pop_range 4, 17
ret
dumping:
.asciz "\r\ndumping "
bytesof:
.asciz " bytes of "
beginning:
.asciz ", beginnig at 0x"
suffix:
.asciz ":\r\n"
.byte 0
/******************************************************************************/
/* void pgm_read_block(void* buffer, uint32_t addr, uint8_t length)
* param buffer: r24:r25
* param addr: r20:r23
* param length: r18
*/
.global pgm_read_block
pgm_read_block:
#if RAMEND<0x10000
movw r26, r24
movw r30, r20
tst r18
breq 3f
1:
lpm r20, Z+
st X+, r20
dec r18
brne 1b
3:
ret
#else
movw r26, r24
movw r30, r20
out RAMPZ, r22
tst r18
breq 3f
1:
elpm r20, Z+
st X+, r20
dec r18
brne 1b
3:
ret
#endif
/******************************************************************************/
/* void ram_read_block(void* buffer, uint32_t addr, uint8_t length)
* param buffer: r24:r25
* param addr: r20:r23
* param length: r18
*/
.global ram_read_block
ram_read_block:
movw r26, r24
movw r30, r20
tst r18
breq 3f
1:
ld r20, Z+
st X+, r20
dec r18
brne 1b
3:
ret
/******************************************************************************/
/* void ee_read_block(void* buffer, uint32_t addr, uint8_t length)
* param buffer: r24:r25
* param addr: r20:r23
* param length: r18
*/
#ifdef EEWE
# define EEPE EEWE
#endif
.global ee_read_block
ee_read_block:
movw r26, r24
movw r30, r20
tst r18
breq 3f
1:
sbic _SFR_IO_ADDR(EECR), EEPE
rjmp 1b
out _SFR_IO_ADDR(EEARH), r31
out _SFR_IO_ADDR(EEARL), r30
sbi _SFR_IO_ADDR(EECR), EERE
adiw r30, 1
in r20, _SFR_IO_ADDR(EEDR)
st X+, r20
dec r18
brne 1b
3:
ret