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

Discussion of development of software for any "obsolete" computer or video game system. See the WSdev wiki and ObscureDev wiki for more information on certain platforms.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

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

Post by Drew Sebastino »

Yup... Again, with all this talk of doing something simple originally, I figured I'd better try something simple, and since I didn't want to backtrack on the SNES, I figured I'd do it here, although that didn't work too well the last time...

Well, because I'm an idiot, I lost my x86 reference pdf file that I think lidnariq gave me. Also, I think I remember lidnariq saying something about not initializing some register during vblank where I was trying to DMA sprite data and that that could potentially be why no sprites ever appeared. In fact, does anyone know what topic that is from? I looked at the "Simple x86 Code" one, but I couldn't find it, so it must be something else.
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

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

Post by lidnariq »

You didn't initialize SS or SP on power up, so when an IRQ finished (or any subroutine, for that matter) it would return to some random value in ROM (since I think both SS and SP power on as 0?).

Unfortunately I have no idea what x86 reference I (if indeed I) gave you.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

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

Post by Drew Sebastino »

lidnariq wrote:You didn't initialize SS or SP on power up, so when an IRQ finished (or any subroutine, for that matter) it would return to some random value in ROM (since I think both SS and SP power on as 0?).
What value are they supposed to hold then?

Also, do you remember what topic this was from?
Joe
Posts: 649
Joined: Mon Apr 01, 2013 11:17 pm

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

Post by Joe »

Espozo wrote:What value are they supposed to hold then?
SS and SP should point to the segment and offset where you want your stack to be. Unlike the 6502 and 65816, you can put the stack anywhere you want; the only limit is that it can't be larger than 64kB (since SP is 16 bits).
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

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

Post by Drew Sebastino »

So, I'm guessing SS is the segment? Again, I'd just make the segment 4 bits and leave the rest 0, because that way, you could write to something like 0x40000 and 0x46000 without having to change the segment.
Joe wrote:you can put the stack anywhere you want; the only limit is that it can't be larger than 64kB (since SP is 16 bits).
Well, that's the exact size of ram. (0xE0000 to 0xEFFFF) Not even the Irem M92 has as much ram as the SNES :lol: (Kind of shows you Nintendo's screwed up priorities...)

Anyway, what way does the stack go? Does it grow backward like on the SNES? If so, I'd just put it at the end of ram.
Joe
Posts: 649
Joined: Mon Apr 01, 2013 11:17 pm

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

Post by Joe »

Espozo wrote:Anyway, what way does the stack go? Does it grow backward like on the SNES? If so, I'd just put it at the end of ram.
The stack grows downward, same as SNES. To put it at the top of RAM, you'd set SS:SP to 0xE000:0x0000.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

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

Post by Drew Sebastino »

Joe wrote:To put it at the top of RAM, you'd set SS:SP to 0xE000:0x0000.
I would have thought it'd be 0xE000:0xFFFF. Anyway, I'm guessing I have to do something like this?

Code: Select all

  mov AX, 0xE000
  mov SS, AX

  mov AX, 0xFFFF
  mov SP, AX
Joe
Posts: 649
Joined: Mon Apr 01, 2013 11:17 pm

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

Post by Joe »

Espozo wrote:I would have thought it'd be 0xE000:0xFFFF.
This is the most common stack-related mistake I see x86 programmers making. Take a look at the description of the stack here. The 6502 family has an empty stack, but x86 has a full stack. In other words, when you push a value to the stack, SP is decremented first and the value is written second, and when you pop a value from the stack, the value is read first and SP is incremented second.
Espozo wrote:Anyway, I'm guessing I have to do something like this?
SP is a general-purpose register, same as AX, so you can set it directly like this:

Code: Select all

    mov ax, 0xe000
    mov ss, ax
    mov sp, 0x0000
It's common to use xor or sub to set a register to zero, even though it affects the flags, because it's a smaller instruction.

Code: Select all

    xor sp, sp
Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

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

Post by Sik »

Espozo wrote:I would have thought it'd be 0xE000:0xFFFF.
Then you'd waste a byte. You should see E000:0000 like it was E000:10000 (then the first time you push a word, it'll go to E000:FFFE-FFFF).
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

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

Post by lidnariq »

Espozo wrote:Also, do you remember what topic this was from?
Towards the end of your previous thread about it: viewtopic.php?p=151870#p151870
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

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

Post by Drew Sebastino »

Well, I though I knew what I was doing, but apparently, I don't because I wanted to make this one simple code that would add 1 to the value of color 0 every frame, which was supposed to start out white, but it doesn't work in that it starts out at the default color black. Have any ideas?

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
  mov sp, 0x0000

;White Color Upload
  mov di, VideoHardwareRamStart
  mov es, di
  mov di, PaletteRam
  mov dx, 0xFFFF
  mov [0x0000], dx
  sti			;Enable Interupts


infinite_loop:
  mov dx, [0x0000]
  add dx, 0x0001
  mov [0x0000], dx
  
  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
I think I just totally forgot how 20 bit addressing works...
Joe
Posts: 649
Joined: Mon Apr 01, 2013 11:17 pm

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

Post by Joe »

Espozo wrote:

Code: Select all

  mov dx, 0xFFFF
  mov [0x0000], dx
This isn't a 6502-family CPU, you can move immediate values directly to memory:

Code: Select all

    mov [0x0000], word 0xffff
Espozo wrote:I think I just totally forgot how 20 bit addressing works...
It looks like you're confusing yourself.

When you try to set the first color, you set ES to 0xF000 and DI to 0x8800, like you're expecting those to be implicitly used as the destination address. Only string instructions like stos and movs do that; everything else uses DS (or sometimes SS) as the segment by default, and requires you to explicitly code the offset.

So, when you do mov [0x0000], word 0xffff you're writing to 0x0000:0x0000 instead of 0xF000:0x8800 like you intended.

If you set DS to 0xF880 at the beginning, it should at least turn the screen white at the beginning. You'll also see the color cycle if any interrupts are occurring. (Recent fixes to MAME's M92 emulation may require you to set up the interrupt controller before you can receive any interrupts.)
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

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

Post by Drew Sebastino »

Okay, sorry for not replying in a while (I have another certain issue...), but I tried this, but it didn't work for whatever reason. I thought I did everything right.

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
  mov sp, 0x0000

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


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
Joe
Posts: 649
Joined: Mon Apr 01, 2013 11:17 pm

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

Post by Joe »

Well, part of the problem is you're setting ES but all of your instructions that access memory are using DS...

Maybe I should write up an overview of x86 addressing modes that apply to the 80186.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

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

Post by Drew Sebastino »

Yay, it works! :) I'm glad we finally got vblank to work correctly. Next up, sprites...

Now, imagine how slow a 24 bit color would change by adding 1...
Joe wrote:Maybe I should write up an overview of x86 addressing modes that apply to the 80186.
I wasn't too bad until I lost my document I was using as a reference.
Post Reply