Jump to content

Dealer Demo, part 10: A complete kernel

Posted by Atari_Ace, 14 September 2018 · 36 views

OK, let's finish off the kernel of Dealer Demo.
The next chunk is the COLD start routine, starting at $1C84, which is implemented as a primitive.  Following that are a variety of standard Forth words dealing with mathematical operations and buffer and screen management.  This leads up to TCIOV, a Dealer Demo primitive to invoke CIO routines.  After the implementations of EMIT and KEY (labeled XEMIT and XKEY), we add a primitive BLKIO for invoking the disk handler, some SIO DCB constants (DCDNO, DCCOM, DCADD, DCSEC) and then the word RSLW which implements reading and writing to disk.  After that we find the implementation of TYPE, and then more standard Forth words for implementing loops and conditions, digit formatting, listing words and screens.
That finishes off the core Forth kernel.  To check our work, we should strip the left hand byte data from the listing and send it through an assembler.  MADS is a popular assembler, but its syntax is a little different from the syntax we've been using, so we need to massage the output slightly, specifically we need to convert *= to ORG and drop the A from the shift accumulator operators.  We should also not emit lines that are included just to list all the bytes for a line that generates more than three bytes of output.  Those requirements yield this little bit of code.

sub lst2mads {
  my $fh = open_lst();
  while (<$fh>) {
    my ($output, $rest) = (/^(.{0,16})(.*)/);
    next if $output !~ /^\s+$/ && $rest eq '';
    my ($comment) = ($rest =~ /(\s*(?<!');.*)$/);
    $rest =~ s/\s*(?<!');.*//;  # truncate comments
    $rest =~ s/\*=/ORG /;
    $rest =~ s/(\s+(?:ASL|LSR|ROR|ROL)\s+)A(\s+|$)/\1\2/;
    print "$rest$comment\n";

And sure enough, it assembles without error.  We could also do some data validation of the $output data, but let's postpone that and instead focus on how the words we just decompiled differ from the published fig-Forth listing.
So what's different:
  • The COLD word checks if the WARMST flag is set, in which case it skips to doing a WARM start only.
  • USE and PREV start out as different values rather than the same in fig-Forth.
  • FLUSH is more complicated in Dealer Demo.  It doesn't use BUFFER, so it needs to duplicate some of its logic.
  • DR0 and DR1 have to set both OFFSET and PHYSOFF, rather than just OFFSET.
  • XKEY, XEMIT and XTYPE are implemented as Forth colon definitions, instead of assembly primitives.  The primitive is instead TCIOV.  Of the remaining words the fig-Forth documentation says to provide implementations, CR is implemented in terms of EMIT, QTERM is always zero and RSLW is implemented around the BLKIO primitive.
  • FORGET is different, using LESS instead of ULESS in some places (in fig-Forth they are equivalent though due to a bug), and starting with CURR @ CON @ - $18 ?ERR, and never invoking the FORTH word.  This word was significantly modified between the 1979 and 1980 publications of the fig-Forth Installation manual, replacing the Ragsdale version with a 'smart' one by David Kilbridge.  The version in Dealer Demo seems to be some combination of the two.
  • INDEX doesn't EMIT a form feed character when done (oddly TRIAD still does, which is likely a bug).
The interesting new primitives are TCIOV and BLKIO.
2025: 27 20     TCIOV   .WORD *+2
2027: 86 FF             STX XSAVE
2029: B5 00             LDA 0,X
202B: A2 00             LDX #0
202D: 20 56 E4          JSR CIOV
2030: A9 00             LDA #0
2032: C0 80             CPY #$80
2034: D0 01             BNE TCIOV1
2036: 98                TYA
2037: 48        TCIOV1  PHA
2038: A6 FF             LDX XSAVE
203A: 4C 3B 0D          JMP PUSH
This regularizes entering into CIO, move the top of the data stack to the accumulator and pushing the return status to the data stack.
20C9: CB 20     BLKIO   .WORD *+2
20CB: 86 FF             STX XSAVE
20CD: 20 53 E4  BLKIO1  JSR DSKINV
20D0: AD 03 03          LDA DSTATS
20D3: 10 06             BPL BLKIO2
20D5: A6 FF             LDX XSAVE
20D7: 48                PHA
20D8: 4C 3D 0D          JMP PUT
20DE: D0 03             BNE BLKIO3
20E0: EE 0B 03          INC DAUX2
20E3: A9 80     BLKIO3  LDA #$80
20E5: 4D 04 03          EOR DBUFLO
20E8: 8D 04 03          STA DBUFLO
20EB: 30 03             BMI BLKIO4
20ED: EE 05 03          INC DBUFHI
20F2: D6 00             DEC 0,X
20F4: D0 D7             BNE BLKIO1
20F6: 4C 42 0D          JMP NEXT
This likewise provides a Forth vector into the disk handler, which RSLW and related words need to interact with the disk.
So there you have it, the Forth kernel in Dealer Demo is about 90% the same as the traditional kernel published by fig-Forth and William Ragsdale.  A few changes here and there, but this is recognizably a fig-Forth derived kernel.
In our next post, we'll talk about the Forth assembler, which is the next bit of code in the Dealer Demo.

Attached Files