It is currently Sat Dec 16, 2017 8:05 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Sat Oct 17, 2015 10:04 pm 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3159
Location: Nacogdoches, Texas
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.


Top
 Profile  
 
PostPosted: Sat Oct 17, 2015 11:23 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6534
Location: Seattle
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.


Top
 Profile  
 
PostPosted: Sun Oct 18, 2015 4:41 am 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3159
Location: Nacogdoches, Texas
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?


Top
 Profile  
 
PostPosted: Sun Oct 18, 2015 5:42 am 
Offline

Joined: Mon Apr 01, 2013 11:17 pm
Posts: 437
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).


Top
 Profile  
 
PostPosted: Sun Oct 18, 2015 6:48 am 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3159
Location: Nacogdoches, Texas
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.


Top
 Profile  
 
PostPosted: Sun Oct 18, 2015 7:35 am 
Offline

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


Top
 Profile  
 
PostPosted: Sun Oct 18, 2015 7:42 am 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3159
Location: Nacogdoches, Texas
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:
  mov AX, 0xE000
  mov SS, AX

  mov AX, 0xFFFF
  mov SP, AX


Top
 Profile  
 
PostPosted: Sun Oct 18, 2015 9:00 am 
Offline

Joined: Mon Apr 01, 2013 11:17 pm
Posts: 437
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:
    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:
    xor sp, sp


Top
 Profile  
 
PostPosted: Mon Oct 19, 2015 7:23 am 
Offline

Joined: Thu Aug 12, 2010 3:43 am
Posts: 1589
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).


Top
 Profile  
 
PostPosted: Mon Oct 19, 2015 2:00 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6534
Location: Seattle
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


Top
 Profile  
 
PostPosted: Mon Oct 19, 2015 7:45 pm 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3159
Location: Nacogdoches, Texas
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:
;========================================================================
;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...


Top
 Profile  
 
PostPosted: Mon Oct 19, 2015 8:16 pm 
Offline

Joined: Mon Apr 01, 2013 11:17 pm
Posts: 437
Espozo wrote:
Code:
  mov dx, 0xFFFF
  mov [0x0000], dx

This isn't a 6502-family CPU, you can move immediate values directly to memory:
Code:
    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.)


Top
 Profile  
 
PostPosted: Sat Oct 24, 2015 7:16 am 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3159
Location: Nacogdoches, Texas
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:
;========================================================================
;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


Top
 Profile  
 
PostPosted: Sat Oct 24, 2015 8:27 am 
Offline

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


Top
 Profile  
 
PostPosted: Sat Oct 24, 2015 9:46 am 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3159
Location: Nacogdoches, Texas
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: lazygecko and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group