;======================================================================= ; ; ; S C L O C K ; ; Ampro/Yasbec SmartWatch Utility ; ; by ; Terry Hazen ; 21460 Bear Creek Road ; Los Gatos CA 95030 ; ; Voice.......... (408) 354-7188 ; Zee-Machine.... (408) 245-1420 ; Ladera Znode... (310) 670-9465 ; ;======================================================================= ; ; Revision history ; ---------------- ; ; 02/01/94 To protect against setting the SmartWatch when the file ; v1.9 can't be found (thus the data record can't be written,) ; the Set function first tests for the presence of the ; file on the current du: before allowing the user to set ; the SmartWatch and aborts with an error message if file ; can't be found. When setting the SmartWatch, the reset ; bit of the clock buffer is now set so that the SmartWatch ; will ignore the reset line. ; - Terry Hazen ; ; 12/03/93 Allows setting Ampro or Yasbec n/BIOS Bios clock. ; v1.8 Automatically corrects the SmartWatch time each time the ; Update function is called, based on a linear correction ; factor. This factor is calculated by using the Set ; function to set the SmartWatch from a time standard ; twice, at least several days apart. After SCLOCK has ; been calibrated, the Update function automatically ; updates the ZSDOS system time from the corrected ; SmartWatch time. ; - Terry Hazen ; ; 04/10/93 Now allows setting SmartWatch even if read attempts ; v1.7 fail. This is so we can reset clocks that have been ; brainwashed. ; - Terry Hazen ; ; 03/14/93 Now automatically checks the processor type and uses ; v1.6 the proper EPROM selection technique so it can run on ; both the Ampro and Yasbec. Made sure the cursor was ; restored after a read error. Added type 3 display to ; banner as a reminder that it doesn't run under GO! ; - Terry Hazen ; ; 08/24/92 Revised to zero tenths when setting SmartWatch. Added ; v1.5 code to turn cursor off during continuous clock display. ; Deleted unnecessary CTC reset code. ; - Terry Hazen ; ; 08/18/92 Rewritten to use TDD syntax and to add option to ; v1.4 update ZSDOS or BIOS39+ clock. Added full type 3 ; header. ; - Terry Hazen ; ; 01/20/92 Fixed option parsing bug. ; v1.3 - Terry Hazen ; ; 06/06/91 Sets day of week to 0 to turn on oscillator. Added ; v1.2 BIOS3.9 check, other minor tune-ups. ; - Terry Hazen ; ; 06/10/91 Fixed to not display clock if bad read. ; v1.1 ; - Terry Hazen ; ; 03/24/91 Initial release. ; v1.0 - Terry Hazen ; ;----------------------------------------------------------------------- ; ; Ampro/Yasbec Little Board SmartWatch utility. Read and set the ; SmartWatch using Ampro BIOS 3.9 time/date format. ; In order to update the ZSDOS clock, the UPDATE option requires a ; ZSDOS clock driver with a SET function (such as in the B/P BIOS,) or ; an Ampro BIOS 3.9+, or Ampro or Yasbec n/BIOS BIOS clock (which acts ; as the ZSDOS clock.) ; ; If the UPDATE option is selected, SCLOCK will try to use the ZSDOS ; driver to update the ZSDOS clock from the SmartWatch. If a driver SET ; function error is reported, SCLOCK will check for a supported BIOS and ; if found, will update the BIOS clock from the SmartWatch. ; ; ; *** IMPORTANT NOTE!! *** ; ; Since the EPROM is mapped into memory from 0000h to 8000h when reading ; the SmartWatch, SCLOCK _must_ be assembled as a TYPE 3 or TYPE 4 utility ; loaded and run at 8000H or greater! Supplied as a TYPE 3 at 8000h. ; ;----------------------------------------------------------------------- ; ; Equates ; vers equ 19 month equ 02 day equ 01 year equ 94 ; on equ 0ffh yes equ on off equ 0 no equ off ; fcb equ 5ch bs equ 8 tab equ 9 cr equ 13 lf equ 10 bell equ 7 del equ 7fh ; bdos equ 5 ; ; n/BIOS equates ; nid equ 77h ; Offset to n/BIOS ID ntim equ 3fh ; Offset to n/BIOS date/time jump ; ; Port equates ; control equ 0 ; Ampro EPROM control port bbr equ 39h ; Z180 Bank Base Register port ; ; SmartWatch equates ; read equ 4 ; SmartWatch read wrt1 equ 3 ; SmartWatch - write a 1 wrt0 equ 2 ; SmartWatch - write a 0 ;======================================================================= ; .request jthlib ext fnamz .request pdat ext pday1,pdat1,space,comma .request nztim ext bi2bc,bc2bi,bc2ju,ju2bc,ss2cp ext hour,colon,mini,seco,gbin .request zslib ext gcomnam,comnam,settim ext mullw,divlw,addlw,sublw,neglw .request vlib ext z3vinit,curon,curoff .request z3lib ext z3log .request syslib ext setdma,f$exist,f$open,r$write,f$close ext eprint,epstr,cout,crlf,condin,capin ext pafdc,pa2hc,eval10,comphd,isdigit ;======================================================================= ; ; Type 3 header ; entry: jr start ; Must use relative jump db 0 ; Filler db 'Z3ENV' db 3 ; Type-3 environment z3eadr: dw 0 ; Filled in by Z33 dw entry ; Intended load address ; ;======================================================================= ; ; Configuration area ; cfg: db 'SCLOCK' ; Default CFG filename - 8 bytes db vers/10+'0',vers mod 10+'0' ds cfg+8-$ db 0 ; Termination ; ; Automatic linear time correction configuration ; altc: db yes ; Use automatic linear time correction arch: db no ; Archive file after writing ; ; Default filename [DU:FN.FT] - 16 bytes max ; deffn: db 'A0:SCLOCK19.COM' ; DU:FN.FT ds deffn+16-$,' ' ; Space fill db 0 ; ; Start buffer on line boundary ; ds 16-[$-entry and 15] and 15 ;======================================================================= ; ; The remainder of the first record contains 4 byte 32-bit set archive ; time/date buffers in 'Julian Seconds' format: ; (db low,lmed,hmed,high) ; SST date/times are included for readability but aren't referenced. ; ; Baseline set date/time ; byr: ds 6 ; SST (System Standard Time) ds 6 ; Fill setbase:ds 4 ; JS32 (32-bit Julian Seconds) ; ; Latest set date/time ; syr: ds 1 ; SST smo: ds 1 sda: ds 1 sho: ds 1 smi: ds 1 sse: ds 1 ds 6 ; Fill setnew: ds 4 ; JS32 ; ; Current clock date/time ; tyr: ds 1 ; SW/SST tmo: ds 1 tda: ds 1 tho: ds 1 tmi: ds 1 tse: ds 1 ttx: ds 1 ttn: ds 1 ds 4 ; Fill clktim: ds 4 ; JS32 ; ; Corrected clock date/time ; cyr: ds 1 ; SST cmo: ds 1 cda: ds 1 cho: ds 1 cmi: ds 1 cse: ds 1 ctx: ds 1 ctn: ds 1 ds 4 ; Fill cortim: ds 4 ; JS32 delta: ; Difference corr: ds 4 ; Correction factor ds 6 ; Fill sign: ds 1 ; LCF sign: 0=clock slow, 1=clock fast ds 1 ; Fill lcf: ds 4 ; Linear correction factor ; ; Fill out the remainder of the first record ; ds 128-[$-entry and 127] and 127 ;======================================================================= ; ; Start of type 3 header code ; start: ld hl,0 ; Point to warmboot entry ld a,(hl) ; Save the byte there di ; Protect against interrupts ld (hl),0c9h ; Replace warmboot with a return opcode rst 0 ; Call address 0, pushing ret addr onto stack ; retaddr:ld (hl),a ; Restore byte at 0 dec sp ; Get stack pointer to point dec sp ; To the value of RetAddr pop hl ; Get it into HL and restore stack ei ; We can allow interrupts again ld de,retaddr ; This is where we should be xor a ; Clear carry flag sbc hl,de ; Subtract -- we should have 0 now jp z,start0 ; If addresses matched, begin real code ; add hl,de ; Restore value of retaddr ld de,notz33-retaddr ; Offset to message add hl,de ex de,hl ; Message pointer in DE ld c,9 jp bdos ; Return via BDOS print string function ; notz33: db 'Not Z33+$' ; Abort message if not Z33-compatible ; banner: call eprint pname: db 'SCLOCK ' ; Default program name db 'vers ' db vers/10+'0','.',vers mod 10+'0',0 ret ; ; Help screen ; help: ld hl,pname call gcomnam call banner call eprint db ' - Ampro/Yasbec SmartWatch Utility ' db '(Type 3 at 8000h)',cr,lf db ' Displays SmartWatch date and time',cr,lf db 'Syntax:',cr,lf,' ',0 ; ld hl,comnam ; Point to name call epstr call eprint db ' [/][option]',cr,lf db 'Options:',cr,lf db ' S - Set SmartWatch interactively',cr,lf db ' U - Update ZSDOS clock from SmartWatch',cr,lf db ' C - Display date and time continuously',0 ; ld a,(altc) or a ret z ; Not using correction ; call eprint db cr,lf db ' (Set and Update use Linear Time Correction)',0 ret ;----------------------------------------------------------------------- ; ; Main program start ; start0: ld (stack),sp ld sp,stack ld hl,exit ; Save exit on stack push hl ; ld hl,(z3eadr) ; Set up TCAP pointers call z3vinit ; ld hl,fcb+1 ; Point to fcb name field ld a,'/' ; Option or help cp (hl) ; Option prefix? jr nz,start1 ; No ; inc hl ; Yes, skip prefix cp (hl) ; Help? jp z,help ; Yes, display help screen ; ld hl,fcb+1 ; Point to fcb name field ld a,'/' ; Option or help cp (hl) ; Option prefix? jr nz,start1 ; No ; inc hl ; Yes, skip prefix ; start1: ld a,'C' ; Continuous? cp (hl) jp z,test ; Yes ; ld a,'S' ; Set clock? cp (hl) jp z,setclk ; Yes, set SmartWatch interactively ; ld a,'U' cp (hl) ; Update? jp z,setzst ; Yes, set ZSDOS/BIOS clocks from SmartWatch ; readclk:call rdclk ; Default is to read clock jp z,rderr jp report ; And display date/time ; ; Read the SmartWatch registers ; rdclk: call wakeup ; Init SmartWatch ld hl,tn ; Bottom of sst buffer ; rdclk0: ld b,8 ; Number of bytes to read ; getbyte:ld d,b ; Save byte count ld b,8 ; Set bit count to 8 xor a ; Clear a ld c,a ; Clear c ; getbit: ld a,(read) and a,1 ; Mask lsb or a,c ; OR in bits rrc a ; Move over for next bit ld c,a ; and save results djnz getbit ; ld (hl),a ; Put in buffer dec hl ; Next byte location ld b,d ; Restore byte count djnz getbyte ; call epoff ; Turn off EPROM ld a,(da) ; Day and a ; Set flags ret z ; Register should be non-zero inc a ; Set Z if 0ffh ret ; ; Display date and time ; report: ld de,yr ; Point to clock buffer call pday1 call space call pdat1 call dash inc de ; Skip day of week ; ; Display time ; ptim: call hour call pafdc ld a,l cp 12 push af call colon call mini call bi2bc call pa2hc call colon call seco call bi2bc call pa2hc ld a,'.' call cout ld hl,6 call gbin call bi2bc call pa2hc call space pop af ld a,'a' jr c,ptimx ; ld a,'p' ; ptimx: call cout ld a,'m' jp cout ; ; Get user input to set SmartWatch ; setclk: call banner ; Display program name and version call dash call rdclk ; Read clock push af call nz,report ; Display time if no read error pop af call z,crlf ; Else blank line ; ld a,(altc) ; Automatic adjustment? or a call nz,filchk ; Yes, find and open file ; call settime call crlf ; Add new line call report call eprint db cr,lf,'Next keypress will set the SmartWatch - ',0 call capin ; Get keypress cp 3 ret z ; ^C, forget it ; ; Read current clock time ; call wakeup ld hl,ttn call rdclk0 ; Read current time to TTN(SW) ld hl,dw ld (hl),10h ; Set to ignore reset call wrclk ; Set SmartWatch ; ld hl,syr ; Make new base archive TD ld de,byr ; at BYR(SST)/SETBASE(JS32) ld bc,16 ldir ; call swsst ; Convert YR(SW) to (SYR)SST ld hl,syr ; Convert SYR(SST) to SETNEW(JS32) ld de,setnew call ss2js ; ld hl,setnew ; Copy it to LCF buffer ld de,lcf ld bc,4 push hl push bc ldir pop bc ; And to DELTA buffer pop hl ld de,delta ldir ; ld hl,tmi ; Convert TYR(SW) to TYR(SST) ld de,tho call swsst0 ld hl,0 ; Clear last two bytes for clarity ld (ttx),hl call convclk ; Convert TYR(SST) to CLKTIM(JS32) ; ld hl,delta ld de,clktim call sublw ; Get difference ld a,0 jr nc,clkslo ; Clock is running slow ; call neglw ; Two's complement, because inc a ; Clock is running fast ; clkslo: ld (sign),a ; 0=slow clock, 0ffh=fast clock ; ld hl,lcf ld de,setbase call sublw ; LCF=setnew-setbase ; ld de,delta call divlw ; Calculate LCF and fall thru ; ; Write data file ; wrtfile:ld hl,entry ; Point to start of first record call setdma ld hl,0 ; Write first record back to disk ld de,fcb ; Point to fcb call r$write jr nz,ferr ; Report disk error ; call f$close ; Close the file jr nz,ferr ; Report disk error ; ld a,(arch) ; Check archive flag or a ret z ; No, we're done ; push de ; Save fcb pointer ld hl,11 ; Archive bit offset add hl,de set 7,(hl) ; Set archive bit pop de ; Restore fcb pointer ld c,30 ; Set file to archived jp bdos ; ; Check for and open file ; filchk: ld hl,deffn ld de,fcb call fnamz call z3log call f$exist ; Test for file jr z,nofil ; Can't find file ; call f$open ; Open file inc a ; Check status ret nz ; Ok ; ; General file error message ; ferr: call eprint db cr,lf,'Disk/File Error!',bell,0 jp exit ; ; No file ; nofil: call eprint db cr,lf,'Can''t find file!',bell,0 jp exit ; ; Write new time/date to SmartWatch ; wrclk: call wakeup ; Init SmartWatch ld hl,tn ; Point to bottom of clock buffer ld b,8 ; Number of bytes to write ; putbyte:ld d,b ; Save byte count ld b,8 ; Number of bits to write ld a,(hl) ; Get byte to write ; putbit: rra ld c,a ; Save byte jr c,putone ld a,(wrt0) ; Write a zero jr pb1 ; putone: ld a,(wrt1) ; Write a one ; pb1: ld a,c ; Get byte back djnz putbit ; dec hl ; Next byte ld b,d ; Byte count djnz putbyte ; ; Turn off EPROM ; epoff: ld a,(z80) ; Test for processor or a ld a,(poff) jr z,z80off ; dw 39edh ; Z180 out0_(39h),a instruction db bbr ; Reselect original bank ret ; z80off: out (control),a ret ; dash: call eprint db ' - ',0 ret ; ; Get new time from user ; settime:call eprint db cr,lf,tab,'Year: (',0 ld a,(yr) call pget jr z,setmo call eval ld (yr),a ; setmo: call eprint db cr,lf,tab,'Month: (',0 ld a,(mo) call pget jr z,setda call eval ld (mo),a ; setda: call eprint db cr,lf,tab,'Day: (',0 ld a,(da) call pget jr z,sethr call eval ld (da),a ; sethr: call eprint db cr,lf,tab,'Hour: (',0 ld a,(hr) call pget jr z,setmi call eval ld (hr),a ; setmi: call eprint db cr,lf,tab,'Minute: (',0 ld a,(mi) call pget jr z,setse call eval ld (mi),a ; setse: call eprint db cr,lf,tab,'Second: (',0 ld a,(se) call pget jr z,setex call eval ; setex: ld (se),a xor a ; Set day of week to 0 ld (dw),a ; This turns on reset and oscillator ld (tn),a ; And zero tenths jp crlf ; pget: call pa2hc ld a,')' call cout call space call tline or a ret ; eval: call eval10 jp bi2bc ; ; Initialize the SmartWatch ; wakeup: ld bc,501h ; Test for Z180 dw 4cedh ; Z180 mlt_bc instruction - Z80 ignores it ld a,c dec a ld (z80),a ; 0=Z80, 1=Z180 jr nz,on180 ; EPROM already available ; ld bc,control ; Get Z80 port xor a out (control),a ; Turn on EPROM jr wake0 ; on180: dw 38edh ; Z180 in0_a,(39h) db bbr ; Bank register port ld (poff),a ; Save current bank number xor a dw 39edh ; Z180 out0_(39h),a instruction db bbr ; Select bank 0 (EPROM) ; wake0: ld hl,wakepat ld b,8 ; Byte count ld a,(read) ; Reset clock ; wakebyte: ld d,b ; Save byte count in 'd' ld b,8 ; Bit count ld a,(hl) ; Get first char ; wakebit:rra ld c,a ; Save byte jr c,wrtone ; ld a,(wrt0) ; Write zero jr wake1 ; wrtone: ld a,(wrt1) ; Write one ; wake1: ld a,c ; Restore pattern djnz wakebit ; Bit count ; ld b,d ; Get byte count back inc hl ; Next pattern location djnz wakebyte ret ; ; Test the SmartWatch by reading until interrupted by console input ; test: call curoff ; Turn off cursor ; test0: call rdclk ; Read clock ret z ; Quit if read error ; ld de,mo ; Point to clock buffer (skip day of week) call ptim ; Display time call condin ; Get character or status ret nz ; Quit when any character entered ; ld a,cr ; Else prepare to update display call cout jr test0 ; ; Set ZSDOS/BIOS clocks from SmartWatch ; setzst: call rdclk ; Read SmartWatch to YR(SW) jp z,rderr ; Quit if error ; ld hl,yr ; Convert YR(SW) ld de,tyr ; To TYR(SST) ld bc,3 ldir inc hl ; Skip day of week call swsst0 call convclk ; Convert TYR(SST) to CLKTIM(JS32) ; ld hl,tyr ; Copy TYR/CLKTIM to corrected time ld de,cyr ; buffers CYR/CORTIM ld bc,16 ldir ; ld a,(altc) ; Automatic adjustment? or a call nz,update ; Yes, adjust the clock time ; call report ; Display SmartWatch date/time ld hl,cyr ; Point to corrected clock buffer call settim ; Set ZSDOS clock jr nz,nozsc ; Set error, assume no ZSDOS clock set ; ld hl,zmsg ; Display set message jp setmsg ; nozsc: ld ix,(z3eadr) ; Get ENV pointer ld h,(ix+2) ; Get CBIOS pointer ld a,h or a jr nz,noz0 ; ld hl,(1) ; Use warm boot pointer ; noz0: ld l,nid ; Offset to n/BIOS ID ld a,(hl) ld l,ntim ; Offset to n/BIOS date/time jump cp 'n' jr z,getptr ; n/BIOS ; ld l,51 ; Ampro extended table call call jphl ; A=BIOS version, HL=NXTTBL pointer cp 39 ; NC if version 3.9+ ld de,badbio ; No, BIOS error jp c,error ; ld de,12 ; Offset to date/time jump add hl,de ; getptr: call jphl ld a,h ; HL=BIOS date buffer or l ; Test for clock ld de,badbio ; No clock jp z,error ; ld de,cyr ; Point to corrected SST buffer di call ss2cp ; Convert it to julian format ld a,(de) ; Move seconds ld (hl),a inc hl ld (hl),0 ; Zero tenths ei ; ld hl,bzmsg ; setmsg: call eprint db cr,lf,' - Setting ',0 call epstr call eprint db ' clock ',0 ; ld a,(altc) ; Check correction or a jr z,setm0 ; None performed ; call eprint setm1 db 'using corrected SmartWatch time:',cr,lf,0 ld de,cyr call pday1 call space call pdat1 call dash jp ptim ; setm0: call eprint db 'from SmartWatch',0 ret ; rderr: ld de,rdermsg ; Point to message and fall thru ; error: ex de,hl ; Message pointer in HL call epstr ; Display error message and quit ; exit: call crlf call curon ; Turn cursor back on before leaving ld sp,(stack) ret ;----------------------------------------------------------------------- ; ; Subroutines ; jphl: jp (hl) ; Call (hl) ; compid: ld b,3 ; complp: ld a,(de) cp (hl) ret nz inc hl inc de djnz complp ret ; ; Copy SmartWatch YS(SW) buffer to SYR(SST) ; swsst: ld hl,yr ; Copy SW buffer ld de,syr ; To SST buffer ld bc,3 ldir inc hl ; Skip day of week ; swsst0: ld bc,3 ldir ret ; ; Correct clock time and reset smartwatch if required ; update: ld hl,setbase ; Can't update if only one baseline call nulchk ; Check for null entry ret z ; Empty, so we're done ; ld hl,clktim ; Copy it to CORR(JS32) ld de,corr ld bc,4 ldir ; ld hl,corr ; Get SETNEW-CORR push hl ; Save pointer ld de,setnew call sublw ld de,lcf call divlw ; Calculate LCF=LCF/(SETNEW-CORR) pop hl ; Restore correction pointer call nulchk ; Quit if no correction required ret z ; ld hl,cortim ; Set buffer pointers for correction ld de,corr ld a,(sign) ; Check if fast or slow or a jr nz,upd0 ; Fast ; call addlw ; Clock is slow, add correction jr upd1 ; upd0: call sublw ; Clock is fast, subtract correction ; upd1: jp js2cyr ; Convert CORTIM(JS32) to CYR(SST) ; ; Check JS32 buffer for null ; Enter:HL=buffer pointer ; Exit: Z if 0,0,0,0 ; nulchk: ld b,4 ; nullp: ld a,(hl) ; Check first two bytes inc hl or a ret nz ; Not null djnz nullp ; ld (altc),a ; Turn off correction ret ; ; Convert TYR(SST) to CLKTIM(JS32) ; convclk:ld hl,tyr ; Point to clock time ld de,clktim ; And fall thru ; ; Convert time from SST format to 32-bit Julian Seconds format ; Entry:HL=pointer to SST buffer ; DE=pointer to JS32 buffer ; Uses: All ; ss2js: ld (ssptr),hl ; Save pointers ld (jsptr),de ; ex de,hl call bc2ju ; Convert yr/mo/day to Julian days ld b,2 call fillb ; Zero out the rest of the buffer ld hl,temp ; And TEMP buffer ld b,4 call fillb ; ld hl,24 ; Convert to hours call multhl ; ld hl,(ssptr) inc hl inc hl inc hl ; Point to hour push hl ; Save SST pointer call mov32 ; Add in hours ; call mult60 ; Convert to minutes pop hl ; Restore SST pointer inc hl ; Point to minutes push hl ; Save SST pointer call mov32 ; Add in minutes ; call mult60 ; Convert to seconds pop hl ; Restore SST pointer inc hl ; Point to seconds and fall thru ; ; Convert byte pointed to by HL binary, add it to JS32 buffer ; mov32: ld a,(hl) ; Get it call bc2bi ; Convert to binary ld h,0 ld l,a ld (temp),hl ; Make sure higher byte is zero'd ld de,temp ; Point to buffers ld hl,(jsptr) ; JS32 pointer jp addlw ; Add it in ; ; Multiply by 60 ; mult60: ld hl,60 ; Multiply by 60 ; ; Multiply JS32 buffer by value in HL ; Exit: HL points to result in JS32 buffer ; multhl: ld (temp),hl ; Save in temp buffer ld de,temp ; Point to temp buffer ld hl,(jsptr) ; Point to JS32 buffer jp mullw ; Do multiplication ; ; Convert time from CORTIM(JS32) to CYR(SST) ; js2cyr: ld hl,cortim call div60 ; Convert TIMDAT3 to minutes ld a,(de) ; Get seconds (remainder) call bi2bc ; Convert to BCD ld (cse),a ; Save it in SST buffer ; call div60 ; Convert to hours ld a,(de) ; Get minutes (remainder) call bi2bc ; Convert to BCD ld (cmi),a ; Save it in SST buffer ; ld de,24 call divde ; Convert to days ld a,(de) ; Get hours (remainder) call bi2bc ; Convert to BCD ld (cho),a ; Save it in SST buffer ; ld de,cyr ; Point to SST buffer jp ju2bc ; Convert to YY MM DD ; ; Divide by 60 ; div60: ld de,60 ; Divide by 60 ; ; Divide JS32 buffer by value in DE ; Entry:HL points to JS32 buffer ; DE = dividend ; Exit: HL points to result in JS32 buffer ; DE points to remainder JS32 buffer ; divde: ld (temp),de ; Save in temp buffer ld de,temp ; Point to temp buffer jp divlw ; Do multiplication ; ; In-line editor. Only backspace and delete are available for editing input ; line. Rejects other control characters, except: ; - ends edit, buffer contains null-terminated string, A=length ; - ^C aborts as if no entry made ; Exit: HL = start of string ; A = number of characters in string ; Uses: AF,BC,DE ; tline: ld hl,tbuf push hl ld b,2 ld d,b ; D=buffer length ld e,0 ; E=character count ; tloop: call capin cp 3 ; Quit? jp z,exit cp cr ; Carriage return? jr z,tlend cp bs ; Backspace? jr z,isbs cp del ; Delete? jr z,isbs cp ' ' ; Control character? jr c,isctrl ; call isdigit ; 0-9? jr nz,alarm ; No ; inc d ; Check number of characters dec d jr z,alarm ; Past end of buffer ; ld (hl),a ; Store character call cout ; Echo it inc hl ; Increment buffer pointer dec d ; Decrement character counter inc e ; Increment character count jr tloop ; ; We're at the beginning or end of the buffer and somebody's trying to ; push through the boundary. Ring the console and do nothing. ; alarm: ld a,bell call cout jr tloop ; ; We have a backspace or delete. If we're not at the beginning ; of the buffer, we backspace 1 character, print a space, and backspace ; again, erasing the last character on the screen. At the beginning of ; the buffer we ring the console and do nothing. ; isbs: ld a,d ; Put character counter in A cp b ; Compare to buffer length in B jr z,alarm ; At beginning of buffer ; call eprint db bs,' ',bs,0 ; inc d ; Increment character counter dec e ; Decrement character count dec hl ; Decrement buffer pointer jr tloop ; isctrl: cp 3 ; ^C ? jr nz,alarm ; No, continue ; pop hl ; Yes, restore buffer pointer push hl ; Save it again ld e,0 ; Clear count ; tlend: ld (hl),0 ; Terminate buffer ; tlend1: pop hl ; Restore buffer pointer ld a,e ; Return with character count in A or a ; Set input flag and quit ret ; ; Fill HL with 0 for B bytes ; fillb: ld (hl),0 inc hl djnz fillb ret ;======================================================================= ; ; Initialized data ; bzmsg: db 'Bios/' zmsg: db 'ZSDOS',0 ; rdermsg:db 'SmartWatch read error!',bell,0 ; badbio: db 'Requires a ZSDOS clock driver with SET,',cr,lf db 'Ampro/Yasbec n/BIOS or Ampro BIOS 3.9+!',bell,0 ; wakepat:db 0c5h,03ah,0a3h,05ch,0c5h,03ah,0a3h,05ch ; poff: db 41h ; Ampro EPROM off control byte and ; Z180 current bank number storage ;======================================================================= ; ; Uninitialized data ; dseg z80: ds 1 ; Processor flag (0=Z80, 1=Z180) tbuf: ds 3 ; Console input buffer for Set ; ; Clock buffer - SST format except for day/wk and tenths ; yr: ds 1 ; Year (00-99) mo: ds 1 ; Month (01-12) da: ds 1 ; Date (01-31) dw: ds 1 ; Day/wk (01-07) hr: ds 1 ; Hour (00-23) mi: ds 1 ; Minutes (00-59) se: ds 1 ; Seconds (00-59) tn: ds 1 ; Tenths (00-99) ; ssptr: ds 2 ; SST buffer pointer jsptr: ds 2 ; JS32 buffer pointer temp: ds 4 ; Temporary JS32 buffer ; ds 64 stack: ds 2 end ; ; End of SCLOCK.Z80 ;