Odd - Interesting - Forgotten

Anything QL Software or Programming Related.
Derek_Stewart
Font of All Knowledge
Posts: 4762
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: Odd - Interesting - Forgotten

Post by Derek_Stewart »

bwinkel67 wrote: Sat Jan 11, 2025 8:47 am
Derek_Stewart wrote: Sat Jan 11, 2025 7:01 am Minerva can do all this, it can enable te Second Screen, (VRAM2), move System Variables and has fast memory move vectors. Just read the Minerva manual.
So you are saying QDOS cannot do this?
Yes.

Minerva can enable the Second Screen at start screen pressing F3/F4 and the System Variables are moved up the memory map 32K.

Minerva introduces assembler extensions, vector MMOVE detailed on page 45/45 Minerva Manual.

I wrote a routine to copy SCR0 to SCR1 in assembler using this Vector.


Regards,

Derek
User avatar
bwinkel67
QL Wafer Drive
Posts: 1541
Joined: Thu Oct 03, 2019 2:09 am

Re: Odd - Interesting - Forgotten

Post by bwinkel67 »

dex wrote: Sat Jan 11, 2025 1:27 pm But previous QDOS versions are not taking second VideoRAM into consideration, although it is implemented in hardware.
Minerva can move system variables and make the VRAM2 area free for the user.

That’s why Omega!s routine (QDOS compatible) does things to make the VRAM2 free, like …
1) Start supervisor mode, disable interrupt
2) Move 32k of the system variables from $28000 to ram (at the end of the routine).

8) Restore system variables
9) Return to QDOS.
I think I understand now how he's using the second screen. I'm guessing the heap is on the other end of the memory map so if there is enough memory, that heap area, containing the INIT22_ASM code and the two screens never gets corrupted. When he puts 32K of a second screen at $28000 (the part in your above outline which happens in "..."), it all works because he first saves that 32K at $28000 to memory allocated in the heap after pausing the system, runs his code to do the two screen meshing, and upon exiting his code restores that 32K at $28000 all back as if nothing ever happened and the system resumes running. So any memory that got corrupted along the way gets uncrorrupted when writing it back. If there's not enough memory (i.e. a 128K machine only has about 80K or so free, and even in my reduced version where I only take up 64k+ for two screens and use one to hold the 32K info at $28000, there's only about 16K free and so when writing the second 32K screen to $28000, that operation actually overwrites its own code, corrupting the actual INIT22_ASM routine and the system crashes.

I think I can make this work in 128K. I load the first screen directly into 131072 from MDV, so I don't need to set that memory aside in the heap and only allocate $32K + 2K leaving me about 46K free (32K of which is needed for the second screen at $28000). Then I just need to swap the second screen with what's at $28000. So I could use a small buffer to do that (say 16x using a 2K buffer), or worse, just swap it byte-for-byte which might make the setup, until it does the color combining, a bit slower.


User avatar
bwinkel67
QL Wafer Drive
Posts: 1541
Joined: Thu Oct 03, 2019 2:09 am

Re: Odd - Interesting - Forgotten

Post by bwinkel67 »

I haven't done very much Motorola 68K assembly (I did a bunch of Z80 in the 80s). The code to copy the image from memory to either $20000 or $28000 does the following, where d0 holds $8000 and a0 an a0 hold the source and destination addresses:

Code: Select all

ldir	move.b	(a0)+,(a1)+
	dbra	d0,ldir
	rts		
Is there an easy way to turn this into a swap routine. Would this work?

Code: Select all

ldir	move.b	(a0),a2
        move.b	(a1),(a0)+
        move.b	a2,(a1)+
	dbra	d0,ldir
	rts		
I just typed it in this forum post using my surface which is not set up to run an emulator.


User avatar
M68008
Gold Card
Posts: 275
Joined: Sat Jan 29, 2011 1:55 am
Contact:

Re: Odd - Interesting - Forgotten

Post by M68008 »

It would work, but use d2 instead of a2 as address registers don't to byte operations.
Even better, if you change everything to .l and divide the counter by 4 it will move 4 bytes at a time and run faster.


User avatar
M68008
Gold Card
Posts: 275
Joined: Sat Jan 29, 2011 1:55 am
Contact:

Re: Odd - Interesting - Forgotten

Post by M68008 »

Also counter needs to be decremented by one if you enter the loop from the top:

Code: Select all

    move.w  #$1FFF,d0
