Jump to content

DZ-Jay

Members
  • Content Count

    13,060
  • Joined

  • Last visited

  • Days Won

    21

Posts posted by DZ-Jay


  1. I have defined 14 new fonts :-)

     

    I have attached the updated custom font file

     

     

    what is still NOT WORKING is that If I add a tile I lost one more letter.... I can print only 23 custom chars... no matter what number I write in DEFINE_GRAM_BLOCK

     

    for each new font I add I lost one letter at the end of the list...

     

    Let me clarify something. Adding characters to the set means that you'll have to change the format word formula. Adding them at the top means you are offsetting the position of the "A" character (ASCII 65) down, which means that you have to add that number of cards to the base card.

     

    Also, you'll need to change the total size of the GRAM block, so you need to alter the call to DEFINE_GRAM_BLOCK to include how many tiles you need.

     

    Can you post the code that you use to define the GRAM block, to load it, and to display it? The "stats" seem to suggest that no GRAM is being used. That doesn't sound right, unless you are not loading the cards at the right point.

     

    If you miss the VBLANK window, it may cause some of the data to not make it to GRAM. This is why it is important to do so in the initialization routines, while interrupts are disabled. There are even comments in the P-Machinery code suggesting what to do.

     

    It'll be much easier if you posted some code. Also if you described the output or posted a screenshot of it.

     

    -dZ.


  2. I have defined 14 new fonts :-)

     

    I have attached the updated custom font file

     

     

    what is still NOT WORKING is that If I add a tile I lost one more letter.... I can print only 23 custom chars... no matter what number I write in DEFINE_GRAM_BLOCK

     

    for each new font I add I lost one letter at the end of the list...

     

    This is a mystery!

     

    Could you upload the statistics (starting with "; RAM: Used" ) at the end of the "pmach-test.ls" file (or whatever it is called now). In my unmodified version, they look like this:

     

    	; RAM: Used
    
    AVAILABLE RAM:
     16-bit System RAM: 35 words.
     8-bit Scratch RAM: 204 bytes.
    
    GRAM USAGE:
     Used: 0 tiles.
     Free: 64 tiles.
    
    ROM USAGE:
    	  ; ROM: Used
     Used:
       Segment 0  (8K): 1218 words.
       Segment 1  (4K): 0 words.
      IF (_m.map = _m.42K)
    	   SMSG $("	  Segment 2 (", $#(.s2_size),"K): ", $#(_m.2sz), " words.")
    	   SMSG $("	  Segment 3  (", $#(.s3_size),"K): ", $#(_m.3sz), " words.")
    	   SMSG $("	  Segment 4  (", $#(.s4_size),"K): ", $#(_m.4sz), " words.")
    	   SMSG $("	  Segment 5  (", $#(.s5_size),"K): ", $#(_m.5sz), " words.")
       ELSE
       Segment 2  (4K): 0 words.
       ENDI
    		   TOTAL: 1218 words.
    
    	 ; ROM: Available
     Available:
       Segment 0  (8K): 6974 words.
       Segment 1  (4K): 4096 words.
     IF (_m.map = _m.42K)
    	   SMSG $("	  Segment 2 (", $#(.s2_size),"K): ", $#(_m.2av), " words.")
    	   SMSG $("	  Segment 3  (", $#(.s3_size),"K): ", $#(_m.3av), " words.")
    	   SMSG $("	  Segment 4  (", $#(.s4_size),"K): ", $#(_m.4av), " words.")
    	   SMSG $("	  Segment 5  (", $#(.s5_size),"K): ", $#(_m.5av), " words.")
       ELSE
       Segment 2  (4K): 4096 words.
       ENDI
    	  TOTAL: 15169 words.
    

     

    This might give us a clue...

     

    Wow, does it really display all that crap? The macro should have suppressed its code of "IF (...) SMSG ..." In fact, it does not show on mine. I'll have to check that.


  3. Note that you won't be able to include spaces in your text since you don't have a "blank" GRAM card in your set. You'll have to use the space in ROM.

     

    The easiest way is to include a "blank" in your GRAM set, right before the first letter. In the ASCII character set, this particular slot is taken by the symbol "@".

     

    Add this before the first letter in the LETTERS data block:

                   ; GRAM Tile: 0
                   ; --------------------------------
                               ; ........ - %00000000
                   DECLE $0000 ; ........ - %00000000
                               ; ........ - %00000000
                   DECLE $0000 ; ........ - %00000000
                               ; ........ - %00000000
                   DECLE $0000 ; ........ - %00000000
                               ; ........ - %00000000
                   DECLE $0000 ; ........ - %00000000
                   ; --------------------------------
    

     

    Also, since the set is now 27 tiles long, you have to modify the GRAM block definition:

    DEFINE_GRAM_BLOCK(font_belli, 27)
    

     

    And finally, since the position of the first letter (A) is changed, we need to modify the format word formula:

        DECLE  ((224 + GRAM_BASE_CARD(Fonts)) SHL 3) OR C_GRN
    

     

    Now you can print spaces with the symbol "@":

    CALL PRINT.FLS
    DECLE ((224 + GRAM_BASE_CARD(font_belli)) SHL 3) OR C_GRN
    DECLE $0200
    STRING '[email protected]@[email protected]'
    BYTE 0
    

     

    Also, remember that you can only use UPPER-CASE LETTERS, since your set does not contain lower-case letters and GRAM is not big enough to contain both. (Well it is, but you'll have to load to different sets and use two different format word formulae).

     

    I've tested this code and it works.

     

    -dZ.


  4. Developing int asm is very stressful :-(

    the more I work on this project the more I admire you people that already have developed games for intv

     

    adding custom fonts should be easy since described by the procedure PRINT.FLS...

    the procedure should be followed by format,location and string being the format something like the pointer to the memory place where I have my custom sprites/fonts

     

    this is what I write:

     

    1. DEFINE_GRAM_BLOCK(font_belli, 26) in GRAM_BLOCK in p-match.asm to define my label for the memory area where I want to load fonts

    2. LOAD_GRAM_BLOCK(LETTERS,font_belli) in ST_TTL_INIT in st_title.asm to put the fonts described by LETTERS in the gram at the location identified by my label (note this give a compiler warning "forward reference to SET/EQU symbol")

    3. CALL PRINT.FLS

    DECLE ((223 + GRAM_BASE_CARD(font_belli)) SHL 3)

    DECLE C_GRN, $0200

    STRING 'Test'

    BYTE 0

     

    in st_level.asm to write 'Test' using the custom fonts

     

    NOTE to DZj: writing DECLE ((223 + GRAM_BASE_CARD(LETTERS)) SHL 3) as you mentioned is not pointing to the label and give me an error...

     

    result is black screen:-|

    just to test in chinese whaterver style: if I put DECLE C_GRN, $0200 before DECLE ((223 + GRAM_BASE_CARD(font_belli)) SHL 3) one char from the font list is written on the screen, then the text 'Test' is written....

     

    Valter,

     

    Making old-school games is not easy. Which it why it has been a dream of many but the life of few. Welcome to a most exclusive club. :)

     

    First, I'll say that helping you on this project has provided some insight into what is needed for a better equipped game development framework. I'll make sure to add an easier mechanism to display text in custom fonts in P-Machinery, and to include instructions in another tutorial.

     

    Now, on to your issue. You have an extra argument word in your call to PRINT.FLS. Originally you had:

    CALL PRINT.FLS
    DECLE C_GRN, $0200
    STRING 'Test'
    BYTE 0
    

     

    That is, the first two arguments are the attribute word (C_GRN), and the position ($0200). Separating words by commas in a DECLE is the same as including more than one DECLE. What you should do now, is replace your attribute word with the one that contains the reference to the custom font.

    CALL PRINT.FLS
    DECLE ((223 + GRAM_BASE_CARD(font_belli)) SHL 3) OR C_GRN
    DECLE $0200
    STRING 'Test'
    BYTE 0
    

     

    Notice that I "OR"ed the color to the attribute. The attribute word represents all attributes for the text, including color, card number, GRAM bit, etc. For more information on how to prepare the attribute word, check out the SDK documentation on the STIC. In particular, look for the BACKTAB word definition. Also, check the documentation comments for the PRINT routine in "print.asm."

     

    I have just tested the code above and it works. The only thing you must remember is that the formula "((223 + GRAM_BASE_CARD(font_belli)) SHL 3)" will only work for GRAM cards. That means that if you plan to include any punctuation symbols--including the blank space--you must either use the ones in ROM, or include them in the GRAM set. However, GRAM only has 64 cards available.

     

    -dZ.


  5. jzIntv does not run alone on windows 7 64-bit, but it does run wh startedas part of the Intelliware package. :)

     

    That's weird, because on my Win 7 64-bit laptop, it runs just fine from the command line. That's the thing though: You do need to run it from the command line, not by clicking the icon.

     

    That´s possible. Command lines are the thingy where you enter commands by typing? Then running from command lines is almost as bad as not running at all! XD

    Who is using that stuff today? I have never used such a thing save for CHKDSK, that black screen scares me! :D

     

    Seriously though, many users today (including myself) don´t know how to use that, so I´d say it is a problem you might wanna put high on your priority list if you work on the emulator again. :)

     

    jzIntv is a great emulator, but mainly intended for programming new games for the Intellivision. It has a full-featured integrated debugger, and so it is very useful from the command line.

     

    -dZ.


  6. And lastly, when should you call the LOAD_GRAM_BLOCK() macro? Well, during initialization, of course!

     

    So I defined the block with label font_belli and having your .asm with fonts that is describing the proc "LETTERS", I need to call in ST_TTL_INIT this way

    LOAD_GRAM_BLOCK(LETTERS,font_belli)

    ?

     

    I have some trouble with a proc called MEMUNPK

     

    Forgive me, I forgot to mention that in order to use the "load_data.mac" library, you need to include "memunpk.asm" from the SDK. If you followed the configuration instructions I posted, you should just be able to do,

     

    INCLUDE "memunpk.asm"
    

     

    without qualification.

     

    Also, don't forget to add the "@@data_size" label to the LETTERS block! I don't think I added it when I posted it. Something like:

     

    ...
    @@data_size  EQU ($ - LETTERS)
      ENDP
    

     

    -dZ.

     

    OK, what I miss here probably is to tell the rom to use the GRAM location I just populated when I define attributes of the rom in the ROMSETUP? the fonts are charged in the Gram but the PRINT is still using the original location to find the cards I guess...

     

    No. That's not how it works. Unfortunately, I did not prepare routines to encapsulate using custom fonts in P-Machinery, so you'll have to use the ones in the SDK, like PRINT.FLS. You'll have to set the attributes in a way that tells the routine to use your GRAM fonts instead of the standard ROM fonts.

     

    Check the header comments in the "print.asm" file. Keep in mind that there are 255 GROM cards, so GRAM cards start at 256. The macro GRAM_BASE_CARD() gives you the card number in GRAM where your block is allocated.

     

    You'll have to do something like this:

    (character_number - 32) + (format_word SHR 3) = card_number.
    (65 - 32) + (format_word SHR 3) = (256 + GRAM_BASE_CARD(LETTERS))
    (format_word SHR 3) = (256 + GRAM_BASE_CARD(LETTERS)) - 33
    

     

    Solving for the format_word gives us,

    format_word = (223 + GRAM_BASE_CARD(LETTERS)) SHL 3
    

     

    When you call the PRINT routine, include the format word above.

     

                   CALL    PRINT.FLS
                   DECLE   ((223 + GRAM_BASE_CARD(LETTERS)) SHL 3)
                   DECLE  $0200
                   STRING  'Test'
                   BYTE    0
    

     

    This is just an example. I haven't tested it, but it gives you an idea. It should work, though.

     

    -dZ.


  7. And lastly, when should you call the LOAD_GRAM_BLOCK() macro? Well, during initialization, of course!

     

    So I defined the block with label font_belli and having your .asm with fonts that is describing the proc "LETTERS", I need to call in ST_TTL_INIT this way

    LOAD_GRAM_BLOCK(LETTERS,font_belli)

    ?

     

    I have some trouble with a proc called MEMUNPK

     

    Forgive me, I forgot to mention that in order to use the "load_data.mac" library, you need to include "memunpk.asm" from the SDK. If you followed the configuration instructions I posted, you should just be able to do,

     

    INCLUDE "memunpk.asm"
    

     

    without qualification.

     

    Also, don't forget to add the "@@data_size" label to the LETTERS block! I don't think I added it when I posted it. Something like:

     

    ...
    @@data_size  EQU ($ - LETTERS)
         ENDP
    

     

    -dZ.


  8. I read now and see how to use fonts...

    in the maintime one comment and one question.

     

    comment: do you plan to make a web page with your P-Machinery Part I-II-etc tutorials, or should be the intelliwiki the good place? your tutorial are very precious and must be easy to find in my opinion :-)

     

    I was planning on compiling all the tutorials and post them on my hosted site. I'll probably do that this weekend.

     

    question about the mek of the music: Intv has only 3 channels, but ECS provides 6, rights? so it would have sense to have double song, a 3 channel and a 6 channel ones when ECS is detected.... this is just a general question, is it possible to handle this difference? it would need specific code or just a call to a different song description?

     

    For that to work, the tracker code would have to support the ECS extra PSG (sound chip). I'm pretty sure it does not. I guess you could instantiate two trackers, however I see that Arnauld's tracker library is hard-code to use the main PSG registers. You would have to modify the code to either be more flexible or to maintain two sets of tracker codes.

     

    I really don't think you want to get into that right now. You have plenty of challenges ahead. P-Machinery eases some parts, but you still need to write a parser and tokenizer, and all game logic, yourself.

     

    If this is your first game, I suggest you keep it simple--especially if you're learning assembly too. Or else you run the risk of never delivering a full game. That's kind of the trouble I'm in right now: I could tweak Christmas Carol and continue adding features and niceties forever, but at some point you just need to narrow down your specifications, and ship a product.

     

    -dZ.


  9. Great! Then it is apparent that your tracker variables were being overwritten with the engine's data. Just keep this in mind. All RAM variables in your game must be allocated using the SCRATCH or SYSTEM, or any of the other allocation macros included in "Cart.mac."

     

    is this concerning also the font to be written in the RAM? my next step is to use the fonts of you, so I have to understand where I set GRAM offset and call your LETTERS proc

     

    Yes. P-Machinery includes macros to allocate GRAM. The idea is to statically allocate the GRAM that you will need for each state, so that the framework can keep track of how much is available. Also, by encapsulating the GRAM allocation, it makes it easier to control access to it. To this end, there are macros that support loading sprite graphics and displaying background tiles. These are all within the "graphix.mac" file.

     

    Take a look at the GRAM_BLOCK definition in the main source file. It contains commentary on how to allocation GRAM tiles for sprites and general use.

     

    In your case, you want to allocate a block of GRAM for the fonts, so you will use the DEFINE_GRAM_BLOCK() macro. You'll have something like this:

     

                   ; =============================================================
                   ; The GRAM_BLOCK structure defines symbols that represent
                   ; pointers to the various graphic assets in GRAM.
                   ;
                   ; P-Mach offers a complimentary set of macros and sub-routines
                   ; that use the GRAM_BLOCK structure to manage and manipulate
                   ; the GRAM.
                   ; =============================================================
    GRAM_BLOCK      STRUCT  0
                   RESET_GRAM
    
                   ; NOTE: YRES (Double vertical resolution) sprites need to start
                   ;       on an even numbered GRAM card.  We define these first to
                   ;       ensure that they start on card number zero, which is even.
    
                   ; SPRITE BLOCKS:
                   ;   Use the DEFINE_SPRITE_GRAM() macro to
                   ;   allocate GRAM blocks for game sprites.
                   ; --------------------------------------
                   ; DEFINE_SPRITE_GRAM(Sprite0,     vDouble)
                   ; DEFINE_SPRITE_GRAM(Sprite1,     vDouble)
                   ; DEFINE_SPRITE_GRAM(Sprite2,     vDouble)
                   ; DEFINE_SPRITE_GRAM(Sprite3,     vDouble)
                   ; DEFINE_SPRITE_GRAM(Sprite4,     vDouble)
                   ; DEFINE_SPRITE_GRAM(Sprite5,     vDouble)
                   ; DEFINE_SPRITE_GRAM(Sprite6,     vDouble)
                   ; DEFINE_SPRITE_GRAM(Sprite7,     vSingle)
                   ; --------------------------------------
    
                   ; BACKGROUND BLOCKS:
                   ;   Use the DEFINE_GRAM_BLOCK() macro to
                   ;   allocate GRAM blocks for the background
                   ;   and other assets.
                   ; --------------------------------------
                   ; DEFINE_GRAM_BLOCK(PlayField, 240)
                   ; --------------------------------------
    
                   DEFINE_GRAM_BLOCK(Font, 26)
    
                   ENDS
    

     

    That will allocate 26 cards in GRAM to a label called "Font". From then on, you can refer to that block by the label "GRAM_BLOCK.Font".

     

    You'll also notice in the "graphix.mac" file that some macros accept a "block" as an argument, for instance, GRAM_BASE_CARD(block). Whenever you see something requiring a "block" you only need to provide the label of your allocated GRAM_BLOCK. So, if you wanted to know the base card number in GRAM for your fonts block, you would use it like this:

     

       MVII    #GRAM_BASE_CARD(Font), R1
    

     

    The macro will expand the label "Font" to "GRAM_BLOCK.Font".

     

     

    Now, DEFINE_GRAM_BLOCK() only allocates the memory; you still need to load the fonts from ROM into GRAM. For this, you use the family of macros included in "load_data.mac". The basic load macro is LOAD_DATA(), which just performs a block-copy. However, to simplify loading to GRAM, there is another macro called LOAD_GRAM_BLOCK(). The usage is,

     

    ;; ======================================================================== ;;
    ;;  LOAD_GRAM_BLOCK(source, dest)                                           ;;
    ;;  Loads a complete block of data into GRAM.                               ;;
    ;;                                                                          ;;
    ;;  ARGUMENTS                                                               ;;
    ;;      source  The name of the source block in ROM to load.  The name      ;;
    ;;              corresponds to the label pointing to the start of the data  ;;
    ;;              source block.                                               ;;
    ;;                                                                          ;;
    ;;      dest    A GRAM_BLOCK record field that contains the pointer to the  ;;
    ;;              destination. The Macro will expand it to GRAM_BLOCK.%dest%. ;;
    ;; ======================================================================== ;;
    

     

    For this to work, you'll need to define your ROM data blocks like this:

     

    ; ===================================================================
    FONTS           PROC
                   ; GRAM Tile: 65
                   ; --------------------------------
                               ; ........ - %00000000
                   DECLE $0000 ; ........ - %00000000
                               ; .######. - %01111110
                   DECLE $827E ; #.....#. - %10000010
                               ; #.....#. - %10000010
                   DECLE $8682 ; #....##. - %10000110
                               ; .####.#. - %01111010
                   DECLE $007A ; ........ - %00000000
                   ; --------------------------------
    
                   ; GRAM Tile: 66
                   ; --------------------------------
                               ; #....... - %10000000
                   DECLE $8080 ; #....... - %10000000
                               ; #.####.. - %10111100
                   DECLE $C2BC ; ##....#. - %11000010
                               ; #.....#. - %10000010
                   DECLE $8282 ; #.....#. - %10000010
                               ; ######.. - %11111100
                   DECLE $00FC ; ........ - %00000000
                   ; --------------------------------
    
    @@data_size     EQU     ($ - FONTS)
                   ENDP
    ; ===================================================================
    

     

     

    Notice the bottom: The @@data_size label defines the length of the block. Saying ($ - FONTS) is the same as saying "the current address pointer minus the beginning of the block," which will yield the word size of the block.

     

    This is important, because the LOAD_DATA() macros need to know how much data to load. The LOAD_GRAM_BLOCK() macro expects this label to be defined in the source block. It simplifies and automates loading without having to really know or keep track of the length of data.

     

    And lastly, when should you call the LOAD_GRAM_BLOCK() macro? Well, during initialization, of course!

     

    -dZ.


  10. OK, I'm back after carefully setup the environemt following the PART I and PART II of tutorial

     

    now the code is cleaner and I'm at the INIT state, where I want to include the tracker

    I will sing the demosong.asm just as in the tracker package of Arnaud.

     

    See if I do the right things:

    1 - insert

    INCLUDE "tracker.asm"

    INCLUDE "tracker.mac"

    INCLUDE "demosong.asm"

    in the main program p-math.asm

     

    2 - I get errors from not having defined several symbols. those are in the tracker_demo source of Arnaud package, so I copy all of that in the main program p-math.asm

    G_FAD RMB 1

    REF_M RMB 1

    NOTE_A RMB 1

    NOTE_B RMB 1

    NOTE_C RMB 1

    REF_A RMB 1

    REF_B RMB 1

    REF_C RMB 1

    VOL_A RMB 1

    VOL_B RMB 1

    VOL_C RMB 1

    INSTR_A RMB 1

    INSTR_B RMB 1

    INSTR_C RMB 1

    COUNT_A RMB 1

    COUNT_B RMB 1

    COUNT_C RMB 1

    COUNT_M RMB 1

    COUNT_P RMB 1

    PAT RMB 1

    SONG RMB 1

    INS_PTR RMB 1

    POS_A RMB 1

    POS_B RMB 1

    POS_C RMB 1

     

    Valter,

     

    The P-Machinery framework uses the "Cart.mac" macro library to allocate variables in RAM. You should then use these for any variables you need to assign. The "Cart.mac" macros keep track of the available RAM and all that.

     

    The two main macros you would use are SCRATCH and SYSTEM, which define a variable in either 8-bit RAM or 16-bit RAM, respectively.

     

     

    Therefore, instead of using the code you posted, you should use something like the following. By the way, I learned that there are many versions of Arnauld's tracker around, and I don't know which one you're using, but the definitions below are taken from the one I use in Christmas Carol.

     

    ; --------------------------------------
    ; Music Tracker Engine
    ; --------------------------------------
    			; System RAM variables
    SONG			SYSTEM  1
    INS_PTR		 SYSTEM  1
    POS_A		   SYSTEM  1
    POS_B		   SYSTEM  1
    POS_C		   SYSTEM  1
    
    			; Scratch RAM variables
    G_FAD		   SCRATCH 1
    REF_M		   SCRATCH 1
    NOTE_A		  SCRATCH 1
    NOTE_B		  SCRATCH 1
    NOTE_C		  SCRATCH 1
    REF_A		   SCRATCH 1
    REF_B		   SCRATCH 1
    REF_C		   SCRATCH 1
    VOL_A		   SCRATCH 1
    VOL_B		   SCRATCH 1
    VOL_C		   SCRATCH 1
    INSTR_A		 SCRATCH 1
    INSTR_B		 SCRATCH 1
    INSTR_C		 SCRATCH 1
    COUNT_A		 SCRATCH 1
    COUNT_B		 SCRATCH 1
    COUNT_C		 SCRATCH 1
    COUNT_M		 SCRATCH 1
    COUNT_P		 SCRATCH 1
    PAT			 SCRATCH 1
    

     

    Not using the memory allocation macros, you cannot guarantee that you won't overwrite memory allocated already by P-Machinery.

     

    -dZ.

     

    that hint was simply magic !! :-0 !!

     

    the song is playing now!

     

    Great! Then it is apparent that your tracker variables were being overwritten with the engine's data. Just keep this in mind. All RAM variables in your game must be allocated using the SCRATCH or SYSTEM, or any of the other allocation macros included in "Cart.mac."

     

    By the way, did you take my suggestion of calling TRKSNGINIT from ST_LVL_INIT? If you're planning on playing the song during the "game play" state (i.e. "level"), then you should initialize it during that state.

     

    -dZ.


  11. OK, I'm back after carefully setup the environemt following the PART I and PART II of tutorial

     

    now the code is cleaner and I'm at the INIT state, where I want to include the tracker

    I will sing the demosong.asm just as in the tracker package of Arnaud.

     

    See if I do the right things:

    1 - insert

    INCLUDE "tracker.asm"

    INCLUDE "tracker.mac"

    INCLUDE "demosong.asm"

    in the main program p-math.asm

     

    2 - I get errors from not having defined several symbols. those are in the tracker_demo source of Arnaud package, so I copy all of that in the main program p-math.asm

    G_FAD RMB 1

    REF_M RMB 1

    NOTE_A RMB 1

    NOTE_B RMB 1

    NOTE_C RMB 1

    REF_A RMB 1

    REF_B RMB 1

    REF_C RMB 1

    VOL_A RMB 1

    VOL_B RMB 1

    VOL_C RMB 1

    INSTR_A RMB 1

    INSTR_B RMB 1

    INSTR_C RMB 1

    COUNT_A RMB 1

    COUNT_B RMB 1

    COUNT_C RMB 1

    COUNT_M RMB 1

    COUNT_P RMB 1

    PAT RMB 1

    SONG RMB 1

    INS_PTR RMB 1

    POS_A RMB 1

    POS_B RMB 1

    POS_C RMB 1

     

    Valter,

     

    The P-Machinery framework uses the "Cart.mac" macro library to allocate variables in RAM. You should then use these for any variables you need to assign. The "Cart.mac" macros keep track of the available RAM and all that.

     

    The two main macros you would use are SCRATCH and SYSTEM, which define a variable in either 8-bit RAM or 16-bit RAM, respectively.

     

     

    Therefore, instead of using the code you posted, you should use something like the following. By the way, I learned that there are many versions of Arnauld's tracker around, and I don't know which one you're using, but the definitions below are taken from the one I use in Christmas Carol.

     

    ; --------------------------------------
    ; Music Tracker Engine
    ; --------------------------------------
                   ; System RAM variables
    SONG            SYSTEM  1
    INS_PTR         SYSTEM  1
    POS_A           SYSTEM  1
    POS_B           SYSTEM  1
    POS_C           SYSTEM  1
    
                   ; Scratch RAM variables
    G_FAD           SCRATCH 1
    REF_M           SCRATCH 1
    NOTE_A          SCRATCH 1
    NOTE_B          SCRATCH 1
    NOTE_C          SCRATCH 1
    REF_A           SCRATCH 1
    REF_B           SCRATCH 1
    REF_C           SCRATCH 1
    VOL_A           SCRATCH 1
    VOL_B           SCRATCH 1
    VOL_C           SCRATCH 1
    INSTR_A         SCRATCH 1
    INSTR_B         SCRATCH 1
    INSTR_C         SCRATCH 1
    COUNT_A         SCRATCH 1
    COUNT_B         SCRATCH 1
    COUNT_C         SCRATCH 1
    COUNT_M         SCRATCH 1
    COUNT_P         SCRATCH 1
    PAT             SCRATCH 1
    

     

    Not using the memory allocation macros, you cannot guarantee that you won't overwrite memory allocated already by P-Machinery.

     

    -dZ.


  12. To anyone interested, the official P-Machinery site will now be hosted here. There is currently no web page there, just two files: the Mac and the Windows distribution.

     

    They are exactly the same, the only difference is that the Mac version contains BASH shell scripts to build and run, while the Windows version contains DOS batch files for the same.

     

    (Also, the source files contain UNIX line terminators (LF) in the Mac version, and DOS line terminators (CR+LF) in the Windows one.)

     

    From now on, I'll keep those files up to date, so you can bookmark the URLs.

     

    -dZ.


  13. Download the latest jzIntv from the web.

     

    What is the link for the Windows people?

     

    The Windows distro can be found here. The official jzIntv page contains all distributions.

     

    -dZ.

     

    Yeah, it's time for me to get off my fat arse and push a new release, isn't it? See my comment above with the latest work-in-progress build.

     

    The current version in the repository is slightly broken. (I broke the dirty rectangle update stuff.) I need to get that all sorted, and then maybe I'll make an actual 1.0 release that doesn't have "beta" in the name. :-)

     

    Hum... I just realized that the version of the SDK that I've been carrying along for about 4 or 5 years now is different than the latest one you posted in the "examples" link. I don't recall if it was because we extended some libraries during the development of Pac-Man and Christmas Carol and the changes never made it to the latest distribution, or if the distribution itself has changed.

     

    If anybody is having trouble following the steps I provided, please post here and I'll try to clear up as best as possible. Sorry for the confusion.

     

    -dZ.


  14. Here are the necessary instructions to set it up in Windows XP.

     

    First, lets assume you downloaded and "installed" jzintv in your "My Documents" folder, so that the path to the jzIntv installation is,

     C:\Documents and Settings\USER\My Documents\jzintv
    

     

     

    Substitute "USER" with your actual Windows username. If you used a different folder, just substitute it below.

     

    1. Right-Click "My Computer" and choose "Properties".

     

    2. Go to the "Advanced" tab and click the "Environment Variables" button at the bottom. You should see two sections. At the top, "User variables for USER"; and at the bottom, "System Variables". We're going to work on the "System Variables" section only.

     

    3. Look for an existing variable called "Path" in the list. Double-Click this entry and a pop-up will appear:

    Variable name:  Path
    Variable value: [whatever]
    

     

    4. We are going to append a path to the end of the "Variable value" field. Move the cursor to the end of the field by hitting the "End" key and type the following:

    ;C:\Documents and Settings\USER\My Documents\jzintv\bin
    

     

    Notice that I started with a ";" symbol. This symbol separates multiple paths, and we are adding a new one to the list. Also, substitute the path with whatever location you installed your jzIntv distribution. Make sure it points to the "bin" sub-directory.

     

    Click "OK" when done.

     

    5. Now we'll add 2 more variables used by the emulator and assembler. For each one, just click the "New" button and enter the following:

    Variable name:  JZINTV_ROM_PATH
    Variable value: C:\Documents and Settings\USER\My Documents\jzintv\rom
    

     

    Variable name:  AS1600_PATH
    Variable value: C:\Documents and Settings\USER\My Documents\library;C:\Documents and Settings\USER\My Documents\jzintv\macro;C:\Documents and Settings\USER\My Documents\jzintv\task
    

     

    (Remember to replace "C:\Documents and Settings\USER\My Documents\jzintv" with the actual path to your installation.)

     

    Click "OK" all the way down when done.

     

    There, your environment should be set up. The next time you open a Command Console, you should be able to use the tools without qualifying their location.

     

    6. Click "Start", then "Run", and type "CMD" and hit "OK". This will open a Command Console. To test the jzIntv tools, type in the command prompt the following:

    C:\> jzintv
    

     

    and

    C:\> as1600
    

     

    You should see the appropriate output as described in the AA post.

     

    That's it.

     

    -dZ.


  15. Part II: Setting up P-Machinery

     

     

    In this part I'll explain how to set up the P-Machinery game framework within your development environment. I assume you have followed the instructions on "Part I: Setting up jzIntv" and that your development environment is up and ready.

     

    1. Download P-Machinery

     

    First off, download the latest P-Machinery distribution from the announcement post. As with jzIntv, there is no real installation; you just copy the ZIP file to wherever you want to install it, and extract the archive. I suggest you create an "intvdev" or "games" folder in your "Documents" folder. You can then use this folder as your repository of games in progress. Really, you can put it anywhere, I just like to be tidy with my files.

     

    You'll end up with something like this:

     

    post-27318-0-00627400-1328281943_thumb.png

     

    And that's it. You're done, really. Assuming that your environment is set up as P-Machinery expects it (which was discussed in Part I), everything should be ready.

     

    2. Assembling the demo

     

    Let's test the P-Machinery demo, called "pmach". P-Machinery comes with two handy shell scripts to build (assemble) and run (execute) the demo. These are called, respectively, "build.sh" and "run.sh".

     

    Open up a Terminal app window and navigate to your newly installed "pmach" directory by typing the following:

    $> cd ~/Documents/intvdev/pmach
    

     

    If you installed the demo in a different folder, just replace the path to the correct one.

     

    Now, run the "build.sh" script to assemble the demo source:

    $> ./build.sh
    

     

    The output will contain general information of the assembled program, including how much ROM space it is using and how much Scratch and System RAM is used and available.

     

    post-27318-0-69500600-1328282779_thumb.png

     

    If everything is set up correctly, you should see the following at the bottom of the output:

    ERROR SUMMARY - ERRORS DETECTED 0
                  -  WARNINGS       0
    DONE.
    

     

    If you see any errors there, go back and review your set up and make sure you followed all the steps, including those in Part I. You can also post here questions and I'll try to help as I can.

     

    All the binary and assemblage files will be stored in the "bin" folder. Among the output generated by the "build.sh" script are the program rom (.rom and .bin), the symbol table (.sym), the memory map (.map), and the assembler listing file (.lst). These last three are useful for debugging your game.

     

     

    3. Running the Demo

     

    Now, let's try running the demo and see if it works. Just invoke the "run.sh" script from the Terminal window like this:

    $> run.sh
    

     

    This will invoke the jzIntv emulator with the demo. You should see the "P-MACH Test" title screen:

     

    post-27318-0-79187100-1328283361_thumb.png

     

    When you're done testing the demo, hit the F-1 key to exit the emulator.

     

    4. Debugging P-Machinery

     

    The "run.sh" does more than run the emulator. It also includes flags to load the symbol table and memory map into the debugger. This is useful when you want to test and debug your own games. By the default, the "run.sh" script runs jzIntv in "emulation" mode. To invoke it in "debugger" mode, just add the "-d" flag in the command-line, like this:

    $> run.sh -d
    

     

    The jzIntv emulator will be executed, but the emulation will be halted waiting for input from the debugger command-line. The Terminal window will show the output of the debugger with a prompt, like this:

     

    post-27318-0-37872600-1328283794_thumb.png

     

    Using the jzIntv debugger is out of the scope of this article, so you'll have to look for that elsewhere. However, you can type the "?" command for a list of all commands accepted by the debugger. When you're done debugging, just type the "q" command to quit:

     

    post-27318-0-55255700-1328284500_thumb.png

     

    5. Making your own games based on P-Machinery

     

    So, how do you make games using P-Machinery? Well, think of the "pmach" demo as a template for games. Just make a copy of the "pmach" folder and rename it to whatever your game will be called. Then rename the file "pmach-test.asm" to whatever you'll call your ROM.

     

    Finally, you'll have to modify the "build.sh" and "run.sh" script to use your game filename instead of "pmach-test".

     

    And you're done. You can modify the demo source with your own code and include library and other source files as you need.

     

    -dZ.

    • Like 1

  16. Download the latest jzIntv from the web.

    What is the link for the Windows people?

     

    I'd strongly recommend getting a more recent build of jzIntv. The most recent build which includes the development tools is here:

    And the most recently release set of source examples, etc. are here: http://spatula-city....14-examples.zip

     

    The most recent builds of jzIntv have better debugging features (such as the ability to do "source level" debugging through smap files), and the most recent version of the library files have been placed into the public domain where possible. (Notable exception is the SP0256-AL2 data, which I have a license to redistribute, but is still owned by Microchip.)

     

    OK, I updated the link in the original post.

     

    -dZ.


  17. Download the latest jzIntv from the web.

     

    What is the link for the Windows people?

     

    The Windows distro can be found here. The official jzIntv page contains all distributions.

     

    -dZ.

     

    Yeah, it's time for me to get off my fat arse and push a new release, isn't it? See my comment above with the latest work-in-progress build.

     

    The current version in the repository is slightly broken. (I broke the dirty rectangle update stuff.) I need to get that all sorted, and then maybe I'll make an actual 1.0 release that doesn't have "beta" in the name. :-)

     

    Good thing you posted those links! Since I only use the bleeding edge stuff you send me directly, I wasn't aware that the repo was not up to date.

     

    Thanks!

     

    -dZ.


  18. Valter,

     

    I thought I'd post this guide on how to properly set up a development environment for jzIntv and P-Machinery. I know you had some trouble doing this before, but hopefully this will help others in the future. You may want to take a look also in case it can help you organize your environment a bit.

     

    First, I'll assume you are using Mac OS X. Doing this in Windows requires slight modifications, but I can include those in another post.

     

    So now, on with the show...

     

     

    Part I: Setting up jzIntv

     

     

    Step 1: Get development tools

     

    Download the latest jzIntv from the web. There is no real installation of the jzIntv tools, so just copy the downloaded archive to the location where you want to install it. I would suggest in your "home" directory, since it is convenient, and it is backed up, and it is retain across OS upgrades.

     

    After you find an appropriate location for it, just extract the archive. That's it! jzIntv is installed.

     

    You may want to rename the folder to something simple like "jzintv" instead of the default "jzintv-1.0-beta-macosx," just for your convenience in finding it later.

     

    You'll end up with something like this:

     

    post-27318-0-38440700-1328275331_thumb.png

     

     

    Step 2: Set-up environment

     

    Now we need to set-up the environment. Open up the Terminal application. We will use a text editor from the command line to modify your local profile to include some global variables useful to jzIntv. A simple to use text editor is nano, which comes with Mac OS X. First, from the Terminal prompt, type the following (note that "$>" represents the prompt):

    $> cd ~
    

     

    That will take you to your HOME directory, where all your user profile information resides. Then to edit your profile, you type the following:

    $> nano .bash_profile
    

     

    The nano editor will open the file in question. Just use the cursor keys to navigate to the bottom of the file and add the following lines:

    export INTV_SDK_PATH="$HOME/jzintv"
    export JZINTV_ROM_PATH=$INTV_SDK_PATH/rom
    export AS1600_PATH=$INTV_SDK_PATH/library:$INTV_SDK_PATH/macro:$INTV_SDK_PATH/task
    export PATH=$PATH:$INTV_SDK_PATH/bin
    

     

    Notice that the path defined for INTV_SDK_PATH should point to the location where you installed jzIntv. I am assuming you used your HOME folder. All other directory paths rely on this one. (Note that multiple paths are separated by colons ":")

     

    When all is done, save the file by hitting the CTRL+O keys (WriteOut), followed by the CTRL+X (Exit) keys. You should be back at the prompt.

     

    Since the .bash_profile file is loaded when a shell is started, the variables will be ready the next time you open a new Terminal window. For now, you can just close the Terminal window and open it again.

     

    To test your environment, from a newly opened Terminal window, type the following:

    $> jzintv
    

     

    It should show the copyright and basic information of the emulator, and its command-line usage.

     

    To test that the assembler works, type the following:

    $> as1600
    

     

    You should get an error stating "as1600: no input file". This is normal, but it lets us know that the assembler was executed.

     

    post-27318-0-82102000-1328277516_thumb.png

     

     

    3. What did we just do?

     

    What we did was install the jzIntv and SDK-1600 into your HOME directory, and set up some global environment variables that allow the emulator/debugger jzIntv and the assembler as1600 to find the SDK library files. From now on, including an SDK library into your game is as simple as adding the INCLUDE directive to your source, without having to qualify where the files reside. For instance:

    INCLUDE "gimini.asm"
    INCLUDE "print.asm"
    INCLUDE "rand.asm"
    

     

    The assembler will find those files in the paths specified in the $AS1600_PATH variable.

     

    Likewise, we specified the directory where jzIntv should look for its standard ROMs, like the EXEC or GROM. If you have your own copy of these ROMs you should put them in the "rom" folder within the "jzintv" installation folder.

     

    And lastly, we added the emulator, the assembler, and all the binary tools included in the SDK to your computer's executable path. This allows you to just invoke them from the Terminal app without qualifying their specific location. In the future, assembling a program should be as simple as just invoking the assembler with the name of the source file:

    $> cd /path/to/my/game
    $> as1600 game.asm
    

     

    That's it for now. Next post will show how to set up P-Machinery to work within this environment.

     

    -dZ.

     

     

    Updated: Link to jzIntv points to latest build.

    • Like 1

  19. Well

    tracker still does not sing for me :-).....

     

    I try to resume:

     

    1- I included all the tracker files

    INCLUDE "tracker.asm"

    INCLUDE "tracker.mac"

    INCLUDE "demosong.asm"

    in the p-math.asm

    no error, so I proceed

    2- I call the initializations in the PROC ST_LVL_INIT inside "st_level.asm" as

     

    CALL TRKINIT ; initialize tracker

    CALL TRKSNGINIT ; initialize song

     

    3- I call the song in ST_WAIT_ENGINE in the "engine_util.asm" as

    ; --------------------------------------

    ; This is a good place to update music

    ; and sound effects states, too.

    ; --------------------------------------

    CALL TRKPLAY

     

    this is not working, the rom is killed after title screen.... I maybe tired and need to sleep :-)

     

    Valter,

     

    The ST_WAIT_ENGINE routine is only called during wait delays. To play music during the "game-play" level, you need to add it to the ST_LVL_PLAY routine. That's the actual handler of the play state. Putting it in both allows for seamless music to play during state transitions.

     

    It will look like this:

     

    ;; ======================================================================== ;;
    ;;  ST_LVL_ENGINE: ISR routine to handle a game level.                      ;;
    ;; ======================================================================== ;;
    ST_LVL_PLAY     PROC
                   ; --------------------------------------
                   ; These access GRAM or the STIC, and so
                   ; need to run as soon as possible at the
                   ; top of the ISR routine.
                   ; --------------------------------------
                   ISR_ENABLE_DISPLAY
                   CALL    POST_STIC_X
    
                   ; --------------------------------------
                   ; Perfom all engine tasks or add them
                   ; to the task queue as necessary:
                   ;   - Update STIC
                   ;   - Update PSG
                   ;   - Cycle GRAM cards
                   ;   - Update score display
                   ;   - Move all sprites
                   ;   - Check collisions
                   ;   - Animate sprites
                   ;   - etc.
                   ; --------------------------------------
                   CALL TRKPLAY                                 ; Update tracker state
    
                   ; --------------------------------------
                   ; Process all timed tasks and counters.
                   ; --------------------------------------
                   DCALL   DOTIMER, iEnabled
                   CALL    PAUSE_GAME                      ; Check for pause
                   IRET
                   ENDP
    

     

    Also, make sure that your call to TRKSNGINIT includes a pointer to the song you want to initialize. For instance,

     

                   CALL    TRKSNGINIT
                   DECLE  MYSONG
    

     

    Can you send me by e-mail your "st_level.asm" and "st_title.asm" files to see if there's anything wrong?

     

    -dZ.


  20. what I need now is:

     

    - implement the waiting loop of 3 seconds, that I use in the welcome screen and maybe somewhere else (TASK

    - integrate the audio tracker to start a forevew song from level1... the song I have to translate, but I would use the one of the trackerdemo for now (demosong) just to see if it's working

    - add you in the credits for the much help you provide :-)

     

     

    pause.asm what is made for?

     

    Implementing the 3 second wait loop is easy. Let's do that first.

     

    If you read my "P-Machinery Theory" post, then you should by now think of this 3-second delay as no more than a scheduled event that needs to be triggered after three seconds. Therefore, you write your "event handler," which is just the code that will execute once that 3-second delay is up, and schedule it as a task.

     

    The following code is an example of how to schedule the task:

    CALL	STARTTASK
    DECLE   TASK.Delay		  ; Task number
    DECLE   DO_SOMETHING		; Event handler
    DECLE   (60 * 3 * 2) - 1	; 60 frames per second times 3
    DECLE   0				   ; No re-schedule
    

     

    As I mentioned before, there are two timing counts that you provide the STARTTASK procedure. The first one is the "initial delay" and the second one is the re-schedule time. The latter is only used for recurring tasks.

     

    Since yours is a one-off task, we set the first count to an odd number (that's why the "-1"), and we set the re-schedule delay to zero to ignore it.

     

    That's it. You're done. The P-Mach engine will iterate doing its thing for 180 iterations (3 seconds at 60 Hz), and call the routine DO_SOMETHING when the timer is up. (Note that "DO_SOMETHING" is a placeholder for whatever task you make.)

     

    In your DO_SOMETHING routine you do whatever needs to happen at that point. Let's say you want to clear the screen, then you do this:

     

    DO_SOMETHING PROC
    CALL	CLRSCR
    
    TRET	; done!
    ENDP
    

     

    Here's an interesting thing to note: When one of your procedures is intended to be called ONLY from the task scheduler, then you do not need to worry about keeping track of the return address. The TRET (Task Return) macro "hard-wires" the return address to the task scheduler.

     

    In other words, the scheduler triggers your event, and your event returns directly so that the scheduler may continue with other tasks.

     

    However, if the routine needs to be called directly (using CALL), then you can't use TRET. You'll have to keep track of the return address and return normally.

     

    At what point do you want to introduce the 3 second delay, and what do you want it to do after?

     

    -dZ.

     

    it's working

    I introduce 3 seconds in the first page with message welcome stranger.. after 3 second goes to first description.

    I may also use this to pretend the text on screen is written in two steps (half page right away and half page after 2 seconds) but do not know if the result is interesting or confusing

     

    Valter, considering that you only have a 20 x 12 matrix in which to display the text, how do you plan on showing long text passages? Perhaps you should consider editing the text for space, making it shorter.

     

    Also, how about just showing a small icon on the right-most bottom of the screen (e.g. an ellipsis, or an arrow, or the word "more" in tiny text) to alert the user that there is more text to display? Then you just wait for any key from the user (or a press of the disc) and display the next "page."

     

    I have a rush of memories of making my own text-based games in the C=64 when I was younger, all peppered with a "[press space to continue]" message at the bottom of the screen in reversed-video. :)

     

    -dZ.


  21. what I need now is:

     

    - implement the waiting loop of 3 seconds, that I use in the welcome screen and maybe somewhere else (TASK

    - integrate the audio tracker to start a forevew song from level1... the song I have to translate, but I would use the one of the trackerdemo for now (demosong) just to see if it's working

    - add you in the credits for the much help you provide :-)

     

     

    pause.asm what is made for?

     

    Now let's deal with the audio tracker updates. You want to play music during the "game-play" state, while the game is engaged, right?

     

    Simple again! All you need to do is periodically call the TRKPLAY procedure from Arnauld's tracker, assuming that you have already called TRKSNGINIT during initialization. By periodically we actually mean, on every ISR interrupt, or on every game-loop iteration.

     

    However, note that the PSG (the sound chip) does not have any access restrictions like the STIC (the video chip). Therefore, we are not constrained to call TRKPLAY during VBLANK. We are safe to call it at any time, as long as we call it once on every loop iteration.

     

    In Christmas Carol, I call the TRKPLAY routine from two centralized points: During the game-play event handler, and during the wait event handler. The former should be self-explanatory by now. The latter, however, warrants some explanation.

     

    P-Machinery allows you to break each main state into sub-states. Along these sub-states there is typically a need for a "wait" state, in which the game engine is doing absolutely nothing but ticking along updating the engine state without any particular game logic to execute.

     

    This is common, for example, when introduce a delay between screen transitions, or when you switch from one main state to another. Indeed, it is so common, that P-Machinery includes a generalized wait state routine called the "wait engine."

     

    The "wait engine" typically does all the housekeeping stuff that the other states need to do, with the exception of game-specific logic, such as collision detection, etc. In essence, it puts the game into an "idle" state, processing timers and other tasks but doing no real game stuff.

     

    The "wait engine" handler in P-Machinery is the routine ST_WAIT_ENGINE in the "engine_util.asm" file. Below is the code currently in P-Mach for this procedure:

     

    ;; ======================================================================== ;;
    ;;  ST_WAIT_ENGINE                                                          ;;
    ;;  Procedure to service all timers.                                        ;;
    ;;                                                                          ;;
    ;;  INPUT for ST_WAIT_ENGINE                                                ;;
    ;;      None.                                                               ;;
    ;;                                                                          ;;
    ;;  OUTPUT                                                                  ;;
    ;;      None.                                                               ;;
    ;; ======================================================================== ;;
    ST_WAIT_ENGINE  PROC
                   ; --------------------------------------
                   ; These access GRAM or the STIC, and so
                   ; need to run as soon as possible at the
                   ; top of the ISR routine.
                   ; --------------------------------------
                   ISR_ENABLE_DISPLAY
                   CALL    POST_STIC_X
    
    @@Task:         ; --------------------------------------
                   ; This is a good place to update music
                   ; and sound effects states, too.
                   ; --------------------------------------
    
                   MVII    #@@__wait_tsk,          R0      ; \_ Set up a task to process timers
                   DCALL   QTASK,  iIgnore                 ; /
                   IRET
    
                   ; --------------------------------------
                   ; Process timed tasks and check for
                   ; a request to pause the game.
                   ; --------------------------------------
    @@__wait_tsk:   DCALL   DOTIMER, iEnabled
                   TCHAIN  PAUSE_GAME                      ; Check for pause
                   ENDP
    

     

    Notice the place holder in the @@Task label. It is indeed a good place to update music states. Just add "CALL TRKPLAY" at that point. Also notice the rest of the basic tasks that the wait engine performs: it sets up a task to process all timers (for scheduled tasks), enables active display, and updates the STIC (video chip) registers.

     

    To play music during game-play, you do something similar in the routine ST_LVL_PLAY in the "st_level.asm" file. That is the handler for the "Game-Play" state. That routine has a similar placeholder for normal game-engine background stuff:

     

    ;; ======================================================================== ;;
    ;;  ST_LVL_ENGINE: ISR routine to handle a game level.                      ;;
    ;; ======================================================================== ;;
    ST_LVL_PLAY     PROC
                   ; --------------------------------------
                   ; These access GRAM or the STIC, and so
                   ; need to run as soon as possible at the
                   ; top of the ISR routine.
                   ; --------------------------------------
                   ISR_ENABLE_DISPLAY
                   CALL    POST_STIC_X
    
                   ; --------------------------------------
                   ; Perfom all engine tasks or add them
                   ; to the task queue as necessary:
                   ;   - Update STIC
                   ;   - Update PSG
                   ;   - Cycle GRAM cards
                   ;   - Update score display
                   ;   - Move all sprites
                   ;   - Check collisions
                   ;   - Animate sprites
                   ;   - etc.
                   ; --------------------------------------
    
                   ; --------------------------------------
                   ; Process all timed tasks and counters.
                   ; --------------------------------------
                   DCALL   DOTIMER, iEnabled
                   CALL    PAUSE_GAME                      ; Check for pause
                   IRET
                   ENDP
    

     

    Like I mentioned in the "P-Machinery Theory" post, rather than writing the code in-line at this point, you should just add the tasks to the queue. This will allow P-Machinery to act in a sort of "multi-tasking" way. Rather than processing a long, single flow of code on each iteration, it processes multiple short tasks in rapid-fire fashion.

     

    This allows the engine to be flexible with time: if at any point it doesn't have enough time to process all tasks in one go, the next game-loop iteration will just add more tasks to the queue, provided there is enough space in the queue. Since the queue is processed in order, they don't collide with each other. Eventually the engine should catch up and everything continues as normal.

     

    I hope this helps.

     

    -dZ.


  22. what I need now is:

     

    - implement the waiting loop of 3 seconds, that I use in the welcome screen and maybe somewhere else (TASK

    - integrate the audio tracker to start a forevew song from level1... the song I have to translate, but I would use the one of the trackerdemo for now (demosong) just to see if it's working

    - add you in the credits for the much help you provide :-)

     

     

    pause.asm what is made for?

     

    Implementing the 3 second wait loop is easy. Let's do that first.

     

    If you read my "P-Machinery Theory" post, then you should by now think of this 3-second delay as no more than a scheduled event that needs to be triggered after three seconds. Therefore, you write your "event handler," which is just the code that will execute once that 3-second delay is up, and schedule it as a task.

     

    The following code is an example of how to schedule the task:

    CALL	STARTTASK
    DECLE   TASK.Delay		  ; Task number
    DECLE   DO_SOMETHING		; Event handler
    DECLE   (60 * 3 * 2) - 1	; 60 frames per second times 3
    DECLE   0				   ; No re-schedule
    

     

    As I mentioned before, there are two timing counts that you provide the STARTTASK procedure. The first one is the "initial delay" and the second one is the re-schedule time. The latter is only used for recurring tasks.

     

    Since yours is a one-off task, we set the first count to an odd number (that's why the "-1"), and we set the re-schedule delay to zero to ignore it.

     

    That's it. You're done. The P-Mach engine will iterate doing its thing for 180 iterations (3 seconds at 60 Hz), and call the routine DO_SOMETHING when the timer is up. (Note that "DO_SOMETHING" is a placeholder for whatever task you make.)

     

    In your DO_SOMETHING routine you do whatever needs to happen at that point. Let's say you want to clear the screen, then you do this:

     

    DO_SOMETHING PROC
    CALL	CLRSCR
    
    TRET	; done!
    ENDP
    

     

    Here's an interesting thing to note: When one of your procedures is intended to be called ONLY from the task scheduler, then you do not need to worry about keeping track of the return address. The TRET (Task Return) macro "hard-wires" the return address to the task scheduler.

     

    In other words, the scheduler triggers your event, and your event returns directly so that the scheduler may continue with other tasks.

     

    However, if the routine needs to be called directly (using CALL), then you can't use TRET. You'll have to keep track of the return address and return normally.

     

    At what point do you want to introduce the 3 second delay, and what do you want it to do after?

     

    -dZ.

×
×
  • Create New...