Writing a disk file using assembly on Commodore 64
Asked Answered
C

2

8

I'm trying to learn how to write disk files using kernal routines following this Codebase64 Tutorial.

I have copied my routine, written in Acme Crossassembler, below. It failed to open file and gives error message: "FILE NOT OPENED"

; Definitions
SETNAM = $FFBD
SETFLS = $FFBA
OPEN   = $FFC0
CHKOUT = $FFC9
READST = $FFB7
CLOSE  = $FFC3
CLRCHN = $FFCC
CHROUT = $ffd2      

;Basic Start
    * = $0801                               ; BASIC start address (#2049)
    !byte $0d,$08,$dc,$07,$9e,$20,$34,$39   ; BASIC loader to start at     $c000...
    !byte $31,$35,$32,$00,$00,$00           ; puts BASIC line 2012 SYS 49152

;Program Code
    * = $c000                               ; Can be executed by writing sys 49152

    ldx #<message0         
    ldy #>message0   
    jsr printMessage    


save2file:      
    ; call SETNAM   
    lda #fname_end-fname    ; file name size
    ldx #<fname             ; file name vector
    ldy #>fname             ; file name vector
    jsr SETNAM              ; call SETNAM

    ; call SETFLS
    lda #$00
    ldx $BA                 ; last used device number
    bne +
        ldx #$08            ; default to device 8
+   ldy #$00
    jsr SETFLS              ; call SETLFS

    ;call OPEN
    jsr OPEN                ; call OPEN
    bcs .error1             ; if carry set, the file could not be opened

    ; call CHKOUT
    ldx #$02                ; filenumber=2
    jsr CHKOUT              ; file 2 now used as output

    ; Copy border color to the file
    jsr READST              ; call READST (read status byte)
    bne .error2             ; write error
    lda $d020               ; get byte from memory
    jsr CHROUT              ; write to file

    ldx #<message1         
    ldy #>message1     
    jsr printMessage

.close
    lda #$02      ; filenumber 2
    jsr CLOSE     ; call CLOSE
    jsr CLRCHN    ; call CLRCHN
    rts

.error1
    ldx #<errorMsg1         
    ldy #>errorMsg1   
    jsr printMessage
    jmp .close

.error2
    ldx #<errorMsg2         
    ldy #>errorMsg2   
    jsr printMessage    
    jmp .close        

fname:  !tx "DATA,S,W"
fname_end:

message0:   !by 141 : !scr"SAVING" : !by 0
message1:   !by 141 : !scr"COLORS SAVED" : !by 0
errorMsg1:  !by 141 : !scr"FILE NOT OPENED" : !by 0
errorMsg2:  !by 17 : !scr"WRITE ERROR" : !by 0

;==========================================================================
; printMessage
;   Prints null terminated string to the memory
;   Input: x,y adress vector of text string 
;==========================================================================
temp     = $fb          ;zero page pointer

printMessage:   
    stx temp            ;save string pointer LSB
    sty temp+1          ;save string pointer MSB
    ldy #0              ;starting string index

-   lda (temp),y        ;get a character
    beq +               ;end of string
        jsr CHROUT      ;print character
        iny             ;next
        bne -
    inc temp+1             
    bne -       
+ rts               

I've prepared the Basic Routine listed below using C64 Programmer's Reference. It works as expected in the very same environment.

10 OPEN 3,8,3, "O:DATA FILE,S,W"
20 PRINT#3, "SENT TO DISK"
30 CLOSE 3      

So, why my asm routine doesn't work?

I'm testing on Vice 2.4

Cristionna answered 11/4, 2017 at 21:6 Comment(3)
BASIC routines are very different to assembler, but saying one language works and the other doesnt is not very useful! Have you debugged the code?Arrival
Your BASIC command is opening file 3 on data channel 3 (3,8,3) but your ASM is trying to access file zero (lda #$00) on data channel 0 (ldy #$00), which is invalid as a secondary address number for device 8 (disk).Gloomy
@Gloomy I've changed the numbers and it worked.Cristionna
C
6

Apperently the problem was in Logical number and secondary adress as indicated by J...

I have fixed it by changing parts .i.e:

    ; call SETFLS
    lda #$03
    ldx $BA                 ; last used device number
    bne +
        ldx #$08            ; default to device 8
+   ldy #$03
    jsr SETFLS              ; call SETLFS

...

    ; call CHKOUT
    ldx #$03                ; filenumber=3
    jsr CHKOUT             ; file 2 now used as output

...

.close
    lda #$03      ; filenumber 3
    jsr CLOSE     ; call CLOSE
    jsr CLRCHN    ; call CLRCHN
    rts

There are other issues like "COLORS SAVED" message got sent to the file instead of screen, but those can be fixed easily.

Cristionna answered 11/4, 2017 at 21:54 Comment(0)
M
1

I know this is an old thread, but simply calling jsr close then rts from each of the error routines would make it print the error to the screen no? that way you close the file/etc before outputting text.

Misguidance answered 19/7, 2021 at 15:21 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.