Skip to content

Commit

Permalink
zsim: new memory access working.
Browse files Browse the repository at this point in the history
  • Loading branch information
maziac committed Mar 22, 2020
1 parent 52d399a commit ad7749b
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 98 deletions.
10 changes: 5 additions & 5 deletions src/remotes/zxsimulator/z80cpu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,13 @@ export class Z80Cpu extends Z80js {
histData.set(regData);
// Store opcode (4 bytes)
const pc=self.pc;
const opcodes8=self.memory.getMemory(pc, 4);
histData[startHist]=opcodes8[0]+(opcodes8[1]<<8);
histData[startHist + 1] = opcodes8[2] + (opcodes8[3] << 8);
const opcodes=self.memory.getMemory32(pc);
histData[startHist]=opcodes&0xFFFF;
histData[startHist+1]=opcodes>>>16;
// Store sp contents
const sp=self.sp;
const spContents8=self.memory.getMemory(sp, 2);
histData[startHist+2]=spContents8[0]+(spContents8[1]<<8);
const spContents=self.memory.getMemory16(sp);
histData[startHist+2]=spContents;
// return
return histData;
}
Expand Down
155 changes: 62 additions & 93 deletions src/remotes/zxsimulator/zxmemory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as fs from 'fs';
import {ImageConvert} from '../../imageconvert';
import {Utility} from '../../misc/utility';
import {MemBuffer} from '../../misc/membuffer';
import {start} from 'repl';


