URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
[/] [open8_urisc/] [trunk/] [Open8 Tools/] [README.2.OPEN8_AS.txt] - Rev 290
Go to most recent revision | Compare with Previous | Blame | View Log
----------------------------------------------PV2ASSembler Documentation - Index----------------------------------------------1..... Introduction2..... Assembler Directives3..... Assembler Syntax3.1.. Case Sensitivity3.2.. Comments3.3.. Labels3.4.. Number Types3.5.. Strings3.6.. Mnemonics4..... Error Messages5..... Bugs6..... Temporary Files7..... Compiling7.1.. Compiling Object Files7.2.. Compiling Library Files8..... Linking9..... Arithmetics10.... PV2 Flags11.... Good things to know about PV212.... Legal Note----------------------------------------------1.... Introduction----------------------------------------------This assembler was originally based on the WLA Assembler that can createmachine code for a boatload of retro consoles. It's really a piece of qualitywork, and an indespensible tool for retro-console hackers.The original WLA assembler can be found at http://www.iki.fi/~vhelin/wla.htmlPlease don't bother Ville Helin if PV2ASS does something wrong. No doubt I'veintroduced a bug or two when I modified it for v8 uRISC code.I forked WLA because I needed an assembler that supported the V8 uRISCCPU which is the heart of the excellent single-use digital PV2 cameras,available from RITZ and CVS Pharmacies for $20 at the time of this writing.WLA is strong featurewise, so I thought that modding the WLA code wouldprovide a great assembler with very little time cost to me.BTW, for more information on the most excellent PV2 camera, check outthe threads at http://www.linux-hacker.net/cgi-bin/UltraBoard/UltraBoard.pl?Action=ShowBoard&Board=camerasThis assembler is my attempt to create a dev community interested in extendingthe firmware within camera itself - it's hard to write large programs whenyou're hand-assembling code.One last note - this documentation is based heavily on the originalWLA docs, with information not pertainent to the PV2/v8uRISC being removed.However, there are still some game-references in the Directive examples, anda lot of the sample assembly in this doc isn't v8uRISC code. This is a smallprice to pay for such a strong assembler, but if it really bugs you, feelfree to update this doc and send the results to billwiley777@gmail.com!----------------------------------------------2.... Assembler Directives----------------------------------------------Here are the supported directives (with examples) in PV2ASS:.ASC "HELLO WORLD!".ASCTABLE.ASCIITABLE.ASM.BR.BREAKPOINT.BYT 100, $30, %1000, "HELLO WORLD!".DB 100, $30, %1000, "HELLO WORLD!".DBCOS 0.2, 10, 3.2, 120, 1.3.DBRND 20, 0, 10.DBSIN 0.2, 10, 3.2, 120, 1.3.DEFINE IF $FF0F.DEF IF $FF0F.DS 256, $10.DSB 256, $10.DSTRUCT waterdrop INSTANCEOF water DATA "tingle", 40, 120.DSW 128, 20.DW 16000, 10, 255.DWCOS 0.2, 10, 3.2, 1024, 1.3.DWRND 20, 0, 10.DWSIN 0.2, 10, 3.2, 1024, 1.3.ELSE.EMPTYFILL $C9.ENDASM.ENDB.ENDE.ENDIF.ENDM.ENDME.ENDR.ENDRO.ENDS.ENDST.ENUM $C000.EQU IF $FF0F.FAIL.FCLOSE FP_DATABIN.FOPEN "data.bin" FP_DATABIN.FREAD FP_DATABIN DATA.FSIZE FP_DATABIN SIZE.IF DEBUG == 2.IFDEF IF.IFDEFM \2.IFEQ DEBUG 2.IFEXISTS "main.s".IFGR DEBUG 2.IFGREQ DEBUG 1.IFLE DEBUG 2.IFLEEQ DEBUG 1.IFNDEF IF.IFNDEFM \2.IFNEQ DEBUG 2.INCBIN "sorority.bin".INCDIR "/usr/programming/gb/include/".INCLUDE "cgb_hardware.i".INPUT NAME.MACRO TEST.ORG $150.OUTNAME "other.o".PRINTT "Here we are...\n".PRINTV DEC DEBUG+1.REDEFINE IF $F.REDEF IF $F.REPEAT 6.REPT 6.SEED 123.SECTION "Init" FORCE.SHIFT.STRUCT enemy_object.SYM SAUSAGE.SYMBOL SAUSAGE.UNDEFINE DEBUG.UNDEF DEBUG.WORD 16000, 10, 255Descriptions:----.ASM----Tells PV2 to start assembling. Use .ASM to continue the work which has beendisabled with .ENDASM. .ASM and .ENDASM can be used to mask away big blocksof code. This is analogous to the ANSI C -comments (/*...*/), but .ASM and.ENDASM can be nested, unlike the ANSI C -counterpart.This is not a compulsory directive.-------.ENDASM-------Tells PV2 to stop assembling. Use .ASM to continue the work.This is not a compulsory directive.----------------.DBRND 20, 0, 10----------------Defines bytes, just like .DSB does, only this time they are filled with(pseudo) random numbers. We use stdlib's rand() to generate the randomnumbers. If you want to seed the random number generator, use .SEED.The first parameter (20 in the example) defines the amount of numberswe want to generate. The next two tell the range of the random numbers,i.e. min and max.Here's how it works:.DBRND A, B, Cfor (i = 0; i < A; i++)output_data((rand() % (C-B+1)) + B);This is not a compulsory directive.----------------.DWRND 20, 0, 10----------------Analogous to .DBRND (but defines words).This is not a compulsory directive.-----------------------------.DBCOS 0.2, 10, 3.2, 120, 1.3-----------------------------Defines bytes just like .DSB does, only this time they are filled withcosine data. .DBCOS takes five arguments.The first argument is the starting angle. Angle value ranges from 0 to359.999..., but you can supply PV2 with values that are out of the range -PV2 fixes them ok. The value can be integer or float.The second one descibes the amount of additional angles. The examplewill define 11 angles.The third one is the adder value which is added to the angle value whennext angle is calculated. The value can be integer or float.The fourth and fifth ones can be seen from the pseudo code below, whichalso describes how .DBCOS works. The values can be integer or float.Remember that cos (and sin) here returns values ranging from -1 to 1..DBCOS A, B, C, D, Efor (B++; B > 0; B--) {output_data((D * cos(A)) + E)A = keep_in_range(A + C)}This is not a compulsory directive.-----------------------------.DBSIN 0.2, 10, 3.2, 120, 1.3-----------------------------Analogous to .DBCOS, but does sin() instead of cos().This is not a compulsory directive.------------------------------.DWCOS 0.2, 10, 3.2, 1024, 1.3------------------------------Analogous to .DBCOS (but defines words).This is not a compulsory directive.------------------------------.DWSIN 0.2, 10, 3.2, 1024, 1.3------------------------------Analogous to .DBCOS (but defines words and does sin() instead of cos()).This is not a compulsory directive.--------------.EMPTYFILL $C9--------------This byte is used in filling the unused areas of memory. EMPTYFILLdefaults to $00.This is not a compulsory directive.--------------------------------------.INCDIR "/usr/programming/pv2/include/"--------------------------------------Changes the current include root directory. Use this to specify maindirectory for the following .INCLUDE and .INCBIN directives.If you want to change to the current working directory (PV2 also defaultsto this), use.INCDIR ""This is not a compulsory directive.-------------------------.INCLUDE "cgb_hardware.i"-------------------------Includes the specified file to the source file. If the file's not foundin the .INCDIR directory, PV2 tries to find it in the current workingdirectory.This is not a compulsory directive.----------------------.INCBIN "sorority.bin"----------------------Includes the specified data file into the source file. .INCBIN cachesall files into memory, so you can .INCBIN any data file millions oftimes, but it is loaded from hard drive only once.You can optionally use SWAP after the file name, e.g.,.INCBIN "kitten.bin" SWAP.INCBIN data is divided into blocks of two bytes, and inside every blockthe bytes are exchanged (like "SWAP r" does to nibbles). This requires thatthe size of the file is even.You can also force PV2 to skip n bytes from the beginning of the fileby writing for example:.INCBIN "kitten.bin" SKIP 4Four bytes are skipped from the beginning of kitten.bin and the restis incbinned.It is also possible to incbin only n bytes from a file:.INCBIN "kitten.bin" READ 10Will read ten bytes from the beginning of kitten.bin.You can also force PV2 to create a definition holding the sizeof the file:.INCBIN "kitten.bin" FSIZE size_of_kittenAnd you can combine all these four commands:.INCBIN "kitten.bin" SKIP 10 READ 8 SWAP FSIZE size_of_kittenThis example shows how to incbin eight bytes (swapped) after skipping10 bytes from the beginning of file "kitten.bin", and how to get thesize of the file into a definition label "size_of_kitten". Note that theorder of the extra commands is important.If the file's not found in the .INCDIR directory, PV2 tries to find itin the current working directory.This is not a compulsory directive.-----------.INPUT NAME-----------.INPUT is much like any Basic-language input: .INPUT asks the userfor a value or string. After .INPUT is the variable name used to storethe data..INPUT works like .REDEFINE, but the user gets to type in the data.Here are few examples how to use input:.PRINTT "The name of the TFT pic? ".INPUT NAME.NAME NAME....PRINTT "Give the .DB amount.\n".INPUT S.PRINTT "Give .DB data one at a time.\n".REPEAT S.INPUT B.DB B.ENDR...This is not a compulsory directive.-----.FAIL-----Terminates the compiling process.This is not a compulsory directive.------------------.FCLOSE FP_DATABIN------------------Closes the filehandle FP_DATABIN.This is not a compulsory directive.----------------------------.FOPEN "data.bin" FP_DATABIN----------------------------Opens the file "data.bin" for reading and associates the filehandle withname "FP_DATABIN".This is not a compulsory directive.----------------------.FREAD FP_DATABIN DATA----------------------Reads one byte from "FP_DATABIN" and creates a definition called "DATA"to hold it. "DATA" is an ordinary definition label, so you can .UNDEFINE it.Here's an example on how to use .FREAD:.fopen "data.bin" fp.fsize fp t.repeat t.fread fp d.db d+26.endr.undefine t, dThis is not a compulsory directive.----------------------.FSIZE FP_DATABIN SIZE----------------------Creates a definition called "SIZE", which holds the size of the fileassociated with the filehandle "FP_DATABIN". "SIZE" is an ordinarydefinition label, so you can .UNDEFINE it.This is not a compulsory directive.-----------.MACRO TEST-----------Begins a macro called 'TEST'.You can use '\@' inside a macro to e.g., separate a label from the othermacro 'TEST' occurrences. '\@' is replaced with an integer numberindicating the amount of times the macro has been called previously soit is unique to every macro call. '\@' can also be used inside stringsinside a macro or just as a plain value. Look at the following examplesfor more information.Also, if you want to use macro arguments in e.g., calculation, you cantype '\X' where X is the number of the argument. Another way to referto the arguments is to use their names given in the definition of themacro (see the examples for this).Remember to use .ENDM to finish the macro definition. Note that youcannot use .INCLUDE inside a macro. Note that PV2's macros are in factmore like procedures than real macros, because PV2 doesn't substitutemacro calls with macro data. Instead PV2 jumps to the macro when itencounters a macro call at compile time.You can call macros from inside a macro. Note that the preprocessordoes not expand the macros. PV2 traverses through the code according tothe macro calls, so macros really define a very simple programminglanguage.Here are some examples:.MACRO NOPMONSTER.REPT 32 ; it's just an example...NOP.ENDR.ENDM.MACRO LOAD_ABCDLD A, \1LD B, \2LD C, \3LD D, \4NOPMONSTERLD HL, 1<<\1.INCBIN \5.ENDM.MACRO QUEENQUEEN\@:LD A, \1LD B, \1CALL QUEEN\@.DB "\@", 0 ; will translate into a zero terminated string; holding the amount of macro QUEEN calls..DB "\\@", 0 ; will translate into a string containing; \@..DB \@ ; will translate into a number indicating; the amount of macro QUEEN calls..ENDM.MACRO LOAD_ABCD_2 ARGS ONE, TWO, THREE, FOUR, FIVELD A, ONELD B, TWOLD C, THREELD D, FOURNOPMONSTERLD HL, 1< \2, etc.)..SHIFT can thus only be used inside a .MACRO.This is not a compulsory directive.---------.ORG $150---------Defines the starting address. The default starting address is $0This is not a compulsory directive.------------.DS 256, $10------------.DS is an alias for .DSB.This is not a compulsory directive.-------------.DSB 256, $10-------------Defines 256 bytes of $10.This is not a compulsory directive.----------------------------------------------------------.DSTRUCT waterdrop INSTANCEOF water DATA "tingle", 40, 120----------------------------------------------------------Defines an instance of struct water, called waterdrop, and fillsit with the given data. Before calling .DSTRUCT we must have definedthe structure, and in this example it could be like:.STRUCT watername ds 8age dbweight dw.ENDSTNote that the keywords INSTANCEOF and DATA are optional, so.DSTRUCT waterdrop, water, "tingle", 40, 120also works. Also note that PV2 fills the missing bytes with the datadefined with .EMPTYFILL, or $00 if no .EMPTYFILL has been issued.In this example you would also get the following labels:waterdropwaterdrop.namewaterdrop.agewaterdrop.weightThis is not a compulsory directive.------------.DSW 128, 20------------Defines 128 words (two bytes) of 20.This is not a compulsory directive.-----------------------------------.DB 100, $30, %1000, "HELLO WORLD!"-----------------------------------Defines bytes.This is not a compulsory directive.------------------------------------.BYT 100, $30, %1000, "HELLO WORLD!"------------------------------------.BYT is an alias for .DB.This is not a compulsory directive.------------.SYM SAUSAGE------------PV2 treats symbols ("SAUSAGE" in this example) like labels, but theyonly appear in the symbol files PV2LINK outputs. Useful for finding outthe location where PV2LINK puts data.This is not a compulsory directive.---------------.SYMBOL SAUSAGE---------------.SYMBOL is an alias for .SYM.This is not a compulsory directive.---.BR---Inserts a breakpoint that behaves like a .SYM without a name. Breakpointscan only be seen in PV2LINK's symbol file.This is not a compulsory directive.-----------.BREAKPOINT-----------.BREAKPOINT is an alias for .BR.This is not a compulsory directive.-----------.ASCIITABLE-----------.ASCIITABLE's only purpose is to provide character mapping for .ASC.Take a look at the example:.ASCIITABLEMAP "A" TO "Z" = 0MAP "!" = 90.ENDAHere we set such a mapping that character 'A' is equal to 0, 'B'is equal to 1, 'C' is equal to 2, and so on, and '!' is equal to 90.After you've given the .ASCIITABLE, use .ASC to define bytes usingthis mapping (.ASC is an alias for .DB, but with .ASCIITABLE mapping).For example, .ASC "AB!" would define bytes 0, 1 and 90.Note that the following works as well:.ASCIITABLEMAP 'A' TO 'Z' = 0MAP 65 = 90.ENDAAlso note that the characters that are not given any mapping in.ASCIITABLE map to themselves (i.e., 'A' maps to 'A', etc.).This is not a compulsory directive.---------.ASCTABLE---------.ASCTABLE is an alias for .ASCIITABLE.This is not a compulsory directive.-------------------.ASC "HELLO WORLD!"-------------------.ASC is an alias for .DB, but if you use .ASC it will remapthe characters using the mapping given via .ASCIITABLE.This is not a compulsory directive.------------------.DW 16000, 10, 255------------------Defines words (two bytes each). .DW takes only numbers andcharacters as input, not strings.This is not a compulsory directive.--------------------.WORD 16000, 10, 255--------------------.WORD is an alias for .DW.This is not a compulsory directive.----------------.DEFINE IF $FF0F----------------Assigns a number or a string to a definition label.By default all defines are local to the file where they arepresented. If you want to make the definition visible to all thefiles in the project, use .EXPORT.Here are some examples:.DEFINE X 1000.DEFINE FILE "PD-03.TFT".DEFINE TXT1 "hello and welcome", 1, "to the PV2", 0.DEFINE BYTES 1, 2, 3, 4, 5.DEFINE COMPUTATION X+1.DEFINE DEFAULTVAll definitions with multiple values are marked as data strings,and .DB is about the only place where you can later on use them..DEFINE BYTES 1, 2, 3, 4, 5.DB 0, BYTES, 6is the same as.DB 0, 1, 2, 3, 4, 5, 6If you omit the definition value (in our example "DEFAULTV"), PV2will default to 0.Note that you must do your definition before you use it, otherwisePV2 will use the final value of the definition. Here's an exampleof this:.DEFINE AAA 10.DB AAA ; will be 10..REDEFINE AAA 11but.DB AAA ; will be 11..DEFINE AAA 10.REDEFINE AAA 11You can also create definitions on the command line. Here's anexample of this:pv2ass -vl -DMOON -DNAME=john -DPRICE=100 -DADDRESS=$100 math.sMOON's value will be 0, NAME is a string definition with value "john",PRICE's value will be 100, and ADDRESS's value will be $100.Note that.DEFINE AAA = 10 ; the same as ".DEFINE AAA 10".works as well.This is not a compulsory directive.-------------.DEF IF $FF0F-------------.DEF is an alias for .DEFINE.This is not a compulsory directive.-------------.EQU IF $FF0F-------------.EQU is an alias for .DEFINE.This is not a compulsory directive.----------------.REDEFINE IF $0F----------------Assigns a new value or a string to an old definition. If thedefinition doesn't exist, .REDEFINE performs .DEFINE's work.When used with .REPT REDEFINE helps creating tables:.DEFINE CNT 0.REPT 256.DB CNT.REDEFINE CNT CNT+1.ENDRThis is not a compulsory directive.-------------.REDEF IF $0F-------------.REDEF is an alias for .REDEFINE.This is not a compulsory directive.--------------.IF DEBUG == 2--------------If the condition is fulfilled the following piece of code isacknowledged until .ENDIF/.ELSE occurs in the text, otherwiseit is skipped. Operands must be immediate values or strings.The following operators are supported:< - less than<= - less or equal to> - greater than>= - greater or equal to== - equals to!= - doesn't equal toAll IF (yes, including .IFDEF, .IFNDEF, etc) directives can benested.This is not a compulsory directive.---------.IFDEF IF---------If "IF" is defined, then the following piece of code is acknowledgeduntil .ENDIF/.ELSE occurs in the text, otherwise it is skipped.This is not a compulsory directive.------------------.IFEXISTS "main.s"------------------If "main.s" file can be found, then the following piece of code isacknowledged until .ENDIF/.LESE occurs in the text, otherwise it isskipped.By writing the following few lines you can include a file if it existswithout breaking the compiling loop if it doesn't exist..IFEXISTS FILE.INCLUDE FILE.ENDIFThis is not a compulsory directive.---------------.UNDEFINE DEBUG---------------Removes the supplied definition label from system. If there is nosuch label as given no error is displayed as the result would be thesame.You can undefine as many definitions as you wish with one .UNDEFINE:.UNDEFINE NUMBER, NAME, ADDRESS, COUNTRY.UNDEFINE NAME, AGEThis is not a compulsory directive.------------.UNDEF DEBUG------------.UNDEF is an alias for .UNDEFINE.This is not a compulsory directive.----------.IFNDEF IF----------If "IF" is not defined, then the following piece of code is acknowledgeduntil .ENDIF/.ELSE occurs in the text, otherwise it is skipped.This is not a compulsory directive.----------.IFDEFM \2----------If the specified argument is defined (argument number two, in the example),then the following piece of code is acknowledged until .ENDIF/.ELSE occursin the macro, otherwise it is skipped.This is not a compulsory directive. .IFDEFM works only inside a macro.-----------.IFNDEFM \2-----------If the specified argument is not defined, then the following piece ofcode is acknowledged until .ENDIF/.ELSE occurs in the macro, otherwiseit is skipped.This is not a compulsory directive. .IFNDEFM works only inside a macro.-------------.IFEQ DEBUG 2-------------If the value of DEBUG equals to 2, then the following piece of code isacknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.Both arguments can be computations, defines or immediate values.This is not a compulsory directive.--------------.IFNEQ DEBUG 2--------------If the value of DEBUG doesn't equal to 2, then the following piece ofcode is acknowledged until .ENDIF/.ELSE occurs in the text, otherwise it isskipped. Both arguments can be computations, defines or immediatevalues.This is not a compulsory directive.-------------.IFLE DEBUG 2-------------If the value of DEBUG is less than 2, then the following piece of code isacknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.Both arguments can be computations, defines or immediate values.This is not a compulsory directive.---------------.IFLEEQ DEBUG 2---------------If the value of DEBUG is less or equal to 2, then the following piece of code isacknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.Both arguments can be computations, defines or immediate values.This is not a compulsory directive.-------------.IFGR DEBUG 2-------------If the value of DEBUG is greater than 2, then the following piece of code isacknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.Both arguments can be computations, defines or immediate values.This is not a compulsory directive.---------------.IFGREQ DEBUG 2---------------If the value of DEBUG is greater or equal to 2, then the following piece of code isacknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.Both arguments can be computations, defines or immediate values.This is not a compulsory directive.-----.ELSE-----If the previous .IFxxx failed then the following text until.ENDIF is acknowledged.This is not a compulsory directive.------.ENDIF------This terminates any .IFxxx directive.This is not a compulsory directive, but if you use any .IFxxx thenyou need also to apply this.---------.REPEAT 6---------Repeats the text enclosed between ".REPEAT x" and ".ENDR" x times (6 inthis example). You can use .REPEATs inside .REPEATs. 'x' must be >= 0.This is not a compulsory directive.-------.REPT 6-------.REPT is an alias for .REPEAT.This is not a compulsory directive.-----.ENDR-----Ends the repetition.This is not a compulsory directive, but when .REPEAT is used this one isrequired to terminate it.-----------.ENUM $C000-----------Starts enumeration from $C000. Very useful for defining variables.To start a descending enumeration, put "DESC" after the startingaddress. PV2 defaults to "ASC" (ascending enumeration).You can also add "EXPORT" after these if you want to export allthe generated definitions automatically.Here's an example of .ENUM:....STRUCT mon ; check out the documentation onname ds 2 ; .STRUCTage db.ENDST.ENUM $A000_scroll_x DB ; db - define byte (byt and byte work also)_scroll_y DBplayer_x: DW ; dw - define word (word works also)player_y: DWmap_01: DS 16 ; ds - define size (bytes)map_02 DSB 16 ; dsb - define size (bytes)map_03 DSW 8 ; dsw - define size (words)monster INSTANCEOF mon 3 ; three instances of structure mondragon INSTANCEOF mon ; one mon.ENDE...Previous example transforms into following definitions:.DEFINE _scroll_x $A000.DEFINE _scroll_y $A001.DEFINE player_x $A002.DEFINE player_y $A004.DEFINE map_01 $A006.DEFINE map_02 $A016.DEFINE map_03 $A026.DEFINE monster $A036.DEFINE monster.name $A036.DEFINE monster.age $A038.DEFINE monster.1 $A036.DEFINE monster.1.name $A036.DEFINE monster.1.age $A038.DEFINE monster.2 $A039.DEFINE monster.2.name $A039.DEFINE monster.2.age $A03B.DEFINE monster.3 $A03C.DEFINE monster.3.name $A03C.DEFINE monster.3.age $A03E.DEFINE dragon $A03F.DEFINE dragon.name $A03F.DEFINE dragon.age $A041DB, DW, DS, DSB, DSW and INSTANCEOF can also be in lowercase. Youcan also use a dotted version of the symbols, but it doesn't advancethe memory address. Here's an exmple:.ENUM $C000 DESC EXPORTbigapple_h dbbigapple_l dbbigapple: .dw.ENDEAnd this is what is generated:.DEFINE bigapple_h $BFFF.DEFINE bigapple_l $BFFE.DEFINE bigapple $BFFE.EXPORT bigapple, bigapple_l, bigapple_hThis way you can generate a 16bit variable address along with pointersto its parts.If you want more flexible variable positioning, take a look at.RAMSECTIONs.This is not a compulsory directive.-----.ENDE-----Ends the enumeration.This is not a compulsory directive, but when .ENUM is used this one isrequired to terminate it.--------------------.STRUCT enemy_object--------------------Begins the definition of a structure. These structures can be placedinside RAMSECTIONs and ENUMs. Here's an example:.STRUCT enemy_objectid dw ; the insides of a .STRUCT are 1:1 like in .ENUMx db ; except that no structs inside structs arey db ; allowed.data ds 10info dsb 16stats dsw 4.ENDSTThis also creates a definition "_sizeof_[struct name]", in our examplethis would be "_sizeof_enemy_object", and the value of this definitionis the size of the object, in bytes (2+1+1+10+16+4*2 = 38 in the example).You'll get the following definitions as well:enemy_object.id (== 0)enemy_object.x (== 2)enemy_object.y (== 3)enemy_object.data (== 4)enemy_object.info (== 14)enemy_object.stats (== 30)After defining a .STRUCT you can create an instance of it in a .RAMSECTION /.ENUM by typingINSTANCEOF [optional, the number of structures]Here's an example:.RAMSECTION "enemies" BANK 4 SLOT 4enemies INSTANCEOF enemy_object 4enemyman INSTANCEOF enemy_objectenemyboss INSTANCEOF enemy_object.ENDSThis will create labels like "enemies", "enemies.id", "enemies.x", "enemies.y"and so on. Label "enemies" is followed by four "enemy_object" structures,and only the first one is labeled. After there four come "enemyman" and"enemyboss" instances.Take a look at the documentation on .RAMSECTION & .ENUM, they have moreexamples of how you can use .STRUCTs.A WORD OF WARNING: Don't use labels b, B, w and W inside a struct as e.g.,PV2 sees enemy.b as a byte sized reference to enemy. All other labels shouldbe safe.lda enemy1.b ; load a byte from zeropage address enemy1 or from the address; of enemy1.b??? i can't tell you, and PV2 can't tell you...This is not a compulsory directive.------.ENDST------Ends the structure definition.This is not a compulsory directive, but when .STRUCT is used this one isrequired to terminate it.---------.SEED 123---------Seeds the random number generator.This is not a compulsory directive. The random number generator isinitially seeded with the output of time(), which is, according tothe manual, "the time since the Epoch (00:00:00 UTC, January 1, 1970),measured in seconds". So if you don't .SEED the random number generatoryourself with a constant value, .DBRND and .DWRND give you differentvalues every time you run PV2.---------------------.SECTION "Init" FORCE---------------------Section is a continuous area of data which is placed into the outputfile according to the section type and .ORG directivevalues.The example begins a section called "Init". Before a section can bedeclared, .ORG must be used unless PV2 is in library fileoutput mode. Library file's sections must all be FREE ones. .BANK tellsthe bank number where this section will be later relocated into. .ORGtells the offset for the relocation from the beginning of .BANK.You can supply the preferred section size (bytes) inside the sectionname string. Here's an example:.SECTION "Init_100" FREEwill create a section ("Init") with size of 100 bytes, unless the actualdata overflows from the section, in which case the section size isenlarged to contain all the data. Note that the syntax for explicitsection size defining is: "NAME_X", where "NAME" is the name of thesection and "X" is the size (decimal or hexadecimal value).You can also give the size of the section the following way:.SECTION "Init" SIZE 100 FREEIt's possible to force PV2LINK to align the FREE, SEMIFREE and SUPERFREEsections by giving the alignment as follows:.SECTION "Init" SIZE 100 ALIGN 4 FREEAnd if you want that PV2 returns the ORG to what it was before issuingthe section, put RETURNORG at the end of the parameter list:.SECTION "Init" SIZE 100 ALIGN 4 FREE RETURNORGBy default PV2 advances the ORG, so, for example, if your ORG was $0 beforea section of 16 bytes, then the ORG will be 16 after the section.Note also that if your section name begins with double underlines (e.g.,"__UNIQUE_SECTION!!!") the section will be unique in the sense thatwhen PV2LINK recieves files containing sections which share the samename, PV2LINK will save only the first of them for further processing,all others are deleted from memory with corresponding labels, referencesand calculations.If a section name begins with an exclamation mark ('!') it tellsPV2LINK to not to drop it, even if you use PV2LINK's ability to discardall unreferenced sections and there are no references to the section.FORCE after the name of the section tells PV2 that the section _must_ beinserted so it starts at .ORG. FORCE can be replaced with FREE whichmeans that the section can be inserted somewhere in the defined bank,where there is room. You can also use OVERWRITE to insert the sectioninto the memory regardless of data collisions. Using OVERWRITE you caneasily patch an existing ROM image just by .BACKGROUND'ing the ROM image andinserting OVERWRITE sections into it. SEMIFREE sections are alsopossible and they behave much like FREE sections. The only differenceis that they are positioned somewhere in the bank starting from .ORG.SUPERFREE sections are also available, and they will be positioned intothe first suitable place inside the first suitable bank (candidatesfor these suitable banks have the same size with the slot of the section,no other banks are considered). You can also leave away the typespecifier as the default type for the section is FREE.You can name the sections as you wish, but there is one special name.A section called "BANKHEADER" is placed in the front of the bankwhere it is defined. These sections contain data that is not in thememory map of the machine, so you can't refer to the data of aBANKHEADER section, but you can write references to outside. So nolabels inside BANKHEADER sections. These special sections are usefulwhen writing e.g., MSX programs. Note that library files don't takeBANKHEADER sections.Here's an example of a "BANKHEADER" section:.BANK 0.ORG 0.SECTION "BANKHEADER".DW MAIN.DW VBI.ENDS.SECTION "Program"MAIN: CALL MONTY_ON_THE_RUNVBI: PUSH HL...POP HLRETI.ENDSHere's an example of an ordinary section:.BANK 0.ORG $150.SECTION "Init" FREEDILD SP, $FFFESUB ALD ($FF00+R_IE), A.ENDSThis tells PV2 that a FREE section called "Init" must be located somewherein bank 0. If you replace FREE with SEMIFREE the section will be insertedsomewhere in the bank 0, but not in the $0-$14F area. If you replace FREEwith SUPERFREE the section will be inserted somewhere in theHere's the order in which PV2 writes the sections:1. FORCE2. SEMIFREE & FREE3. SUPERFREE4. OVERWRITEBefore the sections are inserted into the output file, they are sorted bysize, so that the biggest section gets processed first and the smallestlast.You can also create a RAM section. For more information about them, pleaseread the .RAMSECTION directive explanation.This is not a compulsory directive.--------------.EXPORT work_x--------------Exports the definition "work_x" to outside world. Exported definitions arevisible to all object files and libraries in the linking procedure. Notethat you can only export value definitions, not string definitions.You can export as many definitions as you wish with one .EXPORT:.EXPORT NUMBER, NAME, ADDRESS, COUNTRY.EXPORT NAME, AGEThis is not a compulsory directive.--------------------------.PRINTT "Here we are...\n"--------------------------Prints the given text into stdout. Good for debugging stuff. PRINTT takesonly a string as argument, and the only supported formatting symbol is '\n'(line feed).This is not a compulsory directive.-------------------.PRINTV DEC DEBUG+1-------------------Prints the value of the supplied definition or computation into stdout.Computation must be solvable at the time of printing (just like definitionsvalues). PRINTV takes two parameters. The first describes the type of theprint output. "DEC" means decimal, "HEX" means hexadecimal.Use PRINTV with PRINTT as PRINTV doesn't print linefeeds, only the result.Here's an example:.PRINTT "Value of \"DEBUG\" = $".PRINTV HEX DEBUG.PRINTT "\n"This is not a compulsory directive.------------------.OUTNAME "other.o"------------------Changes the name of the output file. Here's and example:pv2ass -o test.swould normally output "test.o", but if you had written.OUTNAME "new.o"somewhere in the code PV2 would write the output to new.o instead.This is not a compulsory directive.----------------------------------------------3.... Assembler Syntax----------------------------------------------3.1. Case SensitivityPV2ASS is case sensitive, so be careful.3.2. CommentsComments begin with ';' or '*' and end along with the line. ';' can beused anywhere, but '*' can be placed only at the beginning of a new line.PV2ASS also has ANSI-C -like commenting. This means you can start amultiline comment with "/*" and end it with "*/". Additionally, it has.ASM and .ENDASM directives. These function much like ANSI-C comments, butunlike the ANSI-C comments these can be nested.3.3. LabelsLabels are ordinary strings (which can also end to a ':'). Labels startingwith "_" are considered to be local labels and do not show outside sectionswhere they were defined, or outside object files, if they were not definedinside a section.Here are few examples of different labels:VBI_IRQ:VBI_IRQ2_VBI_LOOP:main:3.4. Number Types1000 - decimal$100 - hexadecimal100h - hexadecimal%100 - binary'x' - characterRemember that if you use the suffix 'h' to give a hexadecimal value,and the value begins with an alphabet, you must place a zero in front of itso PV2 knows it's not a label (e.g., "0ah" instead of "ah").3.5. StringsStrings begin with and end to '"'. Note that no 0 is inserted to indicatethe termination of the string like in e.g., ANSI C. You'll have to do ityourself. You can place quotation marks inside strings the way Cpreprocessors accept them.Here are some examples of strings:"Hello world!""He said: \"Please, kiss me honey.\""----------------------------------------------4.... Error Messages----------------------------------------------There are quite a few of them in PV2ASS, but most of them are not veryinformative. Coder beware.----------------------------------------------5.... Bugs----------------------------------------------Report bugs to billwiley777@gmail.com----------------------------------------------6.... Temporary Files----------------------------------------------Note that PV2 will generate two temporary files while it works. Both filesare placed into the current working directory.The filenames are ".wla%PID%a" and ".wla%PID%b" (%PID% is the process id).When PV2 finishes its work these two files are deleted as they serveof no further use.----------------------------------------------7.... Compiling----------------------------------------------7.1. Compiling Object FilesTo compile an object file use:"pv2ass -[itvx]o [DEFINITIONS] [OUTPUT FILE]"These object files can be linked together (or with library files) laterwith "pv2link".Name object files so that they can be recognized as object files. Normalsuffix is ".o" (PV2 default). This can also be changed with .OUTNAME.With object files you can reduce the amount of compiling when editingsmall parts of the program. Note also the possibility of using locallabels (starting with "_").Note! When you compile objects, group 1 directives are saved for linkingtime, when they are all compared and if they differ, an error message isshown. It is advisable to use something like an include file to hold allthe group 1 directives for that particular project and include it to everyobject file.Here are some examples of definitions:-DIEXIST-DDAY=10-DBASE=$10-DNAME=elvisAnd here's an PV2 example creating definitions on the command line:pv2ass -o -DDEBUG -DVERBOSE=5 -DNAME="math v1.0" math.sDEBUG's value will be 0, VERBOSE's 5 and NAME is a string definitionwith value "math v1.0".7.2. Compiling Library FilesTo compile a library file use:"pv2ass -[itvx]l [DEFINITIONS] [OUTPUT FILE]"Name object files so that they can be recognized as library files. Normalsuffix is ".lib" (PV2 default).With library files you can reduce the amount of compiling. Library filesare meant to hold general functions that can be used in different projects.Note also the possibility of using local labels (starting with "_").Library files consist only of FREE sections.----------------------------------------------8... Linking----------------------------------------------After you have produced one or more object files and perhaps some libraryfiles, you might want to link them together to produce a ROM image / programfile. "pv2link" is the program you use for that. Here's how you use it:"pv2link [-divsS]{b/r} "Choose 'b' for program file or 'r' for ROM image linking.Link file is a text file that contains information about the files you wantto link together. Here's the format:1. You must define the group for the files. Put the name of the groupinside brackets. Valid group definitions are[objects][libraries][header][footer][definitions]2. Start to list the file names.[objects]main.ovbi.olevel_01.o...3. Give parameters to the library files:[libraries]bank 0 slot 1 speed.libbank 4 slot 2 map_data.lib...Here you can also use "base" to define the 65816 CPU bank number(like .BASE works in PV2):[libraries]bank 0 slot 1 base $80 speed.libbank 4 slot 2 base $80 map_data.lib...You must tell PV2LINK the bank and the slot for the library files.4. If you want to use header and/or footer in your project,you can type the following:[header]header.dat[footer]footer.dat5. If you want to make value definitions, here's your chance:[definitions]debug 1max_str_len 128start $150...If flag 'v' is used, PV2LINK displays information about ROM file after asuccesful linking.If flag 'd' is used, PV2LINK discards all unreferenced FREE and SEMIFREEsections. This way you can link big libraries to your project and PV2LINKwill choose only the used sections, so you won't be linking any dead code/data.If flag 's' is used, a symbol information file is created.If flag 'S' is used, a symbol information file with breakpoints is created.If flag 'i' is given, PV2LINK will write list files. Note that you mustcompile the object and library files with -i flag as well. Otherwise PV2LINKhas no extra information it needs to build list files. Here is an example ofa list file: Let's assume you've compiled a source file called "main.s" usingthe 'i' flag. After you've linked the result also with the 'i' flag PV2LINKhas created a list file called "main.lst". This file contains the sourcetext and the result data the source compiled into. List files are good fordebugging.Make sure you don't create duplicate labels in different places in thememory map as they break the linking loop. Duplicate labels are allowed whenthey overlap each other in the destination machine's memory. Look at thefollowing example:....BANK 0.ORG $150...LD A, 1CALL LOAD_LEVEL...LOAD_LEVEL:LD HL, $2000LD (HL), ACALL INIT_LEVELRET.BANK 1.ORG 0INIT_LEVEL:...RET.BANK 2.ORG $0INIT_LEVEL:...RET...Here duplicate INIT_LEVEL labels are accepted as they both point to thesame memory address (in the program's point of view).----------------------------------------------9... Arithmetics----------------------------------------------PV2 is able to solve really complex calculations like-((HELLO / 2) | 3)skeletor_end-skeletor10/2.5so you can write something likeLD HL, data_end-dataLD A, (pointer + 1)CP (TEST + %100) & %10101010PV2LINK also has this ability so it can compute the pending calculationsPV2 wasn't able to solve.The following operators are valid:(, ), | (or), & (and), ^ (power), << (shift left), >> (shift right), +, -,# (modulo), ~ (xor), *, /, < (get the low byte) and > (get the high byte).Note that you can do NOT using XOR:VALUE_A ~ $FF = 8bit NOTVALUE_B ~ $FFFF = 16bit NOTPV2 computes internally with real numbers so (5/2)*2 produces 5, not 4.----------------------------------------------10... PV2ASS Flags----------------------------------------------Here are short descriptions for the flags you can give to PV2ASS:You can supply PV2ASS with some (or all or none) of the following option flags.i - Add list file information. Adds extra information to the output soPV2LINK can produce list files.M - PV2 generates makefile rules describing the dependencies of the mainsource file. Use only with flags 'o' and 'l'.q - Quiet mode. .PRINT* -directives output nothing.t - Test compile. Doesn't output any files.v - Verbose mode. Shows a lot of information about the compiling process.x - Extra compile time definitions. PV2 does extra work by creatingfew helpful definitions on the fly.One (and only one) of the following command flags must be defined.l - Output a library file.o - Output an object file.Examples:[seravy@localhost tbp]# pv2ass -voi testa.s[seravy@localhost tbp]# pv2ass -oM testa.s[seravy@localhost tbp]# pv2ass -l testb.s testb.libNote that the first example produces file named "testa.o".----------------------------------------------11... Good things to know about PV2ASS----------------------------------------------- Is 64 bytes too little for a string (file names, labels, definition labels,etc)? Check out "MAX_NAME_LENGTH" in defines.h.- PV2ASS preprocessor doesn't expand macros and repetitions. Those are actuallytraversed in the assembling phase.- PV2ASS's source code is mainly a huge mess, but PV2LINK is quite wellstructured and written. So beware!- Do not write ".E" into your sources as PV2ASS uses it internally to markthe end of a file.----------------------------------------------12... Legal Note----------------------------------------------PV2ASS and PV2LINK is licensed as GPL software, as are any helper programs.Code in the examples section is licensed under the BSD license.
Go to most recent revision | Compare with Previous | Blame | View Log
