Rev 922 | Details | Compare with Previous | Last modification | View Log
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 635 | alone | 1 | DEVICE ZXSPECTRUM128 |
| 2 | include "../_sdk/sys_h.asm" |
||
| 3 | include "8080.asm" |
||
| 4 | |||
| 680 | alone | 5 | NEDOOS=1 |
| 6 | |||
| 630 | alone | 7 | ; |
| 8 | ; BD Software C Compiler v1.6 |
||
| 9 | ; Standard Library Machine Language Functions (part A) |
||
| 10 | ; Copyright (c) 1982, 1986 by BD Software, Inc. |
||
| 11 | ; |
||
| 12 | ; This file is in "CSM" format; to convert to CRL format, |
||
| 13 | ; use CASM.SUB in conjunction with CASM.COM, ASM.COM and CLOAD.COM. |
||
| 14 | ; |
||
| 15 | ; Functions appearing in this file: |
||
| 16 | ; |
||
| 671 | alone | 17 | ; [cmode] [iobreak] getchar kbhit ungetch putchar |
| 630 | alone | 18 | ; gets getline |
| 19 | ; rand srand srand1 nrand |
||
| 671 | alone | 20 | ; [csw] setmem movmem memcmp |
| 630 | alone | 21 | ; call calla |
| 22 | ; inp outp peek poke |
||
| 23 | ; sleep pause exit |
||
| 24 | ; bdos bios biosh |
||
| 671 | alone | 25 | ; codend [externs] endext topofmem |
| 630 | alone | 26 | ; exec execv |
| 27 | ; rbrk sbrk rsvstk |
||
| 28 | ; index |
||
| 29 | ; setjmp longjmp |
||
| 30 | ; |
||
| 640 | alone | 31 | include "liblib.asm" |
| 630 | alone | 32 | |
| 671 | alone | 33 | if 1==1 |
| 635 | alone | 34 | FUNCTION "CMODE" |
| 35 | FUNCHEAD cmodesz |
||
| 630 | alone | 36 | call ma1toh ;get arg |
| 635 | alone | 37 | ex de,hl ;put in DE |
| 38 | ld hl,chmode ;get address of char mode flag |
||
| 39 | ld d,(hl) ;get old mode in D |
||
| 40 | ld (hl),e ;set new mode |
||
| 41 | xor a ;clear pushback byte |
||
| 630 | alone | 42 | sta ungetl |
| 635 | alone | 43 | inc hl |
| 44 | ld (hl),a ;and line buffer char count |
||
| 45 | ld l,d ;return old value of chmode |
||
| 46 | ld h,0 |
||
| 630 | alone | 47 | ret |
| 636 | alone | 48 | ENDFUNC cmodesz,0 |
| 49 | ;dw 0 ;no reloc pars |
||
| 671 | alone | 50 | endif |
| 630 | alone | 51 | |
| 671 | alone | 52 | if 1==1 |
| 635 | alone | 53 | FUNCTION "IOBREAK" |
| 54 | FUNCHEAD iobreaksz |
||
| 630 | alone | 55 | call ma1toh ;get arg |
| 56 | sta iobrf |
||
| 57 | ret |
||
| 636 | alone | 58 | ENDFUNC iobreaksz,0 |
| 59 | ;dw 0 ;no reloc pars |
||
| 671 | alone | 60 | endif |
| 630 | alone | 61 | |
| 635 | alone | 62 | FUNCTION "GETCHAR" |
| 63 | FUNCHEAD getcharsz |
||
| 630 | alone | 64 | lda ungetl ;any character pushed back? |
| 635 | alone | 65 | ld l,a |
| 66 | or a |
||
| 67 | _1=$+1 |
||
| 68 | jp z,getit |
||
| 69 | xor a ;yes. return it and clear the pushback |
||
| 630 | alone | 70 | sta ungetl ;byte in C.CCC. |
| 635 | alone | 71 | ld h,a ;clear h |
| 630 | alone | 72 | ret |
| 73 | |||
| 74 | getit: |
||
| 635 | alone | 75 | push bc |
| 76 | ld hl,chmode ;get address of chmode flag |
||
| 637 | alone | 77 | ;ld a,(hl) |
| 78 | xor a |
||
| 635 | alone | 79 | or a |
| 80 | _2=$+1 |
||
| 81 | jp z,single ;jump if single mode |
||
| 82 | inc hl |
||
| 83 | push hl ;save &nleft |
||
| 84 | ld a,(hl) ;get number of chars left in buf |
||
| 85 | or a |
||
| 86 | _3=$+1 |
||
| 87 | jp nz,gnext ;jump if characters in buffer |
||
| 630 | alone | 88 | ;fill buffer: |
| 635 | alone | 89 | _4=$+1 |
| 90 | ld de,gcbuff ;DE = buffer address |
||
| 91 | ld c,getlin |
||
| 630 | alone | 92 | call bdos ;read console buffer |
| 635 | alone | 93 | ld c,conout |
| 94 | ld e,lf |
||
| 630 | alone | 95 | call bdos ;linefeed to console |
| 635 | alone | 96 | _5=$+1 |
| 97 | ld hl,gcline |
||
| 98 | _6=$+1 |
||
| 630 | alone | 99 | shld gcptr ;initialize gcptr |
| 635 | alone | 100 | _7=$+1 |
| 630 | alone | 101 | lda gcnum ;number of chars just read |
| 635 | alone | 102 | ld hl,nleft ;HL = &nleft |
| 103 | ld (hl),a ;set number of characters |
||
| 104 | cp maxl |
||
| 105 | _8=$+1 |
||
| 106 | jp z,gnext ;if buffer completely full, don't append nl |
||
| 107 | ld e,a |
||
| 108 | ld d,0 ;DE = number of characters |
||
| 109 | inc (hl) ;nleft++ |
||
| 110 | _9=$+1 |
||
| 111 | ld hl,gcline |
||
| 112 | add hl,de ;HL = addr of next char pos after end |
||
| 113 | ld (hl),newlin ;append newline char |
||
| 630 | alone | 114 | |
| 635 | alone | 115 | gnext: |
| 116 | pop hl ;now take a char from the buffer |
||
| 117 | dec (hl) ;nleft-- |
||
| 118 | _10=$+1 |
||
| 630 | alone | 119 | lhld gcptr ;get next char |
| 635 | alone | 120 | ld a,(hl) |
| 121 | inc hl ;bump ptr |
||
| 122 | _11=$+1 |
||
| 630 | alone | 123 | shld gcptr |
| 635 | alone | 124 | _12=$+1 |
| 125 | jp gotit |
||
| 630 | alone | 126 | |
| 635 | alone | 127 | single: |
| 637 | alone | 128 | ;ld c,conin ;get single char from bdos |
| 129 | ;call bdos |
||
| 130 | YIELDGETKEYLOOP |
||
| 635 | alone | 131 | cp cr ;carriage return? |
| 132 | _13=$+1 |
||
| 133 | jp nz,gotit |
||
| 637 | alone | 134 | ;ld c,conout ;if so, echo linefeed |
| 135 | ;ld e,lf |
||
| 136 | ;call bdos |
||
| 137 | ;ld a,newlin ;and return newline (linefeed).. |
||
| 630 | alone | 138 | |
| 637 | alone | 139 | gotit: ;ld b,a ;save char in B |
| 140 | ;lda iobrf ;checking for BREAK character? |
||
| 141 | ;or a |
||
| 142 | ;ld a,b ;restore char into A |
||
| 635 | alone | 143 | pop bc ;restore BC |
| 144 | _14=$+1 |
||
| 145 | jp z,gotit2 ;if not checking for BREAK, skip test |
||
| 637 | alone | 146 | ;cp cntrlc ;control-C ? |
| 147 | ;jp z,exit ;if so, exit the program. |
||
| 148 | gotit2: ;cp 1ah ;control-Z ? |
||
| 149 | ;ld hl,-1 ;if so, return -1. |
||
| 150 | ;ret z |
||
| 635 | alone | 151 | ld l,a ;else return char in HL |
| 152 | ld h,0 |
||
| 630 | alone | 153 | ret |
| 154 | |||
| 155 | maxl equ 79 ;max length of line of buffered console input |
||
| 156 | gcptr ds 2 ;pointer into line where first char is |
||
| 157 | gcbuff db maxl ;max line length fro BDOS 10 |
||
| 158 | gcnum db 0 ;number of characters just read by BDOS 10 |
||
| 159 | gcline ds maxl+1 ;buffer for characters, in case BDOS 10 is used |
||
| 636 | alone | 160 | ENDFUNC getcharsz,14 |
| 630 | alone | 161 | |
| 635 | alone | 162 | FUNCTION "KBHIT" |
| 163 | FUNCHEAD kbhitsz |
||
| 630 | alone | 164 | lda ungetl ;any character ungotten? |
| 635 | alone | 165 | ld h,0 |
| 166 | ld l,a |
||
| 167 | or a |
||
| 168 | ret nz ;if so, return true |
||
| 630 | alone | 169 | |
| 170 | lda nleft ;get number of chars left in buffer |
||
| 635 | alone | 171 | or a |
| 172 | ret nz ;if any characters in buffer, return true |
||
| 630 | alone | 173 | |
| 635 | alone | 174 | push bc |
| 175 | ld c,cstat ;else interrogate console status |
||
| 630 | alone | 176 | call bdos |
| 635 | alone | 177 | pop bc |
| 630 | alone | 178 | |
| 635 | alone | 179 | or a ;0 returned by BDOS if no character ready |
| 180 | ld hl,0 |
||
| 181 | ret z ;return 0 in HL if no character ready |
||
| 182 | inc l ;otherwise return 1 in HL |
||
| 630 | alone | 183 | ret |
| 636 | alone | 184 | ENDFUNC kbhitsz,0 |
| 185 | ;dw 0 ;no reloc pars |
||
| 630 | alone | 186 | |
| 635 | alone | 187 | FUNCTION "UNGETCH" |
| 188 | FUNCHEAD ungetchsz |
||
| 630 | alone | 189 | lda ungetl |
| 635 | alone | 190 | ld l,a |
| 191 | push hl |
||
| 630 | alone | 192 | call ma2toh |
| 193 | sta ungetl |
||
| 635 | alone | 194 | pop hl |
| 195 | ld h,0 |
||
| 630 | alone | 196 | ret |
| 636 | alone | 197 | ENDFUNC ungetchsz,0 |
| 198 | ;dw 0 ;no reloc pars |
||
| 630 | alone | 199 | |
| 635 | alone | 200 | FUNCTION "PUTCHAR" |
| 201 | FUNCHEAD putcharsz |
||
| 630 | alone | 202 | call ma1toh ;get character in A |
| 635 | alone | 203 | push bc |
| 636 | alone | 204 | ;ld c,conout |
| 205 | ds 2 |
||
| 635 | alone | 206 | cp newlin ;newline? |
| 636 | alone | 207 | _1=$+1 |
| 635 | alone | 208 | jp nz,put1 ;if not, just go put out the character |
| 636 | alone | 209 | ;ld e,cr ;else...put out CR-LF |
| 210 | ld a,cr |
||
| 211 | ;call bdos |
||
| 212 | PRCHAR |
||
| 213 | ds 2 |
||
| 214 | ;ld c,conout |
||
| 215 | ds 2 |
||
| 635 | alone | 216 | ld a,lf |
| 630 | alone | 217 | |
| 636 | alone | 218 | put1: ;ld e,a |
| 219 | nop |
||
| 220 | ;call bdos |
||
| 221 | PRCHAR |
||
| 222 | ds 2 |
||
| 630 | alone | 223 | |
| 636 | alone | 224 | put2: ;lda iobrf ;checking for BREAK characters on keyboard? |
| 225 | xor a |
||
| 226 | ds 2 |
||
| 635 | alone | 227 | or a |
| 636 | alone | 228 | _2=$+1 |
| 635 | alone | 229 | jp z,put4 ;if not, all done |
| 630 | alone | 230 | |
| 636 | alone | 231 | ld c,cstat ;now, is input present at the console? |
| 232 | call bdos |
||
| 233 | or a |
||
| 234 | _3=$+1 |
||
| 235 | jp nz,put3 |
||
| 236 | pop bc ;no...all done. |
||
| 237 | ret |
||
| 630 | alone | 238 | |
| 636 | alone | 239 | put3: ld c,conin ;yes. sample it (this will always echo the |
| 240 | call bdos ; character to the screen, alas) |
||
| 241 | cp cntrlc ;is it control-C? |
||
| 242 | jp z,exit ;if so, abort and reboot |
||
| 243 | |||
| 635 | alone | 244 | put4: pop bc ;else ignore it. |
| 630 | alone | 245 | ret |
| 636 | alone | 246 | ENDFUNC putcharsz,3 |
| 630 | alone | 247 | |
| 635 | alone | 248 | FUNCTION "GETS" |
| 249 | FUNCHEAD getssz |
||
| 630 | alone | 250 | call ma1toh ;get destination address |
| 635 | alone | 251 | push bc ;save BC |
| 252 | push hl |
||
| 253 | push hl |
||
| 254 | ld hl,-150 ;use space below stack for reading line |
||
| 255 | add hl,sp |
||
| 256 | push hl ;save buffer address |
||
| 257 | ld (hl),88h ;Allow a max of about 135 characters |
||
| 258 | ld c,getlin |
||
| 259 | ex de,hl ;put buffer addr in DE |
||
| 630 | alone | 260 | call bdos ;get the input line |
| 635 | alone | 261 | ld c,conout |
| 262 | ld e,lf ;put out a LF |
||
| 630 | alone | 263 | call bdos |
| 635 | alone | 264 | pop hl ;get back buffer address |
| 265 | inc hl ;point to returned char count |
||
| 266 | ld b,(hl) ;set B equal to char count |
||
| 267 | inc hl ;HL points to first char of line |
||
| 268 | pop de ;DE points to start destination area |
||
| 269 | copyls: ld a,b ;copy line to start of buffer |
||
| 270 | or a |
||
| 636 | alone | 271 | _1=$+1 |
| 635 | alone | 272 | jp z,gets2s |
| 273 | ld a,(hl) |
||
| 274 | ld (de),a |
||
| 275 | inc hl |
||
| 276 | inc de |
||
| 277 | dec b |
||
| 636 | alone | 278 | _2=$+1 |
| 635 | alone | 279 | jp copyls |
| 630 | alone | 280 | |
| 635 | alone | 281 | gets2s: xor a ;store terminating null |
| 282 | ld (de),a |
||
| 283 | pop hl ;return buffer address in HL |
||
| 284 | pop bc |
||
| 630 | alone | 285 | ret |
| 636 | alone | 286 | ENDFUNC getssz,2 |
| 630 | alone | 287 | |
| 288 | ; |
||
| 289 | ; Getline(str,lim) |
||
| 290 | ; char *str; |
||
| 291 | ; |
||
| 292 | ; Gets a line of text from the console, up to 'lim' characters. |
||
| 293 | ; |
||
| 294 | |||
| 635 | alone | 295 | FUNCTION "GETLINE" |
| 296 | FUNCHEAD getlinesz |
||
| 297 | push bc ;save BC |
||
| 630 | alone | 298 | call ma3toh ;get max no. of chars |
| 635 | alone | 299 | ld c,a ;save max length in C |
| 300 | dec c ;allow room for final terminating null |
||
| 301 | ld de,10 ;allow a bit extra stack for good measure |
||
| 302 | add hl,de |
||
| 630 | alone | 303 | call cmh ;save amount of space to allocate on stack |
| 635 | alone | 304 | push hl |
| 630 | alone | 305 | call ma3toh ;get destination address |
| 635 | alone | 306 | ex (sp),hl ;push dest addr, get back stack offset |
| 307 | add hl,sp ;allocate space on stack |
||
| 308 | push hl ;save buffer address |
||
| 309 | ld (hl),c ;Set max # of characters |
||
| 310 | ld c,getlin |
||
| 311 | ex de,hl ;put buffer addr in DE |
||
| 630 | alone | 312 | call bdos ;get the input line |
| 635 | alone | 313 | ld c,conout |
| 314 | ld e,lf ;put out a LF |
||
| 630 | alone | 315 | call bdos |
| 635 | alone | 316 | pop hl ;get back buffer address |
| 317 | inc hl ;point to returned char count |
||
| 318 | ld b,(hl) ;set B equal to char count |
||
| 319 | inc hl ;HL points to first char of line |
||
| 320 | pop de ;DE points to start destination area |
||
| 321 | ld c,b ;save char count in C |
||
| 322 | copylln: ld a,b ;copy line to start of buffer |
||
| 323 | or a |
||
| 636 | alone | 324 | _1=$+1 |
| 635 | alone | 325 | jp z,gets2ln |
| 326 | ld a,(hl) |
||
| 327 | ld (de),a |
||
| 328 | inc hl |
||
| 329 | inc de |
||
| 330 | dec b |
||
| 636 | alone | 331 | _2=$+1 |
| 635 | alone | 332 | jp copylln |
| 630 | alone | 333 | |
| 635 | alone | 334 | gets2ln: xor a ;store terminating null |
| 335 | ld (de),a |
||
| 336 | ld l,c ;return char count in HL |
||
| 337 | ld h,0 |
||
| 338 | pop bc |
||
| 630 | alone | 339 | ret |
| 636 | alone | 340 | ENDFUNC getlinesz,2 |
| 630 | alone | 341 | |
| 635 | alone | 342 | FUNCTION "RAND" |
| 343 | FUNCHEAD randsz |
||
| 630 | alone | 344 | lhld rseed |
| 635 | alone | 345 | ex de,hl |
| 346 | ld a,48h |
||
| 347 | and e |
||
| 636 | alone | 348 | _1=$+1 |
| 635 | alone | 349 | jp z,rand1 |
| 636 | alone | 350 | _2=$+1 |
| 635 | alone | 351 | jp pe,rand1 |
| 352 | scf |
||
| 630 | alone | 353 | rand1: lhld rseed+2 |
| 635 | alone | 354 | ld a,h |
| 355 | rla |
||
| 356 | ld h,a |
||
| 357 | ld a,l |
||
| 358 | rla |
||
| 359 | ld l,a |
||
| 630 | alone | 360 | shld rseed+2 |
| 635 | alone | 361 | ld a,d |
| 362 | rla |
||
| 363 | ld h,a |
||
| 364 | ld a,e |
||
| 365 | rla |
||
| 366 | ld l,a |
||
| 630 | alone | 367 | shld rseed |
| 635 | alone | 368 | ld a,h |
| 369 | and 7fh |
||
| 370 | ld h,a |
||
| 630 | alone | 371 | ret |
| 636 | alone | 372 | ENDFUNC randsz,2 |
| 630 | alone | 373 | |
| 635 | alone | 374 | FUNCTION "SRAND" |
| 375 | FUNCHEAD srandsz |
||
| 630 | alone | 376 | call ma1toh |
| 635 | alone | 377 | ld a,h |
| 378 | or l |
||
| 636 | alone | 379 | _1=$+1 |
| 635 | alone | 380 | jp z,srand2 |
| 630 | alone | 381 | shld rseed |
| 382 | shld rseed+2 |
||
| 383 | ret |
||
| 384 | |||
| 636 | alone | 385 | srand2: |
| 386 | _2=$+1 |
||
| 387 | ld de,stg1 |
||
| 635 | alone | 388 | push bc |
| 389 | ld c,9 |
||
| 630 | alone | 390 | call bdos |
| 635 | alone | 391 | ld hl,0bdbdh |
| 392 | srand3: push hl |
||
| 393 | ld c,11 |
||
| 630 | alone | 394 | call bdos |
| 635 | alone | 395 | pop hl |
| 396 | inc hl |
||
| 397 | inc hl |
||
| 398 | inc hl |
||
| 399 | and 1 |
||
| 636 | alone | 400 | _3=$+1 |
| 635 | alone | 401 | jp z,srand3 |
| 630 | alone | 402 | shld rseed |
| 403 | shld rseed+2 |
||
| 635 | alone | 404 | ld c,conout |
| 405 | ld e,cr |
||
| 630 | alone | 406 | call bdos |
| 635 | alone | 407 | ld c,conout |
| 408 | ld e,lf |
||
| 630 | alone | 409 | call bdos |
| 635 | alone | 410 | ld c,conin ;clear the character |
| 630 | alone | 411 | call bdos |
| 635 | alone | 412 | pop bc |
| 630 | alone | 413 | ret |
| 414 | stg1: db 'Wait a few seconds, and type a CR: $' |
||
| 636 | alone | 415 | ENDFUNC srandsz,3 |
| 630 | alone | 416 | |
| 417 | |||
| 636 | alone | 418 | |
| 635 | alone | 419 | FUNCTION "SRAND1" |
| 420 | EXTERNAL "PUTS" |
||
| 421 | FUNCHEAD srand1sz |
||
| 636 | alone | 422 | _1=$+1 |
| 423 | jp (1 +1)*3 |
||
| 424 | _puts=$ |
||
| 425 | jp 0 |
||
| 630 | alone | 426 | call ma1toh |
| 635 | alone | 427 | push hl |
| 636 | alone | 428 | _2=$+1 |
| 429 | call _puts ;print prompt string |
||
| 635 | alone | 430 | pop hl |
| 431 | push bc |
||
| 432 | ld hl,5678h |
||
| 433 | sr1a: push hl |
||
| 434 | ld c,cstat |
||
| 630 | alone | 435 | call bdos |
| 635 | alone | 436 | pop hl |
| 437 | inc hl |
||
| 438 | inc hl |
||
| 439 | inc hl |
||
| 440 | or a |
||
| 636 | alone | 441 | _3=$+1 |
| 635 | alone | 442 | jp z,sr1a |
| 630 | alone | 443 | shld rseed |
| 444 | shld rseed+2 |
||
| 635 | alone | 445 | pop bc |
| 630 | alone | 446 | ret |
| 636 | alone | 447 | ENDFUNC srand1sz,3 |
| 630 | alone | 448 | |
| 635 | alone | 449 | FUNCTION "NRAND" |
| 450 | EXTERNAL "PUTS" |
||
| 451 | FUNCHEAD nrandsz |
||
| 636 | alone | 452 | _1=$+1 |
| 453 | jp (1 +1)*3 |
||
| 454 | _puts=$ |
||
| 455 | jp 0 |
||
| 630 | alone | 456 | call arghak |
| 457 | lhld arg1 ;get n (1st arg) |
||
| 635 | alone | 458 | ld a,h |
| 459 | and l |
||
| 460 | cp 255 ;was it -1 (set seed) ? |
||
| 636 | alone | 461 | _2=$+1 |
| 635 | alone | 462 | jp nz,nrand1 |
| 630 | alone | 463 | lhld arg2 ;copy seed |
| 636 | alone | 464 | _3=$+1 |
| 630 | alone | 465 | shld seed |
| 466 | lhld arg3 |
||
| 636 | alone | 467 | _4=$+1 |
| 630 | alone | 468 | shld seed+2 |
| 469 | lhld arg4 |
||
| 636 | alone | 470 | _5=$+1 |
| 630 | alone | 471 | shld seed+4 |
| 472 | ret ;all done |
||
| 473 | |||
| 635 | alone | 474 | nrand1: push bc |
| 475 | ld a,h ;look at first arg again |
||
| 476 | or l |
||
| 636 | alone | 477 | _6=$+1 |
| 635 | alone | 478 | jp nz,nrand3 ;is it 0 (randomize)? |
| 630 | alone | 479 | lhld arg2 |
| 635 | alone | 480 | push hl ;yes. print out string |
| 636 | alone | 481 | _7=$+1 |
| 482 | call _puts ;call puts |
||
| 635 | alone | 483 | pop de |
| 484 | ld hl,5a97h ;yes. start w/something odd |
||
| 485 | nrand2: push hl |
||
| 486 | ld c,cstat ;interrogate console status |
||
| 630 | alone | 487 | call bdos |
| 635 | alone | 488 | pop hl |
| 489 | inc hl ;and keep it odd |
||
| 490 | inc hl ;and growing |
||
| 491 | or a |
||
| 636 | alone | 492 | _8=$+1 |
| 635 | alone | 493 | jp z,nrand2 ;until user types something. |
| 636 | alone | 494 | _9=$+1 |
| 630 | alone | 495 | shld seed ;then plaster the value all over the |
| 636 | alone | 496 | _10=$+1 |
| 630 | alone | 497 | shld seed+2 ;seed. |
| 636 | alone | 498 | _11=$+1 |
| 630 | alone | 499 | shld seed+4 |
| 635 | alone | 500 | pop bc |
| 630 | alone | 501 | ret |
| 502 | |||
| 636 | alone | 503 | nrand3: |
| 504 | _12=$+1 |
||
| 505 | lda seed ;now compute next random number. from this |
||
| 635 | alone | 506 | or 1 ; point on, the code is that of Prof. Paul Gans |
| 636 | alone | 507 | _13=$+1 |
| 630 | alone | 508 | sta seed ;lsb of SEED must be 1 |
| 509 | |||
| 635 | alone | 510 | ld b,6 ;clear 6 PROD bytes to 0 |
| 636 | alone | 511 | _14=$+1 |
| 635 | alone | 512 | ld hl,prod |
| 513 | randm1: ld (hl),0 |
||
| 514 | inc hl |
||
| 515 | dec b |
||
| 636 | alone | 516 | _15=$+1 |
| 635 | alone | 517 | jp nz,randm1 |
| 630 | alone | 518 | |
| 635 | alone | 519 | ld bc,6 ;set byte counter |
| 636 | alone | 520 | randm2: |
| 521 | _16=$+1 |
||
| 522 | ld hl,plier-1 |
||
| 635 | alone | 523 | add hl,bc ;make addr of lsb of PLIER |
| 524 | ld a,(hl) ;PLIER byte |
||
| 525 | push bc ;save byte counter |
||
| 526 | ld b,8 ;set bit counter |
||
| 630 | alone | 527 | |
| 635 | alone | 528 | randm3: ld d,a ;save PLIER byte |
| 636 | alone | 529 | _17=$+1 |
| 635 | alone | 530 | ld hl,prod ;shift whole PROD left one bit |
| 531 | ld c,6 |
||
| 532 | xor a |
||
| 533 | randm4: ld a,(hl) ;get byte |
||
| 534 | rla ;shift left |
||
| 535 | ld (hl),a ;put byte |
||
| 536 | inc hl |
||
| 537 | dec c |
||
| 636 | alone | 538 | _18=$+1 |
| 635 | alone | 539 | jp nz,randm4 |
| 630 | alone | 540 | |
| 635 | alone | 541 | ld a,d ;recover PLIER byte |
| 542 | rla ;look at current high bit |
||
| 636 | alone | 543 | _19=$+1 |
| 635 | alone | 544 | jp nc,randm6 ;0 means no add cycle |
| 630 | alone | 545 | |
| 635 | alone | 546 | push af ;add SEED to PROD |
| 547 | xor a |
||
| 548 | ld c,6 |
||
| 636 | alone | 549 | _20=$+1 |
| 635 | alone | 550 | ld hl,prod |
| 636 | alone | 551 | _21=$+1 |
| 635 | alone | 552 | ld de,seed |
| 553 | randm5: ld a,(de) |
||
| 554 | adc (hl) |
||
| 555 | ld (hl),a |
||
| 556 | inc hl |
||
| 557 | inc de |
||
| 558 | dec c |
||
| 636 | alone | 559 | _22=$+1 |
| 635 | alone | 560 | jp nz,randm5 |
| 561 | pop af |
||
| 630 | alone | 562 | |
| 635 | alone | 563 | randm6: dec b ;test bit counter |
| 636 | alone | 564 | _23=$+1 |
| 635 | alone | 565 | jp nz,randm3 ;go cycle more bits |
| 566 | pop bc ;recover byte counter |
||
| 567 | dec c ;test it |
||
| 636 | alone | 568 | _24=$+1 |
| 635 | alone | 569 | jp nz,randm2 ;go process more bytes |
| 630 | alone | 570 | |
| 635 | alone | 571 | ld b,6 ;complement PROD, add 1 to it, |
| 636 | alone | 572 | _25=$+1 |
| 635 | alone | 573 | ld hl,seed ;and transfer it to SEED. |
| 636 | alone | 574 | _26=$+1 |
| 635 | alone | 575 | ld de,prod |
| 576 | xor a |
||
| 577 | ccf |
||
| 578 | randm7: ld a,(de) |
||
| 579 | cpl |
||
| 580 | adc a,0 |
||
| 581 | ld (hl),a |
||
| 582 | inc hl |
||
| 583 | inc de |
||
| 584 | dec b |
||
| 636 | alone | 585 | _27=$+1 |
| 635 | alone | 586 | jp nz,randm7 |
| 630 | alone | 587 | |
| 635 | alone | 588 | dec hl ;put the two high order bytes |
| 589 | ld a,(hl) ;into HL for return to C, not |
||
| 590 | and 7fh ;neglecting to zero the high |
||
| 591 | ld h,a ;order bit so a positive int |
||
| 636 | alone | 592 | _28=$+1 |
| 630 | alone | 593 | lda seed+4 ;is returned |
| 635 | alone | 594 | ld l,a |
| 595 | pop bc |
||
| 630 | alone | 596 | ret |
| 597 | |||
| 598 | plier: db 0c5h,87h,1 |
||
| 599 | db 0eh,9ah,0e0h |
||
| 600 | |||
| 601 | seed: db 1,0,0,0,0,0 |
||
| 602 | |||
| 603 | prod: db 0,0,0,0,0,0 |
||
| 636 | alone | 604 | ENDFUNC nrandsz,28 |
| 630 | alone | 605 | |
| 671 | alone | 606 | if 1==1 |
| 635 | alone | 607 | FUNCTION "CSW" |
| 608 | FUNCHEAD cswsz |
||
| 609 | in a,(255) ;??? |
||
| 610 | ld l,a |
||
| 611 | ld h,0 |
||
| 630 | alone | 612 | ret |
| 636 | alone | 613 | ENDFUNC cswsz,0 |
| 671 | alone | 614 | endif |
| 630 | alone | 615 | |
| 635 | alone | 616 | FUNCTION "SETMEM" |
| 617 | FUNCHEAD setmemsz |
||
| 630 | alone | 618 | call arghak |
| 635 | alone | 619 | push bc |
| 630 | alone | 620 | lhld arg2 |
| 635 | alone | 621 | ex de,hl |
| 630 | alone | 622 | lhld arg1 |
| 623 | lda arg3 |
||
| 635 | alone | 624 | ld c,a |
| 625 | inc de |
||
| 626 | setm2: dec de |
||
| 627 | ld a,d |
||
| 628 | or e |
||
| 636 | alone | 629 | _1=$+1 |
| 635 | alone | 630 | jp nz,setm3 |
| 631 | pop bc |
||
| 630 | alone | 632 | ret |
| 633 | |||
| 635 | alone | 634 | setm3: ld (hl),c |
| 635 | inc hl |
||
| 636 | alone | 636 | _2=$+1 |
| 635 | alone | 637 | jp setm2 |
| 636 | alone | 638 | ENDFUNC setmemsz,2 |
| 630 | alone | 639 | |
| 635 | alone | 640 | FUNCTION "MOVMEM" |
| 641 | FUNCHEAD movmemsz |
||
| 630 | alone | 642 | call arghak |
| 643 | lhld arg3 ;get block length |
||
| 635 | alone | 644 | ld a,h |
| 645 | or l |
||
| 646 | ret z ;do nothing if zero length |
||
| 647 | push bc |
||
| 648 | ld b,h |
||
| 649 | ld c,l ;set BC to length |
||
| 630 | alone | 650 | lhld arg2 ;get dest addr |
| 635 | alone | 651 | ex de,hl ;put in DE |
| 630 | alone | 652 | lhld arg1 ;get source addr in HL |
| 636 | alone | 653 | call cmphd;movmcmphd ;if source < dest, do tail-first |
| 654 | _1=$+1 |
||
| 635 | alone | 655 | jp c,tailf ;else do head-first |
| 630 | alone | 656 | |
| 635 | alone | 657 | headf: ld a,2 ;test for Z-80 |
| 658 | inc a |
||
| 636 | alone | 659 | _2=$+1 |
| 635 | alone | 660 | jp pe,m8080h ;Z80? |
| 630 | alone | 661 | db 0edh,0b0h ;yes. do block move. |
| 635 | alone | 662 | pop bc |
| 630 | alone | 663 | ret ;and done. |
| 664 | |||
| 635 | alone | 665 | m8080h: ld a,(hl) |
| 666 | ld (de),a |
||
| 667 | inc hl |
||
| 668 | inc de |
||
| 669 | dec bc |
||
| 670 | ld a,b |
||
| 671 | or c |
||
| 636 | alone | 672 | _3=$+1 |
| 635 | alone | 673 | jp nz,m8080h |
| 674 | pop bc |
||
| 630 | alone | 675 | ret |
| 676 | |||
| 635 | alone | 677 | tailf: dec bc ;tail first. Compute new source |
| 678 | add hl,bc ;and destination addresses |
||
| 679 | ex de,hl |
||
| 680 | add hl,bc |
||
| 681 | ex de,hl |
||
| 682 | inc bc |
||
| 683 | ld a,2 ;test for Z80 |
||
| 684 | inc a |
||
| 636 | alone | 685 | _4=$+1 |
| 635 | alone | 686 | jp pe,m8080t ;Z80? |
| 630 | alone | 687 | db 0edh,0b8h ;yes. do block move. |
| 635 | alone | 688 | pop bc |
| 630 | alone | 689 | ret |
| 690 | |||
| 635 | alone | 691 | m8080t: ld a,(hl) |
| 692 | ld (de),a |
||
| 693 | dec hl |
||
| 694 | dec de |
||
| 695 | dec bc |
||
| 696 | ld a,b |
||
| 697 | or c |
||
| 636 | alone | 698 | _5=$+1 |
| 635 | alone | 699 | jp nz,m8080t |
| 700 | pop bc |
||
| 630 | alone | 701 | ret |
| 636 | alone | 702 | ;NU |
| 635 | alone | 703 | movmcmphd: ld a,h |
| 704 | cp d |
||
| 705 | ret nz |
||
| 706 | ld a,l |
||
| 707 | cp e |
||
| 630 | alone | 708 | ret |
| 636 | alone | 709 | ENDFUNC movmemsz,5 |
| 630 | alone | 710 | |
| 635 | alone | 711 | FUNCTION "MEMCMP" |
| 712 | FUNCHEAD memcmpsz |
||
| 630 | alone | 713 | call ma3toh ;get length in HL |
| 635 | alone | 714 | push bc ;save BC |
| 715 | ld b,h |
||
| 716 | ld c,l ;move length to BC |
||
| 630 | alone | 717 | call ma3toh ;get block2 address in HL |
| 635 | alone | 718 | ex de,hl ;move to DE |
| 630 | alone | 719 | call ma2toh ;get block1 address in HL |
| 635 | alone | 720 | loop: ld a,b ;all done? |
| 721 | or c |
||
| 636 | alone | 722 | _1=$+1 |
| 635 | alone | 723 | jp nz,loop1 |
| 724 | ld hl,1 ;if so, return TRUE, for perfect match |
||
| 725 | pop bc |
||
| 630 | alone | 726 | ret |
| 727 | |||
| 635 | alone | 728 | loop1: dec bc ;decrement count |
| 729 | ld a,(de) ;get block2 byte |
||
| 730 | cp (hl) ;compare to block1 byte |
||
| 731 | inc de ;bump pointers |
||
| 732 | inc hl |
||
| 636 | alone | 733 | _2=$+1 |
| 635 | alone | 734 | jp z,loop ;if so far so good, go on comparing |
| 735 | ld hl,0 ;else a mismatch |
||
| 736 | pop bc |
||
| 630 | alone | 737 | ret |
| 636 | alone | 738 | ENDFUNC memcmpsz,2 |
| 630 | alone | 739 | |
| 635 | alone | 740 | FUNCTION "CALL" |
| 741 | FUNCHEAD callsz |
||
| 630 | alone | 742 | call arghak |
| 635 | alone | 743 | push bc |
| 630 | alone | 744 | lhld arg5 |
| 635 | alone | 745 | ex de,hl |
| 630 | alone | 746 | lhld arg4 |
| 635 | alone | 747 | ld b,h |
| 748 | ld c,l |
||
| 630 | alone | 749 | lda arg2 |
| 636 | alone | 750 | _1=$+1 |
| 635 | alone | 751 | ld hl,call2 |
| 752 | push hl |
||
| 630 | alone | 753 | lhld arg1 |
| 635 | alone | 754 | push hl |
| 630 | alone | 755 | lhld arg3 |
| 756 | ret |
||
| 757 | |||
| 635 | alone | 758 | call2: pop bc |
| 630 | alone | 759 | ret |
| 636 | alone | 760 | ENDFUNC callsz,1 |
| 630 | alone | 761 | |
| 635 | alone | 762 | FUNCTION "CALLA" |
| 763 | FUNCHEAD callasz |
||
| 630 | alone | 764 | call arghak |
| 635 | alone | 765 | push bc |
| 630 | alone | 766 | lhld arg5 ;get de value |
| 635 | alone | 767 | ex de,hl |
| 630 | alone | 768 | lhld arg4 ;get bc value |
| 635 | alone | 769 | ld b,h |
| 770 | ld c,l |
||
| 630 | alone | 771 | lda arg2 ;get a value |
| 636 | alone | 772 | _1=$+1 |
| 635 | alone | 773 | ld hl,calla2 ;get return address |
| 774 | push hl ;push it |
||
| 630 | alone | 775 | lhld arg1 ;get address of routine |
| 635 | alone | 776 | push hl |
| 630 | alone | 777 | lhld arg3 ;get hl value |
| 778 | ret ;call routine |
||
| 779 | |||
| 635 | alone | 780 | calla2: ld l,a ;put A value in HL |
| 781 | ld h,0 ;clear high byte |
||
| 782 | pop bc |
||
| 630 | alone | 783 | ret |
| 636 | alone | 784 | ENDFUNC callasz,1 |
| 630 | alone | 785 | |
| 635 | alone | 786 | FUNCTION "INP" |
| 787 | FUNCHEAD inpsz |
||
| 630 | alone | 788 | call ma1toh |
| 789 | sta iohack+1 ;store as arg to ram area input subroutine |
||
| 790 | call iohack ;call the subroutine to get value |
||
| 635 | alone | 791 | ld l,a ;and put into HL |
| 792 | ld h,0 |
||
| 630 | alone | 793 | ret |
| 636 | alone | 794 | ENDFUNC inpsz,0 |
| 630 | alone | 795 | |
| 635 | alone | 796 | FUNCTION "OUTP" |
| 797 | FUNCHEAD outpsz |
||
| 630 | alone | 798 | call ma1toh ;get port number |
| 799 | sta iohack+4 ;store as arg to ram area output subroutine |
||
| 800 | call ma2toh ;get data byte |
||
| 801 | call iohack+3 ;output it |
||
| 802 | ret |
||
| 636 | alone | 803 | ENDFUNC outpsz,0 |
| 630 | alone | 804 | |
| 635 | alone | 805 | FUNCTION "PEEK" |
| 806 | FUNCHEAD peeksz |
||
| 636 | alone | 807 | call ma1toh |
| 635 | alone | 808 | ld l,(hl) |
| 809 | ld h,0 |
||
| 630 | alone | 810 | ret |
| 636 | alone | 811 | ENDFUNC peeksz,0 |
| 630 | alone | 812 | |
| 813 | |||
| 635 | alone | 814 | FUNCTION "POKE" |
| 815 | FUNCHEAD pokesz |
||
| 630 | alone | 816 | call arghak |
| 817 | lhld arg1 |
||
| 818 | lda arg2 |
||
| 635 | alone | 819 | ld (hl),a |
| 630 | alone | 820 | ret |
| 636 | alone | 821 | ENDFUNC pokesz,0 |
| 630 | alone | 822 | |
| 635 | alone | 823 | FUNCTION "SLEEP" |
| 824 | FUNCHEAD sleepsz |
||
| 630 | alone | 825 | call ma1toh |
| 635 | alone | 826 | push bc |
| 827 | inc hl |
||
| 828 | sl1: dec hl |
||
| 829 | ld a,h |
||
| 830 | or l |
||
| 636 | alone | 831 | _1=$+1 |
| 635 | alone | 832 | jp nz,sl1a |
| 833 | pop bc |
||
| 630 | alone | 834 | ret |
| 835 | |||
| 635 | alone | 836 | sl1a: ld de,10000 |
| 837 | sl2: dec de |
||
| 838 | ld a,d |
||
| 839 | or e |
||
| 636 | alone | 840 | _2=$+1 |
| 635 | alone | 841 | jp nz,sl2 |
| 842 | push hl |
||
| 843 | ld c,cstat |
||
| 630 | alone | 844 | call bdos |
| 635 | alone | 845 | or a |
| 846 | pop hl |
||
| 636 | alone | 847 | _3=$+1 |
| 635 | alone | 848 | jp z,sl1 |
| 849 | push hl |
||
| 850 | ld c,conin |
||
| 630 | alone | 851 | call bdos |
| 635 | alone | 852 | cp cntrlc |
| 853 | jp z,exit |
||
| 854 | pop hl |
||
| 636 | alone | 855 | _4=$+1 |
| 635 | alone | 856 | jp sl1 |
| 636 | alone | 857 | ENDFUNC sleepsz,4 |
| 630 | alone | 858 | |
| 635 | alone | 859 | FUNCTION "PAUSE" |
| 860 | FUNCHEAD pausesz |
||
| 861 | push bc |
||
| 862 | paus1: ld c,cstat |
||
| 630 | alone | 863 | call bdos |
| 635 | alone | 864 | or a |
| 636 | alone | 865 | _1=$+1 |
| 635 | alone | 866 | jp z,paus1 |
| 867 | pop bc |
||
| 630 | alone | 868 | ret |
| 636 | alone | 869 | ENDFUNC pausesz,1 |
| 630 | alone | 870 | |
| 871 | |||
| 635 | alone | 872 | FUNCTION "EXIT" |
| 873 | FUNCHEAD exitsz |
||
| 874 | jp exit |
||
| 636 | alone | 875 | ENDFUNC exitsz,0 |
| 630 | alone | 876 | |
| 635 | alone | 877 | FUNCTION "BDOS" |
| 878 | FUNCHEAD bdossz |
||
| 630 | alone | 879 | call arghak |
| 635 | alone | 880 | push bc |
| 630 | alone | 881 | lda arg1 ;get C value |
| 635 | alone | 882 | ld c,a |
| 630 | alone | 883 | lhld arg2 ;get DE value |
| 635 | alone | 884 | ex de,hl ;put in DE |
| 630 | alone | 885 | call bdos ;make the bdos call |
| 635 | alone | 886 | pop bc |
| 630 | alone | 887 | ret ;and return to caller |
| 636 | alone | 888 | ENDFUNC bdossz,0 |
| 630 | alone | 889 | |
| 635 | alone | 890 | FUNCTION "BIOS" |
| 891 | FUNCHEAD biossz |
||
| 630 | alone | 892 | call arghak |
| 635 | alone | 893 | push bc |
| 630 | alone | 894 | lhld base+1 ;get addr of jump table + 3 |
| 635 | alone | 895 | dec hl ;set to addr of first jump |
| 896 | dec hl |
||
| 897 | dec hl |
||
| 630 | alone | 898 | lda arg1 ;get function number (1-85) |
| 635 | alone | 899 | ld b,a ;multiply by 3 |
| 630 | alone | 900 | add a |
| 901 | add b |
||
| 635 | alone | 902 | ld e,a ;put in DE |
| 903 | ld d,0 |
||
| 904 | add hl,de ;add to base of jump table |
||
| 905 | push hl ;and save for later |
||
| 630 | alone | 906 | lhld arg2 ;get value to be put in BC |
| 635 | alone | 907 | ld b,h ;and put it there |
| 908 | ld c,l |
||
| 636 | alone | 909 | _1=$+1 |
| 910 | ld hl,biosretadd ;where call to bios will return to |
||
| 635 | alone | 911 | ex (sp),hl ;get address of vector in HL |
| 912 | jp (hl) ;and go to it... |
||
| 636 | alone | 913 | biosretadd: ld l,a ;all done. now put return value in HL |
| 635 | alone | 914 | ld h,0 |
| 915 | pop bc |
||
| 630 | alone | 916 | ret ;and return to caller |
| 636 | alone | 917 | ENDFUNC biossz,1 |
| 630 | alone | 918 | |
| 635 | alone | 919 | FUNCTION "BIOSH" |
| 920 | FUNCHEAD bioshsz |
||
| 630 | alone | 921 | call arghak |
| 635 | alone | 922 | push bc |
| 630 | alone | 923 | lhld base+1 ;get addr of jump table + 3 |
| 635 | alone | 924 | dec hl ;set to addr of first jump |
| 925 | dec hl |
||
| 926 | dec hl |
||
| 630 | alone | 927 | lda arg1 ;get function number (1-85) |
| 635 | alone | 928 | ld b,a ;multiply by 3 |
| 630 | alone | 929 | add a |
| 930 | add b |
||
| 635 | alone | 931 | ld e,a ;put in DE |
| 932 | ld d,0 |
||
| 933 | add hl,de ;add to base of jump table |
||
| 934 | push hl ;and save for later |
||
| 630 | alone | 935 | |
| 936 | lhld arg2 ;get value to be put in BC |
||
| 635 | alone | 937 | ld b,h ;and put it there |
| 938 | ld c,l |
||
| 630 | alone | 939 | |
| 940 | lhld arg3 ;get value to be put in DE |
||
| 635 | alone | 941 | ld d,h ;adn put it there |
| 942 | ld e,l |
||
| 630 | alone | 943 | |
| 636 | alone | 944 | _1=$+1 |
| 635 | alone | 945 | ld hl,bioshretadd ;where call to bios will return to |
| 946 | ex (sp),hl ;get address of vector in HL |
||
| 947 | jp (hl) ;and go to it... |
||
| 948 | bioshretadd: pop bc ;all done. Leave return value in HL |
||
| 630 | alone | 949 | ret ;and return to caller |
| 636 | alone | 950 | ENDFUNC bioshsz,1 |
| 630 | alone | 951 | |
| 635 | alone | 952 | FUNCTION "CODEND" |
| 953 | FUNCHEAD codendsz |
||
| 630 | alone | 954 | lhld codend |
| 955 | ret |
||
| 636 | alone | 956 | ENDFUNC codendsz,0 |
| 630 | alone | 957 | |
| 671 | alone | 958 | if 1==1 |
| 635 | alone | 959 | FUNCTION "EXTERNS" |
| 960 | FUNCHEAD externssz |
||
| 630 | alone | 961 | lhld extrns |
| 962 | ret |
||
| 636 | alone | 963 | ENDFUNC externssz,0 |
| 671 | alone | 964 | endif |
| 630 | alone | 965 | |
| 635 | alone | 966 | FUNCTION "ENDEXT" |
| 967 | FUNCHEAD endextsz |
||
| 630 | alone | 968 | lhld freram |
| 969 | ret |
||
| 636 | alone | 970 | ENDFUNC endextsz,0 |
| 630 | alone | 971 | |
| 635 | alone | 972 | FUNCTION "TOPOFMEM" |
| 973 | FUNCHEAD topofmemsz |
||
| 630 | alone | 974 | lhld base+6 |
| 975 | lda tpa ;check for "NOBOOT" hackery |
||
| 635 | alone | 976 | cp 0c3h ; "jp" at start of C.CCC (as inserted by "-n")? |
| 977 | dec hl ;if CCC doesn't begin with "ld hl," then top of |
||
| 978 | ret nz ;memory is just below the base of the bdos |
||
| 979 | ld de,-2100 ;else subtract CCP size (plus little more for good |
||
| 980 | add hl,de ;measure) and return that as top of memory. |
||
| 630 | alone | 981 | ret |
| 636 | alone | 982 | ENDFUNC topofmemsz,0 |
| 630 | alone | 983 | |
| 635 | alone | 984 | FUNCTION "EXEC" |
| 985 | EXTERNAL "EXECL" |
||
| 986 | FUNCHEAD execsz |
||
| 636 | alone | 987 | _1=$+1 |
| 988 | jp (1 +1)*3 |
||
| 989 | _execl=$ |
||
| 990 | jp 0 |
||
| 630 | alone | 991 | call ma1toh ;get filename |
| 635 | alone | 992 | ld de,0 ;load null parameter in DE |
| 993 | push de ;push null parameter |
||
| 994 | push hl ;push filename |
||
| 636 | alone | 995 | _2=$+1 |
| 996 | call _execl ;do an execl |
||
| 635 | alone | 997 | pop de ;clean up stack |
| 998 | pop de |
||
| 630 | alone | 999 | ret |
| 636 | alone | 1000 | ENDFUNC execsz,2 |
| 630 | alone | 1001 | |
| 1002 | |||
| 635 | alone | 1003 | FUNCTION "EXECV" |
| 1004 | EXTERNAL "EXECL" |
||
| 1005 | FUNCHEAD execvsz |
||
| 636 | alone | 1006 | _1=$+1 |
| 1007 | jp (1 +1)*3 |
||
| 1008 | _execl=$ |
||
| 1009 | jp 0 |
||
| 630 | alone | 1010 | call arghak |
| 635 | alone | 1011 | push bc ;save BC |
| 630 | alone | 1012 | lhld arg2 ;get -> arg list |
| 635 | alone | 1013 | ld b,0 ;clear arg count |
| 1014 | execv1: inc b ;bump arg count |
||
| 1015 | ld e,(hl) |
||
| 1016 | inc hl |
||
| 1017 | ld d,(hl) |
||
| 1018 | inc hl |
||
| 1019 | ld a,d |
||
| 1020 | or e ;last arg? |
||
| 636 | alone | 1021 | _2=$+1 |
| 635 | alone | 1022 | jp nz,execv1 ;if not, keep looking for last one |
| 630 | alone | 1023 | |
| 635 | alone | 1024 | ld a,b ;save arg count in case of error |
| 636 | alone | 1025 | _3=$+1 |
| 630 | alone | 1026 | sta savcnt |
| 1027 | |||
| 635 | alone | 1028 | dec hl ;HL -> next to last arg |
| 1029 | execv2: ld d,(hl) ;now push args on stack |
||
| 1030 | dec hl |
||
| 1031 | ld e,(hl) |
||
| 1032 | dec hl |
||
| 1033 | dec b |
||
| 1034 | push de |
||
| 636 | alone | 1035 | _4=$+1 |
| 635 | alone | 1036 | jp nz,execv2 |
| 630 | alone | 1037 | |
| 1038 | execv3: lhld arg1 ;get program name |
||
| 635 | alone | 1039 | push hl ;save as first arg to execl |
| 636 | alone | 1040 | _5=$+1 |
| 1041 | call _execl ;go do it; shouldn't come back. |
||
| 1042 | _6=$+1 |
||
| 630 | alone | 1043 | lda savcnt ;woops, we're back. Must've been an error... |
| 635 | alone | 1044 | inc a ;bump to take prog name into consideration |
| 630 | alone | 1045 | add a |
| 635 | alone | 1046 | ld l,a ;put size of passed parameter list |
| 1047 | ld h,0 ;into HL, and adjust stack |
||
| 1048 | add hl,sp |
||
| 1049 | ld sp,hl |
||
| 1050 | pop bc ;restore BC |
||
| 1051 | ld hl,-1 ;return error value |
||
| 630 | alone | 1052 | ret |
| 1053 | |||
| 1054 | savcnt: ds 1 ;save arg count here |
||
| 636 | alone | 1055 | ENDFUNC execvsz,6 |
| 630 | alone | 1056 | |
| 1057 | |||
| 635 | alone | 1058 | FUNCTION "RBRK" |
| 1059 | FUNCHEAD rbrksz |
||
| 630 | alone | 1060 | lhld freram |
| 1061 | shld allocp |
||
| 636 | alone | 1062 | ENDFUNC rbrksz,0 |
| 630 | alone | 1063 | |
| 1064 | |||
| 635 | alone | 1065 | FUNCTION "SBRK" |
| 1066 | FUNCHEAD sbrksz |
||
| 630 | alone | 1067 | call ma1toh ;get # of bytes needed in HL |
| 635 | alone | 1068 | ld a,h ;check for -1 |
| 1069 | and l |
||
| 1070 | inc a |
||
| 636 | alone | 1071 | _1=$+1 |
| 635 | alone | 1072 | jp nz,sbrk2 ;go to sbrk2 if HL wasn't FFFF |
| 630 | alone | 1073 | |
| 1074 | lhld freram ;it WAS ffff: reset sbrk to base of free ram |
||
| 1075 | shld allocp |
||
| 1076 | ret |
||
| 1077 | |||
| 635 | alone | 1078 | sbrk2: ex de,hl ;put into DE |
| 630 | alone | 1079 | lhld allocp ;get current allocation pointer |
| 635 | alone | 1080 | push hl ;save it |
| 1081 | add hl,de ;get tentative last address of new segment |
||
| 636 | alone | 1082 | _2=$+1 |
| 635 | alone | 1083 | jp c,brkerr ;better not allow it to go over the top! |
| 1084 | dec hl |
||
| 1085 | ex de,hl ; now last addr is in DE |
||
| 630 | alone | 1086 | lhld alocmx ;get safety factor |
| 635 | alone | 1087 | ld a,h ;negate |
| 1088 | cpl |
||
| 1089 | ld h,a |
||
| 1090 | ld a,l |
||
| 1091 | cpl |
||
| 1092 | ld l,a |
||
| 1093 | inc hl |
||
| 1094 | add hl,sp ;get HL = (SP - alocmx) |
||
| 630 | alone | 1095 | |
| 636 | alone | 1096 | _3=$+1 |
| 630 | alone | 1097 | call cmpdh ;is DE less than HL? |
| 636 | alone | 1098 | _4=$+1 |
| 635 | alone | 1099 | jp nc,brkerr ;if not, can't provide the needed memory. |
| 1100 | ex de,hl ;else OK. |
||
| 1101 | inc hl |
||
| 630 | alone | 1102 | shld allocp ;save start of next area to be allocated |
| 635 | alone | 1103 | pop hl ;get pointer to this area |
| 630 | alone | 1104 | ret ;and return with it. |
| 1105 | |||
| 635 | alone | 1106 | brkerr: pop hl ;clean up stack |
| 1107 | jp error ;and return with -1 to indicate can't allocate. |
||
| 630 | alone | 1108 | |
| 635 | alone | 1109 | cmpdh: ld a,d |
| 1110 | cp h |
||
| 1111 | ret c |
||
| 1112 | ret nz |
||
| 1113 | ld a,e |
||
| 1114 | cp l |
||
| 630 | alone | 1115 | ret |
| 636 | alone | 1116 | ENDFUNC sbrksz,4 |
| 630 | alone | 1117 | |
| 635 | alone | 1118 | FUNCTION "RSVSTK" |
| 1119 | FUNCHEAD rsvstksz |
||
| 630 | alone | 1120 | call ma1toh ;get the value to reserve |
| 1121 | shld alocmx ;and set new safety factor |
||
| 1122 | ret |
||
| 636 | alone | 1123 | ENDFUNC rsvstksz,0 |
| 630 | alone | 1124 | |
| 1125 | ; |
||
| 1126 | ; Index(str,substr) |
||
| 1127 | ; char *str, *substr; |
||
| 1128 | ; |
||
| 1129 | ; Returns index of substr in str, or -1 if not found. |
||
| 1130 | ; |
||
| 1131 | |||
| 635 | alone | 1132 | FUNCTION "INDEX" |
| 1133 | FUNCHEAD indexsz |
||
| 630 | alone | 1134 | call arghak |
| 1135 | lhld arg1 |
||
| 635 | alone | 1136 | ex de,hl ;main str ptr in DE |
| 630 | alone | 1137 | lhld arg2 ;substr ptr in HL |
| 635 | alone | 1138 | dec de |
| 1139 | index1: inc de |
||
| 1140 | ld a,(de) ;end of str? |
||
| 1141 | or a |
||
| 636 | alone | 1142 | _1=$+1 |
| 635 | alone | 1143 | jp nz,index2 |
| 1144 | ld hl,-1 ;yes. not found. |
||
| 630 | alone | 1145 | ret |
| 635 | alone | 1146 | index2: cp (hl) ;quick check for dissimilarity |
| 636 | alone | 1147 | _2=$+1 |
| 635 | alone | 1148 | jp nz,index1 ;loop if not same right here |
| 1149 | push de ;else do long compare |
||
| 1150 | push hl |
||
| 1151 | index3: inc hl |
||
| 1152 | inc de |
||
| 1153 | ld a,(hl) ;end of substr? |
||
| 1154 | or a |
||
| 636 | alone | 1155 | _3=$+1 |
| 635 | alone | 1156 | jp nz,index4 ;if not, go on testing |
| 1157 | pop de ;else matches |
||
| 1158 | pop de ;get starting address of substr in DE |
||
| 630 | alone | 1159 | lhld arg1 ;subtract beginning of str |
| 1160 | call cmh |
||
| 635 | alone | 1161 | add hl,de ;and return the result |
| 630 | alone | 1162 | ret |
| 1163 | |||
| 635 | alone | 1164 | index4: ld a,(de) ;current char match? |
| 1165 | cp (hl) |
||
| 636 | alone | 1166 | _4=$+1 |
| 635 | alone | 1167 | jp z,index3 ;if so, keep testing |
| 1168 | pop hl ;else go on to next char in str |
||
| 1169 | pop de |
||
| 636 | alone | 1170 | _5=$+1 |
| 635 | alone | 1171 | jp index1 |
| 636 | alone | 1172 | ENDFUNC indexsz,5 |
| 630 | alone | 1173 | |
| 1174 | |||
| 930 | alone | 1175 | include "deff2b.csm" |
| 1176 | include "deff2c.csm" |
||
| 635 | alone | 1177 | |
| 636 | alone | 1178 | FUNCTION "PUTS" |
| 1179 | EXTERNAL "PUTCHAR" |
||
| 1180 | FUNCHEAD putssz |
||
| 1181 | _1=$+1 |
||
| 1182 | jp (1 +1)*3 |
||
| 1183 | _putchar=$ |
||
| 1184 | jp 0 |
||
| 1185 | push bc |
||
| 1186 | ld hl,0 |
||
| 1187 | add hl,sp |
||
| 1188 | ld b,h |
||
| 1189 | ld c,l |
||
| 1190 | puts0: |
||
| 1191 | call sdli ;short-displacement, double-byte local indirection |
||
| 1192 | db 4 ;shift from bc |
||
| 1193 | ld l,(hl) |
||
| 1194 | ld a,l |
||
| 1195 | or a |
||
| 1196 | _2=$+1 |
||
| 1197 | jp z,putsq |
||
| 1198 | ld hl,4 |
||
| 1199 | add hl,bc |
||
| 1200 | ld e,(hl) |
||
| 1201 | inc hl |
||
| 1202 | ld d,(hl) |
||
| 1203 | inc de |
||
| 1204 | ld (hl),d |
||
| 1205 | dec hl |
||
| 1206 | ld (hl),e |
||
| 1207 | dec de |
||
| 1208 | ex de,hl |
||
| 1209 | ld l,(hl) |
||
| 1210 | ld h,0 |
||
| 1211 | push hl |
||
| 1212 | _3=$+1 |
||
| 1213 | call _putchar |
||
| 1214 | pop de |
||
| 1215 | _4=$+1 |
||
| 1216 | jp puts0 |
||
| 1217 | putsq: |
||
| 1218 | pop bc |
||
| 1219 | ret |
||
| 1220 | ENDFUNC putssz,4 |
||
| 1221 | |||
| 680 | alone | 1222 | |
| 636 | alone | 1223 | ; |
| 1224 | ; Read: |
||
| 1225 | ; |
||
| 1226 | ; i = read(fd, buf, n); |
||
| 1227 | ; |
||
| 1228 | ; Read a number of sectors using random-record I/O. |
||
| 1229 | ; |
||
| 1230 | ; The return value is either the number of sectors successfully |
||
| 1231 | ; read, 0 for EOF, or -1 on error with errno() returning the error |
||
| 1232 | ; code (or errmsg(errno()) returning a pointer to an error message). |
||
| 1233 | ; |
||
| 1234 | ; The Random Record Field is incremented following each successful |
||
| 1235 | ; sector is read, just as if the normal (sequential) read function |
||
| 1236 | ; were being used. "seek" must be used to go back to a previous |
||
| 1237 | ; sector. |
||
| 1238 | ; |
||
| 679 | alone | 1239 | ;NOW RETURNS NUMBER OF BYTES, NOT SECTORS!!! |
| 636 | alone | 1240 | |
| 680 | alone | 1241 | if NEDOOS |
| 636 | alone | 1242 | FUNCTION "READ" |
| 1243 | FUNCHEAD readsz |
||
| 680 | alone | 1244 | call arghak |
| 1245 | lda arg1 |
||
| 1246 | call fgfd ;compute fd address for fd in A: ;return hl=fd addr |
||
| 1247 | push bc |
||
| 1248 | ld b,(hl) |
||
| 1249 | ld de,(arg2) |
||
| 1250 | ld hl,(arg3) |
||
| 1251 | OS_READHANDLE |
||
| 1252 | pop bc |
||
| 1253 | or a |
||
| 1254 | ret z |
||
| 1255 | ld hl,-1 |
||
| 1256 | ret |
||
| 1257 | ENDFUNC readsz,0 |
||
| 1258 | |||
| 1259 | else |
||
| 1260 | |||
| 1261 | FUNCTION "READ" |
||
| 1262 | FUNCHEAD readsz |
||
| 636 | alone | 1263 | call arghak |
| 1264 | lda arg1 |
||
| 1265 | call fgfd |
||
| 1266 | ld d,(hl) ;save fdt entry in D |
||
| 1267 | ld a,7 ;prepare for possible "bad fd" |
||
| 671 | alone | 1268 | or a |
| 636 | alone | 1269 | _1=$+1 |
| 1270 | jp c,rerror |
||
| 1271 | |||
| 671 | alone | 1272 | ;ld a,d |
| 1273 | ;and 2 ;4wr |
||
| 636 | alone | 1274 | ld a,8 ;9wr ;prepare for possible "no read permission" |
| 671 | alone | 1275 | or a |
| 636 | alone | 1276 | _2=$+1 |
| 1277 | jp z,rerror |
||
| 1278 | |||
| 1279 | push bc |
||
| 671 | alone | 1280 | ;ld a,d ;get fd table entry |
| 1281 | ;call setusr ;set user area to that of the file |
||
| 636 | alone | 1282 | |
| 1283 | lda arg1 ;get fd |
||
| 1284 | call fgfcb |
||
| 1285 | shld tmp2 ;save fcb address |
||
| 1286 | ld hl,0 |
||
| 1287 | shld tmp2a |
||
| 679 | alone | 1288 | lhld arg3 |
| 1289 | add hl,hl |
||
| 1290 | ld l,h |
||
| 1291 | ld h,0 |
||
| 1292 | shld arg3 ;size/128 |
||
| 636 | alone | 1293 | r2: lhld arg3 ;get countdown |
| 1294 | ld a,h |
||
| 1295 | or l ;done? |
||
| 1296 | |||
| 1297 | r2aa: lhld tmp2a |
||
| 1298 | _3=$+1 |
||
| 1299 | jp nz,r2a |
||
| 679 | alone | 1300 | r2done128: |
| 1301 | xor a |
||
| 1302 | srl h |
||
| 1303 | rr l |
||
| 1304 | rra |
||
| 1305 | ld h,l |
||
| 1306 | ld l,a ;count*128 |
||
| 671 | alone | 1307 | r2done: ;call rstusr ;reset user number |
| 636 | alone | 1308 | pop bc ;yes. return with success count in HL |
| 1309 | ret |
||
| 1310 | |||
| 1311 | r2a: lhld arg2 ;get transfer addr in DE |
||
| 1312 | ex de,hl |
||
| 1313 | ld c,sdma ;set DMA there |
||
| 1314 | call bdos |
||
| 1315 | |||
| 1316 | lhld tmp2 |
||
| 1317 | ex de,hl |
||
| 671 | alone | 1318 | ;ld c,readr ;code for BDOS random read |
| 636 | alone | 1319 | push de ;save DE so we can fudge nr field if |
| 671 | alone | 1320 | ;call bdos ;we stop reading on extent boundary... |
| 1321 | OS_FREAD |
||
| 636 | alone | 1322 | pop de |
| 1323 | or a |
||
| 1324 | _4=$+1 |
||
| 1325 | jp z,r4 ;go to r4 if no problem |
||
| 1326 | |||
| 671 | alone | 1327 | cp 128 ;0 bytes read in NedoOS ;cp 1 ;ok, we have SOME kind of hangup... |
| 636 | alone | 1328 | _5=$+1 |
| 671 | alone | 1329 | jp nz,r2b ;jp z,r2b ;check for EOF condition: |
| 636 | alone | 1330 | cp 4 ; error codes 1 and 4 both indicate reading |
| 1331 | _6=$+1 |
||
| 1332 | jp z,r2b ; unwritten data..treat as EOF |
||
| 1333 | |||
| 1334 | ld b,a ;have we successfully read anything yet? |
||
| 1335 | lda tmp2a |
||
| 1336 | or a |
||
| 1337 | ld b,a ;get error code back in A |
||
| 1338 | _7=$+1 |
||
| 1339 | jp nz,r2c ;if we have read something in, don't set errnum |
||
| 1340 | sta errnum ;otherwise nothing read, so set error code. |
||
| 1341 | |||
| 1342 | r2c: ld hl,-1 ;put ERROR value in HL |
||
| 1343 | _8=$+1 |
||
| 1344 | jp r2done |
||
| 1345 | |||
| 1346 | r2b: lhld tmp2a ;return count |
||
| 671 | alone | 1347 | inc hl ;for NedoOS: we have read at least 1 byte in the last sector |
| 636 | alone | 1348 | _9=$+1 |
| 679 | alone | 1349 | jp r2done128 |
| 636 | alone | 1350 | |
| 1351 | r4: lhld arg3 ;decrement countdown |
||
| 1352 | dec hl |
||
| 1353 | shld arg3 |
||
| 1354 | lhld arg2 ;bump DMA address |
||
| 1355 | ld de,128 |
||
| 1356 | add hl,de |
||
| 1357 | shld arg2 |
||
| 1358 | lhld tmp2a ;bump success count |
||
| 1359 | inc hl |
||
| 1360 | shld tmp2a |
||
| 1361 | |||
| 1362 | lhld tmp2 ;get address of fcb |
||
| 1363 | ld bc,33 ;get addr of random record field |
||
| 1364 | add hl,bc |
||
| 1365 | ld c,(hl) ;bump |
||
| 1366 | inc hl ; value |
||
| 1367 | ld b,(hl) ; of |
||
| 1368 | inc bc ; random |
||
| 1369 | ld (hl),b ; field |
||
| 1370 | dec hl ; by one |
||
| 1371 | ld (hl),c |
||
| 1372 | ld a,b ;overflow past 16-bit record count? |
||
| 1373 | or c |
||
| 1374 | _10=$+1 |
||
| 1375 | jp nz,r2 ; go for next sector if no overflow |
||
| 1376 | inc hl ;else set 3rd byte of random sector count |
||
| 1377 | inc hl |
||
| 1378 | ld (hl),1 |
||
| 1379 | ld a,14 ;"seek past 65536th record of file" |
||
| 1380 | sta errnum |
||
| 1381 | _11=$+1 |
||
| 1382 | jp r2aa ;and don't read any more. |
||
| 1383 | |||
| 1384 | rerror: sta errnum |
||
| 1385 | jp error |
||
| 1386 | ENDFUNC readsz,11 |
||
| 680 | alone | 1387 | endif |
| 636 | alone | 1388 | |
| 671 | alone | 1389 | ;zzz |
| 1390 | if 1==1 |
||
| 1391 | FUNCTION "SETJMP" |
||
| 1392 | FUNCHEAD setjmpsz |
||
| 1393 | call ma1toh |
||
| 1394 | ld (hl),c ;save BC |
||
| 1395 | inc hl |
||
| 1396 | ld (hl),b |
||
| 1397 | inc hl |
||
| 1398 | ex de,hl |
||
| 1399 | ld hl,0 |
||
| 1400 | add hl,sp |
||
| 1401 | ex de,hl |
||
| 1402 | ld (hl),e ;save SP |
||
| 1403 | inc hl |
||
| 1404 | ld (hl),d |
||
| 1405 | inc hl |
||
| 1406 | pop de ;save return address |
||
| 1407 | push de |
||
| 1408 | ld (hl),e |
||
| 1409 | inc hl |
||
| 1410 | ld (hl),d |
||
| 1411 | ld hl,0 ;and return 0 |
||
| 1412 | ret |
||
| 1413 | ENDFUNC setjmpsz,0 |
||
| 1414 | endif |
||
| 1415 | |||
| 1416 | if 1==1 |
||
| 1417 | FUNCTION "LONGJMP" |
||
| 1418 | FUNCHEAD longjmpsz |
||
| 1419 | call ma1toh ;get buffer address |
||
| 1420 | ld c,(hl) ;restore BC |
||
| 1421 | inc hl |
||
| 1422 | ld b,(hl) |
||
| 1423 | inc hl |
||
| 1424 | ld e,(hl) ;restore SP...first put it in DE |
||
| 1425 | inc hl |
||
| 1426 | ld d,(hl) |
||
| 1427 | inc hl |
||
| 1428 | shld tmp2 ;save pointer to return address |
||
| 1429 | call ma2toh ;get return value |
||
| 1430 | ex de,hl ;put return val in DE, old SP in HL |
||
| 1431 | ld sp,hl ;restore SP with old value |
||
| 1432 | pop hl ;pop return address off stack |
||
| 1433 | lhld tmp2 ;get back ptr to return address |
||
| 1434 | ld a,(hl) |
||
| 1435 | inc hl |
||
| 1436 | ld h,(hl) |
||
| 1437 | ld l,a ;HL holds return address |
||
| 1438 | ex de,hl ;put ret addr in DE, get return value in HL |
||
| 1439 | push de ;push return address on stack |
||
| 1440 | ret ;and return... |
||
| 1441 | ENDFUNC longjmpsz,0 |
||
| 1442 | endif |
||
| 1443 | ;display $-zzz |
||
| 1444 | ;ds 0;66 |
||
| 1445 | |||
| 680 | alone | 1446 | ;include "deffgfx.csm" |
| 671 | alone | 1447 | ;align 128 ;doesn't help |
| 1448 | |||
| 635 | alone | 1449 | end |
| 1450 | savebin "deff2.crl",begin,end-begin |
||
| 1451 | |||
| 1452 | LABELSLIST "../../us/user.l" |