Attempting To Code For The Irem M92. Again...
- 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...
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.
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.
Re: Attempting To Code For The Irem M92. Again...
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.
Unfortunately I have no idea what x86 reference I (if indeed I) gave you.
- 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...
What value are they supposed to hold then?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?).
Also, do you remember what topic this was from?
Re: Attempting To Code For The Irem M92. Again...
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).Espozo wrote:What value are they supposed to hold then?
- 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...
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.
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.
Well, that's the exact size of ram. (0xE0000 to 0xEFFFF) Not even the Irem M92 has as much ram as the SNES (Kind of shows you Nintendo's screwed up priorities...)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).
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.
Re: Attempting To Code For The Irem M92. Again...
The stack grows downward, same as SNES. To put it at the top of RAM, you'd set SS:SP to 0xE000:0x0000.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.
- 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...
I would have thought it'd be 0xE000:0xFFFF. Anyway, I'm guessing I have to do something like this?Joe wrote:To put it at the top of RAM, you'd set SS:SP to 0xE000:0x0000.
Code: Select all
mov AX, 0xE000
mov SS, AX
mov AX, 0xFFFF
mov SP, AX
Re: Attempting To Code For The Irem M92. Again...
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:I would have thought it'd be 0xE000:0xFFFF.
SP is a general-purpose register, same as AX, so you can set it directly like this:Espozo wrote:Anyway, I'm guessing I have to do something like this?
Code: Select all
mov ax, 0xe000
mov ss, ax
mov sp, 0x0000
Code: Select all
xor sp, sp
Re: Attempting To Code For The Irem M92. Again...
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).Espozo wrote:I would have thought it'd be 0xE000:0xFFFF.
Re: Attempting To Code For The Irem M92. Again...
Towards the end of your previous thread about it: viewtopic.php?p=151870#p151870Espozo wrote:Also, do you remember what topic this was from?
- 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...
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?
I think I just totally forgot how 20 bit addressing works...
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
Re: Attempting To Code For The Irem M92. Again...
This isn't a 6502-family CPU, you can move immediate values directly to memory:Espozo wrote:Code: Select all
mov dx, 0xFFFF mov [0x0000], dx
Code: Select all
mov [0x0000], word 0xffff
It looks like you're confusing yourself.Espozo wrote:I think I just totally forgot how 20 bit addressing works...
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.)
- 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...
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
Re: Attempting To Code For The Irem M92. Again...
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.
Maybe I should write up an overview of x86 addressing modes that apply to the 80186.
- 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...
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...
Now, imagine how slow a 24 bit color would change by adding 1...
I wasn't too bad until I lost my document I was using as a reference.Joe wrote:Maybe I should write up an overview of x86 addressing modes that apply to the 80186.