15 Commits
v0.9 ... master

Author SHA1 Message Date
Manoël Trapier
01ffa3a834 Add apt update. part 2 2022-03-12 12:04:45 +00:00
Manoël Trapier
fce2815300 Add apt update. 2022-03-12 12:04:18 +00:00
Manoël Trapier
662a45d02f Create codeql-analysis.yml 2022-02-28 15:32:33 +00:00
Manoël Trapier
bb324dc12e Remplace travis build badge with github's one. 2022-02-28 12:33:51 +00:00
Godzil
017983f692 Trying to make the google action to work. 2022-02-28 12:31:43 +00:00
Godzil
b4b1bd83d0 Fix a typo 2022-02-25 18:19:00 +00:00
Manoël Trapier
a85e1ff083 Need to checkout with submodule silly! 2022-02-23 18:02:31 +00:00
Manoël Trapier
4c9ba704ea Testing github action
Travis is no longer free. So need to test alternatives.
2022-02-23 17:59:53 +00:00
Godzil
8fa2ef06ab Rename some functions and a tad of cleanup. 2021-12-20 19:12:33 +00:00
Godzil
4fc5193bc7 Add testserial part of the build. 2021-12-20 19:12:30 +00:00
Godzil
1df15b0192 Uniformise copyright headers. 2021-12-20 19:12:12 +00:00
Godzil
6f539fff1e Not sure how I missed the R_RM8 and R_RM16 decoder. 2021-04-16 00:39:26 +01:00
Godzil
c90b99d650 Fix table size. 2021-04-16 00:33:48 +01:00
Godzil
49a1943cda Add proper support for indirect call/jmp 2021-04-16 00:32:56 +01:00
Godzil
4082d37cb0 Add missing mov cs, rm and mov rm, cs opcode. 2021-04-16 00:32:08 +01:00
30 changed files with 436 additions and 225 deletions

38
.github/workflows/cmake.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: CMake
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
BUILD_TYPE: Release
jobs:
build:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.allow_failure }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-18.04, ubuntu-20.04, ubuntu-latest ]
allow_failure: [ false ]
# include:
# - os: macos-latest
# allow_failure: true
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Install needed dependencies
run: sudo apt update && sudo apt install xorg-dev libglu1-mesa-dev
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

