找回密码
 注册
搜索

[L2] [T-25143]ラングリッサー2魔族編开发讨论专贴

[复制链接]
 楼主| 发表于 2009-6-18 07:26 | 显示全部楼层
既然這貼是在下的開發技術貼,也已經提過一下開發的技術,一般修改技術方面各論壇Hack區的版主們和那些骨幹發佈者們應該都是可以製作出來難度並不高,而製作編輯器稍微會些編程就可以也是難度並不高,但至於高級開發技術方面的東西,就相對比較難,雖説我也知道極少會有人感興趣,不過我是否有必要把我的一些開發資料發出來?............我認爲這些資料都非常珍貴.........至少對我來說還是很重要且核心的.....
 楼主| 发表于 2009-6-18 07:43 | 显示全部楼层
本帖最后由 フラナガン機關 于 2009-6-18 08:07 编辑

以前我曾在前面陸續放出過的就不重復了......再發一些其他核心的信息
Genesis informations:  by hacking-cult.org   drx

1.
Research / Megadrive Programming / 68000 memory map
$000000-$3FFFFF - ROM
$400000-$9FFFFF - Unused
$A00000-$A0FFFF - Z80
$A10000-$A1001F - I/O
$A10020-$BFFFFF - Miscellaneous
$C00000-$C0001F - VDP
$C00020-$DFFFFF - VDP mirrors
$E00000-$FFFFFF - RAM (it repeats each $10000, so $E00000
is the same as $E20000 and $FF0000. Most games use $FF0000-$FFFFFF)
 楼主| 发表于 2009-6-18 07:45 | 显示全部楼层
2.
Research / Megadrive Programming / ROM header
$000-$0FF - Vectors
      $00 - Stack pointer
      $04 - Code start
      $08 - Bus error
      $0C - Address error
      $10 - Illegal instruction
      $14 - Divistion by zero
      $18 - CHK exception
      $1C - TRAPV exception
      $20 - Privilege violation
      $24 - TRACE exeption  
      $28 - LINE 1010 EMULATOR  
      $2C - LINE 1111 EMULATOR  
      $30-$5F - Reserved by Motorola  
      $60 - Spurious exception
      $64 - Interrupt request level 1  
      $68 - Interrupt request level 2  
      $6C - Interrupt request level 3  
      $70 - Interrupt request level 4 (VDP interrupt / Horizontal blank)  
      $74 - Interrupt request level 5  
      $78 - Interrupt request level 6 (Vertical blank)  
      $7C - Interrupt request level 7  
      $80 - TRAP #00 exception  
      $84 - TRAP #01 exception  
      $88 - TRAP #02 exception  
      $8C - TRAP #03 exception  
      $90 - TRAP #04 exception  
      $94 - TRAP #05 exception  
      $98 - TRAP #06 exception  
      $9C - TRAP #07 exception  
      $A0 - TRAP #08 exception  
      $A4 - TRAP #09 exception  
      $A8 - TRAP #10 exception  
      $AC - TRAP #11 exception  
      $B0 - TRAP #12 exception  
      $B4 - TRAP #13 exception  
      $B8 - TRAP #14 exception  
      $BC - TRAP #15 exception  
      $C0-$FF - Reserved by Motorola
$100-$10F - Console name (usually 'SEGA MEGA DRIVE ' or 'SEGA GENESIS    ')
$110-$11F - Release date (usually '(C)XXXX YYYY.MMM'
            where XXXX is the company code, YYYY is the year and MMM - month)
$120-$14F - Domestic name
$150-$17F - International name
$180-$18D - Version ('XX YYYYYYYYYYYY' where XX is the game type and YY the game code)
$18E-$18F - Checksum (for info how to calculate checksum go HERE)
$190-$19F - I/O support
$1A0-$1A3 - ROM start
$1A4-$1A7 - ROM end
$1A8-$1AB - RAM start (usually $00FF0000)
$1AC-$1AF - RAM end (usually $00FFFFFF)
$1B0-$1B2 - 'RA' and $F8 enables SRAM.
$1B3      - unused ($20)
$1B4-$1B7 - SRAM start (default $00200000)
$1B8-$1BB - SRAM end (default $0020FFFF)
$1BC-$1FF - Notes (unused)
 楼主| 发表于 2009-6-18 07:46 | 显示全部楼层
3.
Research / Megadrive Programming / Genesis security
Control code
Models >= 2 of Mega Drive / Genesis have a requirement of putting
'SEGA' to ($A14000).l . Here's the code that will fix it (put it in the
init section)
                move.b        ($A10001).l,d0                ;version
                andi.b        #$F,d0
                beq        SkipSecurity                ;skip if smd model = 1
                move.l        #'SEGA',($A14000).l
