Browse Source

Added source Code for copySL, build scripts not updated

pull/507/head
Mark Pruden 11 months ago
parent
commit
f7b8efd964
  1. 328
      Source/Apps/copysl/cio.asm
  2. 1319
      Source/Apps/copysl/copysl.asm
  3. 1
      Source/Apps/copysl/copysl.doc
  4. 110
      Source/Apps/copysl/crc.asm
  5. 178
      Source/Apps/copysl/hbios.asm

328
Source/Apps/copysl/cio.asm

@ -0,0 +1,328 @@
BDOS .EQU 5
; bdos commands
CONIN .EQU 1
CONOUT .EQU 2
DIRCONIO .EQU 6
; TODO for more routines see assign.asm
; ===============
; INPUT
; Console Input
getchr:
PUSH BC
PUSH DE
PUSH HL
LD C,CONIN
CALL BDOS
POP HL
POP DE
POP BC
RET
; direct console io
; BDOS 6 - FF FE FD - commands
conread:
RET
constatus:
RET
coninput:
RET
; =======================================
; STANDARD OUTPUT
;
; Print character in A without destroying any registers
;
prtchr:
; PUSH AF
PUSH HL ; We must preserve HL, as the BDOS call sets it
PUSH BC
PUSH DE
LD C, CONOUT
LD E, A
CALL BDOS
POP DE
POP BC
POP HL
; POP AF
RET
;
prtdot:
push af
ld a, '.'
call prtchr
pop af
ret
;
; Print a zero terminated string at (HL) without destroying any registers
;
prtstr:
PUSH AF
PUSH BC
push de
prtstr1:
ld a,(hl)
or 0
jr z,prtstr2
ld c, CONOUT
ld e,a
push hl
call BDOS
pop hl
inc hl
jr prtstr1
prtstr2:
pop de
pop bc
pop af
ret
;
; Print the value in A in hex without destroying any registers
;
prthex:
push af ; save AF
push de ; save DE
call hexascii ; convert value in A to hex chars in DE
ld a,d ; get the high order hex char
call prtchr ; print it
ld a,e ; get the low order hex char
call prtchr ; print it
pop de ; restore DE
pop af ; restore AF
ret ; done
;
; print the hex word value in bc
;
prthexword:
push af
ld a,b
call prthex
ld a,c
call prthex
pop af
ret
;
; Convert binary value in A to ascii hex characters in DE
;
hexascii:
ld d,a ; save A in D
call hexconv ; convert low nibble of A to hex
ld e,a ; save it in E
ld a,d ; get original value back
rlca ; rotate high order nibble to low bits
rlca
rlca
rlca
call hexconv ; convert nibble
ld d,a ; save it in D
ret ; done
;
; Convert low nibble of A to ascii hex
;
hexconv:
and 0Fh ; low nibble only
add a,90h
daa
adc a,40h
daa
ret
;
; Print the decimal value of A, with leading zero suppression
;
prtdec:
push hl
ld h,0
ld l,a
call prtdecword ; print it
pop hl
ret
;
; Print the Decimal value (word) in HL
;
prtdecword:
push af
push bc
push de
push hl
call prtdec0
pop hl
pop de
pop bc
pop af
ret
;
prtdec0:
ld e,'0'
ld bc,-10000
call prtdec1
ld bc,-1000
call prtdec1
ld bc,-100
call prtdec1
ld c,-10
call prtdec1
ld e,0
ld c,-1
prtdec1:
ld a,'0' - 1
prtdec2:
inc a
add hl,bc
jr c,prtdec2
sbc hl,bc
cp e
ret z
ld e,0
call prtchr
ret
;
; Print a byte buffer in hex pointed to by DE
; Register A has size of buffer
;
prthexbuf:
or a
ret z ; empty buffer
prthexbuf1:
ld a,' '
call prtchr
ld a,(de)
call prthex
inc de
djnz prthexbuf1
ret
;
; Start a new Line
;
prtcrlf2:
call prtcrlf
prtcrlf:
push hl
ld hl, prtcrlf_msg
call prtstr
pop hl
ret
prtcrlf_msg:
.DB 13,10,0
; =================================
; following is from dmamon util.asm
;
; IMMEDIATE PRINT
; =================================
;
; PRINT A CHARACTER REFERENCED BY POINTER AT TOP OF STACK
; USAGE:
; CALL IPRTCHR
; .DB 'X'
;
iprtchr:
EX (SP),HL
PUSH AF
LD A,(HL)
CALL prtchr
POP AF
INC HL
EX (SP),HL
RET
; Print a string referenced by pointer at top of stack
; Usage
; call iprtstr
; .DB "text", 0
;
iprtstr:
EX (SP),HL
CALL prtstr
INC HL
EX (SP),HL
RET
;
; ===========================================================
;
; Following is for INPUT, used to process command line args
;
; ===========================================================
;
; Skip whitespace at buffer adr in DE, returns with first
; non-whitespace character in A.
;
skipws:
ld a,(hl) ; get next char
or a ; check for eol
ret z ; done if so
cp ' ' ; blank?
ret nz ; nope, done
inc hl ; bump buffer pointer
jr skipws ; and loop
;
; Uppercase character in A
;
upcase:
cp 'a' ; below 'a'?
ret c ; if so, nothing to do
cp 'z'+1 ; above 'z'?
ret nc ; if so, nothing to do
and ~020h ; convert character to lower
ret ; done
;
; Get numeric chars at HL and convert to number returned in A
; Carry flag set on overflow
; C is used as a working register
;
getnum:
ld c,0 ; C is working register
getnum1:
ld a,(hl) ; get the active char
cp '0' ; compare to ascii '0'
jr c,getnum2 ; abort if below
cp '9' + 1 ; compare to ascii '9'
jr nc,getnum2 ; abort if above
;
ld a,c ; get working value to A
rlca ; multiply by 10
ret c ; overflow, return with carry set
rlca ; ...
ret c ; overflow, return with carry set
add a,c ; ...
ret c ; overflow, return with carry set
rlca ; ...
ret c ; overflow, return with carry set
ld c,a ; back to C
ld a,(hl) ; get new digit
sub '0' ; make binary
add a,c ; add in working value
ret c ; overflow, return with carry set
ld c,a ; back to C
;
inc hl ; bump to next char
jr getnum1 ; loop
;
getnum2:
ld a,c ; return result in A
or a ; with flags set, CF is cleared
ret
;
; Is character in A numeric? NZ if not
;
isnum:
cp '0' ; compare to ascii '0'
jr c,isnum1 ; abort if below
cp '9' + 1 ; compare to ascii '9'
jr nc,isnum1 ; abort if above
cp a ; set Z
ret
isnum1:
or 0FFh ; set NZ
ret ; and done

