Simple x86 Code: Does This Look Good?

You can talk about almost anything that you want to on this board.

Moderator: Moderators

Post Reply
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Simple x86 Code: Does This Look Good?

Post by Drew Sebastino »

I had figured that I should make a simple demo of some kind because everyone else seems to be doing it and because I'm in a tough spot trying to make my game. I was going to do it on the SNES, but I don't feel like it, as I already have well beyond what I'm trying to do made. Anyway, this code is trying to make a ball bounce around like in 45 degree angles like pong, which I eventually want to turn this into. Nothing has been defined, and I don't have anything hooked up to any hardware registers, and I think you have a good understanding of what hardware I want this to run on... Vram is the biggest pain in the a** to me, and I thought I'd do it on something that doesn't use vram, so I don't have to upload any tiles or anything.

Here it is: (It isn't hooked up to a starting vector or anything, but that's easy to do. Also, this is meant for the 80186 if that is useful.)

Code: Select all

start:
  mov XDirection, 0x0001
  mov YDirection, 0x0001
  mov XPosition,  0x0000
  mov YPosition,  0x0000


x_movement__start:
  mov DX, #BallXVelocity

x_movement_loop:
  jz  y_movement_loop
  add XPosition, XDirection
  mov AX, #(ScreenWidth+BallDiameter)	;you write it like that, right?
  cmp XPosition, AX
  ja  x_out_of_bounds
  dec DX
  jmp x_movement_loop

x_out_of_bounds:
  xor XDirection, 0xFFFF
  add XPosition, XDirection
  dec DX
  jmp x_movement_loop


y_movement__start:
  mov DX, #BallYVelocity

y_movement_loop:
  jz  next_frame
  add YPosition, YDirection
  mov AX, #(ScreenHieght+BallDiameter)	;you write it like that, right?
  cmp YPosition, AX
  ja  y_out_of_bounds
  dec DX
  jmp y_movement_loop

y_out_of_bounds:
  xor YDirection, 0xFFFF
  add YPosition, YDirection
  dec DX
  jmp y_movement_loop


next_frame:
  int			;is this like wai?
  jmp x_movement__start
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Simple x86 Code: Does This Look Good?

Post by lidnariq »

Espozo wrote:

Code: Select all

  mov DX, #BallXVelocity
[...]
x_movement_loop:
  jz  y_movement_loop
[...]
  dec DX
  jmp x_movement_loop
Consider using LOOP; it operates on CX instead of DX, and it's faster (mostly because it's smaller) on the early x86 machines. (It's equivalent to dec cx / jnz somewhere. On 486 though pentium 3 machines it's slower than its equivalent, and I have absolutely no idea about anything made in the past decade. )

I'm not certain why you'd need to use # to specify some numeric constants and not other ones ... that seems weird to me.
Have you been testing it against an assembler? Not to see if it works, just to avoid syntax errors...
xor XDirection, 0xFFFF
Consider using NOT

Also, most of the time I've seen a more RISC-y data flow: load values into registers, do tests and bounds and changes, write back to registers, and not so much opc mem, imm

Forever ago (BBS era) I found this document: http://www.intel-assembler.it/portale/5 ... -guide.asp describing all the instructions up through the 486, which was invaluable when I was doing more x86 asm.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Simple x86 Code: Does This Look Good?

Post by Drew Sebastino »

lidnariq wrote:Consider using LOOP
lidnariq wrote:Consider using NOT
Grr... Too many instructions! :evil: (The complete opposite of MIPS...)
lidnariq wrote:Also, most of the time I've seen a more RISC-y data flow
I don't want to try anything too RISC-y yet because I'm not very good at x86 assembly right now.

Is this any better?

Code: Select all

start:
  mov XDirection, 0x0001
  mov YDirection, 0x0001
  mov XPosition,  0x0000
  mov YPosition,  0x0000


x_movement__start:
  mov CX, #BallXVelocity

x_movement_loop:
  add  XPosition, XDirection
  mov  AX, #(ScreenWidth+BallDiameter)	;you write it like that, right?
  cmp  XPosition, AX
  ja   x_out_of_bounds
  loop x_movement_loop
  jmp  y_movement_start

x_out_of_bounds:
  not  XDirection
  add  XPosition, XDirection
  loop x_movement_loop


y_movement__start:
  mov CX, #BallYVelocity

y_movement_loop:
  add  YPosition, YDirection
  mov  AX, #(ScreenHieght+BallDiameter)	;you write it like that, right?
  cmp  YPosition, AX
  ja   y_out_of_bounds
  loop x_movement_loop
  jmp  next_frame

y_out_of_bounds:
  not  YDirection
  add  YPosition, YDirection
  loop x_movement_loop

next_frame:
  int			;is this like wai?
  jmp x_movement__start
Anyway though, did you hear of the instruction GAME yet? You just write GAME and it does everything for you.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Simple x86 Code: Does This Look Good?

Post by tepples »

Espozo wrote:Anyway though, did you hear of the instruction GAME yet? You just write GAME and it does everything for you.
The 65C02 derivative in the TurboGrafx-16 is so cool it has SMB3 in one instruction. But then the 68000 has an instruction for making LINK, and the MVP instruction in the Super NES's 65816 might be good for baseball. Like Bad Piggies? ARM has SWINE. Perhaps the "adult" games for Atari 2600 sucked because you need the 6809 in a CoCo to have SEX. And with a 68000, you can TAS anything.

