Browse Source

Merge pull request #317 from b1ackmai1er/dev

vgmplay updates, romldr baud improvements, hbios/cbios low memory handling and other minors
pull/331/head
Wayne Warthen 3 years ago
committed by GitHub
parent
commit
fc634380b0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 201
      Source/Apps/TEST/sound/ay-test.asm
  2. 867
      Source/Apps/VGM/vgmplay.asm
  3. 5
      Source/CBIOS/cbios.asm
  4. 2
      Source/Doc/ROM_Applications.md
  5. 2
      Source/Doc/SystemGuide.md
  6. 11
      Source/HBIOS/ay38910.asm
  7. 64
      Source/HBIOS/hbios.asm
  8. 46
      Source/HBIOS/romldr.asm
  9. 133
      Source/HBIOS/unlzsa2s.asm
  10. 46
      Source/HBIOS/updater.asm
  11. 2
      Source/pSys/ReadMe.txt

201
Source/Apps/TEST/sound/ay-test.asm

@ -0,0 +1,201 @@
;*****************************************************************************
;*****************************************************************************
;** **
;** AY-3-8910 Sound Test Program **
;** Author: Wayne Warthen -- 10/8/2017 **
;** **
;*****************************************************************************
;*****************************************************************************
;
;=============================================================================
; Constants Section
;=============================================================================
;
; Hardware port addresses
;
rsel .equ $9A ; Register seelection port address
rdat .equ $9B ; Register data port address
acr .equ $9C ; Aux control register port address
;
; CPU speed for delay scaling
;
cpuspd .equ 4 ; CPU speed in MHz
;
; BDOS invocation constants
;
bdos .equ $0005 ; BDOS invocation vector
print .equ 9 ; BDOS print function number
conwrt .equ 2 ; BDOS console write char
;
;=============================================================================
; Code Section
;=============================================================================
;
.org $100
;
ld (stksav),sp ; save incoming stack frame
ld sp,stack ; setup our private stack
;
ld de,banner ; load banner string address
ld c,print ; BDOS print function number
call bdos ; do it
;
ld a,$FF ; SCG board activation value
out (acr),a ; write value to ACR
;
xor a ; zero accum
ld (chan),a ; init channel number
;
chloop:
; Test each channel
call tstchan ; test the current channel
ld hl,chan ; point to channel number
ld a,(chan) ; get current channel
inc a ; bump to next
ld (chan),a ; save it
cp 3 ; end of channels?
jr nz,chloop ; loop if not done
;
ld de,crlf ; newline
ld c,print ; BDOS print function
call bdos ; do it
;
ld sp,(stksav) ; restore stack
;
ret ; end of program
;
tstchan:
; Display channel being tested
ld de,chmsg ; point to channel message
ld c,print ; BDOS print function number
call bdos ; do it
ld a,(chan) ; get current channel number
add a,'A' ; offset to print as alpha
ld e,a ; put in E
ld c,conwrt ; BDOS console out function number
call bdos ; do it
ld de,chmsg2 ; point to channel message
ld c,print ; BDOS print function number
call bdos ; do it
;
ld hl,0 ; initial pitch value
ld (pitch),hl ; save it
;
; Setup mixer register
ld a,(chan) ; get channel num (0-2)
inc a ; adjust index (1-3)
ld b,a ; and use as loop counter
xor a ; clear accum
scf ; set carry
mixloop:
rla ; rotate bit
djnz mixloop ; loop based on channel num
cpl ; invert bits
and $FF ; so only target bit is cleared
push af ; save value
ld a,7 ; mixer register
out (rsel),a ; select it
pop af ; recover value
out (rdat),a ; and set register value
;
; Set channel volume to max
ld a,(chan) ; get channel
add a,8 ; adjust for start of vol regs
out (rsel),a ; select register
ld a,$0F ; max volume
out (rdat),a ; write it
;
pitloop:
; Pitch loop
ld a,(chan) ; get channel
sla a ; A := channel pitch reg, 2 bytes per chan
out (rsel),a ; select low byte register
push af ; save register
ld a,l ; get low byte of pitch value
out (rdat),a ; and write it to register
pop af ; recover register index
inc a ; inc to high byte pitch register
out (rsel),a ; select high byte register
ld a,h ; get high byte of pitch value
out (rdat),a ; and write it to register
;
; Delay
ld b,cpuspd ; cpu speed scalar
dlyloop:
call dly64 ; arbitrary delay
djnz dlyloop ; loop based on cpu speed
;
; Next pitch value
ld hl,(pitch) ; get current pitch
inc hl ; increment
ld (pitch),hl ; save new value
ld a,h ; get high byte
;cp 16 ; end of max range?
cp 4 ; end of max range?
jr nz,pitloop ; loop till done
;
; Clean up
call clrpsg ; shut down psg
;
ret ; done
;
; Clear PSG registers to default
;
clrpsg:
ld b,16 ; loop for 18 registers
ld c,0 ; init register index
clrpsg1:
ld a,c ; register num to accum
out (rsel),a ; select it
xor a ; clear accum
out (rdat),a ; and write to register
inc c ; next register
djnz clrpsg1 ; loop through all registers
ret ; return
;
; Program PSG registers from list at HL
;
setpsg:
ld a,(hl) ; get psg reg number
inc hl ; bump index
cp $FF ; check for end
ret z ; return if end marker $FF
out (rsel),a ; select psg register
ld a,(hl) ; get register value
inc hl ; bump index
out (rdat),a ; set register value
jr setpsg ; loop till done
;
; Short delay functions. No clock speed compensation, so they
; will run longer on slower systems. The number indicates the
; number of call/ret invocations. A single call/ret is
; 27 t-states on a z80, 25 t-states on a z180
;
dly256: call dly128
dly128: call dly64
dly64: call dly32
dly32: call dly16
dly16: call dly8
dly8: call dly4
dly4: call dly2
dly2: call dly1
dly1: ret
;
;=============================================================================
; Data Section
;=============================================================================
;
chan .db 0 ; active audio channel
pitch .dw 0 ; current pitch
;
banner .text "\r\nRetroBrew Computers SCG AY-3-8910 Sound Test\r\n"
.text "Set SCG board base I/O address to 0x98\r\n$"
chmsg .text "\r\nPlaying descending tones on channel $"
chmsg2 .text "...$"
crlf .text "\r\n$"
;
stksav .dw 0 ; saved stack frame
.fill 80,$FF ; 40 level private stack
stack .equ $ ; start of stack
;
.end

867
Source/Apps/VGM/vgmplay.asm

