migrated to ACME assembler
commit 145d64aa6e78838ed07cefed372f0ad6a4687e97 Author: FeralChild64 <you@example.com> Date: Sun Sep 20 20:16:57 2020 +0200 ACME adaptation commit 885209d7822286744ea53232ae7461472a01d5d6 Author: FeralChild64 <you@example.com> Date: Sun Sep 20 19:57:25 2020 +0200 ACME adaptation commit 334d84486bc603551887e7cbeb59d329f2224cc7 Author: FeralChild64 <you@example.com> Date: Sun Sep 20 18:29:15 2020 +0200 ACME adaptation commit b5966f49bcd8f0ca79cbec93819a31238924707e Author: FeralChild64 <you@example.com> Date: Sun Sep 20 18:09:31 2020 +0200 ACME adaptation commit 786536a93a5eab5e676fca99625b4eb094a554e7 Author: FeralChild64 <you@example.com> Date: Sun Sep 20 17:24:48 2020 +0200 ACME adaptation commit 704c70dfb1f5d68775d6f3da220803b8a3990f56 Author: FeralChild64 <you@example.com> Date: Sun Sep 20 15:07:12 2020 +0200 ACME adaptation commit 136874964c9083b375f151475310f9636871fc72 Author: FeralChild64 <you@example.com> Date: Sun Sep 20 14:45:14 2020 +0200 ACME adaptation commit 8eca0d5700b72d04336e72c5cd3a68e18b85f96d Author: FeralChild64 <you@example.com> Date: Sun Sep 20 14:06:52 2020 +0200 ACME adaptation commit 11d29eb7ee318239d782f85498b6d0524624d5c4 Author: FeralChild64 <you@example.com> Date: Sun Sep 20 13:56:45 2020 +0200 ACME apaptation commit c9b5e5e04cceb92c66bc027e6440bc0f7c5a499f Author: FeralChild64 <you@example.com> Date: Sun Sep 20 13:49:04 2020 +0200 ACME adaptation commit f5cc254cbc921f07863807468cb3fe26b410b409 Author: FeralChild64 <you@example.com> Date: Sun Sep 20 13:01:18 2020 +0200 ACME adaptation commit e135a27bf9c30cc0965379c954564e06406303b1 Author: FeralChild64 <you@example.com> Date: Sat Sep 19 21:55:01 2020 +0200 ACME adaptation commit e9dfddf90d9e2795e88b7da40ae050d733faeb56 Author: FeralChild64 <you@example.com> Date: Sat Sep 19 21:48:47 2020 +0200 Makefile fix commit 07030104c65cf5e5beeacf6d629ccb9245e58657 Author: FeralChild64 <you@example.com> Date: Sat Sep 19 21:42:00 2020 +0200 ACME adaptation commit f824362ee5bcfbffca86c430b57773b2ffd65655 Author: FeralChild64 <you@example.com> Date: Sat Sep 19 20:14:56 2020 +0200 ACME adaptation commit 3a3c59007dcd4940d89b8669f34ca56b61c25fdf Author: FeralChild64 <you@example.com> Date: Fri Sep 18 21:51:45 2020 +0200 ACME adaptation commit 6790ef7bc88a41de2881c69b7524dd4ab8c74b5d Author: FeralChild64 <you@example.com> Date: Fri Sep 18 20:35:23 2020 +0200 ACME adaptation commit 38ad18b90e9ec713aa7ca49576b3388ce1733357 Author: FeralChild64 <you@example.com> Date: Fri Sep 18 18:46:20 2020 +0200 ACME adaptation commit 541340371122a9702f7b2d9771c298223cffd0e9 Author: FeralChild64 <you@example.com> Date: Fri Sep 18 16:49:46 2020 +0200 ACME adaptation commit 25cfd5e186459be1a260d3eb8cfff767838de370 Author: FeralChild64 <you@example.com> Date: Thu Sep 17 20:13:33 2020 +0200 ACME adaptation commit f61599444d5b1d03d8fd8e4a6a7c3b85069bedb3 Author: FeralChild64 <you@example.com> Date: Thu Sep 17 19:29:23 2020 +0200 ACME adaptation commit b290be31ec7bb2e5723607697da1bbc621c84429 Author: FeralChild64 <you@example.com> Date: Thu Sep 17 17:20:14 2020 +0200 ACME adaptation commit 877be9e856880d98fd4bcb25b42aaaacda9dc463 Author: FeralChild64 <you@example.com> Date: Wed Sep 16 21:47:38 2020 +0200 ACME adaptation commit bb20edaf85d386e41d5c2f715b745b68fbd3362e Author: FeralChild64 <you@example.com> Date: Wed Sep 16 21:31:30 2020 +0200 ACME adaptation commit c5d31bd8685abce37c8e254d15aac20bd1570d9f Author: FeralChild64 <you@example.com> Date: Wed Sep 16 18:40:49 2020 +0200 ACME adaptation commit 29349826b38f8a89649171559dc8cf24c560aff1 Author: FeralChild64 <you@example.com> Date: Mon Sep 14 23:35:47 2020 +0200 ACME adaptation commit 8bcd6a621c4b11766d0cf34f79858ba90a67248e Author: FeralChild64 <you@example.com> Date: Mon Sep 14 22:52:25 2020 +0200 ACME adaptation commit e87a69edc2ce4bfcc460c31e08dcc352a985f88d Author: FeralChild64 <you@example.com> Date: Mon Sep 14 22:43:27 2020 +0200 ACME adaptation commit f49a097bd52e96d00b866c02bda7121e4543233c Author: FeralChild64 <you@example.com> Date: Mon Sep 14 19:02:07 2020 +0200 ACME adaptation commit fa0e9214a633b8e8f867cc70925b390940dcd426 Author: FeralChild64 <you@example.com> Date: Mon Sep 14 17:47:19 2020 +0200 ACME adaptation commit 1b763b91e7a03e426227129c7f22f0ce57a4c197 Author: FeralChild64 <you@example.com> Date: Mon Sep 14 17:17:10 2020 +0200 ACME adaptation commit e92a4b57b232cd85eb1e71090b8a89c7c8461ebc Author: FeralChild64 <you@example.com> Date: Mon Sep 14 17:15:37 2020 +0200 ACME adaptation commit de3c693e8a7e73ea5289198946058e3240894e6a Author: FeralChild64 <you@example.com> Date: Mon Sep 14 17:10:05 2020 +0200 ACME adaptation commit f9bd7ae0f04e932d613be9ed5cb19af9be5d338e Author: FeralChild64 <you@example.com> Date: Sun Sep 13 14:34:44 2020 +0200 ACME adaptation commit 694dee52555dbfc2b1f7f452a9671ff51106c057 Author: FeralChild64 <you@example.com> Date: Sun Sep 13 14:16:14 2020 +0200 ACME adaptation commit 0af2c55edfcd22942d9f25417eb0d35f55b71604 Author: FeralChild64 <you@example.com> Date: Fri Sep 11 17:38:09 2020 +0200 ACME adaptation commit 2015e17334bd56a1e8a13a5abc098d9c2e7ea44f Author: FeralChild64 <you@example.com> Date: Fri Sep 11 16:46:05 2020 +0200 ACME adaptation commit b1e972162798d60f4483cd6cc261e856c20c2c8c Author: FeralChild64 <you@example.com> Date: Fri Sep 11 16:24:31 2020 +0200 ACME adaptation commit 9d027e868466901ba53bf074a79ec8cf16273021 Author: FeralChild64 <you@example.com> Date: Fri Sep 11 15:04:31 2020 +0200 ACME adaptation commit 957186deddd1aa4f3b4f1aa1f421e4239a584e57 Author: FeralChild64 <you@example.com> Date: Thu Sep 10 22:49:07 2020 +0200 ACME adaptation commit b8060f67a455cfac109f08d96b62c360d693b931 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 23:07:28 2020 +0200 ACME adaptation commit e54d004568f44bbfe5c070ef1d7cf3544112e497 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 22:58:20 2020 +0200 ACME adaptation commit f90b77f073c5a605cb31c6ee451f65c8a8aff7d8 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 22:12:09 2020 +0200 ACME adaptation commit b211bb4afcd9c58fe1f5c92f3007717d611cd531 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 22:01:40 2020 +0200 ACME adaptation commit 8d7ea343b07e9e08e5f77f3c414758a6cffd0440 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 21:38:34 2020 +0200 ACME adaptation commit 46413eb0d92d6400aba0ff8dfe556e61e8a44d78 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 21:07:47 2020 +0200 ACME adaptation commit 9f98f69ecc21f7b74a5eb89e247f5a2c6fcb655d Author: FeralChild64 <you@example.com> Date: Wed Sep 9 20:05:03 2020 +0200 ACME adaptation commit 7bb9f1cadc682c7e0a4a6796739d860d473ca110 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 19:55:12 2020 +0200 ACME adaptation commit 5fc115392b5bdca6b56f67ad866b1884d2d2bdf8 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 19:31:10 2020 +0200 ACME adaptation commit b7940fc60e568d859df9e3156f6bacc6d685b2cc Author: FeralChild64 <you@example.com> Date: Wed Sep 9 19:16:09 2020 +0200 ACME adaptation commit 56288cb97197561afa0816b29c134ec1190e8eab Author: FeralChild64 <you@example.com> Date: Wed Sep 9 18:48:23 2020 +0200 ACME adaptation commit 10401a60fc7922a53d782120ef6795d889140218 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 16:34:16 2020 +0200 ACME adaptation commit 8ce76e4d2b56837a691ae84b1a412a2ae32a157b Author: FeralChild64 <you@example.com> Date: Wed Sep 9 16:20:44 2020 +0200 ACME adaptation commit 33fade899fa6172ea6b5b5f6683bb61f544429fd Author: FeralChild64 <you@example.com> Date: Wed Sep 9 15:28:46 2020 +0200 ACME adaptation commit a416f04734402fcfbc57a933731376df2e0180a1 Author: FeralChild64 <you@example.com> Date: Wed Sep 9 12:40:03 2020 +0200 ACME adaptation commit f8daee005b1d29f6912723be2ac94bc5fbeb0508 Author: FeralChild64 <you@example.com> Date: Mon Sep 7 23:29:54 2020 +0200 ACME adaptation commit 83fe6bdd0b08a44fdbfc6eefe323a4b194ccaf5b Author: FeralChild64 <you@example.com> Date: Mon Sep 7 22:23:16 2020 +0200 ACME adaptation commit cb1f75620b9c83000a15c9c7f7acefdfee79a979 Author: FeralChild64 <you@example.com> Date: Mon Sep 7 19:23:12 2020 +0200 ACME adaptation commit e524d517c933ae1f0aeb49764d307fadb4845025 Author: FeralChild64 <you@example.com> Date: Sun Sep 6 08:24:25 2020 +0200 ACME adaptation - replaced comments commit 2ab572c3a21f4a78a7312d0e684bc11d91d1717a Author: FeralChild64 <you@example.com> Date: Sat Sep 5 17:59:10 2020 +0200 ACME adaptation - replaced the assembler
This commit is contained in:
1 parent
bfc8291e41
commit
c8d255130c
685 files changed
+15835
-16296
No files matched your search
@@ -1,148 +1,147 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) part of the LOAD routine
|
||||
//
|
||||
;
|
||||
; Tape (normal) part of the LOAD routine
|
||||
;
|
||||
|
||||
|
||||
// We have the following possible CPU frequencies:
|
||||
// - C64 PAL: CPU frequency 0.985248 MHz
|
||||
// - C64 NTSC: CPU frequency 1.022727 MHz
|
||||
// The clock difference is about 4% - it is unlikely to cause problems.
|
||||
//
|
||||
// We have to distinguish the following pulse lengths (http://sidpreservation.6581.org/tape-format/):
|
||||
// - S (short) tap value $30 (PAL: 352 us)
|
||||
// - M (medium) tap value $42 (PAL: 512 us)
|
||||
// - L (long) tap value $56 (PAL: 672 us)
|
||||
//
|
||||
// The TAP format (http://unusedino.de/ec64/technical/formats/tap.html) uses a resolution of 8 PAL ticks;
|
||||
// this implementation sets the timer for twice the precision (timer B is triggered every 4 CPU cycles),
|
||||
// probably an overkill, but in realityy it does not cost us anything.
|
||||
//
|
||||
// So - we have the following thresholds:
|
||||
// - S vs M $72 (in our units of 4 ticks)
|
||||
// - M vs L $98 (in our units of 4 ticks)
|
||||
//
|
||||
// We need to recognize the following pulse sequences:
|
||||
//
|
||||
// (S,M) = 0 bit
|
||||
// (M,S) = 1 bit
|
||||
// (L,M) = new-data marker
|
||||
// (L,S) = end-of-data marker
|
||||
; We have the following possible CPU frequencies:
|
||||
; - C64 PAL: CPU frequency 0.985248 MHz
|
||||
; - C64 NTSC: CPU frequency 1.022727 MHz
|
||||
; The clock difference is about 4% - it is unlikely to cause problems.
|
||||
;
|
||||
; We have to distinguish the following pulse lengths (http://sidpreservation.6581.org/tape-format/):
|
||||
; - S (short) tap value $30 (PAL: 352 us)
|
||||
; - M (medium) tap value $42 (PAL: 512 us)
|
||||
; - L (long) tap value $56 (PAL: 672 us)
|
||||
;
|
||||
; The TAP format (http://unusedino.de/ec64/technical/formats/tap.html) uses a resolution of 8 PAL ticks;
|
||||
; this implementation sets the timer for twice the precision (timer B is triggered every 4 CPU cycles),
|
||||
; probably an overkill, but in realityy it does not cost us anything.
|
||||
;
|
||||
; So - we have the following thresholds:
|
||||
; - S vs M $72 (in our units of 4 ticks)
|
||||
; - M vs L $98 (in our units of 4 ticks)
|
||||
;
|
||||
; We need to recognize the following pulse sequences:
|
||||
;
|
||||
; (S,M) = 0 bit
|
||||
; (M,S) = 1 bit
|
||||
; (L,M) = new-data marker
|
||||
; (L,S) = end-of-data marker
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
#if !CONFIG_TAPE_AUTODETECT
|
||||
!ifndef CONFIG_TAPE_AUTODETECT {
|
||||
|
||||
load_tape_normal:
|
||||
|
||||
jsr tape_ditch_verify // only LOAD is supported, no VERIFY
|
||||
jsr tape_ditch_verify ; only LOAD is supported, no VERIFY
|
||||
|
||||
// Start playing
|
||||
; Start playing
|
||||
jsr tape_common_prepare_cia
|
||||
jsr tape_ask_play
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
!ifdef CONFIG_TAPE_HEAD_ALIGN {
|
||||
jsr tape_prepare_reading
|
||||
#endif
|
||||
}
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
load_tape_normal_header:
|
||||
|
||||
#else
|
||||
} else {
|
||||
|
||||
load_tape_normal_takeover: // entry point for turbo->normal takeover
|
||||
|
||||
#endif
|
||||
load_tape_normal_takeover: ; entry point for turbo->normal takeover
|
||||
}
|
||||
|
||||
jsr load_MEMUSS_to_STAL
|
||||
|
||||
// Try to load header into tape buffer (we will restore MEMUSS later)
|
||||
; Try to load header into tape buffer (we will restore MEMUSS later)
|
||||
|
||||
jsr tape_normal_get_pilot_header
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
bcs load_tape_normal_switch_turbo // failed, try turbo
|
||||
#endif
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
bcs load_tape_normal_switch_turbo ; failed, try turbo
|
||||
}
|
||||
|
||||
jsr load_TAPE1_to_MEMUSS
|
||||
jsr tape_normal_get_data_1
|
||||
#if !CONFIG_TAPE_AUTODETECT
|
||||
bcs load_tape_normal_header // unable to read block, try again
|
||||
#else
|
||||
bcc !+
|
||||
!ifndef CONFIG_TAPE_AUTODETECT {
|
||||
bcs load_tape_normal_header ; unable to read block, try again
|
||||
} else {
|
||||
bcc load_tape_normal_switch_turbo_skip
|
||||
load_tape_normal_switch_turbo:
|
||||
jsr lvs_STAL_to_MEMUSS
|
||||
jmp load_tape_turbo_takeover // unable to read block, try turbo instead
|
||||
!:
|
||||
#endif
|
||||
jmp load_tape_turbo_takeover ; unable to read block, try turbo instead
|
||||
load_tape_normal_switch_turbo_skip:
|
||||
}
|
||||
|
||||
jsr load_TAPE1_to_MEMUSS
|
||||
jsr tape_normal_get_data_2
|
||||
|
||||
#if !CONFIG_TAPE_AUTODETECT
|
||||
bcs load_tape_normal_header // block load error, try again
|
||||
#else
|
||||
bcs load_tape_normal_switch_turbo // block load error, try turbo instead
|
||||
#endif
|
||||
!ifndef CONFIG_TAPE_AUTODETECT {
|
||||
bcs load_tape_normal_header ; block load error, try again
|
||||
} else {
|
||||
bcs load_tape_normal_switch_turbo ; block load error, try turbo instead
|
||||
}
|
||||
|
||||
// Check header type
|
||||
; Check header type
|
||||
|
||||
ldy #$00
|
||||
lda (TAPE1),y
|
||||
|
||||
cmp #$05
|
||||
beq_16 tape_load_error // end of tape mark, nothing to load
|
||||
+beq tape_load_error ; end of tape mark, nothing to load
|
||||
|
||||
cmp #$01
|
||||
beq !+
|
||||
beq @1
|
||||
cmp #$03
|
||||
#if !CONFIG_TAPE_AUTODETECT
|
||||
bne load_tape_normal_header // header types 1 and 3 are loadable, see Mapping the C64, page 77
|
||||
#else
|
||||
!ifndef CONFIG_TAPE_AUTODETECT {
|
||||
bne load_tape_normal_header ; header types 1 and 3 are loadable, see Mapping the C64, page 77
|
||||
} else {
|
||||
bne load_tape_normal_takeover
|
||||
#endif
|
||||
}
|
||||
|
||||
lda #$01
|
||||
sta SA // this file is non-relocatable; override secondary address with 1
|
||||
!:
|
||||
// Restore MEMUSS, handle header
|
||||
sta SA ; this file is non-relocatable; override secondary address with 1
|
||||
@1:
|
||||
; Restore MEMUSS, handle header
|
||||
|
||||
jsr lvs_STAL_to_MEMUSS
|
||||
jsr tape_handle_header
|
||||
#if !CONFIG_TAPE_AUTODETECT
|
||||
bcs load_tape_normal_header // if name does not match, look for other header
|
||||
#else
|
||||
!ifndef CONFIG_TAPE_AUTODETECT {
|
||||
bcs load_tape_normal_header ; if name does not match, look for other header
|
||||
} else {
|
||||
bcs load_tape_normal_takeover
|
||||
#endif
|
||||
}
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
load_tape_normal_payload:
|
||||
|
||||
// Retrieve data
|
||||
; Retrieve data
|
||||
|
||||
jsr tape_normal_get_pilot_data
|
||||
ldy #$00 // no data size limit
|
||||
ldy #$00 ; no data size limit
|
||||
jsr tape_normal_get_data_1
|
||||
bcs_16 tape_load_error
|
||||
+bcs tape_load_error
|
||||
|
||||
jsr lvs_check_EAL
|
||||
bne_16 tape_load_error // amount of data read does not match header info
|
||||
+bne tape_load_error ; amount of data read does not match header info
|
||||
|
||||
jsr lvs_STAL_to_MEMUSS
|
||||
jsr tape_normal_get_data_2
|
||||
|
||||
bcs_16 tape_load_error
|
||||
+bcs tape_load_error
|
||||
|
||||
jmp tape_load_success
|
||||
|
||||
|
||||
|
||||
load_TAPE1_to_MEMUSS: // set MEMUSS (start address) as tape buffer
|
||||
load_TAPE1_to_MEMUSS: ; set MEMUSS (start address) as tape buffer
|
||||
|
||||
lda TAPE1+1
|
||||
sta MEMUSS+1
|
||||
@@ -151,7 +150,7 @@ load_TAPE1_to_MEMUSS: // set MEMUSS (start address) as tape bu
|
||||
|
||||
rts
|
||||
|
||||
load_MEMUSS_to_STAL: // preserve MEMUSS
|
||||
load_MEMUSS_to_STAL: ; preserve MEMUSS
|
||||
|
||||
lda MEMUSS+1
|
||||
sta STAL+1
|
||||
@@ -159,6 +158,4 @@ load_MEMUSS_to_STAL: // preserve MEMUSS
|
||||
sta STAL+0
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,75 +1,73 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (turbo) part of the LOAD routine
|
||||
//
|
||||
;
|
||||
; Tape (turbo) part of the LOAD routine
|
||||
;
|
||||
|
||||
// Initially based on routine by enthusi/Onslaught, found here:
|
||||
// - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
// but heavily reworked since then. Still, original authors deserve credits!
|
||||
; Initially based on routine by enthusi/Onslaught, found here:
|
||||
; - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
; but heavily reworked since then. Still, original authors deserve credits!
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
!ifdef CONFIG_TAPE_TURBO {
|
||||
|
||||
|
||||
#if !CONFIG_TAPE_AUTODETECT
|
||||
!ifndef CONFIG_TAPE_AUTODETECT {
|
||||
|
||||
load_tape_turbo:
|
||||
|
||||
#else
|
||||
} else {
|
||||
|
||||
load_tape_auto:
|
||||
}
|
||||
|
||||
#endif
|
||||
jsr tape_ditch_verify ; only LOAD is supported, no VERIFY
|
||||
|
||||
jsr tape_ditch_verify // only LOAD is supported, no VERIFY
|
||||
|
||||
// Prepare for sound effects
|
||||
; Prepare for sound effects
|
||||
jsr tape_clean_sid
|
||||
|
||||
// Start playing
|
||||
; Start playing
|
||||
jsr tape_common_prepare_cia
|
||||
jsr tape_ask_play
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
!ifdef CONFIG_TAPE_HEAD_ALIGN {
|
||||
jsr tape_prepare_reading
|
||||
#endif
|
||||
}
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
|
||||
load_tape_turbo_takeover: // entry point for normal->turbo takeover
|
||||
load_tape_turbo_takeover: ; entry point for normal->turbo takeover
|
||||
|
||||
jsr tape_common_autodetect
|
||||
bcc_16 load_tape_normal_takeover
|
||||
+bcc load_tape_normal_takeover
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
load_tape_turbo_header:
|
||||
|
||||
// Read file header; structure described here:
|
||||
// - https://www.luigidifraia.com/c64/docs/tapeloaders.html#turbotape64
|
||||
//
|
||||
// 1 byte - file type (0 = data, odd value = relocatable, even value = non-relocatable)
|
||||
// 2 bytes - start address
|
||||
// 2 bytes - end address + 1
|
||||
// 1 byte - if $B0 (tape timing) contained at the time of saving
|
||||
// (we skip this one to match normal system header)
|
||||
// 16 bytes - filename, padded with 0x20
|
||||
; Read file header; structure described here:
|
||||
; - https://www.luigidifraia.com/c64/docs/tapeloaders.html#turbotape64
|
||||
;
|
||||
; 1 byte - file type (0 = data, odd value = relocatable, even value = non-relocatable)
|
||||
; 2 bytes - start address
|
||||
; 2 bytes - end address + 1
|
||||
; 1 byte - if $B0 (tape timing) contained at the time of saving
|
||||
; (we skip this one to match normal system header)
|
||||
; 16 bytes - filename, padded with 0x20
|
||||
|
||||
jsr tape_turbo_sync_header
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
bcs_16 load_tape_normal_takeover // failure, probably not a turbo tape file
|
||||
#endif
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
+bcs load_tape_normal_takeover ; failure, probably not a turbo tape file
|
||||
}
|
||||
ldy #$00
|
||||
sta (TAPE1), y // store header type
|
||||
sta (TAPE1), y ; store header type
|
||||
iny
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
load_tape_turbo_header_loop:
|
||||
|
||||
@@ -77,85 +75,83 @@ load_tape_turbo_header_loop:
|
||||
sta (TAPE1), y
|
||||
iny
|
||||
cpy #$05
|
||||
bne !+
|
||||
jsr tape_turbo_get_byte // tape timing - skip this one
|
||||
!:
|
||||
cpy #$C0 // header is 192 bytes long in total
|
||||
bne @1
|
||||
jsr tape_turbo_get_byte ; tape timing - skip this one
|
||||
@1:
|
||||
cpy #$C0 ; header is 192 bytes long in total
|
||||
bne load_tape_turbo_header_loop
|
||||
|
||||
// For non-relocatable files, override secondary address
|
||||
ldy #$00 // XXX optimize out for 65C02
|
||||
; For non-relocatable files, override secondary address
|
||||
ldy #$00 ; XXX optimize out for 65C02
|
||||
lda (TAPE1), y
|
||||
beq !+
|
||||
beq @2
|
||||
and #$01
|
||||
bne !+
|
||||
lda #$01 // XXX for 65C02 just set the bit with one instruction
|
||||
bne @2
|
||||
lda #$01 ; XXX for 65C02 just set the bit with one instruction
|
||||
sta SA
|
||||
!:
|
||||
// Handle the header
|
||||
@2:
|
||||
; Handle the header
|
||||
|
||||
jsr tape_clean_sid
|
||||
jsr tape_handle_header
|
||||
bcs load_tape_turbo_header // if name does not match, look for other header
|
||||
bcs load_tape_turbo_header ; if name does not match, look for other header
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
load_tape_turbo_payload:
|
||||
|
||||
// Copy helper byte store routine to RAM, provide default memory mapping
|
||||
; Copy helper byte store routine to RAM, provide default memory mapping
|
||||
|
||||
ldx #(__tape_turbo_bytestore_size - 1)
|
||||
!:
|
||||
@3:
|
||||
lda tape_turbo_bytestore_source, x
|
||||
sta __tape_turbo_bytestore, x
|
||||
dex
|
||||
bpl !-
|
||||
bpl @3
|
||||
|
||||
lda CPU_R6510
|
||||
sta __tape_turbo_bytestore_defmap
|
||||
|
||||
// Initial checksum value
|
||||
; Initial checksum value
|
||||
|
||||
lda #$00
|
||||
sta PRTY
|
||||
|
||||
// Read file payload
|
||||
!:
|
||||
; Read file payload
|
||||
@4:
|
||||
jsr tape_turbo_sync_payload
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
bcs !-
|
||||
#endif
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
bcs @4
|
||||
}
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
load_tape_turbo_loop:
|
||||
|
||||
jsr tape_turbo_get_byte
|
||||
jsr __tape_turbo_bytestore // like 'sta (MEMUSS),y' - but under I/O
|
||||
jsr __tape_turbo_bytestore ; like 'sta (MEMUSS),y' - but under I/O
|
||||
|
||||
eor PRTY // handle checksum
|
||||
eor PRTY ; handle checksum
|
||||
sta PRTY
|
||||
|
||||
// Advance MEMUSS (see Mapping the C64, page 36)
|
||||
#if !HAS_OPCODES_65CE02
|
||||
; Advance MEMUSS (see Mapping the C64, page 36)
|
||||
!ifndef HAS_OPCODES_65CE02 {
|
||||
jsr lvs_advance_MEMUSS
|
||||
#else
|
||||
} else {
|
||||
inw MEMUSS+0
|
||||
#endif
|
||||
}
|
||||
jsr lvs_check_EAL
|
||||
bne load_tape_turbo_loop
|
||||
|
||||
// Get the checksum
|
||||
; Get the checksum
|
||||
jsr tape_turbo_get_byte
|
||||
tax
|
||||
|
||||
// Silence audio
|
||||
; Silence audio
|
||||
jsr tape_clean_sid
|
||||
|
||||
// Verify the checksum
|
||||
; Verify the checksum
|
||||
cpx PRTY
|
||||
beq_16 tape_load_success
|
||||
+beq tape_load_success
|
||||
jmp tape_load_error
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_TURBO
|
||||
}
|
||||
+99
-109
@@ -1,18 +1,18 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Common routines for tape support
|
||||
//
|
||||
;
|
||||
; Common routines for tape support
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
!ifdef HAS_TAPE {
|
||||
|
||||
|
||||
//
|
||||
// Loading terminated by user
|
||||
//
|
||||
;
|
||||
; Loading terminated by user
|
||||
;
|
||||
|
||||
tape_break_error:
|
||||
|
||||
@@ -22,31 +22,30 @@ tape_break_error:
|
||||
jmp kernalerror_ROUTINE_TERMINATED
|
||||
|
||||
|
||||
//
|
||||
// Ask user to press PLAY on tape deck,
|
||||
// Unless user cancelled loading, blank screen and start motor
|
||||
//
|
||||
;
|
||||
; Ask user to press PLAY on tape deck,
|
||||
; Unless user cancelled loading, blank screen and start motor
|
||||
;
|
||||
|
||||
tape_ask_play:
|
||||
|
||||
#if !CONFIG_TAPE_NO_KEY_SENSE
|
||||
!ifndef CONFIG_TAPE_NO_KEY_SENSE {
|
||||
|
||||
// First check whether the button is already pressed
|
||||
; First check whether the button is already pressed
|
||||
|
||||
lda CPU_R6510
|
||||
and #$10
|
||||
beq tape_wait_play_done
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Display message
|
||||
; Display message
|
||||
|
||||
ldx #__MSG_KERNAL_PRESS_PLAY
|
||||
jsr print_kernal_message
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
#if !CONFIG_TAPE_NO_KEY_SENSE
|
||||
!ifndef CONFIG_TAPE_NO_KEY_SENSE {
|
||||
|
||||
tape_wait_play_loop:
|
||||
|
||||
@@ -54,122 +53,118 @@ tape_wait_play_loop:
|
||||
bcs tape_break_error
|
||||
|
||||
lda CPU_R6510
|
||||
and #$10 // check for pressed button
|
||||
and #$10 ; check for pressed button
|
||||
bne tape_wait_play_loop
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
#else
|
||||
} else {
|
||||
|
||||
// The ROM is configured for tape adapter without the key sense - but it is still
|
||||
// possible, that regular Datasette or Tapuino is connected
|
||||
; The ROM is configured for tape adapter without the key sense - but it is still
|
||||
; possible, that regular Datasette or Tapuino is connected
|
||||
|
||||
lda CPU_R6510
|
||||
and #$10
|
||||
beq tape_wait_first_pulse // branch if button reported pressed, most likely really no key sense
|
||||
beq tape_wait_first_pulse ; branch if button reported pressed, most likely really no key sense
|
||||
|
||||
// We have key sense - perform regular waiting
|
||||
!:
|
||||
; We have key sense - perform regular waiting
|
||||
@1:
|
||||
jsr STOP
|
||||
bcs tape_break_error
|
||||
|
||||
lda CPU_R6510
|
||||
and #$10
|
||||
beq !-
|
||||
beq @1
|
||||
|
||||
tape_wait_first_pulse:
|
||||
|
||||
// We have no key sense - so just turn the motor on and wait for the first pulse
|
||||
; We have no key sense - so just turn the motor on and wait for the first pulse
|
||||
|
||||
jsr tape_motor_on
|
||||
|
||||
!:
|
||||
@2:
|
||||
jsr STOP
|
||||
bcs tape_break_error
|
||||
|
||||
lda #$10
|
||||
bit CIA1_ICR // $DC0D
|
||||
bne !-
|
||||
!:
|
||||
bit CIA1_ICR ; $DC0D
|
||||
bne @2
|
||||
@3:
|
||||
jsr STOP
|
||||
bcs tape_break_error
|
||||
|
||||
lda #$10
|
||||
bit CIA1_ICR // $DC0D
|
||||
beq !-
|
||||
bit CIA1_ICR ; $DC0D
|
||||
beq @3
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_wait_play_done:
|
||||
|
||||
lda #$01
|
||||
sta CAS1 // set the interlock
|
||||
sta CAS1 ; set the interlock
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
!ifdef CONFIG_TAPE_HEAD_ALIGN {
|
||||
|
||||
rts
|
||||
|
||||
tape_prepare_reading:
|
||||
|
||||
#endif // CONFIG_TAPE_HEAD_ALIGN
|
||||
} ; CONFIG_TAPE_HEAD_ALIGN
|
||||
|
||||
#if CONFIG_MB_MEGA_65
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
|
||||
// Display confirmation
|
||||
; Display confirmation
|
||||
|
||||
ldx #__MSG_KERNAL_OK_SEARCHING
|
||||
jsr print_kernal_message
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Prepare for reading
|
||||
; Prepare for reading
|
||||
|
||||
jsr print_return
|
||||
jmp tape_screen_off_motor_on
|
||||
|
||||
|
||||
//
|
||||
// Handle file header - display it, decide whether load the file or not, etc.
|
||||
//
|
||||
;
|
||||
; Handle file header - display it, decide whether load the file or not, etc.
|
||||
;
|
||||
|
||||
tape_handle_header:
|
||||
|
||||
#if !CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
!ifndef CONFIG_TAPE_NO_MOTOR_CONTROL {
|
||||
|
||||
jsr tape_screen_on_motor_off
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Print FOUND + file name
|
||||
; Print FOUND + file name
|
||||
|
||||
ldx #__MSG_KERNAL_FOUND
|
||||
jsr print_kernal_message
|
||||
|
||||
ldy #$05
|
||||
!:
|
||||
@4:
|
||||
lda (TAPE1), y
|
||||
jsr JCHROUT
|
||||
iny
|
||||
cpy #$15
|
||||
bne !-
|
||||
bne @4
|
||||
|
||||
#if !CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
!ifndef CONFIG_TAPE_NO_MOTOR_CONTROL {
|
||||
|
||||
// Header, wait for user decision
|
||||
; Header, wait for user decision
|
||||
|
||||
jsr tape_header_get_decision
|
||||
bcs tape_break_error
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Check if file name matches
|
||||
; Check if file name matches
|
||||
|
||||
jsr tape_match_filename
|
||||
bcs tape_handle_header_skip
|
||||
|
||||
// Setup STAL and EAL
|
||||
; Setup STAL and EAL
|
||||
|
||||
ldy #$01
|
||||
lda (TAPE1), y
|
||||
@@ -187,12 +182,12 @@ tape_handle_header:
|
||||
lda (TAPE1), y
|
||||
sta EAL+1
|
||||
|
||||
// Handle the secondary address, 0 means loading to location from MEMUSS
|
||||
; Handle the secondary address, 0 means loading to location from MEMUSS
|
||||
|
||||
lda SA
|
||||
bne !+
|
||||
bne @5
|
||||
|
||||
// EAL = EAL - STAL
|
||||
; EAL = EAL - STAL
|
||||
|
||||
sec
|
||||
lda EAL+0
|
||||
@@ -202,14 +197,14 @@ tape_handle_header:
|
||||
sbc STAL+1
|
||||
sta EAL+1
|
||||
|
||||
// STAL = MEMUSS
|
||||
; STAL = MEMUSS
|
||||
|
||||
lda MEMUSS+0
|
||||
sta STAL+0
|
||||
lda MEMUSS+1
|
||||
sta STAL+1
|
||||
|
||||
// EAL = EAL + STAL
|
||||
; EAL = EAL + STAL
|
||||
|
||||
clc
|
||||
lda EAL+0
|
||||
@@ -218,36 +213,34 @@ tape_handle_header:
|
||||
lda EAL+1
|
||||
adc STAL+1
|
||||
sta EAL+1
|
||||
!:
|
||||
// Setup MEMUSS (see Mapping the C64, page 36)
|
||||
@5:
|
||||
; Setup MEMUSS (see Mapping the C64, page 36)
|
||||
|
||||
jsr lvs_STAL_to_MEMUSS
|
||||
|
||||
#if ROM_LAYOUT_M65
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
|
||||
// Switch to legacy mode if needed
|
||||
; Switch to legacy mode if needed
|
||||
|
||||
jsr m65_load_autoswitch_tape
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Print LOADING and start address
|
||||
; Print LOADING and start address
|
||||
|
||||
jsr lvs_display_loading_verifying
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
#if !CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
!ifndef CONFIG_TAPE_NO_MOTOR_CONTROL {
|
||||
|
||||
tape_handle_header_displayed:
|
||||
|
||||
// Load the file
|
||||
; Load the file
|
||||
|
||||
jsr tape_screen_off_motor_on
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
#endif
|
||||
; FALLTROUGH
|
||||
}
|
||||
|
||||
tape_return_ok:
|
||||
|
||||
@@ -256,12 +249,12 @@ tape_return_ok:
|
||||
|
||||
tape_handle_header_skip:
|
||||
|
||||
// Skip this file
|
||||
; Skip this file
|
||||
|
||||
jsr print_return
|
||||
jsr tape_screen_off_motor_on
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_return_not_ok:
|
||||
|
||||
@@ -269,24 +262,24 @@ tape_return_not_ok:
|
||||
rts
|
||||
|
||||
|
||||
//
|
||||
// Check whether file name matches the pattern
|
||||
//
|
||||
;
|
||||
; Check whether file name matches the pattern
|
||||
;
|
||||
|
||||
tape_match_filename:
|
||||
|
||||
lda FNLEN
|
||||
beq tape_return_ok // no pattern to match
|
||||
beq tape_return_ok ; no pattern to match
|
||||
|
||||
ldy #$00
|
||||
|
||||
tape_match_loop:
|
||||
|
||||
lda #$20 // default byte, for padding
|
||||
lda #$20 ; default byte, for padding
|
||||
cpy FNLEN
|
||||
bcs !+ // end of pattern
|
||||
lda (FNADDR), y // byte from pattern
|
||||
!:
|
||||
bcs @6 ; end of pattern
|
||||
lda (FNADDR), y ; byte from pattern
|
||||
@6:
|
||||
cmp #KEY_ASTERISK
|
||||
beq tape_return_ok
|
||||
|
||||
@@ -311,31 +304,31 @@ tape_match_loop:
|
||||
rts
|
||||
|
||||
|
||||
#if !CONFIG_TAPE_NO_MOTOR_CONTROL
|
||||
!ifndef CONFIG_TAPE_NO_MOTOR_CONTROL {
|
||||
|
||||
//
|
||||
// Get user decision whether to load the file or not
|
||||
//
|
||||
;
|
||||
; Get user decision whether to load the file or not
|
||||
;
|
||||
|
||||
tape_header_get_decision:
|
||||
|
||||
ldy #$00
|
||||
!:
|
||||
@7:
|
||||
jsr udtim_keyboard
|
||||
lda STKEY
|
||||
bpl tape_header_wait_stop // STOP pressed
|
||||
bpl tape_header_wait_stop ; STOP pressed
|
||||
and #$10
|
||||
beq tape_header_wait_space // SPACE pressed
|
||||
beq tape_header_wait_space ; SPACE pressed
|
||||
|
||||
ldx #$80
|
||||
jsr wait_x_bars // sets .X to 0
|
||||
jsr wait_x_bars ; sets .X to 0
|
||||
dex
|
||||
jsr wait_x_bars
|
||||
|
||||
dey
|
||||
bne !-
|
||||
bne @7
|
||||
|
||||
// FALLTROUGH - timeout
|
||||
; FALLTROUGH - timeout
|
||||
|
||||
tape_header_wait_space:
|
||||
|
||||
@@ -346,13 +339,12 @@ tape_header_wait_stop:
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Report that file loading succeeded (or not)
|
||||
//
|
||||
;
|
||||
; Report that file loading succeeded (or not)
|
||||
;
|
||||
|
||||
tape_load_success:
|
||||
|
||||
@@ -364,6 +356,4 @@ tape_load_error:
|
||||
|
||||
jsr tape_screen_on_motor_off
|
||||
jmp lvs_load_verify_error
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,92 +1,92 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tries to detect
|
||||
//
|
||||
// Carry clear - normal, Carry set - turbo
|
||||
//
|
||||
;
|
||||
; Tries to detect
|
||||
;
|
||||
; Carry clear - normal, Carry set - turbo
|
||||
;
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
|
||||
|
||||
tape_common_autodetect:
|
||||
|
||||
// Set screen color to something neutral, silence the audio
|
||||
; Set screen color to something neutral, silence the audio
|
||||
lda #$0B
|
||||
sta VIC_EXTCOL
|
||||
lda #$00
|
||||
#if CONFIG_MB_MEGA_65
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
sta SID_SIGVOL + __SID_R1_OFFSET
|
||||
sta SID_SIGVOL + __SID_L1_OFFSET
|
||||
#else
|
||||
} else {
|
||||
sta SID_SIGVOL
|
||||
#endif
|
||||
}
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_common_autodetect_retry:
|
||||
|
||||
// It is not trivial to distinguish between normal and turbo,
|
||||
// as short pulses of normal (and sync uses only shorts)
|
||||
// have similar lengths as long pulses of turbo
|
||||
; It is not trivial to distinguish between normal and turbo,
|
||||
; as short pulses of normal (and sync uses only shorts)
|
||||
; have similar lengths as long pulses of turbo
|
||||
|
||||
// Thus, the routine here reads certain amount of pulses
|
||||
// looking for evidence for either normal or turbo system;
|
||||
// in case of no evidence found, assume normal
|
||||
; Thus, the routine here reads certain amount of pulses
|
||||
; looking for evidence for either normal or turbo system;
|
||||
; in case of no evidence found, assume normal
|
||||
|
||||
lda #$00 // plus = probably normal, minus = turbo
|
||||
lda #$00 ; plus = probably normal, minus = turbo
|
||||
sta XSAV
|
||||
|
||||
ldy #$60 // $60 pulses cover 12 bytes of turbo recording
|
||||
jsr tape_common_get_pulse // first pulse might be a garbage, ignore it
|
||||
ldy #$60 ; $60 pulses cover 12 bytes of turbo recording
|
||||
jsr tape_common_get_pulse ; first pulse might be a garbage, ignore it
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_common_autodetect_loop:
|
||||
|
||||
jsr tape_common_get_pulse // read pulse for detection attempt
|
||||
jsr tape_common_get_pulse ; read pulse for detection attempt
|
||||
|
||||
// If garbage found, retry detection
|
||||
; If garbage found, retry detection
|
||||
cmp #$28
|
||||
bcc tape_common_autodetect_retry // this is a VERY long pulse
|
||||
bcc tape_common_autodetect_retry ; this is a VERY long pulse
|
||||
cmp #$E8
|
||||
bcs tape_common_autodetect_retry // this is a VERY short pulse
|
||||
bcs tape_common_autodetect_retry ; this is a VERY short pulse
|
||||
|
||||
// First try to distinguish turbo short signal (reference: $CD)
|
||||
// from normal signals (reference: $A5 or lower), these values
|
||||
// give us threshold of ($CD + $A5) / 2 = $B9
|
||||
; First try to distinguish turbo short signal (reference: $CD)
|
||||
; from normal signals (reference: $A5 or lower), these values
|
||||
; give us threshold of ($CD + $A5) / 2 = $B9
|
||||
|
||||
cmp #$B9
|
||||
bcc !+
|
||||
dec XSAV // above $B9 (so signal is shorter), looks like turbo
|
||||
!:
|
||||
// Now try to distinguish turbo signals (reference: $B1 or higher)
|
||||
// from normal medium/long signals (reference: $7D or below), these values
|
||||
// give us threshold of ($B1 + $7D) / 2 = $97
|
||||
bcc @1
|
||||
dec XSAV ; above $B9 (so signal is shorter), looks like turbo
|
||||
@1:
|
||||
; Now try to distinguish turbo signals (reference: $B1 or higher)
|
||||
; from normal medium/long signals (reference: $7D or below), these values
|
||||
; give us threshold of ($B1 + $7D) / 2 = $97
|
||||
|
||||
cmp #$97
|
||||
bcs !+
|
||||
bcs @2
|
||||
inc XSAV
|
||||
!:
|
||||
// The sync for turbo is not too long - if we have enough evidence,
|
||||
// assume turbo recording already
|
||||
@2:
|
||||
; The sync for turbo is not too long - if we have enough evidence,
|
||||
; assume turbo recording already
|
||||
|
||||
lda XSAV
|
||||
cmp #$FD
|
||||
beq tape_common_autodetect_turbo
|
||||
|
||||
// Next iteration
|
||||
; Next iteration
|
||||
dey
|
||||
bpl tape_common_autodetect_loop
|
||||
|
||||
// Last chance for turbo
|
||||
; Last chance for turbo
|
||||
|
||||
lda XSAV
|
||||
bmi tape_common_autodetect_turbo
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_common_autodetect_normal:
|
||||
|
||||
@@ -97,6 +97,4 @@ tape_common_autodetect_turbo:
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,40 +1,38 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Clear the SID settings - for sound effects during LOAD
|
||||
//
|
||||
;
|
||||
; Clear the SID settings - for sound effects during LOAD
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
!ifdef CONFIG_TAPE_TURBO {
|
||||
|
||||
|
||||
tape_clean_sid:
|
||||
|
||||
lda #$00
|
||||
ldy #$1C
|
||||
!:
|
||||
@1:
|
||||
|
||||
#if CONFIG_MB_MEGA_65
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
|
||||
// It should be safer than cleaning whole $D400-D47C range
|
||||
; It should be safer than cleaning whole $D400-D47C range
|
||||
|
||||
sta __SID_BASE + __SID_R1_OFFSET, y
|
||||
sta __SID_BASE + __SID_R2_OFFSET, y
|
||||
sta __SID_BASE + __SID_L1_OFFSET, y
|
||||
sta __SID_BASE + __SID_L2_OFFSET, y
|
||||
|
||||
#else
|
||||
} else {
|
||||
|
||||
sta __SID_BASE, y
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
dey
|
||||
bpl !-
|
||||
bpl @1
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,24 +1,22 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Check if VERIFY asked - if yes, terminate loading
|
||||
//
|
||||
;
|
||||
; Check if VERIFY asked - if yes, terminate loading
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
!ifdef HAS_TAPE {
|
||||
|
||||
|
||||
tape_ditch_verify:
|
||||
|
||||
lda VERCKK
|
||||
bne !+
|
||||
bne @1
|
||||
rts
|
||||
!:
|
||||
@1:
|
||||
pla
|
||||
pla
|
||||
jmp lvs_device_not_found_error
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,33 +1,31 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape helper routine - pulse reading
|
||||
//
|
||||
// Returns pulse length (with a bias, see comments) in .A
|
||||
//
|
||||
;
|
||||
; Tape helper routine - pulse reading
|
||||
;
|
||||
; Returns pulse length (with a bias, see comments) in .A
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
!ifdef HAS_TAPE {
|
||||
|
||||
|
||||
tape_common_get_pulse:
|
||||
|
||||
// Contrary to original ROM implementation we do not use interrupts
|
||||
// (see http://unusedino.de/ec64/technical/formats/tap.html) - busy wait
|
||||
// implementation is probably just shorter
|
||||
; Contrary to original ROM implementation we do not use interrupts
|
||||
; (see http://unusedino.de/ec64/technical/formats/tap.html) - busy wait
|
||||
; implementation is probably just shorter
|
||||
|
||||
lda #$10
|
||||
!:
|
||||
bit CIA1_ICR // $DC0D
|
||||
beq !- // busy loop to detect signal, restart timer afterwards
|
||||
lda CIA2_TIMBLO // $DD06
|
||||
ldx #%01010001 // start timer, force latch reload, count timer A underflows
|
||||
stx CIA2_CRB // $DD0F
|
||||
@1:
|
||||
bit CIA1_ICR ; $DC0D
|
||||
beq @1 ; busy loop to detect signal, restart timer afterwards
|
||||
lda CIA2_TIMBLO ; $DD06
|
||||
ldx #%01010001 ; start timer, force latch reload, count timer A underflows
|
||||
stx CIA2_CRB ; $DD0F
|
||||
|
||||
cmp __pulse_threshold // default pulse check
|
||||
cmp __pulse_threshold ; default pulse check
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,28 +1,30 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# * KERNAL_0 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Handle tape deck motor
|
||||
//
|
||||
;
|
||||
; Handle tape deck motor
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
!ifdef HAS_TAPE {
|
||||
|
||||
|
||||
tape_motor_off:
|
||||
|
||||
lda CPU_R6510
|
||||
ora #$20
|
||||
bne !+ // branch always
|
||||
bne tape_motor_common ; branch always
|
||||
|
||||
tape_motor_on:
|
||||
|
||||
lda CPU_R6510
|
||||
and #($FF - $20)
|
||||
!:
|
||||
|
||||
; FALLTROUGH
|
||||
|
||||
tape_motor_common:
|
||||
|
||||
sta CPU_R6510
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,65 +1,64 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Prepare CIA timers for tape reading
|
||||
//
|
||||
;
|
||||
; Prepare CIA timers for tape reading
|
||||
;
|
||||
|
||||
//
|
||||
// Checked under VICE, PAL, average of 256 pulses:
|
||||
//
|
||||
// normal - short - timer goes down to $A5
|
||||
// normal - medium - timer goes down to $7D
|
||||
// normal - long - timer goes down to $52
|
||||
//
|
||||
// turbo - short - timer goes down to $CD
|
||||
// turbo - long - timer goes down to $B1
|
||||
//
|
||||
//
|
||||
// Measurement subroutine: .A should contain timer value, $C000-$C002 zeroed
|
||||
//
|
||||
// clc
|
||||
// adc $C001
|
||||
// sta $C001
|
||||
// bcc !+
|
||||
// inc $C000
|
||||
// !:
|
||||
// inc $C002
|
||||
// beq !+
|
||||
// rts
|
||||
// !:
|
||||
// lda $C000
|
||||
// .break // .A contains our average
|
||||
// rts
|
||||
//
|
||||
;
|
||||
; Checked under VICE, PAL, average of 256 pulses:
|
||||
;
|
||||
; normal - short - timer goes down to $A5
|
||||
; normal - medium - timer goes down to $7D
|
||||
; normal - long - timer goes down to $52
|
||||
;
|
||||
; turbo - short - timer goes down to $CD
|
||||
; turbo - long - timer goes down to $B1
|
||||
;
|
||||
;
|
||||
; Measurement subroutine: .A should contain timer value, $C000-$C002 zeroed
|
||||
;
|
||||
; clc
|
||||
; adc $C001
|
||||
; sta $C001
|
||||
; bcc !+
|
||||
; inc $C000
|
||||
; !:
|
||||
; inc $C002
|
||||
; beq !+
|
||||
; rts
|
||||
; !:
|
||||
; lda $C000
|
||||
; .break ; .A contains our average
|
||||
; rts
|
||||
;
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
!ifdef HAS_TAPE {
|
||||
|
||||
|
||||
tape_common_prepare_cia:
|
||||
|
||||
// Setup CIA #2 timers
|
||||
; Setup CIA #2 timers
|
||||
|
||||
ldx #$03 // set timer A to 4 ticks
|
||||
ldx #$03 ; set timer A to 4 ticks
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_common_prepare_cia_by_x: // entry point for head align tool
|
||||
tape_common_prepare_cia_by_x: ; entry point for head align tool
|
||||
|
||||
stx CIA2_TIMALO // $DD04
|
||||
stx CIA2_TIMALO ; $DD04
|
||||
ldx #$00
|
||||
stx CIA2_TIMAHI // $DD05
|
||||
stx CIA2_TIMAHI ; $DD05
|
||||
|
||||
stx CIA2_TIMBHI // $DD07
|
||||
dex // puts $FF - for running timer B as long as possible
|
||||
stx CIA2_TIMBLO // $DD06
|
||||
stx CIA2_TIMBHI ; $DD07
|
||||
dex ; puts $FF - for running timer B as long as possible
|
||||
stx CIA2_TIMBLO ; $DD06
|
||||
|
||||
// Let timer A run continuously
|
||||
; Let timer A run continuously
|
||||
|
||||
ldx #%00010001 // start timer, force latch reload
|
||||
stx CIA2_CRA // $DD0E
|
||||
ldx #%00010001 ; start timer, force latch reload
|
||||
stx CIA2_CRA ; $DD0E
|
||||
|
||||
rts
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Handle screen (visible/blanked) + tape deck motor (on/off),
|
||||
// store/restore screen color
|
||||
//
|
||||
;
|
||||
; Handle screen (visible/blanked) + tape deck motor (on/off),
|
||||
; store/restore screen color
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
!ifdef HAS_TAPE {
|
||||
|
||||
|
||||
|
||||
@@ -19,46 +19,44 @@ tape_screen_on_motor_off:
|
||||
lda COLSTORE
|
||||
sta VIC_EXTCOL
|
||||
|
||||
#if !ROM_LAYOUT_M65
|
||||
!ifndef CONFIG_MB_M65 {
|
||||
|
||||
jmp screen_on
|
||||
|
||||
#else
|
||||
} else {
|
||||
|
||||
jsr M65_MODEGET
|
||||
bcs_16 screen_on // MEGA65 native mode does not have badlines, no need to enable/disable screen
|
||||
+bcs screen_on ; MEGA65 native mode does not have badlines, no need to enable/disable screen
|
||||
rts
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
tape_screen_off_motor_on:
|
||||
|
||||
// We do not want interrupts and CHROUT reenables them
|
||||
; We do not want interrupts and CHROUT reenables them
|
||||
sei
|
||||
|
||||
// Clear keyboard buffer
|
||||
; Clear keyboard buffer
|
||||
lda #$00
|
||||
sta NDX
|
||||
|
||||
// Set screen color
|
||||
; Set screen color
|
||||
lda VIC_EXTCOL
|
||||
sta COLSTORE
|
||||
|
||||
#if !ROM_LAYOUT_M65
|
||||
!ifndef CONFIG_MB_M65 {
|
||||
|
||||
jsr screen_off
|
||||
|
||||
#else
|
||||
} else {
|
||||
|
||||
jsr M65_MODEGET
|
||||
// XXX optimize this
|
||||
bcs !+ // MEGA65 native mode does not have badlines, no need to enable/disable screen
|
||||
; XXX optimize this
|
||||
bcs @1 ; MEGA65 native mode does not have badlines, no need to enable/disable screen
|
||||
jsr screen_off
|
||||
!:
|
||||
@1:
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
jmp tape_motor_on
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,64 +1,64 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape head alignemnt tool
|
||||
//
|
||||
;
|
||||
; Tape head alignemnt tool
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
!ifdef CONFIG_TAPE_HEAD_ALIGN {
|
||||
|
||||
|
||||
.label __ha_start = 12 // starting row of the chart
|
||||
.label __ha_rows = 11 // number of rows for scrolling
|
||||
!set __ha_start = 12 ; starting row of the chart
|
||||
!set __ha_rows = 11 ; number of rows for scrolling
|
||||
|
||||
// Helper tables
|
||||
; Helper tables
|
||||
|
||||
.label __ha_offsets = $1000;
|
||||
.label __ha_masks = $1100;
|
||||
!addr __ha_offsets = $1000;
|
||||
!addr __ha_masks = $1100;
|
||||
|
||||
// Generated code location
|
||||
; Generated code location
|
||||
|
||||
.label __ha_scroll = $1300;
|
||||
!addr __ha_scroll = $1300;
|
||||
|
||||
// Flag for GFX effects - reuse BASIC numeric work area on zero page
|
||||
; Flag for GFX effects - reuse BASIC numeric work area on zero page
|
||||
|
||||
.label __ha_gfxflag = TEMPF2; // 1 byte
|
||||
!addr __ha_gfxflag = TEMPF2; ; 1 byte
|
||||
|
||||
|
||||
tape_head_align:
|
||||
|
||||
// Make sure user really wants to launch the tool
|
||||
; Make sure user really wants to launch the tool
|
||||
|
||||
jsr tape_ask_play
|
||||
|
||||
// Disable interrupts, set proper I/O values
|
||||
; Disable interrupts, set proper I/O values
|
||||
|
||||
jsr CLALL
|
||||
|
||||
sei
|
||||
|
||||
jsr IOINIT
|
||||
// jsr CINT
|
||||
; jsr CINT
|
||||
|
||||
jsr nmi_lock
|
||||
|
||||
// Prepare CIA timers
|
||||
; Prepare CIA timers
|
||||
|
||||
ldx #$02 // set timer A to 3 ticks
|
||||
ldx #$02 ; set timer A to 3 ticks
|
||||
jsr tape_common_prepare_cia_by_x
|
||||
|
||||
ldx #$FF // timer to control scroll speed
|
||||
stx CIA1_TIMBLO // $DC06
|
||||
stx CIA1_TIMBHI // $DC07
|
||||
ldx #$FF ; timer to control scroll speed
|
||||
stx CIA1_TIMBLO ; $DC06
|
||||
stx CIA1_TIMBHI ; $DC07
|
||||
|
||||
jsr tape_motor_on
|
||||
|
||||
// Clear color data ($0800)
|
||||
; Clear color data ($0800)
|
||||
|
||||
ldy #$00
|
||||
!:
|
||||
@1:
|
||||
lda #(CONFIG_COLOR_TXT * $10 + CONFIG_COLOR_BG)
|
||||
|
||||
sta $0800, y
|
||||
@@ -67,146 +67,146 @@ tape_head_align:
|
||||
sta $0B00, y
|
||||
|
||||
iny
|
||||
bne !-
|
||||
bne @1
|
||||
|
||||
// Clear bitmap data ($2000)
|
||||
; Clear bitmap data ($2000)
|
||||
|
||||
lda #$20
|
||||
sta SAL+1
|
||||
tya // put 0 to .A
|
||||
tya ; put 0 to .A
|
||||
sta SAL+0
|
||||
!:
|
||||
@2:
|
||||
sta (SAL), y
|
||||
iny
|
||||
bne !-
|
||||
bne @2
|
||||
|
||||
inc SAL+1
|
||||
ldx SAL+1
|
||||
cpx #$40
|
||||
bne !-
|
||||
bne @2
|
||||
|
||||
// Print help message
|
||||
; Print help message
|
||||
|
||||
jsr tape_head_align_print_help
|
||||
|
||||
// Make sure the row where the chart is being created is not visible
|
||||
; Make sure the row where the chart is being created is not visible
|
||||
|
||||
lda #(CONFIG_COLOR_TXT * $10 + CONFIG_COLOR_TXT)
|
||||
ldy #$24
|
||||
!:
|
||||
@3:
|
||||
sta $0800 + __ha_start * 40 + 1, y
|
||||
sta $0800 + __ha_start * 40 + 1 + (__ha_rows + 1) * 40, y
|
||||
|
||||
dey
|
||||
bne !-
|
||||
bne @3
|
||||
|
||||
// Set graphics mode
|
||||
; Set graphics mode
|
||||
|
||||
lda #$28 // graphics start at $2000, color at $0800
|
||||
lda #$28 ; graphics start at $2000, color at $0800
|
||||
sta VIC_YMCSB
|
||||
|
||||
lda #$3B // set bit 5 to enable graphic mode
|
||||
lda #$3B ; set bit 5 to enable graphic mode
|
||||
sta VIC_SCROLY
|
||||
|
||||
// Prepare lookup tables - to speed drawing, we are going to use two of them:
|
||||
// - byte offset table will tell us which byte in memory to alter
|
||||
// - mask will allow us to quickly put the pixel
|
||||
; Prepare lookup tables - to speed drawing, we are going to use two of them:
|
||||
; - byte offset table will tell us which byte in memory to alter
|
||||
; - mask will allow us to quickly put the pixel
|
||||
|
||||
ldx #$00 // loop index
|
||||
ldy #$00 // temporary value for mask calculation
|
||||
!:
|
||||
// Byte offset is simple, just zero the 3 least significant bits
|
||||
ldx #$00 ; loop index
|
||||
ldy #$00 ; temporary value for mask calculation
|
||||
@4:
|
||||
; Byte offset is simple, just zero the 3 least significant bits
|
||||
|
||||
txa
|
||||
and #%11111000
|
||||
sta __ha_offsets, x
|
||||
|
||||
// Mask changes with each iteration, use our temporary value in .Y
|
||||
; Mask changes with each iteration, use our temporary value in .Y
|
||||
|
||||
tya
|
||||
clc
|
||||
ror
|
||||
bne !+
|
||||
bne @5
|
||||
lda #%10000000
|
||||
!:
|
||||
@5:
|
||||
tay
|
||||
sta __ha_masks, x
|
||||
|
||||
// Next iteration
|
||||
; Next iteration
|
||||
|
||||
inx
|
||||
bne !--
|
||||
bne @4
|
||||
|
||||
// Initialize flag for additional GFX effects
|
||||
; Initialize flag for additional GFX effects
|
||||
|
||||
stx __ha_gfxflag // .X is 0 at this moment
|
||||
stx __ha_gfxflag ; .X is 0 at this moment
|
||||
|
||||
// Generate helper code for screen scrolling
|
||||
; Generate helper code for screen scrolling
|
||||
|
||||
jsr tape_head_align_gen_code
|
||||
|
||||
// Provide new IRQ routine address
|
||||
; Provide new IRQ routine address
|
||||
|
||||
lda #<tape_head_align_irq
|
||||
sta CINV+0
|
||||
lda #>tape_head_align_irq
|
||||
sta CINV+1
|
||||
|
||||
// Setup raster interrupt routine - see https://www.c64-wiki.com/wiki/Raster_interrupt
|
||||
; Setup raster interrupt routine - see https://www.c64-wiki.com/wiki/Raster_interrupt
|
||||
|
||||
lda #%01111111 // prevent CIA from generating interrupts
|
||||
sta CIA1_ICR // $DC0D
|
||||
lda #%01111111 ; prevent CIA from generating interrupts
|
||||
sta CIA1_ICR ; $DC0D
|
||||
|
||||
and VIC_SCROLY // clear the highest bit of RASTER
|
||||
sta VIC_SCROLY // $D011
|
||||
and VIC_SCROLY ; clear the highest bit of RASTER
|
||||
sta VIC_SCROLY ; $D011
|
||||
|
||||
lda #$FB // we want no badlines during the interrupt, this raster is 100% safe
|
||||
lda #$FB ; we want no badlines during the interrupt, this raster is 100% safe
|
||||
sta VIC_RASTER
|
||||
|
||||
lda #%00000001 // enable raster interrupts
|
||||
sta VIC_IRQMSK // $D01A
|
||||
lda #%00000001 ; enable raster interrupts
|
||||
sta VIC_IRQMSK ; $D01A
|
||||
cli
|
||||
|
||||
tape_head_align_loop_1:
|
||||
|
||||
// Check for STOP key
|
||||
; Check for STOP key
|
||||
|
||||
jsr udtim_keyboard
|
||||
jsr STOP
|
||||
bcs tape_head_align_quit
|
||||
|
||||
// Launch the timer
|
||||
; Launch the timer
|
||||
|
||||
ldx #%00011001 // start timer, one-shot force latch reload, count system ticks
|
||||
stx CIA1_CRB // $DC0F
|
||||
ldx #%00011001 ; start timer, one-shot force latch reload, count system ticks
|
||||
stx CIA1_CRB ; $DC0F
|
||||
|
||||
// Scroll the whole chart one line down
|
||||
; Scroll the whole chart one line down
|
||||
|
||||
ldx #$00
|
||||
!:
|
||||
jsr __ha_scroll // scroll one column down, using fast generated code
|
||||
@6:
|
||||
jsr __ha_scroll ; scroll one column down, using fast generated code
|
||||
|
||||
txa
|
||||
clc
|
||||
adc #$08
|
||||
tax
|
||||
bne !-
|
||||
bne @6
|
||||
|
||||
// Draw decorations
|
||||
; Draw decorations
|
||||
|
||||
lda __ha_gfxflag
|
||||
inc __ha_gfxflag
|
||||
clc
|
||||
adc #$08
|
||||
and #%00001100
|
||||
bne !+
|
||||
bne @7
|
||||
ldy #%11110001
|
||||
lda #%10001111
|
||||
bne !++
|
||||
!:
|
||||
bne @8
|
||||
@7:
|
||||
ldy #%00000001
|
||||
lda #%10000000
|
||||
!:
|
||||
@8:
|
||||
ora __ha_chart + 7 + 8 * 0
|
||||
sta __ha_chart + 7 + 8 * 0
|
||||
|
||||
@@ -214,13 +214,13 @@ tape_head_align_loop_1:
|
||||
ora __ha_chart + 7 + 8 * 31
|
||||
sta __ha_chart + 7 + 8 * 31
|
||||
|
||||
// Draw helper lines
|
||||
; Draw helper lines
|
||||
|
||||
lda __ha_gfxflag
|
||||
and #%00000010
|
||||
beq !+
|
||||
beq @9
|
||||
|
||||
// For 'normal'
|
||||
; For 'normal'
|
||||
|
||||
lda #%00000001
|
||||
ora __ha_chart + 7 + 8 * 6
|
||||
@@ -230,13 +230,13 @@ tape_head_align_loop_1:
|
||||
ora __ha_chart + 7 + 8 * 13
|
||||
sta __ha_chart + 7 + 8 * 13
|
||||
|
||||
// For 'turbo'
|
||||
; For 'turbo'
|
||||
|
||||
lda #%00010000
|
||||
ora __ha_chart + 7 + 8 * 21
|
||||
sta __ha_chart + 7 + 8 * 21
|
||||
!:
|
||||
// FALLTROUGH
|
||||
@9:
|
||||
; FALLTROUGH
|
||||
|
||||
tape_head_align_loop_2:
|
||||
|
||||
@@ -250,18 +250,18 @@ tape_head_align_loop_2:
|
||||
|
||||
tape_head_align_quit:
|
||||
|
||||
// It makes no sense to return to system, as we already destroyed
|
||||
// a lot of memory; fust clear initial BASIC text area to prevent
|
||||
// data recovery attempts, and reset
|
||||
; It makes no sense to return to system, as we already destroyed
|
||||
; a lot of memory; fust clear initial BASIC text area to prevent
|
||||
; data recovery attempts, and reset
|
||||
|
||||
ldx #$00
|
||||
txa
|
||||
!:
|
||||
@10:
|
||||
sta $0800, x
|
||||
inx
|
||||
bne !-
|
||||
bne @10
|
||||
|
||||
jmp hw_entry_reset
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_HEAD_ALIGN
|
||||
} ; CONFIG_TAPE_HEAD_ALIGN
|
||||
@@ -1,31 +1,31 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape head alignemnt tool - helper code generator
|
||||
//
|
||||
;
|
||||
; Tape head alignemnt tool - helper code generator
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
!ifdef CONFIG_TAPE_HEAD_ALIGN {
|
||||
|
||||
|
||||
// Helper variables - reuse BASIC numeric work area on zero page
|
||||
; Helper variables - reuse BASIC numeric work area on zero page
|
||||
|
||||
.label __ha_lda_addr = TEMPF1 + 0; // 2 bytes, for code generator
|
||||
.label __ha_sta_addr = TEMPF1 + 2; // 2 bytes, for code generator
|
||||
!addr __ha_lda_addr = TEMPF1 + 0; ; 2 bytes, for code generator
|
||||
!addr __ha_sta_addr = TEMPF1 + 2; ; 2 bytes, for code generator
|
||||
|
||||
|
||||
tape_head_align_gen_code:
|
||||
|
||||
// Setup generated code start address
|
||||
; Setup generated code start address
|
||||
|
||||
lda #<__ha_scroll
|
||||
sta SAL+0
|
||||
lda #>__ha_scroll
|
||||
sta SAL+1
|
||||
|
||||
// Setup initial source and destination addresses
|
||||
; Setup initial source and destination addresses
|
||||
|
||||
ldy #<(__ha_chart + __ha_rows * (8 * 40) + 6)
|
||||
sty __ha_lda_addr + 0
|
||||
@@ -36,19 +36,19 @@ tape_head_align_gen_code:
|
||||
sty __ha_lda_addr + 1
|
||||
sty __ha_sta_addr + 1
|
||||
|
||||
// Emit code to move 7 rows of one 8x8 cell
|
||||
!:
|
||||
; Emit code to move 7 rows of one 8x8 cell
|
||||
@1:
|
||||
ldx #$07
|
||||
!:
|
||||
@2:
|
||||
jsr tape_head_align_gen_code_emit_pair
|
||||
|
||||
dec __ha_lda_addr + 0
|
||||
dec __ha_sta_addr + 0
|
||||
|
||||
dex
|
||||
bne !-
|
||||
bne @2
|
||||
|
||||
// Emit code to fetch a top row from the cell above
|
||||
; Emit code to fetch a top row from the cell above
|
||||
|
||||
inc __ha_lda_addr + 0
|
||||
sec
|
||||
@@ -62,7 +62,7 @@ tape_head_align_gen_code:
|
||||
|
||||
jsr tape_head_align_gen_code_emit_pair
|
||||
|
||||
// Prepare addresses for the next iteration
|
||||
; Prepare addresses for the next iteration
|
||||
|
||||
lda __ha_lda_addr + 0
|
||||
sta __ha_sta_addr + 0
|
||||
@@ -71,16 +71,16 @@ tape_head_align_gen_code:
|
||||
|
||||
dec __ha_lda_addr + 0
|
||||
|
||||
// Now, new iteration - if needed
|
||||
; Now, new iteration - if needed
|
||||
|
||||
lda __ha_sta_addr + 0
|
||||
cmp #<(__ha_chart + 7)
|
||||
bne !--
|
||||
bne @1
|
||||
lda __ha_sta_addr + 1
|
||||
cmp #>(__ha_chart + 7)
|
||||
bne !--
|
||||
bne @1
|
||||
|
||||
// Last pair to be generated starts from LDA #$00
|
||||
; Last pair to be generated starts from LDA #$00
|
||||
|
||||
lda #$A9
|
||||
jsr tape_head_align_gen_code_emit_byte
|
||||
@@ -89,7 +89,7 @@ tape_head_align_gen_code:
|
||||
|
||||
jsr tape_head_align_gen_code_emit_sta
|
||||
|
||||
// Emit RTS and quit
|
||||
; Emit RTS and quit
|
||||
|
||||
lda #$60
|
||||
jmp tape_head_align_gen_code_emit_byte
|
||||
@@ -98,7 +98,7 @@ tape_head_align_gen_code:
|
||||
|
||||
tape_head_align_gen_code_emit_pair:
|
||||
|
||||
lda #$BD // LDA absolute, x
|
||||
lda #$BD ; LDA absolute, x
|
||||
jsr tape_head_align_gen_code_emit_byte
|
||||
|
||||
lda __ha_lda_addr + 0
|
||||
@@ -106,33 +106,32 @@ tape_head_align_gen_code_emit_pair:
|
||||
lda __ha_lda_addr + 1
|
||||
jsr tape_head_align_gen_code_emit_byte
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_head_align_gen_code_emit_sta:
|
||||
|
||||
lda #$9D // STA absolute, x
|
||||
lda #$9D ; STA absolute, x
|
||||
jsr tape_head_align_gen_code_emit_byte
|
||||
|
||||
lda __ha_sta_addr + 0
|
||||
jsr tape_head_align_gen_code_emit_byte
|
||||
lda __ha_sta_addr + 1
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_head_align_gen_code_emit_byte:
|
||||
|
||||
ldy #$00
|
||||
sta (SAL), y
|
||||
#if HAS_OPCODES_65CE02
|
||||
!ifdef HAS_OPCODES_65CE02 {
|
||||
inw SAL
|
||||
#else
|
||||
} else {
|
||||
inc SAL+0
|
||||
bne !+
|
||||
bne @3
|
||||
inc SAL+1
|
||||
!:
|
||||
#endif
|
||||
|
||||
@3:
|
||||
}
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_HEAD_ALIGN
|
||||
} ; CONFIG_TAPE_HEAD_ALIGN
|
||||
@@ -1,45 +1,45 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape head alignemnt tool - reading pulses from tape
|
||||
//
|
||||
;
|
||||
; Tape head alignemnt tool - reading pulses from tape
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
!ifdef CONFIG_TAPE_HEAD_ALIGN {
|
||||
|
||||
|
||||
tape_head_align_get_pulse:
|
||||
|
||||
// This routine differs from the one used to read pulse during tape reading:
|
||||
// - it is not as precise
|
||||
// - it terminates when timer reaches $FF
|
||||
// - it returns value in .Y
|
||||
; This routine differs from the one used to read pulse during tape reading:
|
||||
; - it is not as precise
|
||||
; - it terminates when timer reaches $FF
|
||||
; - it returns value in .Y
|
||||
|
||||
lda #$10
|
||||
!:
|
||||
// Loop to detect signal
|
||||
@1:
|
||||
; Loop to detect signal
|
||||
|
||||
ldy CIA2_TIMBLO // $DD06
|
||||
bit CIA1_ICR // $DC0D
|
||||
bne !+
|
||||
ldy CIA2_TIMBLO ; $DD06
|
||||
bit CIA1_ICR ; $DC0D
|
||||
bne @2
|
||||
|
||||
cpy #$FF
|
||||
bne !-
|
||||
!:
|
||||
// FALLTROUGH
|
||||
bne @1
|
||||
@2:
|
||||
; FALLTROUGH
|
||||
|
||||
tape_head_align_get_pulse_start_timer:
|
||||
|
||||
// Start timer again, force latch reload, count timer A underflows
|
||||
; Start timer again, force latch reload, count timer A underflows
|
||||
|
||||
lda #%01010001
|
||||
sta CIA2_CRB // $DD0F
|
||||
sta CIA2_CRB ; $DD0F
|
||||
|
||||
// Return with time elapsed in .Y
|
||||
; Return with time elapsed in .Y
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_HEAD_ALIGN
|
||||
} ; CONFIG_TAPE_HEAD_ALIGN
|
||||
@@ -1,35 +1,35 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape head alignemnt tool - prints out a help message on screen
|
||||
//
|
||||
;
|
||||
; Tape head alignemnt tool - prints out a help message on screen
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
!ifdef CONFIG_TAPE_HEAD_ALIGN {
|
||||
|
||||
|
||||
// Helper variable - reuse BASIC numeric work area on zero page
|
||||
; Helper variable - reuse BASIC numeric work area on zero page
|
||||
|
||||
.label __ha_storage = TEMPF1; // 1 byte
|
||||
!addr __ha_storage = TEMPF1; ; 1 byte
|
||||
|
||||
|
||||
tape_head_align_print_help:
|
||||
|
||||
// Make screen font visible
|
||||
; Make screen font visible
|
||||
|
||||
lda CPU_R6510
|
||||
pha
|
||||
and #%11111011
|
||||
sta CPU_R6510
|
||||
|
||||
// Print help message
|
||||
; Print help message
|
||||
|
||||
ldy #$00
|
||||
|
||||
// Retrieve address
|
||||
!:
|
||||
; Retrieve address
|
||||
@1:
|
||||
lda tape_head_align_help_text, y
|
||||
iny
|
||||
cmp #$FF
|
||||
@@ -39,24 +39,24 @@ tape_head_align_print_help:
|
||||
lda tape_head_align_help_text, y
|
||||
iny
|
||||
sta EAL+1
|
||||
!:
|
||||
// Retrieve and print character
|
||||
@2:
|
||||
; Retrieve and print character
|
||||
|
||||
lda tape_head_align_help_text, y
|
||||
iny
|
||||
cmp #$FF
|
||||
beq !--
|
||||
beq @1
|
||||
|
||||
sty __ha_storage
|
||||
jsr tape_head_align_print_char
|
||||
ldy __ha_storage
|
||||
|
||||
bne !- // branch alwats
|
||||
bne @2 ; branch alwats
|
||||
|
||||
|
||||
tape_head_align_print_end:
|
||||
|
||||
// Restore normal memory configuration and quit
|
||||
; Restore normal memory configuration and quit
|
||||
|
||||
pla
|
||||
sta CPU_R6510
|
||||
@@ -68,7 +68,7 @@ tape_head_align_print_string:
|
||||
|
||||
tape_head_align_print_char:
|
||||
|
||||
// Calculate start address of character in .A
|
||||
; Calculate start address of character in .A
|
||||
|
||||
sta SAL+0
|
||||
lda #$00
|
||||
@@ -86,62 +86,57 @@ tape_head_align_print_char:
|
||||
adc #$D0
|
||||
sta SAL+1
|
||||
|
||||
// Print out the character
|
||||
; Print out the character
|
||||
|
||||
ldy #$07
|
||||
!:
|
||||
@3:
|
||||
lda (SAL), y
|
||||
sta (EAL), y
|
||||
dey
|
||||
bpl !-
|
||||
bpl @3
|
||||
|
||||
// Prepare EAL for the next character
|
||||
; Prepare EAL for the next character
|
||||
|
||||
lda EAL+0
|
||||
clc
|
||||
adc #$08
|
||||
sta EAL+0
|
||||
bne !+
|
||||
bne @4
|
||||
inc EAL+1
|
||||
!:
|
||||
@4:
|
||||
rts
|
||||
|
||||
|
||||
//
|
||||
// Strings to print
|
||||
//
|
||||
|
||||
.encoding "screencode_upper"
|
||||
|
||||
;
|
||||
; Strings to print
|
||||
;
|
||||
|
||||
tape_head_align_help_text:
|
||||
|
||||
// Each string consists of:
|
||||
// - destination (start byte) address
|
||||
// - text in screencodes
|
||||
// - $FF to mark end
|
||||
; Each string consists of:
|
||||
; - destination (start byte) address
|
||||
; - text in screencodes
|
||||
; - $FF to mark end
|
||||
|
||||
.word $2000 + (40 * 8) * 0 + 8 * 1
|
||||
.text "COMPUTER HAS TO TELL THE SIGNALS APART"
|
||||
.byte $FF
|
||||
!word $2000 + (40 * 8) * 0 + 8 * 1
|
||||
!scr "computer has to tell the signals apart"
|
||||
!byte $FF
|
||||
|
||||
.word $2000 + (40 * 8) * 3 + 8 * 6
|
||||
.text "ALIGN HEAD FOR MINIMUM NOISE"
|
||||
.byte $FF
|
||||
!word $2000 + (40 * 8) * 3 + 8 * 6
|
||||
!scr "align head for minimum noise"
|
||||
!byte $FF
|
||||
|
||||
.word $2000 + (40 * 8) * 6 + 8 * 2
|
||||
.text "IF THE DECK HAS A PITCH (TAPE SPEED)"
|
||||
.byte $FF
|
||||
!word $2000 + (40 * 8) * 6 + 8 * 2
|
||||
!scr "if the deck has a pitch (tape speed)"
|
||||
!byte $FF
|
||||
|
||||
.word $2000 + (40 * 8) * 7 + 8 * 1
|
||||
.text "CONTROL, TWEAK IT SO THAT DOTTED LINES"
|
||||
.byte $FF
|
||||
!word $2000 + (40 * 8) * 7 + 8 * 1
|
||||
!scr "control, tweak it so that dotted lines"
|
||||
!byte $FF
|
||||
|
||||
.word $2000 + (40 * 8) * 8 + 8 * 5
|
||||
.text "ARE HALF A WAY BETWEEN SIGNALS"
|
||||
.byte $FF
|
||||
!word $2000 + (40 * 8) * 8 + 8 * 5
|
||||
!scr "are half a way between signals"
|
||||
!byte $FF
|
||||
|
||||
.byte $FF // end of strings
|
||||
|
||||
|
||||
#endif
|
||||
!byte $FF ; end of strings
|
||||
}
|
||||
@@ -1,55 +1,55 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape head alignemnt tool - interrupt routine
|
||||
//
|
||||
;
|
||||
; Tape head alignemnt tool - interrupt routine
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
!ifdef CONFIG_TAPE_HEAD_ALIGN {
|
||||
|
||||
|
||||
tape_head_align_irq:
|
||||
|
||||
// Acknowledge interrupt
|
||||
; Acknowledge interrupt
|
||||
|
||||
asl VIC_IRQ
|
||||
|
||||
// Ignore 2 first pulses, they can be garbage
|
||||
; Ignore 2 first pulses, they can be garbage
|
||||
|
||||
jsr tape_head_align_get_pulse
|
||||
jsr tape_head_align_get_pulse
|
||||
|
||||
// Now, we can retrieve pulses for the chart
|
||||
; Now, we can retrieve pulses for the chart
|
||||
|
||||
ldx #$00
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_head_align_irq_loop:
|
||||
|
||||
jsr tape_head_align_get_pulse
|
||||
|
||||
// If we approached badlines again - we cannot use this measurement anymore
|
||||
; If we approached badlines again - we cannot use this measurement anymore
|
||||
|
||||
lda VIC_SCROLY
|
||||
bmi !+ // branch if lower border
|
||||
bmi @1 ; branch if lower border
|
||||
|
||||
lda VIC_RASTER
|
||||
cmp #$33 // first line where badline can occur
|
||||
cmp #$33 ; first line where badline can occur
|
||||
bcs tape_head_align_irq_end
|
||||
!:
|
||||
// Draw pulse on the screen
|
||||
@1:
|
||||
; Draw pulse on the screen
|
||||
|
||||
cpy #$FF
|
||||
beq !+
|
||||
beq @2
|
||||
|
||||
// Center the chart horizontaly, with some margin from top
|
||||
; Center the chart horizontaly, with some margin from top
|
||||
|
||||
.label __ha_chart = $2000 + 8 * (40 * __ha_start + 4)
|
||||
!addr __ha_chart = $2000 + 8 * (40 * __ha_start + 4)
|
||||
|
||||
phx_trash_a
|
||||
+phx_trash_a
|
||||
|
||||
lda __ha_offsets, y
|
||||
tax
|
||||
@@ -57,19 +57,19 @@ tape_head_align_irq_loop:
|
||||
ora __ha_chart + 7, x
|
||||
sta __ha_chart + 7, x
|
||||
|
||||
plx_trash_a
|
||||
!:
|
||||
// Next iteration
|
||||
+plx_trash_a
|
||||
@2:
|
||||
; Next iteration
|
||||
|
||||
inx
|
||||
cpx #$40
|
||||
bne tape_head_align_irq_loop
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_head_align_irq_end:
|
||||
|
||||
jmp return_from_interrupt
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_HEAD_ALIGN
|
||||
} ; CONFIG_TAPE_HEAD_ALIGN
|
||||
@@ -1,69 +1,69 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) helper routine - reading speed calibration
|
||||
//
|
||||
// Needs pulse length in .A
|
||||
//
|
||||
;
|
||||
; Tape (normal) helper routine - reading speed calibration
|
||||
;
|
||||
; Needs pulse length in .A
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
tape_normal_calibrate_during_pilot: // reecalibration during the pilot
|
||||
tape_normal_calibrate_during_pilot: ; reecalibration during the pilot
|
||||
|
||||
sta __normal_time_S
|
||||
|
||||
// We do not have any recent medium pulse measurement,
|
||||
// probably the only solution is to estimate it
|
||||
; We do not have any recent medium pulse measurement,
|
||||
; probably the only solution is to estimate it
|
||||
|
||||
lda #$FF
|
||||
sec
|
||||
sbc __normal_time_S
|
||||
|
||||
// We now have a difference from the starting point ($FF)
|
||||
; We now have a difference from the starting point ($FF)
|
||||
|
||||
clc
|
||||
ror
|
||||
sta __normal_time_M // this is temporary only!
|
||||
sta __normal_time_M ; this is temporary only!
|
||||
|
||||
// We now have half the difference, substract it from
|
||||
// short pulse measurement result
|
||||
; We now have half the difference, substract it from
|
||||
; short pulse measurement result
|
||||
|
||||
lda __normal_time_S
|
||||
sec
|
||||
sbc __normal_time_M
|
||||
|
||||
// Add a small correction to gain $7D if starting from $A5. Dirty, ugly,
|
||||
// and imprecise hack - but in real life should be good enough
|
||||
; Add a small correction to gain $7D if starting from $A5. Dirty, ugly,
|
||||
; and imprecise hack - but in real life should be good enough
|
||||
|
||||
clc
|
||||
adc #$05
|
||||
sta __normal_time_M // estimated medium pulse length
|
||||
sta __normal_time_M ; estimated medium pulse length
|
||||
|
||||
jmp tape_normal_calibrate_common
|
||||
|
||||
|
||||
|
||||
tape_normal_calibrate_after_S: // recalibration after short pulse
|
||||
tape_normal_calibrate_after_S: ; recalibration after short pulse
|
||||
|
||||
sta __normal_time_S
|
||||
rts
|
||||
skip_2_bytes_trash_nvz
|
||||
+skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_calibrate_after_M: // recalibration after medium pulse
|
||||
tape_normal_calibrate_after_M: ; recalibration after medium pulse
|
||||
|
||||
sta __normal_time_M
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_calibrate_common:
|
||||
|
||||
// Now compare results with current threshold
|
||||
; Now compare results with current threshold
|
||||
|
||||
lda __normal_time_S
|
||||
sec
|
||||
@@ -73,20 +73,20 @@ tape_normal_calibrate_common:
|
||||
|
||||
cmp __pulse_threshold
|
||||
|
||||
beq tape_normal_calibrate_done // branch if no recalibration needed
|
||||
beq tape_normal_calibrate_done ; branch if no recalibration needed
|
||||
|
||||
// Correct the thresholds (default is $91 for the S/M one)
|
||||
; Correct the thresholds (default is $91 for the S/M one)
|
||||
|
||||
bcs tape_normal_calibrate_threshold_inc // branch if .A >= memory
|
||||
bcs tape_normal_calibrate_threshold_inc ; branch if .A >= memory
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
|
||||
tape_normal_calibrate_threshold_dec:
|
||||
|
||||
lda __pulse_threshold
|
||||
cmp #($91-10)
|
||||
bcc tape_normal_calibrate_done // do not decrement thresholds too far
|
||||
bcc tape_normal_calibrate_done ; do not decrement thresholds too far
|
||||
|
||||
sec
|
||||
sbc #$02
|
||||
@@ -97,14 +97,14 @@ tape_normal_calibrate_threshold_dec:
|
||||
sbc #$03
|
||||
sta __pulse_threshold_ML
|
||||
|
||||
bne tape_normal_calibrate_done // branch always
|
||||
bne tape_normal_calibrate_done ; branch always
|
||||
|
||||
|
||||
tape_normal_calibrate_threshold_inc:
|
||||
|
||||
lda __pulse_threshold
|
||||
cmp #($91+11)
|
||||
bcs tape_normal_calibrate_done // do not increment thresholds too far
|
||||
bcs tape_normal_calibrate_done ; do not increment thresholds too far
|
||||
|
||||
clc
|
||||
adc #$02
|
||||
@@ -115,12 +115,10 @@ tape_normal_calibrate_threshold_inc:
|
||||
adc #$03
|
||||
sta __pulse_threshold_ML
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
|
||||
tape_normal_calibrate_done:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,25 +1,25 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) helper routine - bit reading
|
||||
//
|
||||
// Returns bit in Zero flag, Carry set means error, on 0 bit .A is 0 too
|
||||
//
|
||||
;
|
||||
; Tape (normal) helper routine - bit reading
|
||||
;
|
||||
; Returns bit in Zero flag, Carry set means error, on 0 bit .A is 0 too
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
tape_normal_get_bit:
|
||||
|
||||
// Fetch the first pulse
|
||||
; Fetch the first pulse
|
||||
|
||||
jsr tape_common_get_pulse
|
||||
bcc tape_normal_get_bit_1
|
||||
|
||||
// First impulse was short, second should be medium
|
||||
; First impulse was short, second should be medium
|
||||
|
||||
jsr tape_normal_calibrate_after_S
|
||||
|
||||
@@ -28,11 +28,11 @@ tape_normal_get_bit:
|
||||
|
||||
jsr tape_normal_calibrate_after_M
|
||||
|
||||
// We have a bit '0'
|
||||
; We have a bit '0'
|
||||
|
||||
lda #$00
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_bit_done:
|
||||
|
||||
@@ -43,7 +43,7 @@ tape_normal_get_bit_done:
|
||||
|
||||
tape_normal_get_bit_1:
|
||||
|
||||
// First impulse was medium, second should be short
|
||||
; First impulse was medium, second should be short
|
||||
|
||||
jsr tape_normal_calibrate_after_M
|
||||
|
||||
@@ -52,11 +52,11 @@ tape_normal_get_bit_1:
|
||||
|
||||
jsr tape_normal_calibrate_after_S
|
||||
|
||||
// We have a bit '1'
|
||||
; We have a bit '1'
|
||||
|
||||
clc
|
||||
lda #$06
|
||||
bne tape_normal_get_bit_done // branch always
|
||||
bne tape_normal_get_bit_done ; branch always
|
||||
|
||||
|
||||
tape_normal_get_bit_error:
|
||||
@@ -65,4 +65,4 @@ tape_normal_get_bit_error:
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_NORMAL
|
||||
} ; CONFIG_TAPE_NORMAL
|
||||
@@ -1,60 +1,60 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) helper routine - byte reading
|
||||
//
|
||||
// Returns byte in .A (also sotred in INBIT), Carry flag set = error
|
||||
//
|
||||
;
|
||||
; Tape (normal) helper routine - byte reading
|
||||
;
|
||||
; Returns byte in .A (also sotred in INBIT), Carry flag set = error
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
tape_normal_get_byte:
|
||||
|
||||
// Init parity bit and canary bit
|
||||
; Init parity bit and canary bit
|
||||
lda #$01
|
||||
sta PRTY
|
||||
lda #%01111111 // canary bit is 0
|
||||
lda #%01111111 ; canary bit is 0
|
||||
sta INBIT
|
||||
|
||||
// Now fetch individual bits
|
||||
; Now fetch individual bits
|
||||
|
||||
tape_normal_get_byte_loop:
|
||||
|
||||
jsr tape_normal_get_bit
|
||||
bcs tape_normal_get_byte_error
|
||||
beq !+
|
||||
beq @1
|
||||
|
||||
// Handle parity bit
|
||||
; Handle parity bit
|
||||
lda #$01
|
||||
eor PRTY
|
||||
sta PRTY
|
||||
|
||||
sec
|
||||
!: // moved bit state from Zero to Carry flag
|
||||
@1: ; moved bit state from Zero to Carry flag
|
||||
|
||||
ror INBIT // put the bit in
|
||||
bcs tape_normal_get_byte_loop // loop if no canary bit reached
|
||||
ror INBIT ; put the bit in
|
||||
bcs tape_normal_get_byte_loop ; loop if no canary bit reached
|
||||
|
||||
// Byte retrieved (on stack), now we need to validate the parity
|
||||
; Byte retrieved (on stack), now we need to validate the parity
|
||||
|
||||
jsr tape_normal_get_bit
|
||||
bcs tape_normal_get_byte_error
|
||||
beq !+
|
||||
beq @2
|
||||
lda #$01
|
||||
!:
|
||||
@2:
|
||||
eor PRTY
|
||||
bne tape_normal_get_byte_error
|
||||
|
||||
// Checksum validated succesfully
|
||||
; Checksum validated succesfully
|
||||
|
||||
ldx #$0B
|
||||
// Carry already clear
|
||||
; Carry already clear
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_byte_done:
|
||||
|
||||
@@ -66,8 +66,6 @@ tape_normal_get_byte_done:
|
||||
tape_normal_get_byte_error:
|
||||
|
||||
ldx #$09
|
||||
sec // make sure Carry is set to indicate error
|
||||
sec ; make sure Carry is set to indicate error
|
||||
bcs tape_normal_get_byte_done
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,36 +1,36 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) helper routine - data block (primary) reading
|
||||
//
|
||||
// Stores data starting from MEMUSS, Carry set means error, on 0 bit .A is 0 too
|
||||
// .Y not equal to 0 - returns error if data block is longer (length includes checksum)
|
||||
;
|
||||
; Tape (normal) helper routine - data block (primary) reading
|
||||
;
|
||||
; Stores data starting from MEMUSS, Carry set means error, on 0 bit .A is 0 too
|
||||
; .Y not equal to 0 - returns error if data block is longer (length includes checksum)
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
tape_normal_get_data_1:
|
||||
|
||||
// Initialize checksum (RIPRTY, see http://sta.c64.org/cbm64mem.html)
|
||||
// and pointers for error log and correction mechanism
|
||||
; Initialize checksum (RIPRTY, see http://sta.c64.org/cbm64mem.html)
|
||||
; and pointers for error log and correction mechanism
|
||||
lda #$00
|
||||
sta RIPRTY
|
||||
|
||||
sta PTR2
|
||||
sta PTR1
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_data_1_block:
|
||||
|
||||
//
|
||||
// Read the 1st copy of the block
|
||||
//
|
||||
;
|
||||
; Read the 1st copy of the block
|
||||
;
|
||||
|
||||
// Read sync of the block
|
||||
; Read sync of the block
|
||||
ldy #$89
|
||||
jsr tape_normal_sync
|
||||
bcs tape_normal_get_data_1_fail
|
||||
@@ -41,11 +41,11 @@ tape_normal_get_data_1_loop:
|
||||
jsr tape_normal_get_byte
|
||||
bcc tape_normal_get_data_1_loop_byte_OK
|
||||
|
||||
// Problem reading a byte, try to add it to the error log
|
||||
; Problem reading a byte, try to add it to the error log
|
||||
|
||||
tsx
|
||||
cpx #$20 // just to be on a safe side
|
||||
bcc tape_normal_get_data_1_fail // branch if no more space in error log
|
||||
cpx #$20 ; just to be on a safe side
|
||||
bcc tape_normal_get_data_1_fail ; branch if no more space in error log
|
||||
|
||||
ldx PTR1
|
||||
lda MEMUSS+0
|
||||
@@ -56,7 +56,7 @@ tape_normal_get_data_1_loop:
|
||||
inx
|
||||
stx PTR1
|
||||
|
||||
// Addres added to error log, check if this was a checksum
|
||||
; Addres added to error log, check if this was a checksum
|
||||
jsr tape_normal_get_marker
|
||||
bcc tape_normal_get_data_1_loop_advance
|
||||
bcs tape_normal_get_data_1_success
|
||||
@@ -64,33 +64,33 @@ tape_normal_get_data_1_loop:
|
||||
tape_normal_get_data_1_loop_byte_OK:
|
||||
|
||||
jsr tape_normal_get_marker
|
||||
bcc !+
|
||||
bcc @1
|
||||
|
||||
// End of the block
|
||||
; End of the block
|
||||
jsr tape_normal_update_checksum
|
||||
jmp tape_normal_get_data_1_success
|
||||
|
||||
!:
|
||||
// Store byte, calculate checksum
|
||||
@1:
|
||||
; Store byte, calculate checksum
|
||||
lda INBIT
|
||||
ldy #$00
|
||||
#if ROM_LAYOUT_M65
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
jsr tape_normal_byte_store
|
||||
#else
|
||||
} else {
|
||||
sta (MEMUSS), y
|
||||
#endif
|
||||
}
|
||||
jsr tape_normal_update_checksum
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_data_1_loop_advance:
|
||||
|
||||
// Advance pointer
|
||||
#if !HAS_OPCODES_65CE02
|
||||
; Advance pointer
|
||||
!ifndef HAS_OPCODES_65CE02 {
|
||||
jsr lvs_advance_MEMUSS
|
||||
#else
|
||||
} else {
|
||||
inw MEMUSS+0
|
||||
#endif
|
||||
}
|
||||
|
||||
jmp tape_normal_get_data_1_loop
|
||||
|
||||
@@ -104,6 +104,4 @@ tape_normal_get_data_1_fail:
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,77 +1,77 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) helper routine - data block (backup) reading
|
||||
//
|
||||
;
|
||||
; Tape (normal) helper routine - data block (backup) reading
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
tape_normal_get_data_2:
|
||||
|
||||
// NOTE: Always read all the bytes fro second copy, to taht we stop
|
||||
// at the moment when it is safe to start recording!
|
||||
; NOTE: Always read all the bytes fro second copy, to taht we stop
|
||||
; at the moment when it is safe to start recording!
|
||||
|
||||
// Read sync of the block
|
||||
; Read sync of the block
|
||||
|
||||
ldy #$09
|
||||
jsr tape_normal_sync
|
||||
bcs tape_normal_get_data_2_done // Carry already set, will indicate error
|
||||
bcs tape_normal_get_data_2_done ; Carry already set, will indicate error
|
||||
jsr tape_normal_get_marker
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_data_2_loop:
|
||||
|
||||
// Read missing bytes
|
||||
; Read missing bytes
|
||||
|
||||
jsr tape_normal_get_byte
|
||||
bcc tape_normal_get_data_2_loop_byte_OK
|
||||
|
||||
// Problem reading a byte - just skip it
|
||||
; Problem reading a byte - just skip it
|
||||
|
||||
bcs tape_normal_get_data_2_loop_advance
|
||||
|
||||
tape_normal_get_data_2_loop_byte_OK:
|
||||
|
||||
jsr load_cmp_log_MEMUSS
|
||||
beq tape_normal_get_data_2_loop_from_log // branch if byte from the log
|
||||
beq tape_normal_get_data_2_loop_from_log ; branch if byte from the log
|
||||
|
||||
jsr tape_normal_get_marker
|
||||
bcs tape_normal_get_data_2_log_checksum // branch if end of blocks
|
||||
bcs tape_normal_get_data_2_log_checksum ; branch if end of blocks
|
||||
bcc tape_normal_get_data_2_loop_advance
|
||||
|
||||
|
||||
tape_normal_get_data_2_loop_from_log:
|
||||
|
||||
// This is a byte from the log
|
||||
; This is a byte from the log
|
||||
|
||||
jsr tape_normal_get_marker
|
||||
bcs !+
|
||||
bcs @1
|
||||
|
||||
lda INBIT
|
||||
ldy #$00
|
||||
#if ROM_LAYOUT_M65
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
jsr tape_normal_byte_store
|
||||
#else
|
||||
} else {
|
||||
sta (MEMUSS), y
|
||||
#endif
|
||||
!:
|
||||
}
|
||||
@1:
|
||||
jsr tape_normal_update_checksum
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_data_2_loop_advance:
|
||||
|
||||
// Advance pointer
|
||||
#if !HAS_OPCODES_65CE02
|
||||
; Advance pointer
|
||||
!ifndef HAS_OPCODES_65CE02 {
|
||||
jsr lvs_advance_MEMUSS
|
||||
#else
|
||||
} else {
|
||||
inw MEMUSS+0
|
||||
#endif
|
||||
}
|
||||
|
||||
jmp tape_normal_get_data_2_loop
|
||||
|
||||
@@ -80,14 +80,14 @@ tape_normal_get_data_2_log_checksum:
|
||||
|
||||
lda PTR1
|
||||
cmp PTR2
|
||||
bne tape_normal_get_data_2_done // Carry already set
|
||||
bne tape_normal_get_data_2_done ; Carry already set
|
||||
|
||||
// Validate checksum
|
||||
; Validate checksum
|
||||
|
||||
lda RIPRTY
|
||||
cmp #$01 // sets Carry if checksum verification fails
|
||||
cmp #$01 ; sets Carry if checksum verification fails
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_data_2_done:
|
||||
|
||||
@@ -99,19 +99,17 @@ load_cmp_log_MEMUSS:
|
||||
ldx PTR2
|
||||
lda STACK+0, x
|
||||
cmp MEMUSS+0
|
||||
bne !+
|
||||
bne @2
|
||||
|
||||
lda STACK+1, x
|
||||
cmp MEMUSS+1
|
||||
bne !+
|
||||
bne @2
|
||||
|
||||
// MEMUSS matches address from the log
|
||||
; MEMUSS matches address from the log
|
||||
|
||||
inc PTR2
|
||||
inc PTR2
|
||||
lda #$00 // to set Zero flag
|
||||
!:
|
||||
lda #$00 ; to set Zero flag
|
||||
@2:
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) helper routine - marker reading
|
||||
//
|
||||
// Reeturns marker type in Carry flag, set = end of data (normal marker) or failure (marker while sync)
|
||||
//
|
||||
;
|
||||
; Tape (normal) helper routine - marker reading
|
||||
;
|
||||
; Reeturns marker type in Carry flag, set = end of data (normal marker) or failure (marker while sync)
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
// (L,M) - end of byte, (L,S) - end of data
|
||||
; (L,M) - end of byte, (L,S) - end of data
|
||||
|
||||
|
||||
tape_normal_get_marker:
|
||||
@@ -19,9 +19,9 @@ tape_normal_get_marker:
|
||||
|
||||
jsr tape_common_get_pulse
|
||||
cmp __pulse_threshold_ML
|
||||
bcs tape_normal_get_marker // too short for a long pulse
|
||||
bcs tape_normal_get_marker ; too short for a long pulse
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_marker_type:
|
||||
|
||||
@@ -29,21 +29,21 @@ tape_normal_get_marker_type:
|
||||
|
||||
|
||||
|
||||
// Not an entry point!!!
|
||||
!:
|
||||
jsr tape_normal_calibrate_during_pilot // while sync use short pulses for calibration
|
||||
; Not an entry point!!!
|
||||
|
||||
// FALLTROUGH
|
||||
tape_normal_get_marker_while_sync_loop:
|
||||
|
||||
jsr tape_normal_calibrate_during_pilot ; while sync use short pulses for calibration
|
||||
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_marker_while_sync:
|
||||
|
||||
jsr tape_common_get_pulse
|
||||
bcs !- // branch if short pulse
|
||||
bcs tape_normal_get_marker_while_sync_loop ; branch if short pulse
|
||||
|
||||
cmp __pulse_threshold_ML
|
||||
bcs tape_normal_get_marker_while_sync // too short for a long pulse
|
||||
bcs tape_normal_get_marker_while_sync ; too short for a long pulse
|
||||
|
||||
bcc tape_normal_get_marker_type // branch always
|
||||
|
||||
|
||||
#endif
|
||||
bcc tape_normal_get_marker_type ; branch always
|
||||
}
|
||||
@@ -1,25 +1,25 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (turbo) helper routine - handling the pilot
|
||||
//
|
||||
;
|
||||
; Tape (turbo) helper routine - handling the pilot
|
||||
;
|
||||
|
||||
// Injest the pilot - series of short pulses. According to http://sidpreservation.6581.org/tape-format/
|
||||
// it consist of the following number of pulses:
|
||||
// - $6A00 for header
|
||||
// - $1A00 for data and seq block header
|
||||
// - $4F for repeated header/data
|
||||
; Injest the pilot - series of short pulses. According to http://sidpreservation.6581.org/tape-format/
|
||||
; it consist of the following number of pulses:
|
||||
; - $6A00 for header
|
||||
; - $1A00 for data and seq block header
|
||||
; - $4F for repeated header/data
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
tape_normal_get_pilot_header: // entry point, reset calibration, require 128x $40 pulses
|
||||
tape_normal_get_pilot_header: ; entry point, reset calibration, require 128x $40 pulses
|
||||
|
||||
// Reading the pilot header is the first action performed,
|
||||
// thus start by setting default thresholds
|
||||
; Reading the pilot header is the first action performed,
|
||||
; thus start by setting default thresholds
|
||||
|
||||
lda #$91
|
||||
sta __pulse_threshold
|
||||
@@ -28,36 +28,36 @@ tape_normal_get_pilot_header: // entry point, reset calibration, requir
|
||||
|
||||
lda #$80
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
ldy #$FF // marker: try to detect turbo
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
ldy #$FF ; marker: try to detect turbo
|
||||
bmi tape_normal_get_pilot_header_cont
|
||||
#else
|
||||
skip_2_bytes_trash_nvz
|
||||
#endif
|
||||
} else {
|
||||
+skip_2_bytes_trash_nvz
|
||||
}
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_pilot_data: // entry point, require 4x $40 pulses
|
||||
tape_normal_get_pilot_data: ; entry point, require 4x $40 pulses
|
||||
|
||||
lda #$04
|
||||
skip_2_bytes_trash_nvz
|
||||
+skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_pilot_short: // entry point, require 1x $40 pulses
|
||||
tape_normal_get_pilot_short: ; entry point, require 1x $40 pulses
|
||||
|
||||
lda #$01
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
ldy #$00 // marker: do not try to detect turbo
|
||||
// FALLTROUGH
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
ldy #$00 ; marker: do not try to detect turbo
|
||||
; FALLTROUGH
|
||||
tape_normal_get_pilot_header_cont:
|
||||
sty INBIT
|
||||
#else
|
||||
skip_2_bytes_trash_nvz
|
||||
#endif
|
||||
} else {
|
||||
+skip_2_bytes_trash_nvz
|
||||
}
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_pilot_common:
|
||||
|
||||
@@ -66,34 +66,34 @@ tape_normal_get_pilot_common:
|
||||
lda #$0B
|
||||
sta VIC_EXTCOL
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_pilot_common_restart:
|
||||
|
||||
lda FSBLK
|
||||
sta ROPRTY
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_pilot_common_loop_outer:
|
||||
|
||||
ldy #$40
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_normal_get_pilot_common_loop_inner:
|
||||
|
||||
jsr tape_common_get_pulse
|
||||
bcc tape_normal_get_pilot_common_restart // not a pilot - try again
|
||||
bcc tape_normal_get_pilot_common_restart ; not a pilot - try again
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
bit INBIT
|
||||
bpl !+
|
||||
// Try to distinguish turbo by cheecking for short signals
|
||||
cmp #$B9 // see comment in tape_common_autodetect.s
|
||||
bcs !++
|
||||
!:
|
||||
#endif
|
||||
bpl @1
|
||||
; Try to distinguish turbo by checking for short signals
|
||||
cmp #$B9 ; see comment in tape_common_autodetect.s
|
||||
bcs @2
|
||||
@1:
|
||||
}
|
||||
|
||||
jsr tape_normal_calibrate_during_pilot
|
||||
|
||||
@@ -104,8 +104,6 @@ tape_normal_get_pilot_common_loop_inner:
|
||||
bne tape_normal_get_pilot_common_loop_outer
|
||||
|
||||
clc
|
||||
!:
|
||||
@2:
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (turbo) helper routine - synchronization handling
|
||||
//
|
||||
// .Y should contain start value (either $89 or $09)
|
||||
// Carry set = failed
|
||||
;
|
||||
; Tape (turbo) helper routine - synchronization handling
|
||||
;
|
||||
; .Y should contain start value (either $89 or $09)
|
||||
; Carry set = failed
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
tape_normal_sync:
|
||||
@@ -17,20 +17,20 @@ tape_normal_sync:
|
||||
lda #$06
|
||||
sta VIC_EXTCOL
|
||||
|
||||
// Injest bytes of decreasing values
|
||||
; Injest bytes of decreasing values
|
||||
|
||||
jsr tape_normal_get_marker_while_sync
|
||||
bcs tape_normal_sync_fail // branch if end of data marker
|
||||
bcs tape_normal_sync_fail ; branch if end of data marker
|
||||
|
||||
jsr tape_normal_get_byte
|
||||
bcs tape_normal_sync_fail
|
||||
|
||||
cpy INBIT // INBIT contains same value as .A
|
||||
cpy INBIT ; INBIT contains same value as .A
|
||||
bne tape_normal_sync_fail
|
||||
|
||||
dey
|
||||
and #%01111110
|
||||
bne tape_normal_sync // branch if not $80 and not $00
|
||||
bne tape_normal_sync ; branch if not $80 and not $00
|
||||
|
||||
clc
|
||||
rts
|
||||
@@ -40,6 +40,4 @@ tape_normal_sync_fail:
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) helper routine - checksum calculation
|
||||
//
|
||||
;
|
||||
; Tape (normal) helper routine - checksum calculation
|
||||
;
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
!ifdef CONFIG_TAPE_NORMAL {
|
||||
|
||||
|
||||
tape_normal_update_checksum:
|
||||
@@ -17,6 +17,4 @@ tape_normal_update_checksum:
|
||||
sta RIPRTY
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,57 +1,57 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (turbo) helper routine - storing byte uder I/O
|
||||
//
|
||||
// Has to preserve .A and .Y
|
||||
//
|
||||
;
|
||||
; Tape (turbo) helper routine - storing byte uder I/O
|
||||
;
|
||||
; Has to preserve .A and .Y
|
||||
;
|
||||
|
||||
// This helper routine is meant to be copied to the start of CPU stack.
|
||||
// Original ROM tape loading routines uses this area to store information
|
||||
// about bytes that did not read properly for the first time
|
||||
// (see Mapping the C64, page 47); this mechanism is useless for turbo tape,
|
||||
// but it means we can safely use this area for our purposes
|
||||
; This helper routine is meant to be copied to the start of CPU stack.
|
||||
; Original ROM tape loading routines uses this area to store information
|
||||
; about bytes that did not read properly for the first time
|
||||
; (see Mapping the C64, page 47); this mechanism is useless for turbo tape,
|
||||
; but it means we can safely use this area for our purposes
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
!ifdef CONFIG_TAPE_TURBO {
|
||||
|
||||
|
||||
#if ROM_LAYOUT_M65
|
||||
.label __tape_turbo_bytestore_defmap = __tape_turbo_bytestore + 10
|
||||
#else
|
||||
.label __tape_turbo_bytestore_defmap = __tape_turbo_bytestore + 7
|
||||
#endif
|
||||
.label __tape_turbo_bytestore_size = __tape_turbo_bytestore_source_end - tape_turbo_bytestore_source
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
!addr __tape_turbo_bytestore_defmap = __tape_turbo_bytestore + 10
|
||||
} else {
|
||||
!addr __tape_turbo_bytestore_defmap = __tape_turbo_bytestore + 7
|
||||
}
|
||||
!addr __tape_turbo_bytestore_size = __tape_turbo_bytestore_source_end - tape_turbo_bytestore_source
|
||||
|
||||
|
||||
tape_turbo_bytestore_source:
|
||||
|
||||
#if ROM_LAYOUT_M65
|
||||
jsr KERNAL_0.map_NORMAL
|
||||
#endif
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
jsr map_NORMAL
|
||||
}
|
||||
|
||||
// Set all memory as RAM, tape motor ON
|
||||
; Set all memory as RAM, tape motor ON
|
||||
ldx #$00
|
||||
stx CPU_R6510
|
||||
|
||||
// Store byte in memory
|
||||
; Store byte in memory
|
||||
sta (MEMUSS), y
|
||||
|
||||
// Restore default memory layout
|
||||
ldx #$00 // value will be determined later, offset from start: 7 bytes
|
||||
; Restore default memory layout
|
||||
ldx #$00 ; value will be determined later, offset from start: 7 bytes
|
||||
stx CPU_R6510
|
||||
|
||||
#if ROM_LAYOUT_M65
|
||||
// Restore default map and quit
|
||||
jmp KERNAL_0.map_KERNAL_1
|
||||
#else
|
||||
// Go back
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
; Restore default map and quit
|
||||
jmp map_KERNAL_1
|
||||
} else {
|
||||
; Go back
|
||||
rts
|
||||
#endif
|
||||
}
|
||||
|
||||
__tape_turbo_bytestore_source_end:
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_TURBO
|
||||
} ; CONFIG_TAPE_TURBO
|
||||
@@ -1,53 +1,53 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (turbo) helper routine - bit reading
|
||||
//
|
||||
;
|
||||
; Tape (turbo) helper routine - bit reading
|
||||
;
|
||||
|
||||
// Based on routine by enthusi/Onslaught, found here:
|
||||
// - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
; Based on routine by enthusi/Onslaught, found here:
|
||||
; - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
!ifdef CONFIG_TAPE_TURBO {
|
||||
|
||||
|
||||
tape_turbo_get_bit:
|
||||
|
||||
jsr tape_common_get_pulse
|
||||
bcs !+
|
||||
bcs @1
|
||||
|
||||
clc
|
||||
ror
|
||||
sta __turbo_half_S // store half of the last measurement result for short pulse
|
||||
sta __turbo_half_S ; store half of the last measurement result for short pulse
|
||||
|
||||
lda #$01
|
||||
#if CONFIG_MB_MEGA_65
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
sta SID_SIGVOL + __SID_R1_OFFSET
|
||||
sta SID_SIGVOL + __SID_L1_OFFSET
|
||||
#else
|
||||
} else {
|
||||
sta SID_SIGVOL
|
||||
#endif
|
||||
}
|
||||
lda #$06
|
||||
sta VIC_EXTCOL
|
||||
sec
|
||||
rts
|
||||
!:
|
||||
@1:
|
||||
clc
|
||||
ror
|
||||
sta __turbo_half_L // store half of the last measurement result for long pulse
|
||||
sta __turbo_half_L ; store half of the last measurement result for long pulse
|
||||
|
||||
lda #$00
|
||||
#if CONFIG_MB_MEGA_65
|
||||
!ifdef CONFIG_MB_M65 {
|
||||
sta SID_SIGVOL + __SID_R1_OFFSET
|
||||
sta SID_SIGVOL + __SID_L1_OFFSET
|
||||
#else
|
||||
} else {
|
||||
sta SID_SIGVOL
|
||||
#endif
|
||||
}
|
||||
sta VIC_EXTCOL
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_TURBO
|
||||
} ; CONFIG_TAPE_TURBO
|
||||
@@ -1,53 +1,53 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (turbo) helper routine - byte reading
|
||||
//
|
||||
// Returns byte in .A
|
||||
//
|
||||
;
|
||||
; Tape (turbo) helper routine - byte reading
|
||||
;
|
||||
; Returns byte in .A
|
||||
;
|
||||
|
||||
// Based on routine by enthusi/Onslaught, found here:
|
||||
// - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
; Based on routine by enthusi/Onslaught, found here:
|
||||
; - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
!ifdef CONFIG_TAPE_TURBO {
|
||||
|
||||
|
||||
tape_turbo_get_byte:
|
||||
|
||||
phx_trash_a
|
||||
+phx_trash_a
|
||||
lda #$01
|
||||
sta INBIT // init the to-be-read byte with 1 (canary bit to mark loop end)
|
||||
!:
|
||||
sta INBIT ; init the to-be-read byte with 1 (canary bit to mark loop end)
|
||||
@1:
|
||||
jsr tape_turbo_get_bit
|
||||
rol INBIT
|
||||
bcc !- // is the initial 1 shifted into carry already?
|
||||
plx_trash_a
|
||||
bcc @1 ; is the initial 1 shifted into carry already?
|
||||
+plx_trash_a
|
||||
|
||||
// Compensate for tape speed variations
|
||||
; Compensate for tape speed variations
|
||||
|
||||
lda __turbo_half_S // half of the last value for bit '0'
|
||||
lda __turbo_half_S ; half of the last value for bit '0'
|
||||
clc
|
||||
adc __turbo_half_L // half of the last value for bit '1'
|
||||
adc __turbo_half_L ; half of the last value for bit '1'
|
||||
|
||||
sec
|
||||
sbc __pulse_threshold // now we have a diff between current threshold and calculated one
|
||||
beq tape_turbo_get_byte_done // branch if threshold correction not needed
|
||||
sbc __pulse_threshold ; now we have a diff between current threshold and calculated one
|
||||
beq tape_turbo_get_byte_done ; branch if threshold correction not needed
|
||||
|
||||
bpl !+
|
||||
bpl @2
|
||||
|
||||
lda __pulse_threshold
|
||||
cmp #($BF - 10)
|
||||
beq tape_turbo_get_byte_done // do not decrease threshold too far no matter what
|
||||
beq tape_turbo_get_byte_done ; do not decrease threshold too far no matter what
|
||||
|
||||
dec __pulse_threshold
|
||||
bne tape_turbo_get_byte_done // branch always
|
||||
!:
|
||||
bne tape_turbo_get_byte_done ; branch always
|
||||
@2:
|
||||
lda __pulse_threshold
|
||||
cmp #($BF + 10)
|
||||
beq tape_turbo_get_byte_done // do not increase threshold too far no matter what
|
||||
beq tape_turbo_get_byte_done ; do not increase threshold too far no matter what
|
||||
|
||||
inc __pulse_threshold
|
||||
|
||||
@@ -57,4 +57,4 @@ tape_turbo_get_byte_done:
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_TURBO
|
||||
} ; CONFIG_TAPE_TURBO
|
||||
@@ -1,77 +1,76 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (turbo) helper routine - synchronization handling
|
||||
//
|
||||
;
|
||||
; Tape (turbo) helper routine - synchronization handling
|
||||
;
|
||||
|
||||
// Based on routine by enthusi/Onslaught, found here:
|
||||
// - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
; Based on routine by enthusi/Onslaught, found here:
|
||||
; - https://codebase64.pokefinder.org/doku.php?id=base:turbotape_loader_source
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
!ifdef CONFIG_TAPE_TURBO {
|
||||
|
||||
|
||||
tape_turbo_sync_header:
|
||||
|
||||
// Initial pulse threshold
|
||||
lda #$BF // measured 128 bits '0' and 128 bits '1' under VICE, calculated average
|
||||
; Initial pulse threshold
|
||||
lda #$BF ; measured 128 bits '0' and 128 bits '1' under VICE, calculated average
|
||||
sta __pulse_threshold
|
||||
|
||||
// Synchronize with start of sync sequence
|
||||
; Synchronize with start of sync sequence
|
||||
jsr tape_turbo_sync_first
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
bcs tape_turbo_sync_done
|
||||
#endif
|
||||
}
|
||||
|
||||
// Perform synchronization, double loop, total $C0 * $04 iterations
|
||||
; Perform synchronization, double loop, total $C0 * $04 iterations
|
||||
ldx #$C0
|
||||
!:
|
||||
@1:
|
||||
ldy #$04
|
||||
!:
|
||||
@2:
|
||||
stx XSAV
|
||||
jsr tape_turbo_get_byte
|
||||
cmp #$02
|
||||
bne tape_turbo_sync_header // branch if failure
|
||||
bne tape_turbo_sync_header ; branch if failure
|
||||
|
||||
dey
|
||||
bne !-
|
||||
bne @2
|
||||
ldx XSAV
|
||||
dex
|
||||
bne !--
|
||||
bne @1
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_turbo_sync_payload:
|
||||
|
||||
jsr tape_turbo_sync_first
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
bcs tape_turbo_sync_done // this shopuld not happen
|
||||
#endif
|
||||
!:
|
||||
ldx #$09 // 9, 8, ...
|
||||
!:
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
bcs tape_turbo_sync_done ; this shopuld not happen
|
||||
}
|
||||
ldx #$09 ; 9, 8, ...
|
||||
@3:
|
||||
jsr tape_turbo_get_byte
|
||||
cmp #$02
|
||||
beq !-
|
||||
beq @3
|
||||
ldy #$00
|
||||
!:
|
||||
@4:
|
||||
cpx INBIT
|
||||
bne tape_turbo_sync_payload
|
||||
jsr tape_turbo_get_byte
|
||||
dex
|
||||
bne !-
|
||||
bne @4
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
clc
|
||||
#endif
|
||||
}
|
||||
|
||||
// FALLTROUGH
|
||||
; FALLTROUGH
|
||||
|
||||
tape_turbo_sync_done:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_TAPE_TURBO
|
||||
} ; CONFIG_TAPE_TURBO
|
||||
@@ -1,30 +1,30 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
;; #LAYOUT# STD * #TAKE
|
||||
;; #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
;; #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (turbo) helper routine - syynchronize to first byte with value $02
|
||||
//
|
||||
;
|
||||
; Tape (turbo) helper routine - syynchronize to first byte with value $02
|
||||
;
|
||||
|
||||
#if CONFIG_TAPE_TURBO
|
||||
!ifdef CONFIG_TAPE_TURBO {
|
||||
|
||||
|
||||
tape_turbo_sync_first:
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
!ifdef CONFIG_TAPE_AUTODETECT {
|
||||
|
||||
ldy #$00
|
||||
!:
|
||||
@1:
|
||||
jsr tape_turbo_get_bit
|
||||
rol INBIT
|
||||
lda INBIT
|
||||
|
||||
cmp #$FF
|
||||
bne !+
|
||||
bne @2
|
||||
iny
|
||||
bpl !-
|
||||
bmi tape_turbo_sync_first_fail // suspiciously many $FF bytes, probably not a turbo tape
|
||||
!:
|
||||
bpl @1
|
||||
bmi tape_turbo_sync_first_fail ; suspiciously many $FF bytes, probably not a turbo tape
|
||||
@2:
|
||||
cmp #$02
|
||||
bne tape_turbo_sync_first
|
||||
|
||||
@@ -36,7 +36,7 @@ tape_turbo_sync_first_fail:
|
||||
sec
|
||||
rts
|
||||
|
||||
#else // no CONFIG_TAPE_AUTODETECT
|
||||
} else { ; no CONFIG_TAPE_AUTODETECT
|
||||
|
||||
jsr tape_turbo_get_bit
|
||||
rol INBIT
|
||||
@@ -46,8 +46,7 @@ tape_turbo_sync_first_fail:
|
||||
bne tape_turbo_sync_first
|
||||
|
||||
rts
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
Reference in new issue
Block a user