| 1529 | } |
| 1530 | |
| 1531 | static unsigned |
| 1532 | vesa_FindMode(unsigned long mode_addr, unsigned bits) |
| 1533 | { |
| 1534 | unsigned selected_mode; |
| 1535 | struct ModeInfoBlock mode_info0, mode_info; |
| 1536 | unsigned model = (bits == 8) ? 4 : 6; |
| 1537 | |
| 1538 | if (iflags.wc_video_width < 640) { |
| 1539 | iflags.wc_video_width = 640; |
| 1540 | } |
| 1541 | if (iflags.wc_video_height < 480) { |
| 1542 | iflags.wc_video_height = 480; |
| 1543 | } |
| 1544 | |
| 1545 | memset(&mode_info, 0, sizeof(mode_info)); |
| 1546 | selected_mode = 0xFFFF; |
| 1547 | while (1) { |
| 1548 | unsigned mode = _farpeekw(_dos_ds, mode_addr); |
| 1549 | if (mode == 0xFFFF) break; |
| 1550 | mode_addr += 2; |
| 1551 | |
| 1552 | /* Query the mode info; skip to next if not in fact supported */ |
| 1553 | if (!vesa_GetModeInfo(mode, &mode_info0)) continue; |
| 1554 | |
| 1555 | /* Check that the mode is acceptable */ |
| 1556 | if (mode_info0.XResolution < iflags.wc_video_width) continue; |
| 1557 | if (mode_info0.YResolution < iflags.wc_video_height) continue; |
| 1558 | if (mode_info0.NumberOfPlanes != 1) continue; |
| 1559 | if (mode_info0.BitsPerPixel != bits) continue; |
| 1560 | if (mode_info0.NumberOfBanks != 1) continue; |
| 1561 | if (mode_info0.MemoryModel != model) continue; |
| 1562 | if (mode_info0.ModeAttributes & 0x40) continue; |
| 1563 | |
| 1564 | /* The mode is OK. Accept it if it is smaller than any previous mode |
| 1565 | or if no previous mode is accepted. */ |
| 1566 | if (selected_mode == 0xFFFF |
| 1567 | || mode_info0.XResolution * mode_info0.YResolution |
| 1568 | < mode_info.XResolution * mode_info.YResolution) { |
| 1569 | selected_mode = mode; |
| 1570 | mode_info = mode_info0; |
| 1571 | } |
| 1572 | } |
| 1573 | |
| 1574 | return selected_mode; |
| 1575 | } |
| 1576 | |
| 1577 | /* |
| 1578 | * Write character 'ch', at (x,y) and |
no test coverage detected