why wont this routine work.. works fine in 64 mode..

Started by stiggity, July 12, 2010, 07:25 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

stiggity

 *=$1300
start jsr getstr
ldy #0
sty starty
start1 ldy starty
cpy uplen
bcs startd
lda ($fd),y
jsr $ffd2
inc starty
jmp start1

startd rts

GETSTR LDA $2f
STA $BB
LDA $30
STA $BC
OO LDY #$00
LDA ($BB),Y
CMP #65
BNE OO2
INY
LDA ($BB),Y
CMP #128
BEQ OO3
OO2 CLC
LDA $BB
ADC #$07
STA $BB
LDA $BC
ADC #$00
STA $BC
JMP OO
OO3 INY
LDA ($BB),Y
STA UPLEN
INY
LDA ($BB),Y
STA $FD
INY
LDA ($BB),Y
STA $FE
STA $BC
RTS

starty .byte 0
uplen .byte 0


***All i want to do is print the contents of a$ to the screen.. works fine in 64mode when pointers are changed. I do have the 128 PRM, but something aint right.. any help woul dbe greatly appreciated..

-Steve Bell

LokalHorst

It's because in C128-mode all variables are stored in RAM1 aka Bank1, whilst your code accesses RAM0 where the (basic)program is stored.
A solution other than "PRINT A$" :) would be to extend the common area from 1k to 8k ($0000 to $1fff) and switch to RAM1 before accessing the variable(s).

stiggity

lokalhorst:
To switch to RAM1 would i just execite a "BANK 1" in basic?

LokalHorst

