Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

call prodos from aux ram working

11 views
Skip to first unread message

aiia...@gmail.com

unread,
Jan 15, 2007, 2:44:58 AM1/15/07
to
I got it working (hours and hours of stepping through code)

I can use prodos MLI calls for OPEN file and READ file,

other commands should be easy now...

MLI call parameters are passed to MAIN ram through
the input buffer....

I just loaded a file, "TEST" (contains 01 02 03 04 05 06 07 08 09)
to $1400 (what a weird spot... not really, I put #20 instead of #$20)
in aux RAM, just by making an MLI call from AUX ram!

prior to the MLI call from AUX RAM,

*1400L

all it shows is random junk...

after the call,

jsr mli
dfb commandcode (open)
dfb parmtablelo
dfb parmtablehi
jsr mli
dfb commandcode (read)
dfb parmtablelo
dfb parmtablehi

rts

I type:

*1400L

and it shows:

01 02 03 04 05 06 07 08 09


woo hoo!

now I'd like to add:

#00
from aux ram, save file to disk.
just a few more lines of code and I'll have this

execute from main RAM:
1)"load to aux bank # XX", so I can call the mli and have it load the
file to the
appropriate RWIII bank...

2)execute from aux bank, LOAD to aux bank ##, so I can call the MLI and
load
a file to another aux bank

3)execute from aux bank, save AuxBank #XX, address WXYZ to disk, so I
can
save (from aux ram) other areas of RAM in another aux bank

4) add active bank MLI call, caught by my code before it gets to the
MLI,
initializes an aux bank for running code

5) MLI call to JSR any address within another AUX bank, or in main RAM.


basic system doesn't work... I haven't tried to get it to work yet.

basic works from the aux bank, the monitor works from the aux bank,

only 847 bytes of ram required to use OPEN and READ from aux,
as well as switching code to allow switching between "active" banks,
or banks with programs running in them..

thats 847 bytes of ram for code... the buffers require:

256 bytes of ram at $200, to pass call info between
main and aux.. doesn't count towards total, because
input buffer isn't being used during MLI call (as far as I can tell)

256 bytes of ram at $2000, for READ ***data**** buffer,
and 1024 bytes of ram at $6000, for open ***file*** buffer...

847
+1024
+ 256
---------
2127 bytes total

I can cut this down a bit by making some of the code
subroutines..

all of the buffers are definitely moveable... I need to change
some hard coded assembly addresses to labels to make it easy.

that would just allow me to change the buffers at assembly time..
perhaps I should add a few bytes of information to what is transferred
in the input buffer, so the MLI patch knows where the buffers should go
in main RAM..

the data buffer in aux ram is definable, the usual data buffer
specification
in the MLI READ call..

Rich

aiia...@gmail.com

unread,
Jan 15, 2007, 2:58:34 AM1/15/07
to

aiiad...@gmail.com wrote:
> I got it working (hours and hours of stepping through code)
> now I'd like to add:
>

also, another command in the patched MLI:

