1; CRT0 stub for the Old School Computer Architecture (FLOS) 2; 3; Stefano Bodrato - Jul. 2011 4; 5; 6; EXTRA OPTIONS: 7; 8; At C source level: 9; #pragma output osca_bank=(0..14) set the memory bank for locations > 32768 before loading program 10; #pragma output REGISTER_SP=<value> put the stack in a differen place, i.e. 32767 11; #pragma output nostreams - No stdio disc files 12; #pragma output noredir - do not insert the file redirection option while parsing the 13; command line arguments (useless if "nostreams" is set) 14; #pragma output osca_notimer - Save very few bytes and excludes the clock handling, 15; thus disabling those functions connected to time.h 16; #pragma output osca_restoretxt - works only with FLOS > v547, restores the text mode on program exit 17; 18; At compile time: 19; -zorg=<location> parameter permits to specify the program position 20; 21; $Id: osca_crt0.asm,v 1.38 2016-07-15 21:38:08 dom Exp $ 22; 23 24 25 MODULE osca_crt0 26 27; 28; Initially include the zcc_opt.def file to find out lots of lovely 29; information about what we should do.. 30; 31 32 defc crt0 = 1 33 INCLUDE "zcc_opt.def" 34 35; No matter what set up we have, main is always, always external to 36; this file 37 38 EXTERN _main 39 40 41; 42; Some variables which are needed for both app and basic startup 43; 44 45 PUBLIC cleanup 46 PUBLIC l_dcal 47 48 49; FLOS system variables 50 PUBLIC sector_lba0 ; keep this byte order 51 PUBLIC sector_lba1 52 PUBLIC sector_lba2 53 PUBLIC sector_lba3 54 55 PUBLIC a_store1 56 PUBLIC bc_store1 57 PUBLIC de_store1 58 PUBLIC hl_store1 59 PUBLIC a_store2 60 PUBLIC bc_store2 61 PUBLIC de_store2 62 PUBLIC hl_store2 63 PUBLIC storeix 64 PUBLIC storeiy 65 PUBLIC storesp 66 PUBLIC storepc 67 PUBLIC storef 68 PUBLIC store_registers 69 PUBLIC com_start_addr 70 71 PUBLIC cursor_y ;keep this byte order 72 PUBLIC cursor_x ;(allows read as word with y=LSB) 73 74 PUBLIC current_scancode 75 PUBLIC current_asciicode 76 77 78;-------- 79; OSCA / FLOS specific definitions 80;-------- 81 82 INCLUDE "flos.def" 83 INCLUDE "osca.def" 84 85 86; Now, getting to the real stuff now! 87 88 89;-------- 90; Set an origin for the application (-zorg=) default to $5000 91;-------- 92 93IF !DEFINED_CRT_ORG_CODE 94 defc CRT_ORG_CODE = $5000 95ENDIF 96 97 defc CONSOLE_COLUMNS = 40 98 defc CONSOLE_ROWS = 25 99 100 defc TAR__no_ansifont = 1 101 defc TAR__clib_exit_stack_size = 32 102 defc TAR__register_sp = 65536 - 6 103 defc __CPU_CLOCK = 4000000 104 INCLUDE "crt/classic/crt_rules.inc" 105 106 107IF ((CRT_ORG_CODE = $5000) | (!DEFINED_osca_bank)) 108 org CRT_ORG_CODE 109ELSE 110 ; optional Program Location File Header 111 org CRT_ORG_CODE 112 defb $ed 113 defb $00 114 jr start 115 defw CRT_ORG_CODE 116 IF DEFINED_osca_bank 117 defb osca_bank 118 ELSE 119 defb 0 120 ENDIF 121 defb $00 ; control byte: 1=truncate basing on next 3 bytes 122 ;defw 0 ; Load length 15:0 only needed if truncate flag is set 123 ;defb 0 ; Load length ..bits 23:16, only needed if truncate flag is set 124ENDIF 125 126start: 127 di 128 129 ld (cmdline+1),hl 130; ld b,h 131; ld c,l 132 133 ld (start1+1),sp 134 INCLUDE "crt/classic/crt_init_sp.asm" 135 INCLUDE "crt/classic/crt_init_atexit.asm" 136; push bc 137 call crt0_init_bss 138; pop bc 139 ld (exitsp),sp 140; push bc ; keep ptr to arg list 141 142; Optional definition for auto MALLOC init 143; it assumes we have free space between the end of 144; the compiled program and the stack pointer 145IF DEFINED_USING_amalloc 146 INCLUDE "crt/classic/crt_init_amalloc.asm" 147ENDIF 148 149IF (!DEFINED_osca_notimer) 150 151 ld hl,(FLOS_irq_vector) ; The label "irq_vector" = $A01 (contained in equates file) 152 ld (original_irq_vector),hl ; Store the original FLOS vecotr for restoration later. 153 ld hl,my_custom_irq_handler 154 ld (FLOS_irq_vector),hl 155 156 ld a,@10000111 ; Enable keyboard, mouse and timer interrupts 157 out (sys_irq_enable),a 158 159 ld a,250 160 neg 161 out (sys_timer),a 162 163 ld a,@00000100 164 out (sys_clear_irq_flags),a ; Clear the timer IRQ flag 165ELSE 166 ld b,255 167.v_srand_loop 168 ld hl,FLOSvarsaddr 169 add (hl) 170 ld (FRAMES),a 171 inc hl 172 djnz v_srand_loop 173ENDIF 174 ei 175 176 ; Push pointers to argv[n] onto the stack now 177 ; We must start from the end 178 ;pop hl ; command line back again 179cmdline: 180 ld hl,0 ; SMC 181 182 ld bc,0 183 ld a,(hl) 184 and a 185 jr z,argv_done 186 dec hl 187find_end: 188 inc hl 189 inc c 190 ld a,(hl) 191 and a 192 jr nz,find_end 193 dec hl 194 195 INCLUDE "crt/classic/crt_command_line.asm" 196 197 push hl ;argv 198 push bc ;argc 199 200 call _main ;Call user code 201 202 pop bc ;kill argv 203 pop bc ;kill argc 204 205cleanup: 206; 207; Deallocate memory which has been allocated here! 208; 209 push hl ;save exit value 210 call crt0_exit 211 212 ; kjt_flos_display restores the text mode but makes the screen flicker 213 ; if it is in text mode already 214 ; 215IF (DEFINED_osca_restoretxt) 216 call $10c4 ; kjt_flos_display (added in v547) 217ENDIF 218IF (!DEFINED_osca_notimer) 219 di 220 ld hl,(original_irq_vector) 221 ld (FLOS_irq_vector),hl 222 ld a,@10000011 ; Enable keyboard and mouse interrupts only 223 out (sys_irq_enable),a 224 ei 225ENDIF 226 pop hl ; restore exit value 227start1: 228 ld sp,0 229 xor a 230 or h ; ATM we are not mamaging the 'spawn' exception 231 jr nz,cmdok 232 ld l,a 233cmdok: 234 ld a,l ; return code (lowest byte only) 235 and a ; set Z flag to set the eventual error condition 236 ;xor a ; (set A and flags for RESULT=OK) 237 ret 238 239l_dcal: 240 jp (hl) 241 242IF (!DEFINED_osca_notimer) 243; ---------------------------------- 244; Custom Interrupt handlers 245; ---------------------------------- 246my_custom_irq_handler: 247 push af 248 in a,(sys_irq_ps2_flags) 249 bit 0,a 250 call nz,kjt_keyboard_irq_code ; Kernal keyboard irq handler 251 bit 1,a 252 call nz,kjt_mouse_irq_code ; Kernal mouse irq handler 253 bit 2,a 254 call nz,my_timer_irq_code ; User's timer irq handler 255 pop af 256 ei 257 reti 258 259my_timer_irq_code: 260 push af ; (do whatever, push/pop registers!) 261 push hl 262 263; ld hl,(frames_pre) 264; inc (hl) 265; ld a,(hl) 266; bit 4,a 267; jr nz,timer_irq_count_done 268 269 ld hl,(FRAMES) 270 inc hl 271 ld (FRAMES),hl 272 ;;ld (palette),hl ; testing purposes 273 ld a,h 274 or l 275 jr nz,timer_irq_count_done 276 ld hl,(FRAMES+2) 277 inc hl 278 ld (FRAMES+2),hl 279 280timer_irq_count_done: 281 ld a,@00000100 282 out (sys_clear_irq_flags),a ; Clear the timer IRQ flag 283 284 pop hl 285 pop af 286 ret 287ENDIF 288 289 SECTION bss_crt 290 291 PUBLIC FRAMES 292original_irq_vector: 293 defw 0 294 295FRAMES: 296 defw 0 297 defw 0 298 299 300 301end: 302 defb 0 303 304 305;-------------------------------------------------------------------------------------------- 306; 307; OS_variables location as defined in system_equates.asm 308; FLOSv582 sets it to $B00, hopefully it won't change much 309; but we keep the option for making it dynamic 310; 311;-------------------------------------------------------------------------------------------- 312 313IF !DEFINED_FLOSvarsaddr 314 defc FLOSvarsaddr = $B00 315ENDIF 316 317;-------------------------------------------------------------------------------------------- 318 319DEFVARS FLOSvarsaddr 320{ 321 322sector_lba0 ds.b 1 ; keep this byte order 323sector_lba1 ds.b 1 324sector_lba2 ds.b 1 325sector_lba3 ds.b 1 326 327a_store1 ds.b 1 328bc_store1 ds.b 2 329de_store1 ds.b 2 330hl_store1 ds.b 2 331a_store2 ds.b 1 332bc_store2 ds.b 2 333de_store2 ds.b 2 334hl_store2 ds.b 2 335storeix ds.b 2 336storeiy ds.b 2 337storesp ds.b 2 338storepc ds.b 2 339storef ds.b 1 340store_registers ds.b 1 341com_start_addr ds.w 1 342 343cursor_y ds.b 1 ;keep this byte order 344cursor_x ds.b 1 ;(allows read as word with y=LSB) 345 346current_scancode ds.b 1 347current_asciicode ds.b 1 348 349; The other variable positions depend on the FLOS version 350; .. 351} 352 353;-------------------------------------------------------------------------------------------- 354 355 INCLUDE "crt/classic/crt_runtime_selection.asm" 356 INCLUDE "crt/classic/crt_section.asm" 357 358 SECTION code_crt_init 359 ld hl,$2000 360 ld (base_graphics),hl 361 362 363 SECTION rodata_clib 364IF !DEFINED_noredir 365IF CRT_ENABLE_STDIO = 1 366redir_fopen_flag: defb 'w',0 367redir_fopen_flagr: defb 'r',0 368ENDIF 369ENDIF 370 371 372 373; SD CARD interface 374IF DEFINED_NEED_SDCARD 375 SECTION bss_crt 376 PUBLIC card_select 377 PUBLIC sd_card_info 378 379 PUBLIC sector_buffer_loc 380 381; Keep the following 2 bytes in the right order (1-card_select, 2-sd_card_info) !!! 382card_select: defb 0 ; Currently selected MMC/SD slot 383sd_card_info: defb 0 ; Card type flags.. 384 385sector_buffer_loc: defw 0 386sector_buffer: defs 513 387 388 SECTION code_crt_init 389 ld hl,sector_buffer 390 ld (sector_buffer_loc),hl 391 392ENDIF 393 394