summaryrefslogtreecommitdiffstats
path: root/src/mame/machine/hp9845_printer.h
blob: 0c8aea9e5947b1c40075f3dfd20e0399930e49e3 (plain) (blame)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// license:BSD-3-Clause
// copyright-holders:F. Ulivi
/*********************************************************************

    hp9845_printer.h

    HP9845 internal printer HLE

*********************************************************************/

#ifndef MAME_MACHINE_HP9845_PRINTER_H
#define MAME_MACHINE_HP9845_PRINTER_H

#pragma once

#include "imagedev/bitbngr.h"

#define MCFG_9845PRT_IRL_HANDLER(_devcb)                                \
	devcb = &downcast<hp9845_printer_device &>(*device).set_irl_handler(DEVCB_##_devcb);

#define MCFG_9845PRT_FLG_HANDLER(_devcb)                                \
	devcb = &downcast<hp9845_printer_device &>(*device).set_flg_handler(DEVCB_##_devcb);

#define MCFG_9845PRT_STS_HANDLER(_devcb)                                \
	devcb = &downcast<hp9845_printer_device &>(*device).set_sts_handler(DEVCB_##_devcb);

class hp9845_printer_device : public device_t
{
public:
	// construction/destruction
	hp9845_printer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	// configuration helpers
	template <class Object> devcb_base &set_irl_handler(Object &&cb) { return m_irl_handler.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_flg_handler(Object &&cb) { return m_flg_handler.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_sts_handler(Object &&cb) { return m_sts_handler.set_callback(std::forward<Object>(cb)); }

	// device-level overrides
	virtual const tiny_rom_entry *device_rom_region() const override;
	virtual void device_add_mconfig(machine_config &config) override;
	virtual void device_start() override;
	virtual void device_reset() override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;

	// PPU access
	DECLARE_READ16_MEMBER(printer_r);
	DECLARE_WRITE16_MEMBER(printer_w);

private:
	devcb_write_line m_irl_handler;
	devcb_write_line m_flg_handler;
	devcb_write_line m_sts_handler;

	required_device<bitbanger_device> m_prt_graph_out;
	required_device<bitbanger_device> m_prt_alpha_out;
	required_region_ptr<uint8_t> m_prt_chargen;

	emu_timer *m_timer;

	// Size of various buffers
	static constexpr unsigned REDEF_CH_COUNT = 9;
	static constexpr unsigned REDEF_BUFF_LEN = 77;

	// State
	bool m_display_mode;
	bool m_shifted;
	bool m_current_u_l;
	bool m_current_big;
	bool m_ibf;
	bool m_inten;
	bool m_busy;
	uint8_t m_ib;
	uint8_t m_pos;
	uint8_t m_line[ 80 ];
	uint8_t m_attrs[ 80 ];
	uint8_t m_redef_count;
	uint8_t m_redef_idx;
	uint8_t m_redef_chars[ REDEF_CH_COUNT ];
	uint8_t m_replace_count;
	uint8_t m_redef_buff[ REDEF_BUFF_LEN ];
	uint8_t m_next_replace;
	uint8_t m_rep_str_len;
	uint8_t m_rep_str_ptr;
	uint8_t m_octal_accum;
	int m_fsm_state;
	unsigned m_cur_line;

	// FSM states
	enum {
		FSM_NORMAL_TEXT,
		FSM_AFTER_CR,
		FSM_AFTER_ESC,
		FSM_AFTER_ESC_AMP,
		FSM_COLLECT_ESC_QMARK,
		FSM_AFTER_ESC_AMP_K,
		FSM_AFTER_ESC_AMP_K_01,
		FSM_AFTER_ESC_AMP_D,
		FSM_AFTER_ESC_AMP_N,
		FSM_AFTER_ESC_AMP_O,
		FSM_AFTER_ESC_AMP_O_C,
		FSM_AFTER_ESC_AMP_O_C_L,
		FSM_AFTER_ESC_AMP_L,
		FSM_AFTER_ESC_AMP_N_C,
		FSM_WAIT_ESC_Z
	};

	void state_reset();
	void insert_char(uint8_t ch);
	void start_new_line();
	static uint8_t get_ch_matrix_line(const uint8_t *matrix_base , unsigned line_no , const uint8_t *seq);
	unsigned print_560_pixels(unsigned line_no , const uint8_t *pixels);
	uint8_t get_ch_pixels(uint8_t ch , uint8_t attrs , unsigned matrix_line) const;
	static attotime burn_time(unsigned pixel_count);
	void print_line();
	void print_graphic_line();
	void crlf();
	void set_tab();
	void clear_tabs();
	void move_to_next_tab();
	void update_flg();
	bool is_ch_redef(uint8_t ch , unsigned& redef_number) const;
	uint8_t allocate_ch_redef(uint8_t& idx);
	bool is_ch_replaced(uint8_t ch , uint8_t& len , uint8_t& ptr) const;
	uint8_t free_redef_space() const;
	uint8_t apply_shifting(uint8_t ch) const;
	bool parse_octal(uint8_t ch);
	bool parse_ch(uint8_t ch);
	void update_fsm();
};

// device type definition
DECLARE_DEVICE_TYPE(HP9845_PRINTER, hp9845_printer_device)

#endif // MAME_MACHINE_HP9845_PRINTER_H