Attempting To Code For The Irem M92. Again...

Discussion of development of software for any "obsolete" computer or video game system.
Rahsennor
Posts: 475
Joined: Thu Aug 20, 2015 3:09 am

Re: Attempting To Code For The Irem M92. Again...

Post by Rahsennor » Sat Oct 24, 2015 8:45 pm

Code: Select all

[bx+si] [bx+si+off8] [bx+si+off16]
[bx+di] [bx+di+off8] [bx+di+off16] 
[bp+si] [bp+si+off8] [bp+si+off16]
[bp+di] [bp+di+off8] [bp+di+off16]
[si]    [si+off8]    [si+off16]
[di]    [di+off8]    [di+off16]
[off16] [bp+off8]    [bp+off16]
[bx]    [bx+off8]    [bx+off16]
All modes containing BP use SS, the rest use DS.

I couldn't find a single good 80186 reference in my archives or bookmarks - they're all for the 80386 and newer, which would probably just confuse you further. I wish I'd kept those Turbo Assembler books now.

Joe
Posts: 437
Joined: Mon Apr 01, 2013 11:17 pm

Re: Attempting To Code For The Irem M92. Again...

Post by Joe » Sun Oct 25, 2015 4:20 am

Rahsennor wrote:All modes containing BP use SS, the rest use DS.
Unless you're worried about instruction size, it's a lot easier to think of it like this:

Code: Select all

none   none
 BX  +  SI  +  offset
 BP     DI
You can choose a "base" of 0, BX, or BP, an "index" of 0, SI, or DI, and an offset of any value. If you choose BP, the default segment is SS instead of DS.

The "base" and "index" names are for remembering which registers are allowed in each column.

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

Re: Attempting To Code For The Irem M92. Again...

Post by Drew Sebastino » Sun Oct 25, 2015 1:12 pm

Well, I found this old topic just now, and it looks like it should hold the reference I was using...

viewtopic.php?f=5&t=12595

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

Re: Attempting To Code For The Irem M92. Again...

Post by Drew Sebastino » Sun Oct 25, 2015 5:43 pm

Hey, I'm just curious, but are hardware registers like ax zeroed out on startup? It's not the end of the world, I'm honestly just curious if I should do it or not for one occasion. Also, I think I heard something like "mov ax, 0x0000" is as fast as "xor ax, ax" on the 80186, or am I wrong? I suppose it doesn't matter, I just personally like the look of "mov ax, 0x0000" better.

You know though, I'm trying to get sprites to display now, but I remembered the problem... I know the format for each sprite ram entry, (it's on the last page of the topic I linked) but does anyone remember how "sprite control" works? I remember there's a "switch" that DMA's a part of ram (0xF8000) to wherever to make sprites display, but I don't remember what bit does this at what register, and we never figured out how this works, because I remember I tried to activate it during active display and nothing happened, so I tried during vblank, but that's when that wasn't working.

lidnariq
Posts: 9130
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Attempting To Code For The Irem M92. Again...

Post by lidnariq » Sun Oct 25, 2015 6:29 pm

Espozo wrote:are hardware registers like ax zeroed out on startup?
The V33 clears DS, ES, and SS, sets CS to 0xFFFF, and sets IP (and the prefetch pointer) to 0x0000. I don't know about other members of the family; it'd be best if you assumed you needed to initialize things.
[is] "mov ax, 0x0000" [...]as fast as "xor ax, ax" on the 80186[?]
No need to ask us: consult the V33A datasheet itself.
V33 datasheet wrote: MOV   reg, imm   encoded as: 1 0 1 1 W reg | imm  2-3 bytes   2 cycles   operation: reg←imm
[...]
XOR   reg, reg   0 0 1 1 0 0 1 W | 1 1 reg reg'   2 bytes   2 cycles   operation: reg←reg ⊕ reg'
So: If the instruction before it is computation limited (rather than prefetch limited), they'll both take two cycles. Otherwise using the 16-bit literal will be slower by the extra byte.

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

Re: Attempting To Code For The Irem M92. Again...

Post by Drew Sebastino » Sun Oct 25, 2015 6:50 pm

