load_from_card.asm (4574B)
1 ;;; Copyright 2021 Gerd Beuster (gerd@frombelow.net). This is free 2 ;;; software under the GNU GPL v3 license or any later version. See 3 ;;; COPYING in the root directory for details. 4 5 ;;; Don't have to include OS stuff if we are part of the OS. 6 .weak 7 LOAD_FROM_CARD_EMBEDDED = false 8 .endweak 9 .if !LOAD_FROM_CARD_EMBEDDED 10 .include "os.inc" 11 .endif 12 13 14 .dsection code 15 16 .section code 17 18 ;;; ----------------------------------- 19 ;;; 20 ;;; Main 21 ;;; 22 ;;; ----------------------------------- 23 24 .section zero_page 25 delay0: .byte ? 26 delay1: .byte ? 27 delay2: .byte ? 28 .send zero_page 29 30 init: 31 .block 32 cld 33 .if SYMON 34 jsr io.init_acia 35 jsr via.init 36 .endif 37 .if !LOAD_FROM_CARD_EMBEDDED 38 ;; Wait for key to start 39 jsr io.getc 40 .endif 41 #ds.INIT_STACK $7ffd-$0400 42 jsr ls_or_autostart 43 jsr choose_program 44 bcc execute 45 jmp ($fffc) ; Reset 46 .bend 47 48 load_address = $0200 49 50 choose_program: 51 .block 52 lda via.ddra ; Set 53 ora #%00010000 ; PA4 54 sta via.ddra ; as output. 55 lda #$00 ; Prepare 56 sta delay0 ; for 57 sta delay1 ; PA4 58 lda #$03 ; blink. 59 sta delay2 60 #io.PRINTSNL "Choose program (0-9). Any other key reloads card." 61 wait_for_input: 62 dec delay0 63 bne dont_blink 64 dec delay1 65 bne dont_blink 66 dec delay2 67 bne dont_blink 68 lda #$03 69 sta delay2 70 lda via.ra ; Blink 71 eor #%00010000 ; PA4 72 sta via.ra 73 dont_blink: 74 jsr io.getc_nonblocking 75 bcs wait_for_input 76 sec 77 sbc #'0' 78 cmp #$0a ; Sets carry if not a digit 79 pha 80 pla 81 rts 82 .bend 83 84 85 execute: 86 .block 87 pha 88 jsr ds.create_stack_frame 89 #ds.PUSH 4 ; Local variables 90 pla 91 pha ; Save application number 92 ;; Each app has 2**16 blocks, app number is in A, therefore 93 ;; the address of the app is [#$00, A, #$00, #$01] 94 #ds.sta_LOCAL 1 95 #io.PRINTS "Loading and executing program " 96 #ds.lda_LOCAL 1 97 clc 98 adc #'0' 99 jsr io.putc 100 #io.PRINTSNL "." 101 lda #$00 102 #ds.sta_LOCAL 0 103 #ds.sta_LOCAL 2 104 lda #$01 105 #ds.sta_LOCAL 3 106 #mem.COPY_WORD_ABSOLUTE_INDIRECT ds.ptr, sd.data ; Read block 107 #ds.PUSH $0200 ; to stack 108 #ds.CALL sd.read_block, [0, 1, 2, 3], #ds.lda_LOCAL 109 #ds.PULL $0200 ; Reset stack pointer to block read 110 #mem.COPY_WORD_IMMEDIATE load_address, sd.data ; Set Target address 111 lda (ds.ptr) ; Number of blocks 112 read_next_block: 113 pha 114 ;; Advance to next block on card 115 clc 116 #ds.lda_LOCAL 3 117 adc #$01 118 #ds.sta_LOCAL 3 119 #ds.lda_LOCAL 2 120 adc #$00 121 #ds.sta_LOCAL 2 122 #ds.CALL sd.read_block, [0, 1, 2, 3], #ds.lda_LOCAL ; Read block 123 #mem.ADD_WORD sd.data, $0200 ; Advance to next block 124 pla 125 dec a 126 bne read_next_block 127 jsr ds.delete_stack_frame 128 ;; Done. 129 ;; Turn off blinkenlight and execute program 130 lda via.ra 131 and #%11101111 132 sta via.ra 133 jsr via.init 134 pla ; Application number stored on stack 135 jmp load_address ; passed to program executed. 136 .bend 137 138 139 ;; List programs on card 140 ls_or_autostart: 141 .block 142 jsr ds.create_stack_frame 143 jsr sd.open 144 ;; List files on card 145 #mem.COPY_WORD_ABSOLUTE_INDIRECT ds.ptr, sd.data ; Read block 146 #ds.PUSH $0200 ; to stack 147 #ds.CALL sd.read_block, [#$00, #$00, #$00, #$00], lda 148 #ds.PULL $0200 ; Reset stack pointer to point to block read 149 ldy #$00 150 lda (ds.ptr) 151 cmp #$15 ; Check FS type 152 beq cont 153 jmp not_supported 154 cont: 155 iny 156 lda (ds.ptr),y 157 cmp #$e2 ; Check FS type 158 beq cont1 159 jmp not_supported 160 cont1: 161 iny 162 lda (ds.ptr),y 163 cmp #$00 ; Check FS version 164 beq cont2 165 jmp not_supported 166 cont2: 167 iny 168 lda (ds.ptr),y 169 cmp #$ff ; Check autostart 170 beq list_files ; No autostart 171 ;; Autostart 172 pha 173 jsr ds.delete_stack_frame 174 pla 175 jmp execute 176 list_files: 177 lda #$00 ; File number 178 dir_entry_loop: 179 pha 180 clc 181 adc #'0' 182 jsr io.putc 183 #io.PRINTS ": " 184 ;; Each app has 2**16 blocks, therefore 185 ;; the address of app i is [#$00, #i, #$00, #$01] 186 lda #$00 187 #ds.sta_LOCAL 0 188 #ds.sta_LOCAL 2 189 lda #$01 190 #ds.sta_LOCAL 3 191 pla 192 pha 193 #ds.sta_LOCAL 1 194 #ds.PUSH 4 195 #mem.COPY_WORD_ABSOLUTE_INDIRECT ds.ptr, sd.data ; Read block 196 #ds.PUSH $0200 ; to stack 197 #ds.CALL sd.read_block, [0, 1, 2, 3], #ds.lda_LOCAL 198 #ds.PULL $0200 ; Reset stack pointer to block read 199 lda (ds.ptr) ; Number of blocks 200 beq filename_printed ; This spot is not occupied 201 pha 202 #mem.COPY_WORD_ABSOLUTE_INDIRECT ds.ptr, io.puts_str 203 #mem.ADD_WORD io.puts_str, $01 ; Start of filename 204 jsr io.puts 205 #io.PRINTS " (" 206 pla 207 pha 208 jsr io.putd 209 pla 210 cmp #$01 211 beq one_block 212 #io.PRINTS " blocks)" 213 jmp filename_printed 214 one_block: 215 #io.PRINTS " block)" 216 filename_printed: 217 jsr io.putnl 218 #ds.PULL 4 219 pla 220 inc a 221 cmp #$0a 222 bcs done 223 jmp dir_entry_loop 224 done: 225 clc 226 jsr ds.delete_stack_frame 227 rts 228 not_supported: 229 #io.PRINTSNL "This filesystem is not supported." 230 sec 231 jsr ds.delete_stack_frame 232 rts 233 .bend 234 235 end_of_code: 236 .send code