[Coco] os9/drivewire driver problems
aawolfe at gmail.com
Sun Nov 8 19:20:20 EST 2009
On Sun, Nov 8, 2009 at 5:46 PM, Aaron Wolfe <aawolfe at gmail.com> wrote:
> Thanks for the response Boisy. Your name is becoming a very common
> sight on my screen as I look through the NitrOS9 and drivewire
> modules.. is there anything you didn't write or improve? :)
> I tried removing the A from the PULS but got the same results. I am
> failing to understand something about how the data is returned from
> the DWSUB to the calling routine. The reason I was pulling A, was I
> thought the byte read by DWSUB,READ would be on the stack.. because I
> thought I was putting a pointer to my stack in X prior to calling
> DWSUB. But I must be getting this wrong, either in concept or
> implementation. I apologize, my assembler skill was never very good
> and I'm very rusty. Trying to learn as I go here.
> What is the proper way to get 1 byte of data from DWSUB into A? I see
> that when the rbfdw driver reads in a block, it puts a pointer to
> PD.BUF in X prior to the read call, I am guessing this is where OS9
> expects the block to be returned.
> * Get 256 bytes of sector data
> ldx 5,s
> ldx PD.BUF,x get buffer pointer into X
> ldy #$0100
> jsr 3,u
> when the clock2_dw gets time, I see:
> ldx #D.Year
> ldy #$0005
> jsr 3,u
> So X is the constant D.Year, $53 from the coco OS9Defs file, I am
> guessing this is writing the returned bytes directly into OS9's "whats
> the current time" area?
> Eventually I'd like to read a variable amount of data from the server,
> but for now I am trying to just get one character at a time (the
> server additions I've made have a buffer that can make this work sort
> of OK).
> So.. if I just want to get one byte into the A register.. can anyone
> point out where my code or comments are wrong? I'm sure I'm
> misunderstanding something. I've found what I think are some other
> problems in my code, but still I get the same behavior, constant calls
> back and forth to read and write with null results.
> Current attempt:
> Read equ *
> lda #OP_SERREAD ; put opcode for read in A
> pshs a ; put A on stack
> leax ,s ; put pointer to top of stack in X
> ldy #$0001 ; put 1 in Y because we want to send 1 byte
> ldu >D.DWSUB ; put addr of DWSUB in U
> jsr 6,u ; call write routine, it should send one byte to
> server asking for a character
> * puls a ; was removing it, but I think I need to leave a
> byte there so we have room for incoming byte and don't clobber other
> ldy #$0001 ; we want to read 1 byte back
> leax ,s ; and put it on our stack, in place of A/the opcode
> used in previous call
> jsr 3,u ; call DWSUB to read 1 byte
> puls a,pc ; pull that byte and the pc off stack (pc now sends
> us back to calling routine?)
I just did a bit of an experiment, returning the byte sent by the
server as the error code (in B) instead of the data in A. This works
great, I get error #X where X is whatever value the server sends..
Read equ *
lda #$FF ; cause cc to be set
adda #$01 ;
puls b,pc ; return character from DW as error #
So this technique *is* getting the byte from the server. Yet when I
return the same byte in A, with no error... I get strangeness.
What I thought was the shell echoing characters might be something
else, because when I do something like: LIST /T2
which I think should just read from /T2 until EOF (which is not going
to happen, but whatever).. instead I get the same cycle of READ/WRITE
requests to the driver. Why would I get a write request at all here?
I think I am actually getting the bytes from DW, so what I thought was
my problem isn't really the problem.. somehow I am not implementing
or understanding something.. thats about as specific as I can get :)
thanks for any advice, I'm reading through everything I can find on
scf device drivers and not finding the clue so far.
> I am guessing the address I'm supposed to return to is already on the
> stack when Read gets called? Lots of example seem to pull PC of the
> stack when they are ready to return but I haven't found where this is
> documented so not entirely sure.
> Well.. something is wrong with my code, any clues are much appreciated.
> On Sun, Nov 8, 2009 at 8:37 AM, Boisy G. Pitre <boisy at tee-boy.com> wrote:
>> On Nov 8, 2009, at 5:58 AM, Aaron Wolfe wrote:
>>> First, please don't laugh, I am new and surely making many simple mistakes
>>> Second, I cannot say thank you enough to everyone who has made
>>> NitrOS9, the toolshed and drivewire possible. I'm very impressed by
>>> how well the tools work.
>> I think it's awesome that someone is taking the reigns and doing something
>> like this. Good going.
>>> I am trying to add to drivewire the ability to act as a serial port
>>> under NitrOS9. I've managed to setup a build environment and create a
>>> device descriptor and driver for the new device. I added the op codes
>>> and handling routines on the server side, etc. I have write working,
>>> but that's the easy part since the dw printer driver already did that
>>> and I mostly just copied it.
>>> So, I can do things like: LIST STARTUP > /T2
>>> and everything works great.
>> Good so far.
>>> However, read is another story. I can't seem to get anything working
>>> properly and after several hours I am stumped.
>>> Here's what I think I've figured out about how dw works, I might have
>>> some things wrong.
>>> To read a character, I think I am supposed to put my opcode in A,
>>> pointer for the incoming data in X (usually my stack, i think?), the
>>> number of bytes to read in Y.
>>> Then, jsr to the DWSUB and let the magic happen? At least this is
>>> what I think I've gleaned from the source of other modules.
>>> According to the OS9 dev manual, the Read routine should return a
>>> character in reg A.
>> This all sounds correct.
>>> So, my first attempt was:
>>> lda #OP_SERREAD
>>> pshs d
>>> leax ,s
>>> ldy #$0001
>>> ldu >D.DWSUB
>>> jsr 6,u
>>> ldy #$0001
>>> leax ,s
>>> jsr 3,u
>>> puls d,a,pc
>>> I may be doing stupid things here, I haven't done 6809 assembler in
>>> many years. I'm not sure what the 6, and 3, in the JSRs is for, it
>>> seems like every write uses 6 and read uses 3 in the other modules.. ?
>> the jsr 6,u says: "save the address of the next instruction on the stack,
>> then obtain the two byte location 6 bytes from the U register and jump to
>> that location." The 6 jumps into the WRITE section of the DWSUB routine,
>> and the 3 jumps into the READ routine.
>>> This "works" in the sense that the server sees the call and sends back
>>> a byte. However, I've botched something because the process calling
>>> read always gets a null character. If I spawn a shell on /T2, it
>>> reads and writes bytes constantly (I think it's echoing the character
>>> it thinks I typed) but its all null chars.
>> Your last line needs to read: puls d,pc
>> You don't want to pull A off the stack because you haven't pushed it on
>> prior to the call. I think you will find that it works after that.
>> Note that you should be checking for a timeout error after the jsr 3,u and
>> load B with an error if so, but get this working first.
>>> So, I thought to test I would just:
>>> lda #OP_SERREAD
>>> (#OP_SERREAD is the character 'C'). I was hoping then that something
>>> like LIST /T2 would give me a stream of Cs. But instead I get Error
>>> 208, Illegal service request.
>> Error #208 is an illegal service request. I suspect you aren't implementing
>> something in your getstat or setstat routine; I don't remember the exact
>> issue here, and I'm not at my CoCo at the moment to test this out and
>> Try the fix above with your shell test and see if something happens. Let us
>>> Hopefully this makes some kind of sense, I'm sure I've done something
>>> silly but if I make Read just put a constant in A and clear B (no
>>> errors), shouldn't I get a character every time I call Read?
>>> Thanks for any pointers
>>> Coco mailing list
>>> Coco at maltedmedia.com
>> Coco mailing list
>> Coco at maltedmedia.com
More information about the Coco