1 2 ; LST OFF 3 ORG $0800 4 5 ******************************** 6 * * 7 * Pseudo-Disk ][ Boot Selector * 8 * (FAT16 .HDV/.NIB) * 9 * (c)20061226 Alex Freed * 10 * Merlin-8 Source by Deckard * 11 * * 12 ******************************** 13 14 * WARNING: assume ROM = BOOT.MMC (ProDOS mode) 15 16 * In: UNIT = DSSS0000 17 * X = DSSS0000 (e.g. $40=slot 4, drive 1) 18 19 ******************************** 20 21 * Device driver parameters 22 23 P_CMD EQU $42 ; ProDOS command: status, read, write 24 P_UNIT EQU $43 ; DSSS0000 D[0=drive 1,1=drive 2), SSS=slot 25 P_BUFL EQU $44 ; Low address of I/O buffer (Buffer: $0A00-$0BFF) 26 P_BUFH EQU $45 ; High 27 P_BLKL EQU $46 ; Low block number 28 P_BLKH EQU $47 ; High 29 30 * Page 0 31 32 ENTRY_LO EQU $48 ; Low pointer: pseudodisk I/O vector 33 ENTRY_HI EQU $49 ; High 34 STR_LO EQU $F0 ; Low pointer: string (display) 35 STR_HI EQU $F1 ; High 36 BUFF_LO EQU $FC ; Low pointer: Buffer (names in buffer) 37 BUFF_HI EQU $FD ; High 38 LETTER EQU $FE ; 'A', 'B', ... = file pointer in current page 39 40 * User ram 41 42 BUFFER EQU $0A00 ; $0A00-$0BFF : 512 bytes FAT16 sector 43 44 * Rom 45 46 PD8CMD EQU $C08D ; AVR command 47 RDKEY EQU $FD0C ; input 1 key 48 COUT1 EQU $FDF0 ; output acc 49 BELL EQU $FF3A ; bell ring 50 51 * Device command code 52 53 P_STAT = 0 54 P_READ = 1 55 P_WRITE = 2 56 P_FMT = 3 57 P_CORIG = 8 ; change origin 58 P_ROOTST = $55 ; image_start_sector = puny_root_start 59 P_ZERO = $AA ; image_start_sector = 0 60 61 ******************************** 62 63 * Macros 64 65 PR MAC ; display a string 66 LDA #<]1 67 STA STR_LO 68 LDA #>]1 69 STA STR_HI 70 JSR MY_PUTS 71 <<< 72 73 ******************************** 74 0800: 01 75 DFB 1 ; 1x 512 bytes sector 76 0801: 8A 77 BOOT TXA ; acc=DSSS0000 0802: 4A 78 LSR 0803: 4A 79 LSR 0804: 4A 80 LSR 0805: 4A 81 LSR ; Get slot # (DSSS) 0806: 09 C0 82 ORA #$C0 ; $Cslot (eg: acc=#$C4 for slot 4) 0808: 85 49 83 STA ENTRY_HI 080A: A0 FF 84 LDY #$FF ; retrieve last byte from ROM (ProDOS convention) 080C: 84 48 85 STY ENTRY_LO ; = low driver addr 080E: C8 86 INY ; Y=0 080F: B1 48 87 LDA (ENTRY_LO),Y ; $CxFF. acc points to driver entry 0811: 85 48 88 STA ENTRY_LO ; ok, pointer set 89 0813: A9 08 90 LDA #P_CORIG ; AVR command: change origin 0815: A6 43 91 LDX P_UNIT 0817: 9D 8D C0 92 STA PD8CMD,X 081A: A9 55 93 LDA #P_ROOTST ; set to FAT root directory 081C: A6 43 94 LDX P_UNIT 081E: 9D 8D C0 95 STA PD8CMD,X ; image_start_sector=puny_root_start 96 97 * puny_root_start = puny_fat_size * puny_fat_copies 98 * + puny_fat_start 99 * With puny_fat_size = # of 512 bytes sectors per FAT 100 * = $F5 101 * puny_fat_copies = # of FAT 102 * = $02 103 * part_start = MBR($01C6) 104 * = $20 105 * puny_fat_start = # of reserved 512 bytes sectors 106 * before 1st FAT + part_start 107 * = $16 + $20 108 * SD 128 mbytes: 109 * puny_root_start = 2*$F5 + $16 + $20 = $220 sectors 110 * => Offset = $220 sectors * $200 bytes = $44000 bytes 111 112 * Now, fill required inputs for READ request 113 * (ProDOS device driver parameters) 114 0821: A9 00 115 AGAIN LDA #$00 ; Low block $0000 0823: 85 46 116 STA P_BLKL 117 0825: A9 00 118 NEXT LDA #$00 0827: 85 47 119 STA P_BLKH ; High block $0000 0829: 85 44 120 STA P_BUFL ; #BUFFER 082D: 85 45 122 STA P_BUFH 082F: A9 01 123 LDA #P_READ ; ProDOS Read command 0831: 85 42 124 STA P_CMD 125 0833: 20 E3 08 126 JSR DO_CALL ; Read dir block (FAT16 partition 1) into BUFFER 0836: B0 57 127 BCS ERROR 128 129 PR FAT_STR ; display FAT DIRECTORY: 0838: A9 06 129 LDA #FAT_STR 083E: 85 F1 129 STA STR_HI 0840: 20 E7 08 129 JSR MY_PUTS 129 <<< 130 0843: A9 41 131 LDA #'A' ; init first char 0845: 85 FE 132 STA LETTER 0847: A0 0A 133 LDY #>BUFFER 0849: 84 FD 134 STY BUFF_HI 084B: A9 00 135 LDA # end 141 0855: A5 FE 142 LDA LETTER 0857: 09 80 143 ORA #%10000000 ; 'LETTER' -> "LETTER" 0859: 20 F0 FD 144 JSR COUT1 ; display it 085C: A9 A0 145 LDA #" " ; double space 085E: 20 F0 FD 146 JSR COUT1 0861: 20 F0 FD 147 JSR COUT1 148 0864: A0 0C 149 LDY #12 ; Point after the name 0866: A9 00 150 LDA #0 ; Set terminator 0868: 91 FC 151 STA (BUFF_LO),Y 152 086A: A5 FC 153 LDA BUFF_LO ; Work pointer for print 086C: 85 F0 154 STA STR_LO 086E: A5 FD 155 LDA BUFF_HI 0870: 85 F1 156 STA STR_HI 0872: 20 E7 08 157 JSR MY_PUTS ; Display name 158 0875: A9 8D 159 LDA #$8D ; Return 0877: 20 F0 FD 160 JSR COUT1 161 087A: E6 FE 162 INC LETTER 087C: A5 FC 163 LDA BUFF_LO ; Set pointer to next name 087E: 18 164 CLC 087F: 69 20 165 ADC #32 0881: 85 FC 166 STA BUFF_LO ; Low 0883: 90 CA 167 BCC MORE ; continue 168 169 ; second part of the sector (bytes $100 to $1FF) 0885: E6 FD 170 INC BUFF_HI ; High+1 0887: A9 0C 171 LDA #>BUFFER+$0200 0889: C5 FD 172 CMP BUFF_HI ; buffer overflow? 088B: D0 C2 173 BNE MORE ; no: continue 174 088D: F0 0C 175 BEQ DONE ; yep: stop now and display current page 176 177 *------------------------------- 178 179 ERROR PR ERR_STR ; display: error 088F: A9 FB 179 LDA #ERR_STR 0895: 85 F1 179 STA STR_HI 0897: 20 E7 08 179 JSR MY_PUTS 179 <<< 089A: 00 180 BRK ; crash 181 182 *------------------------------- 183 184 DONE PR SEL_STR ; display: select letter or space 089B: A9 18 184 LDA #SEL_STR 08A1: 85 F1 184 STA STR_HI 08A3: 20 E7 08 184 JSR MY_PUTS 184 <<< 185 08A6: 20 0C FD 186 SELECT JSR RDKEY ; Read key 08A9: 29 7F 187 AND #$7F ; "LETTER" -> 'LETTER' 08AB: C9 31 188 CMP #'1' ; 1=refresh 08AD: D0 03 189 BNE NOT_AGAIN 190 08AF: 4C 21 08 191 JMP AGAIN 192 08B2: C9 20 193 NOT_AGAIN CMP #' ' ; next page? 08B4: D0 05 194 BNE NOT_NEXT ; no 195 08B6: E6 46 196 INC P_BLKL ; Next block of dir 08B8: 4C 25 08 197 JMP NEXT ; display the names of this block 198 08BB: C9 41 199 NOT_NEXT CMP #'A' ; >='A'? 08BD: B0 06 200 BCS NOT_UNDER ; yes 201 08BF: 20 3A FF 202 JSR BELL ; bad key. Retry. 08C2: 4C A6 08 203 JMP SELECT 204 08C5: C5 FE 205 NOT_UNDER CMP LETTER ; <=last letter? 08C7: 90 06 206 BCC NOT_OVER ; yes 207 08C9: 20 3A FF 208 JSR BELL ; bad key. Retry. 08CC: 4C A6 08 209 JMP SELECT 210 08CF: A6 43 211 NOT_OVER LDX P_UNIT 08D1: 9D 8D C0 212 STA PD8CMD,X ; acc=key ('A', ...) -> select file in current page 213 ; (loaded buffer) 214 PR OK_STR ; display OK 08D4: A9 02 214 LDA #OK_STR 08DA: 85 F1 214 STA STR_HI 08DC: 20 E7 08 214 JSR MY_PUTS 214 <<< 215 08DF: A9 00 216 LDA #$00 ; exec PR#slot 08E1: 85 48 217 STA ENTRY_LO ; Now points to $Cx00 218 219 *------------------------------- 220 221 * Run Pseudo-Disk ][ ProDOS device driver 222 * with parameters 223 08E3: 6C 48 00 224 DO_CALL JMP (ENTRY_LO) 08E6: 60 225 RTS 226 227 *------------------------------* 228 * * 229 * Display name until terminator* 230 * * 231 *------------------------------* 232 08E7: A0 00 233 MY_PUTS LDY #0 08E9: B1 F0 234 :2 LDA (STR_LO),Y 08EB: F0 0D 235 BEQ :1 ; eol 236 08ED: 09 80 237 ORA #%10000000 08EF: 20 F0 FD 238 JSR COUT1 08F2: E6 F0 239 INC STR_LO 08F4: D0 F3 240 BNE :2 241 08F6: E6 F1 242 INC STR_HI 08F8: D0 EF 243 BNE :2 244 08FA: 60 245 :1 RTS 246 247 248 *------------------------------* 249 * * 250 * Strings * 251 * * 252 *------------------------------* 253 08FB: 65 72 72 254 ERR_STR ASC 'error'0D00 08FE: 6F 72 0D 00 0902: 4F 4B 0D 255 OK_STR ASC 'OK'0D00 0905: 00 0906: 46 41 54 256 FAT_STR ASC 'FAT DIRECTORY:'090D0D00 0909: 20 44 49 52 090D: 45 43 54 4F 0911: 52 59 3A 09 0915: 0D 0D 00 0918: 0D 257 SEL_STR DFB $0D 0919: 53 45 4C 258 ASC 'SELECT. SPACE FOR MORE'0D00 091C: 45 43 54 2E 0920: 20 53 50 41 0924: 43 45 20 46 0928: 4F 52 20 4D 092C: 4F 52 45 0D 0930: 00 259 260 ******************************** 261 0931: 00 00 00 262 DS \ 0934: 00 00 00 00 0938: 00 00 00 00 093C: 00 00 00 00 0940: 00 00 00 00 0944: 00 00 00 00 0948: 00 00 00 00 094C: 00 00 00 00 0950: 00 00 00 00 0954: 00 00 00 00 0958: 00 00 00 00 095C: 00 00 00 00 0960: 00 00 00 00 0964: 00 00 00 00 0968: 00 00 00 00 096C: 00 00 00 00 0970: 00 00 00 00 0974: 00 00 00 00 0978: 00 00 00 00 097C: 00 00 00 00 0980: 00 00 00 00 0984: 00 00 00 00 0988: 00 00 00 00 098C: 00 00 00 00 0990: 00 00 00 00 0994: 00 00 00 00 0998: 00 00 00 00 099C: 00 00 00 00 09A0: 00 00 00 00 09A4: 00 00 00 00 09A8: 00 00 00 00 09AC: 00 00 00 00 09B0: 00 00 00 00 09B4: 00 00 00 00 09B8: 00 00 00 00 09BC: 00 00 00 00 09C0: 00 00 00 00 09C4: 00 00 00 00 09C8: 00 00 00 00 09CC: 00 00 00 00 09D0: 00 00 00 00 09D4: 00 00 00 00 09D8: 00 00 00 00 09DC: 00 00 00 00 09E0: 00 00 00 00 09E4: 00 00 00 00 09E8: 00 00 00 00 09EC: 00 00 00 00 09F0: 00 00 00 00 09F4: 00 00 00 00 09F8: 00 00 00 00 09FC: 00 00 00 00 263 264 SAV SDBOOT Object saved as SDBOOT,A$0800,L$0200,BIN --End assembly, 512 bytes, Errors: 0 Symbol table - alphabetical order: AGAIN =$0821 BELL =$FF3A ? BOOT =$0801 BUFFER =$0A00 BUFF_HI =$FD BUFF_LO =$FC COUT1 =$FDF0 DONE =$089B DO_CALL =$08E3 ENTRY_HI=$49 ENTRY_LO=$48 ERROR =$088F ERR_STR =$08FB FAT_STR =$0906 LETTER =$FE MORE =$084F MY_PUTS =$08E7 NEXT =$0825 NOT_AGAIN=$08B2 NOT_NEXT=$08BB NOT_OVER=$08CF NOT_UNDER=$08C5 OK_STR =$0902 PD8CMD =$C08D MD PR =$8000 P_BLKH =$47 P_BLKL =$46 P_BUFH =$45 P_BUFL =$44 P_CMD =$42 P_CORIG =$08 ? P_FMT =$03 P_READ =$01 P_ROOTST=$55 ? P_STAT =$00 P_UNIT =$43 ? P_WRITE =$02 ? P_ZERO =$AA RDKEY =$FD0C SELECT =$08A6 SEL_STR =$0918 STR_HI =$F1 STR_LO =$F0 Symbol table - numerical order: ? P_STAT =$00 P_READ =$01 ? P_WRITE =$02 ? P_FMT =$03 P_CORIG =$08 P_CMD =$42 P_UNIT =$43 P_BUFL =$44 P_BUFH =$45 P_BLKL =$46 P_BLKH =$47 ENTRY_LO=$48 ENTRY_HI=$49 P_ROOTST=$55 ? P_ZERO =$AA STR_LO =$F0 STR_HI =$F1 BUFF_LO =$FC BUFF_HI =$FD LETTER =$FE ? BOOT =$0801 AGAIN =$0821 NEXT =$0825 MORE =$084F ERROR =$088F DONE =$089B SELECT =$08A6 NOT_AGAIN=$08B2 NOT_NEXT=$08BB NOT_UNDER=$08C5 NOT_OVER=$08CF DO_CALL =$08E3 MY_PUTS =$08E7 ERR_STR =$08FB OK_STR =$0902 FAT_STR =$0906 SEL_STR =$0918 BUFFER =$0A00 MD PR =$8000 PD8CMD =$C08D RDKEY =$FD0C COUT1 =$FDF0 BELL =$FF3A