Shop OBEX P1 Docs P2 Docs Learn Events
Propeller Assembly for beginners - Page 14 — Parallax Forums

Propeller Assembly for beginners

1111214161729

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2011-08-26 11:56
    Hi Harprit,

    your code has longs and res not only behind the last PASM-command but also right inbetween the code
    I don't remember the why but I surely know that all longs and all res HAVE TO BE behind the last PASM-command.

    Maybe braking this rule is causing the problems.
    If I would like to analyse the problem I would singlestep through the PASM-code with PASD.

    keep the coding rules in mind and follow them
    best regards

    Stefan
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-08-26 12:11
    You have data in the middle of your code. That rarely works with any assembler unless the value at :timer just happens to be a valid instruction. You might be able to get away with moving :timer down below the ret instruction but I think putting everything at the end might be the best bet.

    When you come out of the WAITCNT, the program counter is incremented and points to the memory location at :timer and fetches it and tried to execute it. At that point, your program has lost all meaning and is no longer doing what you intened the code to do.
  • jazzedjazzed Posts: 11,803
    edited 2011-08-26 12:50
    Post #23 on page 1:

    'I would add "under no circumstances should a res command be used in the middle of a PASM program" .... blah res N must be at the end of code because it does not allocate space for the variable and will cause any longs or instructions that might come after it to have the wrong register addresses.'

    A long can be anywhere in a PASM program if you follow the rules.

    Everyone learns different ways, but reading is fundamental.
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-08-26 12:54
    jazzed wrote: »
    Post #23 on page 1:

    'I would add "under no circumstances should a res command be used in the middle of a PASM program" .... blah res N must be at the end of code because it does not allocate space for the variable and will cause any longs or instructions that might come after it to have the wrong register addresses.'

    A long can be anywhere in a PASM program if you follow the rules.

    Everyone learns different ways, but reading is fundamental.


    ...and once again, this is why you want expert commenting on the code and not beginners and near-beginners. I was close but incorrect and misleading, which is as good as WRONG at the machine code level!! :smile:
  • HarpritHarprit Posts: 539
    edited 2011-08-26 14:33
    Well there is one thing wrong I learned from a posting. I used to put all my longs and res statements at the end of the code, then someone posted code that put them in the middle of methods so I started doing it. The old learn by seeing trick. What a mess. Back to the beginning. We need rules as to when you can put where.

    Harprit.
  • kuronekokuroneko Posts: 3,623
    edited 2011-08-26 17:18
    Harprit wrote: »
    I used to put all my longs and res statements at the end of the code, then someone posted code that put them in the middle of methods so I started doing it.
    Before this gets more confusing, can you show us the code in question? There may be a perfectly valid reason for doing it like that in the posted code.

    FWIW, data can be anywhere within a cog image (even in the code path as long as you make sure it doesn't affect the code flow, e.g. nop).
    mov     ctra, $+1                ' fetch from current +1
    long    mode << 23 | pin
    
    res should be placed at the end of the cog image (there are exceptions but you don't want to go there right now). Note that if you have several cog images in the same source file it may appear as if res ends up somewhere in the middle.
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-08-26 23:43
    OK the rule has to be modified:

    Can the expert please re-check this:

    Longs can be in the middle of the code but for better overview put them behind the last PASM-command.
    All "res" have to be behind all PASM-commands and behind all longs that belong to a certain cog.

    If you have PASM-code for more than one cog in one file - the code for each cog has to be in its own DAT-section
    inside each DAT-section the rules above apply.

    If you were just looking at the backround-color - in case of PASM-code for multiple cogs - this looks like longs and res are in the middle of code.
    But that is not true. longs and "res" are always at the end of the belonging code-block.

    keep the questions coming
    best regards

    Stefan
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-08-26 23:57
    Harprit wrote: »
    Besides why do you feel so strongly that a good primary education is a prescription for NOT being able ever to discuss nuclear physics. I personally am amazed by that conclusion but there may be aspects to learning a language that are beyond me.

    Harprit

    I do not feel that way at all, rather that is the conclusion you have somehow arrived at. However have you noticed that nearly all primary school teachers must posess or be working towards a masters degree? That being said, I do believe that your idea of having a beginner involved in the authoring of a tutorial work has merit; however I also believe that the author should posess significant experience in both the device and underlying programming principles in order to not propagate erroneous methods and bad habits that will likely hinder the growth of the reading audience. Further there should also be significant experience in the hardware used in the presentation and examples to avoid unexpected frustrations. I am new to the prop, and you asked....

    Frank
  • kuronekokuroneko Posts: 3,623
    edited 2011-08-27 00:30
    StefanL38 wrote: »
    All "res" have to be behind all PASM-commands and behind all longs that belong to a certain cog.
    True 99.9% of the time (so make that usually should be). There are scenarios where it's perfectly valid/reasonable to use res in the middle of the file (example VGA 1280x1024 Tile Driver). As for long placement, I'd argue that placing certain variables belonging to a specific sub-routine directly before or after said sub-routine is acceptable. Just keep them out of the way.
    If you have PASM-code for more than one cog in one file - the code for each cog has to be in its own DAT-section inside each DAT-section the rules above apply.
    Separate DAT sections are not necessary. Important is a valid org directive in front of the new image. Using a new DAT section obviously helps in terms of visual appearance.
  • MazziniMazzini Posts: 58
    edited 2011-08-27 14:01
    Hello ,

    I have an beginner question.
    I have to split 1 byte in two nibble and send them to lcd ( 4 bit bus , 16x2 )
    Can you give me your opinion about this piece of code ?I'am not sure this works
    ' MSB       LSB
    '7 6 5 4  3 2 1 0        SET
    '-----------------------------------------------------------
    '0 0 1 1  0 0 0 0        8 bit mode
    '0 0 1 0  0 0 0 0        4 bit
    '0 0 1 0  1 0 0 0        4-bits, 2-lines, 5x7
    '0 0 0 0  1 0 0 0        display off, cursor off, blink off
    '0 0 0 0  1 1 0 0        display on
    '0 0 0 0  0 0 0 1        Clear display
    '0 0 0 0  0 1 1 0        increment, no display shift
     
    'P32........P24..........P14 P13 P12 P11 P10           P0
    '           En           RS  DB7 DB6 DB5 DB4
    '0  0000000 X 000000000  X   X   X   X   X  0000000000 0    <--------- Port's map 
    
    
    Lcd_init 
                            andn outa,RS
                            mov cmd,#$28 ' 4-bit mode - 2 line - 5x7 font.
                            Call #LcdDat 
                            mov cmd,#$0C ' Display no cursor - no blink.
                            Call #LcdDat
                            mov cmd,#$06 'Automatic Increment - No Display shift.
                            Call #LcdDat
                            mov cmd,#$80 'Address DDRAM with 0 offset 80h.
                            Call #LcdDat     
    
    Lcd_init_ret            ret
    

    LcdDat
    
    'MSB Data
                            mov t2,outa             'copy porta to temp var
                            mov msb,cmd             'copy cmd to msb var
                            ror msb,#4              'shift msb >> 4
                            and msb,#$F0            'msb & 0xF0
                            or t2,msb               'Add new bits to t2 
                            mov outa,t2             'Set port
                            or outa,EN              'EN high
                            nop
                            nop
                            nop
                            nop
                            nop
                            nop
                            nop '-------------------> 250ns
                            andn outa,EN            'EN low -> Send Msb to LCD
    
    'LSB Data                        
                            mov t2,outa             'copy portA to temp var
                            mov lsb,cmd             'copy cmd to msb var
                            and lsb,#$F0            'msb & 0xF0
                            or t2,lsb               'Add new bits to t2 
                            mov outa,t2             'Set port
                            or outa,EN              'EN high
                            nop
                            nop
                            nop
                            nop
                            nop
                            nop
                            nop '-------------------> 250ns
                            andn outa,EN            'EN low -> Send Lsb to LCD
    
                            rdlong  delay200us, #0
                            mov     t1, cnt    ' setup
                            add     t1, delay  ' first add
    
                            waitcnt t1,delay '200us
                           
     
    
    
    LcdDat_ret              ret
    
    msb                     byte
    lsb                     byte
    cmd                     byte
    

    Thanks in advance
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-08-27 15:02
    Hi Mazzini,

    this is a thread where a tutorial about learning PASM and code-examples for this tutorial are discussed.

    Anyway to get onto your question:
    is this working code that you found somewhere and you ant to know how it works in detail?

    or is the code above something that you have written on your own and want to know why it is working (or maybe not working)

    I'm not superfamiliar with bitoperations. So if I would have to check it in detail I would use the PASD_ebugger and singelstep through the code to check if my thoughts
    what the code should do is matching 100% what the code is in fact really doing.

    Or if you don't want to use PASD doing the same operations in SPIN or in a excel-sheet (especially the bit-manipulations) and then compare the results with each other.

    to get the 4 upper bits down a bitshift to the right (instead of bitrotating should do it)

    to delete the upper 4 bits (to extract the lower 4 bit an and #$0F operation should be enough.
    As all commands in PASM are 32bits rotating bits rotates the lowest 4 bits (bits 3,2,1,0 to bits 31,30,29,28)
    You are "OR"-ing the bitvalues t2 and lsb/msb so the bits 31,30,29,28 get changed too and that wasn't intended.


    If I understand right you are using prop-IO-pins P10-P13 as databit-bus 4 bits wide.
    Then the upper and lower nibble has to be shifted to the right position in a variable so "OR"-ing with a variable holding the state of each bit from outa and then write it to outa

    As a first hint do the bitmanipulations in the propellertool to get feedback on what happens
            30        20        10
           10987654321098765432109876543210
    cmd   %00000000000000000000000011010111
    
    get rid of lower nibble
     
            30        20        10
           10987654321098765432109876543210
    cmd   %00000000000000000000000011010111
    
    shift 4 bits right
            30        20        10
           10987654321098765432109876543210
    cmd   %00000000000000000000000000001101
    
    to get it to IO-pin P10-P13
    
    
    shift 10 bits left
    
            30        20        10
                             XXXX
           10987654321098765432109876543210
    cmd   %00000000000000000011010000000000
    
    
    
    upper nibble
    set all bits to zero except upper nibble 
     
    
            30        20        10
           10987654321098765432109876543210
    cmd   %00000000000000000000000011010111
    and   %00000000000000000000000011110000
    result%00000000000000000000000011010000
    
    shift 6 bits left
    
            30        20        10
           10987654321098765432109876543210
                             XXXX
    result%00000000000000000011010000000000
    

    keep the questions coming
    best regards

    Stefan
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-08-27 17:38
    Mazzini,
    Here is what it is doing. (personally, I have just mastered the MUXes and they are powerful!!!)

    The init is pretty straightforward, as the init routine simply sets the pin designated as RS to command mode. After that it repeats the same call to DAT with the values passed in the command variable. The LcdDat routine has two halves where the same thing also is repeated twice, once for each nibble.

    Anyway, the outa register is preserved for manipulation. The command is then copied to a working variable and shifted right 4 places to get the high nibble into position for bits 0-3. The mask I am not so sure is correct. I would not of habit do the mask this way because the immediate bits leave the upper bits of msb unchanged and you could introduce problems later in more complex situations. Better to create a long of $00_00_00_0F for bits 0-3 being command / data lines to the lcd device, same for the dira register if needed when you set your I/O direction. The zeros will be used to make sure there are no inadvertent 1s left in bits 31-4 that could cause mis-setting of outa bits when the msb is or'd with the saved outa prior to clocking with EN. En is raised high and then after a delay, low to clock the value into the LCD. Rinse and repeat for the LSB. You could use this method to shift any number to get the msb/lsb to the pins you have chosen to tie the device to. It looks like the author was expecting to use bits 4-7 from the use of the $F0 mask, though I am not so sure of the match up of the right shift and the original mask used. as to the listed delay times, that would depend entirely on the clock frequency used. I would guess that the clock frequency here was about 16Mhz based on 250ns/NOP. Simply clone this same routine with R/S set to 1 for the data to be displayed.

    To use the pin out shown, set the mask $00_00_1E_00 (easier if on 4 bit boundaries for hex) and you will need to create this mask variable. The immediate instructions will not help you as the 1E00 to mask the bits will be out of range (max $1ff, 9bits) unless you took the rather circuitous route of shifting cmd/data nibbles to bits 0-3, masking them and then carefully shifting to the appropriate pins prior to or'ing with outa. ick.... There is a downside to rip and strip, and that is being able to see what the authors hardware setup was when the code was written. As mentioned above I suspect he was using either bits 0-3 from the right shift used or 4-7 from the mask

    Hope this helps,

    Frank

    Sorry if it seems verbose, to many years as a technical instructor. Enjoy your time on the forum. Some seriously good people share here.
  • potatoheadpotatohead Posts: 10,261
    edited 2011-08-27 17:49
    @Stephen, great post on using the editor to work through bit ops.

    Edit: Prop tool is good for this because it's got real overwrite mode, and it formats in ways favorable to these kinds of activities. I use it all the time for basic ASCII art too, which has similar feature requirements.

    I'm adding that to my beginner stuff.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-08-27 19:39
    I have been writing some assembly lately and also following this thread with great interest.

    Assembly is still full of many mysteries to me. For instance, the difference between 'mylabel' and ':mylabel'. I wasn't even sure there was a difference until I added a new label in some code and it stopped compiling. A search for ":" in the instruction manual revealed a one line entry. However, that was the manual from a few years ago, and the same manual from the latest version has a full page explaining what ":" labels are and has "New" next to this page.

    I read through this new manual and there are a lot more "New" sections and so I'd suggest that anyone trying to learn assembly look at getting the latest download.

    I've then gone off on a tangent thinking about why assembly is confusing. To me, it is things like : and # and what special meanings these have. It is also the structure of assembly, and I find myself using certain constructs over and over. For instance
          cmp myvariable,othervariable wz
    if_nz jmp #label
          some instructions
    label   ' jump to here if not true
    

    If "some instructions" extends to a page of instructions, the overall structure tends to get lost.

    I was thinking that maybe that could be simplified into a higher language construct - eg in a Basic syntax,
    if myvariable = othervariable then
      some code
    endif
    

    and in a C type of syntax
    if (myvariable == othervariable)
    {
      some code
    }
    

    and there is a spin type of syntax too.

    I am thinking of some sort of pre-compiler that takes a hybrid higher level language and turns it into pasm before running it through the pasm compiler.

    One can think of some other constructs that come up over and over in assembly and which can be reverse translated into a higher level language.

    In the case of "if", there are the four combinations of if_z, if_nz, if_c and if_nc.

    Then there are simple loops. There are loops where you set a variable to zero and count up until it equals something. These are loops with jmp instructions. And there are loops where you set a variable to a value and then count down to zero, and these are djnz loops.

    Each of these can be reverse translated into a higher level basic/c/spin type syntax that to my eyes looks easier to read.

    Such a higher level language is not going to be C or Basic or Spin though. Scattered through the code will be assembly instructions that make sense to leave them as they are. But maybe it might look more familiar to write "a = b" or "a :=b" than mov a,b.

    I've got a few more ideas, but in general the aim would be to have a hybrid pasm/high level language where it compiles into the most efficient pasm code one can write.

    I shall ponder this some more...
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-08-27 20:01
    Hey Dr. A

    Yeah, I have noticed some new (good) things in the manual as well. I keep it open on another desktop (inveterate, nah.... incorrigible Xnix user) What I wish it had following instructions would be more examples of usage. Kinda a rip-off of the unix man pages. Truth tables are helpful, but an example of usage goes a long way too.

    C and higher level languages can simplify some things through abstraction at a price. Also there is the issue of portability between platforms, but how often will anyone be porting prop to pic? Would love a good loaded macro assembler. Wonder if anyone has done a cross compiler w/ GCC yet for the prop?

    Frank
  • Heater.Heater. Posts: 21,230
    edited 2011-08-27 23:53
    Frank. There is a gcc cross compiler being written as we speak. It already generates PASM for in COG execution and will also target LMM PASM. Have a look for threads about it on the Parallax Semiconductor forum.
  • MazziniMazzini Posts: 58
    edited 2011-08-28 03:35
    Hello,

    Thanks so much to all for long answers
    Sry if this is the wrong place, I will create a new one in 15 min.
    from this link I tried to translate the code in pasm http://www.8051projects.net/lcd-interfacing/lcd-4-bit-programming.php
    My goal was work on byte data afterward or'in the prop port so that I don't overwrite the whole port

    see you next topic if you agree
  • HarpritHarprit Posts: 539
    edited 2011-08-28 09:10
    @Mazzini

    Here is my code for a 2x16 display from my book on Spin for beginners. I am in the process of converting it to PASM and will post that as soon as I am done. This is in 8 bit mode.
    {{Spin code for 2 x 16 LCD.  Harprit Sandhu)}}
    CON
      _CLKMODE=XTAL1 + PLL16X 'The system clock spec
      _XINFREQ = 5_000_000 'the crystal frequency
    
      RegSelect =  18                                                                                                                                                                                                                                                                                                        
      ReadWrite = 17
      Enable = 16
    
      DataBit0 = 15
      DataBit7 = 8
    
      high =1 'define the High state
      low =0 'define the Low state
    {{
    Defining high and low states will allow us to invert these when we use
    buffers to amplify the output from the prop chip. We will then make
    low=1 and high=0 thus inverting all the values throughout the program.
    I am NOT using a buffer.
    }}
    PUB Go
      DIRA[DataBit7..DataBit0]:=%11111111 'the lines for the LCD are outputs
      DIRA[RegSelect] := High 'the lines for the LCD are outputs
      DIRA[ReadWrite] := High 'the lines for the LCD are outputs
      DIRA[Enable] := High 'the lines for the LCD are outputs 
      INITIALIZE_LCD 'initialize the LCD
      waitcnt(clkfreq/2+cnt) 'wait for LCD to start up    
      repeat 'this is a parking loop to keep the system
        repeat 4 'print 4 'A's
          SEND_CHAR ("A")
        repeat 4 'print 4 'b's
          SEND_CHAR ("b")
        POSITION (1,2) 'move to POSITION: line 2, space 1
        repeat 4 'print 4 'C's
          SEND_CHAR ("C")
        repeat 4 'print 4 'd's
          SEND_CHAR ("d")  
        waitcnt(clkfreq/20+cnt) 'wait for LCD to start up  
        CLEAR 'clear the LCD
    
    PRI INITIALIZE_LCD 'The addresses and data used here are
      waitcnt(clkfreq/2+cnt) 'specified in the Hitachi data sheet for
      'display. YOU MUST CHECK THIS FOR YOURSELF
      OUTA[RegSelect] := Low 'these three lines are specified to write
      OUTA[ReadWrite] := Low 'the initial set up bits for the LCD
      OUTA[Enable] := Low 'See Hitachi HD44780 data sheet
      'display. YOU MUST CHECK THIS FOR YOURSELF.
      SEND_INSTRUCTION (%0011_0000) 'Send 1st
      waitcnt(394_000+cnt) 'wait
      SEND_INSTRUCTION (%0011_0000) 'Send 2nd
      waitcnt(9600+cnt) 'wait
      SEND_INSTRUCTION (%0011_0000) 'Send 3rd
      waitcnt(96_000+cnt) 'wait
      SEND_INSTRUCTION (%0011_1000) 'Sets DL=8 bits, N=2 lines, F=5x7 font
      SEND_INSTRUCTION (%0000_1111) 'Display on, Cursor on, Blink on
      SEND_INSTRUCTION (%0000_0001) 'clear LCD
      SEND_INSTRUCTION (%0000_0110) 'Move Cursor, Do not shift display
      
    PUB CLEAR 'Clear the LCD display and go home
      SEND_INSTRUCTION (%0000_0001)
    
    PUB POSITION (LINE_NUMBER, HOR_POSITION) | CHAR_LOCATION 'Pos crsr
      'HOR_POSITION : Horizontal Position : 1 to 16
      'LINE_NUMBER : Line Number : 1 or 2
      CHAR_LOCATION := (HOR_POSITION-1) * 64 'figure location
      CHAR_LOCATION += (LINE_NUMBER-1) + 128 'figure location
      SEND_INSTRUCTION (CHAR_LOCATION) 'send the instr to position cursor
    
    PUB SEND_CHAR (DISPLAY_DATA) 'set up for writing to the display
      CHECK_BUSY 'wait for busy bit to clear before sending
      OUTA[ReadWrite] := Low 'Set up to read busy bit
      OUTA[RegSelect] := High 'Set up to read busy bit
      OUTA[Enable] := High 'Set up to toggle bit H>L
      OUTA[DataBit7..DataBit0] := DISPLAY_DATA 'Ready to SEND data in
      OUTA[Enable] := Low 'Toggle the bit H>L
    
    PUB CHECK_BUSY | BUSY_BIT 'routine to check busy bit
      OUTA[ReadWrite] := High 'Set to read the busy bit
      OUTA[RegSelect] := Low 'Set to read the busy bit
      DIRA[DataBit7..DataBit0] := %0000_0000 'Set the entire port to input
      REPEAT 'Keep doing it till clear
        OUTA[Enable] := High 'set to 1 to get ready to toggle H>L bit
        BUSY_BIT := INA[DataBit7] 'the busy bit is bit 7 of the byte read
        OUTA[Enable] := Low 'make the enable bit go low for H>L toggle
      WHILE (BUSY_BIT == 1) 'do it as long as the busy bit is 1
      DIRA[DataBit7..DataBit0] := %1111_1111 'set the port back to outputs
    
    PUB SEND_INSTRUCTION (DISPLAY_DATA) 'set up for writing instructions
      CHECK_BUSY 'wait for busy bit to clear before sending
      OUTA[ReadWrite] := Low 'Set up to read busy bit
      OUTA[RegSelect] := Low 'Set up to read busy bit
      OUTA[Enable] := High 'Set up to toggle bit H>L
      OUTA[DataBit7..DataBit0] := DISPLAY_DATA 'Ready to READ data in
      OUTA[Enable] := Low 'Toggle the bit H>L
    
    Harprit
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-08-28 09:32
    @mazinni,

    First place to look if you don't just want to start from scratch...

    OBEX OBEX OBEX.

    There are at least 20 LCD drivers of various types and levels of skill and documentation. There are 8 bit and 4 bit parallel drivers, as well as reduced pin count serial drivers. Also a good spot for just about anything else you may need.

    MIT license, a beautiful thing!!!!!

    Frank

    I have placed a 3 pin serial spin driver there as well. (an early learning project, so it could probably be tightened up a bit)
  • MazziniMazzini Posts: 58
    edited 2011-08-28 09:40
    Hi Harprit,

    Good idea I will compare it to my code in order to learning some stuff of Pasm Thanks so much:D
    Congratulation for your book
  • MazziniMazzini Posts: 58
    edited 2011-08-28 09:53
    @mazinni,

    First place to look if you don't just want to start from scratch...

    OBEX OBEX OBEX.

    There are at least 20 LCD drivers of various types and levels of skill and documentation. There are 8 bit and 4 bit parallel drivers, as well as reduced pin count serial drivers. Also a good spot for just about anything else you may need.

    MIT license, a beautiful thing!!!!!

    Frank

    I have placed a 3 pin serial spin driver there as well. (an early learning project, so it could probably be tightened up a bit)

    Yes you are right , obex are great work and need time to build them and it is free
    I will search one in pasm
  • ratronicratronic Posts: 1,451
    edited 2011-08-28 10:07
    I think the best examples for beginners to learn from are the spin/pasm programs that come with the Propeller tool. They are all written by proffesionals so as a beginner you know they are garaunteed to work so you learn spin/pasm by figuring out how to use them.
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-08-29 00:39
    Last thing for the night....
    A debug/devel trick beginners can use until they master a debugger:

    Instrument the heck out of your code. Echo out significant results to the terminal or add "I am here" messages into the flow of your code. Sort of like where is Waldo except Waldo is saying "here I am". Write out input values and results as you go along. Test as you proceed and then comment them out as they are no longer needed. You could recycle the monitoring variables for further testing or leave commented in place in case you want to do some regression testing if/when something breaks. May not be best for time critical paths, but so far has served me well in shared memory and clock gen for my curve tracer project. Must.........master...............counters.........next

    Frank
  • HarpritHarprit Posts: 539
    edited 2011-08-29 07:48
    @ frank freedman with respect

    Most children, all over the world, learn a language, even unwritten languages, without meeting any one with a BA and MA or a PhD. Linguists tell us that by the time they are conversant they know about 500 words. In these words they can express most everything they need to, for day to day living. At most total immersion language schools, they try to teach you these 500 words under pressure. Its hell but I understand that you learn the language fast. The US Army once used to boast that they could teach you Russian in a week at their Monterrey total immersion school.

    Beginners in PASM don't need any revelations from experts. They need a gentle introduction to what the language is all about. Leave off all the stuff they can pick up on their own later. Just the basics. Without all the scare tactics and know it all bravado.

    My personal take on it is that some of the posters on this forum are bent out of shape because I have the nerve to write a book on something I know absolutely nothing about. As I have admitted, I knew absolutely nothing about all this 6 weeks ago and not much now. Others have been most gracious and kind in providing both help and encouragement.

    The only thing we can go by is the record. My book on SPIN is panned by the experts and loved by novices. It has a few mistakes in it (panned and how by some) that I have corrected on my web site. So lets concentrate on the job and hand and see what I come up with. If nothing it will be a sincere effort. Lots and lots of explaining and commented code. Example code for most PASM instructions that beginners need to be familiar with. Its about those 500 words after all.

    Rather more than what all the critics have come up with in a book for beginners.

    Regards
    H
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-08-29 08:24
    To be a good pasm programmer, it's not about patching others peoples obex code.
    It's to learn to think in a binary way, to really understand what is going on.


    1st thing that got me a little confused when I looked at sample code was.

    The underscores in large numbers, example %11_0000_11
    Why are they there, and sometimes they are not evenly spaced.

    Answer: They are just for your eyes, the assembler skips the underscores.


    2nd, the |<

    Answer, its single bit version of <<
    for example: |<6 (= %1<<6) the assembler will create a number that is %1000000


    3rd, the use of shadow registers as a trick to save on memory.
    example: mov CNT,CNT

    Why would you need to copy CNT to itself?
    It turns out that right field (source) and left field(destination) have two different memory locations.

    That some special registers are called Write or Read Only registers,
    when it's actually more about right (source) and left (destination) versions.
  • mindrobotsmindrobots Posts: 6,506
    edited 2011-08-29 09:05
    @Harprit, with respect.

    I don't think anyone is calling your sincerity or motivation into question.

    To use your language analogy, true that a 4 year old can generally speak their native language well enough for day to day functioning but if I want to learn their language, I won't seek that 4 year old to teach me, I will teach a more experienced with more exposure to the language and the world of speech. While the 4 year old may teach me the word "way" in their context, that 4 year old is going to (hopefully) learn the difference between way, weigh and whey at some point in the future as their education progresses....and break any bad habits associated with misuse. I don't want to for the bad habits in the beginning and then relearn the correct way as my PASM experience grows. I'd rather learn the correct way from the start.

    I don't see scare tactics or bravado in any of the "expert contributions. Possible some frustration with repeating themselves, possibly some lack of teaching skills and patience (I'm guilty of this - I would NEVER want myself as a teacher in any subject I have significant knowledge in!). Tutorial writing and teaching in general are great arts that many people do not possess (guilty as charged). It is hard to remember the things you did when learning, the things that didn't click and the things that you no longer see because you are deeply immersed in the subject. The secret is for some intermediary to be able to come along and take that expert wisdom, break it down and present it in learn-able pieces (often presenting it in different, multiple ways) so the reader/learner can understand and figure out how to synthesize the new information. This is not an easy task and I commend you in taking it on.

    The other hard part is for the writer to avoid teaching bad habits or "not quite correct" things that will need to be relearned later. For a child learning a language, hopefully these good habits and expanded skills are taught in school. For someone that is trying to learn PASM to enjoy or be quickly productive, any bad or misleading information is a disservice.

    I sincerely don't believe the "critics" as you have labeled some are being critical to be mean, spiteful or to express jealously at your writing a book. I think they are trying to be helpful so you can create the best work possible and teach people PASM (often a difficult subject for even an experienced programmer without assembler exposure) so those people can avoid any traps or frustration or well-intended but incorrect information.


    Since you have placed yourself into this role as the intermediary or translator between those knowing PASM and those wanting to learn PASM, you need to understand your reader, where they are coming from and what knowledge you expect them to have (and fill any missing gaps via appendices or introductory chapters) and you also need to be at a level in your PASM knowledge where you can interpret and synthesize the information and tips provided by experts into learn-able lessons and examples.


    "People learn differently" can also be applied to "people teach differently".....based on your background and experience, you know both sides of the coin well!



    I don't expect my 3rd grader's teacher to be able to teach the theory and proof behind division and multiplication but I do expect the kid to come home an know that 1/10 is smaller than 1/5 and 0 times anything is 0 and not leave me a not that she's playing at a "frends" house! To me, those are basics and can't be put off until later when she has more experience.


    Keep up your admirable work, be ready for many rewrites and reorganizations and try to remember that the critics are really trying to help.....they hang around here to help people and don't want to correct any bad habits you may publish! :lol:
  • jazzedjazzed Posts: 11,803
    edited 2011-08-29 09:15
    Hear hear! Very nicely said Rick.
  • HarpritHarprit Posts: 539
    edited 2011-08-30 06:13
    Thank you Rick
    I'll ditto Jazzed

    H
  • HarpritHarprit Posts: 539
    edited 2011-08-30 17:39
    Sorry folks but I had more problems than I expected with the 2 x 16 display. Converting to PASM can get tricky. I got it working now but I'm still getting some garbage on the screen. Should sort it out soon and then I will post.

    Thanks for your patience.

    Harprit
  • HarpritHarprit Posts: 539
    edited 2011-09-01 06:10
    Question

    Assume the pin is pulled high

    Is it enough to debounce it with
    Wait for pin to go low
    wait for pin to go high

    It seems to work OK but I'm bit unsure if this is foolproof

    H
Sign In or Register to comment.