Assembly code Help! PIC16F57 - Page 1
Forum section: electronics / beginners

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 28, 2018, 08:38:07 pm
content: Before I start with what I need help with I feel a little back story will help. I am working on a fruit machine (Slot machine) project that was originally published in the EPE electronics magazine in two parts on December 1994 and January 1995 (a UK electronics magazine) The original project used a PIC16C57 and you had to order this pre-programmed at the time, more on this later. The project also utilised three, seven segment displays which are the reels of the fruit machine.In 2012 I showed an interest in resurrecting and rebuilding the project as the first attempt was a messy one! So I had reached out to the magazines forum and to my amazement the original creator of this project had surfaced and was extremely helpful, he and his collaborative partner of the project kindly decided to open source the code and helped me find the now newer equivalent to the PIC16C57 which is the PIC16F57. With his help I was successful in programming the updated chip with no modification to the code (although it did list some warnings but worked anyway) However there were some differences from original program, for instance the LED demo sequence which Is displayed a couple of seconds after switch on, and is displayed until player inserts a credit, was different from the original. I informed the creator of this and concluded the code was a different version than that supplied on the PIC all those years ago. Unfortunately the creator couldn't find this newer version and the original PIC was code protected and couldn't be copied, but he was very helpful in telling me the parts of the code I could change to manipulate the sequence amongst other things. There was also another difference but more on this in a moment.At the time I had some life issues going on and had to push the project to one side, I had stopped conversing with the creator and lost contact. Its only recently I have decided to pickit! Back up again and get this thing finished. There are things I am still trying to achieve with it but attempts to contact him for further help have failed. Though to be fair, even at the time of talking to him he had sort of moved on from it, I was extremely fortunate and grateful that he helped me as much as he did. He currently operates a fairly successful YouTube channel and in fact has posted a video about the fruit machine project with links to the original magazine article and source code, however he hasn't responded to my questions, and to be fair it was posted 4 years ago and other attempts to contact him are probably lost in a sea of other messages he now probably receives and has no time or even maybe no interest in responding, but I am understanding of that.Link to the YouTube vid, the pdf article and source code files are in the vid's description...https://www.youtube.com/watch?v=GCGmK0gCCUIThere are two things I need help with, the first thing is still regarding the LED sequence. Now my assembly knowledge is extremely limited and need help with getting this to work. The LED sequence works by calling a lookup table named “pattern” using addwf and retlw, the original chip seems to display 32 different LED patterns/combinations and then loops around again, the source code version displays 16, however when I try to add more than 16 hex values to the table, they don't get used, it just loops 16 of them. Obviously as I can’t read the original chip and so I can’t see how he did it. There is a second table named “pattern2” this is the sequence displayed when a player has a win, this is the same as the original and I’m happy with that.The second problem is that on the open sourced version, when you first switch the machine on and put the first credit in, it often gives the player the option to hold all the reels straight of the bat and because the reels are always on bars on the first switch on it gives the player an instant jackpot win! The original chip does not do this and the creator of the project had obviously fixed this in the final version, I don't possess the knowledge to fix this. If someone could please advise me or look at the source code on the YouTube vid, I would so appreciate it. Thank you in advance everybody.

author: jpanhalt
author_rank: Super Contributor
timestamp: September 28, 2018, 10:38:53 pm
content: You will have to post your code for anyone to help.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 28, 2018, 11:03:09 pm
content: OK have attached code, Only changes I made are the list pic value from p=16C57 to p=16f57. added config bits, and I added a bunch of 0FF hex values to the "pattern" table for testing which should keep LEDS on solid but as previously stated only the first 16 I added actually work which is like a chasing/twinkle pattern.

author: Zero999
author_rank: Super Contributor
timestamp: September 28, 2018, 11:07:45 pm
content: Here's a tutorial on how to program in assembly for baseline PIC processors. I followed it myself a few years ago and managed to write a simple program within a day. The PIC16F57 has the same core as the ones described on the tutorial linked below, so it's a good fit.https://www.gooligum.com.au/PIC-tutorials/baseline-PIC-tutorial

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 28, 2018, 11:20:39 pm
content: Thank you so much for that, will try and give it a go but don't think I have a head for this, might end uplol. And I can't think of an instant after this when I would use it again and therefore will probably forget it before long. will give me something to watch at bed time tonight though. you never know it might stick. thanks

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 29, 2018, 12:35:34 am
content: Have looked at the pdf linked to the lessons and I just can't see how I can apply this to an already written code and in the way it's been written. Strange thing is that the lookup table for the three seven segment displays is 30 hex values long but the tables for the 8 yellow Led's above my segment displays are only 16 hex value long, which incidentally are not only the demo display led's but are also the credit led's, inserting a coin effectively stops the light show and they light up one by one as each credit/coin is inserted to indicate credit total.I just need someone to either edit the code or tell me I need to do this, this and this basically.

author: Ian.M
author_rank: Super Contributor
timestamp: September 29, 2018, 08:45:45 am
content: To edit the code successfully you need to understand it. You'll probably have to reverse engineer it enough to draw up a flowchart to get anywhere with it, and will certainly need to be fluent in the 12 bit core subset of MPASM assembler. It would probably be quicker and easier to write a formal specification for what the chip must do, then code your own slot machine firmware in a high level language (e.g. C). However as compiled programs tend to be larger than hand-optimised assembler, it may not fit in the chip and as the PIC16F57 has a rather unique pinout, there's nothing newer with more memory that's pin-compatible, so you'd either need a daughter-board with a SMD modern PIC on it to convert the pinout, or to redesign the whole PCB.If you want someone else to work on the code, expect to have to pay commercial rates. It wont be cheap. . .

author: jpanhalt
author_rank: Super Contributor
timestamp: September 29, 2018, 11:00:02 am
content: Agree with others. To edit code, you need to understand it. There are a few obvious things of concern.Code:carryequ0zerequ2indequ00Default radix is hexadecimal with Microchip. (Choices are binary, octal (I think), decimal, hexadecimal, and ASCII. You can declare the radix during your initialization. RADIX DEC will make the default decimal. It is an Assembler directive and is not part of the chip's instructions per se.) Thus, you have given "carry" and "ind" the same value/identifier. A series of equates is often used to identify user registers. For that chip, user registers (General Purpose RAM) begin at 0x0A, so your equates would probably just substitute a 0x0, 0x2, at each occurrence of those identifiers. Look at your code and see if that makes sense.Be aware that memory is banked. Each bank of GP RAM is only 22 or 16 bytes. Bank0 is 0x0A..0x1F, Bank1 is 0x30..0x3F, and so forth. Here are your register definitions:Code:temp_reg1equ08temp_reg2equ09temp_reg3equ0Atemp_reg4equ0Bmode_byteequ0Cfunction_byteequ0DTherefore temp_reg1 and temp_reg2 do not point to user GP RAM.In sum, I add my advice that it is probably easier to start from scratch or perhaps from a flowchart than to redo that code. If you chose to do that you may wonder why this is written as such:Code:initialisationclrw;START OF INITIALISATION ROUTINESmovwfportAmovwfportBcomfportB;PORT B CONTAINS FFmovwfportC;PORT C CONTAINS 00clrwtrisportA;PORT A ALL BITS AS OUTPUTStrisportB;PORT B ALL BITS AS OUTPUTSThe first instruction clears W, then uses movwf <reg name>. Why not just clrf <reg name>? The authors apparently do that to avoid what is called Read-Modify-Write (RMW) error (there is a lot written about it). "clrf" , however, is not a RMW instruction; whereas, "comf" is. "comf PORTB" is therefore subject to RMW despite the earlier attempts supposedly to avoid using clrf.The last 3 instructions are a correct structure for avoiding RMW when dealing with TRIS. Note, that "TRIS" instruction and MOVWF TRIS have the same effect.However, as you write your code for flashing LED's, you may want to focus on just getting it to work and worry much less about RMW. Do be aware of RMW, though.You hopefully will progress to the enhanced mid-range chips, e.g., 16F1xxx, where you have data latches on the ports for avoiding RMW in those instances where it is a problem.Have fun.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 29, 2018, 02:51:16 pm
content: While the solutions suggested are interesting and sound fantastical they also seem unnecessary, you must see from my point of view that I have a working PIC16C57 with code on it that runs perfectly but I can’t access, and as I want to build another, I have a PIC16F57 which runs the slightly different source code, almost perfectly. Surely a complete rewrite or a new PIC is not necessary.All I need to know is why the machine will not run any more than the 16 hex values in the “pattern” table i.e. 32 values and how I can stop the machine from giving me an option to hold the reels when I put the first credit in...That's it.I have attached the flow chart from the pdf magazine article if that helps. And the links below to the pdf magazine articles themselves if anyone is interested...Part 1http://www.epemag.wimborne.co.uk/EPE_Fruit_Machine_part_1Dec94.pdfPart2http://www.epemag.wimborne.co.uk/EPE_Fruit_Machine_part_2Jan95.pdfUnfortunately the forum I was on when I was able to get hold of the owner has now closed but I did save some ofthe things he said…“We had to write the code as a real-time multitasking operating system. Again this is to ensure no coins are ignored. You probably know that you can insert coins at any time regardless of what the machine is doing. Thiswas very important to us. The machine had to log every single inserted coin - without fail”He also said..“Have a look through the program code. Sorry it's a bit ugly - this was the first PIC code I ever wrote”However the code worked anyway so I wasn’t complaining about its aesthetic or efficiency.

author: jpanhalt
author_rank: Super Contributor
timestamp: September 29, 2018, 04:13:25 pm
content: QuoteIt is a jump table, i.e., the position it goes to is relative to the current program counter position. Do a "disassembly" list and review it. There you can see PCL (program counter low or as you call it, PC) and where each of the entries your table is located.BTW, 16C57's are available on eBay, but you may not be able to program it with your tools. A PicStart Plus can probably do it. (I haven't checked, but I have programmed other 16Cxx chips with that programmer.)

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 29, 2018, 04:41:43 pm
content: Ok thanks will try that. Yeah the 16C57 is not supported by the pickit3, which I own, and owner used the PICstart originally. it was through his advice that we arrived at its direct replacement 16F57 of which I have 5 spare. As previously mentioned they work great with the source code, its just those little things I need to get changed in the code that he provided as he couldn't find the final version of the code that he supplied on the pre-programmed chips back in the day. before I had chance to flesh these things out about the code I had lost contact with him.it's just frustrating because I just don't possess the programming knowledge to achieve this and attempts to learn this is proving very hard for me. I know enough to build the projects and program the PIC's and maybe mess with a few variables in code but it's like gobbledy goop to me. I have had new PCB's made by JLPCB using original schematic (with changes made because of unavailability of the original push buttons and new pinout arrangement for the segment displays) and I have built it up and works superbly with both the original chip and the new 16F57. I am so close grr! just need help!You see this I like a restoration project for me and I am trying to have the code act like the original, I grew up with this machine after having and watching it being built by my dad, now I am building it for my son and my dad would also like to do this again, so I was going to give him the bits he needs as a kit.

author: jpanhalt
author_rank: Super Contributor
timestamp: September 29, 2018, 06:52:57 pm
content: First, I made an error in my previous post. By accident I was looking at the 16F59, not the 16F57. The latter's GP Ram does begin at 0x08, not 0x0A, which is the 16F59.Since your compiler seems to accept PC for PCL, that is probably OK. But, you might want to try PCL

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 29, 2018, 07:01:43 pm
content: looked a the disassembly list and I'm at a loss as to what I am looking at or how I am to conclude why this won't run the 17th - 32nd entry of the "pattern" table. please except my apology but I'm just likehere!,yeah just tried renaming the PC to PCL at the top of code and on all the tables but has made no difference, but will leave it that way since every example I have read seems to have it named that way.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 29, 2018, 07:06:19 pm
content: The other thing is I don't know whether I should be using MPLAB IDE v8.83 or MPLAB X IDE, seem to be able to use both without too much pain since I know where most things are in MPLAB X now!

author: jpanhalt
author_rank: Super Contributor
timestamp: September 29, 2018, 08:21:08 pm
content: I use MPLab 8.92. If 8.83 works, that is what I would use. Either is easier when using Assembly, if the chip is supported. That is not to say MPLab X won't work, and with newer chips, that is the only option. The problem is very unlikely to be the Assembler.Can you snippet the Disassembly and your code for the jump table side by side and post?

