How can i convert these subroutines?

Started by stiggity, December 14, 2010, 05:32 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

stiggity

Hello:
Much appreciation to "Wagner", as he helped me learn. Im running into a bind. From as far as i know, string in ML are handled different than the 64 handles them. I have a small snippet of code, and i would like to convert it to work on the 128. I appreciate anyone even _reading_ this, and i greatly appreciate a response. Here goes.. Please forgive me for the crudeness of these examples.. the program does a LDA#"i", jsr strfin im assuming its setting up i$, but im not too clear about variables on the 128..

strfin ldy  #$80
       sta  $45
       sty  $46
       lda  #$ff
       sta  $0d
       jmp  $b0e7
strstr ldy  #0
       sta  ($47),y
       iny
       lda  #<filename
       sta  ($47),y
       iny
       lda  #>filename
       sta  ($47),y
       rts
strget ldy  #2
x9 lda  ($47),y
sta  strpnt,y
dey
bpl  x9
rts


filename     .byte     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
strpnt = $50

if anyone can even understand this, and explain that would be great.
Thank You
Steve

Wagner

#1
A call to strfin on the 64, supposedly finds/creates the single letter string variable in the A-register, in this case I.  On return from strfin, zero-page pointer ($5f) points to the variable I$, and A and Y (also ($47)) point to the length information in I$.

Calling strstr stores the length of the string from A into I$'s length component, then stores a pointer to "filename" into I$'s pointer component, so that I$ is properly set up to point to "filename."

Assuming that ($47) still points to I$'s information, a call to strget retrieves the length and pointer from I$ and stores it into zero-page locations $50-$52 with the length in $50 and the pointer to "filename" in ($51).

I was partially successful in trying this on the 128, in that my computer didn't go into 64 mode on every attempt. ::)   The corresponding addresses have changed from $b0e7 to $7b0b, from ($45) to ($47), from ($47) to ($49), from $50-$52 to $52-$54, and from ($5f) to ($61), and I$ is now in RAM bank 1;  "filename" would also have to be in RAM bank 1.

stiggity

Wagner:
This is not the first time i have been utterly amazed by the knowledge of the users of this forum. You really "broke it down" and explained how each routine works. But, even with the changes you made, in your response.. every time i access this routine it doesnt work. Would there be  _any_ possibility if you could re-write the sub-routine in question, with the changes you have made. Of course, i have already, but its doing the same thing it did when i was playing with it hours ago. In strfin there is an op STY$46 in your documentation, you didnt re-assign a value to $46. I appreciate the help, and knowledge, Wagner.. and i hate to ask you to write it for me, but i have read your response numerous times, and something still isnt working.. ; (


stiggity

Wagner:
I forgot to mention something. When these strfin/strstr/strget are called within the whole module, it is in bank0, so im breaking to monitor trying to call the  $7b0b routine. I have 44blocks of ML in the $1300 - $3FFF routine, and this module in bank 0 starting at $9000. I am going to ask another question. How could i "swap" or "switch" memory out, to be able to access the $7B0B kernal-call, from within bank 0. thank you very much. This is the last routine that i holding me back.

-Steve

stiggity

Wagner:
While i was fooling around, i got 1/2 of my module working. I 100% re-wrote the strstr routine with some code i have been working with to handle variables in my main program. I just made strfin an RTS and switched strget's $47 to a $4A and i can now recieve files, but an still unable to send any. Here is all of the source i wrote, to replace the original.

strstr LDA $2f
STA $BB
LDA $30
STA $BC
STR1 LDY #$00
jsr fetch1
CMP #73
BNE STR2
INY
jsr fetch1
CMP #128
BEQ STR3
STR2 CLC
LDA $BB
ADC #$07
STA $BB
LDA $BC
ADC #$00
STA $BC
JMP STR1

STR3  INY
  jsr  fetch1   ;get length of i$
  pha    ;remember
  INY
  jsr  fetch1   ;get lo byte of str. ptr.
  STA  $FD   ;set up a second ZP-pointer
  INY
  jsr  fetch1   ;get hi byte of str. ptr.
  STA  $FE
  PLA
  TAY    ;now Y holds the leng
sty commy
ldy #0
looz cpy commy
bcs looend
lda filename,y
loo2 JSR  store1
iny
jmp looz
looend rts



fetch1 LDA  #$BB ;ZP pointer to use
LDX  #1 ;bank index 1
JMP  $FF74 ;kernal

store1  ldx  #$FD ; use pointer $FD/$FE
  stx  $02b9
  ldx  #$01
  jmp $ff77 ;INDSTA

Wagner

#5
QuoteHow could i "swap" or "switch" memory out, to be able to access the $7B0B kernal-call, from within bank 0.

Very carefully.  The following code resides in the same places as your ML modules.  A jump routine at $1300, and another routine at $9000.  The routine at $1300 reconfigures the MMU register and jumps to $9000.  The routine at $9000 finds/creates the string variables A$ thru Z$, and exits.

1300 LDA #$0E
     STA $FF00
     JMP $9000
.
.
.
9000 LDA #$41        ;the letter 'a'
9002 PHA
     JSR $901C       ;call strfin
     LDA #$00
     STA $A2         ;setup a timer
     LDA #$02
900C INC $D020       ;flash the border
     BIT $A2
     BEQ $900C       ;continue flashing briefly
     PLA
     TAX
     INX
     TXA
     CMP #$5B        ;the letter 'z'+1
     BCC $9002
     RTS

901C LDY #$80
     STA $47
     STY $48
     LDA #$FF
     STA $0F
     LDA #14         ;BASIC BANK 14
     STA $02
     LDA #$7B        ;hi-byte of $7b0b
     STA $03
     LDA #$0B        ;lo-byte of $7b0b
     STA $04
     LDA $FF00       ;use current bank configuration
     STA $02DE       ;to modify jsrfar
     JSR $FF6E       ;call $7b0b
     LDA #$00
     STA $02DE       ;restore modified routine
     RTS


After calling this with SYS 4864, you can examine memory at $10400 thru $10500 to see the effect of creating the variables (assuming these are the only variables yet created).  My routine flashes the border in the routine just to have something to do.

stiggity

Wagner:
I am following your last example code, and the more i look at it the more i understand.
My jumptable in the $1300 area, calls the code at $9000 and then when the prg at $9000 is finished it exits to basic, where i perform a bank15 to be able to call other routines.

Im going to play with your source, and see what i can come up with.

Heres anohter Question...
Would you be willing to re-code my first set of subroutines to work from within the $9000 memory range. Sort of re-write them, and if u could comment, that would be great. I always have the best luck, learning from Example code. thank, Wagner.

-Steve

Wagner

QuoteWould you be willing to re-code my first set of subroutines to work from within the $9000 memory range. Sort of re-write them, and if u could comment, that would be great.

Here now...don't make me come over there! :)

Which subroutines?  STRSTR and STRGET?

stiggity

Wagner:
Yes i need help with STRSTR and STRGET... got more questions..

Wagner:
Sorry to hit you up with so many questions!! I prefer to ask, instead of going... uncertain. :)

