title utility routines IOPVERSION equ -1 entry nulldev, nodev entry getmode, setmode, chgstate entry zero, hladdr, lowercase entry waitid IF IOPVERSION entry times2, times4, times8 entry addhla ext hacontinue ELSE entry hwait, hwakeup, hswitch entry delaylp ext addhla ENDIF ext wait, wakeup list nocond, nogen *maclib macros.z80 *include jsysequ.z80 *include headdef.z80 *include modeequ.z80 ; ----------------------------------------------------------------------------- subttl nulldev and nodev nulldev: IF IOPVERSION call hacontinue ; tell host it can send its next command ENDIF and a,a ; no error ret nodev: ld a,?chnaccess ; channel access error scf ret ; ----------------------------------------------------------------------------- subttl get mode getmode: ; a = mode parameter index ; hl = base displacement of the mode parameters in the device ; de = address of device structure ; returns parameter in a-register ; alters af cp a,MODELEN ; check range of the index jr nc,gsmerx ; out of range? call addhla ; no add hl,de ld a,(hl) ; return parameter value in a-register and a,a ret ; ----------------------------------------------------------------------------- subttl set mode setmode: ; a = mode parameter index ; hl = base displacement of the mode parameters in the device ; de = address of device structure ; b = new parameter value(s) ; c = mask for new parameters (used by SMODE) ; returns: interrupts enabled ; a = the old parameter ; alters af, b cp a,MODELEN ; is the index in range? jr nc,gsmerx push af ; yes. save the index call addhla pop af add hl,de cp a,MD_MODED ; if it's the delay mode, skip CHGSTATE jr z,smx cp a,MD_MODE3 + 1 ; if it's one of the 3 mode flag bytes, di ; let CHGSTATE handle it. call c,chgstate ; smx: ld a,(hl) ; return the old parameter value ld (hl),b ; load the new parameter value ei ret gsmerx: ld a,?badvalue ; out of range scf ret chgstate: ; call with: interrupts disabled ; c = mask for desired state ; b = desired state ; hl -> where the state is stored in memory ; returns: b = the resultant new state ; CY cleared ; alters af, b ld a,c ; mask for new state and a,b ld b,a ; the desired state ld a,c cpl ; complemented mask and a,(hl) ; apply to the old state or a,b ; add the desired bits ld b,a ret IF NOT IOPVERSION ; ----------------------------------------------------------------------------- subttl process wait & wakeup hwait: ; tell host process to wait until awaken ; call with: a = reason for the wait (in bits 6 & 7) ; iy -> device data structure which uses ; the standard heading, HEADDEF.Z80 push hl load hl,(iy+devno) call waitid ; calculate the wait id number hw2: call wait pop hl ret hswitch: ; switch processes push hl ld hl,0 jr hw2 hwakeup: ; wakeup host process ; call with: a = reason for the wakeup (in upper bits) ; iy -> device data structure which uses ; the standard heading, HEADDEF.Z80 push hl load hl,(iy+devno) call waitid call wakeup pop hl ret ; ----------------------------------------------------------------------------- subttl miscellaneous delaylp:; call with: the number of milliseconds of delay in hl ; alters: hl ( & af) save de dl2: ld de,153 ; for 1 millisecond wait dl4: dec de test de jr nz,dl4 dec hl test hl jr nz,dl2 restor de ret ELSE ; ----------------------------------------------------------------------------- subttl multiplication times8: call times2 times4: call times2 times2: ; multiply by 2 ; call with: a = N ; returns: if no overflow, a = N * 2 ; if overflow, a = N times2: rlca ret nc rrca ret ; ----------------------------------------------------------------------------- addhla: ; add (a) to (hl) ; alters af, hl add a,l ld l,a ret nc inc h ret ENDIF ; ----------------------------------------------------------------------------- subttl miscellaneous waitid: ; calculate wait identification number ; call with: a = reason for wait (in bits 7 & 6) ; hl = device number ; returns: hl = wait id res 7,l ; zero bits 6 and 7 of the minor res 6,l ; device number or a,l ; add the reason in bits 7 & 6 ld l,a ; to the minor device number ret zero: ; call with: de -> the beginning of the area to be zeroed ; b = the number of bytes to be zeroed ; alters: af, b push de xor a,a zs2: ld (de),a inc de djnz zs2 pop de ret lowercase: ; convert alphabetic character to lower case cp a,'Z' + 1 ret nc cp a,'A' ret c add a,'a' - 'A' ret hladdr: jp (hl) ; =============================================================================