AVRASM ver. 2.2.7 main.asm Mon Jun 19 19:48:15 2023 [builtin](2): Including file '/home/sergeyyarkov/.mchp_packs/Microchip/ATtiny_DFP/3.0.151/avrasm/inc\tn2313Adef.inc' main.asm(15): Including file 'definitions.asm' main.asm(16): Including file 'macros.asm' main.asm(215): Including file 'div16u.asm' div16u.asm(22): warning: Register r16 already defined by the .DEF directive main.asm(215): 'div16u.asm' included form here div16u.asm(23): warning: Register r17 already defined by the .DEF directive main.asm(215): 'div16u.asm' included form here div16u.asm(24): warning: Register r16 already defined by the .DEF directive main.asm(215): 'div16u.asm' included form here div16u.asm(25): warning: Register r17 already defined by the .DEF directive main.asm(215): 'div16u.asm' included form here div16u.asm(27): warning: Register r19 already defined by the .DEF directive main.asm(215): 'div16u.asm' included form here div16u.asm(28): warning: Register r20 already defined by the .DEF directive main.asm(215): 'div16u.asm' included form here [builtin](2): Including file '/home/sergeyyarkov/.mchp_packs/Microchip/ATtiny_DFP/3.0.151/avrasm/inc\tn2313Adef.inc' main.asm(15): Including file 'definitions.asm' main.asm(16): Including file 'macros.asm' main.asm(215): Including file 'div16u.asm' ; ;***** Created: 2011-02-09 12:04 ******* Source: ATtiny2313A.xml ********* ;************************************************************************* ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y ;* ;* Number : AVR000 ;* File Name : "tn2313Adef.inc" ;* Title : Register/Bit Definitions for the ATtiny2313A ;* Date : 2011-02-09 ;* Version : 2.35 ;* Support E-mail : avr@atmel.com ;* Target MCU : ATtiny2313A ;* ;* DESCRIPTION ;* When including this file in the assembly program file, all I/O register ;* names and I/O register bit names appearing in the data book can be used. ;* In addition, the six registers forming the three data pointers X, Y and ;* Z have been assigned names XL - ZH. Highest RAM address for Internal ;* SRAM is also defined ;* ;* The Register names are represented by their hexadecimal address. ;* ;* The Register Bit names are represented by their bit number (0-7). ;* ;* Please observe the difference in using the bit names with instructions ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" ;* (skip if bit in register set/cleared). The following example illustrates ;* this: ;* ;* in r16,PORTB ;read PORTB latch ;* sbr r16,(1< ; **** СЕГМЕНТ ДАННЫХ ******************************************** .DSEG .ORG SRAM_START 000060 MCU_STATE: .BYTE 1 ; Текущее состояние МК 000061 SRAM_TEMP_1: .BYTE 2 ; Хранения временного 16-бит числа в ячейке 000063 DIGITS: .BYTE 4 ; Ячейки, где хранятся символы, для вывода на индикатор 000067 CURRENT_DIGIT: .BYTE 1 ; Номер разряда индикатора, который сейчас горит 000068 SW_FLAGS: .BYTE 1 ; Состояние кнопок 000069 HYSTERESIS: .BYTE 1 ; Отклонение температуры от уставки 00006a TEMP_L: .BYTE 1 00006b TEMP_H: .BYTE 1 ;// // ; **** СЕГМЕНТ КОДА ********************************************** .CSEG // .ORG 0x00 000000 c049 rjmp RESET_vect .ORG 0x000D 00000d c000 rjmp TIMER0_COMPA_vect // // ; **** ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ ************************************ TIMER0_COMPA_vect: 00000e 934f push r20 00000f 935f push r21 000010 930f push r16 000011 b75f in r21, SREG 000012 9140 0067 lds r20, CURRENT_DIGIT 000014 3045 cpi r20, 5 000015 f40c brge _CLR_CURRENT_DIGIT ; сброс активного разряда если >= 5 000016 c003 rjmp _indicate_1 _CLR_CURRENT_DIGIT: ; сброс текущего активного разряда в ноль 000017 2744 clr r20 000018 9340 0067 sts CURRENT_DIGIT, r20 _indicate_1: 00001a 3040 cpi r20, 0 00001b f441 brne _indicate_2 00001c 9893 cbi PORTD, DIGIT_2_PIN 00001d 9894 cbi PORTD, DIGIT_3_PIN 00001e 9895 cbi PORTD, DIGIT_4_PIN 00001f 9a92 sbi PORTD, DIGIT_1_PIN 000020 9100 0066 lds TEMP_REG_A, DIGITS+3 000022 d12b rcall DISPLAY_DECODER 000023 d0b6 rcall USI_TRANSMIT _indicate_2: 000024 3041 cpi r20, 1 000025 f441 brne _indicate_3 000026 9892 cbi PORTD, DIGIT_1_PIN 000027 9894 cbi PORTD, DIGIT_3_PIN 000028 9895 cbi PORTD, DIGIT_4_PIN 000029 9a93 sbi PORTD, DIGIT_2_PIN 00002a 9100 0065 lds TEMP_REG_A, DIGITS+2 00002c d121 rcall DISPLAY_DECODER 00002d d0ac rcall USI_TRANSMIT _indicate_3: 00002e 3042 cpi r20, 2 00002f f441 brne _indicate_4 000030 9892 cbi PORTD, DIGIT_1_PIN 000031 9893 cbi PORTD, DIGIT_2_PIN 000032 9895 cbi PORTD, DIGIT_4_PIN 000033 9a94 sbi PORTD, DIGIT_3_PIN 000034 9100 0064 lds TEMP_REG_A, DIGITS+1 000036 d117 rcall DISPLAY_DECODER 000037 d0a2 rcall USI_TRANSMIT _indicate_4: 000038 3043 cpi r20, 3 000039 f441 brne _indicate_exit 00003a 9892 cbi PORTD, DIGIT_1_PIN 00003b 9893 cbi PORTD, DIGIT_2_PIN 00003c 9894 cbi PORTD, DIGIT_3_PIN 00003d 9a95 sbi PORTD, DIGIT_4_PIN 00003e 9100 0063 lds TEMP_REG_A, DIGITS 000040 d10d rcall DISPLAY_DECODER 000041 d098 rcall USI_TRANSMIT _indicate_exit: 000042 9543 inc r20 000043 9340 0067 sts CURRENT_DIGIT, r20 000045 bf5f out SREG, r21 000046 910f pop r16 000047 915f pop r21 000048 914f pop r20 000049 9518 reti ;// ; **** СТАРТ ПРОГРАММЫ ******************************************* RESET_vect: 00004a ed0f ldi TEMP_REG_A, LOW(RAMEND) 00004b bf0d out SPL, TEMP_REG_A // ; **** ПРОЦЕСС ИНИЦИАЛИЗАЦИИ МК ********************************** MCU_INIT: ; **** ИНИЦИАЛИЗАЦИЯ ПИНОВ ************************************* 00004c e70e 00004d bb01 outi r16, DDRD, (1< // ; **** ГЛАВНЫЙ ЦИКЛ ********************************************** LOOP: ; rcall DISPLAY_UPD_DIGITS 00006b 9100 0060 lds r16, MCU_STATE ; получаем текущее состояние МК _STATE_DEFAULT: 00006d 3000 cpi r16, MCU_STATE_DEFAULT 00006e f489 brne _STATE_PROGRAM 00006f d0c4 rcall DISPLAY_UPD_DIGITS 000070 fd70 sbrc OWFR, OWPRF 000071 9a96 sbi PORTD, PD6 000072 ff70 sbrs OWFR, OWPRF 000073 9896 cbi PORTD, PD6 000074 d059 rcall TEMP_CONV 000075 d0e3 rcall DEBOUNCE_SW 000076 d0e2 rcall DEBOUNCE_SW 000077 d0e1 rcall DEBOUNCE_SW 000078 d0e0 rcall DEBOUNCE_SW 000079 d02e rcall TEMP_RD 00007a 9110 006a lds r17, TEMP_L 00007c 2f81 mov DISP_NUM_L, r17 00007d 9110 006b lds r17, TEMP_H 00007f 2f91 mov DISP_NUM_H, r17 _STATE_PROGRAM: 000080 3001 cpi r16, MCU_STATE_PROGRAM 000081 f411 brne _STATE_ERROR 000082 d0b1 rcall DISPLAY_UPD_DIGITS 000083 d062 rcall SW_CHECK_PROCESS _STATE_ERROR: 000084 3002 cpi r16, MCU_STATE_ERROR 000085 f729 brne LOOP 000086 e01b ldi r17, 11 000087 9310 0063 sts DIGITS, r17 000089 9310 0064 sts DIGITS+1, r17 00008b 9310 0065 sts DIGITS+2, r17 00008d 9310 0066 sts DIGITS+3, r17 00008f 0000 nop 000090 cfda rjmp LOOP // ; **** ПОДПРОГРАММЫ ********************************************** .INCLUDE "div16u.asm" ;* ;* "div16u" - 16/16 Bit Unsigned Division ;* ;* This subroutine divides the two 16-bit numbers ;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor). ;* The result is placed in "dres16uH:dres16uL" and the remainder in ;* "drem16uH:drem16uL". ;* ;* Number of words :19 ;* Number of cycles :235/251 (Min/Max) ;* Low registers used :2 (drem16uL,drem16uH) ;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH, ;* dcnt16u) ;* ;*************************************************************************** ;***** Subroutine Register Variables .def drem16uL=r14 .def drem16uH=r15 .def dres16uL=r16 .def dres16uH=r17 .def dd16uL =r16 .def dd16uH =r17 .def dv16uL =r18 .def dv16uH =r19 .def dcnt16u =r20 ;***** Code div16u: 000091 24ee clr drem16uL ; clear remainder Low byte 000092 18ff sub drem16uH,drem16uH ; clear remainder High byte and carry 000093 e141 ldi dcnt16u,17 ; init loop counter d16u_1: 000094 1f00 rol dd16uL ; shift left dividend 000095 1f11 rol dd16uH 000096 954a dec dcnt16u ; decrement counter 000097 f409 brne d16u_2 ; if done 000098 9508 ret ; return d16u_2: 000099 1cee rol drem16uL ; shift dividend into remainder 00009a 1cff rol drem16uH 00009b 1ae2 sub drem16uL,dv16uL ; remainder = remainder - divisor 00009c 0af3 sbc drem16uH,dv16uH 00009d f420 brcc d16u_3 ; if result negative 00009e 0ee2 add drem16uL,dv16uL ; restore remainder 00009f 1ef3 adc drem16uH,dv16uH 0000a0 9488 clc ; clear carry to be shifted into result 0000a1 cff2 rjmp d16u_1 ; else d16u_3: 0000a2 9408 sec ; set carry to be shifted into result 0000a3 cff0 DELAY_LOOP_16: 0000a4 5041 subi DELAY_8_r, 1 0000a5 4030 sbci DELAY_16_r, 0 0000a6 f7e8 brcc DELAY_LOOP_16 0000a7 9508 ret // TEMP_RD: 0000a8 930f push r16 0000a9 931f push r17 0000aa 932f push r18 0000ab 94f8 cli 0000ac d03f rcall OW_PRESENCE 0000ad ec0c ldi r16, DS18B20_CMD_SKIPROM 0000ae 2e80 mov OW_CMD_r, r16 0000af d04f rcall OW_SEND_BYTE 0000b0 eb0e ldi r16, DS18B20_CMD_RSCRATCHPAD 0000b1 2e80 mov OW_CMD_r, r16 0000b2 d04c rcall OW_SEND_BYTE 0000b3 e6aa ldi XL, LOW(TEMP_L) 0000b4 e0b0 ldi XH, HIGH(TEMP_L) 0000b5 d066 rcall OW_RD_BYTE 0000b6 e6ab ldi XL, LOW(TEMP_H) 0000b7 e0b0 ldi XH, HIGH(TEMP_H) 0000b8 d063 rcall OW_RD_BYTE 0000b9 9110 006a lds r17, TEMP_L 0000bb 9120 006b lds r18, TEMP_H 0000bd 9526 lsr r18 0000be 9517 ror r17 0000bf 9526 lsr r18 0000c0 9517 ror r17 0000c1 9526 lsr r18 0000c2 9517 ror r17 0000c3 9526 lsr r18 0000c4 9517 ror r17 0000c5 9310 006a sts TEMP_L, r17 0000c7 9320 006b sts TEMP_H, r18 0000c9 9478 sei 0000ca 912f pop r18 0000cb 911f pop r17 0000cc 910f pop r16 0000cd 9508 ret ; TEMP_CONV: 0000ce 930f push r16 0000cf 94f8 cli 0000d0 d01b rcall OW_PRESENCE 0000d1 ec0c ldi r16, DS18B20_CMD_SKIPROM 0000d2 2e80 mov OW_CMD_r, r16 0000d3 d02b rcall OW_SEND_BYTE 0000d4 e404 ldi r16, DS18B20_CMD_CONVERTTEMP 0000d5 2e80 mov OW_CMD_r, r16 0000d6 d028 rcall OW_SEND_BYTE 0000d7 9478 sei 0000d8 910f pop r16 0000d9 9508 ret // // ; **** ОТПРАВКА БАЙТА В СДВИГОВЫЙ РЕГИСТР ************************* USI_TRANSMIT: 0000da 930f push r16 0000db b80f out USIDR, r0 ; Байт для отправки всегда находится в регистре r0. Помещаем данные в регистр USIDR. ; Enable USI Overflow Interrupt Flag (will be 0 if transfer is not compeleted) 0000dc e400 ldi TEMP_REG_A, (1< USI Wire Mode ; USICS1 <--------------> USI Clock Source Select ; USICLK <--------------> USI Clock Strobe ; USITC <--------------> USI Toggle Clock (Enable clock generation) 0000de e10b ldi TEMP_REG_A, (1< // SW_CHECK_PROCESS: 0000e6 d072 rcall DEBOUNCE_SW 0000e7 9bb2 sbis SW_PIN, SW_PLUS_PIN 0000e8 9601 adiw DISP_NUM_L, 1 0000e9 9bb3 sbis SW_PIN, SW_MINUS_PIN 0000ea 9701 sbiw DISP_NUM_L, 1 0000eb 9508 ret// // // ; **** ОПРОС ПРИСУТСТВИЯ УСТРОЙСТВА ****************************** OW_PRESENCE: 0000ec 9ab9 ow_pull 0000ed e033 0000ee eb4e 0000ef dfb4 DELAY16 480 0000f0 98b9 ow_release 0000f1 e030 0000f2 e84a 0000f3 dfb0 DELAY16 70 0000f4 d004 rcall OW_CHECK_PRESENCE 0000f5 e033 0000f6 e342 0000f7 dfac DELAY16 410 0000f8 9508 ret // // ; **** ПРОВЕРКА НАЛИЧИЯ УСТРОЙСТВА ******************************* ; Если подчиненное устройство притянет шину, то устанавливаем флаг OWPRF в единицу в регистре флагов ; OW_CHECK_PRESENCE: 0000f9 9bb1 sbis OW_PIN, OW_LINE 0000fa 6071 sbr OWFR, (1< // OW_SEND_BYTE: 0000ff 930f push r16 000100 931f push r17 000101 2d08 mov r16, OW_CMD_r 000102 e018 ldi r17, 8 _OW_SEND_BYTE_LOOP: 000103 9506 lsr r16 000104 f408 brcc _OW_SEND_0 000105 f048 brcs _OW_SEND_1 _OW_SEND_0: 000106 9ab9 ow_pull 000107 e030 000108 e746 000109 df9a DELAY16 60 00010a 98b9 ow_release 00010b e030 00010c e142 00010d df96 DELAY16 10 00010e c008 rjmp _OW_SEND_BYTE_END _OW_SEND_1: 00010f 9ab9 ow_pull 000110 e030 000111 e04a 000112 df91 DELAY16 6 000113 98b9 ow_release 000114 e030 000115 e74e 000116 df8d DELAY16 64 _OW_SEND_BYTE_END: 000117 951a dec r17 000118 f751 brne _OW_SEND_BYTE_LOOP 000119 911f pop r17 00011a 910f pop r16 00011b 9508 ret // // ;OW_RD_BYTE: ; push r16 ; push r17 ; ldi r16, 8 ;_OW_RD_BYTE_LP: ; ow_pull ; DELAY16 6 ; ow_release ; DELAY16 9 ; lds r17, TEMP_L ; lsr r17 ; sbic OW_PIN, OW_LINE ; sbr r17, (1<<7) ; sts TEMP_L, r17 ; DELAY16 55 ; dec r16 ; brne _OW_RD_BYTE_LP ; pop r17 ; pop r16 ; ret OW_RD_BYTE: 00011c 930f push r16 00011d 931f push r17 00011e 2700 clr r16 00011f e018 ldi r17, 8 _OW_RD_BYTE_LP: 000120 9506 lsr r16 000121 9ab9 ow_pull 000122 e030 000123 e04a 000124 df7f DELAY16 6 000125 98b9 ow_release 000126 e030 000127 e140 000128 df7b DELAY16 9 000129 99b1 sbic OW_PIN, OW_LINE 00012a 6800 sbr r16, (1<<7) 00012b e030 00012c e64c 00012d df76 DELAY16 55 00012e 951a dec r17 00012f f781 brne _OW_RD_BYTE_LP 000130 930c st X, r16 000131 911f pop r17 000132 910f pop r16 000133 9508 ret // // // ; **** ПОЛУЧЕНИЕ ЦИФР ИЗ 16-ТИ БИТНОГО ЧИСЛА ********************* ; Описание: Перемещает цифры числа в соответствующие ячейки памяти в SRAM ; путем деления этого числа несколько раз DISPLAY_UPD_DIGITS: 000134 94f8 cli 000135 935f push r21 000136 e054 ldi r21, 4 ; (4 раза делим) т.к индикатор четырех разрядный ; инициализация указателя (за каждый проход цикла будет инкрементироваться) 000137 e6a3 ldi XL, LOW(DIGITS) 000138 e0b0 ldi XH, HIGH(DIGITS) .equ dividend = SRAM_TEMP_1 ; число которе будем делить .equ divisor = 10 ; на что делим ; загружаем число которое хотим поделить в адрес SRAM делимого 000139 9380 0061 sts dividend, DISP_NUM_L 00013b 9390 0062 sts dividend+1, DISP_NUM_H ; четыре раза производим деление для получения остатков DIV_LOOP: ; заполняем нужные регистры 00013d 9100 0061 lds dd16uL, dividend 00013f 9110 0062 lds dd16uH, dividend+1 000141 e02a ldi dv16uL, LOW(divisor) 000142 e030 ldi dv16uH, HIGH(divisor) 000143 df4d rcall div16u ; делим 000144 92ed st X+, drem16uL ; сохраняем остаток в ячейку по указателю и увеличиваем его ; обновляем делимое 000145 9300 0061 sts dividend, dres16uL 000147 9310 0062 sts dividend+1, dres16uH 000149 955a dec r21 ; декрементируем счетчик цикла 00014a f791 brne DIV_LOOP ; делим еще раз если не 0 00014b 915f pop r21 00014c 9478 sei 00014d 9508 ret // // ; **** ЗАГРУЖАЕТ НУЖНЫЙ АДРЕС СИМВОЛА В R0 *********************** DISPLAY_DECODER: 00014e 930f push r16 00014f 931f push r17 000150 eeee ldi ZL, LOW(2*DISPLAY_SYMBOLS) 000151 e0f2 ldi ZH, HIGH(2*DISPLAY_SYMBOLS) 000152 2711 clr TEMP_REG_B 000153 0fe0 add ZL, TEMP_REG_A 000154 1ff1 adc ZH, TEMP_REG_B 000155 9004 lpm r0, Z 000156 911f pop r17 000157 910f pop r16 000158 9508 ret// // DEBOUNCE_SW: 000159 930f push r16 00015a 931f push r17 00015b 932f push r18 00015c e02a ldi r18, 10 _loop_2: 00015d ef1f ldi r17, 255 _loop_0: 00015e ef0f ldi r16, 255 _dec_0: 00015f 950a dec r16 000160 f7f1 brne _dec_0 _loop_1: 000161 951a dec r17 000162 f7d9 brne _loop_0 _loop_3: 000163 952a dec r18 000164 f7c1 brne _loop_2 000165 912f pop r18 000166 911f pop r17 000167 910f pop r16 000168 9508 ret// // DELAY: 000169 930f push r16 00016a 931f push r17 00016b ef0f ldi r16, 255 _DELAY_1: 00016c ef1f ldi r17, 255 _DELAY_2: 00016d 951a dec r17 00016e 0000 nop 00016f 0000 nop 000170 0000 nop 000171 f7d9 brne _DELAY_2 000172 950a dec r16 000173 f7c1 brne _DELAY_1 000174 911f pop r17 000175 910f pop r16 000176 9508 ret // // DISPLAY_SYMBOLS: ; HGFEDCBA HGFEDCBA 000177 f9c0 .DB 0b11000000, 0b11111001 ; 0, 1 000178 b0a4 .DB 0b10100100, 0b10110000 ; 2, 3 000179 9299 .DB 0b10011001, 0b10010010 ; 4, 5 00017a f882 .DB 0b10000010, 0b11111000 ; 6, 7 00017b 9080 .DB 0b10000000, 0b10010000 ; 8, 9 00017c bf9c .DB 0b10011100, 0b10111111 ; °, -// // // ; **** СЕГМЕНТ EEPROM ******************************************** ; .ESEG ; INFO: .DB "AVR Thermostat. Written by Sergey Yarkov 22.01.2023" ; RESOURCE USE INFORMATION ------------------------ Notice: The register and instruction counts are symbol table hit counts, and hence implicitly used resources are not counted, eg, the 'lpm' instruction without operands implicitly uses r0 and z, none of which are counted. x,y,z are separate entities in the symbol table and are counted separately from r26..r31 here. .dseg memory usage only counts static data declared with .byte "ATtiny2313A" register use summary: x : 2 y : 0 z : 1 r0 : 2 r1 : 2 r2 : 0 r3 : 0 r4 : 0 r5 : 0 r6 : 0 r7 : 0 r8 : 5 r9 : 0 r10: 0 r11: 0 r12: 0 r13: 0 r14: 5 r15: 5 r16: 75 r17: 40 r18: 15 r19: 14 r20: 25 r21: 8 r22: 0 r23: 4 r24: 6 r25: 4 r26: 3 r27: 3 r28: 0 r29: 0 r30: 2 r31: 2 Registers used: 20 out of 35 (57.1%) "ATtiny2313A" instruction use summary: .lds : 0 .sts : 0 adc : 2 add : 2 adiw : 1 and : 0 andi : 0 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0 brcc : 3 brcs : 1 break : 0 breq : 0 brge : 1 brhc : 0 brhs : 0 brid : 0 brie : 0 brlo : 0 brlt : 0 brmi : 0 brne : 16 brpl : 0 brsh : 0 brtc : 0 brts : 0 brvc : 0 brvs : 0 bset : 0 bst : 0 cbi : 18 cbr : 1 clc : 1 clh : 0 cli : 3 cln : 0 clr : 6 cls : 0 clt : 0 clv : 0 clz : 0 com : 0 cp : 0 cpc : 0 cpi : 8 cpse : 0 dec : 9 eor : 0 icall : 0 ijmp : 0 in : 1 inc : 1 ld : 0 ldd : 0 ldi : 58 lds : 13 lpm : 2 lsl : 0 lsr : 6 mov : 8 movw : 0 neg : 0 nop : 4 or : 0 ori : 0 out : 12 pop : 20 push : 20 rcall : 38 ret : 14 reti : 1 rjmp : 9 rol : 4 ror : 4 sbc : 1 sbci : 1 sbi : 10 sbic : 2 sbis : 4 sbiw : 1 sbr : 2 sbrc : 1 sbrs : 1 sec : 1 seh : 0 sei : 3 sen : 0 ser : 0 ses : 0 set : 0 sev : 0 sez : 0 sleep : 0 spm : 0 st : 2 std : 0 sts : 16 sub : 2 subi : 1 swap : 0 tst : 0 wdr : 0 Instructions used: 46 out of 105 (43.8%) "ATtiny2313A" memory use summary [bytes]: Segment Begin End Code Data Used Size Use% --------------------------------------------------------------- [.cseg] 0x000000 0x0002fa 726 12 738 2048 36.0% [.dseg] 0x000060 0x00006c 0 12 12 128 9.4% [.eseg] 0x000000 0x000000 0 0 0 128 0.0% Assembly complete, 0 errors, 6 warnings