Author Topic: Is it possible to change screen address from BASIC?  (Read 990 times)

0 Members and 1 Guest are viewing this topic.

Offline mr_lou

  • 6128 Plus
  • ******
  • Posts: 3.185
  • Country: dk
    • index.php?action=treasury
    • 8-bit Memoirs - a Blu-ray diskmag-like eBook about the 8-bit era
  • Liked: 1356
  • Likes Given: 2666
Like the topic says: Is it possible to change screen address from BASIC?

On boot, the address is &C000.
Any OUT and/or POKE commands I can call from BASIC to change it to &4000 ?

Offline roudoudou

  • 6128 Plus
  • ******
  • Posts: 1.006
  • Country: fr
    • urban exploration
  • Liked: 1381
  • Likes Given: 816
Re: Is it possible to change screen address from BASIC?
« Reply #1 on: 15:20, 05 January 20 »
Code: [Select]
10 OUT &BC00,12:OUT &BD00,&10: REM screen in #4000
use RASM, the best assembler ever made :p

I will survive

Offline mr_lou

  • 6128 Plus
  • ******
  • Posts: 3.185
  • Country: dk
    • index.php?action=treasury
    • 8-bit Memoirs - a Blu-ray diskmag-like eBook about the 8-bit era
  • Liked: 1356
  • Likes Given: 2666
Re: Is it possible to change screen address from BASIC?
« Reply #2 on: 15:22, 05 January 20 »
Um.... thanks....
How to reverb back to &c000 then?
Any logic behind these numbers? I mean, how do they relate to &4000?

Offline roudoudou

  • 6128 Plus
  • ******
  • Posts: 1.006
  • Country: fr
    • urban exploration
  • Liked: 1381
  • Likes Given: 816
Re: Is it possible to change screen address from BASIC?
« Reply #3 on: 15:24, 05 January 20 »
it's related to CRTC register (12 & 13)
basically reg12=#10 reg13=00 -> #4000
basically reg12=#30 reg13=00 -> #C000
precisely you must read internal bit meaning http://www.cpcwiki.eu/index.php/CRTC#The_6845_Registers


use RASM, the best assembler ever made :p

I will survive

Offline andycadley

  • Supporter
  • 6128 Plus
  • *
  • Posts: 940
  • Liked: 462
  • Likes Given: 75
Re: Is it possible to change screen address from BASIC?
« Reply #4 on: 22:28, 05 January 20 »
Note that simply changing the screen address like that won't make BASIC use it for things like printing. It will carry on assuming the screen is in the usual place and will reset it if you issue a MODE command or cause the screen to scroll.

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.939
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 1157
  • Likes Given: 1924
Re: Is it possible to change screen address from BASIC?
« Reply #5 on: 13:21, 06 January 20 »
Hope you don't mind me posting here.

