;; This example shows the normal position of the cpc's 300Hz interrupt. ;; (i.e. the interrupt hasn't been delay) ;; ;; We use a fast ticker so we can show the most accurate position. ;; ;; ;; In Winape: ;; Reset cpc ;; Open assembler ;; New file ;; Copy and paste this code into the window ;; Assemble ;; In CPC window type: ;; CALL &8000 ;; firmware functions we use in this example .kl_new_fast_ticker equ &bce0 .mc_wait_flyback equ &bd19 .kl_del_fast_ticker equ &bce6 .km_test_key equ &bb1e .mc_set_inks equ &bd25 .scr_set_mode equ &bc0e .txt_output equ &bb5a .txt_set_cursor equ &bb75 org &8000 .start ld a,1 call scr_set_mode ;; prevent firmware setting colours ;; and stop flicker at the top of screen which is caused by this ld a,&c9 ld (mc_set_inks),a ld hl,message call print_msg call set_vsync_pos ;; synchronise our ticker interrupt with the vsync call mc_wait_flyback halt halt call mc_wait_flyback ld a,6 ld (ticker_counter),a ld hl,colours ld (current_colour_pointer),hl ;; install interrupt ld hl,ticker_event_block ld b,%11000001 ;; near address, express asynchronous event ld c,&80 ;; rom select ld de,ticker_function call kl_new_fast_ticker mainloop: call mc_wait_flyback call check_keys jr c,quit_to_basic halt halt jp mainloop ;; check if a key has been pressed and perform action if it has check_keys: ld a,0 ;; cursor up call km_test_key jp nz,move_up ld a,2 ;; cursor down call km_test_key jp nz,move_down ld a,47 ;; space left call km_test_key ret z scf ret print_msg: ld a,(hl) inc hl or a ret z call txt_output jr print_msg move_up: ld a,(vsync_pos) inc a ld (vsync_pos),a call set_vsync_pos or a ret move_down ld a,(vsync_pos) dec a ld (vsync_pos),a call set_vsync_pos or a ret .set_vsync_pos ld h,1 ld l,12 call txt_set_cursor ld a,'&' call txt_output ld a,(vsync_pos) call print_hex ld bc,&bc07 out (c),c ld a,(vsync_pos) inc b out (c),a ret .vsync_pos defb 30 .quit_to_basic ld hl,ticker_event_block call kl_del_fast_ticker ret ;; this is initialised by ;; the firmware; holds runtime state of ticker interrupt .ticker_event_block defs 10 ;; this is the function called each 1/300th of a second .ticker_function push af push hl ;;push bc ;; The 1/300th of a second interrupt effectively splits ;; the screen into 6 sections of equal height. Each section ;; spans the entire width of the screen. ;; ;; We want to ensure that the effect is stationary so we reset ;; every 6 calls of this function. We need to ensure we are synced with vsync in ;; order that this works correctly. ld a,(ticker_counter) dec a ld (ticker_counter),a or a jr nz,ticker_function2 ld a,6 ld (ticker_counter),a ld hl,colours ld (current_colour_pointer),hl .ticker_function2 ;; get pointer to current mode ld hl,(current_colour_pointer) ;; get the mode ;; Select border ld bc,&7f10 ;; out (c),c ;; ;; Set colour for border ld a,(hl) ;; read colour from table out (c),a ;; set colour ;; update pointer inc hl ;; store pointer ld (current_colour_pointer),hl ;; ensure express asynchronous event is retriggered correctly ;; see SOFT968 LD HL,ticker_event_block+2 LD (HL),#00 ;;pop bc pop hl pop af ret print_hex: push af rrca rrca rrca call print_hex_digit pop af .print_hex_digit and &f cp 10 jr nc,print_hex_digit2 add a,'0' jp txt_output print_hex_digit2: add a,'A'-10 jp txt_output message: defb "The height of each colour bar show the",10,13 defb "time between each interrupt.",10,13,10,13 defb "The point where each colour changes is ",10,13 defb "the position of the interrupt.",10,13,10,13 defb "Use up/down cursor key to change the ",10,13 defb "position of the vertical sync." defb 10,13,10,13 defb "Vsync Position (CRTC Register 7):",10,13,0 .ticker_counter defb 0 .current_colour_pointer defw colours ;; colours for each split .colours defb &43 ;; pastel yellow defb &40 ;; white defb &54 ;; black defb &4b ;; bright white defb &45 ;; purple defb &51 ;; yellow