Added suppot for BSS clearing and command line parsing.
authordtrg <none@none>
Sun, 29 Apr 2007 00:28:06 +0000 (00:28 +0000)
committerdtrg <none@none>
Sun, 29 Apr 2007 00:28:06 +0000 (00:28 +0000)
plat/cpm/boot.s

index bb55898..b36d1ce 100644 (file)
@@ -10,6 +10,8 @@
 .sect .data
 .sect .bss
 
+MAX_ARGV = 8
+
 .sect .bss
 STACKSIZE = 2*1024
 .comm stack, STACKSIZE
@@ -17,11 +19,95 @@ STACKSIZE = 2*1024
 
 .sect .text
 begtext:
+       ! The absolute first thing we have to do is to clear the bss. (argify
+       ! requires it.)
+       
+       lxi h, begbss
+       lxi b, endbss
+       mvi e, 0
+1:
+       mov m, e
+       inx h
+       mov a, b
+       cmp h
+       jnz 1b
+       mov a, c
+       cmp l
+       jnz 1b
+
+       ! Set up the stack (now it's been cleared, since it's in the BSS).
+               
        lxi sp, oldstack + STACKSIZE
+
+       ! C-ify the command line at 0x0080.
+       
+       lxi h, 0x0080
+       mov a, m                 ! a = length of command line
+       cpi 0x7F                 ! 127-byte command lines...
+       jnz 1f
+       dcr a                    ! ...lose the last character 
+1:
+       adi 0x81                 ! write a 0 at 0x0081+length
+       mov l, a
+       mov m, h
+       
+       ! Now argify it.
+       
+       lxi b, 0x0081            ! bc = command line pointer
+       lxi d, argv              ! de = argv pointer
+               
+       ldax b                   ! peek for any leading whitespace
+       ora a
+       cpi ' '
+       jz 3f
+       
+1:  xchg                     ! write out the next argument
+    mov m, c
+    inx h
+    mov m, b
+    inx h
+    xchg
+
+       lda argc                 ! exit if this was the last argument
+       inr a
+       sta argc
+       cpi MAX_ARGV
+    jz end_of_argify
+    
+2:  inx b                    ! scan for whitespace
+    ldax b
+    ora a
+    jz end_of_argify
+    cpi ' '
+    jnz 2b
+    
+    xra a                    ! replace the space with a \0
+    stax b
+    
+3:  inx b                    ! scan for non-whitespace
+    ldax b
+    ora a
+    jz end_of_argify
+    cpi ' '
+    jz 3b
+    jmp 1b
+end_of_argify:
+
+       ! Add the fake parameter for the program name.
+       
+       lxi h, progname
+       shld argv0
+       lxi h, argc
+       inr m
+       
+       ! Push the main() arguments and go.
        
-       lxi h, 0
+       lxi h, envp
        push h
+       lxi h, argv0
        push h
+       lhld argc                ! slightly evil
+       mvi h, 0
        push h
        call __m_a_i_n
        jmp EXIT
@@ -48,7 +134,14 @@ __exit:
 .comm .ignmask, 2
 .comm _errno, 2
 
-! These are used specifically by the CP/M port.
+! Used to store the argv array.
+
+argc: .space 1          ! number of args
+argv0: .space 2         ! always points at progname
+argv: .space 2*MAX_ARGV ! argv array (must be after argv0)
+envp: .space 2          ! envp array (always empty, must be after argv)
+
+! These are used specifically by the i80 code generator.
 
 .define .trapproc, .retadr, .retadr1
 .define .bcreg, .areg
@@ -64,3 +157,6 @@ __exit:
 block1: .space 4        ! used by 32 bits divide and
 block2: .space 4        ! multiply routines
 block3: .space 4        ! must be contiguous (.comm doesn't guarantee this)
+
+.sect .rom
+progname: .asciz 'ACKCPM'