/**
Expand Down Expand Up @@ -132,9 +133,8 @@ export class ZxMemory {
public read8(addr: number): number {
// Visual memory
this.visualMemory[addr>>>this.VISUAL_MEM_SIZE_SHIFT]=this.VISUAL_MEM_COL_READ;
// Real read access
const [bankAddr, bankMem]=this.getBankForAddr(addr);
const value=bankMem[bankAddr];
// Read
const value=this.z80Memory[addr];
return value;
}

Expand All @@ -143,65 +143,44 @@ export class ZxMemory {
public write8(addr: number, val: number) {
// Visual memory
this.visualMemory[addr>>>this.VISUAL_MEM_SIZE_SHIFT]=this.VISUAL_MEM_COL_WRITE;
// Real write access
const [bankAddr, bankMem]=this.getBankForAddr(addr);
bankMem[bankAddr]=val;
// Write
this.z80Memory[addr]=val;
}


// Read a memory area.
// Used e.g. to read data for the history info.
// Reads one byte.
// This is **not** used by the Z80 CPU.
public getMemory(addr: number, size: number): Uint8Array {
assert(size<=ZxMemory.MEMORY_BANK_SIZE);
// Get start address
const [bankAddr, bankMem]=this.getBankForAddr(addr);
// Check if memory area spans 2 banks
const endAddr=bankAddr+size;
let mem;
if (endAddr<=ZxMemory.MEMORY_BANK_SIZE) {
// Within one bank
mem=bankMem.subarray(bankAddr, endAddr);
}
else {
// Spans over 2 banks
mem=new Uint8Array(size);
const len=ZxMemory.MEMORY_BANK_SIZE-bankAddr;
const bMemCopy=bankMem.subarray(bankAddr, ZxMemory.MEMORY_BANK_SIZE);
mem.set(bMemCopy);
const addr2=addr+len;
const [bankAddr2, bankMem2]=this.getBankForAddr(addr2);
assert(bankAddr2==0);
const bMemCopy2=bankMem2.subarray(0, size-len);
mem.set(bMemCopy2, len);
}
// Return
return mem;
public getMemory8(addr: number): number {
const value=this.z80Memory[addr];
return value;
}

// Read s one byte.
// Reads 2 bytes.
// This is **not** used by the Z80 CPU.
public getMemory8(addr: number): number {
const [bankAddr, bankMem]=this.getBankForAddr(addr);
const value=bankMem[bankAddr];
public getMemory16(addr: number): number {
const mem=this.z80Memory;
let value=mem[addr++];
value|=mem[addr&0xFFFF]<<8;
return value;
}

// Read s one byte.
// Reads 4 bytes.
// This is **not** used by the Z80 CPU.
public getMemory16(addr: number): number {
const mem=this.getMemory(addr, 2);
const value=mem[0]+(mem[1]<<8);
public getMemory32(addr: number): number {
const mem=this.z80Memory;
let value=mem[addr++];
value|=mem[(addr++)&0xFFFF]<<8;
value|=mem[(addr++)&0xFFFF]<<16;
value|=mem[addr&0xFFFF]<<24;
return value;
}

// Read s one byte.
// This is **not** used by the Z80 CPU.
public setMemory16(addr: number, val: number) {
const [bankAddr, bankMem]=this.getBankForAddr(addr);
bankMem[bankAddr]=val&0xFF;
const [bankAddr2, bankMem2]=this.getBankForAddr(addr+1);
bankMem2[bankAddr2]=val>>>8;
const mem=this.z80Memory;
mem[addr++]=val&0xFF;
mem[addr&0xFFFF]=val>>>8;
}


Expand Down Expand Up @@ -246,60 +225,51 @@ export class ZxMemory {
* @param size The size of the block.
*/
public readBlock(startAddress: number, size: number): Uint8Array {
const totalBlock=new Uint8Array(size);
let offset=0;
// The block may span several banks.
let addr=startAddress;
while (size>0) {
// Get memory bank
const [bankAddr, bankMem]=this.getBankForAddr(addr);
// Get block within one bank
let blockEnd=bankAddr+size;
if (blockEnd>ZxMemory.MEMORY_BANK_SIZE)
blockEnd=ZxMemory.MEMORY_BANK_SIZE;
const partBlockSize=blockEnd-bankAddr;
// Copy partial block
const partBlock=bankMem.subarray(bankAddr, blockEnd);
// Add to total block
totalBlock.set(partBlock, offset);
// Next
offset+=partBlockSize;
size-=partBlockSize;
addr+=partBlockSize;
let endAddr=startAddress+size;
if (endAddr<=0x10000) {
// No overflow
const mem=new Uint8Array(this.z80Memory.buffer, startAddress, size);
return mem;
}
return totalBlock;

// Overflow. Create new block out of 2 parts.
const mem=new Uint8Array(size);
// First block
const firstSize=0x10000-startAddress;
const firstBlock=new Uint8Array(this.z80Memory.buffer, startAddress, firstSize);
mem.set(firstBlock);
// Second block
const secondSize=size-firstSize;
const secondBlock=new Uint8Array(this.z80Memory.buffer, 0, secondSize);
mem.set(secondBlock, firstSize);
// Return
return mem;
}


/**
* Writes a block of bytes.
* @param startAddress Start address.
* @param totalBlock The block to write.
*/
public writeBlock(startAddress: number, totalBlock: Buffer|Uint8Array) {
if (!(totalBlock instanceof Uint8Array))
totalBlock=new Uint8Array(totalBlock);
let offset=0;
// The block may span several banks.
let addr=startAddress;
let size=totalBlock.length;
while (size>0) {
// Get memory bank
const [bankAddr, bankMem]=this.getBankForAddr(addr);
// Get block within one bank
let blockEnd=bankAddr+size;
if (blockEnd>ZxMemory.MEMORY_BANK_SIZE)
blockEnd=ZxMemory.MEMORY_BANK_SIZE;
const partBlockSize=blockEnd-bankAddr;
// Copy partial block
const partBlock=totalBlock.subarray(offset, offset+partBlockSize);
// Copy to memory bank
bankMem.set(partBlock, bankAddr);
// Next
offset+=partBlockSize;
size-=partBlockSize;
addr+=partBlockSize;
const size=totalBlock.length;
let endAddr=startAddress+size;
if (endAddr<=0x10000) {
// No overflow
this.z80Memory.set(totalBlock);
}
else {
// Overflow. Copy in 2 parts.
// First block
const firstSize=0x10000-startAddress;
const firstBlock=new Uint8Array(totalBlock, 0, firstSize);
this.z80Memory.set(firstBlock, startAddress);
// Second block
const secondSize=size-firstSize;
const secondBlock=new Uint8Array(totalBlock, firstSize, secondSize);
this.z80Memory.set(secondBlock);
}
return totalBlock;
}


Expand Down Expand Up @@ -402,10 +372,8 @@ export class ZxMemory {
* @returns The screen as a gif buffer.
*/
public getUlaScreen(): number[] {
// Get sceen memory
const [, screenMem]=this.getBankForAddr(0x4000);
// Create pixels from the screen memory
const pixels=this.createPixels(screenMem);
const pixels=this.createPixels();
// Get ZX palette
const zxPalette=ZxMemory.getZxPalette();
// Convert to gif
Expand All @@ -419,7 +387,8 @@ export class ZxMemory {
* Converts the screen pixels, the bits in the bytes, into pixels
* with a color index.
*/
protected createPixels(screenMem: Uint8Array): Array<number> {
protected createPixels(): Array<number> {
const screenMem=new Uint8Array(this.z80Memory.buffer, 0x4000);
const colorStart=ZxMemory.SCREEN_HEIGHT*ZxMemory.SCREEN_WIDTH/8;
// Create pixels memory
const pixels=new Array<number>(ZxMemory.SCREEN_HEIGHT*ZxMemory.SCREEN_WIDTH);
Expand Down

0 comments on commit ad7749b

Please sign in to comment.