SkipSecurity:   

Checksum
Checksum is a word in ROM
header that is calculated while compiling (in SEGA). While hacking, you
probably encountered problems like red screen or 'WRONG CHECKSUM'. If
you're asm hacking a rom, you have to find the checking routine and
delete it. The routine is:
                movea.l        #$200,a0
                movea.l        #$7FFFF,a1        ; ROM End
                move.l        (a1),d0
                moveq        #0,d1
loop:
                add.w        (a0)+,d1
                cmp.l        a0,d0
                bcc.s        loop
                movea.l        #$18E,a1        ; Checksum
                cmp.w        (a1),d1
                bne.w        WrongChecksum
So to fix it, delete the 'bne WrongChecksum'. Depends on the rom,
but usually the routine is exactly like that, because that's what's in
the Mega Drive tech docs (by SEGA =P). But if you're hacking in a hex
editor, you have to either calculate the checksum yourself or get a
calculator. To calculate the checksum you do the following:
1. Start at $200
2. Add a word to the checksum (ignore the upper bits)
3. Increment the offset
4. If offset < rom end, go to 2
5. Here's your checksum =)
 楼主| 发表于 2009-6-18 07:49 | 显示全部楼层
4.
Research / Megadrive Programming / I/O ports
I/O
Registers
Address        Description
$A10001        Version
$A10003        Port A data
$A10005        Port B data
$A10007        Port C data
$A10009        Port A control
$A1000B        Port B control
$A1000D        Port C control
$A1000F        Port A TxData
$A10011        Port A RxData
$A10013        Port A serial control
$A10015        Port B TxData
$A10017        Port B RxData
$A10019        Port B serial control
$A1001B        Port C TxData
$A1001D        Port C RxData
$A1001F        Port C serial control
Reading even addresses returns the same as odd ones so you can use both $A10000 and $A10001.
$a10001 - version register
Reading version register returns a byte:
Bit 7 - Export bit. 1 if export (USA, Europe, etc.), 0 if domestic (Japan)
Bit 6 - Video type. 1 if PAL, 0 if NTSC
Bit 5 - 0 if Sega CD connected, 1 if not connected
Bit 4 - Unused (always 0)
Bits 3-0 - 0 - MegaDrive 1 / Genesis 1, 1 - newer. Newer have additional security hardware.
$a10003-7 - data registers
Reading a data register returns the state of all pins:
Bit 7 - Unused
Bit 6 - TH pin
Bit 5 - TR pin
Bit 4 - TL pin
Bit 3 - Data 3 pin
Bit 2 - Data 2 pin
Bit 1 - Data 1 pin
Bit 0 - Data 0 pin
Reading joypads
Here's the code:
pads_read:
                lea     ($FFFFFFF0).w,a0        ;where the joypad states will be written
                lea     ($A10003).l,a1        ;first joypad data port
                bsr.s   joypad_read        ;do the first joypad
                addq.w  #2,a1                ;do the second joypad
joypad_read:
                move.b  #0,(a1)                ;set the first part
                nop                             ;let the hardware parts act
                nop     
                move.b  (a1),d0                ;move the lower byte to d0
                lsl.b   #2,d0                ;shift some stuff
                andi.b  #$C0,d0                ;exclude some dirty stuff
                move.b  #$40,(a1)                ;set the second part
                nop                             ;the delay
                nop     
                move.b  (a1),d1                ;move the upper byte to d1
                andi.b  #$3F,d1                ;exclude some dirty stuff
                or.b    d1,d0                ;or d0 with d1
                not.b   d0                ;not d0
                move.b  (a0),d1                ;move the previous joypad state
                eor.b   d0,d1                ;eor previous state with current state
                                        ;(we get holded joypad state in d1)
                move.b  d0,(a0)+                ;move the pressed state to ram
                and.b   d0,d1                ;and stuff
                move.b  d1,(a0)+                ;move the holded state to ram
                rts     
After executing that code you will have:
$FFFFF0 - Current pressed state of joypad 1
$FFFFF1 - Current holded state of joypad 1
$FFFFF2 - Current pressed state of joypad 2
$FFFFF3 - Current holded state of joypad 2
The joypad output format:
Bit 7 - Start
Bit 6 - A button
Bit 5 - C button
Bit 4 - B button
Bit 3 - Right
Bit 2 - Left
Bit 1 - Down
Bit 0 - Up
 楼主| 发表于 2009-6-18 07:52 | 显示全部楼层
