|
@@ -0,0 +1,648 @@
|
|
|
+#include "memmap.i65"
|
|
|
+
|
|
|
+; SPC Player
|
|
|
+; SPC700 transfer and IO routines by Shay Green <gblargg@gmail.com>
|
|
|
+
|
|
|
+spcplayer:
|
|
|
+ php
|
|
|
+ sep #$30 : .as : .xs
|
|
|
+
|
|
|
+ ldx #$0a ; Check if SPC header is present
|
|
|
+-
|
|
|
+ lda @SPC_HEADER,x
|
|
|
+ cmp @text_spcid,x
|
|
|
+ beq +
|
|
|
+ jmp spc_exit
|
|
|
++
|
|
|
+ dey
|
|
|
+ bne -
|
|
|
+
|
|
|
+ rep #$10 : .xl ; Now draw lots of stuff
|
|
|
+
|
|
|
+ stz bar_wl
|
|
|
+ dec bar_wl
|
|
|
+ stz bar_xl
|
|
|
+ dec bar_xl
|
|
|
+ stz bar_yl
|
|
|
+ dec bar_yl
|
|
|
+ jsr backup_screen
|
|
|
+
|
|
|
+ lda #^text_spcplay ; Loading window
|
|
|
+ sta window_tbank
|
|
|
+ ldx #!text_spcplay
|
|
|
+ stx window_taddr
|
|
|
+ lda @spcplay_win_x
|
|
|
+ sta window_x
|
|
|
+ lda @spcplay_win_y
|
|
|
+ sta window_y
|
|
|
+ lda @spcplay_win_w
|
|
|
+ sta window_w
|
|
|
+ lda @spcplay_win_h
|
|
|
+ sta window_h
|
|
|
+ jsr draw_window
|
|
|
+
|
|
|
+ lda #^text_spcload ; Loading text
|
|
|
+ ldx #!text_spcload
|
|
|
+ sta print_bank
|
|
|
+ stx print_src
|
|
|
+ stz print_pal
|
|
|
+ lda #29
|
|
|
+ sta print_count
|
|
|
+ lda #17
|
|
|
+ sta print_y
|
|
|
+ lda #17
|
|
|
+ sta print_x
|
|
|
+ jsr hiprint
|
|
|
+
|
|
|
+ stz isr_done
|
|
|
+-
|
|
|
+ lda isr_done ; Wait until text is being printed...
|
|
|
+ beq -
|
|
|
+
|
|
|
+ jsr spc700_load ; Load SPC into SPC700
|
|
|
+
|
|
|
+ lda #^text_spcplay
|
|
|
+ sta window_tbank
|
|
|
+ ldx #!text_spcplay
|
|
|
+ stx window_taddr
|
|
|
+ lda @spcstart_win_x
|
|
|
+ sta window_x
|
|
|
+ lda @spcstart_win_y
|
|
|
+ sta window_y
|
|
|
+ lda @spcstart_win_w
|
|
|
+ sta window_w
|
|
|
+ lda @spcstart_win_h
|
|
|
+ sta window_h
|
|
|
+ jsr draw_window
|
|
|
+
|
|
|
+ lda #^text_spcstarta
|
|
|
+ ldx #!text_spcstarta
|
|
|
+ sta print_bank
|
|
|
+ stx print_src
|
|
|
+ lda #$01
|
|
|
+ sta print_pal
|
|
|
+ lda #30
|
|
|
+ sta print_count
|
|
|
+ lda #15
|
|
|
+ sta print_y
|
|
|
+ lda #17
|
|
|
+ sta print_x
|
|
|
+ jsr hiprint
|
|
|
+
|
|
|
+ lda #^text_spcstartb
|
|
|
+ ldx #!text_spcstartb
|
|
|
+ sta print_bank
|
|
|
+ stx print_src
|
|
|
+ lda #$01
|
|
|
+ sta print_pal
|
|
|
+ lda #07
|
|
|
+ sta print_count
|
|
|
+ lda #17
|
|
|
+ sta print_y
|
|
|
+ lda #12
|
|
|
+ sta print_x
|
|
|
+ jsr hiprint
|
|
|
+
|
|
|
+ lda #$de
|
|
|
+ ldx #$004e
|
|
|
+ sta print_bank
|
|
|
+ stx print_src
|
|
|
+ stz print_pal
|
|
|
+ lda #32
|
|
|
+ sta print_count
|
|
|
+ lda #17
|
|
|
+ sta print_y
|
|
|
+ lda #20
|
|
|
+ sta print_x
|
|
|
+ jsr hiprint
|
|
|
+
|
|
|
+ lda #^text_spcstartc
|
|
|
+ ldx #!text_spcstartc
|
|
|
+ sta print_bank
|
|
|
+ stx print_src
|
|
|
+ lda #$01
|
|
|
+ sta print_pal
|
|
|
+ lda #07
|
|
|
+ sta print_count
|
|
|
+ lda #18
|
|
|
+ sta print_y
|
|
|
+ lda #12
|
|
|
+ sta print_x
|
|
|
+ jsr hiprint
|
|
|
+
|
|
|
+ lda #$de
|
|
|
+ ldx #$002e
|
|
|
+ sta print_bank
|
|
|
+ stx print_src
|
|
|
+ stz print_pal
|
|
|
+ lda #32
|
|
|
+ sta print_count
|
|
|
+ lda #18
|
|
|
+ sta print_y
|
|
|
+ lda #20
|
|
|
+ sta print_x
|
|
|
+ jsr hiprint
|
|
|
+
|
|
|
+ lda #^text_spcstartd
|
|
|
+ ldx #!text_spcstartd
|
|
|
+ sta print_bank
|
|
|
+ stx print_src
|
|
|
+ lda #$01
|
|
|
+ sta print_pal
|
|
|
+ lda #07
|
|
|
+ sta print_count
|
|
|
+ lda #19
|
|
|
+ sta print_y
|
|
|
+ lda #12
|
|
|
+ sta print_x
|
|
|
+ jsr hiprint
|
|
|
+
|
|
|
+ lda #$de
|
|
|
+ ldx #$00b1
|
|
|
+ sta print_bank
|
|
|
+ stx print_src
|
|
|
+ stz print_pal
|
|
|
+ lda #32
|
|
|
+ sta print_count
|
|
|
+ lda #19
|
|
|
+ sta print_y
|
|
|
+ lda #20
|
|
|
+ sta print_x
|
|
|
+ jsr hiprint
|
|
|
+
|
|
|
+spc_playloop:
|
|
|
+ lda isr_done ; SPC player loop
|
|
|
+ lsr
|
|
|
+ bcc spc_playloop
|
|
|
+ jsr printtime
|
|
|
+ stz isr_done
|
|
|
+
|
|
|
+ jsr read_pad
|
|
|
+ lda #$80
|
|
|
+ and pad1trig+1
|
|
|
+ bne spc_key_b
|
|
|
+ bra spc_playloop
|
|
|
+
|
|
|
+spc_key_b:
|
|
|
+ rep #$20 : .al
|
|
|
+ tsc
|
|
|
+ sta saved_sp ; Save SP for later re-entry
|
|
|
+ lda #$fa50 ; Write reset signature
|
|
|
+ sta @warm_signature
|
|
|
+ sep #$20 : .as
|
|
|
+
|
|
|
+ sei ; Blank screen & issue CMD_RESET command to Microcontroller...
|
|
|
+ stz $2100 ; ...this is required, because there is no other way to stop S-SMP & S-DSP
|
|
|
+ lda #CMD_RESET
|
|
|
+ sta @AVR_CMD
|
|
|
+-
|
|
|
+ bra - ; At this point, the SNES waits for an external reset from the Microcontroller
|
|
|
+
|
|
|
+spc_exit: ; Return from player in case of wrong SPC file data
|
|
|
+ plp
|
|
|
+ rts
|
|
|
+
|
|
|
+;---------------------------------------
|
|
|
+spc700_load:
|
|
|
+ php
|
|
|
+ sep #$20 : .as
|
|
|
+ rep #$10 : .xl
|
|
|
+
|
|
|
+ sei ; Disable NMI & IRQ
|
|
|
+ stz $4200 ; The SPC player code is really timing sensitive ;)
|
|
|
+ jsr upload_dsp_regs ; Upload S-DSP registers
|
|
|
+ jsr upload_high_ram ; Upload 63.5K of SPC700 ram
|
|
|
+ jsr upload_low_ram ; Upload rest of ram
|
|
|
+ jsr restore_final ; Restore SPC700 state & start execution
|
|
|
+
|
|
|
+ lda #$81 ; VBlank NMI + Auto Joypad Read
|
|
|
+ sta $4200 ; enable V-BLANK NMI
|
|
|
+ cli
|
|
|
+ plp
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+; Uploads DSP registers and some other setup code
|
|
|
+upload_dsp_regs:
|
|
|
+
|
|
|
+; ---- Begin upload
|
|
|
+
|
|
|
+ ldy #$0002
|
|
|
+ jsr spc_begin_upload
|
|
|
+
|
|
|
+; ---- Upload loader
|
|
|
+
|
|
|
+ ldx #$0000
|
|
|
+-
|
|
|
+ lda @loader,x
|
|
|
+ jsr spc_upload_byte
|
|
|
+ inx
|
|
|
+ cpy #31 ; size of loader
|
|
|
+ bne -
|
|
|
+
|
|
|
+; ---- Upload SP, PC & PSW
|
|
|
+
|
|
|
+ lda @SPC_HEADER+43
|
|
|
+ jsr spc_upload_byte
|
|
|
+ lda @SPC_HEADER+38
|
|
|
+ jsr spc_upload_byte
|
|
|
+ lda @SPC_HEADER+37
|
|
|
+ jsr spc_upload_byte
|
|
|
+ lda @SPC_HEADER+42
|
|
|
+ jsr spc_upload_byte
|
|
|
+
|
|
|
+; ---- Upload DSP registers
|
|
|
+
|
|
|
+ ldx #$0000
|
|
|
+-
|
|
|
+ lda @SPC_DSP_REGS,x
|
|
|
+ jsr spc_upload_byte
|
|
|
+ inx
|
|
|
+ cpx #128
|
|
|
+ bne -
|
|
|
+
|
|
|
+; --- Upload fixed values for $F1-$F3
|
|
|
+
|
|
|
+ ldy #$00F1
|
|
|
+ jsr spc_next_upload
|
|
|
+
|
|
|
+ lda #$80 ; stop timers
|
|
|
+ jsr spc_upload_byte
|
|
|
+ lda #$6c ; get dspaddr set for later
|
|
|
+ jsr spc_upload_byte
|
|
|
+ lda #$60
|
|
|
+ jsr spc_upload_byte
|
|
|
+
|
|
|
+; ---- Upload $f8-$1ff
|
|
|
+
|
|
|
+ ldy #$00F8
|
|
|
+ jsr spc_next_upload
|
|
|
+
|
|
|
+ ldx #$00F8
|
|
|
+-
|
|
|
+ lda @SPC_DATA,x
|
|
|
+ jsr spc_upload_byte
|
|
|
+ inx
|
|
|
+ cpx #$200
|
|
|
+ bne -
|
|
|
+
|
|
|
+; ---- Execute loader
|
|
|
+
|
|
|
+ ldy #$0002
|
|
|
+ jsr spc_execute
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+upload_high_ram:
|
|
|
+
|
|
|
+ ldy #$0002
|
|
|
+ jsr spc_begin_upload
|
|
|
+
|
|
|
+; ---- Upload transfer routine
|
|
|
+
|
|
|
+ ldx #$0000
|
|
|
+-
|
|
|
+ lda @transfer,x
|
|
|
+ jsr spc_upload_byte
|
|
|
+ inx
|
|
|
+ cpy #43 ; size of transfer routine
|
|
|
+ bne -
|
|
|
+
|
|
|
+ ldx #$023f ; prepare transfer address
|
|
|
+
|
|
|
+; ---- Execute transfer routine
|
|
|
+
|
|
|
+ ldy #$0002
|
|
|
+ sty APUIO2
|
|
|
+ stz APUIO1
|
|
|
+ lda APUIO0
|
|
|
+ inc
|
|
|
+ inc
|
|
|
+ sta APUIO0
|
|
|
+; Wait for acknowledgement
|
|
|
+-
|
|
|
+ cmp APUIO0
|
|
|
+ bne -
|
|
|
+
|
|
|
+; ---- Burst transfer of 63.5K using custom routine
|
|
|
+
|
|
|
+outer_transfer_loop:
|
|
|
+ ldy #$003f ; 3
|
|
|
+inner_transfer_loop:
|
|
|
+ lda @SPC_DATA,x ; 5 |
|
|
|
+ sta APUIO0 ; 4 |
|
|
|
+ lda @SPC_DATA+$40,x ; 5 |
|
|
|
+ sta APUIO1 ; 4 |
|
|
|
+ lda @SPC_DATA+$80,x ; 5 |
|
|
|
+ sta APUIO2 ; 4 |
|
|
|
+ lda @SPC_DATA+$C0,x ; 5 |
|
|
|
+ sta APUIO3 ; 4 |
|
|
|
+ tya ; 2 >> 38 cycles
|
|
|
+-
|
|
|
+ cmp APUIO3 ; 4 |
|
|
|
+ bne - ; 3 |
|
|
|
+ dex ; 2 |
|
|
|
+ dey ; 2 |
|
|
|
+ bpl inner_transfer_loop ; 3 >> 14 cycles
|
|
|
+
|
|
|
+ rep #$21 : .al ; 3 |
|
|
|
+ txa ; 2 |
|
|
|
+ adc #$140 ; 3 |
|
|
|
+ tax ; 2 |
|
|
|
+ sep #$20 : .as ; 3 |
|
|
|
+ cpx #$003f ; 3 |
|
|
|
+ bne outer_transfer_loop ; 3 >> 19 cycles
|
|
|
+
|
|
|
+ rts
|
|
|
+
|
|
|
+;---------------------------------------
|
|
|
+upload_low_ram:
|
|
|
+
|
|
|
+; ---- Upload $0002-$00EF
|
|
|
+
|
|
|
+ ldy #$0002
|
|
|
+ jsr spc_begin_upload
|
|
|
+
|
|
|
+ ldx #$0002
|
|
|
+-
|
|
|
+ lda @SPC_DATA,x
|
|
|
+ jsr spc_upload_byte
|
|
|
+ inx
|
|
|
+ cpx #$00F0
|
|
|
+ bne -
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+; Executes final restoration code
|
|
|
+restore_final:
|
|
|
+ jsr start_exec_io
|
|
|
+ stz $420d ; SPC700 I/O code requires SLOW timing
|
|
|
+
|
|
|
+; ---- Restore first two bytes of RAM
|
|
|
+
|
|
|
+ lda @SPC_DATA
|
|
|
+ xba
|
|
|
+ lda #$e8 ; MOV A,#@SPC_DATA
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+ ldx #$00C4 ; MOV $00,A
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+ lda @SPC_DATA+1
|
|
|
+ xba
|
|
|
+ lda #$e8 ; MOV A,#@SPC_DATA+1
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+ ldx #$01C4 ; MOV $01,A
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+; ---- Restore SP
|
|
|
+
|
|
|
+ lda @SPC_HEADER+43
|
|
|
+ sec
|
|
|
+ sbc #3
|
|
|
+ xba
|
|
|
+ lda #$cd ; MOV X,#@SPC_HEADER+43
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+ ldx #$bd ; MOV SP,X
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+; ---- Restore X
|
|
|
+
|
|
|
+ lda @SPC_HEADER+40
|
|
|
+ xba
|
|
|
+ lda #$cd ; MOV X,#@SPC_HEADER+40
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+; ---- Restore Y
|
|
|
+
|
|
|
+ lda @SPC_HEADER+41
|
|
|
+ xba
|
|
|
+ lda #$8d ; MOV Y,#@SPC_HEADER+41
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+; ---- Restore DSP FLG register
|
|
|
+
|
|
|
+ lda @SPC_DSP_REGS+$6c
|
|
|
+ xba
|
|
|
+ lda #$e8 ; MOV A,#@SPC_DSP_REGS+$6c
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+ ldx #$f3C4 ; MOV $f3,A -> $f2 has been set-up before by SPC700 loader
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+; ---- Restore DSP KON register
|
|
|
+
|
|
|
+ lda #$4C
|
|
|
+ xba
|
|
|
+ lda #$e8 ; MOV A,#$4c
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+ ldx #$f2C4 ; MOV $f2,A
|
|
|
+ jsr exec_instr
|
|
|
+ lda @SPC_DSP_REGS+$4C
|
|
|
+ xba
|
|
|
+ lda #$e8 ; MOV A,#@SPC_DSP_REGS+$4c
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+ ldx #$f3C4 ; MOV $f3,A
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+; ---- Restore DSP register address
|
|
|
+
|
|
|
+ lda @SPC_DATA+$F2
|
|
|
+ xba
|
|
|
+ lda #$e8 ; MOV A,#@SPC_DATA+$F2
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+ ldx #$f2C4 ; MOV dest,A
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+; ---- Restore CONTROL register
|
|
|
+
|
|
|
+ lda @SPC_DATA+$F1
|
|
|
+ and #$CF ; don't clear input ports
|
|
|
+ xba
|
|
|
+ lda #$e8 ; MOV A,#@SPC_DATA+$F1
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+ ldx #$f1C4 ; MOV $F1,A
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+;---- Restore A
|
|
|
+
|
|
|
+ lda @SPC_HEADER+39
|
|
|
+ xba
|
|
|
+ lda #$e8 ; MOV A,#@SPC_HEADER+39
|
|
|
+ tax
|
|
|
+ jsr exec_instr
|
|
|
+
|
|
|
+;---- Restore PSW and PC
|
|
|
+
|
|
|
+ ldx #$7F00 ; NOP; RTI
|
|
|
+ stx APUIO0
|
|
|
+ lda #$FC ; Patch loop to execute instruction just written
|
|
|
+ sta APUIO3
|
|
|
+
|
|
|
+;---- restore IO ports $f4 - $f7
|
|
|
+
|
|
|
+ rep #$20 : .al
|
|
|
+ lda @SPC_DATA+$F4
|
|
|
+ tax
|
|
|
+ lda @SPC_DATA+$F6
|
|
|
+ sta APUIO2
|
|
|
+ stx APUIO0 ; last to avoid overwriting RETI before run
|
|
|
+ sep #$20 : .as
|
|
|
+
|
|
|
+ lda #$01
|
|
|
+ sta $420d ; restore FAST CPU operation
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+spc_begin_upload:
|
|
|
+
|
|
|
+ sty APUIO2 ; Set address
|
|
|
+
|
|
|
+ ldy #$BBAA ; Wait for SPC
|
|
|
+-
|
|
|
+ cpy APUIO0
|
|
|
+ bne -
|
|
|
+
|
|
|
+ lda #$CC ; Send acknowledgement
|
|
|
+ sta APUIO1
|
|
|
+ sta APUIO0
|
|
|
+
|
|
|
+- ; Wait for acknowledgement
|
|
|
+ cmp APUIO0
|
|
|
+ bne -
|
|
|
+
|
|
|
+ ldy #0 ; Initialize index
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+spc_upload_byte:
|
|
|
+ sta APUIO1
|
|
|
+
|
|
|
+ tya ; Signal it's ready
|
|
|
+ sta APUIO0
|
|
|
+- ; Wait for acknowledgement
|
|
|
+ cmp APUIO0
|
|
|
+ bne -
|
|
|
+
|
|
|
+ iny
|
|
|
+
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+spc_next_upload:
|
|
|
+ sty APUIO2
|
|
|
+
|
|
|
+; Send command
|
|
|
+; Special case operation has been fully tested.
|
|
|
+ lda APUIO0
|
|
|
+ inc
|
|
|
+ inc
|
|
|
+ bne +
|
|
|
+ inc
|
|
|
++
|
|
|
+ sta APUIO1
|
|
|
+ sta APUIO0
|
|
|
+
|
|
|
+; Wait for acknowledgement
|
|
|
+-
|
|
|
+ cmp APUIO0
|
|
|
+ bne -
|
|
|
+
|
|
|
+ ldy #0
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+spc_execute:
|
|
|
+ sty APUIO2
|
|
|
+
|
|
|
+ stz APUIO1
|
|
|
+
|
|
|
+ lda APUIO0
|
|
|
+ inc
|
|
|
+ inc
|
|
|
+ sta APUIO0
|
|
|
+
|
|
|
+; Wait for acknowledgement
|
|
|
+-
|
|
|
+ cmp APUIO0
|
|
|
+ bne -
|
|
|
+
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+start_exec_io:
|
|
|
+; Set execution address
|
|
|
+ ldx #$00F5
|
|
|
+ stx APUIO2
|
|
|
+
|
|
|
+ stz APUIO1 ; NOP
|
|
|
+ ldx #$FE2F ; BRA *-2
|
|
|
+
|
|
|
+; Signal to SPC that we're ready
|
|
|
+ lda APUIO0
|
|
|
+ inc
|
|
|
+ inc
|
|
|
+ sta APUIO0
|
|
|
+
|
|
|
+; Wait for acknowledgement
|
|
|
+-
|
|
|
+ cmp APUIO0
|
|
|
+ bne -
|
|
|
+
|
|
|
+; Quickly write branch
|
|
|
+ stx APUIO2
|
|
|
+
|
|
|
+ rts
|
|
|
+;---------------------------------------
|
|
|
+exec_instr:
|
|
|
+; Replace instruction
|
|
|
+ stx APUIO0
|
|
|
+ lda #$FC
|
|
|
+ sta APUIO3 ; 30
|
|
|
+
|
|
|
+ ; SPC BRA loop takes 4 cycles, so it reads
|
|
|
+ ; the branch offset every 4 SPC cycles (84 master).
|
|
|
+ ; We must handle the case where it read just before
|
|
|
+ ; the write above, and when it reads just after it.
|
|
|
+ ; If it reads just after, we have at least 7 SPC
|
|
|
+ ; cycles (147 master) to change restore the branch
|
|
|
+ ; offset.
|
|
|
+
|
|
|
+ ; 48 minimum, 90 maximum
|
|
|
+ ora #0
|
|
|
+ ora #0
|
|
|
+ ora #0
|
|
|
+ nop
|
|
|
+ nop
|
|
|
+ nop
|
|
|
+
|
|
|
+ ; 66 delay, about the middle of the above limits
|
|
|
+ phd ;4
|
|
|
+ pld ;5
|
|
|
+
|
|
|
+ ; Give plenty of extra time if single execution
|
|
|
+ ; isn't needed, as this avoids such tight timing
|
|
|
+ ; requirements.
|
|
|
+
|
|
|
+; phd ;4
|
|
|
+; pld ;5
|
|
|
+; phd ;4
|
|
|
+; pld ;5
|
|
|
+
|
|
|
+ ; Patch loop to skip first two bytes
|
|
|
+ lda #$FE ; 16
|
|
|
+ sta APUIO3 ; 30
|
|
|
+
|
|
|
+ ; 38 minimum (assuming 66 delay above)
|
|
|
+ phd ; 4
|
|
|
+ pld ; 5
|
|
|
+
|
|
|
+ ; Give plenty of extra time if single execution
|
|
|
+ ; isn't needed, as this avoids such tight timing
|
|
|
+ ; requirements.
|
|
|
+
|
|
|
+ phd
|
|
|
+ pld
|
|
|
+ phd
|
|
|
+ pld
|
|
|
+ rts
|