Commodore 64 (C64) Forum Index
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
Cannot get ASM program to save mem to disk

 
Post new topic   Reply to topic    Commodore 64 (C64) Forum Index -> Scene
View previous topic :: View next topic  
Author Message
Thraka
Newbie


Joined: 01 Jan 2007
Age: 32
Posts: 35
Location: Washington State

PostPosted: Fri Jun 22, 2012 7:34 pm    Post subject: Cannot get ASM program to save mem to disk Reply with quote

Spinning my head here. I'm newish to all this ASM stuff. I've had weird results in trying to get this to work and I cannot figure out why it isn't. It doesn't create a file on the disk at all. Anyone be able to help?

Everything works except the actual SAVE so something has to be wrong with that, SETLFS or SETNAM...

READST does put 40 in the accumulator. I looked it up but I really didn't know what the flags it had, meant.

Code:

; =====================================
; == Kernal routines
; =====================================

KERNAL_SETNAM = $FFBD
KERNAL_SETLFS = $FFBA
KERNAL_CHROUT = $FFD2
KERNAL_PLOT = $FFF0
KERNAL_SAVE = $FFD8
KERNAL_LOAD = $FFD5
KERNAL_READST = $FFB7

;basic boot strap
.include Launcher.asm

* = $1000
; =====================================
; == Variables
; =====================================
ADDR_SCREEN = $0400

; =====================================
; == Program
; =====================================
__start

   ; Clear the screen
   jsr Clr

   ; Print the disk prompt string, wait for key press, and then notify them it's loading
   lda #>data_sDiskPrompt
   pha
   lda #<data_sDiskPrompt
   pha
   jsr PrintStr

   jsr KeyPress ;Watch key buffer for keypress
   jsr NewLine  ;print a new line char


   ; Print the msg that we're loading info
   lda #>data_sLoading
   pha
   lda #<data_sLoading
   pha
   jsr PrintStr

   ;
   lda #1      ;File number
   ldx #8      ;Device Number
   ldy #0      ;Secondary address: 0 = start of basic free mem; 1 = original mem location
   jsr KERNAL_SETLFS

   lda data_fileNameEnd - data_fileName ;length of file name
   ldx #<data_fileName ;lo byte of file name
   ldy #>data_fileName ;hi byte of file name
   jsr KERNAL_SETNAM

   jsr save_routine
   jsr print_data
   jmp exit

save_routine
   ;Save string to file
   lda #<data_TestData
   sta $FB
   lda #>data_TestData
   sta $FC
   lda #$FB
   ldx #<data_TestDataEnd
   ldy #>data_TestDataEnd
   clc
   jsr KERNAL_SAVE
   bcs error
   rts

load_routine
   lda #0
   ldx #<data_TestData
   ldy #>data_TestData
   jsr KERNAL_LOAD
   rts

print_data
   lda #>data_TestData
   pha
   lda #<data_TestData
   pha
   jsr PrintStr
   rts

error
   jsr KERNAL_READST
   rts


exit
   rts


; =====================================
; == Data
; =====================================

data_sDiskPrompt   .null 'PLEASE INSERT DISK TO BE CLEARED...'
data_sLoading      .null 'LOADING NOW...'
data_fileName      .text 'FILE.345'
data_fileNameEnd

data_TestData      .null 'FIRST STRING IS PRINTED HERE. PLEASE HA'
data_TestDataEnd

.include Misc.asm
.include String.asm
Back to top
View user's profile Send private message
malcontent
C64 Enthusiast
C64 Enthusiast


Joined: 25 Feb 2010
Age: 29
Posts: 773
Location: :noitacoL

PostPosted: Fri Jun 22, 2012 7:57 pm    Post subject: Reply with quote

IIRC to save to disk you must prefix the string of filename with zero and colon "0:filename"

Also you must open and read channel channel 15 to check for disk errors. Save will not return with carry set for disk errors I don't think, just tape errors.

This is from one of compute's assembly routine books:

Before load open 15:

Code:
lda #15      ;open the error channel
tay
ldx #8
jsr SETLFS
lda #0
jsr SETNAM
jsr OPEN


Then after jsr SAVE, jsr to this routine which reads the binary coded decimal that the error channel spits out.

Code:
ldx #15
jsr CHKIN
jsr CHRIN
asl
asl
asl
asl
sta error
jsr CHRIN
and #%00001111
ora error
sta error
cmp #$20
rts


It returns with the carry set on an error.
Don't forget to close everything up after you're done.

Code:
lda #15
jsr CLOSE
jsr CLRCHN


Here's a list of errors you can get:
http://unusedino.de/ec64/techn...rormai.htm
_________________
Back to top
View user's profile Send private message Visit poster's website
Thraka
Newbie


