From 826234a93d516bc4ce2c8e73053f753dde553b9b Mon Sep 17 00:00:00 2001 From: giomba Date: Thu, 12 Aug 2021 18:26:03 +0200 Subject: [PATCH] multiple frames --- frame.cpp | 177 +++++++++++++++++++++++++++--------------------------- main.S | 94 ++++++++++++++++++++++++++--- 2 files changed, 176 insertions(+), 95 deletions(-) diff --git a/frame.cpp b/frame.cpp index e2d29f6..7f96f9e 100644 --- a/frame.cpp +++ b/frame.cpp @@ -13,16 +13,10 @@ enum ExitStatus { }; int main(int argc, char** argv) { - if (argc != 2) { + if (argc < 2) { return BAD_ARGUMENT; } - std::fstream infile; - infile.open(argv[1], std::ios::in); - if (! infile) { - return FILE_NOT_OPEN; - } - std::fstream outfile; outfile.open("frame.S", std::ios::out); if (! outfile) { @@ -32,91 +26,100 @@ int main(int argc, char** argv) { outfile << "#include \"macro.h\"" << std::endl; outfile << "#include " << std::endl; - outfile << ".global line_jump_table" << std::endl; - outfile << "line_jump_table:" << std::endl; - for (int i = 0; i < 256; ++i) { - outfile << '\t' << "jmp line_" << i << std::endl; - } - - int width, height; - std::string format; - char c; - - getline(infile, format); - - std::cout << format << std::endl; - - if (format != "P1") { - return FILE_BAD_FORMAT; - } - - // skip one line TODO - getline(infile, format); - std::cout << format << std::endl; - - infile >> width >> height; - std::cout << width << " x " << height << std::endl; - - char* image = new char[height * width]; - - for (int y = 0; y < height; ) { - for (int x = 0; x < width; ) { - c = infile.get(); - if (! infile.good()) - return FILE_BAD_FORMAT; - if (c == '0' || c == '1') { - image[y * width + x] = c; - x++; - } else { - continue; - } + for (int current_image = 0; current_image < argc - 1; ++current_image) { + outfile << ".global line_jump_table_" << current_image << std::endl; + outfile << "line_jump_table_" << current_image << ":" << std::endl; + for (int i = 0; i < 256; ++i) { + outfile << '\t' << "jmp line_" << current_image << "_" << i << std::endl; } - y++; } - infile.close(); - - for (int y = 0; y < height; ++y) { - outfile << "line_" << y << ":" << std::endl; - - int count = 0; - char last = image[y * width + 0]; - - for (int x = 0; x < width; ++x) { - char current = image[y * width + x]; - std::cout << "current " << current << " last " << last << std::endl; - if (current == last) { - ++count; - } else { - std::cout << "detected change" << std::endl; - if (last == '0') { - std::cout << "clear" << std::endl; - outfile << '\t' << "cbi IO(PORTB), 4" << std::endl; - } else if (last == '1') { - std::cout << "set" << std::endl; - outfile << '\t' << "sbi IO(PORTB), 4" << std::endl; - } - - if (count > 1) { - outfile << '\t' << "ldi r31, " << count - 1 << std::endl; - outfile << "1:" << std::endl; - outfile << '\t' << "dec r31" << std::endl; - outfile << '\t' << "nop" << std::endl; - outfile << '\t' << "brne 1b" << std::endl; - } - - outfile << '\t' << "rjmp 2f" << std::endl; - outfile << "2:" << std::endl; - - last = current; - count = 1; - } - - + for (int current_image = 0; current_image < argc - 1; ++current_image) { + std::fstream infile; + infile.open(argv[1 + current_image], std::ios::in); + if (! infile) { + return FILE_NOT_OPEN; } - outfile << '\t' << "cbi IO(PORTB), 4" << std::endl; - outfile << '\t' << "jmp jump_table_return_address" << std::endl; + int width, height; + std::string format; + char c; + + getline(infile, format); + + std::cout << format << std::endl; + + if (format != "P1") { + return FILE_BAD_FORMAT; + } + + // skip one line TODO + getline(infile, format); + std::cout << format << std::endl; + + infile >> width >> height; + std::cout << width << " x " << height << std::endl; + + char* image = new char[height * width]; + + for (int y = 0; y < height; ) { + for (int x = 0; x < width; ) { + c = infile.get(); + if (! infile.good()) + return FILE_BAD_FORMAT; + if (c == '0' || c == '1') { + image[y * width + x] = c; + x++; + } else { + continue; + } + } + y++; + } + + infile.close(); + + for (int y = 0; y < height; ++y) { + outfile << "line_" << current_image << "_" << y << ":" << std::endl; + + int count = 0; + char last = image[y * width + 0]; + + for (int x = 0; x < width; ++x) { + char current = image[y * width + x]; + std::cout << "current " << current << " last " << last << std::endl; + if (current == last) { + ++count; + } else { + std::cout << "detected change" << std::endl; + if (last == '0') { + std::cout << "clear" << std::endl; + outfile << '\t' << "cbi IO(PORTB), 4" << std::endl; + } else if (last == '1') { + std::cout << "set" << std::endl; + outfile << '\t' << "sbi IO(PORTB), 4" << std::endl; + } + + if (count > 1) { + outfile << '\t' << "ldi r31, " << count - 1 << std::endl; + outfile << "1:" << std::endl; + outfile << '\t' << "dec r31" << std::endl; + outfile << '\t' << "nop" << std::endl; + outfile << '\t' << "brne 1b" << std::endl; + } + + outfile << '\t' << "rjmp 2f" << std::endl; + outfile << "2:" << std::endl; + + last = current; + count = 1; + } + } + outfile << '\t' << "cbi IO(PORTB), 4" << std::endl; + outfile << '\t' << "jmp jump_table_return_address" << std::endl; + } + + delete[] image; } diff --git a/main.S b/main.S index bd955d9..0bda2c1 100644 --- a/main.S +++ b/main.S @@ -2,11 +2,25 @@ #include "macro.h" #include "const.h" + +.data +image: +.byte 0xff + +show_image: +.byte 0x00 + +button_next_image: +.byte 0x0 + +current_jump_table: +.word 0x0 + .text .global main main: - ldi r16, 0x30 ; port B, pin 4 and 5 as output + ldi r16, 0x30 ; port B, pin 4 and 5 as output, others as input sts DDRB, r16 ; set interrupt vectors at address 0x0, not bootloader @@ -34,6 +48,10 @@ main: sts line, r16 ldi r16, 0xfe sts line + 1, r16 + ldi r16, 0xff + sts image, r16 + ldi r16, 0 + sts show_image, r16 ; r0 always holds 0 clr r0 @@ -98,10 +116,17 @@ int_timer_0: andi r31, 0xfd ; mask disable interrupt timer A sts TIMSK0, r31 - clr r0 - ldi zl, pm_lo8(line_jump_table) - ldi zh, pm_hi8(line_jump_table) + lds r31, show_image + cpi r31, 0x1 + brne jump_table_return_address + lds zl, current_jump_table + lds zh, current_jump_table + 1 + +; ldi zl, pm_lo8(line_jump_table_0) +; ldi zh, pm_hi8(line_jump_table_0) + + clr r0 lds r29, line add zl, r29 adc zh, r0 @@ -123,8 +148,10 @@ jump_table_return_address: int_vertical_sync: push r31 in r31, IO(SREG) - push r31 - push r30 + push zl + push zh + push yl + push yh lds r31, frame + 1 lds r30, frame @@ -137,9 +164,60 @@ int_vertical_sync: sts line, r30 sts line + 1, r31 + ; check button + in r31, IO(PINB) + andi r31, 0x08 + breq check_if_released + ldi r31, 1 + sts button_next_image, r31 + jmp int_vertical_sync_end + +check_if_released: + lds r31, button_next_image + cpi r31, 1 + brne int_vertical_sync_end + + ; here button is released + lds r31, show_image + cpi r31, 1 + breq 1f + + ldi r31, 1 + sts show_image, r31 + rjmp 2f +1: + ldi r31, 0 + sts show_image, r31 + rjmp end_button_release +2: + ; show image + + ldi zl, pm_lo8(line_jump_table_0) + ldi zh, pm_hi8(line_jump_table_0) + + clr yl + lds yh, image + inc yh + sts image, yh + + add zh, yh + add zh, yh + + sts current_jump_table, zl + sts current_jump_table + 1, zh + + ldi r31, 0x01 + sts show_image, r31 + +end_button_release: + clr yl + sts button_next_image, yl + int_vertical_sync_end: - pop r30 - pop r31 + pop yh + pop yl + pop zh + pop zl out IO(SREG), r31 pop r31 reti