Запись файла на диск с помощью сборки на Commodore 64

Я пытаюсь научиться записывать файлы на диск с помощью подпрограмм ядра, следуя этому Codebase64. Учебник.

Ниже я скопировал свою процедуру, написанную на Acme Crossassembler. Не удалось открыть файл и выдает сообщение об ошибке: "ФАЙЛ НЕ ОТКРЫТ"

; 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               

Я подготовил базовую процедуру, указанную ниже, используя Справочник программиста C64. Он работает, как и ожидалось, в той же самой среде.

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

Итак, почему моя процедура asm не работает?

Тестирую на Vice 2.4


person wizofwor    schedule 11.04.2017    source источник
comment
Подпрограммы BASIC очень отличаются от ассемблера, но говорить, что один язык работает, а другой нет, не очень полезно! Вы отладили код?   -  person t0mm13b    schedule 12.04.2017
comment
Ваша команда BASIC открывает файл 3 в канале данных 3 (3,8,3), но ваш ASM пытается получить доступ к нулевому файлу (lda #$00) в канале данных 0 (ldy #$00), который недействителен в качестве номера вторичного адреса для устройства 8 (диск).   -  person J...    schedule 12.04.2017
comment
@J... Я изменил числа, и это сработало.   -  person wizofwor    schedule 12.04.2017


Ответы (2)


По-видимому, проблема была в Logical number и secondary adress, как указал J...

Я исправил это, изменив части .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

Есть и другие проблемы, такие как сообщение «COLORS SAVED» отправляется в файл, а не на экран, но их можно легко исправить.

person wizofwor    schedule 11.04.2017

Я знаю, что это старый поток, но простой вызов jsr close, а затем rts из каждой из процедур ошибок заставит его вывести ошибку на экран, нет? таким образом вы закрываете файл /etc перед выводом текста.

person James Wilson    schedule 19.07.2021