I am trying to write a simple machine code routine.
I want that program to scan hires screen memory to look for a color byte and change it to another.
I mean, for example, it scans for "1" value in HIRES memory and change all the "1"s to "4" . So in the picture, all the red parts turns to the blue.
Here's the code I wrote but it does not work. AgAin I am not good at assemble monitors or C. I write machine code programs under basic by entering hex codes. So I will give hex codes and try to explain what I ment to with equivalent BASIC tokens.
'DOKE 2,#A000 --> BEGINNING OF HIRES
$1000 A9 00 LDA #$00
$1002 85 02 STA $02
$1004 A9 A0 LDA #$A0
$1006 85 03 STA $03
'DOKE 4,#1F40 ----> Size of hires - 8000 bytes
$1008 A9 40 LDA #$40
$100A 85 04 STA $04
$100C A9 1F LDA #$1F
$100E 85 05 STA $05
'Y=0: A=PEEK(DEEK(2))+Y
$1010 A0 00 LDY #$00
$1012 B1 02 LDA ($02),Y
'IF A=PEEK(0) THEN POKE A,PEEK(1)
$1014 C5 00 CMP $00
$1016 D0 04 BNE $101C
$1018 A5 01 LDA $01
$101A 91 02 STA ($02),Y
'DOKE 2,DEEK(2)+1
$101C 18 CLC
$101D E6 02 INC $02
$101F D0 02 BNE $1023
$1021 E6 03 INC $03
'DOKE 4,DEEK (4)-1
$1023 C6 04 DEC $04
$1025 A5 04 LDA $04
$1027 C9 FF CMP #$FF
$1029 C6 05 DEC $05
'IF DEEK (4) > 0 THEN GOTO $1010
$102B D0 E3 BNE $1010
$102D 60 RTS
My program is like that. It is supposed to look for memory location 0 and change every byte in HIRES which is the same as PEEK(0) TO PEEK(1)
So I do this but nothing changes . It immediately says ready.
POKE 0,1:POKE 1,4 : CALL#1000
I might have errors in branchings and increasing and decreasing the memories.
Can you check and tell me what is wrong?
Or you might suggest easier way to search for a memory and change it like that.
Thank you very much .
A little help for a simple machine code program.
Re: A little help for a simple machine code program.
Okay, let me give it a very quick glance to see if I get something:
Mmm... you are not doing in MC what you type in BASIC. LDA($02),y would do something like A=PEEK(DEEK(2)+Y) instead. Is it what you want? I think it is.... Anyway Y is set to zero, so it is A=PEEK(DEEK(2)). Please forbid me if I get a bit confused with the parenthesis. It's been ages since I last programmed in BASIC...
The comparison is OK, I think. If the contents of register A and the contents of the address $00 are equal then you load 1 into A and store the contents of A (1) into DEEK(2)+Y... therefore something like POKE (DEEK(2)+Y),A or, as Y=0; POKE DEEK(2),A
Clearing the carry is not necessary, as you are not adding, subtracting rotating etc... The above code then increments a 16-bit value stored in $02,$03.
Now you decrement a 16-bit value, but the code seems to be wrong as after the comparison CMP #$ff you should add a branch instruction, something like BNE $102b so you don't decrement the contents at $05.
If I am not wrong, the above code decrements both values at $05 and $04 all the time.
This will only check if the Z flag is set after decrementing the contents of $05, not of the whole 16-bit value being zero. You can do that with something like LDA $04: ORA $05: BNE $1010
So basically I think that the problem is in the decrementing and the comparison, as you imagined.
Hope it helps...
Cheers.
Code: Select all
'Y=0: A=PEEK(DEEK(2))+Y
$1010 A0 00 LDY #$00
$1012 B1 02 LDA ($02),Y
Code: Select all
'IF A=PEEK(0) THEN POKE A,PEEK(1)
$1014 C5 00 CMP $00
$1016 D0 04 BNE $101C
$1018 A5 01 LDA $01
$101A 91 02 STA ($02),Y
Code: Select all
'DOKE 2,DEEK(2)+1
$101C 18 CLC
$101D E6 02 INC $02
$101F D0 02 BNE $1023
$1021 E6 03 INC $03
Code: Select all
'DOKE 4,DEEK (4)-1
$1023 C6 04 DEC $04
$1025 A5 04 LDA $04
$1027 C9 FF CMP #$FF
$1029 C6 05 DEC $05
If I am not wrong, the above code decrements both values at $05 and $04 all the time.
Code: Select all
'IF DEEK (4) > 0 THEN GOTO $1010
$102B D0 E3 BNE $1010
$102D 60 RTS
So basically I think that the problem is in the decrementing and the comparison, as you imagined.
Hope it helps...
Cheers.
Re: A little help for a simple machine code program.
Thank you very much for the quick response. I think I had errors in basic explanations .
Yes, I wanted to set A to PEEK(DEEK(2)) . As there is no such command, I use indirect indexing with Y and setting Y as zero. As long as Y is zero, this part is fine then.
After changes according to your suggestions, my code is like that
`
Aaaaaand it worked perfectly
But It is a bit slower than I expected. Do you have any suggestion to make it faster? Perhaps instead of counting down from 8000 to zero to check if we reach end of HIRES, we can check the DEEK(2). How?
Also, as you see, I am not using Y register and instead increase two byte the zero page address. Do you think it goes faster if we use Y register to scan each 256 byte and then increase 1 byte in (3)?
$1010 A0 00 LDY #$00
$1012 B1 02 LDA ($02),Y
Yes, I wanted to set A to PEEK(DEEK(2)) . As there is no such command, I use indirect indexing with Y and setting Y as zero. As long as Y is zero, this part is fine then.
Here is important. You said "If the contents of register A and the contents of the address $00 are equal then you load 1 into A" I want to load content of (1) into A. So What I want to do is IF PEEK(DEEK(2)) = PEEK(0) THEN POKE DEEK(2),PEEK(1) . So, I think this part is also correct..Code: Select all
$1014 C5 00 CMP $00
$1016 D0 04 BNE $101C
$1018 A5 01 LDA $01
$101A 91 02 STA ($02),Y
The comparison is OK, I think. If the contents of register A and the contents of the address $00 are equal then you load 1 into A and store the contents of A (1) into DEEK(2)+Y... therefore something like POKE (DEEK(2)+Y),A or, as Y=0; POKE DEEK(2),A
After changes according to your suggestions, my code is like that
Code: Select all
$1000 A9 00 LDA #$00 ..
$1002 85 02 STA $02 ..
$1004 A9 A0 LDA #$A0 ..
$1006 85 03 STA $03 ..
$1008 A9 00 LDA #$00 ..
$100A 85 04 STA $04 ..
$100C A9 1F LDA #$1F ..
$100E 85 05 STA $05 ..
$1010 A0 00 LDY #$00 ..
$1012 B1 02 LDA ($02),Y ..
$1014 C5 00 CMP $00 ..
$1016 D0 04 BNE $101C ..
$1018 A5 01 LDA $01 ..
$101A 91 02 STA ($02),Y ..
$101C E6 02 INC $02 ..
$101E D0 02 BNE $1022 ..
$1020 E6 03 INC $03 ..
$1022 C6 04 DEC $04 ..
$1024 A5 04 LDA $04 ..
$1026 C9 FF CMP #$FF ..
$1028 D0 02 BNE $102C ..
$102A C6 05 DEC $05 ..
$102C A5 04 LDA $04 ..
$102E 05 05 ORA $05 ..
$1030 D0 E0 BNE $1012 ..
$1032 60 RTS
Aaaaaand it worked perfectly
But It is a bit slower than I expected. Do you have any suggestion to make it faster? Perhaps instead of counting down from 8000 to zero to check if we reach end of HIRES, we can check the DEEK(2). How?
Also, as you see, I am not using Y register and instead increase two byte the zero page address. Do you think it goes faster if we use Y register to scan each 256 byte and then increase 1 byte in (3)?
Re: A little help for a simple machine code program.
If you are fine with overshooting a bit (ie: also do the replacement in the three lines of TEXT as well), you could indeed optimize by using both Y and a single 8 bit counter: 32 times 256=8192, so you could just set the address to $A000, and increment Y then increment the high byte each time Y reaches back to zero.
That would be wayyyyy faster
That would be wayyyyy faster
Re: A little help for a simple machine code program.
Yep, and if the counter is stored in register X, it would be even faster. Initialize it to 32, then decrement at each loop. A dex:bne $1012 would do.
Re: A little help for a simple machine code program.
Thanks I'll try to implement these advices to the code.
I am making a new "surprise" game using lightpen. These helps will make it better . I hope tomorrow it will be ready to play
I am making a new "surprise" game using lightpen. These helps will make it better . I hope tomorrow it will be ready to play