I've got dozens of 'em.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Simple x86 Code: Does This Look Good?

Post by lidnariq »

Espozo wrote:Is this any better?
Looks reasonable, if non-idiomatic. I'd probably move things around a little, more like:

Code: Select all

x_movement_loop:
  add  XPosition, XDirection
  mov  AX, #(ScreenWidth+BallDiameter)	;you write it like that, right?
  cmp  XPosition, AX
  ja   x_out_of_bounds
  loop x_movement_loop
; moving the error case out of the way allows us to fall through here rather than explicitly jumping

y_movement__start:
[...]

next_frame:
  int			;is this like wai?
  jmp x_movement__start

x_out_of_bounds:
  not  XDirection
  add  XPosition, XDirection
  loop x_movement_loop
Somehow I didn't notice the question about INT..

INT is approximately equivalent to BRK. (It's more useful, though, because it actually does something with its argument.)

HLT is closest to WAI, but ... for some reason I never saw it used.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Simple x86 Code: Does This Look Good?

Post by Drew Sebastino »

DAS: Decimal Adjust AL after Subtraction
DAS.png
DAS.png (43.91 KiB) Viewed 3255 times
Dun dun dunnn!
tepples wrote:SEX
:lol: (I'm really mature as you can tell.)

I'm surprised you didn't say anything about this:
I don't want to try anything too RISC-y yet because I'm not very good at x86 assembly right now.
Get it?
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Simple x86 Code: Does This Look Good?

Post by Drew Sebastino »

This is a dumb question, but the DMA controller isn't actually on the 65816, is it? I just wonder if the 80186 has any sort of thing, but I don't think the DMA controller is actually tied to the processor, considering you have to write to registers to get it working, like the multiplication/division units. Is the NEC V33 like a casing like the 5A22? Is there any alternative to DMA?
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Simple x86 Code: Does This Look Good?

Post by lidnariq »

It'd be best to look at the datasheet.... not that I can find one for the bare V33... Here's the V33A: http://www.datasheetarchive.com/U10032E-datasheet.html

In the original PC, the 8086 did not provide DMA, so they added an external 8237 IC to handle that.

Wikipedia claims that the V33 has some very nice features, but no DMA controller. It looks like NEC didn't integrate the DMA controller until the V53.

This doesn't mean that the arcade board doesn't have one—but if it does it would be an external component instead.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Simple x86 Code: Does This Look Good?

Post by Drew Sebastino »

lidnariq wrote:This doesn't mean that the arcade board doesn't have one—but if it does it would be an external component instead.
It doesn't appear to have one, unfortunately, but luckily, there's no vram to worry about, so all you'd need to worry about is the sprite table and cgram. Does the 80186 support 32 bit loads and stores like the 68000? That would help. Also, do all systems need to be in vblank to update oam and cgram, or does it vary?
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Simple x86 Code: Does This Look Good?

Post by lidnariq »

No, the 8088 through the 80286 are genuine 16 bit processors, so no 32-bit moves. It looks like the Vxx series were always 16-bit.

Anyway, you do have access to the REP MOVSW and REP STOSW instructions, which might help.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Simple x86 Code: Does This Look Good?

Post by Drew Sebastino »

lidnariq wrote:Anyway, you do have access to the REP MOVSW and REP STOSW instructions, which might help.
Is that like for mass transfers of data? I read something and I think it said it will copy from the address stored in DS all the way to ES but I don't understand how it would be able to hold something that big. I guess oam and cgram updates can be done whenever if nothing about turning the screen on or off was ever done. Is there even really a vblank on the Irem M92, or is everything done while the screen is rendering? I imagine that would simplify things.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Simple x86 Code: Does This Look Good?

Post by lidnariq »

MOVSW means "copy the word from DS:SI to ES:DI, then add two to SI and DI". STOSW means "write the word in AX to ES:DI, then add two to DI"
REP MOVSW or REP STOSW means "do the same, but then decrement CX, and if CX isn't 0, do it again"

There's also the MOVSB and STOSB variants, which work on bytes instead. There's also also OUTSW, which writes to the alternate I/O bus instead. (from DS:SI to [DX])
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Simple x86 Code: Does This Look Good?

Post by Drew Sebastino »

So it's like move a word from an address that is being indexed, and than increment the index?
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Simple x86 Code: Does This Look Good?

Post by Dwedit »

Sounds a lot like LDI / LDIR on the Z80.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Simple x86 Code: Does This Look Good?

Post by lidnariq »

Espozo wrote:So it's like move a word from an address that is being indexed, and than increment the index?
The important bit is the REP prefix, which lets you just tell the CPU "copy all this data from here to there". It's similar to other machines' DMA, but there's no trigger, just "move all this data in this manner now".

And, yes, exactly what Dwedit said. Which makes sense when you consider the x86's origins with the 8080 (even though LDI and LDIR are Z80 additions)

Similiarly, x86 REP INSB ↔ Z80 INIR/INDR; x86 REP OUTSB ↔ Z80 OTIR/OTDR; x86 REP CMPSB ↔ Z80 CPIR/CPDR. The major difference is that the x86 specifies "increment" or "decrement" based on the D(irection) flag in the flags register, conveniently toggled by using the CLD/STD instructions.

Confusingly, x86 has a LODSB instruction which differs from the Z80 LDI instruction—LODSB just loads from DS:SI to AL, which is a little confusing to use with the REP prefix.
Post Reply