;; 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,2 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 call set_hsync_pos call set_vdisp call set_hdisp call calc_ram_size ;; 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 jp 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,do_up ld a,2 ;; cursor down call km_test_key jp nz,do_down ld a,8 ;; cursor left call km_test_key jp nz,do_left ld a,1 ;; cursor right call km_test_key jp nz,do_right ld a,47 ;; space 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 do_up: bit 7,c jr nz,make_shorter ld a,(vsync_pos) inc a ld (vsync_pos),a call set_vsync_pos or a ret make_shorter: ld a,(vdisp) dec a ld (vdisp),a call set_vdisp or a ret make_taller: ld a,(vdisp) inc a ld (vdisp),a call set_vdisp or a ret .do_down bit 7,c jr nz,make_taller ld a,(vsync_pos) dec a ld (vsync_pos),a call set_vsync_pos or a ret .do_left bit 7,c jr nz,make_thinner ld a,(hsync_pos) inc a ld (hsync_pos),a call set_hsync_pos or a ret .make_thinner ld a,(hdisp) dec a ld (hdisp),a call set_hdisp or a ret .do_right bit 7,c jr nz,make_fatter ld a,(hsync_pos) dec a ld (hsync_pos),a call set_hsync_pos or a ret .make_fatter ld a,(hdisp) inc a ld (hdisp),a call set_hdisp or a ret .set_vsync_pos ld h,1 ld l,2 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 .set_hsync_pos ld h,1 ld l,4 call txt_set_cursor ld a,'&' call txt_output ld a,(hsync_pos) call print_hex ld bc,&bc02 out (c),c ld a,(hsync_pos) inc b out (c),a ret .set_vdisp ld h,1 ld l,6 call txt_set_cursor ld a,'&' call txt_output ld a,(vdisp) call print_hex ld bc,&bc06 out (c),c ld a,(vdisp) inc b out (c),a call calc_ram_size ret .set_hdisp ld h,1 ld l,8 call txt_set_cursor ld a,'&' call txt_output ld a,(hdisp) call print_hex ld bc,&bc01 out (c),c ld a,(hdisp) inc b out (c),a call calc_ram_size ret .vsync_pos defb 30 .hsync_pos defb 30 .vdisp defb 25 .hdisp defb 40 .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 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 calc_ram_size: ld h,1 ld l,13 call txt_set_cursor ld a,(hdisp) ld l,a ld h,0 ;; x2 to convert hdisp into bytes add hl,hl ld a,(vdisp) call mul16 ;; scanlines per char line add hl,hl add hl,hl add hl,hl push hl ld a,'&' call txt_output ld a,h call print_hex pop hl ld a,l call print_hex ret ;; HL = value (e.g. 1 ;; A = multiplier (not 0) mul16: ld e,l ld d,h mul16a: dec a ret z add hl,de jr mul16a message: defb 31,1,1,"Vsync Position (CRTC Register 7):" defb 31,1,3,"Hsync Position (CRTC Register 2):" defb 31,1,5,"Vertical Displayed (CRTC Register 6):" defb 31,1,7,"Horizontal Displayed (CRTC Register 1):" defb 31,1,12,"RAM used (approx):" defb 31,1,20,"up/down cursor key (no shift): Change vsync pos",10,13 defb "left/right cursor key (no shift): Change hsync pos",10,13 defb "up/down cursor key (shift): Change height",10,13 defb "left/right cursor key (shift): Change width",10,13 defb 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