18 November 2014, 23:06 | #1 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
Wrote my first 68k routine (inside) in a very long time, any pointers?
I've not written any 68k for a very long time.
This is a routine do display a hexadecimal value on the screen at specified character coordinates. Any pointers or optimisation advice? Thanks Code:
; DEBUG: Outputs a Hexadecimal Word to the screen at character coordinates ; ; ENTRY: d0 = Word value to display as 4 digit hex (E.q $ABCD) ; d1 = X coords in chars ; d2 = Y coords in chars ; ; EXIT: Nothing ; ; NOTE: Does not preserve registers Debug: and.l #$ffff,d0 ; Mask off high words and.l #$ffff,d1 and.l #$ffff,d2 lea TestScreen+3,a1 ; Calc screen address, +3 as prints in reverse (right to left) lea DebugRowTable,a0 add d2,d2 move (a0,d2),d2 add d1,d2 add.l d2,a1 lea DebugFont,a0 move.l a0,a2 ; Save pointer move.l d0,d1 ; Save INPUT and #$f,d0 ; Mask off unwanted bits, only printing $0-$f lsl #3,d0 ; Multiply x 8 (8 bytes per bitmap character) add.l d0,a0 bsr.b .DebugPrintChar ; Print nibble ($0-$f) asr.l #4,d1 ; Shift for next nibble move.l d1,d0 and #$f,d0 lsl #3,d0 move.l a2,a0 add.l d0,a0 bsr.b .DebugPrintChar ; Print nibble ($0-$f) asr.l #4,d1 ; Shift for next nibble move.l d1,d0 and #$f,d0 lsl #3,d0 move.l a2,a0 add.l d0,a0 bsr.b .DebugPrintChar ; Print nibble ($0-$f) asr.l #4,d1 ; Shift for next nibble move.l d1,d0 and #$f,d0 lsl #3,d0 move.l a2,a0 add.l d0,a0 ; bsr .DebugPrintChar ; BSR not needed, PC falls through .DebugPrintChar ; Outputs 1 char to screen move.b (a0)+,(a1) move.b (a0)+,40(a1) move.b (a0)+,80(a1) move.b (a0)+,120(a1) move.b (a0)+,160(a1) move.b (a0)+,200(a1) move.b (a0)+,240(a1) move.b (a0)+,280(a1) sub #1,a1 ; Move back 1 char (reverse printing) rts DebugRowTable: dc.w 00*(40*8),01*(40*8),02*(40*8),03*(40*8),04*(40*8),05*(40*8) dc.w 06*(40*8),07*(40*8),08*(40*8),09*(40*8),10*(40*8),11*(40*8) dc.w 12*(40*8),13*(40*8),14*(40*8),15*(40*8),16*(40*8),17*(40*8) dc.w 18*(40*8),19*(40*8),20*(40*8),21*(40*8),22*(40*8),23*(40*8) dc.w 24*(40*8),25*(40*8),26*(40*8),27*(40*8),28*(40*8),29*(40*8) dc.w 30*(40*8),31*(40*8),32*(40*8),33*(40*8),34*(40*8),35*(40*8) dc.w 36*(40*8),37*(40*8),38*(40*8),39*(40*8) DebugFont: ; Ripped from C64 Game Anicpital ;) dc.b $7C, $66, $CE, $F6, $C6, $CC, $78, $00 ; (0) dc.b $18, $78, $18, $18, $18, $18, $7E, $00 ; (1) dc.b $7C, $C6, $66, $0C, $30, $66, $FC, $00 ; (2) dc.b $7C, $C6, $06, $3C, $06, $C6, $7C, $00 ; (3) dc.b $06, $0E, $1E, $36, $7F, $06, $06, $0C ; (4) dc.b $FE, $C6, $C0, $7C, $06, $C6, $7C, $00 ; (5) dc.b $7C, $E6, $60, $7C, $C6, $C6, $7C, $00 ; (6) dc.b $7E, $C6, $0C, $7E, $18, $30, $60, $60 ; (7) dc.b $7C, $E6, $66, $7C, $C6, $C6, $7C, $00 ; (8) dc.b $7C, $E6, $66, $3E, $06, $CC, $78, $00 ; (9) dc.b $30, $78, $EC, $FE, $C6, $C6, $66, $06 ; (.)A dc.b $7C, $E6, $66, $FC, $C6, $C6, $7C, $00 ; (.)B dc.b $3C, $66, $CC, $C0, $C0, $C6, $7C, $00 ; (.)C dc.b $7C, $F6, $66, $66, $66, $CC, $F8, $00 ; (.)D dc.b $3C, $66, $C0, $F8, $C0, $C6, $7C, $00 ; (.)E dc.b $3C, $66, $60, $78, $60, $60, $C0, $C0 ; (.)F |
19 November 2014, 08:53 | #2 |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
|
Look OK at first glance but I would have just used an (optimised) multiplication instead of the row table (320 = 256+64, i.e. shifts work well) to keep the code a bit shorter as the values are all linear anyway.
|
19 November 2014, 19:00 | #3 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
Like this?
Code:
; DebugOutput: Outputs a Hexadecimal Word to the screen at character coordinates ; ; ENTRY: d0 = Word value to display as 4 digit hex (E.q $ABCD) ; d1 = X coords in chars ; d2 = Y coords in chars ; ; EXIT: Nothing ; ; NOTE: Does not preserve registers ; ** DO NOT CALL DIRECTLY - ALWAYS USE THE "DebugOut" MACRO ** ; This will ensure correct conditional assembley (DEBUG_ENABLED) ifd DEBUG_ENABLED DebugOutput: and.l #$ffff,d0 ; Mask off high words and.l #$ffff,d1 and.l #$ffff,d2 lea TestScreen+3,a1 ; Calc screen address, +3 as prints in reverse (right to left) ; lea DebugRowTable,a0 ; add d2,d2 ; move (a0,d2),d2 move d2,d3 asl #8,d2 asl #6,d3 add d3,d2 add d1,d2 add.l d2,a1 lea DebugFont,a0 move.l a0,a2 ; Save pointer move.l d0,d1 ; Save INPUT and #$f,d0 ; Mask off unwanted bits, only printing $0-$f lsl #3,d0 ; Multiply x 8 (8 bytes per bitmap character) add.l d0,a0 bsr.b .DebugPrintChar ; Print nibble ($0-$f) asr.l #4,d1 ; Shift for next nibble move.l d1,d0 and #$f,d0 lsl #3,d0 move.l a2,a0 add.l d0,a0 bsr.b .DebugPrintChar ; Print nibble ($0-$f) asr.l #4,d1 ; Shift for next nibble move.l d1,d0 and #$f,d0 lsl #3,d0 move.l a2,a0 add.l d0,a0 bsr.b .DebugPrintChar ; Print nibble ($0-$f) asr.l #4,d1 ; Shift for next nibble move.l d1,d0 and #$f,d0 lsl #3,d0 move.l a2,a0 add.l d0,a0 ; bsr .DebugPrintChar ; BSR not needed, PC falls through .DebugPrintChar ; Outputs 1 char to screen move.b (a0)+,(a1) move.b (a0)+,40(a1) move.b (a0)+,80(a1) move.b (a0)+,120(a1) move.b (a0)+,160(a1) move.b (a0)+,200(a1) move.b (a0)+,240(a1) move.b (a0)+,280(a1) sub #1,a1 ; Move back 1 char (reverse printing) rts ;DebugRowTable: ; dc.w 00*(40*8),01*(40*8),02*(40*8),03*(40*8),04*(40*8),05*(40*8) ; dc.w 06*(40*8),07*(40*8),08*(40*8),09*(40*8),10*(40*8),11*(40*8) ; dc.w 12*(40*8),13*(40*8),14*(40*8),15*(40*8),16*(40*8),17*(40*8) ; dc.w 18*(40*8),19*(40*8),20*(40*8),21*(40*8),22*(40*8),23*(40*8) ; dc.w 24*(40*8),25*(40*8),26*(40*8),27*(40*8),28*(40*8),29*(40*8) ; dc.w 30*(40*8),31*(40*8),32*(40*8),33*(40*8),34*(40*8),35*(40*8) ; dc.w 36*(40*8),37*(40*8),38*(40*8),39*(40*8) DebugFont: ; Ripped from C64 Game Anicpital ;) dc.b $7C, $66, $CE, $F6, $C6, $CC, $78, $00 ; (0) dc.b $18, $78, $18, $18, $18, $18, $7E, $00 ; (1) dc.b $7C, $C6, $66, $0C, $30, $66, $FC, $00 ; (2) dc.b $7C, $C6, $06, $3C, $06, $C6, $7C, $00 ; (3) dc.b $06, $0E, $1E, $36, $7F, $06, $06, $0C ; (4) dc.b $FE, $C6, $C0, $7C, $06, $C6, $7C, $00 ; (5) dc.b $7C, $E6, $60, $7C, $C6, $C6, $7C, $00 ; (6) dc.b $7E, $C6, $0C, $7E, $18, $30, $60, $60 ; (7) dc.b $7C, $E6, $66, $7C, $C6, $C6, $7C, $00 ; (8) dc.b $7C, $E6, $66, $3E, $06, $CC, $78, $00 ; (9) dc.b $30, $78, $EC, $FE, $C6, $C6, $66, $06 ; (A) dc.b $7C, $E6, $66, $FC, $C6, $C6, $7C, $00 ; (B) dc.b $3C, $66, $CC, $C0, $C0, $C6, $7C, $00 ; (C) dc.b $7C, $F6, $66, $66, $66, $CC, $F8, $00 ; (D) dc.b $3C, $66, $C0, $F8, $C0, $C6, $7C, $00 ; (E) dc.b $3C, $66, $60, $78, $60, $60, $C0, $C0 ; (F) endif |
20 November 2014, 12:51 | #4 |
Registered User
Join Date: Nov 2012
Location: Willich/Germany
Posts: 232
|
Alternative:
Code:
; DEBUG: Outputs a Hexadecimal Word to the screen at character coordinates ; ; ENTRY: d0 = Word value to display as 4 digit hex (E.q $ABCD) ; d1 = X coords in chars ; d2 = Y coords in chars ; ; EXIT: Nothing ; ; NOTE: Does not preserve registers Debug: lea TestScreen+3+1,a1 add d2,d2 add DebugRowTable(pc,d2.w),a1 add d1,a1 lea DebugFont,a2 moveq #4-1,d2 loop: move d0,d1 lsr #4,d0 and #$f,d1 lsl #3,d1 lea (a2,d1.w),a0 move.b (a0)+,-(a1) move.b (a0)+,40(a1) move.b (a0)+,80(a1) move.b (a0)+,120(a1) move.b (a0)+,160(a1) move.b (a0)+,200(a1) move.b (a0)+,240(a1) move.b (a0)+,280(a1) dbf d2,loop rts DebugRowTable: dc.w 00*(40*8),01*(40*8),02*(40*8),03*(40*8),04*(40*8),05*(40*8) dc.w 06*(40*8),07*(40*8),08*(40*8),09*(40*8),10*(40*8),11*(40*8) dc.w 12*(40*8),13*(40*8),14*(40*8),15*(40*8),16*(40*8),17*(40*8) dc.w 18*(40*8),19*(40*8),20*(40*8),21*(40*8),22*(40*8),23*(40*8) dc.w 24*(40*8),25*(40*8),26*(40*8),27*(40*8),28*(40*8),29*(40*8) dc.w 30*(40*8),31*(40*8),32*(40*8),33*(40*8),34*(40*8),35*(40*8) dc.w 36*(40*8),37*(40*8),38*(40*8),39*(40*8) DebugFont: ; Ripped from C64 Game Anicpital ;) dc.b $7C, $66, $CE, $F6, $C6, $CC, $78, $00 ; (0) dc.b $18, $78, $18, $18, $18, $18, $7E, $00 ; (1) dc.b $7C, $C6, $66, $0C, $30, $66, $FC, $00 ; (2) dc.b $7C, $C6, $06, $3C, $06, $C6, $7C, $00 ; (3) dc.b $06, $0E, $1E, $36, $7F, $06, $06, $0C ; (4) dc.b $FE, $C6, $C0, $7C, $06, $C6, $7C, $00 ; (5) dc.b $7C, $E6, $60, $7C, $C6, $C6, $7C, $00 ; (6) dc.b $7E, $C6, $0C, $7E, $18, $30, $60, $60 ; (7) dc.b $7C, $E6, $66, $7C, $C6, $C6, $7C, $00 ; (8) dc.b $7C, $E6, $66, $3E, $06, $CC, $78, $00 ; (9) dc.b $30, $78, $EC, $FE, $C6, $C6, $66, $06 ; (.)A dc.b $7C, $E6, $66, $FC, $C6, $C6, $7C, $00 ; (.)B dc.b $3C, $66, $CC, $C0, $C0, $C6, $7C, $00 ; (.)C dc.b $7C, $F6, $66, $66, $66, $CC, $F8, $00 ; (.)D dc.b $3C, $66, $C0, $F8, $C0, $C6, $7C, $00 ; (.)E dc.b $3C, $66, $60, $78, $60, $60, $C0, $C0 ; (.)F |
20 November 2014, 21:04 | #5 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
Thanks, its really helpful for me to see alternatives.
|
20 November 2014, 22:43 | #6 |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
|
Here's my version.
Code:
; DEBUG: Outputs a Hexadecimal Word to the screen at character coordinates ; ; ENTRY: d0 = Word value to display as 4 digit hex (E.q $ABCD) ; d1 = X coords in chars ; d2 = Y coords in chars ; ; EXIT: Nothing ; ; NOTE: Does not preserve registers Debug: lea SCREEN,a1 mulu.w #40*8,d2 add.l d2,a1 add.w d1,a1 lea DebugFont,a0 bsr.b .copychar bsr.b .copychar bsr.w .copychar .copychar rol.w #4,d0 moveq #15,d1 and.w d0,d1 lsl.w #3,d1 lea (a0,d1.w),a2 moveq #8-1,d7 .copy move.b (a2)+,(a1) add.w #40,a1 dbf d7,.copy sub.w #40*8-1,a1 rts DebugFont: ; Ripped from C64 Game Anicpital ;) dc.b $7C, $66, $CE, $F6, $C6, $CC, $78, $00 ; (0) dc.b $18, $78, $18, $18, $18, $18, $7E, $00 ; (1) dc.b $7C, $C6, $66, $0C, $30, $66, $FC, $00 ; (2) dc.b $7C, $C6, $06, $3C, $06, $C6, $7C, $00 ; (3) dc.b $06, $0E, $1E, $36, $7F, $06, $06, $0C ; (4) dc.b $FE, $C6, $C0, $7C, $06, $C6, $7C, $00 ; (5) dc.b $7C, $E6, $60, $7C, $C6, $C6, $7C, $00 ; (6) dc.b $7E, $C6, $0C, $7E, $18, $30, $60, $60 ; (7) dc.b $7C, $E6, $66, $7C, $C6, $C6, $7C, $00 ; (8) dc.b $7C, $E6, $66, $3E, $06, $CC, $78, $00 ; (9) dc.b $30, $78, $EC, $FE, $C6, $C6, $66, $06 ; (.)A dc.b $7C, $E6, $66, $FC, $C6, $C6, $7C, $00 ; (.)B dc.b $3C, $66, $CC, $C0, $C0, $C6, $7C, $00 ; (.)C dc.b $7C, $F6, $66, $66, $66, $CC, $F8, $00 ; (.)D dc.b $3C, $66, $C0, $F8, $C0, $C6, $7C, $00 ; (.)E dc.b $3C, $66, $60, $78, $60, $60, $C0, $C0 ; (.)F Last edited by StingRay; 21 November 2014 at 09:50. Reason: and.w #$f,d1 -> moveq #15,d1 and.w d1,d0; mulu.w #40,d2 -> mulu.w #40*8,d2 |
20 November 2014, 22:59 | #7 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
Nice and compact!
A little surprised to see a mulu in there, does the mulu change the high word of d2, I assumed it would only affect the lower 16 bits (as its explicitly a word operation), I was concerned about this (ass its added as a LONG), hence the AND's at the beginning of my first post. |
20 November 2014, 23:14 | #8 | |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
|
I like size optimising.
Quote:
|
|
21 November 2014, 00:17 | #9 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
Umm, I am confused. Shouldn't the mulu be by #40*8 ???
Are X/Y in pixels or in chars? (ie. X in [0,39] Y in [0-31]) |
21 November 2014, 00:22 | #10 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
Yeah the coords should be chars, I think it should be #40*8.
|
21 November 2014, 08:01 | #11 |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
|
Sure should! Fixed.
|
21 November 2014, 09:38 | #12 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
Also, I think
and.w d1,d0 should be and.w d0,d1 I thought that bsr.w .copychar .copychar wouldnt be valid (as its a 0 byte offset) maybe pea .chopychar if that is the case. |
21 November 2014, 09:49 | #13 |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
|
That's correct, shouldn't edit my messages late in the evening.
It's not a 0-byte offset, the bsr opcode has a size of 2 bytes. |
21 November 2014, 09:52 | #14 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
Cool, its so helpful to get some feedback on coding, there is no one in my social circles
who would have a clue about anything like this! |
21 November 2014, 10:20 | #15 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
I read here, that PEA is slightly faster than a bsr
Has to be under the right conditions of course, like this debug code. Code:
Finally, if you call a subroutine and then branch somewhere else, you can avoid extra jumping around. For instance, JSR sub ;Make a call JMP next ;and go somewhere else. can be made slightly faster with PEA next ;Push a fake return address JMP sub ;and "call." ;sub will RTS to next for us. (All of the above work for BSR and BRA as well as JSR and JMP.) Do you know if there is any software to cycle count and byte count your code, so you can test which is smaller and which is most efficient? |
21 November 2014, 10:34 | #16 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
A PC-relative PEA is faster than BSR. But an absolute PEA is not faster than a JSR (68000).
Quote:
|
|
21 November 2014, 10:45 | #17 |
Beyond Mutton
Join Date: Mar 2011
Location: North West, UK
Age: 52
Posts: 347
|
So in this case, it would be PC relative and faster?
replacing bsr.b .copychar with pea .copychar(pc) Or am I misunderstanding you. Last edited by jimmy2x2x; 21 November 2014 at 10:48. Reason: clarity |
21 November 2014, 12:38 | #18 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
No. Only in the example from above, where you want to return to a different location after calling the sub-routine.
Which means: Code:
bsr.w sub bra.w next Code:
pea next(pc) bra.w sub |
21 November 2014, 14:08 | #19 | |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
|
Quote:
Code:
PRINTT PRINTT "INTRO SIZE:" PRINTV *-START PRINTT PRINTT "SPACE LEFT:" PRINTV 1024-(*-START) PRINTT |
|
23 November 2014, 13:46 | #20 | |
Posts: n/a
|
Quote:
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Greetings from the UK and long time Amiga user! | chaoshusky | Member Introductions | 6 | 26 May 2015 00:34 |
Long time Atari user here.. | JonB | Member Introductions | 4 | 02 April 2013 07:31 |
Installed my Catweasel after a long time... | Narf the Mouse | support.Hardware | 6 | 22 May 2010 13:34 |
Me so horny, love you long time! | Pyromania | Amiga scene | 4 | 06 November 2007 20:34 |
|
|