• Please review our updated Terms and Rules here

Exidy Experiment

The Sorcerer has 128 user-defined characters in 1K of SRAM. That's great for most games which use tiled displays but it's not enough to cover the whole screen with arbitrary graphics.

I have some 16Kx4 SRAMs which are mostly pin-compatible with the original 1Kx4 chips, so I plugged them in along with a mux chip to drive the 4 extra address lines. During video access, those lines come from the video line counters. During CPU access, they come from a parallel output port. In this prototype, it's the keyboard scan port. So the bitmap display consists of 15 1K banks at the normal addresses FC00 - FFFF. The software paints the screen with 15 copies of the user character set and then it switches banks and fills each with a slice of the image. This test image is a monochrome BMP of Wikipedia's photo of a Sorcerer.
 
The Z80 runs at 2.1 MHz. Loading a 12K .BMP file into main RAM takes 7 seconds at 20 kbaud with my TapeSim. Then the 36-byte loader program uses 12 LDIRs to render it in less than 0.2 second.

I have not written any line drawing or fill routines yet.
 
Imagine what such an upgrade might have been like in 1979. 30 1Kx4 SRAM chips plus a few logic chips. Maybe 2/3 the size of an S100 board.
1745172857944.jpeg
It could have plugged into the rear expansion port. And some ribbon cables with dip headers to tap into the display SRAM sockets. It might have cost $400, half the price of a Sorcerer.

By 1982 it could use 2Kx8 SRAMs and be small enough to fit inside the case as a daughter board. Maybe $200 then.

Now it could use a single 32K or 128K SRAM and have multiple display pages. Or it could use a modern microcontroller to simulate RAM and include a high speed blitter.
 
Neat.

Hijacking the character generation system to wedge graphics into a text system like this was a pretty common approach, but this is certainly a unique take on it, in how the Sorcerer already *had* definable graphics characters, you just needed to add more memory and an automatic line-based bank switcher.
 
A plot using the algorithm published in a BYTE article from August 1977 called Serendipitous Circles:
20250502_204225.jpg
 
Here are the USR functions:
Code:
0078                   ORG     78H
 0078 0000      XCO:    DFB     0,0         ; x coord
 007A 00        YCO:    DFB     0           ; y coord
              
 007B 2A7800            LD      HL,(XCO)    ; Plot pt at x,y
 007E 7D        PLOT:   LD      A,L
 007F E607              AND     #7
 0081 4F                LD      C,A         ; bit index
 0082 7D                LD      A,L
 0083 E6F8              AND     #0F8H
 0085 6F                LD      L,A
 0086 29                ADD     HL,HL
 0087 3A7A00            LD      A,(YCO)
 008A E60F              AND     #0FH
 008C 5F                LD      E,A
 008D 16FC              LD      D,#0FCH
 008F 19                ADD     HL,DE       ; byte ptr
 0090 3A7A00            LD      A,(YCO)
 0093 0F                RRC     A
 0094 0F                RRC     A
 0095 0F                RRC     A
 0096 0F                RRC     A
 0097 3C                INC     A           ; bank 1-15
 0098 E60F              AND     #0FH
 009A 47                LD      B,A
 009B D3FE              OUT     (0FEH),A    ; select bank
 009D 11BF00            LD      DE,#BITS
 00A0 7B                LD      A,E
 00A1 81                ADD     A,C         ; index into bit table
 00A2 5F                LD      E,A
 00A3 1A                LD      A,(DE)      ; pixel on: bit pattern
 00A4 B6                OR      (HL)
 00A5 77                LD      (HL),A      ; OR to screen
 00A6 1A                LD      A,(DE)      ; pixel off:
 00A7 2F                CPL                 ; invert bit pattern
 00A8 4F                LD      C,A
 00A9 2C        DOWN:   INC     L           ; next y down
 00AA 7D                LD      A,L
 00AB E60F              AND     #0FH
 00AD 200B              JR      NZ,POFF
 00AF 7D                LD      A,L
 00B0 D610              SUB     #10H
 00B2 6F                LD      L,A
 00B3 04                INC     B           ; next bank
 00B4 78                LD      A,B
 00B5 E60F              AND     #0FH
 00B7 C8                RETZ
 00B8 D3FE              OUT     (0FEH),A    ; select bank
 00BA 79        POFF:   LD      A,C         ; pixel off
 00BB A6                AND     (HL)
 00BC 77                LD      (HL),A      ; AND to screen
 00BD 18EA              JR      DOWN
 00BF 80402010  BITS:   DFB     80H,40H,20H,10H
 00C3 08040201          DFB     8,4,2,1
              
 00C7 1180F0            LD      DE,#0F080H  ; Fill screen with user chars
 00CA 21C0F0            LD      HL,#0F0C0H
 00CD 018000            LD      BC,#80H
 00D0 79        FILL:   LD      A,C         ; 80-FF
 00D1 12        LOOP:   LD      (DE),A      ; 30 lines of 64 chars   
 00D2 13                INC     DE
 00D3 3C                INC     A
 00D4 77                LD      (HL),A   
 00D5 23                INC     HL
 00D6 3C                INC     A
 00D7 20F8              JR      NZ,LOOP
 00D9 EB                EX      DE,HL
 00DA 09                ADD     HL,BC
 00DB 7C                LD      A,H
 00DC FEF8              CP      #0F8H       ; F080-F7FF
 00DE 20F0              JR      NZ,FILL     ; (512 h x 240 v pixels)
              
 00E0 210000            LD      HL,#0       ; Clear screen
 00E3 44                LD      B,H
 00E4 3E01              LD      A,#1        ; start bank 1
 00E6 ED73F700          LD      (STK+1),SP  ; save SP into instruction at STK below
 00EA D3FE      MOVE:   OUT     (0FEH),A    ; select bank
 00EC F9                LD      SP,HL       ; borrow stack ptr
 00ED E5        CLR:    PUSH    HL          ; user char RAM FC00-FFFF
 00EE E5                PUSH    HL
 00EF 10FC              DJNZ    CLR         ; 256*4
 00F1 3C                INC     A           ; next bank
 00F2 FE10              CP      #16         ; thru bank 15
 00F4 20F4              JR      NZ,MOVE
 00F6 313412    STK:    LD      SP,#1234H   ; restore stack ptr (modified above)
 00F9 C9                RET
 
The init function at 00C7 fills the screen with 15 copies of the user character set, even characters in even rows and odd ones in odd rows. This makes the plotting address calculations simpler. It then clears all 15 1K banks using PUSH for speed.
 
Back
Top