diff --git a/assert.asm b/assert.asm index 529a9bf..b04cc9b 100644 --- a/assert.asm +++ b/assert.asm @@ -34,9 +34,9 @@ __assert start csubroutine (4:f,2:l,4:s),0 - ph4 s - ph2 l - ph4 f + ph4 __assertfp jsl fprintf diff --git a/assert.macros b/assert.macros index f41e7a6..50202ba 100644 --- a/assert.macros +++ b/assert.macros @@ -1,81 +1,94 @@ - MACRO -&LAB PH2 &N1 - LCLC &C -&LAB ANOP -&C AMID &N1,1,1 - AIF "&C"="#",.D - AIF S:LONGA=1,.A - REP #%00100000 -.A - AIF "&C"<>"{",.B -&C AMID &N1,L:&N1,1 - AIF "&C"<>"}",.G -&N1 AMID &N1,2,L:&N1-2 - LDA (&N1) - PHA - AGO .E -.B - LDA &N1 - PHA - AGO .E -.D -&N1 AMID &N1,2,L:&N1-1 - PEA &N1 - AGO .F -.E - AIF S:LONGA=1,.F - SEP #%00100000 -.F - MEXIT -.G - MNOTE "Missing closing '}'",16 - MEND - MACRO -&LAB PH4 &N1 - LCLC &C -&LAB ANOP -&C AMID &N1,1,1 - AIF "&C"="#",.D - AIF S:LONGA=1,.A - REP #%00100000 -.A - AIF "&C"<>"{",.B -&C AMID &N1,L:&N1,1 - AIF "&C"<>"}",.G -&N1 AMID &N1,2,L:&N1-2 - LDY #2 - LDA (&N1),Y - PHA - LDA (&N1) - PHA - AGO .E -.B - AIF "&C"<>"[",.C - LDY #2 - LDA &N1,Y - PHA - LDA &N1 - PHA - AGO .E -.C - LDA &N1+2 - PHA - LDA &N1 - PHA - AGO .E -.D -&N1 AMID &N1,2,L:&N1-1 - PEA +(&N1)|-16 - PEA &N1 - AGO .F -.E - AIF S:LONGA=1,.F - SEP #%00100000 -.F - MEXIT -.G - MNOTE "Missing closing '}'",16 - MEND + macro +&l ph2 &n1 +&l anop + aif "&n1"="*",.f + lclc &c +&c amid &n1,1,1 + aif "&c"="#",.d + aif s:longa=1,.a + rep #%00100000 +.a + aif "&c"<>"{",.b +&c amid &n1,l:&n1,1 + aif "&c"<>"}",.g +&n1 amid &n1,2,l:&n1-2 + lda (&n1) + pha + ago .e +.b + aif "&c"="<",.c + lda &n1 + pha + ago .e +.c +&n1 amid &n1,2,l:&n1-1 + pei &n1 + ago .e +.d +&n1 amid &n1,2,l:&n1-1 + pea &n1 + ago .f +.e + aif s:longa=1,.f + sep #%00100000 +.f + mexit +.g + mnote "Missing closing '}'",16 + mend + macro +&l ph4 &n1 +&l anop + aif "&n1"="*",.f + lclc &c +&c amid &n1,1,1 + aif "&c"="#",.d + aif s:longa=1,.a + rep #%00100000 +.a + aif "&c"<>"{",.b +&c amid &n1,l:&n1,1 + aif "&c"<>"}",.g +&n1 amid &n1,2,l:&n1-2 + ldy #2 + lda (&n1),y + pha + lda (&n1) + pha + ago .e +.b + aif "&c"<>"[",.c + ldy #2 + lda &n1,y + pha + lda &n1 + pha + ago .e +.c + aif "&c"<>"<",.c1 +&n1 amid &n1,2,l:&n1-1 + pei &n1+2 + pei &n1 + ago .e +.c1 + lda &n1+2 + pha + lda &n1 + pha + ago .e +.d +&n1 amid &n1,2,l:&n1-1 + pea +(&n1)|-16 + pea &n1 + ago .f +.e + aif s:longa=1,.f + sep #%00100000 +.f + mexit +.g + mnote "Missing closing '}'",16 + mend MACRO &lab csubroutine &parms,&work &lab anop diff --git a/cc.asm b/cc.asm index 5d200d2..a15101a 100644 --- a/cc.asm +++ b/cc.asm @@ -172,8 +172,8 @@ TAB equ 9 TAB key code plb plx ply - pea 0 make room for argc, argv - pea 0 + pea targv|-16 make room for argc, argv + per targv (default argv = ptr to targv) pea 0 phy put the return addr back on the stack phx @@ -184,36 +184,53 @@ TAB equ 9 TAB key code stz ~ExitList no exit routines, yet stz ~ExitList+2 + stz ~QuickExitList + stz ~QuickExitList+2 lda cLine if cLine == 0 then ora cLine+2 - jeq rtl exit + bne lb0 + stz targv argv[0] = NULL + stz targv+2 + brl rtl exit - add4 cLine,#8 skip the shell identifier +lb0 add4 cLine,#8 skip the shell identifier ldx #0 count the arguments txy short M -lb2 lda [cLine],Y +* skip over white space +lb1 lda [cLine],Y beq lb6 - cmp #' ' - beq lb3 - cmp #'"' - beq lb3 - cmp #TAB - bne lb4 -lb3 iny - bra lb2 -lb4 inx -lb5 lda [cLine],Y - beq lb6 - cmp #' ' - beq lb2 - cmp #'"' - beq lb2 - cmp #TAB - beq lb2 iny - bra lb5 + cmp #' ' + beq lb1 + cmp #TAB + beq lb1 + inx + cmp #'"' + beq lb3 + +* skip to next white space +lb2 anop + lda [cLine],y + beq lb6 + iny + cmp #' ' + beq lb1 + cmp #TAB + beq lb1 + bra lb2 + +* skip to next " +lb3 anop + lda [cLine],y + beq lb6 + iny + cmp #'"' + beq lb1 + bra lb3 + + lb6 long M txa we need (X+1)*4 + strlen(cLine)+1 bytes inc A @@ -333,17 +350,26 @@ start ds 2 start of the command line string plb plx ply - pea 0 set argc, argv to 0 - pea 0 + pea targv|-16 set argc = 0, argv to point to targv + per targv pea 0 phy put the return addr back on the stack phx stz ~ExitList no exit routines, yet stz ~ExitList+2 + stz ~QuickExitList + stz ~QuickExitList+2 + lda #~RTL set up so exit(), etc. call ~RTL + sta ~C_Quit+1 + + stz targv argv[0] = NULL + stz targv+2 plb return rtl + +targv ds 4 end **************************************************************** @@ -422,14 +448,78 @@ lb4 pld return rts end +**************************************************************** +* +* ~QuickExit - call quick exit routines +* +* Inputs: +* ~QuickExitList - list of quick exit routines +* +**************************************************************** +* +~QuickExit start +ptr equ 3 pointer to exit routines +; +; Set up our stack frame +; + phb + phk + plb + ph4 ~QuickExitList set up our stack frame + phd + tsc + tcd +; +; Call the quick exit functions +; +lb1 lda ptr if the pointer is non-nil then + ora ptr+2 + beq lb3 + pea +(lb2-1)|-8 call the function + pea +(lb2-1)|8 + phb + pla + ldy #5 + lda [ptr],Y + pha + dey + dey + lda [ptr],Y + pha + phb + pla + rtl +lb2 ldy #2 dereference the pointer + lda [ptr],Y + tax + lda [ptr] + sta ptr + stx ptr+2 + bra lb1 +; +; return +; +lb3 pld return + pla + pla + plb + rts + end + **************************************************************** * * ~ExitList - list of exit routines +* ~QuickExitList - list of quick exit routines +* ~C_Quit - call to quit (may be changed to call ~RTL) * **************************************************************** * ~ExitList start ds 4 +~QuickExitList entry + ds 4 +~C_Quit entry + jmp ~QUIT end **************************************************************** @@ -998,26 +1088,26 @@ dv10 pld return * ~Zero - zero an area of direct page memory * * Inputs: -* addr - address of the memory -* size - number of bytes to zero (must be > 1) +* addr - address of the memory +* size - number of bytes to zero (must be > 1) * **************************************************************** * -~Zero start +~Zero start csubroutine (2:size,4:addr),0 - lda #0 - sta [addr] - ldx addr - txy - iny - lda size - dea - dea - phb - mvn 0,0 - plb + lda #0 + sta [addr] + ldx addr + txy + iny + lda size + dea + dea + phb + mvn 0,0 + plb creturn - end + end diff --git a/ctype.asm b/ctype.asm index 5cdce57..3c6bcac 100644 --- a/ctype.asm +++ b/ctype.asm @@ -139,8 +139,7 @@ isblank start * **************************************************************** * -iscntrl start -isctrl entry +iscntrl start lda 4,S fetch the operand tax @@ -525,6 +524,8 @@ tolower start pla sta 1,S + txa + bmi lb2 lda >__ctype+1,X branch if the character is not uppercase and #_upper beq lb1 @@ -533,7 +534,7 @@ tolower start rtl lb1 txa return the input character - rtl +lb2 rtl end **************************************************************** @@ -557,6 +558,8 @@ toupper start pla sta 1,S + txa + bmi lb2 lda >__ctype+1,X branch if the character is not lowercase and #_lower beq lb1 @@ -565,7 +568,7 @@ toupper start rtl lb1 txa return the input character - rtl +lb2 rtl end **************************************************************** @@ -847,7 +850,7 @@ __ctype start * __ctype2 - character types array * * This data area defines a second array of of bit masks. It -* is used to test for character types. For example, to +* is used to test for character types. For example, to * determine if a character is allowed as an initial character * in a symbol, and _csym with the array element for the * character being tested. If the result is non-zero, the diff --git a/equates.asm b/equates.asm index 7bc865b..4d7fd05 100644 --- a/equates.asm +++ b/equates.asm @@ -61,7 +61,7 @@ _IOMYBUF gequ $0040 buffer was allocated by stdio _IOEOF gequ $0080 has an EOF been found? _IOERR gequ $0100 has an error occurred? _IOTEXT gequ $0200 is this file a text file? -_IOTEMPFILE gequ $0400 was this file created by tmpfile()? +_IOTEMPFILE gequ $0400 was this file created by tmpfile()? ! record structure ! ---------------- @@ -70,9 +70,9 @@ FILE_ptr gequ FILE_next+4 next location to write to FILE_base gequ FILE_ptr+4 first byte of the buffer FILE_end gequ FILE_base+4 end of the file buffer FILE_size gequ FILE_end+4 size of the file buffer -FILE_cnt gequ FILE_size+4 # chars that can be read/writen to buffer +FILE_cnt gequ FILE_size+4 # chars that can be read/written to buffer FILE_pbk gequ FILE_cnt+4 put back character -FILE_flag gequ FILE_pbk+4 buffer flags +FILE_flag gequ FILE_pbk+2 buffer flags FILE_file gequ FILE_flag+2 GS/OS file ID sizeofFILE gequ FILE_file+2 size of the record diff --git a/orca.asm b/orca.asm index 9792682..41e28fc 100644 --- a/orca.asm +++ b/orca.asm @@ -85,9 +85,9 @@ shellid start rtl lb1 lda >~COMMANDLINE+2 - pha - lda >~COMMANDLINE - pha + pha + lda >~COMMANDLINE + pha phd tsc tcd diff --git a/signal.asm b/signal.asm index 9a74b32..a33959d 100644 --- a/signal.asm +++ b/signal.asm @@ -4,7 +4,7 @@ **************************************************************** * -* signal - Asyncronous event signal handler +* signal - Asynchronous event signal handler * * April 1990 * Mike Westerfield @@ -27,7 +27,7 @@ SIGMAX gequ 6 maximum number of signals * * void (*signal(int sig, void (*func) (int)))(int); * -* Set the interupt handler +* Set the interrupt handler * * Inputs: * sig - signal number @@ -41,7 +41,7 @@ SIGMAX gequ 6 maximum number of signals * signal start using signalCommon -ptr equ 1 old sugnal handler +ptr equ 1 old signal handler csubroutine (2:sig,4:func),4 diff --git a/stdio.asm b/stdio.asm index bb75c9d..93e32ad 100644 --- a/stdio.asm +++ b/stdio.asm @@ -1,4 +1,4 @@ - keep stdio + keep obj/stdio mcopy stdio.macros case on @@ -29,7 +29,7 @@ StdIO start dummy segment * void clearerr(stream) * FILE *stream; * -* Clears the error flag for the givin stream. +* Clears the error flag for the given stream. * * Inputs: * stream - file to clear @@ -334,7 +334,7 @@ fa3 lda #EOF assume there is an error ph4 stream verify that stream exists jsl ~VerifyStream jcs rts - ldy #FILE_flag if the mode is not writting, quit + ldy #FILE_flag if the mode is not writing, quit lda [stream],Y and #_IOWRT beq fl1 @@ -431,16 +431,14 @@ lb0 lda #EOF lb1 ldy #FILE_pbk if there is a char in the putback buffer lda [stream],Y - bmi lb2 - and #$00FF return it + and #$0080 + bne lb2 + lda [stream],Y return it + and #$00FF sta c - ldy #FILE_pbk+2 pop the putback buffer - lda [stream],Y - tax - lda #$FFFF - sta [stream],Y - ldy #FILE_pbk - txa + lda [stream],Y pop the putback buffer + xba + ora #$FF00 sta [stream],Y brl gc9 @@ -623,6 +621,7 @@ rdRefNum ds 2 rdDataBuffer ds 4 rdRequestCount ds 4 rdTransferCount ds 4 + dc i'1' cache priority end **************************************************************** @@ -641,7 +640,7 @@ rdTransferCount ds 4 * * Outputs: * Returns NULL if an EOF is encountered, placing any -* characters read before the EOF into s. Returns S if +* characters read before the EOF into s. Returns S if * a line or part of a line is read. * **************************************************************** @@ -764,10 +763,9 @@ OSname equ 11 pointer to the GS/OS file name lda [type] make sure the file type is in ['a','r','w'] and #$00FF sta fileType - ldx #$0003 + ldx #$0002 cmp #'a' beq cn1 - ldx #$0002 cmp #'w' beq cn1 ldx #$0001 @@ -786,6 +784,7 @@ cn1 stx opAccess set the access flags stx OSname+2 ora OSname+2 jeq rt2 + move4 OSname,opName ; ; check for file modifier characters + and b ; @@ -795,15 +794,21 @@ cn1 stx opAccess set the access flags lda [type],Y jsr Modifier bcc cm1 - iny lda [type],Y jsr Modifier + bcc cm1 + lda fileType if mode is 'w' or 'a' + cmp #'r' + beq cm1 + lda [type],Y check for 'x' in type string + and #$00FF + cmp #'x' + beq of1 cm1 anop ; ; open the file ; - move4 OSname,opName try to open an existing file - OSopen op + OSopen op try to open an existing file bcc of2 lda fileType if the type is 'r', flag an error @@ -815,11 +820,15 @@ cm1 anop of1 move4 OSname,crPathName create the file OScreate cr - bcs errEIO + bcs of1a OSopen op open the file bcc of2 +of1a cmp #$0047 check for dupPathname error=>file exists + bne errEIO + lda #EEXIST + bra err1 errEIO lda #EIO - sta >errno +err1 sta >errno brl rt1 of2 lda fileType if the file type is 'w' then @@ -927,8 +936,6 @@ ar6a sta [fileBuff],Y ldy #FILE_pbk nothing in the putback buffer lda #$FFFF sta [fileBuff],Y - ldy #FILE_pbk+2 - sta [fileBuff],Y ldy #FILE_file set the file ID lda opRefNum sta [fileBuff],Y @@ -950,12 +957,14 @@ Modifier and #$00FF bne md1 lda #$0003 sta opAccess + iny sec rts md1 cmp #'b' bne md2 lda #BIN sta crFileType + iny md2 sec rts @@ -1081,6 +1090,7 @@ cn1 ph4 filename get the length of the name buffer stx OSname+2 ora OSname+2 jeq rt2 + move4 OSname,opName ; ; open the file ; @@ -1098,9 +1108,24 @@ nl1 cmp #'b' bne nl2 lda #BIN sta crFileType + iny + cpy #2 + bne nl2 + lda [type],Y + and #$00FF + cmp #'+' + bne nl2 + iny +nl2 lda fileType check for 'x' in type string + cmp #'r' + beq nl3 + lda [type],Y + and #$00FF + cmp #'x' + beq of1 -nl2 move4 OSname,opName try to open an existing file - OSopen op + +nl3 OSopen op try to open an existing file bcc of2 lda fileType if the type is 'r', flag an error @@ -1112,8 +1137,15 @@ errEIO ph4 stream of1 move4 OSname,crPathName create the file OScreate cr - bcs errEIO - OSopen op open the file + bcc of1a + cmp #$0047 check for dupPathname error=>file exists + bne errEIO + ph4 stream + jsr ~ioerror + lda #EEXIST + sta >errno + brl rt1 +of1a OSopen op open the file bcs errEIO of2 lda fileType if the file type is 'w', reset it @@ -1159,10 +1191,12 @@ ar3 move4 stream,fileBuff set the file buffer address sta [fileBuff],Y ldy #1 set the flags lda [type],Y + cmp #'+b' + beq ar3a and #$00FF cmp #'+' bne ar4 - lda #_IOFBF+_IORW+_IOMYBUF +ar3a lda #_IOFBF+_IORW+_IOMYBUF bra ar6 ar4 lda fileType cmp #'r' @@ -1185,8 +1219,6 @@ ar6a sta [fileBuff],Y ldy #FILE_pbk nothing in the putback buffer lda #$FFFF sta [fileBuff],Y - ldy #FILE_pbk+2 - sta [fileBuff],Y ldy #FILE_file set the file ID lda opRefNum sta [fileBuff],Y @@ -1377,7 +1409,7 @@ lb1 ldy #FILE_flag if the file is not prepared for bne lb2 bit #_IOREAD if it is being read then bne pc2 flag the error - ora #_IOWRT set the writting flag + ora #_IOWRT set the writing flag sta [stream],Y lb2 ldy #FILE_file branch if this is a disk file lda [stream],Y @@ -1799,8 +1831,6 @@ lb6 ldy #FILE_flag clear the EOF , READ, WRITE flags ldy #FILE_pbk nothing in the putback buffer lda #$FFFF sta [stream],Y - ldy #FILE_pbk+2 - sta [stream],Y stz err rts plb @@ -1914,15 +1944,12 @@ lb1 move4 gmPosition,pos set the position lda pos+2 sbc [stream],Y sta pos+2 - ldy #FILE_pbk dec pos by 1 for each char in the - lda [stream],Y putback buffer then - bmi lb2 - dec4 pos - ldy #FILE_pbk+2 - lda [stream],Y - bmi lb2 - dec4 pos -lb2 ldy #FILE_file set the file's mark + ldy #FILE_pbk if there is a char in the putback + lda [stream],Y buffer then + and #$0080 + bne rts + dec4 pos dec pos by 1 + ldy #FILE_file set the file's mark lda [stream],Y sta spRefNum move4 pos,spPosition @@ -2022,11 +2049,12 @@ lb5 div4 wrTransferCount,element_size,count lb6 plb creturn 4:count return -wr dc i'4' parameter block for OSWrite +wr dc i'5' parameter block for OSRead wrRefNum ds 2 wrDataBuffer ds 4 wrRequestCount ds 4 wrTransferCount ds 4 + dc i'1' end **************************************************************** @@ -2035,7 +2063,7 @@ wrTransferCount ds 4 * * Read a character from standard in. No errors are possible. * -* The character read is returned in A. The null character +* The character read is returned in A. The null character * is mapped into EOF. * **************************************************************** @@ -2057,13 +2085,15 @@ getchar start ; get the char from the keyboard ; lda >stdin+4+FILE_pbk if there is a char in the putback - bmi lb1 buffer then - and #$00FF save it in X + and #$0080 buffer then + bne lb1 + lda >stdin+4+FILE_pbk save it in x + and #$00FF tax - lda >stdin+4+FILE_pbk+2 pop the buffer + lda >stdin+4+FILE_pbk pop the buffer + xba + ora #$FF00 sta >stdin+4+FILE_pbk - lda #$FFFF - sta >stdin+4+FILE_pbk+2 txa restore the char bra lb2 @@ -2148,6 +2178,13 @@ s equ 4 string address tsc set up DP addressing phd tcd + + lda s skip prefix string if it is NULL/empty + ora s+2 + beq lb0 + lda [s] + and #$00FF + beq lb0 ph4 >stderr write the error string ph4 s @@ -2158,7 +2195,7 @@ s equ 4 string address ph4 >stderr pea ' ' jsl fputc - ph4 >stderr write the error message +lb0 ph4 >stderr write the error message lda >errno cmp #maxErr+1 blt lb1 @@ -2171,12 +2208,9 @@ lb1 asl A lda >sys_errlist,X pha jsl fputs - ph4 >stderr write lf, cr + ph4 >stderr write lf pea 10 jsl fputc - ph4 >stderr - pea 13 - jsl fputc pld remove parm and return lda 2,S @@ -2238,7 +2272,7 @@ args ds 2 original argument address * int putchar(c) * char c; * -* Print the character to standard out. The character is +* Print the character to standard out. The character is * returned. No errors are possible. * * The character \n is automatically followed by a $0D, which @@ -2669,6 +2703,14 @@ sprintf start plb plx remove the return address ply + phd initialize output to empty string + tsc + tcd + short M + lda #0 + sta [3] + long M + pld pla save the stream sta string pla @@ -2739,6 +2781,132 @@ args ds 2 original argument address string ds 4 string address end +**************************************************************** +* +* int snprintf(char * s, size_t n, const char * format, ...) +* +* Print the format string to a string, with length limit. +* +**************************************************************** +* +snprintf start + using ~printfCommon + + phb use local addressing + phk + plb + plx remove the return address + ply + lda 5,S check if n == 0 + ora 7,S + bne lb1 + lda #put2 set up do-nothing output routine + sta >~putchar+4 + lda #>put2 + sta >~putchar+5 + bra lb2 +lb1 phd initialize output to empty string + tsc + tcd + short M + lda #0 + sta [3] + long M + pld + lda #put set up output routine + sta >~putchar+4 + lda #>put + sta >~putchar+5 +lb2 pla save the destination string + sta string + pla + sta string+2 + pla save n value + sta count + pla + sta count+2 + phy restore return address/data bank + phx + plb + + tsc find the argument list address + clc + adc #8 + sta >args + pea 0 + pha + jsl ~printf call the formatter + sec compute the space to pull from the stack + pla + sbc >args + clc + adc #4 + sta >args + pla + phb remove the return address + plx + ply + tsc update the stack pointer + clc + adc >args + tcs + phy restore the return address + phx + plb + lda >~numChars return the value + rtl return + +put phb remove the char from the stack + phk + plb + plx + pla + ply + pha + phx + lda count decrement count + bne pt1 + dec count+2 +pt1 dec count + bne pt2 if count == 0: + lda count+2 + bne pt2 +pt1a lda #put2 set up do-nothing output routine + sta >~putchar+4 + lda #>put2 + sta >~putchar+5 + bra pt3 return without writing +pt2 ldx string+2 write to string + phx + ldx string + phx + phd + tsc + tcd + tya + and #$00FF + sta [3] + pld + pla + pla + inc4 string +pt3 plb + rtl + +put2 phb remove the char from the stack + plx + pla + ply + pha + phx + plb + rtl return, discarding the character + +args ds 2 original argument address +string ds 4 string address +count ds 4 chars left to write + end + **************************************************************** * * int sscanf(s, format, additional arguments) @@ -2819,7 +2987,7 @@ sys_errlist start dc a4'EEXISTS' dc a4'ENOSPC' -! Note: if more errors are added, change maxErr in perror(). +! Note: if more errors are added, change maxErr in perror() and strerror(). EUNDEF cstr 'invalid error number' EDOM cstr 'domain error' @@ -2898,9 +3066,10 @@ lb4 long M append the two strings ph4 #cname move the string ph4 buf jsl strcpy + bra lb6 lb5 lla buf,cname return the string pointer - plb +lb6 plb creturn 4:buf pr dc i'2' parameter block for OSGet_Prefix @@ -2939,7 +3108,7 @@ f equ 1 file pointer jsl fopen sta f stx f+2 - ora f+2 if sucessful then + ora f+2 if successful then beq lb1 ldy #FILE_flag f->_flag |= _IOTEMPFILE lda [f],Y @@ -2948,7 +3117,7 @@ f equ 1 file pointer lb1 creturn 4:f -type cstr 'w+b' +type cstr 'w+bx' end **************************************************************** @@ -2971,7 +3140,7 @@ type cstr 'w+b' * ungetc start -char equ 1 characater to return +char equ 1 character to return csubroutine (2:c,4:stream),2 @@ -2984,18 +3153,21 @@ char equ 1 characater to return lda c error if EOF is pushed cmp #EOF beq rts - ldy #FILE_pbk+2 error if the buffer is full + ldy #FILE_pbk+1 error if the buffer is full + short M lda [stream],Y bpl rts - ldy #FILE_pbk push the old character (if any) + dey push the old character (if any) lda [stream],Y - ldy #FILE_pbk+2 + iny sta [stream],Y - ldy #FILE_pbk put back the character - lda c - and #$00FF + dey + lda c put back the character sta [stream],Y sta char + stz char+1 + bpl rts + dec char+1 rts long M creturn 2:char end @@ -3147,6 +3319,14 @@ vsprintf start plb plx remove the return address ply + phd initialize output to empty string + tsc + tcd + short M + lda #0 + sta [3] + long M + pld pla save the stream sta string pla @@ -3218,6 +3398,133 @@ put phb remove the char from the stack string ds 4 string address end +**************************************************************** +* +* int vsnprintf(char *s, size_t n, char *format, va_list arg) +* +* Print the format string to a string, with length limit. +* +**************************************************************** +* +vsnprintf start + using ~printfCommon + + phb use local addressing + phk + plb + plx remove the return address + ply + lda 5,S check if n == 0 + ora 7,S + bne lb1 + lda #put2 set up do-nothing output routine + sta >~putchar+4 + lda #>put2 + sta >~putchar+5 + bra lb2 +lb1 phd initialize output to empty string + tsc + tcd + short M + lda #0 + sta [3] + long M + pld + lda #put set up output routine + sta >~putchar+4 + lda #>put + sta >~putchar+5 +lb2 pla save the stream + sta string + pla + sta string+2 + pla save n value + sta count + pla + sta count+2 + phy restore return address/data bank + phx + plb + + phd find the argument list address + tsc + tcd + lda [10] + pld + pea 0 + pha + jsl ~printf call the formatter + ply update the argument list pointer + plx + phd + tsc + tcd + tya + sta [10] + pld + phb remove the return address + plx + ply + tsc update the stack pointer + clc + adc #8 + tcs + phy restore the return address + phx + plb + lda >~numChars return the value + rtl return + +put phb remove the char from the stack + phk + plb + plx + pla + ply + pha + phx + lda count decrement count + bne pt1 + dec count+2 +pt1 dec count + bne pt2 if count == 0: + lda count+2 + bne pt2 +pt1a lda #put2 set up do-nothing output routine + sta >~putchar+4 + lda #>put2 + sta >~putchar+5 + bra pt3 return without writing +pt2 ldx string+2 write to string + phx + ldx string + phx + phd + tsc + tcd + tya + and #$00FF + sta [3] + pld + pla + pla + inc4 string +pt3 plb + rtl + +put2 phb remove the char from the stack + plx + pla + ply + pha + phx + plb + rtl return, discarding the character + +string ds 4 string address +count ds 4 chars left to write + end + **************************************************************** * * ~Format_c - format a '%' character @@ -3269,7 +3576,7 @@ argp equ 7 argument pointer ; For signed numbers, if the value is negative, use the sign flag ; lda ~isLong handle long values - beq sn1 + beq sn0 ldy #2 lda [argp],Y bpl cn0 @@ -3281,10 +3588,19 @@ argp equ 7 argument pointer sbc [argp],Y sta [argp],Y bra sn2 +sn0 lda ~isByte handle (originally) byte-size values + beq sn1 + lda [argp] + and #$00FF + sta [argp] + bit #$0080 + beq cn0 + eor #$00FF + bra sn1a sn1 lda [argp] handle int values bpl cn0 eor #$FFFF - inc a +sn1a inc a sta [argp] sn2 lda #'-' sta ~sign @@ -3303,7 +3619,10 @@ cn0 stz ~hexPrefix don't lead with 0x ! pha ! bra cn2 else cn1 lda [argp] push an int value - pha + ldx ~isByte + beq cn1a + and #$00FF +cn1a pha cn2 ph4 #~str push the string addr ph2 #l:~str push the string buffer length ph2 #0 do an unsigned conversion @@ -3461,7 +3780,11 @@ argp equ 7 argument pointer sta argp stx argp+2 lda ~numChars return the value - sta [argp] + ldx ~isByte if byte, store only low byte + beq lb0 + sep #$20 +lb0 sta [argp] + rep #$20 lda ~isLong if long, set the high word beq lb1 ldy #2 @@ -3508,7 +3831,10 @@ argp equ 7 argument pointer lda [argp],Y sta ~num+2 cn2 lda [argp] - sta ~num + ldx ~isByte + beq cn2a + and #$00FF +cn2a sta ~num ; ; Convert the number to an ASCII string ; @@ -3673,7 +3999,10 @@ cn0 stz ~sign ignore the sign flag lda [argp],Y sta ~num+2 cn2 lda [argp] - sta ~num + ldx ~isByte + beq cn2a + and #$00FF +cn2a sta ~num stz ~hexPrefix assume we won't lead with 0x ; ; Convert the number to an ASCII string @@ -3934,7 +4263,7 @@ lb3 creturn 4:ptr * ------------------------ * * '-' Left justify the output. -* '0' Use '0' for the pad character rather than ' '. This +* '0' Use '0' for the pad character rather than ' '. This * flag is ignored if the '-' flag is also used. * '+' Only used for conversion operations 'd' 'e' 'E' 'f' 'g' 'G'. * Specifies that a leading sign is to be printed for @@ -3948,7 +4277,7 @@ lb3 creturn 4:ptr * Optional Min Field Width * ------------------------ * -* This field is either a number or *. If it is *, an integer +* This field is either a number or *. If it is *, an integer * argument is consumed from the stack and used as the field * width. In either case, the output value is printed in a field * that is NUMBER characters wide. By default, the value is @@ -3957,7 +4286,7 @@ lb3 creturn 4:ptr * Optional Precision * ------------------ * -* This field is a number, *, or is ommitted. If it is an integer, +* This field is a number, *, or is omitted. If it is an integer, * an argument is removed from the stack and used as the precision. * The precision is used to describe how many digits to print. * @@ -3965,16 +4294,16 @@ lb3 creturn 4:ptr * ----------------------- * * An 'l' indicates that the 'd', 'o', 'u', 'x' or 'X' argument is -* long. 'L' and 'u' are also accepted for compliance with ANSI C, +* long. 'L' and 'u' are also accepted for compliance with ANSI C, * but have no effect in this implementation. * * Conversion Specifier * -------------------- * * d,i Signed decimal conversion from type int or long. -* u Signed decmal conversion from type unsigned or unsigned long. +* u Signed decimal conversion from type unsigned or unsigned long. * o Octal conversion. -* x,X Hexadecomal conversion. 'x' generates lowercase hex digits, +* x,X Hexadecimal conversion. 'x' generates lowercase hex digits, * while 'X' generates uppercase hex digits. * c Character. * s String. @@ -4035,6 +4364,7 @@ fm1 inc4 format skip the '%' stz ~precision use the default precision stz ~precisionSpecified stz ~isLong assume short operands + stz ~isByte lda #' ' use a blank for padding sta ~paddChar stz ~leftJustify right justify the output @@ -4053,16 +4383,28 @@ fm2 jsr Flag read and interpret flag characters inc ~precisionSpecified note that the precision is specified jsr GetSize get the precision sta ~precision - lda [format] if *format == 'l' then + lda [format] if *format in ['l','z','t','j'] then and #$00FF fm3 cmp #'l' + beq fm3a + cmp #'z' + beq fm3a + cmp #'t' + beq fm3a + cmp #'j' bne fm4 - inc ~isLong ~isLong = true +fm3a inc ~isLong ~isLong = true bra fm5 ++format fm4 cmp #'L' else if *format in ['L','h'] then beq fm5 cmp #'h' bne fm6 + inc4 format check for 'hh' + lda [format] + and #$00FF + cmp #'h' + bne fm6 + inc ~isByte fm5 inc4 format ++format lda [format] find the proper format character and #$00FF @@ -4160,6 +4502,14 @@ val ds 2 value ; List of format specifiers and the equivalent subroutines ; fList dc c'%',i1'0',a'~Format_Percent' % + dc c'a',i1'0',a'~Format_e' a (not formatted correctly) + dc c'A',i1'0',a'~Format_E' A (not formatted correctly) + dc c'f',i1'0',a'~Format_f' f + dc c'F',i1'0',a'~Format_f' F + dc c'e',i1'0',a'~Format_e' e + dc c'E',i1'0',a'~Format_E' E + dc c'g',i1'0',a'~Format_g' g + dc c'G',i1'0',a'~Format_G' G dc c'n',i1'0',a'~Format_n' n dc c's',i1'0',a'~Format_s' s dc c'b',i1'0',a'~Format_b' b @@ -4171,11 +4521,6 @@ fList dc c'%',i1'0',a'~Format_Percent' % dc c'u',i1'0',a'~Format_u' u dc c'd',i1'0',a'~Format_d' d dc c'i',i1'0',a'~Format_d' i - dc c'f',i1'0',a'~Format_f' f - dc c'e',i1'0',a'~Format_e' e - dc c'E',i1'0',a'~Format_E' E - dc c'g',i1'0',a'~Format_g' g - dc c'G',i1'0',a'~Format_G' G fListEnd anop end @@ -4198,6 +4543,7 @@ fListEnd anop ~fieldWidth ds 2 output field width ~hexPrefix ds 2 hex 0x prefix characters (if present) ~isLong ds 2 is the operand long? +~isByte ds 2 is operand byte-size (converted to int)? ~leftJustify ds 2 left justify the output? ~paddChar ds 2 output padd character ~precision ds 2 precision of output @@ -4225,7 +4571,7 @@ fListEnd anop **************************************************************** * -* ~RemoveWord - remove Y words from the stack for printf +* ~RemoveWord - remove Y words from the stack for scanf * * Inputs: * Y - number of words to remove (must be >0) @@ -4428,8 +4774,12 @@ lb4b lda ~suppress if input is not suppressed then beq lb4c sub4 #0,val,val negate the value lb4c lda val save the value - sta [arg] - dec ~size + ldx ~size + bpl lb4d + sep #$20 +lb4d sta [arg] + rep #$20 + dex bmi lb6 ldy #2 lda val+2 @@ -4579,8 +4929,17 @@ arg equ 11 argument ldx ~suppress if output is not suppressed then bne lb1 lda ~scanCount save the count - sta [arg] - dec ~assignments fix assignment count + ldx ~size + bpl lb0 + sep #$20 +lb0 sta [arg] + rep #$20 + dex + bmi lb0a + lda #0 + ldy #2 + sta [arg],y +lb0a dec ~assignments fix assignment count lb1 ldy #2 remove the parameter from the stack jsr ~RemoveWord rts @@ -4813,8 +5172,12 @@ lb4a lda read if no chars read then lb4b lda ~suppress if input is not suppressed then bne lb7 lda val save the value - sta [arg] - dec ~size + ldx ~size + bpl lb4c + sep #$20 +lb4c sta [arg] + rep #$20 + dex bmi lb6 ldy #2 lda val+2 @@ -4859,13 +5222,13 @@ read ds 2 # chars read * int ~scanf(format, additional arguments) * char *format; * -* Scan by calling ~getchar indirectly. If a '%' is found, it +* Scan by calling ~getchar indirectly. If a '%' is found, it * is interpreted as follows: * * Assignment Suppression Flag * --------------------------- * -* '*' Do everyting but save the result and remove a pointer from +* '*' Do everything but save the result and remove a pointer from * the stack. * * Max Field Width @@ -4885,13 +5248,14 @@ read ds 2 # chars read * -------------------- * * d,i Signed decimal conversion to type int or long. -* u Signed decmal conversion to type unsigned short, unsigned or +* u Signed decimal conversion to type unsigned short, unsigned or * unsigned long. * o Octal conversion. -* x,X Hexadecomal conversion. +* x,X Hexadecimal conversion. * c Character. * s String. -* p Pascal string. +* b Pascal string. +* p Pointer. * n The argument is (int *); the number of characters written so * far is written to the location. * f,e,E,g,G Signed floating point conversion. @@ -4956,9 +5320,10 @@ ps3a txa bra ps1 ps4 cpx #'%' branch if this is a conversion - beq fm1 specification + bne ps5 specification + brl fm1 - stx ch make sure the char matches the format +ps5 stx ch make sure the char matches the format inc4 format specifier jsl ~getchar cmp ch @@ -4972,24 +5337,41 @@ rm1 lda [format] if this is a format specifier then beq rt1 cmp #'%' bne rm4 - inc4 format if it is not a '%' or '*' then - lda [format] - and #$00FF + ldy #2 plan to remove 2 words + jsr IncFormat beq rt1 - cmp #'%' - beq rm4 cmp #'*' + bne rm1a + dey ...but not if '*' found + dey + jsr IncFormat +rm1a cmp #'0' skip field width, if present + blt rm1b + cmp #'9'+1 + bge rm1b + jsr IncFormat + bra rm1a +rm1b cmp #'l' skip 'l' length modifier, if present + bne rm1c + jsr IncFormat +rm1c cmp #'%' ignore if it is '%%' format specifier beq rm4 - cmp #'[' if it is a '[' then + cmp #'[' if it is a '[' then bne rm3 -rm2 inc4 format skip up to the closing ']' - lda [format] - and #$00FF - beq rt1 + jsr IncFormat + cmp #'^' skip '^', if present + bne rm1d + jsr IncFormat +rm1d cmp #']' skip ']' in scanset, if present + bne rm2a +rm2 jsr IncFormat +rm2a tax + beq rt1 skip up to the closing ']' cmp #']' bne rm2 -rm3 ldy #2 remove an addr from the stack - jsr ~RemoveWord +rm3 tyx if '*' not found + beq rm4 + jsr ~RemoveWord remove an addr from the stack rm4 inc4 format next format character bra rm1 ; @@ -5027,19 +5409,31 @@ fm1 inc4 format skip the '%' fm2 jsr GetSize get the field width specifier sta ~scanWidth - lda [format] if the character is an 'l' then + lda [format] if the char is 'l', 'z', 't', or 'j' then and #$00FF cmp #'l' + beq fm2a + cmp #'z' + beq fm2a + cmp #'t' + beq fm2a + cmp #'j' bne fm3 - inc ~size long specifier +fm2a inc ~size long specifier bra fm4 fm3 cmp #'h' else if it is an 'h' then bne fm5 + inc4 format check for 'hh' + lda [format] + and #$00FF + cmp #'h' + bne fm6 + dec ~size fm4 inc4 format ignore the character fm5 lda [format] find the proper format character and #$00FF - inc4 format +fm6 inc4 format ldx #fListEnd-fList-4 fm7 cmp fList,X beq fm8 @@ -5080,6 +5474,15 @@ gs2 and #$000F save the ordinal value gs3 lda val rts +; +; Increment format and load the new character +; +IncFormat anop + inc4 format + lda [format] + and #$00FF + rts + val ds 2 value ; ; List of format specifiers and the equivalent subroutines @@ -5095,7 +5498,10 @@ fList dc c'd',i1'0',a'~Scan_d' d dc c's',i1'0',a'~Scan_s' s dc c'b',i1'0',a'~Scan_b' b dc c'n',i1'0',a'~Scan_n' n + dc c'a',i1'0',a'~Scan_f' a + dc c'A',i1'0',a'~Scan_f' A dc c'f',i1'0',a'~Scan_f' f + dc c'F',i1'0',a'~Scan_f' F dc c'e',i1'0',a'~Scan_f' e dc c'E',i1'0',a'~Scan_f' E dc c'g',i1'0',a'~Scan_f' g @@ -5139,9 +5545,9 @@ ch ds 2 temp storage ~eofFound ds 2 was EOF found during the scan? ~suppress ds 2 suppress assignment? ~scanCount ds 2 # of characters scanned -~scanError ds 2 set to 1 by scaners if an error occurs +~scanError ds 2 set to 1 by scanners if an error occurs ~scanWidth ds 2 max # characters to scan -~size ds 2 size specifier; -1 -> short, 1 -> long, +~size ds 2 size specifier; -1 -> char, 1 -> long, ! 0 -> default end diff --git a/stdlib.asm b/stdlib.asm index 191b0fa..edd8c8a 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -37,7 +37,7 @@ abort start ph2 #SIGABRT jsl raise lda #-1 - jmp ~QUIT + jmp ~C_QUIT end **************************************************************** @@ -70,6 +70,42 @@ lb1 tay return A rtl end +**************************************************************** +* +* void *aligned_alloc(size_t alignment, size_t size) +* +* Allocate memory with specified alignment. +* +* Inputs: +* alignment - alignment to use (only value allowed is 1) +* size - bytes of memory to allocate +* +* Outputs: +* Returns pointer to allocated memory, or NULL on error. +* +**************************************************************** +* +aligned_alloc start + csubroutine (4:alignment,4:size),0 + + lda alignment check that alignment==1 + dec a + ora alignment+2 + beq good + stz size return NULL on error + stz size+2 + lda #EINVAL + sta >errno + bra ret + +good ph4 ~QUICKEXITLIST + sta [ptr] + lda >~QUICKEXITLIST+2 + sta [ptr],Y + lda ptr + sta >~QUICKEXITLIST + lda ptr+2 + sta >~QUICKEXITLIST+2 + iny place the function address in the record + iny + lda func + sta [ptr],Y + iny + iny + lda func+2 + sta [ptr],Y + inc rval success... + +lb1 creturn 2:rval + end + + **************************************************************** * * atof - convert a string to a float @@ -282,7 +372,7 @@ addr equ 1 jsl ~DIV2 sta div_t save the results stx div_t+2 - tay if the result is negative then + lda n if the numerator is negative then bpl lb1 sub2 #0,div_t+2,div_t+2 make the remainder negative lb1 lla addr,div_t return the address @@ -295,11 +385,13 @@ div_t ds 4 **************************************************************** * -* void exit(status) -* int status; +* void exit(int status); * -* void _exit(status) -* int status; +* void _exit(int status); +* +* void _Exit(int status); +* +* void quick_exit(int status); * * Stop the program. Exit cleans up, _exit does not. Status * is the status returned to the shell. @@ -313,8 +405,16 @@ exit start jsr ~EXIT _exit entry +_Exit entry lda 4,S - jmp ~QUIT + jmp ~C_QUIT + end + +quick_exit start + + jsr ~QUICKEXIT + lda 4,S + jmp ~C_QUIT end **************************************************************** @@ -423,7 +523,7 @@ addr equ 1 jsl ~DIV4 pl4 div_t pl4 div_t+4 - lda div_t+2 if the result is negative then + lda n+2 if the numerator is negative then bpl lb1 sub4 #0,div_t+4,div_t+4 make the remainder negative lb1 lla addr,div_t return the result @@ -561,7 +661,7 @@ sr4b ph4 left swap left/right entries lda left cmp right sr5 blt sr2 - ph4 right sqap left/right entries + ph4 right swap left/right entries ph4 left jsr swap ph4 left swap left/last entries @@ -695,9 +795,9 @@ rtl equ 7 return address val equ 3 value negative equ 1 is the number negative? - pea 0 make room for & initialize negative pea 0 make room for & initialize val pea 0 + pea 0 make room for & initialize negative tsc set up direct page addressing phd tcd @@ -738,24 +838,30 @@ cn3 ph4 str save the starting string ph2 base convert the unsigned number ph4 ptr ph4 str - jsl strtoul + jsl ~strtoul stx val+2 sta val txy see if we have an overflow bpl rt1 + ldy negative allow -2147483648 as legal value + beq ov0 + cpx #$8000 + bne ov0 + tay + beq rt1 ; ; Overflow - flag the error ; - lda #ERANGE errno = ERANGE +ov0 lda #ERANGE errno = ERANGE sta >errno - lda ptr if ptr <> NULL then - ora ptr+2 - bne rt1 - lda 1,S *ptr = original str - sta [ptr] - ldy #2 - lda 3,S - sta [ptr],Y + ldx #$7FFF return value = LONG_MAX + ldy #$FFFF + lda negative if negative then + beq ov1 + inx return value = LONG_MIN + iny +ov1 sty val + stx val+2 ; ; return the results ; @@ -783,6 +889,8 @@ rt2 ldx val+2 get the value **************************************************************** * * strtoul - convert a string to an unsigned long +* ~strtoul - alt entry point that does not parse leading +* white space and sign * * Inputs: * str - pointer to the string @@ -797,23 +905,36 @@ rt2 ldx val+2 get the value **************************************************************** * strtoul start -base equ 18 base -ptr equ 14 *return pointer -str equ 10 string pointer -rtl equ 7 return address +base equ 22 base +ptr equ 18 *return pointer +str equ 14 string pointer +rtl equ 11 return address +rangeOK equ 9 was the number within range? +negative equ 7 was there a minus sign? val equ 3 value foundOne equ 1 have we found a number? - pea 0 make room for & initialize foundOne + ldx #0 + bra init + +~strtoul entry alt entry point called from strtol + ldx #1 + +init pea 1 make room for & initialize rangeOK + pea 0 make room for & initialize negative pea 0 make room for & initialize val pea 0 + pea 0 make room for & initialize foundOne tsc set up direct page addressing phd tcd ; ; Skip any leading whitespace ; + txa just process number if called from strtol + bne db1c + lda ptr if ptr in non-null then ora ptr+2 beq sw1 @@ -834,35 +955,44 @@ sw1 lda [str] skip the white space ; ; Deduce the base ; -db1 lda [str] skip any leading '+' +db1 lda [str] if the next char is '-' then and #$00FF - cmp #'+' + cmp #'-' bne db1a - inc4 str -db1a lda base if the base is zero then + inc negative negative := true + bra db1b +db1a cmp #'+' skip any leading '+' + bne db1c +db1b inc4 str +db1c lda base if the base is zero then bne db2 lda #10 assume base 10 sta base lda [str] if the first char is 0 then and #$00FF cmp #'0' - bne db2 + bne cn1 lda #8 assume base 8 sta base ldy #1 if the second char is 'X' or 'x' then lda [str],Y - and #$005F + and #$00DF cmp #'X' - bne db2 + bne cn1 asl base base 16 -db2 lda [str] if the first two chars are 0x or 0X then - and #$5F7F + bra db3 +db2 cmp #16 if the base is 16 then + bne db4 + lda [str] if the first two chars are 0x or 0X then + and #$DFFF cmp #'X0' bne cn1 - add4 str,#2 skip them - lda base make sure the base is 16 - cmp #16 - bne returnERANGE +db3 add4 str,#2 skip them + bra cn1 +db4 cmp #37 check for invalid base value + bge cn6 + dec a + beq cn6 ; ; Convert the number ; @@ -872,7 +1002,7 @@ cn1 lda [str] get a (possible) digit blt cn5 cmp #'9'+1 branch if it is a numeric digit blt cn2 - and #$005F convert lowercase to uppercase + and #$00DF convert lowercase to uppercase cmp #'A' branch if it is not a digit blt cn5 cmp #'Z'+1 branch if it is not a digit @@ -901,47 +1031,56 @@ cn3 cmp base branch if the digit is too big plx ply tax - bne returnERANGE - clc add in the new digit + beq cn3a + stz rangeOK +cn3a clc add in the new digit tya adc val sta val bcc cn4 inc val+2 - beq returnERANGE + bne cn4 + stz rangeOK cn4 inc4 str next char bra cn1 cn5 lda foundOne if no digits were found, flag the error bne rt1 -; -; flag an error -; -returnERANGE anop - lda #ERANGE errno = ERANGE +cn6 lda #EINVAL sta >errno - bra rt2 skip setting ptr + bra rt2a ; ; return the results ; rt1 lda ptr if ptr is non-null then ora ptr+2 - beq rt2 + beq rt1a lda str set it to str sta [ptr] ldy #2 lda str+2 sta [ptr],Y -rt2 ldx val+2 get the value + +rt1a lda rangeOK check if number was out of range + bne rt2 + lda #ERANGE errno = ERANGE + sta >errno + ldx #$FFFF return value = ULONG_MAX + txy + bra rt3 +rt2 lda negative if negative then + beq rt2a + sub4 #0,val,val val = -val +rt2a ldx val+2 get the value ldy val - lda rtl fix the stack +rt3 lda rtl fix the stack sta base-1 lda rtl+1 sta base pld tsc clc - adc #16 + adc #20 tcs tya return rtl @@ -973,14 +1112,28 @@ system start sta exComm pla sta exComm+2 - phy execute the command + ora exComm + sta empty + bne lb1 if calling system(NULL) + lda #empty use empty command string + sta exComm + lda #^empty + sta exComm+2 +lb1 phy execute the command phx plb Execute ex - rtl + ldy empty + bne ret if doing system(NULL) + tya + bcs ret error => no command processor + inc a (& vice versa) +ret rtl ex dc i'$8000' exComm ds 4 + +empty ds 2 end **************************************************************** @@ -1035,7 +1188,7 @@ D equ 1 caller's DP tsc adc >toRemove tcs - pld resore the caller's DP + pld restore the caller's DP plx remove the parameter from the stack ply pla diff --git a/string.asm b/string.asm index f7bf717..283c57e 100644 --- a/string.asm +++ b/string.asm @@ -17,6 +17,7 @@ **************************************************************** * String start dummy routine + copy equates.asm end @@ -84,7 +85,7 @@ lb2 sty str1 * set - pointer to the set of characters * * Outputs: -* strset - set of bytes; non-sero for chars in set +* strset - set of bytes; non-zero for chars in set * **************************************************************** * @@ -202,8 +203,8 @@ lb4 lda rtl+1 remove parameters from the stack * equal, return 0; otherwise, return 1. * * Inputs: -* p1 - string to concatonate to -* p2 - string to concatonate +* p1 - string to concatenate to +* p2 - string to concatenate * * Outputs: * A - result @@ -576,14 +577,14 @@ lb2 long I,M **************************************************************** * -* strcat - string concatonation +* strcat - string concatenation * * Place *s2 at the end of *s1, returning a pointer to *s1. No * checking for length is performed. * * Inputs: -* s1 - string to concatonate to -* s2 - string to concatonate +* s1 - string to concatenate to +* s2 - string to concatenate * * Outputs: * X-A - pointer to the result (s1) @@ -741,7 +742,7 @@ lb1 lda [s1],Y inc s2+2 bra lb1 -lb2 ldx #0 s1 is finished. If s2 is, too, the +lb2 ldx #0 s1 is finished. If s2 is, too, the lda [s2],Y strings are equal. beq lb4 less ldx #-1 It wasn't, so *s1 < *s2 @@ -923,14 +924,14 @@ lb2 long M **************************************************************** * -* strncat - string concatonation with max length +* strncat - string concatenation with max length * * Place *s2 at the end of *s1, returning a pointer to *s1. No * checking for length is performed. * * Inputs: -* s1 - string to concatonate to -* s2 - string to concatonate +* s1 - string to concatenate to +* s2 - string to concatenate * n - max # chars to copy * * Outputs: @@ -988,8 +989,8 @@ lb4 lda #0 write the terminating null * equal, return 0; otherwise, return 1. * * Inputs: -* s1 - string to concatonate to -* s2 - string to concatonate +* s1 - string to concatenate to +* s2 - string to concatenate * n - max length of the strings * * Outputs: @@ -1025,7 +1026,7 @@ lb1a iny inc s2+2 bra lb1 -lb2 ldx #0 s1 is finished. If s2 is, too, the +lb2 ldx #0 s1 is finished. If s2 is, too, the lda [s2],Y strings are equal. beq lb4 less ldx #-1 It wasn't, so *s1 < *s2 @@ -1210,9 +1211,9 @@ lb3 long M **************************************************************** * -* strrchr - find the last occurrance of a character in a string +* strrchr - find the last occurrence of a character in a string * -* Returns a pointer to the last occurrance of the character +* Returns a pointer to the last occurrence of the character * * Inputs: * str - string to search @@ -1274,9 +1275,9 @@ lb4 long M **************************************************************** * -* strrpos - find the last occurrance of a character in a string +* strrpos - find the last occurrence of a character in a string * -* Returns the position of the las occurrance of the character +* Returns the position of the last occurrence of the character * * Inputs: * str - string to search @@ -1565,7 +1566,7 @@ ds5 anop ; ; Search for the string ; -ss0 lda lensub if the length of the sreach string is +ss0 lda lensub if the length of the search string is and #$8000 > 32767 then use a long method ora lensub+2 beq ss3 @@ -1697,15 +1698,17 @@ lb3 lda isp s := internal state pointer ldx isp+2 sta s stx s+2 + ora s+2 check if already at end of string + beq lb4a lb4 anop endif lda [s] if we are at the end of the string then and #$00FF bne lb5 - stz set return NULL - stz set+2 stz isp set the isp to NULL stz isp+2 +lb4a stz set return NULL + stz set+2 bra lb10 else lb5 lda [s] scan to the 1st char not in the set and #$00FF diff --git a/time.asm b/time.asm index 1f61790..4af8d83 100644 --- a/time.asm +++ b/time.asm @@ -41,6 +41,9 @@ second ds 4 second 0..59 count ds 4 seconds since 1 Jan 1970 t1 ds 4 work variable t2 ds 4 work variable + +lasttime ds 4 last time_t value returned by time() +lastDST dc i2'-1' tm_isdst value for lasttime end **************************************************************** @@ -137,7 +140,10 @@ tm_wday equ 12 ldy #tm_mday convert the day to a string lda [timeptr],Y jsr mkstr - sta str+8 + bit #$00CF check for leading '0' + bne lb1 + and #$FFEF convert leading '0' to ' ' +lb1 sta str+8 ldy #tm_hour convert the hour to a string lda [timeptr],Y jsr mkstr @@ -151,17 +157,21 @@ tm_wday equ 12 jsr mkstr sta str+17 ldy #tm_year convert the year to a string - lda #'91' - sta str+20 lda [timeptr],Y - cmp #100 - blt lb1 - ldx #'02' - stx str+20 - sec - sbc #100 -lb1 jsr mkstr + ldy #19 + sec +yr1 iny + sbc #100 + bpl yr1 + clc +yr2 dey + adc #100 + bmi yr2 + jsr mkstr sta str+22 + tya + jsr mkstr + sta str+20 lla timeptr,str plb @@ -277,6 +287,15 @@ gmtime entry lda [t] sta t stx t+2 + + ldy #-1 default DST setting = -1 (unknown) + cmp lasttime determine DST setting, if we can + bne lb0 + cpx lasttime+2 + bne lb0 + ldy lastDST +lb0 sty tm_isdst + lda #69 find the year sta year lda #1 @@ -333,15 +352,6 @@ lb2a ble lb2 sta tm_mday ph4 #tm_sec set the day of week/year jsl mktime - pha determine if it's daylight savings - ph2 #$5E - _ReadBParam - pla - lsr A - and #$0001 - eor #$0001 - sta tm_isdst - lla t,tm_sec plb creturn 4:t @@ -354,7 +364,7 @@ tm_mon ds 2 month 0..11 tm_year ds 2 year 70..200 (1900=0) tm_wday ds 2 day of week 0..6 (Sun = 0) tm_yday ds 2 day of year 0..365 -tm_isdst ds 2 daylight savings? 1 = yes, 0 = no +tm_isdst ds 2 daylight savings? 1 = yes, 0 = no end **************************************************************** @@ -363,7 +373,7 @@ tm_isdst ds 2 daylight savings? 1 = yes, 0 = no * struct tm *tmptr * * Inputs: -* tmptr - poiner to a time record +* tmptr - pointer to a time record * * Outputs: * tmptr->wday - day of week @@ -417,7 +427,6 @@ temp2 equ 5 temp variable div4 count,#60*60*24 ldy #14 set the days lda count - inc A sta [tmptr],Y div4 temp,#60*60*24,temp2 compute the day of week add4 temp2,#4 @@ -493,7 +502,20 @@ time start lda count+2 sta [tptr],Y -lb1 move4 count,tptr +lb1 lda count + sta tptr + sta lasttime + lda count+2 + sta tptr+2 + sta lasttime+2 + pha determine if it's daylight savings + ph2 #$5E + _ReadBParam + pla + lsr A + and #$0001 + eor #$0001 + sta lastDST plb creturn 4:tptr end diff --git a/toolglue.asm b/toolglue.asm index b764fc6..b03e471 100644 --- a/toolglue.asm +++ b/toolglue.asm @@ -36,7 +36,7 @@ ToolGlue start dummy routine **************************************************************** * -* MiscTool - Miscelaneous tool kit +* MiscTool - Miscellaneous tool kit * **************************************************************** * @@ -625,21 +625,21 @@ GetMSData start csubroutine (4:reserved,4:DP),0 - tsc - sec - sbc #8 - tcs - _GetMSData + tsc + sec + sbc #8 + tcs + _GetMSData sta >~TOOLERROR - ldy #2 - pla - sta [DP] - pla - sta [DP],Y - pla - sta [reserved] - pla - sta [reserved],Y + ldy #2 + pla + sta [DP] + pla + sta [DP],Y + pla + sta [reserved] + pla + sta [reserved],Y creturn end