command:
$FF (I'll have to figure out a suitable code)

parm list:

+00 = len, although I don't need this, since I'm grabbing
this before the mLI gets it...
+01 = src bank#, 0 = main, 1 =aux bank1, 2=aux bank2, etc
+02 = destination bank #
+03 = source lo address
+04 = source hi address
+05 = source end lo address
+06 = source end hi address
+07 = dest lo address
+08 = dest hi address

then I can make a call ,

JSR MLI ;update main ram screen
dfb $FF
dfb #>parmlist
dfb #<parmlist
rts

parm list:

dfb #05 ; +00 = len, although I don't need this, since I'm
grabbing
; this before the mLI gets it...
dfb #01 ;+01 = src bank#, 0 = main, 1 =aux bank1, 2=aux bank2, etc
dfb #00 ;+02 = destination bank #
dfb #00 ;+03 = source lo address
dfb #04 ;+04 = source hi address
dfb #FF ;+05 = source end lo address
dfb #07 ;+06 = source end hi address
dfb #00 ;+07 = dest lo address = 0400
dfb #04 ;+08 = dest hi address

and move $400-$7FF, aux bank "text screen" to the main RAM
text screen... the apple II displays
the text screen from main ram only

and it would use the switching code I already have set up in
the MLI patch..

Rich

aiia...@gmail.com

unread,
Jan 15, 2007, 3:17:45 PM1/15/07
to
this code executes properly (loads a file from disk into
aux ram using prodos MLIfrom a program running in aux ram..

something wrong with the return address, so there are
multiple RTS instructions at the end of the routine..

ORG $2600


;TEST TO SEE IF IT WILL LOAD FROM AUX RAM

MLI EQU $BF00

OPENFILE

JSR MLI
DFB #$C8
DFB #<OPENFILEPARM
DFB #>OPENFILEPARM

LDA $207
STA READ_REF_NUM
STA CLOSE_REF_NUM

READFILE JSR MLI
DFB #$CA ;command code = READ
DFB #<READFILEPARM
DFB #>READFILEPARM

RTS
RTS

;CLOSEFILE
; JSR MLI
; DFB #$CC
; DFB #<CLOSEFILEPARM
; DFB #>CLOSEFILEPARM
;
; RTS
NOP
NOP
NOP

CLOSEFILEPARM
DFB #01
CLOSE_REF_NUM DFB #00


READFILEPARM
DFB #04 ;NUM of parameters
READ_REF_NUM DFB #00 ; read ref number
DFB #00 ;<IO_buffer
DFB #$20 ;>IO_buffer
DFB #$90 ;lo requested length
DFB #01 ;hi
ACTUALREAD DFB #00 ;lo actual length read
DFB #00 ;hi


;read:
;+00 = 04 len
;+01 = ref number
;+02, 03 = address of data buffer
;+04, 05 = requested length
;+06, 07 = actual length

OPENFILEPARM
DFB #03
DFB #<PATHNAME
DFB #>PATHNAME
DFB #$00 ;FILE BUFFER
DFB #$60
OPEN_REF_NUM DFB #00 ;reference number of open file

;+00 = 3 len
;+01, 02 = address of pathname
;+03, 04 = address of file buffer
;+05 = reference number


PATHNAME DFB #4 ;LEN
ASC "TEST"

Don Bruder

unread,
Jan 15, 2007, 4:33:20 PM1/15/07
to
In article <1168892264....@11g2000cwr.googlegroups.com>,
aiia...@gmail.com wrote:

> this code executes properly (loads a file from disk into
> aux ram using prodos MLIfrom a program running in aux ram..
>
> something wrong with the return address, so there are
> multiple RTS instructions at the end of the routine..

This is using your homebrewed "MLI interceptor" thing, right? If so, the
"something" that's wrong with the return address is probably the fault
of your interceptor not doing things quite the same way the MLI normally
does. (Standard MLI calls diddle the return address by +3 to jump over
the command byte and the pointer to the parameter block - Are you paying
attention to that step in your interceptor?)

--
Don Bruder - dak...@sonic.net - If your "From:" address isn't on my whitelist,
or the subject of the message doesn't contain the exact text "PopperAndShadow"
somewhere, any message sent to this address will go in the garbage without my
ever knowing it arrived. Sorry... <http://www.sonic.net/~dakidd> for more info

aiia...@gmail.com

unread,
Jan 15, 2007, 10:39:12 PM1/15/07
to

Don Bruder wrote:
> This is using your homebrewed "MLI interceptor" thing, right?

yeah..

>If so, the
> "something" that's wrong with the return address is probably the fault
> of your interceptor not doing things quite the same way the MLI normally
> does. (Standard MLI calls diddle the return address by +3 to jump over
> the command byte and the pointer to the parameter block - Are you paying
> attention to that step in your interceptor?)

yeah.. it's fixed now. Thanks for the reply..


Rich

Oliver Schmidt

unread,
Jan 16, 2007, 4:58:31 PM1/16/07
to
Hi Rich,

>256 bytes of ram at $200, to pass call info between
>main and aux.. doesn't count towards total, because
>input buffer isn't being used during MLI call (as far as I can tell)

Unfortunately this isn't true. If ProDOS finds a Thunderclock
compatible clock it'll call it in about every MLI call to update its
time in the $BF page. And the Thunderclock protocol is to put the
time/date in the input buffer. It was designed that way to be easily
usable from BASIC.

You'll find several places in 'Contiki for the Apple2' where the input
buffer is saved before MLI calls and restored afterwards ;-)

Best, Oliver

aiia...@gmail.com

unread,
Jan 16, 2007, 5:14:46 PM1/16/07
to

Oliver Schmidt wrote:
> Unfortunately this isn't true.
> the Thunderclock protocol is to put the
> time/date in the input buffer. It was designed that way to be easily
> usable from BASIC.

OK.. I didn't know this.. how much of the input buffer is used
for the Thunderclock protocol?


> You'll find several places in 'Contiki for the Apple2' where the input
> buffer is saved before MLI calls and restored afterwards ;-)

What is the purpose of saving the input buffer before MLI call?
IE, what is in the input buffer before the MLI that you would
want to keep?

Thanks for the reply,

Rich

aiia...@gmail.com

unread,
Jan 16, 2007, 9:27:21 PM1/16/07
to

aiia...@gmail.com wrote:
> I got it working

working on the SAVE portion...

requested length to save...
hibyte = # of 256 byte blocks
lobyte = # of left over bytes

I use a 256 byte window to transfer
data between aux and main.. this is to
keep MAIN ram usage minimal.

To save a file, with requested lengh $HILO,
I need to :

transfer $HI blocks of 256bytes,

ldx $hi
loop move aux to main 256 bytes
save (write) 256 bytes
dex
bne loop

there are $lo bytes left over, so I do:
move aux to main 256 bytes
save (write) $LO bytes

just like David Empson suggested on
Thurs, Aug 10 2006 on this newsgroup..

Rich

Michael J. Mahon

unread,
Jan 18, 2007, 2:02:20 AM1/18/07
to
aiia...@gmail.com wrote:
> aiia...@gmail.com wrote:
>
>>I got it working
>
>
> working on the SAVE portion...
>
> requested length to save...
> hibyte = # of 256 byte blocks
> lobyte = # of left over bytes
>
> I use a 256 byte window to transfer
> data between aux and main.. this is to
> keep MAIN ram usage minimal.

If ProDOS optimizes aligned (with start of file)
512-byte transfers, that would be a much more
efficient choice.

-michael

NadaNet networking for Apple II computers!
Home page: http://members.aol.com/MJMahon/

"The wastebasket is our most important design
tool--and it's seriously underused."

aiia...@gmail.com

unread,
Jan 18, 2007, 12:01:46 PM1/18/07
to

Michael J. Mahon wrote:

> aiia...@gmail.com wrote:
> > I use a 256 byte window to transfer
> > data between aux and main.. this is to
> > keep MAIN ram usage minimal.
>
> If ProDOS optimizes aligned (with start of file)
> 512-byte transfers, that would be a much more
> efficient choice.
>


OK...

what the code is doing right now:

in aux... call MLI, "bload" file (read), a$abcd (data buffer), l$abcd
(req. length)
the command code and parm table are saved
the command code and parm table are moved to MAIN
LOWLEN = req. length lowbyte
HILEN = req length hibyte
auxdatabuffer = databuffer ;save the databuffer address

DataBuffer = $2000 in main RAM

req len = $00FF ;request 256 bytes ata time..

loop
call MLI ;loads 256 bytes
dfb command code
dfb parmtable LO
dfb parmtable HI

call auxmove, move those bytes to
databuffer in aux RAM... Increment data buffer
in aux RAM by 256 bytes (increment hibyte)

inc auxdatabufferHI

dec HILEN ;this is number of pages to transfer
bne loop

;now there are LOWLEN bytes left to load then move...


Once it's all running good with my 6502 code that needs
it, I'll optimize it to your suggestions...

Thanksfor the reply,

Rich

Michael J. Mahon

unread,
Jan 18, 2007, 3:54:35 PM1/18/07
to
aiia...@gmail.com wrote:
> Michael J. Mahon wrote:
>
>>aiia...@gmail.com wrote:
>>
>>>I use a 256 byte window to transfer
>>>data between aux and main.. this is to
>>>keep MAIN ram usage minimal.
>>
>>If ProDOS optimizes aligned (with start of file)
>>512-byte transfers, that would be a much more
>>efficient choice.
>>
>
>
>
> OK...
>
> what the code is doing right now:
>
> in aux... call MLI, "bload" file (read), a$abcd (data buffer), l$abcd
> (req. length)
> the command code and parm table are saved
> the command code and parm table are moved to MAIN
> LOWLEN = req. length lowbyte
> HILEN = req length hibyte
> auxdatabuffer = databuffer ;save the databuffer address
>
> DataBuffer = $2000 in main RAM
>
> req len = $00FF ;request 256 bytes ata time..

You want $100 for 256 bytes. ;-)

