Request : Demos for Jasmin

Want to discuss about Demos on the Oric, here you are !
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

Oula, oula.

Forget about Ftdos, forget about Sedoric, the point of using the disc drive in the demo is also to get 16 additional kilobytes. The only demo that uses Sedoric to load the data is first megademo we made, the one without sound and loads slowly :)

All that is required is a "load sector" routine which does it all by itself, without requiring any pre-existing stuff.

The problem is of course that the source code of all parts of the megademo is not available, so it's not possible to rebuild the full demo. So we need to patch the existing stuff.

The problem is of course to know if it's possible to keep the existing sector lay-out, in this case what would need to be done is:
- Get a Jasmin friendly boot sector
- Rewrite the loader

Done :)

I don't remember if the Jasmin and the Microdisc have their bootsectors located at the same location :-/
User avatar
waskol
Flight Lieutenant
Posts: 414
Joined: Wed Jun 13, 2007 8:20 pm
Location: FRANCE, Paris

Post by waskol »

Dbug wrote:Oula, oula.
:lol:
Dbug wrote: Forget about Ftdos, [...]

All that is required is a "load sector" routine which does it all by itself, without requiring any pre-existing stuff.
That's what I understood.
(By the way, I just realised, there are two n°25 Thoric issues November 1986 and December 1986 :lol: A typo error...)

The good clue for that is in Theoric n°26 (and not 25) :
there is a detail explanation of the Jasmin control registers
- #3F4 : command register (Read and Write),. The last bit gives the status of the controller (if it is 0, the controller is ready to receive a new command).
#3F7 : Data register It is the register that permits to send or receive some parameters after an instruction. (Etc...)
#3F6 : Sector number. Contains the sector number that will be treated
#3F5 : Track Number. Contains the track that has been read. Used only for Read operation.
#3F8 : Side Number (0 or 1)
#3FC : activation state of the 1st drive (1 if activated, 0 otherelse)
#3FD : activation state of the 2nd drive
#3FE : 3rd drive
#3FF : 4th drive

Here an example of how to put the drive head on a particular track :