5.
Research / Megadrive Programming / DMA
Overview
What's DMA? DMA stands for Direct Memory Access. There are 3 types of
DMA: 68k memory to VDP memory copy, VDP memory to VDP memory copy, VDP
memory fill.
68k to VDP copy
It's used to copy data from 68000 memory (meaning ROM, SRAM, RAM etc.,
all 68k memory =P) to VDP memory (Video RAM, Vertical Scroll RAM or
Color RAM). Remember to set the auto increment register ($F) to $2
before doing this. First, you need to specify the DMA length using
registers $13 and $14:
$13: L07 L06 L05 L04 L03 L02 L01 L00
$14: L15 L14 L13 L12 L11 L10 L08 L08
Length = number of bytes transferred / 2 (or >>1)
Next, you need to specify the source address (in 68k). Here's how you should set registers $15-$17:
$15: S08 S07 S06 S05 S04 S03 S02 S01
$16: S16 S15 S14 S13 S12 S11 S10 S09
$17:  0  S23 S22 S21 S20 S19 S18 S17
The source address is also shifted to the right by one (divided by 2).
Now, to begin the DMA, you write a longword command to the control port:
Bits 31-24:  CD1 CD0 A13 A12 A11 A10 A09 A08
Bits 23-16:  A07 A06 A05 A04 A03 A02 A01 A00
Bits 15-08:   0   0   0   0   0   0   0   0
Bits 07-00:   1   0   0  CD2  0   0  A15 A14
A15-A00 is the destination address in VRAM, VSRAM or CRAM.
CD2-CD0:
001 - VRAM
011 - CRAM
101 - VSRAM
After doing the above, the DMA will start and until it's done, 68000 will be frozen. For the lazy, the code:
;length = length (original, not shifted)
;source = source addr (not shifted)
;dest = destination addr
;x = %001 if VRAM, %011 if CRAM, %101 if VSRAM
;
;btw, you can just write it like that:
length = $100        ;etc.
                move.w        #$9400+(((length)&$FF00)>>9),($C00004).l
                move.w        #$9300+(((length)&$FF)>>1),($C00004).l
                move.w        #$9600+(((source>>1)&$FF00)>>8),($C00004).l
                move.w        #$9500+((source>>1)&$FF),($C00004).l
                move.w        #$9700+((((source>>1)&$FF0000)>>16)&$7F),($C00004).l
move.l        #($80+((dest&$3FFF)<<16)+((dest&$4000)>>14)+((x&$4)<<2)+((x&$3)<<30)),($C00004).l
If you're too lazy to even do that, use the calculator...
VRAM copy
This DMA is used to copy VRAM to VRAM.
Note: auto increment register ($F) has to be set to $01 before the DMA.
Register $14 contains the higher 8 bits of fill length (shifted by one
to the right), register $13 contains the lower 8 bits. Registers $16
and $15 are the source address in VRAM. Register $17 has to be set to
$C0. The DMA is started when this command is written to the
VDP:
Bits 31-24:  0   0  A13 A12 A11 A10 A09 A08
Bits 23-16: A07 A06 A05 A04 A03 A02 A01 A00
Bits 15-08:  ?   ?   ?   ?   ?   ?   ?   ?
Bits 07-00:  1   1   0   0   ?   ?  A15 A14
A15-A00 - Destination address in VRAM
The code for the lazy:
                move.w        #$8F01,($C00004).l
                move.w        #$9400+(((copylength)&$FF00)>>9),($C00004).l
                move.w        #$9300+(((copylength)&$FF)>>1),($C00004).l
                move.w        #$9600+(((src)&$FF00)>>8),($C00004).l
                move.w        #$9500+((src)&$FF),($C00004).l
                move.w        #$97C0,($C00004).l
                move.l        #($C0+((dest&$3FFF)<<16)+((dest&$4000)>>14)),($C00004).l
                move.w        #$8F02,($C00004).l