Ive added your version of STRFIN and it doesnt BRK to the monitor, eehe but it's not working.......correct.
In my initial post, i entered STRFIN/STRSTR/STRGET.. to make those (3) sub-routines compatible in 128 mode, would i simply re-write the STRFIN routine, with the excellent example you previously posted? Or do i have to modify STRSTR and STRGET, btw.. what value should I assign too the label STRPNT. It was set to $50 in 64mode. If your STRFIN routine finds/creates a string, was it created in bank1? i guess ill have some more work to do in the STRSTR routine, for dumping the "filename" buffer, into the string created in BANK1? am i right?

stiggity

I didnt mean for you to 100% write the entire thing, but i seem to be a tad better ML dabbler, on the 64 -vs- the 128.
I do appreciate all the help, and explanations. Here are (2) more things, i am unclear on. Using the same source in 64mode, there are 2 labels that are giving me fits, trying to convert to a 128 memory map address.

$64
$50

What are the ZP equivalents on the 128?

_Wagner_
Seems out days//timezones are waaaay off, hope to get a reply from you tomorrow morning/afternoon. Thanks Alot!!! :)

8)

Wagner

#10
So is what you are trying to do with these three subroutines related to reading a directory, from ML, into a DIMensionsed string array?

QuoteWhat are the ZP equivalents on the 128?

There's a nice appendix in "Mapping the Commodore 128" by Ottis R. Cowper, generously for free download from http://www.bombjack.org/commodore/books-commodore128.htm  that shows the C64 and C128 zero-page equivalents.  Address $50 on the 64 is the same as $52 on the C128.  Likewise $64 is equivalent to $66 on the C128.

QuoteI didnt mean for you to 100% write the entire thing,

Maybe I'll have to start charging you. ;)

QuoteMy jumptable in the $1300 area, calls the code at $9000 and then when the prg at $9000 is finished it exits to basic, where i perform a bank15 to be able to call other routines.

You should be able to get away with one BANK 15 at the beginning of your code, unless you're using the BANK command elsewhere in your BASIC code.  Changing the MMU configuration after SYSing to ML doesn't change the previous BANK command.  You can try this yourself.  When your program returns to BASIC after an SYS, do a PRINT PEEK(981), it should be the same as before the SYS.

