Quellcode durchsuchen

Added suppot for BSS clearing and command line parsing.

dtrg vor 17 Jahren
Ursprung
Commit
c9d7f7ef23
1 geänderte Dateien mit 98 neuen und 2 gelöschten Zeilen
  1. 98 2
      plat/cpm/boot.s

+ 98 - 2
plat/cpm/boot.s

@@ -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'