From 6ebb56af573388c8e26697c32884c88cfa4281ee Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Tue, 31 Oct 2017 13:18:36 -0400 Subject: [PATCH 01/46] fix tolower/toupper to work with EOF/-1 --- ctype.asm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ctype.asm b/ctype.asm index a3d1365..3e9ae8f 100644 --- a/ctype.asm +++ b/ctype.asm @@ -498,6 +498,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 @@ -506,7 +508,7 @@ tolower start rtl lb1 txa return the input character - rtl +lb2 rtl end **************************************************************** @@ -530,6 +532,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 @@ -538,7 +542,7 @@ toupper start rtl lb1 txa return the input character - rtl +lb2 rtl end **************************************************************** From 649aef5b0f1b2307805ffc57df5410e5877abc12 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 31 Oct 2017 22:50:22 -0500 Subject: [PATCH 02/46] Change sys_nerr from 6 to 12, to reflect actual number of error messages. Fixes the bug in the libca05.c test case. --- vars.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars.asm b/vars.asm index 4fba53c..6f9f8b7 100644 --- a/vars.asm +++ b/vars.asm @@ -31,7 +31,7 @@ _ownerid entry user ID (C) ~USER_ID entry user ID (Pascal, libraries) ds 2 sys_nerr entry # of error messages - dc i'6' + dc i'12' _toolErr entry last error in a tool call (C) ~TOOLERROR entry last error in a tool call (Pascal) ds 2 From 9d116eae354c6a3b9f7acdafaff5c510464531ab Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 31 Oct 2017 22:52:12 -0500 Subject: [PATCH 03/46] Rename isctrl() function to correct standard name of iscntrl(). This doesn't affect the macro, which already had the correct name. Fixes the bug in the libca15.c test case. --- ctype.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ctype.asm b/ctype.asm index a3d1365..9d267c9 100644 --- a/ctype.asm +++ b/ctype.asm @@ -103,7 +103,7 @@ yes lda #1 **************************************************************** * -* int isctrl (int c) +* int iscntrl (int c) * * Inputs: * 4,S - digit to test @@ -113,7 +113,7 @@ yes lda #1 * **************************************************************** * -isctrl start +iscntrl start lda 4,S fetch the operand tax From 56b101a2149b92c253078cf79f40e1247b08625c Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 31 Oct 2017 23:09:27 -0500 Subject: [PATCH 04/46] Change keep location for stdio to be in the obj directory. --- stdio.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdio.asm b/stdio.asm index bb75c9d..778d870 100644 --- a/stdio.asm +++ b/stdio.asm @@ -1,4 +1,4 @@ - keep stdio + keep obj/stdio mcopy stdio.macros case on From d95f9f29d27d02d8c57bd23620f41afbf7607ac5 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sat, 24 Feb 2018 22:40:01 -0500 Subject: [PATCH 05/46] during initial count of arguments on the command-line, use the same logic as the second count when the argv vector is built. --- cc.asm | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/cc.asm b/cc.asm index 907e1db..7b13afb 100644 --- a/cc.asm +++ b/cc.asm @@ -196,27 +196,39 @@ TAB equ 9 TAB key code 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 From e3c0c962d4b0f8077c84f293fac9bc7b76d622c5 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 26 Feb 2018 20:03:14 -0600 Subject: [PATCH 06/46] Revert various stdio changes to make it match the version in the ORCA/C 2.1.1 B3 ORCALib binary on Opus ][. The reverted changes relate mainly to adding a second character position in the putback buffer, but the library with those changes crashes on basic stdio operations like printing a string. For now, this patch reverts stdio to a working, tested version. If the reverted changes are valuable, they can be fixed and then reintroduced later. --- equates.asm | 2 +- stdio.asm | 70 +++++++++++++++++++++++++---------------------------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/equates.asm b/equates.asm index 0659d15..8bf529c 100644 --- a/equates.asm +++ b/equates.asm @@ -71,7 +71,7 @@ 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_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/stdio.asm b/stdio.asm index 778d870..cbd4980 100644 --- a/stdio.asm +++ b/stdio.asm @@ -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 **************************************************************** @@ -927,8 +926,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 @@ -1134,7 +1131,7 @@ ar1 ph4 #BUFSIZ get space for the file buffer bne ar3 lda #ENOMEM memory error sta >errno - brl rt1 + bra rt1 ar3 move4 stream,fileBuff set the file buffer address lda buffStart set the start of the buffer @@ -1185,8 +1182,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 @@ -1799,8 +1794,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 +1907,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 +2012,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 **************************************************************** @@ -2057,13 +2048,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 @@ -2984,18 +2977,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 From f58ef8aea3a69b96ac4438572aa66fc170fc7b19 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 27 Feb 2018 18:44:07 -0600 Subject: [PATCH 07/46] Add support for 'z', 't', and 'j' length modifiers in printf and scanf (C99). 'z' corresponds to size_t, 't' to ptrdiff_t, and 'j' to intmax_t. In ORCA/C, these are all 32-bit types, so these size modifiers are equivalent to 'l'. (Note that C99/C11 require intmax_t to be at least 64-bit, but that is not currently the case in ORCA/C since there is no 64-bit integer type.) --- stdio.asm | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/stdio.asm b/stdio.asm index cbd4980..091a09f 100644 --- a/stdio.asm +++ b/stdio.asm @@ -4049,11 +4049,17 @@ 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 @@ -5023,11 +5029,17 @@ 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 From a6d7d91f3733fa0e09dd59ec39ae275ddf6be783 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 27 Feb 2018 21:29:22 -0600 Subject: [PATCH 08/46] Add initial support for 'F', 'a', and 'A' conversion specifiers for printf (C99). 'F' is currently treated identically to 'f'. This should be a correct implementation for 'F' under C99. (It's not quite correct for 'f', which should print "inf" or "nan" in lower case according to C99.) 'A' and 'a' are not correctly formatted (they are currently treated identically to 'E' and 'e', rather than using the hexadecimal floating-point representation specified by C99), but at least they print the number in some form and consume the correct number of bytes so that the stack isn't corrupted and subsequent conversion specifications print the right values. The floating-point formats are also moved to the top of the list of conversion specifiers to check, which means they are checked last. This should marginally speed up the integer cases. --- stdio.asm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/stdio.asm b/stdio.asm index 091a09f..886fa62 100644 --- a/stdio.asm +++ b/stdio.asm @@ -4162,6 +4162,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 @@ -4173,11 +4181,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 From 62f6b712e7e65c4832d37431b8d26c1c3c62ab31 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 27 Feb 2018 21:39:49 -0600 Subject: [PATCH 09/46] Add support for 'F', 'a', and 'A' conversion specifiers for scanf (C99). These all behave identically to 'f'. Note that none of these accept the hexadecimal floating-point representation as input, which they should under C99. --- stdio.asm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stdio.asm b/stdio.asm index 886fa62..35f5aec 100644 --- a/stdio.asm +++ b/stdio.asm @@ -5106,7 +5106,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 From 8533ea221c13a98c6b4a6b10ef7d31ecd3ae5f6d Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 27 Feb 2018 23:56:14 -0600 Subject: [PATCH 10/46] When argc==0, argv should be a valid pointer and argv[0] should be NULL. This is normal for S16 programs or inits, and can happen with shell executables in certain cases like when being run from Prizm. --- cc.asm | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/cc.asm b/cc.asm index 7b13afb..74c490f 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 @@ -190,9 +190,12 @@ TAB equ 9 TAB key code 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 @@ -348,8 +351,8 @@ 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 @@ -357,8 +360,13 @@ start ds 2 start of the command line string stz ~ExitList no exit routines, yet stz ~ExitList+2 + stz targv argv[0] = NULL + stz targv+2 + plb return rtl + +targv ds 4 end **************************************************************** From 6006cefc70bc69773b5b36382a74ab9042ac65e6 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 4 Mar 2018 22:28:30 -0500 Subject: [PATCH 11/46] add the c99 isblank() function --- ctype.asm | 30 ++++++++++++++++++++++++++++-- equates.asm | 1 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ctype.asm b/ctype.asm index 54a6592..4ba2ece 100644 --- a/ctype.asm +++ b/ctype.asm @@ -101,6 +101,32 @@ yes lda #1 rtl end +**************************************************************** +* +* int isblank (int c) +* +* Inputs: +* 4,S - digit to test +* +* Outputs: +* A - result +* +**************************************************************** +* +isblank start + + lda 4,S fetch the operand + tax + lda 2,S remove parm from stack + sta 4,S + pla + sta 1,S + inx form the result + lda >__ctype2,X + and #_blank + rtl + end + **************************************************************** * * int iscntrl (int c) @@ -844,7 +870,7 @@ __ctype2 start dc i1'0' $06 dc i1'0' $07 dc i1'0' $08 - dc i1'0' $09 + dc i1'_blank' $09 dc i1'0' $0A dc i1'0' $0B dc i1'0' $0C @@ -867,7 +893,7 @@ __ctype2 start dc i1'0' $1D dc i1'0' $1E dc i1'0' $1F - dc i1'0' ' ' + dc i1'_blank' ' ' dc i1'0' ! dc i1'0' " dc i1'0' # diff --git a/equates.asm b/equates.asm index 8bf529c..b5a0614 100644 --- a/equates.asm +++ b/equates.asm @@ -36,6 +36,7 @@ _print gequ $80 [' '..'~'] _csym gequ $01 ['0'..'9','A'..'Z','a'..'z','_'] _csymf gequ $02 ['A'..'Z','a'..'z'.'_'] _octal gequ $04 ['0'..'7'] +_blank gequ $08 ['\t', ' '] ; ; signal numbers ; From 8562842f6625071899e7fffe0832d823020c8e88 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 5 Mar 2018 18:02:36 -0600 Subject: [PATCH 12/46] sprintf/vsprintf should write a terminating null character even if the string produced is empty. They were just not writing anything in this case. --- stdio.asm | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/stdio.asm b/stdio.asm index 35f5aec..b4383ec 100644 --- a/stdio.asm +++ b/stdio.asm @@ -2662,6 +2662,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 @@ -3143,6 +3151,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 From 73f04eaab42472280bb49257cda8bfe9b61c9ae0 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 5 Mar 2018 18:52:43 -0600 Subject: [PATCH 13/46] Add snprintf() and vsnprintf() functions (C99). --- stdio.asm | 253 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) diff --git a/stdio.asm b/stdio.asm index b4383ec..734c388 100644 --- a/stdio.asm +++ b/stdio.asm @@ -2740,6 +2740,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) @@ -3230,6 +3356,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 From a77e44d7b521a605f1d4f5947c37589c6cdc7c0a Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 9 Mar 2018 13:10:53 -0600 Subject: [PATCH 14/46] Fix asctime() to properly print years 1000 through 9999. Also, use a leading space rather than a leading 0 in days 1 through 9. This fixes the libca11.c test case. --- time.asm | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/time.asm b/time.asm index 1f61790..8f868d4 100644 --- a/time.asm +++ b/time.asm @@ -137,7 +137,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 +154,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 From 21d34a30ced17b8564e90caf28652a062dd209a2 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 9 Mar 2018 17:38:14 -0600 Subject: [PATCH 15/46] mktime: tm_yday should be indexed from 0 for January 1st, not 1. This fixes the libca07.c test case. --- time.asm | 1 - 1 file changed, 1 deletion(-) diff --git a/time.asm b/time.asm index 8f868d4..abe25b5 100644 --- a/time.asm +++ b/time.asm @@ -424,7 +424,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 From 7abdfc9beb34966fecfe34d50c98ff5eddbd0bb2 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 13 Mar 2018 17:49:49 -0500 Subject: [PATCH 16/46] Make system(NULL) detect whether a command processor is available. Previously, it just ran an Execute shell call with NULL as the command-line pointer. The fix is to still call Execute, but with an empty string as the command line, and then check if the call gave an error. If running under plain GS/OS, this gives an error for an unknown system call, whereas both ORCA/APW and GNO shells will return with no error in this case. (Golden Gate doesn't implement the Execute shell call, so it also gives an error and will report no command processor available.) This fixes issue #25. --- stdlib.asm | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/stdlib.asm b/stdlib.asm index 191b0fa..a509ae8 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -973,14 +973,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 **************************************************************** From 6e9790667854b57f48631ab6203c0657d20c7ea0 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 13 Mar 2018 22:11:40 -0500 Subject: [PATCH 17/46] Make strtol/strtoul return LONG_MIN/LONG_MAX/ULONG_MAX for out-of-range values. This fixes #10. There are still issues with the end pointer value generated in error cases. --- stdlib.asm | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/stdlib.asm b/stdlib.asm index a509ae8..7dfafbb 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -748,6 +748,14 @@ cn3 ph4 str save the starting string ; lda #ERANGE errno = ERANGE sta >errno + 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 lda ptr if ptr <> NULL then ora ptr+2 bne rt1 @@ -920,7 +928,9 @@ cn5 lda foundOne if no digits were found, flag the error returnERANGE anop lda #ERANGE errno = ERANGE sta >errno - bra rt2 skip setting ptr + ldx #$FFFF return value = ULONG_MAX + txy + bra rt3 skip setting ptr ; ; return the results ; @@ -934,7 +944,7 @@ rt1 lda ptr if ptr is non-null then sta [ptr],Y rt2 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 From 6a2e3c1abdcfdfd87369df16cfe1f5de5a0b6c42 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Wed, 21 Mar 2018 23:05:46 -0400 Subject: [PATCH 18/46] fix typos and misleading commentary. --- stdio.asm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/stdio.asm b/stdio.asm index 734c388..4c366bb 100644 --- a/stdio.asm +++ b/stdio.asm @@ -5139,7 +5139,7 @@ read ds 2 # chars read * 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 @@ -5159,13 +5159,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. From 5ee6e87f445a85c5e7da5c9581fa01557df65db3 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 22 Mar 2018 21:13:09 -0500 Subject: [PATCH 19/46] Implement support for 'hh' length modifier in *printf. This corresponds to signed char or unsigned char (although arguments of those types will have been promoted to int). --- stdio.asm | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/stdio.asm b/stdio.asm index 4c366bb..d47e129 100644 --- a/stdio.asm +++ b/stdio.asm @@ -3534,7 +3534,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 @@ -3546,10 +3546,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 @@ -3568,7 +3577,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 @@ -3726,7 +3738,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 @@ -3773,7 +3789,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 ; @@ -3938,7 +3957,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 @@ -4300,6 +4322,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 @@ -4334,6 +4357,12 @@ 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 @@ -4472,6 +4501,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 From a11660f597d1903deb8e7e012a2beb276c5e6d91 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 22 Mar 2018 22:10:56 -0500 Subject: [PATCH 20/46] Implement support for 'hh' length modifier in *scanf. Also support '%ln', although the length that can be reported is still limited to 64k. --- stdio.asm | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/stdio.asm b/stdio.asm index d47e129..56ed281 100644 --- a/stdio.asm +++ b/stdio.asm @@ -4732,8 +4732,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 @@ -4883,8 +4887,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 @@ -5117,8 +5130,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 @@ -5346,6 +5363,12 @@ 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 fm4 + dec ~size fm4 inc4 format ignore the character fm5 lda [format] find the proper format character @@ -5455,7 +5478,7 @@ ch ds 2 temp storage ~scanCount ds 2 # of characters scanned ~scanError ds 2 set to 1 by scaners 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 From d600cd0b614a04014741e8346aee8dfbaa3ced8b Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Wed, 27 Jun 2018 23:36:02 -0400 Subject: [PATCH 21/46] assert - use updated ph2/ph4 macros that support pei dp vs lda dp / pha. also expand a couple tabs -> spaces. --- assert.asm | 8 +-- assert.macros | 169 +++++++++++++++++++++++++++----------------------- 2 files changed, 95 insertions(+), 82 deletions(-) diff --git a/assert.asm b/assert.asm index 454def3..4bb73f4 100644 --- a/assert.asm +++ b/assert.asm @@ -34,11 +34,11 @@ __assert start csubroutine (4:f,2:l,4:s),0 - ph4 s - ph2 l - ph4 f + ph4 stderr + ph4 >stderr jsl fprintf jsl abort 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 From 2d20af84fdb3209ad541d17b2b76bc1f0d74840c Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 9 Sep 2018 20:55:23 -0500 Subject: [PATCH 22/46] Fix support for 'h' length modifier in scanf. This got broken when adding support for 'hh'. --- stdio.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdio.asm b/stdio.asm index 56ed281..fecd6f9 100644 --- a/stdio.asm +++ b/stdio.asm @@ -5367,13 +5367,13 @@ fm3 cmp #'h' else if it is an 'h' then lda [format] and #$00FF cmp #'h' - bne fm4 + 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 From 2be73c4e5d03cb73e087ed30b7f64526ed3e87c3 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 9 Sep 2018 21:26:21 -0500 Subject: [PATCH 23/46] Make strerror() return a valid error string for unknown errno values. This is required by C99 and later. --- stdio.asm | 2 +- string.asm | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/stdio.asm b/stdio.asm index fecd6f9..66f5e66 100644 --- a/stdio.asm +++ b/stdio.asm @@ -2946,7 +2946,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' diff --git a/string.asm b/string.asm index 397ad05..29ba19d 100644 --- a/string.asm +++ b/string.asm @@ -17,6 +17,7 @@ **************************************************************** * String start dummy routine + copy equates.asm end @@ -888,6 +889,7 @@ lb2 sty set set the disp past the current disp **************************************************************** * strerror start +maxErr equ ENOSPC max error in sys_errlist phb get the error number plx @@ -897,7 +899,10 @@ strerror start phx phk use local data bank plb - asl A compute the index + cmp #maxErr+1 + blt lb1 + lda #0 +lb1 asl A compute the index asl A tay ldx sys_errlist+2,Y load the address From 24ec2ae9bc8b6c847812fff0c025bd663b38b13f Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 9 Sep 2018 21:43:14 -0500 Subject: [PATCH 24/46] Fix perror() issues. perror() should write only a single new-line. Also, it should not write the prefix string, colon and space if the prefix string pointer is NULL or if it points to an empty string. --- stdio.asm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/stdio.asm b/stdio.asm index 66f5e66..a0531f0 100644 --- a/stdio.asm +++ b/stdio.asm @@ -2141,6 +2141,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 @@ -2151,7 +2158,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 @@ -2164,12 +2171,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 From efab82784d14da5f4561cff2e2c75b20f59379c8 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 9 Sep 2018 23:23:19 -0500 Subject: [PATCH 25/46] Add _Exit() function from C99. This exits the programs without calling atexit functions and possibly without doing other clean-up operations. In ORCA/C, it is functionally identical to _exit(). --- stdlib.asm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stdlib.asm b/stdlib.asm index 7dfafbb..0ee837c 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -301,6 +301,9 @@ div_t ds 4 * void _exit(status) * int status; * +* void _Exit(status) +* int status; +* * Stop the program. Exit cleans up, _exit does not. Status * is the status returned to the shell. * @@ -313,6 +316,7 @@ exit start jsr ~EXIT _exit entry +_Exit entry lda 4,S jmp ~QUIT end From 27fc6836ccc1cbab6b0274b68f34b71d0add771e Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 10 Sep 2018 17:09:28 -0500 Subject: [PATCH 26/46] Fix div() and ldiv() to return properly-signed remainders. They could previously give the wrong sign on the remainder in certain cases where one or both of the arguments were negative, because they were using the wrong condition to decide whether to negate it. --- stdlib.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib.asm b/stdlib.asm index 0ee837c..1fb9be7 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -282,7 +282,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 @@ -427,7 +427,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 From 7a20f5f71d3d3c34b5727bec666f1c3459421314 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 13 Sep 2018 02:23:21 -0500 Subject: [PATCH 27/46] strtoul: don't try to parse initial '0x' as hex prefix unless base is 0 or 16. In other bases, the 'x' either ends parsing of the number string or (in base 34 and larger) is a digit. Also, ensure only ASCII characters (with high bit clear) are accepted in all situations. --- stdlib.asm | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/stdlib.asm b/stdlib.asm index 1fb9be7..9d3b212 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -858,23 +858,23 @@ db1a lda base if the base is zero then 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 cn1 + 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 ; ; Convert the number ; @@ -884,7 +884,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 From 571c601b66ee893483617d8a6b47b923c99361c5 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 9 Jun 2019 19:12:51 -0500 Subject: [PATCH 28/46] strtoul: return 0 when given an empty string, as required by the C standards. The issue was introduced in commit 6e9790667. errno is now set to EINVAL in this case. (This is not required by the C standards, but is consistent with various other implementations.) This fixes the cases in #23 related to strtol() and strtoul(). --- stdlib.asm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stdlib.asm b/stdlib.asm index 9d3b212..91f94ba 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -926,6 +926,9 @@ cn4 inc4 str next char cn5 lda foundOne if no digits were found, flag the error bne rt1 + lda #EINVAL + sta >errno + bra rt2 ; ; flag an error ; From 887d66d537bf63a768ed08aad980b1af3696ff07 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 12 Jan 2020 18:54:07 -0600 Subject: [PATCH 29/46] Implement aligned_alloc function (C11). This allocates memory with a specified alignment. Currently, the only allowed alignment value is 1. --- stdlib.asm | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/stdlib.asm b/stdlib.asm index 91f94ba..d3a5e26 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -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 Date: Tue, 21 Jan 2020 17:12:54 -0600 Subject: [PATCH 30/46] Ensure that strtok returns NULL after reaching the end of the string. It had been doing a null pointer dereference and effectively treating memory locations starting from 0 as the continuation of the string, potentially producing inappropriate results depending on what they contained. --- string.asm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/string.asm b/string.asm index 29ba19d..7cb9c9e 100644 --- a/string.asm +++ b/string.asm @@ -1730,15 +1730,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 From 07011e5b05f701c156b4be46e62f09c51ae0b646 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Wed, 22 Jan 2020 07:27:34 -0600 Subject: [PATCH 31/46] Fix issue causing potential stack corruption in scanf(). This could happen if a scan error occurred and certain conversion specifiers containing the % character in a scanset (e.g. %4[%]) appeared as subsequent elements in the format string. The fix is to more thoroughly parse the format string when cleaning up after a scan error. This fixes #26. --- stdio.asm | 55 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/stdio.asm b/stdio.asm index a0531f0..8c8f04c 100644 --- a/stdio.asm +++ b/stdio.asm @@ -5282,9 +5282,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 @@ -5298,24 +5299,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 ; @@ -5418,6 +5436,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 From ee1b7e606da9ab4bdc01b22777176c3192b15e50 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 23 Jan 2020 18:43:20 -0600 Subject: [PATCH 32/46] Implement quick_exit() and at_quick_exit() from C11. Also, make all the exit functions quit via RTL if #pragma rtl was used. This fixes #19. --- cc.asm | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ stdlib.asm | 76 ++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 138 insertions(+), 8 deletions(-) diff --git a/cc.asm b/cc.asm index 74c490f..09e9bf6 100644 --- a/cc.asm +++ b/cc.asm @@ -184,6 +184,8 @@ TAB equ 9 TAB key code stz ~ExitList no exit routines, yet stz ~ExitList+2 + stz ~QuickExitList + stz ~QuickExitList+2 case on jsl ~InitIO reset standard I/O case off @@ -359,6 +361,10 @@ start ds 2 start of the command line string 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 @@ -439,14 +445,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 **************************************************************** diff --git a/stdlib.asm b/stdlib.asm index d3a5e26..4f18eb1 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 **************************************************************** @@ -159,6 +159,60 @@ rval equ 5 return value lb1 creturn 2:rval end +**************************************************************** +* +* int at_quick_exit(func) +* void (*func)(); +* +* This function is used to build a list of functions that will +* be called as part of the quick exit processing. +* +* Inputs: +* func - address of the function to call on quick exit +* +* Outputs: +* Returns 0 if successful, -1 if not. +* +**************************************************************** +* +at_quick_exit start +ptr equ 1 work pointer +rval equ 5 return value + + csubroutine (4:func),6 + + lda #-1 assume we will fail + sta rval assume we will fail + dec4 func we need the addr-1, not the addr + ph4 #8 get space for the record + jsl malloc + stx ptr+2 + sta ptr + ora ptr+2 quit now if we failed + beq lb1 + ldy #2 place the record in the exit list + lda >~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 @@ -331,14 +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(status) -* 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. @@ -354,7 +407,14 @@ exit start _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 **************************************************************** From 599c1e3c7b80ec99c2c453d4531f5a888450c8a8 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 23 Jan 2020 20:42:25 -0600 Subject: [PATCH 33/46] Fix problem where strtol would accept invalid strings like "- +53". This stemmed from its calling strtoul internally, causing it to accept extra while space and/or + signs. The fix is to have an alternate entry point for strtoul that skips that processing. --- stdlib.asm | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/stdlib.asm b/stdlib.asm index 4f18eb1..fdc4d28 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -838,7 +838,7 @@ 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 @@ -891,6 +891,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 @@ -913,7 +915,13 @@ rtl equ 7 return address 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 0 make room for & initialize foundOne pea 0 make room for & initialize val pea 0 tsc set up direct page addressing @@ -924,13 +932,15 @@ foundOne equ 1 have we found a number? ; lda ptr if ptr in non-null then ora ptr+2 - beq sw1 + beq sw0 lda str initialize it to str sta [ptr] ldy #2 lda str+2 sta [ptr],Y +sw0 txa just process number if called from strtol + bne db1a sw1 lda [str] skip the white space and #$00FF tax From ebbb5b73ed009ac36da065c88e7b573de9e38207 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 23 Jan 2020 21:50:11 -0600 Subject: [PATCH 34/46] Allow strtoul to take numbers with a minus sign. The effect of this is to negate the number in the unsigned long type before returning it. --- stdlib.asm | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/stdlib.asm b/stdlib.asm index fdc4d28..8698230 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -907,11 +907,12 @@ 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 20 base +ptr equ 16 *return pointer +str equ 12 string pointer +rtl equ 9 return address +negative equ 7 was there a minus sign? val equ 3 value foundOne equ 1 have we found a number? @@ -921,7 +922,8 @@ foundOne equ 1 have we found a number? ~strtoul entry alt entry point called from strtol ldx #1 -init pea 0 make room for & initialize foundOne +init pea 0 make room for & initialize negative + pea 0 make room for & initialize foundOne pea 0 make room for & initialize val pea 0 tsc set up direct page addressing @@ -940,7 +942,7 @@ init pea 0 make room for & initialize foundOne sta [ptr],Y sw0 txa just process number if called from strtol - bne db1a + bne db1c sw1 lda [str] skip the white space and #$00FF tax @@ -952,12 +954,16 @@ 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 @@ -1055,7 +1061,10 @@ rt1 lda ptr if ptr is non-null then ldy #2 lda str+2 sta [ptr],Y -rt2 ldx val+2 get the value +rt2 lda negative if negative then + beq rt2a + sub4 #0,val,val val = -val +rt2a ldx val+2 get the value ldy val rt3 lda rtl fix the stack sta base-1 @@ -1064,7 +1073,7 @@ rt3 lda rtl fix the stack pld tsc clc - adc #16 + adc #18 tcs tya return rtl From 14554fcdc76d97b344b66a62e5d5b0b9f65add23 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 23 Jan 2020 23:33:29 -0600 Subject: [PATCH 35/46] Make strtol() and strtoul() set the right end pointer in error cases. Previously, they often did not do this. Now they do, as follows: If there was a sequence of the expected numeric form, then they fully parse that sequence and give a pointer past the end of it, even if the number was out of range. If there was not a sequence of the expected form, they give the starting pointer that they were passed in. --- stdlib.asm | 62 +++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/stdlib.asm b/stdlib.asm index 8698230..0272cd9 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -795,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 @@ -856,14 +856,6 @@ cn3 ph4 str save the starting string iny ov1 sty val stx val+2 - 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 ; ; return the results ; @@ -907,11 +899,12 @@ rt2 ldx val+2 get the value **************************************************************** * strtoul start -base equ 20 base -ptr equ 16 *return pointer -str equ 12 string pointer -rtl equ 9 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? @@ -922,27 +915,29 @@ foundOne equ 1 have we found a number? ~strtoul entry alt entry point called from strtol ldx #1 -init pea 0 make room for & initialize negative - pea 0 make room for & initialize foundOne +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 sw0 + beq sw1 lda str initialize it to str sta [ptr] ldy #2 lda str+2 sta [ptr],Y -sw0 txa just process number if called from strtol - bne db1c sw1 lda [str] skip the white space and #$00FF tax @@ -1025,14 +1020,16 @@ 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 @@ -1040,27 +1037,26 @@ cn5 lda foundOne if no digits were found, flag the error bne rt1 lda #EINVAL sta >errno - bra rt2 -; -; flag an error -; -returnERANGE anop - lda #ERANGE errno = ERANGE - sta >errno - ldx #$FFFF return value = ULONG_MAX - txy - bra rt3 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 + +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 @@ -1073,7 +1069,7 @@ rt3 lda rtl fix the stack pld tsc clc - adc #18 + adc #20 tcs tya return rtl From 8490da9d85c9bfdbde0fc08a1361cbf683a12bbc Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 24 Jan 2020 12:25:01 -0600 Subject: [PATCH 36/46] Allow -2147483648 (LONG_MIN) as valid input to strtol(), not setting errno. This is what other implementations do and seems to be the intent of the standards, although the wording isn't entirely clear. --- stdlib.asm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/stdlib.asm b/stdlib.asm index 0272cd9..fe21c02 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -843,10 +843,16 @@ cn3 ph4 str save the starting string 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 ldx #$7FFF return value = LONG_MAX ldy #$FFFF From bd6d51785418a82dff4ed93cb19814a7cb1990b2 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 30 Jan 2020 18:51:59 -0600 Subject: [PATCH 37/46] Note that ~RemoveWord is used by scanf, not printf. --- stdio.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdio.asm b/stdio.asm index 8c8f04c..d3c9e00 100644 --- a/stdio.asm +++ b/stdio.asm @@ -4533,7 +4533,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) From c77c5927d93d6ba39458b8123709820e3309163b Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 30 Jan 2020 20:15:45 -0600 Subject: [PATCH 38/46] Support "x" in fopen()/freopen() mode strings (C11). If the mode string ends in "x", opening a file for writing will fail if the file already exists. --- stdio.asm | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/stdio.asm b/stdio.asm index d3c9e00..4c12127 100644 --- a/stdio.asm +++ b/stdio.asm @@ -785,6 +785,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 ; @@ -794,15 +795,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 @@ -814,11 +821,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 @@ -947,12 +958,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 @@ -1078,6 +1091,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 ; @@ -1095,9 +1109,17 @@ nl1 cmp #'b' bne nl2 lda #BIN sta crFileType + 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 @@ -1109,8 +1131,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 From 27a32d82bd2a21a8e51ea2b4ba3fa644d6b1b48d Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 30 Jan 2020 21:16:48 -0600 Subject: [PATCH 39/46] Allow 'b' to come before '+' in freopen modes (e.g. "wb+"). Previously, only forms like "w+b" worked. --- stdio.asm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/stdio.asm b/stdio.asm index 4c12127..92bbd47 100644 --- a/stdio.asm +++ b/stdio.asm @@ -1110,6 +1110,13 @@ nl1 cmp #'b' 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 @@ -1160,7 +1167,7 @@ ar1 ph4 #BUFSIZ get space for the file buffer bne ar3 lda #ENOMEM memory error sta >errno - bra rt1 + brl rt1 ar3 move4 stream,fileBuff set the file buffer address lda buffStart set the start of the buffer @@ -1185,10 +1192,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' From c439f2e3ea92912d6ff2e7962d67265acc419d7c Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 31 Jan 2020 12:45:02 -0600 Subject: [PATCH 40/46] Make tmpnam() return the pointer passed to it, if non-null. This is what the standards call for. It was previously always returning a pointer to its internal buffer. --- stdio.asm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stdio.asm b/stdio.asm index 92bbd47..1b36bf7 100644 --- a/stdio.asm +++ b/stdio.asm @@ -3067,9 +3067,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 From 9af1c093cbe93cbad648a966e799a5a7e0ec7da4 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Fri, 31 Jan 2020 12:47:34 -0600 Subject: [PATCH 41/46] Ensure tmpfile() doesn't access a file created by someone else. This could happen due to a race condition, which shouldn't generally be an issue on the GS but is at least theoretically possible under GNO or Golden Gate. --- stdio.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdio.asm b/stdio.asm index 1b36bf7..1f18719 100644 --- a/stdio.asm +++ b/stdio.asm @@ -3118,7 +3118,7 @@ f equ 1 file pointer lb1 creturn 4:f -type cstr 'w+b' +type cstr 'w+bx' end **************************************************************** From 44dfc1d1d6ee376d3e4f2a5045a6651c01e41f83 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 2 Feb 2020 12:51:58 -0600 Subject: [PATCH 42/46] Prevent localtime() from potentially giving incorrect tm_isdst values. This could happen when it was called for a time other than the present, because it set tm_isdst based on the current value of the DST flag in BRAM, which is valid only for the current time. Now it works as follows: If localtime() is passed the time_t value that was produced by the most recent call to time(), it gives the DST setting in effect at the time of that call. Otherwise, it sets tm_isdst to -1, indicating that the correct value is unknown. This is about the best we can do without having a full timezone library/database. It should give the right tm_isdst value in probably the most common case, and avoids giving an incorrect value in any case (assuming the system's DST flag is right). This fixes #18. --- time.asm | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/time.asm b/time.asm index abe25b5..b260877 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 **************************************************************** @@ -284,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 @@ -340,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 @@ -499,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 From 573bc6efa9453ca645395db9ec45d5b63c04e030 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 16 Feb 2020 13:28:18 -0600 Subject: [PATCH 43/46] Use consistent indentation within files. Tabs have been expanded to spaces in several files that use mainly spaces for indentation. The files ctype.asm, stdio.asm, and string.asm consistently use tabs for indentation. The tabs in these files have been left alone, except that a few tabs between sentences in comments were changed to spaces. One space-indented line in stdio.asm was changed to use a tab. --- cc.asm | 30 +++++++++++++++--------------- ctype.asm | 2 +- equates.asm | 2 +- orca.asm | 6 +++--- stdio.asm | 16 ++++++++-------- string.asm | 4 ++-- time.asm | 2 +- toolglue.asm | 28 ++++++++++++++-------------- 8 files changed, 45 insertions(+), 45 deletions(-) diff --git a/cc.asm b/cc.asm index 09e9bf6..298fc6a 100644 --- a/cc.asm +++ b/cc.asm @@ -1085,26 +1085,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 4ba2ece..3c6bcac 100644 --- a/ctype.asm +++ b/ctype.asm @@ -850,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 b5a0614..4760a9e 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 ! ---------------- 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/stdio.asm b/stdio.asm index 1f18719..d028667 100644 --- a/stdio.asm +++ b/stdio.asm @@ -640,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. * **************************************************************** @@ -2064,7 +2064,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. * **************************************************************** @@ -2273,7 +2273,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 @@ -4264,7 +4264,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 @@ -4278,7 +4278,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 @@ -4295,7 +4295,7 @@ 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 @@ -5223,7 +5223,7 @@ 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 @@ -5367,7 +5367,7 @@ rm1d cmp #']' skip ']' in scanset, if present bne rm2a rm2 jsr IncFormat rm2a tax - beq rt1 skip up to the closing ']' + beq rt1 skip up to the closing ']' cmp #']' bne rm2 rm3 tyx if '*' not found diff --git a/string.asm b/string.asm index 7cb9c9e..f140c60 100644 --- a/string.asm +++ b/string.asm @@ -742,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 @@ -1058,7 +1058,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 diff --git a/time.asm b/time.asm index b260877..658e18d 100644 --- a/time.asm +++ b/time.asm @@ -364,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 **************************************************************** diff --git a/toolglue.asm b/toolglue.asm index b764fc6..b06522a 100644 --- a/toolglue.asm +++ b/toolglue.asm @@ -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 From e5360c9605015eedb50cae5f3f4253ad90f3d61b Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 16 Feb 2020 13:29:53 -0600 Subject: [PATCH 44/46] Spellcheck comments. --- equates.asm | 2 +- signal.asm | 6 +++--- stdio.asm | 18 +++++++++--------- stdlib.asm | 4 ++-- string.asm | 32 ++++++++++++++++---------------- time.asm | 2 +- toolglue.asm | 2 +- vars.asm | 2 +- 8 files changed, 34 insertions(+), 34 deletions(-) diff --git a/equates.asm b/equates.asm index 4760a9e..4d7fd05 100644 --- a/equates.asm +++ b/equates.asm @@ -70,7 +70,7 @@ 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+2 buffer flags FILE_file gequ FILE_flag+2 GS/OS file ID 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 d028667..c29e897 100644 --- a/stdio.asm +++ b/stdio.asm @@ -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 @@ -1410,7 +1410,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 @@ -3109,7 +3109,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 @@ -3141,7 +3141,7 @@ type cstr 'w+bx' * ungetc start -char equ 1 characater to return +char equ 1 character to return csubroutine (2:c,4:stream),2 @@ -4287,7 +4287,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. * @@ -4302,9 +4302,9 @@ lb3 creturn 4:ptr * -------------------- * * 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. @@ -5546,7 +5546,7 @@ 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 -> char, 1 -> long, ! 0 -> default diff --git a/stdlib.asm b/stdlib.asm index fe21c02..dfa36f7 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -661,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 @@ -1183,7 +1183,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 f140c60..13933a2 100644 --- a/string.asm +++ b/string.asm @@ -85,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 * **************************************************************** * @@ -203,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 @@ -577,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) @@ -956,14 +956,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: @@ -1021,8 +1021,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: @@ -1243,9 +1243,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 @@ -1307,9 +1307,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 @@ -1598,7 +1598,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 diff --git a/time.asm b/time.asm index 658e18d..4af8d83 100644 --- a/time.asm +++ b/time.asm @@ -373,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 diff --git a/toolglue.asm b/toolglue.asm index b06522a..b03e471 100644 --- a/toolglue.asm +++ b/toolglue.asm @@ -36,7 +36,7 @@ ToolGlue start dummy routine **************************************************************** * -* MiscTool - Miscelaneous tool kit +* MiscTool - Miscellaneous tool kit * **************************************************************** * diff --git a/vars.asm b/vars.asm index 6f9f8b7..523c4e0 100644 --- a/vars.asm +++ b/vars.asm @@ -39,7 +39,7 @@ _toolErr entry last error in a tool call (C) **************************************************************** * -* ~InitIO - initialize the standad I/O files +* ~InitIO - initialize the standard I/O files * **************************************************************** * From 717cf99071d3a9093fd9cdaccb08c274055f5398 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 17 Feb 2020 17:37:59 -0600 Subject: [PATCH 45/46] Detect invalid base values in strtol and strtoul. They will now return 0 and set errno to EINVAL if an invalid base value (anything other than 0 or 2..36) is detected. This behavior is required by POSIX. It's not required by the C standards (which leave the behavior in this case undefined), but it seems reasonable to do. --- stdlib.asm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/stdlib.asm b/stdlib.asm index dfa36f7..edd8c8a 100644 --- a/stdlib.asm +++ b/stdlib.asm @@ -982,12 +982,17 @@ db1c lda base if the base is zero then asl base base 16 bra db3 db2 cmp #16 if the base is 16 then - bne cn1 + bne db4 lda [str] if the first two chars are 0x or 0X then and #$DFFF cmp #'X0' bne cn1 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 ; @@ -1041,7 +1046,7 @@ cn4 inc4 str next char cn5 lda foundOne if no digits were found, flag the error bne rt1 - lda #EINVAL +cn6 lda #EINVAL sta >errno bra rt2a ; From e9de42d6c4400c2351ae2ad74e1a87b4ff281c8c Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Mon, 17 Feb 2020 19:49:18 -0600 Subject: [PATCH 46/46] fopen: do not require read access when opening a file for append only. This can cause an error if the file's permissions deny read access. --- stdio.asm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stdio.asm b/stdio.asm index c29e897..93e32ad 100644 --- a/stdio.asm +++ b/stdio.asm @@ -763,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