English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 14 May 2024, 07:58   #21
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,339
subx is handling X not C. If you have carry from ror or cmp, subx isn't going to register it. scs is more appropriate.
jotd is offline  
Old 14 May 2024, 08:11   #22
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,024
Right, can be 2 versions subx.w and scs.
subx.w is perhaps fastest.
for scs also ext.w is perhaps necessary.
Don_Adan is offline  
Old 14 May 2024, 08:15   #23
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,339
subx is useless as it won't catch all occurrences of carry.

add/sub/asr/asl/rox => set X and C
cmp/rol/lsr => set C only

6502 carry is also a nightmare when handling with 68000. It's inverted for comparisons, and also when SBC it's not a carry it's a "borrow", so also inverted.
jotd is offline  
Old 14 May 2024, 08:53   #24
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,024
I dont think that subx.w is useless.
This is emulation, every emulated command can used different handling of Carry.
2 versions of fast enough handling C is for me ok.
Of course, I dont know 6502 instructions.
But if 6502 has something like rorx.b #1 or rolx.b #1 or similar commands.
Then word value as C/X is better than byte value for handling similar instructions.
You can use f.e
Code:
 move.b D0,D6
 ror.w #1,D6
 move.b D6,D0
Don_Adan is offline  
Old 14 May 2024, 09:10   #25
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,350
Quote:
Originally Posted by jotd View Post
add/sub/asr/asl/rox => set X and C
cmp/rol/lsr => set C only
LSR does set X too.

SUBX can be useful for emulating ADC.
For SBC/CMP, you can use SCC rather than SCS.
meynaf is offline  
Old 14 May 2024, 09:57   #26
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,339
yes, LSR sets X, my bad.

ADDX can efficiently emulate ADC.

But SUBX and SBC don't work the same, you have to invert X flag (borrow, not carry). Those 8 bit processors don't have X and also don't have flag set on LDA (move), and they use that a lot.

example on Z80:

Code:
   CP B
   LD  C,A
   BNE xxx
