Omnimaga
Calculator Community => TI Calculators => ASM => Topic started by: Hot_Dog on March 13, 2012, 07:21:30 pm
-
If too many opcodes are put into a processor, it becomes expensive. But sometimes there are commands that we Z80 programmers use so often, we wonder why they don't exist in the Z80 hardware by default...we wonder why we have to code the routines ourselves.
What are some that you wish the Z80 had? Keep it simple--if time changes and the z80 becomes what we want it to be, we don't want it to be expensive ;D
For me: add hl, a sub hl, a cp hl, reg16
-
eZ80 has pretty much everything I'd want. LD HL,(HL) ftw
-
mul reg16
EDIT: I don't think this is too high-end/expensive for Zilog to have added, I'm pretty sure the eZ80 had it.
-
Sure would be darn expensive in the 1980s :P
-
How about add hl,(**)? I would use that in cases where, say, HL is the offset into a buffer and the location of the buffer is at **. Or an instruction I just invented off the top of my head:
asjnc *
It performs add a,c \ sub b and does a relative jump if it did not go below zero. That might be useful, especially for line drawing and circle drawing and whatnot. I think it would be 16 cycles using the current processor.
-
It would be nice if there were IX' and IY'.
LD (REG 16),REG 16 and LD (REG 16),REG 16 would be extremely useful as well.
I wonder how the computer world would be if Zilog made the eZ80 immediately after the z80. Nobody would have to deal with the 8086's yucky segment registers. The world would be a better place. :P
-
It would be nice if there were IX' and IY'.
LD (REG 16),REG 16 and LD (REG 16),REG 16 would be extremely useful as well.
Lol, those are the same.
-
Sure would be darn expensive in the 1980s :P
I bet TI today would use the z80 power as excuse to the $100-130 price tags on their 83+ <_<
-
It would be nice if there were IX' and IY'.
LD (REG 16),REG 16 and LD (REG 16),REG 16 would be extremely useful as well.
Lol, those are the same.
Yeah, I meant LD (Reg 16),Reg 16 and LD Reg 16,(Reg 16). :P
-
eZ80 has pretty much everything I'd want. LD HL,(HL) ftw
A little bump, but ld hl,(hl) would have been great.
-
eZ80 has pretty much everything I'd want. LD HL,(HL) ftw
A little bump, but ld hl,(hl) would have been great.
Oh, ho, ho, let's not forget bcall(_ldHlInd). At three bytes, it's only one byte bigger than ld hl,(hl) would be :D
-
...and just as quick ;)
-
eZ80 has pretty much everything I'd want. LD HL,(HL) ftw
A little bump, but ld hl,(hl) would have been great.
Oh, ho, ho, let's not forget bcall(_ldHlInd). At three bytes, it's only one byte bigger than ld hl,(hl) would be :D
But does it blend?
-
I was looking through some old code of mine today and found "getHL()" all over the place. Btw, what is the ez80? It sounds pretty cool, what devices use it? :D
-
No idea what devices use it, but it's essentially an updated Z80 that has (at least some,not sure how much) backwards compatibility. It was being discussed here because there were a couple of hobbyist projects going on attempting to build a "dream" graphing calculator. That was one of the chips being discussed, and largely for backwards compatibility with TI's stuff IIRC. Ease of transition was also a plus, as many current Z80 programmers would be (largely) familiar with it due to the similarities.
-
Bump. Today i was thinking once again how i wish there were an easy way to transfer registers to their shadow counterparts, like a version of exx that instead of swapping registers copied them. So you could do something like this:
exx' ;copy hl, bc, and de to hl', bc', and de'
;mess up hl, bc, and de
exx ;restore original register values (shadows contain the "messed up" values)
-
has anyone mentioned div or sqrt?
-
@chickendude: I have thought about that, too o.o What if there was a way to refer to a specific shadow register, even if it were an extended instruction. This way you could do something like ex hl',hl or copy hl,hl'.
@tr1p1ea: If there was such a command, it would detract from the fun of creating a multiplication or division routine :P
-
Not to mention fastinvsqrt!
A project I've been thinking about actually addresses this kind of issue: Imagine a processor where all the undocumented instructions are just small FPGA logic grids. You can make them do pretty much anything, as long as it's not too long or insane. (Ie put reg A in reg B while writing reg A to a memory location)
-
@chickendude: I have thought about that, too o.o What if there was a way to refer to a specific shadow register, even if it were an extended instruction. This way you could do something like ex hl',hl or copy hl,hl'.
@tr1p1ea: If there was such a command, it would detract from the fun of creating a multiplication or division routine :P
Fun she says... :P
Multiplication and division would have been nice tbh. :D
-
TBH, we should just move on to another, more modern architecture that has all of these features. Once you know how to structure a program in ASM for one architecture, writing it for a different architecture isn't that hard.
-
TBH, we should just move on to another, more modern architecture that has all of these features. Once you know how to structure a program in ASM for one architecture, writing it for a different architecture isn't that hard.
What's the fun in that? :P
-
Haha i do agree with Xeda and calc84 in that it wouldnt be as fun as figuring out how to beat limitations if these features were there :).
-
TBH, we should just move on to another, more modern architecture that has all of these features. Once you know how to structure a program in ASM for one architecture, writing it for a different architecture isn't that hard.
PIC, anyone? :D
-
How about an FPGA based environment? Get a high-quality chip, something with a few million logic cells (preferably with an open source development environment) and it's easy to make a soft processor plus all sorts of extra hardware that can be reconfigured in real time.
Imagine being able to build a logic structure that calculates your graph in parallel, or a 3D graphics accelerator that handles your rendering. FPGAs are cool.
-
FPGA's are awesome. In a robotics competition I'm competing in there is an FPGA onboard which I am learning to program
-
- ldmsr reg16 11101101 11[reg16]0000 put reg16 into the model specific register at the index specified by register A.
- stmsr reg16 11101101 11[reg16]1000 stores the contents of the msr indexed by A in reg16.
- cpuid 11101101 01110111 puts cpuid data indexed by register A in A, and sets the carry if A <= max cpuid index (otherwise leave the carry and A unchanged)
These encodings made sense to me, but maybe there are better ones.
As for the MSRs,
- 0 settings bits 1 - 15 are reserved and must be zero. bit 0 indicated whether the interrupt stack MSR is used.
- 1 interrupt stack if settings[0] is 1: when an interrupt occurs, SP is stored in user stack and SP is then loaded with interrupt stack before pushing PC.
- 2 user stack receives the value of SP when an interrupt occurs and settings[0] is 1.
If interrupt stack is used, RETI and RETN are changed to do their thing with the interrupt flip flops, pop the return address off the stack, then load userstack into SP, then jump to the return address.
This thing is meant for making interrupts not screw with the stack the running program was using, enabling some optimizations that previously required interrupts to be disabled to leave them running.
I'm pretty sure MSRs could be used to create a place for MMU settings to be, so an MMU can be included in the z80 proper (not having to go through ports), but I'm too lazy to think of a nice way to do it.
As for cpuid, it conditionally sets the carry so you can check whether it's supported like this:
xor a
cpuid
jnc _not_supported
And to make things easy, the cpuid data indexed by zero is max cpuid index, indicating the maximum value you can ask cpuid for.
If cpuid is not supported, it corresponds to an undocumented NOP, which won't set the carry.
There should probably be a bit in the cpuid data indicating support for MSRs. Say, bit 0 of cpuid[A = 1].
-
How could I have forgotten some of the obvious ones:
ex de, ix
ex de, iy
sbc ix, bc
sbc ix, de
sbc ix, ix
sbc ix, sp
adc ix, bc
adc ix, de
adc ix, ix
adc ix, sp
These are all the instructions that you've always assumed existed until you tried to use them. With both the EX's and the SBC's, I was so angry when I used them in my code only to find out that they don't exist.
And, if we want to be hopeful
ldix
ldiy
lddx
lddy
ldirx
ldiry
lddrx
lddry
These would be really cool, even if they did take 4 more t-states per iteration.
-
ld hl, sp
ld ix, sp
ld iy, sp
And an indexRegister+reg8 addressing mode.
But, you know, pipe-lining like the eZ80 has would be just as nice.
-
If too many opcodes are put into a processor, it becomes expensive. But sometimes there are commands that we Z80 programmers use so often, we wonder why they don't exist in the Z80 hardware by default...we wonder why we have to code the routines ourselves.
....
Well, it all depends on what time frame you're talking about.
Z80 was born around 1976 (just about 37 years old!). So, its no wonder that the price of the silicon chip area has changed a LOT since then. Actually, today it would be easily possible to produce a Z80 pin-compatible device with a much improved instruction set and probably much cheaper also. You would need to unsolder (unplug) the original grandpa and replace it with a much brighter grandchild. It can be a hobby or a hard/software student thesis for some of you. Just firing up into the stars... ;)
-
Well, depending on how much backwards compatibility require, you could technically say that the advancement in processor design IS that process.
Heck, there's even an improved CPU called the ez80. Backwards compatible mode, but also its own instruction set, and it goes up into 50 MHz.
-
And it is 4 times faster at the same frequency !
-
That's true too. Thanks to a faster opcode caller or something, right?
-
I don't know the in depth details, sorry. :s
-
I believe on the ez80 instructions all generally fit into one t-state, or rather due to the way the ez80 is set up it can pipeline/decode instructions in advance and execute them within one t-state. On the z80, each cycle takes 3-6 t-states and i assume it's basically the same on the ez80. For example:
xor a takes one machine cycle of 4 t-states.
add a,3 takes two machine cycles, the first is 4 t-states and the second is 3, altogether 7 t-states.
add hl,de takes three machine cycles, the first two are 4 t-states and the third is 3, altogether 11 t-states.
add ix,de takes four machine cycles, three cycles of 4 t-states and the last one is 3, altogether 15 t-states.
ld (ix+4),a takes 5 M cycles, 4 t-states for the IX prefix, 4 more to read the opcode, 3 t-states to read the offset, 5 to add the offset and read a, 3 t-states to write a to the address.
rl (ix) takes six M cycles, amounting to 23 t-states. I'm not sure what each each cycle amounts to, i think first you've got the IX prefix (4 t-states), then the opcode (4 t-states), then the offset (here, +0, 3 t-states), i don't know what the others might be.
So i think on the ez80, these M cycles will be prefetched/decoded while the previous instruction/cycle decodes/executes (each instruction must be fetched, decoded, then executed) so that they can be immediately executed when the previous instruction ends.
EDIT: Also, i was just thinking about how convenient add hl,imm16 would've been. It'd save you from having to destroy bc/de.
-
Yes, add, sub, adc, and sbc with hl for immediate values would have been nice o.o
-
I really like writing assembly for my hobby Z80 (actually, currently Z180) and have done that for a while; I have something like 40000 lines of ASM code in my system. And yes, I also have wondered what kind of added instructions would be most benficial, for ASM-coding and for compiler (another language I'm using is BASIC, and of course I have implemented a compiler for it).
So, here some of the instructions, which are appearing all the time in my existing code, or which I would consider usefull implemented as single byte opcodes (there are something like 7 to 11 single byte opcodes, which no-one or at least I am not using)
LD rr,(HL) where rr=BC, DE, HL
LD (HL),ss where ss=BC or DE
INC2 HL same as INC HL two times
DEC2 HL
These are appearing so often, that in my assembler I have created pseudo-opcodes like LD DE,(HL)++ or LD HL,(HL).
For the compiler I would like to have following two single byte opcodes:
LD DE,(nn) where nn is 16 bit memory address
LD HL,SP+s i.e. HL gets the sum of SP and an 8-bit signed constanst; usefull not only for allocating/deallocating space from stack, but also building a reference to a variable in stack.
And what Z80 is really missing, is couple of indexing registers besides the IX and IY; so I would allocate two of the available single byte opcodes to prefixes for handling these new registers.
Another area where Z80 is lacking, is 16-bit operations. I really would like to have instructions like LD DE,(IX+n) implemented with just 3 bytes, instead of the current 6 bytes (I have also these pseudo-opcodes in my assembler, however, the saving in memory usage would really be wellcome). And yeah, there are a few other opcodes, which would be rather useful...
-
I never even realized that loading 16 bit addresses into bc/de took up 4 bytes instead of 3! And i think we've all wished for a ld rr,(hl) instruction.
As for the index registers, they are just so big and slow, sometimes they're nice just 'cuz it makes your code so much more organized (or you've just run out of registers), but generally i try to stay away from them. One nice side effect of that is that i can easily keep a value in ix (or iy) without worrying about it getting changed, since i almost never use it.
-
Hey Pekka, welcome to Omnimaga! You should head over and <a href=http://www.omnimaga.org/index.php?board=10.0>introduce yourself</a>.
-
I am in need of a subdr instruction right now :P That would let me subtract a big endian number from another.
Also, subir, addir, adddr would be nice. In fact, a bunch of instructions with increment/repeat or decrement/repeat would be nice. You could OR two buffers with:
ld hl,gbuf
ld de,backbuf
ld bc,768
orir
Or shift a buffer right:
ld b,0
ld d,64
ld hl,gbuf
ld c,12 \ srlir \ dec d \ jr nz,$-5
-
Well, there's always the ability to treat any part of RAM like an accumulator register. That's very handy in the ez8.