author: KL27x
author_rank: Super Contributor
timestamp: September 29, 2018, 09:07:30 pm
content: ElectrofinnI think I can help, but this code totally sucks. Fortunately, my own code mostly totally sucks, so I am pretty good at working backwards to fix things.You have identified that the look up table named "pattern" is what produces the sequence of 16 frames that you wish to extend to 32. I'm assuming you are correct in identifying this.Steps.1. Look at "pattern." It is a table that adds the contents of W to the PCL to determine where to jump and exit from. The contents of W must be between 1 and 16 (or is it 0-15? I'm not sure. In modern PIC I use BRW, in this case it would be 0-15, not 1-16; but I digress) or else the PCL will jump to a point that is outside of the contents of pattern. Hence you must figure out what is loaded into the W register before pattern is called. If you simply add 16 more retlw instructions after the original 16, they will never be executed.2. Figure out where "pattern" is called. To do this, first locate "pattern" by right clicking on the code and selecting "goto" from the dropdown menu in MPLAB. Then find header "pattern" in the dropdown list.3. Now you have "pattern" in front of you. Type ".fuckall" after it. Then reassemble. You will get a list of errors where the code is trying to call or goto "pattern." In this case, you will get only one error. But before you click on it, be sure to change "pattern.fuckall" back to "pattern." Then click on the error and it will take you towhere "pattern" is called from. It is called from "feature."4. In "feature," you will find:movf counter_hi,Wcall patternevery single time "pattern" is called, the W register is first loaded with the value that is contained in register designated as "counter_hi."So unless the code is broken, the writer has assured that the value of counter_hi is always something between 1 and 16 (or 0-15?). If it were not, this code would more than likely produce a stack error.5. Find every instance of "counter_hi" in the code.5A - locate where the coder defined counter_hi. In this case, it's a short code, and it is easily found at the top. But if it were more complex there are two ways.A trick I use is to scroll to the very top of the main .asm file and type "counter_hi equ 0"Reassemble.You will get an error that says "counter_hi previously defined"delete the "counter_hi equ 0" you just typed, then click on the error to jump to where the coder has defined "counter_hi"The good part of this is it will find it no matter what file it was placed in, which it could be one of many .inc files and/or .asm files.You will find it here:unused2 equ 14hold_counter equ 15counter_hi equ 16counter_lo equ 17delay_counter equ 18So this means that the coder has defined it to be register 0x16 in general memory. Do not change this to 32. This is a fortuitous coincidence, only. This is an address, not a value.You might have forgotten by now, but the point of locating it was to find out every place it is used in the code. So change the name to produce an error.write "ASS." in front of counter_hi. So it reads "ASS.counter_hi equ 16"reassemble. You will find numerous errors of "counter_hi not defined."Again, be sure to erase the "ASS." before you click on the errors.Scrolling through the errors one at a time, I get to the eleventh error when I find this codesequence1bsf counter_lo,7incf counter_lo,fbtfss status,zerretlw 00incf counter_hi,fbcf counter_hi,4movf credit_count,fbtfsc status,zerretlw 00bcf mode_byte,7bcf mode_byte,5bsf mode_byte,0retlw 00If you notice, this code increments counter_hi, but it clears bit 4. Bits go from 0-7. So bits 0-3 are the only things used. Anything that rolls over into bit 4 gets clipped off. This is how the coder is assuring that the contents of counter_hi, and hence the addw PCL instruction in "pattern" do not overflow past 16. In fact, he clips the range to 0-15. 16 is not included, which is why maybe he has redundant value in the spot 15 and 16 in his pattern table. At 16, counter_hi just rolls back to zero.If you change this 4 to a 5, you will double the range of counter_hi. And your 16 retlw valued you added to the original 16 in "pattern" should now be included in the mixTo be clear, changebcf counter_hi, 4tobcf counter_hi, 5There may be more things which you must take into account and change, but this will get you started.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 29, 2018, 09:38:45 pm
content: wow yes This looks like something I can follow, excellent thank you. will work through your post and report back. yes the original writer had admitted that his code was ugly but hey it works so me personally couldn't argue with it. As I said I grew up playing with this fruit machine for hours and hours without a hitch.would be marvellous if I had a fluent understanding of coding, because believe me if I did, the perfectionist in me would completely re-write this and make it the most efficient code it could possibly be. sadly, I have trouble with coding... and mathematics for that matter.

author: KL27x
author_rank: Super Contributor
timestamp: September 29, 2018, 09:46:48 pm
content: You're welcome.Just to add: if this were important, at all, you would want to carefully check all the errors past #11, too, to make sure that increasing the range of counter_hi is not going to cause some other stack error.A perfectionist would have to completely rewrite this code. This code has very illogical/inefficient use of the stack.* But this was a first attempt at coding in assembly. And even good, efficient assembly code is rarely readable. These "tricks" I have shown are pretty much necessary to do anything complex in assembly, IMO. Without manipulating error codes, it would be near impossible for me. This is why I avoid macros. Trying to make assembly readable is essentially a lost cause; but in some ways it breaks the chain of error codes.*I take that back. This part probably only has 4 deep stack to begin with. This makes is very hard to write assembly!edited to addQuoteWhy on god's earth would you disassemble assembly when you are looking at the source code?

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 29, 2018, 11:25:10 pm
content: OK well sort of a success, increasing the counter_hi does now display the 32 hex values with the pattern like the original so yay! to that one, but playing the machine for around 10 mins I noticed 2 things.1. occasionally on a win it doesn't seem to be playing the correct light sequence, which for a win is the "pattern2" table. sometimes it plays the first 16 of the "pattern" table and other times it runs the correct one.2. and I had one instance when I had ran out of credits and after 2 seconds the "pattern" is meant to be run but the lights stayed off. again this doesn't happen every time.Thank you so much for your help by the way, I really appreciate this.

author: KL27x
author_rank: Super Contributor
timestamp: September 29, 2018, 11:32:03 pm
content: I still have this up on my computer, so error 10 showsmovf counter_hi,Wcall pattern2So pattern2 is analogous to pattern, but it only has the original 16 values, not 32. So when counter_hi is higher than 15, it is leaving pattern2 and producing a stack error. We call this "going off into the weeds."What I would try is locate feature1 (right click on the code, goto, find feature1)feature1btfss mode_byte,4goto feature2movf counter_hi,Wcall pattern2and change it to be:feature1btfss mode_byte,4goto feature2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; movf counter_hi,W ;the semicolon in front removes this from the code but leaves it there for posterity, for your own reference. In case this doesn't work.;movlw 0x0fandwf counter_hi,w;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;call pattern2and see what happens.

author: jpanhalt
author_rank: Super Contributor
timestamp: September 29, 2018, 11:49:39 pm
content: Quote from: KL27x on September 29, 2018, 09:46:48 pmIn my experience, it can be quite quite useful to see how the assembler assembled the code, particularly when there are questions about memory usage and duplicate equates. That original code is a mess, disassembly may help sort it out. I am assuming he is using MPLAB SIM to know where the code fails.We each have our own way to troubleshoot unusual problems, assuming you write Assembly often, that is one way. Please define your use of "source code." Isn't C or any other high-level language also source code?

author: KL27x
author_rank: Super Contributor
timestamp: September 29, 2018, 11:52:55 pm
content: Yeah, but C gets compiled. Disassembly shows you what the compiler wrote in assembly.If you disassemble assembly source code, you get assembly but without headers and tabbing/spacing and variable/constant names that was present in the source code!In this case "source code" means having the assembly in human form, rather than dissembled from reverse from just the hex file.You can view the list file if you want to see how the assembly code is placed in sequence by the assembler, rather than disassembling. This would be useful if you are afraid your addPCL instruction might be rolling over past a byte boundary, for instance. But in this case, the coder has org 200 before and org 300 after those pcl instructions. So this is already proofed in in the source code, which is preferable.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 12:18:26 am
content: OP: scrolling further, counter_hi is also used in other areas: auto1/2/3 and win2So I can write you a foolproof solution, if this doesn't work, by utilizing an additional bit of general memory that is only used by feature/pattern. It is often easier to do it this way and potentially use up more memory and code than to reverse engineer existing code.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 12:21:18 am
content: I love how you encapsulated that so I can see what was changed and what to put back if it doesn't work. brilliant.just testing now, so far so good. will report back.