Close, but without extending the common area your routine would crash (it's located in RAM0 outside of the common area)
You could store your code snippet to RAM1 otherwise, but you'll need to set the variable start addr. above, say $1400 then. (the first option is simplier)

stiggity

lokalhorst:
I am a 100% beginner when it comes to understanding something foreign. How would I extend the common area from 1k to 8k ($0000 to $1fff) ? Even tho i have the 128 PRM, reading it is like trying to
learn a different language..

LokalHorst

#5
lets try:
;assuming that I/O is enabled on entry (BANK15)
*=$1300
lda $D506 ;ram config reg.
pha    ;remember orig. value
and #$fc
ora #$02  ;modify common size only
sta $d506
lda #$4e ;new config ram1+kernal+i/o
sta $ff00
;your prev code
start jsr getstr
...
;up to
startd:
pla
sta $d506
lda #$00
sta $ff00
rts

Edit: the end sequence won't work that way (was to fast hacked) -
change to:
lda #$00
sta $ff00
pla
sta $d506
rts

       +-----------------------------------------------------+
       |             RAM Configuration Register $D506        |
       +------+----------------------------------------------+
       | Bits | Function                                     |
       +------+----------------------------------------------+
       | 7--6 | Video RAM bank (0--3)                        |
       | 5--4 | RAM block (0--3)                             |
       | 3--2 | Common RAM selection                         |
       |      |  00  Common RAM block disabled               |
       |      |  01  Common RAM at bottom of memory          |
       |      |  10  Common RAM at top of memory             |
       |      |  11  Common RAM block at both top and bottom |
       | 1--0 | Size of Common RAM block                     |
       |      |  00  1 kB                                    |
       |      |  01  4 kB                                    |
       |      |  10  8 kB                                    |
       |      |  11  16 kB                                   |
       +------+----------------------------------------------+


(corrected again)

BigDumbDinosaur

Another individual who needs to read Mapping the Commodore 128.
x86?  We ain't got no x86.  We don't need no stinking x86!

stiggity

big dumb..
Im working on getting my hands on that book. Already have the 128 PRM, but like i was saying to lokalhorst (who's a nice person) , its hard to understand something as different as the 128, versus the 64. Lots of similarities, but lots to learn.

lokalhorst:
It didnt work, it gave me the same error i was getting before i added your code. Maybe shoot me an email, and ill attach the source. thank you, and once i learn this string-out routine, the more im going to
want to work on.

stiggity99(AT)comcast.net

LokalHorst

#8
seems to be more complicated as initially thought - I made another (logic) error - as strings are stored from the top of the memory downwards, they are overlayed with kernal+i/o in my above version.
the change would be config to ram1 ($7f) for locating (getstr) and then switch kernal in before each output ($ffd2).
I have to think over a better method.

LokalHorst

#9
Now here is the working approach -
do away with (in this case) bad idea fiddling with the common area and use the 'official' kernal INDFET routine (see fetch1).
Using a straight modification of the original code snippet -> where ever LDA ($BB),Y was used before, now the subroutine fetch1 is called. The labels are the same as with the OP.

; call with bank index 15
* = $1300
getstr LDA $2F
STA $BB
LDA $30
STA $BC

OO LDY #$00
JSR fetch1
CMP #$41
BNE OO2
INY
JSR fetch1
CMP #$80
BEQ OO3

OO2 CLC
LDA $BB
ADC #$07
STA $BB
LDA $BC
ADC #$00
STA $BC
JMP OO

OO3 INY
JSR fetch1
STA start1 + 1 ;strlen
INY
JSR fetch1 ;strptr lo
PHA
INY
JSR fetch1 ;strptr hi
STA $BC
PLA
STA $BB

start LDY #$00

start1 CPY #$FF ;selfmod value
BCS startd
JSR fetch1
JSR $FFD2
INY
bne start1
startd RTS

fetch1 LDA #$BB ;ZP pointer to use
LDX #$01 ;bank index 1
JMP $FF74 ;kernal indfet -> ret. value in A, changes A & X reg.

Despite the orig. mem-fetching problem the routine locks up in an endless loop if A$ isn't defined (label OO to OO3) because of missing var-top checking.
I'm sure it can be 'pimped' more with the use of the basic-rom (var locate) routines (~ @ $7b0b).

bacon

Quote from: stiggity on July 13, 2010, 07:04 AM
Im working on getting my hands on that book.
Get it here.

Quote
Already have the 128 PRM, but like i was saying to lokalhorst (who's a nice person) , its hard to understand something as different as the 128, versus the 64. Lots of similarities, but lots to learn.
Get Compute's 128 Programmer's Guide. It's much easier to understand than the C128 PRG from Commodore, and has virtually all the same information.
Bacon
-------------------------------------------------------
Das rubbernecken Sichtseeren keepen das cotton-pickenen Hands in die Pockets muss; relaxen und watschen die Blinkenlichten.

stiggity

since i dont have 'Mapping the 128" i was wondering if anyone could cross reference these "c64" kernal routines, into there 128 equivalent? unless there is a kernal break down in the 128 PRM. thank You guys!!


RSTKEY = $FE56
NOREST = $FE72
RETURN1 = $FEBC
OLDCHK1 = $F21B
FINDFN = $F30F
DEVNUM = $F31F
NOFILE = $F701



BigDumbDinosaur

Those are all undocumented calls into the kernel ROM.  You'd have to study the information in Mapping the Commodore 128 to find equivalents.  You should be cautious about diving right into the kernel, because the internal functions may shift the memory map without warning and not restore it to its previous state.
x86?  We ain't got no x86.  We don't need no stinking x86!

bacon

If you look at my post above, and BigDumbDinosaur's post, you'll find that we both gave you links to Mapping the Commodore 128. I also gave you a link to Compute's 128 Programmer's Guide.

Jim Butterfield's articles The C128 - You Can Bank On It! (<-link) and The Commodore 128 - Banking On The Turns (<-link) are also great reading about the C128's banks and how to use them with machine language.

Now go read.
Bacon
-------------------------------------------------------
Das rubbernecken Sichtseeren keepen das cotton-pickenen Hands in die Pockets muss; relaxen und watschen die Blinkenlichten.

stiggity

Everyone:
I found Mapping the 128 in .pdf format, and also mapping the 64 (cross-reference). Altho there isnt much material on strings in ML.
 
     I have another question, that i have been working on, but wont work.. i have a main body of basic in memory for the duration of the program running. And i want to "link" modules onto the "end" of the main body of code. I know i have to setup my end of basic, and the starting address for each module, then load them in and link the module to the main body of code. Anyone have any idea's on how this can be done?? I successfully managed to pull it off on the 64, but like all of you are saying. the 128 is a different beast.. any help will be forever greatful..

-Steve

stiggity

here is my module loading routine.. it access the drive, with the correct filename, but nothing is loaded..

;module loading routine
modl JSR MODLO
JMP MODL1
MODLO LDA $2f
STA $BB
LDA $30
STA $BC
mo1 LDY #$00
jsr fetch1
CMP #$41
BNE MO2
INY
jsr fetch1
CMP #$80
BEQ MO3
MO2 CLC
LDA $BB
ADC #$07
STA $BB
LDA $BC
ADC #$00
STA $BC
JMP MO1
MO3 INY
jsr fetch1
STA MDLEN
INY
jsr fetch1
pha
INY
jsr fetch1
STA vrlow
pla
STA vrhi

LDA #$08
LDX #$08
LDY #$00
JSR $F738
LDA MDLEN
LDX VRlow
LDY VRhi
JSR $F731
RTS
MODL1 LDA #$00
LDX lob
LDY hib
JSR $F265
rts
MDLEN .byte 0
VRLOW .byte 0
VRHI .byte 0


LokalHorst

Hi Steve,
if you're using the code from my example (fetch1) it uses the same pointer ($bb,$bc) as the kernal uses for locating filenames, so you can omit the call to setnam ($ffbd).
I saw at least 2 errors in your new snippet.

MO3 INY
jsr fetch1
STA $B7 ;no need for an additional var. -> filenamelengh (see $FFBD)
INY
jsr fetch1
pha  ;this is the lo byte of the string ptr.
INY
jsr fetch1
STA $BC ;this is the hi byte
pla
STA $BB ;lo byte

LDA #$08
LDX #$08
LDY #$00
JSR $FFBA ;setlfs
;missing in your code, but important
LDA #$00 ;bank# where the data is put (load)
LDX #$01 ;bank# where the filename resides (a$)
JSR $FF68
RTS
MODL1 LDA #$00
LDX lob  ;if your module(s) are basic, then this has to be
LDY hib  ;current basic end ptr. -2 (from addr. $1210/$1211)
JSR $FFD5
JMP $4F4F ; was missing -> relink basic lines aka chaining

fetch1   LDA #$BB ;ZP pointer to use
   LDX #$01 ;bank index 1
   JMP $FF74 ;kernal indfet -> ret. value in A, changes A & X reg.

your add. vars. and the call to setnam are stripped.
(add some error checking after jsr$ffd5)

stiggity

Lokalhorst:

Here is what i dont understand..

LDX lob  ;if your module(s) are basic, then this has to be
LDY hib  ;current basic end ptr. -2 (from addr. $1210/$1211

i have some basic i wrote that checks current top of text pointer and then done some math, to set the beginning address of the modules... so far it loads the files, but u cannot list them, sorta like there not in memory. and yes, they are basic modules.. i hate foru to write my entire program, but i am getting the hang of it..

-Steve

LokalHorst

regarding the modul load-address - the last basic line is terminated with a zero byte (like every other basic line), but followed by 2 additional zero-bytes (end of prog marker) which will be the the first line-link-pointer of any attached basic file.
So the basic equivalent of the routine looks like this:
1000 Bank15:ad=(256*Peek(4625)+Peek(4624))-2:Rem the module load addr.
1010 Bload (a$),D0,U8,B0,P(ad):Sys 20303:Rem load & re-link jsr$4f4f

Not mentioned yet - for this way of merging additional code to the (current) end of a program, the basic line-numbers used inside the modules have to be higher than the line-numbers already in use by the main program.

stiggity

Lokal:
You are 1 smart man.. i have to hand it to ya!!! eheheheh that module loading routine works super!!!
If u havnt noticed, im trying to write my own bbs..
wait!! i thing i didnt try was too see if variables stay in memory.. lets see..

-Steve

stiggity

Lokal:
Im a little more familiar with programming on the 64, and it doesnt have an 80column screen. If i wanted to store something on the screen, like a clock that is driven from the IRQ, how would i go about  doing that?

-Steve

stiggity

Lokal,
Assuming im using bank15, my ML starts @ $1300 and right now goes as high as 1BFF. Where else can i store my machine language routines?? Is there a way to swap out basic, and store ML underneath? can i use $1300 to $3FFF? Im writing a BBS program, and it will  be hybrid, basic and assembly. I really enjoy the examples you have been sending me, and also appreciate the patience, and knowledge... hope to hear from you soon. btw, my email address is "stiggity99(at)comcast.net" incase these forum posts dont bother you. :)

-Steve

stiggity

Lokal:
Im now using "fetch1" alot. I know this grabs bytes, is there an equivalent that stores. Im trying to take a buffer, with a y index, and store _it_ into a$.

i wrote an input routine, and after i enter some data and press Return, i want to take that buffer's contents and store them in a$..

thanks for all the guidance! :)

LokalHorst

ugh, so many questions.
we need new topics to address them, or everyone else can't follow.
1. IRQ Clock on VDC -> possible but difficult (if concurrent access happens)
2. more ml space -> as you're using already the rs232 buffers ($0c00/$0d00) only one block in low mem remains $0b00-$0bff used during boot to hold the boot sector. More space by move the basic start up with graphic cmd for ex. (to $4000)
3. store to bank 1 -> kernal INDSTA $FF77
example:
;A holds the value to store
;a zeropage pointer needs to point to the desired addr.
;Y reg is used as index to above addr. (same as INDFET)
LDX #$BB ;ZP-Pointer to use (can be changed)
STX $02B9 ;modify INDSTA routine
LDX #$01 ;bank index 1
JSR $FF77 (or JMP $FF77 if used the same as fetch1)

^- emulates sta ($bb),y in bank1


stiggity

Lokal:
Sorry to be a real Pain.. but your help is much appreciated, but im very new to the 128.
im going to include my source for taking a buffer and storing it into "b$"

STROUT LDA $2f
STA $BB
LDA $30
STA $BC
STR1 LDY #$00
jsr fetch1
CMP #66
BNE STR2
INY
jsr fetch1
CMP #$80
BEQ STR3
STR2 CLC
LDA $BB
ADC #$07
STA $BB
LDA $BC
ADC #$00
STA $BC
JMP STR1
STR3 INY
LDA NY
jsr fet2
INY
LDA #<BUFFER0
jsr fet2  ; STA ($BB),Y
INY
LDA #>BUFFER0
jsr fet2  ; STA ($BB),Y
RTS

fet2 ldx #$bb
stx $02b9
ldx #$01
jmp $ff77

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

If u can point me in the right direction i would appreciate it greatly!!! :)

-Steve