;; This example will show how you can distort the screen horizontally ;; using register 2 of the CRTC (Horizontal Sync Position). ;; ;; This example re-programs the Horizontal Sync Position on every scan-line ;; for a part of the display. ;;--------------------------------------------- ;; NOTE: code position is not important. org &8000 nolist .set_scr_mode equ &bc0e .scr_initialise equ &bbff .txt_output equ &bb5a .scr_set_border equ &bc38 .mc_wait_flyback equ &bd19 ;;---------------------------------------------- ;; setup a screen display so the effect is obvious ;; reset colours to their default values call set_scr_mode ;; set screen mode ld a,1 call scr_set_mode ;; set border to black ld bc,0 call scr_set_border ;; wait for colours to be set by firmware call mc_wait_flyback call mc_wait_flyback ;; display the character set on the screen ld a,'A' ;; initial character to display ld bc,40*24 ;; number of characters to write .dcs1 push af call txt_output ;; write character to screen and update ;; text coordinates pop af inc a ;; increment character value cp 'Z'+1 ;; end of character range? jr nz,dcs2 ld a,'A' ;; reset to start of range .dcs2 dec bc ;; update character counter ld a,b or c jr nz,dcs1 ;; loop to display more characters ;; from here we can't use the firmware functions because this will effect ;; timing. Now we must use direct hardware access. ;;--------------------------------------------- ;; initialisation ;; setup interrupt handler ;; ;; The interrupts are used to synchronise with the CRTC and the display. ;; This simple interrupt handler will always execute in the same time. ;; di ;; disable interrupts ld hl,&c9fb ;; install interrupt handler (EI:RET) ld (&0038),hl ;; (&0038 is IM1 interrupt vector) ei ;; enable interrupts ;; setup initial Horizontal Sync Position. ;; ;; This will define the Horizontal Sync Position for the first ;; frame of this example. The Horizontal Sync Position for subsequent ;; frames is defined within the program loop itself. ld bc,&bc02 out (c),c ld bc,&bd00+46 out (c),c ;;--------------------------------------------- ;; program loop .main_loop ;; wait for start of vsync. This test assumes the vsync ;; is not already active. ld b,&f5 .ml1 in a,(c) rra jr nc,ml1 ;; wait for a position within visible part of display halt halt halt ;; these define a delay which is used to synchronise the program with ;; the CRTC and the display. defs 64-46 defs 64-3-4-3-2-1 ;; ;; select CRTC register 2 (Horizontal Sync Position) ;; ;; all register writes to the CRTC will not effect this ;; register. ld bc,&bc02 out (c),c inc b ;; B = &BD (I/O address for CRTC register write) ld hl,table ;; start of table of horizontal sync values ld e,end_table-table ;; number of horizontal sync values .l1 ld a,(hl) ;; get byte from table (horizontal sync position) out (c),a ;; write to CRTC inc hl ;; increment position in table defs 64-2-4-2-1-3 ;; This defines a delay so that the ;; next CRTC register write occurs ;; at the same horizontal position on the next ;; scan-line dec e ;; decrement loop counter jp nz,l1 ;; loop if there are more bytes to write ;; restore horizontal sync position ;; to default value (default is value assigned by firmware) ld bc,&bc02 out (c),c ld bc,&bd00+46 out (c),c jp main_loop ;; the table of horizontal sync positions .table defb 46 defb 47 defb 48 defb 49 defb 50 defb 51 defb 52 defb 53 defb 54 defb 55 defb 56 defb 55 defb 54 defb 53 defb 52 defb 51 defb 50 defb 49 defb 48 defb 47 defb 46 .end_table ;; end of example