@ -41,6 +41,10 @@ plt_romwbw .equ 1 ; Build for ROMWBW?
plt_type .equ sbcecb ; Select build configuration
debug .equ 0 ; Display port, register, config info
;
;------------------------------------------------------------------------------
; Platform specific definitions. If building for ROMWBW, these may be overridden
;------------------------------------------------------------------------------
#IF (plt_type=custom)
RSEL .equ 09AH ; Primary AY-3-8910 Register selection
RDAT .equ 09BH ; Primary AY-3-8910 Register data
@ -58,8 +62,9 @@ YM2151_SEL1 .equ 0FEH ; Primary YM2151 register selection
YM2151_DAT1 .equ 0FFH ; Primary YM2151 register data
YM2151_SEL2 .equ 0FEH ; Secondary YM2151 register selection
YM2151_DAT2 .equ 0FFH ; Secondary YM2151 register data
plt_cpuspd .equ 6;000000 ; Non ROMWBW cpu speed default
FRAME_DLY .equ 10 ; Frame delay (~ 1/44100)
plt_cpuspd .equ 6 ; Non ROMWBW cpu speed default
#ENDIF
;
#IF (plt_type=P8X180)
@ -83,64 +88,65 @@ plt_cpuspd .equ 20 ; Non ROMWBW cpu speed default
#ENDIF
;
#IF (plt_type=RCBUS)
RSEL .equ 0D8H ; Primary AY-3-8910 Register selection
RDAT .equ 0D0H ; Primary AY-3-8910 Register data
RSEL2 .equ 0A0H ; Secondary AY-3-8910 Register selection
RDAT2 .equ 0A1H ; Secondary AY-3-8910 Register data
PSG1REG .equ 0FFH ; Primary SN76489
PSG2REG .equ 0FBH ; Secondary SN76489
YM2151_SEL1 .equ 0FEH ; Primary YM2151 register selection
YM2151_DAT1 .equ 0FFH ; Primary YM2151 register data
YM2151_SEL2 .equ 0D0H ; Secondary YM2151 register selection
YM2151_DAT2 .equ 0D1H ; Secondary YM2151 register data
ctcbase .equ 000H ; CTC base address
YMSEL .equ 000H ; Primary YM2162 11000000 a1=0 a0=0
YMDAT .equ 000H ; Primary YM2162 11000001 a1=0 a0=1
YM2SEL .equ 000H ; Secondary YM2162 11000010 a1=1 a0=0
YM2DAT .equ 000H ; Secondary YM2162 11000011 a1=1 a0=1
FRAME_DLY .equ 12 ; Frame delay (~ 1/44100)
plt_cpuspd .equ 7 ; Non ROMWBW cpu speed default
RSEL .equ 0D8H ; AYMODE_RCZ80 ; Primary AY-3-8910 Register selection
RDAT .equ 0D0H ; AYMODE_RCZ80 ; Primary AY-3-8910 Register data
RSEL2 .equ 000H ; UNDEFINED ; Secondary AY-3-8910 Register selection
RDAT2 .equ 000H ; UNDEFINED ; Secondary AY-3-8910 Register data
PSG1REG .equ 0FFH ; SNMODE_RC ! ; Primary SN76489
PSG2REG .equ 0FBH ; SNMODE_RC ; Secondary SN76489
YM2151_SEL1 .equ 0FEH ; ED BRINDLEY ; Primary YM2151 register selection
YM2151_DAT1 .equ 0FFH ; ED BRINDLEY ! ; Primary YM2151 register data
YM2151_SEL2 .equ 000H ; UNDEFINED ; Secondary YM2151 register selection
YM2151_DAT2 .equ 000H ; UNDEFINED ; Secondary YM2151 register data
ctcbase .equ 000H ; UNDEFINED ; CTC base address
YMSEL .equ 000H ; UNDEFINED ; Primary YM2162 11000000 a1=0 a0=0
YMDAT .equ 000H ; UNDEFINED ; Primary YM2162 11000001 a1=0 a0=1
YM2SEL .equ 000H ; UNDEFINED ; Secondary YM2162 11000010 a1=1 a0=0
YM2DAT .equ 000H ; UNDEFINED ; Secondary YM2162 11000011 a1=1 a0=1
plt_cpuspd .equ 7;372800 ; CPUOSC ; Non ROMWBW cpu speed default
FRAME_DLY .equ 12 ; Frame delay (~ 1/44100)
#ENDIF
;
#IF (plt_type=sbcecb)
RSEL .equ 09AH ; Primary AY-3-8910 Register selection
RDAT .equ 09BH ; Primary AY-3-8910 Register data
RSEL2 .equ 0A0H ; Secondary AY-3-8910 Register selection
RDAT2 .equ 0A1H ; Secondary AY-3-8910 Register data
VGMBASE .equ $C0
YMSEL .equ VGMBASE+00H ; Primary YM2162 11000000 a1=0 a0=0
YMDAT .equ VGMBASE+01H ; Primary YM2162 11000001 a1=0 a0=1
YM2SEL .equ VGMBASE+02H ; Secondary YM2162 11000010 a1=1 a0=0
YM2DAT .equ VGMBASE+03H ; Secondary YM2162 11000011 a1=1 a0=1
PSG1REG .equ VGMBASE+06H ; Primary SN76489
PSG2REG .equ VGMBASE+07H ; Secondary SN76489
ctcbase .equ VGMBASE+0CH ; CTC base address
YM2151_SEL1 .equ 0FEH ; Primary YM2151 register selection
YM2151_DAT1 .equ 0FFH ; Primary YM2151 register data
YM2151_SEL2 .equ 0FEH ; Secondary YM2151 register selection
YM2151_DAT2 .equ 0FFH ; Secondary YM2151 register data
FRAME_DLY .equ 13 ; Frame delay (~ 1/44100)
plt_cpuspd .equ 8 ; Non ROMWBW cpu speed default
RSEL .equ 09AH ; AYMODE_SCG ; Primary AY-3-8910 Register selection
RDAT .equ 09BH ; AYMODE_SCG ; Primary AY-3-8910 Register data
RSEL2 .equ 000H ; UNDEFINED ; Secondary AY-3-8910 Register selection
RDAT2 .equ 000H ; UNDEFINED ; Secondary AY-3-8910 Register data
VGMBASE .equ $C0 ; ECB-VGM V2 base address
YMSEL .equ VGMBASE+00H ; Primary YM2162 11000000 a1=0 a0=0
YMDAT .equ VGMBASE+01H ; Primary YM2162 11000001 a1=0 a0=1
YM2SEL .equ VGMBASE+02H ; Secondary YM2162 11000010 a1=1 a0=0
YM2DAT .equ VGMBASE+03H ; Secondary YM2162 11000011 a1=1 a0=1
PSG1REG .equ VGMBASE+06H ; SNMODE_VGM ; Primary SN76489
PSG2REG .equ VGMBASE+07H ; SNMODE_VGM ; Secondary SN76489
ctcbase .equ VGMBASE+0CH ; CTC base address
YM2151_SEL1 .equ 000H ; UNDEFINED ; Primary YM2151 register selection
YM2151_DAT1 .equ 000H ; UNDEFINED ; Primary YM2151 register data
YM2151_SEL2 .equ 000H ; UNDEFINED ; Secondary YM2151 register selection
YM2151_DAT2 .equ 000H ; UNDEFINED ; Secondary YM2151 register data
plt_cpuspd .equ 8;000000 ; CPUOSC ; Non ROMWBW cpu speed default
FRAME_DLY .equ 13 ; Frame delay (~ 1/44100)
#ENDIF
;
#IF (plt_type=MBC)
RSEL .equ 0A0H ; Primary AY-3-8910 Register selection
RDAT .equ 0A1H ; Primary AY-3-8910 Register data
RSEL2 .equ 0D8H ; Secondary AY-3-8910 Register selection
RDAT2 .equ 0D0H ; Secondary AY-3-8910 Register data
YMSEL .equ 0C0H ; 11000000 a1=0 a0=0
YMDAT .equ 0C1H ; 11000001 a1=0 a0=1
YM2SEL .equ 0C2H ; 11000010 a1=1 a0=0
YM2DAT .equ 0C3H ; 11000011 a1=1 a0=1
PSG1REG .equ 0C6H ; Primary SN76489
PSG2REG .equ 0C7H ; Secondary SN76489
ctcbase .equ 000H ; CTC base address
YM2151_SEL1 .equ 0FEH ; Primary YM2151 register selection
YM2151_DAT1 .equ 0FFH ; Primary YM2151 register data
YM2151_SEL2 .equ 0FEH ; Secondary YM2151 register selection
YM2151_DAT2 .equ 0FFH ; Secondary YM2151 register data
FRAME_DLY .equ 13 ; Frame delay (~ 1/44100)
plt_cpuspd .equ 8 ; Non ROMWBW cpu speed default
RSEL .equ 0A0H ; AYMODE_MBC ; Primary AY-3-8910 Register selection
RDAT .equ 0A1H ; AYMODE_MBC ; Primary AY-3-8910 Register data
RSEL2 .equ 000H ; UNDEFINED ; Secondary AY-3-8910 Register selection
RDAT2 .equ 000H ; UNDEFINED ; Secondary AY-3-8910 Register data
YMSEL .equ 000H ; UNDEFINED ; Primary YM2162 11000000 a1=0 a0=0
YMDAT .equ 000H ; UNDEFINED ; Primary YM2162 11000001 a1=0 a0=1
YM2SEL .equ 000H ; UNDEFINED ; Secondary YM2162 11000010 a1=1 a0=0
YM2DAT .equ 000H ; UNDEFINED ; Secondary YM2162 11000011 a1=1 a0=1
PSG1REG .equ 000H ; UNDEFINED ; Primary SN76489
PSG2REG .equ 000H ; UNDEFINED ; Secondary SN76489
ctcbase .equ 000H ; UNDEFINED ; CTC base address
YM2151_SEL1 .equ 000H ; UNDEFINED ; Primary YM2151 register selection
YM2151_DAT1 .equ 000H ; UNDEFINED ; Primary YM2151 register data
YM2151_SEL2 .equ 000H ; UNDEFINED ; Secondary YM2151 register selection
YM2151_DAT2 .equ 000H ; UNDEFINED ; Secondary YM2151 register data
plt_cpuspd .equ 8;000000 ; CPUOSC ; Non ROMWBW cpu speed default
FRAME_DLY .equ 13 ; UNDEFINED ; Frame delay (~ 1/44100)
#ENDIF
;
;------------------------------------------------------------------------------
@ -240,47 +246,13 @@ LF .equ 0AH ; line feed
;------------------------------------------------------------------------------
.ORG 100H
;
LD (OLDSTACK),SP ; save old stack pointer
LD SP,STACK ; set new stack pointer
;
#IF (delay_type==cpu_loop)
call setfdelay ; Setup the frame delay based on cpu speed
#ENDIF
;
#IF (delay_type==ctc_poll)
call cfgctc_poll ; If building for polled ctc, initialize it
#ENDIF
;
#IF (delay_type==ctc_int) ; If building for interrupt driven ctc, initialize it
call cfgctc_int
#ENDIF
;
#IF (debug)
; LD A,0 ; tone to validate presence
;TST: LD C,PSG1REG
; OUT (C),A
; LD C,PSG2REG
; OUT (C),A
; JR TST
#ENDIF
CALL vgmsetup ; Device setup
call welcome ; Welcome message and build debug info
CALL READVGM ; Read in the VGM file
CALL VGMINFO ; Check and display VGM Information
LD HL, (VGMDATA + 34H) ; Determine start of VGM
LD A, H ; data.
OR L
JR NZ, _S1
LD HL, 000CH ; Default location (40H - 34H)
_S1 LD DE, VGMDATA + 34H
ADD HL, DE
LD (VGMPOS), HL
LD HL,D60 ; VGM delay (60hz)
LD (vdelay), HL
;
LD IX,VGM_DEV ; IX points to device mask
call vgmreadr ; read in the vgm file
;
;------------------------------------------------------------------------------
; Play loop
@ -349,197 +321,32 @@ EXIT: CALL VGMDEVICES ; Display devices used
LD DE,MSG_EXIT
EXIT_ERR: CALL PRTSTR ; Generic message or error
LD SP, (OLDSTACK) ; Exit to CP/M
RST 00H
DI
HALT
JP BOOT
;
;------------------------------------------------------------------------------
; Welcome
; Read VGM file
;------------------------------------------------------------------------------
;
welcome: LD DE,MSG_WELC ; Welcome Message
CALL PRTSTR
;
#IF (plt_romwbw)
LD DE,MSG_ROMWBW ; display system type
CALL PRTSTR
#ENDIF
;
LD A,delay_type ; display build type
LD DE,MSG_CPU
CALL PRTIDXDEA
vgmreadr:
CALL READVGM ; Read in the VGM file
CALL VGMINFO ; Check and display VGM Information
;
LD A,plt_type ; display system type
LD DE,MSG_CUSTOM
CALL PRTIDXDEA
call CRLF
LD HL, (VGMDATA + 34H) ; Determine start of VGM
LD A, H ; data.
OR L
JR NZ, _S1
LD HL, 000CH ; Default location (40H - 34H)
_S1 LD DE, VGMDATA + 34H
ADD HL, DE
LD (VGMPOS), HL
;
#IF (debug)
#IF (delay_type==cpu_loop)
ld a,'f' ; Display frame rate delay
call PRTCHR
call PRTDOT
ld a,(fdelay)
call PRTDECB
LD A,' '
#ENDIF
CALL PRTCHR
ld a,'c'
call PRTCHR
call PRTDOT
ld a,ctcdiv0 ; Display ctc divider values
call PRTDECB
CALL PRTDOT
ld a,ctcdiv1
call PRTDECB
CALL PRTDOT
ld a,ctcdiv2
call PRTDECB
CALL PRTDOT
ld a,ctcdiv3
call PRTDECB
LD HL,D60 ; VGM delay (60hz)
LD (vdelay), HL
;
#IF (delay_wait)
ld a,' '
CALL PRTCHR
LD A,'w' ; Display if using double wait
CALL PRTCHR
#ENDIF
#ENDIF
CALL CRLF
LD IX,VGM_DEV ; IX points to device mask
ret
;
;------------------------------------------------------------------------------
; Setup frame delay value - Loop count for DJNZ $ loop
;------------------------------------------------------------------------------
;
setfdelay:
#IF (delay_type==cpu_loop)
#IF (plt_romwbw)
LD BC,$F8F0 ; GET CPU SPEED
RST 08 ; FROM HBIOS
LD A,L ;
#ELSE
ld a,plt_cpuspd ; USE STANDALONE CPU SPEED
#ENDIF
LD HL,CLKTBL-1 ; CPU SPEED
ADD A,L ; INDEXES
LD L,A ; INTO
ADC A,H ; TABLE
SUB L
LD H,A ; LOOK IT UP IN THE
LD A,(HL) ; CLOCK TABLE
LD (fdelay),A ; SAVE LOOP COUNTER FOR CPU SPEED
RET
;------------------------------------------------------------------------------
; Frame delay values for different processor speeds.
;------------------------------------------------------------------------------
;
; 1/44100hz = 22676ns
; 16Mhz = 62.5ns : DJNZ $ = 1 frame delay= 22676ns/13*62.5ns = 27.91
; 12Mhz = 83.3ns : DJNZ $ = 1 frame delay= 22676ns/13*83.3ns = 20.94
; 10Mhz = 100ns : DJNZ $ = 1 frame delay= 22676ns/13*100ns = 17.44
; 8Mhz = 125ns : DJNZ $ = 1 frame delay= 22676ns/13*125ns = 13.95
; 7.3728Mhz = 135.6ns : DJNZ $ = 1 frame delay= 22676ns/13*135.6ns = 12.86
; 6Mhz = 166.6s : DJNZ $ = 1 frame delay= 22676ns/13*166.6ns = 10.47
; 4Mhz = 250ns : DJNZ $ = 1 frame delay= 22676ns/13*250ns = 6.98
; 2Mhz = 500ns : DJNZ $ = 1 frame delay= 22676ns/13*500ns = 3.49
; 1Mhz = 1000ns : DJNZ $ = 1 frame delay= 22676ns/13*1000ns = 1.74
;
CLKTBL: .DB 1 ; 1Mhz ; none of these
.DB 3 ; 2Mhz ; have been
.DB 0 ; 3Mhz ; validated
.DB 6 ; 4Mhz
.DB 0 ; 5Mhz
.DB 10 ; 6Mhz
.DB 12 ; 7Mhz 7.3728Mhz
.DB 13 ; 8Mhz
.DB 0 ; 9Mhz
.DB 17 ; 10Mhz
.DB 0 ; 11Mhz
.DB 20 ; 12Mhz
.DB 0 ; 13Mhz
.DB 0 ; 14Mhz
.DB 0 ; 15Mhz
.DB 27 ; 16Mhz
.DB 0 ; 17Mhz
.DB 0 ; 18Mhz
.DB 0 ; 19Mhz
.DB 0 ; 20Mhz
#ENDIF
;
;------------------------------------------------------------------------------
; Initialize CTC
;------------------------------------------------------------------------------
;
; %01010011 ; CTC DEFAULT CONFIG
; %01010111 ; CTC COUNTER MODE CONFIG
; %11010111 ; CTC COUNTER INTERRUPT MODE CONFIG
; |||||||+-- CONTROL WORD FLAG
; ||||||+--- SOFTWARE RESET
; |||||+---- TIME CONSTANT FOLLOWS
; ||||+----- AUTO TRIGGER WHEN TIME CONST LOADED
; |||+------ RISING EDGE TRIGGER
; ||+------- TIMER MODE PRESCALER (0=16, 1=256)
; |+-------- COUNTER MODE
; +--------- INTERRUPT ENABLE
;
cfgctc_poll:
;
ctcch0 .equ ctcbase
ctcch1 .equ ctcbase+1
ctcch2 .equ ctcbase+2
ctcch3 .equ ctcbase+3
;
ctccfg0 .equ %01010011
ctccfg1 .equ %01010111
ctccfg2 .equ %01010111
ctccfg3 .equ %01010111
;
ld a,ctccfg0 & $7f ; ; Channel 0
out (ctcch0),a
;
ld a,ctccfg1 & $7f ; Channel 1
out (ctcch1),a ;
ld a,ctcdiv1 & $ff ;
out (ctcch1),a ;
;
ld a,ctccfg2 & $7f ; Channel 2
out (ctcch2),a ;
ld a,ctcdiv2 & $ff ;
out (ctcch2),a ;
;
ld a,ctccfg3 & $7f ; Channel 3
out (ctcch3),a ;
ld a,ctcdiv3 & $ff ;
out (ctcch3),a ;
;
ret
;
#IF (debug)
ctctest:
ld b,0
ctclp1: in a,(ctcch3) ; wait for counter to reach zero
dec a
jr nz,ctclp1
ctclp2: in a,(ctcch3) ; wait for counter to pass zero
dec a
jr z,ctclp2
call PRTDOT
;
djnz ctclp1
#ENDIF
ret
;
cfgctc_int:
ret
;
;------------------------------------------------------------------------------
; Read VGM file into memory
;------------------------------------------------------------------------------
;
@ -593,101 +400,6 @@ RDONE LD C, CLOSEF ; Close the file
RET
;
;------------------------------------------------------------------------------
; Display VGM information.
;------------------------------------------------------------------------------
;
VGMINFO: LD DE,MSG_BADF ; Check valid file
LD HL,VGMDATA
LD A,(HL)
CP 'V'
JP NZ,EXIT_ERR
INC HL
LD A,(HL)
CP 'g'
JP NZ,EXIT_ERR
INC HL
LD A,(HL)
CP 'm'
JP NZ,EXIT_ERR
INC HL
LD A,(HL)
CP ' '
JP NZ,EXIT_ERR
LD HL,VGMDATA+08H ; Get version in DE:HL
LD E,(HL)
INC HL
LD D,(HL)
INC HL
LD B,(HL)
INC HL
LD C,(HL)
EX DE,HL
PUSH BC
POP DE
; CALL PRTHEX32 ; Debug
LD HL,(VGMDATA+16H) ; Is GD3 in range?
LD A,H
OR L
JR NZ,SKIP_GD3
LD HL,(VGMDATA+14H) ; Is there a GD3 header
LD DE,VGMDATA+14H
ADD HL,DE
LD A,(HL)
CP 'G'
JR NZ,SKIP_GD3
INC HL
LD A,(HL)
CP 'd'
JR NZ,SKIP_GD3
INC HL
LD A,(HL)
CP '3'
JR NZ,SKIP_GD3
INC HL
LD A,(HL)
CP ' '
JR NZ,SKIP_GD3
LD DE,0009H ; Skip version and size
ADD HL,DE
CALL CRLF
LD DE,MSG_TRACK
CALL PRTSTR
GD3_NXT: LD A,(HL) ; Print English Track
OR A
INC HL
INC HL
JR Z,GD3_NXT1
CALL PRTCHR
JR GD3_NXT
GD3_NXT1: LD A,(HL) ; Skip Japanese Track
OR A
INC HL
INC HL
JR NZ,GD3_NXT1
; JR GD3_NXT1
LD DE,MSG_TITLE
CALL PRTSTR
GD3_NXT2: LD A,(HL) ; Print English Title
OR A
INC HL
INC HL
JR Z,GD3_NXT3
CALL PRTCHR
JR GD3_NXT2
GD3_NXT3: CALL CRLF
SKIP_GD3: RET
;
;------------------------------------------------------------------------------
; VGM Player.
;------------------------------------------------------------------------------
PLAY
@ -861,53 +573,148 @@ UNK: SET 0,(IX+1) ; unknown device
;
VGMDEVICES: LD DE,MSG_PO ; Played on ...
CALL PRTSTR
;
LD A,(IX+0)
PUSH AF
;
LD DE,MSG_SN ; SN76489 Devices
CALL CHKDEV
;
POP AF
SRL A
SRL A
PUSH AF
;
LD DE,MSG_AY ; AY-3-8910 Devices
CALL CHKDEV
;
POP AF
SRL A
SRL A
PUSH AF
;
LD DE,MSG_YM2612 ; YM-2612 Devices
CALL CHKDEV
;
POP AF
SRL A
SRL A
PUSH AF
;
LD DE,MSG_YM2151 ; YM-2151 Devices
CALL CHKDEV
;
POP AF
; SRL A
; SRL A
; PUSH AF
;
LD A,(IX+1)
LD DE,MSG_UNK ; Unknown Device Code detected
; CALL CHKDEV
;
CHKDEV: AND %00000011 ; Display
RET Z ; number of
SRL A ; devices
ADC A,'0'
CALL PRTCHR ; Skip if not
CALL PRTSTR ; used.
RET
;
LD A,(IX+0)
PUSH AF
;
LD DE,MSG_SN ; SN76489 Devices
CALL CHKDEV
;
POP AF
SRL A
SRL A
PUSH AF
;
LD DE,MSG_AY ; AY-3-8910 Devices
CALL CHKDEV
;
POP AF
SRL A
SRL A
PUSH AF
;
LD DE,MSG_YM2612 ; YM-2612 Devices
CALL CHKDEV
;
POP AF
SRL A
SRL A
PUSH AF
;
LD DE,MSG_YM2151 ; YM-2151 Devices
CALL CHKDEV
;
POP AF
; SRL A
; SRL A
; PUSH AF
;
LD A,(IX+1)
LD DE,MSG_UNK ; Unknown Device Code detected
; CALL CHKDEV
;
CHKDEV: AND %00000011 ; Display
RET Z ; number of
SRL A ; devices
ADC A,'0'
CALL PRTCHR ; Skip if not
CALL PRTSTR ; used.
RET
;
;------------------------------------------------------------------------------
; Display VGM information.
;------------------------------------------------------------------------------
;
VGMINFO: LD DE,MSG_BADF ; Check valid file
LD HL,VGMDATA
LD A,(HL)
CP 'V'
JP NZ,EXIT_ERR
INC HL
LD A,(HL)
CP 'g'
JP NZ,EXIT_ERR
INC HL
LD A,(HL)
CP 'm'
JP NZ,EXIT_ERR
INC HL
LD A,(HL)
CP ' '
JP NZ,EXIT_ERR
LD HL,VGMDATA+08H ; Get version in DE:HL
LD E,(HL)
INC HL
LD D,(HL)
INC HL
LD B,(HL)
INC HL
LD C,(HL)
EX DE,HL
PUSH BC
POP DE
; CALL PRTHEX32 ; Debug
LD HL,(VGMDATA+16H) ; Is GD3 in range?
LD A,H
OR L
JR NZ,SKIP_GD3
LD HL,(VGMDATA+14H) ; Is there a GD3 header
LD DE,VGMDATA+14H
ADD HL,DE
LD A,(HL)
CP 'G'
JR NZ,SKIP_GD3
INC HL
LD A,(HL)
CP 'd'
JR NZ,SKIP_GD3
INC HL
LD A,(HL)
CP '3'
JR NZ,SKIP_GD3
INC HL
LD A,(HL)
CP ' '
JR NZ,SKIP_GD3
LD DE,0009H ; Skip version and size
ADD HL,DE
CALL CRLF
LD DE,MSG_TRACK
CALL PRTSTR
GD3_NXT: LD A,(HL) ; Print English Track
OR A
INC HL
INC HL
JR Z,GD3_NXT1
CALL PRTCHR
JR GD3_NXT
GD3_NXT1: LD A,(HL) ; Skip Japanese Track
OR A
INC HL
INC HL
JR NZ,GD3_NXT1
; JR GD3_NXT1
LD DE,MSG_TITLE
CALL PRTSTR
GD3_NXT2: LD A,(HL) ; Print English Title
OR A
INC HL
INC HL
JR Z,GD3_NXT3
CALL PRTCHR
JR GD3_NXT2
GD3_NXT3: CALL CRLF
SKIP_GD3: RET
;
;------------------------------------------------------------------------------
; Mute Devices.
@ -1293,7 +1100,6 @@ MSG_MBC .DB " [mbc] ",0
;------------------------------------------------------------------------------
;
VGMPOS .DW 0
;VGMDLY .DW 0 ; Saves number of frames to delay
KEYCHK .DB 0 ; Counter for keypress checks
;
VGM_DEV .DB %00000000 ; IX+0 Flags for devices
@ -1306,12 +1112,237 @@ VGM_DEV .DB %00000000 ; IX+0 Flags for devices
.DB %00000000 ; IX+1 Unimplemented device flags & future devices
;
OLDSTACK .DW 0 ; original stack pointer
.DS 40H ; space for stack
STACK ; top of stack
.FILL 40H ; space for stack
STACK .DW 0 ; top of stack
;------------------------------------------------------------------------------
; VGM data
; VGM data gets loaded into TPA here
;------------------------------------------------------------------------------
;
VGMDATA:
;
;******************************************************************************
;*********** Initialization code that gets overwritten by VGMDATA *************
;******************************************************************************
;
vgmsetup:
#IF (plt_romwbw==1)
CALL cfgports ; Get and setup ports from HBIOS
#ENDIF
;
#IF (delay_type==cpu_loop)
call setfdelay ; Setup the frame delay based on cpu speed
#ENDIF
;
#IF (delay_type==ctc_poll)
call cfgctc_poll ; If building for polled ctc, initialize it
#ENDIF
;
#IF (delay_type==ctc_int) ; If building for interrupt driven ctc, initialize it
call cfgctc_int
#ENDIF
;
#IF (debug)
; LD A,0 ; tone to validate presence
;TST: LD C,PSG1REG
; OUT (C),A
; LD C,PSG2REG
; OUT (C),A
; JR TST
#ENDIF
ret
;
;------------------------------------------------------------------------------
; Welcome
;------------------------------------------------------------------------------
;
welcome: LD DE,MSG_WELC ; Welcome Message
CALL PRTSTR
;
#IF (plt_romwbw)
LD DE,MSG_ROMWBW ; display system type
CALL PRTSTR
#ENDIF
;
LD A,delay_type ; display build type
LD DE,MSG_CPU
CALL PRTIDXDEA
;
LD A,plt_type ; display system type
LD DE,MSG_CUSTOM
CALL PRTIDXDEA
call CRLF
;
#IF (debug)
#IF (delay_type==cpu_loop)
ld a,'f' ; Display frame rate delay
call PRTCHR
call PRTDOT
ld a,(fdelay)
call PRTDECB
LD A,' '
#ENDIF
CALL PRTCHR
ld a,'c'
call PRTCHR
call PRTDOT
ld a,ctcdiv0 ; Display ctc divider values
call PRTDECB
CALL PRTDOT
ld a,ctcdiv1
call PRTDECB
CALL PRTDOT
ld a,ctcdiv2
call PRTDECB
CALL PRTDOT
ld a,ctcdiv3
call PRTDECB
;
#IF (delay_wait)
ld a,' '
CALL PRTCHR
LD A,'w' ; Display if using double wait
CALL PRTCHR
#ENDIF
#ENDIF
CALL CRLF
ret
;
;------------------------------------------------------------------------------
; Probe HBIOS for devices and patch in I/O ports for devices
;------------------------------------------------------------------------------
;
cfgports: ret
;
;------------------------------------------------------------------------------
; Setup frame delay value - Loop count for DJNZ $ loop
;------------------------------------------------------------------------------
;
setfdelay:
#IF (delay_type==cpu_loop)
#IF (plt_romwbw)
LD BC,$F8F0 ; GET CPU SPEED
RST 08 ; FROM HBIOS
LD A,L ;
#ELSE
ld a,plt_cpuspd ; USE STANDALONE CPU SPEED
#ENDIF
LD HL,CLKTBL-1 ; CPU SPEED
ADD A,L ; INDEXES
LD L,A ; INTO
ADC A,H ; TABLE
SUB L
LD H,A ; LOOK IT UP IN THE
LD A,(HL) ; CLOCK TABLE
;
LD (fdelay),A ; SAVE LOOP COUNTER FOR CPU SPEED
RET
;
;------------------------------------------------------------------------------
; Frame delay values for different processor speeds.
;------------------------------------------------------------------------------
;
; 1/44100hz = 22676ns
; 16Mhz = 62.5ns : DJNZ $ = 1 frame delay= 22676ns/13*62.5ns = 27.91
; 12Mhz = 83.3ns : DJNZ $ = 1 frame delay= 22676ns/13*83.3ns = 20.94
; 10Mhz = 100ns : DJNZ $ = 1 frame delay= 22676ns/13*100ns = 17.44
; 8Mhz = 125ns : DJNZ $ = 1 frame delay= 22676ns/13*125ns = 13.95
; 7.3728Mhz = 135.6ns : DJNZ $ = 1 frame delay= 22676ns/13*135.6ns = 12.86
; 6Mhz = 166.6s : DJNZ $ = 1 frame delay= 22676ns/13*166.6ns = 10.47
; 4Mhz = 250ns : DJNZ $ = 1 frame delay= 22676ns/13*250ns = 6.98
; 2Mhz = 500ns : DJNZ $ = 1 frame delay= 22676ns/13*500ns = 3.49
; 1Mhz = 1000ns : DJNZ $ = 1 frame delay= 22676ns/13*1000ns = 1.74
;
CLKTBL: .DB 1 ; 1Mhz ; none of these
.DB 3 ; 2Mhz ; have been
.DB 0 ; 3Mhz ; validated
.DB 6 ; 4Mhz
.DB 0 ; 5Mhz
.DB 10 ; 6Mhz
.DB 12 ; 7Mhz 7.3728Mhz
.DB 13 ; 8Mhz
.DB 0 ; 9Mhz
.DB 17 ; 10Mhz
.DB 0 ; 11Mhz
.DB 20 ; 12Mhz
.DB 0 ; 13Mhz
.DB 0 ; 14Mhz
.DB 0 ; 15Mhz
.DB 27 ; 16Mhz
.DB 0 ; 17Mhz
.DB 0 ; 18Mhz
.DB 0 ; 19Mhz
.DB 0 ; 20Mhz
#ENDIF
;
;
;------------------------------------------------------------------------------
; Initialize CTC
;------------------------------------------------------------------------------
;
; %01010011 ; CTC DEFAULT CONFIG
; %01010111 ; CTC COUNTER MODE CONFIG
; %11010111 ; CTC COUNTER INTERRUPT MODE CONFIG
; |||||||+-- CONTROL WORD FLAG
; ||||||+--- SOFTWARE RESET
; |||||+---- TIME CONSTANT FOLLOWS
; ||||+----- AUTO TRIGGER WHEN TIME CONST LOADED
; |||+------ RISING EDGE TRIGGER
; ||+------- TIMER MODE PRESCALER (0=16, 1=256)
; |+-------- COUNTER MODE
; +--------- INTERRUPT ENABLE
;
cfgctc_poll:
;
ctcch0 .equ ctcbase
ctcch1 .equ ctcbase+1
ctcch2 .equ ctcbase+2
ctcch3 .equ ctcbase+3
;
ctccfg0 .equ %01010011
ctccfg1 .equ %01010111
ctccfg2 .equ %01010111
ctccfg3 .equ %01010111
;
ld a,ctccfg0 & $7f ; ; Channel 0
out (ctcch0),a
;
ld a,ctccfg1 & $7f ; Channel 1
out (ctcch1),a ;
ld a,ctcdiv1 & $ff ;
out (ctcch1),a ;
;
ld a,ctccfg2 & $7f ; Channel 2
out (ctcch2),a ;
ld a,ctcdiv2 & $ff ;
out (ctcch2),a ;
;
ld a,ctccfg3 & $7f ; Channel 3
out (ctcch3),a ;
ld a,ctcdiv3 & $ff ;
out (ctcch3),a ;
;
ret
;
#IF (debug)
ctctest:
ld b,0
ctclp1: in a,(ctcch3) ; wait for counter to reach zero
dec a
jr nz,ctclp1
ctclp2: in a,(ctcch3) ; wait for counter to pass zero
dec a
jr z,ctclp2
call PRTDOT
;
djnz ctclp1
#ENDIF
ret
;
cfgctc_int:
ret
VGMDATA
.END

