|
|
|||||||
| Home | Register | Downloads | FAQ | Members List | Calendar | Arcade | Mark Forums Read |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#21 |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
I only just noticed this, but aren't some of these op codes a problem? Code:
B0 0X 0N 00 SHL RX, N Logical Shift value in register X left N times. Affects [z,n] B1 0X 0N 00 SHR RX, N Logical Shift value in register X right N times. Affects [z,n] B0 0X 0N 00 SAL RX, N Arithmetic Shift value in register X left N times. Affects [z,n] (same as SHL) B2 0X 0N 00 SAR RX, N Arithmetic Shift value in register X right N times. Affects [z,n] B3 YX 00 00 SHL RX, RY Logical Shift value in register X left by the value in (RY & 0xf). Affects [z,n] B4 YX 00 00 SHR RX, RY Logical Shift value in register X right by the value in (RY & 0xf). Affects [z,n] B3 YX 00 00 SAL RX, RY Arithmetic Shift value in register X left by the value in (RY & 0xf). Affects [z,n] (same as SHL) B5 YX 00 00 SAR RX, RY Arithmetic Shift value in register X right by the value in (RY & 0xf). Affects [z,n] Code:
B0 0X 0N 00 SHL RX, N Logical Shift value in register X left N times. Affects [z,n] B0 0X 0N 00 SAL RX, N Arithmetic Shift value in register X left N times. Affects [z,n] (same as SHL) Code:
B3 YX 00 00 SHL RX, RY Logical Shift value in register X left by the value in (RY & 0xf). Affects [z,n] B3 YX 00 00 SAL RX, RY Arithmetic Shift value in register X left by the value in (RY & 0xf). Affects [z,n] (same as SHL) |
|
|
|
| Advertisement | [Remove Advertisement] |
|
|
|
|
|
#22 | |
|
Sober coder
![]() ![]() ![]() Join Date: Aug 2010
Location: London, UK
Posts: 434
|
Quote:
In fact, they are just equivalent operations, and the mnemonics translate to the same opcodes. The reason for this is that right-shifting can extend the sign bit (SAR) or not (SHR); however left-shifting can not extend the sign bit, SAL and SHL are there for consistency in the instruction set. (In the same way some condition codes in the Sign Flag have multiple aliases) Chris2Balls: Keep us posted!
__________________
|
|
|
|
|
|
|
#23 |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
Ok, thanks for the info tykel ![]() In my mind, I was expecting them to do different things... |
|
|
|
|
|
#24 |
|
Registered User
Join Date: Feb 2007
Posts: 3
|
Hi, I wanted to point out an issue with the RND instruction emulated in C or C++ with the rand() function. The problem appears in cottonvibes's emulator playing starfield and probably in other emulators written in C. This seems to come from the rand() function which generate random integers between 0 and RAND_MAX (which is generally 32767) and starfield asks for full 16-bits range. That results in a no fullscreen starfield. Moreover, if you do : Code:
R[x] = rand()%(HHLL + 1) Doing Code:
R[x] = rand()&(HHLL + 1) As a beginner maybe i'm mistaking though. Last edited by Celestion; November 9th, 2011 at 20:46.. |
|
|
|
|
|
#25 |
|
PCSX2 Coder
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jan 2004
Location: Plymouth, UK
Posts: 10,037
|
Maze is best to show this, I did something like V =(rand()%HHLL+1)-1 If you don't do the minus 1 it can go out of range requested Update: This is what i do exactly randval = rand() % ((unsigned short)IMMEDIATE+1); //Apparently if IMMEDIATE is 1, it always generates 0 O_o //Need to make sure result isnt 0 and is in range. if(randval > IMMEDIATE) randval -= 1; REG_X = randval;
__________________
http://www.pcsx2.net Intel i7 920 @ 3.4Ghz, POV GTX 570 1.3Gb, 1.8Tb HD space, 6Gb OCZ Reaper PC3-14400 Triple Channel Dont PM me for help, use the forums, thats what its for! My Chip16 Emulator RefChip16 http://code.google.com/p/refchip16/
Last edited by refraction; November 10th, 2011 at 12:58.. |
|
|
|
|
|
#26 |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
Hey all, I am thinking of trying to make my own emulator, and I am unsure as how to do 'correct' timing in the CPU. The spec says that the CPU is 1MHz, which is 1uS per CPU update. First, this seems much quicker than I might get a software timer to give me a time between updates, so I am unsure how I am going to get an 'accurate' count (ignoring Windows not being a true multi-tasking OS). Is QueryPerformanceCounter going to have enough resolution for this? GetTickCount only supplies around 1mS of resolution... If I can get ok timing, then I see I can do the CPU updates one of two ways: 1) Decode and execute one instruction per CPU tick, and keep track of when to do the next instruction update (global time variable) 2) Decode and execute N instructions per update, and then wait the remainder of the time left in a N * 1uS update chunk before doing the next bunch of updates. Any ideas? Am I being too worried about this part of the machine? ![]() cheers, Paul Last edited by paul_nicholls; November 10th, 2011 at 05:12.. |
|
|
|
|
|
#27 | |
|
You're already dead...
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Sep 2007
Location: Planet Vegeta
Posts: 5,387
|
Quote:
something we might need though are sound interrupts or an APU state register. cuz if you're playing a note, how does the game know that its done in order to play another note? it needs to be able to detect when the note is finished so it can play the next note.
__________________
"It was, of course, a lie what you read about my religious convictions, a lie which is being systematically repeated. I do not believe in a personal God and I have never denied this but have expressed it clearly. If something is in me which can be called religious then it is the unbounded admiration for the structure of the world so far as our science can reveal it." - Albert Einstein check out my blog ![]() |
|
|
|
|
|
|
#28 | |
|
You're already dead...
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Sep 2007
Location: Planet Vegeta
Posts: 5,387
|
Quote:
no-emulator times each instruction individually, they do N instruction chunks, then limit the frame rate by waiting/sleeping for the remainder of the time if it finished early. N = instructions per frame (which is 1,000,000 / 60 since chip16 has a frame-rate of 60fps).
__________________
"It was, of course, a lie what you read about my religious convictions, a lie which is being systematically repeated. I do not believe in a personal God and I have never denied this but have expressed it clearly. If something is in me which can be called religious then it is the unbounded admiration for the structure of the world so far as our science can reveal it." - Albert Einstein check out my blog ![]() |
|
|
|
|
|
|
#29 | |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
Quote:
![]() Hmm..having sound ports (memory mapped) is a very good idea! We could do something similar to the c64, but without filtering and all the other baggage; ie. only worry about the simpler parts like ADSR, volume, and wave types. With detecting the end of a note, perhaps we could have a bit (per voice) that is cleared (or set) when a voice finished playing...similar to the vblank? PS .I am actually just about to try creating programming a class to create some C64-like sounds using similar techniques to the SID (phase-accumulating oscillator + envelope generator). If I can get some ok results, I will share the code. cheers, Paul |
|
|
|
|
|
|
#30 | |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
Quote:
![]() cheers, Paul |
|
|
|
|
|
|
#31 | |
|
Sober coder
![]() ![]() ![]() Join Date: Aug 2010
Location: London, UK
Posts: 434
|
Quote:
So maybe, in line with this, have instructions similar in function to BGC and SPR, for sound properties (see paul_nicholls' post) -- and one or two SND opcodes for playing the sound. I like the idea of sound interrupts! ![]() Two possible issues: won't this make interrupts for other things (drawing, user-defined) desirable aswell? And how much does it complicate the implementation? And since you talk of ports... An idea I have been toying around with is defining some read-write general purpose memory ports (say 0xFFF4 - 0xFFFF) which would be updated every VBLNK; so the value in the ports would be sent out, and a new value would replace it from input, for example. Or otherwise have a set of read-only, and a set write-only. One of the ports could be PFLAGS (port flags), which masks whether the ports have been written to or not. This could be used by the system to only send different values. These serial ports could be used for netplay, or interacting with the outside. Just an idea, anyway ![]() And I added you to the contributors' list, paul_nicholls.
__________________
|
|
|
|
|
|
|
#32 | |
|
PCSX2 Coder
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jan 2004
Location: Plymouth, UK
Posts: 10,037
|
Quote:
Every cycle i add 1 to "cycles" variable, but i also have another variable called "nextvsync" and every time cycles == nextvsync i add (1000000 / 60) on to nextvsync. It seems to work ok :P Then to stop it going to fast, im actually using Direct3D, so i have told it to enable vertical syncing. This would be ok on most systems as many use 60hz for their screen these days, but of course once you get someone whos got a 120hz monitor, id be screwed xD so in the end ill probably have to resort to QueryPerformanceCounter()
__________________
http://www.pcsx2.net Intel i7 920 @ 3.4Ghz, POV GTX 570 1.3Gb, 1.8Tb HD space, 6Gb OCZ Reaper PC3-14400 Triple Channel Dont PM me for help, use the forums, thats what its for! My Chip16 Emulator RefChip16 http://code.google.com/p/refchip16/
|
|
|
|
|
|
|
#33 |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
|
|
|
|
|
|
#34 | |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
Quote:
![]() hmm...thinking about it, I might try something like this: Code:
const
render_fps = 60;
cpu_update = 1e-6;
render_ticks = (1/render_fps) / cpu_update;
procedure TChip16.DoUpdateStep;
begin
// read and process op-code
UpdateCPU();
// see if time to do a render update
// sets VSYNC bit to true when done.
FRenderTick := FRenderTick + 1;
if FRenderTick >= render_ticks then
begin
FRenderTick := FRenderTick - render_ticks;
RenderFrame();
end;
end;
procedure TChip16.Update(aFrameTime: Single);
begin
FUpdateTime := FUpdateTime + aFrameTime;
// do as many updates as possible
while FUpdateTime >= cpu_update do
begin
DoUpdateStep();
FUpdateTime := FUpdateTime - cpu_update;
end;
end;
I will have to try it ![]() cheers, Paul Last edited by paul_nicholls; November 10th, 2011 at 11:36.. |
|
|
|
|
|
|
#35 |
|
Sober coder
![]() ![]() ![]() Join Date: Aug 2010
Location: London, UK
Posts: 434
|
I've made a simple example rom with source for people to learn from and build upon. c16-textdisp.png Press A to print text, it will print on a new line every time, and go to a new screen when it reaches the bottom. I have included the latest tchip16 if you haven't got it, it has some nice new features! Also, can anyone guess what classic computer the font is taken from?
__________________
Last edited by tykel; November 13th, 2011 at 15:40.. |
|
|
|
|
|
#36 |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
Not sure on the font, I am sure it isn't from the C64...maybe a BBC micro?
|
|
|
|
|
|
#37 | |
|
Sober coder
![]() ![]() ![]() Join Date: Aug 2010
Location: London, UK
Posts: 434
|
Spot on EDIT: Quote:
It could also be used for in-game palette swapping, to save on the amount of graphics required! So, I will be adding the following opcode in the next spec revision, unless there are any reservations: Code:
0F 00 LL HH PAL HHLL Loads the palette from memory at address HHLL. Colors are stored as 3 byte RGB triples. So no cheating like on the C64/VIC ![]() And let's get a consensus on the sound! I think we agree on the format of the new SND instruction: Code:
0D 0X LL HH SNP HHLL Play PCM Sound for HHLL miliseconds at the tone specified in address pointed to by Register X We need to define the other instructions, the modifiers.
__________________
Last edited by tykel; November 14th, 2011 at 10:34.. |
|
|
|
|
|
|
#38 |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
I would imagine that the PCB should be 8-Bit (Signed?)...4-Bit would be waaayy too yuck ![]() As to the sound modifiers, how about something like this (memory-mapped like the C64)? Code:
0x0000 - Start of ROM.
0xFDED - Sound Control Register *
0xFDEE - Sound Attack/Decay Register *
0xFDEF - Sound Sustain/Release Register *
0xFDF0 - Start of stack (512 bytes).
0xFFF0 - IO ports.
* = see details below
Control Register Bits
---------------------
D7 D6 D5 D4 D3 D2 D1 D0 W = 2 bit waveform
x x x x x x W W 0x00 = triangle
0x01 = sawtooth
0x02 = square
0x03 = noise
Attack/Decay Register Bits
--------------------------
D7 D6 D5 D4 D3 D2 D1 D0 A = attack nibble (0-15, time value)
A A A A D D D D D = decay nibble (0..15, time value)
Sustain/Release Register Bits
-----------------------------
D7 D6 D5 D4 D3 D2 D1 D0 S = sustain nibble (0..15, volume)
S S S S R R R R R = release nibble (0..15, time value)
ADSR Envelope Values
VALUE ATTACK RATE DECAY RATE RELEASE RATE
0 2 ms 6 ms 6 ms
1 8 ms 24 ms 24 ms
2 16 ms 48 ms 48 ms
3 24 ms 72 ms 72 ms
4 38 ms 114 ms 114 ms
5 56 ms 168 ms 168 ms
6 68 ms 204 ms 204 ms
7 80 ms 240 ms 240 ms
8 100 ms .3 sec .3 sec
9 .25 sec .75 sec .75 sec
10 .5 sec 1.5 sec 1.5 sec
11 .8 sec 2.4 sec 2.4 sec
12 1 sec 3 sec 3 sec
13 3 sec 9 sec 9 sec
14 5 sec 15 sec 15 sec
15 8 sec 24 sec 24 sec
cheers, Paul Last edited by paul_nicholls; November 15th, 2011 at 20:14.. |
|
|
|
|
|
#39 | |
|
Registered User
![]() Join Date: Sep 2011
Location: Australia
Posts: 89
|
Quote:
Here's how my frame timer class looks like: Code:
FrameTimer::FrameTimer() {
TIMECAPS timeCaps;
//Find out the maximum resolution possible in the hardware
if (timeGetDevCaps(&timeCaps, sizeof(timeCaps)) == MMSYSERR_NOERROR)
maxResolution = timeCaps.wPeriodMin;
else
maxResolution = 1; //Just trying our luck with 1
timeBeginPeriod(maxResolution);
previousTime = timeGetTime();
}
FrameTimer::~FrameTimer() { timeEndPeriod(maxResolution); }
//Returns true if difference between previous time and current time is more or equal to 16 milliseconds
bool FrameTimer::renderTime() {
currentTime = timeGetTime();
if (currentTime - previousTime >= 16 || currentTime < previousTime) {
previousTime = currentTime;
return true;
}
return false;
}
|
|
|
|
|
|
|
#40 |
|
Registered User
![]() ![]() Join Date: Sep 2011
Location: Australia, Tasmania
Posts: 180
|
Thanks for the info Prads ![]() Oh, and your website looks interesting...some cool projects there ![]() cheers, Paul |
|
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|