Joined: 01 Jan 2007
Age: 32
Posts: 35
Location: Washington State

PostPosted: Fri Jun 22, 2012 9:13 pm    Post subject: Reply with quote

Thanks for the info.

I found this example online: http://codebase64.org/doku.php...ing_a_file

This code works if I run it, and while it's slightly different than mine, I cannot see what would make mine not work. I'm using a D64 created by VICE, so there shouldn't be any disk errors. And the fact that it works under that code but not mine is odd... I guess i'll just have to keep plugging away. Sad
Back to top
View user's profile Send private message
malcontent
C64 Enthusiast
C64 Enthusiast


Joined: 25 Feb 2010
Age: 29
Posts: 773
Location: :noitacoL

PostPosted: Fri Jun 22, 2012 10:20 pm    Post subject: Reply with quote

I can't really see what's wrong, unless you've got a custom IRQ going, or you are screwing with the stack in the string printing routines.
_________________
Back to top
View user's profile Send private message Visit poster's website
Thraka
Newbie


Joined: 01 Jan 2007
Age: 32
Posts: 35
Location: Washington State

PostPosted: Fri Jun 22, 2012 10:25 pm    Post subject: Reply with quote

I am playing with the stack for the string routines. But I believe I'm restoring the stack properly because the code path does return correctly after each call.

Code:

STR_LO =         $FB
STR_HI =         $FC

; ====== Print String ==
; == Prints a string at the current cursor position
; == The high-byte of the string pointer should be pushed to the stack first, followed by the low-byte
; ======================

PrintStr                .proc
                  ; Need to pull the JSR return address first then the string data
                  pla
                  sta jsr_data
                  pla
                  sta jsr_data+1

                  ; Then pull the string and store it in <$08 and >$09
                  pla
                  sta STR_LO
                  pla
                  sta STR_HI
                  ldy #0
loop
                  lda (STR_LO),y
                  cmp #0
                  beq end
                  iny
                  jsr KERNAL_CHROUT
                  jmp loop
end
                  ; Restore the JSR value
                  lda jsr_data+1
                  pha
                  lda jsr_data
                  pha
                  rts
jsr_data            .byte 0, 0
                  .pend
Back to top
View user's profile Send private message
buzbard
Groupie
Groupie


Joined: 22 Sep 2010
Age: 49
Posts: 219
Location: Washington State

PostPosted: Fri Jun 22, 2012 11:16 pm    Post subject: Reply with quote

There's a routine in the BASIC rom at $AB1E to print a string.
Just load .A & .Y with the low & high bytes of then first address of your string, clear the carry flag then call the routine, your string has to end with a zero byte.
Code:
STROUT = $AB1E

LDA #<msg_text
LDY #>msg_text
CLC
JSR STROUT

...
...
msg_text BYTE "my message", $00


