mirror of https://github.com/wwarthen/RomWBW.git
5 changed files with 1954 additions and 20 deletions
@ -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 |
|||
|
|||
|
|||
File diff suppressed because it is too large
@ -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 |
|||
; |
|||
@ -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…
Reference in new issue