ldir
    move.l  (a0),d2
    move.l  (a1),(a0)+
    move.l  d2,(a1)+
    dbra    d0,ldir
    rts


User avatar
bwinkel67
QL Wafer Drive
Posts: 1541
Joined: Thu Oct 03, 2019 2:09 am

Re: Odd - Interesting - Forgotten

Post by bwinkel67 »

Oh, thank you. Mine gave me errors so I set a2 to point to end of code snippet where there's about 1K buffer of bytes before you hit the image data. Yours is much cleaner so I'll fix it all up at one point:

Code: Select all

swap	move.b	(a0),(a2)
        move.b	(a1),(a0)+
        move.b	(a2),(a1)+
	dbra	d0,swap
	rts		
But it all works. Attached is the modified code that only uses 34K of reserved space and along with the second screen starting at $28000, which uses 32K, it all totals to 68K when running, plenty of space for a 128K BBQL.

DITHVIDE.zip
(164.87 KiB) Downloaded 35 times

So the BOOT file now only stores one file and directly loads in the other file and then calls the code:

Code: Select all

10 REMark Hi Resolution Demo
15 MODE 8: INPUT #0, "Device? "; dev$
20 :
25 code_size=2048
30 a=RESPR(code_size+32768)
35 scr=a+code_size
40 PRINT "Address ",a
45 :
50 DIR dev$&"_dvd":INPUT #0, "Enter pic name, exclude #_dvd? ";a$
55 INPUT #0, "Enter: lores, hires, mixed? ";type$
60 LBYTES dev$&a$&"1_dvd",scr
65 LBYTES dev$&a$&"2_dvd",131072
70 LBYTES dev$&type$&"_bin",a: CALL a
75 MODE 8: GO TO 50
Here's the new assembly -- this one generates mixed_bin, but all you need to do is change where it calls from mixed to hires or lores and re-assemble (that's what the DITHVIDE.MDV is for):

Code: Select all

*       dithVide for Sinclair QL
* /interrupt handler in supervisor mode/
*   (C) Omega 2006 (omega.webnode.com)

nm_frms		EQU	900
nm_lins		EQU	$0fa
ln_wait		EQU	$0006
bg_wait		EQU	$02d7	2e6
sv.plist	EQU	$3c	offset, frame linked list 2803c
sv.pcint	EQU	$35	copy of system interrupt
pc_intr		EQU	$18021	interrupt hw status register
mc_stat		EQU	$18063	master chip settings
screen1		EQU	$20000
screen2		EQU	$28000
*			bit 1	- screen off (1)
*			bit 3	- lores (1), hires (0)
*			bit 6	- (0) PAL, (1) NTSC
*			bit 7	- (0) VRAM starts $20000, (1) $28000

; save registers
; goto supervisor mode
start	trap	#0
	movem.l	d0-d7/a0-a6,-(a7)
; disable interrupt
	ori	#$0700,sr

	lea	ssvsp,a0
	move.l	sp,(a0)		save stack
	
	move.b	#$80,mc_stat	switch to 2nd vram, hires
	lea	stack,sp	new stack address
	move.l	#$28000,a6	sys_vars
	lea	frames,a0
	move.w	#nm_frms,(a0)

; compute memory start for images
	lea	start,a0
	add.l	#2048,a0	add code_size in basic
	
; swap image with vram2
	move.l	#screen2,a1	addr of vram2
        lea     screen,a2
	move.w	#$8000,d0
	jsr	swap
	
;	jsr	clscr

	lea	flipper,a0	address of vector
	lea	mixed,a2	address of routine
	move.l	a2,4(a0)	save routine address to vector
	move.l	a0,$2803c	save vector address to sv.plist

	andi.w	#$f8ff,sr	ei (enable interrupt)
	
loop	jmp	loop
	
exit	ori.w	#$0700,sr	di
	movem.l	(a7)+,a0	restore stack
	
; restore system variables
	move.l	a6,a1
        lea	start,a0
        add.l	#2048,a0
	move.l	#$8000,d0
	jsr	ldir

	move.b	#0,mc_stat	switch to screen1, hires
; exit
	lea	ssvsp,a0
	move.l	(a0),sp		restore stack
	movem.l	(a7)+,d0-d7/a0-a6
	moveq	#0,d0		return no error
	move.w	#$0800,sr	user mode, EI
	rts

; clear both screens
clscr	move.l	#$8000,d0
	move.b	#$ff,d1
	jsr	clmemb
	move.l	#$8000,d0
	move.b	#0,d1
	jsr	clmemb