1) Select the side : #3F8 <--- 0 or 1
2) Select the drive : #3FC <-- 1 ; #3FD to #3FF <-- 0
3) Rese the command register : #3F4 <-- 0
4) Put the head on the good track :
a) Select the track (data register) : #3F7 <-- 0
b) Put the head on the track... : #3F4 <-- #14 (that is the command for head displacement)
c)...wait until drive is ready again : until bit 0 of #3F4 equals 0
d)Then test the command register :
if bit 3 and 4 are both equal to 0, then it is a success
(PEEK(#3F4) AND #18=0)
else it failed, give it a try again from 1), 4 more times (if it failed 5 time, that means there is a communication problem)

Then, read a sector :
Once the head is on the good track and side
1) Select sector num : #3F6 <-- 0, 1, 2, 3, 4, ..., 17
2) Stop processor interupts : SEI
3) Stop VIA interrupts : asm sequence LDA #$7F / STA $030E
4) Read mode command : #3F4 <-- #88.
From this moment, as soon as interrupts are permitted again (CLI), at each interrupt, the controller sends one after the others, each of the 256 bytes of the sector and put them into the data register (#3F7).

In the thoric, they explain how to modify the IRQ management (there is a full asm listing provided).

The read operation terminates when the controller say itself available again (#3F4=0)
Dbug wrote: The problem is of course that the source code of all parts of the megademo is not available, so it's not possible to rebuild the full demo. So we need to patch the existing stuff.
Well, it looks like "Impossible Mission",at least, you have some stuff here for future demos. :wink:
Dbug wrote: The problem is of course to know if it's possible to keep the existing sector lay-out,

I would say yes, since with the method given, we can read Sedoric drives :wink:
A utility given in Theoric showed how to backup Sedoric files from the Jasmin (so there is a compaibility for access tracks/sectors at least for the floppy layout :wink:

Dbug wrote: in this case what would need to be done is:
- Get a Jasmin friendly boot sector
- Rewrite the loader

Done :)

Yep, but you are the only skilled here to be able to do that and figure out how to do it :lol:
Dbug wrote: I don't remember if the Jasmin and the Microdisc have their bootsectors located at the same location :-/

Have to check that this evening.
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

Here is the code of the boot-sector we are using in the demos. It contains first a relocator which moves the code to some known adress (here somewhere in the HIRES screen). The reason is that the Telestrat and the Oric/Atmos Microdisc eproms load the bootsector at different adresses. And doing fully adress relative code in 6502 is just a nighmare, so we decided instead to have full freedom in the way we write the code, and "move it" to the right place.

The idea is as follow:
- Bootsector is loaded *somewhere* in memory and then the system calls it
- The bootsector code relocates the _BEGIN_ to _END_ section somewhere at a known adress
- Then call this adress
- The code at this adress enable the overlay memory, and then loads the real loader from disk (which may be more than one sector long) somewhere in the overlay memory.

Here it is:

Code: Select all

#define FINAL_ADRESS $a000+50*40
;c000

_Reloc
;BreakPointjmp BreakPoint

     sei               ; No interruptions

     lda #$60     ; RTS Opcode
     sta $00          ; Write in $00 Page => take one less byte
LABEL=*+2
     jsr $0000     ; JSR on the RTS immediately return.
_BEGIN_COPY_
     tsx               ; Get stack offset
     dex
     clc
     lda $0100,x     ; Get LOW adress byte
     adc #<(_END_COPY_-_BEGIN_COPY_+1)
     sta $00
     lda $0101,x     ; Get HIGH adress byte
     adc #>(_END_COPY_-_BEGIN_COPY_+1)
     sta $01

     ; Now $00 and $01 contain the adress of LABEL
     ; We can now copy the whole code to it's new
     ; location
     ldy #0
copy_loop
     lda ($00),y
     sta FINAL_ADRESS,y
     iny
     cpy _END_-_BEGIN_
     bne copy_loop

     jmp FINAL_ADRESS
_END_COPY_


; Here is some code compiled at a fixed
; adress in memory.

     *=FINAL_ADRESS

_BEGIN_

/*                                  ICI loading du loader en RAM VIA le Boot sector      */

#include<vip4.h>


#define FDC_command	$0310
#define FDC_status	$0310
#define FDC_track	$0311
#define FDC_sector	$0312
#define FDC_data	$0313
#define MICRODISC	$0314

#define first_sect		17	; number of sectors before the progs on side 1
#define track_loader 0
#define sector_loader 5

;*=$b902
;Boot sector !!!
Initialize
;	sei ; IRQ déjà annulée en haut

_init_disk

	ldy #<(irq_handler)
	lda #>(irq_handler)
	sty $fffe
	sta $ffff

	lda #$7F
	sta $030D ; Lock VIA IRQ
/*VIP4 Boot sector !*/

load_prog
	lda #sector_loader ; First sector for the loader
	sta FDC_sector ; on set le secteur
	sta sect_low ; for count


loader
	lda #nb_sectors_loader ; nb of page à charger
	sta pages ; Fpor count
start_read
	jsr sectread
load_prog_ok
	sei
	lda #%10000001 ; Read finished stop FDC
	sta $0314
	jmp location_loader ; execute the prgm


/*Lecture************************************************************/

readlinsect


	ldx #track_loader ; We get the track of the loader
	cpx FDC_track ; Is it the current track ?

	beq set_sector ; Yes we set sector now !
	stx FDC_data ; On  force la track à changer

wait_drive2
	lda $318 ; We are waiting for the drive maybe not useful if drive is ready after the eprom boot
	bmi wait_drive2

	lda #$1F ; ordre de chgt de track
	sta FDC_command
	jsr wait_completion ; We are waiting for FDC


set_sector

	lda sect_low
	sta FDC_sector ; on set le secteur

	; Interdire les IRQ du fdc ICI !
	lda #%10000101 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
	sta MICRODISC



	lda #$80 ; Demande de lecture #80

command
	sta FDC_command

waitcommand_again
	ldy #wait_status_floppy
waitcommand
	nop ; Not useful but for old Floppy drive maybe
	nop ; Not useful but for old Floppy drive maybe
	dey

	bne waitcommand

readwrite_data

read_sector
	ldy #0
microdisc_read_data
	lda $0318
	bmi microdisc_read_data
	lda $0313
page_to_load
	sta location_loader,y
page_to_load2

	iny
	bne microdisc_read_data
	lda FDC_status
	and #$1C

	rts


/*Lecture du secteur !*/
sectread
	ldy #4
	sta retry
sectreadloop

readretryloop
	jsr readlinsect ; on lit le secteur
	beq sector_OK
	dec retry
	bne readretryloop
sector_OK
	inc sect_low ; on avance le ptr de secteur
	inc page_to_load+2
	dec pages
	bne sectreadloop

	rts

wait_completion
	ldy #4
r_wait_completion
	dey
	bne r_wait_completion
r2_wait_completion
	lda $0310
	lsr
	bcs r2_wait_completion
	asl
	rts

irq_handler
	pla		; get rid of IRQ context
	pla
	pla
	lda #%10000001
	sta $0314	; disables disk irq
	lda $0310	; gets status and resets irq
	and #$7c
	rts


sect_low
	.byt  0
pages
	.byt  0
retry
	.byt  0

_END_
I'm not sure of how large it is. Wonder if it's possible to add Jasmin loading code in it, or to patch the existing code to make it work both on Jasmin and Microdisc.

The loader code itself is here:

Code: Select all

#include "vip4.h"

#define FDC_command	$0310
#define FDC_status	$0310
#define FDC_track	$0311
#define FDC_sector	$0312
#define FDC_data	$0313
#define MICRODISC	$0314

*=location_loader



Initialize
	SEI ; Stop IRQ CPU
	lda #$7F ; Stop VIA interrupt
	sta $030D



/**********************************************************************************************************************/
/*                                                                       MAIN                                                                                                                          */
/**********************************************************************************************************************/


loader
	ldx #0 ; index of loader.cod table
	jsr begin_loading
	jsr execute


main_loop

	jmp main_loop ; We loop else it crash


/**********************************************************************************************************************/
/*                                                                       FIN_MAIN                                                                                                                  */
/**********************************************************************************************************************/



/**********************************************************************************************************************/
/*                                                                       LECTURE                                                                                                                    */
/**********************************************************************************************************************/



/*Lecture************************************************************/

readlinsect
	lda current_sector

	cmp #18 ; On a dépassé une piste
	bne s_set_sector

	inc current_track ; oui on augmente la track

	lda #1 ; on remet à zéro le secteur à un ?
	sta current_sector


s_set_sector

	lda current_track

	sec
	sbc #128 ; On change de face ?
	bmi stay_on_the_good_side
	lda #%00010000
	sta current_side ; We change the side into 2 !
	lda #0
	sta current_track ; now we are in track 0 side 2 !
	lda #1
	sta current_sector

stay_on_the_good_side
	lda current_sector
	sta FDC_sector
	inc current_sector



	lda current_track
	cmp  FDC_track ; On regarde si on est bien sur la bonne piste

	beq stay_on_the_track


	sta	FDC_data ;on set la piste


	lda #$1F ; ordre de chgt de track
	sta FDC_command

	jsr wait_completion

	lda #%10000101 ; on force les le Microdisk en side0, drive A ... Set le bit de données !!!
	ora current_side
	sta MICRODISC

stay_on_the_track
	lda #$80
command
	sta FDC_command


waitcommand_again
	ldy #wait_status_floppy
waitcommand
	nop
	nop
	dey
	bne waitcommand



readbyte
	ldy #0
microdisc_read_data
	lda $0318
        bmi microdisc_read_data
	lda $313
page_to_load
	sta $c000,y
	iny
	bne microdisc_read_data

	lda FDC_status
	and #$1C

	rts



/*On inite !*/


irq_handler
	pla		; get rid of IRQ context
	pla
	pla
	lda #%10000101
	ora current_side
	sta $0314	; disables disk irq
	lda $0310	; gets status and resets irq
	rts

/*Lecture du secteur !*/

start_read



sectreadloop
	jsr readlinsect
	inc page_to_load+2
	dec pages
	bne sectreadloop
	rts

begin_loading

	sei
	lda #$7F ; We stop irq
	sta $030D

	ldy #<irq_handler ; Set irq handler
	lda #>irq_handler
        sty $fffe
	sta $ffff

	;X contains the program to load !
	lda adresse_chargement_high,x
	sta execute+2 ; set high adress (Execute)
	sta page_to_load+2 ; on inite l'adresse de chargement

	lda adresse_chargement_low,x
	sta execute+1
	sta page_to_load+1 ; on inite l'adresse de chargement


	lda #0 ; We go to side 0
	sta current_side

	lda datas_piste,x
	sta temp

	sec
	sbc #128 ; Is it the 2nd side ?
	bmi  good_side ; No we are in side 1
	sta temp

	lda #%00010000 ; We set the second side b4==16
	sta current_side

good_side
	lda temp
	sta current_track

	lda datas_secteur,x
	sta current_sector

	lda nombre_secteur,x ; nb of page à charger
	sta pages
	jsr start_read

	lda #$84
 	ora current_side
	sta $0314

	rts
execute
	jsr $a000 ; will change when the first loading is done
	rts



/**********************************************************************************************************************/
/*                                                                       FIN_LECTURE                                                                                                            */
/**********************************************************************************************************************/





wait_completion
	ldy #4
r_wait_completion
	dey
	bne r_wait_completion
r2_wait_completion
	lda $0310
	lsr
	bcs r2_wait_completion
	asl
	rts



#include<loader.cod>
pages
	.byt  0
temp
	.byt 0
current_track
	.byt 0
current_sector
	.byt 0
current_side
	.byt 0
Have fun :)

Basically, if you can batch the bootsector and the loader, you should have a fully working jasmin demo. And most probably 99% of the code is identical in all our demos.
Post Reply