Does anyone have that, or know of any other RamWorks-style RAM drive software I may have missed?
> Matt
part of Glen Brendon's ProSEL
LST OFF
ORG $2000
TYP $FF
********************************
* *
* RAM.DRV.SYSTEM (type SYS) *
* Driver ProDOS carte Ram *
* RamWorks & Checkmate Tech *
* (c) Glen Bredon (Prosel-8) *
* Source by Deckard *
*
http://boutillon.free.fr *
* *
********************************
* Assembleur: Merlin-8 2.58 (ProDOS)
* Last update: 06 jul 2006
********************************
* Commandes MLI
QUIT = $65
GET_FILE_INFO = $C4
ONLINE = $C5
OPEN = $C8
READ = $CA
CLOSE = $CC
GET_EOF = $D1
* Page 0 main memory
* Parameters device driver
DRV_COMMAND EQU $42 ; command
DRV_BUFFL EQU $44 ; buffer low main mem pour read/write
DRV_BUFFH EQU $45 ; buffer high main mem pour read/write
DRV_BLKL EQU $46 ; block low @ lire ou {crire
DRV_BLKH EQU $47 ; block high @ lire ou {crire
* Ram princ
ONLINE_BUF EQU $0220 ; $0220-$022F Buffer MLI Online
BANK_OK EQU $248C ; $18 octets ($248C-$24A3) Liste des banks retenus
; pour le disk virtuel de ram. Cette liste est mov{e
; dans l'espace $FFBE-$FFD5 du driver ramdisk. Les
; num{ros des banks ne sont pas forc{ment
; chronologiques.
WRK_NB_LCK_BK EQU $24B9 ; zone de travail nombre de banks bloqu{s
LAST_BLK_LCK EQU $24BA ; borne dernier bank bloqu{
BANK_LST EQU $24BB ; $80 octets stockage des banks ($FF=bad bank)
; No locked banks in this buffer (excluded)
BANK_LST_ALL EQU $253B ; $80 octets stockage des banks ($FF=bad bank)
; all banks in this buffer (incl. locked banks)
SAV_BYTE_00 EQU $25BB ; sauvegarde des octets $00 des $80 banks
SAV_BYTE_01 EQU $263B ; sauvegarde des octets $01 des $80 banks
* Ram aux (1er bank aux valide diff{rent de bank $00)
RAM_BLK0002L EQU $0600 ; block 2 : volume dir
RAM_BLK0002H EQU $0700
RAM_BLK0003L EQU $0800 ; block 3 : volume dir
RAM_BLK0003H EQU $0900
RAM_BLK0004L EQU $0A00 ; block 4 : volume dir
RAM_BLK0004H EQU $0B00
RAM_BLK0005L EQU $0C00 ; block 5 : volume dir
RAM_BLK0005H EQU $0D00
RAM_BLK0006L EQU $0E00 ; block 6 : volume bitmap
RAM_BLK0006H EQU $0F00
RAM_BLK0007L EQU $1000 ; block 7 : adresse d{but des datas
* Adresses ProDOS
MLI EQU $BF00 ; appel MLI ProDOS
DEVADR01 EQU $BF10 ; d{but des devices addresses (slot 0, drive 1)
DEVADR32 EQU $BF26 ; addr device driver slot 3, drive 2 (/RAM)
DEVCNT EQU $BF31 ; Count (minus 1) of active devices
DEVLST EQU $BF32 ; List if active devices (Slot, drive, id =DSSSIIII)
DATE EQU $BF90 ; date/time sur 4 octets
* Softswitchs
_80STORE0 EQU $C000 ; utilise main/aux read/wrt
_80STORE1 EQU $C001 ; acc}s page affich
MAINREAD EQU $C002 ; lecture en m{moire principale
AUXREAD EQU $C003 ; lecture en ram aux
MAINWRT EQU $C004 ; {criture en main memory
AUXWRT EQU $C005 ; {criture en ram aux
MAINZP EQU $C008 ; page 0 main memory (ALTZP) + RAMDISK_DRV on
AUXZP EQU $C009 ; page 0 ram aux (ALTZP) + RAMDISK_DRV off
RZPSW EQU $C016 ; lecture {tat ALTZP - read zero page switch
R80ST EQU $C018 ; read 80STORE
BUTTN1 EQU $C062 ; touche pomme-ferm{e=closed-apple (option)
BANKSEL EQU $C073 ; bank switching selector (ramworks et compatibles)
; ou aussi appel{ bank select register.
********************************
H2000 JMP H20E1 ; jump start
*-------------------------------
* Ram driver parameters
*-------------------------------
HEX EEEE ; header id for launcher (used by Block.Warden)
DFB 64 ; length of pathname buffer
; you have to change the following label to use it
; with your own disk!
NEXT_SYS STR '/ABOUT.RAM/BASIC.SYSTEM'
DS 40,0
HEX FFFF ; borne butoire pathname buffer
; not used (because len=64 here)
NB_LOCKED_BK DFB 0 ; nbr de banks bloqu{s (pr{servation usage user)
; lock out how many 64k banks of ramcard memory
; YOU CAN CHANGE IT!!
MAP_SLOT_DRV DFB %00000011 ; (drive*8)-8 + slot -> drive 1, slot 3 (default)
; mapping slot and drive 0000DSSS
; D : 0=drive 1, 1=drive 2 / SSS=slot number
; YOU CAN CHANGE IT!!
********************************
* *
* Prise en compte du prochain *
* .SYS mentionn{ en dur *
* *
********************************
* Run next SYS program
HBD00
ORG $BD00
LDX NEXT_SYS ; longueur next SYSTEM
BEQ :2 ; pas de nom mentionn{
:1 LDA NEXT_SYS,X ; recopie du nom en page 2 (buffer clavier)
STA $0280,X
DEX
BPL :1
JSR MLI , r{cup}re les infos de cet objet
DFB GET_FILE_INFO
DA TBL_GET_F_I
BCS :2 ; err->quit
LDX FILE_TYPE ; $FF (=system)+1
INX
BNE :2 ; pas un type SYS
JSR MLI ; ouverture du SYS
DFB OPEN
DA TBL_OPEN
BCS :3 ; err->quit
LDA OPEN_NUM ; dispatch le num{ro du fichier
STA READ_NUM
STA GET_EOF_NUM
JSR MLI ; recherche fin du fichier SYS
DFB GET_EOF
DA TBL_GET_EOF
BCS :3
LDA EOF_POS+2 ; 3 octets de taille?
BNE :3 ; si oui, trop gros ->err
LDA EOF_POS+1 ; check taille high
CMP #>$9800 ; $2000+9800
BCS :3 ; encore trop long
STA READ_REQ_LEN+1 ; parm read
LDA EOF_POS
STA READ_REQ_LEN
JSR MLI ; charge le SYS en $2000
DFB READ
DA TBL_READ
BCS :3 ; err->quit
JSR MLI
DFB CLOSE
DA TBL_CLOSE
BCS :3 ; err->re-try close+quit
JMP $2000 ; lance du .SYSTEM
:3 JSR MLI ; passe la main
DFB CLOSE
DA TBL_CLOSE
:2 JSR MLI ; passe la main
DFB QUIT
DA TBL_QUIT
*-------------------------------
* Parameters Quit
TBL_QUIT DFB 4
DS 6,0
* Parameters Get File Info
TBL_GET_F_I DFB $0A
DA $0280
DFB 0
FILE_TYPE DFB 0 ; file type
DS 13,0
* Parameters Open
TBL_OPEN DFB $03
DA $0280
DA $1C00
OPEN_NUM DFB 0
* Parameters Close
TBL_CLOSE DFB 1
CLOSE_NUM DFB 0
* Parameters Read
TBL_READ DFB 4
READ_NUM DFB 0
DA $2000 ; adresse implantation
READ_REQ_LEN DS 2,0
DS 2,0
* Parameters Get Eof
TBL_GET_EOF DFB 2
GET_EOF_NUM DFB 0
EOF_POS DS 3,0
********************************
* *
* Point d'entr{e de RAM.DRV *
* *
********************************
ORG
; $20E1
*-------------------------------
* Reloge le code de chargement
* du prochain SYS en $BD00
*-------------------------------
H20E1 LDY #0
:1 LDA HBD00,Y
STA $BD00,Y
INY
BNE :1
*-------------------------------
* Get ram size
*-------------------------------
H20EC STA _80STORE0 ; utilise ramread/ramwrite
LDY #0
STY BANKSEL ; bank 0
STA AUXZP ; utilise page 0 aux
LDA #$FF ; init les 2 buffers de $80 octets avec les listes
H20F9 STA BANK_LST,Y ; des banks ($FF=bad bank) locked et all.
INY ; 2*$80 = $100
BNE H20F9
; Y=0
* Backup adresses $00/$01 de chaque bank
* car ces adresses sont {cras{es pour le test
; start: bank 0 aux ($00/$01 page 0 princ not saved)
H20FF STY BANKSEL ; enclenche bank Y
LDA $00 ; backup $00 addr in buffer
STA SAV_BYTE_00,Y
LDA $01 ; backup $01 addr in buffer
STA SAV_BYTE_01,Y
INY ; for $80 banks ($00-$7F)
BPL H20FF
* Pour tester si un bank est valide, on l'enclenche
* en {crivant son num{ro @ l'adresse sp{ciale $c073
* puis on {crit dedans @ un endroit particulier. Si la
* relecture au meme endroit donne le meme r{sultat,
* cela veut dire que le bank est ok. Ici le test est
* r{alis{ en page 0 sur les octets $00 et $01.
* Phase d'{criture
DEY ; Y=$7F
H2110 STY BANKSEL
STY $00 ; {crit le num{ro du bank dans $00 (page 0 aux)
TYA
EOR #$FF
STA $01 ; {crit le checksum (=num bank eor #$FF) dans $01
DEY ; pour $80-1 banks
BNE H2110 ; ne fait pas le bank 0 aux ici
; Y=0 : fait le bank 0 ici car il faut faire
; aux et princ
STY BANKSEL ; fait le bank 0 aux
STY $00
STY $01 ; no eor
STA MAINZP ; puis la page 0 princ
STY $00
STY $01 ; no eor
STA AUXZP ; repasse en page 0 aux
LDA NB_LOCKED_BK ; place le nb de banks bloqu{s dans la zone
STA WRK_NB_LCK_BK ; de travail qu'on d{cr{mentera @ fur et @ mesure
* Phase de lecture et controle r{sultat
LDY #1 ; skip bank 0 aux (pr{serv{)
H2136 STY BANKSEL ; enclenche bank Y
CPY $00 ; compare avec valeur stock{e pr{cedemment
BNE H2166 ; pas pareil -> bad bank
TYA
EOR #$FF
EOR $01 ; compare checksum avec valeur sauv{e
BNE H2166 ; pas pareil -> bad bank
CPY $00 ; check $00/$01
BNE H2166 ; toujours pas bon -> {carte ce bank aux
TYA ; signale que le bank est valide dans la liste ALL
STA BANK_LST_ALL,Y ; stockage num{ro
LDX WRK_NB_LCK_BK ; reste-il des banks bloqu{s?
BNE H2154 ; oui
STA LAST_BLK_LCK ; non -> set borne dernier bank bloqu{
H2154 DEC WRK_NB_LCK_BK ; un bank bloqu{ en moins
BPL H2166 ; il y en a encore
STA BANK_LST,Y ; sauve le bank dans la liste restreinte
* Recopie @ partir de $00B0 la routine RWRDB
* dans ce bank aux valide
LDX #$45
H215E LDA H2355-1,X
STA $B0-1,X
DEX
BNE H215E
H2166 INY ; passe au bank suivant
BPL H2136 ; fait banks aux $01 @ $7F
* Restauration des donn{es alt{r{es dans chaque bank
* aux valide aux addr $00 et $01
; Y=$80
H2169 LDA BANK_LST_ALL-1,Y ; bank valide (<$80)?
BMI H2180 ; non: bad bank ($FF)
CMP LAST_BLK_LCK ; est-ce la borne bank bloqu{?
BEQ H2180 ; oui, ne fait pas les restaurations
STA BANKSEL ; enclenche bank acc
LDA SAV_BYTE_00-1,Y ; restore addr $00 previously saved
STA $00
LDA SAV_BYTE_01-1,Y ; idem adr $01
STA $01
H2180 DEY ; bank pr{c{dant
BNE H2169 ; ne fait pas le bank 0 aux
; Y=0
STY BANKSEL ; enclenche bank 0
STY $00 ; marque le bank 0 aux
* R{cup}re la liste finale des banks valides
* pour avoir les num{ros regroup{s. On se restreint
* @ la liste des banks aux valides {ligibles.
LDX #$FF ; X -> $FF+1=0
H218A INX ; indice sur BANK_OK
CPX #$18 ; dernier bank accept{?
BCS H219C ; oui, on arrete l@ (>=)
; skip bank 0 aux
H218F INY ; bank suivant
BMI H219C ; fin car on vient de parcourir $80 banks
LDA BANK_LST,Y ; bank valide?
BMI H218F ; non ($FF)
STA BANK_OK,X ; ajoute @ la liste finale
BPL H218A ; toujours
* Calcul du nbr de blocks
* Nbr de bank * 128 (- 8 blocks tous les 8 banks en
* comman\ant d}s le 1er bank).
* Si 01 bank -> 1*128 - 8 blocks = 120 blocks total
* Si 02 banks -> 2*128 - 8 blocks = 248
* etc...
* Si 08 banks -> 8*128 - 8 blocks = 1016
* Si 09 banks -> 9*128 - 16 blocks = 1136
* etc...
* Si 24 banks -> 24*128 - 24 blocks = 3048
*
* Les blocks r{serv{s (par lot de 8) correspondent aux pages
* 0 et 1 (pile=stack) de chaque bank.
; X=nbr de banks dans la liste
H219C TXA ; nbr de blocks * 128
LSR
STA VOL_TOT_BLK+1 ; high
ROR VOL_TOT_BLK
STX HFF55+1 ; sauve nbr de banks valides
DEX
STX H239E ; sauve nbr de banks-1
BMI GO_QUIT ; aucun bank valide r{servable pour le ramdisk
LDA VOL_TOT_BLK ; -nb de bank
SEC
SBC HFF55+1
AND #%11111000
STA VOL_TOT_BLK ; low
STA RWB_ST_BLKL+1
BCS H21C1
DEC VOL_TOT_BLK+1 ; high
H21C1 LDA VOL_TOT_BLK+1
STA RWB_ST_BLKH+1
LDA BANK_OK ; positionne sur le 1er bank aux valide qui est
STA BANKSEL ; diff{rent du bank 0 aux.
LDA $00 ; check si un moins un bank. Bank 0 aux interdit.
BEQ GO_QUIT ; aucun bank! On s'arrete ici.
*-------------------------------
* Pr{paration volume /RAM
*-------------------------------
* Laisse une trace dans le 1er bank aux valide pour identifier
* le driver en place (signature avec nom de l'auteur!)
LDX #2 ; check signature bank aux
H21D3 LDA H23A0,X ; trigramme nom de l'auteur
CMP $06,X ; existe d{ja?
BNE H21EB ; pas encore sign{. Pr{paration du volume @ faire.
DEX ; caract}re suivant
BPL H21D3
; la signature est pr{sente. Donc normalement
; ce volume a d{ja {t{ formatt{ logiquement.
; N{anmoins, l'utilisateur peut demander @ forcer
; un reformattage. Teste la touche sp{ciale.
; X=$FF
BIT BUTTN1 ; test touche pomme-ferm{e=closed-apple (option)
BMI RAM_FORMAT ; oui, touche enfonc{e -> formattage demand{
JMP H2276 ; laisse en {tat et passe @ la suite.
GO_QUIT JMP RAMDISK_QUIT
H21E8 LDA H23A0,X ; set signature
H21EB STA $06,X ; page 0 1er bank aux valide de la liste
DEX
BPL H21E8
* Formattage du ram disk
RAM_FORMAT STA MAINZP
LDY #3 ; date/time volume
H21F5 LDA DATE,Y ; donn{e par la prodos system global page
STA VOL_DATETIME,Y
DEY
BPL H21F5 ; >=0
STA AUXWRT ; {criture bank aux
INY ; Y=0
TYA ; acc=0. Ecrase blocks 2 @ 6.
H2203 STA RAM_BLK0002L,Y
STA RAM_BLK0002H,Y
STA RAM_BLK0003L,Y
STA RAM_BLK0003H,Y
STA RAM_BLK0004L,Y
STA RAM_BLK0004H,Y
STA RAM_BLK0005L,Y
STA RAM_BLK0005H,Y
STA RAM_BLK0006L,Y
STA RAM_BLK0006H,Y
INY
BNE H2203
LDY #$2A ; copie infos volume sur block 2
H2226 LDA VOL_DIR_HEAD,Y
STA RAM_BLK0002L,Y
DEY
BPL H2226
* Effectue le chainage des blocks du volume dir
LDY #<$0002 ; previous block=2 on block 3
STY RAM_BLK0003L
INY
STY RAM_BLK0004L ; previous block=3 on block 4
INY
STY RAM_BLK0005L ; previous block=4 on block 5
STY RAM_BLK0003L+2 ; next block=4 on block 3
INY
STY RAM_BLK0004L+2 ; next block=5 on block 4
* Alimente la volume bitmap (block 6)
LDA VOL_TOT_BLK ; nbr de blocs * 8
STA $3C
LDA VOL_TOT_BLK+1
LSR
ROR $3C
LSR
ROR $3C
LSR
ROR $3C
CLC
ADC #>RAM_BLK0006L ; + adr d{but volume bitmap
STA $3D
LDY #0 ; au dela de l'espace des blocks du volume
TYA ; force les 8 blocks suivant @ l'{tat occup{
H225C STA ($3C),Y ; acc=0 (used) ou $FF (free)
LDA $3C ; octet de la volume bitmap pr{c{dant
SEC
SBC #$01
STA $3C
LDA #$FF ; 8 blocks libres
BCS H225C ; tout le reste est free
DEC $3D
LDX $3D
CPX #>RAM_BLK0006L
BCS H225C ; fait toute la volume bitmap en "free"
; pour finir:
LDA #%00000001 ; signale que les blocks 0 @ 6 sont bloqu{s dans
STA RAM_BLK0006L ; la volume bitmap.
; Vous noterez que rien n'a {t{ fait sur les blocks
; 0 et 1 de l'unit{ ramdisk
*-------------------------------
* Mise en place du driver
*-------------------------------
H2276 LDA #0
STA MAINWRT
STA MAINZP
STA BANKSEL ; bank 0 carte ram
BIT $C08B ; bank 1 -> utilise MEV (RAMDISK_DRV on)
BIT $C08B ; first bit: read allowed. Second bit: write allowed.
LDA #$D8 ; check 'CLD' (ID d{but driver)
CMP RAMDISK_DRV ; un driver d{ja en place? En MEV princ par d{faut
BEQ H229E ; oui
STA AUXZP ; MEV bank aux 0. Au cas o| le driver a {t{ mis
CMP RAMDISK_DRV ; en ram aux bank 0 pour une raison quelconque...
BEQ H229E ; oui. On garde page 0 aux et carte langage aux.
CMP $DE00 ; routine MLI main entry point en place en ram aux?
BEQ H229E ; oui
STA MAINZP ; recopie le driver en MEV princ
H229E LDY #0
H22A0 LDA H23CE,Y
STA RAMDISK_DRV,Y ; RAMDISK_DRV en carte langage
INY
CPY #$EB
BCC H22A0 ; si Y < #$EB
LDY DEVCNT ; recherche dans les devices actives le slot/drive
H22AE LDA DEVLST,Y ; d{fini pour le mapping du disk virtuel
LSR ; format device=DSSSIIII
LSR ; -> 0000DSSS
LSR
LSR
CMP MAP_SLOT_DRV ; est-ce cette device?
BEQ H22CC ; oui
DEY ; passe @ la device pr{c{dante
BPL H22AE
; la device n'est pas active
INC DEVCNT ; on l'ajoute @ la liste
LDY DEVCNT ; d{calage des devices pour inclure la nouvelle
H22C3 LDA DEVLST-1,Y
STA DEVLST,Y
DEY
BNE H22C3
; Y=0
H22CC LDA MAP_SLOT_DRV ; transforme 0000DSSS en DSSS0000
ASL ; D=0 -> drive 1, D=1 -> drive2
TAX ; x=device*2 (si S3 D1, X=6 -> DEVADR31)
ASL
ASL
ASL
STA ONLINE_NUM
ORA #%00001110 ; DSSS1110 -> 1110=no err sur la device
STA DEVLST,Y ; ajoute/modifie @ la liste des devices actives
LDA #<RAMDISK_DRV+1 ; pointeur driver pour cette device (skip CLD)
STA DEVADR01,X ; adr low driver
LDA #>RAMDISK_DRV+1
STA DEVADR01+1,X ; adr high driver
LDA MAP_SLOT_DRV
CMP #%00001011 ; slot 3, drive 2?
BEQ H2321 ; skip traitement slot 3 drive 2
* Traitement du slot 3, drive 2 : d{connection
* d'un driver RAM @ cet endroit
LDY DEVCNT ; recherche si cette device est active
H22F0 LDA DEVLST,Y
AND #%11110000 ; vire statut device
CMP #%10110000 ; slot 3, drive 2?
BEQ H22FE ; ok, found
DEY ; device pr{c{dante
BPL H22F0 ; pas fini
BMI H2321 ; branche toujours si not found
H22FE LDX DEVADR32+1 ; check driver ram en $FFxx
INX ; $FF+1=0
BNE H2321 ; pas un driver ram classique!
H2304 LDA DEVLST+1,Y ; supprime la device de la liste des actives
STA DEVLST,Y
INY
CPY DEVCNT
BCC H2304
BEQ H2304
DEC DEVCNT ; une device de moins
LDA DEVADR01 ; met la gestion de la device 0 @ la place
STA DEVADR32 ; low
LDA DEVADR01+1
STA DEVADR32+1 ; high
*-------------------------------
H2321 BIT $C082 ; lecture rom
JSR MLI ; recherche nom de ce volume @ partir de l'unit{
DFB ONLINE
DA TBL_ONLINE
LDX #0 ; check result
LDA ONLINE_BUF ; 1er octet buffer
ORA H239F
BNE RAMDISK_QUIT ; un caract}re trouv{ -> ok
BCC RAMDISK_QUIT ;
LDA #$FF ; anomalie ONLINE sur volume
STA H239F
STA AUXZP
LDA BANK_OK ; sur 1er bank valide
STA BANKSEL
STX $06 ; kill signature 1er bank aux valide
STX BANKSEL ; repasse sur bank 0 aux
STX VOL_TOT_BLK ; et nbr de blocks low
JMP H20EC ; remet le couvert...
*-------------------------------
* Lance le prochain SYS
*-------------------------------
RAMDISK_QUIT STA MAINZP
JMP $BD00 ; charge le prochain SYS
********************************
* *
* RWRDB *
* Read/Write RamDisk Block *
* Routine recopi{e dans chaque *
* bank aux valide en page 0 *
* (de $00B0 @ $00F4) *
* *
********************************
* Cette routine est exclusivement appel{e par
* CALL_RWRDB quand ce dernier est dans le buffer clavier
* en ram princ.
* In : carry = 1 : read
* carry = 0 : write
* Acc : high buffer ram princ
* X : low buffer ram princ
* Y : adr high ram aux d{but datas
*
* Out: Y = 0 : always
* carry = 0 : always
* N = 0 : req. ZP princ
* N = 1 : req. ZP aux
H2355
ORG $00B0
RWRDB
STA H00DE+2 ; sta high d{but adr ram princ
BCS H00B7 ; si read
STY H00DE+2 ; sta high d{but adr ram aux si write
TAY ; inverse de read
H00B7 LDA #0
STA AUXWRT
BCC H00C7 ; write -> {criture bank aux
TXA ; read -> lecture bank aux, {criture main mem
LDX #0
STA MAINWRT ; read: les donn{es vont de /ram vers la main mem
STA AUXREAD
H00C7 STY H00DB+2 ; lda high d{but block
INY
STY H00E1+2 ; lda high fin block
STA H00DE+1 ; sta low d{but block
STA H00E4+1 ; sta low fin block
STX H00DB+1 ; lda low d{but block
STX H00E1+1 ; lda low fin block
LDY H00DE+2 ; sta high
INY
STY H00E4+2 ; sta
* Effectue le read ou le write
LDY #0
H00DB LDA RAM_BLK0007L,Y ; LDA $??00,Y d{but block
H00DE STA RAM_BLK0007L,Y ; STA $????,Y
H00E1 LDA RAM_BLK0007L,Y ; LDA $??00,Y fin block
H00E4 STA RAM_BLK0007L,Y ; STA $????,Y
INY
BNE H00DB
; Y=0
STA MAINWRT ; {criture en princ
STA MAINREAD ; lecture en princ
CLC
BIT SAVE_ALTZP ; N=1 si ZP aux, N=0 si ZP princ
RTS
ORG $239A ; ORG alone -> BUG in generated code (bad ref addrs!)
*-------------------------------
* Parameters Online
TBL_ONLINE DFB 2
ONLINE_NUM DFB %00110000 ; unit %DSSS0000
DA ONLINE_BUF ; 16 octets $0220-022F
*-------------------------------
H239E DFB 0 ; nbr de banks valides-1
H239F DFB 0 ; pour ORA sur 1er caract}re buff r{sultat Online
* Signature en page 0 1er bank aux valide ($06/$07/$08)
H23A0 ASC "G" ; Glen
ASC "E" ; E.
ASC "B" ; Bredon
*-------------------------------
* Volume directory header
VOL_DIR_HEAD DA $0000 ; no previous dir block
DA $0003 ; next dir bloc
DFB %11110011 ; 4 first bits = $F = vol dir header id
; 4 last bits = $3 = volume name length
ASC 'RAM' ; volume name
DS 12,0 ; compl{ment nom pour 15 caract}res
DS 8,0 ; not used
VOL_DATETIME DS 4,0 ; creation date/time
DFB 1 ; version
DFB 0 ; min version
DFB %11000011 ; access: destroy/rename/write/read
HEX 27 ; lenght of each entry in bytes ($27 = standard)
HEX 0D ; entries per block ($0D = standard)
DA $0000 ; file count
DA $0006 ; bit map pointer (block 6)
VOL_TOT_BLK DFB 0,0 ; total block low/high
********************************
* *
* Driver RamDisk *
* recopi{ en MEV princ dans le *
* banc commut{ en $FF00-$FFEA *
* *
********************************
* Commande STATUS
* ---------------
* In : DRV_COMMAND : 00 (commande)
*
* Out: X : blocks dispos low
* Y : blocks dispos high
* carry : 0 (always) -> no err
* acc : 0 (always) -> no err
*
* Commande FORMAT
* ---------------
* In : DRV_COMMAND : 03 (commande)
*
* Out: carry : 0 (always) -> no err
* acc : 0 (always) -> no err
*
* Commandes READ/WRITE
* --------------------
* In : DRV_COMMAND : 01 (read) or 02 (write)
* DRV_BUFFL : low buffer implantation block
* DRV_BUFFH : high buffer
* DRV_BLKL : low block ProDOS 512 octets
* DRV_BLKH : high block ProDOS 512 octets
*
* Out: carry : 0 (no err) or 1 (err -> see acc)
* acc : 0 (no err) or $27 (I/O err)
H23CE
ORG $FF00
RAMDISK_DRV
CLD ; valid driver for BI
LDA DRV_COMMAND ; commande status?
BNE HFF0C ; non
ORG
*-------------------------------
* Commande : Status
*-------------------------------
* Retourne la taille calcul{e lors du formattage
; acc=0=no err
RWB_ST_BLKL LDX #$00 ; blocks dispos low
RWB_ST_BLKH LDY #$00 ; blocks dispos high
ORG $FF09
HFF09 CLC ; no err
BCC HFF83 ; toujours ->fin
*-------------------------------
* Commande : Format (NO EFFECT)
*-------------------------------
HFF0C CMP #$03 ; commande format?
BEQ HFF09 ; oui. Mais pas autoris{e sur le ramdisk
; carry=0 si commande 1 (read) ou 2 (write)
; carry=1 pour autres valeurs
*-------------------------------
HFF10 LDA #$27 ; I/O err
BCS HFF87 ; si commande > 3
*-------------------------------
* Commandes : Read / Write
*-------------------------------
* Sauvegarde avant utilisation
LDA R80ST ; m{morise {tat 80STORE
PHA
STA _80STORE0 ; utilise ramread/ramwrite
LDA $40 ; sauvegarde octets utilis{s page
PHA
LDA $41
PHA
LDA DRV_BUFFL ; ($40) pointe sur dernier 256 octets buffer ram
STA $40 ; princ pour la phase de swap buffer s'il n'est
LDX DRV_BUFFH ; pas bon
INX
STX $41
JSR CHECK_BUFFH ; routine copie CALL_RWRDB dans buffer clavier et
; check buffer high block
STX H02D3+1 ; met en place LDA#>buffer dans CALL_RWRDB
LDA RZPSW ; store {tat ALTZP (page 0 princ ou aux)
STA SAVE_ALTZP
LDA DRV_BLKH ; sauve block high
PHA
TAX ; X=block high
* Routine tr}s importante!!!!
* A partir d'un num{ro de block, calcule l'adresse en ram
* o| se trouvent les datas et le bank @ s{lectionner.
* Commute aussi la MEV et le bank de 4k si c'est cette
* partie qui est concern{e.
; Y=0
LDA DRV_BLKL ; enl}ve $7F blocks, c'est @ dire le nbr de blocks
HFF3C SEC ; contenus dans un bank
HFF3D INY ; on n'oublie pas qu'il faut prendre en compte le
SBC #$7F ; fait que le block 0 commence @ $0200
BCS HFF3D
DEX ; block high-1
BPL HFF3C
; carry=0
TYA ; ajout pour calc adresse
ADC DRV_BLKL
BCC HFF4C
INC DRV_BLKH
HFF4C ASL ; block restant * 2 = adresse
TAY ; dans Y
LDA DRV_BLKH
ROL
TAX ; num{ro bank
PLA ; restaure block high
STA DRV_BLKH
ORG
HFF55 CPX #$00 ; compare avec nbr de banks valides
ORG $FF57
BCS HFF74 ; trop grand -> reswap et I/O err
TYA ; examine adresse high
SBC #>$BF00
CMP #>$1000 ; banc commut{ 2 4k?
BCS HFF66 ; non
ADC #>$D000 ; skip $C000-$CFFF
TAY
BIT $C083 ; bank 2 4k MEV (read)
; Y=adr mem high
; X=bank @ prendre
HFF66 LDA DRV_COMMAND
LSR ; carry=cmd (=1 pour read, =0 pour write)
LDA RWB_RAM_BK,X
LDX DRV_BUFFL
JSR CALL_RWRDB ; lance les op{rations d'E/S
BIT $C08B ; bank 1 4k MEV (read)
HFF74 JSR CHECK_BUFFH ; remet la situation initiale en place dans le
; buffer clavier
* Restaure les valeurs alt{r{es
PLA ; octets page 0
STA $41
PLA
STA $40
PLA ; restaure {tat 80STORE
BPL HFF83 ; ok d{ja usage ramread/ramwrite
STA _80STORE1 ; acc}s page affichage
*-------------------------------
HFF83 LDA #0 ; no err
BCS HFF10 ; I/O err
; carry=0
HFF87 RTS ; end no err
*-------------------------------
* Swap routine appel RWRDB et
* contenu espace buffer clavier
* et check adr high buffer
*-------------------------------
* Il faudra 2 appels de cette routine:
* 1 pour mettre en place la routine en $02D0
* + backup buffer clavier
* 1 pour remettre la situation initiale
* In : DRV_BUFFH = buffer high main memory
* DRV_BUFFL = buffer low
* ($40) = pointe sur les 256 derniers octets buffer
*
* Out: X = buffer high ram princ valid{
* Y = 0 (always)
*
* carry n'est pas alt{r{e
CHECK_BUFFH
LDY #$15 ; met en place $02D0-$02E4 en ram princ dans le
HFF8A LDX HFFD6-1,Y ; buffer clavier et en meme temps sauve le contenu
LDA CALL_RWRDB-1,Y ; de ce dernier @ la place du code d{plac{.
STA HFFD6-1,Y
TXA
STA CALL_RWRDB-1,Y
DEY
BNE HFF8A
* Il est interdit d'utiliser l'espace >= $BC00
* comme buffer. Si dans l'espace interdit, alors force
* le buffer sur $8000-$81FF.
; Y=0. Default X=buffer high demand{
LDX DRV_BUFFH ; si buffer < $80xx
BPL HFFBD ; buffer high ok
; >=$8000
BIT DRV_BUFFH ; si buffer < $BCxx
BVC HFFBD ; V=0 : buffer ok
HFFA2 LDX $8000,Y ; swap contenu buffer demand{ avec buffer
LDA (DRV_BUFFL),Y ; autoris{
STA $8000,Y ; buffer d{but block
TXA
STA (DRV_BUFFL),Y
LDX $8100,Y ; buffer fin block
LDA ($40),Y
STA $8100,Y
TXA
STA ($40),Y
INY
BNE HFFA2
; Y=0
LDX #>$8000 ; force buffer $8000
HFFBD RTS
*-------------------------------
RWB_RAM_BK DS $18,0 ; $FFBE-$FFD5 (et $248C-$24A3) : liste des banks
; valides s{lectionn{s.
********************************
* *
* Routine d'appel de RWRDB *
* stock{e dans buffer clavier *
* de la ram princ *
* *
********************************
* In : carry = 1 read
* carry = 0 write
* acc = bank aux @ commuter
* Y = adr high ram aux d{but datas
* X = adr low buffer valide ram princ
* $02D3+1 = adr high buffer valide ram princ
HFFD6
ORG $02D0
CALL_RWRDB
STA BANKSEL ; enclenche bank = acc
H02D3 LDA #0 ; LDA#>buffer ram princ
STA AUXZP ; carte langage main mem off (RAMDISK_DRV off)
; et RWRDB bank aux on (page 0 bank aux on)
JSR RWRDB ; passe par la routine en page 0 aux
; Y=0
STY BANKSEL ; bank 0
BMI :1 ; N=1 -> keep ZP aux (cas sp{cial driver en bank 0
; aux)
STA MAINZP ; RAMDISK_DRV on et page 0 ram princ
:1 RTS
SAVE_ALTZP DFB 0 ; sauvegarde switch page 0 (princ ou aux)
; $02E4
SAV RAM.DRV.TST