5
Source/CBIOS/cbios.asm

@ -2381,7 +2381,7 @@ INIT3:
;
ERR_BIOMEM:
CALL NEWLINE2 ; FORMATTING
LD DE,STR_BIOMEM ; HBIOS HEAP MEM OVERFLOW
LD DE,STR_HEAPOVF ; HBIOS HEAP MEM OVERFLOW
CALL WRITESTR ; TELL THE USER
CALL PANIC ; AND GRIND TO A SCREACHING HALT
;
@ -3436,7 +3436,7 @@ STR_INITRAMDISK .DB "Formatting RAMDISK...$"
STR_LDR2 .DB "\r\n"
STR_LDR .DB "\r\n $"
STR_DPHINIT .DB "Configuring Drives...$"
STR_HEAPOVF .DB " *** Insufficient Memory ***$"
STR_HEAPOVF .DB " *** Insufficient HBIOS Heap Memory ***$"
STR_INVMED .DB " *** Invalid Device ID ***$"
STR_VERMIS .DB 7,"*** WARNING: HBIOS/CBIOS Version Mismatch ***$"
STR_MEMFREE .DB " Disk Buffer Bytes Free$"
@ -3444,7 +3444,6 @@ STR_CPM .DB "CP/M-80 v2.2$"
STR_ZSDOS .DB "ZSDOS v1.1$"
STR_TPA1 .DB ", $"
STR_TPA2 .DB "K TPA$"
STR_BIOMEM .DB "*** HBIOS Heap Overflow ***$"
#IFDEF PLTUNA
INIBUF .FILL 512,0 ; LOCATION OF TEMP WORK BUF DURING INIT (512 BYTES)