62
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,62 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '43 19 * * 5'
env:
BUILD_TYPE: Debug
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
submodules: true
- name: Install needed dependencies
run: sudo apt update && sudo apt install xorg-dev libglu1-mesa-dev
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
- name: Running Cmake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Building
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@@ -47,4 +47,5 @@ add_subdirectory(source)
target_link_libraries(wonderswan wswan glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
add_executable(dumpinfo dumpinfo.c)
add_executable(dumpinfo dumpinfo.c)
add_executable(testserial testserial.c)

View File

@@ -1,6 +1,6 @@
NewOswan *(name likely to change)*
==================================
![TravisBadge](https://travis-ci.org/Godzil/NewOswan.svg?branch=master)
[![CMake](https://github.com/Godzil/NewOswan/actions/workflows/cmake.yml/badge.svg)](https://github.com/Godzil/NewOswan/actions/workflows/cmake.yml)
### What is this project?
NewOswan is a WonderSwan emulator originally based on oswan-unix and heavily modified to be more accurate and better

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* dumpinfo.c: Tool to dump the metadata info about a cart rom image.
*
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

5
main.c
View File

@@ -1,10 +1,11 @@
/*
/******************************************************************************
* NewOswan
* main.c: Entry point
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
//
// 13.04.2002: Fixed a small bug causing crashes

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* audio.c:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
//
// Sound information thanks to toshi (wscamp wonderswan emulator)
@@ -210,8 +211,8 @@ void ws_audio_port_write(uint32_t port, uint8_t value)
for (k = 0 ; k < n ; k++)
{
b = cpu_readmem20(i);
cpu_writemem20(j, b);
b = mem_readmem20(i);
mem_writemem20(j, b);
i++;
j++;
}
@@ -1304,7 +1305,7 @@ void ws_audio_process(void)
{
i = (SDMACH << 8) | SDMACL;
j = (SDMASB << 16) | (SDMASH << 8) | SDMASL;
b = cpu_readmem20(j);
b = mem_readmem20(j);
if (!ws_audio_channel_isPlaying[5])
{

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* audio.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* emulate.c:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
@@ -438,24 +439,25 @@ void ws_emulate(void)
dNormalLast = getTicks();
#define HCLK (1000. / 12000.)
while (1)
{
dTemp = getTicks();
dTime = dTemp - dNormalLast;
nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense?
nCount = (int32_t)(dTime * HCLK); // does this calculation make sense?
if (nCount <= 0)
{
/* Sleep for 2ms */
usleep(2000);
/* Sleep for 500us */
usleep(500);
} // No need to do anything for a bit
else
{
dNormalLast += nCount * (1 / 0.07547);
dNormalLast += nCount * (1 / HCLK);
if (nCount > 10)
{
@@ -474,7 +476,7 @@ void ws_emulate(void)
}
}
/* What is this mess? Frameskip? */
for (i = 0 ; i < nCount - 1 ; i++)
{
while (!ws_executeLine(backBuffer, 0))

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* emulate.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//

View File

@@ -1,3 +1,11 @@
/*******************************************************************************
* NewOswan
* gpu.c:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// GPU
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* gpu.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
#ifndef __GPU_H__
#define __GPU_H__

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* io.c: I/O ports implementaton
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
@@ -101,7 +102,7 @@ FILE *ioLogFp = NULL;
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_io_reset(void)
void io_reset(void)
{
ws_key_start = 0;
ws_key_x4 = 0;
@@ -145,14 +146,14 @@ void ws_io_reset(void)
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_io_init(void)
void io_init(void)
{
if (ws_ioRam == NULL)
{
ws_ioRam = (uint8_t *)malloc(0x100);
}
ws_io_reset();
io_reset();
ws_key_flipped = 0;
#ifdef IO_DUMP
@@ -171,7 +172,7 @@ void ws_io_init(void)
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_io_flipControls(void)
void io_flipControls(void)
{
ws_key_flipped = !ws_key_flipped;
}
@@ -187,7 +188,7 @@ void ws_io_flipControls(void)
//
//
////////////////////////////////////////////////////////////////////////////////
void ws_io_done(void)
void io_done(void)
{
if (ws_ioRam == NULL)
{
@@ -258,7 +259,7 @@ void set_baudrate(int speed)
tcsetattr(serialfd, TCSANOW, &options);
/* Make sure read is not blocking */
fcntl(serialfd, F_SETFL, FNDELAY);
fcntl(serialfd, F_SETFL, FNDELAY);
}
void close_serial()
@@ -350,7 +351,7 @@ void write_serial(unsigned char value)
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t cpu_readport(uint8_t port)
uint8_t io_readport(uint8_t port)
{
int w1, w2;
uint8_t retVal = 0;
@@ -618,9 +619,28 @@ uint8_t cpu_readport(uint8_t port)
exit:
if (port < 0xC0)
{
switch(port)
{
case 0x02:
case 0x84:
case 0x85:
case 0x90:
case 0x91:
case 0xB5:
break;
default:
Log(TLOG_DEBUG, "io", "ReadIO %02X <= %02X", port, retVal);
break;
}
}
if (ioLogFp)
{
fprintf(ioLogFp, "%ld, R, %02X, %02X\n", nec_monotonicCycles, port, retVal);
fprintf(ioLogFp, "%llu, R, %02X, %02X\n", nec_monotonicCycles, port, retVal);
}
return retVal;
}
@@ -636,13 +656,13 @@ exit:
//
//
////////////////////////////////////////////////////////////////////////////////
void cpu_writeport(uint32_t port, uint8_t value)
void io_writeport(uint32_t port, uint8_t value)
{
int unknown_io_port = 0;
if (ioLogFp)
{
fprintf(ioLogFp, "%ld, W, %02X, %02X\n", nec_monotonicCycles, port, value);
fprintf(ioLogFp, "%llu, W, %02X, %02X\n", nec_monotonicCycles, port, value);
}
if (port > 0x100)
@@ -792,7 +812,7 @@ void cpu_writeport(uint32_t port, uint8_t value)
for (int ix = 0 ; ix < dma_size ; ix++)
{
cpu_writemem20(dma_end++, cpu_readmem20(dma_start++));
mem_writemem20(dma_end++, mem_readmem20(dma_start++));
}
ws_ioRam[0x47] = 0;

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* io.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
@@ -32,10 +33,13 @@ extern uint8_t ws_key_y3;
extern uint8_t ws_key_button_a;
extern uint8_t ws_key_button_b;
void ws_io_init(void);
void ws_io_reset(void);
void ws_io_flipControls(void);
void ws_io_done(void);
void io_init(void);
void io_reset(void);
void io_flipControls(void);
void io_done(void);
uint8_t io_readport(uint8_t port);
void io_writeport(uint32_t port, uint8_t value);
#endif

View File

@@ -1,10 +1,10 @@
/*
* C Fancy Logger
* log.c:
/*******************************************************************************
* NewOswan
* log.c: C Fancy Logger
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
*
* Created by Manoël Trapier on 20/01/2009.
*/
******************************************************************************/
#define __LOG_C_INTERNAL_

View File

@@ -1,10 +1,10 @@
/*
* C Fancy Logger
* log.h:
/*******************************************************************************
* NewOswan
* log.h: C Fancy Logger
* Copyright (c) 2009-2021 986-Studio. All rights reserved.
*
* Created by Manoël Trapier on 20/01/2009.
*/
******************************************************************************/
#ifndef _LOG_H
#define _LOG_H

View File

@@ -1,12 +1,13 @@
/*
/*******************************************************************************
* NewOswan
* memory.c: Memory implementatoion
* memory.c: Memory implementation
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// Notes: need to optimize cpu_writemem20
// Notes: need to optimize mem_writemem20
//
//
//
@@ -135,7 +136,7 @@ void dump_memory()
//
//
////////////////////////////////////////////////////////////////////////////////
void cpu_writemem20(uint32_t addr, uint8_t value)
void mem_writemem20(uint32_t addr, uint8_t value)
{
uint32_t offset = addr & 0xffff;
uint32_t bank = addr >> 16;
@@ -166,7 +167,7 @@ void cpu_writemem20(uint32_t addr, uint8_t value)
//
//
////////////////////////////////////////////////////////////////////////////////
uint8_t cpu_readmem20(uint32_t addr)
uint8_t mem_readmem20(uint32_t addr)
{
uint32_t offset = addr & 0xffff;
uint32_t bank = addr >> 16;
@@ -259,7 +260,7 @@ uint8_t cpu_readmem20(uint32_t addr)
uint8_t *pagedMemory[0x100];
/* Memory address is 20bit and split in 8 (page) - 12 (offset) */
void cpu_writemem20(uint32_t addr, uint8_t value)
void mem_writemem20(uint32_t addr, uint8_t value)
{
uint8_t page = addr >> 12;
uint16_t offset = addr & 0xFFF;
@@ -273,7 +274,7 @@ void cpu_writemem20(uint32_t addr, uint8_t value)
}
}
uint8_t cpu_readmem20(uint32_t addr)
uint8_t mem_readmem20(uint32_t addr)
{
uint8_t page = addr >> 12;
uint16_t offset = addr & 0xFFF;

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* memory.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
@@ -58,6 +59,11 @@ uint8_t *getRom(uint32_t *size);
uint8_t *getSram(uint32_t *size);
#endif
#define mem_readop mem_readmem20
#define mem_readop_arg mem_readmem20
void mem_writemem20(uint32_t addr, uint8_t value);
uint8_t mem_readmem20(uint32_t addr);
#define BW_IEEPROM_SIZE (128)
#define COLOR_IEEPROM_SIZE (2048)

View File

@@ -1,10 +1,11 @@
/*
/******************************************************************************
* NewOswan
* nec.c:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
/****************************************************************************
NEC V30MZ(V20/V30/V33) emulator
@@ -39,6 +40,9 @@
#include <log.h>
#include "memory.h"
#include "io.h"
#include "nec.h"
#include "necintrf.h"
#include "nec_debugger.h"
@@ -4221,11 +4225,11 @@ int nec_execute(int cycles)
while (nec_ICount > 0)
{
#if 0
if ((I.sregs[CS] == 0x0600) /* && (I.ip > 0x0050) */)
if ((I.sregs[CS] == 0xF000) && (I.ip >= 0x0000) )
{
int tmp;
char buffer[256];
uint8_t op = cpu_readmem20((I.sregs[CS] << 4) + I.ip);
uint8_t op = mem_readmem20((I.sregs[CS] << 4) + I.ip);
//Log(TLOG_NORMAL, "NEC v30", "[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, instructionsName[op], I.IF);
printf("AX: %04X, BX: %04X, CX: %04X, DX: %04X, SI: %04X, DI: %04X, SP: %04X\n",
I.regs.w[AW], I.regs.w[BW], I.regs.w[CW], I.regs.w[DW],

View File

@@ -1,10 +1,11 @@
/*
/******************************************************************************
* NewOswan
* nec.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
#ifndef __NEC_H_
#define __NEC_H_
@@ -114,30 +115,30 @@ typedef struct
#define DefaultBase(Seg) ((seg_prefix && (Seg==DS || Seg==SS)) ? (prefix_base) : (uint32_t)(I.sregs[Seg] << 4))
#define GetMemB(Seg, Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint8_t)cpu_readmem20((DefaultBase(Seg)+(Off))))
#define GetMemW(Seg, Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint16_t) cpu_readmem20((DefaultBase(Seg)+(Off))) + (cpu_readmem20((DefaultBase(Seg)+((Off)+1)))<<8) )
#define GetMemB(Seg, Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint8_t)mem_readmem20((DefaultBase(Seg)+(Off))))
#define GetMemW(Seg, Off) (/*nec_ICount-=((Off)&1)?1:0,*/ (uint16_t) mem_readmem20((DefaultBase(Seg)+(Off))) + (mem_readmem20((DefaultBase(Seg)+((Off)+1)))<<8) )
#define PutMemB(Seg, Off, x) { /*nec_ICount-=((Off)&1)?1:0*/; cpu_writemem20((DefaultBase(Seg)+(Off)),(x)); }
#define PutMemB(Seg, Off, x) { /*nec_ICount-=((Off)&1)?1:0*/; mem_writemem20((DefaultBase(Seg)+(Off)),(x)); }
#define PutMemW(Seg, Off, x) { /*nec_ICount-=((Off)&1)?1:0*/; PutMemB(Seg,Off,(x)&0xff); PutMemB(Seg,(Off)+1,(uint8_t)((x)>>8)); }
/* Todo: Remove these later - plus readword could overflow */
#define ReadByte(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ (uint8_t)cpu_readmem20((ea)))
#define ReadWord(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ cpu_readmem20((ea))+(cpu_readmem20(((ea)+1))<<8))
#define WriteByte(ea, val) { /*nec_ICount-=((ea)&1)?1:0*/; cpu_writemem20((ea),val); }
#define WriteWord(ea, val) { /*nec_ICount-=((ea)&1)?1:0*/; cpu_writemem20((ea),(uint8_t)(val)); cpu_writemem20(((ea)+1),(val)>>8); }
#define ReadByte(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ (uint8_t)mem_readmem20((ea)))
#define ReadWord(ea) (/*nec_ICount-=((ea)&1)?1:0,*/ mem_readmem20((ea))+(mem_readmem20(((ea)+1))<<8))
#define WriteByte(ea, val) { /*nec_ICount-=((ea)&1)?1:0*/; mem_writemem20((ea),val); }
#define WriteWord(ea, val) { /*nec_ICount-=((ea)&1)?1:0*/; mem_writemem20((ea),(uint8_t)(val)); mem_writemem20(((ea)+1),(val)>>8); }
#define read_port(port) cpu_readport(port)
#define write_port(port, val) cpu_writeport(port,val)
#define read_port(port) io_readport(port)
#define write_port(port, val) io_writeport(port,val)
#define FETCH (cpu_readop_arg((I.sregs[CS]<<4)+I.ip++))
#define FETCHOP (cpu_readop((I.sregs[CS]<<4)+I.ip++))
#define FETCHWORD(var) { var=cpu_readop_arg((((I.sregs[CS]<<4)+I.ip)))+(cpu_readop_arg((((I.sregs[CS]<<4)+I.ip+1)))<<8); I.ip+=2; }
#define FETCH (mem_readop_arg((I.sregs[CS]<<4)+I.ip++))
#define FETCHOP (mem_readop((I.sregs[CS]<<4)+I.ip++))
#define FETCHWORD(var) { var=mem_readop_arg((((I.sregs[CS]<<4)+I.ip)))+(mem_readop_arg((((I.sregs[CS]<<4)+I.ip+1)))<<8); I.ip+=2; }
#define PUSH(val) { I.regs.w[SP]-=2; WriteWord((((I.sregs[SS]<<4)+I.regs.w[SP])),val); }
#define POP(var) { var = ReadWord((((I.sregs[SS]<<4)+I.regs.w[SP]))); I.regs.w[SP]+=2; }
#define PEEK(addr) ((uint8_t)cpu_readop_arg(addr))
#define PEEKOP(addr) ((uint8_t)cpu_readop(addr))
#define PEEK(addr) ((uint8_t)mem_readop_arg(addr))
#define PEEKOP(addr) ((uint8_t)mem_readop(addr))
#define GetModRM uint32_t ModRM=cpu_readop_arg((I.sregs[CS]<<4)+I.ip++)
#define GetModRM uint32_t ModRM=mem_readop_arg((I.sregs[CS]<<4)+I.ip++)
/* Cycle count macros:
CLK - cycle count is the same on all processors

View File

@@ -14,6 +14,7 @@
#include "log.h"
#include "nec_debugger.h"
#include "necintrf.h"
#include "memory.h"
/***
* Note: the while code to decode instruction is not meant to be optimised, but to be easy to maintain.
@@ -282,10 +283,10 @@ enum extendedOpcodes
OP_GP2_INC = 0,
OP_GP2_DEC = 1,
OP_GP2_CALL1 = 2,
OP_GP2_CALL2 = 3,
OP_GP2_JMP1 = 4,
OP_GP2_JMP2 = 5,
OP_GP2_CALL = 2,
OP_GP2_CALLF = 3,
OP_GP2_JMP = 4,
OP_GP2_JMPF = 5,
OP_GP2_PUSH = 6,
};
@@ -327,7 +328,7 @@ typedef enum modrmValues
const char *modrmReg8List[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
const char *modrmReg16List[8] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
const char *segmentRegList[4] = { "ds", "cs", "ss", "es" };
const char *segmentRegList[8] = { "es", "cs", "ss", "ds", "ILLEGAL", "ILLEGAL", "ILLEGAL", "ILLEGAL" };
static inline void get_mod_reg_rm(uint8_t value, uint8_t *mod, uint8_t *reg, uint8_t *rm, uint8_t *modrm)
{
if (mod)
@@ -353,8 +354,8 @@ static inline void get_mod_reg_rm(uint8_t value, uint8_t *mod, uint8_t *reg, uin
static int decode_modrm(uint16_t segment, uint16_t offset, modrmValues modrm, bool is8bit, char *buffer, uint32_t bufferLength)
{
uint8_t disp8 = cpu_readmem20(MAKE_LINEAR(segment, offset));
uint16_t disp16 = (cpu_readmem20(MAKE_LINEAR(segment, offset + 1)) << 8) | disp8;
uint8_t disp8 = mem_readmem20(MAKE_LINEAR(segment, offset));
uint16_t disp16 = (mem_readmem20(MAKE_LINEAR(segment, offset + 1)) << 8) | disp8;
char buf[63];
int offsetReturn = 0;
@@ -544,7 +545,7 @@ static int decode_modrm(uint16_t segment, uint16_t offset, modrmValues modrm, bo
int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsigned int bufferSize)
{
uint8_t opcode = cpu_readmem20(MAKE_LINEAR(segment, offset));
uint8_t opcode = mem_readmem20(MAKE_LINEAR(segment, offset));
uint16_t currentOffset = offset;
int16_t param1, param2;
uint8_t modrm, reg;
@@ -562,7 +563,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
{
/* Need to handle opcode group */
case OP_IMMED:
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
get_mod_reg_rm(param1, NULL, &reg, NULL, NULL);
switch (reg)
{
@@ -631,7 +632,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case OP_SHIFT:
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
get_mod_reg_rm(param1, NULL, &reg, NULL, NULL);
switch (reg)
{
@@ -666,7 +667,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case OP_GRP1:
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
get_mod_reg_rm(param1, NULL, &reg, NULL, NULL);
switch (reg)
{
@@ -711,7 +712,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case OP_GRP2:
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
get_mod_reg_rm(param1, NULL, &reg, NULL, NULL);
switch (reg)
{
@@ -721,10 +722,9 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
case OP_GP2_DEC:
strncat(buffer, "dec", bufferSize);
break;
case OP_GP2_CALL1:
case OP_GP2_CALL:
if (opcode == 0xFF)
{
// TODO: Understand this opcode
strncat(buffer, "call", bufferSize);
}
else
@@ -733,11 +733,10 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
opcodeParams = PR_NONE;
}
break;
case OP_GP2_CALL2:
case OP_GP2_CALLF:
if (opcode == 0xFF)
{
// TODO: Understand this opcode
strncat(buffer, "call", bufferSize);
strncat(buffer, "call far", bufferSize);
}
else
{
@@ -745,10 +744,9 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
opcodeParams = PR_NONE;
}
break;
case OP_GP2_JMP1:
case OP_GP2_JMP:
if (opcode == 0xFF)
{
// TODO: Understand this opcode
strncat(buffer, "jmp", bufferSize);
}
else
@@ -757,11 +755,10 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
opcodeParams = PR_NONE;
}
break;
case OP_GP2_JMP2:
case OP_GP2_JMPF:
if (opcode == 0xFF)
{
// TODO: Understand this opcode
strncat(buffer, "jmp", bufferSize);
strncat(buffer, "jmp far", bufferSize);
}
else
{
@@ -791,7 +788,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
case OP_MOVG:
/* Special case for C6 and C7, they are valid ONLY if reg == 0 */
param1 = cpu_readmem20(MAKE_LINEAR(segment, offset + 1));
param1 = mem_readmem20(MAKE_LINEAR(segment, offset + 1));
get_mod_reg_rm(param1, NULL, &reg, NULL, NULL);
if (reg > 0)
{
@@ -856,202 +853,202 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
/******* Immediate values *******/
case PR_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
/******* Register / Immediate *******/
case PR_AL_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " al, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_AH_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " ah, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_AX_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " ax, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_AX_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " ax, 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " ax, 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_IM8_AL:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " 0%Xh, al", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_IM8_AX:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " 0%Xh, ax", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_BL_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " bl, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_BH_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " bh, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_BX_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " bx, 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " bx, 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_CL_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " cl, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_CH_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " ch, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_CX_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " cx, 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " cx, 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_DL_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " dl, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_DH_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " dh, 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
currentOffset++;
break;
case PR_DX_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " dx, 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " dx, 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_SP_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " sp, 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " sp, 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_BP_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " bp, 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " bp, 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_DI_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " di, 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " di, 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_SI_IM16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " si, 0%Xh", param1 & 0xFF);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
snprintf(buf, 63, " si, 0%Xh", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
/******* Register / Memory *******/
case PR_M8_AL:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
/* TODO: If having a list of known label, try to match and display label instead of value */
snprintf(buf, 63, " byte [0%Xh], al", param1 & 0xFF);
snprintf(buf, 63, " byte [0%Xh], al", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_M16_AX:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
/* TODO: If having a list of known label, try to match and display label instead of value */
snprintf(buf, 63, " word [0%Xh], ax", param1 & 0xFF);
snprintf(buf, 63, " word [0%Xh], ax", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_AL_M8:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
/* TODO: If having a list of known label, try to match and display label instead of value */
snprintf(buf, 63, " al, byte [0%Xh]", param1 & 0xFF);
snprintf(buf, 63, " al, byte [0%Xh]", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
case PR_AX_M16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
/* TODO: If having a list of known label, try to match and display label instead of value */
snprintf(buf, 63, " ax, word [0%Xh]", param1 & 0xFF);
snprintf(buf, 63, " ax, word [0%Xh]", param1);
strncat(buffer, buf, bufferSize);
currentOffset += 2;
break;
/******* Address calculation *******/
case PR_REL8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
param1 = currentOffset + (int8_t)param1;
/* TODO: If having a list of known label, try to match and display label instead of value */
@@ -1061,8 +1058,8 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case PR_REL16:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset += 2;
param1 = currentOffset + (int16_t) param1;
@@ -1073,21 +1070,21 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case PR_ABS32:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param2 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 3)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
param2 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 3)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
/* TODO: If having a list of known label, try to match and display label instead of value */
snprintf(buf, 63, " 0%Xh:0%Xh", param2, param1);
snprintf(buf, 63, " 0%Xh:0%Xh", param2 & 0xFFFF, param1 & 0xFFFF);
strncat(buffer, buf, bufferSize);
currentOffset += 4;
break;
/******* Other cases *******/
case PR_IM16_IM8:
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param2 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
param2 = mem_readmem20(MAKE_LINEAR(segment, currentOffset + 2));
snprintf(buf, 63, " 0%Xh:0%Xh", param1, param2);
strncat(buffer, buf, bufferSize);
currentOffset += 3;
@@ -1097,55 +1094,55 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
************************************************ Complicated cases ************************************************
******************************************************************************************************************/
case PR_RM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
break;
case PR_RM16:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
break;
case PR_RM_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
snprintf(buf, 63, ", 0%Xh", param1);
strncat(buffer, buf, bufferSize);
break;
case PR_RM16_IM8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset ++;
snprintf(buf, 63, ", 0%Xh", param1 & 0xFF);
strncat(buffer, buf, bufferSize);
break;
case PR_RM_IM16:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
param1 = (cpu_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset += 2;
snprintf(buf, 63, ", 0%Xh", param1);
strncat(buffer, buf, bufferSize);
break;
case PR_RM8_1:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
@@ -1153,7 +1150,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case PR_RM16_1:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
@@ -1161,7 +1158,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case PR_RM8_CL:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
@@ -1169,7 +1166,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case PR_RM16_CL:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, NULL, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
@@ -1177,7 +1174,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case PR_RM_R8:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, &reg, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
@@ -1186,7 +1183,7 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
break;
case PR_RM_R16:
param1 = cpu_readmem20(MAKE_LINEAR(segment, currentOffset));
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, &reg, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
@@ -1194,12 +1191,46 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
strncat(buffer, buf, bufferSize);
break;
case PR_R_RM8:
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, &reg, NULL, &modrm);
snprintf(buf, 63, " %s,", modrmReg8List[reg]);
strncat(buffer, buf, bufferSize);
currentOffset += decode_modrm(segment, currentOffset, modrm, true, buffer, bufferSize);
break;
case PR_R_RM16:
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, &reg, NULL, &modrm);
snprintf(buf, 63, " %s,", modrmReg16List[reg]);
strncat(buffer, buf, bufferSize);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
break;
case PR_RM16_SEG:
// TODO: Find how to decode the segment value
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, &reg, NULL, &modrm);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset += 2;
snprintf(buf, 63, ", %s", segmentRegList[reg]);
strncat(buffer, buf, bufferSize);
break;
case PR_SEG_RM16:
// TODO: Find how to decode the segment value
param1 = mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset++;
get_mod_reg_rm(param1, NULL, &reg, NULL, &modrm);
snprintf(buf, 63, ", %s", segmentRegList[reg]);
currentOffset += decode_modrm(segment, currentOffset, modrm, false, buffer, bufferSize);
param1 = (mem_readmem20(MAKE_LINEAR(segment, currentOffset + 1)) << 8) |
mem_readmem20(MAKE_LINEAR(segment, currentOffset));
currentOffset += 2;
strncat(buffer, buf, bufferSize);
break;
default:
@@ -1216,3 +1247,22 @@ int nec_decode_instruction(uint16_t segment, uint16_t offset, char *buffer, unsi
return currentOffset - offset;
}
#if 0
if ((I.sregs[CS] == 0x0600) /* && (I.ip > 0x0050) */)
{
int tmp;
char buffer[256];
uint8_t op = mem_readmem20((I.sregs[CS] << 4) + I.ip);
//Log(TLOG_NORMAL, "NEC v30", "[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, instructionsName[op], I.IF);
printf("AX: %04X, BX: %04X, CX: %04X, DX: %04X, SI: %04X, DI: %04X, SP: %04X\n",
I.regs.w[AW], I.regs.w[BW], I.regs.w[CW], I.regs.w[DW],
I.regs.w[IX], I.regs.w[IY], I.regs.w[SP]);
printf("CS: %04X, DS: %04X, SS: %04X, ES: %04X\n",
I.sregs[CS], I.sregs[DS], I.sregs[SS], I.sregs[ES]);
memset(buffer, 0, 256);
nec_decode_instruction(I.sregs[CS], I.ip, buffer, 255);
printf("[%04x:%04xh] %02xh '%s' - I=%d\n", I.sregs[CS], I.ip, op, buffer, I.IF);
tmp = getchar();
}
#endif

View File

@@ -1,10 +1,10 @@
/*
/******************************************************************************
* NewOswan
* necea.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
static uint32_t EA;
static uint16_t EO;

View File

@@ -1,10 +1,10 @@
/*
/******************************************************************************
* NewOswan
* necinstr.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
static void i_add_br8(void);
static void i_add_wr16(void);

View File

@@ -1,10 +1,11 @@
/*
/******************************************************************************
* NewOswan
* necintrf.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
/* ASG 971222 -- rewrote this interface */
#ifndef __NECITRF_H_
#define __NECITRF_H_
@@ -44,11 +45,4 @@ unsigned nec_get_reg(int regnum);
void nec_reset(void *param);
void nec_int(uint16_t vector);
uint8_t cpu_readport(uint8_t);
void cpu_writeport(uint32_t, uint8_t);
#define cpu_readop cpu_readmem20
#define cpu_readop_arg cpu_readmem20
void cpu_writemem20(uint32_t, uint8_t);
uint8_t cpu_readmem20(uint32_t);
#endif /* __NECITRF_H_ */

View File

@@ -1,10 +1,10 @@
/*
/******************************************************************************
* NewOswan
* necmodrm.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
static struct
{

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* tom.c:
* rom.c:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* rom.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//
@@ -32,7 +33,11 @@
#define WS_EEPROM_SIZE_NONE 0
#define WS_EEPROM_SIZE_1k 0x10
#define WS_EEPROM_SIZE_16k 0x20
#define WS_EEPROM_SIZE_32k 0x30
/* 40 is not valid */
#define WS_EEPROM_SIZE_8k 0x50
#define WS_EEPROM_SIZE_4k 0x60
#define WS_EEPROM_SIZE_2k 0x70
#define WS_SRAM_SIZE_NONE 0
#define WS_SRAM_SIZE_64k 0x01
@@ -44,15 +49,16 @@
#pragma pack(1)
typedef struct ws_romHeaderStruct
{
uint8_t developperId;
uint8_t minimumSupportSystem;
uint8_t cartId;
uint8_t gameVertion;
uint8_t romSize;
uint8_t saveSize;
uint8_t cartFlags;
uint8_t realtimeClock;
uint16_t checksum;
/* Miss "Fixed Data" (F5h) */
uint8_t developperId; /* Maker Code L */
uint8_t minimumSupportSystem; /* Maker Code H */
uint8_t cartId; /* Title code */
uint8_t gameVersion; /* Version */
uint8_t romSize; /* ROM Size */
uint8_t saveSize; /* XROM/XEROM Size */
uint8_t cartFlags; /* Boot loader */
uint8_t realtimeClock; /* Syb System LSI */
uint16_t checksum; /* Checksum */
} ws_romHeaderStruct;
#pragma pack()

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* ws.c: Base wonderswan implementation
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
//
//
@@ -132,13 +133,13 @@ int ws_init(char *rompath)
ws_memory_init(rom, romSize);
ws_patchRom();
ws_io_init();
io_init();
ws_audio_init();
ws_gpu_init();
if (ws_rotated())
{
ws_io_flipControls();
io_flipControls();
}
return (1);
@@ -158,7 +159,7 @@ int ws_init(char *rompath)
void ws_reset(void)
{
ws_memory_reset();
ws_io_reset();
io_reset();
ws_audio_reset();
ws_gpu_reset();
nec_reset(NULL);
@@ -287,7 +288,7 @@ int ws_executeLine(int16_t *framebuffer, int renderLine)
void ws_done(void)
{
ws_memory_done();
ws_io_done();
io_done();
ws_audio_done();
ws_gpu_done();
}

View File

@@ -1,10 +1,11 @@
/*
/*******************************************************************************
* NewOswan
* ws.h:
* Based on the original Oswan-unix
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//
//

View File

@@ -1,10 +1,11 @@
/*
/******************************************************************************
* NewOswan
* testserial.c: A simple tool to test serial in/out
* Based on the original Oswan-unix
*
* Copyright (c) 2014-2021 986-Studio. All rights reserved.
*
*/
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -14,6 +15,10 @@
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
/*
* The code, as is, was part of a fuzzer for the WonderSwan Tetris game.
*/
/* Serial port */
#define BDR_9600 (0)
#define BDR_38400 (1)