English Amiga Board


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

 
 
Thread Tools
Old 22 July 2012, 09:05   #1
MrD
Registered User
MrD's Avatar
 
Join Date: May 2009
Location: UK
Posts: 103
dos.library Open() hangs

I'm still working on Gravity Beam. In the version I posted, all the graphics and music are included in the executable as binary data and stuff is copied to chipmem from the middle of this and it's all awful. I'm rewriting it to use AmigaDOS files, which will help me add highscores and the ability to use alternative level packs and stuff like that.

I'm using SetTaskPri (as advised from here), so the game doesn't get interrupted but I can still use dos.library disk access. I've got this at the start of my program, is there anything I'm missing out?

Code:
        move.l  ExecBase,a6                   ; We need exec to do anything!

        sub.l   a1,a1                         ; Zero - Find current task
        jsr     FindTask(a6)

        move.l  d0,a1                         ; Copy result of _LVOFindTask to address parameter.
        moveq   #127,d0                      ; task priority to very high...
        jsr     SetTaskPri(a6)

        ; Open the dos.library and store the address in Ptr_DosBase
        move.l  #String_DosLibrary,a1
        clr.l   d0
        jsr     OpenLibrary(a6)               
        move.l  d0,Ptr_DosBase                ; Address of dos.library base to Ptr_DosBase

; etc. etc. etc.

; Holds the address of the dos.library
Ptr_DosBase:
        dc.l    0

String_DosLibrary:
        dc.b    "dos.library",0
And it works... but only if the files are on a hard drive. If I copy everything to a floppy disk and run the same program, it hangs. I have no idea why.

From what I can tell in the WinUAE debugger, an Open() call never returns (and the drive light stays on). I don't think it's a problem with awry pathnames or anything like that.

Here's an example of how I'm using dos.library. There's probably one too many seeks in here, but it does what it does.

Code:
; Load an entire file into given location.
; Arguments:
;   a0 = memory location to load file into
;   a1 = filename
engine_load_file_into_memory:
        movem.l engine_load_file_into_memory_regs,-(a7)

        move.l  Ptr_DosBase,a4

        movem.l a0,-(a7)                                                   ; Push address of destination.

        ; Open a FILE handle to the given file.
        move.l  a1,d1                                                      ; Filename argument is satisfied.
        move.l  #MODE_FILE_OPEN_READ,d2                                    ; File read mode argument is satisfied.
        jsr     file_Open(a4)                                              ; OPEN FILE; d0 = FILE handle
        movem.l d0,-(a7)                                                   ; Push the returned FILE pointer in case it gets eaten.
        ; Determine the length of the file: seek to the end of the file and then read the current position.
        move.l  (a7),d1                                                    ; Handle argument is satisfied
        move.l  #0,d2                                                      ; Distance argument is satisfied (seek to 0)
        move.l  #MODE_FILE_SEEK_OFFSET_END,d3                              ; Mode argument is satisfied: seek relative to end of file.
        jsr     file_Seek(a4)                                              ; SEEK TO END OF FILE
        move.l  (a7),d1                                                    ; Handle argument is satisfied
        move.l  #0,d2                                                      ; Distance argument is satisfied (seek to 0)
        move.l  #MODE_FILE_SEEK_OFFSET_CURRENT,d3                          ; Mode argument is satisfied: seek relative to beginning of file.
        jsr     file_Seek(a4)                                              ; SEEK WITHIN FILE: don't move cursor, just report current position.
        movem.l d0,-(a7)                                                   ; Push the returned filesize value in case it gets eaten.
        ; Seek to the start of the file again
        move.l  4(a7),d1                                                   ; Handle argument is satisfied
        move.l  #0,d2                                                      ; Distance argument is satisfied (seek to 0)
        move.l  #MODE_FILE_SEEK_OFFSET_BEGINNING,d3                        ; Mode argument is satisfied: seek to beginning of file.
        jsr     file_Seek(a4)                                              ; SEEK TO BEGINNING OF FILE; d0 = 0
        ; Read contents of file into this allocated memory.
        move.l  4(a7),d1                                                   ; Handle argument is satisfied
        move.l  8(a7),d2                                                   ; Retrieve the destination address from the stack
        movem.l (a7)+,d3                                                   ; Pop the filesize value as length argument.
        jsr     file_Read(a4)                                              ; READ FROM FILE; d0 = no read bytes
        movem.l (a7)+,d1                                                   ; Pop the file structure pointer back
        jsr     file_Close(a4)                                             ; CLOSE FILE; File is now closed.
        movem.l (a7)+,d1                                                   ; Pop the variable into which to store pointer value to oblivion

        movem.l (a7)+,engine_load_file_into_memory_regs
        rts
