I was trying to modify a simple 10-Liner which uses the good ol' LOCATE 1,1: print chr$(11)chr$(11) to archieve a scroll like effect and was looking for something a bit better and smoother. Ironically enough this program is in the same issue as David Hall's Space Storm II which uses some impressive Pallarax Scrolling to Move the Stars and Meteors, though it's approach is within a Window, though I think his followup game (Space Storm III which was posted in one of the later AAs scrolled the entire screen).
Anyway, I was just wondering if anyone had any vertical scrollers they wouldn't mind sharing? :-[ One of the things I've noticed and I've played around with one on the CPCtech site is whatever has been scrolled reaches the bottom of the screen, it reappears up top again. Not sure I want that happening in the small 10-Liner, I guess the only way around that is to delete what's on line 25 or are there scroll routines which delete once something falls off the screen?
Quote from: CP/M User on 07:32, 09 November 10
I was trying to modify a simple 10-Liner which uses the good ol' LOCATE 1,1: print chr$(11)chr$(11) to archieve a scroll like effect and was looking for something a bit better and smoother. Ironically enough this program is in the same issue as David Hall's Space Storm II which uses some impressive Pallarax Scrolling to Move the Stars and Meteors, though it's approach is within a Window, though I think his followup game (Space Storm III which was posted in one of the later AAs scrolled the entire screen).
Anyway, I was just wondering if anyone had any vertical scrollers they wouldn't mind sharing? :-[ One of the things I've noticed and I've played around with one on the CPCtech site is whatever has been scrolled reaches the bottom of the screen, it reappears up top again. Not sure I want that happening in the small 10-Liner, I guess the only way around that is to delete what's on line 25 or are there scroll routines which delete once something falls off the screen?
You would need to redraw the line that falls off the screen, this is normal when you're using the hardware scrolling, which is what BASIC uses when it does this.
The smooth scrolling will be using the hardware scrolling, but not pixel by pixel.
It'll be fast and will be running at 8 pixels per movement for vertical.
Making it scroll pixel by pixel is much more challenging.
Back to the hardware scroll, lookup the following firmware functions:
SCR SET OFFSET
SCR GET LOCATION
SCR HW ROLL
Then SCR DOT POSITION, SCR CHAR POSITION, SCR NEXT BYTE, SCR PREV BYTE, SCR NEXT LINE
will all work with scrolled screens.
For example you could use SCR HW ROLL to scroll it, then use SCR CHAR POSITION to calculate the "new" row that has come on, and draw chars/pixels to this. You can use firmware functions if you want.
MC WAIT FLYBACK should be used to synchronise the scrolling with the monitor refresh.
Using this you can get quite good results from firmware.
Of course the best is always to go to the hardware direct, because you have more control, but this is a good way to understand how it works.
Not sure I'm using this to full effect! :( From what I can make out I've got the SCR HW ROLL happening, though while I don't have to position the cursor to the top, the effect appears the same. I'm just a little bit confused what SCR CHAR POSITION is for. For the program I've got it simply plots a series of random dots near the top and SCR HW ROLL pushes them down. I'm just not sure what I need SCR CHAR POSITION for! :(
With the scrolling Pixel for Pixel is that done through the access of Ports? For some reason in David Hall's Space Storm II features some ultra smooth Parallax Scrolling, though a Disassembly of it reveals nothing like that happening (certainly no OUT assembly or anything to suggest that's what it is). I've narrowed the routines down to try and understand what's happening, though the whole program is a series of values going in there and out there! ??? The program also had some way of interacting with the 3 Lines of BASIC, so while it's small, the trickery of the whole thing is mind boggling. Though I'll post the relevant disassembly which may have the Scroller included if anyone's interested to study it.
Quote from: CP/M User on 09:35, 10 November 10
Not sure I'm using this to full effect! :( From what I can make out I've got the SCR HW ROLL happening, though while I don't have to position the cursor to the top, the effect appears the same. I'm just a little bit confused what SCR CHAR POSITION is for. For the program I've got it simply plots a series of random dots near the top and SCR HW ROLL pushes them down. I'm just not sure what I need SCR CHAR POSITION for! :(
With the scrolling Pixel for Pixel is that done through the access of Ports? For some reason in David Hall's Space Storm II features some ultra smooth Parallax Scrolling, though a Disassembly of it reveals nothing like that happening (certainly no OUT assembly or anything to suggest that's what it is). I've narrowed the routines down to try and understand what's happening, though the whole program is a series of values going in there and out there! ??? The program also had some way of interacting with the 3 Lines of BASIC, so while it's small, the trickery of the whole thing is mind boggling. Though I'll post the relevant disassembly which may have the Scroller included if anyone's interested to study it.
You can use the SCR CHAR POSITION to calculate the new address each time to draw to I think.
Not sure about the random dots though.
I would be interested to see this parallax scrolling. Please post a file or program listing.
Okay I've attached the BASIC program (it's in ASCII format), otherwise it's on the ACU90B.DSK which I've attached under SPACEST2.BAS.
This is a Disassembly of the whole M/C from it.
&2710 !!D 21 21 C4 LD HL,&C421
&2713 "06 22 B0 36 LD (&36B0),HL
&2716 >. 3E 96 LD A,&96
&2718 2.R 32 08 52 LD (&5208),A
&271B / AF XOR A
&271C 2.R 32 0B 52 LD (&520B),A
&271F 2 N 32 20 4E LD (&4E20),A
&2722 !.B 21 1D C2 LD HL,&C21D
&2725 ".R 22 09 52 LD (&5209),HL
&2728 !.> 21 7F 3E LD HL,&3E7F
&272B .d 06 64 LD B,&64
&272D 6. 36 00 LD (HL),&00
&272F # 23 INC HL
&2730 .{ 10 FB DJNZ &272D
&2732 M.) CD 0D 29 CALL &290D
&2735 M^' CD 5E 27 CALL &275E
&2738 Mv' CD F6 27 CALL &27F6
&273B M^' CD 5E 27 CALL &275E
&273E Ma( CD 61 28 CALL &2861
&2741 *06 2A B0 36 LD HL,(&36B0)
&2744 M)< CD 29 BC CALL &BC29
&2747 .. 06 06 LD B,&06
&2749 ~ 7E LD A,(HL)
&274A ~. FE 00 CP &00
&274C (. 28 05 JR Z,&2753
&274E ~ FE 20 CP &20
&2750 D.) C4 07 29 CALL NZ,&2907
&2753 # 23 INC HL
&2754 .s 10 F3 DJNZ &2749
&2756 : N 3A 20 4E LD A,(&4E20)
&2759 ~. FE 00 CP &00
&275B @ C0 RET NZ
&275C .T 18 D4 JR &2732
&275E !.> 21 80 3E LD HL,&3E80
&2761 4 34 INC (HL)
&2762 ~ 7E LD A,(HL)
&2763 ~. FE 1A CP &1A
&2765 . 20 1E JR NZ,&2785
&2767 6. 36 00 LD (HL),&00
&2769 !~> 21 7E 3E LD HL,&3E7E
&276C ... 11 03 00 LD DE,&0003
&276F . 19 ADD HL,DE
&2770 / AF XOR A
&2771 > BE CP (HL)
&2772 { 20 FB JR NZ,&276F
&2774 4 34 INC (HL)
&2775 m_ ED 5F LD A,R
&2777 G 47 LD B,A
&2778 / AF XOR A
&2779 < 3C INC A
&277A ~& FE 26 CP &26
&277C (z 28 FA JR Z,&2778
&277E .y 10 F9 DJNZ &2779
&2780 # 23 INC HL
&2781 w 77 LD (HL),A
&2782 # 23 INC HL
&2783 6H 36 C8 LD (HL),&C8
&2785 ]!.> DD 21 81 3E LD IX,&3E81
&2789 >. 3E 09 LD A,&09
&278B 2.> 32 7F 3E LD (&3E7F),A
&278E ]~. DD 7E 00 LD A,(IX+&00)
&2791 ~. FE 00 CP &00
&2793 (: 28 3A JR Z,&27CF
&2795 G 47 LD B,A
&2796 ~. FE 19 CP &19
&2798 8B 38 42 JR C,&27DC
&279A ~\ FE DC CP &DC
&279C . 20 06 JR NZ,&27A4
&279E ]6.. DD 36 00 00 LD (IX+&00),&00
&27A2 .+ 18 2B JR &27CF
&27A4 ~F FE C6 CP &C6
&27A6 0H 30 48 JR NC,&27F0
&27A8 .. 0E 18 LD C,&18
&27AA ]n. DD 6E 01 LD L,(IX+&01)
&27AD ]f. DD 66 02 LD H,(IX+&02)
&27B0 My( CD F9 28 CALL &28F9
&27B3 ]u. DD 75 01 LD (IX+&01),L
&27B6 ]t. DD 74 02 LD (IX+&02),H
&27B9 .8) 11 38 29 LD DE,&2938
&27BC ]4. DD 34 00 INC (IX+&00)
&27BF e E5 PUSH HL
&27C0 .. 06 08 LD B,&08
&27C2 . 1A LD A,(DE)
&27C3 w 77 LD (HL),A
&27C4 . 13 INC DE
&27C5 # 23 INC HL
&27C6 .z 10 FA DJNZ &27C2
&27C8 a E1 POP HL
&27C9 My( CD F9 28 CALL &28F9
&27CC . 0D DEC C
&27CD p 20 F0 JR NZ,&27BF
&27CF ]# DD 23 INC IX
&27D1 ]# DD 23 INC IX
&27D3 ]# DD 23 INC IX
&27D5 :.> 3A 7F 3E LD A,(&3E7F)
&27D8 = 3D DEC A
&27D9 0 20 B0 JR NZ,&278B
&27DB I C9 RET
&27DC !y) 21 F9 29 LD HL,&29F9
&27DF ... 11 08 00 LD DE,&0008
&27E2 O 4F LD C,A
&27E3 mR ED 52 SBC HL,DE
&27E5 .| 10 FC DJNZ &27E3
&27E7 k EB EX DE,HL
&27E8 ]n. DD 6E 01 LD L,(IX+&01)
&27EB ]f. DD 66 02 LD H,(IX+&02)
&27EE .L 18 CC JR &27BC
&27F0 >] 3E DD LD A,&DD
&27F2 . 90 SUB B
&27F3 O 4F LD C,A
&27F4 .4 18 B4 JR &27AA
&27F6 !.: 21 98 3A LD HL,&3A98
&27F9 4 34 INC (HL)
&27FA ~ 7E LD A,(HL)
&27FB ~. FE 06 CP &06
&27FD 20 20 JR NZ,&281F
&27FF 6. 36 00 LD (HL),&00
&2801 !.: 21 96 3A LD HL,&3A96
&2804 ... 11 03 00 LD DE,&0003
&2807 . 19 ADD HL,DE
&2808 ~ 7E LD A,(HL)
&2809 ~. FE 00 CP &00
&280B z 20 FA JR NZ,&2807
&280D 6. 36 01 LD (HL),&01
&280F m_ ED 5F LD A,R
&2811 G 47 LD B,A
&2812 / AF XOR A
&2813 < 3C INC A
&2814 ~- FE 2D CP &2D
&2816 0z 30 FA JR NC,&2812
&2818 .y 10 F9 DJNZ &2813
&281A # 23 INC HL
&281B w 77 LD (HL),A
&281C # 23 INC HL
&281D 6H 36 C8 LD (HL),&C8
&281F .$ 06 24 LD B,&24
&2821 ]!.: DD 21 99 3A LD IX,&3A99
&2825 ]~. DD 7E 00 LD A,(IX+&00)
&2828 ~. FE 00 CP &00
&282A (- 28 2D JR Z,&2859
&282C ]f. DD 66 02 LD H,(IX+&02)
&282F ]n. DD 6E 01 LD L,(IX+&01)
&2832 ~ 7E LD A,(HL)
&2833 ~ FE 20 CP &20
&2835 . 20 02 JR NZ,&2839
&2837 6. 36 00 LD (HL),&00
&2839 My( CD F9 28 CALL &28F9
&283C ]t. DD 74 02 LD (IX+&02),H
&283F ]u. DD 75 01 LD (IX+&01),L
&2842 ~ 7E LD A,(HL)
&2843 ~. FE 00 CP &00
&2845 . 20 02 JR NZ,&2849
&2847 6 36 20 LD (HL),&20
&2849 ]4. DD 34 00 INC (IX+&00)
&284C ]~. DD 7E 00 LD A,(IX+&00)
&284F ~E FE C5 CP &C5
&2851 . 20 06 JR NZ,&2859
&2853 ]6.. DD 36 00 00 LD (IX+&00),&00
&2857 6. 36 00 LD (HL),&00
&2859 ... 11 03 00 LD DE,&0003
&285C ]. DD 19 ADD IX,DE
&285E .E 10 C5 DJNZ &2825
&2860 I C9 RET
&2861 >. 3E 01 LD A,&01
&2863 M.; CD 1E BB CALL &BB1E
&2866 N 20 4E JR NZ,&28B6
&2868 >K 3E 4B LD A,&4B
&286A M.; CD 1E BB CALL &BB1E
&286D G 20 47 JR NZ,&28B6
&286F >J 3E 4A LD A,&4A
&2871 M.; CD 1E BB CALL &BB1E
&2874 . 20 07 JR NZ,&287D
&2876 >. 3E 08 LD A,&08
&2878 M.; CD 1E BB CALL &BB1E
&287B (a 28 61 JR Z,&28DE
&287D *06 2A B0 36 LD HL,(&36B0)
&2880 + 2B DEC HL
&2881 .. 06 12 LD B,&12
&2883 ~ 7E LD A,(HL)
&2884 ~. FE 88 CP &88
&2886 (V 28 56 JR Z,&28DE
&2888 ~ FE 20 CP &20
&288A (. 28 04 JR Z,&2890
&288C ~. FE 00 CP &00
&288E w 20 77 JR NZ,&2907
&2890 My( CD F9 28 CALL &28F9
&2893 .n 10 EE DJNZ &2883
&2895 *06 2A B0 36 LD HL,(&36B0)
&2898 + 2B DEC HL
&2899 .y) 11 F9 29 LD DE,&29F9
&289C "06 22 B0 36 LD (&36B0),HL
&289F >. 3E 07 LD A,&07
&28A1 2h( 32 E8 28 LD (&28E8),A
&28A4 / AF XOR A
&28A5 2o( 32 EF 28 LD (&28EF),A
&28A8 Md( CD E4 28 CALL &28E4
&28AB >. 3E 06 LD A,&06
&28AD 2h( 32 E8 28 LD (&28E8),A
&28B0 >. 3E 13 LD A,&13
&28B2 2o( 32 EF 28 LD (&28EF),A
&28B5 I C9 RET
&28B6 *06 2A B0 36 LD HL,(&36B0)
&28B9 ... 11 06 00 LD DE,&0006
&28BC . 19 ADD HL,DE
&28BD .. 06 12 LD B,&12
&28BF ~ 7E LD A,(HL)
&28C0 ~. FE 88 CP &88
&28C2 (. 28 1A JR Z,&28DE
&28C4 ~ FE 20 CP &20
&28C6 (. 28 04 JR Z,&28CC
&28C8 ~. FE 00 CP &00
&28CA ; 20 3B JR NZ,&2907
&28CC My( CD F9 28 CALL &28F9
&28CF .n 10 EE DJNZ &28BF
&28D1 *06 2A B0 36 LD HL,(&36B0)
&28D4 # 23 INC HL
&28D5 .x) 11 F8 29 LD DE,&29F8
&28D8 "06 22 B0 36 LD (&36B0),HL
&28DB + 2B DEC HL
&28DC .A 18 C1 JR &289F
&28DE .y) 11 F9 29 LD DE,&29F9
&28E1 *06 2A B0 36 LD HL,(&36B0)
&28E4 .. 0E 12 LD C,&12
&28E6 e E5 PUSH HL
&28E7 .. 06 06 LD B,&06
&28E9 . 1A LD A,(DE)
&28EA w 77 LD (HL),A
&28EB . 13 INC DE
&28EC # 23 INC HL
&28ED .z 10 FA DJNZ &28E9
&28EF . 13 INC DE
&28F0 . 13 INC DE
&28F1 a E1 POP HL
&28F2 My( CD F9 28 CALL &28F9
&28F5 . 0D DEC C
&28F6 n 20 EE JR NZ,&28E6
&28F8 I C9 RET
&28F9 | 7C LD A,H
&28FA F. C6 08 ADD &08
&28FC g 67 LD H,A
&28FD ~@ FE C0 CP &C0
&28FF P D0 RET NC
&2900 U D5 PUSH DE
&2901 .P@ 11 50 C0 LD DE,&C050
&2904 . 19 ADD HL,DE
&2905 Q D1 POP DE
&2906 I C9 RET
&2907 >. 3E 02 LD A,&02
&2909 2 N 32 20 4E LD (&4E20),A
&290C I C9 RET
&290D !.R 21 08 52 LD HL,&5208
&2910 4 34 INC (HL)
&2911 ~ 7E LD A,(HL)
&2912 ~. FE 0C CP &0C
&2914 @ C0 RET NZ
&2915 6. 36 00 LD (HL),&00
&2917 *.R 2A 09 52 LD HL,(&5209)
&291A .. 06 06 LD B,&06
&291C 6. 36 00 LD (HL),&00
&291E # 23 INC HL
&291F .{ 10 FB DJNZ &291C
&2921 *.R 2A 09 52 LD HL,(&5209)
&2924 My( CD F9 28 CALL &28F9
&2927 ".R 22 09 52 LD (&5209),HL
&292A !.R 21 0B 52 LD HL,&520B
&292D 4 34 INC (HL)
&292E ~ 7E LD A,(HL)
&292F ~. FE 80 CP &80
&2931 @ C0 RET NZ
&2932 >. 3E 01 LD A,&01
&2934 2 N 32 20 4E LD (&4E20),A
&2937 I C9 RET
&2938 . 00 NOP
&2939 . 00 NOP
&293A . 00 NOP
&293B . 00 NOP
&293C . 00 NOP
&293D . 00 NOP
&293E . 00 NOP
&293F . 00 NOP
&2940 . 00 NOP
&2941 . 00 NOP
&2942 . 00 NOP
&2943 . 00 NOP
&2944 . 00 NOP
&2945 . 00 NOP
&2946 . 00 NOP
&2947 . 00 NOP
&2948 . 00 NOP
&2949 . 00 NOP
&294A ... 01 03 03 LD BC,&0303
&294D . 02 LD (BC),A
&294E . 00 NOP
&294F . 00 NOP
&2950 . 00 NOP
&2951 ... 01 03 03 LD BC,&0303
&2954 . 03 INC BC
&2955 . 03 INC BC
&2956 . 02 LD (BC),A
&2957 . 00 NOP
&2958 . 00 NOP
&2959 . 03 INC BC
&295A . 12 LD (DE),A
&295B !.. 21 03 03 LD HL,&0303
&295E . 03 INC BC
&295F . 00 NOP
&2960 . 00 NOP
&2961 . 03 INC BC
&2962 0! 30 21 JR NC,&2985
&2964 . 03 INC BC
&2965 . 03 INC BC
&2966 . 03 INC BC
&2967 . 00 NOP
&2968 ..0 01 03 30 LD BC,&3003
&296B !.. 21 03 03 LD HL,&0303
&296E . 03 INC BC
&296F . 02 LD (BC),A
&2970 ..0 01 12 30 LD BC,&3012
&2973 . 03 INC BC
&2974 . 03 INC BC
&2975 . 03 INC BC
&2976 . 03 INC BC
&2977 . 82 ADD D
&2978 ..! 01 12 21 LD BC,&2112
&297B . 03 INC BC
&297C . 03 INC BC
&297D . 03 INC BC
&297E C 43 LD B,E
&297F . 02 LD (BC),A
&2980 . 03 INC BC
&2981 . 12 LD (DE),A
&2982 !.. 21 03 03 LD HL,&0303
&2985 . 03 INC BC
&2986 . 03 INC BC
&2987 C.. C3 03 03 JP &0303
&298A . 03 INC BC
&298B . 03 INC BC
&298C . 03 INC BC
&298D . 03 INC BC
&298E C 43 LD B,E
&298F C 43 LD B,E
&2990 . 03 INC BC
&2991 . 03 INC BC
&2992 . 03 INC BC
&2993 . 03 INC BC
&2994 . 03 INC BC
&2995 . 03 INC BC
&2996 . 83 ADD E
&2997 C.. C3 03 03 JP &0303
&299A . 03 INC BC
&299B . 03 INC BC
&299C . 03 INC BC
&299D . 03 INC BC
&299E C 43 LD B,E
&299F C.. C3 03 03 JP &0303
&29A2 . 03 INC BC
&29A3 . 03 INC BC
&29A4 . 03 INC BC
&29A5 . 03 INC BC
&29A6 . 83 ADD E
&29A7 C.. C3 03 03 JP &0303
&29AA . 03 INC BC
&29AB . 03 INC BC
&29AC . 03 INC BC
&29AD C 43 LD B,E
&29AE C 43 LD B,E
&29AF C.. C3 03 03 JP &0303
&29B2 . 03 INC BC
&29B3 . 03 INC BC
&29B4 . 03 INC BC
&29B5 . 03 INC BC
&29B6 CC. C3 C3 03 JP &03C3
&29B9 . 03 INC BC
&29BA . 03 INC BC
&29BB . 03 INC BC
&29BC . 03 INC BC
&29BD C 43 LD B,E
&29BE C 43 LD B,E
&29BF C.. C3 01 03 JP &0301
&29C2 . 03 INC BC
&29C3 . 03 INC BC
&29C4 . 03 INC BC
&29C5 . 83 ADD E
&29C6 C.. C3 82 01 JP &0182
&29C9 . 03 INC BC
&29CA . 03 INC BC
&29CB C 43 LD B,E
&29CC C 43 LD B,E
&29CD C 43 LD B,E
&29CE C.. C3 82 01 JP &0182
&29D1 . 03 INC BC
&29D2 . 83 ADD E
&29D3 . 83 ADD E
&29D4 . 83 ADD E
&29D5 CC. C3 C3 82 JP &82C3
&29D8 . 00 NOP
&29D9 C 43 LD B,E
&29DA C 43 LD B,E
&29DB C 43 LD B,E
&29DC C 43 LD B,E
&29DD CC. C3 C3 00 JP &00C3
&29E0 . 00 NOP
&29E1 CCC C3 C3 C3 JP &C3C3
&29E4 CCC C3 C3 C3 JP &C3C3
&29E7 . 00 NOP
&29E8 . 00 NOP
&29E9 A 41 LD B,C
&29EA CCC C3 C3 C3 JP &C3C3
&29ED C.. C3 82 00 JP &0082
&29F0 . 00 NOP
&29F1 . 00 NOP
&29F2 A 41 LD B,C
&29F3 CC. C3 C3 82 JP &82C3
&29F6 . 00 NOP
&29F7 . 00 NOP
&29F8 . 00 NOP
&29F9 T 54 LD D,H
&29FA |.. FC 00 00 CALL M,&0000
&29FD . 00 NOP
&29FE . 00 NOP
&29FF . 00 NOP
&2A00 . 00 NOP
&2A01 ||( FC FC A8 CALL M,&A8FC
&2A04 . 00 NOP
&2A05 |(. FC A8 00 CALL M,&00A8
&2A08 . 00 NOP
&2A09 0L 30 CC JR NC,&29D7
&2A0B T 20 54 JR NZ,&2A61
&2A0D ||. FC FC 00 CALL M,&00FC
&2A10 . 00 NOP
&2A11 0L 30 CC JR NC,&29DF
&2A13 . 20 10 JR NZ,&2A25
&2A15 d 64 LD H,H
&2A16 . 98 SBC B
&2A17 . 00 NOP
&2A18 . 00 NOP
&2A19 .0 10 30 DJNZ &2A4B
&2A1B . 00 NOP
&2A1C .d 10 64 DJNZ &2A82
&2A1E . 98 SBC B
&2A1F . 00 NOP
&2A20 . 00 NOP
&2A21 . 00 NOP
&2A22 3 33 INC SP
&2A23 . 00 NOP
&2A24 . 00 NOP
&2A25 0 30 20 JR NC,&2A47
&2A27 . 00 NOP
&2A28 . 00 NOP
&2A29 . 00 NOP
&2A2A 3 33 INC SP
&2A2B ".3 22 11 33 LD (&3311),HL
&2A2E . 00 NOP
&2A2F . 00 NOP
&2A30 . 00 NOP
&2A31 . 00 NOP
&2A32 ... 11 1A 8D LD DE,&8D1A
&2A35 ".. 22 00 00 LD (&0000),HL
&2A38 . 00 NOP
&2A39 . 00 NOP
&2A3A . 0F RRCA
&2A3B N 4E LD C,(HL)
&2A3C . 8D ADC L
&2A3D . 0F RRCA
&2A3E . 00 NOP
&2A3F . 00 NOP
&2A40 . 00 NOP
&2A41 . 05 DEC B
&2A42 . 0F RRCA
&2A43 . 0F RRCA
&2A44 . 0F RRCA
&2A45 . 0F RRCA
&2A46 . 0A LD A,(BC)
&2A47 . 00 NOP
&2A48 . 00 NOP
&2A49 . 05 DEC B
&2A4A . 0F RRCA
&2A4B s F3 DI
&2A4C s F3 DI
&2A4D . 0F RRCA
&2A4E . 0A LD A,(BC)
&2A4F . 00 NOP
&2A50 . 00 NOP
&2A51 . 0F RRCA
&2A52 [ 5B LD E,E
&2A53 " A2 AND D
&2A54 Q 51 LD D,C
&2A55 ' A7 AND A
&2A56 . 0F RRCA
&2A57 . 00 NOP
&2A58 . 00 NOP
&2A59 . 0F RRCA
&2A5A [ 5B LD E,E
&2A5B . 00 NOP
&2A5C . 00 NOP
&2A5D ' A7 AND A
&2A5E . 0F RRCA
&2A5F . 00 NOP
&2A60 . 00 NOP
&2A61 . 05 DEC B
&2A62 [ 5B LD E,E
&2A63 . 00 NOP
&2A64 . 00 NOP
&2A65 ' A7 AND A
&2A66 . 0A LD A,(BC)
&2A67 . 00 NOP
&2A68 . 00 NOP
&2A69 . 05 DEC B
&2A6A [ 5B LD E,E
&2A6B " A2 AND D
&2A6C Q 51 LD D,C
&2A6D ' A7 AND A
&2A6E . 0A LD A,(BC)
&2A6F . 00 NOP
&2A70 . 00 NOP
&2A71 . 00 NOP
&2A72 . 0F RRCA
&2A73 s F3 DI
&2A74 s F3 DI
&2A75 . 0F RRCA
&2A76 . 00 NOP
&2A77 . 00 NOP
&2A78 . 00 NOP
&2A79 . 00 NOP
&2A7A . 8A ADC D
&2A7B . 0F RRCA
&2A7C . 0F RRCA
&2A7D E 45 LD B,L
&2A7E . 00 NOP
&2A7F . 00 NOP
&2A80 . 00 NOP
&2A81 o*. EF 2A 00 RST 5,&002A
&2A84 . 00 NOP
&2A85 . 15 DEC D
&2A86 _.. DF 00 00 RST 3,&0000
&2A89 . 00 NOP
&2A8A . 00 NOP
&2A8B . 00 NOP
&2A8C . 00 NOP
&2A8D . 00 NOP
&2A8E . 00 NOP
&2A8F . 00 NOP
&2A90 . 00 NOP
&2A91 . 00 NOP
&2A92 . 00 NOP
&2A93 . 00 NOP
&2A94 . 00 NOP
&2A95 . 00 NOP
&2A96 . 00 NOP
&2A97 . 00 NOP
&2A98 . 00 NOP
&2A99 . 00 NOP
&2A9A . 00 NOP
&2A9B . 00 NOP
&2A9C . 00 NOP
&2A9D . 00 NOP
&2A9E . 00 NOP
&2A9F . 00 NOP
The main subroutine is located at 2732, CALL &275E relates to the Displaying and Moves the Meteors, &27F6 Displays and Moves the Stars and then another call to move the Meteors follows before checking the controls. In the Star routine I did a call to &281F which seemed to be involved with the Displaying and Movement of the Stars. The routine at &27F6 does a few other things before doing a Jump Relative if Result is Not Zero to that Routine.
I'm guessing that program is using some kind of mapped out table of the screen which allows everything to move down a row at a time to give it that slick look.
This is just something I knocked up out of BASIC, not necessarily the same as what Space Storm II is doing, though generates a simular result. In order to make it appear moving though, the old pixel needs to be erased.
10 INK 8,26
20 DIM a(20):a(1)=&C000:a(2)=&C800:a(3)=&D000:a(4)=&D800:a(5)=&E000:a(6)=&E800:a(7)=&F000:a(8)=&F800:a(9)=&C050:a(10)=&C850
30 a(11)=&D050:a(12)=&D850:a(13)=&E050:a(14)=&E850:a(15)=&F050:a(16)=&F850:a(17)=&C0A0:a(18)=&C8A0:a(19)=&D0A0:a(20)=&D8A0
40 MODE 0:FOR num=1 TO 20:POKE a(num)+20,&1
50 oldnum=num-1
60 IF oldnum<>0 THEN POKE a(oldnum)+20,&0
70 FOR delay=1 TO 2:CALL &BD19:NEXT delay
80 NEXT num
90 CALL &BB18:MODE 2
After going though some AAs I found this Vertical Scrolling routine in AA55.
org &4000
ld hl,&c000
ld de,&d800
ld c,16
.loop
push hl
push de
push bc
ld bc,&50
ldir ;; Copy area up three lines
pop bc
pop hl ;; DE steps down a line
call &bc26
ex de,hl
pop hl
call &bc26 ;; HL steps down a line
djnz loop
ret
The figure which accompanies this program pictures the screen as 50 bytes wide and 16 reflects the number of lines in it and it's supposed to push down to &D800, which leaves a point between the position a pixel is placed at and on the offset to &D800 which is the 4 line down.
On close inspection I've noticed there are a few errors in it, the most annoying being C being declared as the looping mechanism when it should be "B" that's being used since DJNZ loop is being used, and to my shock horror I just noticed I'm POPing the HL registers twice when it should be POP DE (the statement accompanying that line even suggests that! ??? ), or am I'm doing that wrong cause the routine is Exchanging the contents between HL & DE?
I've tried fine tuning it, though I'm not doing something right or if it's a bug in the program or strictly by nature this scrolling routine won't allow for fine scrolling. Seems feasable and by looking up the Firmware Instruction which is used for calculating the following line and returning the result in HL!
This is what I've done:
org &4000
ld hl,&c000
ld de,&c800
ld b,100
.loop
push hl
push de
push bc
ld bc,&50
ldir ;; Copy area up three lines
pop bc
pop de ;; DE steps down a line
call &bc26
ex de,hl
pop hl
call &bc26 ;; HL steps down a line
djnz loop
ret
Okay after having a bit of a play with it, I reverted the program so it's POPing HL twice which causes the program to scroll the image down to the next line.
org &4000
ld hl,&c000
ld de,&c800
ld b,100
.loop
push hl
push de
push bc
ld bc,&50
ldir ;; Copy area up three lines
pop bc
pop hl ;; DE steps down a line
call &bc26
ex de,hl
pop hl
call &bc26 ;; HL steps down a line
djnz loop
ret
Is this acceptable though given I haven't POPed the DE registers? I wasn't sure, though the program hasn't crashed - I can only presume it's okay cause I'm Exchanging the contents from DE and HL - I guess the only limitation with it is if you need to use DE for something else - but then you'd probably PUSH and POP DE before using this code - not sure though cause this routine would need something to clear the pixels from the previous position.
Using this method seems reasonible and quick enough, I guess the more I scrounge around looking through Assembly Routines the more I'll find of this sort of thing. It's just a shame I don't understand the updating process of how everything is placed onscreen. I can only use an example to explain:
When I used the routine above to scroll a pixel down the screen e.g. "mode 1:plot 300,399,2:call &4000", that pixel is smeared down from where it was. This is no problem for something like SCR HW ROLL which physically ROLLs the screen down. Unfortunately I don't know if AA ever showed the kind of routine that would demonstrate the process of removing a pixel from one place. Space Storm II for example does everything ramdomibly, the Meteors are scattered throughout the screen as well as the stars. The alien you control is fixed in one position - it all works extremely well. Is simply unbelievable how something so small can be so mindboggling!
It's perfectly fine to do PUSH DE .... POP HL or whatever. The Z80 doesn't care where the data originally came from, it's just manipulating the stack. As long as the number of PUSHes matches the number of POPs* you'll be fine. You'll usually know quite quickly if you get it wrong as stack corruption almost always leads to an immeadiate crash.
*Fancy programmers will point out that code like PUSH DE, RET is also perfectly valid too, if requiring a somewhat deeper understanding to follow.
Quote from: andycadley on 09:48, 27 December 10
*Fancy programmers will point out that code like PUSH DE, RET is also perfectly valid too, if requiring a somewhat deeper understanding to follow.
I have seen this done in some ROM software - what does it do in reality then?
Quote from: redbox on 10:46, 27 December 10
I have seen this done in some ROM software - what does it do in reality then?
This puts DE onto the stack.
RET will then pop it from the stack and execute. So effectively it is like this JP (DE).
Quote from: arnoldemu on 11:00, 27 December 10
This puts DE onto the stack.
RET will then pop it from the stack and execute. So effectively it is like this JP (DE).
Nice trick, thanks for explaining it.
andycadley wrote:
It's perfectly fine to do PUSH DE .... POP HL or whatever. The Z80 doesn't care where the data originally came from, it's just manipulating the stack. As long as the number of PUSHes matches the number of POPs* you'll be fine. You'll usually know quite quickly if you get it wrong as stack corruption almost always leads to an immeadiate crash.
*Fancy programmers will point out that code like PUSH DE, RET is also perfectly valid too, if requiring a somewhat deeper understanding to follow.
Hmmm, I just hope CP/M doesn't throw a wobbley about it - I've got a horrible feeling it's fussy when it comes down to what's PUSHed then POPed. :-[
Quote from: CP/M User on 14:06, 27 December 10
Hmmm, I just hope CP/M doesn't throw a wobbley about it - I've got a horrible feeling it's fussy when it comes down to what's PUSHed then POPed. :-[
There's absolutely no way CP/M can know, as long as the stack is consistent it will be fine.
andycadley wrote:
There's absolutely no way CP/M can know, as long as the stack is consistent it will be fine.
Okay everything appears to be fine with regard to this, unfortunately there's another serious problem which occurs. I should of realised this earlier since CP/M is associated with it, I had the same problem earlier when I was trying to incorporate Sprites in my programs, in the end I simply moved the screen from &C000 to &4000.
My small contribution :
org #A000
LD HL,#C640 ; #C000 + 160 lines down
LD A,160
BCL:
LD D,H
LD E,L ; to do LD DE,HL
LD BC,#F800 ; Here begin my "BC29" routine :-)
ADD HL,BC ; Like ld bc,#800 - sbc hl,bc
BIT 6,H ; HL < #C000 ?
JR NZ,NoAdjust ; No, continue
LD BC,#3FB0
ADD HL,BC
NoAdjust:
LD BC,#50
PUSH HL
LDIR
POP HL
DEC A
JR NZ,BCL
RET
This is looking so simular to what I mentioned in David Hall's program it's incrediable, though looking at what David has in his, it appears somewhat different. Sadly it's another one which CP/M likes to dump with rubbish on screen, if I make another simple demo I maybe able to incorporate this in - seems such a pity that if I want to do something like this in CP/M I have to move the screen memory into the core area! :(
demoniak wrote:
My small contribution :
org #A000
LD HL,#C640 ; #C000 + 160 lines down
LD A,160
BCL:
LD D,H
LD E,L ; to do LD DE,HL
LD BC,#F800 ; Here begin my "BC29" routine :-)
ADD HL,BC ; Like ld bc,#800 - sbc hl,bc
BIT 6,H ; HL < #C000 ?
JR NZ,NoAdjust ; No, continue
LD BC,#3FB0
ADD HL,BC
NoAdjust:
LD BC,#50
PUSH HL
LDIR
POP HL
DEC A
JR NZ,BCL
RET
I've just been trying this with the Screen Mapped at &4000 and unfortunately I haven't been able to get it to work! :-[
Not sure if it's like the trouble I had earlier with the Sprite Driver where the situation is different because of the Screen being at a different location, though it was using NC for the Jump Relatives in that case, where's this is Jumping Relative when the result isn't Zero.
Any advise, suggestions! :-[
Quote from: CP/M User on 07:45, 08 January 11
I've just been trying this with the Screen Mapped at &4000 and unfortunately I haven't been able to get it to work! :-[
Not sure if it's like the trouble I had earlier with the Sprite Driver where the situation is different because of the Screen being at a different location, though it was using NC for the Jump Relatives in that case, where's this is Jumping Relative when the result isn't Zero.
Any advise, suggestions! :-[
Hum, strange...
I've tested this with the screen at #4000, and It works for me. I've simply replaced the LD HL,#C640 by LD HL,#4640
Quote from: CP/M User on 07:45, 08 January 11
I've just been trying this with the Screen Mapped at &4000 and unfortunately I haven't been able to get it to work! :-[
This is because he is using the
BIT 6,H code to check if the address is lower than &C000. When you try the routine at &4000, this won't work.
His routine works like this: the screen address (we'll assume &C000 for this example) is in HL. The high byte (H) therefore contains &C0, which is %11000000 in binary. Bit 6 is therefore set (%1
1000000) so the screen address is &C000 or higher. If the screen address was &BF00, the high byte would be &BF (%1
0111111) and Bit 6 would not be set.
So basically, anything above &C000 will have bit 6 set, anything below won't. Nice routine for standard screen addresses, not so helpful when you want to do it at &4000.
Maybe you could change it so you have another way of checking for this?
Yeah I might have tweaked around with the values in it too much. However when I was compiling the program at the address you have &A000, it didn't seem to do anything with either &4000 or &C000, was working fine at &4000 though.
I was also trying to get this routine to scroll the entire screen down or nearly all of it though wasn't getting it to work properly, do anyone know if that's possible with this kind of routine or is it pretty much at it's limit?
EDIT: Thanks for the explaination Redbox.
Quote from: CP/M User on 10:59, 08 January 11
EDIT: Thanks for the explaination Redbox.
On second thought, I might be wrong here.
&40 also has bit 6 set (%01000000), so it might not be the problem. :-[
Will have to take a closer look later and see what's going on!
Yes I noticed that &C0 uses bits 6 & 7, though &40 begins at bit 6.
Yeah it seems to be working for me when the address is set to &4000. This is what I came up with which scrolls a little bit further down the screen:
ORG &3000
LD HL,&6F30
LD A,190
.BCL
LD D,H
LD E,L
LD BC,&F800
ADD HL,BC
BIT 6,H
JR NZ,NoAdjust
LD BC,&3FB0
ADD HL,BC
.NoAdjust
LD BC,&50
PUSH HL
LDIR
POP HL
DEC A
JR NZ,BCL
RET
Use:
LD A,&40
CALL &BC08
RET
to place the screen at &4000 and don't have the routine within that area between &4000 and &8000 (or it'll probably crash!).