lidnariq wrote:No need to ask us: consult the V33A datasheet itself.
Oh, oops... :lol: I didn't mean to ask questions I could easily answer myself...
lidnariq wrote:computation limited (rather than prefetch limited)
You mean there's more than just the number of cycles I need to be worried about now? :( Well, I'll just sick with "xor ax, ax" I'm sure it also takes less memory, not like I really care though.

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

Re: Attempting To Code For The Irem M92. Again...

Post by Drew Sebastino » Thu Oct 29, 2015 4:04 pm

Well, sorry for not posting on this in a while, but I saw this:
I wrote:Well, relating to sprites, I forgot about how I found something called "sprite control" located at 0xF9000 through 0xF900F, so it's only 16 bits long. I look at the other file, and this is what I found:

Code: Select all

62 WRITE16_MEMBER(m92_state::m92_spritecontrol_w) 
63 { 
64 	COMBINE_DATA(&m_spritecontrol[offset]); 
65 	// offset0: sprite list size (negative) 
66 	// offset1: ? (always 0) 
67 	// offset2: sprite control 
68 	// offset3: ? (always 0) 
69 	// offset4: sprite dma 
70 	// offset5: ? 
71 
 
72 	/* Sprite control - display all sprites, or partial list */ 
73 	if (offset==2 && ACCESSING_BITS_0_7) 
74 	{ 
75 		if ((data & 0xff) == 8) 
76 			m_sprite_list = (((0x100 - m_spritecontrol[0]) & 0xff) * 4); 
77 		else 
78 			m_sprite_list = 0x400; 
79 
 
80 		/* Bit 0 is also significant */ 
81 	} 
82 
 
83 	/* Sprite buffer - the data written doesn't matter (confirmed by several games) */ 
84 	if (offset==4) 
85 	{ 
86 		/* this implementation is not accurate: still some delayed sprites in gunforc2 (might be another issue?) */ 
87 		m_spriteram->copy(); 
88 		m_sprite_buffer_busy = 0; 
89 
 
90 		/* Pixel clock is 26.6666MHz (some boards 27MHz??), we have 0x800 bytes, or 0x400 words to copy from 
91 		spriteram to the buffer.  It seems safe to assume 1 word can be copied per clock. */ 
92 		timer_set(attotime::from_hz(XTAL_26_66666MHz) * 0x400, TIMER_SPRITEBUFFER); 
93 	} 
94 //  logerror("%04x: m92_spritecontrol_w %08x %08x\n",space.device().safe_pc(),offset,data); 
95 } 
So if you write a number to offset 0, (which is 0xF9000?) the number of sprites will be the same as the number you moved there? What's up with this then?

Code: Select all

67 	// offset2: sprite control
...
72 	/* Sprite control - display all sprites, or partial list */ 
73 	if (offset==2 && ACCESSING_BITS_0_7) 
And I saw
Joe wrote:That code says you need to write a value to 0xF9000 that will determine how many sprites to draw, then write 8 (or a word with 8 in the low byte) to 0xF9004 to make the sprite drawing logic use that number. Afterwards, write any value to 0xF9008 to copy the sprites from sprite RAM to the internal drawing buffer.

It looks like this logic was designed specifically for rep movsw.