1319
Source/Apps/copysl/copysl.asm

File diff suppressed because it is too large

1
Source/Apps/copysl/copysl.doc

@ -95,4 +95,3 @@ Future
This would be at the cost of performance
* ability to abort once the copy has started <ctrl><c>


110
Source/Apps/copysl/crc.asm

@ -0,0 +1,110 @@
;
; Simple Block Compare for Comparison purposes
; Both HL and DL contain Block pointers to compare
; HL MUST start on an even block e.g. 8000h
; RET NZ - Failure, Z if no issue
;
_cmp20block
; inc de ; uncommnet to test crc fail!
ld bc, 20h ; 10t Size of Pointer Increment
_cmp20block1:
ld a, (de) ; 7t Do The comparison itself
cp (hl) ; 7t
JR NZ, _cmp20block2 ; 7t / 12t = 21t
add hl, bc ; 11t Add the Increment to both pointers
ex de, hl ; 4t
add hl, bc ; 11t
ex de, hl ; 4t = 30t
ld a, h ; 4t High order byte on Even Boundary
bit 4, a ; 8t has bit 4 been set then exceeded 1000h (4k boundary)
JR Z, _cmp20block1 ; 12t / 7t = 24t
xor a ; 4t
RET ; 10t Return Success
_cmp20block2:
scf ; signal CARRY FLAG Also
RET ; This is the error
; clock cycles for above
; add 40h -> 64 (loop) * 73t =>> 4,672 - 1.56%
; add 20h ->128 (loop) * 73t =>> 9,344 - 3.13% <= WENT WITH THIS
; add 10h ->256 (loop) * 73t =>> 18,688 - 6.25%
; accuracy = 88/4096 => 2.1%
; =====================================================================
; From : https://tomdalby.com/other/crc.html
; And : https://map.grauw.nl/sources/external/z80bits.html#6.1
; =====================================================================
;
; =====================================================================
; input - hl=start of memory to check, de=length of memory to check
; returns - a=result crc
; 20b
; =====================================================================
; THE COMMNETED LINES NEED TO BE UNCOMMENTED
_crc8b:
xor a ; 4t - initial value so first byte can be XORed in (CCITT)
; ld c, 07h ; 7t - c=polyonimal used in loop (small speed up)
_byteloop8b:
xor (hl) ; 7t - xor in next byte, for first pass a=(hl)
inc hl ; 6t - next mem
; ld b, 8 ; 7t - loop over 8 bits
_rotate8b:
; add a,a ; 4t - shift crc left one
; jr nc, _nextbit8b ; 12/7t - only xor polyonimal if msb set (carry=1)
; xor c ; 4t - CRC8_CCITT = 0x07
_nextbit8b:
; djnz _rotate8b ; 13/8t
ld b,a ; 4t - preserve a in b
dec de ; 6t - counter-1
ld a,d ; 4t - check if de=0
or e ; 4t
ld a,b ; 4t - restore a
jr nz, _byteloop8b ; 12/7t
ret ; 10t
; Clock Cycle For above with 4k bypes
; Loop = 4096 * 47 cycles + 11 => 192,523 x 2 (src/dest) => 385,046
; acuracy = 1 / 256 => 0.4 %
; =====================================================================
; CRC-CCITT
;
; CCITT polynomial 1021h
; Initial Value FFFFh
;
; input - de=start of memory to check, bc=length of memory to check
; returns - hl=result crc
; =====================================================================
_crc16:
ld hl, 0ffffh ; 10t - initial crc = $ffff
_byte16:
; push bc ; 11t - preserve counter
ld a,(de) ; 7t - get byte
inc de ; 6t - next mem
; xor h ; 4t - xor byte into crc high byte
; ld h,a ; 4t - back into high byte
; ld b,8 ; 7t - rotate 8 bits
_rotate16:
; add hl,hl ; 11t - rotate crc left one
; jr nc,_nextbit16 ; 12/7t - only xor polyonimal if msb set
; ld a,h ; 4t
; xor 10h ; 7t - high byte with $10
; ld h,a ; 4t
; ld a,l ; 4t
; xor 21h ; 7t - low byte with $21
; ld l,a ; 4t - hl now xor $1021
_nextbit16:
; djnz _rotate16 ; 13/8t - loop over 8 bits
; pop bc ; 10t - bring back main counter
dec bc ; 6t
ld a,b ; 4t
or c ; 4t
jr nz,_byte16 ; 12/7t
ret ; 10t
;