And if you read the file in chunks of 512 ($200) bytes,
ProDOS won't have to read the disk into its buffer and
then move data to your buffer--instead it can read data
directly to your buffer.

Since you already have to move the data once to/from
your "window" buffer, it would be good to avoid another
move by ProDOS.

> loop
> call MLI ;loads 256 bytes
> dfb command code
> dfb parmtable LO
> dfb parmtable HI
>
> call auxmove, move those bytes to
> databuffer in aux RAM... Increment data buffer
> in aux RAM by 256 bytes (increment hibyte)
>
> inc auxdatabufferHI
>
> dec HILEN ;this is number of pages to transfer
> bne loop
>
> ;now there are LOWLEN bytes left to load then move...
>
>
>
>
> Once it's all running good with my 6502 code that needs
> it, I'll optimize it to your suggestions...

Happy coding!

aiia...@gmail.com

unread,
Jan 18, 2007, 4:26:23 PM1/18/07
to

Michael J. Mahon wrote:
> You want $100 for 256 bytes. ;-)

oops..


> And if you read the file in chunks of 512 ($200) bytes,
> ProDOS won't have to read the disk into its buffer and
> then move data to your buffer--instead it can read data
> directly to your buffer.


cool... so If I read 512bytes, the filebuffer is bypassed?