2
Source/Doc/ROM_Applications.md

@ -492,6 +492,8 @@ When your console is the serial device used for the transfer, no progress inform
Due to different platform processor speeds, serials speeds and flow control capabilities the default console or serial device speed may need to be reduced for a successful transfer and flash to occur. The **Set Console Interface/Baud code** option at the Boot Loader can be used to change the speed if required. Additionally, the Updater has options to set to and revert from a recommended speed.
See the ROMWBW Applications guide for additional information on performing upgrades.
## Console Options
Option ( C ) - Set Console Device

2
Source/Doc/SystemGuide.md

@ -1241,7 +1241,7 @@ The Status (A) is a standard HBIOS result code.
Assign the specified character Attribute (E) code to be used for all
subsequent character writes/fills on the specified Video Unit (C). This
attribute is used to fill new lines generated by scroll operations. The
character attributes values are listed abovev. Note that a given video
character attributes values are listed above. Note that a given video
display may or may not support any/all attributes. The Status (A) is a
standard HBIOS result code.

11
Source/HBIOS/ay38910.asm

@ -11,6 +11,13 @@
; @1.7897725 OCTAVE RANGE IS 2 - 7 (Bb2/A#2 .. A7)
; @2.0000000 OCTAVE RANGE IS 2 - 7 (B2 .. A7)
;
; DIFFENCES BETWEEN AY-3-8910 AND YM2149
; THE AY-3-8910 HAS 16 ENVELOPE LEVELS, YM2149 HAS 32.
; THIS AFFECTS AUDIO OUTPUT ONLY. THERE IS NO PROGRAMMING IMPACT.
; UNUSED BITS IN REGISTERS ARE READ AS ZERO ON AY-3-8910.
; UNUSED BITS CAN BE READ BACK AND WRITTEN ON YM.
; VOLTAGE LEVEL OUTPUT ON A AY-3-8910 IS LOW AND AROUND 2V ON YM2149.
;
AY_RCSND .EQU 0 ; 0 = EB MODULE, 1=MF MODULE
;
#IF (AYMODE == AYMODE_SCG)
@ -101,8 +108,8 @@ AY_NOISECNT .EQU 1 ; COUNT NUMBER OF NOISE CHANNELS
;AY_SCALE .EQU 3 ; DATA TO MAINTAIN MAXIMUM
;#ENDIF ; RANGE AND ACCURACY
;
.ECHO "SN76489 CLOCK: "
.ECHO SN7CLK
.ECHO "AY38910 CLOCK: "
.ECHO AY_CLK
.ECHO "\n"
;
#INCLUDE "audio.inc"

64
Source/HBIOS/hbios.asm

@ -4074,7 +4074,7 @@ SYS_ALLOC:
; ALL OTHER REGISTERS PRESERVED
;
SYS_FREE:
SYSCHKERR(ERR_NOTIMPL) ; NOT YET INMPLEMENTED
SYSCHKERR(ERR_NOTIMPL) ; NOT YET IMPLEMENTED
RET
;
; GET SYSTEM INFORMATION
@ -6546,7 +6546,7 @@ PS_DISK:
LD B,BF_DIODEVICE ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C
RST 08 ; DE:=DEVTYP/NUM, H:=DISK ATTRIBUTES
PUSH BC ; SAVE ATTRIBUTES
LD HL,PS_DDSTRREF ; POINT TO DISK DEVICE TYPE NAME TABLE
LD HL,PS_DDMD ; POINT TO DISK DEVICE TYPE NAME TABLE
CALL PS_PRTDEV ; PRINT DISK DEVICE NMEMONIC PADDED TO FIELD WIDTH
POP DE ; RECOVER ATTRIBUTES TO DE
PUSH DE ; SAVE ATTRIBUTES AGAIN
@ -6666,7 +6666,7 @@ PS_SERIAL:
LD B,BF_CIODEVICE ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C
RST 08 ; DE:=DEVTYP/NUM, C:=DEVICE ATTRIBUTES
PUSH BC ; SAVE ATTRIBUTES
LD HL,PS_SDSTRREF ; POINT TO SERIAL DEVICE TYPE NAME TABLE
LD HL,PS_SDUART ; POINT TO SERIAL DEVICE TYPE NAME TABLE
CALL PS_PRTDEV ; PRINT SERIAL DEVICE NMEMONIC PADDED TO FIELD WIDTH
POP BC ; RECOVER ATTRIBUTES
PUSH BC ; SAVE ATTRIBUTES AGAIN
@ -6816,7 +6816,7 @@ PS_VIDEO:
LD B,BF_VDADEV ; FUNC=GET DEVICE INFO, UNIT NUM STILL IN C
RST 08 ; DE:=DEVTYP/NUM, H:=DISK ATTRIBUTES
PUSH BC ; SAVE ATTRIBUTES
LD HL,PS_VDSTRREF ; POINT TO VIDEO DEVICE TYPE NAME TABLE
LD HL,PS_VDVDU ; POINT TO VIDEO DEVICE TYPE NAME TABLE
CALL PS_PRTDEV ; PRINT VIDEO DEVICE NMEMONIC PADDED TO FIELD WIDTH
POP DE ; RECOVER ATTRIBUTES
PUSH DE ; SAVE ATTRIBUTES AGAIN
@ -6920,23 +6920,16 @@ PS_SOUND:
; PRINT DEVICE NMEMONIC, DEVTYP/NUM SPECIFIED IN DE
;
PS_PRTDEV:
LD A,D
RRCA ; TYPE IS IN UPPER NIBBLE, MOVE TO LOWER NIBBLE
RRCA
RRCA
RRCA
RLCA ; X2 FOR WORD OFFSET IN STRING TABLE
CALL ADDHLA
LD A,(HL)
INC HL
LD H,(HL)
LD L,A
CALL PS_PRT ; PRINT $ TERM STRING AT (HL), C:=CHARS PRINTED
LD A,E ; NUM
EX DE,HL
LD C,H
LD A,11110000B ; TYPE IS IN UPPER NIBBLE
CALL PRTIDXMSK
LD A,L ; UNIT NUMBER
CALL PRTDECB ; PRINT NUM, ASSUME 1 CHAR
CALL PC_COLON ; PRINT COLON
LD A,12 - 2 ; 12 CHAR FIELD - 1 POS FOR UNIT NUM AND 1 POS FOR COLON
SUB C
LD A,(PRTIDXCNT)
SUB 12-2+1 ; 12 CHAR FIELD - 1 POS FOR UNIT NUM AND 1 POS FOR COLON
NEG
CALL PS_PAD ; PAD N SPACES (SPECIFIED IN A)
RET
;
@ -6946,11 +6939,9 @@ PS_PRTNUL:
LD HL,PS_STRNUL
; FALL THRU TO PS_PRT
;
; PRINT STRING AT (HL), $ TERM, RETURN CHARS PRINTED IN C
;
;
PS_PRT:
; PRINT STRING AT (HL), $ TERM, RETURN CHARS PRINTED IN C
LD C,0 ; INIT CHAR COUNT
PS_PRT: LD C,0 ; INIT CHAR COUNT
PS_PRT1:
LD A,(HL) ; GET CHAR
INC HL ; BUMP INDEX
@ -6960,11 +6951,9 @@ PS_PRT1:
INC C ; BUMP COUNTER
JR PS_PRT1 ; AND LOOP
;
; PAD N SPACES SPECIFIED IN A
;
;
PS_PAD:
; PAD N SPACES SPECIFIED IN A
LD B,A
PS_PAD: LD B,A
LD A,' '
PS_PAD1:
CALL COUT
@ -6981,10 +6970,6 @@ PS_STRNUL .TEXT "--$" ; DISPLAY STRING FOR NUL VALUE
;
; DISK DEVICE STRINGS
;
PS_DDSTRREF:
.DW PS_DDMD, PS_DDFD, PS_DDRF, PS_DDIDE, PS_DDATAPI, PS_DDPPIDE
.DW PS_DDSD, PS_DDPRPSD, PS_DDPPPSD, PS_DDHDSK
;
PS_DDMD .TEXT "MD$"
PS_DDFD .TEXT "FD$"
PS_DDRF .TEXT "RF$"
@ -7030,10 +7015,6 @@ PS_FLP_DSTR: .TEXT "SD$" ; PS_FLPSD
;
; CHARACTER DEVICE STRINGS
;
PS_SDSTRREF:
.DW PS_SDUART, PS_SDASCI, PS_SDTERM, PS_SDPRPCON, PS_SDPPPCON
.DW PS_SDSIO, PS_SDACIA, PS_SDPIO, PS_SDUF, PS_SDDUART, PS_SDZ2U, PS_SDLPT
;
PS_SDUART .TEXT "UART$"
PS_SDASCI .TEXT "ASCI$"
PS_SDTERM .TEXT "TERM$"
@ -7064,9 +7045,6 @@ PIO_MODE_STR: .TEXT "Output$"
;
; VIDEO DEVICE STRINGS
;
PS_VDSTRREF:
.DW PS_VDVDU, PS_VDCVDU, PS_VDGDC, PS_VDTMS, PS_VDVGA
;
PS_VDVDU .TEXT "VDU$"
PS_VDCVDU .TEXT "CVDU$"
PS_VDGDC .TEXT "GDC$"
@ -7305,6 +7283,16 @@ SLACK .EQU BNKTOP - $
.ECHO "HBIOS space remaining: "
.ECHO SLACK
.ECHO " bytes.\n"
#IF (SLACK<0)
.ECHO "*** ERROR: HBIOS too big.\n"
!!! ; FORCE AN ASSEMBLY ERROR
#ENDIF
;
#IF (CCP_SIZ > SLACK)
.ECHO "*** ERROR: Insufficient space for CCP cache.\n"
!!! ; FORCE AN ASSEMBLY ERROR
#ENDIF
;
#IFDEF ROMBOOT
#IF (ROMSIZE > 0)

46
Source/HBIOS/romldr.asm

@ -525,7 +525,7 @@ nextbaud:
pop de ; get our count value
ld a,32
sub e
jr s_exit
jr setspd
;
mm1: inc hl
mm2: inc hl
@ -540,17 +540,6 @@ mm4: ex (sp),hl ; hl = count value, stack = tbl_baud, de = msw
pop de
jp err_invcmd
;
s_exit: cp 32 ; handle invalid
jp nc,err_invcmd ; baud rate
bit 0,a
jr z,iseven ; convert sequential
inc a ; baud rate code to
srl a ; encoded baud rate
jr setspd ; 13=9600
iseven: dec a ; 15=19200
srl a ; 17=38400
add a,16 ; 20=115200
;
setspd: ld (newspeed),a ; save validated baud rate
;
ld hl,str_chspeed ; notify user
@ -649,37 +638,36 @@ tmpbcd: .db 0
tbl_baud:
PACK('0','0','0','0','0','7','5') ; 75 0 > 0
PACK('0','0','0','0','1','5','0') ; 150 1 > 1
PACK('0','0','0','0','2','2','5') ; 225 2 > 16
PACK('0','0','0','0','3','0','0') ; 300 3 > 2
PACK('0','0','0','0','4','5','0') ; 450 4 > 17
PACK('0','0','0','0','6','0','0') ; 600 5 > 3
PACK('0','0','0','0','9','0','0') ; 900 6 > 18
PACK('0','0','0','1','2','0','0') ; 1200 7 > 4
PACK('0','0','0','1','8','0','0') ; 1800 8 > 19
PACK('0','0','0','2','4','0','0') ; 2400 9 > 5
PACK('0','0','0','3','6','0','0') ; 3600 10 > 20
PACK('0','0','0','4','8','0','0') ; 4800 11 > 6
PACK('0','0','0','7','2','0','0') ; 7200 12 > 21
PACK('0','0','0','9','6','0','0') ; 9600 13 > 7
PACK('0','0','1','4','4','0','0') ; 14400 14 > 22
PACK('0','0','1','9','2','0','0') ; 19200 15 > 8
PACK('0','0','2','8','8','0','0') ; 28800 16 > 23
PACK('0','0','3','8','4','0','0') ; 38400 17 > 9
PACK('0','0','5','7','6','0','0') ; 57600 18 > 24
PACK('0','0','7','6','8','0','0') ; 76800 19 > 10
PACK('0','1','1','5','2','0','0') ; 115200 20 > 25
PACK('0','1','5','3','6','0','0') ; 153600 21 > 11
PACK('0','2','3','0','4','0','0') ; 230400 22 > 26
PACK('0','3','0','7','2','0','0') ; 307200 23 > 12
PACK('0','4','6','0','8','0','0') ; 460800 24 > 27
PACK('0','6','1','4','4','0','0') ; 614400 25 > 13
PACK('0','9','2','1','6','0','0') ; 921600 26 > 28
PACK('1','2','2','8','8','0','0') ; 1228800 27 > 14
PACK('1','8','4','3','2','0','0') ; 1843200 28 > 29
PACK('2','4','5','7','6','0','0') ; 2457600 29 > 15
PACK('0','0','0','0','2','2','5') ; 225 2 > 16
PACK('0','0','0','0','4','5','0') ; 450 4 > 17
PACK('0','0','0','0','9','0','0') ; 900 6 > 18
PACK('0','0','0','1','8','0','0') ; 1800 8 > 19
PACK('0','0','0','3','6','0','0') ; 3600 10 > 20
PACK('0','0','0','7','2','0','0') ; 7200 12 > 21
PACK('0','0','1','4','4','0','0') ; 14400 14 > 22
PACK('0','0','2','8','8','0','0') ; 28800 16 > 23
PACK('0','0','5','7','6','0','0') ; 57600 18 > 24
PACK('0','1','1','5','2','0','0') ; 115200 20 > 25
PACK('0','2','3','0','4','0','0') ; 230400 22 > 26
PACK('0','4','6','0','8','0','0') ; 460800 24 > 27
PACK('0','9','2','1','6','0','0') ; 921600 26 > 28
PACK('1','8','4','3','2','0','0') ; 1843200 28 > 29
PACK('3','6','8','6','4','0','0') ; 3686400 30 > 30
PACK('7','3','7','2','8','0','0') ; 7372800 31 > 31
;
#endif
;
; Set RomWBW HBIOS Diagnostic Level
@ -1405,7 +1393,7 @@ getnum2: ; return result
or a ; with flags set, CF is cleared
ret
;
; Is character in A numberic? NZ if not
; Is character in A numeric? NZ if not
;
isnum:
cp '0' ; compare to ascii '0'
@ -1418,7 +1406,7 @@ isnum1:
or $FF ; set NZ
ret ; and done
;
; Delay 16us (cpu speed compensated) incuding call/ret invocation
; Delay 16us (cpu speed compensated) including call/ret invocation
; Register A and flags destroyed
; No compensation for z180 memory wait states
; There is an overhead of 3ts per invocation

133
Source/HBIOS/unlzsa2s.asm

@ -1,5 +1,5 @@
;
; Size-optimized LZSA2 decompressor by spke & uniabis (139 bytes)
; Size-optimized LZSA2 decompressor by spke & uniabis (134 bytes)
;
; ver.00 by spke for LZSA 1.0.0 (02-09/06/2019, 145 bytes);
; ver.01 by spke for LZSA 1.0.5 (24/07/2019, added support for backward decompression);
@ -8,6 +8,9 @@
; ver.04 by spke for LZSA 1.1.0 (26/09/2019, removed usage of IY, added full revision history)
; ver.05 by spke for LZSA 1.1.1 (11/10/2019, 139(-1) bytes, +0.1% speed)
; ver.051 by PSummers (14/1/2020), ROMWBW version.
; ver.06 by spke (11-12/04/2021, added some comments)
; ver.07 by spke (04-05/04/2022, 134(-5) bytes, +1% speed, using self-modifying code by default)
; ver.071 by PSummers (6/1/2023), ROMWBW version.
;
; The data must be compressed using the command line compressor by Emmanuel Marty
; The compression is done as follows:
@ -56,8 +59,8 @@
; 3. This notice may not be removed or altered from any source distribution.
;
; DEFINE BACKWARD_DECOMPRESS ; uncomment for data compressed with option -b
; DEFINE HD64180 ; uncomment for systems using Hitachi HD64180
; #DEFINE BACKWARD_DECOMPRESS ; uncomment for data compressed with option -b (+5 bytes, -3% speed)
; #DEFINE AVOID_SELFMODIFYING_CODE ; uncomment to disallow self-modifying code (-1 byte, -4% speed)
#IFNDEF BACKWARD_DECOMPRESS
@ -65,106 +68,106 @@
#DEFCONT \ inc hl
#DEFINE ADD_OFFSET \
#DEFCONT \ ex de,hl \ add hl,de
#DEFCONT \ add hl,de
#DEFINE BLOCKCOPY \
#DEFCONT \ ldir
#ELSE
#DEFINE NEXT_HL \
#DEFCONT \ dec hl
#DEFINE ADD_OFFSET \
#DEFCONT \ push hl \ or a \ sbc hl,de \ pop de
#DEFCONT \ ld a,e \ sub l \ ld l,a
#DEFCONT \ ld a,d \ sbc h \ ld h,a ; 6*4 = 24t / 6 bytes
#DEFINE BLOCKCOPY \
#DEFCONT \ lddr
#ENDIF
.ECHO "UNLZSA2 for "
#IFDEF HD64180
.ECHO "HD64180"
#DEFINE LD_IX_DE \
#DEFCONT \ ld ixl,e \ ld ixh,d
#DEFINE LD_DE_IX \
#DEFCONT \ ld e,ixl \ ld d,ixh
#ELSE
.ECHO "Z80"
#DEFINE LD_IX_DE \
#DEFCONT \ push de \ pop ix
#DEFINE LD_DE_IX \
#DEFCONT \ push ix \ pop de
#ENDIF
.ECHO ".\n"
DLZSA2:
; in many places we assume that B = 0
; flag P in A' signals the need to re-load the nibble store
xor a \ ld b,a \ ex af,af' \ jr ReadToken
CASE00x: call ReadNibble
ld e,a \ ld a,c
cp %00100000 \ rl e \ jr SaveOffset
CASE00x: ; token "00Z" stands for 5-bit offsets
; (read a nibble for offset bits 1-4 and use the inverted bit Z
; of the token as bit 0 of the offset; set bits 5-15 of the offset to 1)
push af
call skipLDCA \ ld c,a
pop af
cp %00100000 \ rl c \ jr SaveOffset
CASE0xx ld d,$FF \ cp %01000000 \ jr c,CASE00x
CASE0xx dec b \ cp %01000000 \ jr c,CASE00x
CASE01x: cp %01100000 \ rl d
CASE01x: ; token "01Z" stands for 9-bit offsets
; (read a byte for offset bits 0-7 and use the inverted bit Z
; for bit 8 of the offset; set bits 9-15 of the offset to 1)
cp %01100000
doRLB rl b
OffsetReadE: ld e,(hl) \ NEXT_HL
OffsetReadC: ld c,(hl) \ NEXT_HL
SaveOffset: LD_IX_DE
#IFNDEF AVOID_SELFMODIFYING_CODE
SaveOffset: ld (PrevOffset),bc \ ld b,0
#ELSE
SaveOffset: push bc \ pop ix \ ld b,0
#ENDIF
MatchLen: and %00000111 \ add a,2 \ cp 9 \ call z,ExtendedCode
MatchLen: and %00000111 \ add a,2 \ cp 9
call z,ExtendedCode
CopyMatch: ld c,a
ex (sp),hl ; BC = len, DE = -offset, HL = dest, SP -> [src]
ADD_OFFSET ; BC = len, DE = dest, HL = dest+(-offset), SP -> [src]
BLOCKCOPY ; BC = 0, DE = dest
pop hl ; HL = src
CopyMatch: ld c,a
push hl ; BC = len, DE = dest, HL = -offset, SP -> [src]
#IFNDEF AVOID_SELFMODIFYING_CODE
PrevOffset .EQU $+1 \ ld hl,0
#ELSE
push ix \ pop hl
#ENDIF
ADD_OFFSET
BLOCKCOPY ; BC = 0, DE = dest
pop hl ; HL = src
ReadToken: ld a,(hl) \ NEXT_HL \ push af
and %00011000 \ jr z,NoLiterals
rrca \ rrca \ rrca
call pe,ExtendedCode
ld c,a
BLOCKCOPY
rrca \ rrca \ rrca
call pe,ExtendedCode
NoLiterals: pop af \ push de
or a \ jp p,CASE0xx
ld c,a
BLOCKCOPY
CASE1xx: cp %11000000 \ jr nc,CASE11x
NoLiterals: pop af \ or a \ jp p,CASE0xx
CASE10x: call ReadNibble
ld d,a \ ld a,c
cp %10100000 ;: rl d
dec d \ rl d \ .DB $CA ; jr OffsetReadE ; #CA is JP Z,.. to skip all commands in CASE110 before jr OffsetReadE
CASE1xx cp %11000000 \ jr c,CASE10x
; token "111" stands for repeat offsets
; (reuse the offset value of the previous match command)
cp %11100000 \ jr nc,MatchLen
CASE110: ld d,(hl) \ NEXT_HL \ jr OffsetReadE
CASE110: ; token "110" stands for 16-bit offset
; (read a byte for offset bits 8-15, then another byte for offset bits 0-7)
ld b,(hl) \ NEXT_HL \ jr OffsetReadC
CASE11x: cp %11100000 \ jr c,CASE110
CASE10x: ; token "10Z" stands for 13-bit offsets
; (read a nibble for offset bits 9-12 and use the inverted bit Z
; for bit 8 of the offset, then read a byte for offset bits 0-7.
; set bits 13-15 of the offset to 1. substract 512 from the offset to get the final value)
call ReadNibble \ ld b,a
ld a,c \ cp %10100000
dec b \ jr doRLB
CASE111: LD_DE_IX \ jr MatchLen
ExtendedCode: call ReadNibble \ inc a \ jr z,ExtraByte
sub $F0+1 \ add a,c \ ret
ExtraByte ld a,15 \ add a,c \ add a,(hl) \ NEXT_HL \ ret nc
ld a,(hl) \ NEXT_HL
ld b,(hl) \ NEXT_HL \ ret nz
pop de \ pop de ; RET is not needed, because RET from ReadNibble is sufficient
pop bc ; RET is not needed, because RET from ReadNibble is sufficient
ReadNibble: ld c,a \ xor a \ ex af,af' \ ret m
UpdateNibble ld a,(hl) \ or $F0 \ ex af,af'
ReadNibble: ld c,a
skipLDCA xor a \ ex af,af' \ ret m
ld a,(hl) \ or $F0 \ ex af,af'
ld a,(hl) \ NEXT_HL \ or $0F
rrca \ rrca \ rrca \ rrca \ ret

46
Source/HBIOS/updater.asm

@ -12,6 +12,18 @@
; DISPLAY OUTPUT AND FILES TRANSFER. IF YOU USE A DIFFERENT SERIAL DEVICE FOR
; THE FILE TRANSFER, PROGRESS INFORMATION WILL BE DISPLAYED.
;
; OPTION (>) AND (<) - SET AND REVERT BAUD RATE
;
; THE MAXIMUM TRANSFER RATE IS LOWER IN THE UPDATER UTILITY COMPARED TO
; THE STANDALONE XMODEM APPLICATION. THIS IS BECAUSE THE SENDER CAN OVERFLOW
; THE INPUT RECEIVE BUFFER WHILE THE PREVIOUSLY SENT DATA IS BEING WRITTEN
; TO THE FLASH DEVICE (THE FLASH SECTOR ALSO HAS TO BE ERASED BEFORE THIS WRITE).
; LOWERING THE BAUD RATE HELPS PREVENT THIS TRANSFER/WRITE FAILURE.
; (>) WILL CHANGE THE PLATFORM BOARD RATE TO THE RECOMMENDED BAUD RATE FOR
; THE PLATFORMS CURRENT SPEED. YOU MUST CHANGE THE SENDERS SPEED TO MATCH.
; (<) WILL REVERT THE PLATFORMS BAUD RATE TO ITS ORIGINAL SPEED. AGAIN YOU
; MUST CHANGE THE SENDERS SPEED TO MATCH
;
; OPTION (V) - WRITE VERIFY
;
; BY DEFAULT EACH FLASH SECTOR WILL BE VERIFIED AFTER BEING WRITTEN. SLIGHT
@ -62,17 +74,16 @@
; OPTION (1) AND (2) - CALCULATE AND DISPLAY CRC32 OF 1ST OR 2ND 512K ROM.
; OPTION (3) - CALCULATE AND DISPLAY CRC32 OF A 1024K ROM.
;
; OPTION (H) - DEBUG OPTION - SWITCH ON CPU CLOCK DIVIDER ON SBC-V2-004+
; OPTION (H) - DEBUG OPTION - SWITCH ON CPU CLOCK DIVIDER ON
; OPTION (T) - DEBUG OPTION - TEST TIMER FOR 32S, 16S, 8S, 4S, 2S & 1S
;
;
; V.DEV 23/7/2021 PHIL SUMMERS, DIFFICULTYLEVELHIGH@GMAIL.COM
; V.1 5/1/2023 PHIL SUMMERS, DIFFICULTYLEVELHIGH@GMAIL.COM
; b1ackmai1er ON RETROBREWCOMPUTERS.ORG
;
;
; NOTES:
; TESTED WITH TERATERM XMODEM.
; PARTIAL WRITES CAN BE COMPLETED WITH 39SF040 CHIPS
; PARTIAL WRITES CAN BE COMPLETED WITH 39SF040 CHIPS.
; OTHER CHIPS REQUIRE ENTIRE FLASH TO BE ERASED BEFORE BEFORE BEING WRITTEN.
; SBC V2-005 MEGAFLASH REQUIRED FOR 1MB FLASH SUPPORT.
; ASSUMES BOTH CHIPS ARE SAME TYPE
@ -125,7 +136,8 @@ HBX_BNKSEL .EQU $FE2B
#DEFINE HB_DI DI
#DEFINE HB_EI EI
;
XFUDBG .EQU 0
XFUDBG .EQU 0 ; Enabling will cause a build failure
; Insufficient space for debug features
;
.ORG UPD_LOC
;
@ -857,11 +869,23 @@ TSTDLY: PUSH BC
JR NZ,TSTDLY ; RETURN TO MENU
JP MENULP ; WHEN DELAY GETS TO 1 SECOND
;
OPTIONH:LD A,8 ; TURN ON THE SBC-V2-004+
OUT (RTCIO),A ; CLOCK DIVIDER
LD HL,TmoFct ; AND ADJUST
SRL (HL) ; DELAY FACTOR (/2)
JP MENULP ; BACK TO MENU
OPTIONH:
LD BC,$F8F3 ; GET CURRENT
RST 08 ; SPEED SETTING
LD A,L ; EXIT IF ALREADY
OR A ; HALF SPEED
JP Z,MENULP
;
LD BC,$F9F3 ; TRY TO SWITCH
LD L,0 ; TO HALF SPEED
LD DE,0
RST 08
OR A ; EXIT IF
JP Z,MENULP ; CHANGE FAILS
;
LD HL,TmoFct ; OTHERWISE ADJUST
SRL (HL) ; DELAY FACTOR (/2)
JP MENULP ; BACK TO MENU
;
OPTIONF:LD HL,msgCRLF ; DISPLAY
CALL PRTSTR0 ; BANK
@ -1336,6 +1360,7 @@ MD_FERAC .EQU HBX_LOC-MD_CSIZ+MD_FERAC_R-MD_FSTART ; CALL ADDRESS FOR ERASE FLAS
; Message strings
;
msgHeader: .DB CR,LF,CR,LF,"ROMWBW XMODEM FLASH UPDATER",CR,LF,0
msgPlatform .DB CR,LF,"PLATFORM NOT SUPPORTED",CR,LF,0
msgConfirm: .DB CR,LF,CR,LF,"ENTER Y TO CONFIRM OVERWRITE : ",0
msgInstr: .DB CR,LF,CR,LF,"START TRANSFER OF YOUR UPDATE IMAGE OR ROM",CR,LF,0
msgUserEx: .DB CR,LF,"UPDATER EXITED BY USER",CR,LF,0
@ -1369,7 +1394,6 @@ msgBegin: .DB CR,LF,"(R) Reboot"
.DB CR,LF,"(F) Dump Debug Data"
.DB CR,LF,"(E) Erase Flash chip #1"
.DB CR,LF,"(Z) Erase Flash chip #2"
#ENDIF
.DB CR,LF,CR,LF,"Select : ",0
msgSuccess: .DB CR,LF,CR,LF,"COMPLETED WITHOUT ERRORS ",CR,LF,0

2
Source/pSys/ReadMe.txt

@ -99,7 +99,7 @@ deficient. It insists on polling all of the serial input devices
that it will queue up any characters received. I guess the idea is
that this will help in scenarios where characters are coming in too
fast to be processed. However, the basic/default interpreter does not
support the queues! Strangely, it still polls the the devices and
support the queues! Strangely, it still polls the devices and
literally discards anything received. This completely undermines the
ability of the underlying hardware which is doing it's own robust
interrupt or hardware based buffering and flow control.

Loading…
Cancel
Save