Closed JulienNevo closed 2 years ago
Current behavior:
#include "z80.hpp"
int main()
{
unsigned char rom[256] = {
0x01, 0x34, 0x12, // LD BC, $1234
0x3E, 0x01, // LD A, $01
0xED, 0x79, // OUT (C), A
0xc3, 0x07, 0x00, // JMP $0007
};
Z80 z80([&rom](void* arg, unsigned short addr) {
return rom[addr & 0xFF];
}, [](void* arg, unsigned char addr, unsigned char value) {
// nothing to do
}, [](void* arg, unsigned char port) {
return 0x00;
}, [](void* arg, unsigned char port, unsigned char value) {
printf("OUT port $%02X%02X <- $%02X\n",
((Z80*)arg)->reg.pair.B, // the top half (A8 through A15) of the address bus (reg.B)
port, // the bottom half (A0 through A7) of the address bus to select the I/O device at one of 256 possible ports
value
);
}, &z80);
z80.setDebugMessage([](void* arg, const char* msg) { puts(msg); });
z80.execute(50);
return 0;
}
↓
[0000] LD BC<$0000>, $1234
[0003] LD A<$FF>, $01
[0005] OUT (C<$34>), A<$01>
OUT port $1234 <- $01
[0007] JP $0007
[0007] JP $0007
[0007] JP $0007
Are you saying that this is how you would like it to be?
#include "z80.hpp"
int main()
{
unsigned char rom[256] = {
0x01, 0x34, 0x12, // LD BC, $1234
0x3E, 0x01, // LD A, $01
0xED, 0x79, // OUT (C), A
0xc3, 0x07, 0x00, // JMP $0007
};
Z80 z80([&rom](void* arg, unsigned short addr) {
return rom[addr & 0xFF];
}, [](void* arg, unsigned char addr, unsigned char value) {
// nothing to do
}, [](void* arg, unsigned short port) { // port: uchar -> ushort
return 0x00;
}, [](void* arg, unsigned short port, unsigned char value) { // port: uchar -> ushort
printf("OUT port $%04X <- $%02X\n",
port, // the full (A0 through A15) of the address bus to select the I/O device at one of 65536 possible ports
value
);
}, &z80);
z80.setDebugMessage([](void* arg, const char* msg) { puts(msg); });
z80.execute(50);
return 0;
}
Yes indeed!
Okay, I'll consider it.
Basically, on Amstrad CPC, targeting the sound chip is done this way:
ld bc,#f400+port
out (c),c
ld bc,#f680
out (c),c
ld bc,#f600
out (c),c
ld bc,#f400+value
out (c),c
ld bc,#f6c0
out (c),c
ld bc,#f600
out (c),c
I need to know the 16 bits port that is addressed, else I cannot interpret the port/value correctly. The same is needed for other machines such as Spectrum, MSX, and their various interfaces.
Currently addressing at the Pull Request https://github.com/suzukiplan/z80/pull/43
Ideally, I wanted to overload the callback, but the C++ language specification does not allow it, so I am trying to use a setter as follows:
Z80 z80(readByte, writeByte, &mmu);
z80.setPort16Callback([](void* arg, unsigned short port) {
// port: the full (A0 through A15) of the address bus to select the I/O device at one of 65536 possible ports
}, [](void* arg, unsigned short port, unsigned char value) {
// port: the full (A0 through A15) of the address bus to select the I/O device at one of 65536 possible ports
});
document: https://github.com/suzukiplan/z80/pull/43/commits/e74602901a7256f64b49a1e45626db1157517962
I'm a bit torn as to which one (8bit/16bit) should correspond to the specify in/out callbacks with the constructor...
I have written product code for several Z80 CPU-based emulators (SG-1000, SMS, GameGear, PC-8801 and MSX1) in the past, but have never encountered an example with more than 256 ports, so I am considering using 8-bit callbacks as the default as before.
When using the "out" callback of the MMU on the Z80 initialization, only the Less Significant Byte of the port is sent, so if using:
only "#34" is set in the port callback. It should be a 16 bits value.