Open command requires filebuffer

read/write command require databuffer.

the filebuffer is 1kilobyte...

to open a file from aux RAM, I use 1k of MAIN RAM just
to open the file...

I am trying to keep the DATA buffer (read/write commands)
small to minimize main RAM usage..

Rich

Rich

Michael J. Mahon

unread,
Jan 18, 2007, 5:06:27 PM1/18/07
to

I understand, but another page is only 20% more main RAM space,
and it could considerably speed data transfer, particularly
for fast storage devices.

aiia...@gmail.com

unread,
Jan 18, 2007, 5:14:39 PM1/18/07
to

Michael J. Mahon wrote:

>>aiiadict wrote:
> > I am trying to keep the DATA buffer (read/write commands)
> > small to minimize main RAM usage..
>
> I understand, but another page is only 20% more main RAM space,
> and it could considerably speed data transfer, particularly
> for fast storage devices.
>

OK... The requested length (to read/write) and the ammount
of data to move from main-->aux(read) or aux-->main (write)
are now POKE-able, so you can optimize for 1)minimal RAM
usage or 2)"fast storage device"

a small basic program gives you options 1 and 2 above.

Rich

Oliver Schmidt

unread,
Jan 20, 2007, 8:44:22 AM1/20/07
to
Hi RIch,

>> Unfortunately this isn't true.
>> the Thunderclock protocol is to put the
>> time/date in the input buffer. It was designed that way to be easily
>> usable from BASIC.
>
>OK.. I didn't know this..

I know, therefore I told it to you ;-)

> how much of the input buffer is used
> for the Thunderclock protocol?

I didn't try to figure that out. When I knew I had to deal with it I
just copied the whole page.

