1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
/*
* Copyright (C) 2022-2022 The DOSBox Staging Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PARALLEL_PORT_H_
#define PARALLEL_PORT_H_
#include "bit_view.h"
// There are three hexadecimal addresses commonly
// used for parallel ports: 378h, 278h, 3BCh.
// These are absolute addresses, fixed in memory.
// They can be distinguished from them “logical”
// addresses accessed by users and many programs:
// LPT 1, LPT 2, LPT 3, ...
// These logical addresses
// can be interpreted as “1st Line Printer, 2nd
// Line Printer, 3rd Line Printer,…”
// Consequently, one cannot have a “2nd Line
// Printer,” without having a “1st Line Printer.” –
// ie: You can’t get a LPT 2, unless you already
// have a LPT 1.
// Ref: http://faq.lavalink.com/2006/11/understanding-parallel-port-addressing/
enum LptPorts : io_port_t {
Lpt1Port = 0x378,
Lpt2Port = 0x278,
Lpt3Port = 0x3bc,
};
// The Parallel port has three registers:
// Name Read/write Port offset
// ~~~~ ~~~~~~~~~~ ~~~~~~~~~~~
// Data write-only 0
// Status read-only 1
// Control write-only 2
union LptStatusRegister {
uint8_t data = 0xff;
bit_view<0, 2> reserved;
bit_view<2, 1> irq;
bit_view<3, 1> error;
bit_view<4, 1> select_in;
bit_view<5, 1> paper_out;
bit_view<6, 1> ack;
bit_view<7, 1> busy;
};
// The ERROR, ACK and BUSY signals are active-low when reading from the IO port.
union LptControlRegister {
uint8_t data = 0;
bit_view<0, 1> strobe;
bit_view<1, 1> auto_lf;
bit_view<2, 1> initialize;
bit_view<3, 1> select;
bit_view<4, 1> irq_ack;
bit_view<5, 1> bidi;
bit_view<6, 1> bit6; // unused
bit_view<7, 1> bit7; // unused
};
// The INITIALISE signal is active low when writing to the IO port.
// The STROBE signal is for handshaking and alerts the printer to data
// being ready at the data port.
// AUTO_LF is the Automatic Line-Feed signal. If this is set and the
// printer receives a Carriage-Return character (0x0D), the printer will
// automatically perform a Line-Feed (character 0x0A) as well.
// INITIALISE, sometimes called PRIME, alerts the device that data that
// a data conversation is about to start. This signal may result in a
// printer performing a reset and any buffers being flushed.
// Protocol: data is sent to the connected device by writing the byte to
// the data port, then pulsing the STROBE signal. This pulse informs the
// device that data is ready to be read. The device will respond by
// raising its BUSY signal and then reading the data and performing some
// processing on it. Once this processing is complete, the device will
// lower the Busy signal and may raise a brief ACK signal to indicate
// that it has finished.
// Ref: https://wiki.osdev.org/Parallel_port
#endif
|