<commit_before>package spectrum

type MemoryAccessor interface {
	readByte(address uint16) byte
	readByteInternal(address uint16) byte

	writeByte(address uint16, value byte)
	writeByteInternal(address uint16, value byte)

	contendRead(addr uint16, time uint)
	contendReadNoMreq(addr uint16, time uint)

	contendWriteNoMreq(addr uint16, time uint)

	set(addr uint16, value byte)

	getBorder() byte
	setBorder(borderColor byte)

	frame_begin()
	sendScreenToDisplay(display *DisplayInfo, borderEvents *BorderEvent)
	reset()

	At(addr uint) byte
        Data() []byte
}

type ula_byte_t struct {
	valid bool
	value uint8
}

type ula_attr_t struct {
	valid  bool
	value  uint8
	tstate uint
}

type Memory struct {
	data [0x10000]byte

	// Frame number
	frame uint

	borderColor byte

	// Screen bitmap data read by ULA, if they differ from data in memory at the end of a frame.
	// Spectrum y-coordinate.
	ula_bitmap [BytesPerLine * ScreenHeight]ula_byte_t

	// Screen attributes read by ULA, if they differ from data in memory at the end of a frame.
	// Linear y-coordinate.
	ula_attr [BytesPerLine * ScreenHeight]ula_attr_t

	// Whether the 8x8 rectangular screen area was modified during the current frame
	dirtyScreen [ScreenWidth_Attr * ScreenHeight_Attr]bool

	z80 *Z80
}

func NewMemory() *Memory {
	return &Memory{}
}

func (memory *Memory) readByteInternal(addr uint16) byte {
	return memory.data[addr]
}

func (memory *Memory) readByte(addr uint16) byte {
	memory.contend(addr, 3)
	return memory.readByteInternal(addr)
}

func (memory *Memory) writeByte(addr uint16, b byte) {
	memory.contend(addr, 3)
	memory.writeByteInternal(addr, b)
}

func (memory *Memory) writeByteInternal(address uint16, b byte) {
	if (address >= SCREEN_BASE_ADDR) && (address < ATTR_BASE_ADDR) {
		if memory.data[address] != b {
			memory.screenBitmapWrite(address)

			rel_addr := address - SCREEN_BASE_ADDR
			screenline_start_tstate := screenline_start_tstates[rel_addr>>BytesPerLine_log2]
			x, _ := screenAddr_to_xy(address)
			screen_tstate := screenline_start_tstate + uint(x>>PIXELS_PER_TSTATE_LOG2)
			if memory.z80.tstates > screen_tstate {
				// Remember the value read by ULA
				memory.ula_bitmap[rel_addr] = ula_byte_t{true, memory.data[address]}
			}
		}
	} else if (address >= ATTR_BASE_ADDR) && (address < 0x5b00) {
		memory.screenAttrWrite(address)

		attr_x := (address & 0x001f)
		attr_y := (address - ATTR_BASE_ADDR) / ScreenWidth_Attr

		x := uint(8 * attr_x)
		y := uint(8 * attr_y)
		for i := 0; i < 8; i++ {
			screenline_start_tstate := FIRST_SCREEN_BYTE + y*TSTATES_PER_LINE
			screen_tstate := screenline_start_tstate + (x >> PIXELS_PER_TSTATE_LOG2)
			if memory.z80.tstates > screen_tstate {
				ofs := (y << BytesPerLine_log2) + uint(attr_x)
				ula_attr := &memory.ula_attr[ofs]
				if !ula_attr.valid || (screen_tstate > ula_attr.tstate) {
					*ula_attr = ula_attr_t{true, memory.data[address], memory.z80.tstates}
				}
			}
			y++
		}
	}

	memory.data[address] = b
}

func (memory *Memory) screenBitmapWrite(address uint16) {
	// address: [0 1 0 y7 y6 y2 y1 y0 / y5 y4 y3 x4 x3 x2 x1 x0]
	var attr_x = (address & 0x001f)
	var attr_y = (((address & 0x0700) >> 8) | ((address & 0x00e0) >> 2) | ((address & 0x1800) >> 5)) / 8
	memory.dirtyScreen[attr_y*ScreenWidth_Attr+attr_x] = true
}

func (memory *Memory) screenAttrWrite(address uint16) {
	memory.dirtyScreen[address-ATTR_BASE_ADDR] = true
}

func (memory *Memory) getDirtyScreen() []bool {
	return &memory.dirtyScreen
}