>> You'll find several places in 'Contiki for the Apple2' where the input
>> buffer is saved before MLI calls and restored afterwards ;-)
>
>What is the purpose of saving the input buffer before MLI call?
>IE, what is in the input buffer before the MLI that you would
>want to keep?

The cc65 C-Library for the Apple2 allows to pass command line
parameters with this construct:

call 2048:rem param1 param2 "param 3 with blanks" param4 param5

The C-Library startup code then parses the parameters from the input
buffer and makes them accessable via:

main(int argc, char *argv[])

So I need to take care of the input buffer on MLI calls necessary
before parsing the command line parameters.

BTW: I wrote a generic ProDOS loader. This is a SYS file that loads a
BIN file into memory and jumps to it. It's generic in that it works
with all BIN files fitting into memory (and not using page 3). It
works especially well with cc65 programs as it has a special feature
for them:

My ProDOS loader supports the ProDOS startup file protocol and
"emulates" the behaviour of the command line above so that cc65
programs started with my loader can receive the startup file as the
first (and only) parameter in their main().

I used this feature in Contiki for GS/OS finder integration using a
suitable ICON file. When opening a Contiki program in the GS/OS
finder, Contiki get's started via my loader and receives that program
in its main() and autoloads that program...

Maybe you didn't want to know all those details but I was in the mood
for it ;-)

Best, Oliver

Michael J. Mahon

unread,
Jan 20, 2007, 6:10:12 PM1/20/07
to
Oliver Schmidt wrote:
> Hi RIch,
>
>
>>>Unfortunately this isn't true.
>>>the Thunderclock protocol is to put the
>>>time/date in the input buffer. It was designed that way to be easily
>>>usable from BASIC.
>>
>>OK.. I didn't know this..
>
>
> I know, therefore I told it to you ;-)
>
>
>>how much of the input buffer is used
>>for the Thunderclock protocol?
>
>
> I didn't try to figure that out. When I knew I had to deal with it I
> just copied the whole page.

Most clock cards used the input buffer ($200) to pass their
results to BASIC. The most space that can be used depends on
the format of the time/date information returned, which is
usually selectable by the user.

In no case does it exceed $2FF, since ProDOS uses $280..$2FF
as a pathname buffer (another possible issue).

Actually, lots of that kind of detail can only encourage others
to write code for Contiki. ;-)

In the absence of a "Contiki Technical Reference Manual", every
additional bit of lore helps!

Michael J. Mahon

unread,
Jan 20, 2007, 6:13:06 PM1/20/07
to
Michael J. Mahon wrote:
> Oliver Schmidt wrote:
>
>> Hi RIch,
>>
>>
>>>> Unfortunately this isn't true.
>>>> the Thunderclock protocol is to put the
>>>> time/date in the input buffer. It was designed that way to be easily
>>>> usable from BASIC.
>>>
>>>
>>> OK.. I didn't know this..
>>
>>
>>
>> I know, therefore I told it to you ;-)
>>
>>
>>> how much of the input buffer is used
>>> for the Thunderclock protocol?
>>
>>
>>
>> I didn't try to figure that out. When I knew I had to deal with it I
>> just copied the whole page.
>
>
> Most clock cards used the input buffer ($200) to pass their
> results to BASIC. The most space that can be used depends on
> the format of the time/date information returned, which is
> usually selectable by the user.
>
> In no case does it exceed $2FF, since ProDOS uses $280..$2FF
> as a pathname buffer (another possible issue).

Whoops, that first $2FF was supposed to be $27F. ;-)

aiia...@gmail.com

unread,
Jan 22, 2007, 1:39:09 AM1/22/07
to

aiia...@gmail.com wrote:
>mli WORKING from aux ram

I try loading basic.system to 2000 and then
type 2000G...

the rom gets stuck in an infinite loop in the F100
area..

I'm trying to see if I can modify the exerciser to
not flip the 80 column switches, so I can run
it from aux ram.

Rich

aiia...@gmail.com

unread,
Jan 22, 2007, 2:00:17 AM1/22/07
to

aiia...@gmail.com wrote:
>
> I'm trying to see if I can modify the exerciser to
> not flip the 80 column switches, so I can run
> it from aux ram.
>

