segunda-feira, janeiro 31, 2022

AdrianPage: Assembly Source Code

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


Downloads

Nenhum comentário:

Postar um comentário