;; This example shows how to use the hardware to ;; change the video mode. ;; ;; NOTE: This example can't be used with BASIC. org &8000 nolist start: ;; synchronise with start of vsync ld b,&f5 ;; this loop will pass if VSYNC is already active, or wait ;; until it's active i1: in a,(c) rra jr nc,i1 ;; this loop will pass when VSYNC has ended i2: in a,(c) rra jr c,i2 ;; because VSYNC is not active, this loop will then ;; wait for it to become active i3: in a,(c) rra jr nc,i3 di im 1 ;; Z80 interrupt mode 1 ;; install interrupt ld a,&c3 ;; JP instruction ld hl,interrupt ld (&0038),a ld (&0039),hl ei loop: jp loop interrupt: ;; store registers we want to change push bc push af push hl ;; vsync active? (int triggered 2 HSYNC after VSYNC starts) ;; NOTE: Vsync must be at least 2 lines long. Normally it's 8 lines, but fixed to 16 lines ;; on some CRTC. ld b,&f5 in a,(c) rra ld a,0 ;; counter jr c,interrupt2 ;; not in VSYNC, increment counter ld a,(interrupt_count) inc a interrupt2: ;; store new counter value ld (interrupt_count),a ;; use counter to lookup in array add a,modes AND 255 ld l,a ld a,modes/256 adc a,0 ld h,a ld a,(hl) ;; read mode from array or %10001100 ;; combine disable lower and upper ROM with mode from table out (c),a ;; set mode (and rom state) ;; restore registers we changed pop hl pop af pop bc ei ;; re-enable interrupts reti ;; return from interrupt. ;; this number keeps track of the section of the screen we ;; are on interrupt_count: defb 0 ;; this is the list of modes, one per section of the screen modes: defb 0 defb 1 defb 2 defb 0 defb 1 defb 2 end start