author: rstofer
author_rank: Super Contributor
timestamp: September 30, 2018, 12:29:55 am
content: And yet, sometimes, it is helpful to have a core dump whether a disassembly or actual dump. That way you are forced to think about every instruction. There is no slipping past something because the 'name' seems right. You are dealing only with actual hardware addresses.No, it wasn't fun on the 8080s and Z80s back in the day. Digital Research's Dynamic Debugging Tool (DDT) was my best friend. Such as it was...And, no, I don't want to go back to those days but on the mid-range PICs you are almost there anyway. What an ugly architecture!

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 12:38:41 am
content: QuoteWhen the changes get more involved, you need to get more serious and start using IDE directives (#include, if/else/endif) to blink code in/out of existence but leave it intact. It will get tedious adding and erasing scores of semicolons.QuoteMind that without my fully unraveling the code, this is just a hack. If this were anything important, I would encapsulate the added code rather than mucking with a variable that is used in other places. IF it works, it is because counter_hi gets redefined/reloaded before all those other places it gets used. If it ends up causing other bugs, no problem. We can fix that.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 01:25:20 am
content: ok this seems much, much better than before, I did have one instance where on a win it seemed like it displayed the first 8 of the correct "pattern2" table before going back to my credit led's but I can't seem to get it to do it again. being playing for ages now. but then I guess if it did it once it could do it again.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 01:33:57 am
content: Ok, I suspected this. Because it's a slot machine it might take years to confirm a bug in w/e is called "win2" lol.We can either1. do a bit mask in every other instance counter_hi is used. And in this case, it would be trivial, because it's only a short code. This is what we just did, btw. The last bit of code you added is called a bit mask.2. we can allocate 1 bit of memory only accessed by feature/pattern and add a bit of confoculated code to inject this into feature. But the current registers end at 1F, and now I have to look up the memory map to make sure there's more memory. grr.I'll report back in a bit.Well, this decision was made for me. Every byte of memory is already in use.The general memory goes from 0x07 through 0x1F. And the code uses them all. (oddly, 0x07 is defined as portC, lol. Which even though it doesn't exist, it is used by the code. I don't know if is being used as more than an output, so I shall not mess with it).So there end up more than 4 places this counter_ hi is used. So because I don't want to map out the entire code loop, this may take a bit and I just have to hope we don't run out of code space. Because this is not going to be elegant.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 02:08:18 am
content: Hah, ran out of program memory.And time. Gotta eat dinner.I'll take another look, later. I'm sure there is some unused program memory if I look at the list file and shuffle things around.But one weird thing is that counter_hi is used in one areaincfsz counter_hiAnd it will never roll over to 0, unless it goes beyond 16. So now it makes it much more iffy where and when to bitmask this register.This would be sooo much easier if there was a free byte of memory. I might look for some bit that is unused and do it that way.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 02:28:02 am
content: Lol yeah I would imagine confirming a bug on a full sized machine would be nothing short of an absolute nightmare. Looking over the conversation I have saved from the forum seven odd years ago, their recollection is they kept adding features until they run out of program memory and ended up with just 3 bytes to spare! Would of been interesting to know how different the code is on the protected chip.When I was talking to him back then I had all these wild ideas of expanding on the project but he quickly brought me back down to planet earth with what would be involved. I was going change things like how much gets paid out for a given win, but I am not going to bother, I'm just after the original result now.Incidentally if you wondered what the "odds" table was for, its contains the hex codes that when converted to decimal, is the number of servo actuations made when paying out coins.As for the PORTC output thing you mentioned, not sure if this is relevant or not but the machine has things like a servo I mentioned earlier for the payout mechanism, a piezo speaker which generates a clicky sound to imitate the reels spinning and beeps when there's a win, the hold/collect and gamble/start buttons have leds in them that flash when an option to hold arises or a when a gamble game appears if all three reels match (this doesn't happen every time and I believe is randomly generated)When the option to hold is available the flashing buttons stay solid when pressed to indicate the reel has been held. There is also break beam sensor (Phototransistor and infrared led) for detecting inserted coins.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 04:29:06 am
content: edited for clarityOk, so your version doesn't do a bunch of that stuff and doesn't use the non-existent portC, right?Oh, I was looking at the wrong part of the datasheet for the 16F54. And you use the 57. So disregard this.QuoteOk, this is good. I went over it and found TWO seemingly unused registers, 0x0E and 0x0F.The code uses fsr and ind here and there, so I can't be 100% positive without even MORE work, but if they said it and I found two, it looks like these are in the clear.*Also in the 16F57, there are actually many more available registers. If it were the 16F54, then yeah, there would only be these couple left.Fix: (this will not affect anything except pattern)1. define a new variable as follows. At the top with all the other variables, add this:;Variablestemp_reg1 equ 08temp_reg2 equ 09temp_reg3 equ 0Atemp_reg4 equ 0Bmode_byte equ 0Cfunction_byte equ 0Dnew_byte equ 0E ;bit 0 used for extending "pattern" to 5 bit range. new_byte<7-1> are available. init2 loads 0x00loop_divider equ 10credit_count equ 112. Good practice to initialize variables. So in init2, add this lineinit2clrf fsrmovlw 30 ;FILE TABLE START POSITIONmovwf data_countermovlw 01movwf digit_pointermovwf mode_byteclrf switch_oldclrf switch_newclrf counter_loclrf counter_hiclrf credit_countclrf leds_valueclrf credit_displayclrf new_byte3.This is where we are using the new bit to save information. Change sequence1 tosequence1bsf counter_lo,7incf counter_lo,fbtfss status,zergoto sequendincf counter_hi,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;insert this codemovlw .1btfsc counter_hi,4xorwf new_byte,f ;this toggles bit0 of new_byte when counter_hi overflows to 16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bcf counter_hi,4 ;this must go back to the original bcf counter_hi,4 !!4. This is where we recall this information and utilize it. Change feature to:featureclrf fsrclrwmovwf portA ;SWITCH OFF DIGIT DRIVEmovf credit_display,Wbtfss mode_byte,5goto feature1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; movf counter_hi,W;clrwbtfsc new_byte,0 ;if this bit is setmovlw 0x10 ;we are going to add .16 to whatever is in the counter_hi and place the resultaddwf counter_hi,w ;in w, leaving counter_hi alone. So this is invisible to the rest of the code.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;call pattern5. Ok, this is where the paging thing throws error. so you have to go to "dummy" and change the position of the org instructionorg 0x600 ;put the org 600 instruction in front of "dummy"dummyclrf fsrmovf data_counter,Wmovwf fsrmovlw 4addwf fsr,fmovlw slowdown_time ;CONSTANT FOR SPEED CONTROLmovf ind,fbtfss status,zer ;HAS 'SLOW' REACHED 0 ?decf ind,Wmovwf ind ;RESET 'SLOW' CONSTANTretlw 00; org 600 ; remove the org 600 instruction from here and put it in front of this subroutine.The change you made to feature1 doesn't make any difference, anymore. You can leave it or change it back to how it was, before.6. Cross your fingers.

author: westfw
author_rank: Super Contributor
timestamp: September 30, 2018, 05:21:41 am
content: KL27x - that was really excellent analysis (and write-up)! (man, talk about write-only code, though!)QuoteUnfortunately, that's exactly what you'd expect to happen. The program is using the same code to display pattern and pattern2, so both patterns need to be the same length. Can you just add empty or repeated code to pattern2? It seems to still compile for the simulator for me.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 05:29:29 am
content: ^yeah, that would have fixed the pattern2 bug, if you just redundantly copied those 16 lines! Good catch! (But my previous change was adding just 1 line of code by comparison, which was better!) But there seems to also be something going on with win2, as well. So by not clearing counter_hi at 16 in the "sequence1", and clearing it at 32, instead, you might adversely affect some other part of the code that is also using counter_hi before reloading the value.As I said, it is sometimes easier to just use more memory to add stuff, so you know there is no conflict. It is one of those things that go along with writing absolute code. Keeping track of memory is a pain and should be notated, carefully, especially on device with tiny amount of memory! In this case we used just one more bit of memory and left the rest of the byte usable.Also, if you're playing along, write "errorlevel -305" and "errorlevel -306" at the top of the page, in case you aren't aware of that. Very handy to clean up your error code dialog box.

author: westfw
author_rank: Super Contributor
timestamp: September 30, 2018, 05:50:16 am
content: QuoteQuoteReally? The assembly shows lots of space left. Though of course there's that PIC limitation where it's a lot harder to use the 2nd half of each "program" page...(Or am I missing something else? It's been a long time since I've looked very hard at a low-end PIC...)Code:Program Memory Usage Start End--------- ---------0x000000 0x00008b0x000200 0x0002c70x000400 0x00050b0x000600 0x0007080x000fff 0x000fff874 out of 2053 program addresses used, program memory utilization is 42%

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 06:21:53 am
content: Yeah, I was wrong when I "ran out of program memory." In fact, I got a "must be in lower half of page" error, which I admit I am not even sure I know what that means, anymore. In the modern midrange, when you run across the page boundary, that usually means you have to shuffle code and might be out of space - at least on the current page... and since all the code is written with short calls and gotos, this is like running out of easily used space, even if you have blank pages! I just jumped the gun on that because I had to be somewhere's else. There is none of this half page stuff in the modern PICs.When OP said that they ran out of program memory, I assume he means variable memory, not programming space. (In PIC Harvard architecture, program memory is separate from variable memory!) And the "3 bytes left" seems to be a match. I found 0x0E, 0x0F are undefined. And it LOOKS like 0x10 might also be unused, but I'm not positive. It is defined, but the name is not used in the program, anywhere. But fsr and ind are used to initialize it to zero, and many a time I use code space without naming it (but I will notate the used sections of memory)In the datasheet, general purpose (this is basically RAM or variable memory) is located between 0x07 and 0x1F. So this thing has nearly zip for memory. 25 bytes.QuoteYeah, I have no clue what this means. It has been a decade since I used this type of chip, and I don't think I ever learned this part. But I take it that there are some people who actually get this bit. If changing the position of "dummy" subroutine borks the OP's code, I am at a loss. It wouldn't assemble until I did that.*edit: oh, I was looking at 16F54. The 16F57 has 72 bytes! So there's plenty more variable memory, too.

author: Ian.M
author_rank: Super Contributor
timestamp: September 30, 2018, 07:17:59 am
content: The PIC baseline program memory limitations are due to the short instruction word of the 12 bit core. It takes 11 address bits for the full address range (2K words) possible for the baseline architecture. The top two bits come from STATUS<6:5>, and the remaining 9 bits must be provided by the instruction. GOTO is special - it has a three bit opcode, so has 9 address bits and can jump to any address, but CALL has a 4 bit opcode so only has an 8 bit address. This maxes the upper 256 words of every 512 word page inaccessible to CALL.The easy fix is to put a jump table for subroutines in the bottom half of the page so their entry point is always at a callable address.However IMHO the pain of wrestling with the baseline architecture just isn't worth it. See my comments earlier about replacing it with a modern PIC.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 07:46:30 am
content: ^So the part that doesn't make sense to me is that the code assembles and apparently works just fine the way that the op posted it.There are many subroutines between 0x400 and 0x600. But after adding the seven lines of code in this patch, I get error on the "call dummy" saying it has to be in the lower half of the page.Now after moving this "dummy" subroutine to 0x600, it assembles without error. Meanwhile there are other subroutines left between 400f and 600f which (are still being called but) are still not causing that error. "slow" is located at 0x4EC, and it is called from code. And it does cause this error.Also, what is half a page? In the midrange pics, a page is every 800f. So a half page would be 400f. What does the 600f line have to do with anything, then?There was no overwriting of code. I did not run out of space between any org instruction.Hang on, I'll change the org 600 instruction and see exactly where "dummy" was when it caused error.* Ok. with the error, dummy is located at 0x503. So subroutines at 0x4EC work. At 0x600 works. At 0x503 it doesn't work. What the heck is half page in this context? Is it every 0x200 = a page? (With midrange, you have to long call/goto when passing a (0x800)"page" boundary, and this doesn't appear to be needed in this context)That must be it, then. Pages are every 0x200, so half page is 0x100. When I added that code, I pushed dummy from 0x4ff to 0x500+? And the first part of the code 0x000 to 0x100 is the bottom half of the page, not the top half, like what you might expect looking at the "page on your screen" lol. If that isn't right, then I'll never figure it out. "Pages" are a totally different can of worms with the midrange. Actually (if this is right), the baseline is easier... once you finally get over the dyslexia. If there is no pagesel and longcalls, then as long as it assembles without error, it will worky?Error Z:\EMBEDDED DESIGN\FIRMWARE\CLIP\FRUIT CLIP.ASM 181 : Call or jump not allowed at this address (must be in low half of page)

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 08:16:52 am
content: Wow OK I have a lot to go through here, it's was late over here in UK when I posted my last post so had to go to bed. Will report back when gone through it all.When they said 3 bytes to spare I assumed they meant what was already there but I can not confirm nor deny this.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 08:43:34 am
content: Yeah, I'm learning a lot, too.In fact, after chewing on what Ian said, I'm pretty sure I borked the code.I pushed dummy subroutine to another page, and now I'm pretty sure it is not going to work. I think on these baseline, there is no way to cross page boundary with long calls and pagesel.... hmm...sorry, been a long time.Now that I see what I did wrong, I think "the 3 lines left of program memory" that you were told was because of this, exactly! So hmm.. I have to take another look here. What I posted up there is not going to work!

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 09:21:18 am
content: Code addendum:So, here it is... don't do step 5 from my previous code postDo step 1 through 4. And do step 6.And you will get a error because I added a few lines of code to page 400f-600f. And this pushed "dummy" across a half page boundary. So to fix it, I have reclaimed 4 lines of code with these changes.1.timeout1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; incf counter_lo,f; btfss status,zerincfsz counter_lo,f ;saves one line;;;;;;;;;;;;;;;;;;;;;;;;;;;;goto timend;;;;;;;;;;;;;;;;;;;;;;;;;;;;; decf counter_hi,f; btfss status,zerdecfsz counter_hi,f ;saves one line;;;;;;;;;;;;;;;;;;;;;;;;;;;;goto timendbcf mode_byte,7bcf mode_byte,0bsf mode_byte,5 ; incf/decf affect status Z. But...timend retlw 00 ; incfsz doesn't affect status,Z. But timeout1 is called from extimeout, and I see no checks of Z after the return. So I think it's ok.2.sequence1bsf counter_lo,7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; incf counter_lo,f; btfss status,zerincfsz counter_lo,f ;save one line of code. against have to figure out is status,Z is importance after the return. So maybe ok.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;goto sequendincf counter_hi,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;insert this codemovlw .1 ;this is the 3 lines I added in the previous postbtfsc counter_hi,4xorwf new_byte,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bcf counter_hi,4 ;this must go back to the original bcf counter_hi,4movf credit_count,fbtfsc status,zergoto sequendbcf mode_byte,7bcf mode_byte,5bsf mode_byte,0sequend retlw 00 ;sequence1 is a branch from sequence, and this is called from exsequence,; and I see no checks of Z after this return. So I think it's fine that incfsz doesn't affect Z like incf does.3.start3clrf fsrbcf mode_byte,0bsf mode_byte,1bcf portC,2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; clrw; movwf counter_hi; movwf counter_loclrf counter_hi ;save 1 lineclrf counter_lo;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bcf function_byte,7starend retlw 00 ;and retlw 00 loads 0 in W register. So clrw should not be missed for this reason. RETLW doesn't affect status Z;;the clrw instruction sets Z bit. But... clrf also sets Z. So absolutely no worries on this one.These changes bring "dummy" subroutine back to 0x4FE in program memory to stay on the same page as it is supposed to be, which I believe is page 2 (starting from 0). So now we have room for one more line of additional code in the future!!!Also, I chanced upon STATUS, <6,5> are how pages are selected, and pages are 512 "words" which is simply more confusing to me. So yes, pages have to be selected, and it will be nice to keep everything on the page it started with, esp if you are a hack like me that can't figure out this nonsense. (Took me long enough to figure out the midrange).

author: Ian.M
author_rank: Super Contributor
timestamp: September 30, 2018, 09:51:13 am
content: You still need PAGESEL and/or LCALL, LGOTO to cross baseline page boundaries. (or use manual BSF/BCF instead of PAGESEL and save instructions when one of the page address bits STATUS<6:5> doesn't need changing). The original slot machine code uses minimal BSF/BCF STATUS for page management which doesn't help readability. Cleaning it up to use PAGESEL and LCALL would vastly help future maintainability.Each page is 512 (0x200) instruction words. The bottom half is accessible by CALL, the top half is not. i.e. If the most significant digit of the hex address is odd, CALL cant reach it.If adding code pushes a subroutine label over a half-page boundary, you need to rename the label (e.g. append 'x') and find somewhere in the bottom half of the same page to add:<label> GOTO <label>xto provide an entry point CALL can reach.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 10:02:13 am
content: QuoteAh, ok. Thanks. I totally spaced that.I guess it's essentially the same as the midrange if lcall and pagesel work. Except you also have the half page thing AND the super small pages going on.Good thing you posted that, else OP would have had issues with my half-baked solution, carelessly moving a subroutine.OP, I'm now happy with my latest addendum. But you know what they say about last words.So anyhow, if I had moved dummy to the next page, page 3, (or if you had done this already) it should require this change to work, properly:exdummy ;which is located on page 0bsf status,6 ;CALL SUBROUTINE IN PAGE 400-5FF ; this is page 2, originally.call dummy ;but this would be located on page 3, if you moved it to far side of org 600bcf status,6change this to:exdummybsf status,6bsf status,5call dummybcf status,6bcf status,5orexdummypagesel dummycall dummypagesel $orexdummylcall dummy ;beware this expands to two instructions when assembled (in midrange, this is how it always works for me but maybe I'm wrong?);in case you are using relative jumps or btfss type instruction in front of it.pagesel $ ;pagesel for some reason on midrange seems to only take one instruction??? Maybe I'm wrong, though.So well, OP you have options to try.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 12:10:54 pm
content: Oh crap I think I getting lost here, really sorry KL27x. trouble is the time of day here and when I get chance to get on this.so am I working from your latest addendum?scratch that, having read it again, I think I know what I need to do!

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 01:07:35 pm
content: As I came back to this after all the posts I did not do the step 5 you said to omit, so did not do the correction you mentioned in your last post about exdummy. step 6 really confused me though!testing now, so far so good!

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 01:49:41 pm
content: Ok had two instances in 30mins of playing that it run approx half the "pattern2" sequence on a win. Don't know whether this is relevant but I decided to plug the speaker in to test whether that was also effected and it is, it does half the amount of beeping along with half the "pattern2". Just wondered if code for peizo speaker could be stopping this from working properly maybe? I think its only doing this when I have a two reel win (when first two reels match and any on the third gives a 10 pence win) which is 2 five pence pieces since this machine only takes 5p's, this by the way is 4 servo actuations (1 actuation collects coin from coin stack and another actuation pays it into collection tray) so 4 all together for 2 coins. it seems to do this properly even if half the "pattern2" and half the beeps are run. but everything else is fine though.There Is a real chance that somehow I messed up in the instructions but I don't think I did, I was going to suggest uploading my code, but I don't want to give you the extra task of having to go through mine as well. Or if I try your edited code? would that be easier? you have already worked so hard on this for me, I don't want to give you anything extra to do, unnecessarily. really appreciate this, you're not just creating code you're creating dreams.**edit played for an hour before it did it again. at least the changes haven't broke anything else.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 06:42:54 pm
content: ASM fileIf this has the same problem, I would suggest you try changing new_byte register to location 0x0F.If that has the same problem, I would suggest you try the clip you originally uploaded to see if it didn't have this problem at the time I uploaded it?Repeat Step 6.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 06:43:35 pm
content: Hex file

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 06:44:48 pm
content: ok cool, just added extra text to above post btw.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 07:30:26 pm
content: Lol ok one thing I noticed right of the bat is I put in my custom 32 light sequence into "pattern" and it doesn't seem to run it properly, it looks to me as its playing the first 24 and then repeating again. or repeating the second set of 8 twice if that makes sense

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 07:42:09 pm
content: this is mine that does work.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 07:53:01 pm
content: Oh, haha.I was made at least one edit to my forum post but didn't do it to the code, lol.Try this one.Alsoreel_speed equ 1Fslowdown_time equ 20reel2_trigger equ 20reel1_trigger equ 50reel0_trigger equ 80Also to note: For testing purposes you might want to mess with the values of these constants. So that the thing goes faster, for debugging/validating.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 08:33:18 pm
content: sourceYeah, that would easier to try if I had attached the source code, sorry.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 08:50:43 pm
content: hahah ok, no worries dude. will report back.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 09:09:22 pm
content: ok did it again so now i'm testing with new_byte set to 0F, light show is fine on your version btw

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 09:34:44 pm
content: if this still doesn't work I am almost tempted to call it a day on this particular problem because its not as if its that bad because it happens once in a blue moon and it at least does run the correct table even though it does half it doesn't really take too much away from the aesthetic of the game. if it payed out half the money I'd be like yeah this needs sorting but it's fine and I got the 32 value light show I wanted which is fantastic.The only other problem is just when the machine gives the option to hold reels when you put the first credit in, which normally wouldn't be a problem for most of the session but when you first switch machine on, the displays default to all bars, which is part of the aesthetic but simply just holding all reels and pressing start gives an instant jackpot win. it doesn't seem to do this on the original chip. I think the hold option is a suppose to be a randomly generated thing for the most part but not sure because the source code seems to let this happen at the start without fail.any ideas on that one?**update** ok just had instance where a win did part of the "pattern" table, am switching back to new_byte equ 0E for now. although if it were someone else other than me playing the machine you probably wouldn't of noticed it to be honest.

author: KL27x
author_rank: Super Contributor
timestamp: September 30, 2018, 09:49:51 pm
content: So the most important thing for me to know at this point is what if any of these issues are present in the original source code you provided vs the updated version.The fact the creator didn't find the production version of the code and gave you this one makes me wonder if some/all of these problems might be due to this version of code he gave to you.Did you test the code you originally uploaded in the same way?Here is my guess where the issues originate at this point, but your clarification on testing of the original code would be immensely helpful.1. problems in original code 59%2. problems in intended changes 1% ; highly confident3. problems in my execution of intended changes 30% ; you never really know when coding in assembly4. register 0E and 0F perhaps utilized by the code 10% ; this is a bit weird if these problems are exactly the same when you tried both registers.If you can verify that the code as you uploaded it to me is not producing any of these problems, I am still curious to see this a bit further.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 09:59:54 pm
content: so just to clarify I am testing the completely untouched version straight from owner. will report back.

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 10:08:42 pm
content: ok just noticed something that may or may not have affected testing. just flashed device and its like it didn't take completely, first its like there was no change from last flashed code, then did it again and light show didn't show up and then decided to erase and blank check device and i then re-flashed and now I am back to original untouched code, as intended. up until now I had just been clicking program device without erasing, I forgot that mplab v8 doesn't erase device before re-program or does it?

author: Electrofinn
author_rank: Regular Contributor
timestamp: September 30, 2018, 10:44:57 pm
content: Well it looks like this falls within your 59% or should that of been 69%..anyway it gave me 2 instances of an incorrect win light show. you were absolutely on the right track, good call, I just never noticed it before, just the obvious things.

author: KL27x
author_rank: Super Contributor
timestamp: October 01, 2018, 12:23:01 am
content: I'm sorry, but I'm so so happy to hear this.I have learned quite a bit, though. And if you ever do manage to figure out the general location or memory or something more specific about the issues, try and reach back. It's just quite hard for me to debug without the hardware in front of me.I have learned (or relearned) a bunch of things though.It would appear that baseline takes 3 instructions to do a long call and 2 for a pagesel. Midrange, indeed, is just 2 and 1. This is actually a much bigger limitation than the half page thing, IMO. This could take up more than half the code space of the program loop.To get around the half page, all you should need to do is put your "Subroutine" as one instruction that is "goto subroutine.1" which is located in the upper half of the same page.My partially modified source code page attached. I cleaned out the program loop to make it more legible. And moved the initialization to page 3. And if it works, that would be nice to know. But you might want to check out the main program loop and see how it looks now.When I have trouble locating a bug in my own code, part of the "healing process" is to reformat/tab and generally clean things up. OP you might learn enough to actually fix this... esp with some help. And just see what works and what doesn't. You perhaps have to be a bit of a masochist, though. There's a lot of failure involved in assembly programming, esp when it gets overcomplicated or it's someone else's mess.*You might also try adding some bitmasks before those addwf PCL instructions. Those are a bit of a problematic thing. We added one to ... feature1, I think it was? You might try doing something that with all of the addwf PCL lookup table subroutines. This is a good idea in general when using that instruction.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 01, 2018, 02:13:37 am
content: Excellent, will try your code and do the things you suggested as well. Don't know if you have any idea about the hold problem? no worries if not, you have already done a truck load and I thank you so, so much for all the time and effort you've put in. You have been awesome thank you. Got to go sleep now, got to get up early and get my son to school but will test later today.

author: KL27x
author_rank: Super Contributor
timestamp: October 01, 2018, 03:13:45 am
content: ^ I have a few major obstacles, Finn.I have no clue how indirect addressing works on the baseline PICs, and the datasheet doesn't help. I used midrange FSR/INDF incorrectly for like 2 years before finally figuring that out. I have very little understanding of how to use software debugging/simulation. And I don't have the device. Not even a bare PIC 16F57, and frankly, I don't really want to learn any more about these obsolete devices.So in many ways, you could debug this better than I, IF you had just a few basic skills and learned just a little bit of assembly programming.QuoteSo... I have super little understanding of how this code actually works, partly because of this INDF/FSR indirect addressing mystery (to me). I have no schematic or hardware. So whatever actual physical manifestation occurs in your device, I have no idea how that relates to the code. Something as simple as a bit of test code to blink a LED and just stopping/looping is super helpful. By moving this test code around and seeing where it breaks/stops the code, one might get an idea of where this "hold problem" actually relates to the code. In the code, the headers and hints left by the creator may be very abstract and far removed from what you think it to be. There are simply no good words to describe half the issues that assembly coders solve, and you might as well have names of race horses in there.Curiously missing from the programming header information is a pinout or pin designation. There must be some inputs and outputs, and none of that info seems to be included in this asm file. If you have the schematic/device, you would have some more options for testing. Especially if there are any free pins for hooking up to LEDs or a scope or whatnot.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 01, 2018, 08:42:26 am
content: Yeah no problem I understand, the assembly language all seems very nonintuitive to me and find the comments in creators code quite vague or don't properly explain what it's doing, at least to me anyway. One thing that baffled me is why he called the table for the servo actuations "odds"why not call it "servo"... A little odd! Lol. With the problem you solved with the light sequence, I was really surprised and had no idea that what you did was required to get that to work, I felt that there was no chance I would have been able to come up with that, thought It was going to be a simple case of changing a value or range somewhere. Lol though I don't know why I was surprised because when I tried following along with a tutorial to flash a simple led, It seemed like a rediculous number of steps to get that to work, it felt like repeatedly smashing my head against a brick wall would of felt better! LolI'm not even sure the flow chart included in the magazine article would be much help to me as that could be based on the finished code. In the flow chart it seems to be asking itself, when in idle mode, is there is any credits? and if yes, is the hold feature active. What this is personally telling me is that the hold feature is suppose to be driven by a random generator, and the literature in the article does say something like this but it seems to be pointing straight to the hold feature when you put that first credit in, yet if during the game you run out of credits and decide to put a credit in, it doesn't always give you a hold but sometimes it does, that's when it seems like it's working correctly... Strange, and I don't quite know how I am going to solve this issue.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 01, 2018, 06:23:59 pm
content: Wow, KL27x you have been busy, your changes to the main program loop looks awesome and so neat and tidy, it's thing of beauty. still early in my testing but everything appears to be working ok, will update you though. Sometimes I wish it was as easy as that thing in the matrix movie where they upload to their brains what they need to know or learn In a few moments. need the assembly language program uploaded to mine lolagain thank you for everything you have done.

author: KL27x
author_rank: Super Contributor
timestamp: October 01, 2018, 07:35:06 pm
content: QuoteThis was mostly changing the tabbing to make it more readable. I've spent countless hours doing this to my own code. It's something that feels productive while you are trying to figure out what you should be thinking about. I think there's a word for this in the movie prop industry, but I forget what it is. It's also useful to leave these marks so you know where you've been and what you haven't really looked at before.QuoteProbably 60-75% of my own code comments are useless to even myself, 1 week removed from the project. Some, not all, will have a meaning if/when I dig back into it. So I totally forgive the authors for that.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;So, I did not intend to think about this code today. I was not thinking about it last night. But here it is. I just woke up and was thinking about how I was going to start my day. And a connection just popped into my head out of nowhere.this observation of yoursQuoteTable and odds are the other addwf pc lookup tables I referred to earlier.Next, notice how there are only 7 outcomes in "odds". This is an odd choice for an assembly programmer when adding one more would make life easier. Also, notice how the last two values are the same, 0x08. This is also curious. You see the same redundancy in "pattern," where the last two values (as he originally wrote it) were redundant. But at least in pattern, his redundant retlw finished a nibble. In "odds" this redundant value still leaves the table one line shy of "filling the 3rd bit".Also notice how odds is physically located in front of "pattern".Notice if w reg were loaded with b'0000111" when "odds" were called, it would jump to pattern. And it would add another 7 to the PC. And it would :retlw 0b6So when you saidQuoteDo you suppose this "part of the pattern table" has any relationship to 0xb6 by any chance? Was it exactly this "frame?" I'm assuming "display" subroutine turns that into something up there on your display... a 3x 7 segment deal, is it?;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oddsaddwf pc,fretlw 28 ;0retlw 14 ;1retlw 10 ;2retlw 0C ;3retlw 00 ;4retlw 08 ;5retlw 08 ;6patternaddwf pc,fretlw 07f ;0retlw 0bfretlw 0dfretlw 06f ;3retlw 0b7retlw 0dbretlw 06dretlw 0b6 ;7retlw 0dbretlw 0edretlw 0f6retlw 0fb ;11retlw 0fdretlw 0feretlw 0ffretlw 0ff ;15retlw 0ffretlw 0ffretlw 0ffretlw 0ff ;retlw 0ffretlw 0ffretlw 0ffretlw 0ff ;retlw 0ffretlw 0ffretlw 0ffretlw 0ff ;retlw 0ffretlw 0ffretlw 0ffretlw 0ff ;pattern2 addwf pc,fretlw 00retlw 81retlw 0C3retlw 0E7retlw 0FFretlw 0E7retlw 0C3retlw 81retlw 00retlw 81retlw 0C3retlw 0E7retlw 0FFretlw 0E7retlw 0C3retlw 81

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 01, 2018, 09:10:06 pm
content: Ok just to start, and is probably not relevant to what your asking but I'll get there, below is the values I am now using for "pattern" which is the same pattern as the PIC16C57 I can't access.pattern addwf pc,fretlw 80retlw 0C0retlw 0E0retlw 0F0retlw 0F8retlw 0FCretlw 0FEretlw 0FFretlw 7Fretlw 0BFretlw 0DFretlw 6Fretlw 0B7retlw 0DBretlw 6Dretlw 0B6retlw 0DBretlw 0EDretlw 0F6retlw 0FBretlw 0FDretlw 0FEretlw 0FFretlw 0FFretlw 7Fretlw 3Fretlw 1Fretlw 0Fretlw 07retlw 03retlw 01retlw 00I just added a load of 0FF values just for testing at the time because I hadn't yet figured out what the pattern was until recently when you fixed the code for me and was able to run my 32 values. what these values relate to is the 8 yellow leds that are above my segment displays. have attached a picture of the board I am using to test this, this is the old board as it already has the led's soldered in. each value when converted to binary actually corresponds to which leds are lit. so OFF in binary is (11111111) and so all leds are lit or 80 is (10000000) so farthest left led is lit and the rest off ect.when these values run one by one from the top of the list to the bottom, they create a chasing like led pattern. the first 8 values turn the leds on one by one and stay on as they go, the next 16 values does what I call a twinkle pattern and the last 8 is pretty much the reverse of the first 8, they turn off one by one and stay off as they go. the whole thing loops around and looks very pretty and seamless. it does this only when there are no credits and it keeps doing this until you put a credit in, when a credit is inserted the pattern stops and the leds now become a way of knowing how many credits you have, they light up one by one and stay on as each credit is inserted. obviously there are only 8 leds but even if you put more than 8 credits in, the machine still registers them and the leds only start going off one by one when the credits drop below 8.now the segment displays I believe are actually controlled from the lookup table called "table" the first value is 40 which translates to a bar on the display, I know this because I changed this once and made two segment light up instead of one bar. as for the repetition In the "odds" table that always confused me. especially since the lowest value is 08 and in decimal is 8 which is 8 servo actuations... but that's four coins (20p)… this confused me because this is not the lowest prize amount, 10p is the lowest which should be 4 servo actuations. but there is no 04 in that list, so I think that a 10p win is read from somewhere else in the code.please look at this below and go to 6:44 in the vid, you will see briefly the leds doing their thing before he puts a credit in and you'll see the rest of what happens.https://www.youtube.com/watch?v=GCGmK0gCCUI

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 01, 2018, 09:13:11 pm
content: here's prize break down

author: KL27x
author_rank: Super Contributor
timestamp: October 01, 2018, 09:29:31 pm
content: QuoteSo when you say this, you "won" and "part of the pattern table" happened, do you mean the 8 LEDs lit up in a piece of the "pattern" table?And was it the 8th value in pattern, the way you had changed it?in your revised code that would be 0xFF or all LEDs lit.FYI, in case this state machine is indeed accurate, it can help you figure out the code.The main loop calls all the subroutines in sequence, never-ending.The key to what "state" the program is in is "mode_byte". Depending on what is contained in modebyte, different parts of the Loop become active/inactive.If you wanted to figure out how the program relates to the state machine flow diagram and to the machine, itself, some basic steps would be1. figure out which bits of modebyte are actually used. This may be done with by throwing the "mode_byte not previously defined" error code.I have already formatted the main loop to tab out the mode_byte checks into their own column. It looks like there may be only 3 or so bits actually used.2. list all the subroutines which are active in each valid value of mode_byte3. figure out how that relates to the state machine diagram and/or how the machine is acting.4. you would also be curious about every place mode_byte is manipulated.Also, if you were serious about fixing this or improving it, probably a good place to start is drawing up a schematic and putting a pin configuration into the code header, just for reference. That said, I'm not saying I'm going to help you fix it, if you did this. But it is an important step.One of the things you may learn to do is to use the outputs already on there to debug. Take the 8 LED bar. You could write up a test loop to output the contents of W or mode_byte or w/e other register you are interested in to this 8 LED bar, and now you see the content wherevever you are inserting that to intentionally break the code. Most people might do that in software, but like I said, I'm low tech.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 01, 2018, 10:01:17 pm
content: yes it ran part of the revised twinkle pattern which would begin on the 9th but it could have started from the 8th but would not of noticed as it would have been too brief. btw I noticed in the list you posted you are calling the first value of 07f ;0, your counting from 0 where as I am counting from 1, to me that's value number 1 lol just saying because we maybe getting our wires crossed.everytime you have given me code i went straight in and put my custom pattern in to make sure that worked first.is that what you wanted to know? or am i not understanding you?

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 01, 2018, 10:15:17 pm
content: What I will do is save this topic thread and try my hardest to learn and work through your advice. I hope you don't feel your wasting your time with your superb write up's because if anything else it is extremely interesting and other people will certainly benefit from it, even if I end up failing to wrap my head around it.

author: KL27x
author_rank: Super Contributor
timestamp: October 01, 2018, 10:55:30 pm
content: Good idea. I suggest you continually add any notes to the code whenever you make any connection, even if you don't change any actual code.For instance, you could notepattern;the contents of W are output to 8 LED bar (where, physically? RC0-7? which port/pins?) by subroutine XYZHave fun but not too much. This kind of problem takes small bites to get anywhere. And it may end up producing only a case of indigestion.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 01, 2018, 11:12:22 pm
content: At least I can see with this the physical side of things, just connecting the dots with the code. for the eagle eyed out there, yes the capacitors are the wrong way around on the lower left of the diagram, part 2 of the article warns about the error.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 02, 2018, 12:10:31 am
content: oh wait I just re-read your comment about the redundancy of the two OFF values in the pattern table, didn't click at the time. originally there were only 16 values but I found that if I put anything less than 16 it would start running itself into the pattern2 table to make up the 16, the pattern I first put in was done in 15 so I added the extra 0FF to make it 16 so it would loop just the 16 in the "pattern" table.the odds one is curious and I think I get what your saying now. Is it possible that it jumps to retlw 0b6 and runs from there? because if your asking did it look like it just run this one value, then no, but it did look like it ran retlw 0b6 and 7 more values after it.**update ** your lastest code edit just gave me an instance where on a win it beeped once and maybe ran one value of a table before paying out, maybe that retlw 0b6. Would I just add more redundant values to the odds table to stop it jumping? no wait that's not right argh! I'm confused, so sorry. I need to think about this, but I defo think that's why I am seeing this issue on a win. I think you were on to something. f**k it I'm going to try adding another 08 value on odds table lol

author: KL27x
author_rank: Super Contributor
timestamp: October 02, 2018, 01:13:39 am
content: No, that's exactly right. At least it's exactly what I was thinking, too.What it looks like is that last redundant value in the odds table is either coincidentally the only redundant value and which happens to be done in two consecutive lines. OR it is an attempt by the coder to prevent the pointer from going beyond the bounds of what W can be. In this case it would be odd coincidence.So you are exactly right. By copying that last value and adding it in there to make a total of 8 lines to follow addwf pc in odds, it could potentially "fix it," if this is occurring. Even if it is occurring, it doesn't mean it is causing the problem you saw. In fact, after you described further, it doesn't sound like it. These lists are not performed in sequence, only one of these retlw's is the return point. So if this bad jump happend, "odds" would simply act like the 8th line below the addwf PC instruction happened to be the same line as the 8th line after same instruction in "pattern." It would not cause the "pattern" to "play" on the LEDs. It woudl just cause "odds" to have a perhaps unintended addition to its range, and w/e value was in that 8th spot might or might not cause any problem, but it wouldn't cause "part of the pattern" to light up on the LEDs (unless odds is played out to the LEDS, too, in which case it would only play that 1 frame of pattern, unless there is some other problem). Identifying what port the LEDs are connected to would help in finding the subroutine that actually takes these lookup tables and turns them into the flashing LEDs. The physical part of the problem is something you are still avoiding.This type of error, an occasional glitch is usually caused by1. Bad jump, like what we are talking about just now. This manipulating PC is one of the big things. But in assembly, all kinds of logical errors by the coder can cause this, from mistakes in using BTFSS/C and otherwise.2. Shared memory with bad handling.3. Paging/banking mishandling.So, to find the glitch, these are the type of things I would be looking for, primarily.For 2, the memory problem, it is unfortunate that you have only one free register left in bank0. And also, the code uses INDF/FSR. So to figure out what is actually free in the other banks, you would first have to figure out how INDF/FSR works on this PIC and what values are in the range used by the program. Because the code does some calculations to manipulate FSR. Also, even if you do figure out free memory on other banks, using it will require bank bit or banksel, which will be cumbersome. Memory bank handling is essentially analagous to the paging using status bits 5,6 and/or pagesel/lcall to change the page in the hidden/high part of the PC (program counter/pointer), except to the analogous memory pointer.If there were more free registers on bank 0, the approach I would use is to identify where memory/registers are shared, and see if they can't be separated. For instance, take counter_hi. It's doing something perhaps totally unrelated in auto1/2/3 (but I'm not sure). You could designate a new register as ... counter_higher (lol). And you could change counter_hi to counter_higher in say, just auto1/2/3. It might mess up the program in other ways, of course. *Now the other issue you had with the machine always starting on a win, this might be an easy fix.If it's starting the same every time, it must be because of the initialization of memory.locate init2, and check those registers that are being cleared out. If you're lucky, simply putting ";" in front of the one of the usual suspects will cause the machine to start up randomly (at least pseudorandomly; undefined memory is sorta random on start, but not truly; for this reason, I think it would be better to just make it NOT payout on the first time).*In fact, another thing comes to mind. Where that bcf counter_hi,4 instruction was (I forget the title;header, but it was error/instance #11 of counter_hi, IIRC ). Because of the way that this register is used in auto1/2/3, and because of what it does in feature/pattern, this instruction should really be replaced by a bit mask.** If somewhere else, say in autoX, counter reaches 64 or higher, when it gets used to this spot that incf counter_hi and then clears bit 4... well, when pattern is called, that will cause a bad jump.**;;;;;;;;;;;;;;;;;;;;;;;;;;;bcf counter_hi,4;movlw b'00001111'andwf counter_hi,f;;;;;;;;;;;;;;;;;;;;;;;;;Sorry if this is getting redundant. This is what I was talking about with adding some bit masks, as relating to making sure these addwf PC commands are staying in their intended playgrounds. So just keep in mind the reasons for this stuff... it's ultimately cuz you are interested in finding/fixing bad jumps and bad memory sharing. But it sounds like you're making some connections.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 02, 2018, 02:16:09 am
content: Yes lots of it was just bouncing off my head but when I read back your post and together with my experience with messing about with the tables and also a tutorial I was watching the other day about lookup tables and the program counter, which at the time didn't go in, I just had an epiphany.It's coming I think, be it at a rediculously slow snails pace. Lol

author: KL27x
author_rank: Super Contributor
timestamp: October 02, 2018, 05:32:33 am
content: QuoteAfter first playing with PIC AXE, it took me roughly 6 months to make a PIC blink using assembly. After stumbling through some crappy internet tutorials, I resorted to carrying around a PIC datasheet and slowly learning how to put read the tech speak.I highly recommend you buy the "Gooligum PIC assembly" tutorials, if you find this stuff fun. They're like $5.00 each, if I recall. I stumbled across them several years too late, but I still learned more than a few tricks. And they are easy reading/doing and will probably be fun if you get them before you burn yourself out.Once you safeguard the motor outputs, you could use your slot machine as a learning device and follow along the baseline tutorial, outputting to the LEDs and using the buttons as inputs.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 02, 2018, 04:49:34 pm
content: Think it was sequence1, I have added it anyway just to try it. created separate asm save so I can mess about.Quotehave noticed something else, when I run out of credits and after it waits the two seconds before displaying the "pattern" sequence, rather beginning at the start of the table it often starts somewhere in the middle of the table loop. just trying to figure out what this is telling me, it doesn't matter anyway it's just an interesting observation and I am thinking it has something to do with what ever is in the register at the time causing it to jump straight to that part of the table, sometimes it begins at the start of the pattern table.Don't feel you have to respond or dig any deeper, you have already spent far too much of your time on this.

author: KL27x
author_rank: Super Contributor
timestamp: October 02, 2018, 09:12:50 pm
content: Look at the subroutine sequence. You will see that the first time it is called, it is checking bit 7 of mode_byte. Presumably, this is to determine if this is the first time sequence is being called by the Loop, or not.So if mode_byte 7 is clear, this subroutine clears counter_hi, which determines where pattern starts its "cycle." And it clears counter_lo, which determines when sequence progresses to the next point (the first time, at least). And it sets bit 7 of mode_byte, so that the next time it gets called, it will not repeat these steps. Then, when sequence has been completed, bit 7 of modebyte is cleared. So it is ready to start over. Apparently, it continues until credit_count is zero. This must occur in one of the other active subroutines.Now, the problem here is that sequence, along with every single other subroutine which takes any significant amount of time, is not performed in one shot from beginning to end when it is called. Only one tiny slice of sequence gets performed on each cycle of Loop.* It will perform the same thing 256 times (as determined by counter_lo), before it progresses to the line in pattern. So counter_lo determines the speed that the LEDs change.*You know this, automatically, because there is no interrupt routines (and the chip probably doesn't even have this feature). In order to keep the 7 segment displays refreshed, no subroutine may hold the program counter hostage for any significant amount of time, unless the 7 segment displays are either all off or displaying the same thing.So while sequence is being executed, other things are also being executed. Some other part of the code might be setting bit 5 of modebyte to kill/hold sequence. Presumably if modebyte 5 is set at any other place in the code, bit 7 would also be cleared to "reset" sequence so it starts at the beginning next time. But maybe this has been missed, or maybe the authors prefer it to start at a random location. Who knows, maybe they use some of these registers as part of the random number generator. Or... to beat an old drum, here, there may be a bad memory share/handling regarding counter_hi.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sequence;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;if mode_byte,5 is cleared, these subroutines are called by Loop;sequence;random;flash;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;clrf fsrbtfsc mode_byte,7 ;TEST 'IN PROGRESS' BITgoto sequence1clrf counter_hiclrf counter_lobsf mode_byte,7 ;SET 'IN PROGRESS' BITsequence1bsf counter_lo,7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; incf counter_lo,f; btfss status,zerincfsz counter_lo,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;retlw .0incf counter_hi,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;insert this codemovlw .1btfsc counter_hi,4xorwf new_byte,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;bcf counter_hi,4 ;this must go back to the original bcf counter_hi,4movf credit_count,fbtfsc status,zerretlw .0bcf mode_byte,7bcf mode_byte,5bsf mode_byte,0retlw .0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

author: KL27x
author_rank: Super Contributor
timestamp: October 02, 2018, 09:37:05 pm
content: This structure of the subroutine is not too great. BTW, here, I will show you how to free up some extra space so you have more room on page 3.I shuffled one of the subroutines and I added some new code to feature, so you can see how to change the rate of the LED pattern. See "feature".So check out "slow" to see how to liberate some space if you run into the "half page error."pages are program memory space000-1ff page0200-3ff page1400-5ff page2600-7ff page3000-0ff is the bottom half of page0100-1ff is the top half of page0To see where any of your subroutines/labels are, you can open the list file.Click "file" at the top left of the ide.Select OpenAnd change "file type" box to find list fileAnd open the list file.At the very bottom of this file, there are all your labels in alphabetical order. And in the leftmost column you will find the location of this label to see what page it is on.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 02, 2018, 09:45:34 pm
content: it's really annoying that he didn't have the final code but then I don't think It would of looked much better if this release is anything to go by.can you confirm that I put the bit mask in correctly?sequence1bsf counter_lo,7; v2.02;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; incf counter_lo,f; btfss status,zerincfsz counter_lo,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;goto sequendincf counter_hi,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;insert this codemovlw .1btfsc counter_hi,4xorwf new_byte,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bcf counter_hi,4 ;this must go back to the original bcf counter_hi,4;movlw b'00001111'andwf counter_hi,f;;;;;;;;;;;;;;;;;;;;;;;;;movf credit_count,fbtfsc status,zergoto sequendbcf mode_byte,7bcf mode_byte,5bsf mode_byte,0sequend retlw 00

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 02, 2018, 09:46:55 pm
content: oh ok just read your last post.

author: KL27x
author_rank: Super Contributor
timestamp: October 02, 2018, 09:50:35 pm
content: ^Yeah, that is fine. But note that when you did that, you used the last remaining line of program memory in page2. This is going to make further debugging hell. So see my last post and check out that asm file.If you want to learn how to write assembly, check out Gooligum PIC assembly. You will be writing assembly in a few days with the headstart you already have.If you just want this thing to work, make another complete working slot machine and gift it to me.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 02, 2018, 10:13:11 pm
content: lol on a serious note I might just do that. I have loads of spare parts to make 5-10 of these things lolyou know what it's like when you order a part and end up having to order way more than one, its been like that for practically everything I have ordered lolmy next hurdle is I have to learn some adobe illustrator to produce a vector drawing so a can get the plastic parts laser cut for the pay mechanism. sod doing myself again, me and my dad made it happen back in the day but we ended up with very crude and unevenly cut mechanism which worked for a long time but was very difficult in the beginning to get done with limited tools.I just spent the last four months teaching myself easyeda, I finally achieved it and had boards produced and have turned out excellent. I had to make some design and pinout changes but it turned out well.also the sticker that went on the front of the box which back then you had to order, I have completely redone in photoshop with changes to the graphic around the buttons because the buttons are different shape to the original. so yeah still a bit to go but its coming together.

author: KL27x
author_rank: Super Contributor
timestamp: October 02, 2018, 10:14:49 pm
content: Well, it sounds like you're well on your way to being featured on Make!

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 02, 2018, 10:21:20 pm
content: lol I wish. I wish I had your knowledge though. I'd probably be doing things like changing the segment displays for oleds with real fruit graphics and the like. but as it is it's still a great toy and I am enjoying the nostalgia trip at the moment.

author: KL27x
author_rank: Super Contributor
timestamp: October 02, 2018, 11:03:59 pm
content: Just to go way back, here:QuoteIn this case, the writers of the code are designating bit location of "carry" and "zer." While "ind" is designating a register address.This is redundant if you include the .inc file for the part. Because these are already defined in the device .inc.The .inc file by default defines C bit as 0 and Z bit as 2.Address of INDF is by default 0x00 (same as 0 or .0 or b'00000000'; we just write it this way because it looks more like an address)So there is no conflict, other than you can misuse any designated register or bit designation.For instance, you can writeMovlw PORTAand instead of moving the contents at this address to W, it will load the value of that address.And you can writebsf PORTA,Zthis will set bit 2 of PORTA, even though the only reason Z bit was defined was to make using STATUS,Z easier to remember than STATUS,2 (and possibly more consistent between different devices).ormovlw Zwould put 0x02 in W.This is the reason the IDE can't throw an error when you define multiple things with the same number. That can be an address, it can be a value/constant, or it can be a bit designator 0-7, and it all depends on how the coder uses it. There are dozens of bit designators in the .inc header that will be the same value.The assembler does not distinguish at all between address and literals/constants. We write them differently just to reinforce the difference, because it's up to the coder to know the difference.This is why I always end constant names with ".c" for instance. Even though I like to define them thusly:constant name.c = 0x01This is absolutely no differnet in result than writingname.c equ 1Now, if you wanted to go down this road, you could make "zer" have more utility in a way.#define zer STATUS,Zand now you can writebtfss zerinstead ofbtfss STATUS,ZIn this case, since STATUS is accessible from any bank, you don't need to worry about banking, so you don't have to remember what register zer is even associated with to do this.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 02, 2018, 11:36:40 pm
content: your last asm was probably just meant as an exercise to go with what your teaching me but just thought I'd let you know just in case, it sometimes, but not all the time, fails to run "pattern" on a win. lights just stay off.

author: KL27x
author_rank: Super Contributor
timestamp: October 02, 2018, 11:56:36 pm
content: This is an example of how memory bugs happen. I didn't check the other subroutines that might be using counter_lo. So now we learn more, one tooth at a time.So, let me guess, it also didn't change the speed of the sequence?bsf counter_lo,7I missed this line.bsf counter_lo,7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; incf counter_lo,f; btfss status,zerincfsz counter_lo,f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;retlw .0movlw .128 ;this is b;10000000; if bit 7 gets set, anyway, then this is the same value as zero!* But this register is evidently used elsewheremovwf counter_lo*As far as this subroutine in isolation is concerned. But elsewhere in another subroutine, there is apparently something else. I'm guess there's a Z check of counter_lo in another subroutine**, and 0x80 is not the same thing as zero, as far as other part of the code might be concerned.**similarly to how the coin_counter gets a Z check at the end of this "sequence" subroutine.When writing code, I will end up breaking it many many times. When altering my own code, I'll break it many more times. When altering someone else's code, I'll break it pretty much nonstop. This is why trying to fix it over the internet is pretty much impossible for myself. If it were here, I'd break it just as often, but the iterations would happen much much faster.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 03, 2018, 12:46:37 am
content: QuoteYou guessed right. Will have to look at your posts again tomorrow, this is blowing my mind a little bit lol finding this really hard. I think with this it's going to be like most things I find hard, the more time I expose myself to it the better.QuoteYes absolutely understand that.

author: KL27x
author_rank: Super Contributor
timestamp: October 03, 2018, 12:56:39 am
content: Hard is an understatement. The way these guys used counter_hi and counter_lo is very, very, intertwined and obfuscating. This is made to fail. These counters are manipulated in all kinds of different ways in different subroutines.If they (or he.. I bet anything there was one guy coding and one guy sharing credit) were still coding today and wrote a similar program (on a baseline device, for some reason), they probably would have found a much better way to do this.I imagine I would have a 2 byte counter, incremented only in the main Loop. And instead of Z checks in the individual subroutines, there ought to be compares, doing a subtraction of a literal and a C check. And they would have to submit a request for reset, which if the counter is in use by another routine, this should produce some obvious error code say on the output of the displays.So, here's the rub. There's essentially zero chance you're gonna fix with google and intuition. Maybe in a matter of weeks, if you go through the Gooligum thing and don't lose interest.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 03, 2018, 01:20:52 am
content: QuoteI think you're absolutely right about that, obviously he or "they" managed to achieve it in the end, the PIC16C57 I have is proof of that, but even that, I bet if we were able to see to the contents of that pic there would still be the same theme of unorthodox coding practices going on.It's shame really, I didn't think for a minute that it would be this hard to sort out.

author: KL27x
author_rank: Super Contributor
timestamp: October 03, 2018, 02:38:46 am
content: QuoteYou're original question actually wasn't. Adding stuff is much easier than fixing stuff. Debugging code is why I have learned how to patch drywall.So if shoring up those lookup tables doesn't patch things, there isn't much low-hanging fruit left to my knowledge.QuoteMuch like finishing a PCB and finishing the BOM, sourcing every last part, finishing a quasi professional schematic, and tweaking and verifying all the Gerber settings, and answering stupid questions from the PCB manufacturer/assembler... It's that last few details that suck the worst. If I could do things 95% and stop there, I would have the greatest job in the world.I've actually lost a final production pcb file before; not yet done that with code, though. Luckily. Code can't be reverse engineered from the chip, unlike a pcb.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 03, 2018, 08:58:50 pm
content: lol, yeah bit of a bummer. I do think its kind of curious how the writer couldn't find the final release but could find this one, especially given he seemed quite proud of the success of getting it published after working a year on it and in the video he has the magazine cover on the wall. Me personally would be backing it up everywhere, but then that's me, and maybe my background in computer maintenance tells me never to trust just one back up location. Either way it's frustrating because the original chip is flawless in it's operation, that is kind of why I wanted to at least recreate it because if this chip suddenly goes kaput! it's lost forever.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 04, 2018, 11:12:17 pm
content: Have a very positive update, as of the asm when we added a bitmask and an extra value to the "odds" table I am happy to report the following...1. The machine seems to consistently run the correct "pattern2" table on a win, which is the problem I didn't realise existed in the source code.2. The machine seems to consistently run the full and not just half the "pattern2" table on a win, full sound pattern too!3. The machine did have 2 instances where it didn't run the "pattern" table after 2 seconds of running out of credits (returning to sequence mode), however I realised that if I just waited approx 30-45 seconds the pattern does actually begin to play, which I am actually fine with as it does actually do it and that's the main thing. but perhaps code wise you may know what might be causing that.4. The machine doesn't always have the option to hold all reels when you insert the first credit upon first switch on, which is desirable as it adds a chance element to the game that the player may or may not be able to bag a jackpot win as the default position of the reels on first switch on is all bars.I can take no credit for this as all credit goes to KL27x for his excellent work on taking such a borked code and turning it into a working one, as well as your excellent write up, It's been an education. Thank you so much.

author: KL27x
author_rank: Super Contributor
timestamp: October 05, 2018, 08:42:29 am
content: Glad to see it's improving!QuoteWell, hmm. if it was NOT doing this before, then maybe we messed something up with the bitmasking. So in hindsight, I figure we can go back to the original version of the code and do a cleaner or more targeted fix.* We're gonna do the mask right in the lookup tables. This way, if his code illogically needs counter_hi (or w/e other registers are being loaded before these lookup tables are called) to be beyond the parameters of the table, this fix will allow for that coder oversight/duality.*I intended the results of those bitmasks to only affect contents of w, and only where it was loaded just before calling these tables. But I found a spot where I did a mask to the register, itself, at least in my own code I was messing with. In sequence1. I don't know if I gave you that version. But the following fix on the original code will ensure these kinds of mistakes that I might have given you (or that you may have made) will be avoided. (OTOH, maybe a "mistake" was what fixed one or more of the other problems!)If this works, you can use it like this and simply add just those steps we did in the post were we added "new_byte" in order to extend pattern (which was a "clean" modification), minus any place I put a bitmask in there (if I did so).Code:table;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;andlw0x1F;b'00011111';;32 lines 0-31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;addwfpc,fretlw40 ;0retlw08retlw00retlw00 ;3retlw23 ;4retlw77retlw5Cretlw08 ;7retlw01retlw60retlw38retlw10 ;11retlw00retlw01retlw62retlw3F ;15retlw54retlw08retlw00retlw21 ;19retlw73retlw5Cretlw08retlw01 ;23retlw60retlw39retlw50retlw08 ;27retlw00retlw01 ;29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;add 2 redundat retlw'sto complete this 5 bit tableretlw01retlw01;31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;odds;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;andlw0x07;b'00000111';;8 lines 0-7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;addwfpc,fretlw28;0retlw14;1retlw10;2retlw0C;3retlw00;4retlw08;5retlw08 ;6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;add a redunant relw to complete this 3 bit tableretlw08 ;7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;pattern;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;andlw0x1F;b'00011111';;32 lines 0-31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;addwfpc,fretlw07f;0retlw0bfretlw0dfretlw06f;3retlw0b7retlw0dbretlw06dretlw0b6;7retlw0dbretlw0edretlw0f6retlw0fb;11retlw0fdretlw0feretlw0ffretlw0ff;15retlw0ffretlw0ffretlw0ffretlw0ff;retlw0ffretlw0ffretlw0ffretlw0ff;retlw0ffretlw0ffretlw0ffretlw0ff;retlw0ffretlw0ffretlw0ffretlw0ff;31pattern2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;andlw0x0F;b'00001111';;16 lines 0-15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;addwfpc,fretlw00 ;0retlw81retlw0C3retlw0E7retlw0FFretlw0E7retlw0C3retlw81;7retlw00retlw81retlw0C3retlw0E7retlw0FFretlw0E7retlw0C3retlw81;15

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 05, 2018, 12:13:34 pm
content: You know it's funny you should mention the above because as I was trying think logically about how this might be working, I was thinking couldn't something be incorporated into those tables to do that job, but I just didn't know how or what or even if it would work. You see! There's hope for me yet! LolYou made some major changes to the program loop and shuffled some stuff since then and made it look way neater, the attached asm is where I am at with code,can I not just remove the bitmask from "sequence1" and do the above modifications?only other things I have done is add my custom "pattern" and add tabs or removed tabs so it compiled without warnings.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 05, 2018, 08:16:22 pm
content: just thought i'd try above changes while I gave you time to reply and without bitmask in sequence1 the lights do strange things but with the bitmask its fine. not done enough testing to see if I broke something else but then I didn't want to just in case your face palming about what I was asking loli think i spoke to soon about the pattern2 not doing the full pattern because its just done it on what i thought was the good code...damn it. i was playing it all night aswell..strange. think i might try what you originally told me to do from original code.getting really confused about what was what with all the edits.

author: KL27x
author_rank: Super Contributor
timestamp: October 05, 2018, 09:58:37 pm
content: New revision v21 attachedWell, I just looked at the code you attached, and it looks like all you did was to add that extra line to the odds table? You didn't add any bitmasks, at all, right?So I did the changes in my last post to it and restored sequence1 to how it was, other than the part with new_byte.QuoteThis is where figuring out how to mess with the code and having the device is helpful. If you learned how to find where these issues correlate with the code and how to manipulate the code, you could write a test code between the initialization and the main Loop to set the mode_byte to where it needs to be to jump to this identified problem area. And you could put in test values into the pertinent registers to reproduce the error, without having to play a slot machine for hours.Any rate, since you did not add the bitmasking and simply lengthened odds table, this new version v21 may actually behave differently, maybe even more correctly if we're lucky.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 05, 2018, 10:09:54 pm
content: Ok will test it. big headache this isn't it, I feel we getting closer though. because everything else seems ok. we will see.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 05, 2018, 10:17:20 pm
content: Quotejust that one in sequence1, which looking at v21 you have done away with.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 05, 2018, 10:29:14 pm
content: ok so its just that thing where it didn't play the pattern2 after running out of credits, but again just waiting for 30 seconds or so it begins to play, but mostly it does it after two seconds.

author: KL27x
author_rank: Super Contributor
timestamp: October 05, 2018, 11:55:09 pm
content: Well, I could throw more darts, but I'd probably just be wasting our time.Timeout, featuredel, and anywhere credit_count Z check is done are places to start breaking the code and seeing what gives. Mode_byte,7 might be involved. It looks like a lock bit to prevent subroutines from resetting certain registers when others are using them. But to begin putting any of that together would take active measures, breaking the code and seeing what happens.So it's your call if this is good enough or if you want to get your hands dirty.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 06, 2018, 12:09:06 am
content: well that bit seems good enough to me, however I just had an instance where it didn't do the full pattern2 on a win but something else has cropped up that I need to do further testing on because all this time I have been using a new servo but have noticed that on every servo actuation that the displays and leds very slighty light up and it doesn't do this with my other servo and I have a hunch that maybe the servo maybe interfering with the chips operation. I don't know if its a back emf issue or what but need to rule this out first I think.also when you said it may behave differently, I have noticed that the win sequence seems quicker and the beeping seems a little higher in pitch lol I tried other programmed chip with v20 code on it and I swear its slower or am I going nuts.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 06, 2018, 12:24:29 am
content: no just confirmed! the servo isn't the cause its just done it again. I am beginning to think we wasting time on this, we could be at this forever and I bet your getting sick off this lol

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 06, 2018, 12:12:06 pm
content: I noticed certain things, even in the original source code, run faster than the original chip, like the servo actuations, the win sequence, the flashing of the hold leds ect. My question to is, Is it possible that problems could occur if the program is running to quickly? I'm just thinking clock cycles and timing. And if so how would we go about slowing it down?

author: KL27x
author_rank: Super Contributor
timestamp: October 06, 2018, 05:25:27 pm
content: QuoteNo. If the servo is doing what it's supposed to, that is the only thing that has a speed limitation. The rest of the machine, AFAIK, has no speed limitation.QuoteThe clock speed is set by the external crystal. You could use a slower crystal.You could also try changing the program constants. Programming constants are often there for tuning things like speed/delays. By virtue of existing, constants are something the coder wanted easy access to in order to tweak/tune/adjust, himself. So while doing so will almost certainly not fix the bug, messing around with these constants might give you some insight into how the program works.

author: Ian.M
author_rank: Super Contributor
timestamp: October 06, 2018, 05:53:54 pm
content: If by servo you mean RC servo, the position they move to is set by the pulsewidth, so changing the MCU clock speed will change the position they move to (until the pulse repetition rate goes out of range) , not the actuation speed. To control the speed of movement, the code would need to loop through intermediate positions rapidly enough and with a small enough position increment to cause the servo to move at a steady rate rather than driving to the new final position at its maximum motor speed.At this point you have a much better understanding of what the code needs to do and how the hardware works than you did initially, and IMHO the optimum way forward, assuming the board has a socket for a DIP package PIC16x57, would be to design a pin compatible module with a modern PIC on it to let you rewrite the firmware without compromises using a high level language e.g Microchip XC8. With some thought given to choice of PIC and pinout allocation, you could probably have a dedicated ICSP/ICD header on the module allowing you to debug the new application in circuit, so you could pause execution at any time to examine/modify state variables etc.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 06, 2018, 06:10:21 pm
content: @Kl27x yeah I thought as much. oh well. The ones in the "constants" list seem to be for just the reels, messing with some of them had some strange results like the reels would stop half way between one fruit and another lol one effects the altogether speed but as far as being able to control flashing speeds, I'm guessing they exist in there respective headers?@Ian.m yep, I agree. I am happy with how far we have come and I learnt new things on the way. completely re-doing it maybe something for me to aim for in future.

author: KL27x
author_rank: Super Contributor
timestamp: October 06, 2018, 06:28:21 pm
content: To expand on what Ian said, there is perhaps the only way to make a servo move from position A to B faster is that it is a different brand of servo, it has less resistance to movement, or it is getting higher voltage. So what you are probably saying is that the servo pauses a shorter amount of time before moving to the next position.If the crystal is the same frequency, the most likely reason for the "good" machine to run slightly slower is because the code was changed and more instructions were added or are being executed per program loop. The average length of the program loop essentially determines the "program clock speed," due to how the code is structured. Many/most/all of the delays in this code are predicated off of main loop cycles.So one might guess they had to add a significant amount of code to fix the bug.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 06, 2018, 07:25:02 pm
content: I see what your saying now, yes there is less of a pause between actuations as compared to the original chip as opposed to the actuations themselves being quicker, that is to say the actuation speed is constant throughout but the pause is shorter.If I am understanding this correctly, things like the led blink rate is a product of how many instructions exist in a given loop and not a changeable variable?Quotemaybe this might be what they were talking about when they said they did it with just 3 bytes to spare...perhaps.

author: KL27x
author_rank: Super Contributor
timestamp: October 06, 2018, 07:32:50 pm
content: QuoteDependent on both. There will be a variable/counter, which can be adjusted by the coder, sometimes done through a constant. But what it's counting (in this particular code) is loops/executions of the main program loop.So if pretty much EVERYTHING is slightly slower in the final version, vs one thing relatively slower compared to other things, it is probably a byproduct of there having been added a significant amount of instructions to the main program loop or to a subroutine which is active all or a large proportion of the time. Vs the programmer having slightly tweaked all these counters, proportionally.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 06, 2018, 09:16:00 pm
content: Ok I understand, is programming in a higher level language any better than this? I am beginning to hate this assembly language lol

author: Ian.M
author_rank: Super Contributor
timestamp: October 06, 2018, 09:52:45 pm
content: Quote from: Electrofinn on October 06, 2018, 09:16:00 pmMuch!Assuming you stick to vanilla 'C' without a RTOS to keep it simple, typically for something like this, you'd write functions for each task, each implemented as a non-blocking state machine, with persistent state, + an initialisation function, then in the main() function, you'd call init(), then enter a loop to execute all the task functions in turn, with a sandwich delay using a hardware timer at the end of it so the loop execution time remains constant irrespective of the code executed, as long as the execution time of all the task functions is less than the total loop time. Assuming a suitable PIC, you'd probably also have interrupt driven display multiplexing and hardware assisted servo pulse generation so their interface to the task functions would be via a memory mapped display buffer, and an array of servo positions, one for each servo. Because each task function uses local variables except for a few globals like the servo positions, display buffer, current credit and overall state, there would be a much lower risk of unexpected interactions between them. Also 'C' is *far* more human-readable than assembler, as stuff like generating and correctly accessing RETLW tables is handled invisibly by the compiler - you simply define an array of constants then use the array name with an index in square brackets to access the Nth element of it.

author: rstofer
author_rank: Super Contributor
timestamp: October 06, 2018, 10:08:24 pm
content: If your chosen chip is tight on memory, C isn't the way to go.I have used cc5xhttp://www.bknd.com/cc5x/At the time, 10 years ago, it didn't implement the full C language and, realistically, some legal constructs probably don't translate well to the PIC.

author: KL27x
author_rank: Super Contributor
timestamp: October 06, 2018, 10:11:00 pm
content: QuoteAgreed. But the explanation is a little lacking to me.QuoteWith the exception of "the sandwich delay using a hardware timer," you could say that this assembly program pretty much follows this description to a T. And with a hardware timer, you could implement such a feature in assembly, as well.QuoteThe reason this is a problem in this code is because there are no interrupts on this device. And because, very typically for a noob, he tried to squash all his variables into bank0 to avoid learning. This isn't an assembly vs C problem, IMO. And as rstofer said, you will need much more memory to use C, both data and program memory... particular with PIC baseline architecture which is not efficient with C.IMO, the two most important difference are1. that functions/subroutines in C are in many ways easier to read and modify. If you do not predict future needs or potential issues, it is easy to paint yourself into a corner in assembly to where your code is beyond practical repair. In C, making a paradigm shift might mean moving one parenthesis, and the compiler rips up the old framework and automatically rewrites 1000 lines of assembly.2. C automatically handles when you writes code/routines that occur "simultaneously," to some extent. It hides that, to some extent. (And along with that, any C compiler would produce a metric crap ton of assembly in order to do what this code does... if it had to deal with the limitations of this exact device. This why Ian suggested a more modern device)One of the biggest challenges with assembly really has nothing to do with coding or logic. It's simply the navigation of the code. Over 10 years of coding in assembly, the main improvements I have made are learning how to do that. No matter how you write it, it always ends up feeling like you can only looking at a single point of a strand of DNA that is 30 miles long. The most important tricks to learn are how to use the tools in the IDE in a way that makes this more manageable. In C, this entire code (minus the headers) might fit in one screen shot.The other thing is learning to be more wasteful of the resources. Like a C compiler. When you start, it's easy to be stingy, but it is usually better to waste a ton of memory and programming space, here and there, to write code in a way that is more easy to maintain and modify and less easy to make inadvertent bugs.

author: rstofer
author_rank: Super Contributor
timestamp: October 06, 2018, 11:53:35 pm
content: One of the problems with the mid-range PIC, using assembly language, is paging. I have no idea how long the code is for this project but if you start to approach 2k, you need to figure out how to do paging. It's truly a PITA.http://www.piclist.com/techref/microchip/pages.htmAn example might be a lookup table that crosses a 2k boundary. You can get to one end of the table but when you try to address the far end, in the next bank, what you really get is a wrap-around in the currently addressed bank. And that is usually trash!Hint: If you are going to exceed 2k anyway, start your tables at the beginning of a new page. You have to worry about PCLATH but you would anyway. What you don't want is to have the tables cross a boundary.Banking is a similar problem for variables. You can only reach the currently addressed bank and if your variable is in another bank, you have to get involved with BANKSEL.https://www.rs-online.com/designspark/the-curse-of-the-microchip-banksel--pageselThe mid-range PICs are truly a PITA. That's one reason why people like the AVR chips. It has a nice, regular, architecture with no paging or banking required. It also has a much larger instruction set and this can be either fantastic or a lot more work. AVR chips work a lot better with C, hence the popularity of the Arduino and the ATmega328.

author: KL27x
author_rank: Super Contributor
timestamp: October 07, 2018, 12:05:58 am
content: 16F57 isn't even a midrange PIC; it's baseline. Pages are only 2 address bytes long, lol. So it's not 2k per page, it's 0.5k. Code is already spanning all 4 pages of program space. This device has no interrupts and a 2 deep stack!QuotePIC is worse than that, even. For pointer manipulation, the table must not cross a single address byte or it wraps back to the beginning of that byte block. Tables in this code all start and finish between200f and 299f200h and 2FFh, so no problem, there.*For larger tables you could potentially put them in data memory in an enhanced midrange PIC, where all banks are accessible in a continuous linear block with INDF.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 07, 2018, 01:10:14 am
content: Just having a last ditch effort here, gone back to basics. trying original source code with some of your earlier steps with bitmasks on tables. I'll tell ya, if I had the money! I'd offer you a large sum. the stuff you guy's have mentioned is like a university course worth! you may say I shouldn't doubt myself but...too late! lol

author: KL27x
author_rank: Super Contributor
timestamp: October 07, 2018, 01:45:23 am
content: QuoteOh, the irony.Some of the other PIC assembly coders on the forum laugh off my suggestions/practices and more or less think I'm a total idiot.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 07, 2018, 02:28:49 am
content: Lmao really! Well if they think they're that good they could sort this code out without suggesting I change the pic or some other drastic measure couldn't they lol after all a pair of novices managed it in the end on the same hardware.I already know you could do it, it's just almost impossible to sort out over the Internet and without the hardware in front of you, Add to that it's just way too much work to ask of someone that I can't pay. Nah, you know your stuff, no argument here.

author: KL27x
author_rank: Super Contributor
timestamp: October 07, 2018, 03:48:19 am
content: Oh, at least one of them has dropped by, already, to drop his 2 cents on the pile. But AFAIC, he completely missed the can. The other expert is still doing Edit>Find " " to work out the code flow, after transferring it into a bare bones word editor program.... butQuoteIan.M is one of the most knowledgeable guys alive concerning PIC micros. He answered more than a few questions of mine when I first started learning PIC assembly over on the Microchip forums. Even though it took at least a day or two of reading to understand his 3 sentence answers.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 07, 2018, 08:29:28 am
content: I'll let them off lol, especially since all I can do is test things like a primitive being would i.e bang the thing against my head a couple times before grunting.

author: jpanhalt
author_rank: Super Contributor
timestamp: October 07, 2018, 10:40:51 am
content: Quote from: KL27x on October 07, 2018, 12:05:58 amAnd previously KL27x said:Quote from: KL27x on June 05, 2017, 01:27:50 amGlad you finally looked at the datasheet.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 07, 2018, 02:06:31 pm
content: Have tried my attempt and still no joy, still sometimes runs only part of the "pattern2" on a win. Sometimes it runs like one frame with one beep, or does something like half of it and half the amount of beeping.Seems to be the only thing left that's wrong with this except... And to open up another can of worms lol..Occasionally when winning a jackpot, it stupidly gives you an option to gamble or collect, where it should be just going straight to payout mode when you get three bars! Now, this is not a new problem and is one forgot existed and looking over the conversation I had with creator way back when, it's a question I didn't get answer to because the conversation had digressed, which was my fault. But looking at the code in the "gamble" section, if you match three reels in general play and it enters gamble mode and you manage to gamble your way upto "- - -", the machine knows to instantly pay out. I was wondering if this part of the code could be simply copied to the payout section or where ever it is in the code that it looks for matching reels such that if you spin the reels and it lands on "- - -" it just goes straight to payout rather going to gamble mode... Then again probably not since when is anything in this code or assembly in general ever that simple!I meen the machine still gives the money if you press collect but it's silly the machine even offers a choice to gamble since pressing gamble would just scroll the reels down to the next prize down which is "A A A" = 50pThis "pattern2" issue is bummer though, at least it reads from the correct table, which is an improvement over the source code I guess. This code seems like it's in a right mucking fuddle! Lol

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 07, 2018, 10:36:39 pm
content: QuoteDo you know what, I'm game if you are!but only if you are.the 30 sec delay thing to return to the feature LEDs doesn't bother me, its this partial pattern2 on a win thing that i think really wrecks this. but if the both end up getting fixed as a result then whatever.

author: KL27x
author_rank: Super Contributor
timestamp: October 08, 2018, 04:58:14 am
content: QuoteWell, thanks Jpanhalt. This guy sounds like a fucking idiot!but only if you are.Well, I meant that this would be on you to take some initiate and break some eggs.Example:QuoteTo you this means something. You're the only one that knows what is supposed to happen. What this pattern2 thing manifests as? No one else even knows. Is it something displays on the 7 segments or the 8 LED thing or what?If you wanted me to help, you have to describe what is supposed to happen, and what erroneously happens, how often, under what conditions, and you would have to describe it in super particular detail. Doe the pattern2 erroneously happen at the same time as what's normally supposed to happen. Does the regular function get put on hold and continue AFTER this half-pattern2 thing?See, a video AND a schematic or pinout would perhaps be a good starting point. There's a ton of information that you have but no one else does. So either you need to learn to debug and write assembly, or you need to step up and start gathering and posting this information.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 08, 2018, 07:04:57 am
content: OK allow me a little time to put this together and I will report back.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 08, 2018, 12:55:55 pm
content: Ok, I have here another video, this time from brett, the other dude that was involved in the project. His video illustrates perfectly what "pattern2" is doing."pattern2" and "pattern" for that matter are both for the 8 LED's only.Firstly, a little about "pattern" and then "pattern2"...0:31 into the video he switches the machine on and after approx 2 seconds "pattern" begins its LED sequence (you managed to sort this out already by getting it to run 32 values instead of 16) this is also the sequence thatsometimesdoesn't begin until 30-45sec after running out of credits. Its supposed to be approx 2 seconds after, as you can see at 0:58 into the video, it finishes paying out and he runs out of credits, then approx 2 seconds after, returns to its "pattern" sequence. Another interesting observation on my machine is thatsometimesit doesn't always begin at the start of the "pattern" table. I took some video footage and slowed it down and managed to conclude that when it does begin in the wrong place, it begins on the 17th value (16th if counting from 0) which is 0DB. but if we never sort this out It wouldn't really bother me but it maybe that this and the next problem are somehow related.Now...About pattern2...0:50 into the video, watch what happens when he manages to get a win, which in this case he matches the first two reels (I provided a prize breakdown in an earlier post). As soon as the reels stop, it immediately begins it's "pattern2" LED sequence and is accompanied with a beeping sound, you see the LEDs start illuminating from the outside to the inside and from the inside to the outside, it does this twice (which is the complete "Pattern2" loop). Once the sequence is finished, the servo then begins to Payout the money.As I've previously described,sometimesit does not do the full "pattern2" loop, we already know the complete loop is comprised of 16 hex values, which when converted to their binary equivalents, represents which of the 8 LEDs are lit and which aren't. the problem is that it sometimes will do just 1 frame (one value) of the sixteen, accompanied by 1 beep, or it'll sometimes do more of the loop accompanied by the same amount of beeping before stopping, in either case in does not complete the full loop. Note that the beeping is affected in the exactly the same way as the LED loop. Also note that after this partial loop is finished, the servo begins paying out as normal. An interesting observation is that it seems to be able to do a full loop more times than it fails to do it.In the attached schematic, the LEDs are connected to RB0-RB7 of the Pic, pin numbers are also illustrated in the schematic. here is the two parts of the magazine article as it was published, which the attached schematic came from. I had to save the attached schematic at a lesser quality for it to allow me to upload but for a better quality version, download the following PDF files. schematic is in part 1.Part 1http://www.epemag.wimborne.co.uk/EPE_Fruit_Machine_part_1Dec94.pdfpart 2http://www.epemag.wimborne.co.uk/EPE_Fruit_Machine_part_2Jan95.pdfNote that I am currently using your last asm, Fruit machine v21 beta.I think problem for me is that while I find programming interesting and I like to try and learn, I think my interests lay in classical electronics and project building and for me to complete this project in any meaningful amount of time it's obvious to me that I am going to need some help with this. I have tried hard to go away and work on this myself and I'm failing miserably and Not that I wanted to disclose this on here but I suffer with a mood disorder and I'm finding the concentration and patience needed for this a little beyond me, but at the same time I don't want be a failure and I don't want to just give up on this project, I have come so far.

author: KL27x
author_rank: Super Contributor
timestamp: October 08, 2018, 07:54:49 pm
content: QuoteThis is because of bit zero of new_byte. There is no provision in the program to clear this bit. So if you put a coin in while the pattern is in the second half of the pattern, it will remember this the next time pattern starts being called. If this is undesirable, you just have to put a "bcf new_byte,0" in the program somewhere which won't happen while pattern is being called, like when a coin is detected.The schematic and the video are going to be useful. When I get some free time I'll add the pinout to the header file and along with the video this will give me some frame of reference.So it might be awhile, days, maybe weeks. I'm not retired. But the next time I post I suspect I will have either have some answers and/or I'll have some tasks for you to perform using a test code.In the meantime:Questions1. What happens when you put in more than 1 coin? i don't see a display for how many coins you have put in.Is there any provision for this? Or are you supposed to only put in 1 coin for each spin? What happens when you drop another before hitting the spin button?2. What is the maximum win? And do they all produce the same result other than number of servo/coin drops? Run pattern 2 on the LED a few times with the beeping, and then start dropping coins. Then after done, 2 seconds later, back to "state zero" with pattern running on the LEDs and waiting for user to insert a coin?I imagine the most likely cause of this problem is that he has more than 2 subroutines going at the same time and messing with mode_byte,7 and using the same counter... the one that counts the number of times pattern2 is called before turning itself off. So I imagine the easy fix (if there is one) will be simply using a new register for this counter in the routine that calls pattern2, because we have at least one unused register available.OR the routine that calls pattern2 is being turned off, prematurely, by something else. Via the pertinent mode_byte bit.The super long delay that sometimes occurs before pattern comes on after a win/loss.. ... it might be a missed zero check, because some other subroutine has also inc/dec'd a counter, so that counter rolls over while the routine is not looking. But we have to find what is responsible for that delay, and label "timeout" is the obvious suspect, just from memory. If you had time to mess with this to verify, for instance, you could try to make the delay much much shorter by looking at and changing timeout and seeing if that makes the 2 second delay into a split second delay. The highest order counter is the one you would want to mess with... There would be two levels of counter. Again, just from memory. I don't know what counters are used in timeout, and this is just a verification/ruleout.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 08, 2018, 08:48:50 pm
content: QuoteHere is another video of bretts that should clear this up even further, its only 1:40 long, but it shows him playing the machine. It looks like his first LED is broken in this vid so ignore that but you see as he puts coins in that the credits are registered and displayed with the same LEDs, even whilst he is playing.QuoteMaxiumum win is £1.00 which is all bars "- - -" 20x 5p. he wins a jackpot in the video. The LED sequence and beeping is the same for all wins and yes it then starts dropping coins after the sequence.QuoteYes that is correct.

author: KL27x
author_rank: Super Contributor
timestamp: October 08, 2018, 10:29:26 pm
content: Ok, still haven't looked at the code.So the machine counts how many coins you put in, but there's no display of this? Just a green light on the spin button as long as the count of coins is higher than zero?Is there something special that happens when there are 8 or more coins in there? The code checks for this in one part, and I find it to be curious.

author: Ian.M
author_rank: Super Contributor
timestamp: October 08, 2018, 11:16:50 pm
content: The articles said the max credit is £12.75 (255 x 5p), and the first eight 5p credits are displayed on the pattern LEDs when a pattern isn't running.I was slightly surprised that a NE556 controlled by a logic level was used for the servo pulse generation. Without searching through the code for that, I was expecting that to be interleaved with the display multiplexing code. A modern reimplementation on any PIC with a 16 bit Timer 1 and a CCP module wouldn't need the NE556 as it could generate a stable servo pulse with hardware edge timing directly.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 08, 2018, 11:22:26 pm
content: it just lights up an led for each credit inserted, if more than 8 credits are put in they still get registered, you just can't tell how many are left unless you count in your head or the credit amount drops below 8, in which case the LEDs start to turn off one by one as each credit is played.yes the green light is only displayed when credit count higher than zero and is an indicator the machine is ready to play as it is the start button. the green light does turn off when you press it to spin the reels and comes back on again when machine is ready to be spun again. a picture of sticker I re-designed may also help. its not finished yet but at least you can see what the buttons are for. I will end up using better quality fruit pictures than I used in picture.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 08, 2018, 11:28:59 pm
content: on julians youtube video he explains a little on this and in the comment section, he says "The PIC16C57 didn't have non-volatile storage (EEPROM). So there was nowhere to store the calibrated servo endpoints. By using the 555s, the endpoints are effectively stored on the two trimmer pots.﻿"i happen to like the simplicity of the trimmer pots as i am able to physically and easily calibrate where the servo travels to and stops.here is julians video if you are interested.

author: Ian.M
author_rank: Super Contributor
timestamp: October 09, 2018, 12:00:24 am
content: Quote from: Electrofinn on October 08, 2018, 11:28:59 pmOnly the coin stack end position is critical. It doesn't matter how far the slide goes past the drop hole, so adjustment for a single position could have been entirely mechanical - put the horn on the servo splines turned to set the coarse position, and bend the linkage for fine adjustment.I suspect that the NE556 ended up in there because at that date, Julyan's coding skills on a baseline PIC didn't extend to writing interleaved isochronous code so he was unable to get a stable servo pulse. If the pulse is unstable, the servo would jitter, causing excessive battery consumption.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 12:12:39 am
content: Yes your're right, I still have the old mechanism me and my dad made. I remember a lot of the adjustment was mechanical and little was with the pots. The one I have is very crude in how its been cut and drilled but hey it worked very well for a long time. Will be making another but this time I am thinking of having some acrylic laser cut for me.I will not be using a battery on this, going to power it with a power supply. but i remember battery consumption wasn't all that bad.A few have wondered why he didn't do it the way you said and I think you're absolutely right about why he ended up doing it that way, I just thought it is was an excellent exercise of how a NE556 could be used and I think in the context of the magazine in which it was published 'Every Day Practical Electronics' or EPE for short and perhaps its target market it was probably very fitting. Not sure what part of the world you're in so not sure if you're familiar with the mag.Lot of people have said this was one of the most memorable projects of the magazines history and for me it represents some of the happier moments of my childhood, it's a timeless classic, and yes it could be done a lot better but it has a charm about it, And watching my 7yr old's face playing this with it bare and out of its box just as I did when I was his age was special...yeah I gotta get this finished.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 02:03:22 am
content: QuoteYep, you're absolutely correct, just tested this.QuoteYes no worries, fantastic, thank you.

author: Ian.M
author_rank: Super Contributor
timestamp: October 09, 2018, 02:38:33 am
content: The NE556 based servo control circuit is still over-complex. Its fairly easy to use a single 555 to generate a Futaba servo signal - you just need a single diode across the discharge resistor to let it operate as an astable with a discharge time of approx 18ms and vary the charging resistor to set the pulse width, as small variations in the pulse rate are non-critical.It could also be done without the transistor - just let the PIC output feed the short pulse charging resistor. As its a pain bit-banging the write-only TRIS register on baseline parts, put a diode in series with the PIC output so it can only source current. On midrange or better PICs the TRIS registers are memory mapped, so one can easily toggle between Hi-Z input and outputting '1', so no extra diode is needed.

author: KL27x
author_rank: Super Contributor
timestamp: October 09, 2018, 04:59:13 am
content: New code revision.Notice, I messed with timeout, so I hope there is no timeout, at all, now. Of course this might cause other issues, but the point is to see if this is what causes the 2 second (sometimes 30 second) pause. If this is it, then I'll see how best to fix it.I cleared new_byte,0 in the spot where a coin is detectedand I changed win subroutine.I believe the duration that pattern2 is displayed is dependent on mode_byte,4 being set. And it is only set when win is active. So it only stays on as long as win is in the middle of being executed. So I modified win so it uses a new register in place of counter_hi to see if this changes anything. (It could also be counter_lo;... but I only have one register left.)Coped from my code history where I write revision notes. You can view the code changes by going to the labels "v22.x" which will pop up in your warnings when you assemble:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;V22 10/08/2018;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;v22.1 added a BCF new_byte,0 at were coin_counter is incrementedv22.2 locate subroutine responsible for the delay beforepattern starts up after running out of credits.x put test code to bypass timeout to see what happens.v22.3 win subroutine replacedthe duration of pattern2 appears dependent on duration of winpattern2 is diplayed only as long as win is active.win uses counter_lo and counter_hi to determine durationx replaced busy flag MB,7 with new_byte,1 busy flagx replaced counter_hi with counter_higher0 try replacing counter_lo

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 09:12:20 am
content: QuoteYep, you're correct, there is absolutelynotimeout delay now. Also the issue of it not starting at the beginning of "pattern" has happened a couple of times but now it seems it can't be deliberately reproduced, where as before, you knew that if you inserted a coin during second half of pattern that it would always start from 17th value (16th if counting from zero) but now it doesn't. My observation is that it begins at the start of "pattern" very nearly all of the timeQuoteIt appears to be behaving normally, although it's a little early in my testing to conclude. will thrash the hell of this thing tonight.

author: KL27x
author_rank: Super Contributor
timestamp: October 09, 2018, 09:30:14 pm
content: Encouraging.Here, I shuffled around new_byte so I could use the lower 5 bits as another completely separate timer for timeout subroutine.Timeout should always end after about 2 seconds, now. What other consequences that will have, who knows?I also made some small tweak to win/counter_higher, just to liberate the unused 3 bits at the top. This shoudn't change anything.... unless I made a human error.Oh, and I found I was clearing what was formerly known as "new_byte,0" in the wrong spot, which was part of the code used for the max credit_count check.. So I added another bcf in the spot where it shoudl always be executed on insertion of a coin. So I think pattern will always start at the beginning, now.So fingers crossed and hail to mary. And this might be pretty close

author: KL27x
author_rank: Super Contributor
timestamp: October 09, 2018, 09:43:11 pm
content: New .asmI realized that after a coin is put in, maybe sequence continues for a bit. I dunno.I added another bcf pattern.bit5 (formerly known as mode_byte,0) to the exit of timeout. Timeout turns on sequence, which does the pattern. This should definitely handle the pattern start point thing, without digging into the code any further.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 09:45:21 pm
content: Quote^^this made me chuckle lol ^^Well before you posted the newest code I had been bashing this for 2 and half hours straight and not once did the "pattern2" problem arise and I've had tons and tons of wins. so now I will try your newest code. will report back.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 09:47:34 pm
content: QuoteOk cool will try this one.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 09:52:24 pm
content: something strange is now happening with "pattern" its only running and looping what looks like the first 16 values.shall I try the other one?

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 09:55:01 pm
content: already tried it and its the same.

author: KL27x
author_rank: Super Contributor
timestamp: October 09, 2018, 10:04:36 pm
content: Ok probably a human error. Lemme seeYeah, changed only part of my #define's for shuffling new_byte around.Amended .asm attached.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 10:13:19 pm
content: Nah, Still the same.

author: KL27x
author_rank: Super Contributor
timestamp: October 09, 2018, 10:20:50 pm
content: Ok, no problem.Just checked and I was clearing this bit in front of what I thought was a incf credit_counter, but it turned out to be credit_timer. That would do it. This is par for the course, and why this is a stupid undertaking from the start.FWIW,Source of some these errors (on top of manipulating the same registers in multiple subroutines that run simultaneously) lies in how the coder uses mode_byte,7 as a distinguisher for if a routine is being called for the first time or not.The problem is he uses the same bit for every routine. And many of the routines get activated at the same time.This would have been much clearer and more flexible/options if there were a unique bit for each subroutine as a busy flag. But now that it's all said and done, there are likely places where this mess produces the intended result. So leave sleeping dogs lie.So if this produces unintended results right after the timeout is done, try puttingbcf mode_byte,7right after timeout.end

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 10:36:52 pm
content: QuoteWill do, however everything seems fine so far. Fingers crossed!

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 10:57:46 pm
content: So far so good, I hope so because following our nomenclature I would so love to rename this file something like Fruit Machine_v23_Final lolWill keep you posted.

author: KL27x
author_rank: Super Contributor
timestamp: October 09, 2018, 11:02:13 pm
content: I've just saved it as v22 after your last post. The prior wasn't done, yet, is why it is still "clip" (board).I have had to wrap from 99 back to zero on a project, before.* No need to get crazy with too many revs.*Why not keep going beyond 100? On device with EEPROM, I usually put the revision number into one byte of EEPROM.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 09, 2018, 11:06:10 pm
content: QuoteWow, Jeeze! lets hope we don't repeat that history lolQuoteoh i see.

author: KL27x
author_rank: Super Contributor
timestamp: October 09, 2018, 11:16:02 pm
content: For anyone else learning assembly:I try to make all the major code changes in a revision easy to find, by using indented labels and/or putting instructions/directives in column 1 in order to generate a warning. Save that revision. Then on the clipboard version when I want to forget about them, I can unindent those labels and tab the instructions to clear all those warnings to have a clean state. If I need to see v22 changes, I can load the saved .asm file and those warnings are there in posterity, forever. Unlike using the (cumbersome) bookmark feature in the IDE.

author: KL27x
author_rank: Super Contributor
timestamp: October 09, 2018, 11:33:03 pm
content: Here is my code history .txt. You can put this into your project folder, then right click on "other" folder in the project view window and add this file. You can see the miles of stuff I went through to figure out the few lines of code to change/add.Pin Configuration can be added to the "header" folder in the same way.Typically, I'm going to put each bank of memory on its own .inc file, too, added to the header folder.And error levels, ditto.Now to see those things, it's just a click, and you have that info side-by-side your current place in the code. Rather than scrolling through 5 miles of code AND losing your place in the code AND forgetting what you looked up by the time you have the code on screen, again.But note, if you wanted these .inc files to be included, you would have to include them in the main .asm file. Like this:#include Pin Configuration.inc#include Error_Level.incYou can do this up at the top of the file with the "#include list_16F57.inc," or if adding other .asm files, which you can add to "other" folder, you may put the #include anywhere you want that code to go.None of the defines in the Pin Configuration are utilized, but it's nice to be able to click on it to quickly pull it up for reference. So as it is right now, there's no reason to include it unless you starting using these defined names in the code. It's also often handy to have a spare whiteboard.asm where you right/modify new bits of code, so you can scroll through the main .asm to reference while writing it.**edit... apparently .inc files can't be uploaded. Will change Pin Configuration to .txt and you would have to change it back to .inc before adding it to "header" folder.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 10, 2018, 12:34:32 am
content: Great so far, one little minor and I mean really minor is that the "pattern" sometimes but rarely begins after a shorter delay than 2 seconds, maybe 1/2 a second maybe less. But I wouldn't care if this was left alone. Great info above BTW.

author: KL27x
author_rank: Super Contributor
timestamp: October 10, 2018, 12:55:00 am
content: QuoteNeither would I.

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 10, 2018, 01:03:34 am
content: Lol 😂

author: Electrofinn
author_rank: Regular Contributor
timestamp: October 10, 2018, 04:33:14 pm
content: Well, I think you well and truly nailed this! It's working beautifully, thankyou so much for everything you have done. Was looking over the code and it looks almost unrecognizable from the original, it's incredible.Again thank you so much.KL27x I have sent you a PM