Edit: these registers start at 0xF9000, not 0xF0000.
So I wrote (should I keep copying the whole thing, or do you think we're good?)

Code: Select all

;========================================================================
;Section IVT
;========================================================================

cpu 80186

section ivt start=0 ; you will need this later

idt:
   dw diverr_handler, (section.code.start >> 4)
   dw brk_handler, (section.code.start >> 4)
   dw nmi_handler, (section.code.start >> 4)
   dw int3_handler, (section.code.start >> 4)
   dw into_handler, (section.code.start >> 4)
   dw bound_handler, (section.code.start >> 4)
   dw undefinst_handler, (section.code.start >> 4)
   dw nocoprocessor_handler, (section.code.start >> 4)
   dw vbl_handler, (section.code.start >> 4)
   dw sprbuf_handler, (section.code.start >> 4)
   dw raster_handler, (section.code.start >> 4)
   dw sound_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw coprocessorerror_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw def_handler, (section.code.start >> 4)
   dw vbl_handler, (section.code.start >> 4)
   dw sprbuf_handler, (section.code.start >> 4)
   dw raster_handler, (section.code.start >> 4)
   dw sound_handler, (section.code.start >> 4)

;========================================================================
;Section Code (Pointers)
;========================================================================

section code vstart=0 align=16

diverr_handler:
  iret

brk_handler:
  iret

nmi_handler:
  iret

int3_handler:
  iret

into_handler:
  iret

bound_handler:
  iret

undefinst_handler:
  iret

nocoprocessor_handler:
  iret

vbl_handler:
  iret

sprbuf_handler:
  iret

raster_handler:
  iret

sound_handler:
  iret

def_handler:
  iret

coprocessorerror_handler:
  iret

;========================================================================
;Section Code (Main Code)
;========================================================================

main_code:

;Set Stack Location
  mov sp, 0xE000
  mov ss, sp
  xor sp, sp

;White Color Upload
  mov di, VideoHardwareRamStart
  mov ds, di
  xor di, di
  mov [PaletteRam], word 0xFFFF
  sti				;Enable Interupts

;Display Sprite
  mov [SpriteControlRam + 0], word 0xFFFF
  mov [SpriteControlRam + 4], byte 0x08
  mov [SpriteControlRam + 8], byte 0xFF

infinite_loop:
  add [PaletteRam], word 0x0001
  
  hlt
  jmp infinite_loop

;========================================================================
;Section Data
;========================================================================

section data vstart=0 align=16

;========================================================================
;Section Reset
;========================================================================

section reset start=0x7FFF0 vstart=0

  cli
  jmp (section.code.start >> 4):main_code
  
  times 16-($-$$) db 0

;========================================================================
;Section RAM
;========================================================================

segment bss start=0xE0000 vstart=0 nobits align=16

;Define Stuff:
  WorkRamStart			equ 0xE000
  VideoHardwareRamStart		equ 0xF000

  SpriteRam			equ 0x8000
  PaletteRam			equ 0x8800
  SpriteControlRam		equ 0x9000

  ScreenWidth 			equ 320
  ScreenHieght 			equ 240
But nothing happened, and yes, I have graphics at the beginning of chr rom for sprites. I think I remember running into the same situation and thinking that maybe it needed to go in vblank (which at the time wasn't set up right) but I noticed this:

Code: Select all

65 	// offset0: sprite list size (negative)
What does it mean be "(negative)"? I just wrote 0xFFFF and it didn't seem to work, so I'm assuming I did this wrong. You know, is it me, or have I already asked this exact same thing before? I just can't find it...

Another thing is I wonder if I could try to contact someone again. I remember I went to some MAME forum and asked them some stuff about this, and they basically told me that they didn't have a clue and that I should look at the "official" MAME developer's forum and asked, but it's one of those places where you sign up and wait to be approved, and I checked it after two weeks and I had still never been verified... I have a sad feeling that I know just about as much as this arcade board as anyone else...

Joe
Posts: 437
Joined: Mon Apr 01, 2013 11:17 pm

Re: Attempting To Code For The Irem M92. Again...

Post by Joe » Fri Oct 30, 2015 11:28 am

Espozo wrote:(should I keep copying the whole thing, or do you think we're good?)
Can you put it on GitHub or something? It's really tough to scroll through these posts... (Plus, version control is always a good idea.)
Espozo wrote:But nothing happened,
Probably because you didn't put any sprites in the sprite RAM before starting the sprite DMA. :wink:
Espozo wrote:vblank (which at the time wasn't set up right)
Technically it's still not set up right. You run your vblank "handler" after every interrupt, whether it's vblank or not. Code that needs to run during vblank needs to go in the vblank handler, especially now that you're working with sprites and receiving an interrupt from that as well.

Of course, if you run any code in an interrupt handler, you must save and restore any registers it changes. Fortunately, the V33 is compatible with the 80186, which means you can use pusha and popa to save and restore all 7 of the general-purpose registers. You'll probably want to access memory (or memory-mapped hardware) during vblank, so you'll also need to save and restore at least one segment register.
Espozo wrote:What does it mean be "(negative)"?
It means this:

Code: Select all

m_sprite_list = (((0x100 - m_spritecontrol[0]) & 0xff) * 4);
You wrote -1, so you should get 1 sprite.
Espozo wrote:I have a sad feeling that I know just about as much as this arcade board as anyone else...
If anyone knows more, they haven't fixed the remaining bugs in MAME's implementation. (Incidentally, you're only receiving interrupts because of one of those bugs: on a real M92, you would need to configure the interrupt controller.)

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

Re: Attempting To Code For The Irem M92. Again...

Post by Drew Sebastino » Sat Oct 31, 2015 12:48 pm

Joe wrote:Can you put it on GitHub or something? It's really tough to scroll through these posts... (Plus, version control is always a good idea.)
I don't have a GitHub account or whatever and I don't feel like getting one, so I'll just post whatever I changed from the last time.
Joe wrote:Probably because you didn't put any sprites in the sprite RAM before starting the sprite DMA. :wink:
There are graphics at the first tile in sprite chr data, so the tile number can be 0, and I'm pretty sure the location (0,0) is the top left corner, so something should show even if sprite ram is all zeroed. :wink:
Joe wrote:
Espozo wrote:What does it mean be "(negative)"?
It means this:

Code: Select all

m_sprite_list = (((0x100 - m_spritecontrol[0]) & 0xff) * 4);
You wrote -1, so you should get 1 sprite.
What? Could you just tell me the number value (0xXXXX) for 1 sprite? :oops:

Edit: Oh, wait, I remember, "negative" numbers are just regular numbers with the values of every bit being flipped, right? Well, in that case, shouldn't every sprite be visible if you just wrote 0x00? Wait, also, if this number is an 8 bit number, that means that you always display at least one sprite no matter what, because there are 256 sprites.

Joe
Posts: 437
Joined: Mon Apr 01, 2013 11:17 pm

Re: Attempting To Code For The Irem M92. Again...

Post by Joe » Sat Oct 31, 2015 1:51 pm

Espozo wrote:I don't have a GitHub account or whatever and I don't feel like getting one, so I'll just post whatever I changed from the last time.
If you say so. :|
Espozo wrote:There are graphics at the first tile in sprite chr data, so the tile number can be 0, and I'm pretty sure the location (0,0) is the top left corner, so something should show even if sprite ram is all zeroed. :wink:
Are you sure? There are several bits in there besides coordinates and tile number, and some of them might need to be set for anything to render.
Espozo wrote:What? Could you just tell me the number value (0xXXXX) for 1 sprite? :oops:
-1. Your assembler understands that. In hex, that's FF. (It's only a byte. Your assembler might complain, but it will generate the correct value for any number from -1 to -255.)
Espozo wrote:Oh, wait, I remember, "negative" numbers are just regular numbers with the values of every bit being flipped, right?
Not quite.
Espozo wrote:Well, in that case, shouldn't every sprite be visible if you just wrote 0x00? Wait, also, if this number is an 8 bit number, that means that you always display at least one sprite no matter what, because there are 256 sprites.
Nope. MAME says writing 0 gets you 0 sprites. If you want all 256 sprites, you have to set spritecontrol+4 to some value other than 8.

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

Re: Attempting To Code For The Irem M92. Again...

Post by Drew Sebastino » Sat Oct 31, 2015 2:06 pm

Joe wrote:
Espozo wrote:I don't have a GitHub account or whatever and I don't feel like getting one, so I'll just post whatever I changed from the last time.
If you say so. :|
Is that really that bad? :lol:
Joe wrote:
Espozo wrote:There are graphics at the first tile in sprite chr data, so the tile number can be 0, and I'm pretty sure the location (0,0) is the top left corner, so something should show even if sprite ram is all zeroed. :wink:
Are you sure? There are several bits in there besides coordinates and tile number, and some of them might need to be set for anything to render.
This is it:

Code: Select all

  fedc ba98 7654 3210
0 LLLW WHHy yyyy yyyy
1 tttt tttt tttt tttt
2        YX plll llll
3         x xxxx xxxx
L - layer
W,H - width, height (0,1,2,3 = 1,2,4,8 16x16 tiles)
X,Y - reflect X,Y
x,y - x,y coordinate
t - tile
p - priority
l - color
Joe wrote:Nope. MAME says writing 0 gets you 0 sprites. If you want all 256 sprites, you have to set spritecontrol+4 to some value other than 8.
I was talking about spritecontrol+8.

Joe
Posts: 437
Joined: Mon Apr 01, 2013 11:17 pm

Re: Attempting To Code For The Irem M92. Again...

Post by Joe » Sat Oct 31, 2015 3:42 pm

Espozo wrote:Is that really that bad? :lol:
Your code is terrible and ugly. :roll: It won't be so much of a problem once you're more familiar with x86.
Espozo wrote:This is it:
I saw something in the sprite logic that looked funny, but I didn't trace it out to see which of those values controlled its behavior. Since you have documentation on the format, you can easily try different combinations of parameters while ensuring the X and Y coordinates remain on-screen.
Espozo wrote:
Joe wrote:Nope. MAME says writing 0 gets you 0 sprites. If you want all 256 sprites, you have to set spritecontrol+4 to some value other than 8.
I was talking about spritecontrol+8.
I was talking about spritecontrol+0, since that's the byte that controls how many sprites are displayed when you write 8 to spritecontrol+4. The hardware doesn't care what value you write to spritecontrol+8. Writing any value there begins sprite DMA.

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

Re: Attempting To Code For The Irem M92. Again...

Post by Drew Sebastino » Sat Oct 31, 2015 6:57 pm

Joe wrote:Your code is terrible and ugly. :roll:
Thanks... :lol: If it makes you feel any better, I might get a GitHub account, but only if you're a good boy. :wink:
Joe wrote:I saw something in the sprite logic that looked funny, but I didn't trace it out to see which of those values controlled its behavior.
Oh yeah, you still have all the Irem M92 stuff that I do, don't you... What do you mean by something in the sprite logic "looked funny" though? Where you looking at the Mame C++ code?
Joe wrote:Since you have documentation on the format, you can easily try different combinations of parameters while ensuring the X and Y coordinates remain on-screen.
Well, unless I want to make 300 files with one parameter changed, (which would take for ever because I have to put the .asm file through yasm, and then put the output file through the word splitter, and then rename both of those files and then put them in a folder with the rest of the games files like the tile data and then compress all of that and then put it in the Mame roms folder and then run my batch file to run Mame in debug mode) I would have to change them while the demo is running, which would require reading the controllers... Well, I've gotten BGs to display, so I could test if the controllers are working by manipulating BG positions or something.
Joe wrote:I was talking about spritecontrol+0, since that's the byte that controls how many sprites are displayed when you write 8 to spritecontrol+4. The hardware doesn't care what value you write to spritecontrol+8. Writing any value there begins sprite DMA.
Oops, yeah, I meant spritecontrol+0.

Joe
Posts: 437
Joined: Mon Apr 01, 2013 11:17 pm

Re: Attempting To Code For The Irem M92. Again...

Post by Joe » Sun Nov 01, 2015 2:57 am

Espozo wrote:Oh yeah, you still have all the Irem M92 stuff that I do, don't you... What do you mean by something in the sprite logic "looked funny" though? Where you looking at the Mame C++ code?
I saw something that controlled priority and couldn't tell what it was supposed to do. I just now noticed an explanation for it at the top of this file, so I guess that's not a problem.
Espozo wrote:Well, unless I want to make 300 files with one parameter changed, I would have to change them while the demo is running, which would require reading the controllers...
Or you can cycle through possible values every vblank. Cycling through all possibilities would take a while, but only cycling a few bits would take seconds to repeat.

Also, filling the sprite ROMs so you didn't have to worry about tile numbers might be a good idea.

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

Re: Attempting To Code For The Irem M92. Again...

Post by Drew Sebastino » Sun Nov 01, 2015 8:08 am

Well, I honestly think that it would be good to try and read the controllers, so I was trying to turn on BGs like I did last time, but then I remembered that the registers to enable the BGs exist on some sort of separate address space somehow, same with the controllers: http://patpend.net/technical/arcade/m92.html How do I write to the BG control? Also, I imagine it would be about the same for controllers, except your taking in values instead of sending them.

Post Reply