#include #include #include #include #include #include #define PORT_80 0x80 #define SCAN_DELAY 5000 const unsigned char segment_codes[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, // 0-7 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, // 8-F 0x00, 0x40 // Off, horizontal bar }; typedef struct { int running; int display_value; } DisplayContext; DisplayContext ctx = {1, 0}; void signal_handler(int sig) { printf("\nExiting...\n"); ctx.running = 0; outb(0x00, PORT_80); // Clear Display } // Initialize I/O permissions int init_io() { if (iopl(3) < 0) { perror("iopl failed"); return -1; } return 0; } // Display a single number at the specified position void display_digit(int digit, int position) { unsigned char code; if (digit < 0 || digit > 15) { code = segment_codes[16]; // 熄灭 } else { code = segment_codes[digit]; } // Position 0 uses low 4 bits, and position 1 uses high 4 bits (depending on hardware connection) if (position == 0) { outb(code, PORT_80); } else { outb(code, PORT_80); } } // Display two digits void display_two_digits(int num) { char value = num & 0xff; outb(value, PORT_80); return; int tens = num / 10; int ones = num % 10; int scan_count = 50; for (int i = 0; i < scan_count && ctx.running; i++) { // Display ten digits outb(segment_codes[tens], PORT_80); usleep(SCAN_DELAY); // Display one digit outb(segment_codes[ones], PORT_80); usleep(SCAN_DELAY); } } // Display a number in hexadecimal format void display_hex(int value) { char values = value & 0xff; outb(values, PORT_80); return; // for (int i = 0; i < 50 && ctx.running; i++) { // outb(segment_codes[high], PORT_80); // usleep(SCAN_DELAY); // outb(segment_codes[low], PORT_80); // usleep(SCAN_DELAY); // } } // Display a number in decimal format void blink_display(int num, int times) { for (int i = 0; i < times && ctx.running; i++) { display_two_digits(num); usleep(500000); // 500ms outb(0x00, PORT_80); usleep(300000); // 300ms } } // Scroll a text message across the display void scroll_display(const char *text) { int len = strlen(text); for (int i = 0; i <= len && ctx.running; i++) { for (int j = 0; j < 20 && ctx.running; j++) { if (i < len) { int digit = text[i] - '0'; if (digit >= 0 && digit <= 9) { outb(segment_codes[digit], PORT_80); } } usleep(SCAN_DELAY); } } } int main(int argc, char *argv[]) { int choice = 0; int value; if (init_io() < 0) { printf("error\n"); return 1; } signal(SIGINT, signal_handler); for (int i = 0; i < 3 && ctx.running; i++) { outb(0xFF, PORT_80); usleep(300000); outb(0x00, PORT_80); usleep(200000); } printf("test finish\n\n"); while (ctx.running) { printf("\nPlease select a mode:\n"); printf("1. Show Numbers (0-99)\n"); printf("2. Display Hex (00-FF)\n"); printf("3. Flashing display\n"); printf("4. Scrolling\n"); printf("5. counter\n"); printf("6. exit\n"); printf("select: "); if (scanf("%d", &choice) != 1) { while(getchar() != '\n'); continue; } switch(choice) { case 1: printf("Enter numbers (0-99): "); scanf("%d", &value); if (value >= 0 && value <= 99) { printf("show %d\n", value); display_two_digits(value); } break; case 2: printf("Enter hexadecimal value (00-FF): "); scanf("%x", &value); if (value >= 0 && value <= 0xFF) { printf("show 0x%02X\n", value); display_hex(value); } break; case 3: printf("Enter numbers and flashes: "); scanf("%d %d", &value, &choice); blink_display(value, choice); break; case 4: printf("Input digital string: "); char text[10]; scanf("%s", text); scroll_display(text); break; case 5: printf("Counter mode (press Ctrl+C to exit)\n"); for (int i = 0; i <= 99 && ctx.running; i++) { printf("\rcount: %d", i); fflush(stdout); display_two_digits(i); } printf("\n"); break; case 6: ctx.running = 0; break; default: printf("Invalid selection\n"); } } // 清理 outb(0x00, PORT_80); printf("\nexit\n"); return 0; }