stiggity

Wagner:
Thanks for the reply. Im still running into problems, as im assuming STRSTR needs re-written, and same with STRGET.. if you want to start charging me, i do have a paypal account. :)

-Steve

stiggity

Wagner:
Im serious about sending you some cash.. not that im loaded, but good help is hard to find. And there are alot of examples of assembly source code for the 64, but not alot for the 128. If you could help me with the STRSTR routine, and maybe STRGET or we could work on 1 each day.
thanks alot.
btw. where are you located? I live in Pennsylvania, USA.. cold and snowy here..

-Regards,
-Steve Bell

stiggity

Wagner:

>>So is what you are trying to do with these three subroutines related to reading a directory, from ML, into a DIMensionsed string array?

No, im writing a file transfer protocol...

Ive already got xmodem/xmodemCRC working both ways, and regular flavored "Punter". This will be the final protocol, and it will send the file data, and receive the file data, but the filenames are getting screwed-up, and that is where STRFIN/STRSTR/STRGET come in. It was basically easy to get variables working on the 64, but on the 128 there all stored in bank1, and there are many more kernal calls, etc. Hate to hound you, but if you can help with the STRSTR and STRGET I would be forever in your debt. :)

-Steve

Wagner

#14
So here's what I've come up with.

;a.str

fretop = $35      ;BASIC variables
frespc = $37
varnam = $47
varpnt = $49
strpnt = $52
length = $63

jsrfar = $2cd
newfar = $2a2-22
filename = $1380  ;any place in ram 0

ptrget = $7b0b    ;BASIC subroutines
strlit = $869a

indfet = $ff74    ;kernal jumps
indsta = $ff77



   org $9000

strsub1
   pha
   jsr dupfar     ;dup and mod jsrfar
   pla
   jsr strfin     ;find/create $ in A
   jmp strstr     ;make $ point to var

strsub2
   pha
   jsr dupfar
   pla
   jsr strfin
   jmp strget


dupfar
   ldy #21
g8 lda jsrfar,y
   sta newfar,y
   dey
   bpl g8
   lda $ff00      ;modify to return to
   sta newfar+17  ;calling bank
   rts



strfin
   ldy #$80       ;$ var type
   sta varnam
   sty varnam+1
   lda #$ff       ;flag for type $
   sta $f
   lda #14        ;BASIC bank 14
   sta 2
   lda #>ptrget
   sta 3
   lda #<ptrget
   sta 4
   jmp newfar     ;call ptrget at $7b0b



strstr
   lda #14
   sta 2
   lda #>strlit
   sta 3
   lda #<strlit
   sta 4
   lda #<filename ;address of our $
   sta 6          ;to be allotted/copied
   lda #>filename
   sta 8
   jsr newfar     ;call strlit at $869a
   dec $18        ;calling from ML,
   dec $18        ;so undo $,
   dec $18        ;descriptor stack

   lda #varpnt    ;address of varpnt
   sta $2b9
   ldx #1         ;mmu bank 1 ram
   ldy #0
   lda length     ;$ length
   jsr indsta
   ldx #1
   iny
   lda fretop     ;make our variable
   jsr indsta     ;point to copied $
   ldx #1
   iny
   lda fretop+1
   jsr indsta

   lda #frespc    ;freespc address which
   sta $2b9       ;points to copied $
   ldx #1
   ldy #0
   lda varpnt     ;make $ point back to
   jsr indsta     ;our variable (for
   ldx #1         ;garbage collection
   iny            ;purposes)
   lda varpnt+1
   jmp indsta



strget
   ldy #2
g0 ldx #1
   lda #varpnt
   jsr indfet
   sta strpnt,y
   dey
   bpl g0
   rts


I've parameterized the first routine (I suppose I should have given it a name) so that you could make a call such as SYS 4864, ASC("I") or whatever variable.  If that's not what you want, do what you want with it.  If you like the ASC("I") part, then you would need to modify your jump table at $1300 to preserve the A register.  Perhaps LDY #$0E  STY $FF00  JMP $9000 instead.

I thought maybe modifying JSRFAR directly wasn't such a good idea--if BASIC runs into problems, JSRFAR would probably cause a system crash.  So I duplicated it to the end of the BASIC input buffer and modified it there.

If my code raises more questions than answers I'll be happy to explain as best I can.  If the code isn't what you're looking for, I can try something else.  PM me your address and I can email the petscii text.

stiggity

Wagner:
WOW!!
I converted your response, to metapad format, but you can still send me the equivalent.

