don't click here

Jmp to label in a seperate asm file .

Discussion in 'Engineering & Reverse Engineering' started by cokyen, Jul 15, 2016.

  1. cokyen

    cokyen

    Member
    24
    0
    0
    I am writing in m68k assembly for the sega genesis.I am using the asm68k.exe assembler. My code is as seen below

    ------------------
    A.asm
    Include 'b.asm'
    <code>
    ------------------

    ------------------
    B.asm
    <code>
    jmp CLabel
    -----------------

    ------------------
    C.asm
    CLabel:
    Move.w #$FA14,$00000CA0
    add.b #$A6,d1
    ------------------

    So when I assemble asm with..... asm68k.exe a.asm , a.bin

    It will go to a.asm , which will dump all of b .asm and into the top of a.asm... This code b.asm calls a label CLabel from c.asm, which causes an error because the assembler doesn't know what CLabel in c.asm is as it does not know about C.asm becuase the code doesn't include nor link c.asm

    How can I fix this ? Do I need to create an object .obj file from c.asm and let the linker use that to know what to do when b.asm jumps to CLabel? If so, how does this process work?
     
  2. Fred

    Fred

    Taking a break Oldbie
    1,563
    117
    43
    Portugal
    Sonic 3 Unlocked
    Uhh that might be the problem, then.
     
  3. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber

    You pretty much answered your own question =/


    So, in A.asm or B.asm, anywhere in either of these 2 asm files, include the line:

    Code (Text):
    1.     include 'C.asm'

    Until you do that, it's not going to find CLabel: in C.asm, because you physically haven't told it to include C.asm.


    Or am I really missing your point? I only ask because you answered the question yourself...
     
  4. cokyen

    cokyen

    Member
    24
    0
    0
    The code comes from a zip file with all the source asm files from a tutorial on genesis programming from bigevilcorporations website. I assume due to this , the source code wil work as is ( no added includes needed) . Assuming this is the case , would I need to make c.asm a object file by assembling it and then link it to b.asm? How does this process work of so?
     
  5. Selbi

    Selbi

    The Euphonic Mess Member
    1,497
    48
    28
    Northern Germany
    Sonic ERaZor
    Personally, I still don't understand what you mean by "object file". There's no extra assembling required, all you have to do is write
    Code (Text):
    1.       include 'C.asm'
    in A.asm or B.asm, as redhotsonic has already pointed out. That's it.

    If the source code was given to you like that, it is either broken or you're assembling from the wrong root file. Having the code in question would help here.
     
  6. GerbilSoft

    GerbilSoft

    RickRotate'd. Administrator
    2,971
    76
    28
    USA
    rom-properties
    Or... it's done like a standard programming project, where multiple modules are separate files that are assembled and linked separately. (That's why linkers exist.)

    For example, in C:
    Code (Text):
    1.  
    2. gcc -c file1.c -o file1.o
    3. gcc -c file2.c -o file2.o
    4. gcc -c file3.c -o file3.o
    5. gcc file1.o file2.o file3.o -o program
    6.  
    file1.o, file2.o, and file3.o are all object files. The fourth command tells gcc to invoke the linker to link them all together into a single program.
     
  7. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,735
    334
    63
    SonLVL
    Psy-Q's Saturn dev manual says there is a linker to go with ASM68K, but I have no idea where you would find it, or how you would use it.
     
  8. cokyen

    cokyen

    Member
    24
    0
    0
    Here is the zip file link of all asm code. Other.asm is a useless file I think.

    http://www.mediafire.com/download/he9919g3i0cthd4/asm_sega.zip

    The output file that comes with the zip is test.bin so I assume test.asm is the root .

    Here is test.asm
    Code (Text):
    1.  
    2. ;assembly practice
    3. ;  
    4.    
    5. ; Include SEGA Genesis ROM header and CPU vector table
    6.     include 'header.asm'
    7.    
    8. EntryPoint:
    9.    Loop:
    10.    move.l #0xF, d0 ; Move 15 into register d0
    11.    move.l d0, d1   ; Move contents of register d0 into d1
    12.    jmp Loop        ; Jump back up to 'Loop'
    13.  
    14. HBlankInterrupt:
    15. VBlankInterrupt:
    16.    rte   ; Return from Exception
    17.  
    18. Exception:
    19.    rte   ; Return from Exception
    20.  
    21. __end    ; Very last line, end of ROM address
    22.  
    Here is header.asm

    Code (Text):
    1.  
    2. ;Sega Megadrive ROM header file
    3. ;-----------------------------
    4.  
    5. __Start:
    6.  
    7.     dc.l   0x00FFE000      ; Initial stack pointer value
    8.     dc.l   EntryPoint      ; Start of program
    9.     dc.l   Exception       ; Bus error
    10.     dc.l   Exception       ; Address error
    11.     dc.l   Exception       ; Illegal instruction
    12.     dc.l   Exception       ; Division by zero
    13.     dc.l   Exception       ; CHK exception
    14.     dc.l   Exception       ; TRAPV exception
    15.     dc.l   Exception       ; Privilege violation
    16.     dc.l   Exception       ; TRACE exception
    17.     dc.l   Exception       ; Line-A emulator
    18.     dc.l   Exception       ; Line-F emulator
    19.     dc.l   Exception       ; Unused (reserved)
    20.     dc.l   Exception       ; Unused (reserved)
    21.     dc.l   Exception       ; Unused (reserved)
    22.     dc.l   Exception       ; Unused (reserved)
    23.     dc.l   Exception       ; Unused (reserved)
    24.     dc.l   Exception       ; Unused (reserved)
    25.     dc.l   Exception       ; Unused (reserved)
    26.     dc.l   Exception       ; Unused (reserved)
    27.     dc.l   Exception       ; Unused (reserved)
    28.     dc.l   Exception       ; Unused (reserved)
    29.     dc.l   Exception       ; Unused (reserved)
    30.     dc.l   Exception       ; Unused (reserved)
    31.     dc.l   Exception       ; Spurious exception
    32.     dc.l   Exception       ; IRQ level 1
    33.     dc.l   Exception       ; IRQ level 2
    34.     dc.l   Exception       ; IRQ level 3
    35.     dc.l   HBlankInterrupt ; IRQ level 4 (horizontal retrace interrupt)
    36.     dc.l   Exception       ; IRQ level 5
    37.     dc.l   VBlankInterrupt ; IRQ level 6 (vertical retrace interrupt)
    38.     dc.l   Exception       ; IRQ level 7
    39.     dc.l   Exception       ; TRAP #00 exception
    40.     dc.l   Exception       ; TRAP #01 exception
    41.     dc.l   Exception       ; TRAP #02 exception
    42.     dc.l   Exception       ; TRAP #03 exception
    43.     dc.l   Exception       ; TRAP #04 exception
    44.     dc.l   Exception       ; TRAP #05 exception
    45.     dc.l   Exception       ; TRAP #06 exception
    46.     dc.l   Exception       ; TRAP #07 exception
    47.     dc.l   Exception       ; TRAP #08 exception
    48.     dc.l   Exception       ; TRAP #09 exception
    49.     dc.l   Exception       ; TRAP #10 exception
    50.     dc.l   Exception       ; TRAP #11 exception
    51.     dc.l   Exception       ; TRAP #12 exception
    52.     dc.l   Exception       ; TRAP #13 exception
    53.     dc.l   Exception       ; TRAP #14 exception
    54.     dc.l   Exception       ; TRAP #15 exception
    55.     dc.l   Exception       ; Unused (reserved)
    56.     dc.l   Exception       ; Unused (reserved)
    57.     dc.l   Exception       ; Unused (reserved)
    58.     dc.l   Exception       ; Unused (reserved)
    59.     dc.l   Exception       ; Unused (reserved)
    60.     dc.l   Exception       ; Unused (reserved)
    61.     dc.l   Exception       ; Unused (reserved)
    62.     dc.l   Exception       ; Unused (reserved)
    63.     dc.l   Exception       ; Unused (reserved)
    64.     dc.l   Exception       ; Unused (reserved)
    65.     dc.l   Exception       ; Unused (reserved)
    66.     dc.l   Exception       ; Unused (reserved)
    67.     dc.l   Exception       ; Unused (reserved)
    68.     dc.l   Exception       ; Unused (reserved)
    69.     dc.l   Exception       ; Unused (reserved)
    70.     dc.l   Exception       ; Unused (reserved)
    71.    
    72.     dc.b "SEGA GENESIS    "                                 ; Console name
    73.     dc.b "(C)SEGA 1992.SEP"                                 ; Copyrght holder and release date
    74.     dc.b "Lionel Sanderson                                  " ; Domestic name
    75.     dc.b "Lionel Sanderson                                  " ; International name
    76.     dc.b "GM XXXXXXXX-XX"                                   ; Version number
    77.     dc.w 0x0000                                             ; Checksum
    78.     dc.b "J               "                                 ; I/O support
    79.     dc.l 0x00000000                                         ; Start address of ROM
    80.     dc.l __end                                              ; End address of ROM
    81.     dc.l 0x00FF0000                                         ; Start address of RAM
    82.     dc.l 0x00FFFFFF                                         ; End address of RAM
    83.     dc.l 0x00000000                                         ; SRAM enabled
    84.     dc.l 0x00000000                                         ; Unused
    85.     dc.l 0x00000000                                         ; Start address of SRAM
    86.     dc.l 0x00000000                                         ; End address of SRAM
    87.     dc.l 0x00000000                                         ; Unused
    88.     dc.l 0x00000000                                         ; Unused
    89.     dc.b "                                        "         ; Notes (unused)
    90.     dc.b "JUE             "                                 ; Country codes
    91.    
    92.    
    93.     jmp __init ;jump to the initialisation ASM file (section as its included)to prepare console prior to main code
    94.  
    Finally here init.asm

    Code (Text):
    1.  
    2. ;--------------------------------
    3. ;MEGADRIVE INITIALISATION - Lionel Sanderson, 26-06-16
    4. ;SOURCE: https://bigevilcorporation.co.uk/2012/03/09/sega-megadrive-3-awaking-the-beast/
    5. ;--------------------------------
    6.  
    7. __init:
    8.  
    9. ;=============================
    10. ;1. Checking the Reset Button
    11. ;=============================
    12.  
    13. EntryPoint:          ; Entry point address set in ROM header
    14.     tst.w 0x00A10008  ; Test mystery reset (expansion port reset?)
    15.     bne Main          ; Branch if Not Equal (to zero) - to Main
    16.     tst.w 0x00A1000C  ; Test reset button
    17.     bne Main          ; Branch if Not Equal (to zero) - to Main
    18.  
    19. ;=========================
    20. ;2. Clearing the RAM
    21. ;=========================
    22.  
    23.     move.l #0x00000000, d0     ; Place a 0 into d0, ready to copy to each longword of RAM
    24.     move.l #0x00000000, a0     ; Starting from address 0x0, clearing backwards
    25.     move.l #0x00003FFF, d1     ; Clearing 64k's worth of longwords (minus 1, for the loop to be correct)
    26. @Clear:
    27.     move.l d0, -(a0)           ; Decrement the address by 1 longword, before moving the zero from d0 to it
    28.     dbra d1, @Clear            ; Decrement d0, repeat until depleted
    29.  
    30.  
    31. ;=========================
    32. ;3. Writing the TMSS
    33. ;=========================
    34. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    35. ;the Trade Mark Security Signature – or TMSS – was a feature put in by Sega to combat unlicensed developers from releasing games for their system,
    36. ;which is a kind of killswitch for the VDP. It's the pinnacle of security systems, a very sophisticated encryption key which is almost uncrackable.
    37. ;You write the string “SEGA” to 0x00A14000.
    38. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    39.  
    40.     move.b 0x00A10001, d0      ; Move Megadrive hardware version to d0
    41.     andi.b #0x0F, d0           ; The version is stored in last four bits, so mask it with 0F      https://en.wikipedia.org/wiki/Mask_%28computing%29
    42.     beq @Skip                  ; If version is equal to 0, skip TMSS signature
    43.     move.l #'SEGA', 0x00A14000 ; Move the string "SEGA" to 0xA14000
    44. @Skip:
    45.  
    46. ;============================
    47. ;4. Initialising the Z80
    48. ;============================
    49.     move.w #0x0100, 0x00A11100 ; Request access to the Z80 bus, by writing 0x0100 into the BUSREQ port
    50.     move.w #0x0100, 0x00A11200 ; Hold the Z80 in a reset state, by writing 0x0100 into the RESET port
    51.  
    52. @Wait:
    53.     btst #0x0, 0x00A11100   ; Test bit 0 of A11100 to see if the 68k has access to the Z80 bus yet
    54.     bne @Wait               ; If we don't yet have control, branch back up to Wait
    55.    
    56. ;Here's a new opcode, BTST (bit test). It does the same as TST, but only compares the least significant bits.
    57. ;Now the 68000 has access to the Z80's bus, and the chip is held in a reset state, so we can write the program data to its memory. This is mapped from 0xA000000.
    58.  
    59.     move.l #Z80Data, a0      ; Load address of data into a0
    60.     move.l #0x00A00000, a1   ; Copy Z80 RAM address to a1
    61.     move.l #0x29, d0         ; 42 bytes of init data (minus 1 for counter)
    62. @CopyZ80:
    63.     move.b (a0)+, (a1)+      ; Copy data, and increment the source/dest addresses
    64.     dbra d0, @CopyZ80
    65.  
    66.     move.w #0x0000, 0x00A11200 ; Release reset state
    67.     move.w #0x0000, 0x00A11100 ; Release control of bus
    68.  
    69. ; =====================================================
    70. ;5. Initialising the PSG (programmable sound generator)
    71. ;======================================================
    72.  
    73.     move.l #PSGData, a0      ; Load address of PSG data into a0
    74.     move.l #0x03, d0         ; 4 bytes of data
    75. @CopyPSG:
    76.     move.b (a0)+, 0x00C00011 ; Copy data to PSG RAM
    77.     dbra d0, @CopyPSG
    78.  
    79. ;========================
    80. ;6. Initialising the VDP
    81. ;========================
    82.  
    83.     move.l #VDPRegisters, a0 ; Load address of register table into a0
    84.     move.l #0x18, d0         ; 24 registers to write
    85.     move.l #0x00008000, d1   ; 'Set register 0' command (and clear the rest of d1 ready)
    86.  
    87. @CopyVDP:
    88.     move.b (a0)+, d1         ; Move register value to lower byte of d1
    89.     move.w d1, 0x00C00004    ; Write command and value to VDP control port
    90.     add.w #0x0100, d1        ; Increment register #
    91.     dbra d0, @CopyVDP
    92.  
    93. ;======================================
    94. ;7. Initialising the Controller Ports
    95. ;======================================
    96.  
    97. ;The controller ports are generic 9-pin I/O ports, and are not particularly tailored to any device. They have five mapped I/O address each – CTRL, DATA, TX, RX and S-CTRL:
    98. ;
    99. ;    CTRL controls the I/O direction and enables/disables interrupts generated by the port
    100. ;    DATA is used to send/receive data to or from the port (in bytes or words) when the port is in parallel mode
    101. ;   TX and RX are used to send/receive data in serial mode
    102. ;    S-CTRL is used to get/set the port's current status, baud rate and serial/parallel mode.
    103.  
    104. ; Set IN I/O direction, interrupts off, on all ports
    105.     move.b #0x00, 0x000A10009 ; Controller port 1 CTRL
    106.     move.b #0x00, 0x000A1000B ; Controller port 2 CTRL
    107.     move.b #0x00, 0x000A1000D ; EXP port CTRL
    108.    
    109.  
    110.    
    111. ;=========================================
    112. ;8. Clearing the Registers and Tidying Up
    113. ;=========================================
    114.     move.l #0x00000000, a0    ; Move 0x0 to a0
    115.     movem.l (a0), d0-d7/a1-a7 ; Multiple move 0 to all registers
    116.    
    117.     ;Here's a very useful opcode – MOVEM (move multiple). It can move data to/from a list of registers or register ranges,
    118.     ;for example d0,d3,d5 or a3-a5. A common use for it would be to backup/restore all of the registers to/from the stack, in a single instruction.
    119.    
    120. ;================
    121. ;status register
    122. ;================
    123. ; Init status register (no trace, A7 is Interrupt Stack Pointer, no interrupts, clear condition code bits)
    124.     move #0x2700, sr
    125.  
    126.  
    127.     jmp __main ; Jump to the game code!
    128.  
    129.    
    130.    
    131.    
    132.  
     
  9. Selbi

    Selbi

    The Euphonic Mess Member
    1,497
    48
    28
    Northern Germany
    Sonic ERaZor
    Seems to be MAIN.ASM from here. At least then I get the build to fully run and receive a playable ROM.
     
  10. GerbilSoft

    GerbilSoft

    RickRotate'd. Administrator
    2,971
    76
    28
    USA
    rom-properties
    It seems that the associated linker for asm68k would be lnk68k, but good luck finding it.

    Without a linker, your only option is basically having a top-level .asm that includes all the other ones, e.g. how main.asm is setup in the ZIP file you uploaded.
     
  11. cokyen

    cokyen

    Member
    24
    0
    0
    The problem explained earlier occurs in header.asm at the very bottom of the file when it jmp to label _init which is in Init.asm . It has no clue what _init is . Assuming the code works as is , not including init.as , are their any solutions ? Also do include directives in 68k simply dump the code into memory at the point the directive include <file> is writen? Also are their a way to include a label without going to that label ... Like just have a declarations it knows what it is like in c?
     
  12. GerbilSoft

    GerbilSoft

    RickRotate'd. Administrator
    2,971
    76
    28
    USA
    rom-properties
    There's no linker available. You have to have all the .asm files included from a top-level file, and then assemble the top-level one.

    Init.asm hence has to be included from the file that also includes header.asm.

    The include directive in asm works exactly the same as in C; it acts like the contents of the file to be included are located at that point in the main file.
     
  13. cokyen

    cokyen

    Member
    24
    0
    0
    What assembler and matching linker do you all use for writing Genesis games from scratch assembly ?
     
  14. GerbilSoft

    GerbilSoft

    RickRotate'd. Administrator
    2,971
    76
    28
    USA
    rom-properties
    I haven't actually used a linker for MD games, precisely because there isn't one that's generally available and easy to integrate. (The GNU linker doesn't work too well because it generates ELF binaries, not raw ROM images.)

    Last time I did anything related to MD assembly, I used asmx-2.0b5. However, switching assemblers isn't going to solve the problem you're having. Once again, you *must* include all .asm files from the top-level (or include them from included asm files); otherwise, they won't assemble and you'll run into unresolved symbol errors.
     
  15. cokyen

    cokyen

    Member
    24
    0
    0

    Selbi many thankamthats an easy fix. I was assuming the tutorial assumed the users knew they had to do extra stuff monkeying around . ;)/> ;p
     
  16. cokyen

    cokyen

    Member
    24
    0
    0
    Thanks Selbi Getbalsoft Main Memory Redhotsonic Neo!! :)/> On the subject of include directives, can you include an assemby file that just tells you what the first label in the codes implementation IS (declaration / definition) but not have it go to this first label when in includes this asm file? In other words, can you just have it be their waiting for when u jmp to on Lea a label it will know what to do and at the end of the label it will return to subroutine rts ?
     
  17. AURORA☆FIELDS

    AURORA☆FIELDS

    The cute one here Tech Member
    216
    24
    18
    Finland
    AMPS
    As far as I am aware, BigEvilCorp is a total assembly noob, and I wouldn't take what he tells without a grain of salt.
    Now I am not sure what you mean with this last post, but if you mean something vaguely to do with defining a routine without actually having one, you can do it, but you need to be really careful with it, unless you want your code to jump to bad offsets that is. You can do something along the lines of this in asm68k:
    Code (Text):
    1. Lable equ $FF00
    This will create a symbolic link to lable at address 0xFF00, and will allow your code to target this as if it was just any lable you would define normally.
     
  18. BigEvilCorporation

    BigEvilCorporation

    Member
    29
    0
    0
    UK
    Tanglewood
    That blog was written back when I was learning the language, and it's not a "tutorial", more a log of my learning experiences to help me remember, so yes indeed take everything you read there with a huge grain of salt.

    As for your test.asm issue - assembling that file isn't enough, since it doesn't include the rest of the code. You need to assemble main.asm, which includes both header.asm and init.asm in appropriate locations. I'm not sure where that test.asm came from either, it's not something I wrote. A few people have sent me various ZIP files with their own code that I've fixed up and sent back, was this one of yours?

    It's probably about time I revisited that site and cleaned everything up into proper, fact checked tutorials, now that I know what I'm doing ;) Too many people seem to relying on those posts as gospel, they were written by a noob and they're riddled with mistakes.