woohoo! I got the Exerciser screen to come up
in aux ram (with 80columns active)

I can type in command code,
modify paramaters..

something goes wrong when I execute
the command (BRK at 00) which tells
me something isn't quite right..

but it's progress.

It isn't %100 necessary to get it
working, but it would be nice to..
then I could "exercise" the prodos
MLI commands from aux, to prove
they all work.

anyway, OPEN, READ, WRITE, and
CLOSE are working perfectly from
aux ram.. (verified by me running programs
that call the MLI from aux ram)...
programs can run, unmodified, in aux ram.
(as long as they don't flip aux/main switches)..
IE mli calls work great from aux ram.

now I need to work on my memory manager
to keep track of what I have stored, where

I think I'll do:
file1: bank, address
file2: bank, address

and:

aux1:
page0:used
page1:used
page2:used
page3:free
etc..

maybe copy Prodos method of keeping track of
free pages.

I wish text/graphics could be displayed
directly from aux banks.

Rich

aiia...@gmail.com

unread,
Jan 22, 2007, 3:03:55 AM1/22/07
to

aiia...@gmail.com wrote:
> aiia...@gmail.com wrote:
> >
> > I'm trying to see if I can modify the exerciser to
> > not flip the 80 column switches, so I can run
> > it from aux ram.
> >
>
> woohoo! I got the Exerciser screen to come up
> in aux ram (with 80columns active)
>
> I can type in command code,
> modify paramaters..
>
> something goes wrong when I execute
> the command (BRK at 00) which tells
> me something isn't quite right..

I see.. my MLI call catcher gets overwritten
when exerciser relocates itself.. I need to find
out if exerciser looks at the global page Memory in use
map.. if it does, I can modify the globalpage
to reflect the fact that the RAM is in use..

Rich

aiia...@gmail.com

unread,
Jan 22, 2007, 3:07:21 PM1/22/07
to

aiia...@gmail.com wrote:
>> I wish text/graphics could be displayed
> directly from aux banks.

I can modify CSW (character output)
to point to my own routine...

set WriteMain ram
call the regular CSW routine,
set writeaux ram
rts

the code in main ram will have to save
the text screen to disk if it's important
(or just save it to another part of RAM,
reload it on returning to main ram program)

Rich

aiia...@gmail.com

unread,
Jan 22, 2007, 4:33:37 PM1/22/07
to

aiia...@gmail.com wrote:
> aiia...@gmail.com wrote:
> >> I wish text/graphics could be displayed
> > directly from aux banks.
>
> I can modify CSW (character output)
> to point to my own routine...


I was thinking about the read ROM/Write wram for
the LC area.. you cannot change read/write seperately
for the lower 48k..

but... I figured out a way to do it...

change CSW to myroutine:

PATCHCSW
lda #<myroutine
sta csw
lda #>myroutine
sta csw+1
rts

myroutine:

;A contains character to send to screen?
;set normal RAM state for Prodos
sta wrmainRam; r/w main ram
sta setstdZI ;read/write main zeropage

==;this code has to be in MAIN RAM!
==jsr (CSW)
==sta wrAuxRAM ;set to aux bank RAM

RTS ; in aux ram

That'll slow down text screen access for
aux ram programs, but it should work.

Rich

Oliver Schmidt

unread,
Jan 23, 2007, 7:14:31 PM1/23/07
to
Hi Michael,

>>> I didn't try to figure that out. When I knew I had to deal with it I
>>> just copied the whole page.

>> Most clock cards used the input buffer ($200) to pass their
>> results to BASIC. The most space that can be used depends on
>> the format of the time/date information returned, which is
>> usually selectable by the user.
>>
>> In no case does it exceed $2FF, since ProDOS uses $280..$2FF
>> as a pathname buffer (another possible issue).
>
>Whoops, that first $2FF was supposed to be $27F. ;-)

I was just looking at my code and say that actually didn't copy the
whole page as I stated above but only the first half for the same
reason you pointed out above ;-)

Best, Oliver

0 new messages