Here is a few questions..

You have plainly re-created STRFIN/STRSTR/STRGET , beautiful!!

my protocol calls each of these routines in this manner.

  lda  #"i"
  jsr  strfin
  jsr  strget
  lda  strpnt   ;there is 1 of the 3 calls. call # 1

call # 2

  lda #"i"
  jsr  strfin


call # 3

pha
  jsr  strstr
  pla

using your code, it looks like i have to setup a few things. What would i have to _add_ too each of the 3 calls to basically duplicate the original calls..?


Wagner

#16
Quoteusing your code, it looks like i have to setup a few things.

I added two labels to the above code that I should have put in but didn't.  I thought it might have been more obvious.  The labels I added are strsub1 and strsub2.  Call strsub1 instead of strfin directly.  Strsub1 does some setup before calling strfin and strstr.  Same goes for strsub2--it does some housekeeping, then calls strget.

I don't know how ML fluent you are.  I was kind of assuming you would be able to glean what you needed, or even modify, what I wrote to suit your purpose.

In your code where you say...

   lda #"i"
   jsr strfin
   jsr strget


you should be able to substitute jsr strsub2 instead of the two calls to strfin and strget since strsub2 does both.

I also notice in your code that the second call to strfin...

   lda #"i"
   jsr strfin


occurs some distance before the jsr strstr.  Can the second call to strfin be moved more directly in front of strstr?  Then instead of calling strfin and strstr, just call strsub1, with the accumulator containing #"i" of course.

stiggity

Wagner:
Yeah i tried just about everything, and do , somewhat, understand your code. One thing i didnt try was to remove a few calls here and there, and try too simplify the whole process... we'll see..


stiggity

Wagner:
Yeah im okay at ML, and i usually understand what im looking at. I have been at these routines for 3 days now, and nothing is working. Maybe you can come-up with something with the source i sent you. eh? trying to boggle your example code, into this module isnt working for me. It does nothing.... im sure its accurate, and correct, but there is something im missing...maybe its inexperience..

-Steve

stiggity

Wagner:
I think the problem is this.... I'm in deep with this conversion. If you looked at the protocol source i sent, i think i dont fully understand it, and/or the example source u sent me. I had already been using your STRSUB1 and STRSUB2 routines, altho the code im working with somehow doesnt function with what you entered. I know this is a long-shot, but i hope you take a glance at the source,. and possibly squeeze your routines in there... im still messing with it tho.. im not a quitter.

-Steve

Wagner

So what exactly is happening?  Breaking to the monitor?  Complete lockup?

I don't know if this is the problem, but it could be one problem.  The filename needs to be zero-terminated so that BASIC can find the end of it.  So when your routine finds the CR, you also should zero-terminate filename.

stiggity

Wagner:
What is happening is, when i perform the SYS to the $9000 area, the protocol should take the contents of i$, and send it over the modem to the terminal recieving. The module should wait till the users terminal sends a desired character (not sure which one), and then the file transmission take place. (this works fine). It doesnt lockup, it doesnt break to the monitor either. I have 2 rigs setup running vista/vice 1.16 (patched for TCPSER), and TCPSER. Im doing all of my testing in VICE. As this protocol works 100% in 64mode, with all bytes pointing to the corresponding c64 memory address.

When you say the filename needs to be zero terminated, right now i just have filename     .byte     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  (i dont exactly know what you mean by terminated. If i changed this to an actual memory address like    "filename = $9E00" could that help?

I really appreciate the help. Sometimes its almost as if im the only assembly/basic programmer left on the planet. check your mail, as i send an original source listing, and the one modified with your routines. Maybe if you look it over, you could discover conflict, i have been overlooking.

stiggity

Wagner:
If i would call STRFIN to setup i$ , then LDA length, then jst STRSTR would that help? I was looking over some 64 ml, trying to revisit that, and maybe help with this new 128 ml..

stiggity

Jon:
Well, after playing with you routines for a good day or so, i managed to implement the STRFIN/STRSTR routines. And they work! :)
Now im wondering if there would be anyway to take the contents of i$ and store it in filename? Not sure i need this routine, but i cannot
get the SEND aspect of the protocol working. Kinda waiting too see if you glance at the source i sent you.

-Steve

stiggity

this routine, i have some questions..

prot1e   ldy  #0
jb5  lda  (strpnt+1),y
         jsr  chrout
         ldx  nova
         bne  jb6
  STA  buffer,Y
jb6  iny
  cpy  strpnt
         bcc  jb5


why would it be loading strpnt+1, when strpnt is already hard coded to $52
does it take the contents of i$, and store it into BUFFER??