engine_load_file_into_memory_regs reg d0-d4/a0-a4
Is there a 'but if you're loading from a floppy disk, you need to use WaitUntilItsOkToDoThat()' style gotcha I'm not aware of?

Is Forbid/Permit the better way to do this? (I had a go using that way, but it had no effect.) Or is there a simpler way still?

If you attach '2012_07_22_gravity_beam as HD directory' as a hard drive in WinUAE (A500 or A1200), boot into workbench, go to that directory in the shell and run 'game', the game should work. (There's no signal on the title that it's loaded. You press joy2 fire when all the loading's done to go to the level select.)

The ADF is the same as a bootable floppy. Its startup-sequence runs df0:game, but it just hangs (and the sector number will get stuck on 58).

How can I go about troubleshooting this?
Attached Files
File Type: zip 2012_07_22_gravity_beam as HD directory.zip (131.3 KB, 156 views)
File Type: zip Gravity Beam dodgy fileloading 2012-07 ADF.zip (145.0 KB, 157 views)
MrD is offline  
Old 22 July 2012, 09:55   #2
thomas
Registered User
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 6,121
DOS expects the library base in A6, not in A4. Generally library calls should always be done with the base in A6.

Task priority 127 is not ok, too, especially for writing. Some work is done asyncronously after Read() or Write() have already returned. If your game does not allow this to happen, data will never be written to disk or partitions might stay validating after writing your high scores. File system tasks run at pritority 10, so you should stay below that with your game.
thomas is offline  
Old 22 July 2012, 10:23   #3
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 45
Posts: 24,314
Most original DOS functions (introduced before 2.0) work even if A6 is not dosbase. BCPL side-effects.

It is wrong but it won't explain this problem.
Toni Wilen is offline  
Old 22 July 2012, 14:53   #4
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,265
Did you disable interrupts or disk DMA perhaps?

Quote:
Originally Posted by MrD View Post
I'm still working on Gravity Beam. In the version I posted, all the graphics and music are included in the executable as binary data and stuff is copied to chipmem from the middle of this and it's all awful. I'm rewriting it to use AmigaDOS files, which will help me add highscores and the ability to use alternative level packs and stuff like that.
Any reason you can't put the data in a section of its own and have AmigaOS load it directly to chipmem for you?

Code:
       section code
       
       ; code goes in any type of memory

       lea  sound, a0
       lea  gfx, a1    
       rts


       section data_c

       ; this will be loaded into chipmem

sound  incbin sound.bin
gfx    incbin gfx.bin
Some assemblers use a slightly different syntax and may ask you to add a name for the section, remove whitespace etc. but it should all be in the manual.
Leffmann is offline  
Old 22 July 2012, 23:57   #5
MrD
Registered User
MrD's Avatar
 
Join Date: May 2009
Location: UK
Posts: 103
Thank you all for the suggestions!

Quote:
Did you disable interrupts or disk DMA perhaps?
It was disk DMA.

I disabled most DMAs and set up DIW/DDF to set up the display, but then tried to load my title screen before turning the disk DMA on again. Doh!

Quote:
Any reason you can't put the data in a section of its own and have AmigaOS load it directly to chipmem for you?
That's exactly what I'm trying to avoid.

The title screen is a huge blob that's only shown once; the game goes to the level select after every level. It'll just take up chipmem if I leave it lying around. (You can't deallocate a section once you're done with it? I could use a section to allocate all the chipram I need during the load and have the title screen graphic situated within part of that section with the rest being bss/whatever-kind-of-section-is-allocated-but-not-intialised?)

I had a workaround for a while where the title was a seperate program, but I thought that was a bit silly.

With disk loading, I can load the title screen directly into memory first and do all the other loading and lut setup stuff in the background. I can also make the levels, graphics and music external to the game, so it doesn't need to be reassembled to change stuff. (Though I should make it a bit smarter than 'Let's load music.mod!, it's a 300kb mod that can't possibly fit? sure, I'll give it a go BANG.'.)

One last thing:

While my program is running the drive light stays on all the time. (This also happened with the simplest bitplane example code from the Amiga System Programmers Guide, before I used dos.library at all.)

Do I need to turn this off manually somehow? Is there a signal that my program needs to give when it's loaded right?

Last edited by MrD; 23 July 2012 at 02:02.
MrD is offline  
Old 23 July 2012, 12:29   #6
Keir
Registered User
 
Join Date: May 2011
Location: Cambridge
Posts: 621
Quote:
Originally Posted by MrD View Post
While my program is running the drive light stays on all the time. (This also happened with the simplest bitplane example code from the Amiga System Programmers Guide, before I used dos.library at all.)

Do I need to turn this off manually somehow? Is there a signal that my program needs to give when it's loaded right?
TD_MOTOR command to trackdisk.device before you knock the system on the head. Or st.b $bfd100; mov.b #$87,$bfd100 to turn off all drive motors, after knocking the system on the head.
Keir is offline  
Old 24 July 2012, 07:21   #7
MrD
Registered User
MrD's Avatar
 
Join Date: May 2009
Location: UK
Posts: 103
Quote:
TD_MOTOR command to trackdisk.device before you knock the system on the head.
Don't suppose there's an easy way to do this is there?

I had a look at how to do what you suggested and I found this... as far as I can tell, CreatePort and CreateExtIO amiga.lib functions aren't exposed to asm programs, so the guy writes asm replacements for them in the example code.

He mentions files that he's prepared for beginners with the routines in, but I can't find them or anything like them.

If I try and rewrite his code to work with vasm 1.5a, I just know I'm going to overlook something and blow up somebody's drive. Or it'll just plain not work on most Amigas. If I can't do it safely, I'm just going to have to leave the drive as it is if the program's loaded from floppy. (Which doesn't sound that safe either. )

-

I also tried out the cia motor control you suggested on the simple example code, but it seemed to have the opposite effect: it appeared that all the drive motors came on! Here's the code that I put it into. http://pastebin.com/Kt1Hmidy (This is the bitplane example code from ASPG.)

No idea what's going on there.

Last edited by MrD; 24 July 2012 at 09:52.
MrD is offline  
Old 24 July 2012, 09:59   #8
Asman
68k

Asman's Avatar
 
Join Date: Sep 2005
Location: Somewhere
Posts: 742
There is a easy way to turn off the drive light. Just wait a moment on begin of your program and system will turn off that. Just use (for example) Delay function from dos.library (first of course open dos.library)
Code:
_LVODelay	= -198

move.l	DosBase(pc),a6
moveq	#100,d1		;wait two seconds
jsr	_LVODelay(a6)
I don't remember how long you should wait but you can test it and you will find minimal time amount. Please don't use processor depend routines for such job.

Last edited by Asman; 24 July 2012 at 10:23.
Asman is offline  
Old 24 July 2012, 10:39   #9
MrD
Registered User
MrD's Avatar
 
Join Date: May 2009
Location: UK
Posts: 103
Aha! Yes, that's it! Thank you Asman!

I thought it might be something like that. Because I was using the dos.library read routine, I was surprised that it wasn't doing that itself. I didn't think I'd need to send a direct message to stop it, because I didn't take control of the drive directly to start with.

Of course, it's only afterwards that I realised that when you suppress the system, that means that you suppress the system.

Setting the task priority to something low after disk access and using _LVODelay lets the system conclude its work naturally.

Last edited by MrD; 24 July 2012 at 10:45.
MrD is offline  
Old 24 July 2012, 11:22   #10
Keir
Registered User
 
Join Date: May 2011
Location: Cambridge
Posts: 621
Quote:
Originally Posted by MrD View Post
I also tried out the cia motor control you suggested on the simple example code, but it seemed to have the opposite effect: it appeared that all the drive motors came on! Here's the code that I put it into. http://pastebin.com/Kt1Hmidy (This is the bitplane example code from ASPG.)

No idea what's going on there.
Ah, you're running on UAE probably? I think the drive LED status in the GUI is lit if the drive motor is on *or* the drive is selected in CIABPRB. It's a bit odd! I'm sure the two lines I gave you would work on a real Amiga. To get the LED status on UAE correct, you need three lines. Here's something a minuscule bit nicer than what I wrote before:
Code:
ori.b  #$f8,$bfd100
andi.b #$87,$bfd100
ori.b  #$78,$bfd100
It's really the same except it doesn't fiddle with bits 0-2, and it deselects the drives after setting their motor flip flops.

Personally I would go with this approach over a 2-second delay.

Regarding doing it via trackdisk.device, I must admit my own code to do things the polite way is written in C. I only do asm when I've knocked the system on the head. I would just go at the motor flip flops direct, I think, as above.
Keir is offline  
Old 24 July 2012, 12:14   #11
MrD
Registered User
MrD's Avatar
 
Join Date: May 2009
Location: UK
Posts: 103
Right you are. Well that explains that. Hooray!

The delay would've been no problem. I don't think anybody would notice a few extra seconds on the big title screen starting load, and a three second wait before full-on gameplay is no problem: it's a time trial game! At the moment it just puts you right into the level with the clock already running. I need to go back and put a delay in! :P
MrD is offline  
Old 24 July 2012, 16:57   #12
StingRay
move.l #$c0ff33,throat

StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,542
Quote:
Originally Posted by kaffer View Post
Ah, you're running on UAE probably? I think the drive LED status in the GUI is lit if the drive motor is on *or* the drive is selected in CIABPRB. It's a bit odd! I'm sure the two lines I gave you would work on a real Amiga. To get the LED status on UAE correct, you need three lines.
This has nothing to do with UAE, it's exactly the same on a real Amiga too.
StingRay is offline  
Old 24 July 2012, 18:25   #13
Keir
Registered User
 
Join Date: May 2011
Location: Cambridge
Posts: 621
Quote:
Originally Posted by StingRay View Post
This has nothing to do with UAE, it's exactly the same on a real Amiga too.
Really? I learn something new every day here.

EDIT: I'll have to verify this. At one point I wrote incorrect code to turn on the DF0 motor, which asserted /MTR at the same time as /SEL0, rather than before. Of course on some machines the motor would turn *off* rather than stay on. And I kept /SEL0 asserted as I expected to read from the disk. And I do not remember the internal drive's LED staying on, but annoyingly I can't 100% remember either way. Also A500 schematic shows internal drive LED driven by /MTRON. Oh well, deasserting the /SELx lines is a nice thing to do anyway.

Last edited by Keir; 24 July 2012 at 18:41.
Keir is offline  
Old 24 July 2012, 18:58   #14
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 45
Posts: 24,314
AFAIK drives with built-in led have this behavior (selected = led on). Amiga controlled (Gary for example) led shows motor status.
Toni Wilen is offline  
Old 24 July 2012, 20:39   #15
Keir
Registered User
 
Join Date: May 2011
Location: Cambridge
Posts: 621
Quote:
Originally Posted by Toni Wilen View Post
AFAIK drives with built-in led have this behavior (selected = led on). Amiga controlled (Gary for example) led shows motor status.
Yeah, this rings a bell actually. Thx for clarifying!
Keir is offline  
Old 24 July 2012, 20:55   #16
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,265
Quote:
Originally Posted by MrD View Post
Don't suppose there's an easy way to do this is there?

I had a look at how to do what you suggested and I found this... as far as I can tell, CreatePort and CreateExtIO amiga.lib functions aren't exposed to asm programs, so the guy writes asm replacements for them in the example code.
Calling Delay to wait until the motor has stopped is the shortest way of course, but if you do need to call this or anything else in amiga.lib then, because C was always the intended language to use with AmigaOS, all symbols are prefixed with an underscore and expect the C calling convention. You can get to all of it using assembly, but writing a bit of C and compiling and linking that in is more convenient.

f.ex:
Code:
    xref    _CreatePort

    move.l  #priority, -(sp)
    move.l  #name, -(sp)
    jsr     _CreatePort
    add     #8, sp
    move.l  d0, msgport
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
Open-source dos.library Don_Adan Coders. System 273 02 September 2020 01:42
Open-source graphics library Don_Adan Coders. System 32 15 January 2013 23:15
Couldn't open rexxsyslib.library V36.x! ???????? Kakaboy support.Apps 2 16 May 2010 15:56
unable to open reqtools.library RabidRabbit support.WinUAE 6 31 March 2009 14:43
Can't open version 36 of graphics.library Lambizkit support.Apps 1 07 November 2007 09:00

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 07:24.


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