I'd been doing some work on Double Buffering from a BASIC perspective, using a simple Sprite Driver I'd written to alternate the image between screens along with using the Standard Firmware way of changing the screens, my example isn't working properly, I can get the image to Move down the screen just fine, but as soon as I try to move up, problems with my BASIC end up corrupting some of those areas. I've tried with the same techniques for when the Ball image moves down the screen and add &50 when YP=&3000, but had no luck going the other way. :(

EDIT: I figured out if my Ball was moving fine going down, but being moved in Double Increments, I had to change that and introduce and more Strict concept of alternating the code when the Keys are being pressed. So now when a key is pressed, a series of checks are made to determine if I'm on Screen 1 @ &C000 or Screen 2 @ &4000 and move to where I have to get to, which seemed to be the only way of fixing up the mess I had earlier.

Code: [Select]

100 DEFINT a-z:MEMORY &3FFF:GOSUB 2000
110 MODE 0:BORDER 0:INK 0,3:INK 1,26:INK 2,21
120 CALL &A02E:CLS:CALL &A028:CLS:CALL &A02E
130 sc=2:x1=40:oy=720:ox=40
140 i=720:i1=720:y1=720
150 GOSUB 1310
160 WHILE 1
170   IF INKEY(2)=0 THEN IF y1<>1920 THEN GOSUB 1110
180   IF INKEY(0)=0 THEN IF y1<>0 THEN GOSUB 1140
190   IF INKEY(1)=0 THEN IF x1<>76 THEN GOSUB 1170
200   IF INKEY(8)=0 THEN IF x1<>0 THEN GOSUB 1200
210 WEND
220 END
800 ' Move Down
810 IF y1>&3FFF THEN i1=i+&50:i=i+&50:y1=i1
820 GOSUB 1410:GOSUB 1510
830 RETURN
840 IF y1>&3FFF THEN i1=i+&50:i=i+&50:y1=i1
850 GOSUB 1610:GOSUB 1310
860 RETURN
900 ' Move Up
910 IF y1<0 THEN i2=i+&37B0:i=i-&50:y1=i2
920 GOSUB 1410:GOSUB 1510
930 RETURN
940 IF y1<0 THEN i2=i+&37B0:i=i-&50:y1=i2
950 GOSUB 1610:GOSUB 1310
960 RETURN
1000 ' Move Right
1010 GOSUB 1410:GOSUB 1510
1020 RETURN
1050 ' Move Left
1060 GOSUB 1610:GOSUB 1310
1070 RETURN
1100 ' Check Screen Status and Move accordingly
1110 IF sc=1 THEN oy=z:y1=y1+&800:GOSUB 810:sc=2:RETURN
1120 IF sc=2 THEN oy=z:y1=y1+&800:GOSUB 840:sc=1:RETURN
1130 RETURN
1140 IF sc=1 THEN oy=z:y1=y1-&800:GOSUB 910:sc=2:RETURN
1150 IF sc=2 THEN oy=z:y1=y1-&800:GOSUB 940:sc=1:RETURN
1160 RETURN
1170 IF sc=1 THEN ox=w:x1=x1+1:GOSUB 1010:sc=2:CALL &BD19:RETURN
1180 IF sc=2 THEN ox=w:x1=x1+1:GOSUB 1060:sc=1:CALL &BD19:RETURN
1190 RETURN
1200 IF sc=1 THEN ox=w:x1=x1-1:GOSUB 1010:sc=2:CALL &BD19:RETURN
1210 IF sc=2 THEN ox=w:x1=x1-1:GOSUB 1060:sc=1:CALL &BD19:RETURN
1220 RETURN
1300 ' Draw screen to &4000
1310 s=&4000
1320 z=y1
1330 w=x1
1340 CALL &A000,&A036,(s+z)+w
1350 CALL &A028
1360 RETURN
1400 ' Clear Screen at &C000
1410 s=&C000
1420 oz=oy
1430 ow=ox
1440 CALL &A000,&A056,(s+oz)+ow
1450 RETURN
1500 ' Draw screen at &C000
1510 s=&C000
1520 z=y1
1530 w=x1
1540 CALL &A000,&A036,(s+z)+w
1550 CALL &A02E
1560 RETURN
1600 ' Clear Screeb at &4000
1610 s=&4000
1620 oz=oy
1630 ow=ox
1640 CALL &A000,&A056,(s+oz)+ow
1650 RETURN
2000 addr=&A000
2010 FOR ln=1 TO 7
2020 READ a$
2030 FOR p=1 TO 31 STEP 2
2040 POKE addr,VAL("&"+MID$(a$,p,2))
2050 addr=addr+1
2060 NEXT p:NEXT ln
2070 RETURN
2100 DATA DD6E02DD6603EBDD6E00DD66012234A0
2110 DATA 0608C506041A77132310FA2A34A0CD26
2120 DATA BC2234A0C110EBC93E40CD08BCC93EC0
2130 DATA CD08BCC900C000000000004080000084
2140 DATA 48000084480000844800008448000040
2150 DATA 80000000000000000000000000000000
2170 DATA 00000000000000000000000000000000


I have added the Machine Code Loader at the end of the Demo to show how well it performs, the Sprite Data is also inbedded in the M/C, though have included the Assembly Source & Sprite Data below:


Code: [Select]

org &a000


;; Used in BASIC Double Buffer example.


ld l,(ix+&02)
ld h,(ix+&03) ;; sprite address
ex hl,de ;; is placed into DE register
ld l,(ix+&00)
ld h,(ix+&01) ;; screen address
ld (scradr),hl ;; store screen address


ld b,8 ;; sprite height
.rloop
push bc ;; preserve sprite height
ld b,4 ;; sprite width
.ploop
ld a,(de) ;; contents of sprite (from DE) goes into A register
ld (hl),a ;; and placed onto the Screen
inc de ;; Increment to next position of the Sprite
inc hl ;; Increment to next position of the Screen
djnz ploop ;; Has sprite width been reached?
;; If no, Jump back to ploop, else continue

ld hl,(scradr) ;; Recall the original Screen Address
call &bc26 ;; get the value for the next line down
ld (scradr),hl ;; and store this new value into Screen Address


pop bc ;; Recall the Sprite Height
djnz rloop ;; if this isn't zero return to rloop to draw more lines


ret ;; else exit to BASIC.


.scr40
ld a,&40 ;; Routine to move screen
call &bc08 ;; to &4000
ret
.scrc0
ld a,&c0 ;; Routine to move screen
call &bc08 ;; to &C000
ret


.scradr
defw &c000
.ball
defb 0,0,0,0
defb 0,64,128,0
defb 0,132,72,0
defb 0,132,72,0
defb 0,132,72,0
defb 0,132,72,0
defb 0,64,128,0
defb 0,0,0,0


.blank
defb 0,0,0,0
defb 0,0,0,0
defb 0,0,0,0
defb 0,0,0,0
defb 0,0,0,0
defb 0,0,0,0
« Last Edit: 06:47, 10 January 20 by AMSDOS »
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Offline mv

  • Supporter
  • CPC464
  • *
  • Posts: 42
  • Country: de
  • CPCBasic, CPCemu, CPC 6128
  • Liked: 94
  • Likes Given: 72
Re: Is it possible to change screen address from BASIC?
« Reply #6 on: 01:02, 08 January 20 »
Note that simply changing the screen address like that won't make BASIC use it for things like printing. It will carry on assuming the screen is in the usual place and will reset it if you issue a MODE command or cause the screen to scroll.
There is a nice trick to set both from BASIC:
Code: [Select]
CALL &BC06,&40
This works, because the address part of the firmware call SCR SET OFFSET (&BC05) is used as code:
Code: [Select]
&BC06 3C SCF
&BC07 8B ADC E,A
During the call, register A is the parameter count (1) and DE is the last parameter value (&40). After SCF and ADC A,E , register A contains &42 (only b6,b7 are relevant), which is used the set the base address with SCR SET BASE (&BC08). This works also with parameter &C0.