the condition code is the one set by CP (CMP) not LD (which doesn't set cc).

another example (Z80)

Code:
   CP  B
   RR  C
The result of cp (cmp) can set carry, which is used by RR (like ROXR). On 68000 it doesn't work unless you convert C flag into X flag, as cmp doesn't set X flag.
jotd is offline  
Old 14 May 2024, 10:40   #27
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,024
Of course I dont know 8 bit commands.
But if You want JOTD open new thread, with proposition of fast emulation of 8bit instructions.
For me Carry bit for most 8 bit commands can be handled very fast with subx.w command.
f.e for left shift (8 bit commands):

Code:
 add.b D0,D0
 subx.w D6,D6 ; set carry bit
for left shift with carry


Code:
 add.b D6,D6 ; use carry bit (can be add.w too)
 addx.b D0,D0
 subx.w D6,D6 ; set carry bit
Don_Adan is offline  
Old 14 May 2024, 11:15   #28
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,350
Quote:
Originally Posted by jotd View Post
But SUBX and SBC don't work the same, you have to invert X flag (borrow, not carry).
This may look weird but it is a consequence of how subtraction is done in hardware (with an adder and 1's complement on value to sub).
68k designers valued programmability more than transistor count enough to do that inversion in HW.


Quote:
Originally Posted by jotd View Post
Those 8 bit processors don't have X and also don't have flag set on LDA (move), and they use that a lot.
I don't know z80 enough, but 6502 does set flags on LDA (not C, but NZ).


Quote:
Originally Posted by jotd View Post
The result of cp (cmp) can set carry, which is used by RR (like ROXR). On 68000 it doesn't work unless you convert C flag into X flag, as cmp doesn't set X flag.
The way to handle that depends if you want to perform code conversion or simple emulation.
If you convert code you can use extra register and use SUB rather than CMP, then follow with EORI to CCR to revert the carry.
If you emulate, SCC will give you the carry and then you have to reload and revert it again prior to the SUBX.
meynaf is offline  
Old 14 May 2024, 11:33   #29
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,024
After some rethinking time it must be add.w, not add.b.
Because D6.b can be always used as temp.
Using add.b is wasting this possibility.

for left shift with carry


Code:
 add.w D6,D6 ; use carry bit
 addx.b D0,D0
 subx.w D6,D6 ; set carry bit
Don_Adan is offline  
Old 14 May 2024, 14:09   #30
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,024
Perhaps for handling CCR bits similar code can be used:

Code:
 lea ReturnFull(PC),A6
 sub.l D0,D0
ReturnFull
 subx.w D6,D6  ; set X bit as word
 tst.b D0
 sxx D7
 ext.w D7 ; set N bit as word
 tst.b D0
 sxx D7 ; set Z bit as byte
 move.b (A0)+,D0
 jmp Emu00(PC,D0.L*8)

Emu00
....
Don_Adan is offline  
Old 14 May 2024, 16:10   #31
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,339
Smart, very good use of Sxx. BTW carry is left out of this code. Required for CMP for instance. But maybe flag tests are specific per-instruction?
jotd is offline  
Old 14 May 2024, 17:39   #32
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,024
Of course this is only idea.
Everything can be changed or adapted to be better/faster.
F.e tst.w D7 can check 2 bits (if zero), N and Z.
Dependent which value N and Z is the common too test, then different sxx can be used.
N=1 not must be $FF, can be for emulatiion also set as $00.
Of course also place of flags can be changed.
When I tried to optimize dos.library, I used one data register for fast checking of 3 flags.
And it was very fast, much fastest than original dos.library which using stack for flags via link.w command.

Same here, now D6 is free, but maybe better can be handling 3 CCR bits in 2 registers. I dont know. I dont see emulation code for 6502.

Code:
 lea ReturnFull(PC),A6
 sub.l D0,D0
ReturnFull
 sxx D7
 extb.l  D7 ; set C bit as longword
 tst.b D0
 sxx D7
 ext.w D7 ; set N bit as word
 tst.b D0
 sxx D7 ; set Z bit as byte
 move.b (A0)+,D0
 jmp Emu00(PC,D0.L*8)

Emu00
....
Don_Adan is offline  
Old 14 May 2024, 19:41   #33
NorthWay
Registered User
 
Join Date: May 2013
Location: Grimstad / Norway
Posts: 851
Quote:
Originally Posted by oRBIT View Post
I'm sorry I'm not familiar with Xformer..?
Since the NZC flags can be affected by both LDA/LDX/LDY I can't use A-register only.
Xformer was originally an Atari800 emulator that I hacked a lot on to make AXF-64.


As for X and Y I treat them the same way as A, I just copy the updated register to my "NZ" register. Yes, it would be nice to have more registers for once...
NorthWay is offline  
Old 14 May 2024, 21:07   #34
oRBIT
Zone Friend
 
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 344
Quote:
Originally Posted by NorthWay View Post
Xformer was originally an Atari800 emulator that I hacked a lot on to make AXF-64.


As for X and Y I treat them the same way as A, I just copy the updated register to my "NZ" register. Yes, it would be nice to have more registers for once...
Ah of course.. Can you explain more about how you worked with the Carry-bit?
oRBIT is offline  
Old 15 May 2024, 01:00   #35
NorthWay
Registered User
 
Join Date: May 2013
Location: Grimstad / Norway
Posts: 851
Quote:
Originally Posted by meynaf View Post
What do you do if someone does PLP with a value having Z=1 and N=1 ?
Good question, because that is not so pretty. I can't remember, but I did find the source (who on earth stores it in the emulators partition and not the source one? What a dolt!)
I can't remember if I ever did anything but make it functional. Might even be bugged:
Code:
	move.b	(reg_P,arDATA),drZP_EA
	smi	drNZ
	extb.l	drNZ	; set N		NNNN

	add.b	drZP_EA,drZP_EA				; N V_BDIZC0
	smi	drVC	; set V
	extb.l	drVC		;	VVVV

	lsl.b	#3,drZP_EA				; B DIZC0000

	smi	drEA		; set D
	ext.w	drEA		;
	move.b	drA,drEA
	move.w	drEA,drA

	lsl.b	#2,drZP_EA				; I ZC000000
	scs	(reg_I,arDATA)	; set I

	spl	drNZ		; set Z	 NNNZ
	add.b	drZP_EA,drZP_EA				; Z C0000000
	smi	drVC		; set C	 VVVC
That is probably some of the least pretty parts of the whole thing. Somewhat contortionist(sp?).

This is the register use:
Code:
drJUMP	equr	d0		; use same to dispatch
drZP_EA	equr	d0		; 64k aligned $xxxx00xx, .b is 'scratch'
drSP	equr	d1
drEA	equr	d2		; 64k aligned, .w is 'scratch'
drVC	equr	d3		; .w overflow(15), carry(7-0)
drNZ	equr	d4		; negative(15-8), zero(7-0)
drA	equr	d5		; only low word used	$00xx.w
drD	equr	drA		; .w decimal
drX	equr	d6		; only low word used	$00xx.w
drY	equr	d7		; only low word used	$00xx.w

arDATA	equr	a6		; pointer to base of variables
arPC	equr	a5		; 64k aligned program counter
arJUMP	equr	a4
arWSTAT	equr	a3		; pointer to array of write status bytes
ar68CODE	equr	a2	; 256 functions max 112 bytes big
arEA	equr	a1
hwREG	equr	a1
arTMP	equr	a0
This was originally done for 68000 but I bumped it to 020+ for opcodes and address modes. I'm not sure if the emulated register handling is a win or loss for faster machines.
NorthWay is offline  
Old 15 May 2024, 01:29   #36
NorthWay
Registered User
 
Join Date: May 2013
Location: Grimstad / Norway
Posts: 851
Quote:
Originally Posted by oRBIT View Post
Ah of course.. Can you explain more about how you worked with the Carry-bit?
Hm. My memory lied to us. It was not as easy as I said (see other post with register layout).

This is BCC/CPY/ADC for example:
Code:
; BCC
	op_start
op90_BCC
	CARRYTEST
	bmi.b	.nobcc

	DoBranch

.nobcc
	jump2	2

; CPY abs
	op_start
opCC
	EA_abs
	move.b	drY,drNZ
	ReadCheckF
	sub.b	drZP_EA,drNZ
	scc	drVC
	SETN
	jump3	4

; ADC zp
	op_start
op65
	EA_zp
	movea.l	drZP_EA,arEA
	ReadCheckZP
	move.b	(arEA),drZP_EA
	add.b	drVC,drVC	; set X flag
	DTEST

	bmi.b	.opdec\@

	addx.b	drZP_EA,drA
	MOVENOPW
.opdec\@				; OTHER CODE
	abcd	drZP_EA,drA	; ADDX.B or ABCD drZP_EA,drA

	scs	drNZ
	svs	drVC
	extb.l	drVC
	move.b	drNZ,drVC
	SetAndJump	drA
	jump2	3
Ok, that was kinda cheating, but macros to the rescue eh?
Code:
CARRYTEST	macro
	tst.b	drVC
	endm

ZEROTEST	macro
	tst.b	drNZ
	endm

DTEST	macro
	tst.w	drD
	endm

NEGTEST	macro
	tst.w	drNZ
	endm

VTEST	macro
	tst.w	drVC
	endm

CLEARV	macro
	and.w	#$00ff,drVC
	endm

CLEARD	macro
	and.w	#$00ff,drD
	endm

CLEARCARRY	macro
	clr.b	drVC
	endm

CLEARN	macro
	and.w	#$00ff,drNZ
	endm

SETN	macro
	extb.l	drNZ
	endm

SETD	macro
	or.w	#$ff00,drD
	endm

SETV	macro
	or.w	#$ff00,drVC
	endm

SETCARRY	macro
	move.b	#$ff,drVC
;	st	drVC
	endm
I don't know if this gave you any ideas.
There is a lot to ponder when emulating - do you always read at least 2 bytes from memory for an opcode, do you do hw checks on all opcodes you read from memory, do you use post/pre-increment for memory access or do you make 100% sure that you can handle any wraparound, is there any memory banking going on, and if so do you use indirection tables for accessing the right memory stuff, and how do you handle things like write to ROM with RAM under? Many things are easier if it is not a C= 64 you model.
NorthWay is offline  
Old 15 May 2024, 08:34   #37
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,350
Quote:
Originally Posted by NorthWay View Post
Good question, because that is not so pretty. I can't remember, but I did find the source (who on earth stores it in the emulators partition and not the source one? What a dolt!)
I can't remember if I ever did anything but make it functional. Might even be bugged:
<snip>
Your register usage indicates d4 stores negative(15-8), zero(7-0).
Nothing to do with just storing A,X,Y value for later computation. Wasn't it an idea you had but later rejected, instead ? This is what happened to me.
Perhaps the code for LDA would help understanding the way you handled NZ flags at the end.
meynaf is offline  
Old 15 May 2024, 11:33   #38
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,024
Quote:
Originally Posted by jotd View Post
subx is handling X not C. If you have carry from ror or cmp, subx isn't going to register it. scs is more appropriate.
I thinked a few again.
And for me handling X bit is much easier than C bit.
Then i will add for some instructiions which dont handle X bit, extra code.
f.e for emulating ror it will be

Code:
 ror.b #1,d0
 move.b d0, d7 (temp)
 add.b d7,d7 ; set X bit
Don_Adan is offline  
Old 15 May 2024, 11:49   #39
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,350
You don't need to emulate ror on 6502.
As 6502's rol/ror are actually roxl/roxr with count=1...
meynaf is offline  
Old 15 May 2024, 13:09   #40
Karlos
Alien Bleed
 
Karlos's Avatar
 
Join Date: Aug 2022
Location: UK
Posts: 4,355
This thread is very interesting. Once, long ago, I wrote a z80 emulator for 68020 and I remember the whole threaded jump table approach and trying to make sure every handler was on the same power of 2 boundary etc. I also remember it being a massive pain in the backside, especially flags and interrupts.

I know next to nothing about 6502 by comparison, but ended up writing an emulation (for fun and a challenge) in php of all things.

What is being targeted as a host CPU here?
Karlos is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Converting 6502 to 680x0 (calling all 6502/680x0 experts) oRBIT Coders. General 12 14 January 2015 19:18
Visual 6502 in JavaScript Charlie Retrogaming General Discussion 1 03 October 2010 13:35
6502 Asm pmc Coders. General 21 06 November 2008 09:37

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 09:36.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10122 seconds with 15 queries