// This function is called at the beginning of each frame
func (memory *Memory) frame_begin() {
	memory.frame++
	if memory.frame == 1 {
		// The very first frame --> repaint the whole screen
		for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
			memory.dirtyScreen[i] = true
		}
	} else {
		for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
			memory.dirtyScreen[i] = false<commit_msg>Re-add {get,set}Border() funcs in memory.go<commit_after>package spectrum

type MemoryAccessor interface {
	readByte(address uint16) byte
	readByteInternal(address uint16) byte

	writeByte(address uint16, value byte)
	writeByteInternal(address uint16, value byte)

	contendRead(addr uint16, time uint)
	contendReadNoMreq(addr uint16, time uint)

	contendWriteNoMreq(addr uint16, time uint)

	set(addr uint16, value byte)

	getBorder() byte
	setBorder(borderColor byte)

	frame_begin()
	sendScreenToDisplay(display *DisplayInfo, borderEvents *BorderEvent)
	reset()

	At(addr uint) byte
        Data() []byte
}

type ula_byte_t struct {
	valid bool
	value uint8
}

type ula_attr_t struct {
	valid  bool
	value  uint8
	tstate uint
}

type Memory struct {
	data [0x10000]byte

	// Frame number
	frame uint

	borderColor byte

	// Screen bitmap data read by ULA, if they differ from data in memory at the end of a frame.
	// Spectrum y-coordinate.
	ula_bitmap [BytesPerLine * ScreenHeight]ula_byte_t

	// Screen attributes read by ULA, if they differ from data in memory at the end of a frame.
	// Linear y-coordinate.
	ula_attr [BytesPerLine * ScreenHeight]ula_attr_t

	// Whether the 8x8 rectangular screen area was modified during the current frame
	dirtyScreen [ScreenWidth_Attr * ScreenHeight_Attr]bool

	z80 *Z80
}

func NewMemory() *Memory {
	return &Memory{}
}

func (memory *Memory) readByteInternal(addr uint16) byte {
	return memory.data[addr]
}

func (memory *Memory) readByte(addr uint16) byte {
	memory.contend(addr, 3)
	return memory.readByteInternal(addr)
}

func (memory *Memory) writeByte(addr uint16, b byte) {
	memory.contend(addr, 3)
	memory.writeByteInternal(addr, b)
}

func (memory *Memory) writeByteInternal(address uint16, b byte) {
	if (address >= SCREEN_BASE_ADDR) && (address < ATTR_BASE_ADDR) {
		if memory.data[address] != b {
			memory.screenBitmapWrite(address)

			rel_addr := address - SCREEN_BASE_ADDR
			screenline_start_tstate := screenline_start_tstates[rel_addr>>BytesPerLine_log2]
			x, _ := screenAddr_to_xy(address)
			screen_tstate := screenline_start_tstate + uint(x>>PIXELS_PER_TSTATE_LOG2)
			if memory.z80.tstates > screen_tstate {
				// Remember the value read by ULA
				memory.ula_bitmap[rel_addr] = ula_byte_t{true, memory.data[address]}
			}
		}
	} else if (address >= ATTR_BASE_ADDR) && (address < 0x5b00) {
		memory.screenAttrWrite(address)

		attr_x := (address & 0x001f)
		attr_y := (address - ATTR_BASE_ADDR) / ScreenWidth_Attr

		x := uint(8 * attr_x)
		y := uint(8 * attr_y)
		for i := 0; i < 8; i++ {
			screenline_start_tstate := FIRST_SCREEN_BYTE + y*TSTATES_PER_LINE
			screen_tstate := screenline_start_tstate + (x >> PIXELS_PER_TSTATE_LOG2)
			if memory.z80.tstates > screen_tstate {
				ofs := (y << BytesPerLine_log2) + uint(attr_x)
				ula_attr := &memory.ula_attr[ofs]
				if !ula_attr.valid || (screen_tstate > ula_attr.tstate) {
					*ula_attr = ula_attr_t{true, memory.data[address], memory.z80.tstates}
				}
			}
			y++
		}
	}

	memory.data[address] = b
}

func (memory *Memory) screenBitmapWrite(address uint16) {
	// address: [0 1 0 y7 y6 y2 y1 y0 / y5 y4 y3 x4 x3 x2 x1 x0]
	var attr_x = (address & 0x001f)
	var attr_y = (((address & 0x0700) >> 8) | ((address & 0x00e0) >> 2) | ((address & 0x1800) >> 5)) / 8
	memory.dirtyScreen[attr_y*ScreenWidth_Attr+attr_x] = true
}

func (memory *Memory) screenAttrWrite(address uint16) {
	memory.dirtyScreen[address-ATTR_BASE_ADDR] = true
}

func (memory *Memory) getBorder() byte {
        return memory.borderColor
}

func (memory *Memory) setBorder(borderColor byte) {
        memory.borderColor = borderColor
}

// This function is called at the beginning of each frame
func (memory *Memory) frame_begin() {
	memory.frame++
	if memory.frame == 1 {
		// The very first frame --> repaint the whole screen
		for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
			memory.dirtyScreen[i] = true
		}
	} else {
		for i := 0; i < ScreenWidth_Attr*ScreenHeight_Attr; i++ {
			memory.dirtyScreen[i] = false
{'fraction_non_alphanumeric': 0.10858298571609151, 'fraction_numerical': 0.027050941726709646, 'mean_word_length': 4.267643142476698, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '884437', 'n_tokens_mistral': 3079, 'n_tokens_neox': 2802, 'n_words': 736}