2017-11-26 18:28:26 +00:00
|
|
|
//
|
|
|
|
// 9918.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 25/11/2017.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2017 Thomas Harte. All rights reserved.
|
2017-11-26 18:28:26 +00:00
|
|
|
//
|
|
|
|
|
2017-12-15 01:27:26 +00:00
|
|
|
#ifndef TMS9918_hpp
|
|
|
|
#define TMS9918_hpp
|
2017-11-26 18:28:26 +00:00
|
|
|
|
|
|
|
#include "../../Outputs/CRT/CRT.hpp"
|
|
|
|
#include "../../ClockReceiver/ClockReceiver.hpp"
|
|
|
|
|
2017-12-15 01:27:26 +00:00
|
|
|
#include "Implementation/9918Base.hpp"
|
|
|
|
|
2017-11-26 21:47:59 +00:00
|
|
|
#include <cstdint>
|
|
|
|
|
2017-11-26 18:28:26 +00:00
|
|
|
namespace TI {
|
2018-09-18 02:59:16 +00:00
|
|
|
namespace TMS {
|
2017-11-26 18:28:26 +00:00
|
|
|
|
2017-12-15 01:27:26 +00:00
|
|
|
/*!
|
|
|
|
Provides emulation of the TMS9918a, TMS9928 and TMS9929. Likely in the future to be the
|
|
|
|
vessel for emulation of sufficiently close derivatives, such as the Master System VDP.
|
|
|
|
|
|
|
|
The TMS9918 and descendants are video display generators that own their own RAM, making it
|
|
|
|
accessible through an implicitly-timed register interface, and (depending on model) can generate
|
|
|
|
PAL and NTSC component and composite video.
|
|
|
|
|
|
|
|
These chips have only one non-on-demand interaction with the outside world: an interrupt line.
|
|
|
|
See get_time_until_interrupt and get_interrupt_line for asynchronous operation options.
|
|
|
|
*/
|
2018-09-18 02:59:16 +00:00
|
|
|
class TMS9918: public Base {
|
2017-11-26 18:28:26 +00:00
|
|
|
public:
|
|
|
|
/*!
|
|
|
|
Constructs an instance of the drive controller that behaves according to personality @c p.
|
|
|
|
@param p The type of controller to emulate.
|
|
|
|
*/
|
|
|
|
TMS9918(Personality p);
|
|
|
|
|
2017-12-15 01:27:26 +00:00
|
|
|
/*! Sets the TV standard for this TMS, if that is hard-coded in hardware. */
|
2017-11-29 02:10:30 +00:00
|
|
|
void set_tv_standard(TVStandard standard);
|
|
|
|
|
2018-11-30 04:44:21 +00:00
|
|
|
/*! Sets the scan target this TMS will post content to. */
|
|
|
|
void set_scan_target(Outputs::Display::ScanTarget *);
|
|
|
|
|
2020-01-21 02:45:10 +00:00
|
|
|
/// Gets the current scan status.
|
2020-01-22 03:28:25 +00:00
|
|
|
Outputs::Display::ScanStatus get_scaled_scan_status() const;
|
2020-01-21 02:45:10 +00:00
|
|
|
|
2018-11-30 04:44:21 +00:00
|
|
|
/*! Sets the type of display the CRT will request. */
|
|
|
|
void set_display_type(Outputs::Display::DisplayType);
|
2017-11-26 18:28:26 +00:00
|
|
|
|
2020-03-18 04:06:52 +00:00
|
|
|
/*! Gets the type of display the CRT will request. */
|
2020-05-21 03:34:26 +00:00
|
|
|
Outputs::Display::DisplayType get_display_type() const;
|
2020-03-18 04:06:52 +00:00
|
|
|
|
2017-11-26 18:28:26 +00:00
|
|
|
/*!
|
|
|
|
Runs the VCP for the number of cycles indicate; it is an implicit assumption of the code
|
2018-05-13 19:34:31 +00:00
|
|
|
that the input clock rate is 3579545 Hz, the NTSC colour clock rate.
|
2017-11-26 18:28:26 +00:00
|
|
|
*/
|
2017-11-27 01:07:30 +00:00
|
|
|
void run_for(const HalfCycles cycles);
|
2017-11-26 18:28:26 +00:00
|
|
|
|
2017-12-15 01:27:26 +00:00
|
|
|
/*! Sets a register value. */
|
2020-01-05 18:40:02 +00:00
|
|
|
void write(int address, uint8_t value);
|
2017-12-15 01:27:26 +00:00
|
|
|
|
|
|
|
/*! Gets a register value. */
|
2020-01-05 18:40:02 +00:00
|
|
|
uint8_t read(int address);
|
2017-11-26 21:47:59 +00:00
|
|
|
|
2018-10-05 02:50:35 +00:00
|
|
|
/*! Gets the current scan line; provided by the Master System only. */
|
|
|
|
uint8_t get_current_line();
|
|
|
|
|
2018-10-20 01:36:13 +00:00
|
|
|
/*! Gets the current latched horizontal counter; provided by the Master System only. */
|
2018-10-11 23:56:32 +00:00
|
|
|
uint8_t get_latched_horizontal_counter();
|
|
|
|
|
2018-10-20 01:36:13 +00:00
|
|
|
/*! Latches the current horizontal counter. */
|
2018-10-11 23:56:32 +00:00
|
|
|
void latch_horizontal_counter();
|
|
|
|
|
2017-12-10 04:08:07 +00:00
|
|
|
/*!
|
2021-04-06 01:02:37 +00:00
|
|
|
Returns the amount of time until @c get_interrupt_line would next change if
|
2020-01-05 18:40:02 +00:00
|
|
|
there are no interceding calls to @c write or to @c read.
|
2017-12-10 04:08:07 +00:00
|
|
|
|
2021-04-06 01:02:37 +00:00
|
|
|
If get_interrupt_line is true now of if get_interrupt_line would
|
|
|
|
never return true, returns HalfCycles::max().
|
2017-12-10 04:08:07 +00:00
|
|
|
*/
|
2021-04-06 01:02:37 +00:00
|
|
|
HalfCycles get_next_sequence_point();
|
2017-12-10 04:08:07 +00:00
|
|
|
|
2018-10-25 01:59:30 +00:00
|
|
|
/*!
|
|
|
|
Returns the amount of time until the nominated line interrupt position is
|
|
|
|
reached on line @c line. If no line interrupt position is defined for
|
|
|
|
this VDP, returns the time until the 'beginning' of that line, whatever
|
|
|
|
that may mean.
|
|
|
|
|
|
|
|
@line is relative to the first pixel line of the display and may be negative.
|
|
|
|
*/
|
|
|
|
HalfCycles get_time_until_line(int line);
|
|
|
|
|
2017-12-10 04:08:07 +00:00
|
|
|
/*!
|
|
|
|
@returns @c true if the interrupt line is currently active; @c false otherwise.
|
|
|
|
*/
|
2017-11-30 01:31:55 +00:00
|
|
|
bool get_interrupt_line();
|
2017-11-26 18:28:26 +00:00
|
|
|
};
|
|
|
|
|
2018-09-18 02:59:16 +00:00
|
|
|
}
|
|
|
|
}
|
2017-11-26 18:28:26 +00:00
|
|
|
|
2017-12-15 01:27:26 +00:00
|
|
|
#endif /* TMS9918_hpp */
|