If you're just trying to save a string to a file then try something like this:
Code:
FA = $ba ;current dvice number
SETLFS    = $ffba ;set logical file parameters
SETNAM   = $ffbd ;set filename parameters
OPEN       = $ffc0 ;open a logical file
CLOSE     = $ffc3 ;close a logical file (.A=file#)
CHKOUT   = $ffc9 ;define an output channel (.X=file#)
CHROUT   = $ffd2 ;Output a character (.A)

        lda data_fileNameEnd - data_fileName ;length of file name
        ldx #<data_fileName ;lo byte of file name
        ldy #>data_fileName ;hi byte of file name
        jsr SETNAM      ;Set the filename

        lda #$02
        ldx FA
        bne skip
        ldx #$08
skip
        tay
        jsr SETLFS      ;Set filesystem parameters

        jsr OPEN        ;OPEN2,8,2,"filename"

        ldx #$02
        jsr CHKOUT      ;CMD2

        ...
        ;use CHROUT here in a loop to send individual bytes to the file
        ...

        lda #$02
        jsr CLOSE       ;Close the file
        ldx #$00
        jsr CHKOUT      ;Restore default output


I just typed the above into the reply box, I haven't tested it, so error may exist.
Oh, and add a ",P,W" to the end of the filename.
Code:
data_fileName      .text 'FILE.345,P,W'


P is for PRG and W is for Write.
_________________
Ray...
------------------------------------------------------------------------------------------------------------
It's OK if you don't agree with me, I can't force you to be right.
Back to top
View user's profile Send private message
Thraka
Newbie


Joined: 01 Jan 2007
Age: 32
Posts: 35
Location: Washington State

PostPosted: Sat Jun 23, 2012 8:35 pm    Post subject: Reply with quote

Thanks ray. I didn't know about the string routine, but it was more of a learning exercise for me Smile

Thanks for the file code. It still puzzles me what is wrong with mine though. Originally I had thought of using the CHROUT, but then saw the SAVE routine which was much more compact and to the point. It still puzzles me why it is not working though.

Thanks again!
Back to top
View user's profile Send private message
buzbard
Groupie
Groupie


Joined: 22 Sep 2010
Age: 49
Posts: 219
Location: Washington State

PostPosted: Sun Jun 24, 2012 12:37 am    Post subject: Reply with quote

Well, if you think about it in BASIC, you use "SAVE" to save a program to disk, and you use the "OPEN" command to save data such as text to a file.
Since you don't have a BASIC program in memory, nothing is saved.
_________________
Ray...
------------------------------------------------------------------------------------------------------------
It's OK if you don't agree with me, I can't force you to be right.
Back to top
View user's profile Send private message
Thraka
Newbie


Joined: 01 Jan 2007
Age: 32
Posts: 35
Location: Washington State

PostPosted: Mon Jun 25, 2012 7:46 pm    Post subject: Reply with quote

Hrm, that doesn't seem to be what the explanations for the SAVE routine state. They specify that you set the range of memory you wish to save, not just automatically saving BASIC memory.
Back to top
View user's profile Send private message
Lee73
Newbie


Joined: 15 Mar 2010
Age: 39
Posts: 42
Location: Canada

PostPosted: Wed Jun 27, 2012 3:35 am    Post subject: Reply with quote

Thraka wrote:
It still puzzles me what is wrong with mine though.

Could this be the culprit?
Code:
lda data_fileNameEnd - data_fileName ;length of file name
   ldx #<data_fileName ;lo byte of file name
   ldy #>data_fileName ;hi byte of file name
   jsr KERNAL_SETNAM

Notice you aren't using # for the size of the file name. You actually are fetching from a specific memory location. In this case, unfortunately, that number is from location 8 - which is usually zero - meaning you are not specifying a filename. No save.

Also, shouldn't the SETLFS stuff be "File#,Device#,1" so it honors the specified memory range you want to save?
Back to top
View user's profile Send private message
spider-j
Über Groupie
Über Groupie


Joined: 12 Jun 2012
Posts: 310
Location: Wuppertal, FRG

PostPosted: Wed Jun 27, 2012 8:08 am    Post subject: Reply with quote

Lee73 wrote:
Notice you aren't using # for the size of the file name. You actually are fetching from a specific memory location. In this case, unfortunately, that number is from location 8 - which is usually zero - meaning you are not specifying a filename. No save.

You're right. The # is missing.

Although I don't see why you think it's from location 8? The code starts at $1000, the data field is behind the code and there you find the label data_fileNameEnd

In this case I think the 'F' of "FIRST STRING..." is loaded into accu.


EDIT: this was wrong.


Last edited by spider-j on Wed Jun 27, 2012 9:10 am; edited 1 time in total
Back to top
View user's profile Send private message
mrsid
C64 Enthusiast
C64 Enthusiast


Joined: 27 Jan 2003
Age: 38
Posts: 802
Location: Netherlands

PostPosted: Wed Jun 27, 2012 8:31 am    Post subject: Reply with quote

It loads from the address (data_fileNameEnd - data_fileName) which is $08.
Back to top
View user's profile Send private message
Mogwai
Über Groupie
Über Groupie


Joined: 20 Oct 2011
Age: 48
Posts: 342
Location: Netherlands

PostPosted: Wed Jun 27, 2012 8:32 am    Post subject: Reply with quote

No, the accu is loaded from the memory location pointed to by the result of (data_fileNameEnd - data_fileName), and that is 8.

data_fileName .text 'FILE.345'
data_fileNameEnd

So, depending on the assembler it will be converted to lda $08, or lda $0008.
What you wanted it to be is lda#$08.
Back to top
View user's profile Send private message
spider-j
Über Groupie
Über Groupie


Joined: 12 Jun 2012
Posts: 310
Location: Wuppertal, FRG

PostPosted: Wed Jun 27, 2012 8:47 am    Post subject: Reply with quote

Oh, my mistake. Didn't see that minus stuff. Sorry! Embarassed
Back to top
View user's profile Send private message
Thraka
Newbie


Joined: 01 Jan 2007
Age: 32
Posts: 35
Location: Washington State

PostPosted: Wed Jun 27, 2012 11:25 pm    Post subject: Reply with quote

Yep you guys nailed it. Thanks so much. I totally figured it was something like this and my eyes were just tricking me. Thanks again!!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Commodore 64 (C64) Forum Index -> Scene All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Tip: Get C64 Forever for super-comfy C64 emulation with pre-installed games, demos and other goodies!


Powered by phpBB © 2001, 2005 phpBB Group