HARDWARE SCROLL N.B.: This article is copyright 1992 Thorsten Gudmundsen who is thus responsible for the pseudo-English. oo0 Cheating with SAM part 1, 'Hardware' scroll 0oo ---------------------------------------------------------------- Let's face it! SAM can't hardware scroll! But it's possible to cheat the monitor so that the screen can be updated below the usually Y position. By doing this, it's possible for SAM to display interlace screen modes such as 512x384 4 colours or 256x384 in 16 colours. Another thing that's possible, is to show one screen, and then scroll it either one pixel up or down. Remember it's still the same screen! You can't continue to scroll up - only one pixel up and one pixel down! That's not very efficient as hardware scroll usually means that a part of the screen can be scrolled in all directions without using machine code moving the graphics. 0n the other hand, this 'cheat' technique can be used if both the hardware cheat and programming are combined! As you have surely noticed, Z80B can't move around with all the screen area in one frame, but by using this technique, it's possible to scroll most of the screen in 2 frames, but it would look like it's scrolled for EACH frame! You must use 2 screens, 1 that is shown & use the scroll technique and another that the Z80 works on while the other are displayed. Fig.1: How the SAM works with hardware/software scroll: Screen 1: Screen 2: Frame 1:-------------------------- ----------------------------- VMPR = screen 1 LMPR = screen 2 Border = black Move sprites Frame 2:-------------------------- - 2 pixels down - VMPR = screen 1 in bufferscr Border = white (& therefor scrolls 1 pixel down Frame 3:-------------------------- ----------------------------- LMPR = screen 2 VMPR = screen 2 Border = black Move sprites Frame 4:- 2 pixels down - ----------------------------- in buffer scr. VMPR = screen 2 Border = white and therefore scrolls 1 pixel Frame 5:-------------------------- ----------------------------- Just like frame 1! Just like frame 1! First of all how to cheat the screen: If you load something from SAMD0S while the border are flashing, you might have noticed that the screen either 'jump' a bit up'n'down or that the text become a bit out of focus. That's exactly what the cheat is all about:By shifting between black and white in the border for each frame , the screen will when BLACKed , be steady and when WHITEed be updated a few pixels below the steady screen position. The complete screen area are about twice as big as the the screen you are looking at now! This area are called the border and can with the Phillips CM 8833 monitor series be seen by turning some of the buttons at the back of the monitor. The area of the border that is shifted between black and white can be done in the invincible part of the screen - it will still work! The technique can best be illustrated by fig. 2 that shows all the screen and what to be done with it if you want to scroll the screen down a single line. Fig. 2: The complete screen area: ----------------------------------- Top of screen -----------------------------1--------- :INVINCIBLE PART 0F SCR 2 : 1)Start colour 'chock' : 2 : : 2 : 2)Shift between black & : Border 2 : white here! : 3 : *************************************** 3:Display black border *Y0UR VISI0N N0W! * again * * * --------------------------------- * * :0,191 255,191: * * : : * * : : * * : : * * : Text/graphic display : * * = what you see now! * : : * * : : * * : : * * : : * * : : * * :0,0 255,0: * * --------------------------------- * * * * * *************************************** :INVINCIBLE : : Border : : : : : : : --------------------------------------- Here start the frame Bottom of screen flyback. The 1, 2 and 3's display what tasks the processor must do in specific parts of the whole screen area. When the Z80 processor execute a HALT instruction, it usually waits for the scanline to return back to the top of the screen before the interrupt code will be executed (of course not if you define a line interrupt or other interrupts!). In other words:You know that the scanline will be at the top of the screen when a HALT is executed! It's not very easy to explain this technique, so I've written a program that scrolls garbage down in the screen area so you can see how it works. (Graham: Might be on disk as object code - see ENC 12 section) 0RG 32768 JP START ;*** Scroll down using the hard/software scroll. *** ;(C) 1/4-1992 Thorsten Gudmundsen, tlf:98 18 68 62 ; ;Hardware reg: CLUT0 EQU 248 VMPR EQU 252 LMPR EQU 250 B0RDER EQU 254 ;vars AFSTAND DW 200 LASTC0L DB 0 SCR DB %00100100 ;screen tables. SCRTAB1 DS 192 SCRTAB2 DS 192 ;Interrupt IM2 pointers INTVECT0R EQU #EFFF L0WVECT0R EQU #EF ; START DI LD A,%00100100:0UT (VMPR),A X0R A:0UT (B0RDER),A ; ;Put random garbage on screen1 & 2 ; LD HL,0:LD DE,16384:LD BC,8192 SETL00P1 LD A,C:LD (HL),A:LD (DE),A:INC HL:INC DE:DEC BC LD A,B:0R C:JR NZ,SETL00P1 ; ;screencolour=black on white background ; LD BC,6144 SETL00P2 LD A,56:LD (HL),A:LD (DE),A:INC HL:INC DE:DEC BC LD A,B:0R C:JR NZ,SETL00P2 ; ; ;set screentables:Each word equal to adr on every 2. line ; LD IX,SCRTAB1:LD HL,2:LD DE,64:LD B,96 SETSCRTBL1 LD (IX+0),L:LD (IX+1),H:ADD HL,DE INC IX:INC IX:DJNZ SETSCRTBL1 ; LD IX,SCRTAB2:LD HL,16386:LD B,96 SETSCRTBL2 LD (IX+0),L:LD (IX+1),H:ADD HL,DE INC IX:INC IX:DJNZ SETSCRTBL2 ; ;Rid of SP, Set interruptvector to INT_R1 frame interrupt ; LD SP,#FFF0 LD HL,INT_R1:LD (INTVECT0R),HL LD A,L0WVECT0R:LD I,A:IM 2 EI:HALT:JR START2 ; ;**** MAINPR0GRAM **** ; MAINL00P HALT:CALL SHIFTSCR START2 LD A,(SCR) BIT 0,A JR Z,M0VE2 ; ;Every second frameinterrupt:Shift between the routines that are ;moving bytes between screen1 & 2 ; CALL DSCR0LLSCR1:JR MAINL00P M0VE2 CALL DSCR0LLSCR2:JR MAINL00P ; ;Swap between screen1 and screen 2 ; SHIFTSCR LD A,(SCR):X0R 1:LD (SCR),A 0UT (VMPR),A RET ; ;Frameinterrupt: ; INT_R1 PUSH AF:PUSH HL:PUSH DE:PUSH BC ; ;Clear RGB colour out on border and wait for a while: ; LD A,%01110000:LD BC,CLUT0:0UT (C),A LD HL,1:LD DE,1:LD BC,500:LDIR ; ;*** swap between black and white in the invicible part of the ; screen: ; LD A,(LASTC0L):X0R 127:LD (LASTC0L),A LD BC,CLUT0:0UT (C),A ; ;AFSTAND var set the timelimit for the black/white bordershock ;on the monitor. By doing that, the scanline will move more than ;just one scanline down before updating the display. ; LD HL,1:LD DE,1:LD BC,(AFSTAND):LDIR ; ;Border colour back to colour 0. ; LD BC,CLUT0:X0R A:0UT (C),A ; P0P BC:P0P DE:P0P HL:P0P AF EI:RETI ; ;Routine to kopi screen2 to screen1 (pushed 1 line!) ; DSCR0LLSCR1 LD IX,SCRTAB1+188:LD IY,SCRTAB2+188 LD BC,65536:LD A,96 DAGAINSCR1 LD E,(IX+2):LD D,(IX+3) ;DE=kopiere til LD L,(IY+0):LD H,(IY+1) ;HL=hvorfra DEC IX:DEC IX:DEC IY:DEC IY ; ;copy 28 bytes each screenline ; LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI INC E:INC E:INC E:INC E INC L:INC L:INC L:INC L LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI DEC A:JP NZ,DAGAINSCR1 ; ;Trough garbage out on screen. (in order to see that the display ;REALLY are scrolling!) ; EX DE,HL:LD DE,62:SBC HL,DE LD B,62 DAGAINSCR1B LD A,R:LD (HL),A:INC L:DJNZ DAGAINSCR1B RET ; ;Copy from screen1 to screen2 ; DSCR0LLSCR2 LD IX,SCRTAB2+188:LD IY,SCRTAB1+188 LD BC,65536:LD A,96 DAGAINSCR2 LD E,(IX+2):LD D,(IX+3) LD L,(IY+0):LD H,(IY+1) DEC IX:DEC IX:DEC IY:DEC IY LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI INC E:INC E:INC E:INC E INC L:INC L:INC L:INC L LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI DEC A:JP NZ,DAGAINSCR2 RET Hope you followed all that...