335 lines
6.0 KiB
ArmAsm
335 lines
6.0 KiB
ArmAsm
;; #LAYOUT# STD * #TAKE
|
|
;; #LAYOUT# * KERNAL_0 #TAKE
|
|
;; #LAYOUT# * * #IGNORE
|
|
|
|
;
|
|
; JiffyDOS protocol support for IEC - optimized load loop
|
|
;
|
|
|
|
!ifdef CONFIG_IEC_JIFFYDOS { !ifndef CONFIG_MEMORY_MODEL_60K {
|
|
|
|
|
|
; Note: original JiffyDOS LOAD loop checks for RUN/STOP key every time a sector is read,
|
|
; see description at https://sites.google.com/site/h2obsession/CBM/C128/JiffySoft128
|
|
;
|
|
; For simplicity and some space savings, our routine does not check the RUN/STOP key at all;
|
|
; the protocol is fast enough (especially with modern flash mediums) that probably nobody
|
|
; will want to terminate the loading.
|
|
|
|
|
|
jiffydos_load:
|
|
|
|
|
|
!ifdef CONFIG_IEC_JD_TEST {
|
|
|
|
; XXX test implementation, not ready yet
|
|
|
|
; Switch to optimized LOAD protocol
|
|
jsr UNTLK
|
|
lda FA
|
|
jsr TALK
|
|
bcs jiffydos_load_error
|
|
lda #$61
|
|
jsr TKSA
|
|
|
|
; XXX flow below most likely takes too much time...
|
|
|
|
; Timing is critical, do not allow interrupts
|
|
sei
|
|
|
|
!ifdef CONFIG_IEC_JIFFYDOS_BLANK {
|
|
|
|
!ifdef CONFIG_MB_U64 {
|
|
|
|
; XXX implement for non-blank mode, use jiffydos_prepare_no_preserve_bits
|
|
|
|
; Check if turbo register is available
|
|
lda U64_TURBOCTL
|
|
cmp #$FF
|
|
beq @1
|
|
|
|
; Store turbo register content, disable badlines
|
|
sta TBTCNT
|
|
lda #$80
|
|
sta U64_TURBOCTL
|
|
bne @2
|
|
|
|
; Normal flow - no turbo register
|
|
}
|
|
|
|
@1:
|
|
; Preserve register with screen status (blank/visible)
|
|
lda VIC_SCROLY
|
|
sta TBTCNT
|
|
|
|
; Blank screen to make sure no sprite/badline will interrupt
|
|
jsr screen_off
|
|
@2:
|
|
; Preserve 3 lowest bits of CIA2_PRA
|
|
jsr jiffydos_preserve_bits
|
|
|
|
} else {
|
|
|
|
@1:
|
|
; Store previous sprite status in temporary variable
|
|
jsr jiffydos_prepare
|
|
sta TBTCNT
|
|
@2:
|
|
|
|
}
|
|
; A trick to shorten EAL update time
|
|
ldy #$FF
|
|
|
|
!ifdef CONFIG_MB_M65 {
|
|
; If in native mode, switch to 1 MHz
|
|
jsr m65_iec_fast
|
|
}
|
|
; FALLTROUGH
|
|
|
|
jiffydos_load_loop_esc:
|
|
|
|
; We are now in 'escape mode' - release DATA, wait till receiver releases CLK
|
|
jsr iec_release_clk_data
|
|
jsr iec_wait_for_clk_release
|
|
|
|
; Check DATA line
|
|
bmi jiffydos_load_check_status
|
|
|
|
+panic $01
|
|
|
|
; XXX finish the implementation
|
|
|
|
|
|
|
|
|
|
jiffydos_load_check_status:
|
|
|
|
; Check if a device pulls CLK within the next 1100us (at least 1125 cycles, to be sure for NTSC)
|
|
ldx #$67 ; 2 cycles
|
|
|
|
; FALLTROUGH
|
|
|
|
jiffydos_load_check_loop:
|
|
|
|
lda CIA2_PRA ; 4 cycles
|
|
bvc jiffydos_load_end ; 2 cycles if not taken
|
|
dex ; 2 cycles
|
|
bne jiffydos_load_check_loop ; 3 cycles if taken
|
|
|
|
; FALLTROUGH
|
|
|
|
jiffydos_load_error:
|
|
|
|
+panic $03
|
|
|
|
; XXX finish the implementation
|
|
|
|
|
|
jiffydos_load_end:
|
|
|
|
+panic $FF
|
|
|
|
; XXX finish the implementation
|
|
|
|
|
|
|
|
} else {
|
|
|
|
; XXX implement JiffyDOS optimized LOAD protocol, this one is ineffective
|
|
|
|
|
|
; Timing is critical, do not allow interrupts
|
|
sei
|
|
|
|
!ifdef CONFIG_IEC_JIFFYDOS_BLANK {
|
|
|
|
!ifdef CONFIG_MB_U64 {
|
|
|
|
; XXX implement for non-blank mode, use jiffydos_prepare_no_preserve_bits
|
|
|
|
; Check if turbo register is available
|
|
lda U64_TURBOCTL
|
|
cmp #$FF
|
|
beq @1
|
|
|
|
; Store turbo register content, disable badlines
|
|
sta TBTCNT
|
|
lda #$80
|
|
sta U64_TURBOCTL
|
|
bne @2
|
|
|
|
; Normal flow - no turbo register
|
|
}
|
|
|
|
@1:
|
|
; Preserve register with screen status (blank/visible)
|
|
lda VIC_SCROLY
|
|
sta TBTCNT
|
|
|
|
; Blank screen to make sure no sprite/badline will interrupt
|
|
jsr screen_off
|
|
@2:
|
|
; Preserve 3 lowest bits of CIA2_PRA
|
|
jsr jiffydos_preserve_bits
|
|
|
|
} else {
|
|
|
|
@1:
|
|
; Store previous sprite status in temporary variable
|
|
jsr jiffydos_prepare
|
|
sta TBTCNT
|
|
@2:
|
|
|
|
}
|
|
; A trick to shorten EAL update time
|
|
ldy #$FF
|
|
|
|
!ifdef CONFIG_MB_M65 {
|
|
; If in native mode, switch to 1 MHz
|
|
jsr m65_iec_slow
|
|
}
|
|
; FALLTROUGH
|
|
|
|
jiffydos_load_loop:
|
|
|
|
; Wait until device is ready to send (releases CLK)
|
|
jsr iec_wait_for_clk_release
|
|
|
|
; Prepare 'start sending' message
|
|
lda CIA2_PRA
|
|
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
|
|
|
|
!ifdef CONFIG_IEC_JIFFYDOS_BLANK {
|
|
|
|
; It seems JiffyDOS needs some time here; waste few cycles
|
|
+nop
|
|
jsr iec_wait_rts
|
|
|
|
; Ask device to start sending bits
|
|
sta CIA2_PRA
|
|
|
|
} else {
|
|
|
|
; Wait for appropriate moment, ask device to start sending bits
|
|
tax
|
|
jsr jiffydos_wait_line
|
|
stx CIA2_PRA ; cycles: 4
|
|
}
|
|
|
|
; Prepare 'data pull' byte, cycles: 3 + 2 + 2 = 7
|
|
lda C3PO
|
|
ora #BIT_CIA2_PRA_DAT_OUT ; pull
|
|
tax
|
|
|
|
; Delay, JiffyDOS needs some time, 4 cycles
|
|
+nop
|
|
+nop
|
|
|
|
; Get bits, cycles: 4 + 2 + 2 = 8
|
|
lda CIA2_PRA ; bits 0 and 1 on CLK/DATA
|
|
lsr
|
|
lsr
|
|
|
|
; Delay, JiffyDOS needs some time, 2 cycles
|
|
+nop
|
|
|
|
; Get bits, cycles: 4 + 2 + 2 = 8
|
|
ora CIA2_PRA ; bits 2 and 3 on CLK/DATA
|
|
lsr
|
|
lsr
|
|
|
|
; Get bits, cycles: 3 + 4 + 2 + 2 = 11
|
|
eor C3PO
|
|
eor CIA2_PRA ; bits 4 and 5 on CLK/DATA
|
|
lsr
|
|
lsr
|
|
|
|
; Get bits, cycles: 3 + 4 = 7
|
|
eor C3PO
|
|
eor CIA2_PRA ; bits 6 and 7 on CLK/DATA
|
|
|
|
; Store retrieved byte, cycles: 2 + 6 = 8
|
|
iny ; NTSC needs this delay
|
|
sta (EAL),y ; not compatible with CONFIG_MEMORY_MODEL_60K
|
|
|
|
; Retrieve status bits, cycles: 4
|
|
bit CIA2_PRA
|
|
|
|
; Pull DATA at the end, cycles: 4
|
|
stx CIA2_PRA
|
|
|
|
; If CLK line not active - this was the last byte
|
|
bvs jiffydos_load_end
|
|
|
|
; Handle EAL
|
|
cpy #$FF
|
|
bne jiffydos_load_loop
|
|
inc EAL+1
|
|
+bra jiffydos_load_loop
|
|
|
|
jiffydos_load_end:
|
|
|
|
!ifdef CONFIG_MB_M65 {
|
|
; If in native mode, switch back to fast mode
|
|
jsr m65_iec_fast
|
|
}
|
|
; Save last byte
|
|
tax
|
|
|
|
; Update EAL
|
|
sec
|
|
jsr iec_update_EAL_by_Y
|
|
|
|
; Indicate that no byte waits in output buffer
|
|
lda #$00
|
|
sta C3PO
|
|
|
|
; Restore proper IECPROTO value
|
|
lda #IEC_JIFFY
|
|
sta IECPROTO
|
|
|
|
!ifdef CONFIG_IEC_JIFFYDOS_BLANK {
|
|
|
|
!ifdef CONFIG_MB_U64 {
|
|
|
|
; Check if turbo register is available
|
|
lda U64_TURBOCTL
|
|
cmp #$FF
|
|
beq @3
|
|
|
|
; Restore turbo register content
|
|
lda TBTCNT
|
|
sta U64_TURBOCTL
|
|
jmp @4
|
|
|
|
; Normal flow - no turbo register
|
|
}
|
|
|
|
@3:
|
|
; Restore screen state
|
|
lda TBTCNT
|
|
sta VIC_SCROLY
|
|
@4:
|
|
|
|
} else {
|
|
|
|
@3:
|
|
; Re-enable sprites
|
|
lda TBTCNT
|
|
sta VIC_SPENA
|
|
@4:
|
|
}
|
|
|
|
; Store last byte as unoptimized LOAD routine would
|
|
stx TBTCNT
|
|
|
|
; No need to re-enable interrupts; other IEC routines
|
|
; called by LOAD will do this nevertheless
|
|
|
|
; End of load loop
|
|
jmp load_iec_loop_end
|
|
|
|
|
|
} } ; CONFIG_IEC_JIFFYDOS and not CONFIG_MEMORY_MODEL_60K
|
|
|
|
} |