CALL Implementation
An installation routine for CALL commands; works on any MSX, with RAM on subslots or not (in portuguese).
;
; Rotina de instalacao de modulo CALL para MSX
; (c) 1997 A&L Software
;
; Esta rotina funciona em qualquer MSX com RAM em qualquer slot
;
; Entrada : HL - inicio do programa CALL (destino: pagina 1, 4000h)
; BC - tamanho do programa a ser instalado
; Saida : A - 255 - falha na instalacao (sem RAM???)
; A - 000 - programa instalado com sucesso
; Modifica: todos os registradores
;
; Observacao:
; Se o seu programa invadir a pagina 1 (onde sera' instalado o modulo
; CALL) voce^ devera' modificar a rotina de relocacao (INSTR).
;
; Esta rotina pode ser copiada e modificada livremente
;
exptbl equ 0fcc1h
rdslt equ 000ch
wrslt equ 0014h
enaslt equ 0024h
caltab equ 0fcc9h
start: push hl
push bc
call findram ; Procura RAM
cp 255
jr z,noram
ld c,a
ld hl,caltab ; Tabela de slots do MSX
and 00000011b ; Slot primario
or a
jr z,fndsec
ld de,16
ld b,a
loppri: add hl,de
djnz loppri
fndsec: ld a,c ; Slot secundario
and 00001100b
srl a
srl a
or a
jr z,instc
ld de,4
ld b,a
lopsec: add hl,de
djnz lopsec
instc: inc hl ; Pagina 1
ld a,(hl)
set 5,a ; Seta CALL
ld (hl),a
instr: in a,(0a8h) ; Move rotina
ld (atuslt),a
ld a,(slot2)
ld hl,4000h
call enaslt
pop bc
pop hl
ld de,4000h
ldir
di
ld a,(atuslt)
out (0a8h),a
ei
xor a
ret ; Sai
noram: pop bc
pop hl
ret
findram:di ; Procura RAM no sistema
in a,(0a8h)
ld (conf),a
xor a
ld hl,exptbl
ld b,4
loop1: ld (slot1),a
ld (slot2),a
bit 7,(hl)
jr nz,sec
call test
jr c,endsr
loop1_1:inc hl
ld a,(slot1)
inc a
djnz loop1
notfnd: ld a,0ffh
jr endsr_1
endsr: ld a,(slot2)
endsr_1:ld b,a
ld a,(conf)
out (0a8h),a
ld a,b
ei
ret
sec: push bc
push hl
ld e,0
ld b,4
sec_1: ld a,e
rla
rla
and 00001100b
ld c,a
ld a,(slot1)
and 00000011b
or c
set 7,a
ld (slot2),a
call test
jr c,sec_2
inc e
djnz sec_1
sec_2: pop hl
pop bc
jr nc,loop1_1
jr endsr
test: push bc
push de
push hl
call rslt
push af
ld e,0
call wslt
ld e,0ach
call wslt
call rslt
cp 0ach
jr z,test1
pop af
ld e,a
call wslt
xor a
jr test2
test1: pop af
ld e,a
call wslt
scf
test2: pop hl
pop de
pop bc
ret
rslt: ld hl,6fffh
ld a,(slot2)
call rdslt
ret
wslt: ld hl,6fffh
ld a,(slot2)
call wrslt
ret
conf: db 0
slot1: db 0
slot2: db 0
atuslt: db 0
IO class
Four file manipulation routines: OPEN, CLOSE, READ and WRITE.
; ---------------------------------------------------------------------------
; Assembly I/O class
; Original for RBC compiler
; (c) A&L Software 1997
;
; Implemented functions:
; OPENF, READF, WRITEF, CLOSEF
;
; Error codes: 0 - ok
; 1 - end of file or disk full
; 2 - read error
; 3 - invalid operation
; 255 - file not found or directory full
; ---------------------------------------------------------------------------
; ------------------------------------------
; Open a file for reading/writing
; Input : HL - ASCIIZ string with file name
; format: D:FILENAME.EXT
; A - operation: 0-read, 1-write
; DE - FCB (37 bytes)
; Output: A - error code
; Modify: all registers
; ------------------------------------------
OPENF: push af
call infcb ; initialize FCB
pop af
or a
jr z,openf0
cp 1
jr z,openf1
ld a,3
ret
openf0: ld c,0fh ; open file for reading
call 5
ret
openf1: ld c,16h ; open file for writing
call 5
ret
; ------------------------------------------
; Close a file
; Input : DE - FCB (37 bytes)
; Output: none
; Modify: all registers
; ------------------------------------------
CLOSEF: ld c,10h
call 5
ret
; ------------------------------------------
; Read 128 bytes from a read opened file
; Input : HL - destination address
; DE - FCB (37 bytes)
; Output: A - error code
; Modify: all registers
; ------------------------------------------
READF: call SETDMA
ld c,14h
call 5
ret
; ------------------------------------------
; Write 128 bytes to a write opened file
; Input : HL - data address
; DE - FCB (37 bytes)
; Output: A - error code
; Modify: all registers
; ------------------------------------------
WRITEF: call SETDMA
ld c,15h
call 5
ret
; ------------------------------------------
; Initialize FCB with filename
; Input : HL - ASCIIZ string with file name
; format: D:FILENAME.EXT
; DE - FCB (37 bytes)
; Output: none
; Modify: AF,BC,HL,IX
; ------------------------------------------
INFCB: push de ; initialize FCB
xor a
ld (de),a
inc de
ld a,20
ld b,11
call infcb3 ; clear filename
push de
pop ix
dec ix
dec ix
dec ix ; IX points to file extension
ld b,25
xor a
call infcb3 ; clear FCB
pop de
push de
inc de ; DE to filename
inc hl
ld a,(hl)
dec hl
cp ':' ; set drive
jr nz,infcb0
ld a,(hl)
inc hl
inc hl
dec de
and 223
sub 64
ld (de),a
inc de
infcb0: ld a,(hl)
or a
jr z,infcb2 ; if 00h, end of filename
cp '.'
jr nz,infcb1
inc hl
push ix
pop de ; if '.', set DE to file extension
jr infcb0
infcb1: ld (de),a ; if not '.', set FCB name position
inc hl
inc de
jr infcb0
infcb2: pop de
ret
infcb3: ld (de),a
inc de
djnz infcb3
ret
; ------------------------------------------
; Set DMA to HL
; Input : HL - DMA address
; Output: none
; Modify: AF,BC,HL
; ------------------------------------------
SETDMA: push de
ld d,h
ld e,l
ld c,1ah
call 5
pop de
ret
MegaRAM searcher
A routine do search for MegaRAM on any slot/subslot (in portuguese).
;
; Esta rotina procura uma MegaRAM instalada no sistema
;
; Rotina original retirada do "Guia do Programador MSX"
; de Eduardo Alberto Barbosa, Ed. Ciencia Moderna, 1990
;
; Bug do ultimo subslot corrigido por A&L Software 1997
;
; Entrada : nenhuma
; Saida : A - slot da MegaRAM (0FFh se nao encontrada)
; Modifica: todos os registradores
;
; Esta rotina pode ser copiada e modificada livremente
;
exptbl: equ 0fcc1h
rdslt: equ 000ch
wrslt: equ 0014h
start: di ; desabilita interrupcoes
in a,(0a8h) ; le^ configuracao de slots atual
ld (conf),a ; e salva
ld a,(0ffffh) ; le^ configuracao de subslots atual
cpl
ld (conf2),a ; e salva
xor a ; A=slot 0
ld hl,exptbl ; HL aponta pra tabela de slots
; expandidos
ld b,4 ; B=numero de slots principais
loop1: ld (slot1),a ; salva o slot atual
ld (slot2),a ; salva o subslot atual
bit 7,(hl) ; este slot principal e' expandido?
jr nz,sec ; se sim, procura nos seus slots
; expandidos pela MegaRAM
call test ; se nao, procura no slot principal
jr c,endsr ; se achou, vai para ENDSR
loop1_1:inc hl ; se nao achou, proximo slot
ld a,(slot1)
inc a
djnz loop1 ; e nova busca
notfnd: ld a,0ffh ; se nao achou nada, devolve 0FFh
jr endsr_1
endsr: ld a,(slot2) ; se achou, devolve slot da MegaRAM
endsr_1:ld b,a ; salva slot da MegaRAM
ld a,(conf) ; restaura a configuracao de slots
out (0a8h),a
ld a,(conf2) ; restaura a configuracao de subslots
ld (0ffffh),a
ld a,b ; devolve slot da MegaRAM
ei ; reabilita interrupcoes
ret ; fim!
;
; Esta rotina procura a MegaRAM nos slots expandidos de um slot
; principal
;
sec: push bc ; salva registradores utilizados
push hl
ld e,0 ; E=subslot 0
ld b,4 ; B=numero de subslots
sec_1: ld a,e ; A=numero do slot secundario
rla ; coloca o numero nos bits 2 e 3
rla
and 00001100b ; isola os bits 2 e 3
ld c,a ; salva o resultado em C
ld a,(slot1) ; obtem o slot principal
and 00000011b ; certifica-se que esta' entre 0 e 3
or c ; junta com o numero do slot secunda-
; rio
set 7,a ; seta indicacao de slot expandido
; com isso temos o identificador de
; slot secundario na forma em que as
; rotinas WRSLT, RDSLT e ENASLT pedem
ld (slot2),a ; salva subslot atual
call test ; testa subslot atual
jr c,sec_2 ; se encontrou MegaRAM, vai pra SEC_2
inc e ; senao, proximo subslot
djnz sec_1 ; e nova busca
sec_2: pop hl ; no fim da busca, restaura
pop bc ; registradores utilizados
jp nc,loop1_1 ; se encontrou, termina procura
jr endsr ; senao, procura no proximo slot
;
; Esta rotina testa a presenca MegaRAM no slot/subslot atual
;
test: push bc ; salva registradores utilizados
push de
push hl
call rslt ; le^ byte em 4000h do slot/subslot
push af ; atual e salva na pilha
out (8eh),a ; passa MegaRAM pra ROM pra chavear
ld e,0 ; chaveia MegaRAM para
call wslt ; a pagina 0
in a,(8eh) ; passa MegaRAM para RAM
ld e,0ach ; grava o valor 0ACh
call wslt ; em 4000h
out (8eh),a ; passa MegaRAM para ROM pra chavear
ld e,0 ; chaveia MegaRAM para
call wslt ; a pagina 0 novamente
call rslt ; le^ o conteudo de 4000h
cp 0ach ; se for 0ACh,
jr z,test1 ; vai para TEST1
pop af ; senao restaura o valor original da
ld e,a ; pilha e
call wslt ; grava-o de volta em 4000h
xor a ; limpa o flag C (sem sucesso)
jr test2 ; e vai pra TEST2
test1: pop af ; restaura o valor original da
ld e,a ; pilha e grava-o de volta
call wslt ; em 4000h
scf ; seta o flag C (sucesso)
test2: pop hl ; restaura registradores utilizados
pop de
pop bc
ret ; e retorna
;
; Esta rotina le^ o conteudo do endereco 4000h do slot/subslot atual
; e devolve no registrador A
;
rslt: ld hl,4000h
ld a,(slot2)
call rdslt
ret
;
; Esta rotina grava o conteudo do registrador A no endereco 4000h do
; slot/subslot atual
;
wslt: ld hl,4000h
ld a,(slot2)
call wrslt
ret
conf: db 0 ; configuracao dos slots do MSX
conf2: db 0 ; configuracao dos subslots do MSX
slot1: db 0 ; slot atual em teste
slot2: db 0 ; subslot atual em teste
RAM searcher
A routine to search for RAM pages on any slot/subslot (in portuguese).
;
; Esta rotina procura a RAM instalada no sistema na pagina 1
; e retorna o primeiro slot onde ela foi encontrada
;
; (c) 1997 A&L Software
;
; Entrada : nenhuma
; Saida : A - slot da RAM (0FFh se nao encontrada)
; Modifica: todos os registradores
;
; Esta rotina pode ser copiada e modificada livremente
;
exptbl: equ 0fcc1h
rdslt: equ 000ch
wrslt: equ 0014h
start: di ; desabilita interrupcoes
in a,(0a8h) ; le^ configuracao de slots atual
ld (conf),a ; e salva
ld a,(0ffffh) ; le^ configuracao de subslots atual
cpl
ld (conf2),a ; e salva
xor a ; A=slot 0
ld hl,exptbl ; HL aponta pra tabela de slots
; expandidos
ld b,4 ; B=numero de slots principais
loop1: ld (slot1),a ; salva o slot atual
ld (slot2),a ; salva o subslot atual
bit 7,(hl) ; este slot principal e' expandido?
jr nz,sec ; se sim, procura nos seus slots
; expandidos pela RAM
call test ; se nao, procura no slot principal
jr c,endsr ; se achou, vai para ENDSR
loop1_1:inc hl ; se nao achou, proximo slot
ld a,(slot1)
inc a
djnz loop1 ; e nova busca
notfnd: ld a,0ffh ; se nao achou nada, devolve 0FFh
jr endsr_1
endsr: ld a,(slot2) ; se achou, devolve slot da RAM
endsr_1:ld b,a ; salva slot da RAM
ld a,(conf) ; restaura a configuracao de slots
out (0a8h),a
ld a,(conf2) ; restaura a configuracao de subslots
ld (0ffffh),a
ld a,b ; devolve slot da RAM
ei ; reabilita interrupcoes
ret ; fim!
;
; Esta rotina procura a RAM nos slots expandidos de um slot
; principal
;
sec: push bc ; salva registradores utilizados
push hl
ld e,0 ; E=subslot 0
ld b,4 ; B=numero de subslots
sec_1: ld a,e ; A=numero do slot secundario
rla ; coloca o numero nos bits 2 e 3
rla
and 00001100b ; isola os bits 2 e 3
ld c,a ; salva o resultado em C
ld a,(slot1) ; obtem o slot principal
and 00000011b ; certifica-se que esta' entre 0 e 3
or c ; junta com o numero do slot secunda-
; rio
set 7,a ; seta indicacao de slot expandido
; com isso temos o identificador de
; slot secundario na forma em que as
; rotinas WRSLT, RDSLT e ENASLT pedem
ld (slot2),a ; salva subslot atual
call test ; testa subslot atual
jr c,sec_2 ; se encontrou RAM, vai pra SEC_2
inc e ; senao, proximo subslot
djnz sec_1 ; e nova busca
sec_2: pop hl ; no fim da busca, restaura
pop bc ; registradores utilizados
jp nc,loop1_1 ; se encontrou, termina procura
jr endsr ; senao, procura no proximo slot
;
; Esta rotina testa a presenca RAM no slot/subslot atual
;
test: push bc ; salva registradores utilizados
push de
push hl
call rslt ; le^ byte em 4000h do slot/subslot
push af ; atual e salva na pilha
ld e,0 ; zera o byte em 4000h do slot
call wslt
ld e,0ach ; grava o valor 0ACh
call wslt ; em 4000h
call rslt ; le^ o conteudo de 4000h
cp 0ach ; se for 0ACh,
jr z,test1 ; vai para TEST1
pop af ; senao restaura o valor original da
ld e,a ; pilha e
call wslt ; grava-o de volta em 4000h
xor a ; limpa o flag C (sem sucesso)
jr test2 ; e vai pra TEST2
test1: pop af ; restaura o valor original da
ld e,a ; pilha e grava-o de volta
call wslt ; em 4000h
scf ; seta o flag C (sucesso)
test2: pop hl ; restaura registradores utilizados
pop de
pop bc
ret ; e retorna
;
; Esta rotina le^ o conteudo do endereco 4000h do slot/subslot atual
; e devolve no registrador A
;
rslt: ld hl,4000h
ld a,(slot2)
call rdslt
ret
;
; Esta rotina grava o conteudo do registrador A no endereco 4000h do
; slot/subslot atual
;
wslt: ld hl,4000h
ld a,(slot2)
call wrslt
ret
conf: db 0 ; configuracao dos slots do MSX
conf2: db 0 ; configuracao dos subslots do MSX
slot1: db 0 ; slot atual em teste
slot2: db 0 ; subslot atual em teste
Nenhum comentário:
Postar um comentário