├── .gitignore ├── LICENSE.TXT ├── LICENSE_1_0.TXT ├── README.md ├── TBED ├── BRAM-01.BIN ├── BRAM-02.BIN ├── BRAM-03.BIN ├── BRAM-04.BIN ├── BRAM-05.BIN ├── BRAM-06.BIN ├── BRAM-07.BIN ├── BRAM-08.BIN ├── MB128-01.BIN ├── MB128-02.BIN ├── MB128-03.BIN ├── MB128-04.BIN ├── MB128-05.BIN ├── MB128-06.BIN ├── MB128-07.BIN ├── MB128-08.BIN └── TENNOKOE.BIN ├── aplib.s ├── bram.s ├── build.cmd ├── fake ├── save0.bin ├── save1.bin ├── save2.bin ├── sector00000000.bin ├── sector00000800.bin ├── sector00000AB6.bin ├── sector00002800.bin ├── sector00002850.bin ├── sector00020BC8.bin ├── sector00021818.bin ├── sector00027C20.bin ├── t32-s000000.bin └── t32-s002000.bin ├── fakesd.s ├── fat32.s ├── filefuncs.s ├── font8x16-syscard_bold6.fon ├── font8x8-ascii-bold-short-fat32g.fon ├── fonts.apl ├── huc6280.s ├── mb128.s ├── menu_bram.s ├── menu_hucard.s ├── menu_info.s ├── menu_init.s ├── menu_mb128.s ├── osfunc.s ├── pceas.inc ├── pcengine.inc ├── pcengine.txt ├── run.cmd ├── sd.s ├── ted2.inc ├── teos.s ├── teos_bank0.s ├── teos_bank1.s ├── teos_bank2.s ├── teos_bank3.s └── text.s /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.pce 3 | *.sgx 4 | *.lst 5 | *.sym 6 | teos-beta* 7 | turbo-usb2.exe 8 | -------------------------------------------------------------------------------- /LICENSE.TXT: -------------------------------------------------------------------------------- 1 | This project's source code, scripts and documentation are distributed under 2 | the Boost Software License, Version 1.0. 3 | 4 | (See the accompanying file LICENSE_1_0.txt or the copy at 5 | http://www.boost.org/LICENSE_1_0.txt) 6 | -------------------------------------------------------------------------------- /LICENSE_1_0.TXT: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ***************************************************************************** 2 | 3 | TEOS 4 | ==== 5 | 6 | **A replacement Operating System for Krikzz's Turbo Everdrive v2** 7 | 8 | Copyright John Brandwood 2019-2022. 9 | 10 | Distributed under the Boost Software License, Version 1.0. 11 | 12 | (See the accompanying file LICENSE_1_0.txt or the copy at 13 | http://www.boost.org/LICENSE_1_0.txt) 14 | 15 | 16 | ***************************************************************************** 17 | 18 | About 19 | ----- 20 | 21 | This is a replacement Operating System for Krikzz's Turbo Everdrive v2. 22 | 23 | Please do NOT try to use this on an old Turbo Everdrive v1, IT WILL NOT WORK! 24 | 25 | 26 | While TEOS is graphically nicer than the original Turbo Everdrive OS, the real reasons for using it are ... 27 | 28 | * It allows the TurboGrafx (and PC Engine) to use the Turbo Everdrive v2 as a Super System Card, avoiding the need to buy the very-expensive US TurboGrafx Super System Card. 29 | * It avoids the potentially damaging memory bus-fighting that occurs with Krikzz's OS when running the PC Engine (or TurboGrafx) Super System Card HuCARD on the Turbo Everdrive. 30 | * It supports copying the PC Engine's "Backup RAM" contents to and from the Turbo Everdrive's SD card. 31 | * It supports copying the PC Engine's "Memory Base 128" contents to and from the Turbo Everdrive's SD card. 32 | * It fixes the graphics corruption in the Japanese "POPULOUS" HuCARD game. 33 | * It supports the use of the Japanese "Tennokoe Bank" HuCARD utility. 34 | 35 | 36 | ***************************************************************************** 37 | 38 | TEOS Release v3.01 (2022/06/12) 39 | ------------------------------- 40 | 41 | Just extract the contents of the release "TEOS-3.01-2022-06-12.ZIP" file, and then copy the extracted files to the root of your Turbo EverDrive's SD card. 42 | 43 | In particular ... the contents of the /TBED/ directory *must* go in that directory. 44 | 45 | If you have already got some files with the same name in your /TBED/ directory, then please do NOT overwrite those files, or you will lose your existing BRAM saves! 46 | 47 | 48 | Note that TEOS works both as a HuCARD image, and as a replacement for Krikzz's original Turbo Everdrive OS. 49 | 50 | * To run it as a HuCARD, just select and run TEOS.PCE from your existing Turbo Everdrive OS. 51 | * To replace Krikzz's original Turbo Everdrive OS with TEOS, just rename TEOS.PCE to OS.PCE and copy the OS.PCE file to the /TBED/ folder on your SD card. 52 | 53 | 54 | For Turbo GT (and Turbo Express) owners there is also a version of TEOS called TEOS-GT.PCE which avoids using the high-resolution text mode, and so is a bit more readable on their LCD screen. 55 | 56 | 57 | If you find any problems, then it would be better to report them in the "Homebrew Development" section of the "PC Engine Software Bible forum" (https://pcengine.proboards.com/board/5/homebrew-development), rather than cluttering up KRIKzz's official Turbo Everdrive forum. 58 | 59 | 60 | ***************************************************************************** 61 | 62 | Changes since TEOS Beta 5 (2021/01/26) 63 | -------------------------------------- 64 | 65 | * Support uploading HuCARD games to the TED2 through USB with either Krikzz's "turbo-usb2.exe", or Dave Shadoff's PCE_TurboEverdrive_USB (https://github.com/dshadoff/PCE_TurboEverdrive_USB). 66 | * Backup and restore NEC's Memory Base 128 (a.k.a. Koei's Save Kun) images to and from the TED2's SD card. 67 | * Enable the TED2's "Street Fighter 2" memory mapper for all HuCARDs larger than 1MByte, to allow for future homebrew games using the mapper. 68 | * Fix missing color in "Order of the Gryffon" password screen. 69 | 70 | 71 | ***************************************************************************** 72 | 73 | Changes for TEOS Beta 5 (2021/01/26) 74 | ------------------------------------ 75 | 76 | TEOS Beta 5 fixes initialization problems with the following games ... 77 | 78 | * Tower of Druaga 79 | * Space Harrier 80 | * Shiryou Sensen 81 | * Out Live 82 | * Benkei Gaiden 83 | * Gekisha Boy 84 | * Night Creatures 85 | 86 | 87 | ***************************************************************************** 88 | 89 | Building a new TEOS from Source Code 90 | ------------------------------------ 91 | 92 | The source code for TEOS can be found on GITHUB at https://github.com/jbrandwood/teos 93 | 94 | You will need to use a recent version of the PCEAS assembler to successfully build TEOS. 95 | 96 | 97 | The PCEAS assembler is one component of the HuC project which can be found on GITHUB at https://github.com/jbrandwood/huc 98 | 99 | 100 | ***************************************************************************** 101 | -------------------------------------------------------------------------------- /TBED/BRAM-01.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/BRAM-01.BIN -------------------------------------------------------------------------------- /TBED/BRAM-02.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/BRAM-02.BIN -------------------------------------------------------------------------------- /TBED/BRAM-03.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/BRAM-03.BIN -------------------------------------------------------------------------------- /TBED/BRAM-04.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/BRAM-04.BIN -------------------------------------------------------------------------------- /TBED/BRAM-05.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/BRAM-05.BIN -------------------------------------------------------------------------------- /TBED/BRAM-06.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/BRAM-06.BIN -------------------------------------------------------------------------------- /TBED/BRAM-07.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/BRAM-07.BIN -------------------------------------------------------------------------------- /TBED/BRAM-08.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/BRAM-08.BIN -------------------------------------------------------------------------------- /TBED/MB128-01.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/MB128-01.BIN -------------------------------------------------------------------------------- /TBED/MB128-02.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/MB128-02.BIN -------------------------------------------------------------------------------- /TBED/MB128-03.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/MB128-03.BIN -------------------------------------------------------------------------------- /TBED/MB128-04.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/MB128-04.BIN -------------------------------------------------------------------------------- /TBED/MB128-05.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/MB128-05.BIN -------------------------------------------------------------------------------- /TBED/MB128-06.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/MB128-06.BIN -------------------------------------------------------------------------------- /TBED/MB128-07.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/MB128-07.BIN -------------------------------------------------------------------------------- /TBED/MB128-08.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/MB128-08.BIN -------------------------------------------------------------------------------- /TBED/TENNOKOE.BIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/TBED/TENNOKOE.BIN -------------------------------------------------------------------------------- /aplib.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; aplib_6280.s 5 | ; 6 | ; HuC6280 decompressor for data stored in Jorgen Ibsen's aPLib format. 7 | ; 8 | ; This code is written for the PCEAS/NECASM assembler in HuC & MagicKit. 9 | ; 10 | ; Copyright John Brandwood 2019. 11 | ; 12 | ; Distributed under the Boost Software License, Version 1.0. 13 | ; (See accompanying file LICENSE_1_0.txt or copy at 14 | ; http://www.boost.org/LICENSE_1_0.txt) 15 | ; 16 | ; *************************************************************************** 17 | ; *************************************************************************** 18 | 19 | 20 | 21 | ; *************************************************************************** 22 | ; *************************************************************************** 23 | ; 24 | ; Decompression Options & Macros 25 | ; 26 | 27 | ; 28 | ; Assume that we're decompessing from a large multi-bank 29 | ; compressed data file and that MPR3 (and MPR4) are used 30 | ; as a window into that file? 31 | ; 32 | 33 | APL_FROM_MPR3 = 0 34 | 35 | ; 36 | ; Macro to increment the source pointer to the next page. 37 | ; 38 | 39 | if APL_FROM_MPR3 40 | APL_INC_PAGE macro 41 | bsr .next_page 42 | endm 43 | else 44 | APL_INC_PAGE macro 45 | inc 64768 bytes has 108 | ; been removed, since these don't occur with a 16-bit address range. 109 | ; 110 | ; As an optimization, the code to handle window offsets > 32000 bytes has 111 | ; been commented-out, since these don't occur in typical PC Engine usage. 112 | ; 113 | 114 | apl_decompress: lda #$73 ; TII instruction. 115 | sta <__al 116 | 117 | tii .tii_end, __dh, 3 ; TII ends with JMP. 118 | 119 | lda #$80 ; Initialize an empty 120 | sta 138 | bcc .literal 139 | bne .skip1 140 | bsr .load_bit 141 | bcc .literal 142 | 143 | .skip1: asl - gamma-coded LZSS pair. 242 | ; 243 | 244 | .code_pair: bsr .get_gamma ; Bits 8..15 of offset (min 2). 245 | stz = 32000, length += 2. 264 | ; bcs .match_plus2 265 | cpx #$05 ; If offset >= 1280, length += 1. 266 | bcs .match_plus1 267 | bra .do_match 268 | .lt256: ldx = $4000. 121 | 122 | .found: inc <__ax + 1 123 | 124 | .exit: jsr bm_restore_mpr ; Do NOT shorten this to a JMP! 125 | 126 | lda <__ax + 1 ; Subtract bank address to 127 | sec ; leave size in pages. 128 | sbc #$40 129 | 130 | rts 131 | 132 | 133 | 134 | ; *************************************************************************** 135 | ; *************************************************************************** 136 | ; 137 | ; bm_format_bram - Format the BRAM. 138 | ; 139 | 140 | bm_format_bram: jsr bm_check_size ; Confirm "BRAM size". 141 | beq .no_bram ; Exit if none. 142 | 143 | jsr bm_prepare_mpr 144 | 145 | lda #$F7 ; Map in the BRAM and shadow. 146 | tam3 147 | 148 | jsr bm_format_mpr3 149 | 150 | jsr bm_restore_mpr ; Do NOT shorten this to a JMP! 151 | 152 | lda <__ax + 1 ; Return BRAM size. 153 | .no_bram: rts 154 | 155 | endif 156 | 157 | 158 | 159 | ; *************************************************************************** 160 | ; *************************************************************************** 161 | ; 162 | ; bm_bram_to_bank - Copy BRAM image from actual BRAM hardware to RAM bank. 163 | ; 164 | 165 | bm_bram_to_bank:jsr bm_prepare_mpr 166 | 167 | tii $4000, $6000, 2048 168 | 169 | if REALHW 170 | else 171 | lda #BANK(fake_bram2) 172 | tam2 173 | tii fake_bram2, $6000, 2048 174 | endif 175 | 176 | jsr bm_restore_mpr ; Do NOT shorten this to a JMP! 177 | rts 178 | 179 | 180 | 181 | ; *************************************************************************** 182 | ; *************************************************************************** 183 | ; 184 | ; bm_bank_to_bram - Copy BRAM image in RAM bank to actual BRAM hardware. 185 | ; 186 | 187 | bm_bank_to_bram:jsr bm_prepare_mpr 188 | 189 | tii $6000, $4000, 2048 190 | 191 | jsr bm_restore_mpr ; Do NOT shorten this to a JMP! 192 | rts 193 | 194 | 195 | 196 | ; *************************************************************************** 197 | ; *************************************************************************** 198 | ; 199 | ; bm_check_bram - 200 | ; 201 | ; Uses: __al = Return Code 202 | ; $FF = Unformatted. 203 | ; $00 = Formatted & OK. 204 | ; $01 = Formatted, but has errors. 205 | ; 206 | ; Uses: __ah = BRAM Size ($00=none, $88=2KB, or else unexpected size). 207 | ; Uses: __bx = # of files in BRAM. 208 | ; Uses: __bp = Ptr to next free (in $6010..$67FF range). 209 | ; 210 | 211 | bm_check_bram: jsr bm_prepare_mpr 212 | 213 | lda #$F7 ; Map the BRAM into MPR3 for 214 | tam3 ; testing. 215 | 216 | jsr bm_verify_mpr3 ; Verify the integrity. 217 | 218 | jsr bm_restore_mpr ; Do NOT shorten this to a JMP! 219 | 220 | rts 221 | 222 | 223 | 224 | ; *************************************************************************** 225 | ; *************************************************************************** 226 | ; 227 | ; bm_format_mpr3 - Format the BRAM image mapped into MPR3 ($6000..$67FF). 228 | ; 229 | 230 | bm_format_mpr3: tai tos_zero, $6000, $0800 231 | 232 | tdd bm_signature + 7, $6007, 8 233 | 234 | rts 235 | 236 | bm_signature: db "HUBM" 237 | dw $8800 238 | dw $8010 239 | 240 | 241 | 242 | ; *************************************************************************** 243 | ; *************************************************************************** 244 | ; 245 | ; bm_verify_mpr3 - Verify the BRAM data mapped into MPR3 ($6000..$67FF). 246 | ; 247 | ; Uses: __al = Return Code 248 | ; $FF = Unformatted. 249 | ; $00 = Formatted & OK. 250 | ; $01 = Formatted, but has errors. 251 | ; 252 | ; Uses: __ah = BRAM Size ($00=none, $88=2KB, or else unexpected size). 253 | ; Uses: __bx = # of files in BRAM. 254 | ; Uses: __bp = Ptr to next free (in $6010..$67FF range). 255 | ; 256 | 257 | bm_verify_mpr3: lda #$FF 258 | sta <__al ; $FF = Unformatted. 259 | 260 | stz <__ah ; Return BRAM Size. 261 | stz <__bl ; Return # of files (lo). 262 | stz <__bh ; Return # of files (hi). 263 | 264 | ldx #$FB ; Check signature & lo-byte 265 | .test_header: lda bm_signature - $FB,x ; of size. 266 | cmp $6000 - $FB,x 267 | bne .test_present 268 | inx 269 | bne .test_header 270 | 271 | stz <__al ; $00 = Formatted. 272 | 273 | lda $6005 ; Check that BRAM Size is 2KB. 274 | sta <__ah 275 | cmp #$88 276 | bne .free_wrong 277 | 278 | ldy #<$6010 ; First file in chain. 279 | lda #>$6010 280 | 281 | .file_loop: sty <__bp + 0 ; Update file pointer. 282 | sta <__bp + 1 283 | 284 | .test_free: cpy $6006 285 | bne .test_size 286 | eor #$E0 ; Xvert $6000 base to $8000. 287 | cmp $6007 288 | beq .found_end 289 | 290 | .test_size: ldy #1 ; End of file chain? 291 | lda [__bp],y 292 | tay 293 | ora [__bp] 294 | beq .found_end 295 | 296 | lda [__bp] 297 | .too_small: cmp #$10 ; Size < $0010 (min size)? 298 | bcs .too_large 299 | cpy #$00 300 | beq .bram_corrupt 301 | .too_large: cpy #$20 ; Size > $1FFF (max size)? 302 | bcs .bram_corrupt 303 | 304 | clc ; Calc address of next file. 305 | adc <__bp + 0 306 | say 307 | adc <__bp + 1 308 | cmp #$68 ; Is it beyond BRAM Size? 309 | bcs .bram_corrupt 310 | 311 | inc <__bl ; # of files found. 312 | bne .file_loop 313 | inc <__bh 314 | bra .file_loop 315 | 316 | .bram_corrupt: smb1 <__al ; $01 = Formatted, but errors. 317 | 318 | ; ldy #1 ; Repair damage. 319 | ; cla 320 | ; sta [__bp],y 321 | ; sta [__bp] 322 | 323 | .found_end: ldy <__bp + 0 324 | lda <__bp + 1 325 | eor #$E0 ; Xvert $6000 base to $8000. 326 | 327 | cpy $6006 ; Check BRAM Free address. 328 | bne .free_wrong 329 | cmp $6007 330 | beq .finished 331 | 332 | .free_wrong: smb1 <__al ; $01 = Formatted, but errors. 333 | 334 | ; sty $6006 ; Repair damage. 335 | ; sta $6007 336 | 337 | .finished: lda <__al 338 | rts 339 | 340 | ; 341 | 342 | .test_present: stz $67FF ; Confirm that BRAM is present. 343 | lda $67FF 344 | bne .finished 345 | 346 | lda #$88 ; Report that BRAM Size is 2KB. 347 | sta <__ah 348 | bra .finished 349 | 350 | 351 | 352 | ; *************************************************************************** 353 | ; *************************************************************************** 354 | ; 355 | ; bm_repair_mpr3 - Repair the BRAM data mapped into MPR3 ($6000..$67FF). 356 | ; 357 | 358 | bm_repair_mpr3: jsr bm_verify_mpr3 359 | 360 | ldy <__bp + 0 ; Fix EOF address pointer. 361 | lda <__bp + 1 362 | sty .cleanup + 3 363 | sta .cleanup + 4 364 | eor #$E0 ; Xvert $6000 base to $8000. 365 | sty $6006 ; Fix pointer to next free. 366 | sta $6007 367 | 368 | sec ; Fix EOF marker and clear 369 | lda $6004 ; the free space. 370 | sbc $6006 371 | sta .cleanup + 5 372 | lda $6005 373 | sbc $6007 374 | sta .cleanup + 6 375 | 376 | .cleanup: tai tos_zero, $6000, $0800 377 | 378 | rts 379 | 380 | 381 | 382 | ; *************************************************************************** 383 | ; *************************************************************************** 384 | ; 385 | ; tos_bram_csum - Calc the checkum of a file in a BRAM image. 386 | ; 387 | ; Args: __ax = Ptr to the file header in the BRAM image. 388 | ; Uses: __si = Temporary ptr. 389 | ; Uses: __bx = Checksum result. 390 | ; 391 | 392 | if 0 393 | 394 | tos_bram_csum: lda <__ax + 0 395 | sta <__si + 0 396 | lda <__ax + 1 397 | sta <__si + 1 398 | 399 | lda [__si] 400 | sec 401 | sbc #4 402 | tax 403 | ldy #1 404 | lda [__si],y 405 | sbc #0 406 | inc a 407 | sta <__bl 408 | 409 | ldy #4 410 | cla 411 | sta <__bx + 1 412 | 413 | .sum_loop: clc 414 | adc [__si],y 415 | bcc .sum_skip 416 | inc <__bx + 1 417 | .sum_skip: iny 418 | bne .ptr_skip 419 | inc <__si + 1 420 | .ptr_skip: dex 421 | bne .sum_loop 422 | dec <__bl 423 | bne .sum_loop 424 | sta <__bx + 0 425 | rts 426 | 427 | endif 428 | -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem *************************************************************************** 4 | 5 | rem Put this in your main project directory. 6 | rem 7 | rem It expects "huc" and "squirrel" directories to be in the parent 8 | rem directory, i.e. one level higher. 9 | 10 | rem *************************************************************************** 11 | 12 | setlocal 13 | 14 | cd /d "%~dp0" 15 | 16 | pushd 17 | cd .. 18 | set PATH=%CD%\huc\bin;%PATH% 19 | popd 20 | set PCE_INCLUDE=%CD% 21 | 22 | pceas -raw -m -l 2 -S teos.s 23 | if errorlevel 1 goto :error 24 | 25 | exit /b 0 26 | 27 | rem *************************************************************************** 28 | 29 | :error 30 | rem pause 31 | exit /b 1 32 | 33 | rem *************************************************************************** 34 | -------------------------------------------------------------------------------- /fake/save0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/save0.bin -------------------------------------------------------------------------------- /fake/save1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/save1.bin -------------------------------------------------------------------------------- /fake/save2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/save2.bin -------------------------------------------------------------------------------- /fake/sector00000000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/sector00000000.bin -------------------------------------------------------------------------------- /fake/sector00000800.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/sector00000800.bin -------------------------------------------------------------------------------- /fake/sector00000AB6.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/sector00000AB6.bin -------------------------------------------------------------------------------- /fake/sector00002800.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/sector00002800.bin -------------------------------------------------------------------------------- /fake/sector00002850.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/sector00002850.bin -------------------------------------------------------------------------------- /fake/sector00020BC8.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/sector00020BC8.bin -------------------------------------------------------------------------------- /fake/sector00021818.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/sector00021818.bin -------------------------------------------------------------------------------- /fake/sector00027C20.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/sector00027C20.bin -------------------------------------------------------------------------------- /fake/t32-s000000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/t32-s000000.bin -------------------------------------------------------------------------------- /fake/t32-s002000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbrandwood/teos/ac5396e6b98a52552309576d0f4e81bd26b6f39d/fake/t32-s002000.bin -------------------------------------------------------------------------------- /fakesd.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; fakesd.s 5 | ; 6 | ; Various sectors from an existing SDcard that can be used to simulate a 7 | ; real FAT32 volume when debugging TEOS in mednafen. 8 | ; 9 | ; Copyright John Brandwood 2019. 10 | ; 11 | ; Distributed under the Boost Software License, Version 1.0. 12 | ; (See accompanying file LICENSE_1_0.txt or copy at 13 | ; http://www.boost.org/LICENSE_1_0.txt) 14 | ; 15 | ; *************************************************************************** 16 | ; *************************************************************************** 17 | 18 | 19 | 20 | ; *************************************************************************** 21 | ; *************************************************************************** 22 | ; 23 | ; 24 | ; $0a3a fat1_begins sector 25 | ; 26 | ; $27f0 data_begins sector 27 | ; 28 | ; 8 sectors per cluster 29 | ; 30 | ; 0c 00 00 00 "SuperGrafx" cluster -> sector $2850 -> offset $50a000 2 sectors 31 | ; c2 15 00 00 "USA" directory cluster -> sector $d600 -> offset $1ac0000 2 sectors 32 | ; 7b 3c 00 00 "JAPAN" directory cluster -> sector $20bc8 -> offset $4179000 2 sectors 33 | ; 05 3e 00 00 "A-C" directory cluster -> sector $21818 -> offset $4303000 1 cluster 34 | ; 35 | ; byte offset $014 36 | ; sect offset $07c 37 | ; 38 | ; -> FAT sector address $ab6 39 | ; 40 | ; -> next cluster $4a86 -> sector $27c20 -> offset $4f84000 41 | ; 42 | 43 | if REALHW 44 | else 45 | 46 | .bank 7 47 | .org $4000 48 | 49 | fake_bram1: incbin "fake/save0.bin" 50 | fake_bram2: incbin "fake/save2.bin" 51 | 52 | ; 53 | ; 54 | ; 55 | 56 | fake_sector_l: db $00 57 | db $00 58 | db $B6 59 | db $B7 60 | db $00 61 | db $00 62 | 63 | db $50 64 | db $51 65 | 66 | db $C8 67 | db $C9 68 | 69 | db $18 70 | db $19 71 | db $1A 72 | db $1B 73 | db $1C 74 | db $1D 75 | db $1E 76 | db $1F 77 | 78 | db $20 79 | db $21 80 | db $22 81 | db $FF 82 | 83 | fake_sector_m: db $00 84 | db $08 85 | db $0A 86 | db $0A 87 | db $20 88 | db $28 89 | 90 | db $28 91 | db $28 92 | 93 | db $0B 94 | db $0B 95 | 96 | db $18 97 | db $18 98 | db $18 99 | db $18 100 | db $18 101 | db $18 102 | db $18 103 | db $18 104 | 105 | db $7C 106 | db $7C 107 | db $7C 108 | db $FF 109 | 110 | fake_sector_h: db $00 111 | db $00 112 | db $00 113 | db $00 114 | db $00 115 | db $00 116 | 117 | db $00 118 | db $00 119 | 120 | db $02 121 | db $02 122 | 123 | db $02 124 | db $02 125 | db $02 126 | db $02 127 | db $02 128 | db $02 129 | db $02 130 | db $02 131 | 132 | db $02 133 | db $02 134 | db $02 135 | db $FF 136 | 137 | fake_sector_tii:dw fake_000000 138 | dw fake_000800 139 | dw fake_000AB6 140 | dw fake_000AB7 141 | dw fake_002000 142 | dw fake_002800 143 | 144 | dw fake_002850 145 | dw fake_002851 146 | 147 | dw fake_020BC8 148 | dw fake_020BC9 149 | 150 | dw fake_021818 151 | dw fake_021819 152 | dw fake_02181A 153 | dw fake_02181B 154 | dw fake_02181C 155 | dw fake_02181D 156 | dw fake_02181E 157 | dw fake_02181F 158 | 159 | dw fake_027C20 160 | dw fake_027C21 161 | dw fake_027C22 162 | 163 | fake_000000: tii sector000000 + $0000,f32_cache_buf,512 164 | rts 165 | fake_000800: tii sector000800 + $0000,f32_cache_buf,512 166 | rts 167 | fake_000AB6: tii sector000AB6 + $0000,f32_cache_buf,512 168 | rts 169 | fake_000AB7: tii sector000AB6 + $0200,f32_cache_buf,512 170 | rts 171 | fake_002000: tii sector002000 + $0000,f32_cache_buf,512 172 | rts 173 | fake_002800: tii sector002800 + $0000,f32_cache_buf,512 174 | rts 175 | 176 | fake_002850: tii sector002850 + $0000,f32_cache_buf,512 177 | rts 178 | fake_002851: tii sector002850 + $0200,f32_cache_buf,512 179 | rts 180 | 181 | fake_020BC8: tii sector020BC8 + $0000,f32_cache_buf,512 182 | rts 183 | fake_020BC9: tii sector020BC8 + $0200,f32_cache_buf,512 184 | rts 185 | 186 | fake_021818: tii sector021818 + $0000,f32_cache_buf,512 187 | rts 188 | fake_021819: tii sector021818 + $0200,f32_cache_buf,512 189 | rts 190 | fake_02181A: tii sector021818 + $0400,f32_cache_buf,512 191 | rts 192 | fake_02181B: tii sector021818 + $0600,f32_cache_buf,512 193 | rts 194 | fake_02181C: tii sector021818 + $0800,f32_cache_buf,512 195 | rts 196 | fake_02181D: tii sector021818 + $0A00,f32_cache_buf,512 197 | rts 198 | fake_02181E: tii sector021818 + $0C00,f32_cache_buf,512 199 | rts 200 | fake_02181F: tii sector021818 + $0E00,f32_cache_buf,512 201 | rts 202 | 203 | fake_027C20: tii sector027C20 + $0000,f32_cache_buf,512 204 | rts 205 | fake_027C21: tii sector027C20 + $0200,f32_cache_buf,512 206 | rts 207 | fake_027C22: tii sector027C20 + $0400,f32_cache_buf,512 208 | rts 209 | 210 | ; 211 | ; 212 | ; 213 | 214 | sector000000: incbin "fake/sector00000000.bin" ; (1) MBR 215 | sector000800: incbin "fake/sector00000800.bin" ; (1) FAT32 BPB 216 | sector000AB6: incbin "fake/sector00000AB6.bin" ; (2) FAT for A-C directory 217 | 218 | ;sector000000: incbin "fake/t32-s000000.bin" ; (1) MBR 219 | sector002000: incbin "fake/t32-s002000.bin" ; (1) MBR 220 | 221 | 222 | .bank 8 223 | .org $6000 224 | 225 | sector002800: incbin "fake/sector00002800.bin" ; (1) Root directory 226 | sector002850: incbin "fake/sector00002850.bin" ; (2) SuperGrafx directory 227 | sector020BC8: incbin "fake/sector00020BC8.bin" ; (2) Japan directory 228 | sector021818: incbin "fake/sector00021818.bin" ; (8) A-C directory 1st 229 | sector027C20: incbin "fake/sector00027C20.bin" ; (3) A-C directory 2nd 230 | 231 | endif 232 | -------------------------------------------------------------------------------- /filefuncs.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; filefuncs.s 5 | ; 6 | ; File loading and saving. 7 | ; 8 | ; Copyright John Brandwood 2019. 9 | ; 10 | ; Distributed under the Boost Software License, Version 1.0. 11 | ; (See accompanying file LICENSE_1_0.txt or copy at 12 | ; http://www.boost.org/LICENSE_1_0.txt) 13 | ; 14 | ; *************************************************************************** 15 | ; *************************************************************************** 16 | 17 | 18 | 19 | ; *************************************************************************** 20 | ; *************************************************************************** 21 | ; 22 | ; tos_chdir_tbed - Change to the "/TBED/" directory. 23 | ; 24 | ; Uses: __bp = Pointer to directory entry in cache. 25 | ; 26 | ; Returns: X = F32_OK (and Z flag) or an error code. 27 | ; 28 | 29 | tos_chdir_tbed: jsr f32_select_root ; Start back at the root. 30 | bne .exit 31 | 32 | lda #<.filename ; Locate the 'TBED' folder. 33 | ldy #>.filename 34 | sta <__ax + 0 35 | sty <__ax + 1 36 | jsr f32_find_name 37 | bne .exit 38 | 39 | jmp f32_change_dir 40 | 41 | .exit: rts 42 | 43 | .filename: db "TBED",0 44 | 45 | 46 | 47 | ; *************************************************************************** 48 | ; *************************************************************************** 49 | ; 50 | ; tos_slot_file - 51 | ; 52 | ; Args: tos_bram_slot = Slot #. 53 | ; Uses: __bp = Pointer to directory entry in cache. 54 | ; 55 | ; Returns: X = F32_OK (and Z flag) or an error code. 56 | ; 57 | 58 | tos_slot_file: jsr tos_chdir_tbed ; Select "/TBED/" directory. 59 | bne .exit 60 | 61 | lda tos_bram_slot ; Divide slot # by 10. 62 | inc a 63 | sta <__ax + 0 64 | stz <__ax + 1 65 | lda #10 66 | sta <__cl 67 | jsr tos_div16_7u 68 | 69 | lda <__al ; Dividend. 70 | clc 71 | adc #'0' 72 | sta .filename + 5 73 | lda <__dl ; Remainder. 74 | clc 75 | adc #'0' 76 | sta .filename + 6 77 | 78 | lda #<.filename 79 | ldy #>.filename 80 | sta <__ax + 0 81 | sty <__ax + 1 82 | jsr f32_find_name ; Locate the named file in 83 | bne .exit ; the current directory. 84 | 85 | jsr f32_open_file ; Open the file. 86 | bne .exit 87 | 88 | ldx #TOS_WRONG_SIZE 89 | 90 | lda f32_file_length + 1 ; Check that the file is 2KB. 91 | cmp #$08 92 | bne .close 93 | lda f32_file_length + 3 94 | ora f32_file_length + 2 95 | ora f32_file_length + 0 96 | bne .close 97 | 98 | lda #2048 / 512 99 | sta <__ax + 0 ; Lo-byte of # blocks in file. 100 | stz <__ax + 1 ; Hi-byte of # blocks in file. 101 | 102 | stz .filename 188 | sta <__ax + 0 189 | sty <__ax + 1 190 | jsr f32_find_name ; Locate the named file in 191 | bne .exit ; the current directory. 192 | 193 | jsr f32_open_file ; Open the file. 194 | bne .exit 195 | 196 | ldx #TOS_WRONG_SIZE 197 | 198 | lda f32_file_length + 2 ; Check that the file is 128KB. 199 | cmp #$02 200 | bne .close 201 | lda f32_file_length + 3 202 | ora f32_file_length + 1 203 | ora f32_file_length + 0 204 | bne .close 205 | 206 | stz <__ax + 0 ; Lo-byte of # blocks in file. 207 | lda #>(131072 / 512) 208 | sta <__ax + 1 ; Hi-byte of # blocks in file. 209 | 210 | lda #$4F ; Map in TED2 512KB bank 4. 211 | sta sdc_data_bank 212 | 213 | stz %p5%xl",0 41 | db "%x",0 42 | db "%y",0 43 | db " TENNOKOE SD: Copy BACKUP RAM to SD " 44 | db "%<%p0",$0A,$0A,$0A,0 45 | 46 | cls_swap_bram: db $0C 47 | msg_swap_bram: db "%>%p5%xl",0 48 | db "%x",0 49 | db "%y",0 50 | db " TENNOKOE SD: Swap BACKUP RAM with SD " 51 | db "%<%p0",$0A,$0A,$0A,0 52 | 53 | cls_copy_slot: db $0C 54 | msg_copy_slot: db "%>%p5%xl",0 55 | db "%x",0 56 | db "%y",0 57 | db " TENNOKOE SD: Copy SD to BACKUP RAM " 58 | db "%<%p0",$0A,$0A,$0A,0 59 | 60 | cls_wipe_file: db $0C 61 | msg_wipe_file: db "%>%p5%xl",0 62 | db "%x",0 63 | db "%y",0 64 | ; db "----------------------------------------" 65 | db " TENNOKOE SD: Delete file in BACKUP RAM " 66 | db "%<%p0",$0A,$0A,$0A,0 67 | 68 | ; 69 | ; 70 | ; 71 | 72 | msg_bram_lhs: db "%<%xl",0 73 | 74 | db "%y",2 75 | db "%x",1 76 | db "%b",18,19,0 77 | 78 | db "%p3" 79 | db "%y",3 80 | db "%x",2 81 | db " Name Size" 82 | 83 | db "%x",1 84 | db "%y",21 85 | db "%p0" 86 | db "%p2" 87 | db "%>Console %<" 88 | db "%p2" 89 | db "%r" 90 | dw tos_bram_files + 0 91 | db "Files: %3hu",$0A 92 | db "%r" 93 | dw tos_bram_free + 0 94 | db "%x",9 95 | db "%y",22 96 | db "Free: %4u" 97 | db "%xl",2 98 | db "%x",2 99 | db "%y",4 100 | db "%p0%>",0 101 | 102 | ; 103 | ; 104 | ; 105 | 106 | msg_bram_rhs: db "%<%xl",0 107 | 108 | db "%y",2 109 | db "%x",21 110 | db "%b",18,19,0 111 | 112 | db "%p3" 113 | db "%y",3 114 | db "%x",22 115 | db " Name Size" 116 | 117 | db "%x",21 118 | db "%y",21 119 | db "%p2" 120 | db "%r" 121 | dw tos_bram_slot 122 | ; db "%>Slot %02hu %<" 123 | db "%>Slot #%hu %<" 124 | db "%r" 125 | dw tos_bram_files + 2 126 | db "Files: %3hu",$0A 127 | db "%r" 128 | dw tos_bram_free + 2 129 | db "%x",29 130 | db "%y",22 131 | db "Free: %4u" 132 | db "%xl",22 133 | db "%x",22 134 | db "%y",4 135 | db "%p0%>",0 136 | 137 | ; 138 | ; 139 | ; 140 | 141 | tbl_bram_help: dw hlp_copy_bram ; Help if box is selected. 142 | dw hlp_swap_bram 143 | dw hlp_copy_slot 144 | dw hlp_wipe_file 145 | 146 | hlp_copy_bram: db "%<%p5%xl",0 147 | db "%x",0 148 | db "%y",24 149 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Slot%p5 \\|%p6:Scroll %p5",$0A 150 | db " " 151 | db 30,31 152 | db "%p6:Chg Mode%p5" 153 | db " " 154 | db 28,29 155 | db "%p6:Copy BRAM to Slot %p5",$0A 156 | db "%y",23 157 | db "%p0" 158 | 159 | db "%xl",19 160 | db "%x",19 161 | db "%y",3 162 | db ">>",$0A 163 | db ">>",$0A 164 | db ">>",$0A 165 | db ">>",$0A 166 | db ">>",$0A 167 | db ">>",$0A 168 | db ">>",$0A 169 | db ">>",$0A 170 | db ">>",$0A 171 | db ">>",$0A 172 | db ">>",$0A 173 | db ">>",$0A 174 | db ">>",$0A 175 | db ">>",$0A 176 | db ">>",$0A 177 | db ">>",$0A 178 | db ">>",$0A 179 | 180 | db 0 181 | 182 | ; 183 | 184 | hlp_swap_bram: db "%<%p5%xl",0 185 | db "%x",0 186 | db "%y",24 187 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Slot%p5 \\|%p6:Scroll %p5",$0A 188 | db " " 189 | db 30,31 190 | db "%p6:Chg Mode%p5" 191 | db " " 192 | db 28,29 193 | db "%p6:Swap BRAM with Slot %p5",$0A 194 | db "%y",23 195 | db "%p0" 196 | 197 | db "%xl",19 198 | db "%x",19 199 | db "%y",3 200 | db "><",$0A 201 | db "><",$0A 202 | db "><",$0A 203 | db "><",$0A 204 | db "><",$0A 205 | db "><",$0A 206 | db "><",$0A 207 | db "><",$0A 208 | db "><",$0A 209 | db "><",$0A 210 | db "><",$0A 211 | db "><",$0A 212 | db "><",$0A 213 | db "><",$0A 214 | db "><",$0A 215 | db "><",$0A 216 | db "><",$0A 217 | 218 | db 0 219 | 220 | ; 221 | 222 | hlp_copy_slot: db "%<%p5%xl",0 223 | db "%x",0 224 | db "%y",24 225 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Slot%p5 \\|%p6:Scroll %p5",$0A 226 | db " " 227 | db 30,31 228 | db "%p6:Chg Mode%p5" 229 | db " " 230 | db 28,29 231 | db "%p6:Copy Slot to BRAM %p5",$0A 232 | db "%y",23 233 | db "%p0" 234 | 235 | db "%xl",19 236 | db "%x",19 237 | db "%y",3 238 | db "<<",$0A 239 | db "<<",$0A 240 | db "<<",$0A 241 | db "<<",$0A 242 | db "<<",$0A 243 | db "<<",$0A 244 | db "<<",$0A 245 | db "<<",$0A 246 | db "<<",$0A 247 | db "<<",$0A 248 | db "<<",$0A 249 | db "<<",$0A 250 | db "<<",$0A 251 | db "<<",$0A 252 | db "<<",$0A 253 | db "<<",$0A 254 | db "<<",$0A 255 | 256 | db 0 257 | 258 | ; 259 | 260 | hlp_wipe_file: db "%<%p5%xl",0 261 | db "%x",0 262 | db "%y",24 263 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Slot%p5 \\|%p6:Chg File%p5",$0A 264 | db " " 265 | db 30,31 266 | db "%p6:Chg Mode%p5" 267 | db " " 268 | db 28,29 269 | db "%p6:Delete File from BRAM %p5",$0A 270 | db "%y",23 271 | db "%p0" 272 | ; db "----------------------------------------" 273 | ; db " ------------------ ",0 274 | db 0 275 | 276 | ; 277 | ; 278 | ; 279 | 280 | msg_bram_name: db "%10c %r" 281 | dw tos_temp_length 282 | db "%4u",$0A,$0A,0 283 | 284 | msg_small_index:db "%-2hu",0 285 | msg_large_index:db "%02hu",0 286 | 287 | msg_bram_larrow:db $1C,0 288 | msg_bram_rarrow:db $1D,0 289 | 290 | msg_bram_space: db " ",0 291 | 292 | msg_bram_spaces:db " " 293 | db " ",$0A,$0A,0 294 | 295 | msg_blank_rhs: db "%<%xl",0 296 | 297 | db "%y",2 298 | db "%x",19 299 | db "%p0" 300 | db "%b",20,21,1 301 | 302 | db "%p0%>",0 303 | 304 | ; 305 | ; 306 | ; 307 | 308 | bss 309 | 310 | tos_bram_slot: ds 1 311 | tos_bram_mode: ds 1 312 | tos_bram_focus: ds 1 ; Which side is focused? 313 | 314 | tos_bram_files: ds 2*2 ; # of files on LHS/RHS. 315 | tos_bram_least: ds 2*2 ; Minimum LHS/RHS file choice. 316 | tos_bram_chosen:ds 2*2 ; Current LHS/RHS file choice. 317 | tos_bram_free: ds 2*2 ; BRAM unused on LHS/RHS. 318 | 319 | tos_bram_first: ds 1 320 | tos_bram_choice:ds 1 321 | tos_bram_index: ds 1 322 | tos_bram_hilite:ds 1 323 | 324 | tos_bram_fname: ds 2 ; Ptr to selected name in BRAM. 325 | 326 | tos_temp_index: ds 1 327 | tos_temp_length:ds 2 328 | 329 | code 330 | 331 | 332 | 333 | ; *************************************************************************** 334 | ; *************************************************************************** 335 | ; 336 | ; tos_bram_menu - TENNOKOE SD menu. 337 | ; 338 | 339 | tos_bram_menu: stz tos_bram_mode 340 | stz tos_bram_slot 341 | 342 | jsr bm_exists ; Skip if there is no BRAM. 343 | beq tos_bram_menu2 344 | 345 | jmp tos_info_menu 346 | 347 | tos_bram_menu2: jsr clear_screen 348 | 349 | ; PUTS msg_bram_title 350 | 351 | ; Verify contents of BRAM_BANK. 352 | 353 | lda #BRAM_BANK 354 | tam3 355 | 356 | jsr bm_bram_to_bank 357 | 358 | jsr bm_verify_mpr3 ; Verify the BRAM image. 359 | beq .bram_info ; Is it OK? 360 | bmi .bram_format ; Is it unformatted? 361 | 362 | jmp tos_info_menu ; Wierd size or corrupt. 363 | 364 | .bram_format: jsr bm_format_mpr3 ; Blank the slot. 365 | 366 | .bram_info: ldx #0 ; Save BRAM info. 367 | jsr tos_bram_info 368 | 369 | ; Verify contents of SLOT_BANK. 370 | 371 | .new_slot: stz tos_hilite_idx ; Reset hilite pulsing. 372 | 373 | lda #SLOT_BANK 374 | tam3 375 | 376 | if REALHW 377 | 378 | jsr tos_load_slot ; Load the file data. 379 | beq .got_slot 380 | 381 | jsr bm_format_mpr3 ; Blank the slot. 382 | 383 | else 384 | 385 | tma2 386 | pha 387 | lda #BANK(fake_bram1) 388 | tam2 389 | 390 | tii fake_bram1,$6000,$800 391 | 392 | pla 393 | tam2 394 | 395 | endif 396 | 397 | .got_slot: jsr bm_verify_mpr3 ; Verify the BRAM image. 398 | beq .slot_info ; Is it OK? 399 | 400 | jsr bm_format_mpr3 ; Blank the slot. 401 | 402 | .slot_info: ldx #2 ; Save BRAM info. 403 | jsr tos_bram_info 404 | 405 | ; Has the mode just changed? 406 | 407 | .new_mode: ldx tos_bram_mode ; Lookup which side has focus. 408 | lda .tbl_focus_side,x 409 | sta tos_bram_focus 410 | lda .tbl_min_choice,x ; Lookup minimum selection. 411 | sta tos_bram_least + 0 ; Set minimum selection. 412 | sta tos_bram_least + 2 413 | sta tos_bram_chosen + 0 ; Set current selection. 414 | sta tos_bram_chosen + 2 415 | 416 | cpx #BRAM_DEL ; Delete File mode? 417 | beq .show_title 418 | 419 | ldx #2 420 | .calc_minimum: lda #8 ; Start at the last file 421 | cmp tos_bram_files,x ; shown on the screen so 422 | bcc .set_minimum ; scrolling is immediate. 423 | lda tos_bram_files,x 424 | .set_minimum: sta tos_bram_least,x ; Set minimum selection. 425 | sta tos_bram_chosen,x ; Set current selection. 426 | dex 427 | dex 428 | bpl .calc_minimum 429 | 430 | .show_title: lda tos_bram_mode ; Lookup which title to display. 431 | asl a 432 | tay 433 | ldx tbl_bram_title + 0,y 434 | lda tbl_bram_title + 1,y 435 | jsr tos_print_msg 436 | 437 | ; Redraw the menu screen to reflect changes. 438 | 439 | .show_help: ldx tos_bram_mode ; Lookup which help to display. 440 | ldy .tbl_focus_side,x ; Is there a file selected on 441 | lda tos_bram_chosen,y ; the side that has focus? 442 | sax 443 | ; beq .lookup_help 444 | ; clc ; If so, use 2nd set of help 445 | ; adc #4 ; messages. 446 | .lookup_help: asl a 447 | tay 448 | ldx tbl_bram_help + 0,y 449 | lda tbl_bram_help + 1,y 450 | jsr tos_print_msg 451 | 452 | ; Display contents of BRAM_BANK. 453 | 454 | .show_bram: ldx tos_bram_mode 455 | cpx #BRAM_DEL 456 | bne .bram_box_color 457 | 458 | stz tos_hilite_idx ; Reset hilite pulsing. 459 | 460 | .bram_box_color:lda .tbl_box_lhs,x 461 | jsr tos_set_pen 462 | 463 | PUTS msg_bram_lhs 464 | 465 | lda #BRAM_BANK 466 | tam3 467 | 468 | ldx #0 469 | jsr tos_bram_show 470 | 471 | ; Display contents of SLOT_BANK. 472 | 473 | lda tos_bram_mode 474 | cmp #BRAM_DEL 475 | bne .show_slot 476 | 477 | PUTS msg_blank_rhs 478 | bra .wait_input 479 | 480 | .show_slot: ldx tos_bram_mode 481 | lda .tbl_box_rhs,x 482 | jsr tos_set_pen 483 | 484 | inc tos_bram_slot ; Show slot from '1' not '0'. 485 | PUTS msg_bram_rhs 486 | dec tos_bram_slot 487 | 488 | lda #SLOT_BANK 489 | tam3 490 | 491 | ldx #2 492 | jsr tos_bram_show 493 | 494 | ; 495 | 496 | .wait_input: stz joytrg 497 | .wait_loop: jsr wait_vsync_usb ; Wait, but check for USB. 498 | lda joytrg 499 | beq .wait_loop 500 | 501 | bit #JOY_SEL 502 | beq .same_menu 503 | jmp tos_info_menu 504 | 505 | .same_menu: bit #JOY_L 506 | bne .prev_slot 507 | bit #JOY_R 508 | bne .next_slot 509 | bit #JOY_U 510 | bne .prev_file 511 | bit #JOY_D 512 | bne .next_file 513 | bit #JOY_B1 514 | bne .select 515 | 516 | .back_only: bit #JOY_B2 517 | beq .wait_input 518 | ; jmp .chg_mode 519 | 520 | ; Change Mode. 521 | 522 | lda tos_bram_mode 523 | inc a 524 | and #3 525 | sta tos_bram_mode 526 | jmp .new_mode 527 | 528 | ; Change Save Slot. 529 | 530 | .prev_slot: lda tos_bram_slot 531 | dec a 532 | and #7 533 | sta tos_bram_slot 534 | jmp .new_slot 535 | 536 | .next_slot: lda tos_bram_slot 537 | inc a 538 | and #7 539 | sta tos_bram_slot 540 | jmp .new_slot 541 | 542 | ; Change Selected File. 543 | 544 | .prev_file: clx 545 | ldy #2 546 | .prev_loop: lda tos_bram_chosen,x ; Already at minimum selection? 547 | cmp tos_bram_least,x 548 | bne .check_other 549 | ; lda tos_bram_files,x ; Wrap around to end selection. 550 | bra .set_prev_file 551 | .check_other: cmp tos_bram_chosen,y ; Is the other side on a higher 552 | bcc .set_prev_file ; selection? 553 | dec a 554 | .set_prev_file: pha 555 | sxy 556 | txa 557 | bne .prev_loop 558 | .changed_choice:pla 559 | sta tos_bram_chosen + 2 560 | pla 561 | sta tos_bram_chosen + 0 562 | jmp .show_bram 563 | 564 | .next_file: clx 565 | ldy #2 566 | .next_loop: lda tos_bram_chosen,x ; Already at maximum selection? 567 | cmp tos_bram_files,x 568 | bne .inc_next_file 569 | lda tos_bram_chosen,y ; Is the other side on maximum? 570 | cmp tos_bram_files,y 571 | ; lda tos_bram_least,x ; Wrap around to 1st selection. 572 | ; bcs .set_next_file 573 | lda tos_bram_chosen,x ; Else stay on current choice. 574 | dec a 575 | .inc_next_file: inc a 576 | .set_next_file: pha 577 | sxy 578 | txa 579 | bne .next_loop 580 | bra .changed_choice 581 | 582 | .select: lda tos_bram_mode 583 | asl a 584 | tax 585 | jsr .vector 586 | jmp tos_bram_menu2 587 | 588 | .vector: jmp [.tbl_funcs,x] 589 | 590 | .tbl_funcs: dw func_bram_save 591 | dw func_bram_swap 592 | dw func_bram_load 593 | dw func_bram_del 594 | 595 | .tbl_box_lhs: db 1,1,0,0 ; Palette for box per mode. 596 | .tbl_box_rhs: db 0,1,1,0 ; Palette for box per mode. 597 | .tbl_focus_side:db 0,4,2,0 ; Focused side per mode. 598 | .tbl_min_choice:db 0,0,0,1 ; Minimum choice per mode. 599 | 600 | 601 | 602 | ; *************************************************************************** 603 | ; *************************************************************************** 604 | ; 605 | ; tos_bram_info - Save the info after a verify for later display. 606 | ; 607 | ; N.B. There can be a maximum of 126 files in the 2KB of BRAM. 608 | ; 609 | 610 | tos_bram_info: lda <__bl ; Are there any BRAM files? 611 | sta tos_bram_files + 0,x 612 | stz tos_bram_files + 1,x 613 | bne .calc 614 | 615 | ldy #<2030 ; If not, then maximum free. 616 | lda #>2030 617 | bra .save 618 | 619 | .calc: sec ; Calc amount of free memory. 620 | lda #<($6800 - $02) 621 | sbc <__bp + 0 622 | tay 623 | lda #>($6800 - $02) 624 | sbc <__bp + 1 625 | bcs .save 626 | 627 | cla ; No memory free. 628 | cly 629 | 630 | .save: sta tos_bram_free + 1,x ; Save amount of free memory. 631 | tya 632 | sta tos_bram_free + 0,x 633 | 634 | rts 635 | 636 | 637 | 638 | ; *************************************************************************** 639 | ; *************************************************************************** 640 | ; 641 | ; tos_bram_show - Display the BRAM files in the current bank. 642 | ; 643 | ; N.B. There can be a maximum of 126 files in the 2KB of BRAM. 644 | ; 645 | 646 | tos_bram_show: lda tos_bram_chosen,x ; Decide which file to display 647 | sta tos_bram_choice ; at the top of the box. 648 | sec 649 | sbc #7 650 | bcs .first_to_show 651 | lda #1 652 | .first_to_show: sta tos_bram_first 653 | 654 | .test_focus: lda #1 655 | sta tos_bram_hilite ; Set hilite color to pulsing. 656 | 657 | lda tos_bram_mode ; Only hilite a file in Delete. 658 | cmp #$3 659 | beq .first_in_bram 660 | 661 | stz tos_bram_hilite ; Set hilite color to normal. 662 | stz tos_bram_choice ; Do not hilite any file. 663 | 664 | .first_in_bram: ldy #<$6010 ; Start after the BRAM signature. 665 | lda #>$6010 666 | 667 | stz tos_bram_index 668 | 669 | .file_loop: inc tos_bram_index ; Increment file index. 670 | 671 | sty <__bp + 0 ; Update file pointer. 672 | sta <__bp + 1 673 | 674 | ldy #1 ; End of file chain? 675 | lda [__bp],y 676 | sta tos_temp_length + 1 ; Size to display (hi-byte). 677 | tay 678 | ora [__bp] 679 | bne .not_eof 680 | 681 | .bram_corrupt: nop 682 | 683 | jmp .rest ; EOF, remaining slots blank. 684 | 685 | .not_eof: lda [__bp] 686 | sta tos_temp_length + 0 ; Size to display (lo-byte). 687 | .too_small: cmp #$10 ; Size < $0010 (min size)? 688 | bcs .too_large 689 | cpy #$00 690 | beq .bram_corrupt 691 | .too_large: cpy #$20 ; Size > $1FFF (max size)? 692 | bcs .bram_corrupt 693 | 694 | clc ; Calc address of next file. 695 | adc <__bp + 0 696 | say 697 | adc <__bp + 1 698 | cmp #$68 ; Is it beyond BRAM Size? 699 | bcs .bram_corrupt 700 | 701 | ldx tos_bram_index ; Skip off-screen files. 702 | cpx tos_bram_first 703 | bcc .file_loop 704 | 705 | phy ; Preserve next file pointer. 706 | pha 707 | 708 | cla ; Select the palette to use 709 | ldx tos_bram_index ; for this file entry. 710 | cpx tos_bram_choice 711 | bne .file_color 712 | lda tos_bram_hilite 713 | .file_color: jsr tos_set_pen 714 | 715 | if 0 716 | 717 | ldx #msg_small_index 719 | 720 | lda tos_bram_index 721 | cmp #100 722 | bcc .show_index 723 | sbc #100 724 | 725 | ldx #msg_large_index 727 | 728 | .show_index: sta tos_temp_index ; Truncated to 2 digits. 729 | 730 | lda #tos_temp_index 733 | sta <__di + 1 734 | 735 | ; tya 736 | ; jsr tos_print_msg 737 | 738 | endif 739 | 740 | ldx #msg_bram_space 742 | 743 | lda tos_bram_index 744 | cmp tos_bram_choice 745 | bne .show_lhs_arrow 746 | 747 | ldx #msg_bram_larrow 749 | 750 | .show_lhs_arrow:tya 751 | jsr tos_print_msg 752 | 753 | .file_name: lda #$06 ; Display the file name & size. 754 | clc 755 | adc <__bp + 0 756 | sta <__di + 0 757 | tax 758 | cla 759 | adc <__bp + 1 760 | sta <__di + 1 761 | tay 762 | 763 | lda tos_tty_tile + 1 ; Is this entry in the hilite 764 | and #$F0 ; color? 765 | beq .show_name 766 | 767 | stx tos_bram_fname + 0 ; Save the addr of the selected 768 | sty tos_bram_fname + 1 ; filename. 769 | 770 | .show_name: PUTS msg_bram_name 771 | 772 | pla ; Restore next file pointer. 773 | ply 774 | 775 | ldx tos_tty_ypos ; Display the rest of the 776 | cpx #20 ; BRAM files in the box. 777 | bcs .done 778 | 779 | jmp .file_loop 780 | 781 | .rest: lda tos_tty_ypos ; Blank out the rest of the 782 | cmp #20 ; BRAM files in the box. 783 | bcs .done 784 | 785 | PUTS msg_bram_spaces 786 | bra .rest 787 | 788 | .done: rts 789 | 790 | 791 | 792 | ; *************************************************************************** 793 | ; *************************************************************************** 794 | ; 795 | ; func_bram_save - Copy BRAM to SD card slot. 796 | ; 797 | 798 | func_bram_save: PUTS cls_copy_bram ; Confirm the operation. 799 | inc tos_bram_slot ; Show slot from '1' not '0'. 800 | PUTS .msg_warning 801 | dec tos_bram_slot 802 | 803 | .wait_input: stz joytrg ; Wait for input. 804 | .wait_loop: jsr wait_vsync_usb 805 | lda joytrg 806 | beq .wait_loop 807 | bit #JOY_RUN 808 | bne .confirmed 809 | bit #JOY_B2 810 | beq .wait_input 811 | rts 812 | 813 | .confirmed: PUTS cls_copy_bram ; Inform the user. 814 | PUTS msg_save_bram 815 | 816 | tma2 ; Copy the contents of BRAM 817 | pha ; to the SLOT image in memory. 818 | lda #BRAM_BANK 819 | tam2 820 | lda #SLOT_BANK 821 | tam3 822 | tii $4000, $6000, 2048 823 | pla 824 | tam2 825 | 826 | jsr tos_save_slot ; Save the SLOT image to SD. 827 | beq .finished 828 | 829 | .failed: PUTS msg_fail_bram 830 | 831 | .result: PUTS msg_press_a_key 832 | jsr wait_for_key 833 | 834 | .finished: rts 835 | 836 | .msg_warning: db "%r" 837 | dw tos_bram_slot 838 | db "%y",11 839 | db " Please press %p1RUN%p0 to confirm that you",$0A 840 | db " want to copy BRAM to SD Slot #%hu!",$0A 841 | db "%y",24 842 | db "%x",12 843 | db "%p5RUN%p6:Confirm copy",$0A 844 | db "%x",13 845 | db "%p5",30,31,"%p6:Cancel copy",$0A 846 | db "%p0%y",14,0 847 | 848 | msg_save_bram: db " Saving BRAM to SD card ...",$0A,$0A,0 849 | msg_fail_bram: db " BRAM save failed!",$0A,$0A,0 850 | 851 | 852 | 853 | ; *************************************************************************** 854 | ; *************************************************************************** 855 | ; 856 | ; func_bram_swap - Swap BRAM with SD card slot. 857 | ; 858 | 859 | func_bram_swap: PUTS cls_swap_bram 860 | inc tos_bram_slot ; Show slot from '1' not '0'. 861 | PUTS .msg_warning 862 | dec tos_bram_slot 863 | 864 | .wait_input: stz joytrg ; Wait for input. 865 | .wait_loop: jsr wait_vsync_usb 866 | lda joytrg 867 | beq .wait_loop 868 | bit #JOY_RUN 869 | bne .confirmed 870 | bit #JOY_B2 871 | beq .wait_input 872 | rts 873 | 874 | .confirmed: PUTS cls_swap_bram ; Inform the user. 875 | PUTS msg_save_bram 876 | 877 | tma2 ; Swap the contents of BRAM 878 | pha ; to the SLOT image in memory. 879 | lda #BRAM_BANK 880 | tam2 881 | lda #SLOT_BANK 882 | tam3 883 | stz <__ax + 0 884 | stz <__bx + 0 885 | lda #$40 886 | sta <__ax + 1 887 | lda #$60 888 | sta <__bx + 1 889 | cly 890 | .swap_loop: lda [__ax],y 891 | tax 892 | lda [__bx],y 893 | sta [__ax],y 894 | txa 895 | sta [__bx],y 896 | iny 897 | bne .swap_loop 898 | inc <__ah 899 | inc <__bh 900 | bbr3 <__bh,.swap_loop 901 | pla 902 | tam2 903 | 904 | jsr tos_save_slot ; Save the SLOT image to SD. 905 | bne .failed 906 | 907 | lda #BRAM_BANK ; Copy the contents of BRAM 908 | tam3 ; image from memory to BRAM. 909 | jsr bm_bank_to_bram 910 | bra .finished 911 | 912 | .failed: PUTS msg_fail_bram 913 | 914 | .result: PUTS msg_press_a_key 915 | jsr wait_for_key 916 | 917 | .finished: rts 918 | 919 | .msg_warning: db "%r" 920 | dw tos_bram_slot 921 | db "%y",11 922 | db " Please press %p1RUN%p0 to confirm that you",$0A 923 | db " want to swap BRAM with SD Slot #%hu!",$0A 924 | db "%y",24 925 | db "%x",12 926 | db "%p5RUN%p6:Confirm swap",$0A 927 | db "%x",13 928 | db "%p5",30,31,"%p6:Cancel swap",$0A 929 | db "%p0%y",14,0 930 | 931 | 932 | 933 | ; *************************************************************************** 934 | ; *************************************************************************** 935 | ; 936 | ; func_bram_load - Copy SD card slot to BRAM. 937 | ; 938 | 939 | func_bram_load: PUTS cls_copy_slot 940 | inc tos_bram_slot ; Show slot from '1' not '0'. 941 | PUTS .msg_warning 942 | dec tos_bram_slot 943 | 944 | .wait_input: stz joytrg ; Wait for input. 945 | .wait_loop: jsr wait_vsync_usb 946 | lda joytrg 947 | beq .wait_loop 948 | bit #JOY_RUN 949 | bne .confirmed 950 | bit #JOY_B2 951 | beq .wait_input 952 | rts 953 | 954 | .confirmed: lda #SLOT_BANK ; Copy the contents of SLOT 955 | tam3 ; image from memory to BRAM. 956 | jsr bm_bank_to_bram 957 | 958 | rts 959 | 960 | .msg_warning: db "%r" 961 | dw tos_bram_slot 962 | db "%y",11 963 | db " Please press %p1RUN%p0 to confirm that you",$0A 964 | db " want to copy SD Slot #%hu to BRAM!",$0A 965 | db "%y",24 966 | db "%x",12 967 | db "%p5RUN%p6:Confirm copy",$0A 968 | db "%x",13 969 | db "%p5",30,31,"%p6:Cancel copy",$0A 970 | db "%p0%y",14,0 971 | 972 | 973 | 974 | ; *************************************************************************** 975 | ; *************************************************************************** 976 | ; 977 | ; func_bram_del - Delete a file from BRAM. 978 | ; 979 | 980 | func_bram_del: lda tos_bram_files ; Are there any files in BRAM? 981 | bne .wipe 982 | rts 983 | 984 | .wipe: PUTS cls_wipe_file 985 | 986 | lda tos_bram_fname + 0 ; Get the addr of the selected 987 | sta <__di + 0 ; filename. 988 | lda tos_bram_fname + 1 989 | sta <__di + 1 990 | 991 | PUTS .msg_warning 992 | 993 | .wait_input: stz joytrg ; Wait for input. 994 | .wait_loop: jsr wait_vsync_usb 995 | lda joytrg 996 | beq .wait_loop 997 | bit #JOY_RUN 998 | bne .confirmed 999 | bit #JOY_B2 1000 | beq .wait_input 1001 | rts 1002 | 1003 | .confirmed: lda #BRAM_BANK ; Wipe the file from the BRAM 1004 | tam3 ; image in memory. 1005 | 1006 | lda #$73 ; TII instruction. 1007 | sta <__al 1008 | lda #$60 ; RTS instruction. 1009 | sta <__dh 1010 | 1011 | .copy_data: sec ; Use the addr of the selected 1012 | lda tos_bram_fname + 0 ; filename as the destination. 1013 | sbc #6 1014 | sta <__bh + 0 1015 | lda tos_bram_fname + 1 1016 | sbc #0 1017 | sta <__bh + 1 1018 | 1019 | clc ; Use the addr of the next BRAM 1020 | cly ; file as the source. 1021 | lda [__bh],y 1022 | adc <__bh + 0 1023 | sta <__ah + 0 1024 | iny 1025 | lda [__bh],y 1026 | adc <__bh + 1 1027 | sta <__ah + 1 1028 | 1029 | sec ; Calc length from next free 1030 | lda $6006 ; addr in BRAM. 1031 | sbc <__ah + 0 1032 | sta <__ch + 0 1033 | lda $6007 1034 | sbc <__ah + 1 1035 | sbc #$20 ; Rebase from $8000 to $6000. 1036 | sta <__ch + 1 1037 | ora <__ch + 0 1038 | beq .fill_free 1039 | 1040 | jsr __al ; Execute TII instruction. 1041 | 1042 | .fill_free: clc ; The next free location is 1043 | lda <__ch + 0 ; destination + length. 1044 | adc <__bh + 0 1045 | sta <__bh + 0 1046 | sta $6006 1047 | lda <__ch + 1 1048 | adc <__bh + 1 1049 | sta <__bh + 1 1050 | adc #$20 ; Rebase from $8000 to $6000. 1051 | sta $6007 1052 | 1053 | sec ; Calc length from next free 1054 | lda $6004 ; to the end of BRAM. 1055 | sbc <__bh + 0 1056 | sta <__ch + 0 1057 | lda $6005 1058 | sbc <__bh + 1 1059 | sbc #$20 ; Rebase from $8000 to $6000. 1060 | sta <__ch + 1 1061 | 1062 | lda #$F3 ; TAI instruction. 1063 | sta <__al 1064 | lda #tos_zero 1067 | sta <__ah + 1 1068 | 1069 | jsr __al ; Execute TAI instruction. 1070 | 1071 | jsr bm_bank_to_bram ; Copy the contents of BRAM 1072 | bra .finished ; image from memory to BRAM. 1073 | 1074 | .result: PUTS msg_press_a_key 1075 | jsr wait_for_key 1076 | 1077 | .finished: rts 1078 | 1079 | .msg_warning: db "%y",11 1080 | db " Please press %p1RUN%p0 to confirm that you",$0A 1081 | ; db " want to delete the file from BRAM!",$0A 1082 | db " want to delete ",$22,"%p2%10c%p0",$22," from BRAM!",$0A 1083 | db "%y",24 1084 | db "%x",11 1085 | db "%p5RUN%p6:Confirm delete",$0A 1086 | db "%x",12 1087 | db "%p5",30,31,"%p6:Cancel delete",$0A 1088 | db "%p0%y",14,0 1089 | -------------------------------------------------------------------------------- /menu_hucard.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; menu_hucard.s 5 | ; 6 | ; TEOS Menu Screens 7 | ; 8 | ; Copyright John Brandwood 2019. 9 | ; 10 | ; Distributed under the Boost Software License, Version 1.0. 11 | ; (See accompanying file LICENSE_1_0.txt or copy at 12 | ; http://www.boost.org/LICENSE_1_0.txt) 13 | ; 14 | ; *************************************************************************** 15 | ; *************************************************************************** 16 | 17 | 18 | 19 | ; *************************************************************************** 20 | ; *************************************************************************** 21 | ; 22 | ; 23 | ; 24 | 25 | msg_main_title: db "%>%p5%xl",0 26 | db $0C 27 | db " RUN HuCARD" 28 | db "%<%p0" 29 | db $0A,$0A,$0A,0 30 | 31 | msg_main_help: db "%p5" 32 | db "%y",24 33 | 34 | if HIRES 35 | db "%x",9 ; 480 wide 36 | endif 37 | 38 | ; db "----------------------------------------" 39 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Page%p5 \\|%p6:Chg File%p5",$0A 40 | 41 | if HIRES 42 | db "%x",9 ; 480 wide 43 | endif 44 | 45 | db " " 46 | db 30,31 47 | ; db "%p6:Parent%p5 I%p6:Select%p5",$0A 48 | 49 | db "%p6:Parent%p5 " 50 | db 28,29 51 | db "%p6:Select File or Folder%p5",$0A,0 52 | 53 | msg_main_pageno:db "%p5" 54 | db "%y",1 55 | 56 | if HIRES 57 | db "%x",26+18 ; 480 wide 58 | else 59 | db "%x",26 ; 320 wide 60 | endif 61 | 62 | db "%s" 63 | db "%r" 64 | dw tos_show_page 65 | db "%hu of " 66 | db "%r" 67 | dw tos_num_pages 68 | db "%hu" 69 | db "%p0" 70 | db $0A,$0A,0 71 | 72 | str_page: db " Page ",0 73 | 74 | msg_empty_dir: db "%p2 This directory is empty!%p0",0 75 | 76 | ; 77 | ; 78 | ; 79 | 80 | tos_hucard_menu: 81 | if HIRES 82 | ldx #video_mode_480 84 | jsr tos_screen_mode 85 | endif 86 | 87 | PUTS msg_main_title 88 | PUTS msg_main_help 89 | 90 | jsr f32_clear_cache ; Don't assume that it's valid! 91 | 92 | ldx #15 ; Is this the same SDcard as 93 | .cmp_sdcard: lda sdc_cid_value,x ; the last time? 94 | cmp tos_cur_cardid,x 95 | bne .new_sdcard 96 | dex 97 | bpl .cmp_sdcard 98 | 99 | .old_sdcard: tii tos_cur_folder, f32_dir_cluster, 4 100 | bra .new_directory 101 | 102 | .new_sdcard: tii sdc_cid_value, tos_cur_cardid, 16 103 | 104 | stz tos_cur_depth 105 | tai tos_zero, tos_cur_page, (tos_cur_file - tos_cur_page) * 2 106 | 107 | jsr f32_select_root ; New card resets to root dir. 108 | 109 | .new_directory: tii f32_dir_cluster, tos_cur_folder, 4 110 | 111 | jsr tos_scan_dir ; Find selectable entries. 112 | 113 | .new_page: lda #FILES_PER_PAGE ; Calc file index of the 1st 114 | sta <__bl ; entry on this page. 115 | ldx tos_cur_depth 116 | lda tos_cur_page,x 117 | sta <__al 118 | stz <__ah 119 | jsr tos_mul8u 120 | 121 | jsr tos_fastfwd_dir ; Skip the directory forward. 122 | 123 | ldx tos_cur_depth ; Get the current page # to 124 | lda tos_cur_page,x ; show onscreen. 125 | ldy tos_num_pages 126 | beq .skip0 127 | inc a 128 | .skip0: sta tos_show_page ; Move where "Page" is shown 129 | cmp #10 ; depending upon if either 130 | lda #str_page ; digits. 132 | bcc .skip1 133 | inc a 134 | bne .skip1 135 | inx 136 | .skip1: cpy #10 137 | bcc .skip2 138 | inc a 139 | bne .skip2 140 | inx 141 | .skip2: sta <__di + 0 142 | stx <__di + 1 143 | 144 | ; PUTS msg_main_title 145 | ; PUTS msg_main_help 146 | PUTS msg_main_pageno 147 | 148 | ldx tos_num_pages ; Any files in this directory? 149 | beq .empty_dir 150 | 151 | jsr tos_show_files ; Display the page of files. 152 | 153 | ldx tos_cur_depth ; Make sure that the selection 154 | lda tos_cur_file,x ; is available on this page. 155 | cmp tos_num_files 156 | bcc .selection_ok 157 | lda tos_num_files 158 | dec a 159 | sta tos_cur_file,x 160 | .selection_ok: jsr tos_set_hilite 161 | 162 | .new_file: bra .wait_input 163 | 164 | .empty_dir: PUTS msg_empty_dir 165 | 166 | .wait_input: stz joytrg 167 | .wait_loop: jsr wait_vsync_usb ; Wait, but check for USB. 168 | 169 | lda joytrg 170 | beq .wait_loop 171 | 172 | bit #JOY_SEL 173 | beq .same_menu 174 | 175 | if HIRES 176 | ldx #video_mode_320 178 | jsr tos_screen_mode 179 | endif 180 | 181 | jmp tos_bram_menu 182 | 183 | .same_menu: ldx tos_num_pages 184 | beq .back_only 185 | 186 | bit #JOY_L 187 | bne .prev_page 188 | bit #JOY_R 189 | bne .next_page 190 | bit #JOY_U 191 | bne .prev_file 192 | bit #JOY_D 193 | bne .next_file 194 | bit #JOY_B1 195 | bne .select 196 | 197 | .back_only: bit #JOY_B2 198 | beq .wait_input 199 | jmp .parent 200 | 201 | ; Change Page in current directory. 202 | 203 | .prev_page: ldx tos_cur_depth 204 | lda tos_cur_page,x 205 | bne .dec_page 206 | lda tos_num_pages 207 | .dec_page: dec a 208 | .chk_page: cmp tos_cur_page,x 209 | beq .wait_input 210 | sta tos_cur_page,x 211 | bsr .clr_child_pos 212 | jmp .new_page 213 | 214 | .next_page: ldx tos_cur_depth 215 | lda tos_cur_page,x 216 | inc a 217 | cmp tos_num_pages 218 | bcc .chk_page 219 | cla 220 | bra .chk_page 221 | 222 | ; Change File in current directory. 223 | 224 | .prev_file: ldx tos_cur_depth 225 | lda tos_cur_file,x 226 | bne .dec_file 227 | lda tos_num_files 228 | .dec_file: dec a 229 | .chk_file: cmp tos_cur_file,x 230 | beq .wait_input 231 | pha 232 | jsr tos_clr_hilite 233 | ldx tos_cur_depth 234 | pla 235 | sta tos_cur_file,x 236 | jsr tos_set_hilite 237 | bsr .clr_child_pos 238 | jmp .new_file 239 | 240 | .next_file: ldx tos_cur_depth 241 | lda tos_cur_file,x 242 | inc a 243 | cmp tos_num_files 244 | bcc .chk_file 245 | cla 246 | bra .chk_file 247 | 248 | ; 249 | 250 | .clr_child_pos: ldx tos_cur_depth ; Reset position in child dir. 251 | stz tos_cur_page + 1,x ; Done here so that reentering 252 | stz tos_cur_file + 1,x ; the child dir keeps position. 253 | rts 254 | 255 | .invalid: jmp .wait_input 256 | 257 | ; 258 | 259 | .select: ldx tos_cur_depth 260 | lda tos_cur_file,x 261 | tay 262 | asl a 263 | asl a 264 | tax 265 | lda tos_file_type,y 266 | beq .file 267 | 268 | .directory: ldy tos_cur_depth ; Limit directory depth to 32. 269 | iny 270 | cpy #32 271 | beq .invalid 272 | sty tos_cur_depth 273 | 274 | cly 275 | .dir_loop: lda tos_1st_cluster,x 276 | sta f32_dir_cluster,y 277 | inx 278 | iny 279 | cpy #4 280 | bne .dir_loop 281 | 282 | jsr f32_dir_chosen 283 | beq .changed 284 | 285 | stz tos_cur_depth 286 | jsr f32_select_root 287 | 288 | .changed: jmp .new_directory 289 | 290 | ; 291 | 292 | .parent: stw #dotdot,__ax ; Find the ".." directory entry. 293 | jsr f32_find_name 294 | bne .invalid 295 | 296 | jsr f32_change_dir 297 | bne .invalid 298 | 299 | dec tos_cur_depth 300 | jmp .new_directory 301 | 302 | ; 303 | 304 | .file: cly ; Copy file's initial cluster 305 | .file_loop: lda tos_1st_cluster,x ; and total length. 306 | sta f32_fil_cluster,y 307 | lda tos_file_length,x 308 | sta f32_file_length,y 309 | inx 310 | iny 311 | cpy #4 312 | bne .file_loop 313 | 314 | jsr f32_file_chosen ; Open the file using only the 315 | bne .load_fail ; cluster/length, not a name. 316 | 317 | PUTS msg_main_title 318 | 319 | jsr tos_load_hucard ; Load the current file as 320 | beq .load_good ; a HuCard image. 321 | 322 | .load_fail: PUTS file_failed 323 | bra .hang2 324 | 325 | .load_good: jmp tos_exec_hucard 326 | 327 | .hang: 328 | .hang2: bra .hang2 329 | 330 | 331 | file_loaded: db " File loaded!",$0A,0 332 | 333 | file_failed: db " File error!",$0A,0 334 | 335 | dotdot: db "..",0 336 | 337 | ; 338 | ; 339 | ; 340 | 341 | .hang: jsr wait_vsync 342 | bra .hang 343 | -------------------------------------------------------------------------------- /menu_info.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; menu_info.s 5 | ; 6 | ; TEOS Menu Screens 7 | ; 8 | ; Copyright John Brandwood 2019. 9 | ; 10 | ; Distributed under the Boost Software License, Version 1.0. 11 | ; (See accompanying file LICENSE_1_0.txt or copy at 12 | ; http://www.boost.org/LICENSE_1_0.txt) 13 | ; 14 | ; *************************************************************************** 15 | ; *************************************************************************** 16 | 17 | 18 | 19 | ; *************************************************************************** 20 | ; *************************************************************************** 21 | ; 22 | ; tos_info_menu - System Information Menu. 23 | ; 24 | 25 | 26 | tos_info_menu: ; 16-bit Date : 7-bits Year, 4-bits Month, 5-bits Day. 27 | 28 | lda ted_assem_date + 0 ; Day. 29 | tax 30 | and #$1F 31 | sta tos_info_temp + 3 32 | 33 | lda ted_assem_date + 1 ; Month 34 | lsr a 35 | sax 36 | ror a 37 | lsr a 38 | lsr a 39 | lsr a 40 | lsr a 41 | sta tos_info_temp + 2 42 | 43 | txa ; Year starts from 1980. 44 | clc 45 | adc #<1980 46 | sta tos_info_temp + 0 47 | cla 48 | adc #>1980 49 | sta tos_info_temp + 1 50 | 51 | ; 16-bit time : 2-second increments since midnight. 52 | 53 | tii ted_assem_time, __ax, 2 54 | lda #30 55 | sta <__cl 56 | jsr tos_div16_7u 57 | lda <__dl 58 | asl a 59 | sta tos_info_temp + 6 ; Seconds. 60 | lda #60 61 | sta <__cl 62 | jsr tos_div16_7u 63 | lda <__dl 64 | sta tos_info_temp + 5 ; Minutes. 65 | lda <__al 66 | sta tos_info_temp + 4 ; Hours. 67 | 68 | ; 69 | 70 | PUTS msg_system_info 71 | 72 | .wait_input: stz joytrg 73 | .wait_loop: jsr wait_vsync_usb ; Wait, but check for USB. 74 | lda joytrg 75 | beq .wait_loop 76 | 77 | bit #JOY_SEL 78 | beq .same_menu 79 | jmp tos_m128_menu 80 | 81 | .same_menu: bra .wait_input 82 | 83 | bss 84 | 85 | tos_info_temp: ds 7 86 | 87 | code 88 | 89 | ; 90 | ; 91 | ; 92 | 93 | 94 | msg_system_info:db "%>%p5%xl",0 95 | db $0C 96 | db " SYSTEM INFORMATION%p0" 97 | db $0A,$0A 98 | db "%<" 99 | 100 | db "%xl",2 101 | db "%y",2 102 | db $0A 103 | 104 | db "%p2" 105 | db "Turbo EverDrive V2",$0A 106 | db "Developed by I. Golubovskiy",$0A,$0A 107 | db "%p0" 108 | db "%r" 109 | dw TED_BASE_ADDR + TED_REG_VERSION 110 | db "FPGA Core Ver : %hX",$0A 111 | db "%r" 112 | dw $5000 113 | db "BootLoader1 Ver : %X",$0A 114 | db "%r" 115 | dw ted_boot2_ver 116 | db "BootLoader2 Ver : %X",$0A 117 | db "%r" 118 | dw tos_info_temp 119 | db "Assembly Date : %u-%hu-%hu",$0A 120 | db "Assembly Time : %hu:%hu:%hu",$0A 121 | db "%r" 122 | dw ted_serial_num 123 | db "Serial Number : %X",$0A 124 | db "Support Email : biokrik@gmail.com",$0A 125 | db "Support Forum : http://krikzz.com",$0A,$0A,$0A 126 | 127 | db "%p2" 128 | db "TEOS (Turbo EverDrive OS)",$0A 129 | db "Developed by J. Brandwood",$0A,$0A 130 | db "%p0" 131 | db "%r" 132 | dw $FFF0 133 | db "OS Version : %X",$0A 134 | db "Support Forum :",$0A 135 | db " http://pcengine.proboards.com",$0A 136 | 137 | db "%xl",0,$0A 138 | db "%p5%y",24 139 | ; db "----------------------------------------" 140 | db " SEL%p6:Chg Menu%p5",$0A 141 | db "%p0" 142 | db 0 143 | -------------------------------------------------------------------------------- /menu_init.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; menu_init.s 5 | ; 6 | ; TEOS Menu Screens 7 | ; 8 | ; Copyright John Brandwood 2019. 9 | ; 10 | ; Distributed under the Boost Software License, Version 1.0. 11 | ; (See accompanying file LICENSE_1_0.txt or copy at 12 | ; http://www.boost.org/LICENSE_1_0.txt) 13 | ; 14 | ; *************************************************************************** 15 | ; *************************************************************************** 16 | 17 | 18 | 19 | ; *************************************************************************** 20 | ; *************************************************************************** 21 | ; 22 | ; 23 | ; 24 | 25 | wait_for_key: stz joytrg 26 | .wait: lda joytrg 27 | and #JOY_B1 + JOY_B2 28 | beq .wait 29 | rts 30 | 31 | 32 | 33 | ; *************************************************************************** 34 | ; *************************************************************************** 35 | ; 36 | ; 37 | ; 38 | 39 | msg_wait_init: db "%>%p5" 40 | db $0C 41 | db " INITIALIZING...%<%p0" 42 | db $0A,$0A,$0A,0 43 | 44 | tos_menu_init: ldy #4 ; Decompress the 1st font file. 45 | jsr tos_decompress 46 | jsr upload_font8x8 47 | 48 | ldy #8 ; Decompress the 2nd font file. 49 | jsr tos_decompress 50 | jsr upload_font8x16 51 | 52 | jsr tos_init_crc16 ; Create CRC16 lookup table. 53 | jsr tos_init_crc32 ; Create CRC32 lookup table. 54 | 55 | PUTS msg_wait_init 56 | 57 | ; jsr show_mpr 58 | ; inc tos_tty_ypos 59 | 60 | php 61 | 62 | TED_CFG_FPGA 63 | 64 | ; Save Tennokoe Bank SRAM? 65 | 66 | jsr f32_mount_vol ; Init SDcard and mount drive. 67 | stx $2F00 68 | 69 | cpx #$00 70 | beq .stage1_ok 71 | 72 | PUTS fat32_nomount 73 | .hang: jmp .hang 74 | 75 | .stage1_ok: PUTS fat32_mounted 76 | 77 | ; Save Tennokoe Bank SRAM? 78 | 79 | lda tos_tennokoe ; Did we just run Tennokoe Bank? 80 | beq .skip_tbank 81 | stz tos_tennokoe 82 | jsr tos_save_tbank ; Save the Tennokoe Bank SRAM. 83 | .skip_tbank: nop 84 | 85 | ; 86 | 87 | if 0 88 | 89 | PUTS msg_press_a_key 90 | 91 | jsr wait_for_key 92 | 93 | jsr mb1_read_info 94 | 95 | PUTS msg_press_a_key 96 | 97 | jsr wait_for_key 98 | 99 | endif 100 | 101 | ; 102 | 103 | if 0 104 | 105 | PUTS msg_wait_init 106 | 107 | lda #BRAM_BANK ; Set up the directory bank. 108 | tam3 109 | 110 | lda #<$6000 111 | ldx #>$6000 112 | jsr show_page 113 | 114 | PUTS msg_press_a_key 115 | 116 | jsr wait_for_key 117 | 118 | PUTS msg_wait_init 119 | 120 | lda #BRAM_BANK + 15 ; Set up the directory bank. 121 | tam3 122 | 123 | lda #<$7F80 124 | ldx #>$7F80 125 | jsr show_page 126 | 127 | PUTS msg_press_a_key 128 | 129 | jsr wait_for_key 130 | 131 | PUTS msg_wait_init 132 | 133 | lda #BRAM_BANK + 16 ; Set up the directory bank. 134 | tam3 135 | 136 | lda #<$6000 137 | ldx #>$6000 138 | jsr show_page 139 | 140 | PUTS msg_press_a_key 141 | 142 | jsr wait_for_key 143 | 144 | endif 145 | 146 | if 0 147 | 148 | lda #BRAM_BANK 149 | tam3 150 | 151 | jsr bm_bram_to_bank 152 | 153 | PUTS msg_wait_init 154 | 155 | lda #<$6000 156 | ldx #>$6000 157 | jsr show_page 158 | 159 | PUTS msg_press_a_key 160 | 161 | jsr wait_for_key 162 | 163 | endif 164 | 165 | ; jsr tos_save_test 166 | ; beq .test_ok 167 | ; 168 | ; PUTS test_failed 169 | ;.hang2: jmp .hang2 170 | ; 171 | ;.test_ok: PUTS test_saved 172 | ; 173 | ; lda #sdc_block_cnt 175 | ; jsr show_8bytes 176 | 177 | ; jsr wait_for_key 178 | ; jsr tos_load_test 179 | 180 | ; If emulating, then use the volume ID as the SDcard CID. 181 | 182 | if REALHW 183 | else 184 | tii BS_BootSig32, sdc_cid_value, 16 185 | endif 186 | 187 | ; 188 | 189 | ;.stage2: jsr wait_for_key 190 | 191 | jmp tos_hucard_menu 192 | 193 | msg_press_a_key:db $0A 194 | db " Press%p1" 195 | db 28,29 196 | db "%p0 to continue.",$0A,0 197 | 198 | test_failed: db " Test write failed!",$0A,0 199 | test_saved: db " Test write OK!",$0A,0 200 | 201 | fat32_mounted: db " FAT32 partition mounted.",$0A,0 202 | fat32_nomount: db " FAT32 partition mount failed!",$0A,0 203 | 204 | 205 | 206 | ; *************************************************************************** 207 | ; *************************************************************************** 208 | ; 209 | ; 210 | ; 211 | 212 | show_mpr: tma0 213 | sta mpr + 0 214 | tma1 215 | sta mpr + 1 216 | tma2 217 | sta mpr + 2 218 | tma3 219 | sta mpr + 3 220 | tma4 221 | sta mpr + 4 222 | tma5 223 | sta mpr + 5 224 | tma6 225 | sta mpr + 6 226 | tma7 227 | sta mpr + 7 228 | 229 | lda #mpr 231 | jmp show_8bytes 232 | 233 | .bss 234 | 235 | mpr: ds 8 236 | 237 | .code 238 | 239 | 240 | 241 | ; *************************************************************************** 242 | ; *************************************************************************** 243 | ; 244 | ; show_page - show a 16-bye hex dump 245 | ; 246 | 247 | show_page: ldy #16 248 | .loop: phy 249 | bsr show_8bytes 250 | clc 251 | adc #$08 252 | bcc .skip 253 | inx 254 | .skip: ply 255 | dey 256 | bne .loop 257 | rts 258 | 259 | show_8bytes: php 260 | sei 261 | 262 | pha 263 | phx 264 | sta .tennokoe_name ; the current directory. 395 | sta <__ax + 0 396 | sty <__ax + 1 397 | jsr f32_find_name 398 | bne .exit 399 | 400 | jsr f32_open_file ; Open file and create 401 | bne .exit ; fragment map for I/O. 402 | 403 | ldx #TOS_WRONG_SIZE ; Return error code. 404 | 405 | lda f32_file_length + 1 ; Check that the file is 8KB. 406 | cmp #$20 407 | bne .close 408 | lda f32_file_length + 3 409 | ora f32_file_length + 2 410 | ora f32_file_length + 0 411 | bne .close 412 | 413 | lda #8192 / 512 414 | sta <__ax + 0 ; Lo-byte of # blocks in file. 415 | stz <__ax + 1 ; Hi-byte of # blocks in file. 416 | 417 | lda #$0F ; Map in TED2 512KB bank 0. 418 | sta TED_BASE_ADDR + TED_REG_MAP 419 | sta sdc_data_bank 420 | 421 | stz .load_ok 454 | 455 | jsr f32_close_file ; Close the file & set N & Z. 456 | beq .finished 457 | 458 | .failed: ldy #<.load_bad 459 | lda #>.load_bad 460 | 461 | .finished: phx ; Preserve result code. 462 | sxy 463 | jsr tos_print_msg 464 | plx ; Restore result code. 465 | 466 | lda #$0F ; Map in TED2 512KB bank 0. 467 | sta TED_BASE_ADDR + TED_REG_MAP 468 | lda #$40 ; RAMROM HuCard bank $40. 469 | tam3 470 | 471 | tma2 ; Use the BRAM bank as storage 472 | pha ; to see if the user makes any 473 | lda #BRAM_BANK ; changes to the Tennokoe Bank 474 | tam2 ; SRAM contents. 475 | 476 | txa ; Was the SRAM loaded from 477 | beq .copy ; SD card? 478 | 479 | tai tos_empty, $6000, $2000 ; Clear SRAM. 480 | 481 | .copy: tii $6000, $4000, $2000 ; Copy SRAM to see changes. 482 | 483 | pla ; Restore TED2 bank. 484 | tam2 485 | 486 | lda #$4F ; Set 512KB HuCard mapping. 487 | sta TED_BASE_ADDR + TED_REG_MAP 488 | lda #$40 489 | tam3 490 | 491 | phx 492 | PUTS msg_press_a_key 493 | jsr wait_for_key 494 | plx 495 | 496 | rts 497 | 498 | .loading: db " Loading Tennokoe Bank SRAM from SD ...",$0A,$0A,0 499 | .load_ok: db " SRAM loaded OK!",$0A,$0A 500 | db " When you have finished, please remember to press",$0A 501 | db " the RESET button on your Turbo EverDrive so that",$0A 502 | db " your file chest changes are saved to the SD card!",$0A,$0A,0 503 | .load_bad: db " Unable to read file!",$0A,0 504 | 505 | 506 | 507 | ; *************************************************************************** 508 | ; *************************************************************************** 509 | ; 510 | ; tos_save_tbank - Save the TENNOKOE.BIN file from HuCard bank $40. 511 | ; 512 | 513 | tos_save_tbank: lda #$0F ; Map in TED2 512KB bank 0. 514 | sta TED_BASE_ADDR + TED_REG_MAP 515 | lda #$40 ; RAMROM HuCard bank $40. 516 | tam3 517 | 518 | tma2 ; Map in the copy of the SRAM 519 | pha ; that we made before running 520 | lda #BRAM_BANK ; the HuCard. 521 | tam2 522 | 523 | lda #$40 ; Did the Tennokoe Bank HuCard 524 | sta .self_mod1 + 2 ; user change the contents of 525 | lda #$60 ; the SRAM? 526 | sta .self_mod2 + 2 527 | clx 528 | .loop: 529 | .self_mod1: lda $4000,x ; Compare the 8KB of SRAM. 530 | .self_mod2: cmp $6000,x 531 | bne .save_sram 532 | inx 533 | bne .loop 534 | inc .self_mod1 + 2 535 | inc .self_mod2 + 2 536 | bpl .loop 537 | 538 | pla ; Don't save the SRAM if it 539 | tam2 ; is unchanged. 540 | txa ; Return TOS_OK. 541 | bra .finished 542 | 543 | .save_sram: pla ; Save the Tennokoe Bank SRAM 544 | tam2 ; to SD card. 545 | 546 | .retry: PUTS msg_wait_init ; Inform the user. 547 | PUTS .msg_saving 548 | 549 | jsr tos_tbank_file ; Select "/TBED/TENNOKOE.BIN". 550 | bne .failed 551 | 552 | if 0 553 | ldx #F32_ERR_DSK_RD ; For testing the messages. 554 | else 555 | jsr f32_file_write ; Save the file from HuCard. 556 | endif 557 | 558 | jsr f32_close_file ; Close the file & set N & Z. 559 | beq .success 560 | 561 | ; 562 | 563 | .failed: PUTS .msg_failed ; Warn the user. 564 | 565 | .wait1_input: stz joytrg ; Wait for input. 566 | .wait1_loop: jsr wait_vsync 567 | lda joytrg 568 | beq .wait1_loop 569 | 570 | bit #JOY_RUN 571 | bne .danger 572 | bit #JOY_B1 573 | beq .wait1_input 574 | 575 | .want_retry: PUTS msg_wait_init 576 | bra .retry 577 | 578 | ; 579 | 580 | .danger: PUTS .msg_danger 581 | 582 | .wait2_input: stz joytrg 583 | .wait2_loop: jsr wait_vsync 584 | lda joytrg 585 | beq .wait2_loop 586 | 587 | bit #JOY_B1 588 | bne .want_retry 589 | 590 | bit #JOY_SEL 591 | beq .wait2_input 592 | bra .finished 593 | 594 | ; 595 | 596 | .success: PUTS .msg_save_ok 597 | PUTS msg_press_a_key 598 | 599 | .wait0_input: stz joytrg ; Wait for input. 600 | .wait0_loop: jsr wait_vsync 601 | lda joytrg 602 | beq .wait0_loop 603 | 604 | bit #JOY_B1 605 | beq .wait0_input 606 | bra .finished 607 | 608 | .finished: phx 609 | 610 | lda #$4F ; Set 512KB mapping for HuCard. 611 | sta TED_BASE_ADDR + TED_REG_MAP 612 | lda #$40 613 | tam3 614 | 615 | plx 616 | 617 | rts 618 | 619 | .msg_saving: db " Saving Tennokoe Bank SRAM to SD ...",$0A,$0A,0 620 | .msg_save_ok: db " SRAM saved OK!",$0A,0 621 | 622 | .msg_failed: db "%p5" 623 | db "%y",24 624 | 625 | ; db "----------------------------------------" 626 | db " " 627 | db 28,29 628 | db "%p6:Retry saving the SRAM to SD card%p5",$0A 629 | db " RUN%p6:Continue without saving SRAM",$0A 630 | 631 | db "%p0" 632 | db "%y",5 633 | db " FAILED TO SAVE SRAM TO SD CARD!",$0A,$0A 634 | ; db "----------------------------------------" 635 | db " If you continue, then you will lose",$0A 636 | db " any changes that you just made to",$0A 637 | db " the contents of the Tennokoe Bank",$0A 638 | db " file chests.",$0A,0 639 | 640 | .msg_danger: db $0A,$0A 641 | db " Are you really sure?",$0A,$0A 642 | db " Please press %p1SEL%p0 to confirm that you",$0A 643 | db " want to lose all of the changes that",$0A 644 | db " you made to the Tennokoe Bank SRAM!",$0A 645 | db "%y",25 646 | db "%p5" 647 | db " SEL%p6:Continue without saving SRAM",$0A,0 648 | 649 | ; db " you made while in the Tennokoe Bank!",$0A 650 | -------------------------------------------------------------------------------- /menu_mb128.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; menu_mb128.s 5 | ; 6 | ; TEOS Menu Screens 7 | ; 8 | ; Copyright John Brandwood 2019-2022. 9 | ; 10 | ; Distributed under the Boost Software License, Version 1.0. 11 | ; (See accompanying file LICENSE_1_0.txt or copy at 12 | ; http://www.boost.org/LICENSE_1_0.txt) 13 | ; 14 | ; *************************************************************************** 15 | ; *************************************************************************** 16 | 17 | 18 | 19 | ; *************************************************************************** 20 | ; *************************************************************************** 21 | ; 22 | ; tos_m128_menu - Text messages for the Memory Base SD menu. 23 | ; 24 | 25 | msg_m128_init: db "%>%p5%xl",0 26 | db $0C 27 | db " MEMORY BASE SD: Reading the MB128 " 28 | ; db " MEMORY BASE SD: Initializing ... " 29 | db "%<%p0",$0A,$0A,$0A,0 30 | 31 | ;msg_m128_none: db " Memory Base 128 not detected!",$0A,0 32 | 33 | ; 34 | ; 35 | ; 36 | 37 | M128_SAVE = 0 38 | M128_LOAD = 1 39 | M128_DEL = 2 40 | M128_FRAG = 3 41 | 42 | tbl_m128_title: dw msg_m128_save 43 | dw msg_m128_load 44 | dw msg_m128_del 45 | dw msg_m128_frag 46 | 47 | cls_m128_save: db $0C 48 | msg_m128_save: db "%>%p5%xl",0 49 | db "%x",0 50 | db "%y",0 51 | db " MEMORY BASE SD: Copy the MB128 to SD " 52 | db "%<%p0",$0A,$0A,$0A,0 53 | 54 | cls_m128_load: db $0C 55 | msg_m128_load: db "%>%p5%xl",0 56 | db "%x",0 57 | db "%y",0 58 | db " MEMORY BASE SD: Copy SD to the MB128 " 59 | db "%<%p0",$0A,$0A,$0A,0 60 | 61 | cls_m128_del: db $0C 62 | msg_m128_del: db "%>%p5%xl",0 63 | db "%x",0 64 | db "%y",0 65 | db " MEMORY BASE SD: Delete file in MB128 " 66 | db "%<%p0",$0A,$0A,$0A,0 67 | 68 | cls_m128_frag: db $0C 69 | msg_m128_frag: db "%>%p5%xl",0 70 | db "%x",0 71 | db "%y",0 72 | ; db " MEMORY BASE SD: Delete file in MB128" 73 | ; db " MEMORY BASE SD: Defragment MB128 " 74 | db " MEMORY BASE SD: Defragment the MB128 " 75 | db "%<%p0",$0A,$0A,$0A,0 76 | 77 | ; 78 | ; 79 | ; 80 | 81 | msg_m128_lhs: db "%<%xl",0 82 | 83 | db "%y",2 84 | db "%x",1 85 | db "%b",18,19,0 86 | 87 | db "%p3" 88 | db "%y",3 89 | db "%x",2 90 | db " Name Size" 91 | 92 | db "%x",1 93 | db "%y",21 94 | db "%p2" 95 | db "%>MB128 %<" 96 | db "%r" 97 | dw tos_m128_files + 0 98 | db "Files: %3hu",$0A 99 | db "%r" 100 | dw tos_m128_free + 0 101 | db "%x",9 102 | db "%y",22 103 | db "Free: %4u" 104 | db "%xl",2 105 | db "%x",2 106 | db "%y",4 107 | db "%p0%>",0 108 | 109 | ; 110 | ; 111 | ; 112 | 113 | msg_m128_rhs: db "%<%xl",0 114 | 115 | db "%y",2 116 | db "%x",21 117 | db "%b",18,19,0 118 | 119 | db "%p3" 120 | db "%y",3 121 | db "%x",22 122 | db " Name Size" 123 | 124 | db "%x",21 125 | db "%y",21 126 | db "%p2" 127 | db "%r" 128 | dw tos_m128_slot 129 | db "%>Slot #%hu %<" 130 | db "%r" 131 | dw tos_m128_files + 2 132 | db "Files: %3hu",$0A 133 | db "%r" 134 | dw tos_m128_free + 2 135 | db "%x",29 136 | db "%y",22 137 | db "Free: %4u" 138 | db "%xl",22 139 | db "%x",22 140 | db "%y",4 141 | db "%p0%>",0 142 | 143 | ; 144 | ; 145 | ; 146 | 147 | msg_m128_1frag: db "%>%xl",22 148 | db "%x",22 149 | db "%y",5 150 | db "%p3" 151 | ; db "------------------",$0A 152 | ; db "Congratulations!",$0A,$0A,$0A,$0A 153 | db "MB128 free space",$0A,$0A 154 | db "is defragmented.",$0A,$0A,$0A,$0A 155 | 156 | ; db "It does not need",$0A,$0A 157 | ; db "defragmentation!",$0A,$0A 158 | 159 | db "The maximum size",$0A,$0A 160 | db "of a new file is",$0A,$0A 161 | db "%r" 162 | dw tos_m128_maxsz 163 | db "%p2%lu%p3" 164 | db " bytes.",$0A,$0A 165 | db "%<%xl",0 166 | db 0 167 | 168 | msg_m128_nfrag: db "%>%xl",22 169 | db "%x",22 170 | db "%y",5 171 | db "%p3" 172 | ; db "------------------",$0A 173 | db "MB128 free space",$0A,$0A 174 | db "is fragmented in",$0A,$0A 175 | db "%r" 176 | dw tos_m128_frags 177 | db "%p2%hu%p3" 178 | db " blocks.",$0A,$0A,$0A,$0A 179 | db "Defragment MB128",$0A,$0A 180 | db "to maximize size",$0A,$0A 181 | db "of future files.",$0A,$0A 182 | db "%<%xl",0 183 | db 0 184 | 185 | ; 186 | ; 187 | ; 188 | 189 | tbl_m128_help: dw hlp_m128_save ; Help if box is selected. 190 | dw hlp_m128_load 191 | dw hlp_m128_del 192 | dw hlp_m128_frag 193 | 194 | hlp_m128_save: db "%<%p5%xl",0 195 | db "%x",0 196 | db "%y",24 197 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Slot%p5 \\|%p6:Scroll %p5",$0A 198 | db " " 199 | db 30,31 200 | db "%p6:Chg Mode%p5" 201 | db " " 202 | db 28,29 203 | db "%p6:Copy MB128 to Slot %p5",$0A 204 | db "%y",23 205 | db "%p0" 206 | 207 | db "%xl",19 208 | db "%x",19 209 | db "%y",3 210 | db ">>",$0A 211 | db ">>",$0A 212 | db ">>",$0A 213 | db ">>",$0A 214 | db ">>",$0A 215 | db ">>",$0A 216 | db ">>",$0A 217 | db ">>",$0A 218 | db ">>",$0A 219 | db ">>",$0A 220 | db ">>",$0A 221 | db ">>",$0A 222 | db ">>",$0A 223 | db ">>",$0A 224 | db ">>",$0A 225 | db ">>",$0A 226 | db ">>",$0A 227 | 228 | db 0 229 | 230 | ; 231 | 232 | hlp_m128_load: db "%<%p5%xl",0 233 | db "%x",0 234 | db "%y",24 235 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Slot%p5 \\|%p6:Scroll %p5",$0A 236 | db " " 237 | db 30,31 238 | db "%p6:Chg Mode%p5" 239 | db " " 240 | db 28,29 241 | db "%p6:Copy Slot to MB128 %p5",$0A 242 | db "%y",23 243 | db "%p0" 244 | 245 | db "%xl",19 246 | db "%x",19 247 | db "%y",3 248 | db "<<",$0A 249 | db "<<",$0A 250 | db "<<",$0A 251 | db "<<",$0A 252 | db "<<",$0A 253 | db "<<",$0A 254 | db "<<",$0A 255 | db "<<",$0A 256 | db "<<",$0A 257 | db "<<",$0A 258 | db "<<",$0A 259 | db "<<",$0A 260 | db "<<",$0A 261 | db "<<",$0A 262 | db "<<",$0A 263 | db "<<",$0A 264 | db "<<",$0A 265 | 266 | db 0 267 | 268 | ; 269 | 270 | hlp_m128_del: db "%<%p5%xl",0 271 | db "%x",0 272 | db "%y",24 273 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Slot%p5 \\|%p6:Chg File%p5",$0A 274 | db " " 275 | db 30,31 276 | db "%p6:Chg Mode%p5" 277 | db " " 278 | db 28,29 279 | db "%p6:Delete File in MB128 %p5",$0A 280 | db "%y",23 281 | db "%p0" 282 | db 0 283 | 284 | ; 285 | 286 | hlp_m128_frag: db "%<%p5%xl",0 287 | db "%x",0 288 | db "%y",24 289 | db " SEL%p6:Chg Menu%p5 <>%p6:Chg Slot%p5 \\|%p6:Scroll %p5",$0A 290 | db " " 291 | db 30,31 292 | db "%p6:Chg Mode%p5" 293 | db " " 294 | db 28,29 295 | db "%p6:Defragment the MB128 %p5",$0A 296 | db "%y",23 297 | db "%p0" 298 | db 0 299 | 300 | ; 301 | ; 302 | ; 303 | 304 | msg_m128_name: db "%8c %r" 305 | dw tos_temp_length 306 | db "%4u",$0A,$0A,0 307 | 308 | ; 309 | ; 310 | 311 | msg_m128_format:db " The Memory Base 128 is unformatted! ",$0A,$0A,0 312 | 313 | msg_m128_damage:db " The Memory Base 128 directory seems ",$0A 314 | db " to be corrupted and cannot be used! ",$0A,$0A,0 315 | 316 | msg_m128_empty: db " TEOS will use a new formatted image ",$0A 317 | db " instead, but your MB128 will remain ",$0A 318 | db " unchanged unless you choose to copy ",$0A 319 | db " the contents of an SD Slot to it.",$0A,$0A,0 320 | 321 | ; db " an SD card SLOT to it.",$0A,$0A,0 322 | 323 | ;msg_m128_empty:db " An empty MB128 image will be shown. ",$0A,$0A,0 324 | 325 | ; USE COPIES FROM BRAM MENU 326 | 327 | if 0 328 | 329 | msg_small_index:db "%-2hu",0 330 | msg_large_index:db "%02hu",0 331 | 332 | msg_bram_larrow:db $1C,0 333 | msg_bram_rarrow:db $1D,0 334 | 335 | msg_bram_space: db " ",0 336 | 337 | msg_bram_name: db "%10c %r" 338 | dw tos_temp_length 339 | db "%4u",$0A,$0A,0 340 | 341 | msg_bram_spaces:db " " 342 | db " ",$0A,$0A,0 343 | 344 | msg_blank_rhs: db "%<%xl",0 345 | 346 | db "%y",2 347 | db "%x",19 348 | db "%p0" 349 | db "%b",20,21,1 350 | 351 | db "%p0%>",0 352 | 353 | endif 354 | 355 | ; 356 | ; 357 | ; 358 | 359 | bss 360 | 361 | tos_m128_slot: ds 1 362 | tos_m128_mode: ds 1 363 | tos_m128_focus: ds 1 ; Which side is focused? 364 | 365 | tos_m128_frags: ds 2*2 ; # of frags on LHS/RHS. 366 | tos_m128_files: ds 2*2 ; # of files on LHS/RHS. 367 | tos_m128_least: ds 2*2 ; Minimum LHS/RHS file choice. 368 | tos_m128_chosen:ds 2*2 ; Current LHS/RHS file choice. 369 | tos_m128_free: ds 2*2 ; Blocks unused on LHS/RHS. 370 | 371 | tos_m128_first: ds 1 372 | tos_m128_choice:ds 1 373 | tos_m128_index: ds 1 374 | tos_m128_hilite:ds 1 375 | 376 | tos_m128_fname: ds 2 ; Ptr to selected name in MB128. 377 | 378 | tos_m128_trash: ds 1 ; Is the MB128 contents bad? 379 | tos_slot_trash: ds 1 ; Is the SLOT contents bad? 380 | 381 | tos_m128_maxsz: ds 4 ; Maximum file size. 382 | 383 | code 384 | 385 | 386 | 387 | ; *************************************************************************** 388 | ; *************************************************************************** 389 | ; 390 | ; tos_m128_menu - Memory Base SD menu. 391 | ; 392 | 393 | tos_m128_menu: stz tos_m128_mode 394 | stz tos_m128_slot 395 | 396 | tos_m128_init: if REALHW 397 | 398 | PUTS msg_m128_init 399 | 400 | jsr mb1_detect ; Skip if there is no MB128. 401 | beq .start_menu 402 | 403 | endif 404 | 405 | jmp tos_hucard_menu 406 | 407 | .start_menu: stw #$0000,VCE_CTA 408 | stw #red464_palette,__ax 409 | ldx #8 410 | jsr copy_palettes 411 | 412 | ; jsr clear_screen 413 | 414 | ; Verify contents of BRAM_BANK. 415 | 416 | stz tos_m128_trash ; Mark the MB128 as good. 417 | 418 | lda #BRAM_BANK 419 | sta mb1_base_bank 420 | 421 | jsr mb1_load_dir ; Load the directory. 422 | bne .bad_m128 423 | jsr mb1_csum_dir ; Fix directory for display. 424 | beq .m128_info 425 | 426 | .bad_m128: stx tos_m128_trash ; Mark the MB128 as bad. 427 | 428 | cpx #MB1_ERR_IDENT ; What kind of error? 429 | bne .corrupt 430 | 431 | PUTS msg_m128_format 432 | bra .wait_user 433 | 434 | .corrupt: PUTS msg_m128_damage 435 | 436 | .wait_user: PUTS msg_m128_empty 437 | PUTS msg_press_a_key 438 | jsr wait_for_key 439 | 440 | lda #BRAM_BANK ; Format the MB128 image. 441 | jsr mb1_new_image 442 | 443 | jsr mb1_csum_dir ; Fix directory for display. 444 | 445 | .m128_info: ldx #0 ; Save MB128 info. 446 | jsr tos_m128_info 447 | 448 | lda tos_m128_free ; Save maximum file size. 449 | jsr mb1_xvert_size 450 | sta tos_m128_maxsz + 0 451 | stx tos_m128_maxsz + 1 452 | sty tos_m128_maxsz + 2 453 | stz tos_m128_maxsz + 3 454 | 455 | ; Verify contents of SLOT_BANK. 456 | 457 | .new_slot: stz tos_hilite_idx ; Reset hilite pulsing. 458 | 459 | stz tos_slot_trash ; Mark the SLOT as good. 460 | 461 | lda #SLOT_BANK ; Load the file data. 462 | jsr tos_load_m128 463 | bne .bad_slot 464 | 465 | jsr mb1_test_dir ; Check the directory signature 466 | bne .bad_slot ; and checksum. 467 | jsr mb1_csum_dir ; Fix directory for display. 468 | beq .slot_info 469 | 470 | .bad_slot: stx tos_slot_trash ; Mark the SLOT as bad. 471 | 472 | lda #SLOT_BANK ; Format the SLOT image. 473 | jsr mb1_new_image 474 | 475 | jsr mb1_csum_dir ; Fix directory for display. 476 | 477 | .slot_info: ldx #2 ; Save SLOT info. 478 | jsr tos_m128_info 479 | 480 | ; Has the mode just changed? 481 | 482 | .new_mode: ldx tos_m128_mode ; Lookup which side has focus. 483 | lda .tbl_focus_side,x 484 | sta tos_m128_focus 485 | lda .tbl_min_choice,x ; Lookup minimum selection. 486 | sta tos_m128_least + 0 ; Set minimum selection. 487 | sta tos_m128_least + 2 488 | sta tos_m128_chosen + 0 ; Set current selection. 489 | sta tos_m128_chosen + 2 490 | 491 | cpx #M128_DEL ; Delete File mode? 492 | bcs .show_title 493 | 494 | ldx #2 495 | .calc_minimum: lda #8 ; Start at the last file 496 | cmp tos_m128_files,x ; shown on the screen so 497 | bcc .set_minimum ; scrolling is immediate. 498 | lda tos_m128_files,x 499 | .set_minimum: sta tos_m128_least,x ; Set minimum selection. 500 | sta tos_m128_chosen,x ; Set current selection. 501 | dex 502 | dex 503 | bpl .calc_minimum 504 | 505 | .show_title: lda tos_m128_mode ; Lookup which title to display. 506 | asl a 507 | tay 508 | ldx tbl_m128_title + 0,y 509 | lda tbl_m128_title + 1,y 510 | jsr tos_print_msg 511 | 512 | ; Redraw the menu screen to reflect changes. 513 | 514 | .show_help: ldx tos_m128_mode ; Lookup which help to display. 515 | ldy .tbl_focus_side,x ; Is there a file selected on 516 | lda tos_m128_chosen,y ; the side that has focus? 517 | sax 518 | ; beq .lookup_help 519 | ; clc ; If so, use 2nd set of help 520 | ; adc #4 ; messages. 521 | .lookup_help: asl a 522 | tay 523 | ldx tbl_m128_help + 0,y 524 | lda tbl_m128_help + 1,y 525 | jsr tos_print_msg 526 | 527 | ; Display contents of BRAM_BANK. 528 | 529 | .show_m128: ldx tos_m128_mode 530 | cpx #M128_DEL 531 | bne .m128_box_color 532 | 533 | stz tos_hilite_idx ; Reset hilite pulsing. 534 | 535 | .m128_box_color:lda .tbl_box_lhs,x 536 | jsr tos_set_pen 537 | 538 | PUTS msg_m128_lhs 539 | 540 | lda #BRAM_BANK 541 | tam3 542 | 543 | ldx #0 544 | jsr tos_m128_show 545 | 546 | ; Display contents of SLOT_BANK. 547 | 548 | lda tos_m128_mode 549 | cmp #M128_DEL 550 | bcc .show_slot 551 | bne .show_frag 552 | 553 | .show_null: PUTS msg_blank_rhs ; RHS shows blank. 554 | bra .wait_input 555 | 556 | .show_frag: PUTS msg_blank_rhs ; RHS shows fragmentation. 557 | 558 | lda tos_m128_frags 559 | cmp #2 560 | bcs .show_nfrag 561 | 562 | PUTS msg_m128_1frag ; Defragmented! 563 | bra .wait_input 564 | 565 | .show_nfrag: PUTS msg_m128_nfrag ; Fragmented! 566 | bra .wait_input 567 | 568 | .show_slot: ldx tos_m128_mode 569 | lda .tbl_box_rhs,x 570 | jsr tos_set_pen 571 | 572 | inc tos_m128_slot 573 | PUTS msg_m128_rhs 574 | dec tos_m128_slot 575 | 576 | lda #SLOT_BANK 577 | tam3 578 | 579 | ldx #2 580 | jsr tos_m128_show 581 | 582 | ; 583 | 584 | .wait_input: stz joytrg 585 | .wait_loop: jsr wait_vsync_usb 586 | lda joytrg 587 | beq .wait_loop 588 | 589 | bit #JOY_SEL 590 | beq .same_menu 591 | 592 | stw #$0000,VCE_CTA 593 | stw #cpc464_palette,__ax 594 | ldx #8 595 | jsr copy_palettes 596 | jmp tos_hucard_menu 597 | 598 | .same_menu: bit #JOY_L 599 | bne .prev_slot 600 | bit #JOY_R 601 | bne .next_slot 602 | bit #JOY_U 603 | bne .prev_file 604 | bit #JOY_D 605 | bne .next_file 606 | bit #JOY_B1 607 | bne .select 608 | 609 | .back_only: bit #JOY_B2 610 | beq .wait_input 611 | ; jmp .chg_mode 612 | 613 | ; Change Mode. 614 | 615 | lda tos_m128_mode 616 | inc a 617 | and #3 618 | ; cmp #3 619 | ; bcc .save_mode 620 | ; cla 621 | .save_mode: sta tos_m128_mode 622 | jmp .new_mode 623 | 624 | ; Change Save Slot. 625 | 626 | .prev_slot: lda tos_m128_slot 627 | dec a 628 | and #7 629 | sta tos_m128_slot 630 | jmp .new_slot 631 | 632 | .next_slot: lda tos_m128_slot 633 | inc a 634 | and #7 635 | sta tos_m128_slot 636 | jmp .new_slot 637 | 638 | ; Change Selected File. 639 | 640 | .prev_file: clx 641 | ldy #2 642 | .prev_loop: lda tos_m128_chosen,x ; Already at minimum selection? 643 | cmp tos_m128_least,x 644 | bne .check_other 645 | ; lda tos_m128_files,x ; Wrap around to end selection. 646 | bra .set_prev_file 647 | .check_other: cmp tos_m128_chosen,y ; Is the other side on a higher 648 | bcc .set_prev_file ; selection? 649 | dec a 650 | .set_prev_file: pha 651 | sxy 652 | txa 653 | bne .prev_loop 654 | .changed_choice:pla 655 | sta tos_m128_chosen + 2 656 | pla 657 | sta tos_m128_chosen + 0 658 | jmp .show_m128 659 | 660 | .next_file: clx 661 | ldy #2 662 | .next_loop: lda tos_m128_chosen,x ; Already at maximum selection? 663 | cmp tos_m128_files,x 664 | bne .inc_next_file 665 | lda tos_m128_chosen,y ; Is the other side on maximum? 666 | cmp tos_m128_files,y 667 | ; lda tos_m128_least,x ; Wrap around to 1st selection. 668 | ; bcs .set_next_file 669 | lda tos_m128_chosen,x ; Else stay on current choice. 670 | dec a 671 | .inc_next_file: inc a 672 | .set_next_file: pha 673 | sxy 674 | txa 675 | bne .next_loop 676 | bra .changed_choice 677 | 678 | .select: lda tos_m128_mode 679 | asl a 680 | tax 681 | jsr .vector 682 | jmp tos_m128_init 683 | 684 | .vector: jmp [.tbl_funcs,x] 685 | 686 | .tbl_funcs: dw func_m128_save 687 | dw func_m128_load 688 | dw func_m128_del 689 | dw func_m128_frag 690 | 691 | .tbl_box_lhs: db 1,0,0,1 ; Palette for box per mode. 692 | .tbl_box_rhs: db 0,1,0,0 ; Palette for box per mode. 693 | .tbl_focus_side:db 0,2,0,0 ; Focused side per mode. 694 | .tbl_min_choice:db 0,0,1,0 ; Minimum choice per mode. 695 | 696 | 697 | 698 | ; *************************************************************************** 699 | ; *************************************************************************** 700 | ; 701 | ; tos_m128_info - Save the info after a verify for later display. 702 | ; 703 | ; N.B. There can be a maximum of 63 files in the MB128. 704 | ; 705 | 706 | tos_m128_info: lda mb1_frag_count 707 | sta tos_m128_frags + 0,x 708 | stz tos_m128_frags + 1,x 709 | 710 | lda mb1_file_count 711 | sta tos_m128_files + 0,x 712 | stz tos_m128_files + 1,x 713 | 714 | sec 715 | lda #<256 716 | sbc mb1_directory + MB1_HEAD_USED + 0 717 | sta tos_m128_free + 0,x 718 | lda #>256 719 | sbc mb1_directory + MB1_HEAD_USED + 1 720 | sta tos_m128_free + 1,x 721 | 722 | rts 723 | 724 | 725 | 726 | ; *************************************************************************** 727 | ; *************************************************************************** 728 | ; 729 | ; tos_m128_show - Display the BRAM files in the current bank. 730 | ; 731 | ; N.B. There can be a maximum of 63 files in the MB128. 732 | ; 733 | 734 | tos_m128_show: lda tos_m128_chosen,x ; Decide which file to display 735 | sta tos_m128_choice ; at the top of the box. 736 | sec 737 | sbc #7 738 | bcs .first_to_show 739 | lda #1 740 | .first_to_show: sta tos_m128_first 741 | 742 | .test_focus: lda #1 743 | sta tos_m128_hilite ; Set hilite color to pulsing. 744 | 745 | lda tos_m128_mode ; Only hilite a file in Delete. 746 | cmp #2 747 | beq .first_in_m128 748 | 749 | stz tos_m128_hilite ; Set hilite color to normal. 750 | stz tos_m128_choice ; Do not hilite any file. 751 | 752 | .first_in_m128: ldy #mb1_directory + 16 754 | 755 | stz tos_m128_index 756 | 757 | .file_loop: inc tos_m128_index ; Increment file index. 758 | 759 | cpy #>mb1_directory + 1024 ; Is it beyond directory? 760 | bcs .rest ; EOD, remaining slots blank. 761 | 762 | sty <__bp + 0 ; Update file pointer. 763 | sta <__bp + 1 764 | 765 | .not_eof: lda [__bp] ; Sector# or zero at end. 766 | beq .rest 767 | 768 | ldy #MB1_FILE_SIZE 769 | lda [__bp],y 770 | sta tos_temp_length + 0 ; Size to display (lo-byte). 771 | stz tos_temp_length + 1 ; Size to display (hi-byte). 772 | 773 | lda #$10 ; Calc address of next file. 774 | clc 775 | adc <__bp + 0 776 | say 777 | cla 778 | adc <__bp + 1 779 | 780 | ldx tos_m128_index ; Skip off-screen files. 781 | cpx tos_m128_first 782 | bcc .file_loop 783 | 784 | phy ; Preserve next file pointer. 785 | pha 786 | 787 | cla ; Select the palette to use 788 | ldx tos_m128_index ; for this file entry. 789 | cpx tos_m128_choice 790 | bne .file_color 791 | lda tos_m128_hilite 792 | .file_color: jsr tos_set_pen 793 | 794 | if 0 795 | 796 | ldx #msg_small_index 798 | 799 | lda tos_m128_index 800 | cmp #100 801 | bcc .show_index 802 | sbc #100 803 | 804 | ldx #msg_large_index 806 | 807 | .show_index: sta tos_temp_index ; Truncated to 2 digits. 808 | 809 | lda #tos_temp_index 812 | sta <__di + 1 813 | 814 | ; tya 815 | ; jsr tos_print_msg 816 | 817 | endif 818 | 819 | ldx #msg_bram_space 821 | 822 | lda tos_m128_index 823 | cmp tos_m128_choice 824 | bne .show_lhs_arrow 825 | 826 | ldx #msg_bram_larrow 828 | 829 | .show_lhs_arrow:tya 830 | jsr tos_print_msg 831 | 832 | .file_name: lda #MB1_FILE_NAME ; Display the file name & size. 833 | clc 834 | adc <__bp + 0 835 | sta <__di + 0 836 | tax 837 | cla 838 | adc <__bp + 1 839 | sta <__di + 1 840 | tay 841 | 842 | lda tos_tty_tile + 1 ; Is this entry in the hilite 843 | and #$F0 ; color? 844 | beq .show_name 845 | 846 | stx tos_m128_fname + 0 ; Save the addr of the selected 847 | sty tos_m128_fname + 1 ; filename. 848 | 849 | .show_name: PUTS msg_m128_name 850 | 851 | pla ; Restore next file pointer. 852 | ply 853 | 854 | ldx tos_tty_ypos ; Display the rest of the 855 | cpx #20 ; BRAM files in the box. 856 | bcs .done 857 | 858 | jmp .file_loop 859 | 860 | .rest: lda tos_tty_ypos ; Blank out the rest of the 861 | cmp #20 ; BRAM files in the box. 862 | bcs .done 863 | 864 | PUTS msg_bram_spaces 865 | bra .rest 866 | 867 | .done: rts 868 | 869 | 870 | 871 | ; *************************************************************************** 872 | ; *************************************************************************** 873 | ; 874 | ; func_m128_save - Copy MB128 to SD card slot. 875 | ; 876 | 877 | func_m128_save: PUTS cls_m128_save ; Confirm the operation. 878 | inc tos_m128_slot ; Show slot from '1' not '0'. 879 | PUTS .msg_warning 880 | dec tos_m128_slot 881 | 882 | .wait_input: stz joytrg ; Wait for input. 883 | .wait_loop: jsr wait_vsync_usb 884 | lda joytrg 885 | beq .wait_loop 886 | bit #JOY_RUN 887 | bne .confirmed 888 | bit #JOY_B2 889 | beq .wait_input 890 | rts 891 | 892 | .confirmed: PUTS cls_m128_save ; Inform the user. 893 | 894 | lda tos_m128_trash ; Is the MB128 corrupt? 895 | bne .skip_load ; Save clean copy from memory. 896 | 897 | PUTS .msg_load 898 | 899 | lda #BRAM_BANK ; Load the MB128 image. 900 | jsr mb1_load_image 901 | bne .failed 902 | 903 | .skip_load: PUTS .msg_save 904 | 905 | lda #BRAM_BANK ; Save image to the SD card. 906 | jsr tos_save_m128 907 | bne .failed 908 | 909 | PUTS msg_m128_done 910 | bra .result 911 | 912 | .failed: PUTS msg_m128_fail 913 | 914 | .result: PUTS msg_press_a_key 915 | jsr wait_for_key 916 | 917 | .finished: rts 918 | 919 | .msg_warning: db "%r" 920 | dw tos_m128_slot 921 | db "%y",11 922 | db " Please press %p1RUN%p0 to confirm that you",$0A 923 | db " want to copy the MB128 to SD Slot #%hu",$0A 924 | db "%y",24 925 | db "%x",12 926 | db "%p5RUN%p6:Confirm copy",$0A 927 | db "%x",13 928 | db "%p5",30,31,"%p6:Cancel copy",$0A 929 | db "%p0%y",14,0 930 | 931 | .msg_load: db " Loading data from MB128",0 932 | .msg_save: db " Saving data to SD card.",$0A,$0A,0 933 | 934 | 935 | 936 | ; *************************************************************************** 937 | ; *************************************************************************** 938 | ; 939 | ; func_m128_load - Copy SD card slot to MB128. 940 | ; 941 | 942 | func_m128_load: PUTS cls_m128_load 943 | inc tos_m128_slot ; Show slot from '1' not '0'. 944 | PUTS .msg_warning 945 | dec tos_m128_slot 946 | 947 | .wait_input: stz joytrg ; Wait for input. 948 | .wait_loop: jsr wait_vsync_usb 949 | lda joytrg 950 | beq .wait_loop 951 | bit #JOY_RUN 952 | bne .confirmed 953 | bit #JOY_B2 954 | beq .wait_input 955 | rts 956 | 957 | .confirmed: PUTS cls_m128_load ; Inform the user. 958 | 959 | lda tos_slot_trash ; Is the SLOT corrupt? 960 | bne .skip_load ; Save clean copy from memory. 961 | 962 | PUTS .msg_load 963 | 964 | lda #SLOT_BANK ; Load image from the SD card. 965 | jsr tos_load_m128 966 | bne .failed 967 | 968 | .skip_load: PUTS .msg_save 969 | 970 | lda #SLOT_BANK ; Save the MB128 image. 971 | jsr mb1_save_image 972 | bne .failed 973 | 974 | PUTS msg_m128_done 975 | bra .result 976 | 977 | .failed: PUTS msg_m128_fail 978 | 979 | .result: PUTS msg_press_a_key 980 | jsr wait_for_key 981 | 982 | .finished: rts 983 | 984 | .msg_warning: db "%r" 985 | dw tos_m128_slot 986 | db "%y",11 987 | db " Please press %p1RUN%p0 to confirm that you",$0A 988 | db " want to copy SD Slot #%hu to the MB128",$0A 989 | db "%y",24 990 | db "%x",12 991 | db "%p5RUN%p6:Confirm copy",$0A 992 | db "%x",13 993 | db "%p5",30,31,"%p6:Cancel copy",$0A 994 | db "%p0%y",14,0 995 | 996 | 997 | .msg_load: db " Loading data from SD card.",$0A,$0A,0 998 | .msg_save: db " Saving data to MB128",0 999 | 1000 | msg_m128_fail: db " MB128 operation failed!",$0A,$0A,0 1001 | msg_m128_done: db " MB128 operation completed!",$0A,$0A,0 1002 | 1003 | 1004 | 1005 | ; *************************************************************************** 1006 | ; *************************************************************************** 1007 | ; 1008 | ; func_m128_del - Delete a file from MB128. 1009 | ; 1010 | 1011 | func_m128_del: lda tos_m128_files ; Are there any files in MB128? 1012 | bne .wipe 1013 | rts 1014 | 1015 | .wipe: PUTS cls_m128_del 1016 | 1017 | lda tos_m128_fname + 0 ; Get the addr of the selected 1018 | sta <__di + 0 ; filename. 1019 | lda tos_m128_fname + 1 1020 | sta <__di + 1 1021 | 1022 | PUTS .msg_warning 1023 | 1024 | .wait_input: stz joytrg ; Wait for input. 1025 | .wait_loop: jsr wait_vsync_usb 1026 | lda joytrg 1027 | beq .wait_loop 1028 | bit #JOY_RUN 1029 | bne .confirmed 1030 | bit #JOY_B2 1031 | beq .wait_input 1032 | rts 1033 | 1034 | .confirmed: PUTS cls_m128_del ; Inform the user. 1035 | 1036 | lda #BRAM_BANK ; Wipe the file from the MB128 1037 | tam3 ; image in memory. 1038 | 1039 | lda #$73 ; TII instruction. 1040 | sta <__al 1041 | lda #$60 ; RTS instruction. 1042 | sta <__dh 1043 | 1044 | .copy_data: sec ; Use the addr of the selected 1045 | lda tos_m128_fname + 0 ; filename as the destination. 1046 | sbc #MB1_FILE_NAME 1047 | sta <__bh + 0 1048 | lda tos_m128_fname + 1 1049 | sbc #0 1050 | sta <__bh + 1 1051 | 1052 | clc ; Use the addr of the next MB128 1053 | cly ; file as the source. 1054 | lda #16 1055 | adc <__bh + 0 1056 | sta <__ah + 0 1057 | cla 1058 | adc <__bh + 1 1059 | sta <__ah + 1 1060 | 1061 | sec ; Calc length from the end of 1062 | lda #<(mb1_directory + 1024); directory. 1063 | sbc <__ah + 0 1064 | sta <__ch + 0 1065 | lda #>(mb1_directory + 1024) 1066 | sbc <__ah + 1 1067 | sta <__ch + 1 1068 | ora <__ch + 0 1069 | beq .fill_free 1070 | 1071 | jsr __al ; Execute TII instruction. 1072 | 1073 | .fill_free: tai tos_zero, mb1_directory + 1024 - 16, 16 1074 | 1075 | PUTS mb1_msg_wrd_now 1076 | 1077 | lda #BRAM_BANK ; Update the MB128 directory. 1078 | sta mb1_base_bank 1079 | jsr mb1_save_dir 1080 | bne .failed 1081 | 1082 | PUTS mb1_msg_wrd_ok 1083 | PUTS mb1_msg_lf 1084 | PUTS msg_m128_done 1085 | bra .result 1086 | 1087 | .failed: PUTS msg_m128_fail 1088 | 1089 | .result: PUTS msg_press_a_key 1090 | jsr wait_for_key 1091 | 1092 | .finished: rts 1093 | 1094 | .msg_warning: db "%y",11 1095 | db " Please press %p1RUN%p0 to confirm that you",$0A 1096 | db " want to delete the file ",$22,"%p2%8c%p0",$22,"",$0A 1097 | db "%y",24 1098 | db "%x",11 1099 | db "%p5RUN%p6:Confirm delete",$0A 1100 | db "%x",12 1101 | db "%p5",30,31,"%p6:Cancel delete",$0A 1102 | db "%p0%y",14,0 1103 | 1104 | 1105 | 1106 | ; *************************************************************************** 1107 | ; *************************************************************************** 1108 | ; 1109 | ; func_m128_frag - Defragment Free Space on the MB128. 1110 | ; 1111 | 1112 | func_m128_frag: lda tos_m128_frags 1113 | cmp #2 1114 | bcs .defrag 1115 | 1116 | rts 1117 | 1118 | .defrag: PUTS cls_m128_frag 1119 | 1120 | lda tos_m128_fname + 0 ; Get the addr of the selected 1121 | sta <__di + 0 ; filename. 1122 | lda tos_m128_fname + 1 1123 | sta <__di + 1 1124 | 1125 | PUTS .msg_warning 1126 | 1127 | .wait_input: stz joytrg ; Wait for input. 1128 | .wait_loop: jsr wait_vsync_usb 1129 | lda joytrg 1130 | beq .wait_loop 1131 | bit #JOY_RUN 1132 | bne .confirmed 1133 | bit #JOY_B2 1134 | beq .wait_input 1135 | rts 1136 | 1137 | .confirmed: PUTS cls_m128_frag ; Inform the user. 1138 | 1139 | PUTS .msg_load 1140 | 1141 | lda #BRAM_BANK ; Load all the MB128 files, 1142 | jsr mb1_load_files ; verifying their integrity. 1143 | bne .failed 1144 | 1145 | PUTS .msg_save 1146 | 1147 | lda #BRAM_BANK ; Save all the MB128 files, 1148 | jsr mb1_save_files ; verifying their integrity. 1149 | bne .failed 1150 | 1151 | PUTS msg_m128_done 1152 | bra .result 1153 | 1154 | .failed: PUTS msg_m128_fail 1155 | 1156 | .result: PUTS msg_press_a_key 1157 | jsr wait_for_key 1158 | 1159 | .finished: rts 1160 | 1161 | .msg_warning: db "%y",11 1162 | db " Please press %p1RUN%p0 to confirm that you",$0A 1163 | db " want to defragment MB128 free space!",$0A 1164 | db "%y",24 1165 | db "%x",9 1166 | db "%p5RUN%p6:Confirm defragment",$0A 1167 | db "%x",10 1168 | db "%p5",30,31,"%p6:Cancel defragment",$0A 1169 | db "%p0%y",14,0 1170 | 1171 | .msg_load: db " Loading all MB128 files.",$0A,$0A,0 1172 | .msg_save: db " Saving files to MB128.",$0A,$0A,0 1173 | -------------------------------------------------------------------------------- /pceas.inc: -------------------------------------------------------------------------------- 1 | ; -------- 2 | ; This block defines names for macro 3 | ; argument types (\?x). 4 | ; 5 | 6 | ARG_NONE .equ 0 7 | ARG_REG .equ 1 8 | ARG_IMMED .equ 2 9 | ARG_ABS .equ 3 10 | ARG_ABSOLUTE .equ 3 11 | ARG_INDIRECT .equ 4 12 | ARG_STRING .equ 5 13 | ARG_LABEL .equ 6 14 | 15 | ; 16 | ; 17 | ; 18 | 19 | vreg macro 20 | lda \1 21 | sta 342 pixel slots. 561 | 562 | VDC_HSR_224 = $0402 ; HDS HSW 563 | VDC_HDR_224 = $061B ; HDE HDW 564 | 565 | VDC_HSR_240 = $0302 ; HDS HSW 566 | VDC_HDR_240 = $051D ; HDE HDW 567 | 568 | VDC_HSR_256 = $0202 ; HDS HSW 569 | VDC_HDR_256 = $041F ; HDE HDW 570 | 571 | ; VDC constants for 320 & 336 wide display (Set VDC_MWR_1CYCLE). 572 | 573 | VCE_CR_7MHz = $01 ; 57 chr (actually 57.0) -> 456 pixel slots. 574 | 575 | VDC_HSR_320 = $0503 ; HDS HSW 576 | VDC_HDR_320 = $0627 ; HDE HDW 577 | 578 | VDC_HSR_336 = $0403 ; HDS HSW 579 | VDC_HDR_336 = $0529 ; HDE HDW 580 | 581 | VDC_HSR_344 = $0403 ; HDS HSW 582 | VDC_HDR_344 = $042A ; HDE HDW 583 | 584 | VDC_HSR_352 = $0303 ; HDS HSW 585 | VDC_HDR_352 = $042B ; HDE HDW 586 | 587 | ; VDC constants for 480 & 512 wide display (Set VDC_MWR_2CYCLE). 588 | 589 | VCE_CR_10MHz = $02 ; 86 chr (actually 85.5) -> 684 pixel slots. 590 | 591 | VDC_HSR_480 = $0D05 ; HDS HSW 592 | VDC_HDR_480 = $053B ; HDE HDW 593 | 594 | VDC_HSR_512 = $0B05 ; HDS HSW 595 | VDC_HDR_512 = $033F ; HDE HDW 596 | 597 | ; VDC constants for 200, 224 & 240 high display. 598 | ; 599 | ; N.B. 2 lines higher on the screen than the System Card. 600 | 601 | VDC_VPR_200 = $2102 602 | VDC_VDW_200 = $00C7 603 | VDC_VCR_200 = $0016 ; bios $00E2 604 | 605 | VDC_VPR_208 = $1E02 606 | VDC_VDW_208 = $00CF 607 | VDC_VCR_208 = $0013 ; bios $00EE 608 | 609 | VDC_VPR_224 = $1502 610 | VDC_VDW_224 = $00DF 611 | VDC_VCR_224 = $000B ; bios $00EE 612 | 613 | VDC_VPR_240 = $0D02 614 | VDC_VDW_240 = $00EF 615 | VDC_VCR_240 = $0003 ; bios $00F6 616 | 617 | ; VDC constants for different BAT screen sizes. 618 | 619 | VDC_MWR_32x32 = $0000 620 | VDC_MWR_32x64 = $0040 621 | 622 | VDC_MWR_64x32 = $0010 623 | VDC_MWR_64x64 = $0050 624 | 625 | VDC_MWR_128x32 = $0020 626 | VDC_MWR_128x64 = $0060 627 | -------------------------------------------------------------------------------- /pcengine.txt: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; https://www.renesas.com/sg/en/www/doc/application-note/an1695.pdf 5 | ; 6 | ; 21.47727MHz clock crystal / 24 -> 0.89MHz -> Tandy Color Computer CPU 7 | ; 21.47727MHz clock crystal / 21 -> 1.02MHz -> Commodore 64 CPU 8 | ; 21.47727MHz clock crystal / 12 -> 1.79MHz -> Atari 800 CPU 9 | ; 21.47727MHz clock crystal / 8 -> 2.68MHz -> SNES RAM 10 | ; 21.47727MHz clock crystal / 6 -> 3.58MHz -> SNES CPU / NTSC Color Modulation 11 | ; 21.47727MHz clock crystal / 6 -> 3.58MHz NTSC Color Modulation 12 | ; 13 | 14 | ; *************************************************************************** 15 | ; PC ENGINE VCE TIMING 16 | ; *************************************************************************** 17 | ; 18 | ; 21.47727MHz VCE clock crystal / 4 -> 5.36MHz VDC clock (186ns) 19 | ; 21.47727MHz VCE clock crystal / 3 -> 7.16MHz VDC clock (140ns) 20 | ; 21.47727MHz VCE clock crystal / 2 -> 10.74MHz VDC clock ( 93ns) 21 | ; 22 | ; 63.556us /hsync to /hsync total line time, i.e. 15734.2Hz NTSC 23 | ; 24 | ; 1365 VCE clocks @ 21.47727MHz 25 | ; 26 | ; -> 341.25 VDC cycles @ 5.36MHz (42.7 chr) 27 | ; -> 455.00 VDC cycles @ 7.16MHz (56.9 chr) 28 | ; -> 682.50 VDC cycles @ 10.74MHz (85.3 chr) 29 | ; 30 | ; 11.035us /hsync duration 31 | ; 32 | ; 237 VCE clocks @ 21.47727MHz 33 | ; 34 | ; -> 59.25 VDC clocks @ 5.36MHz 35 | ; -> 79.00 VDC clocks @ 7.16MHz 36 | ; -> 118.50 VDC clocks @ 10.74MHz 37 | ; 38 | ; Note : In the 5.36MHz mode, the 1st cycle in the hblank 39 | ; has an extra 1/4 cycle added (1 clock @ 21.47MHz). 40 | ; 41 | ; 16.651ms /vsync to /vsync total frame time, if VCE CR bit2 is 0 42 | ; 43 | ; 357,630 VCE clocks @ 21.47727MHz 44 | ; 45 | ; -> 119,210 CPU clocks @ 7.16MHz 46 | ; 47 | ; 16.715ms /vsync to /vsync total frame time, if VCE CR bit2 is 1 48 | ; 49 | ; 358,995 VCE clocks @ 21.47727MHz 50 | ; 51 | ; -> 119,665 CPU clocks @ 7.16MHz 52 | ; 53 | ; 1.907ms /vsync duration 54 | ; 55 | ; 4,095 VCE clocks @ 21.47727MHz 56 | ; 57 | ; -> 1,365 CPU clocks @ 7.16MHz 58 | ; 59 | 60 | 61 | 62 | ; *************************************************************************** 63 | ; PC ENGINE VDC SPRITES-PER-LINE LIMITS 64 | ; *************************************************************************** 65 | ; 66 | ; This is caused by the VDC running out of time to load the pixel data for 67 | ; the next line's sprites during the blank time after it is done displaying 68 | ; the current line's pixel data. 69 | ; 70 | ; 71 | ; VDC @ 5.36MHz -> width = total # chr on line = 42 chr 72 | ; VDC @ 7.16MHz -> width = total # chr on line = 56 chr 73 | ; VDC @ 10.74MHz -> width = total # chr on line = 85 chr 74 | ; 75 | ; Sprites-per-line shown (@ 1-clk-per-access) = (width - 2 - (hdw + 1)) * 2 76 | ; Sprites-per-line shown (@ 2-clk-per-access) = (width - 2 - (hdw + 1)) 77 | ; 78 | ; 79 | ; VDC @ 5.36MHz, MWR=$x0 (1-clk-per-access) 80 | ; 81 | ; hds $02 hdw $1F -> 32 chr = 256 pxl -> 16 sprites 82 | ; hds $02 hdw $20 -> 33 chr = 264 pxl -> 14 sprites 83 | ; hds $02 hdw $21 -> 34 chr = 272 pxl -> 12 sprites 84 | ; 85 | ; 86 | ; VDC @ 7.16MHz, MWR=$x0 (1-clk-per-access) 87 | ; 88 | ; hds $06 hdw $25 -> 38 chr = 304 pxl -> 16 sprites 89 | ; ... 90 | ; hds $03 hdw $2B -> 44 chr = 352 pxl -> 16 sprites 91 | ; hds $03 hdw $2C -> 45 chr = 360 pxl -> 16 sprites 92 | ; hds $03 hdw $2D -> 46 chr = 368 pxl -> 16 sprites 93 | ; hds $03 hdw $2E -> 47 chr = 376 pxl -> 14 sprites 94 | ; hds $03 hdw $2F -> 48 chr = 384 pxl -> 12 sprites 95 | ; 96 | ; 97 | ; VDC @ 7.16MHz, MWR=$xA (2-clk-per-access) 98 | ; 99 | ; hds $06 hdw $25 -> 38 chr = 304 pxl -> 16 sprites 100 | ; hds $05 hdw $26 -> 39 chr = 312 pxl -> 15 sprites 101 | ; hds $05 hdw $27 -> 40 chr = 320 pxl -> 14 sprites 102 | ; hds $04 hdw $28 -> 41 chr = 328 pxl -> 13 sprites 103 | ; hds $04 hdw $29 -> 42 chr = 336 pxl -> 12 sprites 104 | ; hds $03 hdw $2A -> 43 chr = 344 pxl -> 11 sprites 105 | ; hds $03 hdw $2B -> 44 chr = 352 pxl -> 10 sprites 106 | ; 107 | ; 108 | ; VDC @ 10.74MHz, MWR=$xA (2-clk-per-access) 109 | ; 110 | ; hds $0B hdw $3B -> 60 chr = 480 pxl -> 16 sprites 111 | ; ... 112 | ; hds $0B hdw $3F -> 64 chr = 512 pxl -> 16 sprites 113 | ; hds $0B hdw $40 -> 65 chr = 520 pxl -> 16 sprites 114 | ; hds $0B hdw $41 -> 66 chr = 528 pxl -> 16 sprites 115 | ; hds $0B hdw $42 -> 67 chr = 536 pxl -> 16 sprites 116 | ; hds $0B hdw $43 -> 68 chr = 544 pxl -> 15 sprites 117 | ; hds $0B hdw $44 -> 69 chr = 552 pxl -> 14 sprites 118 | ; 119 | 120 | 121 | 122 | ; *************************************************************************** 123 | ; PC ENGINE VDC RCR INTERRUPT TO BYR SHADOWED TIMING 124 | ; *************************************************************************** 125 | ; 126 | ; 127 | ; 5.36MHz (with MWR = $x0) 128 | ; 129 | ; Safe to write BYR @ 100 cpu cycles if width=240 hdw=$1D 130 | ; Safe to write BYR @ 90 cpu cycles if width=248 hdw=$1E 131 | ; Safe to write BYR @ 79 cpu cycles if width=256 hdw=$1F 132 | ; Safe to write BYR @ 67 cpu cycles if width=264 hdw=$20 133 | ; 134 | ; 135 | ; 7.16MHz (with MWR = $x0) 136 | ; 137 | ; Safe to write BYR @ 106 cpu cycles if width=320 hdw=$27 138 | ; Safe to write BYR @ 98 cpu cycles if width=328 hdw=$28 139 | ; Safe to write BYR @ 90 cpu cycles if width=336 hdw=$29 140 | ; Safe to write BYR @ 82 cpu cycles if width=344 hdw=$2A 141 | ; Safe to write BYR @ 74 cpu cycles if width=352 hdw=$2B 142 | ; 143 | ; 144 | ; 10.74MHz (with MWR = $xA) 145 | ; 146 | ; Safe to write BYR @ 112 cpu cycles if width=480 hdw=$3B 147 | ; Safe to write BYR @ 107 cpu cycles if width=488 hdw=$3C 148 | ; Safe to write BYR @ 101 cpu cycles if width=496 hdw=$3D 149 | ; Safe to write BYR @ 96 cpu cycles if width=504 hdw=$3E 150 | ; Safe to write BYR @ 91 cpu cycles if width=512 hdw=$3F 151 | ; Safe to write BYR @ 85 cpu cycles if width=520 hdw=$40 152 | ; Safe to write BYR @ 79 cpu cycles if width=528 hdw=$41 153 | ; Safe to write BYR @ 75 cpu cycles if width=536 hdw=$42 154 | ; Safe to write BYR @ 69 cpu cycles if width=544 hdw=$43 155 | ; 156 | ; 157 | ; Note: The VDC's hde,hsw, & hds settings have *NO* effect!!! 158 | ; 159 | ; Note: These cycle timings are to the write-cycle within the 160 | ; instruction, and not to the start of the instruction. 161 | ; 162 | ; Note: The VDC shadows/locks the BYR register a cycle before 163 | ; the BXR register, so write BYR first. After BXR, the 164 | ; CR register is shadowed/locked next. 165 | ; 166 | -------------------------------------------------------------------------------- /run.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem *************************************************************************** 4 | 5 | setlocal 6 | 7 | cd /d "%~dp0" 8 | 9 | start ..\mednafen\mednafen.exe teos.pce 10 | -------------------------------------------------------------------------------- /sd.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; sd.s 5 | ; 6 | ; Functions for using the SD card interface on the Turbo Everdrive v2. 7 | ; 8 | ; Copyright John Brandwood 2019. 9 | ; 10 | ; Distributed under the Boost Software License, Version 1.0. 11 | ; (See accompanying file LICENSE_1_0.txt or copy at 12 | ; http://www.boost.org/LICENSE_1_0.txt) 13 | ; 14 | ; *************************************************************************** 15 | ; *************************************************************************** 16 | ; 17 | ; For SD/MMC programming information, see ... 18 | ; 19 | ; "How to Use MMC/SDC" at http://elm-chan.org/docs/mmc/mmc_e.html 20 | ; 21 | ; *************************************************************************** 22 | ; *************************************************************************** 23 | 24 | 25 | 26 | ; *************************************************************************** 27 | ; *************************************************************************** 28 | ; 29 | ; Definitions 30 | ; 31 | 32 | ; Return Codes for the SD card functions. 33 | 34 | SDC_OK = $00 35 | 36 | SDC_ERR_TIMEOUT = $FF 37 | 38 | SDC_ERR_INIT = $80 39 | SDC_ERR_DSK_RD = $81 40 | SDC_ERR_DSK_WR = $82 41 | SDC_ERR_WR_CRC = $8B ; From SD Data Response code. 42 | SDC_ERR_WR_ERR = $8D ; From SD Data Response code. 43 | 44 | ; Print messages? 45 | 46 | SDC_PRINT_MESSAGES = 1 ; Should functions print error messages? 47 | 48 | ; MMC/SDC Command Codes. 49 | 50 | SDC_GO_IDLE_STATE = $40 ; CMD0 Software Reset. 51 | SDC_SEND_OP_COND = $41 ; CMD1 Initiate initialization process. 52 | SDC_SEND_IF_COND = $48 ; CMD8 SDC V2 only! Check voltage range. 53 | SDC_SEND_CID = $4A ; CMD10 Read CID register. 54 | SDC_STOP_TRANSMISSION = $4C ; CMD12 Stop reading blocks. 55 | SDC_SEND_STATUS = $4D ; CMD13 Send Status. 56 | SDC_SET_BLOCK_LENGTH = $50 ; CMD16 Change R/W block size (not SDHC/SDXC). 57 | SDC_READ_ONE_BLOCK = $51 ; CMD17 Read a block. 58 | SDC_READ_BLOCKS = $52 ; CMD18 Read multiple blocks. 59 | SDC_WRITE_ONE_BLOCK = $58 ; CMD24 Write a block. 60 | SDC_WRITE_BLOCKS = $59 ; CMD25 Write multiple blocks. 61 | SDC_APP_CMD = $77 ; CMD55 Leading command of ACMD command. 62 | SDC_READ_OCR = $7A ; CMD58 Read OCR. 63 | 64 | SDC_APP_SEND_NUM_WR_BLK = $56 ; ACMD22 SDC only! # of blocks written OK. 65 | SDC_APP_WRITE_ERASE_CNT = $57 ; ACMD23 SDC only! Set pre-erase count. 66 | SDC_APP_SEND_OP_COND = $69 ; ACMD41 SDC only! Begin initialization. 67 | 68 | SDC_WRITE_MUL_TOKEN = $FC ; Start of packet for write multiple blocks. 69 | SDC_STOP_TRAN_TOKEN = $FD ; Stop token for write multiple blocks. 70 | SDC_DATA_XFER_TOKEN = $FE ; Start of packet for read/write single block. 71 | 72 | SDC_DUMMY_CRC = $01 ; 7-bit CRC plus 1-bit tail. 73 | 74 | SDC_V2 = $40 ; MUST be $40!!! 75 | SDC_HC = $80 ; NZ if block addressing instead of byte. 76 | 77 | 78 | 79 | ; *************************************************************************** 80 | ; *************************************************************************** 81 | ; 82 | ; 83 | ; Data 84 | ; 85 | 86 | zp 87 | 88 | sdc_data_addr: ds 2 89 | 90 | bss 91 | 92 | sdc_cmd_param: ds 4 ; 32-bits (big-endian). 93 | sdc_block_num: ds 4 ; Current SD block number. 94 | sdc_block_cnt: ds 4 ; Block count (32-bit, but 32MB max). 95 | sdc_card_type: ds 1 ; card type bit0=SDHC bit1=v2 96 | sdc_data_bank: ds 1 ; TED2 512KB bank number. 97 | sdc_cid_value: ds 16 ; SD card's CID register. 98 | 99 | code 100 | 101 | sdc_zero: ds 2 ; zero 102 | 103 | if SDC_PRINT_MESSAGES 104 | 105 | _init_found_v2: db " SDC init found V2 card.",$0D,0 106 | _init_v2_sdhc: db " SDC init found SDHC card.",$0D,0 107 | _init_ready: db " SDC card ready.",$0D,0 108 | 109 | _init_ok: db " SDC init completed OK.",$0D,0 110 | _init_error: db " SDC init failed!",$0D,0 111 | 112 | _disk_read_err: db " SDC read sector failed!",$0D,0 113 | _disk_write_err:db " SDC write sector failed!",$0D,0 114 | 115 | endif 116 | 117 | 118 | 119 | ; *************************************************************************** 120 | ; *************************************************************************** 121 | ; 122 | ; sdc_initialize - Initialize the SD card. 123 | ; 124 | ; Returns: X = SDC_OK (and Z flag) or an error code. 125 | ; 126 | 127 | sdc_initialize: stz TED_BASE_ADDR + TED_REG_SPI_CFG 128 | 129 | stz sdc_card_type 130 | 131 | stz sdc_data_addr + 0 132 | stz sdc_data_addr + 1 133 | 134 | tai sdc_zero, sdc_block_num, 4 135 | 136 | ; Send > 74 clock pulses with CS off to enter native mode. 137 | 138 | TED_SPI_CS_OFF 139 | TED_SPI_SPD_LO 140 | 141 | ldx #24 142 | .reset_native: jsr spi_recv_byte 143 | dex 144 | bne .reset_native 145 | 146 | tai sdc_zero, sdc_cmd_param, 4 147 | 148 | ; Send CMD0 to turn SD card into SPI mode. 149 | 150 | lda #SDC_GO_IDLE_STATE 151 | ldx #$95 ; Valid CRC 152 | jsr sdc_send_cmd 153 | cpx #$01 ; "In Idle" state? 154 | beq .card_idle 155 | 156 | lda #SDC_GO_IDLE_STATE 157 | ldx #$95 ; Valid CRC 158 | jsr sdc_send_cmd 159 | cpx #$01 ; "In Idle" state? 160 | bne .card_error 161 | 162 | ; Send CMD8 to check SDCv2 voltage range. 163 | 164 | .card_idle: lda #$01 ; Set interface voltage 165 | sta sdc_cmd_param + 2 ; range to 2.7-3.6V. 166 | lda #$AA ; Set check pattern. 167 | sta sdc_cmd_param + 3 168 | 169 | lda #SDC_SEND_IF_COND 170 | ldx #$87 ; Valid CRC 171 | jsr sdc_send_cmd 172 | cpx #$01 ; Was the command accepted? 173 | bne .sdc_init 174 | 175 | jsr spi_recv_byte ; Skip 1st byte of response. 176 | jsr spi_recv_byte ; Skip 2nd byte of response. 177 | jsr spi_recv_byte ; Get the voltage range. 178 | and #$0F 179 | tay 180 | jsr spi_recv_byte ; Get the check pattern. 181 | cmp #$AA ; Confirm check pattern. 182 | bne .card_error 183 | cpy #$01 ; Confirm voltage range. 184 | bne .card_error 185 | 186 | lda #SDC_V2 ; We've got a Type 2 card! 187 | tsb sdc_card_type 188 | 189 | if SDC_PRINT_MESSAGES 190 | PUTS _init_found_v2 191 | endif 192 | 193 | .sdc_init: ldy #66 ; Set timeout to > 1 second. 194 | 195 | tai sdc_zero, sdc_cmd_param, 4 196 | 197 | .sdc_init_loop: stz sdc_cmd_param + 0 198 | 199 | lda #SDC_APP_CMD ; Send part 1 of APP command. 200 | ldx #SDC_DUMMY_CRC 201 | jsr sdc_send_cmd 202 | bmi .card_error ; Was there a timeout? 203 | cpx #$02 ; Was there an error? 204 | bcs .sdc_init_wait 205 | 206 | lda sdc_card_type ; SDCv2=$40 or SDCv1=$00 207 | sta sdc_cmd_param + 0 ; Because HCS flag is bit 30! 208 | 209 | lda #SDC_APP_SEND_OP_COND ; Send part 2 of the command, 210 | ldx #SDC_DUMMY_CRC ; to INITIALIZE the SD card. 211 | jsr sdc_send_cmd 212 | beq .sdc_ready ; Is the SD card initialized? 213 | bmi .card_error ; Was there a timeout? 214 | cpx #$01 ; Was there an error? 215 | bne .card_error 216 | 217 | .sdc_init_wait: jsr wait_vsync ; Delay before asking again. 218 | 219 | dey ; Still waiting for the 220 | bne .sdc_init_loop ; card to initialize? 221 | 222 | .card_error: bsr spi_recv_byte ; Wait 8clk before halting SPI. 223 | 224 | ldx #SDC_ERR_INIT ; Timeout or Error. 225 | bra .sdc_init_done 226 | 227 | .sdc_ready: stz sdc_cmd_param + 0 228 | 229 | if SDC_PRINT_MESSAGES 230 | PUTS _init_ready 231 | endif 232 | 233 | tst #SDC_V2,sdc_card_type 234 | beq .sdc_blocklen 235 | 236 | lda #SDC_READ_OCR ; Send CMD58 to read the OCR. 237 | ldx #SDC_DUMMY_CRC 238 | bsr sdc_send_cmd 239 | bne .card_error 240 | 241 | bsr spi_recv_byte ; Read top byte of OCR. 242 | and #$40 ; Save the HCS bit. 243 | tax 244 | bsr spi_recv_byte ; Skip 2nd byte of OCR. 245 | bsr spi_recv_byte ; Skip 3rd byte of OCR. 246 | bsr spi_recv_byte ; Skip btm byte of OCR. 247 | txa ; Check the HCS bit. 248 | beq .sdc_blocklen 249 | 250 | lda #SDC_HC ; Card uses block addressing! 251 | tsb sdc_card_type 252 | 253 | if SDC_PRINT_MESSAGES 254 | PUTS _init_v2_sdhc 255 | endif 256 | 257 | bra .sdc_init_ok 258 | 259 | .sdc_blocklen: lda #>512 ; Set block len to 512 bytes 260 | sta sdc_cmd_param + 2 ; if not an HC card. 261 | ; stz sdc_cmd_param + 3 262 | 263 | lda #SDC_SET_BLOCK_LENGTH 264 | ldx #SDC_DUMMY_CRC 265 | bsr sdc_send_cmd 266 | bne .card_error 267 | 268 | .sdc_init_ok: stz sdc_cmd_param + 2 269 | 270 | lda #SDC_SEND_CID ; Send CMD4A to read the CID. 271 | ldx #SDC_DUMMY_CRC 272 | bsr sdc_send_cmd 273 | bne .card_error 274 | 275 | clx ; Wait for the CID data block. 276 | cly 277 | .sdc_wait_cid: bsr spi_recv_byte 278 | cmp #SDC_DATA_XFER_TOKEN 279 | beq .sdc_xfer_cid 280 | dey 281 | bne .sdc_wait_cid 282 | bra .card_error ; Timeout! 283 | 284 | .sdc_xfer_cid: bsr spi_recv_byte ; Read 16-byte unique Card ID. 285 | sta sdc_cid_value,x 286 | inx 287 | cpx #16 288 | bne .sdc_xfer_cid 289 | 290 | bsr spi_recv_byte ; Skip 2-byte CRC. 291 | bsr spi_recv_byte 292 | 293 | bsr spi_recv_byte ; Wait 8clk before halting SPI. 294 | 295 | ldx #SDC_OK 296 | 297 | TED_SPI_SPD_HI ; OK to do this now. 298 | 299 | .sdc_init_done: TED_SPI_CS_OFF ; All done, deselect the card. 300 | 301 | txa ; Set the N & Z result flags. 302 | rts 303 | 304 | 305 | 306 | ; *************************************************************************** 307 | ; *************************************************************************** 308 | ; 309 | ; spi_recv_byte - Get a byte from the SD card. 310 | ; spi_send_byte - Send a byte to the SD card. 311 | ; 312 | ; Preserves X & Y registers. 313 | ; 314 | 315 | spi_recv_byte: lda #$FF 316 | spi_send_byte: sta TED_BASE_ADDR + TED_REG_SPI 317 | TED_SPI_WAIT 318 | lda TED_BASE_ADDR + TED_REG_SPI 319 | rts 320 | 321 | 322 | 323 | ; *************************************************************************** 324 | ; *************************************************************************** 325 | ; 326 | ; sdc_send_cmd - Send a command packet to the SD card. 327 | ; 328 | ; A = CMD value, X = CRC value. 329 | ; 330 | ; Returns: X = result code (and Z flag) or $FF if timeout. 331 | ; 332 | ; Preserves Y register. 333 | ; 334 | 335 | sdc_send_cmd: pha ; Preserve CMD parameter. 336 | 337 | TED_SPI_WAIT ; Wait if SPI bus busy. 338 | 339 | TED_SPI_CS_OFF ; Cycle the CARD_SELECT. 340 | bsr spi_recv_byte 341 | TED_SPI_CS_ON 342 | bsr spi_recv_byte 343 | 344 | pla ; Send CMD. 345 | pha 346 | bsr spi_send_byte 347 | 348 | lda sdc_cmd_param + 0 ; Send ARG (32-bit big-endian). 349 | bsr spi_send_byte 350 | lda sdc_cmd_param + 1 351 | bsr spi_send_byte 352 | lda sdc_cmd_param + 2 353 | bsr spi_send_byte 354 | lda sdc_cmd_param + 3 355 | bsr spi_send_byte 356 | 357 | txa ; Send CRC. 358 | bsr spi_send_byte 359 | 360 | clx 361 | 362 | ; Discard the byte after SDC_STOP_TRANSMISSION. 363 | 364 | pla 365 | cmp #SDC_STOP_TRANSMISSION 366 | bne .wait 367 | bsr spi_recv_byte 368 | 369 | ; Wait for response (0..8 bytes in SD specification). 370 | 371 | .wait: bsr spi_recv_byte 372 | cmp #$FF 373 | bne .done 374 | dex 375 | bne .wait 376 | 377 | ; Timeout waiting for response! 378 | 379 | .done: tax ; Return response code in X. 380 | rts 381 | 382 | 383 | 384 | ; *************************************************************************** 385 | ; *************************************************************************** 386 | ; 387 | ; sdc_set_blk_arg - Copy the current block number to the SD cmd parameters. 388 | ; 389 | ; Args: sdc_block_num (little-endian) 390 | ; Uses: sdc_cmd_param (big-endian) 391 | ; 392 | 393 | sdc_set_blk_arg:lda sdc_card_type ; Check the SDC_HC flag. 394 | bpl .byte_address 395 | 396 | .block_address: lda sdc_block_num+0 397 | sta sdc_cmd_param+3 398 | lda sdc_block_num+1 399 | sta sdc_cmd_param+2 400 | lda sdc_block_num+2 401 | sta sdc_cmd_param+1 402 | lda sdc_block_num+3 403 | sta sdc_cmd_param+0 404 | rts 405 | 406 | ; Standard SD cards take a byte address. 407 | ; So multiply sector number by 512. 408 | 409 | .byte_address: stz sdc_cmd_param+3 410 | lda sdc_block_num+0 411 | asl a 412 | sta sdc_cmd_param+2 413 | lda sdc_block_num+1 414 | rol a 415 | sta sdc_cmd_param+1 416 | lda sdc_block_num+2 417 | rol a 418 | sta sdc_cmd_param+0 419 | rts 420 | 421 | 422 | 423 | ; *************************************************************************** 424 | ; *************************************************************************** 425 | ; 426 | ; sdc_read_data - Read one or more 512-byte blocks. 427 | ; 428 | ; Args: sdc_data_bank 429 | ; Args: sdc_data_addr 430 | ; Args: sdc_block_num 431 | ; Args: sdc_block_cnt 432 | ; 433 | ; Returns: X = SDC_OK (and Z flag) or an error code. 434 | ; 435 | ; Notes: 436 | ; 437 | ; The sdc_data_addr destination MUST be < $8000, and also 512-byte aligned 438 | ; if using the auto-incrementing bank capability. 439 | ; 440 | ; When the sdc_data_addr increments to >= $8000, then the next PCE bank 441 | ; is mapped into MPR3, and reading continues. 442 | ; 443 | ; This also handles wrapping into new 512KB regions of TED2 memory. 444 | ; 445 | 446 | sdc_read_data: if REALHW 447 | 448 | jsr sdc_set_blk_arg ; Set the block num parameter. 449 | 450 | lda sdc_block_cnt + 0 ; Check for zero blocks. 451 | cmp #2 452 | ora sdc_block_cnt + 1 453 | tax ; Zero returns SDC_OK. 454 | beq .all_done 455 | lda sdc_block_cnt + 1 456 | sbc #0 ; Set C if >= 2 blocks. 457 | 458 | .send_cmd: php ; Preserve C flag. 459 | 460 | cla ; If == 1, SDC_READ_ONE_BLOCK. 461 | adc #SDC_READ_ONE_BLOCK ; If >= 2, SDC_READ_BLOCKS. 462 | ldx #SDC_DUMMY_CRC 463 | jsr sdc_send_cmd 464 | bne .read_error 465 | 466 | .read_data: jsr spi_rd_fast ; Read the blocks from SD card. 467 | 468 | plp ; Restore the C flag. 469 | bcc .all_done ; Was this a multiple read? 470 | 471 | .stop_data: phx ; Preserve result. 472 | 473 | tai sdc_zero, sdc_cmd_param, 4 474 | 475 | lda #SDC_STOP_TRANSMISSION ; Send SDC_STOP_TRANSMISSION. 476 | ldx #SDC_DUMMY_CRC 477 | jsr sdc_send_cmd ; Returns garbage! 478 | 479 | .busy: jsr spi_recv_byte ; Wait for the busy to be done. 480 | cmp #$FF 481 | bne .busy 482 | 483 | plx ; Restore result. 484 | 485 | .all_done: jsr spi_recv_byte ; Wait 8clk before halting SPI. 486 | 487 | TED_SPI_CS_OFF 488 | 489 | txa ; Set flags for result. 490 | 491 | if SDC_PRINT_MESSAGES 492 | beq .exit ; Report the error. 493 | phx 494 | PUTS _disk_read_err 495 | plx 496 | .exit: 497 | endif 498 | 499 | rts ; Return the result. 500 | 501 | .read_error: plp 502 | bra .all_done 503 | 504 | 505 | ; ********************************** 506 | 507 | 508 | else 509 | 510 | tma2 511 | pha 512 | tma3 513 | pha 514 | 515 | lda #$07 ; For testing in Mednafen. 516 | tam2 ; Contains SD card sector data. 517 | inc a 518 | tam3 519 | 520 | lda sdc_block_num + 3 521 | bne .blank 522 | 523 | ldx #$FF 524 | .next: inx 525 | lda fake_sector_h,x 526 | bmi .blank 527 | cmp sdc_block_num + 2 528 | bne .next 529 | lda fake_sector_m,x 530 | cmp sdc_block_num + 1 531 | bne .next 532 | lda fake_sector_l,x 533 | cmp sdc_block_num + 0 534 | bne .next 535 | 536 | bsr .vector 537 | 538 | pla 539 | tam3 540 | pla 541 | tam2 542 | 543 | ldx #$00 544 | bra .success 545 | 546 | .blank: 547 | ; stz f32_cache_buf 548 | ; tii f32_cache_buf,f32_cache_buf+1,511 549 | ldx #$00 550 | bra .success 551 | 552 | .vector: txa 553 | asl a 554 | tax 555 | jmp [fake_sector_tii,x] 556 | 557 | .other: ldx #SDC_ERR_DSK_RD 558 | bra .error 559 | 560 | .success: TED_SPI_CS_OFF 561 | 562 | cpx #$00 563 | rts 564 | 565 | .error: phx 566 | PUTS _disk_read_err 567 | plx 568 | 569 | TED_SPI_CS_OFF 570 | 571 | cpx #$00 572 | rts 573 | 574 | endif 575 | 576 | ; ********************************** 577 | 578 | 579 | 580 | ; *************************************************************************** 581 | ; *************************************************************************** 582 | ; 583 | ; spi_rd_fast - Hardware-accelerated sector read from SD card to RAM. 584 | ; 585 | ; Args: sdc_data_bank 586 | ; Args: sdc_data_addr 587 | ; Args: sdc_block_cnt 588 | ; 589 | ; Returns: X = SDC_OK (and Z flag) or an error code. 590 | ; 591 | ; Notes: 592 | ; 593 | ; The sdc_data_addr destination MUST be < $8000, and also 512-byte aligned 594 | ; if using the auto-incrementing bank capability. 595 | ; 596 | ; When the sdc_data_addr increments to >= $8000, then the next PCE bank 597 | ; is mapped into MPR3, and reading continues. 598 | ; 599 | ; This also handles wrapping into new 512KB regions of TED2 memory. 600 | ; 601 | 602 | spi_rd_fast: TED_SPI_ARD_ON 603 | 604 | lda = $8000, then the next PCE bank 691 | ; is mapped into MPR3, and reading continues. 692 | ; 693 | ; This also handles wrapping into new 512KB regions of TED2 memory. 694 | ; 695 | 696 | sdc_write_data: lda sdc_block_cnt + 0 ; Check for zero blocks. 697 | cmp #2 698 | ora sdc_block_cnt + 1 699 | bne .non_zero 700 | 701 | tax ; Zero returns SDC_OK. 702 | rts ; Return the result. 703 | 704 | .cmd_failed: plp ; Discard the C flag. 705 | bra .finished 706 | 707 | .non_zero: lda sdc_block_cnt + 1 708 | sbc #0 ; Set C if >= 2 blocks. 709 | php ; Preserve C flag. 710 | bcc .start_write 711 | 712 | ; Tell the SD card how many blocks we're writing. 713 | 714 | tai sdc_zero, sdc_cmd_param, 4 715 | 716 | lda #SDC_APP_CMD ; Send part 1 of APP command. 717 | ldx #SDC_DUMMY_CRC 718 | jsr sdc_send_cmd 719 | bne .cmd_failed 720 | 721 | lda sdc_block_cnt + 1 ; Send part 2 with block count. 722 | sta sdc_cmd_param + 2 723 | lda sdc_block_cnt + 0 724 | sta sdc_cmd_param + 3 725 | 726 | lda #SDC_APP_WRITE_ERASE_CNT 727 | ldx #SDC_DUMMY_CRC 728 | jsr sdc_send_cmd 729 | bne .cmd_failed 730 | 731 | ; Write the block(s). 732 | 733 | .start_write: jsr sdc_set_blk_arg ; Set the block num parameter. 734 | 735 | ldy #SDC_DATA_XFER_TOKEN ; Set token for data block. 736 | plp ; Is this a multiple write? 737 | bcc .send_cmd 738 | ldy #SDC_WRITE_MUL_TOKEN 739 | .send_cmd: php ; Preserve C flag. 740 | 741 | cla ; If == 1, SDC_WRITE_ONE_BLOCK. 742 | adc #SDC_WRITE_ONE_BLOCK ; If >= 2, SDC_WRITE_BLOCKS. 743 | ldx #SDC_DUMMY_CRC 744 | jsr sdc_send_cmd 745 | bne .cmd_failed 746 | 747 | .write_data: jsr spi_recv_byte ; Delay write for 1 byte. 748 | 749 | jsr spi_wr_slow ; Write the blocks to SD card. 750 | 751 | plp ; Restore the C flag. 752 | bcc .check_write ; Was this a multiple write? 753 | 754 | lda #SDC_STOP_TRAN_TOKEN ; Stop multiple block write. 755 | jsr spi_send_byte 756 | jsr spi_recv_byte ; Delay for 1 byte. 757 | .busy: jsr spi_recv_byte ; Wait for the busy to be done. 758 | cmp #$FF 759 | bne .busy 760 | 761 | .check_write: txa ; Was there are error in the 762 | bne .finished ; transfer to the SD card? 763 | 764 | tai sdc_zero, sdc_cmd_param, 4 765 | 766 | lda #SDC_SEND_STATUS ; Check the status of the 767 | ldx #SDC_DUMMY_CRC ; actual write itself. 768 | jsr sdc_send_cmd 769 | jsr spi_recv_byte ; Get 2nd byte of status. 770 | bne .write_failed 771 | txa ; X == 0 == SDC_OK if no error. 772 | beq .finished 773 | 774 | .write_failed: if 0 775 | 776 | stz sdc_block_cnt + 0 777 | stz sdc_block_cnt + 1 778 | 779 | lda #SDC_APP_CMD ; Send part 1 of APP command. 780 | ldx #SDC_DUMMY_CRC 781 | jsr sdc_send_cmd 782 | bne .count_done 783 | 784 | lda #SDC_APP_SEND_NUM_WR_BLK; Send part 2 to get count. 785 | ldx #SDC_DUMMY_CRC ; of successfully written blks. 786 | jsr sdc_send_cmd 787 | bne .count_done 788 | 789 | ldx #$80 ; Wait for the block count. 790 | .wait_count: jsr spi_recv_byte ; (0..8 bytes per the SD 791 | cmp #SDC_DATA_XFER_TOKEN ; specification). 792 | beq .xfer_count 793 | dex 794 | bne .wait_count 795 | bra .count_done ; Timeout! 796 | 797 | .xfer_count: jsr spi_recv_byte ; Read 4-byte blk count. 798 | jsr spi_recv_byte 799 | jsr spi_recv_byte 800 | sta sdc_block_cnt + 1 801 | jsr spi_recv_byte 802 | sta sdc_block_cnt + 0 803 | 804 | jsr spi_recv_byte ; Skip 2-byte CRC. 805 | jsr spi_recv_byte 806 | 807 | .count_done: 808 | 809 | endif 810 | 811 | ldx #SDC_ERR_WR_ERR ; Signal that the write failed. 812 | 813 | .finished: jsr spi_recv_byte ; Wait 8clk before halting SPI. 814 | 815 | TED_SPI_CS_OFF 816 | 817 | txa ; Set flags for result. 818 | 819 | if SDC_PRINT_MESSAGES 820 | beq .exit ; Report the error. 821 | phx 822 | PUTS _disk_write_err 823 | plx 824 | .exit: 825 | endif 826 | 827 | rts ; Return the result. 828 | 829 | 830 | 831 | ; *************************************************************************** 832 | ; *************************************************************************** 833 | ; 834 | ; spi_wr_slow - Write one or more data packets to the SPI. 835 | ; 836 | ; Args: sdc_data_bank 837 | ; Args: sdc_data_addr 838 | ; Args: sdc_block_cnt 839 | ; 840 | ; Returns: X = SDC_OK (and Z flag) or an error code. 841 | ; 842 | ; Notes: 843 | ; 844 | ; The sdc_data_addr destination MUST be < $8000, and also 512-byte aligned 845 | ; if using the auto-incrementing bank capability. 846 | ; 847 | ; When the sdc_data_addr increments to >= $8000, then the next PCE bank 848 | ; is mapped into MPR3, and reading continues. 849 | ; 850 | ; This also handles wrapping into new 512KB regions of TED2 memory. 851 | ; 852 | 853 | spi_wr_slow: phy ; Preserve data-start token. 854 | tya 855 | jsr spi_send_byte ; Send data-start token. 856 | 857 | bsr .write_page ; Send 1st 256 bytes of data. 858 | bsr .write_page ; Send 2nd 256 bytes of data. 859 | 860 | jsr spi_recv_byte ; Send 1st byte of dummy CRC. 861 | jsr spi_recv_byte ; Send 2nd byte of dummy CRC. 862 | 863 | jsr spi_recv_byte ; Get the response code. 864 | pha 865 | 866 | .busy: jsr spi_recv_byte ; Wait for the busy to be done, 867 | cmp #$FF ; and allow 8 clocks after xfer 868 | bne .busy ; before halting SPI clock. 869 | 870 | pla ; Check the response code. 871 | and #$1F 872 | ora #$80 ; Make any error negative. 873 | tax 874 | ply ; Restore data-start token. 875 | 876 | cpx #$85 ; Was the data accepted? 877 | bne .error 878 | 879 | lda \1 36 | jsr tos_print_msg 37 | endm 38 | 39 | ; 40 | ; 41 | ; 42 | 43 | 44 | list 45 | mlist 46 | 47 | ASCII_HI = $01 48 | 49 | zp 50 | 51 | view: ds 2 52 | 53 | bss 54 | org $22D0 55 | 56 | data 57 | 58 | code 59 | 60 | 61 | 62 | ; *************************************************************************** 63 | ; *************************************************************************** 64 | ; 65 | ; 66 | ; 67 | 68 | WRAM_BANK = $05 ; Writable in TED2. 69 | FRAG_BANK = $06 ; Writable in TED2. 70 | 71 | BRAM_BANK = $20 ; 128KB allowed for MB128 72 | SLOT_BANK = $30 ; 128KB allowed for MB128 73 | 74 | 75 | 76 | ; *************************************************************************** 77 | ; *************************************************************************** 78 | ; 79 | ; 80 | ; 81 | 82 | include "teos_bank0.s" 83 | include "teos_bank1.s" 84 | include "teos_bank2.s" 85 | include "teos_bank3.s" 86 | 87 | if REALHW 88 | else 89 | include "fakesd.s" 90 | endif 91 | -------------------------------------------------------------------------------- /teos_bank1.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; BANK $01 - LIBRARY CODE 5 | ; 6 | ; Copyright John Brandwood 2019. 7 | ; 8 | ; Distributed under the Boost Software License, Version 1.0. 9 | ; (See accompanying file LICENSE_1_0.txt or copy at 10 | ; http://www.boost.org/LICENSE_1_0.txt) 11 | ; 12 | ; *************************************************************************** 13 | ; *************************************************************************** 14 | 15 | 16 | 17 | .bank 1 18 | .org $A000 19 | 20 | include "mb128.s" 21 | include "huc6280.s" 22 | include "osfunc.s" 23 | include "filefuncs.s" 24 | -------------------------------------------------------------------------------- /teos_bank2.s: -------------------------------------------------------------------------------- 1 | ; *************************************************************************** 2 | ; *************************************************************************** 3 | ; 4 | ; BANK $02 - MENU SCREENS 5 | ; 6 | ; Copyright John Brandwood 2019. 7 | ; 8 | ; Distributed under the Boost Software License, Version 1.0. 9 | ; (See accompanying file LICENSE_1_0.txt or copy at 10 | ; http://www.boost.org/LICENSE_1_0.txt) 11 | ; 12 | ; *************************************************************************** 13 | ; *************************************************************************** 14 | 15 | 16 | 17 | bank 2 18 | org $C000 19 | 20 | include "menu_init.s" 21 | include "menu_hucard.s" 22 | include "menu_bram.s" 23 | include "menu_mb128.s" 24 | include "menu_info.s" 25 | -------------------------------------------------------------------------------- /text.s: -------------------------------------------------------------------------------- 1 | .include "pce.inc" 2 | .include "macro.inc" 3 | .include "ted2.inc" 4 | .include "sd.inc" 5 | 6 | .export _text 7 | .export _ed_test 8 | 9 | .exportzp _view 10 | .exportzp _line 11 | .export _show_page 12 | .exportzp _string 13 | .export _show_string 14 | 15 | .importzp _ed_data_ptr 16 | 17 | 18 | _al = $20f8 19 | 20 | member = $04 21 | 22 | .zeropage 23 | 24 | .feature bracket_as_indirect 25 | 26 | _string: .word 0 27 | _view: .word 0 28 | _line: .byte 0 29 | 30 | .data 31 | 32 | .segment "SDCODE" 33 | 34 | _text: .asciiz "Hello world!" 35 | 36 | _read_sect_0: .asciiz "read_sector_0" 37 | _read_sect_1: .asciiz "read_sector_1" 38 | 39 | .macro PUTS addr 40 | ldx #addr 42 | jsr _show_string 43 | .endmacro 44 | 45 | ; 46 | ; 47 | ; 48 | 49 | _ed_test: cld 50 | 51 | stz _line 52 | jsr _clear_screen 53 | 54 | php 55 | 56 | TED_UNLOCK 57 | TED2_SET_CFG_1MB_RAM 58 | 59 | jsr _clear_ram 60 | 61 | ; 62 | ; 63 | ; 64 | 65 | @skip_sf2: TED_SET_CFG_FPGA 66 | 67 | lda #$6c ; 767KB 68 | tam #$40 ; $C000-$DFFF 69 | 70 | jsr _disk_init 71 | 72 | stx $c004 73 | stw #$c000, _view 74 | jsr _show_page 75 | stw #$d000, _view 76 | jsr _show_page 77 | stw #$d1f0, _view 78 | jsr _show_page 79 | 80 | PUTS _read_sect_0 81 | 82 | lda #$01 83 | sta <_ed_sect_cnt 84 | stw #$0000, _ed_dsk_addr+0 85 | stw #$0000, _ed_dsk_addr+2 86 | stw #$d000, _ed_data_ptr 87 | 88 | jsr _disk_read_sector 89 | 90 | stx $c006 91 | stw #$c000, _view 92 | jsr _show_page 93 | stw #$d1be, _view 94 | jsr _show_page 95 | stw #$d1f0, _view 96 | jsr _show_page 97 | 98 | stw #$d200, _view 99 | jsr _show_page 100 | stw #$d3f0, _view 101 | jsr _show_page 102 | 103 | PUTS _read_sect_1 104 | 105 | lda #$03 106 | sta <_ed_sect_cnt 107 | ; stw #$0800, _ed_dsk_addr+0 108 | stw #$0a3a, _ed_dsk_addr+0 109 | stw #$0000, _ed_dsk_addr+2 110 | stw #$d000, _ed_data_ptr 111 | 112 | jsr _disk_read_sector 113 | 114 | stx $c006 115 | stw #$c000, _view 116 | jsr _show_page 117 | stw #$d000, _view 118 | jsr _show_page 119 | stw #$d1f0, _view 120 | jsr _show_page 121 | 122 | stw #$d200, _view 123 | jsr _show_page 124 | stw #$d3f0, _view 125 | jsr _show_page 126 | 127 | stw #$d400, _view 128 | jsr _show_page 129 | stw #$d5f0, _view 130 | jsr _show_page 131 | 132 | @hang2: bra @hang2 133 | 134 | ; jsr _disk_read_sector 135 | 136 | stx $c006 137 | stw #$c000, _view 138 | jsr _show_page 139 | 140 | stw #$d000, _view 141 | jsr _show_page 142 | 143 | lda #$01 144 | sta <_ed_sect_cnt 145 | stw #$0000, _ed_dsk_addr+0 146 | stw #$0000, _ed_dsk_addr+2 147 | stw #$d000, _ed_data_ptr 148 | 149 | jsr _disk_read_sector 150 | 151 | stw #$d000, _view 152 | jsr _show_page 153 | 154 | lda #$00 ; 767KB 155 | tam #$40 ; $C000-$DFFF 156 | 157 | TED2_SET_CFG_1MB_RAM 158 | 159 | @hang: bra @hang 160 | 161 | jmp [$fffe] 162 | 163 | jmp [$fffe,x] 164 | 165 | plp 166 | rts 167 | 168 | ; 169 | ; 170 | ; 171 | 172 | _clear_ram: lda #$08 173 | clx 174 | 175 | ldy #$ff 176 | ldy #$00 177 | ldy #$88 178 | 179 | @clear_loop: tam #$40 ; $C000-$DFFF 180 | sta $C000 181 | stx $C001 182 | sta $C002 183 | stx $C003 184 | sty $C004 185 | tii $C004,$C005,$1ffb 186 | inc a 187 | cmp #$80 188 | bne @clear_loop 189 | rts 190 | 191 | ; 192 | ; 193 | ; 194 | 195 | _clear_screen: php 196 | sei 197 | st0 #VDC_MAWR 198 | st1 #$00 199 | st2 #$00 200 | st0 #VDC_VWR 201 | ldx #$10 ; $0000-$1FFF 202 | cly 203 | st1 #$00 204 | @word_loop: st2 #$00 205 | dey 206 | bne @word_loop 207 | dex 208 | bne @word_loop 209 | plp 210 | rts 211 | 212 | ; 213 | ; 214 | ; 215 | 216 | _show_page: cld 217 | cly 218 | 219 | @line_loop: st0 #VDC_MAWR 220 | 221 | lda _line 222 | lsr a 223 | tax 224 | cla 225 | ror a 226 | sta VDC_DATA_LO 227 | stx VDC_DATA_HI 228 | 229 | st0 #VDC_VWR 230 | 231 | phy 232 | 233 | @byte_loop: lda [_view],y 234 | lsr a 235 | lsr a 236 | lsr a 237 | lsr a 238 | ora #$30 239 | cmp #$3a 240 | bcc @skip_lo 241 | adc #6 242 | @skip_lo: sta VDC_DATA_LO 243 | st2 #$12 244 | 245 | lda [_view],y 246 | and #$0f 247 | ora #$30 248 | cmp #$3a 249 | bcc @skip_hi 250 | adc #6 251 | @skip_hi: sta VDC_DATA_LO 252 | st2 #$12 253 | 254 | iny 255 | tya 256 | bit #$01 257 | bne @skip_space 258 | 259 | st1 #$20 260 | st2 #$12 261 | 262 | @skip_space: bit #$0f 263 | bne @byte_loop 264 | 265 | ply 266 | 267 | @char_loop: lda [_view],y 268 | cmp #$20 269 | bcc @non_ascii 270 | cmp #$7f 271 | bcc @show_char 272 | @non_ascii: lda #'.' 273 | @show_char: sta VDC_DATA_LO 274 | st2 #$12 275 | 276 | iny 277 | tya 278 | bit #$0f 279 | bne @char_loop 280 | 281 | inc _line 282 | cpy #$40 283 | cpy #$10 284 | bne @line_loop 285 | 286 | ; inc _line 287 | 288 | rts 289 | 290 | 291 | ; 292 | ; 293 | ; 294 | 295 | _show_string: stx _string 296 | sta _string+1 297 | 298 | st0 #VDC_MAWR 299 | 300 | lda _line 301 | lsr a 302 | tax 303 | cla 304 | ror a 305 | sta VDC_DATA_LO 306 | stx VDC_DATA_HI 307 | 308 | st0 #VDC_VWR 309 | 310 | cly 311 | 312 | @char_loop: lda [_string],y 313 | beq @finished 314 | sta VDC_DATA_LO 315 | st2 #$12 316 | iny 317 | bra @char_loop 318 | 319 | @finished: inc _line 320 | 321 | rts 322 | --------------------------------------------------------------------------------