08 October 2012, 20:27 | #1 |
Olle
Join Date: Oct 2012
Location: Uppsala, Sweden
Posts: 10
|
Datastructures in ASM
Hello!
I'm writing a game in BlitzBASIC and would like to use some additional data structures, like hashtables or binary trees. Is it possible to make these in assembly, or should I do them in Blitz directly? Blitz supports inline assembly, but I don't know how, or if it's even possible, to include C code in Blitz programs. Maybe as a lib? Anyway, I would be happy to take part of all the knowledge out there. Regards |
09 October 2012, 01:26 | #2 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
You can write Blitz libraries in both assembly and C as long as you link things correctly; the Blitz library header must appear before anything else, and the file must be of standard Amiga hunk format.
example: Code:
include blitz.i libheader 10, 0, 0, cleanupsub, 0 afunction string noargs subs OMEDVersion, 0, 0 name "OMEDVersion", "- Return OMED version string" astatement noargs subs OMEDVerboseErrors, 0, 0 name "OMEDVerboseErrors", "- Do verbose error reports" astatement noargs subs OMEDQuietErrors, 0, 0 name "OMEDQuietErrors", "- Do quiet error reports" afunction long noargs subs OMEDError, 0, 0 name "OMEDError", "- Return True/False error status" afunction string noargs subs OMEDErrorMessage, 0, 0 name "OMEDErrorMessage", "- Return error message string" astatement noargs subs OMEDOn, 0, 0 name "OMEDOn", "- Turn on OMED" astatement noargs subs OMEDOff, 0, 0 name "OMEDOff", "- Turn off OMED" astatement args2 string, word subs OMEDLoad, 0, 0 name "OMEDLoad", '"filename", bank - Load song from file into chip memory bank' astatement args2 string, word subs OMEDLoadFast, 0, 0 name "OMEDLoadFast", '"filename", bank - Load song from file into fast memory bank' astatement args1 word subs OMEDUnload, 0, 0 name "OMEDUnload", "bank - Unload MED bank" astatement noargs subs OMEDUnloadAll, 0, 0 name "OMEDUnloadAll", "- Unload all MED banks" astatement args1 word subs OMEDPlay, 0, 0 args2 word, word subs OMEDPlaySong, 0, 0 name "OMEDPlay", "bank[, song] - Play song and optional sub song" astatement noargs subs OMEDStop, 0, 0 name "OMEDStop", "- Stop playing" astatement noargs subs OMEDContinue, 0, 0 name "OMEDContinue", "- Continue playing" astatement args1 word subs OMEDVolume, 0, 0 name "OMEDVolume", "volume - Set volume" cleanupsub nullsub cleanup, 0, 0 libfin xref _InitPlayer, _RemPlayer xref _PlayModule, _ContModule, _StopPlayer xref _LoadModule, _LoadModule_Fast, _UnLoadModule xref _RelocModule xref _MasterVol, _ModuleNum, _fastmemplay dc.b "$VER: " versionstring dc.b "OMED OctaMED player 0.3 (17-Feb-2010) " dc.b "robert.leffmann@gmail.com", 0 even errormessageptr dc.l emptystring currentmodule dc.l 0 emptystring dc.b 0 errorhandling dc.b -1 ; 0 = silent !0 = verbose errorstatus dc.b 0 ; 0 = no error !0 = error playerstatus dc.b 0 ; 0 = off !0 = on even ; Return error message pointed to by A0 returnstring move.l a0, -(sp) .copy move.b (a0)+, (a3)+ bne .copy subq.w #1, a3 move.l a3, d0 sub.l (sp)+, d0 rts ; Set error message string pointed to by A0 and start the runtime debugger if ; verbose errors are enabled returnerror move.b errorhandling(pc), d0 ; bne .debug st errorstatus move.l a0, errormessageptr rts .debug move.l a0, -(sp) bsr cleanup move.l (sp)+, d0 trap #0 ;------------------------------------------------------------------------------- ; Return version string OMEDVersion lea versionstring(pc), a0 bra returnstring ;------------------------------------------------------------------------------- ; Return last error message string OMEDErrorMessage move.l errormessageptr(pc), a0 bra returnstring ;------------------------------------------------------------------------------- ; Enable verbose errors for runtime error debugging OMEDVerboseErrors st errorhandling rts ;------------------------------------------------------------------------------- ; Disable verbose errors OMEDQuietErrors sf errorhandling rts ;------------------------------------------------------------------------------- ; Return last error status OMEDError moveq #0, d0 move.b errorstatus(pc), d0 rts ;------------------------------------------------------------------------------- ; Set master volume OMEDVolume move.w d0, _MasterVol rts ;------------------------------------------------------------------------------- ; Turn OMED player on OMEDOn move.b playerstatus(pc), d0 ; Return if already active bne .return movem.l a3-a6, -(sp) jsr _InitPlayer movem.l (sp)+, a3-a6 tst.l d0 beq .error st playerstatus ; Set player active move.l #emptystring, errormessageptr ; No error message .return sf errorstatus ; No error status rts .error lea .msg(pc), a0 bra returnerror ; Error handling .msg dc.b "Could not initialize OctaMED player", 0 even ;------------------------------------------------------------------------------- ; Turn OMED player off OMEDOff move.b playerstatus(pc), d0 ; Return if player is off beq .return movem.l a3-a6, -(sp) move.l currentmodule(pc), d0 ; If a module is currently beq .dontstop ; playing then stop it jsr _StopPlayer .dontstop jsr _RemPlayer movem.l (sp)+, a3-a6 clr.l currentmodule ; Clear current module sf playerstatus ; Player off .return rts ;------------------------------------------------------------------------------- ; Load module loadtype dc.w 0 ; 0 = load to chip !0 = load to fast OMEDLoadFast st loadtype bra loadmod OMEDLoad sf loadtype loadmod subq.w #1, d1 ; bank number must be 1-100 cmp.w #100, d1 bhs .illegalbank lea modules(pc), a1 ; check if the bank is occupied lsl.w #2, d1 move.l (a1, d1.w), d2 beq .load ; if not then load cmp.l currentmodule(pc), d2 ; if the bank we want to bne .unload ; load into is currently movem.l d0-d2/a1/a3-a6, -(sp) ; being played then stop jsr _StopPlayer ; the player first movem.l (sp)+, d0-d2/a1/a3-a6 .unload move.l d2, a0 movem.l d0-d2/a1/a3-a6, -(sp) jsr _UnLoadModule movem.l (sp)+, d0-d2/a1/a3-a6 .load move.l d0, a0 ; point a0 to filename movem.l d1/a1/a3-a6, -(sp) move.b loadtype(pc), d0 ; check load type beq .loadchip jsr _LoadModule_Fast bra .doneloading .loadchip jsr _LoadModule .doneloading movem.l (sp)+, d1/a1/a3-a6 tst.l d0 ; check if successful beq .cantload move.l d0, (a1, d1.w) ; set bank pointer sf errorstatus move.l #emptystring, errormessageptr .return rts .illegalbank lea .bankmsg(pc), a0 bra returnerror .cantload lea .filemsg(pc), a0 bra returnerror .loadtype dc.b 0 ; 0 = chip !0 = fast .filemsg dc.b "Could not load file", 0 .bankmsg dc.b "Illegal bank number", 0 even ;------------------------------------------------------------------------------- ; Play first or selected song of selected bank OMEDPlay moveq #1, d1 ; Set song 1 if none specified OMEDPlaySong subq.w #1, d0 cmp.w #100, d0 bhs.s .illegalbank ; Bank must be 1-100 lsl.w #2, d0 lea modules(pc), a0 ; check if selected bank move.l (a0, d0.w), d2 ; is empty beq .emptybank move.b playerstatus(pc), d3 bne .playerison movem.l d0-d2/a0/a3-a6, -(sp) jsr _InitPlayer move.l d0, d3 movem.l (sp)+, d0-d2/a0/a3-a6 tst.l d3 bne .playererror st playerstatus move.l #emptystring, errormessageptr .playerison move.l currentmodule(pc), d3 beq .nocurrentmod movem.l d1-d2/a3-a6, -(sp) jsr _StopPlayer movem.l (sp)+, d1-d2/a3-a6 .nocurrentmod move.l d2, currentmodule move.l d2, a0 subq.w #1, d1 move.w d1, _ModuleNum movem.l a3-a6, -(sp) jsr _PlayModule movem.l (sp)+, a3-a6 sf errorstatus move.l #emptystring, errormessageptr .return rts .illegalbank st errorstatus move.l #.bankmsg, errormessageptr move.b errorhandling(pc), d0 beq .return bsr Cleanup move.l #.bankmsg, d0 trap #0 .emptybank st errorstatus move.l #.emptymsg, errormessageptr move.b errorhandling(pc), d0 beq .return bsr Cleanup move.l #.emptymsg, d0 trap #0 .playererror st errorstatus move.l #.playermsg, errormessageptr move.b errorhandling(pc), d0 beq .return bsr Cleanup move.l #.playermsg, d0 trap #0 .playermsg dc.b "Could not initialize OctaMED player", 0 .emptymsg dc.b "Module bank is empty", 0 .bankmsg dc.b "Illegal bank number", 0 even OMEDStop move.b playerstatus(pc), d0 beq .return move.l currentmodule(pc), d0 beq .return movem.l a3-a6, -(sp) jsr _StopPlayer movem.l (sp)+, a3-a6 .return rts OMEDContinue move.b playerstatus(pc), d0 beq .return move.l currentmodule(pc), d0 beq .return move.l d0, a0 movem.l a3-a6, -(sp) jsr _ContModule movem.l (sp)+, a3-a6 .return rts OMEDUnload subq.w #1, d0 cmp.w #100, d0 bhs.s .illegalbank lea modules(pc), a0 lsl.w #2, d0 move.l (a0, d0.w), d1 beq .return clr.l (a0, d0.w) cmp.l currentmodule(pc), d1 bne .dontstop clr.l currentmodule movem.l d1/a3-a6, -(sp) jsr _StopPlayer movem.l (sp)+, d1/a3-a6 .dontstop move.l d1, a0 movem.l a3-a6, -(sp) jsr _UnLoadModule movem.l (sp)+, a3-a6 sf errorstatus move.l #emptystring, errormessageptr .return rts .illegalbank st errorstatus move.l #.bankmsg, errormessageptr move.b errorhandling(pc), d0 beq .return bsr Cleanup move.l #.bankmsg, d0 trap #0 .bankmsg dc.b "Illegal bank number", 0 even OMEDUnloadAll movem.l a3-a6, -(sp) jsr _StopPlayer movem.l (sp)+, a3-a6 moveq #100-1, d0 lea modules+400(pc), a0 .unload move.l -(a0), d1 beq .nomod clr.l (a0) movem.l d0/a0/a3-a6, -(sp) move.l d1, a0 jsr _UnLoadModule movem.l (sp)+, d0/a0/a3-a6 .nomod dbf d0, .unload rts cleanup movem.l a3-a6, -(sp) bsr Off bsr UnloadAll movem.l (sp)+, a3-a6 rts modules blk.l 100, 0 |
09 October 2012, 12:13 | #3 |
gone
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
|
Off topic this but... just gotta quickly say: always so impressed with your versatility Leffmann.
|
09 October 2012, 15:19 | #4 |
Olle
Join Date: Oct 2012
Location: Uppsala, Sweden
Posts: 10
|
Thank you, Leffman!
Is there a guide of doing Blitz libs anywhere? The Blitz2 manual only speaks about an "advanced kit", which is nowhere to be found. |
10 October 2012, 12:40 | #5 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Don't know of any thorough guides. I used the LotanLibs as a quick guide, and I also found some information in a Blitz Basic manual. I can't find the manual on my hard drive, and I can't remember where I got it from, sorry.
Thanks, I wish I was less of a tinkerer and more of a finisher like you. You actually finish stuff while I just muck about |
10 October 2012, 20:52 | #6 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
I'm not sure whether there are limits to Blitz Basic that prevent you from taking this simple project further, and I'm not sure where binary trees and hash tables could take the game idea. It's certainly possible to do anything you want with Asm, and to some extent with C++, and if you really understand binary trees and hash tables, you can of course implement them in any language that can access RAM.
Structures in Asm consist of a structure label and offsets to its parts, like C but without type-ing. Assembler macros can help instantiating, but by nature structures are data-less descriptors, or "complex types". Don't know if that or Leffman's structures help you, I think you need a binary tree or hash table example in Asm or Blitz? Hash tables are at least used in AmigaOS, see Libs & Devices, and for a binary tree Huffman coding should be a simple one that exists in Asm for Amiga. Last edited by Photon; 10 October 2012 at 20:57. |
10 October 2012, 22:53 | #7 |
Olle
Join Date: Oct 2012
Location: Uppsala, Sweden
Posts: 10
|
I could actually do it all in Blitz with malloc, peek and poke. Just wanted to know if there was a faster way. But you have to use to OS malloc anyway, even in assembly, so I suppose there's not so much difference. Also, of course, I want to be able to do Blitz libs to limit the size of my already too big source file.
Since there is a lot of Sweds in this thread, I can recomend reading this thread, where morot explains how and why dynamic data structures cause bubbles in the CPU pipeline. Oh, and the Blitz manual and other stuff can be found here: http://www.blitz-2000.co.uk/ |
13 October 2012, 12:38 | #9 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
The compiler will choke on the syntax of course, and I don't think you can use it as inline assembly without rewriting it.
Looking at it again I'm not sure if the library header needs to sit first in the object file, or if Blitz finds the header via the _BlitzLibStart symbol, and in any case I don't think C makes any guarantees about padding, alignment and placement of arrays and structures, so I would just define the header using the assembly macros and write the actual code in C, and link everything together with the header at the beginning. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Need an ASM manual | VoltureX | Coders. General | 2 | 17 November 2011 15:24 |
for ASM programmers | meynaf | Coders. General | 29 | 05 August 2010 10:00 |
Using ReadArgs() from asm | oRBIT | Coders. General | 4 | 11 May 2010 16:11 |
6502 Asm | pmc | Coders. General | 21 | 06 November 2008 09:37 |
ASM Uni Course | BippyM | Coders. Tutorials | 27 | 18 September 2008 10:37 |
|
|