| www.retrosoftware.co.uk http://www.retrosoftware.co.uk/forum/ |
|
| A (probably simple) assembler question. http://www.retrosoftware.co.uk/forum/viewtopic.php?f=11&t=555 |
Page 1 of 1 |
| Author: | MartinW [ Fri Dec 31, 2010 4:02 pm ] |
| Post subject: | A (probably simple) assembler question. |
The last few days I've done some preparatory groundwork for an upcoming project - that I guess I should probably say something about sooner or later, but that's not the point. Anyway, this particular bit of code isn't running on a Beeb, it's running on dedicated hardware. I used BeebASM as it was to hand and I happen to like it. I'm very much a noob when it comes to aseembler and I got stuck and ended up with what I consider a hack. So, consider this code: Code: ;------------------------------------------------ ; State machine LABS instruction (load absolute) ; .positionbeam ldx vector_pc ldy quad_index FOR n, 0, 3, 1 lda (pos_lookup),y sta vector_ram,x inx iny NEXT stx vector_pc rts What I was trying to do was to write 4 bytes into the memory area pointed to by 'vector_pc' (vector memory position counter). But I was trying to make the routine generic so it could position the beam to one of four different places. Now, the code works. But I consider it a bit hacky for two reasons. Both are the use of the FOR loop. Firstly, as this isn't for BBC hardware, I don't consider that I should be using BeebASM specific directives. Ok, that's subjective of course, but when you consider that it's just expanding out the code, if it were 40 bytes, you wouldn't use it, would you? So that's the second reason. I'm using it for no reason other than repetition. The 'n' in the loop isn't actually modifying anything or being used for anything. But my head really exploded on how to do this when I've already taken up X & Y with the indirect indexed addressing. Y holds the index to the position you want to go to (actually it doesn't, it holds the index for the commands you need to write but that's not important here!), X holds the index to the destination position so how would I index the input position? Surely this is going to come up time and time again so what are you meant to do? |
|
| Author: | RichTW [ Fri Dec 31, 2010 5:58 pm ] |
| Post subject: | Re: A (probably simple) assembler question. |
I would say that it's perfectly ok to unroll a loop this small in the way that you're doing it, as in this instance, it's the simplest and fastest way to do what you want to do. If you don't like BeebAsm specific syntax, just write it out in full: Code: .positionbeam ldx vector_pc ldy quad_index lda (pos_lookup),y sta vector_ram,x inx iny lda (pos_lookup),y sta vector_ram,x inx iny lda (pos_lookup),y sta vector_ram,x inx iny lda (pos_lookup),y sta vector_ram,x inx ; note we don't need the final iny (maybe) stx vector_pc rts The body of the loop is only 7 bytes long, so we're not exactly being wasteful with 21 extra bytes to get the job done, plus it will run slightly faster. The question though is whether your concern is optimising for speed or for size. If you wanted to write it as a loop to optimise for size, then the easiest way is to use a zero-page variable as your loop counter, like this: Code: .positionbeam ldx vector_pc ldy quad_index lda #4 sta counter ; some aliased address in the zero page .positionbeamloop lda (pos_lookup),y sta vector_ram,x inx iny dec counter bne positionbeamloop ; if counter<>0, reloop stx vector_pc rts This is particularly convenient as you don't refer to the value of the counter at any point, hence we never need to get it in a register. Hope that helps - look forward to hearing what you've got up your sleeve! |
|
| Author: | MartinW [ Fri Dec 31, 2010 11:34 pm ] |
| Post subject: | Re: A (probably simple) assembler question. |
Cheers Rich, I think that's a case of working on it too late and not seeing the obvious! I even had a reference to a location in zero page called "temp" but hadn't used it As far as the FOR loop is concerned, I've no problem with using it at all, it's just that as the code was being written to show an example of how to do some stuff for other people I thought it probably best not to force anyone that was following to have to use beebasm unless they wanted to. I did recommend it and link to it though This particular bit of the project was just demonstrating to others how to draw stuff on an Atari Asteroids board. Nothing desperately exciting. I've just dug my stash of PCBs out of the shed. I'm going to burn it to a ROM and make sure it works properly on the real hardware tomorrow but in the meantime... |
|
| Author: | MartinW [ Sun Jan 02, 2011 3:48 am ] |
| Post subject: | Re: A (probably simple) assembler question. |
As an aside, while it may be unusual, is there any reason why I can't use locations 0x00 to 0x10? I'll make this as brief as I can! Today I tackled getting this onto the real hardware and it proved a struggle to say the least but I got there. Long story short, it works ok when the PCB's test switch is on but when it's not, the PCB is generating NMI's every (3Khz / 12) and I'm not handling them so all hell breaks loose. The PCB has RAM from 0 - 3FF. So that I don't have to burn a ROM, test and erase every time I want to do anything I've relocated my code down so that it sits in this RAM. I have 16 bytes for variable use at the start and the rest is for the code. It works fine but BeebASM really didn't like me having stuff all the way down to 0. Am I just being thick? So I now have (in the code): 000 - 00F: equb 0 for padding 010 - 01F: reserved for variables 020 - 17F: program code (with some space) 180 - 1FF: data Obviously I can expand up a bit if / when I need to. |
|
| Author: | recycled [ Sun Jan 02, 2011 5:39 am ] |
| Post subject: | Re: A (probably simple) assembler question. |
Err, what processor is your system using again? Zero page can be used for 6502 program code. There are some speed advantages and size reductions that can be achieved by doing this, but also some caveats. Zero page is frequently used by a system's OS for parameter storage, if you want to return control to your OS you should check out which bytes have been left free for you to play in, or which block you can safely blast to the ether so the OS won't panic over it's destruction. Using a special addressing mode of the X register tricky table manipulation can be achieved in these low addresses too, indirect addressing modes with Y for table lookups, stacks and other good juju are achievable. So there are equally as many advantages in keeping your code out of here. The 6502 uses page one for the stack, this is fixed in the CPU hardware itself. This inflexability is often described as a fault with the beastie. It descends downwards from &1FF, details in any 6502 book. Be VERY careful putting code/data in these 256 bytes. You can get away with it, (use the low addresses by all means if you know you won't have a large dumping of temporary registers etc. to look after, but if you start servicing interrupts, nothing can be guaranteed!) |
|
| Author: | MartinW [ Sun Jan 02, 2011 1:05 pm ] |
| Post subject: | Re: A (probably simple) assembler question. |
Hmm. I'm surprised my program runs at all when it's located here then. I've got data that is constantly being referred to living at 180-1FF. That's got to be getting overwritten on every JSR. The CPU is 6502, yes, but there's no OS, only this code so no problems there. I'll shuffle it about so that the code avoids page 1 though. |
|
| Author: | RichTW [ Sun Jan 02, 2011 1:47 pm ] |
| Post subject: | Re: A (probably simple) assembler question. |
MartinW wrote: The PCB has RAM from 0 - 3FF. So that I don't have to burn a ROM, test and erase every time I want to do anything I've relocated my code down so that it sits in this RAM. I have 16 bytes for variable use at the start and the rest is for the code. It works fine but BeebASM really didn't like me having stuff all the way down to 0. Am I just being thick? In what sense does BeebAsm not like it? Do you get an error, or does the resulting code just not work? BeebAsm can be a bit tricky assembling code in the zero page (but then this could be the case with any assembler) because when it encounters a label it hasn't yet seen, it will assume it also to be a zero page location. This is just a side-effect of how it deals with unknown labels (it assigns them a temporary value equal to the current address being assembled at, which can result in a zero-page addressing mode being erroneously used). But it's generally pretty unusual to be assembling code in the zero page, and as recycled said, you're not reserving any space for the stack in page 1 either. Quote: So I now have (in the code): 000 - 00F: equb 0 for padding 010 - 01F: reserved for variables 020 - 17F: program code (with some space) 180 - 1FF: data Obviously I can expand up a bit if / when I need to. At very least you should be reserving even just 16 bytes of stack, for example between 180-18F, and then start your code with: Code: ldx #$8f txs to put the stack pointer at the top of your small piece of stack. |
|
| Page 1 of 1 | All times are UTC [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|