├── .gitignore ├── barebones-interop ├── assets │ ├── 254056__jagadamba__space-sound.wav │ └── pic.png ├── code │ ├── code.s │ ├── main.c │ └── replace_libc_mintlib_junk.s ├── fbuild.bff ├── obj │ └── 254056__jagadamba__space-sound.raw └── readme.md ├── barebones ├── Makefile ├── auto │ └── dummy ├── build.bat ├── cpptest.cpp ├── ctest.c ├── libcxx │ ├── brownboot.o │ ├── brownboot.s │ ├── browncrt++.c │ ├── browncrti.gas │ ├── browncrtn.gas │ ├── brownmint++.c │ ├── lib.h │ ├── libc-symbols.h │ ├── zerocrtfini.c │ └── zerolibc.cpp ├── lolworld.cpp ├── obj │ └── dummy ├── printf.c └── vsnprint.c ├── bigbrownbuild.sh ├── bigbrowngemlib.sh ├── bigbrownlibcmini.sh ├── brownart.png ├── readme.md ├── test-browntran ├── brownboot.o ├── brownboot.s ├── build-pml.sh ├── buildit.sh └── heron.f └── ub.png /.gitignore: -------------------------------------------------------------------------------- 1 | gcc-* 2 | build-* 3 | binary-package* 4 | mintlib-bigbrownbuild* 5 | *.bz2 6 | *.xz 7 | binutils-* 8 | newlib* 9 | -------------------------------------------------------------------------------- /barebones-interop/assets/254056__jagadamba__space-sound.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/barebones-interop/assets/254056__jagadamba__space-sound.wav -------------------------------------------------------------------------------- /barebones-interop/assets/pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/barebones-interop/assets/pic.png -------------------------------------------------------------------------------- /barebones-interop/code/code.s: -------------------------------------------------------------------------------- 1 | 2 | .globl _palette_current 3 | .globl _vbl_count 4 | 5 | 6 | .data 7 | 8 | _screen_phys:: .dc.l SCREEN1 9 | _screen_log:: .dc.l SCREEN2 10 | 11 | .even 12 | _sample_start:: .incbin "obj/254056__jagadamba__space-sound.raw" 13 | _sample_end:: 14 | .even 15 | 16 | _pic_palette:: .incbin "obj/pic.pi1",32,2 17 | _pic_data:: .incbin "obj/pic.pi1",32000,34 18 | _pic_data_end:: 19 | 20 | .bss 21 | ds.b 256 22 | SCREEN1: ds.b 32000 23 | SCREEN2: ds.b 32000 24 | 25 | _old_pal:: .ds.l 8 26 | old_pal_falcon_tt: .ds.l 256 ; enough for ST/E, TT and Falcon 27 | _machine_type:: .ds.w 1 28 | 29 | .text 30 | 31 | ;------------------------------------------------------------------------------- 32 | ; Detect machine and setup video 33 | ;------------------------------------------------------------------------------- 34 | 35 | _detect_machine:: 36 | movem.l d0-a6,-(sp) 37 | 38 | move.l #'Emu?',D5 39 | move.l D5,D6 40 | move.l D6,D7 41 | move.w #$25,-(SP) 42 | trap #14 43 | addq.l #2,SP 44 | cmp.l D5,D7 45 | bne.s find_emu 46 | cmp.l D5,D6 47 | beq.s cookiejar 48 | find_emu: moveq #10,D2 49 | lea emulators(PC),A0 50 | moveq #(end_emulators-emulators)/8-1,D0 51 | find_emu_loop: movem.l (A0)+,D3-D4 52 | cmp.l D3,D6 53 | bne.s diff_emu 54 | cmp.l D4,D7 55 | bne.s diff_emu 56 | lea -8(A0),A1 57 | bra.s found_machine 58 | diff_emu: addq.w #1,D2 59 | dbra D0,find_emu_loop 60 | 61 | 62 | cookiejar: move.l #"_MCH",D1 ;cookie we want 63 | move.l #'CT60',D2 ;for CT6x detection 64 | move.l $05A0.w,D0 ;get address of cookie jar in d0 65 | beq.s .nofind ;If zero, there's no jar. 66 | movea.l D0,A0 ;move the address of the jar to a0 67 | .search: tst.l (A0) ;is this jar entry the last one ? 68 | beq.s .nofind ;yes, the cookie was not found 69 | cmp.l (A0),D1 ;does this cookie match what we're looking for? 70 | beq.s foundit ;yes, it does. 71 | cmp.l (A0),D2 ;detected CT6x? 72 | beq.s ct6x ;yep 73 | addq.l #8,A0 ;advance to the next jar entry 74 | bra.s .search ;and start over 75 | 76 | .nofind: lea m_stfm(PC),A1 77 | moveq #0,D2 78 | bra.s found_machine 79 | 80 | ct6x: lea m_ct6x(PC),A1 81 | moveq #7,D2 82 | bra.s found_machine 83 | 84 | foundit: lea machines(PC),A2 85 | move.l 4(A0),D0 86 | moveq #(end_machines-machines)/12-1,D1 87 | moveq #1,D2 88 | findmachine: cmp.l (A2)+,D0 89 | beq.s found_machine 90 | addq.w #1,D2 91 | addq.l #8,A2 92 | dbra D1,findmachine 93 | lea m_unknown(PC),A1 ;if we got here and didn't find any sane values then we got a problem 94 | moveq #8,D2 95 | 96 | found_machine: 97 | bra.s scr_setup 98 | 99 | m_unknown: DC.B 'Unknown ' 100 | m_stfm: DC.B 'STF/M ' 101 | m_ct6x: DC.B 'CT60/63 ' 102 | machines: 103 | DC.L $010000,'STE ',' ' 104 | DC.L $010010,'Mega',' STE' 105 | DC.L $030000,'Falc','on ' 106 | DC.L $020000,'TT ',' ' 107 | DC.L $010008,'Unof','f/al' 108 | DC.L $010001,'ST B','ook ' 109 | end_machines: 110 | emulators: DC.L 'PaCi','fiST' 111 | DC.L 'Tbox',' ' 112 | DC.L 'STEe','mEng' 113 | end_emulators: 114 | 115 | STFM EQU 0 116 | STE EQU 1 117 | MEGASTE EQU 2 118 | FALCON EQU 3 119 | TT EQU 4 120 | CRAP EQU 5 121 | STBOOK EQU 6 122 | CT6X EQU 7 123 | UNKNOWN EQU 8 124 | PACIFIST EQU 10 125 | TOSBOX EQU 11 126 | STEEM EQU 12 127 | 128 | scr_setup: 129 | 130 | clr.b _screen_phys+3 ; align to 256 byte boundary 131 | clr.b _screen_log+3 ; align to 256 byte boundary 132 | 133 | move.w d2,_machine_type 134 | 135 | cmp.w #FALCON,d2 136 | beq.s setup_falcon 137 | blt setup_st_ste 138 | cmp.w #CT6X,d2 139 | beq.s setup_falcon 140 | cmp.w #TT,d2 141 | beq setup_tt 142 | 143 | bra setup_st_ste ; Let's assume it's a plain ST for the rest - what could go wrong? (lol) 144 | 145 | ; ______ _ 146 | ; | ____| | | 147 | ; | |__ __ _| | ___ ___ _ __ 148 | ; | __/ _` | |/ __/ _ \| '_ \ 149 | ; | | | (_| | | (_| (_) | | | | 150 | ; |_| \__,_|_|\___\___/|_| |_| 151 | 152 | setup_falcon: 153 | 154 | move.w #256-1,d7 155 | lea $ffff9800.w,a0 156 | lea old_pal_falcon_tt,a1 157 | save_falc_pal: 158 | move.l (a0)+,(a1)+ 159 | dbra d7,save_falc_pal 160 | 161 | movem.l $ffff8240.w,d0-d7 162 | movem.l d0-d7,_old_pal 163 | 164 | ; Save Falcon video 165 | ; Saves the current falcon resolution to an internal buffer. 166 | lea save_video,a6 167 | 168 | move.w #2,-(sp) ; physbase 169 | trap #14 170 | addq.l #2,sp 171 | move.l d0,(a6)+ 172 | move.w #3,-(sp) ; logbase 173 | trap #14 174 | addq.l #2,sp 175 | move.l d0,(a6)+ 176 | 177 | move.l $FFFF8282.w,(A6)+ ; h-regs 178 | move.l $FFFF8286.w,(A6)+ ; 179 | move.l $FFFF828A.w,(A6)+ ; 180 | move.l $FFFF82A2.w,(A6)+ ; v-regs 181 | move.l $FFFF82A6.w,(A6)+ ; 182 | move.l $FFFF82AA.w,(A6)+ ; 183 | move.w $FFFF82C0.w,(A6)+ ; vco 184 | move.w $FFFF82C2.w,(A6)+ ; c_s 185 | move.l $FFFF820E.w,(A6)+ ; offset 186 | move.w $FFFF820A.w,(A6)+ ; sync 187 | move.b $FFFF8256.w,(A6)+ ; p_o 188 | clr.b (A6) ; test of st(e) or falcon mode 189 | cmpi.w #$B0,$FFFF8282.w ; hht kleiner $b0? 190 | sle (A6)+ ; flag setzen 191 | move.w $FFFF8266.w,(A6)+ ; f_s 192 | move.w $FFFF8260.w,(A6)+ ; st_s 193 | 194 | ; Setup video 195 | 196 | move.l _screen_phys,d0 197 | lsr.w #8,d0 198 | move.l d0,$ffff8200.w 199 | 200 | move.w #$59,-(sp) 201 | trap #14 202 | addq.l #2,sp 203 | 204 | move.w #$3,d1 ; 320x200x4bpp 205 | cmp.w #2,d0 ; VGA? 206 | bne.s do_setup 207 | or.w #$110,d1 ; set VGA+doubling bit 208 | add.l #320*28,_screen_phys; centre screen vertically for VGA 209 | add.l #320*28,_screen_log; centre screen vertically for VGA 210 | 211 | do_setup: 212 | move.w d1,-(sp) 213 | move.w #$58,-(sp) 214 | trap #14 215 | addq.l #4,sp 216 | 217 | movem.l (sp)+,d0-a6 218 | rts 219 | 220 | 221 | 222 | save_video: .ds.b 40 223 | save_video_ptrs:.ds.l 2 ; plus 2 longs for old phys/log pointers 224 | 225 | ; _______ _______ 226 | ; |__ __|__ __| 227 | ; | | | | 228 | ; | | | | 229 | ; | | | | 230 | ; |_| |_| 231 | 232 | setup_tt: 233 | 234 | ; Save palette 235 | 236 | move.w #256/2-1,d7 237 | lea $ffff8400.w,a0 238 | lea old_pal_falcon_tt,a1 239 | save_tt_pal: 240 | move.l (a0)+,(a1)+ 241 | dbra d7,save_tt_pal 242 | 243 | ; Save video 244 | 245 | lea save_video(pc),a6 246 | move.w $ffff8262.w,(a6)+ 247 | move.w #2,-(sp) ; physbase 248 | trap #14 249 | addq.l #2,sp 250 | move.l d0,(a6)+ 251 | 252 | movem.l (sp)+,d0-a6 253 | rts 254 | 255 | ; _____ _______ _______ _______ ______ 256 | ; / ____|__ __|/ / ____|__ __| ____| 257 | ; | (___ | | / / (___ | | | |__ 258 | ; \___ \ | | / / \___ \ | | | __| 259 | ; ____) | | |/ / ____) | | | | |____ 260 | ; |_____/ |_/_/ |_____/ |_| |______| 261 | 262 | setup_st_ste: 263 | movem.l $ffff8240.w,d0-d7 264 | movem.l d0-d7,_old_pal 265 | lea save_video(pc),a6 266 | move.w #4,-(sp) ; getrez 267 | trap #14 268 | addq.l #2,sp 269 | move.w d0,(a6)+ 270 | move.w #2,-(sp) ; physbase 271 | trap #14 272 | addq.l #2,sp 273 | move.l d0,(a6)+ 274 | move.w #3,-(sp) ; logbase 275 | trap #14 276 | addq.l #2,sp 277 | move.l d0,(a6)+ 278 | 279 | clr.w -(sp) 280 | move.l _screen_phys,-(sp) 281 | move.l (sp),-(sp) 282 | move.w #5,-(sp) 283 | trap #14 284 | lea 12(sp),sp 285 | 286 | movem.l (sp)+,d0-a6 287 | rts 288 | 289 | ;------------------------------------------------------------------------------- 290 | ; Restore video 291 | ;------------------------------------------------------------------------------- 292 | _restore_video:: 293 | movem.l d0-a6,-(sp) 294 | 295 | move.w _machine_type,d2 296 | 297 | cmp.w #FALCON,d2 298 | beq.s restore_video_falcon 299 | blt restore_video_st_ste 300 | cmp.w #CT6X,d2 301 | beq.s restore_video_falcon 302 | cmp.w #TT,d2 303 | beq restore_video_tt 304 | 305 | bra restore_video_st_ste ; Let's assume it's a plain ST for the rest - what could go wrong? (lol) 306 | 307 | ; ______ _ 308 | ; | ____| | | 309 | ; | |__ __ _| | ___ ___ _ __ 310 | ; | __/ _` | |/ __/ _ \| '_ \ 311 | ; | | | (_| | | (_| (_) | | | | 312 | ; |_| \__,_|_|\___\___/|_| |_| 313 | 314 | restore_video_falcon: 315 | lea save_video,a6 316 | 317 | move.w #-1,-(sp) 318 | move.l (a6)+,-(sp) 319 | move.l (a6)+,-(sp) 320 | move.w #5,-(sp) 321 | trap #14 322 | lea 12(sp),sp 323 | 324 | clr.w $FFFF8266.w ; falcon-shift clear 325 | move.l (A6)+,$FFFF8282.w ;0 * h-regs 326 | move.l (A6)+,$FFFF8286.w ;4 * 327 | move.l (A6)+,$FFFF828A.w ;8 * 328 | move.l (A6)+,$FFFF82A2.w ;12 * v-regs 329 | move.l (A6)+,$FFFF82A6.w ;16 * 330 | move.l (A6)+,$FFFF82AA.w ;20 * 331 | move.w (A6)+,$FFFF82C0.w ;24 * vco 332 | move.w (A6)+,$FFFF82C2.w ;26 * c_s 333 | move.l (A6)+,$FFFF820E.w ;28 * offset 334 | move.w (A6)+,$FFFF820A.w ;32 * sync 335 | move.b (A6)+,$FFFF8256.w ;34 * p_o 336 | tst.b (A6)+ ;35 * st(e) compatible mode? 337 | bne.s .st_ste ;36 338 | move.w $0468.w,D0 ; / wait for vbl 339 | .wait468: ; | to avoid 340 | cmp.w $0468.w,D0 ; | falcon monomode 341 | beq.s .wait468 ; \ syncerrors. 342 | move.w (A6),$FFFF8266.w ;38 * falcon-shift 343 | bra.s .video_restored 344 | .st_ste:move.w 2(A6),$FFFF8260.w ;40 * st-shift 345 | move.w -10(A6),$FFFF82C2.w ; c_s 346 | move.l -8(A6),$FFFF820E.w ; offset 347 | .video_restored: 348 | 349 | ; Restore palette 350 | 351 | move.w #256-1,d7 352 | lea old_pal_falcon_tt,a0 353 | lea $ffff9800.w,a1 354 | restore_falc_pal: 355 | move.l (a0)+,(a1)+ 356 | dbra d7,restore_falc_pal 357 | 358 | movem.l (sp)+,d0-a6 359 | rts 360 | ; _______ _______ 361 | ; |__ __|__ __| 362 | ; | | | | 363 | ; | | | | 364 | ; | | | | 365 | ; |_| |_| 366 | 367 | restore_video_tt: 368 | 369 | lea save_video,a6 370 | move.w (a6)+,$ffff8262.w 371 | move.l (a6)+,d0 372 | lsr.w #8,d0 373 | move.l d0,$ffff8200.w 374 | 375 | ; Restore palette 376 | move.w #256/2-1,d7 377 | lea old_pal_falcon_tt,a0 378 | lea $ffff8400.w,a1 379 | restore_tt_pal: 380 | move.l (a0)+,(a1)+ 381 | dbra d7,restore_tt_pal 382 | 383 | movem.l (sp)+,d0-a6 384 | 385 | rts 386 | 387 | ; _____ _______ _______ _______ ______ 388 | ; / ____|__ __|/ / ____|__ __| ____| 389 | ; | (___ | | / / (___ | | | |__ 390 | ; \___ \ | | / / \___ \ | | | __| 391 | ; ____) | | |/ / ____) | | | | |____ 392 | ; |_____/ |_/_/ |_____/ |_| |______| 393 | 394 | restore_video_st_ste: 395 | 396 | lea save_video(pc),a6 397 | move.w (a6)+,-(sp) 398 | move.l (a6)+,-(sp) 399 | move.l (a6)+,-(sp) 400 | move.w #5,-(sp) 401 | trap #14 402 | lea 12(sp),sp 403 | 404 | movem.l (sp)+,d0-a6 405 | rts 406 | 407 | ;------------------------------------------------------------------------------- 408 | ; Fades (modifies) a1 into a0 (one notch per call) 409 | ; Why can't I find a cross fade routine on my personal source archive 410 | ; in the year 2020 and have to write one now? I'm so fired 411 | ;------------------------------------------------------------------------------- 412 | 413 | _cross_fade:: .cargs #12*4,.current_palette.l,.target_palette.l 414 | movem.l D0-A2,-(SP) 415 | move.l .current_palette(sp),a1 416 | move.l .target_palette(sp),a0 417 | move.w #15,D7 418 | 419 | fadein2: move.w (A0)+,D0 420 | move.w D0,D1 421 | move.w D1,D2 422 | lsr.w #8,D0 423 | lsr.w #4,D1 424 | and.w #15,D0 425 | and.w #15,D1 426 | and.w #15,D2 427 | move.w (A1),D3 428 | move.b D3,D4 429 | move.b D4,D5 430 | lsr.w #8,D3 431 | lsr.w #4,D4 432 | and.w #15,D3 433 | and.w #15,D4 434 | and.w #15,D5 435 | 436 | move.b _ste_to_index(PC,D0.w),D0 437 | move.b _ste_to_index(PC,D3.w),D3 438 | cmp.b D3,D0 439 | beq.s green 440 | blt.s red_dec 441 | addq.b #1,D3 442 | bra.s green 443 | red_dec: subq.b #1,D3 444 | 445 | green: move.b _ste_to_index(PC,D1.w),D1 446 | move.b _ste_to_index(PC,D4.w),D4 447 | cmp.b D4,D1 448 | beq.s blue 449 | blt.s green_dec 450 | addq.b #1,D4 451 | bra.s blue 452 | green_dec: subq.b #1,D4 453 | 454 | blue: move.b _ste_to_index(PC,D2.w),D2 455 | move.b _ste_to_index(PC,D5.w),D5 456 | cmp.b D5,D2 457 | beq.s combine 458 | blt.s blue_dec 459 | addq.b #1,D5 460 | bra.s combine 461 | blue_dec: subq.b #1,D5 462 | 463 | combine: move.b _index_to_ste(PC,D3.w),D3 464 | move.b _index_to_ste(PC,D4.w),D4 465 | move.b _index_to_ste(PC,D5.w),D5 466 | lsl.w #8,D3 467 | lsl.b #4,D4 468 | add.b D4,D3 469 | add.b D5,D3 470 | move.w D3,(A1)+ 471 | 472 | dbra D7,fadein2 473 | 474 | movem.l (SP)+,D0-A2 475 | rts 476 | 477 | _index_to_ste:: DC.B 0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15 478 | _ste_to_index:: DC.B 0,2,4,6,8,10,12,14,1,3,5,7,9,11,13,15 479 | 480 | ;------------------------------------------------------------------------------- 481 | ; Vertical blank routine 482 | ;------------------------------------------------------------------------------- 483 | _vbl:: movem.l d0-a6,-(sp) 484 | 485 | movem.l _palette_current,d0-d7 486 | movem.l d0-d7,$ffff8240.w 487 | 488 | addq.w #1,_vbl_count 489 | 490 | movem.l (sp)+,d0-a6 491 | 492 | rte 493 | 494 | 495 | -------------------------------------------------------------------------------- /barebones-interop/code/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern void *sample_start; 6 | extern void *sample_end; 7 | extern unsigned int *screen_phys, *screen_log; 8 | extern void cross_fade(unsigned short *current, unsigned short *target); 9 | 10 | 11 | unsigned int old_sp; 12 | unsigned int old_vbl; 13 | unsigned char old_484; 14 | 15 | #define DMA_MONO (1<<7) 16 | #define DMA_STEREO (0<<7) 17 | #define DMA_FREQ_6258 0 18 | #define DMA_FREQ_12517 1 19 | #define DMA_FREQ_25033 2 20 | #define DMA_FREQ_50066 3 21 | #define DMA_LOOP 2 22 | #define DMA_REPLAY_ON 1 23 | 24 | enum 25 | { 26 | STFM = 0, 27 | STE = 1, 28 | MEGASTE = 2, 29 | FALCON = 3, 30 | TT = 4, 31 | CRAP = 5, 32 | STBOOK = 6, 33 | CT6X = 7, 34 | UNKNOWN = 8, 35 | PACIFIST = 10, 36 | TOSBOX = 11, 37 | STEEM = 12, 38 | }; 39 | 40 | extern unsigned short machine_type; 41 | 42 | void play_sample(void *start_address, void *end_address) 43 | { 44 | *(volatile unsigned char *)0xFF8901 = 0; 45 | if (machine_type == STFM) 46 | { 47 | // Poor ST/STF/STFMs get no love here 48 | return; 49 | } 50 | *(volatile unsigned char *)0xFF8903 = (((unsigned int)start_address>> 16)&0xff); 51 | *(volatile unsigned char *)0xFF8905 = (((unsigned int)start_address>> 8)&0xff); 52 | *(volatile unsigned char *)0xFF8907 = (((unsigned int)start_address>> 0)&0xff); 53 | *(volatile unsigned char *)0xFF890f = (((unsigned int)end_address>> 16)&0xff); 54 | *(volatile unsigned char *)0xFF8911 = (((unsigned int)end_address>> 8)&0xff); 55 | *(volatile unsigned char *)0xFF8913 = (((unsigned int)end_address>> 0)&0xff); 56 | *(volatile unsigned char *)0xFF8921 = DMA_MONO|DMA_FREQ_25033; 57 | *(volatile unsigned char *)0xFF8901 = DMA_REPLAY_ON; 58 | } 59 | 60 | extern void vbl(); 61 | unsigned short palette_current[16]; 62 | extern unsigned short old_pal[16]; 63 | extern void detect_machine(); 64 | volatile unsigned short vbl_count = 0; 65 | unsigned short palette_black[16] = { 0 }; 66 | extern unsigned short pic_palette[16]; 67 | extern unsigned char *pic_data[32000]; 68 | extern void restore_video(); 69 | 70 | void wait_for_vblank(void) 71 | { 72 | volatile unsigned short temp_vbl = vbl_count; 73 | while (vbl_count == temp_vbl) 74 | { 75 | } 76 | } 77 | 78 | void swap_screens() 79 | { 80 | if (machine_type != FALCON && machine_type != CT6X) 81 | { 82 | *(int *)0xffff8200 = ((unsigned int)screen_log&0xffff0000) | (((unsigned int)screen_log&0xff00)>> 8); 83 | unsigned int *temp = screen_log; 84 | screen_log = screen_phys; 85 | screen_phys = temp; 86 | wait_for_vblank(); 87 | } 88 | else 89 | { 90 | unsigned int *temp = screen_log; 91 | screen_log = screen_phys; 92 | screen_phys = temp; 93 | wait_for_vblank(); 94 | *(int *)0xffff8200 = ((unsigned int)temp&0xffff0000) | (((unsigned int)temp&0xff00)>> 8); 95 | } 96 | } 97 | 98 | void fade(unsigned short *current, unsigned short *palette_to_fade_to) 99 | { 100 | unsigned short i; 101 | for (i=0;i<16;i++) 102 | { 103 | wait_for_vblank(); 104 | cross_fade(current, palette_to_fade_to); 105 | } 106 | } 107 | 108 | int main() 109 | { 110 | old_sp = Super(0); 111 | 112 | detect_machine(); 113 | 114 | old_vbl = *(unsigned int *)0x70; 115 | *(int *)0x70 = (int)vbl; 116 | old_484 = *(unsigned char *)0x484; 117 | *(char *)0x484 = 0; // Shut up, keyclick 118 | // Gee, thanks gcc 11: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578 119 | #pragma GCC diagnostic push 120 | #pragma GCC diagnostic ignored "-Wstringop-overread" 121 | memcpy(palette_current, (unsigned short *)0xffff8240, 32); 122 | memcpy(old_pal, (unsigned short *)0xffff8240, 32); 123 | #pragma GCC diagnostic pop 124 | 125 | fade(palette_current, palette_black); 126 | memcpy(screen_phys,&pic_data,32000); 127 | memcpy(screen_log,&pic_data,32000); 128 | play_sample(&sample_start, &sample_end); 129 | fade(palette_current, pic_palette); 130 | 131 | volatile unsigned char key=0; 132 | while (key!=57) 133 | { 134 | swap_screens(); 135 | key=*(volatile unsigned char *)0xfffffc02; 136 | } 137 | 138 | fade(palette_current, palette_black); 139 | 140 | *(int *)0x70 = old_vbl; 141 | restore_video(); 142 | 143 | unsigned short i; 144 | for (i=0;i<16;i++) 145 | { 146 | #pragma GCC diagnostic push 147 | #pragma GCC diagnostic ignored "-Wstringop-overflow" 148 | memcpy((unsigned short *)0xffff8240, palette_current, 32); 149 | #pragma GCC diagnostic pop 150 | Vsync(); 151 | cross_fade(palette_current, old_pal); 152 | } 153 | 154 | *(unsigned char *)0x484 = old_484; 155 | Super(old_sp); 156 | Pterm(0); 157 | 158 | } 159 | -------------------------------------------------------------------------------- /barebones-interop/code/replace_libc_mintlib_junk.s: -------------------------------------------------------------------------------- 1 | ;; "Liberated" from gcc sources (libgcc/config/m68k/lb1sf68k.s) 2 | ; 3 | ;__udivsi3: 4 | ;___udivsi3:: 5 | ; move.l d2, -(sp) 6 | ; move.l 12(sp), d1 ; d1 = divisor 7 | ; move.l 8(sp), d0 ; d0 = dividend 8 | ; 9 | ; cmp.l #$10000, d1 ; divisor >= 2 ^ 16 ? 10 | ; bcc L3 ; then try next algorithm 11 | ; move.l d0, d2 12 | ; clr.w d2 13 | ; swap d2 14 | ; divu d1, d2 ; high quotient in lower word 15 | ; move.w d2, d0 ; save high quotient 16 | ; swap d0 17 | ; move.w 10(sp), d2 ; get low dividend + high rest 18 | ; divu d1, d2 ; low quotient 19 | ; move.w d2, d0 20 | ; bra L6 21 | ; 22 | ;L3: move.l d1, d2 ; use d2 as divisor backup 23 | ;L4: lsr.l #1, d1 ; shift divisor 24 | ; lsr.l #1, d0 ; shift dividend 25 | ; cmp.l #$10000, d1 ; still divisor >= 2 ^ 16 ? 26 | ; bcc L4 27 | ; divu d1, d0 ; now we have 16-bit divisor 28 | ; and.l #$ffff, d0 ; mask out divisor, ignore remainder 29 | ; 30 | ;; Multiply the 16-bit tentative quotient with the 32-bit divisor. Because of 31 | ;; the operand ranges, this might give a 33-bit product. If this product is 32 | ;; greater than the dividend, the tentative quotient was too large. 33 | ; move.l d2, d1 34 | ; mulu d0, d1 ; low part, 32 bits 35 | ; swap d2 36 | ; mulu d0, d2 ; high part, at most 17 bits 37 | ; swap d2 ; align high part with low part 38 | ; tst.w d2 ; high part 17 bits? 39 | ; bne L5 ; if 17 bits, quotient was too large 40 | ; add.l d2, d1 ; add parts 41 | ; bcs L5 ; if sum is 33 bits, quotient was too large 42 | ; cmp.l 8(sp), d1 ; compare the sum with the dividend 43 | ; bls L6 ; if sum > dividend, quotient was too large 44 | ;L5: subq.l #1, d0 ; adjust quotient 45 | ; 46 | ;L6: move.l (sp)+, d2 47 | ; rts 48 | 49 | ;// ----------------------------------------------------------------------------- 50 | ;; "Liberated" from gcc sources (libgcc/config/m68k/lb1sf68.S) 51 | ;___umodsi3:: 52 | ;__umodsi3: 53 | ; move.l 8(sp), d1 ; d1 = divisor 54 | ; move.l 4(sp), d0 ; d0 = dividend 55 | ; move.l d1, -(sp) 56 | ; move.l d0, -(sp) 57 | ; bsr __udivsi3 58 | ; addq.l #8, sp 59 | ; move.l 8(sp), d1 ; d1 = divisor 60 | ; move.l d1, -(sp) 61 | ; move.l d0, -(sp) 62 | ; bsr __mulsi3 ; d0 = (a/b)*b 63 | ; addq.l #8, sp 64 | ; move.l 4(sp), d1 ; d1 = dividend 65 | ; sub.l d0, d1 ; d1 = a - (a/b)*b 66 | ; move.l d1, d0 67 | ; rts 68 | 69 | // ----------------------------------------------------------------------------- 70 | ;; "Liberated" from gcc sources (libgcc/config/m68k/lb1sf68.S) 71 | ;___mulsi3:: 72 | ;__mulsi3: 73 | ; move.w 4(sp), d0 ; x0 -> d0 74 | ; mulu 10(sp), d0 ; x0*y1 75 | ; move.w 6(sp), d1 ; x1 -> d1 76 | ; mulu 8(sp), d1 ; x1*y0 77 | ; add.l d1, d0 78 | ; swap d0 79 | ; clr.w d0 80 | ; move.w 6(sp), d1 ; x1 -> d1 81 | ; mulu 10(sp), d1 ; x1*y1 82 | ; add.l d1, d0 83 | ; 84 | ; rts 85 | 86 | ;// ----------------------------------------------------------------------------- 87 | ;; POSIX open() flags like O_RDONLY etc seem to map 1:1 to the GEMDOS call, at least the simple stuff. 88 | ;; So we pass the flags as-is and brace for impact 89 | ;_open:: .cargs #4,.fname.l,.open_flags.l 90 | ; move.w .open_flags+2(sp),-(sp) 91 | ; move.l 2+.fname(sp),-(sp) 92 | ; move.w #$3d,-(sp) 93 | ; trap #1 94 | ; addq.l #8,sp 95 | ; rts 96 | 97 | ;// ----------------------------------------------------------------------------- 98 | ;_read:: .cargs #4,.handle.l,.buf.l,.length.l 99 | ; move.l .buf(sp),-(sp) 100 | ; move.l 4+.length(sp),-(sp) 101 | ; move.w 8+.handle+2(sp),-(sp) 102 | ; move.w #$3F,-(sp) 103 | ; trap #1 104 | ; lea 12(sp),sp 105 | ; rts 106 | 107 | ;// ----------------------------------------------------------------------------- 108 | ;_write:: .cargs #4,.handle.l,.buf.l,.count.l 109 | ; move.l .buf(sp),-(sp) 110 | ; move.l 4+.count(sp),-(sp) 111 | ; move.w 8+.handle+2(sp),-(sp) 112 | ; move.w #$40,-(sp) 113 | ; trap #1 114 | ; lea 12(sp),sp 115 | ; rts 116 | 117 | ;// ----------------------------------------------------------------------------- 118 | ;_close:: .cargs #4,.handle.l 119 | ; move.w .handle+2(sp),-(sp) 120 | ; move.w #$3E,-(sp) 121 | ; trap #1 122 | ; addq.l #4,sp 123 | ; rts 124 | 125 | ;// ----------------------------------------------------------------------------- 126 | ;_lseek:: .cargs #4,.handle.l,.offset.l,.mode.l 127 | ; move.w .mode+2(sp),-(sp) 128 | ; move.w 2+.handle+2(sp),-(sp) 129 | ; move.l 4+.offset(sp),-(sp) 130 | ; move.w #$42,-(sp) 131 | ; trap #1 132 | ; lea 10(sp),sp 133 | ; rts 134 | 135 | ;// ----------------------------------------------------------------------------- 136 | ;_creat:: .cargs #4,.fname.l,.attr.l 137 | ; move.w .attr+2(sp),-(sp) 138 | ; move.l 2+.fname(sp),-(sp) 139 | ; move.w #$3C,-(sp) 140 | ; trap #1 141 | ; addq.l #8,sp 142 | ; rts 143 | 144 | // ----------------------------------------------------------------------------- 145 | _memcpy:: 146 | ; From mintlib (string/bcopy.s) 147 | 148 | ; new version of bcopy, memcpy and memmove 149 | ; handles overlap, odd/even alignment 150 | ; uses movem to copy 256 bytes blocks faster. 151 | ; Alexander Lehmann alexlehm@iti.informatik.th-darmstadt.de 152 | ; sortof inspired by jrbs bcopy 153 | 154 | ; void *memcpy( void *dest, const void *src, size_t len ); 155 | ; void *memmove( void *dest, const void *src, size_t len ); 156 | ; returns dest 157 | ; functions are aliased 158 | 159 | move.l 4(sp),a1 ; dest 160 | move.l 8(sp),a0 ; src 161 | bra common ; the rest is samea as bcopy 162 | 163 | ; void bcopy( const void *src, void *dest, size_t length ); 164 | ; void _bcopy( const void *src, void *dest, unsigned long length ); 165 | ; return value not used (returns src) 166 | ; functions are aliased (except for HSC -- sb) 167 | 168 | _bcopy: 169 | ___bcopy: 170 | __bcopy: 171 | move.l 4(sp),a0 ; src 172 | move.l 8(sp),a1 ; dest 173 | common: move.l 12(sp),d0 ; length 174 | common2: 175 | beq exit ; length==0? (size_t) 176 | 177 | ; a0 src, a1 dest, d0.l length 178 | move.l d2,-(sp) 179 | 180 | ; overlay ? 181 | cmp.l a0,a1 182 | bgt top_down 183 | 184 | move.w a0,d1 ; test for alignment 185 | move.w a1,d2 186 | eor.w d2,d1 187 | btst #0,d1 ; one odd one even ? 188 | bne slow_copy 189 | btst #0,d2 ; both even ? 190 | beq both_even 191 | move.b (a0)+,(a1)+ ; copy one byte, now we are both even 192 | subq.l #1,d0 193 | both_even: 194 | moveq #0,d1 ; save length less 256 195 | move.b d0,d1 196 | lsr.l #8,d0 ; number of 256 bytes blocks 197 | beq less256 198 | movem.l d1/d3-d7/a2/a3/a5/a6,-(sp) ; d2 is already saved 199 | ; exclude a4 because of -mbaserel 200 | copy256: 201 | movem.l (a0)+,d1-d7/a2/a3/a5/a6 ; copy 5*44+36=256 bytes 202 | movem.l d1-d7/a2/a3/a5/a6,(a1) 203 | movem.l (a0)+,d1-d7/a2/a3/a5/a6 204 | movem.l d1-d7/a2/a3/a5/a6,44(a1) 205 | movem.l (a0)+,d1-d7/a2/a3/a5/a6 206 | movem.l d1-d7/a2/a3/a5/a6,88(a1) 207 | movem.l (a0)+,d1-d7/a2/a3/a5/a6 208 | movem.l d1-d7/a2/a3/a5/a6,132(a1) 209 | movem.l (a0)+,d1-d7/a2/a3/a5/a6 210 | movem.l d1-d7/a2/a3/a5/a6,176(a1) 211 | movem.l (a0)+,d1-d7/a2-a3 212 | movem.l d1-d7/a2-a3,220(a1) 213 | lea 256(a1),a1 ; increment dest, src is already 214 | subq.l #1,d0 215 | bne copy256 ; next, please 216 | movem.l (sp)+,d1/d3-d7/a2/a3/a5/a6 217 | less256: ; copy 16 bytes blocks 218 | move.w d1,d0 219 | lsr.w #2,d0 ; number of 4 bytes blocks 220 | beq less4 ; less that 4 bytes left 221 | move.w d0,d2 222 | neg.w d2 223 | andi.w #3,d2 ; d2 = number of bytes below 16 (-n)&3 224 | subq.w #1,d0 225 | lsr.w #2,d0 ; number of 16 bytes blocks minus 1, if d2==0 226 | add.w d2,d2 ; offset in code (move.l two bytes) 227 | jmp 2(pc,d2.w) ; jmp into loop 228 | copy16: 229 | move.l (a0)+,(a1)+ 230 | move.l (a0)+,(a1)+ 231 | move.l (a0)+,(a1)+ 232 | move.l (a0)+,(a1)+ 233 | dbra d0,copy16 234 | less4: 235 | btst #1,d1 236 | beq less2 237 | move.w (a0)+,(a1)+ 238 | less2: 239 | btst #0,d1 240 | beq none 241 | move.b (a0),(a1) 242 | none: 243 | exit_d2: 244 | move.l (sp)+,d2 245 | exit: 246 | move.l 4(sp),d0 ; return dest (for memcpy only) 247 | rts 248 | 249 | slow_copy: ; byte by bytes copy 250 | move.w d0,d1 251 | neg.w d1 252 | andi.w #7,d1 ; d1 = number of bytes blow 8 (-n)&7 253 | addq.l #7,d0 254 | lsr.l #3,d0 ; number of 8 bytes block plus 1, if d1!=0 255 | add.w d1,d1 ; offset in code (move.b two bytes) 256 | jmp 2(pc,d1.w) ; jump into loop 257 | scopy: 258 | move.b (a0)+,(a1)+ 259 | move.b (a0)+,(a1)+ 260 | move.b (a0)+,(a1)+ 261 | move.b (a0)+,(a1)+ 262 | move.b (a0)+,(a1)+ 263 | move.b (a0)+,(a1)+ 264 | move.b (a0)+,(a1)+ 265 | move.b (a0)+,(a1)+ 266 | subq.l #1,d0 267 | bne scopy 268 | bra exit_d2 269 | 270 | top_down: 271 | add.l d0,a0 ; a0 byte after end of src 272 | add.l d0,a1 ; a1 byte after end of dest 273 | 274 | move.w a0,d1 ; exact the same as above, only with predec 275 | move.w a1,d2 276 | eor.w d2,d1 277 | btst #0,d1 278 | bne slow_copy_d 279 | 280 | btst #0,d2 281 | beq both_even_d 282 | move.b -(a0),-(a1) 283 | subq.l #1,d0 284 | both_even_d: 285 | moveq #0,d1 286 | move.b d0,d1 287 | lsr.l #8,d0 288 | beq less256_d 289 | movem.l d1/d3-d7/a2/a3/a5/a6,-(sp) 290 | copy256_d: 291 | movem.l -44(a0),d1-d7/a2/a3/a5/a6 292 | movem.l d1-d7/a2/a3/a5/a6,-(a1) 293 | movem.l -88(a0),d1-d7/a2/a3/a5/a6 294 | movem.l d1-d7/a2/a3/a5/a6,-(a1) 295 | movem.l -132(a0),d1-d7/a2/a3/a5/a6 296 | movem.l d1-d7/a2/a3/a5/a6,-(a1) 297 | movem.l -176(a0),d1-d7/a2/a3/a5/a6 298 | movem.l d1-d7/a2/a3/a5/a6,-(a1) 299 | movem.l -220(a0),d1-d7/a2/a3/a5/a6 300 | movem.l d1-d7/a2/a3/a5/a6,-(a1) 301 | movem.l -256(a0),d1-d7/a2-a3 302 | movem.l d1-d7/a2-a3,-(a1) 303 | lea -256(a0),a0 304 | subq.l #1,d0 305 | bne copy256_d 306 | movem.l (sp)+,d1/d3-d7/a2/a3/a5/a6 307 | less256_d: 308 | move.w d1,d0 309 | lsr.w #2,d0 310 | beq less4_d 311 | move.w d0,d2 312 | neg.w d2 313 | andi.w #3,d2 314 | subq.w #1,d0 315 | lsr.w #2,d0 316 | add.w d2,d2 317 | jmp 2(pc,d2.w) 318 | copy16_d: 319 | move.l -(a0),-(a1) 320 | move.l -(a0),-(a1) 321 | move.l -(a0),-(a1) 322 | move.l -(a0),-(a1) 323 | dbra d0,copy16_d 324 | less4_d: 325 | btst #1,d1 326 | beq less2_d 327 | move.w -(a0),-(a1) 328 | less2_d: 329 | btst #0,d1 330 | beq exit_d2 331 | move.b -(a0),-(a1) 332 | bra exit_d2 333 | slow_copy_d: 334 | move.w d0,d1 335 | neg.w d1 336 | andi.w #7,d1 337 | addq.l #7,d0 338 | lsr.l #3,d0 339 | add.w d1,d1 340 | jmp 2(pc,d1.w) 341 | scopy_d: 342 | move.b -(a0),-(a1) 343 | move.b -(a0),-(a1) 344 | move.b -(a0),-(a1) 345 | move.b -(a0),-(a1) 346 | move.b -(a0),-(a1) 347 | move.b -(a0),-(a1) 348 | move.b -(a0),-(a1) 349 | move.b -(a0),-(a1) 350 | subq.l #1,d0 351 | bne scopy_d 352 | bra exit_d2 353 | 354 | // ----------------------------------------------------------------------------- 355 | _memset:: 356 | ; From mintlib (string/bzero.s) 357 | 358 | ; new version of bcopy and memset 359 | ; uses movem to set 256 bytes blocks faster. 360 | ; Alexander Lehmann alexlehm@iti.informatik.th-darmstadt.de 361 | ; sortof inspired by jrbs bcopy 362 | ; has to be preprocessed (int parameter in memset) 363 | 364 | 365 | ; void *memset( void *dest, int val, size_t len ); 366 | ; returns dest 367 | ; two versions for 16/32 bits 368 | 369 | move.l 4(sp),a0 ; dest 370 | .if 0 ;__MSHORT__ 371 | move.b 9(sp),d0 ; value 372 | move.l 10(sp),d1 ; length 373 | .else 374 | move.b 11(sp),d0 ; value 375 | move.l 12(sp),d1 ; length 376 | .endif 377 | beq memset_exit ; length==0? (size_t) 378 | 379 | ; void bzero( void *dest, size_t length ); 380 | ; void _bzero( void *dest, unsigned long length ); 381 | ; return value not used (returns dest) 382 | 383 | ___bzero: 384 | _bzero: 385 | 386 | do_set: ; a0 dest, d0.b byte, d1.l length 387 | move.l d2,-(sp) 388 | 389 | add.l d1,a0 ; a0 points to end of area, needed for predec 390 | 391 | move.w a0,d2 ; test for alignment 392 | btst #0,d2 ; odd ? 393 | beq areeven 394 | move.b d0,-(a0) ; set one byte, now we are even 395 | subq.l #1,d1 396 | areeven: 397 | move.b d0,d2 398 | lsl.w #8,d0 399 | move.b d2,d0 400 | move.w d0,d2 401 | swap d2 402 | move.w d0,d2 ; d2 has byte now four times 403 | 404 | moveq #0,d0 ; save length less 256 405 | move.b d1,d0 406 | lsr.l #8,d1 ; number of 256 bytes blocks 407 | beq memset_less256 408 | movem.l d0/d3-d7/a2/a3/a5/a6,-(sp) ; d2 is already saved 409 | ; exclude a4 because of -mbaserel 410 | move.l d2,d0 411 | move.l d2,d3 412 | move.l d2,d4 413 | move.l d2,d5 414 | move.l d2,d6 415 | move.l d2,d7 416 | move.l d2,a2 417 | move.l d2,a3 418 | move.l d2,a5 419 | move.l d2,a6 420 | set256: 421 | movem.l d0/d2-d7/a2/a3/a5/a6,-(a0) ; set 5*44+36=256 bytes 422 | movem.l d0/d2-d7/a2/a3/a5/a6,-(a0) 423 | movem.l d0/d2-d7/a2/a3/a5/a6,-(a0) 424 | movem.l d0/d2-d7/a2/a3/a5/a6,-(a0) 425 | movem.l d0/d2-d7/a2/a3/a5/a6,-(a0) 426 | movem.l d0/d2-d7/a2-a3,-(a0) 427 | subq.l #1,d1 428 | bne set256 ; next, please 429 | movem.l (sp)+,d0/d3-d7/a2/a3/a5/a6 430 | memset_less256: ; set 16 bytes blocks 431 | move.w d0,-(sp) ; save length below 256 for last 3 bytes 432 | lsr.w #2,d0 ; number of 4 bytes blocks 433 | beq memset_less4 ; less that 4 bytes left 434 | move.w d0,d1 435 | neg.w d1 436 | andi.w #3,d1 ; d1 = number of bytes below 16 (-n)&3 437 | subq.w #1,d0 438 | lsr.w #2,d0 ; number of 16 bytes blocks minus 1, if d1==0 439 | add.w d1,d1 ; offset in code (move.l two bytes) 440 | jmp 2(pc,d1.w) ; jmp into loop 441 | set16: 442 | move.l d2,-(a0) 443 | move.l d2,-(a0) 444 | move.l d2,-(a0) 445 | move.l d2,-(a0) 446 | dbra d0,set16 447 | memset_less4: 448 | move.w (sp)+,d0 449 | btst #1,d0 450 | beq .less2 451 | move.w d2,-(a0) 452 | .less2: 453 | btst #0,d0 454 | beq .none 455 | move.b d2,-(a0) 456 | .none: 457 | move.l (sp)+,d2 458 | memset_exit: 459 | move.l 4(sp),d0 ; return dest (for memset only) 460 | rts 461 | -------------------------------------------------------------------------------- /barebones-interop/fbuild.bff: -------------------------------------------------------------------------------- 1 | ; 2 | ; Define the compiler locations. 3 | ; This scheme here assumes a relative position for the tools. Alternatively, if it finds 4 | ; "fbuild_toolchain.bff", it'll include that file and take the values from there. 5 | ; Basically that file contains the values from the "else" case below, but modified for each machine. 6 | ; That way you can avoid committing this file and each machine having its own custom settings that 7 | ; won't appear in source control. 8 | #if file_exists("fbuild_toolchain.bff") 9 | #include "fbuild_toolchain.bff" 10 | #else 11 | .GCC_ROOT="toolchains\browncc-14.1" 12 | .GCC_PREFIX="m68k-atarisubliminalbrown-elf" 13 | .GPP='$GCC_ROOT$\bin\$GCC_PREFIX$-g++.exe' 14 | .GCC='$GCC_ROOT$\bin\$GCC_PREFIX$-gcc.exe' 15 | .AS= '$GCC_ROOT$\bin\$GCC_PREFIX$-as.exe' 16 | .RMAC="tools\rmac.exe" 17 | .NCONVERT="tools\nconvert.exe" 18 | .SOX="tools\sox\sox.exe" 19 | #endif 20 | 21 | ; 22 | ; Uncomment these if you want the linker to do LTO 23 | ; or if you like to produce a map file as part of the build 24 | ; 25 | 26 | ;#define LTO 27 | ;#define PRODUCE_MAP_FILE 28 | 29 | ; 30 | ; Compilers/tools definitions. These are used for the "ObjectList"/"Executable"/etc commands below 31 | ; 32 | Compiler ( 'gcc' ) 33 | { 34 | .Executable=.GCC 35 | } 36 | Compiler ( 'rmac' ) 37 | { 38 | .Executable=.RMAC 39 | .CompilerFamily="custom" 40 | } 41 | Compiler ( 'sox' ) 42 | { 43 | .Executable=.SOX 44 | .CompilerFamily="custom" 45 | } 46 | 47 | #import PATH 48 | #import TEMP 49 | Settings 50 | { 51 | .Environment = { "PATH=$GCC_ROOT$\bin;$PATH$", 52 | "TEMP=$TEMP$" 53 | } 54 | } 55 | 56 | ; 57 | ; Some variables defined here to avoid spamming the commands below 58 | ; 59 | .CFLAGS='' 60 | +' -I.' 61 | ;+' -mshort' 62 | +' -DPLATFORM_ATARI_ST' 63 | 64 | .CODEGEN_FLAGS='' 65 | +' -g' 66 | +' -m68000' 67 | +' -Os' 68 | +' -fomit-frame-pointer' 69 | +' -fstrict-aliasing' 70 | +' -fcaller-saves' 71 | +' -ffunction-sections' 72 | +' -fdata-sections' 73 | +' -fleading-underscore' 74 | #if LTO 75 | + ' -flto' 76 | #endif 77 | 78 | ; 79 | ; File lists, these are used by ObjecList commands below 80 | ; 81 | .C_SRC= 82 | { 83 | "code/main.c", 84 | } 85 | 86 | .ASM_SRC= 87 | { 88 | "code/code.s", 89 | "code/replace_libc_mintlib_junk.s" 90 | } 91 | 92 | .SFX_LIST= 93 | { 94 | "assets\254056__jagadamba__space-sound.wav", 95 | } 96 | 97 | ; 98 | ; ObjectList commands take a source folder or a file list and transform it into output files 99 | ; depending on what the "compiler" is set to. So it can compile files, assemble files 100 | ; or just do sound/graphics conversion. 101 | ; 102 | 103 | ObjectList( 'c_obj' ) 104 | { 105 | .Compiler='gcc' 106 | .CompilerOptions='$CFLAGS$ $CODEGEN_FLAGS$ -c %1 -o %2' 107 | .CompilerOutputPath='obj' 108 | .CompilerOutputExtension='.o' 109 | .CompilerInputFiles=.C_SRC 110 | } 111 | 112 | ObjectList( 'convert_sfx_to_native' ) 113 | { 114 | .Compiler='sox' 115 | .CompilerOptions='%1 --bits 8 --no-dither --channels 1 %2 rate -v -I 25033' 116 | .CompilerInputFiles=.SFX_LIST 117 | .CompilerOutputPath='obj' 118 | .CompilerOutputExtension='.raw' 119 | } 120 | 121 | Exec ( 'convert_graphics' ) 122 | { 123 | .ExecExecutable=.NCONVERT 124 | .ExecOutput='obj/pic.pi1' 125 | .ExecArguments='-overwrite -colors 16 -out degas -o obj\%.pi1 %1' 126 | .ExecInputPath="assets" 127 | .ExecInputPattern="*.png" 128 | } 129 | 130 | ObjectList( 'asm_obj' ) 131 | { 132 | .Compiler='rmac' 133 | .CompilerOptions='-fe -o %2 %1' 134 | .CompilerOutputPath='obj' 135 | .CompilerOutputExtension='.o' 136 | .CompilerInputFiles=.ASM_SRC 137 | .PreBuildDependencies={'convert_sfx_to_native','convert_graphics'} 138 | } 139 | 140 | ; 141 | ; This is a call to the linker for the ELF executable 142 | ; 143 | 144 | Executable( 'game' ) 145 | { 146 | .Linker="$GCC$" 147 | .Libraries={ "c_obj", "asm_obj" } 148 | .LinkerLinkObjects=true 149 | .LinkerOutput='test.elf' 150 | .LinkerOptions='' 151 | +' %1 -o %2' 152 | +' -m68000' 153 | +' -Wl,--emit-relocs' 154 | +' -Wl,-e_start' 155 | +' -Ttext=0' 156 | +' $CODEGEN_FLAGS$' 157 | #if PRODUCE_MAP_FILE 158 | +' -Wl,-Map,test.map' 159 | #endif 160 | +' -nostdlib -nostartfiles' 161 | #if LTO 162 | + ' -flto' 163 | #endif 164 | } 165 | 166 | ; 167 | ; And then we have to do some post-build work to convert the ELF binary to Atari TOS PRG 168 | ; 169 | 170 | Exec ( 'brown' ) 171 | { 172 | .ExecExecutable='$GCC_ROOT$\bin\brownout.exe' 173 | .ExecInput='test.elf' 174 | .ExecOutput='test.prg' 175 | .ExecArguments='-s -x -p 0 -i %1 -o %2' 176 | } 177 | 178 | Exec ( 'emit_assembly') 179 | { 180 | .ExecExecutable='$GCC_ROOT$\bin\$GCC_PREFIX$-objdump.exe' 181 | .ExecInput='test.elf' 182 | .ExecOutput='test.s' 183 | .ExecArguments='-S %1' 184 | .ExecUseStdOutAsOutput = true; 185 | } 186 | 187 | ; 188 | ; The alias to "all" target (which is default). This will convert assets, build code, linke everything, etc 189 | ; 190 | 191 | Alias( 'all' ) { .Targets = { 'brown' } } 192 | -------------------------------------------------------------------------------- /barebones-interop/obj/254056__jagadamba__space-sound.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/barebones-interop/obj/254056__jagadamba__space-sound.raw -------------------------------------------------------------------------------- /barebones-interop/readme.md: -------------------------------------------------------------------------------- 1 | # Minimal example for interoperation between C and assembly 2 | 3 | This is a small example that demonstrates how one can mix C and assembly language with the gcc toolchain. It uses no library calls, and the little libc functions needed are provided as assembly replacements. 4 | 5 | The sample program does the following: 6 | 7 | - Detects type of ST machine (ST/STE/Falcon/etc) 8 | - Saves video 9 | - Sets up video 10 | - Fades a picture in 11 | - Plays a PCM sample (on STE/Falcon/TT) 12 | - Waits for a keypress 13 | - Fades out the colours 14 | - Restores video 15 | - Exits to the desktop 16 | 17 | # How to build 18 | 19 | The following items are required: 20 | 21 | - A working gcc-elf 22 | - Brownout (https://github.com/ggnkua/brownout-git / https://bitbucket.org/ggnkua/brownout-git/) 23 | - Fastbuild (https://www.fastbuild.org/docs/download.html) 24 | - rmac (http://rmac.is-slick.com/download/download/) 25 | - ncovnert (https://www.xnview.com/en/nconvert/) 26 | - sox (http://sox.sourceforge.net) 27 | 28 | The above tools are portable, so they can be all exist inside a single folder (or, if you prefer, a single directory tree). Everything is cross platform, so they should work fine under Windows, Linux and MacOS at least. 29 | 30 | Open ```fbuild.bff``` and edit the paths to each tool. The default locations expected for tools are under a ```tools``` folder inside this directory, and the gcc under ```toolchains``` 31 | 32 | Then, type ```fbuild``` in a console from within the directory this readme exists to build the example. ```test.prg``` should appear in the same directory. 33 | 34 | (If things don't work, try ```fbuild -showcmds -j1``` to try to diagnose the problem) 35 | 36 | -------------------------------------------------------------------------------- /barebones/Makefile: -------------------------------------------------------------------------------- 1 | 2 | VASM = ./vasmm68k_mot.exe -Felf -showcrit -noesc 3 | TOOLCHAIN_NAME = m68k-atarisubliminalbrown-elf 4 | TOOLCHAIN_PREFIX = $(TOOLCHAIN_NAME)- 5 | TOOLCHAIN_VERSION = 14.1.0 6 | 7 | # ----------------------------------------------------------------------------- 8 | 9 | # ============================================================================= 10 | # Use minimal/barebones CRT & library code (i.e. avoiding MiNTlib) 11 | # ============================================================================= 12 | LINK_MINIMAL=yes 13 | # ----------------------------------------------------------------------------- 14 | 15 | # ============================================================================= 16 | # debug = Prevent optimization & add debug info 17 | # testing = Optimize but retain symbols 18 | # release = Optimize, strip 19 | # ============================================================================= 20 | USE_CFG=release 21 | # ----------------------------------------------------------------------------- 22 | 23 | 24 | # ============================================================================= 25 | # Some standard C/ASM config - probably won't need changed too often 26 | # ============================================================================= 27 | 28 | TARGETFLAGS = -m68000 29 | 30 | LIBPATHS = \ 31 | -L/home/ggn/brown/lib/gcc/$(TOOLCHAIN_NAME)/$(TOOLCHAIN_VERSION)/m68000 32 | 33 | LIBS = -lc 34 | 35 | INCPATHS = \ 36 | 37 | LIBCXX = libcxx 38 | 39 | # ----------------------------------------------------------------------------- 40 | # With LINK_MINIMAL, we modify the linker command to use minimal LIBC 41 | # ----------------------------------------------------------------------------- 42 | ifeq ($(LINK_MINIMAL),yes) 43 | # ----------------------------------------------------------------------------- 44 | 45 | CRTSEQ_S = \ 46 | $(LIBCXX)/brownboot.o \ 47 | $(LIBCXX)/browncrti.o \ 48 | $(LIBCXX)/browncrt++.o \ 49 | $(LIBCXX)/zerolibc.o \ 50 | $(LIBCXX)/zerocrtfini.o 51 | CRTSEQ_E = \ 52 | $(LIBCXX)/browncrtn.o 53 | 54 | # GCC6/ELF also needs to generate code with base address = 0 for postprocessing 55 | LDOPTS = -Wl,--emit-relocs -Wl,-e_start -Ttext=0 -nostdlib -nostartfiles 56 | 57 | # ----------------------------------------------------------------------------- 58 | 59 | # ----------------------------------------------------------------------------- 60 | else 61 | # ----------------------------------------------------------------------------- 62 | 63 | # GCC6/ELF linking for MiNTlib & C++ is complicated by changes to ctor/dtor 64 | # list representation, code required to implement them and having to specify 65 | # all of the link pieces manually. 66 | 67 | # crt0: 68 | # gcc-provided entrypoint/boot code 69 | # 70 | # browncrti: 71 | # marks beginning of BrownElf .init_array/.fini_array - must be linked early 72 | # browncrtn: 73 | # marks end of BrownElf .init_array/.fini_array - must be linked last 74 | # brownmint++: 75 | # when combining MiNTlib with C++ using BrownElf, crtinit.c must be replaced with one 76 | # which performs the necessary ELF-style static initialisation because MiNTlib 77 | # doesn't do this and GCC6 doesn't quietly inject static inits before main() as 78 | # GCC4 does 79 | # browncrt++: 80 | # implements BrownElf-specific C++ .init_array/.fini_array procedures 81 | # 82 | # zerocrtfini: 83 | # implements __cxa_atexit/__cxa_finalize needed by C++ static init. missing 84 | # from MiNTlib and reused for bare-bones builds on both compilers. 85 | 86 | CRTSEQ_G = /brown/$(TOOLCHAIN_NAME)/lib/crt0.o 87 | CRTSEQ_S = \ 88 | $(LIBCXX)/browncrti.o \ 89 | $(LIBCXX)/browncrt++.o \ 90 | $(LIBCXX)/brownmint++.o \ 91 | $(LIBCXX)/zerocrtfini.o 92 | CRTSEQ_E = \ 93 | $(LIBCXX)/browncrtn.o 94 | 95 | LDOPTS = -Wl,--gc-sections -Wl,--emit-relocs -Wl,-e__start -Ttext=0 -nostdlib -nostartfiles 96 | LIBS = -lgcc -lc 97 | 98 | # ----------------------------------------------------------------------------- 99 | endif 100 | # ----------------------------------------------------------------------------- 101 | 102 | CC = $(TOOLCHAIN_PREFIX)gcc 103 | CXX = $(TOOLCHAIN_PREFIX)g++ 104 | AR = $(TOOLCHAIN_PREFIX)ar 105 | AS = $(TOOLCHAIN_PREFIX)as 106 | NM = $(TOOLCHAIN_PREFIX)nm 107 | LINK = $(TOOLCHAIN_PREFIX)g++ 108 | STRIP = $(TOOLCHAIN_PREFIX)strip 109 | STACK = $(TOOLCHAIN_PREFIX)stack 110 | FLAGS = $(TOOLCHAIN_PREFIX)flags 111 | 112 | STACKSIZE = 16384 113 | 114 | 115 | # ============================================================================= 116 | # Projects start here! 117 | # ============================================================================= 118 | 119 | 120 | COMPILERDEFS += \ 121 | -D__ATARI__ -D__M68000__ \ 122 | -DELF_CONFIG_STACK=$(STACKSIZE) \ 123 | 124 | 125 | # ----------------------------------------------------------------------------- 126 | # C Code generation 127 | # ----------------------------------------------------------------------------- 128 | 129 | ifeq ($(USE_CFG),debug) 130 | 131 | CODEOPTFLAGS = $(TARGETFLAGS) -g -O0 132 | CODEGENFLAGS = $(CODEOPTFLAGS) 133 | 134 | else 135 | 136 | CODEOPTFLAGS = $(TARGETFLAGS) -Ofast -fomit-frame-pointer -fstrict-aliasing 137 | CODEGENFLAGS = $(CODEOPTFLAGS) -fcaller-saves -flto -ffunction-sections -fdata-sections 138 | 139 | endif 140 | 141 | CODEGENFLAGS += -fleading-underscore 142 | 143 | CFLAGS = $(CODEGENFLAGS) $(COMPILERDEFS) $(INCPATHS) -Wall 144 | CXXFLAGS = $(CODEGENFLAGS) $(COMPILERDEFS) $(INCPATHS) -x c++ -std=c++0x -fno-exceptions -fno-rtti -fno-threadsafe-statics -Wall -Wno-reorder 145 | 146 | LDFLAGS = -Wl,-Map,$*.map $(LDOPTS) $(CODEGENFLAGS) 147 | 148 | # ----------------------------------------------------------------------------- 149 | # Common objects for the examples 150 | # ----------------------------------------------------------------------------- 151 | 152 | OBJECTS_O = \ 153 | vsnprint.o \ 154 | printf.o \ 155 | 156 | # ============================================================================= 157 | # Targets to be built 158 | # ============================================================================= 159 | 160 | # rule to build programs 161 | 162 | all: example1 example2 example3 163 | 164 | # individual programs... 165 | 166 | example1: $(OBJECTS_O) lolworld.elf 167 | example2: $(OBJECTS_O) ctest.elf 168 | example3: $(OBJECTS_O) cpptest.elf 169 | 170 | # in case we are building the startup objects, don't autodelete after building 171 | .PRECIOUS: $(CRTSEQ_S) $(CRTSEQ_E) 172 | 173 | # ============================================================================= 174 | # Rule to clean projects 175 | # ============================================================================= 176 | 177 | clean: 178 | -rm -f *.elf 179 | -rm -f *.tos 180 | -rm -f $(OBJECTS_O) 181 | -rm -rf *.o 182 | -rm -rf *.lst 183 | -rm -rf libcxx/*.o 184 | 185 | 186 | # ============================================================================= 187 | # Rule build a single program (demo!) 188 | # ============================================================================= 189 | %.elf: $(CRTSEQ_G) $(CRTSEQ_S) $(OBJECTS_O) %.o $(CRTSEQ_E) | Makefile 190 | $(LINK) $(LIBPATHS) -o $*.elf $(CRTSEQ_G) $(CRTSEQ_S) $(OBJECTS_O) $*.o $(LDFLAGS) $(LIBS) $(CRTSEQ_E) 191 | # ----------------------------------------------------------------------------- 192 | # Strip symbols & pack executable 193 | # ----------------------------------------------------------------------------- 194 | ifeq ($(USE_CFG),release) 195 | # ----------------------------------------------------------------------------- 196 | brownout.exe -p 0 -i $*.elf -o $*.tos 197 | # ----------------------------------------------------------------------------- 198 | else 199 | # ----------------------------------------------------------------------------- 200 | $(TOOLCHAIN_PREFIX)objdump -h $*.elf 201 | brownout.exe -s -x -p 0 -i $*.elf -o $*.tos 202 | # ----------------------------------------------------------------------------- 203 | endif 204 | # ----------------------------------------------------------------------------- 205 | cp $*.tos auto/$*.prg 206 | 207 | # ============================================================================= 208 | # to use MiNTLib with GCC6 static initialisation (for c++) we need to inject 209 | # a custom version of crtinit.c which calls __libc_csu_init(). 210 | # The compile flags are very specific and the MiNTLib source includes are not 211 | # installed with the compiler so we have copies. 212 | # ----------------------------------------------------------------------------- 213 | # note: alternative LIBC packages may require the same type of modification if 214 | # they don't already call __libc_csu_init() 215 | # ----------------------------------------------------------------------------- 216 | # todo: ship this as a precompiled object! 217 | # ============================================================================= 218 | 219 | $(LIBCXX)/brownmint++.o: $(LIBCXX)/brownmint++.c 220 | $(TOOLCHAIN_PREFIX)gcc -Wall -m68000 -O2 -std=gnu89 -fleading-underscore -nostdinc \ 221 | -I$(LIBCXX) \ 222 | -I/usr/lib/gcc/$(TOOLCHAIN_NAME)/$(TOOLCHAIN_VERSION)/include \ 223 | -I/usr/lib/gcc/$(TOOLCHAIN_NAME)/$(TOOLCHAIN_VERSION)/include-fixed \ 224 | -I/usr/$(TOOLCHAIN_NAME)/include \ 225 | -DHAVE_CONFIG_H -D_LIBC -D_REENTRANT \ 226 | -c $< -o $@ 227 | 228 | 229 | # ============================================================================= 230 | # Build rules for source files 231 | # ============================================================================= 232 | 233 | # rule to compile C files 234 | %.o: %.c 235 | $(CC) -c $(CFLAGS) -o $@ $< 236 | 237 | # rule to compile C++ files 238 | %.o: %.cpp 239 | $(CXX) -c $(CXXFLAGS) -o $@ $< 240 | 241 | # rules to assemble .gas files -> .o 242 | %.o: %.gas 243 | $(AS) -o $@ $< 244 | 245 | 246 | # rules to assemble unspecified .s files -> .o 247 | %.o: %.s 248 | ifeq ($(USE_CFG),debug) 249 | $(VASM) $(COMPILERDEFS) -L $@.lst -o $@ $< 250 | else 251 | $(VASM) $(COMPILERDEFS) -o $@ $< 252 | endif 253 | 254 | -------------------------------------------------------------------------------- /barebones/auto/dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/barebones/auto/dummy -------------------------------------------------------------------------------- /barebones/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | setlocal 4 | 5 | set PROJROOT=. 6 | set PROJNAME1=lolworld 7 | set PROJNAME2=cpptest 8 | set PROJNAME3=ctest 9 | set OUTPUT_FOLDER=auto 10 | 11 | set GCCPATH=c:\msys64\brown 12 | set GPP=%GCCPATH%\bin\m68k-atariturbobrowner-elf-g++ 13 | set GCC=%GCCPATH%\bin\m68k-atariturbobrowner-elf-gcc 14 | set COMMONFLAGS=-c -m68000 -Ofast -fomit-frame-pointer -fstrict-aliasing -fcaller-saves -flto -ffunction-sections -fdata-sections -fleading-underscore -D__ATARI__ -D__M68000__ -DELF_CONFIG_STACK=16384 -Wall 15 | set CPPFLAGS=%COMMONFLAGS% -x c++ -std=c++0x -fno-exceptions -fno-rtti -fno-threadsafe-statics -Wno-reorder 16 | set CFLAGS=%COMMONFLAGS% 17 | set INCPATH=-I%GCCPATH%\include 18 | 19 | set PATH=%PATH%;%GCCPATH%\bin 20 | 21 | set CPPFILES=^ 22 | lolworld ^ 23 | cpptest 24 | 25 | set CFILES=^ 26 | vsnprint ^ 27 | printf ^ 28 | ctest 29 | 30 | set ASMFILES= 31 | 32 | set GASFILES= 33 | 34 | SETLOCAL EnableDelayedExpansion 35 | for %%I in (%CPPFILES% %CFILES% %ASMFILES% %GASFILES%) do set objfiles=!objfiles! obj\%%I.o 36 | rem echo %objfiles% 37 | 38 | if /I "%1"=="clean" goto :cleanup 39 | 40 | del %OUTPUT_FOLDER%\%PROJNAME1%.o 2>NUL 41 | del %OUTPUT_FOLDER%\%PROJNAME2%.o 2>NUL 42 | del %OUTPUT_FOLDER%\%PROJNAME3%.o 2>NUL 43 | 44 | rem Compile cpp files 45 | for %%I in (%CPPFILES%) do call :checkrun "obj\%%I.o" "%%I.cpp" "%GPP% %CPPFLAGS% %INCPATH% -o obj\%%I.o %%I.cpp" 46 | 47 | rem Compile c files 48 | for %%I in (%CFILES%) do call :checkrun "obj\%%I.o" "%%I.c" "%GCC% %CFLAGS% %INCPATH% -o obj\%%I.o %%I.c" 49 | 50 | rem Assemble .s files 51 | for %%I in (%ASMFILES%) do call :checkrun "obj\%%I.o" "%%I.s" "%ASM% %ASMFLAGS% -L obj\%%I.o.lst -o obj\%%I.o %%I.s" 52 | for %%I in (%GASFILES%) do call :checkrun "obj\%%I.o" "%%I.gas" "%GCCPATH%\bin\m68k-atariturbobrowner-elf-as -o obj\%%I.o %%I.gas" 53 | 54 | rem Link 55 | del %OUTPUT_FOLDER%\%PROJNAME%.tos 2>NUL 56 | 57 | %GPP% -o lolworld.elf libcxx/brownboot.o libcxx/browncrti.o libcxx/browncrt++.o libcxx/zerolibc.o libcxx/zerocrtfini.o obj/vsnprint.o obj/printf.o obj/lolworld.o -Wl,-Map,lolworld.map -Wl,--emit-relocs -Wl,-e_start -Ttext=0 -nostdlib -nostartfiles -m68000 -Ofast -fomit-frame-pointer -fstrict-aliasing -fcaller-saves -flto -ffunction-sections -fdata-sections -fleading-underscore libcxx/browncrtn.o 58 | if errorlevel 1 exit /b 59 | 60 | %GPP% -o ctest.elf libcxx/brownboot.o libcxx/browncrti.o libcxx/browncrt++.o libcxx/zerolibc.o libcxx/zerocrtfini.o obj/vsnprint.o obj/printf.o obj/ctest.o -Wl,-Map,ctest.map -Wl,--emit-relocs -Wl,-e_start -Ttext=0 -nostdlib -nostartfiles -m68000 -Ofast -fomit-frame-pointer -fstrict-aliasing -fcaller-saves -flto -ffunction-sections -fdata-sections -fleading-underscore libcxx/browncrtn.o 61 | if errorlevel 1 exit /b 62 | 63 | %GPP% -o cpptest.elf libcxx/brownboot.o libcxx/browncrti.o libcxx/browncrt++.o libcxx/zerolibc.o libcxx/zerocrtfini.o obj/vsnprint.o obj/printf.o obj/cpptest.o -Wl,-Map,cpptest.map -Wl,--emit-relocs -Wl,-e_start -Ttext=0 -nostdlib -nostartfiles -m68000 -Ofast -fomit-frame-pointer -fstrict-aliasing -fcaller-saves -flto -ffunction-sections -fdata-sections -fleading-underscore libcxx/browncrtn.o 64 | if errorlevel 1 exit /b 65 | 66 | rem brown up the elf 67 | brownout -p 0 -i %PROJNAME1%.elf -o %OUTPUT_FOLDER%\%PROJNAME1%.tos 68 | brownout -p 0 -i %PROJNAME2%.elf -o %OUTPUT_FOLDER%\%PROJNAME2%.tos 69 | brownout -p 0 -i %PROJNAME3%.elf -o %OUTPUT_FOLDER%\%PROJNAME3%.tos 70 | 71 | exit /b 72 | 73 | rem Cleanup files 74 | 75 | :cleanup 76 | 77 | for %%I in (%objfiles%) do del /q %%I %%I.lst 2>NUL 78 | del obj\%PROJNAME1%.o 2>NUL 79 | del %OUTPUT_FOLDER%\%PROJNAME1%.tos 2>NUL 80 | del obj\%PROJNAME2%.o 2>NUL 81 | del %OUTPUT_FOLDER%\%PROJNAME2%.tos 2>NUL 82 | del obj\%PROJNAME3%.o 2>NUL 83 | del %OUTPUT_FOLDER%\%PROJNAME3%.tos 2>NUL 84 | 85 | exit /b 86 | 87 | rem checkrun 88 | rem will only execute when either 89 | rem doesn't exist or is older than 90 | :checkrun 91 | if not exist %1 goto run 92 | for /F %%i IN ('dir /b /OD %1 %2 ^| more +1') DO SET NEWEST=%%i 93 | if "%NEWEST%"==%2 GOTO run 94 | 95 | echo File %1 is up to date 96 | 97 | exit /b 98 | 99 | :run 100 | echo %~3 101 | %~3 102 | 103 | exit /b 104 | 105 | -------------------------------------------------------------------------------- /barebones/cpptest.cpp: -------------------------------------------------------------------------------- 1 | //====================================================================================================================== 2 | // BrownELF GCC example: C++ startup/shutdown tests 3 | //====================================================================================================================== 4 | 5 | //---------------------------------------------------------------------------------------------------------------------- 6 | 7 | // --------------------------------------------------------------------------------------------------------------------- 8 | // system headers 9 | 10 | #include 11 | #include 12 | #include // for atexit() 13 | #include // for printf va_args etc. 14 | 15 | // custom printf which can be redirected anywhere 16 | extern "C" int debug_printf(const char *pFormat, ...); 17 | 18 | // force GCC to keep functions that look like they might be dead-stripped due to non-use 19 | #define USED __attribute__((used)) 20 | 21 | // ===================================================================================================================== 22 | // Some tests for C++ constructor/destructor & atexit() sequencing 23 | // ===================================================================================================================== 24 | 25 | USED void preinit_test(int argc, char **argv, char **envp) 26 | { 27 | debug_printf("%s\n", __FUNCTION__); 28 | } 29 | 30 | USED void init_test(int argc, char **argv, char **envp) 31 | { 32 | debug_printf("%s\n", __FUNCTION__); 33 | } 34 | 35 | USED void fini_test() 36 | { 37 | debug_printf("%s\n", __FUNCTION__); 38 | } 39 | 40 | // push above functions directly onto C++ init/fini lists 41 | USED __attribute__((section(".init_array"))) __attribute__((used)) void *__init = (void *)&init_test; 42 | USED __attribute__((section(".preinit_array"))) __attribute__((used)) void *__preinit = (void *)&preinit_test; 43 | USED __attribute__((section(".fini_array"))) __attribute__((used)) void *__fini = (void *)&fini_test; 44 | 45 | 46 | // alternate method: apply ctor/dtor attributes directly to functions 47 | void __attribute__ ((constructor)) constructor_attribute() 48 | { 49 | debug_printf("%s\n", __FUNCTION__); 50 | } 51 | 52 | void __attribute__ ((destructor)) destructor_attribute() 53 | { 54 | debug_printf("%s\n", __FUNCTION__); 55 | } 56 | 57 | // tests for atexit() 58 | void my_atexit() 59 | { 60 | debug_printf("%s\n", __FUNCTION__); 61 | } 62 | 63 | void my_atexit2() 64 | { 65 | debug_printf("%s\n", __FUNCTION__); 66 | } 67 | 68 | // static global class instance to test for ctor/dtor sequencing on exit() or return from main() 69 | class cppclass 70 | { 71 | public: 72 | 73 | cppclass() 74 | { 75 | debug_printf("%s\n", __FUNCTION__); 76 | } 77 | 78 | ~cppclass() 79 | { 80 | debug_printf("%s\n", __FUNCTION__); 81 | } 82 | }; 83 | 84 | cppclass cppclass_instance; 85 | 86 | // ===================================================================================================================== 87 | // program entrypoint 88 | // ===================================================================================================================== 89 | 90 | int main(int argc, char ** argv) 91 | { 92 | atexit(my_atexit); 93 | atexit(my_atexit2); 94 | 95 | debug_printf("C++ test: ready...\n"); 96 | 97 | Crawcin(); 98 | 99 | return 0; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /barebones/ctest.c: -------------------------------------------------------------------------------- 1 | //====================================================================================================================== 2 | // BrownELF GCC example: C++ startup/shutdown tests 3 | //====================================================================================================================== 4 | 5 | //---------------------------------------------------------------------------------------------------------------------- 6 | 7 | // --------------------------------------------------------------------------------------------------------------------- 8 | // system headers 9 | 10 | #include 11 | #include 12 | #include // for atexit() 13 | #include // for printf va_args etc. 14 | 15 | // custom printf which can be redirected anywhere 16 | extern int debug_printf(const char *pFormat, ...); 17 | 18 | // force GCC to keep functions that look like they might be dead-stripped due to non-use 19 | #define USED __attribute__((used)) 20 | 21 | // ===================================================================================================================== 22 | // Some tests for atexit() sequencing 23 | // ===================================================================================================================== 24 | 25 | void my_atexit() 26 | { 27 | debug_printf("%s\n", __FUNCTION__); 28 | } 29 | 30 | void my_atexit2() 31 | { 32 | debug_printf("%s\n", __FUNCTION__); 33 | } 34 | 35 | // ===================================================================================================================== 36 | // program entrypoint 37 | // ===================================================================================================================== 38 | 39 | int main(int argc, char ** argv) 40 | { 41 | atexit(my_atexit); 42 | atexit(my_atexit2); 43 | 44 | debug_printf("C test: ready...\n"); 45 | 46 | Crawcin(); 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /barebones/libcxx/brownboot.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/barebones/libcxx/brownboot.o -------------------------------------------------------------------------------- /barebones/libcxx/brownboot.s: -------------------------------------------------------------------------------- 1 | *------------------------------------------------------------------------------* 2 | * BrownELF GCC startup: dml/2017 3 | *------------------------------------------------------------------------------* 4 | 5 | xdef ___cxa_pure_virtual 6 | xdef __ZSt17__throw_bad_allocv 7 | 8 | xdef _memcpy 9 | xdef _memset 10 | 11 | xref _main 12 | xref _exit 13 | xdef __exit 14 | xdef ___cxa_guard_acquire 15 | xdef ___cxa_guard_release 16 | 17 | xref ___libc_csu_init 18 | 19 | *------------------------------------------------------------------------------* 20 | 21 | BASEPAGE_SIZE = $100 22 | USPS = $100*4 23 | 24 | ifd ELF_CONFIG_STACK 25 | SSPS = (ELF_CONFIG_STACK) 26 | else 27 | SSPS = $4000 28 | endc 29 | 30 | bbreak macro 31 | andi #~2,ccr 32 | bvc.s * 33 | endm 34 | 35 | *------------------------------------------------------------------------------* 36 | __crt_entrypoint: xdef __crt_entrypoint 37 | _start: xdef _start 38 | *------------------------------------------------------------------------------* 39 | move.l 4(sp),a5 40 | *-------------------------------------------------------* 41 | * command info 42 | *-------------------------------------------------------* 43 | ; lea 128(a5),a4 44 | ; move.l a4,cli 45 | *-------------------------------------------------------* 46 | * Mshrink 47 | *-------------------------------------------------------* 48 | move.l 12(a5),d0 ; text segment 49 | add.l 20(a5),d0 ; data segment 50 | add.l 28(a5),d0 ; bss segment 51 | add.l #BASEPAGE_SIZE+USPS,d0 ; base page 52 | *-------------------------------------------------------* 53 | move.l a5,d1 ; address to basepage 54 | add.l d0,d1 ; end of program 55 | and.w #-16,d1 ; align stack 56 | move.l sp,d2 57 | move.l d1,sp ; temporary USP stackspace 58 | move.l d2,-(sp) 59 | *-------------------------------------------------------* 60 | move.l d0,-(sp) 61 | move.l a5,-(sp) 62 | clr.w -(sp) 63 | move.w #$4a,-(sp) 64 | trap #1 ; Mshrink 65 | lea 12(sp),sp 66 | *-------------------------------------------------------* 67 | * Program 68 | *-------------------------------------------------------* 69 | bsr user_start 70 | *-------------------------------------------------------* 71 | * Begone 72 | *-------------------------------------------------------* 73 | clr.w -(sp) ; Pterm0 74 | trap #1 75 | 76 | user_start: 77 | 78 | ; clear bss segment 79 | 80 | move.l $18(a5),a0 81 | move.l $1c(a5),d0 ;length of bss segment 82 | move.l d0,-(sp) 83 | pea 0.w 84 | move.l a0,-(sp) 85 | jsr _memset 86 | lea 12(sp),sp 87 | 88 | ; if (REDIRECT_OUTPUT_TO_SERIAL==1) 89 | ; ; redirect to serial 90 | ; 91 | ; move.w #2,-(sp) 92 | ; move.w #1,-(sp) 93 | ; move.w #$46,-(sp) 94 | ; trap #1 95 | ; addq.l #6,sp 96 | ; 97 | ; endif 98 | 99 | pea super_start 100 | move.w #38,-(sp) 101 | trap #14 102 | addq.l #6,sp 103 | 104 | rts 105 | 106 | ; -------------------------------------------------------------- 107 | super_start: 108 | ; -------------------------------------------------------------- 109 | lea new_ssp,a0 110 | move.l a0,d0 111 | subq.l #4,d0 112 | and.w #-16,d0 113 | move.l d0,a0 114 | move.l sp,-(a0) 115 | move.l usp,a1 116 | move.l a1,-(a0) 117 | move.l a0,sp 118 | 119 | ; __libc_csu_init(int argc, char **argv, char **envp); 120 | 121 | move.l #0,-(sp) 122 | pea dummy_argv 123 | pea dummy_envp 124 | jsr ___libc_csu_init 125 | lea 12(sp),sp 126 | 127 | move.l sp,entrypoint_ssp 128 | 129 | jsr _main 130 | 131 | ; link to high level exit(0) function on return 132 | pea 0.w 133 | jmp _exit 134 | 135 | __exit: 136 | 137 | ; level SSP, because exit() is a subroutine 138 | 139 | move.l entrypoint_ssp,sp 140 | 141 | move.l (sp)+,a0 142 | move.l a0,usp 143 | move.l (sp)+,sp 144 | rts 145 | 146 | ; -------------------------------------------------------------- 147 | _memcpy: 148 | ; -------------------------------------------------------------- 149 | rsreset 150 | ; -------------------------------------------------------------- 151 | .sp_return: rs.l 1 152 | .sp_pdst: rs.l 1 153 | .sp_psrc: rs.l 1 154 | .sp_size: rs.l 1 155 | ; -------------------------------------------------------------- 156 | ; move.l .sp_pdst(sp),a0 157 | ; move.l .sp_psrc(sp),a1 158 | move.l .sp_pdst(sp),d0 159 | move.l d0,a0 160 | move.l .sp_psrc(sp),d1 161 | move.l d1,a1 162 | or.w d0,d1 163 | btst #0,d1 164 | bne.s .memcpy_misaligned 165 | 166 | move.l .sp_size(sp),d1 167 | 168 | lsr.l #4,d1 ; num 16-byte blocks total 169 | move.l d1,d0 170 | swap d0 ; num 1mb blocks (64k * 16bytes) 171 | subq.w #1,d1 ; num 16-byte blocks remaining 172 | bcs.s .ev1mb 173 | 174 | .lp1mb: 175 | .lp16b: move.l (a1)+,(a0)+ 176 | move.l (a1)+,(a0)+ 177 | move.l (a1)+,(a0)+ 178 | move.l (a1)+,(a0)+ 179 | dbra d1,.lp16b 180 | 181 | .ev1mb: subq.w #1,d0 182 | bpl.s .lp1mb 183 | 184 | moveq #16-1,d1 185 | and.w .sp_size+2(sp),d1 186 | lsl.b #4+1,d1 187 | bcc.s .n8 188 | move.l (a1)+,(a0)+ 189 | move.l (a1)+,(a0)+ 190 | .n8: add.b d1,d1 191 | bcc.s .n4 192 | move.l (a1)+,(a0)+ 193 | .n4: add.b d1,d1 194 | bcc.s .n2 195 | move.w (a1)+,(a0)+ 196 | .n2: add.b d1,d1 197 | bcc.s .n1 198 | move.b (a1)+,(a0)+ 199 | .n1: 200 | move.l .sp_pdst(sp),d0 201 | rts 202 | 203 | .memcpy_misaligned: 204 | move.w a1,d1 205 | eor.w d0,d1 206 | btst #0,d1 207 | bne .memcpy_misaligned_sgl 208 | 209 | .memcpy_misaligned_pair: 210 | move.l .sp_size(sp),d1 211 | 212 | move.b (a1)+,(a0)+ 213 | subq.l #1,d1 214 | beq .done 215 | move.w d1,.sp_size+2(sp) 216 | 217 | lsr.l #4,d1 ; num 16-byte blocks total 218 | move.l d1,d0 219 | swap d0 ; num 1mb blocks (64k * 16bytes) 220 | subq.w #1,d1 ; num 16-byte blocks remaining 221 | bcs.s .ev1mc 222 | 223 | .lp1mc: 224 | .lp16c: move.l (a1)+,(a0)+ 225 | move.l (a1)+,(a0)+ 226 | move.l (a1)+,(a0)+ 227 | move.l (a1)+,(a0)+ 228 | dbra d1,.lp16c 229 | 230 | .ev1mc: subq.w #1,d0 231 | bpl.s .lp1mc 232 | 233 | moveq #16-1,d1 234 | and.w .sp_size+2(sp),d1 235 | lsl.b #4+1,d1 236 | bcc.s .n8c 237 | move.l (a1)+,(a0)+ 238 | move.l (a1)+,(a0)+ 239 | .n8c: add.b d1,d1 240 | bcc.s .n4c 241 | move.l (a1)+,(a0)+ 242 | .n4c: add.b d1,d1 243 | bcc.s .n2c 244 | move.w (a1)+,(a0)+ 245 | .n2c: add.b d1,d1 246 | bcc.s .n1c 247 | move.b (a1)+,(a0)+ 248 | .n1c: 249 | .done: move.l .sp_pdst(sp),d0 250 | rts 251 | 252 | .memcpy_misaligned_sgl: 253 | move.l .sp_size(sp),d1 254 | 255 | lsr.l #4,d1 ; num 16-byte blocks total 256 | move.l d1,d0 257 | swap d0 ; num 1mb blocks (64k * 16bytes) 258 | subq.w #1,d1 ; num 16-byte blocks remaining 259 | bcs.s .ev1md 260 | 261 | .lp1md: 262 | .lp16d: move.b (a1)+,(a0)+ 263 | move.b (a1)+,(a0)+ 264 | move.b (a1)+,(a0)+ 265 | move.b (a1)+,(a0)+ 266 | move.b (a1)+,(a0)+ 267 | move.b (a1)+,(a0)+ 268 | move.b (a1)+,(a0)+ 269 | move.b (a1)+,(a0)+ 270 | move.b (a1)+,(a0)+ 271 | move.b (a1)+,(a0)+ 272 | move.b (a1)+,(a0)+ 273 | move.b (a1)+,(a0)+ 274 | move.b (a1)+,(a0)+ 275 | move.b (a1)+,(a0)+ 276 | move.b (a1)+,(a0)+ 277 | move.b (a1)+,(a0)+ 278 | dbra d1,.lp16d 279 | 280 | .ev1md: subq.w #1,d0 281 | bpl.s .lp1md 282 | 283 | ; copy remaining bytes, if any 284 | 285 | moveq #16-1,d1 286 | and.w .sp_size+2(sp),d1 287 | add.w d1,d1 288 | neg.w d1 289 | jmp .jtab(pc,d1.w) 290 | move.b (a1)+,(a0)+ 291 | move.b (a1)+,(a0)+ 292 | move.b (a1)+,(a0)+ 293 | move.b (a1)+,(a0)+ 294 | move.b (a1)+,(a0)+ 295 | move.b (a1)+,(a0)+ 296 | move.b (a1)+,(a0)+ 297 | move.b (a1)+,(a0)+ 298 | move.b (a1)+,(a0)+ 299 | move.b (a1)+,(a0)+ 300 | move.b (a1)+,(a0)+ 301 | move.b (a1)+,(a0)+ 302 | move.b (a1)+,(a0)+ 303 | move.b (a1)+,(a0)+ 304 | move.b (a1)+,(a0)+ 305 | move.b (a1)+,(a0)+ 306 | .jtab: 307 | move.l .sp_pdst(sp),d0 308 | rts 309 | 310 | ; -------------------------------------------------------------- 311 | _memset: 312 | ; -------------------------------------------------------------- 313 | 314 | ; move.l d2,-(sp) 315 | move.l d2,a1 316 | 317 | ; value 318 | move.b 0+8+3(sp),d0 319 | move.b d0,d1 320 | lsl.w #8,d1 321 | move.b d0,d1 322 | move.w d1,d2 323 | swap d2 324 | move.w d1,d2 325 | 326 | ; size 327 | move.l 0+12(sp),d1 328 | 329 | ; dest 330 | move.l 0+4(sp),d0 331 | move.l d0,a0 332 | and.w #1,d0 333 | beq.s .aligned 334 | move.b d2,(a0)+ 335 | subq.l #1,d1 336 | beq .done 337 | move.w d1,0+12+2(sp) 338 | .aligned: 339 | 340 | lsr.l #4,d1 341 | move.l d1,d0 342 | swap d0 343 | subq.w #1,d1 344 | bcs.s .ev1mb 345 | 346 | .lp1mb: 347 | .lp16b: move.l d2,(a0)+ 348 | move.l d2,(a0)+ 349 | move.l d2,(a0)+ 350 | move.l d2,(a0)+ 351 | dbra d1,.lp16b 352 | 353 | .ev1mb: subq.w #1,d0 354 | bpl.s .lp1mb 355 | 356 | moveq #16-1,d1 357 | and.w 0+12+2(sp),d1 358 | lsl.b #4+1,d1 359 | bcc.s .n8 360 | move.l d2,(a0)+ 361 | move.l d2,(a0)+ 362 | .n8: add.b d1,d1 363 | bcc.s .n4 364 | move.l d2,(a0)+ 365 | .n4: add.b d1,d1 366 | bcc.s .n2 367 | move.w d2,(a0)+ 368 | .n2: add.b d1,d1 369 | bcc.s .n1 370 | move.b d2,(a0)+ 371 | .n1: 372 | 373 | .done: move.l 0+4(sp),d0 374 | 375 | move.l a1,d2 376 | ; move.l (sp)+,d2 377 | rts 378 | 379 | ; -------------------------------------------------------------- 380 | 381 | ; -------------------------------------------------------------- 382 | ___mulsi3: xdef ___mulsi3 383 | ; -------------------------------------------------------------- 384 | move.w 6(sp),d0 385 | move.l d0,a0 386 | mulu.w 8(sp),d0 387 | move.w 10(sp),d1 388 | move.l d1,a1 389 | mulu.w 4(sp),d1 390 | add.w d1,d0 391 | swap d0 392 | clr.w d0 393 | exg.l a0,d0 394 | move.l a1,d1 395 | mulu.w d1,d0 396 | add.l a0,d0 397 | rts 398 | 399 | ; -------------------------------------------------------------- 400 | ___modsi3: xdef ___modsi3 401 | ; -------------------------------------------------------------- 402 | move.l (sp)+,a0 403 | move.l 4(sp),d1 404 | bpl.s .nabs 405 | neg.l 4(sp) 406 | .nabs: move.l (sp),d0 407 | pea .ret(pc) 408 | bpl.s .nabsd 409 | neg.l 4(sp) 410 | subq.l #2,(sp) 411 | .nabsd: bra ___udivsi3 412 | neg.l d1 413 | .ret: move.l d1,d0 414 | jmp (a0) 415 | 416 | ; -------------------------------------------------------------- 417 | ___udivsi3: xdef ___udivsi3 418 | ; -------------------------------------------------------------- 419 | move.l d2,-(sp) 420 | move.l 12(sp),d0 421 | move.l 8(sp),d1 422 | .norm: cmpi.l #$10000,d0 423 | bcs.s .normd 424 | lsr.l #1,d0 425 | lsr.l #1,d1 426 | bra.s .norm 427 | .normd: move.w d1,d2 428 | clr.w d1 429 | swap d1 430 | divu.w d0,d1 431 | movea.l d1,a1 432 | move.w d2,d1 433 | divu.w d0,d1 434 | move.l a1,d0 435 | swap d0 436 | clr.w d0 437 | andi.l #$ffff,d1 438 | add.l d1,d0 439 | move.l 12(sp),d2 440 | swap d2 441 | move.l d0,d1 442 | mulu.w d2,d1 443 | movea.l d1,a1 444 | swap d2 445 | move.l d0,d1 446 | swap d1 447 | mulu.w d2,d1 448 | add.l a1,d1 449 | swap d1 450 | clr.w d1 451 | movea.l d2,a1 452 | mulu.w d0,d2 453 | add.l d1,d2 454 | move.l 8(sp),d1 455 | sub.l d2,d1 456 | bcc.s .ninc 457 | subq.l #1,d0 458 | add.l a1,d1 459 | .ninc: move.l (sp)+,d2 460 | rts 461 | 462 | ; -------------------------------------------------------------- 463 | ___umodsi3: xdef ___umodsi3 464 | ; -------------------------------------------------------------- 465 | move.l (sp)+,a0 466 | bsr ___udivsi3 467 | move.l d1,d0 468 | jmp (a0) 469 | 470 | ; -------------------------------------------------------------- 471 | ___divsi3: xdef ___divsi3 472 | ; -------------------------------------------------------------- 473 | move.l 4(sp),d1 474 | bpl.s .nabs1 475 | neg.l 4(sp) 476 | .nabs1: move.l 8(sp),d0 477 | bpl.s .nabs2 478 | neg.l 8(sp) 479 | .nabs2: eor.l d1,d0 480 | bpl.s .npop 481 | move.l (sp)+,a0 482 | pea .ret(pc) 483 | .npop: bra ___udivsi3 484 | .ret: neg.l d0 485 | jmp (a0) 486 | 487 | ; -------------------------------------------------------------- 488 | _putchar: xdef _putchar 489 | ; -------------------------------------------------------------- 490 | move.w 4+2(sp),d1 491 | movem.l d2/a2,-(sp) 492 | move.w d1,-(sp) 493 | move.w #2,-(sp) 494 | move.w #3,-(sp) 495 | trap #13 496 | addq.l #6,sp 497 | moveq #0,d0 498 | movem.l (sp)+,d2/a2 499 | rts 500 | 501 | ; -------------------------------------------------------------- 502 | text 503 | ; -------------------------------------------------------------- 504 | 505 | _rand: XDEF _rand 506 | ___cxa_guard_acquire: 507 | ___cxa_guard_release: 508 | rts 509 | 510 | ; -------------------------------------------------------------- 511 | __ZSt17__throw_bad_allocv: 512 | ___cxa_pure_virtual: 513 | ; -------------------------------------------------------------- 514 | jmp _exit 515 | 516 | ; -------------------------------------------------------------- 517 | data 518 | ; -------------------------------------------------------------- 519 | 520 | dummy_argv: 521 | dummy_envp: 522 | dc.b 0 523 | even 524 | 525 | ; -------------------------------------------------------------- 526 | bss 527 | ; -------------------------------------------------------------- 528 | 529 | ds.b SSPS 530 | new_ssp: 531 | ds.l 1 532 | entrypoint_ssp: 533 | ds.l 1 534 | 535 | ; -------------------------------------------------------------- 536 | 537 | -------------------------------------------------------------------------------- /barebones/libcxx/browncrt++.c: -------------------------------------------------------------------------------- 1 | //====================================================================================================================== 2 | // BrownELF GCC startup: dml/2017 3 | //====================================================================================================================== 4 | // C++ startup/shutdown code including ctor/dtor,preinit/init/fini,atexit handling 5 | //---------------------------------------------------------------------------------------------------------------------- 6 | 7 | // --------------------------------------------------------------------------------------------------------------------- 8 | // system headers 9 | 10 | #include 11 | 12 | // ---------------------------------------------------------------------------------------- 13 | 14 | #include 15 | #include 16 | 17 | //int debug_printf(const char *pFormat, ...); 18 | 19 | // ---------------------------------------------------------------------------------------- 20 | 21 | // references to GCC6 new-style ctor/dtor lists 22 | // 23 | // CAUTION: 24 | // while the .init_array does contain the constructor list, the .fini_array doesn't 25 | // necessarily contain the list of destructors. \o/ 26 | // the destructors seem to be registered secretly by GCC via __cxa_atexit(pdtor,pobj) 27 | // and will be executed during __cxa_finalize(). this is a bit wild and confusing, but 28 | // that's how things really are in gnu land... 29 | // 30 | // Quote: 31 | // "The .ctors/.dtors sections are still relevant. They are slowy being superseded by 32 | // .init_array/.fini_array however (on systems which support it) because .init_array 33 | // sorts ascending and not descending. 34 | // In practice, the .dtors section is normally empty now (unless a function is otherwise 35 | // made a destructor by use of function attributes in GCC) because inside every global 36 | // and local static C++ .ctor a call to __cxa_atexit (or atexit on some non-compliant 37 | // targets) is made to register it's destructor. 38 | // So an OS must still call constructors in the .ctors list (or .init_array depending 39 | // on your system) and must implement __cxa_atexit and __cxa_finalize." 40 | 41 | extern void (*__preinit_array_start []) (int argc, char **argv, char **envp) __attribute__((weak)); 42 | extern void (*__preinit_array_end []) (int argc, char **argv, char **envp) __attribute__((weak)); 43 | extern void (*__init_array_start []) (int argc, char **argv, char **envp) __attribute__((weak)); 44 | extern void (*__init_array_end []) (int argc, char **argv, char **envp) __attribute__((weak)); 45 | extern void (*__fini_array_start []) (void) __attribute__((weak)); 46 | extern void (*__fini_array_end []) (void) __attribute__((weak)); 47 | 48 | typedef void (*aefuncp) (void); // atexit function pointer 49 | 50 | int atexit(aefuncp func); 51 | 52 | // execute the .fini_array, if relevant (but typically *not* destructors) 53 | void __libc_csu_fini(void) 54 | { 55 | size_t i = __fini_array_end - __fini_array_start; 56 | //debug_printf("__libc_csu_fini: fini count: %d\n", i); 57 | while (i-- > 0) 58 | (__fini_array_start[i])(); 59 | } 60 | 61 | // execute the .init_array, if relevant (including constructors) 62 | void __libc_csu_init(int argc, char **argv, char **envp) 63 | { 64 | { 65 | const size_t size = __preinit_array_end - __preinit_array_start; 66 | //debug_printf("__libc_csu_init: preinit count: %d\n", size); 67 | size_t i; 68 | for (i = 0; i < size; i++) 69 | (__preinit_array_start[i])(argc, argv, envp); 70 | } 71 | 72 | { 73 | const size_t size = __init_array_end - __init_array_start; 74 | //debug_printf("__libc_csu_init: init count: %d\n", size); 75 | for (size_t i = 0; i < size; i++) 76 | (__init_array_start[i])(argc, argv, envp); 77 | } 78 | 79 | // register finalize/cleanup 80 | atexit(&__libc_csu_fini); 81 | } 82 | 83 | // ---------------------------------------------------------------------------------------- 84 | -------------------------------------------------------------------------------- /barebones/libcxx/browncrti.gas: -------------------------------------------------------------------------------- 1 | /* 2 | BrownELF GCC startup: dml/2017 3 | 4 | mark the beginning of all ELF/GCC6 initialize/finalize lists. 5 | - required for all C++ projects using static initialization 6 | with constructors/destructors. 7 | - this file should be the first to link after [ crt0.o ] 8 | */ 9 | 10 | .globl ___preinit_array_start 11 | .globl ___init_array_start 12 | .globl ___fini_array_start 13 | 14 | .section .preinit_array,"",@progbits 15 | ___preinit_array_start: 16 | .section .init_array,"",@progbits 17 | ___init_array_start: 18 | .section .fini_array,"",@progbits 19 | ___fini_array_start: 20 | 21 | -------------------------------------------------------------------------------- /barebones/libcxx/browncrtn.gas: -------------------------------------------------------------------------------- 1 | /* 2 | BrownELF GCC startup: dml/2017 3 | 4 | mark the end of all ELF/GCC6 initialize/finalize lists. 5 | - required for all C++ projects using static initialization 6 | with constructors/destructors. 7 | - this file should be the very last to link. 8 | */ 9 | 10 | .globl ___preinit_array_end 11 | .globl ___init_array_end 12 | .globl ___fini_array_end 13 | 14 | .section .preinit_array 15 | ___preinit_array_end: 16 | .long 0 17 | 18 | .section .init_array 19 | ___init_array_end: 20 | .long 0 21 | 22 | .section .fini_array 23 | ___fini_array_end: 24 | .long 0 25 | 26 | -------------------------------------------------------------------------------- /barebones/libcxx/brownmint++.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Crtinit: C run-time initialization code. 3 | * Written by Eric R. Smith, and placed in the public domain. 4 | * Use at your own risk. 5 | * 6 | * 01/03/89 ++jrb 7 | * The (new) meaning of _stksize: (thanks to allan pratt for the feedback) 8 | * 9 | * _stksize meaning 10 | * -1L keep all of memory (except MINFREE at top) and do 11 | * mallocs from own heap, with heap grown upwards towards 12 | * stack, and the stack growing down towards heap, 13 | * with a minimum slush between them so that they 14 | * dont meet (only checked while malloc'ing). With 15 | * this model, further spawning is not possible, but it is 16 | * well suited for programs such as gcc-cc1 etc. 17 | * Thanks to Piet van Oostrum & Atze Dijkstra for this idea 18 | * 19 | * 0L keep minimum amount of memory. this is also the 20 | * case when _stksize is undefined by the user. 21 | * 1L keep 1/4 of memory, free 3/4 ( as in Alcyon GEMSTART) 22 | * 2L keep 2/4 (1/2), free rest 23 | * 3L keep 3/4, free 1/4 24 | * other keep that many bytes 25 | * -other keep |other| bytes, use the heap for mallocs 26 | * 27 | * 02/14/90 ++jrb (thanks edgar) 28 | * auto acc detect 29 | * undump friendly 30 | * 31 | * NOTE: dumping applications should use _initial_stack instead: if 32 | * !=0, then _stksize is initialized from _initial_stack, and 33 | * mallocs are always from internal heap. (TeX works much better now), 34 | * thanks edgar! 35 | * 36 | * Acc convention: 37 | * Preferred: user sets _stksize, then _heapbase is set to Malloc(_stksize) 38 | * sp to _heapbase + _stksize and all mallocs happen from heap 39 | * 40 | * Old way: 41 | * user sets _heapbase to bottom of stack + heap area 42 | * sets _stksize to the size of this area 43 | * at startup, sp will be set to top of this area 44 | * (_heapbase + _stksize ) and malloc()'s will happen from heap. 45 | * (note malloc() and *not* Malloc()) 46 | * 47 | * 02/16/90 ++jrb 48 | * - bug fix: dont get screwed by desktop launch when fast bit is set 49 | * convert env string to format usable 50 | * (atari get your act together!!) 51 | * 52 | * 19 Jan 93 hohmuth 53 | * new variable _PgmSize, holds size of program area 54 | * (useful when doing Ptermres) 55 | * 56 | * 08 Apr 93 hohmuth 57 | * added support for ARGV standard extension allowing empty arguments 58 | * 59 | * dml 2017 60 | * 61 | * added call to __libc_csu_init for C++ startup 62 | */ 63 | 64 | /* define this symbol to get ARGV argument passing that's strictly 65 | * compatible with the Atari standard. If it's not defined, then 66 | * the startup code won't validate the ARGV= variable by checking 67 | * the command byte for 0x127. Note that there are still some 68 | * applications (gulam is a notable example) that implement only 69 | * part of the standard and don't set the command byte to 0x127. 70 | */ 71 | #if 1 72 | #define STRICTLY_COMPATIBLE_WITH_STANDARD 73 | #endif 74 | #define _GNU_SOURCE 75 | 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include "lib.h" 81 | //#include "stksiz.h" 82 | 83 | /* definitions needed in mintlib/crtinit.c and mintlib/stksize.c */ 84 | 85 | #define MINFREE (8L * 1024L) /* free at least this much mem on top */ 86 | #define MINKEEP (64L * 1024L) /* keep at least this much mem on stack */ 87 | 88 | void __libc_csu_init(int argc, char **argv, char **envp); 89 | 90 | #define isspace(c) ((c) == ' '||(c) == '\t') 91 | #define isdigit(c) ((c) >= '0' && (c) <= '9') 92 | 93 | static long parseargs(BASEPAGE *); 94 | 95 | /* 96 | * accessories start here: 97 | */ 98 | static char *acc_argv[] = { "", NULL }; /* no name and no arguments */ 99 | 100 | void _acc_main(void) 101 | { 102 | char *s; 103 | 104 | if (_stksize == 0 || _stksize == -1L) 105 | _stksize = MINKEEP; 106 | 107 | if (_stksize < 0) 108 | _stksize = -_stksize; 109 | 110 | if ((s = getenv("STACKSIZE")) != 0) 111 | _stksize = atoi(s); 112 | 113 | /* stack on word boundary */ 114 | _stksize &= 0xfffffffeL; 115 | 116 | if (_heapbase == 0) { 117 | _heapbase = (void *)Malloc(_stksize); 118 | } 119 | _setstack((char *) _heapbase + _stksize); 120 | 121 | /* this is an accessory */ 122 | _app = 0; 123 | 124 | _main(1L, acc_argv, acc_argv); 125 | /*NOTREACHED*/ 126 | } 127 | 128 | void _crtinit(void) 129 | { 130 | extern void etext(); /* a "function" to fake out pc-rel addressing */ 131 | 132 | register BASEPAGE *bp; 133 | register long m; 134 | register long freemem; 135 | char *s; 136 | 137 | /* its an application */ 138 | _app = 1; 139 | 140 | bp = _base; 141 | 142 | /* m = # bytes used by environment + args */ 143 | m = parseargs(bp); 144 | 145 | /* make m the total number of bytes required by program sans stack/heap */ 146 | m += (bp->p_tlen + bp->p_dlen + bp->p_blen + sizeof(BASEPAGE)); 147 | m = (m + 3L) & (~3L); 148 | 149 | /* freemem the amount of free mem accounting for MINFREE at top */ 150 | if ((freemem = (long)bp->p_hitpa - (long)bp - MINFREE - m) <= 0L) 151 | goto notenough; 152 | 153 | if (_initial_stack) { 154 | /* the primary use of _initial_stack will be in dumping */ 155 | /* applications where only a heap for malloc makes sense */ 156 | _heapbase = (void *)((long)bp + m); 157 | _stksize = _initial_stack; 158 | } else { 159 | if (_stksize >= -1L) 160 | /* malloc from Malloc first, then from own heap */ 161 | _split_mem = 1; 162 | } 163 | 164 | if (_stksize == -1L) { 165 | _stksize = freemem; 166 | _heapbase = (void *)((long)bp + m); 167 | } else if (_stksize == 0L) { /* free all but MINKEEP */ 168 | _stksize = MINKEEP; 169 | } else if (_stksize == 1L) { /* keep 1/4, free 3/4 */ 170 | _stksize = freemem >> 2; 171 | } else if (_stksize == 2L) { /* keep 1/2, free 1/2 */ 172 | _stksize = freemem >> 1; 173 | } else if (_stksize == 3L) { /* keep 3/4, free 1/4 */ 174 | _stksize = freemem - (freemem >> 2); 175 | } else { 176 | if(_stksize < -1L) { /* keep |_stksize|, use heap for mallocs */ 177 | _stksize = -_stksize; 178 | _heapbase = (void *)((long)bp + m); 179 | } 180 | } 181 | 182 | if ((s = getenv("STACKSIZE")) != 0) 183 | _stksize = atoi(s); 184 | 185 | /* make m the total number of bytes including stack */ 186 | _stksize = _stksize & (~3L); 187 | m += _stksize; 188 | 189 | /* make sure there's enough room for the stack */ 190 | if (((long)bp + m) > ((long)bp->p_hitpa - MINFREE)) 191 | goto notenough; 192 | 193 | /* set up the new stack to bp + m */ 194 | _setstack((char *)bp + m); 195 | 196 | /* shrink the TPA */ 197 | (void)Mshrink(bp, m); 198 | 199 | /* keep length of program area */ 200 | _PgmSize = m; 201 | 202 | /* establish handlers, call the main routine */ 203 | _init_signal(); 204 | 205 | /* start profiling, if we were linked with gcrt0.o */ 206 | _monstartup((void *)bp->p_tbase, (void *)((long)etext - 1)); 207 | 208 | /* needed for c++ static inits using ELF GCC6 */ 209 | __libc_csu_init(__libc_argc, __libc_argv, environ); 210 | 211 | _main(__libc_argc, __libc_argv, environ); 212 | /* not reached normally */ 213 | 214 | notenough: 215 | (void) Cconws("Fatal error: insufficient memory\r\n"); 216 | (void) Cconws("Hint: either decrease stack size using 'stack' command (not recomended)\r\n" \ 217 | " or increase TPA_INITIALMEM value in mint.cnf.\r\n"); 218 | Pterm(-1); 219 | } 220 | 221 | /* 222 | * parseargs(bp): parse the environment and arguments pointed to by the 223 | * basepage. Return the number of bytes of environment and arguments 224 | * that have been appended to the bss area (the environ and argv arrays 225 | * are put here, as is a temporary buffer for the command line, if 226 | * necessary). 227 | * 228 | * The MWC extended argument passing scheme is assumed. 229 | * 230 | */ 231 | static long parseargs(BASEPAGE *bp) 232 | { 233 | long count = 4; /* compensate for aligning */ 234 | long i; 235 | char *from, *cmdln, *to; 236 | char **envp, **arg; 237 | char *null_list = 0; 238 | /* flag to indicate desktop-style arg. passing */ 239 | long desktoparg; 240 | 241 | /* handle the environment first */ 242 | 243 | environ = envp = (char **)(( (long)bp->p_bbase + bp->p_blen + 4) & (~3)); 244 | from = bp->p_env; 245 | while (*from) { 246 | 247 | /* if we find MWC arguments, tie off environment here */ 248 | if (*from == 'A' && *(from+1) == 'R' && *(from+2) == 'G' && 249 | *(from+3) == 'V' && *(from+4) == '=') 250 | { 251 | *envp++ = (char *) 0; count += 4; 252 | *from = 0; 253 | #ifdef STRICTLY_COMPATIBLE_WITH_STANDARD 254 | if (bp->p_cmdlin[0] != 127) 255 | goto old_cmdlin; 256 | #endif 257 | from += 5; /* skip ARGV= string */ 258 | 259 | /* find list of empty params 260 | */ 261 | if (*from == 'N' && *(from+1) == 'U' 262 | && *(from+2) == 'L' && *(from+3) == 'L' 263 | && *(from+4) == ':') 264 | { 265 | null_list = from + 5; 266 | } 267 | 268 | while (*from++) ; /* skip ARGV= value */ 269 | __libc_argv = arg = envp; 270 | *arg++ = from; count+= 4; 271 | while (*from++) ; /* skip __libc_argv[0] */ 272 | goto do_argc; 273 | } 274 | *envp++ = from; 275 | count += 4; 276 | desktoparg = 1; 277 | while (*from) { 278 | if (*from == '=') { 279 | desktoparg = 0; 280 | } 281 | from++; 282 | } 283 | from++; /* skip 0 */ 284 | 285 | /* the desktop (and some shells) use the environment in the wrong 286 | way, putting in "PATH=\0C:\0" instead of "PATH=C:". so if we 287 | find an "environment variable" without an '=' in it, we 288 | see if the last environment variable ended with '=\0', and 289 | if so we append this one to the last one 290 | */ 291 | if(desktoparg && envp > &environ[1]) 292 | { 293 | /* launched from desktop -- fix up env */ 294 | char *p, *q; 295 | 296 | q = envp[-2]; /* current one is envp[-1] */ 297 | while (*q) q++; 298 | if (q[-1] == '=') { 299 | p = *--envp; 300 | while(*p) 301 | *q++ = *p++; 302 | *q = '\0'; 303 | } 304 | } 305 | } 306 | *envp++ = (char *)0; 307 | count += 4; 308 | 309 | #ifdef STRICTLY_COMPATIBLE_WITH_STANDARD 310 | old_cmdlin: 311 | #endif 312 | /* Allocate some room for the command line to be parsed */ 313 | cmdln = bp->p_cmdlin; 314 | i = *cmdln++; 315 | from = to = (char *) envp; 316 | if (i > 0) { 317 | count += (i&(~3)); 318 | envp = (char **) ( ((long) envp) + (i&(~3)) ); 319 | } 320 | envp += 2; count += 8; 321 | 322 | /* Now parse the command line and put __libc_argv after the environment */ 323 | 324 | __libc_argv = arg = envp; 325 | *arg++ = ""; /* __libc_argv[0] not available */ 326 | count += 4; 327 | while(i > 0 && isspace(*cmdln) ) 328 | cmdln++,--i; 329 | 330 | /* 331 | * MagXDesk only uses ARGV if the arg is longer than the 126 character 332 | * of bp->cmdlin. If the arg is short enough and contains a file name with 333 | * blanks it will be come quoted via bp->cmdlin!! 334 | */ 335 | if (cmdln[0] != '\'') 336 | { 337 | while (i > 0) { 338 | if (isspace(*cmdln)) { 339 | --i; cmdln++; 340 | while (i > 0 && isspace(*cmdln)) 341 | --i,cmdln++; 342 | *to++ = 0; 343 | } 344 | else { 345 | if ((*to++ = *cmdln++) == 0) break; 346 | --i; 347 | } 348 | } 349 | } 350 | else 351 | { 352 | int in_quote = 0; 353 | 354 | while (i > 0) 355 | { 356 | if (*cmdln == '\'') 357 | { 358 | i--; 359 | cmdln++; 360 | if (in_quote) 361 | { 362 | if (*cmdln == '\'') /* double ': file name contains ' */ 363 | { 364 | *to++ = *cmdln++; 365 | i--; 366 | } 367 | else 368 | { 369 | in_quote = 0; 370 | *to++ = 0; /* end of quoted arg */ 371 | i--; cmdln++; 372 | } 373 | } 374 | else 375 | in_quote = 1; 376 | } 377 | else 378 | { 379 | if (*cmdln == ' ') 380 | { 381 | if (in_quote) 382 | { 383 | *to++ = *cmdln++; 384 | i--; 385 | } 386 | else 387 | { 388 | --i; cmdln++; 389 | *to++ = 0; 390 | } 391 | } 392 | else 393 | { 394 | *to++ = *cmdln++; 395 | i--; 396 | } 397 | } 398 | } 399 | } 400 | 401 | *to++ = '\0'; 402 | *to = '\0'; /* bug fix example:cmdln == '\3' 'a' ' ' 'b' '\0' */ 403 | /* the loop below expects \0\0 at end to terminate! */ 404 | /* the byte @ cmdln[i+2] != 0 when fast bit is set */ 405 | do_argc: 406 | /* Find out the name we have been invoked with. */ 407 | if (__libc_argv[0] != 0 && __libc_argv[0][0] != '\0') { 408 | char* p; 409 | program_invocation_name = __libc_argv[0]; 410 | p = strrchr (program_invocation_name, '\\'); 411 | if (p == 0) 412 | p = strrchr (program_invocation_name, '/'); 413 | if (p != 0) 414 | p++; 415 | program_invocation_short_name = p == 0 ? 416 | program_invocation_name : p; 417 | } 418 | 419 | __libc_argc = 1; /* at this point __libc_argv[0] is done */ 420 | while (*from) { 421 | *arg++ = from; 422 | __libc_argc++; 423 | count += 4; 424 | while(*from++) ; 425 | } 426 | *arg = (char *) 0; 427 | 428 | /* zero epmty params 429 | */ 430 | if (null_list) { 431 | char *s; 432 | long idx; 433 | 434 | while (*null_list) { 435 | s = null_list; 436 | 437 | while (* ++null_list) { /* find ',' or '\0' */ 438 | if (*null_list == ',') { 439 | *null_list++ = 0; 440 | break; 441 | } 442 | } 443 | 444 | idx = 0; 445 | for (;;) { 446 | if (! isdigit(*s)) 447 | goto bail_out; 448 | 449 | /* don't feed this to strtol(), 450 | * do the ascii -> long conversion by 451 | * hand for efficency 452 | */ 453 | idx += *s++ - '0'; 454 | if (*s) 455 | idx = (idx << 3) + (idx << 1); 456 | else 457 | break; 458 | } 459 | 460 | if (idx < __libc_argc) 461 | *(__libc_argv[idx]) = 0; 462 | else 463 | goto bail_out; 464 | } 465 | } 466 | 467 | bail_out: 468 | return count+4; 469 | } 470 | -------------------------------------------------------------------------------- /barebones/libcxx/lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * library-specific stuff 3 | */ 4 | #ifndef _LIB_H 5 | #define _LIB_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include /* for FILE. */ 11 | #include /* for time_t. */ 12 | #include 13 | #include /* For struct stat. */ 14 | 15 | 16 | int _doprnt (int (*)(int, FILE *), FILE *, const char *, __gnuc_va_list); 17 | int _scanf (FILE *, int (*)(FILE *), int (*)(int, FILE *), const char *, __gnuc_va_list); 18 | int _enoent (const char *); 19 | 20 | void _crtinit (void); 21 | void _main (long, char **, char **); 22 | void _acc_main (void); 23 | void _init_signal (void); 24 | void _setstack (char *); 25 | 26 | void _monstartup (void *lowpc, void *highpc); 27 | 28 | 29 | /* mintlib/globals.c */ 30 | 31 | extern int __mint; 32 | extern int __has_no_ssystem; 33 | extern int __libc_enable_secure; 34 | extern int __libc_unix_names; 35 | 36 | extern int _pdomain; 37 | extern char _rootdir; 38 | 39 | extern clock_t _starttime; 40 | extern clock_t _childtime; 41 | 42 | extern BASEPAGE *_base; 43 | extern char **environ; 44 | extern long __libc_argc; 45 | extern char **__libc_argv; 46 | 47 | extern void *_heapbase; 48 | extern short _split_mem; 49 | 50 | extern long _stksize; 51 | extern long _initial_stack; 52 | 53 | extern short _app; 54 | extern unsigned long _PgmSize; 55 | 56 | extern char *program_invocation_name; 57 | extern char *program_invocation_short_name; 58 | 59 | typedef void (*ExitFn)(void); 60 | extern ExitFn *_at_exit; 61 | extern int _num_at_exit; 62 | 63 | /* signal/initsig.c */ 64 | 65 | extern sighandler_t _sig_handler[NSIG]; 66 | extern long _sigmask; 67 | extern long _sigpending; 68 | 69 | /* unix/open.c */ 70 | 71 | extern int __current_umask; 72 | 73 | /* definitions needed in malloc.c and realloc.c */ 74 | 75 | struct mem_chunk 76 | { 77 | long valid; 78 | #define VAL_FREE 0xf4ee0abcL 79 | #define VAL_ALLOC 0xa11c0abcL 80 | #define VAL_BORDER 0xb04d0abcL 81 | 82 | struct mem_chunk *next; 83 | unsigned long size; 84 | }; 85 | #define ALLOC_SIZE(ch) (*(long *)((char *)(ch) + sizeof(*(ch)))) 86 | #define BORDER_EXTRA ((sizeof(struct mem_chunk) + sizeof(long) + 7) & ~7) 87 | 88 | /* linked list of free blocks */ 89 | extern struct mem_chunk _mchunk_free_list; 90 | 91 | 92 | /* status of open files (for isatty, et al.) */ 93 | struct __open_file 94 | { 95 | short status; /* whether or not it's a tty */ 96 | short flags; /* if a tty, its flags */ 97 | short check_eagain; /* < 0 uninitialized 98 | * = 0 don't need workaround 99 | * > 0 need workaround */ 100 | }; 101 | #define __NHANDLES 40 102 | 103 | /* NOTE: this array is indexed by (__OPEN_INDEX(fd)) */ 104 | extern struct __open_file __open_stat[]; 105 | 106 | #define __OPEN_INDEX(x) (((short)(x)) + 3) 107 | 108 | #define FH_UNKNOWN 0 109 | #define FH_ISATTY 1 110 | #define FH_ISAFILE 2 111 | 112 | /* 113 | * macro for converting a long in DOS format to one in Unix format. "x" 114 | * _must_ be an lvalue! 115 | */ 116 | #define __UNIXTIME(x) (x = __unixtime(((unsigned short *) &x)[0], \ 117 | ((unsigned short *) &x)[1])) 118 | 119 | FILE *_fopen_i (const char *, const char *, FILE *); 120 | 121 | /* Maybe not the best place for this... */ 122 | /* This is what Fxattr expects. */ 123 | struct xattr 124 | { 125 | unsigned short st_mode; 126 | long st_ino; /* must be 32 bits */ 127 | unsigned short st_dev; /* must be 16 bits */ 128 | short st_rdev; /* not supported by the kernel */ 129 | unsigned short st_nlink; 130 | unsigned short st_uid; /* must be 16 bits */ 131 | unsigned short st_gid; /* must be 16 bits */ 132 | long st_size; 133 | long st_blksize; 134 | long st_blocks; 135 | unsigned long st_mtime; 136 | unsigned long st_atime; 137 | unsigned long st_ctime; 138 | short st_attr; 139 | short res1; /* reserved for future kernel use */ 140 | long res2[2]; 141 | }; 142 | 143 | /* mintlib/inode.c */ 144 | extern ino_t __inode; 145 | 146 | long __sys_stat(const char *path, struct stat *st, int lflag, int exact); 147 | long __sys_fstat(short fd, struct stat *st, int exact); 148 | 149 | int __quickstat(const char *_path, struct stat *st, int lflag); 150 | int __do_stat(const char *_path, struct stat *st, int lflag); 151 | int __do_fstat(int fd, struct stat *st, int exact); 152 | int __do_lock(int fd, int cmd, long size, int whence); 153 | 154 | int __do_chown16 (const char *_name, uid_t uid, gid_t gid, int follow_links); 155 | 156 | #endif /* _LIB_H */ 157 | -------------------------------------------------------------------------------- /barebones/libcxx/libc-symbols.h: -------------------------------------------------------------------------------- 1 | /* libc-symbols.h -- MiNTLib. 2 | Copyright (C) 2000 Guido Flohr 3 | 4 | This file is part of the MiNTLib project, and may only be used 5 | modified and distributed under the terms of the MiNTLib project 6 | license, COPYMINT. By continuing to use, modify, or distribute 7 | this file you indicate that you have read the license and 8 | understand and accept it fully. 9 | */ 10 | 11 | /* Support macros for making weak and strong aliases for symbols, 12 | and for using symbol sets and linker warnings with GNU ld. */ 13 | 14 | #ifndef _LIBC_SYMBOLS_H 15 | # define _LIBC_SYMBOLS_H 1 16 | 17 | #ifndef _FEATURES_H 18 | # include 19 | #endif 20 | 21 | /* See . That is also one of the files that you have to edit 22 | if you want to add support for other linkers. Currently supported 23 | are recent versions of GNU ld and older versions of GNU ld only 24 | when compiled with gcc (so that we have at least strong aliases). */ 25 | 26 | #ifdef __HAVE_GNU_LD 27 | # define HAVE_WEAK_SYMBOLS 28 | #endif 29 | 30 | # define C_SYMBOL_NAME(name) _##name 31 | 32 | #ifndef __ASSEMBLER__ 33 | 34 | # ifdef __GNUC__ 35 | 36 | /* Define ALIAS as a strong alias for ORIGINAL. */ 37 | # define strong_alias(original, alias) \ 38 | __asm__ (".globl _" #alias "\n\t" \ 39 | ".set _" #alias ",_" #original); 40 | 41 | /* Define ALIAS as a weak alias for ORIGINAL. */ 42 | # ifdef HAVE_WEAK_SYMBOLS 43 | # define weak_alias(original, alias) \ 44 | __asm__ (".weak _" #alias "\n\t" \ 45 | "_" #alias " = " "_" #original); 46 | # define weak_extern(symbol) __asm__ (".weak _" #symbol); 47 | # endif /* !__HAVE_WEAK_SYMBOLS */ 48 | 49 | /* When a reference to SYMBOL is encountered, the linker will emit a 50 | warning message MSG. */ 51 | # ifdef __HAVE_GNU_LD 52 | # define link_warning(symbol, msg) \ 53 | __asm__(".stabs \"" msg "\",30,0,0,0\n\t" \ 54 | ".stabs \"_" #symbol "\",1,0,0,0"); 55 | # endif /* __HAVE_GNU_LD */ 56 | 57 | # endif /* !__GNUC__ */ 58 | 59 | # ifndef strong_alias 60 | # error You have to find a way how to define strong aliases. 61 | # endif 62 | 63 | # ifndef weak_alias 64 | # define weak_alias(original, alias) strong_alias(original, alias) 65 | # endif 66 | 67 | # ifndef weak_extern 68 | # define weak_extern(symbol) /* Do nothing, the reference will be strong. */ 69 | # endif 70 | 71 | # ifndef link_warning 72 | # define link_warning(symbol, msg) /* Our warning will be unheard. */ 73 | # endif 74 | 75 | #else /* !__ASSEMBLER__ */ 76 | 77 | # ifdef HAVE_WEAK_SYMBOLS 78 | # define weak_alias(original, alias) \ 79 | .weak C_SYMBOL_NAME (alias); \ 80 | C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) 81 | 82 | # define weak_extern(symbol) \ 83 | .weak C_SYMBOL_NAME (symbol) 84 | 85 | # else /* !HAVE_WEAK_SYMBOLS */ 86 | # define weak_alias(original, alias) \ 87 | .globl C_SYMBOL_NAME (alias) \ 88 | C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) 89 | 90 | # define weak_extern(symbol) \ 91 | .globl C_SYMBOL_NAME (symbol) 92 | 93 | # endif /* !HAVE_WEAK_SYMBOLS */ 94 | 95 | #endif /* !__ASSEMBLER__ */ 96 | 97 | /* Currently disabled since not supported by gcc for MiNT. FIXME!!! */ 98 | #if (0 && !defined __ASSEMBLER__ && \ 99 | (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))) 100 | /* GCC 2.7 and later has special syntax for weak symbols and aliases. 101 | Using that is better when possible, because the compiler and assembler 102 | are better clued in to what we are doing. */ 103 | # undef strong_alias 104 | # define strong_alias(name, aliasname) \ 105 | extern __typeof (name) aliasname __attribute__ ((alias (#name))); 106 | 107 | # ifdef HAVE_WEAK_SYMBOLS 108 | # undef weak_alias 109 | # define weak_alias(name, aliasname) \ 110 | extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); 111 | 112 | /* This comes between the return type and function name in 113 | a function definition to make that definition weak. */ 114 | # define weak_function __attribute__ ((weak)) 115 | # define weak_const_function __attribute__ ((weak, __const__)) 116 | 117 | # endif /* HAVE_WEAK_SYMBOLS. */ 118 | #endif /* Not __ASSEMBLER__, and GCC 2.7 or later. */ 119 | 120 | #ifndef weak_function 121 | /* If we do not have the __attribute__ ((weak)) syntax, there is no way we 122 | can define functions as weak symbols. The compiler will emit a `.globl' 123 | directive for the function symbol, and a `.weak' directive in addition 124 | will produce an error from the assembler. */ 125 | # define weak_function /* empty */ 126 | # define weak_const_function /* empty */ 127 | #endif 128 | 129 | /* On some platforms we can make internal function calls (i.e., calls of 130 | functions not exported) a bit faster by using a different calling 131 | convention. */ 132 | #ifndef internal_function 133 | # define internal_function /* empty */ 134 | #endif 135 | 136 | /* Prepare for the case that `__builtin_expect' is not available. */ 137 | #ifndef HAVE_BUILTIN_EXPECT 138 | # define __builtin_expect(expr, val) (expr) 139 | #endif 140 | 141 | #endif /* libc-symbols.h */ 142 | -------------------------------------------------------------------------------- /barebones/libcxx/zerocrtfini.c: -------------------------------------------------------------------------------- 1 | //====================================================================================================================== 2 | // BrownELF GCC startup: dml/2017 3 | //====================================================================================================================== 4 | // C shutdown code 5 | //---------------------------------------------------------------------------------------------------------------------- 6 | 7 | // --------------------------------------------------------------------------------------------------------------------- 8 | // system headers 9 | 10 | #include 11 | 12 | //int debug_printf(const char *pFormat, ...); 13 | 14 | // --------------------------------------------------------------------------------------------------------------------- 15 | // Our AGT headers 16 | 17 | // ---------------------------------------------------------------------------------------- 18 | 19 | #define MAX_ATEXIT 32 20 | 21 | // ---------------------------------------------------------------------------------------- 22 | 23 | #include 24 | #include 25 | 26 | // ---------------------------------------------------------------------------------------- 27 | 28 | // this will always be NULL since we don't have shared objects in TOS 29 | void * __dso_handle = NULL; 30 | 31 | // prototype for the internal exit(code) function 32 | void _exit(int return_code) __attribute__((noreturn)); 33 | 34 | typedef void (*aefuncp) (void); // atexit function pointer 35 | typedef void (*oefuncp) (int, void *); // on_exit function pointer 36 | typedef void (*cxaefuncp) (void *); // __cxa_atexit function pointer 37 | 38 | // exit function types 39 | typedef enum { 40 | ef_free, 41 | ef_in_use, 42 | ef_on_exit, 43 | ef_cxa_atexit 44 | } ef_type; 45 | 46 | // record for exit function variants and states 47 | typedef struct exit_function_s 48 | { 49 | long int type; // enum ef_type 50 | union 51 | { 52 | struct 53 | { 54 | oefuncp func; 55 | void *arg; 56 | } on_exit; 57 | struct 58 | { 59 | cxaefuncp func; 60 | void *arg; 61 | void* dso_handle; 62 | } cxa_atexit; 63 | } funcs; 64 | } exit_function_t; 65 | 66 | static short exit_count = 0; 67 | static exit_function_t exit_funcs[MAX_ATEXIT]; 68 | 69 | // internal atexit() registration 70 | int __cxa_atexit(cxaefuncp func, void * arg, void * dso_handle) 71 | { 72 | if (func == NULL) 73 | return 0; 74 | 75 | //debug_printf("__cxa_atexit(func,arg,dso_handle)\n"); 76 | 77 | short pos = exit_count++; 78 | 79 | if (pos >= MAX_ATEXIT) 80 | { 81 | exit_count = MAX_ATEXIT; 82 | return -1; 83 | } 84 | 85 | exit_function_t *efp = &exit_funcs[pos]; 86 | efp->funcs.cxa_atexit.func = func; 87 | efp->funcs.cxa_atexit.arg = arg; 88 | efp->funcs.cxa_atexit.dso_handle = dso_handle; 89 | efp->type = ef_cxa_atexit; 90 | 91 | return 0; 92 | } 93 | 94 | // finalize 95 | __attribute__((optimize("O0"))) 96 | void __cxa_finalize(void * dso_handle) 97 | { 98 | int exit_count_snapshot = exit_count; 99 | 100 | /* In reverse order */ 101 | while ((--exit_count_snapshot) >= 0) 102 | { 103 | exit_function_t *efp = &exit_funcs[exit_count_snapshot]; 104 | 105 | if (efp->type == ef_cxa_atexit) 106 | { 107 | efp->type = ef_free; 108 | 109 | //debug_printf("call ef_cxa_atexit\n"); 110 | 111 | /* glibc passes status (0) too, but that's not in the prototype */ 112 | (*efp->funcs.cxa_atexit.func)(efp->funcs.cxa_atexit.arg); 113 | } 114 | else 115 | { 116 | //debug_printf("unknown atexit type!\n"); 117 | } 118 | } 119 | } 120 | 121 | // user-facing atexit() 122 | int atexit(aefuncp func) 123 | { 124 | //debug_printf("atexit(func)\n"); 125 | return __cxa_atexit((cxaefuncp)func, NULL, NULL); 126 | } 127 | 128 | // user-facing exit() 129 | void exit(int return_code) 130 | { 131 | //debug_printf("_exit(code)\n"); 132 | 133 | __cxa_finalize(NULL); 134 | 135 | _exit(return_code); 136 | } 137 | 138 | // ---------------------------------------------------------------------------------------- 139 | -------------------------------------------------------------------------------- /barebones/libcxx/zerolibc.cpp: -------------------------------------------------------------------------------- 1 | //====================================================================================================================== 2 | // ZeroLibC: dml/2017 3 | //====================================================================================================================== 4 | // Minimal libc support functions - can be used with TOS or ELF based GCC packages 5 | //---------------------------------------------------------------------------------------------------------------------- 6 | // Credits: 7 | // - Based on mStartup.cpp sourced from sqward/saulot as minimal C++ startup/crt 8 | // - Reworked into just libc parts unrelated to startup sequence 9 | // - File I/O added, some other changes 10 | // - Minor changes, additions, fixes for use as minimal libc for AGT 11 | //---------------------------------------------------------------------------------------------------------------------- 12 | 13 | // --------------------------------------------------------------------------------------------------------------------- 14 | // system headers 15 | 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | // ---------------------------------------------------------------------------------------- 23 | 24 | #pragma GCC diagnostic push 25 | #pragma GCC diagnostic ignored "-Wunused-variable" 26 | #pragma GCC diagnostic ignored "-Wunused-but-set-variable" 27 | 28 | // ---------------------------------------------------------------------------------------- 29 | 30 | extern "C" { 31 | 32 | // ---------------------------------------------------------------------------------------- 33 | 34 | void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function) 35 | { 36 | puts("__assert_fail"); 37 | //Pterm(-1); 38 | } 39 | 40 | // ---------------------------------------------------------------------------------------- 41 | 42 | void __main() 43 | { 44 | // printf("___main()\n"); 45 | } 46 | 47 | // ---------------------------------------------------------------------------------------- 48 | 49 | int tolower (int c) { 50 | if ('A' <= c && c <= 'Z') { 51 | c += 'a' - 'A'; 52 | } 53 | return c; 54 | } 55 | 56 | int toupper (int c) { 57 | if ('a' <= c && c <= 'z') { 58 | c -= 'a' - 'A'; 59 | } 60 | return c; 61 | } 62 | 63 | // ---------------------------------------------------------------------------------------- 64 | 65 | int puts( const char* pText ) 66 | { 67 | Cconws ( pText ); 68 | Cconws ( "\r" ); 69 | 70 | return 0; 71 | } 72 | 73 | // ---------------------------------------------------------------------------------------- 74 | 75 | size_t strlen ( const char * str ) 76 | { 77 | size_t len = 0; 78 | while ( *(char*)str ++ != 0 ) len++; 79 | return len; 80 | } 81 | 82 | // ---------------------------------------------------------------------------------------- 83 | 84 | int strcmp(const char *s1, const char *s2) 85 | { 86 | while((*s1 && *s2) && (*s1++ == *s2++)); 87 | return *(--s1) - *(--s2); 88 | } 89 | 90 | int strncmp(const char *s, const char *t, size_t n) 91 | { 92 | int cc; 93 | if (n==0) return 0; 94 | do { cc = (*s++ - *t++); } 95 | while (!cc && s[-1] && --n>0); 96 | return cc; 97 | } 98 | 99 | // ---------------------------------------------------------------------------------------- 100 | 101 | void* memmove(void *destination, const void *source, size_t n) 102 | { 103 | char* dest = (char*)destination; 104 | char* src = (char*)source; 105 | 106 | /* No need to do that thing. */ 107 | if (dest == src) 108 | return destination; 109 | 110 | /* Check for destructive overlap. */ 111 | if (src < dest && dest < src + n) { 112 | /* Destructive overlap ... have to copy backwards. */ 113 | src += n; 114 | dest += n; 115 | while (n-- > 0) 116 | *--dest = *--src; 117 | } else { 118 | /* Do an ascending copy. */ 119 | while (n-- > 0) 120 | *dest++ = *src++; 121 | } 122 | 123 | return destination; 124 | } 125 | 126 | // --------------------------------------------------------------------------------------------------------------------- 127 | // return 1 if character is a digit 0-9 128 | // --------------------------------------------------------------------------------------------------------------------- 129 | 130 | static __inline int _isdigit(int num) 131 | { 132 | if (num >= '0' && num <= '9') 133 | return 1; 134 | 135 | return 0; 136 | } // isdigit 137 | 138 | // --------------------------------------------------------------------------------------------------------------------- 139 | // convert string to integer, until non-digit 140 | // --------------------------------------------------------------------------------------------------------------------- 141 | 142 | int atoi(const char *_string) 143 | { 144 | int sign = 0; 145 | int r = 0; 146 | int n = 255; 147 | 148 | if ('-' == (*_string)) 149 | { 150 | ++_string; 151 | sign = -1; 152 | } 153 | 154 | while (_isdigit(*_string) && (n > 0)) 155 | { 156 | r = (r * 10) + (*_string - '0'); 157 | ++_string; 158 | --n; 159 | } 160 | 161 | if (sign < 0) 162 | r = -r; 163 | 164 | return r; 165 | } // atoi 166 | 167 | // ---------------------------------------------------------------------------------------- 168 | 169 | void bcopy(const void *_src, void *_dest, size_t _len) 170 | { 171 | char* src = (char*)_src; 172 | char* dest = (char*)_dest; 173 | 174 | if (dest < src) 175 | { 176 | while (_len--) 177 | { 178 | *dest++ = *src++; 179 | } 180 | } 181 | else 182 | { 183 | char *lasts = src + (_len-1); 184 | char *lastd = dest + (_len-1); 185 | 186 | while (_len--) 187 | { 188 | *(char *)lastd-- = *(char *)lasts--; 189 | } 190 | } 191 | } // bcopy 192 | 193 | // ---------------------------------------------------------------------------------------- 194 | 195 | int stricmp(const char *s, const char *t) 196 | { 197 | int cc; 198 | do { cc = tolower(*s++) - tolower(*t++); } 199 | while (!cc && s[-1]); 200 | return cc; 201 | } 202 | 203 | int strnicmp(const char *s, const char *t, size_t n) 204 | { 205 | int cc; 206 | if (n==0) return 0; 207 | do { cc = tolower(*s++) - tolower(*t++); } 208 | while (!cc && s[-1] && --n>0); 209 | return cc; 210 | } 211 | 212 | /* from http://clc-wiki.net/wiki/C_standard_library:string.h:strcpy */ 213 | char *strcpy(char *dest, const char* src) 214 | { 215 | char *ret = dest; 216 | while (!!((*dest++) = (*src++))) 217 | ; 218 | return ret; 219 | } 220 | 221 | /* from http://clc-wiki.net/wiki/C_standard_library:string.h:strncpy */ 222 | char *strncpy(char *dest, const char *src, size_t n) 223 | { 224 | char *ret = dest; 225 | do { 226 | if (!n--) 227 | return ret; 228 | } while (!!((*dest++) = (*src++))); 229 | while (n--) 230 | *dest++ = 0; 231 | return ret; 232 | } 233 | 234 | /* from http://clc-wiki.net/wiki/C_standard_library:string.h:strcat */ 235 | char *strcat(char *dest, const char *src) 236 | { 237 | char *ret = dest; 238 | while (*dest) 239 | dest++; 240 | while (!!((*dest++) = (*src++))) 241 | ; 242 | return ret; 243 | } 244 | 245 | 246 | /* from http://clc-wiki.net/wiki/memcmp */ 247 | int memcmp(const void* s1, const void* s2,size_t n) 248 | { 249 | const unsigned char *p1 = (const unsigned char *)s1, *p2 = (const unsigned char *)s2; 250 | while(n--) 251 | if( *p1 != *p2 ) 252 | return *p1 - *p2; 253 | else 254 | p1++,p2++; 255 | return 0; 256 | } 257 | 258 | /* from http://clc-wiki.net/wiki/C_standard_library:string.h:memchr */ 259 | void *memchr(const void *s, int c, size_t n) 260 | { 261 | unsigned char *p = (unsigned char*)s; 262 | while( n-- ) 263 | if( *p != (unsigned char)c ) 264 | p++; 265 | else 266 | return p; 267 | return 0; 268 | } 269 | 270 | /* from http://clc-wiki.net/wiki/strstr */ 271 | /* uses memcmp, strlen */ 272 | /* For 52 more bytes, an assembly optimized version is available in the .s file */ 273 | char *strstr(const char *s1, const char *s2) 274 | { 275 | size_t n = strlen(s2); 276 | while(*s1) 277 | if(!memcmp(s1++,s2,n)) 278 | return (char *) (s1-1); 279 | return (char *)0; 280 | } 281 | 282 | /* from http://clc-wiki.net/wiki/C_standard_library:string.h:strchr */ 283 | char *strchr(const char *s, int c) 284 | { 285 | while (*s != (char)c) 286 | if (!*s++) 287 | return 0; 288 | return (char *)s; 289 | } 290 | 291 | /* from http://code.google.com/p/embox/source/browse/trunk/embox/src/lib/string/strlwr.c?spec=svn3211&r=3211 */ 292 | char *strlwr (char * string ) { 293 | char * cp; 294 | 295 | for (cp=string; *cp; ++cp) { 296 | if ('A' <= *cp && *cp <= 'Z') { 297 | *cp += 'a' - 'A'; 298 | } 299 | } 300 | 301 | return(string); 302 | } 303 | 304 | char *strupr(char* _str) 305 | { 306 | char *str = _str; 307 | if (str) 308 | while (*str) 309 | { 310 | *str = toupper(*str); 311 | str++; 312 | } 313 | return _str; 314 | } 315 | 316 | char *strdup(const char *s) 317 | { 318 | return strcpy((char*)malloc(strlen(s)+1), s); 319 | } 320 | 321 | /* Possible sources: 322 | http://code.google.com/p/plan9front/source/browse/sys/src/libc/68000/?r=d992998a50139655fdb4cb7995e996219c6735d5 323 | https://bitbucket.org/npe/nix/src/15af5ea53bed/src/9kron/libc/68000/ 324 | http://clc-wiki.net/wiki/C_standard_library 325 | http://code.google.com/p/embox/source/browse/trunk/embox/src/lib/string/?r=3211 326 | http://www.koders.com/noncode/fid355C9167E5496B5F863EAEB5758B4236711466D2.aspx 327 | http://svn.opentom.org/opentom/trunk/linux-2.6/arch/m68knommu/lib/ 328 | */ 329 | 330 | // ---------------------------------------------------------------------------------------- 331 | 332 | FILE * fopen(const char * filename, const char * mode) 333 | { 334 | int h = 0; 335 | char c = 0; 336 | int update = 0, append = 0, read = 0, write = 0; 337 | short smode = 0; 338 | const char *pmode; 339 | 340 | pmode = mode; 341 | 342 | while (!!(c = (*pmode++))) 343 | { 344 | if (c == '+') 345 | update = 1; 346 | else 347 | if (c == 'r') 348 | read = 1; 349 | else 350 | if (c == 'w') 351 | write = 1; 352 | else 353 | if (c == 'a') 354 | append = 1; 355 | } 356 | 357 | if (read && write) 358 | smode = S_READWRITE; 359 | else 360 | if (write) 361 | smode = S_WRITE; 362 | else 363 | smode = S_READ; 364 | 365 | if (smode == S_READ) 366 | { 367 | // file must exist 368 | h = (int)(short)Fopen(filename, smode); 369 | } 370 | else 371 | { 372 | if (append) 373 | { 374 | h = (int)(short)Fopen(filename, smode); 375 | if (h >= 0) 376 | Fseek(0, h, 2); 377 | } 378 | else 379 | { 380 | // create file 381 | h = (int)(short)Fcreate(filename, 0); 382 | } 383 | } 384 | 385 | if (h >= 0) 386 | return (FILE*)h; 387 | 388 | return (FILE*)NULL; 389 | } 390 | 391 | int fclose(FILE * stream) 392 | { 393 | Fclose((short)(int)stream); 394 | return 0; 395 | } 396 | 397 | size_t fread(void * ptr, size_t size, size_t count, FILE * stream) 398 | { 399 | int r; 400 | // todo: long multiplier 401 | r = Fread((short)(int)stream, size*count, ptr); 402 | if (r >= 0) 403 | return r; 404 | 405 | return 0; 406 | } 407 | 408 | size_t fwrite(const void * ptr, size_t size, size_t count, FILE * stream) 409 | { 410 | int w; 411 | // todo: long multiplier 412 | w = Fwrite((short)(int)stream, size*count, ptr); 413 | if (w >= 0) 414 | return w; 415 | 416 | return 0; 417 | } 418 | 419 | int fseek(FILE * stream, long int offset, int origin) 420 | { 421 | int pos; 422 | pos = Fseek(offset, (short)(int)stream, (origin==SEEK_SET) ? 0 : (origin==SEEK_CUR) ? 1 : 2); 423 | 424 | if (pos >= 0) 425 | return 0; 426 | 427 | return -1; 428 | } 429 | 430 | long int ftell(FILE * stream) 431 | { 432 | int pos; 433 | pos = Fseek(0, (short)(int)stream, 1); 434 | 435 | if (pos >= 0) 436 | return pos; 437 | 438 | return -1; 439 | } 440 | 441 | int fgetc(FILE * stream) 442 | { 443 | int r; 444 | char c = EOF; 445 | r = Fread((short)(int)stream, 1, &c); 446 | if (r > 0) 447 | return (int)c; 448 | 449 | return EOF; 450 | } 451 | 452 | // ---------------------------------------------------------------------------------------- 453 | 454 | }; //end extern "C" 455 | 456 | // ---------------------------------------------------------------------------------------- 457 | 458 | // ---------------------------------------------------------------------------------------- 459 | // This is a dummy class to force a static initialisation and destruction lists 460 | // to be built by gcc. 461 | 462 | struct MicroStartupForceStaticCtorDtor 463 | { 464 | int m_data; 465 | MicroStartupForceStaticCtorDtor() 466 | { 467 | m_data = 10; 468 | } 469 | ~MicroStartupForceStaticCtorDtor() 470 | { 471 | //printf("static destruct %d\r\n", m_data); 472 | // dml: dtor must do something, otherwise GCC optimizer will prune the __DTOR_LIST__ 473 | // and cause the link step to fail. 474 | m_data = 0; 475 | } 476 | }; 477 | 478 | MicroStartupForceStaticCtorDtor ctordtor; 479 | 480 | // ---------------------------------------------------------------------------------------- 481 | // This is required for basic std::list support 482 | 483 | /* 484 | #include 485 | 486 | namespace std 487 | { 488 | namespace __detail 489 | { 490 | void 491 | _List_node_base::_M_hook(std::__detail::_List_node_base* __position) 492 | { 493 | this->_M_next = __position; 494 | this->_M_prev = __position->_M_prev; 495 | __position->_M_prev->_M_next = this; 496 | __position->_M_prev = this; 497 | } 498 | 499 | void 500 | _List_node_base::_M_unhook() 501 | { 502 | _List_node_base* const __next_node = this->_M_next; 503 | _List_node_base* const __prev_node = this->_M_prev; 504 | __prev_node->_M_next = __next_node; 505 | __next_node->_M_prev = __prev_node; 506 | } 507 | } 508 | } 509 | 510 | */ 511 | 512 | // ---------------------------------------------------------------------------------------- 513 | 514 | #pragma GCC diagnostic pop 515 | 516 | // ---------------------------------------------------------------------------------------- 517 | -------------------------------------------------------------------------------- /barebones/lolworld.cpp: -------------------------------------------------------------------------------- 1 | //====================================================================================================================== 2 | // BrownELF GCC example: simple hello world 3 | //====================================================================================================================== 4 | 5 | //---------------------------------------------------------------------------------------------------------------------- 6 | 7 | // --------------------------------------------------------------------------------------------------------------------- 8 | // system headers 9 | 10 | #include 11 | #include 12 | #include // for atexit() 13 | #include // for printf va_args etc. 14 | 15 | // custom printf which can be redirected anywhere 16 | extern "C" int debug_printf(const char *pFormat, ...); 17 | 18 | // ===================================================================================================================== 19 | // program entrypoint 20 | // ===================================================================================================================== 21 | 22 | int main(int argc, char ** argv) 23 | { 24 | debug_printf("Trololololworld! %d %x\n", 50, 50); 25 | 26 | Crawcin(); 27 | 28 | return 0; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /barebones/obj/dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/barebones/obj/dummy -------------------------------------------------------------------------------- /barebones/printf.c: -------------------------------------------------------------------------------- 1 | //====================================================================================================================== 2 | // BrownELF example: printf redirection 3 | //====================================================================================================================== 4 | 5 | // --------------------------------------------------------------------------------------------------------------------- 6 | // system headers 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | // --------------------------------------------------------------------------------------------------------------------- 14 | 15 | int debug_printf(const char *pFormat, ...) 16 | { 17 | char buf[4096]; 18 | int len = 0; 19 | va_list pArg; 20 | va_start(pArg, pFormat); 21 | len = vsnprintf(buf, 1000, pFormat, pArg); 22 | va_end(pArg); 23 | 24 | // route to TOS console if display is not locked for graphics 25 | //if (!g_displaylocked) 26 | { 27 | char *pscan = buf; 28 | while (*pscan) 29 | { 30 | unsigned short c = *pscan++; 31 | if (c == 10) 32 | Bconout(2, 13); 33 | Bconout(2, c); 34 | } 35 | } 36 | 37 | //steem_print(buf); 38 | //hatari_natfeats_print(buf); 39 | //engine_print(buf); 40 | 41 | return len; 42 | } 43 | -------------------------------------------------------------------------------- /barebones/vsnprint.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Patrick Powell 1995 3 | * This code is based on code written by Patrick Powell (papowell@astart.com) 4 | * It may be used for any purpose as long as this notice remains intact 5 | * on all source code distributions 6 | */ 7 | 8 | /************************************************************** 9 | * Original: 10 | * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 11 | * A bombproof version of doprnt (dopr) included. 12 | * Sigh. This sort of thing is always nasty do deal with. Note that 13 | * the version here does not include floating point... 14 | * 15 | * snprintf() is used instead of sprintf() as it does limit checks 16 | * for string length. This covers a nasty loophole. 17 | * 18 | * The other functions are there to prevent NULL pointers from 19 | * causing nast effects. 20 | * 21 | * More Recently: 22 | * Brandon Long 9/15/96 for mutt 0.43 23 | * This was ugly. It is still ugly. I opted out of floating point 24 | * numbers, but the formatter understands just about everything 25 | * from the normal C string format, at least as far as I can tell from 26 | * the Solaris 2.5 printf(3S) man page. 27 | * 28 | * Brandon Long 10/22/97 for mutt 0.87.1 29 | * Ok, added some minimal floating point support, which means this 30 | * probably requires libm on most operating systems. Don't yet 31 | * support the exponent (e,E) and sigfig (g,G). Also, fmtint() 32 | * was pretty badly broken, it just wasn't being exercised in ways 33 | * which showed it, so that's been fixed. Also, formated the code 34 | * to mutt conventions, and removed dead code left over from the 35 | * original. Also, there is now a builtin-test, just compile with: 36 | * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm 37 | * and run snprintf for results. 38 | * 39 | * Thomas Roessler 01/27/98 for mutt 0.89i 40 | * The PGP code was using unsigned hexadecimal formats. 41 | * Unfortunately, unsigned formats simply didn't work. 42 | * 43 | * Michael Elkins 03/05/98 for mutt 0.90.8 44 | * The original code assumed that both snprintf() and vsnprintf() were 45 | * missing. Some systems only have snprintf() but not vsnprintf(), so 46 | * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. 47 | * 48 | * Andrew Tridgell (tridge@samba.org) Oct 1998 49 | * fixed handling of %.0f 50 | * added test for HAVE_LONG_DOUBLE 51 | * 52 | * dml 53 | * some fixes for float handling 54 | * 55 | * 56 | **************************************************************/ 57 | 58 | //#include "config.h" 59 | 60 | #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) 61 | 62 | // dml: pull in some TOS bindings 63 | #include 64 | #define HAVE_STDARG_H 65 | // disable floating point support to avoid illegal/linef bombs on machines without FPU 66 | //#define VSN_FLOAT 67 | #undef HAVE_LONG_DOUBLE 68 | 69 | #include 70 | //#include 71 | #include 72 | 73 | static __inline int isdigit(int c) { return (c >= '0' && c <= '9') ? 1 : 0; } 74 | 75 | /* Define this as a fall through, HAVE_STDARG_H is probably already set */ 76 | 77 | #define HAVE_VARARGS_H 78 | 79 | 80 | /* varargs declarations: */ 81 | 82 | #if defined(HAVE_STDARG_H) 83 | # include 84 | # define HAVE_STDARGS /* let's hope that works everywhere (mj) */ 85 | # define VA_LOCAL_DECL va_list ap 86 | # define VA_START(f) va_start(ap, f) 87 | # define VA_SHIFT(v,t) ; /* no-op for ANSI */ 88 | # define VA_END va_end(ap) 89 | #else 90 | # if defined(HAVE_VARARGS_H) 91 | # include 92 | # undef HAVE_STDARGS 93 | # define VA_LOCAL_DECL va_list ap 94 | # define VA_START(f) va_start(ap) /* f is ignored! */ 95 | # define VA_SHIFT(v,t) v = va_arg(ap,t) 96 | # define VA_END va_end(ap) 97 | # else 98 | /*XX ** NO VARARGS ** XX*/ 99 | # endif 100 | #endif 101 | 102 | #ifdef VSN_FLOAT 103 | #ifdef HAVE_LONG_DOUBLE 104 | #define LDOUBLE long double 105 | #else 106 | #define LDOUBLE double 107 | #endif 108 | #else 109 | #define LDOUBLE int 110 | #endif 111 | 112 | int snprintf (char *str, size_t count, const char *fmt, ...); 113 | int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); 114 | 115 | static void dopr (char *buffer, size_t maxlen, const char *format, 116 | va_list args); 117 | static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, 118 | char *value, int flags, int min, int max); 119 | static void fmtint (char *buffer, size_t *currlen, size_t maxlen, 120 | long value, int base, int min, int max, int flags); 121 | #ifdef VSN_FLOAT 122 | static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, 123 | LDOUBLE fvalue, int min, int max, int flags); 124 | #endif 125 | static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); 126 | 127 | /* 128 | * dopr(): poor man's version of doprintf 129 | */ 130 | 131 | /* format read states */ 132 | #define DP_S_DEFAULT 0 133 | #define DP_S_FLAGS 1 134 | #define DP_S_MIN 2 135 | #define DP_S_DOT 3 136 | #define DP_S_MAX 4 137 | #define DP_S_MOD 5 138 | #define DP_S_CONV 6 139 | #define DP_S_DONE 7 140 | 141 | /* format flags - Bits */ 142 | #define DP_F_MINUS (1 << 0) 143 | #define DP_F_PLUS (1 << 1) 144 | #define DP_F_SPACE (1 << 2) 145 | #define DP_F_NUM (1 << 3) 146 | #define DP_F_ZERO (1 << 4) 147 | #define DP_F_UP (1 << 5) 148 | #define DP_F_UNSIGNED (1 << 6) 149 | 150 | /* Conversion Flags */ 151 | #define DP_C_SHORT 1 152 | #define DP_C_LONG 2 153 | #define DP_C_LDOUBLE 3 154 | 155 | #define char_to_int(p) (p - '0') 156 | #define MAX(p,q) ((p >= q) ? p : q) 157 | 158 | static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) 159 | { 160 | char ch; 161 | long value; 162 | LDOUBLE fvalue; 163 | char *strvalue; 164 | int min; 165 | int max; 166 | int state; 167 | int flags; 168 | int cflags; 169 | size_t currlen; 170 | 171 | state = DP_S_DEFAULT; 172 | currlen = flags = cflags = min = 0; 173 | max = -1; 174 | ch = *format++; 175 | 176 | while (state != DP_S_DONE) 177 | { 178 | if ((ch == '\0') || (currlen >= maxlen)) 179 | state = DP_S_DONE; 180 | 181 | switch(state) 182 | { 183 | case DP_S_DEFAULT: 184 | if (ch == '%') 185 | state = DP_S_FLAGS; 186 | else 187 | dopr_outch (buffer, &currlen, maxlen, ch); 188 | ch = *format++; 189 | break; 190 | case DP_S_FLAGS: 191 | switch (ch) 192 | { 193 | case '-': 194 | flags |= DP_F_MINUS; 195 | ch = *format++; 196 | break; 197 | case '+': 198 | flags |= DP_F_PLUS; 199 | ch = *format++; 200 | break; 201 | case ' ': 202 | flags |= DP_F_SPACE; 203 | ch = *format++; 204 | break; 205 | case '#': 206 | flags |= DP_F_NUM; 207 | ch = *format++; 208 | break; 209 | case '0': 210 | flags |= DP_F_ZERO; 211 | ch = *format++; 212 | break; 213 | default: 214 | state = DP_S_MIN; 215 | break; 216 | } 217 | break; 218 | case DP_S_MIN: 219 | if (isdigit(ch)) 220 | { 221 | min = 10*min + char_to_int (ch); 222 | ch = *format++; 223 | } 224 | else if (ch == '*') 225 | { 226 | min = va_arg (args, int); 227 | ch = *format++; 228 | state = DP_S_DOT; 229 | } 230 | else 231 | state = DP_S_DOT; 232 | break; 233 | case DP_S_DOT: 234 | if (ch == '.') 235 | { 236 | state = DP_S_MAX; 237 | ch = *format++; 238 | } 239 | else 240 | state = DP_S_MOD; 241 | break; 242 | case DP_S_MAX: 243 | if (isdigit(ch)) 244 | { 245 | if (max < 0) 246 | max = 0; 247 | max = 10*max + char_to_int (ch); 248 | ch = *format++; 249 | } 250 | else if (ch == '*') 251 | { 252 | max = va_arg (args, int); 253 | ch = *format++; 254 | state = DP_S_MOD; 255 | } 256 | else 257 | state = DP_S_MOD; 258 | break; 259 | case DP_S_MOD: 260 | /* Currently, we don't support Long Long, bummer */ 261 | switch (ch) 262 | { 263 | case 'h': 264 | cflags = DP_C_SHORT; 265 | ch = *format++; 266 | break; 267 | case 'l': 268 | cflags = DP_C_LONG; 269 | ch = *format++; 270 | break; 271 | case 'L': 272 | cflags = DP_C_LDOUBLE; 273 | ch = *format++; 274 | break; 275 | default: 276 | break; 277 | } 278 | state = DP_S_CONV; 279 | break; 280 | case DP_S_CONV: 281 | switch (ch) 282 | { 283 | case 'd': 284 | case 'i': 285 | if (cflags == DP_C_SHORT) 286 | value = va_arg (args, /*short*/ int); 287 | else if (cflags == DP_C_LONG) 288 | value = va_arg (args, long int); 289 | else 290 | value = va_arg (args, int); 291 | fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); 292 | break; 293 | case 'o': 294 | flags |= DP_F_UNSIGNED; 295 | if (cflags == DP_C_SHORT) 296 | value = va_arg (args, unsigned /*short*/ int); 297 | else if (cflags == DP_C_LONG) 298 | value = va_arg (args, unsigned long int); 299 | else 300 | value = va_arg (args, unsigned int); 301 | fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); 302 | break; 303 | case 'u': 304 | flags |= DP_F_UNSIGNED; 305 | if (cflags == DP_C_SHORT) 306 | value = va_arg (args, unsigned /*short*/ int); 307 | else if (cflags == DP_C_LONG) 308 | value = va_arg (args, unsigned long int); 309 | else 310 | value = va_arg (args, unsigned int); 311 | fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); 312 | break; 313 | case 'X': 314 | flags |= DP_F_UP; 315 | case 'x': 316 | flags |= DP_F_UNSIGNED; 317 | if (cflags == DP_C_SHORT) 318 | value = va_arg (args, unsigned /*short*/ int); 319 | else if (cflags == DP_C_LONG) 320 | value = va_arg (args, unsigned long int); 321 | else 322 | value = va_arg (args, unsigned int); 323 | fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); 324 | break; 325 | #ifdef VSN_FLOAT 326 | case 'f': 327 | if (cflags == DP_C_LDOUBLE) 328 | fvalue = va_arg (args, LDOUBLE); 329 | else 330 | fvalue = va_arg (args, double); 331 | /* um, floating point? */ 332 | fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); 333 | break; 334 | #endif 335 | case 'E': 336 | flags |= DP_F_UP; 337 | case 'e': 338 | if (cflags == DP_C_LDOUBLE) 339 | fvalue = va_arg (args, LDOUBLE); 340 | else 341 | fvalue = va_arg (args, double); 342 | break; 343 | case 'G': 344 | flags |= DP_F_UP; 345 | case 'g': 346 | if (cflags == DP_C_LDOUBLE) 347 | fvalue = va_arg (args, LDOUBLE); 348 | else 349 | fvalue = va_arg (args, double); 350 | break; 351 | case 'c': 352 | dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); 353 | break; 354 | case 's': 355 | strvalue = va_arg (args, char *); 356 | if (max < 0) 357 | max = maxlen; /* ie, no max */ 358 | fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); 359 | break; 360 | case 'p': 361 | strvalue = va_arg (args, void *); 362 | fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); 363 | break; 364 | case 'n': 365 | if (cflags == DP_C_SHORT) 366 | { 367 | short int *num; 368 | num = va_arg (args, short int *); 369 | *num = currlen; 370 | } 371 | else if (cflags == DP_C_LONG) 372 | { 373 | long int *num; 374 | num = va_arg (args, long int *); 375 | *num = currlen; 376 | } 377 | else 378 | { 379 | int *num; 380 | num = va_arg (args, int *); 381 | *num = currlen; 382 | } 383 | break; 384 | case '%': 385 | dopr_outch (buffer, &currlen, maxlen, ch); 386 | break; 387 | case 'w': 388 | /* not supported yet, treat as next char */ 389 | ch = *format++; 390 | break; 391 | default: 392 | /* Unknown, skip */ 393 | break; 394 | } 395 | ch = *format++; 396 | state = DP_S_DEFAULT; 397 | flags = cflags = min = 0; 398 | max = -1; 399 | break; 400 | case DP_S_DONE: 401 | break; 402 | default: 403 | /* hmm? */ 404 | break; /* some picky compilers need this */ 405 | } 406 | } 407 | if (currlen < maxlen - 1) 408 | buffer[currlen] = '\0'; 409 | else 410 | buffer[maxlen - 1] = '\0'; 411 | } 412 | 413 | static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, 414 | char *value, int flags, int min, int max) 415 | { 416 | int padlen, strln; /* amount to pad */ 417 | int cnt = 0; 418 | 419 | if (value == 0) 420 | { 421 | value = ""; 422 | } 423 | 424 | for (strln = 0; value[strln]; ++strln); /* strlen */ 425 | padlen = min - strln; 426 | if (padlen < 0) 427 | padlen = 0; 428 | if (flags & DP_F_MINUS) 429 | padlen = -padlen; /* Left Justify */ 430 | 431 | while ((padlen > 0) && (cnt < max)) 432 | { 433 | dopr_outch (buffer, currlen, maxlen, ' '); 434 | --padlen; 435 | ++cnt; 436 | } 437 | while (*value && (cnt < max)) 438 | { 439 | dopr_outch (buffer, currlen, maxlen, *value++); 440 | ++cnt; 441 | } 442 | while ((padlen < 0) && (cnt < max)) 443 | { 444 | dopr_outch (buffer, currlen, maxlen, ' '); 445 | ++padlen; 446 | ++cnt; 447 | } 448 | } 449 | 450 | /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ 451 | 452 | static void fmtint (char *buffer, size_t *currlen, size_t maxlen, 453 | long value, int base, int min, int max, int flags) 454 | { 455 | int signvalue = 0; 456 | unsigned long uvalue; 457 | char convert[20]; 458 | int place = 0; 459 | int spadlen = 0; /* amount to space pad */ 460 | int zpadlen = 0; /* amount to zero pad */ 461 | int caps = 0; 462 | 463 | if (max < 0) 464 | max = 0; 465 | 466 | uvalue = value; 467 | 468 | if(!(flags & DP_F_UNSIGNED)) 469 | { 470 | if( value < 0 ) { 471 | signvalue = '-'; 472 | uvalue = -value; 473 | } 474 | else 475 | if (flags & DP_F_PLUS) /* Do a sign (+/i) */ 476 | signvalue = '+'; 477 | else 478 | if (flags & DP_F_SPACE) 479 | signvalue = ' '; 480 | } 481 | 482 | if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ 483 | 484 | do { 485 | convert[place++] = 486 | (caps? "0123456789ABCDEF":"0123456789abcdef") 487 | [uvalue % (unsigned)base ]; 488 | uvalue = (uvalue / (unsigned)base ); 489 | } while(uvalue && (place < 20)); 490 | if (place == 20) place--; 491 | convert[place] = 0; 492 | 493 | zpadlen = max - place; 494 | spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); 495 | if (zpadlen < 0) zpadlen = 0; 496 | if (spadlen < 0) spadlen = 0; 497 | if (flags & DP_F_ZERO) 498 | { 499 | zpadlen = MAX(zpadlen, spadlen); 500 | spadlen = 0; 501 | } 502 | if (flags & DP_F_MINUS) 503 | spadlen = -spadlen; /* Left Justifty */ 504 | 505 | #ifdef DEBUG_SNPRINTF 506 | dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", 507 | zpadlen, spadlen, min, max, place)); 508 | #endif 509 | 510 | /* Spaces */ 511 | while (spadlen > 0) 512 | { 513 | dopr_outch (buffer, currlen, maxlen, ' '); 514 | --spadlen; 515 | } 516 | 517 | /* Sign */ 518 | if (signvalue) 519 | dopr_outch (buffer, currlen, maxlen, signvalue); 520 | 521 | /* Zeros */ 522 | if (zpadlen > 0) 523 | { 524 | while (zpadlen > 0) 525 | { 526 | dopr_outch (buffer, currlen, maxlen, '0'); 527 | --zpadlen; 528 | } 529 | } 530 | 531 | /* Digits */ 532 | while (place > 0) 533 | dopr_outch (buffer, currlen, maxlen, convert[--place]); 534 | 535 | /* Left Justified spaces */ 536 | while (spadlen < 0) { 537 | dopr_outch (buffer, currlen, maxlen, ' '); 538 | ++spadlen; 539 | } 540 | } 541 | 542 | #ifdef VSN_FLOAT 543 | 544 | static LDOUBLE abs_val (LDOUBLE value) 545 | { 546 | LDOUBLE result = value; 547 | 548 | if (value < 0) 549 | result = -value; 550 | 551 | return result; 552 | } 553 | 554 | static LDOUBLE pow10 (int exp) 555 | { 556 | LDOUBLE result = 1; 557 | 558 | while (exp) 559 | { 560 | result *= 10; 561 | exp--; 562 | } 563 | 564 | return result; 565 | } 566 | 567 | static long round (LDOUBLE value) 568 | { 569 | long intpart; 570 | 571 | intpart = value; 572 | value = value - intpart; 573 | if (value >= 0.5) 574 | intpart++; 575 | 576 | return intpart; 577 | } 578 | 579 | static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, 580 | LDOUBLE fvalue, int min, int max, int flags) 581 | { 582 | int signvalue = 0; 583 | LDOUBLE ufvalue; 584 | char iconvert[20]; 585 | char fconvert[20]; 586 | int iplace = 0; 587 | int fplace = 0; 588 | int padlen = 0; /* amount to pad */ 589 | int zpadlen = 0; 590 | int caps = 0; 591 | long intpart; 592 | long fracpart; 593 | 594 | /* 595 | * AIX manpage says the default is 0, but Solaris says the default 596 | * is 6, and sprintf on AIX defaults to 6 597 | */ 598 | if (max < 0) 599 | max = 6; 600 | 601 | ufvalue = abs_val (fvalue); 602 | 603 | if (fvalue < 0) 604 | signvalue = '-'; 605 | else 606 | if (flags & DP_F_PLUS) /* Do a sign (+/i) */ 607 | signvalue = '+'; 608 | else 609 | if (flags & DP_F_SPACE) 610 | signvalue = ' '; 611 | 612 | #if 0 613 | if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ 614 | #endif 615 | 616 | intpart = qfloor(ufvalue); 617 | 618 | /* 619 | * Sorry, we only support 9 digits past the decimal because of our 620 | * conversion method 621 | */ 622 | if (max > 9) 623 | max = 9; 624 | 625 | /* We "cheat" by converting the fractional part to integer by 626 | * multiplying by a factor of 10 627 | */ 628 | fracpart = ((pow10 (max)) * (ufvalue - intpart)); 629 | // fracpart = round ((pow10 (max)) * (ufvalue - intpart)); 630 | 631 | if (fracpart >= pow10 (max)) 632 | { 633 | intpart++; 634 | fracpart -= pow10 (max); 635 | } 636 | 637 | #ifdef DEBUG_SNPRINTF 638 | dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart)); 639 | #endif 640 | 641 | /* Convert integer part */ 642 | do { 643 | iconvert[iplace++] = 644 | (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; 645 | intpart = (intpart / 10); 646 | } while(intpart && (iplace < 20)); 647 | if (iplace == 20) iplace--; 648 | iconvert[iplace] = 0; 649 | 650 | /* Convert fractional part */ 651 | do { 652 | fconvert[fplace++] = 653 | (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; 654 | fracpart = (fracpart / 10); 655 | } while(/*fracpart &&*/ (fplace < max)); 656 | if (fplace == 20) fplace--; 657 | fconvert[fplace] = 0; 658 | 659 | /* -1 for decimal point, another -1 if we are printing a sign */ 660 | padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 661 | zpadlen = max - fplace; 662 | if (zpadlen < 0) 663 | zpadlen = 0; 664 | if (padlen < 0) 665 | padlen = 0; 666 | if (flags & DP_F_MINUS) 667 | padlen = -padlen; /* Left Justifty */ 668 | 669 | if ((flags & DP_F_ZERO) && (padlen > 0)) 670 | { 671 | if (signvalue) 672 | { 673 | dopr_outch (buffer, currlen, maxlen, signvalue); 674 | --padlen; 675 | signvalue = 0; 676 | } 677 | while (padlen > 0) 678 | { 679 | dopr_outch (buffer, currlen, maxlen, '0'); 680 | --padlen; 681 | } 682 | } 683 | while (padlen > 0) 684 | { 685 | dopr_outch (buffer, currlen, maxlen, ' '); 686 | --padlen; 687 | } 688 | if (signvalue) 689 | dopr_outch (buffer, currlen, maxlen, signvalue); 690 | 691 | while (iplace > 0) 692 | dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); 693 | 694 | /* 695 | * Decimal point. This should probably use locale to find the correct 696 | * char to print out. 697 | */ 698 | if (max > 0) 699 | { 700 | dopr_outch (buffer, currlen, maxlen, '.'); 701 | 702 | while (fplace > 0) 703 | dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); 704 | } 705 | 706 | while (zpadlen > 0) 707 | { 708 | dopr_outch (buffer, currlen, maxlen, '0'); 709 | --zpadlen; 710 | } 711 | 712 | while (padlen < 0) 713 | { 714 | dopr_outch (buffer, currlen, maxlen, ' '); 715 | ++padlen; 716 | } 717 | } 718 | #endif 719 | 720 | static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) 721 | { 722 | if (*currlen < maxlen) 723 | buffer[(*currlen)++] = c; 724 | } 725 | 726 | #ifndef HAVE_VSNPRINTF 727 | int vsnprintf (char *str, size_t count, const char *fmt, va_list args) 728 | { 729 | str[0] = 0; 730 | dopr(str, count, fmt, args); 731 | return(strlen(str)); 732 | } 733 | #endif /* !HAVE_VSNPRINTF */ 734 | 735 | #ifndef HAVE_SNPRINTF 736 | /* VARARGS3 */ 737 | #ifdef HAVE_STDARGS 738 | int snprintf (char *str,size_t count,const char *fmt,...) 739 | #else 740 | int snprintf (va_alist) va_dcl 741 | #endif 742 | { 743 | #ifndef HAVE_STDARGS 744 | char *str; 745 | size_t count; 746 | char *fmt; 747 | #endif 748 | VA_LOCAL_DECL; 749 | 750 | VA_START (fmt); 751 | VA_SHIFT (str, char *); 752 | VA_SHIFT (count, size_t ); 753 | VA_SHIFT (fmt, char *); 754 | (void) vsnprintf(str, count, fmt, ap); 755 | VA_END; 756 | return(strlen(str)); 757 | } 758 | #endif /* !HAVE_SNPRINTF */ 759 | 760 | #ifdef TEST_SNPRINTF 761 | #ifndef LONG_STRING 762 | #define LONG_STRING 1024 763 | #endif 764 | int main (void) 765 | { 766 | char buf1[LONG_STRING]; 767 | char buf2[LONG_STRING]; 768 | char *fp_fmt[] = { 769 | "%-1.5f", 770 | "%1.5f", 771 | "%123.9f", 772 | "%10.5f", 773 | "% 10.5f", 774 | "%+22.9f", 775 | "%+4.9f", 776 | "%01.3f", 777 | "%4f", 778 | "%3.1f", 779 | "%3.2f", 780 | "%.0f", 781 | "%.1f", 782 | NULL 783 | }; 784 | double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 785 | 0.9996, 1.996, 4.136, 0}; 786 | char *int_fmt[] = { 787 | "%-1.5d", 788 | "%1.5d", 789 | "%123.9d", 790 | "%5.5d", 791 | "%10.5d", 792 | "% 10.5d", 793 | "%+22.33d", 794 | "%01.3d", 795 | "%4d", 796 | NULL 797 | }; 798 | long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; 799 | int x, y; 800 | int fail = 0; 801 | int num = 0; 802 | 803 | printf ("Testing snprintf format codes against system sprintf...\n"); 804 | 805 | for (x = 0; fp_fmt[x] != NULL ; x++) 806 | for (y = 0; fp_nums[y] != 0 ; y++) 807 | { 808 | snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); 809 | sprintf (buf2, fp_fmt[x], fp_nums[y]); 810 | if (strcmp (buf1, buf2)) 811 | { 812 | printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", 813 | fp_fmt[x], buf1, buf2); 814 | fail++; 815 | } 816 | num++; 817 | } 818 | 819 | for (x = 0; int_fmt[x] != NULL ; x++) 820 | for (y = 0; int_nums[y] != 0 ; y++) 821 | { 822 | snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); 823 | sprintf (buf2, int_fmt[x], int_nums[y]); 824 | if (strcmp (buf1, buf2)) 825 | { 826 | printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", 827 | int_fmt[x], buf1, buf2); 828 | fail++; 829 | } 830 | num++; 831 | } 832 | printf ("%d tests failed out of %d.\n", fail, num); 833 | } 834 | #endif /* SNPRINTF_TEST */ 835 | 836 | #endif /* !HAVE_SNPRINTF */ 837 | /* Shut up the compaq compiler which hates empty files. This will 838 | never be linked anyway. */ 839 | static void do_nothing() { return; } 840 | 841 | 842 | // dml: this should really be in os.c but due to VA_ARGS definitions local to this file it lives here... 843 | #ifdef MINIMAL 844 | #ifdef HAVE_STDARGS 845 | int sprintf (char *str,const char *fmt,...) 846 | #else 847 | int sprintf (va_alist) va_dcl 848 | #endif 849 | { 850 | #ifndef HAVE_STDARGS 851 | char *str; 852 | char *fmt; 853 | #endif 854 | VA_LOCAL_DECL; 855 | 856 | VA_START (fmt); 857 | VA_SHIFT (str, char *); 858 | VA_SHIFT (fmt, char *); 859 | (void) vsnprintf(str, 1000, fmt, ap); 860 | VA_END; 861 | return(strlen(str)); 862 | } 863 | 864 | /* 865 | int vfprintf(FILE * stream, const char *fmt, va_list ap) 866 | { 867 | return _putf(_write, stream->iob_fd, fmt, ap); 868 | } 869 | */ 870 | 871 | #endif -------------------------------------------------------------------------------- /bigbrowngemlib.sh: -------------------------------------------------------------------------------- 1 | set -e #stop on any error encountered 2 | #set -x #echo all commands 3 | 4 | fixregs() 5 | { 6 | sed -i -e "s/sp/%sp/gI" \ 7 | -e "s/a0/%a0/gI" \ 8 | -e "s/a1/%a1/gI" \ 9 | -e "s/a2/%a2/gI" \ 10 | -e "s/a3/%a3/gI" \ 11 | -e "s/a4/%a4/gI" \ 12 | -e "s/a5/%a5/gI" \ 13 | -e "s/a6/%a6/gI" \ 14 | -e "s/a7/%a7/gI" \ 15 | -e "s/d0/%d0/gI" \ 16 | -e "s/d1/%d1/gI" \ 17 | -e "s/d2/%d2/gI" \ 18 | -e "s/d3/%d3/gI" \ 19 | -e "s/d4/%d4/gI" \ 20 | -e "s/d5/%d5/gI" \ 21 | -e "s/d6/%d6/gI" \ 22 | -e "s/d7/%d7/gI" -i $1 23 | } 24 | 25 | #wget http://arnaud.bercegeay.free.fr/gemlib/gemlib-0.44.0-src.tgz 26 | tar -zxvf gemlib-0.44.0-src.tgz 27 | cd gemlib-0.44.0 28 | sed -i -e "s/CROSS = no/CROSS = yes/gI" -e "s/m68k-atari-mint/m68k-ataribrownest-elf/gI" CONFIGVARS 29 | fixregs gemlib/gem_vdiP.h 30 | fixregs gemlib/gem_vdiP.h 31 | fixregs gemlib/_gc_asm_aes.S 32 | fixregs gemlib/_gc_asm_vdi.S 33 | fixregs gemlib/_gc_asm_vq_gdos.S 34 | fixregs gemlib/_gc_asm_vq_vgdos.S 35 | make 36 | 37 | -------------------------------------------------------------------------------- /bigbrownlibcmini.sh: -------------------------------------------------------------------------------- 1 | set -e #stop on any error encountered 2 | #set -x #echo all commands 3 | 4 | fixregs() 5 | { 6 | sed -i -e "s/sp/%sp/gI" \ 7 | -e "s/a0/%a0/gI" \ 8 | -e "s/a1/%a1/gI" \ 9 | -e "s/a2/%a2/gI" \ 10 | -e "s/a3/%a3/gI" \ 11 | -e "s/a4/%a4/gI" \ 12 | -e "s/a5/%a5/gI" \ 13 | -e "s/a6/%a6/gI" \ 14 | -e "s/a7/%a7/gI" \ 15 | -e "s/d0/%d0/gI" \ 16 | -e "s/d1/%d1/gI" \ 17 | -e "s/d2/%d2/gI" \ 18 | -e "s/d3/%d3/gI" \ 19 | -e "s/d4/%d4/gI" \ 20 | -e "s/d5/%d5/gI" \ 21 | -e "s/d6/%d6/gI" \ 22 | -e "s/d7/%d7/gI" -i $1 23 | } 24 | echo Run me inside libcmini/trunk/libcmini 25 | sed -i -e "s/m68k-elf-/m68k-ataribrownest-elf-/gI" -e "s/COMPILE_ELF=N/COMPILE_ELF=Y/gI" Makefile 26 | fixregs sources/_normdf.S 27 | fixregs sources/checkcpu.S 28 | fixregs sources/frexp.S 29 | fixregs sources/getcookie.S 30 | sed -i "s/0x5%a0/0x5a0/gI" sources/getcookie.S 31 | fixregs sources/getsysvar.S 32 | fixregs sources/ldexp.S 33 | fixregs sources/modf.S 34 | fixregs sources/setstack.S 35 | fixregs sources/startup.S 36 | fixregs sources/setjmp.c 37 | fixregs sources/setjmp.c 38 | # This is wrong. gcc 6.2 will crash if a6 is added to the clobber list 39 | # so we remove it. No idea what will happen though. 40 | sed -i -e 's/, "%%a6"//gI' sources/setjmp.c 41 | sed -i -e "s/m68k-atari-mint-/m68k-ataribrownest-elf-/gI" tests/acctest/Makefile 42 | make 43 | -------------------------------------------------------------------------------- /brownart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/brownart.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # bigbrownbuild.sh 2 | 3 | ## What is this 4 | 5 | A collection of brown scripts that build brown compilers and libaries for the Atari ST series of computers. 6 | 7 | ## Notable features 8 | 9 | * link-time whole-program optimisation (inter-module calls & inlining) 10 | 11 | * improved optimiser 12 | 13 | * C++14, C++17 support 14 | 15 | * named section support via C and asm 16 | 17 | * proper C++ initialise/finalise sequence 18 | 19 | * GST extended symbols 20 | 21 | * can preview code generation in Godbolt/68k (try it live at http://brownbot.mooo.com) 22 | 23 | * path open for future gcc releases 24 | 25 | # Requirements 26 | 27 | The script will attempt to auto-fetch the required gcc/binutils/mintlib packages. If something goes wrong you'll have to modify the fetch URLs. 28 | 29 | Make sure you have installed the following libraries and tools. 30 | 31 | ### Linux/Windows 32 | 33 | * GMP (dev) (if you don't download prerequisites, see [GLOBAL_DOWNLOAD_PREREQUISITES](#GLOBAL_DOWNLOAD_PREREQUISITES)) 34 | 35 | * MPFR (dev) (if you don't download prerequisites, see [GLOBAL_DOWNLOAD_PREREQUISITES](#GLOBAL_DOWNLOAD_PREREQUISITES)) 36 | 37 | * MPC (dev) (if you don't download prerequisites, see [GLOBAL_DOWNLOAD_PREREQUISITES](#GLOBAL_DOWNLOAD_PREREQUISITES)) 38 | 39 | * bison-bin 40 | 41 | * flex-bin 42 | 43 | * flex-dev 44 | 45 | * texinfo 46 | 47 | GMP/MPFR/MPC are required for building gcc (if you don't download prerequisites, see [GLOBAL_DOWNLOAD_PREREQUISITES](#GLOBAL_DOWNLOAD_PREREQUISITES)), flex and bison for building MiNTlib. 48 | 49 | ### macOS 50 | 51 | Use Macports and install: 52 | 53 | * gmp (if you don't download prerequisites, see [GLOBAL_DOWNLOAD_PREREQUISITES](#GLOBAL_DOWNLOAD_PREREQUISITES)) 54 | 55 | * mpfr (if you don't download prerequisites, see [GLOBAL_DOWNLOAD_PREREQUISITES](#GLOBAL_DOWNLOAD_PREREQUISITES)) 56 | 57 | * libmpc (if you don't download prerequisites, see [GLOBAL_DOWNLOAD_PREREQUISITES](#GLOBAL_DOWNLOAD_PREREQUISITES)) 58 | 59 | * bison 60 | 61 | * flex 62 | 63 | * gsed 64 | 65 | * gnutar 66 | 67 | * wget 68 | 69 | # Installation 70 | 71 | Before running the script it is advised to open it and go through the "User definable stuff" settings. In brief they are: 72 | 73 | ### GLOBAL_OVERRIDE 74 | 75 | Set this to A if you want a completely automated run. 76 | 77 | ### GLOBAL_BUILD_FORTRAN 78 | 79 | Set this to 1 to build Fortran, anything else to skip building Fortran. 80 | 81 | ### GLOBAL_DOWNLOAD_PREREQUISITES 82 | 83 | Set this to 1 to download prerequisite libs such as MPC and MPFR automatically (without having to install them on the host machine) via the contrib/download_prerequisites script inside each gcc. Not tested extensively but it seems to work with gcc 4.6.4. 84 | 85 | ### BUILD_X_Y_Z 86 | 87 | Which gccs to build. 1=Build, anything else=Don't build. Can be toggled individually. 88 | 89 | ### BUILD_MINTLIB 90 | 91 | Only set this to nonzero when you do want to build mintlib. Note that if you don't build mintlib then libstdc++v3 will also fail to build, so you are advised to keep this on. 92 | 93 | ### CC?/CXX? 94 | 95 | The actual names of the compilers used to build our set of gccs. The names aretuned for ubuntu 17.10 so your mileage may vary! 96 | 97 | Also you might be able to build all gcc versions using one compiler. In Ubuntu 17.10 so many problems were encountered in Ubuntu (including Internal Compiler Errors) that this is now in full pendantic mode. Again, your mileage may vary! 98 | 99 | ### CROSS_COMPILING 100 | 101 | At first this sounds redundant given that the script produces a cross compiler to begin with. This setting should be enabled if the cross compiler is not going to be executed in a different platform than it is built. 102 | 103 | For example: We want to build a 68k cross compiler on a x86 PC that will execute on an ARM processor. 104 | 105 | ### INSTALL_PREFIX 106 | 107 | Where the compiler(s) will be installed. Defaults to ${HOME}/brown. Take care that you don't choose a path that requires root privileges. (In this case you will need to run the script as root) 108 | 109 | ### Other notes 110 | The script will install things to ```INSTALL_PREFIX``` and might need root privileges. Also it'll use ```$JMULT``` cores while building. If this is not to your liking then edit this script and change ```INSTALL_PREFIX``` to the path you would like to install to (including home folder) and ```SUDO``` to nothing if you don't need root rights. Also ```JMULT``` for number of build cores. Examples are inside the script's comments. Log files are written inside each build folder for each version of gcc built. So for example there's ```build-binutils-2.38/binutils_configure.log``, ```build-gcc-12.1.0/gcc_build.log``` and so on. 111 | 112 | # Testing 113 | 114 | Inside the folder ```barebones``` there exist test projects to verify that your gcc installation is sane. Just type ```make``` on installations that have make installed or run ```build.bat``` under Windows (especially if you built the toolchain(s) using MinGW). 115 | 116 | There is also a different example in the folder ```barebones-interop```. This illustrates how to set up a project to work with C and assembly. Consult the ```readme.md``` inside that folder for more information. 117 | 118 | # bigbrowngemlib.sh 119 | 120 | This is a work-in-progress script. Currently it cannot build GEMlib properly. Patches welcome! 121 | 122 | # bigbrownlibcmini.sh 123 | 124 | This is a work-in-progress script. Currently it cannot build GEMlib properly. Patches welcome! 125 | 126 | # Note for MinGW users 127 | 128 | Be warned that the compilation can take a very very VERY long time! If you can spare the RAM, we really recommend using a RAM drive! Our tests have shown that imdisk (http://www.ltr-data.se/opencode.html/#ImDisk) works fine. Of course take notice that you're doing this on your own, we won't accept any liability if something goes wrong with that!!!! 129 | 130 | # Building the "barebones" examples 131 | 132 | Download and build Brownout (https://github.com/ggnkua/brownout-git / https://bitbucket.org/ggnkua/brownout-git/) and place it in the ```barebones``` directory. 133 | 134 | If you have a command prompt that is able to run ```make``` (e.g. Linux, Cygwin, MinGW etc) then just type ```make``` (make sure your build cross gcc is in the PATH). Otherwise on Windows you can just run ```build.bat``` (edit ```GCCPATH``` to point to your toolchain path first). 135 | 136 | Note that this will build only for the latest supported cross gcc version. For older versions, some simple find and replaces should be enough. 137 | 138 | # Credits 139 | 140 | The bulk of the script was written by George 'GGN' Nakos, with enhancements from: 141 | 142 | * Douglas 'DML' Little 143 | * Patrice 'PMANDIN' Mandin 144 | * Troed 'TROED' Sångberg 145 | 146 | -------------------------------------------------------------------------------- /test-browntran/brownboot.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/test-browntran/brownboot.o -------------------------------------------------------------------------------- /test-browntran/brownboot.s: -------------------------------------------------------------------------------- 1 | *------------------------------------------------------------------------------* 2 | * BrownELF GCC startup: dml/2017 3 | *------------------------------------------------------------------------------* 4 | 5 | xdef ___cxa_pure_virtual 6 | xdef __ZSt17__throw_bad_allocv 7 | 8 | ; xdef _memcpy 9 | xdef _memset 10 | 11 | xref _main 12 | xref _exit 13 | xdef __exit 14 | xdef ___cxa_guard_acquire 15 | xdef ___cxa_guard_release 16 | 17 | ; xref ___libc_csu_init 18 | 19 | *------------------------------------------------------------------------------* 20 | 21 | BASEPAGE_SIZE = $100 22 | USPS = $100*4 23 | 24 | ifd ELF_CONFIG_STACK 25 | SSPS = (ELF_CONFIG_STACK) 26 | else 27 | SSPS = $4000 28 | endc 29 | 30 | bbreak macro 31 | andi #~2,ccr 32 | bvc.s * 33 | endm 34 | 35 | *------------------------------------------------------------------------------* 36 | __crt_entrypoint: xdef __crt_entrypoint 37 | _start: xdef _start 38 | *------------------------------------------------------------------------------* 39 | move.l 4(sp),a5 40 | *-------------------------------------------------------* 41 | * command info 42 | *-------------------------------------------------------* 43 | ; lea 128(a5),a4 44 | ; move.l a4,cli 45 | *-------------------------------------------------------* 46 | * Mshrink 47 | *-------------------------------------------------------* 48 | move.l 12(a5),d0 ; text segment 49 | add.l 20(a5),d0 ; data segment 50 | add.l 28(a5),d0 ; bss segment 51 | add.l #BASEPAGE_SIZE+USPS,d0 ; base page 52 | *-------------------------------------------------------* 53 | move.l a5,d1 ; address to basepage 54 | add.l d0,d1 ; end of program 55 | and.w #-16,d1 ; align stack 56 | move.l sp,d2 57 | move.l d1,sp ; temporary USP stackspace 58 | move.l d2,-(sp) 59 | *-------------------------------------------------------* 60 | move.l d0,-(sp) 61 | move.l a5,-(sp) 62 | clr.w -(sp) 63 | move.w #$4a,-(sp) 64 | trap #1 ; Mshrink 65 | lea 12(sp),sp 66 | *-------------------------------------------------------* 67 | * Program 68 | *-------------------------------------------------------* 69 | bsr user_start 70 | *-------------------------------------------------------* 71 | * Begone 72 | *-------------------------------------------------------* 73 | clr.w -(sp) ; Pterm0 74 | trap #1 75 | 76 | user_start: 77 | 78 | ; clear bss segment 79 | 80 | move.l $18(a5),a0 81 | move.l $1c(a5),d0 ;length of bss segment 82 | move.l d0,-(sp) 83 | pea 0.w 84 | move.l a0,-(sp) 85 | jsr _memset 86 | lea 12(sp),sp 87 | 88 | ; if (REDIRECT_OUTPUT_TO_SERIAL==1) 89 | ; ; redirect to serial 90 | ; 91 | ; move.w #2,-(sp) 92 | ; move.w #1,-(sp) 93 | ; move.w #$46,-(sp) 94 | ; trap #1 95 | ; addq.l #6,sp 96 | ; 97 | ; endif 98 | 99 | pea super_start 100 | move.w #38,-(sp) 101 | trap #14 102 | addq.l #6,sp 103 | 104 | rts 105 | 106 | ; -------------------------------------------------------------- 107 | super_start: 108 | ; -------------------------------------------------------------- 109 | lea new_ssp,a0 110 | move.l a0,d0 111 | subq.l #4,d0 112 | and.w #-16,d0 113 | move.l d0,a0 114 | move.l sp,-(a0) 115 | move.l usp,a1 116 | move.l a1,-(a0) 117 | move.l a0,sp 118 | 119 | ; __libc_csu_init(int argc, char **argv, char **envp); 120 | 121 | move.l #0,-(sp) 122 | pea dummy_argv 123 | pea dummy_envp 124 | ; jsr ___libc_csu_init 125 | lea 12(sp),sp 126 | 127 | move.l sp,entrypoint_ssp 128 | 129 | jsr _main 130 | 131 | ; link to high level exit(0) function on return 132 | pea 0.w 133 | jmp _exit 134 | 135 | __exit: 136 | 137 | ; level SSP, because exit() is a subroutine 138 | 139 | move.l entrypoint_ssp,sp 140 | 141 | move.l (sp)+,a0 142 | move.l a0,usp 143 | move.l (sp)+,sp 144 | rts 145 | 146 | ;; -------------------------------------------------------------- 147 | ;_memcpy: 148 | ;; -------------------------------------------------------------- 149 | ; rsreset 150 | ;; -------------------------------------------------------------- 151 | ;.sp_return: rs.l 1 152 | ;.sp_pdst: rs.l 1 153 | ;.sp_psrc: rs.l 1 154 | ;.sp_size: rs.l 1 155 | ;; -------------------------------------------------------------- 156 | ;; move.l .sp_pdst(sp),a0 157 | ;; move.l .sp_psrc(sp),a1 158 | ; move.l .sp_pdst(sp),d0 159 | ; move.l d0,a0 160 | ; move.l .sp_psrc(sp),d1 161 | ; move.l d1,a1 162 | ; or.w d0,d1 163 | ; btst #0,d1 164 | ; bne.s .memcpy_misaligned 165 | ; 166 | ; move.l .sp_size(sp),d1 167 | ; 168 | ; lsr.l #4,d1 ; num 16-byte blocks total 169 | ; move.l d1,d0 170 | ; swap d0 ; num 1mb blocks (64k * 16bytes) 171 | ; subq.w #1,d1 ; num 16-byte blocks remaining 172 | ; bcs.s .ev1mb 173 | ; 174 | ;.lp1mb: 175 | ;.lp16b: move.l (a1)+,(a0)+ 176 | ; move.l (a1)+,(a0)+ 177 | ; move.l (a1)+,(a0)+ 178 | ; move.l (a1)+,(a0)+ 179 | ; dbra d1,.lp16b 180 | ; 181 | ;.ev1mb: subq.w #1,d0 182 | ; bpl.s .lp1mb 183 | ; 184 | ; moveq #16-1,d1 185 | ; and.w .sp_size+2(sp),d1 186 | ; lsl.b #4+1,d1 187 | ; bcc.s .n8 188 | ; move.l (a1)+,(a0)+ 189 | ; move.l (a1)+,(a0)+ 190 | ;.n8: add.b d1,d1 191 | ; bcc.s .n4 192 | ; move.l (a1)+,(a0)+ 193 | ;.n4: add.b d1,d1 194 | ; bcc.s .n2 195 | ; move.w (a1)+,(a0)+ 196 | ;.n2: add.b d1,d1 197 | ; bcc.s .n1 198 | ; move.b (a1)+,(a0)+ 199 | ;.n1: 200 | ; move.l .sp_pdst(sp),d0 201 | ; rts 202 | ; 203 | ;.memcpy_misaligned: 204 | ; move.w a1,d1 205 | ; eor.w d0,d1 206 | ; btst #0,d1 207 | ; bne .memcpy_misaligned_sgl 208 | ; 209 | ;.memcpy_misaligned_pair: 210 | ; move.l .sp_size(sp),d1 211 | ; 212 | ; move.b (a1)+,(a0)+ 213 | ; subq.l #1,d1 214 | ; beq .done 215 | ; move.w d1,.sp_size+2(sp) 216 | ; 217 | ; lsr.l #4,d1 ; num 16-byte blocks total 218 | ; move.l d1,d0 219 | ; swap d0 ; num 1mb blocks (64k * 16bytes) 220 | ; subq.w #1,d1 ; num 16-byte blocks remaining 221 | ; bcs.s .ev1mc 222 | ; 223 | ;.lp1mc: 224 | ;.lp16c: move.l (a1)+,(a0)+ 225 | ; move.l (a1)+,(a0)+ 226 | ; move.l (a1)+,(a0)+ 227 | ; move.l (a1)+,(a0)+ 228 | ; dbra d1,.lp16c 229 | ; 230 | ;.ev1mc: subq.w #1,d0 231 | ; bpl.s .lp1mc 232 | ; 233 | ; moveq #16-1,d1 234 | ; and.w .sp_size+2(sp),d1 235 | ; lsl.b #4+1,d1 236 | ; bcc.s .n8c 237 | ; move.l (a1)+,(a0)+ 238 | ; move.l (a1)+,(a0)+ 239 | ;.n8c: add.b d1,d1 240 | ; bcc.s .n4c 241 | ; move.l (a1)+,(a0)+ 242 | ;.n4c: add.b d1,d1 243 | ; bcc.s .n2c 244 | ; move.w (a1)+,(a0)+ 245 | ;.n2c: add.b d1,d1 246 | ; bcc.s .n1c 247 | ; move.b (a1)+,(a0)+ 248 | ;.n1c: 249 | ;.done: move.l .sp_pdst(sp),d0 250 | ; rts 251 | ; 252 | ;.memcpy_misaligned_sgl: 253 | ; move.l .sp_size(sp),d1 254 | ; 255 | ; lsr.l #4,d1 ; num 16-byte blocks total 256 | ; move.l d1,d0 257 | ; swap d0 ; num 1mb blocks (64k * 16bytes) 258 | ; subq.w #1,d1 ; num 16-byte blocks remaining 259 | ; bcs.s .ev1md 260 | ; 261 | ;.lp1md: 262 | ;.lp16d: move.b (a1)+,(a0)+ 263 | ; move.b (a1)+,(a0)+ 264 | ; move.b (a1)+,(a0)+ 265 | ; move.b (a1)+,(a0)+ 266 | ; move.b (a1)+,(a0)+ 267 | ; move.b (a1)+,(a0)+ 268 | ; move.b (a1)+,(a0)+ 269 | ; move.b (a1)+,(a0)+ 270 | ; move.b (a1)+,(a0)+ 271 | ; move.b (a1)+,(a0)+ 272 | ; move.b (a1)+,(a0)+ 273 | ; move.b (a1)+,(a0)+ 274 | ; move.b (a1)+,(a0)+ 275 | ; move.b (a1)+,(a0)+ 276 | ; move.b (a1)+,(a0)+ 277 | ; move.b (a1)+,(a0)+ 278 | ; dbra d1,.lp16d 279 | ; 280 | ;.ev1md: subq.w #1,d0 281 | ; bpl.s .lp1md 282 | ; 283 | ;; copy remaining bytes, if any 284 | ; 285 | ; moveq #16-1,d1 286 | ; and.w .sp_size+2(sp),d1 287 | ; add.w d1,d1 288 | ; neg.w d1 289 | ; jmp .jtab(pc,d1.w) 290 | ; move.b (a1)+,(a0)+ 291 | ; move.b (a1)+,(a0)+ 292 | ; move.b (a1)+,(a0)+ 293 | ; move.b (a1)+,(a0)+ 294 | ; move.b (a1)+,(a0)+ 295 | ; move.b (a1)+,(a0)+ 296 | ; move.b (a1)+,(a0)+ 297 | ; move.b (a1)+,(a0)+ 298 | ; move.b (a1)+,(a0)+ 299 | ; move.b (a1)+,(a0)+ 300 | ; move.b (a1)+,(a0)+ 301 | ; move.b (a1)+,(a0)+ 302 | ; move.b (a1)+,(a0)+ 303 | ; move.b (a1)+,(a0)+ 304 | ; move.b (a1)+,(a0)+ 305 | ; move.b (a1)+,(a0)+ 306 | ;.jtab: 307 | ; move.l .sp_pdst(sp),d0 308 | ; rts 309 | 310 | ; -------------------------------------------------------------- 311 | _memset: 312 | ; -------------------------------------------------------------- 313 | 314 | ; move.l d2,-(sp) 315 | move.l d2,a1 316 | 317 | ; value 318 | move.b 0+8+3(sp),d0 319 | move.b d0,d1 320 | lsl.w #8,d1 321 | move.b d0,d1 322 | move.w d1,d2 323 | swap d2 324 | move.w d1,d2 325 | 326 | ; size 327 | move.l 0+12(sp),d1 328 | 329 | ; dest 330 | move.l 0+4(sp),d0 331 | move.l d0,a0 332 | and.w #1,d0 333 | beq.s .aligned 334 | move.b d2,(a0)+ 335 | subq.l #1,d1 336 | beq .done 337 | move.w d1,0+12+2(sp) 338 | .aligned: 339 | 340 | lsr.l #4,d1 341 | move.l d1,d0 342 | swap d0 343 | subq.w #1,d1 344 | bcs.s .ev1mb 345 | 346 | .lp1mb: 347 | .lp16b: move.l d2,(a0)+ 348 | move.l d2,(a0)+ 349 | move.l d2,(a0)+ 350 | move.l d2,(a0)+ 351 | dbra d1,.lp16b 352 | 353 | .ev1mb: subq.w #1,d0 354 | bpl.s .lp1mb 355 | 356 | moveq #16-1,d1 357 | and.w 0+12+2(sp),d1 358 | lsl.b #4+1,d1 359 | bcc.s .n8 360 | move.l d2,(a0)+ 361 | move.l d2,(a0)+ 362 | .n8: add.b d1,d1 363 | bcc.s .n4 364 | move.l d2,(a0)+ 365 | .n4: add.b d1,d1 366 | bcc.s .n2 367 | move.w d2,(a0)+ 368 | .n2: add.b d1,d1 369 | bcc.s .n1 370 | move.b d2,(a0)+ 371 | .n1: 372 | 373 | .done: move.l 0+4(sp),d0 374 | 375 | move.l a1,d2 376 | ; move.l (sp)+,d2 377 | rts 378 | 379 | ; -------------------------------------------------------------- 380 | 381 | ; -------------------------------------------------------------- 382 | ___mulsi3: xdef ___mulsi3 383 | ; -------------------------------------------------------------- 384 | move.w 6(sp),d0 385 | move.l d0,a0 386 | mulu.w 8(sp),d0 387 | move.w 10(sp),d1 388 | move.l d1,a1 389 | mulu.w 4(sp),d1 390 | add.w d1,d0 391 | swap d0 392 | clr.w d0 393 | exg.l a0,d0 394 | move.l a1,d1 395 | mulu.w d1,d0 396 | add.l a0,d0 397 | rts 398 | 399 | ; -------------------------------------------------------------- 400 | ___modsi3: xdef ___modsi3 401 | ; -------------------------------------------------------------- 402 | move.l (sp)+,a0 403 | move.l 4(sp),d1 404 | bpl.s .nabs 405 | neg.l 4(sp) 406 | .nabs: move.l (sp),d0 407 | pea .ret(pc) 408 | bpl.s .nabsd 409 | neg.l 4(sp) 410 | subq.l #2,(sp) 411 | .nabsd: bra ___udivsi3 412 | neg.l d1 413 | .ret: move.l d1,d0 414 | jmp (a0) 415 | 416 | ; -------------------------------------------------------------- 417 | ___udivsi3: xdef ___udivsi3 418 | ; -------------------------------------------------------------- 419 | move.l d2,-(sp) 420 | move.l 12(sp),d0 421 | move.l 8(sp),d1 422 | .norm: cmpi.l #$10000,d0 423 | bcs.s .normd 424 | lsr.l #1,d0 425 | lsr.l #1,d1 426 | bra.s .norm 427 | .normd: move.w d1,d2 428 | clr.w d1 429 | swap d1 430 | divu.w d0,d1 431 | movea.l d1,a1 432 | move.w d2,d1 433 | divu.w d0,d1 434 | move.l a1,d0 435 | swap d0 436 | clr.w d0 437 | andi.l #$ffff,d1 438 | add.l d1,d0 439 | move.l 12(sp),d2 440 | swap d2 441 | move.l d0,d1 442 | mulu.w d2,d1 443 | movea.l d1,a1 444 | swap d2 445 | move.l d0,d1 446 | swap d1 447 | mulu.w d2,d1 448 | add.l a1,d1 449 | swap d1 450 | clr.w d1 451 | movea.l d2,a1 452 | mulu.w d0,d2 453 | add.l d1,d2 454 | move.l 8(sp),d1 455 | sub.l d2,d1 456 | bcc.s .ninc 457 | subq.l #1,d0 458 | add.l a1,d1 459 | .ninc: move.l (sp)+,d2 460 | rts 461 | 462 | ; -------------------------------------------------------------- 463 | ___umodsi3: xdef ___umodsi3 464 | ; -------------------------------------------------------------- 465 | move.l (sp)+,a0 466 | bsr ___udivsi3 467 | move.l d1,d0 468 | jmp (a0) 469 | 470 | ; -------------------------------------------------------------- 471 | ___divsi3: xdef ___divsi3 472 | ; -------------------------------------------------------------- 473 | move.l 4(sp),d1 474 | bpl.s .nabs1 475 | neg.l 4(sp) 476 | .nabs1: move.l 8(sp),d0 477 | bpl.s .nabs2 478 | neg.l 8(sp) 479 | .nabs2: eor.l d1,d0 480 | bpl.s .npop 481 | move.l (sp)+,a0 482 | pea .ret(pc) 483 | .npop: bra ___udivsi3 484 | .ret: neg.l d0 485 | jmp (a0) 486 | 487 | ; -------------------------------------------------------------- 488 | _putchar: xdef _putchar 489 | ; -------------------------------------------------------------- 490 | move.w 4+2(sp),d1 491 | movem.l d2/a2,-(sp) 492 | move.w d1,-(sp) 493 | move.w #2,-(sp) 494 | move.w #3,-(sp) 495 | trap #13 496 | addq.l #6,sp 497 | moveq #0,d0 498 | movem.l (sp)+,d2/a2 499 | rts 500 | 501 | ; -------------------------------------------------------------- 502 | text 503 | ; -------------------------------------------------------------- 504 | 505 | _rand: XDEF _rand 506 | ___cxa_guard_acquire: 507 | ___cxa_guard_release: 508 | rts 509 | 510 | ; -------------------------------------------------------------- 511 | __ZSt17__throw_bad_allocv: 512 | ___cxa_pure_virtual: 513 | ; -------------------------------------------------------------- 514 | jmp _exit 515 | 516 | ; -------------------------------------------------------------- 517 | data 518 | ; -------------------------------------------------------------- 519 | 520 | dummy_argv: 521 | dummy_envp: 522 | dc.b 0 523 | even 524 | 525 | ; -------------------------------------------------------------- 526 | bss 527 | ; -------------------------------------------------------------- 528 | 529 | ds.b SSPS 530 | new_ssp: 531 | ds.l 1 532 | entrypoint_ssp: 533 | ds.l 1 534 | 535 | ; -------------------------------------------------------------- 536 | 537 | -------------------------------------------------------------------------------- /test-browntran/build-pml.sh: -------------------------------------------------------------------------------- 1 | set -x 2 | set -e 3 | 4 | echo Get the PML archive from http://d-bug.mooo.com/releases/pml-2.03-ataribrown.tar.gz !! 5 | 6 | #tar -zxvf pml-2.03-ataribrown.tar.gz 7 | cd pml-2.03-ataribrown/pmlsrc 8 | 9 | INSTALL_DIR=/usr 10 | 11 | # 1st pass for compiling m68000 libraries 12 | make 13 | make install CROSSDIR=build-pml$INSTALL_DIR 14 | 15 | # 2nd pass for compiling m68020-60 libraries 16 | make clean 17 | sed -i "s:^\(CFLAGS =.*\):\1 -m68020-60:g" Makefile.32 Makefile.16 18 | sed -i "s:^\(CROSSLIB =.*\):\1/m68020-60:g" Makefile 19 | make 20 | make install CROSSDIR=build-pml$INSTALL_DIR 21 | 22 | # 3rd pass for compiling ColdFire V4e libraries 23 | #make clean 24 | #sed -i "s:-m68020-60:-mcpu=5475:g" Makefile.32 Makefile.16 25 | #sed -i "s:m68020-60:m5475:g" Makefile 26 | #make 27 | #make install CROSSDIR=$PWD/binary-package$INSTALL_DIR 28 | 29 | cd build-pml 30 | find . -name '*.a' -print -exec ~/brown/bin/m68k-atariultrabrown-elf-strip -S -x '{}' ';' 31 | 32 | -------------------------------------------------------------------------------- /test-browntran/buildit.sh: -------------------------------------------------------------------------------- 1 | # You need libpml for this to even begin to link! 2 | # Run build-pml.sh first (make sure you grab the pml archive too) 3 | # and copy libpml.a from the appropriate folders here 4 | # (notice that both 68000 and 68020+ libraries are named libm.a O_o) 5 | 6 | # Brownboot.s needs vasm to build for now... 7 | # vasmm68k_mot -Felf brownboot.s -o brownboot.o 8 | 9 | # 68020 build compiles and links without error but gives 4 bombs when running. 10 | # Looks like some symbol isn't getting relocated.... 11 | ~/brown/bin/m68k-atariultrabrown-elf-gfortran -c -fleading-underscore heron.f -fomit-frame-pointer -L. -Ttext=0 12 | ~/brown/bin/m68k-atariultrabrown-elf-gfortran brownboot.o heron.o -o heron.elf -L. 13 | 14 | # 68000 build doesn't compile yet - it gives: 15 | # /usr/lib/gcc/m68k-atariultrabrown-elf/7.1.0/../../../../m68k-atariultrabrown-elf/lib/libgfortran.a(c99_functions.o): In function `_lgamma': 16 | # (.text.lgamma+0x11c): undefined reference to `_nextafter` 17 | # although libgfortran is somehow patched during building to fix that symbol... 18 | ~/brown/bin/m68k-atariultrabrown-elf-gfortran -c -fleading-underscore heron.f -fomit-frame-pointer -L. -Ttext=0 19 | ~/brown/bin/m68k-atariultrabrown-elf-gfortran brownboot.o heron.o -o heron00.elf -L. 20 | -------------------------------------------------------------------------------- /test-browntran/heron.f: -------------------------------------------------------------------------------- 1 | C AREA OF A TRIANGLE - HERON'S FORMULA 2 | C INPUT - CARD READER UNIT 5, INTEGER INPUT 3 | C OUTPUT - LINE PRINTER UNIT 6, REAL OUTPUT 4 | C INPUT ERROR DISPLAY ERROR OUTPUT CODE 1 IN JOB CONTROL LISTING 5 | INTEGER A,B,C 6 | READ(5,501) A,B,C 7 | 501 FORMAT(3I5) 8 | IF(A.EQ.0 .OR. B.EQ.0 .OR. C.EQ.0) STOP 1 9 | S = (A + B + C) / 2.0 10 | AREA = SQRT( S * (S - A) * (S - B) * (S - C) ) 11 | WRITE(6,601) A,B,C,AREA 12 | 601 FORMAT(4H A= ,I5,5H B= ,I5,5H C= ,I5,8H AREA= ,F10.2, 13 | $13H SQUARE UNITS) 14 | STOP 15 | END 16 | -------------------------------------------------------------------------------- /ub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggnkua/bigbrownbuild-git/c513eec545b7a4d7e92bccbd7cabd6530f7861eb/ub.png --------------------------------------------------------------------------------