178
Source/Apps/copysl/hbios.asm

@ -0,0 +1,178 @@
;
; HBIOS FUNCTIONS
;
;
BF_DIO .EQU 010H
BF_DIOSTATUS .EQU BF_DIO + 0 ; DISK STATUS
BF_DIORESET .EQU BF_DIO + 1 ; DISK RESET
BF_DIOSEEK .EQU BF_DIO + 2 ; DISK SEEK
BF_DIOREAD .EQU BF_DIO + 3 ; DISK READ SECTORS
BF_DIOWRITE .EQU BF_DIO + 4 ; DISK WRITE SECTORS
BF_DIOVERIFY .EQU BF_DIO + 5 ; DISK VERIFY SECTORS
BF_DIOFORMAT .EQU BF_DIO + 6 ; DISK FORMAT TRACK
BF_DIODEVICE .EQU BF_DIO + 7 ; DISK DEVICE INFO REPORT
BF_DIOMEDIA .EQU BF_DIO + 8 ; DISK MEDIA REPORT
BF_DIODEFMED .EQU BF_DIO + 9 ; DEFINE DISK MEDIA
BF_DIOCAP .EQU BF_DIO + 10 ; DISK CAPACITY REPORT
BF_DIOGEOM .EQU BF_DIO + 11 ; DISK GEOMETRY REPORT
;
BF_SYS .EQU 0F0H
BF_SYSRESET .EQU BF_SYS + 0 ; SOFT RESET HBIOS
BF_SYSVER .EQU BF_SYS + 1 ; GET HBIOS VERSION
BF_SYSSETBNK .EQU BF_SYS + 2 ; SET CURRENT BANK
BF_SYSGETBNK .EQU BF_SYS + 3 ; GET CURRENT BANK
BF_SYSSETCPY .EQU BF_SYS + 4 ; BANK MEMORY COPY SETUP
BF_SYSBNKCPY .EQU BF_SYS + 5 ; BANK MEMORY COPY
BF_SYSALLOC .EQU BF_SYS + 6 ; ALLOC HBIOS HEAP MEMORY
BF_SYSFREE .EQU BF_SYS + 7 ; FREE HBIOS HEAP MEMORY
BF_SYSGET .EQU BF_SYS + 8 ; GET HBIOS INFO
BF_SYSSET .EQU BF_SYS + 9 ; SET HBIOS PARAMETERS
BF_SYSPEEK .EQU BF_SYS + 10 ; GET A BYTE VALUE FROM ALT BANK
BF_SYSPOKE .EQU BF_SYS + 11 ; SET A BYTE VALUE IN ALT BANK
BF_SYSINT .EQU BF_SYS + 12 ; MANAGE INTERRUPT VECTORS
;
BF_SYSGET_CIOCNT .EQU 00h ; GET CHAR UNIT COUNT
BF_SYSGET_CIOFN .EQU 01h ; GET CIO UNIT FN/DATA ADR
BF_SYSGET_DIOCNT .EQU 10h ; GET DISK UNIT COUNT
BF_SYSGET_DIOFN .EQU 11h ; GET DIO UNIT FN/DATA ADR
BF_SYSGET_RTCCNT .EQU 20h ; GET RTC UNIT COUNT
BF_SYSGET_DSKYCNT .EQU 30h ; GET DSKY UNIT COUNT
BF_SYSGET_VDACNT .EQU 40h ; GET VDA UNIT COUNT
BF_SYSGET_VDAFN .EQU 41h ; GET VDA UNIT FN/DATA ADR
BF_SYSGET_SNDCNT .EQU 50h ; GET VDA UNIT COUNT
BF_SYSGET_SNDFN .EQU 51h ; GET SND UNIT FN/DATA ADR
BF_SYSGET_TIMER .EQU 0D0h ; GET CURRENT TIMER VALUE
BF_SYSGET_SECS .EQU 0D1h ; GET CURRENT SECONDS VALUE
BF_SYSGET_BOOTINFO .EQU 0E0h ; GET BOOT INFORMATION
BF_SYSGET_CPUINFO .EQU 0F0h ; GET CPU INFORMATION
BF_SYSGET_MEMINFO .EQU 0F1h ; GET MEMORY CAPACTITY INFO
BF_SYSGET_BNKINFO .EQU 0F2h ; GET BANK ASSIGNMENT INFO
BF_SYSGET_CPUSPD .EQU 0F3h ; GET CLOCK SPEED & WAIT STATES
BF_SYSGET_PANEL .EQU 0F4h ; GET FRONT PANEL SWITCHES VAL
BF_SYSGET_APPBNKS .EQU 0F5h ; GET APP BANK INFORMATION
;
; MEDIA ID VALUES
;
MID_NONE .EQU 0
MID_MDROM .EQU 1
MID_MDRAM .EQU 2
MID_RF .EQU 3
MID_HD .EQU 4
MID_FD720 .EQU 5
MID_FD144 .EQU 6
MID_FD360 .EQU 7
MID_FD120 .EQU 8
MID_FD111 .EQU 9
MID_HDNEW .EQU 10
; -----------------
;
; Read timer in sconds.
;
sysgetseconds:
ld b,BF_SYSGET
ld c,BF_SYSGET_SECS
rst 08 ; do it
ret
; -----------------
;
; Return non zero if A (media ID)
; is a type of hard drive
; If not A=0 and Z flag is set
;
isaharddrive:
cp MID_HD
jr z, ishdd1
cp MID_HDNEW
jr z, ishdd1
xor a ; clear A and set Z flag
ret
ishdd1:
or a ; set Z flag and return
ret
; -------------------------------------
;
; used to pass the buffer address argument
;
bankid .DB 0 ; bank id used for read writes
dma .DW 8000h ; address argument for read write
;
;
; basic setup for disk io
; call to get the current bank IO
;
initdiskio:
; Get current RAM bank
ld b,BF_SYSGETBNK ; HBIOS GetBank function
RST 08 ; do it via RST vector, C=bank id
JP NZ, err_hbios
ld a,c ; put bank id in A
ld (bankid),a ; put bank id in Argument
RET
;
;
; Read disk sector(s)
; DE:HL is LBA, B is sector count, C is disk unit
; (dma) is the buffer address
; (bankid) is the memory bank
; Returns E sectors read, and A status
;
diskread:
; Seek to requested sector in DE:HL
push bc ; save unit & count
set 7,d ; set LBA access flag
ld b,BF_DIOSEEK ; HBIOS func: seek
rst 08 ; do it
pop bc ; recover unit & count
jp nz,err_diskio ; handle error
; Read sector(s) into buffer
ld e,b ; transfer count
ld b,BF_DIOREAD ; HBIOS func: disk read
ld hl,(dma) ; read into info sec buffer
ld a,(bankid) ; user bank
ld d,a
rst 08 ; do it
jp nz,err_diskio ; handle error
xor a ; signal success
ret ; and done
;
; Write disk sector(s)
; DE:HL is LBA, B is sector count, C is disk unit
; (dma) is the buffer address
; (bankid) is the memory bank
; Returns E sectors written, and A status
;
diskwrite:
; Seek to requested sector in DE:HL
push bc ; save unit & count
set 7,d ; set LBA access flag
ld b,BF_DIOSEEK ; HBIOS func: seek
rst 08 ; do it
pop bc ; recover unit & count
jp nz,err_diskio ; handle error
; Write sector(s) from buffer
ld e,b ; transfer count
ld b,BF_DIOWRITE ; HBIOS func: disk write
ld hl,(dma) ; write from sec buffer
ld a,(bankid) ; user bank
ld d,a
rst 08 ; do it
jp nz,err_diskio ; handle error
xor a ; signal success
ret ; and done
;
err_diskio:
; push hl
; ld hl,str_err_prefix
; call prtstr
; pop hl
; or 0ffh ; signal error
ret ; done
;str_err_prefix db 13,10,13,10,"*** ",0
Loading…
Cancel
Save