updated go minimum version to 1.20

applied gofmt to source tree to update the documentation comments
This commit is contained in:
JetSetIlly 2023-02-12 13:07:49 +00:00
parent 73a9c91930
commit 178f05f17b
45 changed files with 320 additions and 322 deletions

View file

@ -23,9 +23,9 @@
// As well as the filename, the Loader type allows the cartridge mapping to be
// specified, if required. The simplest instantiation therefore is:
//
// cl := cartridgeloader.Loader{
// Filename: "roms/Pitfall.bin",
// }
// cl := cartridgeloader.Loader{
// Filename: "roms/Pitfall.bin",
// }
//
// It is stronly preferred however, that the NewLoader() function is used to
// initialise the Loader or important fields risk being initialised
@ -36,7 +36,7 @@
// cases the mapper will be "AUTO" to indicate that we don't know (or
// particular care) what the mapping format is.
//
// File Extensions
// # File Extensions
//
// The file extension of a file will specify the cartridge mapping and will
// cause the emulation to use that mapping. Most 2600 ROM files have the
@ -85,7 +85,7 @@
//
// Fingerprinting is not handled by the cartridlgeloader package.
//
// Hash
// # Hash
//
// The Hash field of the Loader type contains the SHA1 value of the loaded
// data. It is valid after the Load() function has completed successfully. If
@ -99,7 +99,7 @@
//
// The hash value is invalid/unused in the case of streamed data
//
// Streaming
// # Streaming
//
// For some cartridge types it is necessary to stream bytes from the file
// rather than load them all at once. For these types of cartridges the Load()
@ -111,21 +111,20 @@
// For streaming to work NewLoader() must have been used to instantiate the
// Loader type.
//
// Closing
// # Closing
//
// Instances of Loader must be closed with Close() when it is no longer
// required.
//
// OnInserted
// # OnInserted
//
// The OnInserted field is used by some cartridges to indicate when the
// cartridge data has been loaded into memory and something else needs to
// happen that is outside of the scope of the cartridge package. Currently,
// this is used by the Supercharder and PlusROM.
//
// Notification Hook
// # Notification Hook
//
// Some cartridge mappers will generate notifications (see notification.Notify type). The
// NotifcationHook can be specified in order to respond to those events.
//
package cartridgeloader

View file

@ -16,13 +16,13 @@
// Package debugger implements a reaonably comprehensive debugging tool.
// Features include:
//
// - cartridge disassembly
// - memory peek and poke
// - cpu and video cycle stepping
// - basic scripting
// - breakpoints
// - traps
// - watches
// - cartridge disassembly
// - memory peek and poke
// - cpu and video cycle stepping
// - basic scripting
// - breakpoints
// - traps
// - watches
//
// Some of these features come courtesy of other packages, described elsewhere,
// and some are inherent in the gopher2600's emulation strategy, but all are

View file

