Browse Source

dma updates

Tidy up driver, standardize terminology half/full
Update dmamon so port address is not hardcoded.
pull/322/head
b1ackmai1er 3 years ago
parent
commit
632cc0e7db
  1. 229
      Source/Apps/Test/DMAmon/dmamon.asm
  2. 64
      Source/HBIOS/dma.asm

229
Source/Apps/Test/DMAmon/dmamon.asm

@ -14,8 +14,8 @@ DMAMODE_RC .EQU 4 ; RCBUS Z80 DMA
DMAMODE_MBC .EQU 5 ; MBC DMAMODE_MBC .EQU 5 ; MBC
DMAMODE_VDG .EQU 6 ; VELESOFT DATAGEAR DMAMODE_VDG .EQU 6 ; VELESOFT DATAGEAR
; ;
DMABASE .EQU $E0 ; DMA: DMA BASE ADDRESS
DMAMODE .EQU DMAMODE_MBC ; SELECT DMA DEVICE FOR TESTING
DMABASE .EQU $0b ; DMA: DMA BASE ADDRESS
DMAMODE .EQU DMAMODE_VDG ; SELECT DMA DEVICE FOR TESTING
DMAIOTST .EQU $68 ; AN OUTPUT PORT FOR TESTING - 16C450 SERIAL OUT DMAIOTST .EQU $68 ; AN OUTPUT PORT FOR TESTING - 16C450 SERIAL OUT
; ;
;================================================================================================== ;==================================================================================================
@ -88,7 +88,7 @@ MAIN:
LD SP,STACK ; STACK LD SP,STACK ; STACK
; ;
call PRTSTRD ; WELCOME call PRTSTRD ; WELCOME
.db "\n\rDMA Monitor V2\n\r$"
.db "\n\rDMA Monitor V3\n\r$"
; ;
#IF (INTENABLE) #IF (INTENABLE)
; ;
@ -111,13 +111,8 @@ MAIN:
#ENDIF #ENDIF
; ;
MENULP: CALL DISPM ; DISPLAY MENU MENULP: CALL DISPM ; DISPLAY MENU
CALL CIN ; GET SELECTION
; Force upper case
CP 'a' ; < 'a'
JR C,MENULP1 ; IF SO, JUST CONTINUE
CP 'z'+1 ; > 'z'
JR NC,MENULP1 ; IS SO, JUST CONTINUE
SUB 'a'-'A' ; CONVERT TO UPPER
CALL CINU ; GET SELECTION
CALL COUT
; ;
MENULP1: MENULP1:
CALL NEWLINE CALL NEWLINE
@ -145,11 +140,24 @@ MENULP1:
CP 'Y' CP 'Y'
JP Z,DMATST_Y ; TOGGLE READY JP Z,DMATST_Y ; TOGGLE READY
#ENDIF #ENDIF
cp 'S'
call z,DMACFG_S ; SET PORT
CP 'X' CP 'X'
JP Z,DMABYE ; EXIT JP Z,DMABYE ; EXIT
; ;
JR MENULP JR MENULP
; ;
DMACFG_S:
call PRTSTRD
.db "\n\rSet port address\n\rPort:$"
call HEXIN
ld hl,dmaport
ld (hl),a
inc hl
inc a
ld (hl),a
jp MENULP
;
DMABYE: DMABYE:
#IF (INTENABLE) #IF (INTENABLE)
; Deinstall interrupt vector ; Deinstall interrupt vector
@ -236,7 +244,7 @@ DISPM: call PRTSTRD
; ;
call PRTSTRD call PRTSTRD
.db ", Port=0x$" .db ", Port=0x$"
LD A,DMABASE ; DISPLAY
LD A,(dmaport) ; DISPLAY
CALL PRTHEXBYTE ; DMA PORT CALL PRTHEXBYTE ; DMA PORT
; ;
#IF (INTENABLE) #IF (INTENABLE)
@ -292,12 +300,14 @@ SPDDISP:LD DE,DMA_SPD_STR
DMA_INIT: DMA_INIT:
CALL NEWLINE CALL NEWLINE
PRTS("DMA: IO=0x$") ; announce PRTS("DMA: IO=0x$") ; announce
LD A, DMABASE
LD A,(dmaport)
CALL PRTHEXBYTE CALL PRTHEXBYTE
; ;
#IF !(DMAMODE==DMAMODE_VDG) #IF !(DMAMODE==DMAMODE_VDG)
ld a,(dmautil)
ld c,a
LD A,DMA_FORCE LD A,DMA_FORCE
out (DMABASE+1),a ; force ready off
out (c),a ; force ready off
#ENDIF #ENDIF
; ;
; ;
@ -357,6 +367,7 @@ MENU_OPT:
.TEXT "1) Test DMA Latch Port Selection\n\r" .TEXT "1) Test DMA Latch Port Selection\n\r"
.TEXT "Y) Test Ready Bit\n\r" .TEXT "Y) Test Ready Bit\n\r"
#ENDIF #ENDIF
.TEXT "S) Set DMA port\n\r"
.TEXT "X) Exit\n\r" .TEXT "X) Exit\n\r"
.TEXT ">$" .TEXT ">$"
@ -401,7 +412,9 @@ DMA_Port01:
call PRTSTRD call PRTSTRD
.db "\r\nPulsing port 0x$" .db "\r\nPulsing port 0x$"
sub '0' ; Calculate sub '0' ; Calculate
add a,DMABASE ; Port to
ld c,a
ld a,(dmaport) ; Port to
add a,c
call PRTHEXBYTE call PRTHEXBYTE
call NEWLINE call NEWLINE
ld c,a ; toggle ld c,a ; toggle
@ -438,7 +451,8 @@ DMA_ReadyT:
#IF !(DMAMODE==DMAMODE_VDG) #IF !(DMAMODE==DMAMODE_VDG)
#ENDIF #ENDIF
ld c,DMABASE+1 ; toggle
ld a,(dmautil)
ld c,a ; toggle
ld b,$20 ; loop counter ld b,$20 ; loop counter
portlp2:push bc portlp2:push bc
ld a,b ld a,b
@ -447,14 +461,14 @@ portlp2:push bc
.db ": ON$" .db ": ON$"
call delay call delay
ld a,$FF ld a,$FF
ld c,DMABASE+1
; ld c,DMABASE+1
out (c),a out (c),a
call PRTSTRD call PRTSTRD
.db " -> OFF$" .db " -> OFF$"
call delay call delay
call PRTSTRD call PRTSTRD
.db "\r \r$" .db "\r \r$"
ld c,DMABASE+1
; ld c,DMABASE+1
ld a,0 ld a,0
out (c),a out (c),a
pop bc pop bc
@ -566,36 +580,38 @@ DMAMemTestIterCont:
;================================================================================================== ;==================================================================================================
; ;
DMAProbe: DMAProbe:
ld a,(dmaport)
ld c,a
ld a,DMA_RESET ld a,DMA_RESET
out (DMABASE),a
out (c),a
ld a,%01111101 ; R0-Transfer mode, A -> B, start address follows ld a,%01111101 ; R0-Transfer mode, A -> B, start address follows
out (DMABASE),a
out (c),a
ld a,$cc ld a,$cc
out (DMABASE),a
out (c),a
ld a,$dd ld a,$dd
out (DMABASE),a
out (c),a
ld a,$e5 ld a,$e5
out (DMABASE),a
out (c),a
ld a,$1a ld a,$1a
out (DMABASE),a
out (c),a
ld a,DMA_LOAD ld a,DMA_LOAD
out (DMABASE),a
out (c),a
; ;
ld a,DMA_READ_MASK_FOLLOWS ; set up ld a,DMA_READ_MASK_FOLLOWS ; set up
out (DMABASE),a ; for
out (c),a ; for
ld a,%00011000 ; register ld a,%00011000 ; register
out (DMABASE),a ; read
out (c),a ; read
ld a,DMA_START_READ_SEQUENCE ld a,DMA_START_READ_SEQUENCE
out (DMABASE),a
out (c),a
; ;
in a,(DMABASE) ; read in
ld c,a ; address
in a,(DMABASE)
ld b,a
in a,(c) ; read in
ld e,a ; address
in a,(c)
ld d,a
; ;
xor a ; is it xor a ; is it
ld hl,$ddcc ; a match ld hl,$ddcc ; a match
sbc hl,bc ; return with
sbc hl,de ; return with
ret z ; status ret z ; status
cpl cpl
ret ret
@ -628,15 +644,16 @@ DMALDIR:
; ;
ld hl,DMACopy ; program the ld hl,DMACopy ; program the
ld b,DMACopy_Len ; dma command ld b,DMACopy_Len ; dma command
ld c,DMABASE ; block
ld a,(dmaport) ; block
ld c,a
; ;
di di
otir ; load and execute dma otir ; load and execute dma
ei ei
; ;
ld a,DMA_READ_STATUS_BYTE ; check status ld a,DMA_READ_STATUS_BYTE ; check status
out (DMABASE),a ; of transfer
in a,(DMABASE) ; set non-zero
out (c),a ; of transfer
in a,(c) ; set non-zero
; and %00111011 ; if failed ; and %00111011 ; if failed
; sub %00011011 ; sub %00011011
ret ret
@ -673,15 +690,16 @@ DMALDIRINT:
; ;
ld hl,DMACopyInt ; program the ld hl,DMACopyInt ; program the
ld b,DMACopyInt_Len ; dma command ld b,DMACopyInt_Len ; dma command
ld c,DMABASE ; block
ld a,(dmaport) ; block
ld c,a
; ;
di di
otir ; load and execute dma otir ; load and execute dma
ei ei
; ;
ld a,DMA_READ_STATUS_BYTE ; check status ld a,DMA_READ_STATUS_BYTE ; check status
out (DMABASE),a ; of transfer
in a,(DMABASE)
out (c),a ; of transfer
in a,(c)
call PRTSTRD call PRTSTRD
.db "Return Status: $" .db "Return Status: $"
@ -728,15 +746,16 @@ DMAOTIR:
; ;
ld hl,DMAOutCode ; program the ld hl,DMAOutCode ; program the
ld b,DMAOut_Len ; dma command ld b,DMAOut_Len ; dma command
ld c,DMABASE ; block
ld a,(dmaport) ; block
ld c,a
; ;
di di
otir ; load and execute dma otir ; load and execute dma
ei ei
; ;
ld a,DMA_READ_STATUS_BYTE ; check status ld a,DMA_READ_STATUS_BYTE ; check status
out (DMABASE),a ; of transfer
in a,(DMABASE) ; set non-zero
out (c),a ; of transfer
in a,(c) ; set non-zero
; and %00111011 ; if failed ; and %00111011 ; if failed
@ -777,17 +796,19 @@ DMAINIR:
; ;
ld hl,DMAInCode ; program the ld hl,DMAInCode ; program the
ld b,DMAIn_Len ; dma command ld b,DMAIn_Len ; dma command
ld c,DMABASE ; block
ld a,(dmaport) ; block
ld c,a
; ;
di di
otir ; load and execute dma otir ; load and execute dma
ei ei
; ;
ld a,DMA_READ_STATUS_BYTE ; check status ld a,DMA_READ_STATUS_BYTE ; check status
out (DMABASE),a ; of transfer
in a,(DMABASE) ; set non-zero
and %00111011 ; if failed
sub %00011011
out (c),a ; of transfer
in a,(c) ; set non-zero
; and %00111011 ; if failed
; sub %00011011
; ;
ret ret
; ;
@ -814,43 +835,111 @@ DMAIn_Len .equ $-DMAInCode
;================================================================================================== ;==================================================================================================
; ;
DMARegDump: DMARegDump:
ld a,(dmaport)
ld c,a
ld a,DMA_READ_MASK_FOLLOWS ld a,DMA_READ_MASK_FOLLOWS
out (DMABASE),a
out (c),a
ld a,%01111110 ld a,%01111110
out (DMABASE),a
out (c),a
ld a,DMA_START_READ_SEQUENCE ld a,DMA_START_READ_SEQUENCE
out (DMABASE),a
out (c),a
; ;
in a,(DMABASE)
ld c,a
in a,(DMABASE)
ld b,a
call PRTHEXWORD
in a,(c)
ld l,a
in a,(c)
ld h,a
call PRTHEXWORDHL
ld a,':' ld a,':'
call COUT call COUT
; ;
in a,(DMABASE)
ld c,a
in a,(DMABASE)
ld b,a
call PRTHEXWORD
in a,(c)
ld l,a
in a,(c)
ld h,a
call PRTHEXWORDHL
ld a,':' ld a,':'
call COUT call COUT
; ;
in a,(DMABASE)
ld c,a
in a,(DMABASE)
ld b,a
call PRTHEXWORD
in a,(c)
ld l,a
in a,(c)
ld h,a
call PRTHEXWORDHL
; ;
call NEWLINE call NEWLINE
ret ret
; ;
CIO_CONSOLE .EQU $80 ; CONSOLE UNIT TO C
;==================================================================================================
; CONSOLE I/O ROUTINES
;==================================================================================================
;
CIO_CONSOLE .EQU $80 ; HBIOS DEFAULT CONSOLE
BF_CIOOUT .EQU $01 ; HBIOS FUNC: OUTPUT CHAR BF_CIOOUT .EQU $01 ; HBIOS FUNC: OUTPUT CHAR
BF_CIOIN .EQU $00 ; HBIOS FUNC: INPUT CHAR BF_CIOIN .EQU $00 ; HBIOS FUNC: INPUT CHAR
BF_CIOIST .EQU $02 ; HBIOS FUNC: INPUT CHAR STATUS BF_CIOIST .EQU $02 ; HBIOS FUNC: INPUT CHAR STATUS
; ;
;__CINU_______________________________________________________________________
;
; INPUT AN UPPERCASE CHARACTER
;_____________________________________________________________________________
;
CINU: CALL CIN
; Force upper case
CP 'a' ; < 'a'
RET C ; IF SO, JUST CONTINUE
CP 'z'+1 ; > 'z'
RET NC ; IS SO, JUST CONTINUE
SUB 'a'-'A' ; CONVERT TO UPPER
RET
;
;__HEXIN_______________________________________________________________________
;
; INPUT A HEX BYTE, RETURN VALUE IN A
;_____________________________________________________________________________
;
HEXIN: CALL CINU ; GET 1 CHAR INPUT
push af
CALL ISHEX ; CHECK FOR VALID CHARACTER
JR C,HEXIN
ADD A,A
ADD A,A
ADD A,A
ADD A,A
LD C,A ; Save top nibble
pop af ; Retreive letter
call COUT ; and display it
;
HEXIN1: CALL CINU ; GET 1 CHAR INPUT
push af
CALL ISHEX ; CHECK FOR VALID CHARACTER
JR C,HEXIN1
;
or c
ld c,a
pop af ; Retreive letter
call COUT ; and display it
;
ld a,c
CALL PRTHEXBYTE
RET
; CF SET MEANS CHARACTER 0-9,A-F
ISHEX: CP '0' ; < '0'?
JR C,ISHEX1 ; YES, NOT 0-9, CHECK A-F
CP '9' + 1 ; > '9'
jr nc,ISHEX1
sub '0' ; MUST BE 0-9, RETURN
ret
ISHEX1: CP 'A' ; < 'A'?
ret c ; YES, NOT A-F, FAIL
cp 'F' + 1 ; > 'F'
jr nc,ISHEX2
sub 'A' - 10
RET ; MUST BE A-F, RETURN
ISHEX2: SCF
RET
;
;__COUT_______________________________________________________________________ ;__COUT_______________________________________________________________________
; ;
; OUTPUT CHARACTER FROM A ; OUTPUT CHARACTER FROM A
@ -942,8 +1031,10 @@ int:
; a DMA_DISABLE command prior to a ; a DMA_DISABLE command prior to a
; DMA_REINIT_STATUS_BYTE command to avoid a ; DMA_REINIT_STATUS_BYTE command to avoid a
; potential race condition. ; potential race condition.
ld a,(dmaport)
ld c,a
ld a,DMA_DISABLE ld a,DMA_DISABLE
out (DMABASE),a
out (c),a
; ;
; The doc confuses me, but apparently it is ; The doc confuses me, but apparently it is
; necessary to reinitialize the status byte ; necessary to reinitialize the status byte
@ -951,7 +1042,7 @@ int:
; the end-of-block condition remains set and ; the end-of-block condition remains set and
; causes the interrupt to fire continuously. ; causes the interrupt to fire continuously.
ld a,DMA_REINIT_STATUS_BYTE ld a,DMA_REINIT_STATUS_BYTE
out (DMABASE),a
out (c),a
; ;
ld hl,(counter) ld hl,(counter)
inc hl inc hl
@ -960,7 +1051,9 @@ int:
or $ff ; signal int handled or $ff ; signal int handled
ret ret
; ;
counter .dw 0
counter .dw 0
dmaport .db DMABASE
dmautil .db DMABASE+1
; ;
hsiz .equ $ - $A000 ; size of handler to relocate hsiz .equ $ - $A000 ; size of handler to relocate
; ;

