English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 08 October 2012, 21:27   #1
lole
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
lole is offline  
Old 09 October 2012, 02:26   #2
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,265
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
You also need http://aminet.net/dev/basic/LotanLibs.lha
Leffmann is offline  
Old 09 October 2012, 13:13   #3
pmc
gone
pmc's Avatar
 
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.
pmc is offline  
Old 09 October 2012, 16:19   #4
lole
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.
lole is offline  
Old 10 October 2012, 13:40   #5
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,265
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.

Quote:
Originally Posted by pmc View Post
Off topic this but... just gotta quickly say: always so impressed with your versatility Leffmann.
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
Leffmann is offline  
Old 10 October 2012, 21:52   #6
Photon
Moderator

Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 4,818
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 21:57.
Photon is offline  
Old 10 October 2012, 23:53   #7
lole
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/
lole is offline  
Old 13 October 2012, 03:14   #8
lole
Olle
 
Join Date: Oct 2012
Location: Uppsala, Sweden
Posts: 10
That "blitz.i" file, is it possible to use those macros in C development? Or do you have to declare the same macros in a .h-file?
lole is offline  
Old 13 October 2012, 13:38   #9
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,265
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.
Leffmann is offline  
 


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 16:24
for ASM programmers meynaf Coders. General 29 05 August 2010 11:00
Using ReadArgs() from asm oRBIT Coders. General 4 11 May 2010 17:11
6502 Asm pmc Coders. General 21 06 November 2008 10:37
ASM Uni Course BippyM Coders. Tutorials 27 18 September 2008 11:37

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 23:56.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.
Page generated in 0.07767 seconds with 15 queries