Amiga.org
Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Jose on April 11, 2004, 12:31:18 PM
-
Ok, I decided to go for some console text printing, just to test some control sequences and that... but I must be missing something very trivial cause the code gets an error in the very first instruction(bsr ini) wich I'm not getting what it is :lol:
execbase =4
openlib =-408
closelib =-414
open =-30
close =-36
write =-48
IoErr =-132
mode_old =1005
alloc_abs =-$cc
main:
bsr init
move.l conhandle,d1
move.l testtext1,d2
move.l #testtextend-testtext1,d3
move.l dosbase,a6
jsr write(a6)
rts
init:
move.l execbase,a6 ;open dos.library
lea dosname(pc),a1
moveq #0,d0
jsr openlib(a6)
move.l d0,dosbase
beq error
move.l dosbase,a6 ;open console
move.l #mode_old,d2
move.l consolename,d1
jsr open(a6)
move.l d0,conhandle
beq error
rts
error: ;maybe later;)
dosname dc.b "dos.library",0,0
consolename dc.b 'con:0/100/640/100 TesttextWindow',0
align 0,2
dosbase ds.l 1
conhandle ds.l 1
testtext1 dc.b 'This thing works dude!!!'
testtext2 dc.b $9b,'4;31;40m'
dc.b 'underline'
dc.b $9b,'3;33;40m',$9b,'5;20H'
dc.b '** Hey Dammit !! **',0
testtextend
-
Hmm...I got the original source with the code indented...
-
Hi dude,
Can't help you with the asm problem, but if you put your code in between {code} {/code} tags, the indentation is preserved. :-)
Start
loop
whatever
end
End
-
Done :-) But it's actually with square brackets not curly...
-
@Jose
I don't mean to pee on your parade, but this is not the place to use asm - unless you are aiming for very small exe size, at least. This kind of thing is far easier and much less error prone in C.
Mixing the two (C and asm) isn't as tricky as you might think ;-)
Souldn't your init code return after a branch to error?
error:
rts
In an error occurs, your main function never returns because of this.
You should put some sort of return code there too, so the caller can tell an error occured and skip the call to write.
So, the end of your init looks like this
...
move #1, X ; success!
rts
error:
move #0, X ; tittybiscuits!
rts
where X is some register or variable that you check afterwards.
You need to test the result in X after calling init to see if it was successful or not, eg tst.l dN followed by a suitable conditional branch to an exit or something.
So suppose we use d7 for X (for sake of argument)
Your complete code would then look like
[size=x-small]
execbase =4
openlib =-408
closelib =-414
open =-30
close =-36
write =-48
IoErr =-132
mode_old =1005
alloc_abs =-$cc
main:
bsr init ; returns zero in d7 if error
tst.l d7
beq exit
move.l conhandle,d1
move.l testtext1,d2
move.l #testtextend-testtext1,d3
move.l dosbase,a6
jsr write(a6)
exit:
; todo insert cleanup code
rts
init:
move.l execbase,a6 ;open dos.library
lea dosname(pc),a1
moveq #0,d0
jsr openlib(a6)
move.l d0,dosbase
beq error
move.l dosbase,a6 ;open console
move.l #mode_old,d2
move.l consolename,d1
jsr open(a6)
move.l d0,conhandle
beq error
moveq #1,d7 ; success!
rts
error:
moveq #0,d7 ; tittybiscuits
rts
dosname dc.b "dos.library",0,0
consolename dc.b 'con:0/100/640/100 TesttextWindow',0
align 0,2
dosbase ds.l 1
conhandle ds.l 1
testtext1 dc.b 'This thing works dude!!!'
testtext2 dc.b $9b,'4;31;40m'
dc.b 'underline'
dc.b $9b,'3;33;40m',$9b,'5;20H'
dc.b '** Hey Dammit !! **',0
testtextend
[/size]
[/quote]
-
Arghhh What is wrong with this asm code? (must be something stupid...)
Yes.
move.l consolename,d1
There are two erros in this single line.
it should either read
move.l #consolename,d1
or
lea consolename(pc),a0
move.l a0,d1
First error is that you load the contents instead of the address into d1, second error is that consolename is on an odd address which makes move.l fail on a 68000 ("dos.library",0,0 are 13 bytes).
And of course I totally agree that leading error: into text is not a very user friendly handling. And I also agree that with C this would be a trivial.
#include
int main (void)
{
BPTR f;
if (f = Open("con:/[b][/b]///bla/CLOSE/WAIT",MODE_OLDFILE))
{
Write (f,"whatever",8);
Close (f);
}
return (0);
}
Bye,
Thomas
-
@Thomas
move.l consolename, d1
:lol: How did I manage to overlook that?
(Spot the guy who only converts functions to asm after all else failed to speed them up)
-
@Karlos
tst.l #d7
Should (obviously) be
tst.l d7
I also suggest not using spaces in asm:
moveq #1, d7 ; success!
but:
moveq #1,d7 ; success!
Some assemblers are known to fail with spaces in wrong places.
-
@Piru
Aye. I think the # was left in there accidentally as I was copying and pasting wihtout much thinking :-)
Man, I sure know how to make myself look stupid in public :-D
-
There are several bugs in the code. Like pointed out by others, you must either move.l #label,reg or lea label,areg to get ptr to label.
Further your CON: string had a bug, it must be:
'CON:0/100/640/100/TesttextWindow',0
not
'CON:0/100/640/100 TesttextWindow',0
Your code printed '\0' char to console. This is not deadly, but causes confusion if you ever use the same method to stdout, and the output is redirected to file. Better learn to avoid it. Linefeeds were missing, too.
Also, your code was lacking all error checking, which I also added. Finally, your libopen LVO was really OldOpenLibrary, that is no longer supported. You must use OpenLibrary (-552).
Here's a working (tested) example:
; simple conwindow example
RETURN_OK EQU 0
RETURN_FAIL EQU 20
MODE_OLDFILE EQU 1005
MODE_NEWFILE EQU 1006
_LVOOpenLibrary EQU -552
_LVOCloseLibrary EQU -414
_LVOOpen EQU -30
_LVOClose EQU -36
_LVOWrite EQU -48
_LVOIoErr EQU -132
_LVODelay EQU -198
main:
moveq #RETURN_FAIL,d7
bsr init
tst.l d0 ; worked?
beq exit
lea testtext1(pc),a0
bsr conputstr
lea testtext2(pc),a0
bsr conputstr
moveq #4,d0 ; wait 4 secs
bsr sleep
bsr cleanup
moveq #RETURN_OK,d7 ; all ok
exit:
move.l d7,d0
rts
; in: void
; out: d0.l success indicator, 0 for error, != 0 for success
init:
movem.l d2/a6,-(sp)
move.l 4,sysbase
move.l sysbase(pc),a6
lea dosname(pc),a1 ; open dos.library
moveq #33,d0
jsr _LVOOpenLibrary(a6)
move.l d0,dosbase
beq initerror
move.l dosbase(pc),a6 ; open console
lea consolename(pc),a0
move.l a0,d1
move.l #MODE_NEWFILE,d2
jsr _LVOOpen(a6)
move.l d0,conhandle
beq initerror
moveq #1,d0 ; success!
bra initpop
initerror:
bsr cleanup
moveq #0,d0 ; error!
initpop:
movem.l (sp)+,d2/a6
rts
; in: void
; out: void
cleanup:
move.l a6,-(sp)
move.l dosbase(pc),d0 ; dos open?
beq nodosbase
move.l d0,a6
move.l conhandle(pc),d1 ; con handle open?
beq noconhandle
jsr _LVOClose(a6)
clr.l conhandle
noconhandle:
move.l sysbase(pc),a6
move.l dosbase(pc),a1
jsr _LVOCloseLibrary(a6)
clr.l dosbase
nodosbase:
move.l (sp)+,a6
rts
; in: a0.l = null terminating string to output
; out: void
conputstr:
movem.l d2-d3/a6,-(sp)
move.l a0,d2
moveq #-1,d3
cps_strlen:
addq.l #1,d3
tst.b (a0)+
bne cps_strlen
; d3 str len, excluding terminating null
move.l dosbase(pc),a6
move.l conhandle(pc),d1
jsr _LVOWrite(a6)
movem.l (sp)+,d2-d3/a6
rts
; in: d0.w = number of seconds to sleep
; out: void
sleep:
move.l a6,-(sp)
move.l dosbase,a6
move.w d0,d1
mulu.w #50,d1
jsr _LVODelay(a6)
move.l (sp)+,a6
rts
dosname: dc.b 'dos.library',0
consolename: dc.b 'CON:0/100/640/100/TesttextWindow',0
testtext1: dc.b 'This thing works dude!!!',10,0
testtext2: dc.b $9b,'4;31;40m'
dc.b 'underline'
dc.b $9b,'3;33;40m',$9b,'5;20H'
dc.b '** Hey Dammit !! **',10,0
CNOP 0,2
sysbase: ds.l 1
dosbase: ds.l 1
conhandle: ds.l 1
-
Thx all, I stand corrected. The error code for the initial code to stop if there's an error was going to be put but I gave up since it was just to fiddle around with it, nothing serious.
@Piru
You're a masochist :-D
-
bsr init
tst.l d0 ; worked?
beq exit
this can be optimized to
bsr init
beq.b exit
Zero flag is allready set
move.l 4,sysbase
move.l 4.w,sysbase
And if you want to live on the edge move dosbase into a5 and sysbase to a6. Normally library bases has to be in a6 but dos library dont care ;)
-Rene
-
@RWO
Dosbase in A5 is just like self-modifying code, 24Bit-addressing, directly jumping into ROM or overwriting unused bits in chipset-registers.
It all worked at the time when the stuff was written........
-
@RWO
this can be optimized...
It can be optimized. It can be also made totally obfuscated and useless for the guy trying to figure out basic 68k assembler.
Size optimization was not the focus here, but clear presentation, and trying to help the guy.
And if you want to live on the edge move dosbase into a5 and sysbase to a6. Normally library bases has to be in a6 but dos library dont care ;)
BEEP! Wrong.
That only was true for Kickstart 1.x (pre-V36). Kickstart V36+ dos.library requires library base in a6, like any other library.
PS. For size optimized 68k assembler, take a look at prim.ASM (http://www.iki.fi/sintonen/src/primc/prim.ASM), sarki.lzx (http://www.iki.fi/sintonen/sw/sarki.lzx) or NanoCLS-src.lha (http://www.aminet.net/util/cli/NanoCLS-src.lha).
-
Hey man, are you the same RWO (René W. Olsen) that is responsible for so many great graphical masterpieces including the desert skull picture in Kefrens Desert Dream?
-
@Piru
>Size optimization was not the focus here
okey.
>BEEP! Wrong.
Well I could sweare that it worked lasttime tryed in v39
@Gelb
No sorry wrong person, I have the same name as RWO/Kefrens well I'm not sure about my middlename.
-
Well I could sweare that it worked lasttime tryed in v39
It might work by luck for some functions, but you can't know for sure which ones. You cannot assume the functions will continue to work like this in future OS versions, either.
Anyway, this hack only works for Kickstart 1.x dos.library, because it uses moveq + bra in jumptable and direct bsr/bra to other dos.library functions inside dos.library (BCPL legacy stuff). This hacky code was removed in V36 dos.library, and dos.library was made normal library.
-
That only was true for Kickstart 1.x (pre-V36). Kickstart V36+ dos.library requires library base in a6, like any other library.
I think that was the suggestion from V36 upwards.
I'm pretty sure the old software that uses a5 for dos will still work
:)
-
I'm pretty sure the old software that uses a5 for dos will still work
And I am sure they don't. Some functions don't need dosbase at all, but what I am 100% sure about is that dos.library functions do NOT look into A5 for dosbase, ever.
At least they will cause problems if dos.library functions are patched (the patch calling dos.library functions by itself & wrong library base in a6 -> boom).
Don't count on it. It won't work. Always put dosbase in a6 when calling dos.library.