@ -244,8 +244,8 @@ func (bp breakpoints) list() {
// parse token and add new breakpoint. for example:
//
// PC 0xf000
// adds a new breakpoint to the PC
// PC 0xf000
// adds a new breakpoint to the PC
//
// in addition to the description in the HELP file, the breakpoint parser has
// some additional features which should probably be removed. if only because

View file

@ -85,11 +85,11 @@ func (n node) usageString() string {
// optimised in this case means the absence of superfluous group indicators.
// for example:
//
// TEST [1 [2] [3] [4] [5]]
// TEST [1 [2] [3] [4] [5]]
//
// is the same as:
//
// TEST [1 2 3 4 5]
// TEST [1 2 3 4 5]
//
// note: string should not be called directly except as a recursive call
// or as an initial call from String() and usageString().

View file

@ -39,23 +39,25 @@ import (
// into a machine friendly representation
//
// Syntax
// [ a ] required keyword
// ( a ) optional keyword
// [ a | b | ... ] required selection
// ( a | b | ... ) optional selection
//
// [ a ] required keyword
// ( a ) optional keyword
// [ a | b | ... ] required selection
// ( a | b | ... ) optional selection
//
// groups can be embedded in one another
//
// Placeholders
// %N numeric value
// %P irrational number value
// %S string (numbers can be strings too)
// %F file name
//
// %N numeric value
// %P irrational number value
// %S string (numbers can be strings too)
// %F file name
//
// Placeholders can be labelled. For example:
//
// %<first name>S
// %<age>N
// %<first name>S
// %<age>N
func ParseCommandTemplate(template []string) (*Commands, error) {
cmds := &Commands{
cmds: make([]*node, 0, 10),

View file

@ -51,7 +51,7 @@
// of the Disassembly instance and will "survive" calls to the FromMemory() and
// FromCartridge() functions.
//
// Segmented Cartridges
// # Segmented Cartridges
//
// The disassembly package treats small bank sized (those less than 4k) by
// performing the disassembly with the cartridge rooted at each origin point -

View file

@ -68,6 +68,7 @@ func (t table) String() string {
}
// make sure symbols is normalised:
//
// no leading or trailing space
// internal space compressed and replaced with underscores
func (t *table) normaliseSymbol(symbol string) string {

2
go.mod
View file

@ -1,6 +1,6 @@
module github.com/jetsetilly/gopher2600
go 1.18
go 1.20
require (
github.com/go-audio/audio v1.0.0

View file

@ -25,14 +25,13 @@
// pixel width; Converted to SVG with the help of Inkscape's Trace Bitmap
// function; and finally imported into an empty TTF file using FontForge.
//
// Licencing
// # Licencing
//
// Gopher2600-Icons.ttf is licenced by Stephen Illingworth, under the Creative
// Commons Attribution 4.0 International licence.
//
// https://creativecommons.org/licenses/by/4.0/legalcode
//
//
// The FontAwesome font (fa-solid-900.ttf) was downloaded on 18th March 2020
// from https://fontawesome.com/download using the "Free for Web" button. Full
// URL was:
@ -41,13 +40,11 @@
//
// FontAwesome is licenced under the Font Awesome Free License.
//
//
// Hack-Regular was downloaded on 20th December 2021 from permalink URL:
//
// https://github.com/source-foundry/Hack/blob/a737c121cabb337fdfe655d8c7304729f351e30f/build/ttf/Hack-Regular.ttf
//
// Hack-Regular is licenced under the MIT License.
//
//
// JetBrainsMono-Regular is licenced under the OFL-1.1 License
package fonts

View file

@ -23,13 +23,13 @@
//
// For example, to create a framebuffer sequence with two textures:
//
// seq := NewSequence(2)
// seq := NewSequence(2)
//
// The Setup() function must be called at least once after NewSequence() and
// called as often as necessary to ensure the dimensions (width and height) are
// correct.
//
// hasChanged := seq.Setup(800, 600)
// hasChanged := seq.Setup(800, 600)
//
// Setup() returns true if the texture data has been recreated in accordance
// with the new dimensions.
@ -39,13 +39,12 @@
// returned and can be used for presentation of as the input for the next call
// to Process() (via the draw() function).
//
// texture := seq.Process(0, func() {
// // 1. set up shader
// // 2. OpenGL draw (eg. gl.DrawElements()
// })
// texture := seq.Process(0, func() {
// // 1. set up shader
// // 2. OpenGL draw (eg. gl.DrawElements()
// })
//
// Note that much of the work of chaning a sequence of shaders must be
// performed by the user of the package. The package does however, hide a lot
// of detail behind the Process() and Setup() functions.
//
package framebuffer

View file

@ -211,8 +211,8 @@ func imguiBooleanButton(trueCol imgui.Vec4, falseCol imgui.Vec4, state bool, tex
// imguiLabel(), you can use the empty string or use the double hash construct.
// For example
//
// imgui.SliderInt("##foo", &v, s, e)
// imguiLabel("My Slider")
// imgui.SliderInt("##foo", &v, s, e)
// imguiLabel("My Slider")
func imguiLabel(text string) {
imgui.AlignTextToFramePadding()
imgui.Text(text)

View file

@ -28,14 +28,12 @@
// be used. There is currently no way of pushing events onto the emulator
// unless the debugging loop is in use.
//
//
// Example
// -------
//
// Retrieving the foreground color of the playfield:
//
// col := lazyval.Playfield.ForegroundColor
//
// col := lazyval.Playfield.ForegroundColor
//
// Writing the playfield values is done thought debugger's "raw event" system:
//
@ -43,7 +41,6 @@
// lazyval.VCS.TIA.Video.Playfield.ForegroundColor = col
// })
//
//
// Implementation
// --------------
//
@ -69,16 +66,16 @@
// The pseudocode below shows how the Refresh() updates the values in every
// type in the lazyvalues system, at the same time as requesting new values.
//
// func Refresh() { .------------------.
// debugger.PushFunction() -----> | CPU.push() |
// | RAM.push() |
// CPU.update() | Playfield.push() |
// RAM.update() | . |
// . | . |
// . | . |
// . | Log.push() |
// Log.update() ------------------
// }
// func Refresh() { .------------------.
// debugger.PushFunction() -----> | CPU.push() |
// | RAM.push() |
// CPU.update() | Playfield.push() |
// RAM.update() | . |
// . | . |
// . | . |
// . | Log.push() |
// Log.update() ------------------
// }
//
// The update() and push() functions (not visible from outside the lazyvalues
// package) of each type handle the retreiving and updating of emulation
@ -102,8 +99,8 @@
// the array. For example, the RAM package has code equivalent to this; an
// array of atomic.Value stored as an atomic value:
//
// var ram atomic.Value
// ram.Store(make([]atomic.Value, size)
// var ram atomic.Value
// ram.Store(make([]atomic.Value, size)
//
// The exception to all the rules is the LazyBreakpoints type. Like LazyRAM it
// employs an array of atomic.Values storied as an atomic Value but unlike
@ -116,7 +113,6 @@
// be other ways of achieving the same effect, but whatever way we do it the
// additional context provided by the disassembly.Entry is required.
//
//
// Ensuring Up-To-Date Information
// -------------------------------
//
@ -131,5 +127,4 @@
// setting the Wait flag to true.
//
// Use of "wait" should be kept to a minimum to ensure system responsiveness.
//
package lazyvalues

View file

@ -202,7 +202,7 @@ func (mc *CPU) LoadPC(directAddress uint16) error {
// read8Bit returns 8bit value from the specified address
//
// side-effects:
// * calls cycleCallback after memory read
// - calls cycleCallback after memory read
func (mc *CPU) read8Bit(address uint16, phantom bool) (uint8, error) {
mc.PhantomMemAccess = phantom
@ -227,7 +227,7 @@ func (mc *CPU) read8Bit(address uint16, phantom bool) (uint8, error) {
// read8BitZero returns 8bit value from the specified zero-page address
//
// side-effects:
// * calls cycleCallback after memory read
// - calls cycleCallback after memory read
func (mc *CPU) read8BitZeroPage(address uint8) (uint8, error) {
mc.PhantomMemAccess = false
@ -269,7 +269,7 @@ func (mc *CPU) write8Bit(address uint16, value uint8, phantom bool) error {
// read16Bit returns 16bit value from the specified address
//
// side-effects:
// * calls cycleCallback after each 8bit read
// - calls cycleCallback after each 8bit read
func (mc *CPU) read16Bit(address uint16) (uint16, error) {
mc.PhantomMemAccess = false
@ -320,10 +320,10 @@ const (
// read8BitPC reads 8 bits from the memory location pointed to by PC
//
// side-effects:
// * updates program counter
// * calls cycleCallback at end of function
// * updates LastResult.ByteCount
// * additional side effect updates LastResult as appropriate
// - updates program counter
// - calls cycleCallback at end of function
// - updates LastResult.ByteCount
// - additional side effect updates LastResult as appropriate
func (mc *CPU) read8BitPC(effect read8BitPCeffect) error {
v, err := mc.mem.Read(mc.PC.Address())
@ -381,12 +381,12 @@ func (mc *CPU) read8BitPC(effect read8BitPCeffect) error {
// read16BitPC reads 16 bits from the memory location pointed to by PC
//
// side-effects:
// * updates program counter
// * calls cycleCallback after each 8 bit read
// * updates LastResult.ByteCount
// * updates InstructionData field, once before each call to cycleCallback
// - no callback function because this function is only ever used
// to read operands
// - updates program counter
// - calls cycleCallback after each 8 bit read
// - updates LastResult.ByteCount
// - updates InstructionData field, once before each call to cycleCallback
// - no callback function because this function is only ever used
// to read operands
func (mc *CPU) read16BitPC() error {
lo, err := mc.mem.Read(mc.PC.Address())
if err != nil {
@ -518,9 +518,9 @@ const (
// ExecuteInstruction steps CPU forward one instruction. The basic process when
// executing an instruction is this:
//
// 1. read opcode and look up instruction definition
// 2. read operands (if any) according to the addressing mode of the instruction
// 3. using the operator as a guide, perform the instruction on the data
// 1. read opcode and look up instruction definition
// 2. read operands (if any) according to the addressing mode of the instruction
// 3. using the operator as a guide, perform the instruction on the data
//
// All instructions take at least 2 cycle. After each cycle, the
// cycleCallback() function is run, thereby allowing the rest of the VCS

View file

@ -95,7 +95,7 @@ const (
// the Value field formatted as a string with the condition that branch instructions
// are formatted as:
//
// Value/Value+1
// Value/Value+1
//
// We do not format any potential PageSensitive cycle.
type Cycles struct {

View file

@ -26,5 +26,4 @@
//
// Currently supported cartridge types are listed in the cartridgeloader
// package.
//
package cartridge

View file

@ -40,7 +40,7 @@ type m3e struct {
}
// cartridges:
// - Sokoboo
// - Sokoboo
func new3e(instance *instance.Instance, data []byte) (mapper.CartMapper, error) {
cart := &m3e{
instance: instance,

View file

@ -41,15 +41,16 @@ type m3ePlus struct {
}
// should work with any size cartridge that is a multiple of 1024:
// - tested with chess3E+20200519_3PQ6_SQ.bin
// https://atariage.com/forums/topic/299157-chess/?do=findComment&comment=4541517
//
// - specifciation:
// https://atariage.com/forums/topic/307914-3e-and-macros-are-your-friend/?tab=comments#comment-4561287
// - tested with chess3E+20200519_3PQ6_SQ.bin
// https://atariage.com/forums/topic/299157-chess/?do=findComment&comment=4541517
//
// - specifciation:
// https://atariage.com/forums/topic/307914-3e-and-macros-are-your-friend/?tab=comments#comment-4561287
//
// cartridges:
// - chess (Andrew Davie)
// cartridges:
//
// - chess (Andrew Davie)
func new3ePlus(instance *instance.Instance, data []byte) (mapper.CartMapper, error) {
cart := &m3ePlus{
instance: instance,

View file

@ -281,10 +281,10 @@ func (cart *atari) AddSuperchip(force bool) {
}
// atari4k is the original and most straightforward format:
// - Pitfall
// - River Raid
// - Barnstormer
// - etc.
// - Pitfall
// - River Raid
// - Barnstormer
// - etc.
type atari4k struct {
atari
}
@ -338,11 +338,11 @@ func (cart *atari4k) AccessVolatile(addr uint16, data uint8, poke bool) error {
}
// atari2k is the half-size cartridge of 2048 bytes:
// - Combat
// - Dragster
// - Outlaw
// - Surround
// - early cartridges
// - Combat
// - Dragster
// - Outlaw
// - Surround
// - early cartridges
//
// it also supports other cartridge sizes less than 4096 bytes
type atari2k struct {
@ -413,9 +413,9 @@ func (cart *atari2k) AccessVolatile(addr uint16, data uint8, poke bool) error {
}
// atari8k (F8):
// - ET
// - Krull
// - etc.
// - ET
// - Krull
// - etc.
type atari8k struct {
atari
}
@ -509,10 +509,10 @@ func (cart *atari8k) WriteHotspots() map[uint16]mapper.CartHotspotInfo {
}
// atari16k (F6):
// - Crystal Castle
// - RS Boxing
// - Midnite Magic
// - etc.
// - Crystal Castle
// - RS Boxing
// - Midnite Magic
// - etc.
type atari16k struct {
atari
}

View file

@ -28,17 +28,16 @@ import (
//
// 12K:
//
// -FA: Used only by CBS. Similar to F8, except you have three 4K banks
// instead of two. You select the desired bank via 1FF8, 1FF9, and 1FFA.
// These carts also have 256 bytes of RAM mapped in at 1000-11FF. 1000-10FF
// is the write port while 1100-11FF is the read port.
//
// -FA: Used only by CBS. Similar to F8, except you have three 4K banks
// instead of two. You select the desired bank via 1FF8, 1FF9, and 1FFA.
// These carts also have 256 bytes of RAM mapped in at 1000-11FF. 1000-10FF
// is the write port while 1100-11FF is the read port.
//
// cartridges:
// - Omega Race
// - Mountain King
// - Tunnel Runner
// - Noice (scene demo)
// - Omega Race
// - Mountain King
// - Tunnel Runner
// - Noice (scene demo)
//
// US patent 4,485,457A describes the format in detail:
//

View file

@ -37,8 +37,8 @@ import (
// from bankswitch_sizes.txt:
//
// cartridges:
// - MagiCard
// - Video Lfe
// - MagiCard
// - Video Lfe
//
// and the reason why I implemented this format for Gopher2600:
//

View file

@ -34,11 +34,10 @@ import (
// for the third 1K. The last 1K always points to the last 1K of the ROM image
// so that the cart always starts up in the exact same place.
//
//
// cartridges:
// - Montezuma's Revenge
// - Lord of the Rings
// - etc.
// - Montezuma's Revenge
// - Lord of the Rings
// - etc.
type parkerBros struct {
instance *instance.Instance

View file

@ -39,8 +39,8 @@ import (
// since you can implement this with only one chip! (a 74LS173).
//
// cartridges:
// - Miner2049
// - River Patrol
// - Miner2049
// - River Patrol
type tigervision struct {
instance *instance.Instance
@ -58,7 +58,7 @@ type tigervision struct {
}
// should work with any size cartridge that is a multiple of 2048:
// - tested with 8k (Miner2049 etc.) and 32k (Genesis_Egypt demo).
// - tested with 8k (Miner2049 etc.) and 32k (Genesis_Egypt demo).
func newTigervision(instance *instance.Instance, data []byte) (mapper.CartMapper, error) {
cart := &tigervision{
instance: instance,

View file

@ -36,9 +36,9 @@ var biosFile = [...]string{
const biosLogTag = "supercharger: bios"
// loadBIOS attempts to load BIOS from (in order of priority):
// - current working directory
// - the same directory as the tape/bin file
// - the emulator's resource path
// - current working directory
// - the same directory as the tape/bin file
// - the emulator's resource path
func loadBIOS(path string) ([]uint8, error) {
// current working directory
for _, b := range biosFile {

View file

@ -26,45 +26,41 @@
// is that the peripheral bus only ever writes to memory. The other buses are
// bidirectional.
//
// PERIPHERALS
//
// PERIPHERALS
// |
// |
// \/
//
// |
// |
// \/
// periph bus
//
// periph bus
// |
// |
// \/
//
// |
// |
// \/
// CPU ---- cpu bus ---- MEMORY ---- chip bus ---- TIA
// \
// | \
// | \---- RIOT
//
// CPU ---- cpu bus ---- MEMORY ---- chip bus ---- TIA
// \
// | \
// | \---- RIOT
// debugger bus
//
// debugger bus
//
// |
// |
//
// DEBUGGER
// |
// |
//
// DEBUGGER
//
// The memory itself is divided into areas, defined in the memorymap package.
// Removing the periph bus and debugger bus from the picture, the above diagram
// with memory areas added is as follows:
//
//
// ===* TIA ---- chip bus ---- TIA
// |
// |===* RIOT ---- chip bus ---- RIOT
// CPU ---- cpu bus -----
// |===* PIA RAM
// |
// ==== Cartridge
//
// ===* TIA ---- chip bus ---- TIA
// |
// |===* RIOT ---- chip bus ---- RIOT
// CPU ---- cpu bus -----
// |===* PIA RAM
// |
// ==== Cartridge
//
// The asterisk indicates that addresses used by the CPU are mapped to the
// primary mirror address. The memorymap package contains more detail on this.

View file

@ -91,8 +91,8 @@ const Memtop = uint16(0x1fff)
//
// Alternatively, the following is an effective way to index an array:
//
// addr := 0xf000
// mem[addr & CartridgeBits] = 0xff
// addr := 0xf000
// mem[addr & CartridgeBits] = 0xff
//
// In the example, index zero of the mem array is assigned the value 0xff.
const (

View file

@ -37,14 +37,13 @@ import (
// "Stella Programmer's Guide" but they are readable anyway and are wired the
// same as the collision and INPTx registers.
//
//
// Explanation of how the TIADrivenPins mask affects the read value
// ----------------------------------------------------------------
//
// If the CPU wants to read the contents of the CXM1P register, it can use the
// address 0x0d to do so.
//
// LDA 0x01
// LDA 0x01
//
// If there are no collisions (between missile 1 and either player, in this
// case) than the value of the most significant bits are zero. The lower six
@ -52,13 +51,13 @@ import (
// when the data is put on the bus. The lower bits of the LDA operation are in
// fact "left over" from the address. In our example, the lowest six bits are
//
// 0bxx000001
// 0bxx000001
//
// meaning the the returned data is in fact 0x01 and not 0x00, as you might
// expect. Things get interesting when we use mirrored addresses. If instead
// of 0x01 we used the mirror address 0x11, the lowest six bits are:
//
// 0bxx01001
// 0bxx01001
//
// meaning that the returned value is 0x11 and not (again, as you might expect)
// 0x00 or even 0x01.
@ -67,12 +66,12 @@ import (
// Meaning that the top bits are not necessarily zero. Let's say there is a
// collusion between missile 1 and player 0, the data before masking will be
//
// 0b01000000
// 0b01000000
//
// If we used address 0x11 to load this value, we would in fact, get this
// pattern (0x51 in hex):
//
// 0b01010001
// 0b01010001
//
// Now, if all ROMs read and interpreted chip registers only as they're
// supposed to (defails in the 2600 programmer's guide) then none of this would
@ -86,7 +85,7 @@ import (
// most-significant byte. So, if the requested address is 0x171, the bit
// pattern for the address is:
//
// 0x0000000101110001
// 0x0000000101110001
//
// the most significant byte in this pattern is 0x00000001 and so the data
// retreived is AND-ed with that. The mapped address for 0x171 incidentally, is

View file

@ -30,9 +30,9 @@ const activityLength = 64
// deriving conditions from two traces is convenient. for example, give two
// traces A and B, a condition for event E might be:
//
// if A.hi() && B.lo2hi() {
// E()
// }
// if A.hi() && B.lo2hi() {
// E()
// }
type Trace struct {
// a recent history of the i2c trace. wraps around at activityLength
activity []float32

View file

@ -63,10 +63,9 @@ type PlugMonitor interface {
// Implementations of Monitorable should also test peripherals that are
// daisy-chained and call AttachPlusMonitor() as appropriate.
//
// if a, ok := periph.daisychain.(pluggin.Monitorable); ok {
// a.AttachPlugMonitor(m)
// }
//
// if a, ok := periph.daisychain.(pluggin.Monitorable); ok {
// a.AttachPlugMonitor(m)
// }
type Monitorable interface {
AttachPlugMonitor(m PlugMonitor)
}

View file

@ -495,23 +495,23 @@ func (p *Ports) PokeField(fld string, v interface{}) {
// the derived value of SWCHA. the value it should be if the RIOT logic has
// proceeded normally (ie. no poking)
//
// SWCHA_W SWACNT <input> SWCHA
// 0 0 1 1 ^SWCHA_W & ^SWACNT & <input>
// 0 0 0 0
// 0 1 1 0
// 0 1 0 0
// 1 0 1 1 SWCHA_W & ^SWACNT & <input>
// 1 0 0 0
// 1 1 1 1 SWCHA_W & SWACNT & <input>
// 1 1 0 0
// SWCHA_W SWACNT <input> SWCHA
// 0 0 1 1 ^SWCHA_W & ^SWACNT & <input>
// 0 0 0 0
// 0 1 1 0
// 0 1 0 0
// 1 0 1 1 SWCHA_W & ^SWACNT & <input>
// 1 0 0 0
// 1 1 1 1 SWCHA_W & SWACNT & <input>
// 1 1 0 0
//
// a := p.swcha_w
// b := swacnt
// c := p.swcha_mux
// a := p.swcha_w
// b := swacnt
// c := p.swcha_mux
//
// (^a & ^b & c) | (a & ^b & c) | (a & b & c)
// (a & c & (^b|b)) | (^a & ^b & c)
// (a & c) | (^a & ^b & c)
// (^a & ^b & c) | (a & ^b & c) | (a & b & c)
// (a & c & (^b|b)) | (^a & ^b & c)
// (a & c) | (^a & ^b & c)
func (p *Ports) deriveSWCHA() uint8 {
swacnt := p.riot.ChipRefer(chipbus.SWACNT)
return (p.swcha_w & p.swcha_mux) | (^p.swcha_w & ^swacnt & p.swcha_mux)
@ -520,25 +520,25 @@ func (p *Ports) deriveSWCHA() uint8 {
// the derived value of SWCHB. the value it should be if the RIOT logic has
// proceeded normally (ie. no poking).
//
// SWCHB_W SWBCNT <input> SWCHB
// 0 0 1 1 ^SWCHB_W & ^SWBCNT & <input>
// 0 0 0 0
// 0 1 1 0
// 0 1 0 0
// 1 0 1 1 SWCHB_W & ^SWBCNT & <input>
// 1 0 0 0
// 1 1 1 1 SWCHB_W & SWBCNT & <input>
// 1 1 0 1 SWCHB_W & SWBCNT & ^<input>
// SWCHB_W SWBCNT <input> SWCHB
// 0 0 1 1 ^SWCHB_W & ^SWBCNT & <input>
// 0 0 0 0
// 0 1 1 0
// 0 1 0 0
// 1 0 1 1 SWCHB_W & ^SWBCNT & <input>
// 1 0 0 0
// 1 1 1 1 SWCHB_W & SWBCNT & <input>
// 1 1 0 1 SWCHB_W & SWBCNT & ^<input>
//
// (The last entry of the truth table is different to the truth table for SWCHA)
// (The last entry of the truth table is different to the truth table for SWCHA)
//
// a := p.swchb_w
// b := swbcnt
// c := p.swchb_raw
// a := p.swchb_w
// b := swbcnt
// c := p.swchb_raw
//
// (^a & ^b & c) | (a & ^b & c) | (a & b & c) | (a & b & ^c)
// (^a & ^b & c) | (a & ^b & c) | (a & b)
// (^b & c) | (a & b)
// (^a & ^b & c) | (a & ^b & c) | (a & b & c) | (a & b & ^c)
// (^a & ^b & c) | (a & ^b & c) | (a & b)
// (^b & c) | (a & b)
func (p *Ports) deriveSWCHB() uint8 {
swbcnt := p.riot.ChipRefer(chipbus.SWBCNT)
return (^swbcnt & p.swchb_raw) | (p.swchb_w & swbcnt)

View file

@ -25,12 +25,12 @@ import (
// Divider indicates how often (in CPU cycles) the timer value decreases.
// the following rules apply:
// * set to 1, 8, 64 or 1024 depending on which address has been
// written to by the CPU
// * is used to reset the cyclesRemaining
// * is changed to 1 once value reaches 0
// * is reset to its initial value of 1, 8, 64, or 1024 whenever INTIM
// is read by the CPU
// - set to 1, 8, 64 or 1024 depending on which address has been
// written to by the CPU
// - is used to reset the cyclesRemaining
// - is changed to 1 once value reaches 0
// - is reset to its initial value of 1, 8, 64, or 1024 whenever INTIM
// is read by the CPU
type Divider int
// List of valid Divider values.
@ -265,10 +265,11 @@ func (tmr *Timer) Step() {
// INTIM register on the cpubus - provided here for convenience.
//
// Supported fields:
// intim (uint8)
// timint (uint8)
// ticksRemainging (int)
// divider (timer.Divider)
//
// intim (uint8)
// timint (uint8)
// ticksRemainging (int)
// divider (timer.Divider)
func (tmr *Timer) PeekField(fld string) interface{} {
switch fld {
case "intim":

View file

@ -28,15 +28,14 @@ import (
// a standard value that can be used to filter out expensive code paths within
// a continueCheck() implementation. For example:
//
// performanceFilter++
// if performanceFilter >= hardware.PerfomrmanceBrake {
// performanceFilter = 0
// if end_condition == true {
// return govern.Ending, nill
// }
// performanceFilter++
// if performanceFilter >= hardware.PerfomrmanceBrake {
// performanceFilter = 0
// if end_condition == true {
// return govern.Ending, nill
// }
// return govern.Running, nill
//
// }
// return govern.Running, nill
const PerformanceBrake = 100
// Run sets the emulation running as quickly as possible

View file

@ -51,17 +51,17 @@
// information about the frame can be acquired with GetFrameInfo(). FrameInfo
// will also be sent to the PixelRenderers as appropriate.
//
// Screen Rolling
// # Screen Rolling
//
// Screen rolling is not handled by the television package. However, the synced
// argument of the NewFrame() function in the PixelRenderer and FrameTrigger
// interfaces can be used to implement it if required. Something like this:
//
// 1) If Synced is false, note scanline of last plot (unsynedScanline)
// 2) For every SetPixel() add unsyncedScanline to the Scanline value in
// the SignalAttributes struct (adjustedScanline)
// 3) Bring adjustedScanline into range by modulo ScanlinesTotal of the
// current TV specification.
// 1. If Synced is false, note scanline of last plot (unsynedScanline)
// 2. For every SetPixel() add unsyncedScanline to the Scanline value in
// the SignalAttributes struct (adjustedScanline)
// 3. Bring adjustedScanline into range by modulo ScanlinesTotal of the
// current TV specification.
//
// Recovery from a screen roll should also be emulated. A good way of doing
// this is to reduce unsyncedScanline by a percentage (80% say) on synced
@ -70,12 +70,12 @@
// A good additionl policy would be to only roll if several, consecutive
// unsynced frames are indicated.
//
// Concurrency
// # Concurrency
//
// None of the functions in the Television type are safe to be called from
// goroutines other than the one the type was created in.
//
// Logging
// # Logging
//
// The television does no logging. This is because the television can be used
// ephemerally and logging would be noisy. Callers of television package

View file

@ -23,40 +23,54 @@ import (
// resizer handles the expansion of the visible area of the TV screen
//
// ROMs used to test resizing:
// * good base cases
// - Pitfall
// - Hero
//
// * needs an additional (or two) scanlines to accommodate full screen
// - Ladybug
// - Man Goes Down
// - good base cases
//
// * frame that needs to be resized after startup period
// - Hack Em Hanglyman (pre-release)
// - Pitfall
//
// * the occasional unsynced frame
// - Hack Em Hanglyman (pre-release)
// - Hero
//
// * lots of unsynced frames (during computer "thinking" period)
// - Andrew Davies' Chess
// - needs an additional (or two) scanlines to accommodate full screen
//
// * does not set VBLANK for pixels that are clearly not meant to be seen
// these ROMs rely on the SafeTop and SafeBottom values being correct
// - Communist Mutants From Space
// - Tapper
// - Spike's Peak
// - Ladybug
//
// * ROMs that do not set VBLANK *at all*. in these cases the commit()
// function uses the black top/bottom values rather than vblank top/bottom
// values.
// - Hack Em Hanglyman (release and pre-release)
// - Legacy of the Beast
// - Man Goes Down
//
// * ROMs that *do* set VBLANK but might be caught by the black top/bottom
// rule if frameHasVBlank was incorrectly set
// - aTaRSI (demo)
// - Supercharger "rewind tape" screen
// - frame that needs to be resized after startup period
//
// - Hack Em Hanglyman (pre-release)
//
// - the occasional unsynced frame
//
// - Hack Em Hanglyman (pre-release)
//
// - lots of unsynced frames (during computer "thinking" period)
//
// - Andrew Davies' Chess
//
// - does not set VBLANK for pixels that are clearly not meant to be seen
// these ROMs rely on the SafeTop and SafeBottom values being correct
//
// - Communist Mutants From Space
//
// - Tapper
//
// - Spike's Peak
//
// - ROMs that do not set VBLANK *at all*. in these cases the commit()
// function uses the black top/bottom values rather than vblank top/bottom
// values.
//
// - Hack Em Hanglyman (release and pre-release)
//
// - Legacy of the Beast
//
// - ROMs that *do* set VBLANK but might be caught by the black top/bottom
// rule if frameHasVBlank was incorrectly set
//
// - aTaRSI (demo)
//
// - Supercharger "rewind tape" screen
type resizer struct {
// candidate top/bottom values for an actual resize.
//

View file

@ -21,11 +21,11 @@
// from both projects was used as reference. Both projects are exactly
// equivalent.
//
// 6502.ts (published under the MIT licence)
// https://github.com/6502ts/6502.ts/blob/6f923e5fe693b82a2448ffac1f85aea9693cacff/src/machine/stella/tia/PCMAudio.ts
// https://github.com/6502ts/6502.ts/blob/6f923e5fe693b82a2448ffac1f85aea9693cacff/src/machine/stella/tia/PCMChannel.ts
// 6502.ts (published under the MIT licence)
// https://github.com/6502ts/6502.ts/blob/6f923e5fe693b82a2448ffac1f85aea9693cacff/src/machine/stella/tia/PCMAudio.ts
// https://github.com/6502ts/6502.ts/blob/6f923e5fe693b82a2448ffac1f85aea9693cacff/src/machine/stella/tia/PCMChannel.ts
//
// Stella (published under the GNU GPL v2.0 licence)
// https://github.com/stella-emu/stella/blob/e6af23d6c12893dd17711002971087f28f87c31f/src/emucore/tia/Audio.cxx
// https://github.com/stella-emu/stella/blob/e6af23d6c12893dd17711002971087f28f87c31f/src/emucore/tia/AudioChannel.cxx
// Stella (published under the GNU GPL v2.0 licence)
// https://github.com/stella-emu/stella/blob/e6af23d6c12893dd17711002971087f28f87c31f/src/emucore/tia/Audio.cxx
// https://github.com/stella-emu/stella/blob/e6af23d6c12893dd17711002971087f28f87c31f/src/emucore/tia/AudioChannel.cxx
package audio

View file

@ -28,13 +28,13 @@
// Both 6502.ts and Stella source was used as reference. Both projects are
// exactly equivalent.
//
// 6502.ts (published under the MIT licence)
// https://github.com/6502ts/6502.ts/blob/6f923e5fe693b82a2448ffac1f85aea9693cacff/src/machine/stella/tia/PCMAudio.ts
// https://github.com/6502ts/6502.ts/blob/6f923e5fe693b82a2448ffac1f85aea9693cacff/src/machine/stella/tia/PCMChannel.ts
// 6502.ts (published under the MIT licence)
// https://github.com/6502ts/6502.ts/blob/6f923e5fe693b82a2448ffac1f85aea9693cacff/src/machine/stella/tia/PCMAudio.ts
// https://github.com/6502ts/6502.ts/blob/6f923e5fe693b82a2448ffac1f85aea9693cacff/src/machine/stella/tia/PCMChannel.ts
//
// Stella (published under the GNU GPL v2.0 licence)
// https://github.com/stella-emu/stella/blob/e6af23d6c12893dd17711002971087f28f87c31f/src/emucore/tia/Audio.cxx
// https://github.com/stella-emu/stella/blob/e6af23d6c12893dd17711002971087f28f87c31f/src/emucore/tia/AudioChannel.cxx
// Stella (published under the GNU GPL v2.0 licence)
// https://github.com/stella-emu/stella/blob/e6af23d6c12893dd17711002971087f28f87c31f/src/emucore/tia/Audio.cxx
// https://github.com/stella-emu/stella/blob/e6af23d6c12893dd17711002971087f28f87c31f/src/emucore/tia/AudioChannel.cxx
package mix
const maxVolume = 0x1e

View file

@ -34,10 +34,10 @@
// The phaseclock can be "ticked" along by incrementing the integer and making
// sure it doesn't exceed the possible values: The accepted pattern is:
//
// p++
// if p >= phaseclock.NumStates {
// p = 0
// }
// p++
// if p >= phaseclock.NumStates {
// p = 0
// }
//
// Resetting and aligning the phase clock can be done by simply assigning the
// correct value to the PhaseClock instance. Use ResetValue and AlignValue for

View file

@ -23,23 +23,23 @@
// the TIA loop (HSYNC counter) we'd still like to know what the equivalent
// polycounter value is. We use a 6-bit polycounter for this.
//
// hsync := polycounter.New(6)
// hsync := polycounter.New(6)
//
// As the emulated polycounter is just an integer we can "tick" it along in the
// obvious way. We should take care to make sure it doesn't run past the end of
// the polycounter however. The accepted pattern is:
//
// p++
// if p >= polycounter.LenTable6Bit {
// p = 0
// }
// p++
// if p >= polycounter.LenTable6Bit {
// p = 0
// }
//
// Whenever the polycounter is to be reset set it it polycounter.ResetValue.
//
// The polycounter bit pattern can be retrieved at any time with the ToBinary()
// function.
//
// Additional Note
// # Additional Note
//
// In the 2600, polycounter logic is also used to generate the bit sequences
// required for TIA audio emulation. A real TIA variously uses 4-bit, 5-bit and

View file

@ -45,7 +45,7 @@
//
// Adding flags is similar to the flag package. Adding a boolean flag:
//
// verbose := md.AddBool("verbose", false, "print additional log messages")
// verbose := md.AddBool("verbose", false, "print additional log messages")
//
// These flag functions return a pointer to a variable of the specified type. The
// initial value of these variables if the default value, the second argument in
@ -132,5 +132,4 @@
// default:
// fmt.Printf("%s not yet implemented", md.Mode())
// }
//
package modalflag

View file

@ -143,15 +143,15 @@ const (
// Parse the top level layer of arguments. Returns a value of ParseResult.
// The idiomatic usage is as follows:
//
// p, err := md.Parse()
// switch p {
// case modalflag.ParseHelp:
// // help message has already been printed
// return
// case modalflag.ParseError:
// printError(err)
// return
// }
// p, err := md.Parse()
// switch p {
// case modalflag.ParseHelp:
// // help message has already been printed
// return
// case modalflag.ParseError:
// printError(err)
// return
// }
//
// Help messages are handled automatically by the function. The return value
// ParseHelp is to help you guide your program appropriately. The above pattern

View file

@ -17,8 +17,8 @@
// that type. These values represent the different notifications that be sent
// to the GUI.
//
// hardware ----> emulation ----> GUI
// (eg. cartridge) (eg. debugger)
// hardware ----> emulation ----> GUI
// (eg. cartridge) (eg. debugger)
//
// Notifications flow in one direction only and can be generated and terminate
// at any of the points in the chart above.

View file

@ -66,8 +66,8 @@ const (
// NotificationHook is used for direct communication between a the hardware and
// the emulation package. Not often used but necessary for (currently):
//
// . Supercharger (eg. tape start/end)
// . PlusROM (eg. new installation)
// . Supercharger (eg. tape start/end)
// . PlusROM (eg. new installation)
//
// The emulation understands how to interpret the event and forward the
// notification to the GUI using the gui.FeatureReq mechanism.

View file

@ -24,13 +24,13 @@
// The first format is simplt the output of "cmp -l <old_file> <new_file>", an
// example of which is shown below:
//
// 862 22 200
// 863 360 376
// 3713 377 242
// 3715 377 232
// 3716 377 114
// 3717 377 22
// 3718 377 360
// 862 22 200
// 863 360 376
// 3713 377 242
// 3715 377 232
// 3716 377 114
// 3717 377 22
// 3718 377 360
//
// The first column is the offset, expressed as a decimal number and measure
// from one. The second column is the current value of the offset being
@ -47,19 +47,19 @@
//
// The following extract illustrates the format:
//
// -------------------------------------------
// - E.T. is Not Green
// -------------------------------------------
// 17FA: FE FC F8 F8 F8
// 1DE8: 04
// -------------------------------------------
// - E.T. is Not Green
// -------------------------------------------
// 17FA: FE FC F8 F8 F8
// 1DE8: 04
//
// Rules:
//
// 1. Lines beginning with a hyphen or white space are ignored
// 2. Offset and values are expressed in hex (case-insensitive)
// 3. Values and offsets are separated by a colon
// 4. Multiple values on a line are poked into consecutive offsets, starting
// from the offset value
// 1. Lines beginning with a hyphen or white space are ignored
// 2. Offset and values are expressed in hex (case-insensitive)
// 3. Values and offsets are separated by a colon
// 4. Multiple values on a line are poked into consecutive offsets, starting
// from the offset value
//
// Note that offsets are expressed with origin zero and have no relationship
// to how memory is mapped inside the VCS. Imagine that the patches are being

View file

@ -41,7 +41,7 @@
// program in the normal way. Changes can be committed to disk with the
// Disk.Save() function and restored with Disk.Load().
//
//Prefs valus and Multiple Disk Instances
// # Prefs valus and Multiple Disk Instances
//
// A prefs values can be added to more than one disk intance at once. Moreover,
// more than disk instance can point to the same file on disk.
@ -51,19 +51,19 @@
// saved. Values that exist on the physical disk but which are missing from the
// limited disk object will be preserved.
//
//Concurrency
// # Concurrency
//
// Generally, it is safe to access a prefs value from any goroutine. However,
// Set() should be used with care *if* SetHookPost() or SetHookPre() has been
// set for that value.
//
//Command Line Support
// # Command Line Support
//
// The *CommandLine*() functions are designed to help with the overriding of
// disk values with a value given on the command line. These values are added
// as a group with AddCommandLineGroup(). For example
//
// AddCommandLineGroup("foo::bar; baz::qux")
// AddCommandLineGroup("foo::bar; baz::qux")
//
// (see below for more detail about the format of the prefs string)
//
@ -83,17 +83,17 @@
//
// For example, if the preferences file has the following entries:
//
// a.b.c :: 100
// d.e.f.g :: false
// h.i :: wibble
// a.b.c :: 100
// d.e.f.g :: false
// h.i :: wibble
//
// A valid string to use with AddCommandLineGroup() might be:
//
// a.b.c::100; h.i::wibble
// a.b.c::100; h.i::wibble
//
// Leading and trailing spaces around the key and value are stripped.
//
//Note
// # Note
//
// While saved preference files are stored in UTF-8 it is not a good idea for
// the files to be edited by hand. As such, manual editing is discorouaged with

View file

@ -27,12 +27,12 @@ import (
//
// Format of returned string is:
//
// filetype_cartname_YYYYMMDD_HHMMSS
// filetype_cartname_YYYYMMDD_HHMMSS
//
// Where cartname is the string returned by cartload.ShortName(). If the
// cartname argument is empty the returned string will be of the format:
//
// filetype_YYYYMMDD_HHMMSS
// filetype_YYYYMMDD_HHMMSS
//
// The filetype argument is simply another way of identifying the file
// uniquely. For example, if saving a screenshot the filetype might simply be
@ -40,7 +40,7 @@ import (
//
// If the filetype argument is empty the returned string will be of the format:
//
// cartname_YYYYMMDD_HHMMSS
// cartname_YYYYMMDD_HHMMSS
//
// If both filetype and cartname arguments are empty then the returned string
// will be the timestamp only.

View file

@ -20,8 +20,8 @@ import "testing"
// ExpectedFailure tests argument v for a failure condition suitable for it's
// type. Currentlly support types:
//
// bool -> bool == false
// error -> error != nil
// bool -> bool == false
// error -> error != nil
//
// If type is nil then the test will fail.
func ExpectedFailure(t *testing.T, v interface{}) bool {
@ -55,8 +55,8 @@ func ExpectedFailure(t *testing.T, v interface{}) bool {
// ExpectedSuccess tests argument v for a success condition suitable for it's
// type. Currentlly support types:
//
// bool -> bool == true
// error -> error == nil
// bool -> bool == true
// error -> error == nil
//
// If type is nil then the test will succeed.
func ExpectedSuccess(t *testing.T, v interface{}) bool {