diff --git a/src/lpt.c b/src/lpt.c index 5f904e692..6ae36ed35 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -118,6 +118,7 @@ lpt_write(uint16_t port, uint8_t val, void *priv) if (dev->dt && dev->dt->write_ctrl) dev->dt->write_ctrl(val, dev->priv); dev->ctrl = val; + dev->enable_irq = val & 0x10; break; } } @@ -139,19 +140,24 @@ lpt_read(uint16_t port, void *priv) case 1: if (dev->dt && dev->dt->read_status) - ret = dev->dt->read_status(dev->priv); + ret = dev->dt->read_status(dev->priv) | 0x0f; else ret = 0xdf; break; case 2: if (dev->dt && dev->dt->read_ctrl) - ret = dev->dt->read_ctrl(dev->priv); + ret = (dev->dt->read_ctrl(dev->priv) & 0xef) | dev->enable_irq; else - ret = 0xe0 | dev->ctrl; + ret = 0xe0 | dev->ctrl | dev->enable_irq; break; } + if (port < 0x278) { + uint32_t *p = NULL; + *p = 5; + } + return ret; } @@ -161,9 +167,7 @@ lpt_irq(void *priv, int raise) { lpt_port_t *dev = (lpt_port_t *) priv; - uint8_t ctrl = lpt_read(2, priv); - - if ((ctrl & 0x10) && (dev->irq != 0xff)) { + if (dev->enable_irq && (dev->irq != 0xff)) { if (raise) picint(1 << dev->irq); else @@ -177,11 +181,12 @@ lpt_init(void) { int i; uint16_t default_ports[3] = { 0x378, 0x278, 0x3bc }; - uint8_t default_irqs[3] = { 5, 7, 5 }; + uint8_t default_irqs[3] = { 7, 5, 7 }; for (i = 0; i < 3; i++) { lpt_ports[i].addr = 0xffff; lpt_ports[i].irq = 0xff; + lpt_ports[i].enable_irq = 0x10; if (lpt_ports[i].enabled) { lpt_port_init(i, default_ports[i]); diff --git a/src/lpt.h b/src/lpt.h index 87cb46f24..c6a95fc4e 100644 --- a/src/lpt.h +++ b/src/lpt.h @@ -37,7 +37,7 @@ typedef struct { uint8_t enabled, irq, dat, ctrl; uint16_t addr, pad0; - int device; + int device, enable_irq; lpt_device_t * dt; void * priv; } lpt_port_t; diff --git a/src/pit.c b/src/pit.c index f260541d1..1011334e9 100644 --- a/src/pit.c +++ b/src/pit.c @@ -32,7 +32,7 @@ double cpuclock, PITCONSTD, SYSCLK, isa_timing, bus_timing; -uint64_t PITCONST, +uint64_t PITCONST, ISACONST, CGACONST, MDACONST, HERCCONST, VGACONST1, VGACONST2, @@ -620,30 +620,21 @@ pit_set_clock(int clock) { /* Set default CPU/crystal clock and xt_cpu_multi. */ if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) { -#if 0 - cpuclock = (double) clock; -#else if (clock == 66666666) cpuclock = 200000000.0 / 3.0; else if (clock == 33333333) cpuclock = 100000000.0 / 3.0; else cpuclock = (double) clock; -#endif -#if 0 - PITCONST = (uint64_t) (cpuclock / 1193182.0 * (double)(1ull << 32)); -#else PITCONSTD = (cpuclock / 1193182.0); PITCONST = (uint64_t) (PITCONSTD * (double)(1ull << 32)); -#endif CGACONST = (uint64_t) ((cpuclock / (19687503.0/11.0)) * (double)(1ull << 32)); + ISACONST = (uint64_t) ((cpuclock / 8000000.0) * (double)(1ull << 32)); xt_cpu_multi = 1ULL; } else { cpuclock = 14318184.0; -#if 1 PITCONSTD = 12.0; -#endif PITCONST = (12ULL << 32ULL); CGACONST = (8ULL << 32ULL); xt_cpu_multi = 3ULL; @@ -682,20 +673,16 @@ pit_set_clock(int clock) } if (cpuclock == 28636368.0) { -#if 1 PITCONSTD = 24.0; -#endif PITCONST = (24ULL << 32LL); CGACONST = (16ULL << 32LL); } else if (cpuclock != 14318184.0) { -#if 0 - PITCONST = (uint64_t) ((cpuclock/1193182.0 * (double)(1ull << 32))); -#else PITCONSTD = (cpuclock / 1193182.0); PITCONST = (uint64_t) (PITCONSTD * (double)(1ull << 32)); -#endif CGACONST = (uint64_t) (((cpuclock/(19687503.0/11.0)) * (double)(1ull << 32))); } + + ISACONST = (1ULL << 32ULL); } xt_cpu_multi <<= 32ULL; diff --git a/src/pit.h b/src/pit.h index 72554306e..17585cf71 100644 --- a/src/pit.h +++ b/src/pit.h @@ -45,7 +45,7 @@ extern PIT pit, extern double SYSCLK; -extern uint64_t PITCONST, +extern uint64_t PITCONST, ISACONST, CGACONST, MDACONST, HERCCONST, diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index e45dba752..597105cd4 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -8,15 +8,15 @@ * * Implementation of the Generic ESC/P Dot-Matrix printer. * - * Version: @(#)prt_escp.c 1.0.6 2018/11/09 + * Version: @(#)prt_escp.c 1.0.7 2019/09/23 * * Authors: Michael Drüing, * Fred N. van Kempen, * * Based on code by Frederic Weymann (originally for DosBox.) * - * Copyright 2018 Michael Drüing. - * Copyright 2018 Fred N. van Kempen. + * Copyright 2018,2019 Michael Drüing. + * Copyright 2019,2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -62,6 +62,7 @@ #include "../timer.h" #include "../mem.h" #include "../rom.h" +#include "../pit.h" #include "../plat.h" #include "../plat_dynld.h" #include "../ui.h" @@ -201,6 +202,7 @@ typedef struct { void *lpt; + pc_timer_t pulse_timer; pc_timer_t timeout_timer; wchar_t page_fn[260]; @@ -290,8 +292,6 @@ typedef struct { uint8_t msb; /* MSB mode, -1 = off */ uint8_t ctrl; - uint8_t char_read; - PALETTE palcol; } escp_t; @@ -425,6 +425,20 @@ new_page(escp_t *dev, int8_t save, int8_t resetx) } +static void +pulse_timer(void *priv) +{ + escp_t *dev = (escp_t *) priv; + + if (dev->ack) { + dev->ack = 0; + lpt_irq(dev->lpt, 1); + } + + timer_disable(&dev->pulse_timer); +} + + static void timeout_timer(void *priv) { @@ -518,8 +532,8 @@ reset_printer(escp_t *dev) static void reset_printer_hard(escp_t *dev) { - dev->char_read = 0; - lpt_irq(dev->lpt, 1); + dev->ack = 0; + timer_disable(&dev->pulse_timer); timer_disable(&dev->timeout_timer); reset_printer(dev); } @@ -1590,8 +1604,6 @@ handle_char(escp_t *dev, uint8_t ch) uint16_t line_start, line_y; double x_advance; - dev->char_read = 1; - if (dev->page == NULL) return; @@ -1757,19 +1769,6 @@ draw_hline(escp_t *dev, unsigned from_x, unsigned to_x, unsigned y, int8_t broke } -static int8_t -print_ack(escp_t *dev) -{ - if (dev->char_read) { - dev->char_read = 0; - lpt_irq(dev->lpt, 1); - return 1; - } - - return 0; -} - - static void setup_bit_image(escp_t *dev, uint8_t density, uint16_t num_columns) { @@ -1980,6 +1979,7 @@ write_ctrl(uint8_t val, void *priv) /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; + timer_set_delay_u64(&dev->pulse_timer, ISACONST); timer_set_delay_u64(&dev->timeout_timer, 500000 * TIMER_USEC); } @@ -2016,7 +2016,7 @@ read_status(void *priv) ret |= 0x80; - if (!print_ack(dev)) + if (!dev->ack) ret |= 0x40; return(ret); @@ -2111,7 +2111,8 @@ escp_init(void *lpt) escp_log("ESC/P: created a virtual page of dimensions %d x %d pixels.\n", dev->page->w, dev->page->h); - timer_add(&dev->timeout_timer, timeout_timer, dev, 0); + timer_add(&dev->pulse_timer, pulse_timer, dev, 0); + timer_add(&dev->timeout_timer, timeout_timer, dev, 0); return(dev); } diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index a25616c67..aa56ae2e1 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -15,11 +15,11 @@ * printer mechanics. This would lead to a page being 66 lines * of 80 characters each. * - * Version: @(#)prt_text.c 1.0.6 2018/11/09 + * Version: @(#)prt_text.c 1.0.7 2019/09/23 * * Author: Fred N. van Kempen, * - * Copyright 2018 Fred N. van Kempen. + * Copyright 2018,2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -59,6 +59,7 @@ #include "../86box.h" #include "../device.h" #include "../timer.h" +#include "../pit.h" #include "../plat.h" #include "../lpt.h" #include "printer.h" @@ -104,6 +105,7 @@ typedef struct { wchar_t filename[1024]; /* Printer timeout. */ + pc_timer_t pulse_timer; pc_timer_t timeout_timer; /* page data (TODO: make configurable) */ @@ -198,6 +200,20 @@ new_page(prnt_t *dev) } +static void +pulse_timer(void *priv) +{ + prnt_t *dev = (prnt_t *) priv; + + if (dev->ack) { + dev->ack = 0; + lpt_irq(dev->lpt, 1); + } + + timer_disable(&dev->pulse_timer); +} + + static void timeout_timer(void *priv) { @@ -222,15 +238,12 @@ reset_printer(prnt_t *dev) dev->bot_margin = PAGE_BMARGIN; dev->cpi = PAGE_CPI; dev->lpi = PAGE_LPI; + dev->ack = 0; /* Default page layout. */ dev->max_chars = (int) ((dev->page_width - dev->left_margin - dev->right_margin) * dev->cpi); dev->max_lines = (int) ((dev->page_height -dev->top_margin - dev->bot_margin) * dev->lpi); - //INFO("PRNT: width=%.1fin,height=%.1fin cpi=%i lpi=%i cols=%i lines=%i\n", - // dev->page_width, dev->page_height, (int)dev->cpi, - // (int)dev->lpi, dev->max_chars, dev->max_lines); - dev->curr_x = dev->curr_y = 0; if (dev->page != NULL) @@ -239,7 +252,8 @@ reset_printer(prnt_t *dev) /* Create a file for this page. */ plat_tempfile(dev->filename, NULL, L".txt"); - timer_disable(&dev->timeout_timer); + timer_disable(&dev->pulse_timer); + timer_disable(&dev->timeout_timer); } @@ -395,6 +409,7 @@ write_ctrl(uint8_t val, void *priv) /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; + timer_set_delay_u64(&dev->pulse_timer, ISACONST); timer_set_delay_u64(&dev->timeout_timer, 500000 * TIMER_USEC); } @@ -406,19 +421,12 @@ static uint8_t read_status(void *priv) { prnt_t *dev = (prnt_t *)priv; - uint8_t ret = 0xff; + uint8_t ret = 0x1f; - if (dev == NULL) return(ret); + ret |= 0x80; - ret = (dev->ack ? 0x00 : 0x40) | - (dev->select ? 0x10 : 0x00) | - (dev->busy ? 0x00 : 0x80) | - (dev->int_pending ? 0x00 : 0x04) | - (dev->error ? 0x00 : 0x08); - - /* Clear ACK after reading status. */ - dev->ack = 0; - lpt_irq(dev->lpt, 1); + if (!dev->ack) + ret |= 0x40; return(ret); } @@ -445,6 +453,7 @@ prnt_init(void *lpt) dev->page->chars = (char *)malloc(dev->page->w * dev->page->h); memset(dev->page->chars, 0x00, dev->page->w * dev->page->h); + timer_add(&dev->pulse_timer, pulse_timer, dev, 0); timer_add(&dev->timeout_timer, timeout_timer, dev, 0); return(dev);