VRAM fill
If you dreamed about filling VRAM with a random word, VRAM fill is for you. It fills VRAM with a specified byte:
Registers $14, $13 - how many bytes to fill
Register $17 - #$80
Register $F - #$01
After setting the registers, you have to write a command to the VDP:
Bits 31-24:  0   1  A13 A12 A11 A10 A09 A08
Bits 23-16: A07 A06 A05 A04 A03 A02 A01 A00
Bits 15-08:  ?   ?   ?   ?   ?   ?   ?   ?
Bits 07-00:  1   0   0   0   ?   ?  A15 A14
A15-A00 - the address in VRAM where the fill will start
Finally, you have to write a word to the data port ($C00000). First byte is the byte that will be copied everywhere, the
other byte is written to the address (only once).
The code:
                move.w        #$8F01,($C00004).l
                move.w        #$9400+(((length)&$FF00)>>9),($C00004).l
                move.w        #$9300+(((length)&$FF)>>1),($C00004).l
                move.w        #$9780,($C00004).l
                move.l        #($40000080+((addr&$3FFF)<<16)+((addr&$4000)>>14)),($C00004).l
                move.w        #$xx00,($C00000).l
                move.w        #$8F02,($C00004).l
That's all folks. If you have problems with calculating all the stuff, use the calculator.
 楼主| 发表于 2009-6-18 07:58 | 显示全部楼层
6.
Research / Megadrive Programming / VDP
VDP
Ports:
Address        Description
$C00000        Data port
$C00002        Data port (mirror)
$C00004        Control port
$C00006        Control port (mirror)
$C00008        HV counter
$C0000A        HV counter (mirror)
$C0000C        HV counter (mirror)
$C0000E        HV counter (mirror)
$C00011        SN76489 PSG
$C00013        SN76489 PSG (mirror)
$C00015        SN76489 PSG (mirror)
$C00017        SN76489 PSG (mirror)
$C00018        Unused
$C0001A        Unused
$C0001C        Unused
$C0001F        Unused
Data port
Here, you write data after programming the control port.
Control port
Reading the control port returns a status word:
Bit 15 - Always 0
Bit 14 - Always 0
Bit 13 - Always 1
Bit 12 - Always 1
Bit 11 - Always 0
Bit 10 - Always 1
Bit 9 - FIFO empty
Bit 8 - FIFO full
Bit 7 - V blank pending
Bit 6 - Sprite overflow
Bit 5 - Sprite collision
Bit 4 - Odd frame
Bit 3 - Vertical blanking
Bit 2 - Horizontal blanking
Bit 1 - DMA in process
Bit 0 - PAL mode flag (1 for PAL, 0 for not PAL)
Accessing VDP RAM
You can access VDP RAM writing a 32-bit command to control port then reading/writing to the data port. Here's the command:
    CD1 CD0 A13 A12 A11 A10 A09 A08     (D31-D24)
    A07 A06 A05 A04 A03 A02 A01 A00     (D23-D16)
     ?   ?   ?   ?   ?   ?   ?   ?      (D15-D8)
    CD5 CD4 CD3 CD2  ?   ?  A15 A14     (D7-D0)
A00-A15 - address
CD0-CD3 - code
CD4 - 1 if VRAM copy DMA mode. 0 otherwise.
CD5 - DMA operation
Bits CD3-CD0:
0000 - VRAM read
0001 - VRAM write
0011 - CRAM write
0100 - VSRAM read
0101 - VSRAM write
1000 - CRAM read
Example:
        move.l        #$C0000000,($c00004).l        ;program the control register
        move.w        #$0EEE,($c00000).l                ;move colo(u)r EEE to CRAM
Programming VDP registers
VDP has 23 registers that can be programmed writing a 16-bit command to the control port:
     1   0   ?  R04 R03 R02 R01 R00     (D15-D8)
    D07 D06 D05 D04 D03 D02 D01 D00     (D7-D0)
R04-R00 - register
D07-D00 - data
Example:
        ;set the border colo(u)r to palette $1, colo(u)r $2
        move.w        #$8712,($c00004).l
Registers can be also set by writing a 32-bit command (2 registers at a time):
        ;set the border color to palette $1, color $2
        ;and set the VDP auto increment data to $2
        move.l        #$87128F02,($c00004).l
List of registers:

Register        Name        Description
$00        Mode Set Register No. 1       
Bits 7-5 - unused
Bit 4 - H interrupts enable
Bit 3 - 1 = invalid display
Bit 2 - 1 = 8 colour mode (only bits 1, 5 and 9 of colours are displayed)
Bit 1 - 1 = HV counter latch enable
Bit 0 - 1 = disable display
$01        Mode Set Register No. 2       
Bit 7 - TMS9918 / Genesis display select
Bit 6 - 1 = display enabled, 0 = fill the screen with backdrop colour (border colour)
Bit 5 - V interrupts enable
Bit 4 - DMA enable
Bit 3 - 1 = PAL (240 lines), 0 = NTSC (224 lines)
Bit 2 - SMS / Genesis display select
Bit 1 - 1 = HV counter latch enable
Bit 0 - 1 = disable display
$02        VRAM Address for Scroll A       
Bits 5-3 of this register correspond to bits A15-A13 of the name table
address for plane A.
$03        VRAM Address for Window       
Bits 5-1 of this register correspond to bits A15-A11 of the name table
address for the window.
In 40-cell mode, A11 is always forced to zero.
$04        VRAM Address for Scroll B       
Bits 2-0 of this register correspond to bits A15-A11 of the name table
address for plane B.
$05        VRAM Address for Sprite Attributes       
Bits 6-0 of this register correspond to bits A15-A09 of the sprite
attribute table.
In 40-cell mode, A09 is always forced to zero.
$06        Unused       
(Used by Master System)
$07        Backdrop colour       
Bits 5-4 - palette line in CRAM
Bits 3-0 - colour
$08        Unused       
(Used by Master System)
$09        Unused       
(Used by Master System)
$0A        H interrupt register       
Value that will be loaded in the counter.
$0B        Mode Set Register No. 3       
Bits 7-4 - unused
Bit 3 - 1 = external interrupts enable
Bit 2 - 1 = 2-cell column based vertical scrolling, 0 = full screen vertical scrolling
Bits 1-0 -
  0 0    - Full screen scroll
  0 1    - Line scroll
  1 0    - Cell scroll
  1 1    - Line scroll
$0C        Mode Set Register No. 4       
Bit 6-4 - unused
Bit 3 - ???
Bits 2-1 -
  0 0   - No interlace
  0 1   - Interlace (normal resolution)
  1 0   - No interlace
  1 1   - Interlace (double resolution
Bits 0,7 -
  0 0    - 32 cells display
  0 1    - 40 cells display (the display is weird a bit)
  1 0    - invalid setting
  1 1    - 40 cells display
$0D        VRAM Address for Horizontal Scroll       
Bits 2-0 of this register correspond to bits A15-A11 of the name table
address for plane B.
$0E        Unused       
---
$0F        Auto Increment Data       
Value to be added VDP address register after each read/write to the data port.
$10        Scroll Size       
Bit 7-6 - unused
Bit 5-4 - Vertical Scroll Size (same as horizontal)
Bit 3-2 - unused
Bit 1-0 - Horizontal Scroll Size:
  0 0    - 32 cells
  0 1    - 64 cells
  1 0    - invalid setting
  1 1    - 128 cells
$11        Window Horizontal Position       
Well, I don't recommend setting it to something different than $00, because I haven't cracked this register fully yet.
$12        Window Vertical Position       
Same as above
$13        DMA Length Bits 7-0       
Bits 7-0 of DMA length.
$14        DMA Length Bits 15-8       
Bits 15-8 of DMA length.
$15        DMA Source Address Bits 7-0       
Bits 7-0 of DMA source address.
$16        DMA Source Address Bits 15-8       
Bits 15-8 of DMA source address.
$17        DMA Type       
Bit 7 - depends.
If bit 7 is 0:
- DMA type is Memory to VRAM (68k memory to VRAM)
- bits 6-0 become bits 22-16 of DMA source address
- the whole DMA source address has to be shifted to the right by one bit
If bit 7 is 1:
- DMA type is VRAM fill (if bit 6 = 0) or VRAM to VRAM copy (if bit 6 = 1)
- Only bits of registers $15 and $16 are taken into account, bits 5-0 of this registers are ignored (I'm not sure, haven't tested this yet)
 楼主| 发表于 2009-6-18 08:00 | 显示全部楼层
本帖最后由 フラナガン機關 于 2009-6-18 08:15 编辑

7.
VDP programming calculator
a programming calculator, so you can easily program VDP

===================================================
前面這些都是屬於需要了解的基礎中的基礎是MD的基本結構與運作原理,而至於相對深度技術開發方面下面再繼續發出來另外程序的部分.....
也希望以後能有其他人搞研究或開發時可以參考,至於能和在下一起來製作方面就不奢求了....
发表于 2009-6-18 13:51 | 显示全部楼层
为什么图像都是那种颜色的
 楼主| 发表于 2009-6-18 22:56 | 显示全部楼层
顔色的表示取決於倒入的調色磐的色彩還原程度是否是100%精確,這個調色磐的完全再現實際上並不容易....也需要一些對圖片素材16bit碼的手動編輯和處理.........
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|虎纹猫家园

GMT+8, 2024-11-23 09:55 , Processed in 0.021329 second(s), 12 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表