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 :-/
Request : Demos for Jasmin
Dbug wrote:Oula, oula.
That's what I understood.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.
(By the way, I just realised, there are two n°25 Thoric issues November 1986 and December 1986 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)
Well, it looks like "Impossible Mission",at least, you have some stuff here for future demos.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.
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
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
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
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.
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:
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:
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.
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_
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
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.