64
Source/HBIOS/dma.asm

@ -23,42 +23,28 @@ DMA_RESET .equ $c3
;DMA_REINIT_STATUS_BYTE .equ $8b ;DMA_REINIT_STATUS_BYTE .equ $8b
; ;
DMA_FBACK .equ TRUE ; ALLOW FALLBACK TO SOFTWARE DMA_FBACK .equ TRUE ; ALLOW FALLBACK TO SOFTWARE
DMA_USEHS .equ TRUE ; USE CLOCK DIVIDER
;
DMA_RDY .EQU %00001000 DMA_RDY .EQU %00001000
DMA_FORCE .EQU 0 DMA_FORCE .EQU 0
#IF (DMA_USEHS & (DMAMODE=DMAMODE_MBC))
;;;#IF (CPUSPDDEF=SPD_HIGH)
;;;#DEFINE DMAIOSLO LD A,(HB_RTCVAL) \ AND %11110111 \ OUT (RTCIO),A
;;;#DEFINE DMAIONOR PUSH AF \ LD A,(HB_RTCVAL) \ OR %00001000 \ OUT (RTCIO),A \ POP AF
;;;#ELSE
;;;#DEFINE DMAIOSLO \;
;;;#DEFINE DMAIONOR \;
;;;#ENDIF
#DEFINE DMAIOSLO LD A,(HB_RTCVAL) \ AND ~%00001000 \ OUT (RTCIO),A
#DEFINE DMAIONOR PUSH AF \ LD A,(HB_RTCVAL) \ OUT (RTCIO),A \ POP AF
;
;==================================================================================================
; DMA CLOCK SPEED CONTROL - OPTION TO SWITCH TO HALF CLOCK SPEED. MOST SYSTEMS NEED THIS.
;==================================================================================================
;
DMA_USEHALF .equ TRUE ; USE CLOCK DIVIDER
;
#IF (DMA_USEHALF & (DMAMODE=DMAMODE_MBC))
#DEFINE DMAIOHALF LD A,(HB_RTCVAL) \ AND ~%00001000 \ OUT (RTCIO),A
#DEFINE DMAIOFULL PUSH AF \ LD A,(HB_RTCVAL) \ OUT (RTCIO),A \ POP AF
#ENDIF #ENDIF
; ;
#IF (DMA_USEHS & (DMAMODE=DMAMODE_ECB))
;;;#IF (CPUSPDDEF=SPD_HIGH)
;;;#DEFINE DMAIOSLO LD A,(HB_RTCVAL) \ OR %00001000 \ OUT (RTCIO),A
;;;#DEFINE DMAIONOR PUSH AF \ LD A,(HB_RTCVAL) \ AND %11110111 \ OUT (RTCIO),A \ POP AF
;;;#ELSE
;;;#DEFINE DMAIOSLO \;
;;;#DEFINE DMAIONOR \;
;;;#ENDIF
#DEFINE DMAIOSLO LD A,(HB_RTCVAL) \ OR %00001000 \ OUT (RTCIO),A
#DEFINE DMAIONOR PUSH AF \ LD A,(HB_RTCVAL) \ OUT (RTCIO),A \ POP AF
#IF (DMA_USEHALF & (DMAMODE=DMAMODE_ECB))
#DEFINE DMAIOHALF LD A,(HB_RTCVAL) \ OR %00001000 \ OUT (RTCIO),A
#DEFINE DMAIOFULL PUSH AF \ LD A,(HB_RTCVAL) \ OUT (RTCIO),A \ POP AF
#ENDIF #ENDIF
#IF (!DMA_USEHS)
#DEFINE DMAIOSLO \;
#DEFINE DMAIONOR \;
;
#IF (!DMA_USEHALF)
#DEFINE DMAIOHALF \;
#DEFINE DMAIOFULL \;
#ENDIF #ENDIF
; ;
;================================================================================================== ;==================================================================================================
@ -74,7 +60,7 @@ DMA_INIT:
LD A,DMA_FORCE LD A,DMA_FORCE
out (DMABASE+1),a ; force ready off out (DMABASE+1),a ; force ready off
; ;
DMAIOSLO
DMAIOHALF
; ;
call DMAProbe ; do we have a dma? call DMAProbe ; do we have a dma?
jr nz,DMA_NOTFOUND jr nz,DMA_NOTFOUND
@ -89,7 +75,7 @@ DMA_INIT:
xor a ; set status xor a ; set status
; ;
DMA_EXIT: DMA_EXIT:
DMAIONOR
DMAIOFULL
ret ret
; ;
@ -179,7 +165,7 @@ DMALDIR:
ld b,DMACopy_Len ; dma command ld b,DMACopy_Len ; dma command
ld c,DMABASE ; block ld c,DMABASE ; block
; ;
DMAIOSLO
DMAIOHALF
; ;
di di
otir ; load and execute dma otir ; load and execute dma
@ -191,7 +177,7 @@ DMALDIR:
and %00111011 ; if failed and %00111011 ; if failed
sub %00011011 sub %00011011
DMAIONOR
DMAIOFULL
ret ret
; ;
@ -225,7 +211,7 @@ DMAOTIR:
ld b,DMAOut_Len ; dma command ld b,DMAOut_Len ; dma command
ld c,DMABASE ; block ld c,DMABASE ; block
; ;
DMAIOSLO
DMAIOHALF
di di
otir ; load and execute dma otir ; load and execute dma
@ -237,7 +223,7 @@ DMAOTIR:
and %00111011 ; if failed and %00111011 ; if failed
sub %00011011 sub %00011011
; ;
DMAIONOR
DMAIOFULL
ret ret
; ;
@ -276,7 +262,7 @@ DMAINIR:
ld b,DMAIn_Len ; dma command ld b,DMAIn_Len ; dma command
ld c,DMABASE ; block ld c,DMABASE ; block
; ;
DMAIOSLO
DMAIOHALF
; ;
di di
otir ; load and execute dma otir ; load and execute dma
@ -288,7 +274,7 @@ DMAINIR:
and %00111011 ; if failed and %00111011 ; if failed
sub %00011011 sub %00011011
; ;
DMAIONOR
DMAIOFULL
; ;
ret ret
; ;

Loading…
Cancel
Save