; ldir (memory move routine) slow
; a0 - from / a1 - to / d0 - size
ldir	move.b	(a0)+,(a1)+
	dbra	d0,ldir
	rts		

; swap (memory swap routine) slow
; a0 - from / a1 - to / a2 - screen / d0 - size
swap    move.b	(a0),(a2)
        move.b  (a1),(a0)+
        move.b  (a2),(a1)+
        dbra	d0,swap
        rts

; clmemb (clear mem) slow
; a0 - where / d0 - size / d1 - with what
clmemb	move.b	d1,(a0)+
	dbra	d0,clmemb
	rts

flipper:
	dc.l	0,0
lores:
	movem.l	d0-d7/a0,-(a7)
	lea	vram_l,a0
	eor.b	#$80,(a0)
	move.b	(a0),mc_stat
	lea	frames,a0
	subi.w	#01,(a0)
	movem.l	(a7)+,d0-d7/a0
	beq	exit
	rts

hires:
	movem.l	d0-d7/a0,-(a7)
	lea	vram_h,a0
	eor.b	#$80,(a0)
	move.b	(a0),mc_stat
	lea	frames,a0
	subi.w	#01,(a0)
	movem.l	(a7)+,d0-d7/a0
	beq	exit
	rts

mixed:
	movem.l	d0-d4/a0,-(a7)
	move.b	#%00000010,mc_stat	screen off
	lea	vram_m,a0
	move.b	(a0),d0
	move.b	#%10001000,d1
	move.w	#bg_wait,d4
bg_wlp	dbra	d4,bg_wlp
	move.w	#nm_lins,d2
nm_llp	move.w	#ln_wait,d3
	move.b	d0,mc_stat
	eor.b	d1,d0
ln_wlp	dbra	d3,ln_wlp
	nop
	nop
	nop
	nop
	dbra	d2,nm_llp
	eor.b	d1,(a0)
	lea	frames,a0
	subi.w	#01,(a0)
	movem.l	(a7)+,d0-d4/a0
	beq	exit
	rts

modes	dc.l	0		lores
	dc.l	0		hires
	dc.l	0		mixed
frames	dc.w	0
vram_l	dc.b	%00001000	ram 0 lores
vram_m	dc.b	%00000000	ram 0 hires
vram_h	dc.b	%10000000	ram 0 hires
ssvsp	dc.l	0
	ds.b	$0200
stack	
screen


User avatar
bwinkel67
QL Wafer Drive
Posts: 1541
Joined: Thu Oct 03, 2019 2:09 am

Re: Odd - Interesting - Forgotten

Post by bwinkel67 »

Could Q-emuLator's screen code be written for this technique to work? Or is it impossible to align with the host machine's screen since I'm guessing system calls are needed.


Derek_Stewart
Font of All Knowledge
Posts: 4762
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: Odd - Interesting - Forgotten

Post by Derek_Stewart »

Hi

Why not use the QDOS definitions in the assembler package you just need to include the definition file.

Doing this with QDOS is hard, when Minerva has all the pre-written routine. Because if you use $28000, which where the System Variables start a routine to move the System Variables will be required, then tell QDOS that you moved them to another address.

Or just allocate 32k of ram to copy the screen. Leaving the System Variables alone.


Regards,

Derek
User avatar
tofro
Font of All Knowledge
Posts: 3131
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Odd - Interesting - Forgotten

Post by tofro »

Derek_Stewart wrote: Sun Jan 12, 2025 12:04 pm Hi

Why not use the QDOS definitions in the assembler package you just need to include the definition file.

Doing this with QDOS is hard, when Minerva has all the pre-written routine. Because if you use $28000, which where the System Variables start a routine to move the System Variables will be required, then tell QDOS that you moved them to another address.

Or just allocate 32k of ram to copy the screen. Leaving the System Variables alone.
QDOS, unlike Minerva, can't live with system variables anywhere else but where they belong. The address is hard-coded in a lot of places.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Derek_Stewart
Font of All Knowledge
Posts: 4762
Joined: Mon Dec 20, 2010 11:40 am
Location: Sunny Runcorn, Cheshire, UK

Re: Odd - Interesting - Forgotten

Post by Derek_Stewart »

so the only to do this in QDOS is leave thd Systdm Variable slone and use an allocated 32K of memory for the copy of the screen memory.


Regards,

Derek
Post Reply